@providerprotocol/ai 0.0.36 → 0.0.38

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.
Files changed (95) hide show
  1. package/README.md +28 -0
  2. package/dist/anthropic/index.d.ts +2 -2
  3. package/dist/anthropic/index.js +12 -10
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/cerebras/index.d.ts +2 -2
  6. package/dist/cerebras/index.js +12 -10
  7. package/dist/cerebras/index.js.map +1 -1
  8. package/dist/{chunk-UFFJDYCE.js → chunk-7GTWHZY2.js} +2 -2
  9. package/dist/{chunk-IDZOVWP3.js → chunk-BDXH6NQS.js} +9 -9
  10. package/dist/{chunk-OIEWDFQU.js → chunk-FYSZFIZS.js} +2 -2
  11. package/dist/chunk-GIDT7C6I.js +37 -0
  12. package/dist/chunk-GIDT7C6I.js.map +1 -0
  13. package/dist/{chunk-VGKZIGVI.js → chunk-LTEMH3CI.js} +2 -2
  14. package/dist/{chunk-RJGTRQ47.js → chunk-MJI74VEJ.js} +6 -1
  15. package/dist/chunk-MJI74VEJ.js.map +1 -0
  16. package/dist/{chunk-AY55T37A.js → chunk-SBGZJVTJ.js} +4 -30
  17. package/dist/chunk-SBGZJVTJ.js.map +1 -0
  18. package/dist/{chunk-A2IM7PGT.js → chunk-TUTYMOBL.js} +2 -2
  19. package/dist/{chunk-BRP5XJ6Q.js → chunk-WU4U6IHF.js} +2 -2
  20. package/dist/chunk-WU4U6IHF.js.map +1 -0
  21. package/dist/{chunk-C4JP64VW.js → chunk-YQLR3XOA.js} +2 -2
  22. package/dist/chunk-ZKNPQBIE.js +265 -0
  23. package/dist/chunk-ZKNPQBIE.js.map +1 -0
  24. package/dist/{chunk-4OGB7JZA.js → chunk-ZRVNAET3.js} +2 -2
  25. package/dist/{embedding-BXA72PlJ.d.ts → embedding-CwZ1ZNWv.d.ts} +1 -1
  26. package/dist/google/index.d.ts +2 -2
  27. package/dist/google/index.js +12 -10
  28. package/dist/google/index.js.map +1 -1
  29. package/dist/groq/index.d.ts +2 -2
  30. package/dist/groq/index.js +12 -10
  31. package/dist/groq/index.js.map +1 -1
  32. package/dist/http/index.d.ts +3 -3
  33. package/dist/http/index.js +2 -1
  34. package/dist/{image-stream-CCgwB7ve.d.ts → image-stream-CeQHtjxS.d.ts} +1 -1
  35. package/dist/index.d.ts +7 -7
  36. package/dist/index.js +86 -283
  37. package/dist/index.js.map +1 -1
  38. package/dist/{llm-ByUFPcFH.d.ts → llm-DS_-l71X.d.ts} +11 -3
  39. package/dist/middleware/logging/index.d.ts +2 -2
  40. package/dist/middleware/parsed-object/index.d.ts +2 -2
  41. package/dist/middleware/parsed-object/index.js +1 -1
  42. package/dist/middleware/persistence/index.d.ts +128 -0
  43. package/dist/middleware/persistence/index.js +144 -0
  44. package/dist/middleware/persistence/index.js.map +1 -0
  45. package/dist/middleware/pubsub/index.d.ts +4 -4
  46. package/dist/middleware/pubsub/server/express/index.d.ts +2 -2
  47. package/dist/middleware/pubsub/server/fastify/index.d.ts +2 -2
  48. package/dist/middleware/pubsub/server/h3/index.d.ts +2 -2
  49. package/dist/middleware/pubsub/server/index.d.ts +2 -2
  50. package/dist/middleware/pubsub/server/webapi/index.d.ts +2 -2
  51. package/dist/moonshot/index.d.ts +510 -0
  52. package/dist/moonshot/index.js +1090 -0
  53. package/dist/moonshot/index.js.map +1 -0
  54. package/dist/ollama/index.d.ts +2 -2
  55. package/dist/ollama/index.js +12 -10
  56. package/dist/ollama/index.js.map +1 -1
  57. package/dist/openai/index.d.ts +2 -2
  58. package/dist/openai/index.js +12 -10
  59. package/dist/openai/index.js.map +1 -1
  60. package/dist/openrouter/index.d.ts +2 -2
  61. package/dist/openrouter/index.js +12 -10
  62. package/dist/openrouter/index.js.map +1 -1
  63. package/dist/proxy/index.d.ts +4 -4
  64. package/dist/proxy/index.js +22 -20
  65. package/dist/proxy/index.js.map +1 -1
  66. package/dist/proxy/server/express/index.d.ts +4 -4
  67. package/dist/proxy/server/express/index.js +3 -3
  68. package/dist/proxy/server/fastify/index.d.ts +4 -4
  69. package/dist/proxy/server/fastify/index.js +3 -3
  70. package/dist/proxy/server/h3/index.d.ts +4 -4
  71. package/dist/proxy/server/h3/index.js +3 -3
  72. package/dist/proxy/server/index.d.ts +4 -4
  73. package/dist/proxy/server/index.js +11 -11
  74. package/dist/proxy/server/webapi/index.d.ts +4 -4
  75. package/dist/proxy/server/webapi/index.js +3 -3
  76. package/dist/responses/index.d.ts +2 -2
  77. package/dist/responses/index.js +12 -10
  78. package/dist/responses/index.js.map +1 -1
  79. package/dist/{retry-BDMo4AVu.d.ts → retry-CgoBNa51.d.ts} +1 -1
  80. package/dist/{stream-S7nwQRqM.d.ts → stream-sXhBtWjl.d.ts} +4 -0
  81. package/dist/{types-CE4B7pno.d.ts → types-Cr4F0tVy.d.ts} +1 -1
  82. package/dist/xai/index.d.ts +2 -2
  83. package/dist/xai/index.js +12 -10
  84. package/dist/xai/index.js.map +1 -1
  85. package/package.json +13 -1
  86. package/dist/chunk-AY55T37A.js.map +0 -1
  87. package/dist/chunk-BRP5XJ6Q.js.map +0 -1
  88. package/dist/chunk-RJGTRQ47.js.map +0 -1
  89. /package/dist/{chunk-UFFJDYCE.js.map → chunk-7GTWHZY2.js.map} +0 -0
  90. /package/dist/{chunk-IDZOVWP3.js.map → chunk-BDXH6NQS.js.map} +0 -0
  91. /package/dist/{chunk-OIEWDFQU.js.map → chunk-FYSZFIZS.js.map} +0 -0
  92. /package/dist/{chunk-VGKZIGVI.js.map → chunk-LTEMH3CI.js.map} +0 -0
  93. /package/dist/{chunk-A2IM7PGT.js.map → chunk-TUTYMOBL.js.map} +0 -0
  94. /package/dist/{chunk-C4JP64VW.js.map → chunk-YQLR3XOA.js.map} +0 -0
  95. /package/dist/{chunk-4OGB7JZA.js.map → chunk-ZRVNAET3.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/providers/moonshot/transform.ts","../../src/providers/moonshot/llm.ts","../../src/providers/moonshot/types.ts","../../src/providers/moonshot/index.ts"],"sourcesContent":["/**\n * @fileoverview Moonshot API Message Transformers\n *\n * This module provides transformation functions for converting between the\n * Universal Provider Protocol (UPP) message format and Moonshot's Chat Completions\n * API format (OpenAI-compatible). It handles both request transformation (UPP -> Moonshot)\n * and response transformation (Moonshot -> UPP), including streaming event transformation.\n *\n * @module providers/moonshot/transform\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, VideoBlock, ReasoningBlock } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { generateId } from '../../utils/id.ts';\nimport type {\n MoonshotLLMParams,\n MoonshotRequest,\n MoonshotMessage,\n MoonshotUserContent,\n MoonshotTool,\n MoonshotResponse,\n MoonshotStreamChunk,\n MoonshotToolCall,\n} from './types.ts';\n\n/**\n * Normalizes system prompt to string.\n */\nfunction normalizeSystem(system: string | unknown[] | undefined): string | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n\n const texts: string[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object' || !('text' in block)) {\n throw new UPPError(\n 'System prompt array must contain objects with a text field',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n const textValue = (block as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'System prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n if (textValue.length > 0) {\n texts.push(textValue);\n }\n }\n\n return texts.length > 0 ? texts.join('\\n\\n') : undefined;\n}\n\n/**\n * Filters content blocks to only include those with a valid type property.\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transforms a UPP content block to Moonshot user content format.\n */\nfunction transformContentBlock(block: ContentBlock): MoonshotUserContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n let url: string;\n\n if (imageBlock.source.type === 'base64') {\n url = `data:${imageBlock.mimeType};base64,${imageBlock.source.data}`;\n } else if (imageBlock.source.type === 'url') {\n url = imageBlock.source.url;\n } else if (imageBlock.source.type === 'bytes') {\n const base64 = Buffer.from(imageBlock.source.data).toString('base64');\n url = `data:${imageBlock.mimeType};base64,${base64}`;\n } else {\n throw new UPPError(\n 'Unknown image source type',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n\n return {\n type: 'image_url',\n image_url: { url },\n };\n }\n\n case 'video': {\n const videoBlock = block as VideoBlock;\n const base64 = Buffer.from(videoBlock.data).toString('base64');\n const url = `data:${videoBlock.mimeType};base64,${base64}`;\n\n return {\n type: 'video_url',\n video_url: { url },\n };\n }\n\n case 'document':\n throw new UPPError(\n 'Moonshot does not support inline document blocks. Use the /v1/files API to upload documents first.',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n\n case 'audio':\n throw new UPPError(\n 'Moonshot does not support audio input',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n\n default:\n throw new UPPError(\n `Unsupported content type: ${block.type}`,\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Transforms a single UPP message to Moonshot format.\n */\nfunction transformMessage(message: Message): MoonshotMessage | null {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n if (validContent.length === 1 && validContent[0]?.type === 'text') {\n return {\n role: 'user',\n content: (validContent[0] as TextBlock).text,\n };\n }\n return {\n role: 'user',\n content: validContent.map(transformContentBlock),\n };\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const textContent = validContent\n .filter((c): c is TextBlock => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n // Extract reasoning content from metadata or content blocks\n const moonshotMeta = message.metadata?.moonshot as { reasoning_content?: string } | undefined;\n let reasoningContent = moonshotMeta?.reasoning_content;\n\n // Also check for ReasoningBlock in content if not in metadata\n if (!reasoningContent) {\n const reasoningBlocks = validContent.filter(\n (c): c is ReasoningBlock => c.type === 'reasoning'\n );\n if (reasoningBlocks.length > 0) {\n reasoningContent = reasoningBlocks.map((b) => b.text).join('\\n');\n }\n }\n\n const assistantMessage: MoonshotMessage = {\n role: 'assistant',\n content: textContent || null,\n };\n\n // Include reasoning_content if present (required for tool call messages)\n if (reasoningContent) {\n (assistantMessage as { reasoning_content?: string }).reasoning_content = reasoningContent;\n }\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n (assistantMessage as { tool_calls?: MoonshotToolCall[] }).tool_calls =\n message.toolCalls.map((call) => ({\n id: call.toolCallId,\n type: 'function' as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.arguments),\n },\n }));\n }\n\n return assistantMessage;\n }\n\n if (isToolResultMessage(message)) {\n const results = message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n\n return results[0] ?? null;\n }\n\n return null;\n}\n\n/**\n * Transforms tool result messages into multiple Moonshot tool messages.\n */\nexport function transformToolResults(message: Message): MoonshotMessage[] {\n if (!isToolResultMessage(message)) {\n const single = transformMessage(message);\n return single ? [single] : [];\n }\n\n return message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n}\n\n/**\n * Transforms UPP messages to Moonshot message format.\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt\n * @returns Array of Moonshot-formatted messages\n */\nfunction transformMessages(\n messages: Message[],\n system?: string | unknown[]\n): MoonshotMessage[] {\n const result: MoonshotMessage[] = [];\n const normalizedSystem = normalizeSystem(system);\n\n if (normalizedSystem) {\n result.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n\n for (const message of messages) {\n if (isToolResultMessage(message)) {\n const toolMessages = transformToolResults(message);\n result.push(...toolMessages);\n } else {\n const transformed = transformMessage(message);\n if (transformed) {\n result.push(transformed);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Extracts Moonshot-specific options from tool metadata.\n */\nfunction extractToolOptions(tool: Tool): { strict?: boolean } {\n const moonshotMeta = tool.metadata?.moonshot as { strict?: boolean } | undefined;\n return { strict: moonshotMeta?.strict };\n}\n\n/**\n * Transforms a UPP tool definition to Moonshot function tool format.\n */\nfunction transformTool(tool: Tool): MoonshotTool {\n const { strict } = extractToolOptions(tool);\n\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n ...(strict !== undefined ? { strict } : {}),\n },\n };\n}\n\n/**\n * Transforms a UPP LLM request into Moonshot Chat Completions API format.\n *\n * @param request - The UPP LLM request containing messages, tools, and configuration\n * @param modelId - The Moonshot model identifier (e.g., 'kimi-k2.5')\n * @returns A Moonshot Chat Completions API request body\n */\nexport function transformRequest(\n request: LLMRequest<MoonshotLLMParams>,\n modelId: string\n): MoonshotRequest {\n const params = request.params ?? ({} as MoonshotLLMParams);\n\n // Extract builtin tools from params before spreading\n const { tools: paramsTools, ...restParams } = params;\n\n const moonshotRequest: MoonshotRequest = {\n ...restParams,\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n // Combine builtin tools from params with transformed UPP tools\n const allTools: MoonshotTool[] = [];\n\n // Add builtin tools from params (already in Moonshot format)\n if (paramsTools && paramsTools.length > 0) {\n allTools.push(...paramsTools);\n }\n\n // Transform and add UPP tools from request.tools\n if (request.tools && request.tools.length > 0) {\n allTools.push(...request.tools.map(transformTool));\n }\n\n if (allTools.length > 0) {\n moonshotRequest.tools = allTools;\n }\n\n if (request.structure) {\n const schema: Record<string, unknown> = {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n ...(request.structure.additionalProperties !== undefined\n ? { additionalProperties: request.structure.additionalProperties }\n : { additionalProperties: false }),\n };\n if (request.structure.description) {\n schema.description = request.structure.description;\n }\n\n moonshotRequest.response_format = {\n type: 'json_schema',\n json_schema: {\n name: 'json_response',\n description: request.structure.description,\n schema,\n strict: true,\n },\n };\n }\n\n return moonshotRequest;\n}\n\n/**\n * Transforms a Moonshot response to UPP LLMResponse format.\n */\nexport function transformResponse(data: MoonshotResponse): LLMResponse {\n const choice = data.choices[0];\n if (!choice) {\n throw new UPPError(\n 'No choices in Moonshot response',\n ErrorCode.InvalidResponse,\n 'moonshot',\n ModalityType.LLM\n );\n }\n\n const contentBlocks: (TextBlock | ReasoningBlock)[] = [];\n let structuredData: unknown;\n\n if (choice.message.reasoning_content) {\n contentBlocks.push({ type: 'reasoning', text: choice.message.reasoning_content });\n }\n\n if (choice.message.content) {\n contentBlocks.push({ type: 'text', text: choice.message.content });\n try {\n structuredData = JSON.parse(choice.message.content);\n } catch {\n // Not JSON - expected for non-structured responses\n }\n }\n\n const toolCalls: ToolCall[] = [];\n if (choice.message.tool_calls) {\n for (const call of choice.message.tool_calls) {\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(call.function.arguments);\n } catch {\n // Invalid JSON - use empty object\n }\n toolCalls.push({\n toolCallId: call.id,\n toolName: call.function.name,\n arguments: args,\n });\n }\n }\n\n const message = new AssistantMessage(\n contentBlocks,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id || generateId(),\n metadata: {\n moonshot: {\n model: data.model,\n finish_reason: choice.finish_reason,\n system_fingerprint: data.system_fingerprint,\n reasoning_content: choice.message.reasoning_content ?? undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.prompt_tokens,\n outputTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n cacheReadTokens: data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (choice.finish_reason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating data during streaming responses.\n */\nexport interface MoonshotStreamState {\n /** Response ID from the first chunk */\n id: string;\n /** Model identifier */\n model: string;\n /** Accumulated text content */\n text: string;\n /** Accumulated reasoning content (thinking traces) */\n reasoningText: string;\n /** Map of tool call index to accumulated tool call data */\n toolCalls: Map<number, { id: string; name: string; arguments: string }>;\n /** The finish reason when streaming completes */\n finishReason: string | null;\n /** Input token count (from usage chunk) */\n inputTokens: number;\n /** Output token count (from usage chunk) */\n outputTokens: number;\n /** Number of tokens read from cache */\n cacheReadTokens: number;\n}\n\n/**\n * Creates a fresh stream state object for a new streaming session.\n */\nexport function createStreamState(): MoonshotStreamState {\n return {\n id: '',\n model: '',\n text: '',\n reasoningText: '',\n toolCalls: new Map(),\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n };\n}\n\n/**\n * Transforms a Moonshot streaming chunk into UPP stream events.\n */\nexport function transformStreamEvent(\n chunk: MoonshotStreamChunk,\n state: MoonshotStreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n if (chunk.id && !state.id) {\n state.id = chunk.id;\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n }\n if (chunk.model) {\n state.model = chunk.model;\n }\n\n const choice = chunk.choices[0];\n if (choice) {\n if (choice.delta.reasoning_content) {\n state.reasoningText += choice.delta.reasoning_content;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: choice.delta.reasoning_content },\n });\n }\n\n if (choice.delta.content) {\n state.text += choice.delta.content;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: choice.delta.content },\n });\n }\n\n if (choice.delta.tool_calls) {\n for (const toolCallDelta of choice.delta.tool_calls) {\n const index = toolCallDelta.index;\n let toolCall = state.toolCalls.get(index);\n\n if (!toolCall) {\n toolCall = { id: '', name: '', arguments: '' };\n state.toolCalls.set(index, toolCall);\n }\n\n if (toolCallDelta.id) {\n toolCall.id = toolCallDelta.id;\n }\n if (toolCallDelta.function?.name) {\n toolCall.name = toolCallDelta.function.name;\n }\n if (toolCallDelta.function?.arguments) {\n toolCall.arguments += toolCallDelta.function.arguments;\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: index,\n delta: {\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n argumentsJson: toolCallDelta.function.arguments,\n },\n });\n }\n }\n }\n\n if (choice.finish_reason) {\n state.finishReason = choice.finish_reason;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n }\n\n if (chunk.usage) {\n state.inputTokens = chunk.usage.prompt_tokens;\n state.outputTokens = chunk.usage.completion_tokens;\n state.cacheReadTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated streaming state.\n */\nexport function buildResponseFromState(state: MoonshotStreamState): LLMResponse {\n const contentBlocks: (TextBlock | ReasoningBlock)[] = [];\n let structuredData: unknown;\n\n if (state.reasoningText) {\n contentBlocks.push({ type: 'reasoning', text: state.reasoningText });\n }\n\n if (state.text) {\n contentBlocks.push({ type: 'text', text: state.text });\n try {\n structuredData = JSON.parse(state.text);\n } catch {\n // Not JSON - expected for non-structured responses\n }\n }\n\n const toolCalls: ToolCall[] = [];\n for (const [, toolCall] of state.toolCalls) {\n let args: Record<string, unknown> = {};\n if (toolCall.arguments) {\n try {\n args = JSON.parse(toolCall.arguments);\n } catch {\n // Invalid JSON - use empty object\n }\n }\n toolCalls.push({\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n arguments: args,\n });\n }\n\n const messageId = state.id || generateId();\n const message = new AssistantMessage(\n contentBlocks,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: messageId,\n metadata: {\n moonshot: {\n model: state.model,\n finish_reason: state.finishReason,\n reasoning_content: state.reasoningText || undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (state.finishReason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * @fileoverview Moonshot Chat Completions API Handler\n *\n * This module implements the LLM handler for Moonshot's Chat Completions API\n * (OpenAI-compatible at `https://api.moonshot.ai/v1/chat/completions`).\n *\n * @see {@link https://platform.moonshot.ai/docs/api/chat Moonshot API Reference}\n * @module providers/moonshot/llm\n */\n\nimport type { BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { LLMHandler } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType, objectDelta } from '../../types/stream.ts';\nimport type { LLMProvider, ProviderConfig } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { MoonshotLLMParams, MoonshotResponse, MoonshotStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Base URL for Moonshot's Chat Completions API endpoint (global) */\nconst MOONSHOT_API_URL = 'https://api.moonshot.ai/v1/chat/completions';\n\n/**\n * Capability declaration for the Moonshot Chat Completions API.\n *\n * Defines what features are supported by this handler:\n * - Streaming: Real-time token-by-token response streaming via SSE\n * - Tools: Function calling for structured interactions\n * - Structured Output: JSON schema-based response formatting\n * - Image Input: Native vision via MoonViT encoder\n * - Video Input: Experimental video support\n */\nconst MOONSHOT_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n documentInput: false,\n videoInput: true,\n audioInput: false,\n};\n\n/**\n * Resolves the Moonshot API key from config or environment variables.\n *\n * Checks in order:\n * 1. config.apiKey (if provided)\n * 2. MOONSHOT_API_KEY environment variable\n * 3. KIMI_API_KEY environment variable (fallback)\n *\n * @param config - Provider configuration\n * @returns The API key\n * @throws UPPError if no API key is found\n */\nasync function resolveMoonshotApiKey(config: ProviderConfig): Promise<string> {\n // First try the standard resolution with MOONSHOT_API_KEY\n try {\n return await resolveApiKey(config, 'MOONSHOT_API_KEY', 'moonshot', 'llm');\n } catch {\n // Fall back to KIMI_API_KEY\n const kimiKey = process.env.KIMI_API_KEY;\n if (kimiKey) {\n return kimiKey;\n }\n\n throw new UPPError(\n 'API key not found. Set MOONSHOT_API_KEY or KIMI_API_KEY environment variable, or pass apiKey in config.',\n ErrorCode.AuthenticationFailed,\n 'moonshot',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Creates an LLM handler for Moonshot's Chat Completions API.\n *\n * This factory function creates a handler that communicates with the\n * `/v1/chat/completions` endpoint. The handler supports both synchronous\n * completion requests and streaming responses.\n *\n * @returns An LLM handler configured for the Moonshot API\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const model = handler.bind('kimi-k2.5');\n *\n * // Synchronous completion\n * const response = await model.complete({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * config: { apiKey: 'sk-...' }\n * });\n *\n * // Streaming completion\n * const stream = model.stream({\n * messages: [{ role: 'user', content: 'Tell me a story' }],\n * config: { apiKey: 'sk-...' }\n * });\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n */\nexport function createLLMHandler(): LLMHandler<MoonshotLLMParams> {\n let providerRef: LLMProvider<MoonshotLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<MoonshotLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<MoonshotLLMParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider() or have _setProvider called.',\n ErrorCode.InvalidRequest,\n 'moonshot',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<MoonshotLLMParams> = {\n modelId,\n capabilities: MOONSHOT_CAPABILITIES,\n\n get provider(): LLMProvider<MoonshotLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<MoonshotLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveMoonshotApiKey(request.config);\n\n const baseUrl = request.config.baseUrl ?? MOONSHOT_API_URL;\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'moonshot',\n 'llm'\n );\n\n const data = await parseJsonResponse<MoonshotResponse>(response, 'moonshot', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<MoonshotLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveMoonshotApiKey(request.config);\n\n const baseUrl = request.config.baseUrl ?? MOONSHOT_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n body.stream_options = { include_usage: true };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n Accept: 'text/event-stream',\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'moonshot',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'moonshot', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'moonshot',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Skip [DONE] marker\n if (data === '[DONE]') {\n continue;\n }\n\n // Check for Moonshot error event\n if (typeof data === 'object' && data !== null) {\n const chunk = data as MoonshotStreamChunk;\n\n // Check for error in chunk\n if ('error' in chunk && chunk.error) {\n const errorData = chunk.error as { message?: string; type?: string };\n const error = new UPPError(\n errorData.message ?? 'Unknown error',\n ErrorCode.ProviderError,\n 'moonshot',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvents = transformStreamEvent(chunk, state);\n for (const event of uppEvents) {\n yield event;\n // Also emit ObjectDelta for structured output - gives developers explicit hook\n if (request.structure && event.type === StreamEventType.TextDelta) {\n yield objectDelta(event.delta.text ?? '', event.index);\n }\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Moonshot AI Provider Type Definitions\n *\n * This module contains all TypeScript type definitions for the Moonshot provider,\n * including types for the Chat Completions API (OpenAI-compatible).\n *\n * @module providers/moonshot/types\n */\n\n/**\n * Thinking mode configuration for Moonshot models.\n *\n * By default, kimi-k2.5 has thinking mode enabled and returns reasoning traces.\n * Use `{ type: 'disabled' }` to switch to instant mode for faster responses.\n */\nexport interface MoonshotThinkingConfig {\n /** Thinking mode type: 'enabled' (default) or 'disabled' for instant mode */\n type: 'enabled' | 'disabled';\n}\n\n/**\n * Parameters for the Moonshot Chat Completions API.\n *\n * These parameters are passed directly to the `/v1/chat/completions` endpoint.\n * Moonshot's API is OpenAI-compatible with additional thinking mode support.\n *\n * @example\n * ```typescript\n * const params: MoonshotLLMParams = {\n * temperature: 1.0,\n * max_tokens: 1000,\n * thinking: { type: 'enabled' } // Default for kimi-k2.5\n * };\n * ```\n */\nexport interface MoonshotLLMParams {\n /** Maximum number of tokens to generate */\n max_tokens?: number;\n\n /** Maximum completion tokens (alias for max_tokens) */\n max_completion_tokens?: number;\n\n /** Temperature for randomness (0.0 to 2.0). Default: 1.0 (thinking) or 0.6 (instant) */\n temperature?: number;\n\n /** Top-p (nucleus) sampling (0.0 - 1.0), default 0.95 */\n top_p?: number;\n\n /** Custom stop sequences */\n stop?: string | string[];\n\n /** Frequency penalty (-2.0 - 2.0) */\n frequency_penalty?: number;\n\n /** Presence penalty (-2.0 - 2.0) */\n presence_penalty?: number;\n\n /** Seed for deterministic sampling */\n seed?: number;\n\n /** User identifier for rate limit tracking */\n user?: string;\n\n /** Response format for structured output */\n response_format?: MoonshotResponseFormat;\n\n /** Thinking mode configuration (kimi-k2.5 specific) */\n thinking?: MoonshotThinkingConfig;\n\n /**\n * Builtin tools to enable for this request.\n * Use the `tools` helper object to create these.\n *\n * @example\n * ```typescript\n * import { moonshot, tools } from '@providerprotocol/ai/moonshot';\n *\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: {\n * tools: [tools.webSearch(), tools.codeRunner()],\n * },\n * });\n * ```\n */\n tools?: MoonshotTool[];\n}\n\n/**\n * Response format options for structured output.\n */\nexport type MoonshotResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | {\n type: 'json_schema';\n json_schema: {\n name: string;\n description?: string;\n schema: Record<string, unknown>;\n strict?: boolean;\n };\n };\n\n/**\n * Request body for the Moonshot Chat Completions API.\n */\nexport interface MoonshotRequest {\n model: string;\n messages: MoonshotMessage[];\n temperature?: number;\n top_p?: number;\n stream?: boolean;\n stream_options?: { include_usage?: boolean };\n stop?: string | string[];\n max_tokens?: number;\n max_completion_tokens?: number;\n presence_penalty?: number;\n frequency_penalty?: number;\n user?: string;\n seed?: number;\n tools?: MoonshotTool[];\n tool_choice?: MoonshotToolChoice;\n response_format?: MoonshotResponseFormat;\n thinking?: MoonshotThinkingConfig;\n}\n\n/**\n * Union type for all message types in the Moonshot API.\n */\nexport type MoonshotMessage =\n | MoonshotSystemMessage\n | MoonshotUserMessage\n | MoonshotAssistantMessage\n | MoonshotToolMessage;\n\n/** System message for setting context and instructions */\nexport interface MoonshotSystemMessage {\n role: 'system';\n content: string;\n}\n\n/** User message with text or multimodal content */\nexport interface MoonshotUserMessage {\n role: 'user';\n content: string | MoonshotUserContent[];\n}\n\n/** Assistant message containing the model's response */\nexport interface MoonshotAssistantMessage {\n role: 'assistant';\n content?: string | null;\n /** Reasoning traces from thinking mode */\n reasoning_content?: string | null;\n tool_calls?: MoonshotToolCall[];\n}\n\n/** Tool result message providing output from a function call */\nexport interface MoonshotToolMessage {\n role: 'tool';\n content: string;\n tool_call_id: string;\n}\n\n/**\n * Union type for user content parts (text, image, or video).\n */\nexport type MoonshotUserContent = MoonshotTextContent | MoonshotImageContent | MoonshotVideoContent;\n\n/** Text content part */\nexport interface MoonshotTextContent {\n type: 'text';\n text: string;\n}\n\n/** Image content part with URL reference (for vision models) */\nexport interface MoonshotImageContent {\n type: 'image_url';\n image_url: {\n url: string;\n };\n}\n\n/** Video content part with URL reference (experimental) */\nexport interface MoonshotVideoContent {\n type: 'video_url';\n video_url: {\n url: string;\n };\n}\n\n/**\n * Tool call structure in assistant messages.\n */\nexport interface MoonshotToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * Tool definition for the Moonshot API.\n * Used for both custom function tools and server-side builtin tools.\n */\nexport interface MoonshotTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: {\n type?: 'object';\n description?: string;\n properties: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n strict?: boolean;\n };\n}\n\n/**\n * Tool choice options for controlling function calling behavior.\n * Moonshot models support full tool_choice including 'required'.\n */\nexport type MoonshotToolChoice =\n | 'none'\n | 'auto'\n | 'required'\n | { type: 'function'; function: { name: string } };\n\n// ============================================\n// Server-Side Tool Factory Functions\n// ============================================\n// These tools are executed by Moonshot's servers, not by the client.\n// The model decides when to call them and the API handles execution.\n//\n// TODO: Implement `excel` plugin - uses `_plugin` format with multiple\n// sub-functions (read_file, list_sheets, describe, inspect, pipe, groupby,\n// orderby, filter, head, value_counts, correlation, sample, select, count,\n// sum, distinct, add_column). Requires file IDs from Moonshot's /v1/files API.\n\n/**\n * Options for web search tool.\n */\nexport interface MoonshotWebSearchOptions {\n /** Search domains to focus on */\n classes?: Array<'all' | 'academic' | 'social' | 'library' | 'finance' | 'code' | 'ecommerce' | 'medical'>;\n}\n\n/**\n * Creates a web search tool (server-side execution).\n * Enables real-time internet search capabilities.\n *\n * Note: Web search is charged separately from regular API usage.\n *\n * @example\n * ```typescript\n * import { moonshot, tools } from '@providerprotocol/ai/moonshot';\n *\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: {\n * tools: [tools.webSearch()],\n * },\n * });\n * ```\n */\nexport function webSearch(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'web_search',\n description: 'Search the web for information',\n parameters: {\n type: 'object',\n properties: {\n query: {\n description: 'What to search for',\n type: 'string',\n },\n classes: {\n description: 'Search domains to focus on. Defaults to \"all\" if not specified.',\n type: 'array',\n items: {\n type: 'string',\n enum: ['all', 'academic', 'social', 'library', 'finance', 'code', 'ecommerce', 'medical'],\n },\n },\n },\n required: ['query'],\n },\n },\n };\n}\n\n/**\n * Creates a Python code runner tool (server-side execution).\n * Allows execution of Python code for calculations and data processing.\n * Supports print output, matplotlib plots, pandas, and file reading via ctx.read_object().\n */\nexport function codeRunner(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'code_runner',\n description: 'Safely executes Python code and returns the result, with print output, last-line evaluation, error handling, and timeout protection.',\n parameters: {\n type: 'object',\n properties: {\n code: {\n description: 'The Python code to execute. Supports print(), matplotlib, pandas, and ctx.read_object() for file reading.',\n type: 'string',\n },\n },\n required: ['code'],\n },\n },\n };\n}\n\n/**\n * Creates a QuickJS JavaScript execution tool (server-side execution).\n * Enables secure JavaScript code execution via the QuickJS engine.\n */\nexport function quickjs(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'quickjs',\n description: 'Safely executes JavaScript code using QuickJS engine',\n parameters: {\n type: 'object',\n properties: {\n code: {\n description: 'The JavaScript code to execute. Supports console.log(), ES6+ features, and ctx.log() for logging.',\n type: 'string',\n },\n },\n required: ['code'],\n },\n },\n };\n}\n\n/**\n * Creates a URL fetch tool (server-side execution).\n * Extracts content from URLs and formats it as Markdown.\n */\nexport function fetch(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'fetch',\n description: 'Fetches a URL from the internet and optionally extracts its contents as markdown.',\n parameters: {\n type: 'object',\n properties: {\n url: {\n description: 'URL to fetch',\n type: 'string',\n format: 'uri',\n },\n max_length: {\n description: 'Maximum number of characters to return (default: 5000)',\n type: 'integer',\n default: 5000,\n },\n start_index: {\n description: 'Start at this character index, useful for pagination',\n type: 'integer',\n default: 0,\n },\n raw: {\n description: 'Get raw HTML without simplification',\n type: 'boolean',\n default: false,\n },\n },\n required: ['url'],\n },\n },\n };\n}\n\n/**\n * Creates a unit conversion tool (server-side execution).\n * Supports length, mass, volume, temperature, area, time, energy,\n * pressure, speed, and currency conversions.\n */\nexport function convert(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'convert',\n description: 'Convert between supported units of length, mass, volume, temperature, area, time, energy, pressure, speed, and currency.',\n parameters: {\n type: 'object',\n properties: {\n value: {\n description: 'Value to convert',\n type: 'number',\n },\n from_unit: {\n description: 'Source unit (e.g., m, km, ft, kg, lb, °C, °F, USD, EUR)',\n type: 'string',\n },\n to_unit: {\n description: 'Target unit',\n type: 'string',\n },\n },\n required: ['value', 'from_unit', 'to_unit'],\n },\n },\n };\n}\n\n/**\n * Creates a date/time processing tool (server-side execution).\n * Handles date and time calculations, timezone conversion, and formatting.\n */\nexport function date(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'date',\n description: 'Date and time processing tool, supports displaying current time, timezone conversion, date calculation, and more.',\n parameters: {\n type: 'object',\n properties: {\n operation: {\n description: 'Operation type',\n type: 'string',\n enum: ['time', 'convert', 'between', 'add', 'subtract'],\n },\n date: {\n description: 'Date string (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)',\n type: 'string',\n },\n date1: {\n description: 'First date (for difference calculation)',\n type: 'string',\n },\n date2: {\n description: 'Second date (for difference calculation)',\n type: 'string',\n },\n days: {\n description: 'Number of days (for add/subtract)',\n type: 'integer',\n },\n zone: {\n description: 'Timezone name (e.g., Asia/Shanghai, America/New_York, UTC)',\n type: 'string',\n },\n from_zone: {\n description: 'Source timezone (for conversion)',\n type: 'string',\n },\n to_zone: {\n description: 'Target timezone (for conversion)',\n type: 'string',\n },\n format: {\n description: 'Output format (Python strftime)',\n type: 'string',\n default: '%Y-%m-%d %H:%M:%S',\n },\n },\n required: ['operation'],\n },\n },\n };\n}\n\n/**\n * Creates a Base64 encoding tool (server-side execution).\n */\nexport function base64Encode(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'base64_encode',\n description: 'Encode text to base64 format',\n parameters: {\n type: 'object',\n properties: {\n data: {\n description: 'Text data to encode to base64',\n type: 'string',\n },\n encoding: {\n description: 'Character encoding to use (default: utf-8)',\n type: 'string',\n default: 'utf-8',\n },\n },\n required: ['data'],\n },\n },\n };\n}\n\n/**\n * Creates a Base64 decoding tool (server-side execution).\n */\nexport function base64Decode(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'base64_decode',\n description: 'Decode base64 text to original format',\n parameters: {\n type: 'object',\n properties: {\n data: {\n description: 'Base64 encoded data to decode',\n type: 'string',\n },\n encoding: {\n description: 'Character encoding to use (default: utf-8)',\n type: 'string',\n default: 'utf-8',\n },\n },\n required: ['data'],\n },\n },\n };\n}\n\n/**\n * Creates a memory storage tool (server-side execution).\n * Supports persistent storage of conversation history and user preferences.\n */\nexport function memory(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'memory',\n description: 'Memory storage and retrieval system, supporting persistence of conversation history, user preferences, and other data.',\n parameters: {\n type: 'object',\n properties: {\n action: {\n description: 'Operation type',\n type: 'string',\n enum: ['store', 'retrieve', 'delete', 'list'],\n },\n key: {\n description: 'Storage key name',\n type: 'string',\n },\n data: {\n description: 'Data content to store',\n type: 'object',\n },\n prefix: {\n description: 'Key prefix for list operation',\n type: 'string',\n },\n ttl: {\n description: 'Data expiration time in seconds (default: 86400 = 24 hours)',\n type: 'integer',\n default: 86400,\n },\n },\n required: ['action'],\n },\n },\n };\n}\n\n/**\n * Creates an intelligent reasoning tool (server-side execution).\n * Allows the model to organize thoughts and plan before responding.\n */\nexport function rethink(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'rethink',\n description: 'Tool for organizing thoughts, making plans, and thinking step by step. Does not return information, just for reflection.',\n parameters: {\n type: 'object',\n properties: {\n thought: {\n description: 'The thought to consider for better solving the current task',\n type: 'string',\n },\n },\n required: ['thought'],\n },\n },\n };\n}\n\n/**\n * Creates a random choice tool (server-side execution).\n * Enables random selection from options with optional weights.\n */\nexport function randomChoice(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'random_choice',\n description: 'Random selection tool that supports choosing items from candidates with optional weights.',\n parameters: {\n type: 'object',\n properties: {\n candidates: {\n description: 'List of candidates to choose from',\n type: 'array',\n items: { type: 'string' },\n },\n count: {\n description: 'Number of items to select (default: 1)',\n type: 'integer',\n default: 1,\n },\n replace: {\n description: 'Allow duplicates (default: false)',\n type: 'boolean',\n default: false,\n },\n weights: {\n description: 'Optional weights for weighted selection',\n type: 'array',\n items: { type: 'number' },\n },\n seed: {\n description: 'Random seed for reproducibility',\n type: 'integer',\n },\n format: {\n description: 'Output format',\n type: 'string',\n enum: ['simple', 'detailed', 'json'],\n default: 'simple',\n },\n },\n required: ['candidates'],\n },\n },\n };\n}\n\n/**\n * Creates a cat meowing/blessing tool (server-side execution).\n * Returns random cat meowing sounds and blessings based on mood.\n */\nexport function mew(): MoonshotTool {\n return {\n type: 'function',\n function: {\n name: 'mew_generator',\n description: \"Randomly generates a cat's meow, accompanied by a blessing.\",\n parameters: {\n type: 'object',\n properties: {\n mood: {\n description: \"The cat's mood\",\n type: 'string',\n enum: ['happy', 'sleepy', 'hungry', 'playful', 'grumpy'],\n },\n },\n required: [],\n },\n },\n };\n}\n\n\n/**\n * Moonshot builtin tools factory object.\n * Provides convenient access to all builtin tool creators.\n *\n * Note: The `excel` plugin tool uses a different format and is not included here.\n * It requires file IDs from the Moonshot file upload API.\n *\n * @example\n * ```typescript\n * import { moonshot, tools } from '@providerprotocol/ai/moonshot';\n *\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: {\n * tools: [\n * tools.webSearch(),\n * tools.codeRunner(),\n * tools.fetch(),\n * ],\n * },\n * });\n * ```\n */\nexport const tools = {\n /** Web search for real-time internet information */\n webSearch,\n /** Python code execution with matplotlib, pandas support */\n codeRunner,\n /** JavaScript execution via QuickJS engine */\n quickjs,\n /** URL content fetching with markdown extraction */\n fetch,\n /** Unit conversion (length, mass, temperature, currency, etc.) */\n convert,\n /** Date/time processing and timezone conversion */\n date,\n /** Base64 encoding */\n base64Encode,\n /** Base64 decoding */\n base64Decode,\n /** Alias for base64Encode */\n base64: base64Encode,\n /** Memory storage and retrieval system */\n memory,\n /** Intelligent reasoning/reflection tool */\n rethink,\n /** Random selection with optional weights */\n randomChoice,\n /** Cat meowing and blessings generator */\n mew,\n};\n\n/**\n * Response structure from the Moonshot Chat Completions API.\n */\nexport interface MoonshotResponse {\n id: string;\n object: 'chat.completion';\n created: number;\n model: string;\n choices: MoonshotChoice[];\n usage: MoonshotUsage;\n system_fingerprint?: string;\n}\n\n/** A single choice from a completion response */\nexport interface MoonshotChoice {\n index: number;\n message: MoonshotAssistantMessage;\n finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;\n}\n\n/** Token usage statistics from the API response */\nexport interface MoonshotUsage {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n prompt_tokens_details?: {\n cached_tokens?: number;\n };\n}\n\n/**\n * Streaming chunk structure from the Moonshot API.\n */\nexport interface MoonshotStreamChunk {\n id: string;\n object: 'chat.completion.chunk';\n created: number;\n model: string;\n choices: MoonshotStreamChoice[];\n usage?: MoonshotUsage | null;\n system_fingerprint?: string;\n}\n\n/** A streaming choice containing incremental content */\nexport interface MoonshotStreamChoice {\n index: number;\n delta: MoonshotStreamDelta;\n finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;\n}\n\n/** Incremental content delta in a streaming chunk */\nexport interface MoonshotStreamDelta {\n role?: 'assistant';\n content?: string | null;\n reasoning_content?: string | null;\n tool_calls?: MoonshotStreamToolCall[];\n}\n\n/** Incremental tool call data in a streaming chunk */\nexport interface MoonshotStreamToolCall {\n index: number;\n id?: string;\n type?: 'function';\n function?: {\n name?: string;\n arguments?: string;\n };\n}\n\n/**\n * Moonshot-specific HTTP headers for API requests.\n *\n * @example\n * ```typescript\n * const headers: MoonshotHeaders = {\n * 'X-Request-Id': 'my-request-id',\n * };\n * ```\n */\nexport interface MoonshotHeaders {\n /** Client-generated request ID for tracing */\n 'X-Request-Id'?: string;\n [key: string]: string | undefined;\n}\n","/**\n * @fileoverview Moonshot Provider Factory\n *\n * This module provides the main Moonshot provider implementation for the\n * OpenAI-compatible Chat Completions API.\n *\n * @module providers/moonshot\n */\n\nimport { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\n\n/**\n * Configuration options for the Moonshot provider.\n *\n * Currently Moonshot only supports one API endpoint (Chat Completions),\n * so no additional options are needed.\n */\nexport interface MoonshotProviderOptions {\n // Reserved for future use\n}\n\n/**\n * The Moonshot provider instance.\n *\n * Use this provider to create model references for Moonshot models like\n * Kimi K2.5 and other models available on the Moonshot AI platform.\n *\n * @example Basic usage\n * ```typescript\n * import { moonshot } from './providers/moonshot';\n * import { llm } from './core/llm';\n *\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example With streaming\n * ```typescript\n * const stream = model.stream('Tell me a story');\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n *\n * const turn = await stream.turn;\n * console.log('Tokens used:', turn.usage.totalTokens);\n * ```\n *\n * @example With thinking mode (default for K2.5)\n * ```typescript\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: {\n * max_tokens: 2000,\n * temperature: 1.0, // Recommended for thinking mode\n * thinking: { type: 'enabled' } // Default\n * }\n * });\n *\n * // Response includes reasoning_content in metadata\n * const turn = await model.generate('Solve this step by step: 2x + 5 = 13');\n * ```\n *\n * @example With instant mode (disabled thinking)\n * ```typescript\n * const model = llm({\n * model: moonshot('kimi-k2.5'),\n * params: {\n * max_tokens: 1000,\n * temperature: 0.6, // Recommended for instant mode\n * thinking: { type: 'disabled' }\n * }\n * });\n * ```\n *\n * @example With vision (image input)\n * ```typescript\n * import { Image } from './core/media/Image';\n *\n * const image = await Image.fromPath('./photo.png');\n * const turn = await model.generate([\n * image.toBlock(),\n * { type: 'text', text: 'Describe this image' }\n * ]);\n * ```\n *\n * @example Available models\n * Production models:\n * - `kimi-k2.5` - Latest K2.5 with 256K context, vision, thinking mode\n *\n * Environment variables:\n * - `MOONSHOT_API_KEY` - Primary API key\n * - `KIMI_API_KEY` - Fallback API key\n */\nexport const moonshot = createProvider<MoonshotProviderOptions>({\n name: 'moonshot',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n },\n});\n\nexport { tools } from './types.ts';\nexport type {\n MoonshotLLMParams,\n MoonshotHeaders,\n MoonshotResponseFormat,\n MoonshotMessage,\n MoonshotRequest,\n MoonshotResponse,\n MoonshotStreamChunk,\n MoonshotTool,\n MoonshotToolCall,\n MoonshotToolChoice,\n MoonshotUsage,\n MoonshotThinkingConfig,\n} from './types.ts';\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-ByUFPcFH.js';
2
- import '../stream-S7nwQRqM.js';
1
+ import { e as Provider } from '../llm-DS_-l71X.js';
2
+ import '../stream-sXhBtWjl.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview Type definitions for the Ollama provider.
@@ -1,33 +1,35 @@
1
1
  import {
2
2
  parseJsonResponse
3
- } from "../chunk-A2IM7PGT.js";
3
+ } from "../chunk-TUTYMOBL.js";
4
4
  import {
5
5
  resolveApiKey
6
6
  } from "../chunk-ARVM24K2.js";
7
7
  import {
8
8
  createProvider
9
9
  } from "../chunk-JA3UZALR.js";
10
+ import {
11
+ doFetch,
12
+ doStreamFetch,
13
+ normalizeHttpError
14
+ } from "../chunk-SBGZJVTJ.js";
15
+ import {
16
+ StreamEventType,
17
+ objectDelta
18
+ } from "../chunk-MJI74VEJ.js";
10
19
  import {
11
20
  AssistantMessage,
12
21
  isAssistantMessage,
13
22
  isToolResultMessage,
14
23
  isUserMessage
15
- } from "../chunk-BRP5XJ6Q.js";
24
+ } from "../chunk-WU4U6IHF.js";
16
25
  import {
17
- doFetch,
18
- doStreamFetch,
19
- normalizeHttpError,
20
26
  toError
21
- } from "../chunk-AY55T37A.js";
27
+ } from "../chunk-GIDT7C6I.js";
22
28
  import {
23
29
  ErrorCode,
24
30
  ModalityType,
25
31
  UPPError
26
32
  } from "../chunk-COS4ON4G.js";
27
- import {
28
- StreamEventType,
29
- objectDelta
30
- } from "../chunk-RJGTRQ47.js";
31
33
 
32
34
  // src/providers/ollama/transform.ts
33
35
  function normalizeSystem(system) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/ollama/transform.ts","../../src/providers/ollama/llm.ts","../../src/providers/ollama/embed.ts","../../src/providers/ollama/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation utilities for Ollama provider.\n *\n * This module handles bidirectional transformation between the Unified Provider\n * Protocol (UPP) format and Ollama's native API format. It includes:\n *\n * - Request transformation (UPP to Ollama)\n * - Response transformation (Ollama to UPP)\n * - Stream chunk processing\n * - Message format conversion\n *\n * @module providers/ollama/transform\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport type {\n OllamaLLMParams,\n OllamaRequest,\n OllamaMessage,\n OllamaTool,\n OllamaResponse,\n OllamaStreamChunk,\n OllamaOptions,\n} from './types.ts';\n\n/**\n * Normalizes system prompt to string.\n * Converts array format to concatenated string for providers that only support strings.\n */\nfunction normalizeSystem(system: string | unknown[] | undefined): string | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const texts: string[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object' || !('text' in block)) {\n throw new UPPError(\n 'System prompt array must contain objects with a text field',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n const textValue = (block as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'System prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n if (textValue.length > 0) {\n texts.push(textValue);\n }\n }\n\n return texts.length > 0 ? texts.join('\\n\\n') : undefined;\n}\n\n/**\n * Transforms UPP messages to Ollama's message format.\n *\n * Handles conversion of:\n * - User messages with text and image content\n * - Assistant messages with text and tool calls\n * - Tool result messages\n * - System prompts (prepended as first message)\n *\n * Image handling:\n * - Base64 images are passed directly\n * - Byte arrays are converted to base64\n * - URL images are converted to text placeholders (Ollama limitation)\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array, normalized to string)\n * @returns Array of Ollama-formatted messages\n */\nfunction transformMessages(messages: Message[], system?: string | unknown[]): OllamaMessage[] {\n const ollamaMessages: OllamaMessage[] = [];\n const normalizedSystem = normalizeSystem(system);\n\n // System prompt as first message\n if (normalizedSystem) {\n ollamaMessages.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const textContent: string[] = [];\n const images: string[] = [];\n\n for (const block of msg.content) {\n if (block.type === 'text') {\n textContent.push(block.text);\n } else if (block.type === 'image') {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n images.push(imageBlock.source.data);\n } else if (imageBlock.source.type === 'bytes') {\n const base64 = Buffer.from(imageBlock.source.data).toString('base64');\n images.push(base64);\n } else if (imageBlock.source.type === 'url') {\n // Ollama doesn't support URL images directly\n // Would need to fetch and convert, for now just add as text\n textContent.push(`[Image: ${imageBlock.source.url}]`);\n }\n }\n }\n\n const message: OllamaMessage = {\n role: 'user',\n content: textContent.join('\\n'),\n };\n\n if (images.length > 0) {\n message.images = images;\n }\n\n ollamaMessages.push(message);\n } else if (isAssistantMessage(msg)) {\n // Filter for text blocks only (exclude reasoning blocks from history)\n // Also strip any <think>...</think> tags that may be embedded in text\n // (required for proper multi-turn with Qwen 3, DeepSeek-R1, etc.)\n const textContent = msg.content\n .filter((block): block is TextBlock => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .replace(/<think>[\\s\\S]*?<\\/think>/g, '')\n .trim();\n\n const message: OllamaMessage = {\n role: 'assistant',\n content: textContent,\n };\n\n // Add tool calls if present\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n message.tool_calls = msg.toolCalls.map((call) => ({\n function: {\n name: call.toolName,\n arguments: call.arguments,\n },\n }));\n }\n\n ollamaMessages.push(message);\n } else if (isToolResultMessage(msg)) {\n // Tool results are sent as 'tool' role messages\n for (const result of msg.results) {\n // Extract tool name from toolCallId (format: {name}_{index})\n const underscoreIndex = result.toolCallId.lastIndexOf('_');\n const toolName = underscoreIndex > 0\n ? result.toolCallId.slice(0, underscoreIndex)\n : result.toolCallId;\n ollamaMessages.push({\n role: 'tool',\n tool_name: toolName,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n });\n }\n }\n }\n\n return ollamaMessages;\n}\n\n/**\n * Transforms a UPP tool definition to Ollama's function format.\n *\n * Ollama uses the OpenAI-style function calling format with a\n * `type: 'function'` wrapper around the function definition.\n *\n * @param tool - The UPP tool definition\n * @returns The Ollama-formatted tool definition\n */\nfunction transformTool(tool: Tool): OllamaTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms a UPP LLM request into Ollama's native API format.\n *\n * This function handles the mapping between UPP's unified request structure\n * and Ollama's specific requirements, including:\n *\n * - Converting messages to Ollama's message format\n * - Mapping model parameters to Ollama's nested `options` structure\n * - Handling top-level parameters like `keep_alive` and `think`\n * - Converting tools to Ollama's function format\n * - Setting up structured output via the `format` field\n *\n * Parameters are spread to allow pass-through of any Ollama API fields,\n * enabling developers to use new API features without library updates.\n *\n * @typeParam TParams - The parameter type extending OllamaLLMParams\n * @param request - The UPP-format LLM request\n * @param modelId - The Ollama model identifier (e.g., 'llama3.2', 'mistral')\n * @returns The transformed Ollama API request body\n *\n * @example\n * ```typescript\n * const ollamaRequest = transformRequest(\n * {\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * config: {},\n * params: { temperature: 0.7 }\n * },\n * 'llama3.2'\n * );\n * ```\n */\nexport function transformRequest<TParams extends OllamaLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): OllamaRequest {\n const params = (request.params ?? {}) as OllamaLLMParams;\n\n // Extract top-level params vs options params\n const {\n keep_alive,\n think,\n logprobs,\n top_logprobs,\n ...optionsParams\n } = params;\n\n // Spread params to pass through all fields, then set required fields\n const ollamaRequest: OllamaRequest = {\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n // Add top-level params if provided\n if (keep_alive !== undefined) ollamaRequest.keep_alive = keep_alive;\n if (think !== undefined) ollamaRequest.think = think;\n if (logprobs !== undefined) ollamaRequest.logprobs = logprobs;\n if (top_logprobs !== undefined) ollamaRequest.top_logprobs = top_logprobs;\n\n // Spread remaining params into options to pass through all model parameters\n if (Object.keys(optionsParams).length > 0) {\n ollamaRequest.options = optionsParams as OllamaOptions;\n }\n\n // Tools come from request, not params\n if (request.tools && request.tools.length > 0) {\n ollamaRequest.tools = request.tools.map(transformTool);\n }\n\n // Structured output via format field\n if (request.structure) {\n ollamaRequest.format = request.structure as unknown as Record<string, unknown>;\n }\n\n return ollamaRequest;\n}\n\n/**\n * Transforms an Ollama API response to the UPP LLMResponse format.\n *\n * This function extracts and normalizes:\n * - Text content from the assistant message\n * - Tool calls with their arguments\n * - Token usage statistics (prompt + completion tokens)\n * - Stop reason mapping (stop -> end_turn, length -> max_tokens)\n * - Ollama-specific metadata (timings, model info, thinking content)\n *\n * For structured output requests, the response content is automatically\n * parsed as JSON and stored in the `data` field.\n *\n * @param data - The raw Ollama API response\n * @returns The normalized UPP LLM response\n */\nexport function transformResponse(data: OllamaResponse): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (data.message.thinking) {\n content.push({ type: 'reasoning', text: data.message.thinking });\n }\n\n // Add main content\n if (data.message.content) {\n content.push({ type: 'text', text: data.message.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(data.message.content);\n } catch {\n // Not valid JSON - that's fine, might not be structured output\n }\n }\n\n // Extract tool calls\n if (data.message.tool_calls) {\n for (let idx = 0; idx < data.message.tool_calls.length; idx++) {\n const call = data.message.tool_calls[idx]!;\n const index = call.function.index ?? idx;\n toolCalls.push({\n toolCallId: `${call.function.name}_${index}`,\n toolName: call.function.name,\n arguments: call.function.arguments,\n });\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: data.model,\n created_at: data.created_at,\n done_reason: data.done_reason,\n thinking: data.message.thinking,\n total_duration: data.total_duration,\n load_duration: data.load_duration,\n prompt_eval_duration: data.prompt_eval_duration,\n eval_duration: data.eval_duration,\n logprobs: data.logprobs,\n },\n },\n }\n );\n\n // Calculate token usage (Ollama doesn't support API-level prompt caching)\n const usage: TokenUsage = {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n totalTokens: (data.prompt_eval_count ?? 0) + (data.eval_count ?? 0),\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (data.done_reason === 'length') {\n stopReason = 'max_tokens';\n } else if (data.done_reason === 'stop') {\n stopReason = 'end_turn';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating data during stream processing.\n *\n * As streaming chunks arrive, this state object accumulates content,\n * tool calls, and metadata. Once the stream completes (indicated by\n * `done: true`), this state is used to build the final LLMResponse.\n */\nexport interface StreamState {\n /** The model name from the stream. */\n model: string;\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated thinking/reasoning content (for models with think mode). */\n thinking: string;\n /** Tool calls extracted from the stream. */\n toolCalls: Array<{ name: string; args: Record<string, unknown> }>;\n /** The reason the generation stopped (stop, length, etc.). */\n doneReason: string | null;\n /** Number of tokens in the prompt evaluation. */\n promptEvalCount: number;\n /** Number of tokens generated in the response. */\n evalCount: number;\n /** Total generation duration in nanoseconds. */\n totalDuration: number;\n /** Whether we're still waiting for the first chunk. */\n isFirstChunk: boolean;\n /** ISO timestamp when the response was created. */\n createdAt: string;\n}\n\n/**\n * Creates an initial empty stream state for accumulating streaming responses.\n *\n * @returns A fresh StreamState object with default values\n */\nexport function createStreamState(): StreamState {\n return {\n model: '',\n content: '',\n thinking: '',\n toolCalls: [],\n doneReason: null,\n promptEvalCount: 0,\n evalCount: 0,\n totalDuration: 0,\n isFirstChunk: true,\n createdAt: '',\n };\n}\n\n/**\n * Transforms an Ollama stream chunk into UPP StreamEvents.\n *\n * Each Ollama chunk may produce zero or more UPP events:\n * - First chunk: `message_start` event\n * - Content chunks: `text_delta` events\n * - Thinking chunks: `reasoning_delta` events\n * - Tool call chunks: `tool_call_delta` events\n * - Final chunk (done=true): `message_stop` event\n *\n * The function also updates the provided state object with accumulated\n * content and metadata for building the final response.\n *\n * @param chunk - The raw Ollama stream chunk\n * @param state - Mutable state object to accumulate data\n * @returns Array of UPP stream events (may be empty)\n */\nexport function transformStreamChunk(\n chunk: OllamaStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n // First chunk - emit message start\n if (state.isFirstChunk) {\n state.model = chunk.model;\n state.createdAt = chunk.created_at;\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n // Process message content\n if (chunk.message) {\n // Text content delta\n if (chunk.message.content) {\n state.content += chunk.message.content;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: chunk.message.content },\n });\n }\n\n // Thinking content delta\n if (chunk.message.thinking) {\n state.thinking += chunk.message.thinking;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: chunk.message.thinking },\n });\n }\n\n // Tool calls (typically come in final chunk)\n if (chunk.message.tool_calls) {\n for (const call of chunk.message.tool_calls) {\n const idx = state.toolCalls.length;\n const toolCallId = `${call.function.name}_${call.function.index ?? idx}`;\n state.toolCalls.push({\n name: call.function.name,\n args: call.function.arguments,\n });\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: idx,\n delta: {\n toolCallId,\n toolName: call.function.name,\n argumentsJson: JSON.stringify(call.function.arguments),\n },\n });\n }\n }\n }\n\n // Final chunk with metrics\n if (chunk.done) {\n state.doneReason = chunk.done_reason ?? null;\n state.promptEvalCount = chunk.prompt_eval_count ?? 0;\n state.evalCount = chunk.eval_count ?? 0;\n state.totalDuration = chunk.total_duration ?? 0;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated stream state.\n *\n * Called after the stream completes to construct the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * For structured output, attempts to parse the accumulated content as JSON\n * and stores it in the `data` field if successful.\n *\n * @param state - The accumulated stream state\n * @returns The complete UPP LLM response\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (state.thinking) {\n content.push({ type: 'reasoning', text: state.thinking });\n }\n\n if (state.content) {\n content.push({ type: 'text', text: state.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not valid JSON - that's fine\n }\n }\n\n for (let idx = 0; idx < state.toolCalls.length; idx++) {\n const tc = state.toolCalls[idx]!;\n toolCalls.push({\n toolCallId: `${tc.name}_${idx}`,\n toolName: tc.name,\n arguments: tc.args,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: state.model,\n created_at: state.createdAt,\n done_reason: state.doneReason,\n thinking: state.thinking || undefined,\n total_duration: state.totalDuration,\n },\n },\n }\n );\n\n // Ollama doesn't support API-level prompt caching\n const usage: TokenUsage = {\n inputTokens: state.promptEvalCount,\n outputTokens: state.evalCount,\n totalTokens: state.promptEvalCount + state.evalCount,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (state.doneReason === 'length') {\n stopReason = 'max_tokens';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * @fileoverview Ollama LLM handler implementation.\n *\n * This module provides the core LLM functionality for the Ollama provider,\n * including both synchronous completion and streaming capabilities. It\n * communicates with Ollama's native `/api/chat` endpoint.\n *\n * @module providers/ollama/llm\n */\n\nimport type {\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { LLMHandler } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType, objectDelta } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OllamaLLMParams, OllamaResponse, OllamaStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Default Ollama server URL for local installations. */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Capability flags for the Ollama provider.\n */\nconst OLLAMA_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n documentInput: false,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Parses Ollama's newline-delimited JSON (NDJSON) stream format.\n *\n * Ollama uses NDJSON where each line is a complete JSON object representing\n * a streaming chunk. This generator reads the stream incrementally, buffering\n * incomplete lines and yielding parsed chunks as they become available.\n *\n * @param body - The raw ReadableStream from the fetch response\n * @yields Parsed Ollama stream chunks\n */\nasync function* parseOllamaStream(\n body: ReadableStream<Uint8Array>\n): AsyncGenerator<OllamaStreamChunk, void, unknown> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete lines (Ollama uses newline-delimited JSON)\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const chunk = JSON.parse(trimmed) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n }\n\n buffer += decoder.decode();\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Creates the Ollama LLM handler for chat completions.\n *\n * This factory function creates an LLM handler that communicates with\n * Ollama's `/api/chat` endpoint. The handler supports both synchronous\n * completions and streaming responses.\n *\n * The handler is designed to be used with `createProvider()` which injects\n * the provider reference after construction.\n *\n * @returns An LLM handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const provider = createProvider({\n * name: 'ollama',\n * version: '1.0.0',\n * handlers: { llm: handler }\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<OllamaLLMParams> {\n let providerRef: LLMProvider<OllamaLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OllamaLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OllamaLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<OllamaLLMParams> = {\n modelId,\n capabilities: OLLAMA_CAPABILITIES,\n\n get provider(): LLMProvider<OllamaLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OllamaLLMParams>): Promise<LLMResponse> {\n // Ollama doesn't require an API key by default, but may use one for auth\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = false;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n const data = await parseJsonResponse<OllamaResponse>(response, 'ollama', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OllamaLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Ollama doesn't require an API key by default\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'ollama', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n // Parse Ollama's newline-delimited JSON stream\n for await (const chunk of parseOllamaStream(response.body)) {\n // Check for error in chunk\n if ('error' in chunk && typeof (chunk as Record<string, unknown>).error === 'string') {\n const error = new UPPError(\n (chunk as Record<string, unknown>).error as string,\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n yield event;\n // Also emit ObjectDelta for structured output - gives developers explicit hook\n if (request.structure && event.type === StreamEventType.TextDelta) {\n yield objectDelta(event.delta.text ?? '', event.index);\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Ollama Embeddings API Handler\n *\n * This module implements the embedding handler for Ollama's local embeddings API.\n * Supports various embedding models including nomic-embed-text, mxbai-embed-large,\n * qwen3-embedding, and others.\n *\n * @see {@link https://github.com/ollama/ollama/blob/main/docs/api.md#embeddings Ollama Embeddings API Reference}\n * @module providers/ollama/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Default URL for Ollama's local API */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Ollama embedding parameters.\n * Passed through to the API.\n */\nexport interface OllamaEmbedParams {\n /** Truncates the end of each input to fit within context length (default: true) */\n truncate?: boolean;\n /** Controls how long the model stays loaded in memory (e.g., '5m', '1h') */\n keep_alive?: string;\n /** Additional model options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Ollama embeddings API response structure.\n */\ninterface OllamaEmbeddingsResponse {\n model: string;\n embeddings: number[][];\n total_duration?: number;\n load_duration?: number;\n prompt_eval_count?: number;\n}\n\n/**\n * Creates an embedding handler for Ollama's local Embeddings API.\n *\n * @returns An embedding handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('nomic-embed-text');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { baseUrl: 'http://localhost:11434' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OllamaEmbedParams> {\n let providerRef: EmbeddingProvider<OllamaEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OllamaEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OllamaEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n }\n\n const model: BoundEmbeddingModel<OllamaEmbedParams> = {\n modelId,\n maxBatchSize: 512,\n maxInputLength: 8192,\n dimensions: 768, // Varies by model\n\n get provider(): EmbeddingProvider<OllamaEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OllamaEmbedParams>): Promise<EmbeddingResponse> {\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'Ollama embeddings only support text input',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n });\n\n // Build request body\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through Ollama-specific params\n if (request.params?.truncate !== undefined) {\n body.truncate = request.params.truncate;\n }\n if (request.params?.keep_alive !== undefined) {\n body.keep_alive = request.params.keep_alive;\n }\n if (request.params?.options !== undefined) {\n body.options = request.params.options;\n }\n\n const url = `${baseUrl}/api/embed`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'ollama', 'embedding');\n\n const data = await parseJsonResponse<OllamaEmbeddingsResponse>(response, 'ollama', 'embedding');\n\n // Return EmbeddingResponse\n return {\n embeddings: data.embeddings.map((vec, index) => ({\n vector: vec,\n index,\n })),\n usage: {\n totalTokens: data.prompt_eval_count ?? 0,\n },\n // Response metadata namespaced under provider (Spec 15.4)\n metadata: {\n ollama: {\n totalDuration: data.total_duration,\n loadDuration: data.load_duration,\n },\n },\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\n\n/**\n * Ollama provider for local LLM inference.\n *\n * Ollama runs models locally on your machine, eliminating the need for API keys\n * and external network calls. This makes it ideal for development, testing,\n * and privacy-sensitive applications.\n *\n * **Supported Models:**\n * - Llama 3.x (Meta's latest open-weight models)\n * - Mistral / Mixtral (Mistral AI's efficient models)\n * - Gemma (Google's lightweight models)\n * - Qwen (Alibaba's multilingual models)\n * - DeepSeek (DeepSeek's code and reasoning models)\n * - Phi (Microsoft's small language models)\n * - CodeLlama (Code-specialized Llama variants)\n * - And many more from the Ollama model library\n *\n * **Prerequisites:**\n * 1. Install Ollama from https://ollama.ai\n * 2. Pull a model: `ollama pull llama3.2`\n * 3. Ensure Ollama is running (default: http://localhost:11434)\n *\n * **Note on Tool Calling:**\n * For tool/function calling, Ollama recommends using their OpenAI-compatible\n * API endpoint. Use the OpenAI provider with `baseUrl` pointed to Ollama instead.\n *\n * @example Basic usage with local model\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Custom Ollama server URL\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({\n * model: ollama('llama3.2'),\n * config: { baseUrl: 'http://my-ollama-server:11434' },\n * });\n * ```\n *\n * @example Streaming responses\n * ```typescript\n * import { llm, StreamEventType } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const stream = model.stream('Write a poem');\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n *\n * @example Using model parameters\n * ```typescript\n * const model = llm({\n * model: ollama('llama3.2'),\n * params: {\n * temperature: 0.9,\n * top_p: 0.95,\n * num_predict: 500,\n * },\n * });\n * const result = await model.generate('Be creative!');\n * ```\n *\n * @see {@link OllamaLLMParams} for available model parameters\n */\nexport const ollama = createProvider({\n name: 'ollama',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n },\n});\n\nexport type { OllamaLLMParams, OllamaHeaders } from './types.ts';\nexport type { OllamaEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["OLLAMA_DEFAULT_URL"]}
1
+ {"version":3,"sources":["../../src/providers/ollama/transform.ts","../../src/providers/ollama/llm.ts","../../src/providers/ollama/embed.ts","../../src/providers/ollama/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation utilities for Ollama provider.\n *\n * This module handles bidirectional transformation between the Unified Provider\n * Protocol (UPP) format and Ollama's native API format. It includes:\n *\n * - Request transformation (UPP to Ollama)\n * - Response transformation (Ollama to UPP)\n * - Stream chunk processing\n * - Message format conversion\n *\n * @module providers/ollama/transform\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport type {\n OllamaLLMParams,\n OllamaRequest,\n OllamaMessage,\n OllamaTool,\n OllamaResponse,\n OllamaStreamChunk,\n OllamaOptions,\n} from './types.ts';\n\n/**\n * Normalizes system prompt to string.\n * Converts array format to concatenated string for providers that only support strings.\n */\nfunction normalizeSystem(system: string | unknown[] | undefined): string | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const texts: string[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object' || !('text' in block)) {\n throw new UPPError(\n 'System prompt array must contain objects with a text field',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n const textValue = (block as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'System prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n if (textValue.length > 0) {\n texts.push(textValue);\n }\n }\n\n return texts.length > 0 ? texts.join('\\n\\n') : undefined;\n}\n\n/**\n * Transforms UPP messages to Ollama's message format.\n *\n * Handles conversion of:\n * - User messages with text and image content\n * - Assistant messages with text and tool calls\n * - Tool result messages\n * - System prompts (prepended as first message)\n *\n * Image handling:\n * - Base64 images are passed directly\n * - Byte arrays are converted to base64\n * - URL images are converted to text placeholders (Ollama limitation)\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array, normalized to string)\n * @returns Array of Ollama-formatted messages\n */\nfunction transformMessages(messages: Message[], system?: string | unknown[]): OllamaMessage[] {\n const ollamaMessages: OllamaMessage[] = [];\n const normalizedSystem = normalizeSystem(system);\n\n // System prompt as first message\n if (normalizedSystem) {\n ollamaMessages.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const textContent: string[] = [];\n const images: string[] = [];\n\n for (const block of msg.content) {\n if (block.type === 'text') {\n textContent.push(block.text);\n } else if (block.type === 'image') {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n images.push(imageBlock.source.data);\n } else if (imageBlock.source.type === 'bytes') {\n const base64 = Buffer.from(imageBlock.source.data).toString('base64');\n images.push(base64);\n } else if (imageBlock.source.type === 'url') {\n // Ollama doesn't support URL images directly\n // Would need to fetch and convert, for now just add as text\n textContent.push(`[Image: ${imageBlock.source.url}]`);\n }\n }\n }\n\n const message: OllamaMessage = {\n role: 'user',\n content: textContent.join('\\n'),\n };\n\n if (images.length > 0) {\n message.images = images;\n }\n\n ollamaMessages.push(message);\n } else if (isAssistantMessage(msg)) {\n // Filter for text blocks only (exclude reasoning blocks from history)\n // Also strip any <think>...</think> tags that may be embedded in text\n // (required for proper multi-turn with Qwen 3, DeepSeek-R1, etc.)\n const textContent = msg.content\n .filter((block): block is TextBlock => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .replace(/<think>[\\s\\S]*?<\\/think>/g, '')\n .trim();\n\n const message: OllamaMessage = {\n role: 'assistant',\n content: textContent,\n };\n\n // Add tool calls if present\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n message.tool_calls = msg.toolCalls.map((call) => ({\n function: {\n name: call.toolName,\n arguments: call.arguments,\n },\n }));\n }\n\n ollamaMessages.push(message);\n } else if (isToolResultMessage(msg)) {\n // Tool results are sent as 'tool' role messages\n for (const result of msg.results) {\n // Extract tool name from toolCallId (format: {name}_{index})\n const underscoreIndex = result.toolCallId.lastIndexOf('_');\n const toolName = underscoreIndex > 0\n ? result.toolCallId.slice(0, underscoreIndex)\n : result.toolCallId;\n ollamaMessages.push({\n role: 'tool',\n tool_name: toolName,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n });\n }\n }\n }\n\n return ollamaMessages;\n}\n\n/**\n * Transforms a UPP tool definition to Ollama's function format.\n *\n * Ollama uses the OpenAI-style function calling format with a\n * `type: 'function'` wrapper around the function definition.\n *\n * @param tool - The UPP tool definition\n * @returns The Ollama-formatted tool definition\n */\nfunction transformTool(tool: Tool): OllamaTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms a UPP LLM request into Ollama's native API format.\n *\n * This function handles the mapping between UPP's unified request structure\n * and Ollama's specific requirements, including:\n *\n * - Converting messages to Ollama's message format\n * - Mapping model parameters to Ollama's nested `options` structure\n * - Handling top-level parameters like `keep_alive` and `think`\n * - Converting tools to Ollama's function format\n * - Setting up structured output via the `format` field\n *\n * Parameters are spread to allow pass-through of any Ollama API fields,\n * enabling developers to use new API features without library updates.\n *\n * @typeParam TParams - The parameter type extending OllamaLLMParams\n * @param request - The UPP-format LLM request\n * @param modelId - The Ollama model identifier (e.g., 'llama3.2', 'mistral')\n * @returns The transformed Ollama API request body\n *\n * @example\n * ```typescript\n * const ollamaRequest = transformRequest(\n * {\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * config: {},\n * params: { temperature: 0.7 }\n * },\n * 'llama3.2'\n * );\n * ```\n */\nexport function transformRequest<TParams extends OllamaLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): OllamaRequest {\n const params = (request.params ?? {}) as OllamaLLMParams;\n\n // Extract top-level params vs options params\n const {\n keep_alive,\n think,\n logprobs,\n top_logprobs,\n ...optionsParams\n } = params;\n\n // Spread params to pass through all fields, then set required fields\n const ollamaRequest: OllamaRequest = {\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n // Add top-level params if provided\n if (keep_alive !== undefined) ollamaRequest.keep_alive = keep_alive;\n if (think !== undefined) ollamaRequest.think = think;\n if (logprobs !== undefined) ollamaRequest.logprobs = logprobs;\n if (top_logprobs !== undefined) ollamaRequest.top_logprobs = top_logprobs;\n\n // Spread remaining params into options to pass through all model parameters\n if (Object.keys(optionsParams).length > 0) {\n ollamaRequest.options = optionsParams as OllamaOptions;\n }\n\n // Tools come from request, not params\n if (request.tools && request.tools.length > 0) {\n ollamaRequest.tools = request.tools.map(transformTool);\n }\n\n // Structured output via format field\n if (request.structure) {\n ollamaRequest.format = request.structure as unknown as Record<string, unknown>;\n }\n\n return ollamaRequest;\n}\n\n/**\n * Transforms an Ollama API response to the UPP LLMResponse format.\n *\n * This function extracts and normalizes:\n * - Text content from the assistant message\n * - Tool calls with their arguments\n * - Token usage statistics (prompt + completion tokens)\n * - Stop reason mapping (stop -> end_turn, length -> max_tokens)\n * - Ollama-specific metadata (timings, model info, thinking content)\n *\n * For structured output requests, the response content is automatically\n * parsed as JSON and stored in the `data` field.\n *\n * @param data - The raw Ollama API response\n * @returns The normalized UPP LLM response\n */\nexport function transformResponse(data: OllamaResponse): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (data.message.thinking) {\n content.push({ type: 'reasoning', text: data.message.thinking });\n }\n\n // Add main content\n if (data.message.content) {\n content.push({ type: 'text', text: data.message.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(data.message.content);\n } catch {\n // Not valid JSON - that's fine, might not be structured output\n }\n }\n\n // Extract tool calls\n if (data.message.tool_calls) {\n for (let idx = 0; idx < data.message.tool_calls.length; idx++) {\n const call = data.message.tool_calls[idx]!;\n const index = call.function.index ?? idx;\n toolCalls.push({\n toolCallId: `${call.function.name}_${index}`,\n toolName: call.function.name,\n arguments: call.function.arguments,\n });\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: data.model,\n created_at: data.created_at,\n done_reason: data.done_reason,\n thinking: data.message.thinking,\n total_duration: data.total_duration,\n load_duration: data.load_duration,\n prompt_eval_duration: data.prompt_eval_duration,\n eval_duration: data.eval_duration,\n logprobs: data.logprobs,\n },\n },\n }\n );\n\n // Calculate token usage (Ollama doesn't support API-level prompt caching)\n const usage: TokenUsage = {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n totalTokens: (data.prompt_eval_count ?? 0) + (data.eval_count ?? 0),\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (data.done_reason === 'length') {\n stopReason = 'max_tokens';\n } else if (data.done_reason === 'stop') {\n stopReason = 'end_turn';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating data during stream processing.\n *\n * As streaming chunks arrive, this state object accumulates content,\n * tool calls, and metadata. Once the stream completes (indicated by\n * `done: true`), this state is used to build the final LLMResponse.\n */\nexport interface StreamState {\n /** The model name from the stream. */\n model: string;\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated thinking/reasoning content (for models with think mode). */\n thinking: string;\n /** Tool calls extracted from the stream. */\n toolCalls: Array<{ name: string; args: Record<string, unknown> }>;\n /** The reason the generation stopped (stop, length, etc.). */\n doneReason: string | null;\n /** Number of tokens in the prompt evaluation. */\n promptEvalCount: number;\n /** Number of tokens generated in the response. */\n evalCount: number;\n /** Total generation duration in nanoseconds. */\n totalDuration: number;\n /** Whether we're still waiting for the first chunk. */\n isFirstChunk: boolean;\n /** ISO timestamp when the response was created. */\n createdAt: string;\n}\n\n/**\n * Creates an initial empty stream state for accumulating streaming responses.\n *\n * @returns A fresh StreamState object with default values\n */\nexport function createStreamState(): StreamState {\n return {\n model: '',\n content: '',\n thinking: '',\n toolCalls: [],\n doneReason: null,\n promptEvalCount: 0,\n evalCount: 0,\n totalDuration: 0,\n isFirstChunk: true,\n createdAt: '',\n };\n}\n\n/**\n * Transforms an Ollama stream chunk into UPP StreamEvents.\n *\n * Each Ollama chunk may produce zero or more UPP events:\n * - First chunk: `message_start` event\n * - Content chunks: `text_delta` events\n * - Thinking chunks: `reasoning_delta` events\n * - Tool call chunks: `tool_call_delta` events\n * - Final chunk (done=true): `message_stop` event\n *\n * The function also updates the provided state object with accumulated\n * content and metadata for building the final response.\n *\n * @param chunk - The raw Ollama stream chunk\n * @param state - Mutable state object to accumulate data\n * @returns Array of UPP stream events (may be empty)\n */\nexport function transformStreamChunk(\n chunk: OllamaStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n // First chunk - emit message start\n if (state.isFirstChunk) {\n state.model = chunk.model;\n state.createdAt = chunk.created_at;\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n // Process message content\n if (chunk.message) {\n // Text content delta\n if (chunk.message.content) {\n state.content += chunk.message.content;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: chunk.message.content },\n });\n }\n\n // Thinking content delta\n if (chunk.message.thinking) {\n state.thinking += chunk.message.thinking;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: chunk.message.thinking },\n });\n }\n\n // Tool calls (typically come in final chunk)\n if (chunk.message.tool_calls) {\n for (const call of chunk.message.tool_calls) {\n const idx = state.toolCalls.length;\n const toolCallId = `${call.function.name}_${call.function.index ?? idx}`;\n state.toolCalls.push({\n name: call.function.name,\n args: call.function.arguments,\n });\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: idx,\n delta: {\n toolCallId,\n toolName: call.function.name,\n argumentsJson: JSON.stringify(call.function.arguments),\n },\n });\n }\n }\n }\n\n // Final chunk with metrics\n if (chunk.done) {\n state.doneReason = chunk.done_reason ?? null;\n state.promptEvalCount = chunk.prompt_eval_count ?? 0;\n state.evalCount = chunk.eval_count ?? 0;\n state.totalDuration = chunk.total_duration ?? 0;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated stream state.\n *\n * Called after the stream completes to construct the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * For structured output, attempts to parse the accumulated content as JSON\n * and stores it in the `data` field if successful.\n *\n * @param state - The accumulated stream state\n * @returns The complete UPP LLM response\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n // Add reasoning/thinking content first (if present)\n if (state.thinking) {\n content.push({ type: 'reasoning', text: state.thinking });\n }\n\n if (state.content) {\n content.push({ type: 'text', text: state.content });\n\n // Try to parse as JSON for structured output\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not valid JSON - that's fine\n }\n }\n\n for (let idx = 0; idx < state.toolCalls.length; idx++) {\n const tc = state.toolCalls[idx]!;\n toolCalls.push({\n toolCallId: `${tc.name}_${idx}`,\n toolName: tc.name,\n arguments: tc.args,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n ollama: {\n model: state.model,\n created_at: state.createdAt,\n done_reason: state.doneReason,\n thinking: state.thinking || undefined,\n total_duration: state.totalDuration,\n },\n },\n }\n );\n\n // Ollama doesn't support API-level prompt caching\n const usage: TokenUsage = {\n inputTokens: state.promptEvalCount,\n outputTokens: state.evalCount,\n totalTokens: state.promptEvalCount + state.evalCount,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n };\n\n // Map done_reason to standard stop reason\n let stopReason = 'end_turn';\n if (state.doneReason === 'length') {\n stopReason = 'max_tokens';\n } else if (toolCalls.length > 0) {\n stopReason = 'tool_use';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * @fileoverview Ollama LLM handler implementation.\n *\n * This module provides the core LLM functionality for the Ollama provider,\n * including both synchronous completion and streaming capabilities. It\n * communicates with Ollama's native `/api/chat` endpoint.\n *\n * @module providers/ollama/llm\n */\n\nimport type {\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { LLMHandler } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType, objectDelta } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OllamaLLMParams, OllamaResponse, OllamaStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Default Ollama server URL for local installations. */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Capability flags for the Ollama provider.\n */\nconst OLLAMA_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n documentInput: false,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Parses Ollama's newline-delimited JSON (NDJSON) stream format.\n *\n * Ollama uses NDJSON where each line is a complete JSON object representing\n * a streaming chunk. This generator reads the stream incrementally, buffering\n * incomplete lines and yielding parsed chunks as they become available.\n *\n * @param body - The raw ReadableStream from the fetch response\n * @yields Parsed Ollama stream chunks\n */\nasync function* parseOllamaStream(\n body: ReadableStream<Uint8Array>\n): AsyncGenerator<OllamaStreamChunk, void, unknown> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete lines (Ollama uses newline-delimited JSON)\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const chunk = JSON.parse(trimmed) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n }\n\n buffer += decoder.decode();\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaStreamChunk;\n yield chunk;\n } catch (error) {\n throw new UPPError(\n 'Invalid JSON in Ollama stream',\n ErrorCode.InvalidResponse,\n 'ollama',\n ModalityType.LLM,\n undefined,\n toError(error)\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Creates the Ollama LLM handler for chat completions.\n *\n * This factory function creates an LLM handler that communicates with\n * Ollama's `/api/chat` endpoint. The handler supports both synchronous\n * completions and streaming responses.\n *\n * The handler is designed to be used with `createProvider()` which injects\n * the provider reference after construction.\n *\n * @returns An LLM handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const provider = createProvider({\n * name: 'ollama',\n * version: '1.0.0',\n * handlers: { llm: handler }\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<OllamaLLMParams> {\n let providerRef: LLMProvider<OllamaLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OllamaLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OllamaLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<OllamaLLMParams> = {\n modelId,\n capabilities: OLLAMA_CAPABILITIES,\n\n get provider(): LLMProvider<OllamaLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OllamaLLMParams>): Promise<LLMResponse> {\n // Ollama doesn't require an API key by default, but may use one for auth\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = false;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n const data = await parseJsonResponse<OllamaResponse>(response, 'ollama', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OllamaLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Ollama doesn't require an API key by default\n let apiKey: string | undefined;\n try {\n apiKey = await resolveApiKey(\n request.config,\n 'OLLAMA_API_KEY',\n 'ollama',\n 'llm'\n );\n } catch {\n // API key is optional for Ollama\n }\n\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n const url = `${baseUrl}/api/chat`;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (apiKey) {\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'ollama',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'ollama', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n // Parse Ollama's newline-delimited JSON stream\n for await (const chunk of parseOllamaStream(response.body)) {\n // Check for error in chunk\n if ('error' in chunk && typeof (chunk as Record<string, unknown>).error === 'string') {\n const error = new UPPError(\n (chunk as Record<string, unknown>).error as string,\n ErrorCode.ProviderError,\n 'ollama',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n yield event;\n // Also emit ObjectDelta for structured output - gives developers explicit hook\n if (request.structure && event.type === StreamEventType.TextDelta) {\n yield objectDelta(event.delta.text ?? '', event.index);\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Ollama Embeddings API Handler\n *\n * This module implements the embedding handler for Ollama's local embeddings API.\n * Supports various embedding models including nomic-embed-text, mxbai-embed-large,\n * qwen3-embedding, and others.\n *\n * @see {@link https://github.com/ollama/ollama/blob/main/docs/api.md#embeddings Ollama Embeddings API Reference}\n * @module providers/ollama/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Default URL for Ollama's local API */\nconst OLLAMA_DEFAULT_URL = 'http://localhost:11434';\n\n/**\n * Ollama embedding parameters.\n * Passed through to the API.\n */\nexport interface OllamaEmbedParams {\n /** Truncates the end of each input to fit within context length (default: true) */\n truncate?: boolean;\n /** Controls how long the model stays loaded in memory (e.g., '5m', '1h') */\n keep_alive?: string;\n /** Additional model options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Ollama embeddings API response structure.\n */\ninterface OllamaEmbeddingsResponse {\n model: string;\n embeddings: number[][];\n total_duration?: number;\n load_duration?: number;\n prompt_eval_count?: number;\n}\n\n/**\n * Creates an embedding handler for Ollama's local Embeddings API.\n *\n * @returns An embedding handler configured for Ollama\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('nomic-embed-text');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { baseUrl: 'http://localhost:11434' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OllamaEmbedParams> {\n let providerRef: EmbeddingProvider<OllamaEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OllamaEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OllamaEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n }\n\n const model: BoundEmbeddingModel<OllamaEmbedParams> = {\n modelId,\n maxBatchSize: 512,\n maxInputLength: 8192,\n dimensions: 768, // Varies by model\n\n get provider(): EmbeddingProvider<OllamaEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OllamaEmbedParams>): Promise<EmbeddingResponse> {\n const baseUrl = request.config.baseUrl ?? OLLAMA_DEFAULT_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'Ollama embeddings only support text input',\n ErrorCode.InvalidRequest,\n 'ollama',\n ModalityType.Embedding\n );\n });\n\n // Build request body\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through Ollama-specific params\n if (request.params?.truncate !== undefined) {\n body.truncate = request.params.truncate;\n }\n if (request.params?.keep_alive !== undefined) {\n body.keep_alive = request.params.keep_alive;\n }\n if (request.params?.options !== undefined) {\n body.options = request.params.options;\n }\n\n const url = `${baseUrl}/api/embed`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'ollama', 'embedding');\n\n const data = await parseJsonResponse<OllamaEmbeddingsResponse>(response, 'ollama', 'embedding');\n\n // Return EmbeddingResponse\n return {\n embeddings: data.embeddings.map((vec, index) => ({\n vector: vec,\n index,\n })),\n usage: {\n totalTokens: data.prompt_eval_count ?? 0,\n },\n // Response metadata namespaced under provider (Spec 15.4)\n metadata: {\n ollama: {\n totalDuration: data.total_duration,\n loadDuration: data.load_duration,\n },\n },\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\n\n/**\n * Ollama provider for local LLM inference.\n *\n * Ollama runs models locally on your machine, eliminating the need for API keys\n * and external network calls. This makes it ideal for development, testing,\n * and privacy-sensitive applications.\n *\n * **Supported Models:**\n * - Llama 3.x (Meta's latest open-weight models)\n * - Mistral / Mixtral (Mistral AI's efficient models)\n * - Gemma (Google's lightweight models)\n * - Qwen (Alibaba's multilingual models)\n * - DeepSeek (DeepSeek's code and reasoning models)\n * - Phi (Microsoft's small language models)\n * - CodeLlama (Code-specialized Llama variants)\n * - And many more from the Ollama model library\n *\n * **Prerequisites:**\n * 1. Install Ollama from https://ollama.ai\n * 2. Pull a model: `ollama pull llama3.2`\n * 3. Ensure Ollama is running (default: http://localhost:11434)\n *\n * **Note on Tool Calling:**\n * For tool/function calling, Ollama recommends using their OpenAI-compatible\n * API endpoint. Use the OpenAI provider with `baseUrl` pointed to Ollama instead.\n *\n * @example Basic usage with local model\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Custom Ollama server URL\n * ```typescript\n * import { llm } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({\n * model: ollama('llama3.2'),\n * config: { baseUrl: 'http://my-ollama-server:11434' },\n * });\n * ```\n *\n * @example Streaming responses\n * ```typescript\n * import { llm, StreamEventType } from 'provider-protocol';\n * import { ollama } from 'provider-protocol/ollama';\n *\n * const model = llm({ model: ollama('llama3.2') });\n * const stream = model.stream('Write a poem');\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n *\n * @example Using model parameters\n * ```typescript\n * const model = llm({\n * model: ollama('llama3.2'),\n * params: {\n * temperature: 0.9,\n * top_p: 0.95,\n * num_predict: 500,\n * },\n * });\n * const result = await model.generate('Be creative!');\n * ```\n *\n * @see {@link OllamaLLMParams} for available model parameters\n */\nexport const ollama = createProvider({\n name: 'ollama',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n },\n});\n\nexport type { OllamaLLMParams, OllamaHeaders } from './types.ts';\nexport type { OllamaEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["OLLAMA_DEFAULT_URL"]}
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-ByUFPcFH.js';
2
- import '../stream-S7nwQRqM.js';
1
+ import { e as Provider } from '../llm-DS_-l71X.js';
2
+ import '../stream-sXhBtWjl.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview OpenAI Provider Type Definitions
@@ -6,35 +6,37 @@ import {
6
6
  } from "../chunk-PMK5LZ5Z.js";
7
7
  import {
8
8
  parseJsonResponse
9
- } from "../chunk-A2IM7PGT.js";
9
+ } from "../chunk-TUTYMOBL.js";
10
10
  import {
11
11
  resolveApiKey
12
12
  } from "../chunk-ARVM24K2.js";
13
13
  import {
14
14
  createProvider
15
15
  } from "../chunk-JA3UZALR.js";
16
+ import {
17
+ doFetch,
18
+ doStreamFetch,
19
+ normalizeHttpError
20
+ } from "../chunk-SBGZJVTJ.js";
21
+ import {
22
+ StreamEventType,
23
+ objectDelta
24
+ } from "../chunk-MJI74VEJ.js";
16
25
  import {
17
26
  AssistantMessage,
18
27
  generateId,
19
28
  isAssistantMessage,
20
29
  isToolResultMessage,
21
30
  isUserMessage
22
- } from "../chunk-BRP5XJ6Q.js";
31
+ } from "../chunk-WU4U6IHF.js";
23
32
  import {
24
- doFetch,
25
- doStreamFetch,
26
- normalizeHttpError,
27
33
  toError
28
- } from "../chunk-AY55T37A.js";
34
+ } from "../chunk-GIDT7C6I.js";
29
35
  import {
30
36
  ErrorCode,
31
37
  ModalityType,
32
38
  UPPError
33
39
  } from "../chunk-COS4ON4G.js";
34
- import {
35
- StreamEventType,
36
- objectDelta
37
- } from "../chunk-RJGTRQ47.js";
38
40
 
39
41
  // src/providers/openai/transform.completions.ts
40
42
  function normalizeSystem(system) {