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
@@ -10,39 +10,13 @@ import { createApiKeyAdapter, type ApiKeyProviderSpec } from "./configured-provi
10
10
  * OpenAI-compatible contract. Providers with static catalogs or additional
11
11
  * upstream behavior remain declared beside their special handling.
12
12
  */
13
- export const DISCOVERY_BACKED_PROVIDER_IDS = [
14
- "groq",
15
- "together",
16
- "deepinfra",
17
- "siliconflow",
18
- "siliconflowcn",
19
- "novita",
20
- "larprouter",
21
- "venice",
22
- "nanogpt",
23
- "baseten",
24
- "synthetic",
25
- "stepfun",
26
- "sakana",
27
- "helmcode",
28
- "coralbricks",
29
- "aiand",
30
- "wafer",
31
- "firepass",
32
- "zhipucoding",
33
- "dashscope",
34
- "qianfan",
35
- ] as const;
36
-
37
- export type DiscoveryBackedProviderId = (typeof DISCOVERY_BACKED_PROVIDER_IDS)[number];
38
-
39
13
  type DiscoveryBackedCapabilities = Pick<
40
14
  ProviderModule,
41
15
  "endpointPathsByWireFamily" | "loadAdapter" | "loadModelDiscovery"
42
16
  >;
43
17
 
44
18
  type ModelDiscoveryFactory = NonNullable<ProviderModule["loadModelDiscovery"]>;
