@providerprotocol/ai 0.0.38 → 0.0.40

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 (136) hide show
  1. package/README.md +363 -37
  2. package/dist/anthropic/index.d.ts +3 -2
  3. package/dist/anthropic/index.js +7 -5
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/cerebras/index.d.ts +3 -2
  6. package/dist/cerebras/index.js +7 -5
  7. package/dist/cerebras/index.js.map +1 -1
  8. package/dist/chunk-3Q5VELKG.js +124 -0
  9. package/dist/chunk-3Q5VELKG.js.map +1 -0
  10. package/dist/{chunk-WU4U6IHF.js → chunk-6QCV4WXF.js} +4 -13
  11. package/dist/chunk-6QCV4WXF.js.map +1 -0
  12. package/dist/{chunk-LTEMH3CI.js → chunk-AC3VHSZJ.js} +6 -4
  13. package/dist/{chunk-LTEMH3CI.js.map → chunk-AC3VHSZJ.js.map} +1 -1
  14. package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
  15. package/dist/chunk-BIBMNP7Y.js.map +1 -0
  16. package/dist/{chunk-CRP6Y7NF.js → chunk-CWGTARDE.js} +2 -2
  17. package/dist/{chunk-ZRVNAET3.js → chunk-DI47UY2H.js} +6 -3
  18. package/dist/chunk-DI47UY2H.js.map +1 -0
  19. package/dist/{chunk-7GTWHZY2.js → chunk-EHR3LIPS.js} +5 -3
  20. package/dist/{chunk-7GTWHZY2.js.map → chunk-EHR3LIPS.js.map} +1 -1
  21. package/dist/chunk-EY2LLDGY.js +94 -0
  22. package/dist/chunk-EY2LLDGY.js.map +1 -0
  23. package/dist/{chunk-MJI74VEJ.js → chunk-F5ENANMJ.js} +18 -2
  24. package/dist/chunk-F5ENANMJ.js.map +1 -0
  25. package/dist/chunk-IKJH5ZSJ.js +1 -0
  26. package/dist/chunk-IKJH5ZSJ.js.map +1 -0
  27. package/dist/{chunk-4RX4VQCB.js → chunk-KBI45OXI.js} +2 -2
  28. package/dist/{chunk-5IWHCXKN.js → chunk-KVUOTFYZ.js} +2 -2
  29. package/dist/{chunk-EPB3GQNL.js → chunk-L6QWKFGE.js} +13 -3
  30. package/dist/chunk-L6QWKFGE.js.map +1 -0
  31. package/dist/{chunk-BDXH6NQS.js → chunk-N4LAFGLX.js} +7 -7
  32. package/dist/{chunk-ZKNPQBIE.js → chunk-R3T2IYOU.js} +5 -3
  33. package/dist/{chunk-ZKNPQBIE.js.map → chunk-R3T2IYOU.js.map} +1 -1
  34. package/dist/chunk-U2G5PHHL.js +25 -0
  35. package/dist/chunk-U2G5PHHL.js.map +1 -0
  36. package/dist/{chunk-SBGZJVTJ.js → chunk-VQZPADW6.js} +100 -33
  37. package/dist/chunk-VQZPADW6.js.map +1 -0
  38. package/dist/{chunk-FYSZFIZS.js → chunk-XTWBAL42.js} +5 -3
  39. package/dist/{chunk-FYSZFIZS.js.map → chunk-XTWBAL42.js.map} +1 -1
  40. package/dist/{chunk-2YXFLRQ6.js → chunk-ZMESKGUY.js} +2 -2
  41. package/dist/chunk-ZSZVWLGE.js +83 -0
  42. package/dist/chunk-ZSZVWLGE.js.map +1 -0
  43. package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-ts1npsDg.d.ts} +1 -1
  44. package/dist/google/index.d.ts +38 -3
  45. package/dist/google/index.js +5 -4
  46. package/dist/google/index.js.map +1 -1
  47. package/dist/groq/index.d.ts +3 -2
  48. package/dist/groq/index.js +7 -5
  49. package/dist/groq/index.js.map +1 -1
  50. package/dist/http/index.d.ts +5 -4
  51. package/dist/http/index.js +19 -22
  52. package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-BPml2YZZ.d.ts} +1 -1
  53. package/dist/index.d.ts +8 -7
  54. package/dist/index.js +316 -113
  55. package/dist/index.js.map +1 -1
  56. package/dist/{llm-DS_-l71X.d.ts → llm-BWLaTzzY.d.ts} +89 -36
  57. package/dist/middleware/logging/index.d.ts +3 -2
  58. package/dist/middleware/logging/index.js +3 -0
  59. package/dist/middleware/logging/index.js.map +1 -1
  60. package/dist/middleware/parsed-object/index.d.ts +3 -2
  61. package/dist/middleware/parsed-object/index.js +5 -1
  62. package/dist/middleware/parsed-object/index.js.map +1 -1
  63. package/dist/middleware/persistence/index.d.ts +3 -2
  64. package/dist/middleware/persistence/index.js +3 -2
  65. package/dist/middleware/persistence/index.js.map +1 -1
  66. package/dist/middleware/pipeline/index.d.ts +195 -0
  67. package/dist/middleware/pipeline/index.js +61 -0
  68. package/dist/middleware/pipeline/index.js.map +1 -0
  69. package/dist/middleware/pubsub/index.d.ts +13 -10
  70. package/dist/middleware/pubsub/index.js +78 -6
  71. package/dist/middleware/pubsub/index.js.map +1 -1
  72. package/dist/middleware/pubsub/server/express/index.d.ts +3 -2
  73. package/dist/middleware/pubsub/server/express/index.js +2 -2
  74. package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -2
  75. package/dist/middleware/pubsub/server/fastify/index.js +2 -2
  76. package/dist/middleware/pubsub/server/h3/index.d.ts +3 -2
  77. package/dist/middleware/pubsub/server/h3/index.js +2 -2
  78. package/dist/middleware/pubsub/server/index.d.ts +50 -8
  79. package/dist/middleware/pubsub/server/index.js +5 -5
  80. package/dist/middleware/pubsub/server/index.js.map +1 -1
  81. package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -2
  82. package/dist/middleware/pubsub/server/webapi/index.js +2 -2
  83. package/dist/moonshot/index.d.ts +3 -2
  84. package/dist/moonshot/index.js +7 -5
  85. package/dist/moonshot/index.js.map +1 -1
  86. package/dist/ollama/index.d.ts +24 -3
  87. package/dist/ollama/index.js +5 -4
  88. package/dist/ollama/index.js.map +1 -1
  89. package/dist/openai/index.d.ts +65 -3
  90. package/dist/openai/index.js +7 -5
  91. package/dist/openai/index.js.map +1 -1
  92. package/dist/openrouter/index.d.ts +4 -3
  93. package/dist/openrouter/index.js +7 -5
  94. package/dist/openrouter/index.js.map +1 -1
  95. package/dist/proxy/index.d.ts +5 -4
  96. package/dist/proxy/index.js +20 -17
  97. package/dist/proxy/index.js.map +1 -1
  98. package/dist/proxy/server/express/index.d.ts +8 -8
  99. package/dist/proxy/server/express/index.js +5 -3
  100. package/dist/proxy/server/fastify/index.d.ts +8 -8
  101. package/dist/proxy/server/fastify/index.js +5 -3
  102. package/dist/proxy/server/h3/index.d.ts +22 -21
  103. package/dist/proxy/server/h3/index.js +5 -3
  104. package/dist/proxy/server/index.d.ts +5 -4
  105. package/dist/proxy/server/index.js +15 -13
  106. package/dist/proxy/server/webapi/index.d.ts +8 -8
  107. package/dist/proxy/server/webapi/index.js +5 -3
  108. package/dist/responses/index.d.ts +3 -2
  109. package/dist/responses/index.js +7 -5
  110. package/dist/responses/index.js.map +1 -1
  111. package/dist/retry-DVfdPLIB.d.ts +322 -0
  112. package/dist/{stream-sXhBtWjl.d.ts → stream-bBd_4Ipu.d.ts} +29 -419
  113. package/dist/tool-BmAfKNBq.d.ts +507 -0
  114. package/dist/{types-Cr4F0tVy.d.ts → types-nTwlpyJE.d.ts} +28 -3
  115. package/dist/utils/index.d.ts +129 -1
  116. package/dist/utils/index.js +28 -1
  117. package/dist/xai/index.d.ts +3 -2
  118. package/dist/xai/index.js +7 -5
  119. package/dist/xai/index.js.map +1 -1
  120. package/package.json +20 -3
  121. package/dist/chunk-ARVM24K2.js +0 -128
  122. package/dist/chunk-ARVM24K2.js.map +0 -1
  123. package/dist/chunk-EPB3GQNL.js.map +0 -1
  124. package/dist/chunk-MJI74VEJ.js.map +0 -1
  125. package/dist/chunk-SBGZJVTJ.js.map +0 -1
  126. package/dist/chunk-WU4U6IHF.js.map +0 -1
  127. package/dist/chunk-Y5H7C5J4.js +0 -263
  128. package/dist/chunk-Y5H7C5J4.js.map +0 -1
  129. package/dist/chunk-YQLR3XOA.js.map +0 -1
  130. package/dist/chunk-ZRVNAET3.js.map +0 -1
  131. package/dist/retry-CgoBNa51.d.ts +0 -531
  132. /package/dist/{chunk-CRP6Y7NF.js.map → chunk-CWGTARDE.js.map} +0 -0
  133. /package/dist/{chunk-4RX4VQCB.js.map → chunk-KBI45OXI.js.map} +0 -0
  134. /package/dist/{chunk-5IWHCXKN.js.map → chunk-KVUOTFYZ.js.map} +0 -0
  135. /package/dist/{chunk-BDXH6NQS.js.map → chunk-N4LAFGLX.js.map} +0 -0
  136. /package/dist/{chunk-2YXFLRQ6.js.map → chunk-ZMESKGUY.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/cerebras/transform.ts","../../src/providers/cerebras/llm.ts","../../src/providers/cerebras/index.ts"],"sourcesContent":["/**\n * @fileoverview Cerebras API Message Transformers\n *\n * This module provides transformation functions for converting between the\n * Universal Provider Protocol (UPP) message format and Cerebras's Chat Completions\n * API format (OpenAI-compatible). It handles both request transformation (UPP -> Cerebras)\n * and response transformation (Cerebras -> UPP), including streaming event transformation.\n *\n * @module providers/cerebras/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 } 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 CerebrasLLMParams,\n CerebrasRequest,\n CerebrasMessage,\n CerebrasUserContent,\n CerebrasTool,\n CerebrasResponse,\n CerebrasStreamChunk,\n CerebrasToolCall,\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 'cerebras',\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 'cerebras',\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 'cerebras',\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 Cerebras user content format.\n */\nfunction transformContentBlock(block: ContentBlock): CerebrasUserContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image':\n throw new UPPError(\n 'Cerebras does not support image input',\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n\n case 'document':\n throw new UPPError(\n 'Cerebras does not support document input',\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n\n default:\n throw new UPPError(\n `Unsupported content type: ${block.type}`,\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Transforms a single UPP message to Cerebras format.\n */\nfunction transformMessage(message: Message): CerebrasMessage | 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 const assistantMessage: CerebrasMessage = {\n role: 'assistant',\n content: textContent || null,\n };\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n (assistantMessage as { tool_calls?: CerebrasToolCall[] }).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 Cerebras tool messages.\n */\nexport function transformToolResults(message: Message): CerebrasMessage[] {\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 Cerebras message format.\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt\n * @returns Array of Cerebras-formatted messages\n */\nfunction transformMessages(\n messages: Message[],\n system?: string | unknown[]\n): CerebrasMessage[] {\n const result: CerebrasMessage[] = [];\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 Cerebras-specific options from tool metadata.\n */\nfunction extractToolOptions(tool: Tool): { strict?: boolean } {\n const cerebrasMeta = tool.metadata?.cerebras as { strict?: boolean } | undefined;\n return { strict: cerebrasMeta?.strict };\n}\n\n/**\n * Transforms a UPP tool definition to Cerebras function tool format.\n */\nfunction transformTool(tool: Tool): CerebrasTool {\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 Cerebras Chat Completions API format.\n *\n * @param request - The UPP LLM request containing messages, tools, and configuration\n * @param modelId - The Cerebras model identifier (e.g., 'llama-3.3-70b')\n * @returns A Cerebras Chat Completions API request body\n */\nexport function transformRequest(\n request: LLMRequest<CerebrasLLMParams>,\n modelId: string\n): CerebrasRequest {\n const params = request.params ?? ({} as CerebrasLLMParams);\n\n const cerebrasRequest: CerebrasRequest = {\n ...params,\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n cerebrasRequest.tools = request.tools.map(transformTool);\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 cerebrasRequest.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 cerebrasRequest;\n}\n\n/**\n * Transforms a Cerebras response to UPP LLMResponse format.\n */\nexport function transformResponse(data: CerebrasResponse): LLMResponse {\n const choice = data.choices[0];\n if (!choice) {\n throw new UPPError(\n 'No choices in Cerebras response',\n ErrorCode.InvalidResponse,\n 'cerebras',\n ModalityType.LLM\n );\n }\n\n const textContent: TextBlock[] = [];\n let structuredData: unknown;\n if (choice.message.content) {\n textContent.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 textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id || generateId(),\n metadata: {\n cerebras: {\n model: data.model,\n finish_reason: choice.finish_reason,\n system_fingerprint: data.system_fingerprint,\n reasoning: choice.message.reasoning,\n time_info: data.time_info,\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 CerebrasStreamState {\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 */\n reasoning: 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 /** Time info from the response */\n timeInfo?: {\n queue_time?: number;\n prompt_time?: number;\n completion_time?: number;\n total_time?: number;\n };\n}\n\n/**\n * Creates a fresh stream state object for a new streaming session.\n */\nexport function createStreamState(): CerebrasStreamState {\n return {\n id: '',\n model: '',\n text: '',\n reasoning: '',\n toolCalls: new Map(),\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n };\n}\n\n/**\n * Transforms a Cerebras streaming chunk into UPP stream events.\n */\nexport function transformStreamEvent(\n chunk: CerebrasStreamChunk,\n state: CerebrasStreamState\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.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.reasoning) {\n state.reasoning += choice.delta.reasoning;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: choice.delta.reasoning },\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 if (chunk.time_info) {\n state.timeInfo = chunk.time_info;\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated streaming state.\n */\nexport function buildResponseFromState(state: CerebrasStreamState): LLMResponse {\n const textContent: TextBlock[] = [];\n let structuredData: unknown;\n if (state.text) {\n textContent.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 textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: messageId,\n metadata: {\n cerebras: {\n model: state.model,\n finish_reason: state.finishReason,\n reasoning: state.reasoning || undefined,\n time_info: state.timeInfo,\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 Cerebras Chat Completions API Handler\n *\n * This module implements the LLM handler for Cerebras's Chat Completions API\n * (OpenAI-compatible at `/v1/chat/completions`).\n *\n * @see {@link https://inference-docs.cerebras.ai/introduction Cerebras API Reference}\n * @module providers/cerebras/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 } 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 { CerebrasLLMParams, CerebrasResponse, CerebrasStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Base URL for Cerebras's Chat Completions API endpoint */\nconst CEREBRAS_API_URL = 'https://api.cerebras.ai/v1/chat/completions';\n\n/**\n * Capability declaration for the Cerebras 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: Not supported\n */\nconst CEREBRAS_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: false,\n documentInput: false,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for Cerebras'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 Cerebras API\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const model = handler.bind('llama-3.3-70b');\n *\n * // Synchronous completion\n * const response = await model.complete({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * config: { apiKey: 'csk-...' }\n * });\n *\n * // Streaming completion\n * const stream = model.stream({\n * messages: [{ role: 'user', content: 'Tell me a story' }],\n * config: { apiKey: 'csk-...' }\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<CerebrasLLMParams> {\n let providerRef: LLMProvider<CerebrasLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<CerebrasLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<CerebrasLLMParams> {\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 'cerebras',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<CerebrasLLMParams> = {\n modelId,\n capabilities: CEREBRAS_CAPABILITIES,\n\n get provider(): LLMProvider<CerebrasLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<CerebrasLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'CEREBRAS_API_KEY',\n 'cerebras',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? CEREBRAS_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 'cerebras',\n 'llm'\n );\n\n const data = await parseJsonResponse<CerebrasResponse>(response, 'cerebras', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<CerebrasLLMParams>): 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 resolveApiKey(\n request.config,\n 'CEREBRAS_API_KEY',\n 'cerebras',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? CEREBRAS_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 'cerebras',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'cerebras', '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 'cerebras',\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 Cerebras error event\n if (typeof data === 'object' && data !== null) {\n const chunk = data as CerebrasStreamChunk;\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 'cerebras',\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 Cerebras Provider Factory\n *\n * This module provides the main Cerebras provider implementation for the\n * OpenAI-compatible Chat Completions API. Cerebras offers extremely fast\n * inference with models like Llama, Qwen, and their reasoning models.\n *\n * @module providers/cerebras\n */\n\nimport { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\n\n/**\n * Configuration options for the Cerebras provider.\n *\n * Currently Cerebras only supports one API endpoint (Chat Completions),\n * so no additional options are needed.\n */\nexport interface CerebrasProviderOptions {\n // Reserved for future use (e.g., if Cerebras adds multiple API modes)\n}\n\n/**\n * The Cerebras provider instance.\n *\n * Use this provider to create model references for Cerebras models like\n * Llama 3.3, Qwen 3, GPT-OSS (reasoning), and other models available on Cerebras.\n *\n * @example Basic usage\n * ```typescript\n * import { cerebras } from './providers/cerebras';\n * import { llm } from './core/llm';\n *\n * const model = llm({\n * model: cerebras('llama-3.3-70b'),\n * params: { max_completion_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 tools\n * ```typescript\n * const calculator = {\n * name: 'calculate',\n * description: 'Calculate a math expression',\n * parameters: {\n * type: 'object',\n * properties: {\n * expression: { type: 'string' }\n * },\n * required: ['expression']\n * },\n * run: async (params: { expression: string }) => {\n * return eval(params.expression);\n * }\n * };\n *\n * const model = llm({\n * model: cerebras('llama-3.3-70b'),\n * tools: [calculator]\n * });\n *\n * const turn = await model.generate('What is 15 + 27?');\n * ```\n *\n * @example With reasoning\n * ```typescript\n * const model = llm({\n * model: cerebras('gpt-oss-120b'),\n * params: {\n * reasoning_effort: 'high',\n * reasoning_format: 'parsed'\n * }\n * });\n *\n * const turn = await model.generate('Solve this complex math problem...');\n * // Reasoning is available in turn.response.metadata.cerebras.reasoning\n * ```\n *\n * @example Available models\n * Production models:\n * - `llama3.1-8b` - Fast Llama 3.1 8B model (~2200 tok/s)\n * - `llama-3.3-70b` - Llama 3.3 70B with tool use (~2100 tok/s)\n * - `qwen-3-32b` - Qwen 3 32B with reasoning support (~2600 tok/s)\n * - `qwen-3-235b-a22b-instruct-2507` - Large Qwen model (~1400 tok/s)\n * - `gpt-oss-120b` - Reasoning model with high performance (~3000 tok/s)\n * - `zai-glm-4.6` - Z.ai GLM model with reasoning (~1000 tok/s)\n * - `zai-glm-4.7` - Z.ai GLM model with reasoning (~1000 tok/s)\n */\nexport const cerebras = createProvider<CerebrasProviderOptions>({\n name: 'cerebras',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n },\n});\n\nexport type {\n CerebrasLLMParams,\n CerebrasHeaders,\n CerebrasResponseFormat,\n CerebrasMessage,\n CerebrasRequest,\n CerebrasResponse,\n CerebrasStreamChunk,\n CerebrasTool,\n CerebrasToolCall,\n CerebrasToolChoice,\n CerebrasUsage,\n CerebrasTimeInfo,\n} from './types.ts';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/providers/cerebras/transform.ts","../../src/providers/cerebras/llm.ts","../../src/providers/cerebras/index.ts"],"sourcesContent":["/**\n * @fileoverview Cerebras API Message Transformers\n *\n * This module provides transformation functions for converting between the\n * Universal Provider Protocol (UPP) message format and Cerebras's Chat Completions\n * API format (OpenAI-compatible). It handles both request transformation (UPP -> Cerebras)\n * and response transformation (Cerebras -> UPP), including streaming event transformation.\n *\n * @module providers/cerebras/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 } 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 CerebrasLLMParams,\n CerebrasRequest,\n CerebrasMessage,\n CerebrasUserContent,\n CerebrasTool,\n CerebrasResponse,\n CerebrasStreamChunk,\n CerebrasToolCall,\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 'cerebras',\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 'cerebras',\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 'cerebras',\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 Cerebras user content format.\n */\nfunction transformContentBlock(block: ContentBlock): CerebrasUserContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image':\n throw new UPPError(\n 'Cerebras does not support image input',\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n\n case 'document':\n throw new UPPError(\n 'Cerebras does not support document input',\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n\n default:\n throw new UPPError(\n `Unsupported content type: ${block.type}`,\n ErrorCode.InvalidRequest,\n 'cerebras',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Transforms a single UPP message to Cerebras format.\n */\nfunction transformMessage(message: Message): CerebrasMessage | 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 const assistantMessage: CerebrasMessage = {\n role: 'assistant',\n content: textContent || null,\n };\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n (assistantMessage as { tool_calls?: CerebrasToolCall[] }).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 Cerebras tool messages.\n */\nexport function transformToolResults(message: Message): CerebrasMessage[] {\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 Cerebras message format.\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt\n * @returns Array of Cerebras-formatted messages\n */\nfunction transformMessages(\n messages: Message[],\n system?: string | unknown[]\n): CerebrasMessage[] {\n const result: CerebrasMessage[] = [];\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 Cerebras-specific options from tool metadata.\n */\nfunction extractToolOptions(tool: Tool): { strict?: boolean } {\n const cerebrasMeta = tool.metadata?.cerebras as { strict?: boolean } | undefined;\n return { strict: cerebrasMeta?.strict };\n}\n\n/**\n * Transforms a UPP tool definition to Cerebras function tool format.\n */\nfunction transformTool(tool: Tool): CerebrasTool {\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 Cerebras Chat Completions API format.\n *\n * @param request - The UPP LLM request containing messages, tools, and configuration\n * @param modelId - The Cerebras model identifier (e.g., 'llama-3.3-70b')\n * @returns A Cerebras Chat Completions API request body\n */\nexport function transformRequest(\n request: LLMRequest<CerebrasLLMParams>,\n modelId: string\n): CerebrasRequest {\n const params = request.params ?? ({} as CerebrasLLMParams);\n\n const cerebrasRequest: CerebrasRequest = {\n ...params,\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n cerebrasRequest.tools = request.tools.map(transformTool);\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 cerebrasRequest.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 cerebrasRequest;\n}\n\n/**\n * Transforms a Cerebras response to UPP LLMResponse format.\n */\nexport function transformResponse(data: CerebrasResponse): LLMResponse {\n const choice = data.choices[0];\n if (!choice) {\n throw new UPPError(\n 'No choices in Cerebras response',\n ErrorCode.InvalidResponse,\n 'cerebras',\n ModalityType.LLM\n );\n }\n\n const textContent: TextBlock[] = [];\n let structuredData: unknown;\n if (choice.message.content) {\n textContent.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 textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id || generateId(),\n metadata: {\n cerebras: {\n model: data.model,\n finish_reason: choice.finish_reason,\n system_fingerprint: data.system_fingerprint,\n reasoning: choice.message.reasoning,\n time_info: data.time_info,\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 CerebrasStreamState {\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 */\n reasoning: 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 /** Time info from the response */\n timeInfo?: {\n queue_time?: number;\n prompt_time?: number;\n completion_time?: number;\n total_time?: number;\n };\n}\n\n/**\n * Creates a fresh stream state object for a new streaming session.\n */\nexport function createStreamState(): CerebrasStreamState {\n return {\n id: '',\n model: '',\n text: '',\n reasoning: '',\n toolCalls: new Map(),\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n };\n}\n\n/**\n * Transforms a Cerebras streaming chunk into UPP stream events.\n */\nexport function transformStreamEvent(\n chunk: CerebrasStreamChunk,\n state: CerebrasStreamState\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.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.reasoning) {\n state.reasoning += choice.delta.reasoning;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: choice.delta.reasoning },\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 if (chunk.time_info) {\n state.timeInfo = chunk.time_info;\n }\n\n return events;\n}\n\n/**\n * Builds a complete LLMResponse from accumulated streaming state.\n */\nexport function buildResponseFromState(state: CerebrasStreamState): LLMResponse {\n const textContent: TextBlock[] = [];\n let structuredData: unknown;\n if (state.text) {\n textContent.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 textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: messageId,\n metadata: {\n cerebras: {\n model: state.model,\n finish_reason: state.finishReason,\n reasoning: state.reasoning || undefined,\n time_info: state.timeInfo,\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 Cerebras Chat Completions API Handler\n *\n * This module implements the LLM handler for Cerebras's Chat Completions API\n * (OpenAI-compatible at `/v1/chat/completions`).\n *\n * @see {@link https://inference-docs.cerebras.ai/introduction Cerebras API Reference}\n * @module providers/cerebras/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 } 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 { CerebrasLLMParams, CerebrasResponse, CerebrasStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Base URL for Cerebras's Chat Completions API endpoint */\nconst CEREBRAS_API_URL = 'https://api.cerebras.ai/v1/chat/completions';\n\n/**\n * Capability declaration for the Cerebras 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: Not supported\n */\nconst CEREBRAS_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: false,\n documentInput: false,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for Cerebras'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 Cerebras API\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const model = handler.bind('llama-3.3-70b');\n *\n * // Synchronous completion\n * const response = await model.complete({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * config: { apiKey: 'csk-...' }\n * });\n *\n * // Streaming completion\n * const stream = model.stream({\n * messages: [{ role: 'user', content: 'Tell me a story' }],\n * config: { apiKey: 'csk-...' }\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<CerebrasLLMParams> {\n let providerRef: LLMProvider<CerebrasLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<CerebrasLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<CerebrasLLMParams> {\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 'cerebras',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<CerebrasLLMParams> = {\n modelId,\n capabilities: CEREBRAS_CAPABILITIES,\n\n get provider(): LLMProvider<CerebrasLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<CerebrasLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'CEREBRAS_API_KEY',\n 'cerebras',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? CEREBRAS_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 'cerebras',\n 'llm'\n );\n\n const data = await parseJsonResponse<CerebrasResponse>(response, 'cerebras', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<CerebrasLLMParams>): 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 resolveApiKey(\n request.config,\n 'CEREBRAS_API_KEY',\n 'cerebras',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? CEREBRAS_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 'cerebras',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'cerebras', '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 'cerebras',\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 Cerebras error event\n if (typeof data === 'object' && data !== null) {\n const chunk = data as CerebrasStreamChunk;\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 'cerebras',\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 Cerebras Provider Factory\n *\n * This module provides the main Cerebras provider implementation for the\n * OpenAI-compatible Chat Completions API. Cerebras offers extremely fast\n * inference with models like Llama, Qwen, and their reasoning models.\n *\n * @module providers/cerebras\n */\n\nimport { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\n\n/**\n * Configuration options for the Cerebras provider.\n *\n * Currently Cerebras only supports one API endpoint (Chat Completions),\n * so no additional options are needed.\n */\nexport interface CerebrasProviderOptions {\n // Reserved for future use (e.g., if Cerebras adds multiple API modes)\n}\n\n/**\n * The Cerebras provider instance.\n *\n * Use this provider to create model references for Cerebras models like\n * Llama 3.3, Qwen 3, GPT-OSS (reasoning), and other models available on Cerebras.\n *\n * @example Basic usage\n * ```typescript\n * import { cerebras } from './providers/cerebras';\n * import { llm } from './core/llm';\n *\n * const model = llm({\n * model: cerebras('llama-3.3-70b'),\n * params: { max_completion_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 tools\n * ```typescript\n * const calculator = {\n * name: 'calculate',\n * description: 'Calculate a math expression',\n * parameters: {\n * type: 'object',\n * properties: {\n * expression: { type: 'string' }\n * },\n * required: ['expression']\n * },\n * run: async (params: { expression: string }) => {\n * return eval(params.expression);\n * }\n * };\n *\n * const model = llm({\n * model: cerebras('llama-3.3-70b'),\n * tools: [calculator]\n * });\n *\n * const turn = await model.generate('What is 15 + 27?');\n * ```\n *\n * @example With reasoning\n * ```typescript\n * const model = llm({\n * model: cerebras('gpt-oss-120b'),\n * params: {\n * reasoning_effort: 'high',\n * reasoning_format: 'parsed'\n * }\n * });\n *\n * const turn = await model.generate('Solve this complex math problem...');\n * // Reasoning is available in turn.response.metadata.cerebras.reasoning\n * ```\n *\n * @example Available models\n * Production models:\n * - `llama3.1-8b` - Fast Llama 3.1 8B model (~2200 tok/s)\n * - `llama-3.3-70b` - Llama 3.3 70B with tool use (~2100 tok/s)\n * - `qwen-3-32b` - Qwen 3 32B with reasoning support (~2600 tok/s)\n * - `qwen-3-235b-a22b-instruct-2507` - Large Qwen model (~1400 tok/s)\n * - `gpt-oss-120b` - Reasoning model with high performance (~3000 tok/s)\n * - `zai-glm-4.6` - Z.ai GLM model with reasoning (~1000 tok/s)\n * - `zai-glm-4.7` - Z.ai GLM model with reasoning (~1000 tok/s)\n */\nexport const cerebras = createProvider<CerebrasProviderOptions>({\n name: 'cerebras',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n },\n});\n\nexport type {\n CerebrasLLMParams,\n CerebrasHeaders,\n CerebrasResponseFormat,\n CerebrasMessage,\n CerebrasRequest,\n CerebrasResponse,\n CerebrasStreamChunk,\n CerebrasTool,\n CerebrasToolCall,\n CerebrasToolChoice,\n CerebrasUsage,\n CerebrasTimeInfo,\n} from './types.ts';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,124 @@
1
+ // src/utils/zod.ts
2
+ var cachedZod;
3
+ var cachedZodToJsonSchema;
4
+ try {
5
+ cachedZod = await import("zod");
6
+ } catch {
7
+ }
8
+ try {
9
+ const mod = await import("zod-to-json-schema");
10
+ cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema };
11
+ } catch {
12
+ }
13
+ function isZodSchema(value) {
14
+ return value !== null && typeof value === "object" && "_def" in value && "parse" in value && typeof value.parse === "function";
15
+ }
16
+ function isZodV4(schema) {
17
+ return "_zod" in schema;
18
+ }
19
+ async function loadZod() {
20
+ if (!cachedZod) {
21
+ cachedZod = await import("zod");
22
+ }
23
+ return cachedZod;
24
+ }
25
+ async function loadZodToJsonSchema() {
26
+ if (!cachedZodToJsonSchema) {
27
+ const mod = await import("zod-to-json-schema");
28
+ cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema };
29
+ }
30
+ return cachedZodToJsonSchema;
31
+ }
32
+ async function zodV4ToJSONSchema(schema) {
33
+ const z = await loadZod();
34
+ if (!("toJSONSchema" in z)) {
35
+ throw new Error(
36
+ "Zod v4+ required for native JSON Schema conversion. Install with: bun add zod@latest"
37
+ );
38
+ }
39
+ const jsonSchema = z.toJSONSchema(schema, { target: "draft-07" });
40
+ return jsonSchema;
41
+ }
42
+ function zodV4ToJSONSchemaSync(schema) {
43
+ if (!cachedZod) {
44
+ throw new Error(
45
+ "Zod module not loaded. Call zodToJSONSchema() first or ensure Zod is imported."
46
+ );
47
+ }
48
+ if (!("toJSONSchema" in cachedZod)) {
49
+ throw new Error(
50
+ "Zod v4+ required for native JSON Schema conversion. Install with: bun add zod@latest"
51
+ );
52
+ }
53
+ const jsonSchema = cachedZod.toJSONSchema(schema, { target: "draft-07" });
54
+ return jsonSchema;
55
+ }
56
+ async function zodV3ToJSONSchema(schema) {
57
+ const { zodToJsonSchema } = await loadZodToJsonSchema();
58
+ const jsonSchema = zodToJsonSchema(schema, {
59
+ $refStrategy: "none"
60
+ });
61
+ return jsonSchema;
62
+ }
63
+ function zodV3ToJSONSchemaSync(schema) {
64
+ if (!cachedZodToJsonSchema) {
65
+ throw new Error(
66
+ "zod-to-json-schema module not loaded. Call zodToJSONSchema() first."
67
+ );
68
+ }
69
+ const jsonSchema = cachedZodToJsonSchema.zodToJsonSchema(
70
+ schema,
71
+ {
72
+ $refStrategy: "none"
73
+ }
74
+ );
75
+ return jsonSchema;
76
+ }
77
+ async function zodToJSONSchema(schema) {
78
+ if (isZodV4(schema)) {
79
+ return zodV4ToJSONSchema(schema);
80
+ }
81
+ return zodV3ToJSONSchema(schema);
82
+ }
83
+ function zodToJSONSchemaSync(schema) {
84
+ if (isZodV4(schema)) {
85
+ return zodV4ToJSONSchemaSync(schema);
86
+ }
87
+ return zodV3ToJSONSchemaSync(schema);
88
+ }
89
+ function validateObjectSchema(schema, context) {
90
+ const s = schema;
91
+ if (s.type !== "object" || typeof s.properties !== "object" || s.properties === null) {
92
+ throw new Error(
93
+ `${context} must be an object schema with properties. Received schema with type: '${s.type ?? "undefined"}'. Use z.object({...}) for Zod schemas.`
94
+ );
95
+ }
96
+ }
97
+ function resolveStructure(structure) {
98
+ if (isZodSchema(structure)) {
99
+ const schema = zodToJSONSchemaSync(structure);
100
+ validateObjectSchema(schema, "Structure schema");
101
+ return schema;
102
+ }
103
+ return structure;
104
+ }
105
+ function resolveTools(tools) {
106
+ return tools.map((tool) => {
107
+ if (isZodSchema(tool.parameters)) {
108
+ const schema = zodToJSONSchemaSync(tool.parameters);
109
+ validateObjectSchema(schema, `Tool '${tool.name}' parameters`);
110
+ return { ...tool, parameters: schema };
111
+ }
112
+ return tool;
113
+ });
114
+ }
115
+
116
+ export {
117
+ isZodSchema,
118
+ isZodV4,
119
+ zodToJSONSchema,
120
+ zodToJSONSchemaSync,
121
+ resolveStructure,
122
+ resolveTools
123
+ };
124
+ //# sourceMappingURL=chunk-3Q5VELKG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/zod.ts"],"sourcesContent":["/**\n * @fileoverview Zod schema utilities for structured output.\n *\n * Provides detection and conversion utilities for Zod schemas,\n * supporting both Zod v3 and v4 schemas.\n *\n * @module utils/zod\n */\n\nimport type { JSONSchema, ZodLike, ZodV3Like, ZodV4Like } from '../types/schema.ts';\nimport type { Tool, ToolInput } from '../types/tool.ts';\nimport type * as Zod from 'zod';\nimport type { zodToJsonSchema as ZodToJsonSchemaFn } from 'zod-to-json-schema';\n\n/** Cached Zod module for sync access */\nlet cachedZod: typeof Zod | undefined;\n\n/** Cached zod-to-json-schema module for sync access */\nlet cachedZodToJsonSchema: { zodToJsonSchema: typeof ZodToJsonSchemaFn } | undefined;\n\n// Pre-load modules at import time for sync access\n// Uses dynamic import which is ESM-compatible\ntry {\n cachedZod = await import('zod') as typeof Zod;\n} catch {\n // Zod not installed - will throw on use\n}\n\ntry {\n const mod = await import('zod-to-json-schema');\n cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema as typeof ZodToJsonSchemaFn };\n} catch {\n // zod-to-json-schema not installed - will throw on use for v3\n}\n\n/**\n * Checks if a value is a Zod schema (v3 or v4).\n *\n * @param value - Value to check\n * @returns True if the value appears to be a Zod schema\n */\nexport function isZodSchema(value: unknown): value is ZodLike {\n return (\n value !== null &&\n typeof value === 'object' &&\n '_def' in value &&\n 'parse' in value &&\n typeof (value as ZodV3Like).parse === 'function'\n );\n}\n\n/**\n * Checks if a Zod schema is v4 or later.\n *\n * @param schema - Zod schema to check\n * @returns True if the schema is Zod v4+\n */\nexport function isZodV4(schema: ZodLike): schema is ZodV4Like {\n return '_zod' in schema;\n}\n\n/**\n * Loads and caches the Zod module.\n */\nasync function loadZod(): Promise<typeof Zod> {\n if (!cachedZod) {\n cachedZod = await import('zod') as typeof Zod;\n }\n return cachedZod;\n}\n\n/**\n * Loads and caches the zod-to-json-schema module.\n */\nasync function loadZodToJsonSchema(): Promise<{ zodToJsonSchema: typeof ZodToJsonSchemaFn }> {\n if (!cachedZodToJsonSchema) {\n const mod = await import('zod-to-json-schema');\n cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema as typeof ZodToJsonSchemaFn };\n }\n return cachedZodToJsonSchema;\n}\n\n/**\n * Converts a Zod v4 schema to JSON Schema using native conversion.\n */\nasync function zodV4ToJSONSchema(schema: ZodV4Like): Promise<JSONSchema> {\n const z = await loadZod();\n if (!('toJSONSchema' in z)) {\n throw new Error(\n 'Zod v4+ required for native JSON Schema conversion. ' +\n 'Install with: bun add zod@latest',\n );\n }\n const jsonSchema = z.toJSONSchema(schema as Zod.ZodType, { target: 'draft-07' });\n return jsonSchema as JSONSchema;\n}\n\n/**\n * Synchronous version for v4 schemas.\n * Requires Zod to be cached via prior async load.\n */\nfunction zodV4ToJSONSchemaSync(schema: ZodV4Like): JSONSchema {\n if (!cachedZod) {\n throw new Error(\n 'Zod module not loaded. Call zodToJSONSchema() first or ensure Zod is imported.',\n );\n }\n if (!('toJSONSchema' in cachedZod)) {\n throw new Error(\n 'Zod v4+ required for native JSON Schema conversion. ' +\n 'Install with: bun add zod@latest',\n );\n }\n const jsonSchema = cachedZod.toJSONSchema(schema as Zod.ZodType, { target: 'draft-07' });\n return jsonSchema as JSONSchema;\n}\n\n/**\n * Converts a Zod v3 schema to JSON Schema using zod-to-json-schema.\n * Uses inline strategy to keep properties at root level for provider compatibility.\n */\nasync function zodV3ToJSONSchema(\n schema: ZodV3Like,\n): Promise<JSONSchema> {\n const { zodToJsonSchema } = await loadZodToJsonSchema();\n const jsonSchema = zodToJsonSchema(schema as Parameters<typeof zodToJsonSchema>[0], {\n $refStrategy: 'none',\n });\n return jsonSchema as unknown as JSONSchema;\n}\n\n/**\n * Synchronous version for v3 schemas.\n * Requires zod-to-json-schema to be cached via prior async load.\n */\nfunction zodV3ToJSONSchemaSync(schema: ZodV3Like): JSONSchema {\n if (!cachedZodToJsonSchema) {\n throw new Error(\n 'zod-to-json-schema module not loaded. Call zodToJSONSchema() first.',\n );\n }\n const jsonSchema = cachedZodToJsonSchema.zodToJsonSchema(\n schema as Parameters<typeof ZodToJsonSchemaFn>[0],\n {\n $refStrategy: 'none',\n },\n );\n return jsonSchema as unknown as JSONSchema;\n}\n\n/**\n * Converts a Zod schema to JSON Schema.\n *\n * For Zod v4+, uses native `z.toJSONSchema()`.\n * For Zod v3, uses `zod-to-json-schema` package.\n *\n * @param schema - Zod schema to convert\n * @returns JSON Schema representation\n * @throws Error if required dependencies are not installed\n */\nexport async function zodToJSONSchema(\n schema: ZodLike,\n): Promise<JSONSchema> {\n if (isZodV4(schema)) {\n return zodV4ToJSONSchema(schema);\n }\n return zodV3ToJSONSchema(schema);\n}\n\n/**\n * Synchronous version of zodToJSONSchema.\n * Requires modules to be cached via prior async load.\n *\n * @param schema - Zod schema to convert\n * @returns JSON Schema representation\n * @throws Error if modules not loaded or dependencies missing\n */\nexport function zodToJSONSchemaSync(\n schema: ZodLike,\n): JSONSchema {\n if (isZodV4(schema)) {\n return zodV4ToJSONSchemaSync(schema);\n }\n return zodV3ToJSONSchemaSync(schema);\n}\n\n/**\n * Validates that a schema is an object schema with properties.\n * Throws if the schema is not a valid object schema.\n */\nfunction validateObjectSchema(schema: unknown, context: string): asserts schema is JSONSchema {\n const s = schema as Record<string, unknown>;\n if (s.type !== 'object' || typeof s.properties !== 'object' || s.properties === null) {\n throw new Error(\n `${context} must be an object schema with properties. ` +\n `Received schema with type: '${s.type ?? 'undefined'}'. ` +\n 'Use z.object({...}) for Zod schemas.',\n );\n }\n}\n\n/**\n * Resolves a structure parameter that may be JSONSchema or Zod schema.\n * Validates that the result is an object schema.\n *\n * @param structure - JSONSchema or Zod schema (must be object type)\n * @returns Resolved JSONSchema\n * @throws Error if schema is not an object type\n */\nexport function resolveStructure(\n structure: JSONSchema | ZodLike,\n): JSONSchema {\n if (isZodSchema(structure)) {\n const schema = zodToJSONSchemaSync(structure);\n validateObjectSchema(schema, 'Structure schema');\n return schema;\n }\n return structure;\n}\n\n/**\n * Resolves an array of tools, converting any Zod parameters to JSONSchema.\n * Validates that each tool's parameters is an object schema.\n *\n * @param tools - Array of tools with Structure parameters\n * @returns Array of tools with resolved JSONSchema parameters\n * @throws Error if any tool parameters is not an object schema\n */\nexport function resolveTools(tools: ToolInput[]): Tool[] {\n return tools.map((tool) => {\n if (isZodSchema(tool.parameters)) {\n const schema = zodToJSONSchemaSync(tool.parameters);\n validateObjectSchema(schema, `Tool '${tool.name}' parameters`);\n return { ...tool, parameters: schema };\n }\n return tool as Tool;\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,6 @@
1
- // src/utils/id.ts
2
- function generateId() {
3
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
4
- return crypto.randomUUID();
5
- }
6
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
7
- const r = Math.random() * 16 | 0;
8
- const v = c === "x" ? r : r & 3 | 8;
9
- return v.toString(16);
10
- });
11
- }
1
+ import {
2
+ generateId
3
+ } from "./chunk-U2G5PHHL.js";
12
4
 
