@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,408 @@
|
|
|
1
|
+
import turnAbortedGuidance from "../prompts/turn-aborted-guidance.md" with { type: "text" };
|
|
2
|
+
import type {
|
|
3
|
+
Api,
|
|
4
|
+
AssistantMessage,
|
|
5
|
+
DeveloperMessage,
|
|
6
|
+
Message,
|
|
7
|
+
Model,
|
|
8
|
+
ToolCall,
|
|
9
|
+
ToolResultMessage,
|
|
10
|
+
UserMessage,
|
|
11
|
+
} from "../types";
|
|
12
|
+
|
|
13
|
+
const enum ToolCallStatus {
|
|
14
|
+
/** Tool call has received a result (real or synthetic for orphan) */
|
|
15
|
+
Resolved = 1,
|
|
16
|
+
/** Tool call was from an aborted message; synthetic result injected, skip real results */
|
|
17
|
+
Aborted = 2,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Normalize tool call ID for cross-provider compatibility.
|
|
22
|
+
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
23
|
+
* Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
|
|
24
|
+
*
|
|
25
|
+
* For aborted/errored turns, this function:
|
|
26
|
+
* - Preserves tool call structure (unlike converting to text summaries)
|
|
27
|
+
* - Injects synthetic "aborted" tool results
|
|
28
|
+
* - Adds a <turn-aborted> guidance marker for the model
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Detect directly adjacent private thinking blocks inside one assistant message's
|
|
32
|
+
* content. `thinking` and `redacted_thinking` are one adjacency class: the
|
|
33
|
+
* Anthropic wire contract rejects a replayed assistant turn where two such blocks
|
|
34
|
+
* sit next to each other with no intervening `tool_use`/`text` block (#4416).
|
|
35
|
+
*
|
|
36
|
+
* This is a pure, allocation-free predicate used by defense-in-depth diagnostics
|
|
37
|
+
* (issue #4443): the write-time transcript assertion (coding-agent persistence)
|
|
38
|
+
* and the stream-assembler SSE diagnostic (anthropic stream completion). It never
|
|
39
|
+
* inspects block payloads — only the block-type sequence — so it cannot leak
|
|
40
|
+
* thinking text, signatures, or credentials.
|
|
41
|
+
*
|
|
42
|
+
* Blocks separated by any non-private block (`tool_use`, `text`, …) are ordinary
|
|
43
|
+
* interleaved-thinking shape and return `false`.
|
|
44
|
+
*/
|
|
45
|
+
export function hasAdjacentPrivateThinkingBlocks(content: { type: string }[]): boolean {
|
|
46
|
+
let previousWasPrivate = false;
|
|
47
|
+
for (const block of content) {
|
|
48
|
+
const isPrivate = block.type === "thinking" || block.type === "redactedThinking";
|
|
49
|
+
if (isPrivate && previousWasPrivate) return true;
|
|
50
|
+
previousWasPrivate = isPrivate;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Collapse a run of directly adjacent `thinking` blocks inside one assistant message down
|
|
57
|
+
* to its first block.
|
|
58
|
+
*
|
|
59
|
+
* Anthropic accepts a replayed assistant turn carrying a single thinking block, and accepts
|
|
60
|
+
* thinking blocks separated by a `tool_use` (ordinary interleaved-thinking shape), but
|
|
61
|
+
* rejects two directly adjacent `thinking` blocks with
|
|
62
|
+
* `messages.N.content.M: thinking or redacted_thinking blocks in the latest assistant
|
|
63
|
+
* message cannot be modified`, citing the *second* block of the pair. Because the offending
|
|
64
|
+
* message keeps its index as history grows, a single such turn makes every later request in
|
|
65
|
+
* that session fail, and the mutation repair - scoped to the latest assistant message -
|
|
66
|
+
* can never reach it (#4416).
|
|
67
|
+
*
|
|
68
|
+
* `redactedThinking` is not folded in this phase, but the final send-boundary
|
|
69
|
+
* collapse in `convertAnthropicMessages` (#4425) treats `thinking` and
|
|
70
|
+
* `redacted_thinking` as one adjacency class per the API contract.
|
|
71
|
+
*/
|
|
72
|
+
function collapseAdjacentThinking<T extends { type: string }>(content: T[]): T[] {
|
|
73
|
+
let previousWasThinking = false;
|
|
74
|
+
let dropped = false;
|
|
75
|
+
const collapsed: T[] = [];
|
|
76
|
+
for (const block of content) {
|
|
77
|
+
const thinking = block.type === "thinking";
|
|
78
|
+
if (thinking && previousWasThinking) {
|
|
79
|
+
dropped = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
previousWasThinking = thinking;
|
|
83
|
+
collapsed.push(block);
|
|
84
|
+
}
|
|
85
|
+
return dropped ? collapsed : content;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function transformMessages<TApi extends Api>(
|
|
89
|
+
messages: Message[],
|
|
90
|
+
model: Model<TApi>,
|
|
91
|
+
normalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string,
|
|
92
|
+
options?: { repairLatestAssistantThinking?: boolean; repairAllAssistantThinking?: boolean },
|
|
93
|
+
): Message[] {
|
|
94
|
+
// Build a map of original tool call IDs to normalized IDs
|
|
95
|
+
const toolCallIdMap = new Map<string, string>();
|
|
96
|
+
|
|
97
|
+
const latestAssistantIndex = messages.findLastIndex(msg => msg.role === "assistant");
|
|
98
|
+
// First pass: transform messages (thinking blocks, tool call ID normalization)
|
|
99
|
+
const transformed = messages.map((msg, index) => {
|
|
100
|
+
// User and developer messages pass through unchanged
|
|
101
|
+
if (msg.role === "user" || msg.role === "developer") {
|
|
102
|
+
return msg;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Handle toolResult messages - normalize toolCallId if we have a mapping
|
|
106
|
+
if (msg.role === "toolResult") {
|
|
107
|
+
const normalizedId = toolCallIdMap.get(msg.toolCallId);
|
|
108
|
+
if (normalizedId && normalizedId !== msg.toolCallId) {
|
|
109
|
+
return { ...msg, toolCallId: normalizedId };
|
|
110
|
+
}
|
|
111
|
+
return msg;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Assistant messages need transformation check
|
|
115
|
+
if (msg.role === "assistant") {
|
|
116
|
+
const assistantMsg = msg as AssistantMessage;
|
|
117
|
+
const isSameModel =
|
|
118
|
+
assistantMsg.provider === model.provider &&
|
|
119
|
+
assistantMsg.api === model.api &&
|
|
120
|
+
assistantMsg.model === model.id;
|
|
121
|
+
|
|
122
|
+
const mustPreserveLatestAnthropicThinking =
|
|
123
|
+
index === latestAssistantIndex &&
|
|
124
|
+
model.api === "anthropic-messages" &&
|
|
125
|
+
assistantMsg.api === "anthropic-messages";
|
|
126
|
+
// Aborted/errored messages may contain partially-streamed thinking blocks.
|
|
127
|
+
// Anthropic requires thinking/redacted_thinking bytes in replayed assistant
|
|
128
|
+
// messages to match the original response exactly; stripping a signature,
|
|
129
|
+
// well-forming text, or keeping a partial redacted block would emit a
|
|
130
|
+
// modified thinking sequence. Drop those private blocks instead. Tool calls
|
|
131
|
+
// are kept so the second pass can either preserve real results or synthesize
|
|
132
|
+
// an explicit aborted result without leaving dangling tool_use blocks.
|
|
133
|
+
const hasPartialThinking = assistantMsg.stopReason === "aborted" || assistantMsg.stopReason === "error";
|
|
134
|
+
// One-shot Anthropic replay repair. `repairLatestAssistantThinking` targets the
|
|
135
|
+
// "latest assistant message ... cannot be modified" 400; `repairAllAssistantThinking`
|
|
136
|
+
// targets the "Invalid `signature` in `thinking` block" 400, which can cite a block
|
|
137
|
+
// anywhere in the replayed history (e.g. after compaction/pruning rewrote an earlier
|
|
138
|
+
// turn), so the drop must apply to every assistant message. Within each
|
|
139
|
+
// message only blocks that would replay as native thinking/redacted_thinking
|
|
140
|
+
// are dropped; cross-model reasoning degrades to text and is preserved.
|
|
141
|
+
const dropAssistantThinkingForRepair =
|
|
142
|
+
(options?.repairAllAssistantThinking === true ||
|
|
143
|
+
(options?.repairLatestAssistantThinking === true && index === latestAssistantIndex)) &&
|
|
144
|
+
model.api === "anthropic-messages" &&
|
|
145
|
+
assistantMsg.api === "anthropic-messages";
|
|
146
|
+
|
|
147
|
+
const transformedContent = assistantMsg.content.flatMap(block => {
|
|
148
|
+
if (block.type === "thinking") {
|
|
149
|
+
if (hasPartialThinking) return [];
|
|
150
|
+
const sanitized = block;
|
|
151
|
+
// Repair must only drop blocks that would otherwise replay as native
|
|
152
|
+
// thinking. Cross-model/provider reasoning degrades to unsigned text
|
|
153
|
+
// below and was never replayed as a signed block, so it cannot be the
|
|
154
|
+
// signature failure — dropping it would silently lose valid context.
|
|
155
|
+
const replaysAsNativeThinking = mustPreserveLatestAnthropicThinking || isSameModel;
|
|
156
|
+
if (dropAssistantThinkingForRepair && replaysAsNativeThinking) return [];
|
|
157
|
+
if (mustPreserveLatestAnthropicThinking) return sanitized;
|
|
158
|
+
// For same model: keep thinking blocks with signatures (needed for replay)
|
|
159
|
+
// even if the thinking text is empty — but only for non-Anthropic APIs where
|
|
160
|
+
// the signature represents OpenAI encrypted reasoning. For anthropic-messages,
|
|
161
|
+
// a signed block with empty text means clear_thinking_20251015 stripped the
|
|
162
|
+
// content server-side while the stale signature remained; replaying it
|
|
163
|
+
// produces `thinking ... cannot be modified` 400s on every turn (#4247).
|
|
164
|
+
if (isSameModel && sanitized.thinkingSignature) {
|
|
165
|
+
if (sanitized.thinking.trim() === "" && model.api === "anthropic-messages") return [];
|
|
166
|
+
return sanitized;
|
|
167
|
+
}
|
|
168
|
+
// Skip empty thinking blocks, convert others to plain text
|
|
169
|
+
if (!sanitized.thinking || sanitized.thinking.trim() === "") return [];
|
|
170
|
+
if (isSameModel) return sanitized;
|
|
171
|
+
return {
|
|
172
|
+
type: "text" as const,
|
|
173
|
+
text: sanitized.thinking,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (block.type === "redactedThinking") {
|
|
178
|
+
if (hasPartialThinking) return [];
|
|
179
|
+
// Same restriction as thinking blocks: cross-model/provider redacted
|
|
180
|
+
// blocks already drop below, so repair only needs to cover blocks that
|
|
181
|
+
// would replay as native redacted_thinking.
|
|
182
|
+
if (dropAssistantThinkingForRepair && (mustPreserveLatestAnthropicThinking || isSameModel)) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
if (mustPreserveLatestAnthropicThinking) return block;
|
|
186
|
+
if (isSameModel) return block;
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (block.type === "text") {
|
|
191
|
+
if (isSameModel) return block;
|
|
192
|
+
return {
|
|
193
|
+
type: "text" as const,
|
|
194
|
+
text: block.text,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (block.type === "toolCall") {
|
|
199
|
+
const toolCall = block as ToolCall;
|
|
200
|
+
let normalizedToolCall: ToolCall = toolCall;
|
|
201
|
+
|
|
202
|
+
if (!isSameModel && toolCall.thoughtSignature) {
|
|
203
|
+
normalizedToolCall = { ...toolCall };
|
|
204
|
+
delete (normalizedToolCall as { thoughtSignature?: string }).thoughtSignature;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!isSameModel && normalizeToolCallId) {
|
|
208
|
+
const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);
|
|
209
|
+
if (normalizedId !== toolCall.id) {
|
|
210
|
+
toolCallIdMap.set(toolCall.id, normalizedId);
|
|
211
|
+
normalizedToolCall = { ...normalizedToolCall, id: normalizedId };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return normalizedToolCall;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return block;
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Only the Anthropic wire shape rejects adjacent private blocks; other targets
|
|
222
|
+
// either degrade reasoning to text above or carry their own encoding rules.
|
|
223
|
+
const replayableContent =
|
|
224
|
+
model.api === "anthropic-messages" ? collapseAdjacentThinking(transformedContent) : transformedContent;
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
...assistantMsg,
|
|
228
|
+
content: replayableContent,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return msg;
|
|
232
|
+
});
|
|
233
|
+
const realToolResultIds = new Set(
|
|
234
|
+
transformed.filter((msg): msg is ToolResultMessage => msg.role === "toolResult").map(msg => msg.toolCallId),
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Anthropic rejects `tool_result` blocks whose `tool_use_id` does not appear in a prior
|
|
238
|
+
// `tool_use` block. After handoff/compaction folds an assistant turn into a summary
|
|
239
|
+
// string, the user-side `toolResult` for that turn can survive while the originating
|
|
240
|
+
// `tool_use` disappears — leaving an orphan that triggers HTTP 400. Track the set of
|
|
241
|
+
// `tool_use` ids that survive transformation so the second pass can drop orphans cleanly.
|
|
242
|
+
const validToolUseIds = new Set<string>();
|
|
243
|
+
for (const msg of transformed) {
|
|
244
|
+
if (msg.role !== "assistant") continue;
|
|
245
|
+
for (const block of msg.content) {
|
|
246
|
+
if (block.type === "toolCall") validToolUseIds.add(block.id);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Second pass: insert synthetic empty tool results for orphaned tool calls
|
|
251
|
+
// and preserve aborted/errored tool results when they were already persisted.
|
|
252
|
+
const result: Message[] = [];
|
|
253
|
+
let pendingToolCalls: ToolCall[] = [];
|
|
254
|
+
let pendingAbortedToolCalls = new Map<string, ToolCall>();
|
|
255
|
+
let pendingAbortedTimestamp: number | undefined;
|
|
256
|
+
// Track tool call status: whether resolved (has result) or aborted (synthetic result injected, skip later real results)
|
|
257
|
+
const toolCallStatus = new Map<string, ToolCallStatus>();
|
|
258
|
+
|
|
259
|
+
const flushPendingToolCalls = (timestamp: number): void => {
|
|
260
|
+
if (pendingToolCalls.length === 0) return;
|
|
261
|
+
for (const tc of pendingToolCalls) {
|
|
262
|
+
if (!toolCallStatus.has(tc.id) && !realToolResultIds.has(tc.id)) {
|
|
263
|
+
result.push({
|
|
264
|
+
role: "toolResult",
|
|
265
|
+
toolCallId: tc.id,
|
|
266
|
+
toolName: tc.name,
|
|
267
|
+
content: [{ type: "text", text: "No result provided" }],
|
|
268
|
+
isError: true,
|
|
269
|
+
timestamp,
|
|
270
|
+
} as ToolResultMessage);
|
|
271
|
+
toolCallStatus.set(tc.id, ToolCallStatus.Resolved);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
pendingToolCalls = [];
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const flushPendingAbortedToolCalls = (): void => {
|
|
278
|
+
if (pendingAbortedTimestamp === undefined) return;
|
|
279
|
+
for (const tc of pendingAbortedToolCalls.values()) {
|
|
280
|
+
if (!toolCallStatus.has(tc.id)) {
|
|
281
|
+
result.push({
|
|
282
|
+
role: "toolResult",
|
|
283
|
+
toolCallId: tc.id,
|
|
284
|
+
toolName: tc.name,
|
|
285
|
+
content: [{ type: "text", text: "aborted" }],
|
|
286
|
+
isError: true,
|
|
287
|
+
timestamp: pendingAbortedTimestamp,
|
|
288
|
+
} as ToolResultMessage);
|
|
289
|
+
toolCallStatus.set(tc.id, ToolCallStatus.Aborted);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
result.push({
|
|
293
|
+
role: "developer",
|
|
294
|
+
content: turnAbortedGuidance,
|
|
295
|
+
timestamp: pendingAbortedTimestamp + 1,
|
|
296
|
+
} as DeveloperMessage);
|
|
297
|
+
pendingAbortedToolCalls = new Map();
|
|
298
|
+
pendingAbortedTimestamp = undefined;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
for (let i = 0; i < transformed.length; i++) {
|
|
302
|
+
const msg = transformed[i];
|
|
303
|
+
const messageTimestamp = "timestamp" in msg && typeof msg.timestamp === "number" ? msg.timestamp : Date.now();
|
|
304
|
+
|
|
305
|
+
if (msg.role === "assistant") {
|
|
306
|
+
flushPendingToolCalls(messageTimestamp);
|
|
307
|
+
flushPendingAbortedToolCalls();
|
|
308
|
+
|
|
309
|
+
const assistantMsg = msg as AssistantMessage;
|
|
310
|
+
const toolCalls = assistantMsg.content.filter(b => b.type === "toolCall") as ToolCall[];
|
|
311
|
+
|
|
312
|
+
if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") {
|
|
313
|
+
// Keep the assistant message with tool calls intact. If real tool results follow, preserve them;
|
|
314
|
+
// otherwise synthesize aborted results before the next turn boundary.
|
|
315
|
+
result.push(msg);
|
|
316
|
+
pendingAbortedToolCalls = new Map(toolCalls.map(toolCall => [toolCall.id, toolCall] as const));
|
|
317
|
+
pendingAbortedTimestamp = assistantMsg.timestamp;
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (toolCalls.length > 0) {
|
|
322
|
+
pendingToolCalls = toolCalls;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
result.push(msg);
|
|
326
|
+
} else if (msg.role === "toolResult") {
|
|
327
|
+
if (pendingAbortedToolCalls.has(msg.toolCallId)) {
|
|
328
|
+
pendingAbortedToolCalls.delete(msg.toolCallId);
|
|
329
|
+
toolCallStatus.set(msg.toolCallId, ToolCallStatus.Resolved);
|
|
330
|
+
result.push(msg);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (toolCallStatus.get(msg.toolCallId) === ToolCallStatus.Aborted) continue;
|
|
335
|
+
|
|
336
|
+
if (!validToolUseIds.has(msg.toolCallId)) {
|
|
337
|
+
// Orphan `tool_result`: the originating `tool_use` is not present in the
|
|
338
|
+
// transformed history (typically because handoff/compaction folded the
|
|
339
|
+
// assistant message into a summary string while the user-side result
|
|
340
|
+
// survived). Sending the block as-is would 400 the request, so it must
|
|
341
|
+
// be dropped.
|
|
342
|
+
//
|
|
343
|
+
// If a pending tool-call window is still open (either normal or
|
|
344
|
+
// aborted), the orphan cannot be replaced with a developer note here:
|
|
345
|
+
//
|
|
346
|
+
// * Anthropic requires the next message after an assistant `tool_use`
|
|
347
|
+
// to be the matching `tool_result`. Inserting a developer message
|
|
348
|
+
// would break that contiguity.
|
|
349
|
+
// * `flushPendingAbortedToolCalls` synthesizes "aborted" results
|
|
350
|
+
// without checking whether a real result lands later in history
|
|
351
|
+
// (unlike `flushPendingToolCalls`, which is gated by
|
|
352
|
+
// `realToolResultIds`). Calling it here would convert a legitimate
|
|
353
|
+
// later `tool_result` into a synthetic "aborted" one via the
|
|
354
|
+
// `ToolCallStatus.Aborted` skip-guard.
|
|
355
|
+
//
|
|
356
|
+
// Drop the orphan silently in that case; the upcoming real
|
|
357
|
+
// `tool_result` will land normally on the next iteration.
|
|
358
|
+
if (pendingToolCalls.length > 0 || pendingAbortedToolCalls.size > 0) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
// No pending tool-call window: safe to preserve the text payload so the
|
|
362
|
+
// model still sees what the tool returned.
|
|
363
|
+
//
|
|
364
|
+
// The note is emitted with `role: "user"` rather than `role: "developer"`
|
|
365
|
+
// because the developer role is elevated by some providers:
|
|
366
|
+
//
|
|
367
|
+
// * Ollama maps `developer` -> `system` (highest instruction priority).
|
|
368
|
+
// * OpenAI chat-completions reasoning models forward `developer` as
|
|
369
|
+
// `developer` (above-user instruction priority).
|
|
370
|
+
//
|
|
371
|
+
// Stale, model-untrusted tool output must not gain instruction priority
|
|
372
|
+
// above user/developer messages it lived alongside before compaction.
|
|
373
|
+
// `user` role is mapped to plain user content by every provider, so the
|
|
374
|
+
// content survives without ever being treated as an instruction the
|
|
375
|
+
// model should obey.
|
|
376
|
+
const textParts: string[] = [];
|
|
377
|
+
for (const part of msg.content) {
|
|
378
|
+
if (part.type === "text" && part.text.trim() !== "") textParts.push(part.text);
|
|
379
|
+
}
|
|
380
|
+
if (textParts.length > 0) {
|
|
381
|
+
const errorAttr = msg.isError ? ' is-error="true"' : "";
|
|
382
|
+
result.push({
|
|
383
|
+
role: "user",
|
|
384
|
+
content: `<stale-tool-result tool="${msg.toolName}" id="${msg.toolCallId}"${errorAttr}>\n${textParts.join("\n")}\n</stale-tool-result>`,
|
|
385
|
+
timestamp: messageTimestamp,
|
|
386
|
+
} as UserMessage);
|
|
387
|
+
}
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
toolCallStatus.set(msg.toolCallId, ToolCallStatus.Resolved);
|
|
392
|
+
result.push(msg);
|
|
393
|
+
} else if (msg.role === "user" || msg.role === "developer") {
|
|
394
|
+
flushPendingToolCalls(messageTimestamp);
|
|
395
|
+
flushPendingAbortedToolCalls();
|
|
396
|
+
result.push(msg);
|
|
397
|
+
} else {
|
|
398
|
+
flushPendingToolCalls(messageTimestamp);
|
|
399
|
+
flushPendingAbortedToolCalls();
|
|
400
|
+
result.push(msg);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
flushPendingToolCalls(Date.now());
|
|
405
|
+
flushPendingAbortedToolCalls();
|
|
406
|
+
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from "../types";
|
|
2
|
+
export declare const NON_VISION_IMAGE_PLACEHOLDER = "[image omitted: model does not support vision]";
|
|
3
|
+
export declare function partitionVisionContent(content: ReadonlyArray<TextContent | ImageContent>, supportsImages: boolean): {
|
|
4
|
+
textBlocks: TextContent[];
|
|
5
|
+
imageBlocks: ImageContent[];
|
|
6
|
+
omittedImages: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function joinTextWithImagePlaceholder(text: string, omittedImages: boolean): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from "../types";
|
|
2
|
+
|
|
3
|
+
export const NON_VISION_IMAGE_PLACEHOLDER = "[image omitted: model does not support vision]";
|
|
4
|
+
|
|
5
|
+
export function partitionVisionContent(
|
|
6
|
+
content: ReadonlyArray<TextContent | ImageContent>,
|
|
7
|
+
supportsImages: boolean,
|
|
8
|
+
): {
|
|
9
|
+
textBlocks: TextContent[];
|
|
10
|
+
imageBlocks: ImageContent[];
|
|
11
|
+
omittedImages: boolean;
|
|
12
|
+
} {
|
|
13
|
+
const textBlocks = content.filter((block): block is TextContent => block.type === "text");
|
|
14
|
+
const imageBlocks = content.filter((block): block is ImageContent => block.type === "image");
|
|
15
|
+
return {
|
|
16
|
+
textBlocks,
|
|
17
|
+
imageBlocks: supportsImages ? imageBlocks : [],
|
|
18
|
+
omittedImages: !supportsImages && imageBlocks.length > 0,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function joinTextWithImagePlaceholder(text: string, omittedImages: boolean): string {
|
|
23
|
+
const parts: string[] = [];
|
|
24
|
+
if (text.length > 0) {
|
|
25
|
+
parts.push(text);
|
|
26
|
+
}
|
|
27
|
+
if (omittedImages) {
|
|
28
|
+
parts.push(NON_VISION_IMAGE_PLACEHOLDER);
|
|
29
|
+
}
|
|
30
|
+
return parts.join("\n");
|
|
31
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate limit reason classification and backoff calculation utilities.
|
|
3
|
+
* Ported from opencode-antigravity-auth plugin for consistency.
|
|
4
|
+
*/
|
|
5
|
+
export type RateLimitReason = "QUOTA_EXHAUSTED" | "RATE_LIMIT_EXCEEDED" | "MODEL_CAPACITY_EXHAUSTED" | "SERVER_ERROR" | "UNKNOWN";
|
|
6
|
+
/**
|
|
7
|
+
* Classify a rate-limit error message into a reason category.
|
|
8
|
+
* Priority order: MODEL_CAPACITY > RATE_LIMIT > QUOTA > SERVER_ERROR > UNKNOWN.
|
|
9
|
+
*
|
|
10
|
+
* "resource exhausted" maps to MODEL_CAPACITY (transient, short wait)
|
|
11
|
+
* "quota exceeded" maps to QUOTA_EXHAUSTED (long wait, switch account)
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseRateLimitReason(errorMessage: string): RateLimitReason;
|
|
14
|
+
/**
|
|
15
|
+
* Calculate backoff delay in ms for a given rate limit reason.
|
|
16
|
+
* MODEL_CAPACITY gets jitter to prevent thundering herd.
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateRateLimitBackoffMs(reason: RateLimitReason): number;
|
|
19
|
+
export declare function isUsageLimitError(errorMessage: string): boolean;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate limit reason classification and backoff calculation utilities.
|
|
3
|
+
* Ported from opencode-antigravity-auth plugin for consistency.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type RateLimitReason =
|
|
7
|
+
| "QUOTA_EXHAUSTED"
|
|
8
|
+
| "RATE_LIMIT_EXCEEDED"
|
|
9
|
+
| "MODEL_CAPACITY_EXHAUSTED"
|
|
10
|
+
| "SERVER_ERROR"
|
|
11
|
+
| "UNKNOWN";
|
|
12
|
+
|
|
13
|
+
const QUOTA_EXHAUSTED_BACKOFF_MS = 30 * 60 * 1000; // 30 min
|
|
14
|
+
const RATE_LIMIT_EXCEEDED_BACKOFF_MS = 30 * 1000; // 30s
|
|
15
|
+
const MODEL_CAPACITY_BASE_MS = 45 * 1000; // 45s base
|
|
16
|
+
const MODEL_CAPACITY_JITTER_MS = 30 * 1000; // uniform +0–30s above base → 45–75s total
|
|
17
|
+
const SERVER_ERROR_BACKOFF_MS = 20 * 1000; // 20s
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Classify a rate-limit error message into a reason category.
|
|
21
|
+
* Priority order: MODEL_CAPACITY > RATE_LIMIT > QUOTA > SERVER_ERROR > UNKNOWN.
|
|
22
|
+
*
|
|
23
|
+
* "resource exhausted" maps to MODEL_CAPACITY (transient, short wait)
|
|
24
|
+
* "quota exceeded" maps to QUOTA_EXHAUSTED (long wait, switch account)
|
|
25
|
+
*/
|
|
26
|
+
export function parseRateLimitReason(errorMessage: string): RateLimitReason {
|
|
27
|
+
const lower = errorMessage.toLowerCase();
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
lower.includes("capacity") ||
|
|
31
|
+
lower.includes("overloaded") ||
|
|
32
|
+
lower.includes("529") ||
|
|
33
|
+
lower.includes("503") ||
|
|
34
|
+
lower.includes("resource exhausted")
|
|
35
|
+
) {
|
|
36
|
+
return "MODEL_CAPACITY_EXHAUSTED";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
lower.includes("out_of_credits") ||
|
|
41
|
+
lower.includes("request would exceed your account's rate limit") ||
|
|
42
|
+
lower.includes("request would exceed your accounts rate limit")
|
|
43
|
+
) {
|
|
44
|
+
return "QUOTA_EXHAUSTED";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
lower.includes("per minute") ||
|
|
49
|
+
lower.includes("rate limit") ||
|
|
50
|
+
lower.includes("too many requests") ||
|
|
51
|
+
lower.includes("presque")
|
|
52
|
+
) {
|
|
53
|
+
return "RATE_LIMIT_EXCEEDED";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (
|
|
57
|
+
lower.includes("exhausted") ||
|
|
58
|
+
lower.includes("quota") ||
|
|
59
|
+
lower.includes("usage limit") ||
|
|
60
|
+
lower.includes("model limit") ||
|
|
61
|
+
lower.includes("model_limit") ||
|
|
62
|
+
lower.includes("message limit") ||
|
|
63
|
+
lower.includes("message_limit") ||
|
|
64
|
+
lower.includes("limit for this model")
|
|
65
|
+
) {
|
|
66
|
+
return "QUOTA_EXHAUSTED";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (lower.includes("500") || lower.includes("internal error") || lower.includes("internal server error")) {
|
|
70
|
+
return "SERVER_ERROR";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return "UNKNOWN";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Calculate backoff delay in ms for a given rate limit reason.
|
|
78
|
+
* MODEL_CAPACITY gets jitter to prevent thundering herd.
|
|
79
|
+
*/
|
|
80
|
+
export function calculateRateLimitBackoffMs(reason: RateLimitReason): number {
|
|
81
|
+
switch (reason) {
|
|
82
|
+
case "QUOTA_EXHAUSTED":
|
|
83
|
+
return QUOTA_EXHAUSTED_BACKOFF_MS;
|
|
84
|
+
case "RATE_LIMIT_EXCEEDED":
|
|
85
|
+
return RATE_LIMIT_EXCEEDED_BACKOFF_MS;
|
|
86
|
+
case "MODEL_CAPACITY_EXHAUSTED":
|
|
87
|
+
return MODEL_CAPACITY_BASE_MS + Math.random() * MODEL_CAPACITY_JITTER_MS;
|
|
88
|
+
case "SERVER_ERROR":
|
|
89
|
+
return SERVER_ERROR_BACKOFF_MS;
|
|
90
|
+
default:
|
|
91
|
+
return QUOTA_EXHAUSTED_BACKOFF_MS; // conservative default
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Detect usage/quota limit errors in error messages (persistent, requires credential switch). */
|
|
96
|
+
// ZAI reports durable token exhaustion as "[1310][Weekly/Monthly Limit Exhausted...]".
|
|
97
|
+
// Keep this explicit so generic "rate limit exhausted, retry..." throttles remain retryable.
|
|
98
|
+
const USAGE_LIMIT_PATTERN =
|
|
99
|
+
/usage.?limit|usage_limit_reached|usage_not_included|limit_reached|model.?limit|model_limit_reached|message.?limit|message_limit_reached|limit for this model|weekly\/monthly\s+limit\s+exhausted|quota.?exceeded|out_of_credits|request would exceed your account.?s rate limit|resource has been exhausted[^\n]*(?:quota|limit)/i;
|
|
100
|
+
export function isUsageLimitError(errorMessage: string): boolean {
|
|
101
|
+
return USAGE_LIMIT_PATTERN.test(errorMessage);
|
|
102
|
+
}
|
package/src/stream.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Effort } from "./model-thinking";
|
|
2
|
+
import type { AnthropicOptions } from "./providers/anthropic";
|
|
3
|
+
import type { Api, AssistantMessage, Context, Model, OptionsForApi, SimpleStreamOptions, ToolChoice } from "./types";
|
|
4
|
+
import { AssistantMessageEventStream } from "./utils/event-stream";
|
|
5
|
+
/**
|
|
6
|
+
* Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
|
|
7
|
+
*
|
|
8
|
+
* Provider authentication intentionally excludes cwd/.env values. Project dotenv files are
|
|
9
|
+
* loaded into $env for app/tool execution, but must not silently fund Vibrato model requests.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getEnvApiKey(provider: string): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Enumerate every provider that has an env-var fallback for `getEnvApiKey`.
|
|
14
|
+
* Used by `vib auth-broker migrate --include-env` to discover env-sourced keys
|
|
15
|
+
* that should be uploaded to the broker.
|
|
16
|
+
*/
|
|
17
|
+
export declare function listProvidersWithEnvKey(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Provider-specific credential guidance appended to "no credential" errors.
|
|
20
|
+
*
|
|
21
|
+
* Headless Vibrato has no interactive `/login` TUI, so a bare "No API key" /
|
|
22
|
+
* "No credentials" error left users — OpenCode Go subscribers especially
|
|
23
|
+
* (#755) — unsure what signal Vibrato actually reads. OpenCode subscriptions are
|
|
24
|
+
* themselves API keys, so this names the env var Vibrato reads for the provider,
|
|
25
|
+
* warns that a project `.env` is intentionally ignored for provider
|
|
26
|
+
* credentials, and points OpenCode users at one-time interactive CLI credential capture.
|
|
27
|
+
*
|
|
28
|
+
* Returns an empty string when the provider has no env-var key and no special
|
|
29
|
+
* handling, so callers can append it unconditionally.
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatProviderCredentialHint(provider: string): string;
|
|
32
|
+
export declare function streamFromLazyImport(createInner: () => Promise<AssistantMessageEventStream>, signal?: AbortSignal, onStreamCreated?: () => void): AssistantMessageEventStream;
|
|
33
|
+
/**
|
|
34
|
+
* Build an actionable "missing API key" error for a provider, used by the
|
|
35
|
+
* low-level `stream`/`complete` entry points (#755).
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatMissingApiKeyError(provider: string): string;
|
|
38
|
+
export declare function stream<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>, onStreamCreated?: () => void): AssistantMessageEventStream;
|
|
39
|
+
export declare function complete<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>): Promise<AssistantMessage>;
|
|
40
|
+
export declare function streamSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream;
|
|
41
|
+
export declare function completeSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): Promise<AssistantMessage>;
|
|
42
|
+
export declare const OUTPUT_FALLBACK_BUFFER = 4000;
|
|
43
|
+
export declare const ANTHROPIC_THINKING: Record<Effort, number>;
|
|
44
|
+
export declare function mapAnthropicToolChoice(choice?: ToolChoice): AnthropicOptions["toolChoice"];
|
|
45
|
+
export declare function resolveDefaultRequestMaxTokens<TApi extends Api>(model: Model<TApi>, requested?: number): number;
|