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
|
@@ -108,7 +108,7 @@ export async function buddyGenerateImage(
|
|
|
108
108
|
context: ProviderDispatchContext,
|
|
109
109
|
): Promise<ImageGenerationOutcome> {
|
|
110
110
|
const model = modelOf(body, candidate);
|
|
111
|
-
if (model.length === 0) throw new GatewayError("invalid_request", 400, "model is required");
|
|
111
|
+
if (model.length === 0) throw new GatewayError("invalid_request", 400, "model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
112
112
|
const prompt = imagePrompt(body);
|
|
113
113
|
if (config.imageGenerationPath !== undefined) {
|
|
114
114
|
const requestBody: Record<string, unknown> = { model, prompt };
|
|
@@ -134,28 +134,28 @@ export async function buddyGenerateImage(
|
|
|
134
134
|
release();
|
|
135
135
|
}
|
|
136
136
|
if (!isRecord(responseBody)) {
|
|
137
|
-
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned an invalid response", {}, "upstream");
|
|
137
|
+
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned an invalid response (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream");
|
|
138
138
|
}
|
|
139
139
|
const providerError = buddyErrorOf(responseBody);
|
|
140
140
|
if (providerError !== undefined) {
|
|
141
|
-
throw new GatewayError("platform_unavailable", 502, providerError
|
|
141
|
+
throw new GatewayError("platform_unavailable", 502, `${providerError} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
142
142
|
}
|
|
143
143
|
if (responseBody.code !== undefined && responseBody.code !== 0 && responseBody.code !== "0") {
|
|
144
144
|
const message =
|
|
145
145
|
typeof responseBody.msg === "string" && responseBody.msg.trim().length > 0
|
|
146
146
|
? responseBody.msg.trim()
|
|
147
147
|
: `CodeBuddy image generation failed with code ${String(responseBody.code)}`;
|
|
148
|
-
throw new GatewayError("platform_unavailable", 502, message
|
|
148
|
+
throw new GatewayError("platform_unavailable", 502, `${message} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
149
149
|
}
|
|
150
150
|
if (!isRecord(responseBody.data)) {
|
|
151
|
-
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned no image data", {}, "upstream");
|
|
151
|
+
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned no image data (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream");
|
|
152
152
|
}
|
|
153
153
|
const result = responseBody.data;
|
|
154
154
|
if (!Array.isArray(result.data) || result.data.some((image) => !isRecord(image))) {
|
|
155
|
-
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned malformed image data", {}, "upstream");
|
|
155
|
+
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned malformed image data (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream");
|
|
156
156
|
}
|
|
157
157
|
if (result.data.length === 0) {
|
|
158
|
-
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned no images", {}, "upstream");
|
|
158
|
+
throw new GatewayError("platform_unavailable", 502, "CodeBuddy image generation returned no images (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream");
|
|
159
159
|
}
|
|
160
160
|
return {
|
|
161
161
|
...(typeof result.created === "number" ? { created: result.created } : {}),
|
|
@@ -173,7 +173,11 @@ export async function buddyGenerateImage(
|
|
|
173
173
|
buddyPrePayloadCommon(payload, undefined, "intl", context);
|
|
174
174
|
const messages = payload["messages"];
|
|
175
175
|
if (Array.isArray(messages)) {
|
|
176
|
-
applyBuddySystemPrompt(
|
|
176
|
+
applyBuddySystemPrompt(
|
|
177
|
+
messages as Array<Record<string, unknown>>,
|
|
178
|
+
config.systemPrompt,
|
|
179
|
+
context?.tenant_system_prompt,
|
|
180
|
+
);
|
|
177
181
|
}
|
|
178
182
|
const headers: Record<string, string> = {
|
|
179
183
|
"content-type": "application/json",
|
|
@@ -213,7 +217,7 @@ export async function buddyGenerateImage(
|
|
|
213
217
|
if (!contentType.includes("text/event-stream")) {
|
|
214
218
|
const parsed: unknown = await response.json().catch(() => null);
|
|
215
219
|
const message = buddyErrorOf(parsed) ?? "CodeBuddy image generation returned a non-stream body";
|
|
216
|
-
throw new GatewayError("platform_unavailable", 502, message
|
|
220
|
+
throw new GatewayError("platform_unavailable", 502, `${message} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
217
221
|
}
|
|
218
222
|
let content = "";
|
|
219
223
|
for await (const event of decodeSseEvents(response.body, { signal: context.abort_signal })) {
|
|
@@ -228,7 +232,7 @@ export async function buddyGenerateImage(
|
|
|
228
232
|
if (!isRecord(parsed)) continue;
|
|
229
233
|
if (isRecord(parsed.error)) {
|
|
230
234
|
const message = isRecord(parsed.error) && typeof parsed.error.message === "string" ? parsed.error.message : "CodeBuddy image generation failed";
|
|
231
|
-
throw new GatewayError("platform_unavailable", 502, message
|
|
235
|
+
throw new GatewayError("platform_unavailable", 502, `${message} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
232
236
|
}
|
|
233
237
|
const choices = parsed.choices;
|
|
234
238
|
if (!Array.isArray(choices) || !isRecord(choices[0])) continue;
|
|
@@ -240,7 +244,7 @@ export async function buddyGenerateImage(
|
|
|
240
244
|
throw new GatewayError(
|
|
241
245
|
"platform_unavailable",
|
|
242
246
|
502,
|
|
243
|
-
"CodeBuddy image generation returned no image in the chat stream",
|
|
247
|
+
"CodeBuddy image generation returned no image in the chat stream (request {requestId}). The upstream came back empty-handed — retry 🌙",
|
|
244
248
|
{},
|
|
245
249
|
"upstream",
|
|
246
250
|
);
|
|
@@ -314,7 +318,7 @@ export async function buddyGenerateVideo(
|
|
|
314
318
|
context: ProviderDispatchContext,
|
|
315
319
|
): Promise<Record<string, unknown>> {
|
|
316
320
|
const model = modelOf(body, candidate);
|
|
317
|
-
if (model.length === 0) throw new GatewayError("invalid_request", 400, "model is required");
|
|
321
|
+
if (model.length === 0) throw new GatewayError("invalid_request", 400, "model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
318
322
|
const prompt = imagePrompt(body);
|
|
319
323
|
const submitBody: Record<string, unknown> = { model, prompt };
|
|
320
324
|
if (typeof body.n === "number" && Number.isFinite(body.n)) submitBody["n"] = Math.max(1, Math.floor(body.n));
|
|
@@ -350,14 +354,14 @@ export async function buddyGenerateVideo(
|
|
|
350
354
|
if (url !== undefined) return { data: [{ url }] };
|
|
351
355
|
// Otherwise cb refused (HTTP 200 error envelope) — surface its own reason.
|
|
352
356
|
const message = buddyErrorOf(submitted) ?? "CodeBuddy video submit returned no task id";
|
|
353
|
-
throw new GatewayError("platform_unavailable", 502, message
|
|
357
|
+
throw new GatewayError("platform_unavailable", 502, `${message} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
354
358
|
}
|
|
355
359
|
// Poll the sibling task endpoint until the clip is ready.
|
|
356
360
|
const taskPath = `${submitUrl.replace(/\/+$/, "")}/${taskId}`;
|
|
357
361
|
const deadline = Date.now() + VIDEO_POLL_TIMEOUT_MS;
|
|
358
362
|
for (;;) {
|
|
359
363
|
if (context.abort_signal?.aborted) {
|
|
360
|
-
throw new GatewayError("transport_closed", 499, "video generation aborted");
|
|
364
|
+
throw new GatewayError("transport_closed", 499, "video generation aborted (request {requestId}). Send it again whenever ready 🙃");
|
|
361
365
|
}
|
|
362
366
|
const lifecycle = createUpstreamDeadlineLifecycle(context);
|
|
363
367
|
let statusRes: Response;
|
|
@@ -370,7 +374,7 @@ export async function buddyGenerateVideo(
|
|
|
370
374
|
} catch (error: unknown) {
|
|
371
375
|
const abortError = abortGatewayError(lifecycle, error, context.abort_signal);
|
|
372
376
|
if (abortError) throw abortError;
|
|
373
|
-
throw new GatewayError("platform_unavailable", 502, `CodeBuddy video status unreachable: ${error instanceof Error ? error.message : String(error)}
|
|
377
|
+
throw new GatewayError("platform_unavailable", 502, `CodeBuddy video status unreachable (request {requestId}): ${error instanceof Error ? error.message : String(error)}. The connection ghosted us — come back in a moment 👻`, {}, "upstream");
|
|
374
378
|
} finally {
|
|
375
379
|
lifecycle.release();
|
|
376
380
|
}
|
|
@@ -382,10 +386,10 @@ export async function buddyGenerateVideo(
|
|
|
382
386
|
if (url !== undefined) return { data: [{ url }], task_id: taskId };
|
|
383
387
|
const status = videoStatusOf(payload);
|
|
384
388
|
if (status !== undefined && !VIDEO_PENDING.has(status)) {
|
|
385
|
-
throw new GatewayError("platform_unavailable", 502, `CodeBuddy video task ended in state "${status}" with no clip
|
|
389
|
+
throw new GatewayError("platform_unavailable", 502, `CodeBuddy video task ended in state "${status}" with no clip (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
386
390
|
}
|
|
387
391
|
if (Date.now() > deadline) {
|
|
388
|
-
throw new GatewayError("platform_unavailable", 504, `CodeBuddy video task ${taskId} did not finish within ${VIDEO_POLL_TIMEOUT_MS}ms
|
|
392
|
+
throw new GatewayError("platform_unavailable", 504, `CodeBuddy video task ${taskId} did not finish within ${VIDEO_POLL_TIMEOUT_MS}ms (request {requestId}). Some things just take longer 🐢`, {}, "upstream");
|
|
389
393
|
}
|
|
390
394
|
await new Promise((resolve) => setTimeout(resolve, VIDEO_POLL_INTERVAL_MS));
|
|
391
395
|
}
|
|
@@ -81,10 +81,14 @@ function codeBuddyIntlPrePayload(
|
|
|
81
81
|
typeof rawModel === "string" && rawModel.length > 0
|
|
82
82
|
? rawModel
|
|
83
83
|
: candidate.model_id;
|
|
84
|
-
if (!source) throw new GatewayError("invalid_request", 400, "CodeBuddy model is required");
|
|
84
|
+
if (!source) throw new GatewayError("invalid_request", 400, "CodeBuddy model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
85
85
|
const messages = payload["messages"];
|
|
86
86
|
if (Array.isArray(messages)) {
|
|
87
|
-
applyBuddySystemPrompt(
|
|
87
|
+
applyBuddySystemPrompt(
|
|
88
|
+
messages as Array<Record<string, unknown>>,
|
|
89
|
+
CODEBUDDY_SYSTEM_PROMPT,
|
|
90
|
+
context?.tenant_system_prompt,
|
|
91
|
+
);
|
|
88
92
|
}
|
|
89
93
|
normalizeBuddyToolNames(payload);
|
|
90
94
|
injectBuddyParallelToolCalls(payload, request);
|
|
@@ -134,11 +134,15 @@ export function workbuddyPrePayload(
|
|
|
134
134
|
const rawModel = payload["model"];
|
|
135
135
|
const source =
|
|
136
136
|
typeof rawModel === "string" && rawModel.length > 0 ? rawModel : candidate.model_id;
|
|
137
|
-
if (!source) throw new GatewayError("invalid_request", 400, "WorkBuddy model is required");
|
|
137
|
+
if (!source) throw new GatewayError("invalid_request", 400, "WorkBuddy model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
138
138
|
const messages = payload["messages"];
|
|
139
139
|
if (Array.isArray(messages)) {
|
|
140
140
|
const normalizedMessages = messages as Array<Record<string, unknown>>;
|
|
141
|
-
applyBuddySystemPrompt(
|
|
141
|
+
applyBuddySystemPrompt(
|
|
142
|
+
normalizedMessages,
|
|
143
|
+
WORKBUDDY_SYSTEM_PROMPT,
|
|
144
|
+
context?.tenant_system_prompt,
|
|
145
|
+
);
|
|
142
146
|
restoreHistoricalToolDefinitions(payload, normalizedMessages);
|
|
143
147
|
}
|
|
144
148
|
normalizeBuddyToolNames(payload);
|
|
@@ -67,7 +67,7 @@ export const ANTHROPIC_BETA_CAPABILITIES: Readonly<Record<string, readonly strin
|
|
|
67
67
|
const BETA_TOKEN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
68
68
|
|
|
69
69
|
function invalidBeta(message: string, value: unknown): GatewayError {
|
|
70
|
-
return new GatewayError("invalid_request", 400, message
|
|
70
|
+
return new GatewayError("invalid_request", 400, `${message} (request {requestId}). Check the shape of what you sent — then resend 🪞`, { field: "anthropic-beta", value });
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
@@ -10,7 +10,7 @@ function invalidHeader(
|
|
|
10
10
|
message: string,
|
|
11
11
|
details: Readonly<Record<string, unknown>> = {},
|
|
12
12
|
): GatewayError {
|
|
13
|
-
return new GatewayError("invalid_request", 400, message
|
|
13
|
+
return new GatewayError("invalid_request", 400, `${message} (request {requestId}). Check the shape of what you sent — then resend 🪞`, details);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function decodeSecret(secret: Uint8Array | undefined): string | undefined {
|
|
@@ -96,5 +96,5 @@ export function planSlowLaneRetry(
|
|
|
96
96
|
|
|
97
97
|
/** Typed error for a caller-aborted wait, so it is never read as a failure. */
|
|
98
98
|
export function slowLaneAborted(): GatewayError {
|
|
99
|
-
return new GatewayError("transport_closed", 499, "
|
|
99
|
+
return new GatewayError("transport_closed", 499, "The request was cancelled during the slow-lane capacity wait (request {requestId}). Send it again whenever ready 🙃");
|
|
100
100
|
}
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
refusalCreditToken,
|
|
62
62
|
sharedFallbackCreditCache,
|
|
63
63
|
} from "./fallback-credit";
|
|
64
|
+
import { assertCredentialKind, assertWireFamily } from "../../provider-contracts";
|
|
64
65
|
import type { ProviderDispatchTarget, ProviderAdapter, ProviderDispatchContext } from "../../provider-contracts";
|
|
65
66
|
import { defineModel } from "../../provider-model-definition";
|
|
66
67
|
import type { ModelDefinition } from "../../provider-model-definition";
|
|
@@ -185,21 +186,13 @@ export class ClaudeAdapter implements ProviderAdapter {
|
|
|
185
186
|
context: ProviderDispatchContext,
|
|
186
187
|
): AsyncIterable<CanonicalEvent> {
|
|
187
188
|
if (candidate.wire_family !== "messages") {
|
|
188
|
-
|
|
189
|
-
"capability_unsupported",
|
|
190
|
-
400,
|
|
191
|
-
"claude supports messages only",
|
|
192
|
-
);
|
|
189
|
+
assertWireFamily(candidate, "messages", "claude");
|
|
193
190
|
}
|
|
194
191
|
if (
|
|
195
192
|
context.credential.credential_kind !== "oauth" &&
|
|
196
193
|
context.credential.credential_kind !== "scoped_access_token"
|
|
197
194
|
) {
|
|
198
|
-
|
|
199
|
-
"invalid_request",
|
|
200
|
-
400,
|
|
201
|
-
`claude: the assistant OAuth credential required (got credential_kind=${context.credential.credential_kind})`,
|
|
202
|
-
);
|
|
195
|
+
assertCredentialKind(context.credential, ["oauth", "scoped_access_token"], "claude");
|
|
203
196
|
}
|
|
204
197
|
const customHeaders = filterClaudeCustomHeaders({
|
|
205
198
|
...this.customHeaders,
|
|
@@ -8,6 +8,7 @@ import { completeRequiredSchema, isRecord } from "../../../protocol/codecs";
|
|
|
8
8
|
import { providerBaseUrl } from "../../provider-metadata";
|
|
9
9
|
import { getCachedModelDiscovery } from "../../operations/model-discovery-cache";
|
|
10
10
|
import { defineModel } from "../../provider-model-definition";
|
|
11
|
+
import { clineReasoningReplayPrepares } from "../buddy/buddy-chat-shared";
|
|
11
12
|
import { clinePlatform, clinePlatformVersion } from "../../operations/cli-platform";
|
|
12
13
|
import {
|
|
13
14
|
getClineCliVersion,
|
|
@@ -133,6 +134,12 @@ function clinePrePayload(
|
|
|
133
134
|
? messages
|
|
134
135
|
: [{ role: "system", content: "You are a helpful assistant." }, ...messages];
|
|
135
136
|
|
|
137
|
+
// 1.5) DeepSeek-replay backfill: Cline resells thinking models (deepseek,
|
|
138
|
+
// reflection/beam) whose upstream rejects the whole history when any prior
|
|
139
|
+
// assistant turn lacks `reasoning_content`. Same wire as OpenRouter/Hermes/
|
|
140
|
+
// Kilo, so the shared helper runs here too — it only mirrors a real trace.
|
|
141
|
+
for (const prepare of clineReasoningReplayPrepares) prepare(payload);
|
|
142
|
+
|
|
136
143
|
// 2) Materialize deepseek-v4-flash non-stream quirk
|
|
137
144
|
const model = typeof payload["model"] === "string" ? (payload["model"] as string) : candidate.model_id;
|
|
138
145
|
const needsMaterialize = !request.stream && model.includes("deepseek-v4-flash");
|
|
@@ -143,7 +150,7 @@ function clinePrePayload(
|
|
|
143
150
|
const cur = typeof payload["max_tokens"] === "number" ? (payload["max_tokens"] as number) : 0;
|
|
144
151
|
payload["max_tokens"] = Math.max(cur, 256);
|
|
145
152
|
// keep GatewayError reachable
|
|
146
|
-
if (!model) throw new GatewayError("invalid_request", 400, "Cline model is required");
|
|
153
|
+
if (!model) throw new GatewayError("invalid_request", 400, "Cline model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
156
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* protocol at the `/anthropic` path suffix, including `thinking_delta`
|
|
17
17
|
* blocks, so the Messages leg is built directly.
|
|
18
18
|
*/
|
|
19
|
+
import { assertWireFamily } from "../../provider-contracts";
|
|
19
20
|
import type {
|
|
20
21
|
ProviderAdapter,
|
|
21
22
|
ProviderDispatchContext,
|
|
@@ -57,7 +58,7 @@ function cloudflareEnvelope(context: ProviderDispatchContext): {
|
|
|
57
58
|
} {
|
|
58
59
|
const secret = context.credential.secret;
|
|
59
60
|
if (secret === undefined || secret.length === 0) {
|
|
60
|
-
throw new GatewayError("invalid_request", 400, "cloudflareai: credential is missing a secret value");
|
|
61
|
+
throw new GatewayError("invalid_request", 400, "cloudflareai: credential is missing a secret value (request {requestId}). Wrong key, right door — check the credential 🔑");
|
|
61
62
|
}
|
|
62
63
|
let envelope: ReturnType<typeof decodeCloudflareAiGatewayCredential>;
|
|
63
64
|
try {
|
|
@@ -66,7 +67,7 @@ function cloudflareEnvelope(context: ProviderDispatchContext): {
|
|
|
66
67
|
throw new GatewayError(
|
|
67
68
|
"invalid_request",
|
|
68
69
|
400,
|
|
69
|
-
`cloudflareai: ${error instanceof Error ? error.message : "stored credential is not a Cloudflare envelope"}
|
|
70
|
+
`cloudflareai: ${error instanceof Error ? error.message : "stored credential is not a Cloudflare envelope"} (request {requestId}). Wrong key, right door — check the credential 🔑`,
|
|
70
71
|
);
|
|
71
72
|
}
|
|
72
73
|
return { token: envelope.token, baseUrl: cloudflareBaseUrl(envelope.accountId, envelope.gatewayId) };
|
|
@@ -93,11 +94,7 @@ class CloudflareAiGatewayAdapter implements ProviderAdapter {
|
|
|
93
94
|
context: ProviderDispatchContext,
|
|
94
95
|
): AsyncIterable<CanonicalEvent> {
|
|
95
96
|
if (candidate.wire_family !== "messages") {
|
|
96
|
-
|
|
97
|
-
"capability_unsupported",
|
|
98
|
-
400,
|
|
99
|
-
`cloudflareai supports messages only, got ${candidate.wire_family}`,
|
|
100
|
-
);
|
|
97
|
+
assertWireFamily(candidate, "messages", "cloudflareai");
|
|
101
98
|
}
|
|
102
99
|
const { token, baseUrl } = cloudflareEnvelope(context);
|
|
103
100
|
const outbound = buildClaudeMessagesRequest({
|
|
@@ -167,7 +167,7 @@ export async function mapCodexErrorResponse(res: Response): Promise<never> {
|
|
|
167
167
|
throw new GatewayError(
|
|
168
168
|
classification.code,
|
|
169
169
|
classification.status,
|
|
170
|
-
friendlyMessage ?? sanitized
|
|
170
|
+
`${friendlyMessage ?? sanitized} (request {requestId}). The upstream came back empty-handed — retry 🌙`,
|
|
171
171
|
details,
|
|
172
172
|
classification.origin,
|
|
173
173
|
);
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* OpenAI-compatible factory's reach — stays bespoke, never re-audit.
|
|
23
23
|
*/
|
|
24
24
|
import type { CanonicalEvent, CanonicalRequest } from "../../../protocol/canonical-model";
|
|
25
|
-
import { GatewayError
|
|
25
|
+
import { GatewayError } from "../../../protocol/gateway-error";
|
|
26
26
|
import { getCodexVersion } from "../../operations/client-versions";
|
|
27
27
|
import { buildCodexUserAgent } from "../../operations/cli-platform";
|
|
28
28
|
import { randomUUID } from "node:crypto";
|
|
@@ -54,6 +54,7 @@ export function _setCodexRateLimitSleepForTesting(
|
|
|
54
54
|
function sleep(ms: number, signal: AbortSignal): Promise<void> {
|
|
55
55
|
return rateLimitSleep(ms, signal);
|
|
56
56
|
}
|
|
57
|
+
import { assertWireFamily } from "../../provider-contracts";
|
|
57
58
|
import type { ImageGenerationOutcome, ProviderDispatchTarget, ProviderAdapter, ProviderDispatchContext, ResolvedCredential, WebSearchOutcome, WebSearchResult } from "../../provider-contracts";
|
|
58
59
|
import type { FetchLike } from "../../quota/quota-contracts";
|
|
59
60
|
import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../../provider-sanitize";
|
|
@@ -199,7 +200,7 @@ export function assertCodexOAuthCredential(
|
|
|
199
200
|
throw new GatewayError(
|
|
200
201
|
"invalid_request",
|
|
201
202
|
400,
|
|
202
|
-
`codex: ChatGPT OAuth credential required (got credential_kind=${credential.credential_kind})
|
|
203
|
+
`codex: ChatGPT OAuth credential required (got credential_kind=${credential.credential_kind}) (request {requestId}). Wrong key, right door — check the credential 🔑`,
|
|
203
204
|
);
|
|
204
205
|
}
|
|
205
206
|
}
|
|
@@ -361,7 +362,7 @@ function authHeadersForCodex(
|
|
|
361
362
|
throw new GatewayError(
|
|
362
363
|
"invalid_request",
|
|
363
364
|
400,
|
|
364
|
-
"codex: OAuth credential is missing a bearer token",
|
|
365
|
+
"codex: OAuth credential is missing a bearer token (request {requestId}). Wrong key, right door — check the credential 🔑",
|
|
365
366
|
);
|
|
366
367
|
}
|
|
367
368
|
const token = new TextDecoder().decode(credential.secret);
|
|
@@ -748,7 +749,7 @@ export function createCodexAdapter(
|
|
|
748
749
|
context: ProviderDispatchContext,
|
|
749
750
|
): Promise<WebSearchOutcome> {
|
|
750
751
|
const query = typeof body.query === "string" ? body.query.trim() : "";
|
|
751
|
-
if (!query) throw new GatewayError("invalid_request", 400, "search query is required");
|
|
752
|
+
if (!query) throw new GatewayError("invalid_request", 400, "search query is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
752
753
|
const requested = typeof body.model === "string" ? body.model.trim() : "";
|
|
753
754
|
const model = requested.length > 0 && requested !== "codex" ? requested : CODEX_SEARCH_DEFAULT_MODEL;
|
|
754
755
|
const request: CanonicalRequest = {
|
|
@@ -779,7 +780,7 @@ export function createCodexAdapter(
|
|
|
779
780
|
}
|
|
780
781
|
const results = normalizeCodexSearchCitations(citations, answerText);
|
|
781
782
|
if (results.length === 0)
|
|
782
|
-
throw new GatewayError("platform_unavailable", 502, "Codex search returned no citations");
|
|
783
|
+
throw new GatewayError("platform_unavailable", 502, "Codex search returned no citations (request {requestId}). The upstream came back empty-handed — retry 🌙");
|
|
783
784
|
const rawMax = body.max_results;
|
|
784
785
|
const maxResults =
|
|
785
786
|
typeof rawMax === "number" && Number.isFinite(rawMax)
|
|
@@ -796,7 +797,7 @@ export function createCodexAdapter(
|
|
|
796
797
|
const prompt = imagePrompt(body);
|
|
797
798
|
const requested =
|
|
798
799
|
candidate.model_id.length > 0 ? candidate.model_id : typeof body.model === "string" ? body.model : "";
|
|
799
|
-
if (requested.length === 0) throw new GatewayError("invalid_request", 400, "model is required");
|
|
800
|
+
if (requested.length === 0) throw new GatewayError("invalid_request", 400, "model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
800
801
|
// A `-image` id is the chat model with the suffix removed. Dedicated
|
|
801
802
|
// image tools still need a chat carrier, and the account's visible 5.6
|
|
802
803
|
// models are the current ones.
|
|
@@ -868,7 +869,7 @@ export function createCodexAdapter(
|
|
|
868
869
|
try {
|
|
869
870
|
parsed = JSON.parse(data);
|
|
870
871
|
} catch {
|
|
871
|
-
throw new GatewayError("platform_unavailable", 502, "Codex image stream returned malformed JSON", {}, "upstream");
|
|
872
|
+
throw new GatewayError("platform_unavailable", 502, "Codex image stream returned malformed JSON (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream");
|
|
872
873
|
}
|
|
873
874
|
if (isRecord(parsed) && (parsed.type === "error" || parsed.type === "response.failed")) {
|
|
874
875
|
const message = isRecord(parsed.error) && typeof parsed.error.message === "string"
|
|
@@ -876,7 +877,7 @@ export function createCodexAdapter(
|
|
|
876
877
|
: isRecord(parsed.response) && isRecord(parsed.response.error) && typeof parsed.response.error.message === "string"
|
|
877
878
|
? parsed.response.error.message
|
|
878
879
|
: "Codex image generation failed";
|
|
879
|
-
throw new GatewayError("platform_unavailable", 502, message
|
|
880
|
+
throw new GatewayError("platform_unavailable", 502, `${message} (request {requestId}). The upstream came back empty-handed — retry 🌙`, {}, "upstream");
|
|
880
881
|
}
|
|
881
882
|
image = responsesImageResult(parsed) ?? image;
|
|
882
883
|
}
|
|
@@ -903,19 +904,17 @@ export function createCodexAdapter(
|
|
|
903
904
|
throw new GatewayError(
|
|
904
905
|
"invalid_request",
|
|
905
906
|
400,
|
|
906
|
-
"codex adapter received non-codex candidate",
|
|
907
|
+
"codex adapter received non-codex candidate (request {requestId}). Even we have bad days — check the registry wiring 🐻",
|
|
907
908
|
);
|
|
908
909
|
}
|
|
909
910
|
if (candidate.wire_family !== "responses") {
|
|
910
|
-
|
|
911
|
-
wire_family: candidate.wire_family,
|
|
912
|
-
});
|
|
911
|
+
assertWireFamily(candidate, "responses", "codex");
|
|
913
912
|
}
|
|
914
913
|
if (request.model.includes("?")) {
|
|
915
914
|
throw new GatewayError(
|
|
916
915
|
"invalid_request",
|
|
917
916
|
400,
|
|
918
|
-
"model must not contain query string",
|
|
917
|
+
"model must not contain query string (request {requestId}). Check the shape of what you sent — then resend 🪞",
|
|
919
918
|
);
|
|
920
919
|
}
|
|
921
920
|
|
|
@@ -1181,8 +1180,8 @@ export function createCodexAdapter(
|
|
|
1181
1180
|
"platform_unavailable",
|
|
1182
1181
|
502,
|
|
1183
1182
|
error instanceof Error
|
|
1184
|
-
? `Malformed SSE event: ${error.message}
|
|
1185
|
-
:
|
|
1183
|
+
? `Malformed SSE event: ${error.message} (request {requestId}). The upstream sent something we can't read — retry 🌙`
|
|
1184
|
+
: `Malformed SSE event (request {requestId}). The upstream sent something we can't read — retry 🌙`,
|
|
1186
1185
|
{},
|
|
1187
1186
|
"upstream",
|
|
1188
1187
|
);
|
|
@@ -527,7 +527,7 @@ export function transformLine(line: string, state: StreamState, seqBase: number)
|
|
|
527
527
|
const message =
|
|
528
528
|
extractUpstreamMessage(raw) ||
|
|
529
529
|
extractUpstreamMessage(event) ||
|
|
530
|
-
"Command Code stream error";
|
|
530
|
+
"Command Code stream error (request {requestId}). The upstream came back empty-handed — retry 🌙";
|
|
531
531
|
throw new GatewayError(
|
|
532
532
|
classification.code,
|
|
533
533
|
classification.status,
|
|
@@ -558,11 +558,11 @@ export async function* transformNdjson(body: ReadableStream<Uint8Array>, signal:
|
|
|
558
558
|
yield { type: "response_start", sequence_number: seq++, model: "commandcode" } as CanonicalEvent;
|
|
559
559
|
|
|
560
560
|
const readWithAbort = (): Promise<{ done: boolean; value?: Uint8Array }> => {
|
|
561
|
-
if (signal.aborted) throw new GatewayError("transport_closed", 499, "Command Code stream aborted");
|
|
561
|
+
if (signal.aborted) throw new GatewayError("transport_closed", 499, "Command Code stream aborted (request {requestId}). Send it again whenever ready 🙃");
|
|
562
562
|
const { promise, resolve, reject } = Promise.withResolvers<{ done: boolean; value?: Uint8Array }>() as unknown as { promise: Promise<{ done: boolean; value?: Uint8Array }>; resolve: (v: unknown) => void; reject: (e: unknown) => void };
|
|
563
563
|
const onAbort = (): void => {
|
|
564
|
-
if (signal.aborted) reject(new GatewayError("transport_closed", 499, "Command Code stream aborted"));
|
|
565
|
-
else reject(new GatewayError("platform_unavailable", 502, "Command Code stream error", {}, "upstream"));
|
|
564
|
+
if (signal.aborted) reject(new GatewayError("transport_closed", 499, "Command Code stream aborted (request {requestId}). Send it again whenever ready 🙃"));
|
|
565
|
+
else reject(new GatewayError("platform_unavailable", 502, "Command Code stream error (request {requestId}). The upstream came back empty-handed — retry 🌙", {}, "upstream"));
|
|
566
566
|
};
|
|
567
567
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
568
568
|
void reader.read().then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
@@ -72,7 +72,11 @@ function creditWindow(credits: Record<string, unknown>): ProviderQuotaWindow | n
|
|
|
72
72
|
return {
|
|
73
73
|
kind: "credits",
|
|
74
74
|
label: "Credits",
|
|
75
|
-
|
|
75
|
+
// These are credits in one unit that can be spent interchangeably, so
|
|
76
|
+
// they are pooled like Qoder's plan/granted balances — not independent
|
|
77
|
+
// rate-limit lanes. The account-row pill and the Quota page both sum
|
|
78
|
+
// pooled windows, so this must be `pooled` or the balance never renders.
|
|
79
|
+
accounting: "pooled",
|
|
76
80
|
usedPercent: null,
|
|
77
81
|
remainingPercent: null,
|
|
78
82
|
resetsAt: null,
|
|
@@ -46,7 +46,7 @@ function connectErrorEnvelope(payload: Uint8Array): GatewayError | undefined {
|
|
|
46
46
|
return new GatewayError(
|
|
47
47
|
"quota_exceeded",
|
|
48
48
|
429,
|
|
49
|
-
`Cursor refused the Run: ${detail}
|
|
49
|
+
`Cursor refused the Run: ${detail} (request {requestId}). You've maxed this window — pace yourself ⏳`,
|
|
50
50
|
{ providerId: "cursor", upstreamCode: code },
|
|
51
51
|
"upstream",
|
|
52
52
|
);
|
|
@@ -54,7 +54,7 @@ function connectErrorEnvelope(payload: Uint8Array): GatewayError | undefined {
|
|
|
54
54
|
return new GatewayError(
|
|
55
55
|
"platform_unavailable",
|
|
56
56
|
502,
|
|
57
|
-
`Cursor refused the Run: ${detail}
|
|
57
|
+
`Cursor refused the Run: ${detail} (request {requestId}). The upstream came back empty-handed — retry 🌙`,
|
|
58
58
|
{ providerId: "cursor", upstreamCode: code },
|
|
59
59
|
"upstream",
|
|
60
60
|
);
|
|
@@ -126,7 +126,7 @@ export async function openCursorRun(input: {
|
|
|
126
126
|
throw new GatewayError(
|
|
127
127
|
"invalid_request",
|
|
128
128
|
400,
|
|
129
|
-
"Cursor Run requires an allowlisted Cursor agent origin",
|
|
129
|
+
"Cursor Run requires an allowlisted Cursor agent origin (request {requestId}). All roads blocked — time to find a new route 🗺️",
|
|
130
130
|
{ origin: input.origin },
|
|
131
131
|
);
|
|
132
132
|
}
|
|
@@ -153,7 +153,7 @@ function grpcError(status: string, message: string | undefined): GatewayError {
|
|
|
153
153
|
return new GatewayError(
|
|
154
154
|
"authentication_failed",
|
|
155
155
|
401,
|
|
156
|
-
`Cursor refused the credential${detail}
|
|
156
|
+
`Cursor refused the credential${detail} (request {requestId}). Wrong key, right door — check the credential 🔑`,
|
|
157
157
|
{ grpcStatus: status },
|
|
158
158
|
"upstream",
|
|
159
159
|
);
|
|
@@ -162,7 +162,7 @@ function grpcError(status: string, message: string | undefined): GatewayError {
|
|
|
162
162
|
return new GatewayError(
|
|
163
163
|
"quota_exceeded",
|
|
164
164
|
429,
|
|
165
|
-
`Cursor refused the Run${detail}
|
|
165
|
+
`Cursor refused the Run${detail} (request {requestId}). You've maxed this window — pace yourself ⏳`,
|
|
166
166
|
{ grpcStatus: status },
|
|
167
167
|
"upstream",
|
|
168
168
|
);
|
|
@@ -171,7 +171,7 @@ function grpcError(status: string, message: string | undefined): GatewayError {
|
|
|
171
171
|
return new GatewayError(
|
|
172
172
|
"deadline_exceeded",
|
|
173
173
|
504,
|
|
174
|
-
`Cursor Run ended before it finished${detail}
|
|
174
|
+
`Cursor Run ended before it finished${detail} (request {requestId}). Some things just take longer 🐢`,
|
|
175
175
|
{ grpcStatus: status },
|
|
176
176
|
"upstream",
|
|
177
177
|
);
|
|
@@ -179,7 +179,7 @@ function grpcError(status: string, message: string | undefined): GatewayError {
|
|
|
179
179
|
return new GatewayError(
|
|
180
180
|
"platform_unavailable",
|
|
181
181
|
502,
|
|
182
|
-
`Cursor Run failed (gRPC ${status})${detail}
|
|
182
|
+
`Cursor Run failed (gRPC ${status})${detail} (request {requestId}). The upstream came back empty-handed — retry 🌙`,
|
|
183
183
|
{ grpcStatus: status },
|
|
184
184
|
"upstream",
|
|
185
185
|
);
|
|
@@ -205,7 +205,7 @@ export function cursorRunTerminationError(input: {
|
|
|
205
205
|
: new GatewayError(
|
|
206
206
|
"transport_unavailable",
|
|
207
207
|
502,
|
|
208
|
-
`Cursor Run transport interrupted: ${input.reason.error.message}
|
|
208
|
+
`Cursor Run transport interrupted: ${input.reason.error.message} (request {requestId}). The connection ghosted us — come back in a moment 👻`,
|
|
209
209
|
{},
|
|
210
210
|
"network",
|
|
211
211
|
);
|
|
@@ -216,7 +216,7 @@ export function cursorRunTerminationError(input: {
|
|
|
216
216
|
return new GatewayError(
|
|
217
217
|
status === 401 || status === 403 ? "authentication_failed" : "platform_unavailable",
|
|
218
218
|
status === 401 || status === 403 ? 401 : 502,
|
|
219
|
-
`Cursor Run failed by remote: ${status}
|
|
219
|
+
`Cursor Run failed by remote: ${status} (request {requestId}). The upstream came back empty-handed — retry 🌙`,
|
|
220
220
|
{ httpStatus: status, ...(message === undefined ? {} : { upstreamMessage: message }) },
|
|
221
221
|
"upstream",
|
|
222
222
|
);
|
|
@@ -229,7 +229,7 @@ export function cursorRunTerminationError(input: {
|
|
|
229
229
|
return new GatewayError(
|
|
230
230
|
"platform_unavailable",
|
|
231
231
|
502,
|
|
232
|
-
"Cursor Run ended before turn_ended",
|
|
232
|
+
"Cursor Run ended before turn_ended (request {requestId}). The upstream came back empty-handed — retry 🌙",
|
|
233
233
|
{},
|
|
234
234
|
"upstream",
|
|
235
235
|
);
|
|
@@ -253,7 +253,7 @@ export async function* decodeServerMessages(
|
|
|
253
253
|
throw new GatewayError(
|
|
254
254
|
"platform_unavailable",
|
|
255
255
|
502,
|
|
256
|
-
"Cursor Run exceeded the frame buffer bound",
|
|
256
|
+
"Cursor Run exceeded the frame buffer bound (request {requestId}). The upstream sent more than we can hold — retry 🌙",
|
|
257
257
|
{},
|
|
258
258
|
"upstream",
|
|
259
259
|
);
|