cartethyia 2.5.10 → 2.6.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.
Files changed (367) hide show
  1. package/.env.example +8 -0
  2. package/dist/dashboard/assets/{BannedPage-Cd30Z0b9.js → BannedPage-l6XMnfr9.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-l6XMnfr9.js.gz +0 -0
  4. package/dist/dashboard/assets/{CliToolDetailPage-wf5u-ww6.js → CliToolDetailPage-DwOzAW45.js} +1 -1
  5. package/dist/dashboard/assets/CliToolDetailPage-DwOzAW45.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolsPage-DykPvuck.js → CliToolsPage-BT3Up3QA.js} +1 -1
  7. package/dist/dashboard/assets/CliToolsPage-BT3Up3QA.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-DwvSD3vs.js → CombosPage-6kYIUpzR.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-6kYIUpzR.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-CIr7KDex.js → ConsoleLogPage-zRnj1mlR.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-zRnj1mlR.js.gz +0 -0
  12. package/dist/dashboard/assets/{CustomizationPage-82X0DDdH.js → CustomizationPage-C7m-H1Rz.js} +1 -1
  13. package/dist/dashboard/assets/CustomizationPage-C7m-H1Rz.js.gz +0 -0
  14. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js +1 -0
  15. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js.gz +0 -0
  16. package/dist/dashboard/assets/{LoginPage-CS5mPuVF.js → LoginPage-CbphLvjg.js} +1 -1
  17. package/dist/dashboard/assets/LoginPage-CbphLvjg.js.gz +0 -0
  18. package/dist/dashboard/assets/{ModelPicker-C0UCUsVJ.js → ModelPicker-DVny4S5_.js} +1 -1
  19. package/dist/dashboard/assets/ModelPicker-DVny4S5_.js.gz +0 -0
  20. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js +1 -0
  21. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js.gz +0 -0
  22. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js +3 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js.gz +0 -0
  24. package/dist/dashboard/assets/{ProvidersPage-vdja5ZPK.js → ProvidersPage-Dfb2896L.js} +1 -1
  25. package/dist/dashboard/assets/ProvidersPage-Dfb2896L.js.gz +0 -0
  26. package/dist/dashboard/assets/{ProxyPage-BB4CNm4-.js → ProxyPage-BaCIdAUt.js} +1 -1
  27. package/dist/dashboard/assets/ProxyPage-BaCIdAUt.js.gz +0 -0
  28. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js +1 -0
  29. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js.gz +0 -0
  30. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js +1 -0
  31. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js.gz +0 -0
  32. package/dist/dashboard/assets/{SetupPage-FadUOl9S.js → SetupPage-D4g6vOGc.js} +1 -1
  33. package/dist/dashboard/assets/SetupPage-D4g6vOGc.js.gz +0 -0
  34. package/dist/dashboard/assets/{SortableList-Cfy6_Khv.js → SortableList-C93i14BD.js} +1 -1
  35. package/dist/dashboard/assets/SortableList-C93i14BD.js.gz +0 -0
  36. package/dist/dashboard/assets/{StudioPage-CM92fgJf.js → StudioPage-SgQpymjm.js} +1 -1
  37. package/dist/dashboard/assets/{StudioPage-CM92fgJf.js.gz → StudioPage-SgQpymjm.js.gz} +0 -0
  38. package/dist/dashboard/assets/{UsagePage-BT4MyQeT.js → UsagePage-BFME-eba.js} +2 -2
  39. package/dist/dashboard/assets/UsagePage-BFME-eba.js.gz +0 -0
  40. package/dist/dashboard/assets/{api-keys-DQYLQxpW.js → api-keys-C23S9sgp.js} +1 -1
  41. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  42. package/dist/dashboard/assets/{app-B7pVRhJ1.js → app-2KhtHCv9.js} +1 -1
  43. package/dist/dashboard/assets/{app-B7pVRhJ1.js.gz → app-2KhtHCv9.js.gz} +0 -0
  44. package/dist/dashboard/assets/app-CEeaMHOy.css +2 -0
  45. package/dist/dashboard/assets/app-CEeaMHOy.css.gz +0 -0
  46. package/dist/dashboard/assets/{assert-C9FD_JwJ.js → assert-DU6qrMA_.js} +1 -1
  47. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-Bvyr7D0u.js → badge-CKsF123d.js} +1 -1
  49. package/dist/dashboard/assets/badge-CKsF123d.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-DIvKAZih.js → banner-8j7uChA9.js} +1 -1
  51. package/dist/dashboard/assets/banner-8j7uChA9.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-D5_gYIS_.js → card-CdsSlWA3.js} +1 -1
  53. package/dist/dashboard/assets/card-CdsSlWA3.js.gz +0 -0
  54. package/dist/dashboard/assets/{cli-tools-CNqzrfdb.js → cli-tools-BaFUuFFF.js} +1 -1
  55. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-B6vDBtbm.js → clipboard-button-uL5aYLfW.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-uL5aYLfW.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-CpjrgdwJ.js → dialog-C07hr5_G.js} +1 -1
  59. package/dist/dashboard/assets/dialog-C07hr5_G.js.gz +0 -0
  60. package/dist/dashboard/assets/{drawer-BWmt3b5y.js → drawer-BPO1TcKH.js} +1 -1
  61. package/dist/dashboard/assets/drawer-BPO1TcKH.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-C_oakV3z.js → entry-Bz_CtDfC.js} +1 -1
  63. package/dist/dashboard/assets/entry-Bz_CtDfC.js.gz +0 -0
  64. package/dist/dashboard/assets/entry-CwPRKk0d.js +4 -0
  65. package/dist/dashboard/assets/entry-CwPRKk0d.js.gz +0 -0
  66. package/dist/dashboard/assets/entry-GJRbmrpA.js +1 -0
  67. package/dist/dashboard/assets/entry-GJRbmrpA.js.gz +0 -0
  68. package/dist/dashboard/assets/{github-badge-RRHHWGxh.js → github-badge-DmQreSDd.js} +1 -1
  69. package/dist/dashboard/assets/github-badge-DmQreSDd.js.gz +0 -0
  70. package/dist/dashboard/assets/{index-Bhey_rg_.js → index-Bblu6erR.js} +2 -2
  71. package/dist/dashboard/assets/index-Bblu6erR.js.gz +0 -0
  72. package/dist/dashboard/assets/{inline-C2_EQ5Uf.js → inline-C9dCYaBZ.js} +1 -1
  73. package/dist/dashboard/assets/inline-C9dCYaBZ.js.gz +0 -0
  74. package/dist/dashboard/assets/{input-BMRlQ450.js → input-CjCnXweJ.js} +1 -1
  75. package/dist/dashboard/assets/input-CjCnXweJ.js.gz +0 -0
  76. package/dist/dashboard/assets/{layout-XR5xP8ew.js → layout-V6y8DAkl.js} +1 -1
  77. package/dist/dashboard/assets/layout-V6y8DAkl.js.gz +0 -0
  78. package/dist/dashboard/assets/{list-row-Cw07dioc.js → list-row-CM1AaG_y.js} +1 -1
  79. package/dist/dashboard/assets/list-row-CM1AaG_y.js.gz +0 -0
  80. package/dist/dashboard/assets/{live-BivGfuUs.js → live-ta6GMb-8.js} +1 -1
  81. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  82. package/dist/dashboard/assets/{model-bans-CmffjLuG.js → model-bans-BmYTmbAk.js} +1 -1
  83. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  84. package/dist/dashboard/assets/{mutation-46P0oWMe.js → mutation-g_fduiNw.js} +1 -1
  85. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  86. package/dist/dashboard/assets/{numbers-DrdA9oSM.js → numbers-BOevJzdz.js} +1 -1
  87. package/dist/dashboard/assets/numbers-BOevJzdz.js.gz +0 -0
  88. package/dist/dashboard/assets/{query-keys-BFhGpwR1.js → query-keys-UETqfytp.js} +1 -1
  89. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  90. package/dist/dashboard/assets/{routing-CAb4F37R.js → routing-BPUo-W8d.js} +1 -1
  91. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  92. package/dist/dashboard/assets/{select-CxVVB__N.js → select-C980c4cz.js} +1 -1
  93. package/dist/dashboard/assets/select-C980c4cz.js.gz +0 -0
  94. package/dist/dashboard/assets/{settings-DNX9sydi.js → settings--3hxSyry.js} +1 -1
  95. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  96. package/dist/dashboard/assets/{stack-uPOwM9Hs.js → stack-_gfTdLVB.js} +1 -1
  97. package/dist/dashboard/assets/stack-_gfTdLVB.js.gz +0 -0
  98. package/dist/dashboard/assets/{state-D1Yz79iL.js → state-2c5V4zo7.js} +1 -1
  99. package/dist/dashboard/assets/state-2c5V4zo7.js.gz +0 -0
  100. package/dist/dashboard/assets/{switch-sevsRrRo.js → switch-Dkke7Naf.js} +1 -1
  101. package/dist/dashboard/assets/switch-Dkke7Naf.js.gz +0 -0
  102. package/dist/dashboard/assets/{useMutation-Dem0lXQj.js → useMutation-EDFRkn1i.js} +1 -1
  103. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  104. package/dist/dashboard/index.html +1 -1
  105. package/dist/dashboard/index.html.gz +0 -0
  106. package/dist/dashboard/precompressed-assets.json +51 -51
  107. package/migrations/README.md +52 -52
  108. package/migrations/full-postgres/0020_add_telemetry_event_analytics.sql +77 -0
  109. package/migrations/full-postgres/0021_add_api_key_concurrency_tolerance.sql +13 -0
  110. package/migrations/full-postgres/0022_add_inferhub_config_key.sql +17 -0
  111. package/migrations/full-postgres/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  112. package/migrations/lite-sqlite3/0020_add_telemetry_event_analytics.sql +69 -0
  113. package/migrations/lite-sqlite3/0021_add_api_key_concurrency_tolerance.sql +13 -0
  114. package/migrations/lite-sqlite3/0022_add_inferhub_config_key.sql +17 -0
  115. package/migrations/lite-sqlite3/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  116. package/package.json +96 -95
  117. package/scripts/cli/admin.ts +126 -128
  118. package/scripts/cli/autostart.ts +237 -237
  119. package/scripts/cli/background.ts +120 -110
  120. package/scripts/cli/bin/carte.cjs +8 -8
  121. package/scripts/cli/bin/cartethyia.cjs +167 -167
  122. package/scripts/cli/console-menu.ts +39 -30
  123. package/scripts/cli/controller.ts +145 -0
  124. package/scripts/cli/env.ts +99 -99
  125. package/scripts/cli/gateway.ts +264 -260
  126. package/scripts/cli/instance.ts +234 -224
  127. package/scripts/cli/main.ts +188 -167
  128. package/scripts/cli/platform.ts +64 -64
  129. package/scripts/cli/prompt.ts +217 -79
  130. package/scripts/cli/services.ts +88 -88
  131. package/scripts/cli/setup.ts +445 -445
  132. package/scripts/cli/start.ts +85 -85
  133. package/scripts/cli/startup-signal.ts +23 -23
  134. package/scripts/cli/telemetry.ts +70 -0
  135. package/scripts/cli/tray/index.ts +263 -263
  136. package/scripts/cli/tray/windows.ps1 +107 -107
  137. package/scripts/cli/tray.ts +29 -4
  138. package/scripts/cli/update.ts +39 -39
  139. package/scripts/cli/version.ts +67 -67
  140. package/scripts/cli/wordmark.ts +58 -58
  141. package/src/boot/app.ts +16 -1
  142. package/src/boot/dependencies.ts +128 -25
  143. package/src/config/resources.ts +137 -0
  144. package/src/config/runtime.ts +133 -76
  145. package/src/config/spec.ts +30 -29
  146. package/src/config/telemetry.ts +0 -25
  147. package/src/console/api-keys/bucket-spend.ts +14 -17
  148. package/src/console/api-keys/contracts.ts +410 -410
  149. package/src/console/api-keys/routes.ts +12 -0
  150. package/src/console/audit/store.ts +2 -3
  151. package/src/console/auth/setup-service.ts +8 -1
  152. package/src/console/backup/routes.ts +7 -0
  153. package/src/console/backup/service.ts +463 -463
  154. package/src/console/backup/store.ts +16 -11
  155. package/src/console/backup/validate.ts +1 -4
  156. package/src/console/cli-tools/fs-ops.ts +18 -2
  157. package/src/console/data-management/contracts.ts +1 -8
  158. package/src/console/data-management/operations.ts +61 -48
  159. package/src/console/data-management/routes.ts +4 -2
  160. package/src/console/domain-registration.ts +25 -3
  161. package/src/console/inferhub/client.ts +139 -0
  162. package/src/console/inferhub/key-store.ts +129 -0
  163. package/src/console/inferhub/normalize.ts +347 -0
  164. package/src/console/inferhub/routes.ts +411 -0
  165. package/src/console/inferhub/store.ts +109 -0
  166. package/src/console/inferhub/types.ts +183 -0
  167. package/src/console/observability/contracts.ts +2 -41
  168. package/src/console/observability/store.ts +176 -371
  169. package/src/console/providers/catalog/public-model-store.ts +0 -0
  170. package/src/console/providers/catalog/store.ts +23 -36
  171. package/src/console/quota/account-quota-shared.ts +52 -52
  172. package/src/console/quota/account-quota-tenant.ts +16 -24
  173. package/src/console/quota/refresh.ts +441 -441
  174. package/src/console/routing/pools/import-parse.ts +206 -206
  175. package/src/console/routing/pools/operations.ts +543 -543
  176. package/src/console/routing/pools/probe-verdict.ts +132 -132
  177. package/src/console/routing/pools/routes.ts +181 -181
  178. package/src/console/settings/contracts.ts +42 -40
  179. package/src/console/settings/store.ts +25 -25
  180. package/src/console/share/share-stats.ts +22 -4
  181. package/src/console/share/share-usage.ts +30 -4
  182. package/src/console/shared/cursor.ts +15 -0
  183. package/src/console/updates/routes.ts +12 -0
  184. package/src/main.ts +13 -5
  185. package/src/network/pool/resolver.ts +1104 -1104
  186. package/src/observability/client-name.ts +22 -0
  187. package/src/observability/event-log.ts +5 -29
  188. package/src/observability/event-query.ts +690 -0
  189. package/src/observability/log-ring.ts +26 -2
  190. package/src/observability/log-sanitize.ts +118 -0
  191. package/src/observability/logger.ts +17 -13
  192. package/src/observability/metrics.ts +35 -0
  193. package/src/observability/payload-capture.ts +114 -41
  194. package/src/observability/payload-store.ts +249 -24
  195. package/src/observability/raw-event-writer.ts +118 -0
  196. package/src/observability/runtime-metrics.ts +71 -1
  197. package/src/observability/telemetry-buffer.ts +100 -17
  198. package/src/observability/telemetry-reconciliation.ts +417 -0
  199. package/src/persistence/boot.ts +20 -9
  200. package/src/persistence/db-pg.ts +13 -0
  201. package/src/persistence/db-sqlite.ts +569 -497
  202. package/src/persistence/dialect.ts +3 -2
  203. package/src/persistence/migrate.ts +181 -181
  204. package/src/persistence/schema.ts +1496 -1406
  205. package/src/persistence/shared-cache.ts +5 -1
  206. package/src/persistence/stores/api-key-store.ts +581 -581
  207. package/src/persistence/stores/telemetry-store.ts +124 -63
  208. package/src/protocol/reasoning-text.ts +30 -0
  209. package/src/protocol/response/chat.ts +33 -7
  210. package/src/protocol/response/codex.ts +14 -2
  211. package/src/protocol/response/messages.ts +5 -2
  212. package/src/providers/authentication/oauth-flow-store.ts +3 -10
  213. package/src/providers/bundled-discovery-providers.ts +122 -122
  214. package/src/providers/default-registry.ts +10 -0
  215. package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
  216. package/src/providers/discovery/models-dev-catalog.ts +354 -354
  217. package/src/providers/discovery/probe-phases.ts +43 -7
  218. package/src/providers/discovery/probing-service.ts +70 -32
  219. package/src/providers/integrations/antigravity/antigravity.ts +9 -2
  220. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +85 -17
  221. package/src/providers/integrations/buddy/buddy-chat-shared.ts +934 -934
  222. package/src/providers/integrations/buddy/buddy-checkin.ts +5 -9
  223. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +3 -7
  224. package/src/providers/integrations/buddy/buddy-quota-shared.ts +3 -1
  225. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +57 -49
  226. package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -180
  227. package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -206
  228. package/src/providers/integrations/buddy/workbuddy/quota.ts +161 -161
  229. package/src/providers/integrations/claude/claude-quota.ts +2 -2
  230. package/src/providers/integrations/claude/claude-user-profiles.ts +3 -2
  231. package/src/providers/integrations/claude/claude.ts +3 -4
  232. package/src/providers/integrations/cline/cline.ts +94 -8
  233. package/src/providers/integrations/codex/codex.ts +61 -37
  234. package/src/providers/integrations/cursor/cursor-catalog.ts +368 -368
  235. package/src/providers/integrations/cursor/cursor-http2.ts +300 -300
  236. package/src/providers/integrations/cursor/cursor-identity.ts +2 -4
  237. package/src/providers/integrations/cursor/cursor-request.ts +11 -0
  238. package/src/providers/integrations/cursor/cursor.ts +29 -17
  239. package/src/providers/integrations/cursor/protocol/framing.ts +129 -129
  240. package/src/providers/integrations/cursor/protocol/messages.ts +2380 -2380
  241. package/src/providers/integrations/cursor/protocol/struct.ts +305 -305
  242. package/src/providers/integrations/cursor/protocol/tool-canonical.ts +275 -0
  243. package/src/providers/integrations/grok/grok-quota.ts +279 -279
  244. package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -73
  245. package/src/providers/integrations/grok/grok-ratelimit.ts +218 -218
  246. package/src/providers/integrations/hermes.ts +7 -1
  247. package/src/providers/integrations/inferhub.ts +201 -73
  248. package/src/providers/integrations/kilo/kilo.ts +152 -152
  249. package/src/providers/integrations/kiro/kiro-machine-id.ts +2 -4
  250. package/src/providers/integrations/openrouter/provider.ts +129 -129
  251. package/src/providers/integrations/qoder/qoder-quota.ts +193 -192
  252. package/src/providers/integrations/qoder/qoder-realm.ts +106 -106
  253. package/src/providers/integrations/trae/trae-oauth.ts +4 -26
  254. package/src/providers/integrations/trae/trae-quota.ts +389 -384
  255. package/src/providers/integrations/trae/trae-realm.ts +15 -2
  256. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +100 -24
  257. package/src/providers/integrations/zcode/oauth.ts +1 -1
  258. package/src/providers/operations/account-health-service.ts +605 -279
  259. package/src/providers/provider-metadata.ts +12 -1
  260. package/src/providers/provider-model-definition.ts +373 -373
  261. package/src/providers/quota/quota-contracts.ts +3 -7
  262. package/src/providers/search/search-provider.ts +2 -6
  263. package/src/security/admission/contracts.ts +10 -0
  264. package/src/security/admission/in-memory-store.ts +89 -14
  265. package/src/security/admission/lua.ts +191 -182
  266. package/src/security/admission/redis-store.ts +30 -0
  267. package/src/security/admission/service.ts +18 -0
  268. package/src/security/api-key-auth-cache.ts +96 -0
  269. package/src/security/api-key-auth.ts +11 -100
  270. package/src/security/client-router-fingerprint.ts +3 -7
  271. package/src/security/ip-boundary.ts +7 -3
  272. package/src/shared/coerce.ts +67 -0
  273. package/src/shared/hash.ts +6 -0
  274. package/src/shared/time.ts +7 -0
  275. package/src/transport/dispatch/attempt-finalize.ts +26 -138
  276. package/src/transport/dispatch/attempt-loop.ts +103 -81
  277. package/src/transport/dispatch/capture-policy.ts +78 -0
  278. package/src/transport/dispatch/proxy-request.ts +4 -2
  279. package/src/transport/dispatch/streaming/encoder.ts +111 -5
  280. package/src/transport/dispatch/streaming/stream.ts +19 -2
  281. package/src/transport/dispatch/streaming/thinking-loop.ts +300 -0
  282. package/src/transport/failure-policy.ts +27 -0
  283. package/src/transport/guards/abuse-guard.ts +2 -2
  284. package/src/transport/guards/auth-guard.ts +17 -0
  285. package/src/transport/guards/body-policy.ts +3 -2
  286. package/src/transport/guards/concurrency-guard.ts +89 -13
  287. package/src/transport/guards/early-rejection-capture.ts +43 -3
  288. package/src/transport/guards/error-lifecycle.ts +10 -2
  289. package/src/transport/guards/guard-errors.ts +23 -0
  290. package/src/transport/guards/headroom-guard.ts +41 -7
  291. package/src/transport/guards/pipeline.ts +24 -0
  292. package/src/transport/guards/request-context.ts +2 -1
  293. package/src/transport/routing/admission.ts +51 -9
  294. package/src/transport/routing/bounded-lru.ts +49 -0
  295. package/src/transport/routing/candidate-index.ts +88 -0
  296. package/src/transport/routing/reservations.ts +121 -7
  297. package/src/transport/routing/round-robin.ts +10 -22
  298. package/src/transport/routing/route-catalog.ts +26 -13
  299. package/src/transport/routing/route-model.ts +22 -2
  300. package/src/transport/routing/router.ts +53 -31
  301. package/src/transport/surface/chat/encode.ts +2 -3
  302. package/src/transport/surface/chat/parse.ts +2 -1
  303. package/src/transport/surface/dialects.ts +11 -3
  304. package/src/transport/surface/messages/encode.ts +2 -1
  305. package/src/transport/surface/messages/parse.ts +3 -1
  306. package/src/transport/surface/messages/stream.ts +2 -6
  307. package/src/workers/maintenance-lease.ts +200 -0
  308. package/src/workers/scheduler.ts +101 -1
  309. package/dist/dashboard/assets/BannedPage-Cd30Z0b9.js.gz +0 -0
  310. package/dist/dashboard/assets/CliToolDetailPage-wf5u-ww6.js.gz +0 -0
  311. package/dist/dashboard/assets/CliToolsPage-DykPvuck.js.gz +0 -0
  312. package/dist/dashboard/assets/CombosPage-DwvSD3vs.js.gz +0 -0
  313. package/dist/dashboard/assets/ConsoleLogPage-CIr7KDex.js.gz +0 -0
  314. package/dist/dashboard/assets/CustomizationPage-82X0DDdH.js.gz +0 -0
  315. package/dist/dashboard/assets/HealthEventsModal-BYPucTTn.js +0 -1
  316. package/dist/dashboard/assets/HealthEventsModal-BYPucTTn.js.gz +0 -0
  317. package/dist/dashboard/assets/LoginPage-CS5mPuVF.js.gz +0 -0
  318. package/dist/dashboard/assets/ModelPicker-C0UCUsVJ.js.gz +0 -0
  319. package/dist/dashboard/assets/OverviewPage-Dk_ew3YU.js +0 -1
  320. package/dist/dashboard/assets/OverviewPage-Dk_ew3YU.js.gz +0 -0
  321. package/dist/dashboard/assets/ProviderDetailPage-CAiRn2Q0.js +0 -3
  322. package/dist/dashboard/assets/ProviderDetailPage-CAiRn2Q0.js.gz +0 -0
  323. package/dist/dashboard/assets/ProvidersPage-vdja5ZPK.js.gz +0 -0
  324. package/dist/dashboard/assets/ProxyPage-BB4CNm4-.js.gz +0 -0
  325. package/dist/dashboard/assets/QuotaPage-FEc4iNyq.js +0 -1
  326. package/dist/dashboard/assets/QuotaPage-FEc4iNyq.js.gz +0 -0
  327. package/dist/dashboard/assets/SettingsPage-Dlfi5L4N.js +0 -1
  328. package/dist/dashboard/assets/SettingsPage-Dlfi5L4N.js.gz +0 -0
  329. package/dist/dashboard/assets/SetupPage-FadUOl9S.js.gz +0 -0
  330. package/dist/dashboard/assets/SortableList-Cfy6_Khv.js.gz +0 -0
  331. package/dist/dashboard/assets/UsagePage-BT4MyQeT.js.gz +0 -0
  332. package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
  333. package/dist/dashboard/assets/app-CX_Z8cMs.css +0 -2
  334. package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
  335. package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
  336. package/dist/dashboard/assets/badge-Bvyr7D0u.js.gz +0 -0
  337. package/dist/dashboard/assets/banner-DIvKAZih.js.gz +0 -0
  338. package/dist/dashboard/assets/card-D5_gYIS_.js.gz +0 -0
  339. package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
  340. package/dist/dashboard/assets/clipboard-button-B6vDBtbm.js.gz +0 -0
  341. package/dist/dashboard/assets/dialog-CpjrgdwJ.js.gz +0 -0
  342. package/dist/dashboard/assets/drawer-BWmt3b5y.js.gz +0 -0
  343. package/dist/dashboard/assets/entry-B-gvimrg.js +0 -1
  344. package/dist/dashboard/assets/entry-B-gvimrg.js.gz +0 -0
  345. package/dist/dashboard/assets/entry-C_oakV3z.js.gz +0 -0
  346. package/dist/dashboard/assets/entry-Dj0cHfEc.js +0 -4
  347. package/dist/dashboard/assets/entry-Dj0cHfEc.js.gz +0 -0
  348. package/dist/dashboard/assets/github-badge-RRHHWGxh.js.gz +0 -0
  349. package/dist/dashboard/assets/index-Bhey_rg_.js.gz +0 -0
  350. package/dist/dashboard/assets/inline-C2_EQ5Uf.js.gz +0 -0
  351. package/dist/dashboard/assets/input-BMRlQ450.js.gz +0 -0
  352. package/dist/dashboard/assets/layout-XR5xP8ew.js.gz +0 -0
  353. package/dist/dashboard/assets/list-row-Cw07dioc.js.gz +0 -0
  354. package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
  355. package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
  356. package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
  357. package/dist/dashboard/assets/numbers-DrdA9oSM.js.gz +0 -0
  358. package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
  359. package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
  360. package/dist/dashboard/assets/select-CxVVB__N.js.gz +0 -0
  361. package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
  362. package/dist/dashboard/assets/stack-uPOwM9Hs.js.gz +0 -0
  363. package/dist/dashboard/assets/state-D1Yz79iL.js.gz +0 -0
  364. package/dist/dashboard/assets/switch-sevsRrRo.js.gz +0 -0
  365. package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +0 -0
  366. package/src/observability/event-compaction.ts +0 -317
  367. package/src/observability/event-day-index.ts +0 -439
