cartethyia 2.7.4 → 2.7.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 +5 -0
- package/README.md +18 -6
- package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
- package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
- package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
- package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
- package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
- package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js +899 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
- package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-C6WlpU5E.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
- package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
- package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-DxjvUzSD.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
- package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js +1 -0
- package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
- package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-DRPavCdU.js} +4 -4
- package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
- package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
- package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-B7M7LvMM.js +56 -0
- package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
- package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
- package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
- package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
- package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
- package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
- package/dist/dashboard/assets/assert-CidQVoNo.js +1 -0
- package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-BaX2GTrn.js} +1 -1
- package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DympBNq4.js → banner-DFH4Bkte.js} +1 -1
- package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
- package/dist/dashboard/assets/brand/login_register.jpg +0 -0
- package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
- package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
- package/dist/dashboard/assets/brand/og_image.jpg +0 -0
- package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CxDw0lK6.js} +1 -1
- package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
- package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
- package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +1 -0
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-DfS1ntiq.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
- package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-QqPul6sC.js} +1 -1
- package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
- package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
- package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
- package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
- package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
- package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
- package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-u7JPB5BX.js} +1 -1
- package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
- package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
- package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
- package/dist/dashboard/assets/{index-DBNPOfhV.js → index-Ko4dLRnV.js} +2 -2
- package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-CHJQwxLa.js} +1 -1
- package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
- package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BlmlizVV.js} +1 -1
- package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-Bz93I-yE.js} +1 -1
- package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Ml16KCfu.js} +1 -1
- package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
- package/dist/dashboard/assets/live-7_QpnYGu.js +1 -0
- package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
- package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
- package/dist/dashboard/assets/network-CuMDaTzT.js +1 -0
- package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
- package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
- package/dist/dashboard/assets/pagination-B5aOoweZ.js +1 -0
- package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
- package/dist/dashboard/assets/providers/zai.webp +0 -0
- package/dist/dashboard/assets/providers/zcode.webp +0 -0
- package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
- package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
- package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
- package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
- package/dist/dashboard/assets/routing-fnCsxgNO.js +1 -0
- package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
- package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BHqpd-bg.js} +2 -2
- package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
- package/dist/dashboard/assets/settings-BxslsErn.js +1 -0
- package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-j7cXjgYX.js} +1 -1
- package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
- package/dist/dashboard/assets/{state-CkfdYWel.js → state-DHmEnLa2.js} +1 -1
- package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
- package/dist/dashboard/assets/{switch-SYm237HG.js → switch-DmZcyTIC.js} +1 -1
- package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-CbCP4w1o.js} +1 -1
- package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.jpg +0 -0
- package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +60 -59
- package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
- package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
- package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
- package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
- package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
- package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
- package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
- package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
- package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
- package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
- package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
- package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
- package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
- package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
- package/package.json +4 -6
- package/scripts/cli/update.ts +15 -41
- package/src/boot/app.ts +58 -2
- package/src/boot/dependencies.ts +794 -732
- package/src/boot/lifecycle.ts +11 -12
- package/src/config/cooldowns.ts +34 -55
- package/src/config/network.ts +1 -1
- package/src/config/package-paths.ts +1 -1
- package/src/config/providers.ts +19 -14
- package/src/config/resources.ts +0 -5
- package/src/config/runtime.ts +2 -5
- package/src/config/spec.ts +33 -6
- package/src/config/usage.ts +27 -0
- package/src/console/api-keys/ban-constants.ts +38 -0
- package/src/console/api-keys/contracts.ts +71 -62
- package/src/console/api-keys/routes.ts +56 -24
- package/src/console/auth/access.ts +4 -4
- package/src/console/auth/account-reset.ts +1 -1
- package/src/console/auth/audit-recorder.ts +1 -1
- package/src/console/auth/lockout.ts +7 -3
- package/src/console/auth/row-coercion.ts +57 -12
- package/src/console/auth/session-resolver.ts +1 -1
- package/src/console/auth/session-service.ts +8 -2
- package/src/console/auth/session.ts +37 -31
- package/src/console/auth/setup-service.ts +4 -3
- package/src/console/auth/user-store.ts +1 -1
- package/src/console/backup/9router-map.ts +0 -3
- package/src/console/backup/contracts.ts +9 -9
- package/src/console/backup/export-endpoint.ts +5 -6
- package/src/console/backup/nine-router.ts +1 -7
- package/src/console/backup/routes.ts +29 -33
- package/src/console/backup/service.ts +468 -468
- package/src/console/backup/store.ts +47 -29
- package/src/console/backup/validate.ts +11 -1
- package/src/console/cli-tools/contracts.ts +43 -299
- package/src/console/cli-tools/fs-ops.ts +29 -0
- package/src/console/cli-tools/injectors/claude.ts +3 -3
- package/src/console/cli-tools/injectors/codex.ts +181 -181
- package/src/console/cli-tools/injectors/driver.ts +150 -247
- package/src/console/cli-tools/injectors/kilo.ts +146 -21
- package/src/console/cli-tools/injectors/opencode.ts +176 -153
- package/src/console/cli-tools/routes.ts +7 -1
- package/src/console/cli-tools/service.ts +8 -7
- package/src/console/cli-tools/store.ts +2 -2
- package/src/console/console-router.ts +32 -0
- package/src/console/dashboard-assets.ts +9 -9
- package/src/console/domain-registration.ts +16 -2
- package/src/console/inferhub/client.ts +0 -7
- package/src/console/inferhub/key-store.ts +1 -1
- package/src/console/inferhub/normalize.ts +2 -2
- package/src/console/inferhub/routes.ts +1 -1
- package/src/console/inferhub/types.ts +1 -1
- package/src/console/observability/contracts.ts +7 -1
- package/src/console/observability/live.ts +31 -18
- package/src/console/observability/logs.ts +1 -1
- package/src/console/observability/sse.ts +62 -8
- package/src/console/observability/store.ts +23 -4
- package/src/console/providers/catalog/catalog-projections.ts +1 -1
- package/src/console/providers/catalog/contracts.ts +39 -0
- package/src/console/providers/catalog/model-operations.ts +1 -1
- package/src/console/providers/catalog/provider-operations.ts +95 -17
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +27 -3
- package/src/console/providers/catalog/store.ts +147 -8
- package/src/console/providers/detail/routes.ts +1 -1
- package/src/console/providers/oauth/callback-listener.ts +100 -18
- package/src/console/providers/oauth/routes.ts +92 -13
- package/src/console/quota/account-quota-global.ts +41 -3
- package/src/console/quota/account-quota-shared.ts +10 -3
- package/src/console/quota/account-quota-tenant.ts +259 -66
- package/src/console/quota/daily-growth-job.ts +308 -0
- package/src/console/quota/native-identity.ts +2 -2
- package/src/console/quota/quota-view.ts +1 -1
- package/src/console/remote-support/routes.ts +1 -1
- package/src/console/remote-support/service.ts +2 -2
- package/src/console/routing/model/contracts.ts +1 -1
- package/src/console/routing/pools/contracts.ts +2 -2
- package/src/console/routing/pools/import-parse.ts +3 -3
- package/src/console/routing/pools/relay-deploy.ts +3 -3
- package/src/console/settings/contracts.ts +29 -2
- package/src/console/settings/store.ts +20 -0
- package/src/console/share/share-router.ts +100 -32
- package/src/console/share/share-stats.ts +11 -13
- package/src/console/share/share-usage.ts +1 -1
- package/src/console/shared/errors.ts +2 -2
- package/src/console/shared/object.ts +18 -0
- package/src/console/shared/read-through-cache.ts +4 -4
- package/src/console/shared/transaction.ts +14 -0
- package/src/console/system-prompt/contracts.ts +89 -12
- package/src/console/system-prompt/routes.ts +98 -45
- package/src/console/updates/apply-update.ts +244 -0
- package/src/console/updates/routes.ts +252 -97
- package/src/main.ts +11 -5
- package/src/network/http2-bidi.ts +1 -1
- package/src/network/ip-utils.ts +298 -0
- package/src/network/outbound-fetch.ts +1 -1
- package/src/network/pool/agent.ts +7 -6
- package/src/network/pool/byte-accounting.ts +1 -1
- package/src/network/pool/resolver.ts +16 -12
- package/src/network/pool/selector.ts +150 -136
- package/src/network/pool-health-machine.ts +1 -1
- package/src/network/rate-limit-verdict.ts +1 -1
- package/src/network/retry.ts +1 -1
- package/src/network/ssrf.ts +20 -71
- package/src/observability/event-log.ts +9 -2
- package/src/observability/event-query.ts +61 -291
- package/src/observability/log-sanitize.ts +1 -1
- package/src/observability/metrics.ts +4 -4
- package/src/observability/payload-capture.ts +6 -5
- package/src/observability/payload-store.ts +1 -1
- package/src/observability/runtime-metrics.ts +1 -1
- package/src/observability/telemetry-buffer.ts +19 -3
- package/src/observability/telemetry-reconciliation.ts +3 -3
- package/src/observability/token-speed.ts +1 -1
- package/src/persistence/connection-url.ts +1 -1
- package/src/persistence/db-handle.ts +1 -1
- package/src/persistence/db-pg.ts +2 -2
- package/src/persistence/db-sqlite.ts +3 -3
- package/src/persistence/dialect.ts +5 -1
- package/src/persistence/readiness.ts +1 -1
- package/src/persistence/redis.ts +1 -1
- package/src/persistence/schema.ts +121 -40
- package/src/persistence/shared-cache.ts +2 -2
- package/src/persistence/sort-order.ts +1 -1
- package/src/persistence/stores/api-key-store.ts +29 -2
- package/src/persistence/stores/share-store.ts +20 -8
- package/src/persistence/system-prompt-store.ts +63 -18
- package/src/persistence/tenant-preferences.ts +1 -1
- package/src/persistence/ttl-cache.ts +3 -3
- package/src/persistence/usage-flush.ts +7 -2
- package/src/protocol/canonical-model.ts +1 -1
- package/src/protocol/codecs.ts +6 -10
- package/src/protocol/dsml.ts +8 -125
- package/src/protocol/image-clamp.ts +2 -2
- package/src/protocol/reasoning-text.ts +1 -1
- package/src/protocol/reasoning.ts +7 -52
- package/src/protocol/registry.ts +50 -15
- package/src/protocol/request/chat.ts +46 -19
- package/src/protocol/request/codex.ts +1 -1
- package/src/protocol/request/messages.ts +46 -14
- package/src/protocol/request/responses.ts +19 -10
- package/src/protocol/response/chat.ts +25 -10
- package/src/protocol/response/codex.ts +1 -1
- package/src/protocol/response/messages.ts +1 -1
- package/src/protocol/response/omp-tool-call-markup.ts +1 -1
- package/src/protocol/response/responses.ts +1 -1
- package/src/protocol/sse-decoder.ts +50 -1
- package/src/protocol/stop-reason.ts +2 -2
- package/src/protocol/think-split.ts +347 -0
- package/src/protocol/translation/attachment-integrity.ts +3 -3
- package/src/protocol/translation/cache-controls.ts +8 -20
- package/src/protocol/translation/capabilities.ts +6 -6
- package/src/protocol/translation/dialect/deepseek.ts +10 -0
- package/src/protocol/translation/dialect/inband.ts +39 -0
- package/src/protocol/translation/dialect/model-thinking.ts +89 -0
- package/src/protocol/translation/dialect/qwen.ts +114 -0
- package/src/protocol/translation/dialect/resolver.ts +83 -0
- package/src/protocol/translation/dialect/rules.ts +93 -0
- package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
- package/src/protocol/translation/dialect/types.ts +58 -0
- package/src/protocol/translation/quirks.ts +18 -4
- package/src/protocol/translation/thinking.ts +12 -252
- package/src/protocol/translation/tool-id.ts +3 -3
- package/src/protocol/translation/tool-repair.ts +1 -1
- package/src/protocol/upstream/post-json.ts +6 -1
- package/src/providers/adapters/compatible-adapter.ts +71 -4
- package/src/providers/authentication/jwt-validator.ts +0 -5
- package/src/providers/authentication/oauth-client.ts +254 -253
- package/src/providers/authentication/oauth-flow-store.ts +42 -7
- package/src/providers/bundled-discovery-providers.ts +6 -30
- package/src/providers/configured-openai-providers.ts +82 -97
- package/src/providers/default-registry.ts +35 -37
- package/src/providers/discovery/catalog/catalog-format.ts +13 -2
- package/src/providers/discovery/discovery-types.ts +0 -1
- package/src/providers/discovery/openai-model-discovery.ts +2 -2
- package/src/providers/discovery/probe-phases.ts +48 -13
- package/src/providers/discovery/probing-service.ts +6 -8
- package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
- package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -28
- package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
- package/src/providers/integrations/antigravity/antigravity.ts +22 -13
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
- package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
- package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
- package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
- package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
- package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
- package/src/providers/integrations/claude/claude-cch.ts +148 -148
- package/src/providers/integrations/claude/fallback-credit.ts +3 -7
- package/src/providers/integrations/cline/cline.ts +1 -1
- package/src/providers/integrations/codex/codex-device-code.ts +101 -101
- package/src/providers/integrations/codex/codex-oauth.ts +0 -1
- package/src/providers/integrations/commandcode/commandcode.ts +75 -115
- package/src/providers/integrations/commandcode/quota.ts +131 -51
- package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
- package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
- package/src/providers/integrations/cursor/cursor-request.ts +0 -87
- package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
- package/src/providers/integrations/cursor/cursor.ts +35 -3
- package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
- package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
- package/src/providers/integrations/factory/factory.ts +9 -9
- package/src/providers/integrations/github/github-discovery.ts +70 -12
- package/src/providers/integrations/github/github-oauth.ts +184 -14
- package/src/providers/integrations/github/github.ts +134 -26
- package/src/providers/integrations/grok/grok-oauth.ts +261 -261
- package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
- package/src/providers/integrations/grok/grok-quota.ts +16 -7
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
- package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
- package/src/providers/integrations/grok/grok.ts +86 -36
- package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
- package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
- package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
- package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
- package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
- package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
- package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
- package/src/providers/integrations/kiro/kiro-request.ts +8 -11
- package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
- package/src/providers/integrations/kiro/kiro.ts +80 -68
- package/src/providers/integrations/muse/muse-oauth.ts +0 -1
- package/src/providers/integrations/muse/muse-quota.ts +0 -4
- package/src/providers/integrations/opencode/fingerprint.ts +7 -5
- package/src/providers/integrations/opencode/provider.ts +17 -24
- package/src/providers/integrations/qoder/qoder-catalog.ts +94 -11
- package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
- package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
- package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
- package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
- package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
- package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
- package/src/providers/integrations/qoder/qoder.ts +422 -71
- package/src/providers/integrations/shared/connect.ts +0 -54
- package/src/providers/integrations/shared/hash.ts +15 -0
- package/src/providers/integrations/shared/session-cache.ts +136 -0
- package/src/providers/integrations/trae/trae-cache.ts +7 -87
- package/src/providers/integrations/trae/trae-catalog.ts +1 -6
- package/src/providers/integrations/trae/trae-protocol.ts +17 -8
- package/src/providers/integrations/trae/trae-realm.ts +0 -7
- package/src/providers/integrations/trae/trae.ts +51 -8
- package/src/providers/integrations/xai/xai-oauth.ts +5 -5
- package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
- package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
- package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
- package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
- package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
- package/src/providers/operations/account-error-classification.ts +198 -133
- package/src/providers/operations/account-health-service.ts +31 -39
- package/src/providers/operations/account-reset-service.ts +58 -1
- package/src/providers/operations/byok-wire-profile.ts +19 -15
- package/src/providers/operations/cli-platform.ts +31 -5
- package/src/providers/operations/client-version-resolver.ts +4 -6
- package/src/providers/operations/client-versions.ts +10 -7
- package/src/providers/operations/provider-catalog-seeder.ts +2 -0
- package/src/providers/operations/provider-catalog-service.ts +18 -2
- package/src/providers/operations/provider-credential-service.ts +19 -2
- package/src/providers/provider-contracts.ts +18 -7
- package/src/providers/provider-metadata.ts +17 -2
- package/src/providers/provider-model-definition.ts +22 -1
- package/src/providers/provider-probe.ts +4 -2
- package/src/providers/provider-usage.ts +50 -19
- package/src/providers/quota/cache.ts +29 -0
- package/src/providers/quota/quota-contracts.ts +4 -0
- package/src/providers/quota/refresh.ts +27 -4
- package/src/providers/quota/snapshot.ts +94 -0
- package/src/providers/search/search-provider.ts +1 -3
- package/src/providers/search/search-providers.ts +2 -1
- package/src/security/abuse.ts +4 -4
- package/src/security/admission/service.ts +13 -6
- package/src/security/admission/ttl.ts +61 -61
- package/src/security/api-key-auth.ts +17 -3
- package/src/security/client-router-fingerprint.ts +4 -4
- package/src/security/credential-codec.ts +3 -3
- package/src/security/csrf.ts +2 -2
- package/src/security/ip-boundary.ts +16 -189
- package/src/security/model-access-rule.ts +1 -1
- package/src/security/outbound-headers.ts +18 -0
- package/src/shared/invoke-guard.ts +47 -0
- package/src/transport/contracts.ts +13 -4
- package/src/transport/dispatch/attempt-finalize.ts +70 -22
- package/src/transport/dispatch/attempt-loop.ts +22 -0
- package/src/transport/dispatch/capture-policy.ts +34 -37
- package/src/transport/dispatch/empty-stream.ts +23 -20
- package/src/transport/dispatch/generation.ts +25 -45
- package/src/transport/dispatch/native-shared.ts +127 -0
- package/src/transport/dispatch/proxy-request.ts +3 -1
- package/src/transport/dispatch/responses-compact.ts +25 -46
- package/src/transport/dispatch/streaming/encoder.ts +18 -72
- package/src/transport/dispatch/streaming/finalize.ts +2 -2
- package/src/transport/dispatch/streaming/stream.ts +7 -3
- package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
- package/src/transport/dispatch/systemone.ts +20 -48
- package/src/transport/dispatch/token-count.ts +41 -38
- package/src/transport/dispatch/websearch.ts +19 -45
- package/src/transport/drain-endpoint.ts +1 -1
- package/src/transport/failure-policy.ts +21 -1
- package/src/transport/guards/auth-guard.ts +0 -6
- package/src/transport/guards/body-policy.ts +3 -3
- package/src/transport/guards/error-lifecycle.ts +4 -0
- package/src/transport/guards/headroom-guard.ts +1 -1
- package/src/transport/guards/pipeline.ts +1 -1
- package/src/transport/guards/request-context.ts +12 -17
- package/src/transport/request/preparer.ts +286 -7
- package/src/transport/request/rtk/compress-request.ts +3 -3
- package/src/transport/request/rtk/rtk-constants.ts +2 -2
- package/src/transport/request/rtk/rtk-filters.ts +8 -8
- package/src/transport/request/state.ts +7 -13
- package/src/transport/request/system-prompt-injection.ts +74 -11
- package/src/transport/request/tenant-preferences.ts +22 -0
- package/src/transport/routing/candidate-index.ts +2 -2
- package/src/transport/routing/round-robin.ts +1 -1
- package/src/transport/routing/route-catalog.ts +17 -18
- package/src/transport/routing/route-model.ts +126 -33
- package/src/transport/routing/router.ts +159 -37
- package/src/transport/shutdown-notice.ts +2 -2
- package/src/transport/surface/adapters.ts +3 -3
- package/src/transport/surface/chat/encode.ts +7 -7
- package/src/transport/surface/chat/parse.ts +7 -7
- package/src/transport/surface/completion.ts +2 -2
- package/src/transport/surface/content-parts.ts +1 -1
- package/src/transport/surface/dialects.ts +2 -2
- package/src/transport/surface/messages/parse.ts +3 -3
- package/src/transport/surface/reasoning-summary.ts +9 -14
- package/src/transport/surface/responses/adapter.ts +1 -1
- package/src/transport/surface/responses/errors.ts +0 -9
- package/src/transport/vision-handoff-cache.ts +58 -0
- package/src/transport/vision-handoff.ts +431 -0
- package/src/workers/account-identity-sweep.ts +2 -2
- package/src/workers/buddy-growth-tasks.ts +392 -346
- package/src/workers/daily-checkin.ts +102 -49
- package/src/workers/maintenance-lease.ts +2 -35
- package/src/workers/oauth-refresh-sweep.ts +8 -1
- package/src/workers/quota-refresh-sweep.ts +120 -82
- package/src/workers/scheduler.ts +67 -4
- package/src/workers/sweep-runner.ts +24 -5
- package/src/workers/zcode-gift-claim.ts +108 -0
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
- package/dist/dashboard/assets/BannedPage-ChG5svFb.js +0 -1
- package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +0 -1
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +0 -1
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-U6AKaJcF.js +0 -1
- package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +0 -1
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
- package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
- package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
- package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
- package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
- package/dist/dashboard/assets/app-BayTTy01.js +0 -9
- package/dist/dashboard/assets/app-BayTTy01.js.gz +0 -0
- package/dist/dashboard/assets/app-a159k0ub.css +0 -2
- package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
- package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
- package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
- package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
- package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
- package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
- package/dist/dashboard/assets/dialog-8fiE6tec.js +0 -1
- package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSAsYsmV.js +0 -1
- package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
- package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
- package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
- package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
- package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
- package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-CPK47xQx.js +0 -1
- package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
- package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
- package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
- package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
- package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
- package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
- package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
- package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
- package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
- package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
- package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
- package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
- package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
- package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
- package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
- package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
- package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
- package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
- package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
- package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
- package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
- package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
- package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
- package/src/console/cli-tools/injectors/cline.ts +0 -110
- package/src/console/cli-tools/injectors/copilot.ts +0 -108
- package/src/console/cli-tools/injectors/cowork.ts +0 -64
- package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
- package/src/console/cli-tools/injectors/droid.ts +0 -96
- package/src/console/cli-tools/injectors/grok-build.ts +0 -70
- package/src/console/cli-tools/injectors/hermes.ts +0 -101
- package/src/console/cli-tools/injectors/jcode.ts +0 -115
- package/src/console/cli-tools/injectors/openclaw.ts +0 -161
- package/src/network/response-headers.ts +0 -39
- package/src/protocol/response/dsml.ts +0 -38
- package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
- /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
- /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
|
@@ -3,7 +3,15 @@ import type { CanonicalRequest } from "../../../../protocol/canonical-model";
|
|
|
3
3
|
import type { ProviderDispatchContext, ProviderDispatchTarget, ProviderId } from "../../../provider-contracts";
|
|
4
4
|
import { resolveInboundSessionId } from "../../../operations/session-resolution";
|
|
5
5
|
import { buddyConversationHeaders } from "../buddy-conversation-headers";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
buddyAgentPurpose,
|
|
8
|
+
buddyEnterprise,
|
|
9
|
+
buddyOAuthIdentityHeaders,
|
|
10
|
+
buddyPrivateData,
|
|
11
|
+
buddyUserId,
|
|
12
|
+
resolveBuddyDeviceBinding,
|
|
13
|
+
resolveBuddyIdentity,
|
|
14
|
+
} from "../buddy-identity";
|
|
7
15
|
import { buildCodeBuddyUserAgent, getCodeBuddyCnVersion, getCodeBuddyVersion } from "../../../operations/client-versions";
|
|
8
16
|
import { buddyDeviceTokenHeaders } from "../workbuddy/shared";
|
|
9
17
|
import { CODEBUDDY_TURING_CONFIG } from "../turing-device-token";
|
|
@@ -40,6 +48,13 @@ export async function codebuddyHeaders(
|
|
|
40
48
|
...(conversationId === undefined ? {} : { conversationId }),
|
|
41
49
|
});
|
|
42
50
|
if (resolveBuddyIdentity(context, cliIdentity) === "cli") {
|
|
51
|
+
const purpose = buddyAgentPurpose(context, request);
|
|
52
|
+
// Root/parent conversation context is forwarded only when the caller
|
|
53
|
+
// actually supplied it — the reference emits these conditionally for
|
|
54
|
+
// subagent/root chains and never invents them.
|
|
55
|
+
const inbound = context?.request_headers;
|
|
56
|
+
const rootRequestId = inbound?.["x-root-request-id"]?.trim();
|
|
57
|
+
const parentConversationId = inbound?.["x-parent-conversation-id"]?.trim();
|
|
43
58
|
return {
|
|
44
59
|
// The CLI sends `Accept: application/json` and no device token. It keeps
|
|
45
60
|
// the request-shape markers (`X-Requested-With`, `X-CodeBuddy-Request`)
|
|
@@ -55,19 +70,24 @@ export async function codebuddyHeaders(
|
|
|
55
70
|
"X-Domain": codebuddyDomain(variant),
|
|
56
71
|
"x-requested-with": "XMLHttpRequest",
|
|
57
72
|
"x-codebuddy-request": "1",
|
|
58
|
-
|
|
59
|
-
// verified against the live API that a request succeeds without it — but
|
|
60
|
-
// it is part of the client's real request, and matching the client is the
|
|
61
|
-
// defence against a channel check tightening later.
|
|
62
|
-
"X-Agent-Purpose": "conversation",
|
|
73
|
+
...(purpose === undefined ? {} : { "X-Agent-Purpose": purpose }),
|
|
63
74
|
...conversation,
|
|
75
|
+
...(rootRequestId === undefined ? {} : { "X-Root-Request-ID": rootRequestId }),
|
|
76
|
+
...(parentConversationId === undefined
|
|
77
|
+
? {}
|
|
78
|
+
: { "X-Parent-Conversation-ID": parentConversationId }),
|
|
64
79
|
...buddyCliTraceHeaders(conversation),
|
|
80
|
+
// The CLI's OAuth identity family: X-User-Id from the JWT sub plus the
|
|
81
|
+
// base64 X-Userinfo envelope when identity fields exist.
|
|
82
|
+
...buddyOAuthIdentityHeaders(context),
|
|
65
83
|
...buddyCliHeaders({
|
|
66
84
|
userId: buddyUserId(context),
|
|
67
85
|
enterpriseId: buddyEnterprise(context),
|
|
86
|
+
privateData: buddyPrivateData(context),
|
|
68
87
|
}),
|
|
69
88
|
};
|
|
70
89
|
}
|
|
90
|
+
const purpose = buddyAgentPurpose(context, request);
|
|
71
91
|
return {
|
|
72
92
|
accept: "text/event-stream",
|
|
73
93
|
"User-Agent": ua,
|
|
@@ -81,9 +101,10 @@ export async function codebuddyHeaders(
|
|
|
81
101
|
"X-Domain": codebuddyDomain(variant),
|
|
82
102
|
"x-requested-with": "XMLHttpRequest",
|
|
83
103
|
"x-codebuddy-request": "1",
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
104
|
+
// The effective agent purpose, matching the reference's dynamic value.
|
|
105
|
+
// The reference does not invent `conversation`; it sends the purpose only
|
|
106
|
+
// when one exists.
|
|
107
|
+
...(purpose === undefined ? {} : { "X-Agent-Purpose": purpose }),
|
|
87
108
|
// Same family WorkBuddy sends: the upstream's channel check reads the
|
|
88
109
|
// turn-level aggregation key, and a chat request without it is refused for a
|
|
89
110
|
// missing conversation id.
|
|
@@ -56,15 +56,11 @@ export const WORKBUDDY_BASE_URL = providerBaseUrl("workbuddy");
|
|
|
56
56
|
* channel"`. So this prompt is a wire contract, not merely a product choice —
|
|
57
57
|
* see the sibling in `codebuddy.ts`.
|
|
58
58
|
*
|
|
59
|
-
* The text is
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* neutral persona was accepted but diverged from every request the official
|
|
63
|
-
* desktop client emits.
|
|
59
|
+
* The text is deliberately neutral: a simple helpful-assistant persona with no
|
|
60
|
+
* client/CLI branding, kept minimal so it reads naturally to any model and
|
|
61
|
+
* does not advertise a channel identity upstream.
|
|
64
62
|
*/
|
|
65
|
-
export const WORKBUDDY_SYSTEM_PROMPT =
|
|
66
|
-
"You are WorkBuddy, a powerful AI assistant.\n\n" +
|
|
67
|
-
"Your main goal is to follow the USER's instructions at each message, denoted by the <user_query> tag.";
|
|
63
|
+
export const WORKBUDDY_SYSTEM_PROMPT = "You are a helpful assistant.";
|
|
68
64
|
|
|
69
65
|
/**
|
|
70
66
|
* Reconstructs generic function declarations when a later tool-history turn
|
|
@@ -156,7 +152,7 @@ export function workbuddyPrePayload(
|
|
|
156
152
|
// declared reasoning-effort scale.
|
|
157
153
|
const WORKBUDDY_RAW: readonly BuddyRawEntry[] = BUDDY_SHARED_RAW;
|
|
158
154
|
|
|
159
|
-
|
|
155
|
+
function makeWorkBuddyModels(providerId: "workbuddy" | "workbuddycn"): readonly ModelDefinition[] {
|
|
160
156
|
return [
|
|
161
157
|
...WORKBUDDY_RAW.filter(
|
|
162
158
|
(entry) => !BUDDY_IMAGE_MODEL_ID_SET.has(entry[0]) && !BUDDY_VIDEO_MODEL_ID_SET.has(entry[0]),
|
|
@@ -8,7 +8,15 @@ 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 {
|
|
11
|
+
import {
|
|
12
|
+
buddyAgentPurpose,
|
|
13
|
+
buddyEnterprise,
|
|
14
|
+
buddyOAuthIdentityHeaders,
|
|
15
|
+
buddyPrivateData,
|
|
16
|
+
buddyUserId,
|
|
17
|
+
resolveBuddyDeviceBinding,
|
|
18
|
+
resolveBuddyIdentity,
|
|
19
|
+
} from "../buddy-identity";
|
|
12
20
|
import {
|
|
13
21
|
buildWorkBuddyUserAgent,
|
|
14
22
|
getWorkBuddyClientVersion,
|
|
@@ -86,7 +94,11 @@ export async function workbuddyHeaders(
|
|
|
86
94
|
messageIdStyle: identity === "desktop" ? "uuid" : "hex",
|
|
87
95
|
});
|
|
88
96
|
const accountId = context?.credential.account_id;
|
|
97
|
+
const purpose = buddyAgentPurpose(context, request);
|
|
89
98
|
if (identity === "cli") {
|
|
99
|
+
const inbound = context?.request_headers;
|
|
100
|
+
const rootRequestId = inbound?.["x-root-request-id"]?.trim();
|
|
101
|
+
const parentConversationId = inbound?.["x-parent-conversation-id"]?.trim();
|
|
90
102
|
// The reference CLI: issued by the OpenAI Node SDK, so no browser
|
|
91
103
|
// *transport* header (origin/referer/accept-language) and no device token,
|
|
92
104
|
// and the machine/session device pair does not exist — only `X-User-Id`,
|
|
@@ -99,17 +111,23 @@ export async function workbuddyHeaders(
|
|
|
99
111
|
"x-requested-with": "XMLHttpRequest",
|
|
100
112
|
"x-codebuddy-request": "1",
|
|
101
113
|
"x-domain": domain,
|
|
102
|
-
"x-agent-purpose":
|
|
114
|
+
...(purpose === undefined ? {} : { "x-agent-purpose": purpose }),
|
|
103
115
|
"x-ide-name": "CLI",
|
|
104
116
|
"x-ide-type": "CLI",
|
|
105
117
|
"x-ide-version": getWorkBuddyCliVersion(),
|
|
106
118
|
"x-product": "SaaS",
|
|
107
119
|
"x-no-enterprise-id": "1",
|
|
108
120
|
...conversation,
|
|
121
|
+
...(rootRequestId === undefined ? {} : { "x-root-request-id": rootRequestId }),
|
|
122
|
+
...(parentConversationId === undefined
|
|
123
|
+
? {}
|
|
124
|
+
: { "x-parent-conversation-id": parentConversationId }),
|
|
109
125
|
...buddyCliTraceHeaders(conversation),
|
|
126
|
+
...buddyOAuthIdentityHeaders(context),
|
|
110
127
|
...buddyCliHeaders({
|
|
111
128
|
userId: buddyUserId(context),
|
|
112
129
|
enterpriseId: buddyEnterprise(context),
|
|
130
|
+
privateData: buddyPrivateData(context),
|
|
113
131
|
}),
|
|
114
132
|
};
|
|
115
133
|
}
|
|
@@ -122,7 +140,7 @@ export async function workbuddyHeaders(
|
|
|
122
140
|
"x-requested-with": "XMLHttpRequest",
|
|
123
141
|
"x-codebuddy-request": "1",
|
|
124
142
|
"x-domain": domain,
|
|
125
|
-
"x-agent-purpose":
|
|
143
|
+
...(purpose === undefined ? {} : { "x-agent-purpose": purpose }),
|
|
126
144
|
"x-ide-name": "WorkBuddy",
|
|
127
145
|
"x-ide-type": "WorkBuddy",
|
|
128
146
|
"x-ide-version": clientVersion,
|
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
|
|
3
|
-
const MASK = 0xffffffffffffffffn;
|
|
4
|
-
const PRIME1 = 0x9e3779b185ebca87n;
|
|
5
|
-
const PRIME2 = 0xc2b2ae3d27d4eb4fn;
|
|
6
|
-
const PRIME3 = 0x165667b19e3779f9n;
|
|
7
|
-
const PRIME4 = 0x85ebca77c2b2ae63n;
|
|
8
|
-
const PRIME5 = 0x27d4eb2f165667c5n;
|
|
9
|
-
const CCH_SEED = 0x4d659218e32a3268n;
|
|
10
|
-
const PLACEHOLDER = "cch=00000";
|
|
11
|
-
const encoder = new TextEncoder();
|
|
12
|
-
|
|
13
|
-
function round(acc: bigint, input: bigint): bigint {
|
|
14
|
-
let value = (acc + input * PRIME2) & MASK;
|
|
15
|
-
value = ((value << 31n) | (value >> 33n)) & MASK;
|
|
16
|
-
return (value * PRIME1) & MASK;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function mergeRound(acc: bigint, value: bigint): bigint {
|
|
20
|
-
let result = acc ^ round(0n, value);
|
|
21
|
-
return (result * PRIME1 + PRIME4) & MASK;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function read32(bytes: Uint8Array, offset: number): bigint {
|
|
25
|
-
return (
|
|
26
|
-
BigInt(bytes[offset] ?? 0) |
|
|
27
|
-
(BigInt(bytes[offset + 1] ?? 0) << 8n) |
|
|
28
|
-
(BigInt(bytes[offset + 2] ?? 0) << 16n) |
|
|
29
|
-
(BigInt(bytes[offset + 3] ?? 0) << 24n)
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function read64(bytes: Uint8Array, offset: number): bigint {
|
|
34
|
-
let value = 0n;
|
|
35
|
-
for (let index = 0; index < 8; index += 1)
|
|
36
|
-
value |= BigInt(bytes[offset + index] ?? 0) << BigInt(index * 8);
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function xxHash64(bytes: Uint8Array, seed: bigint): bigint {
|
|
41
|
-
let offset = 0;
|
|
42
|
-
let hash: bigint;
|
|
43
|
-
if (bytes.length >= 32) {
|
|
44
|
-
let v1 = (seed + PRIME1 + PRIME2) & MASK;
|
|
45
|
-
let v2 = (seed + PRIME2) & MASK;
|
|
46
|
-
let v3 = seed & MASK;
|
|
47
|
-
let v4 = (seed - PRIME1) & MASK;
|
|
48
|
-
while (offset <= bytes.length - 32) {
|
|
49
|
-
v1 = round(v1, read64(bytes, offset));
|
|
50
|
-
v2 = round(v2, read64(bytes, offset + 8));
|
|
51
|
-
v3 = round(v3, read64(bytes, offset + 16));
|
|
52
|
-
v4 = round(v4, read64(bytes, offset + 24));
|
|
53
|
-
offset += 32;
|
|
54
|
-
}
|
|
55
|
-
hash =
|
|
56
|
-
(((v1 << 1n) | (v1 >> 63n)) +
|
|
57
|
-
((v2 << 7n) | (v2 >> 57n)) +
|
|
58
|
-
((v3 << 12n) | (v3 >> 52n)) +
|
|
59
|
-
((v4 << 18n) | (v4 >> 46n))) &
|
|
60
|
-
MASK;
|
|
61
|
-
hash = mergeRound(hash, v1);
|
|
62
|
-
hash = mergeRound(hash, v2);
|
|
63
|
-
hash = mergeRound(hash, v3);
|
|
64
|
-
hash = mergeRound(hash, v4);
|
|
65
|
-
} else hash = (seed + PRIME5) & MASK;
|
|
66
|
-
hash = (hash + BigInt(bytes.length)) & MASK;
|
|
67
|
-
while (offset <= bytes.length - 8) {
|
|
68
|
-
const value = round(0n, read64(bytes, offset));
|
|
69
|
-
hash ^= value;
|
|
70
|
-
hash = (((hash << 27n) | (hash >> 37n)) * PRIME1 + PRIME4) & MASK;
|
|
71
|
-
offset += 8;
|
|
72
|
-
}
|
|
73
|
-
if (offset <= bytes.length - 4) {
|
|
74
|
-
hash ^= (read32(bytes, offset) * PRIME1) & MASK;
|
|
75
|
-
hash = (((hash << 23n) | (hash >> 41n)) * PRIME2 + PRIME3) & MASK;
|
|
76
|
-
offset += 4;
|
|
77
|
-
}
|
|
78
|
-
while (offset < bytes.length) {
|
|
79
|
-
hash ^= (BigInt(bytes[offset] ?? 0) * PRIME5) & MASK;
|
|
80
|
-
hash = (((hash << 11n) | (hash >> 53n)) * PRIME1) & MASK;
|
|
81
|
-
offset += 1;
|
|
82
|
-
}
|
|
83
|
-
hash ^= hash >> 33n;
|
|
84
|
-
hash = (hash * PRIME2) & MASK;
|
|
85
|
-
hash ^= hash >> 29n;
|
|
86
|
-
hash = (hash * PRIME3) & MASK;
|
|
87
|
-
return (hash ^ (hash >> 32n)) & MASK;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Computes Claude Code's five-hex-digit CCH from the exact outgoing body bytes. */
|
|
91
|
-
export function computeClaudeCch(body: Uint8Array): string {
|
|
92
|
-
return (xxHash64(body, CCH_SEED) & 0xfffffn).toString(16).padStart(5, "0");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** Replaces the anchored Claude billing placeholder in a mutable body before sending. */
|
|
96
|
-
export function patchClaudeCch(body: Uint8Array): boolean {
|
|
97
|
-
const marker = encoder.encode('"system":[{"type":"text","text":"x-anthropic-billing-header:');
|
|
98
|
-
const placeholder = encoder.encode(PLACEHOLDER);
|
|
99
|
-
let markerIndex = -1;
|
|
100
|
-
outer: for (let index = 0; index <= body.length - marker.length; index += 1) {
|
|
101
|
-
for (let j = 0; j < marker.length; j += 1) if (body[index + j] !== marker[j]) continue outer;
|
|
102
|
-
markerIndex = index;
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
if (markerIndex < 0) return false;
|
|
106
|
-
const start = markerIndex + marker.length;
|
|
107
|
-
const end = Math.min(body.length - placeholder.length, start + 150);
|
|
108
|
-
for (let index = start; index <= end; index += 1) {
|
|
109
|
-
let found = true;
|
|
110
|
-
for (let j = 0; j < placeholder.length; j += 1)
|
|
111
|
-
if (body[index + j] !== placeholder[j]) {
|
|
112
|
-
found = false;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
if (!found) continue;
|
|
116
|
-
const cch = encoder.encode(computeClaudeCch(body));
|
|
117
|
-
body.set(cch, index + 4);
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** Harness identity instruction, sent on OAuth dispatch. */
|
|
124
|
-
export const CLAUDE_CODE_SYSTEM_INSTRUCTION =
|
|
125
|
-
"You are Claude Code, Anthropic's official CLI for Claude.";
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Builds the billing header text with the captured version suffix:
|
|
129
|
-
* `cc_version={ver}.{sha256("59cf53e54c78" + chars + ver)[0:3]}` where
|
|
130
|
-
* chars are the 5th/8th/21st chars of the first user text (or "0" when
|
|
131
|
-
* absent). `cc_entrypoint=cli` matches the harness UA `(external, cli)`;
|
|
132
|
-
* an older snapshot used `claude-desktop`, which is unverified from local
|
|
133
|
-
* evidence, so cli is kept with this note.
|
|
134
|
-
*/
|
|
135
|
-
export function createClaudeBillingText(userText: string, version: string): string {
|
|
136
|
-
const chars = [4, 7, 20].map((index) => userText[index] ?? "0").join("");
|
|
137
|
-
const suffix = createHash("sha256")
|
|
138
|
-
.update(`59cf53e54c78${chars}${version}`)
|
|
139
|
-
.digest("hex")
|
|
140
|
-
.slice(0, 3);
|
|
141
|
-
return `x-anthropic-billing-header: cc_version=${version}.${suffix}; cc_entrypoint=cli; cch=00000;`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** Patches a string request body and returns its encoded bytes, or undefined when no billing block exists. */
|
|
145
|
-
export function patchClaudeCchBody(body: string): Uint8Array | undefined {
|
|
146
|
-
const bytes = encoder.encode(body);
|
|
147
|
-
return patchClaudeCch(bytes) ? bytes : undefined;
|
|
148
|
-
}
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
const MASK = 0xffffffffffffffffn;
|
|
4
|
+
const PRIME1 = 0x9e3779b185ebca87n;
|
|
5
|
+
const PRIME2 = 0xc2b2ae3d27d4eb4fn;
|
|
6
|
+
const PRIME3 = 0x165667b19e3779f9n;
|
|
7
|
+
const PRIME4 = 0x85ebca77c2b2ae63n;
|
|
8
|
+
const PRIME5 = 0x27d4eb2f165667c5n;
|
|
9
|
+
const CCH_SEED = 0x4d659218e32a3268n;
|
|
10
|
+
const PLACEHOLDER = "cch=00000";
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
|
|
13
|
+
function round(acc: bigint, input: bigint): bigint {
|
|
14
|
+
let value = (acc + input * PRIME2) & MASK;
|
|
15
|
+
value = ((value << 31n) | (value >> 33n)) & MASK;
|
|
16
|
+
return (value * PRIME1) & MASK;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function mergeRound(acc: bigint, value: bigint): bigint {
|
|
20
|
+
let result = acc ^ round(0n, value);
|
|
21
|
+
return (result * PRIME1 + PRIME4) & MASK;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function read32(bytes: Uint8Array, offset: number): bigint {
|
|
25
|
+
return (
|
|
26
|
+
BigInt(bytes[offset] ?? 0) |
|
|
27
|
+
(BigInt(bytes[offset + 1] ?? 0) << 8n) |
|
|
28
|
+
(BigInt(bytes[offset + 2] ?? 0) << 16n) |
|
|
29
|
+
(BigInt(bytes[offset + 3] ?? 0) << 24n)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function read64(bytes: Uint8Array, offset: number): bigint {
|
|
34
|
+
let value = 0n;
|
|
35
|
+
for (let index = 0; index < 8; index += 1)
|
|
36
|
+
value |= BigInt(bytes[offset + index] ?? 0) << BigInt(index * 8);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function xxHash64(bytes: Uint8Array, seed: bigint): bigint {
|
|
41
|
+
let offset = 0;
|
|
42
|
+
let hash: bigint;
|
|
43
|
+
if (bytes.length >= 32) {
|
|
44
|
+
let v1 = (seed + PRIME1 + PRIME2) & MASK;
|
|
45
|
+
let v2 = (seed + PRIME2) & MASK;
|
|
46
|
+
let v3 = seed & MASK;
|
|
47
|
+
let v4 = (seed - PRIME1) & MASK;
|
|
48
|
+
while (offset <= bytes.length - 32) {
|
|
49
|
+
v1 = round(v1, read64(bytes, offset));
|
|
50
|
+
v2 = round(v2, read64(bytes, offset + 8));
|
|
51
|
+
v3 = round(v3, read64(bytes, offset + 16));
|
|
52
|
+
v4 = round(v4, read64(bytes, offset + 24));
|
|
53
|
+
offset += 32;
|
|
54
|
+
}
|
|
55
|
+
hash =
|
|
56
|
+
(((v1 << 1n) | (v1 >> 63n)) +
|
|
57
|
+
((v2 << 7n) | (v2 >> 57n)) +
|
|
58
|
+
((v3 << 12n) | (v3 >> 52n)) +
|
|
59
|
+
((v4 << 18n) | (v4 >> 46n))) &
|
|
60
|
+
MASK;
|
|
61
|
+
hash = mergeRound(hash, v1);
|
|
62
|
+
hash = mergeRound(hash, v2);
|
|
63
|
+
hash = mergeRound(hash, v3);
|
|
64
|
+
hash = mergeRound(hash, v4);
|
|
65
|
+
} else hash = (seed + PRIME5) & MASK;
|
|
66
|
+
hash = (hash + BigInt(bytes.length)) & MASK;
|
|
67
|
+
while (offset <= bytes.length - 8) {
|
|
68
|
+
const value = round(0n, read64(bytes, offset));
|
|
69
|
+
hash ^= value;
|
|
70
|
+
hash = (((hash << 27n) | (hash >> 37n)) * PRIME1 + PRIME4) & MASK;
|
|
71
|
+
offset += 8;
|
|
72
|
+
}
|
|
73
|
+
if (offset <= bytes.length - 4) {
|
|
74
|
+
hash ^= (read32(bytes, offset) * PRIME1) & MASK;
|
|
75
|
+
hash = (((hash << 23n) | (hash >> 41n)) * PRIME2 + PRIME3) & MASK;
|
|
76
|
+
offset += 4;
|
|
77
|
+
}
|
|
78
|
+
while (offset < bytes.length) {
|
|
79
|
+
hash ^= (BigInt(bytes[offset] ?? 0) * PRIME5) & MASK;
|
|
80
|
+
hash = (((hash << 11n) | (hash >> 53n)) * PRIME1) & MASK;
|
|
81
|
+
offset += 1;
|
|
82
|
+
}
|
|
83
|
+
hash ^= hash >> 33n;
|
|
84
|
+
hash = (hash * PRIME2) & MASK;
|
|
85
|
+
hash ^= hash >> 29n;
|
|
86
|
+
hash = (hash * PRIME3) & MASK;
|
|
87
|
+
return (hash ^ (hash >> 32n)) & MASK;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Computes Claude Code's five-hex-digit CCH from the exact outgoing body bytes. */
|
|
91
|
+
export function computeClaudeCch(body: Uint8Array): string {
|
|
92
|
+
return (xxHash64(body, CCH_SEED) & 0xfffffn).toString(16).padStart(5, "0");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Replaces the anchored Claude billing placeholder in a mutable body before sending. */
|
|
96
|
+
export function patchClaudeCch(body: Uint8Array): boolean {
|
|
97
|
+
const marker = encoder.encode('"system":[{"type":"text","text":"x-anthropic-billing-header:');
|
|
98
|
+
const placeholder = encoder.encode(PLACEHOLDER);
|
|
99
|
+
let markerIndex = -1;
|
|
100
|
+
outer: for (let index = 0; index <= body.length - marker.length; index += 1) {
|
|
101
|
+
for (let j = 0; j < marker.length; j += 1) if (body[index + j] !== marker[j]) continue outer;
|
|
102
|
+
markerIndex = index;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
if (markerIndex < 0) return false;
|
|
106
|
+
const start = markerIndex + marker.length;
|
|
107
|
+
const end = Math.min(body.length - placeholder.length, start + 150);
|
|
108
|
+
for (let index = start; index <= end; index += 1) {
|
|
109
|
+
let found = true;
|
|
110
|
+
for (let j = 0; j < placeholder.length; j += 1)
|
|
111
|
+
if (body[index + j] !== placeholder[j]) {
|
|
112
|
+
found = false;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
if (!found) continue;
|
|
116
|
+
const cch = encoder.encode(computeClaudeCch(body));
|
|
117
|
+
body.set(cch, index + 4);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Harness identity instruction, sent on OAuth dispatch. */
|
|
124
|
+
export const CLAUDE_CODE_SYSTEM_INSTRUCTION =
|
|
125
|
+
"You are Claude Code, Anthropic's official CLI for Claude.";
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Builds the billing header text with the captured version suffix:
|
|
129
|
+
* `cc_version={ver}.{sha256("59cf53e54c78" + chars + ver)[0:3]}` where
|
|
130
|
+
* chars are the 5th/8th/21st chars of the first user text (or "0" when
|
|
131
|
+
* absent). `cc_entrypoint=cli` matches the harness UA `(external, cli)`;
|
|
132
|
+
* an older snapshot used `claude-desktop`, which is unverified from local
|
|
133
|
+
* evidence, so cli is kept with this note.
|
|
134
|
+
*/
|
|
135
|
+
export function createClaudeBillingText(userText: string, version: string): string {
|
|
136
|
+
const chars = [4, 7, 20].map((index) => userText[index] ?? "0").join("");
|
|
137
|
+
const suffix = createHash("sha256")
|
|
138
|
+
.update(`59cf53e54c78${chars}${version}`)
|
|
139
|
+
.digest("hex")
|
|
140
|
+
.slice(0, 3);
|
|
141
|
+
return `x-anthropic-billing-header: cc_version=${version}.${suffix}; cc_entrypoint=cli; cch=00000;`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Patches a string request body and returns its encoded bytes, or undefined when no billing block exists. */
|
|
145
|
+
export function patchClaudeCchBody(body: string): Uint8Array | undefined {
|
|
146
|
+
const bytes = encoder.encode(body);
|
|
147
|
+
return patchClaudeCch(bytes) ? bytes : undefined;
|
|
148
|
+
}
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { GatewayError } from "../../../protocol/gateway-error";
|
|
30
|
+
import { fnv1a32 } from "../shared/hash";
|
|
30
31
|
|
|
31
32
|
const CREDIT_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
32
33
|
const MAX_CACHE_SIZE = 64;
|
|
@@ -122,15 +123,10 @@ export class FallbackCreditCache {
|
|
|
122
123
|
|
|
123
124
|
/**
|
|
124
125
|
* Compute a simple hash of the request body for cache keying.
|
|
125
|
-
*
|
|
126
|
+
* FNV-1a — fast, deterministic, sufficient for cache identity.
|
|
126
127
|
*/
|
|
127
128
|
export function hashBody(body: string): string {
|
|
128
|
-
|
|
129
|
-
for (let i = 0; i < body.length; i++) {
|
|
130
|
-
hash ^= body.charCodeAt(i);
|
|
131
|
-
hash = Math.imul(hash, 0x01000193);
|
|
132
|
-
}
|
|
133
|
-
return (hash >>> 0).toString(36);
|
|
129
|
+
return fnv1a32(body).toString(36);
|
|
134
130
|
}
|
|
135
131
|
|
|
136
132
|
// Shared process-wide cache instance
|