Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/(chat)/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use server"

import { generateText, Message } from "ai"
import { generateText, UIMessage } from "ai"
import { cookies } from "next/headers"

import {
Expand All @@ -19,7 +19,7 @@ export async function saveChatModelAsCookie(model: string) {
export async function generateTitleFromUserMessage({
message,
}: {
message: Message
message: UIMessage
}) {
const { text: title } = await generateText({
model: myProvider.languageModel("title-model"),
Expand Down
162 changes: 81 additions & 81 deletions app/(chat)/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
type Message,
createDataStreamResponse,
smoothStream,
streamText,
} from "ai"
import { type UIMessage, smoothStream, streamText, stepCountIs } from "ai"

import { getSession } from "@/app/(auth)/server-auth"
import { myProvider } from "@/lib/ai/models"
Expand Down Expand Up @@ -34,7 +29,7 @@ export async function POST(request: Request) {
// Parse request body
let requestData: {
id: string
messages: Array<Message>
messages: Array<UIMessage>
selectedChatModel: string
}
try {
Expand Down Expand Up @@ -79,10 +74,18 @@ export async function POST(request: Request) {
return new Response("Failed to create or retrieve chat", { status: 500 })
}

// Save user message
// Save user message to database (convert UIMessage to DB format)
try {
await saveMessages({
messages: [{ ...userMessage, createdAt: new Date(), chatId: id }],
messages: [
{
id: userMessage.id,
role: userMessage.role as any,
content: userMessage.parts,
createdAt: new Date(),
chatId: id,
},
],
})
} catch (error) {
console.error("Failed to save user message:", error)
Expand All @@ -91,85 +94,82 @@ export async function POST(request: Request) {

console.log("selectedChatModel", selectedChatModel)

return createDataStreamResponse({
execute: (dataStream) => {
try {
const result = streamText({
model: myProvider.languageModel(selectedChatModel),
system: systemPrompt({
selectedChatModel,
textAttachmentStrings: getTextAttachmentStrings(messages),
}),
messages: removeTextAttachments(messages),
maxSteps: 5,
temperature: 1, // GPT-5 only supports temperature value of 1
experimental_activeTools: selectedChatModel.includes("reasoning")
? []
: ["createDocument", "updateDocument", "requestSuggestions"],
experimental_transform: smoothStream({ chunking: "word" }),
experimental_generateMessageId: generateUUID,
tools: {
createDocument: createDocument({
session,
dataStream,
selectedModelId: selectedChatModel,
}),
updateDocument: updateDocument({
session,
dataStream,
selectedModelId: selectedChatModel,
}),
requestSuggestions: requestSuggestions({
session,
dataStream,
}),
},
onFinish: async ({ response, reasoning }) => {
if (session.user?.id) {
try {
const sanitizedResponseMessages = sanitizeResponseMessages({
messages: response.messages,
reasoning,
})
// Convert UIMessages to ModelMessage format for the AI SDK
const messagesForAI = messages.map((msg) => ({
role: msg.role as "user" | "assistant" | "system",
content: msg.parts as any,
}))

try {
const result = streamText({
model: myProvider.languageModel(selectedChatModel),

system: systemPrompt({
selectedChatModel,
textAttachmentStrings: getTextAttachmentStrings(messages),
}),

messages: messagesForAI,

// GPT-5 only supports temperature value of 1
temperature: 1,

// Note: Tools integration needs update for v5 dataStream API
// For now, disabling tools to get basic streaming working
// tools: {
// createDocument: createDocument({
// session,
// selectedModelId: selectedChatModel,
// }),
// updateDocument: updateDocument({
// session,
// selectedModelId: selectedChatModel,
// }),
// requestSuggestions: requestSuggestions({
// session,
// }),
// },

onFinish: async ({ response }) => {
if (session.user?.id) {
try {
// In v5, save the assistant response messages
for (const message of response.messages) {
if (message.role === "assistant") {
await saveMessages({
messages: sanitizedResponseMessages.map((message) => {
return {
id: message.id,
messages: [
{
id: generateUUID(),
chatId: id,
role: message.role,
content: message.content,
role: "assistant",
content: message.content as any,
createdAt: new Date(),
}
}),
},
],
})
} catch (error) {
console.error("Failed to save assistant messages:", error)
}
}
},
experimental_telemetry: {
isEnabled: true,
functionId: "stream-text",
},
})

result.mergeIntoDataStream(dataStream, {
sendReasoning: true,
})
} catch (error) {
console.error("Error in streamText execution:", error)
dataStream.writeData({
type: "error",
content: `Error: ${error instanceof Error ? error.message : String(error)}`,
})
}
},
onError: (error) => {
console.error("DataStream error:", error)
return `Error: ${error instanceof Error ? error.message : "An unknown error occurred"}`
},
})
} catch (error) {
console.error("Failed to save assistant messages:", error)
}
}
},

experimental_telemetry: {
isEnabled: true,
functionId: "stream-text",
},
})

// In v5, convert the stream result to a proper response
return result.toTextStreamResponse()
} catch (error) {
console.error("Error in streamText execution:", error)
return new Response(
`Error: ${error instanceof Error ? error.message : String(error)}`,
{ status: 500 },
)
}
} catch (error) {
console.error("Unexpected error in POST handler:", error)
return new Response(
Expand Down
2 changes: 1 addition & 1 deletion app/(chat)/api/files/upload/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { put } from "@vercel/blob"
import { NextResponse } from "next/server"
import { z } from "zod"
import { z } from "zod/v3"

import { getSession } from "@/app/(auth)/server-auth"

Expand Down
26 changes: 19 additions & 7 deletions blocks/code/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { z } from "zod"
import { z } from "zod/v3"
import { streamObject } from "ai"
import { myProvider } from "@/lib/ai/models"
import { codePrompt, updateDocumentPrompt } from "@/lib/ai/prompts/prompts"
Expand Down Expand Up @@ -27,9 +27,15 @@ export const codeDocumentHandler = createDocumentHandler<"code">({
const { code } = object

if (code) {
dataStream.writeData({
type: "code-delta",
content: code ?? "",
dataStream.write({
type: "data",

value: [
{
type: "code-delta",
content: code ?? "",
},
],
})

draftContent = code
Expand Down Expand Up @@ -65,9 +71,15 @@ export const codeDocumentHandler = createDocumentHandler<"code">({
const { code } = object

if (code) {
dataStream.writeData({
type: "code-delta",
content: code ?? "",
dataStream.write({
type: "data",

value: [
{
type: "code-delta",
content: code ?? "",
},
],
})

draftContent = code
Expand Down
24 changes: 18 additions & 6 deletions blocks/image/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ export const imageDocumentHandler = createDocumentHandler<"image">({

draftContent = image.base64

dataStream.writeData({
type: "image-delta",
content: image.base64,
dataStream.write({
type: "data",

value: [
{
type: "image-delta",
content: image.base64,
},
],
})

return draftContent
Expand All @@ -33,9 +39,15 @@ export const imageDocumentHandler = createDocumentHandler<"image">({

draftContent = image.base64

dataStream.writeData({
type: "image-delta",
content: image.base64,
dataStream.write({
type: "data",

value: [
{
type: "image-delta",
content: image.base64,
},
],
})

return draftContent
Expand Down
38 changes: 28 additions & 10 deletions blocks/sheet/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { myProvider } from "@/lib/ai/models"
import { updateDocumentPrompt } from "@/lib/ai/prompts/prompts"
import { createDocumentHandler } from "@/lib/blocks/server"
import { streamObject } from "ai"
import { z } from "zod"
import { z } from "zod/v3"

/**
* @deprecated
Expand All @@ -29,19 +29,31 @@ export const sheetDocumentHandler = createDocumentHandler<"sheet">({
const { csv } = object

if (csv) {
dataStream.writeData({
type: "sheet-delta",
content: csv,
dataStream.write({
type: "data",

value: [
{
type: "sheet-delta",
content: csv,
},
],
})

draftContent = csv
}
}
}

dataStream.writeData({
type: "sheet-delta",
content: draftContent,
dataStream.write({
type: "data",

value: [
{
type: "sheet-delta",
content: draftContent,
},
],
})

return draftContent
Expand All @@ -66,9 +78,15 @@ export const sheetDocumentHandler = createDocumentHandler<"sheet">({
const { csv } = object

if (csv) {
dataStream.writeData({
type: "sheet-delta",
content: csv,
dataStream.write({
type: "data",

value: [
{
type: "sheet-delta",
content: csv,
},
],
})

draftContent = csv
Expand Down
Loading