@robota-sdk/agent-provider 3.0.0-beta.64 → 3.0.0-beta.66

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 (124) hide show
  1. package/README.md +89 -0
  2. package/dist/browser/index.d.ts +5 -2
  3. package/dist/browser/index.d.ts.map +1 -1
  4. package/dist/browser/index.js +3 -3
  5. package/dist/browser/index.js.map +1 -1
  6. package/dist/loggers/index.d.ts.map +1 -1
  7. package/dist/loggers/index.js.map +1 -1
  8. package/dist/node/anthropic/index.d.ts.map +1 -1
  9. package/dist/node/anthropic--1vgLC-e.js.map +1 -1
  10. package/dist/node/bytedance/index.d.ts.map +1 -1
  11. package/dist/node/bytedance-C_0sF_pJ.js.map +1 -1
  12. package/dist/node/deepseek/index.d.ts +1 -1
  13. package/dist/node/deepseek-_8Ixx7rA.js.map +1 -1
  14. package/dist/node/gemini/index.d.ts.map +1 -1
  15. package/dist/node/gemini-Bh2U87MY.js.map +1 -1
  16. package/dist/node/gemma/index.cjs +1 -1
  17. package/dist/node/gemma/index.d.ts +1 -1
  18. package/dist/node/gemma/index.js +1 -1
  19. package/dist/node/{gemma-G-Pf_PnX.cjs → gemma-079LPvrN.cjs} +1 -1
  20. package/dist/node/gemma-BMFWnmXE.js +2 -0
  21. package/dist/node/gemma-BMFWnmXE.js.map +1 -0
  22. package/dist/node/google/index.d.ts.map +1 -1
  23. package/dist/node/google/index.js.map +1 -1
  24. package/dist/node/index-B6PnlDMd.d.ts.map +1 -1
  25. package/dist/node/index-B7UvPJcI.d.ts.map +1 -1
  26. package/dist/node/{index-C3beaqKO.d.ts → index-B9a2gTwI.d.ts} +3 -3
  27. package/dist/node/{index-BqixM_XD.d.ts.map → index-B9a2gTwI.d.ts.map} +1 -1
  28. package/dist/node/index-BLPOTNb5.d.ts.map +1 -1
  29. package/dist/node/{index-BqixM_XD.d.ts → index-CjPeNJ1G.d.ts} +3 -3
  30. package/dist/node/{index-C3beaqKO.d.ts.map → index-CjPeNJ1G.d.ts.map} +1 -1
  31. package/dist/node/index-Cp2XRh9G.d.ts.map +1 -1
  32. package/dist/node/index-DSv5xruI.d.ts.map +1 -1
  33. package/dist/node/index-w0bV1uaP.d.ts.map +1 -1
  34. package/dist/node/index.cjs +1 -1
  35. package/dist/node/index.d.ts +11 -5
  36. package/dist/node/index.d.ts.map +1 -0
  37. package/dist/node/index.js +2 -1
  38. package/dist/node/index.js.map +1 -0
  39. package/dist/node/openai/index.cjs +1 -1
  40. package/dist/node/openai/index.d.ts +1 -1
  41. package/dist/node/openai/index.js +1 -1
  42. package/dist/node/openai--CyyQ-E4.js +2 -0
  43. package/dist/node/openai--CyyQ-E4.js.map +1 -0
  44. package/dist/node/{openai-xWC6pY7r.cjs → openai-CmuDu5k-.cjs} +1 -1
  45. package/dist/node/openai-compatible-Dm4Sof9e.js.map +1 -1
  46. package/dist/node/qwen/index.cjs +1 -1
  47. package/dist/node/qwen/index.d.ts +1 -1
  48. package/dist/node/qwen/index.js +1 -1
  49. package/dist/node/qwen-D8gtsbsC.js +2 -0
  50. package/dist/node/qwen-D8gtsbsC.js.map +1 -0
  51. package/dist/node/qwen-DxNnm7Le.cjs +1 -0
  52. package/package.json +4 -2
  53. package/src/anthropic/index.ts +1 -1
  54. package/src/anthropic/message-converter.ts +3 -2
  55. package/src/anthropic/model-catalog-refresh.ts +5 -4
  56. package/src/anthropic/parsers/response-parser.ts +5 -2
  57. package/src/anthropic/provider-definition.ts +2 -1
  58. package/src/anthropic/provider.ts +6 -3
  59. package/src/anthropic/streaming-handler.ts +4 -2
  60. package/src/anthropic/types.ts +1 -1
  61. package/src/bytedance/http-client.ts +1 -1
  62. package/src/bytedance/provider.spec.ts +1 -0
  63. package/src/bytedance/provider.ts +10 -9
  64. package/src/bytedance/status-mapper.ts +1 -1
  65. package/src/deepseek/model-catalog-refresh.ts +6 -5
  66. package/src/deepseek/model-catalog.ts +2 -1
  67. package/src/deepseek/provider-definition.ts +3 -2
  68. package/src/deepseek/provider.ts +11 -9
  69. package/src/deepseek/types.ts +1 -1
  70. package/src/default-provider-definitions.ts +19 -0
  71. package/src/gemini/execution-helpers.ts +14 -12
  72. package/src/gemini/image-operations.ts +2 -2
  73. package/src/gemini/message-converter.ts +1 -0
  74. package/src/gemini/model-catalog-refresh.ts +2 -1
  75. package/src/gemini/provider-definition.ts +2 -1
  76. package/src/gemini/provider.spec.ts +2 -0
  77. package/src/gemini/provider.ts +6 -3
  78. package/src/gemini/tool-schema-converter.ts +1 -0
  79. package/src/gemma/message-factory.ts +2 -1
  80. package/src/gemma/provider-definition.ts +3 -2
  81. package/src/gemma/provider-projection.ts +4 -3
  82. package/src/gemma/provider.ts +19 -17
  83. package/src/gemma/pseudo-command-envelope.ts +1 -0
  84. package/src/gemma/pseudo-tool-call-projector.ts +2 -1
  85. package/src/gemma/streaming-projection.ts +6 -4
  86. package/src/gemma/tool-call-projector.ts +4 -3
  87. package/src/gemma/types.ts +1 -1
  88. package/src/google/provider.ts +1 -0
  89. package/src/index.ts +2 -0
  90. package/src/openai/adapter.ts +1 -1
  91. package/src/openai/chat-completions-chat.ts +8 -7
  92. package/src/openai/loggers/console-payload-logger.ts +4 -2
  93. package/src/openai/loggers/file-payload-logger.ts +5 -2
  94. package/src/openai/message-converter.ts +3 -2
  95. package/src/openai/openai-request-format.ts +1 -1
  96. package/src/openai/parsers/response-parser.ts +3 -2
  97. package/src/openai/provider-definition.ts +3 -2
  98. package/src/openai/provider.ts +11 -9
  99. package/src/openai/responses-chat.ts +7 -5
  100. package/src/openai/responses-converter.ts +6 -6
  101. package/src/openai/responses-parser.ts +4 -2
  102. package/src/openai/responses-types.ts +1 -1
  103. package/src/openai/streaming/stream-handler.ts +6 -4
  104. package/src/openai/types.ts +1 -2
  105. package/src/qwen/model-catalog-refresh.ts +6 -5
  106. package/src/qwen/provider-capabilities.ts +1 -1
  107. package/src/qwen/provider-definition.ts +6 -5
  108. package/src/qwen/provider-streaming-assembly.ts +3 -2
  109. package/src/qwen/provider.ts +19 -12
  110. package/src/qwen/responses-chat.ts +8 -6
  111. package/src/qwen/responses-converter.ts +1 -1
  112. package/src/qwen/responses-parser.ts +4 -2
  113. package/src/qwen/types.ts +1 -1
  114. package/src/shared/openai-compatible/message-converter.ts +1 -1
  115. package/src/shared/openai-compatible/response-parser.ts +4 -2
  116. package/src/shared/openai-compatible/stream-assembler.ts +3 -2
  117. package/src/shared/openai-compatible/types.ts +1 -1
  118. package/dist/node/gemma-Dp_AfCUR.js +0 -2
  119. package/dist/node/gemma-Dp_AfCUR.js.map +0 -1
  120. package/dist/node/openai-CRQjg4xF.js +0 -2
  121. package/dist/node/openai-CRQjg4xF.js.map +0 -1
  122. package/dist/node/qwen-ChUZobTL.js +0 -2
  123. package/dist/node/qwen-ChUZobTL.js.map +0 -1
  124. package/dist/node/qwen-CjT71vSM.cjs +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["toolMsg","streamWithAbort","buildFetchInit","convertMessage","convertAssistantMessage","exhaustive","streamWithAbort","projectText","nextStreamItem","openaiError","assembleOpenAIStream","convertMessage","createMessageInput","convertAssistantMessage","streamWithAbort","nextStreamItem","buildAssistantMessage","extractMessageText","extractFunctionToolCalls","streamWithAbort","buildMessageFromCompletedResponse","applyStreamEvent","extractErrorMessage","applyOutputItem","isFunctionCallOutputItem","convertFunctionCall","buildResponsesRequestParams","openaiError","createStreamDeltaMessage","buildResponsesStreamingRequestParams","exhaustive","requireApiKey","deepSeekError","trimTrailingSlash","buildFetchInit","toModelCatalogEntry","requireApiKey","asRecord","convertAssistantMessage","requireApiKey","toModelCatalogEntry","projectText","appendVisibleTail","longestStartMarkerPrefixSuffixLength","DEFAULT_CALL_ID_PREFIX","createProjectionState","appendVisibleTail","gemmaError","requireApiKey","qwenError","qwenError","qwenError"],"sources":["../../src/anthropic/message-converter.ts","../../src/anthropic/streaming-handler.ts","../../src/anthropic/provider.ts","../../src/anthropic/model-catalog-refresh.ts","../../src/anthropic/provider-definition.ts","../../src/anthropic/index.ts","../../src/shared/openai-compatible/message-converter.ts","../../src/shared/openai-compatible/response-parser.ts","../../src/shared/openai-compatible/stream-assembler.ts","../../src/shared/openai-compatible/native-payload-observer.ts","../../src/shared/openai-compatible/endpoint-probe.ts","../../src/openai/parsers/response-parser.ts","../../src/openai/openai-request-format.ts","../../src/openai/message-converter.ts","../../src/openai/chat-completions-chat.ts","../../src/openai/responses-converter.ts","../../src/openai/responses-stream-utils.ts","../../src/openai/responses-parser.ts","../../src/openai/responses-chat.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/model-catalog-refresh.ts","../../src/openai/provider-definition.ts","../../src/deepseek/defaults.ts","../../src/deepseek/provider.ts","../../src/deepseek/model-catalog.ts","../../src/deepseek/model-catalog-refresh.ts","../../src/deepseek/provider-definition.ts","../../src/gemini/image-operations.ts","../../src/gemini/request-converter.ts","../../src/gemini/tool-schema-converter.ts","../../src/gemini/message-converter.ts","../../src/gemini/execution-helpers.ts","../../src/gemini/provider.ts","../../src/gemini/provider-definition.ts","../../src/gemini/model-catalog-refresh.ts","../../src/gemma/reasoning-projector.ts","../../src/gemma/tool-call-argument-parser.ts","../../src/gemma/pseudo-tool-call-tag-parser.ts","../../src/gemma/pseudo-command-envelope.ts","../../src/gemma/pseudo-tool-call-projector.ts","../../src/gemma/tool-call-projector.ts","../../src/gemma/provider-projection.ts","../../src/gemma/message-factory.ts","../../src/gemma/streaming-projection.ts","../../src/gemma/provider.ts","../../src/gemma/provider-definition.ts","../../src/bytedance/http-client.ts","../../src/bytedance/status-mapper.ts","../../src/bytedance/provider.ts","../../src/qwen/defaults.ts","../../src/qwen/responses-converter.ts","../../src/qwen/responses-stream-utils.ts","../../src/qwen/responses-parser.ts","../../src/qwen/responses-chat.ts","../../src/qwen/provider-capabilities.ts","../../src/qwen/provider-streaming-assembly.ts","../../src/qwen/provider.ts","../../src/qwen/model-catalog-refresh.ts","../../src/qwen/provider-definition.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport Anthropic from '@anthropic-ai/sdk';\nimport type {\n TUniversalMessage,\n IToolSchema,\n IAssistantMessage,\n IToolMessage,\n} from '@robota-sdk/agent-core';\n\n/**\n * Convert TUniversalMessage array to Anthropic message format.\n *\n * CRITICAL: Anthropic API requires specific content handling:\n * - tool_use messages: content MUST be null\n * - regular messages: content should be a string\n */\nexport function convertToAnthropicFormat(messages: TUniversalMessage[]): Anthropic.MessageParam[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n content: msg.content || '',\n };\n } else if (msg.role === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Anthropic uses content blocks — include both text and tool_use\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const contentBlocks: Array<Anthropic.TextBlockParam | Anthropic.ToolUseBlockParam> = [];\n\n // Include text content if present alongside tool calls\n if (assistantMsg.content) {\n contentBlocks.push({\n type: 'text' as const,\n text: assistantMsg.content,\n });\n }\n\n for (const tc of assistantMsg.toolCalls) {\n contentBlocks.push({\n type: 'tool_use' as const,\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n });\n }\n\n return {\n role: 'assistant' as const,\n content: contentBlocks,\n };\n }\n\n // Regular assistant message (no tool calls)\n return {\n role: 'assistant',\n content: assistantMsg.content || '',\n };\n } else if (msg.role === 'tool') {\n // Tool result message — convert to Anthropic tool_result content block\n const toolMsg = msg as IToolMessage;\n return {\n role: 'user' as const,\n content: [\n {\n type: 'tool_result' as const,\n tool_use_id: toolMsg.toolCallId ?? '',\n content: msg.content || '',\n },\n ],\n };\n } else {\n // System messages\n return {\n role: 'user', // Anthropic doesn't have system role, use user\n content: msg.content || '',\n };\n }\n });\n}\n\n/**\n * Convert Anthropic response to TUniversalMessage.\n *\n * Anthropic responses can contain multiple content blocks:\n * e.g., [text(\"I'll read the file\"), tool_use(Read, {...}), tool_use(Bash, {...})]\n * We must extract ALL text and ALL tool_use blocks.\n */\nexport function convertFromAnthropicResponse(response: Anthropic.Message): TUniversalMessage {\n if (!response.content || response.content.length === 0) {\n throw new Error('No content in Anthropic response');\n }\n\n let textParts: string[] = [];\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n\n for (const block of response.content) {\n if (block.type === 'text') {\n const textBlock = block as Anthropic.TextBlock;\n if (textBlock.text) {\n textParts.push(textBlock.text);\n }\n } else if (block.type === 'tool_use') {\n const toolBlock = block as Anthropic.ToolUseBlock;\n toolCalls.push({\n id: toolBlock.id,\n type: 'function' as const,\n function: {\n name: toolBlock.name,\n arguments: JSON.stringify(toolBlock.input),\n },\n });\n } else if (block.type === 'server_tool_use') {\n // Server tool invocation (e.g., web_search) — results come in a separate block\n } else if (block.type === 'web_search_tool_result') {\n const resultBlock = block as Anthropic.Messages.WebSearchToolResultBlock;\n const searchResults = formatWebSearchResults(resultBlock);\n if (searchResults) {\n textParts.push(searchResults);\n }\n }\n }\n\n // Use empty string instead of null so agent-core's buildFinalResult\n // doesn't reject the message. Tool-only responses have no text.\n const textContent = textParts.join('\\n') || '';\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: textContent,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n\n // Add metadata if available\n if (response.usage) {\n result.metadata = {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n model: response.model,\n };\n\n if (response.stop_reason) {\n result.metadata['stopReason'] = response.stop_reason;\n }\n }\n\n return result;\n}\n\n/** Format a WebSearchToolResultBlock into readable text. */\nexport function formatWebSearchResults(block: Anthropic.Messages.WebSearchToolResultBlock): string {\n if (!Array.isArray(block.content)) return '';\n\n const results = block.content\n .filter(\n (r): r is Anthropic.Messages.WebSearchResultBlock =>\n r.type === 'web_search_result' && 'title' in r && 'url' in r,\n )\n .map((r, i) => `${i + 1}. ${r.title}\\n ${r.url}`)\n .join('\\n');\n\n return results ? `[Web Search Results]\\n${results}` : '';\n}\n\n/**\n * Convert tool schemas to Anthropic format.\n */\nexport function convertToolsToAnthropicFormat(tools: IToolSchema[]): Anthropic.Tool[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.parameters as Anthropic.Tool.InputSchema,\n }));\n}\n","import { randomUUID } from 'node:crypto';\nimport Anthropic from '@anthropic-ai/sdk';\nimport type {\n TProviderNativeRawPayloadCallback,\n TUniversalMessage,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\nimport { formatWebSearchResults } from './message-converter';\n\n/**\n * Stream the Anthropic API response and assemble a complete TUniversalMessage.\n *\n * Calls onTextDelta for each text chunk as it arrives.\n * Returns the fully assembled TUniversalMessage when the stream is done.\n */\nexport async function streamAndAssemble(\n client: Anthropic,\n params: Anthropic.MessageCreateParamsNonStreaming,\n onTextDelta: TTextDeltaCallback,\n onServerToolUse: ((toolName: string, input: Record<string, string>) => void) | undefined,\n signal: AbortSignal | undefined,\n onProviderNativeRawPayload?: TProviderNativeRawPayloadCallback,\n): Promise<TUniversalMessage> {\n const streamParams: Anthropic.MessageCreateParamsStreaming = {\n ...params,\n stream: true,\n };\n\n onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'request',\n payload: streamParams,\n });\n const stream = await client.messages.create(streamParams, signal ? { signal } : undefined);\n\n // Accumulate the full response from stream events\n const textParts: string[] = [];\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n let currentToolId = '';\n let currentToolName = '';\n let currentToolJson = '';\n let usage = { input_tokens: 0, output_tokens: 0 };\n let model = '';\n let stopReason: string | null = null;\n\n try {\n let sequence = 0;\n for await (const event of streamWithAbort(stream, signal)) {\n onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'stream_event',\n sequence,\n payload: event,\n });\n sequence++;\n switch (event.type) {\n case 'message_start':\n usage = event.message.usage;\n model = event.message.model;\n break;\n\n case 'content_block_start':\n if (event.content_block.type === 'tool_use') {\n currentToolId = event.content_block.id;\n currentToolName = event.content_block.name;\n currentToolJson = '';\n } else if (event.content_block.type === 'server_tool_use') {\n const serverBlock = event.content_block as {\n name?: string;\n input?: { query?: string };\n };\n const query = serverBlock.input?.query ?? '';\n const toolLabel = query\n ? `\\n🔍 Searching: \"${query}\"\\n`\n : `\\n🔍 [${serverBlock.name ?? 'server_tool'}]\\n`;\n textParts.push(toolLabel);\n onTextDelta(toolLabel);\n if (onServerToolUse) {\n onServerToolUse(serverBlock.name ?? 'server_tool', { query });\n }\n } else if (event.content_block.type === 'web_search_tool_result') {\n const resultBlock = event.content_block as Anthropic.Messages.WebSearchToolResultBlock;\n const formatted = formatWebSearchResults(resultBlock);\n if (formatted) {\n textParts.push(`\\n${formatted}\\n\\n`);\n onTextDelta(`\\n${formatted}\\n\\n`);\n }\n }\n break;\n\n case 'content_block_delta':\n if (event.delta.type === 'text_delta') {\n textParts.push(event.delta.text);\n onTextDelta(event.delta.text);\n } else if (event.delta.type === 'input_json_delta') {\n currentToolJson += event.delta.partial_json;\n }\n break;\n\n case 'content_block_stop':\n if (currentToolId) {\n toolCalls.push({\n id: currentToolId,\n type: 'function' as const,\n function: {\n name: currentToolName,\n arguments: currentToolJson || '{}',\n },\n });\n currentToolId = '';\n currentToolName = '';\n currentToolJson = '';\n }\n break;\n\n case 'message_delta':\n if (event.usage) {\n usage.output_tokens = event.usage.output_tokens;\n }\n stopReason = event.delta.stop_reason;\n break;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return buildPartialResult(textParts, toolCalls, usage, model);\n }\n throw err;\n }\n\n // If aborted via break (not via catch), return partial response\n if (signal?.aborted) {\n return buildPartialResult(textParts, toolCalls, usage, model);\n }\n\n const textContent = textParts.join('') || '';\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: textContent,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n\n result.metadata = {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n model,\n };\n if (stopReason) {\n result.metadata['stopReason'] = stopReason;\n }\n\n return result;\n}\n\nfunction buildPartialResult(\n textParts: string[],\n toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }>,\n usage: { input_tokens: number; output_tokens: number },\n model: string,\n): TUniversalMessage {\n const partialText = textParts.join('') || '';\n const partialResult: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: partialText,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n partialResult.metadata = {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n model,\n stopReason: 'aborted',\n };\n return partialResult;\n}\n\n/**\n * Wrap a stream to support abort signal interruption.\n */\nasync function* streamWithAbort(\n stream: AsyncIterable<Anthropic.MessageStreamEvent>,\n signal?: AbortSignal,\n): AsyncIterable<Anthropic.MessageStreamEvent> {\n for await (const event of stream) {\n if (signal?.aborted) break;\n yield event;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { IAnthropicProviderOptions } from './types';\nimport { AbstractAIProvider, getModelMaxOutput } from '@robota-sdk/agent-core';\nimport type {\n IProviderCapabilities,\n IProviderNativeWebToolRequest,\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\nimport { convertToAnthropicFormat, convertToolsToAnthropicFormat } from './message-converter';\nimport { streamAndAssemble } from './streaming-handler';\n\n/**\n * Anthropic provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Anthropic API:\n * - When tool_calls are present: content MUST be null (not empty string)\n * - For regular assistant messages: content should be a string\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class AnthropicProvider extends AbstractAIProvider {\n override readonly name = 'anthropic';\n override readonly version = '1.0.0';\n\n private readonly client?: Anthropic;\n private readonly options: IAnthropicProviderOptions;\n\n /**\n * When true, Anthropic server tools (web_search) are included in every request.\n * The server executes these tools internally — no local tool registration needed.\n */\n enableWebTools = false;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n /** Callback when a server tool (web_search etc.) is invoked by the API */\n onServerToolUse?: (toolName: string, input: Record<string, string>) => void;\n\n constructor(options: IAnthropicProviderOptions) {\n super();\n this.options = options;\n\n // Set executor if provided\n if (options.executor) {\n this.executor = options.executor;\n }\n\n // Only create client if not using executor\n if (!this.executor) {\n // Create client from apiKey if not provided.\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new Anthropic({\n apiKey: options.apiKey,\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either Anthropic client, apiKey, or executor is required');\n }\n }\n }\n\n /**\n * Generate response using TUniversalMessage\n */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n // Use executor when configured; otherwise use direct execution\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n throw error;\n }\n }\n\n // Direct execution with Anthropic client\n if (!this.client) {\n throw new Error(\n 'Anthropic client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n // Separate system messages for the Anthropic system parameter\n const systemMessages = messages.filter((m) => m.role === 'system');\n const nonSystemMessages = messages.filter((m) => m.role !== 'system');\n const anthropicMessages = convertToAnthropicFormat(nonSystemMessages);\n const systemPrompt = systemMessages.map((m) => m.content || '').join('\\n\\n') || undefined;\n\n if (!options?.model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const functionTools = options?.tools ? convertToolsToAnthropicFormat(options.tools) : [];\n const serverTools: Anthropic.Messages.ToolUnion[] = this.enableWebTools\n ? [{ type: 'web_search_20250305' as const, name: 'web_search' }]\n : [];\n const allTools: Anthropic.Messages.ToolUnion[] = [...functionTools, ...serverTools];\n\n const baseParams: Anthropic.MessageCreateParamsNonStreaming = {\n model: options.model as string,\n messages: anthropicMessages,\n max_tokens: options?.maxTokens || getModelMaxOutput(options.model as string),\n ...(systemPrompt && { system: systemPrompt }),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(allTools.length > 0 && { tools: allTools }),\n };\n\n // Always use streaming to avoid Anthropic SDK's 10-minute non-streaming timeout.\n // When no onTextDelta callback is available, use a no-op to silently assemble the response.\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta ?? (() => {});\n return streamAndAssemble(\n this.client,\n baseParams,\n textDeltaCb,\n this.onServerToolUse,\n options?.signal,\n options?.onProviderNativeRawPayload,\n );\n }\n\n /**\n * Generate streaming response using TUniversalMessage\n */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n // Use executor when configured; otherwise use direct execution\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n throw error;\n }\n }\n\n // Direct execution with Anthropic client\n if (!this.client) {\n throw new Error(\n 'Anthropic client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n const anthropicMessages = convertToAnthropicFormat(messages);\n\n if (!options?.model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams: Anthropic.MessageCreateParamsStreaming = {\n model: options.model as string,\n messages: anthropicMessages,\n max_tokens: options?.maxTokens || getModelMaxOutput(options.model as string),\n stream: true,\n };\n\n if (options?.temperature !== undefined) {\n requestParams.temperature = options.temperature;\n }\n\n const functionTools = options?.tools ? convertToolsToAnthropicFormat(options.tools) : [];\n const serverTools: Anthropic.Messages.ToolUnion[] = this.enableWebTools\n ? [{ type: 'web_search_20250305' as const, name: 'web_search' }]\n : [];\n const allTools: Anthropic.Messages.ToolUnion[] = [...functionTools, ...serverTools];\n\n if (allTools.length > 0) {\n requestParams.tools = allTools;\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.messages.create(requestParams);\n\n let sequence = 0;\n for await (const chunk of stream) {\n options?.onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'stream_event',\n sequence,\n payload: chunk,\n });\n sequence++;\n if (chunk.type === 'content_block_delta' && chunk.delta.type === 'text_delta') {\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: chunk.delta.text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: this.enableWebTools\n ? { supported: true, enabled: true, source: 'anthropic-messages' }\n : {\n supported: true,\n enabled: false,\n source: 'anthropic-messages',\n reason: 'Call configureNativeWebTools({ webSearch: true }) or set enableWebTools.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'anthropic-messages',\n reason: 'Anthropic provider exposes server web search only.',\n },\n },\n };\n }\n\n configureNativeWebTools(request: IProviderNativeWebToolRequest): IProviderCapabilities {\n if (request.webSearch === true) {\n this.enableWebTools = true;\n }\n this.validateNativeWebTools(request);\n return this.getCapabilities();\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Anthropic client doesn't need explicit cleanup\n }\n\n /**\n * Validate TUniversalMessage array\n */\n protected override validateMessages(messages: TUniversalMessage[]): void {\n if (!Array.isArray(messages)) {\n throw new Error('Messages must be an array');\n }\n\n if (messages.length === 0) {\n throw new Error('Messages array cannot be empty');\n }\n\n for (const message of messages) {\n if (!message.role || !['user', 'assistant', 'system', 'tool'].includes(message.role)) {\n throw new Error(`Invalid message role: ${message.role}`);\n }\n }\n }\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport {\n ANTHROPIC_MODEL_SOURCE_URL,\n ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n} from './provider-definition';\n\nconst ANTHROPIC_MODELS_API_URL = 'https://api.anthropic.com/v1/models';\nconst ANTHROPIC_API_VERSION = '2023-06-01';\n\nexport interface IAnthropicModelsResponse {\n data?: Array<{\n id?: string;\n display_name?: string;\n type?: string;\n }>;\n has_more?: boolean;\n}\n\nexport interface IAnthropicFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IAnthropicFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IAnthropicModelsResponse>;\n}\n\nexport type TAnthropicFetch = (\n url: string,\n init?: IAnthropicFetchInit,\n) => Promise<IAnthropicFetchResponse>;\n\nexport async function refreshAnthropicModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TAnthropicFetch = defaultAnthropicFetch,\n): Promise<IProviderModelCatalog> {\n return fetchModelCatalog(profile, fetcher);\n}\n\nasync function fetchModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TAnthropicFetch,\n): Promise<IProviderModelCatalog> {\n const response = await fetcher(ANTHROPIC_MODELS_API_URL, buildFetchInit(profile.apiKey)).catch(\n (err: unknown) => {\n // allow-fallback: catalog refresh is non-terminal; callers expect IProviderModelCatalog\n const message = err instanceof Error ? err.message : String(err);\n return {\n ok: false as const,\n status: 0,\n json: (): Promise<IAnthropicModelsResponse> => Promise.resolve({ data: [] }),\n errorMessage: `Anthropic model refresh failed: ${message}`,\n };\n },\n );\n\n if ('errorMessage' in response) {\n return {\n status: 'unavailable',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n message: response.errorMessage,\n };\n }\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n message: `Anthropic model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const now = new Date().toISOString();\n const entries: IProviderModelCatalogEntry[] = (body.data ?? [])\n .filter(\n (item): item is { id: string; display_name?: string; type?: string } =>\n typeof item.id === 'string' && item.id.length > 0,\n )\n .map(\n (item): IProviderModelCatalogEntry => ({\n id: item.id,\n displayName: item.display_name ?? item.id,\n lifecycle: 'active',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: now,\n }),\n );\n\n return {\n status: 'live',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n entries,\n message: `Fetched ${entries.length} models from Anthropic API`,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IAnthropicFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': ANTHROPIC_API_VERSION,\n },\n };\n}\n\nasync function defaultAnthropicFetch(\n url: string,\n init?: IAnthropicFetchInit,\n): Promise<IAnthropicFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IAnthropicModelsResponse>,\n };\n}\n","import {\n CLAUDE_MODELS,\n type IProviderDefinition,\n type IProviderModelCatalogEntry,\n} from '@robota-sdk/agent-core';\nimport { AnthropicProvider } from './provider';\nimport { refreshAnthropicModelCatalog } from './model-catalog-refresh';\n\nexport const DEFAULT_ANTHROPIC_PROVIDER_MODEL = 'claude-sonnet-4-6';\nexport const DEFAULT_ANTHROPIC_PROVIDER_API_KEY_ENV = 'ANTHROPIC_API_KEY';\nexport const DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_ANTHROPIC_PROVIDER_API_KEY_ENV}`;\nexport const ANTHROPIC_MODEL_SOURCE_URL = 'https://platform.claude.com/docs/en/api/models/list';\nexport const ANTHROPIC_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst ANTHROPIC_API_KEY_URL = 'https://platform.claude.com/settings/keys';\nconst ANTHROPIC_SETUP_SOURCE_URL = 'https://platform.claude.com/docs/en/api/overview';\nconst ANTHROPIC_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst ANTHROPIC_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Anthropic API keys',\n url: ANTHROPIC_API_KEY_URL,\n sourceUrl: ANTHROPIC_SETUP_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createAnthropicProviderDefinition(): IProviderDefinition {\n return {\n type: 'anthropic',\n displayName: 'Anthropic',\n description: 'Claude models through Anthropic API',\n defaults: {\n model: DEFAULT_ANTHROPIC_PROVIDER_MODEL,\n apiKey: DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n entries: buildAnthropicModelCatalogEntries(),\n },\n setupHelpLinks: ANTHROPIC_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'apiKey',\n title: 'Anthropic API key',\n defaultValue: DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n {\n key: 'model',\n title: 'Anthropic model',\n defaultValue: DEFAULT_ANTHROPIC_PROVIDER_MODEL,\n },\n ],\n refreshModelCatalog: ({ profile }) => refreshAnthropicModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n requiresApiKey: true,\n createProvider: (config) =>\n new AnthropicProvider({\n apiKey: requireAnthropicApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction buildAnthropicModelCatalogEntries(): IProviderModelCatalogEntry[] {\n const seen = new Set<string>();\n const entries: IProviderModelCatalogEntry[] = [];\n for (const model of Object.values(CLAUDE_MODELS)) {\n if (seen.has(model.name)) continue;\n seen.add(model.name);\n entries.push({\n id: model.id,\n displayName: model.name,\n contextWindow: model.contextWindow,\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'active',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n });\n }\n return entries;\n}\n\nfunction requireAnthropicApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider anthropic requires apiKey');\n }\n return apiKey;\n}\n","/**\n * @robota-sdk/agent-provider (anthropic)\n *\n * Provides Provider implementation for using Anthropic API with provider-agnostic TUniversalMessage.\n */\n\n// Main exports\nexport * from './provider';\nexport * from './types';\nexport * from './provider-definition';\nexport * from './model-catalog-refresh';\n\nimport type { IAnthropicProviderOptions } from './types';\n\n/**\n * Factory function for creating an AnthropicProvider instance.\n * @param _options - Configuration options for the Anthropic provider\n * @returns An AnthropicProvider instance\n */\nexport function createAnthropicProvider(_options: IAnthropicProviderOptions) {\n // Implementation of createAnthropicProvider function\n}\n","import type OpenAI from 'openai';\nimport type {\n IAssistantMessage,\n IToolCall,\n IToolSchema,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\nexport function convertToOpenAICompatibleMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return messages.map((message) => convertMessage(message));\n}\n\nexport function convertToOpenAICompatibleTools(\n tools: IToolSchema[],\n): OpenAI.Chat.ChatCompletionTool[] {\n return tools.map((tool) => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n }));\n}\n\nfunction convertMessage(message: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n if (message.role === 'user') {\n return {\n role: 'user',\n content: message.content || '',\n };\n }\n\n if (message.role === 'assistant') {\n return convertAssistantMessage(message);\n }\n\n if (message.role === 'system') {\n return {\n role: 'system',\n content: message.content || '',\n };\n }\n\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return {\n role: 'tool',\n content: message.content || '',\n tool_call_id: message.toolCallId,\n };\n }\n\n const exhaustive: never = message;\n throw new Error(`Unsupported message role: ${JSON.stringify(exhaustive)}`);\n}\n\nfunction convertAssistantMessage(\n message: IAssistantMessage,\n): OpenAI.Chat.ChatCompletionAssistantMessageParam {\n if (message.toolCalls && message.toolCalls.length > 0) {\n return {\n role: 'assistant',\n content: message.content === '' ? null : message.content || null,\n tool_calls: message.toolCalls.map((toolCall: IToolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n }\n\n return {\n role: 'assistant',\n content: message.content === null ? null : message.content || '',\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type OpenAI from 'openai';\nimport type { ILogger, IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { SilentLogger } from '@robota-sdk/agent-core';\nimport type {\n IOpenAICompatibleToolCallTextProjector,\n IOpenAICompatibleToolCallTextProjection,\n TOpenAICompatibleTextProjector,\n} from './types';\n\nexport interface IOpenAICompatibleResponseParserOptions {\n logger?: ILogger;\n textProjector?: TOpenAICompatibleTextProjector;\n toolCallTextProjector?: IOpenAICompatibleToolCallTextProjector;\n}\n\nexport class OpenAICompatibleResponseParser {\n private readonly logger: ILogger;\n private readonly textProjector?: TOpenAICompatibleTextProjector;\n private readonly toolCallTextProjector?: IOpenAICompatibleToolCallTextProjector;\n\n constructor(options: IOpenAICompatibleResponseParserOptions = {}) {\n this.logger = options.logger ?? SilentLogger;\n this.textProjector = options.textProjector;\n this.toolCallTextProjector = options.toolCallTextProjector;\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n const choice = response.choices?.[0];\n if (!choice) {\n throw new Error('No choices found in OpenAI-compatible response');\n }\n\n return this.parseChoice(choice, response.usage);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'OpenAI-compatible response parsing failed';\n this.logger.error('Response parsing failed', { error: message });\n throw new Error(`OpenAI-compatible response parsing failed: ${message}`);\n }\n }\n\n private parseChoice(\n choice: OpenAI.Chat.ChatCompletion.Choice,\n usage: OpenAI.CompletionUsage | undefined,\n ): TUniversalMessage {\n const message = choice.message;\n const toolTextProjection = this.projectToolCallText(message.content || '');\n const toolTextFlush = this.toolCallTextProjector?.flush();\n const nativeToolCalls = this.parseNativeToolCalls(message);\n const projectedToolCalls = [\n ...toolTextProjection.toolCalls,\n ...(toolTextFlush?.toolCalls ?? []),\n ];\n const toolCalls = [...nativeToolCalls, ...projectedToolCalls];\n\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: this.projectText(\n toolTextProjection.visibleText + (toolTextFlush?.visibleText ?? ''),\n ),\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n ...(usage && { usage: this.parseUsage(usage) }),\n metadata: {\n finishReason: choice.finish_reason || undefined,\n ...this.buildToolTextMetadata(toolTextProjection, toolTextFlush),\n },\n };\n }\n\n private parseNativeToolCalls(message: OpenAI.Chat.ChatCompletionMessage): IToolCall[] {\n return (\n message.tool_calls?.map((toolCall) => ({\n id: toolCall.id,\n type: 'function' as const,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })) || []\n );\n }\n\n private parseUsage(usage: OpenAI.CompletionUsage): {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n } {\n return {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n };\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n const choice = chunk.choices?.[0];\n if (!choice) {\n return null;\n }\n\n const finishReason = choice.finish_reason;\n const toolCalls = choice.delta.tool_calls?.map((toolCall) => ({\n id: toolCall.id || '',\n type: 'function' as const,\n function: {\n name: toolCall.function?.name || '',\n arguments: toolCall.function?.arguments || '',\n },\n }));\n\n if (toolCalls) {\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n toolCalls,\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n }\n\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: this.projectText(choice.delta.content || ''),\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'OpenAI-compatible chunk parsing failed';\n this.logger.error('Chunk parsing failed', { error: message });\n throw new Error(`OpenAI-compatible chunk parsing failed: ${message}`);\n }\n }\n\n private projectText(text: string): string {\n return this.textProjector ? this.textProjector(text) : text;\n }\n\n private projectToolCallText(text: string): IOpenAICompatibleToolCallTextProjection {\n return (\n this.toolCallTextProjector?.project(text) ?? {\n visibleText: text,\n toolCalls: [],\n removedToolCallText: false,\n }\n );\n }\n\n private buildToolTextMetadata(\n projection: IOpenAICompatibleToolCallTextProjection,\n flush: IOpenAICompatibleToolCallTextProjection | undefined,\n ): Record<string, string | boolean | undefined> {\n const rawToolCallText = [projection.rawToolCallText, flush?.rawToolCallText]\n .filter((text): text is string => typeof text === 'string' && text.length > 0)\n .join('');\n const removedToolCallText =\n projection.removedToolCallText || (flush?.removedToolCallText ?? false);\n\n return {\n ...(removedToolCallText && { toolCallTextProjected: true }),\n ...(rawToolCallText.length > 0 && { rawToolCallText }),\n };\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type OpenAI from 'openai';\nimport type { IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type {\n IOpenAICompatibleToolCallTextProjection,\n IOpenAICompatibleStreamAssemblyOptions,\n TOpenAICompatibleTextProjector,\n} from './types';\n\ninterface IToolCallPart {\n id: string;\n name: string;\n arguments: string;\n}\n\ninterface IAssemblyState {\n textParts: string[];\n toolCallParts: Map<number, IToolCallPart>;\n projectedToolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n toolCallTextProjected: boolean;\n model: string;\n finishReason: string | null;\n}\n\nexport async function assembleOpenAICompatibleStream(\n options: IOpenAICompatibleStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IAssemblyState = {\n textParts: [],\n toolCallParts: new Map(),\n projectedToolCalls: [],\n rawToolCallTextParts: [],\n toolCallTextProjected: false,\n model: '',\n finishReason: null,\n };\n\n for await (const chunk of streamWithAbort(options.stream, options.signal)) {\n applyChunk(state, chunk, options);\n }\n applyProjectedTextFlush(state, options);\n\n return buildMessage(state, options.metadata);\n}\n\nfunction applyChunk(\n state: IAssemblyState,\n chunk: OpenAI.Chat.ChatCompletionChunk,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n if (chunk.model) {\n state.model = chunk.model;\n }\n\n const choice = chunk.choices?.[0];\n if (!choice) {\n return;\n }\n\n state.finishReason = choice.finish_reason ?? state.finishReason;\n applyTextDelta(state, choice.delta.content, options);\n applyToolCallDeltas(state, choice.delta.tool_calls ?? []);\n}\n\nfunction applyTextDelta(\n state: IAssemblyState,\n content: string | null | undefined,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n if (!content) {\n return;\n }\n\n const toolProjection = projectToolCallText(content, options.toolCallTextProjector);\n applyToolCallTextProjection(state, toolProjection);\n const visibleContent = projectText(toolProjection.visibleText, options.textProjector);\n if (visibleContent.length === 0) {\n return;\n }\n\n state.textParts.push(visibleContent);\n options.onTextDelta?.(visibleContent);\n}\n\nfunction projectText(text: string, projector?: TOpenAICompatibleTextProjector): string {\n return projector ? projector(text) : text;\n}\n\nfunction applyProjectedTextFlush(\n state: IAssemblyState,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n const toolProjection = options.toolCallTextProjector?.flush();\n if (toolProjection) {\n applyToolCallTextProjection(state, toolProjection);\n const visibleToolText = projectText(toolProjection.visibleText, options.textProjector);\n if (visibleToolText.length > 0) {\n state.textParts.push(visibleToolText);\n options.onTextDelta?.(visibleToolText);\n }\n }\n\n const visibleContent = options.textProjectorFlush?.();\n if (!visibleContent) {\n return;\n }\n\n state.textParts.push(visibleContent);\n options.onTextDelta?.(visibleContent);\n}\n\nfunction projectToolCallText(\n text: string,\n projector: IOpenAICompatibleStreamAssemblyOptions['toolCallTextProjector'],\n): IOpenAICompatibleToolCallTextProjection {\n return (\n projector?.project(text) ?? {\n visibleText: text,\n toolCalls: [],\n removedToolCallText: false,\n }\n );\n}\n\nfunction applyToolCallTextProjection(\n state: IAssemblyState,\n projection: IOpenAICompatibleToolCallTextProjection,\n): void {\n if (projection.toolCalls.length > 0) {\n state.projectedToolCalls.push(...projection.toolCalls);\n }\n if (projection.removedToolCallText) {\n state.toolCallTextProjected = true;\n }\n if (projection.rawToolCallText && projection.rawToolCallText.length > 0) {\n state.rawToolCallTextParts.push(projection.rawToolCallText);\n }\n}\n\nfunction applyToolCallDeltas(\n state: IAssemblyState,\n deltas: OpenAI.Chat.ChatCompletionChunk.Choice.Delta.ToolCall[],\n): void {\n for (const delta of deltas) {\n const index = delta.index ?? 0;\n const current = state.toolCallParts.get(index) ?? { id: '', name: '', arguments: '' };\n const nextName = delta.function?.name ?? current.name;\n state.toolCallParts.set(index, {\n id: delta.id ?? current.id,\n name: nextName,\n arguments: current.arguments + (delta.function?.arguments ?? ''),\n });\n }\n}\n\nfunction buildMessage(\n state: IAssemblyState,\n metadata: Record<string, string | number | boolean> = {},\n): TUniversalMessage {\n const resultMetadata: NonNullable<TUniversalMessage['metadata']> = { ...metadata };\n if (state.model) {\n resultMetadata['model'] = state.model;\n }\n if (state.finishReason) {\n resultMetadata['finishReason'] = state.finishReason;\n }\n if (state.toolCallTextProjected) {\n resultMetadata['toolCallTextProjected'] = true;\n }\n if (state.rawToolCallTextParts.length > 0) {\n resultMetadata['rawToolCallText'] = state.rawToolCallTextParts.join('');\n }\n\n const toolCalls = buildAllToolCalls(state);\n\n return {\n id: randomUUID(),\n role: 'assistant',\n content: state.textParts.join(''),\n state: 'complete',\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n ...(Object.keys(resultMetadata).length > 0 && { metadata: resultMetadata }),\n };\n}\n\nfunction buildAllToolCalls(state: IAssemblyState): IToolCall[] {\n return [...buildToolCalls(state.toolCallParts), ...state.projectedToolCalls];\n}\n\nfunction buildToolCalls(toolCallParts: Map<number, IToolCallPart>): IToolCall[] {\n return Array.from(toolCallParts.entries())\n .sort(([left], [right]) => left - right)\n .map(([index, toolCall]) => ({\n id: toolCall.id || `call_${index}`,\n type: 'function',\n function: {\n name: toolCall.name,\n arguments: toolCall.arguments || '{}',\n },\n }));\n}\n\nasync function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done) break;\n await yieldToMacrotask(signal);\n if (signal?.aborted) break;\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) return iterator.next();\n if (signal.aborted) return { done: true, value: undefined as T };\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n\nasync function yieldToMacrotask(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) return;\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n}\n","import type { TProviderNativeRawPayloadCallback } from '@robota-sdk/agent-core';\n\nexport interface IObserveProviderNativeRawPayloadStreamOptions {\n provider: string;\n apiSurface?: string;\n onProviderNativeRawPayload?: TProviderNativeRawPayloadCallback;\n initialSequence?: number;\n}\n\nexport async function* observeProviderNativeRawPayloadStream<TPayload extends object>(\n stream: AsyncIterable<TPayload>,\n options: IObserveProviderNativeRawPayloadStreamOptions,\n): AsyncIterable<TPayload> {\n let sequence = options.initialSequence ?? 0;\n for await (const payload of stream) {\n options.onProviderNativeRawPayload?.({\n provider: options.provider,\n ...(options.apiSurface !== undefined && { apiSurface: options.apiSurface }),\n payloadKind: 'stream_event',\n sequence,\n payload,\n });\n sequence++;\n yield payload;\n }\n}\n","import type { IProviderProfileConfig, IProviderProbeResult } from '@robota-sdk/agent-core';\n\nexport interface IOpenAICompatibleModelsResponse {\n data?: Array<{ id?: string }>;\n}\n\nexport interface IOpenAICompatibleFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IOpenAICompatibleModelsResponse>;\n}\n\nexport type TOpenAICompatibleFetch = (url: string) => Promise<IOpenAICompatibleFetchResponse>;\n\nexport async function probeOpenAICompatibleProfile(\n profile: IProviderProfileConfig,\n fetcher: TOpenAICompatibleFetch = defaultOpenAICompatibleFetch,\n): Promise<IProviderProbeResult> {\n if (!profile.baseURL) {\n return { ok: true, message: 'Profile fields are valid; no endpoint probe configured.' };\n }\n\n try {\n const response = await fetcher(`${profile.baseURL.replace(/\\/$/, '')}/models`);\n if (!response.ok) {\n return { ok: false, message: `HTTP ${response.status}` };\n }\n const body = await response.json();\n const models = (body.data ?? []).map((item) => item.id).filter((id): id is string => !!id);\n return { ok: true, message: `${models.length} model(s) discovered`, models };\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) };\n }\n}\n\nasync function defaultOpenAICompatibleFetch(url: string): Promise<IOpenAICompatibleFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IOpenAICompatibleModelsResponse>,\n };\n}\n","import type OpenAI from 'openai';\nimport type { ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { OpenAICompatibleResponseParser } from '../../shared/openai-compatible/index.js';\n\n/**\n * OpenAI response parser compatibility wrapper.\n *\n * The implementation delegates to the shared OpenAI-compatible parser while\n * preserving the OpenAI-branded error messages that are part of this package's\n * current test contract.\n */\nexport class OpenAIResponseParser {\n private readonly parser: OpenAICompatibleResponseParser;\n\n constructor(logger?: ILogger) {\n this.parser = new OpenAICompatibleResponseParser({ logger });\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n return this.parser.parseResponse(response);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI response parsing failed',\n );\n throw new Error(`OpenAI response parsing failed: ${message}`);\n }\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n return this.parser.parseStreamingChunk(chunk);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI chunk parsing failed',\n );\n throw new Error(`OpenAI chunk parsing failed: ${message}`);\n }\n }\n}\n\nfunction normalizeParserMessage(message: string): string {\n return message\n .replace(/^OpenAI-compatible response parsing failed: /, '')\n .replace(/^OpenAI-compatible chunk parsing failed: /, '')\n .replace('OpenAI-compatible response', 'OpenAI response');\n}\n","import type { IOpenAIProviderOptions, TOpenAIProviderOptionValue } from './types';\nimport type {\n IOpenAIResponsesTextConfig,\n IOpenAIResponsesTextFormatJsonSchema,\n} from './responses-types';\n\nexport interface IOpenAIChatTextFormatText {\n type: 'text';\n}\n\nexport interface IOpenAIChatTextFormatJsonObject {\n type: 'json_object';\n}\n\nexport interface IOpenAIChatTextFormatJsonSchema {\n type: 'json_schema';\n json_schema: {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n };\n}\n\nexport type TOpenAIChatResponseFormat =\n | IOpenAIChatTextFormatText\n | IOpenAIChatTextFormatJsonObject\n | IOpenAIChatTextFormatJsonSchema;\n\nexport function buildOpenAIChatResponseFormat(\n options: IOpenAIProviderOptions,\n): TOpenAIChatResponseFormat | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { type: 'json_object' };\n }\n\n const schema = requireJsonSchema(options);\n return {\n type: 'json_schema',\n json_schema: {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n },\n };\n}\n\nexport function buildOpenAIResponsesTextConfig(\n options: IOpenAIProviderOptions,\n): IOpenAIResponsesTextConfig | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { format: { type: 'json_object' } };\n }\n\n const schema = requireJsonSchema(options);\n const format: IOpenAIResponsesTextFormatJsonSchema = {\n type: 'json_schema',\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n return { format };\n}\n\nfunction requireJsonSchema(input: IOpenAIProviderOptions): {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n} {\n const schema = input.jsonSchema;\n if (input.responseFormat !== 'json_schema') {\n throw new Error(`Unsupported OpenAI response format: ${input.responseFormat}`);\n }\n if (!schema?.schema) {\n throw new Error('OpenAI jsonSchema.schema is required when responseFormat is json_schema');\n }\n return {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n}\n","import type OpenAI from 'openai';\nimport type { IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport {\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n} from '../shared/openai-compatible/index.js';\n\n/**\n * Convert TUniversalMessage array to OpenAI chat completion message format.\n */\nexport function convertToOpenAIMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return convertToOpenAICompatibleMessages(messages);\n}\n\n/**\n * Convert tool schemas to OpenAI function tool format.\n */\nexport function convertToOpenAITools(tools: IToolSchema[]): OpenAI.Chat.ChatCompletionTool[] {\n return convertToOpenAICompatibleTools(tools);\n}\n","import type OpenAI from 'openai';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { observeProviderNativeRawPayloadStream } from '../shared/openai-compatible/index.js';\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { IOpenAIError, IOpenAILogData } from './types/api-types';\nimport type { IOpenAIProviderOptions } from './types';\nimport { buildOpenAIChatResponseFormat } from './openai-request-format';\nimport { convertToOpenAIMessages, convertToOpenAITools } from './message-converter';\nimport { OpenAIResponseParser } from './parsers/response-parser';\nimport { assembleOpenAIStream } from './streaming/stream-assembler';\n\nexport interface IOpenAIChatCompletionsOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n payloadLogger?: IPayloadLogger;\n responseParser: OpenAIResponseParser;\n onTextDelta?: TTextDeltaCallback;\n}\n\nexport async function chatWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): Promise<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams = buildChatRequestParams(input);\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return await chatWithStreamingAssembly(client, input, {\n ...requestParams,\n stream: true,\n });\n }\n\n await logPayload(input, requestParams, 'chat');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(requestParams);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return input.responseParser.parseResponse(response);\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI API request failed';\n throw new Error(`OpenAI chat failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): AsyncIterable<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n ...buildChatRequestParams(input),\n stream: true,\n };\n\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n\n for await (const chunk of observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n })) {\n const universalMessage = input.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI API request failed';\n throw new Error(`OpenAI stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildChatRequestParams(\n input: IOpenAIChatCompletionsOptions,\n): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const openaiMessages = convertToOpenAIMessages(input.messages);\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const responseFormat = buildOpenAIChatResponseFormat(input.providerOptions);\n return {\n model,\n messages: openaiMessages,\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && { max_tokens: input.chatOptions.maxTokens }),\n ...(input.chatOptions?.tools && {\n tools: convertToOpenAITools(input.chatOptions.tools),\n tool_choice: 'auto',\n }),\n ...(responseFormat !== undefined && { response_format: responseFormat }),\n } as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n}\n\nasync function chatWithStreamingAssembly(\n client: OpenAI,\n input: IOpenAIChatCompletionsOptions,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n): Promise<TUniversalMessage> {\n try {\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n\n return assembleOpenAIStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n }),\n onTextDelta: input.chatOptions?.onTextDelta ?? input.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI streaming request failed';\n throw new Error(`OpenAI stream failed: ${errorMessage}`);\n }\n}\n\nasync function logPayload(\n input: IOpenAIChatCompletionsOptions,\n requestParams:\n | OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n | OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n type: 'chat' | 'stream',\n): Promise<void> {\n if (!input.payloadLogger?.isEnabled()) {\n return;\n }\n\n const logData: IOpenAILogData = {\n model: requestParams.model,\n messagesCount: requestParams.messages.length,\n hasTools: !!requestParams.tools,\n temperature: requestParams.temperature ?? undefined,\n maxTokens: requestParams.max_tokens ?? undefined,\n timestamp: new Date().toISOString(),\n };\n await input.payloadLogger.logPayload(logData, type);\n}\n\nfunction requireClient(client: OpenAI | undefined): OpenAI {\n if (!client) {\n throw new Error(\n 'OpenAI client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n return client;\n}\n","import type {\n IAssistantMessage,\n IToolSchema,\n TUniversalMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\nimport type {\n IOpenAIResponsesFunctionTool,\n IOpenAIResponsesMessageInput,\n TOpenAIResponsesInputContent,\n TOpenAIResponsesInputItem,\n} from './responses-types';\n\nexport function convertToOpenAIResponsesInput(\n messages: TUniversalMessage[],\n): TOpenAIResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\nexport function convertToOpenAIResponsesTools(\n tools: IToolSchema[] | undefined,\n strictTools: boolean | undefined,\n): IOpenAIResponsesFunctionTool[] | undefined {\n const converted =\n tools?.map((tool) => ({\n type: 'function' as const,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n strict: strictTools ?? false,\n })) ?? [];\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction convertMessage(message: TUniversalMessage): TOpenAIResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', getUserContent(message.content, message.parts))];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TOpenAIResponsesInputItem[] {\n const items: TOpenAIResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction getUserContent(\n content: string,\n parts: TUniversalMessagePart[] | undefined,\n): string | TOpenAIResponsesInputContent[] {\n if (!parts || parts.length === 0) {\n return content;\n }\n\n const converted = parts.map((part) => convertPart(part));\n if (content.length > 0 && !parts.some((part) => part.type === 'text')) {\n return [{ type: 'input_text', text: content }, ...converted];\n }\n return converted;\n}\n\nfunction convertPart(part: TUniversalMessagePart): TOpenAIResponsesInputContent {\n if (part.type === 'text') {\n return { type: 'input_text', text: part.text };\n }\n if (part.type === 'image_uri') {\n return { type: 'input_image', image_url: part.uri };\n }\n return {\n type: 'input_image',\n image_url: `data:${part.mimeType};base64,${part.data}`,\n };\n}\n\nfunction createMessageInput(\n role: IOpenAIResponsesMessageInput['role'],\n content: string | TOpenAIResponsesInputContent[],\n): IOpenAIResponsesMessageInput {\n return {\n role,\n content,\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done || signal?.aborted) {\n break;\n }\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) {\n return iterator.next();\n }\n if (signal.aborted) {\n return { done: true, value: undefined as T };\n }\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) {\n signal.removeEventListener('abort', abortListener);\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { IToolCall, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type {\n IOpenAIResponsesErrorEvent,\n IOpenAIResponsesFunctionCallOutputItem,\n IOpenAIResponsesMessageOutputItem,\n IOpenAIResponsesReasoningOutputItem,\n IOpenAIResponsesResponse,\n IOpenAIResponsesUsage,\n TOpenAIResponsesOutputContent,\n TOpenAIResponsesOutputItem,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport { streamWithAbort } from './responses-stream-utils';\n\ninterface IOpenAIResponsesStreamAssemblyOptions {\n stream: AsyncIterable<TOpenAIResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IOpenAIResponsesReasoningMetadata {\n reasoningSummaryCount: number;\n reasoningSummaries: string[];\n hasEncryptedReasoning: boolean;\n}\n\ninterface IOpenAIResponseUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\ninterface IOpenAIResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}\n\nexport function parseOpenAIResponsesResponse(\n response: IOpenAIResponsesResponse,\n): TUniversalMessage {\n assertUsableResponse(response);\n const output = response.output ?? [];\n const content = response.output_text ?? extractMessageText(output);\n return buildAssistantMessage({\n content,\n toolCalls: extractFunctionToolCalls(output),\n response,\n reasoning: collectReasoningMetadata(output),\n });\n}\n\nexport async function assembleOpenAIResponsesStream(\n options: IOpenAIResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IOpenAIResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n reasoning: createEmptyReasoningMetadata(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n reasoning: state.reasoning,\n });\n}\n\nfunction applyStreamEvent(\n state: IOpenAIResponsesStreamState,\n event: TOpenAIResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata(event.response.output ?? []));\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (\n event.type === 'response.error' ||\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n throw new Error(`OpenAI Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction applyOutputItem(\n state: IOpenAIResponsesStreamState,\n item: TOpenAIResponsesOutputItem,\n): void {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n return;\n }\n if (isReasoningOutputItem(item)) {\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata([item]));\n }\n}\n\nfunction buildMessageFromCompletedResponse(state: IOpenAIResponsesStreamState): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('OpenAI Responses stream completed without response metadata');\n }\n\n assertUsableResponse(response);\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const reasoning = collectReasoningMetadata(output);\n mergeReasoningMetadata(reasoning, state.reasoning);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n reasoning,\n });\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && { usage: mapUsage(input.response.usage) }),\n metadata: buildMetadata(input.response, input.reasoning),\n };\n}\n\nfunction buildMetadata(\n response: IOpenAIResponsesResponse | undefined,\n reasoning: IOpenAIResponsesReasoningMetadata,\n): NonNullable<TUniversalMessage['metadata']> {\n return {\n providerApiSurface: 'responses',\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n ...(reasoning.reasoningSummaryCount > 0 && {\n reasoningSummaryCount: reasoning.reasoningSummaryCount,\n reasoningSummaries: reasoning.reasoningSummaries,\n }),\n ...(reasoning.hasEncryptedReasoning && { hasEncryptedReasoning: true }),\n };\n}\n\nfunction mapUsage(usage: IOpenAIResponsesUsage): IOpenAIResponseUsage {\n return {\n promptTokens: usage.input_tokens ?? 0,\n completionTokens: usage.output_tokens ?? 0,\n totalTokens: usage.total_tokens ?? 0,\n };\n}\n\nfunction extractFunctionToolCalls(output: readonly TOpenAIResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IOpenAIResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TOpenAIResponsesOutputItem[]): string {\n return output\n .filter(isMessageOutputItem)\n .flatMap((item) => item.content)\n .map(extractTextContent)\n .join('');\n}\n\nfunction extractTextContent(content: TOpenAIResponsesOutputContent): string {\n if (content.type === 'refusal') {\n return content.refusal;\n }\n return content.text;\n}\n\nfunction isMessageOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesMessageOutputItem {\n return item.type === 'message' && 'content' in item && Array.isArray(item.content);\n}\n\nfunction collectReasoningMetadata(\n output: readonly TOpenAIResponsesOutputItem[],\n): IOpenAIResponsesReasoningMetadata {\n const metadata = createEmptyReasoningMetadata();\n for (const item of output) {\n if (!isReasoningOutputItem(item)) {\n continue;\n }\n const summaries = item.summary?.map((summary) => summary.text).filter(isString) ?? [];\n metadata.reasoningSummaryCount += summaries.length;\n metadata.reasoningSummaries.push(...summaries);\n metadata.hasEncryptedReasoning = metadata.hasEncryptedReasoning || !!item.encrypted_content;\n }\n return metadata;\n}\n\nfunction isReasoningOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesReasoningOutputItem {\n return item.type === 'reasoning';\n}\n\nfunction createEmptyReasoningMetadata(): IOpenAIResponsesReasoningMetadata {\n return {\n reasoningSummaryCount: 0,\n reasoningSummaries: [],\n hasEncryptedReasoning: false,\n };\n}\n\nfunction mergeReasoningMetadata(\n target: IOpenAIResponsesReasoningMetadata,\n source: IOpenAIResponsesReasoningMetadata,\n): void {\n target.reasoningSummaryCount += source.reasoningSummaryCount;\n target.reasoningSummaries.push(...source.reasoningSummaries);\n target.hasEncryptedReasoning = target.hasEncryptedReasoning || source.hasEncryptedReasoning;\n}\n\nfunction isString(value: string | undefined): value is string {\n return value !== undefined;\n}\n\nfunction assertUsableResponse(response: IOpenAIResponsesResponse): void {\n if (response.status === 'failed' || response.status === 'incomplete') {\n throw new Error(`OpenAI Responses API failed: ${response.error?.message ?? response.status}`);\n }\n}\n\nfunction extractErrorMessage(event: IOpenAIResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\nimport type OpenAI from 'openai';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { observeProviderNativeRawPayloadStream } from '../shared/openai-compatible/index.js';\nimport type { IOpenAIError } from './types/api-types';\nimport type { IOpenAIProviderOptions } from './types';\nimport { buildOpenAIResponsesTextConfig } from './openai-request-format';\nimport {\n convertToOpenAIResponsesInput,\n convertToOpenAIResponsesTools,\n} from './responses-converter';\nimport { assembleOpenAIResponsesStream, parseOpenAIResponsesResponse } from './responses-parser';\nimport type {\n IOpenAIResponsesRequestNonStreaming,\n IOpenAIResponsesRequestStreaming,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\n\nexport interface IOpenAIResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n onTextDelta?: TTextDeltaCallback;\n}\n\ninterface IResponsesStreamMessageQueue {\n deltas: TUniversalMessage[];\n finalMessage?: TUniversalMessage;\n error?: Error;\n wake?: () => void;\n}\n\nexport async function chatWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return parseOpenAIResponsesResponse(response);\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI Responses API request failed';\n throw new Error(`OpenAI responses failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const queue: IResponsesStreamMessageQueue = { deltas: [] };\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n const assembly = chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n textDeltaCb?.(delta);\n enqueueStreamDelta(queue, createStreamDeltaMessage(delta));\n },\n },\n })\n .then((result) => finishStreamQueue(queue, result))\n .catch((error) => failStreamQueue(queue, toError(error)));\n\n yield* drainResponsesStreamQueue(queue);\n await assembly;\n}\n\nasync function chatWithOpenAIResponsesStreamingAssembly(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n return assembleOpenAIResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TOpenAIResponsesStreamEvent>,\n {\n provider: 'openai',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI Responses streaming request failed';\n throw new Error(`OpenAI responses stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const tools = convertToOpenAIResponsesTools(\n input.chatOptions?.tools,\n input.providerOptions.strictTools,\n );\n const textConfig = buildOpenAIResponsesTextConfig(input.providerOptions);\n return {\n model,\n input: convertToOpenAIResponsesInput(input.messages),\n ...(tools !== undefined && { tools, tool_choice: 'auto' }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(textConfig !== undefined && { text: textConfig }),\n ...(input.providerOptions.reasoning !== undefined && {\n reasoning: input.providerOptions.reasoning,\n }),\n ...(input.providerOptions.includeEncryptedReasoning === true && {\n include: ['reasoning.encrypted_content'],\n }),\n ...(input.providerOptions.store !== undefined && { store: input.providerOptions.store }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n providerApiSurface: 'responses',\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n\nasync function* drainResponsesStreamQueue(\n queue: IResponsesStreamMessageQueue,\n): AsyncIterable<TUniversalMessage> {\n while (true) {\n const next = queue.deltas.shift();\n if (next !== undefined) {\n yield next;\n continue;\n }\n if (queue.error !== undefined) {\n throw queue.error;\n }\n if (queue.finalMessage !== undefined) {\n yield createFinalStreamMessage(queue.finalMessage);\n return;\n }\n await waitForStreamQueue(queue);\n }\n}\n\nfunction enqueueStreamDelta(queue: IResponsesStreamMessageQueue, message: TUniversalMessage): void {\n queue.deltas.push(message);\n wakeStreamQueue(queue);\n}\n\nfunction finishStreamQueue(queue: IResponsesStreamMessageQueue, result: TUniversalMessage): void {\n queue.finalMessage = result;\n wakeStreamQueue(queue);\n}\n\nfunction failStreamQueue(queue: IResponsesStreamMessageQueue, error: Error): void {\n queue.error = error;\n wakeStreamQueue(queue);\n}\n\nfunction waitForStreamQueue(queue: IResponsesStreamMessageQueue): Promise<void> {\n return new Promise((resolve) => {\n queue.wake = resolve;\n });\n}\n\nfunction wakeStreamQueue(queue: IResponsesStreamMessageQueue): void {\n queue.wake?.();\n queue.wake = undefined;\n}\n\nfunction createFinalStreamMessage(result: TUniversalMessage): TUniversalMessage {\n return {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nfunction toError(error: Error | string): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n","import OpenAI from 'openai';\nimport type { IOpenAIProviderOptions, TOpenAIApiSurface } from './types';\nimport { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IAssistantMessage,\n IProviderCapabilities,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport { OpenAIResponseParser } from './parsers/response-parser';\nimport { SilentLogger } from '@robota-sdk/agent-core';\nimport {\n chatStreamWithOpenAIChatCompletions,\n chatWithOpenAIChatCompletions,\n} from './chat-completions-chat';\nimport { chatStreamWithOpenAIResponsesApi, chatWithOpenAIResponsesApi } from './responses-chat';\n\n/**\n * OpenAI provider implementation for Robota\n *\n * Provides integration with OpenAI models through the Robota provider contract.\n * Uses OpenAI SDK native types internally for optimal performance and feature support.\n *\n * @public\n */\nexport class OpenAIProvider extends AbstractAIProvider {\n override readonly name = 'openai';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IOpenAIProviderOptions;\n private readonly apiSurface: TOpenAIApiSurface;\n private readonly payloadLogger: IPayloadLogger | undefined;\n private readonly responseParser: OpenAIResponseParser;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IOpenAIProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n this.apiSurface = resolveApiSurface(options);\n validateOpenAIProviderNativeWebTools(this.apiSurface, options.nativeWebTools);\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.organization && { organization: options.organization }),\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either OpenAI client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAIResponseParser(this.logger);\n this.payloadLogger = options.payloadLogger;\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n return chatWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n });\n }\n\n return chatWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n });\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n yield* chatStreamWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n });\n return;\n }\n\n yield* chatStreamWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n });\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n const source =\n this.apiSurface === 'chat-completions'\n ? 'openai-compatible-chat-completions'\n : 'openai-responses';\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'search'),\n },\n webFetch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'fetch'),\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI client doesn't need explicit cleanup\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n}\n\nfunction resolveApiSurface(options: IOpenAIProviderOptions): TOpenAIApiSurface {\n if (options.apiSurface !== undefined) {\n return options.apiSurface;\n }\n return options.baseURL ? 'chat-completions' : 'responses';\n}\n\nfunction getOpenAIUnsupportedNativeWebReason(\n apiSurface: TOpenAIApiSurface,\n toolKind: 'search' | 'fetch',\n): string {\n if (apiSurface === 'chat-completions') {\n return `OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${toolKind}.`;\n }\n return `OpenAI Responses native web ${toolKind} is not wired in this Robota provider version.`;\n}\n\nfunction validateOpenAIProviderNativeWebTools(\n apiSurface: TOpenAIApiSurface,\n nativeWebTools: IOpenAIProviderOptions['nativeWebTools'],\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n throw new Error(\n `Provider openai native web search/fetch is not supported for apiSurface ${apiSurface} in this Robota provider version.`,\n );\n}\n","import OpenAI from 'openai';\nimport type { TUniversalMessage, IAssistantMessage } from '@robota-sdk/agent-core';\n\n/**\n * OpenAI Conversation Adapter\n *\n * Converts between TUniversalMessage format and OpenAI native types.\n * Provides bidirectional conversion for seamless integration.\n *\n * @public\n */\nexport class OpenAIConversationAdapter {\n /**\n * Filter messages for OpenAI compatibility\n *\n * OpenAI has specific requirements:\n * - Tool messages must have valid toolCallId\n * - Messages must be in proper sequence\n * - Tool messages without toolCallId should be excluded\n */\n static filterMessagesForOpenAI(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages.filter((msg) => {\n // Always include user, assistant, and system messages\n if (msg.role === 'user' || msg.role === 'assistant' || msg.role === 'system') {\n return true;\n }\n\n // For tool messages, only include if they have a valid toolCallId\n if (msg.role === 'tool') {\n // Must have toolCallId and it must not be empty or 'unknown'\n return !!(msg.toolCallId && msg.toolCallId.trim() !== '' && msg.toolCallId !== 'unknown');\n }\n\n return false;\n });\n }\n\n /**\n * Convert TUniversalMessage array to OpenAI message format\n * Now properly handles tool messages for OpenAI's tool calling feature\n */\n static toOpenAIFormat(messages: TUniversalMessage[]): OpenAI.Chat.ChatCompletionMessageParam[] {\n // First filter messages for OpenAI compatibility\n const filteredMessages = this.filterMessagesForOpenAI(messages);\n return filteredMessages.map((msg) => this.convertMessage(msg));\n }\n\n /**\n * Convert a single TUniversalMessage to OpenAI format\n * Handles all message types including tool messages\n */\n static convertMessage(msg: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n const messageRole = msg.role;\n\n if (messageRole === 'user') {\n return {\n role: 'user',\n content: msg.content,\n };\n }\n\n if (messageRole === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Handle tool_calls format\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const result: OpenAI.Chat.ChatCompletionAssistantMessageParam = {\n role: 'assistant',\n // CRITICAL: OpenAI API requires content to be null (not empty string) when tool_calls are present\n // VERIFIED: 2024-12 - This prevents \"400 Bad Request\" errors from OpenAI API\n // DO NOT CHANGE without testing against actual OpenAI API\n content: assistantMsg.content === '' ? null : assistantMsg.content || null,\n tool_calls: assistantMsg.toolCalls.map((toolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n return result;\n }\n\n // Regular assistant message (without tool calls)\n // VERIFIED: OpenAI accepts both null and string content for regular messages\n // We preserve null when content is null or empty string for API consistency\n return {\n role: 'assistant',\n content:\n assistantMsg.content === null\n ? null\n : assistantMsg.content === ''\n ? null\n : assistantMsg.content || '',\n };\n }\n\n if (messageRole === 'system') {\n return {\n role: 'system',\n content: msg.content,\n };\n }\n\n // Handle tool messages for OpenAI tool calling\n if (messageRole === 'tool') {\n if (!msg.toolCallId || msg.toolCallId.trim() === '') {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(msg)}`);\n }\n\n const result: OpenAI.Chat.ChatCompletionToolMessageParam = {\n role: 'tool',\n content: msg.content,\n tool_call_id: msg.toolCallId,\n };\n return result;\n }\n\n const exhaustive: never = messageRole;\n throw new Error(`Unsupported message role: ${exhaustive}`);\n }\n\n /**\n * Add system prompt to message array if needed\n */\n static addSystemPromptIfNeeded(\n messages: OpenAI.Chat.ChatCompletionMessageParam[],\n systemPrompt?: string,\n ): OpenAI.Chat.ChatCompletionMessageParam[] {\n if (!systemPrompt) {\n return messages;\n }\n\n // Check if system message already exists\n const hasSystemMessage = messages.some((msg) => msg.role === 'system');\n\n if (hasSystemMessage) {\n return messages;\n }\n\n // Add system prompt at the beginning\n return [{ role: 'system', content: systemPrompt }, ...messages];\n }\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nconst OPENAI_MODELS_ENDPOINT = 'https://api.openai.com/v1/models';\nconst OPENAI_MODELS_SOURCE_URL = 'https://platform.openai.com/docs/api-reference/models/list';\n\nexport interface IOpenAIModelCatalogResponse {\n data?: readonly IOpenAIModelCatalogResource[];\n}\n\nexport interface IOpenAIModelCatalogResource {\n id?: string;\n}\n\nexport interface IOpenAIModelCatalogFetchInit {\n headers: Record<string, string>;\n}\n\nexport interface IOpenAIModelCatalogFetchResponse {\n ok: boolean;\n status: number;\n statusText?: string;\n json: () => Promise<IOpenAIModelCatalogResponse>;\n}\n\nexport type TOpenAIModelCatalogFetch = (\n url: string,\n init: IOpenAIModelCatalogFetchInit,\n) => Promise<IOpenAIModelCatalogFetchResponse>;\n\nexport interface IRefreshOpenAIModelCatalogOptions {\n fetcher?: TOpenAIModelCatalogFetch;\n now?: () => Date;\n}\n\nexport async function refreshOpenAIModelCatalog(\n profile: IProviderProfileConfig,\n options: IRefreshOpenAIModelCatalogOptions = {},\n): Promise<IProviderModelCatalog> {\n if (!profile.apiKey) {\n return createUnavailableCatalog('OpenAI model catalog refresh requires apiKey.');\n }\n\n const fetcher = options.fetcher ?? defaultOpenAIModelCatalogFetch;\n const now = options.now ?? (() => new Date());\n const url = resolveModelsEndpoint(profile.baseURL);\n\n try {\n const response = await fetcher(url, {\n headers: { Authorization: `Bearer ${profile.apiKey}` },\n });\n if (!response.ok) {\n return createUnavailableCatalog(formatHttpFailure(response));\n }\n\n const body = await response.json();\n const entries = toModelCatalogEntries(body);\n return {\n status: 'live',\n entries,\n lastVerifiedAt: now().toISOString(),\n sourceUrl: OPENAI_MODELS_SOURCE_URL,\n message: `${entries.length} OpenAI model(s) discovered.`,\n };\n } catch (error) {\n return createUnavailableCatalog(error instanceof Error ? error.message : String(error));\n }\n}\n\nfunction resolveModelsEndpoint(baseURL: string | undefined): string {\n if (!baseURL) return OPENAI_MODELS_ENDPOINT;\n return `${baseURL.replace(/\\/$/, '')}/models`;\n}\n\nfunction toModelCatalogEntries(\n body: IOpenAIModelCatalogResponse,\n): readonly IProviderModelCatalogEntry[] {\n return (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => id !== undefined && id.trim().length > 0)\n .map((id) => ({\n id,\n displayName: id,\n lifecycle: 'active',\n }));\n}\n\nfunction formatHttpFailure(response: IOpenAIModelCatalogFetchResponse): string {\n const statusText = response.statusText ? ` ${response.statusText}` : '';\n return `OpenAI model catalog refresh failed: HTTP ${response.status}${statusText}`;\n}\n\nfunction createUnavailableCatalog(message: string): IProviderModelCatalog {\n return {\n status: 'unavailable',\n sourceUrl: OPENAI_MODELS_SOURCE_URL,\n message,\n };\n}\n\nasync function defaultOpenAIModelCatalogFetch(\n url: string,\n init: IOpenAIModelCatalogFetchInit,\n): Promise<IOpenAIModelCatalogFetchResponse> {\n const response = await fetch(url, init);\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n json: () => response.json() as Promise<IOpenAIModelCatalogResponse>,\n };\n}\n","import type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\nimport { refreshOpenAIModelCatalog } from './model-catalog-refresh';\nimport { OpenAIProvider } from './provider';\nimport type { IOpenAINativeWebToolsOptions, TOpenAIApiSurface } from './types';\n\nexport const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined = undefined;\nexport const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = '$ENV:OPENAI_API_KEY';\nconst OPENAI_API_KEY_URL = 'https://platform.openai.com/api-keys';\nconst OPENAI_SETUP_SOURCE_URL =\n 'https://developers.openai.com/api/reference/overview#authentication';\nconst OPENAI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst OPENAI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'OpenAI API keys',\n url: OPENAI_API_KEY_URL,\n sourceUrl: OPENAI_SETUP_SOURCE_URL,\n lastVerifiedAt: OPENAI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createOpenAIProviderDefinition(): IProviderDefinition {\n return {\n type: 'openai',\n displayName: 'OpenAI',\n description: 'Official OpenAI Responses API provider',\n defaults: {\n apiKey: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'unavailable',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n message: 'OpenAI model availability should be discovered live from GET /v1/models.',\n },\n setupHelpLinks: OPENAI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'OpenAI model',\n required: true,\n },\n {\n key: 'apiKey',\n title: 'OpenAI API key',\n defaultValue: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n refreshModelCatalog: ({ profile }) => refreshOpenAIModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) => {\n const apiSurface = readApiSurface(config.options);\n const nativeWebTools = readNativeWebTools(config.options);\n validateOpenAINativeWebTools(config.baseURL, apiSurface, nativeWebTools);\n return new OpenAIProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(apiSurface !== undefined && { apiSurface }),\n ...(nativeWebTools !== undefined && { nativeWebTools }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider openai requires apiKey');\n }\n return apiKey;\n}\n\nfunction readApiSurface(\n options: Record<string, TUniversalValue> | undefined,\n): TOpenAIApiSurface | undefined {\n const apiSurface = options?.['apiSurface'];\n if (apiSurface === 'responses' || apiSurface === 'chat-completions') {\n return apiSurface;\n }\n return undefined;\n}\n\nfunction readNativeWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n const nativeWebTools =\n readNativeWebToolsRecord(options?.['nativeWebTools']) ??\n readNativeWebToolsRecord(options?.['builtInWebTools']);\n if (nativeWebTools === undefined) {\n return undefined;\n }\n return nativeWebTools;\n}\n\nfunction readNativeWebToolsRecord(\n value: TUniversalValue | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n if (typeof value !== 'object') {\n return undefined;\n }\n const webSearch = value['webSearch'];\n const webFetch = value['webFetch'];\n return {\n ...(typeof webSearch === 'boolean' && { webSearch }),\n ...(typeof webFetch === 'boolean' && { webFetch }),\n };\n}\n\nfunction validateOpenAINativeWebTools(\n baseURL: string | undefined,\n apiSurface: TOpenAIApiSurface | undefined,\n nativeWebTools: IOpenAINativeWebToolsOptions | undefined,\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n if (baseURL !== undefined || apiSurface === 'chat-completions') {\n throw new Error(\n 'Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n }\n throw new Error(\n 'Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n}\n","export const DEFAULT_DEEPSEEK_PROVIDER_MODEL = 'deepseek-v4-flash';\nexport const DEFAULT_DEEPSEEK_PROVIDER_API_KEY_ENV = 'DEEPSEEK_API_KEY';\nexport const DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_DEEPSEEK_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_DEEPSEEK_PROVIDER_BASE_URL = 'https://api.deepseek.com';\n","import OpenAI from 'openai';\nimport { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport type {\n IChatOptions,\n IProviderCapabilities,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n OpenAICompatibleResponseParser,\n} from '../shared/openai-compatible/index.js';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport { DEFAULT_DEEPSEEK_PROVIDER_BASE_URL } from './defaults';\nimport type {\n IDeepSeekProviderOptions,\n IDeepSeekThinkingConfig,\n TDeepSeekReasoningEffort,\n} from './types';\n\ntype TDeepSeekChatCompletionCreateParamsNonStreaming = Omit<\n OpenAI.Chat.ChatCompletionCreateParamsNonStreaming,\n 'reasoning_effort'\n> & {\n thinking?: IDeepSeekThinkingConfig;\n reasoning_effort?: TDeepSeekReasoningEffort;\n};\n\ntype TDeepSeekChatCompletionCreateParamsStreaming = Omit<\n OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n 'reasoning_effort'\n> & {\n thinking?: IDeepSeekThinkingConfig;\n reasoning_effort?: TDeepSeekReasoningEffort;\n};\n\nexport class DeepSeekProvider extends AbstractAIProvider {\n override readonly name = 'deepseek';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IDeepSeekProviderOptions;\n private readonly responseParser: OpenAICompatibleResponseParser;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IDeepSeekProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL ?? DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either DeepSeek client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAICompatibleResponseParser({ logger: this.logger });\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'DeepSeek Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n const client = this.getClient();\n\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return await this.chatWithStreamingAssembly(\n { ...requestParams, stream: true },\n { ...options, onTextDelta: textDeltaCb },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming,\n );\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return this.responseParser.parseResponse(response);\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek API request failed';\n throw new Error(`DeepSeek chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'DeepSeek Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n const client = this.getClient();\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n );\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n const universalMessage = this.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek API request failed';\n throw new Error(`DeepSeek stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'DeepSeek OpenAI-compatible Chat Completions supports declared function tools, not provider-native web search.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'DeepSeek OpenAI-compatible Chat Completions supports declared function tools, not provider-native web fetch.',\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible DeepSeek clients do not need explicit cleanup.\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): TDeepSeekChatCompletionCreateParamsNonStreaming {\n this.validateTools(options?.tools);\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n return {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n ...(this.options.thinking !== undefined && {\n thinking: { type: this.options.thinking },\n }),\n ...(this.options.reasoningEffort !== undefined && {\n reasoning_effort: this.options.reasoningEffort,\n }),\n };\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): TDeepSeekChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n };\n }\n\n private getClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'DeepSeek client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n return this.client;\n }\n\n private async chatWithStreamingAssembly(\n requestParams: TDeepSeekChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n ): Promise<TUniversalMessage> {\n const client = this.getClient();\n\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options.signal ? { signal: options.signal } : undefined,\n );\n\n return assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n });\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek streaming request failed';\n throw new Error(`DeepSeek stream failed: ${errorMessage}`);\n }\n }\n}\n","import type { IProviderModelCatalogEntry } from '@robota-sdk/agent-core';\nimport { DEFAULT_DEEPSEEK_PROVIDER_MODEL } from './defaults';\n\nexport const DEEPSEEK_MODEL_CATALOG_SOURCE_URL =\n 'https://api-docs.deepseek.com/quick_start/pricing';\nexport const DEEPSEEK_MODEL_LIST_SOURCE_URL = 'https://api-docs.deepseek.com/api/list-models';\nexport const DEEPSEEK_MODEL_LAST_VERIFIED_AT = '2026-05-07';\nexport const DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE = '2026-07-24';\n\nexport const DEEPSEEK_MODEL_CATALOG_ENTRIES: readonly IProviderModelCatalogEntry[] = [\n {\n id: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n displayName: 'DeepSeek V4 Flash',\n contextWindow: 1_000_000,\n capabilities: ['tools', 'reasoning', 'json_schema', 'streaming'],\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-v4-pro',\n displayName: 'DeepSeek V4 Pro',\n contextWindow: 1_000_000,\n capabilities: ['tools', 'reasoning', 'json_schema', 'streaming'],\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-chat',\n displayName: `DeepSeek Chat compatibility alias, deprecated ${DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE}`,\n aliases: [DEFAULT_DEEPSEEK_PROVIDER_MODEL],\n contextWindow: 1_000_000,\n capabilities: ['tools', 'json_schema', 'streaming'],\n lifecycle: 'deprecated',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-reasoner',\n displayName: `DeepSeek Reasoner compatibility alias, deprecated ${DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE}`,\n aliases: [DEFAULT_DEEPSEEK_PROVIDER_MODEL],\n contextWindow: 1_000_000,\n capabilities: ['reasoning', 'json_schema', 'streaming'],\n lifecycle: 'deprecated',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n];\n\nexport function getDeepSeekFallbackModelCatalogEntry(\n id: string,\n): IProviderModelCatalogEntry | undefined {\n return DEEPSEEK_MODEL_CATALOG_ENTRIES.find((entry) => entry.id === id);\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport { DEFAULT_DEEPSEEK_PROVIDER_BASE_URL } from './defaults';\nimport {\n DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n getDeepSeekFallbackModelCatalogEntry,\n} from './model-catalog';\n\nexport interface IDeepSeekModelsResponse {\n data?: Array<{\n id?: string;\n object?: string;\n owned_by?: string;\n }>;\n}\n\nexport interface IDeepSeekFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IDeepSeekFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IDeepSeekModelsResponse>;\n}\n\nexport type TDeepSeekFetch = (\n url: string,\n init?: IDeepSeekFetchInit,\n) => Promise<IDeepSeekFetchResponse>;\n\nexport async function refreshDeepSeekModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TDeepSeekFetch = defaultDeepSeekFetch,\n): Promise<IProviderModelCatalog> {\n const baseURL = trimTrailingSlash(profile.baseURL ?? DEFAULT_DEEPSEEK_PROVIDER_BASE_URL);\n const url = `${baseURL}/models`;\n const response = await fetcher(url, buildFetchInit(profile.apiKey));\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n message: `DeepSeek model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n entries,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IDeepSeekFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n };\n}\n\nfunction toModelCatalogEntry(id: string): IProviderModelCatalogEntry {\n return (\n getDeepSeekFallbackModelCatalogEntry(id) ?? {\n id,\n displayName: id,\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n }\n );\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/, '');\n}\n\nasync function defaultDeepSeekFetch(\n url: string,\n init?: IDeepSeekFetchInit,\n): Promise<IDeepSeekFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IDeepSeekModelsResponse>,\n };\n}\n","import type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\nimport {\n DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n} from './defaults';\nimport {\n DEEPSEEK_MODEL_CATALOG_ENTRIES,\n DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n} from './model-catalog';\nimport { refreshDeepSeekModelCatalog } from './model-catalog-refresh';\nimport { DeepSeekProvider } from './provider';\nimport type { TDeepSeekReasoningEffort, TDeepSeekThinkingMode } from './types';\n\nconst DEEPSEEK_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n entries: DEEPSEEK_MODEL_CATALOG_ENTRIES,\n};\nconst DEEPSEEK_API_KEY_URL = 'https://platform.deepseek.com/api_keys';\nconst DEEPSEEK_SETUP_SOURCE_URL = 'https://api-docs.deepseek.com/';\nconst DEEPSEEK_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst DEEPSEEK_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'DeepSeek API keys',\n url: DEEPSEEK_API_KEY_URL,\n sourceUrl: DEEPSEEK_SETUP_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createDeepSeekProviderDefinition(): IProviderDefinition {\n return {\n type: 'deepseek',\n displayName: 'DeepSeek',\n description: 'DeepSeek OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n apiKey: DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n baseURL: DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n },\n modelCatalog: DEEPSEEK_MODEL_CATALOG,\n setupHelpLinks: DEEPSEEK_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'DeepSeek OpenAI-compatible base URL',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'DeepSeek model',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'DeepSeek API key',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n refreshModelCatalog: ({ profile }) => refreshDeepSeekModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) => {\n const options = parseDeepSeekProviderOptions(config.options);\n return new DeepSeekProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(options.thinking !== undefined && { thinking: options.thinking }),\n ...(options.reasoningEffort !== undefined && { reasoningEffort: options.reasoningEffort }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider deepseek requires apiKey');\n }\n return apiKey;\n}\n\nfunction parseDeepSeekProviderOptions(options: Record<string, TUniversalValue> | undefined): {\n thinking?: TDeepSeekThinkingMode;\n reasoningEffort?: TDeepSeekReasoningEffort;\n} {\n const thinking = parseThinkingMode(options?.['thinking']);\n const reasoningEffort = parseReasoningEffort(options?.['reasoningEffort']);\n return {\n ...(thinking !== undefined && { thinking }),\n ...(reasoningEffort !== undefined && { reasoningEffort }),\n };\n}\n\nfunction parseThinkingMode(value: TUniversalValue | undefined): TDeepSeekThinkingMode | undefined {\n if (value === true) return 'enabled';\n if (value === false) return 'disabled';\n if (value === 'enabled' || value === 'disabled') return value;\n const record = asRecord(value);\n const type = record?.['type'];\n return type === 'enabled' || type === 'disabled' ? type : undefined;\n}\n\nfunction parseReasoningEffort(\n value: TUniversalValue | undefined,\n): TDeepSeekReasoningEffort | undefined {\n if (\n value === 'low' ||\n value === 'medium' ||\n value === 'high' ||\n value === 'xhigh' ||\n value === 'max'\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction asRecord(value: TUniversalValue | undefined): Record<string, TUniversalValue> | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n return typeof value === 'object' ? value : undefined;\n}\n","import type {\n TUniversalMessage,\n TUniversalMessagePart,\n IMediaOutputRef,\n IImageEditRequest,\n IImageComposeRequest,\n TProviderMediaResult,\n IChatOptions,\n} from '@robota-sdk/agent-core';\nimport type { GenerateContentParameters } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\n\n/** Checks whether the given parts contain an image part. */\nexport function hasImagePart(parts: TUniversalMessagePart[] | undefined): boolean {\n if (!parts) {\n return false;\n }\n return parts.some((part) => part.type === 'image_inline' || part.type === 'image_uri');\n}\n\n/** Extracts inline image parts from a message and converts them to media output references. */\nexport function mapInlineImagePartsToMediaOutputs(\n parts: TUniversalMessagePart[] | undefined,\n): IMediaOutputRef[] {\n if (!parts) {\n return [];\n }\n const outputs: IMediaOutputRef[] = [];\n for (const part of parts) {\n if (part.type !== 'image_inline') {\n continue;\n }\n outputs.push({\n kind: 'uri',\n uri: `data:${part.mimeType};base64,${part.data}`,\n mimeType: part.mimeType,\n });\n }\n return outputs;\n}\n\n/** Parses a data URI into its MIME type and base64 payload. */\nexport function parseDataUri(uri: string): { mimeType: string; data: string } | undefined {\n const commaIndex = uri.indexOf(',');\n if (commaIndex < 0) {\n return undefined;\n }\n const header = uri.slice(0, commaIndex);\n const payload = uri.slice(commaIndex + 1);\n if (!header.endsWith(';base64')) {\n return undefined;\n }\n const mimeType = header.replace('data:', '').replace(';base64', '').trim();\n if (mimeType.length === 0 || payload.trim().length === 0) {\n return undefined;\n }\n return {\n mimeType,\n data: payload,\n };\n}\n\n/** Maps an image input source (inline or URI) to a universal message part. */\nexport function mapImageInputSourceToPart(\n source: IImageEditRequest['image'] | IImageComposeRequest['images'][number],\n): TProviderMediaResult<TUniversalMessagePart> {\n if (source.kind === 'inline') {\n if (source.mimeType.trim().length === 0 || source.data.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Inline image source requires non-empty mimeType and data.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: source.mimeType,\n data: source.data,\n },\n };\n }\n if (!source.uri.startsWith('data:')) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Google image provider supports only inline or data URI input sources.',\n },\n };\n }\n const parsedResult = parseDataUri(source.uri);\n if (!parsedResult) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Data URI source must use base64 payload.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: parsedResult.mimeType,\n data: parsedResult.data,\n },\n };\n}\n\n/** Determines which response modalities to request from the Gemini API. */\nexport function buildResponseModalities(\n messages: TUniversalMessage[],\n defaultModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n optionModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n): Array<'TEXT' | 'IMAGE'> {\n if (optionModalities && optionModalities.length > 0) {\n return optionModalities;\n }\n const hasImageInput = messages.some((message) => hasImagePart(message.parts));\n if (hasImageInput) {\n return ['TEXT', 'IMAGE'];\n }\n if (defaultModalities && defaultModalities.length > 0) {\n return defaultModalities;\n }\n return ['TEXT'];\n}\n\n/** Checks whether the specified model is configured as image-capable. */\nexport function isImageCapableModel(\n model: string,\n configuredImageModels: string[] | undefined,\n): boolean {\n if (!configuredImageModels || configuredImageModels.length === 0) {\n return true;\n }\n return configuredImageModels.includes(model);\n}\n\n/** Builds the Gemini generation config including response modalities. */\nexport function buildGenerationConfig(\n messages: TUniversalMessage[],\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): NonNullable<GenerateContentParameters['config']> {\n assertCompatibleStructuredOutputOptions(providerOptions);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n validateImageCapableModel(options?.model, responseModalities, providerOptions);\n const config: NonNullable<GenerateContentParameters['config']> = { responseModalities };\n applyChatOptions(config, options);\n applySafetySettings(config, providerOptions, options);\n applyStructuredOutputOptions(config, providerOptions);\n applyProviderGenerationOptions(config, providerOptions);\n return config;\n}\n\nfunction validateImageCapableModel(\n model: string | undefined,\n responseModalities: Array<'TEXT' | 'IMAGE'>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (!model || !responseModalities.includes('IMAGE')) {\n return;\n }\n if (isImageCapableModel(model, providerOptions.imageCapableModels)) {\n return;\n }\n throw new Error(\n `Selected model \"${model}\" is not configured as image-capable for Google provider.`,\n );\n}\n\nfunction applyChatOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n options?: IChatOptions,\n): void {\n if (typeof options?.temperature === 'number') {\n config.temperature = options.temperature;\n }\n if (typeof options?.maxTokens === 'number') {\n config.maxOutputTokens = options.maxTokens;\n }\n if (typeof options?.google?.topP === 'number') {\n config.topP = options.google.topP;\n }\n if (typeof options?.google?.topK === 'number') {\n config.topK = options.google.topK;\n }\n if (typeof options?.google?.candidateCount === 'number') {\n config.candidateCount = options.google.candidateCount;\n }\n if (options?.google?.stopSequences && options.google.stopSequences.length > 0) {\n config.stopSequences = options.google.stopSequences;\n }\n if (options?.signal) {\n config.abortSignal = options.signal;\n }\n}\n\nfunction applySafetySettings(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): void {\n const safetySettings = options?.google?.safetySettings ?? providerOptions.safetySettings;\n if (safetySettings && safetySettings.length > 0) {\n config.safetySettings = safetySettings as NonNullable<\n GenerateContentParameters['config']\n >['safetySettings'];\n }\n}\n\nfunction applyStructuredOutputOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.responseMimeType) {\n config.responseMimeType = providerOptions.responseMimeType;\n }\n if (providerOptions.responseSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseSchema = providerOptions.responseSchema;\n }\n if (providerOptions.responseJsonSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseJsonSchema = providerOptions.responseJsonSchema;\n }\n}\n\nfunction applyProviderGenerationOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.thinkingConfig) {\n config.thinkingConfig = providerOptions.thinkingConfig as NonNullable<\n GenerateContentParameters['config']\n >['thinkingConfig'];\n }\n if (providerOptions.toolConfig) {\n config.toolConfig = providerOptions.toolConfig as NonNullable<\n GenerateContentParameters['config']\n >['toolConfig'];\n }\n}\n\nfunction assertCompatibleStructuredOutputOptions(providerOptions: IGeminiProviderOptions): void {\n if (providerOptions.responseSchema && providerOptions.responseJsonSchema) {\n throw new Error(\n 'Gemini structured output options responseSchema and responseJsonSchema are mutually exclusive.',\n );\n }\n}\n","import type { Content, Part } from '@google/genai';\nimport type {\n IAssistantMessage,\n ISystemMessage,\n IToolMessage,\n IUserMessage,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\ntype TGoogleJsonValue = string | number | boolean | null | TGoogleJsonValue[] | IGoogleJsonObject;\n\ninterface IGoogleJsonObject {\n readonly [key: string]: TGoogleJsonValue;\n}\n\nexport interface IGeminiMessageConversionResult {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/**\n * Maps universal message parts to Gemini-compatible parts.\n * Supports text and inline image parts; throws on unsupported part types.\n */\nexport function mapMessagePartsToGeminiParts(\n message: IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage,\n): Part[] {\n const parts: Part[] = [];\n const messageParts = message.parts ?? [];\n for (const part of messageParts) {\n if (part.type === 'text') {\n parts.push({ text: part.text });\n continue;\n }\n if (part.type === 'image_inline') {\n parts.push({\n inlineData: {\n mimeType: part.mimeType,\n data: part.data,\n },\n });\n continue;\n }\n throw new Error(`Google provider does not support image URI parts directly: ${part.uri}`);\n }\n if (parts.length === 0 && typeof message.content === 'string' && message.content.length > 0) {\n parts.push({ text: message.content });\n }\n return parts;\n}\n\n/**\n * Converts an array of universal messages to the Gemini Content format.\n *\n * IMPORTANT: Google Gemini allows content with function calls.\n * Content can be empty string or text, but NOT null.\n */\nexport function convertToGeminiFormat(messages: TUniversalMessage[]): Content[] {\n return convertToGeminiRequestFormat(messages).contents;\n}\n\n/**\n * Converts universal messages into Gemini request content plus request config\n * fields. Gemini system instructions are request-level config, not user turns.\n */\nexport function convertToGeminiRequestFormat(\n messages: TUniversalMessage[],\n): IGeminiMessageConversionResult {\n const contents: Content[] = [];\n const systemInstructionParts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n contents.push({\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n });\n continue;\n }\n if (msg.role === 'assistant') {\n contents.push(convertAssistantMessage(msg as IAssistantMessage));\n continue;\n }\n if (msg.role === 'tool') {\n contents.push(convertToolMessage(msg as IToolMessage));\n continue;\n }\n\n const systemInstruction = extractSystemInstructionText(msg as ISystemMessage);\n if (systemInstruction.length > 0) {\n systemInstructionParts.push(systemInstruction);\n }\n }\n\n return {\n contents,\n ...(systemInstructionParts.length > 0 && {\n systemInstruction: systemInstructionParts.join('\\n'),\n }),\n };\n}\n\n/**\n * Converts all messages to Gemini contents, including system instructions as\n * user content. This exists only for compatibility with callers that still need\n * a contents-only value.\n */\nexport function convertToGeminiFormatWithInlineSystem(messages: TUniversalMessage[]): Content[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n };\n }\n if (msg.role === 'assistant') {\n return convertAssistantMessage(msg as IAssistantMessage);\n }\n if (msg.role === 'tool') {\n const toolMessage = msg as IToolMessage;\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(toolMessage),\n };\n }\n const systemMessage = msg as ISystemMessage;\n const systemParts = mapMessagePartsToGeminiParts(systemMessage);\n if (systemParts.length === 0) {\n systemParts.push({ text: `System: ${systemMessage.content || ''}` });\n }\n return {\n role: 'user',\n parts: systemParts,\n };\n });\n}\n\nfunction convertAssistantMessage(assistantMsg: IAssistantMessage): Content {\n const parts: Part[] = [];\n const mappedAssistantParts = mapMessagePartsToGeminiParts(assistantMsg);\n for (const mappedPart of mappedAssistantParts) {\n parts.push(mappedPart);\n }\n if (parts.length === 0 && assistantMsg.content) {\n parts.push({ text: assistantMsg.content });\n }\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n assistantMsg.toolCalls.forEach((tc) => {\n parts.push({\n functionCall: {\n id: tc.id,\n name: tc.function.name,\n args: parseToolCallArguments(tc.function.arguments),\n },\n });\n });\n }\n return {\n role: 'model',\n parts,\n };\n}\n\nfunction convertToolMessage(toolMessage: IToolMessage): Content {\n const functionResponse = {\n id: toolMessage.toolCallId,\n name: requireToolMessageName(toolMessage),\n response: parseToolResponseContent(toolMessage.content),\n };\n return {\n role: 'user',\n parts: [{ functionResponse }],\n };\n}\n\nfunction extractSystemInstructionText(systemMessage: ISystemMessage): string {\n const parts = mapMessagePartsToGeminiParts(systemMessage);\n if (parts.length === 0) {\n return systemMessage.content;\n }\n const textParts: string[] = [];\n for (const part of parts) {\n if (typeof part.text === 'string') {\n textParts.push(part.text);\n continue;\n }\n throw new Error('Google provider system instructions support only text parts.');\n }\n return textParts.join('\\n');\n}\n\nfunction requireToolMessageName(toolMessage: IToolMessage): string {\n const toolName = toolMessage.name?.trim();\n if (!toolName) {\n throw new Error('Google provider tool message requires a function name.');\n }\n return toolName;\n}\n\nfunction parseToolCallArguments(serializedArguments: string): IGoogleJsonObject {\n const parsedArguments = JSON.parse(serializedArguments) as TGoogleJsonValue;\n if (!isJsonObject(parsedArguments)) {\n throw new Error('Google provider tool call arguments must be a JSON object.');\n }\n return parsedArguments;\n}\n\nfunction parseToolResponseContent(content: string): IGoogleJsonObject {\n const trimmedContent = content.trim();\n if (trimmedContent.length === 0) {\n return { output: null };\n }\n try {\n const parsedContent = JSON.parse(trimmedContent) as TGoogleJsonValue;\n if (isJsonObject(parsedContent)) {\n return parsedContent;\n }\n return { output: parsedContent };\n } catch {\n return { output: content };\n }\n}\n\nfunction isJsonObject(value: TGoogleJsonValue): value is IGoogleJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { Type } from '@google/genai';\nimport type { FunctionDeclaration, Schema } from '@google/genai';\nimport type { IParameterSchema, IToolSchema, TJSONSchemaKind } from '@robota-sdk/agent-core';\n\nconst GOOGLE_SCHEMA_TYPE_BY_JSON_KIND: Record<Exclude<TJSONSchemaKind, 'null'>, Type> = {\n string: Type.STRING,\n number: Type.NUMBER,\n integer: Type.INTEGER,\n boolean: Type.BOOLEAN,\n array: Type.ARRAY,\n object: Type.OBJECT,\n};\n\n/** Converts Robota tool schemas to Gemini function declarations. */\nexport function convertToolsToGeminiFormat(tools: IToolSchema[]): FunctionDeclaration[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: {\n type: Type.OBJECT,\n properties: convertParameterProperties(tool.parameters.properties),\n required: tool.parameters.required,\n },\n }));\n}\n\nfunction convertParameterProperties(\n properties: Record<string, IParameterSchema>,\n): Record<string, Schema> {\n const convertedProperties: Record<string, Schema> = {};\n for (const [key, value] of Object.entries(properties)) {\n convertedProperties[key] = convertParameterSchema(value);\n }\n return convertedProperties;\n}\n\nfunction convertParameterSchema(schema: IParameterSchema): Schema {\n const convertedSchema: Schema = {};\n const schemaType = convertSchemaKind(schema.type);\n if (schemaType) {\n convertedSchema.type = schemaType;\n }\n if (schema.description) {\n convertedSchema.description = schema.description;\n }\n if (schema.enum) {\n convertedSchema.enum = schema.enum.map(String);\n }\n if (schema.items) {\n convertedSchema.items = convertParameterSchema(schema.items);\n }\n if (schema.properties) {\n convertedSchema.properties = convertParameterProperties(schema.properties);\n }\n if (typeof schema.minimum === 'number') {\n convertedSchema.minimum = schema.minimum;\n }\n if (typeof schema.maximum === 'number') {\n convertedSchema.maximum = schema.maximum;\n }\n if (schema.pattern) {\n convertedSchema.pattern = schema.pattern;\n }\n if (schema.format) {\n convertedSchema.format = schema.format;\n }\n if (schema.default !== undefined) {\n convertedSchema.default = schema.default;\n }\n return convertedSchema;\n}\n\nfunction convertSchemaKind(kind: TJSONSchemaKind): Type | undefined {\n if (kind === 'null') {\n return undefined;\n }\n return GOOGLE_SCHEMA_TYPE_BY_JSON_KIND[kind];\n}\n","import { randomUUID } from 'node:crypto';\nimport type { Part, FunctionCall, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IAssistantMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nconst RANDOM_ID_RADIX = 36;\nconst RANDOM_ID_LENGTH = 9;\n\ninterface ICollectedGeminiParts {\n textValues: string[];\n messageParts: TUniversalMessagePart[];\n functionCalls: FunctionCall[];\n}\n\nexport {\n convertToGeminiFormat,\n convertToGeminiFormatWithInlineSystem,\n convertToGeminiRequestFormat,\n mapMessagePartsToGeminiParts,\n} from './request-converter';\nexport type { IGeminiMessageConversionResult } from './request-converter';\n\n/** Generates a unique call identifier for function call responses. */\nexport function generateCallId(): string {\n return `call_${Date.now()}_${Math.random().toString(RANDOM_ID_RADIX).substr(2, RANDOM_ID_LENGTH)}`;\n}\n\n/** Converts a Gemini API response into a universal message. */\nexport function convertFromGeminiResponse(response: GenerateContentResponse): TUniversalMessage {\n const candidate = response.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidate in Gemini response');\n }\n\n const content = candidate.content;\n if (!content || !content.parts || content.parts.length === 0) {\n throw new Error('No content in Gemini response');\n }\n\n const collectedParts = collectGeminiParts(content.parts);\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n state: 'complete' as const,\n role: 'assistant',\n content: collectedParts.textValues.length > 0 ? collectedParts.textValues.join('') : null,\n parts: collectedParts.messageParts,\n timestamp: new Date(),\n };\n\n if (collectedParts.functionCalls.length > 0) {\n const assistantResult = result as IAssistantMessage;\n assistantResult.toolCalls = collectedParts.functionCalls.map((fc) => ({\n id: fc.id ?? generateCallId(),\n type: 'function' as const,\n function: {\n name: requireFunctionCallName(fc),\n arguments: JSON.stringify(fc.args ?? {}),\n },\n }));\n }\n\n const usageMetadata = mapUsageMetadata(response);\n if (usageMetadata) {\n result.metadata = usageMetadata;\n }\n\n return result;\n}\n\nfunction collectGeminiParts(parts: Part[]): ICollectedGeminiParts {\n const textValues: string[] = [];\n const messageParts: TUniversalMessagePart[] = [];\n const functionCalls: FunctionCall[] = [];\n\n for (const part of parts) {\n collectTextPart(part, textValues, messageParts);\n collectInlineImagePart(part, messageParts);\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n\n return { textValues, messageParts, functionCalls };\n}\n\nfunction collectTextPart(\n part: Part,\n textValues: string[],\n messageParts: TUniversalMessagePart[],\n): void {\n if (typeof part.text !== 'string') {\n return;\n }\n textValues.push(part.text);\n messageParts.push({ type: 'text', text: part.text });\n}\n\nfunction collectInlineImagePart(part: Part, messageParts: TUniversalMessagePart[]): void {\n if (\n !part.inlineData ||\n typeof part.inlineData.data !== 'string' ||\n typeof part.inlineData.mimeType !== 'string'\n ) {\n return;\n }\n messageParts.push({\n type: 'image_inline',\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n });\n}\n\nfunction mapUsageMetadata(response: GenerateContentResponse): TUniversalMessage['metadata'] {\n if (\n !response.usageMetadata ||\n typeof response.usageMetadata.promptTokenCount !== 'number' ||\n typeof response.usageMetadata.candidatesTokenCount !== 'number' ||\n typeof response.usageMetadata.totalTokenCount !== 'number'\n ) {\n return undefined;\n }\n return {\n promptTokens: response.usageMetadata.promptTokenCount,\n completionTokens: response.usageMetadata.candidatesTokenCount,\n totalTokens: response.usageMetadata.totalTokenCount,\n };\n}\n\nexport { convertToolsToGeminiFormat } from './tool-schema-converter';\n\nfunction requireFunctionCallName(functionCall: FunctionCall): string {\n if (!functionCall.name || functionCall.name.trim().length === 0) {\n throw new Error('Gemini function call is missing a function name.');\n }\n return functionCall.name;\n}\n","import { randomUUID } from 'node:crypto';\nimport type { GoogleGenAI } from '@google/genai';\nimport type { Content, GenerateContentParameters, GenerateContentResponse } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\nimport {\n convertToGeminiRequestFormat,\n convertFromGeminiResponse,\n convertToolsToGeminiFormat,\n} from './message-converter';\nimport {\n hasImagePart,\n mapInlineImagePartsToMediaOutputs,\n buildResponseModalities,\n buildGenerationConfig,\n} from './image-operations';\n\n/**\n * Execute a direct (non-streaming) chat request against the Gemini API.\n */\nexport async function executeDirect(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n\n if (options?.onTextDelta && !responseModalities.includes('IMAGE')) {\n return assembleStreamingChatResponse(client, providerOptions, messages, options, providerName);\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const result = await client.models.generateContent(request);\n emitGeminiNativeRawPayload(options, providerName, 'response', result);\n\n const convertedResponse = convertFromGeminiResponse(result);\n if (responseModalities.includes('IMAGE') && !hasImagePart(convertedResponse.parts)) {\n throw new Error(\n 'Gemini response did not include an image part while IMAGE modality was requested.',\n );\n }\n return convertedResponse;\n}\n\n/**\n * Execute a streaming chat request against the Gemini API.\n */\nexport async function* executeDirectStream(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): AsyncIterable<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n if (responseModalities.includes('IMAGE')) {\n throw new Error('Google provider does not support streaming image modality responses.');\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const stream = await client.models.generateContentStream(request);\n\n let sequence = 0;\n for await (const chunk of stream) {\n emitGeminiNativeRawPayload(options, providerName, 'stream_event', chunk, sequence);\n sequence++;\n const text = extractStreamText(chunk);\n if (text) {\n options?.onTextDelta?.(text);\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n}\n\nfunction buildGenerateContentRequest(\n model: string,\n contents: Content[],\n generationOptions: GenerateContentParameters['config'],\n options?: IChatOptions,\n systemInstruction?: string,\n): GenerateContentParameters {\n const config: GenerateContentParameters['config'] = { ...generationOptions };\n if (options?.tools && options.tools.length > 0) {\n config.tools = [{ functionDeclarations: convertToolsToGeminiFormat(options.tools) }];\n }\n if (systemInstruction) {\n config.systemInstruction = systemInstruction;\n }\n return {\n model,\n contents,\n config,\n };\n}\n\nfunction resolveGeminiModel(\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): string {\n const model = options?.model ?? providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n return model;\n}\n\nasync function assembleStreamingChatResponse(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const textParts: string[] = [];\n for await (const chunk of executeDirectStream(\n client,\n providerOptions,\n messages,\n options,\n providerName,\n )) {\n if (typeof chunk.content === 'string') {\n textParts.push(chunk.content);\n }\n }\n const content = textParts.join('');\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n parts: content.length > 0 ? [{ type: 'text', text: content }] : [],\n state: 'complete',\n timestamp: new Date(),\n };\n}\n\nfunction emitGeminiNativeRawPayload(\n options: IChatOptions | undefined,\n providerName: string,\n payloadKind: 'request' | 'response' | 'stream_event',\n payload: object,\n sequence?: number,\n): void {\n options?.onProviderNativeRawPayload?.({\n provider: providerName,\n apiSurface: 'gemini-generate-content',\n payloadKind,\n ...(sequence !== undefined && { sequence }),\n payload,\n });\n}\n\nfunction extractStreamText(\n chunk: GenerateContentResponse | { readonly text?: () => string },\n): string | undefined {\n const textValue = chunk.text;\n return typeof textValue === 'function' ? textValue() : textValue;\n}\n\n/**\n * Run an image generation request through the chat API.\n */\nexport async function runImageRequest(\n chatFn: (messages: TUniversalMessage[], options?: IChatOptions) => Promise<TUniversalMessage>,\n messages: TUniversalMessage[],\n model: string,\n): Promise<TProviderMediaResult<IImageGenerationResult>> {\n try {\n const response = await chatFn(messages, {\n model,\n google: { responseModalities: ['TEXT', 'IMAGE'] },\n });\n const outputs = mapInlineImagePartsToMediaOutputs(response.parts);\n if (outputs.length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Google image response did not include image output parts.',\n },\n };\n }\n return { ok: true, value: { outputs, model } };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google image request failed.';\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message: errorMessage } };\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { GoogleGenAI } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\nimport { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport type {\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n TUniversalMessagePart,\n IImageGenerationProvider,\n IImageGenerationRequest,\n IImageEditRequest,\n IImageComposeRequest,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\nimport { mapImageInputSourceToPart } from './image-operations';\nimport { executeDirect, executeDirectStream, runImageRequest } from './execution-helpers';\n\n/**\n * Gemini provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Google Gemini API:\n * - Function calls can have content (text) along with function calls\n * - Content can be empty string or actual text, NOT null\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class GeminiProvider extends AbstractAIProvider implements IImageGenerationProvider {\n override readonly name: string = 'gemini';\n override readonly version = '1.0.0';\n public onTextDelta?: TTextDeltaCallback;\n\n private readonly client?: GoogleGenAI;\n private readonly options: IGeminiProviderOptions;\n\n constructor(options: IGeminiProviderOptions) {\n super();\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n this.client = new GoogleGenAI({ apiKey: options.apiKey });\n }\n }\n\n /** Generate response using TUniversalMessage */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n return await executeDirect(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google chat failed: ${errorMessage}`);\n }\n }\n\n /** Generate streaming response using TUniversalMessage */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n yield* executeDirectStream(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google stream failed: ${errorMessage}`);\n }\n }\n\n /** Generate an image from a text prompt using the Gemini API. */\n public async generateImage(\n request: IImageGenerationRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty model.',\n },\n };\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [{ type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Edit an existing image based on a text prompt using the Gemini API. */\n public async editImage(\n request: IImageEditRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty model.',\n },\n };\n }\n\n const inputPartResult = mapImageInputSourceToPart(request.image);\n if (!inputPartResult.ok) {\n return inputPartResult;\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [inputPartResult.value, { type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Compose multiple images together based on a text prompt using the Gemini API. */\n public async composeImage(\n request: IImageComposeRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty model.',\n },\n };\n }\n if (request.images.length < 2) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires at least two input images.',\n },\n };\n }\n\n const messageParts: TUniversalMessagePart[] = [];\n for (const imageSource of request.images) {\n const mappedPartResult = mapImageInputSourceToPart(imageSource);\n if (!mappedPartResult.ok) {\n return mappedPartResult;\n }\n messageParts.push(mappedPartResult.value);\n }\n messageParts.push({ type: 'text', text: request.prompt });\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: messageParts,\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override validateConfig(): boolean {\n if (this.executor) {\n return this.executor.validateConfig();\n }\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Google client does not need explicit cleanup\n }\n\n private withProviderCallbacks(options?: IChatOptions): IChatOptions | undefined {\n const onTextDelta = options?.onTextDelta ?? this.onTextDelta;\n if (!onTextDelta) {\n return options;\n }\n return {\n ...options,\n onTextDelta,\n };\n }\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport { refreshGeminiModelCatalog } from './model-catalog-refresh';\nimport { GeminiProvider } from './provider';\n\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_ENV = 'GEMINI_API_KEY';\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_GEMINI_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_GEMINI_PROVIDER_MODEL = 'gemini-3-flash-preview';\nexport const GEMINI_MODEL_SOURCE_URL = 'https://ai.google.dev/api/models';\nexport const GEMINI_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMINI_API_KEY_URL = 'https://aistudio.google.com/apikey';\nconst GEMINI_SETUP_SOURCE_URL = 'https://ai.google.dev/gemini-api/docs/api-key';\nconst GEMINI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMINI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Google AI Studio API keys',\n url: GEMINI_API_KEY_URL,\n sourceUrl: GEMINI_SETUP_SOURCE_URL,\n lastVerifiedAt: GEMINI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createGeminiProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemini',\n aliases: ['google'],\n displayName: 'Gemini',\n description: 'Google Gemini API provider',\n defaults: {\n model: DEFAULT_GEMINI_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMINI_PROVIDER_MODEL,\n displayName: 'Gemini 3 Flash Preview',\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'preview',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n },\n ],\n },\n setupHelpLinks: GEMINI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'Gemini model',\n defaultValue: DEFAULT_GEMINI_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemini API key',\n defaultValue: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n refreshModelCatalog: ({ profile }) => refreshGeminiModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) =>\n new GeminiProvider({\n apiKey: requireApiKey(config.apiKey),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemini requires apiKey');\n }\n return apiKey;\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport { GEMINI_MODEL_LAST_VERIFIED_AT, GEMINI_MODEL_SOURCE_URL } from './provider-definition';\n\nconst GEMINI_API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models';\n\nexport interface IGeminiModelInfo {\n name?: string;\n displayName?: string;\n description?: string;\n inputTokenLimit?: number;\n outputTokenLimit?: number;\n supportedGenerationMethods?: string[];\n}\n\nexport interface IGeminiModelsResponse {\n models?: IGeminiModelInfo[];\n nextPageToken?: string;\n}\n\nexport interface IGeminiFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IGeminiFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IGeminiModelsResponse>;\n}\n\nexport type TGeminiFetch = (url: string, init?: IGeminiFetchInit) => Promise<IGeminiFetchResponse>;\n\nexport async function refreshGeminiModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TGeminiFetch = defaultGeminiFetch,\n): Promise<IProviderModelCatalog> {\n const url = profile.apiKey ? `${GEMINI_API_ENDPOINT}?key=${profile.apiKey}` : GEMINI_API_ENDPOINT;\n\n const response = await fetcher(url);\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n message: `Gemini model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.models ?? []).filter(supportsGenerateContent).map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: new Date().toISOString(),\n entries,\n message: `Fetched ${entries.length} Gemini models`,\n };\n}\n\nfunction supportsGenerateContent(model: IGeminiModelInfo): boolean {\n return model.supportedGenerationMethods?.includes('generateContent') === true;\n}\n\nfunction toModelCatalogEntry(model: IGeminiModelInfo): IProviderModelCatalogEntry {\n const rawName = model.name ?? '';\n const id = rawName.startsWith('models/') ? rawName.slice('models/'.length) : rawName;\n const lifecycle = rawName.includes('preview') ? 'preview' : 'active';\n\n return {\n id,\n displayName: model.displayName ?? id,\n lifecycle,\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nasync function defaultGeminiFetch(\n url: string,\n _init?: IGeminiFetchInit,\n): Promise<IGeminiFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IGeminiModelsResponse>,\n };\n}\n","const START_MARKER = '<|channel>';\nconst END_MARKER = '<channel|>';\nconst THOUGHT_LABEL = 'thought';\n\nexport interface IGemmaReasoningProjection {\n rawText: string;\n visibleText: string;\n removedReasoning: boolean;\n}\n\ninterface IProjectionOptions {\n final: boolean;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n removedReasoning: boolean;\n}\n\nexport function projectGemmaReasoningText(rawText: string): IGemmaReasoningProjection {\n const result = projectText(rawText, { final: true });\n return {\n rawText,\n visibleText: result.visibleParts.join(''),\n removedReasoning: result.removedReasoning,\n };\n}\n\nexport class GemmaReasoningProjector {\n private buffer = '';\n private emittedVisibleText = '';\n private hasRemovedReasoning = false;\n\n get rawText(): string {\n return this.buffer;\n }\n\n get removedReasoning(): boolean {\n return this.hasRemovedReasoning;\n }\n\n project(delta: string): string {\n if (delta.length === 0) {\n return '';\n }\n\n this.buffer += delta;\n return this.projectVisibleText({ final: false });\n }\n\n flush(): string {\n return this.projectVisibleText({ final: true });\n }\n\n private projectVisibleText(options: IProjectionOptions): string {\n const result = projectText(this.buffer, options);\n this.hasRemovedReasoning = this.hasRemovedReasoning || result.removedReasoning;\n\n const nextVisibleText = result.visibleParts.join('');\n const delta = nextVisibleText.slice(this.emittedVisibleText.length);\n this.emittedVisibleText = nextVisibleText;\n return delta;\n }\n}\n\nfunction projectText(rawText: string, options: IProjectionOptions): IProjectionState {\n const state: IProjectionState = {\n visibleParts: [],\n removedReasoning: false,\n };\n\n let cursor = 0;\n while (cursor < rawText.length) {\n const nextMarker = rawText.indexOf(START_MARKER, cursor);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), options);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), options);\n const afterStart = nextMarker + START_MARKER.length;\n const markerEnd = rawText.indexOf(END_MARKER, afterStart);\n\n if (markerEnd === -1) {\n if (options.final) {\n state.removedReasoning = true;\n }\n break;\n }\n\n state.removedReasoning = true;\n cursor = consumeChannelBlock(rawText, afterStart, markerEnd);\n }\n\n return state;\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IProjectionOptions,\n): void {\n if (tail.length === 0) {\n return;\n }\n\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n\n const heldLength = longestStartMarkerPrefixSuffixLength(tail);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction consumeChannelBlock(rawText: string, afterStart: number, markerEnd: number): number {\n const channelText = rawText.slice(afterStart, markerEnd);\n let cursor = markerEnd + END_MARKER.length;\n\n if (channelText.trim().length === 0) {\n const followingThoughtLabel = rawText.slice(cursor).match(/^thought(?:\\r?\\n)*/);\n if (followingThoughtLabel) {\n cursor += followingThoughtLabel[0].length;\n }\n return cursor;\n }\n\n const channelLabel = channelText.split(/\\r?\\n/, 1)[0]?.trim();\n if (channelLabel === THOUGHT_LABEL) {\n return cursor;\n }\n\n return cursor;\n}\n\nfunction longestStartMarkerPrefixSuffixLength(text: string): number {\n const maxLength = Math.min(text.length, START_MARKER.length - 1);\n for (let length = maxLength; length > 0; length -= 1) {\n if (START_MARKER.startsWith(text.slice(text.length - length))) {\n return length;\n }\n }\n return 0;\n}\n","const STRING_DELIMITER = '<|\"|>';\n\nexport interface IGemmaArgumentObject {\n [key: string]: TGemmaArgumentValue;\n}\n\nexport type TGemmaArgumentValue =\n | string\n | number\n | boolean\n | null\n | IGemmaArgumentObject\n | TGemmaArgumentValue[];\n\nexport class GemmaArgumentParser {\n private cursor = 0;\n\n constructor(private readonly source: string) {}\n\n parse(): IGemmaArgumentObject | undefined {\n const value = this.parseObject();\n this.skipWhitespace();\n if (this.cursor !== this.source.length) {\n return undefined;\n }\n return value;\n }\n\n private parseObject(): IGemmaArgumentObject | undefined {\n if (!this.consume('{')) return undefined;\n const result: IGemmaArgumentObject = {};\n this.skipWhitespace();\n if (this.consume('}')) return result;\n\n while (this.cursor < this.source.length) {\n const key = this.parseKey();\n if (!key || !this.consume(':')) return undefined;\n const value = this.parseValue();\n if (value === undefined) return undefined;\n result[key] = value;\n this.skipWhitespace();\n if (this.consume('}')) return result;\n if (!this.consume(',')) return undefined;\n }\n return undefined;\n }\n\n private parseArray(): TGemmaArgumentValue[] | undefined {\n if (!this.consume('[')) return undefined;\n const result: TGemmaArgumentValue[] = [];\n this.skipWhitespace();\n if (this.consume(']')) return result;\n\n while (this.cursor < this.source.length) {\n const value = this.parseValue();\n if (value === undefined) return undefined;\n result.push(value);\n this.skipWhitespace();\n if (this.consume(']')) return result;\n if (!this.consume(',')) return undefined;\n }\n return undefined;\n }\n\n private parseValue(): TGemmaArgumentValue | undefined {\n this.skipWhitespace();\n if (this.source.startsWith(STRING_DELIMITER, this.cursor)) return this.parseString();\n if (this.source.startsWith('{', this.cursor)) return this.parseObject();\n if (this.source.startsWith('[', this.cursor)) return this.parseArray();\n if (this.consumeLiteral('true')) return true;\n if (this.consumeLiteral('false')) return false;\n if (this.consumeLiteral('null')) return null;\n return this.parseNumber();\n }\n\n private parseKey(): string | undefined {\n this.skipWhitespace();\n if (this.source.startsWith(STRING_DELIMITER, this.cursor)) return this.parseString();\n const match = /^[A-Za-z_][A-Za-z0-9_-]*/.exec(this.source.slice(this.cursor));\n if (!match) return undefined;\n this.cursor += match[0].length;\n this.skipWhitespace();\n return match[0];\n }\n\n private parseString(): string | undefined {\n if (!this.consume(STRING_DELIMITER)) return undefined;\n const end = this.source.indexOf(STRING_DELIMITER, this.cursor);\n if (end === -1) return undefined;\n const value = this.source.slice(this.cursor, end);\n this.cursor = end + STRING_DELIMITER.length;\n this.skipWhitespace();\n return value;\n }\n\n private parseNumber(): number | undefined {\n const match = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/.exec(\n this.source.slice(this.cursor),\n );\n if (!match) return undefined;\n this.cursor += match[0].length;\n this.skipWhitespace();\n return Number(match[0]);\n }\n\n private consume(expected: string): boolean {\n this.skipWhitespace();\n if (!this.source.startsWith(expected, this.cursor)) return false;\n this.cursor += expected.length;\n this.skipWhitespace();\n return true;\n }\n\n private consumeLiteral(expected: string): boolean {\n if (!this.source.startsWith(expected, this.cursor)) return false;\n this.cursor += expected.length;\n this.skipWhitespace();\n return true;\n }\n\n private skipWhitespace(): void {\n while (/\\s/.test(this.source[this.cursor] ?? '')) {\n this.cursor += 1;\n }\n }\n}\n","import type {\n IGemmaConsumedPseudoBlock,\n IGemmaConsumedPseudoToolTag,\n IGemmaParsedPseudoTag,\n IGemmaPseudoProjectionOptions,\n TGemmaJsonValue,\n} from './pseudo-tool-call-types';\n\nconst XML_START_MARKER = '<';\n\nexport function createGemmaPseudoStartMarkers(toolNames: readonly string[]): string[] {\n void toolNames;\n return [XML_START_MARKER];\n}\n\nexport function findNextGemmaPseudoStartMarker(\n text: string,\n cursor: number,\n markers: readonly string[],\n): number {\n void markers;\n return text.indexOf(XML_START_MARKER, cursor);\n}\n\nexport function longestGemmaPseudoStartPrefixSuffixLength(\n text: string,\n markers: readonly string[],\n): number {\n void markers;\n return text.endsWith(XML_START_MARKER) ? XML_START_MARKER.length : 0;\n}\n\nexport function parseGemmaPseudoTag(\n text: string,\n start: number,\n): IGemmaParsedPseudoTag | undefined {\n const tagEnd = text.indexOf('>', start + 1);\n if (tagEnd === -1) {\n return undefined;\n }\n\n const rawOpenTag = text.slice(start, tagEnd + 1);\n const tagMatch = rawOpenTag.match(/^<\\s*([A-Za-z][\\w:-]*)([\\s/>][\\s\\S]*?|)>$/);\n if (!tagMatch) {\n return undefined;\n }\n\n const tagName = tagMatch[1] ?? '';\n return {\n tagName,\n normalizedName: tagName.toLowerCase(),\n rawOpenTag,\n attributes: parseAttributes(tagMatch[2] ?? ''),\n openEnd: tagEnd + 1,\n selfClosing: /\\/\\s*>$/.test(rawOpenTag),\n };\n}\n\nexport function consumeGemmaPseudoControlBlock(\n text: string,\n tag: IGemmaParsedPseudoTag,\n options: IGemmaPseudoProjectionOptions,\n): IGemmaConsumedPseudoBlock {\n if (tag.selfClosing) {\n return {\n innerText: '',\n end: tag.openEnd,\n complete: true,\n };\n }\n\n const closeStart = indexOfClosingTag(text, tag.tagName, tag.openEnd);\n if (closeStart === -1) {\n return {\n innerText: text.slice(tag.openEnd),\n end: options.final ? text.length : tag.openEnd - tag.rawOpenTag.length,\n complete: false,\n };\n }\n\n const closingTagEnd = text.indexOf('>', closeStart);\n return {\n innerText: text.slice(tag.openEnd, closeStart),\n end: closingTagEnd === -1 ? text.length : closingTagEnd + 1,\n complete: true,\n };\n}\n\nexport function consumeGemmaPseudoToolTag(\n text: string,\n tag: IGemmaParsedPseudoTag,\n): IGemmaConsumedPseudoToolTag {\n if (tag.selfClosing) {\n return { rawText: tag.rawOpenTag, end: tag.openEnd };\n }\n\n const closeStart = indexOfClosingTag(text, tag.tagName, tag.openEnd);\n if (closeStart === -1) {\n return { rawText: tag.rawOpenTag, end: tag.openEnd };\n }\n\n const closingTagEnd = text.indexOf('>', closeStart);\n const end = closingTagEnd === -1 ? text.length : closingTagEnd + 1;\n return { rawText: text.slice(tag.openEnd - tag.rawOpenTag.length, end), end };\n}\n\nexport function findGemmaDeclaredToolName(\n tagName: string,\n toolNames: readonly string[],\n): string | undefined {\n const normalizedTagName = normalizeToolName(tagName);\n return toolNames.find((toolName) => normalizeToolName(toolName) === normalizedTagName);\n}\n\nfunction parseAttributes(attributeText: string): Record<string, TGemmaJsonValue> {\n const attributes: Record<string, TGemmaJsonValue> = {};\n const pattern = /([A-Za-z_][\\w:-]*)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/g;\n let match = pattern.exec(attributeText);\n while (match) {\n const key = match[1] ?? '';\n const rawValue = match[2] ?? match[3] ?? '';\n attributes[key] = parseAttributeValue(decodeXmlEntities(rawValue));\n match = pattern.exec(attributeText);\n }\n return attributes;\n}\n\nfunction parseAttributeValue(value: string): TGemmaJsonValue {\n if (value === 'true') return true;\n if (value === 'false') return false;\n if (value === 'null') return null;\n if (/^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$/.test(value)) {\n return Number(value);\n }\n return value;\n}\n\nfunction decodeXmlEntities(value: string): string {\n return value\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&');\n}\n\nfunction indexOfClosingTag(text: string, tagName: string, cursor: number): number {\n return text.toLowerCase().indexOf(`</${tagName.toLowerCase()}>`, cursor);\n}\n\nfunction normalizeToolName(value: string): string {\n return value.replace(/[^a-z0-9]/gi, '').toLowerCase();\n}\n","import { findGemmaDeclaredToolName } from './pseudo-tool-call-tag-parser';\nimport type { TGemmaJsonValue } from './pseudo-tool-call-types';\n\nexport interface IGemmaPseudoCommandEnvelope {\n toolName: string;\n args: Record<string, TGemmaJsonValue>;\n}\n\nexport function parseGemmaPseudoCommandEnvelopes(\n rawText: string,\n toolNames: readonly string[],\n): IGemmaPseudoCommandEnvelope[] {\n const jsonEnvelope = parseGemmaPseudoCommandEnvelope(rawText, toolNames);\n return jsonEnvelope ? [jsonEnvelope] : [];\n}\n\nexport function parseGemmaPseudoCommandEnvelope(\n rawText: string,\n toolNames: readonly string[],\n): IGemmaPseudoCommandEnvelope | undefined {\n const openEnd = rawText.indexOf('>');\n const closeStart = rawText.lastIndexOf('</');\n if (openEnd === -1 || closeStart === -1 || closeStart <= openEnd) {\n return undefined;\n }\n\n const parsed = parseJsonValue(rawText.slice(openEnd + 1, closeStart).trim());\n if (!isJsonRecord(parsed)) {\n return undefined;\n }\n\n const command = parsed['command'];\n const args = parsed['args'];\n if (typeof command !== 'string' || !isJsonRecord(args)) {\n return undefined;\n }\n\n const toolName = findGemmaDeclaredToolName(command, toolNames);\n if (!toolName) {\n return undefined;\n }\n\n return { toolName, args };\n}\n\nfunction parseJsonValue(text: string): TGemmaJsonValue | undefined {\n try {\n return JSON.parse(text) as TGemmaJsonValue;\n } catch {\n return undefined;\n }\n}\n\nfunction isJsonRecord(\n value: TGemmaJsonValue | undefined,\n): value is Record<string, TGemmaJsonValue> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import type { IToolCall } from '@robota-sdk/agent-core';\nimport { parseGemmaPseudoCommandEnvelopes } from './pseudo-command-envelope';\nimport {\n consumeGemmaPseudoControlBlock,\n consumeGemmaPseudoToolTag,\n createGemmaPseudoStartMarkers,\n findGemmaDeclaredToolName,\n findNextGemmaPseudoStartMarker,\n longestGemmaPseudoStartPrefixSuffixLength,\n parseGemmaPseudoTag,\n} from './pseudo-tool-call-tag-parser';\nimport type {\n IGemmaConsumedPseudoBlock,\n IGemmaParsedPseudoTag,\n IGemmaPseudoProjectionOptions,\n TGemmaJsonValue,\n} from './pseudo-tool-call-types';\n\nconst DEFAULT_CALL_ID_PREFIX = 'gemma_call';\n\nexport interface IGemmaPseudoToolCallProjection {\n visibleText: string;\n toolCalls: IToolCall[];\n removedToolCallText: boolean;\n rawToolCallTextParts: string[];\n}\n\nexport interface IGemmaPseudoToolCallProjectorOptions {\n toolNames: readonly string[];\n callIdPrefix?: string;\n startCallIndex?: number;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n toolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n removedToolCallText: boolean;\n}\n\ninterface IProjectTagResult {\n cursor: number;\n completed: boolean;\n}\n\nexport function projectGemmaPseudoToolCallText(\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IGemmaPseudoToolCallProjection {\n const state = createProjectionState();\n const markers = createGemmaPseudoStartMarkers(options.toolNames);\n let cursor = 0;\n\n while (cursor < rawText.length) {\n const nextMarker = findNextGemmaPseudoStartMarker(rawText, cursor, markers);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), projectionOptions, markers);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), projectionOptions, markers);\n const result = projectTagAt(rawText, nextMarker, state, options, projectionOptions);\n if (!result.completed) {\n break;\n }\n cursor = result.cursor;\n }\n\n return {\n visibleText: state.visibleParts.join(''),\n toolCalls: state.toolCalls,\n rawToolCallTextParts: state.rawToolCallTextParts,\n removedToolCallText: state.removedToolCallText,\n };\n}\n\nfunction projectTagAt(\n rawText: string,\n tagStart: number,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n const tag = parseGemmaPseudoTag(rawText, tagStart);\n if (!tag) {\n return projectMalformedTag(rawText, tagStart, state, projectionOptions);\n }\n const toolName = findGemmaDeclaredToolName(tag.tagName, options.toolNames);\n if (toolName) {\n return projectToolTag(rawText, tag, toolName, state, options);\n }\n return projectXmlArtifact(rawText, tagStart, tag, state, options, projectionOptions);\n}\n\nfunction projectMalformedTag(\n rawText: string,\n tagStart: number,\n state: IProjectionState,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n if (!projectionOptions.final) {\n return { cursor: tagStart, completed: false };\n }\n state.visibleParts.push(rawText[tagStart] ?? '');\n return { cursor: tagStart + 1, completed: true };\n}\n\nfunction projectXmlArtifact(\n rawText: string,\n tagStart: number,\n tag: IGemmaParsedPseudoTag,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n const block = consumeGemmaPseudoControlBlock(rawText, tag, projectionOptions);\n if (!block.complete && !projectionOptions.final) {\n return { cursor: tagStart, completed: false };\n }\n\n const rawControlText = rawText.slice(tagStart, block.end);\n const rawPartCount = state.rawToolCallTextParts.length;\n state.removedToolCallText = true;\n appendCommandEnvelopeToolCall(state, rawControlText, options);\n mergeProjection(state, projectControlBlockInner(block, state, options));\n if (state.rawToolCallTextParts.length === rawPartCount) {\n state.rawToolCallTextParts.push(rawControlText);\n }\n return { cursor: block.end, completed: true };\n}\n\nfunction projectControlBlockInner(\n block: IGemmaConsumedPseudoBlock,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): IGemmaPseudoToolCallProjection {\n return projectGemmaPseudoToolCallText(\n block.innerText,\n {\n ...options,\n startCallIndex: getNextCallIndex(state, options),\n },\n { final: true },\n );\n}\n\nfunction projectToolTag(\n rawText: string,\n tag: IGemmaParsedPseudoTag,\n toolName: string,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): IProjectTagResult {\n const rawToolTag = consumeGemmaPseudoToolTag(rawText, tag);\n appendToolCall(state, toolName, tag.attributes, rawToolTag.rawText, options);\n return { cursor: rawToolTag.end, completed: true };\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IGemmaPseudoProjectionOptions,\n markers: readonly string[],\n): void {\n if (tail.length === 0) {\n return;\n }\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n const heldLength = longestGemmaPseudoStartPrefixSuffixLength(tail, markers);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction appendToolCall(\n state: IProjectionState,\n toolName: string,\n args: Record<string, TGemmaJsonValue>,\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n): void {\n if (Object.keys(args).length === 0) {\n return;\n }\n state.toolCalls.push(createToolCall(toolName, args, options, state));\n state.rawToolCallTextParts.push(rawText);\n state.removedToolCallText = true;\n}\n\nfunction appendCommandEnvelopeToolCall(\n state: IProjectionState,\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n): void {\n const commands = parseGemmaPseudoCommandEnvelopes(rawText, options.toolNames);\n for (const command of commands) {\n state.toolCalls.push(createToolCall(command.toolName, command.args, options, state));\n state.rawToolCallTextParts.push(rawText);\n }\n}\n\nfunction createToolCall(\n toolName: string,\n args: Record<string, TGemmaJsonValue>,\n options: IGemmaPseudoToolCallProjectorOptions,\n state: IProjectionState,\n): IToolCall {\n return {\n id: `${options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX}_${getNextCallIndex(state, options)}`,\n type: 'function',\n function: {\n name: toolName,\n arguments: JSON.stringify(args),\n },\n };\n}\n\nfunction createProjectionState(): IProjectionState {\n return {\n visibleParts: [],\n toolCalls: [],\n rawToolCallTextParts: [],\n removedToolCallText: false,\n };\n}\n\nfunction mergeProjection(\n state: IProjectionState,\n projection: IGemmaPseudoToolCallProjection,\n): void {\n state.toolCalls.push(...projection.toolCalls);\n state.rawToolCallTextParts.push(...projection.rawToolCallTextParts);\n state.removedToolCallText = state.removedToolCallText || projection.removedToolCallText;\n}\n\nfunction getNextCallIndex(\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): number {\n return (options.startCallIndex ?? 0) + state.toolCalls.length;\n}\n","import type { IToolCall, IToolSchema } from '@robota-sdk/agent-core';\nimport type {\n IOpenAICompatibleToolCallTextProjection,\n IOpenAICompatibleToolCallTextProjector,\n} from '../shared/openai-compatible/index.js';\nimport { GemmaArgumentParser } from './tool-call-argument-parser';\nimport { projectGemmaPseudoToolCallText } from './pseudo-tool-call-projector';\n\nconst TOOL_CALL_START = '<|tool_call>';\nconst TOOL_CALL_END = '<tool_call|>';\nconst CALL_PREFIX = 'call:';\nconst DEFAULT_CALL_ID_PREFIX = 'gemma_call';\n\nexport interface IGemmaToolCallProjectorOptions {\n toolNames: readonly string[];\n callIdPrefix?: string;\n}\n\nexport interface IGemmaToolCallProjection extends IOpenAICompatibleToolCallTextProjection {\n rawText: string;\n}\n\ninterface IProjectionOptions {\n final: boolean;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n toolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n removedToolCallText: boolean;\n}\n\nexport function createGemmaToolCallProjector(\n tools: readonly IToolSchema[] | undefined,\n): GemmaToolCallProjector | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n return new GemmaToolCallProjector({ toolNames: tools.map((tool) => tool.name) });\n}\n\nexport function projectGemmaToolCallText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n): IGemmaToolCallProjection {\n const result = projectText(rawText, options, { final: true });\n return toPublicProjection(rawText, result);\n}\n\nexport class GemmaToolCallProjector implements IOpenAICompatibleToolCallTextProjector {\n private buffer = '';\n private emittedVisibleText = '';\n private emittedRawToolCallText = '';\n private readonly emittedToolCallIds = new Set<string>();\n\n constructor(private readonly options: IGemmaToolCallProjectorOptions) {}\n\n project(delta: string): IOpenAICompatibleToolCallTextProjection {\n if (delta.length === 0) {\n return emptyProjection();\n }\n\n this.buffer += delta;\n return this.projectVisibleText({ final: false });\n }\n\n flush(): IOpenAICompatibleToolCallTextProjection {\n return this.projectVisibleText({ final: true });\n }\n\n private projectVisibleText(options: IProjectionOptions): IOpenAICompatibleToolCallTextProjection {\n const result = projectText(this.buffer, this.options, options);\n const nextVisibleText = result.visibleParts.join('');\n const visibleText = nextVisibleText.slice(this.emittedVisibleText.length);\n const nextRawToolCallText = result.rawToolCallTextParts.join('');\n const rawToolCallText = nextRawToolCallText.slice(this.emittedRawToolCallText.length);\n this.emittedVisibleText = nextVisibleText;\n this.emittedRawToolCallText = nextRawToolCallText;\n\n const toolCalls = result.toolCalls.filter((toolCall) => {\n if (this.emittedToolCallIds.has(toolCall.id)) {\n return false;\n }\n this.emittedToolCallIds.add(toolCall.id);\n return true;\n });\n\n return {\n visibleText,\n toolCalls,\n removedToolCallText: rawToolCallText.length > 0,\n ...(rawToolCallText.length > 0 && {\n rawToolCallText,\n }),\n };\n }\n}\n\nfunction projectText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n projectionOptions: IProjectionOptions,\n): IProjectionState {\n const nativeProjection = projectNativeToolCallText(rawText, options, projectionOptions);\n const pseudoProjection = projectGemmaPseudoToolCallText(\n nativeProjection.visibleParts.join(''),\n {\n toolNames: options.toolNames,\n callIdPrefix: options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX,\n startCallIndex: nativeProjection.toolCalls.length,\n },\n projectionOptions,\n );\n\n return {\n visibleParts: [pseudoProjection.visibleText],\n toolCalls: [...nativeProjection.toolCalls, ...pseudoProjection.toolCalls],\n rawToolCallTextParts: [\n ...nativeProjection.rawToolCallTextParts,\n ...pseudoProjection.rawToolCallTextParts,\n ],\n removedToolCallText:\n nativeProjection.removedToolCallText || pseudoProjection.removedToolCallText,\n };\n}\n\nfunction projectNativeToolCallText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n projectionOptions: IProjectionOptions,\n): IProjectionState {\n const state = createProjectionState();\n const toolNames = new Set(options.toolNames);\n let cursor = 0;\n let projectedCallIndex = 0;\n\n while (cursor < rawText.length) {\n const nextMarker = rawText.indexOf(TOOL_CALL_START, cursor);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), projectionOptions);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), projectionOptions);\n const afterStart = nextMarker + TOOL_CALL_START.length;\n const markerEnd = rawText.indexOf(TOOL_CALL_END, afterStart);\n if (markerEnd === -1) {\n if (projectionOptions.final) {\n state.visibleParts.push(rawText.slice(nextMarker));\n }\n break;\n }\n\n const rawBlock = rawText.slice(nextMarker, markerEnd + TOOL_CALL_END.length);\n const blockText = rawText.slice(afterStart, markerEnd);\n const toolCall = parseToolCallBlock(blockText, toolNames, options, projectedCallIndex);\n if (!toolCall) {\n state.visibleParts.push(rawBlock);\n } else {\n state.toolCalls.push(toolCall);\n state.rawToolCallTextParts.push(rawBlock);\n state.removedToolCallText = true;\n projectedCallIndex += 1;\n }\n cursor = markerEnd + TOOL_CALL_END.length;\n }\n\n return state;\n}\n\nfunction parseToolCallBlock(\n blockText: string,\n toolNames: ReadonlySet<string>,\n options: IGemmaToolCallProjectorOptions,\n projectedCallIndex: number,\n): IToolCall | undefined {\n const trimmed = blockText.trim();\n if (!trimmed.startsWith(CALL_PREFIX)) {\n return undefined;\n }\n\n const callText = trimmed.slice(CALL_PREFIX.length).trimStart();\n const argsStart = callText.indexOf('{');\n if (argsStart <= 0) {\n return undefined;\n }\n\n const toolName = callText.slice(0, argsStart).trim();\n if (!toolNames.has(toolName)) {\n return undefined;\n }\n\n const args = new GemmaArgumentParser(callText.slice(argsStart)).parse();\n if (!args) {\n return undefined;\n }\n\n return {\n id: `${options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX}_${projectedCallIndex}`,\n type: 'function',\n function: {\n name: toolName,\n arguments: JSON.stringify(args),\n },\n };\n}\n\nfunction createProjectionState(): IProjectionState {\n return {\n visibleParts: [],\n toolCalls: [],\n rawToolCallTextParts: [],\n removedToolCallText: false,\n };\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IProjectionOptions,\n): void {\n if (tail.length === 0) {\n return;\n }\n\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n\n const heldLength = longestStartMarkerPrefixSuffixLength(tail);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction longestStartMarkerPrefixSuffixLength(text: string): number {\n const maxLength = Math.min(text.length, TOOL_CALL_START.length - 1);\n for (let length = maxLength; length > 0; length -= 1) {\n if (TOOL_CALL_START.startsWith(text.slice(text.length - length))) {\n return length;\n }\n }\n return 0;\n}\n\nfunction toPublicProjection(rawText: string, state: IProjectionState): IGemmaToolCallProjection {\n return {\n rawText,\n visibleText: state.visibleParts.join(''),\n toolCalls: state.toolCalls,\n removedToolCallText: state.removedToolCallText,\n ...(state.rawToolCallTextParts.length > 0 && {\n rawToolCallText: state.rawToolCallTextParts.join(''),\n }),\n };\n}\n\nfunction emptyProjection(): IOpenAICompatibleToolCallTextProjection {\n return {\n visibleText: '',\n toolCalls: [],\n removedToolCallText: false,\n };\n}\n","import type OpenAI from 'openai';\nimport type { IChatOptions, ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { OpenAICompatibleResponseParser } from '../shared/openai-compatible/index.js';\nimport { projectGemmaReasoningText } from './reasoning-projector';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\n\nexport function parseGemmaChatCompletion(\n response: OpenAI.Chat.ChatCompletion,\n logger: ILogger,\n options: IChatOptions | undefined,\n): TUniversalMessage {\n const rawContent = response.choices?.[0]?.message.content || '';\n const parser = new OpenAICompatibleResponseParser({\n logger,\n ...(options?.tools && {\n toolCallTextProjector: createGemmaToolCallProjector(options.tools),\n }),\n });\n const parsed = parser.parseResponse(response);\n const projection = projectGemmaReasoningText(parsed.content ?? '');\n\n return withGemmaProjectionMetadata(\n {\n ...parsed,\n content: projection.visibleText,\n },\n rawContent,\n projection.removedReasoning,\n );\n}\n\nexport function withGemmaProjectionMetadata(\n message: TUniversalMessage,\n rawContent: string,\n removedReasoning: boolean,\n): TUniversalMessage {\n if (!removedReasoning) {\n return message;\n }\n\n return {\n ...message,\n metadata: {\n ...(message.metadata ?? {}),\n gemmaReasoningFiltered: true,\n gemmaRawContent: rawContent,\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type OpenAI from 'openai';\nimport type { IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\n\nexport function createStreamTextMessage(\n content: string,\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n}\n\nexport function createStreamToolCallMessage(\n toolCalls: IToolCall[],\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: '',\n toolCalls,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n}\n","import type OpenAI from 'openai';\nimport { isAssistantMessage } from '@robota-sdk/agent-core';\nimport type { ILogger, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport { OpenAICompatibleResponseParser } from '../shared/openai-compatible/index.js';\nimport type { IOpenAICompatibleToolCallTextProjector } from '../shared/openai-compatible/index.js';\nimport { createStreamTextMessage, createStreamToolCallMessage } from './message-factory';\nimport { GemmaReasoningProjector } from './reasoning-projector';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\n\nexport interface IGemmaStreamProjectionState {\n reasoningProjector: GemmaReasoningProjector;\n responseParser: OpenAICompatibleResponseParser;\n toolCallProjector?: IOpenAICompatibleToolCallTextProjector;\n}\n\nexport function createGemmaStreamProjectionState(\n logger: ILogger,\n tools: readonly IToolSchema[] | undefined,\n): IGemmaStreamProjectionState {\n return {\n reasoningProjector: new GemmaReasoningProjector(),\n responseParser: new OpenAICompatibleResponseParser({ logger }),\n ...(tools && { toolCallProjector: createGemmaToolCallProjector(tools) }),\n };\n}\n\nexport function projectGemmaStreamChunk(\n chunk: OpenAI.Chat.ChatCompletionChunk,\n state: IGemmaStreamProjectionState,\n): TUniversalMessage[] {\n const choice = chunk.choices?.[0];\n if (!choice) {\n return [];\n }\n\n const nativeToolCallMessage = state.responseParser.parseStreamingChunk(chunk);\n if (nativeToolCallMessage && isAssistantMessage(nativeToolCallMessage)) {\n if (nativeToolCallMessage.toolCalls?.length) {\n return [nativeToolCallMessage];\n }\n }\n\n return projectGemmaTextDelta(choice.delta.content || '', choice.finish_reason, state);\n}\n\nexport function flushGemmaStreamProjection(\n state: IGemmaStreamProjectionState,\n): TUniversalMessage[] {\n const messages = projectGemmaTextDelta('', null, state, true);\n const flushedContent = state.reasoningProjector.flush();\n if (flushedContent.length > 0) {\n messages.push(createStreamTextMessage(flushedContent, null));\n }\n return messages;\n}\n\nfunction projectGemmaTextDelta(\n rawContent: string,\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n state: IGemmaStreamProjectionState,\n flushToolProjector = false,\n): TUniversalMessage[] {\n const toolProjection = flushToolProjector\n ? state.toolCallProjector?.flush()\n : state.toolCallProjector?.project(rawContent);\n const messages: TUniversalMessage[] = [];\n\n if (toolProjection?.toolCalls.length) {\n messages.push(createStreamToolCallMessage(toolProjection.toolCalls, finishReason));\n }\n\n const contentAfterToolProjection = toolProjection?.visibleText ?? rawContent;\n const visibleContent = state.reasoningProjector.project(contentAfterToolProjection);\n if (visibleContent.length > 0) {\n messages.push(createStreamTextMessage(visibleContent, finishReason));\n }\n\n return messages;\n}\n","import OpenAI from 'openai';\nimport { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport type {\n IAssistantMessage,\n IChatOptions,\n IProviderCapabilities,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n} from '../shared/openai-compatible/index.js';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport type { IGemmaProviderOptions } from './types';\nimport { GemmaReasoningProjector } from './reasoning-projector';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\nimport { parseGemmaChatCompletion, withGemmaProjectionMetadata } from './provider-projection';\nimport {\n createGemmaStreamProjectionState,\n flushGemmaStreamProjection,\n projectGemmaStreamChunk,\n} from './streaming-projection';\n\nexport class GemmaProvider extends AbstractAIProvider {\n override readonly name = 'gemma';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IGemmaProviderOptions;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IGemmaProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.baseURL !== undefined && { baseURL: options.baseURL }),\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either Gemma client, apiKey, or executor is required');\n }\n }\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemma Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return await this.chatWithStreamingAssembly(\n {\n ...requestParams,\n stream: true,\n },\n {\n ...options,\n onTextDelta: textDeltaCb,\n },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await this.client.chat.completions.create(requestParams);\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return parseGemmaChatCompletion(response, this.logger, options);\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma API request failed';\n throw new Error(`Gemma chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemma Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(requestParams);\n const projectionState = createGemmaStreamProjectionState(this.logger, options?.tools);\n\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'gemma',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n for (const message of projectGemmaStreamChunk(chunk, projectionState)) {\n yield message;\n }\n }\n\n for (const message of flushGemmaStreamProjection(projectionState)) {\n yield message;\n }\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma API request failed';\n throw new Error(`Gemma stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web search.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web fetch.',\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible local clients do not need explicit cleanup.\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams = {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n };\n\n return requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n } as OpenAI.Chat.ChatCompletionCreateParamsStreaming;\n }\n\n private async chatWithStreamingAssembly(\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n ): Promise<TUniversalMessage> {\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(\n requestParams,\n options.signal ? { signal: options.signal } : undefined,\n );\n const projector = new GemmaReasoningProjector();\n const result = await assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'gemma',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n textProjector: (text) => projector.project(text),\n textProjectorFlush: () => projector.flush(),\n toolCallTextProjector: createGemmaToolCallProjector(options.tools),\n });\n\n return withGemmaProjectionMetadata(result, projector.rawText, projector.removedReasoning);\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma streaming request failed';\n throw new Error(`Gemma stream failed: ${errorMessage}`);\n }\n }\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\nimport { GemmaProvider } from './provider';\n\nexport const DEFAULT_GEMMA_PROVIDER_MODEL = 'supergemma4-26b-uncensored-v2';\nexport const DEFAULT_GEMMA_PROVIDER_API_KEY = 'lm-studio';\nexport const DEFAULT_GEMMA_PROVIDER_BASE_URL = 'http://localhost:1234/v1';\nconst GEMMA_MODEL_SOURCE_URL = 'https://ai.google.dev/gemma';\nconst GEMMA_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMMA_SETUP_URL = 'https://lmstudio.ai/docs/developer';\nconst GEMMA_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMMA_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'official',\n label: 'LM Studio local API documentation',\n url: GEMMA_SETUP_URL,\n sourceUrl: GEMMA_SETUP_URL,\n lastVerifiedAt: GEMMA_SETUP_LAST_VERIFIED_AT,\n },\n];\nconst GEMMA_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: GEMMA_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMMA_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMMA_PROVIDER_MODEL,\n displayName: 'SuperGemma 4 26B',\n capabilities: ['tools', 'streaming'],\n lifecycle: 'active',\n sourceUrl: GEMMA_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMMA_MODEL_LAST_VERIFIED_AT,\n },\n ],\n};\n\nexport function createGemmaProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemma',\n displayName: 'Gemma',\n description: 'Gemma-family local models through an OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_GEMMA_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMMA_PROVIDER_API_KEY,\n baseURL: DEFAULT_GEMMA_PROVIDER_BASE_URL,\n },\n modelCatalog: GEMMA_MODEL_CATALOG,\n setupHelpLinks: GEMMA_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'Gemma OpenAI-compatible base URL',\n defaultValue: DEFAULT_GEMMA_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'Gemma model',\n defaultValue: DEFAULT_GEMMA_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemma OpenAI-compatible API key',\n defaultValue: DEFAULT_GEMMA_PROVIDER_API_KEY,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n createProvider: (config) =>\n new GemmaProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemma requires apiKey');\n }\n return apiKey;\n}\n","import type { TProviderMediaResult } from '@robota-sdk/agent-core';\nimport type { IBytedanceApiErrorResponse, IBytedanceProviderOptions } from './types';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\n/** HTTP status codes used by the Bytedance API error mapper. */\nconst HTTP_UNAUTHORIZED = 401;\nconst HTTP_FORBIDDEN = 403;\nconst HTTP_NOT_FOUND = 404;\nconst HTTP_CONFLICT = 409;\nconst HTTP_TOO_MANY_REQUESTS = 429;\nconst HTTP_BAD_REQUEST = 400;\nconst HTTP_INTERNAL_ERROR = 500;\n\n/** Sends an HTTP request to the Bytedance API and returns the parsed JSON response. */\nexport async function requestJson<TResponse>(\n options: IBytedanceProviderOptions,\n request: {\n path: string;\n method: 'GET' | 'POST' | 'DELETE';\n body?: string;\n },\n): Promise<TProviderMediaResult<TResponse>> {\n const controller = new AbortController();\n const timeoutHandle = setTimeout(\n () => controller.abort(),\n options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n );\n try {\n const response = await fetch(buildUrl(options.baseUrl, request.path), {\n method: request.method,\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n ...(options.defaultHeaders ?? {}),\n },\n body: request.body,\n signal: controller.signal,\n });\n const responseText = await response.text();\n if (!response.ok) {\n return mapHttpError(response.status, responseText);\n }\n\n const parsedResult = parseJsonRecord(responseText);\n if (!parsedResult.ok) {\n return parsedResult;\n }\n return {\n ok: true,\n value: parsedResult.value as TResponse,\n };\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n ok: false,\n error: { code: 'PROVIDER_TIMEOUT', message: 'Bytedance media request timed out.' },\n };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: error instanceof Error ? error.message : 'Bytedance media request failed.',\n },\n };\n } finally {\n clearTimeout(timeoutHandle);\n }\n}\n\nfunction buildUrl(baseUrl: string, path: string): string {\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n const sanitizedPath = path.startsWith('/') ? path : `/${path}`;\n return `${sanitizedBaseUrl}${sanitizedPath}`;\n}\n\nfunction parseJsonRecord(\n responseText: string,\n): TProviderMediaResult<Record<string, string | number | boolean | undefined>> {\n try {\n const parsedValue = JSON.parse(responseText) as Record<\n string,\n string | number | boolean | undefined\n >;\n return { ok: true, value: parsedValue };\n } catch {\n return {\n ok: false,\n error: { code: 'PROVIDER_UPSTREAM_ERROR', message: 'Bytedance response is not valid JSON.' },\n };\n }\n}\n\nfunction parseErrorResponse(responseText: string): IBytedanceApiErrorResponse {\n try {\n return JSON.parse(responseText) as IBytedanceApiErrorResponse;\n } catch {\n return { message: responseText };\n }\n}\n\nfunction mapHttpError(statusCode: number, responseText: string): TProviderMediaResult<never> {\n const parsedError = parseErrorResponse(responseText);\n if (statusCode === HTTP_UNAUTHORIZED || statusCode === HTTP_FORBIDDEN) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_AUTH_ERROR',\n message: parsedError.message ?? 'Bytedance authentication failed.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_NOT_FOUND) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_JOB_NOT_FOUND',\n message: parsedError.message ?? 'Bytedance video job was not found.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_CONFLICT) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_JOB_NOT_CANCELLABLE',\n message: parsedError.message ?? 'Bytedance video job cannot be cancelled in current state.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_TOO_MANY_REQUESTS) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_RATE_LIMITED',\n message: parsedError.message ?? 'Bytedance rate limit exceeded.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode >= HTTP_BAD_REQUEST && statusCode < HTTP_INTERNAL_ERROR) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: parsedError.message ?? 'Bytedance rejected request payload.',\n details: parsedError.details,\n },\n };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: parsedError.message ?? 'Bytedance upstream request failed.',\n details: parsedError.details,\n },\n };\n}\n","import type { TProviderMediaResult, IVideoJobSnapshot } from '@robota-sdk/agent-core';\nimport type { IBytedanceVideoTaskResponse } from './types';\n\n/** Threshold (in milliseconds) above which a numeric timestamp is treated as milliseconds rather than seconds. */\nconst MILLISECOND_EPOCH_THRESHOLD = 1_000_000_000_000;\n\n/** Conversion factor from seconds to milliseconds. */\nconst MS_PER_SECOND = 1000;\n\n/** Maps a Bytedance video task response into a normalized job snapshot. */\nexport function mapVideoJobSnapshot(\n response: IBytedanceVideoTaskResponse,\n): TProviderMediaResult<IVideoJobSnapshot> {\n if (response.id.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Bytedance video job response is missing task id.',\n },\n };\n }\n const normalizedStatusResult = mapVideoStatus(response.status);\n if (!normalizedStatusResult.ok) {\n return normalizedStatusResult;\n }\n return {\n ok: true,\n value: {\n jobId: response.id,\n status: normalizedStatusResult.value,\n output: mapOutput(response),\n error:\n normalizedStatusResult.value === 'failed' && response.error_message\n ? { code: 'PROVIDER_UPSTREAM_ERROR', message: response.error_message }\n : undefined,\n updatedAt: toIsoTimestamp(response.updated_at ?? response.created_at),\n },\n };\n}\n\n/** Maps a Bytedance status string to a normalized video job status. */\nexport function mapVideoStatus(status: string): TProviderMediaResult<IVideoJobSnapshot['status']> {\n const normalized = status.trim().toLowerCase();\n if (normalized === 'queued' || normalized === 'pending' || normalized === 'submitted') {\n return { ok: true, value: 'queued' };\n }\n if (normalized === 'running' || normalized === 'processing' || normalized === 'in_progress') {\n return { ok: true, value: 'running' };\n }\n if (normalized === 'succeeded' || normalized === 'success' || normalized === 'completed') {\n return { ok: true, value: 'succeeded' };\n }\n if (normalized === 'failed' || normalized === 'error') {\n return { ok: true, value: 'failed' };\n }\n if (normalized === 'cancelled' || normalized === 'canceled') {\n return { ok: true, value: 'cancelled' };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: `Unexpected video job status from Bytedance: ${status}`,\n },\n };\n}\n\n/** Maps the initial createVideo status to queued or running. */\nexport function mapInitialStatus(\n statusValue: string | undefined,\n): TProviderMediaResult<'queued' | 'running'> {\n if (typeof statusValue !== 'string' || statusValue.trim().length === 0) {\n return { ok: true, value: 'queued' };\n }\n const normalizedStatus = statusValue.trim().toLowerCase();\n if (\n normalizedStatus === 'queued' ||\n normalizedStatus === 'pending' ||\n normalizedStatus === 'submitted'\n ) {\n return { ok: true, value: 'queued' };\n }\n if (\n normalizedStatus === 'running' ||\n normalizedStatus === 'processing' ||\n normalizedStatus === 'in_progress'\n ) {\n return { ok: true, value: 'running' };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: `Unexpected createVideo status from Bytedance: ${statusValue}`,\n },\n };\n}\n\n/** Converts a numeric or string timestamp to ISO 8601 format. */\nexport function toIsoTimestamp(value: string | number | undefined): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n const numericTimestamp = value > MILLISECOND_EPOCH_THRESHOLD ? value : value * MS_PER_SECOND;\n const date = new Date(numericTimestamp);\n if (!Number.isNaN(date.getTime())) {\n return date.toISOString();\n }\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n const maybeNumeric = Number(value);\n if (Number.isFinite(maybeNumeric)) {\n return toIsoTimestamp(maybeNumeric);\n }\n const parsedDate = new Date(value);\n if (!Number.isNaN(parsedDate.getTime())) {\n return parsedDate.toISOString();\n }\n }\n return new Date().toISOString();\n}\n\nfunction mapOutput(response: IBytedanceVideoTaskResponse): IVideoJobSnapshot['output'] {\n const directVideoUrl =\n typeof response.video_url === 'string' && response.video_url.trim().length > 0\n ? response.video_url\n : undefined;\n const contentVideoUrl =\n typeof response.content?.video_url === 'string' && response.content.video_url.trim().length > 0\n ? response.content.video_url\n : undefined;\n const resolvedVideoUrl = directVideoUrl ?? contentVideoUrl;\n if (typeof resolvedVideoUrl !== 'string') {\n return undefined;\n }\n return {\n kind: 'uri',\n uri: resolvedVideoUrl,\n mimeType: response.mime_type,\n bytes: response.bytes,\n };\n}\n","import type {\n IInlineImageInputSource,\n IUriImageInputSource,\n TProviderMediaResult,\n IVideoGenerationProvider,\n IVideoGenerationRequest,\n IVideoJobAccepted,\n IVideoJobSnapshot,\n} from '@robota-sdk/agent-core';\nimport type {\n IBytedanceCreateVideoTaskRequest,\n IBytedanceCreateVideoTaskResponse,\n IBytedanceProviderOptions,\n IBytedanceVideoTaskResponse,\n TBytedanceTaskContent,\n} from './types';\nimport { requestJson } from './http-client';\nimport { mapVideoJobSnapshot, mapInitialStatus, toIsoTimestamp } from './status-mapper';\n\nconst DEFAULT_CREATE_VIDEO_PATH = '/contents/generations/tasks';\nconst DEFAULT_GET_VIDEO_TASK_PATH_TEMPLATE = '/contents/generations/tasks/{taskId}';\nconst DEFAULT_CANCEL_VIDEO_TASK_PATH_TEMPLATE = '/contents/generations/tasks/{taskId}';\n\nexport class BytedanceProvider implements IVideoGenerationProvider {\n private readonly options: IBytedanceProviderOptions;\n\n public constructor(options: IBytedanceProviderOptions) {\n this.options = options;\n }\n\n public async createVideo(\n request: IVideoGenerationRequest,\n ): Promise<TProviderMediaResult<IVideoJobAccepted>> {\n if (request.prompt.trim().length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty prompt.');\n }\n if (request.model.trim().length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty model.');\n }\n if (typeof request.seed === 'number') {\n return buildInvalidRequestError(\n 'ModelArk Seedance provider does not support seed field in current contract.',\n );\n }\n\n const contentResult = this.buildContentPayload(request.prompt, request.inputImages);\n if (!contentResult.ok) {\n return contentResult;\n }\n\n const payload: IBytedanceCreateVideoTaskRequest = {\n model: request.model.trim(),\n content: contentResult.value,\n duration: request.durationSeconds,\n ratio: request.aspectRatio,\n };\n\n const responseResult = await requestJson<IBytedanceCreateVideoTaskResponse>(this.options, {\n path: this.options.createVideoPath ?? DEFAULT_CREATE_VIDEO_PATH,\n method: 'POST',\n body: JSON.stringify(payload),\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n\n if (responseResult.value.id.trim().length === 0) {\n return buildUpstreamError('Bytedance createVideo response is missing task id.');\n }\n const mappedStatus = mapInitialStatus(responseResult.value.status);\n if (!mappedStatus.ok) {\n return mappedStatus;\n }\n return {\n ok: true,\n value: {\n jobId: responseResult.value.id,\n status: mappedStatus.value,\n createdAt: toIsoTimestamp(responseResult.value.created_at),\n },\n };\n }\n\n public async getVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>> {\n if (jobId.trim().length === 0) {\n return buildInvalidRequestError('Video job lookup requires non-empty jobId.');\n }\n\n const responseResult = await requestJson<IBytedanceVideoTaskResponse>(this.options, {\n path: buildPath(\n this.options.getVideoTaskPathTemplate ?? DEFAULT_GET_VIDEO_TASK_PATH_TEMPLATE,\n jobId,\n ),\n method: 'GET',\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n return mapVideoJobSnapshot(responseResult.value);\n }\n\n public async cancelVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>> {\n if (jobId.trim().length === 0) {\n return buildInvalidRequestError('Video job cancellation requires non-empty jobId.');\n }\n\n const cancelMethod = this.options.cancelVideoTaskMethod ?? 'DELETE';\n const responseResult = await requestJson<IBytedanceVideoTaskResponse>(this.options, {\n path: buildPath(\n this.options.cancelVideoTaskPathTemplate ?? DEFAULT_CANCEL_VIDEO_TASK_PATH_TEMPLATE,\n jobId,\n ),\n method: cancelMethod,\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n return mapVideoJobSnapshot(responseResult.value);\n }\n\n private buildContentPayload(\n prompt: string,\n inputImages: IVideoGenerationRequest['inputImages'],\n ): TProviderMediaResult<TBytedanceTaskContent[]> {\n const normalizedPrompt = prompt.trim();\n if (normalizedPrompt.length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty prompt.');\n }\n const content: TBytedanceTaskContent[] = [{ type: 'text', text: normalizedPrompt }];\n if (Array.isArray(inputImages)) {\n for (const image of inputImages) {\n const imageUrlResult = toContentImageUrl(image);\n if (!imageUrlResult.ok) {\n return imageUrlResult;\n }\n content.push({ type: 'image_url', image_url: { url: imageUrlResult.value } });\n }\n }\n return { ok: true, value: content };\n }\n}\n\nfunction buildPath(template: string, taskId: string): string {\n return template.replace('{taskId}', encodeURIComponent(taskId));\n}\n\nfunction buildInvalidRequestError(message: string): TProviderMediaResult<never> {\n return { ok: false, error: { code: 'PROVIDER_INVALID_REQUEST', message } };\n}\n\nfunction buildUpstreamError(message: string): TProviderMediaResult<never> {\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message } };\n}\n\nfunction toContentImageUrl(\n image: IInlineImageInputSource | IUriImageInputSource,\n): TProviderMediaResult<string> {\n if (image.kind === 'uri') {\n if (image.uri.trim().length === 0) {\n return buildInvalidRequestError('Image uri must be non-empty.');\n }\n return { ok: true, value: image.uri };\n }\n if (image.data.trim().length === 0) {\n return buildInvalidRequestError('Inline image data must be non-empty.');\n }\n if (image.mimeType.trim().length === 0) {\n return buildInvalidRequestError('Inline image mimeType must be non-empty.');\n }\n return { ok: true, value: `data:${image.mimeType};base64,${image.data}` };\n}\n","export const QWEN_PROVIDER_BASE_URLS = {\n singapore: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n usVirginia: 'https://dashscope-us.aliyuncs.com/compatible-mode/v1',\n beijing: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n hongKong: 'https://cn-hongkong.dashscope.aliyuncs.com/compatible-mode/v1',\n} as const;\n\nexport type TQwenProviderRegion = keyof typeof QWEN_PROVIDER_BASE_URLS;\n\nexport const QWEN_PROVIDER_RESPONSES_BASE_URLS = {\n singapore: 'https://dashscope-intl.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n usVirginia: 'https://dashscope-us.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n beijing: 'https://dashscope.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n} as const;\n\nexport type TQwenProviderResponsesRegion = keyof typeof QWEN_PROVIDER_RESPONSES_BASE_URLS;\n\nexport const DEFAULT_QWEN_PROVIDER_MODEL = 'qwen-plus';\nexport const DEFAULT_QWEN_PROVIDER_API_KEY_ENV = 'DASHSCOPE_API_KEY';\nexport const DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_QWEN_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_QWEN_PROVIDER_BASE_URL = QWEN_PROVIDER_BASE_URLS.singapore;\nexport const DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL = QWEN_PROVIDER_RESPONSES_BASE_URLS.singapore;\n\nexport const QWEN_MODEL_SOURCE_URL =\n 'https://www.alibabacloud.com/help/en/model-studio/compatibility-of-openai-with-dashscope';\nexport const QWEN_MODEL_LAST_VERIFIED_AT = '2026-05-04';\n","import type { IAssistantMessage, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type {\n IQwenBuiltInWebToolsOptions,\n IQwenResponsesFunctionTool,\n IQwenResponsesMessageInput,\n TQwenBuiltInWebToolName,\n TQwenResponsesInputItem,\n TQwenResponsesTool,\n} from './types';\n\nexport function getQwenBuiltInWebToolNames(\n options: IQwenBuiltInWebToolsOptions | undefined,\n): TQwenBuiltInWebToolName[] {\n const tools: TQwenBuiltInWebToolName[] = [];\n if (options?.webSearch === true || options?.webFetch === true) {\n tools.push('web_search');\n }\n if (options?.webFetch === true) {\n tools.push('web_extractor');\n }\n return tools;\n}\n\nexport function hasQwenBuiltInWebTools(options: IQwenBuiltInWebToolsOptions | undefined): boolean {\n return getQwenBuiltInWebToolNames(options).length > 0;\n}\n\nexport function convertToQwenResponsesInput(\n messages: TUniversalMessage[],\n): TQwenResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\nexport function buildQwenResponsesTools(\n builtInWebTools: readonly TQwenBuiltInWebToolName[],\n localTools: IToolSchema[] | undefined,\n): TQwenResponsesTool[] | undefined {\n const tools: TQwenResponsesTool[] = [\n ...builtInWebTools.map((type) => ({ type })),\n ...convertToQwenResponsesFunctionTools(localTools),\n ];\n return tools.length > 0 ? tools : undefined;\n}\n\nfunction convertToQwenResponsesFunctionTools(\n tools: IToolSchema[] | undefined,\n): IQwenResponsesFunctionTool[] {\n return (\n tools?.map((tool) => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n })) ?? []\n );\n}\n\nfunction convertMessage(message: TUniversalMessage): TQwenResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', message.content)];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TQwenResponsesInputItem[] {\n const items: TQwenResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction createMessageInput(\n role: IQwenResponsesMessageInput['role'],\n content: string | null,\n): IQwenResponsesMessageInput {\n return {\n role,\n content: content ?? '',\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done) break;\n if (signal?.aborted) break;\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) return iterator.next();\n if (signal.aborted) return { done: true, value: undefined as T };\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { IToolCall, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type {\n IQwenResponsesFunctionCallOutputItem,\n IQwenResponsesErrorEvent,\n IQwenResponsesResponse,\n IQwenResponsesUsage,\n TQwenBuiltInWebToolName,\n TQwenResponsesOutputItem,\n TQwenResponsesStreamEvent,\n} from './types';\nimport { streamWithAbort } from './responses-stream-utils';\n\ninterface IQwenResponsesParseOptions {\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[];\n}\n\ninterface IQwenResponsesStreamAssemblyOptions extends IQwenResponsesParseOptions {\n stream: AsyncIterable<TQwenResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IQwenProviderToolUsage {\n webSearchCalls: number;\n webExtractorCalls: number;\n unsupportedToolTypes: Set<string>;\n}\n\ninterface IQwenResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IQwenResponsesResponse;\n usage: IQwenProviderToolUsage;\n}\n\nexport function parseQwenResponsesResponse(\n response: IQwenResponsesResponse,\n options: IQwenResponsesParseOptions,\n): TUniversalMessage {\n const output = response.output ?? [];\n const usage = collectProviderToolUsage(output, response.usage);\n const toolCalls = extractFunctionToolCalls(output);\n const content = response.output_text ?? extractMessageText(output);\n\n return buildAssistantMessage({\n content,\n toolCalls,\n response,\n usage,\n enabledBuiltInTools: options.enabledBuiltInTools,\n });\n}\n\nexport async function assembleQwenResponsesStream(\n options: IQwenResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IQwenResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n usage: createEmptyToolUsage(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state, options.enabledBuiltInTools);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n usage: state.usage,\n enabledBuiltInTools: options.enabledBuiltInTools,\n });\n}\n\nfunction applyStreamEvent(\n state: IQwenResponsesStreamState,\n event: TQwenResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeToolUsage(\n state.usage,\n collectProviderToolUsage(event.response.output ?? [], event.response.usage),\n );\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (event.type === 'response.web_search_call.completed') {\n state.usage.webSearchCalls += 1;\n return;\n }\n\n if (event.type === 'response.error' || event.type === 'response.failed') {\n throw new Error(`Qwen Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction buildMessageFromCompletedResponse(\n state: IQwenResponsesStreamState,\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[],\n): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('Qwen Responses stream completed without response metadata');\n }\n\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const usage = collectProviderToolUsage(output, response.usage);\n mergeToolUsage(usage, state.usage);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n usage,\n enabledBuiltInTools,\n });\n}\n\nfunction applyOutputItem(state: IQwenResponsesStreamState, item: TQwenResponsesOutputItem): void {\n if (item.type === 'function_call') {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n }\n return;\n }\n mergeToolUsage(state.usage, collectProviderToolUsage([item], undefined));\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IQwenResponsesResponse;\n usage: IQwenProviderToolUsage;\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[];\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && {\n usage: {\n promptTokens: input.response.usage.input_tokens ?? 0,\n completionTokens: input.response.usage.output_tokens ?? 0,\n totalTokens: input.response.usage.total_tokens ?? 0,\n },\n }),\n metadata: buildProviderToolMetadata(input.enabledBuiltInTools, input.usage, input.response),\n };\n}\n\nfunction buildProviderToolMetadata(\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[],\n usage: IQwenProviderToolUsage,\n response: IQwenResponsesResponse | undefined,\n): NonNullable<TUniversalMessage['metadata']> {\n const usedTools = collectUsedToolNames(usage);\n return {\n providerToolMode: 'qwen_responses',\n providerBuiltInToolsEnabled: [...enabledBuiltInTools],\n ...(usedTools.length > 0 && { providerBuiltInToolsUsed: usedTools }),\n qwenWebSearchCalls: usage.webSearchCalls,\n qwenWebExtractorCalls: usage.webExtractorCalls,\n ...(usage.unsupportedToolTypes.size > 0 && {\n qwenUnsupportedProviderToolTypes: [...usage.unsupportedToolTypes].sort(),\n }),\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n };\n}\n\nfunction collectUsedToolNames(usage: IQwenProviderToolUsage): TQwenBuiltInWebToolName[] {\n const used: TQwenBuiltInWebToolName[] = [];\n if (usage.webSearchCalls > 0) {\n used.push('web_search');\n }\n if (usage.webExtractorCalls > 0) {\n used.push('web_extractor');\n }\n return used;\n}\n\nfunction collectProviderToolUsage(\n output: readonly TQwenResponsesOutputItem[],\n responseUsage: IQwenResponsesUsage | undefined,\n): IQwenProviderToolUsage {\n const usage = createEmptyToolUsage();\n for (const item of output) {\n if (item.type === 'web_search_call') {\n usage.webSearchCalls += 1;\n } else if (item.type === 'web_extractor_call') {\n usage.webExtractorCalls += 1;\n } else if (isProviderToolOutput(item.type)) {\n usage.unsupportedToolTypes.add(item.type);\n }\n }\n applyUsageCounts(usage, responseUsage);\n return usage;\n}\n\nfunction applyUsageCounts(\n usage: IQwenProviderToolUsage,\n responseUsage: IQwenResponsesUsage | undefined,\n): void {\n const xTools = responseUsage?.x_tools;\n if (xTools === undefined) {\n return;\n }\n usage.webSearchCalls = Math.max(usage.webSearchCalls, xTools['web_search']?.count ?? 0);\n usage.webExtractorCalls = Math.max(usage.webExtractorCalls, xTools['web_extractor']?.count ?? 0);\n for (const toolName of Object.keys(xTools)) {\n if (toolName !== 'web_search' && toolName !== 'web_extractor') {\n usage.unsupportedToolTypes.add(toolName);\n }\n }\n}\n\nfunction mergeToolUsage(target: IQwenProviderToolUsage, source: IQwenProviderToolUsage): void {\n target.webSearchCalls = Math.max(target.webSearchCalls, source.webSearchCalls);\n target.webExtractorCalls = Math.max(target.webExtractorCalls, source.webExtractorCalls);\n for (const toolType of source.unsupportedToolTypes) {\n target.unsupportedToolTypes.add(toolType);\n }\n}\n\nfunction createEmptyToolUsage(): IQwenProviderToolUsage {\n return {\n webSearchCalls: 0,\n webExtractorCalls: 0,\n unsupportedToolTypes: new Set(),\n };\n}\n\nfunction isProviderToolOutput(type: string): boolean {\n return type.endsWith('_call') && type !== 'function_call';\n}\n\nfunction extractFunctionToolCalls(output: readonly TQwenResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TQwenResponsesOutputItem,\n): item is IQwenResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IQwenResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TQwenResponsesOutputItem[]): string {\n return output\n .filter((item): item is Extract<TQwenResponsesOutputItem, { type: 'message' }> => {\n return item.type === 'message';\n })\n .flatMap((item) => item.content)\n .map((part) => part.text)\n .join('');\n}\n\nfunction extractErrorMessage(event: IQwenResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\nimport type OpenAI from 'openai';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport {\n observeProviderNativeRawPayloadStream,\n type IOpenAICompatibleError,\n} from '../shared/openai-compatible/index.js';\nimport {\n buildQwenResponsesTools,\n convertToQwenResponsesInput,\n getQwenBuiltInWebToolNames,\n} from './responses-converter';\nimport { assembleQwenResponsesStream, parseQwenResponsesResponse } from './responses-parser';\nimport type {\n IQwenBuiltInWebToolsOptions,\n IQwenResponsesRequestNonStreaming,\n IQwenResponsesRequestStreaming,\n TQwenResponsesStreamEvent,\n} from './types';\n\nexport interface IQwenResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n defaultModel?: string;\n builtInWebTools?: IQwenBuiltInWebToolsOptions;\n onTextDelta?: TTextDeltaCallback;\n}\n\nexport async function chatWithQwenResponsesApi(\n input: IQwenResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithQwenResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return parseQwenResponsesResponse(response, {\n enabledBuiltInTools: getQwenBuiltInWebToolNames(input.builtInWebTools),\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen Responses API request failed';\n throw new Error(`Qwen responses failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithQwenResponsesApi(\n input: IQwenResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const deltas: TUniversalMessage[] = [];\n const result = await chatWithQwenResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n input.chatOptions?.onTextDelta?.(delta);\n deltas.push(createStreamDeltaMessage(delta));\n },\n },\n });\n\n for (const delta of deltas) {\n yield delta;\n }\n yield {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nasync function chatWithQwenResponsesStreamingAssembly(\n input: IQwenResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n return assembleQwenResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TQwenResponsesStreamEvent>,\n {\n provider: 'qwen',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n enabledBuiltInTools: getQwenBuiltInWebToolNames(input.builtInWebTools),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen Responses streaming request failed';\n throw new Error(`Qwen responses stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IQwenResponsesChatOptions,\n): IQwenResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const enabledBuiltInTools = getQwenBuiltInWebToolNames(input.builtInWebTools);\n const tools = buildQwenResponsesTools(enabledBuiltInTools, input.chatOptions?.tools);\n\n return {\n model,\n input: convertToQwenResponsesInput(input.messages),\n ...(tools !== undefined && { tools }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(input.builtInWebTools?.enableThinking !== undefined && {\n enable_thinking: input.builtInWebTools.enableThinking,\n }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IQwenResponsesChatOptions,\n): IQwenResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n","import type { IProviderCapabilities } from '@robota-sdk/agent-core';\nimport type { IQwenProviderOptions } from './types';\n\nconst QWEN_RESPONSES_SOURCE = 'qwen-responses';\nconst ENABLE_WEB_SEARCH_REASON = 'Enable builtInWebTools.webSearch or builtInWebTools.webFetch.';\nconst ENABLE_WEB_FETCH_REASON = 'Enable builtInWebTools.webFetch.';\n\nexport function getQwenProviderCapabilities(options: IQwenProviderOptions): IProviderCapabilities {\n const webTools = options.builtInWebTools;\n const webSearchEnabled = webTools?.webSearch === true || webTools?.webFetch === true;\n const webFetchEnabled = webTools?.webFetch === true;\n\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: webSearchEnabled\n ? { supported: true, enabled: true, source: QWEN_RESPONSES_SOURCE }\n : {\n supported: true,\n enabled: false,\n source: QWEN_RESPONSES_SOURCE,\n reason: ENABLE_WEB_SEARCH_REASON,\n },\n webFetch: webFetchEnabled\n ? { supported: true, enabled: true, source: QWEN_RESPONSES_SOURCE }\n : {\n supported: true,\n enabled: false,\n source: QWEN_RESPONSES_SOURCE,\n reason: ENABLE_WEB_FETCH_REASON,\n },\n },\n };\n}\n","import OpenAI from 'openai';\nimport type { IChatOptions, TUniversalMessage } from '@robota-sdk/agent-core';\nimport {\n assembleOpenAICompatibleStream,\n observeProviderNativeRawPayloadStream,\n} from '../shared/openai-compatible/index.js';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\n\nexport async function qwenChatWithStreamingAssembly(\n client: OpenAI,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n): Promise<TUniversalMessage> {\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n options.signal ? { signal: options.signal } : undefined,\n );\n\n return assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'qwen',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen streaming request failed';\n throw new Error(`Qwen stream failed: ${errorMessage}`);\n }\n}\n","import OpenAI from 'openai';\nimport { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n OpenAICompatibleResponseParser,\n} from '../shared/openai-compatible/index.js';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport {\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n} from './defaults';\nimport { hasQwenBuiltInWebTools } from './responses-converter';\nimport { chatStreamWithQwenResponsesApi, chatWithQwenResponsesApi } from './responses-chat';\nimport { getQwenProviderCapabilities } from './provider-capabilities';\nimport { qwenChatWithStreamingAssembly } from './provider-streaming-assembly';\nimport type { IQwenProviderOptions } from './types';\n\nexport class QwenProvider extends AbstractAIProvider {\n override readonly name = 'qwen';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly responsesClient?: OpenAI;\n private readonly options: IQwenProviderOptions;\n private readonly responseParser: OpenAICompatibleResponseParser;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IQwenProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n this.responsesClient = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL ?? DEFAULT_QWEN_PROVIDER_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n this.responsesClient = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.responsesBaseURL ?? DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either Qwen client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAICompatibleResponseParser({ logger: this.logger });\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n return this.chatViaExecutor(messages, options);\n }\n\n if (this.shouldUseResponsesApi()) {\n return this.chatViaResponsesApi(messages, options, this.getResponsesClient());\n }\n\n return this.chatViaChatCompletions(messages, options, this.getClient());\n }\n\n private async chatViaExecutor(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): Promise<TUniversalMessage> {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Qwen Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n private async chatViaResponsesApi(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n client: OpenAI,\n ): Promise<TUniversalMessage> {\n this.validateTools(options?.tools);\n return chatWithQwenResponsesApi({\n client,\n messages,\n chatOptions: options,\n defaultModel: this.options.defaultModel,\n builtInWebTools: this.options.builtInWebTools,\n onTextDelta: this.onTextDelta,\n });\n }\n\n private async chatViaChatCompletions(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n client: OpenAI,\n ): Promise<TUniversalMessage> {\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return qwenChatWithStreamingAssembly(\n client,\n { ...requestParams, stream: true },\n { ...options, onTextDelta: textDeltaCb },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(requestParams);\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return this.responseParser.parseResponse(response);\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen API request failed';\n throw new Error(`Qwen chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Qwen Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Qwen client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n if (this.shouldUseResponsesApi()) {\n this.validateTools(options?.tools);\n yield* chatStreamWithQwenResponsesApi({\n client: this.responsesClient,\n messages,\n chatOptions: options,\n defaultModel: this.options.defaultModel,\n builtInWebTools: this.options.builtInWebTools,\n onTextDelta: this.onTextDelta,\n });\n return;\n }\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(requestParams);\n\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'qwen',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n const universalMessage = this.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen API request failed';\n throw new Error(`Qwen stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities() {\n return getQwenProviderCapabilities(this.options);\n }\n\n override validateConfig(): boolean {\n return (\n !!this.client && !!this.options && (!this.shouldUseResponsesApi() || !!this.responsesClient)\n );\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible Qwen clients do not need explicit cleanup.\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n this.validateTools(options?.tools);\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams = {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n };\n\n return requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n } as OpenAI.Chat.ChatCompletionCreateParamsStreaming;\n }\n\n private shouldUseResponsesApi(): boolean {\n return hasQwenBuiltInWebTools(this.options.builtInWebTools);\n }\n\n private getClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'Qwen client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n return this.client;\n }\n\n private getResponsesClient(): OpenAI {\n if (!this.responsesClient) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n return this.responsesClient;\n }\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport {\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n QWEN_MODEL_LAST_VERIFIED_AT,\n QWEN_MODEL_SOURCE_URL,\n} from './defaults';\n\nexport interface IQwenModelsResponse {\n data?: Array<{\n id?: string;\n object?: string;\n owned_by?: string;\n }>;\n}\n\nexport interface IQwenFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IQwenFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IQwenModelsResponse>;\n}\n\nexport type TQwenFetch = (url: string, init?: IQwenFetchInit) => Promise<IQwenFetchResponse>;\n\nexport async function refreshQwenModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TQwenFetch = defaultQwenFetch,\n): Promise<IProviderModelCatalog> {\n const baseURL = trimTrailingSlash(profile.baseURL ?? DEFAULT_QWEN_PROVIDER_BASE_URL);\n const url = `${baseURL}/models`;\n const response = await fetcher(url, buildFetchInit(profile.apiKey));\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n message: `Qwen model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n entries,\n message: `Loaded ${entries.length} models from Qwen API`,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IQwenFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n };\n}\n\nfunction toModelCatalogEntry(id: string): IProviderModelCatalogEntry {\n return {\n id,\n displayName: id,\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/, '');\n}\n\nasync function defaultQwenFetch(url: string, init?: IQwenFetchInit): Promise<IQwenFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IQwenModelsResponse>,\n };\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\nimport { QwenProvider } from './provider';\nimport {\n DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_MODEL,\n QWEN_MODEL_LAST_VERIFIED_AT,\n QWEN_MODEL_SOURCE_URL,\n} from './defaults';\nimport type { IQwenBuiltInWebToolsOptions } from './types';\nimport { refreshQwenModelCatalog } from './model-catalog-refresh';\n\nconst QWEN_API_KEY_URL = 'https://modelstudio.console.alibabacloud.com/?tab=api#/api-key';\nconst QWEN_SETUP_SOURCE_URL = 'https://www.alibabacloud.com/help/en/model-studio/get-api-key';\nconst QWEN_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst QWEN_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Alibaba Cloud Model Studio API keys',\n url: QWEN_API_KEY_URL,\n sourceUrl: QWEN_SETUP_SOURCE_URL,\n lastVerifiedAt: QWEN_SETUP_LAST_VERIFIED_AT,\n },\n];\nconst QWEN_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_QWEN_PROVIDER_MODEL,\n displayName: 'Qwen Plus',\n capabilities: ['tools', 'reasoning', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'qwen-max',\n displayName: 'Qwen Max',\n capabilities: ['tools', 'reasoning', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'qwen-flash',\n displayName: 'Qwen Flash',\n capabilities: ['tools', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n ],\n};\n\nexport {\n DEFAULT_QWEN_PROVIDER_API_KEY_ENV,\n DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_MODEL,\n DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n QWEN_PROVIDER_BASE_URLS,\n QWEN_PROVIDER_RESPONSES_BASE_URLS,\n} from './defaults';\nexport type { TQwenProviderRegion, TQwenProviderResponsesRegion } from './defaults';\n\nexport function createQwenProviderDefinition(): IProviderDefinition {\n return {\n type: 'qwen',\n displayName: 'Qwen',\n description: 'Alibaba Cloud Model Studio OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_QWEN_PROVIDER_MODEL,\n apiKey: DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n baseURL: DEFAULT_QWEN_PROVIDER_BASE_URL,\n },\n modelCatalog: QWEN_MODEL_CATALOG,\n refreshModelCatalog: ({ profile }) => refreshQwenModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n setupHelpLinks: QWEN_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'Qwen OpenAI-compatible base URL',\n defaultValue: DEFAULT_QWEN_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'Qwen model',\n defaultValue: DEFAULT_QWEN_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Qwen Model Studio API key',\n defaultValue: DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n createProvider: (config) => {\n const qwenOptions = parseQwenProviderOptions(config.options);\n return new QwenProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(qwenOptions.responsesBaseURL !== undefined && {\n responsesBaseURL: qwenOptions.responsesBaseURL,\n }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(qwenOptions.builtInWebTools !== undefined && {\n builtInWebTools: qwenOptions.builtInWebTools,\n }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider qwen requires apiKey');\n }\n return apiKey;\n}\n\nfunction parseQwenProviderOptions(options: Record<string, TUniversalValue> | undefined): {\n responsesBaseURL?: string;\n builtInWebTools?: IQwenBuiltInWebToolsOptions;\n} {\n const builtInWebTools = parseBuiltInWebTools(asRecord(options?.['builtInWebTools']));\n const responsesBaseURL = asString(options?.['responsesBaseURL']);\n return {\n ...(responsesBaseURL !== undefined && { responsesBaseURL }),\n ...(builtInWebTools !== undefined && { builtInWebTools }),\n };\n}\n\nfunction parseBuiltInWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IQwenBuiltInWebToolsOptions | undefined {\n if (options === undefined) {\n return undefined;\n }\n return {\n ...(asBoolean(options['webSearch']) !== undefined && {\n webSearch: asBoolean(options['webSearch']),\n }),\n ...(asBoolean(options['webFetch']) !== undefined && {\n webFetch: asBoolean(options['webFetch']),\n }),\n ...(asBoolean(options['enableThinking']) !== undefined && {\n enableThinking: asBoolean(options['enableThinking']),\n }),\n };\n}\n\nfunction asRecord(value: TUniversalValue | undefined): Record<string, TUniversalValue> | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n return typeof value === 'object' ? value : undefined;\n}\n\nfunction asBoolean(value: TUniversalValue | undefined): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction asString(value: TUniversalValue | undefined): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["toolMsg","streamWithAbort","buildFetchInit","convertMessage","convertAssistantMessage","exhaustive","streamWithAbort","projectText","nextStreamItem","openaiError","assembleOpenAIStream","convertMessage","createMessageInput","convertAssistantMessage","streamWithAbort","nextStreamItem","buildAssistantMessage","extractMessageText","extractFunctionToolCalls","streamWithAbort","buildMessageFromCompletedResponse","applyStreamEvent","extractErrorMessage","applyOutputItem","isFunctionCallOutputItem","convertFunctionCall","buildResponsesRequestParams","openaiError","createStreamDeltaMessage","buildResponsesStreamingRequestParams","exhaustive","requireApiKey","deepSeekError","trimTrailingSlash","buildFetchInit","toModelCatalogEntry","requireApiKey","asRecord","convertAssistantMessage","requireApiKey","toModelCatalogEntry","projectText","appendVisibleTail","longestStartMarkerPrefixSuffixLength","DEFAULT_CALL_ID_PREFIX","createProjectionState","appendVisibleTail","gemmaError","requireApiKey","qwenError","qwenError","qwenError"],"sources":["../../src/anthropic/message-converter.ts","../../src/anthropic/streaming-handler.ts","../../src/anthropic/provider.ts","../../src/anthropic/model-catalog-refresh.ts","../../src/anthropic/provider-definition.ts","../../src/anthropic/index.ts","../../src/shared/openai-compatible/message-converter.ts","../../src/shared/openai-compatible/response-parser.ts","../../src/shared/openai-compatible/stream-assembler.ts","../../src/shared/openai-compatible/native-payload-observer.ts","../../src/shared/openai-compatible/endpoint-probe.ts","../../src/openai/message-converter.ts","../../src/openai/openai-request-format.ts","../../src/openai/chat-completions-chat.ts","../../src/openai/parsers/response-parser.ts","../../src/openai/responses-converter.ts","../../src/openai/responses-stream-utils.ts","../../src/openai/responses-parser.ts","../../src/openai/responses-chat.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/model-catalog-refresh.ts","../../src/openai/provider-definition.ts","../../src/deepseek/defaults.ts","../../src/deepseek/provider.ts","../../src/deepseek/model-catalog.ts","../../src/deepseek/model-catalog-refresh.ts","../../src/deepseek/provider-definition.ts","../../src/gemini/image-operations.ts","../../src/gemini/request-converter.ts","../../src/gemini/tool-schema-converter.ts","../../src/gemini/message-converter.ts","../../src/gemini/execution-helpers.ts","../../src/gemini/provider.ts","../../src/gemini/provider-definition.ts","../../src/gemini/model-catalog-refresh.ts","../../src/gemma/reasoning-projector.ts","../../src/gemma/pseudo-tool-call-tag-parser.ts","../../src/gemma/pseudo-command-envelope.ts","../../src/gemma/pseudo-tool-call-projector.ts","../../src/gemma/tool-call-argument-parser.ts","../../src/gemma/tool-call-projector.ts","../../src/gemma/provider-projection.ts","../../src/gemma/message-factory.ts","../../src/gemma/streaming-projection.ts","../../src/gemma/provider.ts","../../src/gemma/provider-definition.ts","../../src/bytedance/http-client.ts","../../src/bytedance/status-mapper.ts","../../src/bytedance/provider.ts","../../src/qwen/defaults.ts","../../src/qwen/provider-capabilities.ts","../../src/qwen/provider-streaming-assembly.ts","../../src/qwen/responses-converter.ts","../../src/qwen/responses-stream-utils.ts","../../src/qwen/responses-parser.ts","../../src/qwen/responses-chat.ts","../../src/qwen/provider.ts","../../src/qwen/model-catalog-refresh.ts","../../src/qwen/provider-definition.ts","../../src/default-provider-definitions.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type Anthropic from '@anthropic-ai/sdk';\nimport type {\n TUniversalMessage,\n IToolSchema,\n IAssistantMessage,\n IToolMessage,\n} from '@robota-sdk/agent-core';\n\n/**\n * Convert TUniversalMessage array to Anthropic message format.\n *\n * CRITICAL: Anthropic API requires specific content handling:\n * - tool_use messages: content MUST be null\n * - regular messages: content should be a string\n */\nexport function convertToAnthropicFormat(messages: TUniversalMessage[]): Anthropic.MessageParam[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n content: msg.content || '',\n };\n } else if (msg.role === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Anthropic uses content blocks — include both text and tool_use\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const contentBlocks: Array<Anthropic.TextBlockParam | Anthropic.ToolUseBlockParam> = [];\n\n // Include text content if present alongside tool calls\n if (assistantMsg.content) {\n contentBlocks.push({\n type: 'text' as const,\n text: assistantMsg.content,\n });\n }\n\n for (const tc of assistantMsg.toolCalls) {\n contentBlocks.push({\n type: 'tool_use' as const,\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n });\n }\n\n return {\n role: 'assistant' as const,\n content: contentBlocks,\n };\n }\n\n // Regular assistant message (no tool calls)\n return {\n role: 'assistant',\n content: assistantMsg.content || '',\n };\n } else if (msg.role === 'tool') {\n // Tool result message — convert to Anthropic tool_result content block\n const toolMsg = msg as IToolMessage;\n return {\n role: 'user' as const,\n content: [\n {\n type: 'tool_result' as const,\n tool_use_id: toolMsg.toolCallId ?? '',\n content: msg.content || '',\n },\n ],\n };\n } else {\n // System messages\n return {\n role: 'user', // Anthropic doesn't have system role, use user\n content: msg.content || '',\n };\n }\n });\n}\n\n/**\n * Convert Anthropic response to TUniversalMessage.\n *\n * Anthropic responses can contain multiple content blocks:\n * e.g., [text(\"I'll read the file\"), tool_use(Read, {...}), tool_use(Bash, {...})]\n * We must extract ALL text and ALL tool_use blocks.\n */\nexport function convertFromAnthropicResponse(response: Anthropic.Message): TUniversalMessage {\n if (!response.content || response.content.length === 0) {\n throw new Error('No content in Anthropic response');\n }\n\n const textParts: string[] = [];\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n\n for (const block of response.content) {\n if (block.type === 'text') {\n const textBlock = block as Anthropic.TextBlock;\n if (textBlock.text) {\n textParts.push(textBlock.text);\n }\n } else if (block.type === 'tool_use') {\n const toolBlock = block as Anthropic.ToolUseBlock;\n toolCalls.push({\n id: toolBlock.id,\n type: 'function' as const,\n function: {\n name: toolBlock.name,\n arguments: JSON.stringify(toolBlock.input),\n },\n });\n } else if (block.type === 'server_tool_use') {\n // Server tool invocation (e.g., web_search) — results come in a separate block\n } else if (block.type === 'web_search_tool_result') {\n const resultBlock = block as Anthropic.Messages.WebSearchToolResultBlock;\n const searchResults = formatWebSearchResults(resultBlock);\n if (searchResults) {\n textParts.push(searchResults);\n }\n }\n }\n\n // Use empty string instead of null so agent-core's buildFinalResult\n // doesn't reject the message. Tool-only responses have no text.\n const textContent = textParts.join('\\n') || '';\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: textContent,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n\n // Add metadata if available\n if (response.usage) {\n result.metadata = {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n model: response.model,\n };\n\n if (response.stop_reason) {\n result.metadata['stopReason'] = response.stop_reason;\n }\n }\n\n return result;\n}\n\n/** Format a WebSearchToolResultBlock into readable text. */\nexport function formatWebSearchResults(block: Anthropic.Messages.WebSearchToolResultBlock): string {\n if (!Array.isArray(block.content)) return '';\n\n const results = block.content\n .filter(\n (r): r is Anthropic.Messages.WebSearchResultBlock =>\n r.type === 'web_search_result' && 'title' in r && 'url' in r,\n )\n .map((r, i) => `${i + 1}. ${r.title}\\n ${r.url}`)\n .join('\\n');\n\n return results ? `[Web Search Results]\\n${results}` : '';\n}\n\n/**\n * Convert tool schemas to Anthropic format.\n */\nexport function convertToolsToAnthropicFormat(tools: IToolSchema[]): Anthropic.Tool[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.parameters as Anthropic.Tool.InputSchema,\n }));\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { formatWebSearchResults } from './message-converter';\n\nimport type Anthropic from '@anthropic-ai/sdk';\nimport type {\n TProviderNativeRawPayloadCallback,\n TUniversalMessage,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\n\n/**\n * Stream the Anthropic API response and assemble a complete TUniversalMessage.\n *\n * Calls onTextDelta for each text chunk as it arrives.\n * Returns the fully assembled TUniversalMessage when the stream is done.\n */\nexport async function streamAndAssemble(\n client: Anthropic,\n params: Anthropic.MessageCreateParamsNonStreaming,\n onTextDelta: TTextDeltaCallback,\n onServerToolUse: ((toolName: string, input: Record<string, string>) => void) | undefined,\n signal: AbortSignal | undefined,\n onProviderNativeRawPayload?: TProviderNativeRawPayloadCallback,\n): Promise<TUniversalMessage> {\n const streamParams: Anthropic.MessageCreateParamsStreaming = {\n ...params,\n stream: true,\n };\n\n onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'request',\n payload: streamParams,\n });\n const stream = await client.messages.create(streamParams, signal ? { signal } : undefined);\n\n // Accumulate the full response from stream events\n const textParts: string[] = [];\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n let currentToolId = '';\n let currentToolName = '';\n let currentToolJson = '';\n let usage = { input_tokens: 0, output_tokens: 0 };\n let model = '';\n let stopReason: string | null = null;\n\n try {\n let sequence = 0;\n for await (const event of streamWithAbort(stream, signal)) {\n onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'stream_event',\n sequence,\n payload: event,\n });\n sequence++;\n switch (event.type) {\n case 'message_start':\n usage = event.message.usage;\n model = event.message.model;\n break;\n\n case 'content_block_start':\n if (event.content_block.type === 'tool_use') {\n currentToolId = event.content_block.id;\n currentToolName = event.content_block.name;\n currentToolJson = '';\n } else if (event.content_block.type === 'server_tool_use') {\n const serverBlock = event.content_block as {\n name?: string;\n input?: { query?: string };\n };\n const query = serverBlock.input?.query ?? '';\n const toolLabel = query\n ? `\\n🔍 Searching: \"${query}\"\\n`\n : `\\n🔍 [${serverBlock.name ?? 'server_tool'}]\\n`;\n textParts.push(toolLabel);\n onTextDelta(toolLabel);\n if (onServerToolUse) {\n onServerToolUse(serverBlock.name ?? 'server_tool', { query });\n }\n } else if (event.content_block.type === 'web_search_tool_result') {\n const resultBlock = event.content_block as Anthropic.Messages.WebSearchToolResultBlock;\n const formatted = formatWebSearchResults(resultBlock);\n if (formatted) {\n textParts.push(`\\n${formatted}\\n\\n`);\n onTextDelta(`\\n${formatted}\\n\\n`);\n }\n }\n break;\n\n case 'content_block_delta':\n if (event.delta.type === 'text_delta') {\n textParts.push(event.delta.text);\n onTextDelta(event.delta.text);\n } else if (event.delta.type === 'input_json_delta') {\n currentToolJson += event.delta.partial_json;\n }\n break;\n\n case 'content_block_stop':\n if (currentToolId) {\n toolCalls.push({\n id: currentToolId,\n type: 'function' as const,\n function: {\n name: currentToolName,\n arguments: currentToolJson || '{}',\n },\n });\n currentToolId = '';\n currentToolName = '';\n currentToolJson = '';\n }\n break;\n\n case 'message_delta':\n if (event.usage) {\n usage.output_tokens = event.usage.output_tokens;\n }\n stopReason = event.delta.stop_reason;\n break;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return buildPartialResult(textParts, toolCalls, usage, model);\n }\n throw err;\n }\n\n // If aborted via break (not via catch), return partial response\n if (signal?.aborted) {\n return buildPartialResult(textParts, toolCalls, usage, model);\n }\n\n const textContent = textParts.join('') || '';\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: textContent,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n\n result.metadata = {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n model,\n };\n if (stopReason) {\n result.metadata['stopReason'] = stopReason;\n }\n\n return result;\n}\n\nfunction buildPartialResult(\n textParts: string[],\n toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }>,\n usage: { input_tokens: number; output_tokens: number },\n model: string,\n): TUniversalMessage {\n const partialText = textParts.join('') || '';\n const partialResult: TUniversalMessage = {\n id: randomUUID(),\n role: 'assistant',\n content: partialText,\n state: 'complete' as const,\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n };\n partialResult.metadata = {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n model,\n stopReason: 'aborted',\n };\n return partialResult;\n}\n\n/**\n * Wrap a stream to support abort signal interruption.\n */\nasync function* streamWithAbort(\n stream: AsyncIterable<Anthropic.MessageStreamEvent>,\n signal?: AbortSignal,\n): AsyncIterable<Anthropic.MessageStreamEvent> {\n for await (const event of stream) {\n if (signal?.aborted) break;\n yield event;\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport { AbstractAIProvider, getModelMaxOutput } from '@robota-sdk/agent-core';\n\nimport { convertToAnthropicFormat, convertToolsToAnthropicFormat } from './message-converter';\nimport { streamAndAssemble } from './streaming-handler';\n\nimport type { IAnthropicProviderOptions } from './types';\nimport type {\n IProviderCapabilities,\n IProviderNativeWebToolRequest,\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\n\n/**\n * Anthropic provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Anthropic API:\n * - When tool_calls are present: content MUST be null (not empty string)\n * - For regular assistant messages: content should be a string\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class AnthropicProvider extends AbstractAIProvider {\n override readonly name = 'anthropic';\n override readonly version = '1.0.0';\n\n private readonly client?: Anthropic;\n private readonly options: IAnthropicProviderOptions;\n\n /**\n * When true, Anthropic server tools (web_search) are included in every request.\n * The server executes these tools internally — no local tool registration needed.\n */\n enableWebTools = false;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n /** Callback when a server tool (web_search etc.) is invoked by the API */\n onServerToolUse?: (toolName: string, input: Record<string, string>) => void;\n\n constructor(options: IAnthropicProviderOptions) {\n super();\n this.options = options;\n\n // Set executor if provided\n if (options.executor) {\n this.executor = options.executor;\n }\n\n // Only create client if not using executor\n if (!this.executor) {\n // Create client from apiKey if not provided.\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new Anthropic({\n apiKey: options.apiKey,\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either Anthropic client, apiKey, or executor is required');\n }\n }\n }\n\n /**\n * Generate response using TUniversalMessage\n */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n // Use executor when configured; otherwise use direct execution\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n throw error;\n }\n }\n\n // Direct execution with Anthropic client\n if (!this.client) {\n throw new Error(\n 'Anthropic client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n // Separate system messages for the Anthropic system parameter\n const systemMessages = messages.filter((m) => m.role === 'system');\n const nonSystemMessages = messages.filter((m) => m.role !== 'system');\n const anthropicMessages = convertToAnthropicFormat(nonSystemMessages);\n const systemPrompt = systemMessages.map((m) => m.content || '').join('\\n\\n') || undefined;\n\n if (!options?.model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const functionTools = options?.tools ? convertToolsToAnthropicFormat(options.tools) : [];\n const serverTools: Anthropic.Messages.ToolUnion[] = this.enableWebTools\n ? [{ type: 'web_search_20250305' as const, name: 'web_search' }]\n : [];\n const allTools: Anthropic.Messages.ToolUnion[] = [...functionTools, ...serverTools];\n\n const baseParams: Anthropic.MessageCreateParamsNonStreaming = {\n model: options.model as string,\n messages: anthropicMessages,\n max_tokens: options?.maxTokens || getModelMaxOutput(options.model as string),\n ...(systemPrompt && { system: systemPrompt }),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(allTools.length > 0 && { tools: allTools }),\n };\n\n // Always use streaming to avoid Anthropic SDK's 10-minute non-streaming timeout.\n // When no onTextDelta callback is available, use a no-op to silently assemble the response.\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta ?? (() => {});\n return streamAndAssemble(\n this.client,\n baseParams,\n textDeltaCb,\n this.onServerToolUse,\n options?.signal,\n options?.onProviderNativeRawPayload,\n );\n }\n\n /**\n * Generate streaming response using TUniversalMessage\n */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n // Use executor when configured; otherwise use direct execution\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n throw error;\n }\n }\n\n // Direct execution with Anthropic client\n if (!this.client) {\n throw new Error(\n 'Anthropic client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n const anthropicMessages = convertToAnthropicFormat(messages);\n\n if (!options?.model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams: Anthropic.MessageCreateParamsStreaming = {\n model: options.model as string,\n messages: anthropicMessages,\n max_tokens: options?.maxTokens || getModelMaxOutput(options.model as string),\n stream: true,\n };\n\n if (options?.temperature !== undefined) {\n requestParams.temperature = options.temperature;\n }\n\n const functionTools = options?.tools ? convertToolsToAnthropicFormat(options.tools) : [];\n const serverTools: Anthropic.Messages.ToolUnion[] = this.enableWebTools\n ? [{ type: 'web_search_20250305' as const, name: 'web_search' }]\n : [];\n const allTools: Anthropic.Messages.ToolUnion[] = [...functionTools, ...serverTools];\n\n if (allTools.length > 0) {\n requestParams.tools = allTools;\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.messages.create(requestParams);\n\n let sequence = 0;\n for await (const chunk of stream) {\n options?.onProviderNativeRawPayload?.({\n provider: 'anthropic',\n apiSurface: 'anthropic-messages',\n payloadKind: 'stream_event',\n sequence,\n payload: chunk,\n });\n sequence++;\n if (chunk.type === 'content_block_delta' && chunk.delta.type === 'text_delta') {\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: chunk.delta.text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: this.enableWebTools\n ? { supported: true, enabled: true, source: 'anthropic-messages' }\n : {\n supported: true,\n enabled: false,\n source: 'anthropic-messages',\n reason: 'Call configureNativeWebTools({ webSearch: true }) or set enableWebTools.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'anthropic-messages',\n reason: 'Anthropic provider exposes server web search only.',\n },\n },\n };\n }\n\n configureNativeWebTools(request: IProviderNativeWebToolRequest): IProviderCapabilities {\n if (request.webSearch === true) {\n this.enableWebTools = true;\n }\n this.validateNativeWebTools(request);\n return this.getCapabilities();\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Anthropic client doesn't need explicit cleanup\n }\n\n /**\n * Validate TUniversalMessage array\n */\n protected override validateMessages(messages: TUniversalMessage[]): void {\n if (!Array.isArray(messages)) {\n throw new Error('Messages must be an array');\n }\n\n if (messages.length === 0) {\n throw new Error('Messages array cannot be empty');\n }\n\n for (const message of messages) {\n if (!message.role || !['user', 'assistant', 'system', 'tool'].includes(message.role)) {\n throw new Error(`Invalid message role: ${message.role}`);\n }\n }\n }\n}\n","import {\n ANTHROPIC_MODEL_SOURCE_URL,\n ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n} from './provider-definition';\n\nimport type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nconst ANTHROPIC_MODELS_API_URL = 'https://api.anthropic.com/v1/models';\nconst ANTHROPIC_API_VERSION = '2023-06-01';\n\nexport interface IAnthropicModelsResponse {\n data?: Array<{\n id?: string;\n display_name?: string;\n type?: string;\n }>;\n has_more?: boolean;\n}\n\nexport interface IAnthropicFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IAnthropicFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IAnthropicModelsResponse>;\n}\n\nexport type TAnthropicFetch = (\n url: string,\n init?: IAnthropicFetchInit,\n) => Promise<IAnthropicFetchResponse>;\n\nexport async function refreshAnthropicModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TAnthropicFetch = defaultAnthropicFetch,\n): Promise<IProviderModelCatalog> {\n return fetchModelCatalog(profile, fetcher);\n}\n\nasync function fetchModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TAnthropicFetch,\n): Promise<IProviderModelCatalog> {\n const response = await fetcher(ANTHROPIC_MODELS_API_URL, buildFetchInit(profile.apiKey)).catch(\n (err: unknown) => {\n // allow-fallback: catalog refresh is non-terminal; callers expect IProviderModelCatalog\n const message = err instanceof Error ? err.message : String(err);\n return {\n ok: false as const,\n status: 0,\n json: (): Promise<IAnthropicModelsResponse> => Promise.resolve({ data: [] }),\n errorMessage: `Anthropic model refresh failed: ${message}`,\n };\n },\n );\n\n if ('errorMessage' in response) {\n return {\n status: 'unavailable',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n message: response.errorMessage,\n };\n }\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n message: `Anthropic model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const now = new Date().toISOString();\n const entries: IProviderModelCatalogEntry[] = (body.data ?? [])\n .filter(\n (item): item is { id: string; display_name?: string; type?: string } =>\n typeof item.id === 'string' && item.id.length > 0,\n )\n .map(\n (item): IProviderModelCatalogEntry => ({\n id: item.id,\n displayName: item.display_name ?? item.id,\n lifecycle: 'active',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: now,\n }),\n );\n\n return {\n status: 'live',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n entries,\n message: `Fetched ${entries.length} models from Anthropic API`,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IAnthropicFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': ANTHROPIC_API_VERSION,\n },\n };\n}\n\nasync function defaultAnthropicFetch(\n url: string,\n init?: IAnthropicFetchInit,\n): Promise<IAnthropicFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IAnthropicModelsResponse>,\n };\n}\n","import {\n CLAUDE_MODELS,\n type IProviderDefinition,\n type IProviderModelCatalogEntry,\n} from '@robota-sdk/agent-core';\n\nimport { refreshAnthropicModelCatalog } from './model-catalog-refresh';\nimport { AnthropicProvider } from './provider';\n\nexport const DEFAULT_ANTHROPIC_PROVIDER_MODEL = 'claude-sonnet-4-6';\nexport const DEFAULT_ANTHROPIC_PROVIDER_API_KEY_ENV = 'ANTHROPIC_API_KEY';\nexport const DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_ANTHROPIC_PROVIDER_API_KEY_ENV}`;\nexport const ANTHROPIC_MODEL_SOURCE_URL = 'https://platform.claude.com/docs/en/api/models/list';\nexport const ANTHROPIC_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst ANTHROPIC_API_KEY_URL = 'https://platform.claude.com/settings/keys';\nconst ANTHROPIC_SETUP_SOURCE_URL = 'https://platform.claude.com/docs/en/api/overview';\nconst ANTHROPIC_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst ANTHROPIC_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Anthropic API keys',\n url: ANTHROPIC_API_KEY_URL,\n sourceUrl: ANTHROPIC_SETUP_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createAnthropicProviderDefinition(): IProviderDefinition {\n return {\n type: 'anthropic',\n displayName: 'Anthropic',\n description: 'Claude models through Anthropic API',\n defaults: {\n model: DEFAULT_ANTHROPIC_PROVIDER_MODEL,\n apiKey: DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n entries: buildAnthropicModelCatalogEntries(),\n },\n setupHelpLinks: ANTHROPIC_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'apiKey',\n title: 'Anthropic API key',\n defaultValue: DEFAULT_ANTHROPIC_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n {\n key: 'model',\n title: 'Anthropic model',\n defaultValue: DEFAULT_ANTHROPIC_PROVIDER_MODEL,\n },\n ],\n refreshModelCatalog: ({ profile }) => refreshAnthropicModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n requiresApiKey: true,\n createProvider: (config) =>\n new AnthropicProvider({\n apiKey: requireAnthropicApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction buildAnthropicModelCatalogEntries(): IProviderModelCatalogEntry[] {\n const seen = new Set<string>();\n const entries: IProviderModelCatalogEntry[] = [];\n for (const model of Object.values(CLAUDE_MODELS)) {\n if (seen.has(model.name)) continue;\n seen.add(model.name);\n entries.push({\n id: model.id,\n displayName: model.name,\n contextWindow: model.contextWindow,\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'active',\n sourceUrl: ANTHROPIC_MODEL_SOURCE_URL,\n lastVerifiedAt: ANTHROPIC_MODEL_LAST_VERIFIED_AT,\n });\n }\n return entries;\n}\n\nfunction requireAnthropicApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider anthropic requires apiKey');\n }\n return apiKey;\n}\n","/**\n * @robota-sdk/agent-provider (anthropic)\n *\n * Provides Provider implementation for using Anthropic API with provider-agnostic TUniversalMessage.\n */\n\n// Main exports\nexport * from './provider';\nexport * from './types';\nexport * from './provider-definition';\nexport * from './model-catalog-refresh';\n\nimport type { IAnthropicProviderOptions } from './types';\n\n/**\n * Factory function for creating an AnthropicProvider instance.\n * @param _options - Configuration options for the Anthropic provider\n * @returns An AnthropicProvider instance\n */\nexport function createAnthropicProvider(_options: IAnthropicProviderOptions): void {\n // Implementation of createAnthropicProvider function\n}\n","import type {\n IAssistantMessage,\n IToolCall,\n IToolSchema,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport function convertToOpenAICompatibleMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return messages.map((message) => convertMessage(message));\n}\n\nexport function convertToOpenAICompatibleTools(\n tools: IToolSchema[],\n): OpenAI.Chat.ChatCompletionTool[] {\n return tools.map((tool) => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n }));\n}\n\nfunction convertMessage(message: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n if (message.role === 'user') {\n return {\n role: 'user',\n content: message.content || '',\n };\n }\n\n if (message.role === 'assistant') {\n return convertAssistantMessage(message);\n }\n\n if (message.role === 'system') {\n return {\n role: 'system',\n content: message.content || '',\n };\n }\n\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return {\n role: 'tool',\n content: message.content || '',\n tool_call_id: message.toolCallId,\n };\n }\n\n const exhaustive: never = message;\n throw new Error(`Unsupported message role: ${JSON.stringify(exhaustive)}`);\n}\n\nfunction convertAssistantMessage(\n message: IAssistantMessage,\n): OpenAI.Chat.ChatCompletionAssistantMessageParam {\n if (message.toolCalls && message.toolCalls.length > 0) {\n return {\n role: 'assistant',\n content: message.content === '' ? null : message.content || null,\n tool_calls: message.toolCalls.map((toolCall: IToolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n }\n\n return {\n role: 'assistant',\n content: message.content === null ? null : message.content || '',\n };\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { SilentLogger } from '@robota-sdk/agent-core';\n\nimport type {\n IOpenAICompatibleToolCallTextProjector,\n IOpenAICompatibleToolCallTextProjection,\n TOpenAICompatibleTextProjector,\n} from './types';\nimport type { ILogger, IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAICompatibleResponseParserOptions {\n logger?: ILogger;\n textProjector?: TOpenAICompatibleTextProjector;\n toolCallTextProjector?: IOpenAICompatibleToolCallTextProjector;\n}\n\nexport class OpenAICompatibleResponseParser {\n private readonly logger: ILogger;\n private readonly textProjector?: TOpenAICompatibleTextProjector;\n private readonly toolCallTextProjector?: IOpenAICompatibleToolCallTextProjector;\n\n constructor(options: IOpenAICompatibleResponseParserOptions = {}) {\n this.logger = options.logger ?? SilentLogger;\n this.textProjector = options.textProjector;\n this.toolCallTextProjector = options.toolCallTextProjector;\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n const choice = response.choices?.[0];\n if (!choice) {\n throw new Error('No choices found in OpenAI-compatible response');\n }\n\n return this.parseChoice(choice, response.usage);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'OpenAI-compatible response parsing failed';\n this.logger.error('Response parsing failed', { error: message });\n throw new Error(`OpenAI-compatible response parsing failed: ${message}`);\n }\n }\n\n private parseChoice(\n choice: OpenAI.Chat.ChatCompletion.Choice,\n usage: OpenAI.CompletionUsage | undefined,\n ): TUniversalMessage {\n const message = choice.message;\n const toolTextProjection = this.projectToolCallText(message.content || '');\n const toolTextFlush = this.toolCallTextProjector?.flush();\n const nativeToolCalls = this.parseNativeToolCalls(message);\n const projectedToolCalls = [\n ...toolTextProjection.toolCalls,\n ...(toolTextFlush?.toolCalls ?? []),\n ];\n const toolCalls = [...nativeToolCalls, ...projectedToolCalls];\n\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: this.projectText(\n toolTextProjection.visibleText + (toolTextFlush?.visibleText ?? ''),\n ),\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n ...(usage && { usage: this.parseUsage(usage) }),\n metadata: {\n finishReason: choice.finish_reason || undefined,\n ...this.buildToolTextMetadata(toolTextProjection, toolTextFlush),\n },\n };\n }\n\n private parseNativeToolCalls(message: OpenAI.Chat.ChatCompletionMessage): IToolCall[] {\n return (\n message.tool_calls?.map((toolCall) => ({\n id: toolCall.id,\n type: 'function' as const,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })) || []\n );\n }\n\n private parseUsage(usage: OpenAI.CompletionUsage): {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n } {\n return {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n };\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n const choice = chunk.choices?.[0];\n if (!choice) {\n return null;\n }\n\n const finishReason = choice.finish_reason;\n const toolCalls = choice.delta.tool_calls?.map((toolCall) => ({\n id: toolCall.id || '',\n type: 'function' as const,\n function: {\n name: toolCall.function?.name || '',\n arguments: toolCall.function?.arguments || '',\n },\n }));\n\n if (toolCalls) {\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n toolCalls,\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n }\n\n return {\n id: randomUUID(),\n state: 'complete',\n role: 'assistant',\n content: this.projectText(choice.delta.content || ''),\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'OpenAI-compatible chunk parsing failed';\n this.logger.error('Chunk parsing failed', { error: message });\n throw new Error(`OpenAI-compatible chunk parsing failed: ${message}`);\n }\n }\n\n private projectText(text: string): string {\n return this.textProjector ? this.textProjector(text) : text;\n }\n\n private projectToolCallText(text: string): IOpenAICompatibleToolCallTextProjection {\n return (\n this.toolCallTextProjector?.project(text) ?? {\n visibleText: text,\n toolCalls: [],\n removedToolCallText: false,\n }\n );\n }\n\n private buildToolTextMetadata(\n projection: IOpenAICompatibleToolCallTextProjection,\n flush: IOpenAICompatibleToolCallTextProjection | undefined,\n ): Record<string, string | boolean | undefined> {\n const rawToolCallText = [projection.rawToolCallText, flush?.rawToolCallText]\n .filter((text): text is string => typeof text === 'string' && text.length > 0)\n .join('');\n const removedToolCallText =\n projection.removedToolCallText || (flush?.removedToolCallText ?? false);\n\n return {\n ...(removedToolCallText && { toolCallTextProjected: true }),\n ...(rawToolCallText.length > 0 && { rawToolCallText }),\n };\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type {\n IOpenAICompatibleToolCallTextProjection,\n IOpenAICompatibleStreamAssemblyOptions,\n TOpenAICompatibleTextProjector,\n} from './types';\nimport type { IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\ninterface IToolCallPart {\n id: string;\n name: string;\n arguments: string;\n}\n\ninterface IAssemblyState {\n textParts: string[];\n toolCallParts: Map<number, IToolCallPart>;\n projectedToolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n toolCallTextProjected: boolean;\n model: string;\n finishReason: string | null;\n}\n\nexport async function assembleOpenAICompatibleStream(\n options: IOpenAICompatibleStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IAssemblyState = {\n textParts: [],\n toolCallParts: new Map(),\n projectedToolCalls: [],\n rawToolCallTextParts: [],\n toolCallTextProjected: false,\n model: '',\n finishReason: null,\n };\n\n for await (const chunk of streamWithAbort(options.stream, options.signal)) {\n applyChunk(state, chunk, options);\n }\n applyProjectedTextFlush(state, options);\n\n return buildMessage(state, options.metadata);\n}\n\nfunction applyChunk(\n state: IAssemblyState,\n chunk: OpenAI.Chat.ChatCompletionChunk,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n if (chunk.model) {\n state.model = chunk.model;\n }\n\n const choice = chunk.choices?.[0];\n if (!choice) {\n return;\n }\n\n state.finishReason = choice.finish_reason ?? state.finishReason;\n applyTextDelta(state, choice.delta.content, options);\n applyToolCallDeltas(state, choice.delta.tool_calls ?? []);\n}\n\nfunction applyTextDelta(\n state: IAssemblyState,\n content: string | null | undefined,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n if (!content) {\n return;\n }\n\n const toolProjection = projectToolCallText(content, options.toolCallTextProjector);\n applyToolCallTextProjection(state, toolProjection);\n const visibleContent = projectText(toolProjection.visibleText, options.textProjector);\n if (visibleContent.length === 0) {\n return;\n }\n\n state.textParts.push(visibleContent);\n options.onTextDelta?.(visibleContent);\n}\n\nfunction projectText(text: string, projector?: TOpenAICompatibleTextProjector): string {\n return projector ? projector(text) : text;\n}\n\nfunction applyProjectedTextFlush(\n state: IAssemblyState,\n options: IOpenAICompatibleStreamAssemblyOptions,\n): void {\n const toolProjection = options.toolCallTextProjector?.flush();\n if (toolProjection) {\n applyToolCallTextProjection(state, toolProjection);\n const visibleToolText = projectText(toolProjection.visibleText, options.textProjector);\n if (visibleToolText.length > 0) {\n state.textParts.push(visibleToolText);\n options.onTextDelta?.(visibleToolText);\n }\n }\n\n const visibleContent = options.textProjectorFlush?.();\n if (!visibleContent) {\n return;\n }\n\n state.textParts.push(visibleContent);\n options.onTextDelta?.(visibleContent);\n}\n\nfunction projectToolCallText(\n text: string,\n projector: IOpenAICompatibleStreamAssemblyOptions['toolCallTextProjector'],\n): IOpenAICompatibleToolCallTextProjection {\n return (\n projector?.project(text) ?? {\n visibleText: text,\n toolCalls: [],\n removedToolCallText: false,\n }\n );\n}\n\nfunction applyToolCallTextProjection(\n state: IAssemblyState,\n projection: IOpenAICompatibleToolCallTextProjection,\n): void {\n if (projection.toolCalls.length > 0) {\n state.projectedToolCalls.push(...projection.toolCalls);\n }\n if (projection.removedToolCallText) {\n state.toolCallTextProjected = true;\n }\n if (projection.rawToolCallText && projection.rawToolCallText.length > 0) {\n state.rawToolCallTextParts.push(projection.rawToolCallText);\n }\n}\n\nfunction applyToolCallDeltas(\n state: IAssemblyState,\n deltas: OpenAI.Chat.ChatCompletionChunk.Choice.Delta.ToolCall[],\n): void {\n for (const delta of deltas) {\n const index = delta.index ?? 0;\n const current = state.toolCallParts.get(index) ?? { id: '', name: '', arguments: '' };\n const nextName = delta.function?.name ?? current.name;\n state.toolCallParts.set(index, {\n id: delta.id ?? current.id,\n name: nextName,\n arguments: current.arguments + (delta.function?.arguments ?? ''),\n });\n }\n}\n\nfunction buildMessage(\n state: IAssemblyState,\n metadata: Record<string, string | number | boolean> = {},\n): TUniversalMessage {\n const resultMetadata: NonNullable<TUniversalMessage['metadata']> = { ...metadata };\n if (state.model) {\n resultMetadata['model'] = state.model;\n }\n if (state.finishReason) {\n resultMetadata['finishReason'] = state.finishReason;\n }\n if (state.toolCallTextProjected) {\n resultMetadata['toolCallTextProjected'] = true;\n }\n if (state.rawToolCallTextParts.length > 0) {\n resultMetadata['rawToolCallText'] = state.rawToolCallTextParts.join('');\n }\n\n const toolCalls = buildAllToolCalls(state);\n\n return {\n id: randomUUID(),\n role: 'assistant',\n content: state.textParts.join(''),\n state: 'complete',\n timestamp: new Date(),\n ...(toolCalls.length > 0 && { toolCalls }),\n ...(Object.keys(resultMetadata).length > 0 && { metadata: resultMetadata }),\n };\n}\n\nfunction buildAllToolCalls(state: IAssemblyState): IToolCall[] {\n return [...buildToolCalls(state.toolCallParts), ...state.projectedToolCalls];\n}\n\nfunction buildToolCalls(toolCallParts: Map<number, IToolCallPart>): IToolCall[] {\n return Array.from(toolCallParts.entries())\n .sort(([left], [right]) => left - right)\n .map(([index, toolCall]) => ({\n id: toolCall.id || `call_${index}`,\n type: 'function',\n function: {\n name: toolCall.name,\n arguments: toolCall.arguments || '{}',\n },\n }));\n}\n\nasync function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done) break;\n await yieldToMacrotask(signal);\n if (signal?.aborted) break;\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) return iterator.next();\n if (signal.aborted) return { done: true, value: undefined as T };\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n\nasync function yieldToMacrotask(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) return;\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n}\n","import type { TProviderNativeRawPayloadCallback } from '@robota-sdk/agent-core';\n\nexport interface IObserveProviderNativeRawPayloadStreamOptions {\n provider: string;\n apiSurface?: string;\n onProviderNativeRawPayload?: TProviderNativeRawPayloadCallback;\n initialSequence?: number;\n}\n\nexport async function* observeProviderNativeRawPayloadStream<TPayload extends object>(\n stream: AsyncIterable<TPayload>,\n options: IObserveProviderNativeRawPayloadStreamOptions,\n): AsyncIterable<TPayload> {\n let sequence = options.initialSequence ?? 0;\n for await (const payload of stream) {\n options.onProviderNativeRawPayload?.({\n provider: options.provider,\n ...(options.apiSurface !== undefined && { apiSurface: options.apiSurface }),\n payloadKind: 'stream_event',\n sequence,\n payload,\n });\n sequence++;\n yield payload;\n }\n}\n","import type { IProviderProfileConfig, IProviderProbeResult } from '@robota-sdk/agent-core';\n\nexport interface IOpenAICompatibleModelsResponse {\n data?: Array<{ id?: string }>;\n}\n\nexport interface IOpenAICompatibleFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IOpenAICompatibleModelsResponse>;\n}\n\nexport type TOpenAICompatibleFetch = (url: string) => Promise<IOpenAICompatibleFetchResponse>;\n\nexport async function probeOpenAICompatibleProfile(\n profile: IProviderProfileConfig,\n fetcher: TOpenAICompatibleFetch = defaultOpenAICompatibleFetch,\n): Promise<IProviderProbeResult> {\n if (!profile.baseURL) {\n return { ok: true, message: 'Profile fields are valid; no endpoint probe configured.' };\n }\n\n try {\n const response = await fetcher(`${profile.baseURL.replace(/\\/$/, '')}/models`);\n if (!response.ok) {\n return { ok: false, message: `HTTP ${response.status}` };\n }\n const body = await response.json();\n const models = (body.data ?? []).map((item) => item.id).filter((id): id is string => !!id);\n return { ok: true, message: `${models.length} model(s) discovered`, models };\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) };\n }\n}\n\nasync function defaultOpenAICompatibleFetch(url: string): Promise<IOpenAICompatibleFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IOpenAICompatibleModelsResponse>,\n };\n}\n","import {\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n} from '../shared/openai-compatible/index.js';\n\nimport type { IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * Convert TUniversalMessage array to OpenAI chat completion message format.\n */\nexport function convertToOpenAIMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return convertToOpenAICompatibleMessages(messages);\n}\n\n/**\n * Convert tool schemas to OpenAI function tool format.\n */\nexport function convertToOpenAITools(tools: IToolSchema[]): OpenAI.Chat.ChatCompletionTool[] {\n return convertToOpenAICompatibleTools(tools);\n}\n","import type {\n IOpenAIResponsesTextConfig,\n IOpenAIResponsesTextFormatJsonSchema,\n} from './responses-types';\nimport type { IOpenAIProviderOptions, TOpenAIProviderOptionValue } from './types';\n\nexport interface IOpenAIChatTextFormatText {\n type: 'text';\n}\n\nexport interface IOpenAIChatTextFormatJsonObject {\n type: 'json_object';\n}\n\nexport interface IOpenAIChatTextFormatJsonSchema {\n type: 'json_schema';\n json_schema: {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n };\n}\n\nexport type TOpenAIChatResponseFormat =\n | IOpenAIChatTextFormatText\n | IOpenAIChatTextFormatJsonObject\n | IOpenAIChatTextFormatJsonSchema;\n\nexport function buildOpenAIChatResponseFormat(\n options: IOpenAIProviderOptions,\n): TOpenAIChatResponseFormat | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { type: 'json_object' };\n }\n\n const schema = requireJsonSchema(options);\n return {\n type: 'json_schema',\n json_schema: {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n },\n };\n}\n\nexport function buildOpenAIResponsesTextConfig(\n options: IOpenAIProviderOptions,\n): IOpenAIResponsesTextConfig | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { format: { type: 'json_object' } };\n }\n\n const schema = requireJsonSchema(options);\n const format: IOpenAIResponsesTextFormatJsonSchema = {\n type: 'json_schema',\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n return { format };\n}\n\nfunction requireJsonSchema(input: IOpenAIProviderOptions): {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n} {\n const schema = input.jsonSchema;\n if (input.responseFormat !== 'json_schema') {\n throw new Error(`Unsupported OpenAI response format: ${input.responseFormat}`);\n }\n if (!schema?.schema) {\n throw new Error('OpenAI jsonSchema.schema is required when responseFormat is json_schema');\n }\n return {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n}\n","import { convertToOpenAIMessages, convertToOpenAITools } from './message-converter';\nimport { buildOpenAIChatResponseFormat } from './openai-request-format';\nimport { assembleOpenAIStream } from './streaming/stream-assembler';\nimport { observeProviderNativeRawPayloadStream } from '../shared/openai-compatible/index.js';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { OpenAIResponseParser } from './parsers/response-parser';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IOpenAIError, IOpenAILogData } from './types/api-types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIChatCompletionsOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n payloadLogger?: IPayloadLogger;\n responseParser: OpenAIResponseParser;\n onTextDelta?: TTextDeltaCallback;\n}\n\nexport async function chatWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): Promise<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams = buildChatRequestParams(input);\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return await chatWithStreamingAssembly(client, input, {\n ...requestParams,\n stream: true,\n });\n }\n\n await logPayload(input, requestParams, 'chat');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(requestParams);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return input.responseParser.parseResponse(response);\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI API request failed';\n throw new Error(`OpenAI chat failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): AsyncIterable<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n ...buildChatRequestParams(input),\n stream: true,\n };\n\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n\n for await (const chunk of observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n })) {\n const universalMessage = input.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI API request failed';\n throw new Error(`OpenAI stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildChatRequestParams(\n input: IOpenAIChatCompletionsOptions,\n): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const openaiMessages = convertToOpenAIMessages(input.messages);\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const responseFormat = buildOpenAIChatResponseFormat(input.providerOptions);\n return {\n model,\n messages: openaiMessages,\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && { max_tokens: input.chatOptions.maxTokens }),\n ...(input.chatOptions?.tools && {\n tools: convertToOpenAITools(input.chatOptions.tools),\n tool_choice: 'auto',\n }),\n ...(responseFormat !== undefined && { response_format: responseFormat }),\n } as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n}\n\nasync function chatWithStreamingAssembly(\n client: OpenAI,\n input: IOpenAIChatCompletionsOptions,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n): Promise<TUniversalMessage> {\n try {\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n\n return assembleOpenAIStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n }),\n onTextDelta: input.chatOptions?.onTextDelta ?? input.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI streaming request failed';\n throw new Error(`OpenAI stream failed: ${errorMessage}`);\n }\n}\n\nasync function logPayload(\n input: IOpenAIChatCompletionsOptions,\n requestParams:\n | OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n | OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n type: 'chat' | 'stream',\n): Promise<void> {\n if (!input.payloadLogger?.isEnabled()) {\n return;\n }\n\n const logData: IOpenAILogData = {\n model: requestParams.model,\n messagesCount: requestParams.messages.length,\n hasTools: !!requestParams.tools,\n temperature: requestParams.temperature ?? undefined,\n maxTokens: requestParams.max_tokens ?? undefined,\n timestamp: new Date().toISOString(),\n };\n await input.payloadLogger.logPayload(logData, type);\n}\n\nfunction requireClient(client: OpenAI | undefined): OpenAI {\n if (!client) {\n throw new Error(\n 'OpenAI client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n return client;\n}\n","import { OpenAICompatibleResponseParser } from '../../shared/openai-compatible/index.js';\n\nimport type { ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI response parser compatibility wrapper.\n *\n * The implementation delegates to the shared OpenAI-compatible parser while\n * preserving the OpenAI-branded error messages that are part of this package's\n * current test contract.\n */\nexport class OpenAIResponseParser {\n private readonly parser: OpenAICompatibleResponseParser;\n\n constructor(logger?: ILogger) {\n this.parser = new OpenAICompatibleResponseParser({ logger });\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n return this.parser.parseResponse(response);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI response parsing failed',\n );\n throw new Error(`OpenAI response parsing failed: ${message}`);\n }\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n return this.parser.parseStreamingChunk(chunk);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI chunk parsing failed',\n );\n throw new Error(`OpenAI chunk parsing failed: ${message}`);\n }\n }\n}\n\nfunction normalizeParserMessage(message: string): string {\n return message\n .replace(/^OpenAI-compatible response parsing failed: /, '')\n .replace(/^OpenAI-compatible chunk parsing failed: /, '')\n .replace('OpenAI-compatible response', 'OpenAI response');\n}\n","import type {\n IOpenAIResponsesFunctionTool,\n IOpenAIResponsesMessageInput,\n TOpenAIResponsesInputContent,\n TOpenAIResponsesInputItem,\n} from './responses-types';\nimport type {\n IAssistantMessage,\n IToolSchema,\n TUniversalMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nexport function convertToOpenAIResponsesInput(\n messages: TUniversalMessage[],\n): TOpenAIResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\nexport function convertToOpenAIResponsesTools(\n tools: IToolSchema[] | undefined,\n strictTools: boolean | undefined,\n): IOpenAIResponsesFunctionTool[] | undefined {\n const converted =\n tools?.map((tool) => ({\n type: 'function' as const,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n strict: strictTools ?? false,\n })) ?? [];\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction convertMessage(message: TUniversalMessage): TOpenAIResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', getUserContent(message.content, message.parts))];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TOpenAIResponsesInputItem[] {\n const items: TOpenAIResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction getUserContent(\n content: string,\n parts: TUniversalMessagePart[] | undefined,\n): string | TOpenAIResponsesInputContent[] {\n if (!parts || parts.length === 0) {\n return content;\n }\n\n const converted = parts.map((part) => convertPart(part));\n if (content.length > 0 && !parts.some((part) => part.type === 'text')) {\n return [{ type: 'input_text', text: content }, ...converted];\n }\n return converted;\n}\n\nfunction convertPart(part: TUniversalMessagePart): TOpenAIResponsesInputContent {\n if (part.type === 'text') {\n return { type: 'input_text', text: part.text };\n }\n if (part.type === 'image_uri') {\n return { type: 'input_image', image_url: part.uri };\n }\n return {\n type: 'input_image',\n image_url: `data:${part.mimeType};base64,${part.data}`,\n };\n}\n\nfunction createMessageInput(\n role: IOpenAIResponsesMessageInput['role'],\n content: string | TOpenAIResponsesInputContent[],\n): IOpenAIResponsesMessageInput {\n return {\n role,\n content,\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done || signal?.aborted) {\n break;\n }\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) {\n return iterator.next();\n }\n if (signal.aborted) {\n return { done: true, value: undefined as T };\n }\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) {\n signal.removeEventListener('abort', abortListener);\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { streamWithAbort } from './responses-stream-utils';\n\nimport type {\n IOpenAIResponsesErrorEvent,\n IOpenAIResponsesFunctionCallOutputItem,\n IOpenAIResponsesMessageOutputItem,\n IOpenAIResponsesReasoningOutputItem,\n IOpenAIResponsesResponse,\n IOpenAIResponsesUsage,\n TOpenAIResponsesOutputContent,\n TOpenAIResponsesOutputItem,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type { IToolCall, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\n\ninterface IOpenAIResponsesStreamAssemblyOptions {\n stream: AsyncIterable<TOpenAIResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IOpenAIResponsesReasoningMetadata {\n reasoningSummaryCount: number;\n reasoningSummaries: string[];\n hasEncryptedReasoning: boolean;\n}\n\ninterface IOpenAIResponseUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\ninterface IOpenAIResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}\n\nexport function parseOpenAIResponsesResponse(\n response: IOpenAIResponsesResponse,\n): TUniversalMessage {\n assertUsableResponse(response);\n const output = response.output ?? [];\n const content = response.output_text ?? extractMessageText(output);\n return buildAssistantMessage({\n content,\n toolCalls: extractFunctionToolCalls(output),\n response,\n reasoning: collectReasoningMetadata(output),\n });\n}\n\nexport async function assembleOpenAIResponsesStream(\n options: IOpenAIResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IOpenAIResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n reasoning: createEmptyReasoningMetadata(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n reasoning: state.reasoning,\n });\n}\n\nfunction applyStreamEvent(\n state: IOpenAIResponsesStreamState,\n event: TOpenAIResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata(event.response.output ?? []));\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (\n event.type === 'response.error' ||\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n throw new Error(`OpenAI Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction applyOutputItem(\n state: IOpenAIResponsesStreamState,\n item: TOpenAIResponsesOutputItem,\n): void {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n return;\n }\n if (isReasoningOutputItem(item)) {\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata([item]));\n }\n}\n\nfunction buildMessageFromCompletedResponse(state: IOpenAIResponsesStreamState): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('OpenAI Responses stream completed without response metadata');\n }\n\n assertUsableResponse(response);\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const reasoning = collectReasoningMetadata(output);\n mergeReasoningMetadata(reasoning, state.reasoning);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n reasoning,\n });\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && { usage: mapUsage(input.response.usage) }),\n metadata: buildMetadata(input.response, input.reasoning),\n };\n}\n\nfunction buildMetadata(\n response: IOpenAIResponsesResponse | undefined,\n reasoning: IOpenAIResponsesReasoningMetadata,\n): NonNullable<TUniversalMessage['metadata']> {\n return {\n providerApiSurface: 'responses',\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n ...(reasoning.reasoningSummaryCount > 0 && {\n reasoningSummaryCount: reasoning.reasoningSummaryCount,\n reasoningSummaries: reasoning.reasoningSummaries,\n }),\n ...(reasoning.hasEncryptedReasoning && { hasEncryptedReasoning: true }),\n };\n}\n\nfunction mapUsage(usage: IOpenAIResponsesUsage): IOpenAIResponseUsage {\n return {\n promptTokens: usage.input_tokens ?? 0,\n completionTokens: usage.output_tokens ?? 0,\n totalTokens: usage.total_tokens ?? 0,\n };\n}\n\nfunction extractFunctionToolCalls(output: readonly TOpenAIResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IOpenAIResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TOpenAIResponsesOutputItem[]): string {\n return output\n .filter(isMessageOutputItem)\n .flatMap((item) => item.content)\n .map(extractTextContent)\n .join('');\n}\n\nfunction extractTextContent(content: TOpenAIResponsesOutputContent): string {\n if (content.type === 'refusal') {\n return content.refusal;\n }\n return content.text;\n}\n\nfunction isMessageOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesMessageOutputItem {\n return item.type === 'message' && 'content' in item && Array.isArray(item.content);\n}\n\nfunction collectReasoningMetadata(\n output: readonly TOpenAIResponsesOutputItem[],\n): IOpenAIResponsesReasoningMetadata {\n const metadata = createEmptyReasoningMetadata();\n for (const item of output) {\n if (!isReasoningOutputItem(item)) {\n continue;\n }\n const summaries = item.summary?.map((summary) => summary.text).filter(isString) ?? [];\n metadata.reasoningSummaryCount += summaries.length;\n metadata.reasoningSummaries.push(...summaries);\n metadata.hasEncryptedReasoning = metadata.hasEncryptedReasoning || !!item.encrypted_content;\n }\n return metadata;\n}\n\nfunction isReasoningOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesReasoningOutputItem {\n return item.type === 'reasoning';\n}\n\nfunction createEmptyReasoningMetadata(): IOpenAIResponsesReasoningMetadata {\n return {\n reasoningSummaryCount: 0,\n reasoningSummaries: [],\n hasEncryptedReasoning: false,\n };\n}\n\nfunction mergeReasoningMetadata(\n target: IOpenAIResponsesReasoningMetadata,\n source: IOpenAIResponsesReasoningMetadata,\n): void {\n target.reasoningSummaryCount += source.reasoningSummaryCount;\n target.reasoningSummaries.push(...source.reasoningSummaries);\n target.hasEncryptedReasoning = target.hasEncryptedReasoning || source.hasEncryptedReasoning;\n}\n\nfunction isString(value: string | undefined): value is string {\n return value !== undefined;\n}\n\nfunction assertUsableResponse(response: IOpenAIResponsesResponse): void {\n if (response.status === 'failed' || response.status === 'incomplete') {\n throw new Error(`OpenAI Responses API failed: ${response.error?.message ?? response.status}`);\n }\n}\n\nfunction extractErrorMessage(event: IOpenAIResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { buildOpenAIResponsesTextConfig } from './openai-request-format';\nimport {\n convertToOpenAIResponsesInput,\n convertToOpenAIResponsesTools,\n} from './responses-converter';\nimport { assembleOpenAIResponsesStream, parseOpenAIResponsesResponse } from './responses-parser';\nimport { observeProviderNativeRawPayloadStream } from '../shared/openai-compatible/index.js';\n\nimport type {\n IOpenAIResponsesRequestNonStreaming,\n IOpenAIResponsesRequestStreaming,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IOpenAIError } from './types/api-types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n onTextDelta?: TTextDeltaCallback;\n}\n\ninterface IResponsesStreamMessageQueue {\n deltas: TUniversalMessage[];\n finalMessage?: TUniversalMessage;\n error?: Error;\n wake?: () => void;\n}\n\nexport async function chatWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return parseOpenAIResponsesResponse(response);\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI Responses API request failed';\n throw new Error(`OpenAI responses failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const queue: IResponsesStreamMessageQueue = { deltas: [] };\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n const assembly = chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n textDeltaCb?.(delta);\n enqueueStreamDelta(queue, createStreamDeltaMessage(delta));\n },\n },\n })\n .then((result) => finishStreamQueue(queue, result))\n .catch((error) => failStreamQueue(queue, toError(error)));\n\n yield* drainResponsesStreamQueue(queue);\n await assembly;\n}\n\nasync function chatWithOpenAIResponsesStreamingAssembly(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n return assembleOpenAIResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TOpenAIResponsesStreamEvent>,\n {\n provider: 'openai',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const openaiError = error as IOpenAIError;\n const errorMessage = openaiError.message || 'OpenAI Responses streaming request failed';\n throw new Error(`OpenAI responses stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const tools = convertToOpenAIResponsesTools(\n input.chatOptions?.tools,\n input.providerOptions.strictTools,\n );\n const textConfig = buildOpenAIResponsesTextConfig(input.providerOptions);\n return {\n model,\n input: convertToOpenAIResponsesInput(input.messages),\n ...(tools !== undefined && { tools, tool_choice: 'auto' }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(textConfig !== undefined && { text: textConfig }),\n ...(input.providerOptions.reasoning !== undefined && {\n reasoning: input.providerOptions.reasoning,\n }),\n ...(input.providerOptions.includeEncryptedReasoning === true && {\n include: ['reasoning.encrypted_content'],\n }),\n ...(input.providerOptions.store !== undefined && { store: input.providerOptions.store }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n providerApiSurface: 'responses',\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n\nasync function* drainResponsesStreamQueue(\n queue: IResponsesStreamMessageQueue,\n): AsyncIterable<TUniversalMessage> {\n while (true) {\n const next = queue.deltas.shift();\n if (next !== undefined) {\n yield next;\n continue;\n }\n if (queue.error !== undefined) {\n throw queue.error;\n }\n if (queue.finalMessage !== undefined) {\n yield createFinalStreamMessage(queue.finalMessage);\n return;\n }\n await waitForStreamQueue(queue);\n }\n}\n\nfunction enqueueStreamDelta(queue: IResponsesStreamMessageQueue, message: TUniversalMessage): void {\n queue.deltas.push(message);\n wakeStreamQueue(queue);\n}\n\nfunction finishStreamQueue(queue: IResponsesStreamMessageQueue, result: TUniversalMessage): void {\n queue.finalMessage = result;\n wakeStreamQueue(queue);\n}\n\nfunction failStreamQueue(queue: IResponsesStreamMessageQueue, error: Error): void {\n queue.error = error;\n wakeStreamQueue(queue);\n}\n\nfunction waitForStreamQueue(queue: IResponsesStreamMessageQueue): Promise<void> {\n return new Promise((resolve) => {\n queue.wake = resolve;\n });\n}\n\nfunction wakeStreamQueue(queue: IResponsesStreamMessageQueue): void {\n queue.wake?.();\n queue.wake = undefined;\n}\n\nfunction createFinalStreamMessage(result: TUniversalMessage): TUniversalMessage {\n return {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nfunction toError(error: Error | string): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n","import { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport { SilentLogger } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport {\n chatStreamWithOpenAIChatCompletions,\n chatWithOpenAIChatCompletions,\n} from './chat-completions-chat';\nimport { OpenAIResponseParser } from './parsers/response-parser';\nimport { chatStreamWithOpenAIResponsesApi, chatWithOpenAIResponsesApi } from './responses-chat';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { IOpenAIProviderOptions, TOpenAIApiSurface } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IAssistantMessage,\n IProviderCapabilities,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\n\n/**\n * OpenAI provider implementation for Robota\n *\n * Provides integration with OpenAI models through the Robota provider contract.\n * Uses OpenAI SDK native types internally for optimal performance and feature support.\n *\n * @public\n */\nexport class OpenAIProvider extends AbstractAIProvider {\n override readonly name = 'openai';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IOpenAIProviderOptions;\n private readonly apiSurface: TOpenAIApiSurface;\n private readonly payloadLogger: IPayloadLogger | undefined;\n private readonly responseParser: OpenAIResponseParser;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IOpenAIProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n this.apiSurface = resolveApiSurface(options);\n validateOpenAIProviderNativeWebTools(this.apiSurface, options.nativeWebTools);\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.organization && { organization: options.organization }),\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either OpenAI client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAIResponseParser(this.logger);\n this.payloadLogger = options.payloadLogger;\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n return chatWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n });\n }\n\n return chatWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n });\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n yield* chatStreamWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n });\n return;\n }\n\n yield* chatStreamWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: options,\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n });\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n const source =\n this.apiSurface === 'chat-completions'\n ? 'openai-compatible-chat-completions'\n : 'openai-responses';\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'search'),\n },\n webFetch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'fetch'),\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI client doesn't need explicit cleanup\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n}\n\nfunction resolveApiSurface(options: IOpenAIProviderOptions): TOpenAIApiSurface {\n if (options.apiSurface !== undefined) {\n return options.apiSurface;\n }\n return options.baseURL ? 'chat-completions' : 'responses';\n}\n\nfunction getOpenAIUnsupportedNativeWebReason(\n apiSurface: TOpenAIApiSurface,\n toolKind: 'search' | 'fetch',\n): string {\n if (apiSurface === 'chat-completions') {\n return `OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${toolKind}.`;\n }\n return `OpenAI Responses native web ${toolKind} is not wired in this Robota provider version.`;\n}\n\nfunction validateOpenAIProviderNativeWebTools(\n apiSurface: TOpenAIApiSurface,\n nativeWebTools: IOpenAIProviderOptions['nativeWebTools'],\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n throw new Error(\n `Provider openai native web search/fetch is not supported for apiSurface ${apiSurface} in this Robota provider version.`,\n );\n}\n","import type { TUniversalMessage, IAssistantMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI Conversation Adapter\n *\n * Converts between TUniversalMessage format and OpenAI native types.\n * Provides bidirectional conversion for seamless integration.\n *\n * @public\n */\nexport class OpenAIConversationAdapter {\n /**\n * Filter messages for OpenAI compatibility\n *\n * OpenAI has specific requirements:\n * - Tool messages must have valid toolCallId\n * - Messages must be in proper sequence\n * - Tool messages without toolCallId should be excluded\n */\n static filterMessagesForOpenAI(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages.filter((msg) => {\n // Always include user, assistant, and system messages\n if (msg.role === 'user' || msg.role === 'assistant' || msg.role === 'system') {\n return true;\n }\n\n // For tool messages, only include if they have a valid toolCallId\n if (msg.role === 'tool') {\n // Must have toolCallId and it must not be empty or 'unknown'\n return !!(msg.toolCallId && msg.toolCallId.trim() !== '' && msg.toolCallId !== 'unknown');\n }\n\n return false;\n });\n }\n\n /**\n * Convert TUniversalMessage array to OpenAI message format\n * Now properly handles tool messages for OpenAI's tool calling feature\n */\n static toOpenAIFormat(messages: TUniversalMessage[]): OpenAI.Chat.ChatCompletionMessageParam[] {\n // First filter messages for OpenAI compatibility\n const filteredMessages = this.filterMessagesForOpenAI(messages);\n return filteredMessages.map((msg) => this.convertMessage(msg));\n }\n\n /**\n * Convert a single TUniversalMessage to OpenAI format\n * Handles all message types including tool messages\n */\n static convertMessage(msg: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n const messageRole = msg.role;\n\n if (messageRole === 'user') {\n return {\n role: 'user',\n content: msg.content,\n };\n }\n\n if (messageRole === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Handle tool_calls format\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const result: OpenAI.Chat.ChatCompletionAssistantMessageParam = {\n role: 'assistant',\n // CRITICAL: OpenAI API requires content to be null (not empty string) when tool_calls are present\n // VERIFIED: 2024-12 - This prevents \"400 Bad Request\" errors from OpenAI API\n // DO NOT CHANGE without testing against actual OpenAI API\n content: assistantMsg.content === '' ? null : assistantMsg.content || null,\n tool_calls: assistantMsg.toolCalls.map((toolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n return result;\n }\n\n // Regular assistant message (without tool calls)\n // VERIFIED: OpenAI accepts both null and string content for regular messages\n // We preserve null when content is null or empty string for API consistency\n return {\n role: 'assistant',\n content:\n assistantMsg.content === null\n ? null\n : assistantMsg.content === ''\n ? null\n : assistantMsg.content || '',\n };\n }\n\n if (messageRole === 'system') {\n return {\n role: 'system',\n content: msg.content,\n };\n }\n\n // Handle tool messages for OpenAI tool calling\n if (messageRole === 'tool') {\n if (!msg.toolCallId || msg.toolCallId.trim() === '') {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(msg)}`);\n }\n\n const result: OpenAI.Chat.ChatCompletionToolMessageParam = {\n role: 'tool',\n content: msg.content,\n tool_call_id: msg.toolCallId,\n };\n return result;\n }\n\n const exhaustive: never = messageRole;\n throw new Error(`Unsupported message role: ${exhaustive}`);\n }\n\n /**\n * Add system prompt to message array if needed\n */\n static addSystemPromptIfNeeded(\n messages: OpenAI.Chat.ChatCompletionMessageParam[],\n systemPrompt?: string,\n ): OpenAI.Chat.ChatCompletionMessageParam[] {\n if (!systemPrompt) {\n return messages;\n }\n\n // Check if system message already exists\n const hasSystemMessage = messages.some((msg) => msg.role === 'system');\n\n if (hasSystemMessage) {\n return messages;\n }\n\n // Add system prompt at the beginning\n return [{ role: 'system', content: systemPrompt }, ...messages];\n }\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nconst OPENAI_MODELS_ENDPOINT = 'https://api.openai.com/v1/models';\nconst OPENAI_MODELS_SOURCE_URL = 'https://platform.openai.com/docs/api-reference/models/list';\n\nexport interface IOpenAIModelCatalogResponse {\n data?: readonly IOpenAIModelCatalogResource[];\n}\n\nexport interface IOpenAIModelCatalogResource {\n id?: string;\n}\n\nexport interface IOpenAIModelCatalogFetchInit {\n headers: Record<string, string>;\n}\n\nexport interface IOpenAIModelCatalogFetchResponse {\n ok: boolean;\n status: number;\n statusText?: string;\n json: () => Promise<IOpenAIModelCatalogResponse>;\n}\n\nexport type TOpenAIModelCatalogFetch = (\n url: string,\n init: IOpenAIModelCatalogFetchInit,\n) => Promise<IOpenAIModelCatalogFetchResponse>;\n\nexport interface IRefreshOpenAIModelCatalogOptions {\n fetcher?: TOpenAIModelCatalogFetch;\n now?: () => Date;\n}\n\nexport async function refreshOpenAIModelCatalog(\n profile: IProviderProfileConfig,\n options: IRefreshOpenAIModelCatalogOptions = {},\n): Promise<IProviderModelCatalog> {\n if (!profile.apiKey) {\n return createUnavailableCatalog('OpenAI model catalog refresh requires apiKey.');\n }\n\n const fetcher = options.fetcher ?? defaultOpenAIModelCatalogFetch;\n const now = options.now ?? (() => new Date());\n const url = resolveModelsEndpoint(profile.baseURL);\n\n try {\n const response = await fetcher(url, {\n headers: { Authorization: `Bearer ${profile.apiKey}` },\n });\n if (!response.ok) {\n return createUnavailableCatalog(formatHttpFailure(response));\n }\n\n const body = await response.json();\n const entries = toModelCatalogEntries(body);\n return {\n status: 'live',\n entries,\n lastVerifiedAt: now().toISOString(),\n sourceUrl: OPENAI_MODELS_SOURCE_URL,\n message: `${entries.length} OpenAI model(s) discovered.`,\n };\n } catch (error) {\n return createUnavailableCatalog(error instanceof Error ? error.message : String(error));\n }\n}\n\nfunction resolveModelsEndpoint(baseURL: string | undefined): string {\n if (!baseURL) return OPENAI_MODELS_ENDPOINT;\n return `${baseURL.replace(/\\/$/, '')}/models`;\n}\n\nfunction toModelCatalogEntries(\n body: IOpenAIModelCatalogResponse,\n): readonly IProviderModelCatalogEntry[] {\n return (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => id !== undefined && id.trim().length > 0)\n .map((id) => ({\n id,\n displayName: id,\n lifecycle: 'active',\n }));\n}\n\nfunction formatHttpFailure(response: IOpenAIModelCatalogFetchResponse): string {\n const statusText = response.statusText ? ` ${response.statusText}` : '';\n return `OpenAI model catalog refresh failed: HTTP ${response.status}${statusText}`;\n}\n\nfunction createUnavailableCatalog(message: string): IProviderModelCatalog {\n return {\n status: 'unavailable',\n sourceUrl: OPENAI_MODELS_SOURCE_URL,\n message,\n };\n}\n\nasync function defaultOpenAIModelCatalogFetch(\n url: string,\n init: IOpenAIModelCatalogFetchInit,\n): Promise<IOpenAIModelCatalogFetchResponse> {\n const response = await fetch(url, init);\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n json: () => response.json() as Promise<IOpenAIModelCatalogResponse>,\n };\n}\n","import { refreshOpenAIModelCatalog } from './model-catalog-refresh';\nimport { OpenAIProvider } from './provider';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\n\nimport type { IOpenAINativeWebToolsOptions, TOpenAIApiSurface } from './types';\nimport type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined = undefined;\nexport const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = '$ENV:OPENAI_API_KEY';\nconst OPENAI_API_KEY_URL = 'https://platform.openai.com/api-keys';\nconst OPENAI_SETUP_SOURCE_URL =\n 'https://developers.openai.com/api/reference/overview#authentication';\nconst OPENAI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst OPENAI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'OpenAI API keys',\n url: OPENAI_API_KEY_URL,\n sourceUrl: OPENAI_SETUP_SOURCE_URL,\n lastVerifiedAt: OPENAI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createOpenAIProviderDefinition(): IProviderDefinition {\n return {\n type: 'openai',\n displayName: 'OpenAI',\n description: 'Official OpenAI Responses API provider',\n defaults: {\n apiKey: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'unavailable',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n message: 'OpenAI model availability should be discovered live from GET /v1/models.',\n },\n setupHelpLinks: OPENAI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'OpenAI model',\n required: true,\n },\n {\n key: 'apiKey',\n title: 'OpenAI API key',\n defaultValue: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n refreshModelCatalog: ({ profile }) => refreshOpenAIModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) => {\n const apiSurface = readApiSurface(config.options);\n const nativeWebTools = readNativeWebTools(config.options);\n validateOpenAINativeWebTools(config.baseURL, apiSurface, nativeWebTools);\n return new OpenAIProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(apiSurface !== undefined && { apiSurface }),\n ...(nativeWebTools !== undefined && { nativeWebTools }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider openai requires apiKey');\n }\n return apiKey;\n}\n\nfunction readApiSurface(\n options: Record<string, TUniversalValue> | undefined,\n): TOpenAIApiSurface | undefined {\n const apiSurface = options?.['apiSurface'];\n if (apiSurface === 'responses' || apiSurface === 'chat-completions') {\n return apiSurface;\n }\n return undefined;\n}\n\nfunction readNativeWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n const nativeWebTools =\n readNativeWebToolsRecord(options?.['nativeWebTools']) ??\n readNativeWebToolsRecord(options?.['builtInWebTools']);\n if (nativeWebTools === undefined) {\n return undefined;\n }\n return nativeWebTools;\n}\n\nfunction readNativeWebToolsRecord(\n value: TUniversalValue | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n if (typeof value !== 'object') {\n return undefined;\n }\n const webSearch = value['webSearch'];\n const webFetch = value['webFetch'];\n return {\n ...(typeof webSearch === 'boolean' && { webSearch }),\n ...(typeof webFetch === 'boolean' && { webFetch }),\n };\n}\n\nfunction validateOpenAINativeWebTools(\n baseURL: string | undefined,\n apiSurface: TOpenAIApiSurface | undefined,\n nativeWebTools: IOpenAINativeWebToolsOptions | undefined,\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n if (baseURL !== undefined || apiSurface === 'chat-completions') {\n throw new Error(\n 'Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n }\n throw new Error(\n 'Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n}\n","export const DEFAULT_DEEPSEEK_PROVIDER_MODEL = 'deepseek-v4-flash';\nexport const DEFAULT_DEEPSEEK_PROVIDER_API_KEY_ENV = 'DEEPSEEK_API_KEY';\nexport const DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_DEEPSEEK_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_DEEPSEEK_PROVIDER_BASE_URL = 'https://api.deepseek.com';\n","import { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport { DEFAULT_DEEPSEEK_PROVIDER_BASE_URL } from './defaults';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n OpenAICompatibleResponseParser,\n} from '../shared/openai-compatible/index.js';\n\nimport type {\n IDeepSeekProviderOptions,\n IDeepSeekThinkingConfig,\n TDeepSeekReasoningEffort,\n} from './types';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport type {\n IChatOptions,\n IProviderCapabilities,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\ntype TDeepSeekChatCompletionCreateParamsNonStreaming = Omit<\n OpenAI.Chat.ChatCompletionCreateParamsNonStreaming,\n 'reasoning_effort'\n> & {\n thinking?: IDeepSeekThinkingConfig;\n reasoning_effort?: TDeepSeekReasoningEffort;\n};\n\ntype TDeepSeekChatCompletionCreateParamsStreaming = Omit<\n OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n 'reasoning_effort'\n> & {\n thinking?: IDeepSeekThinkingConfig;\n reasoning_effort?: TDeepSeekReasoningEffort;\n};\n\nexport class DeepSeekProvider extends AbstractAIProvider {\n override readonly name = 'deepseek';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IDeepSeekProviderOptions;\n private readonly responseParser: OpenAICompatibleResponseParser;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IDeepSeekProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL ?? DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either DeepSeek client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAICompatibleResponseParser({ logger: this.logger });\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'DeepSeek Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n const client = this.getClient();\n\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return await this.chatWithStreamingAssembly(\n { ...requestParams, stream: true },\n { ...options, onTextDelta: textDeltaCb },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming,\n );\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return this.responseParser.parseResponse(response);\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek API request failed';\n throw new Error(`DeepSeek chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'DeepSeek Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n const client = this.getClient();\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n );\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n const universalMessage = this.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek API request failed';\n throw new Error(`DeepSeek stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'DeepSeek OpenAI-compatible Chat Completions supports declared function tools, not provider-native web search.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'DeepSeek OpenAI-compatible Chat Completions supports declared function tools, not provider-native web fetch.',\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible DeepSeek clients do not need explicit cleanup.\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): TDeepSeekChatCompletionCreateParamsNonStreaming {\n this.validateTools(options?.tools);\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n return {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n ...(this.options.thinking !== undefined && {\n thinking: { type: this.options.thinking },\n }),\n ...(this.options.reasoningEffort !== undefined && {\n reasoning_effort: this.options.reasoningEffort,\n }),\n };\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): TDeepSeekChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n };\n }\n\n private getClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'DeepSeek client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n return this.client;\n }\n\n private async chatWithStreamingAssembly(\n requestParams: TDeepSeekChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n ): Promise<TUniversalMessage> {\n const client = this.getClient();\n\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams as OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options.signal ? { signal: options.signal } : undefined,\n );\n\n return assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'deepseek',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n });\n } catch (error) {\n const deepSeekError = error as IOpenAICompatibleError;\n const errorMessage = deepSeekError.message || 'DeepSeek streaming request failed';\n throw new Error(`DeepSeek stream failed: ${errorMessage}`);\n }\n }\n}\n","import { DEFAULT_DEEPSEEK_PROVIDER_MODEL } from './defaults';\n\nimport type { IProviderModelCatalogEntry } from '@robota-sdk/agent-core';\n\nexport const DEEPSEEK_MODEL_CATALOG_SOURCE_URL =\n 'https://api-docs.deepseek.com/quick_start/pricing';\nexport const DEEPSEEK_MODEL_LIST_SOURCE_URL = 'https://api-docs.deepseek.com/api/list-models';\nexport const DEEPSEEK_MODEL_LAST_VERIFIED_AT = '2026-05-07';\nexport const DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE = '2026-07-24';\n\nexport const DEEPSEEK_MODEL_CATALOG_ENTRIES: readonly IProviderModelCatalogEntry[] = [\n {\n id: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n displayName: 'DeepSeek V4 Flash',\n contextWindow: 1_000_000,\n capabilities: ['tools', 'reasoning', 'json_schema', 'streaming'],\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-v4-pro',\n displayName: 'DeepSeek V4 Pro',\n contextWindow: 1_000_000,\n capabilities: ['tools', 'reasoning', 'json_schema', 'streaming'],\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-chat',\n displayName: `DeepSeek Chat compatibility alias, deprecated ${DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE}`,\n aliases: [DEFAULT_DEEPSEEK_PROVIDER_MODEL],\n contextWindow: 1_000_000,\n capabilities: ['tools', 'json_schema', 'streaming'],\n lifecycle: 'deprecated',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'deepseek-reasoner',\n displayName: `DeepSeek Reasoner compatibility alias, deprecated ${DEEPSEEK_DEPRECATED_ALIAS_RETIREMENT_DATE}`,\n aliases: [DEFAULT_DEEPSEEK_PROVIDER_MODEL],\n contextWindow: 1_000_000,\n capabilities: ['reasoning', 'json_schema', 'streaming'],\n lifecycle: 'deprecated',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n },\n];\n\nexport function getDeepSeekFallbackModelCatalogEntry(\n id: string,\n): IProviderModelCatalogEntry | undefined {\n return DEEPSEEK_MODEL_CATALOG_ENTRIES.find((entry) => entry.id === id);\n}\n","import { DEFAULT_DEEPSEEK_PROVIDER_BASE_URL } from './defaults';\nimport {\n DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n getDeepSeekFallbackModelCatalogEntry,\n} from './model-catalog';\n\nimport type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nexport interface IDeepSeekModelsResponse {\n data?: Array<{\n id?: string;\n object?: string;\n owned_by?: string;\n }>;\n}\n\nexport interface IDeepSeekFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IDeepSeekFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IDeepSeekModelsResponse>;\n}\n\nexport type TDeepSeekFetch = (\n url: string,\n init?: IDeepSeekFetchInit,\n) => Promise<IDeepSeekFetchResponse>;\n\nexport async function refreshDeepSeekModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TDeepSeekFetch = defaultDeepSeekFetch,\n): Promise<IProviderModelCatalog> {\n const baseURL = trimTrailingSlash(profile.baseURL ?? DEFAULT_DEEPSEEK_PROVIDER_BASE_URL);\n const url = `${baseURL}/models`;\n const response = await fetcher(url, buildFetchInit(profile.apiKey));\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n message: `DeepSeek model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n entries,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IDeepSeekFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n };\n}\n\nfunction toModelCatalogEntry(id: string): IProviderModelCatalogEntry {\n return (\n getDeepSeekFallbackModelCatalogEntry(id) ?? {\n id,\n displayName: id,\n lifecycle: 'active',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n }\n );\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/, '');\n}\n\nasync function defaultDeepSeekFetch(\n url: string,\n init?: IDeepSeekFetchInit,\n): Promise<IDeepSeekFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IDeepSeekModelsResponse>,\n };\n}\n","import {\n DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n} from './defaults';\nimport {\n DEEPSEEK_MODEL_CATALOG_ENTRIES,\n DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n} from './model-catalog';\nimport { refreshDeepSeekModelCatalog } from './model-catalog-refresh';\nimport { DeepSeekProvider } from './provider';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\n\nimport type { TDeepSeekReasoningEffort, TDeepSeekThinkingMode } from './types';\nimport type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\n\nconst DEEPSEEK_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: DEEPSEEK_MODEL_CATALOG_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_MODEL_LAST_VERIFIED_AT,\n entries: DEEPSEEK_MODEL_CATALOG_ENTRIES,\n};\nconst DEEPSEEK_API_KEY_URL = 'https://platform.deepseek.com/api_keys';\nconst DEEPSEEK_SETUP_SOURCE_URL = 'https://api-docs.deepseek.com/';\nconst DEEPSEEK_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst DEEPSEEK_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'DeepSeek API keys',\n url: DEEPSEEK_API_KEY_URL,\n sourceUrl: DEEPSEEK_SETUP_SOURCE_URL,\n lastVerifiedAt: DEEPSEEK_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createDeepSeekProviderDefinition(): IProviderDefinition {\n return {\n type: 'deepseek',\n displayName: 'DeepSeek',\n description: 'DeepSeek OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n apiKey: DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n baseURL: DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n },\n modelCatalog: DEEPSEEK_MODEL_CATALOG,\n setupHelpLinks: DEEPSEEK_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'DeepSeek OpenAI-compatible base URL',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'DeepSeek model',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'DeepSeek API key',\n defaultValue: DEFAULT_DEEPSEEK_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n refreshModelCatalog: ({ profile }) => refreshDeepSeekModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) => {\n const options = parseDeepSeekProviderOptions(config.options);\n return new DeepSeekProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(options.thinking !== undefined && { thinking: options.thinking }),\n ...(options.reasoningEffort !== undefined && { reasoningEffort: options.reasoningEffort }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider deepseek requires apiKey');\n }\n return apiKey;\n}\n\nfunction parseDeepSeekProviderOptions(options: Record<string, TUniversalValue> | undefined): {\n thinking?: TDeepSeekThinkingMode;\n reasoningEffort?: TDeepSeekReasoningEffort;\n} {\n const thinking = parseThinkingMode(options?.['thinking']);\n const reasoningEffort = parseReasoningEffort(options?.['reasoningEffort']);\n return {\n ...(thinking !== undefined && { thinking }),\n ...(reasoningEffort !== undefined && { reasoningEffort }),\n };\n}\n\nfunction parseThinkingMode(value: TUniversalValue | undefined): TDeepSeekThinkingMode | undefined {\n if (value === true) return 'enabled';\n if (value === false) return 'disabled';\n if (value === 'enabled' || value === 'disabled') return value;\n const record = asRecord(value);\n const type = record?.['type'];\n return type === 'enabled' || type === 'disabled' ? type : undefined;\n}\n\nfunction parseReasoningEffort(\n value: TUniversalValue | undefined,\n): TDeepSeekReasoningEffort | undefined {\n if (\n value === 'low' ||\n value === 'medium' ||\n value === 'high' ||\n value === 'xhigh' ||\n value === 'max'\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction asRecord(value: TUniversalValue | undefined): Record<string, TUniversalValue> | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n return typeof value === 'object' ? value : undefined;\n}\n","import type { IGeminiProviderOptions } from './types';\nimport type { GenerateContentParameters } from '@google/genai';\nimport type {\n TUniversalMessage,\n TUniversalMessagePart,\n IMediaOutputRef,\n IImageEditRequest,\n IImageComposeRequest,\n TProviderMediaResult,\n IChatOptions,\n} from '@robota-sdk/agent-core';\n\n/** Checks whether the given parts contain an image part. */\nexport function hasImagePart(parts: TUniversalMessagePart[] | undefined): boolean {\n if (!parts) {\n return false;\n }\n return parts.some((part) => part.type === 'image_inline' || part.type === 'image_uri');\n}\n\n/** Extracts inline image parts from a message and converts them to media output references. */\nexport function mapInlineImagePartsToMediaOutputs(\n parts: TUniversalMessagePart[] | undefined,\n): IMediaOutputRef[] {\n if (!parts) {\n return [];\n }\n const outputs: IMediaOutputRef[] = [];\n for (const part of parts) {\n if (part.type !== 'image_inline') {\n continue;\n }\n outputs.push({\n kind: 'uri',\n uri: `data:${part.mimeType};base64,${part.data}`,\n mimeType: part.mimeType,\n });\n }\n return outputs;\n}\n\n/** Parses a data URI into its MIME type and base64 payload. */\nexport function parseDataUri(uri: string): { mimeType: string; data: string } | undefined {\n const commaIndex = uri.indexOf(',');\n if (commaIndex < 0) {\n return undefined;\n }\n const header = uri.slice(0, commaIndex);\n const payload = uri.slice(commaIndex + 1);\n if (!header.endsWith(';base64')) {\n return undefined;\n }\n const mimeType = header.replace('data:', '').replace(';base64', '').trim();\n if (mimeType.length === 0 || payload.trim().length === 0) {\n return undefined;\n }\n return {\n mimeType,\n data: payload,\n };\n}\n\n/** Maps an image input source (inline or URI) to a universal message part. */\nexport function mapImageInputSourceToPart(\n source: IImageEditRequest['image'] | IImageComposeRequest['images'][number],\n): TProviderMediaResult<TUniversalMessagePart> {\n if (source.kind === 'inline') {\n if (source.mimeType.trim().length === 0 || source.data.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Inline image source requires non-empty mimeType and data.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: source.mimeType,\n data: source.data,\n },\n };\n }\n if (!source.uri.startsWith('data:')) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Google image provider supports only inline or data URI input sources.',\n },\n };\n }\n const parsedResult = parseDataUri(source.uri);\n if (!parsedResult) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Data URI source must use base64 payload.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: parsedResult.mimeType,\n data: parsedResult.data,\n },\n };\n}\n\n/** Determines which response modalities to request from the Gemini API. */\nexport function buildResponseModalities(\n messages: TUniversalMessage[],\n defaultModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n optionModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n): Array<'TEXT' | 'IMAGE'> {\n if (optionModalities && optionModalities.length > 0) {\n return optionModalities;\n }\n const hasImageInput = messages.some((message) => hasImagePart(message.parts));\n if (hasImageInput) {\n return ['TEXT', 'IMAGE'];\n }\n if (defaultModalities && defaultModalities.length > 0) {\n return defaultModalities;\n }\n return ['TEXT'];\n}\n\n/** Checks whether the specified model is configured as image-capable. */\nexport function isImageCapableModel(\n model: string,\n configuredImageModels: string[] | undefined,\n): boolean {\n if (!configuredImageModels || configuredImageModels.length === 0) {\n return true;\n }\n return configuredImageModels.includes(model);\n}\n\n/** Builds the Gemini generation config including response modalities. */\nexport function buildGenerationConfig(\n messages: TUniversalMessage[],\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): NonNullable<GenerateContentParameters['config']> {\n assertCompatibleStructuredOutputOptions(providerOptions);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n validateImageCapableModel(options?.model, responseModalities, providerOptions);\n const config: NonNullable<GenerateContentParameters['config']> = { responseModalities };\n applyChatOptions(config, options);\n applySafetySettings(config, providerOptions, options);\n applyStructuredOutputOptions(config, providerOptions);\n applyProviderGenerationOptions(config, providerOptions);\n return config;\n}\n\nfunction validateImageCapableModel(\n model: string | undefined,\n responseModalities: Array<'TEXT' | 'IMAGE'>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (!model || !responseModalities.includes('IMAGE')) {\n return;\n }\n if (isImageCapableModel(model, providerOptions.imageCapableModels)) {\n return;\n }\n throw new Error(\n `Selected model \"${model}\" is not configured as image-capable for Google provider.`,\n );\n}\n\nfunction applyChatOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n options?: IChatOptions,\n): void {\n if (typeof options?.temperature === 'number') {\n config.temperature = options.temperature;\n }\n if (typeof options?.maxTokens === 'number') {\n config.maxOutputTokens = options.maxTokens;\n }\n if (typeof options?.google?.topP === 'number') {\n config.topP = options.google.topP;\n }\n if (typeof options?.google?.topK === 'number') {\n config.topK = options.google.topK;\n }\n if (typeof options?.google?.candidateCount === 'number') {\n config.candidateCount = options.google.candidateCount;\n }\n if (options?.google?.stopSequences && options.google.stopSequences.length > 0) {\n config.stopSequences = options.google.stopSequences;\n }\n if (options?.signal) {\n config.abortSignal = options.signal;\n }\n}\n\nfunction applySafetySettings(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): void {\n const safetySettings = options?.google?.safetySettings ?? providerOptions.safetySettings;\n if (safetySettings && safetySettings.length > 0) {\n config.safetySettings = safetySettings as NonNullable<\n GenerateContentParameters['config']\n >['safetySettings'];\n }\n}\n\nfunction applyStructuredOutputOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.responseMimeType) {\n config.responseMimeType = providerOptions.responseMimeType;\n }\n if (providerOptions.responseSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseSchema = providerOptions.responseSchema;\n }\n if (providerOptions.responseJsonSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseJsonSchema = providerOptions.responseJsonSchema;\n }\n}\n\nfunction applyProviderGenerationOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.thinkingConfig) {\n config.thinkingConfig = providerOptions.thinkingConfig as NonNullable<\n GenerateContentParameters['config']\n >['thinkingConfig'];\n }\n if (providerOptions.toolConfig) {\n config.toolConfig = providerOptions.toolConfig as NonNullable<\n GenerateContentParameters['config']\n >['toolConfig'];\n }\n}\n\nfunction assertCompatibleStructuredOutputOptions(providerOptions: IGeminiProviderOptions): void {\n if (providerOptions.responseSchema && providerOptions.responseJsonSchema) {\n throw new Error(\n 'Gemini structured output options responseSchema and responseJsonSchema are mutually exclusive.',\n );\n }\n}\n","import type { Content, Part } from '@google/genai';\nimport type {\n IAssistantMessage,\n ISystemMessage,\n IToolMessage,\n IUserMessage,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\ntype TGoogleJsonValue = string | number | boolean | null | TGoogleJsonValue[] | IGoogleJsonObject;\n\ninterface IGoogleJsonObject {\n readonly [key: string]: TGoogleJsonValue;\n}\n\nexport interface IGeminiMessageConversionResult {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/**\n * Maps universal message parts to Gemini-compatible parts.\n * Supports text and inline image parts; throws on unsupported part types.\n */\nexport function mapMessagePartsToGeminiParts(\n message: IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage,\n): Part[] {\n const parts: Part[] = [];\n const messageParts = message.parts ?? [];\n for (const part of messageParts) {\n if (part.type === 'text') {\n parts.push({ text: part.text });\n continue;\n }\n if (part.type === 'image_inline') {\n parts.push({\n inlineData: {\n mimeType: part.mimeType,\n data: part.data,\n },\n });\n continue;\n }\n throw new Error(`Google provider does not support image URI parts directly: ${part.uri}`);\n }\n if (parts.length === 0 && typeof message.content === 'string' && message.content.length > 0) {\n parts.push({ text: message.content });\n }\n return parts;\n}\n\n/**\n * Converts an array of universal messages to the Gemini Content format.\n *\n * IMPORTANT: Google Gemini allows content with function calls.\n * Content can be empty string or text, but NOT null.\n */\nexport function convertToGeminiFormat(messages: TUniversalMessage[]): Content[] {\n return convertToGeminiRequestFormat(messages).contents;\n}\n\n/**\n * Converts universal messages into Gemini request content plus request config\n * fields. Gemini system instructions are request-level config, not user turns.\n */\nexport function convertToGeminiRequestFormat(\n messages: TUniversalMessage[],\n): IGeminiMessageConversionResult {\n const contents: Content[] = [];\n const systemInstructionParts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n contents.push({\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n });\n continue;\n }\n if (msg.role === 'assistant') {\n contents.push(convertAssistantMessage(msg as IAssistantMessage));\n continue;\n }\n if (msg.role === 'tool') {\n contents.push(convertToolMessage(msg as IToolMessage));\n continue;\n }\n\n const systemInstruction = extractSystemInstructionText(msg as ISystemMessage);\n if (systemInstruction.length > 0) {\n systemInstructionParts.push(systemInstruction);\n }\n }\n\n return {\n contents,\n ...(systemInstructionParts.length > 0 && {\n systemInstruction: systemInstructionParts.join('\\n'),\n }),\n };\n}\n\n/**\n * Converts all messages to Gemini contents, including system instructions as\n * user content. This exists only for compatibility with callers that still need\n * a contents-only value.\n */\nexport function convertToGeminiFormatWithInlineSystem(messages: TUniversalMessage[]): Content[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n };\n }\n if (msg.role === 'assistant') {\n return convertAssistantMessage(msg as IAssistantMessage);\n }\n if (msg.role === 'tool') {\n const toolMessage = msg as IToolMessage;\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(toolMessage),\n };\n }\n const systemMessage = msg as ISystemMessage;\n const systemParts = mapMessagePartsToGeminiParts(systemMessage);\n if (systemParts.length === 0) {\n systemParts.push({ text: `System: ${systemMessage.content || ''}` });\n }\n return {\n role: 'user',\n parts: systemParts,\n };\n });\n}\n\nfunction convertAssistantMessage(assistantMsg: IAssistantMessage): Content {\n const parts: Part[] = [];\n const mappedAssistantParts = mapMessagePartsToGeminiParts(assistantMsg);\n for (const mappedPart of mappedAssistantParts) {\n parts.push(mappedPart);\n }\n if (parts.length === 0 && assistantMsg.content) {\n parts.push({ text: assistantMsg.content });\n }\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n assistantMsg.toolCalls.forEach((tc) => {\n parts.push({\n functionCall: {\n id: tc.id,\n name: tc.function.name,\n args: parseToolCallArguments(tc.function.arguments),\n },\n });\n });\n }\n return {\n role: 'model',\n parts,\n };\n}\n\nfunction convertToolMessage(toolMessage: IToolMessage): Content {\n const functionResponse = {\n id: toolMessage.toolCallId,\n name: requireToolMessageName(toolMessage),\n response: parseToolResponseContent(toolMessage.content),\n };\n return {\n role: 'user',\n parts: [{ functionResponse }],\n };\n}\n\nfunction extractSystemInstructionText(systemMessage: ISystemMessage): string {\n const parts = mapMessagePartsToGeminiParts(systemMessage);\n if (parts.length === 0) {\n return systemMessage.content;\n }\n const textParts: string[] = [];\n for (const part of parts) {\n if (typeof part.text === 'string') {\n textParts.push(part.text);\n continue;\n }\n throw new Error('Google provider system instructions support only text parts.');\n }\n return textParts.join('\\n');\n}\n\nfunction requireToolMessageName(toolMessage: IToolMessage): string {\n const toolName = toolMessage.name?.trim();\n if (!toolName) {\n throw new Error('Google provider tool message requires a function name.');\n }\n return toolName;\n}\n\nfunction parseToolCallArguments(serializedArguments: string): IGoogleJsonObject {\n const parsedArguments = JSON.parse(serializedArguments) as TGoogleJsonValue;\n if (!isJsonObject(parsedArguments)) {\n throw new Error('Google provider tool call arguments must be a JSON object.');\n }\n return parsedArguments;\n}\n\nfunction parseToolResponseContent(content: string): IGoogleJsonObject {\n const trimmedContent = content.trim();\n if (trimmedContent.length === 0) {\n return { output: null };\n }\n try {\n const parsedContent = JSON.parse(trimmedContent) as TGoogleJsonValue;\n if (isJsonObject(parsedContent)) {\n return parsedContent;\n }\n return { output: parsedContent };\n } catch {\n return { output: content };\n }\n}\n\nfunction isJsonObject(value: TGoogleJsonValue): value is IGoogleJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { Type } from '@google/genai';\n\nimport type { FunctionDeclaration, Schema } from '@google/genai';\nimport type { IParameterSchema, IToolSchema, TJSONSchemaKind } from '@robota-sdk/agent-core';\n\nconst GOOGLE_SCHEMA_TYPE_BY_JSON_KIND: Record<Exclude<TJSONSchemaKind, 'null'>, Type> = {\n string: Type.STRING,\n number: Type.NUMBER,\n integer: Type.INTEGER,\n boolean: Type.BOOLEAN,\n array: Type.ARRAY,\n object: Type.OBJECT,\n};\n\n/** Converts Robota tool schemas to Gemini function declarations. */\nexport function convertToolsToGeminiFormat(tools: IToolSchema[]): FunctionDeclaration[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: {\n type: Type.OBJECT,\n properties: convertParameterProperties(tool.parameters.properties),\n required: tool.parameters.required,\n },\n }));\n}\n\nfunction convertParameterProperties(\n properties: Record<string, IParameterSchema>,\n): Record<string, Schema> {\n const convertedProperties: Record<string, Schema> = {};\n for (const [key, value] of Object.entries(properties)) {\n convertedProperties[key] = convertParameterSchema(value);\n }\n return convertedProperties;\n}\n\nfunction convertParameterSchema(schema: IParameterSchema): Schema {\n const convertedSchema: Schema = {};\n const schemaType = convertSchemaKind(schema.type);\n if (schemaType) {\n convertedSchema.type = schemaType;\n }\n if (schema.description) {\n convertedSchema.description = schema.description;\n }\n if (schema.enum) {\n convertedSchema.enum = schema.enum.map(String);\n }\n if (schema.items) {\n convertedSchema.items = convertParameterSchema(schema.items);\n }\n if (schema.properties) {\n convertedSchema.properties = convertParameterProperties(schema.properties);\n }\n if (typeof schema.minimum === 'number') {\n convertedSchema.minimum = schema.minimum;\n }\n if (typeof schema.maximum === 'number') {\n convertedSchema.maximum = schema.maximum;\n }\n if (schema.pattern) {\n convertedSchema.pattern = schema.pattern;\n }\n if (schema.format) {\n convertedSchema.format = schema.format;\n }\n if (schema.default !== undefined) {\n convertedSchema.default = schema.default;\n }\n return convertedSchema;\n}\n\nfunction convertSchemaKind(kind: TJSONSchemaKind): Type | undefined {\n if (kind === 'null') {\n return undefined;\n }\n return GOOGLE_SCHEMA_TYPE_BY_JSON_KIND[kind];\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { Part, FunctionCall, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IAssistantMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nconst RANDOM_ID_RADIX = 36;\nconst RANDOM_ID_LENGTH = 9;\n\ninterface ICollectedGeminiParts {\n textValues: string[];\n messageParts: TUniversalMessagePart[];\n functionCalls: FunctionCall[];\n}\n\nexport {\n convertToGeminiFormat,\n convertToGeminiFormatWithInlineSystem,\n convertToGeminiRequestFormat,\n mapMessagePartsToGeminiParts,\n} from './request-converter';\nexport type { IGeminiMessageConversionResult } from './request-converter';\n\n/** Generates a unique call identifier for function call responses. */\nexport function generateCallId(): string {\n return `call_${Date.now()}_${Math.random().toString(RANDOM_ID_RADIX).substr(2, RANDOM_ID_LENGTH)}`;\n}\n\n/** Converts a Gemini API response into a universal message. */\nexport function convertFromGeminiResponse(response: GenerateContentResponse): TUniversalMessage {\n const candidate = response.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidate in Gemini response');\n }\n\n const content = candidate.content;\n if (!content || !content.parts || content.parts.length === 0) {\n throw new Error('No content in Gemini response');\n }\n\n const collectedParts = collectGeminiParts(content.parts);\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n state: 'complete' as const,\n role: 'assistant',\n content: collectedParts.textValues.length > 0 ? collectedParts.textValues.join('') : null,\n parts: collectedParts.messageParts,\n timestamp: new Date(),\n };\n\n if (collectedParts.functionCalls.length > 0) {\n const assistantResult = result as IAssistantMessage;\n assistantResult.toolCalls = collectedParts.functionCalls.map((fc) => ({\n id: fc.id ?? generateCallId(),\n type: 'function' as const,\n function: {\n name: requireFunctionCallName(fc),\n arguments: JSON.stringify(fc.args ?? {}),\n },\n }));\n }\n\n const usageMetadata = mapUsageMetadata(response);\n if (usageMetadata) {\n result.metadata = usageMetadata;\n }\n\n return result;\n}\n\nfunction collectGeminiParts(parts: Part[]): ICollectedGeminiParts {\n const textValues: string[] = [];\n const messageParts: TUniversalMessagePart[] = [];\n const functionCalls: FunctionCall[] = [];\n\n for (const part of parts) {\n collectTextPart(part, textValues, messageParts);\n collectInlineImagePart(part, messageParts);\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n\n return { textValues, messageParts, functionCalls };\n}\n\nfunction collectTextPart(\n part: Part,\n textValues: string[],\n messageParts: TUniversalMessagePart[],\n): void {\n if (typeof part.text !== 'string') {\n return;\n }\n textValues.push(part.text);\n messageParts.push({ type: 'text', text: part.text });\n}\n\nfunction collectInlineImagePart(part: Part, messageParts: TUniversalMessagePart[]): void {\n if (\n !part.inlineData ||\n typeof part.inlineData.data !== 'string' ||\n typeof part.inlineData.mimeType !== 'string'\n ) {\n return;\n }\n messageParts.push({\n type: 'image_inline',\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n });\n}\n\nfunction mapUsageMetadata(response: GenerateContentResponse): TUniversalMessage['metadata'] {\n if (\n !response.usageMetadata ||\n typeof response.usageMetadata.promptTokenCount !== 'number' ||\n typeof response.usageMetadata.candidatesTokenCount !== 'number' ||\n typeof response.usageMetadata.totalTokenCount !== 'number'\n ) {\n return undefined;\n }\n return {\n promptTokens: response.usageMetadata.promptTokenCount,\n completionTokens: response.usageMetadata.candidatesTokenCount,\n totalTokens: response.usageMetadata.totalTokenCount,\n };\n}\n\nexport { convertToolsToGeminiFormat } from './tool-schema-converter';\n\nfunction requireFunctionCallName(functionCall: FunctionCall): string {\n if (!functionCall.name || functionCall.name.trim().length === 0) {\n throw new Error('Gemini function call is missing a function name.');\n }\n return functionCall.name;\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n hasImagePart,\n mapInlineImagePartsToMediaOutputs,\n buildResponseModalities,\n buildGenerationConfig,\n} from './image-operations';\nimport {\n convertToGeminiRequestFormat,\n convertFromGeminiResponse,\n convertToolsToGeminiFormat,\n} from './message-converter';\n\nimport type { IGeminiProviderOptions } from './types';\nimport type { GoogleGenAI } from '@google/genai';\nimport type { Content, GenerateContentParameters, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\n\n/**\n * Execute a direct (non-streaming) chat request against the Gemini API.\n */\nexport async function executeDirect(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n\n if (options?.onTextDelta && !responseModalities.includes('IMAGE')) {\n return assembleStreamingChatResponse(client, providerOptions, messages, options, providerName);\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const result = await client.models.generateContent(request);\n emitGeminiNativeRawPayload(options, providerName, 'response', result);\n\n const convertedResponse = convertFromGeminiResponse(result);\n if (responseModalities.includes('IMAGE') && !hasImagePart(convertedResponse.parts)) {\n throw new Error(\n 'Gemini response did not include an image part while IMAGE modality was requested.',\n );\n }\n return convertedResponse;\n}\n\n/**\n * Execute a streaming chat request against the Gemini API.\n */\nexport async function* executeDirectStream(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): AsyncIterable<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n if (responseModalities.includes('IMAGE')) {\n throw new Error('Google provider does not support streaming image modality responses.');\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const stream = await client.models.generateContentStream(request);\n\n let sequence = 0;\n for await (const chunk of stream) {\n emitGeminiNativeRawPayload(options, providerName, 'stream_event', chunk, sequence);\n sequence++;\n const text = extractStreamText(chunk);\n if (text) {\n options?.onTextDelta?.(text);\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n}\n\nfunction buildGenerateContentRequest(\n model: string,\n contents: Content[],\n generationOptions: GenerateContentParameters['config'],\n options?: IChatOptions,\n systemInstruction?: string,\n): GenerateContentParameters {\n const config: GenerateContentParameters['config'] = { ...generationOptions };\n if (options?.tools && options.tools.length > 0) {\n config.tools = [{ functionDeclarations: convertToolsToGeminiFormat(options.tools) }];\n }\n if (systemInstruction) {\n config.systemInstruction = systemInstruction;\n }\n return {\n model,\n contents,\n config,\n };\n}\n\nfunction resolveGeminiModel(\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): string {\n const model = options?.model ?? providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n return model;\n}\n\nasync function assembleStreamingChatResponse(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const textParts: string[] = [];\n for await (const chunk of executeDirectStream(\n client,\n providerOptions,\n messages,\n options,\n providerName,\n )) {\n if (typeof chunk.content === 'string') {\n textParts.push(chunk.content);\n }\n }\n const content = textParts.join('');\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n parts: content.length > 0 ? [{ type: 'text', text: content }] : [],\n state: 'complete',\n timestamp: new Date(),\n };\n}\n\nfunction emitGeminiNativeRawPayload(\n options: IChatOptions | undefined,\n providerName: string,\n payloadKind: 'request' | 'response' | 'stream_event',\n payload: object,\n sequence?: number,\n): void {\n options?.onProviderNativeRawPayload?.({\n provider: providerName,\n apiSurface: 'gemini-generate-content',\n payloadKind,\n ...(sequence !== undefined && { sequence }),\n payload,\n });\n}\n\nfunction extractStreamText(\n chunk: GenerateContentResponse | { readonly text?: () => string },\n): string | undefined {\n const textValue = chunk.text;\n return typeof textValue === 'function' ? textValue() : textValue;\n}\n\n/**\n * Run an image generation request through the chat API.\n */\nexport async function runImageRequest(\n chatFn: (messages: TUniversalMessage[], options?: IChatOptions) => Promise<TUniversalMessage>,\n messages: TUniversalMessage[],\n model: string,\n): Promise<TProviderMediaResult<IImageGenerationResult>> {\n try {\n const response = await chatFn(messages, {\n model,\n google: { responseModalities: ['TEXT', 'IMAGE'] },\n });\n const outputs = mapInlineImagePartsToMediaOutputs(response.parts);\n if (outputs.length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Google image response did not include image output parts.',\n },\n };\n }\n return { ok: true, value: { outputs, model } };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google image request failed.';\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message: errorMessage } };\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { GoogleGenAI } from '@google/genai';\nimport { AbstractAIProvider } from '@robota-sdk/agent-core';\n\nimport { executeDirect, executeDirectStream, runImageRequest } from './execution-helpers';\nimport { mapImageInputSourceToPart } from './image-operations';\n\nimport type { IGeminiProviderOptions } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n TUniversalMessagePart,\n IImageGenerationProvider,\n IImageGenerationRequest,\n IImageEditRequest,\n IImageComposeRequest,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\n\n/**\n * Gemini provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Google Gemini API:\n * - Function calls can have content (text) along with function calls\n * - Content can be empty string or actual text, NOT null\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class GeminiProvider extends AbstractAIProvider implements IImageGenerationProvider {\n override readonly name: string = 'gemini';\n override readonly version = '1.0.0';\n public onTextDelta?: TTextDeltaCallback;\n\n private readonly client?: GoogleGenAI;\n private readonly options: IGeminiProviderOptions;\n\n constructor(options: IGeminiProviderOptions) {\n super();\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n this.client = new GoogleGenAI({ apiKey: options.apiKey });\n }\n }\n\n /** Generate response using TUniversalMessage */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n return await executeDirect(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google chat failed: ${errorMessage}`);\n }\n }\n\n /** Generate streaming response using TUniversalMessage */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n yield* executeDirectStream(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google stream failed: ${errorMessage}`);\n }\n }\n\n /** Generate an image from a text prompt using the Gemini API. */\n public async generateImage(\n request: IImageGenerationRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty model.',\n },\n };\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [{ type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Edit an existing image based on a text prompt using the Gemini API. */\n public async editImage(\n request: IImageEditRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty model.',\n },\n };\n }\n\n const inputPartResult = mapImageInputSourceToPart(request.image);\n if (!inputPartResult.ok) {\n return inputPartResult;\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [inputPartResult.value, { type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Compose multiple images together based on a text prompt using the Gemini API. */\n public async composeImage(\n request: IImageComposeRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty model.',\n },\n };\n }\n if (request.images.length < 2) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires at least two input images.',\n },\n };\n }\n\n const messageParts: TUniversalMessagePart[] = [];\n for (const imageSource of request.images) {\n const mappedPartResult = mapImageInputSourceToPart(imageSource);\n if (!mappedPartResult.ok) {\n return mappedPartResult;\n }\n messageParts.push(mappedPartResult.value);\n }\n messageParts.push({ type: 'text', text: request.prompt });\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: messageParts,\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override validateConfig(): boolean {\n if (this.executor) {\n return this.executor.validateConfig();\n }\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Google client does not need explicit cleanup\n }\n\n private withProviderCallbacks(options?: IChatOptions): IChatOptions | undefined {\n const onTextDelta = options?.onTextDelta ?? this.onTextDelta;\n if (!onTextDelta) {\n return options;\n }\n return {\n ...options,\n onTextDelta,\n };\n }\n}\n","import { refreshGeminiModelCatalog } from './model-catalog-refresh';\nimport { GeminiProvider } from './provider';\n\nimport type { IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_ENV = 'GEMINI_API_KEY';\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_GEMINI_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_GEMINI_PROVIDER_MODEL = 'gemini-3-flash-preview';\nexport const GEMINI_MODEL_SOURCE_URL = 'https://ai.google.dev/api/models';\nexport const GEMINI_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMINI_API_KEY_URL = 'https://aistudio.google.com/apikey';\nconst GEMINI_SETUP_SOURCE_URL = 'https://ai.google.dev/gemini-api/docs/api-key';\nconst GEMINI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMINI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Google AI Studio API keys',\n url: GEMINI_API_KEY_URL,\n sourceUrl: GEMINI_SETUP_SOURCE_URL,\n lastVerifiedAt: GEMINI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createGeminiProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemini',\n aliases: ['google'],\n displayName: 'Gemini',\n description: 'Google Gemini API provider',\n defaults: {\n model: DEFAULT_GEMINI_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMINI_PROVIDER_MODEL,\n displayName: 'Gemini 3 Flash Preview',\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'preview',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n },\n ],\n },\n setupHelpLinks: GEMINI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'Gemini model',\n defaultValue: DEFAULT_GEMINI_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemini API key',\n defaultValue: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n refreshModelCatalog: ({ profile }) => refreshGeminiModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) =>\n new GeminiProvider({\n apiKey: requireApiKey(config.apiKey),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemini requires apiKey');\n }\n return apiKey;\n}\n","import { GEMINI_MODEL_LAST_VERIFIED_AT, GEMINI_MODEL_SOURCE_URL } from './provider-definition';\n\nimport type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nconst GEMINI_API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models';\n\nexport interface IGeminiModelInfo {\n name?: string;\n displayName?: string;\n description?: string;\n inputTokenLimit?: number;\n outputTokenLimit?: number;\n supportedGenerationMethods?: string[];\n}\n\nexport interface IGeminiModelsResponse {\n models?: IGeminiModelInfo[];\n nextPageToken?: string;\n}\n\nexport interface IGeminiFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IGeminiFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IGeminiModelsResponse>;\n}\n\nexport type TGeminiFetch = (url: string, init?: IGeminiFetchInit) => Promise<IGeminiFetchResponse>;\n\nexport async function refreshGeminiModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TGeminiFetch = defaultGeminiFetch,\n): Promise<IProviderModelCatalog> {\n const url = profile.apiKey ? `${GEMINI_API_ENDPOINT}?key=${profile.apiKey}` : GEMINI_API_ENDPOINT;\n\n const response = await fetcher(url);\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n message: `Gemini model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.models ?? []).filter(supportsGenerateContent).map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: new Date().toISOString(),\n entries,\n message: `Fetched ${entries.length} Gemini models`,\n };\n}\n\nfunction supportsGenerateContent(model: IGeminiModelInfo): boolean {\n return model.supportedGenerationMethods?.includes('generateContent') === true;\n}\n\nfunction toModelCatalogEntry(model: IGeminiModelInfo): IProviderModelCatalogEntry {\n const rawName = model.name ?? '';\n const id = rawName.startsWith('models/') ? rawName.slice('models/'.length) : rawName;\n const lifecycle = rawName.includes('preview') ? 'preview' : 'active';\n\n return {\n id,\n displayName: model.displayName ?? id,\n lifecycle,\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nasync function defaultGeminiFetch(\n url: string,\n _init?: IGeminiFetchInit,\n): Promise<IGeminiFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IGeminiModelsResponse>,\n };\n}\n","const START_MARKER = '<|channel>';\nconst END_MARKER = '<channel|>';\nconst THOUGHT_LABEL = 'thought';\n\nexport interface IGemmaReasoningProjection {\n rawText: string;\n visibleText: string;\n removedReasoning: boolean;\n}\n\ninterface IProjectionOptions {\n final: boolean;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n removedReasoning: boolean;\n}\n\nexport function projectGemmaReasoningText(rawText: string): IGemmaReasoningProjection {\n const result = projectText(rawText, { final: true });\n return {\n rawText,\n visibleText: result.visibleParts.join(''),\n removedReasoning: result.removedReasoning,\n };\n}\n\nexport class GemmaReasoningProjector {\n private buffer = '';\n private emittedVisibleText = '';\n private hasRemovedReasoning = false;\n\n get rawText(): string {\n return this.buffer;\n }\n\n get removedReasoning(): boolean {\n return this.hasRemovedReasoning;\n }\n\n project(delta: string): string {\n if (delta.length === 0) {\n return '';\n }\n\n this.buffer += delta;\n return this.projectVisibleText({ final: false });\n }\n\n flush(): string {\n return this.projectVisibleText({ final: true });\n }\n\n private projectVisibleText(options: IProjectionOptions): string {\n const result = projectText(this.buffer, options);\n this.hasRemovedReasoning = this.hasRemovedReasoning || result.removedReasoning;\n\n const nextVisibleText = result.visibleParts.join('');\n const delta = nextVisibleText.slice(this.emittedVisibleText.length);\n this.emittedVisibleText = nextVisibleText;\n return delta;\n }\n}\n\nfunction projectText(rawText: string, options: IProjectionOptions): IProjectionState {\n const state: IProjectionState = {\n visibleParts: [],\n removedReasoning: false,\n };\n\n let cursor = 0;\n while (cursor < rawText.length) {\n const nextMarker = rawText.indexOf(START_MARKER, cursor);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), options);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), options);\n const afterStart = nextMarker + START_MARKER.length;\n const markerEnd = rawText.indexOf(END_MARKER, afterStart);\n\n if (markerEnd === -1) {\n if (options.final) {\n state.removedReasoning = true;\n }\n break;\n }\n\n state.removedReasoning = true;\n cursor = consumeChannelBlock(rawText, afterStart, markerEnd);\n }\n\n return state;\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IProjectionOptions,\n): void {\n if (tail.length === 0) {\n return;\n }\n\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n\n const heldLength = longestStartMarkerPrefixSuffixLength(tail);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction consumeChannelBlock(rawText: string, afterStart: number, markerEnd: number): number {\n const channelText = rawText.slice(afterStart, markerEnd);\n let cursor = markerEnd + END_MARKER.length;\n\n if (channelText.trim().length === 0) {\n const followingThoughtLabel = rawText.slice(cursor).match(/^thought(?:\\r?\\n)*/);\n if (followingThoughtLabel) {\n cursor += followingThoughtLabel[0].length;\n }\n return cursor;\n }\n\n const channelLabel = channelText.split(/\\r?\\n/, 1)[0]?.trim();\n if (channelLabel === THOUGHT_LABEL) {\n return cursor;\n }\n\n return cursor;\n}\n\nfunction longestStartMarkerPrefixSuffixLength(text: string): number {\n const maxLength = Math.min(text.length, START_MARKER.length - 1);\n for (let length = maxLength; length > 0; length -= 1) {\n if (START_MARKER.startsWith(text.slice(text.length - length))) {\n return length;\n }\n }\n return 0;\n}\n","import type {\n IGemmaConsumedPseudoBlock,\n IGemmaConsumedPseudoToolTag,\n IGemmaParsedPseudoTag,\n IGemmaPseudoProjectionOptions,\n TGemmaJsonValue,\n} from './pseudo-tool-call-types';\n\nconst XML_START_MARKER = '<';\n\nexport function createGemmaPseudoStartMarkers(toolNames: readonly string[]): string[] {\n void toolNames;\n return [XML_START_MARKER];\n}\n\nexport function findNextGemmaPseudoStartMarker(\n text: string,\n cursor: number,\n markers: readonly string[],\n): number {\n void markers;\n return text.indexOf(XML_START_MARKER, cursor);\n}\n\nexport function longestGemmaPseudoStartPrefixSuffixLength(\n text: string,\n markers: readonly string[],\n): number {\n void markers;\n return text.endsWith(XML_START_MARKER) ? XML_START_MARKER.length : 0;\n}\n\nexport function parseGemmaPseudoTag(\n text: string,\n start: number,\n): IGemmaParsedPseudoTag | undefined {\n const tagEnd = text.indexOf('>', start + 1);\n if (tagEnd === -1) {\n return undefined;\n }\n\n const rawOpenTag = text.slice(start, tagEnd + 1);\n const tagMatch = rawOpenTag.match(/^<\\s*([A-Za-z][\\w:-]*)([\\s/>][\\s\\S]*?|)>$/);\n if (!tagMatch) {\n return undefined;\n }\n\n const tagName = tagMatch[1] ?? '';\n return {\n tagName,\n normalizedName: tagName.toLowerCase(),\n rawOpenTag,\n attributes: parseAttributes(tagMatch[2] ?? ''),\n openEnd: tagEnd + 1,\n selfClosing: /\\/\\s*>$/.test(rawOpenTag),\n };\n}\n\nexport function consumeGemmaPseudoControlBlock(\n text: string,\n tag: IGemmaParsedPseudoTag,\n options: IGemmaPseudoProjectionOptions,\n): IGemmaConsumedPseudoBlock {\n if (tag.selfClosing) {\n return {\n innerText: '',\n end: tag.openEnd,\n complete: true,\n };\n }\n\n const closeStart = indexOfClosingTag(text, tag.tagName, tag.openEnd);\n if (closeStart === -1) {\n return {\n innerText: text.slice(tag.openEnd),\n end: options.final ? text.length : tag.openEnd - tag.rawOpenTag.length,\n complete: false,\n };\n }\n\n const closingTagEnd = text.indexOf('>', closeStart);\n return {\n innerText: text.slice(tag.openEnd, closeStart),\n end: closingTagEnd === -1 ? text.length : closingTagEnd + 1,\n complete: true,\n };\n}\n\nexport function consumeGemmaPseudoToolTag(\n text: string,\n tag: IGemmaParsedPseudoTag,\n): IGemmaConsumedPseudoToolTag {\n if (tag.selfClosing) {\n return { rawText: tag.rawOpenTag, end: tag.openEnd };\n }\n\n const closeStart = indexOfClosingTag(text, tag.tagName, tag.openEnd);\n if (closeStart === -1) {\n return { rawText: tag.rawOpenTag, end: tag.openEnd };\n }\n\n const closingTagEnd = text.indexOf('>', closeStart);\n const end = closingTagEnd === -1 ? text.length : closingTagEnd + 1;\n return { rawText: text.slice(tag.openEnd - tag.rawOpenTag.length, end), end };\n}\n\nexport function findGemmaDeclaredToolName(\n tagName: string,\n toolNames: readonly string[],\n): string | undefined {\n const normalizedTagName = normalizeToolName(tagName);\n return toolNames.find((toolName) => normalizeToolName(toolName) === normalizedTagName);\n}\n\nfunction parseAttributes(attributeText: string): Record<string, TGemmaJsonValue> {\n const attributes: Record<string, TGemmaJsonValue> = {};\n const pattern = /([A-Za-z_][\\w:-]*)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/g;\n let match = pattern.exec(attributeText);\n while (match) {\n const key = match[1] ?? '';\n const rawValue = match[2] ?? match[3] ?? '';\n attributes[key] = parseAttributeValue(decodeXmlEntities(rawValue));\n match = pattern.exec(attributeText);\n }\n return attributes;\n}\n\nfunction parseAttributeValue(value: string): TGemmaJsonValue {\n if (value === 'true') return true;\n if (value === 'false') return false;\n if (value === 'null') return null;\n if (/^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$/.test(value)) {\n return Number(value);\n }\n return value;\n}\n\nfunction decodeXmlEntities(value: string): string {\n return value\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&');\n}\n\nfunction indexOfClosingTag(text: string, tagName: string, cursor: number): number {\n return text.toLowerCase().indexOf(`</${tagName.toLowerCase()}>`, cursor);\n}\n\nfunction normalizeToolName(value: string): string {\n return value.replace(/[^a-z0-9]/gi, '').toLowerCase();\n}\n","import { findGemmaDeclaredToolName } from './pseudo-tool-call-tag-parser';\n\nimport type { TGemmaJsonValue } from './pseudo-tool-call-types';\n\nexport interface IGemmaPseudoCommandEnvelope {\n toolName: string;\n args: Record<string, TGemmaJsonValue>;\n}\n\nexport function parseGemmaPseudoCommandEnvelopes(\n rawText: string,\n toolNames: readonly string[],\n): IGemmaPseudoCommandEnvelope[] {\n const jsonEnvelope = parseGemmaPseudoCommandEnvelope(rawText, toolNames);\n return jsonEnvelope ? [jsonEnvelope] : [];\n}\n\nexport function parseGemmaPseudoCommandEnvelope(\n rawText: string,\n toolNames: readonly string[],\n): IGemmaPseudoCommandEnvelope | undefined {\n const openEnd = rawText.indexOf('>');\n const closeStart = rawText.lastIndexOf('</');\n if (openEnd === -1 || closeStart === -1 || closeStart <= openEnd) {\n return undefined;\n }\n\n const parsed = parseJsonValue(rawText.slice(openEnd + 1, closeStart).trim());\n if (!isJsonRecord(parsed)) {\n return undefined;\n }\n\n const command = parsed['command'];\n const args = parsed['args'];\n if (typeof command !== 'string' || !isJsonRecord(args)) {\n return undefined;\n }\n\n const toolName = findGemmaDeclaredToolName(command, toolNames);\n if (!toolName) {\n return undefined;\n }\n\n return { toolName, args };\n}\n\nfunction parseJsonValue(text: string): TGemmaJsonValue | undefined {\n try {\n return JSON.parse(text) as TGemmaJsonValue;\n } catch {\n return undefined;\n }\n}\n\nfunction isJsonRecord(\n value: TGemmaJsonValue | undefined,\n): value is Record<string, TGemmaJsonValue> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { parseGemmaPseudoCommandEnvelopes } from './pseudo-command-envelope';\nimport {\n consumeGemmaPseudoControlBlock,\n consumeGemmaPseudoToolTag,\n createGemmaPseudoStartMarkers,\n findGemmaDeclaredToolName,\n findNextGemmaPseudoStartMarker,\n longestGemmaPseudoStartPrefixSuffixLength,\n parseGemmaPseudoTag,\n} from './pseudo-tool-call-tag-parser';\n\nimport type {\n IGemmaConsumedPseudoBlock,\n IGemmaParsedPseudoTag,\n IGemmaPseudoProjectionOptions,\n TGemmaJsonValue,\n} from './pseudo-tool-call-types';\nimport type { IToolCall } from '@robota-sdk/agent-core';\n\nconst DEFAULT_CALL_ID_PREFIX = 'gemma_call';\n\nexport interface IGemmaPseudoToolCallProjection {\n visibleText: string;\n toolCalls: IToolCall[];\n removedToolCallText: boolean;\n rawToolCallTextParts: string[];\n}\n\nexport interface IGemmaPseudoToolCallProjectorOptions {\n toolNames: readonly string[];\n callIdPrefix?: string;\n startCallIndex?: number;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n toolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n removedToolCallText: boolean;\n}\n\ninterface IProjectTagResult {\n cursor: number;\n completed: boolean;\n}\n\nexport function projectGemmaPseudoToolCallText(\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IGemmaPseudoToolCallProjection {\n const state = createProjectionState();\n const markers = createGemmaPseudoStartMarkers(options.toolNames);\n let cursor = 0;\n\n while (cursor < rawText.length) {\n const nextMarker = findNextGemmaPseudoStartMarker(rawText, cursor, markers);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), projectionOptions, markers);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), projectionOptions, markers);\n const result = projectTagAt(rawText, nextMarker, state, options, projectionOptions);\n if (!result.completed) {\n break;\n }\n cursor = result.cursor;\n }\n\n return {\n visibleText: state.visibleParts.join(''),\n toolCalls: state.toolCalls,\n rawToolCallTextParts: state.rawToolCallTextParts,\n removedToolCallText: state.removedToolCallText,\n };\n}\n\nfunction projectTagAt(\n rawText: string,\n tagStart: number,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n const tag = parseGemmaPseudoTag(rawText, tagStart);\n if (!tag) {\n return projectMalformedTag(rawText, tagStart, state, projectionOptions);\n }\n const toolName = findGemmaDeclaredToolName(tag.tagName, options.toolNames);\n if (toolName) {\n return projectToolTag(rawText, tag, toolName, state, options);\n }\n return projectXmlArtifact(rawText, tagStart, tag, state, options, projectionOptions);\n}\n\nfunction projectMalformedTag(\n rawText: string,\n tagStart: number,\n state: IProjectionState,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n if (!projectionOptions.final) {\n return { cursor: tagStart, completed: false };\n }\n state.visibleParts.push(rawText[tagStart] ?? '');\n return { cursor: tagStart + 1, completed: true };\n}\n\nfunction projectXmlArtifact(\n rawText: string,\n tagStart: number,\n tag: IGemmaParsedPseudoTag,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n projectionOptions: IGemmaPseudoProjectionOptions,\n): IProjectTagResult {\n const block = consumeGemmaPseudoControlBlock(rawText, tag, projectionOptions);\n if (!block.complete && !projectionOptions.final) {\n return { cursor: tagStart, completed: false };\n }\n\n const rawControlText = rawText.slice(tagStart, block.end);\n const rawPartCount = state.rawToolCallTextParts.length;\n state.removedToolCallText = true;\n appendCommandEnvelopeToolCall(state, rawControlText, options);\n mergeProjection(state, projectControlBlockInner(block, state, options));\n if (state.rawToolCallTextParts.length === rawPartCount) {\n state.rawToolCallTextParts.push(rawControlText);\n }\n return { cursor: block.end, completed: true };\n}\n\nfunction projectControlBlockInner(\n block: IGemmaConsumedPseudoBlock,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): IGemmaPseudoToolCallProjection {\n return projectGemmaPseudoToolCallText(\n block.innerText,\n {\n ...options,\n startCallIndex: getNextCallIndex(state, options),\n },\n { final: true },\n );\n}\n\nfunction projectToolTag(\n rawText: string,\n tag: IGemmaParsedPseudoTag,\n toolName: string,\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): IProjectTagResult {\n const rawToolTag = consumeGemmaPseudoToolTag(rawText, tag);\n appendToolCall(state, toolName, tag.attributes, rawToolTag.rawText, options);\n return { cursor: rawToolTag.end, completed: true };\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IGemmaPseudoProjectionOptions,\n markers: readonly string[],\n): void {\n if (tail.length === 0) {\n return;\n }\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n const heldLength = longestGemmaPseudoStartPrefixSuffixLength(tail, markers);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction appendToolCall(\n state: IProjectionState,\n toolName: string,\n args: Record<string, TGemmaJsonValue>,\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n): void {\n if (Object.keys(args).length === 0) {\n return;\n }\n state.toolCalls.push(createToolCall(toolName, args, options, state));\n state.rawToolCallTextParts.push(rawText);\n state.removedToolCallText = true;\n}\n\nfunction appendCommandEnvelopeToolCall(\n state: IProjectionState,\n rawText: string,\n options: IGemmaPseudoToolCallProjectorOptions,\n): void {\n const commands = parseGemmaPseudoCommandEnvelopes(rawText, options.toolNames);\n for (const command of commands) {\n state.toolCalls.push(createToolCall(command.toolName, command.args, options, state));\n state.rawToolCallTextParts.push(rawText);\n }\n}\n\nfunction createToolCall(\n toolName: string,\n args: Record<string, TGemmaJsonValue>,\n options: IGemmaPseudoToolCallProjectorOptions,\n state: IProjectionState,\n): IToolCall {\n return {\n id: `${options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX}_${getNextCallIndex(state, options)}`,\n type: 'function',\n function: {\n name: toolName,\n arguments: JSON.stringify(args),\n },\n };\n}\n\nfunction createProjectionState(): IProjectionState {\n return {\n visibleParts: [],\n toolCalls: [],\n rawToolCallTextParts: [],\n removedToolCallText: false,\n };\n}\n\nfunction mergeProjection(\n state: IProjectionState,\n projection: IGemmaPseudoToolCallProjection,\n): void {\n state.toolCalls.push(...projection.toolCalls);\n state.rawToolCallTextParts.push(...projection.rawToolCallTextParts);\n state.removedToolCallText = state.removedToolCallText || projection.removedToolCallText;\n}\n\nfunction getNextCallIndex(\n state: IProjectionState,\n options: IGemmaPseudoToolCallProjectorOptions,\n): number {\n return (options.startCallIndex ?? 0) + state.toolCalls.length;\n}\n","const STRING_DELIMITER = '<|\"|>';\n\nexport interface IGemmaArgumentObject {\n [key: string]: TGemmaArgumentValue;\n}\n\nexport type TGemmaArgumentValue =\n | string\n | number\n | boolean\n | null\n | IGemmaArgumentObject\n | TGemmaArgumentValue[];\n\nexport class GemmaArgumentParser {\n private cursor = 0;\n\n constructor(private readonly source: string) {}\n\n parse(): IGemmaArgumentObject | undefined {\n const value = this.parseObject();\n this.skipWhitespace();\n if (this.cursor !== this.source.length) {\n return undefined;\n }\n return value;\n }\n\n private parseObject(): IGemmaArgumentObject | undefined {\n if (!this.consume('{')) return undefined;\n const result: IGemmaArgumentObject = {};\n this.skipWhitespace();\n if (this.consume('}')) return result;\n\n while (this.cursor < this.source.length) {\n const key = this.parseKey();\n if (!key || !this.consume(':')) return undefined;\n const value = this.parseValue();\n if (value === undefined) return undefined;\n result[key] = value;\n this.skipWhitespace();\n if (this.consume('}')) return result;\n if (!this.consume(',')) return undefined;\n }\n return undefined;\n }\n\n private parseArray(): TGemmaArgumentValue[] | undefined {\n if (!this.consume('[')) return undefined;\n const result: TGemmaArgumentValue[] = [];\n this.skipWhitespace();\n if (this.consume(']')) return result;\n\n while (this.cursor < this.source.length) {\n const value = this.parseValue();\n if (value === undefined) return undefined;\n result.push(value);\n this.skipWhitespace();\n if (this.consume(']')) return result;\n if (!this.consume(',')) return undefined;\n }\n return undefined;\n }\n\n private parseValue(): TGemmaArgumentValue | undefined {\n this.skipWhitespace();\n if (this.source.startsWith(STRING_DELIMITER, this.cursor)) return this.parseString();\n if (this.source.startsWith('{', this.cursor)) return this.parseObject();\n if (this.source.startsWith('[', this.cursor)) return this.parseArray();\n if (this.consumeLiteral('true')) return true;\n if (this.consumeLiteral('false')) return false;\n if (this.consumeLiteral('null')) return null;\n return this.parseNumber();\n }\n\n private parseKey(): string | undefined {\n this.skipWhitespace();\n if (this.source.startsWith(STRING_DELIMITER, this.cursor)) return this.parseString();\n const match = /^[A-Za-z_][A-Za-z0-9_-]*/.exec(this.source.slice(this.cursor));\n if (!match) return undefined;\n this.cursor += match[0].length;\n this.skipWhitespace();\n return match[0];\n }\n\n private parseString(): string | undefined {\n if (!this.consume(STRING_DELIMITER)) return undefined;\n const end = this.source.indexOf(STRING_DELIMITER, this.cursor);\n if (end === -1) return undefined;\n const value = this.source.slice(this.cursor, end);\n this.cursor = end + STRING_DELIMITER.length;\n this.skipWhitespace();\n return value;\n }\n\n private parseNumber(): number | undefined {\n const match = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/.exec(\n this.source.slice(this.cursor),\n );\n if (!match) return undefined;\n this.cursor += match[0].length;\n this.skipWhitespace();\n return Number(match[0]);\n }\n\n private consume(expected: string): boolean {\n this.skipWhitespace();\n if (!this.source.startsWith(expected, this.cursor)) return false;\n this.cursor += expected.length;\n this.skipWhitespace();\n return true;\n }\n\n private consumeLiteral(expected: string): boolean {\n if (!this.source.startsWith(expected, this.cursor)) return false;\n this.cursor += expected.length;\n this.skipWhitespace();\n return true;\n }\n\n private skipWhitespace(): void {\n while (/\\s/.test(this.source[this.cursor] ?? '')) {\n this.cursor += 1;\n }\n }\n}\n","import { projectGemmaPseudoToolCallText } from './pseudo-tool-call-projector';\nimport { GemmaArgumentParser } from './tool-call-argument-parser';\n\nimport type {\n IOpenAICompatibleToolCallTextProjection,\n IOpenAICompatibleToolCallTextProjector,\n} from '../shared/openai-compatible/index.js';\nimport type { IToolCall, IToolSchema } from '@robota-sdk/agent-core';\n\nconst TOOL_CALL_START = '<|tool_call>';\nconst TOOL_CALL_END = '<tool_call|>';\nconst CALL_PREFIX = 'call:';\nconst DEFAULT_CALL_ID_PREFIX = 'gemma_call';\n\nexport interface IGemmaToolCallProjectorOptions {\n toolNames: readonly string[];\n callIdPrefix?: string;\n}\n\nexport interface IGemmaToolCallProjection extends IOpenAICompatibleToolCallTextProjection {\n rawText: string;\n}\n\ninterface IProjectionOptions {\n final: boolean;\n}\n\ninterface IProjectionState {\n visibleParts: string[];\n toolCalls: IToolCall[];\n rawToolCallTextParts: string[];\n removedToolCallText: boolean;\n}\n\nexport function createGemmaToolCallProjector(\n tools: readonly IToolSchema[] | undefined,\n): GemmaToolCallProjector | undefined {\n if (!tools || tools.length === 0) {\n return undefined;\n }\n return new GemmaToolCallProjector({ toolNames: tools.map((tool) => tool.name) });\n}\n\nexport function projectGemmaToolCallText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n): IGemmaToolCallProjection {\n const result = projectText(rawText, options, { final: true });\n return toPublicProjection(rawText, result);\n}\n\nexport class GemmaToolCallProjector implements IOpenAICompatibleToolCallTextProjector {\n private buffer = '';\n private emittedVisibleText = '';\n private emittedRawToolCallText = '';\n private readonly emittedToolCallIds = new Set<string>();\n\n constructor(private readonly options: IGemmaToolCallProjectorOptions) {}\n\n project(delta: string): IOpenAICompatibleToolCallTextProjection {\n if (delta.length === 0) {\n return emptyProjection();\n }\n\n this.buffer += delta;\n return this.projectVisibleText({ final: false });\n }\n\n flush(): IOpenAICompatibleToolCallTextProjection {\n return this.projectVisibleText({ final: true });\n }\n\n private projectVisibleText(options: IProjectionOptions): IOpenAICompatibleToolCallTextProjection {\n const result = projectText(this.buffer, this.options, options);\n const nextVisibleText = result.visibleParts.join('');\n const visibleText = nextVisibleText.slice(this.emittedVisibleText.length);\n const nextRawToolCallText = result.rawToolCallTextParts.join('');\n const rawToolCallText = nextRawToolCallText.slice(this.emittedRawToolCallText.length);\n this.emittedVisibleText = nextVisibleText;\n this.emittedRawToolCallText = nextRawToolCallText;\n\n const toolCalls = result.toolCalls.filter((toolCall) => {\n if (this.emittedToolCallIds.has(toolCall.id)) {\n return false;\n }\n this.emittedToolCallIds.add(toolCall.id);\n return true;\n });\n\n return {\n visibleText,\n toolCalls,\n removedToolCallText: rawToolCallText.length > 0,\n ...(rawToolCallText.length > 0 && {\n rawToolCallText,\n }),\n };\n }\n}\n\nfunction projectText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n projectionOptions: IProjectionOptions,\n): IProjectionState {\n const nativeProjection = projectNativeToolCallText(rawText, options, projectionOptions);\n const pseudoProjection = projectGemmaPseudoToolCallText(\n nativeProjection.visibleParts.join(''),\n {\n toolNames: options.toolNames,\n callIdPrefix: options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX,\n startCallIndex: nativeProjection.toolCalls.length,\n },\n projectionOptions,\n );\n\n return {\n visibleParts: [pseudoProjection.visibleText],\n toolCalls: [...nativeProjection.toolCalls, ...pseudoProjection.toolCalls],\n rawToolCallTextParts: [\n ...nativeProjection.rawToolCallTextParts,\n ...pseudoProjection.rawToolCallTextParts,\n ],\n removedToolCallText:\n nativeProjection.removedToolCallText || pseudoProjection.removedToolCallText,\n };\n}\n\nfunction projectNativeToolCallText(\n rawText: string,\n options: IGemmaToolCallProjectorOptions,\n projectionOptions: IProjectionOptions,\n): IProjectionState {\n const state = createProjectionState();\n const toolNames = new Set(options.toolNames);\n let cursor = 0;\n let projectedCallIndex = 0;\n\n while (cursor < rawText.length) {\n const nextMarker = rawText.indexOf(TOOL_CALL_START, cursor);\n if (nextMarker === -1) {\n appendVisibleTail(state, rawText.slice(cursor), projectionOptions);\n break;\n }\n\n appendVisibleTail(state, rawText.slice(cursor, nextMarker), projectionOptions);\n const afterStart = nextMarker + TOOL_CALL_START.length;\n const markerEnd = rawText.indexOf(TOOL_CALL_END, afterStart);\n if (markerEnd === -1) {\n if (projectionOptions.final) {\n state.visibleParts.push(rawText.slice(nextMarker));\n }\n break;\n }\n\n const rawBlock = rawText.slice(nextMarker, markerEnd + TOOL_CALL_END.length);\n const blockText = rawText.slice(afterStart, markerEnd);\n const toolCall = parseToolCallBlock(blockText, toolNames, options, projectedCallIndex);\n if (!toolCall) {\n state.visibleParts.push(rawBlock);\n } else {\n state.toolCalls.push(toolCall);\n state.rawToolCallTextParts.push(rawBlock);\n state.removedToolCallText = true;\n projectedCallIndex += 1;\n }\n cursor = markerEnd + TOOL_CALL_END.length;\n }\n\n return state;\n}\n\nfunction parseToolCallBlock(\n blockText: string,\n toolNames: ReadonlySet<string>,\n options: IGemmaToolCallProjectorOptions,\n projectedCallIndex: number,\n): IToolCall | undefined {\n const trimmed = blockText.trim();\n if (!trimmed.startsWith(CALL_PREFIX)) {\n return undefined;\n }\n\n const callText = trimmed.slice(CALL_PREFIX.length).trimStart();\n const argsStart = callText.indexOf('{');\n if (argsStart <= 0) {\n return undefined;\n }\n\n const toolName = callText.slice(0, argsStart).trim();\n if (!toolNames.has(toolName)) {\n return undefined;\n }\n\n const args = new GemmaArgumentParser(callText.slice(argsStart)).parse();\n if (!args) {\n return undefined;\n }\n\n return {\n id: `${options.callIdPrefix ?? DEFAULT_CALL_ID_PREFIX}_${projectedCallIndex}`,\n type: 'function',\n function: {\n name: toolName,\n arguments: JSON.stringify(args),\n },\n };\n}\n\nfunction createProjectionState(): IProjectionState {\n return {\n visibleParts: [],\n toolCalls: [],\n rawToolCallTextParts: [],\n removedToolCallText: false,\n };\n}\n\nfunction appendVisibleTail(\n state: IProjectionState,\n tail: string,\n options: IProjectionOptions,\n): void {\n if (tail.length === 0) {\n return;\n }\n\n if (options.final) {\n state.visibleParts.push(tail);\n return;\n }\n\n const heldLength = longestStartMarkerPrefixSuffixLength(tail);\n state.visibleParts.push(tail.slice(0, tail.length - heldLength));\n}\n\nfunction longestStartMarkerPrefixSuffixLength(text: string): number {\n const maxLength = Math.min(text.length, TOOL_CALL_START.length - 1);\n for (let length = maxLength; length > 0; length -= 1) {\n if (TOOL_CALL_START.startsWith(text.slice(text.length - length))) {\n return length;\n }\n }\n return 0;\n}\n\nfunction toPublicProjection(rawText: string, state: IProjectionState): IGemmaToolCallProjection {\n return {\n rawText,\n visibleText: state.visibleParts.join(''),\n toolCalls: state.toolCalls,\n removedToolCallText: state.removedToolCallText,\n ...(state.rawToolCallTextParts.length > 0 && {\n rawToolCallText: state.rawToolCallTextParts.join(''),\n }),\n };\n}\n\nfunction emptyProjection(): IOpenAICompatibleToolCallTextProjection {\n return {\n visibleText: '',\n toolCalls: [],\n removedToolCallText: false,\n };\n}\n","import { projectGemmaReasoningText } from './reasoning-projector';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\nimport { OpenAICompatibleResponseParser } from '../shared/openai-compatible/index.js';\n\nimport type { IChatOptions, ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport function parseGemmaChatCompletion(\n response: OpenAI.Chat.ChatCompletion,\n logger: ILogger,\n options: IChatOptions | undefined,\n): TUniversalMessage {\n const rawContent = response.choices?.[0]?.message.content || '';\n const parser = new OpenAICompatibleResponseParser({\n logger,\n ...(options?.tools && {\n toolCallTextProjector: createGemmaToolCallProjector(options.tools),\n }),\n });\n const parsed = parser.parseResponse(response);\n const projection = projectGemmaReasoningText(parsed.content ?? '');\n\n return withGemmaProjectionMetadata(\n {\n ...parsed,\n content: projection.visibleText,\n },\n rawContent,\n projection.removedReasoning,\n );\n}\n\nexport function withGemmaProjectionMetadata(\n message: TUniversalMessage,\n rawContent: string,\n removedReasoning: boolean,\n): TUniversalMessage {\n if (!removedReasoning) {\n return message;\n }\n\n return {\n ...message,\n metadata: {\n ...(message.metadata ?? {}),\n gemmaReasoningFiltered: true,\n gemmaRawContent: rawContent,\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { IToolCall, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport function createStreamTextMessage(\n content: string,\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n}\n\nexport function createStreamToolCallMessage(\n toolCalls: IToolCall[],\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: '',\n toolCalls,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: finishReason === 'stop' || finishReason === 'tool_calls',\n },\n };\n}\n","import { isAssistantMessage } from '@robota-sdk/agent-core';\n\nimport { createStreamTextMessage, createStreamToolCallMessage } from './message-factory';\nimport { GemmaReasoningProjector } from './reasoning-projector';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\nimport { OpenAICompatibleResponseParser } from '../shared/openai-compatible/index.js';\n\nimport type { IOpenAICompatibleToolCallTextProjector } from '../shared/openai-compatible/index.js';\nimport type { ILogger, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IGemmaStreamProjectionState {\n reasoningProjector: GemmaReasoningProjector;\n responseParser: OpenAICompatibleResponseParser;\n toolCallProjector?: IOpenAICompatibleToolCallTextProjector;\n}\n\nexport function createGemmaStreamProjectionState(\n logger: ILogger,\n tools: readonly IToolSchema[] | undefined,\n): IGemmaStreamProjectionState {\n return {\n reasoningProjector: new GemmaReasoningProjector(),\n responseParser: new OpenAICompatibleResponseParser({ logger }),\n ...(tools && { toolCallProjector: createGemmaToolCallProjector(tools) }),\n };\n}\n\nexport function projectGemmaStreamChunk(\n chunk: OpenAI.Chat.ChatCompletionChunk,\n state: IGemmaStreamProjectionState,\n): TUniversalMessage[] {\n const choice = chunk.choices?.[0];\n if (!choice) {\n return [];\n }\n\n const nativeToolCallMessage = state.responseParser.parseStreamingChunk(chunk);\n if (nativeToolCallMessage && isAssistantMessage(nativeToolCallMessage)) {\n if (nativeToolCallMessage.toolCalls?.length) {\n return [nativeToolCallMessage];\n }\n }\n\n return projectGemmaTextDelta(choice.delta.content || '', choice.finish_reason, state);\n}\n\nexport function flushGemmaStreamProjection(\n state: IGemmaStreamProjectionState,\n): TUniversalMessage[] {\n const messages = projectGemmaTextDelta('', null, state, true);\n const flushedContent = state.reasoningProjector.flush();\n if (flushedContent.length > 0) {\n messages.push(createStreamTextMessage(flushedContent, null));\n }\n return messages;\n}\n\nfunction projectGemmaTextDelta(\n rawContent: string,\n finishReason: OpenAI.Chat.ChatCompletionChunk.Choice['finish_reason'],\n state: IGemmaStreamProjectionState,\n flushToolProjector = false,\n): TUniversalMessage[] {\n const toolProjection = flushToolProjector\n ? state.toolCallProjector?.flush()\n : state.toolCallProjector?.project(rawContent);\n const messages: TUniversalMessage[] = [];\n\n if (toolProjection?.toolCalls.length) {\n messages.push(createStreamToolCallMessage(toolProjection.toolCalls, finishReason));\n }\n\n const contentAfterToolProjection = toolProjection?.visibleText ?? rawContent;\n const visibleContent = state.reasoningProjector.project(contentAfterToolProjection);\n if (visibleContent.length > 0) {\n messages.push(createStreamTextMessage(visibleContent, finishReason));\n }\n\n return messages;\n}\n","import { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport { parseGemmaChatCompletion, withGemmaProjectionMetadata } from './provider-projection';\nimport { GemmaReasoningProjector } from './reasoning-projector';\nimport {\n createGemmaStreamProjectionState,\n flushGemmaStreamProjection,\n projectGemmaStreamChunk,\n} from './streaming-projection';\nimport { createGemmaToolCallProjector } from './tool-call-projector';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n} from '../shared/openai-compatible/index.js';\n\nimport type { IGemmaProviderOptions } from './types';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport type {\n IAssistantMessage,\n IChatOptions,\n IProviderCapabilities,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\nexport class GemmaProvider extends AbstractAIProvider {\n override readonly name = 'gemma';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IGemmaProviderOptions;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IGemmaProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.baseURL !== undefined && { baseURL: options.baseURL }),\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either Gemma client, apiKey, or executor is required');\n }\n }\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemma Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return await this.chatWithStreamingAssembly(\n {\n ...requestParams,\n stream: true,\n },\n {\n ...options,\n onTextDelta: textDeltaCb,\n },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await this.client.chat.completions.create(requestParams);\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return parseGemmaChatCompletion(response, this.logger, options);\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma API request failed';\n throw new Error(`Gemma chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemma Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(requestParams);\n const projectionState = createGemmaStreamProjectionState(this.logger, options?.tools);\n\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'gemma',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n for (const message of projectGemmaStreamChunk(chunk, projectionState)) {\n yield message;\n }\n }\n\n for (const message of flushGemmaStreamProjection(projectionState)) {\n yield message;\n }\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma API request failed';\n throw new Error(`Gemma stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web search.',\n },\n webFetch: {\n supported: false,\n enabled: false,\n source: 'openai-compatible-chat-completions',\n reason:\n 'Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web fetch.',\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible local clients do not need explicit cleanup.\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams = {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n };\n\n return requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n } as OpenAI.Chat.ChatCompletionCreateParamsStreaming;\n }\n\n private async chatWithStreamingAssembly(\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n ): Promise<TUniversalMessage> {\n if (!this.client) {\n throw new Error(\n 'Gemma client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'gemma',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(\n requestParams,\n options.signal ? { signal: options.signal } : undefined,\n );\n const projector = new GemmaReasoningProjector();\n const result = await assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'gemma',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n textProjector: (text) => projector.project(text),\n textProjectorFlush: () => projector.flush(),\n toolCallTextProjector: createGemmaToolCallProjector(options.tools),\n });\n\n return withGemmaProjectionMetadata(result, projector.rawText, projector.removedReasoning);\n } catch (error) {\n const gemmaError = error as IOpenAICompatibleError;\n const errorMessage = gemmaError.message || 'Gemma streaming request failed';\n throw new Error(`Gemma stream failed: ${errorMessage}`);\n }\n }\n}\n","import { GemmaProvider } from './provider';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\n\nimport type { IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_GEMMA_PROVIDER_MODEL = 'supergemma4-26b-uncensored-v2';\nexport const DEFAULT_GEMMA_PROVIDER_API_KEY = 'lm-studio';\nexport const DEFAULT_GEMMA_PROVIDER_BASE_URL = 'http://localhost:1234/v1';\nconst GEMMA_MODEL_SOURCE_URL = 'https://ai.google.dev/gemma';\nconst GEMMA_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMMA_SETUP_URL = 'https://lmstudio.ai/docs/developer';\nconst GEMMA_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMMA_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'official',\n label: 'LM Studio local API documentation',\n url: GEMMA_SETUP_URL,\n sourceUrl: GEMMA_SETUP_URL,\n lastVerifiedAt: GEMMA_SETUP_LAST_VERIFIED_AT,\n },\n];\nconst GEMMA_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: GEMMA_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMMA_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMMA_PROVIDER_MODEL,\n displayName: 'SuperGemma 4 26B',\n capabilities: ['tools', 'streaming'],\n lifecycle: 'active',\n sourceUrl: GEMMA_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMMA_MODEL_LAST_VERIFIED_AT,\n },\n ],\n};\n\nexport function createGemmaProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemma',\n displayName: 'Gemma',\n description: 'Gemma-family local models through an OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_GEMMA_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMMA_PROVIDER_API_KEY,\n baseURL: DEFAULT_GEMMA_PROVIDER_BASE_URL,\n },\n modelCatalog: GEMMA_MODEL_CATALOG,\n setupHelpLinks: GEMMA_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'Gemma OpenAI-compatible base URL',\n defaultValue: DEFAULT_GEMMA_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'Gemma model',\n defaultValue: DEFAULT_GEMMA_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemma OpenAI-compatible API key',\n defaultValue: DEFAULT_GEMMA_PROVIDER_API_KEY,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n createProvider: (config) =>\n new GemmaProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemma requires apiKey');\n }\n return apiKey;\n}\n","import type { IBytedanceApiErrorResponse, IBytedanceProviderOptions } from './types';\nimport type { TProviderMediaResult } from '@robota-sdk/agent-core';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\n/** HTTP status codes used by the Bytedance API error mapper. */\nconst HTTP_UNAUTHORIZED = 401;\nconst HTTP_FORBIDDEN = 403;\nconst HTTP_NOT_FOUND = 404;\nconst HTTP_CONFLICT = 409;\nconst HTTP_TOO_MANY_REQUESTS = 429;\nconst HTTP_BAD_REQUEST = 400;\nconst HTTP_INTERNAL_ERROR = 500;\n\n/** Sends an HTTP request to the Bytedance API and returns the parsed JSON response. */\nexport async function requestJson<TResponse>(\n options: IBytedanceProviderOptions,\n request: {\n path: string;\n method: 'GET' | 'POST' | 'DELETE';\n body?: string;\n },\n): Promise<TProviderMediaResult<TResponse>> {\n const controller = new AbortController();\n const timeoutHandle = setTimeout(\n () => controller.abort(),\n options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n );\n try {\n const response = await fetch(buildUrl(options.baseUrl, request.path), {\n method: request.method,\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n ...(options.defaultHeaders ?? {}),\n },\n body: request.body,\n signal: controller.signal,\n });\n const responseText = await response.text();\n if (!response.ok) {\n return mapHttpError(response.status, responseText);\n }\n\n const parsedResult = parseJsonRecord(responseText);\n if (!parsedResult.ok) {\n return parsedResult;\n }\n return {\n ok: true,\n value: parsedResult.value as TResponse,\n };\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n ok: false,\n error: { code: 'PROVIDER_TIMEOUT', message: 'Bytedance media request timed out.' },\n };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: error instanceof Error ? error.message : 'Bytedance media request failed.',\n },\n };\n } finally {\n clearTimeout(timeoutHandle);\n }\n}\n\nfunction buildUrl(baseUrl: string, path: string): string {\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n const sanitizedPath = path.startsWith('/') ? path : `/${path}`;\n return `${sanitizedBaseUrl}${sanitizedPath}`;\n}\n\nfunction parseJsonRecord(\n responseText: string,\n): TProviderMediaResult<Record<string, string | number | boolean | undefined>> {\n try {\n const parsedValue = JSON.parse(responseText) as Record<\n string,\n string | number | boolean | undefined\n >;\n return { ok: true, value: parsedValue };\n } catch {\n return {\n ok: false,\n error: { code: 'PROVIDER_UPSTREAM_ERROR', message: 'Bytedance response is not valid JSON.' },\n };\n }\n}\n\nfunction parseErrorResponse(responseText: string): IBytedanceApiErrorResponse {\n try {\n return JSON.parse(responseText) as IBytedanceApiErrorResponse;\n } catch {\n return { message: responseText };\n }\n}\n\nfunction mapHttpError(statusCode: number, responseText: string): TProviderMediaResult<never> {\n const parsedError = parseErrorResponse(responseText);\n if (statusCode === HTTP_UNAUTHORIZED || statusCode === HTTP_FORBIDDEN) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_AUTH_ERROR',\n message: parsedError.message ?? 'Bytedance authentication failed.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_NOT_FOUND) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_JOB_NOT_FOUND',\n message: parsedError.message ?? 'Bytedance video job was not found.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_CONFLICT) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_JOB_NOT_CANCELLABLE',\n message: parsedError.message ?? 'Bytedance video job cannot be cancelled in current state.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode === HTTP_TOO_MANY_REQUESTS) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_RATE_LIMITED',\n message: parsedError.message ?? 'Bytedance rate limit exceeded.',\n details: parsedError.details,\n },\n };\n }\n if (statusCode >= HTTP_BAD_REQUEST && statusCode < HTTP_INTERNAL_ERROR) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: parsedError.message ?? 'Bytedance rejected request payload.',\n details: parsedError.details,\n },\n };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: parsedError.message ?? 'Bytedance upstream request failed.',\n details: parsedError.details,\n },\n };\n}\n","import type { IBytedanceVideoTaskResponse } from './types';\nimport type { TProviderMediaResult, IVideoJobSnapshot } from '@robota-sdk/agent-core';\n\n/** Threshold (in milliseconds) above which a numeric timestamp is treated as milliseconds rather than seconds. */\nconst MILLISECOND_EPOCH_THRESHOLD = 1_000_000_000_000;\n\n/** Conversion factor from seconds to milliseconds. */\nconst MS_PER_SECOND = 1000;\n\n/** Maps a Bytedance video task response into a normalized job snapshot. */\nexport function mapVideoJobSnapshot(\n response: IBytedanceVideoTaskResponse,\n): TProviderMediaResult<IVideoJobSnapshot> {\n if (response.id.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Bytedance video job response is missing task id.',\n },\n };\n }\n const normalizedStatusResult = mapVideoStatus(response.status);\n if (!normalizedStatusResult.ok) {\n return normalizedStatusResult;\n }\n return {\n ok: true,\n value: {\n jobId: response.id,\n status: normalizedStatusResult.value,\n output: mapOutput(response),\n error:\n normalizedStatusResult.value === 'failed' && response.error_message\n ? { code: 'PROVIDER_UPSTREAM_ERROR', message: response.error_message }\n : undefined,\n updatedAt: toIsoTimestamp(response.updated_at ?? response.created_at),\n },\n };\n}\n\n/** Maps a Bytedance status string to a normalized video job status. */\nexport function mapVideoStatus(status: string): TProviderMediaResult<IVideoJobSnapshot['status']> {\n const normalized = status.trim().toLowerCase();\n if (normalized === 'queued' || normalized === 'pending' || normalized === 'submitted') {\n return { ok: true, value: 'queued' };\n }\n if (normalized === 'running' || normalized === 'processing' || normalized === 'in_progress') {\n return { ok: true, value: 'running' };\n }\n if (normalized === 'succeeded' || normalized === 'success' || normalized === 'completed') {\n return { ok: true, value: 'succeeded' };\n }\n if (normalized === 'failed' || normalized === 'error') {\n return { ok: true, value: 'failed' };\n }\n if (normalized === 'cancelled' || normalized === 'canceled') {\n return { ok: true, value: 'cancelled' };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: `Unexpected video job status from Bytedance: ${status}`,\n },\n };\n}\n\n/** Maps the initial createVideo status to queued or running. */\nexport function mapInitialStatus(\n statusValue: string | undefined,\n): TProviderMediaResult<'queued' | 'running'> {\n if (typeof statusValue !== 'string' || statusValue.trim().length === 0) {\n return { ok: true, value: 'queued' };\n }\n const normalizedStatus = statusValue.trim().toLowerCase();\n if (\n normalizedStatus === 'queued' ||\n normalizedStatus === 'pending' ||\n normalizedStatus === 'submitted'\n ) {\n return { ok: true, value: 'queued' };\n }\n if (\n normalizedStatus === 'running' ||\n normalizedStatus === 'processing' ||\n normalizedStatus === 'in_progress'\n ) {\n return { ok: true, value: 'running' };\n }\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: `Unexpected createVideo status from Bytedance: ${statusValue}`,\n },\n };\n}\n\n/** Converts a numeric or string timestamp to ISO 8601 format. */\nexport function toIsoTimestamp(value: string | number | undefined): string {\n if (typeof value === 'number' && Number.isFinite(value)) {\n const numericTimestamp = value > MILLISECOND_EPOCH_THRESHOLD ? value : value * MS_PER_SECOND;\n const date = new Date(numericTimestamp);\n if (!Number.isNaN(date.getTime())) {\n return date.toISOString();\n }\n }\n if (typeof value === 'string' && value.trim().length > 0) {\n const maybeNumeric = Number(value);\n if (Number.isFinite(maybeNumeric)) {\n return toIsoTimestamp(maybeNumeric);\n }\n const parsedDate = new Date(value);\n if (!Number.isNaN(parsedDate.getTime())) {\n return parsedDate.toISOString();\n }\n }\n return new Date().toISOString();\n}\n\nfunction mapOutput(response: IBytedanceVideoTaskResponse): IVideoJobSnapshot['output'] {\n const directVideoUrl =\n typeof response.video_url === 'string' && response.video_url.trim().length > 0\n ? response.video_url\n : undefined;\n const contentVideoUrl =\n typeof response.content?.video_url === 'string' && response.content.video_url.trim().length > 0\n ? response.content.video_url\n : undefined;\n const resolvedVideoUrl = directVideoUrl ?? contentVideoUrl;\n if (typeof resolvedVideoUrl !== 'string') {\n return undefined;\n }\n return {\n kind: 'uri',\n uri: resolvedVideoUrl,\n mimeType: response.mime_type,\n bytes: response.bytes,\n };\n}\n","import { requestJson } from './http-client';\nimport { mapVideoJobSnapshot, mapInitialStatus, toIsoTimestamp } from './status-mapper';\n\nimport type {\n IBytedanceCreateVideoTaskRequest,\n IBytedanceCreateVideoTaskResponse,\n IBytedanceProviderOptions,\n IBytedanceVideoTaskResponse,\n TBytedanceTaskContent,\n} from './types';\nimport type {\n IInlineImageInputSource,\n IUriImageInputSource,\n TProviderMediaResult,\n IVideoGenerationProvider,\n IVideoGenerationRequest,\n IVideoJobAccepted,\n IVideoJobSnapshot,\n} from '@robota-sdk/agent-core';\n\nconst DEFAULT_CREATE_VIDEO_PATH = '/contents/generations/tasks';\nconst DEFAULT_GET_VIDEO_TASK_PATH_TEMPLATE = '/contents/generations/tasks/{taskId}';\nconst DEFAULT_CANCEL_VIDEO_TASK_PATH_TEMPLATE = '/contents/generations/tasks/{taskId}';\n\nexport class BytedanceProvider implements IVideoGenerationProvider {\n private readonly options: IBytedanceProviderOptions;\n\n public constructor(options: IBytedanceProviderOptions) {\n this.options = options;\n }\n\n public async createVideo(\n request: IVideoGenerationRequest,\n ): Promise<TProviderMediaResult<IVideoJobAccepted>> {\n if (request.prompt.trim().length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty prompt.');\n }\n if (request.model.trim().length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty model.');\n }\n if (typeof request.seed === 'number') {\n return buildInvalidRequestError(\n 'ModelArk Seedance provider does not support seed field in current contract.',\n );\n }\n\n const contentResult = this.buildContentPayload(request.prompt, request.inputImages);\n if (!contentResult.ok) {\n return contentResult;\n }\n\n const payload: IBytedanceCreateVideoTaskRequest = {\n model: request.model.trim(),\n content: contentResult.value,\n duration: request.durationSeconds,\n ratio: request.aspectRatio,\n };\n\n const responseResult = await requestJson<IBytedanceCreateVideoTaskResponse>(this.options, {\n path: this.options.createVideoPath ?? DEFAULT_CREATE_VIDEO_PATH,\n method: 'POST',\n body: JSON.stringify(payload),\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n\n if (responseResult.value.id.trim().length === 0) {\n return buildUpstreamError('Bytedance createVideo response is missing task id.');\n }\n const mappedStatus = mapInitialStatus(responseResult.value.status);\n if (!mappedStatus.ok) {\n return mappedStatus;\n }\n return {\n ok: true,\n value: {\n jobId: responseResult.value.id,\n status: mappedStatus.value,\n createdAt: toIsoTimestamp(responseResult.value.created_at),\n },\n };\n }\n\n public async getVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>> {\n if (jobId.trim().length === 0) {\n return buildInvalidRequestError('Video job lookup requires non-empty jobId.');\n }\n\n const responseResult = await requestJson<IBytedanceVideoTaskResponse>(this.options, {\n path: buildPath(\n this.options.getVideoTaskPathTemplate ?? DEFAULT_GET_VIDEO_TASK_PATH_TEMPLATE,\n jobId,\n ),\n method: 'GET',\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n return mapVideoJobSnapshot(responseResult.value);\n }\n\n public async cancelVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>> {\n if (jobId.trim().length === 0) {\n return buildInvalidRequestError('Video job cancellation requires non-empty jobId.');\n }\n\n const cancelMethod = this.options.cancelVideoTaskMethod ?? 'DELETE';\n const responseResult = await requestJson<IBytedanceVideoTaskResponse>(this.options, {\n path: buildPath(\n this.options.cancelVideoTaskPathTemplate ?? DEFAULT_CANCEL_VIDEO_TASK_PATH_TEMPLATE,\n jobId,\n ),\n method: cancelMethod,\n });\n if (!responseResult.ok) {\n return responseResult;\n }\n return mapVideoJobSnapshot(responseResult.value);\n }\n\n private buildContentPayload(\n prompt: string,\n inputImages: IVideoGenerationRequest['inputImages'],\n ): TProviderMediaResult<TBytedanceTaskContent[]> {\n const normalizedPrompt = prompt.trim();\n if (normalizedPrompt.length === 0) {\n return buildInvalidRequestError('Video generation requires non-empty prompt.');\n }\n const content: TBytedanceTaskContent[] = [{ type: 'text', text: normalizedPrompt }];\n if (Array.isArray(inputImages)) {\n for (const image of inputImages) {\n const imageUrlResult = toContentImageUrl(image);\n if (!imageUrlResult.ok) {\n return imageUrlResult;\n }\n content.push({ type: 'image_url', image_url: { url: imageUrlResult.value } });\n }\n }\n return { ok: true, value: content };\n }\n}\n\nfunction buildPath(template: string, taskId: string): string {\n return template.replace('{taskId}', encodeURIComponent(taskId));\n}\n\nfunction buildInvalidRequestError(message: string): TProviderMediaResult<never> {\n return { ok: false, error: { code: 'PROVIDER_INVALID_REQUEST', message } };\n}\n\nfunction buildUpstreamError(message: string): TProviderMediaResult<never> {\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message } };\n}\n\nfunction toContentImageUrl(\n image: IInlineImageInputSource | IUriImageInputSource,\n): TProviderMediaResult<string> {\n if (image.kind === 'uri') {\n if (image.uri.trim().length === 0) {\n return buildInvalidRequestError('Image uri must be non-empty.');\n }\n return { ok: true, value: image.uri };\n }\n if (image.data.trim().length === 0) {\n return buildInvalidRequestError('Inline image data must be non-empty.');\n }\n if (image.mimeType.trim().length === 0) {\n return buildInvalidRequestError('Inline image mimeType must be non-empty.');\n }\n return { ok: true, value: `data:${image.mimeType};base64,${image.data}` };\n}\n","export const QWEN_PROVIDER_BASE_URLS = {\n singapore: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n usVirginia: 'https://dashscope-us.aliyuncs.com/compatible-mode/v1',\n beijing: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n hongKong: 'https://cn-hongkong.dashscope.aliyuncs.com/compatible-mode/v1',\n} as const;\n\nexport type TQwenProviderRegion = keyof typeof QWEN_PROVIDER_BASE_URLS;\n\nexport const QWEN_PROVIDER_RESPONSES_BASE_URLS = {\n singapore: 'https://dashscope-intl.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n usVirginia: 'https://dashscope-us.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n beijing: 'https://dashscope.aliyuncs.com/api/v2/apps/protocols/compatible-mode/v1',\n} as const;\n\nexport type TQwenProviderResponsesRegion = keyof typeof QWEN_PROVIDER_RESPONSES_BASE_URLS;\n\nexport const DEFAULT_QWEN_PROVIDER_MODEL = 'qwen-plus';\nexport const DEFAULT_QWEN_PROVIDER_API_KEY_ENV = 'DASHSCOPE_API_KEY';\nexport const DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_QWEN_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_QWEN_PROVIDER_BASE_URL = QWEN_PROVIDER_BASE_URLS.singapore;\nexport const DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL = QWEN_PROVIDER_RESPONSES_BASE_URLS.singapore;\n\nexport const QWEN_MODEL_SOURCE_URL =\n 'https://www.alibabacloud.com/help/en/model-studio/compatibility-of-openai-with-dashscope';\nexport const QWEN_MODEL_LAST_VERIFIED_AT = '2026-05-04';\n","import type { IQwenProviderOptions } from './types';\nimport type { IProviderCapabilities } from '@robota-sdk/agent-core';\n\nconst QWEN_RESPONSES_SOURCE = 'qwen-responses';\nconst ENABLE_WEB_SEARCH_REASON = 'Enable builtInWebTools.webSearch or builtInWebTools.webFetch.';\nconst ENABLE_WEB_FETCH_REASON = 'Enable builtInWebTools.webFetch.';\n\nexport function getQwenProviderCapabilities(options: IQwenProviderOptions): IProviderCapabilities {\n const webTools = options.builtInWebTools;\n const webSearchEnabled = webTools?.webSearch === true || webTools?.webFetch === true;\n const webFetchEnabled = webTools?.webFetch === true;\n\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: webSearchEnabled\n ? { supported: true, enabled: true, source: QWEN_RESPONSES_SOURCE }\n : {\n supported: true,\n enabled: false,\n source: QWEN_RESPONSES_SOURCE,\n reason: ENABLE_WEB_SEARCH_REASON,\n },\n webFetch: webFetchEnabled\n ? { supported: true, enabled: true, source: QWEN_RESPONSES_SOURCE }\n : {\n supported: true,\n enabled: false,\n source: QWEN_RESPONSES_SOURCE,\n reason: ENABLE_WEB_FETCH_REASON,\n },\n },\n };\n}\n","import {\n assembleOpenAICompatibleStream,\n observeProviderNativeRawPayloadStream,\n} from '../shared/openai-compatible/index.js';\n\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport type { IChatOptions, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport async function qwenChatWithStreamingAssembly(\n client: OpenAI,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n options: IChatOptions,\n): Promise<TUniversalMessage> {\n try {\n options.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await client.chat.completions.create(\n requestParams,\n options.signal ? { signal: options.signal } : undefined,\n );\n\n return assembleOpenAICompatibleStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'qwen',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options.onProviderNativeRawPayload,\n }),\n onTextDelta: options.onTextDelta,\n signal: options.signal,\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen streaming request failed';\n throw new Error(`Qwen stream failed: ${errorMessage}`);\n }\n}\n","import type {\n IQwenBuiltInWebToolsOptions,\n IQwenResponsesFunctionTool,\n IQwenResponsesMessageInput,\n TQwenBuiltInWebToolName,\n TQwenResponsesInputItem,\n TQwenResponsesTool,\n} from './types';\nimport type { IAssistantMessage, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\n\nexport function getQwenBuiltInWebToolNames(\n options: IQwenBuiltInWebToolsOptions | undefined,\n): TQwenBuiltInWebToolName[] {\n const tools: TQwenBuiltInWebToolName[] = [];\n if (options?.webSearch === true || options?.webFetch === true) {\n tools.push('web_search');\n }\n if (options?.webFetch === true) {\n tools.push('web_extractor');\n }\n return tools;\n}\n\nexport function hasQwenBuiltInWebTools(options: IQwenBuiltInWebToolsOptions | undefined): boolean {\n return getQwenBuiltInWebToolNames(options).length > 0;\n}\n\nexport function convertToQwenResponsesInput(\n messages: TUniversalMessage[],\n): TQwenResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\nexport function buildQwenResponsesTools(\n builtInWebTools: readonly TQwenBuiltInWebToolName[],\n localTools: IToolSchema[] | undefined,\n): TQwenResponsesTool[] | undefined {\n const tools: TQwenResponsesTool[] = [\n ...builtInWebTools.map((type) => ({ type })),\n ...convertToQwenResponsesFunctionTools(localTools),\n ];\n return tools.length > 0 ? tools : undefined;\n}\n\nfunction convertToQwenResponsesFunctionTools(\n tools: IToolSchema[] | undefined,\n): IQwenResponsesFunctionTool[] {\n return (\n tools?.map((tool) => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n })) ?? []\n );\n}\n\nfunction convertMessage(message: TUniversalMessage): TQwenResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', message.content)];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TQwenResponsesInputItem[] {\n const items: TQwenResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction createMessageInput(\n role: IQwenResponsesMessageInput['role'],\n content: string | null,\n): IQwenResponsesMessageInput {\n return {\n role,\n content: content ?? '',\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done) break;\n if (signal?.aborted) break;\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) return iterator.next();\n if (signal.aborted) return { done: true, value: undefined as T };\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { streamWithAbort } from './responses-stream-utils';\n\nimport type {\n IQwenResponsesFunctionCallOutputItem,\n IQwenResponsesErrorEvent,\n IQwenResponsesResponse,\n IQwenResponsesUsage,\n TQwenBuiltInWebToolName,\n TQwenResponsesOutputItem,\n TQwenResponsesStreamEvent,\n} from './types';\nimport type { IToolCall, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\n\ninterface IQwenResponsesParseOptions {\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[];\n}\n\ninterface IQwenResponsesStreamAssemblyOptions extends IQwenResponsesParseOptions {\n stream: AsyncIterable<TQwenResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IQwenProviderToolUsage {\n webSearchCalls: number;\n webExtractorCalls: number;\n unsupportedToolTypes: Set<string>;\n}\n\ninterface IQwenResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IQwenResponsesResponse;\n usage: IQwenProviderToolUsage;\n}\n\nexport function parseQwenResponsesResponse(\n response: IQwenResponsesResponse,\n options: IQwenResponsesParseOptions,\n): TUniversalMessage {\n const output = response.output ?? [];\n const usage = collectProviderToolUsage(output, response.usage);\n const toolCalls = extractFunctionToolCalls(output);\n const content = response.output_text ?? extractMessageText(output);\n\n return buildAssistantMessage({\n content,\n toolCalls,\n response,\n usage,\n enabledBuiltInTools: options.enabledBuiltInTools,\n });\n}\n\nexport async function assembleQwenResponsesStream(\n options: IQwenResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IQwenResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n usage: createEmptyToolUsage(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state, options.enabledBuiltInTools);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n usage: state.usage,\n enabledBuiltInTools: options.enabledBuiltInTools,\n });\n}\n\nfunction applyStreamEvent(\n state: IQwenResponsesStreamState,\n event: TQwenResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeToolUsage(\n state.usage,\n collectProviderToolUsage(event.response.output ?? [], event.response.usage),\n );\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (event.type === 'response.web_search_call.completed') {\n state.usage.webSearchCalls += 1;\n return;\n }\n\n if (event.type === 'response.error' || event.type === 'response.failed') {\n throw new Error(`Qwen Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction buildMessageFromCompletedResponse(\n state: IQwenResponsesStreamState,\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[],\n): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('Qwen Responses stream completed without response metadata');\n }\n\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const usage = collectProviderToolUsage(output, response.usage);\n mergeToolUsage(usage, state.usage);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n usage,\n enabledBuiltInTools,\n });\n}\n\nfunction applyOutputItem(state: IQwenResponsesStreamState, item: TQwenResponsesOutputItem): void {\n if (item.type === 'function_call') {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n }\n return;\n }\n mergeToolUsage(state.usage, collectProviderToolUsage([item], undefined));\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IQwenResponsesResponse;\n usage: IQwenProviderToolUsage;\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[];\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && {\n usage: {\n promptTokens: input.response.usage.input_tokens ?? 0,\n completionTokens: input.response.usage.output_tokens ?? 0,\n totalTokens: input.response.usage.total_tokens ?? 0,\n },\n }),\n metadata: buildProviderToolMetadata(input.enabledBuiltInTools, input.usage, input.response),\n };\n}\n\nfunction buildProviderToolMetadata(\n enabledBuiltInTools: readonly TQwenBuiltInWebToolName[],\n usage: IQwenProviderToolUsage,\n response: IQwenResponsesResponse | undefined,\n): NonNullable<TUniversalMessage['metadata']> {\n const usedTools = collectUsedToolNames(usage);\n return {\n providerToolMode: 'qwen_responses',\n providerBuiltInToolsEnabled: [...enabledBuiltInTools],\n ...(usedTools.length > 0 && { providerBuiltInToolsUsed: usedTools }),\n qwenWebSearchCalls: usage.webSearchCalls,\n qwenWebExtractorCalls: usage.webExtractorCalls,\n ...(usage.unsupportedToolTypes.size > 0 && {\n qwenUnsupportedProviderToolTypes: [...usage.unsupportedToolTypes].sort(),\n }),\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n };\n}\n\nfunction collectUsedToolNames(usage: IQwenProviderToolUsage): TQwenBuiltInWebToolName[] {\n const used: TQwenBuiltInWebToolName[] = [];\n if (usage.webSearchCalls > 0) {\n used.push('web_search');\n }\n if (usage.webExtractorCalls > 0) {\n used.push('web_extractor');\n }\n return used;\n}\n\nfunction collectProviderToolUsage(\n output: readonly TQwenResponsesOutputItem[],\n responseUsage: IQwenResponsesUsage | undefined,\n): IQwenProviderToolUsage {\n const usage = createEmptyToolUsage();\n for (const item of output) {\n if (item.type === 'web_search_call') {\n usage.webSearchCalls += 1;\n } else if (item.type === 'web_extractor_call') {\n usage.webExtractorCalls += 1;\n } else if (isProviderToolOutput(item.type)) {\n usage.unsupportedToolTypes.add(item.type);\n }\n }\n applyUsageCounts(usage, responseUsage);\n return usage;\n}\n\nfunction applyUsageCounts(\n usage: IQwenProviderToolUsage,\n responseUsage: IQwenResponsesUsage | undefined,\n): void {\n const xTools = responseUsage?.x_tools;\n if (xTools === undefined) {\n return;\n }\n usage.webSearchCalls = Math.max(usage.webSearchCalls, xTools['web_search']?.count ?? 0);\n usage.webExtractorCalls = Math.max(usage.webExtractorCalls, xTools['web_extractor']?.count ?? 0);\n for (const toolName of Object.keys(xTools)) {\n if (toolName !== 'web_search' && toolName !== 'web_extractor') {\n usage.unsupportedToolTypes.add(toolName);\n }\n }\n}\n\nfunction mergeToolUsage(target: IQwenProviderToolUsage, source: IQwenProviderToolUsage): void {\n target.webSearchCalls = Math.max(target.webSearchCalls, source.webSearchCalls);\n target.webExtractorCalls = Math.max(target.webExtractorCalls, source.webExtractorCalls);\n for (const toolType of source.unsupportedToolTypes) {\n target.unsupportedToolTypes.add(toolType);\n }\n}\n\nfunction createEmptyToolUsage(): IQwenProviderToolUsage {\n return {\n webSearchCalls: 0,\n webExtractorCalls: 0,\n unsupportedToolTypes: new Set(),\n };\n}\n\nfunction isProviderToolOutput(type: string): boolean {\n return type.endsWith('_call') && type !== 'function_call';\n}\n\nfunction extractFunctionToolCalls(output: readonly TQwenResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TQwenResponsesOutputItem,\n): item is IQwenResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IQwenResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TQwenResponsesOutputItem[]): string {\n return output\n .filter((item): item is Extract<TQwenResponsesOutputItem, { type: 'message' }> => {\n return item.type === 'message';\n })\n .flatMap((item) => item.content)\n .map((part) => part.text)\n .join('');\n}\n\nfunction extractErrorMessage(event: IQwenResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n buildQwenResponsesTools,\n convertToQwenResponsesInput,\n getQwenBuiltInWebToolNames,\n} from './responses-converter';\nimport { assembleQwenResponsesStream, parseQwenResponsesResponse } from './responses-parser';\nimport {\n observeProviderNativeRawPayloadStream,\n type IOpenAICompatibleError,\n} from '../shared/openai-compatible/index.js';\n\nimport type {\n IQwenBuiltInWebToolsOptions,\n IQwenResponsesRequestNonStreaming,\n IQwenResponsesRequestStreaming,\n TQwenResponsesStreamEvent,\n} from './types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IQwenResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n defaultModel?: string;\n builtInWebTools?: IQwenBuiltInWebToolsOptions;\n onTextDelta?: TTextDeltaCallback;\n}\n\nexport async function chatWithQwenResponsesApi(\n input: IQwenResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithQwenResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return parseQwenResponsesResponse(response, {\n enabledBuiltInTools: getQwenBuiltInWebToolNames(input.builtInWebTools),\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen Responses API request failed';\n throw new Error(`Qwen responses failed: ${errorMessage}`);\n }\n}\n\nexport async function* chatStreamWithQwenResponsesApi(\n input: IQwenResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const deltas: TUniversalMessage[] = [];\n const result = await chatWithQwenResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n input.chatOptions?.onTextDelta?.(delta);\n deltas.push(createStreamDeltaMessage(delta));\n },\n },\n });\n\n for (const delta of deltas) {\n yield delta;\n }\n yield {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nasync function chatWithQwenResponsesStreamingAssembly(\n input: IQwenResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n input.chatOptions?.signal ? { signal: input.chatOptions.signal } : undefined,\n );\n return assembleQwenResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TQwenResponsesStreamEvent>,\n {\n provider: 'qwen',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n enabledBuiltInTools: getQwenBuiltInWebToolNames(input.builtInWebTools),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen Responses streaming request failed';\n throw new Error(`Qwen responses stream failed: ${errorMessage}`);\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IQwenResponsesChatOptions,\n): IQwenResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const enabledBuiltInTools = getQwenBuiltInWebToolNames(input.builtInWebTools);\n const tools = buildQwenResponsesTools(enabledBuiltInTools, input.chatOptions?.tools);\n\n return {\n model,\n input: convertToQwenResponsesInput(input.messages),\n ...(tools !== undefined && { tools }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(input.builtInWebTools?.enableThinking !== undefined && {\n enable_thinking: input.builtInWebTools.enableThinking,\n }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IQwenResponsesChatOptions,\n): IQwenResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n","import { AbstractAIProvider, SilentLogger } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport {\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n} from './defaults';\nimport { getQwenProviderCapabilities } from './provider-capabilities';\nimport { qwenChatWithStreamingAssembly } from './provider-streaming-assembly';\nimport { chatStreamWithQwenResponsesApi, chatWithQwenResponsesApi } from './responses-chat';\nimport { hasQwenBuiltInWebTools } from './responses-converter';\nimport {\n assembleOpenAICompatibleStream,\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n observeProviderNativeRawPayloadStream,\n OpenAICompatibleResponseParser,\n} from '../shared/openai-compatible/index.js';\n\nimport type { IQwenProviderOptions } from './types';\nimport type { IOpenAICompatibleError } from '../shared/openai-compatible/index.js';\nimport type {\n IChatOptions,\n IProviderCapabilities,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\nexport class QwenProvider extends AbstractAIProvider {\n override readonly name = 'qwen';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly responsesClient?: OpenAI;\n private readonly options: IQwenProviderOptions;\n private readonly responseParser: OpenAICompatibleResponseParser;\n\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IQwenProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n this.responsesClient = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL ?? DEFAULT_QWEN_PROVIDER_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n this.responsesClient = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.responsesBaseURL ?? DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n });\n } else {\n throw new Error('Either Qwen client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAICompatibleResponseParser({ logger: this.logger });\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n return this.chatViaExecutor(messages, options);\n }\n\n if (this.shouldUseResponsesApi()) {\n return this.chatViaResponsesApi(messages, options, this.getResponsesClient());\n }\n\n return this.chatViaChatCompletions(messages, options, this.getClient());\n }\n\n private async chatViaExecutor(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): Promise<TUniversalMessage> {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Qwen Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n private async chatViaResponsesApi(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n client: OpenAI,\n ): Promise<TUniversalMessage> {\n this.validateTools(options?.tools);\n return chatWithQwenResponsesApi({\n client,\n messages,\n chatOptions: options,\n defaultModel: this.options.defaultModel,\n builtInWebTools: this.options.builtInWebTools,\n onTextDelta: this.onTextDelta,\n });\n }\n\n private async chatViaChatCompletions(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n client: OpenAI,\n ): Promise<TUniversalMessage> {\n try {\n const requestParams = this.buildRequestParams(messages, options);\n const textDeltaCb = options?.onTextDelta ?? this.onTextDelta;\n if (textDeltaCb) {\n return qwenChatWithStreamingAssembly(\n client,\n { ...requestParams, stream: true },\n { ...options, onTextDelta: textDeltaCb },\n );\n }\n\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await client.chat.completions.create(requestParams);\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return this.responseParser.parseResponse(response);\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen API request failed';\n throw new Error(`Qwen chat failed: ${errorMessage}`);\n }\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Qwen Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error(\n 'Qwen client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n if (this.shouldUseResponsesApi()) {\n this.validateTools(options?.tools);\n yield* chatStreamWithQwenResponsesApi({\n client: this.responsesClient,\n messages,\n chatOptions: options,\n defaultModel: this.options.defaultModel,\n builtInWebTools: this.options.builtInWebTools,\n onTextDelta: this.onTextDelta,\n });\n return;\n }\n\n try {\n const requestParams = this.buildStreamingRequestParams(messages, options);\n options?.onProviderNativeRawPayload?.({\n provider: 'qwen',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const stream = await this.client.chat.completions.create(requestParams);\n\n const observedStream = observeProviderNativeRawPayloadStream(stream, {\n provider: 'qwen',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: options?.onProviderNativeRawPayload,\n });\n\n for await (const chunk of this.streamWithAbort(observedStream, options?.signal)) {\n const universalMessage = this.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield universalMessage;\n }\n }\n } catch (error) {\n const qwenError = error as IOpenAICompatibleError;\n const errorMessage = qwenError.message || 'Qwen API request failed';\n throw new Error(`Qwen stream failed: ${errorMessage}`);\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n return getQwenProviderCapabilities(this.options);\n }\n\n override validateConfig(): boolean {\n return (\n !!this.client && !!this.options && (!this.shouldUseResponsesApi() || !!this.responsesClient)\n );\n }\n\n override async dispose(): Promise<void> {\n // OpenAI-compatible Qwen clients do not need explicit cleanup.\n }\n\n private buildRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n this.validateTools(options?.tools);\n const model = options?.model ?? this.options.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const requestParams = {\n model,\n messages: convertToOpenAICompatibleMessages(messages),\n ...(options?.temperature !== undefined && { temperature: options.temperature }),\n ...(options?.maxTokens !== undefined && { max_tokens: options.maxTokens }),\n ...(options?.tools && {\n tools: convertToOpenAICompatibleTools(options.tools),\n tool_choice: 'auto' as const,\n }),\n };\n\n return requestParams as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n }\n\n private buildStreamingRequestParams(\n messages: TUniversalMessage[],\n options: IChatOptions | undefined,\n ): OpenAI.Chat.ChatCompletionCreateParamsStreaming {\n return {\n ...this.buildRequestParams(messages, options),\n stream: true,\n } as OpenAI.Chat.ChatCompletionCreateParamsStreaming;\n }\n\n private shouldUseResponsesApi(): boolean {\n return hasQwenBuiltInWebTools(this.options.builtInWebTools);\n }\n\n private getClient(): OpenAI {\n if (!this.client) {\n throw new Error(\n 'Qwen client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n\n return this.client;\n }\n\n private getResponsesClient(): OpenAI {\n if (!this.responsesClient) {\n throw new Error('Qwen Responses client not available for built-in web tools.');\n }\n\n return this.responsesClient;\n }\n}\n","import {\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n QWEN_MODEL_LAST_VERIFIED_AT,\n QWEN_MODEL_SOURCE_URL,\n} from './defaults';\n\nimport type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nexport interface IQwenModelsResponse {\n data?: Array<{\n id?: string;\n object?: string;\n owned_by?: string;\n }>;\n}\n\nexport interface IQwenFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IQwenFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IQwenModelsResponse>;\n}\n\nexport type TQwenFetch = (url: string, init?: IQwenFetchInit) => Promise<IQwenFetchResponse>;\n\nexport async function refreshQwenModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TQwenFetch = defaultQwenFetch,\n): Promise<IProviderModelCatalog> {\n const baseURL = trimTrailingSlash(profile.baseURL ?? DEFAULT_QWEN_PROVIDER_BASE_URL);\n const url = `${baseURL}/models`;\n const response = await fetcher(url, buildFetchInit(profile.apiKey));\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n message: `Qwen model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.data ?? [])\n .map((model) => model.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n entries,\n message: `Loaded ${entries.length} models from Qwen API`,\n };\n}\n\nfunction buildFetchInit(apiKey: string | undefined): IQwenFetchInit | undefined {\n if (!apiKey) {\n return undefined;\n }\n return {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n };\n}\n\nfunction toModelCatalogEntry(id: string): IProviderModelCatalogEntry {\n return {\n id,\n displayName: id,\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/, '');\n}\n\nasync function defaultQwenFetch(url: string, init?: IQwenFetchInit): Promise<IQwenFetchResponse> {\n const response = await fetch(url, {\n ...(init?.headers !== undefined && { headers: init.headers }),\n });\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IQwenModelsResponse>,\n };\n}\n","import {\n DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_MODEL,\n QWEN_MODEL_LAST_VERIFIED_AT,\n QWEN_MODEL_SOURCE_URL,\n} from './defaults';\nimport { refreshQwenModelCatalog } from './model-catalog-refresh';\nimport { QwenProvider } from './provider';\nimport { probeOpenAICompatibleProfile } from '../shared/openai-compatible/index.js';\n\nimport type { IQwenBuiltInWebToolsOptions } from './types';\nimport type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nconst QWEN_API_KEY_URL = 'https://modelstudio.console.alibabacloud.com/?tab=api#/api-key';\nconst QWEN_SETUP_SOURCE_URL = 'https://www.alibabacloud.com/help/en/model-studio/get-api-key';\nconst QWEN_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst QWEN_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Alibaba Cloud Model Studio API keys',\n url: QWEN_API_KEY_URL,\n sourceUrl: QWEN_SETUP_SOURCE_URL,\n lastVerifiedAt: QWEN_SETUP_LAST_VERIFIED_AT,\n },\n];\nconst QWEN_MODEL_CATALOG: NonNullable<IProviderDefinition['modelCatalog']> = {\n status: 'fallback',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_QWEN_PROVIDER_MODEL,\n displayName: 'Qwen Plus',\n capabilities: ['tools', 'reasoning', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'qwen-max',\n displayName: 'Qwen Max',\n capabilities: ['tools', 'reasoning', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n {\n id: 'qwen-flash',\n displayName: 'Qwen Flash',\n capabilities: ['tools', 'native_web', 'streaming'],\n lifecycle: 'active',\n sourceUrl: QWEN_MODEL_SOURCE_URL,\n lastVerifiedAt: QWEN_MODEL_LAST_VERIFIED_AT,\n },\n ],\n};\n\nexport {\n DEFAULT_QWEN_PROVIDER_API_KEY_ENV,\n DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n DEFAULT_QWEN_PROVIDER_BASE_URL,\n DEFAULT_QWEN_PROVIDER_MODEL,\n DEFAULT_QWEN_PROVIDER_RESPONSES_BASE_URL,\n QWEN_PROVIDER_BASE_URLS,\n QWEN_PROVIDER_RESPONSES_BASE_URLS,\n} from './defaults';\nexport type { TQwenProviderRegion, TQwenProviderResponsesRegion } from './defaults';\n\nexport function createQwenProviderDefinition(): IProviderDefinition {\n return {\n type: 'qwen',\n displayName: 'Qwen',\n description: 'Alibaba Cloud Model Studio OpenAI-compatible endpoint',\n defaults: {\n model: DEFAULT_QWEN_PROVIDER_MODEL,\n apiKey: DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n baseURL: DEFAULT_QWEN_PROVIDER_BASE_URL,\n },\n modelCatalog: QWEN_MODEL_CATALOG,\n refreshModelCatalog: ({ profile }) => refreshQwenModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n setupHelpLinks: QWEN_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'baseURL',\n title: 'Qwen OpenAI-compatible base URL',\n defaultValue: DEFAULT_QWEN_PROVIDER_BASE_URL,\n },\n {\n key: 'model',\n title: 'Qwen model',\n defaultValue: DEFAULT_QWEN_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Qwen Model Studio API key',\n defaultValue: DEFAULT_QWEN_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n createProvider: (config) => {\n const qwenOptions = parseQwenProviderOptions(config.options);\n return new QwenProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(qwenOptions.responsesBaseURL !== undefined && {\n responsesBaseURL: qwenOptions.responsesBaseURL,\n }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(qwenOptions.builtInWebTools !== undefined && {\n builtInWebTools: qwenOptions.builtInWebTools,\n }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider qwen requires apiKey');\n }\n return apiKey;\n}\n\nfunction parseQwenProviderOptions(options: Record<string, TUniversalValue> | undefined): {\n responsesBaseURL?: string;\n builtInWebTools?: IQwenBuiltInWebToolsOptions;\n} {\n const builtInWebTools = parseBuiltInWebTools(asRecord(options?.['builtInWebTools']));\n const responsesBaseURL = asString(options?.['responsesBaseURL']);\n return {\n ...(responsesBaseURL !== undefined && { responsesBaseURL }),\n ...(builtInWebTools !== undefined && { builtInWebTools }),\n };\n}\n\nfunction parseBuiltInWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IQwenBuiltInWebToolsOptions | undefined {\n if (options === undefined) {\n return undefined;\n }\n return {\n ...(asBoolean(options['webSearch']) !== undefined && {\n webSearch: asBoolean(options['webSearch']),\n }),\n ...(asBoolean(options['webFetch']) !== undefined && {\n webFetch: asBoolean(options['webFetch']),\n }),\n ...(asBoolean(options['enableThinking']) !== undefined && {\n enableThinking: asBoolean(options['enableThinking']),\n }),\n };\n}\n\nfunction asRecord(value: TUniversalValue | undefined): Record<string, TUniversalValue> | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n return typeof value === 'object' ? value : undefined;\n}\n\nfunction asBoolean(value: TUniversalValue | undefined): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction asString(value: TUniversalValue | undefined): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n","import { createAnthropicProviderDefinition } from './anthropic/index.js';\nimport { createDeepSeekProviderDefinition } from './deepseek/index.js';\nimport { createGeminiProviderDefinition } from './gemini/index.js';\nimport { createGemmaProviderDefinition } from './gemma/index.js';\nimport { createOpenAIProviderDefinition } from './openai/index.js';\nimport { createQwenProviderDefinition } from './qwen/index.js';\n\nimport type { IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport function createDefaultProviderDefinitions(): readonly IProviderDefinition[] {\n return [\n createAnthropicProviderDefinition(),\n createOpenAIProviderDefinition(),\n createGeminiProviderDefinition(),\n createGemmaProviderDefinition(),\n createQwenProviderDefinition(),\n createDeepSeekProviderDefinition(),\n ];\n}\n"],"mappings":"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"}