UNPKG

@ai-sdk/groq

Version:

The **[Groq provider](https://ai-sdk.dev/providers/ai-sdk-providers/groq)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for the Groq chat and completion APIs, transcription support, and browser search tool.

164 lines (146 loc) 4.62 kB
import { UnsupportedFunctionalityError, type LanguageModelV4Prompt, } from '@ai-sdk/provider'; import type { GroqChatPrompt } from './groq-api-types'; import { convertToBase64, getTopLevelMediaType, resolveFullMediaType, } from '@ai-sdk/provider-utils'; export function convertToGroqChatMessages( prompt: LanguageModelV4Prompt, ): GroqChatPrompt { const messages: GroqChatPrompt = []; for (const { role, content } of prompt) { switch (role) { case 'system': { messages.push({ role: 'system', content }); break; } case 'user': { if (content.length === 1 && content[0].type === 'text') { messages.push({ role: 'user', content: content[0].text }); break; } messages.push({ role: 'user', content: content.map(part => { switch (part.type) { case 'text': { return { type: 'text', text: part.text }; } case 'file': { switch (part.data.type) { case 'reference': { throw new UnsupportedFunctionalityError({ functionality: 'file parts with provider references', }); } case 'text': { throw new UnsupportedFunctionalityError({ functionality: 'text file parts', }); } case 'url': case 'data': { if (getTopLevelMediaType(part.mediaType) !== 'image') { throw new UnsupportedFunctionalityError({ functionality: 'Non-image file content parts', }); } return { type: 'image_url', image_url: { url: part.data.type === 'url' ? part.data.url.toString() : `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`, }, }; } } } } }), }); break; } case 'assistant': { let text = ''; let reasoning = ''; const toolCalls: Array<{ id: string; type: 'function'; function: { name: string; arguments: string }; }> = []; for (const part of content) { switch (part.type) { // groq supports reasoning for tool-calls in multi-turn conversations // https://github.com/vercel/ai/issues/7860 case 'reasoning': { reasoning += part.text; break; } case 'text': { text += part.text; break; } case 'tool-call': { toolCalls.push({ id: part.toolCallId, type: 'function', function: { name: part.toolName, arguments: JSON.stringify(part.input), }, }); break; } } } messages.push({ role: 'assistant', content: text, ...(reasoning.length > 0 ? { reasoning } : null), ...(toolCalls.length > 0 ? { tool_calls: toolCalls } : null), }); break; } case 'tool': { for (const toolResponse of content) { if (toolResponse.type === 'tool-approval-response') { continue; } const output = toolResponse.output; let contentValue: string; switch (output.type) { case 'text': case 'error-text': contentValue = output.value; break; case 'execution-denied': contentValue = output.reason ?? 'Tool call execution denied.'; break; case 'content': case 'json': case 'error-json': contentValue = JSON.stringify(output.value); break; } messages.push({ role: 'tool', tool_call_id: toolResponse.toolCallId, content: contentValue, }); } break; } default: { const _exhaustiveCheck: never = role; throw new Error(`Unsupported role: ${_exhaustiveCheck}`); } } } return messages; }