@bastani/pi-ai 0.9.19 → 0.9.20-alpha.10
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 +83 -1
- package/NOTICE.md +1 -1
- package/README.md +203 -30
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +255 -97
- 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 +21 -6
- 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 +20 -15
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.d.ts +4 -0
- package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -0
- package/dist/api/cloudflare-workers-ai-system-one.js +43 -0
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -0
- package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts +3 -0
- package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts.map +1 -0
- package/dist/api/cloudflare-workers-ai-system-one.lazy.js +4 -0
- package/dist/api/cloudflare-workers-ai-system-one.lazy.js.map +1 -0
- package/dist/api/cloudflare.d.ts +2 -0
- package/dist/api/cloudflare.d.ts.map +1 -1
- package/dist/api/cloudflare.js +2 -0
- package/dist/api/cloudflare.js.map +1 -1
- package/dist/api/constrained-sampling.d.ts +8 -3
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +29 -11
- package/dist/api/constrained-sampling.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +23 -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 +26 -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 +18 -13
- 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 +40 -26
- 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 +44 -58
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +11 -5
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +65 -58
- 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 +15 -19
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.d.ts +2 -1
- package/dist/api/openrouter-images.d.ts.map +1 -1
- package/dist/api/openrouter-images.js +1 -0
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/openrouter-images.lazy.d.ts.map +1 -1
- package/dist/api/openrouter-images.lazy.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 +3 -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 +1 -0
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +23 -0
- package/dist/api/system-one-shared.d.ts.map +1 -0
- package/dist/api/system-one-shared.js +170 -0
- package/dist/api/system-one-shared.js.map +1 -0
- 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/api/typesafe-system-one.d.ts +4 -0
- package/dist/api/typesafe-system-one.d.ts.map +1 -0
- package/dist/api/typesafe-system-one.js +19 -0
- package/dist/api/typesafe-system-one.js.map +1 -0
- package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
- package/dist/api/typesafe-system-one.lazy.d.ts.map +1 -0
- package/dist/api/typesafe-system-one.lazy.js +4 -0
- package/dist/api/typesafe-system-one.lazy.js.map +1 -0
- 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/oauth/load.d.ts +2 -0
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -0
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/oauth/meta.d.ts +17 -0
- package/dist/auth/oauth/meta.d.ts.map +1 -0
- package/dist/auth/oauth/meta.js +190 -0
- package/dist/auth/oauth/meta.js.map +1 -0
- package/dist/auth/resolve.d.ts +6 -8
- package/dist/auth/resolve.d.ts.map +1 -1
- package/dist/auth/resolve.js +29 -26
- package/dist/auth/resolve.js.map +1 -1
- package/dist/bun-oauth.d.ts.map +1 -1
- package/dist/bun-oauth.js +2 -0
- package/dist/bun-oauth.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/decision-models.d.ts +21 -0
- package/dist/decision-models.d.ts.map +1 -0
- package/dist/decision-models.generated.d.ts +3 -0
- package/dist/decision-models.generated.d.ts.map +1 -0
- package/dist/decision-models.generated.js +47 -0
- package/dist/decision-models.generated.js.map +1 -0
- package/dist/decision-models.js +8 -0
- package/dist/decision-models.js.map +1 -0
- 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 +61 -43
- package/dist/env-api-keys.js.map +1 -1
- package/dist/image-models.d.ts +19 -8
- package/dist/image-models.d.ts.map +1 -1
- package/dist/image-models.js +14 -13
- package/dist/image-models.js.map +1 -1
- package/dist/images-api-registry.d.ts +7 -7
- package/dist/images-api-registry.d.ts.map +1 -1
- package/dist/images-api-registry.js.map +1 -1
- package/dist/images.d.ts +7 -2
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +5 -0
- package/dist/images.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/model-catalog.d.ts +25 -9
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +14 -2
- package/dist/model-catalog.js.map +1 -1
- package/dist/models-store.d.ts +3 -2
- package/dist/models-store.d.ts.map +1 -1
- package/dist/models-store.js.map +1 -1
- package/dist/models.d.ts +99 -31
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +133 -39
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +133 -39
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +161 -31
- package/dist/models.js.map +1 -1
- package/dist/providers/all.d.ts +19 -13
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js +27 -21
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.d.ts +4 -3
- package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.models.js +4 -2
- package/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/dist/providers/ant-ling.models.d.ts +4 -3
- package/dist/providers/ant-ling.models.d.ts.map +1 -1
- package/dist/providers/ant-ling.models.js +4 -2
- package/dist/providers/ant-ling.models.js.map +1 -1
- package/dist/providers/anthropic.models.d.ts +4 -3
- package/dist/providers/anthropic.models.d.ts.map +1 -1
- package/dist/providers/anthropic.models.js +4 -2
- package/dist/providers/anthropic.models.js.map +1 -1
- package/dist/providers/azure-openai-responses.models.d.ts +4 -3
- package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
- package/dist/providers/azure-openai-responses.models.js +4 -2
- package/dist/providers/azure-openai-responses.models.js.map +1 -1
- package/dist/providers/baseten.models.d.ts +4 -3
- package/dist/providers/baseten.models.d.ts.map +1 -1
- package/dist/providers/baseten.models.js +4 -2
- package/dist/providers/baseten.models.js.map +1 -1
- package/dist/providers/cerebras.models.d.ts +4 -3
- package/dist/providers/cerebras.models.d.ts.map +1 -1
- package/dist/providers/cerebras.models.js +4 -2
- package/dist/providers/cerebras.models.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -3
- package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/dist/providers/cloudflare-stream.d.ts +6 -2
- package/dist/providers/cloudflare-stream.d.ts.map +1 -1
- package/dist/providers/cloudflare-stream.js +6 -0
- package/dist/providers/cloudflare-stream.js.map +1 -1
- package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
- package/dist/providers/cloudflare-workers-ai.js +10 -3
- package/dist/providers/cloudflare-workers-ai.js.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -3
- package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js +4 -2
- 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/ant-ling.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/azure-openai-responses.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/cloudflare-workers-ai.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/groq.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/meta.json +1 -0
- package/dist/providers/data/minimax-cn.json +1 -1
- package/dist/providers/data/minimax.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-individual.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/together.json +1 -1
- package/dist/providers/data/typesafe.json +1 -0
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.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 +4 -3
- package/dist/providers/deepseek.models.d.ts.map +1 -1
- package/dist/providers/deepseek.models.js +4 -2
- package/dist/providers/deepseek.models.js.map +1 -1
- package/dist/providers/faux.d.ts +3 -2
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +12 -11
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/fireworks.models.d.ts +4 -3
- package/dist/providers/fireworks.models.d.ts.map +1 -1
- package/dist/providers/fireworks.models.js +4 -2
- package/dist/providers/fireworks.models.js.map +1 -1
- package/dist/providers/github-copilot.models.d.ts +4 -3
- package/dist/providers/github-copilot.models.d.ts.map +1 -1
- package/dist/providers/github-copilot.models.js +4 -2
- package/dist/providers/github-copilot.models.js.map +1 -1
- package/dist/providers/google-vertex.models.d.ts +4 -3
- package/dist/providers/google-vertex.models.d.ts.map +1 -1
- package/dist/providers/google-vertex.models.js +4 -2
- package/dist/providers/google-vertex.models.js.map +1 -1
- package/dist/providers/google.models.d.ts +4 -3
- package/dist/providers/google.models.d.ts.map +1 -1
- package/dist/providers/google.models.js +4 -2
- package/dist/providers/google.models.js.map +1 -1
- package/dist/providers/groq.models.d.ts +4 -3
- package/dist/providers/groq.models.d.ts.map +1 -1
- package/dist/providers/groq.models.js +4 -2
- package/dist/providers/groq.models.js.map +1 -1
- package/dist/providers/huggingface.models.d.ts +4 -3
- package/dist/providers/huggingface.models.d.ts.map +1 -1
- package/dist/providers/huggingface.models.js +4 -2
- package/dist/providers/huggingface.models.js.map +1 -1
- package/dist/providers/images/register-builtins.d.ts +1 -1
- package/dist/providers/images/register-builtins.d.ts.map +1 -1
- package/dist/providers/images/register-builtins.js.map +1 -1
- package/dist/providers/kimi-coding.models.d.ts +4 -3
- package/dist/providers/kimi-coding.models.d.ts.map +1 -1
- package/dist/providers/kimi-coding.models.js +4 -2
- package/dist/providers/kimi-coding.models.js.map +1 -1
- package/dist/providers/meta.d.ts +3 -0
- package/dist/providers/meta.d.ts.map +1 -0
- package/dist/providers/meta.js +24 -0
- package/dist/providers/meta.js.map +1 -0
- package/dist/providers/meta.models.d.ts +5 -0
- package/dist/providers/meta.models.d.ts.map +1 -0
- package/dist/providers/meta.models.js +8 -0
- package/dist/providers/meta.models.js.map +1 -0
- package/dist/providers/minimax-cn.models.d.ts +4 -3
- package/dist/providers/minimax-cn.models.d.ts.map +1 -1
- package/dist/providers/minimax-cn.models.js +4 -2
- package/dist/providers/minimax-cn.models.js.map +1 -1
- package/dist/providers/minimax.models.d.ts +4 -3
- package/dist/providers/minimax.models.d.ts.map +1 -1
- package/dist/providers/minimax.models.js +4 -2
- package/dist/providers/minimax.models.js.map +1 -1
- package/dist/providers/mistral.models.d.ts +4 -3
- package/dist/providers/mistral.models.d.ts.map +1 -1
- package/dist/providers/mistral.models.js +4 -2
- package/dist/providers/mistral.models.js.map +1 -1
- package/dist/providers/moonshotai-cn.models.d.ts +4 -3
- package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
- package/dist/providers/moonshotai-cn.models.js +4 -2
- package/dist/providers/moonshotai-cn.models.js.map +1 -1
- package/dist/providers/moonshotai.models.d.ts +4 -3
- package/dist/providers/moonshotai.models.d.ts.map +1 -1
- package/dist/providers/moonshotai.models.js +4 -2
- package/dist/providers/moonshotai.models.js.map +1 -1
- package/dist/providers/nvidia.models.d.ts +4 -3
- package/dist/providers/nvidia.models.d.ts.map +1 -1
- package/dist/providers/nvidia.models.js +4 -2
- package/dist/providers/nvidia.models.js.map +1 -1
- package/dist/providers/openai-codex.models.d.ts +4 -3
- package/dist/providers/openai-codex.models.d.ts.map +1 -1
- package/dist/providers/openai-codex.models.js +4 -2
- package/dist/providers/openai-codex.models.js.map +1 -1
- package/dist/providers/openai.models.d.ts +4 -3
- package/dist/providers/openai.models.d.ts.map +1 -1
- package/dist/providers/openai.models.js +4 -2
- package/dist/providers/openai.models.js.map +1 -1
- package/dist/providers/opencode-go.models.d.ts +4 -3
- package/dist/providers/opencode-go.models.d.ts.map +1 -1
- package/dist/providers/opencode-go.models.js +4 -2
- package/dist/providers/opencode-go.models.js.map +1 -1
- package/dist/providers/opencode.models.d.ts +4 -3
- package/dist/providers/opencode.models.d.ts.map +1 -1
- package/dist/providers/opencode.models.js +4 -2
- package/dist/providers/opencode.models.js.map +1 -1
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +11 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/openrouter.models.d.ts +4 -3
- package/dist/providers/openrouter.models.d.ts.map +1 -1
- package/dist/providers/openrouter.models.js +4 -2
- package/dist/providers/openrouter.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -3
- package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js +4 -2
- package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-individual.models.d.ts +4 -3
- package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan-individual.models.js +4 -2
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
- package/dist/providers/qwen-token-plan.models.d.ts +4 -3
- package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
- package/dist/providers/qwen-token-plan.models.js +4 -2
- 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 +5 -0
- package/dist/providers/radius.models.d.ts.map +1 -0
- package/dist/providers/radius.models.js +8 -0
- package/dist/providers/radius.models.js.map +1 -0
- package/dist/providers/together.models.d.ts +4 -3
- package/dist/providers/together.models.d.ts.map +1 -1
- package/dist/providers/together.models.js +4 -2
- package/dist/providers/together.models.js.map +1 -1
- package/dist/providers/typesafe.d.ts +3 -0
- package/dist/providers/typesafe.d.ts.map +1 -0
- package/dist/providers/typesafe.js +18 -0
- package/dist/providers/typesafe.js.map +1 -0
- package/dist/providers/typesafe.models.d.ts +5 -0
- package/dist/providers/typesafe.models.d.ts.map +1 -0
- package/dist/providers/typesafe.models.js +8 -0
- package/dist/providers/typesafe.models.js.map +1 -0
- package/dist/providers/vercel-ai-gateway.models.d.ts +4 -3
- package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.js +4 -2
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/dist/providers/xai.models.d.ts +4 -3
- package/dist/providers/xai.models.d.ts.map +1 -1
- package/dist/providers/xai.models.js +4 -2
- package/dist/providers/xai.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -3
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
- package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -3
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
- package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -3
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
- package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/dist/providers/xiaomi.models.d.ts +4 -3
- package/dist/providers/xiaomi.models.d.ts.map +1 -1
- package/dist/providers/xiaomi.models.js +4 -2
- package/dist/providers/xiaomi.models.js.map +1 -1
- package/dist/providers/zai-coding-cn.models.d.ts +4 -3
- package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
- package/dist/providers/zai-coding-cn.models.js +4 -2
- package/dist/providers/zai-coding-cn.models.js.map +1 -1
- package/dist/providers/zai.models.d.ts +4 -3
- package/dist/providers/zai.models.d.ts.map +1 -1
- package/dist/providers/zai.models.js +4 -2
- package/dist/providers/zai.models.js.map +1 -1
- package/dist/types.d.ts +227 -51
- 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/headers.d.ts +1 -1
- package/dist/utils/headers.d.ts.map +1 -1
- package/dist/utils/headers.js +10 -8
- package/dist/utils/headers.js.map +1 -1
- package/dist/utils/model-operations.d.ts +11 -0
- package/dist/utils/model-operations.d.ts.map +1 -0
- package/dist/utils/model-operations.js +47 -0
- package/dist/utils/model-operations.js.map +1 -0
- package/dist/utils/models-error.d.ts +8 -0
- package/dist/utils/models-error.d.ts.map +1 -0
- package/dist/utils/models-error.js +19 -0
- package/dist/utils/models-error.js.map +1 -0
- 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 +4 -4
- package/dist/image-models.generated.d.ts +0 -785
- package/dist/image-models.generated.d.ts.map +0 -1
- package/dist/image-models.generated.js +0 -787
- package/dist/image-models.generated.js.map +0 -1
- package/dist/images-models.d.ts +0 -95
- package/dist/images-models.d.ts.map +0 -1
- package/dist/images-models.js +0 -143
- package/dist/images-models.js.map +0 -1
- package/dist/providers/openrouter-images.d.ts +0 -3
- package/dist/providers/openrouter-images.d.ts.map +0 -1
- package/dist/providers/openrouter-images.js +0 -22
- package/dist/providers/openrouter-images.js.map +0 -1
- 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,23 +1,19 @@
|
|
|
1
|
-
import { GoogleGenAI,
|
|
1
|
+
import { GoogleGenAI, } from "@google/genai";
|
|
2
2
|
import { calculateCost, clampThinkingLevel } from "../models.js";
|
|
3
3
|
import { formatProviderError, normalizeProviderError } from "../utils/error-body.js";
|
|
4
4
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
5
5
|
import { providerHeadersToRecord } from "../utils/headers.js";
|
|
6
6
|
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
7
7
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
8
|
-
import {
|
|
8
|
+
import { getSystemMessageText } from "../utils/text.js";
|
|
9
|
+
import { collapseSystemMessages, getCurrentTools, getInitialSystemMessage } from "../utils/transcript.js";
|
|
10
|
+
import { convertMessages, convertTools, getDisabledGoogleThinkingConfig, isThinkingPart, mapStopReason, resolveGoogleFunctionCallingMode, resolveGoogleThinkingLevel, retainThoughtSignature, retryGoogleRequest, supportsGoogleStrictToolSampling, toGoogleSdkThinkingLevel, toGoogleThinkingLevel, usesGoogleThinkingLevel, } from "./google-shared.js";
|
|
9
11
|
import { buildBaseOptions } from "./simple-options.js";
|
|
10
|
-
const THINKING_LEVEL_MAP = {
|
|
11
|
-
THINKING_LEVEL_UNSPECIFIED: ThinkingLevel.THINKING_LEVEL_UNSPECIFIED,
|
|
12
|
-
MINIMAL: ThinkingLevel.MINIMAL,
|
|
13
|
-
LOW: ThinkingLevel.LOW,
|
|
14
|
-
MEDIUM: ThinkingLevel.MEDIUM,
|
|
15
|
-
HIGH: ThinkingLevel.HIGH,
|
|
16
|
-
};
|
|
17
12
|
// Counter for generating unique tool call IDs
|
|
18
13
|
let toolCallCounter = 0;
|
|
19
14
|
export const stream = (model, context, options) => {
|
|
20
15
|
const stream = new AssistantMessageEventStream();
|
|
16
|
+
const normalizedContext = collapseSystemMessages(context);
|
|
21
17
|
(async () => {
|
|
22
18
|
const output = {
|
|
23
19
|
role: "assistant",
|
|
@@ -45,7 +41,7 @@ export const stream = (model, context, options) => {
|
|
|
45
41
|
throw new Error(`No API key for provider: ${model.provider}`);
|
|
46
42
|
}
|
|
47
43
|
const client = createClient(model, apiKey, options?.headers);
|
|
48
|
-
let params = buildParams(model,
|
|
44
|
+
let params = buildParams(model, normalizedContext, options);
|
|
49
45
|
const nextParams = await options?.onPayload?.(params, model);
|
|
50
46
|
if (nextParams !== undefined) {
|
|
51
47
|
params = nextParams;
|
|
@@ -56,6 +52,7 @@ export const stream = (model, context, options) => {
|
|
|
56
52
|
const blocks = output.content;
|
|
57
53
|
const blockIndex = () => blocks.length - 1;
|
|
58
54
|
for await (const chunk of googleStream) {
|
|
55
|
+
await options?.onProviderStreamEvent?.(chunk, model);
|
|
59
56
|
// @google/genai documents GenerateContentResponse.responseId as an output-only field
|
|
60
57
|
// used to identify each response. Keep the first non-empty one from the stream.
|
|
61
58
|
output.responseId ||= chunk.responseId;
|
|
@@ -249,14 +246,16 @@ export const streamSimple = (model, context, options) => {
|
|
|
249
246
|
return stream(model, context, { ...base, thinking: { enabled: false } });
|
|
250
247
|
}
|
|
251
248
|
const clampedReasoning = clampThinkingLevel(model, options.reasoning);
|
|
249
|
+
if (clampedReasoning === "off") {
|
|
250
|
+
return stream(model, context, { ...base, thinking: { enabled: false } });
|
|
251
|
+
}
|
|
252
252
|
const resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);
|
|
253
|
-
|
|
254
|
-
if (isGemini3ProModel(googleModel) || isGemini3FlashModel(googleModel) || isGemma4Model(googleModel)) {
|
|
253
|
+
if (usesGoogleThinkingLevel(model)) {
|
|
255
254
|
return stream(model, context, {
|
|
256
255
|
...base,
|
|
257
256
|
thinking: {
|
|
258
257
|
enabled: true,
|
|
259
|
-
level:
|
|
258
|
+
level: toGoogleThinkingLevel(resolvedLevel),
|
|
260
259
|
},
|
|
261
260
|
});
|
|
262
261
|
}
|
|
@@ -264,7 +263,7 @@ export const streamSimple = (model, context, options) => {
|
|
|
264
263
|
...base,
|
|
265
264
|
thinking: {
|
|
266
265
|
enabled: true,
|
|
267
|
-
budgetTokens: getGoogleBudget(
|
|
266
|
+
budgetTokens: getGoogleBudget(model, resolvedLevel, options.thinkingBudgets),
|
|
268
267
|
},
|
|
269
268
|
});
|
|
270
269
|
};
|
|
@@ -285,6 +284,8 @@ function createClient(model, apiKey, optionsHeaders) {
|
|
|
285
284
|
}
|
|
286
285
|
function buildParams(model, context, options = {}) {
|
|
287
286
|
const contents = convertMessages(model, context);
|
|
287
|
+
const initialSystemMessage = getInitialSystemMessage(context.messages);
|
|
288
|
+
const currentTools = getCurrentTools(context.messages);
|
|
288
289
|
const generationConfig = {};
|
|
289
290
|
if (options.temperature !== undefined) {
|
|
290
291
|
generationConfig.temperature = options.temperature;
|
|
@@ -293,15 +294,15 @@ function buildParams(model, context, options = {}) {
|
|
|
293
294
|
generationConfig.maxOutputTokens = options.maxTokens;
|
|
294
295
|
}
|
|
295
296
|
const supportsStrictMode = supportsGoogleStrictToolSampling(model.id);
|
|
296
|
-
const functionCallingMode =
|
|
297
|
-
? resolveGoogleFunctionCallingMode(
|
|
297
|
+
const functionCallingMode = currentTools.length > 0
|
|
298
|
+
? resolveGoogleFunctionCallingMode(currentTools, options.toolChoice, supportsStrictMode)
|
|
298
299
|
: undefined;
|
|
300
|
+
const systemInstruction = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
|
|
299
301
|
const config = {
|
|
300
302
|
...(Object.keys(generationConfig).length > 0 && generationConfig),
|
|
301
|
-
...(
|
|
302
|
-
...(
|
|
303
|
-
|
|
304
|
-
tools: convertTools(context.tools, false, supportsStrictMode),
|
|
303
|
+
...(systemInstruction && { systemInstruction: sanitizeSurrogates(systemInstruction) }),
|
|
304
|
+
...(currentTools.length > 0 && {
|
|
305
|
+
tools: convertTools(currentTools, false, supportsStrictMode),
|
|
305
306
|
}),
|
|
306
307
|
...(functionCallingMode !== undefined && {
|
|
307
308
|
toolConfig: { functionCallingConfig: { mode: functionCallingMode } },
|
|
@@ -310,7 +311,7 @@ function buildParams(model, context, options = {}) {
|
|
|
310
311
|
if (options.thinking?.enabled && model.reasoning) {
|
|
311
312
|
const thinkingConfig = { includeThoughts: true };
|
|
312
313
|
if (options.thinking.level !== undefined) {
|
|
313
|
-
thinkingConfig.thinkingLevel =
|
|
314
|
+
thinkingConfig.thinkingLevel = toGoogleSdkThinkingLevel(options.thinking.level);
|
|
314
315
|
}
|
|
315
316
|
else if (options.thinking.budgetTokens !== undefined) {
|
|
316
317
|
thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
|
|
@@ -318,7 +319,7 @@ function buildParams(model, context, options = {}) {
|
|
|
318
319
|
config.thinkingConfig = thinkingConfig;
|
|
319
320
|
}
|
|
320
321
|
else if (model.reasoning && options.thinking && !options.thinking.enabled) {
|
|
321
|
-
config.thinkingConfig =
|
|
322
|
+
config.thinkingConfig = getDisabledGoogleThinkingConfig(model);
|
|
322
323
|
}
|
|
323
324
|
if (options.signal) {
|
|
324
325
|
if (options.signal.aborted) {
|
|
@@ -333,64 +334,6 @@ function buildParams(model, context, options = {}) {
|
|
|
333
334
|
};
|
|
334
335
|
return params;
|
|
335
336
|
}
|
|
336
|
-
function isGemma4Model(model) {
|
|
337
|
-
return /gemma-?4/.test(model.id.toLowerCase());
|
|
338
|
-
}
|
|
339
|
-
function isGemini3ProModel(model) {
|
|
340
|
-
return /gemini-3(?:\.\d+)?-pro/.test(model.id.toLowerCase());
|
|
341
|
-
}
|
|
342
|
-
function isGemini3FlashModel(model) {
|
|
343
|
-
const id = model.id.toLowerCase();
|
|
344
|
-
return /gemini-3(?:\.\d+)?-flash/.test(id) || id === "gemini-flash-latest" || id === "gemini-flash-lite-latest";
|
|
345
|
-
}
|
|
346
|
-
function getDisabledThinkingConfig(model) {
|
|
347
|
-
// Google docs: Gemini 3.1 Pro cannot disable thinking, and Gemini 3 Flash / Flash-Lite
|
|
348
|
-
// do not support full thinking-off either. For Gemini 3 models, use the lowest supported
|
|
349
|
-
// thinkingLevel without includeThoughts so hidden thinking remains invisible to pi.
|
|
350
|
-
if (isGemini3ProModel(model)) {
|
|
351
|
-
return { thinkingLevel: ThinkingLevel.LOW };
|
|
352
|
-
}
|
|
353
|
-
if (isGemini3FlashModel(model)) {
|
|
354
|
-
return { thinkingLevel: ThinkingLevel.MINIMAL };
|
|
355
|
-
}
|
|
356
|
-
if (isGemma4Model(model)) {
|
|
357
|
-
return { thinkingLevel: ThinkingLevel.MINIMAL };
|
|
358
|
-
}
|
|
359
|
-
// Gemini 2.x supports disabling via thinkingBudget = 0.
|
|
360
|
-
return { thinkingBudget: 0 };
|
|
361
|
-
}
|
|
362
|
-
function getThinkingLevel(effort, model) {
|
|
363
|
-
if (isGemini3ProModel(model)) {
|
|
364
|
-
switch (effort) {
|
|
365
|
-
case "minimal":
|
|
366
|
-
case "low":
|
|
367
|
-
return "LOW";
|
|
368
|
-
case "medium":
|
|
369
|
-
case "high":
|
|
370
|
-
return "HIGH";
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
if (isGemma4Model(model)) {
|
|
374
|
-
switch (effort) {
|
|
375
|
-
case "minimal":
|
|
376
|
-
case "low":
|
|
377
|
-
return "MINIMAL";
|
|
378
|
-
case "medium":
|
|
379
|
-
case "high":
|
|
380
|
-
return "HIGH";
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
switch (effort) {
|
|
384
|
-
case "minimal":
|
|
385
|
-
return "MINIMAL";
|
|
386
|
-
case "low":
|
|
387
|
-
return "LOW";
|
|
388
|
-
case "medium":
|
|
389
|
-
return "MEDIUM";
|
|
390
|
-
case "high":
|
|
391
|
-
return "HIGH";
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
337
|
function getGoogleBudget(model, level, customBudgets) {
|
|
395
338
|
if (customBudgets?.[level] !== undefined) {
|
|
396
339
|
return customBudgets[level];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-generative-ai.js","sourceRoot":"","sources":["../../src/api/google-generative-ai.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype GenerateContentConfig,\n\ttype GenerateContentParameters,\n\tGoogleGenAI,\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\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 { 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 GoogleOptions 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}\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-generative-ai\", GoogleOptions> = (\n\tmodel: Model<\"google-generative-ai\">,\n\tcontext: Context,\n\toptions?: GoogleOptions,\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-generative-ai\" 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 Generative AI adapter\");\n\t\t\t}\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\t\t\tconst client = createClient(model, apiKey, options?.headers);\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// @google/genai documents GenerateContentResponse.responseId as an output-only field\n\t\t\t\t// used to identify each response. Keep the first non-empty one from the stream.\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\t// Generate unique ID if not provided or if it's a duplicate\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 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-generative-ai\", SimpleStreamOptions> = (\n\tmodel: Model<\"google-generative-ai\">,\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 GoogleOptions;\n\tif (!options?.reasoning) {\n\t\treturn stream(model, context, { ...base, thinking: { enabled: false } } satisfies GoogleOptions);\n\t}\n\n\tconst clampedReasoning = clampThinkingLevel(model, options.reasoning);\n\tconst resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);\n\tconst googleModel = model as Model<\"google-generative-ai\">;\n\n\tif (isGemini3ProModel(googleModel) || isGemini3FlashModel(googleModel) || isGemma4Model(googleModel)) {\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: getThinkingLevel(resolvedLevel, googleModel),\n\t\t\t},\n\t\t} satisfies GoogleOptions);\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(googleModel, resolvedLevel, options.thinkingBudgets),\n\t\t},\n\t} satisfies GoogleOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"google-generative-ai\">,\n\tapiKey?: string,\n\toptionsHeaders?: ProviderHeaders,\n): GoogleGenAI {\n\tconst httpOptions: { baseUrl?: string; apiVersion?: string; headers?: Record<string, string> } = {};\n\tif (model.baseUrl) {\n\t\thttpOptions.baseUrl = model.baseUrl;\n\t\thttpOptions.apiVersion = \"\"; // baseUrl already includes version path, don't append\n\t}\n\tconst headers = providerHeadersToRecord({ \"User-Agent\": getPiUserAgent(), ...model.headers, ...optionsHeaders });\n\tif (headers) {\n\t\thttpOptions.headers = headers;\n\t}\n\n\treturn new GoogleGenAI({\n\t\tapiKey,\n\t\thttpOptions: Object.keys(httpOptions).length > 0 ? httpOptions : undefined,\n\t});\n}\n\nfunction buildParams(\n\tmodel: Model<\"google-generative-ai\">,\n\tcontext: Context,\n\toptions: GoogleOptions = {},\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 isGemma4Model(model: Model<\"google-generative-ai\">): boolean {\n\treturn /gemma-?4/.test(model.id.toLowerCase());\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-generative-ai\">): 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\tif (isGemini3ProModel(model)) {\n\t\treturn { thinkingLevel: ThinkingLevel.LOW };\n\t}\n\tif (isGemini3FlashModel(model)) {\n\t\treturn { thinkingLevel: ThinkingLevel.MINIMAL };\n\t}\n\tif (isGemma4Model(model)) {\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 getThinkingLevel(\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\tif (isGemma4Model(model)) {\n\t\tswitch (effort) {\n\t\t\tcase \"minimal\":\n\t\t\tcase \"low\":\n\t\t\t\treturn \"MINIMAL\";\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-lite\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 512,\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\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-generative-ai.js","sourceRoot":"","sources":["../../src/api/google-generative-ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,WAAW,GAEX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAejE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAE1G,OAAO,EACN,eAAe,EACf,YAAY,EACZ,+BAA+B,EAC/B,cAAc,EACd,aAAa,EACb,gCAAgC,EAChC,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,gCAAgC,EAChC,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAWvD,8CAA8C;AAC9C,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB,MAAM,CAAC,MAAM,MAAM,GAA0D,CAC5E,KAAoC,EACpC,OAA0B,EAC1B,OAAuB,EACO,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,2BAA2B,EAAE,CAAC;IACjD,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAE1D,CAAC,KAAK,IAAI,EAAE,CAAC;QACZ,MAAM,MAAM,GAAqB;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,EAAE;YACX,GAAG,EAAE,sBAA6B;YAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,EAAE;YACf,KAAK,EAAE;gBACN,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;gBACZ,UAAU,EAAE,CAAC;gBACb,WAAW,EAAE,CAAC;gBACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;aACpE;YACD,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QAEF,IAAI,CAAC;YACJ,IAAI,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACtF,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;YAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7D,IAAI,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,MAAM,OAAO,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC7D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,GAAG,UAAuC,CAAC;YAClD,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;YAE1G,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAChD,IAAI,YAAY,GAAyC,IAAI,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;YAC9B,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAC3C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACxC,MAAM,OAAO,EAAE,qBAAqB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACrD,qFAAqF;gBACrF,gFAAgF;gBAChF,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;gBACvC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;oBAC/B,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;wBAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;4BAC7B,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;4BACxC,IACC,CAAC,YAAY;gCACb,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC;gCAChD,CAAC,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,CAAC,EAC5C,CAAC;gCACF,IAAI,YAAY,EAAE,CAAC;oCAClB,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wCAClC,MAAM,CAAC,IAAI,CAAC;4CACX,IAAI,EAAE,UAAU;4CAChB,YAAY,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;4CAC/B,OAAO,EAAE,YAAY,CAAC,IAAI;4CAC1B,OAAO,EAAE,MAAM;yCACf,CAAC,CAAC;oCACJ,CAAC;yCAAM,CAAC;wCACP,MAAM,CAAC,IAAI,CAAC;4CACX,IAAI,EAAE,cAAc;4CACpB,YAAY,EAAE,UAAU,EAAE;4CAC1B,OAAO,EAAE,YAAY,CAAC,QAAQ;4CAC9B,OAAO,EAAE,MAAM;yCACf,CAAC,CAAC;oCACJ,CAAC;gCACF,CAAC;gCACD,IAAI,UAAU,EAAE,CAAC;oCAChB,YAAY,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC;oCAChF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oCAClC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;gCACtF,CAAC;qCAAM,CAAC;oCACP,YAAY,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;oCAC1C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oCAClC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;gCAClF,CAAC;4BACF,CAAC;4BACD,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gCACtC,YAAY,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC;gCACnC,YAAY,CAAC,iBAAiB,GAAG,sBAAsB,CACtD,YAAY,CAAC,iBAAiB,EAC9B,IAAI,CAAC,gBAAgB,CACrB,CAAC;gCACF,MAAM,CAAC,IAAI,CAAC;oCACX,IAAI,EAAE,gBAAgB;oCACtB,YAAY,EAAE,UAAU,EAAE;oCAC1B,KAAK,EAAE,IAAI,CAAC,IAAI;oCAChB,OAAO,EAAE,MAAM;iCACf,CAAC,CAAC;4BACJ,CAAC;iCAAM,CAAC;gCACP,YAAY,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;gCAC/B,YAAY,CAAC,aAAa,GAAG,sBAAsB,CAClD,YAAY,CAAC,aAAa,EAC1B,IAAI,CAAC,gBAAgB,CACrB,CAAC;gCACF,MAAM,CAAC,IAAI,CAAC;oCACX,IAAI,EAAE,YAAY;oCAClB,YAAY,EAAE,UAAU,EAAE;oCAC1B,KAAK,EAAE,IAAI,CAAC,IAAI;oCAChB,OAAO,EAAE,MAAM;iCACf,CAAC,CAAC;4BACJ,CAAC;wBACF,CAAC;wBAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;4BACvB,IAAI,YAAY,EAAE,CAAC;gCAClB,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oCAClC,MAAM,CAAC,IAAI,CAAC;wCACX,IAAI,EAAE,UAAU;wCAChB,YAAY,EAAE,UAAU,EAAE;wCAC1B,OAAO,EAAE,YAAY,CAAC,IAAI;wCAC1B,OAAO,EAAE,MAAM;qCACf,CAAC,CAAC;gCACJ,CAAC;qCAAM,CAAC;oCACP,MAAM,CAAC,IAAI,CAAC;wCACX,IAAI,EAAE,cAAc;wCACpB,YAAY,EAAE,UAAU,EAAE;wCAC1B,OAAO,EAAE,YAAY,CAAC,QAAQ;wCAC9B,OAAO,EAAE,MAAM;qCACf,CAAC,CAAC;gCACJ,CAAC;gCACD,YAAY,GAAG,IAAI,CAAC;4BACrB,CAAC;4BAED,4DAA4D;4BAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;4BACxC,MAAM,UAAU,GACf,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;4BACzF,MAAM,UAAU,GAAG,UAAU;gCAC5B,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE;gCAChE,CAAC,CAAC,UAAU,CAAC;4BAEd,MAAM,QAAQ,GAAa;gCAC1B,IAAI,EAAE,UAAU;gCAChB,EAAE,EAAE,UAAU;gCACd,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE;gCAClC,SAAS,EAAG,IAAI,CAAC,YAAY,CAAC,IAA4B,IAAI,EAAE;gCAChE,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;6BACzE,CAAC;4BAEF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;4BAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;4BACrF,MAAM,CAAC,IAAI,CAAC;gCACX,IAAI,EAAE,gBAAgB;gCACtB,YAAY,EAAE,UAAU,EAAE;gCAC1B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;gCACzC,OAAO,EAAE,MAAM;6BACf,CAAC,CAAC;4BACH,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;wBAC9F,CAAC;oBACF,CAAC;gBACF,CAAC;gBAED,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;oBAC7B,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC;oBAC9C,MAAM,CAAC,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBAC1D,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;wBACvF,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;oBAC/B,CAAC;gBACF,CAAC;gBAED,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;oBACzB,MAAM,CAAC,KAAK,GAAG;wBACd,KAAK,EACJ,CAAC,KAAK,CAAC,aAAa,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,uBAAuB,IAAI,CAAC,CAAC;wBACjG,MAAM,EACL,CAAC,KAAK,CAAC,aAAa,CAAC,oBAAoB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,kBAAkB,IAAI,CAAC,CAAC;wBAChG,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,uBAAuB,IAAI,CAAC;wBAC3D,UAAU,EAAE,CAAC;wBACb,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,kBAAkB,IAAI,CAAC;wBACtD,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,eAAe,IAAI,CAAC;wBACrD,IAAI,EAAE;4BACL,KAAK,EAAE,CAAC;4BACR,MAAM,EAAE,CAAC;4BACT,SAAS,EAAE,CAAC;4BACZ,UAAU,EAAE,CAAC;4BACb,KAAK,EAAE,CAAC;yBACR;qBACD,CAAC;oBACF,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC;YACF,CAAC;YAED,IAAI,YAAY,EAAE,CAAC;gBAClB,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAClC,MAAM,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,UAAU;wBAChB,YAAY,EAAE,UAAU,EAAE;wBAC1B,OAAO,EAAE,YAAY,CAAC,IAAI;wBAC1B,OAAO,EAAE,MAAM;qBACf,CAAC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACP,MAAM,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,cAAc;wBACpB,YAAY,EAAE,UAAU,EAAE;wBAC1B,OAAO,EAAE,YAAY,CAAC,QAAQ;wBAC9B,OAAO,EAAE,MAAM;qBACf,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YAED,IAAI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACxC,CAAC;YAED,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;gBACtE,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa;oBACxC,CAAC,CAAC,0BAA0B,MAAM,CAAC,aAAa,EAAE;oBAClD,CAAC,CAAC,2BAA2B,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1E,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,uDAAuD;YACvD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpC,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBACtB,OAAQ,KAA4B,CAAC,KAAK,CAAC;gBAC5C,CAAC;YACF,CAAC;YACD,MAAM,CAAC,UAAU,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YACnE,MAAM,CAAC,YAAY,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;YACzE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;IAAA,CACD,CAAC,EAAE,CAAC;IAEL,OAAO,MAAM,CAAC;AAAA,CACd,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAgE,CACxF,KAAoC,EACpC,OAA0B,EAC1B,OAA6B,EACC,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,IAAI,GAAG;QACZ,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC;QACpD,UAAU,EAAE,OAAO,EAAE,UAAU;KACP,CAAC;IAC1B,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAA0B,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACtE,IAAI,gBAAgB,KAAK,KAAK,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAA0B,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,aAAa,GAAG,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAE1E,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE;YAC7B,GAAG,IAAI;YACP,QAAQ,EAAE;gBACT,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,qBAAqB,CAAC,aAAa,CAAC;aAC3C;SACuB,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE;QAC7B,GAAG,IAAI;QACP,QAAQ,EAAE;YACT,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC;SAC5E;KACuB,CAAC,CAAC;AAAA,CAC3B,CAAC;AAEF,SAAS,YAAY,CACpB,KAAoC,EACpC,MAAe,EACf,cAAgC,EAClB;IACd,MAAM,WAAW,GAAgF,EAAE,CAAC;IACpG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACpC,WAAW,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,sDAAsD;IACpF,CAAC;IACD,MAAM,OAAO,GAAG,uBAAuB,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACjH,IAAI,OAAO,EAAE,CAAC;QACb,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED,OAAO,IAAI,WAAW,CAAC;QACtB,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;KAC1E,CAAC,CAAC;AAAA,CACH;AAED,SAAS,WAAW,CACnB,KAAoC,EACpC,OAA0B,EAC1B,OAAO,GAAkB,EAAE,EACC;IAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEvD,MAAM,gBAAgB,GAA0B,EAAE,CAAC;IACnD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACvC,gBAAgB,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACpD,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACrC,gBAAgB,CAAC,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IACtD,CAAC;IAED,MAAM,kBAAkB,GAAG,gCAAgC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,MAAM,mBAAmB,GACxB,YAAY,CAAC,MAAM,GAAG,CAAC;QACtB,CAAC,CAAC,gCAAgC,CAAC,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,kBAAkB,CAAC;QACxF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,MAAM,MAAM,GAA0B;QACrC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC;QACjE,GAAG,CAAC,iBAAiB,IAAI,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI;YAC9B,KAAK,EAAE,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,kBAAkB,CAAC;SAC5D,CAAC;QACF,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI;YACxC,UAAU,EAAE,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE;SACpE,CAAC;KACF,CAAC;IAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAClD,MAAM,cAAc,GAAmB,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;QACjE,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,cAAc,CAAC,aAAa,GAAG,wBAAwB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjF,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACxD,cAAc,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC/D,CAAC;QACD,MAAM,CAAC,cAAc,GAAG,cAAc,CAAC;IACxC,CAAC;SAAM,IAAI,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC7E,MAAM,CAAC,cAAc,GAAG,+BAA+B,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAA8B;QACzC,KAAK,EAAE,KAAK,CAAC,EAAE;QACf,QAAQ;QACR,MAAM;KACN,CAAC;IAEF,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,eAAe,CACvB,KAAoC,EACpC,KAAkC,EAClC,aAA+B,EACtB;IACT,IAAI,aAAa,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,aAAa,CAAC,KAAK,CAAE,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAgD;YAC5D,OAAO,EAAE,GAAG;YACZ,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,KAAK;SACX,CAAC;QACF,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzC,MAAM,OAAO,GAAgD;YAC5D,OAAO,EAAE,GAAG;YACZ,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,KAAK;SACX,CAAC;QACF,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAgD;YAC5D,OAAO,EAAE,GAAG;YACZ,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,KAAK;SACX,CAAC;QACF,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,CAAC,CAAC;AAAA,CACV","sourcesContent":["import {\n\ttype GenerateContentConfig,\n\ttype GenerateContentParameters,\n\tGoogleGenAI,\n\ttype ThinkingConfig,\n} from \"@google/genai\";\nimport { calculateCost, clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tModel,\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 { 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 GoogleOptions 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}\n\n// Counter for generating unique tool call IDs\nlet toolCallCounter = 0;\n\nexport const stream: StreamFunction<\"google-generative-ai\", GoogleOptions> = (\n\tmodel: Model<\"google-generative-ai\">,\n\tcontext: TranscriptContext,\n\toptions?: GoogleOptions,\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-generative-ai\" 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 Generative AI adapter\");\n\t\t\t}\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\t\t\tconst client = createClient(model, apiKey, options?.headers);\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\tawait options?.onProviderStreamEvent?.(chunk, model);\n\t\t\t\t// @google/genai documents GenerateContentResponse.responseId as an output-only field\n\t\t\t\t// used to identify each response. Keep the first non-empty one from the stream.\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\t// Generate unique ID if not provided or if it's a duplicate\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 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-generative-ai\", SimpleStreamOptions> = (\n\tmodel: Model<\"google-generative-ai\">,\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 GoogleOptions;\n\tif (!options?.reasoning) {\n\t\treturn stream(model, context, { ...base, thinking: { enabled: false } } satisfies GoogleOptions);\n\t}\n\n\tconst clampedReasoning = clampThinkingLevel(model, options.reasoning);\n\tif (clampedReasoning === \"off\") {\n\t\treturn stream(model, context, { ...base, thinking: { enabled: false } } satisfies GoogleOptions);\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 GoogleOptions);\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 GoogleOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"google-generative-ai\">,\n\tapiKey?: string,\n\toptionsHeaders?: ProviderHeaders,\n): GoogleGenAI {\n\tconst httpOptions: { baseUrl?: string; apiVersion?: string; headers?: Record<string, string> } = {};\n\tif (model.baseUrl) {\n\t\thttpOptions.baseUrl = model.baseUrl;\n\t\thttpOptions.apiVersion = \"\"; // baseUrl already includes version path, don't append\n\t}\n\tconst headers = providerHeadersToRecord({ \"User-Agent\": getPiUserAgent(), ...model.headers, ...optionsHeaders });\n\tif (headers) {\n\t\thttpOptions.headers = headers;\n\t}\n\n\treturn new GoogleGenAI({\n\t\tapiKey,\n\t\thttpOptions: Object.keys(httpOptions).length > 0 ? httpOptions : undefined,\n\t});\n}\n\nfunction buildParams(\n\tmodel: Model<\"google-generative-ai\">,\n\tcontext: TranscriptContext,\n\toptions: GoogleOptions = {},\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-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-lite\")) {\n\t\tconst budgets: Record<ResolvedGoogleThinkingLevel, number> = {\n\t\t\tminimal: 512,\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\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,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared utilities for Google Generative AI and Google Vertex providers.
|
|
3
3
|
*/
|
|
4
|
-
import { type Content, FinishReason, FunctionCallingConfigMode, type Part } from "@google/genai";
|
|
5
|
-
import type {
|
|
4
|
+
import { type Content, FinishReason, FunctionCallingConfigMode, ThinkingLevel as GoogleSdkThinkingLevel, type Part, type ThinkingConfig } from "@google/genai";
|
|
5
|
+
import type { Model, StopReason, StreamOptions, ThinkingLevel, Tool, TranscriptContext } from "../types.ts";
|
|
6
6
|
type GoogleApiType = "google-generative-ai" | "google-vertex";
|
|
7
7
|
/**
|
|
8
8
|
* Thinking level for Gemini 3 models.
|
|
@@ -11,7 +11,16 @@ type GoogleApiType = "google-generative-ai" | "google-vertex";
|
|
|
11
11
|
export type GoogleApiThinkingLevel = "THINKING_LEVEL_UNSPECIFIED" | "MINIMAL" | "LOW" | "MEDIUM" | "HIGH";
|
|
12
12
|
export type ResolvedGoogleThinkingLevel = Exclude<ThinkingLevel, "xhigh" | "max">;
|
|
13
13
|
/** Resolve a supported pi level or model-specific Google mapping to a standard Google level. */
|
|
14
|
-
export declare function resolveGoogleThinkingLevel<T extends GoogleApiType>(model: Model<T>, level:
|
|
14
|
+
export declare function resolveGoogleThinkingLevel<T extends GoogleApiType>(model: Model<T>, level: ThinkingLevel): ResolvedGoogleThinkingLevel;
|
|
15
|
+
/**
|
|
16
|
+
* Whether this model uses Gemini's discrete `thinkingLevel` control instead of
|
|
17
|
+
* the token-based `thinkingBudget` control. Supported levels come from the
|
|
18
|
+
* model's `thinkingLevelMap`; this only selects the Google wire format.
|
|
19
|
+
*/
|
|
20
|
+
export declare function usesGoogleThinkingLevel<T extends GoogleApiType>(model: Model<T>): boolean;
|
|
21
|
+
export declare function toGoogleThinkingLevel(level: ResolvedGoogleThinkingLevel): GoogleApiThinkingLevel;
|
|
22
|
+
export declare function toGoogleSdkThinkingLevel(level: GoogleApiThinkingLevel): GoogleSdkThinkingLevel;
|
|
23
|
+
export declare function getDisabledGoogleThinkingConfig<T extends GoogleApiType>(model: Model<T>): ThinkingConfig;
|
|
15
24
|
/**
|
|
16
25
|
* Determines whether a streamed Gemini `Part` should be treated as "thinking".
|
|
17
26
|
*
|
|
@@ -45,7 +54,7 @@ export declare function requiresToolCallId(modelId: string): boolean;
|
|
|
45
54
|
/**
|
|
46
55
|
* Convert internal messages to Gemini Content[] format.
|
|
47
56
|
*/
|
|
48
|
-
export declare function convertMessages<T extends GoogleApiType>(model: Model<T>, context:
|
|
57
|
+
export declare function convertMessages<T extends GoogleApiType>(model: Model<T>, context: TranscriptContext): Content[];
|
|
49
58
|
/**
|
|
50
59
|
* Convert tools to Gemini function declarations format.
|
|
51
60
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-shared.d.ts","sourceRoot":"","sources":["../../src/api/google-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,KAAK,EACX,OAAO,EAEP,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,aAAa,EAEb,aAAa,EACb,IAAI,EACJ,MAAM,aAAa,CAAC;AAMrB,KAAK,aAAa,GAAG,sBAAsB,GAAG,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC1G,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,GAAG,KAAK,CAAC,CAAC;AAElF,gGAAgG;AAChG,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,aAAa,EACjE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,KAAK,EAAE,kBAAkB,GACvB,2BAA2B,CAgB7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAC,GAAG,OAAO,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrH;AAkBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAO3D;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAsJrG;AA6BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,IAAI,EAAE,EACb,aAAa,UAAQ,EACrB,kBAAkB,UAAO,GACvB;IAAE,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,EAAE,GAAG,SAAS,CAiBnE;AAED,uFAAuF;AACvF,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGzE;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,yBAAyB,CAWvE;AAED,wBAAgB,gCAAgC,CAC/C,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,kBAAkB,EAAE,OAAO,GACzB,yBAAyB,GAAG,SAAS,CASvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA4B9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAS9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EACnC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,iBAAiB,GAAG,QAAQ,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAkBZ","sourcesContent":["/**\n * Shared utilities for Google Generative AI and Google Vertex providers.\n */\n\nimport { type Content, FinishReason, FunctionCallingConfigMode, type Part } from \"@google/genai\";\nimport type {\n\tContext,\n\tImageContent,\n\tModel,\n\tModelThinkingLevel,\n\tStopReason,\n\tStreamOptions,\n\tTextContent,\n\tThinkingLevel,\n\tTool,\n} from \"../types.ts\";\nimport { retryProviderRequest } from \"../utils/provider-retry.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from \"./constrained-sampling.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\ntype GoogleApiType = \"google-generative-ai\" | \"google-vertex\";\n\n/**\n * Thinking level for Gemini 3 models.\n * Mirrors Google's ThinkingLevel enum values.\n */\nexport type GoogleApiThinkingLevel = \"THINKING_LEVEL_UNSPECIFIED\" | \"MINIMAL\" | \"LOW\" | \"MEDIUM\" | \"HIGH\";\nexport type ResolvedGoogleThinkingLevel = Exclude<ThinkingLevel, \"xhigh\" | \"max\">;\n\n/** Resolve a supported pi level or model-specific Google mapping to a standard Google level. */\nexport function resolveGoogleThinkingLevel<T extends GoogleApiType>(\n\tmodel: Model<T>,\n\tlevel: ModelThinkingLevel,\n): ResolvedGoogleThinkingLevel {\n\tif (level === \"off\") return \"high\";\n\n\tconst mapped = model.thinkingLevelMap?.[level];\n\tconst resolvedLevel = typeof mapped === \"string\" ? mapped.toLowerCase() : level;\n\tswitch (resolvedLevel) {\n\t\tcase \"minimal\":\n\t\tcase \"low\":\n\t\tcase \"medium\":\n\t\tcase \"high\":\n\t\t\treturn resolvedLevel;\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Unsupported Google thinking level mapping for ${model.provider}/${model.id}: ${level} -> ${String(mapped)}`,\n\t\t\t);\n\t}\n}\n\n/**\n * Determines whether a streamed Gemini `Part` should be treated as \"thinking\".\n *\n * Protocol note (Gemini / Vertex AI thought signatures):\n * - `thought: true` is the definitive marker for thinking content (thought summaries).\n * - `thoughtSignature` is an encrypted representation of the model's internal thought process\n * used to preserve reasoning context across multi-turn interactions.\n * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT\n * indicate the part itself is thinking content.\n * - For non-functionCall responses, the signature appears on the last part for context replay.\n * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;\n * do not merge/move signatures across parts.\n *\n * See: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nexport function isThinkingPart(part: Pick<Part, \"thought\" | \"thoughtSignature\">): boolean {\n\treturn part.thought === true;\n}\n\n/**\n * Retain thought signatures during streaming.\n *\n * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.\n * This helper preserves the last non-empty signature for the current block.\n *\n * Note: this does NOT merge or move signatures across distinct response parts. It only prevents\n * a signature from being overwritten with `undefined` within the same streamed block.\n */\nexport function retainThoughtSignature(existing: string | undefined, incoming: string | undefined): string | undefined {\n\tif (typeof incoming === \"string\" && incoming.length > 0) return incoming;\n\treturn existing;\n}\n\n// Thought signatures must be base64 for Google APIs (TYPE_BYTES).\nconst base64SignaturePattern = /^[A-Za-z0-9+/]+={0,2}$/;\n\nfunction isValidThoughtSignature(signature: string | undefined): boolean {\n\tif (!signature) return false;\n\tif (signature.length % 4 !== 0) return false;\n\treturn base64SignaturePattern.test(signature);\n}\n\n/**\n * Only keep signatures from the same provider/model and with valid base64.\n */\nfunction resolveThoughtSignature(isSameProviderAndModel: boolean, signature: string | undefined): string | undefined {\n\treturn isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : undefined;\n}\n\n/**\n * Models via Google APIs that require explicit tool call IDs in function calls/responses.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\treturn (\n\t\tmodelId.startsWith(\"claude-\") ||\n\t\tmodelId.startsWith(\"gpt-oss-\") ||\n\t\t(geminiMajorVersion !== undefined && geminiMajorVersion >= 3)\n\t);\n}\n\nfunction getGeminiMajorVersion(modelId: string): number | undefined {\n\tconst match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\\d+)/);\n\tif (!match) return undefined;\n\treturn Number.parseInt(match[1], 10);\n}\n\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\tif (geminiMajorVersion !== undefined) {\n\t\treturn geminiMajorVersion >= 3;\n\t}\n\treturn true;\n}\n\n/**\n * Convert internal messages to Gemini Content[] format.\n */\nexport function convertMessages<T extends GoogleApiType>(model: Model<T>, context: Context): Content[] {\n\tconst contents: Content[] = [];\n\tconst normalizeToolCallId = (id: string): string => {\n\t\tif (!requiresToolCallId(model.id)) return id;\n\t\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n\t};\n\n\tconst transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);\n\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst parts: Part[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn { text: sanitizeSurrogates(item.text) };\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tinlineData: {\n\t\t\t\t\t\t\t\tmimeType: item.mimeType,\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (parts.length === 0) continue;\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst parts: Part[] = [];\n\t\t\t// Check if message is from same provider and model - only then keep thinking blocks\n\t\t\tconst isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);\n\t\t\t\t\t// Skip empty text blocks — unless they carry a thought signature. Gemini can attach\n\t\t\t\t\t// the signature to a part whose visible text is empty and requires it echoed back;\n\t\t\t\t\t// dropping it breaks the reasoning chain and the model intermittently ends mid-task\n\t\t\t\t\t// turns with a thought-only STOP (empty completion, no tool call).\n\t\t\t\t\tif ((!block.text || block.text.trim() === \"\") && !thoughtSignature) continue;\n\t\t\t\t\tparts.push({\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Only keep as thinking block if same provider AND same model\n\t\t\t\t\t// Otherwise convert to plain text (no tags to avoid model mimicking them)\n\t\t\t\t\tif (isSameProviderAndModel) {\n\t\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);\n\t\t\t\t\t\t// Same rule as text blocks: an empty thinking block is dropped only when it\n\t\t\t\t\t\t// carries no signature (mirrors the anthropic converter's handling).\n\t\t\t\t\t\tif ((!block.thinking || block.thinking.trim() === \"\") && !thoughtSignature) continue;\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\tthought: true,\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Cross-provider/model: the signature is unusable, empty blocks stay dropped.\n\t\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") continue;\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);\n\t\t\t\t\tconst part: Part = {\n\t\t\t\t\t\tfunctionCall: {\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\targs: block.arguments ?? {},\n\t\t\t\t\t\t\t...(requiresToolCallId(model.id) ? { id: block.id } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t};\n\t\t\t\t\tparts.push(part);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (parts.length === 0) continue;\n\t\t\tcontents.push({\n\t\t\t\trole: \"model\",\n\t\t\t\tparts,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Extract text and image content\n\t\t\tconst textContent = msg.content.filter((c): c is TextContent => c.type === \"text\");\n\t\t\tconst textResult = textContent.map((c) => c.text).join(\"\\n\");\n\t\t\tconst imageContent = model.input.includes(\"image\")\n\t\t\t\t? msg.content.filter((c): c is ImageContent => c.type === \"image\")\n\t\t\t\t: [];\n\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst hasImages = imageContent.length > 0;\n\n\t\t\t// Gemini 3+ models support multimodal function responses with images nested inside\n\t\t\t// functionResponse.parts. Claude and other non-Gemini models behind Cloud Code Assist /\n\t\t\t// Gemini < 3 still needs a separate user image turn.\n\t\t\tconst modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);\n\n\t\t\t// Use \"output\" key for success, \"error\" key for errors as per SDK documentation\n\t\t\tconst responseValue = hasText ? sanitizeSurrogates(textResult) : hasImages ? \"(see attached image)\" : \"\";\n\n\t\t\tconst imageParts: Part[] = imageContent.map((imageBlock) => ({\n\t\t\t\tinlineData: {\n\t\t\t\t\tmimeType: imageBlock.mimeType,\n\t\t\t\t\tdata: imageBlock.data,\n\t\t\t\t},\n\t\t\t}));\n\n\t\t\tconst includeId = requiresToolCallId(model.id);\n\t\t\tconst functionResponsePart: Part = {\n\t\t\t\tfunctionResponse: {\n\t\t\t\t\tname: msg.toolName,\n\t\t\t\t\tresponse: msg.isError ? { error: responseValue } : { output: responseValue },\n\t\t\t\t\t...(hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts }),\n\t\t\t\t\t...(includeId ? { id: msg.toolCallId } : {}),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Cloud Code Assist API requires all function responses to be in a single user turn.\n\t\t\t// Check if the last content is already a user turn with function responses and merge.\n\t\t\tconst lastContent = contents[contents.length - 1];\n\t\t\tif (lastContent?.role === \"user\" && lastContent.parts?.some((p) => p.functionResponse)) {\n\t\t\t\tlastContent.parts.push(functionResponsePart);\n\t\t\t} else {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [functionResponsePart],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// For Gemini < 3, add images in a separate user message\n\t\t\tif (hasImages && !modelSupportsMultimodalFunctionResponse) {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: \"Tool result image:\" }, ...imageParts],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn contents;\n}\n\nconst JSON_SCHEMA_META_DECLARATIONS = new Set([\n\t\"$schema\",\n\t\"$id\",\n\t\"$anchor\",\n\t\"$dynamicAnchor\",\n\t\"$vocabulary\",\n\t\"$comment\",\n\t\"$defs\",\n\t\"definitions\", // pre-draft-2019-09 equivalent of $defs\n]);\n\n/**\n * Strip meta-declarations from a schema obj\n */\nfunction sanitizeForOpenApi(schema: unknown): unknown {\n\tif (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n\t\treturn schema;\n\t}\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(schema)) {\n\t\tif (JSON_SCHEMA_META_DECLARATIONS.has(key)) continue;\n\t\tresult[key] = sanitizeForOpenApi(value);\n\t}\n\treturn result;\n}\n\n/**\n * Convert tools to Gemini function declarations format.\n *\n * By default uses `parametersJsonSchema` which supports full JSON Schema (including\n * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`\n * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude\n * models, where the API translates `parameters` into Anthropic's `input_schema`.\n */\nexport function convertTools(\n\ttools: Tool[],\n\tuseParameters = false,\n\tsupportsStrictMode = true,\n): { functionDeclarations: Record<string, unknown>[] }[] | undefined {\n\tif (tools.length === 0) return undefined;\n\treturn [\n\t\t{\n\t\t\tfunctionDeclarations: tools.map((tool) => {\n\t\t\t\tconst strict = resolveJsonSchemaStrictSampling(tool, supportsStrictMode);\n\t\t\t\tconst parameters = getJsonSchemaToolParameters(tool, strict);\n\t\t\t\treturn {\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t...(useParameters\n\t\t\t\t\t\t? { parameters: sanitizeForOpenApi(parameters as unknown) }\n\t\t\t\t\t\t: { parametersJsonSchema: parameters }),\n\t\t\t\t};\n\t\t\t}),\n\t\t},\n\t];\n}\n\n/** Gemini 3+ enforces required function parameters in validated tool-calling modes. */\nexport function supportsGoogleStrictToolSampling(modelId: string): boolean {\n\tconst majorVersion = getGeminiMajorVersion(modelId);\n\treturn majorVersion !== undefined && majorVersion >= 3;\n}\n\n/** Map tool choice string to Gemini FunctionCallingConfigMode. */\nexport function mapToolChoice(choice: string): FunctionCallingConfigMode {\n\tswitch (choice) {\n\t\tcase \"auto\":\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t\tcase \"none\":\n\t\t\treturn FunctionCallingConfigMode.NONE;\n\t\tcase \"any\":\n\t\t\treturn FunctionCallingConfigMode.ANY;\n\t\tdefault:\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t}\n}\n\nexport function resolveGoogleFunctionCallingMode(\n\ttools: Tool[],\n\ttoolChoice: string | undefined,\n\tsupportsStrictMode: boolean,\n): FunctionCallingConfigMode | undefined {\n\tconst useStrictMode = tools.some((tool) => resolveJsonSchemaStrictSampling(tool, supportsStrictMode) === true);\n\tif (toolChoice === \"none\" || toolChoice === \"any\") {\n\t\treturn mapToolChoice(toolChoice);\n\t}\n\tif (useStrictMode) {\n\t\treturn FunctionCallingConfigMode.VALIDATED;\n\t}\n\treturn toolChoice ? mapToolChoice(toolChoice) : undefined;\n}\n\n/**\n * Map Gemini FinishReason to our StopReason.\n */\nexport function mapStopReason(reason: FinishReason): StopReason {\n\tswitch (reason) {\n\t\tcase FinishReason.STOP:\n\t\t\treturn \"stop\";\n\t\tcase FinishReason.MAX_TOKENS:\n\t\t\treturn \"length\";\n\t\tcase FinishReason.BLOCKLIST:\n\t\tcase FinishReason.PROHIBITED_CONTENT:\n\t\tcase FinishReason.SPII:\n\t\tcase FinishReason.SAFETY:\n\t\tcase FinishReason.IMAGE_SAFETY:\n\t\tcase FinishReason.IMAGE_PROHIBITED_CONTENT:\n\t\tcase FinishReason.IMAGE_RECITATION:\n\t\tcase FinishReason.IMAGE_OTHER:\n\t\tcase FinishReason.RECITATION:\n\t\tcase FinishReason.FINISH_REASON_UNSPECIFIED:\n\t\tcase FinishReason.OTHER:\n\t\tcase FinishReason.LANGUAGE:\n\t\tcase FinishReason.MALFORMED_FUNCTION_CALL:\n\t\tcase FinishReason.UNEXPECTED_TOOL_CALL:\n\t\tcase FinishReason.TOO_MANY_TOOL_CALLS:\n\t\tcase FinishReason.NO_IMAGE:\n\t\t\treturn \"error\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = reason;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Map string finish reason to our StopReason (for raw API responses).\n */\nexport function mapStopReasonString(reason: string): StopReason {\n\tswitch (reason) {\n\t\tcase \"STOP\":\n\t\t\treturn \"stop\";\n\t\tcase \"MAX_TOKENS\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"error\";\n\t}\n}\n\n/**\n * Run a Google GenAI SDK request with the shared provider retry policy\n * (408/409/429/5xx with backoff, honoring retry-after), mirroring how the\n * Anthropic and OpenAI adapters wrap their initial request in\n * retryProviderRequest. The SDK's ApiError has a `status` property but no\n * `headers` property, and retryProviderRequest only retries errors that carry\n * both, so normalize the error by adding the missing `headers` before\n * rethrowing.\n */\nexport function retryGoogleRequest<T>(\n\trequest: () => Promise<T>,\n\toptions?: Pick<StreamOptions, \"maxRetries\" | \"maxRetryDelayMs\" | \"signal\">,\n): Promise<T> {\n\treturn retryProviderRequest(\n\t\tasync () => {\n\t\t\ttry {\n\t\t\t\treturn await request();\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && \"status\" in error && !(\"headers\" in error)) {\n\t\t\t\t\t(error as { headers?: Headers }).headers = undefined;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tmaxRetries: options?.maxRetries,\n\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\t\tsignal: options?.signal,\n\t\t},\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-shared.d.ts","sourceRoot":"","sources":["../../src/api/google-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACN,KAAK,OAAO,EACZ,YAAY,EACZ,yBAAyB,EACzB,aAAa,IAAI,sBAAsB,EACvC,KAAK,IAAI,EACT,KAAK,cAAc,EACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAEX,KAAK,EACL,UAAU,EACV,aAAa,EAEb,aAAa,EACb,IAAI,EACJ,iBAAiB,EACjB,MAAM,aAAa,CAAC;AAOrB,KAAK,aAAa,GAAG,sBAAsB,GAAG,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC1G,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,GAAG,KAAK,CAAC,CAAC;AAUlF,gGAAgG;AAChG,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,aAAa,EACjE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,KAAK,EAAE,aAAa,GAClB,2BAA2B,CAc7B;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAWzF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,2BAA2B,GAAG,sBAAsB,CAWhG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB,CAE9F;AAED,wBAAgB,+BAA+B,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,cAAc,CASxG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAC,GAAG,OAAO,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrH;AAkBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAO3D;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,EAAE,CAwJ/G;AA6BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,IAAI,EAAE,EACb,aAAa,UAAQ,EACrB,kBAAkB,UAAO,GACvB;IAAE,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,EAAE,GAAG,SAAS,CAiBnE;AAED,uFAAuF;AACvF,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGzE;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,yBAAyB,CAWvE;AAED,wBAAgB,gCAAgC,CAC/C,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,kBAAkB,EAAE,OAAO,GACzB,yBAAyB,GAAG,SAAS,CASvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA4B9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAS9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EACnC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,iBAAiB,GAAG,QAAQ,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAkBZ","sourcesContent":["/**\n * Shared utilities for Google Generative AI and Google Vertex providers.\n */\n\nimport {\n\ttype Content,\n\tFinishReason,\n\tFunctionCallingConfigMode,\n\tThinkingLevel as GoogleSdkThinkingLevel,\n\ttype Part,\n\ttype ThinkingConfig,\n} from \"@google/genai\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tImageContent,\n\tModel,\n\tStopReason,\n\tStreamOptions,\n\tTextContent,\n\tThinkingLevel,\n\tTool,\n\tTranscriptContext,\n} from \"../types.ts\";\nimport { retryProviderRequest } from \"../utils/provider-retry.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { collapseSystemMessages, withoutInitialSystemMessage } from \"../utils/transcript.ts\";\nimport { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from \"./constrained-sampling.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\ntype GoogleApiType = \"google-generative-ai\" | \"google-vertex\";\n\n/**\n * Thinking level for Gemini 3 models.\n * Mirrors Google's ThinkingLevel enum values.\n */\nexport type GoogleApiThinkingLevel = \"THINKING_LEVEL_UNSPECIFIED\" | \"MINIMAL\" | \"LOW\" | \"MEDIUM\" | \"HIGH\";\nexport type ResolvedGoogleThinkingLevel = Exclude<ThinkingLevel, \"xhigh\" | \"max\">;\n\nconst GOOGLE_SDK_THINKING_LEVEL_MAP: Record<GoogleApiThinkingLevel, GoogleSdkThinkingLevel> = {\n\tTHINKING_LEVEL_UNSPECIFIED: GoogleSdkThinkingLevel.THINKING_LEVEL_UNSPECIFIED,\n\tMINIMAL: GoogleSdkThinkingLevel.MINIMAL,\n\tLOW: GoogleSdkThinkingLevel.LOW,\n\tMEDIUM: GoogleSdkThinkingLevel.MEDIUM,\n\tHIGH: GoogleSdkThinkingLevel.HIGH,\n};\n\n/** Resolve a supported pi level or model-specific Google mapping to a standard Google level. */\nexport function resolveGoogleThinkingLevel<T extends GoogleApiType>(\n\tmodel: Model<T>,\n\tlevel: ThinkingLevel,\n): ResolvedGoogleThinkingLevel {\n\tconst mapped = model.thinkingLevelMap?.[level];\n\tconst resolvedLevel = typeof mapped === \"string\" ? mapped.toLowerCase() : level;\n\tswitch (resolvedLevel) {\n\t\tcase \"minimal\":\n\t\tcase \"low\":\n\t\tcase \"medium\":\n\t\tcase \"high\":\n\t\t\treturn resolvedLevel;\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Unsupported Google thinking level mapping for ${model.provider}/${model.id}: ${level} -> ${String(mapped)}`,\n\t\t\t);\n\t}\n}\n\n/**\n * Whether this model uses Gemini's discrete `thinkingLevel` control instead of\n * the token-based `thinkingBudget` control. Supported levels come from the\n * model's `thinkingLevelMap`; this only selects the Google wire format.\n */\nexport function usesGoogleThinkingLevel<T extends GoogleApiType>(model: Model<T>): boolean {\n\tconst id = model.id.toLowerCase();\n\treturn (\n\t\t// Match Gemini 3 Pro/Flash IDs with or without a minor version, such as\n\t\t// gemini-3-flash-preview, gemini-3.1-pro-preview, and gemini-3.8-flash.\n\t\t/gemini-3(?:\\.\\d+)?-(?:pro|flash)/.test(id) ||\n\t\tid === \"gemini-flash-latest\" ||\n\t\tid === \"gemini-flash-lite-latest\" ||\n\t\t// Match both hosted Gemma 4 naming forms: gemma-4-* and gemma4-*.\n\t\t/gemma-?4/.test(id)\n\t);\n}\n\nexport function toGoogleThinkingLevel(level: ResolvedGoogleThinkingLevel): GoogleApiThinkingLevel {\n\tswitch (level) {\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\nexport function toGoogleSdkThinkingLevel(level: GoogleApiThinkingLevel): GoogleSdkThinkingLevel {\n\treturn GOOGLE_SDK_THINKING_LEVEL_MAP[level];\n}\n\nexport function getDisabledGoogleThinkingConfig<T extends GoogleApiType>(model: Model<T>): ThinkingConfig {\n\tif (!usesGoogleThinkingLevel(model)) return { thinkingBudget: 0 };\n\n\tconst fallback = clampThinkingLevel(model, \"off\");\n\tif (fallback === \"off\") return { thinkingBudget: 0 };\n\n\tconst resolvedLevel = resolveGoogleThinkingLevel(model, fallback);\n\tconst apiLevel = toGoogleThinkingLevel(resolvedLevel);\n\treturn { thinkingLevel: toGoogleSdkThinkingLevel(apiLevel) };\n}\n\n/**\n * Determines whether a streamed Gemini `Part` should be treated as \"thinking\".\n *\n * Protocol note (Gemini / Vertex AI thought signatures):\n * - `thought: true` is the definitive marker for thinking content (thought summaries).\n * - `thoughtSignature` is an encrypted representation of the model's internal thought process\n * used to preserve reasoning context across multi-turn interactions.\n * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT\n * indicate the part itself is thinking content.\n * - For non-functionCall responses, the signature appears on the last part for context replay.\n * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;\n * do not merge/move signatures across parts.\n *\n * See: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nexport function isThinkingPart(part: Pick<Part, \"thought\" | \"thoughtSignature\">): boolean {\n\treturn part.thought === true;\n}\n\n/**\n * Retain thought signatures during streaming.\n *\n * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.\n * This helper preserves the last non-empty signature for the current block.\n *\n * Note: this does NOT merge or move signatures across distinct response parts. It only prevents\n * a signature from being overwritten with `undefined` within the same streamed block.\n */\nexport function retainThoughtSignature(existing: string | undefined, incoming: string | undefined): string | undefined {\n\tif (typeof incoming === \"string\" && incoming.length > 0) return incoming;\n\treturn existing;\n}\n\n// Thought signatures must be base64 for Google APIs (TYPE_BYTES).\nconst base64SignaturePattern = /^[A-Za-z0-9+/]+={0,2}$/;\n\nfunction isValidThoughtSignature(signature: string | undefined): boolean {\n\tif (!signature) return false;\n\tif (signature.length % 4 !== 0) return false;\n\treturn base64SignaturePattern.test(signature);\n}\n\n/**\n * Only keep signatures from the same provider/model and with valid base64.\n */\nfunction resolveThoughtSignature(isSameProviderAndModel: boolean, signature: string | undefined): string | undefined {\n\treturn isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : undefined;\n}\n\n/**\n * Models via Google APIs that require explicit tool call IDs in function calls/responses.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\treturn (\n\t\tmodelId.startsWith(\"claude-\") ||\n\t\tmodelId.startsWith(\"gpt-oss-\") ||\n\t\t(geminiMajorVersion !== undefined && geminiMajorVersion >= 3)\n\t);\n}\n\nfunction getGeminiMajorVersion(modelId: string): number | undefined {\n\tconst match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\\d+)/);\n\tif (!match) return undefined;\n\treturn Number.parseInt(match[1], 10);\n}\n\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n\tconst geminiMajorVersion = getGeminiMajorVersion(modelId);\n\tif (geminiMajorVersion !== undefined) {\n\t\treturn geminiMajorVersion >= 3;\n\t}\n\treturn true;\n}\n\n/**\n * Convert internal messages to Gemini Content[] format.\n */\nexport function convertMessages<T extends GoogleApiType>(model: Model<T>, context: TranscriptContext): Content[] {\n\t// Gemini has no mid-conversation system messages; the leading prompt is sent as systemInstruction.\n\tconst conversation = withoutInitialSystemMessage(collapseSystemMessages(context).messages);\n\tconst contents: Content[] = [];\n\tconst normalizeToolCallId = (id: string): string => {\n\t\tif (!requiresToolCallId(model.id)) return id;\n\t\treturn id.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64);\n\t};\n\n\tconst transformedMessages = transformMessages(conversation, model, normalizeToolCallId);\n\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst parts: Part[] = msg.content.map((item) => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn { text: sanitizeSurrogates(item.text) };\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tinlineData: {\n\t\t\t\t\t\t\t\tmimeType: item.mimeType,\n\t\t\t\t\t\t\t\tdata: item.data,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (parts.length === 0) continue;\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst parts: Part[] = [];\n\t\t\t// Check if message is from same provider and model - only then keep thinking blocks\n\t\t\tconst isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);\n\t\t\t\t\t// Skip empty text blocks — unless they carry a thought signature. Gemini can attach\n\t\t\t\t\t// the signature to a part whose visible text is empty and requires it echoed back;\n\t\t\t\t\t// dropping it breaks the reasoning chain and the model intermittently ends mid-task\n\t\t\t\t\t// turns with a thought-only STOP (empty completion, no tool call).\n\t\t\t\t\tif ((!block.text || block.text.trim() === \"\") && !thoughtSignature) continue;\n\t\t\t\t\tparts.push({\n\t\t\t\t\t\ttext: sanitizeSurrogates(block.text),\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t});\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\t// Only keep as thinking block if same provider AND same model\n\t\t\t\t\t// Otherwise convert to plain text (no tags to avoid model mimicking them)\n\t\t\t\t\tif (isSameProviderAndModel) {\n\t\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);\n\t\t\t\t\t\t// Same rule as text blocks: an empty thinking block is dropped only when it\n\t\t\t\t\t\t// carries no signature (mirrors the anthropic converter's handling).\n\t\t\t\t\t\tif ((!block.thinking || block.thinking.trim() === \"\") && !thoughtSignature) continue;\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\tthought: true,\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Cross-provider/model: the signature is unusable, empty blocks stay dropped.\n\t\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") continue;\n\t\t\t\t\t\tparts.push({\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(block.thinking),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);\n\t\t\t\t\tconst part: Part = {\n\t\t\t\t\t\tfunctionCall: {\n\t\t\t\t\t\t\tname: block.name,\n\t\t\t\t\t\t\targs: block.arguments ?? {},\n\t\t\t\t\t\t\t...(requiresToolCallId(model.id) ? { id: block.id } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t\t};\n\t\t\t\t\tparts.push(part);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (parts.length === 0) continue;\n\t\t\tcontents.push({\n\t\t\t\trole: \"model\",\n\t\t\t\tparts,\n\t\t\t});\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\t// Extract text and image content\n\t\t\tconst textContent = msg.content.filter((c): c is TextContent => c.type === \"text\");\n\t\t\tconst textResult = textContent.map((c) => c.text).join(\"\\n\");\n\t\t\tconst imageContent = model.input.includes(\"image\")\n\t\t\t\t? msg.content.filter((c): c is ImageContent => c.type === \"image\")\n\t\t\t\t: [];\n\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst hasImages = imageContent.length > 0;\n\n\t\t\t// Gemini 3+ models support multimodal function responses with images nested inside\n\t\t\t// functionResponse.parts. Claude and other non-Gemini models behind Cloud Code Assist /\n\t\t\t// Gemini < 3 still needs a separate user image turn.\n\t\t\tconst modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);\n\n\t\t\t// Use \"output\" key for success, \"error\" key for errors as per SDK documentation\n\t\t\tconst responseValue = hasText ? sanitizeSurrogates(textResult) : hasImages ? \"(see attached image)\" : \"\";\n\n\t\t\tconst imageParts: Part[] = imageContent.map((imageBlock) => ({\n\t\t\t\tinlineData: {\n\t\t\t\t\tmimeType: imageBlock.mimeType,\n\t\t\t\t\tdata: imageBlock.data,\n\t\t\t\t},\n\t\t\t}));\n\n\t\t\tconst includeId = requiresToolCallId(model.id);\n\t\t\tconst functionResponsePart: Part = {\n\t\t\t\tfunctionResponse: {\n\t\t\t\t\tname: msg.toolName,\n\t\t\t\t\tresponse: msg.isError ? { error: responseValue } : { output: responseValue },\n\t\t\t\t\t...(hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts }),\n\t\t\t\t\t...(includeId ? { id: msg.toolCallId } : {}),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// Cloud Code Assist API requires all function responses to be in a single user turn.\n\t\t\t// Check if the last content is already a user turn with function responses and merge.\n\t\t\tconst lastContent = contents[contents.length - 1];\n\t\t\tif (lastContent?.role === \"user\" && lastContent.parts?.some((p) => p.functionResponse)) {\n\t\t\t\tlastContent.parts.push(functionResponsePart);\n\t\t\t} else {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [functionResponsePart],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// For Gemini < 3, add images in a separate user message\n\t\t\tif (hasImages && !modelSupportsMultimodalFunctionResponse) {\n\t\t\t\tcontents.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tparts: [{ text: \"Tool result image:\" }, ...imageParts],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn contents;\n}\n\nconst JSON_SCHEMA_META_DECLARATIONS = new Set([\n\t\"$schema\",\n\t\"$id\",\n\t\"$anchor\",\n\t\"$dynamicAnchor\",\n\t\"$vocabulary\",\n\t\"$comment\",\n\t\"$defs\",\n\t\"definitions\", // pre-draft-2019-09 equivalent of $defs\n]);\n\n/**\n * Strip meta-declarations from a schema obj\n */\nfunction sanitizeForOpenApi(schema: unknown): unknown {\n\tif (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n\t\treturn schema;\n\t}\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(schema)) {\n\t\tif (JSON_SCHEMA_META_DECLARATIONS.has(key)) continue;\n\t\tresult[key] = sanitizeForOpenApi(value);\n\t}\n\treturn result;\n}\n\n/**\n * Convert tools to Gemini function declarations format.\n *\n * By default uses `parametersJsonSchema` which supports full JSON Schema (including\n * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`\n * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude\n * models, where the API translates `parameters` into Anthropic's `input_schema`.\n */\nexport function convertTools(\n\ttools: Tool[],\n\tuseParameters = false,\n\tsupportsStrictMode = true,\n): { functionDeclarations: Record<string, unknown>[] }[] | undefined {\n\tif (tools.length === 0) return undefined;\n\treturn [\n\t\t{\n\t\t\tfunctionDeclarations: tools.map((tool) => {\n\t\t\t\tconst strict = resolveJsonSchemaStrictSampling(tool, supportsStrictMode);\n\t\t\t\tconst parameters = getJsonSchemaToolParameters(tool, strict);\n\t\t\t\treturn {\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t...(useParameters\n\t\t\t\t\t\t? { parameters: sanitizeForOpenApi(parameters as unknown) }\n\t\t\t\t\t\t: { parametersJsonSchema: parameters }),\n\t\t\t\t};\n\t\t\t}),\n\t\t},\n\t];\n}\n\n/** Gemini 3+ enforces required function parameters in validated tool-calling modes. */\nexport function supportsGoogleStrictToolSampling(modelId: string): boolean {\n\tconst majorVersion = getGeminiMajorVersion(modelId);\n\treturn majorVersion !== undefined && majorVersion >= 3;\n}\n\n/** Map tool choice string to Gemini FunctionCallingConfigMode. */\nexport function mapToolChoice(choice: string): FunctionCallingConfigMode {\n\tswitch (choice) {\n\t\tcase \"auto\":\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t\tcase \"none\":\n\t\t\treturn FunctionCallingConfigMode.NONE;\n\t\tcase \"any\":\n\t\t\treturn FunctionCallingConfigMode.ANY;\n\t\tdefault:\n\t\t\treturn FunctionCallingConfigMode.AUTO;\n\t}\n}\n\nexport function resolveGoogleFunctionCallingMode(\n\ttools: Tool[],\n\ttoolChoice: string | undefined,\n\tsupportsStrictMode: boolean,\n): FunctionCallingConfigMode | undefined {\n\tconst useStrictMode = tools.some((tool) => resolveJsonSchemaStrictSampling(tool, supportsStrictMode) === true);\n\tif (toolChoice === \"none\" || toolChoice === \"any\") {\n\t\treturn mapToolChoice(toolChoice);\n\t}\n\tif (useStrictMode) {\n\t\treturn FunctionCallingConfigMode.VALIDATED;\n\t}\n\treturn toolChoice ? mapToolChoice(toolChoice) : undefined;\n}\n\n/**\n * Map Gemini FinishReason to our StopReason.\n */\nexport function mapStopReason(reason: FinishReason): StopReason {\n\tswitch (reason) {\n\t\tcase FinishReason.STOP:\n\t\t\treturn \"stop\";\n\t\tcase FinishReason.MAX_TOKENS:\n\t\t\treturn \"length\";\n\t\tcase FinishReason.BLOCKLIST:\n\t\tcase FinishReason.PROHIBITED_CONTENT:\n\t\tcase FinishReason.SPII:\n\t\tcase FinishReason.SAFETY:\n\t\tcase FinishReason.IMAGE_SAFETY:\n\t\tcase FinishReason.IMAGE_PROHIBITED_CONTENT:\n\t\tcase FinishReason.IMAGE_RECITATION:\n\t\tcase FinishReason.IMAGE_OTHER:\n\t\tcase FinishReason.RECITATION:\n\t\tcase FinishReason.FINISH_REASON_UNSPECIFIED:\n\t\tcase FinishReason.OTHER:\n\t\tcase FinishReason.LANGUAGE:\n\t\tcase FinishReason.MALFORMED_FUNCTION_CALL:\n\t\tcase FinishReason.UNEXPECTED_TOOL_CALL:\n\t\tcase FinishReason.TOO_MANY_TOOL_CALLS:\n\t\tcase FinishReason.NO_IMAGE:\n\t\t\treturn \"error\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = reason;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * Map string finish reason to our StopReason (for raw API responses).\n */\nexport function mapStopReasonString(reason: string): StopReason {\n\tswitch (reason) {\n\t\tcase \"STOP\":\n\t\t\treturn \"stop\";\n\t\tcase \"MAX_TOKENS\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"error\";\n\t}\n}\n\n/**\n * Run a Google GenAI SDK request with the shared provider retry policy\n * (408/409/429/5xx with backoff, honoring retry-after), mirroring how the\n * Anthropic and OpenAI adapters wrap their initial request in\n * retryProviderRequest. The SDK's ApiError has a `status` property but no\n * `headers` property, and retryProviderRequest only retries errors that carry\n * both, so normalize the error by adding the missing `headers` before\n * rethrowing.\n */\nexport function retryGoogleRequest<T>(\n\trequest: () => Promise<T>,\n\toptions?: Pick<StreamOptions, \"maxRetries\" | \"maxRetryDelayMs\" | \"signal\">,\n): Promise<T> {\n\treturn retryProviderRequest(\n\t\tasync () => {\n\t\t\ttry {\n\t\t\t\treturn await request();\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && \"status\" in error && !(\"headers\" in error)) {\n\t\t\t\t\t(error as { headers?: Headers }).headers = undefined;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tmaxRetries: options?.maxRetries,\n\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\t\tsignal: options?.signal,\n\t\t},\n\t);\n}\n"]}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared utilities for Google Generative AI and Google Vertex providers.
|
|
3
3
|
*/
|
|
4
|
-
import { FinishReason, FunctionCallingConfigMode } from "@google/genai";
|
|
4
|
+
import { FinishReason, FunctionCallingConfigMode, ThinkingLevel as GoogleSdkThinkingLevel, } from "@google/genai";
|
|
5
|
+
import { clampThinkingLevel } from "../models.js";
|
|
5
6
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
6
7
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
8
|
+
import { collapseSystemMessages, withoutInitialSystemMessage } from "../utils/transcript.js";
|
|
7
9
|
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
8
10
|
import { transformMessages } from "./transform-messages.js";
|
|
11
|
+
const GOOGLE_SDK_THINKING_LEVEL_MAP = {
|
|
12
|
+
THINKING_LEVEL_UNSPECIFIED: GoogleSdkThinkingLevel.THINKING_LEVEL_UNSPECIFIED,
|
|
13
|
+
MINIMAL: GoogleSdkThinkingLevel.MINIMAL,
|
|
14
|
+
LOW: GoogleSdkThinkingLevel.LOW,
|
|
15
|
+
MEDIUM: GoogleSdkThinkingLevel.MEDIUM,
|
|
16
|
+
HIGH: GoogleSdkThinkingLevel.HIGH,
|
|
17
|
+
};
|
|
9
18
|
/** Resolve a supported pi level or model-specific Google mapping to a standard Google level. */
|
|
10
19
|
export function resolveGoogleThinkingLevel(model, level) {
|
|
11
|
-
if (level === "off")
|
|
12
|
-
return "high";
|
|
13
20
|
const mapped = model.thinkingLevelMap?.[level];
|
|
14
21
|
const resolvedLevel = typeof mapped === "string" ? mapped.toLowerCase() : level;
|
|
15
22
|
switch (resolvedLevel) {
|
|
@@ -22,6 +29,47 @@ export function resolveGoogleThinkingLevel(model, level) {
|
|
|
22
29
|
throw new Error(`Unsupported Google thinking level mapping for ${model.provider}/${model.id}: ${level} -> ${String(mapped)}`);
|
|
23
30
|
}
|
|
24
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether this model uses Gemini's discrete `thinkingLevel` control instead of
|
|
34
|
+
* the token-based `thinkingBudget` control. Supported levels come from the
|
|
35
|
+
* model's `thinkingLevelMap`; this only selects the Google wire format.
|
|
36
|
+
*/
|
|
37
|
+
export function usesGoogleThinkingLevel(model) {
|
|
38
|
+
const id = model.id.toLowerCase();
|
|
39
|
+
return (
|
|
40
|
+
// Match Gemini 3 Pro/Flash IDs with or without a minor version, such as
|
|
41
|
+
// gemini-3-flash-preview, gemini-3.1-pro-preview, and gemini-3.8-flash.
|
|
42
|
+
/gemini-3(?:\.\d+)?-(?:pro|flash)/.test(id) ||
|
|
43
|
+
id === "gemini-flash-latest" ||
|
|
44
|
+
id === "gemini-flash-lite-latest" ||
|
|
45
|
+
// Match both hosted Gemma 4 naming forms: gemma-4-* and gemma4-*.
|
|
46
|
+
/gemma-?4/.test(id));
|
|
47
|
+
}
|
|
48
|
+
export function toGoogleThinkingLevel(level) {
|
|
49
|
+
switch (level) {
|
|
50
|
+
case "minimal":
|
|
51
|
+
return "MINIMAL";
|
|
52
|
+
case "low":
|
|
53
|
+
return "LOW";
|
|
54
|
+
case "medium":
|
|
55
|
+
return "MEDIUM";
|
|
56
|
+
case "high":
|
|
57
|
+
return "HIGH";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function toGoogleSdkThinkingLevel(level) {
|
|
61
|
+
return GOOGLE_SDK_THINKING_LEVEL_MAP[level];
|
|
62
|
+
}
|
|
63
|
+
export function getDisabledGoogleThinkingConfig(model) {
|
|
64
|
+
if (!usesGoogleThinkingLevel(model))
|
|
65
|
+
return { thinkingBudget: 0 };
|
|
66
|
+
const fallback = clampThinkingLevel(model, "off");
|
|
67
|
+
if (fallback === "off")
|
|
68
|
+
return { thinkingBudget: 0 };
|
|
69
|
+
const resolvedLevel = resolveGoogleThinkingLevel(model, fallback);
|
|
70
|
+
const apiLevel = toGoogleThinkingLevel(resolvedLevel);
|
|
71
|
+
return { thinkingLevel: toGoogleSdkThinkingLevel(apiLevel) };
|
|
72
|
+
}
|
|
25
73
|
/**
|
|
26
74
|
* Determines whether a streamed Gemini `Part` should be treated as "thinking".
|
|
27
75
|
*
|
|
@@ -95,13 +143,15 @@ function supportsMultimodalFunctionResponse(modelId) {
|
|
|
95
143
|
* Convert internal messages to Gemini Content[] format.
|
|
96
144
|
*/
|
|
97
145
|
export function convertMessages(model, context) {
|
|
146
|
+
// Gemini has no mid-conversation system messages; the leading prompt is sent as systemInstruction.
|
|
147
|
+
const conversation = withoutInitialSystemMessage(collapseSystemMessages(context).messages);
|
|
98
148
|
const contents = [];
|
|
99
149
|
const normalizeToolCallId = (id) => {
|
|
100
150
|
if (!requiresToolCallId(model.id))
|
|
101
151
|
return id;
|
|
102
152
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
103
153
|
};
|
|
104
|
-
const transformedMessages = transformMessages(
|
|
154
|
+
const transformedMessages = transformMessages(conversation, model, normalizeToolCallId);
|
|
105
155
|
for (const msg of transformedMessages) {
|
|
106
156
|
if (msg.role === "user") {
|
|
107
157
|
if (typeof msg.content === "string") {
|