cartethyia 2.5.4 → 2.5.6
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 +13 -4
- package/README.md +2 -2
- package/dist/dashboard/assets/{BannedPage-C2orBsI2.js → BannedPage-CADDq4IU.js} +1 -1
- package/dist/dashboard/assets/BannedPage-CADDq4IU.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-_z1hID7E.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-_z1hID7E.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BV6pxVQo.js → CliToolsPage-DuO1Z7dq.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-DuO1Z7dq.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DNEPi3xU.js +1 -0
- package/dist/dashboard/assets/CombosPage-DNEPi3xU.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-CW-wPmJ6.js → ConsoleLogPage-BVdpfiz1.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-BVdpfiz1.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-0p8uX7vB.js → CustomizationPage-BR5HHvbi.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-BR5HHvbi.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-BjqSMfko.js → HealthEventsModal-mUfcknqm.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-mUfcknqm.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-BvzCx8Kr.js → LoginPage-V5faV9V2.js} +1 -1
- package/dist/dashboard/assets/LoginPage-V5faV9V2.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js +1 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-BDu20Jdx.js +1 -0
- package/dist/dashboard/assets/OverviewPage-BDu20Jdx.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-Dllr_aFO.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-Dllr_aFO.js.gz +0 -0
- package/dist/dashboard/assets/{ProvidersPage-Js9jUPSb.js → ProvidersPage-uPiGVTTK.js} +1 -1
- package/dist/dashboard/assets/ProvidersPage-uPiGVTTK.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BaUkO-4O.js +7 -0
- package/dist/dashboard/assets/ProxyPage-BaUkO-4O.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-o0IFAsFb.js +1 -0
- package/dist/dashboard/assets/QuotaPage-o0IFAsFb.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CYWqbXjp.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CYWqbXjp.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-DDbMQsoo.js → SetupPage-UB690SE2.js} +1 -1
- package/dist/dashboard/assets/SetupPage-UB690SE2.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-CB3Z7VTf.js → SortableList-BLujdX7N.js} +1 -1
- package/dist/dashboard/assets/SortableList-BLujdX7N.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-D95UCPHI.js → StudioPage-D5C2raAc.js} +3 -3
- package/dist/dashboard/assets/StudioPage-D5C2raAc.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-8uIcxa1W.js +56 -0
- package/dist/dashboard/assets/UsagePage-8uIcxa1W.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-DQYLQxpW.js +1 -0
- package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
- package/dist/dashboard/assets/app-CX_Z8cMs.css +2 -0
- package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
- package/dist/dashboard/assets/{assert-Chi7pCnt.js → assert-C9FD_JwJ.js} +1 -1
- package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D4pQapKj.js → badge-CR72dasT.js} +1 -1
- package/dist/dashboard/assets/badge-CR72dasT.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DH6cg-_B.js → banner-CI9_eSfO.js} +1 -1
- package/dist/dashboard/assets/banner-CI9_eSfO.js.gz +0 -0
- package/dist/dashboard/assets/{card-BKqlUOe4.js → card-DS7CQEsO.js} +1 -1
- package/dist/dashboard/assets/card-DS7CQEsO.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-fTgljTGA.js → cli-tools-CNqzrfdb.js} +1 -1
- package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-D5Ys_sM0.js → clipboard-button-611pSsaX.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-611pSsaX.js.gz +0 -0
- package/dist/dashboard/assets/{fingerprint-pattern-BWuHtbW4.js → concurrency-BDF0ok7y.js} +1 -1
- package/dist/dashboard/assets/concurrency-BDF0ok7y.js.gz +0 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js +1 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js +1 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CQBr6U9c.js → entry-B9Xvtnfj.js} +1 -1
- package/dist/dashboard/assets/entry-B9Xvtnfj.js.gz +0 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js +1 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js.gz +0 -0
- package/dist/dashboard/assets/entry-DxBHnauy.js +4 -0
- package/dist/dashboard/assets/entry-DxBHnauy.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-BlptL8Uf.js → github-badge-sltk1qUi.js} +1 -1
- package/dist/dashboard/assets/github-badge-sltk1qUi.js.gz +0 -0
- package/dist/dashboard/assets/{index-js6TJvdr.js → index-CmxZr14F.js} +2 -2
- package/dist/dashboard/assets/index-CmxZr14F.js.gz +0 -0
- package/dist/dashboard/assets/{inline-DUWDSmDV.js → inline-BhY2sSnO.js} +1 -1
- package/dist/dashboard/assets/inline-BhY2sSnO.js.gz +0 -0
- package/dist/dashboard/assets/{input-LVjgZq4f.js → input-V1umFiBk.js} +1 -1
- package/dist/dashboard/assets/input-V1umFiBk.js.gz +0 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js +1 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-DupvLfDx.js → list-row-1zzZYM0B.js} +1 -1
- package/dist/dashboard/assets/list-row-1zzZYM0B.js.gz +0 -0
- package/dist/dashboard/assets/{live-C4pEJUqI.js → live-BivGfuUs.js} +1 -1
- package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
- package/dist/dashboard/assets/{model-bans-BRiuufkB.js → model-bans-CmffjLuG.js} +1 -1
- package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-B4ROwk8L.js → mutation-46P0oWMe.js} +1 -1
- package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js +2 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-gmjzC3RS.js → query-keys-BFhGpwR1.js} +1 -1
- package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
- package/dist/dashboard/assets/{routing-C7tBT5o-.js → routing-CAb4F37R.js} +1 -1
- package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
- package/dist/dashboard/assets/{select-WUCXorXw.js → select-BYR_5K2c.js} +1 -1
- package/dist/dashboard/assets/select-BYR_5K2c.js.gz +0 -0
- package/dist/dashboard/assets/{settings-C_zKl1GS.js → settings-DNX9sydi.js} +1 -1
- package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
- package/dist/dashboard/assets/{stack-_3O0F8Xn.js → stack-BHTfXdz_.js} +1 -1
- package/dist/dashboard/assets/stack-BHTfXdz_.js.gz +0 -0
- package/dist/dashboard/assets/{state-BgTxHcJS.js → state-mPDRlQkl.js} +1 -1
- package/dist/dashboard/assets/state-mPDRlQkl.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DEjTtOWf.js → switch-DOmJxg7H.js} +1 -1
- package/dist/dashboard/assets/switch-DOmJxg7H.js.gz +0 -0
- package/dist/dashboard/assets/tokens-COzario9.js +1 -0
- package/dist/dashboard/assets/tokens-COzario9.js.gz +0 -0
- package/dist/dashboard/assets/use-modal-focus-By7oJoGd.js +1 -0
- package/dist/dashboard/assets/use-modal-focus-By7oJoGd.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BWSC0UAS.js → useMutation-Dem0lXQj.js} +1 -1
- package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +54 -54
- package/migrations/README.md +52 -52
- package/migrations/lite-sqlite3/0000_baseline.sql +2 -2
- package/package.json +96 -95
- package/scripts/cli/admin.ts +125 -0
- package/scripts/cli/{ui/background.ts → background.ts} +1 -1
- package/scripts/cli/{command/console-menu.ts → console-menu.ts} +275 -244
- package/scripts/cli/doctor.ts +37 -0
- package/scripts/cli/{support/env.ts → env.ts} +99 -99
- package/scripts/cli/{gateway/spawn.ts → gateway.ts} +112 -24
- package/scripts/cli/instance.ts +224 -0
- package/scripts/cli/main.ts +61 -18
- package/scripts/cli/{support/platform.ts → platform.ts} +64 -64
- package/scripts/cli/port.ts +100 -0
- package/scripts/cli/{support/services.ts → services.ts} +88 -88
- package/scripts/cli/{command/setup.ts → setup.ts} +35 -34
- package/scripts/cli/{command/start.ts → start.ts} +10 -5
- package/scripts/cli/{support/startup-signal.ts → startup-signal.ts} +23 -23
- package/scripts/cli/tray/index.ts +62 -12
- package/scripts/cli/{command/tray.ts → tray.ts} +208 -208
- package/scripts/cli/{command/update.ts → update.ts} +39 -39
- package/scripts/cli/version.ts +67 -0
- package/scripts/cli/{ui/wordmark.ts → wordmark.ts} +58 -58
- package/src/boot/app.ts +697 -693
- package/src/boot/dependencies.ts +647 -646
- package/src/boot/timeout.ts +2 -13
- package/src/config/cooldowns.ts +186 -138
- package/src/config/network.ts +8 -14
- package/src/config/providers.ts +7 -10
- package/src/config/runtime.ts +76 -76
- package/src/config/security.ts +15 -0
- package/src/config/spec.ts +20 -30
- package/src/config/telemetry.ts +0 -20
- package/src/config/timeouts.ts +0 -6
- package/src/console/admin/model-abuse/contracts.ts +28 -6
- package/src/console/admin/model-abuse/routes.ts +56 -3
- package/src/console/api-keys/contracts.ts +410 -414
- package/src/console/api-keys/routes.ts +881 -880
- package/src/console/auth/credentials.ts +3 -3
- package/src/console/auth/setup-service.ts +2 -2
- package/src/console/backup/export-endpoint.ts +6 -2
- package/src/console/backup/nine-router.ts +2 -5
- package/src/console/backup/service.ts +4 -0
- package/src/console/backup/store.ts +192 -29
- package/src/console/backup/validate.ts +3 -45
- package/src/console/cli-tools/fs-ops.ts +487 -487
- package/src/console/console-router-guards.ts +1 -1
- package/src/console/data-management/contracts.ts +13 -6
- package/src/console/data-management/operations.ts +23 -18
- package/src/console/data-management/routes.ts +0 -1
- package/src/console/domain-registration.ts +10 -5
- package/src/console/observability/live.ts +22 -0
- package/src/console/observability/store.ts +39 -16
- package/src/console/observability/usage-dimensions.ts +4 -4
- package/src/console/providers/catalog/catalog-projections.ts +6 -7
- package/src/console/providers/catalog/model-operations.ts +5 -2
- package/src/console/providers/catalog/provider-operations.ts +4 -4
- package/src/console/providers/catalog/public-model-store.ts +8 -11
- package/src/console/providers/catalog/store.ts +1553 -1553
- package/src/console/providers/oauth/routes.ts +8 -12
- package/src/console/quota/account-quota-tenant.ts +6 -6
- package/src/console/quota/quota-view.ts +1 -1
- package/src/console/remote-support/contracts.ts +61 -0
- package/src/console/remote-support/routes.ts +65 -0
- package/src/console/remote-support/service.ts +207 -0
- package/src/console/response-compression.ts +0 -3
- package/src/console/routing/pools/probe-result.ts +3 -2
- package/src/console/routing/pools/probe-verdict.ts +132 -132
- package/src/console/routing/pools/store.ts +8 -8
- package/src/console/settings/contracts.ts +58 -2
- package/src/console/settings/store.ts +30 -3
- package/src/console/shared/cursor.ts +8 -8
- package/src/console/shared/errors.ts +1 -3
- package/src/network/http2-bidi.ts +2 -4
- package/src/network/pool/agent.ts +478 -478
- package/src/network/pool/selector.ts +5 -4
- package/src/network/retry.ts +1 -2
- package/src/network/ssrf.ts +5 -4
- package/src/observability/event-compaction.ts +80 -78
- package/src/observability/event-day-index.ts +13 -15
- package/src/observability/event-log.ts +4 -4
- package/src/observability/logger.ts +6 -6
- package/src/observability/payload-capture.ts +151 -33
- package/src/observability/payload-store.ts +397 -440
- package/src/observability/redaction.ts +5 -6
- package/src/observability/request-notify.ts +43 -0
- package/src/observability/telemetry-status.ts +8 -9
- package/src/observability/token-speed.ts +5 -4
- package/src/persistence/db-mode.ts +7 -7
- package/src/persistence/readiness.ts +1 -1
- package/src/persistence/schema.ts +1406 -1402
- package/src/persistence/shared-cache.ts +1 -2
- package/src/persistence/stores/api-key-store.ts +18 -6
- package/src/persistence/stores/share-store.ts +4 -3
- package/src/persistence/stores/telemetry-store.ts +236 -237
- package/src/protocol/canonical-model.ts +11 -3
- package/src/protocol/codecs.ts +138 -4
- package/src/protocol/gateway-error.ts +6 -4
- package/src/protocol/request/chat.ts +21 -1
- package/src/protocol/request/codex.ts +10 -1
- package/src/protocol/request/messages.ts +4 -5
- package/src/protocol/request/responses.ts +9 -1
- package/src/protocol/response/chat.ts +34 -4
- package/src/protocol/response/codex.ts +7 -4
- package/src/protocol/response/dsml.ts +140 -28
- package/src/protocol/response/responses.ts +11 -5
- package/src/protocol/stream-error-frames.ts +4 -5
- package/src/providers/authentication/jwt-validator.ts +9 -10
- package/src/providers/authentication/oauth-refresh-service.ts +9 -11
- package/src/providers/configured-openai-providers.ts +134 -136
- package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
- package/src/providers/discovery/catalog/catalog-format.ts +3 -6
- package/src/providers/discovery/models-dev-catalog.ts +354 -354
- package/src/providers/discovery/probe-phases.ts +4 -4
- package/src/providers/discovery/probe-wire.ts +6 -13
- package/src/providers/discovery/probing-service.ts +1117 -1045
- package/src/providers/integrations/alibabacp/alibabacp.ts +1 -1
- package/src/providers/integrations/antigravity/antigravity-quota.ts +5 -7
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +23 -2
- package/src/providers/integrations/buddy/buddy-checkin.ts +1 -4
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +23 -6
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +0 -1
- package/src/providers/integrations/buddy/buddy-identity.ts +52 -0
- package/src/providers/integrations/buddy/buddy-media.ts +2 -2
- package/src/providers/integrations/buddy/buddy-usage-store.ts +3 -4
- package/src/providers/integrations/buddy/codebuddy/quota.ts +2 -13
- package/src/providers/integrations/buddy/codebuddy/shared.ts +118 -115
- package/src/providers/integrations/buddy/workbuddy/quota.ts +0 -11
- package/src/providers/integrations/buddy/workbuddy/shared.ts +5 -2
- package/src/providers/integrations/claude/claude.ts +608 -608
- package/src/providers/integrations/cline/cline-quota.ts +132 -132
- package/src/providers/integrations/cline/cline.ts +537 -539
- package/src/providers/integrations/codex/codex-oauth.ts +1 -1
- package/src/providers/integrations/commandcode/commandcode.ts +674 -675
- package/src/providers/integrations/commandcode/discovery.ts +117 -116
- package/src/providers/integrations/cursor/cursor-auth.ts +418 -418
- package/src/providers/integrations/cursor/cursor-quota.ts +309 -310
- package/src/providers/integrations/cursor/cursor.ts +11 -163
- package/src/providers/integrations/factory/factory-models.ts +3 -5
- package/src/providers/integrations/grok/grok-install-id.ts +2 -3
- package/src/providers/integrations/grok/grok.ts +6 -7
- package/src/providers/integrations/hermes.ts +14 -18
- package/src/providers/integrations/kiro/kiro-discovery.ts +1 -1
- package/src/providers/integrations/kiro/kiro.ts +1 -1
- package/src/providers/integrations/mistral.ts +6 -6
- package/src/providers/integrations/opencode/fingerprint.ts +3 -3
- package/src/providers/integrations/opencode/provider.ts +8 -8
- package/src/providers/integrations/qoder/qoder-catalog.ts +450 -450
- package/src/providers/integrations/qoder/qoder-oauth.ts +388 -310
- package/src/providers/integrations/qoder/qoder.ts +884 -865
- package/src/providers/integrations/shared/connect.ts +6 -6
- package/src/providers/integrations/trae/trae-catalog.ts +1 -2
- package/src/providers/integrations/trae/trae.ts +2 -2
- package/src/providers/integrations/zcode/oauth.ts +6 -1
- package/src/providers/operations/account-health-service.ts +1528 -1523
- package/src/providers/operations/account-reset-service.ts +1 -1
- package/src/providers/operations/client-versions.ts +6 -6
- package/src/providers/operations/custom-cli-headers.ts +3 -4
- package/src/providers/operations/provider-catalog-seeder.ts +95 -95
- package/src/providers/operations/provider-catalog-service.ts +3 -4
- package/src/providers/provider-metadata.ts +4 -8
- package/src/providers/provider-registry.ts +6 -7
- package/src/providers/provider-usage.ts +1 -1
- package/src/security/abuse.ts +15 -10
- package/src/security/access-control.ts +144 -146
- package/src/security/admission/contracts.ts +11 -0
- package/src/security/admission/in-memory-store.ts +4 -3
- package/src/security/admission/lease-sweep.ts +6 -6
- package/src/security/admission/reasons.ts +5 -1
- package/src/security/admission/redis-store.ts +211 -210
- package/src/security/admission/service.ts +4 -0
- package/src/security/api-key-auth.ts +504 -504
- package/src/security/ip-boundary.ts +155 -15
- package/src/security/model-abuse.ts +366 -94
- package/src/security/outbound-headers.ts +3 -4
- package/src/shared/sleep.ts +4 -0
- package/src/transport/dispatch/attempt-finalize.ts +47 -5
- package/src/transport/dispatch/attempt-loop.ts +531 -530
- package/src/transport/dispatch/stream-bridge.ts +1 -3
- package/src/transport/dispatch/streaming/finalize.ts +1 -1
- package/src/transport/dispatch/streaming/stream.ts +5 -6
- package/src/transport/failure-policy.ts +162 -8
- package/src/transport/guards/auth-guard.ts +7 -4
- package/src/transport/guards/concurrency-guard.ts +0 -5
- package/src/transport/guards/error-lifecycle.ts +13 -6
- package/src/transport/guards/pipeline.ts +15 -3
- package/src/transport/guards/request-context.ts +8 -2
- package/src/transport/request/inflight.ts +5 -6
- package/src/transport/request/preparer.ts +2 -2
- package/src/transport/request/state.ts +12 -8
- package/src/transport/routing/admission.ts +4 -0
- package/src/transport/routing/route-catalog.ts +8 -1
- package/src/transport/routing/route-model.ts +46 -14
- package/src/transport/routing/router.ts +21 -14
- package/src/transport/surface/completion.ts +2 -3
- package/src/transport/surface/dialects.ts +5 -6
- package/src/transport/surface/responses/encode.ts +38 -0
- package/src/transport/surface/responses/parse.ts +4 -0
- package/src/transport/translation/capabilities.ts +2 -3
- package/src/transport/translation/quirks.ts +3 -3
- package/src/workers/buddy-growth-tasks.ts +5 -10
- package/src/workers/daily-checkin.ts +17 -23
- package/src/workers/quota-refresh-sweep.ts +26 -26
- package/dist/dashboard/assets/BannedPage-C2orBsI2.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-BV6pxVQo.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-Bsan4679.js +0 -1
- package/dist/dashboard/assets/CombosPage-Bsan4679.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-CW-wPmJ6.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-0p8uX7vB.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-BvzCx8Kr.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js +0 -1
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js +0 -1
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js +0 -7
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js +0 -1
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-DDbMQsoo.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-CB3Z7VTf.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-D95UCPHI.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js +0 -56
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js +0 -1
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js.gz +0 -0
- package/dist/dashboard/assets/app-COlK95oi.css +0 -2
- package/dist/dashboard/assets/app-COlK95oi.css.gz +0 -0
- package/dist/dashboard/assets/assert-Chi7pCnt.js.gz +0 -0
- package/dist/dashboard/assets/badge-D4pQapKj.js.gz +0 -0
- package/dist/dashboard/assets/banner-DH6cg-_B.js.gz +0 -0
- package/dist/dashboard/assets/card-BKqlUOe4.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-fTgljTGA.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-D5Ys_sM0.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BYj-8WuK.js +0 -1
- package/dist/dashboard/assets/dialog-BYj-8WuK.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js +0 -1
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js.gz +0 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js +0 -1
- package/dist/dashboard/assets/entry-CBg5zeu8.js.gz +0 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js.gz +0 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js +0 -4
- package/dist/dashboard/assets/entry-CgdSAzEV.js.gz +0 -0
- package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-BlptL8Uf.js.gz +0 -0
- package/dist/dashboard/assets/index-js6TJvdr.js.gz +0 -0
- package/dist/dashboard/assets/inline-DUWDSmDV.js.gz +0 -0
- package/dist/dashboard/assets/input-LVjgZq4f.js.gz +0 -0
- package/dist/dashboard/assets/layout-CPfxpsfy.js +0 -1
- package/dist/dashboard/assets/layout-CPfxpsfy.js.gz +0 -0
- package/dist/dashboard/assets/list-row-DupvLfDx.js.gz +0 -0
- package/dist/dashboard/assets/live-C4pEJUqI.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js.gz +0 -0
- package/dist/dashboard/assets/mutation-B4ROwk8L.js.gz +0 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js +0 -2
- package/dist/dashboard/assets/numbers-YNcHvRY7.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-gmjzC3RS.js.gz +0 -0
- package/dist/dashboard/assets/routing-C7tBT5o-.js.gz +0 -0
- package/dist/dashboard/assets/select-WUCXorXw.js.gz +0 -0
- package/dist/dashboard/assets/settings-C_zKl1GS.js.gz +0 -0
- package/dist/dashboard/assets/stack-_3O0F8Xn.js.gz +0 -0
- package/dist/dashboard/assets/state-BgTxHcJS.js.gz +0 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js.gz +0 -0
- package/dist/dashboard/assets/tokens-DDxMbSRL.js +0 -1
- package/dist/dashboard/assets/tokens-DDxMbSRL.js.gz +0 -0
- package/dist/dashboard/assets/use-presence-BSZEBx7U.js +0 -1
- package/dist/dashboard/assets/use-presence-BSZEBx7U.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BWSC0UAS.js.gz +0 -0
- package/scripts/cli/command/admin.ts +0 -65
- package/scripts/cli/command/doctor.ts +0 -257
- package/scripts/cli/gateway/drain-token.ts +0 -78
- package/scripts/cli/gateway/instance-lock.ts +0 -105
- package/scripts/cli/gateway/stop.ts +0 -51
- package/scripts/cli/support/bun.ts +0 -27
- package/scripts/cli/support/version.ts +0 -37
- /package/dist/dashboard/assets/{app-DCQZRmHY.js → app-BIt446yE.js} +0 -0
- /package/dist/dashboard/assets/{app-DCQZRmHY.js.gz → app-BIt446yE.js.gz} +0 -0
- /package/scripts/cli/{ui/prompt.ts → prompt.ts} +0 -0
package/src/boot/timeout.ts
CHANGED
|
@@ -24,19 +24,8 @@ export function withTimeout<T>(
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*/
|
|
30
|
-
export function timeoutAfter(ms: number, message: string): Promise<never> {
|
|
31
|
-
return new Promise<never>((_, reject) => {
|
|
32
|
-
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
33
|
-
if (typeof timer.unref === "function") timer.unref();
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Cancellable variant of {@link timeoutAfter}: the loser timer is cleared
|
|
39
|
-
* when the raced operation wins, instead of firing later against nothing.
|
|
27
|
+
* The loser timer is cleared when the raced operation wins, instead of firing
|
|
28
|
+
* later against nothing.
|
|
40
29
|
*/
|
|
41
30
|
export function cancellableTimeout(ms: number, message: string): { promise: Promise<never>; cancel: () => void } {
|
|
42
31
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
package/src/config/cooldowns.ts
CHANGED
|
@@ -1,138 +1,186 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Account/pool health cooldown fallback resolvers.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { CONFIG_SPEC, readInt } from "./spec";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
CONFIG_SPEC.
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
*/
|
|
86
|
-
export function
|
|
87
|
-
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* `
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Account/pool health cooldown fallback resolvers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CONFIG_SPEC, readInt } from "./spec";
|
|
6
|
+
|
|
7
|
+
let _rateLimitCooldown: number | undefined;
|
|
8
|
+
/** Fallback cooldown for a provider rate limit (default 15m). */
|
|
9
|
+
export function resolveAccountRateLimitCooldownMs(): number {
|
|
10
|
+
if (_rateLimitCooldown === undefined)
|
|
11
|
+
_rateLimitCooldown = readInt(
|
|
12
|
+
"CARTETHYIA_ACCOUNT_RATE_LIMIT_COOLDOWN_MS",
|
|
13
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_RATE_LIMIT_COOLDOWN_MS,
|
|
14
|
+
);
|
|
15
|
+
return _rateLimitCooldown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let _quotaCooldown: number | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Fallback cooldown for provider quota exhaustion when the error states no
|
|
21
|
+
* reset window (default 1h). A provider-specific rule (xAI Grok Build's
|
|
22
|
+
* rolling 24-hour free-tier window) overrides it inside the classifier.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveAccountQuotaCooldownMs(): number {
|
|
25
|
+
if (_quotaCooldown === undefined)
|
|
26
|
+
_quotaCooldown = readInt(
|
|
27
|
+
"CARTETHYIA_ACCOUNT_QUOTA_COOLDOWN_MS",
|
|
28
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_QUOTA_COOLDOWN_MS,
|
|
29
|
+
);
|
|
30
|
+
return _quotaCooldown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let _modelCapacityCooldown: number | undefined;
|
|
34
|
+
/** Fallback cooldown for model-capacity overload (default 2m). */
|
|
35
|
+
export function resolveAccountModelCapacityCooldownMs(): number {
|
|
36
|
+
if (_modelCapacityCooldown === undefined)
|
|
37
|
+
_modelCapacityCooldown = readInt(
|
|
38
|
+
"CARTETHYIA_ACCOUNT_MODEL_CAPACITY_COOLDOWN_MS",
|
|
39
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_MODEL_CAPACITY_COOLDOWN_MS,
|
|
40
|
+
);
|
|
41
|
+
return _modelCapacityCooldown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let _transientCooldown: number | undefined;
|
|
45
|
+
/** Backoff for a transient 5xx/network fault, recorded as `cooldown` (default 30s). */
|
|
46
|
+
export function resolveAccountTransientCooldownMs(): number {
|
|
47
|
+
if (_transientCooldown === undefined)
|
|
48
|
+
_transientCooldown = readInt(
|
|
49
|
+
"CARTETHYIA_ACCOUNT_TRANSIENT_COOLDOWN_MS",
|
|
50
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_TRANSIENT_COOLDOWN_MS,
|
|
51
|
+
);
|
|
52
|
+
return _transientCooldown;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let _unclassifiedCooldown: number | undefined;
|
|
56
|
+
/** Backoff for a failure no rule matched, recorded as `cooldown` (default 1m). */
|
|
57
|
+
export function resolveAccountUnclassifiedCooldownMs(): number {
|
|
58
|
+
if (_unclassifiedCooldown === undefined)
|
|
59
|
+
_unclassifiedCooldown = readInt(
|
|
60
|
+
"CARTETHYIA_ACCOUNT_UNCLASSIFIED_COOLDOWN_MS",
|
|
61
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_UNCLASSIFIED_COOLDOWN_MS,
|
|
62
|
+
);
|
|
63
|
+
return _unclassifiedCooldown;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Ceiling an escalated fallback cooldown may reach (default 1h).
|
|
68
|
+
*
|
|
69
|
+
* A fallback duration is one the provider never stated, so escalating it is our
|
|
70
|
+
* own estimate. The cap keeps that estimate from outliving a short transient
|
|
71
|
+
* window: an account that recovers on its own must not sit parked for a day
|
|
72
|
+
* because a burst of 5xx happened to arrive while it was already cooling.
|
|
73
|
+
*/
|
|
74
|
+
let _escalationMaxCooldown: number | undefined;
|
|
75
|
+
export function resolveAccountCooldownEscalationMaxMs(): number {
|
|
76
|
+
if (_escalationMaxCooldown === undefined)
|
|
77
|
+
_escalationMaxCooldown = readInt(
|
|
78
|
+
"CARTETHYIA_ACCOUNT_COOLDOWN_ESCALATION_MAX_MS",
|
|
79
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_COOLDOWN_ESCALATION_MAX_MS,
|
|
80
|
+
);
|
|
81
|
+
return _escalationMaxCooldown;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let _poolCooldown: number | undefined;
|
|
85
|
+
/** How long a proxy pool stays `cooldown` after a transport fault (default 2m). */
|
|
86
|
+
export function resolvePoolCooldownMs(): number {
|
|
87
|
+
if (_poolCooldown === undefined)
|
|
88
|
+
_poolCooldown = readInt("CARTETHYIA_POOL_COOLDOWN_MS", CONFIG_SPEC.CARTETHYIA_POOL_COOLDOWN_MS);
|
|
89
|
+
return _poolCooldown;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let _authRejectedCooldown: number | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Backoff for an auth rejection that names no revocation (default 5m).
|
|
95
|
+
*
|
|
96
|
+
* A bare `401`/`403` is weak evidence: it covers clock skew, a key rotated
|
|
97
|
+
* upstream a moment ago, an edge cache, and a load balancer that answers before
|
|
98
|
+
* the credential is loaded. None of those is the credential's death, and
|
|
99
|
+
* `disabled` is the one state no sweep recovers — the account would leave
|
|
100
|
+
* rotation until an operator noticed. A cooldown costs the same
|
|
101
|
+
* requests for five minutes and comes back on its own.
|
|
102
|
+
*
|
|
103
|
+
* Only a *named* revocation (`token revoked`, `invalidated oauth token`) still
|
|
104
|
+
* parks the account: the upstream stated the credential itself is dead, there is
|
|
105
|
+
* no expiry to wait out and no refresh to run, so a cooldown would only return
|
|
106
|
+
* it to rotation to fail again. Set this to `0` to return the account to
|
|
107
|
+
* rotation immediately, with no backoff to wait out.
|
|
108
|
+
*/
|
|
109
|
+
export function resolveAccountAuthRejectedCooldownMs(): number {
|
|
110
|
+
if (_authRejectedCooldown === undefined)
|
|
111
|
+
_authRejectedCooldown = readInt(
|
|
112
|
+
"CARTETHYIA_ACCOUNT_AUTH_REJECTED_COOLDOWN_MS",
|
|
113
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_AUTH_REJECTED_COOLDOWN_MS,
|
|
114
|
+
);
|
|
115
|
+
return _authRejectedCooldown;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let _policyBlockCooldown: number | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Base backoff for the buddy policy/channel block (default 5m).
|
|
121
|
+
*
|
|
122
|
+
* Deliberately a *base*, not the 24h flat penalty it replaced. `11140` has two
|
|
123
|
+
* documented causes our classifier cannot separate from the response alone: the
|
|
124
|
+
* user's prompt failed a safety review, **and** sending the wrong desktop
|
|
125
|
+
* `User-Agent` brand (`workbuddy/shared.ts`). A flat 24h meant that after we
|
|
126
|
+
* fixed a header regression every buddy account stayed dead for up to a further
|
|
127
|
+
* day, and one unsafe prompt cost a whole account a day.
|
|
128
|
+
*
|
|
129
|
+
* As a base it escalates through the consecutive-failure ladder instead, which
|
|
130
|
+
* distinguishes the two causes by what they do next: a genuinely blocked account
|
|
131
|
+
* is refused again on its very next request and parks itself within minutes,
|
|
132
|
+
* while a single bad prompt costs five minutes.
|
|
133
|
+
*/
|
|
134
|
+
export function resolveAccountPolicyBlockCooldownMs(): number {
|
|
135
|
+
if (_policyBlockCooldown === undefined)
|
|
136
|
+
_policyBlockCooldown = readInt(
|
|
137
|
+
"CARTETHYIA_ACCOUNT_POLICY_BLOCK_COOLDOWN_MS",
|
|
138
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_POLICY_BLOCK_COOLDOWN_MS,
|
|
139
|
+
);
|
|
140
|
+
return _policyBlockCooldown;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let _disabledRecovery: number | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* How long an **automatically** disabled account stays out of rotation (default 24h).
|
|
146
|
+
*
|
|
147
|
+
* A credential rejected once — a revoked key, a definitively dead refresh grant —
|
|
148
|
+
* would otherwise leave rotation until an operator noticed and clicked Recover by
|
|
149
|
+
* hand. That is the wrong default for a credential that may come back on its own:
|
|
150
|
+
* keys get re-issued, grants get re-authorized, and an upstream's notion of
|
|
151
|
+
* "invalid" can outrun ours.
|
|
152
|
+
*
|
|
153
|
+
* The deadline is what makes this safe to automate rather than a policy guess. A row
|
|
154
|
+
* this gateway disables **by itself** carries the deadline; a row an **operator**
|
|
155
|
+
* disables keeps `cooldownUntil` null, and the recovery sweep selects only rows whose
|
|
156
|
+
* deadline has elapsed. So an operator's decision still outranks the machine, with no
|
|
157
|
+
* extra column and no way to confuse the two.
|
|
158
|
+
*
|
|
159
|
+
* Long on purpose: the states that reach here are the ones where retrying sooner
|
|
160
|
+
* only reproduces the refusal. Set to `0` to make an automatic disable terminal.
|
|
161
|
+
*/
|
|
162
|
+
export function resolveAccountDisabledRecoveryMs(): number {
|
|
163
|
+
if (_disabledRecovery === undefined)
|
|
164
|
+
_disabledRecovery = readInt(
|
|
165
|
+
"CARTETHYIA_ACCOUNT_DISABLED_RECOVERY_MS",
|
|
166
|
+
CONFIG_SPEC.CARTETHYIA_ACCOUNT_DISABLED_RECOVERY_MS,
|
|
167
|
+
);
|
|
168
|
+
return _disabledRecovery;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Resets all cached cooldown values. Call this in tests that override
|
|
173
|
+
* cooldown env-vars between test cases.
|
|
174
|
+
*/
|
|
175
|
+
export function resetCooldownCacheForTests(): void {
|
|
176
|
+
_rateLimitCooldown = undefined;
|
|
177
|
+
_quotaCooldown = undefined;
|
|
178
|
+
_modelCapacityCooldown = undefined;
|
|
179
|
+
_transientCooldown = undefined;
|
|
180
|
+
_unclassifiedCooldown = undefined;
|
|
181
|
+
_escalationMaxCooldown = undefined;
|
|
182
|
+
_poolCooldown = undefined;
|
|
183
|
+
_authRejectedCooldown = undefined;
|
|
184
|
+
_policyBlockCooldown = undefined;
|
|
185
|
+
_disabledRecovery = undefined;
|
|
186
|
+
}
|
package/src/config/network.ts
CHANGED
|
@@ -83,20 +83,15 @@ export function resolveProxyMaxFreeSockets(): number {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// Proxy pool egress is dialed in-process by `network/pool/agent.ts` (http,
|
|
86
|
-
// https, socks5).
|
|
87
|
-
// files, a binary path, a local SOCKS port range, and a uid/gid drop — was
|
|
88
|
-
// removed with that feature; do not reintroduce its resolvers without the
|
|
89
|
-
// daemon that consumed them.
|
|
86
|
+
// https, socks5). Add a resolver here only alongside the consumer it feeds.
|
|
90
87
|
|
|
91
88
|
// ─── Process-wide resource bounds ───────────────────────────────────────────
|
|
92
89
|
|
|
93
90
|
/**
|
|
94
91
|
* Live process-wide resource bounds. Only bounds with a production consumer
|
|
95
92
|
* live here: `maxPostgresPoolSize` feeds `poolMaxFromEnv()`, and
|
|
96
|
-
* `maxTelemetryQueueBytes` caps `TelemetryBatchBuffer`.
|
|
97
|
-
*
|
|
98
|
-
* catalog/replay bounds, `BoundedConfig` + its validators) had zero callers
|
|
99
|
-
* and was removed — re-add a bound only with its consumer in the same change.
|
|
93
|
+
* `maxTelemetryQueueBytes` caps `TelemetryBatchBuffer`. Re-add a bound only
|
|
94
|
+
* with its consumer in the same change.
|
|
100
95
|
*/
|
|
101
96
|
export const DEFAULT_BOUNDS = {
|
|
102
97
|
maxTelemetryQueueBytes: 10 * 1024 * 1024,
|
|
@@ -105,12 +100,11 @@ export const DEFAULT_BOUNDS = {
|
|
|
105
100
|
*
|
|
106
101
|
* This is a *ceiling*, not a reservation: the pool opens connections on
|
|
107
102
|
* demand and returns them to idle, so a value the workload never reaches
|
|
108
|
-
* costs nothing today — it only bounds the worst case. The
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* credential with a per-attempt read, health transitions write, and tenant
|
|
103
|
+
* costs nothing today — it only bounds the worst case. The proxy path is
|
|
104
|
+
* *mostly* database-free — routing comes from `InMemoryRouteSnapshotService`
|
|
105
|
+
* and admission counters live in Redis — but not entirely: a dispatch attempt
|
|
106
|
+
* resolves its credential with a per-attempt read, health transitions write,
|
|
107
|
+
* and tenant
|
|
114
108
|
* preferences are read behind a short cache. Those are small, bounded reads
|
|
115
109
|
* on the request's own attempt, not a per-request fan-out. The larger
|
|
116
110
|
* database consumers remain the console API, one telemetry flush at a time,
|
package/src/config/providers.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provider-specific knobs
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Provider-specific knobs: Kimi OAuth/quota hosts, the GitHub Enterprise domain
|
|
3
|
+
* for the Copilot device login, and the OAuth callback URL builders built on the
|
|
4
|
+
* public origin.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { CONFIG_SPEC, readInt,
|
|
7
|
+
import { CONFIG_SPEC, readInt, readRequired, readText } from "./spec";
|
|
8
8
|
|
|
9
9
|
/** Reads and normalizes the public OAuth origin. */
|
|
10
10
|
export function requirePublicOrigin(): string {
|
|
@@ -64,14 +64,11 @@ export function resolveOpenCodeUnavailableFree():
|
|
|
64
64
|
const raw = process.env.CARTETHYIA_OPENCODE_UNAVAILABLE_FREE?.trim();
|
|
65
65
|
if (raw === undefined || raw === "") return undefined;
|
|
66
66
|
if (raw.toLowerCase() === "none") return "none";
|
|
67
|
-
|
|
68
|
-
"CARTETHYIA_OPENCODE_UNAVAILABLE_FREE",
|
|
69
|
-
CONFIG_SPEC.CARTETHYIA_OPENCODE_UNAVAILABLE_FREE,
|
|
70
|
-
);
|
|
71
|
-
// Separators only: readList drops the empties and yields nothing. Treating
|
|
67
|
+
// Separators only: dropping empties and yielding nothing. Treating
|
|
72
68
|
// that as "trust everything" would un-block every refused model on a typo,
|
|
73
69
|
// so it falls back to the bundled list instead.
|
|
74
|
-
|
|
70
|
+
const entries = raw.split(",").map((v) => v.trim()).filter(Boolean);
|
|
71
|
+
return entries.length === 0 ? undefined : entries;
|
|
75
72
|
}
|
|
76
73
|
|
|
77
74
|
/**
|
package/src/config/runtime.ts
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP listener, dashboard runtime, and graceful-shutdown drain resolvers.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { CONFIG_SPEC, readInt, readOptionalText
|
|
6
|
-
import { resolvePackagePath } from "./package-paths";
|
|
7
|
-
|
|
8
|
-
/** Resolves the HTTP listener port from the process environment. */
|
|
9
|
-
export function resolvePort(): number {
|
|
10
|
-
return readInt("PORT", CONFIG_SPEC.PORT);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** Resolves the dashboard static asset directory. */
|
|
14
|
-
export function resolveDashboardDist(): string {
|
|
15
|
-
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Whether Elysia precompiles route handlers at startup (AOT).
|
|
55
|
-
*
|
|
56
|
-
* Precompilation takes the eager validator branch, which calls TypeBox's
|
|
57
|
-
* `SchemaCompile(schema)` and then reads `.buildResult.external` off the
|
|
58
|
-
* result. In a source-run process that field is absent — the lazy
|
|
59
|
-
* `require("typebox/schema")` resolves to a namespace that does not carry it —
|
|
60
|
-
* and the process dies at the first schema-bearing route with
|
|
61
|
-
* `undefined is not an object (evaluating 'this.tb.buildResult.external')`.
|
|
62
|
-
* `scripts/
|
|
63
|
-
* the namespaces statically, so only the built artifact can actually take the
|
|
64
|
-
* eager path.
|
|
65
|
-
*
|
|
66
|
-
* So: precompilation is on for production *builds*, and off for a source run
|
|
67
|
-
* even when `NODE_ENV=production`. A deployment that runs
|
|
68
|
-
* `bun run src/main.ts` must not be pushed onto the eager branch.
|
|
69
|
-
*
|
|
70
|
-
* `CARTETHYIA_SOURCE_RUN` marks a source run explicitly. It is set by
|
|
71
|
-
* `scripts/deploy/*.sh`, which are the only supported way to run from source.
|
|
72
|
-
*/
|
|
73
|
-
export function resolveElysiaPrecompile(): boolean {
|
|
74
|
-
if (process.env.CARTETHYIA_SOURCE_RUN === "1") return false;
|
|
75
|
-
return process.env.NODE_ENV === "production";
|
|
76
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* HTTP listener, dashboard runtime, and graceful-shutdown drain resolvers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CONFIG_SPEC, readInt, readOptionalText } from "./spec";
|
|
6
|
+
import { resolvePackagePath } from "./package-paths";
|
|
7
|
+
|
|
8
|
+
/** Resolves the HTTP listener port from the process environment. */
|
|
9
|
+
export function resolvePort(): number {
|
|
10
|
+
return readInt("PORT", CONFIG_SPEC.PORT);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Resolves the dashboard static asset directory. */
|
|
14
|
+
export function resolveDashboardDist(): string {
|
|
15
|
+
const raw = process.env.DASHBOARD_DIST?.trim();
|
|
16
|
+
if (!raw) return resolvePackagePath("dist", "dashboard");
|
|
17
|
+
return raw;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the configured default gateway API key (`CARTETHYIA_API_KEY`), if
|
|
22
|
+
* one is set. Consumers that need the raw secret — first-boot seeding and the
|
|
23
|
+
* console's key recovery from existing installations — read it here instead of
|
|
24
|
+
* probing `process.env` directly.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveDefaultGatewayApiKey(): string | undefined {
|
|
27
|
+
return readOptionalText("CARTETHYIA_API_KEY", CONFIG_SPEC.CARTETHYIA_API_KEY);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Resolves the request-body ceiling shared by the Bun listener and ingress middleware. */
|
|
31
|
+
export function resolveMaxBodyBytes(): number {
|
|
32
|
+
return readInt("CARTETHYIA_SERVER_MAX_BODY_BYTES", CONFIG_SPEC.CARTETHYIA_SERVER_MAX_BODY_BYTES);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Resolves the listener idle-socket timeout (seconds). */
|
|
36
|
+
export function resolveIdleTimeout(): number {
|
|
37
|
+
return readInt("CARTETHYIA_SERVER_IDLE_TIMEOUT", CONFIG_SPEC.CARTETHYIA_SERVER_IDLE_TIMEOUT);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Resolves the graceful-shutdown drain window: time for in-flight requests to finish before abort. */
|
|
41
|
+
export function resolveShutdownDrainWindowMs(): number {
|
|
42
|
+
return readInt(
|
|
43
|
+
"CARTETHYIA_SHUTDOWN_DRAIN_WINDOW_MS",
|
|
44
|
+
CONFIG_SPEC.CARTETHYIA_SHUTDOWN_DRAIN_WINDOW_MS,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Resolves the operator drain token, or `undefined` when the drain route is disabled. */
|
|
49
|
+
export function resolveDrainToken(): string | undefined {
|
|
50
|
+
return readOptionalText("CARTETHYIA_DRAIN_TOKEN", CONFIG_SPEC.CARTETHYIA_DRAIN_TOKEN);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Whether Elysia precompiles route handlers at startup (AOT).
|
|
55
|
+
*
|
|
56
|
+
* Precompilation takes the eager validator branch, which calls TypeBox's
|
|
57
|
+
* `SchemaCompile(schema)` and then reads `.buildResult.external` off the
|
|
58
|
+
* result. In a source-run process that field is absent — the lazy
|
|
59
|
+
* `require("typebox/schema")` resolves to a namespace that does not carry it —
|
|
60
|
+
* and the process dies at the first schema-bearing route with
|
|
61
|
+
* `undefined is not an object (evaluating 'this.tb.buildResult.external')`.
|
|
62
|
+
* `scripts/build/aot.ts` avoids this by rewriting the call site and bundling
|
|
63
|
+
* the namespaces statically, so only the built artifact can actually take the
|
|
64
|
+
* eager path.
|
|
65
|
+
*
|
|
66
|
+
* So: precompilation is on for production *builds*, and off for a source run
|
|
67
|
+
* even when `NODE_ENV=production`. A deployment that runs
|
|
68
|
+
* `bun run src/main.ts` must not be pushed onto the eager branch.
|
|
69
|
+
*
|
|
70
|
+
* `CARTETHYIA_SOURCE_RUN` marks a source run explicitly. It is set by
|
|
71
|
+
* `scripts/deploy/*.sh`, which are the only supported way to run from source.
|
|
72
|
+
*/
|
|
73
|
+
export function resolveElysiaPrecompile(): boolean {
|
|
74
|
+
if (process.env.CARTETHYIA_SOURCE_RUN === "1") return false;
|
|
75
|
+
return process.env.NODE_ENV === "production";
|
|
76
|
+
}
|
package/src/config/security.ts
CHANGED
|
@@ -37,6 +37,21 @@ export function resolveModelBanTtlMs(): number {
|
|
|
37
37
|
return readInt("CARTETHYIA_MODEL_BAN_TTL_MS", CONFIG_SPEC.CARTETHYIA_MODEL_BAN_TTL_MS);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* The longest model-abuse ban the console will record, however long a request
|
|
42
|
+
* asks for.
|
|
43
|
+
*
|
|
44
|
+
* A separate knob from the ban TTL because the two are different decisions:
|
|
45
|
+
* the TTL is what a graduated ban gets, this is the ceiling on what an
|
|
46
|
+
* operator may ask for by hand. Raising one was never meant to raise the other.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveModelBanMaxTtlMs(): number {
|
|
49
|
+
return readInt(
|
|
50
|
+
"CARTETHYIA_MODEL_BAN_MAX_TTL_MS",
|
|
51
|
+
CONFIG_SPEC.CARTETHYIA_MODEL_BAN_MAX_TTL_MS,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
40
55
|
/** Reads the application encryption key without caching it. */
|
|
41
56
|
export function requireEncryptionKeyEnv(): string {
|
|
42
57
|
return readRequired("CARTETHYIA_ENCRYPTION_KEY", CONFIG_SPEC.CARTETHYIA_ENCRYPTION_KEY);
|