cartethyia 2.7.3 → 2.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (625) hide show
  1. package/.env.example +2 -0
  2. package/README.md +17 -5
  3. package/dist/dashboard/assets/{BannedPage-2TJD37Hb.js → BannedPage-Cj15GsMp.js} +1 -1
  4. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
  5. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +1 -0
  6. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolDetailPage-xefJNRmJ.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
  8. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
  9. package/dist/dashboard/assets/{CliToolsPage-Rj9iHQ3F.js → CliToolsPage-BIccZmeL.js} +1 -1
  10. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
  11. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +1 -0
  12. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
  13. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js +1 -0
  14. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
  15. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js +1 -0
  16. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js +656 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
  19. package/dist/dashboard/assets/{LoginPage-C4w7vea-.js → LoginPage-DkXb6dx-.js} +1 -1
  20. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BtPcAfot.js → ModelPicker-DnQPSIA8.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
  31. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js +9 -0
  32. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
  37. package/dist/dashboard/assets/{SetupPage-BQS0Rx_u.js → SetupPage-WTa0sktC.js} +1 -1
  38. package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-TP7voAQ0.js → StudioPage-BfAb5-o_.js} +3 -3
  40. package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
  41. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js +56 -0
  42. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
  43. package/dist/dashboard/assets/api-keys-l29JROPv.js +1 -0
  44. package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
  45. package/dist/dashboard/assets/app--PJWq8_C.css +2 -0
  46. package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-C0YYuZJ4.js → assert-C0K-c4eo.js} +1 -1
  48. package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-B_DMpMJN.js → badge-DfbhQU4k.js} +1 -1
  50. package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-DMrMPmth.js → banner-BllT4LcF.js} +1 -1
  52. package/dist/dashboard/assets/banner-BllT4LcF.js.gz +0 -0
  53. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  54. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  55. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  56. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  57. package/dist/dashboard/assets/{card-Be5Uzamx.js → card-CtkX66Wd.js} +1 -1
  58. package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
  59. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  60. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  61. package/dist/dashboard/assets/{cli-tools-muFRphDu.js → cli-tools-CQXVMn4P.js} +1 -1
  62. package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
  63. package/dist/dashboard/assets/{clipboard-button-DOfrVmsi.js → clipboard-button-BQqBQd2n.js} +1 -1
  64. package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
  65. package/dist/dashboard/assets/{dialog-C9omdjQt.js → dialog-BEK7KP0H.js} +1 -1
  66. package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
  67. package/dist/dashboard/assets/{drawer-Bm8WKaGY.js → drawer-BrTEZ8zu.js} +1 -1
  68. package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
  69. package/dist/dashboard/assets/entry-CHWxbS56.js +1 -0
  70. package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
  71. package/dist/dashboard/assets/{entry-q5HwZ8nN.js → entry-EBHJ3DrE.js} +1 -1
  72. package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
  73. package/dist/dashboard/assets/entry-LCS85hiq.js +4 -0
  74. package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
  75. package/dist/dashboard/assets/{formatters-BTScrQpe.js → formatters-BAACA727.js} +1 -1
  76. package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
  77. package/dist/dashboard/assets/{github-badge-Orjuzemr.js → github-badge-YSCE4UC2.js} +1 -1
  78. package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
  79. package/dist/dashboard/assets/{index-cPrX5vn6.js → index-FQlj0HUT.js} +2 -2
  80. package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
  81. package/dist/dashboard/assets/{inline-Dvux8w-0.js → inline-C4gU5iOL.js} +1 -1
  82. package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
  83. package/dist/dashboard/assets/{input-CU1Rgf3p.js → input-BHHX_Tmm.js} +1 -1
  84. package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
  85. package/dist/dashboard/assets/{layout-C_7A6H55.js → layout-CajrYUnD.js} +1 -1
  86. package/dist/dashboard/assets/{layout-C_7A6H55.js.gz → layout-CajrYUnD.js.gz} +0 -0
  87. package/dist/dashboard/assets/{list-row-CzFvogbj.js → list-row-Bx2I7XUe.js} +1 -1
  88. package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
  89. package/dist/dashboard/assets/live-DNNqRbj2.js +1 -0
  90. package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
  91. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +1 -0
  92. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
  93. package/dist/dashboard/assets/{mutation-JJGQm8TD.js → mutation-Rr0TIvcj.js} +1 -1
  94. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  95. package/dist/dashboard/assets/network-C5UBACrJ.js +1 -0
  96. package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
  97. package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
  98. package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
  99. package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
  100. package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
  101. package/dist/dashboard/assets/{query-keys-CLaNz8Xz.js → query-keys-BloKtaXJ.js} +1 -1
  102. package/dist/dashboard/assets/query-keys-BloKtaXJ.js.gz +0 -0
  103. package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
  104. package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
  105. package/dist/dashboard/assets/{routing-BEH32QOC.js → routing-in0f_IfK.js} +1 -1
  106. package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
  107. package/dist/dashboard/assets/{select-B3iTetHN.js → select-BLULNqTp.js} +2 -2
  108. package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
  109. package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
  110. package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
  111. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  112. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  113. package/dist/dashboard/assets/{stack-KrOrm7JZ.js → stack-D2lIR0tg.js} +1 -1
  114. package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
  115. package/dist/dashboard/assets/{state-DLS7IDMy.js → state-DTARjfiW.js} +1 -1
  116. package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
  117. package/dist/dashboard/assets/{switch-42ItvbAs.js → switch-c0oPSnqW.js} +1 -1
  118. package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
  119. package/dist/dashboard/assets/{useMutation-Dmnfh1Ue.js → useMutation-m8WGNPrz.js} +1 -1
  120. package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
  121. package/dist/dashboard/console-backgrounds.jpg +0 -0
  122. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  123. package/dist/dashboard/index.html +2 -2
  124. package/dist/dashboard/index.html.gz +0 -0
  125. package/dist/dashboard/precompressed-assets.json +59 -57
  126. package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +9 -10
  127. package/migrations/full-postgres/0032_add_provider_pool_accounts.sql +53 -0
  128. package/migrations/full-postgres/0033_add_api_key_ban.sql +9 -0
  129. package/migrations/full-postgres/0034_add_api_key_ban_until.sql +7 -0
  130. package/migrations/full-postgres/0035_align_pool_account_status_enum.sql +21 -0
  131. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  132. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  133. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  134. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  135. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  136. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  137. package/migrations/lite-sqlite3/0027_qoder_identity_genuine_seed.sql +9 -10
  138. package/migrations/lite-sqlite3/0032_add_provider_pool_accounts.sql +44 -0
  139. package/migrations/lite-sqlite3/0033_add_api_key_ban.sql +8 -0
  140. package/migrations/lite-sqlite3/0034_add_api_key_ban_until.sql +5 -0
  141. package/migrations/lite-sqlite3/0035_align_pool_account_status_enum.sql +6 -0
  142. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  143. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  144. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  145. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  146. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  147. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  148. package/package.json +4 -5
  149. package/scripts/cli/update.ts +15 -41
  150. package/src/boot/app.ts +67 -10
  151. package/src/boot/dependencies.ts +786 -732
  152. package/src/boot/lifecycle.ts +11 -12
  153. package/src/config/cooldowns.ts +34 -55
  154. package/src/config/network.ts +8 -4
  155. package/src/config/package-paths.ts +1 -1
  156. package/src/config/providers.ts +13 -14
  157. package/src/config/resources.ts +0 -5
  158. package/src/config/runtime.ts +2 -5
  159. package/src/config/spec.ts +26 -6
  160. package/src/console/api-keys/ban-constants.ts +38 -0
  161. package/src/console/api-keys/contracts.ts +92 -31
  162. package/src/console/api-keys/routes.ts +131 -6
  163. package/src/console/audit/routes.ts +3 -3
  164. package/src/console/auth/access.ts +4 -4
  165. package/src/console/auth/account-reset.ts +5 -5
  166. package/src/console/auth/audit-recorder.ts +1 -1
  167. package/src/console/auth/lockout.ts +7 -3
  168. package/src/console/auth/row-coercion.ts +57 -12
  169. package/src/console/auth/session-resolver.ts +1 -1
  170. package/src/console/auth/session-service.ts +8 -2
  171. package/src/console/auth/session.ts +40 -34
  172. package/src/console/auth/setup-service.ts +4 -3
  173. package/src/console/auth/user-store.ts +1 -1
  174. package/src/console/backup/9router-map.ts +0 -3
  175. package/src/console/backup/contracts.ts +11 -9
  176. package/src/console/backup/export-endpoint.ts +11 -12
  177. package/src/console/backup/nine-router.ts +1 -7
  178. package/src/console/backup/routes.ts +32 -36
  179. package/src/console/backup/service.ts +468 -468
  180. package/src/console/backup/store.ts +47 -29
  181. package/src/console/backup/validate.ts +11 -1
  182. package/src/console/cli-tools/contracts.ts +7 -7
  183. package/src/console/cli-tools/injectors/cline.ts +110 -110
  184. package/src/console/cli-tools/injectors/codex.ts +181 -181
  185. package/src/console/cli-tools/injectors/copilot.ts +108 -108
  186. package/src/console/cli-tools/injectors/driver.ts +247 -247
  187. package/src/console/cli-tools/injectors/jcode.ts +115 -115
  188. package/src/console/cli-tools/injectors/openclaw.ts +161 -161
  189. package/src/console/cli-tools/injectors/opencode.ts +153 -153
  190. package/src/console/cli-tools/routes.ts +4 -4
  191. package/src/console/cli-tools/service.ts +1 -1
  192. package/src/console/cli-tools/store.ts +2 -2
  193. package/src/console/console-router-guards.ts +2 -2
  194. package/src/console/console-router.ts +36 -4
  195. package/src/console/dashboard-assets.ts +9 -9
  196. package/src/console/data-management/routes.ts +3 -3
  197. package/src/console/domain-registration.ts +18 -4
  198. package/src/console/inferhub/client.ts +0 -7
  199. package/src/console/inferhub/key-store.ts +1 -1
  200. package/src/console/inferhub/normalize.ts +2 -2
  201. package/src/console/inferhub/routes.ts +1 -1
  202. package/src/console/inferhub/types.ts +1 -1
  203. package/src/console/observability/contracts.ts +5 -1
  204. package/src/console/observability/live.ts +34 -21
  205. package/src/console/observability/logs.ts +4 -4
  206. package/src/console/observability/performance.ts +3 -3
  207. package/src/console/observability/routes.ts +3 -3
  208. package/src/console/observability/sse.ts +62 -8
  209. package/src/console/observability/store.ts +36 -20
  210. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  211. package/src/console/providers/catalog/contracts.ts +82 -22
  212. package/src/console/providers/catalog/model-operations.ts +1 -1
  213. package/src/console/providers/catalog/provider-operations.ts +110 -17
  214. package/src/console/providers/catalog/public-model-store.ts +0 -0
  215. package/src/console/providers/catalog/routes.ts +30 -6
  216. package/src/console/providers/catalog/store-helpers.ts +349 -326
  217. package/src/console/providers/catalog/store.ts +1662 -1292
  218. package/src/console/providers/detail/routes.ts +4 -4
  219. package/src/console/providers/oauth/callback-listener.ts +100 -18
  220. package/src/console/providers/oauth/routes.ts +95 -16
  221. package/src/console/quota/account-quota-global.ts +41 -3
  222. package/src/console/quota/account-quota-shared.ts +10 -3
  223. package/src/console/quota/account-quota-tenant.ts +285 -67
  224. package/src/console/quota/account-test-egress.ts +4 -4
  225. package/src/console/quota/daily-growth-job.ts +308 -0
  226. package/src/console/quota/native-identity.ts +2 -2
  227. package/src/console/quota/quota-view.ts +1 -1
  228. package/src/console/remote-support/routes.ts +1 -1
  229. package/src/console/remote-support/service.ts +2 -2
  230. package/src/console/routing/model/contracts.ts +1 -1
  231. package/src/console/routing/model/routes.ts +3 -3
  232. package/src/console/routing/pools/contracts.ts +13 -10
  233. package/src/console/routing/pools/import-parse.ts +3 -3
  234. package/src/console/routing/pools/operations.ts +14 -7
  235. package/src/console/routing/pools/probe-verdict.ts +8 -3
  236. package/src/console/routing/pools/relay-deploy.ts +12 -12
  237. package/src/console/routing/pools/routes.ts +3 -3
  238. package/src/console/routing/pools/store.ts +21 -1
  239. package/src/console/settings/contracts.ts +29 -2
  240. package/src/console/settings/routes.ts +3 -3
  241. package/src/console/settings/store.ts +20 -0
  242. package/src/console/share/share-router.ts +112 -44
  243. package/src/console/share/share-stats.ts +109 -39
  244. package/src/console/share/share-usage.ts +1 -1
  245. package/src/console/shared/errors.ts +2 -2
  246. package/src/console/shared/object.ts +18 -0
  247. package/src/console/shared/read-through-cache.ts +42 -6
  248. package/src/console/shared/transaction.ts +14 -0
  249. package/src/console/system-prompt/contracts.ts +89 -12
  250. package/src/console/system-prompt/routes.ts +98 -45
  251. package/src/console/updates/apply-update.ts +244 -0
  252. package/src/console/updates/routes.ts +256 -98
  253. package/src/main.ts +11 -5
  254. package/src/network/http2-bidi.ts +1 -1
  255. package/src/network/ip-utils.ts +298 -0
  256. package/src/network/outbound-fetch.ts +76 -5
  257. package/src/network/pool/agent.ts +7 -6
  258. package/src/network/pool/byte-accounting.ts +1 -1
  259. package/src/network/pool/resolver.ts +55 -51
  260. package/src/network/pool/selector.ts +150 -136
  261. package/src/network/pool-cooldown-store.ts +71 -16
  262. package/src/network/pool-health-machine.ts +22 -2
  263. package/src/network/rate-limit-verdict.ts +68 -0
  264. package/src/network/retry.ts +1 -1
  265. package/src/network/ssrf.ts +24 -75
  266. package/src/observability/event-log.ts +2 -2
  267. package/src/observability/event-query.ts +286 -214
  268. package/src/observability/log-sanitize.ts +1 -1
  269. package/src/observability/metrics.ts +4 -4
  270. package/src/observability/payload-capture.ts +6 -5
  271. package/src/observability/payload-store.ts +1 -1
  272. package/src/observability/runtime-metrics.ts +1 -1
  273. package/src/observability/telemetry-buffer.ts +12 -3
  274. package/src/observability/telemetry-reconciliation.ts +3 -3
  275. package/src/observability/telemetry-status.ts +1 -1
  276. package/src/observability/token-speed.ts +1 -1
  277. package/src/persistence/connection-url.ts +1 -1
  278. package/src/persistence/db-handle.ts +1 -1
  279. package/src/persistence/db-pg.ts +2 -2
  280. package/src/persistence/db-sqlite.ts +10 -5
  281. package/src/persistence/dialect.ts +5 -1
  282. package/src/persistence/readiness.ts +19 -7
  283. package/src/persistence/redis.ts +1 -1
  284. package/src/persistence/schema.ts +177 -45
  285. package/src/persistence/shared-cache.ts +2 -2
  286. package/src/persistence/sort-order.ts +1 -1
  287. package/src/persistence/stores/api-key-store.ts +109 -4
  288. package/src/persistence/stores/share-store.ts +20 -8
  289. package/src/persistence/stores/telemetry-store.ts +1 -1
  290. package/src/persistence/system-prompt-store.ts +63 -18
  291. package/src/persistence/tenant-preferences.ts +1 -1
  292. package/src/persistence/ttl-cache.ts +3 -3
  293. package/src/persistence/usage-flush.ts +7 -2
  294. package/src/protocol/canonical-model.ts +1 -1
  295. package/src/protocol/codecs.ts +12 -16
  296. package/src/protocol/dsml.ts +3 -49
  297. package/src/protocol/gateway-error.ts +6 -3
  298. package/src/protocol/image-clamp.ts +2 -2
  299. package/src/protocol/image-generation.ts +2 -2
  300. package/src/protocol/reasoning-text.ts +1 -1
  301. package/src/protocol/reasoning.ts +7 -52
  302. package/src/protocol/registry.ts +50 -15
  303. package/src/protocol/request/chat.ts +46 -19
  304. package/src/protocol/request/codex.ts +1 -1
  305. package/src/protocol/request/messages.ts +46 -14
  306. package/src/protocol/request/responses.ts +19 -10
  307. package/src/protocol/response/chat.ts +27 -12
  308. package/src/protocol/response/codex.ts +2 -2
  309. package/src/protocol/response/gemini.ts +1 -1
  310. package/src/protocol/response/messages.ts +6 -6
  311. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  312. package/src/protocol/response/responses.ts +3 -3
  313. package/src/protocol/sse-decoder.ts +64 -4
  314. package/src/protocol/stop-reason.ts +2 -2
  315. package/src/protocol/think-split.ts +347 -0
  316. package/src/protocol/translation/attachment-integrity.ts +3 -3
  317. package/src/protocol/translation/cache-controls.ts +8 -20
  318. package/src/protocol/translation/capabilities.ts +8 -8
  319. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  320. package/src/protocol/translation/dialect/inband.ts +39 -0
  321. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  322. package/src/protocol/translation/dialect/qwen.ts +114 -0
  323. package/src/protocol/translation/dialect/resolver.ts +83 -0
  324. package/src/protocol/translation/dialect/rules.ts +93 -0
  325. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  326. package/src/protocol/translation/dialect/types.ts +58 -0
  327. package/src/protocol/translation/quirks.ts +18 -4
  328. package/src/protocol/translation/thinking.ts +12 -252
  329. package/src/protocol/translation/tool-id.ts +3 -3
  330. package/src/protocol/translation/tool-repair.ts +1 -1
  331. package/src/protocol/upstream/post-json.ts +6 -1
  332. package/src/protocol/upstream/send-claude-messages.ts +3 -3
  333. package/src/providers/adapters/base-adapter.ts +1 -1
  334. package/src/providers/adapters/compatible-adapter.ts +44 -5
  335. package/src/providers/authentication/jwt-validator.ts +0 -5
  336. package/src/providers/authentication/oauth-client.ts +254 -253
  337. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  338. package/src/providers/authentication/oauth-refresh-service.ts +2 -2
  339. package/src/providers/bundled-discovery-providers.ts +6 -30
  340. package/src/providers/configured-openai-providers.ts +82 -97
  341. package/src/providers/configured-provider.ts +1 -1
  342. package/src/providers/default-registry.ts +23 -35
  343. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  344. package/src/providers/discovery/discovery-types.ts +0 -1
  345. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  346. package/src/providers/discovery/probe-phases.ts +50 -15
  347. package/src/providers/discovery/probing-service.ts +18 -20
  348. package/src/providers/integrations/agentrouter/agentrouter.ts +14 -5
  349. package/src/providers/integrations/alibabacp/alibabacp.ts +2 -2
  350. package/src/providers/integrations/anthropic.ts +4 -11
  351. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  352. package/src/providers/integrations/antigravity/antigravity-protocol.ts +0 -14
  353. package/src/providers/integrations/antigravity/antigravity.ts +15 -26
  354. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +2 -2
  355. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  356. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  357. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +37 -6
  358. package/src/providers/integrations/buddy/buddy-identity.ts +108 -1
  359. package/src/providers/integrations/buddy/buddy-media.ts +16 -16
  360. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  361. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  362. package/src/providers/integrations/buddy/codebuddy/provider.ts +5 -16
  363. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  364. package/src/providers/integrations/buddy/workbuddy/provider.ts +6 -10
  365. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  366. package/src/providers/integrations/claude/claude-betas.ts +1 -1
  367. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  368. package/src/providers/integrations/claude/claude-credentials.ts +1 -1
  369. package/src/providers/integrations/claude/claude-slow-lane-retry.ts +1 -1
  370. package/src/providers/integrations/claude/claude.ts +3 -10
  371. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  372. package/src/providers/integrations/cline/cline.ts +2 -2
  373. package/src/providers/integrations/cloudflareai/cloudflareai.ts +4 -7
  374. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  375. package/src/providers/integrations/codex/codex-errors.ts +1 -1
  376. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  377. package/src/providers/integrations/codex/codex.ts +14 -15
  378. package/src/providers/integrations/commandcode/commandcode.ts +76 -116
  379. package/src/providers/integrations/commandcode/quota.ts +132 -48
  380. package/src/providers/integrations/cursor/cursor-http2.ts +11 -14
  381. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  382. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  383. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  384. package/src/providers/integrations/cursor/cursor.ts +53 -20
  385. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  386. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  387. package/src/providers/integrations/factory/factory.ts +13 -13
  388. package/src/providers/integrations/gemini.ts +11 -11
  389. package/src/providers/integrations/github/github-discovery.ts +55 -10
  390. package/src/providers/integrations/github/github-oauth.ts +6 -5
  391. package/src/providers/integrations/github/github.ts +47 -20
  392. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  393. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  394. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  395. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  396. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  397. package/src/providers/integrations/grok/grok.ts +88 -42
  398. package/src/providers/integrations/inferhub.ts +4 -11
  399. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  400. package/src/providers/integrations/kimi/kimi.ts +4 -11
  401. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  402. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  403. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  404. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  405. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  406. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  407. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  408. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  409. package/src/providers/integrations/kiro/kiro.ts +91 -78
  410. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  411. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  412. package/src/providers/integrations/muse/muse.ts +6 -9
  413. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  414. package/src/providers/integrations/opencode/provider.ts +17 -24
  415. package/src/providers/integrations/perplexity.ts +2 -2
  416. package/src/providers/integrations/qoder/qoder-catalog.ts +132 -17
  417. package/src/providers/integrations/qoder/qoder-checkin.ts +26 -8
  418. package/src/providers/integrations/qoder/qoder-native-identity-store.ts +9 -8
  419. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  420. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  421. package/src/providers/integrations/qoder/qoder-realm.ts +22 -28
  422. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  423. package/src/providers/integrations/qoder/qoder-umid.ts +33 -38
  424. package/src/providers/integrations/qoder/qoder-virtual.ts +14 -2
  425. package/src/providers/integrations/qoder/qoder.ts +521 -63
  426. package/src/providers/integrations/shared/connect.ts +0 -54
  427. package/src/providers/integrations/shared/hash.ts +15 -0
  428. package/src/providers/integrations/shared/session-cache.ts +136 -0
  429. package/src/providers/integrations/tokenharbor.ts +2 -2
  430. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  431. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  432. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  433. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  434. package/src/providers/integrations/trae/trae.ts +59 -19
  435. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  436. package/src/providers/integrations/zcode/oauth.ts +1 -1
  437. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  438. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  439. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  440. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  441. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  442. package/src/providers/operations/account-error-classification.ts +131 -116
  443. package/src/providers/operations/account-health-service.ts +31 -39
  444. package/src/providers/operations/account-reset-service.ts +58 -1
  445. package/src/providers/operations/cli-platform.ts +31 -5
  446. package/src/providers/operations/client-version-resolver.ts +4 -6
  447. package/src/providers/operations/client-versions.ts +10 -7
  448. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  449. package/src/providers/operations/provider-catalog-service.ts +22 -6
  450. package/src/providers/operations/provider-credential-service.ts +35 -6
  451. package/src/providers/operations/upstream-deadline.ts +3 -3
  452. package/src/providers/provider-contracts.ts +65 -10
  453. package/src/providers/provider-credential-resolver.ts +1 -1
  454. package/src/providers/provider-metadata.ts +17 -2
  455. package/src/providers/provider-model-definition.ts +22 -1
  456. package/src/providers/provider-probe.ts +4 -2
  457. package/src/providers/provider-registry.ts +4 -4
  458. package/src/providers/provider-usage.ts +81 -16
  459. package/src/providers/quota/cache.ts +29 -0
  460. package/src/providers/quota/quota-contracts.ts +28 -10
  461. package/src/providers/quota/refresh.ts +29 -6
  462. package/src/providers/quota/snapshot.ts +94 -0
  463. package/src/providers/search/search-provider.ts +6 -8
  464. package/src/providers/search/search-providers.ts +2 -1
  465. package/src/security/abuse.ts +8 -8
  466. package/src/security/admission/reasons.ts +17 -17
  467. package/src/security/admission/service.ts +2 -2
  468. package/src/security/admission/ttl.ts +61 -61
  469. package/src/security/api-key-auth.ts +20 -8
  470. package/src/security/client-router-fingerprint.ts +4 -4
  471. package/src/security/credential-codec.ts +3 -3
  472. package/src/security/csrf.ts +2 -2
  473. package/src/security/ip-boundary.ts +16 -189
  474. package/src/security/model-access-rule.ts +1 -1
  475. package/src/security/outbound-headers.ts +18 -0
  476. package/src/shared/coerce.ts +19 -0
  477. package/src/shared/invoke-guard.ts +47 -0
  478. package/src/transport/contracts.ts +13 -4
  479. package/src/transport/dispatch/attempt-finalize.ts +5 -4
  480. package/src/transport/dispatch/attempt-loop.ts +10 -7
  481. package/src/transport/dispatch/capture-policy.ts +34 -37
  482. package/src/transport/dispatch/empty-stream.ts +28 -25
  483. package/src/transport/dispatch/generation.ts +33 -53
  484. package/src/transport/dispatch/leases.ts +8 -8
  485. package/src/transport/dispatch/native-shared.ts +127 -0
  486. package/src/transport/dispatch/proxy-request.ts +10 -8
  487. package/src/transport/dispatch/responses-compact.ts +35 -56
  488. package/src/transport/dispatch/retry-policy.ts +4 -67
  489. package/src/transport/dispatch/stream-bridge.ts +1 -1
  490. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  491. package/src/transport/dispatch/streaming/finalize.ts +11 -10
  492. package/src/transport/dispatch/streaming/stream.ts +7 -3
  493. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  494. package/src/transport/dispatch/systemone.ts +27 -55
  495. package/src/transport/dispatch/token-count.ts +49 -46
  496. package/src/transport/dispatch/websearch.ts +24 -50
  497. package/src/transport/drain-endpoint.ts +3 -3
  498. package/src/transport/failure-policy.ts +19 -6
  499. package/src/transport/guards/auth-guard.ts +6 -11
  500. package/src/transport/guards/body-policy.ts +7 -7
  501. package/src/transport/guards/error-lifecycle.ts +18 -3
  502. package/src/transport/guards/guard-errors.ts +7 -3
  503. package/src/transport/guards/headroom-guard.ts +2 -2
  504. package/src/transport/guards/pipeline.ts +7 -7
  505. package/src/transport/guards/readiness-guard.ts +16 -2
  506. package/src/transport/guards/request-context.ts +15 -20
  507. package/src/transport/request/preparer.ts +306 -27
  508. package/src/transport/request/rtk/compress-request.ts +3 -3
  509. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  510. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  511. package/src/transport/request/state.ts +5 -20
  512. package/src/transport/request/system-prompt-injection.ts +74 -11
  513. package/src/transport/request/tenant-preferences.ts +22 -0
  514. package/src/transport/routing/candidate-index.ts +2 -2
  515. package/src/transport/routing/round-robin.ts +1 -1
  516. package/src/transport/routing/route-catalog.ts +113 -19
  517. package/src/transport/routing/route-model.ts +131 -38
  518. package/src/transport/routing/router.ts +154 -39
  519. package/src/transport/shutdown-notice.ts +21 -9
  520. package/src/transport/surface/adapters.ts +3 -3
  521. package/src/transport/surface/chat/encode.ts +7 -7
  522. package/src/transport/surface/chat/parse.ts +7 -7
  523. package/src/transport/surface/completion.ts +3 -3
  524. package/src/transport/surface/content-parts.ts +1 -1
  525. package/src/transport/surface/dialects.ts +2 -2
  526. package/src/transport/surface/messages/encode.ts +1 -1
  527. package/src/transport/surface/messages/parse.ts +3 -3
  528. package/src/transport/surface/responses/adapter.ts +1 -1
  529. package/src/transport/surface/responses/errors.ts +0 -9
  530. package/src/transport/vision-handoff-cache.ts +58 -0
  531. package/src/transport/vision-handoff.ts +376 -0
  532. package/src/workers/account-identity-sweep.ts +2 -2
  533. package/src/workers/buddy-growth-tasks.ts +392 -346
  534. package/src/workers/daily-checkin.ts +102 -49
  535. package/src/workers/maintenance-lease.ts +2 -35
  536. package/src/workers/oauth-refresh-sweep.ts +8 -1
  537. package/src/workers/quota-refresh-sweep.ts +120 -82
  538. package/src/workers/scheduler.ts +67 -4
  539. package/src/workers/sweep-runner.ts +24 -5
  540. package/src/workers/zcode-gift-claim.ts +108 -0
  541. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  542. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  543. package/dist/dashboard/assets/BannedPage-2TJD37Hb.js.gz +0 -0
  544. package/dist/dashboard/assets/CliToolDetailPage-xefJNRmJ.js.gz +0 -0
  545. package/dist/dashboard/assets/CliToolsPage-Rj9iHQ3F.js.gz +0 -0
  546. package/dist/dashboard/assets/CombosPage-JEbYJFxw.js +0 -1
  547. package/dist/dashboard/assets/CombosPage-JEbYJFxw.js.gz +0 -0
  548. package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js +0 -1
  549. package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js.gz +0 -0
  550. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js +0 -1
  551. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js.gz +0 -0
  552. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js +0 -1
  553. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js.gz +0 -0
  554. package/dist/dashboard/assets/LoginPage-C4w7vea-.js.gz +0 -0
  555. package/dist/dashboard/assets/ModelPicker-BtPcAfot.js.gz +0 -0
  556. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js +0 -1
  557. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js.gz +0 -0
  558. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js +0 -4
  559. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js.gz +0 -0
  560. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  561. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  562. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js +0 -1
  563. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js.gz +0 -0
  564. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js +0 -9
  565. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js.gz +0 -0
  566. package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js +0 -1
  567. package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js.gz +0 -0
  568. package/dist/dashboard/assets/SettingsPage-CDZjTt87.js +0 -1
  569. package/dist/dashboard/assets/SettingsPage-CDZjTt87.js.gz +0 -0
  570. package/dist/dashboard/assets/SetupPage-BQS0Rx_u.js.gz +0 -0
  571. package/dist/dashboard/assets/SortableList-BAL5npBC.js +0 -1
  572. package/dist/dashboard/assets/SortableList-BAL5npBC.js.gz +0 -0
  573. package/dist/dashboard/assets/StudioPage-TP7voAQ0.js.gz +0 -0
  574. package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js +0 -56
  575. package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js.gz +0 -0
  576. package/dist/dashboard/assets/api-keys-MbI7e7rt.js +0 -1
  577. package/dist/dashboard/assets/api-keys-MbI7e7rt.js.gz +0 -0
  578. package/dist/dashboard/assets/app-B2vyPoII.css +0 -2
  579. package/dist/dashboard/assets/app-B2vyPoII.css.gz +0 -0
  580. package/dist/dashboard/assets/assert-C0YYuZJ4.js.gz +0 -0
  581. package/dist/dashboard/assets/badge-B_DMpMJN.js.gz +0 -0
  582. package/dist/dashboard/assets/banner-DMrMPmth.js.gz +0 -0
  583. package/dist/dashboard/assets/card-Be5Uzamx.js.gz +0 -0
  584. package/dist/dashboard/assets/cli-tools-muFRphDu.js.gz +0 -0
  585. package/dist/dashboard/assets/clipboard-button-DOfrVmsi.js.gz +0 -0
  586. package/dist/dashboard/assets/dialog-C9omdjQt.js.gz +0 -0
  587. package/dist/dashboard/assets/drawer-Bm8WKaGY.js.gz +0 -0
  588. package/dist/dashboard/assets/entry-DS90gUks.js +0 -1
  589. package/dist/dashboard/assets/entry-DS90gUks.js.gz +0 -0
  590. package/dist/dashboard/assets/entry-j40LJotO.js +0 -4
  591. package/dist/dashboard/assets/entry-j40LJotO.js.gz +0 -0
  592. package/dist/dashboard/assets/entry-q5HwZ8nN.js.gz +0 -0
  593. package/dist/dashboard/assets/formatters-BTScrQpe.js.gz +0 -0
  594. package/dist/dashboard/assets/github-badge-Orjuzemr.js.gz +0 -0
  595. package/dist/dashboard/assets/index-cPrX5vn6.js.gz +0 -0
  596. package/dist/dashboard/assets/inline-Dvux8w-0.js.gz +0 -0
  597. package/dist/dashboard/assets/input-CU1Rgf3p.js.gz +0 -0
  598. package/dist/dashboard/assets/list-row-CzFvogbj.js.gz +0 -0
  599. package/dist/dashboard/assets/live-KaG15HLQ.js +0 -1
  600. package/dist/dashboard/assets/live-KaG15HLQ.js.gz +0 -0
  601. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +0 -1
  602. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  603. package/dist/dashboard/assets/mutation-JJGQm8TD.js.gz +0 -0
  604. package/dist/dashboard/assets/numbers-BNDZnsUE.js +0 -2
  605. package/dist/dashboard/assets/numbers-BNDZnsUE.js.gz +0 -0
  606. package/dist/dashboard/assets/query-keys-CLaNz8Xz.js.gz +0 -0
  607. package/dist/dashboard/assets/quota-DZGyp0N5.js +0 -1
  608. package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
  609. package/dist/dashboard/assets/routing-BEH32QOC.js.gz +0 -0
  610. package/dist/dashboard/assets/select-B3iTetHN.js.gz +0 -0
  611. package/dist/dashboard/assets/settings-Dt3Eqbnq.js +0 -1
  612. package/dist/dashboard/assets/settings-Dt3Eqbnq.js.gz +0 -0
  613. package/dist/dashboard/assets/stack-KrOrm7JZ.js.gz +0 -0
  614. package/dist/dashboard/assets/state-DLS7IDMy.js.gz +0 -0
  615. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  616. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  617. package/dist/dashboard/assets/switch-42ItvbAs.js.gz +0 -0
  618. package/dist/dashboard/assets/useMutation-Dmnfh1Ue.js.gz +0 -0
  619. package/src/network/response-headers.ts +0 -39
  620. package/src/protocol/response/dsml.ts +0 -38
  621. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  622. /package/dist/dashboard/assets/{app-wvwCi4Eh.js → app-Bgd3zANQ.js} +0 -0
  623. /package/dist/dashboard/assets/{app-wvwCi4Eh.js.gz → app-Bgd3zANQ.js.gz} +0 -0
  624. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  625. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -1,261 +1,261 @@
