blackriver-gateway 3.8.46
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/.env.example +2070 -0
- package/@omniroute/opencode-plugin/LICENSE +21 -0
- package/@omniroute/opencode-plugin/README.md +296 -0
- package/@omniroute/opencode-plugin/package-lock.json +1930 -0
- package/@omniroute/opencode-plugin/package.json +73 -0
- package/@omniroute/opencode-plugin/src/index.ts +4685 -0
- package/@omniroute/opencode-plugin/src/logger.ts +74 -0
- package/@omniroute/opencode-plugin/src/naming.ts +301 -0
- package/@omniroute/opencode-plugin/tsconfig.json +20 -0
- package/@omniroute/opencode-plugin/tsup.config.ts +20 -0
- package/@omniroute/opencode-provider/LICENSE +21 -0
- package/@omniroute/opencode-provider/README.md +156 -0
- package/@omniroute/opencode-provider/package-lock.json +1514 -0
- package/@omniroute/opencode-provider/package.json +63 -0
- package/@omniroute/opencode-provider/src/index.ts +908 -0
- package/@omniroute/opencode-provider/tsconfig.json +20 -0
- package/@omniroute/opencode-provider/tsup.config.ts +18 -0
- package/LICENSE +22 -0
- package/README.md +1265 -0
- package/bin/_ops-common.sh +70 -0
- package/bin/cli/CONVENTIONS.md +224 -0
- package/bin/cli/README.md +146 -0
- package/bin/cli/api-commands/agent-skills.mjs +70 -0
- package/bin/cli/api-commands/agentbridge.mjs +155 -0
- package/bin/cli/api-commands/api-keys.mjs +42 -0
- package/bin/cli/api-commands/audio.mjs +40 -0
- package/bin/cli/api-commands/chat.mjs +58 -0
- package/bin/cli/api-commands/cli-tools.mjs +361 -0
- package/bin/cli/api-commands/cloud.mjs +81 -0
- package/bin/cli/api-commands/combos.mjs +69 -0
- package/bin/cli/api-commands/compression.mjs +128 -0
- package/bin/cli/api-commands/embedded-services.mjs +202 -0
- package/bin/cli/api-commands/embeddings.mjs +42 -0
- package/bin/cli/api-commands/fallback.mjs +49 -0
- package/bin/cli/api-commands/images.mjs +42 -0
- package/bin/cli/api-commands/memory.mjs +251 -0
- package/bin/cli/api-commands/messages.mjs +40 -0
- package/bin/cli/api-commands/models.mjs +89 -0
- package/bin/cli/api-commands/moderations.mjs +24 -0
- package/bin/cli/api-commands/oauth.mjs +114 -0
- package/bin/cli/api-commands/playground.mjs +83 -0
- package/bin/cli/api-commands/pricing.mjs +44 -0
- package/bin/cli/api-commands/provider-nodes.mjs +62 -0
- package/bin/cli/api-commands/providers.mjs +148 -0
- package/bin/cli/api-commands/quota.mjs +154 -0
- package/bin/cli/api-commands/registry.mjs +75 -0
- package/bin/cli/api-commands/rerank.mjs +24 -0
- package/bin/cli/api-commands/responses.mjs +24 -0
- package/bin/cli/api-commands/settings.mjs +228 -0
- package/bin/cli/api-commands/system.mjs +320 -0
- package/bin/cli/api-commands/telemetry.mjs +26 -0
- package/bin/cli/api-commands/traffic-inspector.mjs +307 -0
- package/bin/cli/api-commands/translator.mjs +65 -0
- package/bin/cli/api-commands/usage.mjs +117 -0
- package/bin/cli/api.mjs +269 -0
- package/bin/cli/commands/a2a.mjs +323 -0
- package/bin/cli/commands/audit.mjs +203 -0
- package/bin/cli/commands/autostart.mjs +57 -0
- package/bin/cli/commands/backup.mjs +469 -0
- package/bin/cli/commands/batches.mjs +235 -0
- package/bin/cli/commands/cache.mjs +102 -0
- package/bin/cli/commands/chat.mjs +162 -0
- package/bin/cli/commands/cloud.mjs +233 -0
- package/bin/cli/commands/combo.mjs +361 -0
- package/bin/cli/commands/completion.mjs +346 -0
- package/bin/cli/commands/compression.mjs +247 -0
- package/bin/cli/commands/config.mjs +351 -0
- package/bin/cli/commands/configure.mjs +180 -0
- package/bin/cli/commands/connect.mjs +132 -0
- package/bin/cli/commands/context-eng.mjs +182 -0
- package/bin/cli/commands/contexts.mjs +271 -0
- package/bin/cli/commands/cost.mjs +144 -0
- package/bin/cli/commands/dashboard.mjs +65 -0
- package/bin/cli/commands/doctor.mjs +527 -0
- package/bin/cli/commands/env.mjs +100 -0
- package/bin/cli/commands/eval.mjs +278 -0
- package/bin/cli/commands/files.mjs +144 -0
- package/bin/cli/commands/health.mjs +123 -0
- package/bin/cli/commands/keys.mjs +599 -0
- package/bin/cli/commands/launch-codex.mjs +201 -0
- package/bin/cli/commands/launch.mjs +155 -0
- package/bin/cli/commands/login.mjs +192 -0
- package/bin/cli/commands/logs.mjs +183 -0
- package/bin/cli/commands/mcp.mjs +273 -0
- package/bin/cli/commands/memory.mjs +244 -0
- package/bin/cli/commands/models.mjs +92 -0
- package/bin/cli/commands/nodes.mjs +177 -0
- package/bin/cli/commands/oauth.mjs +258 -0
- package/bin/cli/commands/oneproxy.mjs +120 -0
- package/bin/cli/commands/open.mjs +75 -0
- package/bin/cli/commands/openapi.mjs +168 -0
- package/bin/cli/commands/plugin.mjs +219 -0
- package/bin/cli/commands/policy.mjs +216 -0
- package/bin/cli/commands/pricing.mjs +123 -0
- package/bin/cli/commands/provider-cmd.mjs +18 -0
- package/bin/cli/commands/providers.mjs +706 -0
- package/bin/cli/commands/quota.mjs +100 -0
- package/bin/cli/commands/redis.mjs +294 -0
- package/bin/cli/commands/registry.mjs +162 -0
- package/bin/cli/commands/repl.mjs +19 -0
- package/bin/cli/commands/reset-encrypted-columns.mjs +88 -0
- package/bin/cli/commands/resilience.mjs +208 -0
- package/bin/cli/commands/restart.mjs +25 -0
- package/bin/cli/commands/runtime.mjs +98 -0
- package/bin/cli/commands/serve.mjs +426 -0
- package/bin/cli/commands/sessions.mjs +108 -0
- package/bin/cli/commands/setup-aider.mjs +146 -0
- package/bin/cli/commands/setup-claude.mjs +219 -0
- package/bin/cli/commands/setup-cline.mjs +160 -0
- package/bin/cli/commands/setup-codex.mjs +387 -0
- package/bin/cli/commands/setup-continue.mjs +173 -0
- package/bin/cli/commands/setup-crush.mjs +148 -0
- package/bin/cli/commands/setup-cursor.mjs +108 -0
- package/bin/cli/commands/setup-goose.mjs +150 -0
- package/bin/cli/commands/setup-kilo.mjs +178 -0
- package/bin/cli/commands/setup-open-code.mjs +398 -0
- package/bin/cli/commands/setup-opencode.mjs +129 -0
- package/bin/cli/commands/setup-qwen.mjs +156 -0
- package/bin/cli/commands/setup-roo.mjs +172 -0
- package/bin/cli/commands/setup.mjs +211 -0
- package/bin/cli/commands/simulate.mjs +125 -0
- package/bin/cli/commands/skills.mjs +373 -0
- package/bin/cli/commands/status.mjs +95 -0
- package/bin/cli/commands/stop.mjs +96 -0
- package/bin/cli/commands/stream.mjs +166 -0
- package/bin/cli/commands/sync.mjs +230 -0
- package/bin/cli/commands/tags.mjs +116 -0
- package/bin/cli/commands/telemetry.mjs +74 -0
- package/bin/cli/commands/test-provider.mjs +242 -0
- package/bin/cli/commands/tokens.mjs +118 -0
- package/bin/cli/commands/translator.mjs +131 -0
- package/bin/cli/commands/tray.mjs +36 -0
- package/bin/cli/commands/tunnel.mjs +347 -0
- package/bin/cli/commands/update.mjs +194 -0
- package/bin/cli/commands/usage.mjs +331 -0
- package/bin/cli/commands/webhooks.mjs +196 -0
- package/bin/cli/contexts.mjs +60 -0
- package/bin/cli/data-dir.mjs +59 -0
- package/bin/cli/encryption.mjs +67 -0
- package/bin/cli/i18n.mjs +106 -0
- package/bin/cli/io.mjs +83 -0
- package/bin/cli/locales/ar.json +32 -0
- package/bin/cli/locales/az.json +32 -0
- package/bin/cli/locales/bg.json +32 -0
- package/bin/cli/locales/bn.json +5 -0
- package/bin/cli/locales/cs.json +32 -0
- package/bin/cli/locales/da.json +32 -0
- package/bin/cli/locales/de.json +32 -0
- package/bin/cli/locales/en.json +1289 -0
- package/bin/cli/locales/es.json +32 -0
- package/bin/cli/locales/fa.json +32 -0
- package/bin/cli/locales/fi.json +32 -0
- package/bin/cli/locales/fr.json +32 -0
- package/bin/cli/locales/gu.json +5 -0
- package/bin/cli/locales/he.json +5 -0
- package/bin/cli/locales/hi.json +32 -0
- package/bin/cli/locales/hu.json +32 -0
- package/bin/cli/locales/id.json +32 -0
- package/bin/cli/locales/in.json +5 -0
- package/bin/cli/locales/it.json +32 -0
- package/bin/cli/locales/ja.json +32 -0
- package/bin/cli/locales/ko.json +32 -0
- package/bin/cli/locales/mr.json +5 -0
- package/bin/cli/locales/ms.json +5 -0
- package/bin/cli/locales/nl.json +32 -0
- package/bin/cli/locales/no.json +32 -0
- package/bin/cli/locales/phi.json +5 -0
- package/bin/cli/locales/pl.json +32 -0
- package/bin/cli/locales/pt-BR.json +1286 -0
- package/bin/cli/locales/pt.json +32 -0
- package/bin/cli/locales/ro.json +32 -0
- package/bin/cli/locales/ru.json +32 -0
- package/bin/cli/locales/sk.json +32 -0
- package/bin/cli/locales/sv.json +32 -0
- package/bin/cli/locales/sw.json +5 -0
- package/bin/cli/locales/ta.json +5 -0
- package/bin/cli/locales/te.json +5 -0
- package/bin/cli/locales/th.json +32 -0
- package/bin/cli/locales/tr.json +32 -0
- package/bin/cli/locales/uk-UA.json +32 -0
- package/bin/cli/locales/ur.json +5 -0
- package/bin/cli/locales/vi.json +32 -0
- package/bin/cli/locales/zh-CN.json +1262 -0
- package/bin/cli/output.mjs +200 -0
- package/bin/cli/plugins.mjs +90 -0
- package/bin/cli/program.mjs +40 -0
- package/bin/cli/provider-catalog.mjs +175 -0
- package/bin/cli/provider-store.mjs +312 -0
- package/bin/cli/provider-test.mjs +181 -0
- package/bin/cli/runtime/index.mjs +19 -0
- package/bin/cli/runtime/magicBytes.mjs +47 -0
- package/bin/cli/runtime/nativeDeps.mjs +137 -0
- package/bin/cli/runtime/processSupervisor.mjs +136 -0
- package/bin/cli/runtime/sqliteRuntime.mjs +129 -0
- package/bin/cli/runtime/supervisorPolicy.mjs +56 -0
- package/bin/cli/runtime/trayRuntime.ts +94 -0
- package/bin/cli/runtime.mjs +61 -0
- package/bin/cli/schemas/output-schemas.mjs +56 -0
- package/bin/cli/scripts/generate-locales.mjs +911 -0
- package/bin/cli/settings-store.mjs +45 -0
- package/bin/cli/spinner.mjs +30 -0
- package/bin/cli/sqlite.mjs +158 -0
- package/bin/cli/tray/autostart.mjs +410 -0
- package/bin/cli/tray/autostart.ts +18 -0
- package/bin/cli/tray/icon.png +0 -0
- package/bin/cli/tray/index.mjs +28 -0
- package/bin/cli/tray/tray.ps1 +99 -0
- package/bin/cli/tray/tray.ts +186 -0
- package/bin/cli/tray/traySystray.mjs +135 -0
- package/bin/cli/tray/trayWin.ts +91 -0
- package/bin/cli/tray/trayWindows.mjs +75 -0
- package/bin/cli/tui/Dashboard.jsx +70 -0
- package/bin/cli/tui/EvalWatch.jsx +171 -0
- package/bin/cli/tui/InterfaceMenu.jsx +55 -0
- package/bin/cli/tui/OAuthFlow.jsx +193 -0
- package/bin/cli/tui/ProvidersTestAll.jsx +190 -0
- package/bin/cli/tui/Repl.jsx +392 -0
- package/bin/cli/tui/session.mjs +54 -0
- package/bin/cli/tui/tabs/Combos.jsx +47 -0
- package/bin/cli/tui/tabs/Cost.jsx +52 -0
- package/bin/cli/tui/tabs/Health.jsx +53 -0
- package/bin/cli/tui/tabs/Keys.jsx +48 -0
- package/bin/cli/tui/tabs/Logs.jsx +60 -0
- package/bin/cli/tui/tabs/Overview.jsx +80 -0
- package/bin/cli/tui/tabs/Providers.jsx +48 -0
- package/bin/cli/tui-components/CodeBlock.jsx +15 -0
- package/bin/cli/tui-components/ConfirmDialog.jsx +40 -0
- package/bin/cli/tui-components/DataTable.jsx +50 -0
- package/bin/cli/tui-components/HeaderSwr.jsx +25 -0
- package/bin/cli/tui-components/KeyMaskedDisplay.jsx +12 -0
- package/bin/cli/tui-components/MarkdownView.jsx +13 -0
- package/bin/cli/tui-components/MenuSelect.jsx +38 -0
- package/bin/cli/tui-components/MultilineInput.jsx +18 -0
- package/bin/cli/tui-components/ProgressBar.jsx +15 -0
- package/bin/cli/tui-components/Sparkline.jsx +15 -0
- package/bin/cli/tui-components/StatusBadge.jsx +17 -0
- package/bin/cli/tui-components/TokenCounter.jsx +18 -0
- package/bin/cli/tui-components/theme.jsx +11 -0
- package/bin/cli/utils/cliToken.mjs +22 -0
- package/bin/cli/utils/clipboard.mjs +35 -0
- package/bin/cli/utils/environment.mjs +50 -0
- package/bin/cli/utils/pid.mjs +110 -0
- package/bin/cli/utils/storageKeyProvision.mjs +31 -0
- package/bin/cold-start-bench.sh +82 -0
- package/bin/mcp-server.mjs +71 -0
- package/bin/nodeRuntimeSupport.mjs +84 -0
- package/bin/omniroute.mjs +237 -0
- package/bin/reset-password.mjs +137 -0
- package/bin/restore-data.sh +64 -0
- package/bin/restore-policies.sh +77 -0
- package/bin/rollback.sh +102 -0
- package/bin/snapshot-data.sh +61 -0
- package/open-sse/config/agyModels.ts +157 -0
- package/open-sse/config/anthropicHeaders.ts +127 -0
- package/open-sse/config/antigravityModelAliases.ts +309 -0
- package/open-sse/config/antigravityUpstream.ts +20 -0
- package/open-sse/config/audioRegistry.ts +547 -0
- package/open-sse/config/azureAi.ts +49 -0
- package/open-sse/config/bedrock.ts +196 -0
- package/open-sse/config/cliFingerprints.ts +405 -0
- package/open-sse/config/codexClient.ts +49 -0
- package/open-sse/config/codexIdentity.ts +87 -0
- package/open-sse/config/codexInstructions.ts +122 -0
- package/open-sse/config/codexQuotaScopes.ts +87 -0
- package/open-sse/config/constants.ts +281 -0
- package/open-sse/config/contextEditing.ts +156 -0
- package/open-sse/config/credentialLoader.ts +123 -0
- package/open-sse/config/datarobot.ts +69 -0
- package/open-sse/config/defaultThinkingSignature.ts +8 -0
- package/open-sse/config/embeddingRegistry.ts +434 -0
- package/open-sse/config/errorConfig.ts +201 -0
- package/open-sse/config/freeModelCatalog.data.ts +467 -0
- package/open-sse/config/freeModelCatalog.ts +142 -0
- package/open-sse/config/freeTierCatalog.ts +101 -0
- package/open-sse/config/geminiRateLimits.json +34 -0
- package/open-sse/config/glmProvider.ts +488 -0
- package/open-sse/config/imageRegistry.ts +752 -0
- package/open-sse/config/maritalk.ts +18 -0
- package/open-sse/config/mediaServiceKinds.ts +70 -0
- package/open-sse/config/moderationRegistry.ts +89 -0
- package/open-sse/config/musicRegistry.ts +115 -0
- package/open-sse/config/oci.ts +44 -0
- package/open-sse/config/ocrRegistry.ts +82 -0
- package/open-sse/config/ollamaModels.ts +28 -0
- package/open-sse/config/providerErrorRules.ts +218 -0
- package/open-sse/config/providerFieldStrips.ts +42 -0
- package/open-sse/config/providerHeaderProfiles.ts +188 -0
- package/open-sse/config/providerModels.ts +199 -0
- package/open-sse/config/providerPluginManifest.ts +186 -0
- package/open-sse/config/providerPluginManifestRegistry.ts +31 -0
- package/open-sse/config/providerPluginManifestUrl.ts +26 -0
- package/open-sse/config/providerRegistry.ts +257 -0
- package/open-sse/config/providers/index.ts +377 -0
- package/open-sse/config/providers/registry/adapta-web/index.ts +20 -0
- package/open-sse/config/providers/registry/agentrouter/index.ts +24 -0
- package/open-sse/config/providers/registry/agy/index.ts +28 -0
- package/open-sse/config/providers/registry/ai21/index.ts +13 -0
- package/open-sse/config/providers/registry/aimlapi/index.ts +21 -0
- package/open-sse/config/providers/registry/alibaba/cn/index.ts +15 -0
- package/open-sse/config/providers/registry/alibaba/index.ts +15 -0
- package/open-sse/config/providers/registry/anthropic/index.ts +52 -0
- package/open-sse/config/providers/registry/antigravity/index.ts +28 -0
- package/open-sse/config/providers/registry/api-airforce/index.ts +57 -0
- package/open-sse/config/providers/registry/auggie/index.ts +38 -0
- package/open-sse/config/providers/registry/bai/index.ts +14 -0
- package/open-sse/config/providers/registry/baichuan/index.ts +20 -0
- package/open-sse/config/providers/registry/baidu/index.ts +31 -0
- package/open-sse/config/providers/registry/bailian-coding-plan/index.ts +27 -0
- package/open-sse/config/providers/registry/baseten/index.ts +13 -0
- package/open-sse/config/providers/registry/bazaarlink/index.ts +48 -0
- package/open-sse/config/providers/registry/bedrock/index.ts +49 -0
- package/open-sse/config/providers/registry/blackbox/index.ts +25 -0
- package/open-sse/config/providers/registry/blackbox/web/index.ts +19 -0
- package/open-sse/config/providers/registry/bluesminds/index.ts +39 -0
- package/open-sse/config/providers/registry/byteplus/index.ts +21 -0
- package/open-sse/config/providers/registry/bytez/index.ts +17 -0
- package/open-sse/config/providers/registry/cerebras/index.ts +16 -0
- package/open-sse/config/providers/registry/charm-hyper/index.ts +14 -0
- package/open-sse/config/providers/registry/chatgpt-web/index.ts +23 -0
- package/open-sse/config/providers/registry/chipotle/index.ts +14 -0
- package/open-sse/config/providers/registry/chutes/index.ts +12 -0
- package/open-sse/config/providers/registry/claude/index.ts +102 -0
- package/open-sse/config/providers/registry/claude/web/index.ts +16 -0
- package/open-sse/config/providers/registry/cline/index.ts +45 -0
- package/open-sse/config/providers/registry/clinepass/index.ts +47 -0
- package/open-sse/config/providers/registry/cloudflare-ai/index.ts +33 -0
- package/open-sse/config/providers/registry/codebuddy-cn/index.ts +151 -0
- package/open-sse/config/providers/registry/codestral/index.ts +13 -0
- package/open-sse/config/providers/registry/codex/index.ts +115 -0
- package/open-sse/config/providers/registry/cohere/index.ts +28 -0
- package/open-sse/config/providers/registry/command-code/index.ts +143 -0
- package/open-sse/config/providers/registry/copilot-m365-web/index.ts +12 -0
- package/open-sse/config/providers/registry/copilot-web/index.ts +16 -0
- package/open-sse/config/providers/registry/coze/index.ts +12 -0
- package/open-sse/config/providers/registry/crof/index.ts +38 -0
- package/open-sse/config/providers/registry/cursor/index.ts +111 -0
- package/open-sse/config/providers/registry/databricks/index.ts +13 -0
- package/open-sse/config/providers/registry/deepinfra/index.ts +13 -0
- package/open-sse/config/providers/registry/deepseek/index.ts +15 -0
- package/open-sse/config/providers/registry/deepseek/web/index.ts +35 -0
- package/open-sse/config/providers/registry/devin-cli/index.ts +68 -0
- package/open-sse/config/providers/registry/dgrid/index.ts +15 -0
- package/open-sse/config/providers/registry/dify/index.ts +12 -0
- package/open-sse/config/providers/registry/digitalocean/index.ts +11 -0
- package/open-sse/config/providers/registry/dit/index.ts +41 -0
- package/open-sse/config/providers/registry/doubao/index.ts +28 -0
- package/open-sse/config/providers/registry/doubao/web/index.ts +15 -0
- package/open-sse/config/providers/registry/duckduckgo-web/index.ts +19 -0
- package/open-sse/config/providers/registry/factory/index.ts +33 -0
- package/open-sse/config/providers/registry/featherless-ai/index.ts +13 -0
- package/open-sse/config/providers/registry/fireworks/index.ts +35 -0
- package/open-sse/config/providers/registry/freeaiapikey/index.ts +38 -0
- package/open-sse/config/providers/registry/freemodel-dev/index.ts +19 -0
- package/open-sse/config/providers/registry/friendliai/index.ts +16 -0
- package/open-sse/config/providers/registry/galadriel/index.ts +13 -0
- package/open-sse/config/providers/registry/gemini/index.ts +63 -0
- package/open-sse/config/providers/registry/gemini/web/index.ts +16 -0
- package/open-sse/config/providers/registry/gigachat/index.ts +13 -0
- package/open-sse/config/providers/registry/github/index.ts +161 -0
- package/open-sse/config/providers/registry/github/models/index.ts +38 -0
- package/open-sse/config/providers/registry/gitlab-duo/index.ts +29 -0
- package/open-sse/config/providers/registry/gitlawb/gmi/index.ts +19 -0
- package/open-sse/config/providers/registry/gitlawb/index.ts +18 -0
- package/open-sse/config/providers/registry/glhf/index.ts +12 -0
- package/open-sse/config/providers/registry/glm/cn/index.ts +17 -0
- package/open-sse/config/providers/registry/glm/index.ts +16 -0
- package/open-sse/config/providers/registry/glm/t/index.ts +16 -0
- package/open-sse/config/providers/registry/grok-cli/index.ts +32 -0
- package/open-sse/config/providers/registry/grok-web/index.ts +18 -0
- package/open-sse/config/providers/registry/groq/index.ts +25 -0
- package/open-sse/config/providers/registry/hackclub/index.ts +19 -0
- package/open-sse/config/providers/registry/haiper/index.ts +15 -0
- package/open-sse/config/providers/registry/hcnsec/index.ts +11 -0
- package/open-sse/config/providers/registry/heroku/index.ts +13 -0
- package/open-sse/config/providers/registry/huggingchat/index.ts +143 -0
- package/open-sse/config/providers/registry/huggingface/index.ts +20 -0
- package/open-sse/config/providers/registry/hyperbolic/index.ts +21 -0
- package/open-sse/config/providers/registry/ideogram/index.ts +15 -0
- package/open-sse/config/providers/registry/iflytek/index.ts +21 -0
- package/open-sse/config/providers/registry/inclusionai/index.ts +12 -0
- package/open-sse/config/providers/registry/inference-net/index.ts +13 -0
- package/open-sse/config/providers/registry/inner-ai/index.ts +43 -0
- package/open-sse/config/providers/registry/kenari/index.ts +14 -0
- package/open-sse/config/providers/registry/kie/index.ts +27 -0
- package/open-sse/config/providers/registry/kilo-gateway/index.ts +21 -0
- package/open-sse/config/providers/registry/kilocode/index.ts +43 -0
- package/open-sse/config/providers/registry/kimi/coding/index.ts +17 -0
- package/open-sse/config/providers/registry/kimi/coding-apikey/index.ts +9 -0
- package/open-sse/config/providers/registry/kimi/index.ts +17 -0
- package/open-sse/config/providers/registry/kimi/web/index.ts +27 -0
- package/open-sse/config/providers/registry/kiro/index.ts +50 -0
- package/open-sse/config/providers/registry/kluster/index.ts +12 -0
- package/open-sse/config/providers/registry/lambda-ai/index.ts +13 -0
- package/open-sse/config/providers/registry/leonardo/index.ts +15 -0
- package/open-sse/config/providers/registry/liquid/index.ts +12 -0
- package/open-sse/config/providers/registry/llamagate/index.ts +13 -0
- package/open-sse/config/providers/registry/llm7/index.ts +27 -0
- package/open-sse/config/providers/registry/longcat/index.ts +24 -0
- package/open-sse/config/providers/registry/maritalk/index.ts +13 -0
- package/open-sse/config/providers/registry/meta-llama/index.ts +13 -0
- package/open-sse/config/providers/registry/mimocode/index.ts +16 -0
- package/open-sse/config/providers/registry/minimax/cn/index.ts +24 -0
- package/open-sse/config/providers/registry/minimax/index.ts +24 -0
- package/open-sse/config/providers/registry/mistral/index.ts +18 -0
- package/open-sse/config/providers/registry/modal/index.ts +12 -0
- package/open-sse/config/providers/registry/modelscope/index.ts +24 -0
- package/open-sse/config/providers/registry/monsterapi/index.ts +17 -0
- package/open-sse/config/providers/registry/moonshot/index.ts +13 -0
- package/open-sse/config/providers/registry/morph/index.ts +13 -0
- package/open-sse/config/providers/registry/muse-spark-web/index.ts +24 -0
- package/open-sse/config/providers/registry/nanogpt/index.ts +13 -0
- package/open-sse/config/providers/registry/nebius/index.ts +9 -0
- package/open-sse/config/providers/registry/nlpcloud/index.ts +19 -0
- package/open-sse/config/providers/registry/nous-research/index.ts +15 -0
- package/open-sse/config/providers/registry/novita/index.ts +15 -0
- package/open-sse/config/providers/registry/nscale/index.ts +13 -0
- package/open-sse/config/providers/registry/nube/index.ts +17 -0
- package/open-sse/config/providers/registry/nvidia/index.ts +36 -0
- package/open-sse/config/providers/registry/ollama-cloud/index.ts +27 -0
- package/open-sse/config/providers/registry/openadapter/index.ts +25 -0
- package/open-sse/config/providers/registry/openai/index.ts +43 -0
- package/open-sse/config/providers/registry/opencode/go/index.ts +61 -0
- package/open-sse/config/providers/registry/opencode/index.ts +51 -0
- package/open-sse/config/providers/registry/opencode/zen/index.ts +98 -0
- package/open-sse/config/providers/registry/openrouter/index.ts +17 -0
- package/open-sse/config/providers/registry/orcarouter/index.ts +87 -0
- package/open-sse/config/providers/registry/ovhcloud/index.ts +13 -0
- package/open-sse/config/providers/registry/perplexity/index.ts +22 -0
- package/open-sse/config/providers/registry/perplexity/web/index.ts +23 -0
- package/open-sse/config/providers/registry/pioneer/index.ts +41 -0
- package/open-sse/config/providers/registry/pollinations/index.ts +51 -0
- package/open-sse/config/providers/registry/predibase/index.ts +13 -0
- package/open-sse/config/providers/registry/publicai/index.ts +13 -0
- package/open-sse/config/providers/registry/puter/index.ts +70 -0
- package/open-sse/config/providers/registry/qianfan/index.ts +18 -0
- package/open-sse/config/providers/registry/qiniu/index.ts +15 -0
- package/open-sse/config/providers/registry/qoder/index.ts +37 -0
- package/open-sse/config/providers/registry/qwen/index.ts +25 -0
- package/open-sse/config/providers/registry/qwen/web/index.ts +24 -0
- package/open-sse/config/providers/registry/reka/index.ts +18 -0
- package/open-sse/config/providers/registry/requesty/index.ts +11 -0
- package/open-sse/config/providers/registry/sambanova/index.ts +13 -0
- package/open-sse/config/providers/registry/scaleway/index.ts +20 -0
- package/open-sse/config/providers/registry/sensenova/index.ts +27 -0
- package/open-sse/config/providers/registry/siliconflow/index.ts +84 -0
- package/open-sse/config/providers/registry/snowflake/index.ts +13 -0
- package/open-sse/config/providers/registry/sparkdesk/index.ts +20 -0
- package/open-sse/config/providers/registry/stepfun/index.ts +20 -0
- package/open-sse/config/providers/registry/sumopod/index.ts +15 -0
- package/open-sse/config/providers/registry/suno/index.ts +18 -0
- package/open-sse/config/providers/registry/synthetic/index.ts +21 -0
- package/open-sse/config/providers/registry/t3-web/index.ts +45 -0
- package/open-sse/config/providers/registry/tencent/index.ts +25 -0
- package/open-sse/config/providers/registry/theoldllm/index.ts +51 -0
- package/open-sse/config/providers/registry/together/index.ts +20 -0
- package/open-sse/config/providers/registry/tokenrouter/index.ts +44 -0
- package/open-sse/config/providers/registry/trae/index.ts +24 -0
- package/open-sse/config/providers/registry/udio/index.ts +12 -0
- package/open-sse/config/providers/registry/uncloseai/index.ts +19 -0
- package/open-sse/config/providers/registry/upstage/index.ts +13 -0
- package/open-sse/config/providers/registry/v0-vercel/index.ts +13 -0
- package/open-sse/config/providers/registry/venice/index.ts +13 -0
- package/open-sse/config/providers/registry/veoaifree-web/index.ts +15 -0
- package/open-sse/config/providers/registry/vercel-ai-gateway/index.ts +13 -0
- package/open-sse/config/providers/registry/vertex/index.ts +33 -0
- package/open-sse/config/providers/registry/vertex/partner/index.ts +22 -0
- package/open-sse/config/providers/registry/volcengine/index.ts +13 -0
- package/open-sse/config/providers/registry/wafer/index.ts +19 -0
- package/open-sse/config/providers/registry/wandb/index.ts +13 -0
- package/open-sse/config/providers/registry/windsurf/index.ts +119 -0
- package/open-sse/config/providers/registry/x5lab/index.ts +15 -0
- package/open-sse/config/providers/registry/xai/index.ts +18 -0
- package/open-sse/config/providers/registry/xiaomi-mimo/index.ts +13 -0
- package/open-sse/config/providers/registry/yi/index.ts +12 -0
- package/open-sse/config/providers/registry/yuanbao-web/index.ts +37 -0
- package/open-sse/config/providers/registry/zai/index.ts +28 -0
- package/open-sse/config/providers/registry/zed-hosted/index.ts +35 -0
- package/open-sse/config/providers/registry/zenmux/index.ts +87 -0
- package/open-sse/config/providers/registry/zenmux-free/index.ts +40 -0
- package/open-sse/config/providers/shared.ts +766 -0
- package/open-sse/config/registryUtils.ts +134 -0
- package/open-sse/config/rerankRegistry.ts +196 -0
- package/open-sse/config/runway.ts +39 -0
- package/open-sse/config/sap.ts +58 -0
- package/open-sse/config/searchRegistry.ts +317 -0
- package/open-sse/config/toolCloaking.ts +253 -0
- package/open-sse/config/videoRegistry.ts +229 -0
- package/open-sse/config/watsonx.ts +43 -0
- package/open-sse/executors/adapta-web.ts +564 -0
- package/open-sse/executors/antigravity/sseCollect.ts +148 -0
- package/open-sse/executors/antigravity.ts +1716 -0
- package/open-sse/executors/antigravityUpstreamError.ts +25 -0
- package/open-sse/executors/auggie.ts +573 -0
- package/open-sse/executors/azure-openai.ts +48 -0
- package/open-sse/executors/base/headers.ts +93 -0
- package/open-sse/executors/base/reasoningEffort.ts +160 -0
- package/open-sse/executors/base.ts +1315 -0
- package/open-sse/executors/bedrock.ts +714 -0
- package/open-sse/executors/blackbox-web.ts +708 -0
- package/open-sse/executors/chatgpt-web/models.ts +133 -0
- package/open-sse/executors/chatgpt-web.ts +3107 -0
- package/open-sse/executors/chatgptWebErrors.ts +18 -0
- package/open-sse/executors/chatgptWebTools.ts +127 -0
- package/open-sse/executors/chipotle.ts +432 -0
- package/open-sse/executors/claude-web/payload.ts +230 -0
- package/open-sse/executors/claude-web-with-auto-refresh.ts +117 -0
- package/open-sse/executors/claude-web.ts +833 -0
- package/open-sse/executors/claudeIdentity.ts +445 -0
- package/open-sse/executors/cliproxyapi.ts +466 -0
- package/open-sse/executors/cloudflare-ai.ts +97 -0
- package/open-sse/executors/codebuddy-cn.ts +53 -0
- package/open-sse/executors/codex/quota.ts +114 -0
- package/open-sse/executors/codex/tools.ts +165 -0
- package/open-sse/executors/codex.ts +1270 -0
- package/open-sse/executors/commandCode.ts +716 -0
- package/open-sse/executors/copilot-m365-connection.ts +271 -0
- package/open-sse/executors/copilot-m365-frames.ts +279 -0
- package/open-sse/executors/copilot-m365-web.ts +341 -0
- package/open-sse/executors/copilot-web.ts +722 -0
- package/open-sse/executors/cursor/composer.ts +53 -0
- package/open-sse/executors/cursor/prompt.ts +75 -0
- package/open-sse/executors/cursor.ts +1465 -0
- package/open-sse/executors/deepseek-web/stream-format.ts +44 -0
- package/open-sse/executors/deepseek-web-with-auto-refresh.ts +184 -0
- package/open-sse/executors/deepseek-web.ts +1123 -0
- package/open-sse/executors/default/urlNormalizers.ts +64 -0
- package/open-sse/executors/default.ts +873 -0
- package/open-sse/executors/devin-cli.ts +470 -0
- package/open-sse/executors/doubao-web.ts +665 -0
- package/open-sse/executors/duckduckgo-web/challenge.ts +151 -0
- package/open-sse/executors/duckduckgo-web.ts +782 -0
- package/open-sse/executors/firecrawl-fetch.ts +177 -0
- package/open-sse/executors/forceResponsesUpstream.ts +60 -0
- package/open-sse/executors/gemini-business.ts +446 -0
- package/open-sse/executors/gemini-web.ts +413 -0
- package/open-sse/executors/github.ts +376 -0
- package/open-sse/executors/gitlab.ts +793 -0
- package/open-sse/executors/gitlabResponses.ts +191 -0
- package/open-sse/executors/glm.ts +520 -0
- package/open-sse/executors/grok-cli.ts +253 -0
- package/open-sse/executors/grok-web/native-tools.ts +182 -0
- package/open-sse/executors/grok-web/text-cleanup.ts +137 -0
- package/open-sse/executors/grok-web/tool-bridge.ts +666 -0
- package/open-sse/executors/grok-web/types.ts +47 -0
- package/open-sse/executors/grok-web.ts +883 -0
- package/open-sse/executors/huggingchat/jsonlStream.ts +221 -0
- package/open-sse/executors/huggingchat.ts +593 -0
- package/open-sse/executors/index.ts +232 -0
- package/open-sse/executors/inner-ai.ts +764 -0
- package/open-sse/executors/jina-reader-fetch.ts +119 -0
- package/open-sse/executors/kie.ts +109 -0
- package/open-sse/executors/kimi-web.ts +455 -0
- package/open-sse/executors/kimi.ts +133 -0
- package/open-sse/executors/kiro/eventstream.ts +192 -0
- package/open-sse/executors/kiro.ts +821 -0
- package/open-sse/executors/kiroThinking.ts +116 -0
- package/open-sse/executors/lmarena.ts +511 -0
- package/open-sse/executors/mimocode.ts +560 -0
- package/open-sse/executors/muse-spark-web/response-parser.ts +383 -0
- package/open-sse/executors/muse-spark-web.ts +928 -0
- package/open-sse/executors/ninerouter.ts +212 -0
- package/open-sse/executors/nlpcloud.ts +546 -0
- package/open-sse/executors/opencode.ts +336 -0
- package/open-sse/executors/perplexity-web/protocol.ts +503 -0
- package/open-sse/executors/perplexity-web.ts +545 -0
- package/open-sse/executors/poe-web.ts +158 -0
- package/open-sse/executors/pollinations.ts +119 -0
- package/open-sse/executors/puter.ts +59 -0
- package/open-sse/executors/qoder.ts +416 -0
- package/open-sse/executors/qwen-web.ts +474 -0
- package/open-sse/executors/t3-chat-web.ts +582 -0
- package/open-sse/executors/tavily-fetch.ts +103 -0
- package/open-sse/executors/theoldllm.ts +354 -0
- package/open-sse/executors/tinyfish-fetch.ts +131 -0
- package/open-sse/executors/trae.ts +481 -0
- package/open-sse/executors/v0-vercel-web.ts +164 -0
- package/open-sse/executors/venice-web.ts +165 -0
- package/open-sse/executors/veoaifree-web.ts +397 -0
- package/open-sse/executors/vertex.ts +208 -0
- package/open-sse/executors/vertexMedia.ts +341 -0
- package/open-sse/executors/windsurf.ts +706 -0
- package/open-sse/executors/xai.ts +94 -0
- package/open-sse/executors/yuanbao-web.ts +504 -0
- package/open-sse/executors/zed-hosted.ts +364 -0
- package/open-sse/executors/zenmux-free.ts +283 -0
- package/open-sse/handlers/audioSpeech.ts +1060 -0
- package/open-sse/handlers/audioTranscription.ts +554 -0
- package/open-sse/handlers/audioTranslation.ts +135 -0
- package/open-sse/handlers/chatCore/attemptLogging.ts +210 -0
- package/open-sse/handlers/chatCore/backgroundRedirect.ts +41 -0
- package/open-sse/handlers/chatCore/cacheUsageMeta.ts +65 -0
- package/open-sse/handlers/chatCore/cavemanOutputAnalytics.ts +47 -0
- package/open-sse/handlers/chatCore/claudeClassifierCompat.ts +99 -0
- package/open-sse/handlers/chatCore/claudeEffortVariant.ts +62 -0
- package/open-sse/handlers/chatCore/claudeMessageTypes.ts +15 -0
- package/open-sse/handlers/chatCore/claudeSystemRole.ts +48 -0
- package/open-sse/handlers/chatCore/claudeToolDefaults.ts +27 -0
- package/open-sse/handlers/chatCore/claudeUpstreamMessages.ts +143 -0
- package/open-sse/handlers/chatCore/clientUsageBuffer.ts +54 -0
- package/open-sse/handlers/chatCore/clineResponseEnvelope.ts +25 -0
- package/open-sse/handlers/chatCore/codexFailover.ts +41 -0
- package/open-sse/handlers/chatCore/codexQuota.ts +85 -0
- package/open-sse/handlers/chatCore/comboContextCache.ts +63 -0
- package/open-sse/handlers/chatCore/compressionAnalyticsWrite.ts +149 -0
- package/open-sse/handlers/chatCore/compressionCacheStats.ts +53 -0
- package/open-sse/handlers/chatCore/compressionComboPredicates.ts +41 -0
- package/open-sse/handlers/chatCore/compressionSettings.ts +35 -0
- package/open-sse/handlers/chatCore/compressionUsageReceipt.ts +27 -0
- package/open-sse/handlers/chatCore/contextEditingTelemetry.ts +40 -0
- package/open-sse/handlers/chatCore/cooldownClassification.ts +26 -0
- package/open-sse/handlers/chatCore/executionCredentials.ts +72 -0
- package/open-sse/handlers/chatCore/executorClientHeaders.ts +36 -0
- package/open-sse/handlers/chatCore/executorHelpers.ts +151 -0
- package/open-sse/handlers/chatCore/executorProxy.ts +117 -0
- package/open-sse/handlers/chatCore/failureUsage.ts +41 -0
- package/open-sse/handlers/chatCore/gamificationEvent.ts +28 -0
- package/open-sse/handlers/chatCore/headers.ts +65 -0
- package/open-sse/handlers/chatCore/idempotency.ts +65 -0
- package/open-sse/handlers/chatCore/jsonBodyToSse.ts +161 -0
- package/open-sse/handlers/chatCore/keyHealth.ts +113 -0
- package/open-sse/handlers/chatCore/logTruncation.ts +93 -0
- package/open-sse/handlers/chatCore/memoryExtraction.ts +131 -0
- package/open-sse/handlers/chatCore/memorySkillsInjection.ts +165 -0
- package/open-sse/handlers/chatCore/nonStreamingJsonResponse.ts +16 -0
- package/open-sse/handlers/chatCore/nonStreamingResponseBody.ts +155 -0
- package/open-sse/handlers/chatCore/nonStreamingResponseHeaders.ts +46 -0
- package/open-sse/handlers/chatCore/nonStreamingResponseParse.ts +135 -0
- package/open-sse/handlers/chatCore/nonStreamingSse.ts +171 -0
- package/open-sse/handlers/chatCore/nonStreamingUsageStats.ts +90 -0
- package/open-sse/handlers/chatCore/outputStyleTelemetry.ts +53 -0
- package/open-sse/handlers/chatCore/passthroughHelpers.ts +83 -0
- package/open-sse/handlers/chatCore/passthroughToolNames.ts +65 -0
- package/open-sse/handlers/chatCore/pluginOnRequest.ts +65 -0
- package/open-sse/handlers/chatCore/pluginOnResponse.ts +34 -0
- package/open-sse/handlers/chatCore/postCallGuardrailContext.ts +47 -0
- package/open-sse/handlers/chatCore/quotaShareConsumption.ts +41 -0
- package/open-sse/handlers/chatCore/requestFormat.ts +111 -0
- package/open-sse/handlers/chatCore/requestSetup.ts +51 -0
- package/open-sse/handlers/chatCore/responseHeaders.ts +138 -0
- package/open-sse/handlers/chatCore/sanitization.ts +63 -0
- package/open-sse/handlers/chatCore/semanticCache.ts +98 -0
- package/open-sse/handlers/chatCore/semanticCacheStore.ts +73 -0
- package/open-sse/handlers/chatCore/serviceTier.ts +70 -0
- package/open-sse/handlers/chatCore/skillsFormat.ts +33 -0
- package/open-sse/handlers/chatCore/stageTrace.ts +30 -0
- package/open-sse/handlers/chatCore/streamErrorResult.ts +58 -0
- package/open-sse/handlers/chatCore/streamFinalize.ts +48 -0
- package/open-sse/handlers/chatCore/streamingCost.ts +37 -0
- package/open-sse/handlers/chatCore/streamingPipeline.ts +99 -0
- package/open-sse/handlers/chatCore/streamingQuotaShare.ts +54 -0
- package/open-sse/handlers/chatCore/streamingResponseHeaders.ts +39 -0
- package/open-sse/handlers/chatCore/streamingSemanticCacheStore.ts +95 -0
- package/open-sse/handlers/chatCore/streamingUsageStats.ts +79 -0
- package/open-sse/handlers/chatCore/targetFormat.ts +34 -0
- package/open-sse/handlers/chatCore/telemetryHelpers.ts +78 -0
- package/open-sse/handlers/chatCore/upstreamBody.ts +168 -0
- package/open-sse/handlers/chatCore/upstreamExecuteHeaders.ts +71 -0
- package/open-sse/handlers/chatCore/upstreamTimeouts.ts +158 -0
- package/open-sse/handlers/chatCore.ts +4452 -0
- package/open-sse/handlers/embeddings.ts +378 -0
- package/open-sse/handlers/imageGeneration/providers/chatgptWeb.ts +187 -0
- package/open-sse/handlers/imageGeneration/providers/comfyUI.ts +116 -0
- package/open-sse/handlers/imageGeneration/providers/haiper.ts +120 -0
- package/open-sse/handlers/imageGeneration/providers/huggingface.ts +90 -0
- package/open-sse/handlers/imageGeneration/providers/hyperbolic.ts +100 -0
- package/open-sse/handlers/imageGeneration/providers/ideogram.ts +96 -0
- package/open-sse/handlers/imageGeneration/providers/imagen3.ts +136 -0
- package/open-sse/handlers/imageGeneration/providers/leonardo.ts +140 -0
- package/open-sse/handlers/imageGeneration/providers/nvidiaNim.ts +286 -0
- package/open-sse/handlers/imageGeneration/providers/sdWebUI.ts +94 -0
- package/open-sse/handlers/imageGeneration.ts +2880 -0
- package/open-sse/handlers/moderations.ts +82 -0
- package/open-sse/handlers/musicGeneration.ts +640 -0
- package/open-sse/handlers/ocr.ts +79 -0
- package/open-sse/handlers/rerank.ts +210 -0
- package/open-sse/handlers/responseSanitizer/reasoning.ts +149 -0
- package/open-sse/handlers/responseSanitizer.ts +1086 -0
- package/open-sse/handlers/responseTranslator.ts +640 -0
- package/open-sse/handlers/responsesHandler.ts +92 -0
- package/open-sse/handlers/search.ts +1545 -0
- package/open-sse/handlers/sseParser.ts +825 -0
- package/open-sse/handlers/usageExtractor.ts +93 -0
- package/open-sse/handlers/videoGeneration/googleFlow.ts +219 -0
- package/open-sse/handlers/videoGeneration/googleFlowHandler.ts +145 -0
- package/open-sse/handlers/videoGeneration.ts +1264 -0
- package/open-sse/handlers/webFetch.ts +130 -0
- package/open-sse/index.ts +170 -0
- package/open-sse/lib/deepseek-pow-solver.cjs +3 -0
- package/open-sse/lib/deepseek-pow.ts +189 -0
- package/open-sse/lib/sha3_wasm_bg.wasm +0 -0
- package/open-sse/mcp-server/README.md +611 -0
- package/open-sse/mcp-server/audit.ts +478 -0
- package/open-sse/mcp-server/catalog.ts +290 -0
- package/open-sse/mcp-server/descriptionCompressor.ts +243 -0
- package/open-sse/mcp-server/httpAuthContext.ts +42 -0
- package/open-sse/mcp-server/httpTransport.ts +306 -0
- package/open-sse/mcp-server/index.ts +19 -0
- package/open-sse/mcp-server/mcpCallerIdentity.ts +53 -0
- package/open-sse/mcp-server/runtimeHeartbeat.ts +162 -0
- package/open-sse/mcp-server/schemas/a2a.ts +203 -0
- package/open-sse/mcp-server/schemas/audit.ts +121 -0
- package/open-sse/mcp-server/schemas/index.ts +116 -0
- package/open-sse/mcp-server/schemas/pickFastestModel.ts +110 -0
- package/open-sse/mcp-server/schemas/toolDefinition.ts +31 -0
- package/open-sse/mcp-server/schemas/toolSearch.ts +37 -0
- package/open-sse/mcp-server/schemas/tools.ts +1481 -0
- package/open-sse/mcp-server/scopeEnforcement.ts +135 -0
- package/open-sse/mcp-server/server.ts +1370 -0
- package/open-sse/mcp-server/toolCardinality.ts +254 -0
- package/open-sse/mcp-server/toolSearch/catalog.ts +98 -0
- package/open-sse/mcp-server/toolSearch/handler.ts +18 -0
- package/open-sse/mcp-server/toolSearch/index.ts +5 -0
- package/open-sse/mcp-server/toolSearch/register.ts +36 -0
- package/open-sse/mcp-server/toolSearch/search.ts +96 -0
- package/open-sse/mcp-server/toolSearch/signature.ts +92 -0
- package/open-sse/mcp-server/tools/advancedTools.ts +1119 -0
- package/open-sse/mcp-server/tools/agentSkillTools.ts +83 -0
- package/open-sse/mcp-server/tools/compressionTools.ts +451 -0
- package/open-sse/mcp-server/tools/gamificationTools.ts +148 -0
- package/open-sse/mcp-server/tools/githubSkillTools.ts +141 -0
- package/open-sse/mcp-server/tools/memoryTools.ts +137 -0
- package/open-sse/mcp-server/tools/notionTools.ts +106 -0
- package/open-sse/mcp-server/tools/obsidianTools.ts +327 -0
- package/open-sse/mcp-server/tools/pickFastestModel.ts +293 -0
- package/open-sse/mcp-server/tools/pluginTools.ts +216 -0
- package/open-sse/mcp-server/tools/poolTools.ts +205 -0
- package/open-sse/mcp-server/tools/skillTools.ts +119 -0
- package/open-sse/package.json +17 -0
- package/open-sse/services/AGENTS.md +78 -0
- package/open-sse/services/accountFallback.ts +1863 -0
- package/open-sse/services/accountSelector.ts +80 -0
- package/open-sse/services/accountSemaphore.ts +367 -0
- package/open-sse/services/antigravity429Engine.ts +178 -0
- package/open-sse/services/antigravityClientProfile.ts +167 -0
- package/open-sse/services/antigravityCredits.ts +68 -0
- package/open-sse/services/antigravityHeaderScrub.ts +75 -0
- package/open-sse/services/antigravityHeaders.ts +121 -0
- package/open-sse/services/antigravityIdentity.ts +127 -0
- package/open-sse/services/antigravityObfuscation.ts +64 -0
- package/open-sse/services/antigravityProjectBootstrap.ts +145 -0
- package/open-sse/services/antigravityQuotaFamily.ts +56 -0
- package/open-sse/services/antigravityVersion.ts +163 -0
- package/open-sse/services/apiKeyRotator.ts +385 -0
- package/open-sse/services/autoCombo/autoPrefix.ts +61 -0
- package/open-sse/services/autoCombo/builtinCatalog.ts +126 -0
- package/open-sse/services/autoCombo/complexityRouter.ts +111 -0
- package/open-sse/services/autoCombo/engine.ts +314 -0
- package/open-sse/services/autoCombo/index.ts +18 -0
- package/open-sse/services/autoCombo/modePacks.ts +105 -0
- package/open-sse/services/autoCombo/modelFamily.ts +95 -0
- package/open-sse/services/autoCombo/paidModelFilter.ts +44 -0
- package/open-sse/services/autoCombo/persistence.ts +124 -0
- package/open-sse/services/autoCombo/pipelineRouter.ts +418 -0
- package/open-sse/services/autoCombo/providerDiversity.ts +170 -0
- package/open-sse/services/autoCombo/providerRegistryAccessor.ts +9 -0
- package/open-sse/services/autoCombo/requestControls.ts +80 -0
- package/open-sse/services/autoCombo/routerStrategy.ts +375 -0
- package/open-sse/services/autoCombo/scoring.ts +242 -0
- package/open-sse/services/autoCombo/selfHealing.ts +167 -0
- package/open-sse/services/autoCombo/speedRanking.ts +327 -0
- package/open-sse/services/autoCombo/suffixComposition.ts +147 -0
- package/open-sse/services/autoCombo/taskFitness.ts +407 -0
- package/open-sse/services/autoCombo/virtualFactory.ts +446 -0
- package/open-sse/services/autoRefreshDaemon.ts +206 -0
- package/open-sse/services/backgroundTaskDetector.ts +263 -0
- package/open-sse/services/bailianQuotaFetcher.ts +333 -0
- package/open-sse/services/batchProcessor.ts +914 -0
- package/open-sse/services/bedrock.ts +160 -0
- package/open-sse/services/browserBackedChat.ts +849 -0
- package/open-sse/services/browserPool.ts +501 -0
- package/open-sse/services/ccBridgeTransforms.ts +581 -0
- package/open-sse/services/ccWireImageBuiltins.ts +26 -0
- package/open-sse/services/chatgptImageCache.ts +143 -0
- package/open-sse/services/chatgptTlsClient.ts +628 -0
- package/open-sse/services/claudeAdaptiveThinking.ts +52 -0
- package/open-sse/services/claudeCodeCCH.ts +49 -0
- package/open-sse/services/claudeCodeCompatible.ts +1198 -0
- package/open-sse/services/claudeCodeCompatibleBeta.ts +23 -0
- package/open-sse/services/claudeCodeCompatibleThinkingDisplay.ts +34 -0
- package/open-sse/services/claudeCodeConstraints.ts +144 -0
- package/open-sse/services/claudeCodeExtraRemap.ts +18 -0
- package/open-sse/services/claudeCodeFingerprint.ts +46 -0
- package/open-sse/services/claudeCodeObfuscation.ts +116 -0
- package/open-sse/services/claudeCodeToolRemapper.ts +339 -0
- package/open-sse/services/claudeHaikuConstraints.ts +88 -0
- package/open-sse/services/claudeTlsClient.ts +590 -0
- package/open-sse/services/claudeTurnstileSolver.ts +206 -0
- package/open-sse/services/claudeUsageCooldown.ts +51 -0
- package/open-sse/services/claudeWebAutoRefresh.ts +224 -0
- package/open-sse/services/clinepassModels.ts +76 -0
- package/open-sse/services/cloudCodeHeaders.ts +41 -0
- package/open-sse/services/cloudCodeThinking.ts +71 -0
- package/open-sse/services/codeAssistSubscription.ts +83 -0
- package/open-sse/services/codexQuotaFetcher.ts +523 -0
- package/open-sse/services/codexUsageQuotas.ts +270 -0
- package/open-sse/services/codexVerbosity.ts +59 -0
- package/open-sse/services/combo/applyStrategyOrdering.ts +226 -0
- package/open-sse/services/combo/autoConfig.ts +62 -0
- package/open-sse/services/combo/autoStrategy.ts +475 -0
- package/open-sse/services/combo/comboCompatFallback.ts +82 -0
- package/open-sse/services/combo/comboCooldownRetry.ts +237 -0
- package/open-sse/services/combo/comboData.ts +24 -0
- package/open-sse/services/combo/comboPredicates.ts +211 -0
- package/open-sse/services/combo/comboSetup.ts +135 -0
- package/open-sse/services/combo/comboStructure.ts +766 -0
- package/open-sse/services/combo/concurrencyCaps.ts +76 -0
- package/open-sse/services/combo/context.ts +46 -0
- package/open-sse/services/combo/fingerprintExpansion.ts +105 -0
- package/open-sse/services/combo/headroomRanking.ts +91 -0
- package/open-sse/services/combo/providerWildcard.ts +253 -0
- package/open-sse/services/combo/quotaExhaustionCutoff.ts +140 -0
- package/open-sse/services/combo/quotaScoring.ts +311 -0
- package/open-sse/services/combo/quotaShareConcurrency.ts +74 -0
- package/open-sse/services/combo/quotaShareInflight.ts +133 -0
- package/open-sse/services/combo/quotaShareStrategy.ts +349 -0
- package/open-sse/services/combo/quotaStrategies.ts +647 -0
- package/open-sse/services/combo/resolveAutoStrategy.ts +334 -0
- package/open-sse/services/combo/responseValidation.ts +206 -0
- package/open-sse/services/combo/rrState.ts +98 -0
- package/open-sse/services/combo/runtimeUnits.ts +269 -0
- package/open-sse/services/combo/sessionStickiness.ts +301 -0
- package/open-sse/services/combo/shadowRouting.ts +179 -0
- package/open-sse/services/combo/targetExhaustion.ts +160 -0
- package/open-sse/services/combo/targetSorters.ts +174 -0
- package/open-sse/services/combo/targetTimeoutRunner.ts +91 -0
- package/open-sse/services/combo/types.ts +175 -0
- package/open-sse/services/combo/validateQuality.ts +445 -0
- package/open-sse/services/combo.ts +3085 -0
- package/open-sse/services/comboAgentMiddleware.ts +214 -0
- package/open-sse/services/comboConfig.ts +248 -0
- package/open-sse/services/comboManifestMetrics.ts +13 -0
- package/open-sse/services/comboMetrics.ts +480 -0
- package/open-sse/services/compression/adaptiveCompression/computeTarget.ts +31 -0
- package/open-sse/services/compression/adaptiveCompression/ladder.ts +59 -0
- package/open-sse/services/compression/adaptiveCompression/resolveAdaptivePlan.ts +104 -0
- package/open-sse/services/compression/adaptiveCompression/types.ts +61 -0
- package/open-sse/services/compression/aggressive.ts +204 -0
- package/open-sse/services/compression/bodyAdapter.ts +354 -0
- package/open-sse/services/compression/cacheAwareConfig.ts +60 -0
- package/open-sse/services/compression/cachingAware.ts +130 -0
- package/open-sse/services/compression/caveman.ts +602 -0
- package/open-sse/services/compression/cavemanRules.ts +432 -0
- package/open-sse/services/compression/deriveDefaultPlan.ts +59 -0
- package/open-sse/services/compression/diffHelper.ts +219 -0
- package/open-sse/services/compression/engineBreakdown.ts +29 -0
- package/open-sse/services/compression/engineCatalog.ts +91 -0
- package/open-sse/services/compression/engines/cavemanAdapter.ts +454 -0
- package/open-sse/services/compression/engines/ccr/ccrQuery.ts +110 -0
- package/open-sse/services/compression/engines/ccr/index.ts +460 -0
- package/open-sse/services/compression/engines/headroom/encoderComparison.ts +72 -0
- package/open-sse/services/compression/engines/headroom/gcf/decode_generic.ts +711 -0
- package/open-sse/services/compression/engines/headroom/gcf/generic.ts +332 -0
- package/open-sse/services/compression/engines/headroom/gcf/index.ts +9 -0
- package/open-sse/services/compression/engines/headroom/gcf/scalar.ts +336 -0
- package/open-sse/services/compression/engines/headroom/index.ts +286 -0
- package/open-sse/services/compression/engines/headroom/smartcrusher.ts +255 -0
- package/open-sse/services/compression/engines/headroom/tabular.ts +263 -0
- package/open-sse/services/compression/engines/headroom/toon.ts +43 -0
- package/open-sse/services/compression/engines/index.ts +42 -0
- package/open-sse/services/compression/engines/ionizer/index.ts +124 -0
- package/open-sse/services/compression/engines/ionizer/sample.ts +200 -0
- package/open-sse/services/compression/engines/llm/index.ts +346 -0
- package/open-sse/services/compression/engines/llmlingua/constants.ts +55 -0
- package/open-sse/services/compression/engines/llmlingua/index.ts +474 -0
- package/open-sse/services/compression/engines/llmlingua/modelStore.ts +67 -0
- package/open-sse/services/compression/engines/llmlingua/onnxWorker.ts +117 -0
- package/open-sse/services/compression/engines/llmlingua/ultraEntry.ts +109 -0
- package/open-sse/services/compression/engines/llmlingua/worker.ts +373 -0
- package/open-sse/services/compression/engines/mcpAccessibility/collapseRepeated.ts +121 -0
- package/open-sse/services/compression/engines/mcpAccessibility/constants.ts +63 -0
- package/open-sse/services/compression/engines/mcpAccessibility/index.ts +52 -0
- package/open-sse/services/compression/engines/readLifecycle/index.ts +299 -0
- package/open-sse/services/compression/engines/registry.ts +87 -0
- package/open-sse/services/compression/engines/relevance/configSchema.ts +63 -0
- package/open-sse/services/compression/engines/relevance/index.ts +185 -0
- package/open-sse/services/compression/engines/relevance/scorer.ts +85 -0
- package/open-sse/services/compression/engines/rtk/codeStripper.ts +145 -0
- package/open-sse/services/compression/engines/rtk/commandDetector.ts +482 -0
- package/open-sse/services/compression/engines/rtk/configSchema.ts +117 -0
- package/open-sse/services/compression/engines/rtk/deduplicator.ts +37 -0
- package/open-sse/services/compression/engines/rtk/discover.ts +150 -0
- package/open-sse/services/compression/engines/rtk/filterLoader.ts +245 -0
- package/open-sse/services/compression/engines/rtk/filterSchema.ts +207 -0
- package/open-sse/services/compression/engines/rtk/filters/aws.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/biome.json +35 -0
- package/open-sse/services/compression/engines/rtk/filters/build-eslint.json +37 -0
- package/open-sse/services/compression/engines/rtk/filters/build-typescript.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/build-vite.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/build-webpack.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/bundle-install.json +35 -0
- package/open-sse/services/compression/engines/rtk/filters/composer.json +81 -0
- package/open-sse/services/compression/engines/rtk/filters/curl.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/df.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/docker-build.json +78 -0
- package/open-sse/services/compression/engines/rtk/filters/docker-logs.json +42 -0
- package/open-sse/services/compression/engines/rtk/filters/docker-ps.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/dotnet.json +47 -0
- package/open-sse/services/compression/engines/rtk/filters/du.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/error-stacktrace.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/gcloud.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/generic-output.json +32 -0
- package/open-sse/services/compression/engines/rtk/filters/gh.json +98 -0
- package/open-sse/services/compression/engines/rtk/filters/git-branch.json +45 -0
- package/open-sse/services/compression/engines/rtk/filters/git-diff.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/git-log.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/git-status.json +40 -0
- package/open-sse/services/compression/engines/rtk/filters/golangci-lint.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/gradle.json +47 -0
- package/open-sse/services/compression/engines/rtk/filters/json-output.json +40 -0
- package/open-sse/services/compression/engines/rtk/filters/kubectl.json +99 -0
- package/open-sse/services/compression/engines/rtk/filters/make.json +38 -0
- package/open-sse/services/compression/engines/rtk/filters/mypy.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/npm-audit.json +43 -0
- package/open-sse/services/compression/engines/rtk/filters/npm-install.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/nx.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/pip.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/playwright.json +42 -0
- package/open-sse/services/compression/engines/rtk/filters/poetry-install.json +35 -0
- package/open-sse/services/compression/engines/rtk/filters/prettier.json +40 -0
- package/open-sse/services/compression/engines/rtk/filters/ps.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/rsync.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/rubocop.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/ruff.json +40 -0
- package/open-sse/services/compression/engines/rtk/filters/shell-find.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/shell-grep.json +37 -0
- package/open-sse/services/compression/engines/rtk/filters/shell-ls.json +33 -0
- package/open-sse/services/compression/engines/rtk/filters/ssh.json +43 -0
- package/open-sse/services/compression/engines/rtk/filters/systemctl-status.json +43 -0
- package/open-sse/services/compression/engines/rtk/filters/terraform-plan.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/test-cargo.json +42 -0
- package/open-sse/services/compression/engines/rtk/filters/test-go.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/test-jest.json +43 -0
- package/open-sse/services/compression/engines/rtk/filters/test-pytest.json +41 -0
- package/open-sse/services/compression/engines/rtk/filters/test-vitest.json +43 -0
- package/open-sse/services/compression/engines/rtk/filters/tofu-plan.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/turbo.json +34 -0
- package/open-sse/services/compression/engines/rtk/filters/uv-sync.json +35 -0
- package/open-sse/services/compression/engines/rtk/filters/wget.json +34 -0
- package/open-sse/services/compression/engines/rtk/grouper.ts +99 -0
- package/open-sse/services/compression/engines/rtk/index.ts +706 -0
- package/open-sse/services/compression/engines/rtk/learn.ts +290 -0
- package/open-sse/services/compression/engines/rtk/lineFilter.ts +178 -0
- package/open-sse/services/compression/engines/rtk/rawOutput.ts +208 -0
- package/open-sse/services/compression/engines/rtk/renderers/gitDiff.ts +39 -0
- package/open-sse/services/compression/engines/rtk/renderers/index.ts +50 -0
- package/open-sse/services/compression/engines/rtk/renderers/structuredTable.ts +96 -0
- package/open-sse/services/compression/engines/rtk/renderers/terraformPlan.ts +40 -0
- package/open-sse/services/compression/engines/rtk/renderers/testGreen.ts +70 -0
- package/open-sse/services/compression/engines/rtk/renderers/types.ts +13 -0
- package/open-sse/services/compression/engines/rtk/smartTruncate.ts +67 -0
- package/open-sse/services/compression/engines/rtk/splitCompositeCommand.ts +111 -0
- package/open-sse/services/compression/engines/rtk/verify.ts +107 -0
- package/open-sse/services/compression/engines/session-dedup/fuzzy.ts +153 -0
- package/open-sse/services/compression/engines/session-dedup/index.ts +435 -0
- package/open-sse/services/compression/engines/types.ts +77 -0
- package/open-sse/services/compression/entrypointWrap.ts +43 -0
- package/open-sse/services/compression/eval/aggregate.ts +62 -0
- package/open-sse/services/compression/eval/corpus.ts +45 -0
- package/open-sse/services/compression/eval/costMeter.ts +31 -0
- package/open-sse/services/compression/eval/executorModelClient.ts +44 -0
- package/open-sse/services/compression/eval/fidelityCheck.ts +61 -0
- package/open-sse/services/compression/eval/grader.ts +27 -0
- package/open-sse/services/compression/eval/judge.ts +68 -0
- package/open-sse/services/compression/eval/report.ts +44 -0
- package/open-sse/services/compression/eval/runner.ts +135 -0
- package/open-sse/services/compression/eval/savings.ts +30 -0
- package/open-sse/services/compression/eval/seedCorpus.ts +60 -0
- package/open-sse/services/compression/eval/types.ts +65 -0
- package/open-sse/services/compression/fidelityGate.ts +124 -0
- package/open-sse/services/compression/fidelityGateStep.ts +44 -0
- package/open-sse/services/compression/hardBudget.ts +196 -0
- package/open-sse/services/compression/harness/benchmark.ts +318 -0
- package/open-sse/services/compression/harness/budgetGate.ts +62 -0
- package/open-sse/services/compression/harness/index.ts +52 -0
- package/open-sse/services/compression/harness/measure.ts +98 -0
- package/open-sse/services/compression/harness/replay.ts +72 -0
- package/open-sse/services/compression/harness/runner.ts +58 -0
- package/open-sse/services/compression/index.ts +165 -0
- package/open-sse/services/compression/languageDetector.ts +51 -0
- package/open-sse/services/compression/lite.ts +241 -0
- package/open-sse/services/compression/messageContent.ts +89 -0
- package/open-sse/services/compression/outputMode.ts +175 -0
- package/open-sse/services/compression/outputStyles/apply.ts +135 -0
- package/open-sse/services/compression/outputStyles/backCompat.ts +29 -0
- package/open-sse/services/compression/outputStyles/catalog.ts +76 -0
- package/open-sse/services/compression/outputStyles/telemetry.ts +50 -0
- package/open-sse/services/compression/pipelineEngineBreaker.ts +139 -0
- package/open-sse/services/compression/pipelineGuards.ts +45 -0
- package/open-sse/services/compression/planResolution.ts +128 -0
- package/open-sse/services/compression/prefixFreeze.ts +124 -0
- package/open-sse/services/compression/preservation.ts +0 -0
- package/open-sse/services/compression/preserveSystemPromptMode.ts +72 -0
- package/open-sse/services/compression/progressiveAging.ts +145 -0
- package/open-sse/services/compression/quantumLock/index.ts +17 -0
- package/open-sse/services/compression/quantumLock/quantumLock.ts +58 -0
- package/open-sse/services/compression/quantumLock/quantumLockStep.ts +72 -0
- package/open-sse/services/compression/quantumLock/quantumPatterns.ts +80 -0
- package/open-sse/services/compression/quantumLock/strategyWrap.ts +72 -0
- package/open-sse/services/compression/resolveCompressionPlan.ts +28 -0
- package/open-sse/services/compression/resultMemo.ts +83 -0
- package/open-sse/services/compression/riskGate/index.ts +3 -0
- package/open-sse/services/compression/riskGate/riskGate.ts +136 -0
- package/open-sse/services/compression/riskGate/riskGateStep.ts +115 -0
- package/open-sse/services/compression/riskGate/riskPatterns.ts +61 -0
- package/open-sse/services/compression/riskGate/strategyWrap.ts +44 -0
- package/open-sse/services/compression/ruleLoader.ts +273 -0
- package/open-sse/services/compression/rules/_schema.json +31 -0
- package/open-sse/services/compression/rules/de/context.json +38 -0
- package/open-sse/services/compression/rules/de/dedup.json +38 -0
- package/open-sse/services/compression/rules/de/filler.json +70 -0
- package/open-sse/services/compression/rules/de/structural.json +30 -0
- package/open-sse/services/compression/rules/de/ultra.json +107 -0
- package/open-sse/services/compression/rules/en/context.json +88 -0
- package/open-sse/services/compression/rules/en/dedup.json +38 -0
- package/open-sse/services/compression/rules/en/filler.json +129 -0
- package/open-sse/services/compression/rules/en/structural.json +102 -0
- package/open-sse/services/compression/rules/en/ultra.json +107 -0
- package/open-sse/services/compression/rules/es/context.json +87 -0
- package/open-sse/services/compression/rules/es/dedup.json +38 -0
- package/open-sse/services/compression/rules/es/filler.json +110 -0
- package/open-sse/services/compression/rules/es/structural.json +105 -0
- package/open-sse/services/compression/rules/es/ultra.json +107 -0
- package/open-sse/services/compression/rules/fr/context.json +38 -0
- package/open-sse/services/compression/rules/fr/dedup.json +38 -0
- package/open-sse/services/compression/rules/fr/filler.json +70 -0
- package/open-sse/services/compression/rules/fr/structural.json +30 -0
- package/open-sse/services/compression/rules/fr/ultra.json +107 -0
- package/open-sse/services/compression/rules/id/context.json +113 -0
- package/open-sse/services/compression/rules/id/dedup.json +38 -0
- package/open-sse/services/compression/rules/id/filler.json +138 -0
- package/open-sse/services/compression/rules/id/structural.json +111 -0
- package/open-sse/services/compression/rules/id/ultra.json +252 -0
- package/open-sse/services/compression/rules/ja/context.json +38 -0
- package/open-sse/services/compression/rules/ja/dedup.json +38 -0
- package/open-sse/services/compression/rules/ja/filler.json +70 -0
- package/open-sse/services/compression/rules/ja/structural.json +30 -0
- package/open-sse/services/compression/rules/ja/ultra.json +86 -0
- package/open-sse/services/compression/rules/pt-BR/context.json +69 -0
- package/open-sse/services/compression/rules/pt-BR/dedup.json +51 -0
- package/open-sse/services/compression/rules/pt-BR/filler.json +151 -0
- package/open-sse/services/compression/rules/pt-BR/structural.json +78 -0
- package/open-sse/services/compression/rules/pt-BR/ultra.json +192 -0
- package/open-sse/services/compression/rules/zh/dedup.json +38 -0
- package/open-sse/services/compression/rules/zh/filler.json +54 -0
- package/open-sse/services/compression/rules/zh/ultra.json +55 -0
- package/open-sse/services/compression/stackedStepCore.ts +87 -0
- package/open-sse/services/compression/stats.ts +59 -0
- package/open-sse/services/compression/strategySelector.ts +1007 -0
- package/open-sse/services/compression/summarizer.ts +244 -0
- package/open-sse/services/compression/toolResultCompressor.ts +283 -0
- package/open-sse/services/compression/types.ts +479 -0
- package/open-sse/services/compression/ultra.ts +321 -0
- package/open-sse/services/compression/ultraHeuristic.ts +157 -0
- package/open-sse/services/compression/validation.ts +432 -0
- package/open-sse/services/contextHandoff.ts +770 -0
- package/open-sse/services/contextManager.ts +617 -0
- package/open-sse/services/credentialGate.ts +84 -0
- package/open-sse/services/crofUsageFetcher.ts +182 -0
- package/open-sse/services/cursorSessionManager.ts +208 -0
- package/open-sse/services/deepseekQuotaFetcher.ts +244 -0
- package/open-sse/services/deviceTracker.ts +307 -0
- package/open-sse/services/emergencyFallback.ts +162 -0
- package/open-sse/services/errorClassifier.ts +198 -0
- package/open-sse/services/evalRouting.ts +276 -0
- package/open-sse/services/freeWebSearch.ts +154 -0
- package/open-sse/services/fusion.ts +337 -0
- package/open-sse/services/geminiRateLimitTracker.ts +145 -0
- package/open-sse/services/geminiThoughtSignatureStore.ts +329 -0
- package/open-sse/services/genericQuotaFetcher.ts +215 -0
- package/open-sse/services/gigachatAuth.ts +113 -0
- package/open-sse/services/githubCopilotModels.ts +162 -0
- package/open-sse/services/gpt5SamplingGuard.ts +81 -0
- package/open-sse/services/grokTlsClient.ts +607 -0
- package/open-sse/services/hfModelSuggestions.ts +63 -0
- package/open-sse/services/inAppLoginService.ts +256 -0
- package/open-sse/services/intentClassifier.ts +665 -0
- package/open-sse/services/ipFilter.ts +340 -0
- package/open-sse/services/keyGroupAuth.ts +84 -0
- package/open-sse/services/kiroModels.ts +195 -0
- package/open-sse/services/manifestAdapter.ts +134 -0
- package/open-sse/services/mimoThinking.ts +54 -0
- package/open-sse/services/model.ts +738 -0
- package/open-sse/services/modelCapabilities.ts +5 -0
- package/open-sse/services/modelDeprecation.ts +173 -0
- package/open-sse/services/modelFamilyFallback.ts +240 -0
- package/open-sse/services/modelStrip.ts +60 -0
- package/open-sse/services/modelscopePolicy.ts +97 -0
- package/open-sse/services/opencodeOllamaUsage.ts +562 -0
- package/open-sse/services/opencodeQuotaFetcher.ts +351 -0
- package/open-sse/services/payloadRules.ts +474 -0
- package/open-sse/services/perplexityTlsClient.ts +593 -0
- package/open-sse/services/pipeline.ts +189 -0
- package/open-sse/services/provider.ts +460 -0
- package/open-sse/services/providerCooldownTracker.ts +198 -0
- package/open-sse/services/providerCostData.ts +52 -0
- package/open-sse/services/providerDefaultRateLimit.ts +94 -0
- package/open-sse/services/providerRequestDefaults.ts +88 -0
- package/open-sse/services/proxyAutoSelector.ts +58 -0
- package/open-sse/services/qoderCli.ts +987 -0
- package/open-sse/services/qoderCliResolve.ts +111 -0
- package/open-sse/services/quotaFetchThrottle.ts +118 -0
- package/open-sse/services/quotaMonitor.ts +377 -0
- package/open-sse/services/quotaPreflight.ts +349 -0
- package/open-sse/services/qwenThinking.ts +44 -0
- package/open-sse/services/rateLimitManager/headers.ts +94 -0
- package/open-sse/services/rateLimitManager.ts +945 -0
- package/open-sse/services/rateLimitSemaphore.ts +231 -0
- package/open-sse/services/reasoningCache.ts +514 -0
- package/open-sse/services/reasoningTokenBuffer.ts +50 -0
- package/open-sse/services/refreshSerializer.ts +131 -0
- package/open-sse/services/requestDedup.ts +127 -0
- package/open-sse/services/responseModelEcho.ts +79 -0
- package/open-sse/services/responsesInputSanitizer.ts +145 -0
- package/open-sse/services/retryAfterJson.ts +44 -0
- package/open-sse/services/roleNormalizer.ts +283 -0
- package/open-sse/services/searchCache.ts +150 -0
- package/open-sse/services/sessionManager.ts +380 -0
- package/open-sse/services/sessionPool/fingerprintRotator.ts +126 -0
- package/open-sse/services/sessionPool/index.ts +28 -0
- package/open-sse/services/sessionPool/poolRegistry.ts +93 -0
- package/open-sse/services/sessionPool/session.ts +119 -0
- package/open-sse/services/sessionPool/sessionFactory.ts +57 -0
- package/open-sse/services/sessionPool/sessionPool.ts +326 -0
- package/open-sse/services/sessionPool/types.ts +100 -0
- package/open-sse/services/sessionPool/webExecutorWrapper.ts +132 -0
- package/open-sse/services/signatureCache.ts +189 -0
- package/open-sse/services/slidingWindowLimiter.ts +84 -0
- package/open-sse/services/specificityDetector.ts +89 -0
- package/open-sse/services/specificityRules.ts +257 -0
- package/open-sse/services/specificityTypes.ts +43 -0
- package/open-sse/services/streamRecovery.ts +545 -0
- package/open-sse/services/systemPrompt.ts +187 -0
- package/open-sse/services/systemTransforms.ts +532 -0
- package/open-sse/services/taskAwareRouter.ts +326 -0
- package/open-sse/services/taskAwareRouting.ts +553 -0
- package/open-sse/services/thinkingBudget.ts +391 -0
- package/open-sse/services/tierConfig.ts +124 -0
- package/open-sse/services/tierDefaults.json +26 -0
- package/open-sse/services/tierResolver.ts +144 -0
- package/open-sse/services/tierTypes.ts +40 -0
- package/open-sse/services/tlsClientProxy.ts +30 -0
- package/open-sse/services/tokenExtractionConfig.ts +398 -0
- package/open-sse/services/tokenLimitCounter.ts +342 -0
- package/open-sse/services/tokenRefresh.ts +2180 -0
- package/open-sse/services/toolLatencyTracker.ts +89 -0
- package/open-sse/services/toolLimitDetector.ts +87 -0
- package/open-sse/services/toolSchemaSanitizer.ts +165 -0
- package/open-sse/services/usage/antigravity.ts +794 -0
- package/open-sse/services/usage/claude.ts +216 -0
- package/open-sse/services/usage/codebuddy-cn.ts +199 -0
- package/open-sse/services/usage/codex.ts +75 -0
- package/open-sse/services/usage/cursor.ts +161 -0
- package/open-sse/services/usage/glm.ts +220 -0
- package/open-sse/services/usage/kimi.ts +209 -0
- package/open-sse/services/usage/kiro.ts +243 -0
- package/open-sse/services/usage/minimax.ts +346 -0
- package/open-sse/services/usage/quota.ts +85 -0
- package/open-sse/services/usage/scalars.ts +75 -0
- package/open-sse/services/usage.ts +1058 -0
- package/open-sse/services/volumeDetector.ts +224 -0
- package/open-sse/services/webSearchFallback.ts +246 -0
- package/open-sse/services/webSearchRouting.ts +68 -0
- package/open-sse/services/webSessionPoolHealth.ts +287 -0
- package/open-sse/services/wildcardRouter.ts +136 -0
- package/open-sse/services/workflowFSM.ts +340 -0
- package/open-sse/shared/zedAuth.ts +535 -0
- package/open-sse/transformer/responsesTransformer.ts +667 -0
- package/open-sse/translator/bootstrap.ts +27 -0
- package/open-sse/translator/deepseekWebTools.ts +486 -0
- package/open-sse/translator/formats.ts +12 -0
- package/open-sse/translator/helpers/claudeHelper.ts +563 -0
- package/open-sse/translator/helpers/geminiHelper.ts +657 -0
- package/open-sse/translator/helpers/geminiToolsSanitizer.ts +255 -0
- package/open-sse/translator/helpers/jsonUtil.ts +18 -0
- package/open-sse/translator/helpers/maxTokensHelper.ts +21 -0
- package/open-sse/translator/helpers/openaiHelper.ts +244 -0
- package/open-sse/translator/helpers/responsesApiHelper.ts +9 -0
- package/open-sse/translator/helpers/schemaCoercion.ts +408 -0
- package/open-sse/translator/helpers/toolCallHelper.ts +224 -0
- package/open-sse/translator/helpers/toolCallShim.ts +113 -0
- package/open-sse/translator/image/sizeMapper.ts +22 -0
- package/open-sse/translator/index.ts +614 -0
- package/open-sse/translator/paramSupport.ts +70 -0
- package/open-sse/translator/registry.ts +41 -0
- package/open-sse/translator/request/antigravity-to-openai.ts +357 -0
- package/open-sse/translator/request/claude-to-gemini.ts +236 -0
- package/open-sse/translator/request/claude-to-openai.ts +534 -0
- package/open-sse/translator/request/gemini-to-openai.ts +193 -0
- package/open-sse/translator/request/openai-responses/helpers.ts +69 -0
- package/open-sse/translator/request/openai-responses/toResponses.ts +357 -0
- package/open-sse/translator/request/openai-responses.ts +533 -0
- package/open-sse/translator/request/openai-to-claude/thinkingBudget.ts +89 -0
- package/open-sse/translator/request/openai-to-claude/toolResultAdjacency.ts +106 -0
- package/open-sse/translator/request/openai-to-claude.ts +747 -0
- package/open-sse/translator/request/openai-to-cursor.ts +226 -0
- package/open-sse/translator/request/openai-to-gemini/helpers.ts +142 -0
- package/open-sse/translator/request/openai-to-gemini.ts +753 -0
- package/open-sse/translator/request/openai-to-kiro/messageHelpers.ts +109 -0
- package/open-sse/translator/request/openai-to-kiro.ts +889 -0
- package/open-sse/translator/response/claude-to-openai.ts +327 -0
- package/open-sse/translator/response/cursor-to-openai.ts +30 -0
- package/open-sse/translator/response/gemini-to-claude.ts +199 -0
- package/open-sse/translator/response/gemini-to-openai.ts +765 -0
- package/open-sse/translator/response/kiro-to-openai.ts +211 -0
- package/open-sse/translator/response/openai-responses/pureHelpers.ts +92 -0
- package/open-sse/translator/response/openai-responses.ts +1011 -0
- package/open-sse/translator/response/openai-to-antigravity.ts +145 -0
- package/open-sse/translator/response/openai-to-claude.ts +289 -0
- package/open-sse/translator/response/openai-to-gemini-sse.ts +431 -0
- package/open-sse/translator/webTools.ts +531 -0
- package/open-sse/tsconfig.json +25 -0
- package/open-sse/types.d.ts +139 -0
- package/open-sse/utils/agentGoalPolicy.ts +112 -0
- package/open-sse/utils/aiSdkCompat.ts +179 -0
- package/open-sse/utils/anthropicHost.ts +25 -0
- package/open-sse/utils/awsSigV4.ts +139 -0
- package/open-sse/utils/bypassHandler.ts +300 -0
- package/open-sse/utils/cacheControlPolicy.ts +374 -0
- package/open-sse/utils/claudeCodeMetaRequests.ts +87 -0
- package/open-sse/utils/clinepassEnvelope.ts +59 -0
- package/open-sse/utils/comfyuiClient.ts +126 -0
- package/open-sse/utils/composerToolCalls.ts +307 -0
- package/open-sse/utils/cors.ts +13 -0
- package/open-sse/utils/cursorAgentProtobuf/wire.ts +143 -0
- package/open-sse/utils/cursorAgentProtobuf.ts +1400 -0
- package/open-sse/utils/cursorChecksum.ts +139 -0
- package/open-sse/utils/cursorImages.ts +354 -0
- package/open-sse/utils/cursorVersionDetector.ts +74 -0
- package/open-sse/utils/diagnostics.ts +288 -0
- package/open-sse/utils/earlyStreamKeepalive.ts +228 -0
- package/open-sse/utils/error.ts +515 -0
- package/open-sse/utils/estimateSize.ts +35 -0
- package/open-sse/utils/finishReason.ts +36 -0
- package/open-sse/utils/flattenToolHistory.ts +116 -0
- package/open-sse/utils/headers.ts +61 -0
- package/open-sse/utils/heapPressure.ts +81 -0
- package/open-sse/utils/jsonToSse.ts +127 -0
- package/open-sse/utils/keepaliveThreshold.ts +62 -0
- package/open-sse/utils/kieTask.ts +127 -0
- package/open-sse/utils/kiroSanitizer.ts +127 -0
- package/open-sse/utils/logger.ts +190 -0
- package/open-sse/utils/networkProxy.ts +75 -0
- package/open-sse/utils/noThinkingAlias.ts +153 -0
- package/open-sse/utils/number.ts +4 -0
- package/open-sse/utils/ollamaTransform.ts +122 -0
- package/open-sse/utils/opencodeHeaders.ts +98 -0
- package/open-sse/utils/passthroughTailProcessor.ts +299 -0
- package/open-sse/utils/progressTracker.ts +112 -0
- package/open-sse/utils/providerRequestLogging.ts +272 -0
- package/open-sse/utils/proxyDispatcher.ts +507 -0
- package/open-sse/utils/proxyDispatcherCache.ts +124 -0
- package/open-sse/utils/proxyFallback.ts +418 -0
- package/open-sse/utils/proxyFamily.ts +24 -0
- package/open-sse/utils/proxyFamilyResolve.ts +39 -0
- package/open-sse/utils/proxyFetch.ts +666 -0
- package/open-sse/utils/publicCreds.ts +215 -0
- package/open-sse/utils/reasoningContentInjector.ts +73 -0
- package/open-sse/utils/reasoningFields.ts +72 -0
- package/open-sse/utils/requestLogger.ts +386 -0
- package/open-sse/utils/responsesInputNormalization.ts +94 -0
- package/open-sse/utils/responsesStatePolicy.ts +75 -0
- package/open-sse/utils/responsesStreamHelpers.ts +166 -0
- package/open-sse/utils/setupPolyfill.ts +33 -0
- package/open-sse/utils/sha3-512.ts +164 -0
- package/open-sse/utils/sleep.ts +9 -0
- package/open-sse/utils/socksConnectorWithFamily.ts +89 -0
- package/open-sse/utils/sseHeartbeat.ts +119 -0
- package/open-sse/utils/stream.ts +2791 -0
- package/open-sse/utils/streamFailureFinalization.ts +174 -0
- package/open-sse/utils/streamHandler.ts +680 -0
- package/open-sse/utils/streamHelpers.ts +460 -0
- package/open-sse/utils/streamPayloadCollector.ts +700 -0
- package/open-sse/utils/streamReadiness.ts +385 -0
- package/open-sse/utils/streamReadinessPolicy.ts +132 -0
- package/open-sse/utils/textualToolCall.ts +112 -0
- package/open-sse/utils/thinkCloseMarker.ts +77 -0
- package/open-sse/utils/thinkTagParser.ts +146 -0
- package/open-sse/utils/tlsClient.ts +243 -0
- package/open-sse/utils/toolCallArguments.ts +32 -0
- package/open-sse/utils/toolSources.ts +69 -0
- package/open-sse/utils/upstreamResponseHeaders.ts +47 -0
- package/open-sse/utils/urlSanitize.ts +24 -0
- package/open-sse/utils/usageTracking.ts +596 -0
- package/package.json +393 -0
- package/scripts/build/build-next-isolated.mjs +322 -0
- package/scripts/build/colocateOptionals.mjs +144 -0
- package/scripts/build/native-binary-compat.mjs +167 -0
- package/scripts/build/postinstall.mjs +357 -0
- package/scripts/build/postinstallSupport.mjs +45 -0
- package/scripts/build/runtime-env.mjs +140 -0
- package/scripts/build/sync-env.mjs +3 -0
- package/scripts/check/check-supported-node-runtime.ts +20 -0
- package/scripts/dev/responses-ws-proxy.mjs +907 -0
- package/scripts/dev/sync-env.mjs +362 -0
- package/scripts/dev/tls-options.mjs +92 -0
- package/scripts/postinstall.mjs +27 -0
- package/src/domain/assessment/assessor.ts +206 -0
- package/src/domain/assessment/categorizer.ts +118 -0
- package/src/domain/assessment/index.ts +24 -0
- package/src/domain/assessment/migration.ts +111 -0
- package/src/domain/assessment/selfHealer.ts +261 -0
- package/src/domain/assessment/types.ts +361 -0
- package/src/domain/comboResolver.ts +106 -0
- package/src/domain/configAudit.ts +285 -0
- package/src/domain/connectionModelRules.ts +82 -0
- package/src/domain/costRules.ts +631 -0
- package/src/domain/degradation.ts +253 -0
- package/src/domain/fallbackPolicy.ts +160 -0
- package/src/domain/lockoutPolicy.ts +208 -0
- package/src/domain/modelAvailability.ts +41 -0
- package/src/domain/omnirouteResponseMeta.ts +202 -0
- package/src/domain/pipeline.ts +307 -0
- package/src/domain/policyEngine.ts +195 -0
- package/src/domain/prompts.ts +103 -0
- package/src/domain/providerExpiration.ts +255 -0
- package/src/domain/quotaCache.ts +553 -0
- package/src/domain/responses.ts +139 -0
- package/src/domain/tagRouter.ts +64 -0
- package/src/domain/types.ts +123 -0
- package/src/lib/a2a/README.md +748 -0
- package/src/lib/a2a/routingLogger.ts +67 -0
- package/src/lib/a2a/skills/costAnalysis.ts +162 -0
- package/src/lib/a2a/skills/healthReport.ts +155 -0
- package/src/lib/a2a/skills/listCapabilities.ts +72 -0
- package/src/lib/a2a/skills/providerDiscovery.ts +202 -0
- package/src/lib/a2a/skills/quotaManagement.ts +121 -0
- package/src/lib/a2a/skills/smartRouting.ts +89 -0
- package/src/lib/a2a/streaming.ts +149 -0
- package/src/lib/a2a/taskExecution.ts +64 -0
- package/src/lib/a2a/taskManager.ts +240 -0
- package/src/lib/accessTokens/scopes.ts +51 -0
- package/src/lib/acp/index.ts +11 -0
- package/src/lib/acp/manager.ts +202 -0
- package/src/lib/acp/registry.ts +384 -0
- package/src/lib/agentSkills/catalog.ts +256 -0
- package/src/lib/agentSkills/cliRegistryParser.ts +242 -0
- package/src/lib/agentSkills/generator.ts +367 -0
- package/src/lib/agentSkills/openapiParser.ts +201 -0
- package/src/lib/agentSkills/schemas.ts +36 -0
- package/src/lib/agentSkills/types.ts +101 -0
- package/src/lib/api/comboErrorResponse.ts +80 -0
- package/src/lib/api/errorResponse.ts +54 -0
- package/src/lib/api/modelTestRunner.ts +390 -0
- package/src/lib/api/proxyRegistryRouteHandlers.ts +142 -0
- package/src/lib/api/requireCliToolsAuth.ts +5 -0
- package/src/lib/api/requireManagementAuth.ts +118 -0
- package/src/lib/api/serverErrorMessage.ts +36 -0
- package/src/lib/apiBridgeServer.ts +233 -0
- package/src/lib/apiKeyExposure.ts +19 -0
- package/src/lib/arenaEloSync.ts +564 -0
- package/src/lib/audit/activityIcons.ts +69 -0
- package/src/lib/audit/highLevelActions.ts +57 -0
- package/src/lib/audit/timeline.ts +132 -0
- package/src/lib/auth/managementPassword.ts +117 -0
- package/src/lib/batches/costEstimator.ts +130 -0
- package/src/lib/batches/csvToJsonl.ts +248 -0
- package/src/lib/batches/dispatch.ts +53 -0
- package/src/lib/batches/retryFailed.ts +77 -0
- package/src/lib/batches/schemas.ts +38 -0
- package/src/lib/batches/types.ts +78 -0
- package/src/lib/batches/validateJsonl.ts +154 -0
- package/src/lib/benchmarks.ts +33 -0
- package/src/lib/build-profile/featureDisabled.ts +23 -0
- package/src/lib/cacheControlSettings.ts +25 -0
- package/src/lib/cacheLayer.ts +220 -0
- package/src/lib/catalog/openrouterCatalog.ts +177 -0
- package/src/lib/cli-helper/claudeProfileAutoSync.ts +92 -0
- package/src/lib/cli-helper/codexProfileAutoSync.ts +80 -0
- package/src/lib/cli-helper/config-generator/claude.ts +25 -0
- package/src/lib/cli-helper/config-generator/cline.ts +23 -0
- package/src/lib/cli-helper/config-generator/codex.ts +34 -0
- package/src/lib/cli-helper/config-generator/continue.ts +37 -0
- package/src/lib/cli-helper/config-generator/hermes-agent.ts +210 -0
- package/src/lib/cli-helper/config-generator/hermes.ts +47 -0
- package/src/lib/cli-helper/config-generator/hermesHome.ts +40 -0
- package/src/lib/cli-helper/config-generator/index.ts +124 -0
- package/src/lib/cli-helper/config-generator/kilocode.ts +23 -0
- package/src/lib/cli-helper/config-generator/opencode.ts +443 -0
- package/src/lib/cli-helper/doctor/checks.ts +41 -0
- package/src/lib/cli-helper/log-streamer.ts +78 -0
- package/src/lib/cli-helper/tool-detector.ts +165 -0
- package/src/lib/cliTools/batchStatusCache.ts +47 -0
- package/src/lib/cliTools/checkToolConfigStatus.ts +112 -0
- package/src/lib/cloudAgent/agents/codex.ts +148 -0
- package/src/lib/cloudAgent/agents/cursor.ts +205 -0
- package/src/lib/cloudAgent/agents/devin.ts +137 -0
- package/src/lib/cloudAgent/agents/jules.ts +354 -0
- package/src/lib/cloudAgent/api.ts +86 -0
- package/src/lib/cloudAgent/baseAgent.ts +98 -0
- package/src/lib/cloudAgent/credentials.ts +89 -0
- package/src/lib/cloudAgent/db.ts +145 -0
- package/src/lib/cloudAgent/index.ts +8 -0
- package/src/lib/cloudAgent/julesApi.ts +7 -0
- package/src/lib/cloudAgent/registry.ts +29 -0
- package/src/lib/cloudAgent/types.ts +90 -0
- package/src/lib/cloudSync.stub.ts +31 -0
- package/src/lib/cloudSync.ts +210 -0
- package/src/lib/cloudflaredTunnel.ts +933 -0
- package/src/lib/combos/autoPromote.ts +92 -0
- package/src/lib/combos/builderDraft.ts +242 -0
- package/src/lib/combos/builderOptions.ts +681 -0
- package/src/lib/combos/compositeTiers.ts +200 -0
- package/src/lib/combos/controlCenter.ts +271 -0
- package/src/lib/combos/intelligentRouting.ts +192 -0
- package/src/lib/combos/steps.ts +322 -0
- package/src/lib/combos/testHealth.ts +190 -0
- package/src/lib/compliance/index.ts +637 -0
- package/src/lib/compliance/noLog.ts +86 -0
- package/src/lib/compliance/providerAudit.ts +98 -0
- package/src/lib/compression/judgeModelClient.ts +43 -0
- package/src/lib/config/hotReload.ts +115 -0
- package/src/lib/config/runtimeSettings.ts +551 -0
- package/src/lib/consoleInterceptor.ts +136 -0
- package/src/lib/container.ts +122 -0
- package/src/lib/contextWindowResolver.ts +147 -0
- package/src/lib/copilot/codegraphKnowledge.ts +229 -0
- package/src/lib/copilot/engine.ts +372 -0
- package/src/lib/copilot/systemPrompt.ts +189 -0
- package/src/lib/copilot/tools.ts +415 -0
- package/src/lib/credentialHealth/cache.ts +206 -0
- package/src/lib/credentialHealth/scheduler.ts +328 -0
- package/src/lib/dataPaths.ts +122 -0
- package/src/lib/db/AGENTS.md +70 -0
- package/src/lib/db/_rowTypes.ts +45 -0
- package/src/lib/db/accessTokens.ts +183 -0
- package/src/lib/db/adapters/betterSqliteAdapter.ts +58 -0
- package/src/lib/db/adapters/driverFactory.ts +98 -0
- package/src/lib/db/adapters/nodeSqliteAdapter.ts +60 -0
- package/src/lib/db/adapters/nodeSqliteShared.ts +148 -0
- package/src/lib/db/adapters/sqljsAdapter.ts +232 -0
- package/src/lib/db/adapters/types.ts +34 -0
- package/src/lib/db/agentBridgeBypass.ts +81 -0
- package/src/lib/db/agentBridgeMappings.ts +47 -0
- package/src/lib/db/agentBridgeState.ts +115 -0
- package/src/lib/db/apiKeyColumnFallbacks.ts +47 -0
- package/src/lib/db/apiKeyContextSources.ts +107 -0
- package/src/lib/db/apiKeyGroups.ts +318 -0
- package/src/lib/db/apiKeyUsageLimitFields.ts +65 -0
- package/src/lib/db/apiKeys/modelPermissions.ts +122 -0
- package/src/lib/db/apiKeys/rowParsers.ts +161 -0
- package/src/lib/db/apiKeys/types.ts +21 -0
- package/src/lib/db/apiKeys.ts +1492 -0
- package/src/lib/db/backup.ts +708 -0
- package/src/lib/db/batches.ts +450 -0
- package/src/lib/db/callLogStats.ts +235 -0
- package/src/lib/db/caseMapping.ts +80 -0
- package/src/lib/db/cleanup.ts +584 -0
- package/src/lib/db/cliToolState.ts +159 -0
- package/src/lib/db/comboForecast.ts +119 -0
- package/src/lib/db/combos.ts +339 -0
- package/src/lib/db/commandCodeAuth.ts +209 -0
- package/src/lib/db/compression.ts +780 -0
- package/src/lib/db/compressionAnalytics.ts +661 -0
- package/src/lib/db/compressionCacheStats.ts +112 -0
- package/src/lib/db/compressionCombos.ts +491 -0
- package/src/lib/db/compressionRunTelemetry.ts +126 -0
- package/src/lib/db/contextHandoffs.ts +233 -0
- package/src/lib/db/core.ts +1520 -0
- package/src/lib/db/creditBalance.ts +92 -0
- package/src/lib/db/databaseSettings.ts +309 -0
- package/src/lib/db/detailedLogs.ts +170 -0
- package/src/lib/db/discovery.ts +97 -0
- package/src/lib/db/discoveryResults.ts +176 -0
- package/src/lib/db/domainState.ts +630 -0
- package/src/lib/db/encryption.ts +327 -0
- package/src/lib/db/evals.ts +786 -0
- package/src/lib/db/featureFlags.ts +82 -0
- package/src/lib/db/files.ts +170 -0
- package/src/lib/db/freeProxies.ts +360 -0
- package/src/lib/db/gamification.ts +613 -0
- package/src/lib/db/healthCheck.ts +565 -0
- package/src/lib/db/inspectorCustomHosts.ts +88 -0
- package/src/lib/db/inspectorSessions.ts +161 -0
- package/src/lib/db/jsonMigration.ts +321 -0
- package/src/lib/db/memoryVec.ts +138 -0
- package/src/lib/db/middleware.ts +239 -0
- package/src/lib/db/migrationRunner/constants.ts +118 -0
- package/src/lib/db/migrationRunner.ts +1069 -0
- package/src/lib/db/migrations/001_initial_schema.sql +226 -0
- package/src/lib/db/migrations/002_mcp_a2a_tables.sql +95 -0
- package/src/lib/db/migrations/003_provider_node_custom_paths.sql +5 -0
- package/src/lib/db/migrations/004_proxy_registry.sql +31 -0
- package/src/lib/db/migrations/005_combo_agent_fields.sql +19 -0
- package/src/lib/db/migrations/006_detailed_request_logs.sql +42 -0
- package/src/lib/db/migrations/007_search_request_type.sql +4 -0
- package/src/lib/db/migrations/008_registered_keys.sql +65 -0
- package/src/lib/db/migrations/009_requested_model.sql +9 -0
- package/src/lib/db/migrations/010_model_combo_mappings.sql +19 -0
- package/src/lib/db/migrations/011_webhooks.sql +15 -0
- package/src/lib/db/migrations/012_fix_token_input_cache_tokens.sql +15 -0
- package/src/lib/db/migrations/013_quota_snapshots.sql +19 -0
- package/src/lib/db/migrations/014_unified_log_artifacts.sql +15 -0
- package/src/lib/db/migrations/015_create_memories.sql +22 -0
- package/src/lib/db/migrations/016_create_skills.sql +37 -0
- package/src/lib/db/migrations/017_version_manager_upstream_proxy.sql +56 -0
- package/src/lib/db/migrations/018_call_logs_detailed_tokens.sql +6 -0
- package/src/lib/db/migrations/019_context_handoffs.sql +28 -0
- package/src/lib/db/migrations/020_combo_sort_order.sql +16 -0
- package/src/lib/db/migrations/021_combo_call_log_targets.sql +5 -0
- package/src/lib/db/migrations/022_add_memory_fts5.sql +33 -0
- package/src/lib/db/migrations/023_fix_memory_fts_uuid.sql +55 -0
- package/src/lib/db/migrations/024_create_sync_tokens.sql +15 -0
- package/src/lib/db/migrations/025_call_logs_summary_storage.sql +145 -0
- package/src/lib/db/migrations/027_skill_mode_and_metadata.sql +10 -0
- package/src/lib/db/migrations/028_create_files_and_batches.sql +51 -0
- package/src/lib/db/migrations/029_provider_connection_max_concurrent.sql +10 -0
- package/src/lib/db/migrations/030_create_eval_runs.sql +28 -0
- package/src/lib/db/migrations/031_create_eval_suites.sql +27 -0
- package/src/lib/db/migrations/032_apikey_lifecycle.sql +24 -0
- package/src/lib/db/migrations/033_create_reasoning_cache.sql +27 -0
- package/src/lib/db/migrations/034_compression_settings.sql +10 -0
- package/src/lib/db/migrations/035_standard_compression_config.sql +9 -0
- package/src/lib/db/migrations/036_aggressive_compression.sql +4 -0
- package/src/lib/db/migrations/037_ultra_compression.sql +6 -0
- package/src/lib/db/migrations/038_compression_analytics.sql +13 -0
- package/src/lib/db/migrations/039_compression_cache_stats.sql +15 -0
- package/src/lib/db/migrations/040_oneproxy_proxy_fields.sql +24 -0
- package/src/lib/db/migrations/041_compression_receipts.sql +18 -0
- package/src/lib/db/migrations/042_compression_combos.sql +43 -0
- package/src/lib/db/migrations/043_default_compression_combo_pipeline.sql +12 -0
- package/src/lib/db/migrations/044_usage_history_api_key_backfill.sql +27 -0
- package/src/lib/db/migrations/045_compression_tokens.sql +4 -0
- package/src/lib/db/migrations/046_database_settings.sql +44 -0
- package/src/lib/db/migrations/047_aggregation_tables.sql +44 -0
- package/src/lib/db/migrations/048_summary_indexes.sql +29 -0
- package/src/lib/db/migrations/049_compression_analytics_indexes.sql +10 -0
- package/src/lib/db/migrations/050_session_account_affinity.sql +11 -0
- package/src/lib/db/migrations/051_hot_path_db_indexes.sql +10 -0
- package/src/lib/db/migrations/052_api_key_combo_throttle.sql +4 -0
- package/src/lib/db/migrations/053_remove_status_from_files.sql +2 -0
- package/src/lib/db/migrations/054_usage_history_service_tier.sql +4 -0
- package/src/lib/db/migrations/056_mcp_accessibility_compression.sql +8 -0
- package/src/lib/db/migrations/057_provider_connection_quota_window_thresholds.sql +14 -0
- package/src/lib/db/migrations/058_command_code_auth_sessions.sql +19 -0
- package/src/lib/db/migrations/059_manifest_routing.sql +21 -0
- package/src/lib/db/migrations/060_create_gamification.sql +94 -0
- package/src/lib/db/migrations/061_cloud_agent_credentials.sql +9 -0
- package/src/lib/db/migrations/062_usage_history_combo_strategy.sql +4 -0
- package/src/lib/db/migrations/063_add_last_model_to_handoffs.sql +7 -0
- package/src/lib/db/migrations/064_create_session_model_history.sql +19 -0
- package/src/lib/db/migrations/065_middleware_hooks.sql +45 -0
- package/src/lib/db/migrations/066_api_key_groups.sql +47 -0
- package/src/lib/db/migrations/067_relay_proxies.sql +56 -0
- package/src/lib/db/migrations/068_free_proxies.sql +52 -0
- package/src/lib/db/migrations/069_webhook_deliveries.sql +15 -0
- package/src/lib/db/migrations/070_webhooks_kind_metadata.sql +3 -0
- package/src/lib/db/migrations/071_services.sql +19 -0
- package/src/lib/db/migrations/072_free_proxies_fk.sql +27 -0
- package/src/lib/db/migrations/073_per_model_token_limits.sql +61 -0
- package/src/lib/db/migrations/074_discovery_results.sql +20 -0
- package/src/lib/db/migrations/075_api_key_self_service_usage_scopes.sql +51 -0
- package/src/lib/db/migrations/076_create_plugins.sql +31 -0
- package/src/lib/db/migrations/077_api_key_stream_default_mode.sql +3 -0
- package/src/lib/db/migrations/078_quota_consumption.sql +24 -0
- package/src/lib/db/migrations/079_provider_plans.sql +19 -0
- package/src/lib/db/migrations/080_agent_bridge.sql +24 -0
- package/src/lib/db/migrations/081_inspector_custom_hosts.sql +11 -0
- package/src/lib/db/migrations/082_inspector_sessions.sql +18 -0
- package/src/lib/db/migrations/083_memory_vec.sql +26 -0
- package/src/lib/db/migrations/084_playground_presets.sql +15 -0
- package/src/lib/db/migrations/085_quota_pools.sql +39 -0
- package/src/lib/db/migrations/086_api_key_allowed_quotas.sql +8 -0
- package/src/lib/db/migrations/087_quota_pool_connections.sql +21 -0
- package/src/lib/db/migrations/088_quota_groups.sql +28 -0
- package/src/lib/db/migrations/089_add_disable_non_public_to_api_keys.sql +3 -0
- package/src/lib/db/migrations/090_plugin_metrics.sql +9 -0
- package/src/lib/db/migrations/091_plugin_analytics.sql +23 -0
- package/src/lib/db/migrations/092_api_key_context_sources.sql +13 -0
- package/src/lib/db/migrations/093_proxy_enable_toggles.sql +17 -0
- package/src/lib/db/migrations/094_per_key_proxy_toggles.sql +12 -0
- package/src/lib/db/migrations/095_provider_node_custom_headers.sql +5 -0
- package/src/lib/db/migrations/096_sync_context_cache_protection.sql +9 -0
- package/src/lib/db/migrations/097_model_intelligence.sql +25 -0
- package/src/lib/db/migrations/098_clear_semantic_cache_for_key_isolation.sql +4 -0
- package/src/lib/db/migrations/099_proxy_family.sql +5 -0
- package/src/lib/db/migrations/100_cli_access_tokens.sql +18 -0
- package/src/lib/db/migrations/101_api_key_usage_limits.sql +4 -0
- package/src/lib/db/migrations/102_compression_engines_map.sql +5 -0
- package/src/lib/db/migrations/103_strip_legacy_combo_config_keys.sql +54 -0
- package/src/lib/db/migrations/104_normalize_database_cache_size.sql +10 -0
- package/src/lib/db/migrations/105_usage_history_endpoint.sql +6 -0
- package/src/lib/db/migrations/106_quota_allocation_model_caps.sql +32 -0
- package/src/lib/db/migrations/107_quota_combos_quota_share_strategy.sql +25 -0
- package/src/lib/db/migrations/108_provider_quota_reset_events.sql +26 -0
- package/src/lib/db/migrations/109_call_logs_correlation_id.sql +2 -0
- package/src/lib/db/migrations/110_model_context_overrides.sql +17 -0
- package/src/lib/db/migrations/111_memory_typed_decay.sql +10 -0
- package/src/lib/db/migrations/112_batch_item_checkpoints.sql +18 -0
- package/src/lib/db/migrations/113_provider_node_icon_url.sql +5 -0
- package/src/lib/db/migrations/114_mux_service_seed.sql +12 -0
- package/src/lib/db/migrations/115_bifrost_service.sql +9 -0
- package/src/lib/db/migrations/116_call_logs_reasoning_source.sql +13 -0
- package/src/lib/db/migrations/117_proxy_pool_rotation.sql +53 -0
- package/src/lib/db/modelComboMappings.ts +255 -0
- package/src/lib/db/modelContextOverrides.ts +133 -0
- package/src/lib/db/modelIntelligence.ts +232 -0
- package/src/lib/db/models/aliases.ts +61 -0
- package/src/lib/db/models/compat.ts +249 -0
- package/src/lib/db/models/mitmAlias.ts +32 -0
- package/src/lib/db/models/shared.ts +19 -0
- package/src/lib/db/models.ts +936 -0
- package/src/lib/db/notion.ts +48 -0
- package/src/lib/db/obsidian.ts +283 -0
- package/src/lib/db/oneproxy.ts +293 -0
- package/src/lib/db/optimizationSettings.ts +284 -0
- package/src/lib/db/playgroundPresets.ts +167 -0
- package/src/lib/db/pluginMetrics.ts +88 -0
- package/src/lib/db/plugins.ts +280 -0
- package/src/lib/db/prompts.ts +302 -0
- package/src/lib/db/providerLimits.ts +131 -0
- package/src/lib/db/providerNodeSelect.ts +48 -0
- package/src/lib/db/providerPlans.ts +149 -0
- package/src/lib/db/providerStats.ts +68 -0
- package/src/lib/db/providers/columns.ts +116 -0
- package/src/lib/db/providers/nodes.ts +169 -0
- package/src/lib/db/providers/rateLimit.ts +198 -0
- package/src/lib/db/providers.ts +803 -0
- package/src/lib/db/proxies/mappers.ts +181 -0
- package/src/lib/db/proxies/types.ts +78 -0
- package/src/lib/db/proxies.ts +1176 -0
- package/src/lib/db/proxyLogs.ts +35 -0
- package/src/lib/db/quotaConsumption.ts +274 -0
- package/src/lib/db/quotaGroups.ts +147 -0
- package/src/lib/db/quotaModelCaps.ts +128 -0
- package/src/lib/db/quotaPools.ts +548 -0
- package/src/lib/db/quotaResetEvents.ts +334 -0
- package/src/lib/db/quotaSnapshots.ts +209 -0
- package/src/lib/db/readCache.ts +202 -0
- package/src/lib/db/reasoningCache.ts +276 -0
- package/src/lib/db/recovery.ts +33 -0
- package/src/lib/db/registeredKeys.ts +532 -0
- package/src/lib/db/relayProxies.ts +364 -0
- package/src/lib/db/schemaColumns.ts +226 -0
- package/src/lib/db/secrets.ts +28 -0
- package/src/lib/db/semanticCache.ts +117 -0
- package/src/lib/db/serviceModels.ts +79 -0
- package/src/lib/db/sessionAccountAffinity.ts +212 -0
- package/src/lib/db/settings/cacheMetrics.ts +235 -0
- package/src/lib/db/settings/lkgp.ts +49 -0
- package/src/lib/db/settings/pricing.ts +254 -0
- package/src/lib/db/settings/shared.ts +9 -0
- package/src/lib/db/settings.ts +661 -0
- package/src/lib/db/skills.ts +62 -0
- package/src/lib/db/stateReset.ts +30 -0
- package/src/lib/db/stats.ts +71 -0
- package/src/lib/db/syncTokens.ts +163 -0
- package/src/lib/db/tierConfig.ts +88 -0
- package/src/lib/db/tokenLimits.ts +295 -0
- package/src/lib/db/upstreamProxy.ts +247 -0
- package/src/lib/db/usageAnalytics/sources.ts +208 -0
- package/src/lib/db/usageAnalytics.ts +723 -0
- package/src/lib/db/usageLogs.ts +94 -0
- package/src/lib/db/usageSummary.ts +18 -0
- package/src/lib/db/vacuumScheduler.ts +326 -0
- package/src/lib/db/versionManager.ts +377 -0
- package/src/lib/db/webSessionDedup.ts +57 -0
- package/src/lib/db/webhookDeliveries.ts +77 -0
- package/src/lib/db/webhooks.ts +178 -0
- package/src/lib/discovery/index.ts +137 -0
- package/src/lib/display/names.ts +73 -0
- package/src/lib/display/useProviderNodeMap.ts +68 -0
- package/src/lib/docsI18nPath.ts +33 -0
- package/src/lib/docsSanitizer.ts +42 -0
- package/src/lib/embeddings/familyGuard.ts +24 -0
- package/src/lib/embeddings/service.ts +288 -0
- package/src/lib/env/runtimeEnv.ts +166 -0
- package/src/lib/evals/evalRunner/builtinSuites.ts +676 -0
- package/src/lib/evals/evalRunner.ts +301 -0
- package/src/lib/evals/runtime.ts +311 -0
- package/src/lib/events/eventBus.ts +148 -0
- package/src/lib/events/types.ts +181 -0
- package/src/lib/freeProviderRankings.ts +340 -0
- package/src/lib/freeProxyProviders/index.ts +24 -0
- package/src/lib/freeProxyProviders/iplocate.ts +107 -0
- package/src/lib/freeProxyProviders/oneproxy.ts +127 -0
- package/src/lib/freeProxyProviders/proxifly.ts +143 -0
- package/src/lib/freeProxyProviders/types.ts +33 -0
- package/src/lib/freeProxyProviders/webshare.ts +148 -0
- package/src/lib/gamification/antiCheat.ts +160 -0
- package/src/lib/gamification/badges.ts +542 -0
- package/src/lib/gamification/events.ts +187 -0
- package/src/lib/gamification/index.ts +37 -0
- package/src/lib/gamification/invites.ts +127 -0
- package/src/lib/gamification/leaderboard.ts +64 -0
- package/src/lib/gamification/notifications.ts +118 -0
- package/src/lib/gamification/servers.ts +179 -0
- package/src/lib/gamification/sharing.ts +56 -0
- package/src/lib/gamification/streaks.ts +164 -0
- package/src/lib/gamification/xp.ts +152 -0
- package/src/lib/gracefulShutdown.ts +151 -0
- package/src/lib/guardrails/base.ts +65 -0
- package/src/lib/guardrails/index.ts +4 -0
- package/src/lib/guardrails/piiMasker.ts +208 -0
- package/src/lib/guardrails/promptInjection.ts +285 -0
- package/src/lib/guardrails/registry.ts +282 -0
- package/src/lib/guardrails/visionBridge.ts +237 -0
- package/src/lib/guardrails/visionBridgeHelpers.ts +499 -0
- package/src/lib/guardrails/visionBridgeRouter.ts +271 -0
- package/src/lib/headroom/detect.ts +214 -0
- package/src/lib/headroom/process.ts +177 -0
- package/src/lib/idempotencyLayer.ts +105 -0
- package/src/lib/images/imageRouteModel.ts +168 -0
- package/src/lib/initCloudSync.ts +52 -0
- package/src/lib/inspector/agentBridgeMaintenanceApi.ts +70 -0
- package/src/lib/inspector/captureState.ts +90 -0
- package/src/lib/inspector/configPortability.ts +86 -0
- package/src/lib/inspector/harExport.ts +188 -0
- package/src/lib/inspector/matchesTrafficFilter.ts +37 -0
- package/src/lib/inspector/secretMask.ts +6 -0
- package/src/lib/inspector/tproxyCaptureApi.ts +60 -0
- package/src/lib/ipUtils.ts +94 -0
- package/src/lib/jobs/budgetResetJob.ts +40 -0
- package/src/lib/jobs/reasoningCacheCleanupJob.ts +40 -0
- package/src/lib/localDb.ts +797 -0
- package/src/lib/localHealthCheck.ts +267 -0
- package/src/lib/logEnv.ts +164 -0
- package/src/lib/logPayloads.ts +110 -0
- package/src/lib/logRotation.ts +206 -0
- package/src/lib/machineToken.ts +53 -0
- package/src/lib/memory/cache.ts +76 -0
- package/src/lib/memory/embedding/cache.ts +77 -0
- package/src/lib/memory/embedding/index.ts +281 -0
- package/src/lib/memory/embedding/remote.ts +95 -0
- package/src/lib/memory/embedding/staticPotion.ts +253 -0
- package/src/lib/memory/embedding/transformersLocal.ts +153 -0
- package/src/lib/memory/embedding/types.ts +40 -0
- package/src/lib/memory/extraction.ts +195 -0
- package/src/lib/memory/injection.ts +211 -0
- package/src/lib/memory/qdrant.ts +521 -0
- package/src/lib/memory/reindex.ts +102 -0
- package/src/lib/memory/retrieval/scoring.ts +104 -0
- package/src/lib/memory/retrieval.ts +1072 -0
- package/src/lib/memory/schemas.ts +39 -0
- package/src/lib/memory/settings.ts +184 -0
- package/src/lib/memory/store.ts +621 -0
- package/src/lib/memory/summarization.ts +202 -0
- package/src/lib/memory/typedDecay.ts +245 -0
- package/src/lib/memory/types.ts +45 -0
- package/src/lib/memory/vectorStore.ts +425 -0
- package/src/lib/memory/verify.ts +56 -0
- package/src/lib/middleware/cliTokenAuth.ts +91 -0
- package/src/lib/middleware/registry.ts +432 -0
- package/src/lib/middleware/types.ts +129 -0
- package/src/lib/modelAliasSeed.ts +82 -0
- package/src/lib/modelCapabilities.ts +481 -0
- package/src/lib/modelMetadataRegistry.ts +574 -0
- package/src/lib/modelsDevSync/transform.ts +279 -0
- package/src/lib/modelsDevSync.ts +677 -0
- package/src/lib/monitoring/comboHealthAutopilot.ts +494 -0
- package/src/lib/monitoring/observability.ts +336 -0
- package/src/lib/monitoring/providerHealthAutopilot.ts +743 -0
- package/src/lib/monitoring/providerHealthMatrix.ts +621 -0
- package/src/lib/ngrokTunnel.ts +142 -0
- package/src/lib/notion/api.ts +247 -0
- package/src/lib/oauth/codexDeviceFlow.ts +316 -0
- package/src/lib/oauth/config/index.ts +31 -0
- package/src/lib/oauth/connectionPersistence.ts +114 -0
- package/src/lib/oauth/constants/oauth.ts +494 -0
- package/src/lib/oauth/credentialBlob.ts +105 -0
- package/src/lib/oauth/deviceFlowTickets.ts +110 -0
- package/src/lib/oauth/gitlab.ts +103 -0
- package/src/lib/oauth/pasteCredentials.ts +51 -0
- package/src/lib/oauth/providers/agy.ts +15 -0
- package/src/lib/oauth/providers/antigravity.ts +159 -0
- package/src/lib/oauth/providers/claude.ts +170 -0
- package/src/lib/oauth/providers/cline.ts +91 -0
- package/src/lib/oauth/providers/codebuddy-cn.ts +123 -0
- package/src/lib/oauth/providers/codex.ts +214 -0
- package/src/lib/oauth/providers/cursor.ts +15 -0
- package/src/lib/oauth/providers/github.ts +89 -0
- package/src/lib/oauth/providers/gitlab-duo.ts +124 -0
- package/src/lib/oauth/providers/grok-cli.ts +155 -0
- package/src/lib/oauth/providers/index.ts +59 -0
- package/src/lib/oauth/providers/kilocode.ts +77 -0
- package/src/lib/oauth/providers/kimi-coding.ts +135 -0
- package/src/lib/oauth/providers/kiro.ts +185 -0
- package/src/lib/oauth/providers/qoder.ts +81 -0
- package/src/lib/oauth/providers/qwen.ts +82 -0
- package/src/lib/oauth/providers/trae.ts +78 -0
- package/src/lib/oauth/providers/windsurf.ts +64 -0
- package/src/lib/oauth/providers/zed-hosted.ts +89 -0
- package/src/lib/oauth/providers/zed.ts +35 -0
- package/src/lib/oauth/providers.ts +278 -0
- package/src/lib/oauth/services/codexImport.ts +222 -0
- package/src/lib/oauth/services/cursor.ts +219 -0
- package/src/lib/oauth/services/kiro.ts +441 -0
- package/src/lib/oauth/utils/agyAuthImport.ts +259 -0
- package/src/lib/oauth/utils/banner.ts +62 -0
- package/src/lib/oauth/utils/claudeAuthFile.ts +334 -0
- package/src/lib/oauth/utils/claudeAuthImport.ts +259 -0
- package/src/lib/oauth/utils/claudeAuthZipExtract.ts +5 -0
- package/src/lib/oauth/utils/cliProxyAuthImport.ts +142 -0
- package/src/lib/oauth/utils/codexAuthFile.ts +352 -0
- package/src/lib/oauth/utils/codexAuthImport.ts +294 -0
- package/src/lib/oauth/utils/codexAuthZipExtract.ts +5 -0
- package/src/lib/oauth/utils/jsonZipExtract.ts +89 -0
- package/src/lib/oauth/utils/pkce.ts +37 -0
- package/src/lib/oauth/utils/server.ts +122 -0
- package/src/lib/oauth/utils/ui.ts +47 -0
- package/src/lib/obsidian/api.ts +390 -0
- package/src/lib/obsidianSync.ts +110 -0
- package/src/lib/oneproxyRotator.ts +19 -0
- package/src/lib/oneproxySync.ts +182 -0
- package/src/lib/piiSanitizer.ts +416 -0
- package/src/lib/playground/codeExport.ts +408 -0
- package/src/lib/playground/promptImprover.ts +147 -0
- package/src/lib/playground/streamMetrics.ts +61 -0
- package/src/lib/playground/types.ts +114 -0
- package/src/lib/plugins/devMode.ts +65 -0
- package/src/lib/plugins/doctor.ts +138 -0
- package/src/lib/plugins/errors.ts +38 -0
- package/src/lib/plugins/hooks.ts +322 -0
- package/src/lib/plugins/index.ts +72 -0
- package/src/lib/plugins/loader.ts +326 -0
- package/src/lib/plugins/logger.ts +50 -0
- package/src/lib/plugins/manager.ts +579 -0
- package/src/lib/plugins/manifest.ts +213 -0
- package/src/lib/plugins/marketplace.ts +202 -0
- package/src/lib/plugins/pluginWorker.ts +246 -0
- package/src/lib/plugins/sandbox.ts +29 -0
- package/src/lib/plugins/scanner.ts +110 -0
- package/src/lib/plugins/sdk.ts +88 -0
- package/src/lib/plugins/signing.ts +34 -0
- package/src/lib/plugins/testRunner.ts +95 -0
- package/src/lib/plugins/watcher.ts +90 -0
- package/src/lib/pricingSync.ts +456 -0
- package/src/lib/promptCache/index.ts +1 -0
- package/src/lib/promptCache/prefixAnalyzer.ts +81 -0
- package/src/lib/providerModels/cursorAgent.ts +166 -0
- package/src/lib/providerModels/geminiModelsParser.ts +91 -0
- package/src/lib/providerModels/managedAvailableModels.ts +165 -0
- package/src/lib/providerModels/managedModelImport.ts +349 -0
- package/src/lib/providerModels/modelDiscovery.ts +151 -0
- package/src/lib/providers/catalog.ts +246 -0
- package/src/lib/providers/claudeExtraUsage.ts +160 -0
- package/src/lib/providers/claudeFastMode.ts +75 -0
- package/src/lib/providers/codexConnectionDefaults.ts +85 -0
- package/src/lib/providers/codexFastTier.ts +210 -0
- package/src/lib/providers/imageValidation.ts +160 -0
- package/src/lib/providers/managedAvailableModels.ts +21 -0
- package/src/lib/providers/modelListingCapability.ts +26 -0
- package/src/lib/providers/nvidiaValidationModel.ts +24 -0
- package/src/lib/providers/requestDefaults.ts +318 -0
- package/src/lib/providers/serviceKindIndex.ts +0 -0
- package/src/lib/providers/staticModels.ts +170 -0
- package/src/lib/providers/validation/anthropicFormat.ts +319 -0
- package/src/lib/providers/validation/audioMiscProviders.ts +582 -0
- package/src/lib/providers/validation/cloudProviders.ts +669 -0
- package/src/lib/providers/validation/cozeError.ts +56 -0
- package/src/lib/providers/validation/directChatProbe.ts +47 -0
- package/src/lib/providers/validation/embeddingProviders.ts +143 -0
- package/src/lib/providers/validation/headers.ts +122 -0
- package/src/lib/providers/validation/metaAi.ts +117 -0
- package/src/lib/providers/validation/openaiFormat.ts +500 -0
- package/src/lib/providers/validation/searchProviders.ts +199 -0
- package/src/lib/providers/validation/transport.ts +109 -0
- package/src/lib/providers/validation/urlHelpers.ts +114 -0
- package/src/lib/providers/validation/webProvidersA.ts +808 -0
- package/src/lib/providers/validation/webProvidersB.ts +536 -0
- package/src/lib/providers/validation.ts +772 -0
- package/src/lib/providers/webCookieAuth.ts +157 -0
- package/src/lib/providers/xai/thinking.ts +127 -0
- package/src/lib/providers/xai/translators/claude.ts +368 -0
- package/src/lib/providers/xai/translators/gemini.ts +371 -0
- package/src/lib/providers/xai/translators/openai-chat.ts +310 -0
- package/src/lib/providers/xai/translators/openai-responses.ts +77 -0
- package/src/lib/proxyEgress.ts +388 -0
- package/src/lib/proxyHealth/decision.ts +77 -0
- package/src/lib/proxyHealth/scheduler.ts +207 -0
- package/src/lib/proxyHealth/statusPolicy.ts +41 -0
- package/src/lib/proxyHealth.ts +173 -0
- package/src/lib/proxyLogger.ts +240 -0
- package/src/lib/proxyRelay/cloudflareWorkerScript.ts +107 -0
- package/src/lib/quota/QuotaStore.ts +23 -0
- package/src/lib/quota/accountBuckets.ts +225 -0
- package/src/lib/quota/burnRate.ts +111 -0
- package/src/lib/quota/connectionProvider.ts +32 -0
- package/src/lib/quota/connectionRecovery.ts +303 -0
- package/src/lib/quota/dimensions.ts +61 -0
- package/src/lib/quota/enforce.ts +401 -0
- package/src/lib/quota/fairShare.ts +186 -0
- package/src/lib/quota/planRegistry.ts +107 -0
- package/src/lib/quota/planResolver.ts +78 -0
- package/src/lib/quota/quotaCombos.ts +414 -0
- package/src/lib/quota/quotaKey.ts +202 -0
- package/src/lib/quota/quotaModelNaming.ts +84 -0
- package/src/lib/quota/redisQuotaStore.ts +352 -0
- package/src/lib/quota/saturationSignals.ts +559 -0
- package/src/lib/quota/spendRecorder.ts +131 -0
- package/src/lib/quota/sqliteQuotaStore.ts +282 -0
- package/src/lib/quota/storeFactory.ts +124 -0
- package/src/lib/quota/types.ts +94 -0
- package/src/lib/resilience/modelLockoutSettings.ts +95 -0
- package/src/lib/resilience/settings/normalize.ts +359 -0
- package/src/lib/resilience/settings/types.ts +182 -0
- package/src/lib/resilience/settings.ts +386 -0
- package/src/lib/runtime/ports.ts +32 -0
- package/src/lib/search/executeWebSearch.ts +270 -0
- package/src/lib/security/localEndpoints.ts +82 -0
- package/src/lib/semanticCache.ts +377 -0
- package/src/lib/services/ServiceSupervisor.ts +243 -0
- package/src/lib/services/apiKey.ts +40 -0
- package/src/lib/services/bootstrap.ts +133 -0
- package/src/lib/services/embedPath.ts +19 -0
- package/src/lib/services/embedWsProxy.ts +285 -0
- package/src/lib/services/healthCheck.ts +79 -0
- package/src/lib/services/htmlRewriter.ts +185 -0
- package/src/lib/services/installers/bifrost.ts +145 -0
- package/src/lib/services/installers/cliproxy.ts +116 -0
- package/src/lib/services/installers/mux.ts +178 -0
- package/src/lib/services/installers/ninerouter.stub.ts +17 -0
- package/src/lib/services/installers/ninerouter.ts +157 -0
- package/src/lib/services/installers/utils.ts +167 -0
- package/src/lib/services/modelSync.ts +105 -0
- package/src/lib/services/portProbe.ts +104 -0
- package/src/lib/services/registry.ts +42 -0
- package/src/lib/services/reverseProxy.ts +180 -0
- package/src/lib/services/ringBuffer.ts +91 -0
- package/src/lib/services/types.ts +50 -0
- package/src/lib/settingsCache.ts +62 -0
- package/src/lib/skills/a2a.ts +34 -0
- package/src/lib/skills/builtin/browser.ts +22 -0
- package/src/lib/skills/builtins.ts +493 -0
- package/src/lib/skills/custom.ts +41 -0
- package/src/lib/skills/executor.ts +196 -0
- package/src/lib/skills/githubCollector.ts +426 -0
- package/src/lib/skills/hybrid.ts +67 -0
- package/src/lib/skills/injection.ts +307 -0
- package/src/lib/skills/interception.ts +343 -0
- package/src/lib/skills/providerSettings.ts +14 -0
- package/src/lib/skills/registry.ts +398 -0
- package/src/lib/skills/sandbox.ts +178 -0
- package/src/lib/skills/schemas.ts +43 -0
- package/src/lib/skills/skillssh.ts +73 -0
- package/src/lib/skills/types.ts +61 -0
- package/src/lib/source.ts +7 -0
- package/src/lib/spend/batchWriter.ts +208 -0
- package/src/lib/sseTextTransform.ts +346 -0
- package/src/lib/streamingPiiTransform.ts +350 -0
- package/src/lib/sync/bundle.ts +208 -0
- package/src/lib/sync/tokens.ts +107 -0
- package/src/lib/system/autoUpdate.ts +400 -0
- package/src/lib/system/globalPackagePath.ts +49 -0
- package/src/lib/system/versionCheck.ts +163 -0
- package/src/lib/tailscaleTunnel.ts +1201 -0
- package/src/lib/tokenHealthCheck.ts +829 -0
- package/src/lib/toolPolicy.ts +150 -0
- package/src/lib/translator/streamTransform.ts +27 -0
- package/src/lib/translatorEvents.ts +40 -0
- package/src/lib/usage/aggregateHistory.ts +212 -0
- package/src/lib/usage/apiKeySelfService.ts +420 -0
- package/src/lib/usage/apiKeyUsageLimits.ts +578 -0
- package/src/lib/usage/callLogArtifacts.ts +337 -0
- package/src/lib/usage/callLogs/format.ts +129 -0
- package/src/lib/usage/callLogs.ts +928 -0
- package/src/lib/usage/callLogsBoundedQueries.ts +42 -0
- package/src/lib/usage/codexResetCredits.ts +355 -0
- package/src/lib/usage/comboForecast.ts +441 -0
- package/src/lib/usage/comboHealth.ts +545 -0
- package/src/lib/usage/comboHealthDashboard.ts +109 -0
- package/src/lib/usage/comboScoringInspector.ts +416 -0
- package/src/lib/usage/completedRequestDetails.ts +103 -0
- package/src/lib/usage/costCalculator.ts +279 -0
- package/src/lib/usage/fetcher.ts +483 -0
- package/src/lib/usage/flatRateProviders.ts +59 -0
- package/src/lib/usage/internalUsageCommand.ts +788 -0
- package/src/lib/usage/migrations.ts +471 -0
- package/src/lib/usage/pendingRequestScope.ts +26 -0
- package/src/lib/usage/providerLimits/quotaNormalize.ts +72 -0
- package/src/lib/usage/providerLimits.ts +997 -0
- package/src/lib/usage/providerWindowCosts.ts +571 -0
- package/src/lib/usage/resilienceExplain.ts +468 -0
- package/src/lib/usage/routeExplain.ts +747 -0
- package/src/lib/usage/tokenAccounting.ts +212 -0
- package/src/lib/usage/usageEvents.ts +91 -0
- package/src/lib/usage/usageHistory/helpers.ts +85 -0
- package/src/lib/usage/usageHistory.ts +916 -0
- package/src/lib/usage/usageStats.ts +581 -0
- package/src/lib/usageAnalytics.ts +372 -0
- package/src/lib/usageDb.ts +38 -0
- package/src/lib/versionManager/binaryManager.ts +240 -0
- package/src/lib/versionManager/healthMonitor.ts +71 -0
- package/src/lib/versionManager/index.ts +155 -0
- package/src/lib/versionManager/processManager.ts +155 -0
- package/src/lib/versionManager/releaseChecker.ts +98 -0
- package/src/lib/vscode/familyFirstModelIds.ts +92 -0
- package/src/lib/vscode/modelPresentation.ts +132 -0
- package/src/lib/vscode/reasoningMetadata.ts +183 -0
- package/src/lib/vscode/serviceTierVariants.ts +202 -0
- package/src/lib/vscode/tokenizedRequest.ts +79 -0
- package/src/lib/webhookDispatcher.ts +221 -0
- package/src/lib/webhooks/eventDescriptions.ts +76 -0
- package/src/lib/webhooks/integrations/discord.ts +49 -0
- package/src/lib/webhooks/integrations/slack.ts +45 -0
- package/src/lib/webhooks/integrations/telegram.ts +67 -0
- package/src/lib/ws/handshake.ts +129 -0
- package/src/lib/zed-oauth/confirmedAccounts.ts +38 -0
- package/src/lib/zed-oauth/credentialFingerprint.ts +23 -0
- package/src/lib/zed-oauth/dockerDetect.ts +38 -0
- package/src/lib/zed-oauth/importUtils.ts +46 -0
- package/src/lib/zed-oauth/keychain-reader.stub.ts +28 -0
- package/src/lib/zed-oauth/keychain-reader.ts +231 -0
- package/src/mitm/_internal/bypass.cjs +170 -0
- package/src/mitm/_internal/forwardTarget.cjs +55 -0
- package/src/mitm/_internal/ingest.cjs +82 -0
- package/src/mitm/cert/generate.ts +41 -0
- package/src/mitm/cert/install.stub.ts +23 -0
- package/src/mitm/cert/install.ts +440 -0
- package/src/mitm/dataDir.ts +41 -0
- package/src/mitm/detection/antigravity.ts +33 -0
- package/src/mitm/detection/claudeCode.ts +25 -0
- package/src/mitm/detection/codex.ts +25 -0
- package/src/mitm/detection/copilot.ts +39 -0
- package/src/mitm/detection/cursor.ts +31 -0
- package/src/mitm/detection/index.ts +53 -0
- package/src/mitm/detection/kiro.ts +30 -0
- package/src/mitm/detection/openCode.ts +32 -0
- package/src/mitm/detection/zed.ts +26 -0
- package/src/mitm/dns/dnsConfig.ts +242 -0
- package/src/mitm/dns/provision.ts +92 -0
- package/src/mitm/handlers/antigravity.ts +192 -0
- package/src/mitm/handlers/base.ts +333 -0
- package/src/mitm/handlers/claudeCode.ts +56 -0
- package/src/mitm/handlers/codex.ts +55 -0
- package/src/mitm/handlers/copilot.ts +55 -0
- package/src/mitm/handlers/cursor.ts +55 -0
- package/src/mitm/handlers/kiro.ts +58 -0
- package/src/mitm/handlers/openCode.ts +55 -0
- package/src/mitm/handlers/trae.ts +24 -0
- package/src/mitm/handlers/zed.ts +55 -0
- package/src/mitm/inspector/agentBridgeHook.ts +137 -0
- package/src/mitm/inspector/buffer.ts +201 -0
- package/src/mitm/inspector/contextKey.ts +98 -0
- package/src/mitm/inspector/conversationNormalizer.ts +393 -0
- package/src/mitm/inspector/diagnostics.ts +67 -0
- package/src/mitm/inspector/httpProxyServer.ts +272 -0
- package/src/mitm/inspector/kindDetector.ts +87 -0
- package/src/mitm/inspector/llmMetadataExtractor.ts +183 -0
- package/src/mitm/inspector/pricing.ts +57 -0
- package/src/mitm/inspector/processAttribution.ts +107 -0
- package/src/mitm/inspector/sseMerger.ts +316 -0
- package/src/mitm/inspector/systemProxyConfig.ts +316 -0
- package/src/mitm/inspector/types.ts +112 -0
- package/src/mitm/manager.runtime.ts +5 -0
- package/src/mitm/manager.stub.ts +44 -0
- package/src/mitm/manager.ts +762 -0
- package/src/mitm/maskSecrets.ts +31 -0
- package/src/mitm/passthrough.ts +76 -0
- package/src/mitm/sanitizeHeaders.ts +61 -0
- package/src/mitm/server.cjs +786 -0
- package/src/mitm/socketTimeouts.ts +24 -0
- package/src/mitm/systemCommands.ts +280 -0
- package/src/mitm/targets/antigravity.ts +85 -0
- package/src/mitm/targets/claudeCode.ts +37 -0
- package/src/mitm/targets/codex.ts +30 -0
- package/src/mitm/targets/copilot.ts +32 -0
- package/src/mitm/targets/cursor.ts +33 -0
- package/src/mitm/targets/index.ts +75 -0
- package/src/mitm/targets/kiro.ts +64 -0
- package/src/mitm/targets/openCode.ts +34 -0
- package/src/mitm/targets/trae.ts +32 -0
- package/src/mitm/targets/zed.ts +32 -0
- package/src/mitm/tproxy/caTrust.ts +120 -0
- package/src/mitm/tproxy/captureManager.ts +118 -0
- package/src/mitm/tproxy/captureMode.ts +226 -0
- package/src/mitm/tproxy/commands.ts +122 -0
- package/src/mitm/tproxy/dynamicCert.ts +119 -0
- package/src/mitm/tproxy/native/README.md +55 -0
- package/src/mitm/tproxy/native/binding.gyp +9 -0
- package/src/mitm/tproxy/native/transparent.c +147 -0
- package/src/mitm/tproxy/setup.ts +68 -0
- package/src/mitm/tproxy/tlsCapture.ts +368 -0
- package/src/mitm/tproxy/transparentSocket.ts +131 -0
- package/src/mitm/types.ts +75 -0
- package/src/mitm/upstreamTrust.ts +40 -0
- package/src/models/index.ts +29 -0
- package/src/server/auth/loginGuard.ts +130 -0
- package/src/server/authz/accessScopes.ts +62 -0
- package/src/server/authz/accessTokenAuth.ts +67 -0
- package/src/server/authz/assertAuth.ts +88 -0
- package/src/server/authz/classify.ts +135 -0
- package/src/server/authz/context.ts +44 -0
- package/src/server/authz/csrf.ts +85 -0
- package/src/server/authz/headers.ts +76 -0
- package/src/server/authz/peerStamp.ts +99 -0
- package/src/server/authz/pipeline.ts +370 -0
- package/src/server/authz/policies/clientApi.ts +72 -0
- package/src/server/authz/policies/management.ts +298 -0
- package/src/server/authz/policies/public.ts +9 -0
- package/src/server/authz/routeGuard.ts +233 -0
- package/src/server/authz/types.ts +77 -0
- package/src/server/cors/origins.ts +172 -0
- package/src/server/origin/publicOrigin.ts +270 -0
- package/src/server/ws/liveServer.ts +630 -0
- package/src/server/ws/liveServerAllowList.ts +106 -0
- package/src/server/ws/types.ts +57 -0
- package/src/shared/components/Avatar.tsx +81 -0
- package/src/shared/components/Badge.tsx +68 -0
- package/src/shared/components/Breadcrumbs.tsx +103 -0
- package/src/shared/components/Button.tsx +85 -0
- package/src/shared/components/Card.tsx +141 -0
- package/src/shared/components/Checkbox.tsx +38 -0
- package/src/shared/components/CloudSyncStatus.tsx +104 -0
- package/src/shared/components/Collapsible.tsx +93 -0
- package/src/shared/components/CollapsibleSection.tsx +66 -0
- package/src/shared/components/ColumnToggle.tsx +100 -0
- package/src/shared/components/CommandPalette.tsx +375 -0
- package/src/shared/components/ConsoleLogViewer.tsx +326 -0
- package/src/shared/components/CursorAuthModal.tsx +198 -0
- package/src/shared/components/DataTable.tsx +195 -0
- package/src/shared/components/DegradationBadge.tsx +41 -0
- package/src/shared/components/DistributeProxiesButton.tsx +74 -0
- package/src/shared/components/EmptyState.tsx +121 -0
- package/src/shared/components/ErrorPageScaffold.tsx +91 -0
- package/src/shared/components/FilterBar.tsx +197 -0
- package/src/shared/components/Footer.tsx +169 -0
- package/src/shared/components/Header.tsx +284 -0
- package/src/shared/components/InfoTooltip.tsx +34 -0
- package/src/shared/components/Input.tsx +155 -0
- package/src/shared/components/KiroAuthModal.tsx +425 -0
- package/src/shared/components/KiroOAuthWrapper.tsx +116 -0
- package/src/shared/components/KiroSocialOAuthModal.tsx +202 -0
- package/src/shared/components/LanguageSelector.tsx +106 -0
- package/src/shared/components/LinkifiedText.tsx +30 -0
- package/src/shared/components/Loading.tsx +128 -0
- package/src/shared/components/LocaleAutoDetect.tsx +43 -0
- package/src/shared/components/MaintenanceBanner.tsx +87 -0
- package/src/shared/components/ManualConfigModal.tsx +51 -0
- package/src/shared/components/Modal.tsx +240 -0
- package/src/shared/components/ModelRoutingSection.tsx +323 -0
- package/src/shared/components/ModelSelectModal.tsx +618 -0
- package/src/shared/components/MonacoEditor.tsx +23 -0
- package/src/shared/components/NavigationProgress.tsx +105 -0
- package/src/shared/components/NoAuthAccountCard.tsx +539 -0
- package/src/shared/components/NoAuthProviderCard.tsx +40 -0
- package/src/shared/components/NoAuthProviderToggle.tsx +36 -0
- package/src/shared/components/NotificationToast.tsx +206 -0
- package/src/shared/components/OAuthModal.tsx +992 -0
- package/src/shared/components/OmniRouteLogo.tsx +86 -0
- package/src/shared/components/PresetSlider.tsx +64 -0
- package/src/shared/components/PricingModal.tsx +211 -0
- package/src/shared/components/ProviderIcon.tsx +263 -0
- package/src/shared/components/ProviderTestSlideOver.tsx +560 -0
- package/src/shared/components/ProxyConfigModal.tsx +781 -0
- package/src/shared/components/ProxyLogDetail.tsx +192 -0
- package/src/shared/components/ProxyLogger.tsx +573 -0
- package/src/shared/components/PwaRegister.tsx +22 -0
- package/src/shared/components/RequestLoggerDetail.tsx +797 -0
- package/src/shared/components/RequestLoggerV2.tsx +1628 -0
- package/src/shared/components/RiskNoticeModal.tsx +81 -0
- package/src/shared/components/SegmentedControl.tsx +69 -0
- package/src/shared/components/Select.tsx +110 -0
- package/src/shared/components/Sidebar.tsx +726 -0
- package/src/shared/components/SkillsConceptCard.tsx +84 -0
- package/src/shared/components/SystemMonitor.tsx +179 -0
- package/src/shared/components/Textarea.tsx +29 -0
- package/src/shared/components/ThemeProvider.tsx +14 -0
- package/src/shared/components/ThemeToggle.tsx +52 -0
- package/src/shared/components/Toggle.tsx +102 -0
- package/src/shared/components/TokenHealthBadge.tsx +113 -0
- package/src/shared/components/Tooltip.tsx +193 -0
- package/src/shared/components/TraeAuthModal.tsx +334 -0
- package/src/shared/components/UsageAnalytics.tsx +414 -0
- package/src/shared/components/UsageStats.tsx +693 -0
- package/src/shared/components/analytics/ApiKeyFilterDropdown.tsx +205 -0
- package/src/shared/components/analytics/CustomRangePicker.tsx +195 -0
- package/src/shared/components/analytics/TimeRangeSelector.tsx +49 -0
- package/src/shared/components/analytics/chartColors.ts +12 -0
- package/src/shared/components/analytics/charts.tsx +1023 -0
- package/src/shared/components/analytics/index.tsx +28 -0
- package/src/shared/components/analytics/rechartsCore.tsx +85 -0
- package/src/shared/components/analytics/rechartsDonuts.tsx +195 -0
- package/src/shared/components/analytics/rechartsUsageCharts.tsx +312 -0
- package/src/shared/components/cli/CliComparisonCard.tsx +82 -0
- package/src/shared/components/cli/CliConceptCard.tsx +58 -0
- package/src/shared/components/cli/CliToolCard.tsx +152 -0
- package/src/shared/components/cli/index.ts +8 -0
- package/src/shared/components/compression/CompressionPipelineEditor.tsx +175 -0
- package/src/shared/components/compression/EngineConfigForm.tsx +78 -0
- package/src/shared/components/compression/EngineConfigPage.tsx +411 -0
- package/src/shared/components/compression/compressionPipelineModel.ts +78 -0
- package/src/shared/components/docs/APIReference.stories.tsx +35 -0
- package/src/shared/components/docs/APIReference.tsx +83 -0
- package/src/shared/components/docs/Callout.stories.tsx +40 -0
- package/src/shared/components/docs/Callout.tsx +38 -0
- package/src/shared/components/docs/CodeBlock.stories.tsx +25 -0
- package/src/shared/components/docs/CodeBlock.tsx +52 -0
- package/src/shared/components/docs/DocsBreadcrumbs.stories.tsx +20 -0
- package/src/shared/components/docs/DocsBreadcrumbs.tsx +46 -0
- package/src/shared/components/docs/DocsSidebar.stories.tsx +31 -0
- package/src/shared/components/docs/DocsSidebar.tsx +77 -0
- package/src/shared/components/docs/DocsThemeProvider.tsx +21 -0
- package/src/shared/components/docs/Tabs.stories.tsx +26 -0
- package/src/shared/components/docs/Tabs.tsx +50 -0
- package/src/shared/components/docs/tokens.ts +38 -0
- package/src/shared/components/flow/FlowCanvas.tsx +151 -0
- package/src/shared/components/flow/StatusDot.tsx +36 -0
- package/src/shared/components/flow/edgeStyles.ts +32 -0
- package/src/shared/components/index.tsx +49 -0
- package/src/shared/components/layouts/AuthLayout.tsx +28 -0
- package/src/shared/components/layouts/DashboardLayout.tsx +131 -0
- package/src/shared/components/layouts/index.tsx +3 -0
- package/src/shared/components/lobeProviderIcons.ts +488 -0
- package/src/shared/components/logTableStyles.ts +7 -0
- package/src/shared/components/modelSelectModalHelpers.ts +75 -0
- package/src/shared/components/oauthBlobSubmit.ts +42 -0
- package/src/shared/components/proxyAssignment.ts +40 -0
- package/src/shared/components/requestLoggerPreferences.ts +44 -0
- package/src/shared/components/requestLoggerSignature.ts +56 -0
- package/src/shared/constants/agentSkills.ts +457 -0
- package/src/shared/constants/antigravityClientProfile.ts +29 -0
- package/src/shared/constants/apiKeyPolicyScopes.ts +5 -0
- package/src/shared/constants/appConfig.ts +12 -0
- package/src/shared/constants/batch.ts +1 -0
- package/src/shared/constants/batchEndpoints.ts +11 -0
- package/src/shared/constants/bodySize.ts +39 -0
- package/src/shared/constants/cliCompatProviders.ts +88 -0
- package/src/shared/constants/cliTools.ts +862 -0
- package/src/shared/constants/clientIdentityProfiles.ts +89 -0
- package/src/shared/constants/colors.ts +147 -0
- package/src/shared/constants/comboConfigMode.ts +9 -0
- package/src/shared/constants/config.ts +44 -0
- package/src/shared/constants/dashboardCsrf.ts +1 -0
- package/src/shared/constants/endpointCategories.ts +133 -0
- package/src/shared/constants/errorCodes.ts +245 -0
- package/src/shared/constants/featureFlagDefinitions.ts +495 -0
- package/src/shared/constants/headers.ts +16 -0
- package/src/shared/constants/homeWidgets.ts +5 -0
- package/src/shared/constants/index.ts +4 -0
- package/src/shared/constants/managementScopes.ts +31 -0
- package/src/shared/constants/mcpScopes.ts +78 -0
- package/src/shared/constants/mitmToolHosts.ts +31 -0
- package/src/shared/constants/modal.ts +5 -0
- package/src/shared/constants/modelCompat.ts +9 -0
- package/src/shared/constants/modelSpecs.ts +607 -0
- package/src/shared/constants/models.ts +40 -0
- package/src/shared/constants/openRouterPreset.ts +11 -0
- package/src/shared/constants/pricing/default-pricing.ts +16 -0
- package/src/shared/constants/pricing/frontier-labs.ts +386 -0
- package/src/shared/constants/pricing/inference-hosts.ts +208 -0
- package/src/shared/constants/pricing/oauth-subscriptions.ts +599 -0
- package/src/shared/constants/pricing/regional.ts +168 -0
- package/src/shared/constants/pricing/shared-tiers.ts +162 -0
- package/src/shared/constants/pricing.ts +40 -0
- package/src/shared/constants/providers/apikey/enterprise-cloud.ts +214 -0
- package/src/shared/constants/providers/apikey/frontier-labs.ts +253 -0
- package/src/shared/constants/providers/apikey/gateways.ts +662 -0
- package/src/shared/constants/providers/apikey/index.ts +21 -0
- package/src/shared/constants/providers/apikey/inference-hosts.ts +328 -0
- package/src/shared/constants/providers/apikey/regional.ts +372 -0
- package/src/shared/constants/providers/apikey/specialty-media.ts +266 -0
- package/src/shared/constants/providers/audio.ts +71 -0
- package/src/shared/constants/providers/cloud-agent.ts +36 -0
- package/src/shared/constants/providers/local.ts +162 -0
- package/src/shared/constants/providers/noauth.ts +123 -0
- package/src/shared/constants/providers/oauth.ts +231 -0
- package/src/shared/constants/providers/search.ts +125 -0
- package/src/shared/constants/providers/system.ts +16 -0
- package/src/shared/constants/providers/upstream-proxy.ts +36 -0
- package/src/shared/constants/providers/web-cookie.ts +364 -0
- package/src/shared/constants/providers.ts +449 -0
- package/src/shared/constants/publicApiRoutes.ts +62 -0
- package/src/shared/constants/responsesPreviousResponseId.ts +5 -0
- package/src/shared/constants/routingStrategies.ts +216 -0
- package/src/shared/constants/selfServiceScopes.ts +20 -0
- package/src/shared/constants/serviceKinds.ts +34 -0
- package/src/shared/constants/sidebarGroupVisibility.ts +31 -0
- package/src/shared/constants/sidebarVisibility/sections.ts +769 -0
- package/src/shared/constants/sidebarVisibility/types.ts +161 -0
- package/src/shared/constants/sidebarVisibility.ts +291 -0
- package/src/shared/constants/spawnCapablePrefixes.ts +35 -0
- package/src/shared/constants/statusColors.ts +17 -0
- package/src/shared/constants/upstreamHeaders.ts +42 -0
- package/src/shared/constants/visionBridgeDefaults.ts +88 -0
- package/src/shared/constants/visionModels.ts +68 -0
- package/src/shared/contracts/quota.ts +138 -0
- package/src/shared/hooks/cli/useToolBatchStatuses.ts +54 -0
- package/src/shared/hooks/index.ts +3 -0
- package/src/shared/hooks/useCopyToClipboard.ts +38 -0
- package/src/shared/hooks/useDisplayBaseUrl.ts +49 -0
- package/src/shared/hooks/useElectron.ts +197 -0
- package/src/shared/hooks/useTheme.ts +59 -0
- package/src/shared/http/apiErrorMessage.ts +19 -0
- package/src/shared/lib/persistLocale.ts +19 -0
- package/src/shared/middleware/bodySizeGuard.ts +97 -0
- package/src/shared/middleware/chatBodyAdmission.ts +161 -0
- package/src/shared/middleware/correlationId.ts +43 -0
- package/src/shared/network/outboundUrlGuard.ts +276 -0
- package/src/shared/network/remoteImageFetch.ts +182 -0
- package/src/shared/network/safeOutboundFetch.ts +372 -0
- package/src/shared/providers/webSessionCredentials.ts +308 -0
- package/src/shared/reasoning/effortStandardization.ts +124 -0
- package/src/shared/schemas/agentBridge.ts +37 -0
- package/src/shared/schemas/cliCatalog.ts +66 -0
- package/src/shared/schemas/inspector.ts +47 -0
- package/src/shared/schemas/memory.ts +142 -0
- package/src/shared/schemas/playground.ts +67 -0
- package/src/shared/schemas/qdrant.ts +39 -0
- package/src/shared/schemas/quota.ts +61 -0
- package/src/shared/schemas/searchTools.ts +39 -0
- package/src/shared/schemas/validation.ts +154 -0
- package/src/shared/services/apiKeyResolver.ts +44 -0
- package/src/shared/services/backupService.ts +233 -0
- package/src/shared/services/claudeCliConfig.ts +17 -0
- package/src/shared/services/cliRuntime.ts +1099 -0
- package/src/shared/services/cloudSyncScheduler.ts +135 -0
- package/src/shared/services/droidCustomModels.ts +118 -0
- package/src/shared/services/initializeCloudSync.ts +31 -0
- package/src/shared/services/loginShellPath.ts +87 -0
- package/src/shared/services/modelSyncScheduler.ts +225 -0
- package/src/shared/services/opencodeConfig.ts +140 -0
- package/src/shared/services/providerLimitsSyncScheduler.ts +72 -0
- package/src/shared/types/cliBatchStatus.ts +18 -0
- package/src/shared/types/index.ts +3 -0
- package/src/shared/types/pagination.ts +61 -0
- package/src/shared/types/utilization.ts +405 -0
- package/src/shared/utils/a11yAudit.ts +140 -0
- package/src/shared/utils/api.ts +112 -0
- package/src/shared/utils/apiAuth.ts +354 -0
- package/src/shared/utils/apiKey.ts +92 -0
- package/src/shared/utils/apiKeyPolicy.ts +680 -0
- package/src/shared/utils/apiResponse.ts +79 -0
- package/src/shared/utils/bulkApiKeyParser.ts +113 -0
- package/src/shared/utils/circuitBreaker.ts +611 -0
- package/src/shared/utils/classify429.ts +253 -0
- package/src/shared/utils/cliCompat.ts +5 -0
- package/src/shared/utils/clineAuth.ts +62 -0
- package/src/shared/utils/clipboard.ts +49 -0
- package/src/shared/utils/cloud.ts +41 -0
- package/src/shared/utils/cn.ts +12 -0
- package/src/shared/utils/codexBaseUrl.ts +32 -0
- package/src/shared/utils/codexConfig.ts +30 -0
- package/src/shared/utils/compressionHeaderEcho.ts +59 -0
- package/src/shared/utils/cors.ts +24 -0
- package/src/shared/utils/costEstimator.ts +126 -0
- package/src/shared/utils/dashboardCsrf.ts +196 -0
- package/src/shared/utils/featureFlags.ts +113 -0
- package/src/shared/utils/fetchError.ts +26 -0
- package/src/shared/utils/fetchTimeout.ts +78 -0
- package/src/shared/utils/formatting.ts +183 -0
- package/src/shared/utils/freeModels.ts +112 -0
- package/src/shared/utils/index.ts +39 -0
- package/src/shared/utils/inputSanitizer.ts +339 -0
- package/src/shared/utils/linkify.ts +54 -0
- package/src/shared/utils/logRedaction.ts +108 -0
- package/src/shared/utils/logger.ts +173 -0
- package/src/shared/utils/machine.ts +5 -0
- package/src/shared/utils/machineId.ts +167 -0
- package/src/shared/utils/maskEmail.ts +77 -0
- package/src/shared/utils/modelCatalogSearch.ts +84 -0
- package/src/shared/utils/noAuthProviders.ts +79 -0
- package/src/shared/utils/nodeRuntimeSupport.ts +112 -0
- package/src/shared/utils/parseApiKeys.ts +41 -0
- package/src/shared/utils/providerDisplayLabel.ts +41 -0
- package/src/shared/utils/providerHints.ts +73 -0
- package/src/shared/utils/providerModelAliases.ts +68 -0
- package/src/shared/utils/rateLimiter.ts +243 -0
- package/src/shared/utils/releaseNotes.ts +53 -0
- package/src/shared/utils/requestId.ts +102 -0
- package/src/shared/utils/requestTelemetry.ts +189 -0
- package/src/shared/utils/requestTimeout.ts +64 -0
- package/src/shared/utils/resolveOmniRouteBaseUrl.ts +24 -0
- package/src/shared/utils/runtimeTimeouts.ts +257 -0
- package/src/shared/utils/secretsValidator.ts +135 -0
- package/src/shared/utils/secureRandom.ts +66 -0
- package/src/shared/utils/serviceTierLabels.ts +42 -0
- package/src/shared/utils/shuffleDeck.ts +147 -0
- package/src/shared/utils/sidebarRouteMatch.ts +43 -0
- package/src/shared/utils/streamTracker.ts +187 -0
- package/src/shared/utils/structuredLogger.ts +219 -0
- package/src/shared/utils/tiktokenCounter.ts +21 -0
- package/src/shared/utils/turkishText.ts +66 -0
- package/src/shared/utils/upstreamError.ts +112 -0
- package/src/shared/validation/compressionConfigSchemas.ts +234 -0
- package/src/shared/validation/freeProxySchemas.ts +111 -0
- package/src/shared/validation/helpers.ts +117 -0
- package/src/shared/validation/oneproxySchemas.ts +14 -0
- package/src/shared/validation/providerSchema.ts +51 -0
- package/src/shared/validation/providerSpecificData.ts +354 -0
- package/src/shared/validation/schemas/apiV1.ts +297 -0
- package/src/shared/validation/schemas/auth.ts +200 -0
- package/src/shared/validation/schemas/cli.ts +86 -0
- package/src/shared/validation/schemas/cloud.ts +53 -0
- package/src/shared/validation/schemas/combo.ts +373 -0
- package/src/shared/validation/schemas/evals.ts +86 -0
- package/src/shared/validation/schemas/gemini.ts +59 -0
- package/src/shared/validation/schemas/keys.ts +144 -0
- package/src/shared/validation/schemas/misc.ts +203 -0
- package/src/shared/validation/schemas/payloadRules.ts +64 -0
- package/src/shared/validation/schemas/pricing.ts +40 -0
- package/src/shared/validation/schemas/provider.ts +430 -0
- package/src/shared/validation/schemas/proxy.ts +243 -0
- package/src/shared/validation/schemas/routing.ts +88 -0
- package/src/shared/validation/schemas/settings.ts +267 -0
- package/src/shared/validation/schemas/translator.ts +44 -0
- package/src/shared/validation/schemas.ts +18 -0
- package/src/shared/validation/settingsSchemas.ts +396 -0
- package/src/sse/handlers/chat.ts +1750 -0
- package/src/sse/handlers/chatHelpers.ts +859 -0
- package/src/sse/handlers/requestBody.ts +24 -0
- package/src/sse/handlers/resolveRoutingModel.ts +17 -0
- package/src/sse/services/auth.ts +2446 -0
- package/src/sse/services/cooldownAwareRetry.ts +162 -0
- package/src/sse/services/model.ts +254 -0
- package/src/sse/services/noAuthProviderSettings.ts +18 -0
- package/src/sse/services/noAuthProxyResolution.ts +111 -0
- package/src/sse/services/sessionAffinityPin.ts +247 -0
- package/src/sse/services/streamState.ts +218 -0
- package/src/sse/services/tokenRefresh.ts +275 -0
- package/src/sse/utils/logger.ts +37 -0
- package/src/types/databaseSettings.ts +124 -0
- package/src/types/global.d.ts +122 -0
- package/src/types/index.ts +10 -0
- package/src/types/provider.ts +9 -0
- package/src/types/sqljs.d.ts +32 -0
|
@@ -0,0 +1,1863 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BACKOFF_STEPS_MS,
|
|
3
|
+
PROVIDER_PROFILES,
|
|
4
|
+
RateLimitReason,
|
|
5
|
+
HTTP_STATUS,
|
|
6
|
+
} from "../config/constants.ts";
|
|
7
|
+
import {
|
|
8
|
+
BACKOFF_CONFIG,
|
|
9
|
+
COOLDOWN_MS,
|
|
10
|
+
calculateBackoffCooldown,
|
|
11
|
+
findMatchingErrorRule,
|
|
12
|
+
matchErrorRuleByText,
|
|
13
|
+
matchErrorRuleByStatus,
|
|
14
|
+
} from "../config/errorConfig.ts";
|
|
15
|
+
import { getProviderErrorRuleMatch } from "../config/providerErrorRules.ts";
|
|
16
|
+
import { getPassthroughProviders, getProviderCategory } from "../config/providerRegistry.ts";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_RESILIENCE_SETTINGS,
|
|
19
|
+
resolveResilienceSettings,
|
|
20
|
+
} from "../../src/lib/resilience/settings";
|
|
21
|
+
import { resolveModelLockoutSettings } from "../../src/lib/resilience/modelLockoutSettings";
|
|
22
|
+
import {
|
|
23
|
+
getAllCircuitBreakerStatuses,
|
|
24
|
+
getCircuitBreaker,
|
|
25
|
+
} from "../../src/shared/utils/circuitBreaker";
|
|
26
|
+
import {
|
|
27
|
+
classify429FromError,
|
|
28
|
+
looksLikeQuotaExhausted,
|
|
29
|
+
type FailureKind,
|
|
30
|
+
} from "../../src/shared/utils/classify429";
|
|
31
|
+
import { resolveProviderId } from "../../src/shared/constants/providers";
|
|
32
|
+
import { resolveUseUpstream429BreakerHints } from "../../src/shared/utils/providerHints";
|
|
33
|
+
import { getCodexModelScope } from "../config/codexQuotaScopes.ts";
|
|
34
|
+
import { getQuotaScopedModelForProvider } from "./antigravityQuotaFamily.ts";
|
|
35
|
+
import { isRpdExhausted, isRpmExhausted } from "./geminiRateLimitTracker.ts";
|
|
36
|
+
import { setConnectionRateLimitUntil } from "@/lib/db/providers";
|
|
37
|
+
import { parseRetryHintFromJsonBody } from "./retryAfterJson.ts";
|
|
38
|
+
|
|
39
|
+
export type ProviderProfile = {
|
|
40
|
+
baseCooldownMs: number;
|
|
41
|
+
useUpstreamRetryHints: boolean;
|
|
42
|
+
useUpstream429BreakerHints?: boolean;
|
|
43
|
+
maxCooldownMs: number;
|
|
44
|
+
maxBackoffSteps: number;
|
|
45
|
+
failureThreshold: number;
|
|
46
|
+
resetTimeoutMs: number;
|
|
47
|
+
transientCooldown: number;
|
|
48
|
+
rateLimitCooldown: number;
|
|
49
|
+
maxBackoffLevel: number;
|
|
50
|
+
circuitBreakerThreshold: number;
|
|
51
|
+
circuitBreakerReset: number;
|
|
52
|
+
// Adaptive circuit breaker fields
|
|
53
|
+
degradationThreshold?: number;
|
|
54
|
+
// Provider-level cooldown fields
|
|
55
|
+
providerFailureThreshold: number;
|
|
56
|
+
providerFailureWindowMs: number;
|
|
57
|
+
providerCooldownMs: number;
|
|
58
|
+
maxBackoffMultiplier?: number;
|
|
59
|
+
backoffEscalationCount?: number;
|
|
60
|
+
};
|
|
61
|
+
type JsonRecord = Record<string, unknown>;
|
|
62
|
+
type RateLimitReasonValue = (typeof RateLimitReason)[keyof typeof RateLimitReason];
|
|
63
|
+
type ModelLockoutEntry = {
|
|
64
|
+
reason: string;
|
|
65
|
+
until: number;
|
|
66
|
+
lockedAt: number;
|
|
67
|
+
failureCount: number;
|
|
68
|
+
lastFailureAt: number;
|
|
69
|
+
resetAfterMs: number;
|
|
70
|
+
};
|
|
71
|
+
type ModelFailureState = {
|
|
72
|
+
failureCount: number;
|
|
73
|
+
lastFailureAt: number;
|
|
74
|
+
resetAfterMs: number;
|
|
75
|
+
/** Cooldown applied on the last failure — extends the escalation window so a
|
|
76
|
+
* model that fails again right after its lockout expires keeps escalating. */
|
|
77
|
+
lastCooldownMs?: number;
|
|
78
|
+
};
|
|
79
|
+
type AccountState = JsonRecord & {
|
|
80
|
+
id?: string | null;
|
|
81
|
+
rateLimitedUntil?: string | null;
|
|
82
|
+
backoffLevel?: number | null;
|
|
83
|
+
lastError?: unknown;
|
|
84
|
+
status?: string;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function toJsonRecord(value: unknown): JsonRecord {
|
|
88
|
+
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Provider-level failure tracking for circuit breaker behavior
|
|
92
|
+
// Error codes that count toward provider-level failure threshold.
|
|
93
|
+
// 429 is included: per-error-type cooldowns (rate_limit: 60s, quota_exhausted: 1h)
|
|
94
|
+
// prevent cascading provider trips at scale (Issue #1846 concern addressed),
|
|
95
|
+
// while still allowing the circuit breaker to open on sustained 429s and
|
|
96
|
+
// prevent infinite combo retries (Issue #3200).
|
|
97
|
+
const PROVIDER_FAILURE_ERROR_CODES = new Set([408, 429, 500, 502, 503, 504]);
|
|
98
|
+
|
|
99
|
+
// Per-connection failure deduplication: prevents rapid-fire failures from the
|
|
100
|
+
// same connection from counting multiple times toward the provider breaker.
|
|
101
|
+
const CONNECTION_FAILURE_DEDUP_MS = 5000;
|
|
102
|
+
const MAX_CONNECTION_FAILURE_DEDUP_ENTRIES = 10_000;
|
|
103
|
+
const lastConnectionFailure = new Map<string, number>();
|
|
104
|
+
|
|
105
|
+
function pruneConnectionFailureDedupeEntries(): void {
|
|
106
|
+
while (lastConnectionFailure.size > MAX_CONNECTION_FAILURE_DEDUP_ENTRIES) {
|
|
107
|
+
const oldestKey = lastConnectionFailure.keys().next().value;
|
|
108
|
+
if (typeof oldestKey !== "string") return;
|
|
109
|
+
lastConnectionFailure.delete(oldestKey);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const _connectionFailureSweep = setInterval(() => {
|
|
114
|
+
const now = Date.now();
|
|
115
|
+
for (const [key, ts] of lastConnectionFailure) {
|
|
116
|
+
if (now - ts > CONNECTION_FAILURE_DEDUP_MS) lastConnectionFailure.delete(key);
|
|
117
|
+
}
|
|
118
|
+
}, 60_000);
|
|
119
|
+
if (typeof _connectionFailureSweep === "object" && "unref" in _connectionFailureSweep) {
|
|
120
|
+
(_connectionFailureSweep as { unref?: () => void }).unref?.();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// T06 (sub2api PR #1037): Signals that indicate permanent account deactivation.
|
|
124
|
+
// When a 401 body contains these strings, the account is permanently dead
|
|
125
|
+
// and should NOT be retried after token refresh.
|
|
126
|
+
export const ACCOUNT_DEACTIVATED_SIGNALS = [
|
|
127
|
+
"account_deactivated",
|
|
128
|
+
"account has been deactivated",
|
|
129
|
+
"account has been disabled",
|
|
130
|
+
"your account has been suspended",
|
|
131
|
+
"this account is deactivated",
|
|
132
|
+
// AG (Antigravity/Google Cloud Code) permanent ban signals
|
|
133
|
+
"verify your account to continue",
|
|
134
|
+
"this service has been disabled in this account for violation",
|
|
135
|
+
"this service has been disabled in this account",
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
// Custom banned signals — loaded from DB settings at runtime.
|
|
139
|
+
// Combined with ACCOUNT_DEACTIVATED_SIGNALS in isAccountDeactivated().
|
|
140
|
+
let _customBannedSignals: string[] = [];
|
|
141
|
+
|
|
142
|
+
export function setCustomBannedSignals(signals: string[]): void {
|
|
143
|
+
_customBannedSignals = signals;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function getMergedBannedSignals(): string[] {
|
|
147
|
+
if (_customBannedSignals.length === 0) return ACCOUNT_DEACTIVATED_SIGNALS;
|
|
148
|
+
return [...ACCOUNT_DEACTIVATED_SIGNALS, ..._customBannedSignals];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// T10 (sub2api PR #1169): Signals that indicate billing credits are exhausted.
|
|
152
|
+
// Distinct from rate-limit 429 — the account won't recover until credits are added.
|
|
153
|
+
export const CREDITS_EXHAUSTED_SIGNALS = [
|
|
154
|
+
"insufficient_quota",
|
|
155
|
+
"billing_hard_limit_reached",
|
|
156
|
+
"exceeded your current quota",
|
|
157
|
+
"exceeded your current usage quota",
|
|
158
|
+
"credit_balance_too_low",
|
|
159
|
+
"your credit balance is too low",
|
|
160
|
+
"credits exhausted",
|
|
161
|
+
"out of credits",
|
|
162
|
+
"payment required",
|
|
163
|
+
"free tier of the model has been exhausted",
|
|
164
|
+
// #5239: providers (e.g. DeepSeek/GLM-style) return "Insufficient account balance"
|
|
165
|
+
// on a depleted key. 402 is already terminalized by status, but catch non-402
|
|
166
|
+
// out-of-credit bodies here too.
|
|
167
|
+
"insufficient balance",
|
|
168
|
+
"insufficient_balance",
|
|
169
|
+
"insufficient account balance",
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
// T11: Signals that indicate OAuth token is invalid/expired (not permanent deactivation)
|
|
173
|
+
export const OAUTH_INVALID_TOKEN_SIGNALS = [
|
|
174
|
+
"invalid authentication credentials",
|
|
175
|
+
"oauth 2",
|
|
176
|
+
"login cookie",
|
|
177
|
+
"valid authentication credential",
|
|
178
|
+
"invalid credentials",
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
// Context overflow patterns — the prompt exceeds the model's maximum context length.
|
|
182
|
+
// Different providers phrase this differently. Used to decide whether a 400 error
|
|
183
|
+
// should trigger combo fallback (a different model may have a larger context window).
|
|
184
|
+
const CONTEXT_OVERFLOW_PATTERNS = [
|
|
185
|
+
/\binput is too long\b/i,
|
|
186
|
+
/\binput too long\b/i,
|
|
187
|
+
/\bcontext.*(too long|exceeded|overflow|limit)/i,
|
|
188
|
+
/\btoo many tokens\b/i,
|
|
189
|
+
/\bprompt is too long\b/i,
|
|
190
|
+
/\bcontext window/i,
|
|
191
|
+
/\bmaximum context/i,
|
|
192
|
+
/\bmax.*token/i,
|
|
193
|
+
/\btoken limit/i,
|
|
194
|
+
/\brequest too large\b/i,
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
// Structured error codes that reliably indicate model access denied
|
|
198
|
+
// (more reliable than regex on human-readable messages).
|
|
199
|
+
// OpenAI: { error: { code: "model_not_found", ... } }
|
|
200
|
+
// Anthropic: { error: { type: "not_found_error", ... } }
|
|
201
|
+
const MODEL_ACCESS_DENIED_CODES = new Set([
|
|
202
|
+
"model_not_found", // OpenAI, OpenAI-compatible (Kiro, Together, Fireworks, etc.)
|
|
203
|
+
"deployment_not_found", // Azure OpenAI
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
const MODEL_ACCESS_DENIED_TYPES = new Set([
|
|
207
|
+
"not_found_error", // Anthropic: model doesn't exist — reliably model-scoped
|
|
208
|
+
]);
|
|
209
|
+
|
|
210
|
+
// Anthropic's permission_error is NOT exclusively model-access related: it also
|
|
211
|
+
// covers API-key scope, organization restrictions and feature gating. Treating it
|
|
212
|
+
// as model-access-denied unconditionally would make a genuinely auth-restricted key
|
|
213
|
+
// silently exhaust every combo target and hide the real error from the caller.
|
|
214
|
+
// So it only counts when the message text confirms it refers to the model.
|
|
215
|
+
const MODEL_ACCESS_AMBIGUOUS_TYPES = new Set([
|
|
216
|
+
"permission_error", // Anthropic: could be model access OR key/org/feature scope
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
// Model access patterns — the account does not have access to the requested model
|
|
220
|
+
// but a different account (e.g. PRO vs free tier) may support it.
|
|
221
|
+
const MODEL_ACCESS_DENIED_PATTERNS = [
|
|
222
|
+
/\binvalid model\b/i,
|
|
223
|
+
/\bmodel.*not.*(?:available|found|supported|accessible)\b/i,
|
|
224
|
+
/\bmodel.*(?:does not exist|doesn't exist)\b/i,
|
|
225
|
+
/\baccess.*denied.*model\b/i,
|
|
226
|
+
/\bmodel.*access.*denied\b/i,
|
|
227
|
+
/\bplease select a different model\b/i,
|
|
228
|
+
// "...access to the requested model" / "model ... access" — bounded lookahead
|
|
229
|
+
// (no nested quantifiers) so it stays ReDoS-safe while requiring BOTH an
|
|
230
|
+
// access/permission word and "model" so a pure auth error never matches.
|
|
231
|
+
/\b(?:access|permission)[\s\S]{0,60}?\bmodel\b/i,
|
|
232
|
+
/\bmodel[\s\S]{0,60}?\b(?:access|permission)\b/i,
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
// Pure credential/authentication failures — the key or token itself is bad, which
|
|
236
|
+
// is NOT a model-availability problem. Some providers phrase these as a 400 that
|
|
237
|
+
// also mentions the model (e.g. "invalid api key for model X"), which would
|
|
238
|
+
// otherwise trip MODEL_ACCESS_DENIED_PATTERNS above and trigger combo fallback
|
|
239
|
+
// across every target, masking the real "fix your credential" error. When the
|
|
240
|
+
// text clearly indicates a bad credential, the regex-based model-access detection
|
|
241
|
+
// is suppressed (structured codes/types like model_not_found are unaffected).
|
|
242
|
+
const AUTH_CREDENTIAL_ERROR_PATTERNS = [
|
|
243
|
+
/\b(?:invalid|incorrect|expired|missing|revoked)\s+api[\s_-]?key\b/i,
|
|
244
|
+
/\bapi[\s_-]?key\s+(?:is\s+)?(?:invalid|incorrect|expired|missing|revoked|not\s+valid)\b/i,
|
|
245
|
+
/\bauthentication\s+(?:failed|error|required)\b/i,
|
|
246
|
+
/\b(?:invalid|expired|missing|revoked)\s+(?:token|credentials?|bearer)\b/i,
|
|
247
|
+
/\bunauthorized\b/i,
|
|
248
|
+
/\bnot\s+authenticated\b/i,
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
// Malformed request patterns — the model rejected the message format but a different
|
|
252
|
+
// provider/model in the combo may accept it.
|
|
253
|
+
const MALFORMED_REQUEST_PATTERNS = [
|
|
254
|
+
/\bimproperly formed request\b/i,
|
|
255
|
+
/\binvalid.*message.*format/i,
|
|
256
|
+
/\bmessages must alternate\b/i,
|
|
257
|
+
/\bempty (message|content)\b/i,
|
|
258
|
+
// Tool call function name errors
|
|
259
|
+
/\bfunction'?s? name (?:can't|can not|is|has) (?:blank|empty|missing)/i,
|
|
260
|
+
/function.*name.*(?:blank|empty|missing)/i,
|
|
261
|
+
/tool_call.*name.*(?:blank|empty|missing)/i,
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
// Rate-limit text on a 400 — some providers (e.g. MiMoCode) signal throttling with a
|
|
265
|
+
// non-standard 400 status whose body carries rate-limit semantics instead of a 429
|
|
266
|
+
// (#4976). When detected, the request is fallback-worthy at connection-cooldown scope
|
|
267
|
+
// (NOT a whole-provider breaker) so combo routing can fail over to another free target.
|
|
268
|
+
// Bounded, non-overlapping patterns only (ReDoS-safe — no nested quantifiers).
|
|
269
|
+
const RATE_LIMIT_TEXT_PATTERNS = [
|
|
270
|
+
/high.?frequency/i,
|
|
271
|
+
/non-compliant/i,
|
|
272
|
+
/too many requests/i,
|
|
273
|
+
/rate.?limit/i,
|
|
274
|
+
/频繁/, // "frequent" (zh) — high-frequency request throttling
|
|
275
|
+
/频率/, // "frequency" (zh) — request-frequency throttling
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
// Parameter validation errors — model-specific constraints (different models = different limits)
|
|
279
|
+
const PARAM_VALIDATION_PATTERNS = [
|
|
280
|
+
/max_tokens.*illegal/i,
|
|
281
|
+
/max_tokens.*must be/i,
|
|
282
|
+
/max_tokens.*range/i,
|
|
283
|
+
/parameter is illegal/i,
|
|
284
|
+
/is illegal.*range/i,
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* T06: Returns true if response body indicates the account is permanently deactivated.
|
|
289
|
+
*/
|
|
290
|
+
export function isAccountDeactivated(errorText: string): boolean {
|
|
291
|
+
const lower = String(errorText || "").toLowerCase();
|
|
292
|
+
return getMergedBannedSignals().some((sig) => lower.includes(sig));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* T10: Returns true if response body indicates credits/quota are permanently exhausted.
|
|
297
|
+
*/
|
|
298
|
+
export function isCreditsExhausted(errorText: string): boolean {
|
|
299
|
+
const lower = String(errorText || "").toLowerCase();
|
|
300
|
+
return CREDITS_EXHAUSTED_SIGNALS.some((sig) => lower.includes(sig));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* T11: Returns true if response body indicates OAuth token is invalid/expired.
|
|
305
|
+
* This is different from permanent account deactivation - token refresh can recover.
|
|
306
|
+
*/
|
|
307
|
+
export function isOAuthInvalidToken(errorText: string): boolean {
|
|
308
|
+
const lower = String(errorText || "").toLowerCase();
|
|
309
|
+
return OAUTH_INVALID_TOKEN_SIGNALS.some((sig) => lower.includes(sig));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ─── Resilience Profile Helper ──────────────────────────────────────────────
|
|
313
|
+
|
|
314
|
+
function asRecord(value: unknown): JsonRecord {
|
|
315
|
+
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function isCompatibleProvider(provider: string | null | undefined): boolean {
|
|
319
|
+
return (
|
|
320
|
+
typeof provider === "string" &&
|
|
321
|
+
(provider.startsWith("openai-compatible-") || provider.startsWith("anthropic-compatible-"))
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function buildProviderProfile(
|
|
326
|
+
category: "oauth" | "apikey",
|
|
327
|
+
settings?: Record<string, unknown> | null
|
|
328
|
+
) {
|
|
329
|
+
const resilience = settings ? resolveResilienceSettings(settings) : DEFAULT_RESILIENCE_SETTINGS;
|
|
330
|
+
const connectionCooldown = resilience.connectionCooldown[category];
|
|
331
|
+
const providerBreaker = resilience.providerBreaker[category];
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
baseCooldownMs: connectionCooldown.baseCooldownMs,
|
|
335
|
+
useUpstreamRetryHints: connectionCooldown.useUpstreamRetryHints,
|
|
336
|
+
useUpstream429BreakerHints: connectionCooldown.useUpstream429BreakerHints,
|
|
337
|
+
maxCooldownMs: resolveModelLockoutSettings(settings).maxCooldownMs,
|
|
338
|
+
maxBackoffSteps: connectionCooldown.maxBackoffSteps,
|
|
339
|
+
failureThreshold: providerBreaker.failureThreshold,
|
|
340
|
+
resetTimeoutMs: providerBreaker.resetTimeoutMs,
|
|
341
|
+
transientCooldown: connectionCooldown.baseCooldownMs,
|
|
342
|
+
rateLimitCooldown: connectionCooldown.useUpstreamRetryHints
|
|
343
|
+
? 0
|
|
344
|
+
: connectionCooldown.baseCooldownMs,
|
|
345
|
+
maxBackoffLevel: connectionCooldown.maxBackoffSteps,
|
|
346
|
+
circuitBreakerThreshold: providerBreaker.failureThreshold,
|
|
347
|
+
circuitBreakerReset: providerBreaker.resetTimeoutMs,
|
|
348
|
+
degradationThreshold: providerBreaker.degradationThreshold,
|
|
349
|
+
// Provider-level cooldown fields are not exposed in resilience settings yet.
|
|
350
|
+
providerFailureThreshold: PROVIDER_PROFILES[category].providerFailureThreshold,
|
|
351
|
+
providerFailureWindowMs: PROVIDER_PROFILES[category].providerFailureWindowMs,
|
|
352
|
+
maxBackoffMultiplier: PROVIDER_PROFILES[category].maxBackoffMultiplier,
|
|
353
|
+
backoffEscalationCount: PROVIDER_PROFILES[category].backoffEscalationCount,
|
|
354
|
+
providerCooldownMs: PROVIDER_PROFILES[category].providerCooldownMs,
|
|
355
|
+
} satisfies ProviderProfile;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Get the resilience profile for a provider (oauth or apikey).
|
|
360
|
+
* @param {string} provider - Provider ID or alias
|
|
361
|
+
*/
|
|
362
|
+
export function getProviderProfile(provider: string): ProviderProfile {
|
|
363
|
+
const category = getProviderCategory(provider);
|
|
364
|
+
return buildProviderProfile(category);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function shouldPreserveQuotaSignalsFor429(provider: string | null | undefined): boolean {
|
|
368
|
+
if (!provider) return true;
|
|
369
|
+
return getProviderCategory(provider) === "oauth";
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export async function getRuntimeProviderProfile(provider: string | null | undefined) {
|
|
373
|
+
try {
|
|
374
|
+
const { getCachedSettings } = await import("@/lib/db/readCache");
|
|
375
|
+
const settings = await getCachedSettings();
|
|
376
|
+
const category = getProviderCategory(provider || "");
|
|
377
|
+
return buildProviderProfile(category, settings);
|
|
378
|
+
} catch {
|
|
379
|
+
return getProviderProfile(provider || "");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ─── Per-Model Lockout Tracking ─────────────────────────────────────────────
|
|
384
|
+
// In-memory map: "provider:connectionId:model" → { reason, until, lockedAt }
|
|
385
|
+
const modelLockouts = new Map<string, ModelLockoutEntry>();
|
|
386
|
+
const modelFailureState = new Map<string, ModelFailureState>();
|
|
387
|
+
|
|
388
|
+
// Aliases (e.g. "cx" → "codex") must share lockout state with their canonical
|
|
389
|
+
// provider, otherwise a model locked via one spelling stays routable via the other.
|
|
390
|
+
const canonicalProviderCache = new Map<string, string>();
|
|
391
|
+
function getCanonicalLockProvider(provider: string): string {
|
|
392
|
+
let canonical = canonicalProviderCache.get(provider);
|
|
393
|
+
if (!canonical) {
|
|
394
|
+
canonical = resolveProviderId(provider);
|
|
395
|
+
canonicalProviderCache.set(provider, canonical);
|
|
396
|
+
}
|
|
397
|
+
return canonical;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function getModelLockKey(provider: string, connectionId: string, model: string) {
|
|
401
|
+
const canonicalProvider = getCanonicalLockProvider(provider);
|
|
402
|
+
const lockModel =
|
|
403
|
+
canonicalProvider === "codex"
|
|
404
|
+
? getCodexModelScope(model)
|
|
405
|
+
: getQuotaScopedModelForProvider(canonicalProvider, model) || model;
|
|
406
|
+
return `${canonicalProvider}:${connectionId}:${lockModel}`;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function getFailureWindowMs(profile: ProviderProfile | null = null, fallbackMs = 30 * 60 * 1000) {
|
|
410
|
+
const configured = profile?.resetTimeoutMs;
|
|
411
|
+
return typeof configured === "number" && configured > 0 ? configured : fallbackMs;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function cleanupModelLockKey(key: string, now = Date.now()) {
|
|
415
|
+
const entry = modelLockouts.get(key);
|
|
416
|
+
if (entry && now > entry.until) {
|
|
417
|
+
modelLockouts.delete(key);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const failure = modelFailureState.get(key);
|
|
421
|
+
if (!failure) return;
|
|
422
|
+
// The escalation window extends past the applied cooldown: a model that fails
|
|
423
|
+
// again right after its lockout expires must keep escalating, not reset to 1.
|
|
424
|
+
if (now - failure.lastFailureAt <= failure.resetAfterMs + (failure.lastCooldownMs ?? 0)) return;
|
|
425
|
+
if (modelLockouts.has(key)) return;
|
|
426
|
+
modelFailureState.delete(key);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function getModelLockBaseCooldown(
|
|
430
|
+
status: number,
|
|
431
|
+
fallbackCooldownMs: number,
|
|
432
|
+
profile: ProviderProfile | null = null
|
|
433
|
+
) {
|
|
434
|
+
if (Number.isFinite(fallbackCooldownMs) && fallbackCooldownMs > 0) {
|
|
435
|
+
return fallbackCooldownMs;
|
|
436
|
+
}
|
|
437
|
+
if (typeof profile?.baseCooldownMs === "number" && profile.baseCooldownMs >= 0) {
|
|
438
|
+
return profile.baseCooldownMs;
|
|
439
|
+
}
|
|
440
|
+
return status === HTTP_STATUS.RATE_LIMITED ? getQuotaCooldown(0) : COOLDOWN_MS.transientInitial;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function getScaledCooldown(
|
|
444
|
+
baseCooldownMs: number,
|
|
445
|
+
failureCount: number,
|
|
446
|
+
maxBackoffLevel = BACKOFF_CONFIG.maxLevel
|
|
447
|
+
) {
|
|
448
|
+
const safeBase = Number.isFinite(baseCooldownMs) && baseCooldownMs > 0 ? baseCooldownMs : 1000;
|
|
449
|
+
const exponent = Math.min(Math.max(0, failureCount - 1), Math.max(0, maxBackoffLevel));
|
|
450
|
+
return safeBase * Math.pow(2, exponent);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Auto-cleanup expired lockouts every 15 seconds (lazy init for Cloudflare Workers compatibility)
|
|
454
|
+
let _cleanupTimer: ReturnType<typeof setInterval> | null = null;
|
|
455
|
+
|
|
456
|
+
function ensureCleanupTimer() {
|
|
457
|
+
if (_cleanupTimer) return;
|
|
458
|
+
try {
|
|
459
|
+
_cleanupTimer = setInterval(() => {
|
|
460
|
+
const now = Date.now();
|
|
461
|
+
for (const key of modelLockouts.keys()) cleanupModelLockKey(key, now);
|
|
462
|
+
for (const key of modelFailureState.keys()) cleanupModelLockKey(key, now);
|
|
463
|
+
}, 15_000);
|
|
464
|
+
if (typeof _cleanupTimer === "object" && "unref" in _cleanupTimer) {
|
|
465
|
+
(_cleanupTimer as { unref?: () => void }).unref?.(); // Don't prevent process exit (Node.js only)
|
|
466
|
+
}
|
|
467
|
+
} catch {
|
|
468
|
+
// Cloudflare Workers may not support setInterval outside handlers — skip cleanup timer
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Lock a specific model on a specific account
|
|
474
|
+
* @param {string} provider
|
|
475
|
+
* @param {string} connectionId
|
|
476
|
+
* @param {string} model
|
|
477
|
+
* @param {string} reason - from RateLimitReason
|
|
478
|
+
* @param {number} cooldownMs
|
|
479
|
+
*/
|
|
480
|
+
export function lockModel(
|
|
481
|
+
provider: string,
|
|
482
|
+
connectionId: string,
|
|
483
|
+
model: string | null | undefined,
|
|
484
|
+
reason: string,
|
|
485
|
+
cooldownMs: number,
|
|
486
|
+
metadata: Partial<ModelLockoutEntry> = {}
|
|
487
|
+
): void {
|
|
488
|
+
if (!model) return; // No model → skip model-level locking
|
|
489
|
+
ensureCleanupTimer();
|
|
490
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
491
|
+
cleanupModelLockKey(key);
|
|
492
|
+
const newUntil = Date.now() + cooldownMs;
|
|
493
|
+
// Preserve the longer cooldown if an existing lock has more time remaining.
|
|
494
|
+
// Safe without a mutex: no await between get/set, so this runs atomically
|
|
495
|
+
// within Node.js's single-threaded event loop.
|
|
496
|
+
const existing = modelLockouts.get(key);
|
|
497
|
+
if (existing && existing.until > newUntil) {
|
|
498
|
+
if (metadata.failureCount && metadata.failureCount > existing.failureCount) {
|
|
499
|
+
existing.failureCount = metadata.failureCount;
|
|
500
|
+
existing.lastFailureAt = metadata.lastFailureAt ?? existing.lastFailureAt;
|
|
501
|
+
existing.resetAfterMs = metadata.resetAfterMs ?? existing.resetAfterMs;
|
|
502
|
+
modelLockouts.set(key, existing);
|
|
503
|
+
}
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const now = Date.now();
|
|
507
|
+
modelLockouts.set(key, {
|
|
508
|
+
reason,
|
|
509
|
+
until: newUntil,
|
|
510
|
+
lockedAt: now,
|
|
511
|
+
failureCount: metadata.failureCount ?? existing?.failureCount ?? 1,
|
|
512
|
+
lastFailureAt: metadata.lastFailureAt ?? now,
|
|
513
|
+
resetAfterMs: metadata.resetAfterMs ?? existing?.resetAfterMs ?? 0,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Pick the `exactCooldownMs` to apply to a model lockout (#1308).
|
|
519
|
+
*
|
|
520
|
+
* When the upstream response carried an explicit reset longer than the base
|
|
521
|
+
* cooldown — e.g. Antigravity "Resets in 160h", a `Retry-After` header, or a
|
|
522
|
+
* parseable reset text already extracted by `checkFallbackError`/`parseRetryFromErrorText`
|
|
523
|
+
* into `parsedCooldownMs` — honor it exactly so an exhausted model is not retried
|
|
524
|
+
* again within minutes. Otherwise preserve the previous behavior: return `0` to let
|
|
525
|
+
* `recordModelLockoutFailure` apply its exponential backoff, or the base cooldown when
|
|
526
|
+
* backoff is disabled.
|
|
527
|
+
*/
|
|
528
|
+
export function selectLockoutCooldownMs(
|
|
529
|
+
parsedCooldownMs: number,
|
|
530
|
+
settings: { baseCooldownMs: number; useExponentialBackoff: boolean }
|
|
531
|
+
): number {
|
|
532
|
+
if (typeof parsedCooldownMs === "number" && parsedCooldownMs > settings.baseCooldownMs) {
|
|
533
|
+
return parsedCooldownMs;
|
|
534
|
+
}
|
|
535
|
+
return settings.useExponentialBackoff ? 0 : settings.baseCooldownMs;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
export function recordModelLockoutFailure(
|
|
539
|
+
provider: string,
|
|
540
|
+
connectionId: string,
|
|
541
|
+
model: string,
|
|
542
|
+
reason: string,
|
|
543
|
+
status: number,
|
|
544
|
+
fallbackCooldownMs: number,
|
|
545
|
+
profile: ProviderProfile | null = null,
|
|
546
|
+
options: { exactCooldownMs?: number | null; maxCooldownMs?: number } = {}
|
|
547
|
+
) {
|
|
548
|
+
ensureCleanupTimer();
|
|
549
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
550
|
+
const now = Date.now();
|
|
551
|
+
cleanupModelLockKey(key, now);
|
|
552
|
+
|
|
553
|
+
// For daily quota exhaustion (quota_exhausted), set cooldown until tomorrow 00:00
|
|
554
|
+
// Use exactCooldownMs to bypass exponential backoff, ensuring precise lock until midnight
|
|
555
|
+
if (reason === "quota_exhausted" && typeof options.exactCooldownMs !== "number") {
|
|
556
|
+
options = { ...options, exactCooldownMs: getMsUntilTomorrow() };
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const resetAfterMs = getFailureWindowMs(profile);
|
|
560
|
+
const previous = modelFailureState.get(key);
|
|
561
|
+
// Escalation window extends past the previously applied cooldown so a model
|
|
562
|
+
// that fails again right after its lockout expires keeps escalating.
|
|
563
|
+
const withinWindow =
|
|
564
|
+
previous &&
|
|
565
|
+
now - previous.lastFailureAt <= previous.resetAfterMs + (previous.lastCooldownMs ?? 0);
|
|
566
|
+
const failureCount = withinWindow ? previous.failureCount + 1 : 1;
|
|
567
|
+
|
|
568
|
+
const baseCooldownMs = getModelLockBaseCooldown(status, fallbackCooldownMs, profile);
|
|
569
|
+
// Cap exponential backoff so repeated failures cannot produce absurdly long
|
|
570
|
+
// lockouts; exact cooldowns (e.g. daily-quota until-midnight) are not capped.
|
|
571
|
+
const maxCooldownMs =
|
|
572
|
+
typeof options.maxCooldownMs === "number" && options.maxCooldownMs > 0
|
|
573
|
+
? options.maxCooldownMs
|
|
574
|
+
: BACKOFF_CONFIG.max;
|
|
575
|
+
const cooldownMs =
|
|
576
|
+
typeof options.exactCooldownMs === "number" && options.exactCooldownMs > 0
|
|
577
|
+
? options.exactCooldownMs
|
|
578
|
+
: Math.min(
|
|
579
|
+
getScaledCooldown(
|
|
580
|
+
baseCooldownMs,
|
|
581
|
+
failureCount,
|
|
582
|
+
profile?.maxBackoffSteps ?? BACKOFF_CONFIG.maxLevel
|
|
583
|
+
),
|
|
584
|
+
maxCooldownMs
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
modelFailureState.set(key, {
|
|
588
|
+
failureCount,
|
|
589
|
+
lastFailureAt: now,
|
|
590
|
+
resetAfterMs,
|
|
591
|
+
lastCooldownMs: cooldownMs,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
lockModel(provider, connectionId, model, reason, cooldownMs, {
|
|
595
|
+
failureCount,
|
|
596
|
+
lastFailureAt: now,
|
|
597
|
+
resetAfterMs,
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
return {
|
|
601
|
+
cooldownMs,
|
|
602
|
+
failureCount,
|
|
603
|
+
resetAfterMs,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
export function clearModelLock(
|
|
608
|
+
provider: string,
|
|
609
|
+
connectionId: string,
|
|
610
|
+
model: string | null | undefined
|
|
611
|
+
): boolean {
|
|
612
|
+
if (!model) return false;
|
|
613
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
614
|
+
const hadLock = modelLockouts.delete(key);
|
|
615
|
+
const hadFailureState = modelFailureState.delete(key);
|
|
616
|
+
return hadLock || hadFailureState;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Whether a provider should use per-model lockouts instead of connection-wide cooldowns.
|
|
621
|
+
* Compatible and passthrough providers multiplex multiple upstream models behind one
|
|
622
|
+
* connection, so transient 404/429 responses should stay model-scoped instead of
|
|
623
|
+
* poisoning the whole connection.
|
|
624
|
+
*
|
|
625
|
+
* @param provider - Provider ID
|
|
626
|
+
* @param _model - Model ID (reserved for future use)
|
|
627
|
+
* @param connectionPassthroughModels - Optional per-connection override from providerSpecificData.
|
|
628
|
+
* When provided, takes precedence over registry/provider-level logic.
|
|
629
|
+
*/
|
|
630
|
+
export function hasPerModelQuota(
|
|
631
|
+
provider: string | null | undefined,
|
|
632
|
+
_model: string | null | undefined = null,
|
|
633
|
+
connectionPassthroughModels?: boolean
|
|
634
|
+
): boolean {
|
|
635
|
+
// Connection-level override takes precedence (e.g., user-configured ModelScope)
|
|
636
|
+
if (typeof connectionPassthroughModels === "boolean") {
|
|
637
|
+
return connectionPassthroughModels;
|
|
638
|
+
}
|
|
639
|
+
if (!provider) return false;
|
|
640
|
+
if (getCanonicalLockProvider(provider) === "codex") return true;
|
|
641
|
+
if (provider === "gemini" || provider === "github") return true;
|
|
642
|
+
if (getPassthroughProviders().has(provider)) return true;
|
|
643
|
+
if (isCompatibleProvider(provider)) return true;
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Lock a model (not connection) for a provider with per-model quotas.
|
|
649
|
+
* No-ops for providers that don't use per-model lockouts.
|
|
650
|
+
*/
|
|
651
|
+
export function lockModelIfPerModelQuota(
|
|
652
|
+
provider: string,
|
|
653
|
+
connectionId: string,
|
|
654
|
+
model: string | null,
|
|
655
|
+
reason: string,
|
|
656
|
+
cooldownMs: number,
|
|
657
|
+
connectionPassthroughModels?: boolean
|
|
658
|
+
): boolean {
|
|
659
|
+
if (!hasPerModelQuota(provider, model, connectionPassthroughModels) || !model) return false;
|
|
660
|
+
// Skip model-level lock if the entire provider is in circuit-breaker cooldown.
|
|
661
|
+
// The provider cooldown already prevents all requests, so a model lock is redundant.
|
|
662
|
+
if (isProviderInCooldown(provider)) return false;
|
|
663
|
+
lockModel(provider, connectionId, model, reason, cooldownMs);
|
|
664
|
+
return true;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
export function shouldMarkAccountExhaustedFrom429(
|
|
668
|
+
provider: string | null | undefined,
|
|
669
|
+
model: string | null | undefined = null,
|
|
670
|
+
connectionPassthroughModels?: boolean,
|
|
671
|
+
failureKind?: FailureKind
|
|
672
|
+
): boolean {
|
|
673
|
+
// A plain 429 means transient rate limiting / high traffic for many OAuth providers.
|
|
674
|
+
// Only connection-poison the quota cache when the upstream body explicitly says
|
|
675
|
+
// the long-window quota is exhausted; otherwise fallback should try another account
|
|
676
|
+
// without making this one look quota-depleted for 5 minutes.
|
|
677
|
+
if (failureKind === "rate_limit" || failureKind === "transient") return false;
|
|
678
|
+
return (
|
|
679
|
+
shouldPreserveQuotaSignalsFor429(provider) &&
|
|
680
|
+
!hasPerModelQuota(provider, model, connectionPassthroughModels)
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export function classifyLockoutReason(status: number): string {
|
|
685
|
+
if (status === 429) return "rate_limit";
|
|
686
|
+
if (status === 403) return "quota_exhausted";
|
|
687
|
+
return "unknown";
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
export type DecayResult = { cleared: boolean; newFailureCount: number };
|
|
691
|
+
|
|
692
|
+
export function decayModelFailureCount(
|
|
693
|
+
provider: string,
|
|
694
|
+
connectionId: string,
|
|
695
|
+
model: string
|
|
696
|
+
): DecayResult {
|
|
697
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
698
|
+
const failure = modelFailureState.get(key);
|
|
699
|
+
if (!failure) return { cleared: false, newFailureCount: 0 };
|
|
700
|
+
|
|
701
|
+
const newFailureCount = Math.floor(failure.failureCount / 2);
|
|
702
|
+
if (newFailureCount === 0) {
|
|
703
|
+
modelFailureState.delete(key);
|
|
704
|
+
return { cleared: true, newFailureCount: 0 };
|
|
705
|
+
} else {
|
|
706
|
+
modelFailureState.set(key, {
|
|
707
|
+
...failure,
|
|
708
|
+
failureCount: newFailureCount,
|
|
709
|
+
});
|
|
710
|
+
return { cleared: false, newFailureCount };
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Clear all in-memory model lockouts and failure state (for tests / full reset).
|
|
716
|
+
*/
|
|
717
|
+
export function clearAllModelLockouts(): void {
|
|
718
|
+
modelLockouts.clear();
|
|
719
|
+
modelFailureState.clear();
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Check if a specific model on a specific account is locked
|
|
724
|
+
* @returns {boolean}
|
|
725
|
+
*/
|
|
726
|
+
export function isModelLocked(
|
|
727
|
+
provider: string,
|
|
728
|
+
connectionId: string,
|
|
729
|
+
model: string | null | undefined
|
|
730
|
+
): boolean {
|
|
731
|
+
if (!model) return false;
|
|
732
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
733
|
+
cleanupModelLockKey(key);
|
|
734
|
+
const entry = modelLockouts.get(key);
|
|
735
|
+
return Boolean(entry);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Get model lockout info (for debugging/dashboard)
|
|
740
|
+
*/
|
|
741
|
+
export function getModelLockoutInfo(
|
|
742
|
+
provider: string,
|
|
743
|
+
connectionId: string,
|
|
744
|
+
model: string | null | undefined
|
|
745
|
+
) {
|
|
746
|
+
if (!model) return null;
|
|
747
|
+
const key = getModelLockKey(provider, connectionId, model);
|
|
748
|
+
cleanupModelLockKey(key);
|
|
749
|
+
const entry = modelLockouts.get(key);
|
|
750
|
+
if (!entry) return null;
|
|
751
|
+
return {
|
|
752
|
+
reason: entry.reason,
|
|
753
|
+
remainingMs: entry.until - Date.now(),
|
|
754
|
+
lockedAt: new Date(entry.lockedAt).toISOString(),
|
|
755
|
+
failureCount: entry.failureCount,
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
export type ModelLockoutInfo = {
|
|
760
|
+
provider: string;
|
|
761
|
+
connectionId: string;
|
|
762
|
+
model: string;
|
|
763
|
+
reason: string;
|
|
764
|
+
remainingMs: number;
|
|
765
|
+
failureCount: number;
|
|
766
|
+
lockedAt: string;
|
|
767
|
+
until: number;
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Get all active model lockouts (for dashboard)
|
|
772
|
+
*/
|
|
773
|
+
export function getAllModelLockouts(): ModelLockoutInfo[] {
|
|
774
|
+
const now = Date.now();
|
|
775
|
+
const active: ModelLockoutInfo[] = [];
|
|
776
|
+
for (const key of modelLockouts.keys()) {
|
|
777
|
+
cleanupModelLockKey(key, now);
|
|
778
|
+
}
|
|
779
|
+
for (const [key, entry] of modelLockouts) {
|
|
780
|
+
const [provider, connectionId, ...modelParts] = key.split(":");
|
|
781
|
+
const model = modelParts.join(":");
|
|
782
|
+
active.push({
|
|
783
|
+
provider,
|
|
784
|
+
connectionId,
|
|
785
|
+
model,
|
|
786
|
+
reason: entry.reason,
|
|
787
|
+
remainingMs: entry.until - now,
|
|
788
|
+
failureCount: entry.failureCount,
|
|
789
|
+
lockedAt: new Date(entry.lockedAt).toISOString(),
|
|
790
|
+
until: entry.until,
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
return active;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// ─── Provider Breaker Compatibility Wrappers ────────────────────────────────
|
|
797
|
+
// Legacy helpers now delegate to the shared provider circuit breaker.
|
|
798
|
+
|
|
799
|
+
type ProviderBreakerProfile = {
|
|
800
|
+
failureThreshold?: number;
|
|
801
|
+
degradationThreshold?: number;
|
|
802
|
+
resetTimeoutMs?: number;
|
|
803
|
+
circuitBreakerThreshold?: number;
|
|
804
|
+
circuitBreakerReset?: number;
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
function getProviderBreaker(provider: string | null | undefined) {
|
|
808
|
+
return provider ? getCircuitBreaker(provider) : null;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function configureProviderBreaker(
|
|
812
|
+
provider: string | null | undefined,
|
|
813
|
+
profile?: ProviderBreakerProfile | null
|
|
814
|
+
) {
|
|
815
|
+
if (!provider) return null;
|
|
816
|
+
|
|
817
|
+
const resolvedProfile = { ...getProviderProfile(provider), ...profile };
|
|
818
|
+
// Issue #2100 follow-up: resolve useUpstream429BreakerHints from the
|
|
819
|
+
// provider profile (stored override) or fall back to per-provider default.
|
|
820
|
+
// Stored value type is `boolean | undefined` — never `null` after PATCH.
|
|
821
|
+
const userValue = resolvedProfile.useUpstream429BreakerHints;
|
|
822
|
+
const useHints = resolveUseUpstream429BreakerHints(provider, userValue);
|
|
823
|
+
return getCircuitBreaker(provider, {
|
|
824
|
+
failureThreshold: resolvedProfile.failureThreshold ?? resolvedProfile.circuitBreakerThreshold,
|
|
825
|
+
resetTimeout: resolvedProfile.resetTimeoutMs ?? resolvedProfile.circuitBreakerReset,
|
|
826
|
+
...(useHints
|
|
827
|
+
? {
|
|
828
|
+
cooldownByKind: {
|
|
829
|
+
rate_limit: 60_000,
|
|
830
|
+
quota_exhausted: 3_600_000,
|
|
831
|
+
} satisfies Partial<Record<FailureKind, number>>,
|
|
832
|
+
classifyError: classify429FromError,
|
|
833
|
+
}
|
|
834
|
+
: {}),
|
|
835
|
+
degradationThreshold: resolvedProfile.degradationThreshold,
|
|
836
|
+
maxBackoffMultiplier: resolvedProfile.maxBackoffMultiplier,
|
|
837
|
+
backoffEscalationCount: resolvedProfile.backoffEscalationCount,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Check if a provider is currently blocked by the shared circuit breaker.
|
|
843
|
+
*/
|
|
844
|
+
export function isProviderInCooldown(provider: string | null | undefined): boolean {
|
|
845
|
+
const breaker = getProviderBreaker(provider);
|
|
846
|
+
return breaker ? !breaker.canExecute() : false;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Get remaining retry-after time for a provider breaker.
|
|
851
|
+
*/
|
|
852
|
+
export function getProviderCooldownRemainingMs(provider: string | null | undefined): number | null {
|
|
853
|
+
const breaker = getProviderBreaker(provider);
|
|
854
|
+
if (!breaker || breaker.canExecute()) return null;
|
|
855
|
+
const remaining = breaker.getRetryAfterMs();
|
|
856
|
+
return remaining > 0 ? remaining : null;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
export function getProviderBreakerState(provider: string | null | undefined) {
|
|
860
|
+
const breaker = getProviderBreaker(provider);
|
|
861
|
+
return breaker?.getStatus?.() ?? null;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Record a provider failure against the shared circuit breaker.
|
|
866
|
+
* Delegates to the existing CircuitBreaker utility which handles
|
|
867
|
+
* failure counting, threshold detection, and state transitions.
|
|
868
|
+
*
|
|
869
|
+
* IMPORTANT: If the breaker is already OPEN (in cooldown), we skip
|
|
870
|
+
* recording the failure to prevent resetting the cooldown timer.
|
|
871
|
+
* This matches the original behavior where failures during cooldown
|
|
872
|
+
* were ignored to avoid indefinite lockout.
|
|
873
|
+
*/
|
|
874
|
+
export function recordProviderFailure(
|
|
875
|
+
provider: string | null | undefined,
|
|
876
|
+
log?: { warn?: (...args: unknown[]) => void },
|
|
877
|
+
connectionId?: string | null,
|
|
878
|
+
profile?: ProviderBreakerProfile | null
|
|
879
|
+
): void {
|
|
880
|
+
if (!provider) return;
|
|
881
|
+
|
|
882
|
+
// Deduplicate rapid-fire failures from the same connection
|
|
883
|
+
if (connectionId) {
|
|
884
|
+
const dedupKey = `${provider}:${connectionId}`;
|
|
885
|
+
const now = Date.now();
|
|
886
|
+
const lastFailure = lastConnectionFailure.get(dedupKey);
|
|
887
|
+
if (lastFailure && now - lastFailure < CONNECTION_FAILURE_DEDUP_MS) {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
lastConnectionFailure.delete(dedupKey);
|
|
891
|
+
lastConnectionFailure.set(dedupKey, now);
|
|
892
|
+
pruneConnectionFailureDedupeEntries();
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
const breaker = configureProviderBreaker(provider, profile);
|
|
896
|
+
if (!breaker) return;
|
|
897
|
+
|
|
898
|
+
if (!breaker.canExecute()) return;
|
|
899
|
+
|
|
900
|
+
breaker._onFailure();
|
|
901
|
+
|
|
902
|
+
if (!breaker.canExecute()) {
|
|
903
|
+
log?.warn?.(`[ProviderFailure] ${provider}: circuit breaker opened after repeated failures`);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Reset the shared provider breaker.
|
|
909
|
+
*/
|
|
910
|
+
export function clearProviderFailure(provider: string | null | undefined): void {
|
|
911
|
+
const breaker = getProviderBreaker(provider);
|
|
912
|
+
breaker?.reset();
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Get all providers currently blocked by the shared breaker.
|
|
917
|
+
*/
|
|
918
|
+
export function getProvidersInCooldown(): Array<{
|
|
919
|
+
provider: string;
|
|
920
|
+
failureCount: number;
|
|
921
|
+
cooldownRemainingMs: number | null;
|
|
922
|
+
lastFailureAt: number | null;
|
|
923
|
+
}> {
|
|
924
|
+
return getAllCircuitBreakerStatuses()
|
|
925
|
+
.filter((status) => {
|
|
926
|
+
const breaker = getProviderBreaker(status.name);
|
|
927
|
+
return Boolean(breaker && !breaker.canExecute());
|
|
928
|
+
})
|
|
929
|
+
.map((status) => ({
|
|
930
|
+
provider: status.name,
|
|
931
|
+
failureCount: status.failureCount,
|
|
932
|
+
cooldownRemainingMs: status.retryAfterMs || null,
|
|
933
|
+
lastFailureAt: status.lastFailureTime,
|
|
934
|
+
}));
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Check if a status code should be counted toward provider failure threshold
|
|
939
|
+
*/
|
|
940
|
+
export function isProviderFailureCode(status: number): boolean {
|
|
941
|
+
return PROVIDER_FAILURE_ERROR_CODES.has(status);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* Returns true when a checkFallbackError result signals that the entire provider
|
|
946
|
+
* quota is exhausted for this request, so the combo router can skip remaining
|
|
947
|
+
* targets from the same provider (#1731).
|
|
948
|
+
*
|
|
949
|
+
* Covers:
|
|
950
|
+
* - reason === "quota_exhausted" (subscription, daily, credits)
|
|
951
|
+
* - creditsExhausted flag
|
|
952
|
+
* - dailyQuotaExhausted flag
|
|
953
|
+
*/
|
|
954
|
+
export function isProviderExhaustedReason(result: {
|
|
955
|
+
reason?: string;
|
|
956
|
+
creditsExhausted?: boolean;
|
|
957
|
+
dailyQuotaExhausted?: boolean;
|
|
958
|
+
}): boolean {
|
|
959
|
+
if (result.creditsExhausted || result.dailyQuotaExhausted) return true;
|
|
960
|
+
return result.reason === RateLimitReason.QUOTA_EXHAUSTED;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// ─── Retry-After Parsing ────────────────────────────────────────────────────
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Parse retry-after information from JSON error response bodies.
|
|
967
|
+
* Providers embed retry info in different formats.
|
|
968
|
+
*
|
|
969
|
+
* @param {string|object} responseBody - Raw response body or parsed JSON
|
|
970
|
+
* @returns {{ retryAfterMs: number|null, reason: string }}
|
|
971
|
+
*/
|
|
972
|
+
export function parseRetryAfterFromBody(responseBody: unknown): {
|
|
973
|
+
retryAfterMs: number | null;
|
|
974
|
+
reason: RateLimitReasonValue;
|
|
975
|
+
} {
|
|
976
|
+
let body: JsonRecord;
|
|
977
|
+
try {
|
|
978
|
+
body = toJsonRecord(typeof responseBody === "string" ? JSON.parse(responseBody) : responseBody);
|
|
979
|
+
} catch {
|
|
980
|
+
return { retryAfterMs: null, reason: RateLimitReason.UNKNOWN };
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
if (Object.keys(body).length === 0) {
|
|
984
|
+
return { retryAfterMs: null, reason: RateLimitReason.UNKNOWN };
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Gemini: { error: { details: [{ retryDelay: "33s" }] } }
|
|
988
|
+
const error = toJsonRecord(body.error);
|
|
989
|
+
const details = error.details || body.details || [];
|
|
990
|
+
for (const detail of Array.isArray(details) ? details : []) {
|
|
991
|
+
const detailRecord = toJsonRecord(detail);
|
|
992
|
+
if (detailRecord.retryDelay) {
|
|
993
|
+
return {
|
|
994
|
+
retryAfterMs: parseDelayString(detailRecord.retryDelay),
|
|
995
|
+
reason: RateLimitReason.RATE_LIMIT_EXCEEDED,
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// OpenAI: "Please retry after 20s" in message
|
|
1001
|
+
const msg = String(error.message || body.message || "");
|
|
1002
|
+
const retryMatch = /retry\s+after\s+(\d+)\s*s/i.exec(msg);
|
|
1003
|
+
if (retryMatch) {
|
|
1004
|
+
return {
|
|
1005
|
+
retryAfterMs: Number.parseInt(retryMatch[1], 10) * 1000,
|
|
1006
|
+
reason: RateLimitReason.RATE_LIMIT_EXCEEDED,
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Anthropic: error type classification
|
|
1011
|
+
const errorType = String(error.type || body.type || "");
|
|
1012
|
+
if (errorType === "rate_limit_error") {
|
|
1013
|
+
return { retryAfterMs: null, reason: RateLimitReason.RATE_LIMIT_EXCEEDED };
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// Classify by error message keywords
|
|
1017
|
+
const reason = classifyErrorText(msg || errorType);
|
|
1018
|
+
return { retryAfterMs: null, reason };
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* Parse delay strings like "33s", "2m", "1h", "1500ms"
|
|
1023
|
+
*/
|
|
1024
|
+
function parseDelayString(value: unknown): number | null {
|
|
1025
|
+
if (!value) return null;
|
|
1026
|
+
const str = String(value).trim();
|
|
1027
|
+
const msMatch = /^(\d+)\s*ms$/i.exec(str);
|
|
1028
|
+
if (msMatch) return Number.parseInt(msMatch[1], 10);
|
|
1029
|
+
const secMatch = /^(\d+)\s*s$/i.exec(str);
|
|
1030
|
+
if (secMatch) return Number.parseInt(secMatch[1], 10) * 1000;
|
|
1031
|
+
const minMatch = /^(\d+)\s*m$/i.exec(str);
|
|
1032
|
+
if (minMatch) return Number.parseInt(minMatch[1], 10) * 60 * 1000;
|
|
1033
|
+
const hrMatch = /^(\d+)\s*h$/i.exec(str);
|
|
1034
|
+
if (hrMatch) return Number.parseInt(hrMatch[1], 10) * 3600 * 1000;
|
|
1035
|
+
// Bare number → seconds
|
|
1036
|
+
const num = Number.parseInt(str, 10);
|
|
1037
|
+
return Number.isNaN(num) ? null : num * 1000;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// T07: parse retry time from error text body with combined "XhYmZs" format.
|
|
1041
|
+
export function parseRetryFromErrorText(errorText: unknown): number | null {
|
|
1042
|
+
if (!errorText || typeof errorText !== "string") return null;
|
|
1043
|
+
const msg: string = String(errorText);
|
|
1044
|
+
|
|
1045
|
+
const bodyHintMs = parseRetryHintFromJsonBody(msg, MAX_PROVIDER_COOLDOWN_MS);
|
|
1046
|
+
if (bodyHintMs !== null) return bodyHintMs;
|
|
1047
|
+
|
|
1048
|
+
// Issue #2321: parse embedded absolute ISO retry timestamps.
|
|
1049
|
+
const isoMatch =
|
|
1050
|
+
/\b(?:try again at|wait until|reset(?:s)? at|available at|retry after)\s+(\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)/i.exec(
|
|
1051
|
+
msg
|
|
1052
|
+
);
|
|
1053
|
+
if (isoMatch) {
|
|
1054
|
+
const parsedTs = Date.parse(isoMatch[1]);
|
|
1055
|
+
if (Number.isFinite(parsedTs)) {
|
|
1056
|
+
const waitMs = parsedTs - Date.now();
|
|
1057
|
+
if (waitMs > 0) return waitMs;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
const match = /reset after (\d+h)?(\d+m)?(\d+s)?/i.exec(msg);
|
|
1062
|
+
if (match?.[1] || match?.[2] || match?.[3]) return computeDurationMs(match);
|
|
1063
|
+
|
|
1064
|
+
// Variant without "reset after": "will reset after XhYmZs"
|
|
1065
|
+
const altMatch = /will reset after (\d+h)?(\d+m)?(\d+s)?/i.exec(msg);
|
|
1066
|
+
if (altMatch?.[1] || altMatch?.[2] || altMatch?.[3]) return computeDurationMs(altMatch);
|
|
1067
|
+
|
|
1068
|
+
// Antigravity / Cloud Code phrasing: "Resets in 164h27m24s".
|
|
1069
|
+
const resetsInMatch = /resets? in (\d+h)?(\d+m)?(\d+s)?/i.exec(msg);
|
|
1070
|
+
if (resetsInMatch?.[1] || resetsInMatch?.[2] || resetsInMatch?.[3]) {
|
|
1071
|
+
return computeDurationMs(resetsInMatch);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
return null;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Compute total milliseconds from regex match groups (Xh)(Ym)(Zs)
|
|
1079
|
+
* Capped at 30 days to prevent adversarial/buggy upstream from locking indefinitely.
|
|
1080
|
+
*/
|
|
1081
|
+
const MAX_PROVIDER_COOLDOWN_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
1082
|
+
|
|
1083
|
+
function computeDurationMs(match: RegExpMatchArray): number | null {
|
|
1084
|
+
let totalMs = 0;
|
|
1085
|
+
if (match[1]) totalMs += Number.parseInt(match[1], 10) * 3600 * 1000; // hours
|
|
1086
|
+
if (match[2]) totalMs += Number.parseInt(match[2], 10) * 60 * 1000; // minutes
|
|
1087
|
+
if (match[3]) totalMs += Number.parseInt(match[3], 10) * 1000; // seconds
|
|
1088
|
+
return totalMs > 0 ? Math.min(totalMs, MAX_PROVIDER_COOLDOWN_MS) : null;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function isSubscriptionQuotaText(lower: string): boolean {
|
|
1092
|
+
return (
|
|
1093
|
+
lower.includes("usage limit reached") ||
|
|
1094
|
+
lower.includes("usage limit has been") ||
|
|
1095
|
+
lower.includes("claude pro usage limit") ||
|
|
1096
|
+
lower.includes("you've reached your usage limit") ||
|
|
1097
|
+
lower.includes("you have reached your usage limit")
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// ─── Error Classification ───────────────────────────────────────────────────
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* Classify error text into RateLimitReason
|
|
1105
|
+
*/
|
|
1106
|
+
export function classifyErrorText(errorText: unknown): RateLimitReasonValue {
|
|
1107
|
+
if (!errorText) return RateLimitReason.UNKNOWN;
|
|
1108
|
+
const lower = String(errorText).toLowerCase();
|
|
1109
|
+
|
|
1110
|
+
if (
|
|
1111
|
+
lower.includes("quota exceeded") ||
|
|
1112
|
+
lower.includes("quota depleted") ||
|
|
1113
|
+
lower.includes("quota will reset") ||
|
|
1114
|
+
lower.includes("your quota will reset") ||
|
|
1115
|
+
lower.includes("quota has been exceeded") ||
|
|
1116
|
+
lower.includes("hour quota") ||
|
|
1117
|
+
lower.includes("billing") ||
|
|
1118
|
+
looksLikeQuotaExhausted(lower) ||
|
|
1119
|
+
// Issue #2321: Anthropic OAuth (Claude Code Pro/Team) 429 bodies surface
|
|
1120
|
+
// the subscription quota with phrases that contain neither "quota" nor
|
|
1121
|
+
// "billing". Without these patterns the error was classified as a
|
|
1122
|
+
// transient RATE_LIMIT_EXCEEDED (~5s base cooldown), which cascades all
|
|
1123
|
+
// Pro accounts into a tight retry loop until the 5h window resets.
|
|
1124
|
+
isSubscriptionQuotaText(lower)
|
|
1125
|
+
) {
|
|
1126
|
+
return RateLimitReason.QUOTA_EXHAUSTED;
|
|
1127
|
+
}
|
|
1128
|
+
// T10: credits_exhausted signals
|
|
1129
|
+
if (isCreditsExhausted(lower)) {
|
|
1130
|
+
return RateLimitReason.QUOTA_EXHAUSTED;
|
|
1131
|
+
}
|
|
1132
|
+
// T06: account_deactivated signals
|
|
1133
|
+
if (isAccountDeactivated(lower)) {
|
|
1134
|
+
return RateLimitReason.AUTH_ERROR;
|
|
1135
|
+
}
|
|
1136
|
+
const configuredRule = matchErrorRuleByText(errorText);
|
|
1137
|
+
if (configuredRule?.reason) return configuredRule.reason;
|
|
1138
|
+
if (lower.includes("rate_limit")) return RateLimitReason.RATE_LIMIT_EXCEEDED;
|
|
1139
|
+
if (lower.includes("resource exhausted") || lower.includes("high demand"))
|
|
1140
|
+
return RateLimitReason.MODEL_CAPACITY;
|
|
1141
|
+
if (
|
|
1142
|
+
lower.includes("unauthorized") ||
|
|
1143
|
+
lower.includes("invalid api key") ||
|
|
1144
|
+
lower.includes("authentication")
|
|
1145
|
+
) {
|
|
1146
|
+
return RateLimitReason.AUTH_ERROR;
|
|
1147
|
+
}
|
|
1148
|
+
if (lower.includes("server error") || lower.includes("internal error")) {
|
|
1149
|
+
return RateLimitReason.SERVER_ERROR;
|
|
1150
|
+
}
|
|
1151
|
+
return RateLimitReason.UNKNOWN;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* Classify HTTP status + error text into RateLimitReason
|
|
1156
|
+
*
|
|
1157
|
+
* If context (provider, headers, body) is supplied, provider-specific rules
|
|
1158
|
+
* are evaluated FIRST. A provider like Opencode can signal account-wide quota
|
|
1159
|
+
* exhaustion via `x-ratelimit-remaining-requests: 0` even when the body says
|
|
1160
|
+
* "rate limit" — without context, classifyError falls through to the global
|
|
1161
|
+
* text rules and misclassifies as RATE_LIMIT_EXCEEDED. With context, the
|
|
1162
|
+
* provider rule takes precedence.
|
|
1163
|
+
*/
|
|
1164
|
+
export function classifyError(
|
|
1165
|
+
status: number,
|
|
1166
|
+
errorText: unknown,
|
|
1167
|
+
context?: { provider?: string | null; headers?: Record<string, string> | null; body?: unknown }
|
|
1168
|
+
): RateLimitReasonValue {
|
|
1169
|
+
// Provider-specific rules take priority — they have the most accurate signal
|
|
1170
|
+
// (e.g. `x-ratelimit-remaining-requests: 0` is irrefutable account exhaustion).
|
|
1171
|
+
if (context?.provider) {
|
|
1172
|
+
const match = getProviderErrorRuleMatch(
|
|
1173
|
+
context.provider,
|
|
1174
|
+
status,
|
|
1175
|
+
context.headers ?? null,
|
|
1176
|
+
context.body
|
|
1177
|
+
);
|
|
1178
|
+
if (match) return match.reason;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Text classification takes priority (more specific)
|
|
1182
|
+
const textReason = classifyErrorText(errorText);
|
|
1183
|
+
if (textReason !== RateLimitReason.UNKNOWN) return textReason;
|
|
1184
|
+
|
|
1185
|
+
// Fall back to status code
|
|
1186
|
+
if (status === HTTP_STATUS.UNAUTHORIZED || status === HTTP_STATUS.FORBIDDEN) {
|
|
1187
|
+
return RateLimitReason.AUTH_ERROR;
|
|
1188
|
+
}
|
|
1189
|
+
if (status === HTTP_STATUS.PAYMENT_REQUIRED) {
|
|
1190
|
+
return RateLimitReason.QUOTA_EXHAUSTED;
|
|
1191
|
+
}
|
|
1192
|
+
if (status === HTTP_STATUS.RATE_LIMITED) {
|
|
1193
|
+
return RateLimitReason.RATE_LIMIT_EXCEEDED;
|
|
1194
|
+
}
|
|
1195
|
+
if (status === HTTP_STATUS.SERVICE_UNAVAILABLE || status === 529) {
|
|
1196
|
+
return RateLimitReason.MODEL_CAPACITY;
|
|
1197
|
+
}
|
|
1198
|
+
if (status >= 500) {
|
|
1199
|
+
return RateLimitReason.SERVER_ERROR;
|
|
1200
|
+
}
|
|
1201
|
+
return RateLimitReason.UNKNOWN;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// ─── Daily Quota Helpers ────────────────────────────────────────────────────
|
|
1205
|
+
|
|
1206
|
+
/**
|
|
1207
|
+
* Calculate milliseconds from now until tomorrow at midnight (00:00:00).
|
|
1208
|
+
* Used to lock a model until the next day when daily quota is exhausted.
|
|
1209
|
+
* @returns {number} Milliseconds until tomorrow
|
|
1210
|
+
*/
|
|
1211
|
+
export function getMsUntilTomorrow(): number {
|
|
1212
|
+
const nowMs = Date.now();
|
|
1213
|
+
const tomorrow = new Date(nowMs);
|
|
1214
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
1215
|
+
tomorrow.setHours(0, 0, 0, 0);
|
|
1216
|
+
const ms = tomorrow.getTime() - nowMs;
|
|
1217
|
+
// Guard against DST edge cases: if ms is negative (shouldn't happen) or
|
|
1218
|
+
// unreasonably large (>25h due to spring-forward), cap at 24 hours.
|
|
1219
|
+
return ms > 0 && ms <= 25 * 60 * 60 * 1000 ? ms : 24 * 60 * 60 * 1000;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* Check if error text indicates daily quota exhaustion (as opposed to rate limiting).
|
|
1224
|
+
* Daily quota errors typically mention "today's quota" or "try again tomorrow".
|
|
1225
|
+
* @param {string} errorText - Error message text
|
|
1226
|
+
* @returns {boolean} True if daily quota is exhausted
|
|
1227
|
+
*/
|
|
1228
|
+
export function isDailyQuotaExhausted(errorText: string): boolean {
|
|
1229
|
+
if (!errorText) return false;
|
|
1230
|
+
const lower = errorText.toLowerCase();
|
|
1231
|
+
return (
|
|
1232
|
+
lower.includes("today's quota") ||
|
|
1233
|
+
lower.includes("daily quota") ||
|
|
1234
|
+
lower.includes("try again tomorrow")
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// ─── Configurable Backoff ───────────────────────────────────────────────────
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* Get backoff duration from configurable steps.
|
|
1242
|
+
* @param {number} failureCount - Number of consecutive failures
|
|
1243
|
+
* @returns {number} Duration in ms
|
|
1244
|
+
*/
|
|
1245
|
+
export function getBackoffDuration(failureCount: number): number {
|
|
1246
|
+
const idx = Math.min(failureCount, BACKOFF_STEPS_MS.length - 1);
|
|
1247
|
+
return BACKOFF_STEPS_MS[idx];
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// ─── Original API (Backward Compatible) ────────────────────────────────────
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* Calculate exponential backoff cooldown for rate limits (429)
|
|
1254
|
+
* Level 0: 1s, Level 1: 2s, Level 2: 4s... → max 2 min
|
|
1255
|
+
* @param {number} backoffLevel - Current backoff level
|
|
1256
|
+
* @returns {number} Cooldown in milliseconds
|
|
1257
|
+
*/
|
|
1258
|
+
export function getQuotaCooldown(backoffLevel = 0) {
|
|
1259
|
+
return calculateBackoffCooldown(backoffLevel);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Check if error should trigger account fallback (switch to next account)
|
|
1264
|
+
* @param {number} status - HTTP status code
|
|
1265
|
+
* @param {string} errorText - Error message text
|
|
1266
|
+
* @param {number} backoffLevel - Current backoff level for exponential backoff
|
|
1267
|
+
* @param {string} [model] - Optional model name for model-level lockout
|
|
1268
|
+
* @param {string} [provider] - Provider ID for profile-aware cooldowns
|
|
1269
|
+
* @returns {{ shouldFallback: boolean, cooldownMs: number, newBackoffLevel?: number, reason?: string }}
|
|
1270
|
+
*/
|
|
1271
|
+
export function checkFallbackError(
|
|
1272
|
+
status: number,
|
|
1273
|
+
errorText: string | null,
|
|
1274
|
+
backoffLevel: number = 0,
|
|
1275
|
+
_model: string | null = null,
|
|
1276
|
+
provider: string | null = null,
|
|
1277
|
+
headers: Headers | Record<string, string> | null = null,
|
|
1278
|
+
profileOverride: ProviderProfile | null = null,
|
|
1279
|
+
structuredError?: { code?: string | null; type?: string | null } | null
|
|
1280
|
+
): {
|
|
1281
|
+
shouldFallback: boolean;
|
|
1282
|
+
cooldownMs: number;
|
|
1283
|
+
baseCooldownMs?: number;
|
|
1284
|
+
newBackoffLevel?: number;
|
|
1285
|
+
usedUpstreamRetryHint?: boolean;
|
|
1286
|
+
reason?: string;
|
|
1287
|
+
permanent?: boolean;
|
|
1288
|
+
creditsExhausted?: boolean;
|
|
1289
|
+
dailyQuotaExhausted?: boolean;
|
|
1290
|
+
/** G-02: true when the error originates from an embedded service supervisor (not the upstream AI
|
|
1291
|
+
* provider itself). Callers should apply connection cooldown only — do NOT record a provider
|
|
1292
|
+
* circuit-breaker failure when this flag is set. */
|
|
1293
|
+
skipProviderBreaker?: boolean;
|
|
1294
|
+
quotaResetHintMs?: number;
|
|
1295
|
+
/** #6061: the provider-configured cooldown (ms) before backoff scaling, surfaced so the
|
|
1296
|
+
* caller can persist an explicit reset window instead of the engine's scaled cooldown. */
|
|
1297
|
+
configuredCooldownMs?: number;
|
|
1298
|
+
} {
|
|
1299
|
+
// G-02: detect embedded service supervisor failures (X-Omni-Fallback-Hint: connection_cooldown).
|
|
1300
|
+
// These are NOT upstream AI provider failures — they are local supervisor state changes.
|
|
1301
|
+
// Apply a short 5s connection cooldown without tripping the provider circuit breaker.
|
|
1302
|
+
if (status === 503 && headers) {
|
|
1303
|
+
const hintValue =
|
|
1304
|
+
typeof (headers as Headers).get === "function"
|
|
1305
|
+
? (headers as Headers).get("x-omni-fallback-hint")
|
|
1306
|
+
: (headers as Record<string, string>)["x-omni-fallback-hint"] ||
|
|
1307
|
+
(headers as Record<string, string>)["X-Omni-Fallback-Hint"];
|
|
1308
|
+
if (typeof hintValue === "string" && hintValue.toLowerCase() === "connection_cooldown") {
|
|
1309
|
+
return {
|
|
1310
|
+
shouldFallback: true,
|
|
1311
|
+
cooldownMs: 5_000,
|
|
1312
|
+
baseCooldownMs: 5_000,
|
|
1313
|
+
newBackoffLevel: 0,
|
|
1314
|
+
reason: "service_not_running",
|
|
1315
|
+
skipProviderBreaker: true,
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
const errorStr = (errorText || "").toString();
|
|
1321
|
+
const profile = profileOverride ?? (provider ? getProviderProfile(provider) : null);
|
|
1322
|
+
const maxBackoffSteps = profile?.maxBackoffSteps ?? BACKOFF_CONFIG.maxLevel;
|
|
1323
|
+
const retryableStatuses = new Set([
|
|
1324
|
+
HTTP_STATUS.REQUEST_TIMEOUT,
|
|
1325
|
+
HTTP_STATUS.RATE_LIMITED,
|
|
1326
|
+
HTTP_STATUS.SERVER_ERROR,
|
|
1327
|
+
HTTP_STATUS.BAD_GATEWAY,
|
|
1328
|
+
HTTP_STATUS.SERVICE_UNAVAILABLE,
|
|
1329
|
+
HTTP_STATUS.GATEWAY_TIMEOUT,
|
|
1330
|
+
]);
|
|
1331
|
+
|
|
1332
|
+
function parseResetFromHeaders(headers: Headers | Record<string, string> | null): number | null {
|
|
1333
|
+
if (!headers) return null;
|
|
1334
|
+
const recordHeaders = headers as Record<string, string>;
|
|
1335
|
+
|
|
1336
|
+
// Retry-After header
|
|
1337
|
+
const retryAfter =
|
|
1338
|
+
typeof (headers as Headers).get === "function"
|
|
1339
|
+
? (headers as Headers).get("retry-after")
|
|
1340
|
+
: recordHeaders["retry-after"] || recordHeaders["Retry-After"];
|
|
1341
|
+
|
|
1342
|
+
if (retryAfter) {
|
|
1343
|
+
const seconds = Number.parseInt(retryAfter, 10);
|
|
1344
|
+
if (!Number.isNaN(seconds) && String(seconds) === String(retryAfter).trim()) {
|
|
1345
|
+
return Date.now() + seconds * 1000;
|
|
1346
|
+
}
|
|
1347
|
+
const date = new Date(retryAfter);
|
|
1348
|
+
if (!Number.isNaN(date.getTime())) return date.getTime();
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// X-RateLimit-Reset
|
|
1352
|
+
const rlReset =
|
|
1353
|
+
typeof (headers as Headers).get === "function"
|
|
1354
|
+
? (headers as Headers).get("x-ratelimit-reset")
|
|
1355
|
+
: recordHeaders["x-ratelimit-reset"] || recordHeaders["X-RateLimit-Reset"];
|
|
1356
|
+
|
|
1357
|
+
if (rlReset) {
|
|
1358
|
+
const ts = Number.parseInt(rlReset, 10);
|
|
1359
|
+
if (!Number.isNaN(ts)) {
|
|
1360
|
+
return ts > 10000000000 ? ts : ts * 1000;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
return null;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
function getUpstreamRetryHintMs() {
|
|
1367
|
+
if (!profile?.useUpstreamRetryHints) return null;
|
|
1368
|
+
const resetTime = parseResetFromHeaders(headers);
|
|
1369
|
+
if (resetTime) {
|
|
1370
|
+
const waitMs = Math.max(resetTime - Date.now(), 0);
|
|
1371
|
+
if (waitMs > 0) return waitMs;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
const retryFromErrorText = parseRetryFromErrorText(errorStr);
|
|
1375
|
+
if (retryFromErrorText && retryFromErrorText > 0) {
|
|
1376
|
+
return retryFromErrorText;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
return null;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
function getScaledBaseCooldown(reason: RateLimitReasonValue, level = backoffLevel) {
|
|
1383
|
+
void reason;
|
|
1384
|
+
const baseCooldownMs =
|
|
1385
|
+
typeof profile?.baseCooldownMs === "number" && profile.baseCooldownMs >= 0
|
|
1386
|
+
? profile.baseCooldownMs
|
|
1387
|
+
: COOLDOWN_MS.transientInitial;
|
|
1388
|
+
return {
|
|
1389
|
+
baseCooldownMs,
|
|
1390
|
+
cooldownMs: getScaledCooldown(baseCooldownMs, level + 1, maxBackoffSteps),
|
|
1391
|
+
newBackoffLevel: Math.min(level + 1, maxBackoffSteps),
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
function buildRetryableFallback(reason: RateLimitReasonValue) {
|
|
1396
|
+
const upstreamRetryHintMs = getUpstreamRetryHintMs();
|
|
1397
|
+
if (typeof upstreamRetryHintMs === "number" && upstreamRetryHintMs > 0) {
|
|
1398
|
+
return {
|
|
1399
|
+
shouldFallback: true,
|
|
1400
|
+
cooldownMs: upstreamRetryHintMs,
|
|
1401
|
+
baseCooldownMs: upstreamRetryHintMs,
|
|
1402
|
+
newBackoffLevel: 0,
|
|
1403
|
+
usedUpstreamRetryHint: true,
|
|
1404
|
+
reason,
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
const scaled = getScaledBaseCooldown(reason, backoffLevel);
|
|
1409
|
+
return {
|
|
1410
|
+
shouldFallback: true,
|
|
1411
|
+
cooldownMs: scaled.cooldownMs,
|
|
1412
|
+
baseCooldownMs: scaled.baseCooldownMs,
|
|
1413
|
+
newBackoffLevel: scaled.newBackoffLevel,
|
|
1414
|
+
usedUpstreamRetryHint: false,
|
|
1415
|
+
reason,
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
const isRateLimitStatus = status === HTTP_STATUS.RATE_LIMITED;
|
|
1420
|
+
const preserveQuota429 = shouldPreserveQuotaSignalsFor429(provider);
|
|
1421
|
+
const shouldUseQuotaSignal = !isRateLimitStatus || preserveQuota429;
|
|
1422
|
+
|
|
1423
|
+
// Check error message FIRST - specific patterns take priority over status codes
|
|
1424
|
+
if (errorText) {
|
|
1425
|
+
// T06 (sub2api #1037): Permanent account deactivation — do NOT retry, mark as permanent failure
|
|
1426
|
+
if (isAccountDeactivated(errorStr)) {
|
|
1427
|
+
return {
|
|
1428
|
+
shouldFallback: true,
|
|
1429
|
+
cooldownMs: 365 * 24 * 60 * 60 * 1000, // 1 year = effectively permanent
|
|
1430
|
+
reason: RateLimitReason.AUTH_ERROR,
|
|
1431
|
+
permanent: true,
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
// T10 (sub2api #1169): Credits/quota exhausted — long cooldown, distinct from rate limit
|
|
1436
|
+
if (shouldUseQuotaSignal && isCreditsExhausted(errorStr)) {
|
|
1437
|
+
return {
|
|
1438
|
+
shouldFallback: true,
|
|
1439
|
+
cooldownMs: COOLDOWN_MS.paymentRequired ?? 3600 * 1000, // 1h cooldown
|
|
1440
|
+
reason: RateLimitReason.QUOTA_EXHAUSTED,
|
|
1441
|
+
creditsExhausted: true,
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// Daily quota exhausted — lock model until tomorrow
|
|
1446
|
+
if (shouldUseQuotaSignal && isDailyQuotaExhausted(errorStr)) {
|
|
1447
|
+
const msUntilTomorrow = getMsUntilTomorrow();
|
|
1448
|
+
// Cap at 24 hours to handle timezone edge cases
|
|
1449
|
+
const cooldownMs = Math.min(msUntilTomorrow, 24 * 60 * 60 * 1000);
|
|
1450
|
+
return {
|
|
1451
|
+
shouldFallback: true,
|
|
1452
|
+
cooldownMs,
|
|
1453
|
+
reason: RateLimitReason.QUOTA_EXHAUSTED,
|
|
1454
|
+
dailyQuotaExhausted: true,
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// Issue #2321: Anthropic OAuth (Claude Pro/Team) returns 429 with
|
|
1459
|
+
// "Usage Limit Reached" for the 5-hour subscription quota. The
|
|
1460
|
+
// pattern-based classifier now flags these as QUOTA_EXHAUSTED, but
|
|
1461
|
+
// without a dedicated branch the request would still fall through to
|
|
1462
|
+
// the generic 429 retry path (~5s base cooldown). Honor upstream
|
|
1463
|
+
// Retry-After / reset hints only when the profile enables them;
|
|
1464
|
+
// otherwise apply a local 1h cooldown so all Pro accounts on the same
|
|
1465
|
+
// subscription tier stop cycling through tight retries without letting
|
|
1466
|
+
// upstream-provided windows bypass the operator setting. (We
|
|
1467
|
+
// deliberately do not use COOLDOWN_MS.paymentRequired here — that
|
|
1468
|
+
// constant is 2 minutes, which is shorter than the recovery time of a
|
|
1469
|
+
// subscription quota.)
|
|
1470
|
+
if (
|
|
1471
|
+
shouldUseQuotaSignal &&
|
|
1472
|
+
!isCreditsExhausted(errorStr) &&
|
|
1473
|
+
!isDailyQuotaExhausted(errorStr) &&
|
|
1474
|
+
isSubscriptionQuotaText(errorStr.toLowerCase())
|
|
1475
|
+
) {
|
|
1476
|
+
// getUpstreamRetryHintMs() gates both headers and body reset text on
|
|
1477
|
+
// profile.useUpstreamRetryHints.
|
|
1478
|
+
const hintMs = getUpstreamRetryHintMs();
|
|
1479
|
+
const SUBSCRIPTION_QUOTA_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour
|
|
1480
|
+
const bodyHint = parseRetryFromErrorText(errorStr);
|
|
1481
|
+
return {
|
|
1482
|
+
shouldFallback: true,
|
|
1483
|
+
cooldownMs: hintMs ?? SUBSCRIPTION_QUOTA_COOLDOWN_MS,
|
|
1484
|
+
reason: RateLimitReason.QUOTA_EXHAUSTED,
|
|
1485
|
+
usedUpstreamRetryHint: Boolean(hintMs),
|
|
1486
|
+
quotaResetHintMs: bodyHint ?? undefined,
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
const quotaResetHintMs = parseRetryFromErrorText(errorStr);
|
|
1491
|
+
if (
|
|
1492
|
+
shouldUseQuotaSignal &&
|
|
1493
|
+
quotaResetHintMs &&
|
|
1494
|
+
classifyErrorText(errorStr) === RateLimitReason.QUOTA_EXHAUSTED
|
|
1495
|
+
) {
|
|
1496
|
+
const fallbackResult = buildRetryableFallback(RateLimitReason.QUOTA_EXHAUSTED);
|
|
1497
|
+
return {
|
|
1498
|
+
...fallbackResult,
|
|
1499
|
+
quotaResetHintMs,
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
// #2929: A route-restriction 403 (e.g. Fireworks Fire Pass keys returning
|
|
1504
|
+
// "Fire Pass API keys are not authorized for this route." on the /models
|
|
1505
|
+
// endpoint) means the key is valid but lacks access to THIS route — it still
|
|
1506
|
+
// serves chat. It must NOT cool down the connection or be classified as an
|
|
1507
|
+
// auth error, otherwise a single model-listing 403 marks the key unavailable.
|
|
1508
|
+
if (
|
|
1509
|
+
status === HTTP_STATUS.FORBIDDEN &&
|
|
1510
|
+
errorStr.toLowerCase().includes("not authorized for this route")
|
|
1511
|
+
) {
|
|
1512
|
+
return { shouldFallback: false, cooldownMs: 0, reason: RateLimitReason.UNKNOWN };
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
if (
|
|
1516
|
+
status === HTTP_STATUS.FORBIDDEN &&
|
|
1517
|
+
provider &&
|
|
1518
|
+
getProviderCategory(provider) === "apikey" &&
|
|
1519
|
+
!errorStr.toLowerCase().includes("has not been used in project") &&
|
|
1520
|
+
!errorStr.toLowerCase().includes("hour quota") &&
|
|
1521
|
+
!errorStr.toLowerCase().includes("quota has been exceeded")
|
|
1522
|
+
) {
|
|
1523
|
+
return buildRetryableFallback(RateLimitReason.AUTH_ERROR);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// Gemini-specific: use known published RPM/RPD limits to distinguish 429 types.
|
|
1528
|
+
// Gemini returns the same error body for both, so we use per-model request
|
|
1529
|
+
// counters to decide: if daily count >= RPD → quota_exhausted (midnight lockout);
|
|
1530
|
+
// if minute count >= RPM → rate_limit_exceeded (exponential backoff).
|
|
1531
|
+
if (provider === "gemini" && status === HTTP_STATUS.RATE_LIMITED && _model) {
|
|
1532
|
+
if (isRpdExhausted(_model)) {
|
|
1533
|
+
return buildRetryableFallback(RateLimitReason.QUOTA_EXHAUSTED);
|
|
1534
|
+
}
|
|
1535
|
+
if (isRpmExhausted(_model)) {
|
|
1536
|
+
return buildRetryableFallback(RateLimitReason.RATE_LIMIT_EXCEEDED);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
const configuredRule =
|
|
1541
|
+
isRateLimitStatus && !preserveQuota429
|
|
1542
|
+
? matchErrorRuleByStatus(status)
|
|
1543
|
+
: findMatchingErrorRule(status, errorStr);
|
|
1544
|
+
if (configuredRule) {
|
|
1545
|
+
if (configuredRule.backoff) {
|
|
1546
|
+
// Provider-specific rules in `providerRuleRegistry` are MORE SPECIFIC
|
|
1547
|
+
// than the configured (global) rule, so we check them first. If a
|
|
1548
|
+
// provider rule matches, it overrides the configured rule's reason
|
|
1549
|
+
// (e.g. Opencode's `x-ratelimit-remaining-requests: 0` overrides
|
|
1550
|
+
// 429 → RATE_LIMIT_EXCEEDED). We do NOT call the full `classifyError`
|
|
1551
|
+
// here because its global status fallback would otherwise override
|
|
1552
|
+
// specific configured reasons (e.g. 503 → SERVER_ERROR would be
|
|
1553
|
+
// shadowed by 503 → MODEL_CAPACITY).
|
|
1554
|
+
const providerMatch = provider
|
|
1555
|
+
? getProviderErrorRuleMatch(provider, status, headers, structuredError ?? null)
|
|
1556
|
+
: null;
|
|
1557
|
+
const reason = providerMatch
|
|
1558
|
+
? providerMatch.reason
|
|
1559
|
+
: (configuredRule.reason ?? RateLimitReason.UNKNOWN);
|
|
1560
|
+
// Fix C: thread `providerMatch.cooldownMs` through so a configured rule
|
|
1561
|
+
// like the "Monthly usage limit reached. Resets in N days." matcher can
|
|
1562
|
+
// declare an explicit cooldown (e.g. 13 days) and have it win over the
|
|
1563
|
+
// scaled backoff default returned by `buildRetryableFallback`. Without
|
|
1564
|
+
// this, the rule's reason is used but its cooldownMs is silently
|
|
1565
|
+
// dropped — which is exactly the user-visible bug where a 13-day
|
|
1566
|
+
// upstream quota reset was being treated as ~60s.
|
|
1567
|
+
const providerCooldownMs =
|
|
1568
|
+
providerMatch?.cooldownMs !== undefined && providerMatch.cooldownMs > 0
|
|
1569
|
+
? providerMatch.cooldownMs
|
|
1570
|
+
: undefined;
|
|
1571
|
+
const fallback = buildRetryableFallback(reason);
|
|
1572
|
+
if (providerCooldownMs !== undefined) {
|
|
1573
|
+
return {
|
|
1574
|
+
...fallback,
|
|
1575
|
+
cooldownMs: providerCooldownMs,
|
|
1576
|
+
baseCooldownMs: providerCooldownMs,
|
|
1577
|
+
configuredCooldownMs: providerCooldownMs,
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
return fallback;
|
|
1581
|
+
}
|
|
1582
|
+
const cooldownMs = configuredRule.cooldownMs ?? 0;
|
|
1583
|
+
return {
|
|
1584
|
+
shouldFallback: true,
|
|
1585
|
+
cooldownMs,
|
|
1586
|
+
baseCooldownMs: cooldownMs,
|
|
1587
|
+
configuredCooldownMs: cooldownMs,
|
|
1588
|
+
reason: configuredRule.reason ?? RateLimitReason.UNKNOWN,
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
if (status === HTTP_STATUS.NOT_ACCEPTABLE || retryableStatuses.has(status)) {
|
|
1593
|
+
return buildRetryableFallback(RateLimitReason.SERVER_ERROR);
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
// 400 — context overflow / malformed request / model access denied
|
|
1597
|
+
if (status === HTTP_STATUS.BAD_REQUEST) {
|
|
1598
|
+
// Check structured error codes first (more reliable, no false positives)
|
|
1599
|
+
// OpenAI: error.code === "model_not_found"
|
|
1600
|
+
// Anthropic: error.type === "not_found_error" / "permission_error"
|
|
1601
|
+
const structuredCode =
|
|
1602
|
+
typeof structuredError?.code === "string" ? structuredError.code.toLowerCase() : "";
|
|
1603
|
+
const structuredType =
|
|
1604
|
+
typeof structuredError?.type === "string" ? structuredError.type.toLowerCase() : "";
|
|
1605
|
+
// A clear bad-credential error must never be reclassified as model-access
|
|
1606
|
+
// (which would silently exhaust every combo target). Structured detection
|
|
1607
|
+
// below still catches genuine model_not_found / not_found_error codes.
|
|
1608
|
+
const looksLikeAuthCredentialError = AUTH_CREDENTIAL_ERROR_PATTERNS.some((p) =>
|
|
1609
|
+
p.test(errorStr)
|
|
1610
|
+
);
|
|
1611
|
+
const matchesModelAccessPattern =
|
|
1612
|
+
!looksLikeAuthCredentialError && MODEL_ACCESS_DENIED_PATTERNS.some((p) => p.test(errorStr));
|
|
1613
|
+
|
|
1614
|
+
const isModelAccessDeniedStructured =
|
|
1615
|
+
!!structuredError &&
|
|
1616
|
+
(MODEL_ACCESS_DENIED_CODES.has(structuredCode) ||
|
|
1617
|
+
MODEL_ACCESS_DENIED_TYPES.has(structuredType) ||
|
|
1618
|
+
// Ambiguous types (e.g. Anthropic permission_error) only count as a model
|
|
1619
|
+
// access denial when the message text confirms it is about the model.
|
|
1620
|
+
(MODEL_ACCESS_AMBIGUOUS_TYPES.has(structuredType) && matchesModelAccessPattern));
|
|
1621
|
+
|
|
1622
|
+
const isOverflow = CONTEXT_OVERFLOW_PATTERNS.some((p) => p.test(errorStr));
|
|
1623
|
+
const isMalformed = MALFORMED_REQUEST_PATTERNS.some((p) => p.test(errorStr));
|
|
1624
|
+
const isParamValidation = PARAM_VALIDATION_PATTERNS.some((p) => p.test(errorStr));
|
|
1625
|
+
const isModelAccessDenied = isModelAccessDeniedStructured || matchesModelAccessPattern;
|
|
1626
|
+
|
|
1627
|
+
if (isOverflow || isMalformed || isParamValidation || isModelAccessDenied) {
|
|
1628
|
+
return {
|
|
1629
|
+
shouldFallback: true,
|
|
1630
|
+
cooldownMs: 0,
|
|
1631
|
+
reason: RateLimitReason.MODEL_CAPACITY,
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// Some providers (e.g. MiMoCode) signal throttling with a non-standard 400 whose
|
|
1636
|
+
// body carries rate-limit semantics ("Detected high-frequency non-compliant
|
|
1637
|
+
// requests from you.") instead of a 429. Detected here (AFTER malformed/overflow
|
|
1638
|
+
// detection above, so a genuinely malformed 400 still wins and keeps its #2101
|
|
1639
|
+
// zero-cooldown MODEL_CAPACITY classification), it is fallback-worthy at
|
|
1640
|
+
// connection-cooldown scope so combo can fail over to another target (#4976).
|
|
1641
|
+
if (RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(errorStr))) {
|
|
1642
|
+
return buildRetryableFallback(RateLimitReason.RATE_LIMIT_EXCEEDED);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// Generic 400 is not account-fallback-worthy. Combo routing may still try a
|
|
1646
|
+
// different provider/model because combo fallback is target-level orchestration.
|
|
1647
|
+
return { shouldFallback: false, cooldownMs: 0, reason: RateLimitReason.UNKNOWN };
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
// All other errors - fallback with transient cooldown
|
|
1651
|
+
return {
|
|
1652
|
+
shouldFallback: true,
|
|
1653
|
+
cooldownMs: profile?.baseCooldownMs ?? COOLDOWN_MS.transient,
|
|
1654
|
+
baseCooldownMs: profile?.baseCooldownMs ?? COOLDOWN_MS.transient,
|
|
1655
|
+
reason: RateLimitReason.UNKNOWN,
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// ─── Account State Management ───────────────────────────────────────────────
|
|
1660
|
+
|
|
1661
|
+
/**
|
|
1662
|
+
* Normalize a stored cooldown timestamp to epoch milliseconds.
|
|
1663
|
+
*
|
|
1664
|
+
* `rate_limited_until` is a TEXT column, but some write paths persist a raw
|
|
1665
|
+
* epoch NUMBER (e.g. `setConnectionRateLimitUntil` on the Antigravity full-quota
|
|
1666
|
+
* path). SQLite TEXT affinity coerces it to a numeric string like
|
|
1667
|
+
* "1781696905131.0", which `new Date(...)` cannot parse (→ NaN). Accept numeric
|
|
1668
|
+
* epoch strings/numbers as well as ISO strings and Date objects (#3954).
|
|
1669
|
+
*/
|
|
1670
|
+
export function cooldownUntilMs(value: string | number | Date | null | undefined): number {
|
|
1671
|
+
if (value === null || value === undefined || value === "") return NaN;
|
|
1672
|
+
if (value instanceof Date) return value.getTime();
|
|
1673
|
+
if (typeof value === "number") return value;
|
|
1674
|
+
const raw = value.trim();
|
|
1675
|
+
if (/^\d+(\.\d+)?$/.test(raw)) return Number(raw);
|
|
1676
|
+
return new Date(raw).getTime();
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
/**
|
|
1680
|
+
* Check if account is currently unavailable (cooldown not expired)
|
|
1681
|
+
*/
|
|
1682
|
+
export function isAccountUnavailable(unavailableUntil: string | Date | null | undefined): boolean {
|
|
1683
|
+
if (!unavailableUntil) return false;
|
|
1684
|
+
const ms = cooldownUntilMs(unavailableUntil);
|
|
1685
|
+
return Number.isFinite(ms) && ms > Date.now();
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
/**
|
|
1689
|
+
* Calculate unavailable until timestamp
|
|
1690
|
+
*/
|
|
1691
|
+
export function getUnavailableUntil(cooldownMs: number): string {
|
|
1692
|
+
return new Date(Date.now() + cooldownMs).toISOString();
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/**
|
|
1696
|
+
* Get the earliest rateLimitedUntil from a list of accounts
|
|
1697
|
+
*/
|
|
1698
|
+
export function getEarliestRateLimitedUntil(
|
|
1699
|
+
accounts: Array<{ rateLimitedUntil?: string | null }>
|
|
1700
|
+
): string | null {
|
|
1701
|
+
let earliest: number | null = null;
|
|
1702
|
+
const now = Date.now();
|
|
1703
|
+
for (const acc of accounts) {
|
|
1704
|
+
if (!acc.rateLimitedUntil) continue;
|
|
1705
|
+
const until = cooldownUntilMs(acc.rateLimitedUntil);
|
|
1706
|
+
if (!Number.isFinite(until) || until <= now) continue;
|
|
1707
|
+
if (!earliest || until < earliest) earliest = until;
|
|
1708
|
+
}
|
|
1709
|
+
if (!earliest) return null;
|
|
1710
|
+
return new Date(earliest).toISOString();
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/**
|
|
1714
|
+
* Format rateLimitedUntil to human-readable "reset after Xm Ys"
|
|
1715
|
+
*/
|
|
1716
|
+
export function formatRetryAfter(
|
|
1717
|
+
rateLimitedUntil: string | number | Date | null | undefined
|
|
1718
|
+
): string {
|
|
1719
|
+
if (!rateLimitedUntil) return "";
|
|
1720
|
+
const diffMs = new Date(rateLimitedUntil).getTime() - Date.now();
|
|
1721
|
+
if (diffMs <= 0) return "reset after 0s";
|
|
1722
|
+
const totalSec = Math.ceil(diffMs / 1000);
|
|
1723
|
+
const h = Math.floor(totalSec / 3600);
|
|
1724
|
+
const m = Math.floor((totalSec % 3600) / 60);
|
|
1725
|
+
const s = totalSec % 60;
|
|
1726
|
+
const parts: string[] = [];
|
|
1727
|
+
if (h > 0) parts.push(`${h}h`);
|
|
1728
|
+
if (m > 0) parts.push(`${m}m`);
|
|
1729
|
+
if (s > 0 || parts.length === 0) parts.push(`${s}s`);
|
|
1730
|
+
return `reset after ${parts.join(" ")}`;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
/**
|
|
1734
|
+
* Filter available accounts (not in cooldown)
|
|
1735
|
+
*/
|
|
1736
|
+
export function filterAvailableAccounts<T extends AccountState>(
|
|
1737
|
+
accounts: T[],
|
|
1738
|
+
excludeId: string | null = null
|
|
1739
|
+
): T[] {
|
|
1740
|
+
const now = Date.now();
|
|
1741
|
+
return accounts.filter((acc) => {
|
|
1742
|
+
if (excludeId && acc.id === excludeId) return false;
|
|
1743
|
+
if (acc.rateLimitedUntil) {
|
|
1744
|
+
const until = cooldownUntilMs(acc.rateLimitedUntil);
|
|
1745
|
+
if (Number.isFinite(until) && until > now) return false;
|
|
1746
|
+
}
|
|
1747
|
+
return true;
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Reset account state when request succeeds
|
|
1753
|
+
*/
|
|
1754
|
+
export function resetAccountState<T extends AccountState | null | undefined>(
|
|
1755
|
+
account: T
|
|
1756
|
+
): T | AccountState {
|
|
1757
|
+
if (!account) return account;
|
|
1758
|
+
// Persist the cooldown clear so a successfully-retried connection is no longer
|
|
1759
|
+
// marked as rate-limited in `provider_connections.rate_limited_until`. Mirrors
|
|
1760
|
+
// Fix A: the in-memory AccountState and the DB row must agree so the cascade
|
|
1761
|
+
// survives the request boundary and `clearStaleCrashCooldowns` doesn't have
|
|
1762
|
+
// to rediscover what we already know is healthy.
|
|
1763
|
+
// Best-effort: a DB write failure must not crash the request path.
|
|
1764
|
+
const connId = (account as AccountState | null | undefined)?.id;
|
|
1765
|
+
if (typeof connId === "string" && connId.length > 0) {
|
|
1766
|
+
try {
|
|
1767
|
+
setConnectionRateLimitUntil(connId, null);
|
|
1768
|
+
} catch {
|
|
1769
|
+
// ignore — best effort
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
return {
|
|
1773
|
+
...account,
|
|
1774
|
+
rateLimitedUntil: null,
|
|
1775
|
+
backoffLevel: 0,
|
|
1776
|
+
lastError: null,
|
|
1777
|
+
status: "active",
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
/**
|
|
1782
|
+
* Apply error state to account
|
|
1783
|
+
*/
|
|
1784
|
+
export function applyErrorState<T extends AccountState | null | undefined>(
|
|
1785
|
+
account: T,
|
|
1786
|
+
status: number,
|
|
1787
|
+
errorText: string | null,
|
|
1788
|
+
provider: string | null = null
|
|
1789
|
+
): T | AccountState {
|
|
1790
|
+
if (!account) return account;
|
|
1791
|
+
|
|
1792
|
+
const backoffLevel = account.backoffLevel || 0;
|
|
1793
|
+
const fallbackDecision = checkFallbackError(status, errorText, backoffLevel, null, provider);
|
|
1794
|
+
const { cooldownMs, reason } = fallbackDecision;
|
|
1795
|
+
const newBackoffLevel =
|
|
1796
|
+
"newBackoffLevel" in fallbackDecision ? fallbackDecision.newBackoffLevel : undefined;
|
|
1797
|
+
|
|
1798
|
+
// Cooldown may be overridden by a configured provider rule (see
|
|
1799
|
+
// `accountFallback.ts:1511-1540` provider-match branch + the
|
|
1800
|
+
// `providerMatch.cooldownMs` thread-through added by Fix C). When the
|
|
1801
|
+
// configured rule sets an explicit cooldownMs, it wins over the scaled
|
|
1802
|
+
// backoff default that `checkFallbackError` returned.
|
|
1803
|
+
const configuredCooldownMs =
|
|
1804
|
+
"configuredCooldownMs" in fallbackDecision
|
|
1805
|
+
? (fallbackDecision as { configuredCooldownMs?: number }).configuredCooldownMs
|
|
1806
|
+
: undefined;
|
|
1807
|
+
const effectiveCooldownMs =
|
|
1808
|
+
typeof configuredCooldownMs === "number" && configuredCooldownMs > 0
|
|
1809
|
+
? configuredCooldownMs
|
|
1810
|
+
: cooldownMs;
|
|
1811
|
+
|
|
1812
|
+
const nextState: T | AccountState = {
|
|
1813
|
+
...account,
|
|
1814
|
+
rateLimitedUntil: effectiveCooldownMs > 0 ? getUnavailableUntil(effectiveCooldownMs) : null,
|
|
1815
|
+
backoffLevel: newBackoffLevel ?? backoffLevel,
|
|
1816
|
+
lastError: { status, message: errorText, timestamp: new Date().toISOString(), reason },
|
|
1817
|
+
status: "error",
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
// Persist the cooldown to `provider_connections.rate_limited_until` so the
|
|
1821
|
+
// cascade survives the request boundary. Before Fix A the cooldown only
|
|
1822
|
+
// lived in the in-memory AccountState object returned here, which was
|
|
1823
|
+
// discarded the moment the request ended — the same exhausted key was
|
|
1824
|
+
// re-picked on the very next request.
|
|
1825
|
+
// Best-effort try/catch mirrors `open-sse/executors/antigravity.ts:343`
|
|
1826
|
+
// (`markConnectionQuotaExhausted`) so a DB failure can never crash the
|
|
1827
|
+
// chat path. See issue #1 (per-account 429 cascade not persisting).
|
|
1828
|
+
const connId = (account as AccountState | null | undefined)?.id;
|
|
1829
|
+
if (
|
|
1830
|
+
typeof connId === "string" &&
|
|
1831
|
+
connId.length > 0 &&
|
|
1832
|
+
effectiveCooldownMs > 0 &&
|
|
1833
|
+
nextState.rateLimitedUntil
|
|
1834
|
+
) {
|
|
1835
|
+
try {
|
|
1836
|
+
const untilMs = cooldownUntilMs(nextState.rateLimitedUntil);
|
|
1837
|
+
if (Number.isFinite(untilMs) && untilMs > Date.now()) {
|
|
1838
|
+
setConnectionRateLimitUntil(connId, untilMs);
|
|
1839
|
+
}
|
|
1840
|
+
} catch {
|
|
1841
|
+
// ignore — best effort
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
return nextState;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
/**
|
|
1849
|
+
* Get account health score (0-100) for P2C selection (Phase 9)
|
|
1850
|
+
* @param {object} account
|
|
1851
|
+
* @returns {number} score 0 = unhealthy, 100 = perfectly healthy
|
|
1852
|
+
*/
|
|
1853
|
+
export function getAccountHealth(
|
|
1854
|
+
account: AccountState | null | undefined,
|
|
1855
|
+
model?: unknown
|
|
1856
|
+
): number {
|
|
1857
|
+
if (!account) return 0;
|
|
1858
|
+
let score = 100;
|
|
1859
|
+
score -= (account.backoffLevel || 0) * 10;
|
|
1860
|
+
if (account.lastError) score -= 20;
|
|
1861
|
+
if (account.rateLimitedUntil && isAccountUnavailable(account.rateLimitedUntil)) score -= 30;
|
|
1862
|
+
return Math.max(0, score);
|
|
1863
|
+
}
|