cartethyia 2.7.2 → 2.7.4
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/dist/dashboard/assets/{BannedPage-XaUmiBrC.js → BannedPage-ChG5svFb.js} +1 -1
- package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +1 -0
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-CXGS_Ct-.js → CombosPage-DCgm5g6g.js} +1 -1
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +1 -0
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-BKtAPYVF.js → HealthEventsModal-DzSWzE_j.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-BdmRLnq2.js → LoginPage-U6AKaJcF.js} +1 -1
- package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BH8Tehdi.js → ModelPicker-BMS2t8BA.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +1 -0
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +5 -0
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js +9 -0
- package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js +1 -0
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +1 -0
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-Dqf4zpS-.js → SortableList-ClzpwyET.js} +1 -1
- package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-Byj2lAEm.js → StudioPage-Cq5tW7hW.js} +3 -3
- package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +56 -0
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-C38iXoO4.js +1 -0
- package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
- package/dist/dashboard/assets/app-a159k0ub.css +2 -0
- package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
- package/dist/dashboard/assets/arrow-up-59ms1iiT.js +1 -0
- package/dist/dashboard/assets/arrow-up-59ms1iiT.js.gz +0 -0
- package/dist/dashboard/assets/assert-DbRA8EG2.js +15 -0
- package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
- package/dist/dashboard/assets/{badge-DC2L43Mj.js → badge-D9CS6dZk.js} +1 -1
- package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
- package/dist/dashboard/assets/{banner-BBVcb0J3.js → banner-DympBNq4.js} +1 -1
- package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
- package/dist/dashboard/assets/{card-Cca1XC6G.js → card-ibRWU_uT.js} +1 -1
- package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js +1 -0
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DUzEbynq.js → clipboard-button-DJm-9pz7.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-DFvWhwTa.js → dialog-8fiE6tec.js} +1 -1
- package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js +1 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
- package/dist/dashboard/assets/{entry-Bqy8RFvM.js → entry-BSAsYsmV.js} +1 -1
- package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
- package/dist/dashboard/assets/entry-CiIQULZD.js +4 -0
- package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
- package/dist/dashboard/assets/entry-Daz0lJ-W.js +1 -0
- package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
- package/dist/dashboard/assets/{concurrency-BDF0ok7y.js → fingerprint-pattern-BWuHtbW4.js} +1 -1
- package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-CWWZ-uCZ.js → formatters-D-MTJxMr.js} +1 -1
- package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-C9e8Ts7e.js → github-badge-CPK47xQx.js} +1 -1
- package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
- package/dist/dashboard/assets/{index-DFVFrnWW.js → index-DBNPOfhV.js} +2 -2
- package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BFUcvllj.js → inline-BT0zntEr.js} +1 -1
- package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
- package/dist/dashboard/assets/{input-C_ILAvBb.js → input-Da2ZViWg.js} +1 -1
- package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
- package/dist/dashboard/assets/{layout-CBIyT6Rt.js → layout-BXNeLw6M.js} +1 -1
- package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-ebJ_-Nsb.js → list-row-BycOrrIV.js} +1 -1
- package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
- package/dist/dashboard/assets/live-DCQNZpF7.js +1 -0
- package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +1 -0
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-sMD965oO.js → mutation-Rr0TIvcj.js} +1 -1
- package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
- package/dist/dashboard/assets/network-9Yj2ZyLo.js +1 -0
- package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-BO9dKaFr.js → numbers-CEagj6ZZ.js} +2 -2
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-CfL_Zdoh.js → query-keys-BloKtaXJ.js} +1 -1
- package/dist/dashboard/assets/query-keys-BloKtaXJ.js.gz +0 -0
- package/dist/dashboard/assets/quota-Caw7wqci.js +1 -0
- package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
- package/dist/dashboard/assets/routing-CO9zCUus.js +1 -0
- package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
- package/dist/dashboard/assets/{select-DBNVLdUu.js → select-BIYIBkMU.js} +2 -2
- package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
- package/dist/dashboard/assets/settings-2-Ds9DQp0t.js +1 -0
- package/dist/dashboard/assets/settings-2-Ds9DQp0t.js.gz +0 -0
- package/dist/dashboard/assets/settings-jS3-PNSA.js +1 -0
- package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
- package/dist/dashboard/assets/{stack-EMrOMt4I.js → stack-DfgnFDWY.js} +1 -1
- package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
- package/dist/dashboard/assets/{state-CWoo7ty5.js → state-CkfdYWel.js} +1 -1
- package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
- package/dist/dashboard/assets/{switch-CCjT6IkF.js → switch-SYm237HG.js} +1 -1
- package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-DjkLHUcE.js → useMutation-BQqCRNIi.js} +1 -1
- package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
- package/dist/dashboard/index.html +3 -2
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +118 -115
- package/migrations/full-postgres/0026_add_qoder_native_identity.sql +20 -0
- package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +21 -0
- package/migrations/full-postgres/0028_add_family_template_key_telemetry.sql +40 -0
- package/migrations/full-postgres/0029_null_share_child_policy_columns.sql +38 -0
- package/migrations/full-postgres/0030_add_api_key_max_children.sql +10 -0
- package/migrations/full-postgres/0031_tenant_system_prompts.sql +16 -0
- package/migrations/full-postgres/0032_add_provider_pool_accounts.sql +53 -0
- package/migrations/full-postgres/0033_add_api_key_ban.sql +9 -0
- package/migrations/full-postgres/0034_add_api_key_ban_until.sql +7 -0
- package/migrations/full-postgres/0035_align_pool_account_status_enum.sql +21 -0
- package/migrations/lite-sqlite3/0026_add_qoder_native_identity.sql +15 -0
- package/migrations/lite-sqlite3/0027_qoder_identity_genuine_seed.sql +21 -0
- package/migrations/lite-sqlite3/0028_add_family_template_key_telemetry.sql +40 -0
- package/migrations/lite-sqlite3/0029_null_share_child_policy_columns.sql +38 -0
- package/migrations/lite-sqlite3/0030_add_api_key_max_children.sql +10 -0
- package/migrations/lite-sqlite3/0031_tenant_system_prompts.sql +10 -0
- package/migrations/lite-sqlite3/0032_add_provider_pool_accounts.sql +44 -0
- package/migrations/lite-sqlite3/0033_add_api_key_ban.sql +8 -0
- package/migrations/lite-sqlite3/0034_add_api_key_ban_until.sql +5 -0
- package/migrations/lite-sqlite3/0035_align_pool_account_status_enum.sql +6 -0
- package/package.json +2 -1
- package/src/boot/app.ts +9 -8
- package/src/config/network.ts +7 -3
- package/src/console/api-keys/bucket-spend.ts +7 -7
- package/src/console/api-keys/contracts.ts +475 -410
- package/src/console/api-keys/routes.ts +211 -23
- package/src/console/audit/routes.ts +3 -3
- package/src/console/auth/account-reset.ts +4 -4
- package/src/console/auth/session.ts +3 -3
- package/src/console/backup/contracts.ts +2 -0
- package/src/console/backup/export-endpoint.ts +14 -17
- package/src/console/backup/routes.ts +43 -11
- package/src/console/backup/service.ts +11 -6
- package/src/console/backup/store.ts +384 -88
- package/src/console/cli-tools/routes.ts +3 -3
- package/src/console/console-router-guards.ts +2 -2
- package/src/console/console-router.ts +4 -4
- package/src/console/dashboard-assets.ts +16 -1
- package/src/console/data-management/routes.ts +3 -3
- package/src/console/domain-registration.ts +4 -2
- package/src/console/observability/contracts.ts +4 -0
- package/src/console/observability/live.ts +3 -3
- package/src/console/observability/logs.ts +3 -3
- package/src/console/observability/performance.ts +3 -3
- package/src/console/observability/routes.ts +3 -3
- package/src/console/observability/store.ts +16 -16
- package/src/console/providers/catalog/contracts.ts +43 -22
- package/src/console/providers/catalog/provider-operations.ts +17 -2
- package/src/console/providers/catalog/routes.ts +3 -3
- package/src/console/providers/catalog/store-helpers.ts +349 -326
- package/src/console/providers/catalog/store.ts +1523 -1292
- package/src/console/providers/detail/routes.ts +3 -3
- package/src/console/providers/oauth/routes.ts +3 -3
- package/src/console/quota/account-quota-tenant.ts +34 -2
- package/src/console/quota/account-quota.ts +4 -1
- package/src/console/quota/account-test-egress.ts +4 -4
- package/src/console/quota/native-identity.ts +189 -0
- package/src/console/remote-support/contracts.ts +12 -6
- package/src/console/remote-support/service.ts +2 -2
- package/src/console/routing/model/routes.ts +3 -3
- package/src/console/routing/pools/contracts.ts +11 -8
- package/src/console/routing/pools/operations.ts +14 -7
- package/src/console/routing/pools/probe-verdict.ts +8 -3
- package/src/console/routing/pools/relay-deploy.ts +9 -9
- package/src/console/routing/pools/routes.ts +3 -3
- package/src/console/routing/pools/store.ts +21 -1
- package/src/console/settings/routes.ts +3 -3
- package/src/console/share/share-router.ts +51 -18
- package/src/console/share/share-stats.ts +158 -49
- package/src/console/share/share-usage.ts +24 -7
- package/src/console/shared/read-through-cache.ts +38 -2
- package/src/console/system-prompt/contracts.ts +102 -0
- package/src/console/system-prompt/routes.ts +165 -0
- package/src/console/updates/routes.ts +7 -4
- package/src/main.ts +11 -0
- package/src/network/outbound-fetch.ts +75 -4
- package/src/network/pool/resolver.ts +39 -39
- package/src/network/pool-cooldown-store.ts +71 -16
- package/src/network/pool-health-machine.ts +21 -1
- package/src/network/rate-limit-verdict.ts +68 -0
- package/src/network/ssrf.ts +4 -4
- package/src/observability/event-query.ts +437 -22
- package/src/observability/telemetry-status.ts +1 -1
- package/src/persistence/db-pg.ts +42 -0
- package/src/persistence/db-sqlite.ts +7 -2
- package/src/persistence/readiness.ts +18 -6
- package/src/persistence/schema.ts +162 -1
- package/src/persistence/stores/api-key-store.ts +849 -581
- package/src/persistence/stores/share-store.ts +65 -13
- package/src/persistence/stores/telemetry-store.ts +58 -2
- package/src/persistence/system-prompt-store.ts +104 -0
- package/src/protocol/codecs.ts +6 -6
- package/src/protocol/gateway-error.ts +6 -3
- package/src/protocol/image-generation.ts +2 -2
- package/src/protocol/reasoning.ts +65 -1
- package/src/protocol/request/chat.ts +1 -0
- package/src/protocol/response/chat.ts +2 -2
- package/src/protocol/response/codex.ts +1 -1
- package/src/protocol/response/gemini.ts +1 -1
- package/src/protocol/response/messages.ts +5 -5
- package/src/protocol/response/responses.ts +2 -2
- package/src/protocol/sse-decoder.ts +14 -3
- package/src/protocol/translation/capabilities.ts +2 -2
- package/src/protocol/upstream/send-claude-messages.ts +3 -3
- package/src/providers/adapters/base-adapter.ts +1 -1
- package/src/providers/adapters/compatible-adapter.ts +2 -2
- package/src/providers/authentication/oauth-refresh-service.ts +2 -2
- package/src/providers/configured-provider.ts +1 -1
- package/src/providers/discovery/probe-phases.ts +2 -2
- package/src/providers/discovery/probing-service.ts +12 -12
- package/src/providers/integrations/agentrouter/agentrouter.ts +2 -3
- package/src/providers/integrations/alibabacp/alibabacp.ts +2 -2
- package/src/providers/integrations/anthropic.ts +4 -11
- package/src/providers/integrations/antigravity/antigravity.ts +33 -47
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +30 -2
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +37 -6
- package/src/providers/integrations/buddy/buddy-identity.ts +22 -1
- package/src/providers/integrations/buddy/buddy-media.ts +21 -17
- package/src/providers/integrations/buddy/codebuddy/provider.ts +6 -2
- package/src/providers/integrations/buddy/workbuddy/provider.ts +6 -2
- package/src/providers/integrations/claude/claude-betas.ts +1 -1
- package/src/providers/integrations/claude/claude-credentials.ts +1 -1
- package/src/providers/integrations/claude/claude-slow-lane-retry.ts +1 -1
- package/src/providers/integrations/claude/claude.ts +3 -10
- package/src/providers/integrations/cline/cline.ts +8 -1
- package/src/providers/integrations/cloudflareai/cloudflareai.ts +4 -7
- package/src/providers/integrations/codex/codex-errors.ts +1 -1
- package/src/providers/integrations/codex/codex.ts +14 -15
- package/src/providers/integrations/commandcode/commandcode.ts +4 -4
- package/src/providers/integrations/commandcode/quota.ts +5 -1
- package/src/providers/integrations/cursor/cursor-http2.ts +11 -11
- package/src/providers/integrations/cursor/cursor.ts +15 -15
- package/src/providers/integrations/factory/factory.ts +4 -4
- package/src/providers/integrations/gemini.ts +11 -11
- package/src/providers/integrations/github/github.ts +26 -7
- package/src/providers/integrations/grok/grok.ts +2 -6
- package/src/providers/integrations/hermes.ts +5 -1
- package/src/providers/integrations/inferhub.ts +4 -11
- package/src/providers/integrations/kilo/kilo.ts +4 -0
- package/src/providers/integrations/kimi/kimi.ts +4 -11
- package/src/providers/integrations/kiro/kiro.ts +10 -10
- package/src/providers/integrations/muse/muse.ts +6 -9
- package/src/providers/integrations/openrouter/provider.ts +4 -0
- package/src/providers/integrations/perplexity.ts +2 -2
- package/src/providers/integrations/qoder/qoder-catalog.ts +47 -9
- package/src/providers/integrations/qoder/qoder-checkin.ts +242 -51
- package/src/providers/integrations/qoder/qoder-native-identity-store.ts +157 -0
- package/src/providers/integrations/qoder/qoder-oauth.ts +12 -3
- package/src/providers/integrations/qoder/qoder-realm.ts +15 -0
- package/src/providers/integrations/qoder/qoder-umid.ts +287 -0
- package/src/providers/integrations/qoder/qoder-virtual.ts +2 -2
- package/src/providers/integrations/qoder/qoder.ts +192 -24
- package/src/providers/integrations/tokenharbor.ts +2 -2
- package/src/providers/integrations/trae/trae.ts +6 -9
- package/src/providers/integrations/zcode/oauth.ts +1 -1
- package/src/providers/operations/account-error-classification.ts +6 -8
- package/src/providers/operations/account-health-service.ts +14 -16
- package/src/providers/operations/client-versions.ts +37 -22
- package/src/providers/operations/provider-catalog-service.ts +4 -4
- package/src/providers/operations/provider-credential-service.ts +16 -4
- package/src/providers/operations/upstream-deadline.ts +3 -3
- package/src/providers/provider-contracts.ts +55 -3
- package/src/providers/provider-credential-resolver.ts +1 -1
- package/src/providers/provider-registry.ts +4 -4
- package/src/providers/quota/quota-contracts.ts +24 -10
- package/src/providers/quota/refresh.ts +2 -2
- package/src/providers/search/search-provider.ts +5 -5
- package/src/security/abuse.ts +4 -4
- package/src/security/access-control.ts +19 -0
- package/src/security/admission/reasons.ts +17 -17
- package/src/security/api-key-auth.ts +18 -5
- package/src/shared/coerce.ts +19 -0
- package/src/transport/dispatch/attempt-finalize.ts +4 -3
- package/src/transport/dispatch/attempt-loop.ts +10 -7
- package/src/transport/dispatch/empty-stream.ts +6 -6
- package/src/transport/dispatch/generation.ts +9 -9
- package/src/transport/dispatch/leases.ts +8 -8
- package/src/transport/dispatch/proxy-request.ts +38 -9
- package/src/transport/dispatch/responses-compact.ts +11 -11
- package/src/transport/dispatch/retry-policy.ts +4 -67
- package/src/transport/dispatch/stream-bridge.ts +1 -1
- package/src/transport/dispatch/streaming/finalize.ts +9 -8
- package/src/transport/dispatch/streaming/stream.ts +16 -1
- package/src/transport/dispatch/systemone.ts +8 -8
- package/src/transport/dispatch/token-count.ts +9 -9
- package/src/transport/dispatch/upstream.ts +10 -0
- package/src/transport/dispatch/websearch.ts +6 -6
- package/src/transport/drain-endpoint.ts +2 -2
- package/src/transport/failure-policy.ts +13 -6
- package/src/transport/guards/auth-guard.ts +6 -5
- package/src/transport/guards/body-policy.ts +4 -4
- package/src/transport/guards/error-lifecycle.ts +18 -3
- package/src/transport/guards/guard-errors.ts +7 -3
- package/src/transport/guards/headroom-guard.ts +1 -1
- package/src/transport/guards/pipeline.ts +6 -6
- package/src/transport/guards/readiness-guard.ts +16 -2
- package/src/transport/guards/request-context.ts +3 -3
- package/src/transport/request/preparer.ts +37 -21
- package/src/transport/request/state.ts +4 -7
- package/src/transport/request/system-prompt-injection.ts +89 -0
- package/src/transport/request/tenant-preferences.ts +43 -0
- package/src/transport/routing/admission.ts +13 -3
- package/src/transport/routing/route-catalog.ts +104 -2
- package/src/transport/routing/route-model.ts +60 -7
- package/src/transport/routing/router.ts +306 -256
- package/src/transport/shutdown-notice.ts +19 -7
- package/src/transport/surface/completion.ts +1 -1
- package/src/transport/surface/messages/encode.ts +1 -1
- package/src/workers/daily-checkin.ts +2 -0
- package/dist/dashboard/assets/BannedPage-XaUmiBrC.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js +0 -1
- package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-CXGS_Ct-.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js +0 -1
- package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BKtAPYVF.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-BdmRLnq2.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CqMxibJB.js +0 -1
- package/dist/dashboard/assets/OverviewPage-CqMxibJB.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js +0 -4
- package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js +0 -9
- package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js +0 -1
- package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-Co12Zzaw.js +0 -1
- package/dist/dashboard/assets/SetupPage-Co12Zzaw.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-Dqf4zpS-.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-Byj2lAEm.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-CTkLAuRc.js +0 -56
- package/dist/dashboard/assets/UsagePage-CTkLAuRc.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-CUi6UXsR.js +0 -1
- package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
- package/dist/dashboard/assets/app-KvsUJUMF.css +0 -2
- package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
- package/dist/dashboard/assets/assert-67xXH5rf.js +0 -1
- package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
- package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
- package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
- package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js +0 -1
- package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
- package/dist/dashboard/assets/concurrency-BDF0ok7y.js.gz +0 -0
- package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CFM2sMX1.js +0 -1
- package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
- package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
- package/dist/dashboard/assets/entry-ClCMCWWQ.js +0 -4
- package/dist/dashboard/assets/entry-ClCMCWWQ.js.gz +0 -0
- package/dist/dashboard/assets/entry-_xHo5x6r.js +0 -1
- package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
- package/dist/dashboard/assets/formatters-CWWZ-uCZ.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
- package/dist/dashboard/assets/index-DFVFrnWW.js.gz +0 -0
- package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
- package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
- package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
- package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
- package/dist/dashboard/assets/live-D0mm--ME.js +0 -1
- package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
- package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +0 -1
- package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
- package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
- package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
- package/dist/dashboard/assets/quota-DZGyp0N5.js +0 -1
- package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
- package/dist/dashboard/assets/routing-BnIpi1IJ.js +0 -1
- package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
- package/dist/dashboard/assets/select-DBNVLdUu.js.gz +0 -0
- package/dist/dashboard/assets/settings-BAFhDgX8.js +0 -1
- package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
- package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
- package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
- package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-DjkLHUcE.js.gz +0 -0
- /package/dist/dashboard/assets/{app-BaWd0puM.js → app-BayTTy01.js} +0 -0
- /package/dist/dashboard/assets/{app-BaWd0puM.js.gz → app-BayTTy01.js.gz} +0 -0
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
networkPools,
|
|
11
11
|
poolRoutingSettings,
|
|
12
12
|
providerAccounts,
|
|
13
|
+
providerPoolAccounts,
|
|
13
14
|
providerRoutingSettings,
|
|
14
15
|
providers,
|
|
15
16
|
tenantDisabledModels,
|
|
@@ -372,6 +373,17 @@ const POOL_COLUMNS = {
|
|
|
372
373
|
weight: networkPools.weight,
|
|
373
374
|
} as const;
|
|
374
375
|
|
|
376
|
+
const POOL_ACCOUNT_COLUMNS = {
|
|
377
|
+
id: providerPoolAccounts.id,
|
|
378
|
+
tenantId: providerPoolAccounts.tenantId,
|
|
379
|
+
networkPoolId: providerPoolAccounts.networkPoolId,
|
|
380
|
+
providerId: providerPoolAccounts.providerId,
|
|
381
|
+
label: providerPoolAccounts.label,
|
|
382
|
+
status: providerPoolAccounts.status,
|
|
383
|
+
cooldownUntil: providerPoolAccounts.cooldownUntil,
|
|
384
|
+
lastErrorCategory: providerPoolAccounts.lastErrorCategory,
|
|
385
|
+
} as const;
|
|
386
|
+
|
|
375
387
|
const DISABLED_MODEL_COLUMNS = {
|
|
376
388
|
tenantId: tenantDisabledModels.tenantId,
|
|
377
389
|
providerId: tenantDisabledModels.providerId,
|
|
@@ -414,7 +426,7 @@ class RouteCatalogRepository {
|
|
|
414
426
|
constructor(private readonly db: CartethyiaDatabase) {}
|
|
415
427
|
|
|
416
428
|
async loadRouteCatalogSnapshot(tenantId?: string): Promise<RouteCatalogSnapshotResult> {
|
|
417
|
-
const [providerRows, modelRows, accountRows, aliasRows, comboRows, routingRows, poolRows, disabledModelRows, cliMappingRows, cliMappingSettingRows, poolSettingRows, settingsRows] =
|
|
429
|
+
const [providerRows, modelRows, accountRows, aliasRows, comboRows, routingRows, poolRows, poolAccountRows, disabledModelRows, cliMappingRows, cliMappingSettingRows, poolSettingRows, settingsRows] =
|
|
418
430
|
await Promise.all([
|
|
419
431
|
this.db.select(PROVIDER_COLUMNS).from(providers).where(eq(providers.enabled, true)),
|
|
420
432
|
this.db.select(MODEL_COLUMNS).from(models),
|
|
@@ -427,6 +439,7 @@ class RouteCatalogRepository {
|
|
|
427
439
|
this.db.select(COMBO_COLUMNS).from(modelCombos),
|
|
428
440
|
this.db.select(ROUTING_COLUMNS).from(providerRoutingSettings),
|
|
429
441
|
this.db.select(POOL_COLUMNS).from(networkPools),
|
|
442
|
+
this.db.select(POOL_ACCOUNT_COLUMNS).from(providerPoolAccounts),
|
|
430
443
|
this.db.select(DISABLED_MODEL_COLUMNS).from(tenantDisabledModels),
|
|
431
444
|
this.db.select(CLI_MAPPING_COLUMNS).from(cliToolMappings),
|
|
432
445
|
this.db.select(CLI_MAPPING_SETTING_COLUMNS).from(cliToolSettings),
|
|
@@ -500,6 +513,28 @@ class RouteCatalogRepository {
|
|
|
500
513
|
activePoolsByTenant.set(pool.tenantId, list);
|
|
501
514
|
}
|
|
502
515
|
|
|
516
|
+
// Pool-as-account rows, grouped by tenant: one per (pool × ip-scoped
|
|
517
|
+
// provider). For a credential-less ip-scoped provider these are the
|
|
518
|
+
// account-equivalent routing entities — a spent egress is excluded from
|
|
519
|
+
// the plan exactly like a cooling account, and the candidate carries the
|
|
520
|
+
// pool-account's health (see the public-candidate fan-out below).
|
|
521
|
+
const poolAccountsByTenant = new Map<
|
|
522
|
+
string,
|
|
523
|
+
Array<{
|
|
524
|
+
id: string;
|
|
525
|
+
networkPoolId: string;
|
|
526
|
+
providerId: string;
|
|
527
|
+
status: string;
|
|
528
|
+
cooldownUntil: Date | null;
|
|
529
|
+
lastErrorCategory: string | null;
|
|
530
|
+
}>
|
|
531
|
+
>();
|
|
532
|
+
for (const poolAccount of poolAccountRows) {
|
|
533
|
+
const list = poolAccountsByTenant.get(poolAccount.tenantId) ?? [];
|
|
534
|
+
list.push(poolAccount);
|
|
535
|
+
poolAccountsByTenant.set(poolAccount.tenantId, list);
|
|
536
|
+
}
|
|
537
|
+
|
|
503
538
|
// Per-tenant pool selection strategy; an absent row reads as the
|
|
504
539
|
// `least_loaded` default at selection time.
|
|
505
540
|
const poolRouting: Record<string, PoolRoutingSetting> = {};
|
|
@@ -657,7 +692,67 @@ class RouteCatalogRepository {
|
|
|
657
692
|
if (accounts.length === 0) {
|
|
658
693
|
const providerRequiresAccount = requiresAccountById.get(model.providerId) ?? true;
|
|
659
694
|
if (!providerRequiresAccount) {
|
|
660
|
-
// Public models inherit active pools for each tenant that has active pools
|
|
695
|
+
// Public models inherit active pools for each tenant that has active pools.
|
|
696
|
+
// When the provider is ip-scoped (limits follow the egress address), the
|
|
697
|
+
// tenant's pool-account rows are the account-equivalent routing entities:
|
|
698
|
+
// one candidate per pool, carrying that pool-account's health, so a spent
|
|
699
|
+
// egress is excluded from the plan exactly like a cooling account.
|
|
700
|
+
const ownedTenantIds = [...poolAccountsByTenant.keys()].filter((tid) =>
|
|
701
|
+
(poolAccountsByTenant.get(tid) ?? []).some((pa) => pa.providerId === model.providerId),
|
|
702
|
+
);
|
|
703
|
+
let emittedPoolAccount = false;
|
|
704
|
+
for (const tenantOwnerId of ownedTenantIds) {
|
|
705
|
+
const poolAccounts = poolAccountsByTenant.get(tenantOwnerId) ?? [];
|
|
706
|
+
const tenantPoolAccounts = new Map<string, typeof poolAccounts>();
|
|
707
|
+
for (const pa of poolAccounts) {
|
|
708
|
+
if (pa.providerId !== model.providerId) continue;
|
|
709
|
+
const list = tenantPoolAccounts.get(pa.networkPoolId) ?? [];
|
|
710
|
+
list.push(pa);
|
|
711
|
+
tenantPoolAccounts.set(pa.networkPoolId, list);
|
|
712
|
+
}
|
|
713
|
+
if (tenantPoolAccounts.size === 0) continue;
|
|
714
|
+
for (const [poolId, pas] of tenantPoolAccounts) {
|
|
715
|
+
const first = pas[0];
|
|
716
|
+
if (!first) continue;
|
|
717
|
+
const tenantPools = resolveNetworkPools(model.providerId, tenantOwnerId);
|
|
718
|
+
if (!tenantPools) continue;
|
|
719
|
+
emittedPoolAccount = true;
|
|
720
|
+
const tenantCandidate: RouteCandidateWithHealth = {
|
|
721
|
+
provider_id: model.providerId,
|
|
722
|
+
model_id: model.modelId,
|
|
723
|
+
wire_family: model.wireFamily as WireFamily,
|
|
724
|
+
service_kind: model.serviceKind,
|
|
725
|
+
endpoint: model.endpointPath,
|
|
726
|
+
...(model.outputLimit == null ? {} : { output_limit: model.outputLimit }),
|
|
727
|
+
capability_profile: capabilityProfile,
|
|
728
|
+
tenant_id: tenantOwnerId,
|
|
729
|
+
// Public credential-less candidates have no account to own them.
|
|
730
|
+
owner_tenant_id: null,
|
|
731
|
+
requires_account: false as const,
|
|
732
|
+
network_pool_ids: [poolId],
|
|
733
|
+
network_pool_required: true,
|
|
734
|
+
network_pool_limits: tenantPools.limits,
|
|
735
|
+
network_pool_weights: tenantPools.weights,
|
|
736
|
+
...(tenantPools.routing ? { network_pool_routing: tenantPools.routing } : {}),
|
|
737
|
+
...providerLimitFor(model.providerId, tenantOwnerId),
|
|
738
|
+
...(first.status === "disabled"
|
|
739
|
+
? { health_status: "disabled" as const }
|
|
740
|
+
: first.status === "cooldown"
|
|
741
|
+
? {
|
|
742
|
+
health_status: "cooldown" as const,
|
|
743
|
+
cooldown_kind: hardCooldownCategory(first.lastErrorCategory) ? "hard" : "soft",
|
|
744
|
+
...(first.cooldownUntil && first.cooldownUntil.getTime() > Date.now()
|
|
745
|
+
? { cooldown_until: first.cooldownUntil.getTime() }
|
|
746
|
+
: {}),
|
|
747
|
+
}
|
|
748
|
+
: {}),
|
|
749
|
+
};
|
|
750
|
+
if (tenantId === undefined || tenantId === tenantOwnerId) {
|
|
751
|
+
candidates.push(tenantCandidate);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
if (emittedPoolAccount) continue;
|
|
661
756
|
for (const tId of configuredPoolTenants) {
|
|
662
757
|
const tenantPools = resolveNetworkPools(model.providerId, tId);
|
|
663
758
|
if (tenantPools) {
|
|
@@ -670,6 +765,8 @@ class RouteCatalogRepository {
|
|
|
670
765
|
...(model.outputLimit == null ? {} : { output_limit: model.outputLimit }),
|
|
671
766
|
capability_profile: capabilityProfile,
|
|
672
767
|
tenant_id: tId,
|
|
768
|
+
// Public credential-less candidates have no account to own them.
|
|
769
|
+
owner_tenant_id: null,
|
|
673
770
|
requires_account: false as const,
|
|
674
771
|
network_pool_ids: tenantPools.ids,
|
|
675
772
|
network_pool_required: true,
|
|
@@ -696,6 +793,8 @@ class RouteCatalogRepository {
|
|
|
696
793
|
...(model.outputLimit == null ? {} : { output_limit: model.outputLimit }),
|
|
697
794
|
capability_profile: capabilityProfile,
|
|
698
795
|
tenant_id: providerTenantId,
|
|
796
|
+
// Public credential-less candidates have no account to own them.
|
|
797
|
+
owner_tenant_id: null,
|
|
699
798
|
...(providerRequiresAccount
|
|
700
799
|
? { health_status: "disabled" as const }
|
|
701
800
|
: { requires_account: false as const }),
|
|
@@ -738,6 +837,9 @@ class RouteCatalogRepository {
|
|
|
738
837
|
...(routeUserAgent === undefined ? {} : { user_agent: routeUserAgent }),
|
|
739
838
|
tenant_id: rowTenantId,
|
|
740
839
|
provider_account_id: account.id,
|
|
840
|
+
// The account's owning tenant (null = shared pool-wide) — the bucket
|
|
841
|
+
// key for admission, distinct from the requesting tenant.
|
|
842
|
+
owner_tenant_id: account.tenantId ?? null,
|
|
741
843
|
// The plan gate is per (account, model): the model may be refused on
|
|
742
844
|
// a free plan and the account may be on one. Both ride here because
|
|
743
845
|
// `plan()` sees the candidate and nothing else.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Routing contracts and snapshots.
|
|
2
2
|
import { GatewayError } from "../../protocol/gateway-error";
|
|
3
3
|
import { type ServiceKind, type WireFamily } from "../../protocol/canonical-model";
|
|
4
|
+
import type { CallerIdentity } from "../../security/access-control";
|
|
5
|
+
|
|
6
|
+
export type { CallerIdentity };
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
export type RoutingRevision = number;
|
|
@@ -57,6 +60,14 @@ export interface RouteCandidate {
|
|
|
57
60
|
readonly network_pool_provider_limit?: number;
|
|
58
61
|
/** `null`/`undefined` = globally routable; a tenant id = routable only for that tenant's requests (BYOK). */
|
|
59
62
|
readonly tenant_id?: string | null;
|
|
63
|
+
/**
|
|
64
|
+
* The tenant that owns this candidate's account (`provider_accounts.tenant_id`),
|
|
65
|
+
* or null for a shared pool-wide account. Distinct from `tenant_id` (the
|
|
66
|
+
* requesting tenant). Used to scope the admission bucket: a shared account
|
|
67
|
+
* is one bucket across tenants; a tenant-owned account is scoped to its
|
|
68
|
+
* owner so two tenants cannot drain each other's ceiling.
|
|
69
|
+
*/
|
|
70
|
+
readonly owner_tenant_id?: string | null;
|
|
60
71
|
/** `false` only for a genuinely credential-less provider (e.g. OpenCode
|
|
61
72
|
* Free) dispatched with zero `provider_accounts` rows — the handler skips
|
|
62
73
|
* `resolveCredentialForAccount` and dispatches with a `"none"` credential.
|
|
@@ -80,6 +91,11 @@ export interface RouteCandidate {
|
|
|
80
91
|
* "free": guessing free here would defeat the gate it exists to serve.
|
|
81
92
|
*/
|
|
82
93
|
readonly account_plan?: string | null;
|
|
94
|
+
/** Usage-floor ceiling from Routing Strategy; read live at plan time. */
|
|
95
|
+
readonly usage_floor?: number;
|
|
96
|
+
readonly usage_floor_unit?: "credit" | "percent";
|
|
97
|
+
/** Live quota windows (cache) the floor check evaluates. */
|
|
98
|
+
readonly quota_windows?: readonly unknown[];
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
/**
|
|
@@ -163,6 +179,16 @@ export interface PoolRoutingSetting {
|
|
|
163
179
|
export interface RouteContinuationAffinity {
|
|
164
180
|
readonly providerId: string;
|
|
165
181
|
readonly providerAccountId: string;
|
|
182
|
+
/**
|
|
183
|
+
* True when the request's tool-result ids are all already answered by the
|
|
184
|
+
* conversation history (a replay), so no call is still owed to the pinned
|
|
185
|
+
* account. In that case, if the pinned account is no longer routable for
|
|
186
|
+
* the requested model, the request may safely rebase to a fresh Run on an
|
|
187
|
+
* eligible account instead of being refused — the recorded exchange travels
|
|
188
|
+
* as history. When false, the pin is a hard constraint: a live pending call
|
|
189
|
+
* must reach the exact account that owns it.
|
|
190
|
+
*/
|
|
191
|
+
readonly rebaseable: boolean;
|
|
166
192
|
}
|
|
167
193
|
|
|
168
194
|
export interface RoutePlan {
|
|
@@ -171,6 +197,33 @@ export interface RoutePlan {
|
|
|
171
197
|
readonly requested_model: string;
|
|
172
198
|
readonly resolved_model: string;
|
|
173
199
|
readonly provider_id: string;
|
|
200
|
+
/**
|
|
201
|
+
* The system decision behind each candidate, keyed by the candidate's
|
|
202
|
+
* admission bucket. Written once at plan time; every later layer (dispatch,
|
|
203
|
+
* telemetry) reads this instead of re-deriving its own ordering.
|
|
204
|
+
*/
|
|
205
|
+
readonly decisions: ReadonlyMap<string, RoutingDecision>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** How eligible a candidate is and why — written once, read by every layer. */
|
|
209
|
+
export const ROUTING_RANK = {
|
|
210
|
+
FRESH: 0,
|
|
211
|
+
SLOW: 1,
|
|
212
|
+
COOLING: 2,
|
|
213
|
+
SATURATED: 3,
|
|
214
|
+
} as const;
|
|
215
|
+
export type RoutingRank = (typeof ROUTING_RANK)[keyof typeof ROUTING_RANK];
|
|
216
|
+
|
|
217
|
+
export interface RoutingDecision {
|
|
218
|
+
readonly eligible: boolean;
|
|
219
|
+
readonly rank: RoutingRank;
|
|
220
|
+
readonly reason: string;
|
|
221
|
+
readonly health_status?: string;
|
|
222
|
+
readonly cooldown_until?: number;
|
|
223
|
+
readonly floor_blocked?: boolean;
|
|
224
|
+
readonly plan_gate_blocked?: boolean;
|
|
225
|
+
readonly capability_blocked?: boolean;
|
|
226
|
+
readonly saturated?: boolean;
|
|
174
227
|
}
|
|
175
228
|
|
|
176
229
|
import type { ComboStrategy, PoolRoutingStrategy, ProviderRoutingStrategy } from "../../persistence/schema";
|
|
@@ -305,7 +358,7 @@ export function ambiguousModelError(bare: string, owners: string[]): GatewayErro
|
|
|
305
358
|
return new GatewayError(
|
|
306
359
|
"ambiguous_model",
|
|
307
360
|
400,
|
|
308
|
-
`'${bare}' matches more than one provider (${owners.join(", ")}). Qualify it as '${owners[0]}/${bare}', or add an alias to pick one
|
|
361
|
+
`'${bare}' matches more than one provider (${owners.join(", ")}). Qualify it as '${owners[0]}/${bare}', or add an alias to pick one. Too popular for its own good — qualify it 🧩`,
|
|
309
362
|
{
|
|
310
363
|
model: bare,
|
|
311
364
|
owners,
|
|
@@ -327,7 +380,7 @@ export function modelNotFoundError(requested: string, resolved: readonly string[
|
|
|
327
380
|
404,
|
|
328
381
|
`'${requested}' is not routed${
|
|
329
382
|
targets.length > 0 ? ` — it resolved to ${hint}, which no account serves` : ""
|
|
330
|
-
}. Enable the model on an account, or point the alias at one that exists
|
|
383
|
+
} (request {requestId}). Enable the model on an account, or point the alias at one that exists. Try another model — this one's off the menu 📚`,
|
|
331
384
|
{
|
|
332
385
|
model: requested,
|
|
333
386
|
...(targets.length > 0 ? { resolved_models: targets } : {}),
|
|
@@ -339,7 +392,7 @@ export function capabilityUnsupportedError(capability: string): GatewayError {
|
|
|
339
392
|
return new GatewayError(
|
|
340
393
|
"capability_unsupported",
|
|
341
394
|
400,
|
|
342
|
-
`No account serving this model supports ${capability}. Drop the ${capability} part of the request, or route to a model that accepts it
|
|
395
|
+
`No account serving this model supports ${capability} (request {requestId}). Drop the ${capability} part of the request, or route to a model that accepts it. Know your tools — this one just isn't in the box 🧰`,
|
|
343
396
|
{ capability },
|
|
344
397
|
);
|
|
345
398
|
}
|
|
@@ -371,8 +424,8 @@ export function capacityExhaustedError(context?: {
|
|
|
371
424
|
"provider_capacity_exhausted",
|
|
372
425
|
429,
|
|
373
426
|
onlyOne
|
|
374
|
-
? "The only account routing this model is at its concurrency limit. Retry shortly; if it persists, raise the provider's max-inflight or add another account."
|
|
375
|
-
: "Every account is at its concurrency limit. Retry shortly; if it persists, raise the provider's max-inflight or add an account.",
|
|
427
|
+
? "The only account routing this model is at its concurrency limit (request {requestId}). Retry shortly; if it persists, raise the provider's max-inflight or add another account. Even the machine needs a rest — chill 🦋"
|
|
428
|
+
: "Every account is at its concurrency limit (request {requestId}). Retry shortly; if it persists, raise the provider's max-inflight or add an account. Even the machine needs a rest — chill 🦋",
|
|
376
429
|
{
|
|
377
430
|
...(context?.providerId !== undefined ? { providerId: context.providerId } : {}),
|
|
378
431
|
...(context?.model !== undefined ? { model: context.model } : {}),
|
|
@@ -403,7 +456,7 @@ export function accountsUnavailableError(
|
|
|
403
456
|
return new GatewayError(
|
|
404
457
|
"accounts_unavailable",
|
|
405
458
|
503,
|
|
406
|
-
`No account in the pool can serve '${requested}' right now (${explainEligibilityReasons(distinct)}). Add an account, or wait for an operator to re-enable one
|
|
459
|
+
`No account in the pool can serve '${requested}' right now (request {requestId}) (${explainEligibilityReasons(distinct)}). Add an account, or wait for an operator to re-enable one. Every account is on a coffee break — try later ☕️`,
|
|
407
460
|
{ model: requested, reasons: distinct, candidate_count: reasons.length, gateway_hint: "no_healthy_account" },
|
|
408
461
|
);
|
|
409
462
|
}
|
|
@@ -439,7 +492,7 @@ export function accountsRateLimitedError(
|
|
|
439
492
|
return new GatewayError(
|
|
440
493
|
"accounts_rate_limited",
|
|
441
494
|
429,
|
|
442
|
-
`Every account serving '${requested}'${routeNote} is cooling down after hitting upstream limits. The request is fine — retry once the cooldown resets
|
|
495
|
+
`Every account serving '${requested}'${routeNote} is cooling down after hitting upstream limits (request {requestId}). The request is fine — retry once the cooldown resets. They're resting up 🌸`,
|
|
443
496
|
{
|
|
444
497
|
model: requested,
|
|
445
498
|
routed_model: routed,
|