@draht/ai 2026.7.30 → 2026.10.4-2
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/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +404 -142
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts +2 -0
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +34 -10
- 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 +210 -24
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/cloudflare-ai-binding.d.ts +77 -0
- package/dist/api/cloudflare-ai-binding.d.ts.map +1 -0
- package/dist/api/cloudflare-ai-binding.js +72 -0
- package/dist/api/cloudflare-ai-binding.js.map +1 -0
- 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 +10 -1
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +137 -4
- package/dist/api/constrained-sampling.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts +2 -2
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +39 -82
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +27 -5
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +126 -18
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts +2 -2
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +42 -73
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +5 -1
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +19 -7
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/llama-cpp-classify.d.ts +33 -0
- package/dist/api/llama-cpp-classify.d.ts.map +1 -0
- package/dist/api/llama-cpp-classify.js +365 -0
- package/dist/api/llama-cpp-classify.js.map +1 -0
- package/dist/api/llama-cpp-classify.lazy.d.ts +3 -0
- package/dist/api/llama-cpp-classify.lazy.d.ts.map +1 -0
- package/dist/api/llama-cpp-classify.lazy.js +4 -0
- package/dist/api/llama-cpp-classify.lazy.js.map +1 -0
- package/dist/api/mistral-conversations.d.ts +2 -2
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +250 -69
- 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 +107 -55
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts +11 -4
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +241 -129
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +8 -4
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +109 -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 +62 -24
- 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 +5 -3
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +13 -4
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts +9 -3
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +22 -11
- 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 +183 -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 +6 -6
- package/dist/auth/credential-store.d.ts.map +1 -1
- package/dist/auth/credential-store.js +24 -15
- package/dist/auth/credential-store.js.map +1 -1
- package/dist/auth/helpers.d.ts +1 -0
- package/dist/auth/helpers.d.ts.map +1 -1
- package/dist/auth/helpers.js +8 -3
- package/dist/auth/helpers.js.map +1 -1
- package/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/dist/auth/oauth/anthropic.js +28 -131
- package/dist/auth/oauth/anthropic.js.map +1 -1
- package/dist/auth/oauth/callback-server.d.ts +55 -0
- package/dist/auth/oauth/callback-server.d.ts.map +1 -0
- package/dist/auth/oauth/callback-server.js +146 -0
- package/dist/auth/oauth/callback-server.js.map +1 -0
- package/dist/auth/oauth/device-code.d.ts +2 -1
- package/dist/auth/oauth/device-code.d.ts.map +1 -1
- package/dist/auth/oauth/device-code.js +5 -5
- package/dist/auth/oauth/device-code.js.map +1 -1
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/dist/auth/oauth/github-copilot.js +121 -41
- package/dist/auth/oauth/github-copilot.js.map +1 -1
- package/dist/auth/oauth/google-antigravity.d.ts +3 -3
- package/dist/auth/oauth/google-antigravity.d.ts.map +1 -1
- package/dist/auth/oauth/google-antigravity.js +17 -9
- package/dist/auth/oauth/google-antigravity.js.map +1 -1
- package/dist/auth/oauth/google-gemini-cli.d.ts +3 -3
- package/dist/auth/oauth/google-gemini-cli.d.ts.map +1 -1
- package/dist/auth/oauth/google-gemini-cli.js +18 -10
- package/dist/auth/oauth/google-gemini-cli.js.map +1 -1
- package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/dist/auth/oauth/kimi-coding.js +5 -6
- package/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/dist/auth/oauth/load.d.ts +4 -0
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +10 -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/oauth/openai-chatgpt.d.ts +9 -0
- package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -0
- package/dist/auth/oauth/openai-chatgpt.js +266 -0
- package/dist/auth/oauth/openai-chatgpt.js.map +1 -0
- package/dist/auth/oauth/openai-codex.d.ts +1 -1
- package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
- package/dist/auth/oauth/openai-codex.js +33 -130
- package/dist/auth/oauth/openai-codex.js.map +1 -1
- package/dist/auth/oauth/openrouter.d.ts +1 -1
- package/dist/auth/oauth/openrouter.d.ts.map +1 -1
- package/dist/auth/oauth/openrouter.js +26 -145
- package/dist/auth/oauth/openrouter.js.map +1 -1
- package/dist/auth/oauth/radius.d.ts +1 -1
- package/dist/auth/oauth/radius.d.ts.map +1 -1
- package/dist/auth/oauth/radius.js +28 -93
- package/dist/auth/oauth/radius.js.map +1 -1
- package/dist/auth/oauth/xai.d.ts.map +1 -1
- package/dist/auth/oauth/xai.js +13 -12
- package/dist/auth/oauth/xai.js.map +1 -1
- package/dist/auth/resolve.d.ts +3 -8
- package/dist/auth/resolve.d.ts.map +1 -1
- package/dist/auth/resolve.js +27 -31
- package/dist/auth/resolve.js.map +1 -1
- package/dist/auth/types.d.ts +29 -8
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/bun-oauth.d.ts.map +1 -1
- package/dist/bun-oauth.js +4 -0
- package/dist/bun-oauth.js.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/compat.d.ts +3 -3
- package/dist/compat.d.ts.map +1 -1
- package/dist/compat.js +9 -6
- package/dist/compat.js.map +1 -1
- package/dist/env-api-keys.d.ts +5 -0
- package/dist/env-api-keys.d.ts.map +1 -1
- package/dist/env-api-keys.js +9 -1
- 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 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -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 +12 -14
- package/dist/models-store.d.ts.map +1 -1
- package/dist/models-store.js +7 -6
- package/dist/models-store.js.map +1 -1
- package/dist/models.d.ts +138 -47
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +135 -37
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +135 -37
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +391 -99
- 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 +31 -21
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.js +15 -7
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.d.ts +4 -2
- 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 -2
- 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.d.ts.map +1 -1
- package/dist/providers/anthropic.js +39 -8
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/anthropic.models.d.ts +4 -2
- 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 -2
- 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.d.ts +3 -0
- package/dist/providers/baseten.d.ts.map +1 -0
- package/dist/providers/baseten.js +15 -0
- package/dist/providers/baseten.js.map +1 -0
- package/dist/providers/baseten.models.d.ts +6 -0
- package/dist/providers/baseten.models.d.ts.map +1 -0
- package/dist/providers/baseten.models.js +8 -0
- package/dist/providers/baseten.models.js.map +1 -0
- package/dist/providers/cerebras.models.d.ts +4 -2
- 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.d.ts +3 -1
- package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.js +4 -0
- package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -2
- 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-auth.d.ts.map +1 -1
- package/dist/providers/cloudflare-auth.js +15 -10
- package/dist/providers/cloudflare-auth.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 -2
- 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 -0
- 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 -0
- 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 -2
- 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 +19 -13
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +109 -18
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/fireworks.models.d.ts +4 -2
- 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.js +1 -1
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/github-copilot.models.d.ts +4 -2
- 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.d.ts.map +1 -1
- package/dist/providers/google-vertex.js +15 -7
- package/dist/providers/google-vertex.js.map +1 -1
- package/dist/providers/google-vertex.models.d.ts +4 -2
- 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 -2
- 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 -2
- 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 -2
- 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.d.ts.map +1 -1
- package/dist/providers/kimi-coding.js +1 -0
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/providers/kimi-coding.models.d.ts +4 -2
- 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 +6 -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 -2
- 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 -2
- 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 -2
- 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 -2
- 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 -2
- 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 -2
- 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.d.ts.map +1 -1
- package/dist/providers/openai-codex.js +6 -2
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/openai-codex.models.d.ts +4 -2
- 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.d.ts.map +1 -1
- package/dist/providers/openai.js +11 -2
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openai.models.d.ts +4 -2
- 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.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +4 -3
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/providers/opencode-go.models.d.ts +4 -2
- 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-headers.d.ts +4 -0
- package/dist/providers/opencode-headers.d.ts.map +1 -0
- package/dist/providers/opencode-headers.js +22 -0
- package/dist/providers/opencode-headers.js.map +1 -0
- package/dist/providers/opencode.d.ts +3 -1
- package/dist/providers/opencode.d.ts.map +1 -1
- package/dist/providers/opencode.js +10 -6
- package/dist/providers/opencode.js.map +1 -1
- package/dist/providers/opencode.models.d.ts +4 -2
- 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 +1 -1
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +16 -3
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/openrouter.models.d.ts +4 -2
- 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 -2
- 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.d.ts +3 -0
- package/dist/providers/qwen-token-plan-individual.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual.js +15 -0
- package/dist/providers/qwen-token-plan-individual.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.d.ts +6 -0
- package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.js +8 -0
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -0
- package/dist/providers/qwen-token-plan.models.d.ts +4 -2
- 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 +53 -29
- package/dist/providers/radius.js.map +1 -1
- package/dist/providers/radius.models.d.ts +6 -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 -2
- 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 +6 -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.d.ts.map +1 -1
- package/dist/providers/vercel-ai-gateway.js +5 -2
- package/dist/providers/vercel-ai-gateway.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.d.ts +4 -2
- 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.d.ts +1 -1
- package/dist/providers/xai.d.ts.map +1 -1
- package/dist/providers/xai.js +2 -5
- package/dist/providers/xai.js.map +1 -1
- package/dist/providers/xai.models.d.ts +4 -2
- 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 -2
- 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 -2
- 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 -2
- 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 -2
- 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 -2
- 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 -2
- 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 +411 -127
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/abort.d.ts +8 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +49 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/assistant-message-frame.d.ts +77 -0
- package/dist/utils/assistant-message-frame.d.ts.map +1 -0
- package/dist/utils/assistant-message-frame.js +425 -0
- package/dist/utils/assistant-message-frame.js.map +1 -0
- 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/draht-user-agent.d.ts +2 -0
- package/dist/utils/draht-user-agent.d.ts.map +1 -0
- package/dist/utils/draht-user-agent.js +12 -0
- package/dist/utils/draht-user-agent.js.map +1 -0
- package/dist/utils/error-body.d.ts.map +1 -1
- package/dist/utils/error-body.js +23 -4
- package/dist/utils/error-body.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/event-stream.d.ts.map +1 -1
- package/dist/utils/event-stream.js +30 -8
- package/dist/utils/event-stream.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/node-http-proxy.d.ts.map +1 -1
- package/dist/utils/node-http-proxy.js +53 -12
- package/dist/utils/node-http-proxy.js.map +1 -1
- package/dist/utils/oauth-page.d.ts.map +1 -0
- package/dist/utils/oauth-page.js.map +1 -0
- package/dist/utils/overflow.d.ts +11 -1
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +24 -6
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/provider-retry.js +3 -2
- package/dist/utils/provider-retry.js.map +1 -1
- package/dist/utils/retry.d.ts +6 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +19 -2
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/sleep.d.ts +2 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +15 -0
- package/dist/utils/sleep.js.map +1 -0
- 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/dist/utils/uuid.d.ts +2 -2
- package/dist/utils/uuid.d.ts.map +1 -1
- package/dist/utils/uuid.js +35 -40
- package/dist/utils/uuid.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +40 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +19 -13
- package/dist/auth/oauth/oauth-page.d.ts.map +0 -1
- package/dist/auth/oauth/oauth-page.js.map +0 -1
- package/dist/image-models.generated.d.ts +0 -605
- package/dist/image-models.generated.d.ts.map +0 -1
- package/dist/image-models.generated.js +0 -607
- 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 -140
- 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
- /package/dist/{auth/oauth → utils}/oauth-page.d.ts +0 -0
- /package/dist/{auth/oauth → utils}/oauth-page.js +0 -0
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
1
|
+
import Anthropic, {} from "@anthropic-ai/sdk";
|
|
2
|
+
import { ANTHROPIC_FEDERATION_RULE_ID_ENV, ANTHROPIC_IDENTITY_TOKEN_FILE_ENV, ANTHROPIC_ORGANIZATION_ID_ENV, ANTHROPIC_SERVICE_ACCOUNT_ID_ENV, ANTHROPIC_WORKSPACE_ID_ENV, } from "../env-api-keys.js";
|
|
2
3
|
import { calculateCost } from "../models.js";
|
|
3
|
-
import {
|
|
4
|
+
import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
|
|
5
|
+
import { getDrahtUserAgent } from "../utils/draht-user-agent.js";
|
|
4
6
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
5
7
|
import { headersToRecord } from "../utils/headers.js";
|
|
6
8
|
import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js";
|
|
7
9
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
8
10
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
9
11
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
10
|
-
import {
|
|
12
|
+
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
13
|
+
import { getCurrentTools, getDeclaredTools, getInitialSystemMessage, hasToolRedefinitions, resolveTranscript, } from "../utils/transcript.js";
|
|
14
|
+
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
11
15
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
12
16
|
import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
|
|
13
17
|
import { transformMessages } from "./transform-messages.js";
|
|
14
18
|
/**
|
|
15
19
|
* Resolve cache retention preference.
|
|
16
|
-
* Defaults to "short" and uses
|
|
20
|
+
* Defaults to "short" and uses DRAHT_CACHE_RETENTION for backward compatibility.
|
|
17
21
|
*/
|
|
18
22
|
function resolveCacheRetention(cacheRetention, env) {
|
|
19
23
|
if (cacheRetention) {
|
|
20
24
|
return cacheRetention;
|
|
21
25
|
}
|
|
22
|
-
if (getProviderEnvValue("
|
|
26
|
+
if (getProviderEnvValue("DRAHT_CACHE_RETENTION", env) === "long") {
|
|
23
27
|
return "long";
|
|
24
28
|
}
|
|
25
29
|
return "short";
|
|
@@ -36,7 +40,7 @@ function getCacheControl(model, cacheRetention, env) {
|
|
|
36
40
|
};
|
|
37
41
|
}
|
|
38
42
|
// Stealth mode: Mimic Claude Code's tool naming exactly
|
|
39
|
-
const claudeCodeVersion = "2.1.
|
|
43
|
+
const claudeCodeVersion = "2.1.280";
|
|
40
44
|
// Claude Code 2.x tool names (canonical casing)
|
|
41
45
|
// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
|
|
42
46
|
// To update: https://github.com/badlogic/cchistory
|
|
@@ -109,33 +113,41 @@ function convertContentBlocks(content) {
|
|
|
109
113
|
}
|
|
110
114
|
const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
|
|
111
115
|
const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
116
|
+
const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
117
|
+
const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
|
|
118
|
+
const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
|
|
119
|
+
const MID_CONVERSATION_TOOL_CHANGES_BETA = "mid-conversation-tool-changes-2026-07-01";
|
|
120
|
+
/**
|
|
121
|
+
* Stable deferred tool declared whenever native tool changes are in use. Anthropic adds
|
|
122
|
+
* hidden prompt scaffolding as soon as any tool has `defer_loading`; declaring this
|
|
123
|
+
* placeholder from the first request keeps that scaffolding in the cached prefix, so the
|
|
124
|
+
* first real late tool does not invalidate the cache (measured: full miss without it).
|
|
125
|
+
* It is never activated and the model cannot see it.
|
|
126
|
+
*/
|
|
127
|
+
const DEFERRED_TOOL_PLACEHOLDER = {
|
|
128
|
+
name: "__pi_deferred_placeholder__",
|
|
129
|
+
description: "Reserved placeholder. Never available. Never call this.",
|
|
130
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
131
|
+
defer_loading: true,
|
|
132
|
+
};
|
|
133
|
+
function shouldUseServerSideFallbackBeta(model) {
|
|
134
|
+
return (model.compat?.allowedFallbackModels?.length ?? 0) > 0;
|
|
135
|
+
}
|
|
112
136
|
function getAnthropicCompat(model) {
|
|
137
|
+
const isOpenRouter = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
|
|
113
138
|
return {
|
|
114
139
|
supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
|
|
115
140
|
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
|
116
|
-
sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ??
|
|
141
|
+
sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter,
|
|
142
|
+
sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? "openrouter" : undefined),
|
|
117
143
|
supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? true,
|
|
118
144
|
supportsTemperature: model.compat?.supportsTemperature ?? true,
|
|
119
145
|
allowEmptySignature: model.compat?.allowEmptySignature ?? false,
|
|
120
146
|
supportsStrictTools: model.compat?.supportsStrictTools ?? false,
|
|
121
|
-
|
|
147
|
+
supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
|
|
148
|
+
supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
|
|
122
149
|
};
|
|
123
150
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Default for `supportsToolReferences`: first-party Anthropic models except
|
|
126
|
-
* Haiku (rejects client-side tool_reference blocks) and models that predate
|
|
127
|
-
* tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).
|
|
128
|
-
*/
|
|
129
|
-
function defaultSupportsToolReferences(model) {
|
|
130
|
-
if (model.provider !== "anthropic" || model.id.includes("haiku"))
|
|
131
|
-
return false;
|
|
132
|
-
const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
|
|
133
|
-
if (!version)
|
|
134
|
-
return false;
|
|
135
|
-
const major = Number(version[1]);
|
|
136
|
-
const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
|
|
137
|
-
return major > 4 || (major === 4 && minor >= 5);
|
|
138
|
-
}
|
|
139
151
|
function mergeHeaders(...headerSources) {
|
|
140
152
|
const merged = {};
|
|
141
153
|
for (const headers of headerSources) {
|
|
@@ -145,6 +157,9 @@ function mergeHeaders(...headerSources) {
|
|
|
145
157
|
}
|
|
146
158
|
return merged;
|
|
147
159
|
}
|
|
160
|
+
function mergeClientHeaders(...headerSources) {
|
|
161
|
+
return mergeHeaders({ "User-Agent": getDrahtUserAgent() }, ...headerSources);
|
|
162
|
+
}
|
|
148
163
|
function hasHeader(headers, name) {
|
|
149
164
|
if (!headers)
|
|
150
165
|
return false;
|
|
@@ -155,16 +170,58 @@ function hasHeader(headers, name) {
|
|
|
155
170
|
}
|
|
156
171
|
return false;
|
|
157
172
|
}
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (hasHeader(headers, "authorization") ||
|
|
173
|
+
function hasRequestAuth(apiKey, headers) {
|
|
174
|
+
return (!!apiKey ||
|
|
175
|
+
hasHeader(headers, "authorization") ||
|
|
162
176
|
hasHeader(headers, "x-api-key") ||
|
|
163
|
-
hasHeader(headers, "cf-aig-authorization"))
|
|
164
|
-
|
|
177
|
+
hasHeader(headers, "cf-aig-authorization"));
|
|
178
|
+
}
|
|
179
|
+
function assertRequestAuth(provider, apiKey, headers) {
|
|
180
|
+
if (!hasRequestAuth(apiKey, headers))
|
|
181
|
+
throw new Error(`No API key for provider: ${provider}`);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Anthropic SDK client that never runs the SDK's own credential chain
|
|
185
|
+
* (ANTHROPIC_PROFILE config files, federation env vars). Without this, every
|
|
186
|
+
* client built with `apiKey: null, authToken: null` for header-owned auth would
|
|
187
|
+
* also resolve and exchange SDK credentials behind pi's auth resolver.
|
|
188
|
+
*/
|
|
189
|
+
class PiAnthropic extends Anthropic {
|
|
190
|
+
_shouldResolveDefaultCredentials() {
|
|
191
|
+
return false;
|
|
165
192
|
}
|
|
166
|
-
throw new Error(`No API key for provider: ${provider}`);
|
|
167
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Workload identity federation config from the ANTHROPIC_* variables the
|
|
196
|
+
* Anthropic SDK documents; the SDK performs the token exchange and refresh.
|
|
197
|
+
* Only for the anthropic provider, since the exchange is an Anthropic API
|
|
198
|
+
* endpoint, and only when no key or auth header was resolved.
|
|
199
|
+
*/
|
|
200
|
+
function getAnthropicFederation(model, apiKey, headers, env) {
|
|
201
|
+
if (model.provider !== "anthropic" || hasRequestAuth(apiKey, headers))
|
|
202
|
+
return undefined;
|
|
203
|
+
const federationRuleId = getProviderEnvValue(ANTHROPIC_FEDERATION_RULE_ID_ENV, env);
|
|
204
|
+
const organizationId = getProviderEnvValue(ANTHROPIC_ORGANIZATION_ID_ENV, env);
|
|
205
|
+
const identityTokenFile = getProviderEnvValue(ANTHROPIC_IDENTITY_TOKEN_FILE_ENV, env);
|
|
206
|
+
if (!federationRuleId || !organizationId || !identityTokenFile)
|
|
207
|
+
return undefined;
|
|
208
|
+
return {
|
|
209
|
+
organization_id: organizationId,
|
|
210
|
+
workspace_id: getProviderEnvValue(ANTHROPIC_WORKSPACE_ID_ENV, env),
|
|
211
|
+
authentication: {
|
|
212
|
+
type: "oidc_federation",
|
|
213
|
+
federation_rule_id: federationRuleId,
|
|
214
|
+
service_account_id: getProviderEnvValue(ANTHROPIC_SERVICE_ACCOUNT_ID_ENV, env),
|
|
215
|
+
identity_token: { source: "file", path: identityTokenFile },
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The SDK caches the federated access token per client, but pi creates a client
|
|
221
|
+
* per request. Keep one client for the current federation config and fetch, and
|
|
222
|
+
* clone it per request with `withOptions()`, which shares the token cache.
|
|
223
|
+
*/
|
|
224
|
+
let federationClient;
|
|
168
225
|
const ANTHROPIC_MESSAGE_EVENTS = new Set([
|
|
169
226
|
"message_start",
|
|
170
227
|
"message_delta",
|
|
@@ -318,13 +375,17 @@ async function* iterateAnthropicEvents(response, signal) {
|
|
|
318
375
|
}
|
|
319
376
|
export const stream = (model, context, options) => {
|
|
320
377
|
const stream = new AssistantMessageEventStream();
|
|
378
|
+
const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
|
|
379
|
+
const currentTools = getCurrentTools(normalizedContext.messages);
|
|
321
380
|
(async () => {
|
|
381
|
+
const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
|
|
322
382
|
const output = {
|
|
323
383
|
role: "assistant",
|
|
324
384
|
content: [],
|
|
325
385
|
api: model.api,
|
|
326
386
|
provider: model.provider,
|
|
327
387
|
model: model.id,
|
|
388
|
+
...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
|
|
328
389
|
usage: {
|
|
329
390
|
input: 0,
|
|
330
391
|
output: 0,
|
|
@@ -339,38 +400,42 @@ export const stream = (model, context, options) => {
|
|
|
339
400
|
try {
|
|
340
401
|
let client;
|
|
341
402
|
let isOAuth;
|
|
403
|
+
let usageModel = model;
|
|
404
|
+
let inputTransformations;
|
|
342
405
|
if (options?.client) {
|
|
343
406
|
client = options.client;
|
|
344
407
|
isOAuth = false;
|
|
345
408
|
}
|
|
346
409
|
else {
|
|
347
410
|
const apiKey = options?.apiKey;
|
|
348
|
-
|
|
411
|
+
const federation = getAnthropicFederation(model, apiKey, options?.headers, options?.env);
|
|
412
|
+
if (!federation)
|
|
413
|
+
assertRequestAuth(model.provider, apiKey, options?.headers);
|
|
349
414
|
let copilotDynamicHeaders;
|
|
350
415
|
if (model.provider === "github-copilot") {
|
|
351
|
-
const hasImages = hasCopilotVisionInput(
|
|
416
|
+
const hasImages = hasCopilotVisionInput(normalizedContext.messages);
|
|
352
417
|
copilotDynamicHeaders = buildCopilotDynamicHeaders({
|
|
353
|
-
messages:
|
|
418
|
+
messages: normalizedContext.messages,
|
|
354
419
|
hasImages,
|
|
355
420
|
});
|
|
356
421
|
}
|
|
357
422
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
358
423
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
359
|
-
const created = createClient(model, apiKey, options?.
|
|
424
|
+
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
|
|
360
425
|
client = created.client;
|
|
361
426
|
isOAuth = created.isOAuthToken;
|
|
362
427
|
}
|
|
363
|
-
let params = buildParams(model,
|
|
428
|
+
let params = buildParams(model, normalizedContext, isOAuth, options);
|
|
364
429
|
const nextParams = await options?.onPayload?.(params, model);
|
|
365
430
|
if (nextParams !== undefined) {
|
|
366
|
-
params = nextParams;
|
|
431
|
+
params = { ...nextParams, stream: true };
|
|
367
432
|
}
|
|
368
433
|
const requestOptions = {
|
|
369
434
|
...(options?.signal ? { signal: options.signal } : {}),
|
|
370
435
|
...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
|
|
371
436
|
maxRetries: 0,
|
|
372
437
|
};
|
|
373
|
-
const response = await retryProviderRequest(() => client.messages.create(
|
|
438
|
+
const response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
|
|
374
439
|
maxRetries: options?.maxRetries,
|
|
375
440
|
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
376
441
|
signal: options?.signal,
|
|
@@ -379,8 +444,19 @@ export const stream = (model, context, options) => {
|
|
|
379
444
|
stream.push({ type: "start", partial: output });
|
|
380
445
|
const blocks = output.content;
|
|
381
446
|
for await (const event of iterateAnthropicEvents(response, options?.signal)) {
|
|
447
|
+
await options?.onProviderStreamEvent?.(event, model);
|
|
382
448
|
if (event.type === "message_start") {
|
|
383
449
|
output.responseId = event.message.id;
|
|
450
|
+
const transformations = event.message.input_transformations;
|
|
451
|
+
if (Array.isArray(transformations))
|
|
452
|
+
inputTransformations = transformations;
|
|
453
|
+
const responseModel = event.message.model;
|
|
454
|
+
if (responseModel !== model.id)
|
|
455
|
+
output.responseModel = responseModel;
|
|
456
|
+
const fallbackCost = responseModel === model.id
|
|
457
|
+
? undefined
|
|
458
|
+
: model.compat?.allowedFallbackModels?.find((fallback) => fallback.provider === model.provider && fallback.model === responseModel)?.cost;
|
|
459
|
+
usageModel = fallbackCost ? { ...model, id: responseModel, cost: fallbackCost } : model;
|
|
384
460
|
// Capture initial token usage from message_start event
|
|
385
461
|
// This ensures we have input token counts even if the stream is aborted early
|
|
386
462
|
output.usage.input = event.message.usage.input_tokens || 0;
|
|
@@ -391,13 +467,19 @@ export const stream = (model, context, options) => {
|
|
|
391
467
|
// Anthropic doesn't provide total_tokens, compute from components
|
|
392
468
|
output.usage.totalTokens =
|
|
393
469
|
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
394
|
-
calculateCost(
|
|
470
|
+
calculateCost(usageModel, output.usage);
|
|
395
471
|
}
|
|
396
472
|
else if (event.type === "content_block_start") {
|
|
473
|
+
if (event.content_block.type === "fallback") {
|
|
474
|
+
if (output.content.length > 0) {
|
|
475
|
+
throw new Error("Anthropic performed an unsupported mid-output model fallback");
|
|
476
|
+
}
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
397
479
|
if (event.content_block.type === "text") {
|
|
398
480
|
const block = {
|
|
399
481
|
type: "text",
|
|
400
|
-
text: "",
|
|
482
|
+
text: event.content_block.text ?? "",
|
|
401
483
|
index: event.index,
|
|
402
484
|
};
|
|
403
485
|
output.content.push(block);
|
|
@@ -406,8 +488,8 @@ export const stream = (model, context, options) => {
|
|
|
406
488
|
else if (event.content_block.type === "thinking") {
|
|
407
489
|
const block = {
|
|
408
490
|
type: "thinking",
|
|
409
|
-
thinking: "",
|
|
410
|
-
thinkingSignature: "",
|
|
491
|
+
thinking: event.content_block.thinking ?? "",
|
|
492
|
+
thinkingSignature: event.content_block.signature ?? "",
|
|
411
493
|
index: event.index,
|
|
412
494
|
};
|
|
413
495
|
output.content.push(block);
|
|
@@ -429,7 +511,7 @@ export const stream = (model, context, options) => {
|
|
|
429
511
|
type: "toolCall",
|
|
430
512
|
id: event.content_block.id,
|
|
431
513
|
name: isOAuth
|
|
432
|
-
? fromClaudeCodeName(event.content_block.name,
|
|
514
|
+
? fromClaudeCodeName(event.content_block.name, currentTools)
|
|
433
515
|
: event.content_block.name,
|
|
434
516
|
arguments: event.content_block.input ?? {},
|
|
435
517
|
partialJson: "",
|
|
@@ -525,6 +607,9 @@ export const stream = (model, context, options) => {
|
|
|
525
607
|
}
|
|
526
608
|
}
|
|
527
609
|
else if (event.type === "message_delta") {
|
|
610
|
+
const transformations = event.input_transformations;
|
|
611
|
+
if (Array.isArray(transformations))
|
|
612
|
+
inputTransformations = transformations;
|
|
528
613
|
if (event.delta.stop_reason) {
|
|
529
614
|
output.rawStopReason = event.delta.stop_reason;
|
|
530
615
|
const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
|
|
@@ -548,11 +633,13 @@ export const stream = (model, context, options) => {
|
|
|
548
633
|
if (event.usage.cache_creation_input_tokens != null) {
|
|
549
634
|
output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
|
|
550
635
|
}
|
|
551
|
-
//
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
636
|
+
// Vercel AI Gateway includes the TTL breakdown in deltas, though the SDK only types it on message_start.
|
|
637
|
+
const cacheCreation = event.usage.cache_creation;
|
|
638
|
+
if (cacheCreation?.ephemeral_1h_input_tokens != null) {
|
|
639
|
+
output.usage.cacheWrite1h = cacheCreation.ephemeral_1h_input_tokens;
|
|
640
|
+
}
|
|
641
|
+
// Anthropic reports reasoning tokens as a subset of output tokens.
|
|
642
|
+
const thinkingTokens = event.usage.output_tokens_details?.thinking_tokens;
|
|
556
643
|
if (thinkingTokens != null) {
|
|
557
644
|
output.usage.reasoning = thinkingTokens;
|
|
558
645
|
}
|
|
@@ -560,7 +647,7 @@ export const stream = (model, context, options) => {
|
|
|
560
647
|
// Anthropic doesn't provide total_tokens, compute from components
|
|
561
648
|
output.usage.totalTokens =
|
|
562
649
|
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
563
|
-
calculateCost(
|
|
650
|
+
calculateCost(usageModel, output.usage);
|
|
564
651
|
}
|
|
565
652
|
}
|
|
566
653
|
if (options?.signal?.aborted) {
|
|
@@ -572,6 +659,19 @@ export const stream = (model, context, options) => {
|
|
|
572
659
|
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
573
660
|
throw new Error(output.errorMessage || "An unknown error occurred");
|
|
574
661
|
}
|
|
662
|
+
if (inputTransformations && inputTransformations.length > 0) {
|
|
663
|
+
appendAssistantMessageDiagnostic(output, {
|
|
664
|
+
type: "anthropic_input_transformations",
|
|
665
|
+
timestamp: Date.now(),
|
|
666
|
+
details: {
|
|
667
|
+
transformations: inputTransformations.map((transformation) => ({
|
|
668
|
+
type: transformation.type ?? undefined,
|
|
669
|
+
path: transformation.path ?? undefined,
|
|
670
|
+
reason: transformation.reason ?? undefined,
|
|
671
|
+
})),
|
|
672
|
+
},
|
|
673
|
+
});
|
|
674
|
+
}
|
|
575
675
|
stream.push({ type: "done", reason: output.stopReason, message: output });
|
|
576
676
|
stream.end();
|
|
577
677
|
}
|
|
@@ -611,10 +711,18 @@ function mapThinkingLevelToEffort(model, level) {
|
|
|
611
711
|
}
|
|
612
712
|
}
|
|
613
713
|
export const streamSimple = (model, context, options) => {
|
|
614
|
-
|
|
615
|
-
|
|
714
|
+
if (!getAnthropicFederation(model, options?.apiKey, options?.headers, options?.env)) {
|
|
715
|
+
assertRequestAuth(model.provider, options?.apiKey, options?.headers);
|
|
716
|
+
}
|
|
717
|
+
const base = {
|
|
718
|
+
...buildBaseOptions(model, context, options, options?.apiKey),
|
|
719
|
+
toolChoice: options?.toolChoice,
|
|
720
|
+
};
|
|
616
721
|
if (!options?.reasoning) {
|
|
617
|
-
return stream(model, context, {
|
|
722
|
+
return stream(model, context, {
|
|
723
|
+
...base,
|
|
724
|
+
thinkingEnabled: false,
|
|
725
|
+
});
|
|
618
726
|
}
|
|
619
727
|
// For models with adaptive thinking: use an effort level.
|
|
620
728
|
// For older models: use budget-based thinking.
|
|
@@ -640,58 +748,66 @@ export const streamSimple = (model, context, options) => {
|
|
|
640
748
|
function isOAuthToken(apiKey) {
|
|
641
749
|
return apiKey.includes("sk-ant-oat");
|
|
642
750
|
}
|
|
643
|
-
function createClient(model, apiKey,
|
|
644
|
-
//
|
|
645
|
-
const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
|
|
646
|
-
const betaFeatures = [];
|
|
647
|
-
if (useFineGrainedToolStreamingBeta) {
|
|
648
|
-
betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA);
|
|
649
|
-
}
|
|
650
|
-
if (needsInterleavedBeta) {
|
|
651
|
-
betaFeatures.push(INTERLEAVED_THINKING_BETA);
|
|
652
|
-
}
|
|
653
|
-
// Copilot: Bearer auth, selective betas.
|
|
751
|
+
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
|
|
752
|
+
// Copilot: Bearer auth.
|
|
654
753
|
if (model.provider === "github-copilot") {
|
|
655
|
-
const client = new
|
|
754
|
+
const client = new PiAnthropic({
|
|
656
755
|
apiKey: null,
|
|
657
756
|
authToken: apiKey ?? null,
|
|
658
757
|
baseURL: model.baseUrl,
|
|
659
758
|
dangerouslyAllowBrowser: true,
|
|
660
759
|
fetch,
|
|
661
|
-
defaultHeaders:
|
|
760
|
+
defaultHeaders: mergeClientHeaders({
|
|
662
761
|
accept: "application/json",
|
|
663
762
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
664
|
-
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
665
763
|
}, model.headers, dynamicHeaders, optionsHeaders),
|
|
666
764
|
});
|
|
667
765
|
return { client, isOAuthToken: false };
|
|
668
766
|
}
|
|
669
767
|
// OAuth: Bearer auth, Claude Code identity headers
|
|
670
768
|
if (apiKey && isOAuthToken(apiKey)) {
|
|
671
|
-
const client = new
|
|
769
|
+
const client = new PiAnthropic({
|
|
672
770
|
apiKey: null,
|
|
673
771
|
authToken: apiKey,
|
|
674
772
|
baseURL: model.baseUrl,
|
|
675
773
|
dangerouslyAllowBrowser: true,
|
|
676
774
|
fetch,
|
|
677
|
-
defaultHeaders:
|
|
775
|
+
defaultHeaders: mergeClientHeaders({
|
|
678
776
|
accept: "application/json",
|
|
679
777
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
680
|
-
"anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
|
|
681
778
|
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
|
682
779
|
"x-app": "cli",
|
|
683
780
|
}, model.headers, optionsHeaders),
|
|
684
781
|
});
|
|
685
782
|
return { client, isOAuthToken: true };
|
|
686
783
|
}
|
|
687
|
-
// API key
|
|
688
|
-
const
|
|
689
|
-
const
|
|
784
|
+
// API key, header-owned auth, or workload identity federation.
|
|
785
|
+
const compat = getAnthropicCompat(model);
|
|
786
|
+
const sessionAffinityHeaders = {};
|
|
787
|
+
if (sessionId && compat.sendSessionAffinityHeaders) {
|
|
788
|
+
const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
|
|
789
|
+
sessionAffinityHeaders[header] = sessionId;
|
|
790
|
+
}
|
|
791
|
+
const defaultHeaders = mergeClientHeaders({
|
|
690
792
|
accept: "application/json",
|
|
691
793
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
692
|
-
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
693
794
|
}, sessionAffinityHeaders, model.headers, optionsHeaders);
|
|
694
|
-
|
|
795
|
+
if (federation) {
|
|
796
|
+
const key = JSON.stringify([model.baseUrl, federation]);
|
|
797
|
+
if (federationClient?.key !== key || federationClient.fetch !== fetch) {
|
|
798
|
+
const client = new PiAnthropic({
|
|
799
|
+
apiKey: null,
|
|
800
|
+
authToken: null,
|
|
801
|
+
config: federation,
|
|
802
|
+
baseURL: model.baseUrl,
|
|
803
|
+
dangerouslyAllowBrowser: true,
|
|
804
|
+
fetch,
|
|
805
|
+
});
|
|
806
|
+
federationClient = { key, fetch, client };
|
|
807
|
+
}
|
|
808
|
+
return { client: federationClient.client.withOptions({ defaultHeaders }), isOAuthToken: false };
|
|
809
|
+
}
|
|
810
|
+
const client = new PiAnthropic({
|
|
695
811
|
apiKey: apiKey ?? null,
|
|
696
812
|
authToken: null,
|
|
697
813
|
baseURL: model.baseUrl,
|
|
@@ -701,24 +817,70 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
701
817
|
});
|
|
702
818
|
return { client, isOAuthToken: false };
|
|
703
819
|
}
|
|
820
|
+
function getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, options) {
|
|
821
|
+
let configuredFeatures;
|
|
822
|
+
for (const headers of [model.headers, options?.headers]) {
|
|
823
|
+
for (const [name, value] of Object.entries(headers ?? {})) {
|
|
824
|
+
if (name.toLowerCase() === "anthropic-beta")
|
|
825
|
+
configuredFeatures = value;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
if (configuredFeatures === null)
|
|
829
|
+
return [];
|
|
830
|
+
if (configuredFeatures !== undefined) {
|
|
831
|
+
return [
|
|
832
|
+
...new Set(configuredFeatures
|
|
833
|
+
.split(",")
|
|
834
|
+
.map((feature) => feature.trim())
|
|
835
|
+
.filter((feature) => feature.length > 0)),
|
|
836
|
+
];
|
|
837
|
+
}
|
|
838
|
+
const features = [];
|
|
839
|
+
if (isOAuthToken)
|
|
840
|
+
features.push("claude-code-20250219", "oauth-2025-04-20");
|
|
841
|
+
if (shouldUseFineGrainedToolStreamingBeta(model, context))
|
|
842
|
+
features.push(FINE_GRAINED_TOOL_STREAMING_BETA);
|
|
843
|
+
if (model.reasoning &&
|
|
844
|
+
options?.thinkingEnabled === true &&
|
|
845
|
+
(options.interleavedThinking ?? true) &&
|
|
846
|
+
model.compat?.forceAdaptiveThinking !== true) {
|
|
847
|
+
features.push(INTERLEAVED_THINKING_BETA);
|
|
848
|
+
}
|
|
849
|
+
if (shouldUseServerSideFallbackBeta(model))
|
|
850
|
+
features.push(SERVER_SIDE_FALLBACK_BETA);
|
|
851
|
+
if (model.compat?.supportsMidConvoEffort === true) {
|
|
852
|
+
features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
|
|
853
|
+
}
|
|
854
|
+
if (nativeToolChanges)
|
|
855
|
+
features.push(MID_CONVERSATION_TOOL_CHANGES_BETA);
|
|
856
|
+
return [...new Set(features)];
|
|
857
|
+
}
|
|
704
858
|
function buildParams(model, context, isOAuthToken, options) {
|
|
705
859
|
const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
|
|
706
860
|
const compat = getAnthropicCompat(model);
|
|
861
|
+
const initialSystemMessage = getInitialSystemMessage(context.messages);
|
|
862
|
+
const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
|
|
707
863
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
864
|
+
const conversationMessages = initialSystemMessage ? transformedMessages.slice(1) : transformedMessages;
|
|
865
|
+
// Native tool changes reference tools by name, so a redefined name cannot be expressed,
|
|
866
|
+
// and Anthropic rejects a tool list where every tool is deferred, so there must be an
|
|
867
|
+
// initial active tool to anchor the deferred ones. Otherwise the current tool list is sent.
|
|
868
|
+
const initialTools = initialSystemMessage?.toolsAdded ?? [];
|
|
869
|
+
const nativeToolChanges = compat.supportsMidConvoSystemMessages &&
|
|
870
|
+
compat.supportsMidConvoToolChanges &&
|
|
871
|
+
initialTools.length > 0 &&
|
|
872
|
+
!hasToolRedefinitions(context.messages);
|
|
873
|
+
const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, model.compat?.supportsMidConvoEffort === true ? model.provider : undefined, nativeToolChanges);
|
|
874
|
+
const activeEffort = options?.effort ?? "high";
|
|
875
|
+
const betaFeatures = getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, options);
|
|
717
876
|
const params = {
|
|
718
877
|
model: model.id,
|
|
719
|
-
messages:
|
|
878
|
+
messages: model.compat?.supportsMidConvoEffort === true
|
|
879
|
+
? insertThinkingLevelMessages(converted, activeEffort)
|
|
880
|
+
: converted.messages,
|
|
720
881
|
max_tokens: options?.maxTokens ?? model.maxTokens,
|
|
721
882
|
stream: true,
|
|
883
|
+
...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
|
|
722
884
|
};
|
|
723
885
|
// For OAuth tokens, we MUST include Claude Code identity
|
|
724
886
|
if (isOAuthToken) {
|
|
@@ -729,36 +891,62 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
729
891
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
730
892
|
},
|
|
731
893
|
];
|
|
732
|
-
if (
|
|
894
|
+
if (initialSystemText) {
|
|
733
895
|
params.system.push({
|
|
734
896
|
type: "text",
|
|
735
|
-
text: sanitizeSurrogates(
|
|
897
|
+
text: sanitizeSurrogates(initialSystemText),
|
|
736
898
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
737
899
|
});
|
|
738
900
|
}
|
|
739
901
|
}
|
|
740
|
-
else if (
|
|
902
|
+
else if (initialSystemText) {
|
|
741
903
|
// Add cache control to system prompt for non-OAuth tokens
|
|
742
904
|
params.system = [
|
|
743
905
|
{
|
|
744
906
|
type: "text",
|
|
745
|
-
text: sanitizeSurrogates(
|
|
907
|
+
text: sanitizeSurrogates(initialSystemText),
|
|
746
908
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
747
909
|
},
|
|
748
910
|
];
|
|
749
911
|
}
|
|
750
912
|
// Temperature is incompatible with extended thinking and unsupported on Claude Opus 4.7+.
|
|
751
|
-
if (options?.temperature !== undefined &&
|
|
913
|
+
if (options?.temperature !== undefined &&
|
|
914
|
+
!options?.thinkingEnabled &&
|
|
915
|
+
model.compat?.supportsMidConvoEffort !== true &&
|
|
916
|
+
compat.supportsTemperature) {
|
|
752
917
|
params.temperature = options.temperature;
|
|
753
918
|
}
|
|
754
|
-
|
|
919
|
+
const toolCacheControl = compat.supportsCacheControlOnTools ? cacheControl : undefined;
|
|
920
|
+
if (nativeToolChanges) {
|
|
921
|
+
// Initial tools stay active with the cache breakpoint on the last one. Every later
|
|
922
|
+
// declaration is deferred and only surfaced by its `tool_addition` block; removed
|
|
923
|
+
// tools stay declared and are withdrawn by `tool_removal`. The request-level list
|
|
924
|
+
// therefore only grows, keeping the cached prefix intact across tool changes.
|
|
925
|
+
const initialNames = new Set(initialTools.map((tool) => tool.name));
|
|
926
|
+
const laterTools = getDeclaredTools(context.messages).filter((tool) => !initialNames.has(tool.name));
|
|
755
927
|
params.tools = [
|
|
756
|
-
...convertTools(
|
|
757
|
-
|
|
928
|
+
...convertTools(initialTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl),
|
|
929
|
+
DEFERRED_TOOL_PLACEHOLDER,
|
|
930
|
+
...convertTools(laterTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools).map((tool) => ({ ...tool, defer_loading: true })),
|
|
758
931
|
];
|
|
759
932
|
}
|
|
760
|
-
|
|
761
|
-
|
|
933
|
+
else {
|
|
934
|
+
const tools = getCurrentTools(context.messages);
|
|
935
|
+
if (tools.length > 0) {
|
|
936
|
+
params.tools = convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
// Managed effort models always use adaptive thinking so prefix mismatches can
|
|
940
|
+
// be dropped instead of surfacing as persistent 400 responses.
|
|
941
|
+
if (model.compat?.supportsMidConvoEffort === true) {
|
|
942
|
+
params.thinking = {
|
|
943
|
+
type: "adaptive",
|
|
944
|
+
display: options?.thinkingDisplay ?? "summarized",
|
|
945
|
+
block_binding: { prefix_mismatch_behavior: "drop_block" },
|
|
946
|
+
};
|
|
947
|
+
params.output_config = { effort: "high" };
|
|
948
|
+
}
|
|
949
|
+
else if (model.reasoning) {
|
|
762
950
|
if (options?.thinkingEnabled) {
|
|
763
951
|
// Default to "summarized" so Opus 4.7 and Mythos Preview behave like
|
|
764
952
|
// older Claude 4 models (whose API default is also "summarized").
|
|
@@ -767,11 +955,7 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
767
955
|
// Adaptive thinking: Claude decides when and how much to think.
|
|
768
956
|
params.thinking = { type: "adaptive", display };
|
|
769
957
|
if (options.effort) {
|
|
770
|
-
|
|
771
|
-
params.output_config =
|
|
772
|
-
options.effort === "xhigh"
|
|
773
|
-
? { effort: options.effort }
|
|
774
|
-
: { effort: options.effort };
|
|
958
|
+
params.output_config = { effort: options.effort };
|
|
775
959
|
}
|
|
776
960
|
}
|
|
777
961
|
else {
|
|
@@ -801,46 +985,64 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
801
985
|
params.tool_choice = options.toolChoice;
|
|
802
986
|
}
|
|
803
987
|
}
|
|
988
|
+
const allowedFallbackModels = model.compat?.allowedFallbackModels;
|
|
989
|
+
if (allowedFallbackModels && allowedFallbackModels.length > 0) {
|
|
990
|
+
params.fallbacks = allowedFallbackModels.map((fallback) => ({ model: fallback.model }));
|
|
991
|
+
}
|
|
804
992
|
return params;
|
|
805
993
|
}
|
|
806
994
|
// Normalize tool call IDs to match Anthropic's required pattern and length
|
|
807
995
|
function normalizeToolCallId(id) {
|
|
808
996
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
809
997
|
}
|
|
810
|
-
function convertToolResult(msg
|
|
811
|
-
const references = [];
|
|
812
|
-
for (const name of msg.addedToolNames ?? []) {
|
|
813
|
-
const normalizedName = normalizeToolName(name);
|
|
814
|
-
if (!deferredToolNames.has(normalizedName) || loadedToolNames.has(normalizedName))
|
|
815
|
-
continue;
|
|
816
|
-
loadedToolNames.add(normalizedName);
|
|
817
|
-
references.push({
|
|
818
|
-
type: "tool_reference",
|
|
819
|
-
tool_name: isOAuthToken ? toClaudeCodeName(name) : name,
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
const convertedContent = convertContentBlocks(msg.content);
|
|
823
|
-
// Anthropic rejects tool references mixed with ordinary tool-result content.
|
|
998
|
+
function convertToolResult(msg) {
|
|
824
999
|
return {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
is_error: msg.isError,
|
|
830
|
-
},
|
|
831
|
-
siblingContent: references.length === 0
|
|
832
|
-
? []
|
|
833
|
-
: typeof convertedContent === "string"
|
|
834
|
-
? [{ type: "text", text: convertedContent }]
|
|
835
|
-
: convertedContent,
|
|
1000
|
+
type: "tool_result",
|
|
1001
|
+
tool_use_id: msg.toolCallId,
|
|
1002
|
+
content: convertContentBlocks(msg.content),
|
|
1003
|
+
is_error: msg.isError,
|
|
836
1004
|
};
|
|
837
1005
|
}
|
|
838
|
-
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false,
|
|
1006
|
+
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, nativeToolChanges = false) {
|
|
839
1007
|
const params = [];
|
|
840
|
-
const
|
|
1008
|
+
const assistantLevels = new Map();
|
|
1009
|
+
// Later system messages are held back and emitted directly before the next assistant
|
|
1010
|
+
// message (or at the end of the transcript). Anthropic requires `tool_result` blocks to
|
|
1011
|
+
// immediately follow their `tool_use`, so a system message between them is rejected; this
|
|
1012
|
+
// also mirrors where the managed-effort system messages are inserted. As a result an
|
|
1013
|
+
// update placed before a user message in the transcript lands after it on the wire.
|
|
1014
|
+
const pendingSystemMessages = [];
|
|
1015
|
+
const flushPendingSystemMessages = () => {
|
|
1016
|
+
params.push(...pendingSystemMessages);
|
|
1017
|
+
pendingSystemMessages.length = 0;
|
|
1018
|
+
};
|
|
841
1019
|
for (let i = 0; i < transformedMessages.length; i++) {
|
|
842
1020
|
const msg = transformedMessages[i];
|
|
843
|
-
if (msg.role === "
|
|
1021
|
+
if (msg.role === "system") {
|
|
1022
|
+
// Later system messages only reach this point when the model accepts them natively;
|
|
1023
|
+
// otherwise the transcript was collapsed into the leading message before conversion.
|
|
1024
|
+
const text = renderSystemMessageUpdate(msg);
|
|
1025
|
+
const blocks = [];
|
|
1026
|
+
if (text.length > 0)
|
|
1027
|
+
blocks.push({ type: "text", text: sanitizeSurrogates(text) });
|
|
1028
|
+
if (nativeToolChanges) {
|
|
1029
|
+
for (const tool of msg.toolsRemoved ?? []) {
|
|
1030
|
+
blocks.push({
|
|
1031
|
+
type: "tool_removal",
|
|
1032
|
+
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
for (const tool of msg.toolsAdded ?? []) {
|
|
1036
|
+
blocks.push({
|
|
1037
|
+
type: "tool_addition",
|
|
1038
|
+
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
if (blocks.length > 0)
|
|
1043
|
+
pendingSystemMessages.push({ role: "system", content: blocks });
|
|
1044
|
+
}
|
|
1045
|
+
else if (msg.role === "user") {
|
|
844
1046
|
if (typeof msg.content === "string") {
|
|
845
1047
|
if (msg.content.trim().length > 0) {
|
|
846
1048
|
params.push({
|
|
@@ -883,6 +1085,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
883
1085
|
}
|
|
884
1086
|
}
|
|
885
1087
|
else if (msg.role === "assistant") {
|
|
1088
|
+
flushPendingSystemMessages();
|
|
886
1089
|
const blocks = [];
|
|
887
1090
|
for (const block of msg.content) {
|
|
888
1091
|
if (block.type === "text") {
|
|
@@ -940,39 +1143,47 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
940
1143
|
}
|
|
941
1144
|
if (blocks.length === 0)
|
|
942
1145
|
continue;
|
|
1146
|
+
const messageIndex = params.length;
|
|
943
1147
|
params.push({
|
|
944
1148
|
role: "assistant",
|
|
945
1149
|
content: blocks,
|
|
946
1150
|
});
|
|
1151
|
+
if (managedProvider !== undefined &&
|
|
1152
|
+
msg.api === "anthropic-messages" &&
|
|
1153
|
+
msg.provider === managedProvider &&
|
|
1154
|
+
isAnthropicEffort(msg.providerThinkingLevel)) {
|
|
1155
|
+
assistantLevels.set(messageIndex, msg.providerThinkingLevel);
|
|
1156
|
+
}
|
|
947
1157
|
}
|
|
948
1158
|
else if (msg.role === "toolResult") {
|
|
949
1159
|
// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
|
|
950
1160
|
const toolResults = [];
|
|
951
|
-
const siblingContent = [];
|
|
952
1161
|
let j = i;
|
|
953
1162
|
while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
|
|
954
|
-
|
|
955
|
-
toolResults.push(converted.toolResult);
|
|
956
|
-
siblingContent.push(...converted.siblingContent);
|
|
1163
|
+
toolResults.push(convertToolResult(transformedMessages[j]));
|
|
957
1164
|
j++;
|
|
958
1165
|
}
|
|
959
1166
|
// Skip the messages we've already processed.
|
|
960
1167
|
i = j - 1;
|
|
961
|
-
// Displaced reference-bearing results must follow every tool_result block.
|
|
962
1168
|
params.push({
|
|
963
1169
|
role: "user",
|
|
964
|
-
content:
|
|
1170
|
+
content: toolResults,
|
|
965
1171
|
});
|
|
966
1172
|
}
|
|
967
1173
|
}
|
|
968
|
-
|
|
1174
|
+
flushPendingSystemMessages();
|
|
1175
|
+
// Add cache_control to the last user or system message to cache conversation history
|
|
969
1176
|
if (cacheControl && params.length > 0) {
|
|
970
1177
|
const lastMessage = params[params.length - 1];
|
|
971
|
-
if (lastMessage.role === "user") {
|
|
1178
|
+
if (lastMessage.role === "user" || lastMessage.role === "system") {
|
|
972
1179
|
if (Array.isArray(lastMessage.content)) {
|
|
973
1180
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
974
1181
|
if (lastBlock &&
|
|
975
|
-
(lastBlock.type === "text" ||
|
|
1182
|
+
(lastBlock.type === "text" ||
|
|
1183
|
+
lastBlock.type === "image" ||
|
|
1184
|
+
lastBlock.type === "tool_result" ||
|
|
1185
|
+
lastBlock.type === "tool_addition" ||
|
|
1186
|
+
lastBlock.type === "tool_removal")) {
|
|
976
1187
|
lastBlock.cache_control = cacheControl;
|
|
977
1188
|
}
|
|
978
1189
|
}
|
|
@@ -987,17 +1198,69 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
987
1198
|
}
|
|
988
1199
|
}
|
|
989
1200
|
}
|
|
990
|
-
return params;
|
|
1201
|
+
return { messages: params, assistantLevels };
|
|
1202
|
+
}
|
|
1203
|
+
function isAnthropicEffort(value) {
|
|
1204
|
+
return value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
|
|
1205
|
+
}
|
|
1206
|
+
function insertThinkingLevelMessages(converted, activeEffort) {
|
|
1207
|
+
const messages = [];
|
|
1208
|
+
for (let index = 0; index < converted.messages.length; index++) {
|
|
1209
|
+
const historicalEffort = converted.assistantLevels.get(index);
|
|
1210
|
+
if (historicalEffort !== undefined) {
|
|
1211
|
+
messages.push({ role: "system", content: [], output_config: { effort: historicalEffort } });
|
|
1212
|
+
}
|
|
1213
|
+
messages.push(converted.messages[index]);
|
|
1214
|
+
}
|
|
1215
|
+
messages.push({ role: "system", content: [], output_config: { effort: activeEffort } });
|
|
1216
|
+
return messages;
|
|
991
1217
|
}
|
|
992
1218
|
function shouldUseFineGrainedToolStreamingBeta(model, context) {
|
|
993
|
-
return
|
|
1219
|
+
return getCurrentTools(context.messages).length > 0 && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
|
|
994
1220
|
}
|
|
995
|
-
|
|
1221
|
+
// Keywords Anthropic strict tool use rejects with a 400 for the whole request.
|
|
1222
|
+
// https://platform.claude.com/docs/en/build-with-claude/structured-outputs#json-schema-limitations
|
|
1223
|
+
const ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS = new Set([
|
|
1224
|
+
"minimum",
|
|
1225
|
+
"maximum",
|
|
1226
|
+
"exclusiveMinimum",
|
|
1227
|
+
"exclusiveMaximum",
|
|
1228
|
+
"multipleOf",
|
|
1229
|
+
"maxItems",
|
|
1230
|
+
"uniqueItems",
|
|
1231
|
+
"minContains",
|
|
1232
|
+
"maxContains",
|
|
1233
|
+
"minProperties",
|
|
1234
|
+
"maxProperties",
|
|
1235
|
+
]);
|
|
1236
|
+
const ANTHROPIC_STRICT_STRING_FORMATS = new Set([
|
|
1237
|
+
"date-time",
|
|
1238
|
+
"time",
|
|
1239
|
+
"date",
|
|
1240
|
+
"duration",
|
|
1241
|
+
"email",
|
|
1242
|
+
"hostname",
|
|
1243
|
+
"uri",
|
|
1244
|
+
"ipv4",
|
|
1245
|
+
"ipv6",
|
|
1246
|
+
"uuid",
|
|
1247
|
+
]);
|
|
1248
|
+
const isAnthropicStrictUnsupportedKeyword = (key, value) => {
|
|
1249
|
+
if (ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS.has(key))
|
|
1250
|
+
return true;
|
|
1251
|
+
if (key === "minItems")
|
|
1252
|
+
return value !== 0 && value !== 1;
|
|
1253
|
+
if (key === "format")
|
|
1254
|
+
return typeof value !== "string" || !ANTHROPIC_STRICT_STRING_FORMATS.has(value);
|
|
1255
|
+
return false;
|
|
1256
|
+
};
|
|
1257
|
+
function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl) {
|
|
996
1258
|
if (!tools)
|
|
997
1259
|
return [];
|
|
998
1260
|
return tools.map((tool, index) => {
|
|
999
|
-
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
|
|
1000
|
-
const
|
|
1261
|
+
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
|
|
1262
|
+
const parameters = getJsonSchemaToolParameters(tool, strict);
|
|
1263
|
+
const schema = parameters;
|
|
1001
1264
|
const legacyInputSchema = {
|
|
1002
1265
|
type: "object",
|
|
1003
1266
|
properties: schema.properties ?? {},
|
|
@@ -1005,7 +1268,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1005
1268
|
};
|
|
1006
1269
|
const inputSchema = strict === true
|
|
1007
1270
|
? {
|
|
1008
|
-
...
|
|
1271
|
+
...parameters,
|
|
1009
1272
|
...legacyInputSchema,
|
|
1010
1273
|
}
|
|
1011
1274
|
: legacyInputSchema;
|
|
@@ -1015,7 +1278,6 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1015
1278
|
...(supportsEagerToolInputStreaming ? { eager_input_streaming: true } : {}),
|
|
1016
1279
|
...(strict === true ? { strict: true } : {}),
|
|
1017
1280
|
input_schema: inputSchema,
|
|
1018
|
-
...(deferLoading ? { defer_loading: true } : {}),
|
|
1019
1281
|
...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),
|
|
1020
1282
|
};
|
|
1021
1283
|
});
|