cartethyia 2.7.4 → 2.7.6

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 (595) hide show
  1. package/.env.example +5 -0
  2. package/README.md +18 -6
  3. package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js +899 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-DxjvUzSD.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-DRPavCdU.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
  42. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
  43. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js +56 -0
  44. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
  45. package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
  46. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  47. package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
  48. package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
  49. package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
  50. package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
  51. package/dist/dashboard/assets/assert-CidQVoNo.js +1 -0
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-DympBNq4.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  58. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  59. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  60. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  61. package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CxDw0lK6.js} +1 -1
  62. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  63. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  64. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  65. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  66. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  67. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +1 -0
  68. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  69. package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-DfS1ntiq.js} +1 -1
  70. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  71. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  72. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  73. package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-QqPul6sC.js} +1 -1
  74. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  75. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  76. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  77. package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
  78. package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
  79. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  80. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  81. package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-u7JPB5BX.js} +1 -1
  82. package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
  83. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  84. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  85. package/dist/dashboard/assets/{index-DBNPOfhV.js → index-Ko4dLRnV.js} +2 -2
  86. package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
  87. package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-CHJQwxLa.js} +1 -1
  88. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  89. package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BlmlizVV.js} +1 -1
  90. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  91. package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-Bz93I-yE.js} +1 -1
  92. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  93. package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Ml16KCfu.js} +1 -1
  94. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  95. package/dist/dashboard/assets/live-7_QpnYGu.js +1 -0
  96. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  97. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  98. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  99. package/dist/dashboard/assets/network-CuMDaTzT.js +1 -0
  100. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  101. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  102. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  103. package/dist/dashboard/assets/pagination-B5aOoweZ.js +1 -0
  104. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  105. package/dist/dashboard/assets/providers/zai.webp +0 -0
  106. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  107. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  108. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  109. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  110. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  111. package/dist/dashboard/assets/routing-fnCsxgNO.js +1 -0
  112. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  113. package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BHqpd-bg.js} +2 -2
  114. package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
  115. package/dist/dashboard/assets/settings-BxslsErn.js +1 -0
  116. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  117. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  118. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  119. package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-j7cXjgYX.js} +1 -1
  120. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  121. package/dist/dashboard/assets/{state-CkfdYWel.js → state-DHmEnLa2.js} +1 -1
  122. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  123. package/dist/dashboard/assets/{switch-SYm237HG.js → switch-DmZcyTIC.js} +1 -1
  124. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  125. package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-CbCP4w1o.js} +1 -1
  126. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  127. package/dist/dashboard/console-backgrounds.jpg +0 -0
  128. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  129. package/dist/dashboard/index.html +2 -2
  130. package/dist/dashboard/index.html.gz +0 -0
  131. package/dist/dashboard/precompressed-assets.json +60 -59
  132. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  133. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  134. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  135. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  136. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  137. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  138. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  139. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  140. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  141. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  142. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  143. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  144. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  145. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  146. package/package.json +4 -6
  147. package/scripts/cli/update.ts +15 -41
  148. package/src/boot/app.ts +58 -2
  149. package/src/boot/dependencies.ts +794 -732
  150. package/src/boot/lifecycle.ts +11 -12
  151. package/src/config/cooldowns.ts +34 -55
  152. package/src/config/network.ts +1 -1
  153. package/src/config/package-paths.ts +1 -1
  154. package/src/config/providers.ts +19 -14
  155. package/src/config/resources.ts +0 -5
  156. package/src/config/runtime.ts +2 -5
  157. package/src/config/spec.ts +33 -6
  158. package/src/config/usage.ts +27 -0
  159. package/src/console/api-keys/ban-constants.ts +38 -0
  160. package/src/console/api-keys/contracts.ts +71 -62
  161. package/src/console/api-keys/routes.ts +56 -24
  162. package/src/console/auth/access.ts +4 -4
  163. package/src/console/auth/account-reset.ts +1 -1
  164. package/src/console/auth/audit-recorder.ts +1 -1
  165. package/src/console/auth/lockout.ts +7 -3
  166. package/src/console/auth/row-coercion.ts +57 -12
  167. package/src/console/auth/session-resolver.ts +1 -1
  168. package/src/console/auth/session-service.ts +8 -2
  169. package/src/console/auth/session.ts +37 -31
  170. package/src/console/auth/setup-service.ts +4 -3
  171. package/src/console/auth/user-store.ts +1 -1
  172. package/src/console/backup/9router-map.ts +0 -3
  173. package/src/console/backup/contracts.ts +9 -9
  174. package/src/console/backup/export-endpoint.ts +5 -6
  175. package/src/console/backup/nine-router.ts +1 -7
  176. package/src/console/backup/routes.ts +29 -33
  177. package/src/console/backup/service.ts +468 -468
  178. package/src/console/backup/store.ts +47 -29
  179. package/src/console/backup/validate.ts +11 -1
  180. package/src/console/cli-tools/contracts.ts +43 -299
  181. package/src/console/cli-tools/fs-ops.ts +29 -0
  182. package/src/console/cli-tools/injectors/claude.ts +3 -3
  183. package/src/console/cli-tools/injectors/codex.ts +181 -181
  184. package/src/console/cli-tools/injectors/driver.ts +150 -247
  185. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  186. package/src/console/cli-tools/injectors/opencode.ts +176 -153
  187. package/src/console/cli-tools/routes.ts +7 -1
  188. package/src/console/cli-tools/service.ts +8 -7
  189. package/src/console/cli-tools/store.ts +2 -2
  190. package/src/console/console-router.ts +32 -0
  191. package/src/console/dashboard-assets.ts +9 -9
  192. package/src/console/domain-registration.ts +16 -2
  193. package/src/console/inferhub/client.ts +0 -7
  194. package/src/console/inferhub/key-store.ts +1 -1
  195. package/src/console/inferhub/normalize.ts +2 -2
  196. package/src/console/inferhub/routes.ts +1 -1
  197. package/src/console/inferhub/types.ts +1 -1
  198. package/src/console/observability/contracts.ts +7 -1
  199. package/src/console/observability/live.ts +31 -18
  200. package/src/console/observability/logs.ts +1 -1
  201. package/src/console/observability/sse.ts +62 -8
  202. package/src/console/observability/store.ts +23 -4
  203. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  204. package/src/console/providers/catalog/contracts.ts +39 -0
  205. package/src/console/providers/catalog/model-operations.ts +1 -1
  206. package/src/console/providers/catalog/provider-operations.ts +95 -17
  207. package/src/console/providers/catalog/public-model-store.ts +0 -0
  208. package/src/console/providers/catalog/routes.ts +27 -3
  209. package/src/console/providers/catalog/store.ts +147 -8
  210. package/src/console/providers/detail/routes.ts +1 -1
  211. package/src/console/providers/oauth/callback-listener.ts +100 -18
  212. package/src/console/providers/oauth/routes.ts +92 -13
  213. package/src/console/quota/account-quota-global.ts +41 -3
  214. package/src/console/quota/account-quota-shared.ts +10 -3
  215. package/src/console/quota/account-quota-tenant.ts +259 -66
  216. package/src/console/quota/daily-growth-job.ts +308 -0
  217. package/src/console/quota/native-identity.ts +2 -2
  218. package/src/console/quota/quota-view.ts +1 -1
  219. package/src/console/remote-support/routes.ts +1 -1
  220. package/src/console/remote-support/service.ts +2 -2
  221. package/src/console/routing/model/contracts.ts +1 -1
  222. package/src/console/routing/pools/contracts.ts +2 -2
  223. package/src/console/routing/pools/import-parse.ts +3 -3
  224. package/src/console/routing/pools/relay-deploy.ts +3 -3
  225. package/src/console/settings/contracts.ts +29 -2
  226. package/src/console/settings/store.ts +20 -0
  227. package/src/console/share/share-router.ts +100 -32
  228. package/src/console/share/share-stats.ts +11 -13
  229. package/src/console/share/share-usage.ts +1 -1
  230. package/src/console/shared/errors.ts +2 -2
  231. package/src/console/shared/object.ts +18 -0
  232. package/src/console/shared/read-through-cache.ts +4 -4
  233. package/src/console/shared/transaction.ts +14 -0
  234. package/src/console/system-prompt/contracts.ts +89 -12
  235. package/src/console/system-prompt/routes.ts +98 -45
  236. package/src/console/updates/apply-update.ts +244 -0
  237. package/src/console/updates/routes.ts +252 -97
  238. package/src/main.ts +11 -5
  239. package/src/network/http2-bidi.ts +1 -1
  240. package/src/network/ip-utils.ts +298 -0
  241. package/src/network/outbound-fetch.ts +1 -1
  242. package/src/network/pool/agent.ts +7 -6
  243. package/src/network/pool/byte-accounting.ts +1 -1
  244. package/src/network/pool/resolver.ts +16 -12
  245. package/src/network/pool/selector.ts +150 -136
  246. package/src/network/pool-health-machine.ts +1 -1
  247. package/src/network/rate-limit-verdict.ts +1 -1
  248. package/src/network/retry.ts +1 -1
  249. package/src/network/ssrf.ts +20 -71
  250. package/src/observability/event-log.ts +9 -2
  251. package/src/observability/event-query.ts +61 -291
  252. package/src/observability/log-sanitize.ts +1 -1
  253. package/src/observability/metrics.ts +4 -4
  254. package/src/observability/payload-capture.ts +6 -5
  255. package/src/observability/payload-store.ts +1 -1
  256. package/src/observability/runtime-metrics.ts +1 -1
  257. package/src/observability/telemetry-buffer.ts +19 -3
  258. package/src/observability/telemetry-reconciliation.ts +3 -3
  259. package/src/observability/token-speed.ts +1 -1
  260. package/src/persistence/connection-url.ts +1 -1
  261. package/src/persistence/db-handle.ts +1 -1
  262. package/src/persistence/db-pg.ts +2 -2
  263. package/src/persistence/db-sqlite.ts +3 -3
  264. package/src/persistence/dialect.ts +5 -1
  265. package/src/persistence/readiness.ts +1 -1
  266. package/src/persistence/redis.ts +1 -1
  267. package/src/persistence/schema.ts +121 -40
  268. package/src/persistence/shared-cache.ts +2 -2
  269. package/src/persistence/sort-order.ts +1 -1
  270. package/src/persistence/stores/api-key-store.ts +29 -2
  271. package/src/persistence/stores/share-store.ts +20 -8
  272. package/src/persistence/system-prompt-store.ts +63 -18
  273. package/src/persistence/tenant-preferences.ts +1 -1
  274. package/src/persistence/ttl-cache.ts +3 -3
  275. package/src/persistence/usage-flush.ts +7 -2
  276. package/src/protocol/canonical-model.ts +1 -1
  277. package/src/protocol/codecs.ts +6 -10
  278. package/src/protocol/dsml.ts +8 -125
  279. package/src/protocol/image-clamp.ts +2 -2
  280. package/src/protocol/reasoning-text.ts +1 -1
  281. package/src/protocol/reasoning.ts +7 -52
  282. package/src/protocol/registry.ts +50 -15
  283. package/src/protocol/request/chat.ts +46 -19
  284. package/src/protocol/request/codex.ts +1 -1
  285. package/src/protocol/request/messages.ts +46 -14
  286. package/src/protocol/request/responses.ts +19 -10
  287. package/src/protocol/response/chat.ts +25 -10
  288. package/src/protocol/response/codex.ts +1 -1
  289. package/src/protocol/response/messages.ts +1 -1
  290. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  291. package/src/protocol/response/responses.ts +1 -1
  292. package/src/protocol/sse-decoder.ts +50 -1
  293. package/src/protocol/stop-reason.ts +2 -2
  294. package/src/protocol/think-split.ts +347 -0
  295. package/src/protocol/translation/attachment-integrity.ts +3 -3
  296. package/src/protocol/translation/cache-controls.ts +8 -20
  297. package/src/protocol/translation/capabilities.ts +6 -6
  298. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  299. package/src/protocol/translation/dialect/inband.ts +39 -0
  300. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  301. package/src/protocol/translation/dialect/qwen.ts +114 -0
  302. package/src/protocol/translation/dialect/resolver.ts +83 -0
  303. package/src/protocol/translation/dialect/rules.ts +93 -0
  304. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  305. package/src/protocol/translation/dialect/types.ts +58 -0
  306. package/src/protocol/translation/quirks.ts +18 -4
  307. package/src/protocol/translation/thinking.ts +12 -252
  308. package/src/protocol/translation/tool-id.ts +3 -3
  309. package/src/protocol/translation/tool-repair.ts +1 -1
  310. package/src/protocol/upstream/post-json.ts +6 -1
  311. package/src/providers/adapters/compatible-adapter.ts +71 -4
  312. package/src/providers/authentication/jwt-validator.ts +0 -5
  313. package/src/providers/authentication/oauth-client.ts +254 -253
  314. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  315. package/src/providers/bundled-discovery-providers.ts +6 -30
  316. package/src/providers/configured-openai-providers.ts +82 -97
  317. package/src/providers/default-registry.ts +35 -37
  318. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  319. package/src/providers/discovery/discovery-types.ts +0 -1
  320. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  321. package/src/providers/discovery/probe-phases.ts +48 -13
  322. package/src/providers/discovery/probing-service.ts +6 -8
  323. package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
  324. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  325. package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -28
  326. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  327. package/src/providers/integrations/antigravity/antigravity.ts +22 -13
  328. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  329. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  330. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  331. package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
  332. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  333. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
  335. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  336. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
  337. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  338. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  339. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  340. package/src/providers/integrations/cline/cline.ts +1 -1
  341. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  342. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  343. package/src/providers/integrations/commandcode/commandcode.ts +75 -115
  344. package/src/providers/integrations/commandcode/quota.ts +131 -51
  345. package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
  346. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  347. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  348. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  349. package/src/providers/integrations/cursor/cursor.ts +35 -3
  350. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  351. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  352. package/src/providers/integrations/factory/factory.ts +9 -9
  353. package/src/providers/integrations/github/github-discovery.ts +70 -12
  354. package/src/providers/integrations/github/github-oauth.ts +184 -14
  355. package/src/providers/integrations/github/github.ts +134 -26
  356. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  357. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  358. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  359. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  360. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  361. package/src/providers/integrations/grok/grok.ts +86 -36
  362. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  363. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  364. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  365. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  366. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  367. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  368. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  369. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  370. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  371. package/src/providers/integrations/kiro/kiro.ts +80 -68
  372. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  373. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  374. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  375. package/src/providers/integrations/opencode/provider.ts +17 -24
  376. package/src/providers/integrations/qoder/qoder-catalog.ts +94 -11
  377. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  378. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  379. package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
  380. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  381. package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
  382. package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
  383. package/src/providers/integrations/qoder/qoder.ts +422 -71
  384. package/src/providers/integrations/shared/connect.ts +0 -54
  385. package/src/providers/integrations/shared/hash.ts +15 -0
  386. package/src/providers/integrations/shared/session-cache.ts +136 -0
  387. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  388. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  389. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  390. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  391. package/src/providers/integrations/trae/trae.ts +51 -8
  392. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  393. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  394. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  395. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  396. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  397. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  398. package/src/providers/operations/account-error-classification.ts +198 -133
  399. package/src/providers/operations/account-health-service.ts +31 -39
  400. package/src/providers/operations/account-reset-service.ts +58 -1
  401. package/src/providers/operations/byok-wire-profile.ts +19 -15
  402. package/src/providers/operations/cli-platform.ts +31 -5
  403. package/src/providers/operations/client-version-resolver.ts +4 -6
  404. package/src/providers/operations/client-versions.ts +10 -7
  405. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  406. package/src/providers/operations/provider-catalog-service.ts +18 -2
  407. package/src/providers/operations/provider-credential-service.ts +19 -2
  408. package/src/providers/provider-contracts.ts +18 -7
  409. package/src/providers/provider-metadata.ts +17 -2
  410. package/src/providers/provider-model-definition.ts +22 -1
  411. package/src/providers/provider-probe.ts +4 -2
  412. package/src/providers/provider-usage.ts +50 -19
  413. package/src/providers/quota/cache.ts +29 -0
  414. package/src/providers/quota/quota-contracts.ts +4 -0
  415. package/src/providers/quota/refresh.ts +27 -4
  416. package/src/providers/quota/snapshot.ts +94 -0
  417. package/src/providers/search/search-provider.ts +1 -3
  418. package/src/providers/search/search-providers.ts +2 -1
  419. package/src/security/abuse.ts +4 -4
  420. package/src/security/admission/service.ts +13 -6
  421. package/src/security/admission/ttl.ts +61 -61
  422. package/src/security/api-key-auth.ts +17 -3
  423. package/src/security/client-router-fingerprint.ts +4 -4
  424. package/src/security/credential-codec.ts +3 -3
  425. package/src/security/csrf.ts +2 -2
  426. package/src/security/ip-boundary.ts +16 -189
  427. package/src/security/model-access-rule.ts +1 -1
  428. package/src/security/outbound-headers.ts +18 -0
  429. package/src/shared/invoke-guard.ts +47 -0
  430. package/src/transport/contracts.ts +13 -4
  431. package/src/transport/dispatch/attempt-finalize.ts +70 -22
  432. package/src/transport/dispatch/attempt-loop.ts +22 -0
  433. package/src/transport/dispatch/capture-policy.ts +34 -37
  434. package/src/transport/dispatch/empty-stream.ts +23 -20
  435. package/src/transport/dispatch/generation.ts +25 -45
  436. package/src/transport/dispatch/native-shared.ts +127 -0
  437. package/src/transport/dispatch/proxy-request.ts +3 -1
  438. package/src/transport/dispatch/responses-compact.ts +25 -46
  439. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  440. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  441. package/src/transport/dispatch/streaming/stream.ts +7 -3
  442. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  443. package/src/transport/dispatch/systemone.ts +20 -48
  444. package/src/transport/dispatch/token-count.ts +41 -38
  445. package/src/transport/dispatch/websearch.ts +19 -45
  446. package/src/transport/drain-endpoint.ts +1 -1
  447. package/src/transport/failure-policy.ts +21 -1
  448. package/src/transport/guards/auth-guard.ts +0 -6
  449. package/src/transport/guards/body-policy.ts +3 -3
  450. package/src/transport/guards/error-lifecycle.ts +4 -0
  451. package/src/transport/guards/headroom-guard.ts +1 -1
  452. package/src/transport/guards/pipeline.ts +1 -1
  453. package/src/transport/guards/request-context.ts +12 -17
  454. package/src/transport/request/preparer.ts +286 -7
  455. package/src/transport/request/rtk/compress-request.ts +3 -3
  456. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  457. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  458. package/src/transport/request/state.ts +7 -13
  459. package/src/transport/request/system-prompt-injection.ts +74 -11
  460. package/src/transport/request/tenant-preferences.ts +22 -0
  461. package/src/transport/routing/candidate-index.ts +2 -2
  462. package/src/transport/routing/round-robin.ts +1 -1
  463. package/src/transport/routing/route-catalog.ts +17 -18
  464. package/src/transport/routing/route-model.ts +126 -33
  465. package/src/transport/routing/router.ts +159 -37
  466. package/src/transport/shutdown-notice.ts +2 -2
  467. package/src/transport/surface/adapters.ts +3 -3
  468. package/src/transport/surface/chat/encode.ts +7 -7
  469. package/src/transport/surface/chat/parse.ts +7 -7
  470. package/src/transport/surface/completion.ts +2 -2
  471. package/src/transport/surface/content-parts.ts +1 -1
  472. package/src/transport/surface/dialects.ts +2 -2
  473. package/src/transport/surface/messages/parse.ts +3 -3
  474. package/src/transport/surface/reasoning-summary.ts +9 -14
  475. package/src/transport/surface/responses/adapter.ts +1 -1
  476. package/src/transport/surface/responses/errors.ts +0 -9
  477. package/src/transport/vision-handoff-cache.ts +58 -0
  478. package/src/transport/vision-handoff.ts +431 -0
  479. package/src/workers/account-identity-sweep.ts +2 -2
  480. package/src/workers/buddy-growth-tasks.ts +392 -346
  481. package/src/workers/daily-checkin.ts +102 -49
  482. package/src/workers/maintenance-lease.ts +2 -35
  483. package/src/workers/oauth-refresh-sweep.ts +8 -1
  484. package/src/workers/quota-refresh-sweep.ts +120 -82
  485. package/src/workers/scheduler.ts +67 -4
  486. package/src/workers/sweep-runner.ts +24 -5
  487. package/src/workers/zcode-gift-claim.ts +108 -0
  488. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  489. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  490. package/dist/dashboard/assets/BannedPage-ChG5svFb.js +0 -1
  491. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  492. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +0 -1
  493. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  494. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +0 -1
  495. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  496. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
  497. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  498. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
  499. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  500. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +0 -1
  501. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  502. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
  503. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  504. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js +0 -1
  505. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  506. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  507. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
  508. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  509. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
  510. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  511. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  512. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  513. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
  514. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  515. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  516. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
  517. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  518. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
  519. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  520. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +0 -1
  521. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  522. package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
  523. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  524. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  525. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  526. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  527. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
  528. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  529. package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
  530. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  531. package/dist/dashboard/assets/app-BayTTy01.js +0 -9
  532. package/dist/dashboard/assets/app-BayTTy01.js.gz +0 -0
  533. package/dist/dashboard/assets/app-a159k0ub.css +0 -2
  534. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  535. package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
  536. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  537. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  538. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  539. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  540. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
  541. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  542. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  543. package/dist/dashboard/assets/dialog-8fiE6tec.js +0 -1
  544. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  545. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  546. package/dist/dashboard/assets/entry-BSAsYsmV.js +0 -1
  547. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  548. package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
  549. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  550. package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
  551. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  552. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  553. package/dist/dashboard/assets/github-badge-CPK47xQx.js +0 -1
  554. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  555. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  556. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  557. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  558. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  559. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  560. package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
  561. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  562. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  563. package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
  564. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  565. package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
  566. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  567. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  568. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  569. package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
  570. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  571. package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
  572. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  573. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  574. package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
  575. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  576. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  577. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  578. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  579. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  580. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  581. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  582. package/src/console/cli-tools/injectors/cline.ts +0 -110
  583. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  584. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  585. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  586. package/src/console/cli-tools/injectors/droid.ts +0 -96
  587. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  588. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  589. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  590. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
  591. package/src/network/response-headers.ts +0 -39
  592. package/src/protocol/response/dsml.ts +0 -38
  593. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  594. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  595. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -4,12 +4,13 @@ import { buildProductionDeps } from "./dependencies";