@@ -0,0 +1,275 @@
1
+ // Cursor-native tool calls, unified into one canonical shape.
2
+ //
3
+ // Cursor's `agent.v1.ToolCall` is a oneof of ~30 variants spanning three
4
+ // unrelated generations: the legacy natives (`ReadToolCall` 8, `ShellToolCall`
5
+ // 1, `EditToolCall` 12, …), the modern exec family (`PiReadToolCall` 61 …
6
+ // `PiLsToolCall` 67), and MCP (`McpToolCall` 15). Each carries its own args
7
+ // message and its own `*ToolResult` oneof of `success`/`error`, so handling
8
+ // them individually meant a decoder and a builder per variant — most of them
9
+ // saying the same thing.
10
+ //
11
+ // This module is the single join point. One table maps a wire variant to a
12
+ // canonical tool identity, and the decode/encode paths below are written once
13
+ // against that table rather than once per variant.
14
+ //
15
+ // **Variants stay separate.** `ReadToolCall` and `PiReadToolCall` are two tools,
16
+ // not one tool seen twice: their args and their result shapes genuinely differ,
17
+ // and folding them would mean picking one shape and lying about the other. A
18
+ // new variant is one table row, not a new converter.
19
+ //
20
+ // **Cursor-scoped on purpose.** Nothing here is shared with the other provider
21
+ // integrations. The canonical vocabulary is Cursor's own (`read`, `pi_read`,
22
+ // `shell`, …), so a tool named `read` on Cursor and a `read` on some other
23
+ // provider are unrelated and cannot collide through a shared registry.
24
+ import type { ToolDefinition } from "../../../../protocol/canonical-model";
25
+
26
+ /**
27
+ * One `ToolCall` oneof arm, as it exists on the wire.
28
+ *
29
+ * `field` is the oneof number from `agent.proto` — the only stable identity a
30
+ * variant has. `wireType` and `argsType` name the protobuf messages so a
31
+ * decoder can resolve them against the type registry without this file
32
+ * importing the registry (and without the registry growing a second notion of
33
+ * which variants exist).
34
+ */
35
+ export interface CursorToolVariant {
36
+ readonly field: number;
37
+ readonly wireType: string;
38
+ readonly argsType: string;
39
+ /** Result message carrying the `success`/`error` oneof. */
40
+ readonly resultType: string;
41
+ /**
42
+ * Canonical tool name for this variant.
43
+ *
44
+ * Deliberately not shared across generations: `read` and `pi_read` are two
45
+ * names because they are two tools. A caller that wants both treats them as
46
+ * both; a caller that wants one filters on one.
47
+ */
48
+ readonly name: string;
49
+ }
50
+
51
+ const VARIANT = (
52
+ field: number,
53
+ wireType: string,
54
+ argsType: string,
55
+ resultType: string,
56
+ name: string,
57
+ ): CursorToolVariant => ({ field, wireType, argsType, resultType, name });
58
+
59
+ /**
60
+ * Every Cursor-native tool variant this layer speaks, keyed by oneof field.
61
+ *
62
+ * `McpToolCall` is absent on purpose: client-declared tools have no native
63
+ * slot anywhere in `agent.proto` — `RequestContext.tools` (#7) is
64
+ * `repeated McpToolDefinition` and `AgentRunRequest.mcp_tools` (#4) is the only
65
+ * other place tools travel — so those stay on the MCP meta-tool path. This
66
+ * table is for the arms Cursor itself owns.
67
+ */
68
+ export const CURSOR_TOOL_VARIANTS: ReadonlyMap<number, CursorToolVariant> = new Map([
69
+ VARIANT(1, "ShellToolCall", "ShellArgs", "ShellResult", "shell"),
70
+ VARIANT(3, "DeleteToolCall", "DeleteArgs", "DeleteResult", "delete"),
71
+ VARIANT(4, "GlobToolCall", "GlobArgs", "GlobResult", "glob"),
72
+ VARIANT(5, "GrepToolCall", "GrepArgs", "GrepResult", "grep"),
73
+ VARIANT(8, "ReadToolCall", "ReadToolArgs", "ReadToolResult", "read"),
74
+ VARIANT(9, "UpdateTodosToolCall", "UpdateTodosArgs", "UpdateTodosResult", "update_todos"),
75
+ VARIANT(10, "ReadTodosToolCall", "ReadTodosArgs", "ReadTodosResult", "read_todos"),
76
+ VARIANT(12, "EditToolCall", "EditToolArgs", "EditToolResult", "edit"),
77
+ VARIANT(13, "LsToolCall", "LsArgs", "LsResult", "ls"),
78
+ VARIANT(14, "ReadLintsToolCall", "ReadLintsToolArgs", "ReadLintsToolResult", "read_lints"),
79
+ VARIANT(16, "SemSearchToolCall", "SemSearchToolArgs", "SemSearchToolResult", "sem_search"),
80
+ VARIANT(17, "CreatePlanToolCall", "CreatePlanArgs", "CreatePlanResult", "create_plan"),
81
+ VARIANT(18, "WebSearchToolCall", "WebSearchToolArgs", "WebSearchToolResult", "web_search"),
82
+ VARIANT(19, "TaskToolCall", "TaskToolArgs", "TaskToolResult", "task"),
83
+ VARIANT(22, "ApplyAgentDiffToolCall", "ApplyAgentDiffArgs", "ApplyAgentDiffResult", "apply_agent_diff"),
84
+ VARIANT(23, "AskQuestionToolCall", "AskQuestionArgs", "AskQuestionResult", "ask_question"),
85
+ VARIANT(24, "FetchToolCall", "FetchToolArgs", "FetchToolResult", "fetch"),
86
+ VARIANT(25, "SwitchModeToolCall", "SwitchModeArgs", "SwitchModeResult", "switch_mode"),
87
+ VARIANT(26, "ExaSearchToolCall", "ExaSearchArgs", "ExaSearchResult", "exa_search"),
88
+ VARIANT(27, "ExaFetchToolCall", "ExaFetchArgs", "ExaFetchResult", "exa_fetch"),
89
+ VARIANT(28, "GenerateImageToolCall", "GenerateImageArgs", "GenerateImageResult", "generate_image"),
90
+ VARIANT(29, "RecordScreenToolCall", "RecordScreenArgs", "RecordScreenResult", "record_screen"),
91
+ VARIANT(30, "ComputerUseToolCall", "ComputerUseArgs", "ComputerUseResult", "computer_use"),
92
+ VARIANT(31, "WriteShellStdinToolCall", "WriteShellStdinArgs", "WriteShellStdinResult", "write_shell_stdin"),
93
+ VARIANT(32, "ReflectToolCall", "ReflectArgs", "ReflectResult", "reflect"),
94
+ VARIANT(33, "SetupVmEnvironmentToolCall", "SetupVmEnvironmentArgs", "SetupVmEnvironmentResult", "setup_vm_environment"),
95
+ VARIANT(34, "TruncatedToolCall", "TruncatedArgs", "TruncatedResult", "truncated"),
96
+ // The modern exec family. Same join point, separate identities.
97
+ VARIANT(61, "PiReadToolCall", "PiReadToolArgs", "PiReadExecResult", "pi_read"),
98
+ VARIANT(62, "PiBashToolCall", "PiBashToolArgs", "PiBashExecResult", "pi_bash"),
99
+ VARIANT(63, "PiEditToolCall", "PiEditToolArgs", "PiEditExecResult", "pi_edit"),
100
+ VARIANT(64, "PiWriteToolCall", "PiWriteToolArgs", "PiWriteExecResult", "pi_write"),
101
+ VARIANT(65, "PiGrepToolCall", "PiGrepToolArgs", "PiGrepExecResult", "pi_grep"),
102
+ VARIANT(66, "PiFindToolCall", "PiFindToolArgs", "PiFindExecResult", "pi_find"),
103
+ VARIANT(67, "PiLsToolCall", "PiLsToolArgs", "PiLsExecResult", "pi_ls"),
104
+ ].map((entry) => [entry.field, entry]));
105
+
106
+ /**
107
+ * A decoded Cursor-native tool call, in the same shape the rest of the gateway
108
+ * already reasons about.
109
+ *
110
+ * `variant` is carried rather than discarded so a result can be encoded back
111
+ * into the wire arm it came from. Dropping it would mean `pi_read` in and
112
+ * `read` out, which silently breaks the client's own tool loop.
113
+ */
114
+ export interface CursorNativeToolCall {
115
+ readonly variant: CursorToolVariant;
116
+ readonly name: string;
117
+ readonly callId: string;
118
+ readonly arguments: Record<string, unknown>;
119
+ }
120
+
121
+ /** Which oneof arm a `ToolCall` message carries, as `(field, message)`. */
122
+ type OneofArm = { readonly field: number; readonly payload: Record<string, unknown> };
123
+
124
+ /**
125
+ * Reads the single arm a `ToolCall` is holding.
126
+ *
127
+ * A oneof has exactly one populated field; a message with none is not a tool
128
+ * call at all and is reported as `undefined` rather than guessed at. An arm
129
+ * this layer does not know is also `undefined` — that is what leaves room for
130
+ * MCP to claim it.
131
+ */
132
+ export function cursorToolArm(
133
+ toolCall: Record<string, unknown>,
134
+ ): OneofArm | undefined {
135
+ for (const [key, value] of Object.entries(toolCall)) {
136
+ if (value === null || value === undefined) continue;
137
+ const variant = [...CURSOR_TOOL_VARIANTS.values()].find(
138
+ (entry) => entry.wireType.toLowerCase() === key.toLowerCase(),
139
+ );
140
+ if (variant === undefined) continue;
141
+ return { field: variant.field, payload: value as Record<string, unknown> };
142
+ }
143
+ return undefined;
144
+ }
145
+
146
+ /**
147
+ * Decodes one `ToolCall` into a canonical call, or `undefined` when the arm is
148
+ * not a Cursor-native tool.
149
+ *
150
+ * Arguments come off the variant's `args` sub-message and are normalised to
151
+ * canonical OpenAI-style tool arguments: snake_case keys, all the way down.
152
+ * Cursor's own arms disagree with each other and with the OpenAI spelling, and
153
+ * this is the gateway's translation boundary — the point where a Cursor call
154
+ * becomes a tool call every other protocol can read. Leaving the keys as the
155
+ * wire sent them would make the same tool mean different things depending on
156
+ * which arm happened to carry it.
157
+ */
158
+ export function decodeCursorNativeToolCall(
159
+ callId: string,
160
+ toolCall: Record<string, unknown>,
161
+ ): CursorNativeToolCall | undefined {
162
+ const arm = cursorToolArm(toolCall);
163
+ if (arm === undefined) return undefined;
164
+ const variant = CURSOR_TOOL_VARIANTS.get(arm.field);
165
+ if (variant === undefined) return undefined;
166
+ const args = arm.payload["args"];
167
+ return {
168
+ variant,
169
+ name: variant.name,
170
+ callId,
171
+ arguments: canonicalToolArguments(args),
172
+ };
173
+ }
174
+
175
+ /**
176
+ * Recursive snake_case normalisation of a tool-argument value.
177
+ *
178
+ * OpenAI-style tool arguments are snake_case throughout, nested values
179
+ * included, so the conversion has to walk the whole tree rather than the top
180
+ * level — a Cursor `EditToolArgs` can carry nested objects whose keys would
181
+ * otherwise stay camelCase and be invisible to a client reading the canonical
182
+ * spelling. Array elements are walked for the same reason; a scalar is
183
+ * returned untouched because there is no key to convert.
184
+ */
185
+ export function canonicalToolArguments(value: unknown): Record<string, unknown> {
186
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
187
+ return Object.fromEntries(
188
+ Object.entries(value as Record<string, unknown>).map(([key, child]) => [
189
+ snakeCaseKey(key),
190
+ canonicalToolValue(child),
191
+ ]),
192
+ );
193
+ }
194
+
195
+ function canonicalToolValue(value: unknown): unknown {
196
+ if (Array.isArray(value)) return value.map(canonicalToolValue);
197
+ if (value !== null && typeof value === "object") return canonicalToolArguments(value);
198
+ return value;
199
+ }
200
+
201
+ /** `someKeyName` → `some_key_name`; already-snake keys come back unchanged. */
202
+ function snakeCaseKey(key: string): string {
203
+ return key
204
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
205
+ .replace(/[\s-]+/g, "_")
206
+ .toLowerCase();
207
+ }
208
+
209
+ /**
210
+ * The variant whose args a host-exec frame is carrying.
211
+ *
212
+ * Exec frames name their payload after the args message — `read_args`,
213
+ * `shell_args`, `pi_read_args` — not after the `ToolCall` arm, so the lookup
214
+ * runs off `argsType`. Anything not ending in `_args` is not a tool payload
215
+ * (`id`, `exec_id`, `request_context_args`, …) and is reported as `undefined`.
216
+ */
217
+ export function cursorVariantForExecArgs(
218
+ execServer: Record<string, unknown>,
219
+ ): { readonly variant: CursorToolVariant; readonly args: Record<string, unknown> } | undefined {
220
+ for (const [key, value] of Object.entries(execServer)) {
221
+ if (value === null || value === undefined || !key.endsWith("_args")) continue;
222
+ const wanted = key.slice(0, -"_args".length);
223
+ const variant = [...CURSOR_TOOL_VARIANTS.values()].find((entry) =>
224
+ entry.argsType.toLowerCase().startsWith(wanted.toLowerCase()),
225
+ );
226
+ if (variant === undefined) continue;
227
+ return {
228
+ variant,
229
+ args: canonicalToolArguments(value),
230
+ };
231
+ }
232
+ return undefined;
233
+ }
234
+
235
+ /**
236
+ * The variant an inbound result must be encoded back into.
237
+ *
238
+ * Keyed by `call_id`, which is what the response carries and what the client
239
+ * echoes on the result. Consulted before encoding so a result for a tool this
240
+ * layer never decoded is not invented into some other variant's shape.
241
+ */
242
+ export class CursorToolCallProvenance {
243
+ readonly #byCallId = new Map<string, CursorToolVariant>();
244
+
245
+ record(callId: string, variant: CursorToolVariant): void {
246
+ this.#byCallId.set(callId, variant);
247
+ }
248
+
249
+ lookup(callId: string): CursorToolVariant | undefined {
250
+ return this.#byCallId.get(callId);
251
+ }
252
+
253
+ /** Drops one call's provenance once its result has been encoded. */
254
+ complete(callId: string): void {
255
+ this.#byCallId.delete(callId);
256
+ }
257
+ }
258
+
259
+ /**
260
+ * A tool declaration the gateway can advertise for Cursor-native tools.
261
+ *
262
+ * Kept separate from `ToolDefinition`'s own name on purpose: the canonical name
263
+ * (`pi_read`) is not the name a client's schema would use, so advertising one
264
+ * under the other would make the call/result round trip undecidable.
265
+ */
266
+ export function cursorNativeToolDeclaration(
267
+ variant: CursorToolVariant,
268
+ description: string,
269
+ ): ToolDefinition {
270
+ return {
271
+ name: variant.name,
272
+ description,
273
+ jsonSchema: { type: "object", properties: {} },
274
+ };
275
+ }