cartethyia 2.7.4 → 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 (553) hide show
  1. package/.env.example +2 -0
  2. package/README.md +17 -5
  3. package/dist/dashboard/assets/{BannedPage-ChG5svFb.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-BIcWQun7.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
  8. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
  9. package/dist/dashboard/assets/{CliToolsPage-Bf2VelDe.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-ggeMSjte.js → CustomizationPage-BKj_r0rp.js} +1 -1
  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-U6AKaJcF.js → LoginPage-DkXb6dx-.js} +1 -1
  20. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.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-lsrx7NYg.js → ProxyPage-5SnUSy3j.js} +1 -1
  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-f0DE1h0-.js → SetupPage-WTa0sktC.js} +1 -1
  38. package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.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-C0K-c4eo.js +1 -0
  48. package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-DfbhQU4k.js} +1 -1
  50. package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-DympBNq4.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-ibRWU_uT.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-CQXVMn4P.js +1 -0
  62. package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
  63. package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.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-8fiE6tec.js → dialog-BEK7KP0H.js} +1 -1
  66. package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
  67. package/dist/dashboard/assets/{drawer-CqGYeOrd.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-BSAsYsmV.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-D-MTJxMr.js → formatters-BAACA727.js} +1 -1
  76. package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
  77. package/dist/dashboard/assets/{github-badge-CPK47xQx.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-DBNPOfhV.js → index-FQlj0HUT.js} +2 -2
  80. package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
  81. package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-C4gU5iOL.js} +1 -1
  82. package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
  83. package/dist/dashboard/assets/{input-Da2ZViWg.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-BXNeLw6M.js → layout-CajrYUnD.js} +1 -1
  86. package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
  87. package/dist/dashboard/assets/{list-row-BycOrrIV.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/network-C5UBACrJ.js +1 -0
  92. package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
  93. package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
  94. package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
  95. package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
  96. package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
  97. package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
  98. package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
  99. package/dist/dashboard/assets/routing-in0f_IfK.js +1 -0
  100. package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
  101. package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BLULNqTp.js} +1 -1
  102. package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
  103. package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
  104. package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
  105. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  106. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  107. package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-D2lIR0tg.js} +1 -1
  108. package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
  109. package/dist/dashboard/assets/{state-CkfdYWel.js → state-DTARjfiW.js} +1 -1
  110. package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
  111. package/dist/dashboard/assets/{switch-SYm237HG.js → switch-c0oPSnqW.js} +1 -1
  112. package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
  113. package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-m8WGNPrz.js} +1 -1
  114. package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
  115. package/dist/dashboard/console-backgrounds.jpg +0 -0
  116. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  117. package/dist/dashboard/index.html +2 -2
  118. package/dist/dashboard/index.html.gz +0 -0
  119. package/dist/dashboard/precompressed-assets.json +56 -55
  120. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  121. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  122. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  123. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  124. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  125. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  126. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  127. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  128. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  129. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  130. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  131. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  132. package/package.json +4 -6
  133. package/scripts/cli/update.ts +15 -41
  134. package/src/boot/app.ts +58 -2
  135. package/src/boot/dependencies.ts +786 -732
  136. package/src/boot/lifecycle.ts +11 -12
  137. package/src/config/cooldowns.ts +34 -55
  138. package/src/config/network.ts +1 -1
  139. package/src/config/package-paths.ts +1 -1
  140. package/src/config/providers.ts +13 -14
  141. package/src/config/resources.ts +0 -5
  142. package/src/config/runtime.ts +2 -5
  143. package/src/config/spec.ts +26 -6
  144. package/src/console/api-keys/ban-constants.ts +38 -0
  145. package/src/console/api-keys/contracts.ts +71 -62
  146. package/src/console/api-keys/routes.ts +48 -12
  147. package/src/console/auth/access.ts +4 -4
  148. package/src/console/auth/account-reset.ts +1 -1
  149. package/src/console/auth/audit-recorder.ts +1 -1
  150. package/src/console/auth/lockout.ts +7 -3
  151. package/src/console/auth/row-coercion.ts +57 -12
  152. package/src/console/auth/session-resolver.ts +1 -1
  153. package/src/console/auth/session-service.ts +8 -2
  154. package/src/console/auth/session.ts +37 -31
  155. package/src/console/auth/setup-service.ts +4 -3
  156. package/src/console/auth/user-store.ts +1 -1
  157. package/src/console/backup/9router-map.ts +0 -3
  158. package/src/console/backup/contracts.ts +9 -9
  159. package/src/console/backup/export-endpoint.ts +5 -6
  160. package/src/console/backup/nine-router.ts +1 -7
  161. package/src/console/backup/routes.ts +29 -33
  162. package/src/console/backup/service.ts +468 -468
  163. package/src/console/backup/store.ts +47 -29
  164. package/src/console/backup/validate.ts +11 -1
  165. package/src/console/cli-tools/contracts.ts +7 -7
  166. package/src/console/cli-tools/injectors/cline.ts +110 -110
  167. package/src/console/cli-tools/injectors/codex.ts +181 -181
  168. package/src/console/cli-tools/injectors/copilot.ts +108 -108
  169. package/src/console/cli-tools/injectors/driver.ts +247 -247
  170. package/src/console/cli-tools/injectors/jcode.ts +115 -115
  171. package/src/console/cli-tools/injectors/openclaw.ts +161 -161
  172. package/src/console/cli-tools/injectors/opencode.ts +153 -153
  173. package/src/console/cli-tools/routes.ts +1 -1
  174. package/src/console/cli-tools/service.ts +1 -1
  175. package/src/console/cli-tools/store.ts +2 -2
  176. package/src/console/console-router.ts +32 -0
  177. package/src/console/dashboard-assets.ts +9 -9
  178. package/src/console/domain-registration.ts +16 -2
  179. package/src/console/inferhub/client.ts +0 -7
  180. package/src/console/inferhub/key-store.ts +1 -1
  181. package/src/console/inferhub/normalize.ts +2 -2
  182. package/src/console/inferhub/routes.ts +1 -1
  183. package/src/console/inferhub/types.ts +1 -1
  184. package/src/console/observability/contracts.ts +1 -1
  185. package/src/console/observability/live.ts +31 -18
  186. package/src/console/observability/logs.ts +1 -1
  187. package/src/console/observability/sse.ts +62 -8
  188. package/src/console/observability/store.ts +20 -4
  189. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  190. package/src/console/providers/catalog/contracts.ts +39 -0
  191. package/src/console/providers/catalog/model-operations.ts +1 -1
  192. package/src/console/providers/catalog/provider-operations.ts +95 -17
  193. package/src/console/providers/catalog/public-model-store.ts +0 -0
  194. package/src/console/providers/catalog/routes.ts +27 -3
  195. package/src/console/providers/catalog/store.ts +147 -8
  196. package/src/console/providers/detail/routes.ts +1 -1
  197. package/src/console/providers/oauth/callback-listener.ts +100 -18
  198. package/src/console/providers/oauth/routes.ts +92 -13
  199. package/src/console/quota/account-quota-global.ts +41 -3
  200. package/src/console/quota/account-quota-shared.ts +10 -3
  201. package/src/console/quota/account-quota-tenant.ts +259 -66
  202. package/src/console/quota/daily-growth-job.ts +308 -0
  203. package/src/console/quota/native-identity.ts +2 -2
  204. package/src/console/quota/quota-view.ts +1 -1
  205. package/src/console/remote-support/routes.ts +1 -1
  206. package/src/console/remote-support/service.ts +2 -2
  207. package/src/console/routing/model/contracts.ts +1 -1
  208. package/src/console/routing/pools/contracts.ts +2 -2
  209. package/src/console/routing/pools/import-parse.ts +3 -3
  210. package/src/console/routing/pools/relay-deploy.ts +3 -3
  211. package/src/console/settings/contracts.ts +29 -2
  212. package/src/console/settings/store.ts +20 -0
  213. package/src/console/share/share-router.ts +100 -32
  214. package/src/console/share/share-stats.ts +4 -4
  215. package/src/console/share/share-usage.ts +1 -1
  216. package/src/console/shared/errors.ts +2 -2
  217. package/src/console/shared/object.ts +18 -0
  218. package/src/console/shared/read-through-cache.ts +4 -4
  219. package/src/console/shared/transaction.ts +14 -0
  220. package/src/console/system-prompt/contracts.ts +89 -12
  221. package/src/console/system-prompt/routes.ts +98 -45
  222. package/src/console/updates/apply-update.ts +244 -0
  223. package/src/console/updates/routes.ts +252 -97
  224. package/src/main.ts +11 -5
  225. package/src/network/http2-bidi.ts +1 -1
  226. package/src/network/ip-utils.ts +298 -0
  227. package/src/network/outbound-fetch.ts +1 -1
  228. package/src/network/pool/agent.ts +7 -6
  229. package/src/network/pool/byte-accounting.ts +1 -1
  230. package/src/network/pool/resolver.ts +16 -12
  231. package/src/network/pool/selector.ts +150 -136
  232. package/src/network/pool-health-machine.ts +1 -1
  233. package/src/network/rate-limit-verdict.ts +1 -1
  234. package/src/network/retry.ts +1 -1
  235. package/src/network/ssrf.ts +20 -71
  236. package/src/observability/event-log.ts +2 -2
  237. package/src/observability/event-query.ts +59 -291
  238. package/src/observability/log-sanitize.ts +1 -1
  239. package/src/observability/metrics.ts +4 -4
  240. package/src/observability/payload-capture.ts +6 -5
  241. package/src/observability/payload-store.ts +1 -1
  242. package/src/observability/runtime-metrics.ts +1 -1
  243. package/src/observability/telemetry-buffer.ts +12 -3
  244. package/src/observability/telemetry-reconciliation.ts +3 -3
  245. package/src/observability/token-speed.ts +1 -1
  246. package/src/persistence/connection-url.ts +1 -1
  247. package/src/persistence/db-handle.ts +1 -1
  248. package/src/persistence/db-pg.ts +2 -2
  249. package/src/persistence/db-sqlite.ts +3 -3
  250. package/src/persistence/dialect.ts +5 -1
  251. package/src/persistence/readiness.ts +1 -1
  252. package/src/persistence/redis.ts +1 -1
  253. package/src/persistence/schema.ts +113 -40
  254. package/src/persistence/shared-cache.ts +2 -2
  255. package/src/persistence/sort-order.ts +1 -1
  256. package/src/persistence/stores/api-key-store.ts +10 -1
  257. package/src/persistence/stores/share-store.ts +20 -8
  258. package/src/persistence/system-prompt-store.ts +63 -18
  259. package/src/persistence/tenant-preferences.ts +1 -1
  260. package/src/persistence/ttl-cache.ts +3 -3
  261. package/src/persistence/usage-flush.ts +7 -2
  262. package/src/protocol/canonical-model.ts +1 -1
  263. package/src/protocol/codecs.ts +6 -10
  264. package/src/protocol/dsml.ts +3 -49
  265. package/src/protocol/image-clamp.ts +2 -2
  266. package/src/protocol/reasoning-text.ts +1 -1
  267. package/src/protocol/reasoning.ts +7 -52
  268. package/src/protocol/registry.ts +50 -15
  269. package/src/protocol/request/chat.ts +46 -19
  270. package/src/protocol/request/codex.ts +1 -1
  271. package/src/protocol/request/messages.ts +46 -14
  272. package/src/protocol/request/responses.ts +19 -10
  273. package/src/protocol/response/chat.ts +25 -10
  274. package/src/protocol/response/codex.ts +1 -1
  275. package/src/protocol/response/messages.ts +1 -1
  276. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  277. package/src/protocol/response/responses.ts +1 -1
  278. package/src/protocol/sse-decoder.ts +50 -1
  279. package/src/protocol/stop-reason.ts +2 -2
  280. package/src/protocol/think-split.ts +347 -0
  281. package/src/protocol/translation/attachment-integrity.ts +3 -3
  282. package/src/protocol/translation/cache-controls.ts +8 -20
  283. package/src/protocol/translation/capabilities.ts +6 -6
  284. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  285. package/src/protocol/translation/dialect/inband.ts +39 -0
  286. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  287. package/src/protocol/translation/dialect/qwen.ts +114 -0
  288. package/src/protocol/translation/dialect/resolver.ts +83 -0
  289. package/src/protocol/translation/dialect/rules.ts +93 -0
  290. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  291. package/src/protocol/translation/dialect/types.ts +58 -0
  292. package/src/protocol/translation/quirks.ts +18 -4
  293. package/src/protocol/translation/thinking.ts +12 -252
  294. package/src/protocol/translation/tool-id.ts +3 -3
  295. package/src/protocol/translation/tool-repair.ts +1 -1
  296. package/src/protocol/upstream/post-json.ts +6 -1
  297. package/src/providers/adapters/compatible-adapter.ts +42 -3
  298. package/src/providers/authentication/jwt-validator.ts +0 -5
  299. package/src/providers/authentication/oauth-client.ts +254 -253
  300. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  301. package/src/providers/bundled-discovery-providers.ts +6 -30
  302. package/src/providers/configured-openai-providers.ts +82 -97
  303. package/src/providers/default-registry.ts +23 -35
  304. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  305. package/src/providers/discovery/discovery-types.ts +0 -1
  306. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  307. package/src/providers/discovery/probe-phases.ts +48 -13
  308. package/src/providers/discovery/probing-service.ts +6 -8
  309. package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
  310. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  311. package/src/providers/integrations/antigravity/antigravity-protocol.ts +0 -14
  312. package/src/providers/integrations/antigravity/antigravity.ts +2 -2
  313. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  314. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  315. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  316. package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
  317. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  318. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  319. package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
  320. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  321. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
  322. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  323. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  324. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  325. package/src/providers/integrations/cline/cline.ts +1 -1
  326. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  327. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  328. package/src/providers/integrations/commandcode/commandcode.ts +75 -115
  329. package/src/providers/integrations/commandcode/quota.ts +131 -51
  330. package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
  331. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  332. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  333. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  334. package/src/providers/integrations/cursor/cursor.ts +38 -5
  335. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  336. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  337. package/src/providers/integrations/factory/factory.ts +9 -9
  338. package/src/providers/integrations/github/github-discovery.ts +55 -10
  339. package/src/providers/integrations/github/github-oauth.ts +6 -5
  340. package/src/providers/integrations/github/github.ts +41 -14
  341. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  342. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  343. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  344. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  345. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  346. package/src/providers/integrations/grok/grok.ts +86 -36
  347. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  348. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  349. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  350. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  351. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  352. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  353. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  354. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  355. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  356. package/src/providers/integrations/kiro/kiro.ts +81 -68
  357. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  358. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  359. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  360. package/src/providers/integrations/opencode/provider.ts +17 -24
  361. package/src/providers/integrations/qoder/qoder-catalog.ts +85 -8
  362. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  363. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  364. package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
  365. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  366. package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
  367. package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
  368. package/src/providers/integrations/qoder/qoder.ts +354 -62
  369. package/src/providers/integrations/shared/connect.ts +0 -54
  370. package/src/providers/integrations/shared/hash.ts +15 -0
  371. package/src/providers/integrations/shared/session-cache.ts +136 -0
  372. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  373. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  374. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  375. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  376. package/src/providers/integrations/trae/trae.ts +53 -10
  377. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  378. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  379. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  380. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  381. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  382. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  383. package/src/providers/operations/account-error-classification.ts +131 -116
  384. package/src/providers/operations/account-health-service.ts +31 -39
  385. package/src/providers/operations/account-reset-service.ts +58 -1
  386. package/src/providers/operations/cli-platform.ts +31 -5
  387. package/src/providers/operations/client-version-resolver.ts +4 -6
  388. package/src/providers/operations/client-versions.ts +10 -7
  389. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  390. package/src/providers/operations/provider-catalog-service.ts +18 -2
  391. package/src/providers/operations/provider-credential-service.ts +19 -2
  392. package/src/providers/provider-contracts.ts +18 -7
  393. package/src/providers/provider-metadata.ts +17 -2
  394. package/src/providers/provider-model-definition.ts +22 -1
  395. package/src/providers/provider-probe.ts +4 -2
  396. package/src/providers/provider-usage.ts +81 -16
  397. package/src/providers/quota/cache.ts +29 -0
  398. package/src/providers/quota/quota-contracts.ts +4 -0
  399. package/src/providers/quota/refresh.ts +27 -4
  400. package/src/providers/quota/snapshot.ts +94 -0
  401. package/src/providers/search/search-provider.ts +1 -3
  402. package/src/providers/search/search-providers.ts +2 -1
  403. package/src/security/abuse.ts +4 -4
  404. package/src/security/admission/service.ts +2 -2
  405. package/src/security/admission/ttl.ts +61 -61
  406. package/src/security/api-key-auth.ts +16 -4
  407. package/src/security/client-router-fingerprint.ts +4 -4
  408. package/src/security/credential-codec.ts +3 -3
  409. package/src/security/csrf.ts +2 -2
  410. package/src/security/ip-boundary.ts +16 -189
  411. package/src/security/model-access-rule.ts +1 -1
  412. package/src/security/outbound-headers.ts +18 -0
  413. package/src/shared/invoke-guard.ts +47 -0
  414. package/src/transport/contracts.ts +13 -4
  415. package/src/transport/dispatch/attempt-finalize.ts +1 -1
  416. package/src/transport/dispatch/capture-policy.ts +34 -37
  417. package/src/transport/dispatch/empty-stream.ts +23 -20
  418. package/src/transport/dispatch/generation.ts +25 -45
  419. package/src/transport/dispatch/native-shared.ts +127 -0
  420. package/src/transport/dispatch/proxy-request.ts +3 -1
  421. package/src/transport/dispatch/responses-compact.ts +25 -46
  422. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  423. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  424. package/src/transport/dispatch/streaming/stream.ts +7 -3
  425. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  426. package/src/transport/dispatch/systemone.ts +20 -48
  427. package/src/transport/dispatch/token-count.ts +41 -38
  428. package/src/transport/dispatch/websearch.ts +19 -45
  429. package/src/transport/drain-endpoint.ts +1 -1
  430. package/src/transport/failure-policy.ts +6 -0
  431. package/src/transport/guards/auth-guard.ts +0 -6
  432. package/src/transport/guards/body-policy.ts +3 -3
  433. package/src/transport/guards/headroom-guard.ts +1 -1
  434. package/src/transport/guards/pipeline.ts +1 -1
  435. package/src/transport/guards/request-context.ts +12 -17
  436. package/src/transport/request/preparer.ts +286 -7
  437. package/src/transport/request/rtk/compress-request.ts +3 -3
  438. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  439. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  440. package/src/transport/request/state.ts +1 -13
  441. package/src/transport/request/system-prompt-injection.ts +74 -11
  442. package/src/transport/request/tenant-preferences.ts +22 -0
  443. package/src/transport/routing/candidate-index.ts +2 -2
  444. package/src/transport/routing/round-robin.ts +1 -1
  445. package/src/transport/routing/route-catalog.ts +17 -18
  446. package/src/transport/routing/route-model.ts +126 -33
  447. package/src/transport/routing/router.ts +152 -37
  448. package/src/transport/shutdown-notice.ts +2 -2
  449. package/src/transport/surface/adapters.ts +3 -3
  450. package/src/transport/surface/chat/encode.ts +7 -7
  451. package/src/transport/surface/chat/parse.ts +7 -7
  452. package/src/transport/surface/completion.ts +2 -2
  453. package/src/transport/surface/content-parts.ts +1 -1
  454. package/src/transport/surface/dialects.ts +2 -2
  455. package/src/transport/surface/messages/parse.ts +3 -3
  456. package/src/transport/surface/responses/adapter.ts +1 -1
  457. package/src/transport/surface/responses/errors.ts +0 -9
  458. package/src/transport/vision-handoff-cache.ts +58 -0
  459. package/src/transport/vision-handoff.ts +376 -0
  460. package/src/workers/account-identity-sweep.ts +2 -2
  461. package/src/workers/buddy-growth-tasks.ts +392 -346
  462. package/src/workers/daily-checkin.ts +102 -49
  463. package/src/workers/maintenance-lease.ts +2 -35
  464. package/src/workers/oauth-refresh-sweep.ts +8 -1
  465. package/src/workers/quota-refresh-sweep.ts +120 -82
  466. package/src/workers/scheduler.ts +67 -4
  467. package/src/workers/sweep-runner.ts +24 -5
  468. package/src/workers/zcode-gift-claim.ts +108 -0
  469. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  470. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  471. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  472. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  473. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  474. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
  475. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  476. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
  477. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  478. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  479. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
  480. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  481. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  482. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  483. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
  484. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  485. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
  486. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  487. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  488. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  489. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
  490. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  491. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  492. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
  493. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  494. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
  495. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  496. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  497. package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
  498. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  499. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  500. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
  501. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  502. package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
  503. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  504. package/dist/dashboard/assets/app-a159k0ub.css +0 -2
  505. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  506. package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
  507. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  508. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  509. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  510. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  511. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
  512. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  513. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  514. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  515. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  516. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  517. package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
  518. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  519. package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
  520. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  521. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  522. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  523. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  524. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  525. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  526. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  527. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  528. package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
  529. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  530. package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
  531. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  532. package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
  533. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  534. package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
  535. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  536. package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
  537. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  538. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  539. package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
  540. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  541. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  542. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  543. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  544. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  545. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  546. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  547. package/src/network/response-headers.ts +0 -39
  548. package/src/protocol/response/dsml.ts +0 -38
  549. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  550. /package/dist/dashboard/assets/{app-BayTTy01.js → app-Bgd3zANQ.js} +0 -0
  551. /package/dist/dashboard/assets/{app-BayTTy01.js.gz → app-Bgd3zANQ.js.gz} +0 -0
  552. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  553. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -44,17 +44,34 @@ export const GITHUB_ENDPOINT_PATH = "/chat/completions" as const;
