2025-09-21 11:02:31 -07:00
import { tool , type UIMessageStreamWriter } from "ai" ;
2026-03-20 09:37:02 +00:00
import type { Session } from "next-auth" ;
2025-09-21 11:02:31 -07:00
import { z } from "zod" ;
2025-02-13 08:25:57 -08:00
import {
artifactKinds ,
documentHandlersByArtifactKind ,
2025-09-21 11:02:31 -07:00
} from "@/lib/artifacts/server" ;
import type { ChatMessage } from "@/lib/types" ;
import { generateUUID } from "@/lib/utils" ;
2025-01-23 01:19:48 +05:30
2025-09-21 11:02:31 -07:00
type CreateDocumentProps = {
2026-03-20 09:37:02 +00:00
session : Session ;
2025-07-03 02:26:34 -07:00
dataStream : UIMessageStreamWriter < ChatMessage > ;
2026-03-20 09:37:02 +00:00
modelId : string ;
2025-09-21 11:02:31 -07:00
} ;
2025-01-23 01:19:48 +05:30
2026-03-20 09:37:02 +00:00
export const createDocument = ( {
session ,
dataStream ,
modelId ,
} : CreateDocumentProps ) = >
2025-01-23 01:19:48 +05:30
tool ( {
description :
2026-03-20 09:37:02 +00:00
"Create an artifact. You MUST specify kind: use 'code' for any programming/algorithm request (creates a script), 'text' for essays/writing (creates a document), 'sheet' for spreadsheets/data." ,
2025-07-03 02:26:34 -07:00
inputSchema : z.object ( {
2026-03-20 09:37:02 +00:00
title : z.string ( ) . describe ( "The title of the artifact" ) ,
kind : z
. enum ( artifactKinds )
. describe (
"REQUIRED. 'code' for programming/algorithms, 'text' for essays/writing, 'sheet' for spreadsheets"
) ,
2025-01-23 01:19:48 +05:30
} ) ,
execute : async ( { title , kind } ) = > {
const id = generateUUID ( ) ;
2025-02-04 17:15:39 +03:00
2025-07-03 02:26:34 -07:00
dataStream . write ( {
2025-09-21 11:02:31 -07:00
type : "data-kind" ,
2025-07-03 02:26:34 -07:00
data : kind ,
transient : true ,
2025-02-04 17:15:39 +03:00
} ) ;
2025-01-23 01:19:48 +05:30
2025-07-03 02:26:34 -07:00
dataStream . write ( {
2025-09-21 11:02:31 -07:00
type : "data-id" ,
2025-07-03 02:26:34 -07:00
data : id ,
transient : true ,
2025-01-23 01:19:48 +05:30
} ) ;
2025-07-03 02:26:34 -07:00
dataStream . write ( {
2025-09-21 11:02:31 -07:00
type : "data-title" ,
2025-07-03 02:26:34 -07:00
data : title ,
transient : true ,
2025-01-23 01:19:48 +05:30
} ) ;
2025-07-03 02:26:34 -07:00
dataStream . write ( {
2025-09-21 11:02:31 -07:00
type : "data-clear" ,
2025-07-03 02:26:34 -07:00
data : null ,
transient : true ,
2025-01-23 01:19:48 +05:30
} ) ;
2025-02-13 08:25:57 -08:00
const documentHandler = documentHandlersByArtifactKind . find (
( documentHandlerByArtifactKind ) = >
2025-09-21 11:02:31 -07:00
documentHandlerByArtifactKind . kind === kind
2025-02-04 17:15:39 +03:00
) ;
2025-01-23 01:19:48 +05:30
2025-02-04 17:15:39 +03:00
if ( ! documentHandler ) {
throw new Error ( ` No document handler found for kind: ${ kind } ` ) ;
2025-01-23 01:19:48 +05:30
}
2025-02-04 17:15:39 +03:00
await documentHandler . onCreateDocument ( {
id ,
title ,
dataStream ,
session ,
2026-03-20 09:37:02 +00:00
modelId ,
2025-02-04 17:15:39 +03:00
} ) ;
2025-09-21 11:02:31 -07:00
dataStream . write ( { type : "data-finish" , data : null , transient : true } ) ;
2025-01-23 01:19:48 +05:30
return {
id ,
title ,
kind ,
2026-03-20 09:37:02 +00:00
content :
kind === "code"
? "A script was created and is now visible to the user."
: "A document was created and is now visible to the user." ,
2025-01-23 01:19:48 +05:30
} ;
} ,
} ) ;