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
@@ -57,7 +57,7 @@ const BAN_ROUTE_KEY = "#ban";
57
57
  * `banThreshold` is both the identity-wide escalation threshold and the
58
58
  * highest count either ring must keep observable.
59
59
  */
60
- export interface IpAbuseAttempt {
60
+ interface IpAbuseAttempt {
61
61
  readonly identity: string;
62
62
  readonly route: string;
63
63
  readonly now: number;
@@ -67,7 +67,7 @@ export interface IpAbuseAttempt {
67
67
  }
68
68
 
69
69
  /** What one admission step decided. */
70
- export interface IpAbuseOutcome {
70
+ interface IpAbuseOutcome {
71
71
  /** The identity was already banned; nothing was incremented. */
72
72
  readonly banned: boolean;
73
73
  /** Attempts now in this route's window, including this one. `0` when banned. */
@@ -115,13 +115,13 @@ export interface IpAbuseStore {
115
115
  checkAndRecord(attempt: IpAbuseAttempt): Promise<IpAbuseOutcome>;
116
116
  }
117
117
 
118
- export interface IpAbuseProtectionServiceOptions {
118
+ interface IpAbuseProtectionServiceOptions {
119
119
  readonly maxRequestsPerWindow?: number;
120
120
  readonly banThreshold?: number;
121
121
  readonly banDurationMs?: number;
122
122
  }
123
123
 
124
- export interface InMemoryIpAbuseStoreOptions {
124
+ interface InMemoryIpAbuseStoreOptions {
125
125
  readonly windowMs?: number;
126
126
  readonly clock?: () => number;
127
127
  /** Distinct (identity, route) keys tracked before the oldest is evicted. */
@@ -399,7 +399,7 @@ export class IpAbuseProtectionService {
399
399
  readonly signal?: AbortSignal;
400
400
  }): Promise<void> {
401
401
  if (input.signal?.aborted) {
402
- throw new GatewayError("admission_unavailable", 503, "The abuse check never ran because the request was already cancelled.", {
402
+ throw new GatewayError("admission_unavailable", 503, "The abuse check never ran because the request was already cancelled (request {requestId}). Send it again whenever ready 🙃", {
403
403
  reason: "admission-unavailable",
404
404
  });
405
405
  }
@@ -436,7 +436,7 @@ export class IpAbuseProtectionService {
436
436
 
437
437
  if (outcome.banned) {
438
438
  metrics.cartethyia_ip_abuse_refusals_total.inc(1, { reason: "ip-banned" });
439
- throw new GatewayError("quota_exceeded", 429, "This address is temporarily banned for too many failed requests. Wait for the ban to lift, then slow down.", {
439
+ throw new GatewayError("rate_limited", 429, "This address is temporarily banned for too many failed requests (request {requestId}). Wait for the ban to lift, then slow down. You've maxed this window — pace yourself ⏳", {
440
440
  // Distinguishes this from the rate-limited 429 below and from an API
441
441
  // key's own budget. It used to be "admission-unavailable", which is
442
442
  // the label for an *unreachable* store — so every refusal from this
@@ -454,7 +454,7 @@ export class IpAbuseProtectionService {
454
454
 
455
455
  if (outcome.count > this.maxRequestsPerWindow) {
456
456
  metrics.cartethyia_ip_abuse_refusals_total.inc(1, { reason: "ip-rate-limited" });
457
- throw new GatewayError("quota_exceeded", 429, "This address is sending requests faster than the abuse limit allows. Back off and retry after the window rolls over.", {
457
+ throw new GatewayError("rate_limited", 429, "This address is sending requests faster than the abuse limit allows (request {requestId}). Back off and retry after the window rolls over. You've maxed this window — pace yourself ⏳", {
458
458
  reason: "ip-rate-limited",
459
459
  ip,
460
460
  route: input.route,
@@ -464,7 +464,7 @@ export class IpAbuseProtectionService {
464
464
  }
465
465
  } catch (err) {
466
466
  if (err instanceof GatewayError) throw err;
467
- throw new GatewayError("admission_unavailable", 503, "The abuse-tracking store is unreachable, so requests from this address cannot be checked. Retry shortly.", {
467
+ throw new GatewayError("admission_unavailable", 503, "The abuse-tracking store is unreachable, so requests from this address cannot be checked (request {requestId}). Retry shortly. The bouncer stepped out — come back shortly 🚪", {
468
468
  reason: "admission-unavailable",
469
469
  cause: (err as Error).message,
470
470
  });
@@ -19,26 +19,26 @@ const REASON_META: Record<
19
19
  }
20
20
  > = {
21
21
  "rpm-exhausted": {
22
- message: "This key has used its requests-per-minute allowance. Wait for the window to roll over, or raise the key's rpm limit.",
23
- code: "quota_exceeded",
22
+ message: "This key has used its requests-per-minute allowance (request {requestId}). Wait for the window to roll over, or raise the key's rpm limit. You've maxed this window — pace yourself ⏳",
23
+ code: "rate_limited",
24
24
  status: 429,
25
25
  metricLabel: "rpm_exhausted",
26
26
  },
27
27
  "daily-token-limit": {
28
- message: "This key has used today's token allowance. It resets at the start of the next day, or raise the key's daily limit.",
29
- code: "quota_exceeded",
28
+ message: "This key has used today's token allowance (request {requestId}). It resets at the start of the next day, or raise the key's daily limit. Pace yourself — it resets tomorrow ⏳",
29
+ code: "rate_limited",
30
30
  status: 429,
31
31
  metricLabel: "daily",
32
32
  },
33
33
  "monthly-token-limit": {
34
- message: "This key has used this month's token allowance. It resets at the start of the next month, or raise the key's monthly limit.",
35
- code: "quota_exceeded",
34
+ message: "This key has used this month's token allowance (request {requestId}). It resets at the start of the next month, or raise the key's monthly limit. Saving up for next month? It resets then ⏳",
35
+ code: "rate_limited",
36
36
  status: 429,
37
37
  metricLabel: "monthly",
38
38
  },
39
39
  "lifetime-token-budget": {
40
- message: "This key has spent its lifetime token budget. Raise the budget, or issue a new key.",
41
- code: "quota_exceeded",
40
+ message: "This key has spent its lifetime token budget (request {requestId}). Raise the budget, or issue a new key. The piggy bank is empty — top it up or mint a new key 🐷",
41
+ code: "rate_limited",
42
42
  status: 429,
43
43
  metricLabel: "lifetime",
44
44
  },
@@ -47,27 +47,27 @@ const REASON_META: Record<
47
47
  // max-inflight. The two used to be indistinguishable and both named the
48
48
  // provider, sending operators to the wrong setting after a rejection. The
49
49
  // `details` carry the limit so a client can tell which one fired.
50
- message: "This API key is already serving its maximum number of concurrent requests. Retry shortly, or raise the key's concurrency limit.",
50
+ message: "This API key is already serving its maximum number of concurrent requests (request {requestId}). Retry shortly, or raise the key's concurrency limit. It'll free up in a moment 🌊",
51
51
  code: "capacity_exhausted",
52
52
  status: 429,
53
53
  metricLabel: "concurrency",
54
54
  },
55
55
  "tenant-capacity-exhausted": {
56
- message: "This tenant is already serving its maximum number of concurrent requests. Retry shortly, or raise the tenant's concurrency limit.",
56
+ message: "This tenant is already serving its maximum number of concurrent requests (request {requestId}). Retry shortly, or raise the tenant's concurrency limit. The tenant is maxed out right now — chill 🏠",
57
57
  code: "tenant_capacity_exhausted",
58
58
  status: 429,
59
59
  metricLabel: "tenant_capacity",
60
60
  },
61
61
  "model-not-allowed": {
62
- message: "This key is not allowed to use this model under its allowlist. Add the model to the key, or use one it already allows.",
63
- code: "model_not_found",
64
- status: 404,
62
+ message: "This key is not allowed to use this model under its allowlist (request {requestId}). Add the model to the key, or use one it already allows. The door's locked for this one — check the allowlist 🔒",
63
+ code: "model_not_allowed",
64
+ status: 403,
65
65
  metricLabel: "model_not_allowed",
66
66
  },
67
67
  "model-denied": {
68
- message: "This key's denylist blocks this model. Remove the model from the denylist, or use a different model.",
69
- code: "model_not_found",
70
- status: 404,
68
+ message: "This key's denylist blocks this model (request {requestId}). Remove the model from the denylist, or use a different model. This one's on the banned list — pick another 🚫",
69
+ code: "model_not_allowed",
70
+ status: 403,
71
71
  metricLabel: "model_not_allowed",
72
72
  },
73
73
  "admission-unavailable": {
@@ -76,7 +76,7 @@ const REASON_META: Record<
76
76
  // `invalid_counter`, `unknown_reservation`, `invalid_actual_usage`). The
77
77
  // second is not an outage, so the text must not claim one — it names the
78
78
  // effect the client can act on, and the diagnostic stays in `details.reason`.
79
- message: "The gateway could not admit this request. Retry shortly; if it persists, check the instance's Redis or coordination backend.",
79
+ message: "The gateway could not admit this request (request {requestId}). Retry shortly; if it persists, check the instance's Redis or coordination backend. The bouncer stepped out — come back shortly 🚪",
80
80
  code: "admission_unavailable",
81
81
  status: 503,
82
82
  metricLabel: "admission_unavailable",
@@ -12,7 +12,7 @@ import { admissionMetricLabel, reasonToGatewayError } from "./reasons";
12
12
 
13
13
  /** Persists reconciled lifetime token consumption for an API key. Injected so
14
14
  * the in-memory admission service stays decoupled from Drizzle/Postgres. */
15
- export type LifetimeUsagePersister = (input: {
15
+ type LifetimeUsagePersister = (input: {
16
16
  apiKeyId: string;
17
17
  delta: number;
18
18
  }) => Promise<void>;
@@ -23,7 +23,7 @@ export type LifetimeUsagePersister = (input: {
23
23
  * counter store only when it is about to seed a missing lifetime counter, so
24
24
  * the ≤3s-stale snapshot value cannot freeze a low baseline in place. Injected
25
25
  * so the admission module stays decoupled from Drizzle/Postgres. */
26
- export type FreshLifetimeConsumedReader = (apiKeyId: string) => Promise<number | undefined>;
26
+ type FreshLifetimeConsumedReader = (apiKeyId: string) => Promise<number | undefined>;
27
27
 
28
28
 
29
29
  export class ApiKeyAdmissionService {
@@ -1,61 +1,61 @@
1
- /**
2
- * Lease and counter lifetimes, and the calendar bucket keys they key on.
3
- *
4
- * These live together because they are one arithmetic problem: a counter
5
- * must outlive the lease that charges it, and a lease key must outlive the
6
- * horizon the sweeper reads. Splitting them across files is how those
7
- * invariants silently break, so the reasoning stays in one place.
8
- */
9
- export const LEASE_TTL_MS = 3600_000;
10
-
11
- /**
12
- * The lease key's own Redis TTL is deliberately LONGER than the `expires_at`
13
- * horizon the lease hash records.
14
- *
15
- * `expires_at` is the moment the sweeper becomes allowed to reclaim the lease.
16
- * If the key TTL equalled that horizon, Redis would evict the hash at exactly
17
- * the moment `reapIfExpired` wanted to read it: `HGET state` would return nil,
18
- * the sweep would skip it, and a crash between reserve and release would strand
19
- * the held concurrency / tenant-concurrency slot for as long as the counter
20
- * keeps being refreshed — every later reserve re-arms the counter's own TTL, so
21
- * a key still in use never recovers its leaked slot. The grace window keeps the
22
- * hash readable for several sweep intervals past the horizon, so the recovery
23
- * path actually runs.
24
- *
25
- * Exported so the invariant is asserted directly: a lease key must outlive the
26
- * horizon it records by more than one sweep interval (`sweepLeases` runs every
27
- * 30s, wired in `runtime/dependencies.ts`).
28
- */
29
- const LEASE_TTL_GRACE_SECONDS = 120;
30
- /** Seconds after which a lease hash is reapable (`expires_at` horizon). */
31
- export const LEASE_REAP_HORIZON_SECONDS = Math.ceil(LEASE_TTL_MS / 1000);
32
- /** Seconds the lease hash itself lives; must exceed the reap horizon. */
33
- export const LEASE_KEY_TTL_SECONDS = LEASE_REAP_HORIZON_SECONDS + LEASE_TTL_GRACE_SECONDS;
34
-
35
- /**
36
- * TTLs for the token-budget counters, in seconds.
37
- *
38
- * Daily lives just past two days (a day bucket plus slack to cover a request
39
- * straddling midnight); monthly and lifetime share one 35-day window — long
40
- * enough that a month bucket is never evicted mid-month, and it is the *only*
41
- * thing bounding `admission:lifetime:*`, which has no natural bucket to expire
42
- * on. Every writer below must therefore carry its own TTL: a plain `SET`
43
- * without one creates a key that outlives every bucket it feeds.
44
- */
45
- export const DAILY_COUNTER_TTL_SECONDS = 172800;
46
- export const MONTHLY_COUNTER_TTL_SECONDS = 3024000;
47
- export const LIFETIME_COUNTER_TTL_SECONDS = 3024000;
48
- /** RPM window plus slack; concurrency slots are held for the request duration. */
49
- export const RPM_WINDOW_TTL_SECONDS = 65;
50
- // Must exceed the lease's own lifetime (`LEASE_TTL_MS` + grace), otherwise a
51
- // request held longer than this lets its concurrency counter expire underneath
52
- // a still-live lease and a later reserve INCRs from zero. Derived rather than
53
- // hard-coded so raising the lease TTL cannot silently reopen the hole.
54
- export const CONCURRENCY_TTL_SECONDS = LEASE_KEY_TTL_SECONDS;
55
-
56
- export function dailyBucket(now: number): string {
57
- return new Date(now).toISOString().slice(0, 10);
58
- }
59
- export function monthlyBucket(now: number): string {
60
- return new Date(now).toISOString().slice(0, 7);
61
- }
1
+ /**
2
+ * Lease and counter lifetimes, and the calendar bucket keys they key on.
3
+ *
4
+ * These live together because they are one arithmetic problem: a counter
5
+ * must outlive the lease that charges it, and a lease key must outlive the
6
+ * horizon the sweeper reads. Splitting them across files is how those
7
+ * invariants silently break, so the reasoning stays in one place.
8
+ */
9
+ export const LEASE_TTL_MS = 3600_000;
10
+
11
+ /**
12
+ * The lease key's own Redis TTL is deliberately LONGER than the `expires_at`
13
+ * horizon the lease hash records.
14
+ *
15
+ * `expires_at` is the moment the sweeper becomes allowed to reclaim the lease.
16
+ * If the key TTL equalled that horizon, Redis would evict the hash at exactly
17
+ * the moment `reapIfExpired` wanted to read it: `HGET state` would return nil,
18
+ * the sweep would skip it, and a crash between reserve and release would strand
19
+ * the held concurrency / tenant-concurrency slot for as long as the counter
20
+ * keeps being refreshed — every later reserve re-arms the counter's own TTL, so
21
+ * a key still in use never recovers its leaked slot. The grace window keeps the
22
+ * hash readable for several sweep intervals past the horizon, so the recovery
23
+ * path actually runs.
24
+ *
25
+ * Exported so the invariant is asserted directly: a lease key must outlive the
26
+ * horizon it records by more than one sweep interval (`sweepLeases` runs every
27
+ * 30s, wired in `runtime/dependencies.ts`).
28
+ */
29
+ const LEASE_TTL_GRACE_SECONDS = 120;
30
+ /** Seconds after which a lease hash is reapable (`expires_at` horizon). */
31
+ export const LEASE_REAP_HORIZON_SECONDS = Math.ceil(LEASE_TTL_MS / 1000);
32
+ /** Seconds the lease hash itself lives; must exceed the reap horizon. */
33
+ export const LEASE_KEY_TTL_SECONDS = LEASE_REAP_HORIZON_SECONDS + LEASE_TTL_GRACE_SECONDS;
34
+
35
+ /**
36
+ * TTLs for the token-budget counters, in seconds.
37
+ *
38
+ * Daily lives just past two days (a day bucket plus slack to cover a request
39
+ * straddling midnight); monthly and lifetime share one 35-day window — long
40
+ * enough that a month bucket is never evicted mid-month, and it is the *only*
41
+ * thing bounding `admission:lifetime:*`, which has no natural bucket to expire
42
+ * on. Every writer below must therefore carry its own TTL: a plain `SET`
43
+ * without one creates a key that outlives every bucket it feeds.
44
+ */
45
+ export const DAILY_COUNTER_TTL_SECONDS = 172800;
46
+ export const MONTHLY_COUNTER_TTL_SECONDS = 3024000;
47
+ export const LIFETIME_COUNTER_TTL_SECONDS = 3024000;
48
+ /** RPM window plus slack; concurrency slots are held for the request duration. */
49
+ export const RPM_WINDOW_TTL_SECONDS = 65;
50
+ // Must exceed the lease's own lifetime (`LEASE_TTL_MS` + grace), otherwise a
51
+ // request held longer than this lets its concurrency counter expire underneath
52
+ // a still-live lease and a later reserve INCRs from zero. Derived rather than
53
+ // hard-coded so raising the lease TTL cannot silently reopen the hole.
54
+ export const CONCURRENCY_TTL_SECONDS = LEASE_KEY_TTL_SECONDS;
55
+
56
+ export function dailyBucket(now: number): string {
57
+ return new Date(now).toISOString().slice(0, 10);
58
+ }
59
+ export function monthlyBucket(now: number): string {
60
+ return new Date(now).toISOString().slice(0, 7);
61
+ }
@@ -118,7 +118,7 @@ function freezeList(
118
118
  return arr;
119
119
  }
120
120
 
121
- export function freezeSnapshot(s: ApiKeyAuthorizationSnapshot): ApiKeyAuthorizationSnapshot {
121
+ function freezeSnapshot(s: ApiKeyAuthorizationSnapshot): ApiKeyAuthorizationSnapshot {
122
122
  const model_list = freezeList(s.model_list);
123
123
  const model_access_mode: ApiKeyModelAccessMode =
124
124
  s.model_access_mode === "blacklist" ? "blacklist" : "whitelist";
@@ -239,7 +239,7 @@ export interface ResolvedApiKey {
239
239
  * indistinguishable — distinguishing them would let a caller confirm that a
240
240
  * guessed token once existed — so there is no variant carrying a reason.
241
241
  */
242
- const INVALID_KEY_MESSAGE = "Invalid API key. Check the key you are sending, or create a new one in API Keys and send it as: Authorization: Bearer <key>.";
242
+ const INVALID_KEY_MESSAGE = "Invalid API key (request {requestId}). Check the key you are sending, or create a new one in API Keys and send it as: Authorization: Bearer <key>. Wrong key, right door — double-check and come back 🔑";
243
243
 
244
244
  export function unknownApiKeyError(): GatewayError {
245
245
  return new GatewayError("authentication_failed", 401, INVALID_KEY_MESSAGE);
@@ -258,7 +258,7 @@ export function modelsListApiKeyError(): GatewayError {
258
258
  return new GatewayError(
259
259
  "authentication_failed",
260
260
  401,
261
- "Invalid API key. Rotate the default Cartethyia API key in API Keys and send the new key as: Authorization: Bearer <key>.",
261
+ "Invalid API key (request {requestId}). Rotate the default Cartethyia API key in API Keys and send the new key as: Authorization: Bearer <key>. Wrong key, right door — rotate and try again 🔑",
262
262
  );
263
263
  }
264
264
 
@@ -279,12 +279,12 @@ export function requestToken(headers: Headers | Record<string, string>): string
279
279
  // *different* credentials stay a conflict — accepting whichever came first
280
280
  // would silently decide the request's identity.
281
281
  if (bearerMatch?.[1] === apiKey) return apiKey;
282
- throw new GatewayError("invalid_request", 400, "The request sends two different credentials. Send exactly one key, either as Authorization: Bearer <key> or as the api-key header.");
282
+ throw new GatewayError("invalid_request", 400, "The request sends two different credentials (request {requestId}). Send exactly one key, either as Authorization: Bearer <key> or as the api-key header. Pick one key and stick with it 🤝");
283
283
  }
284
284
  if (hasApiKey) return apiKey;
285
285
  const token = bearerMatch?.[1];
286
286
  if (token === undefined)
287
- throw new GatewayError("invalid_request", 401, "The request carries no usable credential. Send the key as: Authorization: Bearer <key>.");
287
+ throw new GatewayError("authentication_failed", 401, "The request carries no usable credential (request {requestId}). Send the key as: Authorization: Bearer <key>. We need a key to let you in 🔑");
288
288
  return token;
289
289
  }
290
290
 
@@ -363,6 +363,12 @@ export async function resolveApiKeyAuthorization(
363
363
  // keep the issued row values forever. Reading the parent here makes denylist /
364
364
  // one-time / recurring edits apply on the next cache miss.
365
365
  const policy = parent ?? row;
366
+ // Share-template concurrency scope decides whether the family shares one
367
+ // admission counter (default `family`) or each recipient has its own
368
+ // (`per_key`). In `family` mode the child participates in the parent's
369
+ // counter namespace; in `per_key` mode the child is its own admission
370
+ // identity and carries its own cap.
371
+ const perKeyConcurrency = parent !== undefined && row.concurrencyScope === "per_key";
366
372
  // Only a `share` parent can have children, and children are the only thing
367
373
  // the SUM below can find. Every other key ran an aggregate that was certain
368
374
  // to return 0 — one extra Postgres round-trip on the auth path for nothing.
@@ -381,8 +387,10 @@ export async function resolveApiKeyAuthorization(
381
387
  api_key_id: row.id,
382
388
  tenant_id: row.tenantId,
383
389
  // Family quota / concurrency share one admission counter namespace so two
384
- // recipients cannot each burn a full lifetime/daily budget.
385
- ...(parent ? { admission_identity: parent.id } : {}),
390
+ // recipients cannot each burn a full lifetime/daily budget. In `per_key`
391
+ // concurrency mode the child is its own admission identity so its cap and
392
+ // counter are independent.
393
+ ...(parent && !perKeyConcurrency ? { admission_identity: parent.id } : {}),
386
394
  ...(policy.modelList ? { model_list: policy.modelList as string[] } : {}),
387
395
  model_access_mode: policy.modelAccessMode ?? "whitelist",
388
396
  ...(policy.clientRouterDenylist
@@ -393,7 +401,11 @@ export async function resolveApiKeyAuthorization(
393
401
  ...(policy.monthlyTokenLimit != null ? { monthly_tokens: policy.monthlyTokenLimit } : {}),
394
402
  ...(policy.lifetimeTokenBudget != null ? { lifetime_token_budget: policy.lifetimeTokenBudget } : {}),
395
403
  lifetime_tokens_consumed: consumed,
396
- ...(policy.maxConcurrentRequests != null ? { max_concurrent: policy.maxConcurrentRequests } : {}),
404
+ // `per_key` mode: the child carries its own cap (copied at issue); family
405
+ // mode inherits the parent's cap.
406
+ ...((perKeyConcurrency ? row.maxConcurrentRequests : policy.maxConcurrentRequests) != null
407
+ ? { max_concurrent: perKeyConcurrency ? row.maxConcurrentRequests : policy.maxConcurrentRequests }
408
+ : {}),
397
409
  scopes,
398
410
  });
399
411
 
@@ -21,7 +21,7 @@ import { getHeader as readRecordHeader } from "../protocol/canonical-model";
21
21
  * `id` is the stable token an operator stores in a key's denylist, so it is
22
22
  * part of the persisted contract and must not be renamed casually.
23
23
  */
24
- export interface ClientRouterDefinition {
24
+ interface ClientRouterDefinition {
25
25
  readonly id: string;
26
26
  /** Human label for the dashboard. */
27
27
  readonly label: string;
@@ -40,7 +40,7 @@ export interface ClientRouterDefinition {
40
40
  * safe for a uniquely named header; a header whose value distinguishes it must
41
41
  * name a matcher instead.
42
42
  */
43
- export interface ClientRouterSignal {
43
+ interface ClientRouterSignal {
44
44
  /** Header name, lowercase. */
45
45
  readonly field: string;
46
46
  /** Human description shown when the signal matches. */
@@ -114,14 +114,14 @@ export const CLIENT_ROUTERS: readonly ClientRouterDefinition[] = [
114
114
  const LEGACY_CLIENT_ROUTER_IDS: Readonly<Record<string, string>> = { omniroute: "9router" };
115
115
 
116
116
  /** A signal that matched, with the product it belongs to. */
117
- export interface MatchedClientSignal {
117
+ interface MatchedClientSignal {
118
118
  readonly field: string;
119
119
  readonly description: string;
120
120
  /** The observed value, capped, for the operator's audit trail. */
121
121
  readonly value: string;
122
122
  }
123
123
 
124
- export interface ClientRouterMatch {
124
+ interface ClientRouterMatch {
125
125
  readonly routerId: string;
126
126
  readonly label: string;
127
127
  readonly signals: readonly MatchedClientSignal[];
@@ -22,7 +22,7 @@ import { isRecord } from "../protocol/codecs";
22
22
  const TEXT_DECODER = new TextDecoder();
23
23
 
24
24
  /** Decodes a stored secret: UTF-8 bytes or a string, trimmed. */
25
- export function decodeSecretText(secret: Uint8Array | string): string {
25
+ function decodeSecretText(secret: Uint8Array | string): string {
26
26
  const raw = typeof secret === "string" ? secret : TEXT_DECODER.decode(secret);
27
27
  return raw.trim();
28
28
  }
@@ -48,7 +48,7 @@ function fieldString(record: Record<string, unknown>, key: string): string {
48
48
  }
49
49
 
50
50
  /** `{accessToken, orgId?}` — the Kilo Code envelope (org scoping is optional). */
51
- export interface KiloEnvelope {
51
+ interface KiloEnvelope {
52
52
  readonly accessToken: string;
53
53
  /** Organization the gateway scopes requests to; absent when the profile omits one. */
54
54
  readonly orgId?: string;
@@ -79,7 +79,7 @@ export function decodeKiloCredential(secret: Uint8Array | string): KiloEnvelope
79
79
  }
80
80
 
81
81
  /** `{oauthAccessToken, apiKey}` — the Muse Code (Meta) envelope. */
82
- export interface MuseEnvelope {
82
+ interface MuseEnvelope {
83
83
  readonly oauthAccessToken: string;
84
84
  readonly apiKey: string;
85
85
  }
@@ -16,7 +16,7 @@ import { isRecord } from "../protocol/codecs";
16
16
  * but cannot read the cookie value, so it cannot forge the header.
17
17
  */
18
18
  export const CSRF_COOKIE_NAME = "csrf_token";
19
- export const CSRF_HEADER_NAME = "x-csrf-token";
19
+ const CSRF_HEADER_NAME = "x-csrf-token";
20
20
 
21
21
  /**
22
22
  * Name of the session cookie whose presence gates CSRF validation in
@@ -30,7 +30,7 @@ export const SESSION_COOKIE_NAME = "session_token";
30
30
  * `SessionCookiePolicy` structurally satisfies this (extra fields are fine),
31
31
  * so call sites keep passing their existing policy object unchanged.
32
32
  */
33
- export interface CsrfCookiePolicy {
33
+ interface CsrfCookiePolicy {
34
34
  readonly maxAge: number;
35
35
  readonly sameSite: "Lax" | "Strict" | "None";
36
36
  readonly secure: boolean;