cartethyia 2.6.7 → 2.7.1

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 (335) hide show
  1. package/.env.example +1 -7
  2. package/README.md +25 -2
  3. package/dist/dashboard/assets/{BannedPage-Dskhyp0l.js → BannedPage-D-J75hBM.js} +1 -1
  4. package/dist/dashboard/assets/BannedPage-D-J75hBM.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolDetailPage--SJhk7qQ.js → CliToolDetailPage-CVe6RaBH.js} +1 -1
  6. package/dist/dashboard/assets/CliToolDetailPage-CVe6RaBH.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolsPage-C203VT-c.js → CliToolsPage-Dd8ZSamp.js} +1 -1
  8. package/dist/dashboard/assets/CliToolsPage-Dd8ZSamp.js.gz +0 -0
  9. package/dist/dashboard/assets/{CombosPage-BcS7kGG1.js → CombosPage-QoJ6foxo.js} +1 -1
  10. package/dist/dashboard/assets/CombosPage-QoJ6foxo.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js.gz +0 -0
  13. package/dist/dashboard/assets/{CustomizationPage-uujbBYwC.js → CustomizationPage-CKUFTcW4.js} +1 -1
  14. package/dist/dashboard/assets/CustomizationPage-CKUFTcW4.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js.gz +0 -0
  17. package/dist/dashboard/assets/LoginPage-DubdQcvX.js +1 -0
  18. package/dist/dashboard/assets/LoginPage-DubdQcvX.js.gz +0 -0
  19. package/dist/dashboard/assets/{ModelPicker-CA1kLs45.js → ModelPicker-BH8Tehdi.js} +1 -1
  20. package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
  21. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js +1 -0
  22. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js.gz +0 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js +4 -0
  24. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +1 -0
  26. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  27. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js +1 -0
  28. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js.gz +0 -0
  29. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js +9 -0
  30. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js.gz +0 -0
  31. package/dist/dashboard/assets/{QuotaPage-BueSWX5D.js → QuotaPage-ATpaxrbl.js} +1 -1
  32. package/dist/dashboard/assets/QuotaPage-ATpaxrbl.js.gz +0 -0
  33. package/dist/dashboard/assets/SettingsPage-CETophpx.js +1 -0
  34. package/dist/dashboard/assets/SettingsPage-CETophpx.js.gz +0 -0
  35. package/dist/dashboard/assets/SetupPage-BdgECjqq.js +1 -0
  36. package/dist/dashboard/assets/SetupPage-BdgECjqq.js.gz +0 -0
  37. package/dist/dashboard/assets/{SortableList-DrKeMcGN.js → SortableList-CAK-EN9z.js} +1 -1
  38. package/dist/dashboard/assets/SortableList-CAK-EN9z.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-qjuYtccc.js → StudioPage-B7W2_RhT.js} +3 -3
  40. package/dist/dashboard/assets/StudioPage-B7W2_RhT.js.gz +0 -0
  41. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js +56 -0
  42. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js.gz +0 -0
  43. package/dist/dashboard/assets/{api-keys-C23S9sgp.js → api-keys-CUi6UXsR.js} +1 -1
  44. package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
  45. package/dist/dashboard/assets/app-KvsUJUMF.css +2 -0
  46. package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-DU6qrMA_.js → assert-67xXH5rf.js} +1 -1
  48. package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-Bkz_-RrM.js → badge-DC2L43Mj.js} +1 -1
  50. package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-C-7y3VKV.js → banner-BBVcb0J3.js} +1 -1
  52. package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
  53. package/dist/dashboard/assets/{card-BOPBuBzD.js → card-Cca1XC6G.js} +1 -1
  54. package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
  55. package/dist/dashboard/assets/{cli-tools-BaFUuFFF.js → cli-tools-KvsWa1Jl.js} +1 -1
  56. package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
  57. package/dist/dashboard/assets/{clipboard-button-e-Mlk0FH.js → clipboard-button-DUzEbynq.js} +1 -1
  58. package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
  59. package/dist/dashboard/assets/{dialog-Iec_ywbD.js → dialog-DFvWhwTa.js} +1 -1
  60. package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
  61. package/dist/dashboard/assets/{drawer-Bs8MIIHc.js → drawer-CFM2sMX1.js} +1 -1
  62. package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
  63. package/dist/dashboard/assets/{entry-DOddwoc0.js → entry-BLBLxX0h.js} +3 -3
  64. package/dist/dashboard/assets/entry-BLBLxX0h.js.gz +0 -0
  65. package/dist/dashboard/assets/{entry-DcobaKFu.js → entry-Bqy8RFvM.js} +1 -1
  66. package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
  67. package/dist/dashboard/assets/{entry-BRszm4_Z.js → entry-_xHo5x6r.js} +1 -1
  68. package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
  69. package/dist/dashboard/assets/formatters-mpBPqAQ8.js +1 -0
  70. package/dist/dashboard/assets/formatters-mpBPqAQ8.js.gz +0 -0
  71. package/dist/dashboard/assets/{github-badge-BuDsrsPn.js → github-badge-C9e8Ts7e.js} +1 -1
  72. package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
  73. package/dist/dashboard/assets/{index-BeLRhsmt.js → index-D6QzEC_n.js} +2 -2
  74. package/dist/dashboard/assets/index-D6QzEC_n.js.gz +0 -0
  75. package/dist/dashboard/assets/{inline-DToMICwl.js → inline-BFUcvllj.js} +1 -1
  76. package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
  77. package/dist/dashboard/assets/{input-WlyHWeG2.js → input-C_ILAvBb.js} +1 -1
  78. package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
  79. package/dist/dashboard/assets/{layout-DaJ5baJr.js → layout-CBIyT6Rt.js} +1 -1
  80. package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
  81. package/dist/dashboard/assets/{list-row-B3oSK13z.js → list-row-ebJ_-Nsb.js} +1 -1
  82. package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
  83. package/dist/dashboard/assets/{live-ta6GMb-8.js → live-D0mm--ME.js} +1 -1
  84. package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
  85. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +1 -0
  86. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  87. package/dist/dashboard/assets/{mutation-g_fduiNw.js → mutation-sMD965oO.js} +1 -1
  88. package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
  89. package/dist/dashboard/assets/{numbers-Dulqgys5.js → numbers-BO9dKaFr.js} +1 -1
  90. package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
  91. package/dist/dashboard/assets/providers/inception.svg +5 -0
  92. package/dist/dashboard/assets/providers/inception.svg.gz +0 -0
  93. package/dist/dashboard/assets/{query-keys-UETqfytp.js → query-keys-CfL_Zdoh.js} +1 -1
  94. package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
  95. package/dist/dashboard/assets/{routing-BPUo-W8d.js → routing-BnIpi1IJ.js} +1 -1
  96. package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
  97. package/dist/dashboard/assets/{select-BfZ3SCTM.js → select-Cj5Nw43g.js} +1 -1
  98. package/dist/dashboard/assets/select-Cj5Nw43g.js.gz +0 -0
  99. package/dist/dashboard/assets/settings-BAFhDgX8.js +1 -0
  100. package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
  101. package/dist/dashboard/assets/{stack-B1w5BM0u.js → stack-EMrOMt4I.js} +1 -1
  102. package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
  103. package/dist/dashboard/assets/{state-DhZBfWgx.js → state-CWoo7ty5.js} +1 -1
  104. package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
  105. package/dist/dashboard/assets/{switch-yD7D99Lg.js → switch-CCjT6IkF.js} +1 -1
  106. package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
  107. package/dist/dashboard/assets/{useMutation-EDFRkn1i.js → useMutation-DjkLHUcE.js} +1 -1
  108. package/dist/dashboard/assets/useMutation-DjkLHUcE.js.gz +0 -0
  109. package/dist/dashboard/index.html +1 -1
  110. package/dist/dashboard/index.html.gz +0 -0
  111. package/dist/dashboard/precompressed-assets.json +55 -54
  112. package/migrations/full-postgres/0024_add_pool_provider_cooldowns.sql +12 -0
  113. package/migrations/full-postgres/0025_add_pool_random_strategy.sql +3 -0
  114. package/migrations/lite-sqlite3/0024_add_pool_provider_cooldowns.sql +12 -0
  115. package/migrations/lite-sqlite3/0025_add_pool_random_strategy.sql +20 -0
  116. package/package.json +1 -1
  117. package/scripts/cli/console-menu.ts +5 -2
  118. package/scripts/cli/tray.ts +21 -6
  119. package/src/boot/app.ts +24 -62
  120. package/src/boot/dependencies.ts +732 -750
  121. package/src/config/cooldowns.ts +16 -0
  122. package/src/config/providers.ts +13 -1
  123. package/src/config/resources.ts +13 -80
  124. package/src/config/security.ts +2 -38
  125. package/src/config/spec.ts +16 -23
  126. package/src/console/console-router.ts +7 -7
  127. package/src/console/domain-registration.ts +19 -12
  128. package/src/console/providers/catalog/catalog-projections.ts +2 -6
  129. package/src/console/providers/catalog/contracts.ts +19 -0
  130. package/src/console/providers/catalog/provider-operations.ts +38 -0
  131. package/src/console/providers/catalog/routes.ts +14 -0
  132. package/src/console/providers/catalog/store-helpers.ts +326 -0
  133. package/src/console/providers/catalog/store.ts +1292 -1563
  134. package/src/console/quota/account-quota-global.ts +2 -2
  135. package/src/console/quota/account-quota-shared.ts +1 -1
  136. package/src/console/quota/account-quota-tenant.ts +35 -12
  137. package/src/console/quota/quota-view.ts +2 -2
  138. package/src/console/remote-support/contracts.ts +3 -1
  139. package/src/console/remote-support/service.ts +115 -6
  140. package/src/console/routing/pools/contracts.ts +41 -1
  141. package/src/console/routing/pools/operations.ts +183 -4
  142. package/src/console/routing/pools/relay-deploy.ts +17 -4
  143. package/src/console/routing/pools/routes.ts +30 -0
  144. package/src/console/routing/pools/store.ts +98 -8
  145. package/src/main.ts +16 -2
  146. package/src/network/outbound-fetch.ts +226 -365
  147. package/src/network/pool/agent.ts +8 -0
  148. package/src/network/pool/pool-state.ts +7 -0
  149. package/src/network/pool/selector.ts +110 -2
  150. package/src/network/pool-cooldown-store.ts +252 -0
  151. package/src/network/pool-health-machine.ts +5 -3
  152. package/src/network/pool-health.ts +36 -9
  153. package/src/observability/event-query.ts +57 -0
  154. package/src/observability/metrics.ts +15 -5
  155. package/src/observability/runtime-metrics.ts +30 -15
  156. package/src/persistence/health-event-flush.ts +2 -0
  157. package/src/persistence/schema.ts +19 -0
  158. package/src/persistence/usage-flush.ts +8 -3
  159. package/src/protocol/canonical-model.ts +1 -1
  160. package/src/protocol/dsml.ts +377 -0
  161. package/src/protocol/gateway-error.ts +0 -1
  162. package/src/{providers/provider-reasoning.ts → protocol/reasoning.ts} +10 -9
  163. package/src/protocol/request/chat.ts +7 -7
  164. package/src/protocol/request/codex.ts +2 -2
  165. package/src/protocol/request/gemini.ts +1 -1
  166. package/src/protocol/request/messages.ts +6 -6
  167. package/src/protocol/request/responses.ts +7 -7
  168. package/src/protocol/response/dsml.ts +12 -133
  169. package/src/{transport → protocol}/translation/attachment-integrity.ts +2 -2
  170. package/src/{transport → protocol}/translation/cache-controls.ts +1 -1
  171. package/src/{transport → protocol}/translation/capabilities.ts +2 -2
  172. package/src/{transport → protocol}/translation/normalize.ts +1 -1
  173. package/src/{transport → protocol}/translation/quirks.ts +1 -1
  174. package/src/{transport → protocol}/translation/search.ts +1 -1
  175. package/src/{transport → protocol}/translation/thinking.ts +23 -1
  176. package/src/{transport → protocol}/translation/tool-id.ts +1 -1
  177. package/src/{transport → protocol}/translation/tool-repair.ts +2 -2
  178. package/src/protocol/upstream-parsing.ts +176 -0
  179. package/src/providers/adapters/compatible-adapter.ts +11 -2
  180. package/src/providers/authentication/oauth-refresh-service.ts +9 -5
  181. package/src/providers/default-registry.ts +21 -5
  182. package/src/providers/discovery/probe-phases.ts +16 -3
  183. package/src/providers/discovery/probing-service.ts +4 -1
  184. package/src/providers/integrations/anthropic.ts +1 -1
  185. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -4
  186. package/src/providers/integrations/buddy/buddy-chat-shared.ts +141 -8
  187. package/src/providers/integrations/buddy/buddy-checkin.ts +5 -1
  188. package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -82
  189. package/src/providers/integrations/buddy/buddy-identity.ts +25 -0
  190. package/src/providers/integrations/buddy/buddy-server-tools.ts +240 -0
  191. package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +36 -0
  192. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +6 -31
  193. package/src/providers/integrations/buddy/codebuddy/provider.ts +2 -0
  194. package/src/providers/integrations/buddy/codebuddy/shared.ts +19 -4
  195. package/src/providers/integrations/buddy/turing-device-token.ts +262 -0
  196. package/src/providers/integrations/buddy/workbuddy/provider.ts +2 -0
  197. package/src/providers/integrations/buddy/workbuddy/shared.ts +56 -3
  198. package/src/providers/integrations/claude/claude.ts +1 -1
  199. package/src/providers/integrations/cloudflareai/cloudflareai.ts +1 -1
  200. package/src/providers/integrations/codex/codex-errors.ts +1 -1
  201. package/src/providers/integrations/codex/codex.ts +1 -1
  202. package/src/providers/integrations/commandcode/commandcode.ts +134 -104
  203. package/src/providers/integrations/commandcode/discovery.ts +6 -5
  204. package/src/providers/integrations/factory/factory.ts +1 -1
  205. package/src/providers/integrations/github/github.ts +1 -1
  206. package/src/providers/integrations/grok/grok.ts +1 -1
  207. package/src/providers/integrations/inception/provider.ts +91 -0
  208. package/src/providers/integrations/inferhub.ts +1 -1
  209. package/src/providers/integrations/kiro/kiro-request.ts +1 -1
  210. package/src/providers/integrations/mistral.ts +193 -19
  211. package/src/providers/integrations/opencode/fingerprint.ts +19 -2
  212. package/src/providers/integrations/opencode/prompt.ts +111 -0
  213. package/src/providers/integrations/opencode/provider.ts +101 -23
  214. package/src/providers/integrations/opencode/tool-definitions.ts +4 -4
  215. package/src/providers/integrations/qoder/qoder-checkin.ts +303 -0
  216. package/src/providers/integrations/qoder/qoder.ts +1641 -884
  217. package/src/providers/integrations/shared/install-id.ts +2 -1
  218. package/src/providers/integrations/trae/trae-cache.ts +110 -0
  219. package/src/providers/integrations/trae/trae-oauth.ts +29 -4
  220. package/src/providers/integrations/trae/trae-protocol.ts +2 -1
  221. package/src/providers/integrations/trae/trae.ts +106 -23
  222. package/src/providers/operations/account-error-classification.ts +1660 -0
  223. package/src/providers/operations/account-health-service.ts +621 -2097
  224. package/src/providers/operations/account-reset-service.ts +2 -0
  225. package/src/providers/provider-contracts.ts +0 -2
  226. package/src/providers/provider-metadata.ts +25 -4
  227. package/src/providers/provider-probe.ts +2 -2
  228. package/src/{console → providers}/quota/cache.ts +1 -1
  229. package/src/{console → providers}/quota/refresh.ts +5 -5
  230. package/src/security/abuse.ts +17 -0
  231. package/src/transport/dispatch/attempt-finalize.ts +114 -12
  232. package/src/transport/dispatch/attempt-loop.ts +3 -0
  233. package/src/transport/dispatch/empty-stream.ts +224 -217
  234. package/src/transport/dispatch/generation.ts +37 -55
  235. package/src/transport/dispatch/handler-deps.ts +32 -0
  236. package/src/transport/dispatch/leases.ts +9 -4
  237. package/src/transport/dispatch/proxy-request.ts +6 -30
  238. package/src/transport/dispatch/responses-compact.ts +22 -43
  239. package/src/transport/dispatch/streaming/finalize.ts +3 -0
  240. package/src/transport/dispatch/streaming/stream.ts +0 -8
  241. package/src/transport/dispatch/systemone.ts +22 -42
  242. package/src/transport/dispatch/token-count.ts +23 -39
  243. package/src/transport/dispatch/upstream.ts +1 -3
  244. package/src/transport/dispatch/websearch.ts +22 -41
  245. package/src/transport/failure-policy.ts +59 -178
  246. package/src/transport/guards/abuse-guard.ts +10 -0
  247. package/src/transport/guards/auth-guard.ts +0 -18
  248. package/src/transport/guards/error-lifecycle.ts +1 -1
  249. package/src/transport/guards/pipeline.ts +0 -6
  250. package/src/transport/guards/request-context.ts +18 -91
  251. package/src/transport/request/degradation.ts +20 -1
  252. package/src/transport/request/inflight.ts +4 -95
  253. package/src/transport/request/preparer.ts +6 -6
  254. package/src/transport/request/state.ts +66 -38
  255. package/src/transport/request/tenant-preferences.ts +1 -1
  256. package/src/transport/routing/route-catalog.ts +41 -31
  257. package/src/transport/routing/router.ts +2 -2
  258. package/src/transport/surface/messages/parse.ts +1 -1
  259. package/src/workers/buddy-growth-tasks.ts +346 -425
  260. package/src/workers/daily-checkin.ts +17 -6
  261. package/src/workers/quota-refresh-sweep.ts +2 -2
  262. package/src/workers/scheduler.ts +17 -1
  263. package/dist/dashboard/assets/BannedPage-Dskhyp0l.js.gz +0 -0
  264. package/dist/dashboard/assets/CliToolDetailPage--SJhk7qQ.js.gz +0 -0
  265. package/dist/dashboard/assets/CliToolsPage-C203VT-c.js.gz +0 -0
  266. package/dist/dashboard/assets/CombosPage-BcS7kGG1.js.gz +0 -0
  267. package/dist/dashboard/assets/ConsoleLogPage-ChmiSLwO.js +0 -1
  268. package/dist/dashboard/assets/ConsoleLogPage-ChmiSLwO.js.gz +0 -0
  269. package/dist/dashboard/assets/CustomizationPage-uujbBYwC.js.gz +0 -0
  270. package/dist/dashboard/assets/HealthEventsModal-fKAWd-OQ.js +0 -1
  271. package/dist/dashboard/assets/HealthEventsModal-fKAWd-OQ.js.gz +0 -0
  272. package/dist/dashboard/assets/LoginPage-DoOUthbG.js +0 -1
  273. package/dist/dashboard/assets/LoginPage-DoOUthbG.js.gz +0 -0
  274. package/dist/dashboard/assets/ModelPicker-CA1kLs45.js.gz +0 -0
  275. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js +0 -1
  276. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js.gz +0 -0
  277. package/dist/dashboard/assets/ProviderDetailPage-CFu1qGcT.js +0 -3
  278. package/dist/dashboard/assets/ProviderDetailPage-CFu1qGcT.js.gz +0 -0
  279. package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js +0 -1
  280. package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js.gz +0 -0
  281. package/dist/dashboard/assets/ProvidersPage-CnlJZbxF.js +0 -1
  282. package/dist/dashboard/assets/ProvidersPage-CnlJZbxF.js.gz +0 -0
  283. package/dist/dashboard/assets/ProxyPage-B9mBTweh.js +0 -7
  284. package/dist/dashboard/assets/ProxyPage-B9mBTweh.js.gz +0 -0
  285. package/dist/dashboard/assets/QuotaPage-BueSWX5D.js.gz +0 -0
  286. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js +0 -1
  287. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js.gz +0 -0
  288. package/dist/dashboard/assets/SetupPage-DQ9oDRpi.js +0 -1
  289. package/dist/dashboard/assets/SetupPage-DQ9oDRpi.js.gz +0 -0
  290. package/dist/dashboard/assets/SortableList-DrKeMcGN.js.gz +0 -0
  291. package/dist/dashboard/assets/StudioPage-qjuYtccc.js.gz +0 -0
  292. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js +0 -56
  293. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js.gz +0 -0
  294. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  295. package/dist/dashboard/assets/app-BUSiYL6F.css +0 -2
  296. package/dist/dashboard/assets/app-BUSiYL6F.css.gz +0 -0
  297. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  298. package/dist/dashboard/assets/badge-Bkz_-RrM.js.gz +0 -0
  299. package/dist/dashboard/assets/banner-C-7y3VKV.js.gz +0 -0
  300. package/dist/dashboard/assets/card-BOPBuBzD.js.gz +0 -0
  301. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  302. package/dist/dashboard/assets/clipboard-button-e-Mlk0FH.js.gz +0 -0
  303. package/dist/dashboard/assets/cog-CdWhsajs.js +0 -1
  304. package/dist/dashboard/assets/cog-CdWhsajs.js.gz +0 -0
  305. package/dist/dashboard/assets/dialog-Iec_ywbD.js.gz +0 -0
  306. package/dist/dashboard/assets/drawer-Bs8MIIHc.js.gz +0 -0
  307. package/dist/dashboard/assets/entry-BRszm4_Z.js.gz +0 -0
  308. package/dist/dashboard/assets/entry-DOddwoc0.js.gz +0 -0
  309. package/dist/dashboard/assets/entry-DcobaKFu.js.gz +0 -0
  310. package/dist/dashboard/assets/github-badge-BuDsrsPn.js.gz +0 -0
  311. package/dist/dashboard/assets/index-BeLRhsmt.js.gz +0 -0
  312. package/dist/dashboard/assets/inline-DToMICwl.js.gz +0 -0
  313. package/dist/dashboard/assets/input-WlyHWeG2.js.gz +0 -0
  314. package/dist/dashboard/assets/layout-DaJ5baJr.js.gz +0 -0
  315. package/dist/dashboard/assets/list-row-B3oSK13z.js.gz +0 -0
  316. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  317. package/dist/dashboard/assets/model-bans-BmYTmbAk.js +0 -1
  318. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  319. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  320. package/dist/dashboard/assets/numbers-Dulqgys5.js.gz +0 -0
  321. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  322. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  323. package/dist/dashboard/assets/select-BfZ3SCTM.js.gz +0 -0
  324. package/dist/dashboard/assets/settings--3hxSyry.js +0 -1
  325. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  326. package/dist/dashboard/assets/stack-B1w5BM0u.js.gz +0 -0
  327. package/dist/dashboard/assets/state-DhZBfWgx.js.gz +0 -0
  328. package/dist/dashboard/assets/switch-yD7D99Lg.js.gz +0 -0
  329. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  330. package/src/console/admin/model-abuse/contracts.ts +0 -38
  331. package/src/console/admin/model-abuse/routes.ts +0 -97
  332. package/src/security/model-abuse.ts +0 -704
  333. package/src/transport/guards/concurrency-guard.ts +0 -125
  334. /package/dist/dashboard/assets/{app-MdVfwraB.js → app-BaWd0puM.js} +0 -0
  335. /package/dist/dashboard/assets/{app-MdVfwraB.js.gz → app-BaWd0puM.js.gz} +0 -0
