UNPKG

ai-sdk-ollama

Version:

Vercel AI SDK Provider for Ollama using official ollama-js library

1 lines 44.7 kB
{"version":3,"sources":["../src/index.ts","../src/provider.ts","../src/utils/convert-to-ollama-messages.ts","../src/utils/map-ollama-finish-reason.ts","../src/utils/ollama-error.ts","../src/models/chat-language-model.ts","../src/models/embedding-model.ts"],"sourcesContent":["export {\n createOllama,\n ollama,\n type OllamaProvider,\n type OllamaProviderSettings,\n type OllamaChatSettings,\n type OllamaEmbeddingSettings,\n type OllamaProviderOptions,\n type OllamaChatProviderOptions,\n type OllamaEmbeddingProviderOptions,\n} from './provider';\n\nexport { OllamaChatLanguageModel } from './models/chat-language-model';\nexport type { OllamaChatConfig } from './models/chat-language-model';\nexport { OllamaEmbeddingModel } from './models/embedding-model';\nexport type { OllamaEmbeddingConfig } from './models/embedding-model';\nexport { OllamaError } from './utils/ollama-error';\nexport type { OllamaErrorData } from './utils/ollama-error';\n","import {\n LanguageModelV2,\n EmbeddingModelV2,\n ProviderV2,\n NoSuchModelError,\n} from '@ai-sdk/provider';\nimport { Ollama } from 'ollama';\nimport { OllamaChatLanguageModel } from './models/chat-language-model';\nimport { OllamaEmbeddingModel } from './models/embedding-model';\n\nexport interface OllamaProviderSettings {\n /**\n * Base URL for the Ollama API (defaults to http://127.0.0.1:11434)\n */\n baseURL?: string;\n\n /**\n * Custom headers for API requests\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation\n */\n fetch?: typeof fetch;\n}\n\nexport interface OllamaProvider extends ProviderV2 {\n /**\n * Create a language model instance\n */\n (modelId: string, settings?: OllamaChatSettings): LanguageModelV2;\n\n /**\n * Create a language model instance with the `chat` method\n */\n chat(modelId: string, settings?: OllamaChatSettings): LanguageModelV2;\n\n /**\n * Create a language model instance with the `languageModel` method\n */\n languageModel(\n modelId: string,\n settings?: OllamaChatSettings,\n ): LanguageModelV2;\n\n /**\n * Create an embedding model instance\n */\n embedding(\n modelId: string,\n settings?: OllamaEmbeddingSettings,\n ): EmbeddingModelV2<string>;\n\n /**\n * Create an embedding model instance with the `textEmbedding` method\n */\n textEmbedding(\n modelId: string,\n settings?: OllamaEmbeddingSettings,\n ): EmbeddingModelV2<string>;\n\n /**\n * Create an embedding model instance with the `textEmbeddingModel` method\n */\n textEmbeddingModel(\n modelId: string,\n settings?: OllamaEmbeddingSettings,\n ): EmbeddingModelV2<string>;\n}\n\nexport interface OllamaChatSettings {\n /**\n * Enable structured output mode\n */\n structuredOutputs?: boolean;\n\n /**\n * Enable reasoning support for models that support it\n */\n reasoning?: boolean;\n\n /**\n * Additional model parameters\n */\n options?: {\n num_ctx?: number;\n num_predict?: number;\n temperature?: number;\n top_k?: number;\n top_p?: number;\n min_p?: number;\n seed?: number;\n stop?: string[];\n num_keep?: number;\n typical_p?: number;\n repeat_last_n?: number;\n repeat_penalty?: number;\n presence_penalty?: number;\n frequency_penalty?: number;\n mirostat?: number;\n mirostat_tau?: number;\n mirostat_eta?: number;\n penalize_newline?: boolean;\n numa?: boolean;\n num_thread?: number;\n num_gpu?: number;\n main_gpu?: number;\n low_vram?: boolean;\n f16_kv?: boolean;\n vocab_only?: boolean;\n use_mmap?: boolean;\n use_mlock?: boolean;\n };\n}\n\nexport interface OllamaEmbeddingSettings {\n /**\n * Additional embedding parameters\n */\n options?: {\n num_thread?: number;\n };\n}\n\n/**\n * Options for configuring Ollama provider calls\n */\nexport interface OllamaProviderOptions {\n /**\n * Additional headers to include in requests\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Options for configuring Ollama chat model calls\n */\nexport interface OllamaChatProviderOptions extends OllamaProviderOptions {\n /**\n * Enable structured output mode for object generation\n */\n structuredOutputs?: boolean;\n}\n\n/**\n * Options for configuring Ollama embedding model calls\n */\nexport interface OllamaEmbeddingProviderOptions extends OllamaProviderOptions {\n /**\n * Maximum number of embeddings to process in a single call\n */\n maxEmbeddingsPerCall?: number;\n}\n\n/**\n * Create an Ollama provider instance\n */\nexport function createOllama(\n options: OllamaProviderSettings = {},\n): OllamaProvider {\n const client = new Ollama({\n host: options.baseURL,\n fetch: options.fetch,\n headers: options.headers,\n });\n\n const createChatModel = (\n modelId: string,\n settings: OllamaChatSettings = {},\n ) => {\n return new OllamaChatLanguageModel(modelId, settings, {\n client,\n provider: 'ollama',\n });\n };\n\n const createEmbeddingModel = (\n modelId: string,\n settings: OllamaEmbeddingSettings = {},\n ) => {\n return new OllamaEmbeddingModel(modelId, settings, {\n client,\n provider: 'ollama',\n });\n };\n\n const provider = function (modelId: string, settings?: OllamaChatSettings) {\n if (new.target) {\n throw new Error(\n 'The Ollama provider cannot be called with the new keyword.',\n );\n }\n return createChatModel(modelId, settings);\n };\n\n provider.chat = createChatModel;\n provider.languageModel = createChatModel;\n provider.embedding = createEmbeddingModel;\n provider.textEmbedding = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n provider.imageModel = (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'imageModel',\n message: 'Image generation is not supported by Ollama',\n });\n };\n\n return provider as OllamaProvider;\n}\n\n/**\n * Default Ollama provider instance\n */\nexport const ollama = createOllama();\n","import { LanguageModelV2Prompt } from '@ai-sdk/provider';\nimport { Message as OllamaMessage } from 'ollama';\n\n/**\n * Enhanced message conversion that supports all Ollama capabilities\n * and handles edge cases better than the referenced implementation\n */\nexport function convertToOllamaChatMessages(\n prompt: LanguageModelV2Prompt,\n): OllamaMessage[] {\n const messages: OllamaMessage[] = [];\n\n for (const message of prompt) {\n switch (message.role) {\n case 'system': {\n messages.push({\n role: 'system',\n content: message.content,\n });\n break;\n }\n\n case 'user': {\n if (typeof message.content === 'string') {\n messages.push({\n role: 'user',\n content: message.content,\n });\n } else {\n // Handle multi-part content with enhanced image support\n const textParts = message.content\n .filter((part) => part.type === 'text')\n .map((part) => part.text)\n .join('\\n');\n\n const imageParts = message.content\n .filter(\n (part): part is Extract<typeof part, { type: 'file' }> =>\n part.type === 'file',\n )\n .filter((part) => {\n // Support image files only\n return part.mediaType?.startsWith('image/') || false;\n })\n .map((part) => {\n const imageData = part.data;\n\n if (imageData instanceof URL) {\n // Handle image URLs - extract base64 from data URLs or use URL directly\n if (imageData.protocol === 'data:') {\n const base64Match = imageData.href.match(\n /data:[^;]+;base64,(.+)/,\n );\n if (base64Match) {\n return base64Match[1]; // Return just the base64 part\n }\n // If no base64 match, return the full data URL\n return imageData.href;\n }\n // For HTTP URLs, return as-is (Ollama will handle them)\n return imageData.href;\n } else if (typeof imageData === 'string') {\n // Handle base64 strings\n if (imageData.startsWith('data:')) {\n const base64Match = imageData.match(/data:[^;]+;base64,(.+)/);\n if (base64Match) {\n return base64Match[1]; // Return just the base64 part\n }\n }\n return imageData;\n } else if (imageData instanceof Uint8Array) {\n // Handle Uint8Array by converting to base64\n return Buffer.from(imageData).toString('base64');\n } else {\n // Fallback for other types\n console.warn(\n `Unsupported image data type: ${typeof imageData}`,\n );\n return null;\n }\n })\n .filter((img): img is string => img !== null);\n\n messages.push({\n role: 'user',\n content: textParts || '', // Ensure content is never undefined\n images: imageParts.length > 0 ? imageParts : undefined,\n });\n }\n break;\n }\n\n case 'assistant': {\n let content = '';\n\n if (typeof message.content === 'string') {\n content = message.content;\n } else {\n // Enhanced content handling with better tool call support\n const textParts = message.content\n .filter((part) => part.type === 'text')\n .map((part) => part.text)\n .join('');\n\n const reasoningParts = message.content\n .filter((part) => part.type === 'reasoning')\n .map((part) => part.text)\n .join('\\n');\n\n // Combine text and reasoning\n content = [textParts, reasoningParts].filter(Boolean).join('\\n');\n\n // Handle tool calls if present\n const toolCalls = message.content.filter(\n (part) => part.type === 'tool-call',\n );\n if (toolCalls.length > 0) {\n // For now, we'll append tool calls as text since Ollama doesn't have native support\n const toolCallText = toolCalls\n .map((tc) => `[Tool Call: ${tc.toolName}]`)\n .join('\\n');\n if (toolCallText) {\n content = content ? `${content}\\n${toolCallText}` : toolCallText;\n }\n }\n }\n\n messages.push({\n role: 'assistant',\n content: content || '', // Ensure content is never undefined\n });\n break;\n }\n\n case 'tool': {\n // Enhanced tool result handling\n if (typeof message.content === 'string') {\n messages.push({\n role: 'user', // Ollama doesn't have native tool role, so we use user\n content: `[Tool Result]: ${message.content}`,\n });\n } else {\n // Handle multi-part tool results\n const toolResultParts = message.content\n .filter((part) => part.type === 'tool-result')\n .map((part) => {\n if (part.output.type === 'text') {\n return part.output.value;\n } else if (part.output.type === 'json') {\n return JSON.stringify(part.output.value);\n }\n return String(part.output.value);\n })\n .join('\\n');\n\n messages.push({\n role: 'user',\n content: `[Tool Result]: ${toolResultParts || ''}`,\n });\n }\n break;\n }\n\n default: {\n // Enhanced error handling with more descriptive messages\n const role = (message as { role: string }).role;\n throw new Error(\n `Unsupported message role: ${role}. Supported roles are: system, user, assistant, tool`,\n );\n }\n }\n }\n\n return messages;\n}\n","import { LanguageModelV2FinishReason } from '@ai-sdk/provider';\n\nexport function mapOllamaFinishReason(\n reason?: string | null,\n): LanguageModelV2FinishReason {\n if (!reason) return 'unknown';\n\n switch (reason) {\n case 'stop': {\n return 'stop';\n }\n case 'length': {\n return 'length';\n }\n default: {\n return 'unknown';\n }\n }\n}\n","export interface OllamaErrorData {\n message: string;\n code?: string;\n details?: unknown;\n}\n\nexport class OllamaError extends Error {\n readonly cause?: unknown;\n readonly data?: OllamaErrorData;\n\n constructor({\n message,\n cause,\n data,\n }: {\n message: string;\n cause?: unknown;\n data?: OllamaErrorData;\n }) {\n super(message);\n this.name = 'OllamaError';\n this.cause = cause;\n this.data = data;\n }\n\n static isOllamaError(error: unknown): error is OllamaError {\n return error instanceof OllamaError;\n }\n}\n","import {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2CallWarning,\n LanguageModelV2FinishReason,\n LanguageModelV2StreamPart,\n LanguageModelV2Usage,\n LanguageModelV2Content,\n JSONValue,\n} from '@ai-sdk/provider';\nimport { Ollama, Message as OllamaMessage, ChatResponse, Tool } from 'ollama';\nimport { OllamaChatSettings } from '../provider';\nimport { convertToOllamaChatMessages } from '../utils/convert-to-ollama-messages';\nimport { mapOllamaFinishReason } from '../utils/map-ollama-finish-reason';\nimport { OllamaError } from '../utils/ollama-error';\n\nexport interface OllamaChatConfig {\n client: Ollama;\n provider: string;\n}\n\nexport class OllamaChatLanguageModel implements LanguageModelV2 {\n readonly specificationVersion = 'v2' as const;\n readonly defaultObjectGenerationMode = 'json';\n readonly supportsImages = true; // ✅ Ollama supports images (URLs, files, base64)\n readonly supportsVideoURLs = false; // ❌ Not supported by Ollama API\n readonly supportsAudioURLs = false; // ❌ Not supported by Ollama API\n readonly supportsVideoFile = false; // ❌ Not supported by Ollama API\n readonly supportsAudioFile = false; // ❌ Not supported by Ollama API\n readonly supportsImageFile = true; // ✅ Already correct\n readonly supportedUrls: Record<string, RegExp[]> = {\n // Support common image URL patterns\n image: [\n /^https?:\\/\\/.*\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i,\n /^data:image\\/[^;]+;base64,/i, // Data URLs\n ],\n };\n\n constructor(\n public readonly modelId: string,\n public readonly settings: OllamaChatSettings,\n private readonly config: OllamaChatConfig,\n ) {}\n\n get provider(): string {\n return this.config.provider;\n }\n\n get supportsStructuredOutputs(): boolean {\n // Auto-detect structured outputs when JSON schema is provided\n // This allows generateObject and streamObject to work without explicit structuredOutputs: true\n return this.settings.structuredOutputs ?? false;\n }\n\n /**\n * Check if structured outputs should be enabled based on the call options\n * This is used internally to auto-detect when structured outputs are needed\n */\n private shouldEnableStructuredOutputs(\n options: LanguageModelV2CallOptions,\n ): boolean {\n // Auto-detect: if we have a JSON schema, we need structured outputs\n // This overrides explicit settings to ensure object generation works\n if (\n options.responseFormat?.type === 'json' &&\n options.responseFormat.schema\n ) {\n // Warn if structuredOutputs was explicitly set to false but we're auto-enabling it\n if (this.settings.structuredOutputs === false) {\n console.warn(\n 'Ollama: structuredOutputs was set to false but auto-enabled for object generation. ' +\n 'This ensures generateObject and streamObject work correctly.',\n );\n }\n return true;\n }\n\n // If explicitly set, use that value (for text generation)\n if (this.settings.structuredOutputs !== undefined) {\n return this.settings.structuredOutputs;\n }\n\n // Default to false for regular text generation\n return false;\n }\n\n private getCallOptions(options: LanguageModelV2CallOptions): {\n messages: OllamaMessage[];\n options: Record<string, unknown>;\n format?: string | Record<string, unknown>;\n tools?: Tool[];\n warnings: LanguageModelV2CallWarning[];\n } {\n const {\n prompt,\n temperature,\n maxOutputTokens,\n topP,\n topK,\n frequencyPenalty,\n presencePenalty,\n stopSequences,\n seed,\n responseFormat,\n tools,\n } = options;\n\n const warnings: LanguageModelV2CallWarning[] = [];\n\n // Auto-detect structured outputs when JSON schema is provided\n const needsStructuredOutputs = this.shouldEnableStructuredOutputs(options);\n\n // Check for unsupported features and throw errors\n if (\n responseFormat?.type === 'json' &&\n responseFormat.schema &&\n !needsStructuredOutputs\n ) {\n throw new Error(\n 'JSON schema is only supported when structuredOutputs is enabled',\n );\n }\n\n // Convert AI SDK tools to Ollama format (error already thrown if unsupported)\n const ollamaTools: Tool[] | undefined = tools\n ? tools.map((tool): Tool => {\n if (tool.type === 'function') {\n // The inputSchema from AI SDK should already be a JSON schema\n // when tools are passed to providers\n let jsonSchema: Record<string, unknown>;\n\n // Check if we have a Zod schema (has parse method) or a JSON schema\n if (tool.inputSchema && typeof tool.inputSchema === 'object') {\n if (\n 'parse' in tool.inputSchema &&\n typeof tool.inputSchema.parse === 'function'\n ) {\n // It's a Zod schema - we need to convert it\n // For now, we'll use a basic fallback since zod-to-json-schema has version issues\n console.warn(\n `Tool ${tool.name} is using a Zod schema directly. Schema conversion may not work properly due to Zod version mismatch.`,\n );\n jsonSchema = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n };\n } else if (\n 'properties' in tool.inputSchema ||\n 'type' in tool.inputSchema\n ) {\n // It looks like a JSON schema already\n jsonSchema = tool.inputSchema as Record<string, unknown>;\n } else {\n // Unknown schema format\n jsonSchema = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n };\n }\n } else {\n // No schema provided\n jsonSchema = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n };\n }\n\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: jsonSchema,\n },\n };\n }\n // Provider-defined tools not supported by Ollama\n throw new Error(\n `Provider-defined tools are not supported by Ollama. Use function tools instead.`,\n );\n })\n : undefined;\n\n // Build options with correct precedence:\n // 1. AI SDK call parameters (mapped to Ollama equivalents)\n // 2. Model settings (Ollama options) override AI SDK parameters when both are specified\n const ollamaOptions: Record<string, unknown> = {\n // Start with AI SDK parameters mapped to Ollama names\n ...(temperature !== undefined && { temperature }),\n ...(maxOutputTokens !== undefined && { num_predict: maxOutputTokens }),\n ...(topP !== undefined && { top_p: topP }),\n ...(topK !== undefined && { top_k: topK }),\n ...(frequencyPenalty !== undefined && {\n frequency_penalty: frequencyPenalty,\n }),\n ...(presencePenalty !== undefined && {\n presence_penalty: presencePenalty,\n }),\n ...(stopSequences !== undefined && { stop: stopSequences }),\n ...(seed !== undefined && { seed }),\n // Ollama model options override AI SDK parameters\n ...this.settings.options,\n };\n\n // Remove undefined values\n for (const key of Object.keys(ollamaOptions)) {\n if (ollamaOptions[key] === undefined) {\n delete ollamaOptions[key];\n }\n }\n\n let format: string | Record<string, unknown> | undefined;\n if (responseFormat?.type === 'json') {\n format =\n responseFormat.schema && needsStructuredOutputs\n ? (responseFormat.schema as Record<string, unknown>)\n : 'json';\n }\n\n const messages = convertToOllamaChatMessages(prompt);\n\n return {\n messages,\n options: ollamaOptions,\n format,\n tools: ollamaTools,\n warnings,\n };\n }\n\n async doGenerate(options: LanguageModelV2CallOptions): Promise<{\n content: LanguageModelV2Content[];\n finishReason: LanguageModelV2FinishReason;\n usage: LanguageModelV2Usage;\n providerMetadata?: Record<string, Record<string, JSONValue>>;\n request?: { body: string };\n response?: { id?: string; timestamp?: Date; modelId?: string };\n warnings: LanguageModelV2CallWarning[];\n }> {\n const {\n messages,\n options: ollamaOptions,\n format,\n tools,\n warnings,\n } = this.getCallOptions(options);\n\n try {\n const response = (await this.config.client.chat({\n model: this.modelId,\n messages,\n options: ollamaOptions,\n format,\n tools,\n stream: false,\n })) as ChatResponse;\n\n const text = response.message.content;\n const toolCalls = response.message.tool_calls;\n const thinking = response.message.thinking;\n\n // Convert content based on whether we have tool calls, reasoning, or text\n const content: LanguageModelV2Content[] = [];\n\n // Add reasoning content if present and enabled\n if (thinking && this.settings.reasoning) {\n content.push({ type: 'reasoning', text: thinking });\n }\n\n // Add text content if present\n if (text) {\n content.push({ type: 'text', text });\n }\n\n // Add tool calls if present\n if (toolCalls && toolCalls.length > 0) {\n for (const toolCall of toolCalls) {\n const toolInput = toolCall.function.arguments || {};\n\n content.push({\n type: 'tool-call',\n toolCallId: crypto.randomUUID(), // Ollama doesn't provide IDs\n toolName: toolCall.function.name,\n input: JSON.stringify(toolInput),\n });\n }\n }\n\n return {\n content,\n finishReason: mapOllamaFinishReason(\n response.done_reason,\n ) as LanguageModelV2FinishReason,\n usage: {\n inputTokens: response.prompt_eval_count || 0,\n outputTokens: response.eval_count || 0,\n totalTokens:\n (response.prompt_eval_count || 0) + (response.eval_count || 0),\n },\n providerMetadata: {\n ollama: {\n model: response.model,\n created_at: response.created_at\n ? new Date(response.created_at).toISOString()\n : undefined,\n total_duration: response.total_duration,\n load_duration: response.load_duration,\n eval_duration: response.eval_duration,\n } as Record<string, JSONValue>,\n },\n request: {\n body: JSON.stringify({\n model: this.modelId,\n messages,\n options: ollamaOptions,\n format,\n tools,\n }),\n },\n response: {\n timestamp: new Date(),\n modelId: this.modelId,\n },\n warnings,\n };\n } catch (error) {\n throw new OllamaError({\n message: error instanceof Error ? error.message : String(error),\n cause: error,\n });\n }\n }\n\n async doStream(options: LanguageModelV2CallOptions): Promise<{\n stream: ReadableStream<LanguageModelV2StreamPart>;\n rawCall: {\n rawPrompt: unknown;\n rawSettings: Record<string, unknown>;\n };\n warnings?: LanguageModelV2CallWarning[];\n }> {\n const {\n messages,\n options: ollamaOptions,\n format,\n tools,\n warnings,\n } = this.getCallOptions(options);\n\n try {\n const stream = await this.config.client.chat({\n model: this.modelId,\n messages,\n options: ollamaOptions,\n format,\n tools,\n stream: true,\n });\n\n let usage: LanguageModelV2Usage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n let finishReason: LanguageModelV2FinishReason = 'unknown';\n\n // Capture settings for use in transform function\n const reasoningEnabled = this.settings.reasoning;\n\n const transformStream = new TransformStream<\n ChatResponse,\n LanguageModelV2StreamPart\n >({\n async transform(chunk: ChatResponse, controller) {\n // Validate chunk\n if (!chunk || typeof chunk !== 'object') {\n return; // Skip invalid chunks\n }\n\n // Regular chunk with content\n if (chunk.done) {\n // If the final chunk carries residual content, emit it before finish\n if (\n chunk.message &&\n typeof chunk.message.content === 'string' &&\n chunk.message.content.length > 0\n ) {\n controller.enqueue({\n type: 'text-delta',\n id: crypto.randomUUID(),\n delta: chunk.message.content,\n });\n }\n\n // Final chunk with metadata\n usage = {\n inputTokens: chunk.prompt_eval_count || 0,\n outputTokens: chunk.eval_count || 0,\n totalTokens:\n (chunk.prompt_eval_count || 0) + (chunk.eval_count || 0),\n };\n finishReason = mapOllamaFinishReason(\n chunk.done_reason,\n ) as LanguageModelV2FinishReason;\n\n controller.enqueue({\n type: 'finish',\n finishReason,\n usage,\n });\n } else {\n // Handle reasoning in streaming\n if (chunk.message.thinking && reasoningEnabled) {\n // For reasoning, we'll emit it as a single reasoning content\n // since Ollama doesn't stream reasoning in chunks\n controller.enqueue({\n type: 'reasoning-start',\n id: crypto.randomUUID(),\n });\n\n controller.enqueue({\n type: 'reasoning-delta',\n id: crypto.randomUUID(),\n delta: chunk.message.thinking,\n });\n\n controller.enqueue({\n type: 'reasoning-end',\n id: crypto.randomUUID(),\n });\n }\n\n // Handle tool calls in streaming\n if (\n chunk.message.tool_calls &&\n chunk.message.tool_calls.length > 0\n ) {\n for (const toolCall of chunk.message.tool_calls) {\n const toolInput = toolCall.function.arguments || {};\n\n controller.enqueue({\n type: 'tool-call',\n toolCallId: crypto.randomUUID(), // Ollama doesn't provide IDs\n toolName: toolCall.function.name,\n input: JSON.stringify(toolInput),\n });\n }\n }\n\n // Handle text content in streaming (always emit if present)\n if (\n chunk.message.content &&\n typeof chunk.message.content === 'string' &&\n chunk.message.content.length > 0\n ) {\n controller.enqueue({\n type: 'text-delta',\n id: crypto.randomUUID(), // Generate unique ID for each text chunk\n delta: chunk.message.content,\n });\n }\n }\n },\n });\n\n // Create a readable stream from the async generator\n const readableStream = new ReadableStream({\n async start(controller) {\n try {\n for await (const chunk of stream) {\n // Ensure chunk is valid before enqueuing\n if (chunk && typeof chunk === 'object') {\n controller.enqueue(chunk);\n }\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return {\n stream: readableStream.pipeThrough(transformStream),\n rawCall: {\n rawPrompt: messages,\n rawSettings: {\n model: this.modelId,\n options: ollamaOptions,\n format,\n tools,\n },\n },\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n } catch (error) {\n throw new OllamaError({\n message: error instanceof Error ? error.message : String(error),\n cause: error,\n });\n }\n }\n}\n","import { EmbeddingModelV2, EmbeddingModelV2Embedding } from '@ai-sdk/provider';\nimport { Ollama } from 'ollama';\nimport { OllamaEmbeddingSettings } from '../provider';\nimport { OllamaError } from '../utils/ollama-error';\n\nexport interface OllamaEmbeddingConfig {\n client: Ollama;\n provider: string;\n}\n\nexport class OllamaEmbeddingModel implements EmbeddingModelV2<string> {\n readonly specificationVersion = 'v2' as const;\n readonly modelId: string;\n readonly maxEmbeddingsPerCall = 2048;\n readonly supportsParallelCalls = true;\n\n constructor(\n modelId: string,\n private readonly settings: OllamaEmbeddingSettings,\n private readonly config: OllamaEmbeddingConfig,\n ) {\n this.modelId = modelId;\n }\n\n get provider(): string {\n return this.config.provider;\n }\n\n async doEmbed(params: {\n values: string[];\n abortSignal?: AbortSignal;\n }): Promise<{\n embeddings: EmbeddingModelV2Embedding[];\n }> {\n const { values, abortSignal } = params;\n if (values.length > this.maxEmbeddingsPerCall) {\n throw new OllamaError({\n message: `Too many values to embed. Maximum: ${this.maxEmbeddingsPerCall}, Received: ${values.length}`,\n });\n }\n\n // Handle empty array case\n if (values.length === 0) {\n return { embeddings: [] };\n }\n\n try {\n const embeddings: EmbeddingModelV2Embedding[] = [];\n\n // Ollama's embed API currently only supports single prompts\n // So we need to make multiple requests\n for (const value of values) {\n // Skip undefined values (AI SDK interface issue workaround)\n if (value === undefined || value === null) {\n continue;\n }\n\n const response = await this.config.client.embed({\n model: this.modelId,\n input: value,\n options: this.settings.options,\n });\n\n if (!response.embeddings) {\n throw new OllamaError({\n message: `No embeddings field in response`,\n });\n }\n\n if (response.embeddings.length === 0) {\n throw new OllamaError({\n message: `Empty embeddings array returned`,\n });\n }\n\n embeddings.push(response.embeddings[0] as number[]);\n\n // Check if we should abort\n if (abortSignal?.aborted) {\n throw new Error('Embedding generation aborted');\n }\n }\n\n if (embeddings.length === 0) {\n throw new OllamaError({\n message: `No valid values provided for embedding (all were undefined/null)`,\n });\n }\n\n return {\n embeddings,\n };\n } catch (error) {\n if (error instanceof OllamaError) {\n throw error;\n }\n\n throw new OllamaError({\n message: error instanceof Error ? error.message : String(error),\n cause: error,\n });\n }\n }\n}\n"],"mappings":"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","names":[]}