4
4
  import type { ProductionDeps } from "./dependencies";
5
5
  import { withTimeout } from "./timeout";
6
6
  import { resolveShutdownDrainWindowMs } from "../config/runtime";
7
+ import { log } from "../observability/logger";
7
8
 
8
9
  export type ShutdownReason = "SIGTERM" | "SIGINT" | "reload" | "update";
9
- export type ShutdownState =
10
+ type ShutdownState =
10
11
  "idle" | "stop_admitting" | "bounded_drain_wait" | "flush_telemetry" | "close_pools" | "done";
11
12
 
12
- export interface ShutdownHooks {
13
+ interface ShutdownHooks {
13
14
  flushTelemetry?: (deadlineMs: number) => Promise<void>;
14
15
  closePools?: () => Promise<void>;
15
16
  abortInflight?: () => void;
@@ -107,7 +108,10 @@ export class ShutdownCoordinator {
107
108
  if (this.inflight.size > 0) {
108
109
  try {
109
110
  this.hooks.abortInflight?.();
110
- } catch {
111
+ } catch (error) {
112
+ // A failed abort must not be silent: it leaks in-flight work into
113
+ // close_pools, which then closes pools under live requests.
114
+ log.warn("[shutdown] abort in-flight failed", error as Error);
111
115
  }
112
116
  }
113
117
  await this.waitForDrain(Date.now() + this.drainTimeoutMs);
@@ -156,14 +160,9 @@ export class ShutdownCoordinator {
156
160
  const remaining = Math.max(0, deadlineMs - Date.now());
157
161
  // No budget left: invoking the hook would start work with zero deadline
158
162
  // that withTimeout immediately cancels; skip straight to pool close.
159
- if (remaining <= 0 || !this.hooks.flushTelemetry) {
160
- if (remaining > 0 && !this.hooks.flushTelemetry) {
161
- // bounded small delay to simulate flush
162
- const wait = Math.min(remaining, 5);
163
- await new Promise<void>((r) => setTimeout(r, wait));
164
- }
165
- return;
166
- }
163
+ // Without a hook there is nothing to flush either — both cases return
164
+ // here and the drain proceeds to pool close.
165
+ if (remaining <= 0 || !this.hooks.flushTelemetry) return;
167
166
  try {
168
167
  await withTimeout(
169
168
  this.hooks.flushTelemetry(deadlineMs),
@@ -189,7 +188,7 @@ export class ShutdownCoordinator {
189
188
  }
190
189
  }
191
190
 
192
- export interface ElyxiaServer {
191
+ interface ElyxiaServer {
193
192
  stop(closeActiveConnections?: boolean): unknown;
194
193
  }
195
194
 
@@ -4,63 +4,67 @@
4
4
 
5
5
  import { CONFIG_SPEC, readInt } from "./spec";
6
6
 
7
- let _rateLimitCooldown: number | undefined;
7
+ /** The spec row shape every cooldown resolver reads. */
8
+ type CooldownSpecEntry = {
9
+ readonly kind: "int";
10
+ readonly default: number;
11
+ readonly min: number;
12
+ readonly max: number;
13
+ };
14
+
15
+ /** Shared cache keyed by env-var name, so one resolver per knob stays warm. */
16
+ const cooldownCache = new Map<string, number>();
17
+
18
+ function cachedCooldownMs(name: string, entry: CooldownSpecEntry): number {
19
+ const cached = cooldownCache.get(name);
20
+ if (cached !== undefined) return cached;
21
+ const value = readInt(name, entry);
22
+ cooldownCache.set(name, value);
23
+ return value;
24
+ }
25
+
8
26
  /** Fallback cooldown for a provider rate limit (default 15m). */
9
27
  export function resolveAccountRateLimitCooldownMs(): number {
10
- if (_rateLimitCooldown === undefined)
11
- _rateLimitCooldown = readInt(
28
+ return cachedCooldownMs(
12
29
  "CARTETHYIA_ACCOUNT_RATE_LIMIT_COOLDOWN_MS",
13
30
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_RATE_LIMIT_COOLDOWN_MS,
14
31
  );
15
- return _rateLimitCooldown;
16
32
  }
17
33
 
18
- let _quotaCooldown: number | undefined;
19
34
  /**
20
35
  * Fallback cooldown for provider quota exhaustion when the error states no
21
36
  * reset window (default 1h). A provider-specific rule (xAI Grok Build's
22
37
  * rolling 24-hour free-tier window) overrides it inside the classifier.
23
38
  */
24
39
  export function resolveAccountQuotaCooldownMs(): number {
25
- if (_quotaCooldown === undefined)
26
- _quotaCooldown = readInt(
40
+ return cachedCooldownMs(
27
41
  "CARTETHYIA_ACCOUNT_QUOTA_COOLDOWN_MS",
28
42
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_QUOTA_COOLDOWN_MS,
29
43
  );
30
- return _quotaCooldown;
31
44
  }
32
45
 
33
- let _modelCapacityCooldown: number | undefined;
34
46
  /** Fallback cooldown for model-capacity overload (default 2m). */
35
47
  export function resolveAccountModelCapacityCooldownMs(): number {
36
- if (_modelCapacityCooldown === undefined)
37
- _modelCapacityCooldown = readInt(
48
+ return cachedCooldownMs(
38
49
  "CARTETHYIA_ACCOUNT_MODEL_CAPACITY_COOLDOWN_MS",
39
50
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_MODEL_CAPACITY_COOLDOWN_MS,
40
51
  );
41
- return _modelCapacityCooldown;
42
52
  }
43
53
 
44
- let _transientCooldown: number | undefined;
45
54
  /** Backoff for a transient 5xx/network fault, recorded as `cooldown` (default 30s). */
46
55
  export function resolveAccountTransientCooldownMs(): number {
47
- if (_transientCooldown === undefined)
48
- _transientCooldown = readInt(
56
+ return cachedCooldownMs(
49
57
  "CARTETHYIA_ACCOUNT_TRANSIENT_COOLDOWN_MS",
50
58
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_TRANSIENT_COOLDOWN_MS,
51
59
  );
52
- return _transientCooldown;
53
60
  }
54
61
 
55
- let _unclassifiedCooldown: number | undefined;
56
62
  /** Backoff for a failure no rule matched, recorded as `cooldown` (default 1m). */
57
63
  export function resolveAccountUnclassifiedCooldownMs(): number {
58
- if (_unclassifiedCooldown === undefined)
59
- _unclassifiedCooldown = readInt(
64
+ return cachedCooldownMs(
60
65
  "CARTETHYIA_ACCOUNT_UNCLASSIFIED_COOLDOWN_MS",
61
66
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_UNCLASSIFIED_COOLDOWN_MS,
62
67
  );
63
- return _unclassifiedCooldown;
64
68
  }
65
69
 
66
70
  /**
@@ -71,25 +75,21 @@ export function resolveAccountUnclassifiedCooldownMs(): number {
71
75
  * window: an account that recovers on its own must not sit parked for a day
72
76
  * because a burst of 5xx happened to arrive while it was already cooling.
73
77
  */
74
- let _escalationMaxCooldown: number | undefined;
75
78
  export function resolveAccountCooldownEscalationMaxMs(): number {
76
- if (_escalationMaxCooldown === undefined)
77
- _escalationMaxCooldown = readInt(
79
+ return cachedCooldownMs(
78
80
  "CARTETHYIA_ACCOUNT_COOLDOWN_ESCALATION_MAX_MS",
79
81
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_COOLDOWN_ESCALATION_MAX_MS,
80
82
  );
81
- return _escalationMaxCooldown;
82
83
  }
83
84
 
84
- let _poolCooldown: number | undefined;
85
85
  /** How long a proxy pool stays `cooldown` after a transport fault (default 2m). */
86
86
  export function resolvePoolCooldownMs(): number {
87
- if (_poolCooldown === undefined)
88
- _poolCooldown = readInt("CARTETHYIA_POOL_COOLDOWN_MS", CONFIG_SPEC.CARTETHYIA_POOL_COOLDOWN_MS);
89
- return _poolCooldown;
87
+ return cachedCooldownMs(
88
+ "CARTETHYIA_POOL_COOLDOWN_MS",
89
+ CONFIG_SPEC.CARTETHYIA_POOL_COOLDOWN_MS,
90
+ );
90
91
  }
91
92
 
92
- let _authRejectedCooldown: number | undefined;
93
93
  /**
94
94
  * Backoff for an auth rejection that names no revocation (default 5m).
95
95
  *
@@ -107,15 +107,12 @@ let _authRejectedCooldown: number | undefined;
107
107
  * rotation immediately, with no backoff to wait out.
108
108
  */
109
109
  export function resolveAccountAuthRejectedCooldownMs(): number {
110
- if (_authRejectedCooldown === undefined)
111
- _authRejectedCooldown = readInt(
110
+ return cachedCooldownMs(
112
111
  "CARTETHYIA_ACCOUNT_AUTH_REJECTED_COOLDOWN_MS",
113
112
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_AUTH_REJECTED_COOLDOWN_MS,
114
113
  );
115
- return _authRejectedCooldown;
116
114
  }
117
115
 
118
- let _policyBlockCooldown: number | undefined;
119
116
  /**
120
117
  * Base backoff for the buddy policy/channel block (default 5m).
121
118
  *
@@ -132,15 +129,12 @@ let _policyBlockCooldown: number | undefined;
132
129
  * while a single bad prompt costs five minutes.
133
130
  */
134
131
  export function resolveAccountPolicyBlockCooldownMs(): number {
135
- if (_policyBlockCooldown === undefined)
136
- _policyBlockCooldown = readInt(
132
+ return cachedCooldownMs(
137
133
  "CARTETHYIA_ACCOUNT_POLICY_BLOCK_COOLDOWN_MS",
138
134
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_POLICY_BLOCK_COOLDOWN_MS,
139
135
  );
140
- return _policyBlockCooldown;
141
136
  }
142
137
 
143
- let _disabledRecovery: number | undefined;
144
138
  /**
145
139
  * How long an **automatically** disabled account stays out of rotation (default 24h).
146
140
  *
@@ -160,27 +154,22 @@ let _disabledRecovery: number | undefined;
160
154
  * only reproduces the refusal. Set to `0` to make an automatic disable terminal.
161
155
  */
162
156
  export function resolveAccountDisabledRecoveryMs(): number {
163
- if (_disabledRecovery === undefined)
164
- _disabledRecovery = readInt(
157
+ return cachedCooldownMs(
165
158
  "CARTETHYIA_ACCOUNT_DISABLED_RECOVERY_MS",
166
159
  CONFIG_SPEC.CARTETHYIA_ACCOUNT_DISABLED_RECOVERY_MS,
167
160
  );
168
- return _disabledRecovery;
169
161
  }
170
162
 
171
- let _poolProviderRateLimitCooldown: number | undefined;
172
163
  /**
173
164
  * Fallback cooldown for a provider-scoped egress 429 when the upstream named no
174
165
  * window (default 1h). See `CARTETHYIA_POOL_PROVIDER_RATE_LIMIT_COOLDOWN_MS`.
175
166
  * An upstream `retryAfterMs` always wins over this.
176
167
  */
177
168
  export function resolvePoolProviderRateLimitCooldownMs(): number {
178
- if (_poolProviderRateLimitCooldown === undefined)
179
- _poolProviderRateLimitCooldown = readInt(
169
+ return cachedCooldownMs(
180
170
  "CARTETHYIA_POOL_PROVIDER_RATE_LIMIT_COOLDOWN_MS",
181
171
  CONFIG_SPEC.CARTETHYIA_POOL_PROVIDER_RATE_LIMIT_COOLDOWN_MS,
182
172
  );
183
- return _poolProviderRateLimitCooldown;
184
173
  }
185
174
 
186
175
  /**
@@ -188,15 +177,5 @@ export function resolvePoolProviderRateLimitCooldownMs(): number {
188
177
  * cooldown env-vars between test cases.
189
178
  */
190
179
  export function resetCooldownCacheForTests(): void {
191
- _rateLimitCooldown = undefined;
192
- _quotaCooldown = undefined;
193
- _modelCapacityCooldown = undefined;
194
- _transientCooldown = undefined;
195
- _unclassifiedCooldown = undefined;
196
- _escalationMaxCooldown = undefined;
197
- _poolCooldown = undefined;
198
- _poolProviderRateLimitCooldown = undefined;
199
- _authRejectedCooldown = undefined;
200
- _policyBlockCooldown = undefined;
201
- _disabledRecovery = undefined;
180
+ cooldownCache.clear();
202
181
  }
@@ -24,7 +24,7 @@ export type TrustedProxyMode = "disabled" | "trusted" | "platform";
24
24
  * naming CIDRs. It cannot be mistaken for an address, so the list form stays
25
25
  * unambiguous.
26
26
  */
27
- export const TRUSTED_PROXY_PLATFORM_TOKEN = "platform";
27
+ const TRUSTED_PROXY_PLATFORM_TOKEN = "platform";
28
28
 
29
29
  /** Trusted reverse-proxy boundary used for forwarded client addresses. */
30
30
  export interface TrustedProxyBoundary {
@@ -6,7 +6,7 @@ import { resolve } from "node:path";
6
6
  * virtual `import.meta.dir`, so deployments can point this at the shipped
7
7
  * assets directory explicitly.
8
8
  */
9
- export function resolvePackageRoot(
9
+ function resolvePackageRoot(
10
10
  moduleDir: string,
11
11
  configuredRoot: string | undefined,
12
12
  ): string {
@@ -4,20 +4,7 @@
4
4
  * public origin.
5
5
  */
6
6
 
7
- import { CONFIG_SPEC, readInt, readOptionalText, readRequired, readText } from "./spec";
8
-
9
- /** Reads and normalizes the public OAuth origin. */
10
- export function requirePublicOrigin(): string {
11
- return readRequired("CARTETHYIA_PUBLIC_ORIGIN", CONFIG_SPEC.CARTETHYIA_PUBLIC_ORIGIN).replace(
12
- /\/+$/,
13
- "",
14
- );
15
- }
16
-
17
- /** Builds the fixed OAuth callback URL for a provider id. */
18
- export function oauthCallbackUrl(providerId: string): string {
19
- return `${requirePublicOrigin()}/console/api/providers/${providerId}/oauth/callback`;
20
- }
7
+ import { CONFIG_SPEC, readInt, readOptionalText, readText } from "./spec";
21
8
 
22
9
  /**
23
10
  * Browser-authorize redirect URI for a provider.
@@ -103,3 +90,21 @@ export function resolveGithubEnterpriseDomain(): string {
103
90
  return "";
104
91
  }
105
92
  }
93
+
94
+ export type GithubCopilotMode = "opencode-copilot" | "vscode-client-real";
95
+
96
+ /**
97
+ * Which GitHub Copilot wire identity the adapter uses. Defaults to
98
+ * `opencode-copilot` (raw GitHub OAuth token + minimal OpenCode headers),
99
+ * which is the proven-most-stable path (one token, no mint expiry). The
100
+ * `vscode-client-real` mode matches the VS Code reference client exactly but
101
+ * requires a freshly minted Copilot token.
102
+ */
103
+ export function resolveGithubCopilotMode(): GithubCopilotMode {
104
+ const raw = readText(
105
+ "CARTETHYIA_GITHUB_COPILOT_MODE",
106
+ CONFIG_SPEC.CARTETHYIA_GITHUB_COPILOT_MODE,
107
+ ).trim().toLowerCase();
108
+ if (raw === "vscode-client-real") return "vscode-client-real";
109
+ return "opencode-copilot";
110
+ }
@@ -21,7 +21,6 @@ import { CONFIG_SPEC, readOptionalInt } from "./spec";
21
21
  /** Used when no limit is discoverable at all (native dev, macOS, Windows). */
22
22
  export const FALLBACK_MEMORY_LIMIT_BYTES = 512 * 1024 * 1024;
23
23
 
24
-
25
24
  /**
26
25
  * How many copies of a request body are resident at once.
27
26
  *
@@ -30,15 +29,12 @@ export const FALLBACK_MEMORY_LIMIT_BYTES = 512 * 1024 * 1024;
30
29
  * collection lags rather than keeping them to one. Budgeting one copy halves
31
30
  * the real peak and lets the process admit twice the concurrency it can hold.
32
31
  */
33
- export const REQUEST_BODY_TRANSIENT_COPIES = 2;
34
32
 
35
33
  /** Share of the memory limit all in-flight request bodies together may hold. */
36
- export const REQUEST_BODY_BUDGET_FRACTION = 0.25;
37
34
 
38
35
  /** Share of the memory limit kept free for allocation spikes and GC slack. */
39
36
  export const MEMORY_HEADROOM_FRACTION = 0.2;
40
37
 
41
-
42
38
  /**
43
39
  * Bytes kept free below the memory limit.
44
40
  *
@@ -51,7 +47,6 @@ export function deriveMemoryHeadroomBytes(memoryLimitBytes: number): number {
51
47
  return Math.ceil(memoryLimitBytes * MEMORY_HEADROOM_FRACTION);
52
48
  }
53
49
 
54
-
55
50
  /**
56
51
  * Slack added on top of every key's concurrency limit.
57
52
  *
@@ -2,8 +2,7 @@
2
2
  * HTTP listener, dashboard runtime, and graceful-shutdown drain resolvers.
3
3
  */
4
4
 
5
- import { CONFIG_SPEC, readInt, readOptionalText } from "./spec";
6
- import { resolvePackagePath } from "./package-paths";
5
+ import { CONFIG_SPEC, readInt, readOptionalText, readText } from "./spec";
7
6
 
8
7
  /** Resolves the HTTP listener port from the process environment. */
9
8
  export function resolvePort(): number {
@@ -12,9 +11,7 @@ export function resolvePort(): number {
12
11
 
13
12
  /** Resolves the dashboard static asset directory. */
14
13
  export function resolveDashboardDist(): string {
15
- const raw = process.env.DASHBOARD_DIST?.trim();
16
- if (!raw) return resolvePackagePath("dist", "dashboard");
17
- return raw;
14
+ return readText("DASHBOARD_DIST", CONFIG_SPEC.DASHBOARD_DIST);
18
15
  }
19
16
 
20
17
  /**
@@ -188,6 +188,13 @@ export const CONFIG_SPEC = {
188
188
  min: 1 * 1024 * 1024,
189
189
  max: 16 * 1024 * 1024,
190
190
  },
191
+ // Input-token accounting for usage display. Providers disagree on whether
192
+ // `input_tokens` already includes cached tokens: OpenAI/DeepSeek report the
193
+ // inclusive total with a cached subset, while Anthropic reports fresh-only
194
+ // with cache reads separate. `inclusive` (default) folds cache into input so
195
+ // every provider reads alike — IN is always the whole prompt and CACHED its
196
+ // subset. `as-is` keeps the raw upstream semantics.
197
+ CARTETHYIA_USAGE_INPUT_MODE: { kind: "text", default: "inclusive" },
191
198
 
192
199
  // Upstream request timeout + retry backoff
193
200
  //
@@ -297,6 +304,20 @@ export const CONFIG_SPEC = {
297
304
  * an operator on one has no other way to point the login at it.
298
305
  */
299
306
  CARTETHYIA_GITHUB_ENTERPRISE_DOMAIN: { kind: "text", default: "" },
307
+ /**
308
+ * Which wire identity the GitHub Copilot Auto/chat path presents to the
309
+ * upstream:
310
+ *
311
+ * - `opencode-copilot` (default): the long-lived GitHub OAuth token + minimal
312
+ * OpenCode headers. One token, no mint step, no short-lived minted-token
313
+ * expiry. This is the most stable in practice.
314
+ * - `vscode-client-real`: a freshly minted Copilot token + the full VS Code
315
+ * reference headers. Matches the VS Code client exactly, but requires the
316
+ * minted token (expires ~25 min) and the reference identity.
317
+ */
318
+ CARTETHYIA_GITHUB_COPILOT_MODE: { kind: "text", default: "opencode-copilot" },
319
+ // Only the literal true opts active ZCode accounts into daily gift claims.
320
+ CARTETHYIA_ZCODE_AUTO_CLAIM: { kind: "text", default: "false" },
300
321
  /**
301
322
  * Free-tier OpenCode ids the listing still advertises but upstream refuses.
302
323
  * Replaces the bundled list outright; the single token `none` trusts the
@@ -330,8 +351,10 @@ export function readText(name: string, entry: TextConfigEntry): string {
330
351
  }
331
352
 
332
353
  /** Reads an optional string; empty or whitespace reads as absent. */
333
- export function readOptionalText(name: string, entry: OptionalTextConfigEntry): string | undefined {
334
- void entry;
354
+ export function readOptionalText(name: string, entry: ConfigEntry): string | undefined {
355
+ if (entry.kind !== "optional-text") {
356
+ throw new Error(`${name} must be declared optional-text in CONFIG_SPEC`);
357
+ }
335
358
  const raw = process.env[name]?.trim();
336
359
  return raw && raw.length > 0 ? raw : undefined;
337
360
  }
@@ -355,14 +378,18 @@ export function readRequired(name: string, entry: RequiredTextConfigEntry): stri
355
378
  }
356
379
 
357
380
  /** Reads a flag: enabled unless the literal `"false"` is set. */
358
- export function readFlag(name: string, entry: FlagConfigEntry): boolean {
359
- void entry;
381
+ export function readFlag(name: string, entry: ConfigEntry): boolean {
382
+ if (entry.kind !== "flag") {
383
+ throw new Error(`${name} must be declared flag in CONFIG_SPEC`);
384
+ }
360
385
  return process.env[name] !== "false";
361
386
  }
362
387
 
363
388
  /** Reads a comma-separated list, dropping empty entries. */
364
- export function readList(name: string, entry: ListConfigEntry): readonly string[] | undefined {
365
- void entry;
389
+ export function readList(name: string, entry: ConfigEntry): readonly string[] | undefined {
390
+ if (entry.kind !== "list") {
391
+ throw new Error(`${name} must be declared list in CONFIG_SPEC`);
392
+ }
366
393
  const entries = process.env[name]
367
394
  ?.split(",")
368
395
  .map((value) => value.trim())
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Usage input-token accounting mode.
3
+ *
4
+ * Providers disagree on whether `input_tokens` already includes cached tokens.
5
+ * OpenAI/DeepSeek report the inclusive total with a cached subset; Anthropic
6
+ * reports fresh-only with cache reads (and writes) separate. `normalizeUsage`
7
+ * reads this mode to decide whether to fold cache into input so every provider
8
+ * reads alike (`inclusive`, the default) or to keep the raw upstream semantics
9
+ * (`as-is`).
10
+ */
11
+
12
+ import { CONFIG_SPEC, readText } from "./spec";
13
+
14
+ export type UsageInputMode = "inclusive" | "as-is";
15
+
16
+ /** Resolves the operator's chosen accounting mode; defaults to inclusive. */
17
+ export function resolveUsageInputMode(): UsageInputMode {
18
+ const raw = readText(
19
+ "CARTETHYIA_USAGE_INPUT_MODE",
20
+ CONFIG_SPEC.CARTETHYIA_USAGE_INPUT_MODE,
21
+ )
22
+ .trim()
23
+ .toLowerCase();
24
+ if (raw === "inclusive") return "inclusive";
25
+ if (raw === "as-is") return "as-is";
26
+ throw new Error('CARTETHYIA_USAGE_INPUT_MODE must be "inclusive" or "as-is"');
27
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Pure ban dropdown constants (reasons + durations), kept free of any `node:*`
3
+ * import so the dashboard can import them without evaluating Node-only modules.
4
+ *
5
+ * The dashboard mirrors these into its UI; the console API validates against
6
+ * the same lists. They used to live in `contracts.ts`, which also imports
7
+ * `hashSecret` (→ `security/crypto` → `node:crypto`) and `randomBytes` — so a
8
+ * browser bundle that imported any value from `contracts.ts` dragged the whole
9
+ * Node crypto chain along and blew up in the client (module externalized).
10
+ * Moving the pure lists here keeps one source of truth for the values while
11
+ * keeping the browser bundle clean.
12
+ */
13
+
14
+ /** Ban reasons offered by the console dropdown. The first two are the operator's
15
+ * own: "Instant Ban — Suka suka Gw" for the arbitrary ban, and a template for
16
+ * suspicious traffic. The rest are generic, and an operator can still type a
17
+ * custom reason — the dropdown is a convenience, not a closed set. */
18
+ export const API_KEY_BAN_REASONS: readonly { readonly value: string; readonly label: string }[] = [
19
+ { value: "instant_arbitrary", label: "Instant Ban — Suka suka Gw" },
20
+ { value: "traffic_suspicious", label: "Your traffic looks suspicious" },
21
+ { value: "abuse", label: "Abuse of the gateway" },
22
+ { value: "policy_violation", label: "Policy violation" },
23
+ { value: "compromised", label: "Key may be compromised" },
24
+ { value: "quota_exceeded", label: "Quota abused" },
25
+ { value: "other", label: "Other / custom" },
26
+ ] as const;
27
+
28
+ /** Ban durations the console offers, in whole minutes. `null` is permanent.
29
+ * Mirrored by the dashboard (`dashboard/src/lib/ban-durations.ts`) so the UI
30
+ * and the API agree on one list. */
31
+ export const BAN_DURATION_CHOICES: readonly { readonly minutes: number | null; readonly label: string }[] = [
32
+ { minutes: 60, label: "1 hour" },
33
+ { minutes: 6 * 60, label: "6 hours" },
34
+ { minutes: 12 * 60, label: "12 hours" },
35
+ { minutes: 24 * 60, label: "1 day" },
36
+ { minutes: 7 * 24 * 60, label: "7 days" },
37
+ { minutes: null, label: "Permanent" },
38
+ ] as const;