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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* plans are served by different hosts and their keys are not interchangeable,
|
|
7
7
|
* and which plan a key belongs to is per-account state stored with it. A spec
|
|
8
8
|
* declares one `base_url` at construction, so the host is resolved from the
|
|
9
|
-
* credential at dispatch time and a stored region that
|
|
9
|
+
* credential at dispatch time and a stored region that does not resolve is a
|
|
10
10
|
* dispatch-time error rather than a silent fallback to the default host.
|
|
11
11
|
*/
|
|
12
12
|
import { createApiKeyAdapter } from "../../configured-provider";
|
|
@@ -33,10 +33,9 @@ interface AntigravityQuotaFamily {
|
|
|
33
33
|
* resulting id, so a quota row exists for exactly the models the operator can
|
|
34
34
|
* select.
|
|
35
35
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* for a model that cannot be chosen.
|
|
39
|
-
* model removes its quota row in the same change.
|
|
36
|
+
* Deriving the set means removing a catalog model removes its quota row in the
|
|
37
|
+
* same change — a hand-kept list would let a deployment the catalog does not
|
|
38
|
+
* serve report a quota row for a model that cannot be chosen.
|
|
40
39
|
*/
|
|
41
40
|
const CATALOG_MODEL_IDS: ReadonlySet<string> = new Set(
|
|
42
41
|
ANTIGRAVITY_MODELS.filter((model) => model.serviceKind !== "websearch").map((model) => model.modelId),
|
|
@@ -83,9 +82,8 @@ const SUMMARY_WINDOW_LABELS: Readonly<Record<SummaryWindowKind, string>> = Objec
|
|
|
83
82
|
*
|
|
84
83
|
* The upstream names the window in `window` (`5h`, `daily`, `weekly`) and
|
|
85
84
|
* repeats it in the display name. Daily must be tested before the 5-hour
|
|
86
|
-
* session:
|
|
87
|
-
*
|
|
88
|
-
* session is what dropped the daily row.
|
|
85
|
+
* session: a bucket whose own text says "daily" is the daily allowance, and
|
|
86
|
+
* treating it as the session is what drops the daily row.
|
|
89
87
|
*/
|
|
90
88
|
function summaryWindowKind(bucket: Record<string, unknown>): SummaryWindowKind | undefined {
|
|
91
89
|
const source = `${text(bucket.window) ?? ""} ${text(bucket.bucketId) ?? ""} ${text(bucket.displayName) ?? ""}`.toLowerCase();
|
|
@@ -822,9 +822,30 @@ export function dropEmptyBuddyMessages(messages: Array<Record<string, unknown>>)
|
|
|
822
822
|
if (Array.isArray(message["tool_calls"]) && message["tool_calls"].length > 0) return true;
|
|
823
823
|
if (typeof message["tool_call_id"] === "string" && message["tool_call_id"].trim().length > 0)
|
|
824
824
|
return true;
|
|
825
|
-
if (typeof message["reasoning_content"] === "string") return true;
|
|
826
825
|
const content = message["content"];
|
|
827
|
-
if (typeof content === "string")
|
|
826
|
+
if (typeof content === "string") {
|
|
827
|
+
if (content.trim().length > 0) return true;
|
|
828
|
+
// `content === ""` on a bare assistant turn (no tool_calls, no
|
|
829
|
+
// tool_call_id) is unverifiable by the receiving model regardless of
|
|
830
|
+
// what `reasoning_content` carries. The upstream rejects it with
|
|
831
|
+
// code `11151 "history not found"` for both shapes observed in the
|
|
832
|
+
// wild:
|
|
833
|
+
// (a) `reasoning_content: ""` — the Chat encoder's output for a
|
|
834
|
+
// canonical `reasoning` part with no `.summary` and a non-string
|
|
835
|
+
// `.payload` (signature-less thinking block already stripped on
|
|
836
|
+
// an earlier hop), and
|
|
837
|
+
// (b) `reasoning_content: "reasoning unavailable"` — the OMP client's
|
|
838
|
+
// sentinel in a Responses `reasoning` input item of shape
|
|
839
|
+
// `{summary: [], content: [{type: "reasoning_text",
|
|
840
|
+
// text: "reasoning unavailable"}]}`, emitted when the client
|
|
841
|
+
// strips the previous turn's trace on a model switch.
|
|
842
|
+
// Both are unverifiable: the receiving model never issued that
|
|
843
|
+
// signature, so nothing is round-trippable. Verifiable signatures
|
|
844
|
+
// round-trip on `tool_calls` turns (kept by the guard above) via the
|
|
845
|
+
// `reasoning_content` side channel; a signature on a bare turn with
|
|
846
|
+
// no tool_calls is not a shape any upstream in this family accepts.
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
828
849
|
if (Array.isArray(content)) return content.length > 0;
|
|
829
850
|
// Null content with no tool/reasoning load is a bare turn the upstream
|
|
830
851
|
// rejects — drop it rather than dispatch a known-invalid payload.
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
// claim short-circuits the day, so a restart cannot double-post.
|
|
20
20
|
|
|
21
21
|
import { providerBaseUrl } from "../../provider-metadata";
|
|
22
|
+
import { sleep } from "../../../shared/sleep";
|
|
22
23
|
import { WORKBUDDY_DOMAIN } from "./workbuddy/shared";
|
|
23
24
|
import { BUDDY_PROVIDER_IDS } from "../../provider-metadata";
|
|
24
25
|
import {
|
|
@@ -368,10 +369,6 @@ function isRetryableClaim(error: unknown, status: number | null): boolean {
|
|
|
368
369
|
return !(error instanceof DOMException && error.name === "AbortError");
|
|
369
370
|
}
|
|
370
371
|
|
|
371
|
-
function sleep(ms: number): Promise<void> {
|
|
372
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
373
|
-
}
|
|
374
|
-
|
|
375
372
|
function asRecord(value: unknown): Record<string, unknown> | null {
|
|
376
373
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
377
374
|
? (value as Record<string, unknown>)
|
|
@@ -69,7 +69,14 @@ export function buddyCliTraceHeaders(
|
|
|
69
69
|
* conversation family, because those vary by provider and realm: only the
|
|
70
70
|
* headers that are the same for every CLI dispatch are built here.
|
|
71
71
|
*/
|
|
72
|
-
export function buddyCliHeaders(args: {
|
|
72
|
+
export function buddyCliHeaders(args: {
|
|
73
|
+
readonly userId: string;
|
|
74
|
+
readonly enterpriseId?: string | undefined;
|
|
75
|
+
}): Record<string, string> {
|
|
76
|
+
const enterpriseId =
|
|
77
|
+
args.enterpriseId !== undefined && args.enterpriseId.trim().length > 0
|
|
78
|
+
? args.enterpriseId.trim()
|
|
79
|
+
: undefined;
|
|
73
80
|
return {
|
|
74
81
|
"X-Agent-Intent": "craft",
|
|
75
82
|
"X-Agent-Type": "main",
|
|
@@ -78,11 +85,21 @@ export function buddyCliHeaders(args: { readonly userId: string }): Record<strin
|
|
|
78
85
|
// of the three, so "other" is the honest value rather than a guess.
|
|
79
86
|
"X-Agent-Runtime": "other",
|
|
80
87
|
"X-User-Id": args.userId,
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
88
|
+
// The reference sends the flag either way, `true` only for an enterprise
|
|
89
|
+
// id. A personal account stays `false`; an enterprise account flips to
|
|
90
|
+
// `true` and names the enterprise, because the two travel together — a
|
|
91
|
+
// `true` with no id, or an id under `false`, is a combination no real
|
|
92
|
+
// client produces.
|
|
93
|
+
"X-Private-Data": enterpriseId === undefined ? "false" : "true",
|
|
94
|
+
...(enterpriseId === undefined
|
|
95
|
+
? {}
|
|
96
|
+
: {
|
|
97
|
+
"X-Enterprise-Id": enterpriseId,
|
|
98
|
+
// The tenant falls back to the enterprise: the two are the same value
|
|
99
|
+
// for an account that belongs to one enterprise, and the upstream
|
|
100
|
+
// reads both.
|
|
101
|
+
"X-Tenant-Id": enterpriseId,
|
|
102
|
+
}),
|
|
86
103
|
...buddyStainlessHeaders(),
|
|
87
104
|
};
|
|
88
105
|
}
|
|
@@ -91,7 +91,6 @@ export function buddyConversationHeaders(
|
|
|
91
91
|
};
|
|
92
92
|
// Always sent, invented when the caller gave none.
|
|
93
93
|
//
|
|
94
|
-
// This used to be omitted unless the client supplied one. That was wrong:
|
|
95
94
|
// `x-conversation-id` is mandatory, and a chat request without it is refused
|
|
96
95
|
// with `400 · 11-128 "request illegal"` — an error that names neither the
|
|
97
96
|
// header nor the channel, and which reads like a block rather than a missing
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProviderDispatchContext } from "../../provider-contracts";
|
|
2
|
+
import { decodeJwtPayload } from "../../authentication/oauth-flow-store";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Which upstream client a buddy provider presents itself as.
|
|
@@ -44,3 +45,54 @@ export function buddyUserId(context?: ProviderDispatchContext): string {
|
|
|
44
45
|
const accountId = context?.credential.account_id;
|
|
45
46
|
return accountId !== undefined && accountId.length > 0 ? accountId : "anonymous";
|
|
46
47
|
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Claim names a buddy access token may carry the enterprise id under.
|
|
51
|
+
*
|
|
52
|
+
* A list of candidates rather than one name because the upstream's token shape
|
|
53
|
+
* is not pinned anywhere this codebase can verify, and guessing one name would
|
|
54
|
+
* silently report "personal" for every account whose token spells it another
|
|
55
|
+
* way. Every candidate is a plausible spelling of the same fact; the first that
|
|
56
|
+
* holds a non-empty string wins, and a token carrying none yields no enterprise.
|
|
57
|
+
*/
|
|
58
|
+
const ENTERPRISE_CLAIMS: readonly string[] = [
|
|
59
|
+
"enterprise_id",
|
|
60
|
+
"enterpriseId",
|
|
61
|
+
"enterprise",
|
|
62
|
+
"tenant_id",
|
|
63
|
+
"tenantId",
|
|
64
|
+
"org_id",
|
|
65
|
+
"organization_id",
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The enterprise this buddy account belongs to, or `undefined` for a personal
|
|
70
|
+
* one.
|
|
71
|
+
*
|
|
72
|
+
* Two sources, in this order:
|
|
73
|
+
*
|
|
74
|
+
* 1. **`auth_state.enterpriseId`** — written when the account was authorized, or
|
|
75
|
+
* set by an operator for an account whose token does not carry the fact.
|
|
76
|
+
* Wins because it is the one a human can correct.
|
|
77
|
+
* 2. **A claim on the access token** — for accounts authorized before this
|
|
78
|
+
* existed, whose `auth_state` was never populated.
|
|
79
|
+
*
|
|
80
|
+
* Deliberately conservative: no enterprise id means *personal*, and personal is
|
|
81
|
+
* what the gateway already sends. An unknown account is therefore unchanged
|
|
82
|
+
* rather than being given an enterprise it may not have — claiming one the
|
|
83
|
+
* upstream does not recognise is the kind of mismatch that draws a channel
|
|
84
|
+
* check.
|
|
85
|
+
*/
|
|
86
|
+
export function buddyEnterprise(context?: ProviderDispatchContext): string | undefined {
|
|
87
|
+
const stored = context?.credential.auth_state?.["enterpriseId"];
|
|
88
|
+
if (typeof stored === "string" && stored.trim().length > 0) return stored.trim();
|
|
89
|
+
const token = context?.credential.secret;
|
|
90
|
+
if (token === undefined || token.length === 0) return undefined;
|
|
91
|
+
const claims = decodeJwtPayload(new TextDecoder().decode(token).trim());
|
|
92
|
+
if (claims === undefined) return undefined;
|
|
93
|
+
for (const claim of ENTERPRISE_CLAIMS) {
|
|
94
|
+
const value = claims[claim];
|
|
95
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* ⚠️ The provider's actual polling route has not been verified. The sibling
|
|
17
17
|
* URL is an implementation inference, not an observed contract. See
|
|
18
|
-
* `documentation/features/buddy-media-generation.md` before changing it.
|
|
18
|
+
* `documentation/features/07-buddy-media-generation.md` before changing it.
|
|
19
19
|
*/
|
|
20
20
|
import { OpenAICompatibleAdapter, authHeaders, type OpenAICompatibleAdapterConfig } from "../../adapters/compatible-adapter";
|
|
21
21
|
import { GatewayError } from "../../../protocol/gateway-error";
|
|
@@ -305,7 +305,7 @@ export function buddyErrorOf(payload: unknown): string | undefined {
|
|
|
305
305
|
* inferred sibling task URL until it reports a finished clip.
|
|
306
306
|
*
|
|
307
307
|
* ⚠️ The status path is not provider-verified; see the module header and
|
|
308
|
-
* `documentation/features/buddy-media-generation.md`.
|
|
308
|
+
* `documentation/features/07-buddy-media-generation.md`.
|
|
309
309
|
*/
|
|
310
310
|
export async function buddyGenerateVideo(
|
|
311
311
|
config: BuddyMediaConfig,
|
|
@@ -92,10 +92,9 @@ const DEFAULT_LIMIT_PER_ACCOUNT = 30;
|
|
|
92
92
|
/**
|
|
93
93
|
* Reads each account's stored usage, newest day first.
|
|
94
94
|
*
|
|
95
|
-
* Bounded on both axes
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* dashboard polls.
|
|
95
|
+
* Bounded on both axes: with no day filter and no `LIMIT`, an account would
|
|
96
|
+
* fetch every bucket it had ever stored (~1500 rows for a 30-day window) to
|
|
97
|
+
* render 30 of them, on the route the dashboard polls.
|
|
99
98
|
*
|
|
100
99
|
* - The day window is semantic, not a truncation: {@link pruneBuddyUsageSnapshots}
|
|
101
100
|
* already drops everything older, so no row it excludes could have been
|
|
@@ -24,9 +24,9 @@ export const CODEBUDDY_CN_USAGE_URL =
|
|
|
24
24
|
`${providerBaseUrl("cbcn")}/billing/meter/get-user-resource`;
|
|
25
25
|
export const CODEBUDDY_INTL_USAGE_URL =
|
|
26
26
|
`${providerBaseUrl("cb")}/billing/meter/get-user-resource`;
|
|
27
|
-
|
|
27
|
+
const CODEBUDDY_CN_REQUEST_USAGE_URL =
|
|
28
28
|
`${providerBaseUrl("cbcn")}/billing/meter/get-user-request-usage`;
|
|
29
|
-
|
|
29
|
+
const CODEBUDDY_INTL_REQUEST_USAGE_URL =
|
|
30
30
|
`${providerBaseUrl("cb")}/billing/meter/get-user-request-usage`;
|
|
31
31
|
|
|
32
32
|
type CodeBuddyProviderId = "cb" | "cbcn";
|
|
@@ -152,14 +152,3 @@ export async function fetchCodeBuddyRequestUsage(
|
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
export const fetchCodeBuddyCnRequestUsage = (
|
|
156
|
-
credential: string,
|
|
157
|
-
fetcher: FetchLike,
|
|
158
|
-
days: number = 30,
|
|
159
|
-
): Promise<BuddyUsageResult> => fetchCodeBuddyRequestUsage(credential, fetcher, "cbcn", days);
|
|
160
|
-
|
|
161
|
-
export const fetchCodeBuddyIntlRequestUsage = (
|
|
162
|
-
credential: string,
|
|
163
|
-
fetcher: FetchLike,
|
|
164
|
-
days: number = 30,
|
|
165
|
-
): Promise<BuddyUsageResult> => fetchCodeBuddyRequestUsage(credential, fetcher, "cb", days);
|
|
@@ -1,115 +1,118 @@
|
|
|
1
|
-
import { withBearerAuthentication, type OpenAICompatibleAdapterConfig } from "../../../adapters/compatible-adapter";
|
|
2
|
-
import type { CanonicalRequest } from "../../../../protocol/canonical-model";
|
|
3
|
-
import type { ProviderDispatchContext, ProviderDispatchTarget, ProviderId } from "../../../provider-contracts";
|
|
4
|
-
import { resolveInboundSessionId } from "../../../operations/session-resolution";
|
|
5
|
-
import { buddyConversationHeaders } from "../buddy-conversation-headers";
|
|
6
|
-
import { buddyUserId, resolveBuddyIdentity } from "../buddy-identity";
|
|
7
|
-
import { buildCodeBuddyUserAgent, getCodeBuddyCnVersion, getCodeBuddyVersion } from "../../../operations/client-versions";
|
|
8
|
-
import { readBuddyDeviceToken } from "../workbuddy/shared";
|
|
9
|
-
import { buddyCliHeaders, buddyCliTraceHeaders } from "../buddy-cli-headers";
|
|
10
|
-
|
|
11
|
-
/** Client identity variant behind the per-request CodeBuddy headers. */
|
|
12
|
-
export type CodeBuddyVariant = "IDE" | "CLI";
|
|
13
|
-
|
|
14
|
-
export function codebuddyDomain(variant: CodeBuddyVariant): string {
|
|
15
|
-
return variant === "IDE" ? "www.codebuddy.ai" : "copilot.tencent.com";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Per-request CodeBuddy headers — exact provider contract shared by the
|
|
21
|
-
* international (IDE identity) and CN (CLI identity). The stable conversation
|
|
22
|
-
* header is preserved from the client when available; request IDs rotate.
|
|
23
|
-
*
|
|
24
|
-
* `cliIdentity` selects the real CLI contract rather than today's hybrid: the
|
|
25
|
-
* reference CLI is issued by the OpenAI Node SDK, so it carries no browser
|
|
26
|
-
* headers and no device token, and it adds the agent envelope. Left unset it
|
|
27
|
-
* keeps the current behaviour for every provider.
|
|
28
|
-
*/
|
|
29
|
-
export async function codebuddyHeaders(
|
|
30
|
-
variant: CodeBuddyVariant,
|
|
31
|
-
context?: ProviderDispatchContext,
|
|
32
|
-
request?: CanonicalRequest,
|
|
33
|
-
cliIdentity?: boolean,
|
|
34
|
-
): Promise<Record<string, string>> {
|
|
35
|
-
const identity = variant === "IDE" ? "IDE" : "CLI";
|
|
36
|
-
const ua = buildCodeBuddyUserAgent(identity);
|
|
37
|
-
const deviceToken = readBuddyDeviceToken(context);
|
|
38
|
-
const conversationId = resolveInboundSessionId(context, request);
|
|
39
|
-
const conversation = buddyConversationHeaders({
|
|
40
|
-
...(conversationId === undefined ? {} : { conversationId }),
|
|
41
|
-
});
|
|
42
|
-
if (resolveBuddyIdentity(context, cliIdentity) === "cli") {
|
|
43
|
-
return {
|
|
44
|
-
// The CLI sends `Accept: application/json` and no device token. The
|
|
45
|
-
// browser-shaped pair (`X-Requested-With`, `x-codebuddy-request`) stays
|
|
46
|
-
// off this branch: a request carrying both halves is a hybrid no real
|
|
47
|
-
// client produces, and that is a fidelity choice, not a requirement —
|
|
48
|
-
// the live API answers either way.
|
|
49
|
-
accept: "application/json",
|
|
50
|
-
"User-Agent": `CLI/${getCodeBuddyVersion()} CodeBuddy/${getCodeBuddyVersion()}`,
|
|
51
|
-
"X-Product": "SaaS",
|
|
52
|
-
"X-IDE-Type": "CLI",
|
|
53
|
-
"X-IDE-Name": "CLI",
|
|
54
|
-
"X-IDE-Version": getCodeBuddyVersion(),
|
|
55
|
-
"X-Domain": codebuddyDomain(variant),
|
|
56
|
-
// The conversation purpose the reference client states. Not required —
|
|
57
|
-
// verified against the live API that a request succeeds without it — but
|
|
58
|
-
// it is part of the client's real request, and matching the client is the
|
|
59
|
-
// defence against a channel check tightening later.
|
|
60
|
-
"X-Agent-Purpose": "conversation",
|
|
61
|
-
...conversation,
|
|
62
|
-
...buddyCliTraceHeaders(conversation),
|
|
63
|
-
...buddyCliHeaders({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
// Same
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
1
|
+
import { withBearerAuthentication, type OpenAICompatibleAdapterConfig } from "../../../adapters/compatible-adapter";
|
|
2
|
+
import type { CanonicalRequest } from "../../../../protocol/canonical-model";
|
|
3
|
+
import type { ProviderDispatchContext, ProviderDispatchTarget, ProviderId } from "../../../provider-contracts";
|
|
4
|
+
import { resolveInboundSessionId } from "../../../operations/session-resolution";
|
|
5
|
+
import { buddyConversationHeaders } from "../buddy-conversation-headers";
|
|
6
|
+
import { buddyEnterprise, buddyUserId, resolveBuddyIdentity } from "../buddy-identity";
|
|
7
|
+
import { buildCodeBuddyUserAgent, getCodeBuddyCnVersion, getCodeBuddyVersion } from "../../../operations/client-versions";
|
|
8
|
+
import { readBuddyDeviceToken } from "../workbuddy/shared";
|
|
9
|
+
import { buddyCliHeaders, buddyCliTraceHeaders } from "../buddy-cli-headers";
|
|
10
|
+
|
|
11
|
+
/** Client identity variant behind the per-request CodeBuddy headers. */
|
|
12
|
+
export type CodeBuddyVariant = "IDE" | "CLI";
|
|
13
|
+
|
|
14
|
+
export function codebuddyDomain(variant: CodeBuddyVariant): string {
|
|
15
|
+
return variant === "IDE" ? "www.codebuddy.ai" : "copilot.tencent.com";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Per-request CodeBuddy headers — exact provider contract shared by the
|
|
21
|
+
* international (IDE identity) and CN (CLI identity). The stable conversation
|
|
22
|
+
* header is preserved from the client when available; request IDs rotate.
|
|
23
|
+
*
|
|
24
|
+
* `cliIdentity` selects the real CLI contract rather than today's hybrid: the
|
|
25
|
+
* reference CLI is issued by the OpenAI Node SDK, so it carries no browser
|
|
26
|
+
* headers and no device token, and it adds the agent envelope. Left unset it
|
|
27
|
+
* keeps the current behaviour for every provider.
|
|
28
|
+
*/
|
|
29
|
+
export async function codebuddyHeaders(
|
|
30
|
+
variant: CodeBuddyVariant,
|
|
31
|
+
context?: ProviderDispatchContext,
|
|
32
|
+
request?: CanonicalRequest,
|
|
33
|
+
cliIdentity?: boolean,
|
|
34
|
+
): Promise<Record<string, string>> {
|
|
35
|
+
const identity = variant === "IDE" ? "IDE" : "CLI";
|
|
36
|
+
const ua = buildCodeBuddyUserAgent(identity);
|
|
37
|
+
const deviceToken = readBuddyDeviceToken(context);
|
|
38
|
+
const conversationId = resolveInboundSessionId(context, request);
|
|
39
|
+
const conversation = buddyConversationHeaders({
|
|
40
|
+
...(conversationId === undefined ? {} : { conversationId }),
|
|
41
|
+
});
|
|
42
|
+
if (resolveBuddyIdentity(context, cliIdentity) === "cli") {
|
|
43
|
+
return {
|
|
44
|
+
// The CLI sends `Accept: application/json` and no device token. The
|
|
45
|
+
// browser-shaped pair (`X-Requested-With`, `x-codebuddy-request`) stays
|
|
46
|
+
// off this branch: a request carrying both halves is a hybrid no real
|
|
47
|
+
// client produces, and that is a fidelity choice, not a requirement —
|
|
48
|
+
// the live API answers either way.
|
|
49
|
+
accept: "application/json",
|
|
50
|
+
"User-Agent": `CLI/${getCodeBuddyVersion()} CodeBuddy/${getCodeBuddyVersion()}`,
|
|
51
|
+
"X-Product": "SaaS",
|
|
52
|
+
"X-IDE-Type": "CLI",
|
|
53
|
+
"X-IDE-Name": "CLI",
|
|
54
|
+
"X-IDE-Version": getCodeBuddyVersion(),
|
|
55
|
+
"X-Domain": codebuddyDomain(variant),
|
|
56
|
+
// The conversation purpose the reference client states. Not required —
|
|
57
|
+
// verified against the live API that a request succeeds without it — but
|
|
58
|
+
// it is part of the client's real request, and matching the client is the
|
|
59
|
+
// defence against a channel check tightening later.
|
|
60
|
+
"X-Agent-Purpose": "conversation",
|
|
61
|
+
...conversation,
|
|
62
|
+
...buddyCliTraceHeaders(conversation),
|
|
63
|
+
...buddyCliHeaders({
|
|
64
|
+
userId: buddyUserId(context),
|
|
65
|
+
enterpriseId: buddyEnterprise(context),
|
|
66
|
+
}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
accept: "text/event-stream",
|
|
71
|
+
"User-Agent": ua,
|
|
72
|
+
"X-Product": "SaaS",
|
|
73
|
+
"X-IDE-Type": identity,
|
|
74
|
+
"X-IDE-Name": identity,
|
|
75
|
+
// Every reference branch sends this, in both the desktop and the CLI
|
|
76
|
+
// product; its absence here is what made a CodeBuddy dispatch the only
|
|
77
|
+
// buddy caller with no client version on the wire.
|
|
78
|
+
"X-IDE-Version": identity === "CLI" ? getCodeBuddyCnVersion() : getCodeBuddyVersion(),
|
|
79
|
+
"X-Domain": codebuddyDomain(variant),
|
|
80
|
+
"x-requested-with": "XMLHttpRequest",
|
|
81
|
+
"x-codebuddy-request": "1",
|
|
82
|
+
// Same value the CLI branch sends, for the same reason: part of the
|
|
83
|
+
// client's real request, harmless when the channel check does not read it.
|
|
84
|
+
"X-Agent-Purpose": "conversation",
|
|
85
|
+
// Same family WorkBuddy sends: the upstream's channel check reads the
|
|
86
|
+
// turn-level aggregation key, and a chat request without it is refused for a
|
|
87
|
+
// missing conversation id.
|
|
88
|
+
...conversation,
|
|
89
|
+
...(deviceToken === undefined ? {} : { "X-Device-Token": deviceToken }),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Shared OpenAI-compatible chat-adapter config for both CodeBuddy variants:
|
|
95
|
+
* bearer auth, chat-only wire contract, per-request identity headers, and the
|
|
96
|
+
* variant's payload hook.
|
|
97
|
+
*/
|
|
98
|
+
export function codebuddyAdapterConfig(args: {
|
|
99
|
+
providerId: ProviderId;
|
|
100
|
+
baseUrl: string;
|
|
101
|
+
variant: CodeBuddyVariant;
|
|
102
|
+
prePayload: (
|
|
103
|
+
payload: Record<string, unknown>,
|
|
104
|
+
request: CanonicalRequest,
|
|
105
|
+
candidate: ProviderDispatchTarget,
|
|
106
|
+
) => void;
|
|
107
|
+
fetchImpl?: typeof fetch;
|
|
108
|
+
cliIdentity?: boolean;
|
|
109
|
+
}): OpenAICompatibleAdapterConfig {
|
|
110
|
+
return withBearerAuthentication({
|
|
111
|
+
provider_id: args.providerId,
|
|
112
|
+
base_url: args.baseUrl,
|
|
113
|
+
buildExtraHeaders: (context, request) =>
|
|
114
|
+
codebuddyHeaders(args.variant, context, request, args.cliIdentity),
|
|
115
|
+
prePayload: args.prePayload,
|
|
116
|
+
...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
@@ -38,11 +38,6 @@ const WORKBUDDY_CN_BILLING_BASE_URL = "https://www.codebuddy.cn";
|
|
|
38
38
|
export const WORKBUDDY_USAGE_URL =
|
|
39
39
|
`${providerBaseUrl("workbuddy")}/v2/billing/meter/get-user-resource`;
|
|
40
40
|
|
|
41
|
-
export const WORKBUDDY_REQUEST_USAGE_URL =
|
|
42
|
-
`${providerBaseUrl("workbuddy")}/billing/meter/get-user-request-usage`;
|
|
43
|
-
export const WORKBUDDY_CN_REQUEST_USAGE_URL =
|
|
44
|
-
`${providerBaseUrl("workbuddycn")}/billing/meter/get-user-request-usage`;
|
|
45
|
-
|
|
46
41
|
async function billingHeaders(
|
|
47
42
|
domain: string,
|
|
48
43
|
clientVersion: string,
|
|
@@ -164,9 +159,3 @@ export async function fetchWorkBuddyRequestUsage(
|
|
|
164
159
|
});
|
|
165
160
|
}
|
|
166
161
|
|
|
167
|
-
export const fetchWorkBuddyCnRequestUsage = (
|
|
168
|
-
credential: string,
|
|
169
|
-
fetcher: FetchLike,
|
|
170
|
-
days: number = 30,
|
|
171
|
-
): Promise<BuddyUsageResult> =>
|
|
172
|
-
fetchWorkBuddyRequestUsage(credential, fetcher, { providerId: "workbuddycn", days });
|
|
@@ -8,7 +8,7 @@ import type { ProviderDispatchContext, ProviderDispatchTarget, ProviderId } from
|
|
|
8
8
|
import { resolveInboundSessionId } from "../../../operations/session-resolution";
|
|
9
9
|
import { buddyConversationHeaders } from "../buddy-conversation-headers";
|
|
10
10
|
import { buddyCliHeaders, buddyCliTraceHeaders } from "../buddy-cli-headers";
|
|
11
|
-
import { buddyUserId, resolveBuddyIdentity } from "../buddy-identity";
|
|
11
|
+
import { buddyEnterprise, buddyUserId, resolveBuddyIdentity } from "../buddy-identity";
|
|
12
12
|
import {
|
|
13
13
|
buildWorkBuddyUserAgent,
|
|
14
14
|
getWorkBuddyClientVersion,
|
|
@@ -91,7 +91,10 @@ export async function workbuddyHeaders(
|
|
|
91
91
|
"x-no-enterprise-id": "1",
|
|
92
92
|
...conversation,
|
|
93
93
|
...buddyCliTraceHeaders(conversation),
|
|
94
|
-
...buddyCliHeaders({
|
|
94
|
+
...buddyCliHeaders({
|
|
95
|
+
userId: buddyUserId(context),
|
|
96
|
+
enterpriseId: buddyEnterprise(context),
|
|
97
|
+
}),
|
|
95
98
|
};
|
|
96
99
|
}
|
|
97
100
|
const headers: Record<string, string> = {
|