@prometheus-ai/ai 0.5.3 → 0.5.8
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/types/auth-broker/remote-store.d.ts +2 -1
- package/dist/types/auth-broker/wire-schemas.d.ts +4 -1
- package/dist/types/auth-gateway/server.d.ts +19 -0
- package/dist/types/auth-gateway/types.d.ts +9 -3
- package/dist/types/auth-retry.d.ts +119 -0
- package/dist/types/auth-storage.d.ts +217 -8
- package/dist/types/errors.d.ts +24 -0
- package/dist/types/index.d.ts +5 -9
- package/dist/types/provider-details.d.ts +1 -1
- package/dist/types/providers/amazon-bedrock.d.ts +12 -6
- package/dist/types/providers/anthropic-client.d.ts +10 -3
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +2 -2
- package/dist/types/providers/anthropic-messages-server.d.ts +3 -3
- package/dist/types/providers/anthropic-wire.d.ts +3 -3
- package/dist/types/providers/anthropic.d.ts +41 -34
- package/dist/types/providers/aws-credentials.d.ts +8 -0
- package/dist/types/providers/azure-openai-responses.d.ts +1 -0
- package/dist/types/providers/google-gemini-cli.d.ts +22 -1
- package/dist/types/providers/google-shared.d.ts +22 -0
- package/dist/types/providers/google-types.d.ts +13 -1
- package/dist/types/providers/mock.d.ts +8 -3
- package/dist/types/providers/ollama.d.ts +6 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +6 -3
- package/dist/types/providers/openai-chat-server.d.ts +3 -3
- package/dist/types/providers/openai-chat-wire.d.ts +644 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +8 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +9 -0
- package/dist/types/providers/openai-codex-responses.d.ts +31 -2
- package/dist/types/providers/openai-completions-compat.d.ts +2 -25
- package/dist/types/providers/openai-completions.d.ts +2 -10
- package/dist/types/providers/openai-responses-server-schema.d.ts +4 -4
- package/dist/types/providers/openai-responses-server.d.ts +2 -2
- package/dist/types/providers/openai-responses-shared.d.ts +49 -9
- package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
- package/dist/types/providers/openai-responses.d.ts +13 -4
- package/dist/types/providers/prometheus-native-client.d.ts +9 -0
- package/dist/types/providers/prometheus-native-server.d.ts +4 -3
- package/dist/types/providers/transform-messages.d.ts +1 -2
- package/dist/types/rate-limit-utils.d.ts +3 -2
- package/dist/types/registry/aimlapi.d.ts +4 -0
- package/dist/types/registry/alibaba-coding-plan.d.ts +7 -0
- package/dist/types/registry/amazon-bedrock.d.ts +5 -0
- package/dist/types/registry/anthropic.d.ts +10 -0
- package/dist/types/{utils/oauth → registry}/api-key-login.d.ts +8 -2
- package/dist/types/{utils/oauth → registry}/api-key-validation.d.ts +15 -0
- package/dist/types/registry/cerebras.d.ts +7 -0
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
- package/dist/types/registry/cursor.d.ts +7 -0
- package/dist/types/registry/deepseek.d.ts +8 -0
- package/dist/types/registry/derived.d.ts +5 -0
- package/dist/types/registry/firepass.d.ts +16 -0
- package/dist/types/registry/fireworks.d.ts +7 -0
- package/dist/types/registry/github-copilot.d.ts +7 -0
- package/dist/types/registry/gitlab-duo.d.ts +9 -0
- package/dist/types/registry/google-antigravity.d.ts +9 -0
- package/dist/types/registry/google-gemini-cli.d.ts +9 -0
- package/dist/types/registry/google-vertex.d.ts +5 -0
- package/dist/types/registry/google.d.ts +4 -0
- package/dist/types/registry/groq.d.ts +4 -0
- package/dist/types/registry/huggingface.d.ts +7 -0
- package/dist/types/registry/index.d.ts +4 -0
- package/dist/types/registry/kagi.d.ts +14 -0
- package/dist/types/registry/kilo.d.ts +7 -0
- package/dist/types/registry/kimi-code.d.ts +7 -0
- package/dist/types/registry/litellm.d.ts +13 -0
- package/dist/types/registry/lm-studio.d.ts +8 -0
- package/dist/types/registry/minimax-code-cn.d.ts +6 -0
- package/dist/types/registry/minimax-code.d.ts +6 -0
- package/dist/types/registry/minimax.d.ts +4 -0
- package/dist/types/registry/mistral.d.ts +4 -0
- package/dist/types/registry/moonshot.d.ts +7 -0
- package/dist/types/registry/nanogpt.d.ts +7 -0
- package/dist/types/registry/nvidia.d.ts +7 -0
- package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
- package/dist/types/{utils → registry}/oauth/anthropic.d.ts +2 -1
- package/dist/types/{utils → registry}/oauth/github-copilot.d.ts +15 -23
- package/dist/types/{utils → registry}/oauth/index.d.ts +1 -0
- package/dist/types/{utils → registry}/oauth/minimax-code.d.ts +5 -5
- package/dist/types/{utils → registry}/oauth/types.d.ts +6 -1
- package/dist/types/{utils → registry}/oauth/xai-oauth.d.ts +2 -1
- package/dist/types/registry/ollama-cloud.d.ts +7 -0
- package/dist/types/registry/ollama.d.ts +12 -0
- package/dist/types/registry/openai-codex-device.d.ts +8 -0
- package/dist/types/registry/openai-codex.d.ts +9 -0
- package/dist/types/registry/openai.d.ts +4 -0
- package/dist/types/registry/opencode-go.d.ts +6 -0
- package/dist/types/registry/opencode-zen.d.ts +6 -0
- package/dist/types/registry/openrouter.d.ts +13 -0
- package/dist/types/registry/parallel.d.ts +14 -0
- package/dist/types/registry/perplexity.d.ts +7 -0
- package/dist/types/registry/qianfan.d.ts +7 -0
- package/dist/types/registry/qwen-portal.d.ts +7 -0
- package/dist/types/registry/registry.d.ts +272 -0
- package/dist/types/registry/synthetic.d.ts +6 -0
- package/dist/types/registry/tavily.d.ts +14 -0
- package/dist/types/registry/together.d.ts +6 -0
- package/dist/types/registry/types.d.ts +51 -0
- package/dist/types/registry/venice.d.ts +13 -0
- package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
- package/dist/types/registry/vllm.d.ts +7 -0
- package/dist/types/registry/wafer-pass.d.ts +6 -0
- package/dist/types/registry/wafer-serverless.d.ts +6 -0
- package/dist/types/registry/xai-oauth.d.ts +7 -0
- package/dist/types/registry/xai.d.ts +4 -0
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
- package/dist/types/registry/xiaomi.d.ts +6 -0
- package/dist/types/registry/zai.d.ts +7 -0
- package/dist/types/registry/zenmux.d.ts +7 -0
- package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
- package/dist/types/stream.d.ts +9 -1
- package/dist/types/types.d.ts +56 -295
- package/dist/types/usage/google-antigravity.d.ts +15 -1
- package/dist/types/usage/openai-codex-reset.d.ts +79 -0
- package/dist/types/usage/openai-codex.d.ts +1 -0
- package/dist/types/usage.d.ts +77 -4
- package/dist/types/utils/abort.d.ts +6 -0
- package/dist/types/utils/event-stream.d.ts +2 -0
- package/dist/types/utils/http-inspector.d.ts +0 -1
- package/dist/types/utils/idle-iterator.d.ts +35 -0
- package/dist/types/utils/openai-http.d.ts +58 -0
- package/dist/types/utils/request-debug.d.ts +3 -0
- package/dist/types/utils/retry-after.d.ts +1 -0
- package/dist/types/utils/schema/fields.d.ts +5 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +7 -15
- package/dist/types/utils/sse-debug.d.ts +0 -5
- package/dist/types/utils/stream-markup-healing.d.ts +2 -0
- package/dist/types/utils.d.ts +1 -5
- package/package.json +17 -29
- package/src/auth-broker/remote-store.ts +10 -1
- package/src/auth-broker/snapshot-cache.ts +1 -1
- package/src/auth-broker/wire-schemas.ts +1 -1
- package/src/auth-gateway/http.ts +1 -1
- package/src/auth-gateway/server.ts +95 -30
- package/src/auth-gateway/types.ts +10 -2
- package/src/auth-retry.ts +238 -0
- package/src/auth-storage.ts +935 -430
- package/src/errors.ts +32 -0
- package/src/index.ts +9 -14
- package/src/provider-details.ts +1 -1
- package/src/providers/__tests__/google-auth.test.ts +144 -0
- package/src/providers/amazon-bedrock.ts +70 -40
- package/src/providers/anthropic-client.ts +15 -13
- package/src/providers/anthropic-messages-server-schema.ts +17 -7
- package/src/providers/anthropic-messages-server.ts +88 -20
- package/src/providers/anthropic-wire.ts +4 -3
- package/src/providers/anthropic.ts +1234 -621
- package/src/providers/aws-credentials.ts +47 -5
- package/src/providers/aws-eventstream.ts +5 -0
- package/src/providers/azure-openai-responses.ts +117 -67
- package/src/providers/cursor.ts +30 -30
- package/src/providers/github-copilot-headers.ts +1 -1
- package/src/providers/gitlab-duo.ts +36 -29
- package/src/providers/google-auth.ts +71 -8
- package/src/providers/google-gemini-cli.ts +118 -22
- package/src/providers/google-shared.ts +163 -43
- package/src/providers/google-types.ts +10 -1
- package/src/providers/kimi.ts +1 -1
- package/src/providers/mock.ts +11 -3
- package/src/providers/ollama.ts +64 -7
- package/src/providers/openai-anthropic-shim.ts +17 -8
- package/src/providers/openai-chat-server-schema.ts +9 -3
- package/src/providers/openai-chat-server.ts +82 -16
- package/src/providers/openai-chat-wire.ts +847 -0
- package/src/providers/openai-codex/request-transformer.ts +129 -34
- package/src/providers/openai-codex/response-handler.ts +22 -1
- package/src/providers/openai-codex-responses.ts +699 -247
- package/src/providers/openai-completions-compat.ts +8 -308
- package/src/providers/openai-completions.ts +416 -267
- package/src/providers/openai-responses-server-schema.ts +15 -9
- package/src/providers/openai-responses-server.ts +162 -114
- package/src/providers/openai-responses-shared.ts +320 -82
- package/src/providers/openai-responses-wire.ts +6391 -0
- package/src/providers/openai-responses.ts +382 -176
- package/src/providers/prometheus-native-client.ts +27 -11
- package/src/providers/prometheus-native-server.ts +44 -17
- package/src/providers/transform-messages.ts +311 -120
- package/src/providers/vision-guard.ts +5 -3
- package/src/rate-limit-utils.ts +13 -3
- package/src/registry/aimlapi.ts +6 -0
- package/src/{utils/oauth → registry}/alibaba-coding-plan.ts +8 -18
- package/src/registry/amazon-bedrock.ts +22 -0
- package/src/registry/anthropic.ts +26 -0
- package/src/{utils/oauth → registry}/api-key-login.ts +25 -3
- package/src/{utils/oauth → registry}/api-key-validation.ts +62 -2
- package/src/{utils/oauth → registry}/cerebras.ts +8 -1
- package/src/{utils/oauth → registry}/cloudflare-ai-gateway.ts +8 -12
- package/src/registry/cursor.ts +20 -0
- package/src/{utils/oauth → registry}/deepseek.ts +9 -17
- package/src/registry/derived.ts +9 -0
- package/src/{utils/oauth → registry}/firepass.ts +10 -2
- package/src/{utils/oauth → registry}/fireworks.ts +8 -1
- package/src/registry/github-copilot.ts +22 -0
- package/src/registry/gitlab-duo.ts +19 -0
- package/src/registry/google-antigravity.ts +21 -0
- package/src/registry/google-gemini-cli.ts +21 -0
- package/src/registry/google-vertex.ts +38 -0
- package/src/registry/google.ts +6 -0
- package/src/registry/groq.ts +6 -0
- package/src/{utils/oauth → registry}/huggingface.ts +8 -19
- package/src/registry/index.ts +4 -0
- package/src/{utils/oauth → registry}/kagi.ts +9 -11
- package/src/{utils/oauth → registry}/kilo.ts +11 -6
- package/src/registry/kimi-code.ts +17 -0
- package/src/{utils/oauth → registry}/litellm.ts +8 -12
- package/src/{utils/oauth → registry}/lm-studio.ts +9 -17
- package/src/registry/minimax-code-cn.ts +12 -0
- package/src/registry/minimax-code.ts +12 -0
- package/src/registry/minimax.ts +6 -0
- package/src/registry/mistral.ts +6 -0
- package/src/{utils/oauth → registry}/moonshot.ts +8 -9
- package/src/{utils/oauth → registry}/nanogpt.ts +8 -1
- package/src/{utils/oauth → registry}/nvidia.ts +8 -18
- package/src/{utils → registry}/oauth/__tests__/xai-oauth.test.ts +4 -7
- package/src/{utils → registry}/oauth/anthropic.ts +38 -17
- package/src/{utils → registry}/oauth/github-copilot.ts +79 -115
- package/src/registry/oauth/gitlab-duo.ts +198 -0
- package/src/{utils → registry}/oauth/google-antigravity.ts +1 -4
- package/src/{utils → registry}/oauth/google-gemini-cli.ts +1 -4
- package/src/registry/oauth/index.ts +164 -0
- package/src/{utils → registry}/oauth/minimax-code.ts +16 -14
- package/src/{utils → registry}/oauth/types.ts +7 -51
- package/src/{utils → registry}/oauth/wafer.ts +1 -1
- package/src/{utils → registry}/oauth/xai-oauth.ts +16 -8
- package/src/{utils → registry}/oauth/xiaomi.ts +9 -4
- package/src/{utils/oauth → registry}/ollama-cloud.ts +8 -1
- package/src/{utils/oauth → registry}/ollama.ts +8 -13
- package/src/registry/openai-codex-device.ts +18 -0
- package/src/registry/openai-codex.ts +19 -0
- package/src/registry/openai.ts +6 -0
- package/src/registry/opencode-go.ts +12 -0
- package/src/registry/opencode-zen.ts +12 -0
- package/src/{utils/oauth → registry}/openrouter.ts +10 -2
- package/src/{utils/oauth → registry}/parallel.ts +9 -11
- package/src/registry/perplexity.ts +13 -0
- package/src/{utils/oauth → registry}/qianfan.ts +8 -17
- package/src/{utils/oauth → registry}/qwen-portal.ts +8 -19
- package/src/registry/registry.ts +149 -0
- package/src/{utils/oauth → registry}/synthetic.ts +7 -1
- package/src/{utils/oauth → registry}/tavily.ts +10 -12
- package/src/{utils/oauth → registry}/together.ts +7 -1
- package/src/registry/types.ts +56 -0
- package/src/{utils/oauth → registry}/venice.ts +8 -12
- package/src/{utils/oauth → registry}/vercel-ai-gateway.ts +8 -18
- package/src/{utils/oauth → registry}/vllm.ts +9 -16
- package/src/registry/wafer-pass.ts +12 -0
- package/src/registry/wafer-serverless.ts +12 -0
- package/src/registry/xai-oauth.ts +17 -0
- package/src/registry/xai.ts +6 -0
- package/src/registry/xiaomi-token-plan-ams.ts +12 -0
- package/src/registry/xiaomi-token-plan-cn.ts +12 -0
- package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
- package/src/registry/xiaomi.ts +12 -0
- package/src/{utils/oauth → registry}/zai.ts +10 -22
- package/src/{utils/oauth → registry}/zenmux.ts +8 -1
- package/src/{utils/oauth/zhipu.ts → registry/zhipu-coding-plan.ts} +9 -21
- package/src/stream.ts +229 -199
- package/src/types.ts +63 -384
- package/src/usage/claude.ts +4 -2
- package/src/usage/github-copilot.ts +4 -2
- package/src/usage/google-antigravity.ts +196 -28
- package/src/usage/kimi.ts +1 -1
- package/src/usage/minimax-code.ts +5 -6
- package/src/usage/openai-codex-reset.ts +174 -0
- package/src/usage/openai-codex.ts +19 -2
- package/src/usage/zai.ts +2 -1
- package/src/usage.ts +93 -4
- package/src/utils/abort.ts +14 -0
- package/src/utils/event-stream.ts +17 -0
- package/src/utils/http-inspector.ts +4 -12
- package/src/utils/idle-iterator.ts +250 -79
- package/src/utils/openai-http.ts +157 -0
- package/src/utils/request-debug.ts +67 -19
- package/src/utils/retry-after.ts +1 -1
- package/src/utils/retry.ts +23 -2
- package/src/utils/schema/CONSTRAINTS.md +4 -2
- package/src/utils/schema/fields.ts +16 -0
- package/src/utils/schema/json-schema-validator.ts +19 -1
- package/src/utils/schema/normalize.ts +80 -8
- package/src/utils/schema/stamps.ts +22 -10
- package/src/utils/schema/wire.ts +2 -2
- package/src/utils/sse-debug.ts +0 -271
- package/src/utils/stream-markup-healing.ts +50 -8
- package/src/utils/validation.ts +49 -13
- package/src/utils.ts +2 -26
- package/dist/types/model-cache.d.ts +0 -17
- package/dist/types/model-manager.d.ts +0 -64
- package/dist/types/model-thinking.d.ts +0 -100
- package/dist/types/models.d.ts +0 -12
- package/dist/types/provider-models/bundled-references.d.ts +0 -4
- package/dist/types/provider-models/descriptors.d.ts +0 -50
- package/dist/types/provider-models/google.d.ts +0 -24
- package/dist/types/provider-models/index.d.ts +0 -5
- package/dist/types/provider-models/ollama.d.ts +0 -7
- package/dist/types/provider-models/openai-compat.d.ts +0 -323
- package/dist/types/provider-models/special.d.ts +0 -16
- package/dist/types/utils/discovery/antigravity.d.ts +0 -61
- package/dist/types/utils/discovery/codex.d.ts +0 -38
- package/dist/types/utils/discovery/cursor.d.ts +0 -23
- package/dist/types/utils/discovery/gemini.d.ts +0 -25
- package/dist/types/utils/discovery/index.d.ts +0 -4
- package/dist/types/utils/discovery/openai-compatible.d.ts +0 -72
- package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +0 -18
- package/dist/types/utils/oauth/cerebras.d.ts +0 -1
- package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +0 -18
- package/dist/types/utils/oauth/deepseek.d.ts +0 -10
- package/dist/types/utils/oauth/firepass.d.ts +0 -1
- package/dist/types/utils/oauth/fireworks.d.ts +0 -1
- package/dist/types/utils/oauth/huggingface.d.ts +0 -19
- package/dist/types/utils/oauth/kagi.d.ts +0 -17
- package/dist/types/utils/oauth/kilo.d.ts +0 -5
- package/dist/types/utils/oauth/litellm.d.ts +0 -18
- package/dist/types/utils/oauth/lm-studio.d.ts +0 -17
- package/dist/types/utils/oauth/moonshot.d.ts +0 -1
- package/dist/types/utils/oauth/nanogpt.d.ts +0 -1
- package/dist/types/utils/oauth/nvidia.d.ts +0 -18
- package/dist/types/utils/oauth/ollama-cloud.d.ts +0 -2
- package/dist/types/utils/oauth/ollama.d.ts +0 -18
- package/dist/types/utils/oauth/openrouter.d.ts +0 -1
- package/dist/types/utils/oauth/parallel.d.ts +0 -17
- package/dist/types/utils/oauth/qianfan.d.ts +0 -17
- package/dist/types/utils/oauth/qwen-portal.d.ts +0 -19
- package/dist/types/utils/oauth/synthetic.d.ts +0 -1
- package/dist/types/utils/oauth/tavily.d.ts +0 -17
- package/dist/types/utils/oauth/together.d.ts +0 -1
- package/dist/types/utils/oauth/venice.d.ts +0 -18
- package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +0 -18
- package/dist/types/utils/oauth/vllm.d.ts +0 -16
- package/dist/types/utils/oauth/zai.d.ts +0 -18
- package/dist/types/utils/oauth/zenmux.d.ts +0 -1
- package/dist/types/utils/oauth/zhipu.d.ts +0 -18
- package/src/model-cache.ts +0 -129
- package/src/model-manager.ts +0 -469
- package/src/model-thinking.ts +0 -756
- package/src/models.json +0 -60287
- package/src/models.json.d.ts +0 -9
- package/src/models.ts +0 -56
- package/src/provider-models/bundled-references.ts +0 -38
- package/src/provider-models/descriptors.ts +0 -364
- package/src/provider-models/google.ts +0 -88
- package/src/provider-models/index.ts +0 -5
- package/src/provider-models/ollama.ts +0 -153
- package/src/provider-models/openai-compat.ts +0 -2904
- package/src/provider-models/special.ts +0 -67
- package/src/utils/discovery/antigravity.ts +0 -261
- package/src/utils/discovery/codex.ts +0 -371
- package/src/utils/discovery/cursor.ts +0 -306
- package/src/utils/discovery/gemini.ts +0 -248
- package/src/utils/discovery/index.ts +0 -4
- package/src/utils/discovery/openai-compatible.ts +0 -224
- package/src/utils/oauth/gitlab-duo.ts +0 -123
- package/src/utils/oauth/index.ts +0 -502
- /package/dist/types/{utils/oauth/__tests__/xai-oauth.test.d.ts → providers/__tests__/google-auth.test.d.ts} +0 -0
- /package/dist/types/{utils → registry}/oauth/callback-server.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/cursor.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/gitlab-duo.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/google-antigravity.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/google-gemini-cli.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/google-oauth-shared.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/kimi.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/openai-codex.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/opencode.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/perplexity.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/pkce.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/wafer.d.ts +0 -0
- /package/dist/types/{utils → registry}/oauth/xiaomi.d.ts +0 -0
- /package/src/{utils → registry}/oauth/callback-server.ts +0 -0
- /package/src/{utils → registry}/oauth/cursor.ts +0 -0
- /package/src/{utils → registry}/oauth/google-oauth-shared.ts +0 -0
- /package/src/{utils → registry}/oauth/kimi.ts +0 -0
- /package/src/{utils → registry}/oauth/oauth.html +0 -0
- /package/src/{utils → registry}/oauth/openai-codex.ts +0 -0
- /package/src/{utils → registry}/oauth/opencode.ts +0 -0
- /package/src/{utils → registry}/oauth/perplexity.ts +0 -0
- /package/src/{utils → registry}/oauth/pkce.ts +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { extractHttpStatusFromError } from "@prometheus-ai/utils";
|
|
2
|
+
import type { OAuthAccess } from "./auth-storage";
|
|
3
|
+
import { isUsageLimitError } from "./rate-limit-utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Context passed to an {@link ApiKeyResolver} on each resolution attempt.
|
|
7
|
+
*
|
|
8
|
+
* The `error`/`lastChance` pair drives the central a/b/c retry policy shared by
|
|
9
|
+
* the streaming ({@link streamSimple}) and non-streaming ({@link withAuth})
|
|
10
|
+
* drivers:
|
|
11
|
+
* - `error === undefined` → **initial resolve** (no force-refresh; cheap, may
|
|
12
|
+
* return a locally-cached not-yet-expired token).
|
|
13
|
+
* - `error !== undefined && !lastChance` → **step (b): refresh the SAME
|
|
14
|
+
* account** (force a token re-mint / await an in-flight broker refresh).
|
|
15
|
+
* - `error !== undefined && lastChance` → **step (c): switch account**
|
|
16
|
+
* (invalidate/usage-limit the current credential and rotate to a sibling).
|
|
17
|
+
*
|
|
18
|
+
* The resolver returns the bearer to send, or `undefined` to stop retrying and
|
|
19
|
+
* surface the last error to the caller.
|
|
20
|
+
*/
|
|
21
|
+
export interface ApiKeyResolveContext {
|
|
22
|
+
/** True on the final retry step — the resolver should rotate to a sibling credential. */
|
|
23
|
+
lastChance: boolean;
|
|
24
|
+
/** The auth error that triggered this re-resolution, or `undefined` on the initial resolve. */
|
|
25
|
+
error: unknown;
|
|
26
|
+
/** Caller cancel signal, threaded into any credential refresh / rotation work. */
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolves the API key to send for a request, retried through the a/b/c policy
|
|
32
|
+
* described on {@link ApiKeyResolveContext}.
|
|
33
|
+
*/
|
|
34
|
+
export type ApiKeyResolver = (ctx: ApiKeyResolveContext) => Promise<string | undefined> | string | undefined;
|
|
35
|
+
|
|
36
|
+
/** A static bearer string, or a {@link ApiKeyResolver} that mints/rotates one. */
|
|
37
|
+
export type ApiKey = string | ApiKeyResolver;
|
|
38
|
+
|
|
39
|
+
/** Narrows {@link ApiKey} to its resolver form. */
|
|
40
|
+
export function isApiKeyResolver(key: ApiKey | undefined): key is ApiKeyResolver {
|
|
41
|
+
return typeof key === "function";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Performs the initial resolve of an {@link ApiKey} (`error: undefined`,
|
|
46
|
+
* `lastChance: false`). Static keys pass through unchanged.
|
|
47
|
+
*/
|
|
48
|
+
export async function resolveApiKeyOnce(key: ApiKey | undefined, signal?: AbortSignal): Promise<string | undefined> {
|
|
49
|
+
if (key === undefined) return undefined;
|
|
50
|
+
if (isApiKeyResolver(key)) return (await key({ lastChance: false, error: undefined, signal })) || undefined;
|
|
51
|
+
return key;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Classifies whether an error should trigger a credential refresh/rotation
|
|
56
|
+
* retry: a hard `401`, or a rotatable usage-limit ("usage_limit_reached",
|
|
57
|
+
* Codex's "you have hit your ChatGPT usage limit", etc.).
|
|
58
|
+
*/
|
|
59
|
+
export function isAuthRetryableError(error: unknown): boolean {
|
|
60
|
+
if (extractHttpStatusFromError(error) === 401) return true;
|
|
61
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : undefined;
|
|
62
|
+
if (!message) return false;
|
|
63
|
+
if (extractHttpStatusFromError({ message }) === 401) return true;
|
|
64
|
+
return isUsageLimitError(message);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The ordered `lastChance` values for the retry steps after the initial
|
|
69
|
+
* attempt fails: `false` → step (b) refresh-same, `true` → step (c) switch.
|
|
70
|
+
* Shared by {@link withAuth} and the streaming retry driver so both run the
|
|
71
|
+
* same policy.
|
|
72
|
+
*/
|
|
73
|
+
export const AUTH_RETRY_STEPS: readonly boolean[] = [false, true];
|
|
74
|
+
|
|
75
|
+
/** Resolve a single retry step, swallowing resolver failures into `undefined`. */
|
|
76
|
+
export async function resolveRetryKey(
|
|
77
|
+
resolver: ApiKeyResolver,
|
|
78
|
+
lastChance: boolean,
|
|
79
|
+
error: unknown,
|
|
80
|
+
signal?: AbortSignal,
|
|
81
|
+
): Promise<string | undefined> {
|
|
82
|
+
try {
|
|
83
|
+
return (await resolver({ lastChance, error, signal })) || undefined;
|
|
84
|
+
} catch {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Runs an auth-protected operation through the central a/b/c retry policy.
|
|
91
|
+
*
|
|
92
|
+
* - A static string key (or any non-resolver) → a single `attempt` with no
|
|
93
|
+
* retry (identical to the legacy static-key path).
|
|
94
|
+
* - A resolver → initial `attempt`, then on a retryable auth error up to two
|
|
95
|
+
* more attempts (refresh-same, then switch). A step is skipped when the
|
|
96
|
+
* resolver returns the same key it just tried or `undefined`; non-auth errors
|
|
97
|
+
* propagate immediately.
|
|
98
|
+
*
|
|
99
|
+
* Used by non-streaming consumers (image generation, web search, completion
|
|
100
|
+
* helpers). The streaming driver in `stream.ts` implements the same policy with
|
|
101
|
+
* its replay-safe buffering machinery.
|
|
102
|
+
*/
|
|
103
|
+
export async function withAuth<T>(
|
|
104
|
+
key: ApiKey | undefined,
|
|
105
|
+
attempt: (key: string) => Promise<T>,
|
|
106
|
+
opts?: { isAuthError?: (error: unknown) => boolean; signal?: AbortSignal; missingKeyMessage?: string },
|
|
107
|
+
): Promise<T> {
|
|
108
|
+
const isAuthError = opts?.isAuthError ?? isAuthRetryableError;
|
|
109
|
+
const missingKey = (): Error => new Error(opts?.missingKeyMessage ?? "No API key available");
|
|
110
|
+
|
|
111
|
+
if (!isApiKeyResolver(key)) {
|
|
112
|
+
if (key === undefined) throw missingKey();
|
|
113
|
+
return attempt(key);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const resolver = key;
|
|
117
|
+
const signal = opts?.signal;
|
|
118
|
+
let lastKey = await resolveRetryKey(resolver, false, undefined, signal);
|
|
119
|
+
if (lastKey === undefined) throw missingKey();
|
|
120
|
+
|
|
121
|
+
let lastError: unknown;
|
|
122
|
+
try {
|
|
123
|
+
return await attempt(lastKey);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (!isAuthError(error)) throw error;
|
|
126
|
+
lastError = error;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (let i = 0; i < AUTH_RETRY_STEPS.length; i++) {
|
|
130
|
+
const nextKey = await resolveRetryKey(resolver, AUTH_RETRY_STEPS[i]!, lastError, signal);
|
|
131
|
+
if (nextKey === undefined || nextKey === lastKey) continue;
|
|
132
|
+
lastKey = nextKey;
|
|
133
|
+
try {
|
|
134
|
+
return await attempt(nextKey);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (!isAuthError(error)) throw error;
|
|
137
|
+
lastError = error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw lastError;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Minimal structural slice of `AuthStorage` consumed by {@link withOAuthAccess}.
|
|
146
|
+
* Typed structurally (and importing only the `OAuthAccess` type) so this module
|
|
147
|
+
* never takes a runtime dependency on `./auth-storage`.
|
|
148
|
+
*/
|
|
149
|
+
export interface OAuthAccessSource {
|
|
150
|
+
getOAuthAccess(
|
|
151
|
+
provider: string,
|
|
152
|
+
sessionId?: string,
|
|
153
|
+
options?: { forceRefresh?: boolean; signal?: AbortSignal },
|
|
154
|
+
): Promise<OAuthAccess | undefined>;
|
|
155
|
+
rotateSessionCredential(
|
|
156
|
+
provider: string,
|
|
157
|
+
sessionId: string | undefined,
|
|
158
|
+
options?: { error?: unknown; signal?: AbortSignal },
|
|
159
|
+
): Promise<boolean>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface WithOAuthAccessOptions {
|
|
163
|
+
/** Session id for credential stickiness, threaded into every resolve. */
|
|
164
|
+
sessionId?: string;
|
|
165
|
+
signal?: AbortSignal;
|
|
166
|
+
/** Override the retryable-error classifier (default {@link isAuthRetryableError}). */
|
|
167
|
+
isAuthError?: (error: unknown) => boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Pre-resolved access used for the initial attempt. Callers that already
|
|
170
|
+
* resolved access for an availability gate pass it here so the helper
|
|
171
|
+
* doesn't double-resolve (mirrors the gateway resolver's `initialKey`).
|
|
172
|
+
*/
|
|
173
|
+
seed?: OAuthAccess;
|
|
174
|
+
missingAccessMessage?: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* {@link withAuth} for OAuth-access consumers: runs an auth-protected
|
|
179
|
+
* operation through the central a/b/c retry policy, handing the attempt the
|
|
180
|
+
* full {@link OAuthAccess} (bearer + identity metadata: `accountId`,
|
|
181
|
+
* `projectId`, `enterpriseUrl`) instead of bare API-key bytes.
|
|
182
|
+
*
|
|
183
|
+
* - initial → `getOAuthAccess` (or `opts.seed`).
|
|
184
|
+
* - step (b) → `getOAuthAccess` with `forceRefresh: true` (re-mint the SAME
|
|
185
|
+
* account; picks up peer/broker rotations).
|
|
186
|
+
* - step (c) → `rotateSessionCredential` then re-resolve (switch to a sibling).
|
|
187
|
+
*
|
|
188
|
+
* A step is skipped when it yields no access or the same `accessToken` that
|
|
189
|
+
* just failed; non-auth errors propagate immediately. Use this instead of
|
|
190
|
+
* hand-rolled `getOAuthAccess` + fetch flows so 401s and usage-limits rotate
|
|
191
|
+
* credentials instead of failing the call.
|
|
192
|
+
*/
|
|
193
|
+
export async function withOAuthAccess<T>(
|
|
194
|
+
storage: OAuthAccessSource,
|
|
195
|
+
provider: string,
|
|
196
|
+
attempt: (access: OAuthAccess) => Promise<T>,
|
|
197
|
+
opts?: WithOAuthAccessOptions,
|
|
198
|
+
): Promise<T> {
|
|
199
|
+
const isAuthError = opts?.isAuthError ?? isAuthRetryableError;
|
|
200
|
+
const { sessionId, signal } = opts ?? {};
|
|
201
|
+
|
|
202
|
+
let lastAccess = opts?.seed ?? (await storage.getOAuthAccess(provider, sessionId, { signal }));
|
|
203
|
+
if (!lastAccess) {
|
|
204
|
+
throw new Error(opts?.missingAccessMessage ?? `No OAuth credential available for provider: ${provider}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const resolveStep = async (lastChance: boolean, error: unknown): Promise<OAuthAccess | undefined> => {
|
|
208
|
+
try {
|
|
209
|
+
if (!lastChance) return await storage.getOAuthAccess(provider, sessionId, { forceRefresh: true, signal });
|
|
210
|
+
await storage.rotateSessionCredential(provider, sessionId, { error, signal });
|
|
211
|
+
return await storage.getOAuthAccess(provider, sessionId, { signal });
|
|
212
|
+
} catch {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
let lastError: unknown;
|
|
218
|
+
try {
|
|
219
|
+
return await attempt(lastAccess);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (!isAuthError(error)) throw error;
|
|
222
|
+
lastError = error;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
for (const lastChance of AUTH_RETRY_STEPS) {
|
|
226
|
+
const next = await resolveStep(lastChance, lastError);
|
|
227
|
+
if (!next || next.accessToken === lastAccess.accessToken) continue;
|
|
228
|
+
lastAccess = next;
|
|
229
|
+
try {
|
|
230
|
+
return await attempt(next);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (!isAuthError(error)) throw error;
|
|
233
|
+
lastError = error;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
throw lastError;
|
|
238
|
+
}
|