@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,59 @@
|
|
|
1
|
+
export type RawHttpRequestDump = {
|
|
2
|
+
provider: string;
|
|
3
|
+
api: string;
|
|
4
|
+
model: string;
|
|
5
|
+
method?: string;
|
|
6
|
+
url?: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
body?: unknown;
|
|
9
|
+
diagnostics?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export type CapturedHttpErrorResponse = {
|
|
12
|
+
status: number;
|
|
13
|
+
headers?: Headers;
|
|
14
|
+
bodyText?: string;
|
|
15
|
+
bodyJson?: unknown;
|
|
16
|
+
};
|
|
17
|
+
/** Whether `message` (from a 400 response) signals an unavailable/unknown model. */
|
|
18
|
+
export declare function isModelUnavailableError(message: string, error: unknown): boolean;
|
|
19
|
+
/** Actionable guidance for selecting an available model/provider. */
|
|
20
|
+
export declare function formatModelUnavailableGuidance(dump: RawHttpRequestDump | undefined): string;
|
|
21
|
+
/** Directory holding the retained HTTP 400 dumps. */
|
|
22
|
+
export declare function httpRequestDumpDir(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Drop the oldest dumps beyond the cap. Best-effort: diagnostics must never turn
|
|
25
|
+
* a request failure into a second failure, so every step swallows its error.
|
|
26
|
+
*
|
|
27
|
+
* File names are `${Date.now()}-${hash}.json`, so a lexical sort is chronological
|
|
28
|
+
* for the millisecond timestamps this writer produces.
|
|
29
|
+
*/
|
|
30
|
+
export declare function pruneHttpRequestDumps(dir?: string): Promise<number>;
|
|
31
|
+
export declare function appendRawHttpRequestDumpFor400(message: string, error: unknown, dump: RawHttpRequestDump | undefined): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Name the failed connection when the request never produced an HTTP status.
|
|
34
|
+
*
|
|
35
|
+
* Bun raises DNS and socket failures as a bare `Error` whose message is a
|
|
36
|
+
* standalone hint ("Was there a typo in the url or port?", "Unable to connect.
|
|
37
|
+
* Is the computer able to access the url?") while the actionable facts live on
|
|
38
|
+
* `code` and `path`. Those properties are dropped when only `message` reaches
|
|
39
|
+
* the assistant message, so a provider outage, a local DNS failure, and a
|
|
40
|
+
* mistyped custom base URL all render as the same context-free sentence.
|
|
41
|
+
* Appending the code and the target URL tells the user which host failed and
|
|
42
|
+
* whether the fault is theirs.
|
|
43
|
+
*/
|
|
44
|
+
export declare function appendTransportFailureContext(message: string, error: unknown, rawRequestDump: RawHttpRequestDump | undefined): string;
|
|
45
|
+
export declare function finalizeErrorMessage(error: unknown, rawRequestDump: RawHttpRequestDump | undefined, capturedErrorResponse?: CapturedHttpErrorResponse): Promise<string>;
|
|
46
|
+
export declare function withHttpStatus(error: unknown, status: number): Error;
|
|
47
|
+
/**
|
|
48
|
+
* Rewrite error message for GitHub Copilot request failures.
|
|
49
|
+
* Must run AFTER finalizeErrorMessage since it replaces the message entirely.
|
|
50
|
+
*
|
|
51
|
+
* 400 `model_not_supported` = Copilot routing rollout gap for our OAuth client.
|
|
52
|
+
* A preview model (gpt-5.3-OpenAI code backend, gpt-5.4*, ...) flaps between 200 and
|
|
53
|
+
* 400 because only some of Copilot's backends have the model. After the
|
|
54
|
+
* in-request retry exhausts, surface guidance rather than the raw error.
|
|
55
|
+
* 401 = token invalid/expired → credential removal is safe, prompt re-login.
|
|
56
|
+
* 403 = token valid but access denied (plan, model policy, org restriction) →
|
|
57
|
+
* do NOT reuse the auth-failed string (which triggers credential removal).
|
|
58
|
+
*/
|
|
59
|
+
export declare function rewriteCopilotError(errorMessage: string, error: unknown, provider: string): string;
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { APP_NAME, extractHttpStatusFromError, getLogsDir } from "@vib-rato/utils";
|
|
4
|
+
import { isCopilotTransientModelError } from "./retry.js";
|
|
5
|
+
import { formatErrorMessageWithRetryAfter } from "./retry-after.js";
|
|
6
|
+
|
|
7
|
+
export type RawHttpRequestDump = {
|
|
8
|
+
provider: string;
|
|
9
|
+
api: string;
|
|
10
|
+
model: string;
|
|
11
|
+
method?: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
body?: unknown;
|
|
15
|
+
diagnostics?: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type CapturedHttpErrorResponse = {
|
|
19
|
+
status: number;
|
|
20
|
+
headers?: Headers;
|
|
21
|
+
bodyText?: string;
|
|
22
|
+
bodyJson?: unknown;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type ErrorWithStatus = {
|
|
26
|
+
status?: unknown;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const SENSITIVE_HEADERS = ["authorization", "x-api-key", "api-key", "cookie", "set-cookie", "proxy-authorization"];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Connection-level failure codes, meaning the request never reached the
|
|
33
|
+
* provider and no HTTP status exists. Bun reports the first group for `fetch`;
|
|
34
|
+
* the `E*`/`UND_ERR_*` group comes from Node-style DNS and socket errors.
|
|
35
|
+
*
|
|
36
|
+
* Deliberately excludes aborts and TLS/certificate codes: an abort is a
|
|
37
|
+
* user/watchdog outcome with its own display path, and its message must keep
|
|
38
|
+
* matching the abort normalizers in `modes/utils/abort-message`.
|
|
39
|
+
*/
|
|
40
|
+
const TRANSPORT_FAILURE_CODES: ReadonlySet<string> = new Set([
|
|
41
|
+
"ConnectionClosed",
|
|
42
|
+
"ConnectionRefused",
|
|
43
|
+
"ConnectionReset",
|
|
44
|
+
"ConnectionTimeout",
|
|
45
|
+
"FailedToOpenSocket",
|
|
46
|
+
"HTTP2Unsupported",
|
|
47
|
+
"EAI_AGAIN",
|
|
48
|
+
"ECONNREFUSED",
|
|
49
|
+
"ECONNRESET",
|
|
50
|
+
"EHOSTUNREACH",
|
|
51
|
+
"ENETUNREACH",
|
|
52
|
+
"ENOTFOUND",
|
|
53
|
+
"EPIPE",
|
|
54
|
+
"ETIMEDOUT",
|
|
55
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
56
|
+
"UND_ERR_SOCKET",
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Privacy note appended next to a saved raw HTTP request dump. The dump is
|
|
61
|
+
* sanitized (secrets/thinking redacted) but can still contain prompt content
|
|
62
|
+
* and request metadata, so we explicitly discourage pasting it into public
|
|
63
|
+
* channels (issue #438).
|
|
64
|
+
*/
|
|
65
|
+
const RAW_HTTP_REQUEST_PRIVACY_NOTE =
|
|
66
|
+
"note: this local file is for your own debugging and may contain prompt content or request metadata — review it before sharing and do not paste its contents into public channels (issues, Discord, etc.).";
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Patterns that indicate the configured model is unavailable on the provider
|
|
70
|
+
* (e.g. OpenAI's "The requested model '...' does not exist."). Used to surface
|
|
71
|
+
* actionable model/provider guidance instead of only a raw 400 + log path.
|
|
72
|
+
*/
|
|
73
|
+
const MODEL_UNAVAILABLE_PATTERNS: readonly RegExp[] = [
|
|
74
|
+
/\bmodel\b[^\n]*\bdoes not exist\b/i,
|
|
75
|
+
/\bdoes not exist\b[^\n]*\bmodel\b/i,
|
|
76
|
+
/\bmodel\b[^\n]*\b(not found|unavailable|not supported|no access|does not have access)\b/i,
|
|
77
|
+
/\b(unknown|unsupported|invalid)\s+model\b/i,
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
/** Whether `message` (from a 400 response) signals an unavailable/unknown model. */
|
|
81
|
+
export function isModelUnavailableError(message: string, error: unknown): boolean {
|
|
82
|
+
if (extractHttpStatusFromError(error) !== 400) return false;
|
|
83
|
+
return MODEL_UNAVAILABLE_PATTERNS.some(pattern => pattern.test(message));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Actionable guidance for selecting an available model/provider. */
|
|
87
|
+
export function formatModelUnavailableGuidance(dump: RawHttpRequestDump | undefined): string {
|
|
88
|
+
const modelPart = dump?.model ? ` '${dump.model}'` : "";
|
|
89
|
+
const providerPart = dump?.provider ? ` on provider '${dump.provider}'` : "";
|
|
90
|
+
return [
|
|
91
|
+
`The configured model${modelPart}${providerPart} is not available on this account/provider.`,
|
|
92
|
+
"Pick an available model before retrying:",
|
|
93
|
+
` • List available models: ${APP_NAME} --list-models`,
|
|
94
|
+
` • Run with a model: ${APP_NAME} --model <model>`,
|
|
95
|
+
` • Configure a provider: ${APP_NAME} setup provider`,
|
|
96
|
+
].join("\n");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Cap on retained HTTP 400 request dumps.
|
|
101
|
+
*
|
|
102
|
+
* Each dump carries the full sanitized request body, so they are large: a
|
|
103
|
+
* developer machine accumulated 27,249 files totalling 7.0 GB, averaging 264 KB
|
|
104
|
+
* each, because nothing ever removed them. The rotating application log already
|
|
105
|
+
* bounds itself (`maxSize: 10m`, `maxFiles: 5`); these diagnostics get the same
|
|
106
|
+
* treatment so the newest failures stay available without unbounded growth.
|
|
107
|
+
*/
|
|
108
|
+
const MAX_RETAINED_DUMPS = 50;
|
|
109
|
+
|
|
110
|
+
/** Directory holding the retained HTTP 400 dumps. */
|
|
111
|
+
export function httpRequestDumpDir(): string {
|
|
112
|
+
return path.join(getLogsDir(), "http-400-requests");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Drop the oldest dumps beyond the cap. Best-effort: diagnostics must never turn
|
|
117
|
+
* a request failure into a second failure, so every step swallows its error.
|
|
118
|
+
*
|
|
119
|
+
* File names are `${Date.now()}-${hash}.json`, so a lexical sort is chronological
|
|
120
|
+
* for the millisecond timestamps this writer produces.
|
|
121
|
+
*/
|
|
122
|
+
export async function pruneHttpRequestDumps(dir: string = httpRequestDumpDir()): Promise<number> {
|
|
123
|
+
const entries = await fs.readdir(dir).catch(() => undefined);
|
|
124
|
+
if (!entries) return 0;
|
|
125
|
+
|
|
126
|
+
const dumps = entries.filter(name => name.endsWith(".json")).sort();
|
|
127
|
+
if (dumps.length <= MAX_RETAINED_DUMPS) return 0;
|
|
128
|
+
|
|
129
|
+
let removed = 0;
|
|
130
|
+
for (const name of dumps.slice(0, dumps.length - MAX_RETAINED_DUMPS)) {
|
|
131
|
+
if (
|
|
132
|
+
await fs.rm(path.join(dir, name), { force: true }).then(
|
|
133
|
+
() => true,
|
|
134
|
+
() => false,
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
removed++;
|
|
138
|
+
}
|
|
139
|
+
return removed;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export async function appendRawHttpRequestDumpFor400(
|
|
143
|
+
message: string,
|
|
144
|
+
error: unknown,
|
|
145
|
+
dump: RawHttpRequestDump | undefined,
|
|
146
|
+
): Promise<string> {
|
|
147
|
+
if (!dump || extractHttpStatusFromError(error) !== 400) {
|
|
148
|
+
return message;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const sanitizedDump = sanitizeDump(dump);
|
|
152
|
+
const fileName = `${Date.now()}-${Bun.hash(JSON.stringify(sanitizedDump)).toString(36)}.json`;
|
|
153
|
+
const dumpDir = httpRequestDumpDir();
|
|
154
|
+
const filePath = path.join(dumpDir, fileName);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await Bun.write(filePath, `${JSON.stringify(sanitizedDump, null, 2)}\n`);
|
|
158
|
+
await pruneHttpRequestDumps(dumpDir);
|
|
159
|
+
return `${message}\nraw-http-request=${filePath}\n${RAW_HTTP_REQUEST_PRIVACY_NOTE}`;
|
|
160
|
+
} catch (writeError) {
|
|
161
|
+
const writeMessage = writeError instanceof Error ? writeError.message : String(writeError);
|
|
162
|
+
return `${message}\nraw-http-request-save-failed=${writeMessage}`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Origin and path of `value`, dropping query, fragment, and credentials so a
|
|
167
|
+
* key carried in the request URL (Google `?key=`, signed URLs) never lands in
|
|
168
|
+
* a user-visible error string. */
|
|
169
|
+
function redactRequestUrl(value: unknown): string | undefined {
|
|
170
|
+
if (typeof value !== "string" || value.trim().length === 0) return undefined;
|
|
171
|
+
try {
|
|
172
|
+
const url = new URL(value);
|
|
173
|
+
return `${url.origin}${url.pathname}`;
|
|
174
|
+
} catch {
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function findTransportFailure(error: unknown, depth: number): { code: string; url?: string } | undefined {
|
|
180
|
+
if (!error || typeof error !== "object" || depth > 2) return undefined;
|
|
181
|
+
const info = error as { code?: unknown; path?: unknown; url?: unknown; cause?: unknown };
|
|
182
|
+
if (typeof info.code === "string" && TRANSPORT_FAILURE_CODES.has(info.code)) {
|
|
183
|
+
return { code: info.code, url: redactRequestUrl(info.path) ?? redactRequestUrl(info.url) };
|
|
184
|
+
}
|
|
185
|
+
return findTransportFailure(info.cause, depth + 1);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Name the failed connection when the request never produced an HTTP status.
|
|
190
|
+
*
|
|
191
|
+
* Bun raises DNS and socket failures as a bare `Error` whose message is a
|
|
192
|
+
* standalone hint ("Was there a typo in the url or port?", "Unable to connect.
|
|
193
|
+
* Is the computer able to access the url?") while the actionable facts live on
|
|
194
|
+
* `code` and `path`. Those properties are dropped when only `message` reaches
|
|
195
|
+
* the assistant message, so a provider outage, a local DNS failure, and a
|
|
196
|
+
* mistyped custom base URL all render as the same context-free sentence.
|
|
197
|
+
* Appending the code and the target URL tells the user which host failed and
|
|
198
|
+
* whether the fault is theirs.
|
|
199
|
+
*/
|
|
200
|
+
export function appendTransportFailureContext(
|
|
201
|
+
message: string,
|
|
202
|
+
error: unknown,
|
|
203
|
+
rawRequestDump: RawHttpRequestDump | undefined,
|
|
204
|
+
): string {
|
|
205
|
+
if (extractHttpStatusFromError(error) !== undefined) return message;
|
|
206
|
+
const failure = findTransportFailure(error, 0);
|
|
207
|
+
if (!failure) return message;
|
|
208
|
+
|
|
209
|
+
const url = failure.url ?? redactRequestUrl(rawRequestDump?.url);
|
|
210
|
+
const context = url ? `transport=${failure.code} url=${url}` : `transport=${failure.code}`;
|
|
211
|
+
return message.includes(context) ? message : `${message} (${context})`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export async function finalizeErrorMessage(
|
|
215
|
+
error: unknown,
|
|
216
|
+
rawRequestDump: RawHttpRequestDump | undefined,
|
|
217
|
+
capturedErrorResponse?: CapturedHttpErrorResponse,
|
|
218
|
+
): Promise<string> {
|
|
219
|
+
let message = formatErrorMessageWithRetryAfter(error, capturedErrorResponse?.headers);
|
|
220
|
+
const capturedMessage = formatCapturedHttpError(capturedErrorResponse);
|
|
221
|
+
if (capturedMessage) {
|
|
222
|
+
if (/\bstatus code\s*\(no body\)/i.test(message)) {
|
|
223
|
+
message = `${capturedErrorResponse?.status ?? "HTTP"} status code: ${capturedMessage}`;
|
|
224
|
+
} else if (!message.includes(capturedMessage)) {
|
|
225
|
+
message = `${message}\n${capturedMessage}`;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (isModelUnavailableError(message, error)) {
|
|
229
|
+
message = `${message}\n\n${formatModelUnavailableGuidance(rawRequestDump)}`;
|
|
230
|
+
}
|
|
231
|
+
message = appendTransportFailureContext(message, error, rawRequestDump);
|
|
232
|
+
return appendRawHttpRequestDumpFor400(message, error, rawRequestDump);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function withHttpStatus(error: unknown, status: number): Error {
|
|
236
|
+
const wrapped = error instanceof Error ? error : new Error(String(error));
|
|
237
|
+
(wrapped as ErrorWithStatus).status = status;
|
|
238
|
+
return wrapped;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Rewrite error message for GitHub Copilot request failures.
|
|
243
|
+
* Must run AFTER finalizeErrorMessage since it replaces the message entirely.
|
|
244
|
+
*
|
|
245
|
+
* 400 `model_not_supported` = Copilot routing rollout gap for our OAuth client.
|
|
246
|
+
* A preview model (gpt-5.3-OpenAI code backend, gpt-5.4*, ...) flaps between 200 and
|
|
247
|
+
* 400 because only some of Copilot's backends have the model. After the
|
|
248
|
+
* in-request retry exhausts, surface guidance rather than the raw error.
|
|
249
|
+
* 401 = token invalid/expired → credential removal is safe, prompt re-login.
|
|
250
|
+
* 403 = token valid but access denied (plan, model policy, org restriction) →
|
|
251
|
+
* do NOT reuse the auth-failed string (which triggers credential removal).
|
|
252
|
+
*/
|
|
253
|
+
export function rewriteCopilotError(errorMessage: string, error: unknown, provider: string): string {
|
|
254
|
+
if (provider !== "github-copilot") return errorMessage;
|
|
255
|
+
const status = extractHttpStatusFromError(error);
|
|
256
|
+
if (status === 401) {
|
|
257
|
+
return `GitHub Copilot authentication failed (HTTP 401). Your token may have been revoked. Please re-login with /login github-copilot`;
|
|
258
|
+
}
|
|
259
|
+
if (status === 403) {
|
|
260
|
+
return `GitHub Copilot access denied (HTTP 403). Your account may not have access to this model or feature. Check your Copilot plan or model policy settings.`;
|
|
261
|
+
}
|
|
262
|
+
if (isCopilotTransientModelError(error)) {
|
|
263
|
+
return `GitHub Copilot rejected this model (HTTP 400 model_not_supported) after retries. This is a known intermittent rollout gap for preview models on OAuth clients other than VS Code. Try again in a few seconds, switch to a GA model (gpt-5-mini, gpt-5.2), or run this model from VS Code.`;
|
|
264
|
+
}
|
|
265
|
+
return errorMessage;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function sanitizeDump(dump: RawHttpRequestDump): RawHttpRequestDump {
|
|
269
|
+
return {
|
|
270
|
+
...dump,
|
|
271
|
+
url: redactRequestUrl(dump.url),
|
|
272
|
+
headers: redactHeaders(dump.headers),
|
|
273
|
+
body: sanitizeDumpBody(dump.body),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function sanitizeDumpBody(value: unknown): unknown {
|
|
278
|
+
if (Array.isArray(value)) {
|
|
279
|
+
return value.map(item => sanitizeDumpBody(item));
|
|
280
|
+
}
|
|
281
|
+
if (!isObject(value)) {
|
|
282
|
+
return value;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const type = typeof value.type === "string" ? value.type : undefined;
|
|
286
|
+
const redactedKeys = getRedactedBodyKeys(type);
|
|
287
|
+
const sanitized: Record<string, unknown> = {};
|
|
288
|
+
for (const [key, property] of Object.entries(value)) {
|
|
289
|
+
if (redactedKeys.has(key)) {
|
|
290
|
+
sanitized[key] = "[redacted]";
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
sanitized[key] = sanitizeDumpBody(property);
|
|
294
|
+
}
|
|
295
|
+
return sanitized;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function getRedactedBodyKeys(type: string | undefined): Set<string> {
|
|
299
|
+
const keys = new Set<string>();
|
|
300
|
+
if (type === "thinking") {
|
|
301
|
+
keys.add("thinking");
|
|
302
|
+
keys.add("signature");
|
|
303
|
+
keys.add("thinkingSignature");
|
|
304
|
+
keys.add("thoughtSignature");
|
|
305
|
+
}
|
|
306
|
+
if (type === "redacted_thinking" || type === "redactedThinking") {
|
|
307
|
+
keys.add("data");
|
|
308
|
+
}
|
|
309
|
+
return keys;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function redactHeaders(headers: Record<string, string> | undefined): Record<string, string> | undefined {
|
|
313
|
+
if (!headers) {
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const redacted: Record<string, string> = {};
|
|
318
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
319
|
+
if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {
|
|
320
|
+
redacted[key] = "[redacted]";
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
redacted[key] = value;
|
|
324
|
+
}
|
|
325
|
+
return redacted;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function formatCapturedHttpError(captured: CapturedHttpErrorResponse | undefined): string | undefined {
|
|
329
|
+
if (!captured) return undefined;
|
|
330
|
+
const bodyText = captured.bodyText?.trim();
|
|
331
|
+
if (!bodyText) return undefined;
|
|
332
|
+
const payload = parseCapturedErrorPayload(captured);
|
|
333
|
+
if (!payload) return bodyText;
|
|
334
|
+
|
|
335
|
+
const errorPayload = getObjectProperty(payload, "error") ?? payload;
|
|
336
|
+
// {"error": "string"} — the error value is a plain string, not a nested object.
|
|
337
|
+
// Fall back to it when the structured fields ("message", etc.) are absent.
|
|
338
|
+
const stringError = errorPayload === payload ? getStringProperty(payload, "error") : undefined;
|
|
339
|
+
const message =
|
|
340
|
+
getStringProperty(errorPayload, "message") ?? getStringProperty(payload, "message") ?? stringError ?? bodyText;
|
|
341
|
+
const extras = [
|
|
342
|
+
getStringProperty(errorPayload, "type") ?? getStringProperty(payload, "type"),
|
|
343
|
+
getStringProperty(errorPayload, "param") ?? getStringProperty(payload, "param"),
|
|
344
|
+
getStringProperty(errorPayload, "code") ?? getStringProperty(payload, "code"),
|
|
345
|
+
]
|
|
346
|
+
.filter(Boolean)
|
|
347
|
+
.map((value, index) => {
|
|
348
|
+
if (index === 0) return `type=${value}`;
|
|
349
|
+
if (index === 1) return `param=${value}`;
|
|
350
|
+
return `code=${value}`;
|
|
351
|
+
});
|
|
352
|
+
return extras.length > 0 ? `${message} (${extras.join(" ")})` : message;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function parseCapturedErrorPayload(captured: CapturedHttpErrorResponse): Record<string, unknown> | undefined {
|
|
356
|
+
if (isObject(captured.bodyJson)) {
|
|
357
|
+
return captured.bodyJson;
|
|
358
|
+
}
|
|
359
|
+
if (!captured.bodyText) return undefined;
|
|
360
|
+
try {
|
|
361
|
+
const parsed = JSON.parse(captured.bodyText);
|
|
362
|
+
return isObject(parsed) ? parsed : undefined;
|
|
363
|
+
} catch {
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function getObjectProperty(value: Record<string, unknown>, key: string): Record<string, unknown> | undefined {
|
|
369
|
+
const property = value[key];
|
|
370
|
+
return isObject(property) ? property : undefined;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function getStringProperty(value: Record<string, unknown>, key: string): string | undefined {
|
|
374
|
+
const property = value[key];
|
|
375
|
+
return typeof property === "string" && property.trim().length > 0 ? property : undefined;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function isObject(value: unknown): value is Record<string, unknown> {
|
|
379
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
380
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export declare function getProviderStreamIdleTimeoutFallbackMs(provider: string): number | undefined;
|
|
2
|
+
export declare function isGrokModelId(modelId: string | undefined): boolean;
|
|
3
|
+
export declare function getProviderFirstEventTimeoutFallbackMs(provider: string): number | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the idle timeout used for provider streaming transports.
|
|
6
|
+
*
|
|
7
|
+
* `VIB_OPENAI_STREAM_IDLE_TIMEOUT_MS` is honored first; `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` is a backward-compatible alias.
|
|
8
|
+
* Set `PI_STREAM_IDLE_TIMEOUT_MS=0` to disable the watchdog.
|
|
9
|
+
*
|
|
10
|
+
* Providers that legitimately stream much slower than the global default can pass
|
|
11
|
+
* `fallbackMs` to widen the floor used when neither env var nor caller option is set.
|
|
12
|
+
* Caller options still take precedence; env overrides still trump the fallback.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getStreamIdleTimeoutMs(fallbackMs?: number): number | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the idle timeout used for OpenAI-family streaming transports.
|
|
17
|
+
*
|
|
18
|
+
* Honors `VIB_OPENAI_STREAM_IDLE_TIMEOUT_MS` first (`PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` is the legacy alias). Set `=0` to disable.
|
|
19
|
+
* When `provider` is given, long-reasoning hosts (xAI Grok and Grok Build) use that floor instead of the 120s default.
|
|
20
|
+
* Grok models reached through other OpenAI-compatible hosts (`openrouter/x-ai/grok-*`, kilo, litellm, …) get the
|
|
21
|
+
* same floor keyed on the model id, because long-reasoning silence is a property of the model (#4797).
|
|
22
|
+
*/
|
|
23
|
+
export declare function getOpenAIStreamIdleTimeoutMs(provider?: string, modelId?: string): number | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the timeout used while waiting for the first stream event.
|
|
26
|
+
* The first token can legitimately take longer than later inter-event gaps,
|
|
27
|
+
* so the default never undershoots the steady-state idle timeout.
|
|
28
|
+
*
|
|
29
|
+
* Set `PI_STREAM_FIRST_EVENT_TIMEOUT_MS=0` to disable the watchdog.
|
|
30
|
+
*
|
|
31
|
+
* Providers whose first response can legitimately take longer (heavy reasoning,
|
|
32
|
+
* slow cold-start proxies) can pass `fallbackMs` to widen the floor used when
|
|
33
|
+
* neither env var nor caller option is set. Caller options still take precedence;
|
|
34
|
+
* env overrides still trump the fallback.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getStreamFirstEventTimeoutMs(idleTimeoutMs?: number, fallbackMs?: number): number | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the OpenAI SDK client `timeout` so stalled-before-headers requests are
|
|
39
|
+
* bounded by the same first-event window the transport watchdog uses after
|
|
40
|
+
* `create()` returns. Without this, providers that only arm
|
|
41
|
+
* `iterateWithIdleTimeout` post-setup can wait the full SDK default (10 minutes
|
|
42
|
+
* per attempt) before any provider-owned watchdog exists.
|
|
43
|
+
*
|
|
44
|
+
* - Explicit `0` disables the request timeout (the SDK treats `timeout: 0` as an
|
|
45
|
+
* immediate failure, so callers that disable the first-event watchdog must not
|
|
46
|
+
* pass a timeout).
|
|
47
|
+
* - Providers with a first-event fallback (Alibaba, Kimi) honor an explicit
|
|
48
|
+
* nonzero override as-is, even when shorter than the fallback.
|
|
49
|
+
* - Other providers floor an explicit override at the env/default first-event
|
|
50
|
+
* window so a short post-connect first-event budget cannot kill legitimate
|
|
51
|
+
* slow setup.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveOpenAISdkRequestTimeoutMs(provider: string, streamFirstEventTimeoutOverride?: number, modelId?: string): number | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Resolves the Anthropic SDK client `timeout` so stalled-before-headers requests
|
|
56
|
+
* are bounded. The Anthropic first-event watchdog deliberately arms only once
|
|
57
|
+
* response headers have arrived (setup latency must not consume the first-event
|
|
58
|
+
* budget), which left the connect/headers phase governed solely by the SDK
|
|
59
|
+
* default of 10 minutes per attempt — multiplied by SDK-internal retries, a
|
|
60
|
+
* connection that silently died right after a completed tool call could spin
|
|
61
|
+
* with no user-visible error for the better part of an hour.
|
|
62
|
+
*
|
|
63
|
+
* - Explicit `0` disables the request timeout, matching a disabled first-event
|
|
64
|
+
* watchdog.
|
|
65
|
+
* - An explicit nonzero override is floored at the env/default first-event
|
|
66
|
+
* window (which itself never undershoots the provider idle window) so a short
|
|
67
|
+
* post-connect first-event budget cannot kill legitimate slow setup.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveAnthropicSdkRequestTimeoutMs(provider: string, streamFirstEventTimeoutOverride?: number, streamIdleTimeoutOverride?: number): number | undefined;
|
|
70
|
+
export type Watchdog = NodeJS.Timeout | undefined;
|
|
71
|
+
export interface FirstEventTimeoutFacts {
|
|
72
|
+
requestBytes?: number;
|
|
73
|
+
firstEventElapsedMs?: number;
|
|
74
|
+
firstEventTimeoutMs?: number;
|
|
75
|
+
endpointClass?: "canonical" | "custom";
|
|
76
|
+
retryMaxAttempts?: number;
|
|
77
|
+
}
|
|
78
|
+
export declare class FirstEventTimeoutError extends Error {
|
|
79
|
+
readonly providerCode = "stream_first_event_timeout";
|
|
80
|
+
readonly requestBytes?: number;
|
|
81
|
+
readonly firstEventElapsedMs?: number;
|
|
82
|
+
readonly firstEventTimeoutMs?: number;
|
|
83
|
+
readonly endpointClass?: "canonical" | "custom";
|
|
84
|
+
readonly retryMaxAttempts?: number;
|
|
85
|
+
constructor(message: string, facts?: FirstEventTimeoutFacts);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Starts a watchdog that aborts a request if no first stream event arrives in time.
|
|
89
|
+
* Call `markFirstEventReceived()` as soon as the first event is observed.
|
|
90
|
+
*/
|
|
91
|
+
export declare function createWatchdog(timeoutMs: number | undefined, onTimeout: () => void): Watchdog;
|
|
92
|
+
export interface IdleTimeoutIteratorOptions {
|
|
93
|
+
watchdog?: Watchdog;
|
|
94
|
+
idleTimeoutMs?: number;
|
|
95
|
+
firstItemTimeoutMs?: number;
|
|
96
|
+
errorMessage: string;
|
|
97
|
+
firstItemErrorMessage?: string;
|
|
98
|
+
onIdle?: () => void;
|
|
99
|
+
onFirstItemTimeout?: () => void;
|
|
100
|
+
/**
|
|
101
|
+
* Optional semantic-progress predicate. Non-progress items are still yielded,
|
|
102
|
+
* but they do not reset the idle deadline. This prevents provider
|
|
103
|
+
* keepalive/no-op events from keeping a stalled tool call alive forever.
|
|
104
|
+
*/
|
|
105
|
+
isProgressItem?: (item: unknown) => boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Cancel iteration as soon as this signal aborts. Required for caller-driven
|
|
108
|
+
* cancellation (ESC) when the underlying transport does not surface signal
|
|
109
|
+
* aborts to the iterator (HTTP/2 proxies, native sockets, mocked fetch).
|
|
110
|
+
* Without this, the consumer sleeps on iterator.next() until the idle/first
|
|
111
|
+
* -event watchdog fires — observable as the issue #912 "Working… forever"
|
|
112
|
+
* symptom on the github-copilot provider.
|
|
113
|
+
*/
|
|
114
|
+
abortSignal?: AbortSignal;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Yields items from an async iterable while enforcing a maximum idle gap between items.
|
|
118
|
+
*
|
|
119
|
+
* The first item may use a shorter timeout so stuck requests can be aborted and retried
|
|
120
|
+
* before any user-visible content has streamed.
|
|
121
|
+
*/
|
|
122
|
+
export declare function iterateWithIdleTimeout<T>(iterable: AsyncIterable<T>, options: IdleTimeoutIteratorOptions): AsyncGenerator<T>;
|