cartethyia 2.7.1 → 2.7.3

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 (263) hide show
  1. package/.env.example +2 -0
  2. package/dist/dashboard/assets/{BannedPage-D-J75hBM.js → BannedPage-2TJD37Hb.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-2TJD37Hb.js.gz +0 -0
  4. package/dist/dashboard/assets/CliToolDetailPage-xefJNRmJ.js +1 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-xefJNRmJ.js.gz +0 -0
  6. package/dist/dashboard/assets/CliToolsPage-Rj9iHQ3F.js +1 -0
  7. package/dist/dashboard/assets/CliToolsPage-Rj9iHQ3F.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-QoJ6foxo.js → CombosPage-JEbYJFxw.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-JEbYJFxw.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-DpNRay4C.js → ConsoleLogPage-C3xx_inM.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js.gz +0 -0
  12. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js +1 -0
  13. package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js.gz +0 -0
  14. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js +1 -0
  15. package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js.gz +0 -0
  16. package/dist/dashboard/assets/{LoginPage-DubdQcvX.js → LoginPage-C4w7vea-.js} +1 -1
  17. package/dist/dashboard/assets/LoginPage-C4w7vea-.js.gz +0 -0
  18. package/dist/dashboard/assets/{ModelPicker-BH8Tehdi.js → ModelPicker-BtPcAfot.js} +1 -1
  19. package/dist/dashboard/assets/ModelPicker-BtPcAfot.js.gz +0 -0
  20. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js +1 -0
  21. package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js.gz +0 -0
  22. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js +4 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js.gz +0 -0
  24. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js +1 -0
  25. package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js.gz +0 -0
  26. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js +9 -0
  27. package/dist/dashboard/assets/ProxyPage-DdPc8slb.js.gz +0 -0
  28. package/dist/dashboard/assets/{QuotaPage-ATpaxrbl.js → QuotaPage-Ci5O4BnH.js} +1 -1
  29. package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js.gz +0 -0
  30. package/dist/dashboard/assets/{SettingsPage-CETophpx.js → SettingsPage-CDZjTt87.js} +1 -1
  31. package/dist/dashboard/assets/SettingsPage-CDZjTt87.js.gz +0 -0
  32. package/dist/dashboard/assets/SetupPage-BQS0Rx_u.js +1 -0
  33. package/dist/dashboard/assets/SetupPage-BQS0Rx_u.js.gz +0 -0
  34. package/dist/dashboard/assets/{SortableList-CAK-EN9z.js → SortableList-BAL5npBC.js} +1 -1
  35. package/dist/dashboard/assets/SortableList-BAL5npBC.js.gz +0 -0
  36. package/dist/dashboard/assets/{StudioPage-B7W2_RhT.js → StudioPage-TP7voAQ0.js} +3 -3
  37. package/dist/dashboard/assets/StudioPage-TP7voAQ0.js.gz +0 -0
  38. package/dist/dashboard/assets/{UsagePage-6T4EFDjW.js → UsagePage-Cj_fEzhg.js} +13 -13
  39. package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js.gz +0 -0
  40. package/dist/dashboard/assets/{api-keys-CUi6UXsR.js → api-keys-MbI7e7rt.js} +1 -1
  41. package/dist/dashboard/assets/api-keys-MbI7e7rt.js.gz +0 -0
  42. package/dist/dashboard/assets/app-B2vyPoII.css +2 -0
  43. package/dist/dashboard/assets/app-B2vyPoII.css.gz +0 -0
  44. package/dist/dashboard/assets/arrow-up-59ms1iiT.js +1 -0
  45. package/dist/dashboard/assets/arrow-up-59ms1iiT.js.gz +0 -0
  46. package/dist/dashboard/assets/{assert-67xXH5rf.js → assert-C0YYuZJ4.js} +1 -1
  47. package/dist/dashboard/assets/assert-C0YYuZJ4.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-DC2L43Mj.js → badge-B_DMpMJN.js} +1 -1
  49. package/dist/dashboard/assets/badge-B_DMpMJN.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-BBVcb0J3.js → banner-DMrMPmth.js} +1 -1
  51. package/dist/dashboard/assets/banner-DMrMPmth.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-Cca1XC6G.js → card-Be5Uzamx.js} +1 -1
  53. package/dist/dashboard/assets/card-Be5Uzamx.js.gz +0 -0
  54. package/dist/dashboard/assets/{cli-tools-KvsWa1Jl.js → cli-tools-muFRphDu.js} +1 -1
  55. package/dist/dashboard/assets/cli-tools-muFRphDu.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-DUzEbynq.js → clipboard-button-DOfrVmsi.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-DOfrVmsi.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-DFvWhwTa.js → dialog-C9omdjQt.js} +1 -1
  59. package/dist/dashboard/assets/dialog-C9omdjQt.js.gz +0 -0
  60. package/dist/dashboard/assets/drawer-Bm8WKaGY.js +1 -0
  61. package/dist/dashboard/assets/drawer-Bm8WKaGY.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-_xHo5x6r.js → entry-DS90gUks.js} +1 -1
  63. package/dist/dashboard/assets/entry-DS90gUks.js.gz +0 -0
  64. package/dist/dashboard/assets/{entry-BLBLxX0h.js → entry-j40LJotO.js} +3 -3
  65. package/dist/dashboard/assets/entry-j40LJotO.js.gz +0 -0
  66. package/dist/dashboard/assets/{entry-Bqy8RFvM.js → entry-q5HwZ8nN.js} +1 -1
  67. package/dist/dashboard/assets/entry-q5HwZ8nN.js.gz +0 -0
  68. package/dist/dashboard/assets/{concurrency-BDF0ok7y.js → fingerprint-pattern-BWuHtbW4.js} +1 -1
  69. package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
  70. package/dist/dashboard/assets/{formatters-mpBPqAQ8.js → formatters-BTScrQpe.js} +1 -1
  71. package/dist/dashboard/assets/formatters-BTScrQpe.js.gz +0 -0
  72. package/dist/dashboard/assets/{github-badge-C9e8Ts7e.js → github-badge-Orjuzemr.js} +1 -1
  73. package/dist/dashboard/assets/github-badge-Orjuzemr.js.gz +0 -0
  74. package/dist/dashboard/assets/{index-D6QzEC_n.js → index-cPrX5vn6.js} +2 -2
  75. package/dist/dashboard/assets/index-cPrX5vn6.js.gz +0 -0
  76. package/dist/dashboard/assets/{inline-BFUcvllj.js → inline-Dvux8w-0.js} +1 -1
  77. package/dist/dashboard/assets/inline-Dvux8w-0.js.gz +0 -0
  78. package/dist/dashboard/assets/{input-C_ILAvBb.js → input-CU1Rgf3p.js} +1 -1
  79. package/dist/dashboard/assets/input-CU1Rgf3p.js.gz +0 -0
  80. package/dist/dashboard/assets/{layout-CBIyT6Rt.js → layout-C_7A6H55.js} +1 -1
  81. package/dist/dashboard/assets/layout-C_7A6H55.js.gz +0 -0
  82. package/dist/dashboard/assets/{list-row-ebJ_-Nsb.js → list-row-CzFvogbj.js} +1 -1
  83. package/dist/dashboard/assets/list-row-CzFvogbj.js.gz +0 -0
  84. package/dist/dashboard/assets/{live-D0mm--ME.js → live-KaG15HLQ.js} +1 -1
  85. package/dist/dashboard/assets/live-KaG15HLQ.js.gz +0 -0
  86. package/dist/dashboard/assets/{mutation-sMD965oO.js → mutation-JJGQm8TD.js} +1 -1
  87. package/dist/dashboard/assets/mutation-JJGQm8TD.js.gz +0 -0
  88. package/dist/dashboard/assets/{numbers-BO9dKaFr.js → numbers-BNDZnsUE.js} +1 -1
  89. package/dist/dashboard/assets/numbers-BNDZnsUE.js.gz +0 -0
  90. package/dist/dashboard/assets/{query-keys-CfL_Zdoh.js → query-keys-CLaNz8Xz.js} +1 -1
  91. package/dist/dashboard/assets/query-keys-CLaNz8Xz.js.gz +0 -0
  92. package/dist/dashboard/assets/{routing-BnIpi1IJ.js → routing-BEH32QOC.js} +1 -1
  93. package/dist/dashboard/assets/routing-BEH32QOC.js.gz +0 -0
  94. package/dist/dashboard/assets/{select-Cj5Nw43g.js → select-B3iTetHN.js} +1 -1
  95. package/dist/dashboard/assets/select-B3iTetHN.js.gz +0 -0
  96. package/dist/dashboard/assets/settings-2-Ds9DQp0t.js +1 -0
  97. package/dist/dashboard/assets/settings-2-Ds9DQp0t.js.gz +0 -0
  98. package/dist/dashboard/assets/{settings-BAFhDgX8.js → settings-Dt3Eqbnq.js} +1 -1
  99. package/dist/dashboard/assets/settings-Dt3Eqbnq.js.gz +0 -0
  100. package/dist/dashboard/assets/{stack-EMrOMt4I.js → stack-KrOrm7JZ.js} +1 -1
  101. package/dist/dashboard/assets/stack-KrOrm7JZ.js.gz +0 -0
  102. package/dist/dashboard/assets/{state-CWoo7ty5.js → state-DLS7IDMy.js} +1 -1
  103. package/dist/dashboard/assets/state-DLS7IDMy.js.gz +0 -0
  104. package/dist/dashboard/assets/{switch-CCjT6IkF.js → switch-42ItvbAs.js} +1 -1
  105. package/dist/dashboard/assets/switch-42ItvbAs.js.gz +0 -0
  106. package/dist/dashboard/assets/{useMutation-DjkLHUcE.js → useMutation-Dmnfh1Ue.js} +1 -1
  107. package/dist/dashboard/assets/useMutation-Dmnfh1Ue.js.gz +0 -0
  108. package/dist/dashboard/index.html +3 -2
  109. package/dist/dashboard/index.html.gz +0 -0
  110. package/dist/dashboard/precompressed-assets.json +117 -115
  111. package/migrations/full-postgres/0026_add_qoder_native_identity.sql +20 -0
  112. package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +22 -0
  113. package/migrations/full-postgres/0028_add_family_template_key_telemetry.sql +40 -0
  114. package/migrations/full-postgres/0029_null_share_child_policy_columns.sql +38 -0
  115. package/migrations/full-postgres/0030_add_api_key_max_children.sql +10 -0
  116. package/migrations/full-postgres/0031_tenant_system_prompts.sql +16 -0
  117. package/migrations/lite-sqlite3/0026_add_qoder_native_identity.sql +15 -0
  118. package/migrations/lite-sqlite3/0027_qoder_identity_genuine_seed.sql +22 -0
  119. package/migrations/lite-sqlite3/0028_add_family_template_key_telemetry.sql +40 -0
  120. package/migrations/lite-sqlite3/0029_null_share_child_policy_columns.sql +38 -0
  121. package/migrations/lite-sqlite3/0030_add_api_key_max_children.sql +10 -0
  122. package/migrations/lite-sqlite3/0031_tenant_system_prompts.sql +10 -0
  123. package/package.json +1 -1
  124. package/src/config/network.ts +1 -1
  125. package/src/console/api-keys/bucket-spend.ts +7 -7
  126. package/src/console/api-keys/contracts.ts +423 -410
  127. package/src/console/api-keys/routes.ts +118 -19
  128. package/src/console/backup/export-endpoint.ts +8 -11
  129. package/src/console/backup/routes.ts +40 -8
  130. package/src/console/backup/service.ts +11 -6
  131. package/src/console/backup/store.ts +384 -88
  132. package/src/console/cli-tools/contracts.ts +10 -4
  133. package/src/console/dashboard-assets.ts +16 -1
  134. package/src/console/domain-registration.ts +2 -0
  135. package/src/console/quota/account-quota-tenant.ts +8 -1
  136. package/src/console/quota/account-quota.ts +4 -1
  137. package/src/console/quota/native-identity.ts +189 -0
  138. package/src/console/remote-support/contracts.ts +12 -6
  139. package/src/console/remote-support/service.ts +2 -2
  140. package/src/console/share/share-router.ts +39 -6
  141. package/src/console/share/share-stats.ts +64 -25
  142. package/src/console/share/share-usage.ts +24 -7
  143. package/src/console/system-prompt/contracts.ts +102 -0
  144. package/src/console/system-prompt/routes.ts +165 -0
  145. package/src/main.ts +11 -0
  146. package/src/network/outbound-fetch.ts +281 -226
  147. package/src/network/pool/agent.ts +7 -0
  148. package/src/observability/event-query.ts +118 -7
  149. package/src/persistence/db-pg.ts +42 -0
  150. package/src/persistence/schema.ts +102 -0
  151. package/src/persistence/stores/api-key-store.ts +753 -581
  152. package/src/persistence/stores/share-store.ts +65 -13
  153. package/src/persistence/stores/telemetry-store.ts +57 -1
  154. package/src/persistence/system-prompt-store.ts +104 -0
  155. package/src/protocol/reasoning.ts +65 -1
  156. package/src/protocol/request/chat.ts +1 -0
  157. package/src/providers/default-registry.ts +1 -0
  158. package/src/providers/integrations/antigravity/antigravity.ts +20 -23
  159. package/src/providers/integrations/buddy/buddy-chat-shared.ts +30 -2
  160. package/src/providers/integrations/buddy/buddy-media.ts +5 -1
  161. package/src/providers/integrations/buddy/codebuddy/provider.ts +5 -1
  162. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -1
  163. package/src/providers/integrations/cline/cline.ts +7 -0
  164. package/src/providers/integrations/github/github.ts +20 -1
  165. package/src/providers/integrations/hermes.ts +5 -1
  166. package/src/providers/integrations/kilo/kilo.ts +4 -0
  167. package/src/providers/integrations/ollamacloud-models.ts +50 -0
  168. package/src/providers/integrations/openrouter/provider.ts +4 -0
  169. package/src/providers/integrations/qoder/qoder-checkin.ts +224 -51
  170. package/src/providers/integrations/qoder/qoder-native-identity-store.ts +156 -0
  171. package/src/providers/integrations/qoder/qoder-oauth.ts +24 -4
  172. package/src/providers/integrations/qoder/qoder-realm.ts +20 -0
  173. package/src/providers/integrations/qoder/qoder-text-tools.ts +277 -0
  174. package/src/providers/integrations/qoder/qoder-umid.ts +288 -0
  175. package/src/providers/integrations/qoder/qoder.ts +1375 -1641
  176. package/src/providers/operations/account-error-classification.ts +1682 -1660
  177. package/src/providers/operations/account-health-service.ts +619 -621
  178. package/src/providers/operations/client-versions.ts +37 -22
  179. package/src/providers/operations/provider-catalog-service.ts +11 -1
  180. package/src/providers/provider-contracts.ts +15 -2
  181. package/src/security/access-control.ts +19 -0
  182. package/src/security/api-key-auth.ts +14 -1
  183. package/src/security/cli-client-fingerprint.ts +9 -2
  184. package/src/transport/dispatch/empty-stream.ts +224 -224
  185. package/src/transport/dispatch/proxy-request.ts +31 -2
  186. package/src/transport/dispatch/streaming/stream.ts +16 -1
  187. package/src/transport/dispatch/upstream.ts +10 -0
  188. package/src/transport/failure-policy.ts +33 -0
  189. package/src/transport/request/preparer.ts +17 -1
  190. package/src/transport/request/system-prompt-injection.ts +89 -0
  191. package/src/transport/request/tenant-preferences.ts +43 -0
  192. package/src/transport/routing/admission.ts +13 -3
  193. package/src/transport/routing/route-catalog.ts +41 -12
  194. package/src/transport/routing/route-model.ts +53 -0
  195. package/src/transport/routing/router.ts +306 -228
  196. package/src/transport/surface/responses/encode.ts +2 -3
  197. package/src/transport/surface/responses/parse.ts +49 -7
  198. package/src/types/undici.d.ts +33 -0
  199. package/src/workers/daily-checkin.ts +2 -0
  200. package/dist/dashboard/assets/BannedPage-D-J75hBM.js.gz +0 -0
  201. package/dist/dashboard/assets/CliToolDetailPage-CVe6RaBH.js +0 -1
  202. package/dist/dashboard/assets/CliToolDetailPage-CVe6RaBH.js.gz +0 -0
  203. package/dist/dashboard/assets/CliToolsPage-Dd8ZSamp.js +0 -1
  204. package/dist/dashboard/assets/CliToolsPage-Dd8ZSamp.js.gz +0 -0
  205. package/dist/dashboard/assets/CombosPage-QoJ6foxo.js.gz +0 -0
  206. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js.gz +0 -0
  207. package/dist/dashboard/assets/CustomizationPage-CKUFTcW4.js +0 -1
  208. package/dist/dashboard/assets/CustomizationPage-CKUFTcW4.js.gz +0 -0
  209. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js +0 -1
  210. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js.gz +0 -0
  211. package/dist/dashboard/assets/LoginPage-DubdQcvX.js.gz +0 -0
  212. package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
  213. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js +0 -1
  214. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js.gz +0 -0
  215. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js +0 -4
  216. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js.gz +0 -0
  217. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js +0 -1
  218. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js.gz +0 -0
  219. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js +0 -9
  220. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js.gz +0 -0
  221. package/dist/dashboard/assets/QuotaPage-ATpaxrbl.js.gz +0 -0
  222. package/dist/dashboard/assets/SettingsPage-CETophpx.js.gz +0 -0
  223. package/dist/dashboard/assets/SetupPage-BdgECjqq.js +0 -1
  224. package/dist/dashboard/assets/SetupPage-BdgECjqq.js.gz +0 -0
  225. package/dist/dashboard/assets/SortableList-CAK-EN9z.js.gz +0 -0
  226. package/dist/dashboard/assets/StudioPage-B7W2_RhT.js.gz +0 -0
  227. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js.gz +0 -0
  228. package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
  229. package/dist/dashboard/assets/app-KvsUJUMF.css +0 -2
  230. package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
  231. package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
  232. package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
  233. package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
  234. package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
  235. package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
  236. package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
  237. package/dist/dashboard/assets/concurrency-BDF0ok7y.js.gz +0 -0
  238. package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
  239. package/dist/dashboard/assets/drawer-CFM2sMX1.js +0 -1
  240. package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
  241. package/dist/dashboard/assets/entry-BLBLxX0h.js.gz +0 -0
  242. package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
  243. package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
  244. package/dist/dashboard/assets/formatters-mpBPqAQ8.js.gz +0 -0
  245. package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
  246. package/dist/dashboard/assets/index-D6QzEC_n.js.gz +0 -0
  247. package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
  248. package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
  249. package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
  250. package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
  251. package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
  252. package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
  253. package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
  254. package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
  255. package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
  256. package/dist/dashboard/assets/select-Cj5Nw43g.js.gz +0 -0
  257. package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
  258. package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
  259. package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
  260. package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
  261. package/dist/dashboard/assets/useMutation-DjkLHUcE.js.gz +0 -0
  262. /package/dist/dashboard/assets/{app-BaWd0puM.js → app-wvwCi4Eh.js} +0 -0
  263. /package/dist/dashboard/assets/{app-BaWd0puM.js.gz → app-wvwCi4Eh.js.gz} +0 -0
