cartethyia 2.7.4 → 2.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (595) hide show
  1. package/.env.example +5 -0
  2. package/README.md +18 -6
  3. package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js +899 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-DxjvUzSD.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-DRPavCdU.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
  42. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
  43. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js +56 -0
  44. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
  45. package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
  46. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  47. package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
  48. package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
  49. package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
  50. package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
  51. package/dist/dashboard/assets/assert-CidQVoNo.js +1 -0
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-DympBNq4.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  58. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  59. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  60. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  61. package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CxDw0lK6.js} +1 -1
  62. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  63. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  64. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  65. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  66. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  67. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +1 -0
  68. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  69. package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-DfS1ntiq.js} +1 -1
  70. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  71. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  72. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  73. package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-QqPul6sC.js} +1 -1
  74. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  75. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  76. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  77. package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
  78. package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
  79. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  80. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  81. package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-u7JPB5BX.js} +1 -1
  82. package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
  83. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  84. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  85. package/dist/dashboard/assets/{index-DBNPOfhV.js → index-Ko4dLRnV.js} +2 -2
  86. package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
  87. package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-CHJQwxLa.js} +1 -1
  88. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  89. package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BlmlizVV.js} +1 -1
  90. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  91. package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-Bz93I-yE.js} +1 -1
  92. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  93. package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Ml16KCfu.js} +1 -1
  94. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  95. package/dist/dashboard/assets/live-7_QpnYGu.js +1 -0
  96. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  97. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  98. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  99. package/dist/dashboard/assets/network-CuMDaTzT.js +1 -0
  100. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  101. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  102. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  103. package/dist/dashboard/assets/pagination-B5aOoweZ.js +1 -0
  104. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  105. package/dist/dashboard/assets/providers/zai.webp +0 -0
  106. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  107. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  108. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  109. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  110. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  111. package/dist/dashboard/assets/routing-fnCsxgNO.js +1 -0
  112. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  113. package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BHqpd-bg.js} +2 -2
  114. package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
  115. package/dist/dashboard/assets/settings-BxslsErn.js +1 -0
  116. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  117. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  118. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  119. package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-j7cXjgYX.js} +1 -1
  120. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  121. package/dist/dashboard/assets/{state-CkfdYWel.js → state-DHmEnLa2.js} +1 -1
  122. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  123. package/dist/dashboard/assets/{switch-SYm237HG.js → switch-DmZcyTIC.js} +1 -1
  124. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  125. package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-CbCP4w1o.js} +1 -1
  126. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  127. package/dist/dashboard/console-backgrounds.jpg +0 -0
  128. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  129. package/dist/dashboard/index.html +2 -2
  130. package/dist/dashboard/index.html.gz +0 -0
  131. package/dist/dashboard/precompressed-assets.json +60 -59
  132. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  133. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  134. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  135. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  136. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  137. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  138. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  139. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  140. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  141. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  142. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  143. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  144. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  145. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  146. package/package.json +4 -6
  147. package/scripts/cli/update.ts +15 -41
  148. package/src/boot/app.ts +58 -2
  149. package/src/boot/dependencies.ts +794 -732
  150. package/src/boot/lifecycle.ts +11 -12
  151. package/src/config/cooldowns.ts +34 -55
  152. package/src/config/network.ts +1 -1
  153. package/src/config/package-paths.ts +1 -1
  154. package/src/config/providers.ts +19 -14
  155. package/src/config/resources.ts +0 -5
  156. package/src/config/runtime.ts +2 -5
  157. package/src/config/spec.ts +33 -6
  158. package/src/config/usage.ts +27 -0
  159. package/src/console/api-keys/ban-constants.ts +38 -0
  160. package/src/console/api-keys/contracts.ts +71 -62
  161. package/src/console/api-keys/routes.ts +56 -24
  162. package/src/console/auth/access.ts +4 -4
  163. package/src/console/auth/account-reset.ts +1 -1
  164. package/src/console/auth/audit-recorder.ts +1 -1
  165. package/src/console/auth/lockout.ts +7 -3
  166. package/src/console/auth/row-coercion.ts +57 -12
  167. package/src/console/auth/session-resolver.ts +1 -1
  168. package/src/console/auth/session-service.ts +8 -2
  169. package/src/console/auth/session.ts +37 -31
  170. package/src/console/auth/setup-service.ts +4 -3
  171. package/src/console/auth/user-store.ts +1 -1
  172. package/src/console/backup/9router-map.ts +0 -3
  173. package/src/console/backup/contracts.ts +9 -9
  174. package/src/console/backup/export-endpoint.ts +5 -6
  175. package/src/console/backup/nine-router.ts +1 -7
  176. package/src/console/backup/routes.ts +29 -33
  177. package/src/console/backup/service.ts +468 -468
  178. package/src/console/backup/store.ts +47 -29
  179. package/src/console/backup/validate.ts +11 -1
  180. package/src/console/cli-tools/contracts.ts +43 -299
  181. package/src/console/cli-tools/fs-ops.ts +29 -0
  182. package/src/console/cli-tools/injectors/claude.ts +3 -3
  183. package/src/console/cli-tools/injectors/codex.ts +181 -181
  184. package/src/console/cli-tools/injectors/driver.ts +150 -247
  185. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  186. package/src/console/cli-tools/injectors/opencode.ts +176 -153
  187. package/src/console/cli-tools/routes.ts +7 -1
  188. package/src/console/cli-tools/service.ts +8 -7
  189. package/src/console/cli-tools/store.ts +2 -2
  190. package/src/console/console-router.ts +32 -0
  191. package/src/console/dashboard-assets.ts +9 -9
  192. package/src/console/domain-registration.ts +16 -2
  193. package/src/console/inferhub/client.ts +0 -7
  194. package/src/console/inferhub/key-store.ts +1 -1
  195. package/src/console/inferhub/normalize.ts +2 -2
  196. package/src/console/inferhub/routes.ts +1 -1
  197. package/src/console/inferhub/types.ts +1 -1
  198. package/src/console/observability/contracts.ts +7 -1
  199. package/src/console/observability/live.ts +31 -18
  200. package/src/console/observability/logs.ts +1 -1
  201. package/src/console/observability/sse.ts +62 -8
  202. package/src/console/observability/store.ts +23 -4
  203. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  204. package/src/console/providers/catalog/contracts.ts +39 -0
  205. package/src/console/providers/catalog/model-operations.ts +1 -1
  206. package/src/console/providers/catalog/provider-operations.ts +95 -17
  207. package/src/console/providers/catalog/public-model-store.ts +0 -0
  208. package/src/console/providers/catalog/routes.ts +27 -3
  209. package/src/console/providers/catalog/store.ts +147 -8
  210. package/src/console/providers/detail/routes.ts +1 -1
  211. package/src/console/providers/oauth/callback-listener.ts +100 -18
  212. package/src/console/providers/oauth/routes.ts +92 -13
  213. package/src/console/quota/account-quota-global.ts +41 -3
  214. package/src/console/quota/account-quota-shared.ts +10 -3
  215. package/src/console/quota/account-quota-tenant.ts +259 -66
  216. package/src/console/quota/daily-growth-job.ts +308 -0
  217. package/src/console/quota/native-identity.ts +2 -2
  218. package/src/console/quota/quota-view.ts +1 -1
  219. package/src/console/remote-support/routes.ts +1 -1
  220. package/src/console/remote-support/service.ts +2 -2
  221. package/src/console/routing/model/contracts.ts +1 -1
  222. package/src/console/routing/pools/contracts.ts +2 -2
  223. package/src/console/routing/pools/import-parse.ts +3 -3
  224. package/src/console/routing/pools/relay-deploy.ts +3 -3
  225. package/src/console/settings/contracts.ts +29 -2
  226. package/src/console/settings/store.ts +20 -0
  227. package/src/console/share/share-router.ts +100 -32
  228. package/src/console/share/share-stats.ts +11 -13
  229. package/src/console/share/share-usage.ts +1 -1
  230. package/src/console/shared/errors.ts +2 -2
  231. package/src/console/shared/object.ts +18 -0
  232. package/src/console/shared/read-through-cache.ts +4 -4
  233. package/src/console/shared/transaction.ts +14 -0
  234. package/src/console/system-prompt/contracts.ts +89 -12
  235. package/src/console/system-prompt/routes.ts +98 -45
  236. package/src/console/updates/apply-update.ts +244 -0
  237. package/src/console/updates/routes.ts +252 -97
  238. package/src/main.ts +11 -5
  239. package/src/network/http2-bidi.ts +1 -1
  240. package/src/network/ip-utils.ts +298 -0
  241. package/src/network/outbound-fetch.ts +1 -1
  242. package/src/network/pool/agent.ts +7 -6
  243. package/src/network/pool/byte-accounting.ts +1 -1
  244. package/src/network/pool/resolver.ts +16 -12
  245. package/src/network/pool/selector.ts +150 -136
  246. package/src/network/pool-health-machine.ts +1 -1
  247. package/src/network/rate-limit-verdict.ts +1 -1
  248. package/src/network/retry.ts +1 -1
  249. package/src/network/ssrf.ts +20 -71
  250. package/src/observability/event-log.ts +9 -2
  251. package/src/observability/event-query.ts +61 -291
  252. package/src/observability/log-sanitize.ts +1 -1
  253. package/src/observability/metrics.ts +4 -4
  254. package/src/observability/payload-capture.ts +6 -5
  255. package/src/observability/payload-store.ts +1 -1
  256. package/src/observability/runtime-metrics.ts +1 -1
  257. package/src/observability/telemetry-buffer.ts +19 -3
  258. package/src/observability/telemetry-reconciliation.ts +3 -3
  259. package/src/observability/token-speed.ts +1 -1
  260. package/src/persistence/connection-url.ts +1 -1
  261. package/src/persistence/db-handle.ts +1 -1
  262. package/src/persistence/db-pg.ts +2 -2
  263. package/src/persistence/db-sqlite.ts +3 -3
  264. package/src/persistence/dialect.ts +5 -1
  265. package/src/persistence/readiness.ts +1 -1
  266. package/src/persistence/redis.ts +1 -1
  267. package/src/persistence/schema.ts +121 -40
  268. package/src/persistence/shared-cache.ts +2 -2
  269. package/src/persistence/sort-order.ts +1 -1
  270. package/src/persistence/stores/api-key-store.ts +29 -2
  271. package/src/persistence/stores/share-store.ts +20 -8
  272. package/src/persistence/system-prompt-store.ts +63 -18
  273. package/src/persistence/tenant-preferences.ts +1 -1
  274. package/src/persistence/ttl-cache.ts +3 -3
  275. package/src/persistence/usage-flush.ts +7 -2
  276. package/src/protocol/canonical-model.ts +1 -1
  277. package/src/protocol/codecs.ts +6 -10
  278. package/src/protocol/dsml.ts +8 -125
  279. package/src/protocol/image-clamp.ts +2 -2
  280. package/src/protocol/reasoning-text.ts +1 -1
  281. package/src/protocol/reasoning.ts +7 -52
  282. package/src/protocol/registry.ts +50 -15
  283. package/src/protocol/request/chat.ts +46 -19
  284. package/src/protocol/request/codex.ts +1 -1
  285. package/src/protocol/request/messages.ts +46 -14
  286. package/src/protocol/request/responses.ts +19 -10
  287. package/src/protocol/response/chat.ts +25 -10
  288. package/src/protocol/response/codex.ts +1 -1
  289. package/src/protocol/response/messages.ts +1 -1
  290. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  291. package/src/protocol/response/responses.ts +1 -1
  292. package/src/protocol/sse-decoder.ts +50 -1
  293. package/src/protocol/stop-reason.ts +2 -2
  294. package/src/protocol/think-split.ts +347 -0
  295. package/src/protocol/translation/attachment-integrity.ts +3 -3
  296. package/src/protocol/translation/cache-controls.ts +8 -20
  297. package/src/protocol/translation/capabilities.ts +6 -6
  298. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  299. package/src/protocol/translation/dialect/inband.ts +39 -0
  300. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  301. package/src/protocol/translation/dialect/qwen.ts +114 -0
  302. package/src/protocol/translation/dialect/resolver.ts +83 -0
  303. package/src/protocol/translation/dialect/rules.ts +93 -0
  304. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  305. package/src/protocol/translation/dialect/types.ts +58 -0
  306. package/src/protocol/translation/quirks.ts +18 -4
  307. package/src/protocol/translation/thinking.ts +12 -252
  308. package/src/protocol/translation/tool-id.ts +3 -3
  309. package/src/protocol/translation/tool-repair.ts +1 -1
  310. package/src/protocol/upstream/post-json.ts +6 -1
  311. package/src/providers/adapters/compatible-adapter.ts +71 -4
  312. package/src/providers/authentication/jwt-validator.ts +0 -5
  313. package/src/providers/authentication/oauth-client.ts +254 -253
  314. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  315. package/src/providers/bundled-discovery-providers.ts +6 -30
  316. package/src/providers/configured-openai-providers.ts +82 -97
  317. package/src/providers/default-registry.ts +35 -37
  318. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  319. package/src/providers/discovery/discovery-types.ts +0 -1
  320. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  321. package/src/providers/discovery/probe-phases.ts +48 -13
  322. package/src/providers/discovery/probing-service.ts +6 -8
  323. package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
  324. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  325. package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -28
  326. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  327. package/src/providers/integrations/antigravity/antigravity.ts +22 -13
  328. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  329. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  330. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  331. package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
  332. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  333. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
  335. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  336. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
  337. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  338. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  339. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  340. package/src/providers/integrations/cline/cline.ts +1 -1
  341. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  342. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  343. package/src/providers/integrations/commandcode/commandcode.ts +75 -115
  344. package/src/providers/integrations/commandcode/quota.ts +131 -51
  345. package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
  346. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  347. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  348. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  349. package/src/providers/integrations/cursor/cursor.ts +35 -3
  350. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  351. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  352. package/src/providers/integrations/factory/factory.ts +9 -9
  353. package/src/providers/integrations/github/github-discovery.ts +70 -12
  354. package/src/providers/integrations/github/github-oauth.ts +184 -14
  355. package/src/providers/integrations/github/github.ts +134 -26
  356. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  357. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  358. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  359. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  360. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  361. package/src/providers/integrations/grok/grok.ts +86 -36
  362. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  363. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  364. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  365. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  366. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  367. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  368. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  369. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  370. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  371. package/src/providers/integrations/kiro/kiro.ts +80 -68
  372. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  373. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  374. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  375. package/src/providers/integrations/opencode/provider.ts +17 -24
  376. package/src/providers/integrations/qoder/qoder-catalog.ts +94 -11
  377. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  378. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  379. package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
  380. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  381. package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
  382. package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
  383. package/src/providers/integrations/qoder/qoder.ts +422 -71
  384. package/src/providers/integrations/shared/connect.ts +0 -54
  385. package/src/providers/integrations/shared/hash.ts +15 -0
  386. package/src/providers/integrations/shared/session-cache.ts +136 -0
  387. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  388. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  389. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  390. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  391. package/src/providers/integrations/trae/trae.ts +51 -8
  392. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  393. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  394. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  395. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  396. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  397. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  398. package/src/providers/operations/account-error-classification.ts +198 -133
  399. package/src/providers/operations/account-health-service.ts +31 -39
  400. package/src/providers/operations/account-reset-service.ts +58 -1
  401. package/src/providers/operations/byok-wire-profile.ts +19 -15
  402. package/src/providers/operations/cli-platform.ts +31 -5
  403. package/src/providers/operations/client-version-resolver.ts +4 -6
  404. package/src/providers/operations/client-versions.ts +10 -7
  405. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  406. package/src/providers/operations/provider-catalog-service.ts +18 -2
  407. package/src/providers/operations/provider-credential-service.ts +19 -2
  408. package/src/providers/provider-contracts.ts +18 -7
  409. package/src/providers/provider-metadata.ts +17 -2
  410. package/src/providers/provider-model-definition.ts +22 -1
  411. package/src/providers/provider-probe.ts +4 -2
  412. package/src/providers/provider-usage.ts +50 -19
  413. package/src/providers/quota/cache.ts +29 -0
  414. package/src/providers/quota/quota-contracts.ts +4 -0
  415. package/src/providers/quota/refresh.ts +27 -4
  416. package/src/providers/quota/snapshot.ts +94 -0
  417. package/src/providers/search/search-provider.ts +1 -3
  418. package/src/providers/search/search-providers.ts +2 -1
  419. package/src/security/abuse.ts +4 -4
  420. package/src/security/admission/service.ts +13 -6
  421. package/src/security/admission/ttl.ts +61 -61
  422. package/src/security/api-key-auth.ts +17 -3
  423. package/src/security/client-router-fingerprint.ts +4 -4
  424. package/src/security/credential-codec.ts +3 -3
  425. package/src/security/csrf.ts +2 -2
  426. package/src/security/ip-boundary.ts +16 -189
  427. package/src/security/model-access-rule.ts +1 -1
  428. package/src/security/outbound-headers.ts +18 -0
  429. package/src/shared/invoke-guard.ts +47 -0
  430. package/src/transport/contracts.ts +13 -4
  431. package/src/transport/dispatch/attempt-finalize.ts +70 -22
  432. package/src/transport/dispatch/attempt-loop.ts +22 -0
  433. package/src/transport/dispatch/capture-policy.ts +34 -37
  434. package/src/transport/dispatch/empty-stream.ts +23 -20
  435. package/src/transport/dispatch/generation.ts +25 -45
  436. package/src/transport/dispatch/native-shared.ts +127 -0
  437. package/src/transport/dispatch/proxy-request.ts +3 -1
  438. package/src/transport/dispatch/responses-compact.ts +25 -46
  439. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  440. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  441. package/src/transport/dispatch/streaming/stream.ts +7 -3
  442. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  443. package/src/transport/dispatch/systemone.ts +20 -48
  444. package/src/transport/dispatch/token-count.ts +41 -38
  445. package/src/transport/dispatch/websearch.ts +19 -45
  446. package/src/transport/drain-endpoint.ts +1 -1
  447. package/src/transport/failure-policy.ts +21 -1
  448. package/src/transport/guards/auth-guard.ts +0 -6
  449. package/src/transport/guards/body-policy.ts +3 -3
  450. package/src/transport/guards/error-lifecycle.ts +4 -0
  451. package/src/transport/guards/headroom-guard.ts +1 -1
  452. package/src/transport/guards/pipeline.ts +1 -1
  453. package/src/transport/guards/request-context.ts +12 -17
  454. package/src/transport/request/preparer.ts +286 -7
  455. package/src/transport/request/rtk/compress-request.ts +3 -3
  456. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  457. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  458. package/src/transport/request/state.ts +7 -13
  459. package/src/transport/request/system-prompt-injection.ts +74 -11
  460. package/src/transport/request/tenant-preferences.ts +22 -0
  461. package/src/transport/routing/candidate-index.ts +2 -2
  462. package/src/transport/routing/round-robin.ts +1 -1
  463. package/src/transport/routing/route-catalog.ts +17 -18
  464. package/src/transport/routing/route-model.ts +126 -33
  465. package/src/transport/routing/router.ts +159 -37
  466. package/src/transport/shutdown-notice.ts +2 -2
  467. package/src/transport/surface/adapters.ts +3 -3
  468. package/src/transport/surface/chat/encode.ts +7 -7
  469. package/src/transport/surface/chat/parse.ts +7 -7
  470. package/src/transport/surface/completion.ts +2 -2
  471. package/src/transport/surface/content-parts.ts +1 -1
  472. package/src/transport/surface/dialects.ts +2 -2
  473. package/src/transport/surface/messages/parse.ts +3 -3
  474. package/src/transport/surface/reasoning-summary.ts +9 -14
  475. package/src/transport/surface/responses/adapter.ts +1 -1
  476. package/src/transport/surface/responses/errors.ts +0 -9
  477. package/src/transport/vision-handoff-cache.ts +58 -0
  478. package/src/transport/vision-handoff.ts +431 -0
  479. package/src/workers/account-identity-sweep.ts +2 -2
  480. package/src/workers/buddy-growth-tasks.ts +392 -346
  481. package/src/workers/daily-checkin.ts +102 -49
  482. package/src/workers/maintenance-lease.ts +2 -35
  483. package/src/workers/oauth-refresh-sweep.ts +8 -1
  484. package/src/workers/quota-refresh-sweep.ts +120 -82
  485. package/src/workers/scheduler.ts +67 -4
  486. package/src/workers/sweep-runner.ts +24 -5
  487. package/src/workers/zcode-gift-claim.ts +108 -0
  488. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  489. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  490. package/dist/dashboard/assets/BannedPage-ChG5svFb.js +0 -1
  491. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  492. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +0 -1
  493. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  494. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +0 -1
  495. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  496. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
  497. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  498. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
  499. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  500. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +0 -1
  501. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  502. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
  503. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  504. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js +0 -1
  505. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  506. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  507. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
  508. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  509. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
  510. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  511. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  512. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  513. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
  514. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  515. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  516. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
  517. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  518. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
  519. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  520. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +0 -1
  521. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  522. package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
  523. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  524. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  525. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  526. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  527. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
  528. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  529. package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
  530. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  531. package/dist/dashboard/assets/app-BayTTy01.js +0 -9
  532. package/dist/dashboard/assets/app-BayTTy01.js.gz +0 -0
  533. package/dist/dashboard/assets/app-a159k0ub.css +0 -2
  534. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  535. package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
  536. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  537. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  538. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  539. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  540. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
  541. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  542. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  543. package/dist/dashboard/assets/dialog-8fiE6tec.js +0 -1
  544. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  545. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  546. package/dist/dashboard/assets/entry-BSAsYsmV.js +0 -1
  547. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  548. package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
  549. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  550. package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
  551. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  552. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  553. package/dist/dashboard/assets/github-badge-CPK47xQx.js +0 -1
  554. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  555. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  556. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  557. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  558. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  559. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  560. package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
  561. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  562. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  563. package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
  564. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  565. package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
  566. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  567. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  568. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  569. package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
  570. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  571. package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
  572. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  573. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  574. package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
  575. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  576. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  577. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  578. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  579. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  580. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  581. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  582. package/src/console/cli-tools/injectors/cline.ts +0 -110
  583. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  584. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  585. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  586. package/src/console/cli-tools/injectors/droid.ts +0 -96
  587. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  588. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  589. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  590. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
  591. package/src/network/response-headers.ts +0 -39
  592. package/src/protocol/response/dsml.ts +0 -38
  593. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  594. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  595. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -1,9 +1,9 @@
