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,2180 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import { PROVIDERS, OAUTH_ENDPOINTS } from "../config/constants.ts";
|
|
4
|
+
import { getGitHubCopilotRefreshHeaders } from "../config/providerHeaderProfiles.ts";
|
|
5
|
+
import { pbkdf2Sync } from "node:crypto";
|
|
6
|
+
import { runWithProxyContext } from "../utils/proxyFetch.ts";
|
|
7
|
+
import { serializeRefresh, wasRefreshTokenRotated } from "./refreshSerializer.ts";
|
|
8
|
+
import { WINDSURF_CONFIG } from "@/lib/oauth/constants/oauth";
|
|
9
|
+
import { buildGitLabOAuthEndpoints, resolveGitLabOAuthBaseUrl } from "@/lib/oauth/gitlab";
|
|
10
|
+
|
|
11
|
+
// Default token expiry buffer (refresh if expires within 5 minutes).
|
|
12
|
+
// Used as fallback for providers without an explicit lead time in
|
|
13
|
+
// REFRESH_LEAD_MS below.
|
|
14
|
+
export const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
// Per-provider proactive-refresh lead time.
|
|
17
|
+
//
|
|
18
|
+
// For multi-account OAuth on providers that enforce "single active session per
|
|
19
|
+
// client_id" (notably OpenAI Codex / Auth0), refreshing one account's token
|
|
20
|
+
// can invalidate the refresh_token family of OTHER accounts under the same
|
|
21
|
+
// client. We MINIMIZE refresh frequency for these providers: stay on the
|
|
22
|
+
// original access_token until it is genuinely about to expire, so each account
|
|
23
|
+
// gets the full access_token lifetime without triggering Auth0's family-
|
|
24
|
+
// invalidation logic on its siblings.
|
|
25
|
+
//
|
|
26
|
+
// Trade-off: when refresh finally happens (last 5 min before expiry), Auth0
|
|
27
|
+
// MAY invalidate other accounts' refresh_tokens. The user must re-auth those.
|
|
28
|
+
// This is the upstream limitation documented in openai/codex#9648.
|
|
29
|
+
//
|
|
30
|
+
// Providers with non-rotating tokens (Google, Anthropic) or where multi-
|
|
31
|
+
// account is naturally isolated keep longer lead times.
|
|
32
|
+
export const REFRESH_LEAD_MS: Record<string, number> = {
|
|
33
|
+
// Rotating refresh tokens — minimize refresh frequency to avoid the
|
|
34
|
+
// "refresh-invalidates-siblings" cascade documented for OpenAI Auth0.
|
|
35
|
+
codex: 5 * 60 * 1000, // 5 minutes
|
|
36
|
+
openai: 5 * 60 * 1000, // same Auth0 backend as codex
|
|
37
|
+
claude: 5 * 60 * 1000, // Anthropic OAuth rotates refresh_tokens (user-reported)
|
|
38
|
+
"gitlab-duo": 5 * 60 * 1000, // GitLab token family revocation on misuse
|
|
39
|
+
kiro: 5 * 60 * 1000, // AWS SSO OIDC issues one-time-use refresh tokens
|
|
40
|
+
"kimi-coding": 5 * 60 * 1000, // Moonshot rotates per-refresh
|
|
41
|
+
qwen: 5 * 60 * 1000, // Alibaba device-code path also rotates
|
|
42
|
+
// Non-rotating providers — longer lead is safe.
|
|
43
|
+
iflow: 24 * 60 * 60 * 1000, // 24 hours
|
|
44
|
+
// Google OAuth refresh_tokens are permanent (non-rotating) — longer lead
|
|
45
|
+
// is safe and reduces unnecessary upstream chatter.
|
|
46
|
+
antigravity: 15 * 60 * 1000,
|
|
47
|
+
agy: 15 * 60 * 1000, // same Google backend as antigravity (non-rotating refresh tokens)
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get the proactive refresh lead time (ms) for a given provider.
|
|
52
|
+
*
|
|
53
|
+
* Precedence:
|
|
54
|
+
* 1. A per-connection override in `providerSpecificData.refreshLeadMs`
|
|
55
|
+
* (must be a positive finite number), so an operator can tune the lead
|
|
56
|
+
* time for a single connection without touching the provider defaults.
|
|
57
|
+
* 2. The provider default from REFRESH_LEAD_MS.
|
|
58
|
+
* 3. TOKEN_EXPIRY_BUFFER_MS (5 min) when nothing else applies.
|
|
59
|
+
*/
|
|
60
|
+
export function getRefreshLeadMs(
|
|
61
|
+
provider: string,
|
|
62
|
+
providerSpecificData?: { refreshLeadMs?: unknown } | null
|
|
63
|
+
): number {
|
|
64
|
+
const override = providerSpecificData?.refreshLeadMs;
|
|
65
|
+
if (typeof override === "number" && Number.isFinite(override) && override > 0) {
|
|
66
|
+
return override;
|
|
67
|
+
}
|
|
68
|
+
return REFRESH_LEAD_MS[provider] ?? TOKEN_EXPIRY_BUFFER_MS;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const CACHE_SECRET = "omniroute-token-cache";
|
|
72
|
+
|
|
73
|
+
// In-flight refresh promise cache to prevent race conditions
|
|
74
|
+
// Key: "provider:sha256(refreshToken)" → Value: Promise<result>
|
|
75
|
+
const refreshPromiseCache = new Map();
|
|
76
|
+
|
|
77
|
+
// Per-connection mutex: prevents parallel OAuth refresh for rotating tokens.
|
|
78
|
+
// Key: connectionId → Value: { promise, waiters }
|
|
79
|
+
// Primary dedup when credentials.connectionId is present; refreshPromiseCache is fallback.
|
|
80
|
+
const connectionRefreshMutex = new Map();
|
|
81
|
+
|
|
82
|
+
// ─── Token Rotation Map (codex-multi-auth pattern) ─────────────────────────
|
|
83
|
+
//
|
|
84
|
+
// When a rotating-token provider (Codex, Kimi, GitLab Duo, etc.) refreshes,
|
|
85
|
+
// the old refresh_token is consumed and a new one is issued. Any subsequent
|
|
86
|
+
// caller arriving with the OLD token would, without protection, hit upstream
|
|
87
|
+
// and trigger "refresh_token_reused" — which Auth0 treats as a security event
|
|
88
|
+
// and invalidates the entire token family.
|
|
89
|
+
//
|
|
90
|
+
// This in-memory map caches RECENT rotations so a stale caller can be redirected
|
|
91
|
+
// to the new tokens WITHOUT touching upstream. The DB staleness check inside
|
|
92
|
+
// the per-connection mutex covers the same scenario when connectionId is known,
|
|
93
|
+
// but not all callers pass connectionId (e.g., legacy code paths, retries that
|
|
94
|
+
// snapshot credentials before the rotation lands in DB).
|
|
95
|
+
//
|
|
96
|
+
// Ported from ndycode/codex-multi-auth (lib/refresh-queue.ts:218-248), the only
|
|
97
|
+
// publicly known tool that reliably sustains multiple Codex OAuth accounts.
|
|
98
|
+
//
|
|
99
|
+
// Key format: `provider:sha256(oldRefreshToken)`
|
|
100
|
+
// Value: { result: tokens, expiresAt: ms_since_epoch }
|
|
101
|
+
type RotationEntry = {
|
|
102
|
+
result: { accessToken: string; refreshToken: string; expiresIn?: number; expiresAt?: string };
|
|
103
|
+
expiresAt: number;
|
|
104
|
+
};
|
|
105
|
+
const tokenRotationMap = new Map<string, RotationEntry>();
|
|
106
|
+
const ROTATION_MAP_TTL_MS = 60 * 1000; // 60 seconds — long enough to catch in-flight stale callers
|
|
107
|
+
|
|
108
|
+
function cleanupRotationMap(now: number = Date.now()): void {
|
|
109
|
+
if (tokenRotationMap.size === 0) return;
|
|
110
|
+
for (const [key, entry] of tokenRotationMap.entries()) {
|
|
111
|
+
if (entry.expiresAt <= now) tokenRotationMap.delete(key);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function lookupRotation(provider: string, refreshToken: string): RotationEntry | undefined {
|
|
116
|
+
cleanupRotationMap();
|
|
117
|
+
const key = getRefreshCacheKey(provider, refreshToken);
|
|
118
|
+
const entry = tokenRotationMap.get(key);
|
|
119
|
+
if (!entry) return undefined;
|
|
120
|
+
if (entry.expiresAt <= Date.now()) {
|
|
121
|
+
tokenRotationMap.delete(key);
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return entry;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function recordRotation(
|
|
128
|
+
provider: string,
|
|
129
|
+
oldRefreshToken: string,
|
|
130
|
+
result: { accessToken: string; refreshToken: string; expiresIn?: number; expiresAt?: string }
|
|
131
|
+
): void {
|
|
132
|
+
if (!oldRefreshToken || !result.refreshToken || oldRefreshToken === result.refreshToken) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const key = getRefreshCacheKey(provider, oldRefreshToken);
|
|
136
|
+
tokenRotationMap.set(key, {
|
|
137
|
+
result,
|
|
138
|
+
expiresAt: Date.now() + ROTATION_MAP_TTL_MS,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Exported for tests + diagnostics; not part of the public API surface.
|
|
143
|
+
export function _getTokenRotationMapStats(): { size: number; entries: number } {
|
|
144
|
+
cleanupRotationMap();
|
|
145
|
+
return { size: tokenRotationMap.size, entries: tokenRotationMap.size };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function _clearTokenRotationMap(): void {
|
|
149
|
+
tokenRotationMap.clear();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// AsyncLocalStorage for plumbing `onPersist` through executor.refreshCredentials
|
|
153
|
+
// without modifying every executor's signature. The chatCore.ts / base.ts call
|
|
154
|
+
// sites wrap executor.refreshCredentials in `runWithOnPersist(persistFn, () => ...)`
|
|
155
|
+
// and `getAccessToken` reads the active store as a fallback when no explicit
|
|
156
|
+
// onPersist parameter is provided. This keeps Fix A's atomic [refresh + persist]
|
|
157
|
+
// guarantee while avoiding per-executor signature changes.
|
|
158
|
+
type RefreshPersistResult = Record<string, unknown>;
|
|
159
|
+
type RefreshPersistFn = (result: RefreshPersistResult) => Promise<void>;
|
|
160
|
+
const onPersistStore = new AsyncLocalStorage<RefreshPersistFn>();
|
|
161
|
+
|
|
162
|
+
export function runWithOnPersist<T>(
|
|
163
|
+
onPersist: RefreshPersistFn | undefined | null,
|
|
164
|
+
fn: () => Promise<T>
|
|
165
|
+
): Promise<T> {
|
|
166
|
+
if (!onPersist) return fn();
|
|
167
|
+
return onPersistStore.run(onPersist, fn);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function getActiveOnPersist(): RefreshPersistFn | undefined {
|
|
171
|
+
return onPersistStore.getStore();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ── #4038: compare-and-swap (CAS) guard on the refresh persist ───────────────
|
|
175
|
+
// Fix A makes [network refresh + DB write] atomic *for a single connection's
|
|
176
|
+
// mutex*. It does NOT protect against a THIRD writer (a sibling process, a
|
|
177
|
+
// concurrent HealthCheck, or a replica) landing a fresher rotation on the same
|
|
178
|
+
// `connection_id` between the moment the caller read the row and the moment this
|
|
179
|
+
// persist runs. Overwriting that fresher row reverts the sibling's rotation, the
|
|
180
|
+
// next caller loads the reverted (now-consumed) refresh_token, and Auth0/Anthropic
|
|
181
|
+
// revoke the whole token family (the 1352× claude/aa5dd5cf invalidation storm).
|
|
182
|
+
//
|
|
183
|
+
// The CAS guard carries the refresh_token the caller PRESENTED (the version token,
|
|
184
|
+
// since refresh_tokens rotate on every refresh) plus a `reread` of the row's
|
|
185
|
+
// current refresh_token. Right before persisting, `getAccessToken` re-reads and, if
|
|
186
|
+
// a concurrent writer already rotated the row past the presented token, SKIPS the
|
|
187
|
+
// persist so the DB stays at the fresher state. The caller still receives the new
|
|
188
|
+
// accessToken — upstream already authenticated the request; only the DB write is
|
|
189
|
+
// skipped. No active guard ⇒ behavior is byte-identical to before (opt-in).
|
|
190
|
+
type CasGuard = {
|
|
191
|
+
/** The refresh_token the caller presented for this refresh (CAS version token). */
|
|
192
|
+
expectedRefreshToken: string | null;
|
|
193
|
+
/** Re-reads the CURRENT persisted refresh_token for this connection (decrypted). */
|
|
194
|
+
reread: () => Promise<string | null | undefined>;
|
|
195
|
+
};
|
|
196
|
+
const casGuardStore = new AsyncLocalStorage<CasGuard>();
|
|
197
|
+
const casGuardStats = { skipped: 0, persisted: 0 };
|
|
198
|
+
|
|
199
|
+
export function runWithCasGuard<T>(
|
|
200
|
+
guard: CasGuard | undefined | null,
|
|
201
|
+
fn: () => Promise<T>
|
|
202
|
+
): Promise<T> {
|
|
203
|
+
if (!guard) return fn();
|
|
204
|
+
return casGuardStore.run(guard, fn);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function getActiveCasGuard(): CasGuard | undefined {
|
|
208
|
+
return casGuardStore.getStore();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Skip/persist counters for observability + tests. */
|
|
212
|
+
export function getCasGuardStats(): { skipped: number; persisted: number } {
|
|
213
|
+
return { ...casGuardStats };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Test-only: reset the CAS counters between cases. */
|
|
217
|
+
export function _resetCasGuardStats(): void {
|
|
218
|
+
casGuardStats.skipped = 0;
|
|
219
|
+
casGuardStats.persisted = 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Returns true when the persist should be SKIPPED because a concurrent writer
|
|
224
|
+
* already rotated the row's refresh_token past the one we presented (CAS mismatch).
|
|
225
|
+
* Best-effort: any reread failure falls through to persist (never blocks recovery).
|
|
226
|
+
*/
|
|
227
|
+
async function casGuardShouldSkipPersist(log?: RefreshLogger): Promise<boolean> {
|
|
228
|
+
const guard = getActiveCasGuard();
|
|
229
|
+
if (!guard || !guard.expectedRefreshToken) return false;
|
|
230
|
+
let current: string | null | undefined;
|
|
231
|
+
try {
|
|
232
|
+
current = await guard.reread();
|
|
233
|
+
} catch {
|
|
234
|
+
return false; // reread failed — fall through to persist (best-effort)
|
|
235
|
+
}
|
|
236
|
+
// wasRefreshTokenRotated is true iff both are non-empty AND current !== expected.
|
|
237
|
+
if (wasRefreshTokenRotated(guard.expectedRefreshToken, current)) {
|
|
238
|
+
casGuardStats.skipped++;
|
|
239
|
+
log?.warn?.(
|
|
240
|
+
"TOKEN_REFRESH",
|
|
241
|
+
"CAS guard: skipping persist — a concurrent writer already rotated the refresh_token (#4038)"
|
|
242
|
+
);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
casGuardStats.persisted++;
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
type RefreshLogger = {
|
|
250
|
+
info?: (tag: string, message: string, data?: Record<string, unknown>) => void;
|
|
251
|
+
warn?: (tag: string, message: string, data?: Record<string, unknown>) => void;
|
|
252
|
+
error?: (tag: string, message: string, data?: Record<string, unknown>) => void;
|
|
253
|
+
debug?: (tag: string, message: string, data?: Record<string, unknown>) => void;
|
|
254
|
+
} | null;
|
|
255
|
+
|
|
256
|
+
function buildFormParams(entries: Record<string, unknown>): URLSearchParams {
|
|
257
|
+
const params = new URLSearchParams();
|
|
258
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
259
|
+
if (typeof value === "string" && value.length > 0) {
|
|
260
|
+
params.set(key, value);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return params;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function getRefreshCacheKey(provider, refreshToken) {
|
|
267
|
+
const tokenHash = pbkdf2Sync(refreshToken, CACHE_SECRET, 1000, 32, "sha256").toString("hex");
|
|
268
|
+
return `${provider}:${tokenHash}`;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* OAuth2 error codes that mean the refresh token is permanently dead and
|
|
273
|
+
* retrying will never succeed → callers must emit the unrecoverable sentinel
|
|
274
|
+
* so the HealthCheck deactivates the account instead of looping every 60s.
|
|
275
|
+
* Deliberately EXCLUDES transient codes (server_error, temporarily_unavailable,
|
|
276
|
+
* slow_down) so we never deactivate an account over a recoverable blip.
|
|
277
|
+
*/
|
|
278
|
+
const UNRECOVERABLE_OAUTH_ERROR_CODES = new Set([
|
|
279
|
+
"invalid_grant",
|
|
280
|
+
"invalid_request",
|
|
281
|
+
"refresh_token_reused",
|
|
282
|
+
"invalid_token",
|
|
283
|
+
"expired_token",
|
|
284
|
+
"unauthorized_client",
|
|
285
|
+
"access_denied",
|
|
286
|
+
]);
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Extract a canonical OAuth error code from a refresh-endpoint error body of
|
|
290
|
+
* ANY shape. Production proxies/MITMs deliver the same `invalid_grant` 400 in
|
|
291
|
+
* several shapes — a plain object `{error:"invalid_grant"}`, a nested
|
|
292
|
+
* `{error:{code:"invalid_grant"}}`, a JSON **string** (double-encoded body),
|
|
293
|
+
* or the raw JSON text wrapped as `{error:"<json text>"}` by a catch branch.
|
|
294
|
+
* The old `errorBody.error === "invalid_grant"` only matched the first shape,
|
|
295
|
+
* so the others returned `null` → the HealthCheck refresh loop (root cause of
|
|
296
|
+
* the 1352× claude/aa5dd5cf invalidation storm).
|
|
297
|
+
*
|
|
298
|
+
* Returns the matched code (only if it is in UNRECOVERABLE_OAUTH_ERROR_CODES)
|
|
299
|
+
* or null. Never matches loosely — a known code is accepted only when it is a
|
|
300
|
+
* bare code string or the value of an `"error"`/`"error_code"` field, so a 502
|
|
301
|
+
* HTML page or a `server_error` body never becomes a false positive.
|
|
302
|
+
*/
|
|
303
|
+
export function extractOAuthErrorCode(raw: unknown, depth = 0): string | null {
|
|
304
|
+
if (raw == null || depth > 6) return null;
|
|
305
|
+
|
|
306
|
+
if (typeof raw === "string") {
|
|
307
|
+
const s = raw.trim();
|
|
308
|
+
if (!s) return null;
|
|
309
|
+
if (UNRECOVERABLE_OAUTH_ERROR_CODES.has(s)) return s;
|
|
310
|
+
// The string may itself be JSON (a double-encoded body, or the raw text).
|
|
311
|
+
if (s[0] === "{" || s[0] === "[" || s[0] === '"') {
|
|
312
|
+
try {
|
|
313
|
+
const nested = extractOAuthErrorCode(JSON.parse(s), depth + 1);
|
|
314
|
+
if (nested) return nested;
|
|
315
|
+
} catch {
|
|
316
|
+
// not valid JSON — fall through to the field scan
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// Safety net: a known code appearing as the value of an "error"/"error_code"
|
|
320
|
+
// field inside otherwise-unparsed text. Scoped to avoid false positives.
|
|
321
|
+
const m = s.match(/"error(?:_code)?"\s*:\s*"([a-z_]+)"/i);
|
|
322
|
+
if (m && UNRECOVERABLE_OAUTH_ERROR_CODES.has(m[1])) return m[1];
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (typeof raw === "object") {
|
|
327
|
+
const o = raw as Record<string, unknown>;
|
|
328
|
+
return (
|
|
329
|
+
extractOAuthErrorCode(o.error, depth + 1) ??
|
|
330
|
+
extractOAuthErrorCode(o.code, depth + 1) ??
|
|
331
|
+
extractOAuthErrorCode(o.error_code, depth + 1)
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Read an error response body ONCE and classify it. Returns the raw text (for
|
|
340
|
+
* logging) and the extracted unrecoverable OAuth code (or null). Reading once
|
|
341
|
+
* avoids the double-read bug where `response.json()` consumes the stream and a
|
|
342
|
+
* later `response.text()` returns empty.
|
|
343
|
+
*/
|
|
344
|
+
async function readRefreshErrorBody(
|
|
345
|
+
response: Response
|
|
346
|
+
): Promise<{ rawText: string; code: string | null }> {
|
|
347
|
+
const rawText = await response.text().catch(() => "");
|
|
348
|
+
let parsed: unknown = rawText;
|
|
349
|
+
try {
|
|
350
|
+
parsed = JSON.parse(rawText);
|
|
351
|
+
} catch {
|
|
352
|
+
// keep rawText as-is
|
|
353
|
+
}
|
|
354
|
+
const code = extractOAuthErrorCode(parsed) ?? extractOAuthErrorCode(rawText);
|
|
355
|
+
return { rawText, code };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Refresh OAuth access token using refresh token
|
|
360
|
+
*/
|
|
361
|
+
export async function refreshAccessToken(
|
|
362
|
+
provider,
|
|
363
|
+
refreshToken,
|
|
364
|
+
credentials,
|
|
365
|
+
log,
|
|
366
|
+
proxyConfig: unknown = null
|
|
367
|
+
) {
|
|
368
|
+
const config = PROVIDERS[provider];
|
|
369
|
+
|
|
370
|
+
const refreshEndpoint = config?.refreshUrl || config?.tokenUrl;
|
|
371
|
+
if (!config || !refreshEndpoint) {
|
|
372
|
+
log?.warn?.("TOKEN_REFRESH", `No refresh endpoint configured for provider: ${provider}`);
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (!refreshToken) {
|
|
377
|
+
log?.warn?.("TOKEN_REFRESH", `No refresh token available for provider: ${provider}`);
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
const params = new URLSearchParams({
|
|
383
|
+
grant_type: "refresh_token",
|
|
384
|
+
refresh_token: refreshToken,
|
|
385
|
+
});
|
|
386
|
+
if (config.clientId) params.set("client_id", config.clientId);
|
|
387
|
+
if (config.clientSecret) params.set("client_secret", config.clientSecret);
|
|
388
|
+
|
|
389
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
390
|
+
fetch(refreshEndpoint, {
|
|
391
|
+
method: "POST",
|
|
392
|
+
headers: {
|
|
393
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
394
|
+
Accept: "application/json",
|
|
395
|
+
},
|
|
396
|
+
body: params,
|
|
397
|
+
})
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
if (!response.ok) {
|
|
401
|
+
const errorText = await response.text();
|
|
402
|
+
log?.error?.("TOKEN_REFRESH", `Failed to refresh token for ${provider}`, {
|
|
403
|
+
status: response.status,
|
|
404
|
+
error: errorText,
|
|
405
|
+
});
|
|
406
|
+
const code = extractOAuthErrorCode(errorText);
|
|
407
|
+
if (code === "invalid_grant" || code === "invalid_request") {
|
|
408
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
409
|
+
}
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const tokens = await response.json();
|
|
414
|
+
|
|
415
|
+
log?.info?.("TOKEN_REFRESH", `Successfully refreshed token for ${provider}`, {
|
|
416
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
417
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
418
|
+
expiresIn: tokens.expires_in,
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
accessToken: tokens.access_token,
|
|
423
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
424
|
+
expiresIn: tokens.expires_in,
|
|
425
|
+
};
|
|
426
|
+
} catch (error) {
|
|
427
|
+
log?.error?.("TOKEN_REFRESH", `Error refreshing token for ${provider}`, {
|
|
428
|
+
error: error.message,
|
|
429
|
+
});
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Specialized refresh for Cline OAuth tokens.
|
|
436
|
+
* Cline refresh endpoint expects JSON body and returns camelCase fields.
|
|
437
|
+
*/
|
|
438
|
+
/**
|
|
439
|
+
* Refresh Windsurf (Devin CLI / Codeium) tokens.
|
|
440
|
+
*
|
|
441
|
+
* Windsurf uses Firebase Secure Token Service (STS) for token refresh.
|
|
442
|
+
* If the token is a long-lived Codeium API key (import flow), it never
|
|
443
|
+
* expires and refresh is a no-op returning the same token.
|
|
444
|
+
* If the token is a Firebase ID token (device-code flow), it expires after
|
|
445
|
+
* ~1 hour and can be refreshed with the stored Firebase refresh token.
|
|
446
|
+
*/
|
|
447
|
+
export async function refreshWindsurfToken(
|
|
448
|
+
refreshToken: string,
|
|
449
|
+
providerSpecificData: Record<string, unknown> | null | undefined,
|
|
450
|
+
log: RefreshLogger,
|
|
451
|
+
proxyConfig: unknown = null
|
|
452
|
+
) {
|
|
453
|
+
if (!refreshToken) {
|
|
454
|
+
log?.warn?.(
|
|
455
|
+
"TOKEN_REFRESH",
|
|
456
|
+
"No refresh token stored for Windsurf — token may be a long-lived API key"
|
|
457
|
+
);
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const authMethod = (providerSpecificData?.authMethod as string) || "import";
|
|
462
|
+
|
|
463
|
+
// Long-lived Codeium API keys (import flow) have no expiry — nothing to refresh.
|
|
464
|
+
if (authMethod === "import") {
|
|
465
|
+
log?.debug?.("TOKEN_REFRESH", "Windsurf import token is long-lived — no refresh needed");
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Firebase STS refresh for browser-flow tokens.
|
|
470
|
+
// Resolves via WINDSURF_CONFIG.firebaseApiKey, which honors the
|
|
471
|
+
// WINDSURF_FIREBASE_API_KEY env override and falls back to the embedded
|
|
472
|
+
// public default in publicCreds.ts. See docs/security/PUBLIC_CREDS.md.
|
|
473
|
+
const firebaseApiKey = WINDSURF_CONFIG.firebaseApiKey || "";
|
|
474
|
+
if (!firebaseApiKey) {
|
|
475
|
+
log?.warn?.(
|
|
476
|
+
"TOKEN_REFRESH",
|
|
477
|
+
"Windsurf Firebase API key unavailable — skipping Firebase token refresh"
|
|
478
|
+
);
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
const tokenUrl = `https://securetoken.googleapis.com/v1/token?key=${firebaseApiKey}`;
|
|
482
|
+
|
|
483
|
+
try {
|
|
484
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
485
|
+
fetch(tokenUrl, {
|
|
486
|
+
method: "POST",
|
|
487
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
488
|
+
body: buildFormParams({ grant_type: "refresh_token", refresh_token: refreshToken }),
|
|
489
|
+
})
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
const errorText = await response.text();
|
|
494
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Windsurf Firebase token", {
|
|
495
|
+
status: response.status,
|
|
496
|
+
error: errorText.slice(0, 200),
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// Firebase STS returns structured errors. Detect unrecoverable token states.
|
|
500
|
+
try {
|
|
501
|
+
const fbError = JSON.parse(errorText);
|
|
502
|
+
const fbCode =
|
|
503
|
+
typeof fbError?.error?.message === "string"
|
|
504
|
+
? fbError.error.message
|
|
505
|
+
: typeof fbError?.error === "string"
|
|
506
|
+
? fbError.error
|
|
507
|
+
: null;
|
|
508
|
+
if (
|
|
509
|
+
typeof fbCode === "string" &&
|
|
510
|
+
(fbCode.includes("USER_DISABLED") ||
|
|
511
|
+
fbCode.includes("TOKEN_EXPIRED") ||
|
|
512
|
+
fbCode.includes("INVALID_REFRESH_TOKEN") ||
|
|
513
|
+
fbCode.includes("USER_NOT_FOUND"))
|
|
514
|
+
) {
|
|
515
|
+
log?.error?.(
|
|
516
|
+
"TOKEN_REFRESH",
|
|
517
|
+
"Windsurf Firebase token is permanently invalid. Re-authentication required.",
|
|
518
|
+
{
|
|
519
|
+
fbCode,
|
|
520
|
+
}
|
|
521
|
+
);
|
|
522
|
+
return { error: "unrecoverable_refresh_error", code: fbCode };
|
|
523
|
+
}
|
|
524
|
+
} catch {
|
|
525
|
+
// not JSON — fall through
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const data = await response.json();
|
|
532
|
+
const expiresIn = parseInt(data.expires_in ?? "3600", 10);
|
|
533
|
+
|
|
534
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Windsurf Firebase token", {
|
|
535
|
+
expiresIn,
|
|
536
|
+
hasNewIdToken: !!data.id_token,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
return {
|
|
540
|
+
accessToken: data.id_token,
|
|
541
|
+
refreshToken: data.refresh_token || refreshToken,
|
|
542
|
+
expiresIn,
|
|
543
|
+
};
|
|
544
|
+
} catch (error) {
|
|
545
|
+
log?.error?.(
|
|
546
|
+
"TOKEN_REFRESH",
|
|
547
|
+
`Network error refreshing Windsurf token: ${error instanceof Error ? error.message : String(error)}`
|
|
548
|
+
);
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* CodeBuddy CN (Tencent) token refresh — POST /v2/plugin/auth/token/refresh with
|
|
555
|
+
* the refresh token carried in the X-Refresh-Token header (not a form body),
|
|
556
|
+
* matching the official CodeBuddy CLI. Response: { code: 0, data: <token> }.
|
|
557
|
+
*/
|
|
558
|
+
export async function refreshCodebuddyCnToken(
|
|
559
|
+
refreshToken: string,
|
|
560
|
+
log: RefreshLogger,
|
|
561
|
+
proxyConfig: unknown = null
|
|
562
|
+
) {
|
|
563
|
+
if (!refreshToken) return null;
|
|
564
|
+
const { CODEBUDDY_CN_CONFIG } = await import("@/lib/oauth/constants/oauth");
|
|
565
|
+
const oauth = CODEBUDDY_CN_CONFIG;
|
|
566
|
+
try {
|
|
567
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
568
|
+
fetch(oauth.refreshUrl, {
|
|
569
|
+
method: "POST",
|
|
570
|
+
headers: {
|
|
571
|
+
"Content-Type": "application/json",
|
|
572
|
+
Accept: "application/json",
|
|
573
|
+
"User-Agent": oauth.userAgent,
|
|
574
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
575
|
+
"X-Domain": "copilot.tencent.com",
|
|
576
|
+
"X-Refresh-Token": refreshToken,
|
|
577
|
+
"X-Auth-Refresh-Source": "plugin",
|
|
578
|
+
"X-Product": "SaaS",
|
|
579
|
+
},
|
|
580
|
+
body: "{}",
|
|
581
|
+
})
|
|
582
|
+
);
|
|
583
|
+
|
|
584
|
+
if (!response.ok) {
|
|
585
|
+
const errorText = await response.text();
|
|
586
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh CodeBuddy CN token", {
|
|
587
|
+
status: response.status,
|
|
588
|
+
error: errorText,
|
|
589
|
+
});
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const data = await response.json();
|
|
594
|
+
if (data?.code !== 0 || !data?.data?.accessToken) {
|
|
595
|
+
log?.error?.("TOKEN_REFRESH", "CodeBuddy CN token refresh returned no token", {
|
|
596
|
+
code: data?.code,
|
|
597
|
+
msg: data?.msg,
|
|
598
|
+
});
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed CodeBuddy CN token", {
|
|
603
|
+
hasNewAccessToken: !!data.data.accessToken,
|
|
604
|
+
hasNewRefreshToken: !!data.data.refreshToken,
|
|
605
|
+
expiresIn: data.data.expiresIn,
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
return {
|
|
609
|
+
accessToken: data.data.accessToken,
|
|
610
|
+
refreshToken: data.data.refreshToken || refreshToken,
|
|
611
|
+
expiresIn: data.data.expiresIn,
|
|
612
|
+
};
|
|
613
|
+
} catch (error) {
|
|
614
|
+
log?.error?.("TOKEN_REFRESH", `Network error refreshing CodeBuddy CN token: ${error?.message}`);
|
|
615
|
+
return null;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
export async function refreshClineToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
620
|
+
const endpoint = PROVIDERS.cline?.refreshUrl;
|
|
621
|
+
if (!endpoint) {
|
|
622
|
+
log?.warn?.("TOKEN_REFRESH", "No refresh URL configured for Cline");
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
628
|
+
fetch(endpoint, {
|
|
629
|
+
method: "POST",
|
|
630
|
+
headers: {
|
|
631
|
+
"Content-Type": "application/json",
|
|
632
|
+
Accept: "application/json",
|
|
633
|
+
},
|
|
634
|
+
body: JSON.stringify({
|
|
635
|
+
refreshToken,
|
|
636
|
+
grantType: "refresh_token",
|
|
637
|
+
clientType: "extension",
|
|
638
|
+
}),
|
|
639
|
+
})
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
if (!response.ok) {
|
|
643
|
+
const errorText = await response.text();
|
|
644
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Cline token", {
|
|
645
|
+
status: response.status,
|
|
646
|
+
error: errorText,
|
|
647
|
+
});
|
|
648
|
+
const code = extractOAuthErrorCode(errorText);
|
|
649
|
+
if (code === "invalid_grant" || code === "invalid_request") {
|
|
650
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
651
|
+
}
|
|
652
|
+
return null;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
const payload = await response.json();
|
|
656
|
+
const data = payload?.data || payload;
|
|
657
|
+
const expiresAtIso = data?.expiresAt;
|
|
658
|
+
const expiresIn = expiresAtIso
|
|
659
|
+
? Math.max(1, Math.floor((new Date(expiresAtIso).getTime() - Date.now()) / 1000))
|
|
660
|
+
: undefined;
|
|
661
|
+
|
|
662
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Cline token", {
|
|
663
|
+
hasNewAccessToken: !!data?.accessToken,
|
|
664
|
+
hasNewRefreshToken: !!data?.refreshToken,
|
|
665
|
+
expiresIn,
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
return {
|
|
669
|
+
accessToken: data?.accessToken,
|
|
670
|
+
refreshToken: data?.refreshToken || refreshToken,
|
|
671
|
+
expiresIn,
|
|
672
|
+
};
|
|
673
|
+
} catch (error) {
|
|
674
|
+
log?.error?.("TOKEN_REFRESH", `Network error refreshing Cline token: ${error.message}`);
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Specialized refresh for Kimi Coding OAuth tokens.
|
|
681
|
+
* Uses custom X-Msh-* headers required by Kimi OAuth API.
|
|
682
|
+
*
|
|
683
|
+
* Uses a stable device_id from providerSpecificData (stored at login) to avoid
|
|
684
|
+
* anti-bot detection from ephemeral IDs. If absent, derives a deterministic ID
|
|
685
|
+
* from the refresh token hash so it is at least stable across refreshes for the
|
|
686
|
+
* same token.
|
|
687
|
+
*/
|
|
688
|
+
export async function refreshKimiCodingToken(
|
|
689
|
+
refreshToken: string,
|
|
690
|
+
providerSpecificData: Record<string, unknown> | null | undefined,
|
|
691
|
+
log: RefreshLogger,
|
|
692
|
+
proxyConfig: unknown = null
|
|
693
|
+
) {
|
|
694
|
+
const endpoint = PROVIDERS["kimi-coding"]?.refreshUrl || PROVIDERS["kimi-coding"]?.tokenUrl;
|
|
695
|
+
if (!endpoint) {
|
|
696
|
+
log?.warn?.("TOKEN_REFRESH", "No refresh URL configured for Kimi Coding");
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Prefer stable device_id persisted at login time; fall back to a
|
|
701
|
+
// deterministic hash of the refresh token so it is at least consistent
|
|
702
|
+
// across refreshes for the same session.
|
|
703
|
+
const stableDeviceId =
|
|
704
|
+
(providerSpecificData?.deviceId as string) ||
|
|
705
|
+
pbkdf2Sync(refreshToken, "kimi-device-id", 1000, 16, "sha256").toString("hex");
|
|
706
|
+
|
|
707
|
+
const platform = "kimi_cli";
|
|
708
|
+
const version = process.env.KIMI_CLI_VERSION || "1.36.0";
|
|
709
|
+
|
|
710
|
+
// Build device model string matching the format from providers/kimi-coding.ts.
|
|
711
|
+
// open-sse is a portable workspace — use process.platform/arch (always available in Node).
|
|
712
|
+
const osTypeStr = typeof process !== "undefined" ? process.platform : "unknown";
|
|
713
|
+
const archStr = typeof process !== "undefined" ? process.arch : "unknown";
|
|
714
|
+
const deviceModel = [osTypeStr, archStr].filter(Boolean).join(" ");
|
|
715
|
+
|
|
716
|
+
try {
|
|
717
|
+
const params = new URLSearchParams({
|
|
718
|
+
grant_type: "refresh_token",
|
|
719
|
+
refresh_token: refreshToken,
|
|
720
|
+
client_id: PROVIDERS["kimi-coding"]?.clientId || "",
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
724
|
+
fetch(endpoint, {
|
|
725
|
+
method: "POST",
|
|
726
|
+
headers: {
|
|
727
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
728
|
+
Accept: "application/json",
|
|
729
|
+
"X-Msh-Platform": platform,
|
|
730
|
+
"X-Msh-Version": version,
|
|
731
|
+
"X-Msh-Device-Model": (providerSpecificData?.deviceModel as string) || deviceModel,
|
|
732
|
+
"X-Msh-Device-Id": stableDeviceId,
|
|
733
|
+
// These headers match getKimiOAuthHeaders() in providers/kimi-coding.ts.
|
|
734
|
+
// They're derived at runtime from os module calls; use safe fallbacks here
|
|
735
|
+
// since open-sse is a portable workspace without direct fs/os access.
|
|
736
|
+
"X-Msh-Device-Name": (providerSpecificData?.deviceName as string) || osTypeStr,
|
|
737
|
+
"X-Msh-Os-Version": (providerSpecificData?.osVersion as string) || osTypeStr,
|
|
738
|
+
},
|
|
739
|
+
body: params,
|
|
740
|
+
})
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
if (!response.ok) {
|
|
744
|
+
const errorText = await response.text();
|
|
745
|
+
|
|
746
|
+
// Detect unrecoverable errors
|
|
747
|
+
try {
|
|
748
|
+
const parsed = JSON.parse(errorText);
|
|
749
|
+
const errorCode = parsed?.error;
|
|
750
|
+
if (errorCode === "invalid_grant" || errorCode === "invalid_request") {
|
|
751
|
+
log?.error?.(
|
|
752
|
+
"TOKEN_REFRESH",
|
|
753
|
+
"Kimi Coding refresh token invalid. Re-authentication required.",
|
|
754
|
+
{
|
|
755
|
+
errorCode,
|
|
756
|
+
}
|
|
757
|
+
);
|
|
758
|
+
return { error: "unrecoverable_refresh_error", code: errorCode };
|
|
759
|
+
}
|
|
760
|
+
} catch {
|
|
761
|
+
// not JSON — fall through
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Kimi Coding token", {
|
|
765
|
+
status: response.status,
|
|
766
|
+
error: errorText.slice(0, 200),
|
|
767
|
+
});
|
|
768
|
+
return null;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const tokens = await response.json();
|
|
772
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Kimi Coding token", {
|
|
773
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
774
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
775
|
+
expiresIn: tokens.expires_in,
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
return {
|
|
779
|
+
accessToken: tokens.access_token,
|
|
780
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
781
|
+
expiresIn: tokens.expires_in,
|
|
782
|
+
tokenType: tokens.token_type,
|
|
783
|
+
scope: tokens.scope,
|
|
784
|
+
};
|
|
785
|
+
} catch (error) {
|
|
786
|
+
log?.error?.(
|
|
787
|
+
"TOKEN_REFRESH",
|
|
788
|
+
`Network error refreshing Kimi Coding token: ${error instanceof Error ? error.message : String(error)}`
|
|
789
|
+
);
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Specialized refresh for GitLab Duo OAuth tokens.
|
|
796
|
+
* Token URL is instance-specific; resolves from providerSpecificData.baseUrl.
|
|
797
|
+
* Uses PKCE authorization_code flow initially but refresh_token grant does NOT
|
|
798
|
+
* require code_verifier — only client_id + refresh_token.
|
|
799
|
+
* On invalid_grant (revoked/expired refresh token) returns the unrecoverable sentinel.
|
|
800
|
+
*/
|
|
801
|
+
export async function refreshGitLabDuoToken(
|
|
802
|
+
refreshToken: string,
|
|
803
|
+
providerSpecificData: Record<string, unknown> | null | undefined,
|
|
804
|
+
log: RefreshLogger,
|
|
805
|
+
proxyConfig: unknown = null
|
|
806
|
+
) {
|
|
807
|
+
if (!refreshToken) {
|
|
808
|
+
log?.warn?.("TOKEN_REFRESH", "No refresh token for GitLab Duo");
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
const baseUrl = resolveGitLabOAuthBaseUrl(providerSpecificData);
|
|
813
|
+
const endpoints = buildGitLabOAuthEndpoints(baseUrl);
|
|
814
|
+
const tokenUrl = endpoints.tokenUrl;
|
|
815
|
+
|
|
816
|
+
// client_id from providerSpecificData (stored at login) or fall back to PROVIDERS config
|
|
817
|
+
const clientId =
|
|
818
|
+
(providerSpecificData?.clientId as string) ||
|
|
819
|
+
PROVIDERS["gitlab-duo"]?.clientId ||
|
|
820
|
+
process.env.GITLAB_DUO_OAUTH_CLIENT_ID ||
|
|
821
|
+
process.env.GITLAB_OAUTH_CLIENT_ID ||
|
|
822
|
+
"";
|
|
823
|
+
|
|
824
|
+
try {
|
|
825
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
826
|
+
fetch(tokenUrl, {
|
|
827
|
+
method: "POST",
|
|
828
|
+
headers: {
|
|
829
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
830
|
+
Accept: "application/json",
|
|
831
|
+
},
|
|
832
|
+
body: buildFormParams({
|
|
833
|
+
grant_type: "refresh_token",
|
|
834
|
+
refresh_token: refreshToken,
|
|
835
|
+
client_id: clientId,
|
|
836
|
+
}),
|
|
837
|
+
})
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
if (!response.ok) {
|
|
841
|
+
const errorText = await response.text();
|
|
842
|
+
|
|
843
|
+
// Detect unrecoverable token — GitLab returns standard OAuth2 error codes.
|
|
844
|
+
try {
|
|
845
|
+
const errorBody = JSON.parse(errorText);
|
|
846
|
+
const errorCode = errorBody.error;
|
|
847
|
+
if (errorCode === "invalid_grant" || errorCode === "invalid_request") {
|
|
848
|
+
log?.error?.(
|
|
849
|
+
"TOKEN_REFRESH",
|
|
850
|
+
"GitLab Duo refresh token invalid. Re-authentication required.",
|
|
851
|
+
{
|
|
852
|
+
errorCode,
|
|
853
|
+
}
|
|
854
|
+
);
|
|
855
|
+
return { error: "unrecoverable_refresh_error", code: errorCode };
|
|
856
|
+
}
|
|
857
|
+
} catch {
|
|
858
|
+
// not JSON — fall through
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh GitLab Duo token", {
|
|
862
|
+
status: response.status,
|
|
863
|
+
error: errorText.slice(0, 200),
|
|
864
|
+
});
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const tokens = await response.json();
|
|
869
|
+
|
|
870
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed GitLab Duo token", {
|
|
871
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
872
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
873
|
+
expiresIn: tokens.expires_in,
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
return {
|
|
877
|
+
accessToken: tokens.access_token,
|
|
878
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
879
|
+
expiresIn: tokens.expires_in,
|
|
880
|
+
};
|
|
881
|
+
} catch (error) {
|
|
882
|
+
log?.error?.(
|
|
883
|
+
"TOKEN_REFRESH",
|
|
884
|
+
`Network error refreshing GitLab Duo token: ${error instanceof Error ? error.message : String(error)}`
|
|
885
|
+
);
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Specialized refresh for Claude OAuth tokens
|
|
892
|
+
*/
|
|
893
|
+
export async function refreshClaudeOAuthToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
894
|
+
try {
|
|
895
|
+
// Standard OAuth2 token refresh uses form-urlencoded (not JSON)
|
|
896
|
+
const params = buildFormParams({
|
|
897
|
+
grant_type: "refresh_token",
|
|
898
|
+
refresh_token: refreshToken,
|
|
899
|
+
client_id: PROVIDERS.claude.clientId,
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
903
|
+
fetch(OAUTH_ENDPOINTS.anthropic.token, {
|
|
904
|
+
method: "POST",
|
|
905
|
+
headers: {
|
|
906
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
907
|
+
Accept: "application/json",
|
|
908
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
909
|
+
},
|
|
910
|
+
body: params.toString(),
|
|
911
|
+
})
|
|
912
|
+
);
|
|
913
|
+
|
|
914
|
+
if (!response.ok) {
|
|
915
|
+
// Read + classify the body ONCE, shape-agnostic. A proxy/MITM can deliver
|
|
916
|
+
// the invalid_grant 400 as a JSON string, a double-encoded string, a
|
|
917
|
+
// nested {error:{code}}, or raw text — all must yield the sentinel so the
|
|
918
|
+
// HealthCheck deactivates instead of looping every 60s.
|
|
919
|
+
const { rawText, code } = await readRefreshErrorBody(response);
|
|
920
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Claude OAuth token", {
|
|
921
|
+
status: response.status,
|
|
922
|
+
error: rawText.slice(0, 300),
|
|
923
|
+
});
|
|
924
|
+
if (code === "invalid_grant" || code === "invalid_request") {
|
|
925
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
926
|
+
}
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
const tokens = await response.json();
|
|
931
|
+
|
|
932
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Claude OAuth token", {
|
|
933
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
934
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
935
|
+
expiresIn: tokens.expires_in,
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
return {
|
|
939
|
+
accessToken: tokens.access_token,
|
|
940
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
941
|
+
expiresIn: tokens.expires_in,
|
|
942
|
+
};
|
|
943
|
+
} catch (error) {
|
|
944
|
+
log?.error?.("TOKEN_REFRESH", `Network error refreshing Claude token: ${error.message}`);
|
|
945
|
+
return null;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* Specialized refresh for Google providers (Gemini, Antigravity)
|
|
951
|
+
*/
|
|
952
|
+
export async function refreshGoogleToken(
|
|
953
|
+
refreshToken,
|
|
954
|
+
clientId,
|
|
955
|
+
clientSecret,
|
|
956
|
+
log,
|
|
957
|
+
proxyConfig: unknown = null
|
|
958
|
+
) {
|
|
959
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
960
|
+
fetch(OAUTH_ENDPOINTS.google.token, {
|
|
961
|
+
method: "POST",
|
|
962
|
+
headers: {
|
|
963
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
964
|
+
Accept: "application/json",
|
|
965
|
+
},
|
|
966
|
+
body: buildFormParams({
|
|
967
|
+
grant_type: "refresh_token",
|
|
968
|
+
refresh_token: refreshToken,
|
|
969
|
+
client_id: clientId,
|
|
970
|
+
client_secret: clientSecret,
|
|
971
|
+
}),
|
|
972
|
+
})
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
if (!response.ok) {
|
|
976
|
+
const errorText = await response.text();
|
|
977
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Google token", {
|
|
978
|
+
status: response.status,
|
|
979
|
+
error: errorText.slice(0, 200),
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
// Detect unrecoverable token (invalid_grant = revoked / expired refresh token)
|
|
983
|
+
try {
|
|
984
|
+
const errorBody = JSON.parse(errorText);
|
|
985
|
+
if (errorBody.error === "invalid_grant") {
|
|
986
|
+
log?.error?.("TOKEN_REFRESH", "Google refresh token invalid. Re-authentication required.", {
|
|
987
|
+
provider: "google",
|
|
988
|
+
});
|
|
989
|
+
return { error: "unrecoverable_refresh_error", code: "invalid_grant" };
|
|
990
|
+
}
|
|
991
|
+
} catch {
|
|
992
|
+
// not JSON — fall through
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
const tokens = await response.json();
|
|
999
|
+
|
|
1000
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Google token", {
|
|
1001
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
1002
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
1003
|
+
expiresIn: tokens.expires_in,
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
return {
|
|
1007
|
+
accessToken: tokens.access_token,
|
|
1008
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
1009
|
+
expiresIn: tokens.expires_in,
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
export async function refreshQwenToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
1014
|
+
const endpoint = OAUTH_ENDPOINTS.qwen.token;
|
|
1015
|
+
|
|
1016
|
+
try {
|
|
1017
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1018
|
+
fetch(endpoint, {
|
|
1019
|
+
method: "POST",
|
|
1020
|
+
headers: {
|
|
1021
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1022
|
+
Accept: "application/json",
|
|
1023
|
+
},
|
|
1024
|
+
body: buildFormParams({
|
|
1025
|
+
grant_type: "refresh_token",
|
|
1026
|
+
refresh_token: refreshToken,
|
|
1027
|
+
client_id: PROVIDERS.qwen.clientId,
|
|
1028
|
+
}),
|
|
1029
|
+
})
|
|
1030
|
+
);
|
|
1031
|
+
|
|
1032
|
+
if (response.status === 200) {
|
|
1033
|
+
const tokens = await response.json();
|
|
1034
|
+
|
|
1035
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Qwen token", {
|
|
1036
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
1037
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
1038
|
+
expiresIn: tokens.expires_in,
|
|
1039
|
+
});
|
|
1040
|
+
|
|
1041
|
+
return {
|
|
1042
|
+
accessToken: tokens.access_token,
|
|
1043
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
1044
|
+
expiresIn: tokens.expires_in,
|
|
1045
|
+
providerSpecificData: tokens.resource_url
|
|
1046
|
+
? { resourceUrl: tokens.resource_url }
|
|
1047
|
+
: undefined,
|
|
1048
|
+
};
|
|
1049
|
+
} else {
|
|
1050
|
+
const errorText = await response.text().catch(() => "");
|
|
1051
|
+
|
|
1052
|
+
// Detect unrecoverable invalid_request (expired/revoked refresh token or bad client_id)
|
|
1053
|
+
let errorCode = null;
|
|
1054
|
+
try {
|
|
1055
|
+
const parsed = JSON.parse(errorText);
|
|
1056
|
+
errorCode = parsed?.error;
|
|
1057
|
+
} catch {
|
|
1058
|
+
// not JSON, ignore
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
if (errorCode === "invalid_request" || errorCode === "invalid_grant") {
|
|
1062
|
+
log?.error?.(
|
|
1063
|
+
"TOKEN_REFRESH",
|
|
1064
|
+
"Qwen refresh token is invalid or expired. Re-authentication required.",
|
|
1065
|
+
{
|
|
1066
|
+
status: response.status,
|
|
1067
|
+
errorCode,
|
|
1068
|
+
}
|
|
1069
|
+
);
|
|
1070
|
+
return { error: "unrecoverable_refresh_error", code: errorCode };
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
log?.warn?.("TOKEN_REFRESH", `Error with Qwen endpoint`, {
|
|
1074
|
+
status: response.status,
|
|
1075
|
+
error: errorText,
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
} catch (error) {
|
|
1079
|
+
log?.warn?.("TOKEN_REFRESH", `Network error trying Qwen endpoint`, {
|
|
1080
|
+
error: error.message,
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Qwen token");
|
|
1085
|
+
return null;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Specialized refresh for Codex (OpenAI) OAuth tokens.
|
|
1090
|
+
* OpenAI uses rotating (one-time-use) refresh tokens.
|
|
1091
|
+
* Returns { error: 'unrecoverable_refresh_error', code } when the token has already been
|
|
1092
|
+
* consumed or is invalid, so callers can stop retrying and request re-authentication.
|
|
1093
|
+
*/
|
|
1094
|
+
export async function refreshCodexToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
1095
|
+
try {
|
|
1096
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1097
|
+
fetch(OAUTH_ENDPOINTS.openai.token, {
|
|
1098
|
+
method: "POST",
|
|
1099
|
+
headers: {
|
|
1100
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1101
|
+
Accept: "application/json",
|
|
1102
|
+
},
|
|
1103
|
+
// Body intentionally omits `scope`. RFC 6749 §6 makes scope optional on a
|
|
1104
|
+
// refresh_token grant (the server reuses the originally-granted scope when
|
|
1105
|
+
// absent). Including `scope` causes Auth0 (which OpenAI Codex OAuth is
|
|
1106
|
+
// built on) to treat the request as a re-scope, which can invalidate
|
|
1107
|
+
// sibling refresh_token families on the same client_id. Matches the
|
|
1108
|
+
// pattern used by ndycode/codex-multi-auth, the only known tool that
|
|
1109
|
+
// sustains multiple Codex accounts without cross-invalidation.
|
|
1110
|
+
body: buildFormParams({
|
|
1111
|
+
grant_type: "refresh_token",
|
|
1112
|
+
refresh_token: refreshToken,
|
|
1113
|
+
client_id: PROVIDERS.codex.clientId,
|
|
1114
|
+
}),
|
|
1115
|
+
})
|
|
1116
|
+
);
|
|
1117
|
+
|
|
1118
|
+
if (!response.ok) {
|
|
1119
|
+
const errorText = await response.text();
|
|
1120
|
+
|
|
1121
|
+
// Detect unrecoverable "refresh_token_reused" or "invalid_grant" error from OpenAI
|
|
1122
|
+
// This means the token was already consumed or has expired.
|
|
1123
|
+
// Retrying with the same token will never succeed.
|
|
1124
|
+
let errorCode = null;
|
|
1125
|
+
try {
|
|
1126
|
+
const parsed = JSON.parse(errorText);
|
|
1127
|
+
errorCode =
|
|
1128
|
+
parsed?.error?.code || (typeof parsed?.error === "string" ? parsed.error : null);
|
|
1129
|
+
} catch {
|
|
1130
|
+
// not JSON, ignore
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
if (
|
|
1134
|
+
errorCode === "refresh_token_reused" ||
|
|
1135
|
+
errorCode === "invalid_grant" ||
|
|
1136
|
+
errorCode === "token_expired" ||
|
|
1137
|
+
errorCode === "invalid_token"
|
|
1138
|
+
) {
|
|
1139
|
+
log?.error?.(
|
|
1140
|
+
"TOKEN_REFRESH",
|
|
1141
|
+
"Codex refresh token already used or invalid. Re-authentication required.",
|
|
1142
|
+
{
|
|
1143
|
+
status: response.status,
|
|
1144
|
+
errorCode,
|
|
1145
|
+
}
|
|
1146
|
+
);
|
|
1147
|
+
return { error: "unrecoverable_refresh_error", code: errorCode };
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// Defense-in-depth (port from decolua/9router#1821): any 401 from OpenAI's
|
|
1151
|
+
// OAuth token endpoint means the refresh credential itself was rejected
|
|
1152
|
+
// (e.g. rotated away, or a payload variant whose code we do not yet
|
|
1153
|
+
// recognize — OpenAI has shipped both `token_expired` and the bare
|
|
1154
|
+
// "Could not validate your token" message). Retrying with the same dead
|
|
1155
|
+
// refresh token will never succeed; surface re-auth instead of looping.
|
|
1156
|
+
// 429 / 5xx remain transient and fall through to the retryable branch.
|
|
1157
|
+
if (response.status === 401) {
|
|
1158
|
+
const code = errorCode || "unauthorized";
|
|
1159
|
+
log?.error?.(
|
|
1160
|
+
"TOKEN_REFRESH",
|
|
1161
|
+
"Codex OAuth token endpoint returned 401. Re-authentication required.",
|
|
1162
|
+
{
|
|
1163
|
+
status: response.status,
|
|
1164
|
+
errorCode: code,
|
|
1165
|
+
}
|
|
1166
|
+
);
|
|
1167
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Codex token", {
|
|
1171
|
+
status: response.status,
|
|
1172
|
+
error: errorText,
|
|
1173
|
+
});
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
const tokens = await response.json();
|
|
1178
|
+
|
|
1179
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Codex token", {
|
|
1180
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
1181
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
1182
|
+
expiresIn: tokens.expires_in,
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
return {
|
|
1186
|
+
accessToken: tokens.access_token,
|
|
1187
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
1188
|
+
expiresIn: tokens.expires_in,
|
|
1189
|
+
};
|
|
1190
|
+
} catch (error) {
|
|
1191
|
+
log?.error?.("TOKEN_REFRESH", `Network error refreshing Codex token: ${error.message}`);
|
|
1192
|
+
return null;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Specialized refresh for Kiro (AWS CodeWhisperer) tokens
|
|
1198
|
+
* Supports both AWS SSO OIDC (Builder ID/IDC) and Social Auth (Google/GitHub)
|
|
1199
|
+
*/
|
|
1200
|
+
export async function refreshKiroToken(
|
|
1201
|
+
refreshToken,
|
|
1202
|
+
providerSpecificData,
|
|
1203
|
+
log,
|
|
1204
|
+
proxyConfig: unknown = null
|
|
1205
|
+
) {
|
|
1206
|
+
try {
|
|
1207
|
+
const authMethod = providerSpecificData?.authMethod;
|
|
1208
|
+
const clientId = providerSpecificData?.clientId;
|
|
1209
|
+
const clientSecret = providerSpecificData?.clientSecret;
|
|
1210
|
+
const region = providerSpecificData?.region;
|
|
1211
|
+
|
|
1212
|
+
// AWS SSO OIDC (Builder ID or IDC)
|
|
1213
|
+
// If clientId and clientSecret exist, assume AWS SSO OIDC (default to builder-id if authMethod not specified).
|
|
1214
|
+
// Exception: imported social tokens (authMethod === "imported") carry a freshly-registered
|
|
1215
|
+
// clientId/clientSecret but their refresh token is Kiro-social-issued — the isolated OIDC client
|
|
1216
|
+
// cannot refresh it, so they must fall through to the social auth path (#2467).
|
|
1217
|
+
if (clientId && clientSecret && authMethod !== "imported") {
|
|
1218
|
+
const endpoint = `https://oidc.${region || "us-east-1"}.amazonaws.com/token`;
|
|
1219
|
+
|
|
1220
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1221
|
+
fetch(endpoint, {
|
|
1222
|
+
method: "POST",
|
|
1223
|
+
headers: {
|
|
1224
|
+
"Content-Type": "application/json",
|
|
1225
|
+
Accept: "application/json",
|
|
1226
|
+
},
|
|
1227
|
+
body: JSON.stringify({
|
|
1228
|
+
clientId: clientId,
|
|
1229
|
+
clientSecret: clientSecret,
|
|
1230
|
+
refreshToken: refreshToken,
|
|
1231
|
+
grantType: "refresh_token",
|
|
1232
|
+
}),
|
|
1233
|
+
})
|
|
1234
|
+
);
|
|
1235
|
+
|
|
1236
|
+
if (!response.ok) {
|
|
1237
|
+
const errorText = await response.text();
|
|
1238
|
+
|
|
1239
|
+
// AWS SSO OIDC uses {"__type": "InvalidGrantException"} error format (not standard OAuth2).
|
|
1240
|
+
let awsErrorType: string | undefined;
|
|
1241
|
+
try {
|
|
1242
|
+
const awsError = JSON.parse(errorText);
|
|
1243
|
+
awsErrorType = awsError.__type || awsError.error;
|
|
1244
|
+
} catch {
|
|
1245
|
+
// not JSON
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// If the refresh token itself is expired/revoked, no amount of re-registration helps.
|
|
1249
|
+
if (
|
|
1250
|
+
awsErrorType === "InvalidGrantException" ||
|
|
1251
|
+
awsErrorType === "ExpiredTokenException" ||
|
|
1252
|
+
awsErrorType === "invalid_grant"
|
|
1253
|
+
) {
|
|
1254
|
+
log?.error?.(
|
|
1255
|
+
"TOKEN_REFRESH",
|
|
1256
|
+
"Kiro AWS refresh token expired/invalid. Re-authentication required.",
|
|
1257
|
+
{ awsErrorType }
|
|
1258
|
+
);
|
|
1259
|
+
return { error: "unrecoverable_refresh_error", code: awsErrorType };
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
// Client credentials may be expired/invalid (DB import, TTL expiry, browser conflict).
|
|
1263
|
+
// Re-register a fresh OIDC client and retry once before giving up (#2524).
|
|
1264
|
+
log?.warn?.(
|
|
1265
|
+
"TOKEN_REFRESH",
|
|
1266
|
+
"Kiro OIDC refresh failed, attempting client re-registration...",
|
|
1267
|
+
{ status: response.status, error: errorText.slice(0, 200) }
|
|
1268
|
+
);
|
|
1269
|
+
|
|
1270
|
+
try {
|
|
1271
|
+
const resolvedRegion = region || "us-east-1";
|
|
1272
|
+
const regEndpoint = `https://oidc.${resolvedRegion}.amazonaws.com/client/register`;
|
|
1273
|
+
const regRes = await runWithProxyContext(proxyConfig, () =>
|
|
1274
|
+
fetch(regEndpoint, {
|
|
1275
|
+
method: "POST",
|
|
1276
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
1277
|
+
body: JSON.stringify({
|
|
1278
|
+
clientName: "kiro-oauth-client",
|
|
1279
|
+
clientType: "public",
|
|
1280
|
+
scopes: [
|
|
1281
|
+
"codewhisperer:completions",
|
|
1282
|
+
"codewhisperer:analysis",
|
|
1283
|
+
"codewhisperer:conversations",
|
|
1284
|
+
],
|
|
1285
|
+
grantTypes: ["urn:ietf:params:oauth:grant-type:device_code", "refresh_token"],
|
|
1286
|
+
issuerUrl: "https://identitycenter.amazonaws.com/ssoins-722374e8c3c8e6c6",
|
|
1287
|
+
}),
|
|
1288
|
+
})
|
|
1289
|
+
);
|
|
1290
|
+
|
|
1291
|
+
if (regRes.ok) {
|
|
1292
|
+
const newClient = await regRes.json();
|
|
1293
|
+
const retryRes = await runWithProxyContext(proxyConfig, () =>
|
|
1294
|
+
fetch(endpoint, {
|
|
1295
|
+
method: "POST",
|
|
1296
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
1297
|
+
body: JSON.stringify({
|
|
1298
|
+
clientId: newClient.clientId,
|
|
1299
|
+
clientSecret: newClient.clientSecret,
|
|
1300
|
+
refreshToken: refreshToken,
|
|
1301
|
+
grantType: "refresh_token",
|
|
1302
|
+
}),
|
|
1303
|
+
})
|
|
1304
|
+
);
|
|
1305
|
+
|
|
1306
|
+
if (retryRes.ok) {
|
|
1307
|
+
const retryTokens = await retryRes.json();
|
|
1308
|
+
log?.info?.("TOKEN_REFRESH", "Kiro refresh recovered via client re-registration", {
|
|
1309
|
+
hasNewAccessToken: !!retryTokens.accessToken,
|
|
1310
|
+
expiresIn: retryTokens.expiresIn,
|
|
1311
|
+
});
|
|
1312
|
+
return {
|
|
1313
|
+
accessToken: retryTokens.accessToken,
|
|
1314
|
+
refreshToken: retryTokens.refreshToken || refreshToken,
|
|
1315
|
+
expiresIn: retryTokens.expiresIn,
|
|
1316
|
+
_newClientId: newClient.clientId,
|
|
1317
|
+
_newClientSecret: newClient.clientSecret,
|
|
1318
|
+
_newClientSecretExpiresAt: newClient.clientSecretExpiresAt,
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
} catch (reRegErr) {
|
|
1323
|
+
log?.warn?.("TOKEN_REFRESH", "Kiro client re-registration fallback failed", {
|
|
1324
|
+
error: String(reRegErr),
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Kiro AWS token", {
|
|
1329
|
+
status: response.status,
|
|
1330
|
+
error: errorText.slice(0, 200),
|
|
1331
|
+
});
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
const tokens = await response.json();
|
|
1336
|
+
|
|
1337
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Kiro AWS token", {
|
|
1338
|
+
hasNewAccessToken: !!tokens.accessToken,
|
|
1339
|
+
expiresIn: tokens.expiresIn,
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
return {
|
|
1343
|
+
accessToken: tokens.accessToken,
|
|
1344
|
+
refreshToken: tokens.refreshToken || refreshToken,
|
|
1345
|
+
expiresIn: tokens.expiresIn,
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
// Social Auth (Google/GitHub) - use Kiro's refresh endpoint
|
|
1350
|
+
const tokenUrl = PROVIDERS.kiro.tokenUrl;
|
|
1351
|
+
if (!tokenUrl) {
|
|
1352
|
+
log?.error?.("TOKEN_REFRESH", "Missing Kiro token endpoint");
|
|
1353
|
+
return null;
|
|
1354
|
+
}
|
|
1355
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1356
|
+
fetch(tokenUrl, {
|
|
1357
|
+
method: "POST",
|
|
1358
|
+
headers: {
|
|
1359
|
+
"Content-Type": "application/json",
|
|
1360
|
+
Accept: "application/json",
|
|
1361
|
+
},
|
|
1362
|
+
body: JSON.stringify({
|
|
1363
|
+
refreshToken: refreshToken,
|
|
1364
|
+
}),
|
|
1365
|
+
})
|
|
1366
|
+
);
|
|
1367
|
+
|
|
1368
|
+
if (!response.ok) {
|
|
1369
|
+
const errorText = await response.text();
|
|
1370
|
+
|
|
1371
|
+
// Also check for AWS-style errors on the social auth path (Kiro may relay them)
|
|
1372
|
+
try {
|
|
1373
|
+
const awsError = JSON.parse(errorText);
|
|
1374
|
+
const awsErrorType = awsError.__type || awsError.error;
|
|
1375
|
+
if (
|
|
1376
|
+
awsErrorType === "InvalidGrantException" ||
|
|
1377
|
+
awsErrorType === "ExpiredTokenException" ||
|
|
1378
|
+
awsErrorType === "invalid_grant"
|
|
1379
|
+
) {
|
|
1380
|
+
log?.error?.(
|
|
1381
|
+
"TOKEN_REFRESH",
|
|
1382
|
+
"Kiro social refresh token expired/invalid. Re-authentication required.",
|
|
1383
|
+
{
|
|
1384
|
+
awsErrorType,
|
|
1385
|
+
}
|
|
1386
|
+
);
|
|
1387
|
+
return { error: "unrecoverable_refresh_error", code: awsErrorType };
|
|
1388
|
+
}
|
|
1389
|
+
} catch {
|
|
1390
|
+
// not JSON — fall through
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Kiro social token", {
|
|
1394
|
+
status: response.status,
|
|
1395
|
+
error: errorText.slice(0, 200),
|
|
1396
|
+
});
|
|
1397
|
+
return null;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
const tokens = await response.json();
|
|
1401
|
+
|
|
1402
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Kiro social token", {
|
|
1403
|
+
hasNewAccessToken: !!tokens.accessToken,
|
|
1404
|
+
expiresIn: tokens.expiresIn,
|
|
1405
|
+
});
|
|
1406
|
+
|
|
1407
|
+
return {
|
|
1408
|
+
accessToken: tokens.accessToken,
|
|
1409
|
+
refreshToken: tokens.refreshToken || refreshToken,
|
|
1410
|
+
expiresIn: tokens.expiresIn,
|
|
1411
|
+
};
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
log?.error?.("TOKEN_REFRESH", `Network error refreshing Kiro token: ${error.message}`);
|
|
1414
|
+
return null;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
* Specialized refresh for Qoder OAuth tokens
|
|
1420
|
+
*/
|
|
1421
|
+
export async function refreshQoderToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
1422
|
+
if (!OAUTH_ENDPOINTS.qoder.token || !PROVIDERS.qoder.clientId || !PROVIDERS.qoder.clientSecret) {
|
|
1423
|
+
log?.warn?.(
|
|
1424
|
+
"TOKEN_REFRESH",
|
|
1425
|
+
"Qoder OAuth refresh skipped: browser OAuth is not configured in this environment"
|
|
1426
|
+
);
|
|
1427
|
+
return null;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
const basicAuth = btoa(`${PROVIDERS.qoder.clientId}:${PROVIDERS.qoder.clientSecret}`);
|
|
1431
|
+
|
|
1432
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1433
|
+
fetch(OAUTH_ENDPOINTS.qoder.token, {
|
|
1434
|
+
method: "POST",
|
|
1435
|
+
headers: {
|
|
1436
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1437
|
+
Accept: "application/json",
|
|
1438
|
+
Authorization: `Basic ${basicAuth}`,
|
|
1439
|
+
},
|
|
1440
|
+
body: buildFormParams({
|
|
1441
|
+
grant_type: "refresh_token",
|
|
1442
|
+
refresh_token: refreshToken,
|
|
1443
|
+
client_id: PROVIDERS.qoder.clientId,
|
|
1444
|
+
client_secret: PROVIDERS.qoder.clientSecret,
|
|
1445
|
+
}),
|
|
1446
|
+
})
|
|
1447
|
+
);
|
|
1448
|
+
|
|
1449
|
+
if (!response.ok) {
|
|
1450
|
+
const errorText = await response.text();
|
|
1451
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Qoder token", {
|
|
1452
|
+
status: response.status,
|
|
1453
|
+
error: errorText,
|
|
1454
|
+
});
|
|
1455
|
+
const code = extractOAuthErrorCode(errorText);
|
|
1456
|
+
if (code === "invalid_grant" || code === "invalid_request") {
|
|
1457
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
1458
|
+
}
|
|
1459
|
+
return null;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
const tokens = await response.json();
|
|
1463
|
+
|
|
1464
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Qoder token", {
|
|
1465
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
1466
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
1467
|
+
expiresIn: tokens.expires_in,
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1470
|
+
return {
|
|
1471
|
+
accessToken: tokens.access_token,
|
|
1472
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
1473
|
+
expiresIn: tokens.expires_in,
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* Specialized refresh for GitHub Copilot OAuth tokens
|
|
1479
|
+
*/
|
|
1480
|
+
export async function refreshGitHubToken(refreshToken, log, proxyConfig: unknown = null) {
|
|
1481
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1482
|
+
fetch(OAUTH_ENDPOINTS.github.token, {
|
|
1483
|
+
method: "POST",
|
|
1484
|
+
headers: {
|
|
1485
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1486
|
+
Accept: "application/json",
|
|
1487
|
+
},
|
|
1488
|
+
body: buildFormParams({
|
|
1489
|
+
grant_type: "refresh_token",
|
|
1490
|
+
refresh_token: refreshToken,
|
|
1491
|
+
client_id: PROVIDERS.github.clientId,
|
|
1492
|
+
client_secret: PROVIDERS.github.clientSecret,
|
|
1493
|
+
}),
|
|
1494
|
+
})
|
|
1495
|
+
);
|
|
1496
|
+
|
|
1497
|
+
if (!response.ok) {
|
|
1498
|
+
const errorText = await response.text();
|
|
1499
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh GitHub token", {
|
|
1500
|
+
status: response.status,
|
|
1501
|
+
error: errorText,
|
|
1502
|
+
});
|
|
1503
|
+
const code = extractOAuthErrorCode(errorText);
|
|
1504
|
+
if (code === "invalid_grant" || code === "invalid_request") {
|
|
1505
|
+
return { error: "unrecoverable_refresh_error", code };
|
|
1506
|
+
}
|
|
1507
|
+
return null;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
const tokens = await response.json();
|
|
1511
|
+
|
|
1512
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed GitHub token", {
|
|
1513
|
+
hasNewAccessToken: !!tokens.access_token,
|
|
1514
|
+
hasNewRefreshToken: !!tokens.refresh_token,
|
|
1515
|
+
expiresIn: tokens.expires_in,
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
return {
|
|
1519
|
+
accessToken: tokens.access_token,
|
|
1520
|
+
refreshToken: tokens.refresh_token || refreshToken,
|
|
1521
|
+
expiresIn: tokens.expires_in,
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
/**
|
|
1526
|
+
* Refresh GitHub Copilot token using GitHub access token
|
|
1527
|
+
*/
|
|
1528
|
+
export async function refreshCopilotToken(githubAccessToken, log, proxyConfig: unknown = null) {
|
|
1529
|
+
try {
|
|
1530
|
+
const response = await runWithProxyContext(proxyConfig, () =>
|
|
1531
|
+
fetch("https://api.github.com/copilot_internal/v2/token", {
|
|
1532
|
+
headers: getGitHubCopilotRefreshHeaders(`token ${githubAccessToken}`),
|
|
1533
|
+
})
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
if (!response.ok) {
|
|
1537
|
+
const errorText = await response.text();
|
|
1538
|
+
log?.error?.("TOKEN_REFRESH", "Failed to refresh Copilot token", {
|
|
1539
|
+
status: response.status,
|
|
1540
|
+
error: errorText,
|
|
1541
|
+
});
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
const data = await response.json();
|
|
1546
|
+
|
|
1547
|
+
log?.info?.("TOKEN_REFRESH", "Successfully refreshed Copilot token", {
|
|
1548
|
+
hasToken: !!data.token,
|
|
1549
|
+
expiresAt: data.expires_at,
|
|
1550
|
+
});
|
|
1551
|
+
|
|
1552
|
+
return {
|
|
1553
|
+
token: data.token,
|
|
1554
|
+
expiresAt: data.expires_at,
|
|
1555
|
+
};
|
|
1556
|
+
} catch (error) {
|
|
1557
|
+
log?.error?.("TOKEN_REFRESH", "Error refreshing Copilot token", {
|
|
1558
|
+
error: error.message,
|
|
1559
|
+
});
|
|
1560
|
+
return null;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* Get access token for a specific provider (internal, does the actual work)
|
|
1566
|
+
*/
|
|
1567
|
+
async function _getAccessTokenInternal(provider, credentials, log, proxyConfig: unknown = null) {
|
|
1568
|
+
switch (provider) {
|
|
1569
|
+
case "gemini":
|
|
1570
|
+
case "antigravity":
|
|
1571
|
+
case "agy":
|
|
1572
|
+
return await refreshGoogleToken(
|
|
1573
|
+
credentials.refreshToken,
|
|
1574
|
+
PROVIDERS[provider].clientId,
|
|
1575
|
+
PROVIDERS[provider].clientSecret,
|
|
1576
|
+
log,
|
|
1577
|
+
proxyConfig
|
|
1578
|
+
);
|
|
1579
|
+
|
|
1580
|
+
case "claude":
|
|
1581
|
+
return await refreshClaudeOAuthToken(credentials.refreshToken, log, proxyConfig);
|
|
1582
|
+
|
|
1583
|
+
case "codex":
|
|
1584
|
+
return await refreshCodexToken(credentials.refreshToken, log, proxyConfig);
|
|
1585
|
+
|
|
1586
|
+
case "qwen":
|
|
1587
|
+
return await refreshQwenToken(credentials.refreshToken, log, proxyConfig);
|
|
1588
|
+
|
|
1589
|
+
case "qoder":
|
|
1590
|
+
return await refreshQoderToken(credentials.refreshToken, log, proxyConfig);
|
|
1591
|
+
|
|
1592
|
+
case "github":
|
|
1593
|
+
return await refreshGitHubToken(credentials.refreshToken, log, proxyConfig);
|
|
1594
|
+
|
|
1595
|
+
case "kiro":
|
|
1596
|
+
case "amazon-q":
|
|
1597
|
+
return await refreshKiroToken(
|
|
1598
|
+
credentials.refreshToken,
|
|
1599
|
+
credentials.providerSpecificData,
|
|
1600
|
+
log,
|
|
1601
|
+
proxyConfig
|
|
1602
|
+
);
|
|
1603
|
+
|
|
1604
|
+
case "cline":
|
|
1605
|
+
return await refreshClineToken(credentials.refreshToken, log, proxyConfig);
|
|
1606
|
+
|
|
1607
|
+
case "kimi-coding":
|
|
1608
|
+
return await refreshKimiCodingToken(
|
|
1609
|
+
credentials.refreshToken,
|
|
1610
|
+
credentials.providerSpecificData,
|
|
1611
|
+
log,
|
|
1612
|
+
proxyConfig
|
|
1613
|
+
);
|
|
1614
|
+
|
|
1615
|
+
case "gitlab-duo":
|
|
1616
|
+
return await refreshGitLabDuoToken(
|
|
1617
|
+
credentials.refreshToken,
|
|
1618
|
+
credentials.providerSpecificData,
|
|
1619
|
+
log,
|
|
1620
|
+
proxyConfig
|
|
1621
|
+
);
|
|
1622
|
+
|
|
1623
|
+
case "windsurf":
|
|
1624
|
+
case "devin-cli":
|
|
1625
|
+
return await refreshWindsurfToken(
|
|
1626
|
+
credentials.refreshToken,
|
|
1627
|
+
credentials.providerSpecificData,
|
|
1628
|
+
log,
|
|
1629
|
+
proxyConfig
|
|
1630
|
+
);
|
|
1631
|
+
|
|
1632
|
+
case "codebuddy-cn":
|
|
1633
|
+
return await refreshCodebuddyCnToken(credentials.refreshToken, log, proxyConfig);
|
|
1634
|
+
|
|
1635
|
+
default:
|
|
1636
|
+
// Fallback to generic OAuth refresh for unknown providers
|
|
1637
|
+
return refreshAccessToken(provider, credentials.refreshToken, credentials, log, proxyConfig);
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
/**
|
|
1642
|
+
* Whether a provider has a supported refresh path in this service.
|
|
1643
|
+
*/
|
|
1644
|
+
export function supportsTokenRefresh(provider) {
|
|
1645
|
+
const explicitlySupported = new Set([
|
|
1646
|
+
"gemini",
|
|
1647
|
+
"antigravity",
|
|
1648
|
+
"agy",
|
|
1649
|
+
"claude",
|
|
1650
|
+
"codex",
|
|
1651
|
+
"qwen",
|
|
1652
|
+
"qoder",
|
|
1653
|
+
"github",
|
|
1654
|
+
"kiro",
|
|
1655
|
+
"amazon-q",
|
|
1656
|
+
"cline",
|
|
1657
|
+
"kimi-coding",
|
|
1658
|
+
"windsurf",
|
|
1659
|
+
"devin-cli",
|
|
1660
|
+
"gitlab-duo",
|
|
1661
|
+
"codebuddy-cn",
|
|
1662
|
+
]);
|
|
1663
|
+
if (explicitlySupported.has(provider)) return true;
|
|
1664
|
+
const config = PROVIDERS[provider];
|
|
1665
|
+
return !!(config?.refreshUrl || config?.tokenUrl);
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* Check if a refresh result indicates an unrecoverable error
|
|
1670
|
+
* (e.g. the refresh token was already consumed and cannot be reused).
|
|
1671
|
+
* Callers should stop retrying and request re-authentication.
|
|
1672
|
+
*/
|
|
1673
|
+
export function isUnrecoverableRefreshError(result) {
|
|
1674
|
+
return (
|
|
1675
|
+
result &&
|
|
1676
|
+
typeof result === "object" &&
|
|
1677
|
+
(result.error === "unrecoverable_refresh_error" ||
|
|
1678
|
+
result.error === "refresh_token_reused" ||
|
|
1679
|
+
result.error === "invalid_request" ||
|
|
1680
|
+
result.error === "invalid_grant")
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
/**
|
|
1685
|
+
* Get access token for a specific provider (with deduplication).
|
|
1686
|
+
*
|
|
1687
|
+
* Deduplication strategy (two layers):
|
|
1688
|
+
* 1. Per-connection mutex (primary): if credentials.connectionId is present, all concurrent
|
|
1689
|
+
* callers for that connection share one in-flight promise regardless of which token they
|
|
1690
|
+
* loaded. This prevents refresh_token_reused errors with rotating (one-time-use) tokens,
|
|
1691
|
+
* e.g. Codex/OpenAI, where callers that loaded credentials at different times may hold
|
|
1692
|
+
* different token strings but refer to the same connection.
|
|
1693
|
+
* 2. Token-hash fallback: if no connectionId, dedup by provider+sha256(refreshToken) as before.
|
|
1694
|
+
*
|
|
1695
|
+
* Additionally, when connectionId is present, the stale-token check reads the DB to detect
|
|
1696
|
+
* whether another process already refreshed the token. If the DB token is still valid it is
|
|
1697
|
+
* returned immediately without a new upstream call.
|
|
1698
|
+
*
|
|
1699
|
+
* @param onPersist - Optional callback invoked INSIDE the per-connection mutex closure after a
|
|
1700
|
+
* successful refresh, before the mutex releases. Use this to atomically persist the new tokens
|
|
1701
|
+
* to the DB within the same lock window. If `onPersist` throws, the error is logged and
|
|
1702
|
+
* re-thrown so the caller is aware of the persistence failure.
|
|
1703
|
+
*/
|
|
1704
|
+
export async function getAccessToken(
|
|
1705
|
+
provider,
|
|
1706
|
+
credentials,
|
|
1707
|
+
log,
|
|
1708
|
+
proxyConfig: unknown = null,
|
|
1709
|
+
onPersist?: RefreshPersistFn
|
|
1710
|
+
) {
|
|
1711
|
+
if (!credentials || !credentials.refreshToken || typeof credentials.refreshToken !== "string") {
|
|
1712
|
+
log?.warn?.("TOKEN_REFRESH", `No valid refresh token available for provider: ${provider}`);
|
|
1713
|
+
return null;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
// If the caller did not pass onPersist explicitly, fall back to the active
|
|
1717
|
+
// AsyncLocalStorage store. This lets `runWithOnPersist(persistFn, () =>
|
|
1718
|
+
// executor.refreshCredentials(creds, log))` plumb the persist callback through
|
|
1719
|
+
// executors (e.g. CodexExecutor) without modifying their signature.
|
|
1720
|
+
const effectiveOnPersist = onPersist ?? getActiveOnPersist();
|
|
1721
|
+
|
|
1722
|
+
const connectionId = credentials.connectionId;
|
|
1723
|
+
|
|
1724
|
+
// ── Layer 1: per-connection mutex ──────────────────────────────────────────
|
|
1725
|
+
if (connectionId && typeof connectionId === "string") {
|
|
1726
|
+
const existing = connectionRefreshMutex.get(connectionId);
|
|
1727
|
+
if (existing) {
|
|
1728
|
+
existing.waiters++;
|
|
1729
|
+
log?.info?.("TOKEN_REFRESH", "Concurrent refresh detected — sharing in-flight refresh", {
|
|
1730
|
+
provider,
|
|
1731
|
+
connectionId,
|
|
1732
|
+
waiters: existing.waiters,
|
|
1733
|
+
});
|
|
1734
|
+
return existing.promise;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
const entry = { promise: null, waiters: 0 };
|
|
1738
|
+
entry.promise = (async () => {
|
|
1739
|
+
const result = await _getAccessTokenWithStalenessCheck(
|
|
1740
|
+
provider,
|
|
1741
|
+
credentials,
|
|
1742
|
+
log,
|
|
1743
|
+
proxyConfig
|
|
1744
|
+
);
|
|
1745
|
+
// Invoke onPersist INSIDE the mutex so [network call + DB write] are one atomic step.
|
|
1746
|
+
// This prevents a concurrent waiter from reading stale credentials before the DB is updated.
|
|
1747
|
+
if (result?.accessToken && effectiveOnPersist) {
|
|
1748
|
+
// #4038: skip the persist if a concurrent writer already rotated this row past the
|
|
1749
|
+
// refresh_token we presented (compare-and-swap) — overwriting would revert it.
|
|
1750
|
+
if (await casGuardShouldSkipPersist(log)) {
|
|
1751
|
+
return result;
|
|
1752
|
+
}
|
|
1753
|
+
try {
|
|
1754
|
+
await effectiveOnPersist(result);
|
|
1755
|
+
} catch (persistErr) {
|
|
1756
|
+
const { sanitizeErrorMessage } = await import("../utils/error.ts");
|
|
1757
|
+
log?.error?.(
|
|
1758
|
+
"TOKEN_REFRESH",
|
|
1759
|
+
`onPersist callback failed for ${provider}/${connectionId}: ${sanitizeErrorMessage(persistErr instanceof Error ? persistErr : new Error(String(persistErr)))}`
|
|
1760
|
+
);
|
|
1761
|
+
throw persistErr;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
return result;
|
|
1765
|
+
})().finally(() => {
|
|
1766
|
+
connectionRefreshMutex.delete(connectionId);
|
|
1767
|
+
});
|
|
1768
|
+
connectionRefreshMutex.set(connectionId, entry);
|
|
1769
|
+
return entry.promise;
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
// ── Layer 2: token-hash fallback (no connectionId) ─────────────────────────
|
|
1773
|
+
const cacheKey = getRefreshCacheKey(provider, credentials.refreshToken);
|
|
1774
|
+
|
|
1775
|
+
if (refreshPromiseCache.has(cacheKey)) {
|
|
1776
|
+
log?.info?.("TOKEN_REFRESH", `Reusing in-flight refresh for ${provider}`);
|
|
1777
|
+
return refreshPromiseCache.get(cacheKey);
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// Layer 2 has no per-connection mutex, so callers that pass an onPersist
|
|
1781
|
+
// callback expect it to fire after a successful refresh. Without this hook
|
|
1782
|
+
// the legacy `connectionId`-less path would silently swallow the callback,
|
|
1783
|
+
// leaving DB rows out of sync with rotated tokens (Codex/OpenAI). We still
|
|
1784
|
+
// resolve the promise to all waiters with the refreshed credentials.
|
|
1785
|
+
const refreshPromise = serializeRefresh(provider, () =>
|
|
1786
|
+
_getAccessTokenInternal(provider, credentials, log, proxyConfig)
|
|
1787
|
+
)
|
|
1788
|
+
.then(async (result) => {
|
|
1789
|
+
if (result?.accessToken && effectiveOnPersist) {
|
|
1790
|
+
// #4038: same compare-and-swap guard as Layer 1 — skip the persist if a concurrent
|
|
1791
|
+
// writer already rotated this row past the refresh_token we presented.
|
|
1792
|
+
if (await casGuardShouldSkipPersist(log)) {
|
|
1793
|
+
return result;
|
|
1794
|
+
}
|
|
1795
|
+
try {
|
|
1796
|
+
await effectiveOnPersist(result);
|
|
1797
|
+
} catch (persistErr) {
|
|
1798
|
+
const { sanitizeErrorMessage } = await import("../utils/error.ts");
|
|
1799
|
+
log?.error?.(
|
|
1800
|
+
"TOKEN_REFRESH",
|
|
1801
|
+
`Layer 2 onPersist callback failed for ${provider}: ${sanitizeErrorMessage(persistErr instanceof Error ? persistErr : new Error(String(persistErr)))}`
|
|
1802
|
+
);
|
|
1803
|
+
throw persistErr;
|
|
1804
|
+
}
|
|
1805
|
+
} else if (result?.accessToken && !effectiveOnPersist) {
|
|
1806
|
+
log?.warn?.(
|
|
1807
|
+
"TOKEN_REFRESH",
|
|
1808
|
+
`Layer 2 refresh succeeded for ${provider} without onPersist — DB row will not be updated with rotated token. Callers should pass connectionId for Layer 1 atomicity.`
|
|
1809
|
+
);
|
|
1810
|
+
}
|
|
1811
|
+
return result;
|
|
1812
|
+
})
|
|
1813
|
+
.finally(() => {
|
|
1814
|
+
refreshPromiseCache.delete(cacheKey);
|
|
1815
|
+
});
|
|
1816
|
+
|
|
1817
|
+
refreshPromiseCache.set(cacheKey, refreshPromise);
|
|
1818
|
+
return refreshPromise;
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
/**
|
|
1822
|
+
* Internal helper: performs the DB staleness check then calls the actual refresh.
|
|
1823
|
+
* Only called from the per-connection mutex path (Layer 1 above).
|
|
1824
|
+
*/
|
|
1825
|
+
async function _getAccessTokenWithStalenessCheck(provider, credentials, log, proxyConfig) {
|
|
1826
|
+
// ROTATION MAP CHECK (codex-multi-auth pattern): if this refresh_token was
|
|
1827
|
+
// rotated very recently (within ROTATION_MAP_TTL_MS), reuse the cached new
|
|
1828
|
+
// tokens INSTEAD of hitting upstream. Auth0 treats re-use of a rotated token
|
|
1829
|
+
// as a security event and revokes the entire token family — fatal for
|
|
1830
|
+
// multi-account Codex setups. The in-memory rotation map catches this even
|
|
1831
|
+
// when the caller bypasses the DB staleness path (no connectionId, stale
|
|
1832
|
+
// in-memory credentials in retries, etc.).
|
|
1833
|
+
const rotated = lookupRotation(provider, credentials.refreshToken);
|
|
1834
|
+
if (rotated) {
|
|
1835
|
+
log?.info?.(
|
|
1836
|
+
"TOKEN_REFRESH",
|
|
1837
|
+
`Rotation map hit for ${provider}. Returning cached rotated tokens (avoids family-revoke).`
|
|
1838
|
+
);
|
|
1839
|
+
return rotated.result;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
// RACE CONDITION PREVENTION:
|
|
1843
|
+
// If the credentials object in memory is stale (e.g. it waited in a semaphore while another
|
|
1844
|
+
// request refreshed the token), using its OLD refreshToken will cause the provider (e.g. OpenAI)
|
|
1845
|
+
// to reject it with 'refresh_token_reused' and revoke the new token family.
|
|
1846
|
+
// We MUST check if the DB has a newer token before proceeding with a network refresh.
|
|
1847
|
+
if (credentials.connectionId) {
|
|
1848
|
+
try {
|
|
1849
|
+
const { getProviderConnectionById } = await import("../../src/lib/db/providers");
|
|
1850
|
+
const dbConnection = await getProviderConnectionById(credentials.connectionId);
|
|
1851
|
+
if (dbConnection && dbConnection.refreshToken) {
|
|
1852
|
+
const now = Date.now();
|
|
1853
|
+
const dbExpiresAt = dbConnection.expiresAt ? new Date(dbConnection.expiresAt).getTime() : 0;
|
|
1854
|
+
|
|
1855
|
+
if (dbConnection.refreshToken !== credentials.refreshToken) {
|
|
1856
|
+
log?.info?.(
|
|
1857
|
+
"TOKEN_REFRESH",
|
|
1858
|
+
`Stale token detected in memory for ${provider}. Using refreshed token from DB.`
|
|
1859
|
+
);
|
|
1860
|
+
|
|
1861
|
+
// If the DB token is not expired, we can just return it!
|
|
1862
|
+
if (dbExpiresAt > now + 60000) {
|
|
1863
|
+
// 60 seconds buffer
|
|
1864
|
+
log?.info?.("TOKEN_REFRESH", `DB token is still valid. Skipping OAuth refresh.`);
|
|
1865
|
+
return {
|
|
1866
|
+
accessToken: dbConnection.accessToken,
|
|
1867
|
+
refreshToken: dbConnection.refreshToken,
|
|
1868
|
+
// Return absolute expiresAt so downstream callers do NOT recompute lifetime
|
|
1869
|
+
// from a relative expiresIn value (which would incorrectly extend the TTL).
|
|
1870
|
+
// expiresIn intentionally omitted here.
|
|
1871
|
+
expiresAt: dbConnection.expiresAt,
|
|
1872
|
+
};
|
|
1873
|
+
} else {
|
|
1874
|
+
// DB token is also expired, but it's the NEWEST one. We must use it to refresh.
|
|
1875
|
+
credentials.refreshToken = dbConnection.refreshToken;
|
|
1876
|
+
credentials.accessToken = dbConnection.accessToken;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
// NOTE: Fix F (skip when DB == memory and DB > now+60s) was intentionally
|
|
1880
|
+
// removed. The caller (checkAndRefreshToken) already decided to refresh
|
|
1881
|
+
// because the token is within TOKEN_EXPIRY_BUFFER_MS of expiry. Re-checking
|
|
1882
|
+
// with a tighter 60-second window here would skip legitimate refreshes and
|
|
1883
|
+
// let near-expired tokens hit the upstream. Layer-1 mutex (per-connection)
|
|
1884
|
+
// and Layer-2 dedup (token-hash) already prevent concurrent refreshes for
|
|
1885
|
+
// the import-burst scenario.
|
|
1886
|
+
}
|
|
1887
|
+
} catch (e) {
|
|
1888
|
+
log?.warn?.(
|
|
1889
|
+
"TOKEN_REFRESH",
|
|
1890
|
+
`Failed to check DB for stale token: ${e instanceof Error ? e.message : String(e)}`
|
|
1891
|
+
);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
const oldRefreshToken = credentials.refreshToken;
|
|
1896
|
+
// Front 1: serialize the network refresh across all connections of the same
|
|
1897
|
+
// rotation group (e.g. Codex+openai share one Auth0 client) so two sibling
|
|
1898
|
+
// accounts never refresh concurrently and trip Auth0 family revocation.
|
|
1899
|
+
const result = await serializeRefresh(provider, () =>
|
|
1900
|
+
_getAccessTokenInternal(provider, credentials, log, proxyConfig)
|
|
1901
|
+
);
|
|
1902
|
+
|
|
1903
|
+
// Record the rotation so subsequent stale callers can be redirected to the
|
|
1904
|
+
// new tokens without re-hitting upstream (which would trigger Auth0 family
|
|
1905
|
+
// revocation). Only records when the refresh actually rotated the token.
|
|
1906
|
+
if (
|
|
1907
|
+
result &&
|
|
1908
|
+
typeof result === "object" &&
|
|
1909
|
+
!("error" in result) &&
|
|
1910
|
+
(result as { accessToken?: string }).accessToken &&
|
|
1911
|
+
(result as { refreshToken?: string }).refreshToken
|
|
1912
|
+
) {
|
|
1913
|
+
recordRotation(
|
|
1914
|
+
provider,
|
|
1915
|
+
oldRefreshToken,
|
|
1916
|
+
result as {
|
|
1917
|
+
accessToken: string;
|
|
1918
|
+
refreshToken: string;
|
|
1919
|
+
expiresIn?: number;
|
|
1920
|
+
expiresAt?: string;
|
|
1921
|
+
}
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
return result;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
/**
|
|
1929
|
+
* Refresh token by provider type (alias for getAccessToken)
|
|
1930
|
+
* @deprecated Since v0.2.70 — use getAccessToken() directly.
|
|
1931
|
+
* Still exported because open-sse/index.js and src/sse wrapper use it.
|
|
1932
|
+
* Will be removed in a future major version.
|
|
1933
|
+
*/
|
|
1934
|
+
export const refreshTokenByProvider = getAccessToken;
|
|
1935
|
+
|
|
1936
|
+
/**
|
|
1937
|
+
* Format credentials for provider
|
|
1938
|
+
*/
|
|
1939
|
+
export function formatProviderCredentials(provider, credentials, log) {
|
|
1940
|
+
const config = PROVIDERS[provider];
|
|
1941
|
+
if (!config) {
|
|
1942
|
+
log?.warn?.("TOKEN_REFRESH", `No configuration found for provider: ${provider}`);
|
|
1943
|
+
return null;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
switch (provider) {
|
|
1947
|
+
case "gemini":
|
|
1948
|
+
return {
|
|
1949
|
+
apiKey: credentials.apiKey,
|
|
1950
|
+
accessToken: credentials.accessToken,
|
|
1951
|
+
projectId: credentials.projectId,
|
|
1952
|
+
};
|
|
1953
|
+
|
|
1954
|
+
case "claude":
|
|
1955
|
+
return {
|
|
1956
|
+
apiKey: credentials.apiKey,
|
|
1957
|
+
accessToken: credentials.accessToken,
|
|
1958
|
+
};
|
|
1959
|
+
|
|
1960
|
+
case "codex":
|
|
1961
|
+
case "qwen":
|
|
1962
|
+
case "qoder":
|
|
1963
|
+
case "openai":
|
|
1964
|
+
case "openrouter":
|
|
1965
|
+
return {
|
|
1966
|
+
apiKey: credentials.apiKey,
|
|
1967
|
+
accessToken: credentials.accessToken,
|
|
1968
|
+
};
|
|
1969
|
+
|
|
1970
|
+
case "antigravity":
|
|
1971
|
+
case "agy":
|
|
1972
|
+
return {
|
|
1973
|
+
accessToken: credentials.accessToken,
|
|
1974
|
+
refreshToken: credentials.refreshToken,
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1977
|
+
default:
|
|
1978
|
+
return {
|
|
1979
|
+
apiKey: credentials.apiKey,
|
|
1980
|
+
accessToken: credentials.accessToken,
|
|
1981
|
+
refreshToken: credentials.refreshToken,
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* Get all access tokens for a user
|
|
1988
|
+
*/
|
|
1989
|
+
export async function getAllAccessTokens(userInfo, log) {
|
|
1990
|
+
const results = {};
|
|
1991
|
+
|
|
1992
|
+
if (userInfo.connections && Array.isArray(userInfo.connections)) {
|
|
1993
|
+
for (const connection of userInfo.connections) {
|
|
1994
|
+
if (connection.isActive && connection.provider) {
|
|
1995
|
+
const token = await getAccessToken(
|
|
1996
|
+
connection.provider,
|
|
1997
|
+
{
|
|
1998
|
+
refreshToken: connection.refreshToken,
|
|
1999
|
+
},
|
|
2000
|
+
log
|
|
2001
|
+
);
|
|
2002
|
+
|
|
2003
|
+
if (token) {
|
|
2004
|
+
results[connection.provider] = token;
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
return results;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
/**
|
|
2014
|
+
* Refresh token with retry and exponential backoff
|
|
2015
|
+
* Retries on failure with increasing delay: 1s, 2s, 3s...
|
|
2016
|
+
*
|
|
2017
|
+
* Includes:
|
|
2018
|
+
* - Per-provider circuit breaker (5 consecutive failures → 30min pause)
|
|
2019
|
+
* - 30s timeout per refresh attempt to prevent hanging connections
|
|
2020
|
+
*
|
|
2021
|
+
* @param {function} refreshFn - Async function that returns token or null
|
|
2022
|
+
* @param {number} maxRetries - Max retry attempts (default 3)
|
|
2023
|
+
* @param {object} log - Logger instance (optional)
|
|
2024
|
+
* @param {string} provider - Provider ID for circuit breaker tracking (optional)
|
|
2025
|
+
* @returns {Promise<object|null>} Token result or null if all retries fail
|
|
2026
|
+
*/
|
|
2027
|
+
|
|
2028
|
+
// ─── Circuit Breaker State ──────────────────────────────────────────────────
|
|
2029
|
+
const _circuitBreaker: Record<string, { failures: number; blockedUntil: number }> = {};
|
|
2030
|
+
const CIRCUIT_BREAKER_THRESHOLD = 5; // consecutive failures before tripping
|
|
2031
|
+
const CIRCUIT_BREAKER_COOLDOWN = 30 * 60 * 1000; // 30 minutes
|
|
2032
|
+
const REFRESH_TIMEOUT_MS = 30_000; // 30s max per refresh attempt
|
|
2033
|
+
|
|
2034
|
+
interface CircuitBreakerStatusEntry {
|
|
2035
|
+
failures: number;
|
|
2036
|
+
blocked: boolean;
|
|
2037
|
+
blockedUntil: string | null;
|
|
2038
|
+
remainingMs: number;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
interface RefreshLoggerLike {
|
|
2042
|
+
error?: (scope: string, message: string) => void;
|
|
2043
|
+
warn?: (scope: string, message: string) => void;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
/**
|
|
2047
|
+
* Check if a provider is circuit-breaker blocked.
|
|
2048
|
+
*/
|
|
2049
|
+
export function isProviderBlocked(provider: string): boolean {
|
|
2050
|
+
const state = _circuitBreaker[provider];
|
|
2051
|
+
if (!state) return false;
|
|
2052
|
+
if (!state.blockedUntil) return false;
|
|
2053
|
+
if (state.blockedUntil > Date.now()) return true;
|
|
2054
|
+
// Cooldown expired — reset
|
|
2055
|
+
delete _circuitBreaker[provider];
|
|
2056
|
+
return false;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* Get active per-connection mutex entries (for diagnostics/metrics).
|
|
2061
|
+
* Returns a snapshot of connections that have an in-flight refresh and their waiter count.
|
|
2062
|
+
*/
|
|
2063
|
+
export function getConnectionRefreshMutexStatus(): Record<string, { waiters: number }> {
|
|
2064
|
+
const result: Record<string, { waiters: number }> = {};
|
|
2065
|
+
for (const [connectionId, entry] of connectionRefreshMutex.entries()) {
|
|
2066
|
+
result[connectionId] = { waiters: entry.waiters };
|
|
2067
|
+
}
|
|
2068
|
+
return result;
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
/**
|
|
2072
|
+
* Get circuit breaker status for all providers (for diagnostics).
|
|
2073
|
+
*/
|
|
2074
|
+
export function getCircuitBreakerStatus(): Record<string, CircuitBreakerStatusEntry> {
|
|
2075
|
+
const result: Record<string, CircuitBreakerStatusEntry> = {};
|
|
2076
|
+
for (const [provider, state] of Object.entries(_circuitBreaker)) {
|
|
2077
|
+
result[provider] = {
|
|
2078
|
+
failures: state.failures,
|
|
2079
|
+
blocked: state.blockedUntil > Date.now(),
|
|
2080
|
+
blockedUntil:
|
|
2081
|
+
state.blockedUntil > Date.now() ? new Date(state.blockedUntil).toISOString() : null,
|
|
2082
|
+
remainingMs: Math.max(0, state.blockedUntil - Date.now()),
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2085
|
+
return result;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
/**
|
|
2089
|
+
* Record a successful refresh — resets circuit breaker for provider.
|
|
2090
|
+
*/
|
|
2091
|
+
function recordSuccess(provider: string) {
|
|
2092
|
+
if (_circuitBreaker[provider]) {
|
|
2093
|
+
delete _circuitBreaker[provider];
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
/**
|
|
2098
|
+
* Record a failed refresh — increments circuit breaker counter.
|
|
2099
|
+
*/
|
|
2100
|
+
function recordFailure(provider: string, log: RefreshLoggerLike | null = null) {
|
|
2101
|
+
if (!_circuitBreaker[provider]) {
|
|
2102
|
+
_circuitBreaker[provider] = { failures: 0, blockedUntil: 0 };
|
|
2103
|
+
}
|
|
2104
|
+
_circuitBreaker[provider].failures++;
|
|
2105
|
+
|
|
2106
|
+
if (_circuitBreaker[provider].failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
2107
|
+
_circuitBreaker[provider].blockedUntil = Date.now() + CIRCUIT_BREAKER_COOLDOWN;
|
|
2108
|
+
log?.error?.(
|
|
2109
|
+
"TOKEN_REFRESH",
|
|
2110
|
+
`🔴 Circuit breaker tripped for ${provider}: ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures. ` +
|
|
2111
|
+
`Blocked for ${CIRCUIT_BREAKER_COOLDOWN / 60000}min. Provider needs re-authentication.`
|
|
2112
|
+
);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
/**
|
|
2117
|
+
* Execute a function with a timeout.
|
|
2118
|
+
*/
|
|
2119
|
+
async function withTimeout<T>(fn: () => Promise<T>, timeoutMs: number): Promise<T | null> {
|
|
2120
|
+
return await new Promise<T | null>((resolve, reject) => {
|
|
2121
|
+
const timer = setTimeout(() => resolve(null), timeoutMs);
|
|
2122
|
+
if (typeof timer === "object" && "unref" in timer) {
|
|
2123
|
+
(timer as { unref?: () => void }).unref?.();
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
fn().then(
|
|
2127
|
+
(result) => {
|
|
2128
|
+
clearTimeout(timer);
|
|
2129
|
+
resolve(result);
|
|
2130
|
+
},
|
|
2131
|
+
(error) => {
|
|
2132
|
+
clearTimeout(timer);
|
|
2133
|
+
reject(error);
|
|
2134
|
+
}
|
|
2135
|
+
);
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
export async function refreshWithRetry(
|
|
2140
|
+
refreshFn,
|
|
2141
|
+
maxRetries = 3,
|
|
2142
|
+
log: RefreshLogger = null,
|
|
2143
|
+
provider = "unknown"
|
|
2144
|
+
) {
|
|
2145
|
+
// Circuit breaker check
|
|
2146
|
+
if (isProviderBlocked(provider)) {
|
|
2147
|
+
log?.warn?.("TOKEN_REFRESH", `⚡ Circuit breaker active for ${provider}, skipping refresh`);
|
|
2148
|
+
return null;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
2152
|
+
if (attempt > 0) {
|
|
2153
|
+
const delay = attempt * 1000;
|
|
2154
|
+
log?.debug?.("TOKEN_REFRESH", `Retry ${attempt}/${maxRetries} after ${delay}ms`);
|
|
2155
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
try {
|
|
2159
|
+
const result = await withTimeout(refreshFn, REFRESH_TIMEOUT_MS);
|
|
2160
|
+
if (isUnrecoverableRefreshError(result)) {
|
|
2161
|
+
log?.warn?.(
|
|
2162
|
+
"TOKEN_REFRESH",
|
|
2163
|
+
`Unrecoverable refresh error for ${provider}: ${result.error} — skipping retries`
|
|
2164
|
+
);
|
|
2165
|
+
return result;
|
|
2166
|
+
}
|
|
2167
|
+
if (result) {
|
|
2168
|
+
recordSuccess(provider);
|
|
2169
|
+
return result;
|
|
2170
|
+
}
|
|
2171
|
+
} catch (error) {
|
|
2172
|
+
log?.warn?.("TOKEN_REFRESH", `Attempt ${attempt + 1}/${maxRetries} failed: ${error.message}`);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
// All retries exhausted — record failure for circuit breaker
|
|
2177
|
+
recordFailure(provider, log);
|
|
2178
|
+
log?.error?.("TOKEN_REFRESH", `All ${maxRetries} retry attempts failed for ${provider}`);
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|