1
- /** xAI Grok Build device-code OAuth client. */
2
- import { devicePollBackoff, nonEmptyTrimmedString, parseDeviceAuthStart, postFormTokenRequest, readJsonResponse } from "../../authentication/oauth-flow-store";
3
- import type {
4
- OAuthDeviceFlowContext,
5
- OAuthDevicePollResult,
6
- OAuthDeviceStartResult,
7
- } from "../../authentication/oauth-flow-store";
8
- import type { OAuthTokenRefreshResult } from "../../authentication/oauth-refresh-service";
9
- import { OAuthDeviceFlow } from "../../authentication/oauth-device-flow";
10
- import type { FetchLike } from "../../authentication/oauth-client";
11
- import { XAI_AUTH_SERVER } from "../xai/xai-oauth";
12
-
13
- /**
14
- * The Grok Build client registers against the same authorization server as
15
- * the xAI subscription client, so the client id and the device/token
16
- * endpoints are read from the one declaration rather than restated here.
17
- */
18
- export const GROK_CLIENT_ID = XAI_AUTH_SERVER.clientId;
19
- export const GROK_DEVICE_URL = XAI_AUTH_SERVER.deviceUrl;
20
- export const GROK_TOKEN_URL = XAI_AUTH_SERVER.tokenUrl;
21
- export const GROK_USER_URL = "https://cli-chat-proxy.grok.com/v1/user" as const;
22
- export const GROK_SCOPE = [
23
- "openid",
24
- "profile",
25
- "email",
26
- "offline_access",
27
- "grok-cli:access",
28
- "api:access",
29
- "conversations:read",
30
- "conversations:write",
31
- "workspaces:read",
32
- "workspaces:write",
33
- ].join(" ");
34
- import {
35
- buildGrokAuthUserAgent,
36
- getGrokVersion,
37
- } from "../../operations/client-versions";
38
-
39
- interface TokenPayload {
40
- access_token?: unknown;
41
- refresh_token?: unknown;
42
- expires_in?: unknown;
43
- error?: unknown;
44
- error_description?: unknown;
45
- interval?: unknown;
46
- }
47
- interface UserPayload {
48
- email?: unknown;
49
- userId?: unknown;
50
- principalId?: unknown;
51
- firstName?: unknown;
52
- lastName?: unknown;
53
- hasGrokCodeAccess?: unknown;
54
- subscriptionTier?: unknown;
55
- }
56
-
57
- /**
58
- * Identity Grok's proxy reports, kept beyond the display label.
59
- *
60
- * `userId`/`principalId` are the account's upstream identity — the token does
61
- * not carry them and the gateway cannot derive them, so they are persisted in
62
- * `auth_state` rather than thrown away once the label is chosen.
63
- */
64
- interface GrokIdentity {
65
- readonly label?: string | undefined;
66
- readonly userId?: string | undefined;
67
- readonly principalId?: string | undefined;
68
- readonly hasGrokCodeAccess?: boolean | undefined;
69
- readonly subscriptionTier?: string | undefined;
70
- }
71
-
72
- function grokAuthState(identity: GrokIdentity): Record<string, unknown> | undefined {
73
- const state: Record<string, unknown> = {};
74
- if (identity.userId !== undefined) state["userId"] = identity.userId;
75
- if (identity.principalId !== undefined) state["principalId"] = identity.principalId;
76
- if (identity.hasGrokCodeAccess !== undefined)
77
- state["hasGrokCodeAccess"] = identity.hasGrokCodeAccess;
78
- if (identity.subscriptionTier !== undefined)
79
- state["subscriptionTier"] = identity.subscriptionTier;
80
- return Object.keys(state).length > 0 ? state : undefined;
81
- }
82
-
83
- async function fetchGrokIdentity(
84
- accessToken: string,
85
- fetcher: FetchLike,
86
- ): Promise<GrokIdentity> {
87
- try {
88
- const version = getGrokVersion();
89
- const response = await fetcher(GROK_USER_URL, {
90
- headers: {
91
- authorization: `Bearer ${accessToken}`,
92
- accept: "application/json",
93
- "user-agent": buildGrokAuthUserAgent(version),
94
- "x-xai-token-auth": "xai-grok-cli",
95
- "x-grok-client-version": version,
96
- },
97
- signal: AbortSignal.timeout(10_000),
98
- });
99
- if (!response.ok) return {};
100
- const payload = (await response.json()) as UserPayload;
101
- const displayName =
102
- [nonEmptyTrimmedString(payload.firstName), nonEmptyTrimmedString(payload.lastName)]
103
- .filter((part): part is string => part !== undefined)
104
- .join(" ")
105
- .trim() || undefined;
106
- return {
107
- label:
108
- displayName ??
109
- nonEmptyTrimmedString(payload.email) ??
110
- nonEmptyTrimmedString(payload.userId) ??
111
- nonEmptyTrimmedString(payload.principalId),
112
- ...(nonEmptyTrimmedString(payload.userId) === undefined
113
- ? {}
114
- : { userId: nonEmptyTrimmedString(payload.userId)! }),
115
- ...(nonEmptyTrimmedString(payload.principalId) === undefined
116
- ? {}
117
- : { principalId: nonEmptyTrimmedString(payload.principalId)! }),
118
- ...(typeof payload.hasGrokCodeAccess === "boolean"
119
- ? { hasGrokCodeAccess: payload.hasGrokCodeAccess }
120
- : {}),
121
- ...(nonEmptyTrimmedString(payload.subscriptionTier) === undefined
122
- ? {}
123
- : { subscriptionTier: nonEmptyTrimmedString(payload.subscriptionTier)! }),
124
- };
125
- } catch {
126
- return {};
127
- }
128
- }
129
-
130
- function authHeaders(): Record<string, string> {
131
- const version = getGrokVersion();
132
- return {
133
- "content-type": "application/x-www-form-urlencoded",
134
- accept: "application/json",
135
- "user-agent": buildGrokAuthUserAgent(version),
136
- "x-grok-client-version": version,
137
- "x-grok-client-surface": "ui",
138
- };
139
- }
140
-
141
- /** Device-code OAuth client for Grok Build CLI subscriptions. */
142
- export class GrokOAuthClient extends OAuthDeviceFlow {
143
- override readonly supportsDeviceCode = true;
144
- override readonly supportsBrowserCode = false;
145
-
146
- protected override readonly providerLabel = "grok";
147
- protected override readonly clientId = GROK_CLIENT_ID;
148
- protected override readonly tokenUrl = GROK_TOKEN_URL;
149
- protected override readonly scopes = GROK_SCOPE;
150
-
151
- override async startDeviceAuth(_context?: OAuthDeviceFlowContext): Promise<OAuthDeviceStartResult> {
152
- const body = new URLSearchParams({
153
- client_id: GROK_CLIENT_ID,
154
- scope: GROK_SCOPE,
155
- referrer: "grok-build",
156
- });
157
- const response = await this.fetchFn(GROK_DEVICE_URL, {
158
- method: "POST",
159
- headers: authHeaders(),
160
- body,
161
- });
162
- const payload = await readJsonResponse(response, "grok device authorization");
163
- // The device correlation lives in Redis with the store's 900 s TTL: a
164
- // longer advertised lifetime would outlive the correlation and force a
165
- // restart at 900 s even when the provider code is still valid.
166
- const start = parseDeviceAuthStart(payload, {
167
- intervalSeconds: 5,
168
- expiresInSeconds: 900,
169
- });
170
- if (!start) throw new Error("grok device response omitted required fields");
171
- return {
172
- verificationUri: start.verificationUriComplete ?? start.verificationUri,
173
- userCode: start.userCode,
174
- deviceAuthId: start.deviceCode,
175
- intervalSeconds: start.intervalSeconds,
176
- expiresInSeconds: start.expiresInSeconds,
177
- };
178
- }
179
-
180
- override async pollDeviceAuth(deviceAuthId: string, _context?: OAuthDeviceFlowContext): Promise<OAuthDevicePollResult> {
181
- const body = new URLSearchParams({
182
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
183
- device_code: deviceAuthId,
184
- client_id: GROK_CLIENT_ID,
185
- });
186
- const response = await this.fetchFn(GROK_TOKEN_URL, {
187
- method: "POST",
188
- headers: authHeaders(),
189
- body,
190
- });
191
- const raw = await response.text();
192
- let payload: TokenPayload;
193
- try {
194
- payload = JSON.parse(raw) as TokenPayload;
195
- } catch {
196
- return { status: "failed", reason: "grok token endpoint returned invalid JSON" };
197
- }
198
- const error = nonEmptyTrimmedString(payload.error);
199
- const verdict = devicePollBackoff(error, payload.interval);
200
- if (verdict !== undefined) return verdict;
201
- if (!response.ok) {
202
- return { status: "failed", reason: nonEmptyTrimmedString(payload.error_description) ?? error ?? `token polling failed (${response.status})` };
203
- }
204
- // A 2xx is not by itself a completed authorization: the endpoint can answer
205
- // 200 with an `error` field and no token. Returning `failed` rather than
206
- // letting the shared parser throw keeps the verdict inside the poll
207
- // contract — the dashboard's poll error path stops polling but shows no
208
- // reason, so a throw would look like a spinner that never ends.
209
- if (nonEmptyTrimmedString(payload.access_token) === undefined) {
210
- return {
211
- status: "failed",
212
- reason:
213
- nonEmptyTrimmedString(payload.error_description) ??
214
- error ??
215
- "grok token response omitted access_token",
216
- };
217
- }
218
- const result = this.parseTokenResponse(payload);
219
- const identity = await fetchGrokIdentity(result.access, this.fetchFn);
220
- const authState = grokAuthState(identity);
221
- return {
222
- status: "complete",
223
- result: this.toExchangeResult({
224
- ...result,
225
- ...(identity.label === undefined ? {} : { accountLabel: identity.label }),
226
- // Omitted when the proxy reported nothing, which leaves any stored
227
- // state alone rather than blanking it.
228
- ...(authState === undefined ? {} : { auth_state: authState }),
229
- }),
230
- };
231
- }
232
-
233
- override async refresh(refreshToken: string, signal?: AbortSignal): Promise<OAuthTokenRefreshResult> {
234
- const payload = (await postFormTokenRequest({
235
- url: GROK_TOKEN_URL,
236
- fetchFn: this.fetchFn,
237
- params: {
238
- grant_type: "refresh_token",
239
- client_id: GROK_CLIENT_ID,
240
- refresh_token: refreshToken,
241
- },
242
- headers: authHeaders(),
243
- signal,
244
- timeoutMs: 15_000,
245
- label: "grok token refresh",
246
- })) as TokenPayload;
247
- const result = this.parseTokenResponse(payload, refreshToken);
248
- // Re-read the identity on refresh: a persisted id that went stale is
249
- // otherwise never corrected, and the call is best-effort — a failure
250
- // returns nothing, which the store reads as "keep what we have".
251
- const identity = await fetchGrokIdentity(result.access, this.fetchFn);
252
- const authState = grokAuthState(identity);
253
- return this.toRefreshResult({
254
- ...result,
255
- ...(identity.label === undefined ? {} : { accountLabel: identity.label }),
256
- ...(authState === undefined ? {} : { auth_state: authState }),
257
- });
258
- }
259
- }
260
-
261
- export const grokOAuthClient = new GrokOAuthClient();
1
+ /** xAI Grok Build device-code OAuth client. */
2
+ import { devicePollBackoff, nonEmptyTrimmedString, parseDeviceAuthStart, postFormTokenRequest, readJsonResponse } from "../../authentication/oauth-flow-store";
3
+ import type {
4
+ OAuthDeviceFlowContext,
5
+ OAuthDevicePollResult,
6
+ OAuthDeviceStartResult,
7
+ } from "../../authentication/oauth-flow-store";
8
+ import type { OAuthTokenRefreshResult } from "../../authentication/oauth-refresh-service";
9
+ import { OAuthDeviceFlow } from "../../authentication/oauth-device-flow";
10
+ import type { FetchLike } from "../../authentication/oauth-client";
11
+ import { XAI_AUTH_SERVER } from "../xai/xai-oauth";
12
+
13
+ /**
14
+ * The Grok Build client registers against the same authorization server as
15
+ * the xAI subscription client, so the client id and the device/token
16
+ * endpoints are read from the one declaration rather than restated here.
17
+ */
18
+ export const GROK_CLIENT_ID = XAI_AUTH_SERVER.clientId;
19
+ export const GROK_DEVICE_URL = XAI_AUTH_SERVER.deviceUrl;
20
+ export const GROK_TOKEN_URL = XAI_AUTH_SERVER.tokenUrl;
21
+ export const GROK_USER_URL = "https://cli-chat-proxy.grok.com/v1/user" as const;
22
+ export const GROK_SCOPE = [
23
+ "openid",
24
+ "profile",
25
+ "email",
26
+ "offline_access",
27
+ "grok-cli:access",
28
+ "api:access",
29
+ "conversations:read",
30
+ "conversations:write",
31
+ "workspaces:read",
32
+ "workspaces:write",
33
+ ].join(" ");
34
+ import {
35
+ buildGrokAuthUserAgent,
36
+ getGrokVersion,
37
+ } from "../../operations/client-versions";
38
+
39
+ interface TokenPayload {
40
+ access_token?: unknown;
41
+ refresh_token?: unknown;
42
+ expires_in?: unknown;
43
+ error?: unknown;
44
+ error_description?: unknown;
45
+ interval?: unknown;
46
+ }
47
+ interface UserPayload {
48
+ email?: unknown;
49
+ userId?: unknown;
50
+ principalId?: unknown;
51
+ firstName?: unknown;
52
+ lastName?: unknown;
53
+ hasGrokCodeAccess?: unknown;
54
+ subscriptionTier?: unknown;
55
+ }
56
+
57
+ /**
58
+ * Identity Grok's proxy reports, kept beyond the display label.
59
+ *
60
+ * `userId`/`principalId` are the account's upstream identity — the token does
61
+ * not carry them and the gateway cannot derive them, so they are persisted in
62
+ * `auth_state` rather than thrown away once the label is chosen.
63
+ */
64
+ interface GrokIdentity {
65
+ readonly label?: string | undefined;
66
+ readonly userId?: string | undefined;
67
+ readonly principalId?: string | undefined;
68
+ readonly hasGrokCodeAccess?: boolean | undefined;
69
+ readonly subscriptionTier?: string | undefined;
70
+ }
71
+
72
+ function grokAuthState(identity: GrokIdentity): Record<string, unknown> | undefined {
73
+ const state: Record<string, unknown> = {};
74
+ if (identity.userId !== undefined) state["userId"] = identity.userId;
75
+ if (identity.principalId !== undefined) state["principalId"] = identity.principalId;
76
+ if (identity.hasGrokCodeAccess !== undefined)
77
+ state["hasGrokCodeAccess"] = identity.hasGrokCodeAccess;
78
+ if (identity.subscriptionTier !== undefined)
79
+ state["subscriptionTier"] = identity.subscriptionTier;
80
+ return Object.keys(state).length > 0 ? state : undefined;
81
+ }
82
+
83
+ async function fetchGrokIdentity(
84
+ accessToken: string,
85
+ fetcher: FetchLike,
86
+ ): Promise<GrokIdentity> {
87
+ try {
88
+ const version = getGrokVersion();
89
+ const response = await fetcher(GROK_USER_URL, {
90
+ headers: {
91
+ authorization: `Bearer ${accessToken}`,
92
+ accept: "application/json",
93
+ "user-agent": buildGrokAuthUserAgent(version),
94
+ "x-xai-token-auth": "xai-grok-cli",
95
+ "x-grok-client-version": version,
96
+ },
97
+ signal: AbortSignal.timeout(10_000),
98
+ });
99
+ if (!response.ok) return {};
100
+ const payload = (await response.json()) as UserPayload;
101
+ const displayName =
102
+ [nonEmptyTrimmedString(payload.firstName), nonEmptyTrimmedString(payload.lastName)]
103
+ .filter((part): part is string => part !== undefined)
104
+ .join(" ")
105
+ .trim() || undefined;
106
+ return {
107
+ label:
108
+ displayName ??
109
+ nonEmptyTrimmedString(payload.email) ??
110
+ nonEmptyTrimmedString(payload.userId) ??
111
+ nonEmptyTrimmedString(payload.principalId),
112
+ ...(nonEmptyTrimmedString(payload.userId) === undefined
113
+ ? {}
114
+ : { userId: nonEmptyTrimmedString(payload.userId)! }),
115
+ ...(nonEmptyTrimmedString(payload.principalId) === undefined
116
+ ? {}
117
+ : { principalId: nonEmptyTrimmedString(payload.principalId)! }),
118
+ ...(typeof payload.hasGrokCodeAccess === "boolean"
119
+ ? { hasGrokCodeAccess: payload.hasGrokCodeAccess }
120
+ : {}),
121
+ ...(nonEmptyTrimmedString(payload.subscriptionTier) === undefined
122
+ ? {}
123
+ : { subscriptionTier: nonEmptyTrimmedString(payload.subscriptionTier)! }),
124
+ };
125
+ } catch {
126
+ return {};
127
+ }
128
+ }
129
+
130
+ function authHeaders(): Record<string, string> {
131
+ const version = getGrokVersion();
132
+ return {
133
+ "content-type": "application/x-www-form-urlencoded",
134
+ accept: "application/json",
135
+ "user-agent": buildGrokAuthUserAgent(version),
136
+ "x-grok-client-version": version,
137
+ "x-grok-client-surface": "ui",
138
+ };
139
+ }
140
+
141
+ /** Device-code OAuth client for Grok Build CLI subscriptions. */
142
+ export class GrokOAuthClient extends OAuthDeviceFlow {
143
+ override readonly supportsDeviceCode = true;
144
+ override readonly supportsBrowserCode = false;
145
+
146
+ protected override readonly providerLabel = "grok";
147
+ protected override readonly clientId = GROK_CLIENT_ID;
148
+ protected override readonly tokenUrl = GROK_TOKEN_URL;
149
+ protected override readonly scopes = GROK_SCOPE;
150
+
151
+ override async startDeviceAuth(_context?: OAuthDeviceFlowContext): Promise<OAuthDeviceStartResult> {
152
+ const body = new URLSearchParams({
153
+ client_id: GROK_CLIENT_ID,
154
+ scope: GROK_SCOPE,
155
+ referrer: "grok-build",
156
+ });
157
+ const response = await this.fetchFn(GROK_DEVICE_URL, {
158
+ method: "POST",
159
+ headers: authHeaders(),
160
+ body,
161
+ });
162
+ const payload = await readJsonResponse(response, "grok device authorization");
163
+ // The device correlation lives in Redis with the store's 900 s TTL: a
164
+ // longer advertised lifetime would outlive the correlation and force a
165
+ // restart at 900 s even when the provider code is still valid.
166
+ const start = parseDeviceAuthStart(payload, {
167
+ intervalSeconds: 5,
168
+ expiresInSeconds: 900,
169
+ });
170
+ if (!start) throw new Error("grok device response omitted required fields");
171
+ return {
172
+ verificationUri: start.verificationUriComplete ?? start.verificationUri,
173
+ userCode: start.userCode,
174
+ deviceAuthId: start.deviceCode,
175
+ intervalSeconds: start.intervalSeconds,
176
+ expiresInSeconds: start.expiresInSeconds,
177
+ };
178
+ }
179
+
180
+ override async pollDeviceAuth(deviceAuthId: string, _context?: OAuthDeviceFlowContext): Promise<OAuthDevicePollResult> {
181
+ const body = new URLSearchParams({
182
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
183
+ device_code: deviceAuthId,
184
+ client_id: GROK_CLIENT_ID,
185
+ });
186
+ const response = await this.fetchFn(GROK_TOKEN_URL, {
187
+ method: "POST",
188
+ headers: authHeaders(),
189
+ body,
190
+ });
191
+ const raw = await response.text();
192
+ let payload: TokenPayload;
193
+ try {
194
+ payload = JSON.parse(raw) as TokenPayload;
195
+ } catch {
196
+ return { status: "failed", reason: "grok token endpoint returned invalid JSON" };
197
+ }
198
+ const error = nonEmptyTrimmedString(payload.error);
199
+ const verdict = devicePollBackoff(error, payload.interval);
200
+ if (verdict !== undefined) return verdict;
201
+ if (!response.ok) {
202
+ return { status: "failed", reason: nonEmptyTrimmedString(payload.error_description) ?? error ?? `token polling failed (${response.status})` };
203
+ }
204
+ // A 2xx is not by itself a completed authorization: the endpoint can answer
205
+ // 200 with an `error` field and no token. Returning `failed` rather than
206
+ // letting the shared parser throw keeps the verdict inside the poll
207
+ // contract — the dashboard's poll error path stops polling but shows no
208
+ // reason, so a throw would look like a spinner that never ends.
209
+ if (nonEmptyTrimmedString(payload.access_token) === undefined) {
210
+ return {
211
+ status: "failed",
212
+ reason:
213
+ nonEmptyTrimmedString(payload.error_description) ??
214
+ error ??
215
+ "grok token response omitted access_token",
216
+ };
217
+ }
218
+ const result = this.parseTokenResponse(payload);
219
+ const identity = await fetchGrokIdentity(result.access, this.fetchFn);
220
+ const authState = grokAuthState(identity);
221
+ return {
222
+ status: "complete",
223
+ result: this.toExchangeResult({
224
+ ...result,
225
+ ...(identity.label === undefined ? {} : { accountLabel: identity.label }),
226
+ // Omitted when the proxy reported nothing, which leaves any stored
227
+ // state alone rather than blanking it.
228
+ ...(authState === undefined ? {} : { auth_state: authState }),
229
+ }),
230
+ };
231
+ }
232
+
233
+ override async refresh(refreshToken: string, signal?: AbortSignal): Promise<OAuthTokenRefreshResult> {
234
+ const payload = (await postFormTokenRequest({
235
+ url: GROK_TOKEN_URL,
236
+ fetchFn: this.fetchFn,
237
+ params: {
238
+ grant_type: "refresh_token",
239
+ client_id: GROK_CLIENT_ID,
240
+ refresh_token: refreshToken,
241
+ },
242
+ headers: authHeaders(),
243
+ signal,
244
+ timeoutMs: 15_000,
245
+ label: "grok token refresh",
246
+ })) as TokenPayload;
247
+ const result = this.parseTokenResponse(payload, refreshToken);
248
+ // Re-read the identity on refresh: a persisted id that went stale is
249
+ // otherwise never corrected, and the call is best-effort — a failure
250
+ // returns nothing, which the store reads as "keep what we have".
251
+ const identity = await fetchGrokIdentity(result.access, this.fetchFn);
252
+ const authState = grokAuthState(identity);
253
+ return this.toRefreshResult({
254
+ ...result,
255
+ ...(identity.label === undefined ? {} : { accountLabel: identity.label }),
256
+ ...(authState === undefined ? {} : { auth_state: authState }),
257
+ });
258
+ }
259
+ }
260
+
261
+ export const grokOAuthClient = new GrokOAuthClient();
@@ -17,7 +17,7 @@ const WIRE_TYPE_FIXED32 = 5;
17
17
  const GRPC_WEB_TRAILER_FLAG_BIT = 0x80;
