@mariozechner/pi-ai 0.67.68 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/models.generated.d.ts +64 -35
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +77 -56
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.js +9 -1
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/google-shared.d.ts.map +1 -1
- package/dist/providers/google-shared.js +30 -4
- package/dist/providers/google-shared.js.map +1 -1
- package/dist/providers/openai-completions.d.ts +5 -1
- package/dist/providers/openai-completions.d.ts.map +1 -1
- package/dist/providers/openai-completions.js +149 -60
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/dist/providers/openai-responses-shared.js +2 -5
- package/dist/providers/openai-responses-shared.js.map +1 -1
- package/dist/providers/simple-options.d.ts.map +1 -1
- package/dist/providers/simple-options.js +1 -1
- package/dist/providers/simple-options.js.map +1 -1
- package/dist/providers/transform-messages.d.ts.map +1 -1
- package/dist/providers/transform-messages.js +41 -2
- package/dist/providers/transform-messages.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/oauth/anthropic.d.ts.map +1 -1
- package/dist/utils/oauth/anthropic.js +1 -1
- package/dist/utils/oauth/anthropic.js.map +1 -1
- package/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/dist/utils/oauth/google-antigravity.js +2 -1
- package/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.js +2 -1
- package/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/dist/utils/oauth/openai-codex.d.ts.map +1 -1
- package/dist/utils/oauth/openai-codex.js +3 -2
- package/dist/utils/oauth/openai-codex.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAS1C,OAAO,KAAK,EAQX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AAkIrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAYD,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA2PlF,CAAC;AA4CF,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAuC3F,CAAC","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tCacheControlEphemeral,\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord } from \"../utils/headers.js\";\nimport { parseStreamingJson } from \"../utils/json-parse.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCacheControl(\n\tbaseUrl: string,\n\tcacheRetention?: CacheRetention,\n): { retention: CacheRetention; cacheControl?: CacheControlEphemeral } {\n\tconst retention = resolveCacheRetention(cacheRetention);\n\tif (retention === \"none\") {\n\t\treturn { retention };\n\t}\n\tconst ttl = retention === \"long\" && baseUrl.includes(\"api.anthropic.com\") ? \"1h\" : undefined;\n\treturn {\n\t\tretention,\n\t\tcacheControl: { type: \"ephemeral\", ...(ttl && { ttl }) },\n\t};\n}\n\n// Stealth mode: Mimic Claude Code's tool naming exactly\nconst claudeCodeVersion = \"2.1.75\";\n\n// Claude Code 2.x tool names (canonical casing)\n// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md\n// To update: https://github.com/badlogic/cchistory\nconst claudeCodeTools = [\n\t\"Read\",\n\t\"Write\",\n\t\"Edit\",\n\t\"Bash\",\n\t\"Grep\",\n\t\"Glob\",\n\t\"AskUserQuestion\",\n\t\"EnterPlanMode\",\n\t\"ExitPlanMode\",\n\t\"KillShell\",\n\t\"NotebookEdit\",\n\t\"Skill\",\n\t\"Task\",\n\t\"TaskOutput\",\n\t\"TodoWrite\",\n\t\"WebFetch\",\n\t\"WebSearch\",\n];\n\nconst ccToolLookup = new Map(claudeCodeTools.map((t) => [t.toLowerCase(), t]));\n\n// Convert tool name to CC canonical casing if it matches (case-insensitive)\nconst toClaudeCodeName = (name: string) => ccToolLookup.get(name.toLowerCase()) ?? name;\nconst fromClaudeCodeName = (name: string, tools?: Tool[]) => {\n\tif (tools && tools.length > 0) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tconst matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);\n\t\tif (matchedTool) return matchedTool.name;\n\t}\n\treturn name;\n};\n\n/**\n * Convert content blocks to Anthropic API format\n */\nfunction convertContentBlocks(content: (TextContent | ImageContent)[]):\n\t| string\n\t| Array<\n\t\t\t| { type: \"text\"; text: string }\n\t\t\t| {\n\t\t\t\t\ttype: \"image\";\n\t\t\t\t\tsource: {\n\t\t\t\t\t\ttype: \"base64\";\n\t\t\t\t\t\tmedia_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n\t\t\t\t\t\tdata: string;\n\t\t\t\t\t};\n\t\t\t }\n\t > {\n\t// If only text blocks, return as concatenated string for simplicity\n\tconst hasImages = content.some((c) => c.type === \"image\");\n\tif (!hasImages) {\n\t\treturn sanitizeSurrogates(content.map((c) => (c as TextContent).text).join(\"\\n\"));\n\t}\n\n\t// If we have images, convert to content block array\n\tconst blocks = content.map((block) => {\n\t\tif (block.type === \"text\") {\n\t\t\treturn {\n\t\t\t\ttype: \"text\" as const,\n\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\ttype: \"image\" as const,\n\t\t\tsource: {\n\t\t\t\ttype: \"base64\" as const,\n\t\t\t\tmedia_type: block.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\tdata: block.data,\n\t\t\t},\n\t\t};\n\t});\n\n\t// If only images (no text), add placeholder text block\n\tconst hasText = blocks.some((b) => b.type === \"text\");\n\tif (!hasText) {\n\t\tblocks.unshift({\n\t\t\ttype: \"text\" as const,\n\t\t\ttext: \"(see attached image)\",\n\t\t});\n\t}\n\n\treturn blocks;\n}\n\nexport type AnthropicEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\nexport type AnthropicThinkingDisplay = \"summarized\" | \"omitted\";\n\nexport interface AnthropicOptions extends StreamOptions {\n\t/**\n\t * Enable extended thinking.\n\t * For Opus 4.6 and Sonnet 4.6: uses adaptive thinking (model decides when/how much to think).\n\t * For older models: uses budget-based thinking with thinkingBudgetTokens.\n\t */\n\tthinkingEnabled?: boolean;\n\t/**\n\t * Token budget for extended thinking (older models only).\n\t * Ignored for Opus 4.6 and Sonnet 4.6, which use adaptive thinking.\n\t */\n\tthinkingBudgetTokens?: number;\n\t/**\n\t * Effort level for adaptive thinking (Opus 4.6+ and Sonnet 4.6).\n\t * Controls how much thinking Claude allocates:\n\t * - \"max\": Always thinks with no constraints (Opus 4.6 only)\n\t * - \"xhigh\": Highest reasoning level (Opus 4.7)\n\t * - \"high\": Always thinks, deep reasoning (default)\n\t * - \"medium\": Moderate thinking, may skip for simple queries\n\t * - \"low\": Minimal thinking, skips for simple tasks\n\t * Ignored for older models.\n\t */\n\teffort?: AnthropicEffort;\n\t/**\n\t * Controls how thinking content is returned in API responses.\n\t * - \"summarized\": Thinking blocks contain summarized thinking text (default here).\n\t * - \"omitted\": Thinking blocks return an empty thinking field; the encrypted\n\t * signature still travels back for multi-turn continuity. Use for faster\n\t * time-to-first-text-token when your UI does not surface thinking.\n\t *\n\t * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview\n\t * is \"omitted\". We default to \"summarized\" here to keep behavior consistent\n\t * with older Claude 4 models. Set this explicitly to \"omitted\" to opt in.\n\t */\n\tthinkingDisplay?: AnthropicThinkingDisplay;\n\tinterleavedThinking?: boolean;\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n\t/**\n\t * Pre-built Anthropic client instance. When provided, skips internal client\n\t * construction entirely. Use this to inject alternative SDK clients such as\n\t * `AnthropicVertex` that shares the same messaging API.\n\t */\n\tclient?: Anthropic;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tlet client: Anthropic;\n\t\t\tlet isOAuth: boolean;\n\n\t\t\tif (options?.client) {\n\t\t\t\tclient = options.client;\n\t\t\t\tisOAuth = false;\n\t\t\t} else {\n\t\t\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\t\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\t\t\tif (model.provider === \"github-copilot\") {\n\t\t\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\thasImages,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst created = createClient(\n\t\t\t\t\tmodel,\n\t\t\t\t\tapiKey,\n\t\t\t\t\toptions?.interleavedThinking ?? true,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t\tcopilotDynamicHeaders,\n\t\t\t\t);\n\t\t\t\tclient = created.client;\n\t\t\t\tisOAuth = created.isOAuthToken;\n\t\t\t}\n\t\t\tlet params = buildParams(model, context, isOAuth, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as MessageCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst { data: anthropicStream, response } = await client.messages\n\t\t\t\t.stream({ ...params, stream: true }, { signal: options?.signal })\n\t\t\t\t.withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\ttype Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };\n\t\t\tconst blocks = output.content as Block[];\n\n\t\t\tfor await (const event of anthropicStream) {\n\t\t\t\tif (event.type === \"message_start\") {\n\t\t\t\t\toutput.responseId = event.message.id;\n\t\t\t\t\t// Capture initial token usage from message_start event\n\t\t\t\t\t// This ensures we have input token counts even if the stream is aborted early\n\t\t\t\t\toutput.usage.input = event.message.usage.input_tokens || 0;\n\t\t\t\t\toutput.usage.output = event.message.usage.output_tokens || 0;\n\t\t\t\t\toutput.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;\n\t\t\t\t\toutput.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t} else if (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\tthinkingSignature: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"redacted_thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"[Reasoning redacted]\",\n\t\t\t\t\t\t\tthinkingSignature: event.content_block.data,\n\t\t\t\t\t\t\tredacted: true,\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: isOAuth\n\t\t\t\t\t\t\t\t? fromClaudeCodeName(event.content_block.name, context.tools)\n\t\t\t\t\t\t\t\t: event.content_block.name,\n\t\t\t\t\t\t\targuments: (event.content_block.input as Record<string, any>) ?? {},\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"text\") {\n\t\t\t\t\t\t\tblock.text += event.delta.text;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinking += event.delta.thinking;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.partialJson += event.delta.partial_json;\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.partial_json,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"signature_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinkingSignature = block.thinkingSignature || \"\";\n\t\t\t\t\t\t\tblock.thinkingSignature += event.delta.signature;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_stop\") {\n\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\tif (block) {\n\t\t\t\t\t\tdelete (block as any).index;\n\t\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t\t\t\t// carries parsed arguments.\n\t\t\t\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\ttoolCall: block,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"message_delta\") {\n\t\t\t\t\tif (event.delta.stop_reason) {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(event.delta.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\t// Only update usage fields if present (not null).\n\t\t\t\t\t// Preserves input_tokens from message_start when proxies omit it in message_delta.\n\t\t\t\t\tif (event.usage.input_tokens != null) {\n\t\t\t\t\t\toutput.usage.input = event.usage.input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.output_tokens != null) {\n\t\t\t\t\t\toutput.usage.output = event.usage.output_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_read_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheRead = event.usage.cache_read_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_creation_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheWrite = event.usage.cache_creation_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Check if a model supports adaptive thinking (Opus 4.6+, Sonnet 4.6)\n */\nfunction supportsAdaptiveThinking(modelId: string): boolean {\n\t// Adaptive-thinking model IDs (with or without date suffix)\n\treturn (\n\t\tmodelId.includes(\"opus-4-6\") ||\n\t\tmodelId.includes(\"opus-4.6\") ||\n\t\tmodelId.includes(\"opus-4-7\") ||\n\t\tmodelId.includes(\"opus-4.7\") ||\n\t\tmodelId.includes(\"sonnet-4-6\") ||\n\t\tmodelId.includes(\"sonnet-4.6\")\n\t);\n}\n\n/**\n * Map ThinkingLevel to Anthropic effort levels for adaptive thinking.\n * Note: effort \"max\" is only valid on Opus 4.6, while Opus 4.7 supports \"xhigh\".\n */\nfunction mapThinkingLevelToEffort(level: SimpleStreamOptions[\"reasoning\"], modelId: string): AnthropicEffort {\n\tswitch (level) {\n\t\tcase \"minimal\":\n\t\t\treturn \"low\";\n\t\tcase \"low\":\n\t\t\treturn \"low\";\n\t\tcase \"medium\":\n\t\t\treturn \"medium\";\n\t\tcase \"high\":\n\t\t\treturn \"high\";\n\t\tcase \"xhigh\":\n\t\t\tif (modelId.includes(\"opus-4-6\") || modelId.includes(\"opus-4.6\")) {\n\t\t\t\treturn \"max\";\n\t\t\t}\n\t\t\tif (modelId.includes(\"opus-4-7\") || modelId.includes(\"opus-4.7\")) {\n\t\t\t\treturn \"xhigh\";\n\t\t\t}\n\t\t\treturn \"high\";\n\t\tdefault:\n\t\t\treturn \"high\";\n\t}\n}\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n\nfunction isOAuthToken(apiKey: string): boolean {\n\treturn apiKey.includes(\"sk-ant-oat\");\n}\n\nfunction createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): { client: Anthropic; isOAuthToken: boolean } {\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\tconst betaFeatures = [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// OAuth: Bearer auth, Claude Code identity headers\n\tif (isOAuthToken(apiKey)) {\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t\"anthropic-beta\": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(\",\")}`,\n\t\t\t\t\t\"user-agent\": `claude-cli/${claudeCodeVersion}`,\n\t\t\t\t\t\"x-app\": \"cli\",\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: true };\n\t}\n\n\t// API key auth\n\tconst client = new Anthropic({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\"anthropic-beta\": betaFeatures.join(\",\"),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nfunction buildParams(\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\tisOAuthToken: boolean,\n\toptions?: AnthropicOptions,\n): MessageCreateParamsStreaming {\n\tconst { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);\n\tconst params: MessageCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tmessages: convertMessages(context.messages, model, isOAuthToken, cacheControl),\n\t\tmax_tokens: options?.maxTokens || (model.maxTokens / 3) | 0,\n\t\tstream: true,\n\t};\n\n\t// For OAuth tokens, we MUST include Claude Code identity\n\tif (isOAuthToken) {\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t\tif (context.systemPrompt) {\n\t\t\tparams.system.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t});\n\t\t}\n\t} else if (context.systemPrompt) {\n\t\t// Add cache control to system prompt for non-OAuth tokens\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t}\n\n\t// Temperature is incompatible with extended thinking (adaptive or budget-based).\n\tif (options?.temperature !== undefined && !options?.thinkingEnabled) {\n\t\tparams.temperature = options.temperature;\n\t}\n\n\tif (context.tools) {\n\t\tparams.tools = convertTools(context.tools, isOAuthToken, cacheControl);\n\t}\n\n\t// Configure thinking mode: adaptive (Opus 4.6+ and Sonnet 4.6),\n\t// budget-based (older models), or explicitly disabled.\n\tif (model.reasoning) {\n\t\tif (options?.thinkingEnabled) {\n\t\t\t// Default to \"summarized\" so Opus 4.7 and Mythos Preview behave like\n\t\t\t// older Claude 4 models (whose API default is also \"summarized\").\n\t\t\tconst display: AnthropicThinkingDisplay = options.thinkingDisplay ?? \"summarized\";\n\t\t\tif (supportsAdaptiveThinking(model.id)) {\n\t\t\t\t// Adaptive thinking: Claude decides when and how much to think.\n\t\t\t\tparams.thinking = { type: \"adaptive\", display };\n\t\t\t\tif (options.effort) {\n\t\t\t\t\t// The Anthropic SDK types can lag newly supported effort values such as \"xhigh\".\n\t\t\t\t\tparams.output_config =\n\t\t\t\t\t\toptions.effort === \"xhigh\"\n\t\t\t\t\t\t\t? ({ effort: options.effort } as unknown as NonNullable<\n\t\t\t\t\t\t\t\t\tMessageCreateParamsStreaming[\"output_config\"]\n\t\t\t\t\t\t\t\t>)\n\t\t\t\t\t\t\t: { effort: options.effort };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Budget-based thinking for older models\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinkingBudgetTokens || 1024,\n\t\t\t\t\tdisplay,\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (options?.thinkingEnabled === false) {\n\t\t\tparams.thinking = { type: \"disabled\" };\n\t\t}\n\t}\n\n\tif (options?.metadata) {\n\t\tconst userId = options.metadata.user_id;\n\t\tif (typeof userId === \"string\") {\n\t\t\tparams.metadata = { user_id: userId };\n\t\t}\n\t}\n\n\tif (options?.toolChoice) {\n\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t} else {\n\t\t\tparams.tool_choice = options.toolChoice;\n\t\t}\n\t}\n\n\treturn params;\n}\n\n// Normalize tool call IDs to match Anthropic's required pattern and length\nfunction normalizeToolCallId(id: string): string {\n\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n}\n\nfunction convertMessages(\n\tmessages: Message[],\n\tmodel: Model<\"anthropic-messages\">,\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): MessageParam[] {\n\tconst params: MessageParam[] = [];\n\n\t// Transform messages for cross-provider compatibility\n\tconst transformedMessages = transformMessages(messages, model, normalizeToolCallId);\n\n\tfor (let i = 0; i < transformedMessages.length; i++) {\n\t\tconst msg = transformedMessages[i];\n\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tif (msg.content.trim().length > 0) {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: sanitizeSurrogates(msg.content),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tlet filteredBlocks = !model?.input.includes(\"image\") ? blocks.filter((b) => b.type !== \"image\") : blocks;\n\t\t\t\tfilteredBlocks = filteredBlocks.filter((b) => {\n\t\t\t\t\tif (b.type === \"text\") {\n\t\t\t\t\t\treturn b.text.trim().length > 0;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\t\t\t\tif (filteredBlocks.length === 0) continue;\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: filteredBlocks,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (block.text.trim().length === 0) continue;\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking: pass the opaque payload back as redacted_thinking\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"redacted_thinking\",\n\t\t\t\t\t\t\tdata: block.thinkingSignature!,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (block.thinking.trim().length === 0) continue;\n\t\t\t\t\t// If thinking signature is missing/empty (e.g., from aborted stream),\n\t\t\t\t\t// convert to plain text block without <thinking> tags to avoid API rejection\n\t\t\t\t\t// and prevent Claude from mimicking the tags in responses\n\t\t\t\t\tif (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\tsignature: block.thinkingSignature,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\tname: isOAuthToken ? toClaudeCodeName(block.name) : block.name,\n\t\t\t\t\t\tinput: block.arguments ?? {},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (blocks.length === 0) continue;\n\t\t\tparams.push({\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint\n\t\t\tconst toolResults: ContentBlockParam[] = [];\n\n\t\t\t// Add the current tool result\n\t\t\ttoolResults.push({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\tcontent: convertContentBlocks(msg.content),\n\t\t\t\tis_error: msg.isError,\n\t\t\t});\n\n\t\t\t// Look ahead for consecutive toolResult messages\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < transformedMessages.length && transformedMessages[j].role === \"toolResult\") {\n\t\t\t\tconst nextMsg = transformedMessages[j] as ToolResultMessage; // We know it's a toolResult\n\t\t\t\ttoolResults.push({\n\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\ttool_use_id: nextMsg.toolCallId,\n\t\t\t\t\tcontent: convertContentBlocks(nextMsg.content),\n\t\t\t\t\tis_error: nextMsg.isError,\n\t\t\t\t});\n\t\t\t\tj++;\n\t\t\t}\n\n\t\t\t// Skip the messages we've already processed\n\t\t\ti = j - 1;\n\n\t\t\t// Add a single user message with all tool results\n\t\t\tparams.push({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: toolResults,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add cache_control to the last user message to cache conversation history\n\tif (cacheControl && params.length > 0) {\n\t\tconst lastMessage = params[params.length - 1];\n\t\tif (lastMessage.role === \"user\") {\n\t\t\tif (Array.isArray(lastMessage.content)) {\n\t\t\t\tconst lastBlock = lastMessage.content[lastMessage.content.length - 1];\n\t\t\t\tif (\n\t\t\t\t\tlastBlock &&\n\t\t\t\t\t(lastBlock.type === \"text\" || lastBlock.type === \"image\" || lastBlock.type === \"tool_result\")\n\t\t\t\t) {\n\t\t\t\t\t(lastBlock as any).cache_control = cacheControl;\n\t\t\t\t}\n\t\t\t} else if (typeof lastMessage.content === \"string\") {\n\t\t\t\tlastMessage.content = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: lastMessage.content,\n\t\t\t\t\t\tcache_control: cacheControl,\n\t\t\t\t\t},\n\t\t\t\t] as any;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction convertTools(\n\ttools: Tool[],\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): Anthropic.Messages.Tool[] {\n\tif (!tools) return [];\n\n\treturn tools.map((tool, index) => {\n\t\tconst schema = tool.parameters as { properties?: unknown; required?: string[] };\n\n\t\treturn {\n\t\t\tname: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: schema.properties ?? {},\n\t\t\t\trequired: schema.required ?? [],\n\t\t\t},\n\t\t\t...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),\n\t\t};\n\t});\n}\n\nfunction mapStopReason(reason: Anthropic.Messages.StopReason | string): StopReason {\n\tswitch (reason) {\n\t\tcase \"end_turn\":\n\t\t\treturn \"stop\";\n\t\tcase \"max_tokens\":\n\t\t\treturn \"length\";\n\t\tcase \"tool_use\":\n\t\t\treturn \"toolUse\";\n\t\tcase \"refusal\":\n\t\t\treturn \"error\";\n\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\treturn \"stop\";\n\t\tcase \"stop_sequence\":\n\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\tcase \"sensitive\": // Content flagged by safety filters (not yet in SDK types)\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\t// Handle unknown stop reasons gracefully (API may add new values)\n\t\t\tthrow new Error(`Unhandled stop reason: ${reason}`);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAS1C,OAAO,KAAK,EAQX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AAkIrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAYD,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA2PlF,CAAC;AA4CF,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAuC3F,CAAC","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tCacheControlEphemeral,\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord } from \"../utils/headers.js\";\nimport { parseStreamingJson } from \"../utils/json-parse.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCacheControl(\n\tbaseUrl: string,\n\tcacheRetention?: CacheRetention,\n): { retention: CacheRetention; cacheControl?: CacheControlEphemeral } {\n\tconst retention = resolveCacheRetention(cacheRetention);\n\tif (retention === \"none\") {\n\t\treturn { retention };\n\t}\n\tconst ttl = retention === \"long\" && baseUrl.includes(\"api.anthropic.com\") ? \"1h\" : undefined;\n\treturn {\n\t\tretention,\n\t\tcacheControl: { type: \"ephemeral\", ...(ttl && { ttl }) },\n\t};\n}\n\n// Stealth mode: Mimic Claude Code's tool naming exactly\nconst claudeCodeVersion = \"2.1.75\";\n\n// Claude Code 2.x tool names (canonical casing)\n// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md\n// To update: https://github.com/badlogic/cchistory\nconst claudeCodeTools = [\n\t\"Read\",\n\t\"Write\",\n\t\"Edit\",\n\t\"Bash\",\n\t\"Grep\",\n\t\"Glob\",\n\t\"AskUserQuestion\",\n\t\"EnterPlanMode\",\n\t\"ExitPlanMode\",\n\t\"KillShell\",\n\t\"NotebookEdit\",\n\t\"Skill\",\n\t\"Task\",\n\t\"TaskOutput\",\n\t\"TodoWrite\",\n\t\"WebFetch\",\n\t\"WebSearch\",\n];\n\nconst ccToolLookup = new Map(claudeCodeTools.map((t) => [t.toLowerCase(), t]));\n\n// Convert tool name to CC canonical casing if it matches (case-insensitive)\nconst toClaudeCodeName = (name: string) => ccToolLookup.get(name.toLowerCase()) ?? name;\nconst fromClaudeCodeName = (name: string, tools?: Tool[]) => {\n\tif (tools && tools.length > 0) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tconst matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);\n\t\tif (matchedTool) return matchedTool.name;\n\t}\n\treturn name;\n};\n\n/**\n * Convert content blocks to Anthropic API format\n */\nfunction convertContentBlocks(content: (TextContent | ImageContent)[]):\n\t| string\n\t| Array<\n\t\t\t| { type: \"text\"; text: string }\n\t\t\t| {\n\t\t\t\t\ttype: \"image\";\n\t\t\t\t\tsource: {\n\t\t\t\t\t\ttype: \"base64\";\n\t\t\t\t\t\tmedia_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n\t\t\t\t\t\tdata: string;\n\t\t\t\t\t};\n\t\t\t }\n\t > {\n\t// If only text blocks, return as concatenated string for simplicity\n\tconst hasImages = content.some((c) => c.type === \"image\");\n\tif (!hasImages) {\n\t\treturn sanitizeSurrogates(content.map((c) => (c as TextContent).text).join(\"\\n\"));\n\t}\n\n\t// If we have images, convert to content block array\n\tconst blocks = content.map((block) => {\n\t\tif (block.type === \"text\") {\n\t\t\treturn {\n\t\t\t\ttype: \"text\" as const,\n\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\ttype: \"image\" as const,\n\t\t\tsource: {\n\t\t\t\ttype: \"base64\" as const,\n\t\t\t\tmedia_type: block.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\tdata: block.data,\n\t\t\t},\n\t\t};\n\t});\n\n\t// If only images (no text), add placeholder text block\n\tconst hasText = blocks.some((b) => b.type === \"text\");\n\tif (!hasText) {\n\t\tblocks.unshift({\n\t\t\ttype: \"text\" as const,\n\t\t\ttext: \"(see attached image)\",\n\t\t});\n\t}\n\n\treturn blocks;\n}\n\nexport type AnthropicEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\nexport type AnthropicThinkingDisplay = \"summarized\" | \"omitted\";\n\nexport interface AnthropicOptions extends StreamOptions {\n\t/**\n\t * Enable extended thinking.\n\t * For Opus 4.6 and Sonnet 4.6: uses adaptive thinking (model decides when/how much to think).\n\t * For older models: uses budget-based thinking with thinkingBudgetTokens.\n\t */\n\tthinkingEnabled?: boolean;\n\t/**\n\t * Token budget for extended thinking (older models only).\n\t * Ignored for Opus 4.6 and Sonnet 4.6, which use adaptive thinking.\n\t */\n\tthinkingBudgetTokens?: number;\n\t/**\n\t * Effort level for adaptive thinking (Opus 4.6+ and Sonnet 4.6).\n\t * Controls how much thinking Claude allocates:\n\t * - \"max\": Always thinks with no constraints (Opus 4.6 only)\n\t * - \"xhigh\": Highest reasoning level (Opus 4.7)\n\t * - \"high\": Always thinks, deep reasoning (default)\n\t * - \"medium\": Moderate thinking, may skip for simple queries\n\t * - \"low\": Minimal thinking, skips for simple tasks\n\t * Ignored for older models.\n\t */\n\teffort?: AnthropicEffort;\n\t/**\n\t * Controls how thinking content is returned in API responses.\n\t * - \"summarized\": Thinking blocks contain summarized thinking text (default here).\n\t * - \"omitted\": Thinking blocks return an empty thinking field; the encrypted\n\t * signature still travels back for multi-turn continuity. Use for faster\n\t * time-to-first-text-token when your UI does not surface thinking.\n\t *\n\t * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview\n\t * is \"omitted\". We default to \"summarized\" here to keep behavior consistent\n\t * with older Claude 4 models. Set this explicitly to \"omitted\" to opt in.\n\t */\n\tthinkingDisplay?: AnthropicThinkingDisplay;\n\tinterleavedThinking?: boolean;\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n\t/**\n\t * Pre-built Anthropic client instance. When provided, skips internal client\n\t * construction entirely. Use this to inject alternative SDK clients such as\n\t * `AnthropicVertex` that shares the same messaging API.\n\t */\n\tclient?: Anthropic;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tlet client: Anthropic;\n\t\t\tlet isOAuth: boolean;\n\n\t\t\tif (options?.client) {\n\t\t\t\tclient = options.client;\n\t\t\t\tisOAuth = false;\n\t\t\t} else {\n\t\t\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\t\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\t\t\tif (model.provider === \"github-copilot\") {\n\t\t\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\thasImages,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst created = createClient(\n\t\t\t\t\tmodel,\n\t\t\t\t\tapiKey,\n\t\t\t\t\toptions?.interleavedThinking ?? true,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t\tcopilotDynamicHeaders,\n\t\t\t\t);\n\t\t\t\tclient = created.client;\n\t\t\t\tisOAuth = created.isOAuthToken;\n\t\t\t}\n\t\t\tlet params = buildParams(model, context, isOAuth, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as MessageCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst { data: anthropicStream, response } = await client.messages\n\t\t\t\t.stream({ ...params, stream: true }, { signal: options?.signal })\n\t\t\t\t.withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\ttype Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };\n\t\t\tconst blocks = output.content as Block[];\n\n\t\t\tfor await (const event of anthropicStream) {\n\t\t\t\tif (event.type === \"message_start\") {\n\t\t\t\t\toutput.responseId = event.message.id;\n\t\t\t\t\t// Capture initial token usage from message_start event\n\t\t\t\t\t// This ensures we have input token counts even if the stream is aborted early\n\t\t\t\t\toutput.usage.input = event.message.usage.input_tokens || 0;\n\t\t\t\t\toutput.usage.output = event.message.usage.output_tokens || 0;\n\t\t\t\t\toutput.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;\n\t\t\t\t\toutput.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t} else if (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\tthinkingSignature: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"redacted_thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"[Reasoning redacted]\",\n\t\t\t\t\t\t\tthinkingSignature: event.content_block.data,\n\t\t\t\t\t\t\tredacted: true,\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: isOAuth\n\t\t\t\t\t\t\t\t? fromClaudeCodeName(event.content_block.name, context.tools)\n\t\t\t\t\t\t\t\t: event.content_block.name,\n\t\t\t\t\t\t\targuments: (event.content_block.input as Record<string, any>) ?? {},\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"text\") {\n\t\t\t\t\t\t\tblock.text += event.delta.text;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinking += event.delta.thinking;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.partialJson += event.delta.partial_json;\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.partial_json,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"signature_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinkingSignature = block.thinkingSignature || \"\";\n\t\t\t\t\t\t\tblock.thinkingSignature += event.delta.signature;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_stop\") {\n\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\tif (block) {\n\t\t\t\t\t\tdelete (block as any).index;\n\t\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t\t\t\t// carries parsed arguments.\n\t\t\t\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\ttoolCall: block,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"message_delta\") {\n\t\t\t\t\tif (event.delta.stop_reason) {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(event.delta.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\t// Only update usage fields if present (not null).\n\t\t\t\t\t// Preserves input_tokens from message_start when proxies omit it in message_delta.\n\t\t\t\t\tif (event.usage.input_tokens != null) {\n\t\t\t\t\t\toutput.usage.input = event.usage.input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.output_tokens != null) {\n\t\t\t\t\t\toutput.usage.output = event.usage.output_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_read_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheRead = event.usage.cache_read_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_creation_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheWrite = event.usage.cache_creation_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Check if a model supports adaptive thinking (Opus 4.6+, Sonnet 4.6)\n */\nfunction supportsAdaptiveThinking(modelId: string): boolean {\n\t// Adaptive-thinking model IDs (with or without date suffix)\n\treturn (\n\t\tmodelId.includes(\"opus-4-6\") ||\n\t\tmodelId.includes(\"opus-4.6\") ||\n\t\tmodelId.includes(\"opus-4-7\") ||\n\t\tmodelId.includes(\"opus-4.7\") ||\n\t\tmodelId.includes(\"sonnet-4-6\") ||\n\t\tmodelId.includes(\"sonnet-4.6\")\n\t);\n}\n\n/**\n * Map ThinkingLevel to Anthropic effort levels for adaptive thinking.\n * Note: effort \"max\" is only valid on Opus 4.6, while Opus 4.7 supports \"xhigh\".\n */\nfunction mapThinkingLevelToEffort(level: SimpleStreamOptions[\"reasoning\"], modelId: string): AnthropicEffort {\n\tswitch (level) {\n\t\tcase \"minimal\":\n\t\t\treturn \"low\";\n\t\tcase \"low\":\n\t\t\treturn \"low\";\n\t\tcase \"medium\":\n\t\t\treturn \"medium\";\n\t\tcase \"high\":\n\t\t\treturn \"high\";\n\t\tcase \"xhigh\":\n\t\t\tif (modelId.includes(\"opus-4-6\") || modelId.includes(\"opus-4.6\")) {\n\t\t\t\treturn \"max\";\n\t\t\t}\n\t\t\tif (modelId.includes(\"opus-4-7\") || modelId.includes(\"opus-4.7\")) {\n\t\t\t\treturn \"xhigh\";\n\t\t\t}\n\t\t\treturn \"high\";\n\t\tdefault:\n\t\t\treturn \"high\";\n\t}\n}\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n\nfunction isOAuthToken(apiKey: string): boolean {\n\treturn apiKey.includes(\"sk-ant-oat\");\n}\n\nfunction createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): { client: Anthropic; isOAuthToken: boolean } {\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\tconst betaFeatures = [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// OAuth: Bearer auth, Claude Code identity headers\n\tif (isOAuthToken(apiKey)) {\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t\"anthropic-beta\": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(\",\")}`,\n\t\t\t\t\t\"user-agent\": `claude-cli/${claudeCodeVersion}`,\n\t\t\t\t\t\"x-app\": \"cli\",\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: true };\n\t}\n\n\t// API key auth\n\tconst client = new Anthropic({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\"anthropic-beta\": betaFeatures.join(\",\"),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nfunction buildParams(\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\tisOAuthToken: boolean,\n\toptions?: AnthropicOptions,\n): MessageCreateParamsStreaming {\n\tconst { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);\n\tconst params: MessageCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tmessages: convertMessages(context.messages, model, isOAuthToken, cacheControl),\n\t\tmax_tokens: options?.maxTokens || (model.maxTokens / 3) | 0,\n\t\tstream: true,\n\t};\n\n\t// For OAuth tokens, we MUST include Claude Code identity\n\tif (isOAuthToken) {\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t\tif (context.systemPrompt) {\n\t\t\tparams.system.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t});\n\t\t}\n\t} else if (context.systemPrompt) {\n\t\t// Add cache control to system prompt for non-OAuth tokens\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t}\n\n\t// Temperature is incompatible with extended thinking (adaptive or budget-based).\n\tif (options?.temperature !== undefined && !options?.thinkingEnabled) {\n\t\tparams.temperature = options.temperature;\n\t}\n\n\tif (context.tools) {\n\t\tparams.tools = convertTools(context.tools, isOAuthToken, cacheControl);\n\t}\n\n\t// Configure thinking mode: adaptive (Opus 4.6+ and Sonnet 4.6),\n\t// budget-based (older models), or explicitly disabled.\n\tif (model.reasoning) {\n\t\tif (options?.thinkingEnabled) {\n\t\t\t// Default to \"summarized\" so Opus 4.7 and Mythos Preview behave like\n\t\t\t// older Claude 4 models (whose API default is also \"summarized\").\n\t\t\tconst display: AnthropicThinkingDisplay = options.thinkingDisplay ?? \"summarized\";\n\t\t\tif (supportsAdaptiveThinking(model.id)) {\n\t\t\t\t// Adaptive thinking: Claude decides when and how much to think.\n\t\t\t\tparams.thinking = { type: \"adaptive\", display };\n\t\t\t\tif (options.effort) {\n\t\t\t\t\t// The Anthropic SDK types can lag newly supported effort values such as \"xhigh\".\n\t\t\t\t\tparams.output_config =\n\t\t\t\t\t\toptions.effort === \"xhigh\"\n\t\t\t\t\t\t\t? ({ effort: options.effort } as unknown as NonNullable<\n\t\t\t\t\t\t\t\t\tMessageCreateParamsStreaming[\"output_config\"]\n\t\t\t\t\t\t\t\t>)\n\t\t\t\t\t\t\t: { effort: options.effort };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Budget-based thinking for older models\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinkingBudgetTokens || 1024,\n\t\t\t\t\tdisplay,\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (options?.thinkingEnabled === false) {\n\t\t\tparams.thinking = { type: \"disabled\" };\n\t\t}\n\t}\n\n\tif (options?.metadata) {\n\t\tconst userId = options.metadata.user_id;\n\t\tif (typeof userId === \"string\") {\n\t\t\tparams.metadata = { user_id: userId };\n\t\t}\n\t}\n\n\tif (options?.toolChoice) {\n\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t} else {\n\t\t\tparams.tool_choice = options.toolChoice;\n\t\t}\n\t}\n\n\treturn params;\n}\n\n// Normalize tool call IDs to match Anthropic's required pattern and length\nfunction normalizeToolCallId(id: string): string {\n\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n}\n\nfunction convertMessages(\n\tmessages: Message[],\n\tmodel: Model<\"anthropic-messages\">,\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): MessageParam[] {\n\tconst params: MessageParam[] = [];\n\n\t// Transform messages for cross-provider compatibility\n\tconst transformedMessages = transformMessages(messages, model, normalizeToolCallId);\n\n\tfor (let i = 0; i < transformedMessages.length; i++) {\n\t\tconst msg = transformedMessages[i];\n\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tif (msg.content.trim().length > 0) {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: sanitizeSurrogates(msg.content),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst filteredBlocks = blocks.filter((b) => {\n\t\t\t\t\tif (b.type === \"text\") {\n\t\t\t\t\t\treturn b.text.trim().length > 0;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\t\t\t\tif (filteredBlocks.length === 0) continue;\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: filteredBlocks,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (block.text.trim().length === 0) continue;\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking: pass the opaque payload back as redacted_thinking\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"redacted_thinking\",\n\t\t\t\t\t\t\tdata: block.thinkingSignature!,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (block.thinking.trim().length === 0) continue;\n\t\t\t\t\t// If thinking signature is missing/empty (e.g., from aborted stream),\n\t\t\t\t\t// convert to plain text block without <thinking> tags to avoid API rejection\n\t\t\t\t\t// and prevent Claude from mimicking the tags in responses\n\t\t\t\t\tif (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\tsignature: block.thinkingSignature,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\tname: isOAuthToken ? toClaudeCodeName(block.name) : block.name,\n\t\t\t\t\t\tinput: block.arguments ?? {},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (blocks.length === 0) continue;\n\t\t\tparams.push({\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint\n\t\t\tconst toolResults: ContentBlockParam[] = [];\n\n\t\t\t// Add the current tool result\n\t\t\ttoolResults.push({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\tcontent: convertContentBlocks(msg.content),\n\t\t\t\tis_error: msg.isError,\n\t\t\t});\n\n\t\t\t// Look ahead for consecutive toolResult messages\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < transformedMessages.length && transformedMessages[j].role === \"toolResult\") {\n\t\t\t\tconst nextMsg = transformedMessages[j] as ToolResultMessage; // We know it's a toolResult\n\t\t\t\ttoolResults.push({\n\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\ttool_use_id: nextMsg.toolCallId,\n\t\t\t\t\tcontent: convertContentBlocks(nextMsg.content),\n\t\t\t\t\tis_error: nextMsg.isError,\n\t\t\t\t});\n\t\t\t\tj++;\n\t\t\t}\n\n\t\t\t// Skip the messages we've already processed\n\t\t\ti = j - 1;\n\n\t\t\t// Add a single user message with all tool results\n\t\t\tparams.push({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: toolResults,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add cache_control to the last user message to cache conversation history\n\tif (cacheControl && params.length > 0) {\n\t\tconst lastMessage = params[params.length - 1];\n\t\tif (lastMessage.role === \"user\") {\n\t\t\tif (Array.isArray(lastMessage.content)) {\n\t\t\t\tconst lastBlock = lastMessage.content[lastMessage.content.length - 1];\n\t\t\t\tif (\n\t\t\t\t\tlastBlock &&\n\t\t\t\t\t(lastBlock.type === \"text\" || lastBlock.type === \"image\" || lastBlock.type === \"tool_result\")\n\t\t\t\t) {\n\t\t\t\t\t(lastBlock as any).cache_control = cacheControl;\n\t\t\t\t}\n\t\t\t} else if (typeof lastMessage.content === \"string\") {\n\t\t\t\tlastMessage.content = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: lastMessage.content,\n\t\t\t\t\t\tcache_control: cacheControl,\n\t\t\t\t\t},\n\t\t\t\t] as any;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction convertTools(\n\ttools: Tool[],\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): Anthropic.Messages.Tool[] {\n\tif (!tools) return [];\n\n\treturn tools.map((tool, index) => {\n\t\tconst schema = tool.parameters as { properties?: unknown; required?: string[] };\n\n\t\treturn {\n\t\t\tname: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: schema.properties ?? {},\n\t\t\t\trequired: schema.required ?? [],\n\t\t\t},\n\t\t\t...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),\n\t\t};\n\t});\n}\n\nfunction mapStopReason(reason: Anthropic.Messages.StopReason | string): StopReason {\n\tswitch (reason) {\n\t\tcase \"end_turn\":\n\t\t\treturn \"stop\";\n\t\tcase \"max_tokens\":\n\t\t\treturn \"length\";\n\t\tcase \"tool_use\":\n\t\t\treturn \"toolUse\";\n\t\tcase \"refusal\":\n\t\t\treturn \"error\";\n\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\treturn \"stop\";\n\t\tcase \"stop_sequence\":\n\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\tcase \"sensitive\": // Content flagged by safety filters (not yet in SDK types)\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\t// Handle unknown stop reasons gracefully (API may add new values)\n\t\t\tthrow new Error(`Unhandled stop reason: ${reason}`);\n\t}\n}\n"]}
|
|
@@ -609,8 +609,7 @@ function convertMessages(messages, model, isOAuthToken, cacheControl) {
|
|
|
609
609
|
};
|
|
610
610
|
}
|
|
611
611
|
});
|
|
612
|
-
|
|
613
|
-
filteredBlocks = filteredBlocks.filter((b) => {
|
|
612
|
+
const filteredBlocks = blocks.filter((b) => {
|
|
614
613
|
if (b.type === "text") {
|
|
615
614
|
return b.text.trim().length > 0;
|
|
616
615
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tCacheControlEphemeral,\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord } from \"../utils/headers.js\";\nimport { parseStreamingJson } from \"../utils/json-parse.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCacheControl(\n\tbaseUrl: string,\n\tcacheRetention?: CacheRetention,\n): { retention: CacheRetention; cacheControl?: CacheControlEphemeral } {\n\tconst retention = resolveCacheRetention(cacheRetention);\n\tif (retention === \"none\") {\n\t\treturn { retention };\n\t}\n\tconst ttl = retention === \"long\" && baseUrl.includes(\"api.anthropic.com\") ? \"1h\" : undefined;\n\treturn {\n\t\tretention,\n\t\tcacheControl: { type: \"ephemeral\", ...(ttl && { ttl }) },\n\t};\n}\n\n// Stealth mode: Mimic Claude Code's tool naming exactly\nconst claudeCodeVersion = \"2.1.75\";\n\n// Claude Code 2.x tool names (canonical casing)\n// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md\n// To update: https://github.com/badlogic/cchistory\nconst claudeCodeTools = [\n\t\"Read\",\n\t\"Write\",\n\t\"Edit\",\n\t\"Bash\",\n\t\"Grep\",\n\t\"Glob\",\n\t\"AskUserQuestion\",\n\t\"EnterPlanMode\",\n\t\"ExitPlanMode\",\n\t\"KillShell\",\n\t\"NotebookEdit\",\n\t\"Skill\",\n\t\"Task\",\n\t\"TaskOutput\",\n\t\"TodoWrite\",\n\t\"WebFetch\",\n\t\"WebSearch\",\n];\n\nconst ccToolLookup = new Map(claudeCodeTools.map((t) => [t.toLowerCase(), t]));\n\n// Convert tool name to CC canonical casing if it matches (case-insensitive)\nconst toClaudeCodeName = (name: string) => ccToolLookup.get(name.toLowerCase()) ?? name;\nconst fromClaudeCodeName = (name: string, tools?: Tool[]) => {\n\tif (tools && tools.length > 0) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tconst matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);\n\t\tif (matchedTool) return matchedTool.name;\n\t}\n\treturn name;\n};\n\n/**\n * Convert content blocks to Anthropic API format\n */\nfunction convertContentBlocks(content: (TextContent | ImageContent)[]):\n\t| string\n\t| Array<\n\t\t\t| { type: \"text\"; text: string }\n\t\t\t| {\n\t\t\t\t\ttype: \"image\";\n\t\t\t\t\tsource: {\n\t\t\t\t\t\ttype: \"base64\";\n\t\t\t\t\t\tmedia_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n\t\t\t\t\t\tdata: string;\n\t\t\t\t\t};\n\t\t\t }\n\t > {\n\t// If only text blocks, return as concatenated string for simplicity\n\tconst hasImages = content.some((c) => c.type === \"image\");\n\tif (!hasImages) {\n\t\treturn sanitizeSurrogates(content.map((c) => (c as TextContent).text).join(\"\\n\"));\n\t}\n\n\t// If we have images, convert to content block array\n\tconst blocks = content.map((block) => {\n\t\tif (block.type === \"text\") {\n\t\t\treturn {\n\t\t\t\ttype: \"text\" as const,\n\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\ttype: \"image\" as const,\n\t\t\tsource: {\n\t\t\t\ttype: \"base64\" as const,\n\t\t\t\tmedia_type: block.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\tdata: block.data,\n\t\t\t},\n\t\t};\n\t});\n\n\t// If only images (no text), add placeholder text block\n\tconst hasText = blocks.some((b) => b.type === \"text\");\n\tif (!hasText) {\n\t\tblocks.unshift({\n\t\t\ttype: \"text\" as const,\n\t\t\ttext: \"(see attached image)\",\n\t\t});\n\t}\n\n\treturn blocks;\n}\n\nexport type AnthropicEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\nexport type AnthropicThinkingDisplay = \"summarized\" | \"omitted\";\n\nexport interface AnthropicOptions extends StreamOptions {\n\t/**\n\t * Enable extended thinking.\n\t * For Opus 4.6 and Sonnet 4.6: uses adaptive thinking (model decides when/how much to think).\n\t * For older models: uses budget-based thinking with thinkingBudgetTokens.\n\t */\n\tthinkingEnabled?: boolean;\n\t/**\n\t * Token budget for extended thinking (older models only).\n\t * Ignored for Opus 4.6 and Sonnet 4.6, which use adaptive thinking.\n\t */\n\tthinkingBudgetTokens?: number;\n\t/**\n\t * Effort level for adaptive thinking (Opus 4.6+ and Sonnet 4.6).\n\t * Controls how much thinking Claude allocates:\n\t * - \"max\": Always thinks with no constraints (Opus 4.6 only)\n\t * - \"xhigh\": Highest reasoning level (Opus 4.7)\n\t * - \"high\": Always thinks, deep reasoning (default)\n\t * - \"medium\": Moderate thinking, may skip for simple queries\n\t * - \"low\": Minimal thinking, skips for simple tasks\n\t * Ignored for older models.\n\t */\n\teffort?: AnthropicEffort;\n\t/**\n\t * Controls how thinking content is returned in API responses.\n\t * - \"summarized\": Thinking blocks contain summarized thinking text (default here).\n\t * - \"omitted\": Thinking blocks return an empty thinking field; the encrypted\n\t * signature still travels back for multi-turn continuity. Use for faster\n\t * time-to-first-text-token when your UI does not surface thinking.\n\t *\n\t * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview\n\t * is \"omitted\". We default to \"summarized\" here to keep behavior consistent\n\t * with older Claude 4 models. Set this explicitly to \"omitted\" to opt in.\n\t */\n\tthinkingDisplay?: AnthropicThinkingDisplay;\n\tinterleavedThinking?: boolean;\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n\t/**\n\t * Pre-built Anthropic client instance. When provided, skips internal client\n\t * construction entirely. Use this to inject alternative SDK clients such as\n\t * `AnthropicVertex` that shares the same messaging API.\n\t */\n\tclient?: Anthropic;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tlet client: Anthropic;\n\t\t\tlet isOAuth: boolean;\n\n\t\t\tif (options?.client) {\n\t\t\t\tclient = options.client;\n\t\t\t\tisOAuth = false;\n\t\t\t} else {\n\t\t\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\t\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\t\t\tif (model.provider === \"github-copilot\") {\n\t\t\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\thasImages,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst created = createClient(\n\t\t\t\t\tmodel,\n\t\t\t\t\tapiKey,\n\t\t\t\t\toptions?.interleavedThinking ?? true,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t\tcopilotDynamicHeaders,\n\t\t\t\t);\n\t\t\t\tclient = created.client;\n\t\t\t\tisOAuth = created.isOAuthToken;\n\t\t\t}\n\t\t\tlet params = buildParams(model, context, isOAuth, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as MessageCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst { data: anthropicStream, response } = await client.messages\n\t\t\t\t.stream({ ...params, stream: true }, { signal: options?.signal })\n\t\t\t\t.withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\ttype Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };\n\t\t\tconst blocks = output.content as Block[];\n\n\t\t\tfor await (const event of anthropicStream) {\n\t\t\t\tif (event.type === \"message_start\") {\n\t\t\t\t\toutput.responseId = event.message.id;\n\t\t\t\t\t// Capture initial token usage from message_start event\n\t\t\t\t\t// This ensures we have input token counts even if the stream is aborted early\n\t\t\t\t\toutput.usage.input = event.message.usage.input_tokens || 0;\n\t\t\t\t\toutput.usage.output = event.message.usage.output_tokens || 0;\n\t\t\t\t\toutput.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;\n\t\t\t\t\toutput.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t} else if (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\tthinkingSignature: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"redacted_thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"[Reasoning redacted]\",\n\t\t\t\t\t\t\tthinkingSignature: event.content_block.data,\n\t\t\t\t\t\t\tredacted: true,\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: isOAuth\n\t\t\t\t\t\t\t\t? fromClaudeCodeName(event.content_block.name, context.tools)\n\t\t\t\t\t\t\t\t: event.content_block.name,\n\t\t\t\t\t\t\targuments: (event.content_block.input as Record<string, any>) ?? {},\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"text\") {\n\t\t\t\t\t\t\tblock.text += event.delta.text;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinking += event.delta.thinking;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.partialJson += event.delta.partial_json;\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.partial_json,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"signature_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinkingSignature = block.thinkingSignature || \"\";\n\t\t\t\t\t\t\tblock.thinkingSignature += event.delta.signature;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_stop\") {\n\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\tif (block) {\n\t\t\t\t\t\tdelete (block as any).index;\n\t\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t\t\t\t// carries parsed arguments.\n\t\t\t\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\ttoolCall: block,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"message_delta\") {\n\t\t\t\t\tif (event.delta.stop_reason) {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(event.delta.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\t// Only update usage fields if present (not null).\n\t\t\t\t\t// Preserves input_tokens from message_start when proxies omit it in message_delta.\n\t\t\t\t\tif (event.usage.input_tokens != null) {\n\t\t\t\t\t\toutput.usage.input = event.usage.input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.output_tokens != null) {\n\t\t\t\t\t\toutput.usage.output = event.usage.output_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_read_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheRead = event.usage.cache_read_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_creation_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheWrite = event.usage.cache_creation_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Check if a model supports adaptive thinking (Opus 4.6+, Sonnet 4.6)\n */\nfunction supportsAdaptiveThinking(modelId: string): boolean {\n\t// Adaptive-thinking model IDs (with or without date suffix)\n\treturn (\n\t\tmodelId.includes(\"opus-4-6\") ||\n\t\tmodelId.includes(\"opus-4.6\") ||\n\t\tmodelId.includes(\"opus-4-7\") ||\n\t\tmodelId.includes(\"opus-4.7\") ||\n\t\tmodelId.includes(\"sonnet-4-6\") ||\n\t\tmodelId.includes(\"sonnet-4.6\")\n\t);\n}\n\n/**\n * Map ThinkingLevel to Anthropic effort levels for adaptive thinking.\n * Note: effort \"max\" is only valid on Opus 4.6, while Opus 4.7 supports \"xhigh\".\n */\nfunction mapThinkingLevelToEffort(level: SimpleStreamOptions[\"reasoning\"], modelId: string): AnthropicEffort {\n\tswitch (level) {\n\t\tcase \"minimal\":\n\t\t\treturn \"low\";\n\t\tcase \"low\":\n\t\t\treturn \"low\";\n\t\tcase \"medium\":\n\t\t\treturn \"medium\";\n\t\tcase \"high\":\n\t\t\treturn \"high\";\n\t\tcase \"xhigh\":\n\t\t\tif (modelId.includes(\"opus-4-6\") || modelId.includes(\"opus-4.6\")) {\n\t\t\t\treturn \"max\";\n\t\t\t}\n\t\t\tif (modelId.includes(\"opus-4-7\") || modelId.includes(\"opus-4.7\")) {\n\t\t\t\treturn \"xhigh\";\n\t\t\t}\n\t\t\treturn \"high\";\n\t\tdefault:\n\t\t\treturn \"high\";\n\t}\n}\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n\nfunction isOAuthToken(apiKey: string): boolean {\n\treturn apiKey.includes(\"sk-ant-oat\");\n}\n\nfunction createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): { client: Anthropic; isOAuthToken: boolean } {\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\tconst betaFeatures = [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// OAuth: Bearer auth, Claude Code identity headers\n\tif (isOAuthToken(apiKey)) {\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t\"anthropic-beta\": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(\",\")}`,\n\t\t\t\t\t\"user-agent\": `claude-cli/${claudeCodeVersion}`,\n\t\t\t\t\t\"x-app\": \"cli\",\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: true };\n\t}\n\n\t// API key auth\n\tconst client = new Anthropic({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\"anthropic-beta\": betaFeatures.join(\",\"),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nfunction buildParams(\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\tisOAuthToken: boolean,\n\toptions?: AnthropicOptions,\n): MessageCreateParamsStreaming {\n\tconst { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);\n\tconst params: MessageCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tmessages: convertMessages(context.messages, model, isOAuthToken, cacheControl),\n\t\tmax_tokens: options?.maxTokens || (model.maxTokens / 3) | 0,\n\t\tstream: true,\n\t};\n\n\t// For OAuth tokens, we MUST include Claude Code identity\n\tif (isOAuthToken) {\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t\tif (context.systemPrompt) {\n\t\t\tparams.system.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t});\n\t\t}\n\t} else if (context.systemPrompt) {\n\t\t// Add cache control to system prompt for non-OAuth tokens\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t}\n\n\t// Temperature is incompatible with extended thinking (adaptive or budget-based).\n\tif (options?.temperature !== undefined && !options?.thinkingEnabled) {\n\t\tparams.temperature = options.temperature;\n\t}\n\n\tif (context.tools) {\n\t\tparams.tools = convertTools(context.tools, isOAuthToken, cacheControl);\n\t}\n\n\t// Configure thinking mode: adaptive (Opus 4.6+ and Sonnet 4.6),\n\t// budget-based (older models), or explicitly disabled.\n\tif (model.reasoning) {\n\t\tif (options?.thinkingEnabled) {\n\t\t\t// Default to \"summarized\" so Opus 4.7 and Mythos Preview behave like\n\t\t\t// older Claude 4 models (whose API default is also \"summarized\").\n\t\t\tconst display: AnthropicThinkingDisplay = options.thinkingDisplay ?? \"summarized\";\n\t\t\tif (supportsAdaptiveThinking(model.id)) {\n\t\t\t\t// Adaptive thinking: Claude decides when and how much to think.\n\t\t\t\tparams.thinking = { type: \"adaptive\", display };\n\t\t\t\tif (options.effort) {\n\t\t\t\t\t// The Anthropic SDK types can lag newly supported effort values such as \"xhigh\".\n\t\t\t\t\tparams.output_config =\n\t\t\t\t\t\toptions.effort === \"xhigh\"\n\t\t\t\t\t\t\t? ({ effort: options.effort } as unknown as NonNullable<\n\t\t\t\t\t\t\t\t\tMessageCreateParamsStreaming[\"output_config\"]\n\t\t\t\t\t\t\t\t>)\n\t\t\t\t\t\t\t: { effort: options.effort };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Budget-based thinking for older models\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinkingBudgetTokens || 1024,\n\t\t\t\t\tdisplay,\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (options?.thinkingEnabled === false) {\n\t\t\tparams.thinking = { type: \"disabled\" };\n\t\t}\n\t}\n\n\tif (options?.metadata) {\n\t\tconst userId = options.metadata.user_id;\n\t\tif (typeof userId === \"string\") {\n\t\t\tparams.metadata = { user_id: userId };\n\t\t}\n\t}\n\n\tif (options?.toolChoice) {\n\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t} else {\n\t\t\tparams.tool_choice = options.toolChoice;\n\t\t}\n\t}\n\n\treturn params;\n}\n\n// Normalize tool call IDs to match Anthropic's required pattern and length\nfunction normalizeToolCallId(id: string): string {\n\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n}\n\nfunction convertMessages(\n\tmessages: Message[],\n\tmodel: Model<\"anthropic-messages\">,\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): MessageParam[] {\n\tconst params: MessageParam[] = [];\n\n\t// Transform messages for cross-provider compatibility\n\tconst transformedMessages = transformMessages(messages, model, normalizeToolCallId);\n\n\tfor (let i = 0; i < transformedMessages.length; i++) {\n\t\tconst msg = transformedMessages[i];\n\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tif (msg.content.trim().length > 0) {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: sanitizeSurrogates(msg.content),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tlet filteredBlocks = !model?.input.includes(\"image\") ? blocks.filter((b) => b.type !== \"image\") : blocks;\n\t\t\t\tfilteredBlocks = filteredBlocks.filter((b) => {\n\t\t\t\t\tif (b.type === \"text\") {\n\t\t\t\t\t\treturn b.text.trim().length > 0;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\t\t\t\tif (filteredBlocks.length === 0) continue;\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: filteredBlocks,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (block.text.trim().length === 0) continue;\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking: pass the opaque payload back as redacted_thinking\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"redacted_thinking\",\n\t\t\t\t\t\t\tdata: block.thinkingSignature!,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (block.thinking.trim().length === 0) continue;\n\t\t\t\t\t// If thinking signature is missing/empty (e.g., from aborted stream),\n\t\t\t\t\t// convert to plain text block without <thinking> tags to avoid API rejection\n\t\t\t\t\t// and prevent Claude from mimicking the tags in responses\n\t\t\t\t\tif (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\tsignature: block.thinkingSignature,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\tname: isOAuthToken ? toClaudeCodeName(block.name) : block.name,\n\t\t\t\t\t\tinput: block.arguments ?? {},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (blocks.length === 0) continue;\n\t\t\tparams.push({\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint\n\t\t\tconst toolResults: ContentBlockParam[] = [];\n\n\t\t\t// Add the current tool result\n\t\t\ttoolResults.push({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\tcontent: convertContentBlocks(msg.content),\n\t\t\t\tis_error: msg.isError,\n\t\t\t});\n\n\t\t\t// Look ahead for consecutive toolResult messages\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < transformedMessages.length && transformedMessages[j].role === \"toolResult\") {\n\t\t\t\tconst nextMsg = transformedMessages[j] as ToolResultMessage; // We know it's a toolResult\n\t\t\t\ttoolResults.push({\n\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\ttool_use_id: nextMsg.toolCallId,\n\t\t\t\t\tcontent: convertContentBlocks(nextMsg.content),\n\t\t\t\t\tis_error: nextMsg.isError,\n\t\t\t\t});\n\t\t\t\tj++;\n\t\t\t}\n\n\t\t\t// Skip the messages we've already processed\n\t\t\ti = j - 1;\n\n\t\t\t// Add a single user message with all tool results\n\t\t\tparams.push({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: toolResults,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add cache_control to the last user message to cache conversation history\n\tif (cacheControl && params.length > 0) {\n\t\tconst lastMessage = params[params.length - 1];\n\t\tif (lastMessage.role === \"user\") {\n\t\t\tif (Array.isArray(lastMessage.content)) {\n\t\t\t\tconst lastBlock = lastMessage.content[lastMessage.content.length - 1];\n\t\t\t\tif (\n\t\t\t\t\tlastBlock &&\n\t\t\t\t\t(lastBlock.type === \"text\" || lastBlock.type === \"image\" || lastBlock.type === \"tool_result\")\n\t\t\t\t) {\n\t\t\t\t\t(lastBlock as any).cache_control = cacheControl;\n\t\t\t\t}\n\t\t\t} else if (typeof lastMessage.content === \"string\") {\n\t\t\t\tlastMessage.content = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: lastMessage.content,\n\t\t\t\t\t\tcache_control: cacheControl,\n\t\t\t\t\t},\n\t\t\t\t] as any;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction convertTools(\n\ttools: Tool[],\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): Anthropic.Messages.Tool[] {\n\tif (!tools) return [];\n\n\treturn tools.map((tool, index) => {\n\t\tconst schema = tool.parameters as { properties?: unknown; required?: string[] };\n\n\t\treturn {\n\t\t\tname: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: schema.properties ?? {},\n\t\t\t\trequired: schema.required ?? [],\n\t\t\t},\n\t\t\t...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),\n\t\t};\n\t});\n}\n\nfunction mapStopReason(reason: Anthropic.Messages.StopReason | string): StopReason {\n\tswitch (reason) {\n\t\tcase \"end_turn\":\n\t\t\treturn \"stop\";\n\t\tcase \"max_tokens\":\n\t\t\treturn \"length\";\n\t\tcase \"tool_use\":\n\t\t\treturn \"toolUse\";\n\t\tcase \"refusal\":\n\t\t\treturn \"error\";\n\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\treturn \"stop\";\n\t\tcase \"stop_sequence\":\n\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\tcase \"sensitive\": // Content flagged by safety filters (not yet in SDK types)\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\t// Handle unknown stop reasons gracefully (API may add new values)\n\t\t\tthrow new Error(`Unhandled stop reason: ${reason}`);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n\tCacheControlEphemeral,\n\tContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tMessageParam,\n} from \"@anthropic-ai/sdk/resources/messages.js\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport { calculateCost } from \"../models.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord } from \"../utils/headers.js\";\nimport { parseStreamingJson } from \"../utils/json-parse.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCacheControl(\n\tbaseUrl: string,\n\tcacheRetention?: CacheRetention,\n): { retention: CacheRetention; cacheControl?: CacheControlEphemeral } {\n\tconst retention = resolveCacheRetention(cacheRetention);\n\tif (retention === \"none\") {\n\t\treturn { retention };\n\t}\n\tconst ttl = retention === \"long\" && baseUrl.includes(\"api.anthropic.com\") ? \"1h\" : undefined;\n\treturn {\n\t\tretention,\n\t\tcacheControl: { type: \"ephemeral\", ...(ttl && { ttl }) },\n\t};\n}\n\n// Stealth mode: Mimic Claude Code's tool naming exactly\nconst claudeCodeVersion = \"2.1.75\";\n\n// Claude Code 2.x tool names (canonical casing)\n// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md\n// To update: https://github.com/badlogic/cchistory\nconst claudeCodeTools = [\n\t\"Read\",\n\t\"Write\",\n\t\"Edit\",\n\t\"Bash\",\n\t\"Grep\",\n\t\"Glob\",\n\t\"AskUserQuestion\",\n\t\"EnterPlanMode\",\n\t\"ExitPlanMode\",\n\t\"KillShell\",\n\t\"NotebookEdit\",\n\t\"Skill\",\n\t\"Task\",\n\t\"TaskOutput\",\n\t\"TodoWrite\",\n\t\"WebFetch\",\n\t\"WebSearch\",\n];\n\nconst ccToolLookup = new Map(claudeCodeTools.map((t) => [t.toLowerCase(), t]));\n\n// Convert tool name to CC canonical casing if it matches (case-insensitive)\nconst toClaudeCodeName = (name: string) => ccToolLookup.get(name.toLowerCase()) ?? name;\nconst fromClaudeCodeName = (name: string, tools?: Tool[]) => {\n\tif (tools && tools.length > 0) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tconst matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);\n\t\tif (matchedTool) return matchedTool.name;\n\t}\n\treturn name;\n};\n\n/**\n * Convert content blocks to Anthropic API format\n */\nfunction convertContentBlocks(content: (TextContent | ImageContent)[]):\n\t| string\n\t| Array<\n\t\t\t| { type: \"text\"; text: string }\n\t\t\t| {\n\t\t\t\t\ttype: \"image\";\n\t\t\t\t\tsource: {\n\t\t\t\t\t\ttype: \"base64\";\n\t\t\t\t\t\tmedia_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n\t\t\t\t\t\tdata: string;\n\t\t\t\t\t};\n\t\t\t }\n\t > {\n\t// If only text blocks, return as concatenated string for simplicity\n\tconst hasImages = content.some((c) => c.type === \"image\");\n\tif (!hasImages) {\n\t\treturn sanitizeSurrogates(content.map((c) => (c as TextContent).text).join(\"\\n\"));\n\t}\n\n\t// If we have images, convert to content block array\n\tconst blocks = content.map((block) => {\n\t\tif (block.type === \"text\") {\n\t\t\treturn {\n\t\t\t\ttype: \"text\" as const,\n\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\ttype: \"image\" as const,\n\t\t\tsource: {\n\t\t\t\ttype: \"base64\" as const,\n\t\t\t\tmedia_type: block.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\tdata: block.data,\n\t\t\t},\n\t\t};\n\t});\n\n\t// If only images (no text), add placeholder text block\n\tconst hasText = blocks.some((b) => b.type === \"text\");\n\tif (!hasText) {\n\t\tblocks.unshift({\n\t\t\ttype: \"text\" as const,\n\t\t\ttext: \"(see attached image)\",\n\t\t});\n\t}\n\n\treturn blocks;\n}\n\nexport type AnthropicEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\nexport type AnthropicThinkingDisplay = \"summarized\" | \"omitted\";\n\nexport interface AnthropicOptions extends StreamOptions {\n\t/**\n\t * Enable extended thinking.\n\t * For Opus 4.6 and Sonnet 4.6: uses adaptive thinking (model decides when/how much to think).\n\t * For older models: uses budget-based thinking with thinkingBudgetTokens.\n\t */\n\tthinkingEnabled?: boolean;\n\t/**\n\t * Token budget for extended thinking (older models only).\n\t * Ignored for Opus 4.6 and Sonnet 4.6, which use adaptive thinking.\n\t */\n\tthinkingBudgetTokens?: number;\n\t/**\n\t * Effort level for adaptive thinking (Opus 4.6+ and Sonnet 4.6).\n\t * Controls how much thinking Claude allocates:\n\t * - \"max\": Always thinks with no constraints (Opus 4.6 only)\n\t * - \"xhigh\": Highest reasoning level (Opus 4.7)\n\t * - \"high\": Always thinks, deep reasoning (default)\n\t * - \"medium\": Moderate thinking, may skip for simple queries\n\t * - \"low\": Minimal thinking, skips for simple tasks\n\t * Ignored for older models.\n\t */\n\teffort?: AnthropicEffort;\n\t/**\n\t * Controls how thinking content is returned in API responses.\n\t * - \"summarized\": Thinking blocks contain summarized thinking text (default here).\n\t * - \"omitted\": Thinking blocks return an empty thinking field; the encrypted\n\t * signature still travels back for multi-turn continuity. Use for faster\n\t * time-to-first-text-token when your UI does not surface thinking.\n\t *\n\t * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview\n\t * is \"omitted\". We default to \"summarized\" here to keep behavior consistent\n\t * with older Claude 4 models. Set this explicitly to \"omitted\" to opt in.\n\t */\n\tthinkingDisplay?: AnthropicThinkingDisplay;\n\tinterleavedThinking?: boolean;\n\ttoolChoice?: \"auto\" | \"any\" | \"none\" | { type: \"tool\"; name: string };\n\t/**\n\t * Pre-built Anthropic client instance. When provided, skips internal client\n\t * construction entirely. Use this to inject alternative SDK clients such as\n\t * `AnthropicVertex` that shares the same messaging API.\n\t */\n\tclient?: Anthropic;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tlet client: Anthropic;\n\t\t\tlet isOAuth: boolean;\n\n\t\t\tif (options?.client) {\n\t\t\t\tclient = options.client;\n\t\t\t\tisOAuth = false;\n\t\t\t} else {\n\t\t\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\t\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\t\t\tif (model.provider === \"github-copilot\") {\n\t\t\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\thasImages,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst created = createClient(\n\t\t\t\t\tmodel,\n\t\t\t\t\tapiKey,\n\t\t\t\t\toptions?.interleavedThinking ?? true,\n\t\t\t\t\toptions?.headers,\n\t\t\t\t\tcopilotDynamicHeaders,\n\t\t\t\t);\n\t\t\t\tclient = created.client;\n\t\t\t\tisOAuth = created.isOAuthToken;\n\t\t\t}\n\t\t\tlet params = buildParams(model, context, isOAuth, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as MessageCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst { data: anthropicStream, response } = await client.messages\n\t\t\t\t.stream({ ...params, stream: true }, { signal: options?.signal })\n\t\t\t\t.withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\ttype Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };\n\t\t\tconst blocks = output.content as Block[];\n\n\t\t\tfor await (const event of anthropicStream) {\n\t\t\t\tif (event.type === \"message_start\") {\n\t\t\t\t\toutput.responseId = event.message.id;\n\t\t\t\t\t// Capture initial token usage from message_start event\n\t\t\t\t\t// This ensures we have input token counts even if the stream is aborted early\n\t\t\t\t\toutput.usage.input = event.message.usage.input_tokens || 0;\n\t\t\t\t\toutput.usage.output = event.message.usage.output_tokens || 0;\n\t\t\t\t\toutput.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;\n\t\t\t\t\toutput.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t} else if (event.type === \"content_block_start\") {\n\t\t\t\t\tif (event.content_block.type === \"text\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\tthinkingSignature: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"redacted_thinking\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: \"[Reasoning redacted]\",\n\t\t\t\t\t\t\tthinkingSignature: event.content_block.data,\n\t\t\t\t\t\t\tredacted: true,\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t} else if (event.content_block.type === \"tool_use\") {\n\t\t\t\t\t\tconst block: Block = {\n\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\tid: event.content_block.id,\n\t\t\t\t\t\t\tname: isOAuth\n\t\t\t\t\t\t\t\t? fromClaudeCodeName(event.content_block.name, context.tools)\n\t\t\t\t\t\t\t\t: event.content_block.name,\n\t\t\t\t\t\t\targuments: (event.content_block.input as Record<string, any>) ?? {},\n\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t\tindex: event.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t\toutput.content.push(block);\n\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_delta\") {\n\t\t\t\t\tif (event.delta.type === \"text_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"text\") {\n\t\t\t\t\t\t\tblock.text += event.delta.text;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"thinking_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinking += event.delta.thinking;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"input_json_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.partialJson += event.delta.partial_json;\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tdelta: event.delta.partial_json,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (event.delta.type === \"signature_delta\") {\n\t\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\t\tif (block && block.type === \"thinking\") {\n\t\t\t\t\t\t\tblock.thinkingSignature = block.thinkingSignature || \"\";\n\t\t\t\t\t\t\tblock.thinkingSignature += event.delta.signature;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"content_block_stop\") {\n\t\t\t\t\tconst index = blocks.findIndex((b) => b.index === event.index);\n\t\t\t\t\tconst block = blocks[index];\n\t\t\t\t\tif (block) {\n\t\t\t\t\t\tdelete (block as any).index;\n\t\t\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.text,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\tcontent: block.thinking,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\t\tblock.arguments = parseStreamingJson(block.partialJson);\n\t\t\t\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t\t\t\t// carries parsed arguments.\n\t\t\t\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\t\t\t\tcontentIndex: index,\n\t\t\t\t\t\t\t\ttoolCall: block,\n\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (event.type === \"message_delta\") {\n\t\t\t\t\tif (event.delta.stop_reason) {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(event.delta.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\t// Only update usage fields if present (not null).\n\t\t\t\t\t// Preserves input_tokens from message_start when proxies omit it in message_delta.\n\t\t\t\t\tif (event.usage.input_tokens != null) {\n\t\t\t\t\t\toutput.usage.input = event.usage.input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.output_tokens != null) {\n\t\t\t\t\t\toutput.usage.output = event.usage.output_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_read_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheRead = event.usage.cache_read_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.usage.cache_creation_input_tokens != null) {\n\t\t\t\t\t\toutput.usage.cacheWrite = event.usage.cache_creation_input_tokens;\n\t\t\t\t\t}\n\t\t\t\t\t// Anthropic doesn't provide total_tokens, compute from components\n\t\t\t\t\toutput.usage.totalTokens =\n\t\t\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Check if a model supports adaptive thinking (Opus 4.6+, Sonnet 4.6)\n */\nfunction supportsAdaptiveThinking(modelId: string): boolean {\n\t// Adaptive-thinking model IDs (with or without date suffix)\n\treturn (\n\t\tmodelId.includes(\"opus-4-6\") ||\n\t\tmodelId.includes(\"opus-4.6\") ||\n\t\tmodelId.includes(\"opus-4-7\") ||\n\t\tmodelId.includes(\"opus-4.7\") ||\n\t\tmodelId.includes(\"sonnet-4-6\") ||\n\t\tmodelId.includes(\"sonnet-4.6\")\n\t);\n}\n\n/**\n * Map ThinkingLevel to Anthropic effort levels for adaptive thinking.\n * Note: effort \"max\" is only valid on Opus 4.6, while Opus 4.7 supports \"xhigh\".\n */\nfunction mapThinkingLevelToEffort(level: SimpleStreamOptions[\"reasoning\"], modelId: string): AnthropicEffort {\n\tswitch (level) {\n\t\tcase \"minimal\":\n\t\t\treturn \"low\";\n\t\tcase \"low\":\n\t\t\treturn \"low\";\n\t\tcase \"medium\":\n\t\t\treturn \"medium\";\n\t\tcase \"high\":\n\t\t\treturn \"high\";\n\t\tcase \"xhigh\":\n\t\t\tif (modelId.includes(\"opus-4-6\") || modelId.includes(\"opus-4.6\")) {\n\t\t\t\treturn \"max\";\n\t\t\t}\n\t\t\tif (modelId.includes(\"opus-4-7\") || modelId.includes(\"opus-4.7\")) {\n\t\t\t\treturn \"xhigh\";\n\t\t\t}\n\t\t\treturn \"high\";\n\t\tdefault:\n\t\t\treturn \"high\";\n\t}\n}\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n\nfunction isOAuthToken(apiKey: string): boolean {\n\treturn apiKey.includes(\"sk-ant-oat\");\n}\n\nfunction createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): { client: Anthropic; isOAuthToken: boolean } {\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\tconst betaFeatures = [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// OAuth: Bearer auth, Claude Code identity headers\n\tif (isOAuthToken(apiKey)) {\n\t\tconst client = new Anthropic({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: model.baseUrl,\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t\"anthropic-beta\": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(\",\")}`,\n\t\t\t\t\t\"user-agent\": `claude-cli/${claudeCodeVersion}`,\n\t\t\t\t\t\"x-app\": \"cli\",\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: true };\n\t}\n\n\t// API key auth\n\tconst client = new Anthropic({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\"anthropic-beta\": betaFeatures.join(\",\"),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nfunction buildParams(\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\tisOAuthToken: boolean,\n\toptions?: AnthropicOptions,\n): MessageCreateParamsStreaming {\n\tconst { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);\n\tconst params: MessageCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tmessages: convertMessages(context.messages, model, isOAuthToken, cacheControl),\n\t\tmax_tokens: options?.maxTokens || (model.maxTokens / 3) | 0,\n\t\tstream: true,\n\t};\n\n\t// For OAuth tokens, we MUST include Claude Code identity\n\tif (isOAuthToken) {\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"You are Claude Code, Anthropic's official CLI for Claude.\",\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t\tif (context.systemPrompt) {\n\t\t\tparams.system.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t});\n\t\t}\n\t} else if (context.systemPrompt) {\n\t\t// Add cache control to system prompt for non-OAuth tokens\n\t\tparams.system = [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: sanitizeSurrogates(context.systemPrompt),\n\t\t\t\t...(cacheControl ? { cache_control: cacheControl } : {}),\n\t\t\t},\n\t\t];\n\t}\n\n\t// Temperature is incompatible with extended thinking (adaptive or budget-based).\n\tif (options?.temperature !== undefined && !options?.thinkingEnabled) {\n\t\tparams.temperature = options.temperature;\n\t}\n\n\tif (context.tools) {\n\t\tparams.tools = convertTools(context.tools, isOAuthToken, cacheControl);\n\t}\n\n\t// Configure thinking mode: adaptive (Opus 4.6+ and Sonnet 4.6),\n\t// budget-based (older models), or explicitly disabled.\n\tif (model.reasoning) {\n\t\tif (options?.thinkingEnabled) {\n\t\t\t// Default to \"summarized\" so Opus 4.7 and Mythos Preview behave like\n\t\t\t// older Claude 4 models (whose API default is also \"summarized\").\n\t\t\tconst display: AnthropicThinkingDisplay = options.thinkingDisplay ?? \"summarized\";\n\t\t\tif (supportsAdaptiveThinking(model.id)) {\n\t\t\t\t// Adaptive thinking: Claude decides when and how much to think.\n\t\t\t\tparams.thinking = { type: \"adaptive\", display };\n\t\t\t\tif (options.effort) {\n\t\t\t\t\t// The Anthropic SDK types can lag newly supported effort values such as \"xhigh\".\n\t\t\t\t\tparams.output_config =\n\t\t\t\t\t\toptions.effort === \"xhigh\"\n\t\t\t\t\t\t\t? ({ effort: options.effort } as unknown as NonNullable<\n\t\t\t\t\t\t\t\t\tMessageCreateParamsStreaming[\"output_config\"]\n\t\t\t\t\t\t\t\t>)\n\t\t\t\t\t\t\t: { effort: options.effort };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Budget-based thinking for older models\n\t\t\t\tparams.thinking = {\n\t\t\t\t\ttype: \"enabled\",\n\t\t\t\t\tbudget_tokens: options.thinkingBudgetTokens || 1024,\n\t\t\t\t\tdisplay,\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (options?.thinkingEnabled === false) {\n\t\t\tparams.thinking = { type: \"disabled\" };\n\t\t}\n\t}\n\n\tif (options?.metadata) {\n\t\tconst userId = options.metadata.user_id;\n\t\tif (typeof userId === \"string\") {\n\t\t\tparams.metadata = { user_id: userId };\n\t\t}\n\t}\n\n\tif (options?.toolChoice) {\n\t\tif (typeof options.toolChoice === \"string\") {\n\t\t\tparams.tool_choice = { type: options.toolChoice };\n\t\t} else {\n\t\t\tparams.tool_choice = options.toolChoice;\n\t\t}\n\t}\n\n\treturn params;\n}\n\n// Normalize tool call IDs to match Anthropic's required pattern and length\nfunction normalizeToolCallId(id: string): string {\n\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n}\n\nfunction convertMessages(\n\tmessages: Message[],\n\tmodel: Model<\"anthropic-messages\">,\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): MessageParam[] {\n\tconst params: MessageParam[] = [];\n\n\t// Transform messages for cross-provider compatibility\n\tconst transformedMessages = transformMessages(messages, model, normalizeToolCallId);\n\n\tfor (let i = 0; i < transformedMessages.length; i++) {\n\t\tconst msg = transformedMessages[i];\n\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tif (msg.content.trim().length > 0) {\n\t\t\t\t\tparams.push({\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: sanitizeSurrogates(msg.content),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst blocks: ContentBlockParam[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"image\",\n\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\ttype: \"base64\",\n\t\t\t\t\t\t\t\tmedia_type: item.mimeType as \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst filteredBlocks = blocks.filter((b) => {\n\t\t\t\t\tif (b.type === \"text\") {\n\t\t\t\t\t\treturn b.text.trim().length > 0;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\t\t\t\tif (filteredBlocks.length === 0) continue;\n\t\t\t\tparams.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: filteredBlocks,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst blocks: ContentBlockParam[] = [];\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (block.text.trim().length === 0) continue;\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking: pass the opaque payload back as redacted_thinking\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"redacted_thinking\",\n\t\t\t\t\t\t\tdata: block.thinkingSignature!,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (block.thinking.trim().length === 0) continue;\n\t\t\t\t\t// If thinking signature is missing/empty (e.g., from aborted stream),\n\t\t\t\t\t// convert to plain text block without <thinking> tags to avoid API rejection\n\t\t\t\t\t// and prevent Claude from mimicking the tags in responses\n\t\t\t\t\tif (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblocks.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\tsignature: block.thinkingSignature,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tblocks.push({\n\t\t\t\t\t\ttype: \"tool_use\",\n\t\t\t\t\t\tid: block.id,\n\t\t\t\t\t\tname: isOAuthToken ? toClaudeCodeName(block.name) : block.name,\n\t\t\t\t\t\tinput: block.arguments ?? {},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (blocks.length === 0) continue;\n\t\t\tparams.push({\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: blocks,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint\n\t\t\tconst toolResults: ContentBlockParam[] = [];\n\n\t\t\t// Add the current tool result\n\t\t\ttoolResults.push({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttool_use_id: msg.toolCallId,\n\t\t\t\tcontent: convertContentBlocks(msg.content),\n\t\t\t\tis_error: msg.isError,\n\t\t\t});\n\n\t\t\t// Look ahead for consecutive toolResult messages\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < transformedMessages.length && transformedMessages[j].role === \"toolResult\") {\n\t\t\t\tconst nextMsg = transformedMessages[j] as ToolResultMessage; // We know it's a toolResult\n\t\t\t\ttoolResults.push({\n\t\t\t\t\ttype: \"tool_result\",\n\t\t\t\t\ttool_use_id: nextMsg.toolCallId,\n\t\t\t\t\tcontent: convertContentBlocks(nextMsg.content),\n\t\t\t\t\tis_error: nextMsg.isError,\n\t\t\t\t});\n\t\t\t\tj++;\n\t\t\t}\n\n\t\t\t// Skip the messages we've already processed\n\t\t\ti = j - 1;\n\n\t\t\t// Add a single user message with all tool results\n\t\t\tparams.push({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: toolResults,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Add cache_control to the last user message to cache conversation history\n\tif (cacheControl && params.length > 0) {\n\t\tconst lastMessage = params[params.length - 1];\n\t\tif (lastMessage.role === \"user\") {\n\t\t\tif (Array.isArray(lastMessage.content)) {\n\t\t\t\tconst lastBlock = lastMessage.content[lastMessage.content.length - 1];\n\t\t\t\tif (\n\t\t\t\t\tlastBlock &&\n\t\t\t\t\t(lastBlock.type === \"text\" || lastBlock.type === \"image\" || lastBlock.type === \"tool_result\")\n\t\t\t\t) {\n\t\t\t\t\t(lastBlock as any).cache_control = cacheControl;\n\t\t\t\t}\n\t\t\t} else if (typeof lastMessage.content === \"string\") {\n\t\t\t\tlastMessage.content = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: lastMessage.content,\n\t\t\t\t\t\tcache_control: cacheControl,\n\t\t\t\t\t},\n\t\t\t\t] as any;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction convertTools(\n\ttools: Tool[],\n\tisOAuthToken: boolean,\n\tcacheControl?: CacheControlEphemeral,\n): Anthropic.Messages.Tool[] {\n\tif (!tools) return [];\n\n\treturn tools.map((tool, index) => {\n\t\tconst schema = tool.parameters as { properties?: unknown; required?: string[] };\n\n\t\treturn {\n\t\t\tname: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinput_schema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: schema.properties ?? {},\n\t\t\t\trequired: schema.required ?? [],\n\t\t\t},\n\t\t\t...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),\n\t\t};\n\t});\n}\n\nfunction mapStopReason(reason: Anthropic.Messages.StopReason | string): StopReason {\n\tswitch (reason) {\n\t\tcase \"end_turn\":\n\t\t\treturn \"stop\";\n\t\tcase \"max_tokens\":\n\t\t\treturn \"length\";\n\t\tcase \"tool_use\":\n\t\t\treturn \"toolUse\";\n\t\tcase \"refusal\":\n\t\t\treturn \"error\";\n\t\tcase \"pause_turn\": // Stop is good enough -> resubmit\n\t\t\treturn \"stop\";\n\t\tcase \"stop_sequence\":\n\t\t\treturn \"stop\"; // We don't supply stop sequences, so this should never happen\n\t\tcase \"sensitive\": // Content flagged by safety filters (not yet in SDK types)\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\t// Handle unknown stop reasons gracefully (API may add new values)\n\t\t\tthrow new Error(`Unhandled stop reason: ${reason}`);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-shared.d.ts","sourceRoot":"","sources":["../../src/providers/google-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAgB,KAAK,EAAE,UAAU,EAAe,IAAI,EAAE,MAAM,aAAa,CAAC;AAI/F,KAAK,aAAa,GAAG,sBAAsB,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAEpF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAC,GAAG,OAAO,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrH;AAuBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAsJrG;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,IAAI,EAAE,EACb,aAAa,UAAQ,GACnB;IAAE,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,EAAE,GAAG,SAAS,CAWnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,yBAAyB,CAWvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA2B9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAS9D","sourcesContent":["/**\n * Shared utilities for Google Generative AI and Google Cloud Code Assist providers.\n */\n\nimport { type Content, FinishReason, FunctionCallingConfigMode, type Part } from \"@google/genai\";\nimport type { Context, ImageContent, Model, StopReason, TextContent, Tool } from \"../types.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\ntype GoogleApiType = \"google-generative-ai\" | \"google-gemini-cli\" | \"google-vertex\";\n\n/**\n * Determines whether a streamed Gemini `Part` should be treated as \"thinking\".\n *\n * Protocol note (Gemini / Vertex AI thought signatures):\n * - `thought: true` is the definitive marker for thinking content (thought summaries).\n * - `thoughtSignature` is an encrypted representation of the model's internal thought process\n * used to preserve reasoning context across multi-turn interactions.\n * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT\n * indicate the part itself is thinking content.\n * - For non-functionCall responses, the signature appears on the last part for context replay.\n * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;\n * do not merge/move signatures across parts.\n *\n * See: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nexport function isThinkingPart(part: Pick<Part, \"thought\" | \"thoughtSignature\">): boolean {\n\treturn part.thought === true;\n}\n\n/**\n * Retain thought signatures during streaming.\n *\n * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.\n * This helper preserves the last non-empty signature for the current block.\n *\n * Note: this does NOT merge or move signatures across distinct response parts. It only prevents\n * a signature from being overwritten with `undefined` within the same streamed block.\n */\nexport function retainThoughtSignature(existing: string | undefined, incoming: string | undefined): string | undefined {\n\tif (typeof incoming === \"string\" && incoming.length > 0) return incoming;\n\treturn existing;\n}\n\n// Thought signatures must be base64 for Google APIs (TYPE_BYTES).\nconst base64SignaturePattern = /^[A-Za-z0-9+/]+={0,2}$/;\n\n// Sentinel value that tells the Gemini API to skip thought signature validation.\n// Used for unsigned function call parts (e.g. replayed from providers without thought signatures).\n// See: https://ai.google.dev/gemini-api/docs/thought-signatures\nconst SKIP_THOUGHT_SIGNATURE = \"skip_thought_signature_validator\";\n\nfunction isValidThoughtSignature(signature: string | undefined): boolean {\n\tif (!signature) return false;\n\tif (signature.length % 4 !== 0) return false;\n\treturn base64SignaturePattern.test(signature);\n}\n\n/**\n * Only keep signatures from the same provider/model and with valid base64.\n */\nfunction resolveThoughtSignature(isSameProviderAndModel: boolean, signature: string | undefined): string | undefined {\n\treturn isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : undefined;\n}\n\n/**\n * Models via Google APIs that require explicit tool call IDs in function calls/responses.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n\treturn modelId.startsWith(\"claude-\") || modelId.startsWith(\"gpt-oss-\");\n}\n\nfunction getGeminiMajorVersion(modelId: string): number | undefined {\n\tconst match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\\d+)/);\n\tif (!match) return undefined;\n\treturn Number.parseInt(match[1], 10);\n}\n\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\tif (geminiMajorVersion !== undefined) {\n\t\treturn geminiMajorVersion >= 3;\n\t}\n\treturn true;\n}\n\n/**\n * Convert internal messages to Gemini Content[] format.\n */\nexport function convertMessages<T extends GoogleApiType>(model: Model<T>, context: Context): Content[] {\n\tconst contents: Content[] = [];\n\tconst normalizeToolCallId = (id: string): string => {\n\t\tif (!requiresToolCallId(model.id)) return id;\n\t\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n\t};\n\n\tconst transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);\n\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst parts: Part[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn { text: sanitizeSurrogates(item.text) };\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tinlineData: {\n\t\t\t\t\t\t\t\tmimeType: item.mimeType,\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst filteredParts = !model.input.includes(\"image\") ? parts.filter((p) => p.text !== undefined) : parts;\n\t\t\t\tif (filteredParts.length === 0) continue;\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: filteredParts,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst parts: Part[] = [];\n\t\t\t// Check if message is from same provider and model - only then keep thinking blocks\n\t\t\tconst isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t// Skip empty text blocks - they can cause issues with some models (e.g. Claude via Antigravity)\n\t\t\t\t\tif (!block.text || block.text.trim() === \"\") continue;\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);\n\t\t\t\t\tparts.push({\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Skip empty thinking blocks\n\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") continue;\n\t\t\t\t\t// Only keep as thinking block if same provider AND same model\n\t\t\t\t\t// Otherwise convert to plain text (no tags to avoid model mimicking them)\n\t\t\t\t\tif (isSameProviderAndModel) {\n\t\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\tthought: true,\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);\n\t\t\t\t\t// Gemini 3 requires thoughtSignature on all function calls when thinking mode is enabled.\n\t\t\t\t\t// Use the skip_thought_signature_validator sentinel for unsigned function calls\n\t\t\t\t\t// (e.g. replayed from providers without thought signatures like Claude via Antigravity).\n\t\t\t\t\tconst isGemini3 = model.id.toLowerCase().includes(\"gemini-3\");\n\t\t\t\t\tconst effectiveSignature = thoughtSignature || (isGemini3 ? SKIP_THOUGHT_SIGNATURE : undefined);\n\t\t\t\t\tconst part: Part = {\n\t\t\t\t\t\tfunctionCall: {\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\targs: block.arguments ?? {},\n\t\t\t\t\t\t\t...(requiresToolCallId(model.id) ? { id: block.id } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...(effectiveSignature && { thoughtSignature: effectiveSignature }),\n\t\t\t\t\t};\n\t\t\t\t\tparts.push(part);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (parts.length === 0) continue;\n\t\t\tcontents.push({\n\t\t\t\trole: \"model\",\n\t\t\t\tparts,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Extract text and image content\n\t\t\tconst textContent = msg.content.filter((c): c is TextContent => c.type === \"text\");\n\t\t\tconst textResult = textContent.map((c) => c.text).join(\"\\n\");\n\t\t\tconst imageContent = model.input.includes(\"image\")\n\t\t\t\t? msg.content.filter((c): c is ImageContent => c.type === \"image\")\n\t\t\t\t: [];\n\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst hasImages = imageContent.length > 0;\n\n\t\t\t// Gemini 3+ models support multimodal function responses with images nested inside\n\t\t\t// functionResponse.parts. Claude and other non-Gemini models behind Cloud Code Assist /\n\t\t\t// Antigravity also accept this shape. Gemini < 3 still needs a separate user image turn.\n\t\t\tconst modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);\n\n\t\t\t// Use \"output\" key for success, \"error\" key for errors as per SDK documentation\n\t\t\tconst responseValue = hasText ? sanitizeSurrogates(textResult) : hasImages ? \"(see attached image)\" : \"\";\n\n\t\t\tconst imageParts: Part[] = imageContent.map((imageBlock) => ({\n\t\t\t\tinlineData: {\n\t\t\t\t\tmimeType: imageBlock.mimeType,\n\t\t\t\t\tdata: imageBlock.data,\n\t\t\t\t},\n\t\t\t}));\n\n\t\t\tconst includeId = requiresToolCallId(model.id);\n\t\t\tconst functionResponsePart: Part = {\n\t\t\t\tfunctionResponse: {\n\t\t\t\t\tname: msg.toolName,\n\t\t\t\t\tresponse: msg.isError ? { error: responseValue } : { output: responseValue },\n\t\t\t\t\t...(hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts }),\n\t\t\t\t\t...(includeId ? { id: msg.toolCallId } : {}),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Cloud Code Assist API requires all function responses to be in a single user turn.\n\t\t\t// Check if the last content is already a user turn with function responses and merge.\n\t\t\tconst lastContent = contents[contents.length - 1];\n\t\t\tif (lastContent?.role === \"user\" && lastContent.parts?.some((p) => p.functionResponse)) {\n\t\t\t\tlastContent.parts.push(functionResponsePart);\n\t\t\t} else {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [functionResponsePart],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// For Gemini < 3, add images in a separate user message\n\t\t\tif (hasImages && !modelSupportsMultimodalFunctionResponse) {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: \"Tool result image:\" }, ...imageParts],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn contents;\n}\n\n/**\n * Convert tools to Gemini function declarations format.\n *\n * By default uses `parametersJsonSchema` which supports full JSON Schema (including\n * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`\n * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude\n * models, where the API translates `parameters` into Anthropic's `input_schema`.\n */\nexport function convertTools(\n\ttools: Tool[],\n\tuseParameters = false,\n): { functionDeclarations: Record<string, unknown>[] }[] | undefined {\n\tif (tools.length === 0) return undefined;\n\treturn [\n\t\t{\n\t\t\tfunctionDeclarations: tools.map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\t...(useParameters ? { parameters: tool.parameters } : { parametersJsonSchema: tool.parameters }),\n\t\t\t})),\n\t\t},\n\t];\n}\n\n/**\n * Map tool choice string to Gemini FunctionCallingConfigMode.\n */\nexport function mapToolChoice(choice: string): FunctionCallingConfigMode {\n\tswitch (choice) {\n\t\tcase \"auto\":\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t\tcase \"none\":\n\t\t\treturn FunctionCallingConfigMode.NONE;\n\t\tcase \"any\":\n\t\t\treturn FunctionCallingConfigMode.ANY;\n\t\tdefault:\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t}\n}\n\n/**\n * Map Gemini FinishReason to our StopReason.\n */\nexport function mapStopReason(reason: FinishReason): StopReason {\n\tswitch (reason) {\n\t\tcase FinishReason.STOP:\n\t\t\treturn \"stop\";\n\t\tcase FinishReason.MAX_TOKENS:\n\t\t\treturn \"length\";\n\t\tcase FinishReason.BLOCKLIST:\n\t\tcase FinishReason.PROHIBITED_CONTENT:\n\t\tcase FinishReason.SPII:\n\t\tcase FinishReason.SAFETY:\n\t\tcase FinishReason.IMAGE_SAFETY:\n\t\tcase FinishReason.IMAGE_PROHIBITED_CONTENT:\n\t\tcase FinishReason.IMAGE_RECITATION:\n\t\tcase FinishReason.IMAGE_OTHER:\n\t\tcase FinishReason.RECITATION:\n\t\tcase FinishReason.FINISH_REASON_UNSPECIFIED:\n\t\tcase FinishReason.OTHER:\n\t\tcase FinishReason.LANGUAGE:\n\t\tcase FinishReason.MALFORMED_FUNCTION_CALL:\n\t\tcase FinishReason.UNEXPECTED_TOOL_CALL:\n\t\tcase FinishReason.NO_IMAGE:\n\t\t\treturn \"error\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = reason;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Map string finish reason to our StopReason (for raw API responses).\n */\nexport function mapStopReasonString(reason: string): StopReason {\n\tswitch (reason) {\n\t\tcase \"STOP\":\n\t\t\treturn \"stop\";\n\t\tcase \"MAX_TOKENS\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"error\";\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-shared.d.ts","sourceRoot":"","sources":["../../src/providers/google-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAgB,KAAK,EAAE,UAAU,EAAe,IAAI,EAAE,MAAM,aAAa,CAAC;AAI/F,KAAK,aAAa,GAAG,sBAAsB,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAEpF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAC,GAAG,OAAO,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrH;AAuBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAqJrG;AA6BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,IAAI,EAAE,EACb,aAAa,UAAQ,GACnB;IAAE,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,EAAE,GAAG,SAAS,CAanE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,yBAAyB,CAWvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA2B9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAS9D","sourcesContent":["/**\n * Shared utilities for Google Generative AI and Google Cloud Code Assist providers.\n */\n\nimport { type Content, FinishReason, FunctionCallingConfigMode, type Part } from \"@google/genai\";\nimport type { Context, ImageContent, Model, StopReason, TextContent, Tool } from \"../types.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\nimport { transformMessages } from \"./transform-messages.js\";\n\ntype GoogleApiType = \"google-generative-ai\" | \"google-gemini-cli\" | \"google-vertex\";\n\n/**\n * Determines whether a streamed Gemini `Part` should be treated as \"thinking\".\n *\n * Protocol note (Gemini / Vertex AI thought signatures):\n * - `thought: true` is the definitive marker for thinking content (thought summaries).\n * - `thoughtSignature` is an encrypted representation of the model's internal thought process\n * used to preserve reasoning context across multi-turn interactions.\n * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT\n * indicate the part itself is thinking content.\n * - For non-functionCall responses, the signature appears on the last part for context replay.\n * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;\n * do not merge/move signatures across parts.\n *\n * See: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nexport function isThinkingPart(part: Pick<Part, \"thought\" | \"thoughtSignature\">): boolean {\n\treturn part.thought === true;\n}\n\n/**\n * Retain thought signatures during streaming.\n *\n * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.\n * This helper preserves the last non-empty signature for the current block.\n *\n * Note: this does NOT merge or move signatures across distinct response parts. It only prevents\n * a signature from being overwritten with `undefined` within the same streamed block.\n */\nexport function retainThoughtSignature(existing: string | undefined, incoming: string | undefined): string | undefined {\n\tif (typeof incoming === \"string\" && incoming.length > 0) return incoming;\n\treturn existing;\n}\n\n// Thought signatures must be base64 for Google APIs (TYPE_BYTES).\nconst base64SignaturePattern = /^[A-Za-z0-9+/]+={0,2}$/;\n\n// Sentinel value that tells the Gemini API to skip thought signature validation.\n// Used for unsigned function call parts (e.g. replayed from providers without thought signatures).\n// See: https://ai.google.dev/gemini-api/docs/thought-signatures\nconst SKIP_THOUGHT_SIGNATURE = \"skip_thought_signature_validator\";\n\nfunction isValidThoughtSignature(signature: string | undefined): boolean {\n\tif (!signature) return false;\n\tif (signature.length % 4 !== 0) return false;\n\treturn base64SignaturePattern.test(signature);\n}\n\n/**\n * Only keep signatures from the same provider/model and with valid base64.\n */\nfunction resolveThoughtSignature(isSameProviderAndModel: boolean, signature: string | undefined): string | undefined {\n\treturn isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : undefined;\n}\n\n/**\n * Models via Google APIs that require explicit tool call IDs in function calls/responses.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n\treturn modelId.startsWith(\"claude-\") || modelId.startsWith(\"gpt-oss-\");\n}\n\nfunction getGeminiMajorVersion(modelId: string): number | undefined {\n\tconst match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\\d+)/);\n\tif (!match) return undefined;\n\treturn Number.parseInt(match[1], 10);\n}\n\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\tif (geminiMajorVersion !== undefined) {\n\t\treturn geminiMajorVersion >= 3;\n\t}\n\treturn true;\n}\n\n/**\n * Convert internal messages to Gemini Content[] format.\n */\nexport function convertMessages<T extends GoogleApiType>(model: Model<T>, context: Context): Content[] {\n\tconst contents: Content[] = [];\n\tconst normalizeToolCallId = (id: string): string => {\n\t\tif (!requiresToolCallId(model.id)) return id;\n\t\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n\t};\n\n\tconst transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);\n\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst parts: Part[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn { text: sanitizeSurrogates(item.text) };\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tinlineData: {\n\t\t\t\t\t\t\t\tmimeType: item.mimeType,\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (parts.length === 0) continue;\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst parts: Part[] = [];\n\t\t\t// Check if message is from same provider and model - only then keep thinking blocks\n\t\t\tconst isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\t// Skip empty text blocks - they can cause issues with some models (e.g. Claude via Antigravity)\n\t\t\t\t\tif (!block.text || block.text.trim() === \"\") continue;\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);\n\t\t\t\t\tparts.push({\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Skip empty thinking blocks\n\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") continue;\n\t\t\t\t\t// Only keep as thinking block if same provider AND same model\n\t\t\t\t\t// Otherwise convert to plain text (no tags to avoid model mimicking them)\n\t\t\t\t\tif (isSameProviderAndModel) {\n\t\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\tthought: true,\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);\n\t\t\t\t\t// Gemini 3 requires thoughtSignature on all function calls when thinking mode is enabled.\n\t\t\t\t\t// Use the skip_thought_signature_validator sentinel for unsigned function calls\n\t\t\t\t\t// (e.g. replayed from providers without thought signatures like Claude via Antigravity).\n\t\t\t\t\tconst isGemini3 = model.id.toLowerCase().includes(\"gemini-3\");\n\t\t\t\t\tconst effectiveSignature = thoughtSignature || (isGemini3 ? SKIP_THOUGHT_SIGNATURE : undefined);\n\t\t\t\t\tconst part: Part = {\n\t\t\t\t\t\tfunctionCall: {\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\targs: block.arguments ?? {},\n\t\t\t\t\t\t\t...(requiresToolCallId(model.id) ? { id: block.id } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...(effectiveSignature && { thoughtSignature: effectiveSignature }),\n\t\t\t\t\t};\n\t\t\t\t\tparts.push(part);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (parts.length === 0) continue;\n\t\t\tcontents.push({\n\t\t\t\trole: \"model\",\n\t\t\t\tparts,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Extract text and image content\n\t\t\tconst textContent = msg.content.filter((c): c is TextContent => c.type === \"text\");\n\t\t\tconst textResult = textContent.map((c) => c.text).join(\"\\n\");\n\t\t\tconst imageContent = model.input.includes(\"image\")\n\t\t\t\t? msg.content.filter((c): c is ImageContent => c.type === \"image\")\n\t\t\t\t: [];\n\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst hasImages = imageContent.length > 0;\n\n\t\t\t// Gemini 3+ models support multimodal function responses with images nested inside\n\t\t\t// functionResponse.parts. Claude and other non-Gemini models behind Cloud Code Assist /\n\t\t\t// Antigravity also accept this shape. Gemini < 3 still needs a separate user image turn.\n\t\t\tconst modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);\n\n\t\t\t// Use \"output\" key for success, \"error\" key for errors as per SDK documentation\n\t\t\tconst responseValue = hasText ? sanitizeSurrogates(textResult) : hasImages ? \"(see attached image)\" : \"\";\n\n\t\t\tconst imageParts: Part[] = imageContent.map((imageBlock) => ({\n\t\t\t\tinlineData: {\n\t\t\t\t\tmimeType: imageBlock.mimeType,\n\t\t\t\t\tdata: imageBlock.data,\n\t\t\t\t},\n\t\t\t}));\n\n\t\t\tconst includeId = requiresToolCallId(model.id);\n\t\t\tconst functionResponsePart: Part = {\n\t\t\t\tfunctionResponse: {\n\t\t\t\t\tname: msg.toolName,\n\t\t\t\t\tresponse: msg.isError ? { error: responseValue } : { output: responseValue },\n\t\t\t\t\t...(hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts }),\n\t\t\t\t\t...(includeId ? { id: msg.toolCallId } : {}),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Cloud Code Assist API requires all function responses to be in a single user turn.\n\t\t\t// Check if the last content is already a user turn with function responses and merge.\n\t\t\tconst lastContent = contents[contents.length - 1];\n\t\t\tif (lastContent?.role === \"user\" && lastContent.parts?.some((p) => p.functionResponse)) {\n\t\t\t\tlastContent.parts.push(functionResponsePart);\n\t\t\t} else {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [functionResponsePart],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// For Gemini < 3, add images in a separate user message\n\t\t\tif (hasImages && !modelSupportsMultimodalFunctionResponse) {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: \"Tool result image:\" }, ...imageParts],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn contents;\n}\n\nconst JSON_SCHEMA_META_DECLARATIONS = new Set([\n\t\"$schema\",\n\t\"$id\",\n\t\"$anchor\",\n\t\"$dynamicAnchor\",\n\t\"$vocabulary\",\n\t\"$comment\",\n\t\"$defs\",\n\t\"definitions\", // pre-draft-2019-09 equivalent of $defs\n]);\n\n/**\n * Strip meta-declarations from a schema obj\n */\nfunction sanitizeForOpenApi(schema: unknown): unknown {\n\tif (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n\t\treturn schema;\n\t}\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(schema)) {\n\t\tif (JSON_SCHEMA_META_DECLARATIONS.has(key)) continue;\n\t\tresult[key] = sanitizeForOpenApi(value);\n\t}\n\treturn result;\n}\n\n/**\n * Convert tools to Gemini function declarations format.\n *\n * By default uses `parametersJsonSchema` which supports full JSON Schema (including\n * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`\n * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude\n * models, where the API translates `parameters` into Anthropic's `input_schema`.\n */\nexport function convertTools(\n\ttools: Tool[],\n\tuseParameters = false,\n): { functionDeclarations: Record<string, unknown>[] }[] | undefined {\n\tif (tools.length === 0) return undefined;\n\treturn [\n\t\t{\n\t\t\tfunctionDeclarations: tools.map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\t...(useParameters\n\t\t\t\t\t? { parameters: sanitizeForOpenApi(tool.parameters as unknown) }\n\t\t\t\t\t: { parametersJsonSchema: tool.parameters }),\n\t\t\t})),\n\t\t},\n\t];\n}\n\n/**\n * Map tool choice string to Gemini FunctionCallingConfigMode.\n */\nexport function mapToolChoice(choice: string): FunctionCallingConfigMode {\n\tswitch (choice) {\n\t\tcase \"auto\":\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t\tcase \"none\":\n\t\t\treturn FunctionCallingConfigMode.NONE;\n\t\tcase \"any\":\n\t\t\treturn FunctionCallingConfigMode.ANY;\n\t\tdefault:\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t}\n}\n\n/**\n * Map Gemini FinishReason to our StopReason.\n */\nexport function mapStopReason(reason: FinishReason): StopReason {\n\tswitch (reason) {\n\t\tcase FinishReason.STOP:\n\t\t\treturn \"stop\";\n\t\tcase FinishReason.MAX_TOKENS:\n\t\t\treturn \"length\";\n\t\tcase FinishReason.BLOCKLIST:\n\t\tcase FinishReason.PROHIBITED_CONTENT:\n\t\tcase FinishReason.SPII:\n\t\tcase FinishReason.SAFETY:\n\t\tcase FinishReason.IMAGE_SAFETY:\n\t\tcase FinishReason.IMAGE_PROHIBITED_CONTENT:\n\t\tcase FinishReason.IMAGE_RECITATION:\n\t\tcase FinishReason.IMAGE_OTHER:\n\t\tcase FinishReason.RECITATION:\n\t\tcase FinishReason.FINISH_REASON_UNSPECIFIED:\n\t\tcase FinishReason.OTHER:\n\t\tcase FinishReason.LANGUAGE:\n\t\tcase FinishReason.MALFORMED_FUNCTION_CALL:\n\t\tcase FinishReason.UNEXPECTED_TOOL_CALL:\n\t\tcase FinishReason.NO_IMAGE:\n\t\t\treturn \"error\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = reason;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Map string finish reason to our StopReason (for raw API responses).\n */\nexport function mapStopReasonString(reason: string): StopReason {\n\tswitch (reason) {\n\t\tcase \"STOP\":\n\t\t\treturn \"stop\";\n\t\tcase \"MAX_TOKENS\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"error\";\n\t}\n}\n"]}
|