1
- // Kiro (CodeWhisperer) quota.
1
+ // Kiro (Kiro Control Plane) quota.
2
2
  //
3
- // Billing lives on two hosts and the right one depends on how the account
4
- // authenticates: an API key or enterprise token is served by the Amazon
5
- // surfaces, while the interactive families are answered by either. The
6
- // endpoints are tried in order and the first usable answer wins.
3
+ // Billing lives on the Kiro control-plane (management) service — in the
4
+ // 1.4.62 build `GetUsageLimits` is `GET /Get-Usage-Limits` on
5
+ // `https://management.{region}.kiro.dev`. The legacy `codewhisperer.*` /
6
+ // `q.*` AWS usage surfaces are no longer used.
7
7
  //
8
8
  // The account's region and profile matter here for the same reason they matter
9
9
  // at dispatch: the request is scoped to them, and an account-bound credential
@@ -15,7 +15,6 @@
15
15
  // device here and another at dispatch is the shape this gateway exists to avoid.
16
16
 
17
17
  import type {
18
- FetchLike,
19
18
  ProviderQuotaResult,
20
19
  ProviderQuotaWindow,
21
20
  } from "../../quota/quota-contracts";
@@ -35,9 +34,16 @@ import {
35
34
  } from "../../operations/client-versions";
