@linxiraos/pi-ai 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5066 -0
- package/README.md +1195 -0
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth/sqlite-credential-store.d.ts +117 -0
- package/dist/types/auth-broker/client.d.ts +93 -0
- package/dist/types/auth-broker/discover.d.ts +39 -0
- package/dist/types/auth-broker/index.d.ts +7 -0
- package/dist/types/auth-broker/refresher.d.ts +25 -0
- package/dist/types/auth-broker/remote-store.d.ts +136 -0
- package/dist/types/auth-broker/server.d.ts +48 -0
- package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
- package/dist/types/auth-broker/types.d.ts +152 -0
- package/dist/types/auth-broker/wire-schema-resource.d.ts +53 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +5 -0
- package/dist/types/auth-gateway/http.d.ts +56 -0
- package/dist/types/auth-gateway/index.d.ts +3 -0
- package/dist/types/auth-gateway/server.d.ts +36 -0
- package/dist/types/auth-gateway/types.d.ts +127 -0
- package/dist/types/auth-retry.d.ts +150 -0
- package/dist/types/auth-storage.d.ts +1258 -0
- package/dist/types/dialect/anthropic.d.ts +15 -0
- package/dist/types/dialect/catalog.d.ts +3 -0
- package/dist/types/dialect/coercion.d.ts +23 -0
- package/dist/types/dialect/deepseek.d.ts +14 -0
- package/dist/types/dialect/demotion.d.ts +30 -0
- package/dist/types/dialect/examples.d.ts +18 -0
- package/dist/types/dialect/factory.d.ts +3 -0
- package/dist/types/dialect/fenced-thinking.d.ts +53 -0
- package/dist/types/dialect/gemini.d.ts +17 -0
- package/dist/types/dialect/gemma.d.ts +15 -0
- package/dist/types/dialect/glm.d.ts +9 -0
- package/dist/types/dialect/harmony.d.ts +8 -0
- package/dist/types/dialect/hermes.d.ts +9 -0
- package/dist/types/dialect/history.d.ts +3 -0
- package/dist/types/dialect/index.d.ts +11 -0
- package/dist/types/dialect/inventory.d.ts +9 -0
- package/dist/types/dialect/kimi.d.ts +14 -0
- package/dist/types/dialect/minimax.d.ts +3 -0
- package/dist/types/dialect/owned-stream.d.ts +4 -0
- package/dist/types/dialect/qwen3.d.ts +9 -0
- package/dist/types/dialect/rendering.d.ts +54 -0
- package/dist/types/dialect/thinking.d.ts +6 -0
- package/dist/types/dialect/types.d.ts +68 -0
- package/dist/types/dialect/xml.d.ts +9 -0
- package/dist/types/error/abort.d.ts +14 -0
- package/dist/types/error/auth-classify.d.ts +20 -0
- package/dist/types/error/auth.d.ts +27 -0
- package/dist/types/error/aws.d.ts +27 -0
- package/dist/types/error/classes.d.ts +106 -0
- package/dist/types/error/finalize.d.ts +39 -0
- package/dist/types/error/flags.d.ts +94 -0
- package/dist/types/error/format.d.ts +20 -0
- package/dist/types/error/gateway.d.ts +20 -0
- package/dist/types/error/index.d.ts +14 -0
- package/dist/types/error/oauth.d.ts +43 -0
- package/dist/types/error/provider.d.ts +42 -0
- package/dist/types/error/rate-limit.d.ts +80 -0
- package/dist/types/error/retryable.d.ts +27 -0
- package/dist/types/error/validation.d.ts +32 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/providers/amazon-bedrock.d.ts +39 -0
- package/dist/types/providers/anthropic-client.d.ts +106 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +937 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic-wire.d.ts +345 -0
- package/dist/types/providers/anthropic.d.ts +261 -0
- package/dist/types/providers/aws-credentials.d.ts +48 -0
- package/dist/types/providers/aws-eventstream.d.ts +39 -0
- package/dist/types/providers/aws-sigv4.d.ts +55 -0
- package/dist/types/providers/azure-openai-responses.d.ts +16 -0
- package/dist/types/providers/bedrock-mantle.d.ts +13 -0
- package/dist/types/providers/claude-code-fingerprint.d.ts +19 -0
- package/dist/types/providers/cowork-fetch.d.ts +3 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
- package/dist/types/providers/cursor-pi-args.d.ts +105 -0
- package/dist/types/providers/cursor.d.ts +221 -0
- package/dist/types/providers/devin.d.ts +12 -0
- package/dist/types/providers/error-message.d.ts +25 -0
- package/dist/types/providers/github-copilot-headers.d.ts +40 -0
- package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
- package/dist/types/providers/gitlab-duo.d.ts +27 -0
- package/dist/types/providers/google-auth.d.ts +24 -0
- package/dist/types/providers/google-gemini-cli.d.ts +120 -0
- package/dist/types/providers/google-shared.d.ts +203 -0
- package/dist/types/providers/google-types.d.ts +155 -0
- package/dist/types/providers/google-vertex.d.ts +7 -0
- package/dist/types/providers/google.d.ts +4 -0
- package/dist/types/providers/grammar.d.ts +1 -0
- package/dist/types/providers/kimi.d.ts +27 -0
- package/dist/types/providers/mock.d.ts +179 -0
- package/dist/types/providers/ollama.d.ts +8 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +35 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +1311 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-chat-wire.d.ts +669 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +109 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
- package/dist/types/providers/openai-codex-responses.d.ts +238 -0
- package/dist/types/providers/openai-completions.d.ts +48 -0
- package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +1314 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-wire.d.ts +6099 -0
- package/dist/types/providers/openai-responses.d.ts +131 -0
- package/dist/types/providers/openai-shared.d.ts +624 -0
- package/dist/types/providers/pi-native-client.d.ts +13 -0
- package/dist/types/providers/pi-native-server.d.ts +69 -0
- package/dist/types/providers/register-builtins.d.ts +37 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +32 -0
- package/dist/types/providers/vision-guard.d.ts +20 -0
- package/dist/types/registry/aiand.d.ts +7 -0
- package/dist/types/registry/aimlapi.d.ts +4 -0
- package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
- package/dist/types/registry/alibaba-token-plan.d.ts +18 -0
- package/dist/types/registry/amazon-bedrock.d.ts +5 -0
- package/dist/types/registry/anthropic.d.ts +10 -0
- package/dist/types/registry/api-key-login.d.ts +42 -0
- package/dist/types/registry/api-key-validation.d.ts +43 -0
- package/dist/types/registry/aws.d.ts +13 -0
- package/dist/types/registry/azure.d.ts +4 -0
- package/dist/types/registry/baseten.d.ts +7 -0
- package/dist/types/registry/bedrock-mantle.d.ts +22 -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/coreweave.d.ts +7 -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/devin.d.ts +8 -0
- package/dist/types/registry/exa.d.ts +8 -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-workflow.d.ts +10 -0
- package/dist/types/registry/gitlab-duo.d.ts +9 -0
- package/dist/types/registry/gmi-cloud.d.ts +7 -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/llama-cpp.d.ts +8 -0
- package/dist/types/registry/lm-studio.d.ts +8 -0
- package/dist/types/registry/meta.d.ts +7 -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/novita.d.ts +6 -0
- package/dist/types/registry/nvidia.d.ts +7 -0
- package/dist/types/registry/oauth/anthropic-constants.d.ts +12 -0
- package/dist/types/registry/oauth/anthropic.d.ts +24 -0
- package/dist/types/registry/oauth/callback-server.d.ts +74 -0
- package/dist/types/registry/oauth/cursor.d.ts +16 -0
- package/dist/types/registry/oauth/device-code.d.ts +25 -0
- package/dist/types/registry/oauth/devin.d.ts +5 -0
- package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
- package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
- package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +22 -0
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +56 -0
- package/dist/types/registry/oauth/index.d.ts +45 -0
- package/dist/types/registry/oauth/kimi.d.ts +21 -0
- package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
- package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
- package/dist/types/registry/oauth/opencode.d.ts +18 -0
- package/dist/types/registry/oauth/perplexity.d.ts +9 -0
- package/dist/types/registry/oauth/pkce.d.ts +8 -0
- package/dist/types/registry/oauth/types.d.ts +87 -0
- package/dist/types/registry/oauth/wafer.d.ts +1 -0
- package/dist/types/registry/oauth/xai-oauth.d.ts +46 -0
- package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
- package/dist/types/registry/oauth/zai.d.ts +25 -0
- 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 +367 -0
- package/dist/types/registry/sakana.d.ts +7 -0
- package/dist/types/registry/siliconflow-cn.d.ts +7 -0
- package/dist/types/registry/siliconflow.d.ts +7 -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 +75 -0
- package/dist/types/registry/umans.d.ts +7 -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-serverless.d.ts +6 -0
- package/dist/types/registry/xai-oauth.d.ts +7 -0
- package/dist/types/registry/xai.d.ts +7 -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 +15 -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 +46 -0
- package/dist/types/types.d.ts +1064 -0
- package/dist/types/usage/alibaba-token-plan.d.ts +3 -0
- package/dist/types/usage/claude.d.ts +4 -0
- package/dist/types/usage/cursor.d.ts +4 -0
- package/dist/types/usage/gemini.d.ts +2 -0
- package/dist/types/usage/github-copilot.d.ts +7 -0
- package/dist/types/usage/google-antigravity.d.ts +15 -0
- package/dist/types/usage/kimi.d.ts +2 -0
- package/dist/types/usage/minimax-code.d.ts +3 -0
- package/dist/types/usage/ollama.d.ts +5 -0
- package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
- package/dist/types/usage/openai-codex-reset.d.ts +88 -0
- package/dist/types/usage/openai-codex.d.ts +10 -0
- package/dist/types/usage/opencode-go.d.ts +2 -0
- package/dist/types/usage/shared.d.ts +1 -0
- package/dist/types/usage/synthetic.d.ts +2 -0
- package/dist/types/usage/umans.d.ts +2 -0
- package/dist/types/usage/xai-oauth.d.ts +12 -0
- package/dist/types/usage/zai.d.ts +3 -0
- package/dist/types/usage.d.ts +527 -0
- package/dist/types/utils/abort.d.ts +25 -0
- package/dist/types/utils/anthropic-auth.d.ts +35 -0
- package/dist/types/utils/aws-profile.d.ts +17 -0
- package/dist/types/utils/block-symbols.d.ts +62 -0
- package/dist/types/utils/deterministic-id.d.ts +16 -0
- package/dist/types/utils/empty-completion-retry.d.ts +21 -0
- package/dist/types/utils/event-stream.d.ts +39 -0
- package/dist/types/utils/foundry.d.ts +1 -0
- package/dist/types/utils/google-validation.d.ts +2 -0
- package/dist/types/utils/harmony-leak.d.ts +135 -0
- package/dist/types/utils/http-inspector.d.ts +49 -0
- package/dist/types/utils/idle-iterator.d.ts +149 -0
- package/dist/types/utils/leaked-thinking-stream.d.ts +33 -0
- package/dist/types/utils/openai-http.d.ts +48 -0
- package/dist/types/utils/openrouter-headers.d.ts +1 -0
- package/dist/types/utils/parse-bind.d.ts +23 -0
- package/dist/types/utils/provider-response.d.ts +3 -0
- package/dist/types/utils/proxy.d.ts +39 -0
- package/dist/types/utils/request-debug.d.ts +29 -0
- package/dist/types/utils/retry-after.d.ts +4 -0
- package/dist/types/utils/retry.d.ts +14 -0
- package/dist/types/utils/schema/adapt.d.ts +24 -0
- package/dist/types/utils/schema/compatibility.d.ts +30 -0
- package/dist/types/utils/schema/dereference.d.ts +11 -0
- package/dist/types/utils/schema/draft.d.ts +10 -0
- package/dist/types/utils/schema/equality.d.ts +4 -0
- package/dist/types/utils/schema/fields.d.ts +54 -0
- package/dist/types/utils/schema/index.d.ts +14 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
- package/dist/types/utils/schema/meta-validator.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +153 -0
- package/dist/types/utils/schema/spill.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +17 -0
- package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
- package/dist/types/utils/schema/types.d.ts +4 -0
- package/dist/types/utils/schema/typescript.d.ts +24 -0
- package/dist/types/utils/schema/wire.d.ts +52 -0
- package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
- package/dist/types/utils/sse-debug.d.ts +5 -0
- package/dist/types/utils/stream-markup-healing.d.ts +87 -0
- package/dist/types/utils/thinking-loop.d.ts +102 -0
- package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
- package/dist/types/utils/tool-choice.d.ts +52 -0
- package/dist/types/utils/validation.d.ts +28 -0
- package/dist/types/utils.d.ts +57 -0
- package/package.json +138 -0
- package/src/api-registry.ts +109 -0
- package/src/auth/sqlite-credential-store.ts +2066 -0
- package/src/auth-broker/client.ts +471 -0
- package/src/auth-broker/discover.ts +310 -0
- package/src/auth-broker/index.ts +7 -0
- package/src/auth-broker/refresher.ts +117 -0
- package/src/auth-broker/remote-store.ts +1332 -0
- package/src/auth-broker/server.ts +898 -0
- package/src/auth-broker/snapshot-cache.ts +200 -0
- package/src/auth-broker/types.ts +193 -0
- package/src/auth-broker/wire-schema-resource.ts +487 -0
- package/src/auth-broker/wire-schemas.ts +43 -0
- package/src/auth-gateway/http.ts +227 -0
- package/src/auth-gateway/index.ts +3 -0
- package/src/auth-gateway/server.ts +836 -0
- package/src/auth-gateway/types.ts +153 -0
- package/src/auth-retry.ts +401 -0
- package/src/auth-storage.ts +6540 -0
- package/src/dialect/anthropic.md +31 -0
- package/src/dialect/anthropic.ts +608 -0
- package/src/dialect/catalog.ts +29 -0
- package/src/dialect/coercion.ts +136 -0
- package/src/dialect/deepseek.md +24 -0
- package/src/dialect/deepseek.ts +609 -0
- package/src/dialect/demotion.ts +40 -0
- package/src/dialect/examples.ts +71 -0
- package/src/dialect/factory.ts +34 -0
- package/src/dialect/fenced-thinking.ts +184 -0
- package/src/dialect/gemini.md +44 -0
- package/src/dialect/gemini.ts +583 -0
- package/src/dialect/gemma.md +33 -0
- package/src/dialect/gemma.ts +387 -0
- package/src/dialect/glm.md +32 -0
- package/src/dialect/glm.ts +579 -0
- package/src/dialect/harmony.md +31 -0
- package/src/dialect/harmony.ts +345 -0
- package/src/dialect/hermes.md +25 -0
- package/src/dialect/hermes.ts +206 -0
- package/src/dialect/history.ts +81 -0
- package/src/dialect/index.ts +15 -0
- package/src/dialect/inventory.ts +30 -0
- package/src/dialect/kimi.md +24 -0
- package/src/dialect/kimi.ts +340 -0
- package/src/dialect/minimax.md +31 -0
- package/src/dialect/minimax.ts +95 -0
- package/src/dialect/owned-stream.ts +481 -0
- package/src/dialect/prompt-template.md +12 -0
- package/src/dialect/qwen3.md +28 -0
- package/src/dialect/qwen3.ts +240 -0
- package/src/dialect/rendering.ts +304 -0
- package/src/dialect/thinking.ts +292 -0
- package/src/dialect/types.ts +56 -0
- package/src/dialect/xml.md +22 -0
- package/src/dialect/xml.ts +90 -0
- package/src/error/abort.ts +18 -0
- package/src/error/auth-classify.ts +47 -0
- package/src/error/auth.ts +48 -0
- package/src/error/aws.ts +35 -0
- package/src/error/classes.ts +281 -0
- package/src/error/finalize.ts +69 -0
- package/src/error/flags.ts +602 -0
- package/src/error/format.ts +45 -0
- package/src/error/gateway.ts +96 -0
- package/src/error/index.ts +14 -0
- package/src/error/oauth.ts +58 -0
- package/src/error/provider.ts +63 -0
- package/src/error/rate-limit.ts +303 -0
- package/src/error/retryable.ts +70 -0
- package/src/error/validation.ts +44 -0
- package/src/index.ts +51 -0
- package/src/provider-details.ts +90 -0
- package/src/providers/amazon-bedrock.ts +1064 -0
- package/src/providers/anthropic-client.ts +317 -0
- package/src/providers/anthropic-messages-server-schema.ts +252 -0
- package/src/providers/anthropic-messages-server.ts +818 -0
- package/src/providers/anthropic-wire.ts +359 -0
- package/src/providers/anthropic.ts +4539 -0
- package/src/providers/aws-credentials.ts +772 -0
- package/src/providers/aws-eventstream.ts +181 -0
- package/src/providers/aws-sigv4.ts +218 -0
- package/src/providers/azure-openai-responses.ts +438 -0
- package/src/providers/bedrock-mantle.ts +110 -0
- package/src/providers/claude-code-fingerprint.ts +20 -0
- package/src/providers/cowork-fetch.ts +201 -0
- package/src/providers/cursor/exec-modern.ts +496 -0
- package/src/providers/cursor/proto/agent.proto +4533 -0
- package/src/providers/cursor/proto/buf.gen.yaml +6 -0
- package/src/providers/cursor/proto/buf.yaml +17 -0
- package/src/providers/cursor-pi-args.ts +165 -0
- package/src/providers/cursor.ts +4689 -0
- package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
- package/src/providers/devin/proto/buf.gen.yaml +33 -0
- package/src/providers/devin/proto/buf.yaml +17 -0
- package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
- package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
- package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
- package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
- package/src/providers/devin/proto/cel/expr/value.proto +41 -0
- package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
- package/src/providers/devin/proto/errorspb/errors.proto +56 -0
- package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
- package/src/providers/devin/proto/errorspb/markers.proto +10 -0
- package/src/providers/devin/proto/errorspb/tags.proto +12 -0
- package/src/providers/devin/proto/errorspb/testing.proto +6 -0
- package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
- package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
- package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
- package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
- package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
- package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
- package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
- package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
- package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
- package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
- package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
- package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
- package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
- package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
- package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
- package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
- package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
- package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
- package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
- package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
- package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
- package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
- package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
- package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
- package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
- package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
- package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
- package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
- package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
- package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
- package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
- package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
- package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
- package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
- package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
- package/src/providers/devin.ts +679 -0
- package/src/providers/error-message.ts +23 -0
- package/src/providers/github-copilot-headers.ts +141 -0
- package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
- package/src/providers/gitlab-duo-workflow.ts +3135 -0
- package/src/providers/gitlab-duo.ts +399 -0
- package/src/providers/google-auth.ts +330 -0
- package/src/providers/google-gemini-cli.ts +1370 -0
- package/src/providers/google-shared.ts +1122 -0
- package/src/providers/google-types.ts +180 -0
- package/src/providers/google-vertex.ts +135 -0
- package/src/providers/google.ts +47 -0
- package/src/providers/grammar.ts +70 -0
- package/src/providers/kimi.ts +51 -0
- package/src/providers/mock.ts +514 -0
- package/src/providers/ollama.ts +776 -0
- package/src/providers/openai-anthropic-shim.ts +166 -0
- package/src/providers/openai-chat-server-schema.ts +243 -0
- package/src/providers/openai-chat-server.ts +752 -0
- package/src/providers/openai-chat-wire.ts +859 -0
- package/src/providers/openai-codex/request-transformer.ts +491 -0
- package/src/providers/openai-codex/response-handler.ts +102 -0
- package/src/providers/openai-codex-responses.ts +4716 -0
- package/src/providers/openai-completions.ts +2389 -0
- package/src/providers/openai-reasoning-fallback.ts +269 -0
- package/src/providers/openai-responses-server-schema.ts +397 -0
- package/src/providers/openai-responses-server.ts +1466 -0
- package/src/providers/openai-responses-wire.ts +6416 -0
- package/src/providers/openai-responses.ts +1393 -0
- package/src/providers/openai-shared.ts +3500 -0
- package/src/providers/pi-native-client.ts +275 -0
- package/src/providers/pi-native-server.ts +245 -0
- package/src/providers/register-builtins.ts +503 -0
- package/src/providers/synthetic.ts +50 -0
- package/src/providers/transform-messages.ts +1083 -0
- package/src/providers/vision-guard.ts +54 -0
- package/src/registry/aiand.ts +22 -0
- package/src/registry/aimlapi.ts +6 -0
- package/src/registry/alibaba-coding-plan.ts +104 -0
- package/src/registry/alibaba-token-plan.ts +125 -0
- package/src/registry/amazon-bedrock.ts +22 -0
- package/src/registry/anthropic.ts +26 -0
- package/src/registry/api-key-login.ts +115 -0
- package/src/registry/api-key-validation.ts +145 -0
- package/src/registry/aws.ts +57 -0
- package/src/registry/azure.ts +6 -0
- package/src/registry/baseten.ts +22 -0
- package/src/registry/bedrock-mantle.ts +34 -0
- package/src/registry/cerebras.ts +23 -0
- package/src/registry/cloudflare-ai-gateway.ts +45 -0
- package/src/registry/coreweave.ts +40 -0
- package/src/registry/cursor.ts +20 -0
- package/src/registry/deepseek.ts +46 -0
- package/src/registry/derived.ts +9 -0
- package/src/registry/devin.ts +15 -0
- package/src/registry/exa.ts +19 -0
- package/src/registry/firepass.ts +32 -0
- package/src/registry/fireworks.ts +28 -0
- package/src/registry/github-copilot.ts +22 -0
- package/src/registry/gitlab-duo-workflow.ts +20 -0
- package/src/registry/gitlab-duo.ts +19 -0
- package/src/registry/gmi-cloud.ts +22 -0
- package/src/registry/google-antigravity.ts +22 -0
- package/src/registry/google-gemini-cli.ts +22 -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/registry/huggingface.ts +29 -0
- package/src/registry/index.ts +4 -0
- package/src/registry/kagi.ts +46 -0
- package/src/registry/kilo.ts +114 -0
- package/src/registry/kimi-code.ts +17 -0
- package/src/registry/litellm.ts +45 -0
- package/src/registry/llama-cpp.ts +35 -0
- package/src/registry/lm-studio.ts +31 -0
- package/src/registry/meta.ts +22 -0
- 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/registry/moonshot.ts +28 -0
- package/src/registry/nanogpt.ts +22 -0
- package/src/registry/novita.ts +25 -0
- package/src/registry/nvidia.ts +61 -0
- package/src/registry/oauth/anthropic-constants.ts +12 -0
- package/src/registry/oauth/anthropic.ts +346 -0
- package/src/registry/oauth/callback-server.ts +438 -0
- package/src/registry/oauth/cursor.ts +187 -0
- package/src/registry/oauth/device-code.ts +92 -0
- package/src/registry/oauth/devin.ts +124 -0
- package/src/registry/oauth/github-copilot.ts +369 -0
- package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
- package/src/registry/oauth/gitlab-duo.ts +222 -0
- package/src/registry/oauth/google-antigravity.ts +225 -0
- package/src/registry/oauth/google-gemini-cli.ts +297 -0
- package/src/registry/oauth/google-oauth-shared.ts +211 -0
- package/src/registry/oauth/index.ts +187 -0
- package/src/registry/oauth/kimi.ts +297 -0
- package/src/registry/oauth/minimax-code.ts +53 -0
- package/src/registry/oauth/oauth.html +317 -0
- package/src/registry/oauth/openai-codex.ts +384 -0
- package/src/registry/oauth/opencode.ts +50 -0
- package/src/registry/oauth/perplexity.ts +228 -0
- package/src/registry/oauth/pkce.ts +18 -0
- package/src/registry/oauth/types.ts +96 -0
- package/src/registry/oauth/wafer.ts +24 -0
- package/src/registry/oauth/xai-oauth.ts +559 -0
- package/src/registry/oauth/xiaomi.ts +211 -0
- package/src/registry/oauth/zai.ts +285 -0
- package/src/registry/ollama-cloud.ts +36 -0
- package/src/registry/ollama.ts +43 -0
- 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/registry/openrouter.ts +28 -0
- package/src/registry/parallel.ts +45 -0
- package/src/registry/perplexity.ts +13 -0
- package/src/registry/qianfan.ts +27 -0
- package/src/registry/qwen-portal.ts +50 -0
- package/src/registry/registry.ts +182 -0
- package/src/registry/sakana.ts +22 -0
- package/src/registry/siliconflow-cn.ts +22 -0
- package/src/registry/siliconflow.ts +22 -0
- package/src/registry/synthetic.ts +21 -0
- package/src/registry/tavily.ts +45 -0
- package/src/registry/together.ts +22 -0
- package/src/registry/types.ts +86 -0
- package/src/registry/umans.ts +23 -0
- package/src/registry/venice.ts +33 -0
- package/src/registry/vercel-ai-gateway.ts +38 -0
- package/src/registry/vllm.ts +34 -0
- package/src/registry/wafer-serverless.ts +12 -0
- package/src/registry/xai-oauth.ts +17 -0
- package/src/registry/xai.ts +22 -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/registry/zai.ts +41 -0
- package/src/registry/zenmux.ts +22 -0
- package/src/registry/zhipu-coding-plan.ts +27 -0
- package/src/stream.ts +1944 -0
- package/src/types.ts +1243 -0
- package/src/usage/alibaba-token-plan.ts +230 -0
- package/src/usage/claude.ts +830 -0
- package/src/usage/cursor.ts +335 -0
- package/src/usage/gemini.ts +258 -0
- package/src/usage/github-copilot.ts +424 -0
- package/src/usage/google-antigravity.ts +497 -0
- package/src/usage/kimi.ts +277 -0
- package/src/usage/minimax-code.ts +291 -0
- package/src/usage/ollama.ts +41 -0
- package/src/usage/openai-codex-base-url.ts +35 -0
- package/src/usage/openai-codex-reset.ts +205 -0
- package/src/usage/openai-codex.ts +627 -0
- package/src/usage/opencode-go.ts +89 -0
- package/src/usage/shared.ts +10 -0
- package/src/usage/synthetic.ts +180 -0
- package/src/usage/umans.ts +192 -0
- package/src/usage/xai-oauth.ts +414 -0
- package/src/usage/zai.ts +370 -0
- package/src/usage.ts +411 -0
- package/src/utils/abort.ts +67 -0
- package/src/utils/anthropic-auth.ts +93 -0
- package/src/utils/aws-profile.ts +88 -0
- package/src/utils/block-symbols.ts +78 -0
- package/src/utils/deterministic-id.ts +20 -0
- package/src/utils/empty-completion-retry.ts +161 -0
- package/src/utils/event-stream.ts +202 -0
- package/src/utils/foundry.ts +8 -0
- package/src/utils/google-validation.ts +25 -0
- package/src/utils/harmony-leak.ts +500 -0
- package/src/utils/http-inspector.ts +196 -0
- package/src/utils/idle-iterator.ts +531 -0
- package/src/utils/leaked-thinking-stream.ts +483 -0
- package/src/utils/openai-http.ts +119 -0
- package/src/utils/openrouter-headers.ts +12 -0
- package/src/utils/parse-bind.ts +56 -0
- package/src/utils/provider-response.ts +30 -0
- package/src/utils/proxy.ts +314 -0
- package/src/utils/request-debug.ts +351 -0
- package/src/utils/retry-after.ts +121 -0
- package/src/utils/retry.ts +77 -0
- package/src/utils/schema/CONSTRAINTS.md +168 -0
- package/src/utils/schema/adapt.ts +36 -0
- package/src/utils/schema/compatibility.ts +435 -0
- package/src/utils/schema/dereference.ts +98 -0
- package/src/utils/schema/draft.ts +341 -0
- package/src/utils/schema/equality.ts +97 -0
- package/src/utils/schema/fields.ts +210 -0
- package/src/utils/schema/index.ts +14 -0
- package/src/utils/schema/json-schema-validator.ts +595 -0
- package/src/utils/schema/meta-validator.ts +167 -0
- package/src/utils/schema/normalize.ts +2314 -0
- package/src/utils/schema/spill.ts +43 -0
- package/src/utils/schema/stamps.ts +109 -0
- package/src/utils/schema/strict-tool-validation.ts +117 -0
- package/src/utils/schema/types.ts +10 -0
- package/src/utils/schema/typescript.ts +212 -0
- package/src/utils/schema/wire.ts +662 -0
- package/src/utils/sdk-stream-timeout.ts +43 -0
- package/src/utils/sse-debug.ts +18 -0
- package/src/utils/stream-markup-healing.ts +247 -0
- package/src/utils/thinking-loop.ts +552 -0
- package/src/utils/tool-call-loop-guard.ts +107 -0
- package/src/utils/tool-choice.ts +101 -0
- package/src/utils/validation.ts +1932 -0
- package/src/utils.ts +492 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { Effort } from "@linxiraos/pi-catalog/effort";
|
|
2
|
+
import type {
|
|
3
|
+
AssistantMessage,
|
|
4
|
+
AssistantMessageEventStream,
|
|
5
|
+
CacheRetention,
|
|
6
|
+
Context,
|
|
7
|
+
OpenAIResponseInclude,
|
|
8
|
+
ServiceTier,
|
|
9
|
+
TokenTaskBudget,
|
|
10
|
+
} from "../types";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Wire types for the omp auth-gateway.
|
|
14
|
+
*
|
|
15
|
+
* The gateway sits between unauthenticated clients (containerized omp,
|
|
16
|
+
* llm-git, …) and the broker. It accepts provider-format HTTP requests
|
|
17
|
+
* (OpenAI chat-completions / Anthropic messages / OpenAI Responses),
|
|
18
|
+
* dispatches them through pi-ai's `streamSimple()`, and translates the
|
|
19
|
+
* canonical event stream back to the matching wire format. The gateway
|
|
20
|
+
* injects `Authorization` server-side so clients never see access tokens.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Default bind. Loopback-only — front with reverse proxy for remote access. */
|
|
24
|
+
export const DEFAULT_AUTH_GATEWAY_BIND = "127.0.0.1:4000";
|
|
25
|
+
|
|
26
|
+
export type AuthGatewayToolChoice = "auto" | "none" | "required" | { name: string } | { type: "computer" };
|
|
27
|
+
|
|
28
|
+
export interface AuthGatewayParsedRequestOptions {
|
|
29
|
+
// ── Sampling ──────────────────────────────────────────────────────────
|
|
30
|
+
maxOutputTokens?: number;
|
|
31
|
+
temperature?: number;
|
|
32
|
+
topP?: number;
|
|
33
|
+
topK?: number;
|
|
34
|
+
/** OpenAI nucleus-min sampling (`min_p`). */
|
|
35
|
+
minP?: number;
|
|
36
|
+
/** Anthropic `stop_sequences` / OpenAI `stop`. */
|
|
37
|
+
stopSequences?: string[];
|
|
38
|
+
/** OpenAI `presence_penalty`. */
|
|
39
|
+
presencePenalty?: number;
|
|
40
|
+
/** OpenAI `frequency_penalty`. */
|
|
41
|
+
frequencyPenalty?: number;
|
|
42
|
+
/** OpenRouter / vLLM `repetition_penalty`. */
|
|
43
|
+
repetitionPenalty?: number;
|
|
44
|
+
/** OpenAI deterministic-sampling `seed`. */
|
|
45
|
+
seed?: number;
|
|
46
|
+
/** OpenAI `logit_bias` map (token id → bias). */
|
|
47
|
+
logitBias?: Record<string, number>;
|
|
48
|
+
/** OpenAI `response_format` (text | json_object | json_schema). Opaque passthrough. */
|
|
49
|
+
responseFormat?: unknown;
|
|
50
|
+
|
|
51
|
+
// ── Tools ─────────────────────────────────────────────────────────────
|
|
52
|
+
toolChoice?: AuthGatewayToolChoice;
|
|
53
|
+
/** OpenAI `parallel_tool_calls`. */
|
|
54
|
+
parallelToolCalls?: boolean;
|
|
55
|
+
/** OpenAI Responses fields requested in the response payload. */
|
|
56
|
+
include?: OpenAIResponseInclude[];
|
|
57
|
+
// ── Reasoning ─────────────────────────────────────────────────────────
|
|
58
|
+
/** Effort-level reasoning request (OpenAI Responses / Chat `reasoning_effort`). */
|
|
59
|
+
reasoning?: Effort;
|
|
60
|
+
/** Force-disable reasoning (Anthropic `thinking: { type: "disabled" }`). */
|
|
61
|
+
disableReasoning?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Explicit Anthropic `thinking.budget_tokens`. Mirrors Rust's
|
|
64
|
+
* `resolve_thinking_budget`: pins onto whichever effort the client
|
|
65
|
+
* requested (defaulting to High when unspecified). Preferred over the
|
|
66
|
+
* removed legacy single-number `thinkingBudget` for new code.
|
|
67
|
+
*/
|
|
68
|
+
explicitThinkingBudgetTokens?: number;
|
|
69
|
+
/** Per-effort thinking budget map. */
|
|
70
|
+
thinkingBudgets?: Partial<Record<Effort, number>>;
|
|
71
|
+
/** Suppress the provider's reasoning summary stream. */
|
|
72
|
+
hideThinkingSummary?: boolean;
|
|
73
|
+
/** Anthropic `output_config.task_budget` advisory loop budget. */
|
|
74
|
+
taskBudget?: TokenTaskBudget;
|
|
75
|
+
|
|
76
|
+
// ── Service / routing ─────────────────────────────────────────────────
|
|
77
|
+
/** OpenAI service tier (auto|default|flex|scale|priority). */
|
|
78
|
+
serviceTier?: ServiceTier;
|
|
79
|
+
/** Cache retention hint derived from inbound `cache_control` markers. */
|
|
80
|
+
cacheRetention?: CacheRetention;
|
|
81
|
+
/** OpenAI Responses `prompt_cache_key`; also seeds provider routing when no separate session id exists. */
|
|
82
|
+
promptCacheKey?: string;
|
|
83
|
+
/** OpenAI Responses `previous_response_id` for response chaining. */
|
|
84
|
+
previousResponseId?: string;
|
|
85
|
+
/** OpenAI / abuse-tracking `user` field. */
|
|
86
|
+
user?: string;
|
|
87
|
+
|
|
88
|
+
// ── Passthrough ───────────────────────────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* Provider-specific metadata. Anthropic uses `metadata.user_id`; OpenRouter
|
|
91
|
+
* carries routing hints; xAI uses `search_parameters`; OpenAI accepts a
|
|
92
|
+
* free-form bag. The gateway forwards as-is.
|
|
93
|
+
*/
|
|
94
|
+
metadata?: Record<string, unknown>;
|
|
95
|
+
/**
|
|
96
|
+
* Captured allow-listed passthrough headers (anthropic-beta,
|
|
97
|
+
* anthropic-version, openai-organization, openai-project, openai-beta,
|
|
98
|
+
* x-stainless-*). Keys are lowercased.
|
|
99
|
+
*/
|
|
100
|
+
headers?: Record<string, string>;
|
|
101
|
+
/**
|
|
102
|
+
* Escape hatch for provider-specific request controls that don't yet have a
|
|
103
|
+
* first-class field. Prefer adding a typed field over widening this.
|
|
104
|
+
*/
|
|
105
|
+
extra?: Record<string, unknown>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface AuthGatewayParsedRequest {
|
|
109
|
+
modelId: string;
|
|
110
|
+
context: Context;
|
|
111
|
+
stream: boolean;
|
|
112
|
+
options: AuthGatewayParsedRequestOptions;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface AuthGatewayStreamControl {
|
|
116
|
+
/** Gateway request signal. Encoders stop producing frames when it aborts. */
|
|
117
|
+
signal?: AbortSignal;
|
|
118
|
+
/** Called when the HTTP response body is cancelled by the client. */
|
|
119
|
+
onCancel?: (reason?: unknown) => void;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface AuthGatewayFormatModule {
|
|
123
|
+
parseRequest(body: unknown, headers?: Headers): AuthGatewayParsedRequest;
|
|
124
|
+
encodeResponse(message: AssistantMessage, requestedModelId: string): Record<string, unknown>;
|
|
125
|
+
encodeStream(
|
|
126
|
+
events: AssistantMessageEventStream,
|
|
127
|
+
requestedModelId: string,
|
|
128
|
+
options?: AuthGatewayParsedRequestOptions,
|
|
129
|
+
control?: AuthGatewayStreamControl,
|
|
130
|
+
): ReadableStream<Uint8Array>;
|
|
131
|
+
/**
|
|
132
|
+
* Emit a protocol-specific error envelope. OpenAI returns
|
|
133
|
+
* `{ error: { message, type } }`; Anthropic returns
|
|
134
|
+
* `{ type: "error", error: { type, message } }`.
|
|
135
|
+
*/
|
|
136
|
+
formatError(status: number, type: string, message: string): Response;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface AuthGatewayServerOptions {
|
|
140
|
+
/** Listen address. Default `127.0.0.1:4000`. */
|
|
141
|
+
bind?: string;
|
|
142
|
+
/** Accept any of these bearer tokens. Empty allows unauthenticated calls. */
|
|
143
|
+
bearerTokens: string[];
|
|
144
|
+
/** Version surfaced on `/healthz`. */
|
|
145
|
+
version?: string;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface AuthGatewayServerHandle {
|
|
149
|
+
url: string;
|
|
150
|
+
port: number;
|
|
151
|
+
hostname: string;
|
|
152
|
+
close(): Promise<void>;
|
|
153
|
+
}
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import { extractHttpStatusFromError } from "@linxiraos/pi-utils";
|
|
2
|
+
import type { OAuthAccess } from "./auth-storage";
|
|
3
|
+
import * as AIError from "./error";
|
|
4
|
+
import { isAuthRetryableError, isInvalidatedOAuthTokenError } from "./error/auth-classify";
|
|
5
|
+
import { isUsageLimit } from "./error/flags";
|
|
6
|
+
import { isConcurrencyCapExclusion, isUsageLimitOutcome } from "./error/rate-limit";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Context passed to an {@link ApiKeyResolver} on each resolution attempt.
|
|
10
|
+
*
|
|
11
|
+
* The `error`/`lastChance` pair preserves the legacy a/b/c resolver contract
|
|
12
|
+
* shared by streaming ({@link streamSimple}) and non-streaming ({@link withAuth})
|
|
13
|
+
* drivers:
|
|
14
|
+
* - `error === undefined` → **initial resolve** (no force-refresh; cheap, may
|
|
15
|
+
* return a locally-cached not-yet-expired token).
|
|
16
|
+
* - `error !== undefined && !lastChance` → **step (b): refresh the SAME
|
|
17
|
+
* account** (force a token re-mint / await an in-flight broker refresh).
|
|
18
|
+
* - `error !== undefined && lastChance` → **step (c): switch account**
|
|
19
|
+
* (invalidate/usage-limit the current credential and rotate to a sibling).
|
|
20
|
+
*
|
|
21
|
+
* Current drivers preserve that bounded a/b/c sequence for ordinary 401/auth
|
|
22
|
+
* failures. 403/usage-limit failures skip refresh and may repeat step (c)
|
|
23
|
+
* until the resolver returns `undefined`, cycles, or hits
|
|
24
|
+
* {@link AUTH_RETRY_MAX_ATTEMPTS}.
|
|
25
|
+
*/
|
|
26
|
+
export interface ApiKeyResolveContext {
|
|
27
|
+
/** True when the resolver should rotate to a sibling credential. */
|
|
28
|
+
lastChance: boolean;
|
|
29
|
+
/** The auth error that triggered this re-resolution, or `undefined` on the initial resolve. */
|
|
30
|
+
error: unknown;
|
|
31
|
+
/** Bearer used by the failed attempt, when the caller can expose it. */
|
|
32
|
+
previousKey?: string;
|
|
33
|
+
/** Caller cancel signal, threaded into any credential refresh / rotation work. */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the API key to send for a request, retried through the a/b/c policy
|
|
39
|
+
* described on {@link ApiKeyResolveContext}.
|
|
40
|
+
*/
|
|
41
|
+
export type ApiKeyResolver = (ctx: ApiKeyResolveContext) => Promise<string | undefined> | string | undefined;
|
|
42
|
+
|
|
43
|
+
/** A static bearer string, or a {@link ApiKeyResolver} that mints/rotates one. */
|
|
44
|
+
export type ApiKey = string | ApiKeyResolver;
|
|
45
|
+
|
|
46
|
+
/** Narrows {@link ApiKey} to its resolver form. */
|
|
47
|
+
export function isApiKeyResolver(key: ApiKey | undefined): key is ApiKeyResolver {
|
|
48
|
+
return typeof key === "function";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Performs the initial resolve of an {@link ApiKey} (`error: undefined`,
|
|
53
|
+
* `lastChance: false`). Static keys pass through unchanged.
|
|
54
|
+
*/
|
|
55
|
+
export async function resolveApiKeyOnce(key: ApiKey | undefined, signal?: AbortSignal): Promise<string | undefined> {
|
|
56
|
+
if (key === undefined) return undefined;
|
|
57
|
+
if (isApiKeyResolver(key)) return (await key({ lastChance: false, error: undefined, signal })) || undefined;
|
|
58
|
+
return key;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Wraps a resolver with a bearer that was already selected for this request.
|
|
63
|
+
*
|
|
64
|
+
* Callers that preflight credentials can pass the returned resolver to the
|
|
65
|
+
* auth-retry driver without making the driver know about that preflight: the
|
|
66
|
+
* first initial resolution reuses `seed`, and all later resolutions delegate to
|
|
67
|
+
* `resolver`.
|
|
68
|
+
*/
|
|
69
|
+
export function seedApiKeyResolver(seed: string | undefined, resolver: ApiKeyResolver): ApiKeyResolver {
|
|
70
|
+
let seedPending = seed !== undefined;
|
|
71
|
+
return ctx => {
|
|
72
|
+
if (seedPending && ctx.error === undefined) {
|
|
73
|
+
seedPending = false;
|
|
74
|
+
return seed;
|
|
75
|
+
}
|
|
76
|
+
return resolver(ctx);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Re-exported from the error module (its new home); see error/auth-classify.ts.
|
|
81
|
+
export { isAuthRetryableError };
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Legacy bounded a/b/c retry sequence retained for public compatibility:
|
|
85
|
+
* `false` → refresh-same, `true` → rotate/switch. Current drivers consume it
|
|
86
|
+
* once for ordinary 401/auth failures; usage/account-limit failures may repeat
|
|
87
|
+
* sibling rotation until a termination guard fires.
|
|
88
|
+
*/
|
|
89
|
+
export const AUTH_RETRY_STEPS: readonly boolean[] = [false, true];
|
|
90
|
+
|
|
91
|
+
export const AUTH_RETRY_MAX_ATTEMPTS = 64;
|
|
92
|
+
|
|
93
|
+
function isDirectCredentialRotationError(error: unknown): boolean {
|
|
94
|
+
if (isUsageLimit(error) || isInvalidatedOAuthTokenError(error)) return true;
|
|
95
|
+
const status = AIError.status(error);
|
|
96
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : undefined;
|
|
97
|
+
// A 403 normally means a valid token lacks access, so rotate through
|
|
98
|
+
// siblings. A concurrency-cap 403 is transient instead; do not burn a
|
|
99
|
+
// sibling before the caller's backoff layer can retry it.
|
|
100
|
+
const isForbidden =
|
|
101
|
+
status === 403 ||
|
|
102
|
+
(status === undefined && message !== undefined && extractHttpStatusFromError({ message }) === 403);
|
|
103
|
+
if (isForbidden && !isConcurrencyCapExclusion(status, message)) return true;
|
|
104
|
+
return isUsageLimitOutcome(status, message);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Resolve a single retry step, swallowing resolver failures into `undefined`. */
|
|
108
|
+
export async function resolveRetryKey(
|
|
109
|
+
resolver: ApiKeyResolver,
|
|
110
|
+
lastChance: boolean,
|
|
111
|
+
error: unknown,
|
|
112
|
+
signal?: AbortSignal,
|
|
113
|
+
previousKey?: string,
|
|
114
|
+
): Promise<string | undefined> {
|
|
115
|
+
try {
|
|
116
|
+
const rotateSibling = lastChance || (!lastChance && isDirectCredentialRotationError(error));
|
|
117
|
+
return (await resolver({ lastChance: rotateSibling, error, signal, previousKey })) || undefined;
|
|
118
|
+
} catch {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface AuthRetryKeyState {
|
|
124
|
+
/** Bearer strings already sent during this logical operation. */
|
|
125
|
+
attemptedKeys: Set<string>;
|
|
126
|
+
/** Bearer used by the most recent failed attempt. */
|
|
127
|
+
lastKey: string;
|
|
128
|
+
/** Whether the current credential already consumed its 401 refresh-same retry. */
|
|
129
|
+
refreshedCurrent: boolean;
|
|
130
|
+
/** Whether the legacy non-usage auth path already switched to one sibling. */
|
|
131
|
+
legacyAuthSwitchUsed: boolean;
|
|
132
|
+
/** Total outbound attempts accepted for this logical operation, including the initial request. */
|
|
133
|
+
attempts: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function createAuthRetryKeyState(initialKey: string): AuthRetryKeyState {
|
|
137
|
+
return {
|
|
138
|
+
attemptedKeys: new Set([initialKey]),
|
|
139
|
+
lastKey: initialKey,
|
|
140
|
+
refreshedCurrent: false,
|
|
141
|
+
legacyAuthSwitchUsed: false,
|
|
142
|
+
attempts: 1,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function acceptRetryKey(state: AuthRetryKeyState, key: string, refreshedCurrent: boolean): string | undefined {
|
|
147
|
+
if (state.attemptedKeys.has(key) || state.attempts >= AUTH_RETRY_MAX_ATTEMPTS) return undefined;
|
|
148
|
+
state.attemptedKeys.add(key);
|
|
149
|
+
state.attempts += 1;
|
|
150
|
+
state.lastKey = key;
|
|
151
|
+
state.refreshedCurrent = refreshedCurrent;
|
|
152
|
+
return key;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export async function resolveNextAuthRetryKey(
|
|
156
|
+
state: AuthRetryKeyState,
|
|
157
|
+
resolver: ApiKeyResolver,
|
|
158
|
+
error: unknown,
|
|
159
|
+
signal?: AbortSignal,
|
|
160
|
+
): Promise<string | undefined> {
|
|
161
|
+
if (signal?.aborted) return undefined;
|
|
162
|
+
if (state.attempts >= AUTH_RETRY_MAX_ATTEMPTS) return undefined;
|
|
163
|
+
const directRotation = isDirectCredentialRotationError(error);
|
|
164
|
+
if (!directRotation) {
|
|
165
|
+
if (state.legacyAuthSwitchUsed) return undefined;
|
|
166
|
+
if (!state.refreshedCurrent) {
|
|
167
|
+
const refreshed = await resolveRetryKey(resolver, false, error, signal, state.lastKey);
|
|
168
|
+
state.refreshedCurrent = true;
|
|
169
|
+
if (signal?.aborted) return undefined;
|
|
170
|
+
if (refreshed !== undefined) {
|
|
171
|
+
const accepted = acceptRetryKey(state, refreshed, true);
|
|
172
|
+
if (accepted !== undefined) return accepted;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (signal?.aborted) return undefined;
|
|
178
|
+
const rotated = await resolveRetryKey(resolver, true, error, signal, state.lastKey);
|
|
179
|
+
if (signal?.aborted || rotated === undefined) return undefined;
|
|
180
|
+
const accepted = acceptRetryKey(state, rotated, !directRotation);
|
|
181
|
+
if (accepted !== undefined && !directRotation) state.legacyAuthSwitchUsed = true;
|
|
182
|
+
return accepted;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function oauthCredentialIdentity(access: OAuthAccess): string {
|
|
186
|
+
return access.credentialId !== undefined ? `credential:${access.credentialId}` : `bearer:${access.accessToken}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function runOAuthAttempt<T>(
|
|
190
|
+
access: OAuthAccess,
|
|
191
|
+
attempt: (access: OAuthAccess) => Promise<T>,
|
|
192
|
+
isAuthError: (error: unknown) => boolean,
|
|
193
|
+
): Promise<{ ok: true; result: T } | { ok: false; error: unknown }> {
|
|
194
|
+
try {
|
|
195
|
+
return { ok: true, result: await attempt(access) };
|
|
196
|
+
} catch (error) {
|
|
197
|
+
if (!isAuthError(error)) throw error;
|
|
198
|
+
return { ok: false, error };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Runs an auth-protected operation through the central a/b/c retry policy.
|
|
204
|
+
*
|
|
205
|
+
* - A static string key (or any non-resolver) → a single `attempt` with no
|
|
206
|
+
* retry (identical to the legacy static-key path).
|
|
207
|
+
* - A resolver → initial `attempt`, then resolver-driven retries until the
|
|
208
|
+
* applicable policy is exhausted, the resolver declines or cycles, or the
|
|
209
|
+
* operation reaches {@link AUTH_RETRY_MAX_ATTEMPTS}. Ordinary 401/auth
|
|
210
|
+
* failures retain one refresh-same plus one sibling switch; 403/usage-limit
|
|
211
|
+
* failures rotate directly through distinct siblings.
|
|
212
|
+
*
|
|
213
|
+
* Used by non-streaming consumers (image generation, web search, completion
|
|
214
|
+
* helpers). The streaming driver in `stream.ts` implements the same policy with
|
|
215
|
+
* its replay-safe buffering machinery.
|
|
216
|
+
*/
|
|
217
|
+
export async function withAuth<T>(
|
|
218
|
+
key: ApiKey | undefined,
|
|
219
|
+
attempt: (key: string) => Promise<T>,
|
|
220
|
+
opts?: { isAuthError?: (error: unknown) => boolean; signal?: AbortSignal; missingKeyMessage?: string },
|
|
221
|
+
): Promise<T> {
|
|
222
|
+
const isAuthError = opts?.isAuthError ?? isAuthRetryableError;
|
|
223
|
+
const missingKey = (): Error => new AIError.MissingApiKeyError(undefined, opts?.missingKeyMessage);
|
|
224
|
+
|
|
225
|
+
if (!isApiKeyResolver(key)) {
|
|
226
|
+
if (key === undefined) throw missingKey();
|
|
227
|
+
return attempt(key);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const resolver = key;
|
|
231
|
+
const signal = opts?.signal;
|
|
232
|
+
const initialKey = await resolveRetryKey(resolver, false, undefined, signal);
|
|
233
|
+
if (initialKey === undefined) throw missingKey();
|
|
234
|
+
|
|
235
|
+
const state = createAuthRetryKeyState(initialKey);
|
|
236
|
+
let lastError: unknown;
|
|
237
|
+
try {
|
|
238
|
+
return await attempt(initialKey);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (!isAuthError(error)) throw error;
|
|
241
|
+
lastError = error;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
while (true) {
|
|
245
|
+
const nextKey = await resolveNextAuthRetryKey(state, resolver, lastError, signal);
|
|
246
|
+
if (nextKey === undefined) break;
|
|
247
|
+
try {
|
|
248
|
+
return await attempt(nextKey);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (!isAuthError(error)) throw error;
|
|
251
|
+
lastError = error;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
throw lastError;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Minimal structural slice of `AuthStorage` consumed by {@link withOAuthAccess}.
|
|
260
|
+
* Typed structurally (and importing only the `OAuthAccess` type) so this module
|
|
261
|
+
* never takes a runtime dependency on `./auth-storage`.
|
|
262
|
+
*/
|
|
263
|
+
export interface OAuthAccessSource {
|
|
264
|
+
getOAuthAccess(
|
|
265
|
+
provider: string,
|
|
266
|
+
sessionId?: string,
|
|
267
|
+
options?: { forceRefresh?: boolean; signal?: AbortSignal },
|
|
268
|
+
): Promise<OAuthAccess | undefined>;
|
|
269
|
+
rotateSessionCredential(
|
|
270
|
+
provider: string,
|
|
271
|
+
sessionId: string | undefined,
|
|
272
|
+
options?: { error?: unknown; signal?: AbortSignal; apiKey?: string; credentialId?: number },
|
|
273
|
+
): Promise<boolean>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface WithOAuthAccessOptions {
|
|
277
|
+
/** Session id for credential stickiness, threaded into every resolve. */
|
|
278
|
+
sessionId?: string;
|
|
279
|
+
signal?: AbortSignal;
|
|
280
|
+
/** Override the retryable-error classifier (default {@link isAuthRetryableError}). */
|
|
281
|
+
isAuthError?: (error: unknown) => boolean;
|
|
282
|
+
/**
|
|
283
|
+
* Pre-resolved access used for the initial attempt. Callers that already
|
|
284
|
+
* resolved access for an availability gate pass it here so the helper
|
|
285
|
+
* doesn't double-resolve (mirrors the gateway resolver's `initialKey`).
|
|
286
|
+
*/
|
|
287
|
+
seed?: OAuthAccess;
|
|
288
|
+
missingAccessMessage?: string;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* {@link withAuth} for OAuth-access consumers: runs an auth-protected
|
|
293
|
+
* operation through the central a/b/c retry policy, handing the attempt the
|
|
294
|
+
* full {@link OAuthAccess} (bearer + identity metadata: `accountId`,
|
|
295
|
+
* `projectId`, `enterpriseUrl`) instead of bare API-key bytes.
|
|
296
|
+
*
|
|
297
|
+
* - initial → `getOAuthAccess` (or `opts.seed`).
|
|
298
|
+
* - 401/auth failure → one `getOAuthAccess` with `forceRefresh: true` for the
|
|
299
|
+
* current account, then sibling rotation.
|
|
300
|
+
* - 403/usage-limit failure → `rotateSessionCredential` directly, without a
|
|
301
|
+
* force-refresh detour.
|
|
302
|
+
*
|
|
303
|
+
* A refresh-same step may retry a new bearer for the same credential identity;
|
|
304
|
+
* sibling rotation stops when it yields a credential identity
|
|
305
|
+
* (`credentialId ?? accessToken`) or bearer already attempted in this turn.
|
|
306
|
+
* All OAuth attempts share the {@link AUTH_RETRY_MAX_ATTEMPTS} ceiling.
|
|
307
|
+
* Non-auth errors propagate immediately. Use this instead of hand-rolled
|
|
308
|
+
* `getOAuthAccess` + fetch flows so 401s and usage-limits rotate credentials
|
|
309
|
+
* instead of failing the call.
|
|
310
|
+
*/
|
|
311
|
+
export async function withOAuthAccess<T>(
|
|
312
|
+
storage: OAuthAccessSource,
|
|
313
|
+
provider: string,
|
|
314
|
+
attempt: (access: OAuthAccess) => Promise<T>,
|
|
315
|
+
opts?: WithOAuthAccessOptions,
|
|
316
|
+
): Promise<T> {
|
|
317
|
+
const isAuthError = opts?.isAuthError ?? isAuthRetryableError;
|
|
318
|
+
const { sessionId, signal } = opts ?? {};
|
|
319
|
+
|
|
320
|
+
let lastAccess = opts?.seed ?? (await storage.getOAuthAccess(provider, sessionId, { signal }));
|
|
321
|
+
if (!lastAccess) {
|
|
322
|
+
throw new AIError.MissingApiKeyError(
|
|
323
|
+
provider,
|
|
324
|
+
opts?.missingAccessMessage ?? `No OAuth credential available for provider: ${provider}`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const attemptedBearers = new Set([lastAccess.accessToken]);
|
|
329
|
+
const attemptedCredentialIdentities = new Set([oauthCredentialIdentity(lastAccess)]);
|
|
330
|
+
let attemptCount = 1;
|
|
331
|
+
let legacyAuthSwitchUsed = false;
|
|
332
|
+
let refreshedCurrent = false;
|
|
333
|
+
let attemptResult = await runOAuthAttempt(lastAccess, attempt, isAuthError);
|
|
334
|
+
if (attemptResult.ok) return attemptResult.result;
|
|
335
|
+
|
|
336
|
+
let lastError = attemptResult.error;
|
|
337
|
+
while (true) {
|
|
338
|
+
let next: OAuthAccess | undefined;
|
|
339
|
+
if (signal?.aborted || attemptCount >= AUTH_RETRY_MAX_ATTEMPTS) break;
|
|
340
|
+
const directRotation = isDirectCredentialRotationError(lastError);
|
|
341
|
+
if (!directRotation) {
|
|
342
|
+
if (legacyAuthSwitchUsed) break;
|
|
343
|
+
if (!refreshedCurrent) {
|
|
344
|
+
refreshedCurrent = true;
|
|
345
|
+
try {
|
|
346
|
+
next = await storage.getOAuthAccess(provider, sessionId, { forceRefresh: true, signal });
|
|
347
|
+
} catch {
|
|
348
|
+
next = undefined;
|
|
349
|
+
}
|
|
350
|
+
if (signal?.aborted) break;
|
|
351
|
+
if (next) {
|
|
352
|
+
const bearer = next.accessToken;
|
|
353
|
+
if (!attemptedBearers.has(bearer) && attemptCount < AUTH_RETRY_MAX_ATTEMPTS) {
|
|
354
|
+
attemptedCredentialIdentities.add(oauthCredentialIdentity(next));
|
|
355
|
+
attemptedBearers.add(bearer);
|
|
356
|
+
attemptCount += 1;
|
|
357
|
+
lastAccess = next;
|
|
358
|
+
attemptResult = await runOAuthAttempt(next, attempt, isAuthError);
|
|
359
|
+
if (attemptResult.ok) return attemptResult.result;
|
|
360
|
+
lastError = attemptResult.error;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (signal?.aborted || attemptCount >= AUTH_RETRY_MAX_ATTEMPTS) break;
|
|
368
|
+
try {
|
|
369
|
+
const rotated = await storage.rotateSessionCredential(provider, sessionId, {
|
|
370
|
+
error: lastError,
|
|
371
|
+
signal,
|
|
372
|
+
apiKey: lastAccess.accessToken,
|
|
373
|
+
credentialId: lastAccess.credentialId,
|
|
374
|
+
});
|
|
375
|
+
if (!rotated) break;
|
|
376
|
+
next = await storage.getOAuthAccess(provider, sessionId, { signal });
|
|
377
|
+
} catch {
|
|
378
|
+
next = undefined;
|
|
379
|
+
}
|
|
380
|
+
if (signal?.aborted || !next) break;
|
|
381
|
+
const credentialIdentity = oauthCredentialIdentity(next);
|
|
382
|
+
if (
|
|
383
|
+
attemptedCredentialIdentities.has(credentialIdentity) ||
|
|
384
|
+
attemptedBearers.has(next.accessToken) ||
|
|
385
|
+
attemptCount >= AUTH_RETRY_MAX_ATTEMPTS
|
|
386
|
+
) {
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
attemptedCredentialIdentities.add(credentialIdentity);
|
|
390
|
+
attemptedBearers.add(next.accessToken);
|
|
391
|
+
attemptCount += 1;
|
|
392
|
+
lastAccess = next;
|
|
393
|
+
refreshedCurrent = !directRotation;
|
|
394
|
+
if (!directRotation) legacyAuthSwitchUsed = true;
|
|
395
|
+
attemptResult = await runOAuthAttempt(next, attempt, isAuthError);
|
|
396
|
+
if (attemptResult.ok) return attemptResult.result;
|
|
397
|
+
lastError = attemptResult.error;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
throw lastError;
|
|
401
|
+
}
|