44
44
  */
45
45
  export const GITHUB_RESPONSES_ENDPOINT_PATH = "/responses" as const;
46
46
 
47
+ /**
48
+ * Anthropic Messages surface. Copilot serves the premium Claude family
49
+ * (`claude-sonnet-*`, `claude-opus-*`, `claude-haiku-*`, `claude-fable-*`)
50
+ * on the native `/v1/messages` wire, and some SKUs are messages-only. The
51
+ * adapter's shared pipeline already speaks the messages codec; this constant
52
+ * lets discovery route those rows here instead of dropping them.
53
+ */
54
+ export const GITHUB_MESSAGES_ENDPOINT_PATH = "/v1/messages" as const;
55
+
47
56
 
48
57
 
49
58
  /**
50
- * The highest reasoning effort Copilot serves. A caller asking for `max` or
51
- * `xhigh` is answered at `high` rather than refused: the model has no level
52
- * above it, and the request is otherwise valid.
59
+ * The highest reasoning effort Copilot serves as a fallback when a model does
60
+ * not declare its own ladder. A caller asking for `max` or `xhigh` is answered
61
+ * at `high` rather than refused: the model has no level above it, and the
62
+ * request is otherwise valid.
53
63
  */
54
64
  const GITHUB_REASONING_EFFORT_CAP = "high";
