UNPKG

@assistant-ui/react

Version:

React components for AI chat.

126 lines (115 loc) 3.6 kB
import { LanguageModelV1Message } from "@ai-sdk/provider"; import { CoreMessage, ToolCallContentPart } from "../../../types"; type fromLanguageModelMessagesOptions = { mergeSteps: boolean; }; export const fromLanguageModelMessages = ( lm: LanguageModelV1Message[], { mergeSteps }: fromLanguageModelMessagesOptions, ): CoreMessage[] => { const messages: CoreMessage[] = []; for (const lmMessage of lm) { const role = lmMessage.role; switch (role) { case "system": { messages.push({ role: "system", content: [ { type: "text", text: lmMessage.content, }, ], }); break; } case "user": { messages.push({ role: "user", content: lmMessage.content.map((part) => { const type = part.type; switch (type) { case "text": { return { type: "text", text: part.text, }; } case "image": { if (part.image instanceof URL) { return { type: "image", image: part.image.href, }; } throw new Error("Only images with URL data are supported"); } case "file": { // TODO throw new Error("File content parts are not supported"); } default: { const unhandledType: never = type; throw new Error(`Unknown content part type: ${unhandledType}`); } } }), }); break; } case "assistant": { const newContent = lmMessage.content.map((part) => { if (part.type === "tool-call") { return { type: "tool-call", toolCallId: part.toolCallId, toolName: part.toolName, argsText: JSON.stringify(part.args), args: part.args as Record<string, unknown>, } satisfies ToolCallContentPart; } return part; }); if (mergeSteps) { const previousMessage = messages[messages.length - 1]; if (previousMessage?.role === "assistant") { previousMessage.content.push(...newContent); break; } } messages.push({ role: "assistant", content: newContent, }); break; } case "tool": { const previousMessage = messages[messages.length - 1]; if (previousMessage?.role !== "assistant") throw new Error( "A tool message must be preceded by an assistant message.", ); for (const tool of lmMessage.content) { const toolCall = previousMessage.content.find( (c): c is ToolCallContentPart => c.type === "tool-call" && c.toolCallId === tool.toolCallId, ); if (!toolCall) throw new Error("Received tool result for an unknown tool call."); if (toolCall.toolName !== tool.toolName) throw new Error("Tool call name mismatch."); toolCall.result = tool.result; if (tool.isError) { toolCall.isError = true; } } break; } default: { const unhandledRole: never = role; throw new Error(`Unknown message role: ${unhandledRole}`); } } } return messages; };