cartethyia 2.4.6 → 2.5.1
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/README.md +45 -13
- package/dist/dashboard/assets/BannedPage-ChqnTRpZ.js +1 -0
- package/dist/dashboard/assets/BannedPage-ChqnTRpZ.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-Bcy150Jo.js → CliToolDetailPage-Bb9CNuoh.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-Bb9CNuoh.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-DyNXefph.js → CliToolsPage-BXUaRCQQ.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BXUaRCQQ.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-CisNZOUt.js +1 -0
- package/dist/dashboard/assets/CombosPage-CisNZOUt.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-CATpAEOz.js → ConsoleLogPage-BOpI_LOH.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-BOpI_LOH.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-D6jEU7nL.js → CustomizationPage-DAkdvJ4k.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-DAkdvJ4k.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-CZkpn0a7.js → HealthEventsModal-DeT-VXHd.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-DeT-VXHd.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-BJlMVN4U.js → LoginPage-CytxSeGP.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CytxSeGP.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-Br3CXEau.js → ModelPicker-oQ-SDXp8.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-oQ-SDXp8.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CU7S1wJs.js +1 -0
- package/dist/dashboard/assets/OverviewPage-CU7S1wJs.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-DLm2baot.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-DLm2baot.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-DOXfuzfL.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-DOXfuzfL.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-wvk0ciQN.js +7 -0
- package/dist/dashboard/assets/ProxyPage-wvk0ciQN.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-Cn_fcUHE.js +1 -0
- package/dist/dashboard/assets/QuotaPage-Cn_fcUHE.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-BHW4Zt06.js → SettingsPage-8-eVadhc.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-8-eVadhc.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-VOYC_lIa.js → SetupPage-uEIXPyGO.js} +1 -1
- package/dist/dashboard/assets/SetupPage-uEIXPyGO.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DCY0TPTZ.js +1 -0
- package/dist/dashboard/assets/SortableList-DCY0TPTZ.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-BNIDLiU6.js → StudioPage-DqK5E26W.js} +4 -4
- package/dist/dashboard/assets/StudioPage-DqK5E26W.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-38JfiZ0H.js +56 -0
- package/dist/dashboard/assets/UsagePage-38JfiZ0H.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-BETfaMYZ.js → api-keys-BmDbsior.js} +1 -1
- package/dist/dashboard/assets/api-keys-BmDbsior.js.gz +0 -0
- package/dist/dashboard/assets/app-BbpSarVV.css +2 -0
- package/dist/dashboard/assets/app-BbpSarVV.css.gz +0 -0
- package/dist/dashboard/assets/assert-BHfaei-X.js +1 -0
- package/dist/dashboard/assets/assert-BHfaei-X.js.gz +0 -0
- package/dist/dashboard/assets/{badge-BTyGk_DL.js → badge-DpXT4Ixt.js} +1 -1
- package/dist/dashboard/assets/badge-DpXT4Ixt.js.gz +0 -0
- package/dist/dashboard/assets/{banner-bujTWYM4.js → banner-CSAAWLJv.js} +1 -1
- package/dist/dashboard/assets/banner-CSAAWLJv.js.gz +0 -0
- package/dist/dashboard/assets/{card-B0Bnx5CA.js → card-DEhRXXw4.js} +1 -1
- package/dist/dashboard/assets/card-DEhRXXw4.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-DE2ug812.js → cli-tools-B0wBq-RL.js} +1 -1
- package/dist/dashboard/assets/cli-tools-B0wBq-RL.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-R_rArH8S.js → clipboard-button-DOo6EU8O.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-DOo6EU8O.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BWIP_EvW.js → dialog-BvQeBMfP.js} +1 -1
- package/dist/dashboard/assets/dialog-BvQeBMfP.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-BKcgVugF.js → drawer-CMwPXwQB.js} +1 -1
- package/dist/dashboard/assets/drawer-CMwPXwQB.js.gz +0 -0
- package/dist/dashboard/assets/entry--yj84zk3.js +4 -0
- package/dist/dashboard/assets/entry--yj84zk3.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CcWkGR4a.js → entry-D4O2229X.js} +1 -1
- package/dist/dashboard/assets/{entry-CcWkGR4a.js.gz → entry-D4O2229X.js.gz} +0 -0
- package/dist/dashboard/assets/{entry-kTiTFrvh.js → entry-DKvr5Q9K.js} +1 -1
- package/dist/dashboard/assets/entry-DKvr5Q9K.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-Booc5mNe.js → github-badge-zliLvBwr.js} +1 -1
- package/dist/dashboard/assets/github-badge-zliLvBwr.js.gz +0 -0
- package/dist/dashboard/assets/{index-D70pChfn.js → index-CcD1eSJ6.js} +2 -2
- package/dist/dashboard/assets/index-CcD1eSJ6.js.gz +0 -0
- package/dist/dashboard/assets/{inline-D1TCqM2D.js → inline-D1IlZZ8H.js} +1 -1
- package/dist/dashboard/assets/inline-D1IlZZ8H.js.gz +0 -0
- package/dist/dashboard/assets/{input-B9oyU93y.js → input-BpVZdrbc.js} +1 -1
- package/dist/dashboard/assets/input-BpVZdrbc.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BArzXirQ.js → layout-BioLW7gN.js} +1 -1
- package/dist/dashboard/assets/layout-BioLW7gN.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BVZzaoHF.js → list-row-CwVcGAIc.js} +1 -1
- package/dist/dashboard/assets/list-row-CwVcGAIc.js.gz +0 -0
- package/dist/dashboard/assets/{live-EmuIayqp.js → live-yfEJFF9T.js} +1 -1
- package/dist/dashboard/assets/live-yfEJFF9T.js.gz +0 -0
- package/dist/dashboard/assets/{model-bans-CSPQ9xB0.js → model-bans-CT-TxSNX.js} +1 -1
- package/dist/dashboard/assets/model-bans-CT-TxSNX.js.gz +0 -0
- package/dist/dashboard/assets/providers/cursor.webp +0 -0
- package/dist/dashboard/assets/providers/trae.webp +0 -0
- package/dist/dashboard/assets/{routing-BExgxxBU.js → routing-Cs6jl49L.js} +1 -1
- package/dist/dashboard/assets/routing-Cs6jl49L.js.gz +0 -0
- package/dist/dashboard/assets/select-XPJ-dIw3.js +41 -0
- package/dist/dashboard/assets/select-XPJ-dIw3.js.gz +0 -0
- package/dist/dashboard/assets/settings-CfcTcOyU.js +1 -0
- package/dist/dashboard/assets/settings-CfcTcOyU.js.gz +0 -0
- package/dist/dashboard/assets/{stack-Ca5HxI5i.js → stack-C9_uUjaA.js} +1 -1
- package/dist/dashboard/assets/stack-C9_uUjaA.js.gz +0 -0
- package/dist/dashboard/assets/{state-CzUPfLXo.js → state-DA0B95UQ.js} +1 -1
- package/dist/dashboard/assets/state-DA0B95UQ.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DOUIky_i.js → switch-Cittxy-x.js} +1 -1
- package/dist/dashboard/assets/switch-Cittxy-x.js.gz +0 -0
- package/dist/dashboard/assets/{toast-C76WrMhc.js → toast-CNt_jzO4.js} +1 -1
- package/dist/dashboard/assets/toast-CNt_jzO4.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-D87FZwH0.js → useMutation-BQKMcJ1H.js} +1 -1
- package/dist/dashboard/assets/useMutation-BQKMcJ1H.js.gz +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +51 -52
- package/migrations/full-postgres/0015_add_payload_stages.sql +18 -0
- package/migrations/full-postgres/0016_add_share_link_slug.sql +20 -0
- package/migrations/full-postgres/0017_add_models_pro_only.sql +18 -0
- package/migrations/full-postgres/0018_add_accounts_quota_plan.sql +18 -0
- package/migrations/full-postgres/0019_add_models_free_tier.sql +15 -0
- package/migrations/lite-sqlite3/0015_add_payload_stages.sql +18 -0
- package/migrations/lite-sqlite3/0016_add_share_link_slug.sql +20 -0
- package/migrations/lite-sqlite3/0017_add_models_pro_only.sql +18 -0
- package/migrations/lite-sqlite3/0018_add_accounts_quota_plan.sql +18 -0
- package/migrations/lite-sqlite3/0019_add_models_free_tier.sql +15 -0
- package/package.json +3 -2
- package/scripts/cli/command/console-menu.ts +30 -11
- package/scripts/cli/command/start.ts +77 -13
- package/scripts/cli/command/tray.ts +47 -8
- package/scripts/cli/command/update.ts +1 -1
- package/scripts/cli/gateway/instance-lock.ts +105 -0
- package/scripts/cli/gateway/spawn.ts +173 -101
- package/scripts/cli/ui/background.ts +110 -49
- package/src/boot/app.ts +20 -6
- package/src/boot/dependencies.ts +19 -0
- package/src/boot/elysia-typebox-bridge.ts +37 -0
- package/src/boot/lifecycle.ts +2 -0
- package/src/config/cooldowns.ts +138 -138
- package/src/config/providers.ts +5 -5
- package/src/config/runtime.ts +19 -3
- package/src/config/spec.ts +9 -0
- package/src/console/api-keys/contracts.ts +414 -391
- package/src/console/api-keys/routes.ts +880 -870
- package/src/console/auth/account-reset-store.ts +14 -0
- package/src/console/auth/account-reset.ts +3 -2
- package/src/console/auth/setup-service.ts +6 -3
- package/src/console/domain-registration.ts +9 -2
- package/src/console/observability/contracts.ts +475 -455
- package/src/console/observability/store.ts +1015 -952
- package/src/console/providers/catalog/contracts.ts +31 -0
- package/src/console/providers/catalog/provider-operations.ts +8 -0
- package/src/console/providers/catalog/store.ts +1532 -1525
- package/src/console/providers/oauth/callback-listener.ts +18 -3
- package/src/console/providers/oauth/routes.ts +38 -15
- package/src/console/quota/refresh.ts +19 -0
- package/src/console/updates/routes.ts +162 -4
- package/src/main.ts +3 -0
- package/src/network/http2-bidi.ts +85 -0
- package/src/network/outbound-fetch.ts +1 -26
- package/src/network/pool/agent.ts +478 -460
- package/src/network/pool/resolver.ts +1104 -544
- package/src/network/pool-health-machine.ts +12 -5
- package/src/observability/payload-capture.ts +344 -324
- package/src/persistence/db-pg.ts +9 -3
- package/src/persistence/db-sqlite.ts +497 -495
- package/src/persistence/health-event-flush.ts +137 -0
- package/src/persistence/migrate.ts +181 -129
- package/src/persistence/schema.ts +1360 -1295
- package/src/persistence/settings-revision.ts +25 -0
- package/src/persistence/shared-cache.ts +217 -0
- package/src/persistence/stores/share-store.ts +556 -528
- package/src/persistence/usage-flush.ts +61 -1
- package/src/protocol/canonical-model.ts +23 -1
- package/src/protocol/response/chat.ts +143 -10
- package/src/protocol/response/omp-tool-call-markup.ts +221 -0
- package/src/providers/default-registry.ts +173 -1
- package/src/providers/discovery/openai-model-discovery.ts +39 -3
- package/src/providers/discovery/openrouter-free-roster.ts +98 -0
- package/src/providers/discovery/probing-service.ts +1022 -1001
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +39 -0
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +913 -914
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +18 -5
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +4 -0
- package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -175
- package/src/providers/integrations/buddy/codebuddy/shared.ts +15 -6
- package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -204
- package/src/providers/integrations/buddy/workbuddy/shared.ts +3 -3
- package/src/providers/integrations/claude/claude.ts +606 -582
- package/src/providers/integrations/cline/cline-quota.ts +18 -16
- package/src/providers/integrations/cline/cline.ts +539 -468
- package/src/providers/integrations/commandcode/commandcode.ts +675 -541
- package/src/providers/integrations/commandcode/discovery.ts +116 -0
- package/src/providers/integrations/commandcode/quota.ts +160 -0
- package/src/providers/integrations/cursor/cursor-auth.ts +418 -0
- package/src/providers/integrations/cursor/cursor-catalog.ts +368 -0
- package/src/providers/integrations/cursor/cursor-http2.ts +300 -0
- package/src/providers/integrations/cursor/cursor-identity.ts +92 -0
- package/src/providers/integrations/cursor/cursor-request.ts +471 -0
- package/src/providers/integrations/cursor/cursor-session-manager.ts +281 -0
- package/src/providers/integrations/cursor/cursor-shared.ts +108 -0
- package/src/providers/integrations/cursor/cursor.ts +960 -0
- package/src/providers/integrations/cursor/protocol/framing.ts +129 -0
- package/src/providers/integrations/cursor/protocol/messages.ts +2355 -0
- package/src/providers/integrations/cursor/protocol/struct.ts +305 -0
- package/src/providers/integrations/github/github.ts +4 -4
- package/src/providers/integrations/hermes.ts +79 -8
- package/src/providers/integrations/kilo/kilo-discovery.ts +10 -1
- package/src/providers/integrations/kilo/kilo.ts +153 -146
- package/src/providers/integrations/opencode/provider.ts +532 -538
- package/src/providers/integrations/openrouter/provider.ts +139 -281
- package/src/providers/integrations/qoder/qoder-catalog.ts +450 -0
- package/src/providers/integrations/qoder/qoder-oauth.ts +310 -257
- package/src/providers/integrations/qoder/qoder-realm.ts +106 -0
- package/src/providers/integrations/qoder/qoder-virtual.ts +77 -0
- package/src/providers/integrations/qoder/qoder.ts +865 -730
- package/src/providers/integrations/trae/trae-catalog.ts +190 -0
- package/src/providers/integrations/trae/trae-headers.ts +149 -0
- package/src/providers/integrations/trae/trae-oauth.ts +773 -0
- package/src/providers/integrations/trae/trae-protocol.ts +400 -0
- package/src/providers/integrations/trae/trae-realm.ts +220 -0
- package/src/providers/integrations/trae/trae.ts +458 -0
- package/src/providers/operations/account-health-service.ts +107 -10
- package/src/providers/operations/client-versions.ts +133 -6
- package/src/providers/operations/provider-catalog-seeder.ts +95 -86
- package/src/providers/operations/provider-credential-service.ts +46 -7
- package/src/providers/provider-contracts.ts +76 -0
- package/src/providers/provider-metadata.ts +78 -6
- package/src/providers/provider-model-definition.ts +373 -349
- package/src/security/api-key-auth.ts +126 -8
- package/src/transport/contracts.ts +3 -0
- package/src/transport/dispatch/attempt-finalize.ts +32 -1
- package/src/transport/dispatch/attempt-loop.ts +530 -515
- package/src/transport/dispatch/generation.ts +88 -21
- package/src/transport/dispatch/leases.ts +99 -2
- package/src/transport/dispatch/proxy-request.ts +60 -3
- package/src/transport/dispatch/streaming/finalize.ts +16 -1
- package/src/transport/dispatch/streaming/stream.ts +22 -2
- package/src/transport/dispatch/upstream.ts +19 -1
- package/src/transport/guards/auth-guard.ts +26 -1
- package/src/transport/guards/body-policy.ts +5 -4
- package/src/transport/request/preparer.ts +103 -0
- package/src/transport/request/state.ts +14 -0
- package/src/transport/routing/plan-gate.ts +45 -0
- package/src/transport/routing/route-catalog.ts +799 -777
- package/src/transport/routing/route-model.ts +52 -1
- package/src/transport/routing/router.ts +51 -0
- package/dist/dashboard/assets/BannedPage-QhvbJB9o.js +0 -1
- package/dist/dashboard/assets/BannedPage-QhvbJB9o.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-Bcy150Jo.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-DyNXefph.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-Cak0ljnO.js +0 -1
- package/dist/dashboard/assets/CombosPage-Cak0ljnO.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-CATpAEOz.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-D6jEU7nL.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-CZkpn0a7.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-BJlMVN4U.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-Br3CXEau.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CQxXbo2g.js +0 -1
- package/dist/dashboard/assets/OverviewPage-CQxXbo2g.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage--0RBNh99.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage--0RBNh99.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-paOCq8I0.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-paOCq8I0.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-1M-C3mbu.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-1M-C3mbu.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-CXiumA53.js +0 -7
- package/dist/dashboard/assets/ProxyPage-CXiumA53.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BGDIfIYP.js +0 -1
- package/dist/dashboard/assets/QuotaPage-BGDIfIYP.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BHW4Zt06.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-VOYC_lIa.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DpOTnGuH.js +0 -1
- package/dist/dashboard/assets/SortableList-DpOTnGuH.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-BNIDLiU6.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BAFaSDQV.js +0 -56
- package/dist/dashboard/assets/UsagePage-BAFaSDQV.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BETfaMYZ.js.gz +0 -0
- package/dist/dashboard/assets/app-BLCvGdzb.css +0 -2
- package/dist/dashboard/assets/app-BLCvGdzb.css.gz +0 -0
- package/dist/dashboard/assets/assert-7J6_LVD3.js +0 -1
- package/dist/dashboard/assets/assert-7J6_LVD3.js.gz +0 -0
- package/dist/dashboard/assets/badge-BTyGk_DL.js.gz +0 -0
- package/dist/dashboard/assets/banner-bujTWYM4.js.gz +0 -0
- package/dist/dashboard/assets/card-B0Bnx5CA.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-DE2ug812.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-R_rArH8S.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BWIP_EvW.js.gz +0 -0
- package/dist/dashboard/assets/drawer-BKcgVugF.js.gz +0 -0
- package/dist/dashboard/assets/entry-7dpgvpJ3.js +0 -4
- package/dist/dashboard/assets/entry-7dpgvpJ3.js.gz +0 -0
- package/dist/dashboard/assets/entry-kTiTFrvh.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-Booc5mNe.js.gz +0 -0
- package/dist/dashboard/assets/index-D70pChfn.js.gz +0 -0
- package/dist/dashboard/assets/inline-D1TCqM2D.js.gz +0 -0
- package/dist/dashboard/assets/input-B9oyU93y.js.gz +0 -0
- package/dist/dashboard/assets/layout-BArzXirQ.js.gz +0 -0
- package/dist/dashboard/assets/list-row-BVZzaoHF.js.gz +0 -0
- package/dist/dashboard/assets/live-EmuIayqp.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-CSPQ9xB0.js.gz +0 -0
- package/dist/dashboard/assets/routing-BExgxxBU.js.gz +0 -0
- package/dist/dashboard/assets/select-C9mMoEpJ.js +0 -41
- package/dist/dashboard/assets/select-C9mMoEpJ.js.gz +0 -0
- package/dist/dashboard/assets/settings-C4_Gn_wq.js +0 -1
- package/dist/dashboard/assets/settings-C4_Gn_wq.js.gz +0 -0
- package/dist/dashboard/assets/sliders-horizontal-ClG7dBeJ.js +0 -1
- package/dist/dashboard/assets/sliders-horizontal-ClG7dBeJ.js.gz +0 -0
- package/dist/dashboard/assets/stack-Ca5HxI5i.js.gz +0 -0
- package/dist/dashboard/assets/state-CzUPfLXo.js.gz +0 -0
- package/dist/dashboard/assets/switch-DOUIky_i.js.gz +0 -0
- package/dist/dashboard/assets/toast-C76WrMhc.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-D87FZwH0.js.gz +0 -0
- package/src/network/tls/bun-client-hello.ts +0 -112
- /package/dist/dashboard/assets/{app-Cjq7nrwu.js → app-C-Y4oZT0.js} +0 -0
- /package/dist/dashboard/assets/{app-Cjq7nrwu.js.gz → app-C-Y4oZT0.js.gz} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { GatewayError } from "../../protocol/gateway-error";
|
|
2
2
|
import type { CanonicalRequest, ServiceKind } from "../../protocol/canonical-model";
|
|
3
|
+
import { toolResultParts } from "../../protocol/canonical-model";
|
|
3
4
|
import type { ApiKeyAdmissionService } from "../../security/admission/service";
|
|
4
5
|
import type { RouteCandidate as RouteCandidate, InMemoryRouteSnapshotService, RoutePlan } from "../routing/route-model";
|
|
6
|
+
import type { RouteContinuationAffinity } from "../routing/route-model";
|
|
5
7
|
import { resolveAliasTarget, type RoutingEngine } from "../routing/router";
|
|
6
8
|
import { projectForRoute, routeCapabilitiesFor } from "../translation/capabilities";
|
|
7
9
|
import type { RequiredCapability } from "../translation/capabilities";
|
|
@@ -14,6 +16,7 @@ import { parseThinkingSuffix, withThinkingSuffixIntent } from "../translation/th
|
|
|
14
16
|
import { nativeServicePathFor } from "../contracts";
|
|
15
17
|
import { log } from "../../observability/logger";
|
|
16
18
|
import { BUDDY_PROVIDER_IDS } from "../../providers/provider-metadata";
|
|
19
|
+
import { cursorRunSessions } from "../../providers/integrations/cursor/cursor-session-manager";
|
|
17
20
|
import {
|
|
18
21
|
degradedRequestVariants,
|
|
19
22
|
degradeEncryptedReasoning,
|
|
@@ -32,6 +35,90 @@ function requestNeedsToolRepair(request: CanonicalRequest): boolean {
|
|
|
32
35
|
return false;
|
|
33
36
|
}
|
|
34
37
|
|
|
38
|
+
/** Prefix of a provider-continuation tool-call id the gateway itself minted. */
|
|
39
|
+
const CURSOR_CALL_PREFIX = "call_cursor_";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The provider-continuation tool results this request carries.
|
|
43
|
+
*
|
|
44
|
+
* Only ids the gateway minted (`call_cursor_<run-id>_<exec-id>`) are considered.
|
|
45
|
+
* Any other id belongs to a conversation the client owns; it is not a
|
|
46
|
+
* continuation and must not influence routing.
|
|
47
|
+
*/
|
|
48
|
+
export function continuationCallIds(request: CanonicalRequest): readonly string[] {
|
|
49
|
+
const ids: string[] = [];
|
|
50
|
+
for (const message of request.messages) {
|
|
51
|
+
if (message.role !== "tool" && message.role !== "user") continue;
|
|
52
|
+
for (const part of toolResultParts(message)) {
|
|
53
|
+
if (!part.call_id.startsWith(CURSOR_CALL_PREFIX)) continue;
|
|
54
|
+
if (!ids.includes(part.call_id)) ids.push(part.call_id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ids;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Resolves a request's pending tool results to the one account that owns them.
|
|
62
|
+
*
|
|
63
|
+
* Every pending id must resolve to the *same* live Run and the same account.
|
|
64
|
+
* Ids resolving to different Runs, or to no live Run at all, are refused rather
|
|
65
|
+
* than partially applied: one result cannot be delivered to another account's
|
|
66
|
+
* upstream turn, and a request that cannot be satisfied as a whole must not be
|
|
67
|
+
* dispatched at all.
|
|
68
|
+
*
|
|
69
|
+
* Returns `undefined` when the request carries no continuation ids — the
|
|
70
|
+
* ordinary routing path.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveContinuationAffinity(
|
|
73
|
+
request: CanonicalRequest,
|
|
74
|
+
authorization: ResolvedApiKey,
|
|
75
|
+
): RouteContinuationAffinity | undefined {
|
|
76
|
+
const ids = continuationCallIds(request);
|
|
77
|
+
if (ids.length === 0) return undefined;
|
|
78
|
+
const scope = {
|
|
79
|
+
tenantId: authorization.tenantId,
|
|
80
|
+
apiKeyId: authorization.id,
|
|
81
|
+
};
|
|
82
|
+
let affinity: RouteContinuationAffinity | undefined;
|
|
83
|
+
for (const callId of ids) {
|
|
84
|
+
// The registry resolves by tenant + API key + provider + account, so a call
|
|
85
|
+
// id replayed from another key or tenant resolves nothing.
|
|
86
|
+
const record = lookupPendingCall(callId, scope);
|
|
87
|
+
if (record === undefined) {
|
|
88
|
+
throw new GatewayError(
|
|
89
|
+
"invalid_request",
|
|
90
|
+
400,
|
|
91
|
+
"This tool result refers to a Cursor tool call that is no longer pending. Resend the complete conversation.",
|
|
92
|
+
{ callId },
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (affinity !== undefined && affinity.providerAccountId !== record.providerAccountId) {
|
|
96
|
+
throw new GatewayError(
|
|
97
|
+
"invalid_request",
|
|
98
|
+
400,
|
|
99
|
+
"These tool results belong to different Cursor accounts; resend them one account at a time.",
|
|
100
|
+
{ callIds: [...ids] },
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
affinity = {
|
|
104
|
+
providerId: record.providerId,
|
|
105
|
+
providerAccountId: record.providerAccountId,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return affinity;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Looks up one pending call across every provider that records continuations. */
|
|
112
|
+
function lookupPendingCall(
|
|
113
|
+
callId: string,
|
|
114
|
+
scope: { readonly tenantId: string; readonly apiKeyId: string },
|
|
115
|
+
): { readonly providerId: string; readonly providerAccountId: string } | undefined {
|
|
116
|
+
const record = cursorRunSessions.describePendingCall(callId, scope);
|
|
117
|
+
return record === undefined
|
|
118
|
+
? undefined
|
|
119
|
+
: { providerId: record.providerId, providerAccountId: record.providerAccountId };
|
|
120
|
+
}
|
|
121
|
+
|
|
35
122
|
export interface PreparedProxyRequest {
|
|
36
123
|
readonly canonicalRequest: CanonicalRequest;
|
|
37
124
|
readonly authorization: ResolvedApiKey;
|
|
@@ -42,6 +129,13 @@ export interface PreparedProxyRequest {
|
|
|
42
129
|
readonly degradedCapabilities?: readonly RequiredCapability[];
|
|
43
130
|
/** Snapshot-consistent plan used to reserve each individual attempt. */
|
|
44
131
|
readonly plan: RoutePlan;
|
|
132
|
+
/**
|
|
133
|
+
* The account this request must reach because a provider session is already
|
|
134
|
+
* live on it. Set only when the request carried a live tool result; the
|
|
135
|
+
* dispatch path uses it to borrow the held session instead of acquiring a
|
|
136
|
+
* second account and pool slot.
|
|
137
|
+
*/
|
|
138
|
+
readonly continuationAffinity?: RouteContinuationAffinity;
|
|
45
139
|
readonly estimatedInputTokens: number;
|
|
46
140
|
readonly estimatedOutputTokens: number;
|
|
47
141
|
readonly deadlineMs: number;
|
|
@@ -150,6 +244,13 @@ export class ProxyRequestPreparer {
|
|
|
150
244
|
// requires the `image` capability — it plans like the text request it has
|
|
151
245
|
// become, instead of being routed to a vision route for nothing.
|
|
152
246
|
const requestWithAttachments = dropCorruptAttachments(request).request;
|
|
247
|
+
// Continuation affinity is resolved before anything else: a request
|
|
248
|
+
// carrying a tool result for a live provider session must be planned against
|
|
249
|
+
// the one account that owns that session, before capability derivation or
|
|
250
|
+
// degradation could narrow the candidate set past it. This is also the
|
|
251
|
+
// point where a mismatched or expired call id becomes a 400 the caller can
|
|
252
|
+
// act on, instead of a dispatch that silently starts a new upstream turn.
|
|
253
|
+
const continuationAffinity = resolveContinuationAffinity(request, authorization);
|
|
153
254
|
// Capability-aware routing: derive requirements BEFORE planning so the
|
|
154
255
|
// router filters candidates against snapshot profiles. When nothing
|
|
155
256
|
// supports the full request, degrade (same greedy order) and re-plan
|
|
@@ -176,6 +277,7 @@ export class ProxyRequestPreparer {
|
|
|
176
277
|
variant.required,
|
|
177
278
|
allowCliMappings,
|
|
178
279
|
authorization.cliMappingOwnerId ?? authorization.id,
|
|
280
|
+
continuationAffinity,
|
|
179
281
|
);
|
|
180
282
|
} catch (error) {
|
|
181
283
|
if (error instanceof GatewayError && error.code === "capability_unsupported") continue;
|
|
@@ -303,6 +405,7 @@ export class ProxyRequestPreparer {
|
|
|
303
405
|
eligibleRouteCandidates: eligible,
|
|
304
406
|
degradedCapabilities: degraded,
|
|
305
407
|
plan,
|
|
408
|
+
...(continuationAffinity === undefined ? {} : { continuationAffinity }),
|
|
306
409
|
estimatedInputTokens,
|
|
307
410
|
estimatedOutputTokens,
|
|
308
411
|
deadlineMs: input.deadlineMs,
|
|
@@ -4,6 +4,7 @@ import type { ClientIdentity } from "../../security/abuse";
|
|
|
4
4
|
import type { ResolvedApiKey } from "../../security/api-key-auth";
|
|
5
5
|
import type { PreparedProxyRequest } from "./preparer";
|
|
6
6
|
import type { PayloadCaptureState, TelemetryPayloadCapture } from "../../observability/payload-capture";
|
|
7
|
+
import type { TelemetryPayloadDepth, TelemetryPayloadMode } from "../../console/settings/contracts";
|
|
7
8
|
import { createInFlightRegistry, type InFlightSnapshot } from "./inflight";
|
|
8
9
|
import { log } from "../../observability/logger";
|
|
9
10
|
import { fastPathname } from "../pathname";
|
|
@@ -103,6 +104,19 @@ export interface ProxyRequestState {
|
|
|
103
104
|
* hint at it, and they look identical in both cases.
|
|
104
105
|
*/
|
|
105
106
|
payloadCaptureState?: PayloadCaptureState;
|
|
107
|
+
/**
|
|
108
|
+
* This request's resolved payload-capture preference, memoized on the request.
|
|
109
|
+
*
|
|
110
|
+
* The preference is a tenant setting, so it cannot change between attempts of
|
|
111
|
+
* one request. It was resolved twice — once per attempt to decide whether to
|
|
112
|
+
* tee the provider body, and again on the terminal attempt to decide what to
|
|
113
|
+
* store — so a request with several attempts paid for it several times.
|
|
114
|
+
* Memoized here, the second read is free and the two cannot disagree about
|
|
115
|
+
* whether capture is on.
|
|
116
|
+
*/
|
|
117
|
+
payloadCapturePreference?:
|
|
118
|
+
| { readonly ok: true; readonly mode: TelemetryPayloadMode; readonly depth: TelemetryPayloadDepth }
|
|
119
|
+
| { readonly ok: false };
|
|
106
120
|
/**
|
|
107
121
|
* Set by the dispatch handler synchronously before returning a streaming
|
|
108
122
|
* response. `afterResponse` lifecycle hooks read it to skip finalization
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether an account's reported plan is known to be a free one.
|
|
3
|
+
*
|
|
4
|
+
* CodeBuddy is the reason this exists. It refuses a set of models on a free
|
|
5
|
+
* plan with `11158 "model [X] is not allowed for user type [personal_free_user]"`,
|
|
6
|
+
* and the plan is the only thing that predicts it — the model directory
|
|
7
|
+
* publishes nothing usable. Routing therefore has to keep those models away
|
|
8
|
+
* from accounts that are known to be free, and the only per-account signal is
|
|
9
|
+
* the plan string the quota read reported: `"Free Plan Subscription"`.
|
|
10
|
+
*
|
|
11
|
+
* The match is deliberately narrow and the default is deliberately permissive.
|
|
12
|
+
* Only a plan that names itself free excludes an account. Anything else — a
|
|
13
|
+
* paid plan name, a provider that reports no plan, a plan string that changed
|
|
14
|
+
* shape — leaves the account in rotation, because the alternative is worse:
|
|
15
|
+
* guessing "free" for an unrecognised plan would take a working account out of
|
|
16
|
+
* rotation on the strength of a string we failed to parse. A wrong free match
|
|
17
|
+
* costs one refused request that the cooldown machinery already handles; a
|
|
18
|
+
* wrong paid match silently blackholes a model.
|
|
19
|
+
*/
|
|
20
|
+
const FREE_PLAN_MARKERS: readonly string[] = ["free"];
|
|
21
|
+
|
|
22
|
+
export function isFreePlanAccount(plan: string | null | undefined): boolean {
|
|
23
|
+
if (plan === null || plan === undefined) return false;
|
|
24
|
+
const normalized = plan.trim().toLowerCase();
|
|
25
|
+
if (normalized.length === 0) return false;
|
|
26
|
+
return FREE_PLAN_MARKERS.some((marker) => normalized.includes(marker));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Whether this candidate can serve a request, given what is known about the
|
|
31
|
+
* model's plan gate and the account's plan.
|
|
32
|
+
*
|
|
33
|
+
* Returns `true` for every case except the one that is known to fail: a model
|
|
34
|
+
* the upstream refuses on a free plan, on an account the upstream reports as
|
|
35
|
+
* free. That pair is a certain refusal, so sending it wastes the request and
|
|
36
|
+
* advances the account's failure streak toward a six-hour park for something
|
|
37
|
+
* that is not the account's fault.
|
|
38
|
+
*/
|
|
39
|
+
export function planAllowsCandidate(candidate: {
|
|
40
|
+
readonly pro_only?: boolean;
|
|
41
|
+
readonly account_plan?: string | null;
|
|
42
|
+
}): boolean {
|
|
43
|
+
if (candidate.pro_only !== true) return true;
|
|
44
|
+
return !isFreePlanAccount(candidate.account_plan);
|
|
45
|
+
}
|