36
35
  import { machineIdForAuthState } from "./kiro-machine-id";
37
36
  import { resolveKiroProfileArn } from "./kiro-profile";
37
+ import { AWS_REGION_PATTERN, KIRO_DEFAULT_REGION, KIRO_MANAGEMENT_HOST_TEMPLATE } from "./kiro-catalog";
38
38
 
39
- /** AWS region shape, checked before a region is interpolated into a URL. */
40
- const AWS_REGION_PATTERN = /^[a-z]{2}-[a-z]+-\d{1,2}$/;
39
+ /**
40
+ * The fetcher shape this module needs: a plain callable. `FetchLike` from the
41
+ * quota contracts is the global `typeof fetch` (which carries extra callable
42
+ * properties like `preconnect`), and the OAuth client passes its narrower
43
+ * structural `FetchLike` here — so accept the common callable shape instead of
44
+ * either full type.
45
+ */
46
+ type KiroFetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
41
47
 
42
48
  interface KiroQuotaAuth {
43
49
  readonly region: string;
@@ -50,7 +56,7 @@ interface KiroQuotaAuth {
50
56
  function quotaAuth(context: QuotaCollectionContext | undefined): KiroQuotaAuth {
51
57
  const raw = context?.auth_state ?? {};
52
58
  const regionRaw = typeof raw["region"] === "string" ? raw["region"].trim() : "";
53
- const region = AWS_REGION_PATTERN.test(regionRaw) ? regionRaw : "us-east-1";
59
+ const region = AWS_REGION_PATTERN.test(regionRaw) ? regionRaw : KIRO_DEFAULT_REGION;
54
60
  const authMethod = typeof raw["authMethod"] === "string" ? raw["authMethod"] : "builder-id";
55
61
  // The usage surface is profile-scoped and refuses a request without the field,
56
62
  // exactly as generation does, so it scopes to the same value generation does:
@@ -72,13 +78,13 @@ function usageHeaders(credential: string, auth: KiroQuotaAuth): Record<string, s
72
78
  connection: "close",
73
79
  "amz-sdk-request": "attempt=1; max=1",
74
80
  "amz-sdk-invocation-id": crypto.randomUUID(),
75
- "x-amzn-kiro-agent-mode": "vibe",
76
- "x-amzn-codewhisperer-optout": "true",
77
81
  "x-amz-user-agent": buildKiroAmzUserAgent(version, auth.machineId),
78
82
  "user-agent": buildKiroRuntimeUserAgent(version, auth.machineId),
83
+ "x-kiro-machineid": auth.machineId,
79
84
  };
80
- if (auth.authMethod === "api_key") headers["tokentype"] = "API_KEY";
81
- else if (auth.authMethod === "external_idp") headers["tokentype"] = "EXTERNAL_IDP";
85
+ if (auth.authMethod === "api_key") headers["TokenType"] = "API_KEY";
86
+ else if (auth.authMethod === "external_idp") headers["TokenType"] = "EXTERNAL_IDP";
87
+ else if (auth.authMethod === "idc") headers["TokenType"] = "SSO_OIDC";
82
88
  return headers;
83
89
  }
84
90
 
@@ -127,11 +133,18 @@ function parseUsage(payload: unknown): ProviderQuotaResult {
127
133
  }
128
134
  }
