cartethyia 2.5.9 → 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 (386) hide show
  1. package/.env.example +15 -42
  2. package/README.md +11 -10
  3. package/dist/dashboard/assets/{BannedPage-Brvuj_Eb.js → BannedPage-l6XMnfr9.js} +1 -1
  4. package/dist/dashboard/assets/BannedPage-l6XMnfr9.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolDetailPage-CqfXtI3y.js → CliToolDetailPage-DwOzAW45.js} +1 -1
  6. package/dist/dashboard/assets/CliToolDetailPage-DwOzAW45.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolsPage-GQeS91bg.js → CliToolsPage-BT3Up3QA.js} +1 -1
  8. package/dist/dashboard/assets/CliToolsPage-BT3Up3QA.js.gz +0 -0
  9. package/dist/dashboard/assets/{CombosPage-BDRsTXBB.js → CombosPage-6kYIUpzR.js} +1 -1
  10. package/dist/dashboard/assets/CombosPage-6kYIUpzR.js.gz +0 -0
  11. package/dist/dashboard/assets/{ConsoleLogPage-zP8AFHX0.js → ConsoleLogPage-zRnj1mlR.js} +1 -1
  12. package/dist/dashboard/assets/ConsoleLogPage-zRnj1mlR.js.gz +0 -0
  13. package/dist/dashboard/assets/{CustomizationPage-BmfrNZ14.js → CustomizationPage-C7m-H1Rz.js} +1 -1
  14. package/dist/dashboard/assets/CustomizationPage-C7m-H1Rz.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js.gz +0 -0
  17. package/dist/dashboard/assets/{LoginPage-DoreIgm8.js → LoginPage-CbphLvjg.js} +1 -1
  18. package/dist/dashboard/assets/LoginPage-CbphLvjg.js.gz +0 -0
  19. package/dist/dashboard/assets/{ModelPicker-C7pDb41R.js → ModelPicker-DVny4S5_.js} +1 -1
  20. package/dist/dashboard/assets/ModelPicker-DVny4S5_.js.gz +0 -0
  21. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js +1 -0
  22. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js.gz +0 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js +3 -0
  24. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js.gz +0 -0
  25. package/dist/dashboard/assets/{ProvidersPage-BnoPgA7w.js → ProvidersPage-Dfb2896L.js} +1 -1
  26. package/dist/dashboard/assets/ProvidersPage-Dfb2896L.js.gz +0 -0
  27. package/dist/dashboard/assets/{ProxyPage-Bq_TGgdb.js → ProxyPage-BaCIdAUt.js} +1 -1
  28. package/dist/dashboard/assets/ProxyPage-BaCIdAUt.js.gz +0 -0
  29. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js +1 -0
  30. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js.gz +0 -0
  31. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js +1 -0
  32. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js.gz +0 -0
  33. package/dist/dashboard/assets/{SetupPage-Day3mCOn.js → SetupPage-D4g6vOGc.js} +1 -1
  34. package/dist/dashboard/assets/SetupPage-D4g6vOGc.js.gz +0 -0
  35. package/dist/dashboard/assets/{SortableList-DQxllnB5.js → SortableList-C93i14BD.js} +1 -1
  36. package/dist/dashboard/assets/SortableList-C93i14BD.js.gz +0 -0
  37. package/dist/dashboard/assets/{StudioPage-uMExoWu1.js → StudioPage-SgQpymjm.js} +1 -1
  38. package/dist/dashboard/assets/{StudioPage-uMExoWu1.js.gz → StudioPage-SgQpymjm.js.gz} +0 -0
  39. package/dist/dashboard/assets/{UsagePage-DXa1oR-4.js → UsagePage-BFME-eba.js} +2 -2
  40. package/dist/dashboard/assets/UsagePage-BFME-eba.js.gz +0 -0
  41. package/dist/dashboard/assets/{api-keys-DQYLQxpW.js → api-keys-C23S9sgp.js} +1 -1
  42. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  43. package/dist/dashboard/assets/{app-BIt446yE.js → app-2KhtHCv9.js} +1 -1
  44. package/dist/dashboard/assets/{app-BIt446yE.js.gz → app-2KhtHCv9.js.gz} +0 -0
  45. package/dist/dashboard/assets/app-CEeaMHOy.css +2 -0
  46. package/dist/dashboard/assets/app-CEeaMHOy.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-C9FD_JwJ.js → assert-DU6qrMA_.js} +1 -1
  48. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-CR72dasT.js → badge-CKsF123d.js} +1 -1
  50. package/dist/dashboard/assets/badge-CKsF123d.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-CI9_eSfO.js → banner-8j7uChA9.js} +1 -1
  52. package/dist/dashboard/assets/banner-8j7uChA9.js.gz +0 -0
  53. package/dist/dashboard/assets/{card-DS7CQEsO.js → card-CdsSlWA3.js} +1 -1
  54. package/dist/dashboard/assets/card-CdsSlWA3.js.gz +0 -0
  55. package/dist/dashboard/assets/{cli-tools-CNqzrfdb.js → cli-tools-BaFUuFFF.js} +1 -1
  56. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  57. package/dist/dashboard/assets/{clipboard-button-611pSsaX.js → clipboard-button-uL5aYLfW.js} +1 -1
  58. package/dist/dashboard/assets/clipboard-button-uL5aYLfW.js.gz +0 -0
  59. package/dist/dashboard/assets/{dialog-k37exjNt.js → dialog-C07hr5_G.js} +1 -1
  60. package/dist/dashboard/assets/dialog-C07hr5_G.js.gz +0 -0
  61. package/dist/dashboard/assets/{drawer-CX7N8ucR.js → drawer-BPO1TcKH.js} +1 -1
  62. package/dist/dashboard/assets/drawer-BPO1TcKH.js.gz +0 -0
  63. package/dist/dashboard/assets/{entry-CTP8AyiS.js → entry-Bz_CtDfC.js} +1 -1
  64. package/dist/dashboard/assets/entry-Bz_CtDfC.js.gz +0 -0
  65. package/dist/dashboard/assets/entry-CwPRKk0d.js +4 -0
  66. package/dist/dashboard/assets/entry-CwPRKk0d.js.gz +0 -0
  67. package/dist/dashboard/assets/entry-GJRbmrpA.js +1 -0
  68. package/dist/dashboard/assets/entry-GJRbmrpA.js.gz +0 -0
  69. package/dist/dashboard/assets/{github-badge-sltk1qUi.js → github-badge-DmQreSDd.js} +1 -1
  70. package/dist/dashboard/assets/github-badge-DmQreSDd.js.gz +0 -0
  71. package/dist/dashboard/assets/{index-z3zDOSMM.js → index-Bblu6erR.js} +2 -2
  72. package/dist/dashboard/assets/index-Bblu6erR.js.gz +0 -0
  73. package/dist/dashboard/assets/{inline-BhY2sSnO.js → inline-C9dCYaBZ.js} +1 -1
  74. package/dist/dashboard/assets/inline-C9dCYaBZ.js.gz +0 -0
  75. package/dist/dashboard/assets/{input-V1umFiBk.js → input-CjCnXweJ.js} +1 -1
  76. package/dist/dashboard/assets/input-CjCnXweJ.js.gz +0 -0
  77. package/dist/dashboard/assets/{layout-BBOYycyS.js → layout-V6y8DAkl.js} +1 -1
  78. package/dist/dashboard/assets/layout-V6y8DAkl.js.gz +0 -0
  79. package/dist/dashboard/assets/{list-row-1zzZYM0B.js → list-row-CM1AaG_y.js} +1 -1
  80. package/dist/dashboard/assets/list-row-CM1AaG_y.js.gz +0 -0
  81. package/dist/dashboard/assets/{live-BivGfuUs.js → live-ta6GMb-8.js} +1 -1
  82. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  83. package/dist/dashboard/assets/{model-bans-CmffjLuG.js → model-bans-BmYTmbAk.js} +1 -1
  84. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  85. package/dist/dashboard/assets/{mutation-46P0oWMe.js → mutation-g_fduiNw.js} +1 -1
  86. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  87. package/dist/dashboard/assets/{numbers-DkfMR5Qs.js → numbers-BOevJzdz.js} +1 -1
  88. package/dist/dashboard/assets/numbers-BOevJzdz.js.gz +0 -0
  89. package/dist/dashboard/assets/{query-keys-BFhGpwR1.js → query-keys-UETqfytp.js} +1 -1
  90. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  91. package/dist/dashboard/assets/{routing-CAb4F37R.js → routing-BPUo-W8d.js} +1 -1
  92. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  93. package/dist/dashboard/assets/{select-C6MMiaio.js → select-C980c4cz.js} +1 -1
  94. package/dist/dashboard/assets/select-C980c4cz.js.gz +0 -0
  95. package/dist/dashboard/assets/{settings-DNX9sydi.js → settings--3hxSyry.js} +1 -1
  96. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  97. package/dist/dashboard/assets/{stack-BHTfXdz_.js → stack-_gfTdLVB.js} +1 -1
  98. package/dist/dashboard/assets/stack-_gfTdLVB.js.gz +0 -0
  99. package/dist/dashboard/assets/{state-mPDRlQkl.js → state-2c5V4zo7.js} +1 -1
  100. package/dist/dashboard/assets/state-2c5V4zo7.js.gz +0 -0
  101. package/dist/dashboard/assets/{switch-DOmJxg7H.js → switch-Dkke7Naf.js} +1 -1
  102. package/dist/dashboard/assets/switch-Dkke7Naf.js.gz +0 -0
  103. package/dist/dashboard/assets/{useMutation-Dem0lXQj.js → useMutation-EDFRkn1i.js} +1 -1
  104. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  105. package/dist/dashboard/index.html +1 -1
  106. package/dist/dashboard/index.html.gz +0 -0
  107. package/dist/dashboard/precompressed-assets.json +51 -51
  108. package/migrations/README.md +52 -52
  109. package/migrations/full-postgres/0020_add_telemetry_event_analytics.sql +77 -0
  110. package/migrations/full-postgres/0021_add_api_key_concurrency_tolerance.sql +13 -0
  111. package/migrations/full-postgres/0022_add_inferhub_config_key.sql +17 -0
  112. package/migrations/full-postgres/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  113. package/migrations/lite-sqlite3/0020_add_telemetry_event_analytics.sql +69 -0
  114. package/migrations/lite-sqlite3/0021_add_api_key_concurrency_tolerance.sql +13 -0
  115. package/migrations/lite-sqlite3/0022_add_inferhub_config_key.sql +17 -0
  116. package/migrations/lite-sqlite3/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  117. package/package.json +96 -97
  118. package/scripts/cli/admin.ts +126 -125
  119. package/scripts/cli/autostart.ts +237 -237
  120. package/scripts/cli/background.ts +120 -110
  121. package/scripts/cli/bin/carte.cjs +8 -8
  122. package/scripts/cli/bin/cartethyia.cjs +167 -167
  123. package/scripts/cli/console-menu.ts +308 -275
  124. package/scripts/cli/controller.ts +145 -0
  125. package/scripts/cli/doctor.ts +1 -1
  126. package/scripts/cli/env.ts +99 -99
  127. package/scripts/cli/gateway.ts +264 -261
  128. package/scripts/{health.ts → cli/health.ts} +4 -4
  129. package/scripts/cli/instance.ts +234 -224
  130. package/scripts/cli/main.ts +188 -164
  131. package/scripts/cli/platform.ts +64 -64
  132. package/scripts/cli/prompt.ts +275 -107
  133. package/scripts/cli/services.ts +88 -88
  134. package/scripts/cli/setup.ts +445 -445
  135. package/scripts/cli/start.ts +85 -82
  136. package/scripts/cli/startup-signal.ts +23 -23
  137. package/scripts/cli/telemetry.ts +70 -0
  138. package/scripts/cli/tray/index.ts +263 -263
  139. package/scripts/cli/tray/windows.ps1 +107 -107
  140. package/scripts/cli/tray.ts +192 -208
  141. package/scripts/cli/update.ts +39 -39
  142. package/scripts/cli/version.ts +67 -67
  143. package/scripts/cli/wordmark.ts +58 -58
  144. package/src/boot/app.ts +16 -1
  145. package/src/boot/dependencies.ts +128 -25
  146. package/src/config/package-paths.ts +24 -0
  147. package/src/config/resources.ts +137 -0
  148. package/src/config/runtime.ts +133 -76
  149. package/src/config/spec.ts +30 -29
  150. package/src/config/telemetry.ts +0 -25
  151. package/src/console/api-keys/bucket-spend.ts +14 -17
  152. package/src/console/api-keys/contracts.ts +410 -410
  153. package/src/console/api-keys/routes.ts +12 -0
  154. package/src/console/audit/store.ts +2 -3
  155. package/src/console/auth/setup-service.ts +8 -1
  156. package/src/console/backup/routes.ts +7 -0
  157. package/src/console/backup/service.ts +463 -463
  158. package/src/console/backup/store.ts +16 -11
  159. package/src/console/backup/validate.ts +1 -4
  160. package/src/console/cli-tools/fs-ops.ts +18 -2
  161. package/src/console/data-management/contracts.ts +1 -8
  162. package/src/console/data-management/operations.ts +61 -48
  163. package/src/console/data-management/routes.ts +4 -2
  164. package/src/console/domain-registration.ts +25 -3
  165. package/src/console/inferhub/client.ts +139 -0
  166. package/src/console/inferhub/key-store.ts +129 -0
  167. package/src/console/inferhub/normalize.ts +347 -0
  168. package/src/console/inferhub/routes.ts +411 -0
  169. package/src/console/inferhub/store.ts +109 -0
  170. package/src/console/inferhub/types.ts +183 -0
  171. package/src/console/observability/contracts.ts +2 -41
  172. package/src/console/observability/store.ts +176 -371
  173. package/src/console/providers/catalog/public-model-store.ts +0 -0
  174. package/src/console/providers/catalog/store.ts +23 -36
  175. package/src/console/quota/account-quota-shared.ts +52 -52
  176. package/src/console/quota/account-quota-tenant.ts +16 -24
  177. package/src/console/quota/refresh.ts +441 -441
  178. package/src/console/remote-support/service.ts +270 -114
  179. package/src/console/routing/pools/import-parse.ts +206 -206
  180. package/src/console/routing/pools/operations.ts +543 -543
  181. package/src/console/routing/pools/probe-verdict.ts +132 -132
  182. package/src/console/routing/pools/routes.ts +181 -181
  183. package/src/console/routing/pools/store.ts +1 -1
  184. package/src/console/settings/contracts.ts +42 -40
  185. package/src/console/settings/store.ts +25 -25
  186. package/src/console/share/share-stats.ts +22 -4
  187. package/src/console/share/share-usage.ts +30 -4
  188. package/src/console/shared/cursor.ts +15 -0
  189. package/src/console/updates/repository-updates.ts +40 -39
  190. package/src/console/updates/routes.ts +12 -0
  191. package/src/main.ts +13 -5
  192. package/src/network/pool/resolver.ts +1104 -1104
  193. package/src/observability/client-name.ts +22 -0
  194. package/src/observability/event-log.ts +5 -29
  195. package/src/observability/event-query.ts +690 -0
  196. package/src/observability/log-ring.ts +26 -2
  197. package/src/observability/log-sanitize.ts +118 -0
  198. package/src/observability/logger.ts +17 -13
  199. package/src/observability/metrics.ts +35 -0
  200. package/src/observability/payload-capture.ts +114 -41
  201. package/src/observability/payload-store.ts +249 -24
  202. package/src/observability/raw-event-writer.ts +118 -0
  203. package/src/observability/runtime-metrics.ts +71 -1
  204. package/src/observability/telemetry-buffer.ts +100 -17
  205. package/src/observability/telemetry-reconciliation.ts +417 -0
  206. package/src/persistence/boot.ts +20 -9
  207. package/src/persistence/db-pg.ts +13 -0
  208. package/src/persistence/db-sqlite.ts +569 -497
  209. package/src/persistence/dialect.ts +3 -2
  210. package/src/persistence/migrate.ts +181 -181
  211. package/src/persistence/schema.ts +1496 -1406
  212. package/src/persistence/shared-cache.ts +5 -1
  213. package/src/persistence/stores/api-key-store.ts +581 -581
  214. package/src/persistence/stores/telemetry-store.ts +124 -63
  215. package/src/protocol/reasoning-text.ts +30 -0
  216. package/src/protocol/registry.ts +2 -0
  217. package/src/protocol/response/chat.ts +33 -7
  218. package/src/protocol/response/codex.ts +14 -2
  219. package/src/protocol/response/messages.ts +5 -2
  220. package/src/providers/authentication/oauth-flow-store.ts +3 -10
  221. package/src/providers/bundled-discovery-providers.ts +122 -122
  222. package/src/providers/default-registry.ts +14 -0
  223. package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
  224. package/src/providers/discovery/models-dev-catalog.ts +354 -354
  225. package/src/providers/discovery/probe-phases.ts +43 -7
  226. package/src/providers/discovery/probing-service.ts +70 -32
  227. package/src/providers/integrations/antigravity/antigravity.ts +9 -2
  228. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +85 -17
  229. package/src/providers/integrations/buddy/buddy-chat-shared.ts +934 -934
  230. package/src/providers/integrations/buddy/buddy-checkin.ts +5 -9
  231. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +3 -7
  232. package/src/providers/integrations/buddy/buddy-quota-shared.ts +3 -1
  233. package/src/providers/integrations/buddy/capabilities.ts +4 -0
  234. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +57 -49
  235. package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -180
  236. package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -206
  237. package/src/providers/integrations/buddy/workbuddy/quota.ts +161 -161
  238. package/src/providers/integrations/claude/claude-quota.ts +2 -2
  239. package/src/providers/integrations/claude/claude-user-profiles.ts +3 -2
  240. package/src/providers/integrations/claude/claude.ts +3 -4
  241. package/src/providers/integrations/cline/cline.ts +94 -8
  242. package/src/providers/integrations/codex/codex.ts +61 -37
  243. package/src/providers/integrations/cursor/cursor-catalog.ts +368 -368
  244. package/src/providers/integrations/cursor/cursor-http2.ts +300 -300
  245. package/src/providers/integrations/cursor/cursor-identity.ts +2 -4
  246. package/src/providers/integrations/cursor/cursor-request.ts +11 -0
  247. package/src/providers/integrations/cursor/cursor.ts +29 -17
  248. package/src/providers/integrations/cursor/protocol/framing.ts +129 -129
  249. package/src/providers/integrations/cursor/protocol/messages.ts +2380 -2380
  250. package/src/providers/integrations/cursor/protocol/struct.ts +305 -305
  251. package/src/providers/integrations/cursor/protocol/tool-canonical.ts +275 -0
  252. package/src/providers/integrations/github/github.ts +3 -1
  253. package/src/providers/integrations/grok/grok-quota.ts +279 -279
  254. package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -73
  255. package/src/providers/integrations/grok/grok-ratelimit.ts +218 -218
  256. package/src/providers/integrations/hermes.ts +7 -1
  257. package/src/providers/integrations/inferhub.ts +201 -73
  258. package/src/providers/integrations/kilo/kilo.ts +152 -152
  259. package/src/providers/integrations/kiro/kiro-machine-id.ts +2 -4
  260. package/src/providers/integrations/opencode/provider.ts +2 -0
  261. package/src/providers/integrations/openrouter/provider.ts +129 -129
  262. package/src/providers/integrations/qoder/qoder-quota.ts +193 -192
  263. package/src/providers/integrations/qoder/qoder-realm.ts +106 -106
  264. package/src/providers/integrations/trae/trae-headers.ts +17 -48
  265. package/src/providers/integrations/trae/trae-oauth.ts +4 -26
  266. package/src/providers/integrations/trae/trae-quota.ts +389 -384
  267. package/src/providers/integrations/trae/trae-realm.ts +15 -2
  268. package/src/providers/integrations/trae/trae.ts +22 -24
  269. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +100 -24
  270. package/src/providers/integrations/zcode/oauth.ts +1 -1
  271. package/src/providers/operations/account-health-service.ts +605 -279
  272. package/src/providers/provider-metadata.ts +12 -1
  273. package/src/providers/provider-model-definition.ts +373 -373
  274. package/src/providers/provider-probe.ts +3 -0
  275. package/src/providers/quota/quota-contracts.ts +3 -7
  276. package/src/providers/search/search-provider.ts +2 -6
  277. package/src/security/admission/contracts.ts +10 -0
  278. package/src/security/admission/in-memory-store.ts +89 -14
  279. package/src/security/admission/lua.ts +191 -182
  280. package/src/security/admission/redis-store.ts +30 -0
  281. package/src/security/admission/service.ts +18 -0
  282. package/src/security/api-key-auth-cache.ts +96 -0
  283. package/src/security/api-key-auth.ts +11 -100
  284. package/src/security/client-router-fingerprint.ts +3 -7
  285. package/src/security/ip-boundary.ts +7 -3
  286. package/src/shared/coerce.ts +67 -0
  287. package/src/shared/hash.ts +6 -0
  288. package/src/shared/time.ts +7 -0
  289. package/src/transport/dispatch/attempt-finalize.ts +26 -138
  290. package/src/transport/dispatch/attempt-loop.ts +103 -81
  291. package/src/transport/dispatch/capture-policy.ts +78 -0
  292. package/src/transport/dispatch/proxy-request.ts +4 -2
  293. package/src/transport/dispatch/streaming/encoder.ts +111 -5
  294. package/src/transport/dispatch/streaming/stream.ts +19 -2
  295. package/src/transport/dispatch/streaming/thinking-loop.ts +300 -0
  296. package/src/transport/failure-policy.ts +27 -0
  297. package/src/transport/guards/abuse-guard.ts +2 -2
  298. package/src/transport/guards/auth-guard.ts +17 -0
  299. package/src/transport/guards/body-policy.ts +3 -2
  300. package/src/transport/guards/concurrency-guard.ts +89 -13
  301. package/src/transport/guards/early-rejection-capture.ts +43 -3
  302. package/src/transport/guards/error-lifecycle.ts +10 -2
  303. package/src/transport/guards/guard-errors.ts +23 -0
  304. package/src/transport/guards/headroom-guard.ts +41 -7
  305. package/src/transport/guards/pipeline.ts +24 -0
  306. package/src/transport/guards/request-context.ts +2 -1
  307. package/src/transport/routing/admission.ts +51 -9
  308. package/src/transport/routing/bounded-lru.ts +49 -0
  309. package/src/transport/routing/candidate-index.ts +88 -0
  310. package/src/transport/routing/reservations.ts +121 -7
  311. package/src/transport/routing/round-robin.ts +10 -22
  312. package/src/transport/routing/route-catalog.ts +26 -13
  313. package/src/transport/routing/route-model.ts +22 -2
  314. package/src/transport/routing/router.ts +53 -31
  315. package/src/transport/surface/chat/encode.ts +2 -3
  316. package/src/transport/surface/chat/parse.ts +2 -1
  317. package/src/transport/surface/dialects.ts +11 -3
  318. package/src/transport/surface/messages/encode.ts +2 -1
  319. package/src/transport/surface/messages/parse.ts +3 -1
  320. package/src/transport/surface/messages/stream.ts +2 -6
  321. package/src/workers/maintenance-lease.ts +200 -0
  322. package/src/workers/scheduler.ts +101 -1
  323. package/dist/dashboard/assets/BannedPage-Brvuj_Eb.js.gz +0 -0
  324. package/dist/dashboard/assets/CliToolDetailPage-CqfXtI3y.js.gz +0 -0
  325. package/dist/dashboard/assets/CliToolsPage-GQeS91bg.js.gz +0 -0
  326. package/dist/dashboard/assets/CombosPage-BDRsTXBB.js.gz +0 -0
  327. package/dist/dashboard/assets/ConsoleLogPage-zP8AFHX0.js.gz +0 -0
  328. package/dist/dashboard/assets/CustomizationPage-BmfrNZ14.js.gz +0 -0
  329. package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js +0 -1
  330. package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js.gz +0 -0
  331. package/dist/dashboard/assets/LoginPage-DoreIgm8.js.gz +0 -0
  332. package/dist/dashboard/assets/ModelPicker-C7pDb41R.js.gz +0 -0
  333. package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js +0 -1
  334. package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js.gz +0 -0
  335. package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js +0 -3
  336. package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js.gz +0 -0
  337. package/dist/dashboard/assets/ProvidersPage-BnoPgA7w.js.gz +0 -0
  338. package/dist/dashboard/assets/ProxyPage-Bq_TGgdb.js.gz +0 -0
  339. package/dist/dashboard/assets/QuotaPage-D9DHXvom.js +0 -1
  340. package/dist/dashboard/assets/QuotaPage-D9DHXvom.js.gz +0 -0
  341. package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js +0 -1
  342. package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js.gz +0 -0
  343. package/dist/dashboard/assets/SetupPage-Day3mCOn.js.gz +0 -0
  344. package/dist/dashboard/assets/SortableList-DQxllnB5.js.gz +0 -0
  345. package/dist/dashboard/assets/UsagePage-DXa1oR-4.js.gz +0 -0
  346. package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
  347. package/dist/dashboard/assets/app-CX_Z8cMs.css +0 -2
  348. package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
  349. package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
  350. package/dist/dashboard/assets/badge-CR72dasT.js.gz +0 -0
  351. package/dist/dashboard/assets/banner-CI9_eSfO.js.gz +0 -0
  352. package/dist/dashboard/assets/card-DS7CQEsO.js.gz +0 -0
  353. package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
  354. package/dist/dashboard/assets/clipboard-button-611pSsaX.js.gz +0 -0
  355. package/dist/dashboard/assets/dialog-k37exjNt.js.gz +0 -0
  356. package/dist/dashboard/assets/drawer-CX7N8ucR.js.gz +0 -0
  357. package/dist/dashboard/assets/entry-B9Xvtnfj.js +0 -1
  358. package/dist/dashboard/assets/entry-B9Xvtnfj.js.gz +0 -0
  359. package/dist/dashboard/assets/entry-ByMGkR3C.js +0 -4
  360. package/dist/dashboard/assets/entry-ByMGkR3C.js.gz +0 -0
  361. package/dist/dashboard/assets/entry-CTP8AyiS.js.gz +0 -0
  362. package/dist/dashboard/assets/github-badge-sltk1qUi.js.gz +0 -0
  363. package/dist/dashboard/assets/index-z3zDOSMM.js.gz +0 -0
  364. package/dist/dashboard/assets/inline-BhY2sSnO.js.gz +0 -0
  365. package/dist/dashboard/assets/input-V1umFiBk.js.gz +0 -0
  366. package/dist/dashboard/assets/layout-BBOYycyS.js.gz +0 -0
  367. package/dist/dashboard/assets/list-row-1zzZYM0B.js.gz +0 -0
  368. package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
  369. package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
  370. package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
  371. package/dist/dashboard/assets/numbers-DkfMR5Qs.js.gz +0 -0
  372. package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
  373. package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
  374. package/dist/dashboard/assets/select-C6MMiaio.js.gz +0 -0
  375. package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
  376. package/dist/dashboard/assets/stack-BHTfXdz_.js.gz +0 -0
  377. package/dist/dashboard/assets/state-mPDRlQkl.js.gz +0 -0
  378. package/dist/dashboard/assets/switch-DOmJxg7H.js.gz +0 -0
  379. package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +0 -0
  380. package/scripts/build/aot.ts +0 -143
  381. package/scripts/build/build.ts +0 -24
  382. package/scripts/build/compile.ts +0 -88
  383. package/scripts/build/restart.ts +0 -120
  384. package/scripts/build/start.ts +0 -25
  385. package/src/observability/event-compaction.ts +0 -317
  386. package/src/observability/event-day-index.ts +0 -440