@@ -1,101 +1,10 @@
1
1
  /**
2
- * In-flight provider-dispatch registry — the single source of truth for the
3
- * live "in flight" gauge. One entry per request that has actually acquired
4
- * provider-dispatch leases, keyed by `requestId`, carrying the client IP
5
- * captured at ingress and the hard deadline the flight must not outlive.
6
- *
7
- * The registry is *owned* by the `ProxyRequestStateStore` (`state.ts`), which
8
- * is also the one place that evicts a request, so a flight cannot outlive its
9
- * state. A separate process-global counter alongside the store's
10
- * `liveControllers` map would be a second registry able to disagree with it: a
11
- * flight the store had already torn down would stay counted there forever.
12
- *
13
- * The store hands each entry an `expiresAtMs` (the request's hard deadline). A
14
- * periodic backstop sweep reads `overdue()` and force-releases any flight whose
15
- * deadline has passed, so the gauge settles even if an abort path never fires.
16
- *
17
- * Pub/sub lets the console push the live snapshot over SSE instead of polling.
18
- * Process-local: each gateway instance reports its own flights.
2
+ * The live "in flight" snapshot shape, shared by the store, the console live
3
+ * domain, and the dashboard. Derived from the request state store's own
4
+ * `liveControllers` map — the single registry that already owns a request's
5
+ * lifetime — so the gauge cannot disagree with what is actually running.
19
6
  */