18
18
  const MAX_VARINT_SHIFT_BITS = 70n;
19
19
 
20
- export function probeFrameHeader(
20
+ function probeFrameHeader(
21
21
  buffer: Uint8Array,
22
22
  offset = 0,
23
23
  ): { flag: number; payloadStart: number; payloadLength: number } | null {
@@ -7,6 +7,7 @@ import {
7
7
  grokHeaderRequestsWindow,
8
8
  grokHeaderWindow,
9
9
  GROK_FREE_USAGE_EXHAUSTED,
10
+ GROK_SPENDING_LIMIT_EXHAUSTED,
10
11
  parseGrokFreeUsageVerdict,
11
12
  readGrokRateLimitHeaders,
12
13
  } from "./grok-ratelimit";
@@ -15,7 +16,6 @@ import { storedGrokRateLimit } from "./grok-ratelimit-store";
15
16
  import type { QuotaCollectionContext } from "../../quota/quota-support";
16
17
 
17
18
  const BILLING_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
18
- const BILLING_SOURCE = "cli-chat-proxy.grok.com/v1/billing";
19
19
  const USER_URL = "https://cli-chat-proxy.grok.com/v1/user?include=subscription";
20
20
  const GRPC_CREDITS_URL = "https://grok.com/grok_api_v2.GrokBuildBilling/GetGrokCreditsConfig";
21
21
  const GRPC_EMPTY_FRAME = new Uint8Array([0, 0, 0, 0, 0]);
@@ -31,10 +31,10 @@ const GRPC_EMPTY_FRAME = new Uint8Array([0, 0, 0, 0, 0]);
31
31
  */
32
32
  const PROBE_URL = "https://cli-chat-proxy.grok.com/v1/responses";
33
33
  const PROBE_BODY = {
34
- model: "grok-4.6",
35
- stream: false,
36
- max_output_tokens: 1,
37
- input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "hi" }] }],
34
+ model: "grok-4.7",
35
+ stream: true,
36
+ max_output_tokens: 256,
37
+ input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "Hi" }] }],
38
38
  };
