cartethyia 2.7.4 → 2.7.5
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 +2 -0
- package/README.md +17 -5
- package/dist/dashboard/assets/{BannedPage-ChG5svFb.js → BannedPage-Cj15GsMp.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +1 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BIcWQun7.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-Bf2VelDe.js → CliToolsPage-BIccZmeL.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +1 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-ggeMSjte.js → CustomizationPage-BKj_r0rp.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js +656 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-U6AKaJcF.js → LoginPage-DkXb6dx-.js} +1 -1
- package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-DnQPSIA8.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +1 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +5 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-5SnUSy3j.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +1 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js +1 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-f0DE1h0-.js → SetupPage-WTa0sktC.js} +1 -1
- package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-BfAb5-o_.js} +3 -3
- package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js +56 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js +1 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
- package/dist/dashboard/assets/app--PJWq8_C.css +2 -0
- package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js +1 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-DfbhQU4k.js} +1 -1
- package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DympBNq4.js → banner-BllT4LcF.js} +1 -1
- package/dist/dashboard/assets/banner-BllT4LcF.js.gz +0 -0
- package/dist/dashboard/assets/brand/login_register.jpg +0 -0
- package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
- package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
- package/dist/dashboard/assets/brand/og_image.jpg +0 -0
- package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CtkX66Wd.js} +1 -1
- package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js +1 -0
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-BQqBQd2n.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-8fiE6tec.js → dialog-BEK7KP0H.js} +1 -1
- package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-BrTEZ8zu.js} +1 -1
- package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js +1 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
- package/dist/dashboard/assets/{entry-BSAsYsmV.js → entry-EBHJ3DrE.js} +1 -1
- package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js +4 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-BAACA727.js} +1 -1
- package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-CPK47xQx.js → github-badge-YSCE4UC2.js} +1 -1
- package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
- package/dist/dashboard/assets/{index-DBNPOfhV.js → index-FQlj0HUT.js} +2 -2
- package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-C4gU5iOL.js} +1 -1
- package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
- package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BHHX_Tmm.js} +1 -1
- package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-CajrYUnD.js} +1 -1
- package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Bx2I7XUe.js} +1 -1
- package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js +1 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js +1 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js +1 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
- package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BLULNqTp.js} +1 -1
- package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
- package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
- package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-D2lIR0tg.js} +1 -1
- package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
- package/dist/dashboard/assets/{state-CkfdYWel.js → state-DTARjfiW.js} +1 -1
- package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
- package/dist/dashboard/assets/{switch-SYm237HG.js → switch-c0oPSnqW.js} +1 -1
- package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-m8WGNPrz.js} +1 -1
- package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.jpg +0 -0
- package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +56 -55
- package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
- package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
- package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
- package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
- package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
- package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
- package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
- package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
- package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
- package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
- package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
- package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
- package/package.json +4 -6
- package/scripts/cli/update.ts +15 -41
- package/src/boot/app.ts +58 -2
- package/src/boot/dependencies.ts +786 -732
- package/src/boot/lifecycle.ts +11 -12
- package/src/config/cooldowns.ts +34 -55
- package/src/config/network.ts +1 -1
- package/src/config/package-paths.ts +1 -1
- package/src/config/providers.ts +13 -14
- package/src/config/resources.ts +0 -5
- package/src/config/runtime.ts +2 -5
- package/src/config/spec.ts +26 -6
- package/src/console/api-keys/ban-constants.ts +38 -0
- package/src/console/api-keys/contracts.ts +71 -62
- package/src/console/api-keys/routes.ts +48 -12
- package/src/console/auth/access.ts +4 -4
- package/src/console/auth/account-reset.ts +1 -1
- package/src/console/auth/audit-recorder.ts +1 -1
- package/src/console/auth/lockout.ts +7 -3
- package/src/console/auth/row-coercion.ts +57 -12
- package/src/console/auth/session-resolver.ts +1 -1
- package/src/console/auth/session-service.ts +8 -2
- package/src/console/auth/session.ts +37 -31
- package/src/console/auth/setup-service.ts +4 -3
- package/src/console/auth/user-store.ts +1 -1
- package/src/console/backup/9router-map.ts +0 -3
- package/src/console/backup/contracts.ts +9 -9
- package/src/console/backup/export-endpoint.ts +5 -6
- package/src/console/backup/nine-router.ts +1 -7
- package/src/console/backup/routes.ts +29 -33
- package/src/console/backup/service.ts +468 -468
- package/src/console/backup/store.ts +47 -29
- package/src/console/backup/validate.ts +11 -1
- package/src/console/cli-tools/contracts.ts +7 -7
- package/src/console/cli-tools/injectors/cline.ts +110 -110
- package/src/console/cli-tools/injectors/codex.ts +181 -181
- package/src/console/cli-tools/injectors/copilot.ts +108 -108
- package/src/console/cli-tools/injectors/driver.ts +247 -247
- package/src/console/cli-tools/injectors/jcode.ts +115 -115
- package/src/console/cli-tools/injectors/openclaw.ts +161 -161
- package/src/console/cli-tools/injectors/opencode.ts +153 -153
- package/src/console/cli-tools/routes.ts +1 -1
- package/src/console/cli-tools/service.ts +1 -1
- package/src/console/cli-tools/store.ts +2 -2
- package/src/console/console-router.ts +32 -0
- package/src/console/dashboard-assets.ts +9 -9
- package/src/console/domain-registration.ts +16 -2
- package/src/console/inferhub/client.ts +0 -7
- package/src/console/inferhub/key-store.ts +1 -1
- package/src/console/inferhub/normalize.ts +2 -2
- package/src/console/inferhub/routes.ts +1 -1
- package/src/console/inferhub/types.ts +1 -1
- package/src/console/observability/contracts.ts +1 -1
- package/src/console/observability/live.ts +31 -18
- package/src/console/observability/logs.ts +1 -1
- package/src/console/observability/sse.ts +62 -8
- package/src/console/observability/store.ts +20 -4
- package/src/console/providers/catalog/catalog-projections.ts +1 -1
- package/src/console/providers/catalog/contracts.ts +39 -0
- package/src/console/providers/catalog/model-operations.ts +1 -1
- package/src/console/providers/catalog/provider-operations.ts +95 -17
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +27 -3
- package/src/console/providers/catalog/store.ts +147 -8
- package/src/console/providers/detail/routes.ts +1 -1
- package/src/console/providers/oauth/callback-listener.ts +100 -18
- package/src/console/providers/oauth/routes.ts +92 -13
- package/src/console/quota/account-quota-global.ts +41 -3
- package/src/console/quota/account-quota-shared.ts +10 -3
- package/src/console/quota/account-quota-tenant.ts +259 -66
- package/src/console/quota/daily-growth-job.ts +308 -0
- package/src/console/quota/native-identity.ts +2 -2
- package/src/console/quota/quota-view.ts +1 -1
- package/src/console/remote-support/routes.ts +1 -1
- package/src/console/remote-support/service.ts +2 -2
- package/src/console/routing/model/contracts.ts +1 -1
- package/src/console/routing/pools/contracts.ts +2 -2
- package/src/console/routing/pools/import-parse.ts +3 -3
- package/src/console/routing/pools/relay-deploy.ts +3 -3
- package/src/console/settings/contracts.ts +29 -2
- package/src/console/settings/store.ts +20 -0
- package/src/console/share/share-router.ts +100 -32
- package/src/console/share/share-stats.ts +4 -4
- package/src/console/share/share-usage.ts +1 -1
- package/src/console/shared/errors.ts +2 -2
- package/src/console/shared/object.ts +18 -0
- package/src/console/shared/read-through-cache.ts +4 -4
- package/src/console/shared/transaction.ts +14 -0
- package/src/console/system-prompt/contracts.ts +89 -12
- package/src/console/system-prompt/routes.ts +98 -45
- package/src/console/updates/apply-update.ts +244 -0
- package/src/console/updates/routes.ts +252 -97
- package/src/main.ts +11 -5
- package/src/network/http2-bidi.ts +1 -1
- package/src/network/ip-utils.ts +298 -0
- package/src/network/outbound-fetch.ts +1 -1
- package/src/network/pool/agent.ts +7 -6
- package/src/network/pool/byte-accounting.ts +1 -1
- package/src/network/pool/resolver.ts +16 -12
- package/src/network/pool/selector.ts +150 -136
- package/src/network/pool-health-machine.ts +1 -1
- package/src/network/rate-limit-verdict.ts +1 -1
- package/src/network/retry.ts +1 -1
- package/src/network/ssrf.ts +20 -71
- package/src/observability/event-log.ts +2 -2
- package/src/observability/event-query.ts +59 -291
- package/src/observability/log-sanitize.ts +1 -1
- package/src/observability/metrics.ts +4 -4
- package/src/observability/payload-capture.ts +6 -5
- package/src/observability/payload-store.ts +1 -1
- package/src/observability/runtime-metrics.ts +1 -1
- package/src/observability/telemetry-buffer.ts +12 -3
- package/src/observability/telemetry-reconciliation.ts +3 -3
- package/src/observability/token-speed.ts +1 -1
- package/src/persistence/connection-url.ts +1 -1
- package/src/persistence/db-handle.ts +1 -1
- package/src/persistence/db-pg.ts +2 -2
- package/src/persistence/db-sqlite.ts +3 -3
- package/src/persistence/dialect.ts +5 -1
- package/src/persistence/readiness.ts +1 -1
- package/src/persistence/redis.ts +1 -1
- package/src/persistence/schema.ts +113 -40
- package/src/persistence/shared-cache.ts +2 -2
- package/src/persistence/sort-order.ts +1 -1
- package/src/persistence/stores/api-key-store.ts +10 -1
- package/src/persistence/stores/share-store.ts +20 -8
- package/src/persistence/system-prompt-store.ts +63 -18
- package/src/persistence/tenant-preferences.ts +1 -1
- package/src/persistence/ttl-cache.ts +3 -3
- package/src/persistence/usage-flush.ts +7 -2
- package/src/protocol/canonical-model.ts +1 -1
- package/src/protocol/codecs.ts +6 -10
- package/src/protocol/dsml.ts +3 -49
- package/src/protocol/image-clamp.ts +2 -2
- package/src/protocol/reasoning-text.ts +1 -1
- package/src/protocol/reasoning.ts +7 -52
- package/src/protocol/registry.ts +50 -15
- package/src/protocol/request/chat.ts +46 -19
- package/src/protocol/request/codex.ts +1 -1
- package/src/protocol/request/messages.ts +46 -14
- package/src/protocol/request/responses.ts +19 -10
- package/src/protocol/response/chat.ts +25 -10
- package/src/protocol/response/codex.ts +1 -1
- package/src/protocol/response/messages.ts +1 -1
- package/src/protocol/response/omp-tool-call-markup.ts +1 -1
- package/src/protocol/response/responses.ts +1 -1
- package/src/protocol/sse-decoder.ts +50 -1
- package/src/protocol/stop-reason.ts +2 -2
- package/src/protocol/think-split.ts +347 -0
- package/src/protocol/translation/attachment-integrity.ts +3 -3
- package/src/protocol/translation/cache-controls.ts +8 -20
- package/src/protocol/translation/capabilities.ts +6 -6
- package/src/protocol/translation/dialect/deepseek.ts +10 -0
- package/src/protocol/translation/dialect/inband.ts +39 -0
- package/src/protocol/translation/dialect/model-thinking.ts +89 -0
- package/src/protocol/translation/dialect/qwen.ts +114 -0
- package/src/protocol/translation/dialect/resolver.ts +83 -0
- package/src/protocol/translation/dialect/rules.ts +93 -0
- package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
- package/src/protocol/translation/dialect/types.ts +58 -0
- package/src/protocol/translation/quirks.ts +18 -4
- package/src/protocol/translation/thinking.ts +12 -252
- package/src/protocol/translation/tool-id.ts +3 -3
- package/src/protocol/translation/tool-repair.ts +1 -1
- package/src/protocol/upstream/post-json.ts +6 -1
- package/src/providers/adapters/compatible-adapter.ts +42 -3
- package/src/providers/authentication/jwt-validator.ts +0 -5
- package/src/providers/authentication/oauth-client.ts +254 -253
- package/src/providers/authentication/oauth-flow-store.ts +42 -7
- package/src/providers/bundled-discovery-providers.ts +6 -30
- package/src/providers/configured-openai-providers.ts +82 -97
- package/src/providers/default-registry.ts +23 -35
- package/src/providers/discovery/catalog/catalog-format.ts +13 -2
- package/src/providers/discovery/discovery-types.ts +0 -1
- package/src/providers/discovery/openai-model-discovery.ts +2 -2
- package/src/providers/discovery/probe-phases.ts +48 -13
- package/src/providers/discovery/probing-service.ts +6 -8
- package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
- package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +0 -14
- package/src/providers/integrations/antigravity/antigravity.ts +2 -2
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
- package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
- package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
- package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
- package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
- package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
- package/src/providers/integrations/claude/claude-cch.ts +148 -148
- package/src/providers/integrations/claude/fallback-credit.ts +3 -7
- package/src/providers/integrations/cline/cline.ts +1 -1
- package/src/providers/integrations/codex/codex-device-code.ts +101 -101
- package/src/providers/integrations/codex/codex-oauth.ts +0 -1
- package/src/providers/integrations/commandcode/commandcode.ts +75 -115
- package/src/providers/integrations/commandcode/quota.ts +131 -51
- package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
- package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
- package/src/providers/integrations/cursor/cursor-request.ts +0 -87
- package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
- package/src/providers/integrations/cursor/cursor.ts +38 -5
- package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
- package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
- package/src/providers/integrations/factory/factory.ts +9 -9
- package/src/providers/integrations/github/github-discovery.ts +55 -10
- package/src/providers/integrations/github/github-oauth.ts +6 -5
- package/src/providers/integrations/github/github.ts +41 -14
- package/src/providers/integrations/grok/grok-oauth.ts +261 -261
- package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
- package/src/providers/integrations/grok/grok-quota.ts +16 -7
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
- package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
- package/src/providers/integrations/grok/grok.ts +86 -36
- package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
- package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
- package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
- package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
- package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
- package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
- package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
- package/src/providers/integrations/kiro/kiro-request.ts +8 -11
- package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
- package/src/providers/integrations/kiro/kiro.ts +81 -68
- package/src/providers/integrations/muse/muse-oauth.ts +0 -1
- package/src/providers/integrations/muse/muse-quota.ts +0 -4
- package/src/providers/integrations/opencode/fingerprint.ts +7 -5
- package/src/providers/integrations/opencode/provider.ts +17 -24
- package/src/providers/integrations/qoder/qoder-catalog.ts +85 -8
- package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
- package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
- package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
- package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
- package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
- package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
- package/src/providers/integrations/qoder/qoder.ts +354 -62
- package/src/providers/integrations/shared/connect.ts +0 -54
- package/src/providers/integrations/shared/hash.ts +15 -0
- package/src/providers/integrations/shared/session-cache.ts +136 -0
- package/src/providers/integrations/trae/trae-cache.ts +7 -87
- package/src/providers/integrations/trae/trae-catalog.ts +1 -6
- package/src/providers/integrations/trae/trae-protocol.ts +17 -8
- package/src/providers/integrations/trae/trae-realm.ts +0 -7
- package/src/providers/integrations/trae/trae.ts +53 -10
- package/src/providers/integrations/xai/xai-oauth.ts +5 -5
- package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
- package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
- package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
- package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
- package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
- package/src/providers/operations/account-error-classification.ts +131 -116
- package/src/providers/operations/account-health-service.ts +31 -39
- package/src/providers/operations/account-reset-service.ts +58 -1
- package/src/providers/operations/cli-platform.ts +31 -5
- package/src/providers/operations/client-version-resolver.ts +4 -6
- package/src/providers/operations/client-versions.ts +10 -7
- package/src/providers/operations/provider-catalog-seeder.ts +2 -0
- package/src/providers/operations/provider-catalog-service.ts +18 -2
- package/src/providers/operations/provider-credential-service.ts +19 -2
- package/src/providers/provider-contracts.ts +18 -7
- package/src/providers/provider-metadata.ts +17 -2
- package/src/providers/provider-model-definition.ts +22 -1
- package/src/providers/provider-probe.ts +4 -2
- package/src/providers/provider-usage.ts +81 -16
- package/src/providers/quota/cache.ts +29 -0
- package/src/providers/quota/quota-contracts.ts +4 -0
- package/src/providers/quota/refresh.ts +27 -4
- package/src/providers/quota/snapshot.ts +94 -0
- package/src/providers/search/search-provider.ts +1 -3
- package/src/providers/search/search-providers.ts +2 -1
- package/src/security/abuse.ts +4 -4
- package/src/security/admission/service.ts +2 -2
- package/src/security/admission/ttl.ts +61 -61
- package/src/security/api-key-auth.ts +16 -4
- package/src/security/client-router-fingerprint.ts +4 -4
- package/src/security/credential-codec.ts +3 -3
- package/src/security/csrf.ts +2 -2
- package/src/security/ip-boundary.ts +16 -189
- package/src/security/model-access-rule.ts +1 -1
- package/src/security/outbound-headers.ts +18 -0
- package/src/shared/invoke-guard.ts +47 -0
- package/src/transport/contracts.ts +13 -4
- package/src/transport/dispatch/attempt-finalize.ts +1 -1
- package/src/transport/dispatch/capture-policy.ts +34 -37
- package/src/transport/dispatch/empty-stream.ts +23 -20
- package/src/transport/dispatch/generation.ts +25 -45
- package/src/transport/dispatch/native-shared.ts +127 -0
- package/src/transport/dispatch/proxy-request.ts +3 -1
- package/src/transport/dispatch/responses-compact.ts +25 -46
- package/src/transport/dispatch/streaming/encoder.ts +18 -72
- package/src/transport/dispatch/streaming/finalize.ts +2 -2
- package/src/transport/dispatch/streaming/stream.ts +7 -3
- package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
- package/src/transport/dispatch/systemone.ts +20 -48
- package/src/transport/dispatch/token-count.ts +41 -38
- package/src/transport/dispatch/websearch.ts +19 -45
- package/src/transport/drain-endpoint.ts +1 -1
- package/src/transport/failure-policy.ts +6 -0
- package/src/transport/guards/auth-guard.ts +0 -6
- package/src/transport/guards/body-policy.ts +3 -3
- package/src/transport/guards/headroom-guard.ts +1 -1
- package/src/transport/guards/pipeline.ts +1 -1
- package/src/transport/guards/request-context.ts +12 -17
- package/src/transport/request/preparer.ts +286 -7
- package/src/transport/request/rtk/compress-request.ts +3 -3
- package/src/transport/request/rtk/rtk-constants.ts +2 -2
- package/src/transport/request/rtk/rtk-filters.ts +8 -8
- package/src/transport/request/state.ts +1 -13
- package/src/transport/request/system-prompt-injection.ts +74 -11
- package/src/transport/request/tenant-preferences.ts +22 -0
- package/src/transport/routing/candidate-index.ts +2 -2
- package/src/transport/routing/round-robin.ts +1 -1
- package/src/transport/routing/route-catalog.ts +17 -18
- package/src/transport/routing/route-model.ts +126 -33
- package/src/transport/routing/router.ts +152 -37
- package/src/transport/shutdown-notice.ts +2 -2
- package/src/transport/surface/adapters.ts +3 -3
- package/src/transport/surface/chat/encode.ts +7 -7
- package/src/transport/surface/chat/parse.ts +7 -7
- package/src/transport/surface/completion.ts +2 -2
- package/src/transport/surface/content-parts.ts +1 -1
- package/src/transport/surface/dialects.ts +2 -2
- package/src/transport/surface/messages/parse.ts +3 -3
- package/src/transport/surface/responses/adapter.ts +1 -1
- package/src/transport/surface/responses/errors.ts +0 -9
- package/src/transport/vision-handoff-cache.ts +58 -0
- package/src/transport/vision-handoff.ts +376 -0
- package/src/workers/account-identity-sweep.ts +2 -2
- package/src/workers/buddy-growth-tasks.ts +392 -346
- package/src/workers/daily-checkin.ts +102 -49
- package/src/workers/maintenance-lease.ts +2 -35
- package/src/workers/oauth-refresh-sweep.ts +8 -1
- package/src/workers/quota-refresh-sweep.ts +120 -82
- package/src/workers/scheduler.ts +67 -4
- package/src/workers/sweep-runner.ts +24 -5
- package/src/workers/zcode-gift-claim.ts +108 -0
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
- package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
- package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
- package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
- package/dist/dashboard/assets/app-a159k0ub.css +0 -2
- package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
- package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
- package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
- package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
- package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
- package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
- package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
- package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
- package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
- package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
- package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
- package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
- package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
- package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
- package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
- package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
- package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
- package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
- package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
- package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
- package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
- package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
- package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
- package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
- package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
- package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
- package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
- package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
- package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
- package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
- package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
- package/src/network/response-headers.ts +0 -39
- package/src/protocol/response/dsml.ts +0 -38
- package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
- /package/dist/dashboard/assets/{app-BayTTy01.js → app-Bgd3zANQ.js} +0 -0
- /package/dist/dashboard/assets/{app-BayTTy01.js.gz → app-Bgd3zANQ.js.gz} +0 -0
- /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
- /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
|
@@ -10,39 +10,13 @@ import { createApiKeyAdapter, type ApiKeyProviderSpec } from "./configured-provi
|
|
|
10
10
|
* OpenAI-compatible contract. Providers with static catalogs or additional
|
|
11
11
|
* upstream behavior remain declared beside their special handling.
|
|
12
12
|
*/
|
|
13
|
-
export const DISCOVERY_BACKED_PROVIDER_IDS = [
|
|
14
|
-
"groq",
|
|
15
|
-
"together",
|
|
16
|
-
"deepinfra",
|
|
17
|
-
"siliconflow",
|
|
18
|
-
"siliconflowcn",
|
|
19
|
-
"novita",
|
|
20
|
-
"larprouter",
|
|
21
|
-
"venice",
|
|
22
|
-
"nanogpt",
|
|
23
|
-
"baseten",
|
|
24
|
-
"synthetic",
|
|
25
|
-
"stepfun",
|
|
26
|
-
"sakana",
|
|
27
|
-
"helmcode",
|
|
28
|
-
"coralbricks",
|
|
29
|
-
"aiand",
|
|
30
|
-
"wafer",
|
|
31
|
-
"firepass",
|
|
32
|
-
"zhipucoding",
|
|
33
|
-
"dashscope",
|
|
34
|
-
"qianfan",
|
|
35
|
-
] as const;
|
|
36
|
-
|
|
37
|
-
export type DiscoveryBackedProviderId = (typeof DISCOVERY_BACKED_PROVIDER_IDS)[number];
|
|
38
|
-
|
|
39
13
|
type DiscoveryBackedCapabilities = Pick<
|
|
40
14
|
ProviderModule,
|
|
41
15
|
"endpointPathsByWireFamily" | "loadAdapter" | "loadModelDiscovery"
|
|
42
16
|
>;
|
|
43
17
|
|
|
44
18
|
type ModelDiscoveryFactory = NonNullable<ProviderModule["loadModelDiscovery"]>;
|
|
45
|
-
type OpenAIModelDiscoveryFactory = (
|
|
19
|
+
export type OpenAIModelDiscoveryFactory = (
|
|
46
20
|
providerId: string,
|
|
47
21
|
options?: {
|
|
48
22
|
readonly headers?: (credential: string) => Readonly<Record<string, string>>;
|
|
@@ -71,10 +45,12 @@ const DISCOVERY_BACKED_PROVIDER_SPECS = {
|
|
|
71
45
|
zhipucoding: VERSIONED_ROOT_API_KEY_SPECS.zhipucoding,
|
|
72
46
|
dashscope: GENERIC_API_KEY_SPECS.dashscope,
|
|
73
47
|
qianfan: VERSIONED_ROOT_API_KEY_SPECS.qianfan,
|
|
74
|
-
} satisfies Readonly<Record<
|
|
48
|
+
} satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
|
|
75
49
|
|
|
76
|
-
|
|
77
|
-
|
|
50
|
+
type DiscoveryBackedProviderId = keyof typeof DISCOVERY_BACKED_PROVIDER_SPECS;
|
|
51
|
+
|
|
52
|
+
export function discoveryBackedCapabilities(
|
|
53
|
+
providerId: string,
|
|
78
54
|
spec: ApiKeyProviderSpec,
|
|
79
55
|
openAIModelDiscovery: OpenAIModelDiscoveryFactory,
|
|
80
56
|
): DiscoveryBackedCapabilities {
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
import type { ApiKeyProviderSpec } from "./configured-provider";
|
|
2
2
|
import type { ProviderId } from "./provider-contracts";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The shared spec builder for every builtin bearer-AI provider: "bearer auth
|
|
6
|
+
* against the provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible
|
|
7
|
+
* chat + responses, with the endpoint paths declared *below* the version root".
|
|
8
|
+
*
|
|
9
|
+
* `joinUrl` is plain concatenation and nothing rewrites a declared path, so a
|
|
10
|
+
* base already rooted at a version (`/openai/v1`, `/v1/openai`, `/v3/openai`,
|
|
11
|
+
* `/api/v1`, `/v2`, `/inference/v1`) plus a `/v1/…` path would double the
|
|
12
|
+
* segment and 404 every request. These specs therefore declare the path below
|
|
13
|
+
* the version root — the provider stating the truth about its own wire, not a
|
|
14
|
+
* correction applied to it.
|
|
15
|
+
*/
|
|
16
|
+
function apiKeySpec(
|
|
17
|
+
providerId: ProviderId,
|
|
18
|
+
paths: Readonly<Partial<Record<"chat" | "responses", string>>>,
|
|
19
|
+
): ApiKeyProviderSpec {
|
|
20
|
+
return {
|
|
21
|
+
provider_id: providerId,
|
|
22
|
+
endpoint_paths_by_wire_family: paths,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const BEARER_PATHS = { chat: "/chat/completions", responses: "/responses" } as const;
|
|
27
|
+
|
|
4
28
|
/**
|
|
5
29
|
* Builtin providers whose entire adapter contract is "bearer auth against the
|
|
6
30
|
* provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible chat +
|
|
7
|
-
* responses,
|
|
8
|
-
* provider-specific payload hook, so they
|
|
9
|
-
* one module each.
|
|
31
|
+
* responses, with endpoint paths declared below the base's version root". They
|
|
32
|
+
* carry no catalog, no OAuth, and no provider-specific payload hook, so they
|
|
33
|
+
* share one spec shape rather than one module each.
|
|
10
34
|
*
|
|
11
35
|
* `base_url` is resolved per provider by `providerBaseUrl(provider_id)`.
|
|
12
36
|
*
|
|
@@ -14,29 +38,31 @@ import type { ProviderId } from "./provider-contracts";
|
|
|
14
38
|
* than a static catalog: every one of them republishes an aggregator's whole
|
|
15
39
|
* roster, which changes faster than a committed array can. Each registry row
|
|
16
40
|
* pairs this spec with `openAIModelDiscovery`.
|
|
41
|
+
*
|
|
42
|
+
* The id list is derived from the spec record so the two cannot drift apart.
|
|
17
43
|
*/
|
|
18
|
-
export const
|
|
19
|
-
"larprouter",
|
|
20
|
-
"mistral",
|
|
21
|
-
"fireworks",
|
|
22
|
-
"nvidia",
|
|
23
|
-
"gmi",
|
|
24
|
-
"ollamacloud",
|
|
25
|
-
"together",
|
|
26
|
-
"siliconflow",
|
|
27
|
-
"siliconflowcn",
|
|
28
|
-
"nanogpt",
|
|
29
|
-
"baseten",
|
|
30
|
-
"synthetic",
|
|
31
|
-
"stepfun",
|
|
32
|
-
"sakana",
|
|
33
|
-
"helmcode",
|
|
34
|
-
"coralbricks",
|
|
35
|
-
"aiand",
|
|
36
|
-
"wafer",
|
|
37
|
-
"coreweave",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
44
|
+
export const GENERIC_API_KEY_SPECS = {
|
|
45
|
+
larprouter: apiKeySpec("larprouter", BEARER_PATHS),
|
|
46
|
+
mistral: apiKeySpec("mistral", BEARER_PATHS),
|
|
47
|
+
fireworks: apiKeySpec("fireworks", BEARER_PATHS),
|
|
48
|
+
nvidia: apiKeySpec("nvidia", BEARER_PATHS),
|
|
49
|
+
gmi: apiKeySpec("gmi", BEARER_PATHS),
|
|
50
|
+
ollamacloud: apiKeySpec("ollamacloud", BEARER_PATHS),
|
|
51
|
+
together: apiKeySpec("together", BEARER_PATHS),
|
|
52
|
+
siliconflow: apiKeySpec("siliconflow", BEARER_PATHS),
|
|
53
|
+
siliconflowcn: apiKeySpec("siliconflowcn", BEARER_PATHS),
|
|
54
|
+
nanogpt: apiKeySpec("nanogpt", BEARER_PATHS),
|
|
55
|
+
baseten: apiKeySpec("baseten", BEARER_PATHS),
|
|
56
|
+
synthetic: apiKeySpec("synthetic", BEARER_PATHS),
|
|
57
|
+
stepfun: apiKeySpec("stepfun", BEARER_PATHS),
|
|
58
|
+
sakana: apiKeySpec("sakana", BEARER_PATHS),
|
|
59
|
+
helmcode: apiKeySpec("helmcode", BEARER_PATHS),
|
|
60
|
+
coralbricks: apiKeySpec("coralbricks", BEARER_PATHS),
|
|
61
|
+
aiand: apiKeySpec("aiand", BEARER_PATHS),
|
|
62
|
+
wafer: apiKeySpec("wafer", BEARER_PATHS),
|
|
63
|
+
coreweave: apiKeySpec("coreweave", BEARER_PATHS),
|
|
64
|
+
dashscope: apiKeySpec("dashscope", BEARER_PATHS),
|
|
65
|
+
"qwen-portal": apiKeySpec("qwen-portal", BEARER_PATHS),
|
|
40
66
|
// `deepseek` is intentionally absent: it dispatches on the Anthropic Messages
|
|
41
67
|
// wire at its `/anthropic` root, not the OpenAI chat/responses wires, so it
|
|
42
68
|
// carries a dedicated entry in `default-registry.ts` instead.
|
|
@@ -45,10 +71,24 @@ export const GENERIC_API_KEY_PROVIDER_IDS = [
|
|
|
45
71
|
// already rooted at a version segment that the `/v1`-prefixed path this shape
|
|
46
72
|
// pins would duplicate (`/openai/v1`, `/v1/openai`, `/v3/openai`, `/api/v1`,
|
|
47
73
|
// `/v2`, and `/inference/v1`), so `joinUrl` would produce
|
|
48
|
-
// `…/v1/v1/chat/completions`. They use
|
|
74
|
+
// `…/v1/v1/chat/completions`. They use the versioned-root spec instead,
|
|
49
75
|
// which pins the path below the version root — the same reason `cerebras`
|
|
50
76
|
// declares `/chat/completions` explicitly.
|
|
51
|
-
|
|
77
|
+
} satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* One id that has both a generic spec and a registry row.
|
|
81
|
+
*
|
|
82
|
+
* Exported so the registry can be checked against the spec list rather than
|
|
83
|
+
* repeating the id as a string: `discoveryBackedProvider` takes this type, so a
|
|
84
|
+
* row naming a provider with no spec is a compile error instead of an
|
|
85
|
+
* `undefined` adapter at first dispatch.
|
|
86
|
+
*/
|
|
87
|
+
export type GenericApiKeyProviderId = keyof typeof GENERIC_API_KEY_SPECS;
|
|
88
|
+
|
|
89
|
+
export const GENERIC_API_KEY_PROVIDER_IDS = Object.keys(
|
|
90
|
+
GENERIC_API_KEY_SPECS,
|
|
91
|
+
) as readonly GenericApiKeyProviderId[];
|
|
52
92
|
|
|
53
93
|
/**
|
|
54
94
|
* Ids whose base URL already ends at a version segment.
|
|
@@ -59,77 +99,22 @@ export const GENERIC_API_KEY_PROVIDER_IDS = [
|
|
|
59
99
|
* version root. That is the provider stating the truth about its own wire, not
|
|
60
100
|
* a correction applied to it: a wrong path now reaches the operator as the
|
|
61
101
|
* wrong URL instead of being quietly rewritten into a different address.
|
|
62
|
-
*/
|
|
63
|
-
export const VERSIONED_ROOT_API_KEY_PROVIDER_IDS = [
|
|
64
|
-
"groq",
|
|
65
|
-
"deepinfra",
|
|
66
|
-
"novita",
|
|
67
|
-
"venice",
|
|
68
|
-
"qianfan",
|
|
69
|
-
"zhipucoding",
|
|
70
|
-
"firepass",
|
|
71
|
-
] as const;
|
|
72
|
-
|
|
73
|
-
export type VersionedRootApiKeyProviderId =
|
|
74
|
-
(typeof VERSIONED_ROOT_API_KEY_PROVIDER_IDS)[number];
|
|
75
|
-
|
|
76
|
-
function versionedRootApiKeySpec(providerId: ProviderId): ApiKeyProviderSpec {
|
|
77
|
-
return {
|
|
78
|
-
provider_id: providerId,
|
|
79
|
-
endpoint_paths_by_wire_family: {
|
|
80
|
-
chat: "/chat/completions",
|
|
81
|
-
responses: "/responses",
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export const VERSIONED_ROOT_API_KEY_SPECS = {
|
|
87
|
-
groq: versionedRootApiKeySpec("groq"),
|
|
88
|
-
deepinfra: versionedRootApiKeySpec("deepinfra"),
|
|
89
|
-
novita: versionedRootApiKeySpec("novita"),
|
|
90
|
-
venice: versionedRootApiKeySpec("venice"),
|
|
91
|
-
qianfan: versionedRootApiKeySpec("qianfan"),
|
|
92
|
-
zhipucoding: versionedRootApiKeySpec("zhipucoding"),
|
|
93
|
-
firepass: versionedRootApiKeySpec("firepass"),
|
|
94
|
-
} satisfies Readonly<Record<VersionedRootApiKeyProviderId, ApiKeyProviderSpec>>;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* One id that has both a generic spec and a registry row.
|
|
98
102
|
*
|
|
99
|
-
*
|
|
100
|
-
* repeating the id as a string: `discoveryBackedProvider` takes this type, so a
|
|
101
|
-
* row naming a provider with no spec is a compile error instead of an
|
|
102
|
-
* `undefined` adapter at first dispatch.
|
|
103
|
+
* The id list is derived from the spec record so the two cannot drift apart.
|
|
103
104
|
*/
|
|
104
|
-
export
|
|
105
|
+
export const VERSIONED_ROOT_API_KEY_SPECS = {
|
|
106
|
+
groq: apiKeySpec("groq", BEARER_PATHS),
|
|
107
|
+
deepinfra: apiKeySpec("deepinfra", BEARER_PATHS),
|
|
108
|
+
novita: apiKeySpec("novita", BEARER_PATHS),
|
|
109
|
+
venice: apiKeySpec("venice", BEARER_PATHS),
|
|
110
|
+
qianfan: apiKeySpec("qianfan", BEARER_PATHS),
|
|
111
|
+
zhipucoding: apiKeySpec("zhipucoding", BEARER_PATHS),
|
|
112
|
+
firepass: apiKeySpec("firepass", BEARER_PATHS),
|
|
113
|
+
} satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
|
|
105
114
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// — so the path is declared below that root. Both spec shapes declare the same
|
|
109
|
-
// thing, so this is the one implementation.
|
|
110
|
-
return versionedRootApiKeySpec(providerId);
|
|
111
|
-
}
|
|
115
|
+
export type VersionedRootApiKeyProviderId =
|
|
116
|
+
keyof typeof VERSIONED_ROOT_API_KEY_SPECS;
|
|
112
117
|
|
|
113
|
-
export const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
fireworks: genericApiKeySpec("fireworks"),
|
|
117
|
-
nvidia: genericApiKeySpec("nvidia"),
|
|
118
|
-
gmi: genericApiKeySpec("gmi"),
|
|
119
|
-
ollamacloud: genericApiKeySpec("ollamacloud"),
|
|
120
|
-
together: genericApiKeySpec("together"),
|
|
121
|
-
siliconflow: genericApiKeySpec("siliconflow"),
|
|
122
|
-
siliconflowcn: genericApiKeySpec("siliconflowcn"),
|
|
123
|
-
nanogpt: genericApiKeySpec("nanogpt"),
|
|
124
|
-
baseten: genericApiKeySpec("baseten"),
|
|
125
|
-
synthetic: genericApiKeySpec("synthetic"),
|
|
126
|
-
stepfun: genericApiKeySpec("stepfun"),
|
|
127
|
-
sakana: genericApiKeySpec("sakana"),
|
|
128
|
-
helmcode: genericApiKeySpec("helmcode"),
|
|
129
|
-
coralbricks: genericApiKeySpec("coralbricks"),
|
|
130
|
-
aiand: genericApiKeySpec("aiand"),
|
|
131
|
-
wafer: genericApiKeySpec("wafer"),
|
|
132
|
-
coreweave: genericApiKeySpec("coreweave"),
|
|
133
|
-
dashscope: genericApiKeySpec("dashscope"),
|
|
134
|
-
"qwen-portal": genericApiKeySpec("qwen-portal"),
|
|
135
|
-
} satisfies Readonly<Record<GenericApiKeyProviderId, ApiKeyProviderSpec>>;
|
|
118
|
+
export const VERSIONED_ROOT_API_KEY_PROVIDER_IDS = Object.keys(
|
|
119
|
+
VERSIONED_ROOT_API_KEY_SPECS,
|
|
120
|
+
) as readonly VersionedRootApiKeyProviderId[];
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import {
|
|
6
6
|
GENERIC_API_KEY_SPECS,
|
|
7
7
|
} from "./configured-openai-providers";
|
|
8
|
-
import { createDiscoveryBackedProviderCapabilities } from "./bundled-discovery-providers";
|
|
8
|
+
import { createDiscoveryBackedProviderCapabilities, discoveryBackedCapabilities } from "./bundled-discovery-providers";
|
|
9
9
|
import { createApiKeyAdapter } from "./configured-provider";
|
|
10
10
|
import type { ApiKeyProviderSpec } from "./configured-provider";
|
|
11
11
|
import { oauthCapability, quotaCapability, type ProviderModuleCapabilities } from "./provider-capabilities";
|
|
@@ -131,39 +131,6 @@ function qoderDiscovery(
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
/**
|
|
135
|
-
* Builds the `loadAdapter` + `loadModelDiscovery` pair every plain bearer
|
|
136
|
-
* provider needs.
|
|
137
|
-
*
|
|
138
|
-
* Only the base URL differs between them, so both halves are shared: the
|
|
139
|
-
* adapter is the generic spec and the discovery call is a bearer
|
|
140
|
-
* `GET {base}/models`. Keeping them in one function is what stops the pairing
|
|
141
|
-
* from drifting — registering a provider with one half and not the other is
|
|
142
|
-
* exactly how `gmi`, `nvidia`, and `fireworks` came to ship with no catalog
|
|
143
|
-
* *and* no discovery, which is a provider that lists zero models with no way to
|
|
144
|
-
* fetch any. `test/providers/generic-provider-completeness.test.ts` holds both.
|
|
145
|
-
*/
|
|
146
|
-
function discoveryBacked(
|
|
147
|
-
providerId: string,
|
|
148
|
-
spec: ApiKeyProviderSpec,
|
|
149
|
-
): ProviderModuleCapabilities {
|
|
150
|
-
return {
|
|
151
|
-
// The registry map is what discovery and probing read
|
|
152
|
-
// (`discoveryPathsFor`), while the spec's copy is what the adapter
|
|
153
|
-
// dispatches on. Setting only the spec leaves a discovered model resolving
|
|
154
|
-
// its wire from the generic default instead of the path the adapter will
|
|
155
|
-
// actually call, which is how a probe verifies one endpoint while dispatch
|
|
156
|
-
// hits another.
|
|
157
|
-
...(spec.endpoint_paths_by_wire_family === undefined
|
|
158
|
-
? {}
|
|
159
|
-
: { endpointPathsByWireFamily: spec.endpoint_paths_by_wire_family }),
|
|
160
|
-
loadAdapter: async () => createApiKeyAdapter(spec),
|
|
161
|
-
loadModelDiscovery: openAIModelDiscovery(providerId, {
|
|
162
|
-
headers: (credential) => ({ authorization: `Bearer ${credential}` }),
|
|
163
|
-
}),
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
134
|
function openAIModelDiscovery(
|
|
168
135
|
providerId: string,
|
|
169
136
|
options?: {
|
|
@@ -617,6 +584,27 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
617
584
|
// and Z.AI publishes no refresh grant for it (`refresh "none"` upstream).
|
|
618
585
|
loadAuthentication: oauthCapability(() => import("./integrations/zcode/oauth"), "zcodeOAuthClient"),
|
|
619
586
|
},
|
|
587
|
+
"zcode-start": {
|
|
588
|
+
// Free plan surface: an Anthropic-Messages endpoint that only accepts the
|
|
589
|
+
// dressed ZCode client request (see the integration). The credential is a
|
|
590
|
+
// ZCode login JWT — pasted, or minted by the sign-in flow below.
|
|
591
|
+
loadAdapter: async () =>
|
|
592
|
+
createApiKeyAdapter(
|
|
593
|
+
(await import("./integrations/zcode-start-plan/provider")).ZCODE_START_PLAN_SPEC,
|
|
594
|
+
),
|
|
595
|
+
loadModels: async () =>
|
|
596
|
+
(await import("./integrations/zcode-start-plan/provider")).ZCODE_START_PLAN_MODELS,
|
|
597
|
+
// The device flow stores the issued ZCode login JWT, not a Coding Plan key.
|
|
598
|
+
loadAuthentication: oauthCapability(
|
|
599
|
+
() => import("./integrations/zcode-start-plan/oauth"),
|
|
600
|
+
"zcodeStartPlanOAuthClient",
|
|
601
|
+
),
|
|
602
|
+
// Keep each reported entitlement and activation/reset window separate.
|
|
603
|
+
loadQuotaCollector: quotaCapability(
|
|
604
|
+
() => import("./integrations/zcode-start-plan/quota"),
|
|
605
|
+
"fetchZcodeStartPlanQuota",
|
|
606
|
+
),
|
|
607
|
+
},
|
|
620
608
|
"factory": {
|
|
621
609
|
loadAdapter: async () => (await import("./integrations/factory/factory")).factoryAdapter,
|
|
622
610
|
// Factory publishes no model-listing endpoint — the roster is a client-side
|
|
@@ -765,7 +753,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
765
753
|
// synced account sees whatever the plan currently serves. The catalog keeps
|
|
766
754
|
// the provider usable before anyone syncs.
|
|
767
755
|
dashscope: {
|
|
768
|
-
...
|
|
756
|
+
...discoveryBackedCapabilities("dashscope", GENERIC_API_KEY_SPECS.dashscope, openAIModelDiscovery),
|
|
769
757
|
loadModels: async () => (await import("./integrations/dashscope-models")).DASHSCOPE_MODELS,
|
|
770
758
|
},
|
|
771
759
|
|
|
@@ -420,13 +420,24 @@ export class PackedCatalog {
|
|
|
420
420
|
return metadata;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
-
/**
|
|
423
|
+
/**
|
|
424
|
+
* Stated context limit, or `null`.
|
|
425
|
+
*
|
|
426
|
+
* Stored in a `Uint32Array` column; the generator
|
|
427
|
+
* (`scripts/tools/generate-models.ts`) refuses to write a value ≥ 2^31
|
|
428
|
+
* (`checkedPackedLimit`), so no row here can wrap modulo 2^32 and decode as a
|
|
429
|
+
* garbage limit.
|
|
430
|
+
*/
|
|
424
431
|
rowContext(index: number): number | null {
|
|
425
432
|
const value = this.u32At(this.layout.ctx + index * 4);
|
|
426
433
|
return value > 0 ? value : null;
|
|
427
434
|
}
|
|
428
435
|
|
|
429
|
-
/**
|
|
436
|
+
/**
|
|
437
|
+
* Stated output limit, or `null`.
|
|
438
|
+
*
|
|
439
|
+
* Same u32 storage contract as `rowContext` — see the generator guard.
|
|
440
|
+
*/
|
|
430
441
|
rowOutput(index: number): number | null {
|
|
431
442
|
const value = this.u32At(this.layout.out + index * 4);
|
|
432
443
|
return value > 0 ? value : null;
|
|
@@ -3,6 +3,7 @@ import { isRecord } from "../../protocol/codecs";
|
|
|
3
3
|
import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../provider-sanitize";
|
|
4
4
|
import { modelsDevCatalog } from "./models-dev-catalog";
|
|
5
5
|
import { isResponsesNativeModelId } from "../provider-model-definition";
|
|
6
|
+
import { composeAbortSignal } from "../authentication/oauth-flow-store";
|
|
6
7
|
interface FetchModelsOptions {
|
|
7
8
|
readonly baseUrl: string;
|
|
8
9
|
/**
|
|
@@ -27,8 +28,7 @@ export async function fetchOpenAICompatibleModels(
|
|
|
27
28
|
): Promise<readonly ModelDefinition[] | null> {
|
|
28
29
|
const fetcher = options.fetcher ?? fetch;
|
|
29
30
|
const url = `${options.baseUrl.replace(/\/+$/, "")}/models`;
|
|
30
|
-
const
|
|
31
|
-
const signal = options.signal === undefined ? timeoutSignal : AbortSignal.any([options.signal, timeoutSignal]);
|
|
31
|
+
const signal = composeAbortSignal(options.signal, 10_000);
|
|
32
32
|
try {
|
|
33
33
|
const response = await fetcher(url, {
|
|
34
34
|
headers: {
|
|
@@ -74,8 +74,24 @@ export function wireContextFrom(
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/**
|
|
78
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Grok's account feature probe intentionally uses the same Responses request as
|
|
79
|
+
* live traffic.
|
|
80
|
+
*
|
|
81
|
+
* The prompt must make the model actually reply `407` — that literal is the
|
|
82
|
+
* healthy-account signal the probe verdict keys on. Naive phrasing refused by
|
|
83
|
+
* the model ("I can't reply with only a specific number", "I won't comply
|
|
84
|
+
* with a demand to output only an exact phrase") are listed above; verified
|
|
85
|
+
* live 2026-11-02 (grok-4.7) that this prompt returns exactly `407`:
|
|
86
|
+
*
|
|
87
|
+
* "Type the number 407." → "407"
|
|
88
|
+
* "Echo the diagnostic code 407." → "407"
|
|
89
|
+
* "Print the number 407 and nothing else." → "407"
|
|
90
|
+
*
|
|
91
|
+
* The verdict normalizes away Grok's trailing confidence annotation
|
|
92
|
+
* (`407 \confidence{100}`), so the match is on the bare number.
|
|
93
|
+
*/
|
|
94
|
+
export const GROK_407_PROBE_PROMPT = "Type the number 407.";
|
|
79
95
|
|
|
80
96
|
/**
|
|
81
97
|
* Converts a failed/mismatched Grok feature probe into a quota-shaped upstream
|
|
@@ -91,8 +107,10 @@ export function grok407ProbeFailure(args: {
|
|
|
91
107
|
if (args.providerId !== "grok" || args.prompt !== GROK_407_PROBE_PROMPT) return undefined;
|
|
92
108
|
const sample = extractSample(args.events);
|
|
93
109
|
const normalizedSample = sample?.replace(/\\confidence\{\d+\}\s*$/i, "").trim();
|
|
94
|
-
// A
|
|
95
|
-
//
|
|
110
|
+
// A healthy account answers exactly `407` (optionally with Grok's trailing
|
|
111
|
+
// confidence annotation). The model refuses some phrasings of the same ask,
|
|
112
|
+
// but the probe prompt above is engineered to pass, so any other sample is a
|
|
113
|
+
// failure — quota-shaped, not a payload bug.
|
|
96
114
|
if (normalizedSample === "407") return undefined;
|
|
97
115
|
const priorDetails = args.dispatchError instanceof GatewayError ? args.dispatchError.details : {};
|
|
98
116
|
const providerStatus =
|
|
@@ -348,6 +366,30 @@ export type ProbeAccountSelection =
|
|
|
348
366
|
| { readonly ok: true; readonly accountId: string | undefined }
|
|
349
367
|
| { readonly ok: false; readonly error: string };
|
|
350
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Selects the first usable account row: status ≠ disabled, cooldown elapsed
|
|
371
|
+
* (unless `allowCoolingAccount`), preferring a tenant-owned account over a
|
|
372
|
+
* shared global one. Shared by the discovery and probing paths so both
|
|
373
|
+
* agree on which account a provider answers as.
|
|
374
|
+
*/
|
|
375
|
+
export function selectUsableAccount<T extends {
|
|
376
|
+
readonly tenantId: string | null;
|
|
377
|
+
readonly status: string;
|
|
378
|
+
readonly cooldownUntil: Date | null;
|
|
379
|
+
}>(
|
|
380
|
+
rows: readonly T[],
|
|
381
|
+
allowCoolingAccount = false,
|
|
382
|
+
now = Date.now(),
|
|
383
|
+
): T | undefined {
|
|
384
|
+
return rows
|
|
385
|
+
.filter(
|
|
386
|
+
(row) =>
|
|
387
|
+
row.status !== "disabled" &&
|
|
388
|
+
(allowCoolingAccount || row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
|
|
389
|
+
)
|
|
390
|
+
.sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null))[0];
|
|
391
|
+
}
|
|
392
|
+
|
|
351
393
|
/**
|
|
352
394
|
* Phase 2 — pick the account the probe runs as. Snapshot-equivalent health
|
|
353
395
|
* filtering: disabled accounts and live cooldowns never route, so probes must
|
|
@@ -388,15 +430,8 @@ export async function selectProbeAccount(args: {
|
|
|
388
430
|
),
|
|
389
431
|
)
|
|
390
432
|
: [];
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
.filter(
|
|
394
|
-
(row) =>
|
|
395
|
-
row.status !== "disabled" &&
|
|
396
|
-
(allowCoolingAccount || row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
|
|
397
|
-
)
|
|
398
|
-
.sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null));
|
|
399
|
-
const accountId = requestedAccountId ?? usableAccounts[0]?.id;
|
|
433
|
+
const usableAccount = selectUsableAccount(accountRows, allowCoolingAccount);
|
|
434
|
+
const accountId = requestedAccountId ?? usableAccount?.id;
|
|
400
435
|
if (!accountId && requiresAccount) {
|
|
401
436
|
return {
|
|
402
437
|
ok: false,
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
resolveProbeAdapter,
|
|
51
51
|
resolveProbeTarget,
|
|
52
52
|
selectProbeAccount,
|
|
53
|
+
selectUsableAccount,
|
|
53
54
|
wireContextFrom,
|
|
54
55
|
type ProbeProviderRow,
|
|
55
56
|
} from "./probe-phases";
|
|
@@ -915,6 +916,9 @@ export class ProviderProbingService {
|
|
|
915
916
|
source: discDef?.freeTier === true ? "auto_free" : "discovered",
|
|
916
917
|
sourceUpdatedAt,
|
|
917
918
|
enabled: true,
|
|
919
|
+
...(discDef?.dialect === undefined && knownDefinition?.dialect === undefined
|
|
920
|
+
? {}
|
|
921
|
+
: { dialect: discDef?.dialect ?? knownDefinition?.dialect }),
|
|
918
922
|
});
|
|
919
923
|
}
|
|
920
924
|
// One statement per chunk (500, the account-health batch step) instead of
|
|
@@ -936,6 +940,7 @@ export class ProviderProbingService {
|
|
|
936
940
|
cost: sql`excluded.cost`,
|
|
937
941
|
proOnly: sql`excluded.pro_only`,
|
|
938
942
|
freeTier: sql`excluded.free_tier`,
|
|
943
|
+
dialect: sql`excluded.dialect`,
|
|
939
944
|
// The proposed row's own source, not a constant: a free-tier
|
|
940
945
|
// discovery and an ordinary one write the same upsert, and pinning
|
|
941
946
|
// this to `discovered` would relabel every free-tier row on the
|
|
@@ -1000,14 +1005,7 @@ export class ProviderProbingService {
|
|
|
1000
1005
|
globalOrOwnedBy(providerAccounts.tenantId, tenantId),
|
|
1001
1006
|
),
|
|
1002
1007
|
);
|
|
1003
|
-
const
|
|
1004
|
-
const usable = rows
|
|
1005
|
-
.filter(
|
|
1006
|
-
(row) =>
|
|
1007
|
-
row.status !== "disabled" &&
|
|
1008
|
-
(row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
|
|
1009
|
-
)
|
|
1010
|
-
.sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null))[0];
|
|
1008
|
+
const usable = selectUsableAccount(rows);
|
|
1011
1009
|
if (!usable?.credentialCiphertext) return undefined;
|
|
1012
1010
|
const authState = isRecord(usable.authState) ? usable.authState as Readonly<Record<string, unknown>> : undefined;
|
|
1013
1011
|
return {
|
|
@@ -16,9 +16,19 @@ import { readCredentialSecret, assertWireFamily, type ProviderDispatchTarget, ty
|
|
|
16
16
|
import { providerBaseUrl } from "../../provider-metadata";
|
|
17
17
|
import { buildClaudeMessagesRequest } from "../shared/claude-messages";
|
|
18
18
|
import { sendClaudeMessagesRequest } from "../../../protocol/upstream/send-claude-messages";
|
|
19
|
+
import { ANTHROPIC_BETA_CAPABILITIES } from "../claude/claude-betas";
|
|
19
20
|
|
|
20
21
|
export const AGENTROUTER_PROVIDER_ID = "agentrouter" as const;
|
|
21
|
-
|
|
22
|
+
const AGENTROUTER_BASE_URL = `${providerBaseUrl("agentrouter")}/v1/messages?beta=true`;
|
|
23
|
+
|
|
24
|
+
/** The CLI beta set, typed against the canonical Anthropic beta vocabulary. */
|
|
25
|
+
const AGENTROUTER_ANTHROPIC_BETAS: ReadonlyArray<
|
|
26
|
+
keyof typeof ANTHROPIC_BETA_CAPABILITIES
|
|
27
|
+
> = [
|
|
28
|
+
"claude-code-20250219",
|
|
29
|
+
"interleaved-thinking-2025-05-14",
|
|
30
|
+
"effort-2025-11-24",
|
|
31
|
+
];
|
|
22
32
|
|
|
23
33
|
/**
|
|
24
34
|
* The AgentRouter CLI fingerprint headers. Every value is part of the
|
|
@@ -29,7 +39,7 @@ export const AGENTROUTER_BASE_URL = `${providerBaseUrl("agentrouter")}/v1/messag
|
|
|
29
39
|
*/
|
|
30
40
|
function agentRouterFingerprintHeaders(stream: boolean): Record<string, string> {
|
|
31
41
|
return {
|
|
32
|
-
"anthropic-beta": "
|
|
42
|
+
"anthropic-beta": AGENTROUTER_ANTHROPIC_BETAS.join(","),
|
|
33
43
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
34
44
|
"x-app": "cli",
|
|
35
45
|
"user-agent": "claude-cli/2.1.195 (external, sdk-cli)",
|
|
@@ -257,8 +257,6 @@ export function normalizeAntigravityToolSchemas(request: CanonicalRequest): Cano
|
|
|
257
257
|
const lastGoodEndpoints = new Map<string, string>();
|
|
258
258
|
const LAST_GOOD_ENDPOINT_MAX = 256;
|
|
259
259
|
|
|
260
|
-
const DEFAULT_ORDER_INDEX = Number.MAX_SAFE_INTEGER;
|
|
261
|
-
|
|
262
260
|
/**
|
|
263
261
|
* Records the endpoint that just served a successful turn. Call this with the
|
|
264
262
|
* `endpoint` reported by empty-stream recovery (or the URL that produced a
|
|
@@ -301,18 +299,6 @@ export function orderAntigravityEndpoints(
|
|
|
301
299
|
return [sticky, ...endpoints.slice(0, index), ...endpoints.slice(index + 1)];
|
|
302
300
|
}
|
|
303
301
|
|
|
304
|
-
/**
|
|
305
|
-
* Position of `endpoint` in the caller's own endpoint order, used to log a
|
|
306
|
-
* failover without the caller re-deriving the list.
|
|
307
|
-
*/
|
|
308
|
-
export function antigravityEndpointOrderIndex(
|
|
309
|
-
endpoints: readonly string[],
|
|
310
|
-
endpoint: string,
|
|
311
|
-
): number {
|
|
312
|
-
const index = endpoints.indexOf(endpoint);
|
|
313
|
-
return index < 0 ? DEFAULT_ORDER_INDEX : index;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
302
|
// Model discovery (`v1internal:fetchAvailableModels`) — live catalog.
|
|
317
303
|
|
|
318
304
|
const ANTIGRAVITY_DISCOVERY_PATH = "/v1internal:fetchAvailableModels";
|
|
@@ -758,7 +758,7 @@ export class AntigravitySessionStore {
|
|
|
758
758
|
* `"-" + (sha256(first-user-text)[0:8] & INT63 | random <9e18)`.
|
|
759
759
|
* A positive or hyphenated-UUID value here is a one-glance synthetic signal.
|
|
760
760
|
*/
|
|
761
|
-
|
|
761
|
+
function signedAntigravitySessionId(seed?: string): string {
|
|
762
762
|
if (seed !== undefined && /^-?\d+$/.test(seed)) return seed;
|
|
763
763
|
const text = seed !== undefined && seed.length > 0 ? seed : randomUUID();
|
|
764
764
|
const head = BigInt(`0x${createHash("sha256").update(text).digest("hex").slice(0, 8)}`);
|
|
@@ -769,7 +769,7 @@ export function signedAntigravitySessionId(seed?: string): string {
|
|
|
769
769
|
}
|
|
770
770
|
|
|
771
771
|
/** Thinking budget per wire model, matching the client's effort tiers. */
|
|
772
|
-
|
|
772
|
+
function antigravityThinkingBudget(modelId: string): number | undefined {
|
|
773
773
|
if (!modelId.includes("claude") && !modelId.includes("gemini-3")) return undefined;
|
|
774
774
|
if (modelId.endsWith("-low")) return 1_000;
|
|
775
775
|
if (modelId.endsWith("-medium")) return 4_000;
|
|
@@ -160,7 +160,7 @@ export function makeBuddyCnImageModels(
|
|
|
160
160
|
* plan rather than about the model. A pro account serves all six. The pill is
|
|
161
161
|
* therefore a hint about a free account, and a dispatch is what settles it.
|
|
162
162
|
*
|
|
163
|
-
* @see
|
|
163
|
+
* @see `documentation/research/codebuddy/2026-10-19-codebuddy-chat-dispatch-headers.md`
|
|
164
164
|
*/
|
|
165
165
|
export const BUDDY_PRO_ONLY_MODEL_IDS: ReadonlySet<string> = new Set([
|
|
166
166
|
"primary-model",
|