@@ -2,72 +2,72 @@
2
2
  "count": 114,
3
3
  "assets": [
4
4
  "assets\\AccountCooldown-Bjo92Qat.js",
5
- "assets\\BannedPage-Brvuj_Eb.js",
6
- "assets\\CliToolDetailPage-CqfXtI3y.js",
7
- "assets\\CliToolsPage-GQeS91bg.js",
8
- "assets\\CombosPage-BDRsTXBB.js",
9
- "assets\\ConsoleLogPage-zP8AFHX0.js",
10
- "assets\\CustomizationPage-BmfrNZ14.js",
11
- "assets\\HealthEventsModal-Dn3M6WZc.js",
12
- "assets\\LoginPage-DoreIgm8.js",
13
- "assets\\ModelPicker-C7pDb41R.js",
14
- "assets\\OverviewPage-CvvD1Ugk.js",
15
- "assets\\ProviderDetailPage-Clbn1gsW.js",
5
+ "assets\\BannedPage-l6XMnfr9.js",
6
+ "assets\\CliToolDetailPage-DwOzAW45.js",
7
+ "assets\\CliToolsPage-BT3Up3QA.js",
8
+ "assets\\CombosPage-6kYIUpzR.js",
9
+ "assets\\ConsoleLogPage-zRnj1mlR.js",
10
+ "assets\\CustomizationPage-C7m-H1Rz.js",
11
+ "assets\\HealthEventsModal-C8MR_BdB.js",
12
+ "assets\\LoginPage-CbphLvjg.js",
13
+ "assets\\ModelPicker-DVny4S5_.js",
14
+ "assets\\OverviewPage-DABu2Wgt.js",
15
+ "assets\\ProviderDetailPage-C15x9q13.js",
16
16
  "assets\\ProviderIcon-CmfzxpVM.js",
17
- "assets\\ProvidersPage-BnoPgA7w.js",
18
- "assets\\ProxyPage-Bq_TGgdb.js",
19
- "assets\\QuotaPage-D9DHXvom.js",
20
- "assets\\SettingsPage-7xV8WkWL.js",
21
- "assets\\SetupPage-Day3mCOn.js",
22
- "assets\\SortableList-DQxllnB5.js",
23
- "assets\\StudioPage-uMExoWu1.js",
17
+ "assets\\ProvidersPage-Dfb2896L.js",
18
+ "assets\\ProxyPage-BaCIdAUt.js",
19
+ "assets\\QuotaPage-BsdoCIw1.js",
20
+ "assets\\SettingsPage-KVJFh3Ip.js",
21
+ "assets\\SetupPage-D4g6vOGc.js",
22
+ "assets\\SortableList-C93i14BD.js",
23
+ "assets\\StudioPage-SgQpymjm.js",
24
24
  "assets\\ToolIcon-K1ckcDKg.js",
25
- "assets\\UsagePage-DXa1oR-4.js",
26
- "assets\\api-keys-DQYLQxpW.js",
27
- "assets\\app-BIt446yE.js",
28
- "assets\\app-CX_Z8cMs.css",
25
+ "assets\\UsagePage-BFME-eba.js",
26
+ "assets\\api-keys-C23S9sgp.js",
27
+ "assets\\app-2KhtHCv9.js",
28
+ "assets\\app-CEeaMHOy.css",
29
29
  "assets\\arrow-left-CpBxkoxI.js",
30
30
  "assets\\arrow-right-Dl5yKnp8.js",
31
- "assets\\assert-C9FD_JwJ.js",
31
+ "assets\\assert-DU6qrMA_.js",
32
32
  "assets\\backup-file-gdKIlg8U.js",
33
- "assets\\badge-CR72dasT.js",
34
- "assets\\banner-CI9_eSfO.js",
33
+ "assets\\badge-CKsF123d.js",
34
+ "assets\\banner-8j7uChA9.js",
35
35
  "assets\\brain-Cwed_72z.js",
36
- "assets\\card-DS7CQEsO.js",
36
+ "assets\\card-CdsSlWA3.js",
37
37
  "assets\\chevron-right-BXIy5l3h.js",
38
38
  "assets\\circle-alert-CntYHV5v.js",
39
39
  "assets\\circle-check-BU3v_mFW.js",
40
- "assets\\cli-tools-CNqzrfdb.js",
41
- "assets\\clipboard-button-611pSsaX.js",
40
+ "assets\\cli-tools-BaFUuFFF.js",
41
+ "assets\\clipboard-button-uL5aYLfW.js",
42
42
  "assets\\cog-CdWhsajs.js",
43
43
  "assets\\concurrency-BDF0ok7y.js",
44
44
  "assets\\database-Dz9N3zGd.js",
45
+ "assets\\dialog-C07hr5_G.js",
45
46
  "assets\\dialog-actions-B1axpEg7.js",
46
- "assets\\dialog-k37exjNt.js",
47
47
  "assets\\download-dRFo5_Wu.js",
48
- "assets\\drawer-CX7N8ucR.js",
49
- "assets\\entry-B9Xvtnfj.js",
50
- "assets\\entry-ByMGkR3C.js",
51
- "assets\\entry-CTP8AyiS.js",
48
+ "assets\\drawer-BPO1TcKH.js",
49
+ "assets\\entry-Bz_CtDfC.js",
50
+ "assets\\entry-CwPRKk0d.js",
51
+ "assets\\entry-GJRbmrpA.js",
52
52
  "assets\\eye-C_hawfH4.js",
53
53
  "assets\\eye-off-Bk5g2luF.js",
54
54
  "assets\\gauge-BbIMy7MB.js",
55
- "assets\\github-badge-sltk1qUi.js",
55
+ "assets\\github-badge-DmQreSDd.js",
56
56
  "assets\\image-BPaouViG.js",
57
- "assets\\index-z3zDOSMM.js",
58
- "assets\\inline-BhY2sSnO.js",
59
- "assets\\input-V1umFiBk.js",
57
+ "assets\\index-Bblu6erR.js",
58
+ "assets\\inline-C9dCYaBZ.js",
59
+ "assets\\input-CjCnXweJ.js",
60
60
  "assets\\jsx-runtime-CXUMngI_.js",
61
61
  "assets\\key-round-UkavsGxp.js",
62
62
  "assets\\layers-2-glBbjl.js",
63
- "assets\\layout-BBOYycyS.js",
64
- "assets\\list-row-1zzZYM0B.js",
65
- "assets\\live-BivGfuUs.js",
63
+ "assets\\layout-V6y8DAkl.js",
64
+ "assets\\list-row-CM1AaG_y.js",
65
+ "assets\\live-ta6GMb-8.js",
66
66
  "assets\\log-in-BmRjy60c.js",
67
67
  "assets\\message-circle-CCxGwRvv.js",
68
- "assets\\model-bans-CmffjLuG.js",
69
- "assets\\mutation-46P0oWMe.js",
70
- "assets\\numbers-DkfMR5Qs.js",
68
+ "assets\\model-bans-BmYTmbAk.js",
69
+ "assets\\mutation-g_fduiNw.js",
70
+ "assets\\numbers-BOevJzdz.js",
71
71
  "assets\\pencil-768ysRAr.js",
72
72
  "assets\\plus-DIdX_g-x.js",
73
73
  "assets\\power-off-Yjw9GMJh.js",
@@ -89,21 +89,21 @@
89
89
  "assets\\providers\\parallel.svg",
90
90
  "assets\\providers\\tokenharbor.svg",
91
91
  "assets\\providers\\zai-coding-plan.svg",
92
- "assets\\query-keys-BFhGpwR1.js",
92
+ "assets\\query-keys-UETqfytp.js",
93
93
  "assets\\quota-DZGyp0N5.js",
94
94
  "assets\\refresh-cw-BqJFk4sU.js",
95
95
  "assets\\rotate-ccw-CufcqITi.js",
96
96
  "assets\\route-CNSNj9Zm.js",
97
- "assets\\routing-CAb4F37R.js",
97
+ "assets\\routing-BPUo-W8d.js",
98
98
  "assets\\scaling-nWE4Cx8f.js",
99
99
  "assets\\search-JOKus9rb.js",
100
- "assets\\select-C6MMiaio.js",
101
- "assets\\settings-DNX9sydi.js",
100
+ "assets\\select-C980c4cz.js",
101
+ "assets\\settings--3hxSyry.js",
102
102
  "assets\\shield-check-DVS0Foqh.js",
103
- "assets\\stack-BHTfXdz_.js",
104
- "assets\\state-mPDRlQkl.js",
103
+ "assets\\stack-_gfTdLVB.js",
104
+ "assets\\state-2c5V4zo7.js",
105
105
  "assets\\stream-retry-5QnVuSSo.js",
106
- "assets\\switch-DOmJxg7H.js",
106
+ "assets\\switch-Dkke7Naf.js",
107
107
  "assets\\terminal-0_IjPWTk.js",
108
108
  "assets\\tokens-COzario9.js",
109
109
  "assets\\trash-Cppn5c3R.js",
@@ -111,7 +111,7 @@
111
111
  "assets\\use-modal-focus-By7oJoGd.js",
112
112
  "assets\\use-reduced-motion-C4B0R6Sz.js",
113
113
  "assets\\use-timeout-BwcBBRrT.js",
114
- "assets\\useMutation-Dem0lXQj.js",
114
+ "assets\\useMutation-EDFRkn1i.js",
115
115
  "assets\\wrench-B6E1oEuY.js",
116
116
  "assets\\zap-C4EeVW4q.js",
117
117
  "index.html"
@@ -1,52 +1,52 @@
1
- # Database baselines
2
-
3
- Cartethyia keeps one SQL baseline per database backend:
4
-
5
- - `full-postgres/0000_baseline.sql` defines the foundational PostgreSQL schema
6
- for a new database.
7
- - `lite-sqlite3/0000_baseline.sql` is generated from the PostgreSQL baseline by
8
- `scripts/tools/generate-sqlite.ts`; do not edit it by hand.
9
-
10
- The startup runner applies the baseline and numbered forward migrations,
11
- recording them in `cartethyia_schema_migrations` along with a hash marker for
12
- the exact baseline contents. Released baselines are immutable so existing
13
- installations keep matching their marker; numbered migrations bring that
14
- foundational schema up to the current schema. Each backend's migrations must
15
- have matching behavior. Startup fails with a recovery instruction for a
16
- database with unsupported retired migration history instead of treating it as
17
- current.
18
-
19
- ## Recovering an existing installation
20
-
21
- 1. Export a backup from the existing installation before switching it to a
22
- release with unsupported migration history.
23
- 2. Create a fresh database and point the application at it.
24
- 3. Start the application so it creates the baseline schema.
25
- 4. Restore the backup through the console restore flow.
26
-
27
- Restore normalizes legacy values that no longer satisfy current constraints,
28
- including `bypass_proxy` → `skip_proxy`, `bridge` → `https`, the retired
29
- provider User-Agent default, Cline's skip-proxy default, and `fusion` →
30
- `fallback`. Unknown or retired columns are reported and skipped according to
31
- the backup contract.
32
-
33
- Do not point tests or recovery steps at development or production databases.
34
- The startup path runs `ensureMigrated()` before provider/catalog seeding. Full
35
- mode uses `src/persistence/db-pg.ts` and an advisory lock; Lite uses
36
- `src/persistence/db-sqlite.ts`. Readiness compares the ledger to the available baseline and forward migration
37
- files. A failed migration aborts startup and is not recorded.
38
-
39
- Migrations are package assets, not resolved from the process working directory:
40
- `src/config/package-paths.ts` resolves them from the package root. `package.json`
41
- includes `migrations/` in the published files, and the Dockerfile copies the
42
- migration directories into `/app/migrations`.
43
-
44
- ## Next schema change
45
-
46
- 1. Update `src/persistence/schema.ts` and add matching numbered migrations to
47
- both backends. Preserve released baseline files so existing baseline markers
48
- remain valid.
49
- 2. Update backup validation/mapping when old exported rows need normalization
50
- or new required values.
51
- 3. Run focused migration, restore, and typecheck tests. Validate against an
52
- isolated database only.
1
+ # Database baselines
2
+
3
+ Cartethyia keeps one SQL baseline per database backend:
4
+
5
+ - `full-postgres/0000_baseline.sql` defines the foundational PostgreSQL schema
6
+ for a new database.
7
+ - `lite-sqlite3/0000_baseline.sql` is generated from the PostgreSQL baseline by
8
+ `scripts/tools/generate-sqlite.ts`; do not edit it by hand.
9
+
10
+ The startup runner applies the baseline and numbered forward migrations,
11
+ recording them in `cartethyia_schema_migrations` along with a hash marker for
12
+ the exact baseline contents. Released baselines are immutable so existing
13
+ installations keep matching their marker; numbered migrations bring that
14
+ foundational schema up to the current schema. Each backend's migrations must
15
+ have matching behavior. Startup fails with a recovery instruction for a
16
+ database with unsupported retired migration history instead of treating it as
17
+ current.
18
+
19
+ ## Recovering an existing installation
20
+
21
+ 1. Export a backup from the existing installation before switching it to a
22
+ release with unsupported migration history.
23
+ 2. Create a fresh database and point the application at it.
24
+ 3. Start the application so it creates the baseline schema.
25
+ 4. Restore the backup through the console restore flow.
26
+
27
+ Restore normalizes legacy values that no longer satisfy current constraints,
28
+ including `bypass_proxy` → `skip_proxy`, `bridge` → `https`, the retired
29
+ provider User-Agent default, Cline's skip-proxy default, and `fusion` →
30
+ `fallback`. Unknown or retired columns are reported and skipped according to
31
+ the backup contract.
32
+
33
+ Do not point tests or recovery steps at development or production databases.
34
+ The startup path runs `ensureMigrated()` before provider/catalog seeding. Full
35
+ mode uses `src/persistence/db-pg.ts` and an advisory lock; Lite uses
36
+ `src/persistence/db-sqlite.ts`. Readiness compares the ledger to the available baseline and forward migration
37
+ files. A failed migration aborts startup and is not recorded.
38
+
39
+ Migrations are package assets, not resolved from the process working directory:
40
+ `src/config/package-paths.ts` resolves them from the package root. `package.json`
41
+ includes `migrations/` in the published files, and the Dockerfile copies the
42
+ migration directories into `/app/migrations`.
43
+
44
+ ## Next schema change
45
+
46
+ 1. Update `src/persistence/schema.ts` and add matching numbered migrations to
47
+ both backends. Preserve released baseline files so existing baseline markers
48
+ remain valid.
49
+ 2. Update backup validation/mapping when old exported rows need normalization
50
+ or new required values.
51
+ 3. Run focused migration, restore, and typecheck tests. Validate against an
52
+ isolated database only.
@@ -0,0 +1,77 @@
1
+ -- Telemetry analytics: the console's read-side cutover to `telemetry_events`.
2
+ --
3
+ -- The durable, indexed SQL store already receives every event; the console
4
+ -- reader ignored it and scanned the raw JSONL window instead (the regression
5
+ -- this fixes). These changes make the SQL store the canonical analytics
6
+ -- source:
7
+ --
8
+ -- - `client_name`: the canonical `clientNameFromUserAgent()` result, stamped
9
+ -- at ingestion so client breakdowns group in SQL instead of in JavaScript
10
+ -- over every row in the window.
11
+ -- - `UNIQUE (tenant_id, request_id)`: the cross-process idempotency boundary.
12
+ -- One terminal event per request; probes mint their own request UUIDs.
13
+ -- `INSERT ... ON CONFLICT DO NOTHING` makes a retried drain or a
14
+ -- cross-process race converge to one row and one usage charge.
15
+ -- - Keyset pagination index `(tenant_id, created_at DESC, id DESC)`: the
16
+ -- `(tenant_id, created_at)` index it replaces cannot break ties
17
+ -- deterministically (created_at is second-resolution), so a cursor on
18
+ -- created_at alone could skip or repeat rows at a boundary.
19
+ -- - Status and api-key breakdown indexes: the Usage chart and per-key family
20
+ -- spend filter on exactly these columns; without them each query scans the
21
+ -- tenant's whole retained window.
22
+ --
23
+ -- No dimension indexes beyond these without measured query plans. No
24
+ -- `CREATE INDEX CONCURRENTLY`: the transactional runner cannot run it, and
25
+ -- this migration runs at startup with no traffic to serve concurrently with.
26
+
27
+ ALTER TABLE "telemetry_events"
28
+ ADD COLUMN IF NOT EXISTS "client_name" text;
29
+
30
+ -- One terminal event per (tenant, request). Existing duplicates, if any,
31
+ -- cannot exist under the old writer (one row per request per tenant), but the
32
+ -- index creation is guarded defensively: a pre-existing violation would fail
33
+ -- startup loudly rather than silently double-charging.
34
+ --> statement-breakpoint
35
+ CREATE UNIQUE INDEX IF NOT EXISTS "telemetry_events_tenant_request_uidx"
36
+ ON "telemetry_events" ("tenant_id", "request_id");
37
+ --> statement-breakpoint
38
+ DROP INDEX IF EXISTS "telemetry_events_tenant_created_idx";
39
+ --> statement-breakpoint
40
+ CREATE INDEX IF NOT EXISTS "telemetry_events_tenant_created_id_idx"
41
+ ON "telemetry_events" ("tenant_id", "created_at" DESC, "id" DESC);
42
+ --> statement-breakpoint
43
+ CREATE INDEX IF NOT EXISTS "telemetry_events_tenant_http_created_id_idx"
44
+ ON "telemetry_events" ("tenant_id", "http_status", "created_at" DESC, "id" DESC);
45
+ --> statement-breakpoint
46
+ CREATE INDEX IF NOT EXISTS "telemetry_events_tenant_api_key_created_id_idx"
47
+ ON "telemetry_events" ("tenant_id", "api_key_id", "created_at" DESC, "id" DESC);
48
+ --> statement-breakpoint
49
+ CREATE TABLE IF NOT EXISTS "telemetry_reconciliation_state" (
50
+ "job_name" text PRIMARY KEY,
51
+ "lease_owner" text,
52
+ "lease_expires_at" timestamp with time zone,
53
+ "file_name" text NOT NULL DEFAULT '',
54
+ "byte_offset" bigint NOT NULL DEFAULT 0,
55
+ "files_completed" bigint DEFAULT 0,
56
+ "events_examined" bigint DEFAULT 0,
57
+ "events_inserted" bigint DEFAULT 0,
58
+ "conflicts" bigint DEFAULT 0,
59
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now(),
60
+ CONSTRAINT "telemetry_reconciliation_state_offset_nonneg" CHECK ("byte_offset" >= 0),
61
+ CONSTRAINT "telemetry_reconciliation_state_files_nonneg" CHECK ("files_completed" >= 0),
62
+ CONSTRAINT "telemetry_reconciliation_state_examined_nonneg" CHECK ("events_examined" >= 0),
63
+ CONSTRAINT "telemetry_reconciliation_state_inserted_nonneg" CHECK ("events_inserted" >= 0),
64
+ CONSTRAINT "telemetry_reconciliation_state_conflicts_nonneg" CHECK ("conflicts" >= 0)
65
+ );
66
+
67
+ --> statement-breakpoint
68
+ -- Align the payload storage CHECK with the schema: the `jsonb-file` binary
69
+ -- header shape was fully retired (nothing reads or writes it; the reader
70
+ -- treats anything that is not a base64-gzip line as not-a-frame). The
71
+ -- baseline's two-value constraint drifted from schema.ts's single-value
72
+ -- constraint at the initial release and is reconciled here.
73
+ ALTER TABLE "telemetry_payloads"
74
+ DROP CONSTRAINT IF EXISTS "telemetry_payloads_storage_check";
75
+ --> statement-breakpoint
76
+ ALTER TABLE "telemetry_payloads"
77
+ ADD CONSTRAINT "telemetry_payloads_storage_check" CHECK ("storage" = 'jsonl-file');
@@ -0,0 +1,13 @@
1
+ -- Slack above a key's concurrency limit.
2
+ --
3
+ -- `max_concurrent_requests` is the number an operator chose and the number a
4
+ -- refusal names. This is deliberate allowance above it: a run that lands a few
5
+ -- requests over is not refused at the number it was told. The effective ceiling
6
+ -- is `max_concurrent_requests + max_concurrent_tolerance`, and only requests
7
+ -- past that are refused — never ones already admitted.
8
+ --
9
+ -- Nullable on purpose: absent means "no allowance", which keeps the existing
10
+ -- behaviour for every key that has never seen this field. A default of 0 would
11
+ -- be indistinguishable from unset and would need its own "is this a deliberate
12
+ -- zero" question on every read.
13
+ ALTER TABLE api_keys ADD COLUMN max_concurrent_tolerance integer;
@@ -0,0 +1,17 @@
1
+ -- InferHub `config_read` key.
2
+ --
3
+ -- Stored on its own row rather than in `provider_accounts.auth_state`, because
4
+ -- `auth_state` is documented as the per-account non-secret upstream config and
5
+ -- travels with the account through backup/restore. This value is a credential,
6
+ -- so it lives here encrypted at rest and is reachable only through the InferHub
7
+ -- market routes.
8
+ --
9
+ -- One row for the whole deployment: the key is a single operator credential,
10
+ -- not a per-account one. `fingerprint` is a hash for change detection only —
11
+ -- it is never used to verify the key, and the plaintext is never returned.
12
+ CREATE TABLE IF NOT EXISTS inferhub_config_keys (
13
+ id text PRIMARY KEY,
14
+ ciphertext bytea NOT NULL,
15
+ fingerprint text NOT NULL,
16
+ updated_at timestamptz NOT NULL DEFAULT now()
17
+ );
@@ -0,0 +1,13 @@
1
+ -- Concurrency slack is tenant-wide now, so the per-key column goes away.
2
+ --
3
+ -- The two used to stack: a key's own `max_concurrent_tolerance` won, and the
4
+ -- tenant's `concurrencyTolerance` was only the answer for a key that had never
5
+ -- been given one. One number in two places meant an operator setting the
6
+ -- tenant-wide value could not tell why one key still refused early — the
7
+ -- override was invisible from the Settings page that appears to own the number.
8
+ --
9
+ -- Dropped rather than left behind: a column nothing reads is still one an
10
+ -- operator finds in a backup or a query and trusts. Keys that had an override
11
+ -- now fall back to the tenant value, which is the behaviour every other key
12
+ -- already had.
13
+ ALTER TABLE api_keys DROP COLUMN max_concurrent_tolerance;
@@ -0,0 +1,69 @@
1
+ -- Adds telemetry analytics (Lite / SQLite) — see the identically named
2
+ -- PostgreSQL migration for why. Both backends must apply the same behavior;
3
+ -- SQLite stores `uuid` as text and `timestamptz` as text.
4
+ --
5
+ -- Idempotency comes from the migration ledger, not from the statement: the
6
+ -- runner records the file inside the same transaction, so a file that has
7
+ -- already run is never re-executed. The baseline is generated from
8
+ -- `0000_baseline.sql` alone and does not carry these changes.
9
+ --
10
+ -- NOTE: the runner already wraps each migration in a transaction, so this file
11
+ -- must NOT issue BEGIN/COMMIT.
12
+ ALTER TABLE "telemetry_events" ADD COLUMN "client_name" text;
13
+ --> statement-breakpoint
14
+ -- One terminal event per (tenant, request): the cross-process idempotency
15
+ -- boundary. SQLite has no "IF NOT EXISTS" for indexes; the migration ledger
16
+ -- guarantees single execution.
17
+ CREATE UNIQUE INDEX "telemetry_events_tenant_request_uidx" ON "telemetry_events" ("tenant_id", "request_id");
18
+ --> statement-breakpoint
19
+ DROP INDEX "telemetry_events_tenant_created_idx";
20
+ --> statement-breakpoint
21
+ -- Keyset pagination: (created_at, id) DESC breaks ties deterministically.
22
+ CREATE INDEX "telemetry_events_tenant_created_id_idx" ON "telemetry_events" ("tenant_id", "created_at" DESC, "id" DESC);
23
+ --> statement-breakpoint
24
+ CREATE INDEX "telemetry_events_tenant_http_created_id_idx" ON "telemetry_events" ("tenant_id", "http_status", "created_at" DESC, "id" DESC);
25
+ --> statement-breakpoint
26
+ CREATE INDEX "telemetry_events_tenant_api_key_created_id_idx" ON "telemetry_events" ("tenant_id", "api_key_id", "created_at" DESC, "id" DESC);
27
+ --> statement-breakpoint
28
+ CREATE TABLE "telemetry_reconciliation_state" (
29
+ "job_name" text PRIMARY KEY,
30
+ "lease_owner" text,
31
+ "lease_expires_at" text,
32
+ "file_name" text NOT NULL DEFAULT '',
33
+ "byte_offset" integer NOT NULL DEFAULT 0,
34
+ "files_completed" integer DEFAULT 0,
35
+ "events_examined" integer DEFAULT 0,
36
+ "events_inserted" integer DEFAULT 0,
37
+ "conflicts" integer DEFAULT 0,
38
+ "updated_at" text NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
39
+ CONSTRAINT "telemetry_reconciliation_state_offset_nonneg" CHECK ("byte_offset" >= 0),
40
+ CONSTRAINT "telemetry_reconciliation_state_files_nonneg" CHECK ("files_completed" >= 0),
41
+ CONSTRAINT "telemetry_reconciliation_state_examined_nonneg" CHECK ("events_examined" >= 0),
42
+ CONSTRAINT "telemetry_reconciliation_state_inserted_nonneg" CHECK ("events_inserted" >= 0),
43
+ CONSTRAINT "telemetry_reconciliation_state_conflicts_nonneg" CHECK ("conflicts" >= 0)
44
+ );
45
+
46
+ --> statement-breakpoint
47
+ -- Align the payload storage CHECK with the schema (jsonb-file retired). A
48
+ -- table's CHECK cannot be altered in place in SQLite: rebuild and copy.
49
+ CREATE TABLE "telemetry_payloads_new" (
50
+ "id" text PRIMARY KEY NOT NULL,
51
+ "tenant_id" text NOT NULL,
52
+ "request_id" text,
53
+ "captured_at" text NOT NULL,
54
+ "expires_at" text NOT NULL,
55
+ "storage" text NOT NULL,
56
+ "file" text NOT NULL,
57
+ "offset" integer NOT NULL,
58
+ "length" integer NOT NULL,
59
+ "checksum" text NOT NULL,
60
+ "version" integer NOT NULL,
61
+ "stages" integer DEFAULT 0,
62
+ CONSTRAINT "telemetry_payloads_storage_check" CHECK ("storage" = 'jsonl-file')
63
+ );
64
+ --> statement-breakpoint
65
+ INSERT INTO "telemetry_payloads_new" SELECT "id", "tenant_id", "request_id", "captured_at", "expires_at", "storage", "file", "offset", "length", "checksum", "version", "stages" FROM "telemetry_payloads";
66
+ --> statement-breakpoint
67
+ DROP TABLE "telemetry_payloads";
68
+ --> statement-breakpoint
69
+ ALTER TABLE "telemetry_payloads_new" RENAME TO "telemetry_payloads";
@@ -0,0 +1,13 @@
1
+ -- Slack above a key's concurrency limit.
2
+ --
3
+ -- `max_concurrent_requests` is the number an operator chose and the number a
4
+ -- refusal names. This is deliberate allowance above it: a run that lands a few
5
+ -- requests over is not refused at the number it was told. The effective ceiling
6
+ -- is `max_concurrent_requests + max_concurrent_tolerance`, and only requests
7
+ -- past that are refused — never ones already admitted.
8
+ --
9
+ -- Nullable on purpose: absent means "no allowance", which keeps the existing
10
+ -- behaviour for every key that has never seen this field. A default of 0 would
11
+ -- be indistinguishable from unset and would need its own "is this a deliberate
12
+ -- zero" question on every read.
13
+ ALTER TABLE api_keys ADD COLUMN max_concurrent_tolerance integer;
@@ -0,0 +1,17 @@
1
+ -- InferHub `config_read` key.
2
+ --
3
+ -- Stored on its own row rather than in `provider_accounts.auth_state`, because
4
+ -- `auth_state` is documented as the per-account non-secret upstream config and
5
+ -- travels with the account through backup/restore. This value is a credential,
6
+ -- so it lives here encrypted at rest and is reachable only through the InferHub
7
+ -- market routes.
8
+ --
9
+ -- One row for the whole deployment: the key is a single operator credential,
10
+ -- not a per-account one. `fingerprint` is a hash for change detection only —
11
+ -- it is never used to verify the key, and the plaintext is never returned.
12
+ CREATE TABLE IF NOT EXISTS inferhub_config_keys (
13
+ id text PRIMARY KEY,
14
+ ciphertext blob NOT NULL,
15
+ fingerprint text NOT NULL,
16
+ updated_at text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) NOT NULL
17
+ );
@@ -0,0 +1,13 @@
1
+ -- Concurrency slack is tenant-wide now, so the per-key column goes away.
2
+ --
3
+ -- The two used to stack: a key's own `max_concurrent_tolerance` won, and the
4
+ -- tenant's `concurrencyTolerance` was only the answer for a key that had never
5
+ -- been given one. One number in two places meant an operator setting the
6
+ -- tenant-wide value could not tell why one key still refused early — the
7
+ -- override was invisible from the Settings page that appears to own the number.
8
+ --
9
+ -- Dropped rather than left behind: a column nothing reads is still one an
10
+ -- operator finds in a backup or a query and trusts. Keys that had an override
11
+ -- now fall back to the tenant value, which is the behaviour every other key
12
+ -- already had.
13
+ ALTER TABLE api_keys DROP COLUMN max_concurrent_tolerance;