39
39
 
40
40
  /**
@@ -194,10 +194,21 @@ async function probeRateLimit(
194
194
  const verdict = parseGrokFreeUsageVerdict(parsePayload(body), body);
195
195
  authoritative = verdict ? grokAuthoritativeWindow(verdict) : null;
196
196
  note = GROK_FREE_USAGE_EXHAUSTED;
197
+ } else if (response.status === 402) {
198
+ // A 402 names a spend/entitlement wall (e.g.
199
+ // `personal-team-blocked:spending-limit`), not a reading failure. The
200
+ // account cannot serve, so it is a refusal — but there is no token
201
+ // allowance to display, so we carry the note without a window.
202
+ await response.text();
203
+ note = GROK_SPENDING_LIMIT_EXHAUSTED;
197
204
  } else if (!response.ok) {
198
205
  // Drain so the connection is reusable, then report nothing: an unrelated
199
206
  // failure must not read as an exhausted allowance.
200
207
  await response.text();
208
+ } else {
209
+ // A 2xx stream is read for its headers only; cancel the body so the
210
+ // connection is released without waiting for the full completion.
211
+ await response.body?.cancel?.();
201
212
  }
202
213
  return {
203
214
  header: grokHeaderWindow(reading),
@@ -275,5 +286,3 @@ export async function fetchGrokQuota(
275
286
  // broken; the authoritative window below is what carries the verdict.
276
287
  return { source: "grok", plan, windows: ordered, error: null };
277
288
  }
278
-
279
- export { BILLING_SOURCE as GROK_BILLING_SOURCE };
@@ -62,11 +62,6 @@ export function storedGrokRateLimit(accountId: string, now = Date.now()): readon
62
62
  return snapshot.windows;
63
63
  }
64
64
 
65
- /** Whether a fresh reading exists, so the collector can skip its probe. */
66
- export function hasFreshGrokRateLimit(accountId: string, now = Date.now()): boolean {
67
- return storedGrokRateLimit(accountId, now) !== null;
68
- }
69
-
70
65
  /** Test seam. */
71
66
  export function clearGrokRateLimitSnapshots(): void {
72
67
  snapshots.clear();
@@ -37,6 +37,9 @@ const HEADER_RESET_TOKENS = "x-ratelimit-reset-tokens";
37
37
  /** The upstream code that carries the authoritative free-usage allowance. */
38
38
  export const GROK_FREE_USAGE_EXHAUSTED = "subscription:free-usage-exhausted";
39
39
 
40
+ /** A spend/entitlement wall code (402) — the account cannot serve. */
41
+ export const GROK_SPENDING_LIMIT_EXHAUSTED = "spending-limit";
42
+
40
43
  /** Kinds, so the view can tell an indicator from a verdict. */
41
44
  export const GROK_HEADER_WINDOW_KIND = "grok:cli-header";
42
45
  export const GROK_HEADER_REQUESTS_WINDOW_KIND = "grok:cli-header-requests";