cartethyia 2.7.4 → 2.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -0
- package/README.md +17 -5
- package/dist/dashboard/assets/{BannedPage-ChG5svFb.js → BannedPage-Cj15GsMp.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +1 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BIcWQun7.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-Bf2VelDe.js → CliToolsPage-BIccZmeL.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +1 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-ggeMSjte.js → CustomizationPage-BKj_r0rp.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js +656 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-U6AKaJcF.js → LoginPage-DkXb6dx-.js} +1 -1
- package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-DnQPSIA8.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +1 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +5 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-5SnUSy3j.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +1 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js +1 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-f0DE1h0-.js → SetupPage-WTa0sktC.js} +1 -1
- package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-BfAb5-o_.js} +3 -3
- package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js +56 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js +1 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
- package/dist/dashboard/assets/app--PJWq8_C.css +2 -0
- package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js +1 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-DfbhQU4k.js} +1 -1
- package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DympBNq4.js → banner-BllT4LcF.js} +1 -1
- package/dist/dashboard/assets/banner-BllT4LcF.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-CtkX66Wd.js} +1 -1
- package/dist/dashboard/assets/card-CtkX66Wd.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/cli-tools-CQXVMn4P.js +1 -0
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-BQqBQd2n.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-8fiE6tec.js → dialog-BEK7KP0H.js} +1 -1
- package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-BrTEZ8zu.js} +1 -1
- package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js +1 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
- package/dist/dashboard/assets/{entry-BSAsYsmV.js → entry-EBHJ3DrE.js} +1 -1
- package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js +4 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-BAACA727.js} +1 -1
- package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-CPK47xQx.js → github-badge-YSCE4UC2.js} +1 -1
- package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
- package/dist/dashboard/assets/{index-DBNPOfhV.js → index-FQlj0HUT.js} +2 -2
- package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-C4gU5iOL.js} +1 -1
- package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
- package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BHHX_Tmm.js} +1 -1
- package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-CajrYUnD.js} +1 -1
- package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Bx2I7XUe.js} +1 -1
- package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js +1 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js +1 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js +1 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
- package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BLULNqTp.js} +1 -1
- package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
- package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
- package/dist/dashboard/assets/settings-CcGczj6I.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-D2lIR0tg.js} +1 -1
- package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
- package/dist/dashboard/assets/{state-CkfdYWel.js → state-DTARjfiW.js} +1 -1
- package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
- package/dist/dashboard/assets/{switch-SYm237HG.js → switch-c0oPSnqW.js} +1 -1
- package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-m8WGNPrz.js} +1 -1
- package/dist/dashboard/assets/useMutation-m8WGNPrz.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 +56 -55
- 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/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/package.json +4 -6
- package/scripts/cli/update.ts +15 -41
- package/src/boot/app.ts +58 -2
- package/src/boot/dependencies.ts +786 -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 +13 -14
- package/src/config/resources.ts +0 -5
- package/src/config/runtime.ts +2 -5
- package/src/config/spec.ts +26 -6
- 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 +48 -12
- 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 +7 -7
- package/src/console/cli-tools/injectors/cline.ts +110 -110
- package/src/console/cli-tools/injectors/codex.ts +181 -181
- package/src/console/cli-tools/injectors/copilot.ts +108 -108
- package/src/console/cli-tools/injectors/driver.ts +247 -247
- package/src/console/cli-tools/injectors/jcode.ts +115 -115
- package/src/console/cli-tools/injectors/openclaw.ts +161 -161
- package/src/console/cli-tools/injectors/opencode.ts +153 -153
- package/src/console/cli-tools/routes.ts +1 -1
- package/src/console/cli-tools/service.ts +1 -1
- 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 +1 -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 +20 -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 +4 -4
- 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 +2 -2
- package/src/observability/event-query.ts +59 -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 +12 -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 +113 -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 +10 -1
- 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 +3 -49
- 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 +42 -3
- 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 +23 -35
- 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 +0 -14
- package/src/providers/integrations/antigravity/antigravity.ts +2 -2
- 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 +38 -5
- 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 +55 -10
- package/src/providers/integrations/github/github-oauth.ts +6 -5
- package/src/providers/integrations/github/github.ts +41 -14
- 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 +81 -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 +85 -8
- 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 +354 -62
- 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 +53 -10
- 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 +131 -116
- package/src/providers/operations/account-health-service.ts +31 -39
- package/src/providers/operations/account-reset-service.ts +58 -1
- 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 +81 -16
- 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 +2 -2
- package/src/security/admission/ttl.ts +61 -61
- package/src/security/api-key-auth.ts +16 -4
- 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 +1 -1
- 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 +6 -0
- package/src/transport/guards/auth-guard.ts +0 -6
- package/src/transport/guards/body-policy.ts +3 -3
- 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 +1 -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 +152 -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/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 +376 -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.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
- 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.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.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.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/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-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.gz +0 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
- 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.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/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/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/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/{app-BayTTy01.js → app-Bgd3zANQ.js} +0 -0
- /package/dist/dashboard/assets/{app-BayTTy01.js.gz → app-Bgd3zANQ.js.gz} +0 -0
- /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
|
@@ -303,17 +303,6 @@ export function buildHeartbeat(): Uint8Array {
|
|
|
303
303
|
return encodeMessage("AgentClientMessage", { client_heartbeat: {} });
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
/**
|
|
307
|
-
* `ACM#5 exec_client_control_message.heartbeat{id}`: Cursor CLI sends one every
|
|
308
|
-
* few seconds for each exec it is still running. A zero id is left out, as
|
|
309
|
-
* proto3 does for a default scalar.
|
|
310
|
-
*/
|
|
311
|
-
export function buildExecHeartbeat(execId: number): Uint8Array {
|
|
312
|
-
return encodeMessage("AgentClientMessage", {
|
|
313
|
-
exec_client_control_message: { heartbeat: execId === 0 ? {} : { id: execId } },
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
306
|
/** `ACM#5 exec_client_control_message.stream_close{id}` after an exec result. */
|
|
318
307
|
export function buildExecStreamClose(execId: number, execIdString?: string): Uint8Array {
|
|
319
308
|
return encodeMessage("AgentClientMessage", {
|
|
@@ -424,82 +413,6 @@ export function buildMcpResult(input: {
|
|
|
424
413
|
});
|
|
425
414
|
}
|
|
426
415
|
|
|
427
|
-
/**
|
|
428
|
-
* `ACM#2 exec_client_message{shell_result|write_result|read_result}` for a host
|
|
429
|
-
* exec the canonical client executed locally.
|
|
430
|
-
*
|
|
431
|
-
* Cursor's executor replies to its own host requests with the variant's typed
|
|
432
|
-
* result frame (the generic `mcp_result` leaves the server unmatched on a frame
|
|
433
|
-
* it did rank), and after every exec result it sends `stream_close` — without
|
|
434
|
-
* it the cloud waits forever on shell execs. `is_error` keeps the failure as
|
|
435
|
-
* the variant's error/failure case rather than a crafted success.
|
|
436
|
-
*/
|
|
437
|
-
export type CursorHostExecResultVariant = "shell" | "write" | "read";
|
|
438
|
-
|
|
439
|
-
export function buildHostExecResult(input: {
|
|
440
|
-
readonly execId: number;
|
|
441
|
-
readonly execIdString?: string;
|
|
442
|
-
readonly variant: CursorHostExecResultVariant;
|
|
443
|
-
readonly text: string;
|
|
444
|
-
readonly isError: boolean;
|
|
445
|
-
readonly host: {
|
|
446
|
-
readonly command?: string;
|
|
447
|
-
readonly workingDirectory?: string;
|
|
448
|
-
readonly path?: string;
|
|
449
|
-
readonly lines?: number;
|
|
450
|
-
readonly fileSize?: number;
|
|
451
|
-
};
|
|
452
|
-
}): Uint8Array[] {
|
|
453
|
-
const id = { id: input.execId, exec_id: input.execIdString ?? "" };
|
|
454
|
-
const variant = input.variant;
|
|
455
|
-
const text = input.text;
|
|
456
|
-
let result: Record<string, unknown>;
|
|
457
|
-
if (variant === "shell") {
|
|
458
|
-
result = {
|
|
459
|
-
shell_result: input.isError
|
|
460
|
-
? { failure: { command: input.host.command ?? "", exit_code: 1, stderr: text } }
|
|
461
|
-
: {
|
|
462
|
-
success: {
|
|
463
|
-
command: input.host.command ?? "",
|
|
464
|
-
exit_code: 0,
|
|
465
|
-
stdout: text,
|
|
466
|
-
...(input.host.workingDirectory === undefined ? {} : { working_directory: input.host.workingDirectory }),
|
|
467
|
-
},
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
} else if (variant === "write") {
|
|
471
|
-
result = {
|
|
472
|
-
write_result: input.isError
|
|
473
|
-
? { error: { path: input.host.path ?? "", error: text } }
|
|
474
|
-
: {
|
|
475
|
-
success: {
|
|
476
|
-
path: input.host.path ?? "",
|
|
477
|
-
lines_created: input.host.lines ?? 0,
|
|
478
|
-
file_size: input.host.fileSize ?? 0,
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
};
|
|
482
|
-
} else {
|
|
483
|
-
result = {
|
|
484
|
-
read_result: input.isError
|
|
485
|
-
? { error: { path: input.host.path ?? "", error: text } }
|
|
486
|
-
: {
|
|
487
|
-
success: {
|
|
488
|
-
path: input.host.path ?? "",
|
|
489
|
-
content: text,
|
|
490
|
-
total_lines: text.length > 0 ? text.split("\n").length : 0,
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
return [
|
|
496
|
-
encodeMessage("AgentClientMessage", { exec_client_message: { ...id, ...result } }),
|
|
497
|
-
// The real CLI pairs every typed exec result with stream_close — the cloud
|
|
498
|
-
// waits on it for shell execs specifically.
|
|
499
|
-
buildExecStreamClose(input.execId, input.execIdString),
|
|
500
|
-
];
|
|
501
|
-
}
|
|
502
|
-
|
|
503
416
|
/**
|
|
504
417
|
* `ACM#2 exec_client_message{mcp_result}` rejecting a tool the client never
|
|
505
418
|
* declared.
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// protocol was verified against: they are declared once so the auth flow, the
|
|
6
6
|
// unary catalog calls, and the Run stream cannot drift apart on host, path, or
|
|
7
7
|
// client id.
|
|
8
|
-
import type { WireFamily } from "../../../protocol/canonical-model";
|
|
9
8
|
|
|
10
9
|
/** Canonical bundled provider id. */
|
|
11
10
|
export const CURSOR_PROVIDER_ID = "cursor";
|
|
@@ -72,9 +71,6 @@ export const SESSION_REFRESH_TIMEOUT_MS = 20_000;
|
|
|
72
71
|
*/
|
|
73
72
|
export const RUN_IDLE_TTL_MS = 10 * 60_000;
|
|
74
73
|
|
|
75
|
-
/** Chat wire is the declared default; the adapter owns the native protocol. */
|
|
76
|
-
export const CURSOR_WIRE_FAMILY: WireFamily = "chat";
|
|
77
|
-
|
|
78
74
|
/**
|
|
79
75
|
* Any HTTPS subdomain of `cursor.sh` is an acceptable Run host: the region
|
|
80
76
|
* Cursor routes an account to varies (`agentn.*`, `agent.*`, `api5`, …).
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
} from "../../../protocol/canonical-model";
|
|
28
28
|
import { resolveImageSource, splitDataUrl } from "../../../protocol/codecs";
|
|
29
29
|
import { IMAGE_CLAMP_MAX_BYTES } from "../../../protocol/image-clamp";
|
|
30
|
+
import { applyCacheMode } from "../../provider-usage";
|
|
30
31
|
import type { ProviderAdapter, ProviderDispatchContext, ProviderDispatchTarget } from "../../provider-contracts";
|
|
31
32
|
import { readCredentialSecret } from "../../provider-contracts";
|
|
32
33
|
import type { Http2BidiEndReason, ValidatedHttp2BidiStream } from "../../../network/http2-bidi";
|
|
@@ -62,6 +63,7 @@ import { defaultParameterValues, fetchCursorModels } from "./cursor-catalog";
|
|
|
62
63
|
import type { CursorModelInfo } from "./cursor-catalog";
|
|
63
64
|
import { decodeValueToJson, decodeStructEntriesToJson } from "./protocol/struct";
|
|
64
65
|
import { cursorVariantForExecArgs } from "./protocol/tool-canonical";
|
|
66
|
+
import { fnv1a32 } from "../shared/hash";
|
|
65
67
|
|
|
66
68
|
/**
|
|
67
69
|
* Client-heartbeat cadence for every Cursor Run.
|
|
@@ -81,8 +83,38 @@ const CURSOR_HEARTBEAT_INTERVAL_MS = 5_000;
|
|
|
81
83
|
* every dispatch.
|
|
82
84
|
*/
|
|
83
85
|
const CURSOR_ROSTER_TTL_MS = 300_000;
|
|
84
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* credential → { roster, fetchedAt } for the parameter lookup.
|
|
88
|
+
*
|
|
89
|
+
* Keyed by an FNV-1a digest of the credential rather than the raw token so a
|
|
90
|
+
* long-lived map does not hold live credentials as keys. Bounded by
|
|
91
|
+
* `ROSTER_CACHE_MAX` with oldest-first eviction: the TTL is only checked on
|
|
92
|
+
* read, so without a cap rotated tokens would grow the map without bound.
|
|
93
|
+
*/
|
|
94
|
+
const ROSTER_CACHE_MAX = 1024;
|
|
85
95
|
const rosterCache = new Map<string, { roster: readonly CursorModelInfo[]; fetchedAt: number }>();
|
|
96
|
+
|
|
97
|
+
function rosterCacheSet(credential: string, roster: readonly CursorModelInfo[]): void {
|
|
98
|
+
const key = String(fnv1a32(credential));
|
|
99
|
+
rosterCache.delete(key); // re-set moves the entry to newest position
|
|
100
|
+
rosterCache.set(key, { roster, fetchedAt: Date.now() });
|
|
101
|
+
while (rosterCache.size > ROSTER_CACHE_MAX) {
|
|
102
|
+
const oldest = rosterCache.keys().next().value;
|
|
103
|
+
if (oldest === undefined) break;
|
|
104
|
+
rosterCache.delete(oldest);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Test-only access to the roster cache (cap/eviction/TTL behavior is covered
|
|
110
|
+
* by `test/providers/cursor-roster-cache.test.ts` without a full dispatch).
|
|
111
|
+
*/
|
|
112
|
+
export const rosterCacheForTests = {
|
|
113
|
+
size: (): number => rosterCache.size,
|
|
114
|
+
set: rosterCacheSet,
|
|
115
|
+
get: (credential: string): { roster: readonly CursorModelInfo[]; fetchedAt: number } | undefined =>
|
|
116
|
+
rosterCache.get(String(fnv1a32(credential))),
|
|
117
|
+
};
|
|
86
118
|
/** Client-heartbeat cadence the Cursor edge expects (donor `heartbeatMs`). */
|
|
87
119
|
const CURSOR_HEARTBEAT_INTERVAL_OVERRIDE = (() => {
|
|
88
120
|
const raw = process.env.CARTETHYIA_CURSOR_HEARTBEAT_MS?.trim();
|
|
@@ -249,7 +281,7 @@ function usageFromTurnEnded(turnEnded: Record<string, unknown>): UsageRecord {
|
|
|
249
281
|
const input = count(turnEnded["input_tokens"]);
|
|
250
282
|
const output = count(turnEnded["output_tokens"]);
|
|
251
283
|
const cacheRead = count(turnEnded["cache_read"]);
|
|
252
|
-
return {
|
|
284
|
+
return applyCacheMode({
|
|
253
285
|
input_tokens: input,
|
|
254
286
|
cached_input_tokens: cacheRead,
|
|
255
287
|
cache_write_tokens: count(turnEnded["cache_write"]),
|
|
@@ -258,7 +290,7 @@ function usageFromTurnEnded(turnEnded: Record<string, unknown>): UsageRecord {
|
|
|
258
290
|
reasoning_tokens: count(turnEnded["reasoning_tokens"]),
|
|
259
291
|
estimated_cost: null,
|
|
260
292
|
total_tokens: input + output,
|
|
261
|
-
};
|
|
293
|
+
});
|
|
262
294
|
}
|
|
263
295
|
|
|
264
296
|
function nonEmptyStringOf(value: unknown): string | undefined {
|
|
@@ -846,7 +878,8 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
846
878
|
credential: string,
|
|
847
879
|
context: ProviderDispatchContext,
|
|
848
880
|
): Promise<readonly CursorModelInfo[]> {
|
|
849
|
-
const
|
|
881
|
+
const key = String(fnv1a32(credential));
|
|
882
|
+
const cached = rosterCache.get(key);
|
|
850
883
|
if (cached !== undefined && Date.now() - cached.fetchedAt < CURSOR_ROSTER_TTL_MS) {
|
|
851
884
|
return cached.roster;
|
|
852
885
|
}
|
|
@@ -858,7 +891,7 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
858
891
|
: { fetcher: context.outbound_fetch as unknown as typeof fetch }),
|
|
859
892
|
signal: context.abort_signal,
|
|
860
893
|
});
|
|
861
|
-
|
|
894
|
+
rosterCacheSet(credential, roster);
|
|
862
895
|
return roster;
|
|
863
896
|
} catch {
|
|
864
897
|
return cached?.roster ?? [];
|
|
@@ -71,59 +71,3 @@ export function* streamFrames(buffer: Uint8Array): Generator<Frame, void, void>
|
|
|
71
71
|
offset = start + len
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
export async function* asyncStreamFrames(
|
|
76
|
-
stream: ReadableStream<Uint8Array>,
|
|
77
|
-
): AsyncGenerator<Frame, void, void> {
|
|
78
|
-
const reader = stream.getReader()
|
|
79
|
-
const chunks: Uint8Array[] = []
|
|
80
|
-
let pendingLength = 0
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
while (true) {
|
|
84
|
-
const { done, value } = await reader.read()
|
|
85
|
-
if (done && chunks.length === 0) return
|
|
86
|
-
if (value) {
|
|
87
|
-
chunks.push(value)
|
|
88
|
-
pendingLength += value.length
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Try to parse frames from accumulated data
|
|
92
|
-
const merged = mergeChunks(chunks)
|
|
93
|
-
const frames = Array.from(streamFrames(merged))
|
|
94
|
-
const consumed = frames.reduce((sum, f) => sum + 5 + f.payload.length, 0)
|
|
95
|
-
|
|
96
|
-
if (frames.length > 0) {
|
|
97
|
-
for (const frame of frames) {
|
|
98
|
-
yield frame
|
|
99
|
-
}
|
|
100
|
-
// Keep any trailing bytes for next iteration
|
|
101
|
-
const remaining = merged.subarray(consumed)
|
|
102
|
-
chunks.length = 0
|
|
103
|
-
if (remaining.length > 0) {
|
|
104
|
-
chunks.push(remaining)
|
|
105
|
-
pendingLength = remaining.length
|
|
106
|
-
} else {
|
|
107
|
-
pendingLength = 0
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (done) return
|
|
112
|
-
}
|
|
113
|
-
} finally {
|
|
114
|
-
reader.releaseLock()
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function mergeChunks(chunks: Uint8Array[]): Uint8Array {
|
|
119
|
-
const first = chunks[0]
|
|
120
|
-
if (chunks.length === 1 && first !== undefined) return first
|
|
121
|
-
const total = chunks.reduce((s, c) => s + c.length, 0)
|
|
122
|
-
const merged = new Uint8Array(total)
|
|
123
|
-
let offset = 0
|
|
124
|
-
for (const c of chunks) {
|
|
125
|
-
merged.set(c, offset)
|
|
126
|
-
offset += c.length
|
|
127
|
-
}
|
|
128
|
-
return merged
|
|
129
|
-
}
|
|
@@ -2282,99 +2282,3 @@ export function decodeMessage<T = Record<string, unknown>>(
|
|
|
2282
2282
|
const decoded = type.decode(data)
|
|
2283
2283
|
return type.toObject(decoded, { defaults: true, json: true, longs: Number }) as T
|
|
2284
2284
|
}
|
|
2285
|
-
|
|
2286
|
-
/** Decode without inventing absent proto defaults (used for byte-stable snapshots). */
|
|
2287
|
-
export function decodeMessageSparse<T = Record<string, unknown>>(
|
|
2288
|
-
typeName: string,
|
|
2289
|
-
data: Uint8Array,
|
|
2290
|
-
): T {
|
|
2291
|
-
const root = getMessageTypes()
|
|
2292
|
-
const type = root.lookupType(typeName)
|
|
2293
|
-
const decoded = type.decode(data)
|
|
2294
|
-
return type.toObject(decoded, { json: true, longs: Number }) as T
|
|
2295
|
-
}
|
|
2296
|
-
|
|
2297
|
-
type RawField = {
|
|
2298
|
-
field: number
|
|
2299
|
-
wireType: number
|
|
2300
|
-
varint?: string
|
|
2301
|
-
fixed?: number | string
|
|
2302
|
-
bytes?: Uint8Array
|
|
2303
|
-
}
|
|
2304
|
-
|
|
2305
|
-
/** Schema-free walk of one message's top-level wire fields (no nested descent). */
|
|
2306
|
-
function readRawFields(buf: Uint8Array): RawField[] {
|
|
2307
|
-
const reader = protobuf.Reader.create(buf)
|
|
2308
|
-
const fields: RawField[] = []
|
|
2309
|
-
while (reader.pos < reader.len) {
|
|
2310
|
-
const tag = reader.uint32()
|
|
2311
|
-
const field = tag >>> 3
|
|
2312
|
-
const wireType = tag & 7
|
|
2313
|
-
switch (wireType) {
|
|
2314
|
-
case 0:
|
|
2315
|
-
fields.push({ field, wireType, varint: reader.uint64().toString() })
|
|
2316
|
-
break
|
|
2317
|
-
case 1:
|
|
2318
|
-
fields.push({ field, wireType, fixed: reader.fixed64().toString() })
|
|
2319
|
-
break
|
|
2320
|
-
case 2:
|
|
2321
|
-
fields.push({ field, wireType, bytes: reader.bytes() })
|
|
2322
|
-
break
|
|
2323
|
-
case 5:
|
|
2324
|
-
fields.push({ field, wireType, fixed: reader.fixed32() })
|
|
2325
|
-
break
|
|
2326
|
-
default:
|
|
2327
|
-
// Groups (3/4) aren't used on this wire; bail rather than desync the reader.
|
|
2328
|
-
return fields
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
return fields
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
/**
|
|
2335
|
-
* Diagnostic-only: walk AgentServerMessage.interaction_update(1).turn_ended(14)
|
|
2336
|
-
* without going through our hand-written TurnEnded schema, so a `cache_write`/
|
|
2337
|
-
* `reasoning_tokens` question can be checked against the raw wire instead of
|
|
2338
|
-
* guessed. Confirmed field ids 1-5 (input/output/cache_read/cache_write/
|
|
2339
|
-
* reasoning) decode correctly. Live captures routinely include `f4` explicitly
|
|
2340
|
-
* as `0` while `f3` (cache_read) and `f5` (reasoning) are non-zero — Cursor's
|
|
2341
|
-
* agent TurnEnded populates the field but does not report write counts here.
|
|
2342
|
-
*/
|
|
2343
|
-
export function debugWalkTurnEnded(payload: Uint8Array): string {
|
|
2344
|
-
try {
|
|
2345
|
-
const top = readRawFields(payload)
|
|
2346
|
-
const iuField = top.find((f) => f.field === 1 && f.wireType === 2)
|
|
2347
|
-
if (!iuField?.bytes) return "(no interaction_update field)"
|
|
2348
|
-
const iu = readRawFields(iuField.bytes)
|
|
2349
|
-
const teField = iu.find((f) => f.field === 14 && f.wireType === 2)
|
|
2350
|
-
if (!teField?.bytes) return "(no turn_ended field in interaction_update)"
|
|
2351
|
-
const te = readRawFields(teField.bytes)
|
|
2352
|
-
return te
|
|
2353
|
-
.map(
|
|
2354
|
-
(f) =>
|
|
2355
|
-
`f${f.field}:wt${f.wireType}=${f.varint ?? f.fixed ?? (f.bytes ? `bytes[${f.bytes.length}]` : "?")}`,
|
|
2356
|
-
)
|
|
2357
|
-
.join(" ")
|
|
2358
|
-
} catch (e) {
|
|
2359
|
-
return `(walk failed: ${(e as Error).message})`
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
/**
|
|
2364
|
-
* Decode a protobuf sub-message from a frame payload that wraps it in
|
|
2365
|
-
* a top-level field key + length varint. Skips the outer wrapper and
|
|
2366
|
-
* decodes the inner body as `typeName`.
|
|
2367
|
-
*/
|
|
2368
|
-
export function decodeWrappedMessage<T = Record<string, unknown>>(
|
|
2369
|
-
typeName: string,
|
|
2370
|
-
data: Uint8Array,
|
|
2371
|
-
): T {
|
|
2372
|
-
let offset = 1 // skip field key
|
|
2373
|
-
// skip varint length
|
|
2374
|
-
while (offset < data.length) {
|
|
2375
|
-
const b = data[offset] ?? 0
|
|
2376
|
-
offset++
|
|
2377
|
-
if (!(b & 0x80)) break
|
|
2378
|
-
}
|
|
2379
|
-
return decodeMessage<T>(typeName, data.subarray(offset))
|
|
2380
|
-
}
|
|
@@ -106,7 +106,7 @@ function factoryClientHeaders(orgId: string): Record<string, string> {
|
|
|
106
106
|
* (`packages/ai/src/providers/factory-droid.ts:271` — `"x-api-provider":
|
|
107
107
|
* input.upstream`), so a value outside it has no meaning on this wire.
|
|
108
108
|
*/
|
|
109
|
-
|
|
109
|
+
const FACTORY_DROID_UPSTREAMS = [
|
|
110
110
|
"fireworks",
|
|
111
111
|
"baseten",
|
|
112
112
|
"mistral",
|
|
@@ -123,7 +123,7 @@ export const FACTORY_DROID_UPSTREAMS = [
|
|
|
123
123
|
"databricks",
|
|
124
124
|
] as const;
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
type FactoryDroidUpstream = (typeof FACTORY_DROID_UPSTREAMS)[number];
|
|
127
127
|
|
|
128
128
|
const FACTORY_DROID_UPSTREAM_SET: ReadonlySet<string> = new Set(FACTORY_DROID_UPSTREAMS);
|
|
129
129
|
|
|
@@ -154,7 +154,7 @@ function logDroppedUpstream(reason: string, value: string): void {
|
|
|
154
154
|
* unmapped failure. Omitting falls back to Factory's default routing, which is
|
|
155
155
|
* the behavior a request that names no upstream already gets.
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
function factoryApiProviderHeader(
|
|
158
158
|
options: Readonly<Record<string, unknown>> | undefined,
|
|
159
159
|
): Record<string, string> {
|
|
160
160
|
const value = options?.["factory_api_provider"];
|
|
@@ -179,7 +179,7 @@ export function factoryApiProviderHeader(
|
|
|
179
179
|
* `/api/cli/whoami` reported. An account with no recorded residency is the
|
|
180
180
|
* global host, which is Factory's default.
|
|
181
181
|
*/
|
|
182
|
-
|
|
182
|
+
function factoryBaseUrl(context: ProviderDispatchContext): string {
|
|
183
183
|
const region = context.credential.auth_state?.["region"];
|
|
184
184
|
return region === "eu" ? FACTORY_DROID_EU_BASE_URL : FACTORY_DROID_BASE_URL;
|
|
185
185
|
}
|
|
@@ -200,7 +200,7 @@ export function factoryBaseUrl(context: ProviderDispatchContext): string {
|
|
|
200
200
|
* operator wrote into `auth_state`. The two-axis read is kept because the donor
|
|
201
201
|
* needs it, not because we currently populate the second axis.
|
|
202
202
|
*/
|
|
203
|
-
|
|
203
|
+
function factoryInferenceRegion(
|
|
204
204
|
context: ProviderDispatchContext,
|
|
205
205
|
): "global" | "us" | "eu" {
|
|
206
206
|
const state = context.credential.auth_state;
|
|
@@ -266,7 +266,7 @@ const REGION_UPSTREAMS: Readonly<Record<"global" | "us" | "eu", readonly Factory
|
|
|
266
266
|
* is, which is a property of the route rather than of the request. The donor's
|
|
267
267
|
* own message text is preserved as the `reason` so the mapping is traceable.
|
|
268
268
|
*/
|
|
269
|
-
|
|
269
|
+
function factoryRegionUnavailable(modelId: string, region: string): GatewayError {
|
|
270
270
|
return new GatewayError(
|
|
271
271
|
"capability_unsupported",
|
|
272
272
|
400,
|
|
@@ -294,7 +294,7 @@ export function factoryRegionUnavailable(modelId: string, region: string): Gatew
|
|
|
294
294
|
* Sending `configured_order` without that discovery would claim a rotation we
|
|
295
295
|
* never resolved.
|
|
296
296
|
*/
|
|
297
|
-
|
|
297
|
+
function factoryRoutingSourceHeader(request: CanonicalRequest): Record<string, string> {
|
|
298
298
|
const continuing = request.messages.some((message) => message.role === "assistant");
|
|
299
299
|
return { "x-provider-routing-source": continuing ? "session_lock" : "registry_default" };
|
|
300
300
|
}
|
|
@@ -313,7 +313,7 @@ export function factoryRoutingSourceHeader(request: CanonicalRequest): Record<st
|
|
|
313
313
|
* donor's own region-unavailable error rather than an upstream 4xx this layer
|
|
314
314
|
* cannot explain.
|
|
315
315
|
*/
|
|
316
|
-
|
|
316
|
+
function factoryRegionCheckedApiProviderHeader(
|
|
317
317
|
request: CanonicalRequest,
|
|
318
318
|
context: ProviderDispatchContext,
|
|
319
319
|
): Record<string, string> {
|
|
@@ -330,7 +330,7 @@ export function factoryRegionCheckedApiProviderHeader(
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
/** The two routing headers together, as every Factory wire sends them. */
|
|
333
|
-
|
|
333
|
+
function factoryRoutingHeaders(
|
|
334
334
|
request: CanonicalRequest,
|
|
335
335
|
context: ProviderDispatchContext,
|
|
336
336
|
): Record<string, string> {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
GITHUB_PROVIDER_ID,
|
|
30
30
|
GITHUB_ENDPOINT_PATH,
|
|
31
31
|
GITHUB_RESPONSES_ENDPOINT_PATH,
|
|
32
|
+
GITHUB_MESSAGES_ENDPOINT_PATH,
|
|
32
33
|
GITHUB_AUTO_MODELS,
|
|
33
34
|
recordGithubModelRoutes,
|
|
34
35
|
} from "./github";
|
|
@@ -47,12 +48,11 @@ function positiveLimit(value: unknown): number | undefined {
|
|
|
47
48
|
* The surfaces a row answers on, normalized to the canonical paths this
|
|
48
49
|
* gateway registers.
|
|
49
50
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* row as chat would publish a route that fails on first dispatch.
|
|
51
|
+
* Copilot serves three OpenAI/Anthropic surfaces: `/chat/completions`,
|
|
52
|
+
* `/responses`, and `/v1/messages`. A row that supports none of them is
|
|
53
|
+
* skipped rather than defaulted.
|
|
54
54
|
*/
|
|
55
|
-
function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | undefined {
|
|
55
|
+
function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | "messages" | undefined {
|
|
56
56
|
const declared = boundedUpstreamArray(entry.supported_endpoints);
|
|
57
57
|
if (!declared) return "chat";
|
|
58
58
|
const endpoints = new Set<string>();
|
|
@@ -60,11 +60,12 @@ function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | u
|
|
|
60
60
|
const label = sanitizeUpstreamLabel(value);
|
|
61
61
|
if (label !== undefined) endpoints.add(label.replace(/^\/v1(?=\/)/, ""));
|
|
62
62
|
}
|
|
63
|
-
// Chat is preferred when a row supports
|
|
64
|
-
// OpenAI-compatible client already speaks
|
|
65
|
-
//
|
|
63
|
+
// Chat is preferred when a row supports it: it is the surface every
|
|
64
|
+
// OpenAI-compatible client already speaks. Responses and Messages are used
|
|
65
|
+
// only when chat is absent, in that order.
|
|
66
66
|
if (endpoints.has("/chat/completions")) return "chat";
|
|
67
67
|
if (endpoints.has("/responses")) return "responses";
|
|
68
|
+
if (endpoints.has("/messages")) return "messages";
|
|
68
69
|
return undefined;
|
|
69
70
|
}
|
|
70
71
|
|
|
@@ -75,6 +76,34 @@ function supports(entry: Record<string, unknown>, key: string): boolean {
|
|
|
75
76
|
return declared?.[key] === true;
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Price deltas from the account's `/models` row when it publishes `token_prices`
|
|
81
|
+
* (dollars per 1M tokens). This is the real per-account price Copilot serves,
|
|
82
|
+
* which the shared models.dev catalog cannot know; when absent the base-catalog
|
|
83
|
+
* estimate is used instead.
|
|
84
|
+
*/
|
|
85
|
+
function copilotCost(entry: Record<string, unknown>): ModelDefinition["cost"] {
|
|
86
|
+
const billing = isRecord(entry.billing) ? entry.billing : undefined;
|
|
87
|
+
const prices = isRecord(billing?.token_prices) ? billing.token_prices : undefined;
|
|
88
|
+
const defaultTier = isRecord(prices?.default) ? prices.default : undefined;
|
|
89
|
+
const input = positiveLimit(defaultTier?.input_price);
|
|
90
|
+
const output = positiveLimit(defaultTier?.output_price);
|
|
91
|
+
if (input === undefined && output === undefined) {
|
|
92
|
+
return modelsDevCatalog.costFor(GITHUB_PROVIDER_ID, String(entry.id ?? ""));
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
input: input ?? null,
|
|
96
|
+
output: output ?? null,
|
|
97
|
+
...(typeof (defaultTier as Record<string, unknown> | undefined)?.cache_read_price === "number"
|
|
98
|
+
? { cache_read: (defaultTier as { cache_read_price?: number }).cache_read_price }
|
|
99
|
+
: {}),
|
|
100
|
+
...(typeof (defaultTier as Record<string, unknown> | undefined)?.cache_write_price === "number"
|
|
101
|
+
? { cache_write: (defaultTier as { cache_write_price?: number }).cache_write_price }
|
|
102
|
+
: {}),
|
|
103
|
+
pricing_model: "pay-per-use",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
78
107
|
function toModelDefinition(entry: Record<string, unknown>): ModelDefinition | undefined {
|
|
79
108
|
const modelId = sanitizeUpstreamLabel(entry.id);
|
|
80
109
|
if (modelId === undefined) return undefined;
|
|
@@ -89,16 +118,32 @@ function toModelDefinition(entry: Record<string, unknown>): ModelDefinition | un
|
|
|
89
118
|
// clamped the same way every other catalog row is.
|
|
90
119
|
const outputLimit = Math.min(declaredOutput, contextLimit);
|
|
91
120
|
const vision = supports(entry, "vision");
|
|
121
|
+
// `reasoning_effort` is a list (e.g. ["low","medium","high","xhigh","max"])
|
|
122
|
+
// when the model supports effort levels; absence means the model does not
|
|
123
|
+
// expose an effort knob. Carrying it lets routing clamp to the model's real
|
|
124
|
+
// ladder instead of the provider-wide `max→high` cap.
|
|
125
|
+
const supportsObj = isRecord(capabilities?.supports) ? capabilities.supports : undefined;
|
|
126
|
+
const reasoningEfforts = Array.isArray(supportsObj?.reasoning_effort)
|
|
127
|
+
? (supportsObj.reasoning_effort as unknown[])
|
|
128
|
+
.filter((level): level is string => typeof level === "string" && level.length > 0)
|
|
129
|
+
: undefined;
|
|
130
|
+
const cost = copilotCost(entry);
|
|
92
131
|
return {
|
|
93
132
|
modelId,
|
|
94
133
|
wireFamily,
|
|
95
|
-
endpointPath:
|
|
134
|
+
endpointPath:
|
|
135
|
+
wireFamily === "responses"
|
|
136
|
+
? GITHUB_RESPONSES_ENDPOINT_PATH
|
|
137
|
+
: wireFamily === "messages"
|
|
138
|
+
? GITHUB_MESSAGES_ENDPOINT_PATH
|
|
139
|
+
: GITHUB_ENDPOINT_PATH,
|
|
96
140
|
contextLimit,
|
|
97
141
|
outputLimit,
|
|
98
142
|
modalities: { input: vision ? ["text", "image"] : ["text"], output: ["text"] },
|
|
99
143
|
reasoning: true,
|
|
144
|
+
...(reasoningEfforts === undefined ? {} : { reasoningEfforts }),
|
|
100
145
|
toolCall: true,
|
|
101
|
-
cost
|
|
146
|
+
cost,
|
|
102
147
|
};
|
|
103
148
|
}
|
|
104
149
|
|
|
@@ -43,13 +43,14 @@ export const GITHUB_DEFAULT_API_HOST = "api.individual.githubcopilot.com" as con
|
|
|
43
43
|
* The API rejects a request that does not identify a Copilot client, so these
|
|
44
44
|
* are a protocol requirement rather than cosmetic fingerprinting — unlike the
|
|
45
45
|
* Codex/Claude CLI identities elsewhere in this repository, which exist to look
|
|
46
|
-
* like a first-party client. The version pair is the Copilot Chat extension's
|
|
47
|
-
* which is what the upstream expects for this
|
|
46
|
+
* like a first-party client. The version pair is the Copilot Chat extension's
|
|
47
|
+
* (0.72.0 on VS Code 1.144), which is what the upstream expects for this
|
|
48
|
+
* client id.
|
|
48
49
|
*/
|
|
49
50
|
export const GITHUB_REQUEST_HEADERS: Readonly<Record<string, string>> = Object.freeze({
|
|
50
|
-
"user-agent": "GitHubCopilotChat/0.
|
|
51
|
-
"editor-version": "vscode/1.
|
|
52
|
-
"editor-plugin-version": "copilot-chat/0.
|
|
51
|
+
"user-agent": "GitHubCopilotChat/0.72.0",
|
|
52
|
+
"editor-version": "vscode/1.144.0",
|
|
53
|
+
"editor-plugin-version": "copilot-chat/0.72.0",
|
|
53
54
|
"copilot-integration-id": "vscode-chat",
|
|
54
55
|
"x-github-api-version": "2026-08-01",
|
|
55
56
|
});
|