ai-sdk-ollama 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/index.browser.cjs +2 -1
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.d.cts +19 -35
- package/dist/index.browser.d.ts +19 -35
- package/dist/index.browser.js +2 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -36
- package/dist/index.d.ts +20 -36
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0e2f392: Fix TypeScript compilation errors in examples
|
|
8
|
+
- Fixed variable naming conflicts in stream-vs-generate-test.ts, debug-streaming-issue.ts, generate-all-ollama-demo.ts, stream-object-ollama-demo.ts, and stream-text-ollama-demo.ts
|
|
9
|
+
- Fixed undefined variable 'ollamaRaw' in existing-client-example.ts
|
|
10
|
+
- Fixed browser example to use createOllama() instead of passing baseURL to ollama() function
|
|
11
|
+
- Fixed async tool calls access in streaming examples
|
|
12
|
+
- Fixed Zod schema definitions for record types
|
|
13
|
+
- All examples now compile and run successfully
|
|
14
|
+
|
|
15
|
+
## 0.6.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 80fbf5b: Update to ollama-0.5.18
|
|
20
|
+
- Updated Ollama provider to support version 0.5.18
|
|
21
|
+
- Enhanced embedding model functionality
|
|
22
|
+
- Improved provider implementation with better error handling
|
|
23
|
+
- Updated examples to demonstrate new features
|
|
24
|
+
|
|
3
25
|
## 0.6.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/dist/index.browser.cjs
CHANGED
|
@@ -581,7 +581,8 @@ var OllamaEmbeddingModel = class {
|
|
|
581
581
|
const response = await this.config.client.embed({
|
|
582
582
|
model: this.modelId,
|
|
583
583
|
input: value,
|
|
584
|
-
options: this.settings.options
|
|
584
|
+
options: this.settings.options,
|
|
585
|
+
...this.settings.dimensions !== void 0 && { dimensions: this.settings.dimensions }
|
|
585
586
|
});
|
|
586
587
|
if (!response.embeddings) {
|
|
587
588
|
throw new OllamaError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.browser.ts","../src/provider.browser.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":["// Browser entry point - uses ollama/browser\nexport {\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.browser';\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","// Browser-specific provider that uses ollama/browser\nimport { NoSuchModelError } from '@ai-sdk/provider';\nimport { Ollama } from 'ollama/browser';\nimport { OllamaChatLanguageModel } from './models/chat-language-model';\nimport { OllamaEmbeddingModel } from './models/embedding-model';\n\n// Re-export all the types\nexport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n OllamaProviderOptions,\n OllamaChatProviderOptions,\n OllamaEmbeddingProviderOptions,\n} from './provider';\n\n// Import types only to avoid duplication\nimport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n} from './provider';\n\n/**\n * Create an Ollama provider instance for browser environments\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 }) as any; // Cast to any to bypass type checking differences\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 for browser environments\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":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.browser.ts","../src/provider.browser.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":["// Browser entry point - uses ollama/browser\nexport {\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.browser';\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","// Browser-specific provider that uses ollama/browser\nimport { NoSuchModelError } from '@ai-sdk/provider';\nimport { Ollama } from 'ollama/browser';\nimport { OllamaChatLanguageModel } from './models/chat-language-model';\nimport { OllamaEmbeddingModel } from './models/embedding-model';\n\n// Re-export all the types\nexport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n OllamaProviderOptions,\n OllamaChatProviderOptions,\n OllamaEmbeddingProviderOptions,\n} from './provider';\n\n// Import types only to avoid duplication\nimport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n} from './provider';\n\n/**\n * Create an Ollama provider instance for browser environments\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 }) as any; // Cast to any to bypass type checking differences\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 for browser environments\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 ...(this.settings.dimensions !== undefined && { dimensions: this.settings.dimensions }),\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":[]}
|
package/dist/index.browser.d.cts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ProviderV2, LanguageModelV2, EmbeddingModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, JSONValue, LanguageModelV2CallWarning, LanguageModelV2StreamPart, EmbeddingModelV2Embedding } from '@ai-sdk/provider';
|
|
2
|
-
import { Ollama } from 'ollama';
|
|
2
|
+
import { Ollama, Options as Options$1 } from 'ollama';
|
|
3
|
+
|
|
4
|
+
interface Options extends Options$1 {
|
|
5
|
+
/**
|
|
6
|
+
* Minimum probability threshold for token selection
|
|
7
|
+
* This parameter is supported by Ollama API but missing from ollama-js TypeScript definitions
|
|
8
|
+
*/
|
|
9
|
+
min_p?: number;
|
|
10
|
+
}
|
|
3
11
|
|
|
4
12
|
interface OllamaProviderSettings {
|
|
5
13
|
/**
|
|
@@ -55,45 +63,21 @@ interface OllamaChatSettings {
|
|
|
55
63
|
*/
|
|
56
64
|
reasoning?: boolean;
|
|
57
65
|
/**
|
|
58
|
-
* Additional model parameters
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
num_predict?: number;
|
|
63
|
-
temperature?: number;
|
|
64
|
-
top_k?: number;
|
|
65
|
-
top_p?: number;
|
|
66
|
-
min_p?: number;
|
|
67
|
-
seed?: number;
|
|
68
|
-
stop?: string[];
|
|
69
|
-
num_keep?: number;
|
|
70
|
-
typical_p?: number;
|
|
71
|
-
repeat_last_n?: number;
|
|
72
|
-
repeat_penalty?: number;
|
|
73
|
-
presence_penalty?: number;
|
|
74
|
-
frequency_penalty?: number;
|
|
75
|
-
mirostat?: number;
|
|
76
|
-
mirostat_tau?: number;
|
|
77
|
-
mirostat_eta?: number;
|
|
78
|
-
penalize_newline?: boolean;
|
|
79
|
-
numa?: boolean;
|
|
80
|
-
num_thread?: number;
|
|
81
|
-
num_gpu?: number;
|
|
82
|
-
main_gpu?: number;
|
|
83
|
-
low_vram?: boolean;
|
|
84
|
-
f16_kv?: boolean;
|
|
85
|
-
vocab_only?: boolean;
|
|
86
|
-
use_mmap?: boolean;
|
|
87
|
-
use_mlock?: boolean;
|
|
88
|
-
};
|
|
66
|
+
* Additional model parameters - re-exported from ollama-js
|
|
67
|
+
* This automatically includes ALL Ollama parameters including new ones like 'dimensions'
|
|
68
|
+
*/
|
|
69
|
+
options?: Partial<Options>;
|
|
89
70
|
}
|
|
90
71
|
interface OllamaEmbeddingSettings {
|
|
91
72
|
/**
|
|
92
73
|
* Additional embedding parameters
|
|
93
74
|
*/
|
|
94
|
-
options?:
|
|
95
|
-
|
|
96
|
-
|
|
75
|
+
options?: Partial<Options>;
|
|
76
|
+
/**
|
|
77
|
+
* Dimensions for embedding output (if supported by the model)
|
|
78
|
+
* This is a direct parameter of EmbedRequest, not part of Options
|
|
79
|
+
*/
|
|
80
|
+
dimensions?: number;
|
|
97
81
|
}
|
|
98
82
|
/**
|
|
99
83
|
* Options for configuring Ollama provider calls
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ProviderV2, LanguageModelV2, EmbeddingModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, JSONValue, LanguageModelV2CallWarning, LanguageModelV2StreamPart, EmbeddingModelV2Embedding } from '@ai-sdk/provider';
|
|
2
|
-
import { Ollama } from 'ollama';
|
|
2
|
+
import { Ollama, Options as Options$1 } from 'ollama';
|
|
3
|
+
|
|
4
|
+
interface Options extends Options$1 {
|
|
5
|
+
/**
|
|
6
|
+
* Minimum probability threshold for token selection
|
|
7
|
+
* This parameter is supported by Ollama API but missing from ollama-js TypeScript definitions
|
|
8
|
+
*/
|
|
9
|
+
min_p?: number;
|
|
10
|
+
}
|
|
3
11
|
|
|
4
12
|
interface OllamaProviderSettings {
|
|
5
13
|
/**
|
|
@@ -55,45 +63,21 @@ interface OllamaChatSettings {
|
|
|
55
63
|
*/
|
|
56
64
|
reasoning?: boolean;
|
|
57
65
|
/**
|
|
58
|
-
* Additional model parameters
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
num_predict?: number;
|
|
63
|
-
temperature?: number;
|
|
64
|
-
top_k?: number;
|
|
65
|
-
top_p?: number;
|
|
66
|
-
min_p?: number;
|
|
67
|
-
seed?: number;
|
|
68
|
-
stop?: string[];
|
|
69
|
-
num_keep?: number;
|
|
70
|
-
typical_p?: number;
|
|
71
|
-
repeat_last_n?: number;
|
|
72
|
-
repeat_penalty?: number;
|
|
73
|
-
presence_penalty?: number;
|
|
74
|
-
frequency_penalty?: number;
|
|
75
|
-
mirostat?: number;
|
|
76
|
-
mirostat_tau?: number;
|
|
77
|
-
mirostat_eta?: number;
|
|
78
|
-
penalize_newline?: boolean;
|
|
79
|
-
numa?: boolean;
|
|
80
|
-
num_thread?: number;
|
|
81
|
-
num_gpu?: number;
|
|
82
|
-
main_gpu?: number;
|
|
83
|
-
low_vram?: boolean;
|
|
84
|
-
f16_kv?: boolean;
|
|
85
|
-
vocab_only?: boolean;
|
|
86
|
-
use_mmap?: boolean;
|
|
87
|
-
use_mlock?: boolean;
|
|
88
|
-
};
|
|
66
|
+
* Additional model parameters - re-exported from ollama-js
|
|
67
|
+
* This automatically includes ALL Ollama parameters including new ones like 'dimensions'
|
|
68
|
+
*/
|
|
69
|
+
options?: Partial<Options>;
|
|
89
70
|
}
|
|
90
71
|
interface OllamaEmbeddingSettings {
|
|
91
72
|
/**
|
|
92
73
|
* Additional embedding parameters
|
|
93
74
|
*/
|
|
94
|
-
options?:
|
|
95
|
-
|
|
96
|
-
|
|
75
|
+
options?: Partial<Options>;
|
|
76
|
+
/**
|
|
77
|
+
* Dimensions for embedding output (if supported by the model)
|
|
78
|
+
* This is a direct parameter of EmbedRequest, not part of Options
|
|
79
|
+
*/
|
|
80
|
+
dimensions?: number;
|
|
97
81
|
}
|
|
98
82
|
/**
|
|
99
83
|
* Options for configuring Ollama provider calls
|
package/dist/index.browser.js
CHANGED
|
@@ -553,7 +553,8 @@ var OllamaEmbeddingModel = class {
|
|
|
553
553
|
const response = await this.config.client.embed({
|
|
554
554
|
model: this.modelId,
|
|
555
555
|
input: value,
|
|
556
|
-
options: this.settings.options
|
|
556
|
+
options: this.settings.options,
|
|
557
|
+
...this.settings.dimensions !== void 0 && { dimensions: this.settings.dimensions }
|
|
557
558
|
});
|
|
558
559
|
if (!response.embeddings) {
|
|
559
560
|
throw new OllamaError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.browser.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":["// Browser-specific provider that uses ollama/browser\nimport { NoSuchModelError } from '@ai-sdk/provider';\nimport { Ollama } from 'ollama/browser';\nimport { OllamaChatLanguageModel } from './models/chat-language-model';\nimport { OllamaEmbeddingModel } from './models/embedding-model';\n\n// Re-export all the types\nexport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n OllamaProviderOptions,\n OllamaChatProviderOptions,\n OllamaEmbeddingProviderOptions,\n} from './provider';\n\n// Import types only to avoid duplication\nimport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n} from './provider';\n\n/**\n * Create an Ollama provider instance for browser environments\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 }) as any; // Cast to any to bypass type checking differences\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 for browser environments\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":[]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.browser.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":["// Browser-specific provider that uses ollama/browser\nimport { NoSuchModelError } from '@ai-sdk/provider';\nimport { Ollama } from 'ollama/browser';\nimport { OllamaChatLanguageModel } from './models/chat-language-model';\nimport { OllamaEmbeddingModel } from './models/embedding-model';\n\n// Re-export all the types\nexport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n OllamaProviderOptions,\n OllamaChatProviderOptions,\n OllamaEmbeddingProviderOptions,\n} from './provider';\n\n// Import types only to avoid duplication\nimport type {\n OllamaProviderSettings,\n OllamaProvider,\n OllamaChatSettings,\n OllamaEmbeddingSettings,\n} from './provider';\n\n/**\n * Create an Ollama provider instance for browser environments\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 }) as any; // Cast to any to bypass type checking differences\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 for browser environments\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 ...(this.settings.dimensions !== undefined && { dimensions: this.settings.dimensions }),\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":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -579,7 +579,8 @@ var OllamaEmbeddingModel = class {
|
|
|
579
579
|
const response = await this.config.client.embed({
|
|
580
580
|
model: this.modelId,
|
|
581
581
|
input: value,
|
|
582
|
-
options: this.settings.options
|
|
582
|
+
options: this.settings.options,
|
|
583
|
+
...this.settings.dimensions !== void 0 && { dimensions: this.settings.dimensions }
|
|
583
584
|
});
|
|
584
585
|
if (!response.embeddings) {
|
|
585
586
|
throw new OllamaError({
|