cartethyia 2.7.0 → 2.7.2
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 +107 -106
- package/README.md +25 -2
- package/dist/dashboard/assets/{BannedPage-P76QLGJA.js → BannedPage-XaUmiBrC.js} +1 -1
- package/dist/dashboard/assets/BannedPage-XaUmiBrC.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-DdBggJS9.js → CliToolDetailPage-CqD7QiLM.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-aN1iXhhP.js → CliToolsPage-0XUo4UMn.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-DE-F1nxZ.js → CombosPage-CXGS_Ct-.js} +1 -1
- package/dist/dashboard/assets/CombosPage-CXGS_Ct-.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-3CUxMy2X.js → CustomizationPage-DAG5J9EY.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BKtAPYVF.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-BKtAPYVF.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-BdmRLnq2.js +1 -0
- package/dist/dashboard/assets/LoginPage-BdmRLnq2.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-DKVslqG3.js → ModelPicker-BH8Tehdi.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CqMxibJB.js +1 -0
- package/dist/dashboard/assets/OverviewPage-CqMxibJB.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js +4 -0
- package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js +9 -0
- package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js.gz +0 -0
- package/dist/dashboard/assets/{QuotaPage-BjldQwIU.js → QuotaPage-7P2n--Fv.js} +1 -1
- package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-DUIoLRxk.js → SettingsPage-CxZ1fTkN.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-Co12Zzaw.js +1 -0
- package/dist/dashboard/assets/SetupPage-Co12Zzaw.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-fI7JkdIB.js → SortableList-Dqf4zpS-.js} +1 -1
- package/dist/dashboard/assets/SortableList-Dqf4zpS-.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-CHVZqskZ.js → StudioPage-Byj2lAEm.js} +3 -3
- package/dist/dashboard/assets/StudioPage-Byj2lAEm.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-CTkLAuRc.js +56 -0
- package/dist/dashboard/assets/UsagePage-CTkLAuRc.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-DFY_fZU4.js → api-keys-CUi6UXsR.js} +1 -1
- package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
- package/dist/dashboard/assets/app-KvsUJUMF.css +2 -0
- package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
- package/dist/dashboard/assets/{assert-CwdnZARt.js → assert-67xXH5rf.js} +1 -1
- package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
- package/dist/dashboard/assets/{badge-Dr-uf0Au.js → badge-DC2L43Mj.js} +1 -1
- package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
- package/dist/dashboard/assets/{banner-BddmMdoS.js → banner-BBVcb0J3.js} +1 -1
- package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
- package/dist/dashboard/assets/{card-CK0PXWlX.js → card-Cca1XC6G.js} +1 -1
- package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-CcB6mGh2.js → cli-tools-KvsWa1Jl.js} +1 -1
- package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DGb2P9Yx.js → clipboard-button-DUzEbynq.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-LkfuL50u.js → dialog-DFvWhwTa.js} +1 -1
- package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-ZbEZ_84c.js → drawer-CFM2sMX1.js} +1 -1
- package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
- package/dist/dashboard/assets/{entry-BJfsVMvA.js → entry-Bqy8RFvM.js} +1 -1
- package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CWBY5A0f.js → entry-ClCMCWWQ.js} +3 -3
- package/dist/dashboard/assets/entry-ClCMCWWQ.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CvC1-Zqx.js → entry-_xHo5x6r.js} +1 -1
- package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
- package/dist/dashboard/assets/formatters-CWWZ-uCZ.js +1 -0
- package/dist/dashboard/assets/formatters-CWWZ-uCZ.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-BxpznFLt.js → github-badge-C9e8Ts7e.js} +1 -1
- package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
- package/dist/dashboard/assets/{index-CDzP3ovJ.js → index-DFVFrnWW.js} +2 -2
- package/dist/dashboard/assets/index-DFVFrnWW.js.gz +0 -0
- package/dist/dashboard/assets/{inline-Ae13MQ5w.js → inline-BFUcvllj.js} +1 -1
- package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
- package/dist/dashboard/assets/{input-D23fo7cp.js → input-C_ILAvBb.js} +1 -1
- package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
- package/dist/dashboard/assets/{layout-CSsxjj5P.js → layout-CBIyT6Rt.js} +1 -1
- package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-dmbwZMDY.js → list-row-ebJ_-Nsb.js} +1 -1
- package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
- package/dist/dashboard/assets/{live-BG1oUsZZ.js → live-D0mm--ME.js} +1 -1
- package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-DSF-e4ho.js → mutation-sMD965oO.js} +1 -1
- package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-Bm_aECY7.js → numbers-BO9dKaFr.js} +1 -1
- package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
- package/dist/dashboard/assets/providers/inception.svg +5 -0
- package/dist/dashboard/assets/providers/inception.svg.gz +0 -0
- package/dist/dashboard/assets/{query-keys-CF56nYIV.js → query-keys-CfL_Zdoh.js} +1 -1
- package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
- package/dist/dashboard/assets/{routing-CeA71n7G.js → routing-BnIpi1IJ.js} +1 -1
- package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
- package/dist/dashboard/assets/{select-KIT0rC6G.js → select-DBNVLdUu.js} +1 -1
- package/dist/dashboard/assets/select-DBNVLdUu.js.gz +0 -0
- package/dist/dashboard/assets/{settings-B_2gkePf.js → settings-BAFhDgX8.js} +1 -1
- package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
- package/dist/dashboard/assets/{stack-D7WOSzcX.js → stack-EMrOMt4I.js} +1 -1
- package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
- package/dist/dashboard/assets/{state-BBxtKZOQ.js → state-CWoo7ty5.js} +1 -1
- package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DNS_D5Ea.js → switch-CCjT6IkF.js} +1 -1
- package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BgoxdoMk.js → useMutation-DjkLHUcE.js} +1 -1
- package/dist/dashboard/assets/useMutation-DjkLHUcE.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 +54 -53
- package/migrations/full-postgres/0024_add_pool_provider_cooldowns.sql +12 -0
- package/migrations/full-postgres/0025_add_pool_random_strategy.sql +3 -0
- package/migrations/lite-sqlite3/0024_add_pool_provider_cooldowns.sql +12 -0
- package/migrations/lite-sqlite3/0025_add_pool_random_strategy.sql +20 -0
- package/package.json +96 -96
- package/scripts/cli/console-menu.ts +5 -2
- package/scripts/cli/tray.ts +21 -6
- package/src/boot/app.ts +684 -714
- package/src/boot/dependencies.ts +65 -62
- package/src/config/cooldowns.ts +16 -0
- package/src/config/providers.ts +13 -1
- package/src/config/resources.ts +70 -70
- package/src/config/security.ts +37 -37
- package/src/config/spec.ts +371 -358
- package/src/console/cli-tools/contracts.ts +10 -4
- package/src/console/console-router.ts +233 -225
- package/src/console/domain-registration.ts +398 -381
- package/src/console/providers/catalog/catalog-projections.ts +2 -6
- package/src/console/providers/catalog/contracts.ts +19 -0
- package/src/console/providers/catalog/provider-operations.ts +38 -0
- package/src/console/providers/catalog/routes.ts +14 -0
- package/src/console/providers/catalog/store-helpers.ts +326 -0
- package/src/console/providers/catalog/store.ts +1292 -1563
- package/src/console/quota/account-quota-global.ts +2 -2
- package/src/console/quota/account-quota-shared.ts +1 -1
- package/src/console/quota/account-quota-tenant.ts +35 -12
- package/src/console/quota/quota-view.ts +2 -2
- package/src/console/routing/pools/contracts.ts +41 -1
- package/src/console/routing/pools/operations.ts +183 -4
- package/src/console/routing/pools/relay-deploy.ts +17 -4
- package/src/console/routing/pools/routes.ts +30 -0
- package/src/console/routing/pools/store.ts +98 -8
- package/src/main.ts +183 -167
- package/src/network/outbound-fetch.ts +124 -208
- package/src/network/pool/agent.ts +15 -0
- package/src/network/pool/pool-state.ts +7 -0
- package/src/network/pool/selector.ts +110 -2
- package/src/network/pool-cooldown-store.ts +252 -0
- package/src/network/pool-health-machine.ts +5 -3
- package/src/network/pool-health.ts +36 -9
- package/src/observability/event-query.ts +57 -0
- package/src/observability/metrics.ts +467 -467
- package/src/observability/runtime-metrics.ts +269 -269
- package/src/persistence/health-event-flush.ts +2 -0
- package/src/persistence/schema.ts +19 -0
- package/src/persistence/usage-flush.ts +8 -3
- package/src/protocol/canonical-model.ts +1 -1
- package/src/protocol/dsml.ts +377 -0
- package/src/protocol/gateway-error.ts +232 -232
- package/src/{providers/provider-reasoning.ts → protocol/reasoning.ts} +10 -9
- package/src/protocol/request/chat.ts +7 -7
- package/src/protocol/request/codex.ts +2 -2
- package/src/protocol/request/gemini.ts +1 -1
- package/src/protocol/request/messages.ts +6 -6
- package/src/protocol/request/responses.ts +7 -7
- package/src/protocol/response/dsml.ts +12 -133
- package/src/{transport → protocol}/translation/attachment-integrity.ts +2 -2
- package/src/{transport → protocol}/translation/cache-controls.ts +1 -1
- package/src/{transport → protocol}/translation/capabilities.ts +2 -2
- package/src/{transport → protocol}/translation/normalize.ts +1 -1
- package/src/{transport → protocol}/translation/quirks.ts +1 -1
- package/src/{transport → protocol}/translation/search.ts +1 -1
- package/src/{transport → protocol}/translation/thinking.ts +23 -1
- package/src/{transport → protocol}/translation/tool-id.ts +1 -1
- package/src/{transport → protocol}/translation/tool-repair.ts +2 -2
- package/src/protocol/upstream-parsing.ts +176 -0
- package/src/providers/adapters/compatible-adapter.ts +11 -2
- package/src/providers/authentication/oauth-refresh-service.ts +9 -5
- package/src/providers/default-registry.ts +22 -5
- package/src/providers/discovery/probe-phases.ts +16 -3
- package/src/providers/discovery/probing-service.ts +4 -1
- package/src/providers/integrations/anthropic.ts +1 -1
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -4
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +141 -8
- package/src/providers/integrations/buddy/buddy-checkin.ts +5 -1
- package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -82
- package/src/providers/integrations/buddy/buddy-identity.ts +25 -0
- package/src/providers/integrations/buddy/buddy-server-tools.ts +240 -0
- package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +36 -0
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +6 -31
- package/src/providers/integrations/buddy/codebuddy/provider.ts +2 -0
- package/src/providers/integrations/buddy/codebuddy/shared.ts +19 -4
- package/src/providers/integrations/buddy/turing-device-token.ts +262 -0
- package/src/providers/integrations/buddy/workbuddy/provider.ts +2 -0
- package/src/providers/integrations/buddy/workbuddy/shared.ts +56 -3
- package/src/providers/integrations/claude/claude.ts +1 -1
- package/src/providers/integrations/cloudflareai/cloudflareai.ts +1 -1
- package/src/providers/integrations/codex/codex-errors.ts +1 -1
- package/src/providers/integrations/codex/codex.ts +1 -1
- package/src/providers/integrations/factory/factory.ts +1 -1
- package/src/providers/integrations/github/github.ts +1 -1
- package/src/providers/integrations/grok/grok.ts +1 -1
- package/src/providers/integrations/inception/provider.ts +91 -0
- package/src/providers/integrations/inferhub.ts +1 -1
- package/src/providers/integrations/kiro/kiro-request.ts +1 -1
- package/src/providers/integrations/mistral.ts +193 -19
- package/src/providers/integrations/ollamacloud-models.ts +50 -0
- package/src/providers/integrations/opencode/fingerprint.ts +19 -2
- package/src/providers/integrations/opencode/prompt.ts +111 -0
- package/src/providers/integrations/opencode/provider.ts +101 -23
- package/src/providers/integrations/opencode/tool-definitions.ts +4 -4
- package/src/providers/integrations/qoder/qoder-checkin.ts +303 -0
- package/src/providers/integrations/qoder/qoder-oauth.ts +12 -1
- package/src/providers/integrations/qoder/qoder-realm.ts +20 -0
- package/src/providers/integrations/qoder/qoder-text-tools.ts +277 -0
- package/src/providers/integrations/qoder/qoder.ts +315 -400
- package/src/providers/integrations/shared/install-id.ts +2 -1
- package/src/providers/integrations/trae/trae-cache.ts +110 -0
- package/src/providers/integrations/trae/trae-oauth.ts +29 -4
- package/src/providers/integrations/trae/trae-protocol.ts +2 -1
- package/src/providers/integrations/trae/trae.ts +106 -23
- package/src/providers/operations/account-error-classification.ts +1684 -0
- package/src/providers/operations/account-health-service.ts +27 -1503
- package/src/providers/operations/account-reset-service.ts +2 -0
- package/src/providers/operations/provider-catalog-service.ts +11 -1
- package/src/providers/provider-contracts.ts +7 -4
- package/src/providers/provider-metadata.ts +25 -4
- package/src/providers/provider-probe.ts +2 -2
- package/src/{console → providers}/quota/cache.ts +1 -1
- package/src/{console → providers}/quota/refresh.ts +5 -5
- package/src/security/cli-client-fingerprint.ts +9 -2
- package/src/transport/dispatch/attempt-finalize.ts +114 -12
- package/src/transport/dispatch/attempt-loop.ts +3 -0
- package/src/transport/dispatch/empty-stream.ts +9 -2
- package/src/transport/dispatch/generation.ts +37 -55
- package/src/transport/dispatch/handler-deps.ts +32 -0
- package/src/transport/dispatch/leases.ts +9 -4
- package/src/transport/dispatch/proxy-request.ts +6 -30
- package/src/transport/dispatch/responses-compact.ts +22 -43
- package/src/transport/dispatch/streaming/finalize.ts +3 -0
- package/src/transport/dispatch/streaming/stream.ts +0 -8
- package/src/transport/dispatch/systemone.ts +22 -42
- package/src/transport/dispatch/token-count.ts +23 -39
- package/src/transport/dispatch/upstream.ts +1 -3
- package/src/transport/dispatch/websearch.ts +22 -41
- package/src/transport/failure-policy.ts +92 -178
- package/src/transport/guards/abuse-guard.ts +10 -0
- package/src/transport/guards/auth-guard.ts +109 -109
- package/src/transport/guards/error-lifecycle.ts +1 -1
- package/src/transport/guards/pipeline.ts +220 -220
- package/src/transport/guards/request-context.ts +245 -238
- package/src/transport/request/degradation.ts +20 -1
- package/src/transport/request/inflight.ts +4 -114
- package/src/transport/request/preparer.ts +6 -6
- package/src/transport/request/state.ts +66 -38
- package/src/transport/request/tenant-preferences.ts +1 -1
- package/src/transport/routing/route-catalog.ts +75 -43
- package/src/transport/routing/router.ts +30 -2
- package/src/transport/surface/messages/parse.ts +1 -1
- package/src/transport/surface/responses/encode.ts +2 -3
- package/src/transport/surface/responses/parse.ts +49 -7
- package/src/types/undici.d.ts +33 -0
- package/src/workers/buddy-growth-tasks.ts +346 -425
- package/src/workers/daily-checkin.ts +17 -6
- package/src/workers/quota-refresh-sweep.ts +2 -2
- package/src/workers/scheduler.ts +17 -1
- package/dist/dashboard/assets/BannedPage-P76QLGJA.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DdBggJS9.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-aN1iXhhP.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DE-F1nxZ.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-5SpmfLyw.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-5SpmfLyw.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-3CUxMy2X.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BkmJQKC0.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-BkmJQKC0.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-B_0FUKWc.js +0 -1
- package/dist/dashboard/assets/LoginPage-B_0FUKWc.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-DKVslqG3.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-D-H4MEiT.js +0 -1
- package/dist/dashboard/assets/OverviewPage-D-H4MEiT.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CEJw6Guo.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-CEJw6Guo.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CEplAR-i.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-CEplAR-i.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-CAN7hy0f.js +0 -7
- package/dist/dashboard/assets/ProxyPage-CAN7hy0f.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BjldQwIU.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-DUIoLRxk.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-_bCaTM0v.js +0 -1
- package/dist/dashboard/assets/SetupPage-_bCaTM0v.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-fI7JkdIB.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-CHVZqskZ.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DiFBymHj.js +0 -56
- package/dist/dashboard/assets/UsagePage-DiFBymHj.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-DFY_fZU4.js.gz +0 -0
- package/dist/dashboard/assets/app-BOJ1_xUB.css +0 -2
- package/dist/dashboard/assets/app-BOJ1_xUB.css.gz +0 -0
- package/dist/dashboard/assets/assert-CwdnZARt.js.gz +0 -0
- package/dist/dashboard/assets/badge-Dr-uf0Au.js.gz +0 -0
- package/dist/dashboard/assets/banner-BddmMdoS.js.gz +0 -0
- package/dist/dashboard/assets/card-CK0PXWlX.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-CcB6mGh2.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DGb2P9Yx.js.gz +0 -0
- package/dist/dashboard/assets/cog-CdWhsajs.js +0 -1
- package/dist/dashboard/assets/cog-CdWhsajs.js.gz +0 -0
- package/dist/dashboard/assets/dialog-LkfuL50u.js.gz +0 -0
- package/dist/dashboard/assets/drawer-ZbEZ_84c.js.gz +0 -0
- package/dist/dashboard/assets/entry-BJfsVMvA.js.gz +0 -0
- package/dist/dashboard/assets/entry-CWBY5A0f.js.gz +0 -0
- package/dist/dashboard/assets/entry-CvC1-Zqx.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-BxpznFLt.js.gz +0 -0
- package/dist/dashboard/assets/index-CDzP3ovJ.js.gz +0 -0
- package/dist/dashboard/assets/inline-Ae13MQ5w.js.gz +0 -0
- package/dist/dashboard/assets/input-D23fo7cp.js.gz +0 -0
- package/dist/dashboard/assets/layout-CSsxjj5P.js.gz +0 -0
- package/dist/dashboard/assets/list-row-dmbwZMDY.js.gz +0 -0
- package/dist/dashboard/assets/live-BG1oUsZZ.js.gz +0 -0
- package/dist/dashboard/assets/mutation-DSF-e4ho.js.gz +0 -0
- package/dist/dashboard/assets/numbers-Bm_aECY7.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-CF56nYIV.js.gz +0 -0
- package/dist/dashboard/assets/routing-CeA71n7G.js.gz +0 -0
- package/dist/dashboard/assets/select-KIT0rC6G.js.gz +0 -0
- package/dist/dashboard/assets/settings-B_2gkePf.js.gz +0 -0
- package/dist/dashboard/assets/stack-D7WOSzcX.js.gz +0 -0
- package/dist/dashboard/assets/state-BBxtKZOQ.js.gz +0 -0
- package/dist/dashboard/assets/switch-DNS_D5Ea.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BgoxdoMk.js.gz +0 -0
- /package/dist/dashboard/assets/{app-CaXZ9SCn.js → app-BaWd0puM.js} +0 -0
- /package/dist/dashboard/assets/{app-CaXZ9SCn.js.gz → app-BaWd0puM.js.gz} +0 -0
|
@@ -8,12 +8,18 @@ import type { ProviderDispatchContext, ProviderDispatchTarget, ProviderId } from
|
|
|
8
8
|
import { resolveInboundSessionId } from "../../../operations/session-resolution";
|
|
9
9
|
import { buddyConversationHeaders } from "../buddy-conversation-headers";
|
|
10
10
|
import { buddyCliHeaders, buddyCliTraceHeaders } from "../buddy-cli-headers";
|
|
11
|
-
import { buddyEnterprise, buddyUserId, resolveBuddyIdentity } from "../buddy-identity";
|
|
11
|
+
import { buddyEnterprise, buddyUserId, resolveBuddyDeviceBinding, resolveBuddyIdentity } from "../buddy-identity";
|
|
12
12
|
import {
|
|
13
13
|
buildWorkBuddyUserAgent,
|
|
14
14
|
getWorkBuddyClientVersion,
|
|
15
15
|
getWorkBuddyCliVersion,
|
|
16
16
|
} from "../../../operations/client-versions";
|
|
17
|
+
import {
|
|
18
|
+
getTuringDeviceTokenService,
|
|
19
|
+
resolveTuringSdkRoot,
|
|
20
|
+
type TuringSdkConfig,
|
|
21
|
+
WORKBUDDY_TURING_CONFIG,
|
|
22
|
+
} from "../turing-device-token";
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* WorkBuddy serves chat from a versioned path on a base URL that carries no
|
|
@@ -140,8 +146,17 @@ export async function workbuddyHeaders(
|
|
|
140
146
|
headers["x-machine-id"] = deriveAccountStableId(accountId, "machine");
|
|
141
147
|
headers["x-session-id"] = deriveAccountStableId(accountId, "session");
|
|
142
148
|
}
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
// Per-account device binding: distinct device identity per account (see
|
|
150
|
+
// resolveBuddyDeviceBinding). Sent as the desktop's X-Device-Id-List.
|
|
151
|
+
const binding = resolveBuddyDeviceBinding(context);
|
|
152
|
+
if (binding !== undefined) {
|
|
153
|
+
headers["x-device-id-list"] = JSON.stringify({ qimei36: binding });
|
|
154
|
+
}
|
|
155
|
+
Object.assign(headers, await buddyDeviceTokenHeaders({
|
|
156
|
+
realm: domain.endsWith(".cn") ? "cn" : "intl",
|
|
157
|
+
context,
|
|
158
|
+
cliIdentity,
|
|
159
|
+
}));
|
|
145
160
|
return headers;
|
|
146
161
|
}
|
|
147
162
|
|
|
@@ -165,6 +180,44 @@ export function readBuddyDeviceToken(context?: ProviderDispatchContext): string
|
|
|
165
180
|
return readDeviceTokenFile();
|
|
166
181
|
}
|
|
167
182
|
|
|
183
|
+
/**
|
|
184
|
+
* The reference `X-Device-Token` pair, per the official desktop app.
|
|
185
|
+
*
|
|
186
|
+
* The desktop client (WorkBuddyAI, channel 400111) always presents one of the
|
|
187
|
+
* two on chat traffic — a real token from the TuringShield SDK, or an
|
|
188
|
+
* `X-Device-Token-Error` when the SDK cannot produce one. It never omits both,
|
|
189
|
+
* and it sends the header on every realm (Intl and CN alike). The SDK is a
|
|
190
|
+
* proprietary native addon; when it is not configured we fall back to a
|
|
191
|
+
* captured token (auth_state / `CARTETHYIA_DEVICE_TOKEN_FILE`) and only then
|
|
192
|
+
* to the official failure state.
|
|
193
|
+
*
|
|
194
|
+
* - `CARTETHYIA_TURING_SDK_PATH` → real token via `TuringDeviceTokenService`.
|
|
195
|
+
* - Legacy token (auth_state/file) → used when the SDK is unavailable.
|
|
196
|
+
* - CLI identity never carries a device token (the CLI has no device).
|
|
197
|
+
*/
|
|
198
|
+
export async function buddyDeviceTokenHeaders(args: {
|
|
199
|
+
realm: "intl" | "cn";
|
|
200
|
+
context: ProviderDispatchContext | undefined;
|
|
201
|
+
cliIdentity: boolean | undefined;
|
|
202
|
+
turingConfig?: TuringSdkConfig;
|
|
203
|
+
}): Promise<Record<string, string>> {
|
|
204
|
+
const { context, cliIdentity, turingConfig } = args;
|
|
205
|
+
void args.realm; // the desktop client sends the token on both realms
|
|
206
|
+
if (resolveBuddyIdentity(context, cliIdentity) === "cli") return {};
|
|
207
|
+
// Native SDK first (real token), when configured.
|
|
208
|
+
if (resolveTuringSdkRoot() !== null) {
|
|
209
|
+
const sdkHeaders = await getTuringDeviceTokenService(turingConfig ?? WORKBUDDY_TURING_CONFIG).headersForRequest(false);
|
|
210
|
+
if (sdkHeaders["x-device-token"] !== undefined) return sdkHeaders;
|
|
211
|
+
// SDK configured but could not produce a token: mirror its failure state,
|
|
212
|
+
// like the desktop client does — do not fall back to a stale file token.
|
|
213
|
+
return sdkHeaders;
|
|
214
|
+
}
|
|
215
|
+
// No SDK on this deployment: a captured token is better than nothing.
|
|
216
|
+
const token = readBuddyDeviceToken(context);
|
|
217
|
+
if (token !== undefined) return { "x-device-token": token };
|
|
218
|
+
return { "x-device-token-error": "sdk_not_initialized" };
|
|
219
|
+
}
|
|
220
|
+
|
|
168
221
|
function readDeviceTokenFile(): string | undefined {
|
|
169
222
|
const now = Date.now();
|
|
170
223
|
if (deviceTokenFileCache !== undefined && now - deviceTokenFileCache.readAt < DEVICE_TOKEN_FILE_TTL_MS) {
|
|
@@ -49,7 +49,7 @@ import { getClaudeCliVersion, adoptClaudeCliVersion, getClaudeSdkVersion } from
|
|
|
49
49
|
import { adoptRequiredVersion } from "../../operations/client-version-resolver";
|
|
50
50
|
import { getOrCreateInstallId } from "../shared/install-id";
|
|
51
51
|
import { canonicalToClaudeMessagesPayload } from "../../../protocol/request/messages";
|
|
52
|
-
import { applyParamQuirks } from "../../../
|
|
52
|
+
import { applyParamQuirks } from "../../../protocol/translation/quirks";
|
|
53
53
|
import { CLAUDE_BILLING_HEADER_PREFIX, endpointUrl } from "../../../protocol/codecs";
|
|
54
54
|
import { sendClaudeMessagesRequest } from "../../../protocol/upstream/send-claude-messages";
|
|
55
55
|
import {
|
|
@@ -25,7 +25,7 @@ import type { CanonicalEvent, CanonicalRequest } from "../../../protocol/canonic
|
|
|
25
25
|
import { GatewayError } from "../../../protocol/gateway-error";
|
|
26
26
|
import { buildClaudeMessagesRequest, filterClaudeCustomHeaders } from "../shared/claude-messages";
|
|
27
27
|
import { sendClaudeMessagesRequest } from "../../../protocol/upstream/send-claude-messages";
|
|
28
|
-
import { applyParamQuirks } from "../../../
|
|
28
|
+
import { applyParamQuirks } from "../../../protocol/translation/quirks";
|
|
29
29
|
import { decodeCloudflareAiGatewayCredential } from "../../../security/credential-codec";
|
|
30
30
|
|
|
31
31
|
export const CLOUDFLAREAI_PROVIDER_ID = "cloudflareai" as const;
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
import { GatewayError } from "../../../protocol/gateway-error";
|
|
8
8
|
import {
|
|
9
9
|
classifyUpstreamError,
|
|
10
|
-
parseRetryAfter,
|
|
11
10
|
extractUpstreamMessage,
|
|
12
11
|
upstreamErrorIdentifier,
|
|
13
12
|
upstreamRequestId,
|
|
14
13
|
} from "../../../transport/failure-policy";
|
|
14
|
+
import { parseRetryAfter } from "../../../protocol/upstream-parsing";
|
|
15
15
|
import { tryParseJsonObject } from "../../../protocol/codecs";
|
|
16
16
|
|
|
17
17
|
function toNumberOrUndefined(value: string | null): number | undefined {
|
|
@@ -33,9 +33,9 @@ import { isRecord, joinUrl } from "../../../protocol/codecs";
|
|
|
33
33
|
import { postUpstreamJson } from "../../../protocol/upstream/post-json";
|
|
34
34
|
import {
|
|
35
35
|
MIN_RETRY_BUDGET_MS,
|
|
36
|
-
parseUpstreamBackoff,
|
|
37
36
|
sleep as defaultSleep,
|
|
38
37
|
} from "../../../transport/failure-policy";
|
|
38
|
+
import { parseUpstreamBackoff } from "../../../protocol/upstream-parsing";
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Sleep used by the 429 capacity-wait loop, overridable in tests.
|
|
@@ -49,7 +49,7 @@ import { createUpstreamDeadlineLifecycle, abortGatewayError } from "../../operat
|
|
|
49
49
|
import { mapUpstreamHttpError } from "../../../transport/failure-policy";
|
|
50
50
|
import { buildClaudeMessagesRequest, filterClaudeCustomHeaders } from "../shared/claude-messages";
|
|
51
51
|
import { sendClaudeMessagesRequest } from "../../../protocol/upstream/send-claude-messages";
|
|
52
|
-
import { applyParamQuirks } from "../../../
|
|
52
|
+
import { applyParamQuirks } from "../../../protocol/translation/quirks";
|
|
53
53
|
import { createApiKeyAdapter } from "../../configured-provider";
|
|
54
54
|
import type { ApiKeyProviderSpec } from "../../configured-provider";
|
|
55
55
|
import { decodeFactoryDroidCredential } from "../../../security/credential-codec";
|
|
@@ -25,7 +25,7 @@ import { postUpstreamJson } from "../../../protocol/upstream/post-json";
|
|
|
25
25
|
import { providerBaseUrl } from "../../provider-metadata";
|
|
26
26
|
import { getOrCreateInstallId } from "../shared/install-id";
|
|
27
27
|
import { resolveRedisClient } from "../../../persistence/redis";
|
|
28
|
-
import { applyParamQuirks } from "../../../
|
|
28
|
+
import { applyParamQuirks } from "../../../protocol/translation/quirks";
|
|
29
29
|
import { resolveInboundSessionId } from "../../operations/session-resolution";
|
|
30
30
|
import {
|
|
31
31
|
GITHUB_REQUEST_HEADERS,
|
|
@@ -20,7 +20,7 @@ import { providerBaseUrl } from "../../provider-metadata";
|
|
|
20
20
|
import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../../provider-sanitize";
|
|
21
21
|
import { isRecord } from "../../../protocol/codecs";
|
|
22
22
|
import { modelsDevCatalog } from "../../discovery/models-dev-catalog";
|
|
23
|
-
import type { ReasoningEffortLevel } from "../../../
|
|
23
|
+
import type { ReasoningEffortLevel } from "../../../protocol/translation/thinking";
|
|
24
24
|
import type { FetchLike } from "../../quota/quota-contracts";
|
|
25
25
|
import { resolveInboundSessionId, resolvePromptCacheKey } from "../../operations/session-resolution";
|
|
26
26
|
import {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ApiKeyProviderSpec } from "../../configured-provider";
|
|
2
|
+
import { fetchOpenAICompatibleModels } from "../../discovery/openai-model-discovery";
|
|
3
|
+
import { defineModel, type ModelDefinition } from "../../provider-model-definition";
|
|
4
|
+
|
|
5
|
+
const INCEPTION_PROVIDER_ID = "inception" as const;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Inception Labs (Mercury) — bearer-authenticated OpenAI-compatible chat.
|
|
9
|
+
*
|
|
10
|
+
* The upstream is a plain `POST /v1/chat/completions` service (SSE streaming,
|
|
11
|
+
* tool calling, structured outputs, `reasoning_effort`). Base URL comes from
|
|
12
|
+
* `BUNDLED_PROVIDER_METADATA`; the chat path is declared below the `/v1`
|
|
13
|
+
* root, exactly like every other version-rooted OpenAI-compatible provider.
|
|
14
|
+
*/
|
|
15
|
+
export const INCEPTION_SPEC: ApiKeyProviderSpec = {
|
|
16
|
+
provider_id: INCEPTION_PROVIDER_ID,
|
|
17
|
+
endpoint_paths_by_wire_family: {},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Offline floor: the Mercury chat model this provider serves, pinned to the
|
|
22
|
+
* free-tier allowance (100M free tokens at signup).
|
|
23
|
+
*
|
|
24
|
+
* The roster intentionally carries only `mercury-3` — the operator's choice.
|
|
25
|
+
* Mercury Voice is enterprise-gated, Mercury Decide is a native decisions
|
|
26
|
+
* endpoint, and Mercury Edit 2 is FIM/edit; none of them is a chat model, and
|
|
27
|
+
* a chat wire would not serve them.
|
|
28
|
+
*
|
|
29
|
+
* `freeTier` is the catalog flag the console groups on; `free: true` zeroes
|
|
30
|
+
* the cost the way every other free-allowance provider models its rows — the
|
|
31
|
+
* allowance does not bill, so the row must not show a price. Limits are
|
|
32
|
+
* mercury-3's own chat-completions numbers: 1M context, 131072 max output,
|
|
33
|
+
* reasoning (instant/low/medium/high), tool calling.
|
|
34
|
+
*/
|
|
35
|
+
export const INCEPTION_MODELS: readonly ModelDefinition[] = [
|
|
36
|
+
defineModel({
|
|
37
|
+
id: "mercury-3",
|
|
38
|
+
wireFamily: "chat",
|
|
39
|
+
endpoint: "/chat/completions",
|
|
40
|
+
ctx: 1_000_000,
|
|
41
|
+
out: 131_072,
|
|
42
|
+
reasoning: true,
|
|
43
|
+
toolCall: true,
|
|
44
|
+
free: true,
|
|
45
|
+
freeTier: true,
|
|
46
|
+
}),
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Live `/v1/models` listing, pinned to the free tier.
|
|
51
|
+
*
|
|
52
|
+
* The listing requires the API key (matches the chat endpoint's bearer), so
|
|
53
|
+
* the credential is forwarded when present; an unauthenticated fetch fails
|
|
54
|
+
* cleanly and the static roster stays authoritative.
|
|
55
|
+
*
|
|
56
|
+
* Every fetched row is stamped `freeTier` and zero-priced, the same rule the
|
|
57
|
+
* static roster declares: this provider is pinned to its free allowance, so a
|
|
58
|
+
* model upstream adds must not land in the billed tail.
|
|
59
|
+
*
|
|
60
|
+
* A fetched id that the static roster already knows keeps the roster row
|
|
61
|
+
* whole, not the listing's fields: upstream publishes `max_output_length` and
|
|
62
|
+
* no `reasoning`/`tool_call` keys, so the shared OpenAI-compatible reader
|
|
63
|
+
* would otherwise overwrite mercury-3's advertised 131072 output and reasoning
|
|
64
|
+
* flag with its 64k/not-reasoning defaults. The roster is the canonical
|
|
65
|
+
* metadata for the models we know; the listing only adds genuinely new ids.
|
|
66
|
+
*/
|
|
67
|
+
export async function discoverInceptionFreeModels(options: {
|
|
68
|
+
readonly baseUrl: string;
|
|
69
|
+
readonly credential?: string;
|
|
70
|
+
readonly fetcher?: typeof fetch;
|
|
71
|
+
}): Promise<readonly ModelDefinition[] | null> {
|
|
72
|
+
const listed = await fetchOpenAICompatibleModels({
|
|
73
|
+
baseUrl: options.baseUrl,
|
|
74
|
+
providerId: "inception",
|
|
75
|
+
...(typeof options.credential === "string" && options.credential.trim().length > 0
|
|
76
|
+
? { headers: { authorization: `Bearer ${options.credential}` } }
|
|
77
|
+
: {}),
|
|
78
|
+
...(options.fetcher === undefined ? {} : { fetcher: options.fetcher }),
|
|
79
|
+
});
|
|
80
|
+
if (listed === null) return null;
|
|
81
|
+
const known = new Map(INCEPTION_MODELS.map((model) => [model.modelId, model]));
|
|
82
|
+
return listed.map((model) => {
|
|
83
|
+
const roster = known.get(model.modelId);
|
|
84
|
+
if (roster !== undefined) return roster;
|
|
85
|
+
return {
|
|
86
|
+
...model,
|
|
87
|
+
freeTier: true,
|
|
88
|
+
cost: { input: 0, output: 0, pricing_model: "pay-per-use" },
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -11,7 +11,7 @@ import type { FetchLike, ProviderQuotaResult } from "../quota/quota-contracts";
|
|
|
11
11
|
import { probeApiKeyConnectivity } from "../quota/quota-support";
|
|
12
12
|
import type { CanonicalEvent, CanonicalRequest, ContentPart } from "../../protocol/canonical-model";
|
|
13
13
|
import { GatewayError } from "../../protocol/gateway-error";
|
|
14
|
-
import { applyParamQuirks } from "../../
|
|
14
|
+
import { applyParamQuirks } from "../../protocol/translation/quirks";
|
|
15
15
|
import { buildClaudeMessagesRequest, filterClaudeCustomHeaders } from "./shared/claude-messages";
|
|
16
16
|
import { resolveInboundSessionId } from "../operations/session-resolution";
|
|
17
17
|
import { isRecord } from "../../protocol/codecs";
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
import { createHash, randomUUID } from "node:crypto";
|
|
22
22
|
import type { CanonicalMessage, CanonicalRequest, ContentPart, ToolDefinition } from "../../../protocol/canonical-model";
|
|
23
23
|
import { resolveImageSource, splitDataUrl } from "../../../protocol/codecs";
|
|
24
|
-
import type { ReasoningEffortLevel } from "../../../
|
|
24
|
+
import type { ReasoningEffortLevel } from "../../../protocol/translation/thinking";
|
|
25
25
|
|
|
26
26
|
/** Longest tool name the upstream accepts, counted in code points. */
|
|
27
27
|
export const KIRO_TOOL_NAME_MAX_LENGTH = 64;
|
|
@@ -4,14 +4,11 @@ import { defineModel } from "../provider-model-definition";
|
|
|
4
4
|
const MISTRAL_PROVIDER_ID = "mistral" as const;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Mistral's
|
|
7
|
+
* Mistral's catalog for the generic OpenAI-compatible API-key provider.
|
|
8
8
|
*
|
|
9
|
-
* The provider is registered as a generic
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `latest` aliases Mistral keeps pointed at its current generalist models —
|
|
13
|
-
* `mistral-large-latest` (Large 4) and `mistral-medium-latest` (Medium 3.5),
|
|
14
|
-
* per the Mistral model overview.
|
|
9
|
+
* The provider is registered as a generic API-key provider, which carries no
|
|
10
|
+
* catalog of its own: without this list, every model it serves stays absent
|
|
11
|
+
* until a discovery run happens to fetch them.
|
|
15
12
|
*
|
|
16
13
|
* Limits and pricing come from the base catalog via `providerId`: `defineModel`
|
|
17
14
|
* resolves `mistral:<id>` and falls back to the majority row, so no number is
|
|
@@ -19,28 +16,110 @@ const MISTRAL_PROVIDER_ID = "mistral" as const;
|
|
|
19
16
|
* because the base catalog is keyed by bare id and a bare id maps to many
|
|
20
17
|
* providers' servings.
|
|
21
18
|
*
|
|
19
|
+
* Which rows are here: the chat models live on a real Mistral account (the
|
|
20
|
+
* code/codestral family, the ministral small/medium/large sizes, voxtral
|
|
21
|
+
* small, and the small/medium generalist tiers). A live probe against the
|
|
22
|
+
* Mistral API verified each of these responds on `/v1/chat/completions`.
|
|
23
|
+
*
|
|
22
24
|
* Deliberately not included:
|
|
23
25
|
*
|
|
24
|
-
* -
|
|
25
|
-
*
|
|
26
|
-
* -
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* -
|
|
30
|
-
*
|
|
31
|
-
* advertises models the provider is actively retiring.
|
|
32
|
-
* - The open-weights rows (`open-mistral-7b`, `open-mixtral-8x7b`), the
|
|
33
|
-
* embedding row (`mistral-embed`, not a chat model), and the devstral and
|
|
34
|
-
* codestral families — Mistral publishes those as separate product lines.
|
|
26
|
+
* - `mistral-large-latest` / dated large rows — tier-gated (Mistral answers
|
|
27
|
+
* 403 `tier_not_allowed` on many subscription tiers).
|
|
28
|
+
* - The embed/moderation/OCR/transcribe/TTS/realtime rows — they speak a
|
|
29
|
+
* different endpoint, not chat.
|
|
30
|
+
* - The Labs rows (`labs-leanstral-*`) — need an organization admin flag.
|
|
31
|
+
* - The open-weights rows (`open-mistral-7b`, `open-mixtral-8x7b`) and the
|
|
32
|
+
* devstral family — separate product lines.
|
|
35
33
|
*/
|
|
36
34
|
export const MISTRAL_MODELS: readonly ModelDefinition[] = [
|
|
35
|
+
// Code / coding family
|
|
36
|
+
defineModel({
|
|
37
|
+
id: "codestral-2508",
|
|
38
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
39
|
+
wireFamily: "chat",
|
|
40
|
+
vision: true,
|
|
41
|
+
toolCall: true,
|
|
42
|
+
}),
|
|
43
|
+
defineModel({
|
|
44
|
+
id: "codestral-latest",
|
|
45
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
46
|
+
wireFamily: "chat",
|
|
47
|
+
vision: true,
|
|
48
|
+
toolCall: true,
|
|
49
|
+
}),
|
|
50
|
+
defineModel({
|
|
51
|
+
id: "mistral-code-latest",
|
|
52
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
53
|
+
wireFamily: "chat",
|
|
54
|
+
vision: true,
|
|
55
|
+
toolCall: true,
|
|
56
|
+
}),
|
|
57
|
+
defineModel({
|
|
58
|
+
id: "mistral-code-fim-latest",
|
|
59
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
60
|
+
wireFamily: "chat",
|
|
61
|
+
vision: true,
|
|
62
|
+
toolCall: true,
|
|
63
|
+
}),
|
|
64
|
+
// Ministral sizes
|
|
65
|
+
defineModel({
|
|
66
|
+
id: "ministral-14b-2512",
|
|
67
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
68
|
+
wireFamily: "chat",
|
|
69
|
+
vision: true,
|
|
70
|
+
toolCall: true,
|
|
71
|
+
}),
|
|
72
|
+
defineModel({
|
|
73
|
+
id: "ministral-14b-latest",
|
|
74
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
75
|
+
wireFamily: "chat",
|
|
76
|
+
vision: true,
|
|
77
|
+
toolCall: true,
|
|
78
|
+
}),
|
|
37
79
|
defineModel({
|
|
38
|
-
id: "
|
|
80
|
+
id: "ministral-8b-2512",
|
|
39
81
|
providerId: MISTRAL_PROVIDER_ID,
|
|
40
82
|
wireFamily: "chat",
|
|
41
83
|
vision: true,
|
|
42
84
|
toolCall: true,
|
|
43
85
|
}),
|
|
86
|
+
defineModel({
|
|
87
|
+
id: "ministral-8b-latest",
|
|
88
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
89
|
+
wireFamily: "chat",
|
|
90
|
+
vision: true,
|
|
91
|
+
toolCall: true,
|
|
92
|
+
}),
|
|
93
|
+
defineModel({
|
|
94
|
+
id: "ministral-3b-2512",
|
|
95
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
96
|
+
wireFamily: "chat",
|
|
97
|
+
vision: true,
|
|
98
|
+
toolCall: true,
|
|
99
|
+
}),
|
|
100
|
+
defineModel({
|
|
101
|
+
id: "ministral-3b-latest",
|
|
102
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
103
|
+
wireFamily: "chat",
|
|
104
|
+
vision: true,
|
|
105
|
+
toolCall: true,
|
|
106
|
+
}),
|
|
107
|
+
// Voxtral small (chat-capable)
|
|
108
|
+
defineModel({
|
|
109
|
+
id: "voxtral-small-2507",
|
|
110
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
111
|
+
wireFamily: "chat",
|
|
112
|
+
vision: true,
|
|
113
|
+
toolCall: true,
|
|
114
|
+
}),
|
|
115
|
+
defineModel({
|
|
116
|
+
id: "voxtral-small-latest",
|
|
117
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
118
|
+
wireFamily: "chat",
|
|
119
|
+
vision: true,
|
|
120
|
+
toolCall: true,
|
|
121
|
+
}),
|
|
122
|
+
// Medium generalist tiers
|
|
44
123
|
defineModel({
|
|
45
124
|
id: "mistral-medium-latest",
|
|
46
125
|
providerId: MISTRAL_PROVIDER_ID,
|
|
@@ -49,4 +128,99 @@ export const MISTRAL_MODELS: readonly ModelDefinition[] = [
|
|
|
49
128
|
reasoning: true,
|
|
50
129
|
toolCall: true,
|
|
51
130
|
}),
|
|
131
|
+
defineModel({
|
|
132
|
+
id: "mistral-medium",
|
|
133
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
134
|
+
wireFamily: "chat",
|
|
135
|
+
vision: true,
|
|
136
|
+
reasoning: true,
|
|
137
|
+
toolCall: true,
|
|
138
|
+
}),
|
|
139
|
+
defineModel({
|
|
140
|
+
id: "mistral-medium-3-5",
|
|
141
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
142
|
+
wireFamily: "chat",
|
|
143
|
+
vision: true,
|
|
144
|
+
reasoning: true,
|
|
145
|
+
toolCall: true,
|
|
146
|
+
}),
|
|
147
|
+
defineModel({
|
|
148
|
+
id: "mistral-medium-3.5",
|
|
149
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
150
|
+
wireFamily: "chat",
|
|
151
|
+
vision: true,
|
|
152
|
+
reasoning: true,
|
|
153
|
+
toolCall: true,
|
|
154
|
+
}),
|
|
155
|
+
defineModel({
|
|
156
|
+
id: "mistral-medium-3",
|
|
157
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
158
|
+
wireFamily: "chat",
|
|
159
|
+
vision: true,
|
|
160
|
+
reasoning: true,
|
|
161
|
+
toolCall: true,
|
|
162
|
+
}),
|
|
163
|
+
defineModel({
|
|
164
|
+
id: "mistral-medium-2604",
|
|
165
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
166
|
+
wireFamily: "chat",
|
|
167
|
+
vision: true,
|
|
168
|
+
reasoning: true,
|
|
169
|
+
toolCall: true,
|
|
170
|
+
}),
|
|
171
|
+
// Vibe CLI family
|
|
172
|
+
defineModel({
|
|
173
|
+
id: "mistral-vibe-cli-latest",
|
|
174
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
175
|
+
wireFamily: "chat",
|
|
176
|
+
vision: true,
|
|
177
|
+
toolCall: true,
|
|
178
|
+
}),
|
|
179
|
+
defineModel({
|
|
180
|
+
id: "mistral-vibe-cli-with-tools",
|
|
181
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
182
|
+
wireFamily: "chat",
|
|
183
|
+
vision: true,
|
|
184
|
+
toolCall: true,
|
|
185
|
+
}),
|
|
186
|
+
defineModel({
|
|
187
|
+
id: "mistral-vibe-cli-fast",
|
|
188
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
189
|
+
wireFamily: "chat",
|
|
190
|
+
vision: true,
|
|
191
|
+
toolCall: true,
|
|
192
|
+
}),
|
|
193
|
+
// Magistral / small generalist tiers (chat-capable)
|
|
194
|
+
defineModel({
|
|
195
|
+
id: "magistral-medium-latest",
|
|
196
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
197
|
+
wireFamily: "chat",
|
|
198
|
+
vision: true,
|
|
199
|
+
reasoning: true,
|
|
200
|
+
toolCall: true,
|
|
201
|
+
}),
|
|
202
|
+
defineModel({
|
|
203
|
+
id: "mistral-small-2603",
|
|
204
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
205
|
+
wireFamily: "chat",
|
|
206
|
+
vision: true,
|
|
207
|
+
reasoning: true,
|
|
208
|
+
toolCall: true,
|
|
209
|
+
}),
|
|
210
|
+
defineModel({
|
|
211
|
+
id: "mistral-small-latest",
|
|
212
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
213
|
+
wireFamily: "chat",
|
|
214
|
+
vision: true,
|
|
215
|
+
reasoning: true,
|
|
216
|
+
toolCall: true,
|
|
217
|
+
}),
|
|
218
|
+
defineModel({
|
|
219
|
+
id: "magistral-small-latest",
|
|
220
|
+
providerId: MISTRAL_PROVIDER_ID,
|
|
221
|
+
wireFamily: "chat",
|
|
222
|
+
vision: true,
|
|
223
|
+
reasoning: true,
|
|
224
|
+
toolCall: true,
|
|
225
|
+
}),
|
|
52
226
|
];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama Cloud (`ollamacloud`) model catalog.
|
|
3
|
+
*
|
|
4
|
+
* The provider is discovery-backed: live `/v1/models` on `https://ollama.com/v1`
|
|
5
|
+
* is the primary source and publishes every model's real context window. This
|
|
6
|
+
* static floor keeps the models an operator most likely wants routable before
|
|
7
|
+
* any account sync — and pins the verified live limits so a cold process never
|
|
8
|
+
* falls back to the invented 200k/64k defaults.
|
|
9
|
+
*
|
|
10
|
+
* Limits below are taken from the live `/v1/models` roster (verified 2026-10):
|
|
11
|
+
* - `gemma4:31b` -> 262144 ctx, text+image, thinking none/medium
|
|
12
|
+
* - `gpt-oss:20b` / `gpt-oss:120b` -> 131072 ctx, text, reasoning low/med/high
|
|
13
|
+
* - `nemotron-3-nano:30b` / `nemotron-3-super` / `nemotron-3-ultra`
|
|
14
|
+
* -> 262144 ctx, text, thinking none/medium
|
|
15
|
+
*
|
|
16
|
+
* All six serve the chat wire (none is a Responses-native id), and all report
|
|
17
|
+
* `supported_in_api: true` on the live roster.
|
|
18
|
+
*/
|
|
19
|
+
import { defineModel } from "../provider-model-definition";
|
|
20
|
+
import type { ModelDefinition } from "../provider-model-definition";
|
|
21
|
+
|
|
22
|
+
export const OLLAMACLOUD_PROVIDER_ID = "ollamacloud" as const;
|
|
23
|
+
|
|
24
|
+
/** Chat path below the `/v1`-rooted base. */
|
|
25
|
+
const CHAT_ENDPOINT = "/chat/completions";
|
|
26
|
+
|
|
27
|
+
type CatalogRow = readonly [id: string, ctx: number, vision: boolean, reasoning: boolean];
|
|
28
|
+
|
|
29
|
+
function ollamaCloudModel([id, ctx, vision, reasoning]: CatalogRow): ModelDefinition {
|
|
30
|
+
return defineModel({
|
|
31
|
+
id,
|
|
32
|
+
providerId: OLLAMACLOUD_PROVIDER_ID,
|
|
33
|
+
wireFamily: "chat",
|
|
34
|
+
endpoint: CHAT_ENDPOINT,
|
|
35
|
+
ctx,
|
|
36
|
+
vision,
|
|
37
|
+
reasoning,
|
|
38
|
+
toolCall: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Static Ollama Cloud floor; live discovery adds to it per account. */
|
|
43
|
+
export const OLLAMACLOUD_MODELS: readonly ModelDefinition[] = [
|
|
44
|
+
["gemma4:31b", 262_144, true, true] as const,
|
|
45
|
+
["gpt-oss:20b", 131_072, false, true] as const,
|
|
46
|
+
["gpt-oss:120b", 131_072, false, true] as const,
|
|
47
|
+
["nemotron-3-nano:30b", 262_144, false, true] as const,
|
|
48
|
+
["nemotron-3-super", 262_144, false, true] as const,
|
|
49
|
+
["nemotron-3-ultra", 262_144, false, true] as const,
|
|
50
|
+
].map(ollamaCloudModel);
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { getOpenCodeVersion } from "../../operations/client-versions";
|
|
2
2
|
import { createHash, randomBytes } from "node:crypto";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The OpenCode fallback client identity, used only while version discovery has
|
|
6
|
+
* not resolved yet. The live feed (`opencode/latest/<version>/cli`) wins once
|
|
7
|
+
* it is available; upstream accepts a range of releases, so the fallback does
|
|
8
|
+
* not need chasing.
|
|
9
|
+
*/
|
|
10
|
+
export const OPENCODE_CLIENT_VERSION = "2.1.1";
|
|
11
|
+
|
|
4
12
|
let lastTimestamp = 0;
|
|
5
13
|
let sequenceCounter = 0;
|
|
6
14
|
const SESSION_ID_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
@@ -118,11 +126,19 @@ function createTraceHeaders(): Record<string, string> {
|
|
|
118
126
|
};
|
|
119
127
|
}
|
|
120
128
|
|
|
121
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Build the observed OpenCode CLI identity headers for an upstream dispatch.
|
|
131
|
+
*
|
|
132
|
+
* The v2 lane splits root and child session ids exactly like the reference
|
|
133
|
+
* gateway: `x-opencode-session` / `x-session-affinity` / `x-session-id` carry
|
|
134
|
+
* the root session, while `x-opencode-session-id` carries the child (the
|
|
135
|
+
* client's own session id when it sent one, else the root).
|
|
136
|
+
*/
|
|
122
137
|
export function buildOpenCodeHeaders(
|
|
123
138
|
version = getOpenCodeVersion(),
|
|
124
139
|
affinity?: string,
|
|
125
140
|
projectId?: string,
|
|
141
|
+
childSessionId?: string,
|
|
126
142
|
): Record<string, string> {
|
|
127
143
|
let sessionId: string;
|
|
128
144
|
if (isOpenCodeSessionId(affinity)) {
|
|
@@ -132,6 +148,7 @@ export function buildOpenCodeHeaders(
|
|
|
132
148
|
} else {
|
|
133
149
|
sessionId = generateOpenCodeSessionId();
|
|
134
150
|
}
|
|
151
|
+
const childId = isOpenCodeSessionId(childSessionId) ? childSessionId : sessionId;
|
|
135
152
|
return {
|
|
136
153
|
// The gate accepts both "cli" and "desktop" (measured 2026-10-17), so this
|
|
137
154
|
// is not a refusal either way. It is "cli" because that is what the client
|
|
@@ -140,7 +157,7 @@ export function buildOpenCodeHeaders(
|
|
|
140
157
|
// client identity this adapter does not have, for no measured benefit.
|
|
141
158
|
"x-opencode-client": "cli",
|
|
142
159
|
"x-opencode-session": sessionId,
|
|
143
|
-
"x-opencode-session-id":
|
|
160
|
+
"x-opencode-session-id": childId,
|
|
144
161
|
"x-session-affinity": sessionId,
|
|
145
162
|
"x-session-id": sessionId,
|
|
146
163
|
// No `x-opencode-request`: the current client no longer sends it, and
|