@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
package/src/usage.ts
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage reporting types for provider quota/limit endpoints.
|
|
3
|
+
*
|
|
4
|
+
* Provides a normalized schema to represent multiple limit windows, model tiers,
|
|
5
|
+
* and shared quotas across providers.
|
|
6
|
+
*/
|
|
7
|
+
import { type } from "@linxiraos/pi-omptype";
|
|
8
|
+
import type { FetchImpl, Provider } from "./types";
|
|
9
|
+
export type UsageUnit = "percent" | "tokens" | "requests" | "usd" | "minutes" | "bytes" | "unknown";
|
|
10
|
+
|
|
11
|
+
export type UsageStatus = "ok" | "warning" | "exhausted" | "unknown";
|
|
12
|
+
|
|
13
|
+
/** Time window for a limit (e.g. 5h, 7d, monthly). */
|
|
14
|
+
export interface UsageWindow {
|
|
15
|
+
/** Stable identifier (e.g. "5h", "7d", "monthly"). */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Human label (e.g. "5 Hour", "7 Day"). */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Window duration in milliseconds, when known. */
|
|
20
|
+
durationMs?: number;
|
|
21
|
+
/** Absolute reset timestamp in milliseconds since epoch. */
|
|
22
|
+
resetsAt?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Verb rendered before the {@link resetsAt} countdown (e.g. "tick", "regen").
|
|
25
|
+
* Defaults to "resets" — override for rolling windows where the timestamp is
|
|
26
|
+
* an incremental regeneration step rather than a full window reset.
|
|
27
|
+
*/
|
|
28
|
+
resetLabel?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Quantitative usage data. */
|
|
32
|
+
export interface UsageAmount {
|
|
33
|
+
/** Amount used in the given unit. */
|
|
34
|
+
used?: number;
|
|
35
|
+
/** Maximum limit in the given unit. */
|
|
36
|
+
limit?: number;
|
|
37
|
+
/** Remaining amount in the given unit. */
|
|
38
|
+
remaining?: number;
|
|
39
|
+
/** Fraction used (0..1). */
|
|
40
|
+
usedFraction?: number;
|
|
41
|
+
/** Fraction remaining (0..1). */
|
|
42
|
+
remainingFraction?: number;
|
|
43
|
+
/** Unit for the amounts (percent, tokens, etc.). */
|
|
44
|
+
unit: UsageUnit;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Scope metadata describing what the limit applies to. */
|
|
48
|
+
export interface UsageScope {
|
|
49
|
+
provider: Provider;
|
|
50
|
+
accountId?: string;
|
|
51
|
+
projectId?: string;
|
|
52
|
+
orgId?: string;
|
|
53
|
+
modelId?: string;
|
|
54
|
+
tier?: string;
|
|
55
|
+
windowId?: string;
|
|
56
|
+
shared?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Normalized limit entry for a single window or quota bucket. */
|
|
60
|
+
export interface UsageLimit {
|
|
61
|
+
/** Stable identifier for this limit entry. */
|
|
62
|
+
id: string;
|
|
63
|
+
/** Human label for display. */
|
|
64
|
+
label: string;
|
|
65
|
+
scope: UsageScope;
|
|
66
|
+
window?: UsageWindow;
|
|
67
|
+
amount: UsageAmount;
|
|
68
|
+
status?: UsageStatus;
|
|
69
|
+
notes?: string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Per-credit detail for a saved/banked rate-limit reset.
|
|
74
|
+
*
|
|
75
|
+
* Populated when the provider's listing endpoint returns individual credit
|
|
76
|
+
* metadata (e.g. OpenAI Codex `wham/rate-limit-reset-credits`). Callers that
|
|
77
|
+
* only need the count can ignore this; display layers use `expiresAt` to show
|
|
78
|
+
* when banked resets expire ([#3339](https://github.com/can1357/oh-my-pi/issues/3339)).
|
|
79
|
+
*/
|
|
80
|
+
export interface UsageResetCreditDetail {
|
|
81
|
+
/** ISO timestamp when the credit was granted. */
|
|
82
|
+
grantedAt?: string;
|
|
83
|
+
/** ISO timestamp when the credit expires and can no longer be redeemed. */
|
|
84
|
+
expiresAt?: string;
|
|
85
|
+
/** Backend status, e.g. `available`, `redeemed`. */
|
|
86
|
+
status?: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Saved/banked rate-limit resets an account can redeem on demand.
|
|
91
|
+
*
|
|
92
|
+
* Surfaced by providers that let users defer a usage-window reset and spend it
|
|
93
|
+
* later (OpenAI Codex "saved rate limit resets"). The redeem itself is a
|
|
94
|
+
* separate, provider-specific action; this is the read-only count for display.
|
|
95
|
+
*/
|
|
96
|
+
export interface UsageResetCredits {
|
|
97
|
+
/** Number of resets available to redeem right now. */
|
|
98
|
+
availableCount: number;
|
|
99
|
+
/** Individual credit details (expiry dates, etc.) when the provider exposes them. */
|
|
100
|
+
credits?: UsageResetCreditDetail[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Aggregated usage report for a provider. */
|
|
104
|
+
export interface UsageReport {
|
|
105
|
+
provider: Provider;
|
|
106
|
+
fetchedAt: number;
|
|
107
|
+
limits: UsageLimit[];
|
|
108
|
+
/** Saved rate-limit resets the account can redeem, when the provider reports them. */
|
|
109
|
+
resetCredits?: UsageResetCredits;
|
|
110
|
+
/**
|
|
111
|
+
* Provider-wide disclaimers shown once above per-account sections.
|
|
112
|
+
* Use this for caveats that apply to every limit (e.g. "OMP-observed
|
|
113
|
+
* spend only"). Per-limit notes that differ per window (e.g. "Overage
|
|
114
|
+
* requests: N") stay on {@link UsageLimit.notes}.
|
|
115
|
+
*/
|
|
116
|
+
notes?: string[];
|
|
117
|
+
metadata?: Record<string, unknown>;
|
|
118
|
+
raw?: unknown;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Resolve a limit's used fraction (0..1; >1 means overage) from whichever
|
|
123
|
+
* amount fields the provider populated. Precedence mirrors the usage UIs:
|
|
124
|
+
* explicit fraction > used/limit > percent-unit used > inverted remaining.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveUsedFraction(limit: UsageLimit): number | undefined {
|
|
127
|
+
const amount = limit.amount;
|
|
128
|
+
if (amount.usedFraction !== undefined) return amount.usedFraction;
|
|
129
|
+
if (amount.used !== undefined && amount.limit !== undefined && amount.limit > 0) {
|
|
130
|
+
return amount.used / amount.limit;
|
|
131
|
+
}
|
|
132
|
+
if (amount.unit === "percent" && amount.used !== undefined) return amount.used / 100;
|
|
133
|
+
if (amount.remainingFraction !== undefined) return Math.max(0, 1 - amount.remainingFraction);
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* One recorded usage-limit snapshot: a single limit window of one account at
|
|
139
|
+
* a point in time. The usage cache itself is latest-snapshot-only; history
|
|
140
|
+
* rows are appended by the auth storage layer whenever a fresh report is
|
|
141
|
+
* fetched, so limit utilization stays inspectable over time.
|
|
142
|
+
*/
|
|
143
|
+
export interface UsageHistoryEntry {
|
|
144
|
+
/** Epoch ms the report was fetched. */
|
|
145
|
+
recordedAt: number;
|
|
146
|
+
provider: Provider;
|
|
147
|
+
/** Stable credential identity key (account/email/project derived). */
|
|
148
|
+
accountKey: string;
|
|
149
|
+
email?: string;
|
|
150
|
+
accountId?: string;
|
|
151
|
+
/** {@link UsageLimit.id} of the recorded window. */
|
|
152
|
+
limitId: string;
|
|
153
|
+
/** Human label of the limit. */
|
|
154
|
+
label: string;
|
|
155
|
+
windowLabel?: string;
|
|
156
|
+
/** Used fraction (0..1) when resolvable. */
|
|
157
|
+
usedFraction?: number;
|
|
158
|
+
status?: UsageStatus;
|
|
159
|
+
/** Epoch ms the window resets, when known. */
|
|
160
|
+
resetsAt?: number;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Filter for reading recorded usage history. */
|
|
164
|
+
export interface UsageHistoryQuery {
|
|
165
|
+
provider?: string;
|
|
166
|
+
/** Inclusive lower bound on {@link UsageHistoryEntry.recordedAt} (epoch ms). */
|
|
167
|
+
sinceMs?: number;
|
|
168
|
+
}
|
|
169
|
+
/** One observed provider request cost, attributed to the credential that made it. */
|
|
170
|
+
export interface UsageCostHistoryEntry {
|
|
171
|
+
/** Epoch ms the request completed. */
|
|
172
|
+
recordedAt: number;
|
|
173
|
+
provider: Provider;
|
|
174
|
+
/** Stable credential identity key (account/email/project/secret derived). */
|
|
175
|
+
accountKey: string;
|
|
176
|
+
/** Estimated request cost in USD. */
|
|
177
|
+
costUsd: number;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Filter for reading observed request costs. */
|
|
181
|
+
export interface UsageCostHistoryQuery {
|
|
182
|
+
provider?: string;
|
|
183
|
+
accountKey?: string;
|
|
184
|
+
/** Inclusive lower bound on {@link UsageCostHistoryEntry.recordedAt} (epoch ms). */
|
|
185
|
+
sinceMs?: number;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Aggregated request usage a client observed for one (provider, model) pair.
|
|
190
|
+
* Clients fold every completed request into per-pair buckets and flush them to
|
|
191
|
+
* the auth broker on a short cadence, so the broker can attribute token burn
|
|
192
|
+
* to the install that produced it.
|
|
193
|
+
*/
|
|
194
|
+
export interface ObservedUsageEntry {
|
|
195
|
+
/** Epoch ms of the newest request folded into this bucket. */
|
|
196
|
+
at: number;
|
|
197
|
+
provider: Provider;
|
|
198
|
+
model: string;
|
|
199
|
+
/** Completed requests folded into this bucket. */
|
|
200
|
+
requests: number;
|
|
201
|
+
inputTokens: number;
|
|
202
|
+
outputTokens: number;
|
|
203
|
+
cacheReadTokens: number;
|
|
204
|
+
cacheWriteTokens: number;
|
|
205
|
+
/** Estimated USD cost of the folded requests (0 when unknown). */
|
|
206
|
+
costUsd: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** One client's observed-usage report, keyed by its stable install id. */
|
|
210
|
+
export interface ClientUsageReport {
|
|
211
|
+
/** Stable per-machine install id — the client primary key. */
|
|
212
|
+
installId: string;
|
|
213
|
+
/** Human-readable machine name for display surfaces. */
|
|
214
|
+
hostname?: string;
|
|
215
|
+
entries: ObservedUsageEntry[];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Per-provider aggregate of one client's recorded usage. */
|
|
219
|
+
export interface ClientProviderUsage {
|
|
220
|
+
provider: string;
|
|
221
|
+
requests: number;
|
|
222
|
+
inputTokens: number;
|
|
223
|
+
outputTokens: number;
|
|
224
|
+
cacheReadTokens: number;
|
|
225
|
+
cacheWriteTokens: number;
|
|
226
|
+
costUsd: number;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** One known client with its usage aggregates over the queried window. */
|
|
230
|
+
export interface ClientUsageClientSummary {
|
|
231
|
+
installId: string;
|
|
232
|
+
hostname?: string;
|
|
233
|
+
firstSeen: number;
|
|
234
|
+
lastSeen: number;
|
|
235
|
+
providers: ClientProviderUsage[];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Aggregated per-client usage recorded by the broker host. */
|
|
239
|
+
export interface ClientUsageSummary {
|
|
240
|
+
clients: ClientUsageClientSummary[];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ─── Zod schemas (wire-shape validation for the broker `/v1/usage` endpoint) ─
|
|
244
|
+
|
|
245
|
+
export const usageUnitSchema = type("'percent' | 'tokens' | 'requests' | 'usd' | 'minutes' | 'bytes' | 'unknown'");
|
|
246
|
+
export const usageStatusSchema = type("'ok' | 'warning' | 'exhausted' | 'unknown'");
|
|
247
|
+
|
|
248
|
+
export const usageWindowSchema = type({
|
|
249
|
+
id: "string",
|
|
250
|
+
label: "string",
|
|
251
|
+
"durationMs?": "number",
|
|
252
|
+
"resetsAt?": "number",
|
|
253
|
+
"resetLabel?": "string",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
export const usageAmountSchema = type({
|
|
257
|
+
"used?": "number",
|
|
258
|
+
"limit?": "number",
|
|
259
|
+
"remaining?": "number",
|
|
260
|
+
"usedFraction?": "number",
|
|
261
|
+
"remainingFraction?": "number",
|
|
262
|
+
unit: usageUnitSchema,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
export const usageScopeSchema = type({
|
|
266
|
+
provider: "string",
|
|
267
|
+
"accountId?": "string",
|
|
268
|
+
"projectId?": "string",
|
|
269
|
+
"orgId?": "string",
|
|
270
|
+
"modelId?": "string",
|
|
271
|
+
"tier?": "string",
|
|
272
|
+
"windowId?": "string",
|
|
273
|
+
"shared?": "boolean",
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
export const usageLimitSchema = type({
|
|
277
|
+
id: "string",
|
|
278
|
+
label: "string",
|
|
279
|
+
scope: usageScopeSchema,
|
|
280
|
+
"window?": usageWindowSchema,
|
|
281
|
+
amount: usageAmountSchema,
|
|
282
|
+
"status?": usageStatusSchema,
|
|
283
|
+
"notes?": "string[]",
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
export const usageResetCreditDetailSchema = type({
|
|
287
|
+
"grantedAt?": "string",
|
|
288
|
+
"expiresAt?": "string",
|
|
289
|
+
"status?": "string",
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
export const usageResetCreditsSchema = type({
|
|
293
|
+
availableCount: "number",
|
|
294
|
+
"credits?": usageResetCreditDetailSchema.array(),
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
export const usageReportSchema = type({
|
|
298
|
+
provider: "string",
|
|
299
|
+
fetchedAt: "number",
|
|
300
|
+
limits: usageLimitSchema.array(),
|
|
301
|
+
"resetCredits?": usageResetCreditsSchema,
|
|
302
|
+
"notes?": "string[]",
|
|
303
|
+
"metadata?": { "[string]": "unknown" },
|
|
304
|
+
// `raw` is provider-specific and may be anything; the broker strips it before
|
|
305
|
+
// sending the report over the wire, so accept-but-ignore here.
|
|
306
|
+
"raw?": "unknown",
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
/** Optional logger for usage fetchers. */
|
|
310
|
+
export interface UsageLogger {
|
|
311
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
312
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Credential bundle for usage endpoints. */
|
|
316
|
+
export interface UsageCredential {
|
|
317
|
+
type: "api_key" | "oauth";
|
|
318
|
+
apiKey?: string;
|
|
319
|
+
accessToken?: string;
|
|
320
|
+
refreshToken?: string;
|
|
321
|
+
expiresAt?: number;
|
|
322
|
+
accountId?: string;
|
|
323
|
+
projectId?: string;
|
|
324
|
+
email?: string;
|
|
325
|
+
/** Organization/workspace the credential is scoped to (see OAuthCredentials.orgId). */
|
|
326
|
+
orgId?: string;
|
|
327
|
+
/** Human-readable organization name for display. */
|
|
328
|
+
orgName?: string;
|
|
329
|
+
enterpriseUrl?: string;
|
|
330
|
+
metadata?: Record<string, unknown>;
|
|
331
|
+
apiEndpoint?: string;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** Parameters provided to a usage fetcher. */
|
|
335
|
+
export interface UsageFetchParams {
|
|
336
|
+
provider: Provider;
|
|
337
|
+
credential: UsageCredential;
|
|
338
|
+
/** Stable credential identity key derived by the auth storage layer. */
|
|
339
|
+
accountKey?: string;
|
|
340
|
+
baseUrl?: string;
|
|
341
|
+
signal?: AbortSignal;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Shared runtime utilities for fetchers. */
|
|
345
|
+
export interface UsageFetchContext {
|
|
346
|
+
fetch: FetchImpl;
|
|
347
|
+
logger?: UsageLogger;
|
|
348
|
+
retryWait?: (delayMs: number, signal?: AbortSignal) => Promise<void>;
|
|
349
|
+
/** Observed request-cost history for providers without upstream usage APIs. */
|
|
350
|
+
listUsageCosts?: (query?: UsageCostHistoryQuery) => UsageCostHistoryEntry[];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Provider implementation for fetching usage information. */
|
|
354
|
+
export interface UsageProvider {
|
|
355
|
+
id: Provider;
|
|
356
|
+
fetchUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null>;
|
|
357
|
+
/** Parse provider rate-limit response headers (lowercased keys) into a usage report, if supported. */
|
|
358
|
+
parseRateLimitHeaders?(headers: Record<string, string>, now?: number): UsageReport | null;
|
|
359
|
+
supports?(params: UsageFetchParams): boolean;
|
|
360
|
+
/** True when fetchUsage contacts upstream and can authenticate the credential for health checks. */
|
|
361
|
+
validatesCredentials?: boolean;
|
|
362
|
+
/** Whether a failed refresh may serve the previous successful report. Defaults to true. */
|
|
363
|
+
retainLastGoodOnFailure?: boolean;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** Request context used when ranking usage for a specific model. */
|
|
367
|
+
export interface CredentialRankingContext {
|
|
368
|
+
/** Provider model id, when the caller is selecting a credential for one model. */
|
|
369
|
+
modelId?: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** Strategy for usage-based credential ranking. Providers implement this to opt into smart credential selection. */
|
|
373
|
+
export interface CredentialRankingStrategy {
|
|
374
|
+
/** Extract the primary (short) and secondary (long) window limits from a usage report. */
|
|
375
|
+
findWindowLimits(
|
|
376
|
+
report: UsageReport,
|
|
377
|
+
context?: CredentialRankingContext,
|
|
378
|
+
): {
|
|
379
|
+
primary?: UsageLimit;
|
|
380
|
+
secondary?: UsageLimit;
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Restrict limits to the ones relevant for the requested model before
|
|
384
|
+
* credential-wide exhaustion checks and ranking. Providers with shared
|
|
385
|
+
* account-wide quotas can omit this and use all limits.
|
|
386
|
+
*/
|
|
387
|
+
scopeLimits?(report: UsageReport, context?: CredentialRankingContext): UsageLimit[];
|
|
388
|
+
/**
|
|
389
|
+
* Return a provider-local backoff scope for the requested model. Providers
|
|
390
|
+
* with backend-specific quotas use this so one exhausted model family does
|
|
391
|
+
* not block unrelated families on the same OAuth credential.
|
|
392
|
+
*/
|
|
393
|
+
blockScope?(context?: CredentialRankingContext): string | undefined;
|
|
394
|
+
/**
|
|
395
|
+
* Scopes that apply to a request, most specific first. With a context, the
|
|
396
|
+
* request's own scope plus any legacy catch-all scope whose blocks still
|
|
397
|
+
* apply to everything. Without one — reconciliation runs with no request —
|
|
398
|
+
* every scope whose blocks must be healed.
|
|
399
|
+
*
|
|
400
|
+
* A provider that scopes backoff by model family must implement this, or a
|
|
401
|
+
* block written under one scope is invisible to requests and to healing.
|
|
402
|
+
*/
|
|
403
|
+
blockScopes?(context?: CredentialRankingContext): string[];
|
|
404
|
+
/** Fallback window durations (ms) when limits don't specify durationMs. */
|
|
405
|
+
windowDefaults: {
|
|
406
|
+
primaryMs: number;
|
|
407
|
+
secondaryMs: number;
|
|
408
|
+
};
|
|
409
|
+
/** Optional: priority boost for specific credential states (e.g., fresh 5h ticker start). */
|
|
410
|
+
hasPriorityBoost?(primary: UsageLimit | undefined): boolean;
|
|
411
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as AIError from "../error";
|
|
2
|
+
|
|
3
|
+
export interface AbortSourceTracker {
|
|
4
|
+
requestAbortController: AbortController;
|
|
5
|
+
requestSignal: AbortSignal;
|
|
6
|
+
abortLocally(reason: Error): Error;
|
|
7
|
+
getLocalAbortReason(): Error | undefined;
|
|
8
|
+
wasCallerAbort(): boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tracks whether a merged request signal was aborted by the caller or by provider-local logic.
|
|
13
|
+
*
|
|
14
|
+
* Caller aborts always take priority. When both the caller and a local watchdog fire near
|
|
15
|
+
* each other, the merged `requestSignal.reason` reflects whichever AbortController called
|
|
16
|
+
* `.abort()` first — but ordering is racy and not meaningful for upstream consumers. What
|
|
17
|
+
* matters is intent: if the caller's signal aborted, the request was cancelled by the
|
|
18
|
+
* caller, and any local watchdog reason is incidental and **MUST NOT** be surfaced as a
|
|
19
|
+
* retryable transient error (which would cause auto-retry to re-enter streaming and leave
|
|
20
|
+
* the UI showing a spinner the user already tried to cancel).
|
|
21
|
+
*/
|
|
22
|
+
export function createAbortSourceTracker(callerSignal?: AbortSignal): AbortSourceTracker {
|
|
23
|
+
const requestAbortController = new AbortController();
|
|
24
|
+
const requestSignal = callerSignal
|
|
25
|
+
? AbortSignal.any([callerSignal, requestAbortController.signal])
|
|
26
|
+
: requestAbortController.signal;
|
|
27
|
+
let localAbortReason: Error | undefined;
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
requestAbortController,
|
|
31
|
+
requestSignal,
|
|
32
|
+
abortLocally(reason) {
|
|
33
|
+
localAbortReason = reason;
|
|
34
|
+
requestAbortController.abort(reason);
|
|
35
|
+
return reason;
|
|
36
|
+
},
|
|
37
|
+
getLocalAbortReason() {
|
|
38
|
+
// Caller intent dominates. Surface a local reason only when the caller did not
|
|
39
|
+
// abort, so timeout/idle-watchdog errors don't masquerade as the user's cancel.
|
|
40
|
+
if (!localAbortReason || callerSignal?.aborted) return undefined;
|
|
41
|
+
return requestSignal.reason === localAbortReason ? localAbortReason : undefined;
|
|
42
|
+
},
|
|
43
|
+
wasCallerAbort() {
|
|
44
|
+
// If the caller signal aborted, treat it as a caller abort regardless of which
|
|
45
|
+
// AbortController won the race to set `requestSignal.reason`. The previous
|
|
46
|
+
// `requestSignal.reason !== localAbortReason` heuristic flipped the result to
|
|
47
|
+
// `false` when a local watchdog fired microseconds before the user's ESC, which
|
|
48
|
+
// then routed user-initiated cancels through the auto-retry transient-error
|
|
49
|
+
// path.
|
|
50
|
+
return callerSignal?.aborted === true;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Race a shared promise against a caller's AbortSignal without coupling the
|
|
57
|
+
* underlying work to that signal. The shared promise keeps running (and caches
|
|
58
|
+
* its result) even when an individual caller bails out.
|
|
59
|
+
*/
|
|
60
|
+
export function raceWithSignal<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {
|
|
61
|
+
if (!signal) return promise;
|
|
62
|
+
if (signal.aborted) return Promise.reject(signal.reason ?? new AIError.AbortError());
|
|
63
|
+
const { promise: aborted, reject } = Promise.withResolvers<never>();
|
|
64
|
+
const onAbort = () => reject(signal.reason ?? new AIError.AbortError());
|
|
65
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
66
|
+
return Promise.race([promise, aborted]).finally(() => signal.removeEventListener("abort", onAbort));
|
|
67
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Authentication
|
|
3
|
+
*
|
|
4
|
+
* Thin helper for turning an already-resolved API key into the request-shaping
|
|
5
|
+
* config consumed by {@link buildAnthropicSearchHeaders} / {@link buildAnthropicUrl}.
|
|
6
|
+
*
|
|
7
|
+
* Credential storage and refresh live in `AuthStorage` — call
|
|
8
|
+
* `authStorage.getApiKey("anthropic", sessionId)` first, then pass the result
|
|
9
|
+
* through {@link buildAnthropicAuthConfig} for header/URL shaping.
|
|
10
|
+
*/
|
|
11
|
+
import { $env } from "@linxiraos/pi-utils";
|
|
12
|
+
import {
|
|
13
|
+
buildAnthropicHeaders as buildProviderAnthropicHeaders,
|
|
14
|
+
normalizeAnthropicBaseUrl,
|
|
15
|
+
resolveAnthropicCustomHeadersForBaseUrl,
|
|
16
|
+
} from "../providers/anthropic";
|
|
17
|
+
import { isFoundryEnabled } from "./foundry";
|
|
18
|
+
|
|
19
|
+
/** Auth configuration for Anthropic */
|
|
20
|
+
export interface AnthropicAuthConfig {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
isOAuth: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const DEFAULT_BASE_URL = "https://api.anthropic.com";
|
|
27
|
+
|
|
28
|
+
function normalizeBaseUrl(baseUrl: string | undefined): string | undefined {
|
|
29
|
+
const trimmed = baseUrl?.trim();
|
|
30
|
+
return trimmed ? trimmed.replace(/\/+$/, "") : undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function resolveAnthropicBaseUrlFromEnv(): string | undefined {
|
|
34
|
+
if (isFoundryEnabled()) {
|
|
35
|
+
const foundryBaseUrl = normalizeBaseUrl($env.FOUNDRY_BASE_URL);
|
|
36
|
+
if (foundryBaseUrl) return foundryBaseUrl;
|
|
37
|
+
}
|
|
38
|
+
const anthropicBaseUrl = normalizeBaseUrl($env.ANTHROPIC_BASE_URL);
|
|
39
|
+
return anthropicBaseUrl || undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Checks if a token is an OAuth token by looking for sk-ant-oat prefix.
|
|
44
|
+
*/
|
|
45
|
+
export function isOAuthToken(apiKey: string): boolean {
|
|
46
|
+
return apiKey.includes("sk-ant-oat");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Build an {@link AnthropicAuthConfig} from an already-resolved API key.
|
|
51
|
+
*
|
|
52
|
+
* `apiKey` is whatever the caller chose for `Authorization`/`x-api-key` —
|
|
53
|
+
* usually `authStorage.getApiKey("anthropic")`. `baseUrl` overrides the
|
|
54
|
+
* env-derived base; pass `undefined` to fall back to FOUNDRY/ANTHROPIC env
|
|
55
|
+
* resolution and finally `DEFAULT_BASE_URL`.
|
|
56
|
+
*
|
|
57
|
+
* `isOAuth` is derived from the token prefix so the helper stays pure: callers
|
|
58
|
+
* never have to thread the OAuth flag through their own resolution logic.
|
|
59
|
+
*/
|
|
60
|
+
export function buildAnthropicAuthConfig(apiKey: string, baseUrl?: string): AnthropicAuthConfig {
|
|
61
|
+
return {
|
|
62
|
+
apiKey,
|
|
63
|
+
baseUrl: normalizeBaseUrl(baseUrl) ?? resolveAnthropicBaseUrlFromEnv() ?? DEFAULT_BASE_URL,
|
|
64
|
+
isOAuth: isOAuthToken(apiKey),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Builds HTTP headers for Anthropic API requests (search variant).
|
|
70
|
+
*
|
|
71
|
+
* Forwards `ANTHROPIC_CUSTOM_HEADERS` when the resolver deems them applicable
|
|
72
|
+
* (Foundry mode, or a non-Anthropic base URL — typically an enterprise
|
|
73
|
+
* gateway), matching the streaming path so web search behaves identically.
|
|
74
|
+
*/
|
|
75
|
+
export function buildAnthropicSearchHeaders(auth: AnthropicAuthConfig): Record<string, string> {
|
|
76
|
+
return buildProviderAnthropicHeaders({
|
|
77
|
+
apiKey: auth.apiKey,
|
|
78
|
+
baseUrl: auth.baseUrl,
|
|
79
|
+
isOAuth: auth.isOAuth,
|
|
80
|
+
extraBetas: ["web-search-2025-03-05"],
|
|
81
|
+
stream: false,
|
|
82
|
+
modelHeaders: resolveAnthropicCustomHeadersForBaseUrl(auth.baseUrl),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Builds the full API URL for Anthropic messages endpoint.
|
|
88
|
+
*/
|
|
89
|
+
export function buildAnthropicUrl(auth: AnthropicAuthConfig): string {
|
|
90
|
+
const normalizedBaseUrl = normalizeAnthropicBaseUrl(auth.baseUrl);
|
|
91
|
+
const base = `${normalizedBaseUrl}/v1/messages`;
|
|
92
|
+
return `${base}?beta=true`;
|
|
93
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { $env } from "@linxiraos/pi-utils";
|
|
5
|
+
|
|
6
|
+
/** INI sections with `profile ` / `sso-session ` prefixes normalized. */
|
|
7
|
+
export type AwsIniFile = Record<string, Record<string, string>>;
|
|
8
|
+
|
|
9
|
+
export function parseAwsIni(text: string): AwsIniFile {
|
|
10
|
+
const out: AwsIniFile = {};
|
|
11
|
+
let current: Record<string, string> | null = null;
|
|
12
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
13
|
+
const line = rawLine.trim();
|
|
14
|
+
if (!line || line.startsWith("#") || line.startsWith(";")) continue;
|
|
15
|
+
if (line.startsWith("[") && line.endsWith("]")) {
|
|
16
|
+
let name = line.slice(1, -1).trim();
|
|
17
|
+
if (name.startsWith("profile ")) name = name.slice(8).trim();
|
|
18
|
+
if (name.startsWith("sso-session ")) name = `sso-session:${name.slice(12).trim()}`;
|
|
19
|
+
let section = out[name];
|
|
20
|
+
if (!section) {
|
|
21
|
+
section = {};
|
|
22
|
+
out[name] = section;
|
|
23
|
+
}
|
|
24
|
+
current = section;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!current) continue;
|
|
28
|
+
const eq = line.indexOf("=");
|
|
29
|
+
if (eq === -1) continue;
|
|
30
|
+
current[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readAwsIniSync(filePath: string): AwsIniFile | undefined {
|
|
36
|
+
try {
|
|
37
|
+
return parseAwsIni(fs.readFileSync(filePath, "utf8"));
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Resolve the selected shared-credentials profile. */
|
|
44
|
+
export function resolveAwsProfile(profile?: string): string {
|
|
45
|
+
return profile || $env.AWS_PROFILE || "default";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether the shared config file participates in profile/region resolution.
|
|
50
|
+
* Explicit profile selection enables it; the implicit default profile follows
|
|
51
|
+
* the AWS SDK's `AWS_SDK_LOAD_CONFIG` opt-in.
|
|
52
|
+
*/
|
|
53
|
+
export function shouldLoadAwsSharedConfig(profile?: string): boolean {
|
|
54
|
+
if (profile || $env.AWS_PROFILE) return true;
|
|
55
|
+
const value = $env.AWS_SDK_LOAD_CONFIG?.toLowerCase();
|
|
56
|
+
return value === "1" || value === "true";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function resolveAwsProfileRegion(profile?: string): string | undefined {
|
|
60
|
+
if (!shouldLoadAwsSharedConfig(profile)) return undefined;
|
|
61
|
+
const configPath = $env.AWS_CONFIG_FILE || path.join(os.homedir(), ".aws", "config");
|
|
62
|
+
return readAwsIniSync(configPath)?.[resolveAwsProfile(profile)]?.region;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Region selected by the environment or active shared-config profile. */
|
|
66
|
+
export function resolveAwsAmbientRegion(profile?: string): string | undefined {
|
|
67
|
+
return $env.AWS_REGION || $env.AWS_DEFAULT_REGION || resolveAwsProfileRegion(profile);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Resolve the region precedence shared by AWS transports and credential exchanges. */
|
|
71
|
+
export function resolveAwsRegion(explicitRegion?: string, profile?: string): string {
|
|
72
|
+
return explicitRegion || resolveAwsAmbientRegion(profile) || "us-east-1";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function hasConfiguredAwsProfile(profile?: string): boolean {
|
|
76
|
+
const selectedProfile = resolveAwsProfile(profile);
|
|
77
|
+
const credentialsPath = $env.AWS_SHARED_CREDENTIALS_FILE || path.join(os.homedir(), ".aws", "credentials");
|
|
78
|
+
const configPath = $env.AWS_CONFIG_FILE || path.join(os.homedir(), ".aws", "config");
|
|
79
|
+
const credentialsIni = readAwsIniSync(credentialsPath);
|
|
80
|
+
const configIni = shouldLoadAwsSharedConfig(profile) ? readAwsIniSync(configPath) : undefined;
|
|
81
|
+
const merged = { ...(configIni?.[selectedProfile] ?? {}), ...(credentialsIni?.[selectedProfile] ?? {}) };
|
|
82
|
+
if (merged.aws_access_key_id && merged.aws_secret_access_key) return true;
|
|
83
|
+
if (merged.credential_process) return true;
|
|
84
|
+
if (!merged.sso_account_id || !merged.sso_role_name) return false;
|
|
85
|
+
if (merged.sso_start_url && merged.sso_region) return true;
|
|
86
|
+
const session = merged.sso_session ? configIni?.[`sso-session:${merged.sso_session}`] : undefined;
|
|
87
|
+
return !!(session?.sso_start_url && session.sso_region);
|
|
88
|
+
}
|