20
- import { metrics } from "../../observability/metrics";
21
-
22
7
  export interface InFlightSnapshot {
23
8
  readonly inFlight: number;
24
9
  readonly uniqueIps: number;
25
10
  }
26
-
27
- interface Flight {
28
- readonly clientIp: string;
29
- /** Hard deadline after which the backstop sweep releases this flight. */
30
- expiresAtMs: number;
31
- }
32
-
33
- export interface InFlightRegistry {
34
- /** Register a flight once its dispatch leases are acquired. Idempotent per id. */
35
- track(requestId: string, clientIp: string, expiresAtMs: number): void;
36
- /** Release a flight. Idempotent; an unknown id is a no-op. */
37
- untrack(requestId: string): void;
38
- /** Re-arm a flight's hard deadline (streaming swaps the pre-stream budget). */
39
- extend(requestId: string, expiresAtMs: number): void;
40
- snapshot(): InFlightSnapshot;
41
- count(): number;
42
- /** Ids whose deadline plus the sweep grace has elapsed — the backstop's worklist. */
43
- overdue(nowMs: number, graceMs: number): readonly string[];
44
- subscribe(listener: (snapshot: InFlightSnapshot) => void): () => void;
45
- }
46
-
47
- export function createInFlightRegistry(): InFlightRegistry {
48
- const flights = new Map<string, Flight>();
49
- const listeners = new Set<(snapshot: InFlightSnapshot) => void>();
50
-
51
- const snapshot = (): InFlightSnapshot => {
52
- let uniqueIps = 0;
53
- const seen = new Set<string>();
54
- for (const flight of flights.values()) {
55
- if (!seen.has(flight.clientIp)) {
56
- seen.add(flight.clientIp);
57
- uniqueIps += 1;
58
- }
59
- }
60
- return { inFlight: flights.size, uniqueIps };
61
- };
62
-
63
- const publish = (): void => {
64
- const current = snapshot();
65
- metrics.proxy_in_flight.set(current.inFlight);
66
- for (const listener of listeners) listener(current);
67
- };
68
-
69
- return {
70
- track(requestId, clientIp, expiresAtMs) {
71
- flights.set(requestId, { clientIp: clientIp.length > 0 ? clientIp : "unknown", expiresAtMs });
72
- publish();
73
- },
74
- untrack(requestId) {
75
- if (!flights.delete(requestId)) return;
76
- publish();
77
- },
78
- extend(requestId, expiresAtMs) {
79
- const flight = flights.get(requestId);
80
- if (flight === undefined) return;
81
- flight.expiresAtMs = expiresAtMs;
82
- },
83
- snapshot,
84
- count() {
85
- return flights.size;
86
- },
87
- overdue(nowMs, graceMs) {
88
- const ids: string[] = [];
89
- for (const [requestId, flight] of flights) {
90
- if (nowMs >= flight.expiresAtMs + graceMs) ids.push(requestId);
91
- }
92
- return ids;
93
- },
94
- subscribe(listener) {
95
- listeners.add(listener);
96
- return () => {
97
- listeners.delete(listener);
98
- };
99
- },
100
- };
101
- }
@@ -5,14 +5,14 @@ import type { ApiKeyAdmissionService } from "../../security/admission/service";
5
5
  import type { RouteCandidate as RouteCandidate, InMemoryRouteSnapshotService, RoutePlan } from "../routing/route-model";