129
135
  const subscription = record(root["subscriptionInfo"]);
136
+ // The bundle asks with `isEmailRequired: true`, and the upstream then reports
137
+ // the account's email in `userInfo.email`. That is the only identity a social/
138
+ // imported token exposes (the access token itself is opaque, not a JWT), so it
139
+ // becomes the suggested account label for the refresh sweep to adopt.
140
+ const userInfo = record(root["userInfo"]);
141
+ const email = text(userInfo?.["email"]);
130
142
  return {
131
143
  source: "kiro",
132
144
  plan: text(subscription?.["subscriptionTitle"]) ?? "Kiro",
133
145
  windows,
134
146
  error: null,
147
+ ...(email === null ? {} : { accountLabel: email }),
135
148
  };
136
149
  }
137
150
 
@@ -144,7 +157,7 @@ function parseUsage(payload: unknown): ProviderQuotaResult {
144
157
  */
145
158
  export async function fetchKiroQuota(
146
159
  credential: string,
147
- fetcher: FetchLike,
160
+ fetcher: KiroFetchLike,
148
161
  context?: QuotaCollectionContext,
149
162
  ): Promise<ProviderQuotaResult> {
150
163
  const token = credential.trim();
@@ -156,43 +169,18 @@ export async function fetchKiroQuota(
156
169
  origin: "AI_EDITOR",
157
170
  resourceType: "AGENTIC_REQUEST",
158
171
  });
159
- const usageBody = JSON.stringify({
160
- origin: "AI_EDITOR",
161
- ...(auth.profileArn.length > 0 ? { profileArn: auth.profileArn } : {}),
162
- resourceType: "AGENTIC_REQUEST",
163
- });
172
+ // The 1.4.62 client sends the profile in the query (`GetUsageLimitsCommand`
173
+ // with `{origin, profileArn, resourceType, isEmailRequired}`). Without it the
174
+ // upstream answers 400 `Invalid profileArn.` — and there is no POST surface;
175
+ // the legacy `codewhisperer.*`/`q.*` AWS usage paths are gone.
176
+ if (auth.profileArn.length > 0) query.set("profileArn", auth.profileArn);
164
177
 
165
- // Which surface answers depends on the account's auth family. The profile
166
- // travels in the POST body only: the GET form rejects it in the query with
167
- // `400`, which is what a freshly imported account was failing its test on.
178
+ const managementHost = KIRO_MANAGEMENT_HOST_TEMPLATE.replace("{region}", auth.region);
168
179
  const attempts: readonly { readonly name: string; readonly run: () => Promise<Response> }[] = [
169
180
  {
170
- name: "codewhisperer-get",
171
- run: () =>
172
- fetcher(`https://codewhisperer.us-east-1.amazonaws.com/getUsageLimits?${query.toString()}`, {
173
- method: "GET",
174
- headers,
175
- signal: AbortSignal.timeout(15_000),
176
- }),
177
- },
178
- {
179
- name: "codewhisperer-post",
180
- run: () =>
181
- fetcher("https://codewhisperer.us-east-1.amazonaws.com", {
182
- method: "POST",
183
- headers: {
184
- ...headers,
185
- "content-type": "application/x-amz-json-1.0",
186
- "x-amz-target": "AmazonCodeWhispererService.GetUsageLimits",
187
- },
188
- body: usageBody,
189
- signal: AbortSignal.timeout(15_000),
190
- }),
191
- },
192
- {
193
- name: "q-get",
181
+ name: "management-get",
194
182
  run: () =>
195
- fetcher(`https://q.${auth.region}.amazonaws.com/getUsageLimits?${query.toString()}`, {
183
+ fetcher(`${managementHost}/Get-Usage-Limits?${query.toString()}`, {
196
184
  method: "GET",
197
185
  headers,
198
186
  signal: AbortSignal.timeout(15_000),
@@ -55,15 +55,10 @@ interface KiroToolSpecification {
55
55
  };
56
56
  }
57
57
 
58
- /** The checkpoint the upstream keys its prompt cache on. */
59
- interface KiroCachePoint {
60
- readonly cachePoint: { readonly type: "default" };
61
- }
62
-
63
58
  /** One entry of `currentMessage.userInputMessage.userInputMessageContext`. */
64
59
  interface KiroUserInputContext {
65
60
  readonly toolResults?: readonly KiroToolResult[];
66
- readonly tools?: readonly (KiroToolSpecification | KiroCachePoint)[];
61
+ readonly tools?: readonly KiroToolSpecification[];
67
62
  }
68
63
 
69
64
  interface KiroToolResult {
@@ -111,6 +106,8 @@ export interface KiroConversationError {
111
106
  /** Options the adapter supplies that are not part of the canonical request. */
112
107
  export interface KiroWireRequestOptions {
113
108
  readonly conversationId: string;
109
+ /** Root conversation id; defaults to `conversationId`, mirroring the client's `rootConversationId ?? conversationId`. */
110
+ readonly rootConversationId?: string | undefined;
114
111
  readonly modelId: string;
115
112
  readonly profileArn: string;
116
113
  /** Reasoning effort the routed model advertises, already validated by the adapter. */
@@ -176,6 +173,10 @@ export function buildKiroWireRequest(
176
173
  agentContinuationId: randomUUID(),
177
174
  chatTriggerType: "MANUAL",
178
175
  conversationId: options.conversationId,
176
+ // The client always sends the root conversation id, defaulting to the
177
+ // conversation id when the conversation is self-rooted (1.4.62 bundle:
178
+ // `rootConversationId: A ?? S`).
179
+ rootConversationId: options.rootConversationId ?? options.conversationId,
179
180
  currentMessage: { userInputMessage: currentMessage },
180
181
  history,
181
182
  },
@@ -197,8 +198,7 @@ export function buildKiroWireRequest(
197
198
  * This text is deliberately the *only* thing the opening turn carries besides
198
199
  * the caller's own words, because it is the prefix the upstream caches: every
199
200
  * request in a conversation repeats it byte-for-byte on that same turn. A value
200
- * that changes per request belongs on the current turn instead — see
201
- * `buildCurrentTimeLine`.
201
+ * that changes per request belongs on the current turn instead.
202
202
  */
203
203
  function buildStablePrefix(request: CanonicalRequest, options: KiroWireRequestOptions): string {
204
204
  const parts: string[] = [];
@@ -221,9 +221,6 @@ function buildStablePrefix(request: CanonicalRequest, options: KiroWireRequestOp
221
221
  * prefix differ on every request, so the upstream could never reuse the cached
222
222
  * one and the whole conversation would be re-read each turn.
223
223
  */
224
- export function buildCurrentTimeLine(now: Date = new Date()): string {
225
- return `[Context: Current time is ${now.toISOString()}]`;
226
- }
227
224
 
228
225
  /** The marker the upstream reads to enable thinking with a budget. */
229
226
  export function buildThinkingMarker(budget: number): string {
@@ -132,6 +132,10 @@ export class KiroStreamDecoder {
132
132
 
133
133
  const eventType = event.headers[":event-type"] ?? "";
134
134
  switch (eventType) {
135
+ // First frame of a stream; carries only an empty conversation id. Nothing
136
+ // to emit (observed live 2026-11-02: `{"conversationId":""}`).
137
+ case "initial-response":
138
+ return { deltas: [] };
135
139
  case "assistantResponseEvent":
136
140
  return { deltas: this.#textDeltas(readString(event.payload, "content")) };
137
141
  case "reasoningContentEvent":
@@ -303,6 +307,13 @@ function readString(payload: string | null, key: string): string {
303
307
  *
304
308
  * The upstream has sent this payload as a bare string, as `{text}`, and as
305
309
  * `{content}` across versions; all three are accepted rather than picking one.
310
+ *
311
+ * One shape must NOT be read as text: `{redactedContent:"…"}`. That is an
312
+ * encrypted envelope (observed live 2026-11-02: base64 → `.KTR~~<base64url-
313
+ * JSON>` → `{"encryptionRegion":null,"mintedAtMs":…,"modelHash":"…","slots":
314
+ * [],"v":1}`) whose content the upstream never exposes. Emitting it as
315
+ * reasoning would leak a blob that is not reasoning, so it is treated as no
316
+ * text at all.
306
317
  */
307
318
  function readReasoning(payload: string | null): string {
308
319
  const parsed = parsePayload(payload);
@@ -311,6 +322,8 @@ function readReasoning(payload: string | null): string {
311
322
  if (typeof value === "string") return value;
312
323
  if (value !== null && typeof value === "object") {
313
324
  const record = value as Record<string, unknown>;
325
+ // Redacted envelope: not reasoning text; never surface it.
326
+ if (typeof record.redactedContent === "string") return "";
314
327
  if (typeof record.text === "string") return record.text;
315
328
  if (typeof record.content === "string") return record.content;
316
329
  }
@@ -1,4 +1,4 @@
1
- // Kiro (CodeWhisperer) adapter.
1
+ // Kiro (CodeWhisperer / Kiro Runtime) adapter.
2
2
  //
3
3
  // Kiro does not speak a chat-shaped protocol: a request is a `conversationState`
4
4
  // ledger, and the answer is an AWS EventStream binary frame sequence. The
@@ -7,19 +7,21 @@
7
7
  //
8
8
  // Two upstream behaviours drive the header and endpoint logic:
9
9
  //
10
- // * There is exactly one generation surface, `q.{region}.amazonaws.com`. The
11
- // `codewhisperer.*` host and the vendor's own path-style gateway are
12
- // not what the real client talks to, and reaching for them is actively
13
- // harmful: an account that has just been refused would immediately probe two
14
- // other service entries with the same token, which is the shape of credential
15
- // probing rather than of a client retrying. A refusal is reported, never
16
- // replayed onto another host.
10
+ // * There is exactly one generation surface, `https://runtime.{region}.kiro.dev`
11
+ // (the Kiro runtime service). The legacy `q.{region}.amazonaws.com` /
12
+ // `codewhisperer.*` AWS hosts are what older Kiro builds used; the 1.4.62
13
+ // IDE ships `KiroRuntimeService` clients against the runtime host, and
14
+ // reaching for the legacy hosts is actively harmful: an account that has
15
+ // just been refused would immediately probe other service entries with the
16
+ // same token, which is the shape of credential probing rather than of a
17
+ // client retrying. A refusal is reported, never replayed onto another host.
17
18
  // * Every request carries a device identity (`KiroIDE-{version}-{machineId}`
18
- // in the User-Agent) and closes its connection. A connection reused across
19
- // accounts lets one TCP session carry several tokens that each claim to be a
20
- // different machine — the strongest possible evidence of sharing. An account
21
- // whose machine id cannot be derived is refused rather than dispatched with a
22
- // constant or a per-request random value.
19
+ // in the User-Agent and `x-kiro-machineid` as a header) and closes its
20
+ // connection. A connection reused across accounts lets one TCP session carry
21
+ // several tokens that each claim to be a different machine — the strongest
22
+ // possible evidence of sharing. An account whose machine id cannot be
23
+ // derived is refused rather than dispatched with a constant or a per-request
24
+ // random value.
23
25
  //
24
26
  // The profile ARN is never manufactured: an account that resolved none sends
25
27
  // none. The shared placeholder belongs to the vendor's own account and the
@@ -27,6 +29,7 @@
27
29
 
28
30
  import type {
29
31
  CanonicalEvent,
32
+ CanonicalMessage,
30
33
  CanonicalRequest,
31
34
  CanonicalStopReason,
32
35
  UsageRecord,
@@ -48,9 +51,16 @@ import {
48
51
  type KiroWireRequest,
49
52
  } from "./kiro-request";
50
53
  import { machineIdForAuthState } from "./kiro-machine-id";
54
+ import { estimateKiroSessionCache } from "./kiro-cache";
51
55
  import { resolveKiroProfileArn } from "./kiro-profile";
52
- import { kiroContextWindow } from "./kiro-catalog";
53
- import { resolveInboundSessionId, resolvePromptCacheKey } from "../../operations/session-resolution";
56
+ import {
57
+ AWS_REGION_PATTERN,
58
+ KIRO_DEFAULT_REGION,
59
+ kiroContextWindow,
60
+ KIRO_GENERATE_PATH,
61
+ KIRO_RUNTIME_HOST_TEMPLATE,
62
+ } from "./kiro-catalog";
63
+ import { resolveInboundSessionId } from "../../operations/session-resolution";
54
64
  import { KiroStreamDecoder, isKiroTruncationReason, type KiroUsage } from "./kiro-stream";
55
65
 
56
66
  /** Provider id this adapter registers under. */
@@ -70,9 +80,6 @@ interface KiroAuthState {
70
80
  readonly machineId?: string;
71
81
  }
72
82
 
73
- /** AWS region shape, checked before a region is interpolated into a URL. */
74
- const AWS_REGION_PATTERN = /^[a-z]{2}-[a-z]+-\d{1,2}$/;
75
-
76
83
  interface KiroAdapterOptions {
77
84
  readonly fetch?: typeof fetch;
78
85
  }
@@ -83,7 +90,7 @@ function readAuthState(context: ProviderDispatchContext): KiroAuthState | undefi
83
90
  if (raw === undefined) return undefined;
84
91
  const authMethod = typeof raw["authMethod"] === "string" ? raw["authMethod"] : undefined;
85
92
  if (authMethod === undefined) return undefined;
86
- const region = typeof raw["region"] === "string" && raw["region"].trim().length > 0 ? raw["region"].trim() : "us-east-1";
93
+ const region = typeof raw["region"] === "string" && raw["region"].trim().length > 0 ? raw["region"].trim() : KIRO_DEFAULT_REGION;
87
94
  const profileArn = typeof raw["profileArn"] === "string" && raw["profileArn"].trim().length > 0 ? raw["profileArn"].trim() : undefined;
88
95
  const machineId = typeof raw["machineId"] === "string" && raw["machineId"].trim().length > 0 ? raw["machineId"].trim() : undefined;
89
96
  return {
@@ -121,35 +128,6 @@ function resolveKiroConversationId(
121
128
  );
122
129
  }
123
130
 
124
- /**
125
- * The field the upstream keys its prompt cache on.
126
- *
127
- * A stable `conversationId` is not enough: the upstream ignores `cache_control`
128
- * entirely unless `metadata.user_id` is present, and then recomputes the whole
129
- * prompt on every turn. The value follows the shape the real client sends, and
130
- * its session id is the same one the conversation already uses, so turns of one
131
- * conversation hit and a different conversation does not.
132
- */
133
- function withKiroCacheKey(
134
- payload: Record<string, unknown>,
135
- request: CanonicalRequest,
136
- context: ProviderDispatchContext,
137
- ): Record<string, unknown> {
138
- const existing = (payload.metadata as { user_id?: unknown } | undefined)?.user_id;
139
- if (typeof existing === "string" && existing.length > 0) return payload;
140
- const sessionId = resolvePromptCacheKey(request, context) ?? resolveKiroConversationId(request, context);
141
- return {
142
- ...payload,
143
- metadata: {
144
- user_id: JSON.stringify({
145
- device_id: resolveAccountMachineId(context),
146
- account_uuid: "",
147
- session_id: sessionId,
148
- }),
149
- },
150
- };
151
- }
152
-
153
131
  /**
154
132
  * The profile ARN this request carries, or `""` when it carries none.
155
133
  *
@@ -180,8 +158,8 @@ function resolveAccountMachineId(context: ProviderDispatchContext): string {
180
158
 
181
159
  /** Region validated before interpolation into an endpoint URL. */
182
160
  function safeRegion(authState: KiroAuthState | undefined): string {
183
- const region = authState?.region ?? "us-east-1";
184
- return AWS_REGION_PATTERN.test(region) ? region : "us-east-1";
161
+ const region = authState?.region ?? KIRO_DEFAULT_REGION;
162
+ return AWS_REGION_PATTERN.test(region) ? region : KIRO_DEFAULT_REGION;
185
163
  }
186
164
 
187
165
  /**
@@ -191,9 +169,30 @@ function safeRegion(authState: KiroAuthState | undefined): string {
191
169
  * replayed onto another service entry.
192
170
  */
193
171
  export function kiroEndpoint(authState: KiroAuthState | undefined): string {
194
- return `https://q.${safeRegion(authState)}.amazonaws.com/generateAssistantResponse`;
172
+ const host = KIRO_RUNTIME_HOST_TEMPLATE.replace("{region}", safeRegion(authState));
173
+ return `${host}${KIRO_GENERATE_PATH}`;
195
174
  }
196
175
 
176
+ /**
177
+ * AWS JSON 1.0 target for the runtime generation operation. The service name
178
+ * and operation are what the 1.4.62 client sends in `x-amz-target` (it is a
179
+ * Smithy `awsJson1_0` client with serviceTarget `KiroRuntimeService`).
180
+ */
181
+ export const KIRO_RUNTIME_AWS_JSON_TARGET = "KiroRuntimeService.GenerateAssistantResponse" as const;
182
+
183
+ /**
184
+ * Maps an auth method onto the `TokenType` header the 1.4.62 client sends.
185
+ *
186
+ * Observed map (`qje`): `api_key → API_KEY`, `external_idp → EXTERNAL_IDP`,
187
+ * `idc → SSO_OIDC`, `machine_token → KIRO_MACHINE_TOKEN`. Google/GitHub/
188
+ * Builder-ID sessions send no `TokenType` header.
189
+ */
190
+ const KIRO_TOKEN_TYPE: Readonly<Record<string, string>> = {
191
+ api_key: "API_KEY",
192
+ external_idp: "EXTERNAL_IDP",
193
+ idc: "SSO_OIDC",
194
+ };
195
+
197
196
  /**
198
197
  * Builds the request headers.
199
198
  *
@@ -206,37 +205,37 @@ export function kiroEndpoint(authState: KiroAuthState | undefined): string {
206
205
  * * `x-amzn-codewhisperer-optout` — the observed client opts out of data
207
206
  * collection on every generation request.
208
207
  * * `x-amzn-kiro-agent-mode` — the agent mode the observed client declares.
209
- * * `tokentype` — an API key or enterprise token is rejected as an OAuth access
210
- * token unless it is labelled as one.
208
+ * * `TokenType` — an API key or enterprise token is labelled so the upstream
209
+ * can tell it apart from an OAuth access token.
211
210
  */
212
211
  export function kiroHeaders(
213
212
  secret: string,
214
213
  authState: KiroAuthState | undefined,
215
214
  machineId: string,
215
+ agentMode: string,
216
216
  ): Record<string, string> {
217
217
  const authMethod = authState?.authMethod;
218
218
  const version = getKiroVersion();
219
219
  const headers: Record<string, string> = {
220
- "content-type": "application/json",
220
+ "content-type": "application/x-amz-json-1.0",
221
221
  accept: KIRO_STREAM_ACCEPT,
222
222
  connection: "close",
223
+ "x-amz-target": KIRO_RUNTIME_AWS_JSON_TARGET,
223
224
  "x-amzn-codewhisperer-optout": "true",
224
- "x-amzn-kiro-agent-mode": "spec",
225
+ "x-amzn-kiro-agent-mode": agentMode,
226
+ "x-kiro-machineid": machineId,
225
227
  "amz-sdk-request": "attempt=1; max=3",
226
228
  "amz-sdk-invocation-id": crypto.randomUUID(),
227
229
  "user-agent": buildKiroUserAgent(version, machineId),
228
230
  "x-amz-user-agent": buildKiroAmzUserAgent(version, machineId),
229
231
  authorization: `Bearer ${secret}`,
230
232
  };
231
- if (authMethod === "api_key") {
232
- headers["tokentype"] = "API_KEY";
233
- } else if (authMethod === "external_idp") {
234
- headers["tokentype"] = "EXTERNAL_IDP";
235
- } else {
236
- headers["x-amz-sso-bearer"] = secret;
233
+ const tokenType = authMethod === undefined ? undefined : KIRO_TOKEN_TYPE[authMethod];
234
+ if (tokenType !== undefined) {
235
+ headers["TokenType"] = tokenType;
237
236
  }
238
237
  if (authState?.profileArn !== undefined && authState.profileArn.length > 0) {
239
- headers["x-amzn-codewhisperer-profile-arn"] = authState.profileArn;
238
+ headers["x-amzn-kiro-profile-arn"] = authState.profileArn;
240
239
  }
241
240
  return headers;
242
241
  }
@@ -257,11 +256,17 @@ export function kiroHeaders(
257
256
  * estimate: the upstream never says how long its own answer was, so the emitted
258
257
  * text is counted at the usual ~4 characters per token.
259
258
  */
260
- function kiroUsage(usage: KiroUsage, modelId: string, outputText: string): UsageRecord {
259
+ function kiroUsage(
260
+ usage: KiroUsage,
261
+ modelId: string,
262
+ outputText: string,
263
+ messages?: readonly CanonicalMessage[],
264
+ sessionId?: string,
265
+ ): UsageRecord {
261
266
  const cacheRead = usage.cacheReadTokens ?? 0;
262
267
  const cacheWrite = usage.cacheWriteTokens ?? 0;
263
268
  const [input, output] = kiroTokenCounts(usage, modelId, outputText);
264
- return {
269
+ const record: UsageRecord = {
265
270
  input_tokens: input,
266
271
  cached_input_tokens: cacheRead > 0 ? cacheRead : "unavailable",
267
272
  cache_write_tokens: cacheWrite > 0 ? cacheWrite : "unavailable",
@@ -275,6 +280,10 @@ function kiroUsage(usage: KiroUsage, modelId: string, outputText: string): Usage
275
280
  total_tokens: input + output,
276
281
  ...(usage.credits === undefined ? {} : { credit_used: usage.credits }),
277
282
  };
283
+ // The runtime never reports cache hits; close the gap with our own history.
284
+ // A genuine ( >0) report conserves the complete record. Then the operator's
285
+ // cache mode decides whether a hit makes the whole input count as cached.
286
+ return estimateKiroSessionCache(record, sessionId, messages);
278
287
  }
279
288
 
280
289
  /**
@@ -370,6 +379,7 @@ class KiroAdapter implements ProviderAdapter {
370
379
  : (request.reasoning?.budget_tokens ?? kiroThinkingBudgetForEffort(requestedEffort));
371
380
  const built = buildKiroWireRequest(request, {
372
381
  conversationId: resolveKiroConversationId(request, context),
382
+ rootConversationId: resolveKiroConversationId(request, context),
373
383
  modelId,
374
384
  profileArn: resolveProfileArn(context),
375
385
  ...(effortPath === undefined || effort === undefined ? {} : { effortPath, effort }),
@@ -386,7 +396,8 @@ class KiroAdapter implements ProviderAdapter {
386
396
  );
387
397
  }
388
398
  const fetchFn = (context.outbound_fetch as unknown as typeof fetch | undefined) ?? this.#fetch;
389
- const body = JSON.stringify(withKiroCacheKey(built.value.payload, request, context));
399
+ const builtPayload = { ...built.value.payload, agentMode: "vibe" };
400
+ const body = JSON.stringify(builtPayload);
390
401
  const machineId = resolveAccountMachineId(context);
391
402
  const response = await this.#send(
392
403
  fetchFn,
@@ -403,7 +414,7 @@ class KiroAdapter implements ProviderAdapter {
403
414
  }, "upstream");
404
415
  }
405
416
 
406
- yield* this.#stream(response.body, built.value, request);
417
+ yield* this.#stream(response.body, built.value, request, context);
407
418
  }
408
419
 
409
420
  /**
@@ -427,7 +438,7 @@ class KiroAdapter implements ProviderAdapter {
427
438
  try {
428
439
  response = await fetchFn(url, {
429
440
  method: "POST",
430
- headers: kiroHeaders(secret, authState, machineId),
441
+ headers: kiroHeaders(secret, authState, machineId, "vibe"),
431
442
  body,
432
443
  signal: context.abort_signal,
433
444
  });
@@ -460,6 +471,7 @@ class KiroAdapter implements ProviderAdapter {
460
471
  stream: ReadableStream<Uint8Array>,
461
472
  built: KiroWireRequest,
462
473
  request: CanonicalRequest,
474
+ context: ProviderDispatchContext,
463
475
  ): AsyncIterable<CanonicalEvent> {
464
476
  const decoder = new KiroStreamDecoder();
465
477
  const reader = stream.getReader();
@@ -593,7 +605,7 @@ class KiroAdapter implements ProviderAdapter {
593
605
  reader.releaseLock();
594
606
  }
595
607
 
596
- const finalUsage = kiroUsage(usage, request.model, outputText);
608
+ const finalUsage = kiroUsage(usage, request.model, outputText, request.messages, resolveKiroConversationId(request, context));
597
609
  yield {
598
610
  type: "usage",
599
611
  sequence_number: sequence++,
@@ -199,4 +199,3 @@ export class MuseCodeOAuthClient extends OAuthDeviceFlow {
199
199
  }
200
200
 
201
201
  export const museCodeOAuthClient = new MuseCodeOAuthClient();
202
- export { requestMuseCodeKey };
@@ -10,8 +10,6 @@ import {
10
10
  } from "./muse-oauth";
11
11
  import { parseMuseCodeCredential } from "./muse";
12
12
 
13
- const SOURCE = "api.meta.ai/muse-code/key";
14
-
15
13
  interface MuseSubscriptionWindow {
16
14
  used_percent?: unknown;
17
15
  usedPercent?: unknown;
@@ -132,5 +130,3 @@ export async function fetchMuseQuota(
132
130
  error: null,
133
131
  };
134
132
  }
135
-
136
- export { SOURCE as MUSE_QUOTA_SOURCE };
@@ -2,12 +2,14 @@ import { getOpenCodeVersion } from "../../operations/client-versions";
2
2
  import { createHash, randomBytes } from "node:crypto";
3
3
 
4
4
  /**
5
- * The OpenCode fallback client identity, used only while version discovery has
6
- * not resolved yet. The live feed (`opencode/latest/<version>/cli`) wins once
7
- * it is available; upstream accepts a range of releases, so the fallback does
8
- * not need chasing.
5
+ * The pinned reference client identity the parity suite asserts on.
6
+ *
7
+ * The runtime fallback lives in `VERSION_SOURCES.opencode.fallback`
8
+ * (`operations/client-versions.ts`); this mirror exists so the parity suite
9
+ * can pin the exact identity sent before discovery resolves. Keep both in
10
+ * lockstep when the CLI releases.
9
11
  */
10
- export const OPENCODE_CLIENT_VERSION = "2.1.1";
12
+ export const OPENCODE_CLIENT_VERSION = "2.2.5";
11
13
 
12
14
  let lastTimestamp = 0;
13
15
  let sequenceCounter = 0;
@@ -150,17 +150,6 @@ export function isFreeTierZenModel(modelId: string): boolean {
150
150
  return bare.endsWith("-free") || KNOWN_FREE_ZEN_IDS.includes(bare) || bare.toLowerCase().includes("free");
151
151
  }
152
152
 
153
- /**
154
- * The anonymous credential the free tier accepts.
155
- *
156
- * Captured from a real client dispatch and confirmed live 2026-10-14: without
157
- * it a free-model request is refused with 403 `FreeTierError` even when every
158
- * other field is byte-exact, and with it the same request returns 200. It is a
159
- * sentinel the upstream recognizes, not a secret — but it is a credential
160
- * value, so it lives here rather than in the shared fingerprint.
161
- */
162
- const ANONYMOUS_ZEN_BEARER = "public";
163
-
164
153
  /**
165
154
  * The `Accept` a free-tier dispatch advertises.
166
155
  *
@@ -184,9 +173,10 @@ function opencodeDesktopHeaders(
184
173
  context.request_headers?.["x-opencode-project"],
185
174
  context.request_headers?.["x-opencode-session-id"],
186
175
  ),
187
- // The gate reads the anonymous sentinel: a free dispatch with no
188
- // Authorization is refused regardless of headers, tools, or session shape.
189
- ...(freeModel ? { authorization: `Bearer ${ANONYMOUS_ZEN_BEARER}` } : {}),
176
+ // The free-tier gate accepts dispatches with no `Authorization` at all
177
+ // (verified live 2026-11-02: the same captured flow answers 200 both with
178
+ // `Bearer public` and with no auth header, as long as the body/session
179
+ // fingerprint is valid). No anonymous sentinel is sent.
190
180
  // The free-tier gate refuses non-streaming dispatches with 403
191
181
  // FreeTierError, so free models always advertise SSE regardless of the
192
182
  // client's own Accept; billed models keep the JSON default. The value is
@@ -211,27 +201,28 @@ function opencodeDesktopHeaders(
211
201
  * `ToolDefinition`s — every wire codec serializes them, no per-wire patching.
212
202
  */
213
203
  /**
214
- * Every tool the free-tier gate recognises, in the order the client declares
215
- * them, with the client's own description and schema.
204
+ * Every tool the free-tier gate recognises, in the order the real 2.2.0
205
+ * client declares them on the wire (mitm capture 2026-11-02, flow 4), with
206
+ * the client's own description and schema.
216
207
  *
217
208
  * The gate compares a recognised tool's definition, not just its name: a stub
218
209
  * carrying the right name is refused. These are therefore verbatim captures —
219
- * see `./tool-definitions` for provenance.
210
+ * see `./tool-definitions` for provenance. A real dispatch carries exactly
211
+ * these 11 tools (the binary's full `UPt` registry has 14, but the build
212
+ * agent sends only these).
220
213
  */
221
214
  const FREE_AGENT_TOOL_NAMES_ORDERED: readonly string[] = [
222
- "shell",
215
+ "edit",
223
216
  "glob",
224
- "read",
225
217
  "grep",
218
+ "read",
219
+ "shell",
220
+ "skill",
221
+ "subagent",
226
222
  "webfetch",
227
223
  "websearch",
228
224
  "write",
229
- "edit",
230
- "subagent",
231
225
  "execute",
232
- "patch",
233
- "question",
234
- "skill",
235
226
  ];
236
227
 
237
228
  /**
@@ -268,6 +259,8 @@ function ensureFreeAgentRequest(request: CanonicalRequest): CanonicalRequest {
268
259
  name,
269
260
  description: definition?.description ?? name,
270
261
  jsonSchema: (definition?.parameters ?? FREE_AGENT_TOOL_SCHEMA) as ToolDefinition["jsonSchema"],
262
+ // The real client marks every declared tool strict:false on the wire.
263
+ strict: false,
271
264
  };
272
265
  });
273
266
  if (missing.length === 0) return request;