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
@@ -1,153 +1,153 @@
1
- import type {} from "../contracts";
2
- import { ensureV1Suffix, homeDir, join, readJsonFile, writeJsonFile } from "../fs-ops";
3
- import type { InjectorSpec } from "../contracts";
4
-
5
-
6
- // OpenCode injector spec.
7
- interface OpencodeModel {
8
- name: string;
9
- modalities: { input: string[]; output: string[] };
10
- }
11
-
12
- interface OpencodeProvider {
13
- npm: string;
14
- options: { baseURL?: string; apiKey?: string };
15
- models: Record<string, OpencodeModel>;
16
- }
17
-
18
- interface OpencodeConfig {
19
- provider?: Record<string, OpencodeProvider>;
20
- model?: string;
21
- agent?: {
22
- explorer?: {
23
- description?: string;
24
- mode?: string;
25
- model?: string;
26
- };
27
- [k: string]: unknown;
28
- };
29
- [k: string]: unknown;
30
- }
31
-
32
- function buildOpencodeModels(models: readonly string[]): Record<string, OpencodeModel> {
33
- const map: Record<string, OpencodeModel> = {};
34
- for (const m of models) {
35
- if (!m) continue;
36
- map[m] = { name: m, modalities: { input: ["text", "image"], output: ["text"] } };
37
- }
38
- return map;
39
- }
40
-
41
- export const opencodeSpec: InjectorSpec = {
42
- toolId: "opencode",
43
- displayName: "OpenCode",
44
- binary: "opencode",
45
- resolvePath: () => join(homeDir(), ".config", "opencode", "opencode.json"),
46
- resolveDir: () => join(homeDir(), ".config", "opencode"),
47
-
48
- async readStatus(path) {
49
- const config = (await readJsonFile(path)) as OpencodeConfig | null;
50
- if (!config) {
51
- return { configured: false, currentEndpoint: null, rawApiKey: null, currentModels: null };
52
- }
53
- const provider = config.provider?.cartethyia;
54
- const endpoint = provider?.options?.baseURL ?? null;
55
- const models = provider?.models ? Object.keys(provider.models) : null;
56
- const active =
57
- typeof config.model === "string" && config.model.startsWith("cartethyia/")
58
- ? config.model.split("/").slice(1).join("/")
59
- : null;
60
- return {
61
- configured: !!provider,
62
- currentEndpoint: endpoint,
63
- rawApiKey: provider?.options?.apiKey ?? null,
64
- currentModels: active && models ? [active, ...models.filter((m) => m !== active)] : models,
65
- };
66
- },
67
-
68
- async apply(input, path) {
69
- const existing = (await readJsonFile(path)) as OpencodeConfig | null;
70
- const config: OpencodeConfig = (existing ?? {}) as OpencodeConfig;
71
-
72
- if (!config.provider) config.provider = {};
73
- const prior = config.provider.cartethyia;
74
- config.provider.cartethyia = {
75
- npm: "@ai-sdk/openai-compatible",
76
- options: {
77
- ...(prior?.options ?? {}),
78
- baseURL: ensureV1Suffix(input.endpoint),
79
- apiKey: input.apiKey,
80
- },
81
- models: { ...(prior?.models ?? {}), ...buildOpencodeModels(input.modelIds) },
82
- };
83
-
84
- const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
85
- config.model = activeModel === "" ? "" : `cartethyia/${activeModel}`;
86
-
87
- if (!config.agent) config.agent = {};
88
- const subagentModel = input.subagentModel ?? input.modelIds[0] ?? activeModel;
89
- config.agent.explorer = {
90
- description: "Fast explorer subagent",
91
- mode: "subagent",
92
- model: `cartethyia/${subagentModel}`,
93
- };
94
-
95
- await writeJsonFile(path, config);
96
- },
97
-
98
- async reset(path) {
99
- const config = (await readJsonFile(path)) as OpencodeConfig | null;
100
- if (!config) return false;
101
-
102
- if (config.provider) {
103
- delete config.provider.cartethyia;
104
- if (Object.keys(config.provider).length === 0) delete config.provider;
105
- }
106
-
107
- if (typeof config.model === "string" && config.model.startsWith("cartethyia/")) {
108
- delete config.model;
109
- }
110
-
111
- if (config.agent?.explorer?.model?.startsWith("cartethyia/")) {
112
- delete config.agent.explorer;
113
- if (Object.keys(config.agent).length === 0) delete config.agent;
114
- }
115
-
116
- await writeJsonFile(path, config);
117
- },
118
-
119
- download(input) {
120
- const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
121
- const subagentModel = input.subagentModel ?? input.modelIds[0] ?? activeModel;
122
- const config: OpencodeConfig = {
123
- provider: {
124
- cartethyia: {
125
- npm: "@ai-sdk/openai-compatible",
126
- options: {
127
- baseURL: ensureV1Suffix(input.endpoint),
128
- apiKey: input.apiKey,
129
- },
130
- models: buildOpencodeModels(input.modelIds),
131
- },
132
- },
133
- model: activeModel === "" ? "" : `cartethyia/${activeModel}`,
134
- agent: {
135
- explorer: {
136
- description: "Fast explorer subagent",
137
- mode: "subagent",
138
- model: `cartethyia/${subagentModel}`,
139
- },
140
- },
141
- };
142
- return {
143
- content: JSON.stringify(config, null, 2),
144
- filename: "opencode.json",
145
- mimeType: "application/json",
146
- };
147
- },
148
-
149
- messages: {
150
- applied: "OpenCode settings applied",
151
- reset: "Cartethyia settings removed from OpenCode",
152
- },
153
- };
1
+ import type {} from "../contracts";
2
+ import { ensureV1Suffix, homeDir, join, readJsonFile, writeJsonFile } from "../fs-ops";
3
+ import type { InjectorSpec } from "../contracts";
4
+
5
+
6
+ // OpenCode injector spec.
7
+ interface OpencodeModel {
8
+ name: string;
9
+ modalities: { input: string[]; output: string[] };
10
+ }
11
+
12
+ interface OpencodeProvider {
13
+ npm: string;
14
+ options: { baseURL?: string; apiKey?: string };
15
+ models: Record<string, OpencodeModel>;
16
+ }
17
+
18
+ interface OpencodeConfig {
19
+ provider?: Record<string, OpencodeProvider>;
20
+ model?: string;
21
+ agent?: {
22
+ explorer?: {
23
+ description?: string;
24
+ mode?: string;
25
+ model?: string;
26
+ };
27
+ [k: string]: unknown;
28
+ };
29
+ [k: string]: unknown;
30
+ }
31
+
32
+ function buildOpencodeModels(models: readonly string[]): Record<string, OpencodeModel> {
33
+ const map: Record<string, OpencodeModel> = {};
34
+ for (const m of models) {
35
+ if (!m) continue;
36
+ map[m] = { name: m, modalities: { input: ["text", "image"], output: ["text"] } };
37
+ }
38
+ return map;
39
+ }
40
+
41
+ export const opencodeSpec: InjectorSpec = {
42
+ toolId: "opencode",
43
+ displayName: "OpenCode",
44
+ binary: "opencode",
45
+ resolvePath: () => join(homeDir(), ".config", "opencode", "opencode.json"),
46
+ resolveDir: () => join(homeDir(), ".config", "opencode"),
47
+
48
+ async readStatus(path) {
49
+ const config = (await readJsonFile(path)) as OpencodeConfig | null;
50
+ if (!config) {
51
+ return { configured: false, currentEndpoint: null, rawApiKey: null, currentModels: null };
52
+ }
53
+ const provider = config.provider?.cartethyia;
54
+ const endpoint = provider?.options?.baseURL ?? null;
55
+ const models = provider?.models ? Object.keys(provider.models) : null;
56
+ const active =
57
+ typeof config.model === "string" && config.model.startsWith("cartethyia/")
58
+ ? config.model.split("/").slice(1).join("/")
59
+ : null;
60
+ return {
61
+ configured: !!provider,
62
+ currentEndpoint: endpoint,
63
+ rawApiKey: provider?.options?.apiKey ?? null,
64
+ currentModels: active && models ? [active, ...models.filter((m) => m !== active)] : models,
65
+ };
66
+ },
67
+
68
+ async apply(input, path) {
69
+ const existing = (await readJsonFile(path)) as OpencodeConfig | null;
70
+ const config: OpencodeConfig = (existing ?? {}) as OpencodeConfig;
71
+
72
+ if (!config.provider) config.provider = {};
73
+ const prior = config.provider.cartethyia;
74
+ config.provider.cartethyia = {
75
+ npm: "@ai-sdk/openai-compatible",
76
+ options: {
77
+ ...(prior?.options ?? {}),
78
+ baseURL: ensureV1Suffix(input.endpoint),
79
+ apiKey: input.apiKey,
80
+ },
81
+ models: { ...(prior?.models ?? {}), ...buildOpencodeModels(input.modelIds) },
82
+ };
83
+
84
+ const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
85
+ config.model = activeModel === "" ? "" : `cartethyia/${activeModel}`;
86
+
87
+ if (!config.agent) config.agent = {};
88
+ const subagentModel = input.subagentModel ?? input.modelIds[0] ?? activeModel;
89
+ config.agent.explorer = {
90
+ description: "Fast explorer subagent",
91
+ mode: "subagent",
92
+ model: `cartethyia/${subagentModel}`,
93
+ };
94
+
95
+ await writeJsonFile(path, config);
96
+ },
97
+
98
+ async reset(path) {
99
+ const config = (await readJsonFile(path)) as OpencodeConfig | null;
100
+ if (!config) return false;
101
+
102
+ if (config.provider) {
103
+ delete config.provider.cartethyia;
104
+ if (Object.keys(config.provider).length === 0) delete config.provider;
105
+ }
106
+
107
+ if (typeof config.model === "string" && config.model.startsWith("cartethyia/")) {
108
+ delete config.model;
109
+ }
110
+
111
+ if (config.agent?.explorer?.model?.startsWith("cartethyia/")) {
112
+ delete config.agent.explorer;
113
+ if (Object.keys(config.agent).length === 0) delete config.agent;
114
+ }
115
+
116
+ await writeJsonFile(path, config);
117
+ },
118
+
119
+ download(input) {
120
+ const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
121
+ const subagentModel = input.subagentModel ?? input.modelIds[0] ?? activeModel;
122
+ const config: OpencodeConfig = {
123
+ provider: {
124
+ cartethyia: {
125
+ npm: "@ai-sdk/openai-compatible",
126
+ options: {
127
+ baseURL: ensureV1Suffix(input.endpoint),
128
+ apiKey: input.apiKey,
129
+ },
130
+ models: buildOpencodeModels(input.modelIds),
131
+ },
132
+ },
133
+ model: activeModel === "" ? "" : `cartethyia/${activeModel}`,
134
+ agent: {
135
+ explorer: {
136
+ description: "Fast explorer subagent",
137
+ mode: "subagent",
138
+ model: `cartethyia/${subagentModel}`,
139
+ },
140
+ },
141
+ };
142
+ return {
143
+ content: JSON.stringify(config, null, 2),
144
+ filename: "opencode.json",
145
+ mimeType: "application/json",
146
+ };
147
+ },
148
+
149
+ messages: {
150
+ applied: "OpenCode settings applied",
151
+ reset: "Cartethyia settings removed from OpenCode",
152
+ },
153
+ };
@@ -1,6 +1,6 @@
1
1
  import type { ConsoleAccessResolver } from "../auth/access";