55
65
  const GITHUB_CAPPED_EFFORTS = new Set(["max", "xhigh"]);
56
66
 
57
- /** Rewrites an effort above Copilot's ceiling to `high`, on either wire. */
67
+ /**
68
+ * Rewrites an effort above Copilot's ceiling to the highest level we know the
69
+ * model accepts. The shared encoder already pinned the effort to the model's
70
+ * declared ladder (`resolveThinkingForModel` reads `reasoningEfforts` from the
71
+ * catalog); this hook only guards a bare fallback so a caller asking for
72
+ * `max`/`xhigh` on a model without a declared ladder is answered at `high`
73
+ * rather than refused.
74
+ */
58
75
  function clampGithubReasoningEffort(payload: Record<string, unknown>): void {
59
76
  const effort = payload["reasoning_effort"];
60
77
  if (typeof effort === "string" && GITHUB_CAPPED_EFFORTS.has(effort)) {
@@ -88,12 +105,6 @@ export const GITHUB_EXCLUDED_MODEL_IDS: ReadonlySet<string> = new Set([
88
105
  "gpt-6-luna-medium",
89
106
  "gpt-6-luna-high",
90
107
  "kimi-k3",
91
- "kimi-k3-base",
92
- "kimi-k3-copilot",
93
- "mai-code-1-flash-4th",
94
- "mai-code-1-flash-secondary",
95
- "mai-code-1-flash-tertiary",
96
- "mai-code-1.1-flash",
97
108
  ]);
98
109
 
99
110
  const modelRoutesByCredential = new Map<string, ReadonlyMap<string, GithubModelRoute>>();
@@ -122,7 +133,10 @@ function parseRouteMap(raw: string): Map<string, GithubModelRoute> | undefined {
122
133
  if (typeof modelId !== "string" || route === null || typeof route !== "object") continue;
123
134
  const wireFamily = (route as { wireFamily?: unknown }).wireFamily;
124
135
  const endpointPath = (route as { endpointPath?: unknown }).endpointPath;
125
- if ((wireFamily === "chat" || wireFamily === "responses") && typeof endpointPath === "string") {
136
+ if (
137
+ (wireFamily === "chat" || wireFamily === "responses" || wireFamily === "messages") &&
138
+ typeof endpointPath === "string"
139
+ ) {
126
140
  map.set(modelId, { wireFamily, endpointPath });
127
141
  }
128
142
  }
@@ -162,7 +176,7 @@ async function writeSharedModelRoutes(
162
176
  }
163
177
 
164
178
  export interface GithubModelRoute {
165
- readonly wireFamily: "chat" | "responses";
179
+ readonly wireFamily: "chat" | "responses" | "messages";
166
180
  readonly endpointPath: string;
167
181
  }
168
182
  const GITHUB_AUTO_SESSION_CACHE_MAX_ENTRIES = 50;
@@ -187,8 +201,8 @@ export function recordGithubModelRoutes(
187
201
  if (key === undefined) return;
188
202
  const routes = models
189
203
  .filter(
190
- (model): model is ModelDefinition & { readonly wireFamily: "chat" | "responses" } =>
191
- model.wireFamily === "chat" || model.wireFamily === "responses",
204
+ (model): model is ModelDefinition & { readonly wireFamily: "chat" | "responses" | "messages" } =>
205
+ model.wireFamily === "chat" || model.wireFamily === "responses" || model.wireFamily === "messages",
192
206
  )
193
207
  .map((model) => [
194
208
  model.modelId.toLowerCase(),
@@ -304,6 +318,9 @@ function routeFromAutoModel(value: unknown): GithubModelRoute | undefined {
304
318
  if (endpoints.has("/responses")) {
305
319
  return { wireFamily: "responses", endpointPath: GITHUB_RESPONSES_ENDPOINT_PATH };
306
320
  }
321
+ if (endpoints.has("/messages")) {
322
+ return { wireFamily: "messages", endpointPath: GITHUB_MESSAGES_ENDPOINT_PATH };
323
+ }
307
324
  return undefined;
308
325
  }
309
326
 
@@ -640,10 +657,20 @@ class GithubAdapter extends OpenAICompatibleAdapter {
640
657
  "editor-device-id": await getOrCreateInstallId("github"),
641
658
  "openai-intent": "conversation-agent",
642
659
  "x-agent-task-id": requestId,
660
+ "x-interaction-id": requestId,
643
661
  "x-initiator": isAgentInitiated(request) ? "agent" : "user",
644
662
  "x-interaction-type": "conversation-agent",
645
663
  "x-request-id": requestId,
664
+ "x-vscode-user-agent-library-version": "vscode-chat/0.72.0",
646
665
  });
666
+ // The copy Claude family is served on the native Anthropic Messages wire,
667
+ // which gates feature betas behind `anthropic-beta` (mirroring the
668
+ // Copilot extension's `getAnthropicBetaHeader`). Adaptive thinking is the
669
+ // baseline the model roster declares, so it is requested for every messages
670
+ // route; the header is scoped to that wire and never sent elsewhere.
671
+ if (candidate?.wire_family === "messages") {
672
+ headers["anthropic-beta"] = "interleaved-thinking-2025-05-14";
673
+ }
647
674
  if (allParts(request).some(containsImage)) {
648
675
  headers["copilot-vision-request"] = "true";
649
676
  } else {
@@ -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 {