13
5
  // src/types/messages.ts
14
6
  var MessageRole = {
@@ -164,7 +156,6 @@ function isToolResultMessage(msg) {
164
156
  }
165
157
 
166
158
  export {
167
- generateId,
168
159
  MessageRole,
169
160
  Message,
170
161
  UserMessage,
@@ -174,4 +165,4 @@ export {
174
165
  isAssistantMessage,
175
166
  isToolResultMessage
176
167
  };
177
- //# sourceMappingURL=chunk-WU4U6IHF.js.map
168
+ //# sourceMappingURL=chunk-6QCV4WXF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/messages.ts"],"sourcesContent":["/**\n * @fileoverview Message types for conversation history.\n *\n * Defines the message classes used to represent conversation turns\n * between users and assistants, including support for multimodal\n * content and tool calls.\n *\n * @module types/messages\n */\n\nimport { generateId } from '../utils/id.ts';\nimport type {\n ContentBlock,\n TextBlock,\n ReasoningBlock,\n ImageBlock,\n DocumentBlock,\n AudioBlock,\n VideoBlock,\n UserContent,\n AssistantContent,\n} from './content.ts';\nimport type { ToolCall, ToolResult } from './tool.ts';\n\n/**\n * Message serialized to JSON format.\n * Picks common fields from Message, converts timestamp to string.\n */\nexport type MessageJSON = Pick<Message, 'id' | 'type' | 'metadata'> & {\n timestamp: string;\n content: ContentBlock[];\n toolCalls?: ToolCall[];\n results?: ToolResult[];\n};\n\n/**\n * Message role/type constants.\n *\n * Use these constants instead of raw strings for type-safe message handling:\n *\n * @example\n * ```typescript\n * import { MessageRole, isUserMessage } from 'upp';\n *\n * if (message.type === MessageRole.User) {\n * console.log('User said:', message.text);\n * } else if (message.type === MessageRole.Assistant) {\n * console.log('Assistant replied:', message.text);\n * }\n * ```\n */\nexport const MessageRole = {\n /** User message */\n User: 'user',\n /** Assistant/model response */\n Assistant: 'assistant',\n /** Tool execution result */\n ToolResult: 'tool_result',\n} as const;\n\n/**\n * Message type discriminator union.\n *\n * This type is derived from {@link MessageRole} constants. The name `MessageType`\n * is kept for backward compatibility; `MessageRole` works as both the const\n * object and this type.\n */\nexport type MessageType = (typeof MessageRole)[keyof typeof MessageRole];\n\n/**\n * Type alias for MessageType, allowing `MessageRole` to work as both const and type.\n */\nexport type MessageRole = MessageType;\n\n/**\n * Provider-namespaced metadata for messages.\n *\n * Each provider can attach its own metadata under its namespace,\n * preventing conflicts between different providers.\n *\n * @example\n * ```typescript\n * const metadata: MessageMetadata = {\n * openai: { model: 'gpt-4', finishReason: 'stop' },\n * anthropic: { model: 'claude-3', stopReason: 'end_turn' }\n * };\n * ```\n */\nexport interface MessageMetadata {\n [provider: string]: Record<string, unknown> | undefined;\n}\n\n/**\n * Options for constructing messages.\n */\nexport interface MessageOptions {\n /** Custom message ID (auto-generated if not provided) */\n id?: string;\n\n /** Message timestamp override (defaults to now) */\n timestamp?: Date;\n\n /** Provider-specific metadata */\n metadata?: MessageMetadata;\n}\n\n/**\n * Abstract base class for all message types.\n *\n * Provides common functionality for user, assistant, and tool result\n * messages, including content accessors and metadata handling.\n *\n * @example\n * ```typescript\n * // Access text content from any message\n * const text = message.text;\n *\n * // Access images\n * const images = message.images;\n * ```\n */\nexport abstract class Message {\n /** Unique message identifier */\n readonly id: string;\n\n /** Timestamp when the message was created */\n readonly timestamp: Date;\n\n /** Provider-specific metadata, namespaced by provider name */\n readonly metadata?: MessageMetadata;\n\n /** Message type discriminator (implemented by subclasses) */\n abstract readonly type: MessageType;\n\n /**\n * Returns the content blocks for this message.\n * Implemented by subclasses to provide type-specific content.\n */\n protected abstract getContent(): ContentBlock[];\n\n /**\n * Creates a new message instance.\n *\n * @param options - Optional message ID and metadata\n */\n constructor(options?: MessageOptions) {\n this.id = options?.id ?? generateId();\n this.timestamp = options?.timestamp ?? new Date();\n this.metadata = options?.metadata;\n }\n\n /**\n * Concatenated text content from all text blocks.\n * Blocks are joined with double newlines.\n */\n get text(): string {\n return this.getContent()\n .filter((block): block is TextBlock => block.type === 'text')\n .map((block) => block.text)\n .join('\\n\\n');\n }\n\n /**\n * All image content blocks in this message.\n */\n get images(): ImageBlock[] {\n return this.getContent().filter((block): block is ImageBlock => block.type === 'image');\n }\n\n /**\n * All document content blocks in this message.\n */\n get documents(): DocumentBlock[] {\n return this.getContent().filter((block): block is DocumentBlock => block.type === 'document');\n }\n\n /**\n * All audio content blocks in this message.\n */\n get audio(): AudioBlock[] {\n return this.getContent().filter((block): block is AudioBlock => block.type === 'audio');\n }\n\n /**\n * All video content blocks in this message.\n */\n get video(): VideoBlock[] {\n return this.getContent().filter((block): block is VideoBlock => block.type === 'video');\n }\n\n /**\n * All reasoning/thinking content blocks in this message.\n * Available when using extended thinking models.\n */\n get reasoning(): ReasoningBlock[] {\n return this.getContent().filter((block): block is ReasoningBlock => block.type === 'reasoning');\n }\n}\n\n/**\n * User input message.\n *\n * Represents a message from the user, which can contain text and/or\n * multimodal content like images, audio, or video.\n *\n * @example\n * ```typescript\n * // Simple text message\n * const msg = new UserMessage('Hello, world!');\n *\n * // Multimodal message\n * const msg = new UserMessage([\n * { type: 'text', text: 'What is in this image?' },\n * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }\n * ]);\n * ```\n */\nexport class UserMessage extends Message {\n /** Message type discriminator */\n readonly type = 'user' as const;\n\n /** Content blocks in this message */\n readonly content: UserContent[];\n\n /**\n * Creates a new user message.\n *\n * @param content - String (converted to TextBlock) or array of content blocks\n * @param options - Optional message ID and metadata\n */\n constructor(content: string | UserContent[], options?: MessageOptions) {\n super(options);\n if (typeof content === 'string') {\n this.content = [{ type: 'text', text: content }];\n } else {\n this.content = content;\n }\n }\n\n protected getContent(): ContentBlock[] {\n return this.content;\n }\n}\n\n/**\n * Assistant response message.\n *\n * Represents a response from the AI assistant, which may contain\n * text, media content, and/or tool call requests.\n *\n * @example\n * ```typescript\n * // Simple text response\n * const msg = new AssistantMessage('Hello! How can I help?');\n *\n * // Response with tool calls\n * const msg = new AssistantMessage(\n * 'Let me check the weather...',\n * [{ toolCallId: 'call_1', toolName: 'get_weather', arguments: { location: 'NYC' } }]\n * );\n * ```\n */\nexport class AssistantMessage extends Message {\n /** Message type discriminator */\n readonly type = 'assistant' as const;\n\n /** Content blocks in this message */\n readonly content: AssistantContent[];\n\n /** Tool calls requested by the model (if any) */\n readonly toolCalls?: ToolCall[];\n\n /**\n * Creates a new assistant message.\n *\n * @param content - String (converted to TextBlock) or array of content blocks\n * @param toolCalls - Tool calls requested by the model\n * @param options - Optional message ID and metadata\n */\n constructor(\n content: string | AssistantContent[],\n toolCalls?: ToolCall[],\n options?: MessageOptions\n ) {\n super(options);\n if (typeof content === 'string') {\n this.content = [{ type: 'text', text: content }];\n } else {\n this.content = content;\n }\n this.toolCalls = toolCalls;\n }\n\n protected getContent(): ContentBlock[] {\n return this.content;\n }\n\n /**\n * Whether this message contains tool call requests.\n */\n get hasToolCalls(): boolean {\n return this.toolCalls !== undefined && this.toolCalls.length > 0;\n }\n}\n\n/**\n * Tool execution result message.\n *\n * Contains the results of executing one or more tool calls,\n * sent back to the model for further processing.\n *\n * @example\n * ```typescript\n * const msg = new ToolResultMessage([\n * { toolCallId: 'call_1', result: { temperature: 72, conditions: 'sunny' } },\n * { toolCallId: 'call_2', result: 'File not found', isError: true }\n * ]);\n * ```\n */\nexport class ToolResultMessage extends Message {\n /** Message type discriminator */\n readonly type = 'tool_result' as const;\n\n /** Results from tool executions */\n readonly results: ToolResult[];\n\n /**\n * Creates a new tool result message.\n *\n * @param results - Array of tool execution results\n * @param options - Optional message ID and metadata\n */\n constructor(results: ToolResult[], options?: MessageOptions) {\n super(options);\n this.results = results;\n }\n\n protected getContent(): ContentBlock[] {\n return this.results.map((result) => ({\n type: 'text' as const,\n text:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n }\n}\n\n/**\n * Type guard for UserMessage.\n *\n * @param msg - The message to check\n * @returns True if the message is a UserMessage\n *\n * @example\n * ```typescript\n * if (isUserMessage(msg)) {\n * console.log('User said:', msg.text);\n * }\n * ```\n */\nexport function isUserMessage(msg: Message): msg is UserMessage {\n return msg.type === MessageRole.User;\n}\n\n/**\n * Type guard for AssistantMessage.\n *\n * @param msg - The message to check\n * @returns True if the message is an AssistantMessage\n *\n * @example\n * ```typescript\n * if (isAssistantMessage(msg)) {\n * console.log('Assistant said:', msg.text);\n * if (msg.hasToolCalls) {\n * console.log('Tool calls:', msg.toolCalls);\n * }\n * }\n * ```\n */\nexport function isAssistantMessage(msg: Message): msg is AssistantMessage {\n return msg.type === MessageRole.Assistant;\n}\n\n/**\n * Type guard for ToolResultMessage.\n *\n * @param msg - The message to check\n * @returns True if the message is a ToolResultMessage\n *\n * @example\n * ```typescript\n * if (isToolResultMessage(msg)) {\n * for (const result of msg.results) {\n * console.log(`Tool ${result.toolCallId}:`, result.result);\n * }\n * }\n * ```\n */\nexport function isToolResultMessage(msg: Message): msg is ToolResultMessage {\n return msg.type === MessageRole.ToolResult;\n}\n"],"mappings":";;;;;AAmDO,IAAM,cAAc;AAAA;AAAA,EAEzB,MAAM;AAAA;AAAA,EAEN,WAAW;AAAA;AAAA,EAEX,YAAY;AACd;AA+DO,IAAe,UAAf,MAAuB;AAAA;AAAA,EAEnB;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBT,YAAY,SAA0B;AACpC,SAAK,KAAK,SAAS,MAAM,WAAW;AACpC,SAAK,YAAY,SAAS,aAAa,oBAAI,KAAK;AAChD,SAAK,WAAW,SAAS;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAe;AACjB,WAAO,KAAK,WAAW,EACpB,OAAO,CAAC,UAA8B,MAAM,SAAS,MAAM,EAC3D,IAAI,CAAC,UAAU,MAAM,IAAI,EACzB,KAAK,MAAM;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAuB;AACzB,WAAO,KAAK,WAAW,EAAE,OAAO,CAAC,UAA+B,MAAM,SAAS,OAAO;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAA6B;AAC/B,WAAO,KAAK,WAAW,EAAE,OAAO,CAAC,UAAkC,MAAM,SAAS,UAAU;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsB;AACxB,WAAO,KAAK,WAAW,EAAE,OAAO,CAAC,UAA+B,MAAM,SAAS,OAAO;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsB;AACxB,WAAO,KAAK,WAAW,EAAE,OAAO,CAAC,UAA+B,MAAM,SAAS,OAAO;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YAA8B;AAChC,WAAO,KAAK,WAAW,EAAE,OAAO,CAAC,UAAmC,MAAM,SAAS,WAAW;AAAA,EAChG;AACF;AAoBO,IAAM,cAAN,cAA0B,QAAQ;AAAA;AAAA,EAE9B,OAAO;AAAA;AAAA,EAGP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,YAAY,SAAiC,SAA0B;AACrE,UAAM,OAAO;AACb,QAAI,OAAO,YAAY,UAAU;AAC/B,WAAK,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,IACjD,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EAEU,aAA6B;AACrC,WAAO,KAAK;AAAA,EACd;AACF;AAoBO,IAAM,mBAAN,cAA+B,QAAQ;AAAA;AAAA,EAEnC,OAAO;AAAA;AAAA,EAGP;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAST,YACE,SACA,WACA,SACA;AACA,UAAM,OAAO;AACb,QAAI,OAAO,YAAY,UAAU;AAC/B,WAAK,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,IACjD,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AACA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEU,aAA6B;AACrC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,eAAwB;AAC1B,WAAO,KAAK,cAAc,UAAa,KAAK,UAAU,SAAS;AAAA,EACjE;AACF;AAgBO,IAAM,oBAAN,cAAgC,QAAQ;AAAA;AAAA,EAEpC,OAAO;AAAA;AAAA,EAGP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,YAAY,SAAuB,SAA0B;AAC3D,UAAM,OAAO;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEU,aAA6B;AACrC,WAAO,KAAK,QAAQ,IAAI,CAAC,YAAY;AAAA,MACnC,MAAM;AAAA,MACN,MACE,OAAO,OAAO,WAAW,WACrB,OAAO,SACP,KAAK,UAAU,OAAO,MAAM;AAAA,IACpC,EAAE;AAAA,EACJ;AACF;AAeO,SAAS,cAAc,KAAkC;AAC9D,SAAO,IAAI,SAAS,YAAY;AAClC;AAkBO,SAAS,mBAAmB,KAAuC;AACxE,SAAO,IAAI,SAAS,YAAY;AAClC;AAiBO,SAAS,oBAAoB,KAAwC;AAC1E,SAAO,IAAI,SAAS,YAAY;AAClC;","names":[]}
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  deserializeEmbeddingInput,
3
3
  deserializeImage,
4
- deserializeMessage,
5
4
  resolveImageResult,
6
5
  serializeImageResult,
7
- serializeImageStreamEvent,
6
+ serializeImageStreamEvent
7
+ } from "./chunk-BIBMNP7Y.js";
8
+ import {
9
+ deserializeMessage,
8
10
  serializeStreamEvent,
9
11
  serializeTurn
10
- } from "./chunk-YQLR3XOA.js";
12
+ } from "./chunk-ZSZVWLGE.js";
11
13
 