2
2
  import type { AuditSink } from "../audit/contracts";
3
- import { Elysia, t } from "elysia";
3
+ import { Elysia, t, type AnyElysia } from "elysia";
4
4
  import { errorResponse, requireTenantScope } from "../shared/errors";
5
5
  import type { CliToolService } from "./service";
6
6
  import type { ApplyInput, CliMappingInput, CliModelMapping } from "./contracts";
@@ -23,7 +23,7 @@ import type { ApplyInput, CliMappingInput, CliModelMapping } from "./contracts";
23
23
  * `download` and `apply` require `keyId`; the server resolves the recoverable
24
24
  * AES-256-GCM copy so the operator never pastes a raw secret.
25
25
  */
26
- export interface CliToolsRoutesConfig {
26
+ interface CliToolsRoutesConfig {
27
27
  readonly service: CliToolService;
28
28
  readonly accessResolver: ConsoleAccessResolver;
29
29
  readonly auditSink?: AuditSink;
@@ -143,7 +143,7 @@ const mappingBody = t.Object({
143
143
  ),
144
144
  });
145
145
 
146
- export function createCliToolsRoutes(config: CliToolsRoutesConfig): Elysia {
146
+ export function createCliToolsRoutes(config: CliToolsRoutesConfig): AnyElysia {
147
147
  const { service, accessResolver, auditSink, snapshotInvalidator } = config;
148
148
 
149
149
  return new Elysia({ prefix: "/cli-tools" })
@@ -335,5 +335,5 @@ export function createCliToolsRoutes(config: CliToolsRoutesConfig): Elysia {
335
335
  } catch (e) {
336
336
  return errorResponse(e, set, "CLI tool operation failed");
337
337
  }
338
- }) as unknown as Elysia;
338
+ });
339
339
  }
