@bastani/pi-ai 0.9.20-alpha.2 → 0.9.20-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -1
- package/NOTICE.md +1 -1
- package/README.md +28 -5
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +167 -85
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +17 -5
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +15 -12
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +22 -80
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +13 -4
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +54 -4
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +25 -65
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +15 -11
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +20 -22
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts +6 -4
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +39 -57
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +7 -5
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +56 -56
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +14 -19
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/pi-messages.d.ts +3 -3
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +2 -2
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts +3 -3
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/transform-messages.d.ts.map +1 -1
- package/dist/api/transform-messages.js +21 -7
- package/dist/api/transform-messages.js.map +1 -1
- package/dist/auth/credential-store.d.ts.map +1 -1
- package/dist/auth/credential-store.js +3 -2
- package/dist/auth/credential-store.js.map +1 -1
- package/dist/auth/resolve.d.ts +4 -0
- package/dist/auth/resolve.d.ts.map +1 -1
- package/dist/auth/resolve.js +27 -8
- package/dist/auth/resolve.js.map +1 -1
- package/dist/compat.d.ts +3 -3
- package/dist/compat.d.ts.map +1 -1
- package/dist/compat.js +9 -6
- package/dist/compat.js.map +1 -1
- package/dist/env-api-keys.d.ts +2 -0
- package/dist/env-api-keys.d.ts.map +1 -1
- package/dist/env-api-keys.js +59 -43
- package/dist/env-api-keys.js.map +1 -1
- package/dist/image-models.generated.d.ts +30 -0
- package/dist/image-models.generated.d.ts.map +1 -1
- package/dist/image-models.generated.js +34 -4
- package/dist/image-models.generated.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +5 -4
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +2 -0
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +2 -0
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +6 -3
- package/dist/models.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.d.ts +1 -2
- package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/dist/providers/ant-ling.models.d.ts +1 -2
- package/dist/providers/ant-ling.models.d.ts.map +1 -1
- package/dist/providers/ant-ling.models.js.map +1 -1
- package/dist/providers/anthropic.models.d.ts +1 -2
- package/dist/providers/anthropic.models.d.ts.map +1 -1
- package/dist/providers/anthropic.models.js.map +1 -1
- package/dist/providers/azure-openai-responses.models.d.ts +1 -2
- package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
- package/dist/providers/azure-openai-responses.models.js.map +1 -1
- package/dist/providers/baseten.models.d.ts +1 -2
- package/dist/providers/baseten.models.d.ts.map +1 -1
- package/dist/providers/baseten.models.js.map +1 -1
- package/dist/providers/cerebras.models.d.ts +1 -2
- package/dist/providers/cerebras.models.d.ts.map +1 -1
- package/dist/providers/cerebras.models.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.d.ts +1 -2
- package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.d.ts +1 -2
- package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cerebras.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/deepseek.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.json +1 -1
- package/dist/providers/data/moonshotai.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -0
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/data/zai.json +1 -1
- package/dist/providers/deepseek.models.d.ts +1 -2
- package/dist/providers/deepseek.models.d.ts.map +1 -1
- package/dist/providers/deepseek.models.js.map +1 -1
- package/dist/providers/faux.d.ts +2 -2
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +11 -11
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/fireworks.models.d.ts +1 -2
- package/dist/providers/fireworks.models.d.ts.map +1 -1
- package/dist/providers/fireworks.models.js.map +1 -1
- package/dist/providers/github-copilot.models.d.ts +1 -2
- package/dist/providers/github-copilot.models.d.ts.map +1 -1
- package/dist/providers/github-copilot.models.js.map +1 -1
- package/dist/providers/google-vertex.models.d.ts +1 -2
- package/dist/providers/google-vertex.models.d.ts.map +1 -1
- package/dist/providers/google-vertex.models.js.map +1 -1
- package/dist/providers/google.models.d.ts +1 -2
- package/dist/providers/google.models.d.ts.map +1 -1
- package/dist/providers/google.models.js.map +1 -1
- package/dist/providers/groq.models.d.ts +1 -2
- package/dist/providers/groq.models.d.ts.map +1 -1
- package/dist/providers/groq.models.js.map +1 -1
- package/dist/providers/huggingface.models.d.ts +1 -2
- package/dist/providers/huggingface.models.d.ts.map +1 -1
- package/dist/providers/huggingface.models.js.map +1 -1
- package/dist/providers/kimi-coding.models.d.ts +1 -2
- package/dist/providers/kimi-coding.models.d.ts.map +1 -1
- package/dist/providers/kimi-coding.models.js.map +1 -1
- package/dist/providers/minimax-cn.models.d.ts +1 -2
- package/dist/providers/minimax-cn.models.d.ts.map +1 -1
- package/dist/providers/minimax-cn.models.js.map +1 -1
- package/dist/providers/minimax.models.d.ts +1 -2
- package/dist/providers/minimax.models.d.ts.map +1 -1
- package/dist/providers/minimax.models.js.map +1 -1
- package/dist/providers/mistral.models.d.ts +1 -2
- package/dist/providers/mistral.models.d.ts.map +1 -1
- package/dist/providers/mistral.models.js.map +1 -1
- package/dist/providers/moonshotai-cn.models.d.ts +1 -2
- package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
- package/dist/providers/moonshotai-cn.models.js.map +1 -1
- package/dist/providers/moonshotai.models.d.ts +1 -2
- package/dist/providers/moonshotai.models.d.ts.map +1 -1
- package/dist/providers/moonshotai.models.js.map +1 -1
- package/dist/providers/nvidia.models.d.ts +1 -2
- package/dist/providers/nvidia.models.d.ts.map +1 -1
- package/dist/providers/nvidia.models.js.map +1 -1
- package/dist/providers/openai-codex.models.d.ts +1 -2
- package/dist/providers/openai-codex.models.d.ts.map +1 -1
- package/dist/providers/openai-codex.models.js.map +1 -1
- package/dist/providers/openai.models.d.ts +1 -2
- package/dist/providers/openai.models.d.ts.map +1 -1
- package/dist/providers/openai.models.js.map +1 -1
- package/dist/providers/opencode-go.models.d.ts +1 -2
- package/dist/providers/opencode-go.models.d.ts.map +1 -1
- package/dist/providers/opencode-go.models.js.map +1 -1
- package/dist/providers/opencode.models.d.ts +1 -2
- package/dist/providers/opencode.models.d.ts.map +1 -1
- package/dist/providers/opencode.models.js.map +1 -1
- package/dist/providers/openrouter.models.d.ts +1 -2
- package/dist/providers/openrouter.models.d.ts.map +1 -1
- package/dist/providers/openrouter.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.d.ts +1 -2
- package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-individual.models.d.ts +1 -2
- package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
- package/dist/providers/qwen-token-plan.models.d.ts +1 -2
- package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan.models.js.map +1 -1
- package/dist/providers/radius.d.ts.map +1 -1
- package/dist/providers/radius.js +19 -5
- package/dist/providers/radius.js.map +1 -1
- package/dist/providers/radius.models.d.ts +3 -0
- package/dist/providers/radius.models.d.ts.map +1 -0
- package/dist/providers/radius.models.js +6 -0
- package/dist/providers/radius.models.js.map +1 -0
- package/dist/providers/together.models.d.ts +1 -2
- package/dist/providers/together.models.d.ts.map +1 -1
- package/dist/providers/together.models.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.d.ts +1 -2
- package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/dist/providers/xai.models.d.ts +1 -2
- package/dist/providers/xai.models.d.ts.map +1 -1
- package/dist/providers/xai.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts +1 -2
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts +1 -2
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +1 -2
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/dist/providers/xiaomi.models.d.ts +1 -2
- package/dist/providers/xiaomi.models.d.ts.map +1 -1
- package/dist/providers/xiaomi.models.js.map +1 -1
- package/dist/providers/zai-coding-cn.models.d.ts +1 -2
- package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
- package/dist/providers/zai-coding-cn.models.js.map +1 -1
- package/dist/providers/zai.models.d.ts +1 -2
- package/dist/providers/zai.models.d.ts.map +1 -1
- package/dist/providers/zai.models.js.map +1 -1
- package/dist/types.d.ts +95 -26
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/diagnostics.d.ts +3 -2
- package/dist/utils/diagnostics.d.ts.map +1 -1
- package/dist/utils/diagnostics.js.map +1 -1
- package/dist/utils/estimate.d.ts +2 -2
- package/dist/utils/estimate.d.ts.map +1 -1
- package/dist/utils/estimate.js +8 -29
- package/dist/utils/estimate.js.map +1 -1
- package/dist/utils/overflow.d.ts +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +17 -5
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +2 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/text.d.ts +9 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js +26 -0
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/transcript.d.ts +84 -0
- package/dist/utils/transcript.d.ts.map +1 -0
- package/dist/utils/transcript.js +204 -0
- package/dist/utils/transcript.js.map +1 -0
- package/package.json +3 -3
- package/dist/utils/deferred-tools.d.ts +0 -9
- package/dist/utils/deferred-tools.d.ts.map +0 -1
- package/dist/utils/deferred-tools.js +0 -36
- package/dist/utils/deferred-tools.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-vertex.js","sourceRoot":"","sources":["../../src/api/google-vertex.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype GenerateContentConfig,\n\ttype GenerateContentParameters,\n\tGoogleGenAI,\n\ttype HttpOptions,\n\tResourceScope,\n\ttype ThinkingConfig,\n\tThinkingLevel,\n} from \"@google/genai\";\nimport { calculateCost, clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tContext,\n\tModel,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingBudgets,\n\tThinkingContent,\n\tToolCall,\n} from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { providerHeadersToRecord } from \"../utils/headers.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport type { GoogleApiThinkingLevel, ResolvedGoogleThinkingLevel } from \"./google-shared.ts\";\nimport {\n\tconvertMessages,\n\tconvertTools,\n\tisThinkingPart,\n\tmapStopReason,\n\tresolveGoogleFunctionCallingMode,\n\tresolveGoogleThinkingLevel,\n\tretainThoughtSignature,\n\tretryGoogleRequest,\n\tsupportsGoogleStrictToolSampling,\n} from \"./google-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nexport interface GoogleVertexOptions extends StreamOptions {\n\ttoolChoice?: \"auto\" | \"none\" | \"any\";\n\tthinking?: {\n\t\tenabled: boolean;\n\t\tbudgetTokens?: number; // -1 for dynamic, 0 to disable\n\t\tlevel?: GoogleApiThinkingLevel;\n\t};\n\tproject?: string;\n\tlocation?: string;\n}\n\nconst API_VERSION = \"v1\";\nconst GCP_VERTEX_CREDENTIALS_MARKER = \"gcp-vertex-credentials\";\n\nconst THINKING_LEVEL_MAP: Record<GoogleApiThinkingLevel, ThinkingLevel> = {\n\tTHINKING_LEVEL_UNSPECIFIED: ThinkingLevel.THINKING_LEVEL_UNSPECIFIED,\n\tMINIMAL: ThinkingLevel.MINIMAL,\n\tLOW: ThinkingLevel.LOW,\n\tMEDIUM: ThinkingLevel.MEDIUM,\n\tHIGH: ThinkingLevel.HIGH,\n};\n\n// Counter for generating unique tool call IDs\nlet toolCallCounter = 0;\n\nexport const stream: StreamFunction<\"google-vertex\", GoogleVertexOptions> = (\n\tmodel: Model<\"google-vertex\">,\n\tcontext: Context,\n\toptions?: GoogleVertexOptions,\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: \"google-vertex\" 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: \"pending\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tif (options?.fetch && options.fetch !== globalThis.fetch) {\n\t\t\t\tthrow new Error(\"Custom fetch is not supported by the Google Vertex adapter\");\n\t\t\t}\n\t\t\tconst apiKey = resolveApiKey(options);\n\t\t\t// Create the client using either a Vertex API key, if provided, or ADC with project and location\n\t\t\tconst client = apiKey\n\t\t\t\t? createClientWithApiKey(model, apiKey, options?.headers)\n\t\t\t\t: createClient(model, resolveProject(options), resolveLocation(options), options?.headers, options?.env);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as GenerateContentParameters;\n\t\t\t}\n\t\t\tconst googleStream = await retryGoogleRequest(() => client.models.generateContentStream(params), options);\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\tlet currentBlock: TextContent | ThinkingContent | null = null;\n\t\t\tconst blocks = output.content;\n\t\t\tconst blockIndex = () => blocks.length - 1;\n\t\t\tfor await (const chunk of googleStream) {\n\t\t\t\t// Vertex uses the same @google/genai GenerateContentResponse type as Gemini.\n\t\t\t\t// responseId is documented there as an output-only identifier for each response.\n\t\t\t\toutput.responseId ||= chunk.responseId;\n\t\t\t\tconst candidate = chunk.candidates?.[0];\n\t\t\t\tif (candidate?.content?.parts) {\n\t\t\t\t\tfor (const part of candidate.content.parts) {\n\t\t\t\t\t\tif (part.text !== undefined) {\n\t\t\t\t\t\t\tconst isThinking = isThinkingPart(part);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!currentBlock ||\n\t\t\t\t\t\t\t\t(isThinking && currentBlock.type !== \"thinking\") ||\n\t\t\t\t\t\t\t\t(!isThinking && currentBlock.type !== \"text\")\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tif (currentBlock) {\n\t\t\t\t\t\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: blocks.length - 1,\n\t\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isThinking) {\n\t\t\t\t\t\t\t\t\tcurrentBlock = { type: \"thinking\", thinking: \"\", thinkingSignature: undefined };\n\t\t\t\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (currentBlock.type === \"thinking\") {\n\t\t\t\t\t\t\t\tcurrentBlock.thinking += part.text;\n\t\t\t\t\t\t\t\tcurrentBlock.thinkingSignature = retainThoughtSignature(\n\t\t\t\t\t\t\t\t\tcurrentBlock.thinkingSignature,\n\t\t\t\t\t\t\t\t\tpart.thoughtSignature,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\tdelta: part.text,\n\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrentBlock.text += part.text;\n\t\t\t\t\t\t\t\tcurrentBlock.textSignature = retainThoughtSignature(\n\t\t\t\t\t\t\t\t\tcurrentBlock.textSignature,\n\t\t\t\t\t\t\t\t\tpart.thoughtSignature,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\tdelta: part.text,\n\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (part.functionCall) {\n\t\t\t\t\t\t\tif (currentBlock) {\n\t\t\t\t\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcurrentBlock = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst providedId = part.functionCall.id;\n\t\t\t\t\t\t\tconst needsNewId =\n\t\t\t\t\t\t\t\t!providedId || output.content.some((b) => b.type === \"toolCall\" && b.id === providedId);\n\t\t\t\t\t\t\tconst toolCallId = needsNewId\n\t\t\t\t\t\t\t\t? `${part.functionCall.name}_${Date.now()}_${++toolCallCounter}`\n\t\t\t\t\t\t\t\t: providedId;\n\n\t\t\t\t\t\t\tconst toolCall: ToolCall = {\n\t\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\t\tid: toolCallId,\n\t\t\t\t\t\t\t\tname: part.functionCall.name || \"\",\n\t\t\t\t\t\t\t\targuments: (part.functionCall.args as Record<string, any>) ?? {},\n\t\t\t\t\t\t\t\t...(part.thoughtSignature && { thoughtSignature: part.thoughtSignature }),\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\toutput.content.push(toolCall);\n\t\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: blockIndex(), partial: output });\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: blockIndex(),\n\t\t\t\t\t\t\t\tdelta: JSON.stringify(toolCall.arguments),\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\tstream.push({ type: \"toolcall_end\", contentIndex: blockIndex(), toolCall, partial: output });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (candidate?.finishReason) {\n\t\t\t\t\toutput.rawStopReason = candidate.finishReason;\n\t\t\t\t\toutput.stopReason = mapStopReason(candidate.finishReason);\n\t\t\t\t\tif (output.content.some((b) => b.type === \"toolCall\") && output.stopReason === \"stop\") {\n\t\t\t\t\t\toutput.stopReason = \"toolUse\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (chunk.usageMetadata) {\n\t\t\t\t\toutput.usage = {\n\t\t\t\t\t\tinput:\n\t\t\t\t\t\t\t(chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),\n\t\t\t\t\t\toutput:\n\t\t\t\t\t\t\t(chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),\n\t\t\t\t\t\tcacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,\n\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\treasoning: chunk.usageMetadata.thoughtsTokenCount || 0,\n\t\t\t\t\t\ttotalTokens: chunk.usageMetadata.totalTokenCount || 0,\n\t\t\t\t\t\tcost: {\n\t\t\t\t\t\t\tinput: 0,\n\t\t\t\t\t\t\toutput: 0,\n\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentBlock) {\n\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\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 === \"pending\") {\n\t\t\t\tthrow new Error(\"Google Vertex stream ended without a finish reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tconst errorMessage = output.rawStopReason\n\t\t\t\t\t? `Provider stopped with: ${output.rawStopReason}`\n\t\t\t\t\t: \"An unknown error occurred\";\n\t\t\t\tthrow new Error(errorMessage);\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\t// Remove internal index property used during streaming\n\t\t\tfor (const block of output.content) {\n\t\t\t\tif (\"index\" in block) {\n\t\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatProviderError(normalizeProviderError(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\nexport const streamSimple: StreamFunction<\"google-vertex\", SimpleStreamOptions> = (\n\tmodel: Model<\"google-vertex\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, undefined),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies GoogleVertexOptions;\n\tif (!options?.reasoning) {\n\t\treturn stream(model, context, {\n\t\t\t...base,\n\t\t\tthinking: { enabled: false },\n\t\t} satisfies GoogleVertexOptions);\n\t}\n\n\tconst clampedReasoning = clampThinkingLevel(model, options.reasoning);\n\tconst resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);\n\tconst geminiModel = model as unknown as Model<\"google-generative-ai\">;\n\n\tif (isGemini3ProModel(geminiModel) || isGemini3FlashModel(geminiModel)) {\n\t\treturn stream(model, context, {\n\t\t\t...base,\n\t\t\tthinking: {\n\t\t\t\tenabled: true,\n\t\t\t\tlevel: getGemini3ThinkingLevel(resolvedLevel, geminiModel),\n\t\t\t},\n\t\t} satisfies GoogleVertexOptions);\n\t}\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\tthinking: {\n\t\t\tenabled: true,\n\t\t\tbudgetTokens: getGoogleBudget(geminiModel, resolvedLevel, options.thinkingBudgets),\n\t\t},\n\t} satisfies GoogleVertexOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"google-vertex\">,\n\tproject: string,\n\tlocation: string,\n\toptionsHeaders?: ProviderHeaders,\n\tenv?: ProviderEnv,\n): GoogleGenAI {\n\tconst googleAuthOptions = buildGoogleAuthOptions(env);\n\treturn new GoogleGenAI({\n\t\tvertexai: true,\n\t\tproject,\n\t\tlocation,\n\t\tapiVersion: API_VERSION,\n\t\t...(googleAuthOptions ? { googleAuthOptions } : {}),\n\t\thttpOptions: buildHttpOptions(model, optionsHeaders),\n\t});\n}\n\nfunction createClientWithApiKey(\n\tmodel: Model<\"google-vertex\">,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n): GoogleGenAI {\n\treturn new GoogleGenAI({\n\t\tvertexai: true,\n\t\tapiKey,\n\t\tapiVersion: API_VERSION,\n\t\thttpOptions: buildHttpOptions(model, optionsHeaders),\n\t});\n}\n\nfunction buildHttpOptions(model: Model<\"google-vertex\">, optionsHeaders?: ProviderHeaders): HttpOptions | undefined {\n\tconst httpOptions: HttpOptions = {};\n\tconst baseUrl = resolveCustomBaseUrl(model.baseUrl);\n\tif (baseUrl) {\n\t\thttpOptions.baseUrl = baseUrl;\n\t\thttpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;\n\t\tif (baseUrlIncludesApiVersion(baseUrl)) {\n\t\t\thttpOptions.apiVersion = \"\";\n\t\t}\n\t}\n\n\tconst headers = providerHeadersToRecord({ \"User-Agent\": getPiUserAgent(), ...model.headers, ...optionsHeaders });\n\tif (headers) {\n\t\thttpOptions.headers = headers;\n\t}\n\n\treturn Object.keys(httpOptions).length > 0 ? httpOptions : undefined;\n}\n\nfunction resolveCustomBaseUrl(baseUrl: string): string | undefined {\n\tconst trimmed = baseUrl.trim();\n\tif (!trimmed || trimmed.includes(\"{location}\")) {\n\t\treturn undefined;\n\t}\n\treturn trimmed;\n}\n\nfunction baseUrlIncludesApiVersion(baseUrl: string): boolean {\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\t\treturn url.pathname.split(\"/\").some((part) => /^v\\d+(?:beta\\d*)?$/.test(part));\n\t} catch {\n\t\treturn /(?:^|\\/)v\\d+(?:beta\\d*)?(?:\\/|$)/.test(baseUrl);\n\t}\n}\n\nfunction buildGoogleAuthOptions(env?: ProviderEnv): { keyFilename: string } | undefined {\n\tconst keyFilename = getProviderEnvValue(\"GOOGLE_APPLICATION_CREDENTIALS\", env);\n\treturn keyFilename ? { keyFilename } : undefined;\n}\n\nfunction resolveApiKey(options?: GoogleVertexOptions): string | undefined {\n\tconst apiKey = options?.apiKey?.trim();\n\tif (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) {\n\t\treturn undefined;\n\t}\n\treturn apiKey;\n}\n\nfunction isPlaceholderApiKey(apiKey: string): boolean {\n\treturn /^<[^>]+>$/.test(apiKey);\n}\n\nfunction resolveProject(options?: GoogleVertexOptions): string {\n\tconst project =\n\t\toptions?.project ||\n\t\tgetProviderEnvValue(\"GOOGLE_CLOUD_PROJECT\", options?.env) ||\n\t\tgetProviderEnvValue(\"GCLOUD_PROJECT\", options?.env);\n\tif (!project) {\n\t\tthrow new Error(\n\t\t\t\"Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.\",\n\t\t);\n\t}\n\treturn project;\n}\n\nfunction resolveLocation(options?: GoogleVertexOptions): string {\n\tconst location = options?.location || getProviderEnvValue(\"GOOGLE_CLOUD_LOCATION\", options?.env);\n\tif (!location) {\n\t\tthrow new Error(\"Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.\");\n\t}\n\treturn location;\n}\n\nfunction buildParams(\n\tmodel: Model<\"google-vertex\">,\n\tcontext: Context,\n\toptions: GoogleVertexOptions = {},\n): GenerateContentParameters {\n\tconst contents = convertMessages(model, context);\n\n\tconst generationConfig: GenerateContentConfig = {};\n\tif (options.temperature !== undefined) {\n\t\tgenerationConfig.temperature = options.temperature;\n\t}\n\tif (options.maxTokens !== undefined) {\n\t\tgenerationConfig.maxOutputTokens = options.maxTokens;\n\t}\n\n\tconst supportsStrictMode = supportsGoogleStrictToolSampling(model.id);\n\tconst functionCallingMode = context.tools?.length\n\t\t? resolveGoogleFunctionCallingMode(context.tools, options.toolChoice, supportsStrictMode)\n\t\t: undefined;\n\tconst config: GenerateContentConfig = {\n\t\t...(Object.keys(generationConfig).length > 0 && generationConfig),\n\t\t...(context.systemPrompt && { systemInstruction: sanitizeSurrogates(context.systemPrompt) }),\n\t\t...(context.tools &&\n\t\t\tcontext.tools.length > 0 && {\n\t\t\t\ttools: convertTools(context.tools, false, supportsStrictMode),\n\t\t\t}),\n\t\t...(functionCallingMode !== undefined && {\n\t\t\ttoolConfig: { functionCallingConfig: { mode: functionCallingMode } },\n\t\t}),\n\t};\n\n\tif (options.thinking?.enabled && model.reasoning) {\n\t\tconst thinkingConfig: ThinkingConfig = { includeThoughts: true };\n\t\tif (options.thinking.level !== undefined) {\n\t\t\tthinkingConfig.thinkingLevel = THINKING_LEVEL_MAP[options.thinking.level];\n\t\t} else if (options.thinking.budgetTokens !== undefined) {\n\t\t\tthinkingConfig.thinkingBudget = options.thinking.budgetTokens;\n\t\t}\n\t\tconfig.thinkingConfig = thinkingConfig;\n\t} else if (model.reasoning && options.thinking && !options.thinking.enabled) {\n\t\tconfig.thinkingConfig = getDisabledThinkingConfig(model);\n\t}\n\n\tif (options.signal) {\n\t\tif (options.signal.aborted) {\n\t\t\tthrow new Error(\"Request aborted\");\n\t\t}\n\t\tconfig.abortSignal = options.signal;\n\t}\n\n\tconst params: GenerateContentParameters = {\n\t\tmodel: model.id,\n\t\tcontents,\n\t\tconfig,\n\t};\n\n\treturn params;\n}\n\nfunction isGemini3ProModel(model: Model<\"google-generative-ai\">): boolean {\n\treturn /gemini-3(?:\\.\\d+)?-pro/.test(model.id.toLowerCase());\n}\n\nfunction isGemini3FlashModel(model: Model<\"google-generative-ai\">): boolean {\n\tconst id = model.id.toLowerCase();\n\treturn /gemini-3(?:\\.\\d+)?-flash/.test(id) || id === \"gemini-flash-latest\" || id === \"gemini-flash-lite-latest\";\n}\n\nfunction getDisabledThinkingConfig(model: Model<\"google-vertex\">): ThinkingConfig {\n\t// Google docs: Gemini 3.1 Pro cannot disable thinking, and Gemini 3 Flash / Flash-Lite\n\t// do not support full thinking-off either. For Gemini 3 models, use the lowest supported\n\t// thinkingLevel without includeThoughts so hidden thinking remains invisible to pi.\n\tconst geminiModel = model as unknown as Model<\"google-generative-ai\">;\n\tif (isGemini3ProModel(geminiModel)) {\n\t\treturn { thinkingLevel: ThinkingLevel.LOW };\n\t}\n\tif (isGemini3FlashModel(geminiModel)) {\n\t\treturn { thinkingLevel: ThinkingLevel.MINIMAL };\n\t}\n\n\t// Gemini 2.x supports disabling via thinkingBudget = 0.\n\treturn { thinkingBudget: 0 };\n}\n\nfunction getGemini3ThinkingLevel(\n\teffort: ResolvedGoogleThinkingLevel,\n\tmodel: Model<\"google-generative-ai\">,\n): GoogleApiThinkingLevel {\n\tif (isGemini3ProModel(model)) {\n\t\tswitch (effort) {\n\t\t\tcase \"minimal\":\n\t\t\tcase \"low\":\n\t\t\t\treturn \"LOW\";\n\t\t\tcase \"medium\":\n\t\t\tcase \"high\":\n\t\t\t\treturn \"HIGH\";\n\t\t}\n\t}\n\tswitch (effort) {\n\t\tcase \"minimal\":\n\t\t\treturn \"MINIMAL\";\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}\n}\n\nfunction getGoogleBudget(\n\tmodel: Model<\"google-generative-ai\">,\n\tlevel: ResolvedGoogleThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): number {\n\tif (customBudgets?.[level] !== undefined) {\n\t\treturn customBudgets[level]!;\n\t}\n\n\tif (model.id.includes(\"2.5-pro\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 32768,\n\t\t};\n\t\treturn budgets[level];\n\t}\n\n\tif (model.id.includes(\"2.5-flash\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 24576,\n\t\t};\n\t\treturn budgets[level];\n\t}\n\n\treturn -1;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-vertex.js","sourceRoot":"","sources":["../../src/api/google-vertex.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype GenerateContentConfig,\n\ttype GenerateContentParameters,\n\tGoogleGenAI,\n\ttype HttpOptions,\n\tResourceScope,\n\ttype ThinkingConfig,\n} from \"@google/genai\";\nimport { calculateCost, clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tModel,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingBudgets,\n\tThinkingContent,\n\tToolCall,\n\tTranscriptContext,\n} from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { providerHeadersToRecord } from \"../utils/headers.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { getSystemMessageText } from \"../utils/text.ts\";\nimport { collapseSystemMessages, getCurrentTools, getInitialSystemMessage } from \"../utils/transcript.ts\";\nimport type { GoogleApiThinkingLevel, ResolvedGoogleThinkingLevel } from \"./google-shared.ts\";\nimport {\n\tconvertMessages,\n\tconvertTools,\n\tgetDisabledGoogleThinkingConfig,\n\tisThinkingPart,\n\tmapStopReason,\n\tresolveGoogleFunctionCallingMode,\n\tresolveGoogleThinkingLevel,\n\tretainThoughtSignature,\n\tretryGoogleRequest,\n\tsupportsGoogleStrictToolSampling,\n\ttoGoogleSdkThinkingLevel,\n\ttoGoogleThinkingLevel,\n\tusesGoogleThinkingLevel,\n} from \"./google-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nexport interface GoogleVertexOptions extends StreamOptions {\n\ttoolChoice?: \"auto\" | \"none\" | \"any\";\n\tthinking?: {\n\t\tenabled: boolean;\n\t\tbudgetTokens?: number; // -1 for dynamic, 0 to disable\n\t\tlevel?: GoogleApiThinkingLevel;\n\t};\n\tproject?: string;\n\tlocation?: string;\n}\n\nconst API_VERSION = \"v1\";\nconst GCP_VERTEX_CREDENTIALS_MARKER = \"gcp-vertex-credentials\";\n\n// Counter for generating unique tool call IDs\nlet toolCallCounter = 0;\n\nexport const stream: StreamFunction<\"google-vertex\", GoogleVertexOptions> = (\n\tmodel: Model<\"google-vertex\">,\n\tcontext: TranscriptContext,\n\toptions?: GoogleVertexOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst normalizedContext = collapseSystemMessages(context);\n\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: \"google-vertex\" 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: \"pending\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\tif (options?.fetch && options.fetch !== globalThis.fetch) {\n\t\t\t\tthrow new Error(\"Custom fetch is not supported by the Google Vertex adapter\");\n\t\t\t}\n\t\t\tconst apiKey = resolveApiKey(options);\n\t\t\t// Create the client using either a Vertex API key, if provided, or ADC with project and location\n\t\t\tconst client = apiKey\n\t\t\t\t? createClientWithApiKey(model, apiKey, options?.headers)\n\t\t\t\t: createClient(model, resolveProject(options), resolveLocation(options), options?.headers, options?.env);\n\t\t\tlet params = buildParams(model, normalizedContext, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as GenerateContentParameters;\n\t\t\t}\n\t\t\tconst googleStream = await retryGoogleRequest(() => client.models.generateContentStream(params), options);\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\tlet currentBlock: TextContent | ThinkingContent | null = null;\n\t\t\tconst blocks = output.content;\n\t\t\tconst blockIndex = () => blocks.length - 1;\n\t\t\tfor await (const chunk of googleStream) {\n\t\t\t\t// Vertex uses the same @google/genai GenerateContentResponse type as Gemini.\n\t\t\t\t// responseId is documented there as an output-only identifier for each response.\n\t\t\t\toutput.responseId ||= chunk.responseId;\n\t\t\t\tconst candidate = chunk.candidates?.[0];\n\t\t\t\tif (candidate?.content?.parts) {\n\t\t\t\t\tfor (const part of candidate.content.parts) {\n\t\t\t\t\t\tif (part.text !== undefined) {\n\t\t\t\t\t\t\tconst isThinking = isThinkingPart(part);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!currentBlock ||\n\t\t\t\t\t\t\t\t(isThinking && currentBlock.type !== \"thinking\") ||\n\t\t\t\t\t\t\t\t(!isThinking && currentBlock.type !== \"text\")\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tif (currentBlock) {\n\t\t\t\t\t\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: blocks.length - 1,\n\t\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isThinking) {\n\t\t\t\t\t\t\t\t\tcurrentBlock = { type: \"thinking\", thinking: \"\", thinkingSignature: undefined };\n\t\t\t\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (currentBlock.type === \"thinking\") {\n\t\t\t\t\t\t\t\tcurrentBlock.thinking += part.text;\n\t\t\t\t\t\t\t\tcurrentBlock.thinkingSignature = retainThoughtSignature(\n\t\t\t\t\t\t\t\t\tcurrentBlock.thinkingSignature,\n\t\t\t\t\t\t\t\t\tpart.thoughtSignature,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\tdelta: part.text,\n\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrentBlock.text += part.text;\n\t\t\t\t\t\t\t\tcurrentBlock.textSignature = retainThoughtSignature(\n\t\t\t\t\t\t\t\t\tcurrentBlock.textSignature,\n\t\t\t\t\t\t\t\t\tpart.thoughtSignature,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\tdelta: part.text,\n\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (part.functionCall) {\n\t\t\t\t\t\t\tif (currentBlock) {\n\t\t\t\t\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcurrentBlock = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst providedId = part.functionCall.id;\n\t\t\t\t\t\t\tconst needsNewId =\n\t\t\t\t\t\t\t\t!providedId || output.content.some((b) => b.type === \"toolCall\" && b.id === providedId);\n\t\t\t\t\t\t\tconst toolCallId = needsNewId\n\t\t\t\t\t\t\t\t? `${part.functionCall.name}_${Date.now()}_${++toolCallCounter}`\n\t\t\t\t\t\t\t\t: providedId;\n\n\t\t\t\t\t\t\tconst toolCall: ToolCall = {\n\t\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\t\tid: toolCallId,\n\t\t\t\t\t\t\t\tname: part.functionCall.name || \"\",\n\t\t\t\t\t\t\t\targuments: (part.functionCall.args as Record<string, any>) ?? {},\n\t\t\t\t\t\t\t\t...(part.thoughtSignature && { thoughtSignature: part.thoughtSignature }),\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\toutput.content.push(toolCall);\n\t\t\t\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: blockIndex(), partial: output });\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: blockIndex(),\n\t\t\t\t\t\t\t\tdelta: JSON.stringify(toolCall.arguments),\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\tstream.push({ type: \"toolcall_end\", contentIndex: blockIndex(), toolCall, partial: output });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (candidate?.finishReason) {\n\t\t\t\t\toutput.rawStopReason = candidate.finishReason;\n\t\t\t\t\toutput.stopReason = mapStopReason(candidate.finishReason);\n\t\t\t\t\tif (output.content.some((b) => b.type === \"toolCall\") && output.stopReason === \"stop\") {\n\t\t\t\t\t\toutput.stopReason = \"toolUse\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (chunk.usageMetadata) {\n\t\t\t\t\toutput.usage = {\n\t\t\t\t\t\tinput:\n\t\t\t\t\t\t\t(chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),\n\t\t\t\t\t\toutput:\n\t\t\t\t\t\t\t(chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),\n\t\t\t\t\t\tcacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,\n\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\treasoning: chunk.usageMetadata.thoughtsTokenCount || 0,\n\t\t\t\t\t\ttotalTokens: chunk.usageMetadata.totalTokenCount || 0,\n\t\t\t\t\t\tcost: {\n\t\t\t\t\t\t\tinput: 0,\n\t\t\t\t\t\t\toutput: 0,\n\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tcalculateCost(model, output.usage);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentBlock) {\n\t\t\t\tif (currentBlock.type === \"text\") {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tcontent: currentBlock.text,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tcontent: currentBlock.thinking,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\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 === \"pending\") {\n\t\t\t\tthrow new Error(\"Google Vertex stream ended without a finish reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tconst errorMessage = output.rawStopReason\n\t\t\t\t\t? `Provider stopped with: ${output.rawStopReason}`\n\t\t\t\t\t: \"An unknown error occurred\";\n\t\t\t\tthrow new Error(errorMessage);\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\t// Remove internal index property used during streaming\n\t\t\tfor (const block of output.content) {\n\t\t\t\tif (\"index\" in block) {\n\t\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatProviderError(normalizeProviderError(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\nexport const streamSimple: StreamFunction<\"google-vertex\", SimpleStreamOptions> = (\n\tmodel: Model<\"google-vertex\">,\n\tcontext: TranscriptContext,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, undefined),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies GoogleVertexOptions;\n\tif (!options?.reasoning) {\n\t\treturn stream(model, context, {\n\t\t\t...base,\n\t\t\tthinking: { enabled: false },\n\t\t} satisfies GoogleVertexOptions);\n\t}\n\n\tconst clampedReasoning = clampThinkingLevel(model, options.reasoning);\n\tif (clampedReasoning === \"off\") {\n\t\treturn stream(model, context, {\n\t\t\t...base,\n\t\t\tthinking: { enabled: false },\n\t\t} satisfies GoogleVertexOptions);\n\t}\n\tconst resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);\n\n\tif (usesGoogleThinkingLevel(model)) {\n\t\treturn stream(model, context, {\n\t\t\t...base,\n\t\t\tthinking: {\n\t\t\t\tenabled: true,\n\t\t\t\tlevel: toGoogleThinkingLevel(resolvedLevel),\n\t\t\t},\n\t\t} satisfies GoogleVertexOptions);\n\t}\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\tthinking: {\n\t\t\tenabled: true,\n\t\t\tbudgetTokens: getGoogleBudget(model, resolvedLevel, options.thinkingBudgets),\n\t\t},\n\t} satisfies GoogleVertexOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"google-vertex\">,\n\tproject: string,\n\tlocation: string,\n\toptionsHeaders?: ProviderHeaders,\n\tenv?: ProviderEnv,\n): GoogleGenAI {\n\tconst googleAuthOptions = buildGoogleAuthOptions(env);\n\treturn new GoogleGenAI({\n\t\tvertexai: true,\n\t\tproject,\n\t\tlocation,\n\t\tapiVersion: API_VERSION,\n\t\t...(googleAuthOptions ? { googleAuthOptions } : {}),\n\t\thttpOptions: buildHttpOptions(model, optionsHeaders),\n\t});\n}\n\nfunction createClientWithApiKey(\n\tmodel: Model<\"google-vertex\">,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n): GoogleGenAI {\n\treturn new GoogleGenAI({\n\t\tvertexai: true,\n\t\tapiKey,\n\t\tapiVersion: API_VERSION,\n\t\thttpOptions: buildHttpOptions(model, optionsHeaders),\n\t});\n}\n\nfunction buildHttpOptions(model: Model<\"google-vertex\">, optionsHeaders?: ProviderHeaders): HttpOptions | undefined {\n\tconst httpOptions: HttpOptions = {};\n\tconst baseUrl = resolveCustomBaseUrl(model.baseUrl);\n\tif (baseUrl) {\n\t\thttpOptions.baseUrl = baseUrl;\n\t\thttpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;\n\t\tif (baseUrlIncludesApiVersion(baseUrl)) {\n\t\t\thttpOptions.apiVersion = \"\";\n\t\t}\n\t}\n\n\tconst headers = providerHeadersToRecord({ \"User-Agent\": getPiUserAgent(), ...model.headers, ...optionsHeaders });\n\tif (headers) {\n\t\thttpOptions.headers = headers;\n\t}\n\n\treturn Object.keys(httpOptions).length > 0 ? httpOptions : undefined;\n}\n\nfunction resolveCustomBaseUrl(baseUrl: string): string | undefined {\n\tconst trimmed = baseUrl.trim();\n\tif (!trimmed || trimmed.includes(\"{location}\")) {\n\t\treturn undefined;\n\t}\n\treturn trimmed;\n}\n\nfunction baseUrlIncludesApiVersion(baseUrl: string): boolean {\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\t\treturn url.pathname.split(\"/\").some((part) => /^v\\d+(?:beta\\d*)?$/.test(part));\n\t} catch {\n\t\treturn /(?:^|\\/)v\\d+(?:beta\\d*)?(?:\\/|$)/.test(baseUrl);\n\t}\n}\n\nfunction buildGoogleAuthOptions(env?: ProviderEnv): { keyFilename: string } | undefined {\n\tconst keyFilename = getProviderEnvValue(\"GOOGLE_APPLICATION_CREDENTIALS\", env);\n\treturn keyFilename ? { keyFilename } : undefined;\n}\n\nfunction resolveApiKey(options?: GoogleVertexOptions): string | undefined {\n\tconst apiKey = options?.apiKey?.trim();\n\tif (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) {\n\t\treturn undefined;\n\t}\n\treturn apiKey;\n}\n\nfunction isPlaceholderApiKey(apiKey: string): boolean {\n\treturn /^<[^>]+>$/.test(apiKey);\n}\n\nfunction resolveProject(options?: GoogleVertexOptions): string {\n\tconst project =\n\t\toptions?.project ||\n\t\tgetProviderEnvValue(\"GOOGLE_CLOUD_PROJECT\", options?.env) ||\n\t\tgetProviderEnvValue(\"GCLOUD_PROJECT\", options?.env);\n\tif (!project) {\n\t\tthrow new Error(\n\t\t\t\"Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.\",\n\t\t);\n\t}\n\treturn project;\n}\n\nfunction resolveLocation(options?: GoogleVertexOptions): string {\n\tconst location = options?.location || getProviderEnvValue(\"GOOGLE_CLOUD_LOCATION\", options?.env);\n\tif (!location) {\n\t\tthrow new Error(\"Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.\");\n\t}\n\treturn location;\n}\n\nfunction buildParams(\n\tmodel: Model<\"google-vertex\">,\n\tcontext: TranscriptContext,\n\toptions: GoogleVertexOptions = {},\n): GenerateContentParameters {\n\tconst contents = convertMessages(model, context);\n\tconst initialSystemMessage = getInitialSystemMessage(context.messages);\n\tconst currentTools = getCurrentTools(context.messages);\n\n\tconst generationConfig: GenerateContentConfig = {};\n\tif (options.temperature !== undefined) {\n\t\tgenerationConfig.temperature = options.temperature;\n\t}\n\tif (options.maxTokens !== undefined) {\n\t\tgenerationConfig.maxOutputTokens = options.maxTokens;\n\t}\n\n\tconst supportsStrictMode = supportsGoogleStrictToolSampling(model.id);\n\tconst functionCallingMode =\n\t\tcurrentTools.length > 0\n\t\t\t? resolveGoogleFunctionCallingMode(currentTools, options.toolChoice, supportsStrictMode)\n\t\t\t: undefined;\n\tconst systemInstruction = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : \"\";\n\tconst config: GenerateContentConfig = {\n\t\t...(Object.keys(generationConfig).length > 0 && generationConfig),\n\t\t...(systemInstruction && { systemInstruction: sanitizeSurrogates(systemInstruction) }),\n\t\t...(currentTools.length > 0 && {\n\t\t\ttools: convertTools(currentTools, false, supportsStrictMode),\n\t\t}),\n\t\t...(functionCallingMode !== undefined && {\n\t\t\ttoolConfig: { functionCallingConfig: { mode: functionCallingMode } },\n\t\t}),\n\t};\n\n\tif (options.thinking?.enabled && model.reasoning) {\n\t\tconst thinkingConfig: ThinkingConfig = { includeThoughts: true };\n\t\tif (options.thinking.level !== undefined) {\n\t\t\tthinkingConfig.thinkingLevel = toGoogleSdkThinkingLevel(options.thinking.level);\n\t\t} else if (options.thinking.budgetTokens !== undefined) {\n\t\t\tthinkingConfig.thinkingBudget = options.thinking.budgetTokens;\n\t\t}\n\t\tconfig.thinkingConfig = thinkingConfig;\n\t} else if (model.reasoning && options.thinking && !options.thinking.enabled) {\n\t\tconfig.thinkingConfig = getDisabledGoogleThinkingConfig(model);\n\t}\n\n\tif (options.signal) {\n\t\tif (options.signal.aborted) {\n\t\t\tthrow new Error(\"Request aborted\");\n\t\t}\n\t\tconfig.abortSignal = options.signal;\n\t}\n\n\tconst params: GenerateContentParameters = {\n\t\tmodel: model.id,\n\t\tcontents,\n\t\tconfig,\n\t};\n\n\treturn params;\n}\n\nfunction getGoogleBudget(\n\tmodel: Model<\"google-vertex\">,\n\tlevel: ResolvedGoogleThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): number {\n\tif (customBudgets?.[level] !== undefined) {\n\t\treturn customBudgets[level]!;\n\t}\n\n\tif (model.id.includes(\"2.5-pro\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 32768,\n\t\t};\n\t\treturn budgets[level];\n\t}\n\n\tif (model.id.includes(\"2.5-flash\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 24576,\n\t\t};\n\t\treturn budgets[level];\n\t}\n\n\treturn -1;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mistral-conversations.d.ts","sourceRoot":"","sources":["../../src/api/mistral-conversations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAKX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAKb,MAAM,aAAa,CAAC;AAerB;;GAEG;AACH,KAAK,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,cAAe,SAAQ,aAAa;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACrG,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,eAAe,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAiFD;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,uBAAuB,EAAE,cAAc,CA8D1E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,uBAAuB,EAAE,mBAAmB,CAwBrF,CAAC","sourcesContent":["import { calculateCost, clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { shortHash } from \"../utils/hash.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { createStreamDeadline, withStreamDeadline } from \"../utils/stream-deadline.ts\";\nimport { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from \"./constrained-sampling.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\nconst MISTRAL_TOOL_CALL_ID_LENGTH = 9;\nconst MAX_MISTRAL_ERROR_BODY_CHARS = 4000;\n\n/**\n * Provider-specific options for the Mistral API.\n */\ntype MistralReasoningEffort = \"none\" | \"high\";\n\nexport interface MistralOptions extends StreamOptions {\n\ttoolChoice?: \"auto\" | \"none\" | \"any\" | \"required\" | { type: \"function\"; function: { name: string } };\n\tpromptMode?: \"reasoning\";\n\treasoningEffort?: MistralReasoningEffort;\n}\n\ntype MistralContentChunk =\n\t| { type: \"text\"; text: string }\n\t| { type: \"image_url\"; imageUrl: string }\n\t| { type: \"thinking\"; thinking: Array<{ type: \"text\"; text: string }> };\n\ntype MistralRequestToolCall = {\n\tid: string;\n\ttype: \"function\";\n\tfunction: { name: string; arguments: string };\n\tindex: number;\n};\n\ntype MistralChatMessage = {\n\trole: \"system\" | \"user\" | \"assistant\" | \"tool\";\n\tcontent?: string | MistralContentChunk[];\n\ttoolCalls?: MistralRequestToolCall[];\n\ttoolCallId?: string;\n\tname?: string;\n\tprefix?: boolean;\n};\n\ntype MistralFunctionTool = {\n\ttype: \"function\";\n\tfunction: {\n\t\tname: string;\n\t\tdescription: string;\n\t\tparameters: Record<string, unknown>;\n\t\tstrict: boolean;\n\t};\n};\n\ntype MistralChatPayload = {\n\t[key: string]: unknown;\n\tmodel: string;\n\tstream: boolean;\n\tmessages: MistralChatMessage[];\n\ttools?: MistralFunctionTool[];\n\ttemperature?: number;\n\tmaxTokens?: number;\n\ttoolChoice?: Exclude<MistralOptions[\"toolChoice\"], undefined>;\n\tpromptMode?: \"reasoning\";\n\treasoningEffort?: MistralReasoningEffort;\n\tpromptCacheKey?: string;\n};\n\ntype MistralStreamContentChunk = {\n\ttype: string;\n\ttext?: string;\n\tthinking?: Array<{ text?: string }>;\n};\n\ntype MistralStreamToolCall = {\n\tid?: string;\n\tindex?: number;\n\tfunction: {\n\t\tname: string;\n\t\targuments: string | Record<string, unknown>;\n\t};\n};\n\ntype MistralCompletionEvent = {\n\tdata: {\n\t\tid?: string;\n\t\tusage?: {\n\t\t\t[key: string]: unknown;\n\t\t\tprompt_tokens?: number;\n\t\t\tcompletion_tokens?: number;\n\t\t\ttotal_tokens?: number;\n\t\t};\n\t\tchoices: Array<{\n\t\t\tfinish_reason?: string | null;\n\t\t\tdelta: {\n\t\t\t\tcontent?: string | MistralStreamContentChunk[] | null;\n\t\t\t\ttool_calls?: MistralStreamToolCall[] | null;\n\t\t\t};\n\t\t}>;\n\t};\n};\n\n/**\n * Stream responses from the native Mistral Chat Completions endpoint.\n */\nexport const stream: StreamFunction<\"mistral-conversations\", MistralOptions> = (\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: Context,\n\toptions?: MistralOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst output = createOutput(model);\n\t\tconst streamDeadline = createStreamDeadline(options?.streamDeadlineMs, options?.signal);\n\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t\t\t}\n\n\t\t\tconst normalizeMistralToolCallId = createMistralToolCallIdNormalizer();\n\t\t\tconst transformedMessages = transformMessages(context.messages, model, (id) => normalizeMistralToolCallId(id));\n\n\t\t\tlet payload = buildChatPayload(model, context, transformedMessages, options);\n\t\t\tconst nextPayload = await options?.onPayload?.(payload, model);\n\t\t\tif (nextPayload !== undefined) {\n\t\t\t\tpayload = nextPayload as MistralChatPayload;\n\t\t\t}\n\t\t\tconst mistralStream = await requestMistralStream(model, payload, apiKey, options, streamDeadline.signal);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\tawait consumeChatStream(\n\t\t\t\tmodel,\n\t\t\t\toutput,\n\t\t\t\tstream,\n\t\t\t\twithStreamDeadline(mistralStream, streamDeadline.deadlineMs, streamDeadline.abort),\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 === \"pending\") {\n\t\t\t\tthrow new Error(\"Mistral stream ended without a finish reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(output.errorMessage || \"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\t// partialArgs is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialArgs?: string }).partialArgs;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatMistralError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t} finally {\n\t\t\tstreamDeadline.cleanup();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Maps provider-agnostic `SimpleStreamOptions` to Mistral options.\n */\nexport const streamSimple: StreamFunction<\"mistral-conversations\", SimpleStreamOptions> = (\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey;\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, apiKey),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies MistralOptions;\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoning = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\tconst shouldUseReasoning = model.reasoning && reasoning !== undefined;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\tpromptMode: shouldUseReasoning && usesPromptModeReasoning(model) ? \"reasoning\" : undefined,\n\t\treasoningEffort:\n\t\t\tshouldUseReasoning && usesReasoningEffort(model) ? mapReasoningEffort(model, reasoning) : undefined,\n\t} satisfies MistralOptions);\n};\n\nfunction createOutput(model: Model<\"mistral-conversations\">): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"pending\",\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createMistralToolCallIdNormalizer(): (id: string) => string {\n\tconst idMap = new Map<string, string>();\n\tconst reverseMap = new Map<string, string>();\n\n\treturn (id: string): string => {\n\t\tconst existing = idMap.get(id);\n\t\tif (existing) return existing;\n\n\t\tlet attempt = 0;\n\t\twhile (true) {\n\t\t\tconst candidate = deriveMistralToolCallId(id, attempt);\n\t\t\tconst owner = reverseMap.get(candidate);\n\t\t\tif (!owner || owner === id) {\n\t\t\t\tidMap.set(id, candidate);\n\t\t\t\treverseMap.set(candidate, id);\n\t\t\t\treturn candidate;\n\t\t\t}\n\t\t\tattempt++;\n\t\t}\n\t};\n}\n\nfunction deriveMistralToolCallId(id: string, attempt: number): string {\n\tconst normalized = id.replace(/[^a-zA-Z0-9]/g, \"\");\n\tif (attempt === 0 && normalized.length === MISTRAL_TOOL_CALL_ID_LENGTH) return normalized;\n\tconst seedBase = normalized || id;\n\tconst seed = attempt === 0 ? seedBase : `${seedBase}:${attempt}`;\n\treturn shortHash(seed)\n\t\t.replace(/[^a-zA-Z0-9]/g, \"\")\n\t\t.slice(0, MISTRAL_TOOL_CALL_ID_LENGTH);\n}\n\nfunction formatMistralError(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tconst httpError = error as Error & { statusCode?: unknown; body?: unknown };\n\t\tconst statusCode = typeof httpError.statusCode === \"number\" ? httpError.statusCode : undefined;\n\t\tconst bodyText = typeof httpError.body === \"string\" ? httpError.body.trim() : undefined;\n\t\tif (statusCode !== undefined && bodyText) {\n\t\t\treturn `Mistral API error (${statusCode}): ${truncateErrorText(bodyText, MAX_MISTRAL_ERROR_BODY_CHARS)}`;\n\t\t}\n\t\tif (statusCode !== undefined) return `Mistral API error (${statusCode}): ${error.message}`;\n\t\treturn error.message;\n\t}\n\treturn safeJsonStringify(error);\n}\n\nfunction truncateErrorText(text: string, maxChars: number): string {\n\tif (text.length <= maxChars) return text;\n\treturn `${text.slice(0, maxChars)}... [truncated ${text.length - maxChars} chars]`;\n}\n\nfunction safeJsonStringify(value: unknown): string {\n\ttry {\n\t\tconst serialized = JSON.stringify(value);\n\t\treturn serialized === undefined ? String(value) : serialized;\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nasync function requestMistralStream(\n\tmodel: Model<\"mistral-conversations\">,\n\tpayload: MistralChatPayload,\n\tapiKey: string,\n\toptions?: MistralOptions,\n\trequestSignal?: AbortSignal,\n): Promise<AsyncIterable<MistralCompletionEvent>> {\n\tconst baseUrl = new URL(model.baseUrl);\n\tbaseUrl.pathname = `${baseUrl.pathname.replace(/\\/+$/u, \"\")}/`;\n\tconst url = new URL(\"v1/chat/completions\", baseUrl);\n\tconst headers = buildMistralHeaders(model, apiKey, options);\n\tconst timeoutSignal = AbortSignal.timeout(options?.timeoutMs ?? 60_000);\n\tconst signal = requestSignal ? AbortSignal.any([requestSignal, timeoutSignal]) : timeoutSignal;\n\tconst response = await (options?.fetch ?? globalThis.fetch)(url, {\n\t\tmethod: \"POST\",\n\t\theaders,\n\t\tbody: JSON.stringify(toMistralWirePayload(payload)),\n\t\tsignal,\n\t});\n\n\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\n\tif (!response.ok) {\n\t\tconst body = await response.text();\n\t\tthrow new MistralHttpError(response.status, body, response.statusText);\n\t}\n\tif (!response.body) {\n\t\tthrow new Error(\"Mistral response has no body\");\n\t}\n\n\treturn readMistralEvents(response.body, signal);\n}\n\nclass MistralHttpError extends Error {\n\tstatusCode: number;\n\tbody: string;\n\n\tconstructor(statusCode: number, body: string, statusText: string) {\n\t\tsuper(statusText || `Request failed with status ${statusCode}`);\n\t\tthis.name = \"MistralHttpError\";\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nfunction buildMistralHeaders(model: Model<\"mistral-conversations\">, apiKey: string, options?: MistralOptions): Headers {\n\tconst headers = new Headers({\n\t\t\"User-Agent\": getPiUserAgent(),\n\t\taccept: \"text/event-stream\",\n\t\tauthorization: `Bearer ${apiKey}`,\n\t\t\"content-type\": \"application/json\",\n\t});\n\tapplyMistralHeaderOverrides(headers, model.headers);\n\tapplyMistralHeaderOverrides(headers, options?.headers);\n\n\tconst hasExplicitAffinity =\n\t\thasMistralHeaderOverride(model.headers, \"x-affinity\") || hasMistralHeaderOverride(options?.headers, \"x-affinity\");\n\tif (shouldUsePromptCaching(options) && !hasExplicitAffinity) {\n\t\theaders.set(\"x-affinity\", options.sessionId);\n\t}\n\n\treturn headers;\n}\n\nfunction applyMistralHeaderOverrides(headers: Headers, overrides?: Record<string, string | null>): void {\n\tif (!overrides) return;\n\tfor (const [name, value] of Object.entries(overrides)) {\n\t\tif (value === null) headers.delete(name);\n\t\telse headers.set(name, value);\n\t}\n}\n\nfunction hasMistralHeaderOverride(overrides: Record<string, string | null> | undefined, target: string): boolean {\n\treturn !!overrides && Object.keys(overrides).some((name) => name.toLowerCase() === target);\n}\n\nfunction toMistralWirePayload(payload: MistralChatPayload): Record<string, unknown> {\n\tconst wirePayload: Record<string, unknown> = { ...payload };\n\tfor (const [source, target] of [\n\t\t[\"topP\", \"top_p\"],\n\t\t[\"maxTokens\", \"max_tokens\"],\n\t\t[\"randomSeed\", \"random_seed\"],\n\t\t[\"responseFormat\", \"response_format\"],\n\t\t[\"toolChoice\", \"tool_choice\"],\n\t\t[\"presencePenalty\", \"presence_penalty\"],\n\t\t[\"frequencyPenalty\", \"frequency_penalty\"],\n\t\t[\"parallelToolCalls\", \"parallel_tool_calls\"],\n\t\t[\"reasoningEffort\", \"reasoning_effort\"],\n\t\t[\"promptMode\", \"prompt_mode\"],\n\t\t[\"promptCacheKey\", \"prompt_cache_key\"],\n\t\t[\"safePrompt\", \"safe_prompt\"],\n\t] as const) {\n\t\tremapMistralProperty(wirePayload, source, target);\n\t}\n\twirePayload.messages = payload.messages.map((message) => toMistralWireMessage(message));\n\n\tconst responseFormat = wirePayload.response_format;\n\tif (isMistralRecord(responseFormat)) {\n\t\tconst wireResponseFormat = { ...responseFormat };\n\t\tremapMistralProperty(wireResponseFormat, \"jsonSchema\", \"json_schema\");\n\t\tconst jsonSchema = wireResponseFormat.json_schema;\n\t\tif (isMistralRecord(jsonSchema)) {\n\t\t\tconst wireJsonSchema = { ...jsonSchema };\n\t\t\tremapMistralProperty(wireJsonSchema, \"schemaDefinition\", \"schema\");\n\t\t\twireResponseFormat.json_schema = wireJsonSchema;\n\t\t}\n\t\twirePayload.response_format = wireResponseFormat;\n\t}\n\n\treturn wirePayload;\n}\n\nfunction toMistralWireMessage(message: MistralChatMessage): Record<string, unknown> {\n\tconst wireMessage: Record<string, unknown> = { ...message };\n\tremapMistralProperty(wireMessage, \"toolCalls\", \"tool_calls\");\n\tremapMistralProperty(wireMessage, \"toolCallId\", \"tool_call_id\");\n\tif (Array.isArray(message.content)) {\n\t\twireMessage.content = message.content.map((chunk) => toMistralWireContentChunk(chunk));\n\t}\n\treturn wireMessage;\n}\n\nfunction toMistralWireContentChunk(chunk: MistralContentChunk): Record<string, unknown> {\n\tconst wireChunk: Record<string, unknown> = { ...chunk };\n\tfor (const [source, target] of [\n\t\t[\"imageUrl\", \"image_url\"],\n\t\t[\"documentUrl\", \"document_url\"],\n\t\t[\"documentName\", \"document_name\"],\n\t\t[\"fileId\", \"file_id\"],\n\t\t[\"referenceIds\", \"reference_ids\"],\n\t\t[\"inputAudio\", \"input_audio\"],\n\t] as const) {\n\t\tremapMistralProperty(wireChunk, source, target);\n\t}\n\treturn wireChunk;\n}\n\nfunction remapMistralProperty(record: Record<string, unknown>, source: string, target: string): void {\n\tif (!(source in record)) return;\n\trecord[target] = record[source];\n\tdelete record[source];\n}\n\nfunction isMistralRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst MISTRAL_STREAM_DONE = Symbol(\"mistral-stream-done\");\n\nasync function* readMistralEvents(\n\tbody: ReadableStream<Uint8Array>,\n\tsignal: AbortSignal,\n): AsyncGenerator<MistralCompletionEvent> {\n\tconst reader = body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet buffer = \"\";\n\tconst onAbort = () => {\n\t\tvoid reader.cancel().catch(() => {});\n\t};\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\n\ttry {\n\t\twhile (true) {\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tbuffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n\n\t\t\tlet boundary = findMistralEventBoundary(buffer);\n\t\t\twhile (boundary) {\n\t\t\t\tconst event = parseMistralEvent(buffer.slice(0, boundary.index));\n\t\t\t\tbuffer = buffer.slice(boundary.index + boundary.length);\n\t\t\t\tif (event === MISTRAL_STREAM_DONE) return;\n\t\t\t\tif (event) yield event;\n\t\t\t\tboundary = findMistralEventBoundary(buffer);\n\t\t\t}\n\n\t\t\tif (done) break;\n\t\t}\n\n\t\tif (buffer.trim()) {\n\t\t\tconst event = parseMistralEvent(buffer);\n\t\t\tif (event !== MISTRAL_STREAM_DONE && event) yield event;\n\t\t}\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\ttry {\n\t\t\tawait reader.cancel();\n\t\t} catch {}\n\t\ttry {\n\t\t\treader.releaseLock();\n\t\t} catch {}\n\t}\n}\n\nfunction findMistralEventBoundary(buffer: string): { index: number; length: number } | undefined {\n\tconst match = /\\r\\n\\r\\n|\\r\\n\\r|\\r\\n\\n|\\r\\r\\n|\\n\\r\\n|\\r\\r|\\n\\r|\\n\\n/u.exec(buffer);\n\treturn match?.index === undefined ? undefined : { index: match.index, length: match[0].length };\n}\n\nfunction parseMistralEvent(raw: string): MistralCompletionEvent | typeof MISTRAL_STREAM_DONE | undefined {\n\tconst data = raw\n\t\t.split(/\\r\\n|\\r|\\n/u)\n\t\t.filter((line) => line.startsWith(\"data:\"))\n\t\t.map((line) => line.slice(5).trimStart())\n\t\t.join(\"\\n\")\n\t\t.trim();\n\tif (!data) return undefined;\n\tif (data === \"[DONE]\") return MISTRAL_STREAM_DONE;\n\n\tconst parsed: unknown = JSON.parse(data);\n\tif (!isMistralRecord(parsed) || !Array.isArray(parsed.choices)) {\n\t\tthrow new Error(\"Invalid Mistral streaming event\");\n\t}\n\treturn { data: parsed as MistralCompletionEvent[\"data\"] };\n}\n\nfunction buildChatPayload(\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: Context,\n\tmessages: Message[],\n\toptions?: MistralOptions,\n): MistralChatPayload {\n\tconst payload: MistralChatPayload = {\n\t\tmodel: model.id,\n\t\tstream: true,\n\t\tmessages: toChatMessages(messages, model.input.includes(\"image\")),\n\t};\n\n\tif (context.tools?.length) payload.tools = toFunctionTools(context.tools);\n\tif (options?.temperature !== undefined) payload.temperature = options.temperature;\n\tif (options?.maxTokens !== undefined) payload.maxTokens = options.maxTokens;\n\tif (options?.toolChoice) payload.toolChoice = mapToolChoice(options.toolChoice);\n\tif (options?.promptMode) payload.promptMode = options.promptMode;\n\tif (options?.reasoningEffort) payload.reasoningEffort = options.reasoningEffort;\n\tif (shouldUsePromptCaching(options)) payload.promptCacheKey = options.sessionId;\n\n\tif (context.systemPrompt) {\n\t\tpayload.messages.unshift({\n\t\t\trole: \"system\",\n\t\t\tcontent: sanitizeSurrogates(context.systemPrompt),\n\t\t});\n\t}\n\n\treturn payload;\n}\n\nfunction shouldUsePromptCaching(options?: MistralOptions): options is MistralOptions & { sessionId: string } {\n\treturn options?.cacheRetention !== \"none\" && !!options?.sessionId;\n}\n\nfunction getMistralCachedPromptTokens(usage: unknown, promptTokens: number): number {\n\tconst rawUsage = usage as {\n\t\tpromptTokensDetails?: { cachedTokens?: unknown } | null;\n\t\tprompt_tokens_details?: { cached_tokens?: unknown } | null;\n\t\tpromptTokenDetails?: { cachedTokens?: unknown } | null;\n\t\tprompt_token_details?: { cached_tokens?: unknown } | null;\n\t\tnumCachedTokens?: unknown;\n\t\tnum_cached_tokens?: unknown;\n\t};\n\tconst rawCachedTokens =\n\t\trawUsage.promptTokensDetails?.cachedTokens ??\n\t\trawUsage.prompt_tokens_details?.cached_tokens ??\n\t\trawUsage.promptTokenDetails?.cachedTokens ??\n\t\trawUsage.prompt_token_details?.cached_tokens ??\n\t\trawUsage.numCachedTokens ??\n\t\trawUsage.num_cached_tokens ??\n\t\t0;\n\tconst cachedTokens = typeof rawCachedTokens === \"number\" && Number.isFinite(rawCachedTokens) ? rawCachedTokens : 0;\n\treturn Math.min(promptTokens, Math.max(0, cachedTokens));\n}\n\nasync function consumeChatStream(\n\tmodel: Model<\"mistral-conversations\">,\n\toutput: AssistantMessage,\n\tstream: AssistantMessageEventStream,\n\tmistralStream: AsyncIterable<MistralCompletionEvent>,\n): Promise<void> {\n\tlet currentBlock: TextContent | ThinkingContent | null = null;\n\tconst blocks = output.content;\n\tconst blockIndex = () => blocks.length - 1;\n\tconst toolBlocksByKey = new Map<string | number, number>();\n\n\tconst finishCurrentBlock = (block?: typeof currentBlock) => {\n\t\tif (!block) return;\n\t\tif (block.type === \"text\") {\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_end\",\n\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\tcontent: block.text,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (block.type === \"thinking\") {\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_end\",\n\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\tcontent: block.thinking,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t};\n\n\tfor await (const event of mistralStream) {\n\t\tconst chunk = event.data;\n\t\t// Mistral's streamed CompletionChunk carries an id field. Keep the first non-empty one,\n\t\t// mirroring how OpenAI-style streaming exposes a stable response identifier per stream.\n\t\toutput.responseId ||= chunk.id;\n\n\t\tif (chunk.usage) {\n\t\t\tconst promptTokens = chunk.usage.prompt_tokens || 0;\n\t\t\tconst cachedPromptTokens = getMistralCachedPromptTokens(chunk.usage, promptTokens);\n\n\t\t\toutput.usage.input = Math.max(0, promptTokens - cachedPromptTokens);\n\t\t\toutput.usage.output = chunk.usage.completion_tokens || 0;\n\t\t\toutput.usage.cacheRead = cachedPromptTokens;\n\t\t\toutput.usage.cacheWrite = 0;\n\t\t\toutput.usage.totalTokens =\n\t\t\t\tchunk.usage.total_tokens ||\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t}\n\n\t\tconst choice = chunk.choices[0];\n\t\tif (!choice) continue;\n\n\t\tif (choice.finish_reason) {\n\t\t\toutput.rawStopReason = choice.finish_reason;\n\t\t\tconst stopReasonResult = mapChatStopReason(choice.finish_reason);\n\t\t\toutput.stopReason = stopReasonResult.stopReason;\n\t\t\tif (stopReasonResult.errorMessage) {\n\t\t\t\toutput.errorMessage = stopReasonResult.errorMessage;\n\t\t\t}\n\t\t}\n\n\t\tconst delta = choice.delta;\n\t\tif (delta.content !== null && delta.content !== undefined) {\n\t\t\tconst contentItems = typeof delta.content === \"string\" ? [delta.content] : delta.content;\n\t\t\tfor (const item of contentItems) {\n\t\t\t\tif (typeof item === \"string\") {\n\t\t\t\t\tconst textDelta = sanitizeSurrogates(item);\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"text\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.text += textDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: textDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (item.type === \"thinking\") {\n\t\t\t\t\tconst deltaText = (item.thinking ?? [])\n\t\t\t\t\t\t.map((part) => part.text ?? \"\")\n\t\t\t\t\t\t.filter((text) => text.length > 0)\n\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\tconst thinkingDelta = sanitizeSurrogates(deltaText);\n\t\t\t\t\tif (!thinkingDelta) continue;\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"thinking\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"thinking\", thinking: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.thinking += thinkingDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: thinkingDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\tconst textDelta = sanitizeSurrogates(item.text ?? \"\");\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"text\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.text += textDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: textDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst toolCalls = delta.tool_calls || [];\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tif (currentBlock) {\n\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\tcurrentBlock = null;\n\t\t\t}\n\t\t\tconst callId =\n\t\t\t\ttoolCall.id && toolCall.id !== \"null\"\n\t\t\t\t\t? toolCall.id\n\t\t\t\t\t: deriveMistralToolCallId(`toolcall:${toolCall.index ?? 0}`, 0);\n\t\t\tconst key = toolCall.index ?? callId;\n\t\t\tconst existingIndex = toolBlocksByKey.get(key);\n\t\t\tlet block: (ToolCall & { partialArgs?: string }) | undefined;\n\n\t\t\tif (existingIndex !== undefined) {\n\t\t\t\tconst existing = output.content[existingIndex];\n\t\t\t\tif (existing?.type === \"toolCall\") {\n\t\t\t\t\tblock = existing as ToolCall & { partialArgs?: string };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!block) {\n\t\t\t\tblock = {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\tid: callId,\n\t\t\t\t\tname: toolCall.function.name,\n\t\t\t\t\targuments: {},\n\t\t\t\t\tpartialArgs: \"\",\n\t\t\t\t};\n\t\t\t\toutput.content.push(block);\n\t\t\t\ttoolBlocksByKey.set(key, output.content.length - 1);\n\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t}\n\n\t\t\tconst argsDelta =\n\t\t\t\ttypeof toolCall.function.arguments === \"string\"\n\t\t\t\t\t? toolCall.function.arguments\n\t\t\t\t\t: JSON.stringify(toolCall.function.arguments || {});\n\t\t\tblock.partialArgs = (block.partialArgs || \"\") + argsDelta;\n\t\t\tblock.arguments = parseStreamingJson<Record<string, unknown>>(block.partialArgs);\n\t\t\tstream.push({\n\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\tcontentIndex: toolBlocksByKey.get(key)!,\n\t\t\t\tdelta: argsDelta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t}\n\n\tfinishCurrentBlock(currentBlock);\n\tfor (const index of toolBlocksByKey.values()) {\n\t\tconst block = output.content[index];\n\t\tif (block.type !== \"toolCall\") continue;\n\t\tconst toolBlock = block as ToolCall & { partialArgs?: string };\n\t\ttoolBlock.arguments = parseStreamingJson<Record<string, unknown>>(toolBlock.partialArgs);\n\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t// carries parsed arguments.\n\t\tdelete toolBlock.partialArgs;\n\t\tstream.push({\n\t\t\ttype: \"toolcall_end\",\n\t\t\tcontentIndex: index,\n\t\t\ttoolCall: toolBlock,\n\t\t\tpartial: output,\n\t\t});\n\t}\n}\n\nfunction toFunctionTools(tools: Tool[]): MistralFunctionTool[] {\n\treturn tools.map((tool) => {\n\t\tconst strict = resolveJsonSchemaStrictSampling(tool, true);\n\t\treturn {\n\t\t\ttype: \"function\",\n\t\t\tfunction: {\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparameters: stripSymbolKeys(getJsonSchemaToolParameters(tool, strict)) as Record<string, unknown>,\n\t\t\t\tstrict: strict ?? false,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction stripSymbolKeys(value: unknown): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item) => stripSymbolKeys(item));\n\t}\n\n\tif (value && typeof value === \"object\") {\n\t\tconst result: Record<string, unknown> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tresult[key] = stripSymbolKeys(entry);\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn value;\n}\n\nfunction toChatMessages(messages: Message[], supportsImages: boolean): MistralChatMessage[] {\n\tconst result: MistralChatMessage[] = [];\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tresult.push({ role: \"user\", content: sanitizeSurrogates(msg.content) });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst hadImages = msg.content.some((item) => item.type === \"image\");\n\t\t\tconst content: MistralContentChunk[] = msg.content\n\t\t\t\t.filter((item) => item.type === \"text\" || supportsImages)\n\t\t\t\t.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") return { type: \"text\", text: sanitizeSurrogates(item.text) };\n\t\t\t\t\treturn { type: \"image_url\", imageUrl: `data:${item.mimeType};base64,${item.data}` };\n\t\t\t\t});\n\t\t\tif (content.length > 0) {\n\t\t\t\tresult.push({ role: \"user\", content });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (hadImages && !supportsImages) {\n\t\t\t\tresult.push({ role: \"user\", content: \"(image omitted: model does not support images)\" });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst contentParts: MistralContentChunk[] = [];\n\t\t\tconst toolCalls: MistralRequestToolCall[] = [];\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) {\n\t\t\t\t\t\tcontentParts.push({ type: \"text\", text: sanitizeSurrogates(block.text) });\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\tif (block.thinking.trim().length > 0) {\n\t\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: [{ type: \"text\", text: sanitizeSurrogates(block.thinking) }],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Anthropic server-side fallback markers have no Mistral representation and carry no\n\t\t\t\t// content; skip them rather than mis-serializing them as a tool call.\n\t\t\t\tif (block.type !== \"toolCall\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\ttoolCalls.push({\n\t\t\t\t\tid: block.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: { name: block.name, arguments: JSON.stringify(block.arguments || {}) },\n\t\t\t\t\tindex: 0,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst assistantMessage: MistralChatMessage = { role: \"assistant\", prefix: false };\n\t\t\tif (contentParts.length > 0) assistantMessage.content = contentParts;\n\t\t\tif (toolCalls.length > 0) assistantMessage.toolCalls = toolCalls;\n\t\t\tif (contentParts.length > 0 || toolCalls.length > 0) result.push(assistantMessage);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst toolContent: MistralContentChunk[] = [];\n\t\tconst textResult = msg.content\n\t\t\t.filter((part) => part.type === \"text\")\n\t\t\t.map((part) => (part.type === \"text\" ? sanitizeSurrogates(part.text) : \"\"))\n\t\t\t.join(\"\\n\");\n\t\tconst hasImages = msg.content.some((part) => part.type === \"image\");\n\t\tconst toolText = buildToolResultText(textResult, hasImages, supportsImages, msg.isError);\n\t\ttoolContent.push({ type: \"text\", text: toolText });\n\t\tfor (const part of msg.content) {\n\t\t\tif (!supportsImages) continue;\n\t\t\tif (part.type !== \"image\") continue;\n\t\t\ttoolContent.push({\n\t\t\t\ttype: \"image_url\",\n\t\t\t\timageUrl: `data:${part.mimeType};base64,${part.data}`,\n\t\t\t});\n\t\t}\n\t\tresult.push({\n\t\t\trole: \"tool\",\n\t\t\ttoolCallId: msg.toolCallId,\n\t\t\tname: msg.toolName,\n\t\t\tcontent: toolContent,\n\t\t});\n\t}\n\n\treturn result;\n}\n\nfunction buildToolResultText(text: string, hasImages: boolean, supportsImages: boolean, isError: boolean): string {\n\tconst trimmed = text.trim();\n\tconst errorPrefix = isError ? \"[tool error] \" : \"\";\n\n\tif (trimmed.length > 0) {\n\t\tconst imageSuffix = hasImages && !supportsImages ? \"\\n[tool image omitted: model does not support images]\" : \"\";\n\t\treturn `${errorPrefix}${trimmed}${imageSuffix}`;\n\t}\n\n\tif (hasImages) {\n\t\tif (supportsImages) {\n\t\t\treturn isError ? \"[tool error] (see attached image)\" : \"(see attached image)\";\n\t\t}\n\t\treturn isError\n\t\t\t? \"[tool error] (image omitted: model does not support images)\"\n\t\t\t: \"(image omitted: model does not support images)\";\n\t}\n\n\treturn isError ? \"[tool error] (no tool output)\" : \"(no tool output)\";\n}\n\nfunction usesReasoningEffort(model: Model<\"mistral-conversations\">): boolean {\n\treturn (\n\t\tmodel.id === \"mistral-small-2603\" ||\n\t\tmodel.id === \"mistral-small-latest\" ||\n\t\tmodel.id.startsWith(\"mistral-medium-\") ||\n\t\tmodel.id === \"zai-glm-5-2\"\n\t);\n}\n\nfunction usesPromptModeReasoning(model: Model<\"mistral-conversations\">): boolean {\n\treturn model.reasoning && !usesReasoningEffort(model);\n}\n\nfunction mapReasoningEffort(\n\tmodel: Model<\"mistral-conversations\">,\n\tlevel: Exclude<SimpleStreamOptions[\"reasoning\"], undefined>,\n): MistralReasoningEffort {\n\treturn (model.thinkingLevelMap?.[level] ?? \"high\") as MistralReasoningEffort;\n}\n\nfunction mapToolChoice(\n\tchoice: MistralOptions[\"toolChoice\"],\n): \"auto\" | \"none\" | \"any\" | \"required\" | { type: \"function\"; function: { name: string } } | undefined {\n\tif (!choice) return undefined;\n\tif (choice === \"auto\" || choice === \"none\" || choice === \"any\" || choice === \"required\") {\n\t\treturn choice;\n\t}\n\treturn {\n\t\ttype: \"function\",\n\t\tfunction: { name: choice.function.name },\n\t};\n}\n\nfunction mapChatStopReason(reason: string | null): { stopReason: StopReason; errorMessage?: string } {\n\tif (reason === null) return { stopReason: \"stop\" };\n\tswitch (reason) {\n\t\tcase \"stop\":\n\t\t\treturn { stopReason: \"stop\" };\n\t\tcase \"length\":\n\t\tcase \"model_length\":\n\t\t\treturn { stopReason: \"length\" };\n\t\tcase \"tool_calls\":\n\t\t\treturn { stopReason: \"toolUse\" };\n\t\tcase \"error\":\n\t\t\treturn { stopReason: \"error\", errorMessage: \"Provider stopped with: error\" };\n\t\tdefault:\n\t\t\treturn { stopReason: \"error\", errorMessage: `Provider stopped with: ${reason}` };\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mistral-conversations.d.ts","sourceRoot":"","sources":["../../src/api/mistral-conversations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AAiBrB;;GAEG;AACH,KAAK,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,cAAe,SAAQ,aAAa;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACrG,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,eAAe,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAiFD;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,uBAAuB,EAAE,cAAc,CAiE1E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,uBAAuB,EAAE,mBAAmB,CAwBrF,CAAC","sourcesContent":["import { calculateCost, clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStopReason,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tTranscriptContext,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { shortHash } from \"../utils/hash.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { createStreamDeadline, withStreamDeadline } from \"../utils/stream-deadline.ts\";\nimport { getSystemMessageText, renderSystemMessageUpdate } from \"../utils/text.ts\";\nimport { getCurrentTools, resolveTranscript } from \"../utils/transcript.ts\";\nimport { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from \"./constrained-sampling.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\nconst MISTRAL_TOOL_CALL_ID_LENGTH = 9;\nconst MAX_MISTRAL_ERROR_BODY_CHARS = 4000;\n\n/**\n * Provider-specific options for the Mistral API.\n */\ntype MistralReasoningEffort = \"none\" | \"high\";\n\nexport interface MistralOptions extends StreamOptions {\n\ttoolChoice?: \"auto\" | \"none\" | \"any\" | \"required\" | { type: \"function\"; function: { name: string } };\n\tpromptMode?: \"reasoning\";\n\treasoningEffort?: MistralReasoningEffort;\n}\n\ntype MistralContentChunk =\n\t| { type: \"text\"; text: string }\n\t| { type: \"image_url\"; imageUrl: string }\n\t| { type: \"thinking\"; thinking: Array<{ type: \"text\"; text: string }> };\n\ntype MistralRequestToolCall = {\n\tid: string;\n\ttype: \"function\";\n\tfunction: { name: string; arguments: string };\n\tindex: number;\n};\n\ntype MistralChatMessage = {\n\trole: \"system\" | \"user\" | \"assistant\" | \"tool\";\n\tcontent?: string | MistralContentChunk[];\n\ttoolCalls?: MistralRequestToolCall[];\n\ttoolCallId?: string;\n\tname?: string;\n\tprefix?: boolean;\n};\n\ntype MistralFunctionTool = {\n\ttype: \"function\";\n\tfunction: {\n\t\tname: string;\n\t\tdescription: string;\n\t\tparameters: Record<string, unknown>;\n\t\tstrict: boolean;\n\t};\n};\n\ntype MistralChatPayload = {\n\t[key: string]: unknown;\n\tmodel: string;\n\tstream: boolean;\n\tmessages: MistralChatMessage[];\n\ttools?: MistralFunctionTool[];\n\ttemperature?: number;\n\tmaxTokens?: number;\n\ttoolChoice?: Exclude<MistralOptions[\"toolChoice\"], undefined>;\n\tpromptMode?: \"reasoning\";\n\treasoningEffort?: MistralReasoningEffort;\n\tpromptCacheKey?: string;\n};\n\ntype MistralStreamContentChunk = {\n\ttype: string;\n\ttext?: string;\n\tthinking?: Array<{ text?: string }>;\n};\n\ntype MistralStreamToolCall = {\n\tid?: string;\n\tindex?: number;\n\tfunction: {\n\t\tname: string;\n\t\targuments: string | Record<string, unknown>;\n\t};\n};\n\ntype MistralCompletionEvent = {\n\tdata: {\n\t\tid?: string;\n\t\tusage?: {\n\t\t\t[key: string]: unknown;\n\t\t\tprompt_tokens?: number;\n\t\t\tcompletion_tokens?: number;\n\t\t\ttotal_tokens?: number;\n\t\t};\n\t\tchoices: Array<{\n\t\t\tfinish_reason?: string | null;\n\t\t\tdelta: {\n\t\t\t\tcontent?: string | MistralStreamContentChunk[] | null;\n\t\t\t\ttool_calls?: MistralStreamToolCall[] | null;\n\t\t\t};\n\t\t}>;\n\t};\n};\n\n/**\n * Stream responses from the native Mistral Chat Completions endpoint.\n */\nexport const stream: StreamFunction<\"mistral-conversations\", MistralOptions> = (\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: TranscriptContext,\n\toptions?: MistralOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst normalizedContext = resolveTranscript(context, model.compat?.supportsMidConvoSystemMessages);\n\n\t(async () => {\n\t\tconst output = createOutput(model);\n\t\tconst streamDeadline = createStreamDeadline(options?.streamDeadlineMs, options?.signal);\n\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t\t\t}\n\n\t\t\tconst normalizeMistralToolCallId = createMistralToolCallIdNormalizer();\n\t\t\tconst transformedMessages = transformMessages(normalizedContext.messages, model, (id) =>\n\t\t\t\tnormalizeMistralToolCallId(id),\n\t\t\t);\n\n\t\t\tlet payload = buildChatPayload(model, normalizedContext, transformedMessages, options);\n\t\t\tconst nextPayload = await options?.onPayload?.(payload, model);\n\t\t\tif (nextPayload !== undefined) {\n\t\t\t\tpayload = nextPayload as MistralChatPayload;\n\t\t\t}\n\t\t\tconst mistralStream = await requestMistralStream(model, payload, apiKey, options, streamDeadline.signal);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\tawait consumeChatStream(\n\t\t\t\tmodel,\n\t\t\t\toutput,\n\t\t\t\tstream,\n\t\t\t\twithStreamDeadline(mistralStream, streamDeadline.deadlineMs, streamDeadline.abort),\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 === \"pending\") {\n\t\t\t\tthrow new Error(\"Mistral stream ended without a finish reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(output.errorMessage || \"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\t// partialArgs is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialArgs?: string }).partialArgs;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatMistralError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t} finally {\n\t\t\tstreamDeadline.cleanup();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\n/**\n * Maps provider-agnostic `SimpleStreamOptions` to Mistral options.\n */\nexport const streamSimple: StreamFunction<\"mistral-conversations\", SimpleStreamOptions> = (\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: TranscriptContext,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey;\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, apiKey),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies MistralOptions;\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoning = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\tconst shouldUseReasoning = model.reasoning && reasoning !== undefined;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\tpromptMode: shouldUseReasoning && usesPromptModeReasoning(model) ? \"reasoning\" : undefined,\n\t\treasoningEffort:\n\t\t\tshouldUseReasoning && usesReasoningEffort(model) ? mapReasoningEffort(model, reasoning) : undefined,\n\t} satisfies MistralOptions);\n};\n\nfunction createOutput(model: Model<\"mistral-conversations\">): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"pending\",\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createMistralToolCallIdNormalizer(): (id: string) => string {\n\tconst idMap = new Map<string, string>();\n\tconst reverseMap = new Map<string, string>();\n\n\treturn (id: string): string => {\n\t\tconst existing = idMap.get(id);\n\t\tif (existing) return existing;\n\n\t\tlet attempt = 0;\n\t\twhile (true) {\n\t\t\tconst candidate = deriveMistralToolCallId(id, attempt);\n\t\t\tconst owner = reverseMap.get(candidate);\n\t\t\tif (!owner || owner === id) {\n\t\t\t\tidMap.set(id, candidate);\n\t\t\t\treverseMap.set(candidate, id);\n\t\t\t\treturn candidate;\n\t\t\t}\n\t\t\tattempt++;\n\t\t}\n\t};\n}\n\nfunction deriveMistralToolCallId(id: string, attempt: number): string {\n\tconst normalized = id.replace(/[^a-zA-Z0-9]/g, \"\");\n\tif (attempt === 0 && normalized.length === MISTRAL_TOOL_CALL_ID_LENGTH) return normalized;\n\tconst seedBase = normalized || id;\n\tconst seed = attempt === 0 ? seedBase : `${seedBase}:${attempt}`;\n\treturn shortHash(seed)\n\t\t.replace(/[^a-zA-Z0-9]/g, \"\")\n\t\t.slice(0, MISTRAL_TOOL_CALL_ID_LENGTH);\n}\n\nfunction formatMistralError(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tconst httpError = error as Error & { statusCode?: unknown; body?: unknown };\n\t\tconst statusCode = typeof httpError.statusCode === \"number\" ? httpError.statusCode : undefined;\n\t\tconst bodyText = typeof httpError.body === \"string\" ? httpError.body.trim() : undefined;\n\t\tif (statusCode !== undefined && bodyText) {\n\t\t\treturn `Mistral API error (${statusCode}): ${truncateErrorText(bodyText, MAX_MISTRAL_ERROR_BODY_CHARS)}`;\n\t\t}\n\t\tif (statusCode !== undefined) return `Mistral API error (${statusCode}): ${error.message}`;\n\t\treturn error.message;\n\t}\n\treturn safeJsonStringify(error);\n}\n\nfunction truncateErrorText(text: string, maxChars: number): string {\n\tif (text.length <= maxChars) return text;\n\treturn `${text.slice(0, maxChars)}... [truncated ${text.length - maxChars} chars]`;\n}\n\nfunction safeJsonStringify(value: unknown): string {\n\ttry {\n\t\tconst serialized = JSON.stringify(value);\n\t\treturn serialized === undefined ? String(value) : serialized;\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nasync function requestMistralStream(\n\tmodel: Model<\"mistral-conversations\">,\n\tpayload: MistralChatPayload,\n\tapiKey: string,\n\toptions?: MistralOptions,\n\trequestSignal?: AbortSignal,\n): Promise<AsyncIterable<MistralCompletionEvent>> {\n\tconst baseUrl = new URL(model.baseUrl);\n\tbaseUrl.pathname = `${baseUrl.pathname.replace(/\\/+$/u, \"\")}/`;\n\tconst url = new URL(\"v1/chat/completions\", baseUrl);\n\tconst headers = buildMistralHeaders(model, apiKey, options);\n\tconst timeoutSignal = AbortSignal.timeout(options?.timeoutMs ?? 60_000);\n\tconst signal = requestSignal ? AbortSignal.any([requestSignal, timeoutSignal]) : timeoutSignal;\n\tconst response = await (options?.fetch ?? globalThis.fetch)(url, {\n\t\tmethod: \"POST\",\n\t\theaders,\n\t\tbody: JSON.stringify(toMistralWirePayload(payload)),\n\t\tsignal,\n\t});\n\n\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\n\tif (!response.ok) {\n\t\tconst body = await response.text();\n\t\tthrow new MistralHttpError(response.status, body, response.statusText);\n\t}\n\tif (!response.body) {\n\t\tthrow new Error(\"Mistral response has no body\");\n\t}\n\n\treturn readMistralEvents(response.body, signal);\n}\n\nclass MistralHttpError extends Error {\n\tstatusCode: number;\n\tbody: string;\n\n\tconstructor(statusCode: number, body: string, statusText: string) {\n\t\tsuper(statusText || `Request failed with status ${statusCode}`);\n\t\tthis.name = \"MistralHttpError\";\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t}\n}\n\nfunction buildMistralHeaders(model: Model<\"mistral-conversations\">, apiKey: string, options?: MistralOptions): Headers {\n\tconst headers = new Headers({\n\t\t\"User-Agent\": getPiUserAgent(),\n\t\taccept: \"text/event-stream\",\n\t\tauthorization: `Bearer ${apiKey}`,\n\t\t\"content-type\": \"application/json\",\n\t});\n\tapplyMistralHeaderOverrides(headers, model.headers);\n\tapplyMistralHeaderOverrides(headers, options?.headers);\n\n\tconst hasExplicitAffinity =\n\t\thasMistralHeaderOverride(model.headers, \"x-affinity\") || hasMistralHeaderOverride(options?.headers, \"x-affinity\");\n\tif (shouldUsePromptCaching(options) && !hasExplicitAffinity) {\n\t\theaders.set(\"x-affinity\", options.sessionId);\n\t}\n\n\treturn headers;\n}\n\nfunction applyMistralHeaderOverrides(headers: Headers, overrides?: Record<string, string | null>): void {\n\tif (!overrides) return;\n\tfor (const [name, value] of Object.entries(overrides)) {\n\t\tif (value === null) headers.delete(name);\n\t\telse headers.set(name, value);\n\t}\n}\n\nfunction hasMistralHeaderOverride(overrides: Record<string, string | null> | undefined, target: string): boolean {\n\treturn !!overrides && Object.keys(overrides).some((name) => name.toLowerCase() === target);\n}\n\nfunction toMistralWirePayload(payload: MistralChatPayload): Record<string, unknown> {\n\tconst wirePayload: Record<string, unknown> = { ...payload };\n\tfor (const [source, target] of [\n\t\t[\"topP\", \"top_p\"],\n\t\t[\"maxTokens\", \"max_tokens\"],\n\t\t[\"randomSeed\", \"random_seed\"],\n\t\t[\"responseFormat\", \"response_format\"],\n\t\t[\"toolChoice\", \"tool_choice\"],\n\t\t[\"presencePenalty\", \"presence_penalty\"],\n\t\t[\"frequencyPenalty\", \"frequency_penalty\"],\n\t\t[\"parallelToolCalls\", \"parallel_tool_calls\"],\n\t\t[\"reasoningEffort\", \"reasoning_effort\"],\n\t\t[\"promptMode\", \"prompt_mode\"],\n\t\t[\"promptCacheKey\", \"prompt_cache_key\"],\n\t\t[\"safePrompt\", \"safe_prompt\"],\n\t] as const) {\n\t\tremapMistralProperty(wirePayload, source, target);\n\t}\n\twirePayload.messages = payload.messages.map((message) => toMistralWireMessage(message));\n\n\tconst responseFormat = wirePayload.response_format;\n\tif (isMistralRecord(responseFormat)) {\n\t\tconst wireResponseFormat = { ...responseFormat };\n\t\tremapMistralProperty(wireResponseFormat, \"jsonSchema\", \"json_schema\");\n\t\tconst jsonSchema = wireResponseFormat.json_schema;\n\t\tif (isMistralRecord(jsonSchema)) {\n\t\t\tconst wireJsonSchema = { ...jsonSchema };\n\t\t\tremapMistralProperty(wireJsonSchema, \"schemaDefinition\", \"schema\");\n\t\t\twireResponseFormat.json_schema = wireJsonSchema;\n\t\t}\n\t\twirePayload.response_format = wireResponseFormat;\n\t}\n\n\treturn wirePayload;\n}\n\nfunction toMistralWireMessage(message: MistralChatMessage): Record<string, unknown> {\n\tconst wireMessage: Record<string, unknown> = { ...message };\n\tremapMistralProperty(wireMessage, \"toolCalls\", \"tool_calls\");\n\tremapMistralProperty(wireMessage, \"toolCallId\", \"tool_call_id\");\n\tif (Array.isArray(message.content)) {\n\t\twireMessage.content = message.content.map((chunk) => toMistralWireContentChunk(chunk));\n\t}\n\treturn wireMessage;\n}\n\nfunction toMistralWireContentChunk(chunk: MistralContentChunk): Record<string, unknown> {\n\tconst wireChunk: Record<string, unknown> = { ...chunk };\n\tfor (const [source, target] of [\n\t\t[\"imageUrl\", \"image_url\"],\n\t\t[\"documentUrl\", \"document_url\"],\n\t\t[\"documentName\", \"document_name\"],\n\t\t[\"fileId\", \"file_id\"],\n\t\t[\"referenceIds\", \"reference_ids\"],\n\t\t[\"inputAudio\", \"input_audio\"],\n\t] as const) {\n\t\tremapMistralProperty(wireChunk, source, target);\n\t}\n\treturn wireChunk;\n}\n\nfunction remapMistralProperty(record: Record<string, unknown>, source: string, target: string): void {\n\tif (!(source in record)) return;\n\trecord[target] = record[source];\n\tdelete record[source];\n}\n\nfunction isMistralRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst MISTRAL_STREAM_DONE = Symbol(\"mistral-stream-done\");\n\nasync function* readMistralEvents(\n\tbody: ReadableStream<Uint8Array>,\n\tsignal: AbortSignal,\n): AsyncGenerator<MistralCompletionEvent> {\n\tconst reader = body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet buffer = \"\";\n\tconst onAbort = () => {\n\t\tvoid reader.cancel().catch(() => {});\n\t};\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\n\ttry {\n\t\twhile (true) {\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tbuffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n\n\t\t\tlet boundary = findMistralEventBoundary(buffer);\n\t\t\twhile (boundary) {\n\t\t\t\tconst event = parseMistralEvent(buffer.slice(0, boundary.index));\n\t\t\t\tbuffer = buffer.slice(boundary.index + boundary.length);\n\t\t\t\tif (event === MISTRAL_STREAM_DONE) return;\n\t\t\t\tif (event) yield event;\n\t\t\t\tboundary = findMistralEventBoundary(buffer);\n\t\t\t}\n\n\t\t\tif (done) break;\n\t\t}\n\n\t\tif (buffer.trim()) {\n\t\t\tconst event = parseMistralEvent(buffer);\n\t\t\tif (event !== MISTRAL_STREAM_DONE && event) yield event;\n\t\t}\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\ttry {\n\t\t\tawait reader.cancel();\n\t\t} catch {}\n\t\ttry {\n\t\t\treader.releaseLock();\n\t\t} catch {}\n\t}\n}\n\nfunction findMistralEventBoundary(buffer: string): { index: number; length: number } | undefined {\n\tconst match = /\\r\\n\\r\\n|\\r\\n\\r|\\r\\n\\n|\\r\\r\\n|\\n\\r\\n|\\r\\r|\\n\\r|\\n\\n/u.exec(buffer);\n\treturn match?.index === undefined ? undefined : { index: match.index, length: match[0].length };\n}\n\nfunction parseMistralEvent(raw: string): MistralCompletionEvent | typeof MISTRAL_STREAM_DONE | undefined {\n\tconst data = raw\n\t\t.split(/\\r\\n|\\r|\\n/u)\n\t\t.filter((line) => line.startsWith(\"data:\"))\n\t\t.map((line) => line.slice(5).trimStart())\n\t\t.join(\"\\n\")\n\t\t.trim();\n\tif (!data) return undefined;\n\tif (data === \"[DONE]\") return MISTRAL_STREAM_DONE;\n\n\tconst parsed: unknown = JSON.parse(data);\n\tif (!isMistralRecord(parsed) || !Array.isArray(parsed.choices)) {\n\t\tthrow new Error(\"Invalid Mistral streaming event\");\n\t}\n\treturn { data: parsed as MistralCompletionEvent[\"data\"] };\n}\n\nfunction buildChatPayload(\n\tmodel: Model<\"mistral-conversations\">,\n\tcontext: TranscriptContext,\n\tmessages: Message[],\n\toptions?: MistralOptions,\n): MistralChatPayload {\n\tconst payload: MistralChatPayload = {\n\t\tmodel: model.id,\n\t\tstream: true,\n\t\tmessages: toChatMessages(messages, model.input.includes(\"image\")),\n\t};\n\n\tconst currentTools = getCurrentTools(context.messages);\n\tif (currentTools.length > 0) payload.tools = toFunctionTools(currentTools);\n\tif (options?.temperature !== undefined) payload.temperature = options.temperature;\n\tif (options?.maxTokens !== undefined) payload.maxTokens = options.maxTokens;\n\tif (options?.toolChoice) payload.toolChoice = mapToolChoice(options.toolChoice);\n\tif (options?.promptMode) payload.promptMode = options.promptMode;\n\tif (options?.reasoningEffort) payload.reasoningEffort = options.reasoningEffort;\n\tif (shouldUsePromptCaching(options)) payload.promptCacheKey = options.sessionId;\n\n\treturn payload;\n}\n\nfunction shouldUsePromptCaching(options?: MistralOptions): options is MistralOptions & { sessionId: string } {\n\treturn options?.cacheRetention !== \"none\" && !!options?.sessionId;\n}\n\nfunction getMistralCachedPromptTokens(usage: unknown, promptTokens: number): number {\n\tconst rawUsage = usage as {\n\t\tpromptTokensDetails?: { cachedTokens?: unknown } | null;\n\t\tprompt_tokens_details?: { cached_tokens?: unknown } | null;\n\t\tpromptTokenDetails?: { cachedTokens?: unknown } | null;\n\t\tprompt_token_details?: { cached_tokens?: unknown } | null;\n\t\tnumCachedTokens?: unknown;\n\t\tnum_cached_tokens?: unknown;\n\t};\n\tconst rawCachedTokens =\n\t\trawUsage.promptTokensDetails?.cachedTokens ??\n\t\trawUsage.prompt_tokens_details?.cached_tokens ??\n\t\trawUsage.promptTokenDetails?.cachedTokens ??\n\t\trawUsage.prompt_token_details?.cached_tokens ??\n\t\trawUsage.numCachedTokens ??\n\t\trawUsage.num_cached_tokens ??\n\t\t0;\n\tconst cachedTokens = typeof rawCachedTokens === \"number\" && Number.isFinite(rawCachedTokens) ? rawCachedTokens : 0;\n\treturn Math.min(promptTokens, Math.max(0, cachedTokens));\n}\n\nasync function consumeChatStream(\n\tmodel: Model<\"mistral-conversations\">,\n\toutput: AssistantMessage,\n\tstream: AssistantMessageEventStream,\n\tmistralStream: AsyncIterable<MistralCompletionEvent>,\n): Promise<void> {\n\tlet currentBlock: TextContent | ThinkingContent | null = null;\n\tconst blocks = output.content;\n\tconst blockIndex = () => blocks.length - 1;\n\tconst toolBlocksByKey = new Map<string | number, number>();\n\n\tconst finishCurrentBlock = (block?: typeof currentBlock) => {\n\t\tif (!block) return;\n\t\tif (block.type === \"text\") {\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_end\",\n\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\tcontent: block.text,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (block.type === \"thinking\") {\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_end\",\n\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\tcontent: block.thinking,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t};\n\n\tfor await (const event of mistralStream) {\n\t\tconst chunk = event.data;\n\t\t// Mistral's streamed CompletionChunk carries an id field. Keep the first non-empty one,\n\t\t// mirroring how OpenAI-style streaming exposes a stable response identifier per stream.\n\t\toutput.responseId ||= chunk.id;\n\n\t\tif (chunk.usage) {\n\t\t\tconst promptTokens = chunk.usage.prompt_tokens || 0;\n\t\t\tconst cachedPromptTokens = getMistralCachedPromptTokens(chunk.usage, promptTokens);\n\n\t\t\toutput.usage.input = Math.max(0, promptTokens - cachedPromptTokens);\n\t\t\toutput.usage.output = chunk.usage.completion_tokens || 0;\n\t\t\toutput.usage.cacheRead = cachedPromptTokens;\n\t\t\toutput.usage.cacheWrite = 0;\n\t\t\toutput.usage.totalTokens =\n\t\t\t\tchunk.usage.total_tokens ||\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t}\n\n\t\tconst choice = chunk.choices[0];\n\t\tif (!choice) continue;\n\n\t\tif (choice.finish_reason) {\n\t\t\toutput.rawStopReason = choice.finish_reason;\n\t\t\tconst stopReasonResult = mapChatStopReason(choice.finish_reason);\n\t\t\toutput.stopReason = stopReasonResult.stopReason;\n\t\t\tif (stopReasonResult.errorMessage) {\n\t\t\t\toutput.errorMessage = stopReasonResult.errorMessage;\n\t\t\t}\n\t\t}\n\n\t\tconst delta = choice.delta;\n\t\tif (delta.content !== null && delta.content !== undefined) {\n\t\t\tconst contentItems = typeof delta.content === \"string\" ? [delta.content] : delta.content;\n\t\t\tfor (const item of contentItems) {\n\t\t\t\tif (typeof item === \"string\") {\n\t\t\t\t\tconst textDelta = sanitizeSurrogates(item);\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"text\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.text += textDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: textDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (item.type === \"thinking\") {\n\t\t\t\t\tconst deltaText = (item.thinking ?? [])\n\t\t\t\t\t\t.map((part) => part.text ?? \"\")\n\t\t\t\t\t\t.filter((text) => text.length > 0)\n\t\t\t\t\t\t.join(\"\");\n\t\t\t\t\tconst thinkingDelta = sanitizeSurrogates(deltaText);\n\t\t\t\t\tif (!thinkingDelta) continue;\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"thinking\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"thinking\", thinking: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.thinking += thinkingDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: thinkingDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\tconst textDelta = sanitizeSurrogates(item.text ?? \"\");\n\t\t\t\t\tif (!currentBlock || currentBlock.type !== \"text\") {\n\t\t\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\t\t\tcurrentBlock = { type: \"text\", text: \"\" };\n\t\t\t\t\t\toutput.content.push(currentBlock);\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tcurrentBlock.text += textDelta;\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\tcontentIndex: blockIndex(),\n\t\t\t\t\t\tdelta: textDelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst toolCalls = delta.tool_calls || [];\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tif (currentBlock) {\n\t\t\t\tfinishCurrentBlock(currentBlock);\n\t\t\t\tcurrentBlock = null;\n\t\t\t}\n\t\t\tconst callId =\n\t\t\t\ttoolCall.id && toolCall.id !== \"null\"\n\t\t\t\t\t? toolCall.id\n\t\t\t\t\t: deriveMistralToolCallId(`toolcall:${toolCall.index ?? 0}`, 0);\n\t\t\tconst key = toolCall.index ?? callId;\n\t\t\tconst existingIndex = toolBlocksByKey.get(key);\n\t\t\tlet block: (ToolCall & { partialArgs?: string }) | undefined;\n\n\t\t\tif (existingIndex !== undefined) {\n\t\t\t\tconst existing = output.content[existingIndex];\n\t\t\t\tif (existing?.type === \"toolCall\") {\n\t\t\t\t\tblock = existing as ToolCall & { partialArgs?: string };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!block) {\n\t\t\t\tblock = {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\tid: callId,\n\t\t\t\t\tname: toolCall.function.name,\n\t\t\t\t\targuments: {},\n\t\t\t\t\tpartialArgs: \"\",\n\t\t\t\t};\n\t\t\t\toutput.content.push(block);\n\t\t\t\ttoolBlocksByKey.set(key, output.content.length - 1);\n\t\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: output.content.length - 1, partial: output });\n\t\t\t}\n\n\t\t\tconst argsDelta =\n\t\t\t\ttypeof toolCall.function.arguments === \"string\"\n\t\t\t\t\t? toolCall.function.arguments\n\t\t\t\t\t: JSON.stringify(toolCall.function.arguments || {});\n\t\t\tblock.partialArgs = (block.partialArgs || \"\") + argsDelta;\n\t\t\tblock.arguments = parseStreamingJson<ToolCall[\"arguments\"]>(block.partialArgs);\n\t\t\tstream.push({\n\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\tcontentIndex: toolBlocksByKey.get(key)!,\n\t\t\t\tdelta: argsDelta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t}\n\t}\n\n\tfinishCurrentBlock(currentBlock);\n\tfor (const index of toolBlocksByKey.values()) {\n\t\tconst block = output.content[index];\n\t\tif (block.type !== \"toolCall\") continue;\n\t\tconst toolBlock = block as ToolCall & { partialArgs?: string };\n\t\ttoolBlock.arguments = parseStreamingJson<ToolCall[\"arguments\"]>(toolBlock.partialArgs);\n\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t// carries parsed arguments.\n\t\tdelete toolBlock.partialArgs;\n\t\tstream.push({\n\t\t\ttype: \"toolcall_end\",\n\t\t\tcontentIndex: index,\n\t\t\ttoolCall: toolBlock,\n\t\t\tpartial: output,\n\t\t});\n\t}\n}\n\nfunction toFunctionTools(tools: Tool[]): MistralFunctionTool[] {\n\treturn tools.map((tool) => {\n\t\tconst strict = resolveJsonSchemaStrictSampling(tool, true);\n\t\treturn {\n\t\t\ttype: \"function\",\n\t\t\tfunction: {\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparameters: stripSymbolKeys(getJsonSchemaToolParameters(tool, strict)) as Record<string, unknown>,\n\t\t\t\tstrict: strict ?? false,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction stripSymbolKeys(value: unknown): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item) => stripSymbolKeys(item));\n\t}\n\n\tif (value && typeof value === \"object\") {\n\t\tconst result: Record<string, unknown> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tresult[key] = stripSymbolKeys(entry);\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn value;\n}\n\nfunction toChatMessages(messages: Message[], supportsImages: boolean): MistralChatMessage[] {\n\tconst result: MistralChatMessage[] = [];\n\n\tfor (const [index, msg] of messages.entries()) {\n\t\tif (msg.role === \"system\") {\n\t\t\tconst text = index === 0 ? getSystemMessageText(msg) : renderSystemMessageUpdate(msg);\n\t\t\tif (text.length > 0) result.push({ role: \"system\", content: sanitizeSurrogates(text) });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tresult.push({ role: \"user\", content: sanitizeSurrogates(msg.content) });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst hadImages = msg.content.some((item) => item.type === \"image\");\n\t\t\tconst content: MistralContentChunk[] = msg.content\n\t\t\t\t.filter((item) => item.type === \"text\" || supportsImages)\n\t\t\t\t.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") return { type: \"text\", text: sanitizeSurrogates(item.text) };\n\t\t\t\t\treturn { type: \"image_url\", imageUrl: `data:${item.mimeType};base64,${item.data}` };\n\t\t\t\t});\n\t\t\tif (content.length > 0) {\n\t\t\t\tresult.push({ role: \"user\", content });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (hadImages && !supportsImages) {\n\t\t\t\tresult.push({ role: \"user\", content: \"(image omitted: model does not support images)\" });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst contentParts: MistralContentChunk[] = [];\n\t\t\tconst toolCalls: MistralRequestToolCall[] = [];\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) {\n\t\t\t\t\t\tcontentParts.push({ type: \"text\", text: sanitizeSurrogates(block.text) });\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\tif (block.thinking.trim().length > 0) {\n\t\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\tthinking: [{ type: \"text\", text: sanitizeSurrogates(block.thinking) }],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Anthropic server-side fallback markers have no Mistral representation and carry no\n\t\t\t\t// content; skip them rather than mis-serializing them as a tool call.\n\t\t\t\tif (block.type !== \"toolCall\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\ttoolCalls.push({\n\t\t\t\t\tid: block.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: { name: block.name, arguments: JSON.stringify(block.arguments || {}) },\n\t\t\t\t\tindex: 0,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst assistantMessage: MistralChatMessage = { role: \"assistant\", prefix: false };\n\t\t\tif (contentParts.length > 0) assistantMessage.content = contentParts;\n\t\t\tif (toolCalls.length > 0) assistantMessage.toolCalls = toolCalls;\n\t\t\tif (contentParts.length > 0 || toolCalls.length > 0) result.push(assistantMessage);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst toolContent: MistralContentChunk[] = [];\n\t\tconst textResult = msg.content\n\t\t\t.filter((part) => part.type === \"text\")\n\t\t\t.map((part) => (part.type === \"text\" ? sanitizeSurrogates(part.text) : \"\"))\n\t\t\t.join(\"\\n\");\n\t\tconst hasImages = msg.content.some((part) => part.type === \"image\");\n\t\tconst toolText = buildToolResultText(textResult, hasImages, supportsImages, msg.isError);\n\t\ttoolContent.push({ type: \"text\", text: toolText });\n\t\tfor (const part of msg.content) {\n\t\t\tif (!supportsImages) continue;\n\t\t\tif (part.type !== \"image\") continue;\n\t\t\ttoolContent.push({\n\t\t\t\ttype: \"image_url\",\n\t\t\t\timageUrl: `data:${part.mimeType};base64,${part.data}`,\n\t\t\t});\n\t\t}\n\t\tresult.push({\n\t\t\trole: \"tool\",\n\t\t\ttoolCallId: msg.toolCallId,\n\t\t\tname: msg.toolName,\n\t\t\tcontent: toolContent,\n\t\t});\n\t}\n\n\treturn result;\n}\n\nfunction buildToolResultText(text: string, hasImages: boolean, supportsImages: boolean, isError: boolean): string {\n\tconst trimmed = text.trim();\n\tconst errorPrefix = isError ? \"[tool error] \" : \"\";\n\n\tif (trimmed.length > 0) {\n\t\tconst imageSuffix = hasImages && !supportsImages ? \"\\n[tool image omitted: model does not support images]\" : \"\";\n\t\treturn `${errorPrefix}${trimmed}${imageSuffix}`;\n\t}\n\n\tif (hasImages) {\n\t\tif (supportsImages) {\n\t\t\treturn isError ? \"[tool error] (see attached image)\" : \"(see attached image)\";\n\t\t}\n\t\treturn isError\n\t\t\t? \"[tool error] (image omitted: model does not support images)\"\n\t\t\t: \"(image omitted: model does not support images)\";\n\t}\n\n\treturn isError ? \"[tool error] (no tool output)\" : \"(no tool output)\";\n}\n\nfunction usesReasoningEffort(model: Model<\"mistral-conversations\">): boolean {\n\treturn (\n\t\tmodel.id === \"mistral-small-2603\" ||\n\t\tmodel.id === \"mistral-small-latest\" ||\n\t\tmodel.id.startsWith(\"mistral-medium-\") ||\n\t\tmodel.id === \"zai-glm-5-2\"\n\t);\n}\n\nfunction usesPromptModeReasoning(model: Model<\"mistral-conversations\">): boolean {\n\treturn model.reasoning && !usesReasoningEffort(model);\n}\n\nfunction mapReasoningEffort(\n\tmodel: Model<\"mistral-conversations\">,\n\tlevel: Exclude<SimpleStreamOptions[\"reasoning\"], undefined>,\n): MistralReasoningEffort {\n\treturn (model.thinkingLevelMap?.[level] ?? \"high\") as MistralReasoningEffort;\n}\n\nfunction mapToolChoice(\n\tchoice: MistralOptions[\"toolChoice\"],\n): \"auto\" | \"none\" | \"any\" | \"required\" | { type: \"function\"; function: { name: string } } | undefined {\n\tif (!choice) return undefined;\n\tif (choice === \"auto\" || choice === \"none\" || choice === \"any\" || choice === \"required\") {\n\t\treturn choice;\n\t}\n\treturn {\n\t\ttype: \"function\",\n\t\tfunction: { name: choice.function.name },\n\t};\n}\n\nfunction mapChatStopReason(reason: string | null): { stopReason: StopReason; errorMessage?: string } {\n\tif (reason === null) return { stopReason: \"stop\" };\n\tswitch (reason) {\n\t\tcase \"stop\":\n\t\t\treturn { stopReason: \"stop\" };\n\t\tcase \"length\":\n\t\tcase \"model_length\":\n\t\t\treturn { stopReason: \"length\" };\n\t\tcase \"tool_calls\":\n\t\t\treturn { stopReason: \"toolUse\" };\n\t\tcase \"error\":\n\t\t\treturn { stopReason: \"error\", errorMessage: \"Provider stopped with: error\" };\n\t\tdefault:\n\t\t\treturn { stopReason: \"error\", errorMessage: `Provider stopped with: ${reason}` };\n\t}\n}\n"]}
|
|
@@ -6,6 +6,8 @@ import { parseStreamingJson } from "../utils/json-parse.js";
|
|
|
6
6
|
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
7
7
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
8
8
|
import { createStreamDeadline, withStreamDeadline } from "../utils/stream-deadline.js";
|
|
9
|
+
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
10
|
+
import { getCurrentTools, resolveTranscript } from "../utils/transcript.js";
|
|
9
11
|
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
10
12
|
import { buildBaseOptions } from "./simple-options.js";
|
|
11
13
|
import { transformMessages } from "./transform-messages.js";
|
|
@@ -16,6 +18,7 @@ const MAX_MISTRAL_ERROR_BODY_CHARS = 4000;
|
|
|
16
18
|
*/
|
|
17
19
|
export const stream = (model, context, options) => {
|
|
18
20
|
const stream = new AssistantMessageEventStream();
|
|
21
|
+
const normalizedContext = resolveTranscript(context, model.compat?.supportsMidConvoSystemMessages);
|
|
19
22
|
(async () => {
|
|
20
23
|
const output = createOutput(model);
|
|
21
24
|
const streamDeadline = createStreamDeadline(options?.streamDeadlineMs, options?.signal);
|
|
@@ -25,8 +28,8 @@ export const stream = (model, context, options) => {
|
|
|
25
28
|
throw new Error(`No API key for provider: ${model.provider}`);
|
|
26
29
|
}
|
|
27
30
|
const normalizeMistralToolCallId = createMistralToolCallIdNormalizer();
|
|
28
|
-
const transformedMessages = transformMessages(
|
|
29
|
-
let payload = buildChatPayload(model,
|
|
31
|
+
const transformedMessages = transformMessages(normalizedContext.messages, model, (id) => normalizeMistralToolCallId(id));
|
|
32
|
+
let payload = buildChatPayload(model, normalizedContext, transformedMessages, options);
|
|
30
33
|
const nextPayload = await options?.onPayload?.(payload, model);
|
|
31
34
|
if (nextPayload !== undefined) {
|
|
32
35
|
payload = nextPayload;
|
|
@@ -361,8 +364,9 @@ function buildChatPayload(model, context, messages, options) {
|
|
|
361
364
|
stream: true,
|
|
362
365
|
messages: toChatMessages(messages, model.input.includes("image")),
|
|
363
366
|
};
|
|
364
|
-
|
|
365
|
-
|
|
367
|
+
const currentTools = getCurrentTools(context.messages);
|
|
368
|
+
if (currentTools.length > 0)
|
|
369
|
+
payload.tools = toFunctionTools(currentTools);
|
|
366
370
|
if (options?.temperature !== undefined)
|
|
367
371
|
payload.temperature = options.temperature;
|
|
368
372
|
if (options?.maxTokens !== undefined)
|
|
@@ -375,12 +379,6 @@ function buildChatPayload(model, context, messages, options) {
|
|
|
375
379
|
payload.reasoningEffort = options.reasoningEffort;
|
|
376
380
|
if (shouldUsePromptCaching(options))
|
|
377
381
|
payload.promptCacheKey = options.sessionId;
|
|
378
|
-
if (context.systemPrompt) {
|
|
379
|
-
payload.messages.unshift({
|
|
380
|
-
role: "system",
|
|
381
|
-
content: sanitizeSurrogates(context.systemPrompt),
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
382
|
return payload;
|
|
385
383
|
}
|
|
386
384
|
function shouldUsePromptCaching(options) {
|
|
@@ -604,7 +602,13 @@ function stripSymbolKeys(value) {
|
|
|
604
602
|
}
|
|
605
603
|
function toChatMessages(messages, supportsImages) {
|
|
606
604
|
const result = [];
|
|
607
|
-
for (const msg of messages) {
|
|
605
|
+
for (const [index, msg] of messages.entries()) {
|
|
606
|
+
if (msg.role === "system") {
|
|
607
|
+
const text = index === 0 ? getSystemMessageText(msg) : renderSystemMessageUpdate(msg);
|
|
608
|
+
if (text.length > 0)
|
|
609
|
+
result.push({ role: "system", content: sanitizeSurrogates(text) });
|
|
610
|
+
continue;
|
|
611
|
+
}
|
|
608
612
|
if (msg.role === "user") {
|
|
609
613
|
if (typeof msg.content === "string") {
|
|
610
614
|
result.push({ role: "user", content: sanitizeSurrogates(msg.content) });
|