cartethyia 2.7.8 → 2.8.0
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 +3 -3
- package/README.md +29 -59
- package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js +1 -0
- package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BRWKPQPf.js → CliToolDetailPage-Bqj2aa1T.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BP-Y5iHN.js → CliToolsPage-CXsaOAO2.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js +1 -0
- package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js +1 -0
- package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
- package/dist/dashboard/assets/{InjectSystemPromptPanel-Cv-2Ol_K.js → InjectSystemPromptPanel-BWFLECmz.js} +2 -2
- package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-bKfz_b1K.js → LoginPage-CgoPc5B9.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-B-WQxx_H.js → ModelPicker-D9bFQern.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js +1 -0
- package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +8 -0
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-emlTuxz6.js → ProxyPage-BwNC_-Cx.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js +1 -0
- package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CctTga2C.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-CUZrKs9r.js → SetupPage-febLU4r1.js} +1 -1
- package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-jWmUdDpy.js → StudioPage-M6fvR5Wz.js} +1 -1
- package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-nyeuRqz9.js +56 -0
- package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BFOlvrJC.js +1 -0
- package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
- package/dist/dashboard/assets/app-Dx2QgsNj.css +2 -0
- package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
- package/dist/dashboard/assets/{assert-CidQVoNo.js → assert-CqTLw5e7.js} +1 -1
- package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
- package/dist/dashboard/assets/{badge-DyI_mJfi.js → badge-C83EqLB0.js} +1 -1
- package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
- package/dist/dashboard/assets/ban-durations-B58FyRxC.js +1 -0
- package/dist/dashboard/assets/ban-durations-B58FyRxC.js.gz +0 -0
- package/dist/dashboard/assets/{banner-B-yXtCqb.js → banner-D1xn7pIe.js} +1 -1
- package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
- package/dist/dashboard/assets/brand/bansos_page.webp +0 -0
- package/dist/dashboard/assets/brand/denia_bansos.webp +0 -0
- package/dist/dashboard/assets/brand/favicon.webp +0 -0
- package/dist/dashboard/assets/brand/login_register.webp +0 -0
- package/dist/dashboard/assets/brand/login_register_initial.webp +0 -0
- package/dist/dashboard/assets/brand/og_bansos.webp +0 -0
- package/dist/dashboard/assets/brand/og_image.webp +0 -0
- package/dist/dashboard/assets/brand/sidebar_ico.webp +0 -0
- package/dist/dashboard/assets/{card-_HwAEqFF.js → card-DU3Lq5Lm.js} +1 -1
- package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-Dw1U_drK.js +1 -0
- package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-ByjCk0o9.js → clipboard-button-CEL5Sg_J.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BZhOlfz-.js → dialog-BjFR5UHy.js} +1 -1
- package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-BADqIRYP.js → drawer-HvBW0AjI.js} +1 -1
- package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSu3gFlt.js +4 -0
- package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
- package/dist/dashboard/assets/{entry-COaC-irN.js → entry-CECVELyy.js} +1 -1
- package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
- package/dist/dashboard/assets/entry-DYYofQ7W.js +1 -0
- package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-DcHJyRiu.js → formatters-DLW4i8zK.js} +1 -1
- package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
- package/dist/dashboard/assets/{index-CgKmFngv.js → index-1-fCqe64.js} +2 -2
- package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
- package/dist/dashboard/assets/{inline-B2BirKry.js → inline-DGvU2oLK.js} +1 -1
- package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
- package/dist/dashboard/assets/{input-D-qV9dKY.js → input-iNnO1X2K.js} +1 -1
- package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
- package/dist/dashboard/assets/{layout-B7tVWhtV.js → layout-0q8UGypb.js} +1 -1
- package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-CtkGE3bF.js → list-row-C0w2bQjJ.js} +1 -1
- package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
- package/dist/dashboard/assets/{live-DGizF06-.js → live-M5aJ_xCa.js} +1 -1
- package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-GU7XdEjz.js → mutation-BQ0ccH_A.js} +1 -1
- package/dist/dashboard/assets/mutation-BQ0ccH_A.js.gz +0 -0
- package/dist/dashboard/assets/{network-C9UE-bOr.js → network-BKeQGT3K.js} +1 -1
- package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-BnAd22a_.js → numbers-CivAk3da.js} +1 -1
- package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
- package/dist/dashboard/assets/{pagination-BAywyMzS.js → pagination-CpzvI5ep.js} +1 -1
- package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
- package/dist/dashboard/assets/providers/devin.svg +9 -0
- package/dist/dashboard/assets/providers/devin.svg.gz +0 -0
- package/dist/dashboard/assets/providers/windsurf.svg +10 -0
- package/dist/dashboard/assets/providers/windsurf.svg.gz +0 -0
- package/dist/dashboard/assets/providers/zro.svg +3 -0
- package/dist/dashboard/assets/providers/zro.svg.gz +0 -0
- package/dist/dashboard/assets/{query-keys-YSoQOUh6.js → query-keys-IKLh0YFd.js} +1 -1
- package/dist/dashboard/assets/query-keys-IKLh0YFd.js.gz +0 -0
- package/dist/dashboard/assets/quota-DiPD6UKH.js +1 -0
- package/dist/dashboard/assets/quota-DiPD6UKH.js.gz +0 -0
- package/dist/dashboard/assets/routing-BFQX2VBc.js +1 -0
- package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
- package/dist/dashboard/assets/{select-BCOcv8WK.js → select-CXbck0jG.js} +2 -2
- package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
- package/dist/dashboard/assets/settings-C_XvMHh9.js +1 -0
- package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
- package/dist/dashboard/assets/{stack-ByKt3Q1g.js → stack-DggRiCxE.js} +1 -1
- package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
- package/dist/dashboard/assets/{state-DXbGTx7N.js → state-ClFzfbYp.js} +1 -1
- package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
- package/dist/dashboard/assets/story/25817331.webp +0 -0
- package/dist/dashboard/assets/story/Shorekeeper.webp +0 -0
- package/dist/dashboard/assets/story/cartethyia-god.webp +0 -0
- package/dist/dashboard/assets/story/fleurdelys_plus.webp +0 -0
- package/dist/dashboard/assets/story/jinhsi-blossom.webp +0 -0
- package/dist/dashboard/assets/story/phrolova-a.webp +0 -0
- package/dist/dashboard/assets/story/requestdeniawokkjpg.webp +0 -0
- package/dist/dashboard/assets/story/wuthering-waves-hiyuki-aemeath-hiyuki-rover.webp +0 -0
- package/dist/dashboard/assets/{switch-ZeTsW623.js → switch-CTIFxKqS.js} +1 -1
- package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-CbCP4w1o.js → useMutation-BClG3yWj.js} +1 -1
- package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.webp +0 -0
- package/dist/dashboard/console-backgrounds_initial.webp +0 -0
- package/dist/dashboard/donation/qris-risun-marke.webp +0 -0
- package/dist/dashboard/index.html +3 -3
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +59 -56
- package/migrations/full-postgres/0044_add_models_warning_metadata.sql +10 -0
- package/migrations/full-postgres/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
- package/migrations/full-postgres/0046_add_accounts_quota_plan_fetched_at.sql +7 -0
- package/migrations/lite-sqlite3/0044_add_models_warning_metadata.sql +11 -0
- package/migrations/lite-sqlite3/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
- package/migrations/lite-sqlite3/0046_add_accounts_quota_plan_fetched_at.sql +4 -0
- package/package.json +1 -1
- package/src/boot/app.ts +10 -13
- package/src/boot/dependencies.ts +12 -4
- package/src/boot/flush.ts +20 -0
- package/src/boot/lifecycle.ts +7 -5
- package/src/config/cooldowns.ts +1 -1
- package/src/config/routing.ts +26 -0
- package/src/config/spec-metadata.ts +72 -0
- package/src/config/spec.ts +20 -6
- package/src/console/api-keys/contracts.ts +12 -1
- package/src/console/api-keys/routes.ts +50 -31
- package/src/console/auth/account-reset.ts +7 -9
- package/src/console/backup/contracts.ts +4 -0
- package/src/console/backup/export-endpoint.ts +7 -5
- package/src/console/cli-tools/service.ts +6 -12
- package/src/console/console-router-guards.ts +23 -16
- package/src/console/console-router.ts +7 -0
- package/src/console/dashboard-assets.ts +5 -5
- package/src/console/domain-registration.ts +27 -2
- package/src/console/inferhub/normalize.ts +24 -28
- package/src/console/inferhub/types.ts +3 -0
- package/src/console/ip-bans/routes.ts +93 -0
- package/src/console/observability/store.ts +0 -53
- package/src/console/providers/catalog/catalog-projections.ts +5 -2
- package/src/console/providers/catalog/contracts.ts +123 -0
- package/src/console/providers/catalog/discover-constants.ts +6 -0
- package/src/console/providers/catalog/model-operations.ts +122 -10
- package/src/console/providers/catalog/provider-operations.ts +116 -8
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +65 -4
- package/src/console/providers/catalog/store-helpers.ts +30 -1
- package/src/console/providers/catalog/store.ts +249 -4
- package/src/console/quota/account-quota-global.ts +97 -19
- package/src/console/quota/account-quota-shared.ts +49 -0
- package/src/console/quota/account-quota-tenant.ts +6 -18
- package/src/console/quota/native-identity.ts +2 -0
- package/src/console/quota/quota-view.ts +19 -3
- package/src/console/routing/pools/operations.ts +31 -46
- package/src/console/settings/contracts.ts +18 -0
- package/src/console/settings/store.ts +32 -0
- package/src/console/shared/errors.ts +33 -6
- package/src/console/system-prompt/contracts.ts +0 -1
- package/src/main.ts +3 -3
- package/src/network/pool/byte-accounting.ts +3 -2
- package/src/network/pool/selector.ts +182 -39
- package/src/network/pool-cooldown-store.ts +89 -14
- package/src/network/pool-health.ts +49 -61
- package/src/network/rate-limit-verdict.ts +1 -1
- package/src/network/ssrf.ts +6 -6
- package/src/observability/event-log.ts +7 -361
- package/src/observability/event-query.ts +18 -4
- package/src/observability/performance-metrics.ts +9 -0
- package/src/observability/runtime-metrics.ts +14 -9
- package/src/observability/telemetry-buffer.ts +15 -25
- package/src/observability/telemetry-reconciliation.ts +9 -37
- package/src/observability/telemetry-row.ts +125 -0
- package/src/persistence/db-mode.ts +4 -1
- package/src/persistence/dialect.ts +30 -0
- package/src/persistence/migrate.ts +6 -3
- package/src/persistence/schema.ts +28 -2
- package/src/persistence/ttl-cache.ts +20 -2
- package/src/protocol/codecs.ts +1 -1
- package/src/protocol/dsml.ts +35 -87
- package/src/protocol/gateway-error.ts +1 -0
- package/src/protocol/markup-stream-parser.ts +195 -0
- package/src/protocol/reasoning-text.ts +19 -0
- package/src/protocol/reasoning.ts +1 -1
- package/src/protocol/request/chat.ts +14 -14
- package/src/protocol/request/gemini.ts +8 -2
- package/src/protocol/request/messages.ts +4 -5
- package/src/protocol/response/chat.ts +12 -20
- package/src/protocol/response/gemini.ts +6 -1
- package/src/protocol/response/omp-tool-call-markup.ts +43 -86
- package/src/protocol/response/responses.ts +18 -2
- package/src/protocol/sse-decoder.ts +25 -8
- package/src/protocol/stop-reason.ts +23 -1
- package/src/protocol/stream-error-frames.ts +13 -3
- package/src/protocol/think-split.ts +112 -0
- package/src/protocol/translation/dialect/qwen.ts +26 -58
- package/src/protocol/translation/quirks.ts +1 -1
- package/src/protocol/translation/tool-repair.ts +2 -2
- package/src/protocol/upstream/send-claude-messages.ts +15 -4
- package/src/protocol/upstream-parsing.ts +1 -1
- package/src/providers/adapters/compatible-adapter.ts +78 -17
- package/src/providers/authentication/oauth-client.ts +1 -1
- package/src/providers/authentication/oauth-device-flow.ts +98 -8
- package/src/providers/authentication/oauth-refresh-service.ts +153 -59
- package/src/providers/configured-provider.ts +148 -0
- package/src/providers/default-registry.ts +117 -27
- package/src/providers/discovery/discovery-types.ts +12 -0
- package/src/providers/discovery/probe-phases.ts +74 -33
- package/src/providers/discovery/probing-service.ts +293 -165
- package/src/providers/integrations/alibabacp/alibabacp-models.ts +1 -2
- package/src/providers/integrations/{dashscope-models.ts → alibabacp/dashscope-models.ts} +2 -2
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +121 -2
- package/src/providers/integrations/antigravity/antigravity.ts +13 -2
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +72 -34
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +191 -35
- package/src/providers/integrations/buddy/buddy-checkin.ts +17 -39
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +2 -2
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +5 -5
- package/src/providers/integrations/buddy/buddy-identity.ts +89 -6
- package/src/providers/integrations/buddy/buddy-media.ts +4 -5
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +2 -2
- package/src/providers/integrations/buddy/buddy-quota-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-usage-shared.ts +1 -3
- package/src/providers/integrations/buddy/capabilities.ts +6 -43
- package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +2 -1
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +23 -1
- package/src/providers/integrations/buddy/codebuddy/provider.ts +6 -2
- package/src/providers/integrations/buddy/codebuddy/shared.ts +38 -27
- package/src/providers/integrations/claude/claude-quota.ts +14 -17
- package/src/providers/integrations/cline/cline.ts +2 -2
- package/src/providers/integrations/commandcode/quota.ts +22 -28
- package/src/providers/integrations/cursor/cursor-auth.ts +0 -8
- package/src/providers/integrations/cursor/cursor-catalog.ts +2 -0
- package/src/providers/integrations/cursor/cursor-exec.ts +745 -0
- package/src/providers/integrations/cursor/cursor-http2.ts +2 -0
- package/src/providers/integrations/cursor/cursor-request.ts +35 -20
- package/src/providers/integrations/cursor/cursor-shared.ts +26 -5
- package/src/providers/integrations/cursor/cursor.ts +139 -70
- package/src/providers/integrations/cursor/protocol/messages.ts +22 -29
- package/src/providers/integrations/cursor/protocol/protobuf-schema.ts +37 -0
- package/src/providers/integrations/cursor/protocol/tool-canonical.ts +26 -100
- package/src/providers/integrations/devin/devin-auth.ts +353 -0
- package/src/providers/integrations/devin/devin-catalog.ts +207 -0
- package/src/providers/integrations/devin/devin-http.ts +91 -0
- package/src/providers/integrations/devin/devin-quota.ts +214 -0
- package/src/providers/integrations/devin/devin-shared.ts +111 -0
- package/src/providers/integrations/devin/devin.ts +539 -0
- package/src/providers/integrations/devin/protocol/devin-proto.ts +558 -0
- package/src/providers/integrations/devin/protocol/framing.ts +124 -0
- package/src/providers/integrations/factory/factory-oauth.ts +17 -44
- package/src/providers/integrations/factory/factory.ts +2 -2
- package/src/providers/integrations/freebuff/assets/official-system-manager.txt +88 -0
- package/src/providers/integrations/freebuff/assets/official-system-worker.txt +57 -0
- package/src/providers/integrations/freebuff/assets/official-tools.json +1070 -0
- package/src/providers/integrations/freebuff/freebuff-catalog.ts +120 -0
- package/src/providers/integrations/freebuff/freebuff-constants.ts +1233 -0
- package/src/providers/integrations/freebuff/freebuff-discovery.ts +108 -0
- package/src/providers/integrations/freebuff/freebuff-oauth.ts +240 -0
- package/src/providers/integrations/freebuff/freebuff-quota.ts +260 -0
- package/src/providers/integrations/freebuff/freebuff-virtual.ts +89 -0
- package/src/providers/integrations/freebuff/freebuff.ts +682 -0
- package/src/providers/integrations/freepi/freepi-catalog.ts +60 -0
- package/src/providers/integrations/freepi/freepi-discovery.ts +82 -0
- package/src/providers/integrations/freepi/freepi-headers.ts +21 -0
- package/src/providers/integrations/freepi/freepi-oauth.ts +142 -0
- package/src/providers/integrations/freepi/freepi-protocol.ts +242 -0
- package/src/providers/integrations/freepi/freepi-quota.ts +126 -0
- package/src/providers/integrations/freepi/freepi-realm.ts +35 -0
- package/src/providers/integrations/freepi/freepi.ts +292 -0
- package/src/providers/integrations/gemini.ts +2 -2
- package/src/providers/integrations/grok/grok-oauth.ts +48 -45
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +10 -17
- package/src/providers/integrations/grok/grok-turn-index.ts +11 -16
- package/src/providers/integrations/hermes/hermes-oauth.ts +94 -0
- package/src/providers/integrations/{hermes.ts → hermes/hermes.ts} +13 -21
- package/src/providers/integrations/hermes/index.ts +2 -0
- package/src/providers/integrations/kiro/kiro-catalog.ts +17 -1
- package/src/providers/integrations/kiro/kiro-discovery.ts +10 -12
- package/src/providers/integrations/kiro/kiro-quota.ts +8 -4
- package/src/providers/integrations/kiro/kiro.ts +15 -19
- package/src/providers/integrations/ollamacloud/index.ts +2 -0
- package/src/providers/integrations/{ollamacloud-models.ts → ollamacloud/models.ts} +2 -2
- package/src/providers/integrations/{ollamacloud-quota.ts → ollamacloud/quota.ts} +3 -3
- package/src/providers/integrations/opencode/fingerprint.ts +1 -1
- package/src/providers/integrations/opencode/opencode-go-quota.ts +2 -8
- package/src/providers/integrations/perch/perch-catalog.ts +105 -0
- package/src/providers/integrations/perch/perch-credential.ts +25 -0
- package/src/providers/integrations/perch/perch-oauth.ts +170 -0
- package/src/providers/integrations/perch/perch-protocol.ts +208 -0
- package/src/providers/integrations/perch/perch-quota.ts +123 -0
- package/src/providers/integrations/perch/perch-realm.ts +82 -0
- package/src/providers/integrations/perch/perch-system-prompt.ts +13 -0
- package/src/providers/integrations/perch/perch.ts +305 -0
- package/src/providers/integrations/perch/saffron-system-prompt.txt +8 -0
- package/src/providers/integrations/qoder/chat-proto.ts +328 -328
- package/src/providers/integrations/qoder/claim-qoder-credits.ts +19 -60
- package/src/providers/integrations/qoder/qoder-adapter.ts +90 -40
- package/src/providers/integrations/qoder/qoder-auth.ts +101 -29
- package/src/providers/integrations/qoder/qoder-cache.ts +32 -0
- package/src/providers/integrations/qoder/qoder-catalog.ts +26 -6
- package/src/providers/integrations/qoder/qoder-chat.ts +7 -21
- package/src/providers/integrations/qoder/qoder-checkin.ts +6 -6
- package/src/providers/integrations/qoder/qoder-grpc.ts +210 -7
- package/src/providers/integrations/qoder/qoder-ide.ts +5 -108
- package/src/providers/integrations/qoder/qoder-identity-cache.ts +184 -0
- package/src/providers/integrations/qoder/qoder-native-identity-store.ts +83 -18
- package/src/providers/integrations/qoder/qoder-realm.ts +9 -6
- package/src/providers/integrations/qoder/qoder-umid.ts +109 -342
- package/src/providers/integrations/qoder/qoder-virtual.ts +33 -1
- package/src/providers/integrations/qoder/qoder.ts +3 -7
- package/src/providers/integrations/trae/trae-catalog.ts +9 -14
- package/src/providers/integrations/trae/trae-headers.ts +36 -11
- package/src/providers/integrations/trae/trae-oauth.ts +14 -17
- package/src/providers/integrations/trae/trae-protocol.ts +12 -11
- package/src/providers/integrations/trae/trae-quota.ts +96 -36
- package/src/providers/integrations/trae/trae-realm.ts +74 -15
- package/src/providers/integrations/trae/trae.ts +99 -26
- package/src/providers/integrations/zcode-start-plan/provider.ts +226 -23
- package/src/providers/integrations/zcode-start-plan/quota.ts +19 -2
- package/src/providers/integrations/zro/zro.ts +204 -0
- package/src/providers/operations/account-error-classification.ts +235 -278
- package/src/providers/operations/account-health-service.ts +273 -26
- package/src/providers/operations/account-refresh-status.ts +269 -0
- package/src/providers/operations/account-tier.ts +66 -0
- package/src/providers/operations/client-version-resolver.ts +1 -1
- package/src/providers/operations/client-versions.ts +42 -150
- package/src/providers/operations/cooldown-rules.ts +56 -0
- package/src/providers/operations/{model-catalog-cache.ts → provider-caches.ts} +68 -16
- package/src/providers/operations/provider-catalog-seeder.ts +4 -0
- package/src/providers/operations/provider-catalog-service.ts +1 -1
- package/src/providers/operations/provider-credential-service.ts +102 -32
- package/src/providers/operations/provider-rules/github.ts +48 -0
- package/src/providers/operations/provider-rules/grok.ts +33 -0
- package/src/providers/operations/provider-rules/inception.ts +49 -0
- package/src/providers/operations/provider-rules/index.ts +32 -0
- package/src/providers/operations/provider-rules/perch.ts +37 -0
- package/src/providers/operations/provider-rules/qoder.ts +70 -0
- package/src/providers/operations/provider-rules/trae.ts +81 -0
- package/src/providers/provider-contracts.ts +33 -2
- package/src/providers/{provider-credential-resolver.ts → provider-credentials.ts} +40 -3
- package/src/providers/provider-metadata.ts +99 -14
- package/src/providers/provider-model-definition.ts +36 -0
- package/src/providers/provider-probe.ts +15 -1
- package/src/providers/provider-registry.ts +42 -33
- package/src/providers/quota/quota-limit-windows.ts +16 -5
- package/src/providers/quota/quota-support.ts +1 -1
- package/src/providers/quota/quota-window-parser.ts +90 -18
- package/src/providers/quota/refresh.ts +96 -18
- package/src/security/abuse.ts +71 -0
- package/src/security/api-key-auth-cache.ts +1 -1
- package/src/security/api-key-auth.ts +6 -2
- package/src/transport/dispatch/attempt-finalize.ts +14 -13
- package/src/transport/dispatch/attempt-loop.ts +71 -17
- package/src/transport/dispatch/generation.ts +2 -8
- package/src/transport/dispatch/native-shared.ts +25 -0
- package/src/transport/dispatch/proxy-request.ts +9 -46
- package/src/transport/dispatch/responses-compact.ts +2 -8
- package/src/transport/dispatch/streaming/finalize.ts +9 -6
- package/src/transport/dispatch/streaming/stream.ts +9 -36
- package/src/transport/dispatch/systemone.ts +2 -8
- package/src/transport/dispatch/token-count.ts +2 -6
- package/src/transport/dispatch/upstream.ts +67 -1
- package/src/transport/drain-endpoint.ts +31 -4
- package/src/transport/failure-policy.ts +129 -37
- package/src/transport/guards/body-policy.ts +7 -1
- package/src/transport/guards/error-lifecycle.ts +13 -1
- package/src/transport/guards/request-context.ts +22 -14
- package/src/transport/request/preparer.ts +81 -71
- package/src/transport/routing/bounded-lru.ts +14 -0
- package/src/transport/routing/drain-reserve.ts +129 -0
- package/src/transport/routing/plan-gate.ts +7 -1
- package/src/transport/routing/round-robin.ts +60 -0
- package/src/transport/routing/route-catalog.ts +123 -111
- package/src/transport/routing/route-model.ts +51 -9
- package/src/transport/routing/router.ts +418 -33
- package/src/transport/surface/adapters.ts +11 -2
- package/src/transport/surface/chat/adapter.ts +2 -2
- package/src/transport/surface/chat/encode.ts +47 -4
- package/src/transport/surface/chat/parse.ts +2 -12
- package/src/transport/surface/completion.ts +44 -33
- package/src/transport/surface/content-parts.ts +21 -0
- package/src/transport/surface/messages/adapter.ts +9 -2
- package/src/transport/surface/messages/encode.ts +11 -3
- package/src/transport/surface/messages/parse.ts +2 -1
- package/src/transport/surface/messages/stream.ts +33 -17
- package/src/transport/surface/responses/encode.ts +34 -6
- package/src/transport/surface/responses/parse.ts +3 -11
- package/src/workers/daily-checkin.ts +1 -1
- package/src/workers/quota-refresh-sweep.ts +1 -1
- package/src/workers/scheduler.ts +22 -4
- package/dist/dashboard/assets/BannedPage-DeIbIiBU.js +0 -1
- package/dist/dashboard/assets/BannedPage-DeIbIiBU.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BRWKPQPf.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-BP-Y5iHN.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-B7JHozVa.js +0 -1
- package/dist/dashboard/assets/CombosPage-B7JHozVa.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js +0 -1
- package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-Cv-2Ol_K.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-bKfz_b1K.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-B-WQxx_H.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js +0 -1
- package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js +0 -7
- package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-emlTuxz6.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CMJKNYWb.js +0 -1
- package/dist/dashboard/assets/QuotaPage-CMJKNYWb.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js +0 -1
- package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-CUZrKs9r.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-jWmUdDpy.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-5F9tGVGG.js +0 -56
- package/dist/dashboard/assets/UsagePage-5F9tGVGG.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-KvX83mRe.js +0 -1
- package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
- package/dist/dashboard/assets/app-BEsU8hKs.css +0 -2
- package/dist/dashboard/assets/app-BEsU8hKs.css.gz +0 -0
- package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
- package/dist/dashboard/assets/badge-DyI_mJfi.js.gz +0 -0
- package/dist/dashboard/assets/banner-B-yXtCqb.js.gz +0 -0
- package/dist/dashboard/assets/brand/bansos_page.png +0 -0
- package/dist/dashboard/assets/brand/denia_bansos.jpg +0 -0
- package/dist/dashboard/assets/brand/favicon.jpg +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/brand/sidebar_ico.jpg +0 -0
- package/dist/dashboard/assets/card-_HwAEqFF.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +0 -1
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-ByjCk0o9.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BZhOlfz-.js.gz +0 -0
- package/dist/dashboard/assets/drawer-BADqIRYP.js.gz +0 -0
- package/dist/dashboard/assets/entry-COaC-irN.js.gz +0 -0
- package/dist/dashboard/assets/entry-Ca7LSCet.js +0 -4
- package/dist/dashboard/assets/entry-Ca7LSCet.js.gz +0 -0
- package/dist/dashboard/assets/entry-PDd27uCd.js +0 -1
- package/dist/dashboard/assets/entry-PDd27uCd.js.gz +0 -0
- package/dist/dashboard/assets/formatters-DcHJyRiu.js.gz +0 -0
- package/dist/dashboard/assets/index-CgKmFngv.js.gz +0 -0
- package/dist/dashboard/assets/inline-B2BirKry.js.gz +0 -0
- package/dist/dashboard/assets/input-D-qV9dKY.js.gz +0 -0
- package/dist/dashboard/assets/layout-B7tVWhtV.js.gz +0 -0
- package/dist/dashboard/assets/list-row-CtkGE3bF.js.gz +0 -0
- package/dist/dashboard/assets/live-DGizF06-.js.gz +0 -0
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +0 -1
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
- package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
- package/dist/dashboard/assets/network-C9UE-bOr.js.gz +0 -0
- package/dist/dashboard/assets/numbers-BnAd22a_.js.gz +0 -0
- package/dist/dashboard/assets/pagination-BAywyMzS.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-YSoQOUh6.js.gz +0 -0
- package/dist/dashboard/assets/quota-DJ1QlAOq.js +0 -1
- package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
- package/dist/dashboard/assets/routing-fnCsxgNO.js +0 -1
- package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
- package/dist/dashboard/assets/select-BCOcv8WK.js.gz +0 -0
- package/dist/dashboard/assets/settings-BxslsErn.js +0 -1
- package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
- package/dist/dashboard/assets/stack-ByKt3Q1g.js.gz +0 -0
- package/dist/dashboard/assets/state-DXbGTx7N.js.gz +0 -0
- package/dist/dashboard/assets/switch-ZeTsW623.js.gz +0 -0
- 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/donation/qris-risun-marke.png +0 -0
- package/src/providers/bundled-discovery-providers.ts +0 -98
- package/src/providers/configured-openai-providers.ts +0 -120
- package/src/providers/integrations/buddy/turing-device-token.ts +0 -262
- package/src/providers/integrations/buddy/workbuddy/cn-oauth.ts +0 -30
- package/src/providers/integrations/buddy/workbuddy/cn-provider.ts +0 -58
- package/src/providers/integrations/buddy/workbuddy/oauth.ts +0 -31
- package/src/providers/integrations/buddy/workbuddy/provider.ts +0 -209
- package/src/providers/integrations/buddy/workbuddy/quota.ts +0 -161
- package/src/providers/integrations/buddy/workbuddy/shared.ts +0 -285
- package/src/providers/operations/model-discovery-cache.ts +0 -34
- package/src/providers/operations/probe-fetch.ts +0 -15
- package/src/providers/operations/provider-version-cache.ts +0 -30
- package/src/providers/provider-capabilities.ts +0 -33
- package/src/providers/provider-credential-envelope.ts +0 -43
- /package/dist/dashboard/assets/{app-CTxoqyYB.js → app-DIXLjojg.js} +0 -0
- /package/dist/dashboard/assets/{app-CTxoqyYB.js.gz → app-DIXLjojg.js.gz} +0 -0
|
@@ -22,6 +22,7 @@ import { resolvePromptCacheKey } from "../../operations/session-resolution";
|
|
|
22
22
|
import { estimateTraeSessionCache } from "./trae-cache";
|
|
23
23
|
import { TRAE_CN_MODELS, TRAE_INTL_MODELS, traeMaxContextWindow } from "./trae-catalog";
|
|
24
24
|
import { buildTraeHeaders } from "./trae-headers";
|
|
25
|
+
import { getTraeVersion } from "../../operations/client-versions";
|
|
25
26
|
import {
|
|
26
27
|
buildTraeChatBody,
|
|
27
28
|
isTraeAgentEndpoint,
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
TRAE_AGENT_ENDPOINT,
|
|
31
32
|
TRAE_CHAT_ENDPOINT,
|
|
32
33
|
} from "./trae-protocol";
|
|
33
|
-
import {
|
|
34
|
+
import { traeCoreForAccount, TRAE_MODEL_LIST_PATH, TRAE_AGENT_FUNCTION, type TraeRealm } from "./trae-realm";
|
|
34
35
|
|
|
35
36
|
export interface TraeAdapterOptions {
|
|
36
37
|
readonly providerId?: string;
|
|
@@ -94,13 +95,22 @@ function extractToken(secret: string): string | undefined {
|
|
|
94
95
|
* Maps a Trae upstream error (a named `error` SSE event, or an error object
|
|
95
96
|
* in a frame body) to the canonical GatewayError.
|
|
96
97
|
*
|
|
97
|
-
*
|
|
98
|
+
* Codes resolved from live probing (2026-11-06), not guessed:
|
|
98
99
|
* - `1001` — "we are not able to authenticate you" — is a credential verdict.
|
|
99
100
|
* It must surface as account-scoped `authentication_failed` so the account
|
|
100
101
|
* is parked for re-login and failover tries a sibling — never the proxy
|
|
101
|
-
* pool.
|
|
102
|
+
* pool. Note: the pay host answers it on *region mismatch* too (an sg
|
|
103
|
+
* account sent to the us pay host), which is not the same as an expired
|
|
104
|
+
* token — a token that answers `GetUserInfo` 200 is alive.
|
|
102
105
|
* - `4008` / "exceeded the quota" — free-tier quota exhausted. That is a
|
|
103
106
|
* `quota_exceeded` 429, not a platform fault.
|
|
107
|
+
* - `1005` (extra `{"plan":N}`) and `4015` — entitlement verdicts. Verified
|
|
108
|
+
* live: identical wire, a paid-capable account streams the same model fine
|
|
109
|
+
* while a Free account is refused with these codes, and the refused
|
|
110
|
+
* account's token still answers `GetUserInfo` 200. Neither auth nor
|
|
111
|
+
* platform fault: `quota_exceeded`.
|
|
112
|
+
* - `4013` / region message — durable regional unavailability, scoped by the
|
|
113
|
+
* classifier to the account (`trae-region-unavailable`).
|
|
104
114
|
* - Everything else is a platform fault (`platform_unavailable`).
|
|
105
115
|
*/
|
|
106
116
|
function throwTraeUpstreamError(
|
|
@@ -163,6 +173,27 @@ function throwTraeUpstreamError(
|
|
|
163
173
|
);
|
|
164
174
|
}
|
|
165
175
|
|
|
176
|
+
// `1005` and `4015` are entitlement verdicts, not auth failures and not
|
|
177
|
+
// platform faults. Verified live: the same wire streams fine on a
|
|
178
|
+
// paid-capable account while a Free account is refused with these codes,
|
|
179
|
+
// and the refused account's token still answers `GetUserInfo` 200. Treating
|
|
180
|
+
// them as auth would park the account for re-login pointlessly; treating
|
|
181
|
+
// them as platform faults would failover to another account that hits the
|
|
182
|
+
// same wall. They are `quota_exceeded` — the model/account cannot serve.
|
|
183
|
+
if (code === "1005" || code === "4015") {
|
|
184
|
+
throw new GatewayError(
|
|
185
|
+
"quota_exceeded",
|
|
186
|
+
429,
|
|
187
|
+
`Trae model not available on this account (upstream code ${code}): ${message} (request {requestId}). The model needs a plan or permission this account does not hold — pick another model or account ⏳`,
|
|
188
|
+
{
|
|
189
|
+
providerCode: code,
|
|
190
|
+
providerStatus: code === "1005" ? 1005 : 4015,
|
|
191
|
+
...(providerId ? { providerId } : {}),
|
|
192
|
+
},
|
|
193
|
+
"upstream",
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
166
197
|
throw new GatewayError(
|
|
167
198
|
"platform_unavailable",
|
|
168
199
|
502,
|
|
@@ -234,9 +265,15 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
234
265
|
token: auth.token,
|
|
235
266
|
uid: auth.uid,
|
|
236
267
|
stream: true,
|
|
268
|
+
appVersion: getTraeVersion(),
|
|
269
|
+
trafficType: agentSurface ? "agent" : "chat",
|
|
237
270
|
});
|
|
238
271
|
|
|
239
|
-
const
|
|
272
|
+
const region =
|
|
273
|
+
typeof context.credential.auth_state?.["region"] === "string"
|
|
274
|
+
? context.credential.auth_state["region"].toLowerCase()
|
|
275
|
+
: "";
|
|
276
|
+
const primary = traeCoreForAccount(this.realm, region);
|
|
240
277
|
const path = agentSurface ? TRAE_AGENT_ENDPOINT : TRAE_CHAT_ENDPOINT;
|
|
241
278
|
const url =
|
|
242
279
|
candidate.endpoint_path && candidate.endpoint_path.startsWith("http")
|
|
@@ -326,7 +363,7 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
326
363
|
/**
|
|
327
364
|
* Two frame layouts reach here and both are live.
|
|
328
365
|
*
|
|
329
|
-
*
|
|
366
|
+
* Upstream's client nests the answer under `chunk`; the region host this
|
|
330
367
|
* gateway talks to sends it flat — `event: output` with
|
|
331
368
|
* `{"response":"…"}` — and reports usage as a separate `token_usage`
|
|
332
369
|
* frame with the OpenAI spelling at the top level. Reading only `chunk`
|
|
@@ -503,6 +540,17 @@ export function createTraeCnAdapter(options: TraeAdapterOptions = {}): ProviderA
|
|
|
503
540
|
/**
|
|
504
541
|
* Live model discovery.
|
|
505
542
|
*
|
|
543
|
+
* The source follows the realm, not one endpoint:
|
|
544
|
+
*
|
|
545
|
+
* - **intl** — the agent picker (`batch_get_detail_param` with
|
|
546
|
+
* `function: solo_agent`), filtered to `usage == "chat_completion"` rows.
|
|
547
|
+
* The chat `model_list` is NOT the intl source: it lists only the legacy
|
|
548
|
+
* nine chat ids, and an agent roster row (`gpt-5-paygo`,
|
|
549
|
+
* `deepseek-v4.1-flash`, `search_agent_*`, …) is absent from it (verified
|
|
550
|
+
* live 2026-11-06). Reading it would replace the agent catalog with models
|
|
551
|
+
* the agent surface rejects (`4023 model is unknown`).
|
|
552
|
+
* - **CN** — the chat `model_list`, which is the surface that serves CN.
|
|
553
|
+
*
|
|
506
554
|
* The listing is per account region, not per realm: it answers on CN and on the
|
|
507
555
|
* intl region host that serves the account (`coresg-normal.trae.ai` verified),
|
|
508
556
|
* while the generic intl core answers `403 no schema found`. An empty result is
|
|
@@ -526,8 +574,51 @@ export async function discoverTraeModels(input: {
|
|
|
526
574
|
realm: input.realm,
|
|
527
575
|
token: input.token,
|
|
528
576
|
uid: input.uid,
|
|
577
|
+
appVersion: getTraeVersion(),
|
|
529
578
|
});
|
|
530
|
-
const
|
|
579
|
+
const core = traeCoreForAccount(input.realm, (input.region ?? "").toLowerCase());
|
|
580
|
+
|
|
581
|
+
if (input.realm === "intl") {
|
|
582
|
+
// The agent picker: the only surface that lists the intl roster's configs.
|
|
583
|
+
const url = `${core}/api/ide/v1/batch_get_detail_param`;
|
|
584
|
+
const response = await input.fetcher(url, {
|
|
585
|
+
method: "POST",
|
|
586
|
+
headers,
|
|
587
|
+
body: JSON.stringify({ functions: [TRAE_AGENT_FUNCTION], Request: {} }),
|
|
588
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
589
|
+
});
|
|
590
|
+
if (!response.ok) return [];
|
|
591
|
+
const parsed = (await response.json()) as { function_configs?: unknown };
|
|
592
|
+
const groups = Array.isArray(parsed.function_configs) ? parsed.function_configs : [];
|
|
593
|
+
const out: { id: string; ctx: number | undefined }[] = [];
|
|
594
|
+
for (const group of groups) {
|
|
595
|
+
if (typeof group !== "object" || group === null) continue;
|
|
596
|
+
const list = (group as Record<string, unknown>)["config_info_list"];
|
|
597
|
+
if (!Array.isArray(list)) continue;
|
|
598
|
+
for (const entry of list) {
|
|
599
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
600
|
+
const row = entry as Record<string, unknown>;
|
|
601
|
+
// Only chat-capable configs are dispatch targets; fast_apply,
|
|
602
|
+
// title_generation, etc. are not.
|
|
603
|
+
if (String(row["usage"] ?? "") !== "chat_completion") continue;
|
|
604
|
+
const id = String(row["config_name"] ?? "").trim();
|
|
605
|
+
if (id.length === 0) continue;
|
|
606
|
+
// Context: the picker row carries `model_detail_list` with the real
|
|
607
|
+
// upstream rows; prefer the widest selectable window among them.
|
|
608
|
+
let ctx: number | undefined;
|
|
609
|
+
const details = Array.isArray(row["model_detail_list"]) ? row["model_detail_list"] : [];
|
|
610
|
+
for (const detail of details) {
|
|
611
|
+
const w = traeMaxContextWindow(detail);
|
|
612
|
+
if (w !== undefined && (ctx === undefined || w > ctx)) ctx = w;
|
|
613
|
+
}
|
|
614
|
+
out.push({ id, ctx });
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return out;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// CN: the chat roster surface.
|
|
621
|
+
const url = `${core}${TRAE_MODEL_LIST_PATH}`;
|
|
531
622
|
const response = await input.fetcher(url, {
|
|
532
623
|
method: "POST",
|
|
533
624
|
headers,
|
|
@@ -550,8 +641,8 @@ export async function discoverTraeModels(input: {
|
|
|
550
641
|
return rows
|
|
551
642
|
.filter((row): row is Record<string, unknown> => typeof row === "object" && row !== null)
|
|
552
643
|
.map((row) => ({
|
|
553
|
-
// `model_name` is the key upstream's listing uses;
|
|
554
|
-
// spellings
|
|
644
|
+
// `model_name` is the key upstream's listing uses; `name`/`id` are
|
|
645
|
+
// spellings older snapshots assumed.
|
|
555
646
|
id: String(row["model_name"] ?? row["name"] ?? row["id"] ?? "").trim(),
|
|
556
647
|
ctx: traeMaxContextWindow(row),
|
|
557
648
|
}))
|
|
@@ -559,21 +650,3 @@ export async function discoverTraeModels(input: {
|
|
|
559
650
|
}
|
|
560
651
|
|
|
561
652
|
export { TRAE_CN_MODELS, TRAE_INTL_MODELS };
|
|
562
|
-
|
|
563
|
-
/**
|
|
564
|
-
* Core host for one account.
|
|
565
|
-
*
|
|
566
|
-
* An intl account is provisioned into a region and its token only authenticates
|
|
567
|
-
* against that region's host, so the account's own `region` wins over the
|
|
568
|
-
* realm default. Falling back to the realm keeps older accounts (stored before
|
|
569
|
-
* the region was captured) working exactly as before.
|
|
570
|
-
*/
|
|
571
|
-
function traeCoreForAccount(
|
|
572
|
-
realm: TraeRealm,
|
|
573
|
-
authState: Readonly<Record<string, unknown>> | undefined,
|
|
574
|
-
): string {
|
|
575
|
-
const region = typeof authState?.["region"] === "string" ? authState["region"].toLowerCase() : "";
|
|
576
|
-
const regional = TRAE_REGION_CORE_HOSTS[region];
|
|
577
|
-
if (regional !== undefined) return regional;
|
|
578
|
-
return traeCoreCandidates(realm)[0] ?? "";
|
|
579
|
-
}
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ZCode Start Plan
|
|
3
|
-
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
2
|
+
* ZCode Start Plan provider integration.
|
|
3
|
+
*
|
|
4
|
+
* The plan lane is an Anthropic Messages endpoint that only accepts the
|
|
5
|
+
* dressed ZCode client request (see `dress`): the gateway content-inspects the
|
|
6
|
+
* `system` field and refuses a request without the exact three-block identity
|
|
7
|
+
* fingerprint with `405 {code:3012}`. The credential is a ZCode login JWT —
|
|
8
|
+
* pasted, or minted by the sign-in flow (`oauth.ts`).
|
|
9
|
+
*
|
|
10
|
+
* Wire facts mirrored from the donor gateway (verified live 2026-10-30):
|
|
11
|
+
* - `anthropic-beta: mid-conversation-system-2026-04-07` rides every request.
|
|
12
|
+
* - `metadata.user_id` is a JSON string `{"device_id","account_uuid","session_id"}`
|
|
13
|
+
* the gateway reads for attribution; it lives in the body, not a header.
|
|
14
|
+
* - The LLM identity face carries per-request correlation ids: `x-session-id`,
|
|
15
|
+
* `x-request-id`, `x-zcode-trace-id`, `x-query-id`, `x-zcode-query-source`.
|
|
16
|
+
* - Errors inside an HTTP 200 response come as a `{code,msg,logid}` envelope
|
|
17
|
+
* (`1113` grant spent, `3009` model concurrency, `3012` identity gate) and
|
|
18
|
+
* are mapped through the shared `classifyUpstreamError`.
|
|
6
19
|
*/
|
|
7
20
|
import { randomUUID } from "node:crypto";
|
|
8
21
|
import { release as osRelease } from "node:os";
|
|
9
22
|
|
|
10
|
-
import type { ApiKeyProviderSpec } from "../../configured-provider";
|
|
11
23
|
import { defineModel } from "../../provider-model-definition";
|
|
12
24
|
import type { ModelDefinition } from "../../provider-model-definition";
|
|
13
25
|
import { getOrCreateInstallId } from "../shared/install-id";
|
|
26
|
+
import { resolveInboundSessionId } from "../../operations/session-resolution";
|
|
27
|
+
import { assertCredentialKind, assertWireFamily } from "../../provider-contracts";
|
|
28
|
+
import type { ProviderAdapter, ProviderDispatchContext, ProviderDispatchTarget } from "../../provider-contracts";
|
|
29
|
+
import { GatewayError } from "../../../protocol/gateway-error";
|
|
30
|
+
import { applyParamQuirks } from "../../../protocol/translation/quirks";
|
|
31
|
+
import { buildClaudeMessagesRequest, filterClaudeCustomHeaders } from "../shared/claude-messages";
|
|
32
|
+
import { mapClaudeHttpError } from "../../../protocol/messages-errors";
|
|
33
|
+
import { isRecord } from "../../../protocol/codecs";
|
|
34
|
+
import { classifyUpstreamError, upstreamErrorIdentifier, upstreamMessageAsIs } from "../../../transport/failure-policy";
|
|
35
|
+
import { parseClaudeSseStream, claudeResponseToEvents } from "../../../protocol/response/messages";
|
|
36
|
+
import { createUpstreamDeadlineLifecycle } from "../../operations/upstream-deadline";
|
|
37
|
+
import type { CanonicalEvent, CanonicalRequest } from "../../../protocol/canonical-model";
|
|
38
|
+
import { parseJwt } from "../../authentication/jwt-validator";
|
|
14
39
|
import prompt from "./zcode_prompt.json";
|
|
15
40
|
|
|
16
41
|
const CLI_PREFIX: string = prompt.cliPrefix;
|
|
@@ -21,8 +46,18 @@ export const ZCODE_START_PLAN_PROVIDER_ID = "zcode-start" as const;
|
|
|
21
46
|
export const ZCODE_START_PLAN_ENDPOINT_PATH = "/v1/messages" as const;
|
|
22
47
|
export const ZCODE_START_PLAN_BASE_URL = "https://zcode.z.ai/api/v1/zcode-plan/anthropic" as const;
|
|
23
48
|
|
|
24
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Client version the plan endpoint expects in the identity headers. This is
|
|
51
|
+
* kept in step with the bundled prompt asset (`zcode_prompt.json`, 3.14.5):
|
|
52
|
+
* the gateway content-inspects the system blocks, and a version/prompt split
|
|
53
|
+
* (e.g. 3.16.3 headers over 3.14.5 blocks) risks the 3012 identity gate. Bump
|
|
54
|
+
* both together only after re-capturing the live blocks and re-verifying.
|
|
55
|
+
*/
|
|
25
56
|
const APP_VERSION = "3.14.5";
|
|
57
|
+
/** Anthropic beta the desktop client sends on the plan lane (captured live). */
|
|
58
|
+
const ANTHROPIC_BETA = "mid-conversation-system-2026-04-07";
|
|
59
|
+
/** The plan gateway enforces a serial per-account in-flight limit; 8192 is the desktop default. */
|
|
60
|
+
const DEFAULT_MAX_TOKENS = 8192;
|
|
26
61
|
|
|
27
62
|
type Loose = Record<string, unknown>;
|
|
28
63
|
type TextBlock = { type: "text"; text: string; cache_control?: { type: "ephemeral" } };
|
|
@@ -40,26 +75,47 @@ function environmentBlock(provider: string, model: string): string {
|
|
|
40
75
|
.replace("{model}", model);
|
|
41
76
|
}
|
|
42
77
|
|
|
78
|
+
/** The account uuid carried by the plan JWT, for metadata attribution. */
|
|
79
|
+
function jwtUserId(credential: { secret?: Uint8Array | undefined } | undefined): string {
|
|
80
|
+
if (!credential?.secret || credential.secret.length === 0) return "";
|
|
81
|
+
try {
|
|
82
|
+
const token = new TextDecoder().decode(credential.secret);
|
|
83
|
+
const parsed = parseJwt(token);
|
|
84
|
+
const userId = parsed?.payload?.["user_id"];
|
|
85
|
+
return typeof userId === "string" ? userId : "";
|
|
86
|
+
} catch {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
43
91
|
/** Identity headers every dispatch carries; the adapter adds Authorization. */
|
|
44
|
-
async function identityHeaders(): Promise<Record<string, string>> {
|
|
92
|
+
async function identityHeaders(context: ProviderDispatchContext): Promise<Record<string, string>> {
|
|
93
|
+
const sessionId = resolveInboundSessionId(context) ?? `session_${randomUUID().replace(/-/g, "").slice(0, 32)}`;
|
|
94
|
+
const requestId = randomUUID();
|
|
95
|
+
const traceId = randomUUID();
|
|
96
|
+
const queryId = `01a1${requestId.slice(4).replace(/-/g, "").slice(0, 28)}`;
|
|
97
|
+
const deviceMid = await getOrCreateInstallId("zcode-start-plan");
|
|
45
98
|
return {
|
|
46
99
|
"user-agent": `ZCode/${APP_VERSION} ai-sdk/anthropic/3.0.81`,
|
|
47
100
|
"http-referer": "https://zcode.z.ai",
|
|
48
|
-
"x-title": "Z Code@
|
|
101
|
+
"x-title": "Z Code@electron",
|
|
49
102
|
"x-zcode-app-version": APP_VERSION,
|
|
50
103
|
"x-zcode-agent": "glm",
|
|
51
104
|
"x-release-channel": "production",
|
|
52
105
|
"x-client-language": "en-US",
|
|
53
106
|
"x-client-timezone": "Asia/Jakarta",
|
|
54
|
-
"x-platform": "linux",
|
|
107
|
+
"x-platform": "linux-x64",
|
|
55
108
|
"x-os-category": "linux",
|
|
56
109
|
"x-os-version": osRelease(),
|
|
57
|
-
"x-request-id":
|
|
110
|
+
"x-request-id": requestId,
|
|
111
|
+
"x-query-id": queryId,
|
|
112
|
+
"x-zcode-trace-id": traceId,
|
|
58
113
|
"x-zcode-session-type": "main",
|
|
59
|
-
"x-zcode-
|
|
60
|
-
|
|
61
|
-
"x-device-mid":
|
|
114
|
+
"x-zcode-query-source": "main_turn",
|
|
115
|
+
"x-session-id": sessionId,
|
|
116
|
+
"x-device-mid": deviceMid,
|
|
62
117
|
"anthropic-version": "2023-06-01",
|
|
118
|
+
"anthropic-beta": ANTHROPIC_BETA,
|
|
63
119
|
};
|
|
64
120
|
}
|
|
65
121
|
|
|
@@ -119,13 +175,160 @@ export const ZCODE_START_PLAN_MODELS: readonly ModelDefinition[] = [
|
|
|
119
175
|
}),
|
|
120
176
|
];
|
|
121
177
|
|
|
122
|
-
/**
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
178
|
+
/** True when the body is the ZCode `{code,msg,logid}` business-error envelope. */
|
|
179
|
+
function isZcodeEnvelopeError(body: Record<string, unknown>): boolean {
|
|
180
|
+
if (body["success"] === false) return true;
|
|
181
|
+
const code = body["code"];
|
|
182
|
+
return code !== undefined && ![0, 200, "0", "200"].includes(code as string | number);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Plan-lane Messages adapter. Unlike the plain Anthropic adapter it must (a)
|
|
187
|
+
* dress the three-block system fingerprint, (b) inject `metadata.user_id`, and
|
|
188
|
+
* (c) treat a `{code,msg}` envelope inside an HTTP 200 as a refusal — the
|
|
189
|
+
* gateway reports business errors on success statuses.
|
|
190
|
+
*/
|
|
191
|
+
export class ZcodeStartPlanAdapter implements ProviderAdapter {
|
|
192
|
+
readonly provider_id = ZCODE_START_PLAN_PROVIDER_ID;
|
|
193
|
+
private readonly fetchFn: typeof fetch;
|
|
194
|
+
private readonly baseUrl: string;
|
|
195
|
+
|
|
196
|
+
constructor(fetchImpl?: typeof fetch, baseUrl?: string) {
|
|
197
|
+
this.fetchFn = fetchImpl ?? globalThis.fetch;
|
|
198
|
+
this.baseUrl = (baseUrl ?? ZCODE_START_PLAN_BASE_URL).replace(/\/+$/, "");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async *dispatch(
|
|
202
|
+
request: CanonicalRequest,
|
|
203
|
+
candidate: ProviderDispatchTarget,
|
|
204
|
+
context: ProviderDispatchContext,
|
|
205
|
+
): AsyncIterable<CanonicalEvent> {
|
|
206
|
+
if (candidate.wire_family !== "messages") {
|
|
207
|
+
assertWireFamily(candidate, "messages", "zcode-start messages leg");
|
|
208
|
+
}
|
|
209
|
+
if (context.credential.credential_kind !== "api_key") {
|
|
210
|
+
assertCredentialKind(context.credential, "api_key", "zcode-start");
|
|
211
|
+
}
|
|
212
|
+
if (context.credential.secret === undefined || context.credential.secret.length === 0) {
|
|
213
|
+
throw new GatewayError(
|
|
214
|
+
"invalid_request",
|
|
215
|
+
400,
|
|
216
|
+
"zcode-start: plan JWT is missing a secret value (request {requestId}). Wrong key, right door — check the credential 🔑",
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
const planJwt = new TextDecoder().decode(context.credential.secret);
|
|
220
|
+
const sessionId = resolveInboundSessionId(context, request) ?? `session_${randomUUID().replace(/-/g, "").slice(0, 32)}`;
|
|
221
|
+
const deviceMid = await getOrCreateInstallId("zcode-start-plan");
|
|
222
|
+
const accountUuid = jwtUserId(context.credential);
|
|
223
|
+
const customHeaders = filterClaudeCustomHeaders({
|
|
224
|
+
...context.credential.custom_headers,
|
|
225
|
+
});
|
|
226
|
+
const outbound = buildClaudeMessagesRequest({
|
|
227
|
+
request: applyParamQuirks(request, candidate.provider_id),
|
|
228
|
+
authHeader: "bearer",
|
|
229
|
+
credential: { secret: planJwt, customHeaders },
|
|
230
|
+
baseUrl: this.baseUrl,
|
|
231
|
+
endpointPath: candidate.endpoint_path,
|
|
232
|
+
mutatePayload: (payload) => {
|
|
233
|
+
dress(payload);
|
|
234
|
+
const metadata = (isRecord(payload["metadata"]) ? payload["metadata"] : {}) as Loose;
|
|
235
|
+
metadata["user_id"] = JSON.stringify({
|
|
236
|
+
device_id: deviceMid,
|
|
237
|
+
account_uuid: accountUuid,
|
|
238
|
+
session_id: sessionId,
|
|
239
|
+
});
|
|
240
|
+
payload.metadata = metadata;
|
|
241
|
+
if (payload["max_tokens"] == null) payload["max_tokens"] = DEFAULT_MAX_TOKENS;
|
|
242
|
+
return payload;
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
Object.assign(outbound.headers, await identityHeaders(context));
|
|
246
|
+
|
|
247
|
+
const outboundFetch = context.outbound_fetch ?? this.fetchFn;
|
|
248
|
+
const lifecycle = createUpstreamDeadlineLifecycle(context);
|
|
249
|
+
let response: Response;
|
|
250
|
+
try {
|
|
251
|
+
response = await outboundFetch(outbound.url, {
|
|
252
|
+
method: "POST",
|
|
253
|
+
headers: outbound.headers,
|
|
254
|
+
body: outbound.body,
|
|
255
|
+
signal: lifecycle.signal,
|
|
256
|
+
});
|
|
257
|
+
} catch (error: unknown) {
|
|
258
|
+
lifecycle.release();
|
|
259
|
+
if (error instanceof GatewayError) throw error;
|
|
260
|
+
throw new GatewayError(
|
|
261
|
+
"transport_unavailable",
|
|
262
|
+
502,
|
|
263
|
+
`zcode-start upstream fetch failed: ${(error as Error)?.message ?? String(error)}`,
|
|
264
|
+
{},
|
|
265
|
+
"network",
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
lifecycle.release();
|
|
269
|
+
|
|
270
|
+
if (!response.ok) {
|
|
271
|
+
const bodyText = await response.text().catch(() => "");
|
|
272
|
+
throw mapClaudeHttpError(response.status, bodyText, response.headers);
|
|
273
|
+
}
|
|
274
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
275
|
+
if (contentType.toLowerCase().includes("text/event-stream") || request.stream) {
|
|
276
|
+
if (response.body === null) {
|
|
277
|
+
throw new GatewayError(
|
|
278
|
+
"platform_unavailable",
|
|
279
|
+
502,
|
|
280
|
+
"zcode-start returned no stream body (request {requestId}). The upstream came back empty-handed — retry 🌙",
|
|
281
|
+
{},
|
|
282
|
+
"upstream",
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
yield* parseClaudeSseStream(response.body, context.abort_signal, false);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const bodyText = await response.text().catch(() => "");
|
|
289
|
+
let json: unknown;
|
|
290
|
+
try {
|
|
291
|
+
json = JSON.parse(bodyText) as unknown;
|
|
292
|
+
} catch {
|
|
293
|
+
const upstreamText = upstreamMessageAsIs(bodyText, "");
|
|
294
|
+
throw new GatewayError(
|
|
295
|
+
"platform_unavailable",
|
|
296
|
+
502,
|
|
297
|
+
upstreamText.message || "zcode-start response is not valid JSON (request {requestId}). The upstream came back empty-handed — retry 🌙",
|
|
298
|
+
{ raw: bodyText.slice(0, 4096) },
|
|
299
|
+
"upstream",
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
if (!isRecord(json)) {
|
|
303
|
+
throw new GatewayError(
|
|
304
|
+
"platform_unavailable",
|
|
305
|
+
502,
|
|
306
|
+
"zcode-start response must be an object (request {requestId}). The upstream came back empty-handed — retry 🌙",
|
|
307
|
+
{},
|
|
308
|
+
"upstream",
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
if (isZcodeEnvelopeError(json)) {
|
|
312
|
+
const identifier = upstreamErrorIdentifier(json);
|
|
313
|
+
const classification = classifyUpstreamError(undefined, identifier);
|
|
314
|
+
const upstreamText = upstreamMessageAsIs(json, "");
|
|
315
|
+
throw new GatewayError(
|
|
316
|
+
classification.code,
|
|
317
|
+
classification.status,
|
|
318
|
+
upstreamText.message || "zcode-start reported an upstream error",
|
|
319
|
+
{
|
|
320
|
+
providerId: this.provider_id,
|
|
321
|
+
...(identifier === undefined ? {} : { providerCode: identifier }),
|
|
322
|
+
...(upstreamText.hadUpstreamText ? { upstreamMessageAsIs: true } : {}),
|
|
323
|
+
raw: bodyText.slice(0, 4096),
|
|
324
|
+
},
|
|
325
|
+
classification.origin,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
yield* claudeResponseToEvents(json, request, false);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function createZcodeStartPlanAdapter(fetchImpl?: typeof fetch): ProviderAdapter {
|
|
333
|
+
return new ZcodeStartPlanAdapter(fetchImpl);
|
|
334
|
+
}
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import { asCoercedNumber, asRecord, asTrimmedString } from "../../../shared/coerce";
|
|
2
3
|
import type { FetchLike, ProviderQuotaResult, ProviderQuotaWindow } from "../../quota/quota-contracts";
|
|
3
4
|
|
|
4
5
|
const BALANCE_URL = "https://zcode.z.ai/api/v1/zcode-plan/billing/balance?app_version=3.16.3";
|
|
5
|
-
const DEVICE_MID = "9f1b0d4e-3c2a-4e7b-9f1d-6a2c8b5e0d31";
|
|
6
6
|
const APP_VERSION = "3.16.3";
|
|
7
|
+
const PLATFORM = "linux-x64";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Stable per-account device mid. The gateway validates `X-Device-Mid` as a
|
|
11
|
+
* UUID (billing answers `3001 parameter error` without it) and attributes
|
|
12
|
+
* usage to it; a hardcoded shared UUID would lump every account into one
|
|
13
|
+
* billing identity. Derivation matches the gift-claim device id, so quota and
|
|
14
|
+
* claim present the same device per account.
|
|
15
|
+
*/
|
|
16
|
+
function deviceMid(accountId: string): string {
|
|
17
|
+
const hash = createHash("sha256").update(`zcode-device\0${accountId}`).digest("hex");
|
|
18
|
+
const variant = ((parseInt(hash[16] as string, 16) & 3) | 8).toString(16);
|
|
19
|
+
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-4${hash.slice(13, 16)}-${variant}${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
|
|
20
|
+
}
|
|
7
21
|
|
|
8
22
|
function instant(value: unknown): string | null {
|
|
9
23
|
const seconds = asCoercedNumber(value);
|
|
@@ -57,16 +71,19 @@ function samePlan(bucket: Record<string, unknown>, plan: Record<string, unknown>
|
|
|
57
71
|
export async function fetchZcodeStartPlanQuota(
|
|
58
72
|
credential: string,
|
|
59
73
|
fetcher: FetchLike,
|
|
74
|
+
context?: { accountId?: string },
|
|
60
75
|
): Promise<ProviderQuotaResult> {
|
|
61
76
|
const source = "zcode-start";
|
|
62
77
|
try {
|
|
78
|
+
const accountId = context?.accountId ?? credential.trim();
|
|
63
79
|
const response = await fetcher(BALANCE_URL, {
|
|
64
80
|
headers: {
|
|
65
81
|
authorization: `Bearer ${credential}`,
|
|
66
82
|
accept: "application/json",
|
|
67
|
-
"x-device-mid":
|
|
83
|
+
"x-device-mid": deviceMid(accountId),
|
|
68
84
|
"x-zcode-app-version": APP_VERSION,
|
|
69
85
|
"x-client-language": "en-US",
|
|
86
|
+
"x-platform": PLATFORM,
|
|
70
87
|
},
|
|
71
88
|
signal: AbortSignal.timeout(15_000),
|
|
72
89
|
});
|