6
6
  import type { RouteContinuationAffinity } from "../routing/route-model";
7
7
  import { resolveAliasTarget, type RoutingEngine } from "../routing/router";
8
- import { projectForRoute, routeCapabilitiesFor } from "../translation/capabilities";
9
- import type { RequiredCapability } from "../translation/capabilities";
8
+ import { projectForRoute, routeCapabilitiesFor } from "../../protocol/translation/capabilities";
9
+ import type { RequiredCapability } from "../../protocol/translation/capabilities";
10
10
  import { isModelAllowed, type ResolvedApiKey } from "../../security/api-key-auth";
11
11
  import { allowsCliToolMappings } from "../../security/cli-client-fingerprint";
12
- import { dropIncompleteToolRounds, repairRequestToolCalls } from "../translation/tool-repair";
13
- import { sanitizeRequestToolIds } from "../translation/tool-id";
14
- import { dropCorruptAttachments } from "../translation/attachment-integrity";
15
- import { parseThinkingSuffix, withThinkingSuffixIntent } from "../translation/thinking";
12
+ import { dropIncompleteToolRounds, repairRequestToolCalls } from "../../protocol/translation/tool-repair";
13
+ import { sanitizeRequestToolIds } from "../../protocol/translation/tool-id";
14
+ import { dropCorruptAttachments } from "../../protocol/translation/attachment-integrity";
15
+ import { parseThinkingSuffix, withThinkingSuffixIntent } from "../../protocol/translation/thinking";
16
16
  import { nativeServicePathFor } from "../contracts";