@@ -46,6 +46,17 @@ async function traeVersion(response: Response): Promise<string | null> {
46
46
  /"insert":"((?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},\s*\d{4}\s*\([^)]*\))\\n"/g;
47
47
  for (const match of text.matchAll(heading)) {
48
48
  const window = text.slice(match.index ?? 0, (match.index ?? 0) + 900);
49
+ // A release line may name a *range* ("TRAE v3.6.1 ~ 3.6.4 are released"),
50
+ // and the newest entry is the newest build in it. Taking the first number
51
+ // reported 3.6.1 while 3.6.4 was already shipping — and on an entry whose
52
+ // heading carried no version at all the old pattern matched nothing, so
53
+ // discovery fell through to the next (older) entry and the pin drifted
54
+ // backwards on every refresh.
55
+ const range = window.match(/(\d+\.\d+\.\d+)\s*[~–-]\s*(\d+\.\d+\.\d+)/);
56
+ if (range) {
57
+ const high = range[2] ?? range[1];
58
+ if (high && isSemverish(high)) return high.trim();
59
+ }
49
60
  const found = window.match(/TraeCode\s+v?(\d+\.\d+\.\d+)|v?(\d+\.\d+\.\d+)\s+is\s+released/i);
50
61
  const version = found?.[1] ?? found?.[2];
51
62
  if (version && isSemverish(version)) return version.trim();
@@ -221,7 +232,7 @@ const KIRO_NODE_VERSION = "24.18.0";
221
232
  export const VERSION_SOURCES = {
222
233
  antigravity: {
223
234
  key: "antigravity",
224
- fallback: "2.24.0",
235
+ fallback: "2.28.2",
225
236
  sources: [
226
237
  {
227
238
  url: "https://antigravity-hub-auto-updater-974169037036.us-central1.run.app/manifest/latest-arm64-mac.yml",
@@ -231,7 +242,7 @@ export const VERSION_SOURCES = {
231
242
  },
232
243
  qoder: {
233
244
  key: "qoder",
234
- fallback: "1.1.74",
245
+ fallback: "1.1.81",
235
246
  sources: [
236
247
  {
237
248
  url: "https://registry.npmjs.org/@qoder-ai/qodercli/latest",
@@ -243,18 +254,21 @@ export const VERSION_SOURCES = {
243
254
  key: "opencode",
244
255
  // The v1 package (`opencode-ai`) stopped at 1.18. The v2 line publishes
245
256
  // under `@opencode/cli`, and this feed is what its own installer reads.
246
- fallback: "2.0.32",
257
+ fallback: "2.2.2",
247
258
  minVersion: "2.0.0",
248
259
  sources: [{ url: "https://opencode.ai/update/api/latest/cli/npm" }],
249
260
  },
250
261
  commandcode: {
251
262
  key: "commandcode",
252
- fallback: "1.84.0",
263
+ // npm `command-code` latest as of 2026-10-30. The CLI sends this as
264
+ // `x-command-code-version`, so a stale fallback presents a client build
265
+ // the upstream no longer ships — raise it whenever the package moves.
266
+ fallback: "1.88.2",
253
267
  sources: [{ url: "https://registry.npmjs.org/command-code/latest" }],
254
268
  },
255
269
  grok: {
256
270
  key: "grok",
257
- fallback: "1.0.62",
271
+ fallback: "1.0.70",
258
272
  sources: [
259
273
  { url: "https://storage.googleapis.com/grok-build-public-artifacts/cli/stable" },
260
274
  { url: "https://registry.npmjs.org/@xai-official/grok/latest" },
@@ -262,7 +276,7 @@ export const VERSION_SOURCES = {
262
276
  },
263
277
  clineClient: {
264
278
  key: "cline-client",
265
- fallback: "4.1.25",
279
+ fallback: "4.1.26",
266
280
  minVersion: "4.1.23",
267
281
  sources: [
268
282
  {
@@ -273,22 +287,22 @@ export const VERSION_SOURCES = {
273
287
  },
274
288
  clineSdk: {
275
289
  key: "cline-sdk",
276
- fallback: "0.0.95",
290
+ fallback: "0.2.0",
277
291
  sources: [{ url: "https://registry.npmjs.org/@cline/sdk/latest", extract: clineSdkVersion }],
278
292
  },
279
293
  clineCli: {
280
294
  key: "cline-cli",
281
- fallback: "3.0.73",
295
+ fallback: "3.0.74",
282
296
  sources: [{ url: "https://registry.npmjs.org/cline/latest", extract: clineSdkVersion }],
283
297
  },
284
298
  codex: {
285
299
  key: "codex",
286
- fallback: "0.163.0",
300
+ fallback: "0.166.0",
287
301
  sources: [{ url: "https://registry.npmjs.org/@openai/codex/latest" }],
288
302
  },
289
303
  workbuddyClient: {
290
304
  key: "workbuddy-client",
291
- fallback: "5.8.4.41366630",
305
+ fallback: "5.9.4.42593613",
292
306
  sources: [
293
307
  {
294
308
  url: "https://www.workbuddy.ai/v2/update?platform=workbuddy-win32-x64-user",
@@ -302,7 +316,7 @@ export const VERSION_SOURCES = {
302
316
  },
303
317
  workbuddyCnClient: {
304
318
  key: "workbuddy-cn-client",
305
- fallback: "5.8.3.41334564",
319
+ fallback: "5.9.3.42398134",
306
320
  sources: [
307
321
  {
308
322
  url: "https://www.workbuddy.cn/v2/update?platform=workbuddy-win32-x64-user",
@@ -316,7 +330,7 @@ export const VERSION_SOURCES = {
316
330
  },
317
331
  workbuddyCli: {
318
332
  key: "workbuddy",
319
- fallback: "2.169.0",
333
+ fallback: "2.178.1",
320
334
  sources: [
321
335
  { url: "https://registry.npmjs.org/@tencent-ai/codebuddy-code/latest" },
322
336
  { url: "https://registry.npmmirror.com/@tencent-ai/codebuddy-code/latest" },
@@ -329,7 +343,7 @@ export const VERSION_SOURCES = {
329
343
  },
330
344
  kiro: {
331
345
  key: "kiro",
332
- fallback: "1.3.11",
346
+ fallback: "1.4.62",
333
347
  sources: [
334
348
  {
335
349
  // Kiro's downloads page exposes no stable version string. Homebrew
@@ -343,7 +357,7 @@ export const VERSION_SOURCES = {
343
357
  },
344
358
  codebuddy: {
345
359
  key: "codebuddy",
346
- fallback: "2.169.0",
360
+ fallback: "2.178.1",
347
361
  sources: [
348
362
  { url: "https://registry.npmjs.org/@tencent-ai/codebuddy-code/latest" },
349
363
  { url: "https://registry.npmmirror.com/@tencent-ai/codebuddy-code/latest" },
@@ -366,7 +380,7 @@ export const VERSION_SOURCES = {
366
380
  // Current `@anthropic-ai/claude-code` release, so the billing
367
381
  // `cc_version=` suffix and the `claude-cli/` User-Agent stay on what
368
382
  // upstream ships.
369
- fallback: "2.1.302",
383
+ fallback: "2.1.314",
370
384
  sources: [{ url: "https://registry.npmjs.org/@anthropic-ai/claude-code/latest" }],
371
385
  },
372
386
  claudeSdk: {
@@ -393,20 +407,21 @@ export const VERSION_SOURCES = {
393
407
  },
394
408
  kilo: {
395
409
  key: "kilo-code",
396
- fallback: "7.8.14",
410
+ fallback: "7.8.25",
397
411
  sources: [{ url: "https://open-vsx.org/api/kilocode/kilo-code" }],
398
412
  },
399
413
  muse: {
400
414
  key: "muse-code",
401
- fallback: "1.4.10-R6427.1",
415
+ fallback: "1.4.14-R7309.1",
402
416
  sources: [{ url: "https://api.meta.ai/muse-code/channels/muse-stable" }],
403
417
  },
404
418
  trae: {
405
419
  key: "trae",
406
- // Fallback = the donor's last observed client version. Discovery replaces
407
- // it within one monitor tick; it is only what a cold process sends before
420
+ // Fallback = the newest release the changelog names, which is the *high*
421
+ // end of its newest line ("TRAE v3.6.1 ~ 3.6.4"). Discovery replaces it
422
+ // within one monitor tick; it is only what a cold process sends before
408
423
  // the first successful fetch.
409
- fallback: "3.6.2",
424
+ fallback: "3.6.4",
410
425
  sources: [
411
426
  {
412
427
  url: "https://docs.trae.ai/ide/changelog?_lang=en",
@@ -419,7 +434,7 @@ export const VERSION_SOURCES = {
419
434
  // Fallback = the last observed wire version. Discovery replaces it within
420
435
  // one monitor tick; it is only what a cold process sends before the first
421
436
  // successful fetch.
422
- fallback: "cli-2026.10.19-6bbf2c4",
437
+ fallback: "cli-3.27.22-b1aa50c",
423
438
  sources: [
424
439
  {
425
440
  url: "https://cursor.com/api/download?platform=win32-x64-user&releaseTrack=stable",
@@ -433,7 +448,7 @@ export const VERSION_SOURCES = {
433
448
  // comment this replaced claimed no semver existed and pinned a date tag
434
449
  // (`v2026.9.24`) as the version — a tag, not a release, and not the
435
450
  // identity the client sends.
436
- fallback: "0.22.2",
451
+ fallback: "0.22.5",
437
452
  sources: [
438
453
  {
439
454
  url: "https://api.github.com/repos/NousResearch/hermes-agent/releases/latest",
@@ -338,7 +338,17 @@ export async function registerByokProviders(
338
338
  provider_id: providerId,
339
339
  base_url: baseUrl,
340
340
  authentication_header_shape: wireProfile.authHeaderShape,
341
- buildExtraHeaders: (_context, _request, candidate) => {
341
+ buildExtraHeaders: (context, _request, candidate) => {
342
+ // An operator-set route identity wins over both auto modes: Routing
343
+ // Strategy now serves custom providers too, and its value (including
344
+ // the empty "None" choice) must be honored verbatim.
345
+ const routeAgent = context.user_agent;
346
+ if (routeAgent !== undefined) {
347
+ return {
348
+ ...(routeAgent.length > 0 ? { "user-agent": routeAgent } : {}),
349
+ ...(compatibilityProfile?.extra_headers ?? {}),
350
+ };
351
+ }
342
352
  // Explicit gateway identity wins over CLI cloaking, and Codex /
343
353
  // Claude-Code-shaped traffic can never take this path: this hook
344
354
  // only runs for BYOK custom rows, never bundled first-party
@@ -136,7 +136,11 @@ export interface ProviderDispatchContext {
136
136
  readonly outbound_attachment_fetch?: ValidatedOutboundFetch | undefined;
137
137
  /** Validated bidirectional HTTP/2 egress bound to the same selected network pool. */
138
138
  readonly outbound_http2?: ValidatedOutboundHttp2Bidi | undefined;
139
- /** Built-in API-key route-selected fallback User-Agent; custom providers leave this unset. */
139
+ /**
140
+ * Route-selected fallback User-Agent from Routing Strategy; set when the
141
+ * operator configured one (bundled API-key providers default to the Claude
142
+ * CLI identity). Empty means the operator chose "None".
143
+ */
140
144
  readonly user_agent?: string | undefined;
141
145
  /** Gateway request id, stable across provider retries for one logical request. */
142
146
  readonly request_id?: string | undefined;
@@ -151,6 +155,14 @@ export interface ProviderDispatchContext {
151
155
  * and hold no database handle.
152
156
  */
153
157
  readonly image_clamp_max_bytes?: number | undefined;
158
+ /**
159
+ * Tenant system-prompt text resolved once per request (append/override
160
+ * injection). The buddy adapters fold it into their fixed system turn after
161
+ * serialization, wrapped in the gateway's marker prefix/suffix, so the
162
+ * upstream's channel-identity validation still sees its prompt as the
163
+ * opener.
164
+ */
165
+ readonly tenant_system_prompt?: string | undefined;
154
166
  /** Opaque identity shared by retries of one logical gateway request. */
155
167
  readonly request_identity?: object | undefined;
156
168
  /**
@@ -188,7 +200,8 @@ export function applyRouteUserAgent(
188
200
  if (
189
201
  credential.credential_kind === "oauth" ||
190
202
  credential.credential_kind === "scoped_access_token" ||
191
- userAgent === undefined
203
+ userAgent === undefined ||
204
+ userAgent.trim().length === 0
192
205
  ) {
193
206
  return;
194
207
  }
@@ -1,5 +1,24 @@
1
1
  // Shared authorization primitives: closed scope model and immutable access decisions.
2
2
 
3
+ /**
4
+ * The single identity of "who is speaking" — resolved once at auth and carried
5
+ * through planning, admission, pool selection, and telemetry so every layer
6
+ * reasons about the same caller.
7
+ *
8
+ * - `apiKeyId` — the credential that authenticated.
9
+ * - `admissionIdentity` — the quota/concurrency owner (the share parent for a
10
+ * child key; otherwise the key itself).
11
+ * - `tenantId` — the tenant the request runs as.
12
+ *
13
+ * Provider/account/model are added by the candidate, not here: the caller
14
+ * identity is stable regardless of what serves the request.
15
+ */
16
+ export interface CallerIdentity {
17
+ readonly apiKeyId: string;
18
+ readonly admissionIdentity: string;
19
+ readonly tenantId: string;
20
+ }
21
+
3
22
  /**
4
23
  * Closed set of authorization scopes.
5
24
  * - `routing:invoke`: May call only /v1/* gateway routes within holder's tenant.
@@ -6,7 +6,7 @@ import { DrizzleApiKeyStore } from "../persistence/stores/api-key-store";
6
6
  import { GatewayError } from "../protocol/gateway-error";
7
7
  import { hashSecret } from "./crypto";
8
8
  import { AUTH_CACHE_TTL_MS, createApiKeyAuthorizationCache } from "./api-key-auth-cache";
9
- import type { AccessScope } from "./access-control";
9
+ import type { AccessScope, CallerIdentity } from "./access-control";
10
10
  import type { ApiKeyModelAccessMode } from "../persistence/schema";
11
11
 
12
12
  // ── Authorization cache ──────────────────────────────────────────────────────
@@ -222,6 +222,12 @@ export interface ResolvedApiKey {
222
222
  readonly modelPrefix?: string;
223
223
  /** Share-template id whose remote CLI mappings are inherited by this child. */
224
224
  readonly cliMappingOwnerId?: string;
225
+ /**
226
+ * Single "who is speaking" identity derived at auth. Carried through
227
+ * planning, admission, pool selection, and telemetry so every gate reasons
228
+ * about the same caller.
229
+ */
230
+ readonly caller: CallerIdentity;
225
231
  }
226
232
 
227
233
  /**
@@ -398,6 +404,13 @@ export async function resolveApiKeyAuthorization(
398
404
  snapshot,
399
405
  ...(policy.modelPrefix ? { modelPrefix: policy.modelPrefix } : {}),
400
406
  ...(parent?.keyMode === "share" ? { cliMappingOwnerId: parent.id } : {}),
407
+ caller: {
408
+ apiKeyId: row.id,
409
+ // The admission identity is the family owner for a share child — the
410
+ // same id every counter/lease in the system keys against.
411
+ admissionIdentity: snapshot.admission_identity ?? row.id,
412
+ tenantId: row.tenantId,
413
+ },
401
414
  };
402
415
  authorizationCache.rememberPositive(hash, value.id, value, Date.now());
403
416
  // Shared copy for peer processes, keyed by the token hash so a lookup can
@@ -50,13 +50,20 @@ const REMOTE_CLI_TOOL_UA: ReadonlyArray<{
50
50
  // filtering; MCP traffic uses `claude-code/<version>` instead.
51
51
  { toolId: "claude", pattern: /(^|[^a-z0-9])claude-cli\//i },
52
52
  { toolId: "claude", pattern: /(^|[^a-z0-9])claude-code\//i },
53
+ // Codex CLI (TUI/CLI builds) — the Guardian auto-review agent sends a
54
+ // `codex-auto-review` model that is only useful when the gateway can
55
+ // remap it to a serving provider. `codex-tui`, `codex-cli`, and the
56
+ // desktop agent's `opencode`-ish UAs all carry this prefix.
57
+ { toolId: "codex", pattern: /(^|[^a-z0-9])codex-(tui|cli)\//i },
53
58
  ];
54
59
 
55
60
  /**
56
61
  * Returns the remote CLI tool id recognised from the probe, or `null` when
57
62
  * the caller is not a remote-mapping client. Ordinary SDKs, curl, and local
58
- * mapping tools (Codex, …) stay unlabelled so their model ids resolve
59
- * through ordinary aliases / allowlists.
63
+ * mapping tools stay unlabelled so their model ids resolve through ordinary
64
+ * aliases / allowlists. Codex is labelled because its Guardian auto-review
65
+ * agent sends the hardcoded `codex-auto-review` model, which must be remapable
66
+ * to a serving provider for approval reviews to work at all.
60
67
  */
61
68
  export function detectRemoteCliToolId(probe: CliClientProbe): string | null {
62
69
  const userAgent = readUserAgent(probe);