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
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
FALLBACK_CLIENT_VERSION,
|
|
17
17
|
RUN_PATH,
|
|
18
18
|
isAllowedAgentHost,
|
|
19
|
+
resolveCursorTimezone,
|
|
19
20
|
} from "./cursor-shared";
|
|
20
21
|
import { createCursorChecksumHeader, resolveCursorDeviceIds } from "./cursor-identity";
|
|
21
22
|
|
|
@@ -102,6 +103,7 @@ async function runHeaders(credential: string, clientVersion: string): Promise<Re
|
|
|
102
103
|
"x-cursor-streaming": "true",
|
|
103
104
|
"x-ghost-mode": "true",
|
|
104
105
|
"x-request-id": crypto.randomUUID(),
|
|
106
|
+
...(resolveCursorTimezone() === "" ? {} : { "x-cursor-timezone": resolveCursorTimezone() }),
|
|
105
107
|
"user-agent": "connect-es/1.6.1",
|
|
106
108
|
};
|
|
107
109
|
}
|
|
@@ -23,8 +23,6 @@ import { encodeJsonAsValue } from "./protocol/struct";
|
|
|
23
23
|
// a caller has to discover separately.
|
|
24
24
|
export {
|
|
25
25
|
CURSOR_TOOL_VARIANTS,
|
|
26
|
-
CursorToolCallProvenance,
|
|
27
|
-
cursorNativeToolDeclaration,
|
|
28
26
|
cursorToolArm,
|
|
29
27
|
decodeCursorNativeToolCall,
|
|
30
28
|
} from "./protocol/tool-canonical";
|
|
@@ -221,7 +219,9 @@ export function systemPromptFrom(request: CanonicalRequest): string | undefined
|
|
|
221
219
|
*/
|
|
222
220
|
export function historyFromRequest(request: CanonicalRequest): CursorHistoryEntry[] {
|
|
223
221
|
const entries: CursorHistoryEntry[] = [];
|
|
224
|
-
|
|
222
|
+
const liveIndex = lastLiveUserMessageIndex(request);
|
|
223
|
+
for (const [index, message] of request.messages.entries()) {
|
|
224
|
+
if (index === liveIndex) continue;
|
|
225
225
|
const text = messageText(message);
|
|
226
226
|
if (text.trim().length === 0) continue;
|
|
227
227
|
if (message.role === "assistant") entries.push({ role: "assistant", content: text });
|
|
@@ -237,9 +237,6 @@ export function buildRunRequest(input: {
|
|
|
237
237
|
readonly text: string;
|
|
238
238
|
readonly modelId: string;
|
|
239
239
|
readonly conversationId: string;
|
|
240
|
-
/** Stable parent group; unlike the conversation id it survives a rebase. */
|
|
241
|
-
readonly conversationGroupId?: string;
|
|
242
|
-
readonly runId?: string;
|
|
243
240
|
readonly messageId?: string;
|
|
244
241
|
readonly history?: readonly CursorHistoryEntry[];
|
|
245
242
|
/** Cursor-declared parameter tuple (effort/context/fast) for this model. */
|
|
@@ -279,12 +276,17 @@ export function buildRunRequest(input: {
|
|
|
279
276
|
userMessageAction["request_context"] = requestContext;
|
|
280
277
|
const runRequest: Record<string, unknown> = {
|
|
281
278
|
conversation_id: input.conversationId,
|
|
282
|
-
conversation_group_id: input.conversationGroupId ?? input.conversationId,
|
|
283
|
-
run_id: input.runId ?? messageId,
|
|
284
279
|
action:
|
|
285
280
|
input.action === "resume"
|
|
286
281
|
? { resume_action: { request_context: requestContext } }
|
|
287
282
|
: { user_message_action: userMessageAction },
|
|
283
|
+
// `model_details` (#3) carries the safe wire id; `requested_model` (#9)
|
|
284
|
+
// carries the parameter tuple. Matches `agent.proto` exactly — the old
|
|
285
|
+
// schema invented extra fields that have no wire meaning.
|
|
286
|
+
model_details: {
|
|
287
|
+
model_id: input.modelId,
|
|
288
|
+
max_mode: input.maxMode ?? false,
|
|
289
|
+
},
|
|
288
290
|
requested_model: {
|
|
289
291
|
model_id: input.modelId,
|
|
290
292
|
max_mode: input.maxMode ?? false,
|
|
@@ -292,8 +294,6 @@ export function buildRunRequest(input: {
|
|
|
292
294
|
},
|
|
293
295
|
conversation_state: seeded ? buildSeedConversationState() : input.conversationState,
|
|
294
296
|
mcp_tools: { mcp_tools: [] },
|
|
295
|
-
unknown_flag: 0,
|
|
296
|
-
field_12: 0,
|
|
297
297
|
};
|
|
298
298
|
return encodeMessage("AgentClientMessage", { run_request: runRequest });
|
|
299
299
|
}
|
|
@@ -311,9 +311,12 @@ export function buildExecStreamClose(execId: number, execIdString?: string): Uin
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
/** Stops the live Run, as Cursor CLI does before closing the stream. */
|
|
314
|
-
export function buildCancelAction(
|
|
314
|
+
export function buildCancelAction(_reason: string): Uint8Array {
|
|
315
|
+
// `agent.proto` CancelAction is empty — the oneof presence is the signal,
|
|
316
|
+
// and the reason travels out-of-band (stream close). Sending a `reason`
|
|
317
|
+
// field would encode bytes the server does not expect.
|
|
315
318
|
return encodeMessage("AgentClientMessage", {
|
|
316
|
-
conversation_action: { cancel_action: {
|
|
319
|
+
conversation_action: { cancel_action: {} },
|
|
317
320
|
});
|
|
318
321
|
}
|
|
319
322
|
|
|
@@ -440,15 +443,18 @@ export function buildMcpRejected(
|
|
|
440
443
|
* `ACM#2 exec_client_message{*_allowlist_precheck_result}` for frames 41/42/43.
|
|
441
444
|
*
|
|
442
445
|
* Cursor asks whether a shell command, MCP tool, or web fetch would be
|
|
443
|
-
* permitted *before* it emits the real call.
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
446
|
+
* permitted *before* it emits the real call.
|
|
447
|
+
*
|
|
448
|
+
* - `shell` → `true`: the native executor runs shell locally.
|
|
449
|
+
* - `mcp` → `true` only when the tool is client-declared (relayed); the
|
|
450
|
+
* caller decides on the `allowlisted` flag.
|
|
451
|
+
* - `web_fetch` → `false`: web fetch is not executed by this gateway.
|
|
447
452
|
*/
|
|
448
453
|
export function buildAllowlistPrecheckResult(
|
|
449
454
|
execId: number,
|
|
450
455
|
kind: "shell" | "mcp" | "web_fetch",
|
|
451
|
-
execIdString
|
|
456
|
+
execIdString: string | undefined,
|
|
457
|
+
allowlisted: boolean,
|
|
452
458
|
): Uint8Array {
|
|
453
459
|
const frame =
|
|
454
460
|
kind === "shell"
|
|
@@ -457,7 +463,7 @@ export function buildAllowlistPrecheckResult(
|
|
|
457
463
|
? "mcp_allowlist_precheck_result"
|
|
458
464
|
: "web_fetch_allowlist_precheck_result";
|
|
459
465
|
return encodeMessage("AgentClientMessage", {
|
|
460
|
-
exec_client_message: { id: execId, exec_id: execIdString ?? "", [frame]: { allowlisted
|
|
466
|
+
exec_client_message: { id: execId, exec_id: execIdString ?? "", [frame]: { allowlisted } },
|
|
461
467
|
});
|
|
462
468
|
}
|
|
463
469
|
|
|
@@ -529,12 +535,21 @@ function toolResultText(part: Extract<ContentPart, { kind: "toolResult" }>): str
|
|
|
529
535
|
* only the current prompt.
|
|
530
536
|
*/
|
|
531
537
|
export function liveUserText(request: CanonicalRequest): string {
|
|
538
|
+
const index = lastLiveUserMessageIndex(request);
|
|
539
|
+
if (index === -1) return "";
|
|
540
|
+
const message = request.messages[index];
|
|
541
|
+
if (message === undefined) return "";
|
|
542
|
+
return messageText(message);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/** Index of the current user/tool turn Cursor should send as the live prompt. */
|
|
546
|
+
function lastLiveUserMessageIndex(request: CanonicalRequest): number {
|
|
532
547
|
for (let index = request.messages.length - 1; index >= 0; index -= 1) {
|
|
533
548
|
const message = request.messages[index];
|
|
534
549
|
if (message === undefined) continue;
|
|
535
550
|
if (message.role !== "user" && message.role !== "tool") continue;
|
|
536
551
|
const text = messageText(message);
|
|
537
|
-
if (text.trim().length > 0) return
|
|
552
|
+
if (text.trim().length > 0) return index;
|
|
538
553
|
}
|
|
539
|
-
return
|
|
554
|
+
return -1;
|
|
540
555
|
}
|
|
@@ -33,7 +33,7 @@ export const CURSOR_OAUTH_CLIENT_ID = "KbZUR41cY7W6zRSdpSUJ7I7mLYBKOCmB";
|
|
|
33
33
|
* operator was not what the request carried. Discovery supersedes both on its
|
|
34
34
|
* first successful fetch.
|
|
35
35
|
*/
|
|
36
|
-
export const FALLBACK_CLIENT_VERSION = "cli-
|
|
36
|
+
export const FALLBACK_CLIENT_VERSION = "cli-3.29.9-306d153";
|
|
37
37
|
|
|
38
38
|
/** Connect-RPC paths. Run is served by the discovered agent origin, not the API host. */
|
|
39
39
|
export const RUN_PATH = "/agent.v1.AgentService/Run";
|
|
@@ -44,6 +44,24 @@ export const SERVER_CONFIG_PATH = "/aiserver.v1.ServerConfigService/GetServerCon
|
|
|
44
44
|
export const CONTENT_TYPE_CONNECT_PROTO = "application/connect+proto";
|
|
45
45
|
export const CONNECT_PROTOCOL_VERSION = "1";
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* The client's timezone name, as the CLI sends on every request
|
|
49
|
+
* (`Intl.DateTimeFormat().resolvedOptions().timeZone`). Computed once: the
|
|
50
|
+
* value is stable for one process and the call is not cheap enough to repeat
|
|
51
|
+
* per request.
|
|
52
|
+
*/
|
|
53
|
+
let cachedTimezone: string | undefined;
|
|
54
|
+
export function resolveCursorTimezone(): string {
|
|
55
|
+
if (cachedTimezone !== undefined) return cachedTimezone;
|
|
56
|
+
try {
|
|
57
|
+
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
58
|
+
cachedTimezone = typeof zone === "string" && zone.length > 0 ? zone : "";
|
|
59
|
+
} catch {
|
|
60
|
+
cachedTimezone = "";
|
|
61
|
+
}
|
|
62
|
+
return cachedTimezone;
|
|
63
|
+
}
|
|
64
|
+
|
|
47
65
|
/** A raw Cursor API key (as opposed to a JWT already exchanged from one). */
|
|
48
66
|
const CURSOR_API_KEY_PREFIX = "crsr_";
|
|
49
67
|
|
|
@@ -65,11 +83,14 @@ export const SESSION_REFRESH_TIMEOUT_MS = 20_000;
|
|
|
65
83
|
|
|
66
84
|
/**
|
|
67
85
|
* How long a live Cursor Run is held open waiting for the client's next
|
|
68
|
-
* tool-result request. Matches the donor's
|
|
69
|
-
*
|
|
70
|
-
* a pool slot for the life
|
|
86
|
+
* tool-result request. Matches the donor's relay hold (`CURSOR_RELAY_IDLE_
|
|
87
|
+
* TIMEOUT_MS` in oh-my-pi: 30 minutes): a tool round the client never answers
|
|
88
|
+
* must not hold an HTTP/2 stream, an account lease, or a pool slot for the life
|
|
89
|
+
* of the process, but a human-approved tool round often takes longer than ten
|
|
90
|
+
* minutes — a shorter TTL expired the Run mid-approval and forced the client to
|
|
91
|
+
* resend the whole conversation.
|
|
71
92
|
*/
|
|
72
|
-
export const RUN_IDLE_TTL_MS =
|
|
93
|
+
export const RUN_IDLE_TTL_MS = 30 * 60_000;
|
|
73
94
|
|
|
74
95
|
/**
|
|
75
96
|
* Any HTTPS subdomain of `cursor.sh` is an acceptable Run host: the region
|
|
@@ -61,8 +61,10 @@ import { fetchCursorRunOrigin } from "./cursor-catalog";
|
|
|
61
61
|
import { defaultParameterValues, fetchCursorModels } from "./cursor-catalog";
|
|
62
62
|
import type { CursorModelInfo } from "./cursor-catalog";
|
|
63
63
|
import { decodeValueToJson, decodeStructEntriesToJson } from "./protocol/struct";
|
|
64
|
-
import {
|
|
64
|
+
import { encodeMessage } from "./protocol/messages";
|
|
65
|
+
import { executeNativeTool, resolveExecFrame } from "./cursor-exec";
|
|
65
66
|
import { fnv1a32 } from "../shared/hash";
|
|
67
|
+
import { TtlCache } from "../../../persistence/ttl-cache";
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
70
|
* Client-heartbeat cadence for every Cursor Run.
|
|
@@ -83,25 +85,25 @@ const CURSOR_HEARTBEAT_INTERVAL_MS = 5_000;
|
|
|
83
85
|
*/
|
|
84
86
|
const CURSOR_ROSTER_TTL_MS = 300_000;
|
|
85
87
|
/**
|
|
86
|
-
* credential →
|
|
88
|
+
* credential → roster for the parameter lookup.
|
|
87
89
|
*
|
|
88
90
|
* Keyed by an FNV-1a digest of the credential rather than the raw token so a
|
|
89
91
|
* long-lived map does not hold live credentials as keys. Bounded by
|
|
90
|
-
* `ROSTER_CACHE_MAX` with
|
|
91
|
-
*
|
|
92
|
+
* `ROSTER_CACHE_MAX` with LRU eviction: the TTL is only checked on read, so
|
|
93
|
+
* without a cap rotated tokens would grow the map without bound. Implemented
|
|
94
|
+
* by the canonical `TtlCache` in LRU mode — re-setting moves the entry to the
|
|
95
|
+
* newest position, and the cap evicts the least-recently-used entry.
|
|
92
96
|
*/
|
|
93
97
|
const ROSTER_CACHE_MAX = 1024;
|
|
94
|
-
const rosterCache = new
|
|
98
|
+
const rosterCache = new TtlCache<{ roster: readonly CursorModelInfo[] }>({
|
|
99
|
+
ttlMs: CURSOR_ROSTER_TTL_MS,
|
|
100
|
+
maxEntries: ROSTER_CACHE_MAX,
|
|
101
|
+
lru: true,
|
|
102
|
+
});
|
|
95
103
|
|
|
96
104
|
function rosterCacheSet(credential: string, roster: readonly CursorModelInfo[]): void {
|
|
97
105
|
const key = String(fnv1a32(credential));
|
|
98
|
-
rosterCache.
|
|
99
|
-
rosterCache.set(key, { roster, fetchedAt: Date.now() });
|
|
100
|
-
while (rosterCache.size > ROSTER_CACHE_MAX) {
|
|
101
|
-
const oldest = rosterCache.keys().next().value;
|
|
102
|
-
if (oldest === undefined) break;
|
|
103
|
-
rosterCache.delete(oldest);
|
|
104
|
-
}
|
|
106
|
+
rosterCache.set(key, { roster });
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
/**
|
|
@@ -111,7 +113,7 @@ function rosterCacheSet(credential: string, roster: readonly CursorModelInfo[]):
|
|
|
111
113
|
export const rosterCacheForTests = {
|
|
112
114
|
size: (): number => rosterCache.size,
|
|
113
115
|
set: rosterCacheSet,
|
|
114
|
-
get: (credential: string): { roster: readonly CursorModelInfo[]
|
|
116
|
+
get: (credential: string): { roster: readonly CursorModelInfo[] } | undefined =>
|
|
115
117
|
rosterCache.get(String(fnv1a32(credential))),
|
|
116
118
|
};
|
|
117
119
|
/** Client-heartbeat cadence the Cursor edge expects (donor `heartbeatMs`). */
|
|
@@ -538,26 +540,56 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
538
540
|
);
|
|
539
541
|
}
|
|
540
542
|
const resolvedAll = pending.map((item) => cursorRunSessions.resolveCall(item.callId, scope));
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
//
|
|
545
|
-
//
|
|
546
|
-
//
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
543
|
+
const resolved = resolvedAll.filter((entry) => entry !== undefined);
|
|
544
|
+
const allSameRun =
|
|
545
|
+
resolved.length === pending.length && new Set(resolved.map((entry) => entry.session.runId)).size === 1;
|
|
546
|
+
// A call id that is live in this process but resolves to nothing under this
|
|
547
|
+
// caller's scope belongs to another tenant's Run. Rebasing over it would
|
|
548
|
+
// surface that conversation under this caller — always a hard refusal.
|
|
549
|
+
const foreignLive = pending.some(
|
|
550
|
+
(item) =>
|
|
551
|
+
cursorRunSessions.resolveCall(item.callId, scope) === undefined &&
|
|
552
|
+
cursorRunSessions.hasAnyCall(item.callId),
|
|
553
|
+
);
|
|
554
|
+
// Complete-replay rebase (donor / oh-my-pi behavior): when the request is
|
|
555
|
+
// the full transcript — every `call_cursor_*` result it carries is paired
|
|
556
|
+
// with a `toolCall` in the same conversation — and no foreign-live call is
|
|
557
|
+
// involved, cancel whatever live Runs its ids still touch and rebuild a
|
|
558
|
+
// fresh Run from history. This covers the cases the old code refused with
|
|
559
|
+
// a hard 400: a replay mixing results of an already-answered leg with a
|
|
560
|
+
// live one ("mixes live Cursor tool results"), and results spanning
|
|
561
|
+
// multiple live Runs. A hard refusal there is what stalled the client loop
|
|
562
|
+
// every time Cursor replays a superseded transcript; the donor instead
|
|
563
|
+
// closes the parked runs and answers with a fresh turn.
|
|
564
|
+
if (!allSameRun && !foreignLive && isCompleteToolHistoryReplay(request, pending)) {
|
|
565
|
+
for (const entry of resolved) {
|
|
566
|
+
cursorRunSessions.terminate(entry.session.runId, "Cursor Run superseded by a rebase");
|
|
567
|
+
this.#handles.delete(entry.session.runId);
|
|
568
|
+
this.cleanupReader(entry.session.runId);
|
|
569
|
+
}
|
|
555
570
|
yield* this.#startRun(request, candidate, context);
|
|
556
571
|
return;
|
|
557
572
|
}
|
|
558
|
-
const resolved = resolvedAll.filter((entry) => entry !== undefined);
|
|
559
573
|
const runId = resolved[0]?.session.runId;
|
|
560
|
-
if (
|
|
574
|
+
if (!allSameRun) {
|
|
575
|
+
// Not a safe rebase. Two distinct cases:
|
|
576
|
+
// 1. A partial tail — a result whose `toolCall` is absent from the sent
|
|
577
|
+
// conversation. That is not a complete replay, so there is nothing
|
|
578
|
+
// safe to rebase; name the missing ids so the client can resend the
|
|
579
|
+
// whole transcript.
|
|
580
|
+
// 2. A complete replay that still resolves to mixed runs — either a call
|
|
581
|
+
// id live under another scope (foreignLive, hard refusal) or results
|
|
582
|
+
// spanning more than one live Run with a transcript that is not a
|
|
583
|
+
// complete replay. Both stay refused rather than partially applied.
|
|
584
|
+
const missing = missingToolCallIds(request, pending);
|
|
585
|
+
if (missing.length > 0) {
|
|
586
|
+
throw new GatewayError(
|
|
587
|
+
"invalid_request",
|
|
588
|
+
400,
|
|
589
|
+
"This tool result has no matching tool call in the sent conversation (request {requestId}); resend the complete conversation. The session went cold — reconnect or resend 🔌",
|
|
590
|
+
{ callIds: missing },
|
|
591
|
+
);
|
|
592
|
+
}
|
|
561
593
|
throw new GatewayError(
|
|
562
594
|
"invalid_request",
|
|
563
595
|
400,
|
|
@@ -565,12 +597,10 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
565
597
|
{ callIds: pending.map((item) => item.callId) },
|
|
566
598
|
);
|
|
567
599
|
}
|
|
568
|
-
if (
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
"These tool results belong to different Cursor Runs (request {requestId}); resend them one Run at a time. The session went cold — reconnect or resend 🔌",
|
|
573
|
-
);
|
|
600
|
+
if (runId === undefined) {
|
|
601
|
+
// Unreachable: every path that leaves `allSameRun` false throws above or
|
|
602
|
+
// rebases. This keeps the non-null narrowing legible for the rest.
|
|
603
|
+
throw new GatewayError("invalid_request", 400, "Cursor Run is no longer live (request {requestId}). The session went cold — reconnect or resend 🔌");
|
|
574
604
|
}
|
|
575
605
|
const session = cursorRunSessions.get(runId);
|
|
576
606
|
if (session === undefined) {
|
|
@@ -703,7 +733,6 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
703
733
|
text: liveUserText(request),
|
|
704
734
|
modelId,
|
|
705
735
|
conversationId,
|
|
706
|
-
runId,
|
|
707
736
|
...(images.length > 0 ? { images } : {}),
|
|
708
737
|
...(descriptors.length > 0 ? { descriptors } : {}),
|
|
709
738
|
...(systemPrompt === undefined ? {} : { systemPrompt }),
|
|
@@ -878,10 +907,11 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
878
907
|
context: ProviderDispatchContext,
|
|
879
908
|
): Promise<readonly CursorModelInfo[]> {
|
|
880
909
|
const key = String(fnv1a32(credential));
|
|
910
|
+
// Peek first: `get` deletes expired entries, but the stale roster must
|
|
911
|
+
// survive as the fallback when the refetch fails (see the catch below).
|
|
912
|
+
const stale = rosterCache.peek(key);
|
|
881
913
|
const cached = rosterCache.get(key);
|
|
882
|
-
if (cached !== undefined
|
|
883
|
-
return cached.roster;
|
|
884
|
-
}
|
|
914
|
+
if (cached !== undefined) return cached.roster;
|
|
885
915
|
try {
|
|
886
916
|
const roster = await fetchCursorModels({
|
|
887
917
|
credential,
|
|
@@ -893,7 +923,7 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
893
923
|
rosterCacheSet(credential, roster);
|
|
894
924
|
return roster;
|
|
895
925
|
} catch {
|
|
896
|
-
return
|
|
926
|
+
return stale?.roster ?? [];
|
|
897
927
|
}
|
|
898
928
|
}
|
|
899
929
|
|
|
@@ -929,6 +959,8 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
929
959
|
if (execServer !== undefined) {
|
|
930
960
|
const handled = await this.#handleExecServerMessage(execServer, session, handle);
|
|
931
961
|
if (handled.kind !== "tool_call") continue;
|
|
962
|
+
// Only MCP arms are relayed to the client for execution (client-
|
|
963
|
+
// declared tools). Native tools are answered in-band by the executor.
|
|
932
964
|
const callId = `call_cursor_${runId}_${handled.execId}`;
|
|
933
965
|
const scope = context.continuation_scope;
|
|
934
966
|
if (scope === undefined) {
|
|
@@ -1107,9 +1139,9 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
1107
1139
|
return { kind: "handled" };
|
|
1108
1140
|
}
|
|
1109
1141
|
// Allowlist prechecks precede the real call. They are approval probes, not
|
|
1110
|
-
// invocations
|
|
1111
|
-
//
|
|
1112
|
-
//
|
|
1142
|
+
// invocations. Shell is allowlisted because the native executor runs it
|
|
1143
|
+
// locally; MCP is allowlisted only when the tool is client-declared
|
|
1144
|
+
// (relayed to the client); web fetch is never executed and stays denied.
|
|
1113
1145
|
const precheckKind = recordOf(execServer["shell_allowlist_precheck_args"]) !== undefined
|
|
1114
1146
|
? "shell"
|
|
1115
1147
|
: recordOf(execServer["mcp_allowlist_precheck_args"]) !== undefined
|
|
@@ -1118,35 +1150,37 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
1118
1150
|
? "web_fetch"
|
|
1119
1151
|
: undefined;
|
|
1120
1152
|
if (precheckKind !== undefined) {
|
|
1121
|
-
|
|
1153
|
+
const allowlisted =
|
|
1154
|
+
precheckKind === "shell" ? true
|
|
1155
|
+
: precheckKind === "web_fetch" ? false
|
|
1156
|
+
: this.mcpArgsAreDeclared(execServer, session.descriptors);
|
|
1157
|
+
await handle.write(buildAllowlistPrecheckResult(execId, precheckKind, execIdString, allowlisted));
|
|
1122
1158
|
return { kind: "handled" };
|
|
1123
1159
|
}
|
|
1124
|
-
// Native
|
|
1125
|
-
//
|
|
1126
|
-
//
|
|
1127
|
-
//
|
|
1128
|
-
//
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
arguments: JSON.stringify(nativeCall.args),
|
|
1145
|
-
};
|
|
1160
|
+
// Native exec frames (`read_args`, `shell_args`, `ct_read_args`, …) are
|
|
1161
|
+
// executed locally by this gateway — not relayed to the client and not
|
|
1162
|
+
// refused. The executor returns the wire result message for the frame's
|
|
1163
|
+
// result oneof, so a reply can only come back in the arm it arrived on.
|
|
1164
|
+
// Frames the executor does not implement fall through to the refusal.
|
|
1165
|
+
const execFrame = resolveExecFrame(execServer);
|
|
1166
|
+
if (execFrame !== undefined) {
|
|
1167
|
+
const executed = await executeNativeTool(execFrame.frameKey, execFrame.args, process.cwd());
|
|
1168
|
+
if (executed !== undefined) {
|
|
1169
|
+
await handle.write(
|
|
1170
|
+
encodeMessage("AgentClientMessage", {
|
|
1171
|
+
exec_client_message: {
|
|
1172
|
+
id: execId,
|
|
1173
|
+
exec_id: execIdString ?? "",
|
|
1174
|
+
[executed.field]: executed.message,
|
|
1175
|
+
},
|
|
1176
|
+
}),
|
|
1177
|
+
);
|
|
1178
|
+
return { kind: "handled" };
|
|
1179
|
+
}
|
|
1146
1180
|
}
|
|
1147
|
-
// MCP
|
|
1148
|
-
//
|
|
1149
|
-
//
|
|
1181
|
+
// MCP remains for client-declared tools: they have no native slot, so a
|
|
1182
|
+
// declared `mcp_args` arm is relayed to the client as an ordinary tool
|
|
1183
|
+
// call. Undeclared MCP is refused.
|
|
1150
1184
|
const mcpArgs = recordOf(execServer["mcp_args"]);
|
|
1151
1185
|
if (mcpArgs !== undefined) {
|
|
1152
1186
|
const call = readExecutableMcpCall(mcpArgs, session.descriptors);
|
|
@@ -1170,6 +1204,21 @@ class CursorAdapter implements ProviderAdapter {
|
|
|
1170
1204
|
return { kind: "handled" };
|
|
1171
1205
|
}
|
|
1172
1206
|
|
|
1207
|
+
/**
|
|
1208
|
+
* True when an MCP allowlist precheck targets a tool the request actually
|
|
1209
|
+
* declared (so it can be relayed to the client). Undeclared MCP is denied.
|
|
1210
|
+
*/
|
|
1211
|
+
mcpArgsAreDeclared(
|
|
1212
|
+
execServer: Record<string, unknown>,
|
|
1213
|
+
descriptors: readonly CursorToolDescriptor[],
|
|
1214
|
+
): boolean {
|
|
1215
|
+
const precheck = recordOf(execServer["mcp_allowlist_precheck_args"]);
|
|
1216
|
+
if (precheck === undefined) return false;
|
|
1217
|
+
const toolName = nonEmptyStringOf(precheck["tool_name"]);
|
|
1218
|
+
if (toolName === undefined) return false;
|
|
1219
|
+
return descriptors.some((d) => d.toolName === toolName);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1173
1222
|
/**
|
|
1174
1223
|
* Answers one interaction query so the Run RPC can continue.
|
|
1175
1224
|
*
|
|
@@ -1343,6 +1392,13 @@ function readPendingToolResult(
|
|
|
1343
1392
|
* when it resends its recorded transcript — a gateway restart between legs or
|
|
1344
1393
|
* an evicted Run — and the only shape safe to rebase into a fresh Run, where
|
|
1345
1394
|
* the recorded exchange travels as history.
|
|
1395
|
+
*
|
|
1396
|
+
* The matching `toolCall` may live anywhere in the conversation, not only in
|
|
1397
|
+
* the trailing assistant turn: Claude Code resends the full transcript, which
|
|
1398
|
+
* contains several earlier `call_cursor_*` rounds. A scan that accepted only
|
|
1399
|
+
* one trailing assistant/tool pair refused those complete replays with
|
|
1400
|
+
* "no longer pending" even though every result was paired and none was live
|
|
1401
|
+
* (mirrors `isCompleteContinuationReplay` in the preparer).
|
|
1346
1402
|
*/
|
|
1347
1403
|
function isCompleteToolHistoryReplay(
|
|
1348
1404
|
request: CanonicalRequest,
|
|
@@ -1357,6 +1413,20 @@ function isCompleteToolHistoryReplay(
|
|
|
1357
1413
|
return pending.every((item) => calledIds.has(item.callId));
|
|
1358
1414
|
}
|
|
1359
1415
|
|
|
1416
|
+
/** The `call_cursor_*` result ids with no matching `toolCall` in the conversation. */
|
|
1417
|
+
function missingToolCallIds(
|
|
1418
|
+
request: CanonicalRequest,
|
|
1419
|
+
pending: readonly PendingToolResult[],
|
|
1420
|
+
): string[] {
|
|
1421
|
+
const calledIds = new Set<string>();
|
|
1422
|
+
for (const message of request.messages) {
|
|
1423
|
+
for (const part of message.content) {
|
|
1424
|
+
if (part.kind === "toolCall") calledIds.add(part.call_id);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
return pending.filter((item) => !calledIds.has(item.callId)).map((item) => item.callId);
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1360
1430
|
/** Reconstructs one tool result's text and images for the adapter's tests. */
|
|
1361
1431
|
export { decodeStructEntriesToJson, decodeValueToJson };
|
|
1362
1432
|
|
|
@@ -1374,4 +1444,3 @@ function resolveCursorWireModelId(rawModelId: string): string {
|
|
|
1374
1444
|
if (id === "auto") return "default";
|
|
1375
1445
|
return rawModelId;
|
|
1376
1446
|
}
|
|
1377
|
-
|
|
@@ -25,28 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import protobuf from "protobufjs"
|
|
28
|
-
|
|
29
|
-
// ── Helper: create a root and add a Type with fields ──
|
|
30
|
-
|
|
31
|
-
type FieldDef = { id: number; name: string; type: string; repeated?: boolean }
|
|
32
|
-
type OneofDef = { name: string; fields: string[] }
|
|
33
|
-
|
|
34
|
-
function addType(
|
|
35
|
-
root: protobuf.Root,
|
|
36
|
-
name: string,
|
|
37
|
-
fields: FieldDef[],
|
|
38
|
-
oneofs?: OneofDef[],
|
|
39
|
-
): protobuf.Type {
|
|
40
|
-
const t = new protobuf.Type(name)
|
|
41
|
-
for (const f of fields) {
|
|
42
|
-
t.add(new protobuf.Field(f.name, f.id, f.type, f.repeated ? "repeated" : undefined))
|
|
43
|
-
}
|
|
44
|
-
for (const o of oneofs ?? []) {
|
|
45
|
-
t.add(new protobuf.OneOf(o.name, o.fields))
|
|
46
|
-
}
|
|
47
|
-
root.add(t)
|
|
48
|
-
return t
|
|
49
|
-
}
|
|
28
|
+
import { addType } from "./protobuf-schema"
|
|
50
29
|
|
|
51
30
|
// ── Utility messages ──
|
|
52
31
|
|
|
@@ -1809,8 +1788,8 @@ export function createMessageTypes(): protobuf.Root {
|
|
|
1809
1788
|
])
|
|
1810
1789
|
|
|
1811
1790
|
addType(root, "CancelAction", [
|
|
1812
|
-
//
|
|
1813
|
-
|
|
1791
|
+
// `agent.proto` declares CancelAction empty (oneof presence is the signal);
|
|
1792
|
+
// the reason travels on the stream, not in the message.
|
|
1814
1793
|
])
|
|
1815
1794
|
|
|
1816
1795
|
// Deferred answers for an AskQuestion the client already replied to with
|
|
@@ -1922,8 +1901,24 @@ export function createMessageTypes(): protobuf.Root {
|
|
|
1922
1901
|
{ id: 8, name: "turns", type: "ConversationTurn", repeated: true },
|
|
1923
1902
|
])
|
|
1924
1903
|
|
|
1904
|
+
// `agent.proto` ModelDetails.thinking_details — empty in the current build;
|
|
1905
|
+
// declared for wire-shape completeness.
|
|
1906
|
+
addType(root, "ThinkingDetails", [])
|
|
1907
|
+
|
|
1908
|
+
// `agent.proto` AgentRunRequest.skill_options (deprecated upstream; kept for
|
|
1909
|
+
// wire-shape completeness).
|
|
1910
|
+
addType(root, "SkillOptions", [
|
|
1911
|
+
{ id: 1, name: "skill_descriptors", type: "SkillDescriptor", repeated: true },
|
|
1912
|
+
])
|
|
1913
|
+
|
|
1925
1914
|
addType(root, "ModelDetails", [
|
|
1926
1915
|
{ id: 1, name: "model_id", type: "string" },
|
|
1916
|
+
{ id: 2, name: "thinking_details", type: "ThinkingDetails" },
|
|
1917
|
+
{ id: 3, name: "display_model_id", type: "string" },
|
|
1918
|
+
{ id: 4, name: "display_name", type: "string" },
|
|
1919
|
+
{ id: 5, name: "display_name_short", type: "string" },
|
|
1920
|
+
{ id: 6, name: "aliases", type: "string", repeated: true },
|
|
1921
|
+
{ id: 7, name: "max_mode", type: "bool" },
|
|
1927
1922
|
])
|
|
1928
1923
|
|
|
1929
1924
|
addType(root, "McpTools", [
|
|
@@ -1933,15 +1928,13 @@ export function createMessageTypes(): protobuf.Root {
|
|
|
1933
1928
|
addType(root, "AgentRunRequest", [
|
|
1934
1929
|
{ id: 1, name: "conversation_state", type: "bytes" },
|
|
1935
1930
|
{ id: 2, name: "action", type: "ConversationAction" },
|
|
1931
|
+
{ id: 3, name: "model_details", type: "ModelDetails" },
|
|
1936
1932
|
{ id: 4, name: "mcp_tools", type: "McpTools" },
|
|
1937
1933
|
{ id: 5, name: "conversation_id", type: "string" },
|
|
1934
|
+
{ id: 6, name: "mcp_file_system_options", type: "McpFileSystemOptions" },
|
|
1935
|
+
{ id: 7, name: "skill_options", type: "SkillOptions" },
|
|
1938
1936
|
{ id: 8, name: "custom_system_prompt", type: "string" },
|
|
1939
1937
|
{ id: 9, name: "requested_model", type: "RequestedModel" },
|
|
1940
|
-
{ id: 10, name: "unknown_flag", type: "uint32" },
|
|
1941
|
-
{ id: 12, name: "field_12", type: "uint32" },
|
|
1942
|
-
{ id: 14, name: "selected_subagent_models", type: "RequestedModel", repeated: true },
|
|
1943
|
-
{ id: 16, name: "conversation_group_id", type: "string" },
|
|
1944
|
-
{ id: 25, name: "run_id", type: "string" },
|
|
1945
1938
|
])
|
|
1946
1939
|
|
|
1947
1940
|
// ── Client heartbeat ──
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared protobufjs schema-builder helpers.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from the vendored protocol modules that each carried the
|
|
5
|
+
* same implementation: `cursor/protocol/messages.ts` (vendored from
|
|
6
|
+
* `cursor-opencode-provider`, MIT) and `devin/protocol/devin-proto.ts`
|
|
7
|
+
* (vendored from `oh-my-pi`, MIT). The original license texts remain in those
|
|
8
|
+
* files; this module exists so future schema additions have one place to fix.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import protobuf from "protobufjs";
|
|
12
|
+
|
|
13
|
+
export type FieldDef = { id: number; name: string; type: string; repeated?: boolean };
|
|
14
|
+
export type OneofDef = { name: string; fields: string[] };
|
|
15
|
+
|
|
16
|
+
/** Create a root Type with fields and optional oneofs, and register it. */
|
|
17
|
+
export function addType(
|
|
18
|
+
root: protobuf.Root,
|
|
19
|
+
name: string,
|
|
20
|
+
fields: FieldDef[],
|
|
21
|
+
oneofs?: OneofDef[],
|
|
22
|
+
): protobuf.Type {
|
|
23
|
+
const t = new protobuf.Type(name);
|
|
24
|
+
for (const f of fields) {
|
|
25
|
+
t.add(new protobuf.Field(f.name, f.id, f.type, f.repeated ? "repeated" : undefined));
|
|
26
|
+
}
|
|
27
|
+
for (const o of oneofs ?? []) {
|
|
28
|
+
t.add(new protobuf.OneOf(o.name, o.fields));
|
|
29
|
+
}
|
|
30
|
+
root.add(t);
|
|
31
|
+
return t;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Register an enum on the root. */
|
|
35
|
+
export function addEnum(root: protobuf.Root, name: string, values: Record<string, number>): void {
|
|
36
|
+
root.add(new protobuf.Enum(name, values));
|
|
37
|
+
}
|