cartethyia 2.7.3 → 2.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (625) hide show
  1. package/.env.example +2 -0
  2. package/README.md +17 -5
  3. package/dist/dashboard/assets/{BannedPage-2TJD37Hb.js → BannedPage-Cj15GsMp.js} +1 -1
  4. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
  5. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +1 -0
  6. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolDetailPage-xefJNRmJ.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
  8. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
  9. package/dist/dashboard/assets/{CliToolsPage-Rj9iHQ3F.js → CliToolsPage-BIccZmeL.js} +1 -1
  10. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
  11. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +1 -0
  12. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
  13. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js +1 -0
  14. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
  15. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js +1 -0
  16. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js +656 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
  19. package/dist/dashboard/assets/{LoginPage-C4w7vea-.js → LoginPage-DkXb6dx-.js} +1 -1
  20. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BtPcAfot.js → ModelPicker-DnQPSIA8.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
  31. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js +9 -0
  32. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
  37. package/dist/dashboard/assets/{SetupPage-BQS0Rx_u.js → SetupPage-WTa0sktC.js} +1 -1
  38. package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-TP7voAQ0.js → StudioPage-BfAb5-o_.js} +3 -3
  40. package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
  41. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js +56 -0
  42. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
  43. package/dist/dashboard/assets/api-keys-l29JROPv.js +1 -0
  44. package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
  45. package/dist/dashboard/assets/app--PJWq8_C.css +2 -0
  46. package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-C0YYuZJ4.js → assert-C0K-c4eo.js} +1 -1
  48. package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-B_DMpMJN.js → badge-DfbhQU4k.js} +1 -1
  50. package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-DMrMPmth.js → banner-BllT4LcF.js} +1 -1
  52. package/dist/dashboard/assets/banner-BllT4LcF.js.gz +0 -0
  53. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  54. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  55. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  56. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  57. package/dist/dashboard/assets/{card-Be5Uzamx.js → card-CtkX66Wd.js} +1 -1
  58. package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
  59. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  60. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  61. package/dist/dashboard/assets/{cli-tools-muFRphDu.js → cli-tools-CQXVMn4P.js} +1 -1
  62. package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
  63. package/dist/dashboard/assets/{clipboard-button-DOfrVmsi.js → clipboard-button-BQqBQd2n.js} +1 -1
  64. package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
  65. package/dist/dashboard/assets/{dialog-C9omdjQt.js → dialog-BEK7KP0H.js} +1 -1
  66. package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
  67. package/dist/dashboard/assets/{drawer-Bm8WKaGY.js → drawer-BrTEZ8zu.js} +1 -1
  68. package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
  69. package/dist/dashboard/assets/entry-CHWxbS56.js +1 -0
  70. package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
  71. package/dist/dashboard/assets/{entry-q5HwZ8nN.js → entry-EBHJ3DrE.js} +1 -1
  72. package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
  73. package/dist/dashboard/assets/entry-LCS85hiq.js +4 -0
  74. package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
  75. package/dist/dashboard/assets/{formatters-BTScrQpe.js → formatters-BAACA727.js} +1 -1
  76. package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
  77. package/dist/dashboard/assets/{github-badge-Orjuzemr.js → github-badge-YSCE4UC2.js} +1 -1
  78. package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
  79. package/dist/dashboard/assets/{index-cPrX5vn6.js → index-FQlj0HUT.js} +2 -2
  80. package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
  81. package/dist/dashboard/assets/{inline-Dvux8w-0.js → inline-C4gU5iOL.js} +1 -1
  82. package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
  83. package/dist/dashboard/assets/{input-CU1Rgf3p.js → input-BHHX_Tmm.js} +1 -1
  84. package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
  85. package/dist/dashboard/assets/{layout-C_7A6H55.js → layout-CajrYUnD.js} +1 -1
  86. package/dist/dashboard/assets/{layout-C_7A6H55.js.gz → layout-CajrYUnD.js.gz} +0 -0
  87. package/dist/dashboard/assets/{list-row-CzFvogbj.js → list-row-Bx2I7XUe.js} +1 -1
  88. package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
  89. package/dist/dashboard/assets/live-DNNqRbj2.js +1 -0
  90. package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
  91. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +1 -0
  92. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
  93. package/dist/dashboard/assets/{mutation-JJGQm8TD.js → mutation-Rr0TIvcj.js} +1 -1
  94. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  95. package/dist/dashboard/assets/network-C5UBACrJ.js +1 -0
  96. package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
  97. package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
  98. package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
  99. package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
  100. package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
  101. package/dist/dashboard/assets/{query-keys-CLaNz8Xz.js → query-keys-BloKtaXJ.js} +1 -1
  102. package/dist/dashboard/assets/query-keys-BloKtaXJ.js.gz +0 -0
  103. package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
  104. package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
  105. package/dist/dashboard/assets/{routing-BEH32QOC.js → routing-in0f_IfK.js} +1 -1
  106. package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
  107. package/dist/dashboard/assets/{select-B3iTetHN.js → select-BLULNqTp.js} +2 -2
  108. package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
  109. package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
  110. package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
  111. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  112. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  113. package/dist/dashboard/assets/{stack-KrOrm7JZ.js → stack-D2lIR0tg.js} +1 -1
  114. package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
  115. package/dist/dashboard/assets/{state-DLS7IDMy.js → state-DTARjfiW.js} +1 -1
  116. package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
  117. package/dist/dashboard/assets/{switch-42ItvbAs.js → switch-c0oPSnqW.js} +1 -1
  118. package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
  119. package/dist/dashboard/assets/{useMutation-Dmnfh1Ue.js → useMutation-m8WGNPrz.js} +1 -1
  120. package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
  121. package/dist/dashboard/console-backgrounds.jpg +0 -0
  122. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  123. package/dist/dashboard/index.html +2 -2
  124. package/dist/dashboard/index.html.gz +0 -0
  125. package/dist/dashboard/precompressed-assets.json +59 -57
  126. package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +9 -10
  127. package/migrations/full-postgres/0032_add_provider_pool_accounts.sql +53 -0
  128. package/migrations/full-postgres/0033_add_api_key_ban.sql +9 -0
  129. package/migrations/full-postgres/0034_add_api_key_ban_until.sql +7 -0
  130. package/migrations/full-postgres/0035_align_pool_account_status_enum.sql +21 -0
  131. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  132. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  133. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  134. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  135. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  136. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  137. package/migrations/lite-sqlite3/0027_qoder_identity_genuine_seed.sql +9 -10
  138. package/migrations/lite-sqlite3/0032_add_provider_pool_accounts.sql +44 -0
  139. package/migrations/lite-sqlite3/0033_add_api_key_ban.sql +8 -0
  140. package/migrations/lite-sqlite3/0034_add_api_key_ban_until.sql +5 -0
  141. package/migrations/lite-sqlite3/0035_align_pool_account_status_enum.sql +6 -0
  142. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  143. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  144. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  145. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  146. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  147. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  148. package/package.json +4 -5
  149. package/scripts/cli/update.ts +15 -41
  150. package/src/boot/app.ts +67 -10
  151. package/src/boot/dependencies.ts +786 -732
  152. package/src/boot/lifecycle.ts +11 -12
  153. package/src/config/cooldowns.ts +34 -55
  154. package/src/config/network.ts +8 -4
  155. package/src/config/package-paths.ts +1 -1
  156. package/src/config/providers.ts +13 -14
  157. package/src/config/resources.ts +0 -5
  158. package/src/config/runtime.ts +2 -5
  159. package/src/config/spec.ts +26 -6
  160. package/src/console/api-keys/ban-constants.ts +38 -0
  161. package/src/console/api-keys/contracts.ts +92 -31
  162. package/src/console/api-keys/routes.ts +131 -6
  163. package/src/console/audit/routes.ts +3 -3
  164. package/src/console/auth/access.ts +4 -4
  165. package/src/console/auth/account-reset.ts +5 -5
  166. package/src/console/auth/audit-recorder.ts +1 -1
  167. package/src/console/auth/lockout.ts +7 -3
  168. package/src/console/auth/row-coercion.ts +57 -12
  169. package/src/console/auth/session-resolver.ts +1 -1
  170. package/src/console/auth/session-service.ts +8 -2
  171. package/src/console/auth/session.ts +40 -34
  172. package/src/console/auth/setup-service.ts +4 -3
  173. package/src/console/auth/user-store.ts +1 -1
  174. package/src/console/backup/9router-map.ts +0 -3
  175. package/src/console/backup/contracts.ts +11 -9
  176. package/src/console/backup/export-endpoint.ts +11 -12
  177. package/src/console/backup/nine-router.ts +1 -7
  178. package/src/console/backup/routes.ts +32 -36
  179. package/src/console/backup/service.ts +468 -468
  180. package/src/console/backup/store.ts +47 -29
  181. package/src/console/backup/validate.ts +11 -1
  182. package/src/console/cli-tools/contracts.ts +7 -7
  183. package/src/console/cli-tools/injectors/cline.ts +110 -110
  184. package/src/console/cli-tools/injectors/codex.ts +181 -181
  185. package/src/console/cli-tools/injectors/copilot.ts +108 -108
  186. package/src/console/cli-tools/injectors/driver.ts +247 -247
  187. package/src/console/cli-tools/injectors/jcode.ts +115 -115
  188. package/src/console/cli-tools/injectors/openclaw.ts +161 -161
  189. package/src/console/cli-tools/injectors/opencode.ts +153 -153
  190. package/src/console/cli-tools/routes.ts +4 -4
  191. package/src/console/cli-tools/service.ts +1 -1
  192. package/src/console/cli-tools/store.ts +2 -2
  193. package/src/console/console-router-guards.ts +2 -2
  194. package/src/console/console-router.ts +36 -4
  195. package/src/console/dashboard-assets.ts +9 -9
  196. package/src/console/data-management/routes.ts +3 -3
  197. package/src/console/domain-registration.ts +18 -4
  198. package/src/console/inferhub/client.ts +0 -7
  199. package/src/console/inferhub/key-store.ts +1 -1
  200. package/src/console/inferhub/normalize.ts +2 -2
  201. package/src/console/inferhub/routes.ts +1 -1
  202. package/src/console/inferhub/types.ts +1 -1
  203. package/src/console/observability/contracts.ts +5 -1
  204. package/src/console/observability/live.ts +34 -21
  205. package/src/console/observability/logs.ts +4 -4
  206. package/src/console/observability/performance.ts +3 -3
  207. package/src/console/observability/routes.ts +3 -3
  208. package/src/console/observability/sse.ts +62 -8
  209. package/src/console/observability/store.ts +36 -20
  210. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  211. package/src/console/providers/catalog/contracts.ts +82 -22
  212. package/src/console/providers/catalog/model-operations.ts +1 -1
  213. package/src/console/providers/catalog/provider-operations.ts +110 -17
  214. package/src/console/providers/catalog/public-model-store.ts +0 -0
  215. package/src/console/providers/catalog/routes.ts +30 -6
  216. package/src/console/providers/catalog/store-helpers.ts +349 -326
  217. package/src/console/providers/catalog/store.ts +1662 -1292
  218. package/src/console/providers/detail/routes.ts +4 -4
  219. package/src/console/providers/oauth/callback-listener.ts +100 -18
  220. package/src/console/providers/oauth/routes.ts +95 -16
  221. package/src/console/quota/account-quota-global.ts +41 -3
  222. package/src/console/quota/account-quota-shared.ts +10 -3
  223. package/src/console/quota/account-quota-tenant.ts +285 -67
  224. package/src/console/quota/account-test-egress.ts +4 -4
  225. package/src/console/quota/daily-growth-job.ts +308 -0
  226. package/src/console/quota/native-identity.ts +2 -2
  227. package/src/console/quota/quota-view.ts +1 -1
  228. package/src/console/remote-support/routes.ts +1 -1
  229. package/src/console/remote-support/service.ts +2 -2
  230. package/src/console/routing/model/contracts.ts +1 -1
  231. package/src/console/routing/model/routes.ts +3 -3
  232. package/src/console/routing/pools/contracts.ts +13 -10
  233. package/src/console/routing/pools/import-parse.ts +3 -3
  234. package/src/console/routing/pools/operations.ts +14 -7
  235. package/src/console/routing/pools/probe-verdict.ts +8 -3
  236. package/src/console/routing/pools/relay-deploy.ts +12 -12
  237. package/src/console/routing/pools/routes.ts +3 -3
  238. package/src/console/routing/pools/store.ts +21 -1
  239. package/src/console/settings/contracts.ts +29 -2
  240. package/src/console/settings/routes.ts +3 -3
  241. package/src/console/settings/store.ts +20 -0
  242. package/src/console/share/share-router.ts +112 -44
  243. package/src/console/share/share-stats.ts +109 -39
  244. package/src/console/share/share-usage.ts +1 -1
  245. package/src/console/shared/errors.ts +2 -2
  246. package/src/console/shared/object.ts +18 -0
  247. package/src/console/shared/read-through-cache.ts +42 -6
  248. package/src/console/shared/transaction.ts +14 -0
  249. package/src/console/system-prompt/contracts.ts +89 -12
  250. package/src/console/system-prompt/routes.ts +98 -45
  251. package/src/console/updates/apply-update.ts +244 -0
  252. package/src/console/updates/routes.ts +256 -98
  253. package/src/main.ts +11 -5
  254. package/src/network/http2-bidi.ts +1 -1
  255. package/src/network/ip-utils.ts +298 -0
  256. package/src/network/outbound-fetch.ts +76 -5
  257. package/src/network/pool/agent.ts +7 -6
  258. package/src/network/pool/byte-accounting.ts +1 -1
  259. package/src/network/pool/resolver.ts +55 -51
  260. package/src/network/pool/selector.ts +150 -136
  261. package/src/network/pool-cooldown-store.ts +71 -16
  262. package/src/network/pool-health-machine.ts +22 -2
  263. package/src/network/rate-limit-verdict.ts +68 -0
  264. package/src/network/retry.ts +1 -1
  265. package/src/network/ssrf.ts +24 -75
  266. package/src/observability/event-log.ts +2 -2
  267. package/src/observability/event-query.ts +286 -214
  268. package/src/observability/log-sanitize.ts +1 -1
  269. package/src/observability/metrics.ts +4 -4
  270. package/src/observability/payload-capture.ts +6 -5
  271. package/src/observability/payload-store.ts +1 -1
  272. package/src/observability/runtime-metrics.ts +1 -1
  273. package/src/observability/telemetry-buffer.ts +12 -3
  274. package/src/observability/telemetry-reconciliation.ts +3 -3
  275. package/src/observability/telemetry-status.ts +1 -1
  276. package/src/observability/token-speed.ts +1 -1
  277. package/src/persistence/connection-url.ts +1 -1
  278. package/src/persistence/db-handle.ts +1 -1
  279. package/src/persistence/db-pg.ts +2 -2
  280. package/src/persistence/db-sqlite.ts +10 -5
  281. package/src/persistence/dialect.ts +5 -1
  282. package/src/persistence/readiness.ts +19 -7
  283. package/src/persistence/redis.ts +1 -1
  284. package/src/persistence/schema.ts +177 -45
  285. package/src/persistence/shared-cache.ts +2 -2
  286. package/src/persistence/sort-order.ts +1 -1
  287. package/src/persistence/stores/api-key-store.ts +109 -4
  288. package/src/persistence/stores/share-store.ts +20 -8
  289. package/src/persistence/stores/telemetry-store.ts +1 -1
  290. package/src/persistence/system-prompt-store.ts +63 -18
  291. package/src/persistence/tenant-preferences.ts +1 -1
  292. package/src/persistence/ttl-cache.ts +3 -3
  293. package/src/persistence/usage-flush.ts +7 -2
  294. package/src/protocol/canonical-model.ts +1 -1
  295. package/src/protocol/codecs.ts +12 -16
  296. package/src/protocol/dsml.ts +3 -49
  297. package/src/protocol/gateway-error.ts +6 -3
  298. package/src/protocol/image-clamp.ts +2 -2
  299. package/src/protocol/image-generation.ts +2 -2
  300. package/src/protocol/reasoning-text.ts +1 -1
  301. package/src/protocol/reasoning.ts +7 -52
  302. package/src/protocol/registry.ts +50 -15
  303. package/src/protocol/request/chat.ts +46 -19
  304. package/src/protocol/request/codex.ts +1 -1
  305. package/src/protocol/request/messages.ts +46 -14
  306. package/src/protocol/request/responses.ts +19 -10
  307. package/src/protocol/response/chat.ts +27 -12
  308. package/src/protocol/response/codex.ts +2 -2
  309. package/src/protocol/response/gemini.ts +1 -1
  310. package/src/protocol/response/messages.ts +6 -6
  311. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  312. package/src/protocol/response/responses.ts +3 -3
  313. package/src/protocol/sse-decoder.ts +64 -4
  314. package/src/protocol/stop-reason.ts +2 -2
  315. package/src/protocol/think-split.ts +347 -0
  316. package/src/protocol/translation/attachment-integrity.ts +3 -3
  317. package/src/protocol/translation/cache-controls.ts +8 -20
  318. package/src/protocol/translation/capabilities.ts +8 -8
  319. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  320. package/src/protocol/translation/dialect/inband.ts +39 -0
  321. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  322. package/src/protocol/translation/dialect/qwen.ts +114 -0
  323. package/src/protocol/translation/dialect/resolver.ts +83 -0
  324. package/src/protocol/translation/dialect/rules.ts +93 -0
  325. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  326. package/src/protocol/translation/dialect/types.ts +58 -0
  327. package/src/protocol/translation/quirks.ts +18 -4
  328. package/src/protocol/translation/thinking.ts +12 -252
  329. package/src/protocol/translation/tool-id.ts +3 -3
  330. package/src/protocol/translation/tool-repair.ts +1 -1
  331. package/src/protocol/upstream/post-json.ts +6 -1
  332. package/src/protocol/upstream/send-claude-messages.ts +3 -3
  333. package/src/providers/adapters/base-adapter.ts +1 -1
  334. package/src/providers/adapters/compatible-adapter.ts +44 -5
  335. package/src/providers/authentication/jwt-validator.ts +0 -5
  336. package/src/providers/authentication/oauth-client.ts +254 -253
  337. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  338. package/src/providers/authentication/oauth-refresh-service.ts +2 -2
  339. package/src/providers/bundled-discovery-providers.ts +6 -30
  340. package/src/providers/configured-openai-providers.ts +82 -97
  341. package/src/providers/configured-provider.ts +1 -1
  342. package/src/providers/default-registry.ts +23 -35
  343. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  344. package/src/providers/discovery/discovery-types.ts +0 -1
  345. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  346. package/src/providers/discovery/probe-phases.ts +50 -15
  347. package/src/providers/discovery/probing-service.ts +18 -20
  348. package/src/providers/integrations/agentrouter/agentrouter.ts +14 -5
  349. package/src/providers/integrations/alibabacp/alibabacp.ts +2 -2
  350. package/src/providers/integrations/anthropic.ts +4 -11
  351. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  352. package/src/providers/integrations/antigravity/antigravity-protocol.ts +0 -14
  353. package/src/providers/integrations/antigravity/antigravity.ts +15 -26
  354. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +2 -2
  355. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  356. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  357. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +37 -6
  358. package/src/providers/integrations/buddy/buddy-identity.ts +108 -1
  359. package/src/providers/integrations/buddy/buddy-media.ts +16 -16
  360. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  361. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  362. package/src/providers/integrations/buddy/codebuddy/provider.ts +5 -16
  363. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  364. package/src/providers/integrations/buddy/workbuddy/provider.ts +6 -10
  365. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  366. package/src/providers/integrations/claude/claude-betas.ts +1 -1
  367. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  368. package/src/providers/integrations/claude/claude-credentials.ts +1 -1
  369. package/src/providers/integrations/claude/claude-slow-lane-retry.ts +1 -1
  370. package/src/providers/integrations/claude/claude.ts +3 -10
  371. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  372. package/src/providers/integrations/cline/cline.ts +2 -2
  373. package/src/providers/integrations/cloudflareai/cloudflareai.ts +4 -7
  374. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  375. package/src/providers/integrations/codex/codex-errors.ts +1 -1
  376. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  377. package/src/providers/integrations/codex/codex.ts +14 -15
  378. package/src/providers/integrations/commandcode/commandcode.ts +76 -116
  379. package/src/providers/integrations/commandcode/quota.ts +132 -48
  380. package/src/providers/integrations/cursor/cursor-http2.ts +11 -14
  381. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  382. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  383. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  384. package/src/providers/integrations/cursor/cursor.ts +53 -20
  385. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  386. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  387. package/src/providers/integrations/factory/factory.ts +13 -13
  388. package/src/providers/integrations/gemini.ts +11 -11
  389. package/src/providers/integrations/github/github-discovery.ts +55 -10
  390. package/src/providers/integrations/github/github-oauth.ts +6 -5
  391. package/src/providers/integrations/github/github.ts +47 -20
  392. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  393. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  394. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  395. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  396. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  397. package/src/providers/integrations/grok/grok.ts +88 -42
  398. package/src/providers/integrations/inferhub.ts +4 -11
  399. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  400. package/src/providers/integrations/kimi/kimi.ts +4 -11
  401. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  402. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  403. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  404. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  405. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  406. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  407. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  408. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  409. package/src/providers/integrations/kiro/kiro.ts +91 -78
  410. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  411. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  412. package/src/providers/integrations/muse/muse.ts +6 -9
  413. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  414. package/src/providers/integrations/opencode/provider.ts +17 -24
  415. package/src/providers/integrations/perplexity.ts +2 -2
  416. package/src/providers/integrations/qoder/qoder-catalog.ts +132 -17
  417. package/src/providers/integrations/qoder/qoder-checkin.ts +26 -8
  418. package/src/providers/integrations/qoder/qoder-native-identity-store.ts +9 -8
  419. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  420. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  421. package/src/providers/integrations/qoder/qoder-realm.ts +22 -28
  422. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  423. package/src/providers/integrations/qoder/qoder-umid.ts +33 -38
  424. package/src/providers/integrations/qoder/qoder-virtual.ts +14 -2
  425. package/src/providers/integrations/qoder/qoder.ts +521 -63
  426. package/src/providers/integrations/shared/connect.ts +0 -54
  427. package/src/providers/integrations/shared/hash.ts +15 -0
  428. package/src/providers/integrations/shared/session-cache.ts +136 -0
  429. package/src/providers/integrations/tokenharbor.ts +2 -2
  430. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  431. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  432. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  433. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  434. package/src/providers/integrations/trae/trae.ts +59 -19
  435. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  436. package/src/providers/integrations/zcode/oauth.ts +1 -1
  437. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  438. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  439. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  440. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  441. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  442. package/src/providers/operations/account-error-classification.ts +131 -116
  443. package/src/providers/operations/account-health-service.ts +31 -39
  444. package/src/providers/operations/account-reset-service.ts +58 -1
  445. package/src/providers/operations/cli-platform.ts +31 -5
  446. package/src/providers/operations/client-version-resolver.ts +4 -6
  447. package/src/providers/operations/client-versions.ts +10 -7
  448. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  449. package/src/providers/operations/provider-catalog-service.ts +22 -6
  450. package/src/providers/operations/provider-credential-service.ts +35 -6
  451. package/src/providers/operations/upstream-deadline.ts +3 -3
  452. package/src/providers/provider-contracts.ts +65 -10
  453. package/src/providers/provider-credential-resolver.ts +1 -1
  454. package/src/providers/provider-metadata.ts +17 -2
  455. package/src/providers/provider-model-definition.ts +22 -1
  456. package/src/providers/provider-probe.ts +4 -2
  457. package/src/providers/provider-registry.ts +4 -4
  458. package/src/providers/provider-usage.ts +81 -16
  459. package/src/providers/quota/cache.ts +29 -0
  460. package/src/providers/quota/quota-contracts.ts +28 -10
  461. package/src/providers/quota/refresh.ts +29 -6
  462. package/src/providers/quota/snapshot.ts +94 -0
  463. package/src/providers/search/search-provider.ts +6 -8
  464. package/src/providers/search/search-providers.ts +2 -1
  465. package/src/security/abuse.ts +8 -8
  466. package/src/security/admission/reasons.ts +17 -17
  467. package/src/security/admission/service.ts +2 -2
  468. package/src/security/admission/ttl.ts +61 -61
  469. package/src/security/api-key-auth.ts +20 -8
  470. package/src/security/client-router-fingerprint.ts +4 -4
  471. package/src/security/credential-codec.ts +3 -3
  472. package/src/security/csrf.ts +2 -2
  473. package/src/security/ip-boundary.ts +16 -189
  474. package/src/security/model-access-rule.ts +1 -1
  475. package/src/security/outbound-headers.ts +18 -0
  476. package/src/shared/coerce.ts +19 -0
  477. package/src/shared/invoke-guard.ts +47 -0
  478. package/src/transport/contracts.ts +13 -4
  479. package/src/transport/dispatch/attempt-finalize.ts +5 -4
  480. package/src/transport/dispatch/attempt-loop.ts +10 -7
  481. package/src/transport/dispatch/capture-policy.ts +34 -37
  482. package/src/transport/dispatch/empty-stream.ts +28 -25
  483. package/src/transport/dispatch/generation.ts +33 -53
  484. package/src/transport/dispatch/leases.ts +8 -8
  485. package/src/transport/dispatch/native-shared.ts +127 -0
  486. package/src/transport/dispatch/proxy-request.ts +10 -8
  487. package/src/transport/dispatch/responses-compact.ts +35 -56
  488. package/src/transport/dispatch/retry-policy.ts +4 -67
  489. package/src/transport/dispatch/stream-bridge.ts +1 -1
  490. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  491. package/src/transport/dispatch/streaming/finalize.ts +11 -10
  492. package/src/transport/dispatch/streaming/stream.ts +7 -3
  493. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  494. package/src/transport/dispatch/systemone.ts +27 -55
  495. package/src/transport/dispatch/token-count.ts +49 -46
  496. package/src/transport/dispatch/websearch.ts +24 -50
  497. package/src/transport/drain-endpoint.ts +3 -3
  498. package/src/transport/failure-policy.ts +19 -6
  499. package/src/transport/guards/auth-guard.ts +6 -11
  500. package/src/transport/guards/body-policy.ts +7 -7
  501. package/src/transport/guards/error-lifecycle.ts +18 -3
  502. package/src/transport/guards/guard-errors.ts +7 -3
  503. package/src/transport/guards/headroom-guard.ts +2 -2
  504. package/src/transport/guards/pipeline.ts +7 -7
  505. package/src/transport/guards/readiness-guard.ts +16 -2
  506. package/src/transport/guards/request-context.ts +15 -20
  507. package/src/transport/request/preparer.ts +306 -27
  508. package/src/transport/request/rtk/compress-request.ts +3 -3
  509. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  510. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  511. package/src/transport/request/state.ts +5 -20
  512. package/src/transport/request/system-prompt-injection.ts +74 -11
  513. package/src/transport/request/tenant-preferences.ts +22 -0
  514. package/src/transport/routing/candidate-index.ts +2 -2
  515. package/src/transport/routing/round-robin.ts +1 -1
  516. package/src/transport/routing/route-catalog.ts +113 -19
  517. package/src/transport/routing/route-model.ts +131 -38
  518. package/src/transport/routing/router.ts +154 -39
  519. package/src/transport/shutdown-notice.ts +21 -9
  520. package/src/transport/surface/adapters.ts +3 -3
  521. package/src/transport/surface/chat/encode.ts +7 -7
  522. package/src/transport/surface/chat/parse.ts +7 -7
  523. package/src/transport/surface/completion.ts +3 -3
  524. package/src/transport/surface/content-parts.ts +1 -1
  525. package/src/transport/surface/dialects.ts +2 -2
  526. package/src/transport/surface/messages/encode.ts +1 -1
  527. package/src/transport/surface/messages/parse.ts +3 -3
  528. package/src/transport/surface/responses/adapter.ts +1 -1
  529. package/src/transport/surface/responses/errors.ts +0 -9
  530. package/src/transport/vision-handoff-cache.ts +58 -0
  531. package/src/transport/vision-handoff.ts +376 -0
  532. package/src/workers/account-identity-sweep.ts +2 -2
  533. package/src/workers/buddy-growth-tasks.ts +392 -346
  534. package/src/workers/daily-checkin.ts +102 -49
  535. package/src/workers/maintenance-lease.ts +2 -35
  536. package/src/workers/oauth-refresh-sweep.ts +8 -1
  537. package/src/workers/quota-refresh-sweep.ts +120 -82
  538. package/src/workers/scheduler.ts +67 -4
  539. package/src/workers/sweep-runner.ts +24 -5
  540. package/src/workers/zcode-gift-claim.ts +108 -0
  541. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  542. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  543. package/dist/dashboard/assets/BannedPage-2TJD37Hb.js.gz +0 -0
  544. package/dist/dashboard/assets/CliToolDetailPage-xefJNRmJ.js.gz +0 -0
  545. package/dist/dashboard/assets/CliToolsPage-Rj9iHQ3F.js.gz +0 -0
  546. package/dist/dashboard/assets/CombosPage-JEbYJFxw.js +0 -1
  547. package/dist/dashboard/assets/CombosPage-JEbYJFxw.js.gz +0 -0
  548. package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js +0 -1
  549. package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js.gz +0 -0
  550. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js +0 -1
  551. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js.gz +0 -0
  552. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js +0 -1
  553. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js.gz +0 -0
  554. package/dist/dashboard/assets/LoginPage-C4w7vea-.js.gz +0 -0
  555. package/dist/dashboard/assets/ModelPicker-BtPcAfot.js.gz +0 -0
  556. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js +0 -1
  557. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js.gz +0 -0
  558. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js +0 -4
  559. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js.gz +0 -0
  560. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  561. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  562. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js +0 -1
  563. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js.gz +0 -0
  564. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js +0 -9
  565. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js.gz +0 -0
  566. package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js +0 -1
  567. package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js.gz +0 -0
  568. package/dist/dashboard/assets/SettingsPage-CDZjTt87.js +0 -1
  569. package/dist/dashboard/assets/SettingsPage-CDZjTt87.js.gz +0 -0
  570. package/dist/dashboard/assets/SetupPage-BQS0Rx_u.js.gz +0 -0
  571. package/dist/dashboard/assets/SortableList-BAL5npBC.js +0 -1
  572. package/dist/dashboard/assets/SortableList-BAL5npBC.js.gz +0 -0
  573. package/dist/dashboard/assets/StudioPage-TP7voAQ0.js.gz +0 -0
  574. package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js +0 -56
  575. package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js.gz +0 -0
  576. package/dist/dashboard/assets/api-keys-MbI7e7rt.js +0 -1
  577. package/dist/dashboard/assets/api-keys-MbI7e7rt.js.gz +0 -0
  578. package/dist/dashboard/assets/app-B2vyPoII.css +0 -2
  579. package/dist/dashboard/assets/app-B2vyPoII.css.gz +0 -0
  580. package/dist/dashboard/assets/assert-C0YYuZJ4.js.gz +0 -0
  581. package/dist/dashboard/assets/badge-B_DMpMJN.js.gz +0 -0
  582. package/dist/dashboard/assets/banner-DMrMPmth.js.gz +0 -0
  583. package/dist/dashboard/assets/card-Be5Uzamx.js.gz +0 -0
  584. package/dist/dashboard/assets/cli-tools-muFRphDu.js.gz +0 -0
  585. package/dist/dashboard/assets/clipboard-button-DOfrVmsi.js.gz +0 -0
  586. package/dist/dashboard/assets/dialog-C9omdjQt.js.gz +0 -0
  587. package/dist/dashboard/assets/drawer-Bm8WKaGY.js.gz +0 -0
  588. package/dist/dashboard/assets/entry-DS90gUks.js +0 -1
  589. package/dist/dashboard/assets/entry-DS90gUks.js.gz +0 -0
  590. package/dist/dashboard/assets/entry-j40LJotO.js +0 -4
  591. package/dist/dashboard/assets/entry-j40LJotO.js.gz +0 -0
  592. package/dist/dashboard/assets/entry-q5HwZ8nN.js.gz +0 -0
  593. package/dist/dashboard/assets/formatters-BTScrQpe.js.gz +0 -0
  594. package/dist/dashboard/assets/github-badge-Orjuzemr.js.gz +0 -0
  595. package/dist/dashboard/assets/index-cPrX5vn6.js.gz +0 -0
  596. package/dist/dashboard/assets/inline-Dvux8w-0.js.gz +0 -0
  597. package/dist/dashboard/assets/input-CU1Rgf3p.js.gz +0 -0
  598. package/dist/dashboard/assets/list-row-CzFvogbj.js.gz +0 -0
  599. package/dist/dashboard/assets/live-KaG15HLQ.js +0 -1
  600. package/dist/dashboard/assets/live-KaG15HLQ.js.gz +0 -0
  601. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +0 -1
  602. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  603. package/dist/dashboard/assets/mutation-JJGQm8TD.js.gz +0 -0
  604. package/dist/dashboard/assets/numbers-BNDZnsUE.js +0 -2
  605. package/dist/dashboard/assets/numbers-BNDZnsUE.js.gz +0 -0
  606. package/dist/dashboard/assets/query-keys-CLaNz8Xz.js.gz +0 -0
  607. package/dist/dashboard/assets/quota-DZGyp0N5.js +0 -1
  608. package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
  609. package/dist/dashboard/assets/routing-BEH32QOC.js.gz +0 -0
  610. package/dist/dashboard/assets/select-B3iTetHN.js.gz +0 -0
  611. package/dist/dashboard/assets/settings-Dt3Eqbnq.js +0 -1
  612. package/dist/dashboard/assets/settings-Dt3Eqbnq.js.gz +0 -0
  613. package/dist/dashboard/assets/stack-KrOrm7JZ.js.gz +0 -0
  614. package/dist/dashboard/assets/state-DLS7IDMy.js.gz +0 -0
  615. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  616. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  617. package/dist/dashboard/assets/switch-42ItvbAs.js.gz +0 -0
  618. package/dist/dashboard/assets/useMutation-Dmnfh1Ue.js.gz +0 -0
  619. package/src/network/response-headers.ts +0 -39
  620. package/src/protocol/response/dsml.ts +0 -38
  621. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  622. /package/dist/dashboard/assets/{app-wvwCi4Eh.js → app-Bgd3zANQ.js} +0 -0
  623. /package/dist/dashboard/assets/{app-wvwCi4Eh.js.gz → app-Bgd3zANQ.js.gz} +0 -0
  624. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  625. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -26,7 +26,7 @@ import type {
26
26
  /** Ask buckets are keyed to this many decimals so float noise cannot split one price into two tiers. */
27
27
  const PRICE_PRECISION = 6;
28
28
  /** Default number of live providers a capacity-weighted price must have behind it. */
29
- export const DEFAULT_MIN_CAPACITY = 2;
29
+ const DEFAULT_MIN_CAPACITY = 2;
30
30
 
31
31
  const FAMILY_STATES: readonly FamilyState[] = [
32
32
  "operational",
@@ -114,7 +114,7 @@ export function groupTiers(
114
114
  * provider count would make `providersLive` wrong, and a wrong availability
115
115
  * number is worse than an absent one.
116
116
  */
117
- export function pricePointsToTiers(
117
+ function pricePointsToTiers(
118
118
  points: unknown,
119
119
  official: number | null,
120
120
  ): readonly Tier[] {
@@ -57,7 +57,7 @@ import type {
57
57
  /** Success rate below which a model is not routed to, when one is reported. */
58
58
  const MIN_SUCCESS_RATE_PCT = 80;
59
59
 
60
- export interface InferhubRoutesConfig {
60
+ interface InferhubRoutesConfig {
61
61
  readonly accessResolver: (request: Request) => AccessDecision | undefined;
62
62
  /** Resolves the `config_read` key. Absent means the catalog cannot be read. */
63
63
  readonly resolveConfigKey?: () => Promise<string | undefined> | string | undefined;
@@ -34,7 +34,7 @@ export interface ModelHealth {
34
34
  readonly familyState: FamilyState | null;
35
35
  }
36
36
 
37
- export interface ModelCapabilities {
37
+ interface ModelCapabilities {
38
38
  readonly contextWindow: number | null;
39
39
  readonly maxOutputTokens: number | null;
40
40
  readonly modalities: readonly string[];
@@ -173,7 +173,7 @@ export interface UsageCacheResponse {
173
173
  cacheWriteTokens: number;
174
174
  hitRate: number;
175
175
  }
176
- export type UsageRequestMode = "stream" | "non_stream";
176
+ type UsageRequestMode = "stream" | "non_stream";
177
177
  export interface UsageRequestItem {
178
178
  requestId: string;
179
179
  surface?: string;
@@ -191,6 +191,10 @@ export interface UsageRequestItem {
191
191
  apiKeyId?: string;
192
192
  userAgent?: string;
193
193
  clientName?: string;
194
+ /** The proxy pool that carried this request, when one was used. */
195
+ networkPoolId?: string;
196
+ /** Operator-facing label of the pool; absent when the pool is gone. */
197
+ networkPoolLabel?: string;
194
198
  estimatedCost?: number;
195
199
  /** Provider-billed credits; absent when the upstream reported no credit field. */
196
200
  creditUsed?: number;
@@ -7,7 +7,7 @@
7
7
  // Every endpoint requires `dashboard:read`. The global request count is
8
8
  // process-level; pool usage and health are filtered to the caller's tenant.
9
9
 
10
- import { Elysia } from "elysia";
10
+ import { Elysia, type AnyElysia } from "elysia";
11
11
  import { errorResponse, requireScope } from "../shared/errors";
12
12
  import type { ConsoleAccessResolver } from "../auth/access";
13
13
  /**
@@ -34,7 +34,7 @@ import { poolByteSnapshot } from "../../network/pool/byte-accounting";
34
34
  import { consoleSseResponse, createConsoleSseStream } from "./sse";
35
35
  import { subscribeRequestCompleted } from "../../observability/request-notify";
36
36
 
37
- export interface LiveConfig {
37
+ interface LiveConfig {
38
38
  readonly accessResolver: ConsoleAccessResolver;
39
39
  readonly poolSelector?: NetworkPoolSelector;
40
40
  readonly db?: CartethyiaDatabase;
@@ -86,7 +86,7 @@ function withPoolBytes<T extends { poolId: string; currentInflight?: number }>(
86
86
  });
87
87
  }
88
88
 
89
- export function createLiveRoutes(config: LiveConfig): Elysia {
89
+ export function createLiveRoutes(config: LiveConfig): AnyElysia {
90
90
  return new Elysia()
91
91
  .get("/live/requests/stream", ({ request, set }) => {
92
92
  try {
@@ -94,10 +94,9 @@ export function createLiveRoutes(config: LiveConfig): Elysia {
94
94
  requireScope(access, "dashboard:read");
95
95
  const tenantId = access?.tenantId;
96
96
  if (!tenantId) return errorResponse(new Error("Tenant required"), set, "Live operation failed");
97
- set.headers["content-type"] = "text/event-stream";
98
- set.headers["cache-control"] = "no-cache, no-transform";
99
- set.headers["connection"] = "keep-alive";
100
- set.headers["x-accel-buffering"] = "no";
97
+ // No `set.headers` writes here: this handler returns a `Response`, so
98
+ // Elysia discards `set` and `consoleSseResponse` below owns the SSE
99
+ // headers (content-type, cache-control, connection, buffering).
101
100
  return consoleSseResponse(
102
101
  createConsoleSseStream(request.signal, ({ send }) => {
103
102
  return subscribeRequestCompleted((notice) => {
@@ -119,22 +118,36 @@ export function createLiveRoutes(config: LiveConfig): Elysia {
119
118
  })
120
119
  .get("/live/in-flight/stream", ({ request, set }) => {
121
120
  try {
122
- requireScope(config.accessResolver(request), "dashboard:read");
121
+ const access = requireScope(config.accessResolver(request), "dashboard:read");
122
+ const tenantId = access?.tenantId;
123
+ return consoleSseResponse(
124
+ createConsoleSseStream(request.signal, ({ send }) => {
125
+ const store = config.stateStore;
126
+ if (!store) {
127
+ send("count", EMPTY_IN_FLIGHT);
128
+ return () => {};
129
+ }
130
+ // The Usage page keeps one stream open for both the in-flight gauge
131
+ // and request-table invalidation, so this route also fans out
132
+ // `request_completed` events (tagged by kind) for the tenant,
133
+ // mirroring `/live/requests/stream`.
134
+ const unsubscribe = store.subscribeInFlight((snapshot) => send("count", snapshot));
135
+ let unsubscribeCompleted: (() => void) | undefined;
136
+ if (tenantId) {
137
+ unsubscribeCompleted = subscribeRequestCompleted((notice) => {
138
+ if (notice.tenantId === tenantId) send("request_completed", notice);
139
+ });
140
+ }
141
+ send("count", store.inFlightSnapshot());
142
+ return () => {
143
+ unsubscribe();
144
+ unsubscribeCompleted?.();
145
+ };
146
+ }),
147
+ );
123
148
  } catch (e) {
124
149
  return errorResponse(e, set, "Live operation failed");
125
150
  }
126
- return consoleSseResponse(
127
- createConsoleSseStream(request.signal, ({ send }) => {
128
- const store = config.stateStore;
129
- if (!store) {
130
- send("count", EMPTY_IN_FLIGHT);
131
- return () => {};
132
- }
133
- const unsubscribe = store.subscribeInFlight((snapshot) => send("count", snapshot));
134
- send("count", store.inFlightSnapshot());
135
- return unsubscribe;
136
- }),
137
- );
138
151
  })
139
152
  .get("/live/pools", async ({ request, set }) => {
140
153
  try {
@@ -176,5 +189,5 @@ export function createLiveRoutes(config: LiveConfig): Elysia {
176
189
  };
177
190
  }),
178
191
  );
179
- }) as unknown as Elysia;
192
+ });
180
193
  }
@@ -8,7 +8,7 @@
8
8
  // metadata and their args are redacted at the source, the same audience
9
9
  // that already reads request/response bodies on Usage.
10
10
 
11
- import { Elysia, t } from "elysia";
11
+ import { Elysia, t, type AnyElysia } from "elysia";
12
12
  import { ConsoleDomainError, errorResponse, requireScope } from "../shared/errors";
13
13
  import { parseQueryLimit } from "../shared/query";
14
14
  import type { ConsoleAccessResolver } from "../auth/access";
@@ -23,7 +23,7 @@ import {
23
23
  } from "../../observability/log-ring";
24
24
  import { consoleSseResponse, createConsoleSseStream } from "./sse";
25
25
 
26
- export interface LogsConfig {
26
+ interface LogsConfig {
27
27
  readonly accessResolver: ConsoleAccessResolver;
28
28
  readonly auditSink?: AuditSink;
29
29
  }
@@ -37,7 +37,7 @@ const logsQuery = t.Object({
37
37
  limit: t.Optional(t.String()),
38
38
  });
39
39
 
40
- export function createLogRoutes(config: LogsConfig): Elysia {
40
+ export function createLogRoutes(config: LogsConfig): AnyElysia {
41
41
  const readLogs = (access: AccessDecision | undefined, level?: string, limitRaw?: string) => {
42
42
  requireScope(access, "dashboard:read");
43
43
  if (level !== undefined && !isLogLevel(level)) {
@@ -83,5 +83,5 @@ export function createLogRoutes(config: LogsConfig): Elysia {
83
83
  });
84
84
  }),
85
85
  );
86
- }) as unknown as Elysia;
86
+ });
87
87
  }
@@ -5,12 +5,12 @@
5
5
  // this instance's own module graph and egress), so the route is guarded by
6
6
  // `platform:admin` like the other instance-level operations.
7
7
 
8
- import { Elysia } from "elysia";
8
+ import { Elysia, type AnyElysia } from "elysia";
9
9
  import { errorResponse, requireGlobalAdmin } from "../shared/errors";
10
10
  import { performanceMetricsSnapshot } from "../../observability/performance-metrics";
11
11
  import type { PerformanceConfig } from "./performance-contracts";
12
12
 
13
- export function createPerformanceRoutes(config: PerformanceConfig): Elysia {
13
+ export function createPerformanceRoutes(config: PerformanceConfig): AnyElysia {
14
14
  return new Elysia()
15
15
  .get("/system/performance", ({ request, set }) => {
16
16
  try {
@@ -19,5 +19,5 @@ export function createPerformanceRoutes(config: PerformanceConfig): Elysia {
19
19
  } catch (e) {
20
20
  return errorResponse(e, set, "Performance operation failed");
21
21
  }
22
- }) as unknown as Elysia;
22
+ });
23
23
  }
@@ -1,4 +1,4 @@
1
- import { Elysia, t } from "elysia";
1
+ import { Elysia, t, type AnyElysia } from "elysia";
2
2
  import { ConsoleDomainError, consoleErrorHandler } from "../shared/errors";
3
3
  import { USAGE_DIMENSIONS, type UsageDimension } from "./usage-dimensions";
4
4
  import { createObservabilityOperations, type ObservabilityConfig } from "./contracts";
@@ -18,7 +18,7 @@ const telemetryDetailQuery = t.Object({
18
18
  includePayload: t.Optional(t.String()),
19
19
  createdAt: t.Optional(t.String()),
20
20
  });
21
- export function createObservabilityRoutes(config: ObservabilityConfig): Elysia {
21
+ export function createObservabilityRoutes(config: ObservabilityConfig): AnyElysia {
22
22
  const factory = createObservabilityOperations(config);
23
23
  return new Elysia()
24
24
  .error(consoleErrorHandler("Observability operation failed"))
@@ -114,5 +114,5 @@ export function createObservabilityRoutes(config: ObservabilityConfig): Elysia {
114
114
  query.createdAt,
115
115
  );
116
116
  },
117
- ) as unknown as Elysia;
117
+ );
118
118
  }
@@ -5,14 +5,14 @@
5
5
  * the shared `buildSseEventFrame` core so the two layers cannot drift.
6
6
  */
7
7
 
8
- export interface SseSender {
8
+ interface SseSender {
9
9
  send(event: string, data: unknown): void;
10
10
  }
11
11
 
12
12
  /** Register endpoint-specific SSE subscriptions; return their teardown callback. */
13
- export type SseSetup = (sender: SseSender) => () => void;
13
+ type SseSetup = (sender: SseSender) => () => void;
14
14
 
15
- import { buildSseEventFrame as formatSseFrame } from "../../protocol/sse-frame";
15
+ import { TEXT_ENCODER, buildSseEventFrame as formatSseFrame } from "../../protocol/sse-frame";
16
16
 
17
17
  export { formatSseFrame };
18
18
 
@@ -22,38 +22,82 @@ export { formatSseFrame };
22
22
  */
23
23
  const SSE_HEARTBEAT_MS = 25_000;
24
24
 
25
+ /**
26
+ * Hard cap on one stream's lifetime. A tab that is abandoned but never
27
+ * unloads (a backgrounded browser window, a parked laptop) would otherwise
28
+ * hold its subscription and timers forever; the client reconnects on close,
29
+ * so this only forces a refresh. 45 minutes is far longer than any live view
30
+ * needs in one stretch.
31
+ */
32
+ const SSE_MAX_LIFETIME_MS = 45 * 60_000;
33
+
34
+ /**
35
+ * Idle timeout: if no *data* frame is sent for this long, the stream sends a
36
+ * terminal `close` event and closes. Heartbeats deliberately do not count —
37
+ * they are there to keep proxies alive, not to prove someone is reading, so
38
+ * they must not defeat the abandoned-tab cutoff.
39
+ */
40
+ const SSE_IDLE_TIMEOUT_MS = 5 * 60_000;
41
+
42
+ /** Watchdog cadence; the two cutoffs above are checked on this tick. */
43
+ const SSE_WATCHDOG_MS = 30_000;
44
+
45
+ /** Frame sent when the server cuts the stream (idle or max lifetime). */
46
+ function closeFrame(reason: string): Uint8Array {
47
+ return TEXT_ENCODER.encode(formatSseFrame("close", JSON.stringify({ reason })));
48
+ }
49
+
25
50
  /**
26
51
  * Console SSE response stream with uniform JSON event encoding, heartbeat,
27
- * and abort/cancel cleanup. The setup callback runs synchronously at stream
28
- * start so the initial snapshot is enqueued before the first read.
52
+ * idle/max-lifetime cutoff, and abort/cancel cleanup. The setup callback runs
53
+ * synchronously at stream start so the initial snapshot is enqueued before the
54
+ * first read.
55
+ *
56
+ * The encoder is the module-level shared `TextEncoder` from the frame module:
57
+ * allocating one per stream (let alone per send) is unnecessary garbage for a
58
+ * hot path that encodes a frame every few hundred milliseconds per connection.
29
59
  */
30
60
  export function createConsoleSseStream(
31
61
  signal: AbortSignal,
32
62
  setup: SseSetup,
33
63
  ): ReadableStream<Uint8Array> {
34
- const encoder = new TextEncoder();
35
64
  let cleanupSubscription: (() => void) | undefined;
36
65
  let heartbeat: ReturnType<typeof setInterval> | undefined;
66
+ let watchdog: ReturnType<typeof setInterval> | undefined;
37
67
  let close: (() => void) | undefined;
38
68
 
39
69
  return new ReadableStream<Uint8Array>({
40
70
  start(controller) {
41
71
  let closed = false;
72
+ const startedAt = Date.now();
73
+ let lastDataAt = startedAt;
42
74
  const sender: SseSender = {
43
75
  send(event, data) {
44
76
  if (closed) return;
45
77
  try {
46
- controller.enqueue(encoder.encode(formatSseFrame(event, JSON.stringify(data))));
78
+ lastDataAt = Date.now();
79
+ controller.enqueue(TEXT_ENCODER.encode(formatSseFrame(event, JSON.stringify(data))));
47
80
  } catch {
48
81
  close?.();
49
82
  }
50
83
  },
51
84
  };
52
85
 
86
+ const terminate = (reason: string): void => {
87
+ if (closed) return;
88
+ try {
89
+ controller.enqueue(closeFrame(reason));
90
+ } catch {
91
+ // Fall through to close regardless.
92
+ }
93
+ close?.();
94
+ };
95
+
53
96
  close = () => {
54
97
  if (closed) return;
55
98
  closed = true;
56
99
  clearInterval(heartbeat);
100
+ clearInterval(watchdog);
57
101
  cleanupSubscription?.();
58
102
  try {
59
103
  controller.close();
@@ -70,12 +114,22 @@ export function createConsoleSseStream(
70
114
  heartbeat = setInterval(() => {
71
115
  if (closed) return;
72
116
  try {
73
- controller.enqueue(encoder.encode(": ping\n\n"));
117
+ controller.enqueue(TEXT_ENCODER.encode(": ping\n\n"));
74
118
  } catch {
75
119
  close?.();
76
120
  }
77
121
  }, SSE_HEARTBEAT_MS);
78
122
 
123
+ watchdog = setInterval(() => {
124
+ if (closed) return;
125
+ const now = Date.now();
126
+ if (now - lastDataAt > SSE_IDLE_TIMEOUT_MS) {
127
+ terminate("idle");
128
+ } else if (now - startedAt > SSE_MAX_LIFETIME_MS) {
129
+ terminate("max_lifetime");
130
+ }
131
+ }, SSE_WATCHDOG_MS);
132
+
79
133
  signal.addEventListener("abort", close, { once: true });
80
134
  },
81
135
  cancel() {
@@ -7,11 +7,8 @@ import { type TelemetryEventRecord } from "../../observability/event-log";
7
7
  import {
8
8
  breakdownTelemetry,
9
9
  chartTelemetry,
10
- healthTelemetry,
11
10
  queryTelemetryEvents as queryTelemetryEventPage,
12
- summarizeHealthPerformance,
13
- summarizeUsagePerformanceSql,
14
- summarizeTelemetry,
11
+ summarizeUsageWithPerformance,
15
12
  } from "../../observability/event-query";
16
13
  import { clientNameFromUserAgent } from "../../observability/client-name";
17
14
 
@@ -145,6 +142,7 @@ function mapUsageRequestItem(
145
142
  : {}),
146
143
  ...(event.endpoint ? { endpoint: event.endpoint } : {}),
147
144
  ...(event.apiKeyId ? { apiKeyId: event.apiKeyId } : {}),
145
+ ...(event.networkPoolId ? { networkPoolId: event.networkPoolId } : {}),
148
146
  ...(event.userAgent ? { userAgent: event.userAgent } : {}),
149
147
  ...(event.userAgent ? { clientName: clientNameFromUserAgent(event.userAgent) } : {}),
150
148
  ...(event.clientIp
@@ -186,6 +184,14 @@ async function resolveProxyLabel(
186
184
  }
187
185
  const HEALTH_WINDOW_MS = 24 * 3_600_000;
188
186
  const TOP_N = 50;
187
+ /**
188
+ * TTL for the usage analytics read-through (summary, chart, breakdown, totals).
189
+ * The dashboard polls these every 5–10s; a 30s TTL means the heavy telemetry
190
+ * window scans run once per 30s and the polls in between are answered from
191
+ * Redis (or the in-process fallback) with a `304`. Health stays on the
192
+ * default 10s — it feeds the live status tile.
193
+ */
194
+ const USAGE_READ_THROUGH_TTL_SECONDS = 30;
189
195
 
190
196
  /**
191
197
  * Nearest-rank percentile over a sorted array — kept for the JS-side
@@ -199,7 +205,7 @@ function percentile(sorted: readonly number[], fraction: number): number {
199
205
  return Math.round(sorted[index] ?? 0);
200
206
  }
201
207
 
202
- export interface UsagePerformanceSummary {
208
+ interface UsagePerformanceSummary {
203
209
  avgResolveMs: number;
204
210
  avgDurationMs: number;
205
211
  latencyP50Ms: number;
@@ -326,11 +332,10 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
326
332
  // cost on the dashboard. `healthTelemetry` returns the totals and the
327
333
  // database computes the percentiles.
328
334
  const since = new Date(Date.now() - HEALTH_WINDOW_MS);
329
- const totals = await healthTelemetry(this.db, tenantId, since);
330
- const performance = await summarizeHealthPerformance(this.db, tenantId, since);
335
+ const { summary: totals, performance } = await summarizeUsageWithPerformance(this.db, tenantId, since);
331
336
  total = totals.requests;
332
337
  errors = totals.errors;
333
- avg = performance.latencyAvgMs === null ? 0 : Math.round(performance.latencyAvgMs);
338
+ avg = Math.round(performance.avgDurationMs ?? 0);
334
339
  p95 = performance.latencyP95Ms ?? 0;
335
340
  p99 = performance.latencyP99Ms ?? 0;
336
341
  const inputTokens = totals.inputTokens;
@@ -392,6 +397,7 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
392
397
  async usage(tenantId: string, period: string): Promise<CachedResult<UsageResponse>> {
393
398
  return this.readThroughWithEtag(this.usageCacheKey(tenantId, period, "usage"), () =>
394
399
  this.computeUsage(tenantId, period),
400
+ USAGE_READ_THROUGH_TTL_SECONDS,
395
401
  );
396
402
  }
397
403
 
@@ -408,8 +414,12 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
408
414
  * configured — and returns the strong validator alongside it, so a repeated
409
415
  * poll can be answered with a `304` instead of the whole payload.
410
416
  */
411
- private readThroughWithEtag<T>(key: string, compute: () => Promise<T>): Promise<CachedResult<T>> {
412
- return cachedReadWithEtag(this.redis, key, compute);
417
+ private readThroughWithEtag<T>(
418
+ key: string,
419
+ compute: () => Promise<T>,
420
+ ttlSeconds?: number,
421
+ ): Promise<CachedResult<T>> {
422
+ return cachedReadWithEtag(this.redis, key, compute, ttlSeconds);
413
423
  }
414
424
 
415
425
  private async computeUsage(tenantId: string, period: string): Promise<UsageResponse> {
@@ -417,8 +427,8 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
417
427
  // Totals AND the top-model/top-provider counts come from SQL: the old
418
428
  // shape parsed the whole retained window into an array to count two
419
429
  // dimensions in JavaScript.
420
- const [summary, models, providers] = await Promise.all([
421
- summarizeTelemetry(this.db, tenantId, since),
430
+ const [{ summary }, models, providers] = await Promise.all([
431
+ summarizeUsageWithPerformance(this.db, tenantId, since),
422
432
  breakdownTelemetry(this.db, tenantId, "model", since),
423
433
  breakdownTelemetry(this.db, tenantId, "provider", since),
424
434
  ]);
@@ -462,18 +472,18 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
462
472
  async usageSummary(tenantId: string, period: string): Promise<CachedResult<UsageSummaryResponse>> {
463
473
  return this.readThroughWithEtag(this.usageCacheKey(tenantId, period, "summary"), () =>
464
474
  this.computeSummary(tenantId, period),
475
+ USAGE_READ_THROUGH_TTL_SECONDS,
465
476
  );
466
477
  }
467
478
 
468
479
  private async computeSummary(tenantId: string, period: string): Promise<UsageSummaryResponse> {
469
480
  const since = this.periodSince(period);
470
481
  // Totals, status breakdown, and latency percentiles all computed in SQL.
471
- // This used to parse the whole retained window into JavaScript to sum six
472
- // counters and sort a latency array.
473
- const [summary, statuses, performance] = await Promise.all([
474
- summarizeTelemetry(this.db, tenantId, since),
482
+ // The summary totals and performance figures come from ONE combined window
483
+ // scan (one percentile pass), not two independent scans.
484
+ const [{ summary, performance }, statuses] = await Promise.all([
485
+ summarizeUsageWithPerformance(this.db, tenantId, since),
475
486
  breakdownTelemetry(this.db, tenantId, "status", since),
476
- summarizeUsagePerformanceSql(this.db, tenantId, since),
477
487
  ]);
478
488
  const inputTokens = summary.inputTokens;
479
489
  const cachedTokens = summary.cachedInputTokens;
@@ -503,6 +513,7 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
503
513
  async usageChart(tenantId: string, period: string): Promise<CachedResult<UsageChartResponse>> {
504
514
  return this.readThroughWithEtag(this.usageCacheKey(tenantId, period, "chart"), () =>
505
515
  this.computeChart(tenantId, period),
516
+ USAGE_READ_THROUGH_TTL_SECONDS,
506
517
  );
507
518
  }
508
519
 
@@ -526,7 +537,7 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
526
537
  input: bucket.inputTokens,
527
538
  // `cached` is the cached share of the prompt: the SQL reader sums
528
539
  // cached_input_tokens, which is the same number the old JS loop used.
529
- cached: bucket.inputTokens,
540
+ cached: bucket.cachedInputTokens,
530
541
  output: bucket.outputTokens,
531
542
  });
532
543
  }
@@ -550,6 +561,7 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
550
561
  ): Promise<CachedResult<UsageByResponse>> {
551
562
  return this.readThroughWithEtag(this.usageCacheKey(tenantId, `${dimension}:${period}`, "by"), () =>
552
563
  this.computeBy(tenantId, dimension, period),
564
+ USAGE_READ_THROUGH_TTL_SECONDS,
553
565
  );
554
566
  }
555
567
 
@@ -655,7 +667,7 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
655
667
  }
656
668
 
657
669
  private async computeCache(tenantId: string, period: string): Promise<UsageCacheResponse> {
658
- const summary = await summarizeTelemetry(this.db, tenantId, this.periodSince(period));
670
+ const { summary } = await summarizeUsageWithPerformance(this.db, tenantId, this.periodSince(period));
659
671
  const inputTokens = summary.inputTokens;
660
672
  const outputTokens = summary.outputTokens;
661
673
  const cachedTokens = summary.cachedInputTokens;
@@ -766,7 +778,11 @@ export class DrizzleObservabilityStore implements ObservabilityStore {
766
778
  const item = mapUsageRequestItem(event, hideClientIp);
767
779
  const keyLabel = event.apiKeyId ? keyLabels?.get(event.apiKeyId) : undefined;
768
780
  const labeled = keyLabel === undefined ? item : { ...item, apiKeyLabel: keyLabel };
769
- const presented = { ...labeled, proxy };
781
+ const presented = {
782
+ ...labeled,
783
+ proxy,
784
+ ...(event.networkPoolId ? { networkPoolLabel: proxy } : {}),
785
+ };
770
786
  // Filter the payload table directly instead of joining `telemetry_events`
771
787
  // only to re-apply the tenant predicate: `telemetry_payloads` carries
772
788
  // `tenant_id` itself, so the join added a second table's rows to filter for
@@ -23,7 +23,7 @@ import type { ProviderRecord } from "./contracts";
23
23
  * purpose: the projection should not be able to reach a loader, so the type
24
24
  * cannot drift into "call something expensive to answer a boolean".
25
25
  */
26
- export interface ProviderDiscoveryLookup {
26
+ interface ProviderDiscoveryLookup {
27
27
  hasModelDiscovery(providerId: string): boolean;
28
28
  }
29
29