17
17
  import { log } from "../../observability/logger";
18
18
  import { BUDDY_PROVIDER_IDS } from "../../providers/provider-metadata";
@@ -5,8 +5,8 @@ import type { ResolvedApiKey } from "../../security/api-key-auth";
5
5
  import type { PreparedProxyRequest } from "./preparer";
6
6
  import type { PayloadCaptureState, TelemetryPayloadCapture } from "../../observability/payload-capture";
7
7
  import type { TelemetryPayloadDepth, TelemetryPayloadMode } from "../../console/settings/contracts";
8
- import { createInFlightRegistry, type InFlightSnapshot } from "./inflight";
9
8
  import { log } from "../../observability/logger";
9
+ import type { InFlightSnapshot } from "./inflight";
10
10
  import { fastPathname } from "../pathname";
11
11
 
12
12
  export interface ProxyRequestOutcome {
@@ -182,15 +182,39 @@ export interface RequestTracker {
182
182
  * shutdown coordination, which waits on tracked requests (or aborts them
183
183
  * past the grace window) instead of relying on connection close events.
184
184
  */
185
+ /**
186
+ * Minimal pub/sub over a store's snapshot. Polling already re-reads
187
+ * `inFlightSnapshot()`, so this only pushes the same derived value to the
188
+ * console's SSE stream; no second registry behind it.
189
+ */
190
+ function subscribeInFlightSnapshot(
191
+ store: { inFlightSnapshot(): InFlightSnapshot },
192
+ listener: (snapshot: InFlightSnapshot) => void,
193
+ ): () => void {
194
+ const timers = new Set<ReturnType<typeof setTimeout>>();
195
+ const push = (): void => listener(store.inFlightSnapshot());
196
+ push();
197
+ const handle = setInterval(push, 1_000);
198
+ (handle as unknown as { unref?: () => void })?.unref?.();
199
+ return () => {
200
+ clearInterval(handle);
201
+ for (const t of timers) clearTimeout(t);
202
+ timers.clear();
203
+ };
204
+ }
205
+
185
206
  export class ProxyRequestStateStore {
186
207
  private readonly states = new WeakMap<Request, ProxyRequestState>();
187
208
  private readonly liveControllers = new Map<string, AbortController>();
188
209
  /**
189
- * The in-flight gauge lives here, not in a free-standing module: this store
190
- * is the one place that owns a request's lifetime and evicts it, so the
191
- * gauge can never count a request the store has already torn down.
210
+ * The in-flight gauge is derived from the same map that owns a request's
211
+ * lifetime. There is no second registry: a count that disagreed with
212
+ * `liveControllers` was the ghost — entries that outlived the request they
213
+ * described. The deadline each flight last armed is kept alongside, so the
214
+ * backstop sweep still finds requests whose abort path never fired.
192
215
  */
193
- private readonly inFlight = createInFlightRegistry();
216
+ private readonly inFlightDeadlines = new Map<string, number>();
217
+ private readonly inFlightIps = new Map<string, string>();
194
218
 
195
219
  constructor(private readonly tracker?: RequestTracker) {}
196
220
 
@@ -199,43 +223,38 @@ export class ProxyRequestStateStore {
199
223
  }
200
224
 
201
225
  inFlightSnapshot(): InFlightSnapshot {
202
- return this.inFlight.snapshot();
226
+ let uniqueIps = 0;
227
+ const seen = new Set<string>();
228
+ for (const ip of this.inFlightIps.values()) {
229
+ if (!seen.has(ip)) {
230
+ seen.add(ip);
231
+ uniqueIps += 1;
232
+ }
233
+ }
234
+ return { inFlight: this.inFlightDeadlines.size, uniqueIps };
203
235
  }
204
236
 
205
237
  /** Live flight count for this store. */
206
238
  inFlightCount(): number {
207
- return this.inFlight.count();
239
+ return this.inFlightDeadlines.size;
208
240
  }
209
241
 
210
242
  subscribeInFlight(listener: (snapshot: InFlightSnapshot) => void): () => void {
211
- return this.inFlight.subscribe(listener);
243
+ return subscribeInFlightSnapshot(this, listener);
212
244
  }
213
245
 
214
246
  /**
215
- * Backstop worklist: ids whose hard deadline plus `graceMs` has elapsed while
216
- * still tracked. A correctly-released request never appears here — this is
217
- * the safety net for an abort path that did not fire (a half-closed socket
218
- * that neither pulls, cancels, nor aborts).
219
- */
220
- overdueInFlight(nowMs: number, graceMs: number): readonly string[] {
221
- return this.inFlight.overdue(nowMs, graceMs);
222
- }
223
-
224
- /**
225
- * Releases every flight past its deadline. Two tiers, because aborting the
226
- * controller unwinds the fetch but only *releases* the flight if some path
227
- * observes the abort:
228
- *
229
- * - Past `expiresAtMs + graceMs`: abort the controller, which unblocks a
230
- * paused read and fires the release in `dispatch/proxy-request`.
231
- * - Past `expiresAtMs + hardGraceMs`: the abort did not release it, so
232
- * force-drop the gauge entry. The fetch is already torn down by the abort,
233
- * so leaving the entry would only mean a permanently wrong number — the
234
- * exact defect this backstop exists to end. Logged, never silent.
247
+ * Releases every flight past its deadline. Aborting the controller unwinds
248
+ * the fetch and lets the request's own `cleanup` run, which drops the
249
+ * flight's entry with it. A request nothing observes — a half-closed socket
250
+ * that neither pulls, cancels, nor aborts — never runs that cleanup, so
251
+ * after a further grace window the sweep drops the entry itself: the fetch
252
+ * is already torn down by the abort, and a permanently wrong number is the
253
+ * exact defect this backstop exists to end. Logged, never silent.
235
254
  */
236
255
  sweepOverdueInFlight(nowMs: number, graceMs: number, hardGraceMs: number): number {
237
- const released = this.inFlight.overdue(nowMs, graceMs);
238
- for (const requestId of released) {
256
+ for (const [requestId, deadline] of this.inFlightDeadlines) {
257
+ if (nowMs < deadline + graceMs) continue;
239
258
  const controller = this.liveControllers.get(requestId);
240
259
  try {
241
260
  if (controller && !controller.signal.aborted) {
@@ -246,14 +265,19 @@ export class ProxyRequestStateStore {
246
265
  } catch {
247
266
  }
248
267
  }
249
- const stuck = this.inFlight.overdue(nowMs, hardGraceMs);
250
- for (const requestId of stuck) {
268
+ let forced = 0;
269
+ for (const [requestId, deadline] of this.inFlightDeadlines) {
270
+ if (nowMs < deadline + hardGraceMs) continue;
271
+ this.inFlightDeadlines.delete(requestId);
272
+ this.inFlightIps.delete(requestId);
273
+ forced += 1;
274
+ }
275
+ if (forced > 0) {
251
276
  log.error(
252
- `[inflight-backstop] force-releasing request ${requestId}: abort did not release it within ${hardGraceMs}ms`,
277
+ `[inflight-backstop] force-releasing ${forced} flight(s): abort did not release them within ${hardGraceMs}ms`,
253
278
  );
254
- this.inFlight.untrack(requestId);
255
279
  }
256
- return stuck.length > 0 ? stuck.length : released.length;
280
+ return forced;
257
281
  }
258
282
 
259
283
  abortAll(reason?: unknown): void {
@@ -325,7 +349,8 @@ export class ProxyRequestStateStore {
325
349
  startProviderFlight: () => {
326
350
  if (cleaned || providerFlightStarted) return;
327
351
  providerFlightStarted = true;
328
- this.inFlight.track(requestId, state.clientIdentity?.address ?? "unknown", state.deadlineMs);
352
+ this.inFlightDeadlines.set(requestId, state.deadlineMs);
353
+ this.inFlightIps.set(requestId, state.clientIdentity?.address || "unknown");
329
354
  },
330
355
  releaseIngressBody: () => {
331
356
  state.ingressBody = undefined;
@@ -342,7 +367,7 @@ export class ProxyRequestStateStore {
342
367
  // request that legitimately extends its budget must move the flight's
343
368
  // deadline too — otherwise the sweep would force-release a healthy
344
369
  // long stream the moment the pre-stream budget elapsed.
345
- this.inFlight.extend(requestId, state.deadlineMs);
370
+ if (providerFlightStarted) this.inFlightDeadlines.set(requestId, state.deadlineMs);
346
371
  armDeadline(ms);
347
372
  },
348
373
  cleanup: () => {
@@ -351,7 +376,10 @@ export class ProxyRequestStateStore {
351
376
  // Every step is guarded: one throwing cleanup must not skip the
352
377
  // remaining cleanups, the abort, or the map eviction (leak).
353
378
  try {
354
- if (providerFlightStarted) this.inFlight.untrack(state.requestId);
379
+ if (providerFlightStarted) {
380
+ this.inFlightDeadlines.delete(state.requestId);
381
+ this.inFlightIps.delete(state.requestId);
382
+ }
355
383
  } catch {
356
384
  }
357
385
  try {
@@ -10,7 +10,7 @@
10
10
  import type { CartethyiaDatabase } from "../../persistence/db-handle";
11
11
  import type { CanonicalRequest } from "../../protocol/canonical-model";
12
12
  import type { PreparedProxyRequest } from "./preparer";
13
- import { normalizeThinkingConfig } from "../translation/thinking";
13
+ import { normalizeThinkingConfig } from "../../protocol/translation/thinking";
14
14
  import { compressRequest } from "./rtk/compress-request";
15
15
  import { preferencesReaderFor } from "../../persistence/tenant-preferences";
16
16
  import { resolveUpstreamTimeoutMs } from "../../config/timeouts";
@@ -741,43 +741,53 @@ class RouteCatalogRepository {
741
741
  : {}),
742
742
  };
743
743
  if (account.status === "cooldown") {
744
- // Expired cooldowns read as healthy here without a fire-and-forget
745
- // write: AccountHealthSweeper materializes the recovery every 30s,
746
- // so the builder stays a pure read (no UPDATE racing the request).
744
+ // A row that still says `cooldown` stays excluded until the sweeper
745
+ // flips it back to `active`. An *expired* deadline used to read as
746
+ // healthy here (the comment below's "pure read" reasoning), which let
747
+ // routing redial the account in the window between the deadline
748
+ // elapsing and the next 30s sweep — reproducing the refusal that
749
+ // cooled it and logging a fresh `cooldown → cooldown` row each time
750
+ // (the operator's "still hit a cooled-down account" report). The
751
+ // sweep is the only exit from `cooldown`; until it runs the row is
752
+ // not proof the account can serve.
747
753
  //
748
754
  // `forceDisableCooldown` skips the exclusion entirely. The cooldown
749
755
  // is still real and still recorded — it simply stops deciding
750
756
  // routing. That is what makes the setting reversible: nothing was
751
757
  // written, so turning it off needs no cleanup, and Health still
752
758
  // reports the truth about the account.
753
- if (account.cooldownUntil && account.cooldownUntil.getTime() > Date.now()) {
754
- const overrideActive =
755
- rowTenantId === null
756
- ? anyTenantOverrides
757
- : cooldownOverrideTenants.has(rowTenantId);
758
- if (overrideActive) {
759
- // The account is still cooling — this only stops it from being
760
- // excluded. `plan()` reads `cooldown_until` to answer the
761
- // all-cooling case, so it stays populated either way.
762
- //
763
- // Neither `health_status` nor `cooldown_kind` is set: the
764
- // evaluator excludes a hard cooldown on `health_status ===
765
- // "cooldown"` alone, so stamping it here would keep excluding
766
- // the very accounts the override exists to reach — a spent quota
767
- // or a policy block, which are the ones an operator actually
768
- // wants to override.
769
- candidate.cooldown_until = account.cooldownUntil.getTime();
770
- } else {
771
- candidate.health_status = "cooldown";
772
- candidate.cooldown_kind = hardCooldownCategory(account.lastErrorCategory)
773
- ? "hard"
774
- : "soft";
775
- // The deadline rides with the exclusion it explains. `plan()`
776
- // reads it to answer the all-cooling case with the real reset
777
- // instead of a bare 429, so a client backs off for the window
778
- // that is actually open rather than inventing one.
779
- candidate.cooldown_until = account.cooldownUntil.getTime();
780
- }
759
+ const overrideActive =
760
+ rowTenantId === null
761
+ ? anyTenantOverrides
762
+ : cooldownOverrideTenants.has(rowTenantId);
763
+ const accountDeadline = account.cooldownUntil;
764
+ const unexpired =
765
+ accountDeadline !== null && accountDeadline.getTime() > Date.now();
766
+ if (overrideActive) {
767
+ // The account is still cooling — this only stops it from being
768
+ // excluded. `plan()` reads `cooldown_until` to answer the
769
+ // all-cooling case, so it stays populated either way.
770
+ //
771
+ // Neither `health_status` nor `cooldown_kind` is set: the
772
+ // evaluator excludes a hard cooldown on `health_status ===
773
+ // "cooldown"` alone, so stamping it here would keep excluding
774
+ // the very accounts the override exists to reach — a spent quota
775
+ // or a policy block, which are the ones an operator actually
776
+ // wants to override.
777
+ if (unexpired) candidate.cooldown_until = accountDeadline!.getTime();
778
+ } else {
779
+ candidate.health_status = "cooldown";
780
+ candidate.cooldown_kind = hardCooldownCategory(account.lastErrorCategory)
781
+ ? "hard"
782
+ : "soft";
783
+ // The deadline rides with the exclusion it explains. `plan()`
784
+ // reads it to answer the all-cooling case with the real reset
785
+ // instead of a bare 429, so a client backs off for the window
786
+ // that is actually open rather than inventing one. An expired
787
+ // deadline carries no reset — the sweep is about to recover the
788
+ // row, and quoting a past instant would tell the client to retry
789
+ // "immediately" for a wait that is already over.
790
+ if (unexpired) candidate.cooldown_until = accountDeadline!.getTime();
781
791
  }
782
792
  }
783
793
 
@@ -21,7 +21,7 @@ import {
21
21
  import {
22
22
  candidateSupportsRequest,
23
23
  type RequiredCapability,
24
- } from "../translation/capabilities";
24
+ } from "../../protocol/translation/capabilities";
25
25
  import { planAllowsCandidate } from "./plan-gate";
26
26
  import { InMemoryAdmissionController, admissionKey } from "./admission";
27
27
  import { ReservationManager } from "./reservations";
@@ -32,7 +32,7 @@ import {
32
32
  routeCandidateIndex,
33
33
  } from "./candidate-index";
34
34
  import { totalRemainingCredit, totalRemainingPercent, type ProviderQuotaWindow } from "../../providers/quota/quota-contracts";
35
- import { getCachedQuotaEntry, quotaLens } from "../../console/quota/cache";
35
+ import { getCachedQuotaEntry, quotaLens } from "../../providers/quota/cache";
36
36
  import type { RedisClient } from "../../persistence/redis";
37
37
  import { sharedClaudeSlowLanes } from "../../providers/integrations/claude/claude-slow-lane";
38
38
 
@@ -6,7 +6,7 @@ import { parseToolDefinition } from "../dialects";
6
6
  import { canContainToolResult } from "../../../protocol/canonical-model";
7
7
  import { MessagesLedgerError } from "./errors";
8
8
  import { finiteNumber, stringValue } from "../../../protocol/codecs";
9
- import { LEVEL_TO_BUDGET } from "../../translation/thinking";
9
+ import { LEVEL_TO_BUDGET } from "../../../protocol/translation/thinking";
10
10
 
11
11
  export interface MessagesParseOptions {
12
12
  /** Explicit Claude model generation (for example `4.6` or `4.7`). */