@vib-rato/ai 0.16.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 +3354 -0
- package/README.md +1194 -0
- package/dist/types/adapter-internals/provider-safety-stop.d.ts +45 -0
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth-broker/client.d.ts +80 -0
- package/dist/types/auth-broker/index.d.ts +5 -0
- package/dist/types/auth-broker/redact.d.ts +7 -0
- package/dist/types/auth-broker/refresher.d.ts +25 -0
- package/dist/types/auth-broker/remote-store.d.ts +153 -0
- package/dist/types/auth-broker/server.d.ts +32 -0
- package/dist/types/auth-broker/types.d.ts +132 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +555 -0
- package/dist/types/auth-gateway/http.d.ts +40 -0
- package/dist/types/auth-gateway/index.d.ts +3 -0
- package/dist/types/auth-gateway/server.d.ts +70 -0
- package/dist/types/auth-gateway/types.d.ts +129 -0
- package/dist/types/auth-storage.d.ts +1074 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/codex-tools.d.ts +4 -0
- package/dist/types/context-cap-policy.d.ts +68 -0
- package/dist/types/core.d.ts +35 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/model-cache.d.ts +24 -0
- package/dist/types/model-manager.d.ts +77 -0
- package/dist/types/model-pricing.d.ts +3 -0
- package/dist/types/model-retirements.d.ts +6 -0
- package/dist/types/model-thinking.d.ts +100 -0
- package/dist/types/models.d.ts +21 -0
- package/dist/types/openai-completions-compat.d.ts +34 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/provider-models/bundled-references.d.ts +4 -0
- package/dist/types/provider-models/descriptors.d.ts +48 -0
- package/dist/types/provider-models/google.d.ts +20 -0
- package/dist/types/provider-models/index.d.ts +5 -0
- package/dist/types/provider-models/ollama.d.ts +7 -0
- package/dist/types/provider-models/openai-compat.d.ts +293 -0
- package/dist/types/provider-models/special.d.ts +29 -0
- package/dist/types/providers/amazon-bedrock.d.ts +60 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +450 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic.d.ts +280 -0
- package/dist/types/providers/aws-credential-config.d.ts +19 -0
- package/dist/types/providers/aws-credentials.d.ts +43 -0
- package/dist/types/providers/aws-eventstream.d.ts +38 -0
- package/dist/types/providers/aws-sigv4.d.ts +55 -0
- package/dist/types/providers/azure-openai-responses.d.ts +22 -0
- package/dist/types/providers/composer-discipline.d.ts +32 -0
- package/dist/types/providers/cursor/client-version.d.ts +10 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
- package/dist/types/providers/cursor/gen/agent_pb.d.ts +16769 -0
- package/dist/types/providers/cursor-pi-args.d.ts +119 -0
- package/dist/types/providers/cursor.d.ts +72 -0
- package/dist/types/providers/dashscope-token-plan-headers.d.ts +57 -0
- package/dist/types/providers/error-message.d.ts +27 -0
- package/dist/types/providers/github-copilot-headers.d.ts +40 -0
- package/dist/types/providers/gitlab-duo.d.ts +27 -0
- package/dist/types/providers/google-auth.d.ts +26 -0
- package/dist/types/providers/google-gemini-cli.d.ts +75 -0
- package/dist/types/providers/google-gemini-headers.d.ts +43 -0
- package/dist/types/providers/google-shared.d.ts +183 -0
- package/dist/types/providers/google-types.d.ts +138 -0
- package/dist/types/providers/google-vertex.d.ts +11 -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/kiro-api-key.d.ts +50 -0
- package/dist/types/providers/kiro-codewhisperer.d.ts +11 -0
- package/dist/types/providers/mock.d.ts +189 -0
- package/dist/types/providers/ollama.d.ts +41 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
- package/dist/types/providers/openai-bounded-rate-limits.d.ts +3 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +1733 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-codex/constants.d.ts +26 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +50 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +18 -0
- package/dist/types/providers/openai-codex-responses.d.ts +71 -0
- package/dist/types/providers/openai-completions-compat.d.ts +6 -0
- package/dist/types/providers/openai-completions.d.ts +35 -0
- package/dist/types/providers/openai-opencodex-responses.d.ts +10 -0
- package/dist/types/providers/openai-request-transform.d.ts +4 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-shared.d.ts +106 -0
- package/dist/types/providers/openai-responses.d.ts +37 -0
- package/dist/types/providers/pi-native-client.d.ts +29 -0
- package/dist/types/providers/pi-native-server.d.ts +60 -0
- package/dist/types/providers/register-builtins.d.ts +59 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +33 -0
- package/dist/types/providers/vision-guard.d.ts +8 -0
- package/dist/types/rate-limit-utils.d.ts +19 -0
- package/dist/types/stream.d.ts +45 -0
- package/dist/types/types.d.ts +1073 -0
- package/dist/types/usage/claude.d.ts +3 -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 +2 -0
- package/dist/types/usage/grok-cli.d.ts +17 -0
- package/dist/types/usage/kimi.d.ts +4 -0
- package/dist/types/usage/minimax-code.d.ts +2 -0
- package/dist/types/usage/openai-codex.d.ts +3 -0
- package/dist/types/usage/shared.d.ts +1 -0
- package/dist/types/usage/zai.d.ts +2 -0
- package/dist/types/usage.d.ts +264 -0
- package/dist/types/utils/abort.d.ts +19 -0
- package/dist/types/utils/anthropic-auth.d.ts +39 -0
- package/dist/types/utils/block-symbols.d.ts +6 -0
- package/dist/types/utils/discovery/antigravity.d.ts +67 -0
- package/dist/types/utils/discovery/codex.d.ts +38 -0
- package/dist/types/utils/discovery/cursor.d.ts +49 -0
- package/dist/types/utils/discovery/gemini.d.ts +25 -0
- package/dist/types/utils/discovery/index.d.ts +4 -0
- package/dist/types/utils/discovery/openai-compatible.d.ts +81 -0
- package/dist/types/utils/event-stream.d.ts +41 -0
- package/dist/types/utils/fallback-transport.d.ts +110 -0
- package/dist/types/utils/fireworks-model-id.d.ts +10 -0
- package/dist/types/utils/foundry.d.ts +11 -0
- package/dist/types/utils/h2-fetch.d.ts +22 -0
- package/dist/types/utils/http-inspector.d.ts +59 -0
- package/dist/types/utils/idle-iterator.d.ts +122 -0
- package/dist/types/utils/json-parse.d.ts +98 -0
- package/dist/types/utils/oauth/alibaba-token-plan.d.ts +19 -0
- package/dist/types/utils/oauth/anthropic.d.ts +41 -0
- package/dist/types/utils/oauth/api-key-login.d.ts +38 -0
- package/dist/types/utils/oauth/api-key-validation.d.ts +39 -0
- package/dist/types/utils/oauth/bizrouter.d.ts +1 -0
- package/dist/types/utils/oauth/callback-server.d.ts +80 -0
- package/dist/types/utils/oauth/cerebras.d.ts +1 -0
- package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
- package/dist/types/utils/oauth/commandcode.d.ts +1 -0
- package/dist/types/utils/oauth/cursor.d.ts +15 -0
- package/dist/types/utils/oauth/deepinfra.d.ts +1 -0
- package/dist/types/utils/oauth/deepseek.d.ts +10 -0
- package/dist/types/utils/oauth/firepass.d.ts +1 -0
- package/dist/types/utils/oauth/fireworks.d.ts +1 -0
- package/dist/types/utils/oauth/fugu.d.ts +1 -0
- package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
- package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
- package/dist/types/utils/oauth/glm-zcode.d.ts +71 -0
- package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
- package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
- package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
- package/dist/types/utils/oauth/huggingface.d.ts +19 -0
- package/dist/types/utils/oauth/index.d.ts +39 -0
- package/dist/types/utils/oauth/kagi.d.ts +17 -0
- package/dist/types/utils/oauth/kilo.d.ts +5 -0
- package/dist/types/utils/oauth/kimi.d.ts +17 -0
- package/dist/types/utils/oauth/kiro.d.ts +71 -0
- package/dist/types/utils/oauth/litellm.d.ts +18 -0
- package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
- package/dist/types/utils/oauth/mara.d.ts +1 -0
- package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
- package/dist/types/utils/oauth/moonshot.d.ts +1 -0
- package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
- package/dist/types/utils/oauth/nvidia.d.ts +18 -0
- package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
- package/dist/types/utils/oauth/ollama.d.ts +18 -0
- package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
- package/dist/types/utils/oauth/opencode.d.ts +18 -0
- package/dist/types/utils/oauth/opengateway.d.ts +1 -0
- package/dist/types/utils/oauth/openrouter.d.ts +1 -0
- package/dist/types/utils/oauth/parallel.d.ts +17 -0
- package/dist/types/utils/oauth/perplexity.d.ts +4 -0
- package/dist/types/utils/oauth/pkce.d.ts +8 -0
- package/dist/types/utils/oauth/qianfan.d.ts +17 -0
- package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
- package/dist/types/utils/oauth/sglang.d.ts +16 -0
- package/dist/types/utils/oauth/synthetic.d.ts +1 -0
- package/dist/types/utils/oauth/tavily.d.ts +17 -0
- package/dist/types/utils/oauth/together.d.ts +1 -0
- package/dist/types/utils/oauth/types.d.ts +56 -0
- package/dist/types/utils/oauth/venice.d.ts +18 -0
- package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
- package/dist/types/utils/oauth/vllm.d.ts +16 -0
- package/dist/types/utils/oauth/xai.d.ts +30 -0
- package/dist/types/utils/oauth/xiaomi.d.ts +25 -0
- package/dist/types/utils/oauth/zai.d.ts +18 -0
- package/dist/types/utils/oauth/zenmux.d.ts +1 -0
- package/dist/types/utils/overflow.d.ts +14 -0
- package/dist/types/utils/parse-bind.d.ts +26 -0
- package/dist/types/utils/provider-response.d.ts +6 -0
- package/dist/types/utils/provider-safety-stop.d.ts +8 -0
- package/dist/types/utils/proxy.d.ts +7 -0
- package/dist/types/utils/retry-after.d.ts +3 -0
- package/dist/types/utils/retry-budget.d.ts +1 -0
- package/dist/types/utils/retry.d.ts +29 -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 +49 -0
- package/dist/types/utils/schema/index.d.ts +14 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
- package/dist/types/utils/schema/meta-validator.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +93 -0
- package/dist/types/utils/schema/root-combinator.d.ts +12 -0
- package/dist/types/utils/schema/spill.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +25 -0
- package/dist/types/utils/schema/types.d.ts +4 -0
- package/dist/types/utils/schema/wire.d.ts +54 -0
- package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
- package/dist/types/utils/sse-debug.d.ts +10 -0
- package/dist/types/utils/tool-call-healing.d.ts +80 -0
- package/dist/types/utils/tool-choice-capability.d.ts +57 -0
- package/dist/types/utils/tool-choice.d.ts +50 -0
- package/dist/types/utils/validation.d.ts +17 -0
- package/dist/types/utils.d.ts +117 -0
- package/package.json +152 -0
- package/src/adapter-internals/provider-safety-stop.d.ts +45 -0
- package/src/adapter-internals/provider-safety-stop.ts +156 -0
- package/src/api-registry.d.ts +30 -0
- package/src/api-registry.ts +96 -0
- package/src/auth-broker/client.ts +444 -0
- package/src/auth-broker/index.ts +5 -0
- package/src/auth-broker/redact.ts +39 -0
- package/src/auth-broker/refresher.ts +130 -0
- package/src/auth-broker/remote-store.ts +1576 -0
- package/src/auth-broker/server.ts +764 -0
- package/src/auth-broker/types.ts +164 -0
- package/src/auth-broker/wire-schemas.ts +261 -0
- package/src/auth-gateway/http.ts +198 -0
- package/src/auth-gateway/index.ts +3 -0
- package/src/auth-gateway/server.ts +1315 -0
- package/src/auth-gateway/types.ts +160 -0
- package/src/auth-storage.ts +7312 -0
- package/src/cli.ts +269 -0
- package/src/codex-tools.d.ts +4 -0
- package/src/codex-tools.ts +24 -0
- package/src/context-cap-policy.d.ts +68 -0
- package/src/context-cap-policy.ts +123 -0
- package/src/core.ts +44 -0
- package/src/index.ts +61 -0
- package/src/model-cache.ts +236 -0
- package/src/model-manager.ts +744 -0
- package/src/model-pricing.d.ts +3 -0
- package/src/model-pricing.ts +68 -0
- package/src/model-retirements.d.ts +6 -0
- package/src/model-retirements.ts +19 -0
- package/src/model-thinking.d.ts +100 -0
- package/src/model-thinking.ts +1054 -0
- package/src/models.d.ts +21 -0
- package/src/models.json +94672 -0
- package/src/models.json.d.ts +9 -0
- package/src/models.ts +126 -0
- package/src/openai-completions-compat.d.ts +34 -0
- package/src/openai-completions-compat.ts +383 -0
- package/src/prompts/composer-bash-policy-recovery.md +1 -0
- package/src/prompts/cursor-composer-bash-policy-recovery.md +1 -0
- package/src/prompts/cursor-composer-edit-discipline.md +7 -0
- package/src/prompts/turn-aborted-guidance.md +4 -0
- package/src/provider-details.ts +90 -0
- package/src/provider-models/bundled-references.ts +38 -0
- package/src/provider-models/descriptors.ts +392 -0
- package/src/provider-models/google.ts +92 -0
- package/src/provider-models/index.ts +5 -0
- package/src/provider-models/ollama.ts +159 -0
- package/src/provider-models/openai-compat.ts +2920 -0
- package/src/provider-models/special.ts +185 -0
- package/src/providers/amazon-bedrock.d.ts +60 -0
- package/src/providers/amazon-bedrock.ts +939 -0
- package/src/providers/anthropic-messages-server-schema.ts +229 -0
- package/src/providers/anthropic-messages-server.ts +839 -0
- package/src/providers/anthropic.d.ts +280 -0
- package/src/providers/anthropic.ts +4421 -0
- package/src/providers/aws-credential-config.d.ts +19 -0
- package/src/providers/aws-credential-config.ts +179 -0
- package/src/providers/aws-credentials.d.ts +43 -0
- package/src/providers/aws-credentials.ts +457 -0
- package/src/providers/aws-eventstream.d.ts +38 -0
- package/src/providers/aws-eventstream.ts +185 -0
- package/src/providers/aws-sigv4.d.ts +55 -0
- package/src/providers/aws-sigv4.ts +218 -0
- package/src/providers/azure-openai-responses.d.ts +22 -0
- package/src/providers/azure-openai-responses.ts +447 -0
- package/src/providers/composer-discipline.d.ts +32 -0
- package/src/providers/composer-discipline.ts +95 -0
- package/src/providers/cursor/client-version.d.ts +10 -0
- package/src/providers/cursor/client-version.ts +10 -0
- package/src/providers/cursor/exec-modern.d.ts +98 -0
- package/src/providers/cursor/exec-modern.ts +497 -0
- package/src/providers/cursor/gen/agent_pb.d.ts +16769 -0
- package/src/providers/cursor/gen/agent_pb.ts +19780 -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.d.ts +119 -0
- package/src/providers/cursor-pi-args.ts +187 -0
- package/src/providers/cursor.d.ts +72 -0
- package/src/providers/cursor.ts +3396 -0
- package/src/providers/dashscope-token-plan-headers.d.ts +57 -0
- package/src/providers/dashscope-token-plan-headers.ts +84 -0
- package/src/providers/error-message.d.ts +27 -0
- package/src/providers/error-message.ts +21 -0
- package/src/providers/github-copilot-headers.d.ts +40 -0
- package/src/providers/github-copilot-headers.ts +140 -0
- package/src/providers/gitlab-duo.d.ts +27 -0
- package/src/providers/gitlab-duo.ts +393 -0
- package/src/providers/google-auth.d.ts +26 -0
- package/src/providers/google-auth.ts +262 -0
- package/src/providers/google-gemini-cli.d.ts +75 -0
- package/src/providers/google-gemini-cli.ts +969 -0
- package/src/providers/google-gemini-headers.d.ts +43 -0
- package/src/providers/google-gemini-headers.ts +100 -0
- package/src/providers/google-shared.d.ts +183 -0
- package/src/providers/google-shared.ts +1105 -0
- package/src/providers/google-types.d.ts +138 -0
- package/src/providers/google-types.ts +167 -0
- package/src/providers/google-vertex.d.ts +11 -0
- package/src/providers/google-vertex.ts +124 -0
- package/src/providers/google.d.ts +4 -0
- package/src/providers/google.ts +41 -0
- package/src/providers/grammar.d.ts +1 -0
- package/src/providers/grammar.ts +70 -0
- package/src/providers/kimi.d.ts +27 -0
- package/src/providers/kimi.ts +52 -0
- package/src/providers/kiro-api-key.d.ts +50 -0
- package/src/providers/kiro-api-key.ts +786 -0
- package/src/providers/kiro-codewhisperer.d.ts +11 -0
- package/src/providers/kiro-codewhisperer.ts +600 -0
- package/src/providers/mock.ts +526 -0
- package/src/providers/ollama.d.ts +41 -0
- package/src/providers/ollama.ts +645 -0
- package/src/providers/openai-anthropic-shim.d.ts +31 -0
- package/src/providers/openai-anthropic-shim.ts +156 -0
- package/src/providers/openai-bounded-rate-limits.d.ts +3 -0
- package/src/providers/openai-bounded-rate-limits.ts +57 -0
- package/src/providers/openai-chat-server-schema.ts +254 -0
- package/src/providers/openai-chat-server.ts +724 -0
- package/src/providers/openai-codex/constants.d.ts +26 -0
- package/src/providers/openai-codex/constants.ts +43 -0
- package/src/providers/openai-codex/request-transformer.d.ts +50 -0
- package/src/providers/openai-codex/request-transformer.ts +219 -0
- package/src/providers/openai-codex/response-handler.d.ts +18 -0
- package/src/providers/openai-codex/response-handler.ts +111 -0
- package/src/providers/openai-codex-responses.d.ts +71 -0
- package/src/providers/openai-codex-responses.ts +3288 -0
- package/src/providers/openai-completions-compat.d.ts +6 -0
- package/src/providers/openai-completions-compat.ts +6 -0
- package/src/providers/openai-completions.d.ts +35 -0
- package/src/providers/openai-completions.ts +2294 -0
- package/src/providers/openai-opencodex-responses.ts +174 -0
- package/src/providers/openai-request-transform.d.ts +4 -0
- package/src/providers/openai-request-transform.ts +136 -0
- package/src/providers/openai-responses-server-schema.ts +290 -0
- package/src/providers/openai-responses-server.ts +1268 -0
- package/src/providers/openai-responses-shared.d.ts +106 -0
- package/src/providers/openai-responses-shared.ts +1253 -0
- package/src/providers/openai-responses.d.ts +37 -0
- package/src/providers/openai-responses.ts +989 -0
- package/src/providers/pi-native-client.d.ts +29 -0
- package/src/providers/pi-native-client.ts +243 -0
- package/src/providers/pi-native-server.ts +488 -0
- package/src/providers/register-builtins.d.ts +59 -0
- package/src/providers/register-builtins.ts +544 -0
- package/src/providers/synthetic.d.ts +26 -0
- package/src/providers/synthetic.ts +50 -0
- package/src/providers/transform-messages.d.ts +33 -0
- package/src/providers/transform-messages.ts +408 -0
- package/src/providers/vision-guard.d.ts +8 -0
- package/src/providers/vision-guard.ts +31 -0
- package/src/rate-limit-utils.d.ts +19 -0
- package/src/rate-limit-utils.ts +102 -0
- package/src/stream.d.ts +45 -0
- package/src/stream.ts +1306 -0
- package/src/types.d.ts +1073 -0
- package/src/types.ts +1305 -0
- package/src/usage/claude.ts +449 -0
- package/src/usage/gemini.ts +250 -0
- package/src/usage/github-copilot.ts +421 -0
- package/src/usage/google-antigravity.ts +201 -0
- package/src/usage/grok-cli.ts +259 -0
- package/src/usage/kimi.ts +285 -0
- package/src/usage/minimax-code.ts +31 -0
- package/src/usage/openai-codex.ts +503 -0
- package/src/usage/shared.ts +10 -0
- package/src/usage/zai.ts +247 -0
- package/src/usage.ts +190 -0
- package/src/utils/abort.d.ts +19 -0
- package/src/utils/abort.ts +51 -0
- package/src/utils/anthropic-auth.ts +95 -0
- package/src/utils/block-symbols.d.ts +6 -0
- package/src/utils/block-symbols.ts +11 -0
- package/src/utils/discovery/antigravity.ts +275 -0
- package/src/utils/discovery/codex.ts +362 -0
- package/src/utils/discovery/cursor.ts +388 -0
- package/src/utils/discovery/gemini.ts +248 -0
- package/src/utils/discovery/index.ts +4 -0
- package/src/utils/discovery/openai-compatible.ts +379 -0
- package/src/utils/event-stream.d.ts +41 -0
- package/src/utils/event-stream.ts +269 -0
- package/src/utils/fallback-transport.d.ts +110 -0
- package/src/utils/fallback-transport.ts +411 -0
- package/src/utils/fireworks-model-id.d.ts +10 -0
- package/src/utils/fireworks-model-id.ts +30 -0
- package/src/utils/foundry.d.ts +11 -0
- package/src/utils/foundry.ts +18 -0
- package/src/utils/h2-fetch.ts +60 -0
- package/src/utils/http-inspector.d.ts +59 -0
- package/src/utils/http-inspector.ts +380 -0
- package/src/utils/idle-iterator.d.ts +122 -0
- package/src/utils/idle-iterator.ts +410 -0
- package/src/utils/json-parse.d.ts +98 -0
- package/src/utils/json-parse.ts +607 -0
- package/src/utils/oauth/alibaba-token-plan.ts +60 -0
- package/src/utils/oauth/anthropic.ts +233 -0
- package/src/utils/oauth/api-key-login.ts +98 -0
- package/src/utils/oauth/api-key-validation.ts +344 -0
- package/src/utils/oauth/bizrouter.ts +15 -0
- package/src/utils/oauth/callback-server.d.ts +80 -0
- package/src/utils/oauth/callback-server.ts +359 -0
- package/src/utils/oauth/cerebras.ts +16 -0
- package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
- package/src/utils/oauth/commandcode.ts +17 -0
- package/src/utils/oauth/cursor.ts +157 -0
- package/src/utils/oauth/deepinfra.ts +15 -0
- package/src/utils/oauth/deepseek.ts +53 -0
- package/src/utils/oauth/firepass.ts +24 -0
- package/src/utils/oauth/fireworks.ts +15 -0
- package/src/utils/oauth/fugu.ts +15 -0
- package/src/utils/oauth/github-copilot.d.ts +38 -0
- package/src/utils/oauth/github-copilot.ts +362 -0
- package/src/utils/oauth/gitlab-duo.ts +123 -0
- package/src/utils/oauth/glm-zcode.d.ts +71 -0
- package/src/utils/oauth/glm-zcode.ts +433 -0
- package/src/utils/oauth/google-antigravity.ts +200 -0
- package/src/utils/oauth/google-gemini-cli.ts +256 -0
- package/src/utils/oauth/google-oauth-shared.ts +110 -0
- package/src/utils/oauth/huggingface.ts +62 -0
- package/src/utils/oauth/index.ts +558 -0
- package/src/utils/oauth/kagi.ts +47 -0
- package/src/utils/oauth/kilo.ts +87 -0
- package/src/utils/oauth/kimi.d.ts +17 -0
- package/src/utils/oauth/kimi.ts +275 -0
- package/src/utils/oauth/kiro.ts +448 -0
- package/src/utils/oauth/litellm.ts +47 -0
- package/src/utils/oauth/lm-studio.ts +38 -0
- package/src/utils/oauth/mara.ts +16 -0
- package/src/utils/oauth/minimax-code.ts +78 -0
- package/src/utils/oauth/moonshot.ts +16 -0
- package/src/utils/oauth/nanogpt.ts +15 -0
- package/src/utils/oauth/nvidia.ts +70 -0
- package/src/utils/oauth/oauth.html +199 -0
- package/src/utils/oauth/ollama-cloud.ts +28 -0
- package/src/utils/oauth/ollama.ts +47 -0
- package/src/utils/oauth/openai-codex.ts +299 -0
- package/src/utils/oauth/opencode.ts +49 -0
- package/src/utils/oauth/opengateway.ts +15 -0
- package/src/utils/oauth/openrouter.ts +16 -0
- package/src/utils/oauth/parallel.ts +46 -0
- package/src/utils/oauth/perplexity.ts +225 -0
- package/src/utils/oauth/pkce.ts +18 -0
- package/src/utils/oauth/qianfan.ts +58 -0
- package/src/utils/oauth/qwen-portal.ts +60 -0
- package/src/utils/oauth/sglang.ts +42 -0
- package/src/utils/oauth/synthetic.ts +15 -0
- package/src/utils/oauth/tavily.ts +46 -0
- package/src/utils/oauth/together.ts +16 -0
- package/src/utils/oauth/types.d.ts +56 -0
- package/src/utils/oauth/types.ts +122 -0
- package/src/utils/oauth/venice.ts +59 -0
- package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
- package/src/utils/oauth/vllm.ts +42 -0
- package/src/utils/oauth/xai.ts +246 -0
- package/src/utils/oauth/xiaomi.ts +199 -0
- package/src/utils/oauth/zai.ts +60 -0
- package/src/utils/oauth/zenmux.ts +15 -0
- package/src/utils/overflow.ts +275 -0
- package/src/utils/parse-bind.ts +81 -0
- package/src/utils/provider-response.d.ts +6 -0
- package/src/utils/provider-response.ts +30 -0
- package/src/utils/provider-safety-stop.ts +8 -0
- package/src/utils/proxy.d.ts +7 -0
- package/src/utils/proxy.ts +652 -0
- package/src/utils/retry-after.d.ts +3 -0
- package/src/utils/retry-after.ts +110 -0
- package/src/utils/retry-budget.d.ts +1 -0
- package/src/utils/retry-budget.ts +4 -0
- package/src/utils/retry.d.ts +29 -0
- package/src/utils/retry.ts +67 -0
- package/src/utils/schema/CONSTRAINTS.md +164 -0
- package/src/utils/schema/adapt.d.ts +24 -0
- package/src/utils/schema/adapt.ts +36 -0
- package/src/utils/schema/compatibility.d.ts +30 -0
- package/src/utils/schema/compatibility.ts +435 -0
- package/src/utils/schema/dereference.d.ts +11 -0
- package/src/utils/schema/dereference.ts +98 -0
- package/src/utils/schema/draft.d.ts +10 -0
- package/src/utils/schema/draft.ts +341 -0
- package/src/utils/schema/equality.d.ts +4 -0
- package/src/utils/schema/equality.ts +97 -0
- package/src/utils/schema/fields.d.ts +49 -0
- package/src/utils/schema/fields.ts +190 -0
- package/src/utils/schema/index.d.ts +14 -0
- package/src/utils/schema/index.ts +14 -0
- package/src/utils/schema/json-schema-validator.d.ts +12 -0
- package/src/utils/schema/json-schema-validator.ts +577 -0
- package/src/utils/schema/meta-validator.d.ts +2 -0
- package/src/utils/schema/meta-validator.ts +167 -0
- package/src/utils/schema/normalize.d.ts +93 -0
- package/src/utils/schema/normalize.ts +1588 -0
- package/src/utils/schema/root-combinator.d.ts +12 -0
- package/src/utils/schema/root-combinator.ts +143 -0
- package/src/utils/schema/spill.d.ts +8 -0
- package/src/utils/schema/spill.ts +43 -0
- package/src/utils/schema/stamps.d.ts +25 -0
- package/src/utils/schema/stamps.ts +97 -0
- package/src/utils/schema/types.d.ts +4 -0
- package/src/utils/schema/types.ts +11 -0
- package/src/utils/schema/wire.d.ts +54 -0
- package/src/utils/schema/wire.ts +213 -0
- package/src/utils/schema/zod-decontaminate.d.ts +31 -0
- package/src/utils/schema/zod-decontaminate.ts +331 -0
- package/src/utils/sse-debug.d.ts +10 -0
- package/src/utils/sse-debug.ts +289 -0
- package/src/utils/tool-call-healing.d.ts +80 -0
- package/src/utils/tool-call-healing.ts +298 -0
- package/src/utils/tool-choice-capability.d.ts +57 -0
- package/src/utils/tool-choice-capability.ts +633 -0
- package/src/utils/tool-choice.d.ts +50 -0
- package/src/utils/tool-choice.ts +99 -0
- package/src/utils/validation.ts +1080 -0
- package/src/utils.d.ts +117 -0
- package/src/utils.ts +523 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { copyProviderSafetyStopAdapterInvocation } from "../adapter-internals/provider-safety-stop";
|
|
2
|
+
import { ANTHROPIC_THINKING, mapAnthropicToolChoice } from "../stream";
|
|
3
|
+
import type { Api, Context, FetchImpl, Model, SimpleStreamOptions } from "../types";
|
|
4
|
+
import { AssistantMessageEventStream } from "../utils/event-stream";
|
|
5
|
+
import { createProviderErrorMessage } from "./error-message";
|
|
6
|
+
import type { OpenAICompletionsOptions } from "./openai-completions";
|
|
7
|
+
import type { OpenAIResponsesOptions } from "./openai-responses";
|
|
8
|
+
import { streamAnthropic, streamOpenAICompletions, streamOpenAIResponses } from "./register-builtins";
|
|
9
|
+
|
|
10
|
+
const GITLAB_COM_URL = "https://gitlab.com";
|
|
11
|
+
const AI_GATEWAY_URL = "https://cloud.gitlab.com";
|
|
12
|
+
const ANTHROPIC_PROXY_URL = `${AI_GATEWAY_URL}/ai/v1/proxy/anthropic/`;
|
|
13
|
+
const OPENAI_PROXY_URL = `${AI_GATEWAY_URL}/ai/v1/proxy/openai/v1`;
|
|
14
|
+
const DIRECT_ACCESS_TTL_MS = 25 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
type GitLabProvider = "anthropic" | "openai";
|
|
17
|
+
type GitLabOpenAIApiType = "chat" | "responses";
|
|
18
|
+
|
|
19
|
+
export type GitLabModelMapping = {
|
|
20
|
+
provider: GitLabProvider;
|
|
21
|
+
model: string;
|
|
22
|
+
openaiApiType?: GitLabOpenAIApiType;
|
|
23
|
+
name: string;
|
|
24
|
+
reasoning: boolean;
|
|
25
|
+
input: ("text" | "image")[];
|
|
26
|
+
cost: { input: number; output: number; cacheRead: number; cacheWrite: number };
|
|
27
|
+
contextWindow: number;
|
|
28
|
+
maxTokens: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const MODEL_MAPPINGS: Record<string, GitLabModelMapping> = {
|
|
32
|
+
"duo-chat-opus-4-6": {
|
|
33
|
+
provider: "anthropic",
|
|
34
|
+
model: "claude-opus-4-6",
|
|
35
|
+
name: "Duo Chat Opus 4.6",
|
|
36
|
+
reasoning: true,
|
|
37
|
+
input: ["text", "image"],
|
|
38
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
39
|
+
contextWindow: 200000,
|
|
40
|
+
maxTokens: 64000,
|
|
41
|
+
},
|
|
42
|
+
"duo-chat-sonnet-4-6": {
|
|
43
|
+
provider: "anthropic",
|
|
44
|
+
model: "claude-sonnet-4-6",
|
|
45
|
+
name: "Duo Chat Sonnet 4.6",
|
|
46
|
+
reasoning: true,
|
|
47
|
+
input: ["text", "image"],
|
|
48
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
49
|
+
contextWindow: 200000,
|
|
50
|
+
maxTokens: 64000,
|
|
51
|
+
},
|
|
52
|
+
"duo-chat-opus-4-5": {
|
|
53
|
+
provider: "anthropic",
|
|
54
|
+
model: "claude-opus-4-5-20251101",
|
|
55
|
+
name: "Duo Chat Opus 4.5",
|
|
56
|
+
reasoning: true,
|
|
57
|
+
input: ["text", "image"],
|
|
58
|
+
cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
59
|
+
contextWindow: 200000,
|
|
60
|
+
maxTokens: 64000,
|
|
61
|
+
},
|
|
62
|
+
"duo-chat-sonnet-4-5": {
|
|
63
|
+
provider: "anthropic",
|
|
64
|
+
model: "claude-sonnet-4-5-20250929",
|
|
65
|
+
name: "Duo Chat Sonnet 4.5",
|
|
66
|
+
reasoning: true,
|
|
67
|
+
input: ["text", "image"],
|
|
68
|
+
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
69
|
+
contextWindow: 200000,
|
|
70
|
+
maxTokens: 64000,
|
|
71
|
+
},
|
|
72
|
+
"duo-chat-haiku-4-5": {
|
|
73
|
+
provider: "anthropic",
|
|
74
|
+
model: "claude-haiku-4-5-20251001",
|
|
75
|
+
name: "Duo Chat Haiku 4.5",
|
|
76
|
+
reasoning: true,
|
|
77
|
+
input: ["text", "image"],
|
|
78
|
+
cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
|
|
79
|
+
contextWindow: 200000,
|
|
80
|
+
maxTokens: 64000,
|
|
81
|
+
},
|
|
82
|
+
"duo-chat-gpt-5-1": {
|
|
83
|
+
provider: "openai",
|
|
84
|
+
model: "gpt-5.1-2025-11-13",
|
|
85
|
+
openaiApiType: "chat",
|
|
86
|
+
name: "Duo Chat GPT-5.1",
|
|
87
|
+
reasoning: true,
|
|
88
|
+
input: ["text", "image"],
|
|
89
|
+
cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 },
|
|
90
|
+
contextWindow: 128000,
|
|
91
|
+
maxTokens: 16384,
|
|
92
|
+
},
|
|
93
|
+
"duo-chat-gpt-5-2": {
|
|
94
|
+
provider: "openai",
|
|
95
|
+
model: "gpt-5.2-2025-12-11",
|
|
96
|
+
openaiApiType: "chat",
|
|
97
|
+
name: "Duo Chat GPT-5.2",
|
|
98
|
+
reasoning: true,
|
|
99
|
+
input: ["text", "image"],
|
|
100
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
101
|
+
contextWindow: 128000,
|
|
102
|
+
maxTokens: 16384,
|
|
103
|
+
},
|
|
104
|
+
"duo-chat-gpt-5-mini": {
|
|
105
|
+
provider: "openai",
|
|
106
|
+
model: "gpt-5-mini-2025-08-07",
|
|
107
|
+
openaiApiType: "chat",
|
|
108
|
+
name: "Duo Chat GPT-5 Mini",
|
|
109
|
+
reasoning: true,
|
|
110
|
+
input: ["text", "image"],
|
|
111
|
+
cost: { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 },
|
|
112
|
+
contextWindow: 128000,
|
|
113
|
+
maxTokens: 16384,
|
|
114
|
+
},
|
|
115
|
+
"duo-chat-gpt-5-codex": {
|
|
116
|
+
provider: "openai",
|
|
117
|
+
model: "gpt-5-codex",
|
|
118
|
+
openaiApiType: "responses",
|
|
119
|
+
name: "Duo Chat GPT-5 Codex",
|
|
120
|
+
reasoning: true,
|
|
121
|
+
input: ["text", "image"],
|
|
122
|
+
cost: { input: 2.5, output: 10, cacheRead: 0, cacheWrite: 0 },
|
|
123
|
+
contextWindow: 272000,
|
|
124
|
+
maxTokens: 128000,
|
|
125
|
+
},
|
|
126
|
+
"duo-chat-gpt-5-2-codex": {
|
|
127
|
+
provider: "openai",
|
|
128
|
+
model: "gpt-5.2-codex",
|
|
129
|
+
openaiApiType: "responses",
|
|
130
|
+
name: "Duo Chat GPT-5.2 Codex",
|
|
131
|
+
reasoning: true,
|
|
132
|
+
input: ["text", "image"],
|
|
133
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
134
|
+
contextWindow: 272000,
|
|
135
|
+
maxTokens: 128000,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export function getModelMapping(modelId: string): GitLabModelMapping | undefined {
|
|
140
|
+
const direct = MODEL_MAPPINGS[modelId];
|
|
141
|
+
if (direct) return direct;
|
|
142
|
+
|
|
143
|
+
// Support canonical model IDs (e.g. "gpt-5-OpenAI code backend", "Anthropic model-sonnet-4-5-20250929")
|
|
144
|
+
// in addition to Duo aliases (e.g. "duo-chat-gpt-5-OpenAI code backend").
|
|
145
|
+
return Object.values(MODEL_MAPPINGS).find(mapping => mapping.model === modelId);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function getGitLabDuoModels(): Model<Api>[] {
|
|
149
|
+
return Object.entries(MODEL_MAPPINGS).map(([id, mapping]) => ({
|
|
150
|
+
id,
|
|
151
|
+
name: mapping.name,
|
|
152
|
+
api:
|
|
153
|
+
mapping.provider === "anthropic"
|
|
154
|
+
? "anthropic-messages"
|
|
155
|
+
: mapping.openaiApiType === "responses"
|
|
156
|
+
? "openai-responses"
|
|
157
|
+
: "openai-completions",
|
|
158
|
+
provider: "gitlab-duo",
|
|
159
|
+
baseUrl: mapping.provider === "anthropic" ? ANTHROPIC_PROXY_URL : OPENAI_PROXY_URL,
|
|
160
|
+
reasoning: mapping.reasoning,
|
|
161
|
+
input: [...mapping.input],
|
|
162
|
+
cost: { ...mapping.cost },
|
|
163
|
+
contextWindow: mapping.contextWindow,
|
|
164
|
+
maxTokens: mapping.maxTokens,
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface DirectAccessToken {
|
|
169
|
+
token: string;
|
|
170
|
+
headers: Record<string, string>;
|
|
171
|
+
expiresAt: number;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const directAccessCache = new Map<string, DirectAccessToken>();
|
|
175
|
+
|
|
176
|
+
async function getDirectAccessToken(
|
|
177
|
+
gitlabAccessToken: string,
|
|
178
|
+
fetchImpl: FetchImpl = fetch,
|
|
179
|
+
onStreamCreated?: () => void,
|
|
180
|
+
): Promise<DirectAccessToken> {
|
|
181
|
+
const cached = directAccessCache.get(gitlabAccessToken);
|
|
182
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
183
|
+
return cached;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
onStreamCreated?.();
|
|
187
|
+
const response = await fetchImpl(`${GITLAB_COM_URL}/api/v4/ai/third_party_agents/direct_access`, {
|
|
188
|
+
method: "POST",
|
|
189
|
+
headers: {
|
|
190
|
+
Authorization: `Bearer ${gitlabAccessToken}`,
|
|
191
|
+
"Content-Type": "application/json",
|
|
192
|
+
},
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
feature_flags: { DuoAgentPlatformNext: true },
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
const detail = await response.text();
|
|
200
|
+
if (response.status === 403) {
|
|
201
|
+
throw new Error(`GitLab Duo access denied. Ensure Duo is enabled for this account. ${detail}`);
|
|
202
|
+
}
|
|
203
|
+
throw new Error(`Failed to get GitLab Duo direct access token: ${response.status} ${detail}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const payload = (await response.json()) as { token?: string; headers?: Record<string, string> };
|
|
207
|
+
if (!payload.token || typeof payload.token !== "string") {
|
|
208
|
+
throw new Error("GitLab Duo direct access response missing token");
|
|
209
|
+
}
|
|
210
|
+
if (!payload.headers || typeof payload.headers !== "object") {
|
|
211
|
+
throw new Error("GitLab Duo direct access response missing headers");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const token: DirectAccessToken = {
|
|
215
|
+
token: payload.token,
|
|
216
|
+
headers: payload.headers,
|
|
217
|
+
expiresAt: Date.now() + DIRECT_ACCESS_TTL_MS,
|
|
218
|
+
};
|
|
219
|
+
directAccessCache.set(gitlabAccessToken, token);
|
|
220
|
+
return token;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function clearGitLabDuoDirectAccessCache(): void {
|
|
224
|
+
directAccessCache.clear();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function isGitLabDuoModel(model: Model<Api>): boolean {
|
|
228
|
+
return model.provider === "gitlab-duo";
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function streamGitLabDuo(
|
|
232
|
+
model: Model<Api>,
|
|
233
|
+
context: Context,
|
|
234
|
+
options?: SimpleStreamOptions,
|
|
235
|
+
): AssistantMessageEventStream {
|
|
236
|
+
const stream = new AssistantMessageEventStream();
|
|
237
|
+
|
|
238
|
+
(async () => {
|
|
239
|
+
try {
|
|
240
|
+
if (!options?.apiKey) {
|
|
241
|
+
throw new Error("Missing GitLab access token. Run /login gitlab-duo or set GITLAB_TOKEN.");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const mapping = getModelMapping(model.id);
|
|
245
|
+
if (!mapping) {
|
|
246
|
+
throw new Error(`Unsupported GitLab Duo model: ${model.id}`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const directAccess = await getDirectAccessToken(options.apiKey, options.fetch, options.onStreamCreated);
|
|
250
|
+
const headers = {
|
|
251
|
+
...directAccess.headers,
|
|
252
|
+
...options.headers,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const reasoningEffort = options.reasoning;
|
|
256
|
+
|
|
257
|
+
const inner =
|
|
258
|
+
mapping.provider === "anthropic"
|
|
259
|
+
? streamAnthropic(
|
|
260
|
+
{
|
|
261
|
+
...model,
|
|
262
|
+
id: mapping.model,
|
|
263
|
+
api: "anthropic-messages",
|
|
264
|
+
baseUrl: ANTHROPIC_PROXY_URL,
|
|
265
|
+
} as Model<"anthropic-messages">,
|
|
266
|
+
context,
|
|
267
|
+
copyProviderSafetyStopAdapterInvocation(options, {
|
|
268
|
+
apiKey: directAccess.token,
|
|
269
|
+
isOAuth: true,
|
|
270
|
+
temperature: options.temperature,
|
|
271
|
+
topP: options.topP,
|
|
272
|
+
topK: options.topK,
|
|
273
|
+
minP: options.minP,
|
|
274
|
+
presencePenalty: options.presencePenalty,
|
|
275
|
+
repetitionPenalty: options.repetitionPenalty,
|
|
276
|
+
maxTokens: options.maxTokens ?? Math.min(model.maxTokens, 32000),
|
|
277
|
+
signal: options.signal,
|
|
278
|
+
cacheRetention: options.cacheRetention,
|
|
279
|
+
headers,
|
|
280
|
+
maxRetryDelayMs: options.maxRetryDelayMs,
|
|
281
|
+
requestMaxRetries: options.requestMaxRetries,
|
|
282
|
+
streamMaxRetries: options.streamMaxRetries,
|
|
283
|
+
fallbackManaged: options.fallbackManaged,
|
|
284
|
+
disableProviderRetries: options.disableProviderRetries,
|
|
285
|
+
metadata: options.metadata,
|
|
286
|
+
sessionId: options.sessionId,
|
|
287
|
+
providerSessionState: options.providerSessionState,
|
|
288
|
+
onPayload: options.onPayload,
|
|
289
|
+
onStreamCreated: options.onStreamCreated,
|
|
290
|
+
attemptScope: options?.attemptScope,
|
|
291
|
+
onResponse: options.onResponse,
|
|
292
|
+
onSseEvent: options.onSseEvent,
|
|
293
|
+
fetch: options.fetch,
|
|
294
|
+
thinkingEnabled: Boolean(reasoningEffort) && model.reasoning,
|
|
295
|
+
thinkingBudgetTokens: reasoningEffort
|
|
296
|
+
? (options.thinkingBudgets?.[reasoningEffort] ?? ANTHROPIC_THINKING[reasoningEffort])
|
|
297
|
+
: undefined,
|
|
298
|
+
reasoning: reasoningEffort,
|
|
299
|
+
toolChoice: mapAnthropicToolChoice(options.toolChoice),
|
|
300
|
+
}),
|
|
301
|
+
)
|
|
302
|
+
: mapping.openaiApiType === "responses"
|
|
303
|
+
? streamOpenAIResponses(
|
|
304
|
+
{
|
|
305
|
+
...model,
|
|
306
|
+
id: mapping.model,
|
|
307
|
+
api: "openai-responses",
|
|
308
|
+
baseUrl: OPENAI_PROXY_URL,
|
|
309
|
+
} as Model<"openai-responses">,
|
|
310
|
+
context,
|
|
311
|
+
copyProviderSafetyStopAdapterInvocation(options, {
|
|
312
|
+
apiKey: directAccess.token,
|
|
313
|
+
temperature: options.temperature,
|
|
314
|
+
topP: options.topP,
|
|
315
|
+
topK: options.topK,
|
|
316
|
+
minP: options.minP,
|
|
317
|
+
presencePenalty: options.presencePenalty,
|
|
318
|
+
repetitionPenalty: options.repetitionPenalty,
|
|
319
|
+
maxTokens: options.maxTokens ?? model.maxTokens,
|
|
320
|
+
signal: options.signal,
|
|
321
|
+
cacheRetention: options.cacheRetention,
|
|
322
|
+
headers,
|
|
323
|
+
maxRetryDelayMs: options.maxRetryDelayMs,
|
|
324
|
+
requestMaxRetries: options.requestMaxRetries,
|
|
325
|
+
streamMaxRetries: options.streamMaxRetries,
|
|
326
|
+
fallbackManaged: options.fallbackManaged,
|
|
327
|
+
disableProviderRetries: options.disableProviderRetries,
|
|
328
|
+
metadata: options.metadata,
|
|
329
|
+
sessionId: options.sessionId,
|
|
330
|
+
providerSessionState: options.providerSessionState,
|
|
331
|
+
onPayload: options.onPayload,
|
|
332
|
+
onStreamCreated: options.onStreamCreated,
|
|
333
|
+
attemptScope: options?.attemptScope,
|
|
334
|
+
onResponse: options.onResponse,
|
|
335
|
+
onSseEvent: options.onSseEvent,
|
|
336
|
+
fetch: options.fetch,
|
|
337
|
+
reasoning: reasoningEffort,
|
|
338
|
+
toolChoice: options.toolChoice,
|
|
339
|
+
}) satisfies OpenAIResponsesOptions,
|
|
340
|
+
)
|
|
341
|
+
: streamOpenAICompletions(
|
|
342
|
+
{
|
|
343
|
+
...model,
|
|
344
|
+
id: mapping.model,
|
|
345
|
+
api: "openai-completions",
|
|
346
|
+
baseUrl: OPENAI_PROXY_URL,
|
|
347
|
+
} as Model<"openai-completions">,
|
|
348
|
+
context,
|
|
349
|
+
copyProviderSafetyStopAdapterInvocation(options, {
|
|
350
|
+
apiKey: directAccess.token,
|
|
351
|
+
temperature: options.temperature,
|
|
352
|
+
topP: options.topP,
|
|
353
|
+
topK: options.topK,
|
|
354
|
+
minP: options.minP,
|
|
355
|
+
presencePenalty: options.presencePenalty,
|
|
356
|
+
repetitionPenalty: options.repetitionPenalty,
|
|
357
|
+
maxTokens: options.maxTokens ?? model.maxTokens,
|
|
358
|
+
signal: options.signal,
|
|
359
|
+
cacheRetention: options.cacheRetention,
|
|
360
|
+
headers,
|
|
361
|
+
maxRetryDelayMs: options.maxRetryDelayMs,
|
|
362
|
+
requestMaxRetries: options.requestMaxRetries,
|
|
363
|
+
streamMaxRetries: options.streamMaxRetries,
|
|
364
|
+
fallbackManaged: options.fallbackManaged,
|
|
365
|
+
disableProviderRetries: options.disableProviderRetries,
|
|
366
|
+
metadata: options.metadata,
|
|
367
|
+
sessionId: options.sessionId,
|
|
368
|
+
providerSessionState: options.providerSessionState,
|
|
369
|
+
onPayload: options.onPayload,
|
|
370
|
+
onStreamCreated: options.onStreamCreated,
|
|
371
|
+
attemptScope: options?.attemptScope,
|
|
372
|
+
onResponse: options.onResponse,
|
|
373
|
+
onSseEvent: options.onSseEvent,
|
|
374
|
+
fetch: options.fetch,
|
|
375
|
+
reasoning: reasoningEffort,
|
|
376
|
+
toolChoice: options.toolChoice,
|
|
377
|
+
}) satisfies OpenAICompletionsOptions,
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
for await (const event of inner) {
|
|
381
|
+
stream.push(event);
|
|
382
|
+
}
|
|
383
|
+
} catch (err) {
|
|
384
|
+
stream.push({
|
|
385
|
+
type: "error",
|
|
386
|
+
reason: "error",
|
|
387
|
+
error: createProviderErrorMessage(model, err),
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
})();
|
|
391
|
+
|
|
392
|
+
return stream;
|
|
393
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Default Credentials (ADC) resolution for Vertex AI.
|
|
3
|
+
*
|
|
4
|
+
* Replaces `google-auth-library` with a direct WebCrypto + REST implementation.
|
|
5
|
+
* Sources, in priority order:
|
|
6
|
+
* 1. `GOOGLE_APPLICATION_CREDENTIALS` env → file with `type: "service_account"` (RS256 JWT exchange)
|
|
7
|
+
* or `type: "authorized_user"` (refresh-token exchange).
|
|
8
|
+
* 2. `~/.config/gcloud/application_default_credentials.json` (user ADC, same authorized_user flow).
|
|
9
|
+
* 3. GCE / Cloud Run metadata server (`metadata.google.internal`).
|
|
10
|
+
*
|
|
11
|
+
* Tokens are cached per source key and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` before expiry
|
|
12
|
+
* (default 60s). Concurrent callers waiting on a refresh share the same in-flight promise.
|
|
13
|
+
*/
|
|
14
|
+
import type { FetchImpl } from "../types";
|
|
15
|
+
/** Test seam: the ADC credentials file path as resolved from trusted env. */
|
|
16
|
+
export declare function resolveAdcCredentialsPathForTest(): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a Bearer access token suitable for the `Authorization` header on Vertex AI calls.
|
|
19
|
+
* The token is cached in module scope and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` ms before it expires.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getVertexAccessToken(options?: {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
fetch?: FetchImpl;
|
|
24
|
+
}): Promise<string>;
|
|
25
|
+
/** Test seam: clears every cached token. */
|
|
26
|
+
export declare function __resetVertexTokenCache(): void;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Default Credentials (ADC) resolution for Vertex AI.
|
|
3
|
+
*
|
|
4
|
+
* Replaces `google-auth-library` with a direct WebCrypto + REST implementation.
|
|
5
|
+
* Sources, in priority order:
|
|
6
|
+
* 1. `GOOGLE_APPLICATION_CREDENTIALS` env → file with `type: "service_account"` (RS256 JWT exchange)
|
|
7
|
+
* or `type: "authorized_user"` (refresh-token exchange).
|
|
8
|
+
* 2. `~/.config/gcloud/application_default_credentials.json` (user ADC, same authorized_user flow).
|
|
9
|
+
* 3. GCE / Cloud Run metadata server (`metadata.google.internal`).
|
|
10
|
+
*
|
|
11
|
+
* Tokens are cached per source key and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` before expiry
|
|
12
|
+
* (default 60s). Concurrent callers waiting on a refresh share the same in-flight promise.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { Buffer } from "node:buffer";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
import { $credentialEnv, $envpos, getTrustedHomeDir, isEnoent, logger } from "@vib-rato/utils";
|
|
18
|
+
import type { FetchImpl } from "../types";
|
|
19
|
+
|
|
20
|
+
const OAUTH_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
21
|
+
const METADATA_TOKEN_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
|
|
22
|
+
const CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
|
|
23
|
+
const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
24
|
+
|
|
25
|
+
interface CachedToken {
|
|
26
|
+
token: string;
|
|
27
|
+
expiresAtMs: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ServiceAccountCredentials {
|
|
31
|
+
type: "service_account";
|
|
32
|
+
client_email: string;
|
|
33
|
+
private_key: string;
|
|
34
|
+
private_key_id?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface AuthorizedUserCredentials {
|
|
38
|
+
type: "authorized_user";
|
|
39
|
+
client_id: string;
|
|
40
|
+
client_secret: string;
|
|
41
|
+
refresh_token: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type AdcFileCredentials = ServiceAccountCredentials | AuthorizedUserCredentials;
|
|
45
|
+
|
|
46
|
+
interface TokenResponse {
|
|
47
|
+
access_token: string;
|
|
48
|
+
expires_in: number;
|
|
49
|
+
token_type?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const tokenCache = new Map<string, CachedToken>();
|
|
53
|
+
const inflight = new Map<string, Promise<string>>();
|
|
54
|
+
|
|
55
|
+
function getRefreshSkewMs(): number {
|
|
56
|
+
return $envpos("GOOGLE_VERTEX_REFRESH_SKEW_MS", 60_000);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function userAdcPath(): string {
|
|
60
|
+
return path.join(getTrustedHomeDir(), ".config", "gcloud", "application_default_credentials.json");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function readJsonFile<T>(filePath: string): Promise<T | undefined> {
|
|
64
|
+
try {
|
|
65
|
+
return (await Bun.file(filePath).json()) as T;
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if (isEnoent(err)) return undefined;
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Test seam: the ADC credentials file path as resolved from trusted env. */
|
|
73
|
+
export function resolveAdcCredentialsPathForTest(): string | undefined {
|
|
74
|
+
return $credentialEnv("GOOGLE_APPLICATION_CREDENTIALS");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function loadAdcCredentials(): Promise<{ source: string; creds: AdcFileCredentials } | undefined> {
|
|
78
|
+
// Trusted sources only: this path is read as service-account / authorized-user
|
|
79
|
+
// credentials and exchanged for a Google access token, so whatever can set it
|
|
80
|
+
// chooses the identity the agent authenticates as. `Bun.env` is `process.env`
|
|
81
|
+
// and the env module merges the caller's `cwd/.env` into it, so reading it
|
|
82
|
+
// there would let repository content point this at a key file it ships.
|
|
83
|
+
// `stream.ts` already resolves the same variable through `$credentialEnv`.
|
|
84
|
+
const gacPath = $credentialEnv("GOOGLE_APPLICATION_CREDENTIALS");
|
|
85
|
+
if (gacPath) {
|
|
86
|
+
const creds = await readJsonFile<AdcFileCredentials>(gacPath);
|
|
87
|
+
if (!creds) {
|
|
88
|
+
throw new Error(`GOOGLE_APPLICATION_CREDENTIALS points to a missing file: ${gacPath}`);
|
|
89
|
+
}
|
|
90
|
+
return { source: `gac:${gacPath}`, creds };
|
|
91
|
+
}
|
|
92
|
+
const userPath = userAdcPath();
|
|
93
|
+
const creds = await readJsonFile<AdcFileCredentials>(userPath);
|
|
94
|
+
if (creds) return { source: `user:${userPath}`, creds };
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function base64UrlEncode(bytes: Uint8Array | string): string {
|
|
99
|
+
const buf = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : bytes;
|
|
100
|
+
return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString("base64url");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function pemToPkcs8(pem: string): Uint8Array<ArrayBuffer> {
|
|
104
|
+
const body = pem
|
|
105
|
+
.replace(/-----BEGIN [^-]+-----/g, "")
|
|
106
|
+
.replace(/-----END [^-]+-----/g, "")
|
|
107
|
+
.replace(/\s+/g, "");
|
|
108
|
+
if (!body) throw new Error("Invalid PEM: empty body");
|
|
109
|
+
return Uint8Array.fromBase64(body);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function signJwtRs256(claims: Record<string, unknown>, privateKeyPem: string, keyId?: string): Promise<string> {
|
|
113
|
+
const header: Record<string, unknown> = { alg: "RS256", typ: "JWT" };
|
|
114
|
+
if (keyId) header.kid = keyId;
|
|
115
|
+
const payload = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(claims))}`;
|
|
116
|
+
|
|
117
|
+
const key = await globalThis.crypto.subtle.importKey(
|
|
118
|
+
"pkcs8",
|
|
119
|
+
pemToPkcs8(privateKeyPem),
|
|
120
|
+
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
|
|
121
|
+
false,
|
|
122
|
+
["sign"],
|
|
123
|
+
);
|
|
124
|
+
const signature = new Uint8Array(
|
|
125
|
+
await globalThis.crypto.subtle.sign("RSASSA-PKCS1-v1_5", key, new TextEncoder().encode(payload)),
|
|
126
|
+
);
|
|
127
|
+
return `${payload}.${base64UrlEncode(signature)}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function exchangeJwtForToken(
|
|
131
|
+
creds: ServiceAccountCredentials,
|
|
132
|
+
signal: AbortSignal | undefined,
|
|
133
|
+
fetchImpl: FetchImpl,
|
|
134
|
+
): Promise<TokenResponse> {
|
|
135
|
+
const now = Math.floor(Date.now() / 1000);
|
|
136
|
+
const assertion = await signJwtRs256(
|
|
137
|
+
{
|
|
138
|
+
iss: creds.client_email,
|
|
139
|
+
scope: CLOUD_PLATFORM_SCOPE,
|
|
140
|
+
aud: OAUTH_TOKEN_URL,
|
|
141
|
+
exp: now + 3600,
|
|
142
|
+
iat: now,
|
|
143
|
+
},
|
|
144
|
+
creds.private_key,
|
|
145
|
+
creds.private_key_id,
|
|
146
|
+
);
|
|
147
|
+
const body = new URLSearchParams({ grant_type: JWT_BEARER_GRANT, assertion });
|
|
148
|
+
return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function exchangeRefreshToken(
|
|
152
|
+
creds: AuthorizedUserCredentials,
|
|
153
|
+
signal: AbortSignal | undefined,
|
|
154
|
+
fetchImpl: FetchImpl,
|
|
155
|
+
): Promise<TokenResponse> {
|
|
156
|
+
const body = new URLSearchParams({
|
|
157
|
+
client_id: creds.client_id,
|
|
158
|
+
client_secret: creds.client_secret,
|
|
159
|
+
refresh_token: creds.refresh_token,
|
|
160
|
+
grant_type: "refresh_token",
|
|
161
|
+
});
|
|
162
|
+
return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function fetchMetadataToken(
|
|
166
|
+
signal: AbortSignal | undefined,
|
|
167
|
+
fetchImpl: FetchImpl,
|
|
168
|
+
): Promise<TokenResponse | undefined> {
|
|
169
|
+
const timeout = AbortSignal.timeout(2000);
|
|
170
|
+
const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
171
|
+
try {
|
|
172
|
+
const response = await fetchImpl(METADATA_TOKEN_URL, {
|
|
173
|
+
method: "GET",
|
|
174
|
+
headers: { "Metadata-Flavor": "Google" },
|
|
175
|
+
signal: combined,
|
|
176
|
+
});
|
|
177
|
+
if (!response.ok) return undefined;
|
|
178
|
+
return (await response.json()) as TokenResponse;
|
|
179
|
+
} catch {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function postForToken(
|
|
185
|
+
url: string,
|
|
186
|
+
body: URLSearchParams,
|
|
187
|
+
signal: AbortSignal | undefined,
|
|
188
|
+
fetchImpl: FetchImpl,
|
|
189
|
+
): Promise<TokenResponse> {
|
|
190
|
+
const response = await fetchImpl(url, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
193
|
+
body: body.toString(),
|
|
194
|
+
signal,
|
|
195
|
+
});
|
|
196
|
+
if (!response.ok) {
|
|
197
|
+
const detail = await response.text().catch(() => "");
|
|
198
|
+
throw new Error(`Google OAuth token exchange failed (${response.status}): ${detail}`);
|
|
199
|
+
}
|
|
200
|
+
return (await response.json()) as TokenResponse;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function resolveAccessTokenUncached(
|
|
204
|
+
signal: AbortSignal | undefined,
|
|
205
|
+
fetchImpl: FetchImpl,
|
|
206
|
+
): Promise<{ source: string; token: TokenResponse }> {
|
|
207
|
+
const adc = await loadAdcCredentials();
|
|
208
|
+
if (adc) {
|
|
209
|
+
const token =
|
|
210
|
+
adc.creds.type === "service_account"
|
|
211
|
+
? await exchangeJwtForToken(adc.creds, signal, fetchImpl)
|
|
212
|
+
: await exchangeRefreshToken(adc.creds, signal, fetchImpl);
|
|
213
|
+
return { source: adc.source, token };
|
|
214
|
+
}
|
|
215
|
+
const metadata = await fetchMetadataToken(signal, fetchImpl);
|
|
216
|
+
if (metadata) return { source: "metadata", token: metadata };
|
|
217
|
+
throw new Error(
|
|
218
|
+
"Vertex AI requires Application Default Credentials. Set GOOGLE_APPLICATION_CREDENTIALS, run `gcloud auth application-default login`, or run on a GCE/Cloud Run instance with a service account.",
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Returns a Bearer access token suitable for the `Authorization` header on Vertex AI calls.
|
|
224
|
+
* The token is cached in module scope and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` ms before it expires.
|
|
225
|
+
*/
|
|
226
|
+
export async function getVertexAccessToken(options?: { signal?: AbortSignal; fetch?: FetchImpl }): Promise<string> {
|
|
227
|
+
const fetchImpl = options?.fetch ?? globalThis.fetch.bind(globalThis);
|
|
228
|
+
const skew = getRefreshSkewMs();
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
|
|
231
|
+
// Best-effort cache key probe: we don't know the source until we resolve, but cached entries
|
|
232
|
+
// are keyed by their resolved source. Try every cached source first.
|
|
233
|
+
for (const [source, cached] of tokenCache) {
|
|
234
|
+
if (cached.expiresAtMs - skew > now) return cached.token;
|
|
235
|
+
// expired entry — drop and re-resolve
|
|
236
|
+
tokenCache.delete(source);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const cacheKey = "vertex-adc";
|
|
240
|
+
const existing = inflight.get(cacheKey);
|
|
241
|
+
if (existing) return existing;
|
|
242
|
+
|
|
243
|
+
const promise = (async () => {
|
|
244
|
+
try {
|
|
245
|
+
const { source, token } = await resolveAccessTokenUncached(options?.signal, fetchImpl);
|
|
246
|
+
const expiresAtMs = Date.now() + Math.max(0, token.expires_in * 1000);
|
|
247
|
+
tokenCache.set(source, { token: token.access_token, expiresAtMs });
|
|
248
|
+
logger.debug("vertex.adc acquired access token", { source, expiresInSec: token.expires_in });
|
|
249
|
+
return token.access_token;
|
|
250
|
+
} finally {
|
|
251
|
+
inflight.delete(cacheKey);
|
|
252
|
+
}
|
|
253
|
+
})();
|
|
254
|
+
inflight.set(cacheKey, promise);
|
|
255
|
+
return promise;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Test seam: clears every cached token. */
|
|
259
|
+
export function __resetVertexTokenCache(): void {
|
|
260
|
+
tokenCache.clear();
|
|
261
|
+
inflight.clear();
|
|
262
|
+
}
|