@draht/ai 2026.9.5-1 → 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 +392 -137
- 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 -11
- 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 +194 -22
- 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.map +1 -1
- package/dist/api/google-generative-ai.js +26 -73
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +14 -5
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +68 -13
- 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 +30 -65
- 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 +246 -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 +58 -24
- 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 +232 -126
- 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 +58 -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 +12 -3
- 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 +13 -9
- 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 +26 -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 +3 -2
- 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.map +1 -1
- package/dist/providers/xai.js +1 -0
- 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 +409 -128
- 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/{pi-user-agent.js → draht-user-agent.js} +3 -3
- package/dist/utils/draht-user-agent.js.map +1 -0
- 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/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 +18 -2
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/sleep.d.ts +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js +4 -4
- package/dist/utils/sleep.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/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 +34 -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/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.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,26 +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
|
-
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
8
9
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
9
10
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
10
11
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
11
|
-
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";
|
|
12
15
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
13
16
|
import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
|
|
14
17
|
import { transformMessages } from "./transform-messages.js";
|
|
15
18
|
/**
|
|
16
19
|
* Resolve cache retention preference.
|
|
17
|
-
* Defaults to "short" and uses
|
|
20
|
+
* Defaults to "short" and uses DRAHT_CACHE_RETENTION for backward compatibility.
|
|
18
21
|
*/
|
|
19
22
|
function resolveCacheRetention(cacheRetention, env) {
|
|
20
23
|
if (cacheRetention) {
|
|
21
24
|
return cacheRetention;
|
|
22
25
|
}
|
|
23
|
-
if (getProviderEnvValue("
|
|
26
|
+
if (getProviderEnvValue("DRAHT_CACHE_RETENTION", env) === "long") {
|
|
24
27
|
return "long";
|
|
25
28
|
}
|
|
26
29
|
return "short";
|
|
@@ -37,7 +40,7 @@ function getCacheControl(model, cacheRetention, env) {
|
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
// Stealth mode: Mimic Claude Code's tool naming exactly
|
|
40
|
-
const claudeCodeVersion = "2.1.
|
|
43
|
+
const claudeCodeVersion = "2.1.280";
|
|
41
44
|
// Claude Code 2.x tool names (canonical casing)
|
|
42
45
|
// Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
|
|
43
46
|
// To update: https://github.com/badlogic/cchistory
|
|
@@ -110,33 +113,41 @@ function convertContentBlocks(content) {
|
|
|
110
113
|
}
|
|
111
114
|
const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
|
|
112
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
|
+
}
|
|
113
136
|
function getAnthropicCompat(model) {
|
|
137
|
+
const isOpenRouter = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
|
|
114
138
|
return {
|
|
115
139
|
supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
|
|
116
140
|
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
|
117
|
-
sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ??
|
|
141
|
+
sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter,
|
|
142
|
+
sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? "openrouter" : undefined),
|
|
118
143
|
supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? true,
|
|
119
144
|
supportsTemperature: model.compat?.supportsTemperature ?? true,
|
|
120
145
|
allowEmptySignature: model.compat?.allowEmptySignature ?? false,
|
|
121
146
|
supportsStrictTools: model.compat?.supportsStrictTools ?? false,
|
|
122
|
-
|
|
147
|
+
supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
|
|
148
|
+
supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
|
|
123
149
|
};
|
|
124
150
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Default for `supportsToolReferences`: first-party Anthropic models except
|
|
127
|
-
* Haiku (rejects client-side tool_reference blocks) and models that predate
|
|
128
|
-
* tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).
|
|
129
|
-
*/
|
|
130
|
-
function defaultSupportsToolReferences(model) {
|
|
131
|
-
if (model.provider !== "anthropic" || model.id.includes("haiku"))
|
|
132
|
-
return false;
|
|
133
|
-
const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
|
|
134
|
-
if (!version)
|
|
135
|
-
return false;
|
|
136
|
-
const major = Number(version[1]);
|
|
137
|
-
const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
|
|
138
|
-
return major > 4 || (major === 4 && minor >= 5);
|
|
139
|
-
}
|
|
140
151
|
function mergeHeaders(...headerSources) {
|
|
141
152
|
const merged = {};
|
|
142
153
|
for (const headers of headerSources) {
|
|
@@ -147,7 +158,7 @@ function mergeHeaders(...headerSources) {
|
|
|
147
158
|
return merged;
|
|
148
159
|
}
|
|
149
160
|
function mergeClientHeaders(...headerSources) {
|
|
150
|
-
return mergeHeaders({ "User-Agent":
|
|
161
|
+
return mergeHeaders({ "User-Agent": getDrahtUserAgent() }, ...headerSources);
|
|
151
162
|
}
|
|
152
163
|
function hasHeader(headers, name) {
|
|
153
164
|
if (!headers)
|
|
@@ -159,16 +170,58 @@ function hasHeader(headers, name) {
|
|
|
159
170
|
}
|
|
160
171
|
return false;
|
|
161
172
|
}
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (hasHeader(headers, "authorization") ||
|
|
173
|
+
function hasRequestAuth(apiKey, headers) {
|
|
174
|
+
return (!!apiKey ||
|
|
175
|
+
hasHeader(headers, "authorization") ||
|
|
166
176
|
hasHeader(headers, "x-api-key") ||
|
|
167
|
-
hasHeader(headers, "cf-aig-authorization"))
|
|
168
|
-
|
|
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;
|
|
169
192
|
}
|
|
170
|
-
throw new Error(`No API key for provider: ${provider}`);
|
|
171
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;
|
|
172
225
|
const ANTHROPIC_MESSAGE_EVENTS = new Set([
|
|
173
226
|
"message_start",
|
|
174
227
|
"message_delta",
|
|
@@ -322,13 +375,17 @@ async function* iterateAnthropicEvents(response, signal) {
|
|
|
322
375
|
}
|
|
323
376
|
export const stream = (model, context, options) => {
|
|
324
377
|
const stream = new AssistantMessageEventStream();
|
|
378
|
+
const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
|
|
379
|
+
const currentTools = getCurrentTools(normalizedContext.messages);
|
|
325
380
|
(async () => {
|
|
381
|
+
const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
|
|
326
382
|
const output = {
|
|
327
383
|
role: "assistant",
|
|
328
384
|
content: [],
|
|
329
385
|
api: model.api,
|
|
330
386
|
provider: model.provider,
|
|
331
387
|
model: model.id,
|
|
388
|
+
...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
|
|
332
389
|
usage: {
|
|
333
390
|
input: 0,
|
|
334
391
|
output: 0,
|
|
@@ -343,38 +400,42 @@ export const stream = (model, context, options) => {
|
|
|
343
400
|
try {
|
|
344
401
|
let client;
|
|
345
402
|
let isOAuth;
|
|
403
|
+
let usageModel = model;
|
|
404
|
+
let inputTransformations;
|
|
346
405
|
if (options?.client) {
|
|
347
406
|
client = options.client;
|
|
348
407
|
isOAuth = false;
|
|
349
408
|
}
|
|
350
409
|
else {
|
|
351
410
|
const apiKey = options?.apiKey;
|
|
352
|
-
|
|
411
|
+
const federation = getAnthropicFederation(model, apiKey, options?.headers, options?.env);
|
|
412
|
+
if (!federation)
|
|
413
|
+
assertRequestAuth(model.provider, apiKey, options?.headers);
|
|
353
414
|
let copilotDynamicHeaders;
|
|
354
415
|
if (model.provider === "github-copilot") {
|
|
355
|
-
const hasImages = hasCopilotVisionInput(
|
|
416
|
+
const hasImages = hasCopilotVisionInput(normalizedContext.messages);
|
|
356
417
|
copilotDynamicHeaders = buildCopilotDynamicHeaders({
|
|
357
|
-
messages:
|
|
418
|
+
messages: normalizedContext.messages,
|
|
358
419
|
hasImages,
|
|
359
420
|
});
|
|
360
421
|
}
|
|
361
422
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
362
423
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
363
|
-
const created = createClient(model, apiKey, options?.
|
|
424
|
+
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
|
|
364
425
|
client = created.client;
|
|
365
426
|
isOAuth = created.isOAuthToken;
|
|
366
427
|
}
|
|
367
|
-
let params = buildParams(model,
|
|
428
|
+
let params = buildParams(model, normalizedContext, isOAuth, options);
|
|
368
429
|
const nextParams = await options?.onPayload?.(params, model);
|
|
369
430
|
if (nextParams !== undefined) {
|
|
370
|
-
params = nextParams;
|
|
431
|
+
params = { ...nextParams, stream: true };
|
|
371
432
|
}
|
|
372
433
|
const requestOptions = {
|
|
373
434
|
...(options?.signal ? { signal: options.signal } : {}),
|
|
374
435
|
...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
|
|
375
436
|
maxRetries: 0,
|
|
376
437
|
};
|
|
377
|
-
const response = await retryProviderRequest(() => client.messages.create(
|
|
438
|
+
const response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
|
|
378
439
|
maxRetries: options?.maxRetries,
|
|
379
440
|
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
380
441
|
signal: options?.signal,
|
|
@@ -383,8 +444,19 @@ export const stream = (model, context, options) => {
|
|
|
383
444
|
stream.push({ type: "start", partial: output });
|
|
384
445
|
const blocks = output.content;
|
|
385
446
|
for await (const event of iterateAnthropicEvents(response, options?.signal)) {
|
|
447
|
+
await options?.onProviderStreamEvent?.(event, model);
|
|
386
448
|
if (event.type === "message_start") {
|
|
387
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;
|
|
388
460
|
// Capture initial token usage from message_start event
|
|
389
461
|
// This ensures we have input token counts even if the stream is aborted early
|
|
390
462
|
output.usage.input = event.message.usage.input_tokens || 0;
|
|
@@ -395,9 +467,15 @@ export const stream = (model, context, options) => {
|
|
|
395
467
|
// Anthropic doesn't provide total_tokens, compute from components
|
|
396
468
|
output.usage.totalTokens =
|
|
397
469
|
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
398
|
-
calculateCost(
|
|
470
|
+
calculateCost(usageModel, output.usage);
|
|
399
471
|
}
|
|
400
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
|
+
}
|
|
401
479
|
if (event.content_block.type === "text") {
|
|
402
480
|
const block = {
|
|
403
481
|
type: "text",
|
|
@@ -433,7 +511,7 @@ export const stream = (model, context, options) => {
|
|
|
433
511
|
type: "toolCall",
|
|
434
512
|
id: event.content_block.id,
|
|
435
513
|
name: isOAuth
|
|
436
|
-
? fromClaudeCodeName(event.content_block.name,
|
|
514
|
+
? fromClaudeCodeName(event.content_block.name, currentTools)
|
|
437
515
|
: event.content_block.name,
|
|
438
516
|
arguments: event.content_block.input ?? {},
|
|
439
517
|
partialJson: "",
|
|
@@ -529,6 +607,9 @@ export const stream = (model, context, options) => {
|
|
|
529
607
|
}
|
|
530
608
|
}
|
|
531
609
|
else if (event.type === "message_delta") {
|
|
610
|
+
const transformations = event.input_transformations;
|
|
611
|
+
if (Array.isArray(transformations))
|
|
612
|
+
inputTransformations = transformations;
|
|
532
613
|
if (event.delta.stop_reason) {
|
|
533
614
|
output.rawStopReason = event.delta.stop_reason;
|
|
534
615
|
const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
|
|
@@ -552,11 +633,13 @@ export const stream = (model, context, options) => {
|
|
|
552
633
|
if (event.usage.cache_creation_input_tokens != null) {
|
|
553
634
|
output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
|
|
554
635
|
}
|
|
555
|
-
//
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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;
|
|
560
643
|
if (thinkingTokens != null) {
|
|
561
644
|
output.usage.reasoning = thinkingTokens;
|
|
562
645
|
}
|
|
@@ -564,7 +647,7 @@ export const stream = (model, context, options) => {
|
|
|
564
647
|
// Anthropic doesn't provide total_tokens, compute from components
|
|
565
648
|
output.usage.totalTokens =
|
|
566
649
|
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
567
|
-
calculateCost(
|
|
650
|
+
calculateCost(usageModel, output.usage);
|
|
568
651
|
}
|
|
569
652
|
}
|
|
570
653
|
if (options?.signal?.aborted) {
|
|
@@ -576,6 +659,19 @@ export const stream = (model, context, options) => {
|
|
|
576
659
|
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
577
660
|
throw new Error(output.errorMessage || "An unknown error occurred");
|
|
578
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
|
+
}
|
|
579
675
|
stream.push({ type: "done", reason: output.stopReason, message: output });
|
|
580
676
|
stream.end();
|
|
581
677
|
}
|
|
@@ -615,13 +711,18 @@ function mapThinkingLevelToEffort(model, level) {
|
|
|
615
711
|
}
|
|
616
712
|
}
|
|
617
713
|
export const streamSimple = (model, context, options) => {
|
|
618
|
-
|
|
714
|
+
if (!getAnthropicFederation(model, options?.apiKey, options?.headers, options?.env)) {
|
|
715
|
+
assertRequestAuth(model.provider, options?.apiKey, options?.headers);
|
|
716
|
+
}
|
|
619
717
|
const base = {
|
|
620
718
|
...buildBaseOptions(model, context, options, options?.apiKey),
|
|
621
719
|
toolChoice: options?.toolChoice,
|
|
622
720
|
};
|
|
623
721
|
if (!options?.reasoning) {
|
|
624
|
-
return stream(model, context, {
|
|
722
|
+
return stream(model, context, {
|
|
723
|
+
...base,
|
|
724
|
+
thinkingEnabled: false,
|
|
725
|
+
});
|
|
625
726
|
}
|
|
626
727
|
// For models with adaptive thinking: use an effort level.
|
|
627
728
|
// For older models: use budget-based thinking.
|
|
@@ -647,19 +748,10 @@ export const streamSimple = (model, context, options) => {
|
|
|
647
748
|
function isOAuthToken(apiKey) {
|
|
648
749
|
return apiKey.includes("sk-ant-oat");
|
|
649
750
|
}
|
|
650
|
-
function createClient(model, apiKey,
|
|
651
|
-
//
|
|
652
|
-
const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
|
|
653
|
-
const betaFeatures = [];
|
|
654
|
-
if (useFineGrainedToolStreamingBeta) {
|
|
655
|
-
betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA);
|
|
656
|
-
}
|
|
657
|
-
if (needsInterleavedBeta) {
|
|
658
|
-
betaFeatures.push(INTERLEAVED_THINKING_BETA);
|
|
659
|
-
}
|
|
660
|
-
// Copilot: Bearer auth, selective betas.
|
|
751
|
+
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
|
|
752
|
+
// Copilot: Bearer auth.
|
|
661
753
|
if (model.provider === "github-copilot") {
|
|
662
|
-
const client = new
|
|
754
|
+
const client = new PiAnthropic({
|
|
663
755
|
apiKey: null,
|
|
664
756
|
authToken: apiKey ?? null,
|
|
665
757
|
baseURL: model.baseUrl,
|
|
@@ -668,14 +760,13 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
668
760
|
defaultHeaders: mergeClientHeaders({
|
|
669
761
|
accept: "application/json",
|
|
670
762
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
671
|
-
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
672
763
|
}, model.headers, dynamicHeaders, optionsHeaders),
|
|
673
764
|
});
|
|
674
765
|
return { client, isOAuthToken: false };
|
|
675
766
|
}
|
|
676
767
|
// OAuth: Bearer auth, Claude Code identity headers
|
|
677
768
|
if (apiKey && isOAuthToken(apiKey)) {
|
|
678
|
-
const client = new
|
|
769
|
+
const client = new PiAnthropic({
|
|
679
770
|
apiKey: null,
|
|
680
771
|
authToken: apiKey,
|
|
681
772
|
baseURL: model.baseUrl,
|
|
@@ -684,21 +775,39 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
684
775
|
defaultHeaders: mergeClientHeaders({
|
|
685
776
|
accept: "application/json",
|
|
686
777
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
687
|
-
"anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
|
|
688
778
|
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
|
689
779
|
"x-app": "cli",
|
|
690
780
|
}, model.headers, optionsHeaders),
|
|
691
781
|
});
|
|
692
782
|
return { client, isOAuthToken: true };
|
|
693
783
|
}
|
|
694
|
-
// API key
|
|
695
|
-
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
|
+
}
|
|
696
791
|
const defaultHeaders = mergeClientHeaders({
|
|
697
792
|
accept: "application/json",
|
|
698
793
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
699
|
-
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
700
794
|
}, sessionAffinityHeaders, model.headers, optionsHeaders);
|
|
701
|
-
|
|
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({
|
|
702
811
|
apiKey: apiKey ?? null,
|
|
703
812
|
authToken: null,
|
|
704
813
|
baseURL: model.baseUrl,
|
|
@@ -708,24 +817,70 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
708
817
|
});
|
|
709
818
|
return { client, isOAuthToken: false };
|
|
710
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
|
+
}
|
|
711
858
|
function buildParams(model, context, isOAuthToken, options) {
|
|
712
859
|
const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
|
|
713
860
|
const compat = getAnthropicCompat(model);
|
|
861
|
+
const initialSystemMessage = getInitialSystemMessage(context.messages);
|
|
862
|
+
const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
|
|
714
863
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
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);
|
|
724
876
|
const params = {
|
|
725
877
|
model: model.id,
|
|
726
|
-
messages:
|
|
878
|
+
messages: model.compat?.supportsMidConvoEffort === true
|
|
879
|
+
? insertThinkingLevelMessages(converted, activeEffort)
|
|
880
|
+
: converted.messages,
|
|
727
881
|
max_tokens: options?.maxTokens ?? model.maxTokens,
|
|
728
882
|
stream: true,
|
|
883
|
+
...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
|
|
729
884
|
};
|
|
730
885
|
// For OAuth tokens, we MUST include Claude Code identity
|
|
731
886
|
if (isOAuthToken) {
|
|
@@ -736,36 +891,62 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
736
891
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
737
892
|
},
|
|
738
893
|
];
|
|
739
|
-
if (
|
|
894
|
+
if (initialSystemText) {
|
|
740
895
|
params.system.push({
|
|
741
896
|
type: "text",
|
|
742
|
-
text: sanitizeSurrogates(
|
|
897
|
+
text: sanitizeSurrogates(initialSystemText),
|
|
743
898
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
744
899
|
});
|
|
745
900
|
}
|
|
746
901
|
}
|
|
747
|
-
else if (
|
|
902
|
+
else if (initialSystemText) {
|
|
748
903
|
// Add cache control to system prompt for non-OAuth tokens
|
|
749
904
|
params.system = [
|
|
750
905
|
{
|
|
751
906
|
type: "text",
|
|
752
|
-
text: sanitizeSurrogates(
|
|
907
|
+
text: sanitizeSurrogates(initialSystemText),
|
|
753
908
|
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
754
909
|
},
|
|
755
910
|
];
|
|
756
911
|
}
|
|
757
912
|
// Temperature is incompatible with extended thinking and unsupported on Claude Opus 4.7+.
|
|
758
|
-
if (options?.temperature !== undefined &&
|
|
913
|
+
if (options?.temperature !== undefined &&
|
|
914
|
+
!options?.thinkingEnabled &&
|
|
915
|
+
model.compat?.supportsMidConvoEffort !== true &&
|
|
916
|
+
compat.supportsTemperature) {
|
|
759
917
|
params.temperature = options.temperature;
|
|
760
918
|
}
|
|
761
|
-
|
|
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));
|
|
762
927
|
params.tools = [
|
|
763
|
-
...convertTools(
|
|
764
|
-
|
|
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 })),
|
|
765
931
|
];
|
|
766
932
|
}
|
|
767
|
-
|
|
768
|
-
|
|
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) {
|
|
769
950
|
if (options?.thinkingEnabled) {
|
|
770
951
|
// Default to "summarized" so Opus 4.7 and Mythos Preview behave like
|
|
771
952
|
// older Claude 4 models (whose API default is also "summarized").
|
|
@@ -774,11 +955,7 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
774
955
|
// Adaptive thinking: Claude decides when and how much to think.
|
|
775
956
|
params.thinking = { type: "adaptive", display };
|
|
776
957
|
if (options.effort) {
|
|
777
|
-
|
|
778
|
-
params.output_config =
|
|
779
|
-
options.effort === "xhigh"
|
|
780
|
-
? { effort: options.effort }
|
|
781
|
-
: { effort: options.effort };
|
|
958
|
+
params.output_config = { effort: options.effort };
|
|
782
959
|
}
|
|
783
960
|
}
|
|
784
961
|
else {
|
|
@@ -808,46 +985,64 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
808
985
|
params.tool_choice = options.toolChoice;
|
|
809
986
|
}
|
|
810
987
|
}
|
|
988
|
+
const allowedFallbackModels = model.compat?.allowedFallbackModels;
|
|
989
|
+
if (allowedFallbackModels && allowedFallbackModels.length > 0) {
|
|
990
|
+
params.fallbacks = allowedFallbackModels.map((fallback) => ({ model: fallback.model }));
|
|
991
|
+
}
|
|
811
992
|
return params;
|
|
812
993
|
}
|
|
813
994
|
// Normalize tool call IDs to match Anthropic's required pattern and length
|
|
814
995
|
function normalizeToolCallId(id) {
|
|
815
996
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
816
997
|
}
|
|
817
|
-
function convertToolResult(msg
|
|
818
|
-
const references = [];
|
|
819
|
-
for (const name of msg.addedToolNames ?? []) {
|
|
820
|
-
const normalizedName = normalizeToolName(name);
|
|
821
|
-
if (!deferredToolNames.has(normalizedName) || loadedToolNames.has(normalizedName))
|
|
822
|
-
continue;
|
|
823
|
-
loadedToolNames.add(normalizedName);
|
|
824
|
-
references.push({
|
|
825
|
-
type: "tool_reference",
|
|
826
|
-
tool_name: isOAuthToken ? toClaudeCodeName(name) : name,
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
const convertedContent = convertContentBlocks(msg.content);
|
|
830
|
-
// Anthropic rejects tool references mixed with ordinary tool-result content.
|
|
998
|
+
function convertToolResult(msg) {
|
|
831
999
|
return {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
is_error: msg.isError,
|
|
837
|
-
},
|
|
838
|
-
siblingContent: references.length === 0
|
|
839
|
-
? []
|
|
840
|
-
: typeof convertedContent === "string"
|
|
841
|
-
? [{ type: "text", text: convertedContent }]
|
|
842
|
-
: convertedContent,
|
|
1000
|
+
type: "tool_result",
|
|
1001
|
+
tool_use_id: msg.toolCallId,
|
|
1002
|
+
content: convertContentBlocks(msg.content),
|
|
1003
|
+
is_error: msg.isError,
|
|
843
1004
|
};
|
|
844
1005
|
}
|
|
845
|
-
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false,
|
|
1006
|
+
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, nativeToolChanges = false) {
|
|
846
1007
|
const params = [];
|
|
847
|
-
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
|
+
};
|
|
848
1019
|
for (let i = 0; i < transformedMessages.length; i++) {
|
|
849
1020
|
const msg = transformedMessages[i];
|
|
850
|
-
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") {
|
|
851
1046
|
if (typeof msg.content === "string") {
|
|
852
1047
|
if (msg.content.trim().length > 0) {
|
|
853
1048
|
params.push({
|
|
@@ -890,6 +1085,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
890
1085
|
}
|
|
891
1086
|
}
|
|
892
1087
|
else if (msg.role === "assistant") {
|
|
1088
|
+
flushPendingSystemMessages();
|
|
893
1089
|
const blocks = [];
|
|
894
1090
|
for (const block of msg.content) {
|
|
895
1091
|
if (block.type === "text") {
|
|
@@ -947,39 +1143,47 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
947
1143
|
}
|
|
948
1144
|
if (blocks.length === 0)
|
|
949
1145
|
continue;
|
|
1146
|
+
const messageIndex = params.length;
|
|
950
1147
|
params.push({
|
|
951
1148
|
role: "assistant",
|
|
952
1149
|
content: blocks,
|
|
953
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
|
+
}
|
|
954
1157
|
}
|
|
955
1158
|
else if (msg.role === "toolResult") {
|
|
956
1159
|
// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
|
|
957
1160
|
const toolResults = [];
|
|
958
|
-
const siblingContent = [];
|
|
959
1161
|
let j = i;
|
|
960
1162
|
while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
|
|
961
|
-
|
|
962
|
-
toolResults.push(converted.toolResult);
|
|
963
|
-
siblingContent.push(...converted.siblingContent);
|
|
1163
|
+
toolResults.push(convertToolResult(transformedMessages[j]));
|
|
964
1164
|
j++;
|
|
965
1165
|
}
|
|
966
1166
|
// Skip the messages we've already processed.
|
|
967
1167
|
i = j - 1;
|
|
968
|
-
// Displaced reference-bearing results must follow every tool_result block.
|
|
969
1168
|
params.push({
|
|
970
1169
|
role: "user",
|
|
971
|
-
content:
|
|
1170
|
+
content: toolResults,
|
|
972
1171
|
});
|
|
973
1172
|
}
|
|
974
1173
|
}
|
|
975
|
-
|
|
1174
|
+
flushPendingSystemMessages();
|
|
1175
|
+
// Add cache_control to the last user or system message to cache conversation history
|
|
976
1176
|
if (cacheControl && params.length > 0) {
|
|
977
1177
|
const lastMessage = params[params.length - 1];
|
|
978
|
-
if (lastMessage.role === "user") {
|
|
1178
|
+
if (lastMessage.role === "user" || lastMessage.role === "system") {
|
|
979
1179
|
if (Array.isArray(lastMessage.content)) {
|
|
980
1180
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
981
1181
|
if (lastBlock &&
|
|
982
|
-
(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")) {
|
|
983
1187
|
lastBlock.cache_control = cacheControl;
|
|
984
1188
|
}
|
|
985
1189
|
}
|
|
@@ -994,17 +1198,69 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
994
1198
|
}
|
|
995
1199
|
}
|
|
996
1200
|
}
|
|
997
|
-
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;
|
|
998
1217
|
}
|
|
999
1218
|
function shouldUseFineGrainedToolStreamingBeta(model, context) {
|
|
1000
|
-
return
|
|
1219
|
+
return getCurrentTools(context.messages).length > 0 && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
|
|
1001
1220
|
}
|
|
1002
|
-
|
|
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) {
|
|
1003
1258
|
if (!tools)
|
|
1004
1259
|
return [];
|
|
1005
1260
|
return tools.map((tool, index) => {
|
|
1006
|
-
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
|
|
1007
|
-
const
|
|
1261
|
+
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
|
|
1262
|
+
const parameters = getJsonSchemaToolParameters(tool, strict);
|
|
1263
|
+
const schema = parameters;
|
|
1008
1264
|
const legacyInputSchema = {
|
|
1009
1265
|
type: "object",
|
|
1010
1266
|
properties: schema.properties ?? {},
|
|
@@ -1012,7 +1268,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1012
1268
|
};
|
|
1013
1269
|
const inputSchema = strict === true
|
|
1014
1270
|
? {
|
|
1015
|
-
...
|
|
1271
|
+
...parameters,
|
|
1016
1272
|
...legacyInputSchema,
|
|
1017
1273
|
}
|
|
1018
1274
|
: legacyInputSchema;
|
|
@@ -1022,7 +1278,6 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1022
1278
|
...(supportsEagerToolInputStreaming ? { eager_input_streaming: true } : {}),
|
|
1023
1279
|
...(strict === true ? { strict: true } : {}),
|
|
1024
1280
|
input_schema: inputSchema,
|
|
1025
|
-
...(deferLoading ? { defer_loading: true } : {}),
|
|
1026
1281
|
...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),
|
|
1027
1282
|
};
|
|
1028
1283
|
});
|