12
14
  // src/providers/proxy/server/webapi.ts
13
15
  function parseBody(body) {
@@ -219,4 +221,4 @@ export {
219
221
  bindTools,
220
222
  webapi
221
223
  };
222
- //# sourceMappingURL=chunk-LTEMH3CI.js.map
224
+ //# sourceMappingURL=chunk-AC3VHSZJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/proxy/server/webapi.ts"],"sourcesContent":["/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { EmbeddingInput } from '../../../types/provider.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/messages.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\nimport {\n deserializeEmbeddingInput,\n deserializeImage,\n serializeImageResult,\n serializeImageStreamEvent,\n type SerializedEmbeddingInput,\n type SerializedImage,\n} from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n model?: string;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parsed request body for embedding endpoints.\n */\nexport interface ParsedEmbeddingRequest {\n inputs: EmbeddingInput[];\n params?: Record<string, unknown>;\n model?: string;\n}\n\n/**\n * Parsed request body for image endpoints.\n */\nexport interface ParsedImageRequest {\n prompt: string;\n params?: Record<string, unknown>;\n model?: string;\n image?: ReturnType<typeof deserializeImage>;\n mask?: ReturnType<typeof deserializeImage>;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into embedding inputs.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed embedding request data\n */\nexport function parseEmbeddingBody(body: unknown): ParsedEmbeddingRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.inputs)) {\n throw new Error('Request body must have an inputs array');\n }\n\n const inputs = data.inputs.map((input) =>\n deserializeEmbeddingInput(input as SerializedEmbeddingInput)\n );\n\n return {\n inputs,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into image request data.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed image request data\n */\nexport function parseImageBody(body: unknown): ParsedImageRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n const promptValue = data.prompt;\n\n let prompt: string | undefined;\n if (typeof promptValue === 'string') {\n prompt = promptValue;\n } else if (promptValue && typeof promptValue === 'object') {\n const promptObj = promptValue as Record<string, unknown>;\n if (typeof promptObj.prompt === 'string') {\n prompt = promptObj.prompt;\n }\n }\n\n if (!prompt) {\n throw new Error('Request body must have a prompt string');\n }\n\n const image = data.image ? deserializeImage(data.image as SerializedImage) : undefined;\n const mask = data.mask ? deserializeImage(data.mask as SerializedImage) : undefined;\n\n return {\n prompt,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n image,\n mask,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an embedding result.\n *\n * @param result - The embedding result\n * @returns HTTP Response with JSON body\n */\nexport function toEmbeddingJSON(result: EmbeddingResult): Response {\n return new Response(JSON.stringify(result), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an image result.\n *\n * @param result - The image result\n * @returns HTTP Response with JSON body\n */\nexport function toImageJSON(result: ImageResult): Response {\n return new Response(JSON.stringify(serializeImageResult(result)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an SSE Response from an ImageStreamResult.\n *\n * Streams image events as SSE, then sends the final image result.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @returns HTTP Response with SSE body\n */\nexport function toImageSSE(stream: ImageStreamLike): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n const result = await resolveImageResult(stream);\n const resultData = serializeImageResult(result);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(resultData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n parseEmbeddingBody,\n parseImageBody,\n toJSON,\n toEmbeddingJSON,\n toImageJSON,\n toSSE,\n toImageSSE,\n toError,\n bindTools,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/providers/proxy/server/webapi.ts"],"sourcesContent":["/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { EmbeddingInput } from '../../../types/provider.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/messages.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\nimport {\n deserializeEmbeddingInput,\n deserializeImage,\n serializeImageResult,\n serializeImageStreamEvent,\n type SerializedEmbeddingInput,\n type SerializedImage,\n} from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n model?: string;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parsed request body for embedding endpoints.\n */\nexport interface ParsedEmbeddingRequest {\n inputs: EmbeddingInput[];\n params?: Record<string, unknown>;\n model?: string;\n}\n\n/**\n * Parsed request body for image endpoints.\n */\nexport interface ParsedImageRequest {\n prompt: string;\n params?: Record<string, unknown>;\n model?: string;\n image?: ReturnType<typeof deserializeImage>;\n mask?: ReturnType<typeof deserializeImage>;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into embedding inputs.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed embedding request data\n */\nexport function parseEmbeddingBody(body: unknown): ParsedEmbeddingRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.inputs)) {\n throw new Error('Request body must have an inputs array');\n }\n\n const inputs = data.inputs.map((input) =>\n deserializeEmbeddingInput(input as SerializedEmbeddingInput)\n );\n\n return {\n inputs,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into image request data.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed image request data\n */\nexport function parseImageBody(body: unknown): ParsedImageRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n const promptValue = data.prompt;\n\n let prompt: string | undefined;\n if (typeof promptValue === 'string') {\n prompt = promptValue;\n } else if (promptValue && typeof promptValue === 'object') {\n const promptObj = promptValue as Record<string, unknown>;\n if (typeof promptObj.prompt === 'string') {\n prompt = promptObj.prompt;\n }\n }\n\n if (!prompt) {\n throw new Error('Request body must have a prompt string');\n }\n\n const image = data.image ? deserializeImage(data.image as SerializedImage) : undefined;\n const mask = data.mask ? deserializeImage(data.mask as SerializedImage) : undefined;\n\n return {\n prompt,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n image,\n mask,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an embedding result.\n *\n * @param result - The embedding result\n * @returns HTTP Response with JSON body\n */\nexport function toEmbeddingJSON(result: EmbeddingResult): Response {\n return new Response(JSON.stringify(result), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an image result.\n *\n * @param result - The image result\n * @returns HTTP Response with JSON body\n */\nexport function toImageJSON(result: ImageResult): Response {\n return new Response(JSON.stringify(serializeImageResult(result)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an SSE Response from an ImageStreamResult.\n *\n * Streams image events as SSE, then sends the final image result.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @returns HTTP Response with SSE body\n */\nexport function toImageSSE(stream: ImageStreamLike): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n const result = await resolveImageResult(stream);\n const resultData = serializeImageResult(result);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(resultData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm, exponentialBackoff, roundRobinKeys } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: roundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: exponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n parseEmbeddingBody,\n parseImageBody,\n toJSON,\n toEmbeddingJSON,\n toImageJSON,\n toSSE,\n toImageSSE,\n toError,\n bindTools,\n};\n"],"mappings":"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","names":[]}