45
- type OpenAIModelDiscoveryFactory = (
19
+ export type OpenAIModelDiscoveryFactory = (
46
20
  providerId: string,
47
21
  options?: {
48
22
  readonly headers?: (credential: string) => Readonly<Record<string, string>>;
@@ -71,10 +45,12 @@ const DISCOVERY_BACKED_PROVIDER_SPECS = {
71
45
  zhipucoding: VERSIONED_ROOT_API_KEY_SPECS.zhipucoding,
72
46
  dashscope: GENERIC_API_KEY_SPECS.dashscope,
73
47
  qianfan: VERSIONED_ROOT_API_KEY_SPECS.qianfan,
74
- } satisfies Readonly<Record<DiscoveryBackedProviderId, ApiKeyProviderSpec>>;
48
+ } satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
75
49
 
76
- function discoveryBackedCapabilities(
77
- providerId: DiscoveryBackedProviderId,
50
+ type DiscoveryBackedProviderId = keyof typeof DISCOVERY_BACKED_PROVIDER_SPECS;
51
+
52
+ export function discoveryBackedCapabilities(
53
+ providerId: string,
78
54
  spec: ApiKeyProviderSpec,
79
55
  openAIModelDiscovery: OpenAIModelDiscoveryFactory,
80
56
  ): DiscoveryBackedCapabilities {
@@ -1,12 +1,36 @@
1
1
  import type { ApiKeyProviderSpec } from "./configured-provider";
2
2
  import type { ProviderId } from "./provider-contracts";
3
3
 
4
+ /**
5
+ * The shared spec builder for every builtin bearer-AI provider: "bearer auth
6
+ * against the provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible
7
+ * chat + responses, with the endpoint paths declared *below* the version root".
8
+ *
9
+ * `joinUrl` is plain concatenation and nothing rewrites a declared path, so a
10
+ * base already rooted at a version (`/openai/v1`, `/v1/openai`, `/v3/openai`,
11
+ * `/api/v1`, `/v2`, `/inference/v1`) plus a `/v1/…` path would double the
12
+ * segment and 404 every request. These specs therefore declare the path below
13
+ * the version root — the provider stating the truth about its own wire, not a
14
+ * correction applied to it.
15
+ */
16
+ function apiKeySpec(
17
+ providerId: ProviderId,
18
+ paths: Readonly<Partial<Record<"chat" | "responses", string>>>,
19
+ ): ApiKeyProviderSpec {
20
+ return {
21
+ provider_id: providerId,
22
+ endpoint_paths_by_wire_family: paths,
23
+ };
24
+ }
25
+
26
+ const BEARER_PATHS = { chat: "/chat/completions", responses: "/responses" } as const;
27
+
4
28
  /**
5
29
  * Builtin providers whose entire adapter contract is "bearer auth against the
6
30
  * provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible chat +
7
- * responses, `/v1`-prefixed paths". They carry no catalog, no OAuth, and no
8
- * provider-specific payload hook, so they share one spec shape rather than
9
- * one module each.
31
+ * responses, with endpoint paths declared below the base's version root". They
32
+ * carry no catalog, no OAuth, and no provider-specific payload hook, so they
33
+ * share one spec shape rather than one module each.
10
34
  *
11
35
  * `base_url` is resolved per provider by `providerBaseUrl(provider_id)`.
12
36
  *
@@ -14,29 +38,31 @@ import type { ProviderId } from "./provider-contracts";
14
38
  * than a static catalog: every one of them republishes an aggregator's whole
15
39
  * roster, which changes faster than a committed array can. Each registry row
16
40
  * pairs this spec with `openAIModelDiscovery`.
41
+ *
42
+ * The id list is derived from the spec record so the two cannot drift apart.
17
43
  */
18
- export const GENERIC_API_KEY_PROVIDER_IDS = [
19
- "larprouter",
20
- "mistral",
21
- "fireworks",
22
- "nvidia",
23
- "gmi",
24
- "ollamacloud",
25
- "together",
26
- "siliconflow",
27
- "siliconflowcn",
28
- "nanogpt",
29
- "baseten",
30
- "synthetic",
31
- "stepfun",
32
- "sakana",
33
- "helmcode",
34
- "coralbricks",
35
- "aiand",
36
- "wafer",
37
- "coreweave",
38
- "qwen-portal",
39
- "dashscope",
44
+ export const GENERIC_API_KEY_SPECS = {
45
+ larprouter: apiKeySpec("larprouter", BEARER_PATHS),
46
+ mistral: apiKeySpec("mistral", BEARER_PATHS),
47
+ fireworks: apiKeySpec("fireworks", BEARER_PATHS),
48
+ nvidia: apiKeySpec("nvidia", BEARER_PATHS),
49
+ gmi: apiKeySpec("gmi", BEARER_PATHS),
50
+ ollamacloud: apiKeySpec("ollamacloud", BEARER_PATHS),
51
+ together: apiKeySpec("together", BEARER_PATHS),
52
+ siliconflow: apiKeySpec("siliconflow", BEARER_PATHS),
53
+ siliconflowcn: apiKeySpec("siliconflowcn", BEARER_PATHS),
54
+ nanogpt: apiKeySpec("nanogpt", BEARER_PATHS),
55
+ baseten: apiKeySpec("baseten", BEARER_PATHS),
56
+ synthetic: apiKeySpec("synthetic", BEARER_PATHS),
57
+ stepfun: apiKeySpec("stepfun", BEARER_PATHS),
58
+ sakana: apiKeySpec("sakana", BEARER_PATHS),
59
+ helmcode: apiKeySpec("helmcode", BEARER_PATHS),
60
+ coralbricks: apiKeySpec("coralbricks", BEARER_PATHS),
61
+ aiand: apiKeySpec("aiand", BEARER_PATHS),
62
+ wafer: apiKeySpec("wafer", BEARER_PATHS),
63
+ coreweave: apiKeySpec("coreweave", BEARER_PATHS),
64
+ dashscope: apiKeySpec("dashscope", BEARER_PATHS),
65
+ "qwen-portal": apiKeySpec("qwen-portal", BEARER_PATHS),
40
66
  // `deepseek` is intentionally absent: it dispatches on the Anthropic Messages
41
67
  // wire at its `/anthropic` root, not the OpenAI chat/responses wires, so it
42
68
  // carries a dedicated entry in `default-registry.ts` instead.
@@ -45,10 +71,24 @@ export const GENERIC_API_KEY_PROVIDER_IDS = [
45
71
  // already rooted at a version segment that the `/v1`-prefixed path this shape
46
72
  // pins would duplicate (`/openai/v1`, `/v1/openai`, `/v3/openai`, `/api/v1`,
47
73
  // `/v2`, and `/inference/v1`), so `joinUrl` would produce
48
- // `…/v1/v1/chat/completions`. They use `versionedRootApiKeySpec` instead,
74
+ // `…/v1/v1/chat/completions`. They use the versioned-root spec instead,
49
75
  // which pins the path below the version root — the same reason `cerebras`
50
76
  // declares `/chat/completions` explicitly.
51
- ] as const;
77
+ } satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
78
+
79
+ /**
80
+ * One id that has both a generic spec and a registry row.
81
+ *
82
+ * Exported so the registry can be checked against the spec list rather than
83
+ * repeating the id as a string: `discoveryBackedProvider` takes this type, so a
84
+ * row naming a provider with no spec is a compile error instead of an
85
+ * `undefined` adapter at first dispatch.
86
+ */
87
+ export type GenericApiKeyProviderId = keyof typeof GENERIC_API_KEY_SPECS;
88
+
89
+ export const GENERIC_API_KEY_PROVIDER_IDS = Object.keys(
90
+ GENERIC_API_KEY_SPECS,
91
+ ) as readonly GenericApiKeyProviderId[];
52
92
 
53
93
  /**
54
94
  * Ids whose base URL already ends at a version segment.
@@ -59,77 +99,22 @@ export const GENERIC_API_KEY_PROVIDER_IDS = [
59
99
  * version root. That is the provider stating the truth about its own wire, not
60
100
  * a correction applied to it: a wrong path now reaches the operator as the
61
101
  * wrong URL instead of being quietly rewritten into a different address.
62
- */
63
- export const VERSIONED_ROOT_API_KEY_PROVIDER_IDS = [
64
- "groq",
65
- "deepinfra",
66
- "novita",
67
- "venice",
68
- "qianfan",
69
- "zhipucoding",
70
- "firepass",
71
- ] as const;
72
-
73
- export type VersionedRootApiKeyProviderId =
74
- (typeof VERSIONED_ROOT_API_KEY_PROVIDER_IDS)[number];
75
-
76
- function versionedRootApiKeySpec(providerId: ProviderId): ApiKeyProviderSpec {
77
- return {
78
- provider_id: providerId,
79
- endpoint_paths_by_wire_family: {
80
- chat: "/chat/completions",
81
- responses: "/responses",
82
- },
83
- };
84
- }
85
-
86
- export const VERSIONED_ROOT_API_KEY_SPECS = {
87
- groq: versionedRootApiKeySpec("groq"),
88
- deepinfra: versionedRootApiKeySpec("deepinfra"),
89
- novita: versionedRootApiKeySpec("novita"),
90
- venice: versionedRootApiKeySpec("venice"),
91
- qianfan: versionedRootApiKeySpec("qianfan"),
92
- zhipucoding: versionedRootApiKeySpec("zhipucoding"),
93
- firepass: versionedRootApiKeySpec("firepass"),
94
- } satisfies Readonly<Record<VersionedRootApiKeyProviderId, ApiKeyProviderSpec>>;
95
-
96
- /**
97
- * One id that has both a generic spec and a registry row.
98
102
  *
99
- * Exported so the registry can be checked against the spec list rather than
100
- * repeating the id as a string: `discoveryBackedProvider` takes this type, so a
101
- * row naming a provider with no spec is a compile error instead of an
102
- * `undefined` adapter at first dispatch.
103
+ * The id list is derived from the spec record so the two cannot drift apart.
103
104
  */
104
- export type GenericApiKeyProviderId = (typeof GENERIC_API_KEY_PROVIDER_IDS)[number];
105
+ export const VERSIONED_ROOT_API_KEY_SPECS = {
106
+ groq: apiKeySpec("groq", BEARER_PATHS),
107
+ deepinfra: apiKeySpec("deepinfra", BEARER_PATHS),
108
+ novita: apiKeySpec("novita", BEARER_PATHS),
109
+ venice: apiKeySpec("venice", BEARER_PATHS),
110
+ qianfan: apiKeySpec("qianfan", BEARER_PATHS),
111
+ zhipucoding: apiKeySpec("zhipucoding", BEARER_PATHS),
112
+ firepass: apiKeySpec("firepass", BEARER_PATHS),
113
+ } satisfies Readonly<Record<string, ApiKeyProviderSpec>>;
105
114
 
106
- function genericApiKeySpec(providerId: GenericApiKeyProviderId): ApiKeyProviderSpec {
107
- // These roots are *not* bare hosts — every one of them already ends at `/v1`
108
- // — so the path is declared below that root. Both spec shapes declare the same
109
- // thing, so this is the one implementation.
110
- return versionedRootApiKeySpec(providerId);
111
- }
115
+ export type VersionedRootApiKeyProviderId =
116
+ keyof typeof VERSIONED_ROOT_API_KEY_SPECS;
112
117
 
113
- export const GENERIC_API_KEY_SPECS = {
114
- larprouter: genericApiKeySpec("larprouter"),
115
- mistral: genericApiKeySpec("mistral"),
116
- fireworks: genericApiKeySpec("fireworks"),
117
- nvidia: genericApiKeySpec("nvidia"),
118
- gmi: genericApiKeySpec("gmi"),
119
- ollamacloud: genericApiKeySpec("ollamacloud"),
120
- together: genericApiKeySpec("together"),
121
- siliconflow: genericApiKeySpec("siliconflow"),
122
- siliconflowcn: genericApiKeySpec("siliconflowcn"),
123
- nanogpt: genericApiKeySpec("nanogpt"),
124
- baseten: genericApiKeySpec("baseten"),
125
- synthetic: genericApiKeySpec("synthetic"),
126
- stepfun: genericApiKeySpec("stepfun"),
127
- sakana: genericApiKeySpec("sakana"),
128
- helmcode: genericApiKeySpec("helmcode"),
129
- coralbricks: genericApiKeySpec("coralbricks"),
130
- aiand: genericApiKeySpec("aiand"),
131
- wafer: genericApiKeySpec("wafer"),
132
- coreweave: genericApiKeySpec("coreweave"),
133
- dashscope: genericApiKeySpec("dashscope"),
134
- "qwen-portal": genericApiKeySpec("qwen-portal"),
135
- } satisfies Readonly<Record<GenericApiKeyProviderId, ApiKeyProviderSpec>>;
118
+ export const VERSIONED_ROOT_API_KEY_PROVIDER_IDS = Object.keys(
119
+ VERSIONED_ROOT_API_KEY_SPECS,
120
+ ) as readonly VersionedRootApiKeyProviderId[];
@@ -5,7 +5,7 @@
5
5
  import {
6
6
  GENERIC_API_KEY_SPECS,
7
7
  } from "./configured-openai-providers";
8
- import { createDiscoveryBackedProviderCapabilities } from "./bundled-discovery-providers";
8
+ import { createDiscoveryBackedProviderCapabilities, discoveryBackedCapabilities } from "./bundled-discovery-providers";
9
9
  import { createApiKeyAdapter } from "./configured-provider";
10
10
  import type { ApiKeyProviderSpec } from "./configured-provider";
11
11
  import { oauthCapability, quotaCapability, type ProviderModuleCapabilities } from "./provider-capabilities";
@@ -131,39 +131,6 @@ function qoderDiscovery(
131
131
  }
132
132
 
133
133
 
134
- /**
135
- * Builds the `loadAdapter` + `loadModelDiscovery` pair every plain bearer
136
- * provider needs.
137
- *
138
- * Only the base URL differs between them, so both halves are shared: the
139
- * adapter is the generic spec and the discovery call is a bearer
140
- * `GET {base}/models`. Keeping them in one function is what stops the pairing
141
- * from drifting — registering a provider with one half and not the other is
142
- * exactly how `gmi`, `nvidia`, and `fireworks` came to ship with no catalog
143
- * *and* no discovery, which is a provider that lists zero models with no way to
144
- * fetch any. `test/providers/generic-provider-completeness.test.ts` holds both.
145
- */
146
- function discoveryBacked(
147
- providerId: string,
148
- spec: ApiKeyProviderSpec,
149
- ): ProviderModuleCapabilities {
150
- return {
151
- // The registry map is what discovery and probing read
152
- // (`discoveryPathsFor`), while the spec's copy is what the adapter
153
- // dispatches on. Setting only the spec leaves a discovered model resolving
154
- // its wire from the generic default instead of the path the adapter will
155
- // actually call, which is how a probe verifies one endpoint while dispatch
156
- // hits another.
157
- ...(spec.endpoint_paths_by_wire_family === undefined
158
- ? {}
159
- : { endpointPathsByWireFamily: spec.endpoint_paths_by_wire_family }),
160
- loadAdapter: async () => createApiKeyAdapter(spec),
161
- loadModelDiscovery: openAIModelDiscovery(providerId, {
162
- headers: (credential) => ({ authorization: `Bearer ${credential}` }),
163
- }),
164
- };
165
- }
166
-
167
134
  function openAIModelDiscovery(
168
135
  providerId: string,
169
136
  options?: {
@@ -617,6 +584,27 @@ export const PROVIDER_CAPABILITIES = {
617
584
  // and Z.AI publishes no refresh grant for it (`refresh "none"` upstream).
618
585
  loadAuthentication: oauthCapability(() => import("./integrations/zcode/oauth"), "zcodeOAuthClient"),
619
586
  },
587
+ "zcode-start": {
588
+ // Free plan surface: an Anthropic-Messages endpoint that only accepts the
589
+ // dressed ZCode client request (see the integration). The credential is a
590
+ // ZCode login JWT — pasted, or minted by the sign-in flow below.
591
+ loadAdapter: async () =>
592
+ createApiKeyAdapter(
593
+ (await import("./integrations/zcode-start-plan/provider")).ZCODE_START_PLAN_SPEC,
594
+ ),
595
+ loadModels: async () =>
596
+ (await import("./integrations/zcode-start-plan/provider")).ZCODE_START_PLAN_MODELS,
597
+ // The device flow stores the issued ZCode login JWT, not a Coding Plan key.
598
+ loadAuthentication: oauthCapability(
599
+ () => import("./integrations/zcode-start-plan/oauth"),
600
+ "zcodeStartPlanOAuthClient",
601
+ ),
602
+ // Keep each reported entitlement and activation/reset window separate.
603
+ loadQuotaCollector: quotaCapability(
604
+ () => import("./integrations/zcode-start-plan/quota"),
605
+ "fetchZcodeStartPlanQuota",
606
+ ),
607
+ },
620
608
  "factory": {
621
609
  loadAdapter: async () => (await import("./integrations/factory/factory")).factoryAdapter,
622
610
  // Factory publishes no model-listing endpoint — the roster is a client-side
@@ -765,7 +753,7 @@ export const PROVIDER_CAPABILITIES = {
765
753
  // synced account sees whatever the plan currently serves. The catalog keeps
766
754
  // the provider usable before anyone syncs.
767
755
  dashscope: {
768
- ...discoveryBacked("dashscope", GENERIC_API_KEY_SPECS.dashscope),
756
+ ...discoveryBackedCapabilities("dashscope", GENERIC_API_KEY_SPECS.dashscope, openAIModelDiscovery),
769
757
  loadModels: async () => (await import("./integrations/dashscope-models")).DASHSCOPE_MODELS,
770
758
  },
771
759
 
@@ -420,13 +420,24 @@ export class PackedCatalog {
420
420
  return metadata;
421
421
  }
422
422
 
423
- /** Stated context limit, or `null`. */
423
+ /**
424
+ * Stated context limit, or `null`.
425
+ *
426
+ * Stored in a `Uint32Array` column; the generator
427
+ * (`scripts/tools/generate-models.ts`) refuses to write a value ≥ 2^31
428
+ * (`checkedPackedLimit`), so no row here can wrap modulo 2^32 and decode as a
429
+ * garbage limit.
430
+ */
424
431
  rowContext(index: number): number | null {
425
432
  const value = this.u32At(this.layout.ctx + index * 4);
426
433
  return value > 0 ? value : null;
427
434
  }
428
435
 
429
- /** Stated output limit, or `null`. */
436
+ /**
437
+ * Stated output limit, or `null`.
438
+ *
439
+ * Same u32 storage contract as `rowContext` — see the generator guard.
440
+ */
430
441
  rowOutput(index: number): number | null {
431
442
  const value = this.u32At(this.layout.out + index * 4);
432
443
  return value > 0 ? value : null;
@@ -1,7 +1,6 @@
1
1
  import type { FetchLike } from "../quota/quota-contracts";
2
2
  import type { ModelDefinition } from "../provider-model-definition";
3
3
  import type { ServiceKind } from "../../protocol/canonical-model";
4
-
5
4
  /**
6
5
  * Credential-scoped model-discovery input.
7
6
  *
@@ -3,6 +3,7 @@ import { isRecord } from "../../protocol/codecs";
3
3
  import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../provider-sanitize";
4
4
  import { modelsDevCatalog } from "./models-dev-catalog";
5
5
  import { isResponsesNativeModelId } from "../provider-model-definition";
6
+ import { composeAbortSignal } from "../authentication/oauth-flow-store";
6
7
  interface FetchModelsOptions {
7
8
  readonly baseUrl: string;
8
9
  /**
@@ -27,8 +28,7 @@ export async function fetchOpenAICompatibleModels(
27
28
  ): Promise<readonly ModelDefinition[] | null> {
28
29
  const fetcher = options.fetcher ?? fetch;
29
30
  const url = `${options.baseUrl.replace(/\/+$/, "")}/models`;
30
- const timeoutSignal = AbortSignal.timeout(10_000);
31
- const signal = options.signal === undefined ? timeoutSignal : AbortSignal.any([options.signal, timeoutSignal]);
31
+ const signal = composeAbortSignal(options.signal, 10_000);
32
32
  try {
33
33
  const response = await fetcher(url, {
34
34
  headers: {
@@ -74,8 +74,24 @@ export function wireContextFrom(
74
74
  };
75
75
  }
76
76
 
77
- /** Grok's account feature probe intentionally uses the same Responses request as live traffic. */
78
- export const GROK_407_PROBE_PROMPT = "reply my message with exact number 407";
77
+ /**
78
+ * Grok's account feature probe intentionally uses the same Responses request as
79
+ * live traffic.
80
+ *
81
+ * The prompt must make the model actually reply `407` — that literal is the
82
+ * healthy-account signal the probe verdict keys on. Naive phrasing refused by
83
+ * the model ("I can't reply with only a specific number", "I won't comply
84
+ * with a demand to output only an exact phrase") are listed above; verified
85
+ * live 2026-11-02 (grok-4.7) that this prompt returns exactly `407`:
86
+ *
87
+ * "Type the number 407." → "407"
88
+ * "Echo the diagnostic code 407." → "407"
89
+ * "Print the number 407 and nothing else." → "407"
90
+ *
91
+ * The verdict normalizes away Grok's trailing confidence annotation
92
+ * (`407 \confidence{100}`), so the match is on the bare number.
93
+ */
94
+ export const GROK_407_PROBE_PROMPT = "Type the number 407.";
79
95
 
80
96
  /**
81
97
  * Converts a failed/mismatched Grok feature probe into a quota-shaped upstream
@@ -91,8 +107,10 @@ export function grok407ProbeFailure(args: {
91
107
  if (args.providerId !== "grok" || args.prompt !== GROK_407_PROBE_PROMPT) return undefined;
92
108
  const sample = extractSample(args.events);
93
109
  const normalizedSample = sample?.replace(/\\confidence\{\d+\}\s*$/i, "").trim();
94
- // A valid Grok answer may carry the provider's confidence annotation after
95
- // the numeric result, and a terminal metadata error may arrive after text.
110
+ // A healthy account answers exactly `407` (optionally with Grok's trailing
111
+ // confidence annotation). The model refuses some phrasings of the same ask,
112
+ // but the probe prompt above is engineered to pass, so any other sample is a
113
+ // failure — quota-shaped, not a payload bug.
96
114
  if (normalizedSample === "407") return undefined;
97
115
  const priorDetails = args.dispatchError instanceof GatewayError ? args.dispatchError.details : {};
98
116
  const providerStatus =
@@ -348,6 +366,30 @@ export type ProbeAccountSelection =
348
366
  | { readonly ok: true; readonly accountId: string | undefined }
349
367
  | { readonly ok: false; readonly error: string };
350
368
 
369
+ /**
370
+ * Selects the first usable account row: status ≠ disabled, cooldown elapsed
371
+ * (unless `allowCoolingAccount`), preferring a tenant-owned account over a
372
+ * shared global one. Shared by the discovery and probing paths so both
373
+ * agree on which account a provider answers as.
374
+ */
375
+ export function selectUsableAccount<T extends {
376
+ readonly tenantId: string | null;
377
+ readonly status: string;
378
+ readonly cooldownUntil: Date | null;
379
+ }>(
380
+ rows: readonly T[],
381
+ allowCoolingAccount = false,
382
+ now = Date.now(),
383
+ ): T | undefined {
384
+ return rows
385
+ .filter(
386
+ (row) =>
387
+ row.status !== "disabled" &&
388
+ (allowCoolingAccount || row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
389
+ )
390
+ .sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null))[0];
391
+ }
392
+
351
393
  /**
352
394
  * Phase 2 — pick the account the probe runs as. Snapshot-equivalent health
353
395
  * filtering: disabled accounts and live cooldowns never route, so probes must
@@ -388,15 +430,8 @@ export async function selectProbeAccount(args: {
388
430
  ),
389
431
  )
390
432
  : [];
391
- const now = Date.now();
392
- const usableAccounts = accountRows
393
- .filter(
394
- (row) =>
395
- row.status !== "disabled" &&
396
- (allowCoolingAccount || row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
397
- )
398
- .sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null));
399
- const accountId = requestedAccountId ?? usableAccounts[0]?.id;
433
+ const usableAccount = selectUsableAccount(accountRows, allowCoolingAccount);
434
+ const accountId = requestedAccountId ?? usableAccount?.id;
400
435
  if (!accountId && requiresAccount) {
401
436
  return {
402
437
  ok: false,
@@ -50,6 +50,7 @@ import {
50
50
  resolveProbeAdapter,
51
51
  resolveProbeTarget,
52
52
  selectProbeAccount,
53
+ selectUsableAccount,
53
54
  wireContextFrom,
54
55
  type ProbeProviderRow,
55
56
  } from "./probe-phases";
@@ -915,6 +916,9 @@ export class ProviderProbingService {
915
916
  source: discDef?.freeTier === true ? "auto_free" : "discovered",
916
917
  sourceUpdatedAt,
917
918
  enabled: true,
919
+ ...(discDef?.dialect === undefined && knownDefinition?.dialect === undefined
920
+ ? {}
921
+ : { dialect: discDef?.dialect ?? knownDefinition?.dialect }),
918
922
  });
919
923
  }
920
924
  // One statement per chunk (500, the account-health batch step) instead of
@@ -936,6 +940,7 @@ export class ProviderProbingService {
936
940
  cost: sql`excluded.cost`,
937
941
  proOnly: sql`excluded.pro_only`,
938
942
  freeTier: sql`excluded.free_tier`,
943
+ dialect: sql`excluded.dialect`,
939
944
  // The proposed row's own source, not a constant: a free-tier
940
945
  // discovery and an ordinary one write the same upsert, and pinning
941
946
  // this to `discovered` would relabel every free-tier row on the
@@ -1000,14 +1005,7 @@ export class ProviderProbingService {
1000
1005
  globalOrOwnedBy(providerAccounts.tenantId, tenantId),
1001
1006
  ),
1002
1007
  );
1003
- const now = Date.now();
1004
- const usable = rows
1005
- .filter(
1006
- (row) =>
1007
- row.status !== "disabled" &&
1008
- (row.cooldownUntil === null || row.cooldownUntil.getTime() <= now),
1009
- )
1010
- .sort((left, right) => Number(right.tenantId !== null) - Number(left.tenantId !== null))[0];
1008
+ const usable = selectUsableAccount(rows);
1011
1009
  if (!usable?.credentialCiphertext) return undefined;
1012
1010
  const authState = isRecord(usable.authState) ? usable.authState as Readonly<Record<string, unknown>> : undefined;
1013
1011
  return {
@@ -16,9 +16,19 @@ import { readCredentialSecret, assertWireFamily, type ProviderDispatchTarget, ty
16
16
  import { providerBaseUrl } from "../../provider-metadata";
17
17
  import { buildClaudeMessagesRequest } from "../shared/claude-messages";
18
18
  import { sendClaudeMessagesRequest } from "../../../protocol/upstream/send-claude-messages";
19
+ import { ANTHROPIC_BETA_CAPABILITIES } from "../claude/claude-betas";
19
20
 
20
21
  export const AGENTROUTER_PROVIDER_ID = "agentrouter" as const;
21
- export const AGENTROUTER_BASE_URL = `${providerBaseUrl("agentrouter")}/v1/messages?beta=true`;
22
+ const AGENTROUTER_BASE_URL = `${providerBaseUrl("agentrouter")}/v1/messages?beta=true`;
23
+
24
+ /** The CLI beta set, typed against the canonical Anthropic beta vocabulary. */
25
+ const AGENTROUTER_ANTHROPIC_BETAS: ReadonlyArray<
26
+ keyof typeof ANTHROPIC_BETA_CAPABILITIES
27
+ > = [
28
+ "claude-code-20250219",
29
+ "interleaved-thinking-2025-05-14",
30
+ "effort-2025-11-24",
31
+ ];
22
32
 
23
33
  /**
24
34
  * The AgentRouter CLI fingerprint headers. Every value is part of the
@@ -29,7 +39,7 @@ export const AGENTROUTER_BASE_URL = `${providerBaseUrl("agentrouter")}/v1/messag
29
39
  */
30
40
  function agentRouterFingerprintHeaders(stream: boolean): Record<string, string> {
31
41
  return {
32
- "anthropic-beta": "claude-code-20250219,interleaved-thinking-2025-05-14,effort-2025-11-24",
42
+ "anthropic-beta": AGENTROUTER_ANTHROPIC_BETAS.join(","),
33
43
  "anthropic-dangerous-direct-browser-access": "true",
34
44
  "x-app": "cli",
35
45
  "user-agent": "claude-cli/2.1.195 (external, sdk-cli)",
@@ -212,4 +212,3 @@ export class AntigravityOAuthClient extends OAuthClient {
212
212
  }
213
213
 
214
214
  export const antigravityOAuthClient = new AntigravityOAuthClient();
215
- export { exchangeCodeForToken };
@@ -257,8 +257,6 @@ export function normalizeAntigravityToolSchemas(request: CanonicalRequest): Cano
257
257
  const lastGoodEndpoints = new Map<string, string>();
258
258
  const LAST_GOOD_ENDPOINT_MAX = 256;
259
259
 
260
- const DEFAULT_ORDER_INDEX = Number.MAX_SAFE_INTEGER;
261
-
262
260
  /**
263
261
  * Records the endpoint that just served a successful turn. Call this with the
264
262
  * `endpoint` reported by empty-stream recovery (or the URL that produced a
@@ -301,18 +299,6 @@ export function orderAntigravityEndpoints(
301
299
  return [sticky, ...endpoints.slice(0, index), ...endpoints.slice(index + 1)];
302
300
  }
303
301
 
304
- /**
305
- * Position of `endpoint` in the caller's own endpoint order, used to log a
306
- * failover without the caller re-deriving the list.
307
- */
308
- export function antigravityEndpointOrderIndex(
309
- endpoints: readonly string[],
310
- endpoint: string,
311
- ): number {
312
- const index = endpoints.indexOf(endpoint);
313
- return index < 0 ? DEFAULT_ORDER_INDEX : index;
314
- }
315
-
316
302
  // Model discovery (`v1internal:fetchAvailableModels`) — live catalog.
317
303
 
318
304
  const ANTIGRAVITY_DISCOVERY_PATH = "/v1internal:fetchAvailableModels";
@@ -758,7 +758,7 @@ export class AntigravitySessionStore {
758
758
  * `"-" + (sha256(first-user-text)[0:8] & INT63 | random <9e18)`.
759
759
  * A positive or hyphenated-UUID value here is a one-glance synthetic signal.
760
760
  */
761
- export function signedAntigravitySessionId(seed?: string): string {
761
+ function signedAntigravitySessionId(seed?: string): string {
762
762
  if (seed !== undefined && /^-?\d+$/.test(seed)) return seed;
763
763
  const text = seed !== undefined && seed.length > 0 ? seed : randomUUID();
764
764
  const head = BigInt(`0x${createHash("sha256").update(text).digest("hex").slice(0, 8)}`);
@@ -769,7 +769,7 @@ export function signedAntigravitySessionId(seed?: string): string {
769
769
  }
770
770
 
771
771
  /** Thinking budget per wire model, matching the client's effort tiers. */
772
- export function antigravityThinkingBudget(modelId: string): number | undefined {
772
+ function antigravityThinkingBudget(modelId: string): number | undefined {
773
773
  if (!modelId.includes("claude") && !modelId.includes("gemini-3")) return undefined;
774
774
  if (modelId.endsWith("-low")) return 1_000;
775
775
  if (modelId.endsWith("-medium")) return 4_000;
@@ -160,7 +160,7 @@ export function makeBuddyCnImageModels(
160
160
  * plan rather than about the model. A pro account serves all six. The pill is
161
161
  * therefore a hint about a free account, and a dispatch is what settles it.
162
162
  *
163
- * @see `.skills/cartethyia-reverse-engineering/references/codebuddy-dispatch-headers.md`
163
+ * @see `documentation/research/codebuddy/2026-10-19-codebuddy-chat-dispatch-headers.md`
164
164
  */
165
165
  export const BUDDY_PRO_ONLY_MODEL_IDS: ReadonlySet<string> = new Set([
166
166
  "primary-model",