cartethyia 2.7.5 → 2.7.7

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 (300) hide show
  1. package/.env.example +8 -3
  2. package/README.md +26 -2
  3. package/dist/dashboard/assets/BannedPage-B05aF8Dg.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B05aF8Dg.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-CLUhmjUy.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-CLUhmjUy.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-CQmrqqrk.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-CQmrqqrk.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-CHG_1Wr3.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-CHG_1Wr3.js.gz +0 -0
  11. package/dist/dashboard/assets/{ConsoleLogPage-D5rol2j2.js → ConsoleLogPage-DPgbklad.js} +1 -1
  12. package/dist/dashboard/assets/ConsoleLogPage-DPgbklad.js.gz +0 -0
  13. package/dist/dashboard/assets/{CustomizationPage-BKj_r0rp.js → CustomizationPage-pnfAqr_-.js} +1 -1
  14. package/dist/dashboard/assets/CustomizationPage-pnfAqr_-.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-DGJuU2A6.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-DGJuU2A6.js.gz +0 -0
  17. package/dist/dashboard/assets/{InjectSystemPromptPanel-B5nZvmf0.js → InjectSystemPromptPanel-C-e2AMz6.js} +245 -2
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-C-e2AMz6.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-J8wPbmfT.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-J8wPbmfT.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-DnQPSIA8.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-BSQnF2Lp.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-BSQnF2Lp.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-DK_e0FJz.js +7 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-DK_e0FJz.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-D_a3r6Gc.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-D_a3r6Gc.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-5SnUSy3j.js → ProxyPage-BBTRBAQ3.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-BBTRBAQ3.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-B2WqMSG1.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-B2WqMSG1.js.gz +0 -0
  35. package/dist/dashboard/assets/{SettingsPage-BJtRZ4qD.js → SettingsPage-D7xp5Ij_.js} +1 -1
  36. package/dist/dashboard/assets/SettingsPage-D7xp5Ij_.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-LND6_Ss7.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-LND6_Ss7.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-BfAb5-o_.js → StudioPage-BzNnm6Bi.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-BzNnm6Bi.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-BNzeZ2Vk.js → UsagePage-C1TbL24N.js} +13 -13
  44. package/dist/dashboard/assets/UsagePage-C1TbL24N.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-C0K-c4eo.js → assert-CidQVoNo.js} +1 -1
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-DfbhQU4k.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-BllT4LcF.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/{card-CtkX66Wd.js → card-CxDw0lK6.js} +1 -1
  58. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  59. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  60. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  61. package/dist/dashboard/assets/{cli-tools-CQXVMn4P.js → cli-tools-Bwv5-zGZ.js} +1 -1
  62. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  63. package/dist/dashboard/assets/{clipboard-button-BQqBQd2n.js → clipboard-button-DfS1ntiq.js} +1 -1
  64. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  65. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  66. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  67. package/dist/dashboard/assets/{drawer-BrTEZ8zu.js → drawer-QqPul6sC.js} +1 -1
  68. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  69. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  70. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  71. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  72. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  73. package/dist/dashboard/assets/entry-vqGb8yVz.js +4 -0
  74. package/dist/dashboard/assets/entry-vqGb8yVz.js.gz +0 -0
  75. package/dist/dashboard/assets/formatters-DP-5E01-.js +1 -0
  76. package/dist/dashboard/assets/formatters-DP-5E01-.js.gz +0 -0
  77. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  78. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  79. package/dist/dashboard/assets/{index-FQlj0HUT.js → index-D36vCZht.js} +2 -2
  80. package/dist/dashboard/assets/index-D36vCZht.js.gz +0 -0
  81. package/dist/dashboard/assets/{inline-C4gU5iOL.js → inline-CHJQwxLa.js} +1 -1
  82. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  83. package/dist/dashboard/assets/{input-BHHX_Tmm.js → input-BlmlizVV.js} +1 -1
  84. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  85. package/dist/dashboard/assets/{layout-CajrYUnD.js → layout-Bz93I-yE.js} +1 -1
  86. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  87. package/dist/dashboard/assets/{list-row-Bx2I7XUe.js → list-row-Ml16KCfu.js} +1 -1
  88. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  89. package/dist/dashboard/assets/{live-DNNqRbj2.js → live-7_QpnYGu.js} +1 -1
  90. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  91. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  92. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  93. package/dist/dashboard/assets/{network-C5UBACrJ.js → network-CuMDaTzT.js} +1 -1
  94. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  95. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  96. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  97. package/dist/dashboard/assets/{pagination-Xsi9Qx04.js → pagination-B5aOoweZ.js} +1 -1
  98. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  99. package/dist/dashboard/assets/providers/zai.webp +0 -0
  100. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  101. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  102. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  103. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  104. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  105. package/dist/dashboard/assets/{routing-in0f_IfK.js → routing-fnCsxgNO.js} +1 -1
  106. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  107. package/dist/dashboard/assets/{select-BLULNqTp.js → select-C9Ssle9b.js} +2 -2
  108. package/dist/dashboard/assets/select-C9Ssle9b.js.gz +0 -0
  109. package/dist/dashboard/assets/{settings-CcGczj6I.js → settings-BxslsErn.js} +1 -1
  110. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  111. package/dist/dashboard/assets/{stack-D2lIR0tg.js → stack-j7cXjgYX.js} +1 -1
  112. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  113. package/dist/dashboard/assets/{state-DTARjfiW.js → state-DHmEnLa2.js} +1 -1
  114. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  115. package/dist/dashboard/assets/{switch-c0oPSnqW.js → switch-DmZcyTIC.js} +1 -1
  116. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  117. package/dist/dashboard/assets/{useMutation-m8WGNPrz.js → useMutation-CbCP4w1o.js} +1 -1
  118. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  119. package/dist/dashboard/index.html +2 -2
  120. package/dist/dashboard/index.html.gz +0 -0
  121. package/dist/dashboard/precompressed-assets.json +57 -57
  122. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  123. package/migrations/full-postgres/0043_add_provider_custom_user_agent.sql +14 -0
  124. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  125. package/migrations/lite-sqlite3/0043_add_provider_custom_user_agent.sql +10 -0
  126. package/package.json +3 -1
  127. package/src/boot/dependencies.ts +10 -2
  128. package/src/config/providers.ts +13 -7
  129. package/src/config/security.ts +1 -1
  130. package/src/config/spec.ts +31 -17
  131. package/src/config/usage.ts +27 -0
  132. package/src/console/api-keys/routes.ts +19 -23
  133. package/src/console/cli-tools/cartethyia-websearch-plugin.ts +186 -0
  134. package/src/console/cli-tools/contracts.ts +39 -295
  135. package/src/console/cli-tools/fs-ops.ts +29 -0
  136. package/src/console/cli-tools/injectors/claude.ts +3 -3
  137. package/src/console/cli-tools/injectors/codex.ts +6 -6
  138. package/src/console/cli-tools/injectors/driver.ts +8 -105
  139. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  140. package/src/console/cli-tools/injectors/opencode.ts +68 -17
  141. package/src/console/cli-tools/routes.ts +6 -0
  142. package/src/console/cli-tools/service.ts +7 -6
  143. package/src/console/observability/contracts.ts +6 -0
  144. package/src/console/observability/store.ts +3 -0
  145. package/src/console/providers/catalog/contracts.ts +4 -0
  146. package/src/console/providers/catalog/routes.ts +1 -0
  147. package/src/console/providers/detail/routes.ts +8 -0
  148. package/src/console/providers/detail/store.ts +4 -0
  149. package/src/console/quota/account-quota-tenant.ts +74 -0
  150. package/src/console/share/share-stats.ts +7 -9
  151. package/src/observability/event-log.ts +7 -0
  152. package/src/observability/event-query.ts +2 -0
  153. package/src/observability/telemetry-buffer.ts +9 -1
  154. package/src/persistence/boot.ts +13 -4
  155. package/src/persistence/schema.ts +15 -1
  156. package/src/persistence/stores/api-key-store.ts +19 -1
  157. package/src/protocol/canonical-model.ts +7 -0
  158. package/src/protocol/dsml.ts +5 -76
  159. package/src/protocol/request/gemini.ts +20 -1
  160. package/src/protocol/tool-identity.ts +15 -1
  161. package/src/providers/adapters/compatible-adapter.ts +29 -1
  162. package/src/providers/default-registry.ts +20 -4
  163. package/src/providers/discovery/discovery-types.ts +18 -0
  164. package/src/providers/discovery/probe-phases.ts +45 -0
  165. package/src/providers/discovery/probing-service.ts +41 -6
  166. package/src/providers/integrations/antigravity/antigravity-protocol.ts +108 -16
  167. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  168. package/src/providers/integrations/antigravity/antigravity.ts +44 -11
  169. package/src/providers/integrations/codex/codex.ts +28 -1
  170. package/src/providers/integrations/cursor/cursor.ts +2 -3
  171. package/src/providers/integrations/github/github-discovery.ts +15 -2
  172. package/src/providers/integrations/github/github-oauth.ts +178 -9
  173. package/src/providers/integrations/github/github.ts +95 -14
  174. package/src/providers/integrations/kiro/kiro.ts +1 -2
  175. package/src/providers/integrations/qoder/chat-proto.ts +328 -0
  176. package/src/providers/integrations/qoder/claim-qoder-credits.ts +258 -0
  177. package/src/providers/integrations/qoder/qoder-adapter.ts +275 -0
  178. package/src/providers/integrations/qoder/qoder-auth.ts +201 -0
  179. package/src/providers/integrations/qoder/qoder-body.ts +78 -0
  180. package/src/providers/integrations/qoder/qoder-catalog.ts +14 -4
  181. package/src/providers/integrations/qoder/qoder-chat.ts +514 -0
  182. package/src/providers/integrations/qoder/qoder-cosy.ts +162 -0
  183. package/src/providers/integrations/qoder/qoder-grpc.ts +667 -0
  184. package/src/providers/integrations/qoder/qoder-ide.ts +584 -0
  185. package/src/providers/integrations/qoder/qoder-oauth.ts +4 -4
  186. package/src/providers/integrations/qoder/qoder-quota.ts +1 -1
  187. package/src/providers/integrations/qoder/qoder-realm.ts +40 -4
  188. package/src/providers/integrations/qoder/qoder-types.ts +51 -0
  189. package/src/providers/integrations/qoder/qoder-umid.ts +123 -8
  190. package/src/providers/integrations/qoder/qoder.ts +147 -1830
  191. package/src/providers/integrations/trae/trae.ts +2 -2
  192. package/src/providers/operations/account-error-classification.ts +67 -17
  193. package/src/providers/operations/byok-wire-profile.ts +19 -15
  194. package/src/providers/provider-contracts.ts +7 -0
  195. package/src/providers/provider-usage.ts +24 -55
  196. package/src/security/abuse.ts +5 -5
  197. package/src/security/admission/service.ts +11 -4
  198. package/src/security/api-key-auth.ts +5 -3
  199. package/src/transport/dispatch/attempt-finalize.ts +69 -21
  200. package/src/transport/dispatch/attempt-loop.ts +22 -0
  201. package/src/transport/dispatch/upstream.ts +4 -2
  202. package/src/transport/failure-policy.ts +15 -1
  203. package/src/transport/guards/error-lifecycle.ts +4 -0
  204. package/src/transport/request/state.ts +6 -0
  205. package/src/transport/routing/route-catalog.ts +8 -0
  206. package/src/transport/routing/route-model.ts +4 -0
  207. package/src/transport/routing/router.ts +8 -110
  208. package/src/transport/surface/reasoning-summary.ts +9 -14
  209. package/src/transport/vision-handoff.ts +83 -28
  210. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js +0 -1
  211. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
  212. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +0 -1
  213. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
  214. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js +0 -1
  215. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
  216. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js +0 -1
  217. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
  218. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +0 -1
  219. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
  220. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
  221. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
  222. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
  223. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js +0 -1
  224. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
  225. package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
  226. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +0 -1
  227. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
  228. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +0 -5
  229. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
  230. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +0 -1
  231. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
  232. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +0 -1
  233. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
  234. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
  235. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +0 -1
  236. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
  237. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
  238. package/dist/dashboard/assets/SetupPage-WTa0sktC.js +0 -1
  239. package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
  240. package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
  241. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  242. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  243. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
  244. package/dist/dashboard/assets/api-keys-l29JROPv.js +0 -1
  245. package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
  246. package/dist/dashboard/assets/app--PJWq8_C.css +0 -2
  247. package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
  248. package/dist/dashboard/assets/app-Bgd3zANQ.js +0 -9
  249. package/dist/dashboard/assets/app-Bgd3zANQ.js.gz +0 -0
  250. package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
  251. package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
  252. package/dist/dashboard/assets/banner-BllT4LcF.js.gz +0 -0
  253. package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
  254. package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
  255. package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
  256. package/dist/dashboard/assets/dialog-BEK7KP0H.js +0 -1
  257. package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
  258. package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
  259. package/dist/dashboard/assets/entry-CHWxbS56.js +0 -1
  260. package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
  261. package/dist/dashboard/assets/entry-EBHJ3DrE.js +0 -1
  262. package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
  263. package/dist/dashboard/assets/entry-LCS85hiq.js +0 -4
  264. package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
  265. package/dist/dashboard/assets/formatters-BAACA727.js +0 -1
  266. package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
  267. package/dist/dashboard/assets/github-badge-YSCE4UC2.js +0 -1
  268. package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
  269. package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
  270. package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
  271. package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
  272. package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
  273. package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
  274. package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
  275. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  276. package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
  277. package/dist/dashboard/assets/numbers-CUWAZK4J.js +0 -2
  278. package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
  279. package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
  280. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  281. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  282. package/dist/dashboard/assets/quota-DvQbD_sr.js +0 -1
  283. package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
  284. package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
  285. package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
  286. package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
  287. package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
  288. package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
  289. package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
  290. package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
  291. package/src/console/cli-tools/injectors/cline.ts +0 -110
  292. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  293. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  294. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  295. package/src/console/cli-tools/injectors/droid.ts +0 -96
  296. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  297. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  298. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  299. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
  300. package/src/providers/integrations/qoder/qoder-text-tools.ts +0 -277
