@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
package/dist/models.js
CHANGED
|
@@ -3,7 +3,20 @@ import { defaultProviderAuthContext as defaultAuthContext } from "./auth/context
|
|
|
3
3
|
import { InMemoryCredentialStore } from "./auth/credential-store.js";
|
|
4
4
|
import { ModelsError, resolveProviderAuth } from "./auth/resolve.js";
|
|
5
5
|
import { InMemoryModelsStore } from "./models-store.js";
|
|
6
|
+
import { operationSignal, raceWithAbortSignal } from "./utils/abort.js";
|
|
7
|
+
import { assertChatModel, assertClassifierModel, assertImageModel, classifierErrorResult, getModelType, imageErrorResult, isModelType, } from "./utils/model-operations.js";
|
|
8
|
+
import { normalizeContext } from "./utils/transcript.js";
|
|
6
9
|
export { ModelsError } from "./auth/resolve.js";
|
|
10
|
+
export { getModelType, isModelType } from "./utils/model-operations.js";
|
|
11
|
+
const KNOWN_MODEL_TYPES = { chat: true, image: true, classifier: true };
|
|
12
|
+
/** Models from stores and remote sources may have types that only newer versions know. */
|
|
13
|
+
function hasKnownModelType(model) {
|
|
14
|
+
return Object.hasOwn(KNOWN_MODEL_TYPES, getModelType(model));
|
|
15
|
+
}
|
|
16
|
+
/** Drops stored models whose type this version does not know. */
|
|
17
|
+
function withKnownModelTypes(entry) {
|
|
18
|
+
return { ...entry, models: entry.models.filter(hasKnownModelType) };
|
|
19
|
+
}
|
|
7
20
|
function mergeHeaders(base, override) {
|
|
8
21
|
if (!base && !override)
|
|
9
22
|
return undefined;
|
|
@@ -19,19 +32,30 @@ function mergeHeaders(base, override) {
|
|
|
19
32
|
return merged;
|
|
20
33
|
}
|
|
21
34
|
class ModelsImpl {
|
|
35
|
+
providers = new Map();
|
|
36
|
+
credentials;
|
|
37
|
+
modelsStore;
|
|
38
|
+
authContext;
|
|
39
|
+
refreshGenerations = new Map();
|
|
40
|
+
refreshControllers = new Map();
|
|
41
|
+
publicationChains = new Map();
|
|
22
42
|
constructor(options) {
|
|
23
|
-
this.providers = new Map();
|
|
24
43
|
this.credentials = options?.credentials ?? new InMemoryCredentialStore();
|
|
25
44
|
this.modelsStore = options?.modelsStore ?? new InMemoryModelsStore();
|
|
26
45
|
this.authContext = options?.authContext ?? defaultAuthContext();
|
|
27
46
|
}
|
|
28
47
|
setProvider(provider) {
|
|
48
|
+
this.supersedeProviderRefresh(provider.id);
|
|
29
49
|
this.providers.set(provider.id, provider);
|
|
30
50
|
}
|
|
31
51
|
deleteProvider(id) {
|
|
52
|
+
this.supersedeProviderRefresh(id);
|
|
32
53
|
this.providers.delete(id);
|
|
33
54
|
}
|
|
34
55
|
clearProviders() {
|
|
56
|
+
for (const id of new Set([...this.providers.keys(), ...this.refreshControllers.keys()])) {
|
|
57
|
+
this.supersedeProviderRefresh(id);
|
|
58
|
+
}
|
|
35
59
|
this.providers.clear();
|
|
36
60
|
}
|
|
37
61
|
getProviders() {
|
|
@@ -63,90 +87,180 @@ class ModelsImpl {
|
|
|
63
87
|
}
|
|
64
88
|
return models;
|
|
65
89
|
}
|
|
90
|
+
getAllModels(provider) {
|
|
91
|
+
if (provider !== undefined) {
|
|
92
|
+
const entry = this.providers.get(provider);
|
|
93
|
+
if (!entry)
|
|
94
|
+
return [];
|
|
95
|
+
try {
|
|
96
|
+
return entry.getAllModels?.() ?? entry.getModels();
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const models = [];
|
|
103
|
+
for (const entry of this.providers.values()) {
|
|
104
|
+
try {
|
|
105
|
+
models.push(...(entry.getAllModels?.() ?? entry.getModels()));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Best-effort: ill-behaved providers yield no models.
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return models;
|
|
112
|
+
}
|
|
113
|
+
getModelsOfType(type, provider) {
|
|
114
|
+
return this.getAllModels(provider).filter((model) => isModelType(model, type));
|
|
115
|
+
}
|
|
66
116
|
getModel(provider, id) {
|
|
67
117
|
return this.getModels(provider).find((model) => model.id === id);
|
|
68
118
|
}
|
|
119
|
+
getModelOfType(type, provider, id) {
|
|
120
|
+
return this.getModelsOfType(type, provider).find((model) => model.id === id);
|
|
121
|
+
}
|
|
122
|
+
supersedeProviderRefresh(providerId) {
|
|
123
|
+
const generation = (this.refreshGenerations.get(providerId) ?? 0) + 1;
|
|
124
|
+
this.refreshGenerations.set(providerId, generation);
|
|
125
|
+
const previous = this.refreshControllers.get(providerId);
|
|
126
|
+
if (previous) {
|
|
127
|
+
this.refreshControllers.delete(providerId);
|
|
128
|
+
previous.abort();
|
|
129
|
+
}
|
|
130
|
+
return generation;
|
|
131
|
+
}
|
|
132
|
+
beginProviderRefresh(providerId) {
|
|
133
|
+
const generation = this.supersedeProviderRefresh(providerId);
|
|
134
|
+
const controller = new AbortController();
|
|
135
|
+
this.refreshControllers.set(providerId, controller);
|
|
136
|
+
return { generation, controller };
|
|
137
|
+
}
|
|
138
|
+
publishProviderModels(providerId, generation, signal, publication) {
|
|
139
|
+
const previous = this.publicationChains.get(providerId) ?? Promise.resolve();
|
|
140
|
+
const queued = (async () => {
|
|
141
|
+
await previous.catch(() => { });
|
|
142
|
+
if (signal.aborted || this.refreshGenerations.get(providerId) !== generation)
|
|
143
|
+
return false;
|
|
144
|
+
if (publication.persist === null) {
|
|
145
|
+
await this.modelsStore.delete(providerId, { signal });
|
|
146
|
+
}
|
|
147
|
+
else if (publication.persist !== undefined) {
|
|
148
|
+
await this.modelsStore.write(providerId, structuredClone(publication.persist), { signal });
|
|
149
|
+
}
|
|
150
|
+
if (signal.aborted || this.refreshGenerations.get(providerId) !== generation)
|
|
151
|
+
return false;
|
|
152
|
+
publication.update?.();
|
|
153
|
+
return true;
|
|
154
|
+
})();
|
|
155
|
+
const tail = queued.catch(() => { });
|
|
156
|
+
this.publicationChains.set(providerId, tail);
|
|
157
|
+
void tail.then(() => {
|
|
158
|
+
if (this.publicationChains.get(providerId) === tail)
|
|
159
|
+
this.publicationChains.delete(providerId);
|
|
160
|
+
});
|
|
161
|
+
return raceWithAbortSignal(queued, signal);
|
|
162
|
+
}
|
|
163
|
+
async runProviderRefreshPhase(provider, credential, allowNetwork, force, generation, signal) {
|
|
164
|
+
const stored = await this.modelsStore.read(provider.id, { signal });
|
|
165
|
+
await provider.refreshModels({
|
|
166
|
+
credential,
|
|
167
|
+
stored: stored ? withKnownModelTypes(structuredClone(stored)) : undefined,
|
|
168
|
+
publish: (publication) => this.publishProviderModels(provider.id, generation, signal, publication),
|
|
169
|
+
allowNetwork,
|
|
170
|
+
force: allowNetwork ? force : undefined,
|
|
171
|
+
signal,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
69
174
|
async refresh(options = {}) {
|
|
70
175
|
const allowNetwork = options.allowNetwork ?? true;
|
|
176
|
+
const callerSignal = operationSignal(options.signal);
|
|
71
177
|
const errors = new Map();
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
178
|
+
if (callerSignal.aborted)
|
|
179
|
+
return { aborted: true, errors };
|
|
180
|
+
const selected = options.providers ? new Set(options.providers) : undefined;
|
|
181
|
+
const refreshable = Array.from(this.providers.values()).filter((provider) => provider.refreshModels !== undefined && (!selected || selected.has(provider.id)));
|
|
182
|
+
const refresh = Promise.all(refreshable.map(async (provider) => {
|
|
183
|
+
const { generation, controller } = this.beginProviderRefresh(provider.id);
|
|
184
|
+
const signal = AbortSignal.any([callerSignal, controller.signal]);
|
|
185
|
+
const operation = (async () => {
|
|
186
|
+
let storedCredential;
|
|
187
|
+
let credentialError;
|
|
188
|
+
try {
|
|
189
|
+
storedCredential = await this.readCredential(provider.id, signal);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
credentialError = error;
|
|
193
|
+
}
|
|
194
|
+
// Restore cached provider state before auth resolution or network access.
|
|
195
|
+
await this.runProviderRefreshPhase(provider, storedCredential, false, undefined, generation, signal);
|
|
196
|
+
if (credentialError !== undefined)
|
|
197
|
+
throw credentialError;
|
|
198
|
+
if (!allowNetwork || signal.aborted)
|
|
199
|
+
return;
|
|
200
|
+
const credential = await this.resolveRefreshCredential(provider, storedCredential, signal);
|
|
85
201
|
if (!credential)
|
|
86
202
|
return;
|
|
87
|
-
await provider.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
force: options.force,
|
|
92
|
-
signal: options.signal,
|
|
93
|
-
});
|
|
203
|
+
await this.runProviderRefreshPhase(provider, credential, true, options.force, generation, signal);
|
|
204
|
+
})();
|
|
205
|
+
try {
|
|
206
|
+
await raceWithAbortSignal(operation, signal);
|
|
94
207
|
}
|
|
95
208
|
catch (error) {
|
|
96
|
-
if (!
|
|
209
|
+
if (!signal.aborted) {
|
|
97
210
|
errors.set(provider.id, error instanceof Error
|
|
98
211
|
? error
|
|
99
212
|
: new ModelsError("model_source", `Model refresh failed for ${provider.id}`, { cause: error }));
|
|
100
213
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
allowNetwork: false,
|
|
106
|
-
signal: options.signal,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
// Preserve the original auth/network error; cache restoration is best-effort here.
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
if (this.refreshControllers.get(provider.id) === controller) {
|
|
217
|
+
this.refreshControllers.delete(provider.id);
|
|
111
218
|
}
|
|
112
219
|
}
|
|
113
220
|
}));
|
|
114
|
-
|
|
221
|
+
try {
|
|
222
|
+
await raceWithAbortSignal(refresh, callerSignal);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
if (!callerSignal.aborted)
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
return { aborted: callerSignal.aborted, errors: new Map(errors) };
|
|
115
229
|
}
|
|
116
|
-
async resolveRefreshCredential(provider, stored,
|
|
230
|
+
async resolveRefreshCredential(provider, stored, signal) {
|
|
117
231
|
if (stored?.type === "oauth") {
|
|
118
232
|
const oauth = provider.auth.oauth;
|
|
119
233
|
if (!oauth)
|
|
120
234
|
return undefined;
|
|
121
|
-
if (
|
|
235
|
+
if (Date.now() < stored.expires)
|
|
122
236
|
return stored;
|
|
123
|
-
if (signal
|
|
237
|
+
if (signal.aborted)
|
|
124
238
|
return undefined;
|
|
125
239
|
const post = await this.credentials.modify(provider.id, async (current) => {
|
|
126
240
|
if (current?.type !== "oauth" || Date.now() < current.expires)
|
|
127
241
|
return undefined;
|
|
128
242
|
return oauth.refresh(current, signal);
|
|
129
|
-
});
|
|
243
|
+
}, { signal });
|
|
130
244
|
return post?.type === "oauth" ? post : undefined;
|
|
131
245
|
}
|
|
132
246
|
const apiKey = provider.auth.apiKey;
|
|
133
247
|
if (!apiKey)
|
|
134
248
|
return undefined;
|
|
135
249
|
const credential = stored?.type === "api_key" ? stored : undefined;
|
|
136
|
-
const result = await apiKey.resolve({ ctx: this.authContext, credential });
|
|
250
|
+
const result = await apiKey.resolve({ ctx: this.authContext, credential, signal });
|
|
137
251
|
if (!result)
|
|
138
252
|
return undefined;
|
|
139
253
|
return { type: "api_key", key: result.auth.apiKey, env: result.env };
|
|
140
254
|
}
|
|
141
|
-
async readCredential(providerId) {
|
|
255
|
+
async readCredential(providerId, signal) {
|
|
142
256
|
try {
|
|
143
|
-
return await this.credentials.read(providerId);
|
|
257
|
+
return await this.credentials.read(providerId, { signal });
|
|
144
258
|
}
|
|
145
259
|
catch (error) {
|
|
146
260
|
throw new ModelsError("auth", `Credential store read failed for ${providerId}`, { cause: error });
|
|
147
261
|
}
|
|
148
262
|
}
|
|
149
|
-
async checkProviderAuth(provider, credential) {
|
|
263
|
+
async checkProviderAuth(provider, credential, signal) {
|
|
150
264
|
if (credential?.type === "oauth") {
|
|
151
265
|
return provider.auth.oauth ? { source: "OAuth", type: "oauth" } : undefined;
|
|
152
266
|
}
|
|
@@ -158,42 +272,75 @@ class ModelsImpl {
|
|
|
158
272
|
return await apiKey.check({
|
|
159
273
|
ctx: this.authContext,
|
|
160
274
|
credential: credential?.type === "api_key" ? credential : undefined,
|
|
275
|
+
signal,
|
|
161
276
|
});
|
|
162
277
|
}
|
|
163
278
|
catch (error) {
|
|
164
279
|
throw new ModelsError("auth", `API key auth check failed for provider ${provider.id}`, { cause: error });
|
|
165
280
|
}
|
|
166
281
|
}
|
|
167
|
-
const resolution = await resolveProviderAuth(provider, this.credentials, this.authContext);
|
|
282
|
+
const resolution = await resolveProviderAuth(provider, this.credentials, this.authContext, { signal });
|
|
168
283
|
return resolution ? { source: resolution.source, type: "api_key" } : undefined;
|
|
169
284
|
}
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
285
|
+
checkAuth(providerId, options) {
|
|
286
|
+
const signal = operationSignal(options?.signal);
|
|
287
|
+
const check = (async () => {
|
|
288
|
+
signal.throwIfAborted();
|
|
289
|
+
const provider = this.providers.get(providerId);
|
|
290
|
+
if (!provider)
|
|
291
|
+
return undefined;
|
|
292
|
+
return this.checkProviderAuth(provider, await this.readCredential(providerId, signal), signal);
|
|
293
|
+
})();
|
|
294
|
+
return raceWithAbortSignal(check, signal);
|
|
175
295
|
}
|
|
176
|
-
async
|
|
296
|
+
async getAuthenticatedProviders(providerId, signal) {
|
|
297
|
+
signal.throwIfAborted();
|
|
177
298
|
const providers = providerId
|
|
178
299
|
? [this.providers.get(providerId)].filter((entry) => entry !== undefined)
|
|
179
300
|
: this.getProviders();
|
|
180
301
|
const checks = await Promise.all(providers.map(async (provider) => {
|
|
181
|
-
const credential = await this.readCredential(provider.id);
|
|
182
|
-
return { provider, credential, auth: await this.checkProviderAuth(provider, credential) };
|
|
302
|
+
const credential = await this.readCredential(provider.id, signal);
|
|
303
|
+
return { provider, credential, auth: await this.checkProviderAuth(provider, credential, signal) };
|
|
183
304
|
}));
|
|
184
|
-
return checks.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
305
|
+
return checks.filter((entry) => entry.auth !== undefined);
|
|
306
|
+
}
|
|
307
|
+
getAvailable(providerId, options) {
|
|
308
|
+
const signal = operationSignal(options?.signal);
|
|
309
|
+
const available = (async () => {
|
|
310
|
+
const providers = await this.getAuthenticatedProviders(providerId, signal);
|
|
311
|
+
return providers.flatMap(({ provider, credential }) => {
|
|
312
|
+
const models = provider.getModels();
|
|
313
|
+
return provider.filterModels?.(models, credential) ?? models;
|
|
314
|
+
});
|
|
315
|
+
})();
|
|
316
|
+
return raceWithAbortSignal(available, signal);
|
|
317
|
+
}
|
|
318
|
+
async getAvailableOfType(type, providerId, options) {
|
|
319
|
+
return (await this.getAllAvailable(providerId, options)).filter((model) => isModelType(model, type));
|
|
320
|
+
}
|
|
321
|
+
getAllAvailable(providerId, options) {
|
|
322
|
+
const signal = operationSignal(options?.signal);
|
|
323
|
+
const available = (async () => {
|
|
324
|
+
const providers = await this.getAuthenticatedProviders(providerId, signal);
|
|
325
|
+
return providers.flatMap(({ provider, credential }) => {
|
|
326
|
+
const models = provider.getAllModels?.() ?? provider.getModels();
|
|
327
|
+
if (provider.filterAllModels)
|
|
328
|
+
return provider.filterAllModels(models, credential);
|
|
329
|
+
if (!provider.filterModels)
|
|
330
|
+
return models;
|
|
331
|
+
const availableChatIds = new Set(provider.filterModels(provider.getModels(), credential).map((model) => model.id));
|
|
332
|
+
return models.filter((model) => !isModelType(model, "chat") || availableChatIds.has(model.id));
|
|
333
|
+
});
|
|
334
|
+
})();
|
|
335
|
+
return raceWithAbortSignal(available, signal);
|
|
190
336
|
}
|
|
191
337
|
async getAuth(providerOrModel, overrides) {
|
|
338
|
+
const signal = operationSignal(overrides?.signal);
|
|
192
339
|
const providerId = typeof providerOrModel === "string" ? providerOrModel : providerOrModel.provider;
|
|
193
340
|
const provider = this.providers.get(providerId);
|
|
194
341
|
if (!provider)
|
|
195
342
|
return undefined;
|
|
196
|
-
const result = await resolveProviderAuth(provider, this.credentials, this.authContext, overrides);
|
|
343
|
+
const result = await resolveProviderAuth(provider, this.credentials, this.authContext, { ...overrides, signal });
|
|
197
344
|
if (!result || typeof providerOrModel === "string" || !providerOrModel.headers)
|
|
198
345
|
return result;
|
|
199
346
|
return {
|
|
@@ -204,7 +351,9 @@ class ModelsImpl {
|
|
|
204
351
|
},
|
|
205
352
|
};
|
|
206
353
|
}
|
|
207
|
-
async login(providerId, type, interaction) {
|
|
354
|
+
async login(providerId, type, interaction, options) {
|
|
355
|
+
const signal = operationSignal(interaction.signal);
|
|
356
|
+
signal.throwIfAborted();
|
|
208
357
|
const provider = this.providers.get(providerId);
|
|
209
358
|
if (!provider)
|
|
210
359
|
throw new ModelsError("provider", `Unknown provider: ${providerId}`);
|
|
@@ -212,20 +361,52 @@ class ModelsImpl {
|
|
|
212
361
|
if (!method?.login) {
|
|
213
362
|
throw new ModelsError("auth", `${provider.name} does not support ${type} login`);
|
|
214
363
|
}
|
|
215
|
-
const
|
|
364
|
+
const loginOperation = method.login({ ...interaction, signal }, options);
|
|
365
|
+
const credential = await raceWithAbortSignal(loginOperation, signal);
|
|
366
|
+
let mutationStarted = false;
|
|
367
|
+
let markMutationStarted;
|
|
368
|
+
const started = new Promise((resolve) => {
|
|
369
|
+
markMutationStarted = resolve;
|
|
370
|
+
});
|
|
371
|
+
const mutation = this.credentials.modify(providerId, async () => {
|
|
372
|
+
mutationStarted = true;
|
|
373
|
+
markMutationStarted?.();
|
|
374
|
+
return credential;
|
|
375
|
+
}, { signal });
|
|
376
|
+
void mutation.catch(() => { });
|
|
216
377
|
try {
|
|
217
|
-
await
|
|
378
|
+
await new Promise((resolve, reject) => {
|
|
379
|
+
const onAbort = () => {
|
|
380
|
+
if (!mutationStarted)
|
|
381
|
+
reject(signal.reason);
|
|
382
|
+
};
|
|
383
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
384
|
+
void Promise.race([started, mutation]).then(() => {
|
|
385
|
+
signal.removeEventListener("abort", onAbort);
|
|
386
|
+
resolve();
|
|
387
|
+
}, (error) => {
|
|
388
|
+
signal.removeEventListener("abort", onAbort);
|
|
389
|
+
reject(error);
|
|
390
|
+
});
|
|
391
|
+
if (signal.aborted)
|
|
392
|
+
onAbort();
|
|
393
|
+
});
|
|
394
|
+
await mutation;
|
|
218
395
|
}
|
|
219
396
|
catch (error) {
|
|
397
|
+
signal.throwIfAborted();
|
|
220
398
|
throw new ModelsError("auth", `Credential store modify failed for ${providerId}`, { cause: error });
|
|
221
399
|
}
|
|
222
400
|
return credential;
|
|
223
401
|
}
|
|
224
|
-
async logout(providerId) {
|
|
402
|
+
async logout(providerId, options) {
|
|
403
|
+
const signal = operationSignal(options?.signal);
|
|
404
|
+
signal.throwIfAborted();
|
|
225
405
|
try {
|
|
226
|
-
await this.credentials.delete(providerId);
|
|
406
|
+
await this.credentials.delete(providerId, { signal });
|
|
227
407
|
}
|
|
228
408
|
catch (error) {
|
|
409
|
+
signal.throwIfAborted();
|
|
229
410
|
throw new ModelsError("auth", `Credential store delete failed for ${providerId}`, { cause: error });
|
|
230
411
|
}
|
|
231
412
|
}
|
|
@@ -236,11 +417,16 @@ class ModelsImpl {
|
|
|
236
417
|
}
|
|
237
418
|
return provider;
|
|
238
419
|
}
|
|
420
|
+
requireChatProvider(model) {
|
|
421
|
+
assertChatModel(model);
|
|
422
|
+
return this.requireProvider(model);
|
|
423
|
+
}
|
|
239
424
|
async applyAuth(model, options) {
|
|
240
425
|
this.requireProvider(model);
|
|
241
426
|
const resolution = await this.getAuth(model, {
|
|
242
427
|
apiKey: options?.apiKey,
|
|
243
428
|
env: options?.env,
|
|
429
|
+
signal: options?.signal,
|
|
244
430
|
});
|
|
245
431
|
if (!resolution) {
|
|
246
432
|
throw new ModelsError("auth", `Provider is not configured: ${model.provider}`);
|
|
@@ -258,44 +444,108 @@ class ModelsImpl {
|
|
|
258
444
|
return { requestModel, requestOptions };
|
|
259
445
|
}
|
|
260
446
|
stream(model, context, options) {
|
|
447
|
+
const transcript = normalizeContext(context);
|
|
261
448
|
return lazyStream(model, async () => {
|
|
262
|
-
const provider = this.
|
|
449
|
+
const provider = this.requireChatProvider(model);
|
|
263
450
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
264
|
-
return provider.stream(requestModel,
|
|
451
|
+
return provider.stream(requestModel, transcript, requestOptions);
|
|
265
452
|
});
|
|
266
453
|
}
|
|
267
454
|
async complete(model, context, options) {
|
|
268
455
|
return this.stream(model, context, options).result();
|
|
269
456
|
}
|
|
270
457
|
streamSimple(model, context, options) {
|
|
458
|
+
const transcript = normalizeContext(context);
|
|
271
459
|
return lazyStream(model, async () => {
|
|
272
|
-
const provider = this.
|
|
460
|
+
const provider = this.requireChatProvider(model);
|
|
273
461
|
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
274
|
-
return provider.streamSimple(requestModel,
|
|
462
|
+
return provider.streamSimple(requestModel, transcript, requestOptions);
|
|
275
463
|
});
|
|
276
464
|
}
|
|
277
465
|
async completeSimple(model, context, options) {
|
|
278
466
|
return this.streamSimple(model, context, options).result();
|
|
279
467
|
}
|
|
468
|
+
streamDeferred(model, handle, options) {
|
|
469
|
+
return lazyStream(model, async () => {
|
|
470
|
+
const provider = this.requireChatProvider(model);
|
|
471
|
+
if (!provider.fetchDeferred) {
|
|
472
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
|
|
473
|
+
}
|
|
474
|
+
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
475
|
+
return provider.fetchDeferred(requestModel, handle, requestOptions);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
async fetchDeferred(model, handle, options) {
|
|
479
|
+
return this.streamDeferred(model, handle, options).result();
|
|
480
|
+
}
|
|
481
|
+
async cancelDeferred(model, handle, options) {
|
|
482
|
+
const provider = this.requireChatProvider(model);
|
|
483
|
+
if (!provider.cancelDeferred) {
|
|
484
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
|
|
485
|
+
}
|
|
486
|
+
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
487
|
+
await provider.cancelDeferred(requestModel, handle, requestOptions);
|
|
488
|
+
}
|
|
489
|
+
async generateImages(model, context, options) {
|
|
490
|
+
try {
|
|
491
|
+
assertImageModel(model);
|
|
492
|
+
const provider = this.requireProvider(model);
|
|
493
|
+
if (!provider.generateImages) {
|
|
494
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support image generation`);
|
|
495
|
+
}
|
|
496
|
+
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
497
|
+
return await provider.generateImages(requestModel, context, requestOptions);
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
return imageErrorResult(model, error, options?.signal?.aborted);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
async classify(model, context, options) {
|
|
504
|
+
try {
|
|
505
|
+
assertClassifierModel(model);
|
|
506
|
+
const provider = this.requireProvider(model);
|
|
507
|
+
if (!provider.classify) {
|
|
508
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support classification`);
|
|
509
|
+
}
|
|
510
|
+
const { requestModel, requestOptions } = await this.applyAuth(model, options);
|
|
511
|
+
return await provider.classify(requestModel, context, requestOptions);
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
return classifierErrorResult(model, error, options?.signal?.aborted);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
280
517
|
}
|
|
281
518
|
export function createModels(options) {
|
|
282
519
|
return new ModelsImpl(options);
|
|
283
520
|
}
|
|
284
521
|
/**
|
|
285
522
|
* Builds a provider from parts. Built-in provider factories and models.json
|
|
286
|
-
* custom providers both go through this. A single `api` streams all
|
|
287
|
-
* an `api` map dispatches on `model.api`, and a model whose api has
|
|
288
|
-
* produces a stream error.
|
|
523
|
+
* custom providers both go through this. A single `api` streams all chat
|
|
524
|
+
* models; an `api` map dispatches on `model.api`, and a model whose api has
|
|
525
|
+
* no entry produces a stream error. One-shot operation maps dispatch on
|
|
526
|
+
* `model.api` the same way. At least one concrete implementation across
|
|
527
|
+
* `api`/`images`/`classifiers` is required; empty maps are rejected.
|
|
289
528
|
*/
|
|
290
529
|
export function createProvider(input) {
|
|
530
|
+
const single = input.api && typeof input.api.stream === "function"
|
|
531
|
+
? input.api
|
|
532
|
+
: undefined;
|
|
533
|
+
const byApi = single || !input.api ? undefined : input.api;
|
|
534
|
+
const images = input.images;
|
|
535
|
+
const classifiers = input.classifiers;
|
|
536
|
+
const streams = single ? [single] : Object.values(byApi ?? {}).filter((entry) => entry !== undefined);
|
|
537
|
+
const imageImplementations = Object.values(images ?? {}).filter((entry) => entry !== undefined);
|
|
538
|
+
const classifierImplementations = Object.values(classifiers ?? {}).filter((entry) => entry !== undefined);
|
|
539
|
+
if (streams.length === 0 && imageImplementations.length === 0 && classifierImplementations.length === 0) {
|
|
540
|
+
throw new Error(`Provider ${input.id}: at least one of "api", "images", or "classifiers" is required.`);
|
|
541
|
+
}
|
|
291
542
|
const baselineModels = input.models;
|
|
292
543
|
let dynamicModels = [];
|
|
293
|
-
let inflightRefresh;
|
|
294
544
|
const fetchModels = input.fetchModels;
|
|
295
545
|
const currentModels = () => {
|
|
296
546
|
const merged = [...baselineModels];
|
|
297
547
|
for (const model of dynamicModels) {
|
|
298
|
-
const index = merged.findIndex((entry) => entry.id === model.id);
|
|
548
|
+
const index = merged.findIndex((entry) => getModelType(entry) === getModelType(model) && entry.id === model.id);
|
|
299
549
|
if (index >= 0)
|
|
300
550
|
merged[index] = model;
|
|
301
551
|
else
|
|
@@ -303,8 +553,6 @@ export function createProvider(input) {
|
|
|
303
553
|
}
|
|
304
554
|
return merged;
|
|
305
555
|
};
|
|
306
|
-
const single = typeof input.api.stream === "function" ? input.api : undefined;
|
|
307
|
-
const byApi = single ? undefined : input.api;
|
|
308
556
|
const apiFor = (model) => single ?? byApi?.[model.api];
|
|
309
557
|
const dispatch = (model, run) => {
|
|
310
558
|
const streams = apiFor(model);
|
|
@@ -315,42 +563,84 @@ export function createProvider(input) {
|
|
|
315
563
|
}
|
|
316
564
|
return run(streams);
|
|
317
565
|
};
|
|
318
|
-
|
|
566
|
+
const provider = {
|
|
319
567
|
id: input.id,
|
|
320
568
|
name: input.name ?? input.id,
|
|
321
569
|
baseUrl: input.baseUrl,
|
|
322
570
|
headers: input.headers,
|
|
323
571
|
auth: input.auth,
|
|
324
|
-
getModels: currentModels,
|
|
572
|
+
getModels: () => currentModels().filter((model) => isModelType(model, "chat")),
|
|
573
|
+
getAllModels: currentModels,
|
|
325
574
|
refreshModels: fetchModels
|
|
326
|
-
? (context) => {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const refreshed = await fetchModels(context);
|
|
338
|
-
if (context.signal?.aborted)
|
|
339
|
-
return;
|
|
340
|
-
dynamicModels = refreshed;
|
|
341
|
-
await context.store.write({ models: refreshed, checkedAt: Date.now() });
|
|
342
|
-
}
|
|
343
|
-
finally {
|
|
344
|
-
inflightRefresh = undefined;
|
|
575
|
+
? async (context) => {
|
|
576
|
+
if (context.stored) {
|
|
577
|
+
const restored = context.stored.models
|
|
578
|
+
.filter((model) => model.provider === input.id)
|
|
579
|
+
.map((model) => model);
|
|
580
|
+
if (!(await context.publish({
|
|
581
|
+
update: () => {
|
|
582
|
+
dynamicModels = restored;
|
|
583
|
+
},
|
|
584
|
+
}))) {
|
|
585
|
+
return;
|
|
345
586
|
}
|
|
346
|
-
}
|
|
347
|
-
|
|
587
|
+
}
|
|
588
|
+
if (!context.allowNetwork || context.signal.aborted)
|
|
589
|
+
return;
|
|
590
|
+
const fetched = await fetchModels(context);
|
|
591
|
+
if (context.signal.aborted)
|
|
592
|
+
return;
|
|
593
|
+
const refreshed = fetched.filter(hasKnownModelType);
|
|
594
|
+
await context.publish({
|
|
595
|
+
persist: { models: refreshed, checkedAt: Date.now() },
|
|
596
|
+
update: () => {
|
|
597
|
+
dynamicModels = refreshed;
|
|
598
|
+
},
|
|
599
|
+
});
|
|
348
600
|
}
|
|
349
601
|
: undefined,
|
|
350
602
|
filterModels: input.filterModels,
|
|
603
|
+
filterAllModels: input.filterAllModels,
|
|
351
604
|
stream: (model, context, options) => dispatch(model, (streams) => streams.stream(model, context, options)),
|
|
352
605
|
streamSimple: (model, context, options) => dispatch(model, (streams) => streams.streamSimple(model, context, options)),
|
|
353
606
|
};
|
|
607
|
+
if (streams.some((entry) => entry.fetchDeferred !== undefined)) {
|
|
608
|
+
provider.fetchDeferred = (model, handle, options) => lazyStream(model, async () => {
|
|
609
|
+
const implementation = apiFor(model);
|
|
610
|
+
if (!implementation?.fetchDeferred) {
|
|
611
|
+
throw new ModelsError("provider", `Provider ${input.id} does not support deferred responses for "${model.api}"`);
|
|
612
|
+
}
|
|
613
|
+
return implementation.fetchDeferred(model, handle, options);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
if (streams.some((entry) => entry.cancelDeferred !== undefined)) {
|
|
617
|
+
provider.cancelDeferred = async (model, handle, options) => {
|
|
618
|
+
const implementation = apiFor(model);
|
|
619
|
+
if (!implementation?.cancelDeferred) {
|
|
620
|
+
throw new ModelsError("provider", `Provider ${input.id} cannot cancel deferred responses for "${model.api}"`);
|
|
621
|
+
}
|
|
622
|
+
await implementation.cancelDeferred(model, handle, options);
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
if (images && imageImplementations.length > 0) {
|
|
626
|
+
provider.generateImages = async (model, context, options) => {
|
|
627
|
+
const implementation = images[model.api];
|
|
628
|
+
if (!implementation) {
|
|
629
|
+
return imageErrorResult(model, new ModelsError("provider", `Provider ${input.id} has no image generation implementation for "${model.api}"`));
|
|
630
|
+
}
|
|
631
|
+
return implementation.generateImages(model, context, options);
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
if (classifiers && classifierImplementations.length > 0) {
|
|
635
|
+
provider.classify = async (model, context, options) => {
|
|
636
|
+
const implementation = classifiers[model.api];
|
|
637
|
+
if (!implementation) {
|
|
638
|
+
return classifierErrorResult(model, new ModelsError("provider", `Provider ${input.id} has no classifier implementation for "${model.api}"`));
|
|
639
|
+
}
|
|
640
|
+
return implementation.classify(model, context, options);
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
return provider;
|
|
354
644
|
}
|
|
355
645
|
/**
|
|
356
646
|
* Runtime-checked narrowing for dynamically looked-up models:
|
|
@@ -361,9 +651,11 @@ export function createProvider(input) {
|
|
|
361
651
|
* // model: Model<"anthropic-messages">, stream options fully typed
|
|
362
652
|
* }
|
|
363
653
|
* ```
|
|
654
|
+
*
|
|
655
|
+
* Non-chat models never match, even when their api id equals `api`.
|
|
364
656
|
*/
|
|
365
657
|
export function hasApi(model, api) {
|
|
366
|
-
return model.api === api;
|
|
658
|
+
return isModelType(model, "chat") && model.api === api;
|
|
367
659
|
}
|
|
368
660
|
export function calculateCost(model, usage) {
|
|
369
661
|
const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
@@ -447,12 +739,12 @@ export function supportsMax(model) {
|
|
|
447
739
|
model.id.includes("opus-4.7"));
|
|
448
740
|
}
|
|
449
741
|
/**
|
|
450
|
-
* Check if two models are equal by comparing
|
|
742
|
+
* Check if two models are equal by comparing their type, id, and provider.
|
|
451
743
|
* Returns false if either model is null or undefined.
|
|
452
744
|
*/
|
|
453
745
|
export function modelsAreEqual(a, b) {
|
|
454
746
|
if (!a || !b)
|
|
455
747
|
return false;
|
|
456
|
-
return a.id === b.id && a.provider === b.provider;
|
|
748
|
+
return getModelType(a) === getModelType(b) && a.id === b.id && a.provider === b.provider;
|
|
457
749
|
}
|
|
458
750
|
//# sourceMappingURL=models.js.map
|