@@ -27,7 +27,7 @@ import { ConsoleDomainError } from "../shared/errors";
27
27
  * and share one process's home directory (they are not tenant-scoped).
28
28
  */
29
29
 
30
- export function toToolRegistryEntry(def: ToolDef): ToolRegistryEntry {
30
+ function toToolRegistryEntry(def: ToolDef): ToolRegistryEntry {
31
31
  return {
32
32
  id: def.id,
33
33
  name: def.name,
@@ -14,13 +14,13 @@ import type {
14
14
  * The API-layer service owns validation against the registry; this store
15
15
  * only serializes rows in and out of Postgres.
16
16
  */
17
- export interface StoredMappingRow extends CliModelMapping {
17
+ interface StoredMappingRow extends CliModelMapping {
18
18
  readonly toolId: string;
19
19
  readonly tenantId: string;
20
20
  readonly apiKeyId: string;
21
21
  }
22
22
 
23
- export interface StoredSettings {
23
+ interface StoredSettings {
24
24
  readonly tenantId: string;
25
25
  readonly toolId: string;
26
26
  readonly apiKeyId: string;
@@ -35,7 +35,7 @@ export function createConsoleCsrfMiddleware(): Elysia {
35
35
  // CSRF enforcement applies exactly when a session cookie is present.
36
36
  if (!token) return;
37
37
  if (!isCsrfValid(request))
38
- throw new GatewayError("invalid_request", 403, "CSRF validation failed");
38
+ throw new GatewayError("policy_rejected", 403, "CSRF validation failed (request {requestId}). Not allowed by policy — no hard feelings 🫂");
39
39
  })
40
40
  .as("plugin");
41
41
  }
@@ -102,7 +102,7 @@ export function createConsoleMutationLimiterMiddleware(): Elysia {
102
102
  ? Math.ceil(CONSOLE_MUTATION_WINDOW_MS / 1000)
103
103
  : Math.max(1, Math.ceil((oldest + CONSOLE_MUTATION_WINDOW_MS - now) / 1000));
104
104
  set.headers["retry-after"] = String(retryAfterSeconds);
105
- throw new GatewayError("quota_exceeded", 429, "Console mutation rate limit exceeded");
105
+ throw new GatewayError("rate_limited", 429, "Console mutation rate limit exceeded (request {requestId}). Retry shortly. You've maxed this window — pace yourself ⏳");
106
106
  }
107
107
  hits.push(now);
108
108
  consoleMutationHits.set(key, hits);
@@ -4,7 +4,7 @@
4
4
  * composition time; concrete Drizzle stores are the defaults, so this file
5
5
  * is the single place that knows them.
6
6
  */
7
- import { Elysia } from "elysia";
7
+ import { Elysia, type AnyElysia } from "elysia";
8
8
  import { log } from "../observability/logger";
9
9
  import { resolveConsoleAccess, resolveConsoleUser } from "./auth/session-resolver";
10
10
  import { ConsoleCredentialService } from "./auth/credentials";
@@ -36,6 +36,7 @@ import type { BundledProviderCatalog } from "../providers/operations/provider-ca
36
36
  import type { ValidatedNetworkBindingFactory } from "../network/pool/resolver";
37
37
  import type { TrustedProxyBoundary } from "../config/network";
38
38
  import { gzipResponse } from "./response-compression";
39
+ import { beginConsoleActivity } from "../shared/invoke-guard";
39
40
 
40
41
  export interface ConsoleApiCompositionDeps {
41
42
  readonly db: CartethyiaDatabase;
@@ -80,6 +81,15 @@ export interface ConsoleApiCompositionDeps {
80
81
  | undefined;
81
82
  readonly resolvePeerAddress?: (request: Request) => string | null;
82
83
  readonly trustedProxyBoundary?: TrustedProxyBoundary;
84
+ /**
85
+ * The process shutdown coordinator, narrowed to the surface the update apply
86
+ * route needs. Declared structural (not the class) so the console composition
87
+ * root does not import the boot layer; `ShutdownCoordinator` satisfies it.
88
+ */
89
+ readonly shutdownCoordinator?: {
90
+ readonly begin: (reason: "update") => Promise<void>;
91
+ readonly totalShutdownBudgetMs: () => number;
92
+ };
83
93
  }
84
94
  /**
85
95
  * Extracts a bearer API key from a console request, or `undefined`.
@@ -100,7 +110,7 @@ function readApiKeyBearer(request: Request): string | undefined {
100
110
  return match?.[1];
101
111
  }
102
112
 
103
- export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
113
+ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): AnyElysia {
104
114
  const { db, routeSnapshotService, poolSelector, telemetryBuffer, redis } = deps;
105
115
  /**
106
116
  * Per-request cache: `beforeHandle` resolves the session asynchronously, and
@@ -109,6 +119,12 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
109
119
  * process (tests, or a second app instance) never share decisions.
110
120
  */
111
121
  const sessionAccessCache = new WeakMap<Request, AccessDecision | null>();
122
+ /**
123
+ * G-03 InvokeGuard: the console control plane's foreground-activity count.
124
+ * `beforeHandle` bumps it for the request; `afterResponse` releases it. The
125
+ * end callback is keyed by request so parallel requests pair correctly.
126
+ */
127
+ const consoleActivityEnds = new WeakMap<Request, () => void>();
112
128
  const cookiePolicy = defaultSessionCookiePolicy;
113
129
  const credentialService = new ConsoleCredentialService();
114
130
  const sessionService = new ConsoleSessionService(db, cookiePolicy);
@@ -137,6 +153,12 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
137
153
  .use(createConsoleCsrfMiddleware())
138
154
  .use(createConsoleMutationLimiterMiddleware())
139
155
  .beforeHandle(async ({ request }: { request: Request }) => {
156
+ // G-03: count this console request as foreground activity for the
157
+ // duration of its handling. Released in `afterResponse` below (or by
158
+ // the catch-all in the error path, which also runs before the response
159
+ // leaves). The scheduled worker registry uses this to defer sweeps
160
+ // while the operator is actively using the console.
161
+ consoleActivityEnds.set(request, beginConsoleActivity());
140
162
  // The auth routes (`/console/api/auth/*`) resolve the session themselves
141
163
  // and never read `accessResolver`, so resolving here too would repeat the
142
164
  // session lookup plus its user query on every login/session/logout call
@@ -167,6 +189,15 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
167
189
  }),
168
190
  );
169
191
  })
192
+ .afterResponse(({ request }: { request: Request }) => {
193
+ // G-03: release the foreground-activity count for this request.
194
+ // Elysia runs `afterResponse` for every completed request, errored ones
195
+ // included (the error is converted to a response first), so this is the
196
+ // single reliable release point — a failing route can never leak an
197
+ // elevated foreground count (which would defer sweeps forever).
198
+ consoleActivityEnds.get(request)?.();
199
+ consoleActivityEnds.delete(request);
200
+ })
170
201
  .use(
171
202
  createConsoleAuthRoutes(
172
203
  db,
@@ -197,6 +228,7 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
197
228
  admissionService: deps.admissionService,
198
229
  readRoutingAccountInflight: deps.readRoutingAccountInflight,
199
230
  ...(deps.flushBuffers ? { flushBuffers: deps.flushBuffers } : {}),
231
+ ...(deps.shutdownCoordinator ? { shutdownCoordinator: deps.shutdownCoordinator } : {}),
200
232
  credentialService,
201
233
  // The backup surface re-authenticates the operator, so it needs the current
202
234
  // user's hash. Read from the session on the request that asks for it, never
@@ -207,7 +239,7 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
207
239
  return user === null ? null : { passwordHash: user.passwordHash };
208
240
  },
209
241
  };
210
- registerConsoleDomains(console as unknown as Elysia, ctx);
242
+ registerConsoleDomains(console, ctx);
211
243
  // Compress the JSON control plane on the way out.
212
244
  //
213
245
  // `wrap` is used rather than a lifecycle hook because this Elysia beta does
@@ -229,5 +261,5 @@ export function createConsoleRouter(deps: ConsoleApiCompositionDeps): Elysia {
229
261
  gzipResponse(request, response),
230
262
  ),
231
263
  );
232
- return console as unknown as Elysia;
264
+ return console;
233
265
  }
@@ -9,7 +9,7 @@ import { acceptsGzip } from "./response-compression";
9
9
  /**
10
10
  * Represents the result of serving a static file.
11
11
  */
12
- export interface StaticServeResult {
12
+ interface StaticServeResult {
13
13
  status: number;
14
14
  body: Uint8Array | undefined;
15
15
  headers: Record<string, string>;
@@ -18,7 +18,7 @@ export interface StaticServeResult {
18
18
  /**
19
19
  * Configuration for the static file handler.
20
20
  */
21
- export interface StaticHandlerConfig {
21
+ interface StaticHandlerConfig {
22
22
  /** Absolute path to the dashboard build directory */
23
23
  buildDir: string;
24
24
  /**
@@ -30,7 +30,7 @@ export interface StaticHandlerConfig {
30
30
  }
31
31
 
32
32
  /** Shared landing, console, and public share entry document produced by Vite. */
33
- export const DEFAULT_ENTRY_DOCUMENTS: Readonly<Record<string, string>> = {
33
+ const DEFAULT_ENTRY_DOCUMENTS: Readonly<Record<string, string>> = {
34
34
  "/": "index.html",
35
35
  "/share": "index.html",
36
36
  "/console": "index.html",
@@ -47,7 +47,7 @@ function dashboardBuildHeader(html: string): Record<string, string> {
47
47
  * their own card here — crawlers do not run the client bundle, so a
48
48
  * `document.title` set at runtime cannot reach them.
49
49
  */
50
- export interface SocialMeta {
50
+ interface SocialMeta {
51
51
  title: string;
52
52
  description: string;
53
53
  image: string;
@@ -62,11 +62,11 @@ export const SHARE_SOCIAL_META: SocialMeta = {
62
62
  title: "Cartethyia — Bansos Token",
63
63
  description:
64
64
  "Come and save your tokens 💖 Shared Cartethyia API key — Bansos Token with live quota, usage and model allowlist.",
65
- image: "/assets/brand/og_bansos.webp",
66
- imageType: "image/webp",
67
- // Read from the file's own VP8 header, not carried over from the JPEG this
68
- // replaced: og:image:width/height are what a crawler uses to allocate the
69
- // card before the bytes arrive, so a copied size makes every preview crop.
65
+ image: "/assets/brand/og_bansos.jpg",
66
+ imageType: "image/jpeg",
67
+ // Read from the file's own header, not carried over from a previous image:
68
+ // og:image:width/height are what a crawler uses to allocate the card before
69
+ // the bytes arrive, so a copied size makes every preview crop.
70
70
  imageWidth: 1760,
71
71
  imageHeight: 576,
72
72
  imageAlt: "Cartethyia Bansos Token — Come and save your tokens",
@@ -1,4 +1,4 @@
1
- import { Elysia } from "elysia";
1
+ import { Elysia, type AnyElysia } from "elysia";
2
2
  import { t } from "elysia";
3
3
  import { errorResponse, requireAnyScope } from "../shared/errors";
4
4
  import type { AccessDecision } from "../../security/access-control";
@@ -39,7 +39,7 @@ export function createDataManagementRoutes(
39
39
  } | undefined;
40
40
  readonly flusher?: { flush(): Promise<void> } | undefined;
41
41
  },
42
- ): Elysia {
42
+ ): AnyElysia {
43
43
  const operations = createDataManagementOperations(config);
44
44
 
45
45
  return new Elysia({ prefix: "/data-management" })
@@ -101,5 +101,5 @@ export function createDataManagementRoutes(
101
101
  } catch (error) {
102
102
  return errorResponse(error, set, "Purge failed");
103
103
  }
104
- }) as unknown as Elysia;
104
+ });
105
105
  }
@@ -1,4 +1,4 @@
1
- import { Elysia } from "elysia";
1
+ import { type AnyElysia } from "elysia";
2
2
  import { ConsoleDomainError } from "./shared/errors";
3
3
  import { createCliToolsRoutes } from "./cli-tools/routes";
4
4
  import { createAccountQuotaRoutes } from "./quota/account-quota";
@@ -124,6 +124,16 @@ export interface ConsoleDomainContext {
124
124
  readonly loadConsoleUser: (request: Request) => Promise<{ readonly passwordHash: string } | null>;
125
125
  /** Password verification against the console user's stored hash. */
126
126
  readonly credentialService: Pick<ConsoleCredentialService, "verifyPassword">;
127
+ /**
128
+ * The process shutdown coordinator, narrowed to the update apply route's
129
+ * drain surface. Optional because reduced compositions (tests) legitimately
130
+ * build a console that cannot apply updates; the apply route answers 503
131
+ * rather than exiting undrained when it is absent.
132
+ */
133
+ readonly shutdownCoordinator?: {
134
+ readonly begin: (reason: "update") => Promise<void>;
135
+ readonly totalShutdownBudgetMs: () => number;
136
+ };
127
137
  }
128
138
  import { and, eq, isNull, or } from "drizzle-orm";
129
139
  import { networkPools, providerRoutingSettings } from "../persistence/schema";
@@ -133,7 +143,7 @@ import type { ProbeOutboundBinding } from "../providers/discovery/probing-servic
133
143
 
134
144
 
135
145
  export function registerConsoleDomains(
136
- console: Elysia<any, any, any, any, any, any, any, any>,
146
+ console: AnyElysia,
137
147
  ctx: ConsoleDomainContext,
138
148
  ): void {
139
149
  const observabilityStore = new DrizzleObservabilityStore(ctx.db, ctx.redis);
@@ -252,6 +262,9 @@ export function registerConsoleDomains(
252
262
  console.use(createUpdateRoutes({
253
263
  accessResolver: ctx.accessResolver,
254
264
  observabilityStore,
265
+ ...(ctx.shutdownCoordinator === undefined
266
+ ? {}
267
+ : { shutdownCoordinator: ctx.shutdownCoordinator }),
255
268
  }));
256
269
  console.use(createRemoteSupportRoutes({
257
270
  accessResolver: ctx.accessResolver,
@@ -271,6 +284,7 @@ export function registerConsoleDomains(
271
284
  accessResolver: ctx.accessResolver,
272
285
  auditSink: ctx.auditRecorder,
273
286
  providerRegistry: ctx.providerRegistry,
287
+ redis: ctx.redis,
274
288
  snapshotInvalidator: ctx.routeSnapshotService,
275
289
  resolveExportCredentials,
276
290
  // Without this, a custom provider only becomes dispatchable after a
@@ -384,8 +398,8 @@ export function registerConsoleDomains(
384
398
  // it is released when the last of those flows settles.
385
399
  const oauthCallbackListener = new OAuthCallbackListener({
386
400
  completer: {
387
- complete: (providerId, code, state) =>
388
- completeLogin(oauthConfig, providerId, code, state),
401
+ complete: (providerId, code, state, callbackParams) =>
402
+ completeLogin(oauthConfig, providerId, code, state, callbackParams),
389
403
  },
390
404
  });
391
405
  const oauthConfig: OAuthLoginConfig = {
@@ -54,13 +54,6 @@ export interface InferhubClientOptions {
54
54
  readonly now?: () => number;
55
55
  }
56
56
 
57
- export class InferhubRateLimited extends Error {
58
- constructor() {
59
- super("inferhub management rate limit reached");
60
- this.name = "InferhubRateLimited";
61
- }
62
- }
63
-
64
57
  /**
65
58
  * One management GET.
66
59
  *
@@ -20,7 +20,7 @@ import { decryptCredentialToString, encryptCredential, hashSecret } from "../../
20
20
  import type { CartethyiaDatabase } from "../../persistence/db-handle";
21
21
 
22
22
  /** Shape returned to the console: whether a key is set, and never the key. */
23
- export interface InferhubKeyStatus {
23
+ interface InferhubKeyStatus {
24
24
  readonly configured: boolean;
25
25
  /** Last four characters, so an operator can tell two keys apart. */
26
26
  readonly last4: string | null;