@@ -202,7 +202,10 @@ export const PROVIDER_CAPABILITIES = {
202
202
  },
203
203
  codex: {
204
204
  loadAdapter: async () => (await import("./integrations/codex/codex")).createCodexAdapter({ provider_id: "codex" }),
205
- loadModels: async () => (await import("./integrations/codex/codex")).CODEX_MODELS,
205
+ loadModels: async () => {
206
+ const { CODEX_MODELS, CODEX_SEARCH_MODELS } = await import("./integrations/codex/codex");
207
+ return [...CODEX_MODELS, ...CODEX_SEARCH_MODELS];
208
+ },
206
209
  loadAuthentication: oauthCapability(() => import("./integrations/codex/codex-oauth"), "codexOAuthClient", { withRefresher: true }),
207
210
  loadQuotaCollector: quotaCapability(() => import("./integrations/codex/codex-quota"), "fetchCodexQuota"),
208
211
  loadModelDiscovery: async () => async ({ credential, fetcher }) =>
@@ -235,12 +238,25 @@ export const PROVIDER_CAPABILITIES = {
235
238
  },
236
239
  antigravity: {
237
240
  loadAdapter: async () => (await import("./integrations/antigravity/antigravity")).antigravityAdapter,
238
- loadModels: async () => (await import("./integrations/antigravity/antigravity")).ANTIGRAVITY_MODELS,
241
+ loadModels: async () => {
242
+ const { ANTIGRAVITY_MODELS, ANTIGRAVITY_SEARCH_MODELS } = await import("./integrations/antigravity/antigravity");
243
+ return [...ANTIGRAVITY_MODELS, ...ANTIGRAVITY_SEARCH_MODELS];
244
+ },
239
245
  loadAuthentication: oauthCapability(() => import("./integrations/antigravity/antigravity-oauth"), "antigravityOAuthClient", { withRefresher: true }),
240
246
  loadQuotaCollector: quotaCapability(() => import("./integrations/antigravity/antigravity-quota"), "fetchAntigravityQuota"),
241
247
  loadModelDiscovery: async () => async ({ baseUrl, credential, fetcher }) => {
242
- const { discoverAntigravityModels } = await import("./integrations/antigravity/antigravity-protocol");
243
- return discoverAntigravityModels(credential, { baseUrl, ...(fetcher ? { fetcher } : {}) });
248
+ const { discoverAntigravityModels, loadAntigravityProject } = await import("./integrations/antigravity/antigravity-protocol");
249
+ // The reference client resolves the project before catalog calls; the
250
+ // live backend accepts both, but sending it matches the captured wire.
251
+ const projectId = await loadAntigravityProject(credential, {
252
+ ...(baseUrl === undefined ? {} : { baseUrl }),
253
+ ...(fetcher ? { fetcher } : {}),
254
+ }).catch(() => undefined);
255
+ return discoverAntigravityModels(credential, {
256
+ baseUrl,
257
+ ...(fetcher ? { fetcher } : {}),
258
+ ...(projectId === undefined ? {} : { projectId }),
259
+ });
244
260
  },
245
261
  },
246
262
  muse: {
@@ -74,6 +74,17 @@ export interface ProbeModelRequest {
74
74
  reasoningEffort?: ProbeReasoningEffort;
75
75
  maxOutputTokens?: number;
76
76
  stream?: boolean;
77
+ /**
78
+ * Provider-specific transport override for the probe.
79
+ *
80
+ * `undefined` (default) probes through the same transport live traffic
81
+ * uses. A provider may expose extra surfaces that only a probe can force —
82
+ * Qoder's IDE surface (`/model/v1`) is the only one that echoes strategy
83
+ * metadata (`provider_model`, `target`, …) alongside the answer, while the
84
+ * production transports (gRPC / COSY) do not. Forcing it makes the probe
85
+ * result the richest available source of truth.
86
+ */
87
+ surface?: "default" | "cosy" | "grpc" | "ide";
77
88
  }
78
89
  export interface ProbeModelResult {
79
90
  accountId?: string;
@@ -93,6 +104,13 @@ export interface ProbeModelResult {
93
104
  reportedModel?: string;
94
105
  statusCode?: number;
95
106
  error?: string;
107
+ /**
108
+ * Provider-specific upstream metadata about the model that actually served
109
+ * the turn (native model id, supply target, tier). Filled when the probed
110
+ * transport exposes it — Qoder's IDE surface reports it in `raw_usage`;
111
+ * the production transports do not.
112
+ */
113
+ providerMetadata?: Readonly<Record<string, unknown>>;
96
114
  /** Normalized hits a `websearch` probe returned, so the console can show them. */
97
115
  searchResults?: ReadonlyArray<{
98
116
  readonly title: string;
@@ -150,6 +150,27 @@ export function extractSample(events: readonly CanonicalEvent[]): string | undef
150
150
  return trimmed.length > 0 ? trimmed.slice(0, 200) : undefined;
151
151
  }
152
152
 
153
+ /**
154
+ * Reads the model an adapter reported in its canonical events.
155
+ *
156
+ * The HTTP-only `readReportedModel` inspects the raw response body, so it
157
+ * cannot see the model on non-HTTP transports (Qoder gRPC). Adapters surface
158
+ * the upstream echo as `response_start`/`message_start` with a `model` field;
159
+ * this reads that as a fallback.
160
+ */
161
+ export function modelFromEvents(events: readonly CanonicalEvent[]): string | undefined {
162
+ for (const event of events) {
163
+ if (
164
+ (event.type === "response_start" || event.type === "message_start") &&
165
+ typeof event.model === "string" &&
166
+ event.model.trim().length > 0
167
+ ) {
168
+ return event.model.trim();
169
+ }
170
+ }
171
+ return undefined;
172
+ }
173
+
153
174
  export function hasMeaningfulOutput(events: readonly CanonicalEvent[]): boolean {
154
175
  return events.some((event) => {
155
176
  if (event.type === "tool_call_delta") return true;
@@ -581,6 +602,30 @@ export async function loadProbePreferences(args: {
581
602
  return { probeReasoning, payloadCapture };
582
603
  }
583
604
 
605
+ /**
606
+ * The probe's default identity prompt (`What model are you...`) works for
607
+ * every Qoder roster row except `cmodel` (virtual id `cantus`): that row's
608
+ * gRPC surface answers the identity question with `406 Upstream error [stream]`
609
+ * from the upstream proxy (verified live 2026-11-04; dmodel/qmodel/smodel all
610
+ * accept it). Returns the neutral replacement prompt when the probe targets
611
+ * that row with no explicit prompt, `undefined` otherwise.
612
+ *
613
+ * The replacement prompt must never *ask* an identity question: the upstream
614
+ * guardrail is content-based and swallows the reply (empty sample) for any
615
+ * phrasing that interrogates identity — even indirect ones (`what would you
616
+ * call yourself`, `which model are you`, `perkenalkan dirimu`). A plain
617
+ * greeting that *asserts* the wrong identity (`halo gpt`) makes the model
618
+ * correct us on its own, and returns a sample 3/3 runs (verified live
619
+ * 2026-11-04). We keep that phrasing — it is 100% consistent and the model
620
+ * names itself ("saya Claude... buatan Anthropic") without us ever asking.
621
+ */
622
+ export function qoderCmodelProbePrompt(providerId: string, modelId: string, prompt: string | undefined): string | undefined {
623
+ if (prompt !== undefined) return undefined;
624
+ if (providerId !== "qoder" && providerId !== "qodercn") return undefined;
625
+ if (modelId !== "cmodel" && modelId !== "cantus") return undefined;
626
+ return "halo gpt";
627
+ }
628
+
584
629
  /**
585
630
  * Phase 5 — build the canonical probe request. The probe prompt must pass every
586
631
  * provider's content-policy review (a bare "hi" trips CodeBuddy's 11140 safety
@@ -42,10 +42,12 @@ import {
42
42
  buildProbeCanonicalRequest,
43
43
  computeProbeVerdict,
44
44
  extractSample,
45
+ modelFromEvents,
45
46
  GROK_407_PROBE_PROMPT,
46
47
  grok407ProbeFailure,
47
48
  hasMeaningfulOutput,
48
49
  loadProbePreferences,
50
+ qoderCmodelProbePrompt,
49
51
  recordProbeHealth,
50
52
  resolveProbeAdapter,
51
53
  resolveProbeTarget,
@@ -186,7 +188,16 @@ export class ProviderProbingService {
186
188
  request: ProbeModelRequest,
187
189
  ): Promise<ProbeModelResult> {
188
190
  const startedAt = Date.now();
189
- const modelId = request.modelId;
191
+ // Qoder's IDE surface is the only transport that echoes provider metadata
192
+ // (`provider_model`, `target`, …) in its raw_usage, so probes for Qoder
193
+ // default to it unless the operator picked a surface explicitly. This
194
+ // covers every entry point (single model, all models, all accounts).
195
+ const normalizedRequest: ProbeModelRequest =
196
+ (providerId === "qoder" || providerId === "qodercn") &&
197
+ (request.surface === undefined || request.surface === "default")
198
+ ? { ...request, surface: "ide" }
199
+ : request;
200
+ const modelId = normalizedRequest.modelId;
190
201
  // One provider snapshot per probe: the contract gate, the account gate, the
191
202
  // custom-adapter fallback, and the wire context all read this same row, so a
192
203
  // concurrent edit cannot make two reads disagree.
@@ -207,10 +218,10 @@ export class ProviderProbingService {
207
218
  db: this.db,
208
219
  tenantId,
209
220
  providerId,
210
- requestedAccountId: request.accountId,
221
+ requestedAccountId: normalizedRequest.accountId,
211
222
  requiresAccount,
212
223
  allowCoolingAccount:
213
- providerId === "grok" && request.prompt === GROK_407_PROBE_PROMPT,
224
+ providerId === "grok" && normalizedRequest.prompt === GROK_407_PROBE_PROMPT,
214
225
  });
215
226
  if (!account.ok) {
216
227
  return { ok: false, latencyMs: Date.now() - startedAt, error: account.error };
@@ -236,9 +247,16 @@ export class ProviderProbingService {
236
247
  wireFamily,
237
248
  request,
238
249
  });
250
+ // Qoder's gRPC surface refuses a probe that asks a model to identify
251
+ // itself (406 from the upstream proxy) for one roster row (`cmodel`,
252
+ // virtual id `cantus`). dmodel/qmodel/smodel accept the identity prompt
253
+ // fine — only cmodel refuses it — so the workaround is scoped to that
254
+ // row, not to every Qoder probe, and never overrides an explicit prompt.
255
+ const qoderCmodelPrompt = qoderCmodelProbePrompt(providerId, modelId, normalizedRequest.prompt);
256
+ const probeRequest = qoderCmodelPrompt === undefined ? normalizedRequest : { ...normalizedRequest, prompt: qoderCmodelPrompt };
239
257
  const canonicalRequest = buildProbeCanonicalRequest({
240
258
  modelId,
241
- request,
259
+ request: probeRequest,
242
260
  probeReasoning,
243
261
  sourceSurface,
244
262
  });
@@ -257,6 +275,11 @@ export class ProviderProbingService {
257
275
  // The model row's own output ceiling, so a probe with a max-output
258
276
  // ceiling (OpenCode free) shapes with the model's limit, not a guess.
259
277
  ...(outputLimit == null ? {} : { output_limit: outputLimit }),
278
+ // Probe-only transport override, when the operator asked for one. Live
279
+ // dispatch never sets this.
280
+ ...(normalizedRequest.surface === undefined || normalizedRequest.surface === "default"
281
+ ? {}
282
+ : { probe_surface: normalizedRequest.surface }),
260
283
  };
261
284
 
262
285
  const probeSignal = AbortSignal.timeout(30_000);
@@ -308,7 +331,7 @@ export class ProviderProbingService {
308
331
  `Provider ${providerId} has no web search transport (request {requestId}). Know your tools — this one just isn't in the box 🧰`,
309
332
  );
310
333
  }
311
- const searchProbeQuery = request.prompt?.trim() || "Cartethyia gateway probe";
334
+ const searchProbeQuery = normalizedRequest.prompt?.trim() || "Cartethyia gateway probe";
312
335
  const response = await adapter.websearch(
313
336
  { model: modelId, query: searchProbeQuery, max_results: 3 },
314
337
  candidate,
@@ -574,7 +597,16 @@ export class ProviderProbingService {
574
597
  }
575
598
 
576
599
  const sample = extractSample(events);
577
- const reportedModel = await probeCapture?.reportedModel?.catch(() => undefined);
600
+ // The HTTP-only `readReportedModel` covers response-body transports; a
601
+ // non-HTTP transport (Qoder gRPC) reports the upstream echo as a
602
+ // `response_start` event instead — fall back to that when the body read
603
+ // came up empty.
604
+ const reportedModel =
605
+ (await probeCapture?.reportedModel?.catch(() => undefined)) ?? modelFromEvents(events);
606
+ // Provider-specific upstream model metadata (Qoder IDE surface raw_usage):
607
+ // carried on the terminal event by the adapter, surfaced verbatim.
608
+ const terminal = events.find((event) => event.type === "terminal");
609
+ const providerMetadata = terminal?.type === "terminal" ? terminal.provider_metadata : undefined;
578
610
  return {
579
611
  ...(accountId ? { accountId } : {}),
580
612
  ok,
@@ -583,6 +615,9 @@ export class ProviderProbingService {
583
615
  ...(upstreamStatusCode === undefined ? {} : { statusCode: upstreamStatusCode }),
584
616
  ...(sample ? { sample } : {}),
585
617
  ...(reportedModel === undefined ? {} : { reportedModel }),
618
+ ...(providerMetadata === undefined || Object.keys(providerMetadata).length === 0
619
+ ? {}
620
+ : { providerMetadata }),
586
621
  ...(searchResults !== undefined && searchResults.length > 0 ? { searchResults } : {}),
587
622
  ...(errorMessage ? { error: errorMessage } : {}),
588
623
  };
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { createHash } from "node:crypto";
19
19
  import { providerBaseUrl } from "../../provider-metadata";
20
- import type { ModelDefinition } from "../../provider-model-definition";
20
+ import { defineModel, type ModelDefinition } from "../../provider-model-definition";
21
21
  import { isRecord } from "../../../protocol/codecs";
22
22
  import { modelsDevCatalog } from "../../discovery/models-dev-catalog";
23
23
  import type { CanonicalRequest, ReasoningIntent } from "../../../protocol/canonical-model";
@@ -96,7 +96,8 @@ interface AntigravityModelWireProfile {
96
96
 
97
97
  /**
98
98
  * `maxOutputTokens` the backend enforces per wire id (captured from the real
99
- * `antigravity/hub` client). Claude on `daily-cloudcode-pa` rejects
99
+ * `antigravity/hub` client and verified live against `fetchAvailableModels`
100
+ * on 2026-11-03). Claude on `daily-cloudcode-pa` rejects
100
101
  * `maxOutputTokens > 64000` with a `400 Request contains an invalid argument`
101
102
  * regardless of the thinking budget; Gemini SKUs accept their discovered
102
103
  * output ceiling. Keyed by the routed upstream wire id (post effort-routing),
@@ -106,22 +107,75 @@ interface AntigravityModelWireProfile {
106
107
  const ANTIGRAVITY_MODEL_WIRE_PROFILES: Readonly<
107
108
  Record<string, AntigravityModelWireProfile>
108
109
  > = Object.freeze({
109
- // Anthropic on Antigravity caps at 64000 output tokens.
110
- "claude-opus-4-6-thinking": { maxOutputTokens: 64000 },
111
- "claude-sonnet-4-6": { maxOutputTokens: 64000 },
112
- // Gemini effort-routed wire ids (real deployment names).
113
- "gemini-3-flash-agent": {
114
- modelEnum: "MODEL_PLACEHOLDER_M132",
110
+ // Anthropic on Antigravity caps at 64000 output tokens (verified live).
111
+ "claude-opus-4-6-thinking": {
112
+ modelEnum: "MODEL_PLACEHOLDER_M26",
113
+ maxOutputTokens: 64000,
114
+ },
115
+ "claude-sonnet-4-6": {
116
+ modelEnum: "MODEL_PLACEHOLDER_M35",
117
+ maxOutputTokens: 64000,
118
+ },
119
+ // Gemini SKUs, as the live roster publishes them (2026-11-03).
120
+ "gemini-2.5-flash": {
121
+ modelEnum: "MODEL_GOOGLE_GEMINI_2_5_FLASH",
122
+ maxOutputTokens: 65535,
123
+ },
124
+ "gemini-2.5-flash-thinking": {
125
+ modelEnum: "MODEL_GOOGLE_GEMINI_2_5_FLASH_THINKING",
126
+ maxOutputTokens: 65535,
127
+ },
128
+ "gemini-2.5-flash-lite": {
129
+ modelEnum: "MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE",
130
+ maxOutputTokens: 65535,
131
+ },
132
+ "gemini-2.5-pro": {
133
+ modelEnum: "MODEL_GOOGLE_GEMINI_2_5_PRO",
134
+ maxOutputTokens: 65535,
135
+ },
136
+ "gemini-3-flash": {
137
+ modelEnum: "MODEL_PLACEHOLDER_M18",
115
138
  maxOutputTokens: 65536,
116
139
  },
117
- "gemini-3.1-pro-low": {
118
- modelEnum: "MODEL_PLACEHOLDER_M36",
140
+ "gemini-3.1-flash-lite": {
141
+ modelEnum: "MODEL_PLACEHOLDER_M50",
119
142
  maxOutputTokens: 65535,
120
143
  },
121
- "gemini-pro-agent": {
122
- modelEnum: "MODEL_PLACEHOLDER_M16",
144
+ "gemini-3.1-flash-image": {
145
+ modelEnum: "MODEL_PLACEHOLDER_M21",
146
+ maxOutputTokens: 65536,
147
+ },
148
+ "gemini-3.5-flash-lite": {
149
+ modelEnum: "MODEL_PLACEHOLDER_M198",
123
150
  maxOutputTokens: 65535,
124
151
  },
152
+ // Gemini 3.8 Flash effort tiers (real deployment names).
153
+ "gemini-3.8-flash-low": {
154
+ modelEnum: "MODEL_PLACEHOLDER_M320",
155
+ maxOutputTokens: 65536,
156
+ },
157
+ "gemini-3.8-flash-medium": {
158
+ modelEnum: "MODEL_PLACEHOLDER_M319",
159
+ maxOutputTokens: 65536,
160
+ },
161
+ "gemini-3.8-flash-high": {
162
+ modelEnum: "MODEL_PLACEHOLDER_M318",
163
+ maxOutputTokens: 65536,
164
+ },
165
+ "gemini-3.8-flash-tiered": {
166
+ modelEnum: "MODEL_PLACEHOLDER_M322",
167
+ maxOutputTokens: 65536,
168
+ },
169
+ // GPT-OSS via Antigravity (verified live).
170
+ "gpt-oss-120b-medium": {
171
+ modelEnum: "MODEL_OPENAI_GPT_OSS_120B_MEDIUM",
172
+ maxOutputTokens: 32768,
173
+ },
174
+ // Tab (laptop-class) preview SKU.
175
+ "tab_flash_lite_preview": {
176
+ modelEnum: "MODEL_PLACEHOLDER_M19",
177
+ maxOutputTokens: 4096,
178
+ },
125
179
  });
126
180
 
127
181
  export function getAntigravityModelWireProfile(
@@ -398,6 +452,7 @@ export async function discoverAntigravityModels(
398
452
  readonly baseUrl?: string;
399
453
  readonly fetcher?: typeof fetch;
400
454
  readonly signal?: AbortSignal;
455
+ readonly projectId?: string;
401
456
  } = {},
402
457
  ): Promise<readonly ModelDefinition[] | null> {
403
458
  const fetcher = options.fetcher ?? fetch;
@@ -419,7 +474,10 @@ export async function discoverAntigravityModels(
419
474
  "content-type": "application/json",
420
475
  "user-agent": getAntigravityUserAgent(),
421
476
  },
422
- body: "{}",
477
+ // The reference client always sends the resolved project
478
+ // (`cloudCodeMainService.js`); the live backend accepts both, but the
479
+ // project is required for billing-gated endpoints.
480
+ body: JSON.stringify(options.projectId === undefined ? {} : { project: options.projectId }),
423
481
  signal,
424
482
  });
425
483
  if (!response.ok) continue;
@@ -427,7 +485,25 @@ export async function discoverAntigravityModels(
427
485
  (await response.json()) as unknown,
428
486
  );
429
487
  if (models === null) continue;
430
- return models;
488
+ // Keep the static websearch row on top of discovered rows: the live
489
+ // catalog does not publish search SKUs, and `/v1/search` needs a
490
+ // `service_kind: "websearch"` row to route.
491
+ return [
492
+ ...models,
493
+ defineModel({
494
+ id: "gemini-2.5-flash",
495
+ providerId: "antigravity",
496
+ serviceKind: "websearch",
497
+ wireFamily: "chat",
498
+ // Empty endpoint — see `ANTIGRAVITY_SEARCH_MODELS`.
499
+ endpoint: "",
500
+ ctx: 1_000_000,
501
+ out: 65_535,
502
+ vision: true,
503
+ reasoning: true,
504
+ toolCall: false,
505
+ }),
506
+ ];
431
507
  } catch {
432
508
  // Best-effort: a failed live catalog must never break static routing.
433
509
  }
@@ -489,9 +565,16 @@ export function applySkipThoughtSignatureBypass(
489
565
  * Sending the Gemini shape makes the backend treat the call as a different
490
566
  * client and refuse to enroll the account, which the operator sees as
491
567
  * "You do not have a valid license of this product".
568
+ *
569
+ * The reference client (`cloudCodeMainService.js`) sends the full product
570
+ * identity: `ideName`, `ideType`, and `ideVersion`. `ideType` alone was
571
+ * accepted live, but the full shape is the captured wire and avoids any
572
+ * client-class gating on the control plane.
492
573
  */
493
574
  export const ANTIGRAVITY_LOAD_CODE_ASSIST_METADATA = Object.freeze({
575
+ ideName: "antigravity",
494
576
  ideType: "ANTIGRAVITY",
577
+ ideVersion: getAntigravityVersion(),
495
578
  });
496
579
 
497
580
  const projectIdCache = new Map<string, string>();
@@ -570,7 +653,9 @@ const FREE_TIER_ID = "free-tier";
570
653
  const ONBOARD_USER_PATH = "/v1internal:onboardUser";
571
654
  const ONBOARD_OPERATIONS_PATH = "/v1internal";
572
655
  const ONBOARD_TIMEOUT_MS = 30_000;
573
- const ONBOARD_POLL_INTERVAL_MS = 1_000;
656
+ // Reference client (`cloudCodeMainService.js`) polls the operation every
657
+ // 500ms (`gXa = 500`).
658
+ const ONBOARD_POLL_INTERVAL_MS = 500;
574
659
 
575
660
  /** Thrown when an account cannot be enrolled in the Antigravity free tier. */
576
661
  export class AntigravityProvisioningError extends Error {
@@ -699,6 +784,9 @@ async function onboardUser(
699
784
  if (left <= 0) throw new AntigravityProvisioningError("onboardUser timed out");
700
785
  return left;
701
786
  };
787
+ const projectId = extractProjectId(
788
+ await loadCodeAssist(fetcher, base, accessToken, signal),
789
+ );
702
790
  let operation = await cloudCodeAssistCall(
703
791
  fetcher,
704
792
  base,
@@ -706,7 +794,11 @@ async function onboardUser(
706
794
  ONBOARD_USER_PATH,
707
795
  {
708
796
  method: "POST",
709
- body: { tierId: FREE_TIER_ID, metadata: ANTIGRAVITY_LOAD_CODE_ASSIST_METADATA },
797
+ body: {
798
+ tierId: FREE_TIER_ID,
799
+ ...(projectId === undefined ? {} : { cloudaicompanionProject: projectId }),
800
+ metadata: ANTIGRAVITY_LOAD_CODE_ASSIST_METADATA,
801
+ },
710
802
  },
711
803
  signal,
712
804
  );
@@ -118,9 +118,6 @@ function keepWorse(
118
118
  return candidateRemaining < currentRemaining ? candidate : current;
119
119
  }
120
120
 
121
- /** Total the upstream's fractional allowance is normalized against. */
122
- const QUOTA_TOTAL = 1000;
123
-
124
121
  /** Builds a window from a `remainingFraction` + `resetTime` pair. */
125
122
  function fractionWindow(
126
123
  kind: string,
@@ -129,9 +126,8 @@ function fractionWindow(
129
126
  resetsAt: string | null,
130
127
  ): ProviderQuotaWindow {
131
128
  const fraction = Math.min(1, Math.max(0, remainingFraction));
132
- const used = QUOTA_TOTAL - Math.round(QUOTA_TOTAL * fraction);
133
129
  return {
134
- ...percentWindow(kind, label, (1 - fraction) * 100, resetsAt, used, QUOTA_TOTAL, "independent"),
130
+ ...percentWindow(kind, label, (1 - fraction) * 100, resetsAt, null, null, "independent"),
135
131
  recurring: true,
136
132
  };
137
133
  }
@@ -316,7 +312,23 @@ export async function fetchAntigravityQuota(
316
312
  ...(project === undefined ? {} : { project }),
317
313
  }),
318
314
  );
319
- windows.push(...parseModelQuotas(models));
315
+ // The summary endpoint already covers a family with a weekly window; the
316
+ // per-model windows are a subset of that same allowance, so rendering
317
+ // both doubles every row the operator sees. Per-model windows stay as a
318
+ // fallback when the summary was unavailable, so a family still reports
319
+ // something.
320
+ const summaryLabels = windows.map((window) => window.label.toLowerCase());
321
+ // Model family key → the summary family label it falls under.
322
+ const summaryLabelForModel = (key: string): string =>
323
+ key === "google" ? "gemini" : "claude";
324
+ const modelWindows = parseModelQuotas(models);
325
+ windows.push(
326
+ ...modelWindows.filter((window) => {
327
+ const familyKey = window.kind.split(":")[0] ?? "";
328
+ const summaryLabel = summaryLabelForModel(familyKey);
329
+ return !summaryLabels.some((label) => label.includes(summaryLabel));
330
+ }),
331
+ );
320
332
  plan = plan ?? text(models.tier) ?? text(models.plan);
321
333
  break;
322
334
  } catch {
@@ -94,22 +94,50 @@ export const ANTIGRAVITY_MODELS: readonly ModelDefinition[] = [
94
94
  antigravityModel("claude-opus-4-6", 250_000, 64_000, true),
95
95
  antigravityModel("claude-sonnet-5-5", 1_000_000, 128_000, true),
96
96
  antigravityModel("claude-opus-5-5", 1_000_000, 128_000, true),
97
- // Gemini text SKUs, as the Antigravity roster publishes them.
98
- antigravityModel("gemini-2.5-flash", 1_000_000, 66_000, true),
99
- antigravityModel("gemini-2.5-flash-thinking", 1_000_000, 66_000, true),
100
- antigravityModel("gemini-3-flash", 1_000_000, 66_000, true),
101
- antigravityModel("gemini-3.1-flash-lite", 1_000_000, 66_000, true),
102
- antigravityModel("gemini-2.5-flash-lite", 1_000_000, 66_000, true),
103
- antigravityModel("gemini-3.5-flash-lite", 1_000_000, 66_000, true),
104
- antigravityModel("gemini-3.8-flash", 1_000_000, 66_000, true),
97
+ // Gemini text SKUs, as the Antigravity roster publishes them (verified live
98
+ // 2026-11-03): Gemini SKUs ceiling at 65535/65536 output tokens.
99
+ antigravityModel("gemini-2.5-flash", 1_000_000, 65_535, true),
100
+ antigravityModel("gemini-2.5-flash-thinking", 1_000_000, 65_535, true),
101
+ antigravityModel("gemini-2.5-flash-lite", 1_000_000, 65_535, true),
102
+ antigravityModel("gemini-2.5-pro", 1_000_000, 65_535, true),
103
+ antigravityModel("gemini-3-flash", 1_000_000, 65_536, true),
104
+ antigravityModel("gemini-3.1-flash-lite", 1_000_000, 65_535, true),
105
+ antigravityModel("gemini-3.5-flash-lite", 1_000_000, 65_535, true),
106
+ antigravityModel("gemini-3.8-flash", 1_000_000, 65_536, true),
105
107
  antigravityModel("gemini-4-argon", 1_000_000, 65_536, true),
106
108
  antigravityModel("gemini-4-carbon", 1_000_000, 65_536, true),
107
109
  // Tab (laptop-class) preview SKU.
108
110
  antigravityModel("tab_flash_lite_preview", 16_000, 4_000, true),
109
111
  // Gemini image generation. `gemini-3-pro-image` uses the same catalog
110
112
  // limits/capabilities as the existing `gemini-3.1-flash-image` row.
111
- antigravityModel("gemini-3.1-flash-image", 200_000, 64_000, false, true),
112
- antigravityModel("gemini-3-pro-image", 200_000, 64_000, false, true),
113
+ antigravityModel("gemini-3.1-flash-image", 65_536, 65_536, false, true),
114
+ antigravityModel("gemini-3-pro-image", 65_536, 65_536, false, true),
115
+ // GPT-OSS via Antigravity (verified live 2026-11-03).
116
+ antigravityModel("gpt-oss-120b", 131_072, 32_768, true),
117
+ ];
118
+
119
+ /**
120
+ * Web-search rows served by `/v1/search`. Antigravity grounds search through a
121
+ * Gemini chat call with a `web_search` tool (see `websearch`); the cheap flash
122
+ * SKU is the default search model.
123
+ */
124
+ export const ANTIGRAVITY_SEARCH_MODELS: readonly ModelDefinition[] = [
125
+ defineModel({
126
+ id: "gemini-2.5-flash",
127
+ providerId: "antigravity",
128
+ serviceKind: "websearch",
129
+ wireFamily: "chat",
130
+ // Empty endpoint: the adapter resolves the URL from the request stream flag
131
+ // (`GENERATE_PATH`), so the row only needs to exist as a websearch route.
132
+ // An empty value also keeps it distinct from the llm row (the unique key is
133
+ // provider+model+endpoint).
134
+ endpoint: "",
135
+ ctx: 1_000_000,
136
+ out: 65_535,
137
+ vision: true,
138
+ reasoning: true,
139
+ toolCall: false,
140
+ }),
113
141
  ];
114
142
 
115
143
  function normalizeAntigravityGrounding(data: unknown, maxResults: number): readonly WebSearchResult[] {
@@ -777,8 +805,13 @@ function antigravityThinkingBudget(modelId: string): number | undefined {
777
805
  return modelId.includes("3.1-pro") ? 10_001 : 10_000;
778
806
  }
779
807
 
808
+ // Original reference instruction (captured from the Antigravity client):
809
+ // "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Absolute paths only****Proactiveness**"
810
+ // Generalized to a neutral identity so the gateway does not impersonate the
811
+ // vendor's branded assistant. The brand-specific wording is kept above for
812
+ // reference; re-enable it if an upstream behavior ever depends on it.
780
813
  const ANTIGRAVITY_SYSTEM_INSTRUCTION =
781
- "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Absolute paths only****Proactiveness**";
814
+ "You are a helpful assistant.";
782
815
 
783
816
  /**
784
817
  * Restatement appended as a trailing user turn when a Gemini route carries a
@@ -145,6 +145,30 @@ export const CODEX_MODELS: readonly ModelDefinition[] = [
145
145
  ];
146
146
  const CODEX_SEARCH_DEFAULT_MODEL = "gpt-5.6-luna";
147
147
 
148
+ /**
149
+ * Web-search rows served by `/v1/search`. Codex grounds search through a
150
+ * Responses call with a `web_search` tool (see `websearch`); the cheap 5.6
151
+ * SKU is the default search model.
152
+ */
153
+ export const CODEX_SEARCH_MODELS: readonly ModelDefinition[] = [
154
+ defineModel({
155
+ id: "gpt-5.6-luna",
156
+ providerId: "codex",
157
+ serviceKind: "websearch",
158
+ wireFamily: "responses",
159
+ // Empty endpoint: the adapter falls back to
160
+ // `/backend-api/codex/responses` when the candidate path is empty (see
161
+ // `dispatch`), and an empty value keeps the row distinct from the llm row
162
+ // in the (provider, model, endpoint) unique key.
163
+ endpoint: "",
164
+ ctx: 1_000_000,
165
+ out: 128_000,
166
+ vision: true,
167
+ reasoning: true,
168
+ toolCall: false,
169
+ }),
170
+ ];
171
+
148
172
  function normalizeCodexSearchCitations(
149
173
  citations: readonly unknown[],
150
174
  answerText: string,
@@ -528,7 +552,10 @@ export async function discoverCodexModels(input: {
528
552
  ),
529
553
  );
530
554
  }
531
- return [...byId.values()].sort((a, b) => a.modelId.localeCompare(b.modelId));
555
+ // Keep the static websearch rows on top of discovered llm rows: the codex
556
+ // registry does not publish search SKUs, and `/v1/search` needs a
557
+ // `service_kind: "websearch"` row to route.
558
+ return [...byId.values(), ...CODEX_SEARCH_MODELS].sort((a, b) => a.modelId.localeCompare(b.modelId));
532
559
  }
533
560
 
534
561
  /** Reads just enough of an untyped body to tell SSE from JSON, then replays it. */
@@ -27,7 +27,6 @@ import type {
27
27
  } from "../../../protocol/canonical-model";
28
28
  import { resolveImageSource, splitDataUrl } from "../../../protocol/codecs";
29
29
  import { IMAGE_CLAMP_MAX_BYTES } from "../../../protocol/image-clamp";
30
- import { applyCacheMode } from "../../provider-usage";
31
30
  import type { ProviderAdapter, ProviderDispatchContext, ProviderDispatchTarget } from "../../provider-contracts";
32
31
  import { readCredentialSecret } from "../../provider-contracts";
33
32
  import type { Http2BidiEndReason, ValidatedHttp2BidiStream } from "../../../network/http2-bidi";
@@ -281,7 +280,7 @@ function usageFromTurnEnded(turnEnded: Record<string, unknown>): UsageRecord {
281
280
  const input = count(turnEnded["input_tokens"]);
282
281
  const output = count(turnEnded["output_tokens"]);
283
282
  const cacheRead = count(turnEnded["cache_read"]);
284
- return applyCacheMode({
283
+ return {
285
284
  input_tokens: input,
286
285
  cached_input_tokens: cacheRead,
287
286
  cache_write_tokens: count(turnEnded["cache_write"]),
@@ -290,7 +289,7 @@ function usageFromTurnEnded(turnEnded: Record<string, unknown>): UsageRecord {
290
289
  reasoning_tokens: count(turnEnded["reasoning_tokens"]),
291
290
  estimated_cost: null,
292
291
  total_tokens: input + output,
293
- });
292
+ };
294
293
  }
295
294
 
296
295
  function nonEmptyStringOf(value: unknown): string | undefined {