cartethyia 2.5.10 → 2.6.0

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 (367) hide show
  1. package/.env.example +8 -0
  2. package/dist/dashboard/assets/{BannedPage-Cd30Z0b9.js → BannedPage-l6XMnfr9.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-l6XMnfr9.js.gz +0 -0
  4. package/dist/dashboard/assets/{CliToolDetailPage-wf5u-ww6.js → CliToolDetailPage-DwOzAW45.js} +1 -1
  5. package/dist/dashboard/assets/CliToolDetailPage-DwOzAW45.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolsPage-DykPvuck.js → CliToolsPage-BT3Up3QA.js} +1 -1
  7. package/dist/dashboard/assets/CliToolsPage-BT3Up3QA.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-DwvSD3vs.js → CombosPage-6kYIUpzR.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-6kYIUpzR.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-CIr7KDex.js → ConsoleLogPage-zRnj1mlR.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-zRnj1mlR.js.gz +0 -0
  12. package/dist/dashboard/assets/{CustomizationPage-82X0DDdH.js → CustomizationPage-C7m-H1Rz.js} +1 -1
  13. package/dist/dashboard/assets/CustomizationPage-C7m-H1Rz.js.gz +0 -0
  14. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js +1 -0
  15. package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js.gz +0 -0
  16. package/dist/dashboard/assets/{LoginPage-CS5mPuVF.js → LoginPage-CbphLvjg.js} +1 -1
  17. package/dist/dashboard/assets/LoginPage-CbphLvjg.js.gz +0 -0
  18. package/dist/dashboard/assets/{ModelPicker-C0UCUsVJ.js → ModelPicker-DVny4S5_.js} +1 -1
  19. package/dist/dashboard/assets/ModelPicker-DVny4S5_.js.gz +0 -0
  20. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js +1 -0
  21. package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js.gz +0 -0
  22. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js +3 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js.gz +0 -0
  24. package/dist/dashboard/assets/{ProvidersPage-vdja5ZPK.js → ProvidersPage-Dfb2896L.js} +1 -1
  25. package/dist/dashboard/assets/ProvidersPage-Dfb2896L.js.gz +0 -0
  26. package/dist/dashboard/assets/{ProxyPage-BB4CNm4-.js → ProxyPage-BaCIdAUt.js} +1 -1
  27. package/dist/dashboard/assets/ProxyPage-BaCIdAUt.js.gz +0 -0
  28. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js +1 -0
  29. package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js.gz +0 -0
  30. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js +1 -0
  31. package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js.gz +0 -0
  32. package/dist/dashboard/assets/{SetupPage-FadUOl9S.js → SetupPage-D4g6vOGc.js} +1 -1
  33. package/dist/dashboard/assets/SetupPage-D4g6vOGc.js.gz +0 -0
  34. package/dist/dashboard/assets/{SortableList-Cfy6_Khv.js → SortableList-C93i14BD.js} +1 -1
  35. package/dist/dashboard/assets/SortableList-C93i14BD.js.gz +0 -0
  36. package/dist/dashboard/assets/{StudioPage-CM92fgJf.js → StudioPage-SgQpymjm.js} +1 -1
  37. package/dist/dashboard/assets/{StudioPage-CM92fgJf.js.gz → StudioPage-SgQpymjm.js.gz} +0 -0
  38. package/dist/dashboard/assets/{UsagePage-BT4MyQeT.js → UsagePage-BFME-eba.js} +2 -2
  39. package/dist/dashboard/assets/UsagePage-BFME-eba.js.gz +0 -0
  40. package/dist/dashboard/assets/{api-keys-DQYLQxpW.js → api-keys-C23S9sgp.js} +1 -1
  41. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  42. package/dist/dashboard/assets/{app-B7pVRhJ1.js → app-2KhtHCv9.js} +1 -1
  43. package/dist/dashboard/assets/{app-B7pVRhJ1.js.gz → app-2KhtHCv9.js.gz} +0 -0
  44. package/dist/dashboard/assets/app-CEeaMHOy.css +2 -0
  45. package/dist/dashboard/assets/app-CEeaMHOy.css.gz +0 -0
  46. package/dist/dashboard/assets/{assert-C9FD_JwJ.js → assert-DU6qrMA_.js} +1 -1
  47. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-Bvyr7D0u.js → badge-CKsF123d.js} +1 -1
  49. package/dist/dashboard/assets/badge-CKsF123d.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-DIvKAZih.js → banner-8j7uChA9.js} +1 -1
  51. package/dist/dashboard/assets/banner-8j7uChA9.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-D5_gYIS_.js → card-CdsSlWA3.js} +1 -1
  53. package/dist/dashboard/assets/card-CdsSlWA3.js.gz +0 -0
  54. package/dist/dashboard/assets/{cli-tools-CNqzrfdb.js → cli-tools-BaFUuFFF.js} +1 -1
  55. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-B6vDBtbm.js → clipboard-button-uL5aYLfW.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-uL5aYLfW.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-CpjrgdwJ.js → dialog-C07hr5_G.js} +1 -1
  59. package/dist/dashboard/assets/dialog-C07hr5_G.js.gz +0 -0
  60. package/dist/dashboard/assets/{drawer-BWmt3b5y.js → drawer-BPO1TcKH.js} +1 -1
  61. package/dist/dashboard/assets/drawer-BPO1TcKH.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-C_oakV3z.js → entry-Bz_CtDfC.js} +1 -1
  63. package/dist/dashboard/assets/entry-Bz_CtDfC.js.gz +0 -0
  64. package/dist/dashboard/assets/entry-CwPRKk0d.js +4 -0
  65. package/dist/dashboard/assets/entry-CwPRKk0d.js.gz +0 -0
  66. package/dist/dashboard/assets/entry-GJRbmrpA.js +1 -0
  67. package/dist/dashboard/assets/entry-GJRbmrpA.js.gz +0 -0
  68. package/dist/dashboard/assets/{github-badge-RRHHWGxh.js → github-badge-DmQreSDd.js} +1 -1
  69. package/dist/dashboard/assets/github-badge-DmQreSDd.js.gz +0 -0
  70. package/dist/dashboard/assets/{index-Bhey_rg_.js → index-Bblu6erR.js} +2 -2
  71. package/dist/dashboard/assets/index-Bblu6erR.js.gz +0 -0
  72. package/dist/dashboard/assets/{inline-C2_EQ5Uf.js → inline-C9dCYaBZ.js} +1 -1
  73. package/dist/dashboard/assets/inline-C9dCYaBZ.js.gz +0 -0
  74. package/dist/dashboard/assets/{input-BMRlQ450.js → input-CjCnXweJ.js} +1 -1
  75. package/dist/dashboard/assets/input-CjCnXweJ.js.gz +0 -0
  76. package/dist/dashboard/assets/{layout-XR5xP8ew.js → layout-V6y8DAkl.js} +1 -1
  77. package/dist/dashboard/assets/layout-V6y8DAkl.js.gz +0 -0
  78. package/dist/dashboard/assets/{list-row-Cw07dioc.js → list-row-CM1AaG_y.js} +1 -1
  79. package/dist/dashboard/assets/list-row-CM1AaG_y.js.gz +0 -0
  80. package/dist/dashboard/assets/{live-BivGfuUs.js → live-ta6GMb-8.js} +1 -1
  81. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  82. package/dist/dashboard/assets/{model-bans-CmffjLuG.js → model-bans-BmYTmbAk.js} +1 -1
  83. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  84. package/dist/dashboard/assets/{mutation-46P0oWMe.js → mutation-g_fduiNw.js} +1 -1
  85. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  86. package/dist/dashboard/assets/{numbers-DrdA9oSM.js → numbers-BOevJzdz.js} +1 -1
  87. package/dist/dashboard/assets/numbers-BOevJzdz.js.gz +0 -0
  88. package/dist/dashboard/assets/{query-keys-BFhGpwR1.js → query-keys-UETqfytp.js} +1 -1
  89. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  90. package/dist/dashboard/assets/{routing-CAb4F37R.js → routing-BPUo-W8d.js} +1 -1
  91. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  92. package/dist/dashboard/assets/{select-CxVVB__N.js → select-C980c4cz.js} +1 -1
  93. package/dist/dashboard/assets/select-C980c4cz.js.gz +0 -0
  94. package/dist/dashboard/assets/{settings-DNX9sydi.js → settings--3hxSyry.js} +1 -1
  95. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  96. package/dist/dashboard/assets/{stack-uPOwM9Hs.js → stack-_gfTdLVB.js} +1 -1
  97. package/dist/dashboard/assets/stack-_gfTdLVB.js.gz +0 -0
  98. package/dist/dashboard/assets/{state-D1Yz79iL.js → state-2c5V4zo7.js} +1 -1
  99. package/dist/dashboard/assets/state-2c5V4zo7.js.gz +0 -0
  100. package/dist/dashboard/assets/{switch-sevsRrRo.js → switch-Dkke7Naf.js} +1 -1
  101. package/dist/dashboard/assets/switch-Dkke7Naf.js.gz +0 -0
  102. package/dist/dashboard/assets/{useMutation-Dem0lXQj.js → useMutation-EDFRkn1i.js} +1 -1
  103. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  104. package/dist/dashboard/index.html +1 -1
  105. package/dist/dashboard/index.html.gz +0 -0
  106. package/dist/dashboard/precompressed-assets.json +51 -51
  107. package/migrations/README.md +52 -52
  108. package/migrations/full-postgres/0020_add_telemetry_event_analytics.sql +77 -0
  109. package/migrations/full-postgres/0021_add_api_key_concurrency_tolerance.sql +13 -0
  110. package/migrations/full-postgres/0022_add_inferhub_config_key.sql +17 -0
  111. package/migrations/full-postgres/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  112. package/migrations/lite-sqlite3/0020_add_telemetry_event_analytics.sql +69 -0
  113. package/migrations/lite-sqlite3/0021_add_api_key_concurrency_tolerance.sql +13 -0
  114. package/migrations/lite-sqlite3/0022_add_inferhub_config_key.sql +17 -0
  115. package/migrations/lite-sqlite3/0023_drop_api_key_concurrency_tolerance.sql +13 -0
  116. package/package.json +96 -95
  117. package/scripts/cli/admin.ts +126 -128
  118. package/scripts/cli/autostart.ts +237 -237
  119. package/scripts/cli/background.ts +120 -110
  120. package/scripts/cli/bin/carte.cjs +8 -8
  121. package/scripts/cli/bin/cartethyia.cjs +167 -167
  122. package/scripts/cli/console-menu.ts +39 -30
  123. package/scripts/cli/controller.ts +145 -0
  124. package/scripts/cli/env.ts +99 -99
  125. package/scripts/cli/gateway.ts +264 -260
  126. package/scripts/cli/instance.ts +234 -224
  127. package/scripts/cli/main.ts +188 -167
  128. package/scripts/cli/platform.ts +64 -64
  129. package/scripts/cli/prompt.ts +217 -79
  130. package/scripts/cli/services.ts +88 -88
  131. package/scripts/cli/setup.ts +445 -445
  132. package/scripts/cli/start.ts +85 -85
  133. package/scripts/cli/startup-signal.ts +23 -23
  134. package/scripts/cli/telemetry.ts +70 -0
  135. package/scripts/cli/tray/index.ts +263 -263
  136. package/scripts/cli/tray/windows.ps1 +107 -107
  137. package/scripts/cli/tray.ts +29 -4
  138. package/scripts/cli/update.ts +39 -39
  139. package/scripts/cli/version.ts +67 -67
  140. package/scripts/cli/wordmark.ts +58 -58
  141. package/src/boot/app.ts +16 -1
  142. package/src/boot/dependencies.ts +128 -25
  143. package/src/config/resources.ts +137 -0
  144. package/src/config/runtime.ts +133 -76
  145. package/src/config/spec.ts +30 -29
  146. package/src/config/telemetry.ts +0 -25
  147. package/src/console/api-keys/bucket-spend.ts +14 -17
  148. package/src/console/api-keys/contracts.ts +410 -410
  149. package/src/console/api-keys/routes.ts +12 -0
  150. package/src/console/audit/store.ts +2 -3
  151. package/src/console/auth/setup-service.ts +8 -1
  152. package/src/console/backup/routes.ts +7 -0
  153. package/src/console/backup/service.ts +463 -463
  154. package/src/console/backup/store.ts +16 -11
  155. package/src/console/backup/validate.ts +1 -4
  156. package/src/console/cli-tools/fs-ops.ts +18 -2
  157. package/src/console/data-management/contracts.ts +1 -8
  158. package/src/console/data-management/operations.ts +61 -48
  159. package/src/console/data-management/routes.ts +4 -2
  160. package/src/console/domain-registration.ts +25 -3
  161. package/src/console/inferhub/client.ts +139 -0
  162. package/src/console/inferhub/key-store.ts +129 -0
  163. package/src/console/inferhub/normalize.ts +347 -0
  164. package/src/console/inferhub/routes.ts +411 -0
  165. package/src/console/inferhub/store.ts +109 -0
  166. package/src/console/inferhub/types.ts +183 -0
  167. package/src/console/observability/contracts.ts +2 -41
  168. package/src/console/observability/store.ts +176 -371
  169. package/src/console/providers/catalog/public-model-store.ts +0 -0
  170. package/src/console/providers/catalog/store.ts +23 -36
  171. package/src/console/quota/account-quota-shared.ts +52 -52
  172. package/src/console/quota/account-quota-tenant.ts +16 -24
  173. package/src/console/quota/refresh.ts +441 -441
  174. package/src/console/routing/pools/import-parse.ts +206 -206
  175. package/src/console/routing/pools/operations.ts +543 -543
  176. package/src/console/routing/pools/probe-verdict.ts +132 -132
  177. package/src/console/routing/pools/routes.ts +181 -181
  178. package/src/console/settings/contracts.ts +42 -40
  179. package/src/console/settings/store.ts +25 -25
  180. package/src/console/share/share-stats.ts +22 -4
  181. package/src/console/share/share-usage.ts +30 -4
  182. package/src/console/shared/cursor.ts +15 -0
  183. package/src/console/updates/routes.ts +12 -0
  184. package/src/main.ts +13 -5
  185. package/src/network/pool/resolver.ts +1104 -1104
  186. package/src/observability/client-name.ts +22 -0
  187. package/src/observability/event-log.ts +5 -29
  188. package/src/observability/event-query.ts +690 -0
  189. package/src/observability/log-ring.ts +26 -2
  190. package/src/observability/log-sanitize.ts +118 -0
  191. package/src/observability/logger.ts +17 -13
  192. package/src/observability/metrics.ts +35 -0
  193. package/src/observability/payload-capture.ts +114 -41
  194. package/src/observability/payload-store.ts +249 -24
  195. package/src/observability/raw-event-writer.ts +118 -0
  196. package/src/observability/runtime-metrics.ts +71 -1
  197. package/src/observability/telemetry-buffer.ts +100 -17
  198. package/src/observability/telemetry-reconciliation.ts +417 -0
  199. package/src/persistence/boot.ts +20 -9
  200. package/src/persistence/db-pg.ts +13 -0
  201. package/src/persistence/db-sqlite.ts +569 -497
  202. package/src/persistence/dialect.ts +3 -2
  203. package/src/persistence/migrate.ts +181 -181
  204. package/src/persistence/schema.ts +1496 -1406
  205. package/src/persistence/shared-cache.ts +5 -1
  206. package/src/persistence/stores/api-key-store.ts +581 -581
  207. package/src/persistence/stores/telemetry-store.ts +124 -63
  208. package/src/protocol/reasoning-text.ts +30 -0
  209. package/src/protocol/response/chat.ts +33 -7
  210. package/src/protocol/response/codex.ts +14 -2
  211. package/src/protocol/response/messages.ts +5 -2
  212. package/src/providers/authentication/oauth-flow-store.ts +3 -10
  213. package/src/providers/bundled-discovery-providers.ts +122 -122
  214. package/src/providers/default-registry.ts +10 -0
  215. package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
  216. package/src/providers/discovery/models-dev-catalog.ts +354 -354
  217. package/src/providers/discovery/probe-phases.ts +43 -7
  218. package/src/providers/discovery/probing-service.ts +70 -32
  219. package/src/providers/integrations/antigravity/antigravity.ts +9 -2
  220. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +85 -17
  221. package/src/providers/integrations/buddy/buddy-chat-shared.ts +934 -934
  222. package/src/providers/integrations/buddy/buddy-checkin.ts +5 -9
  223. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +3 -7
  224. package/src/providers/integrations/buddy/buddy-quota-shared.ts +3 -1
  225. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +57 -49
  226. package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -180
  227. package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -206
  228. package/src/providers/integrations/buddy/workbuddy/quota.ts +161 -161
  229. package/src/providers/integrations/claude/claude-quota.ts +2 -2
  230. package/src/providers/integrations/claude/claude-user-profiles.ts +3 -2
  231. package/src/providers/integrations/claude/claude.ts +3 -4
  232. package/src/providers/integrations/cline/cline.ts +94 -8
  233. package/src/providers/integrations/codex/codex.ts +61 -37
  234. package/src/providers/integrations/cursor/cursor-catalog.ts +368 -368
  235. package/src/providers/integrations/cursor/cursor-http2.ts +300 -300
  236. package/src/providers/integrations/cursor/cursor-identity.ts +2 -4
  237. package/src/providers/integrations/cursor/cursor-request.ts +11 -0
  238. package/src/providers/integrations/cursor/cursor.ts +29 -17
  239. package/src/providers/integrations/cursor/protocol/framing.ts +129 -129
  240. package/src/providers/integrations/cursor/protocol/messages.ts +2380 -2380
  241. package/src/providers/integrations/cursor/protocol/struct.ts +305 -305
  242. package/src/providers/integrations/cursor/protocol/tool-canonical.ts +275 -0
  243. package/src/providers/integrations/grok/grok-quota.ts +279 -279
  244. package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -73
  245. package/src/providers/integrations/grok/grok-ratelimit.ts +218 -218
  246. package/src/providers/integrations/hermes.ts +7 -1
  247. package/src/providers/integrations/inferhub.ts +201 -73
  248. package/src/providers/integrations/kilo/kilo.ts +152 -152
  249. package/src/providers/integrations/kiro/kiro-machine-id.ts +2 -4
  250. package/src/providers/integrations/openrouter/provider.ts +129 -129
  251. package/src/providers/integrations/qoder/qoder-quota.ts +193 -192
  252. package/src/providers/integrations/qoder/qoder-realm.ts +106 -106
  253. package/src/providers/integrations/trae/trae-oauth.ts +4 -26
  254. package/src/providers/integrations/trae/trae-quota.ts +389 -384
  255. package/src/providers/integrations/trae/trae-realm.ts +15 -2
  256. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +100 -24
  257. package/src/providers/integrations/zcode/oauth.ts +1 -1
  258. package/src/providers/operations/account-health-service.ts +605 -279
  259. package/src/providers/provider-metadata.ts +12 -1
  260. package/src/providers/provider-model-definition.ts +373 -373
  261. package/src/providers/quota/quota-contracts.ts +3 -7
  262. package/src/providers/search/search-provider.ts +2 -6
  263. package/src/security/admission/contracts.ts +10 -0
  264. package/src/security/admission/in-memory-store.ts +89 -14
  265. package/src/security/admission/lua.ts +191 -182
  266. package/src/security/admission/redis-store.ts +30 -0
  267. package/src/security/admission/service.ts +18 -0
  268. package/src/security/api-key-auth-cache.ts +96 -0
  269. package/src/security/api-key-auth.ts +11 -100
  270. package/src/security/client-router-fingerprint.ts +3 -7
  271. package/src/security/ip-boundary.ts +7 -3
  272. package/src/shared/coerce.ts +67 -0
  273. package/src/shared/hash.ts +6 -0
  274. package/src/shared/time.ts +7 -0
  275. package/src/transport/dispatch/attempt-finalize.ts +26 -138
  276. package/src/transport/dispatch/attempt-loop.ts +103 -81
  277. package/src/transport/dispatch/capture-policy.ts +78 -0
  278. package/src/transport/dispatch/proxy-request.ts +4 -2
  279. package/src/transport/dispatch/streaming/encoder.ts +111 -5
  280. package/src/transport/dispatch/streaming/stream.ts +19 -2
  281. package/src/transport/dispatch/streaming/thinking-loop.ts +300 -0
  282. package/src/transport/failure-policy.ts +27 -0
  283. package/src/transport/guards/abuse-guard.ts +2 -2
  284. package/src/transport/guards/auth-guard.ts +17 -0
  285. package/src/transport/guards/body-policy.ts +3 -2
  286. package/src/transport/guards/concurrency-guard.ts +89 -13
  287. package/src/transport/guards/early-rejection-capture.ts +43 -3
  288. package/src/transport/guards/error-lifecycle.ts +10 -2
  289. package/src/transport/guards/guard-errors.ts +23 -0
  290. package/src/transport/guards/headroom-guard.ts +41 -7
  291. package/src/transport/guards/pipeline.ts +24 -0
  292. package/src/transport/guards/request-context.ts +2 -1
  293. package/src/transport/routing/admission.ts +51 -9
  294. package/src/transport/routing/bounded-lru.ts +49 -0
  295. package/src/transport/routing/candidate-index.ts +88 -0
  296. package/src/transport/routing/reservations.ts +121 -7
  297. package/src/transport/routing/round-robin.ts +10 -22
  298. package/src/transport/routing/route-catalog.ts +26 -13
  299. package/src/transport/routing/route-model.ts +22 -2
  300. package/src/transport/routing/router.ts +53 -31
  301. package/src/transport/surface/chat/encode.ts +2 -3
  302. package/src/transport/surface/chat/parse.ts +2 -1
  303. package/src/transport/surface/dialects.ts +11 -3
  304. package/src/transport/surface/messages/encode.ts +2 -1
  305. package/src/transport/surface/messages/parse.ts +3 -1
  306. package/src/transport/surface/messages/stream.ts +2 -6
  307. package/src/workers/maintenance-lease.ts +200 -0
  308. package/src/workers/scheduler.ts +101 -1
  309. package/dist/dashboard/assets/BannedPage-Cd30Z0b9.js.gz +0 -0
  310. package/dist/dashboard/assets/CliToolDetailPage-wf5u-ww6.js.gz +0 -0
  311. package/dist/dashboard/assets/CliToolsPage-DykPvuck.js.gz +0 -0
  312. package/dist/dashboard/assets/CombosPage-DwvSD3vs.js.gz +0 -0
  313. package/dist/dashboard/assets/ConsoleLogPage-CIr7KDex.js.gz +0 -0
  314. package/dist/dashboard/assets/CustomizationPage-82X0DDdH.js.gz +0 -0
  315. package/dist/dashboard/assets/HealthEventsModal-BYPucTTn.js +0 -1
  316. package/dist/dashboard/assets/HealthEventsModal-BYPucTTn.js.gz +0 -0
  317. package/dist/dashboard/assets/LoginPage-CS5mPuVF.js.gz +0 -0
  318. package/dist/dashboard/assets/ModelPicker-C0UCUsVJ.js.gz +0 -0
  319. package/dist/dashboard/assets/OverviewPage-Dk_ew3YU.js +0 -1
  320. package/dist/dashboard/assets/OverviewPage-Dk_ew3YU.js.gz +0 -0
  321. package/dist/dashboard/assets/ProviderDetailPage-CAiRn2Q0.js +0 -3
  322. package/dist/dashboard/assets/ProviderDetailPage-CAiRn2Q0.js.gz +0 -0
  323. package/dist/dashboard/assets/ProvidersPage-vdja5ZPK.js.gz +0 -0
  324. package/dist/dashboard/assets/ProxyPage-BB4CNm4-.js.gz +0 -0
  325. package/dist/dashboard/assets/QuotaPage-FEc4iNyq.js +0 -1
  326. package/dist/dashboard/assets/QuotaPage-FEc4iNyq.js.gz +0 -0
  327. package/dist/dashboard/assets/SettingsPage-Dlfi5L4N.js +0 -1
  328. package/dist/dashboard/assets/SettingsPage-Dlfi5L4N.js.gz +0 -0
  329. package/dist/dashboard/assets/SetupPage-FadUOl9S.js.gz +0 -0
  330. package/dist/dashboard/assets/SortableList-Cfy6_Khv.js.gz +0 -0
  331. package/dist/dashboard/assets/UsagePage-BT4MyQeT.js.gz +0 -0
  332. package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
  333. package/dist/dashboard/assets/app-CX_Z8cMs.css +0 -2
  334. package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
  335. package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
  336. package/dist/dashboard/assets/badge-Bvyr7D0u.js.gz +0 -0
  337. package/dist/dashboard/assets/banner-DIvKAZih.js.gz +0 -0
  338. package/dist/dashboard/assets/card-D5_gYIS_.js.gz +0 -0
  339. package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
  340. package/dist/dashboard/assets/clipboard-button-B6vDBtbm.js.gz +0 -0
  341. package/dist/dashboard/assets/dialog-CpjrgdwJ.js.gz +0 -0
  342. package/dist/dashboard/assets/drawer-BWmt3b5y.js.gz +0 -0
  343. package/dist/dashboard/assets/entry-B-gvimrg.js +0 -1
  344. package/dist/dashboard/assets/entry-B-gvimrg.js.gz +0 -0
  345. package/dist/dashboard/assets/entry-C_oakV3z.js.gz +0 -0
  346. package/dist/dashboard/assets/entry-Dj0cHfEc.js +0 -4
  347. package/dist/dashboard/assets/entry-Dj0cHfEc.js.gz +0 -0
  348. package/dist/dashboard/assets/github-badge-RRHHWGxh.js.gz +0 -0
  349. package/dist/dashboard/assets/index-Bhey_rg_.js.gz +0 -0
  350. package/dist/dashboard/assets/inline-C2_EQ5Uf.js.gz +0 -0
  351. package/dist/dashboard/assets/input-BMRlQ450.js.gz +0 -0
  352. package/dist/dashboard/assets/layout-XR5xP8ew.js.gz +0 -0
  353. package/dist/dashboard/assets/list-row-Cw07dioc.js.gz +0 -0
  354. package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
  355. package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
  356. package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
  357. package/dist/dashboard/assets/numbers-DrdA9oSM.js.gz +0 -0
  358. package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
  359. package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
  360. package/dist/dashboard/assets/select-CxVVB__N.js.gz +0 -0
  361. package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
  362. package/dist/dashboard/assets/stack-uPOwM9Hs.js.gz +0 -0
  363. package/dist/dashboard/assets/state-D1Yz79iL.js.gz +0 -0
  364. package/dist/dashboard/assets/switch-sevsRrRo.js.gz +0 -0
  365. package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +0 -0
  366. package/src/observability/event-compaction.ts +0 -317
  367. package/src/observability/event-day-index.ts +0 -439
@@ -36,6 +36,8 @@ import { OpenAICompatibleAdapter } from "../adapters/compatible-adapter";
36
36
  import { resolveByokWireProfile } from "../operations/byok-wire-profile";
37
37
  import { recordAccountFailure, recordAccountSuccess } from "../operations/account-health-service";
38
38
  import { buildCapabilityProfile } from "../../transport/routing/route-catalog";
39
+ import { payloadRetentionMs, resolvePayloadCapture } from "../../observability/payload-capture";
40
+ import type { TelemetryPayloadDepth } from "../../console/settings/contracts";
39
41
  import { classifyUpstreamFailure } from "../../transport/failure-policy";
40
42
  import { terminalFailure } from "../../transport/dispatch/attempt-finalize";
41
43
  import { GatewayError } from "../../protocol/gateway-error";
@@ -448,7 +450,23 @@ export interface ProbeReasoning {
448
450
  /** Tenant probe preferences that shape the request and telemetry. */
449
451
  export interface ProbePreferences {
450
452
  readonly probeReasoning: ProbeReasoning | undefined;
451
- readonly payloadCaptureEnabled: boolean;
453
+ /**
454
+ * The tenant's resolved capture policy for the probe, through the same
455
+ * `resolvePayloadCapture` path every dispatched request uses.
456
+ *
457
+ * `none` (and a failed preference read — capture fails closed) captures
458
+ * nothing; `metadata` captures stage presence only; `full` keeps bodies at
459
+ * the tenant's own depth and retention. The previous boolean collapsed all
460
+ * three into "capture on", so a probe teed bodies at the flat deployment
461
+ * cap for a tenant whose choice was `metadata` — and whose live requests
462
+ * stored none.
463
+ */
464
+ readonly payloadCapture: {
465
+ readonly enabled: boolean;
466
+ readonly mode: "none" | "metadata" | "full";
467
+ readonly depth: TelemetryPayloadDepth;
468
+ readonly retentionMs: number;
469
+ };
452
470
  }
453
471
 
454
472
  /**
@@ -465,7 +483,12 @@ export async function loadProbePreferences(args: {
465
483
  }): Promise<ProbePreferences> {
466
484
  const { db, tenantId, wireFamily, request } = args;
467
485
  let probeReasoning: ProbeReasoning | undefined;
468
- let payloadCaptureEnabled = false;
486
+ let payloadCapture: ProbePreferences["payloadCapture"] = {
487
+ enabled: false,
488
+ mode: "none",
489
+ depth: "minimum",
490
+ retentionMs: payloadRetentionMs(),
491
+ };
469
492
  // `auto` (and an omitted effort) means "send no reasoning intent": the probe
470
493
  // must reflect what the route does by itself, and a model that does not
471
494
  // support reasoning would otherwise fail a probe that should have passed.
@@ -483,10 +506,23 @@ export async function loadProbePreferences(args: {
483
506
  const raw = preferences?.responsesReasoningSummary;
484
507
  const mode: "auto" | "concise" | "detailed" =
485
508
  raw === "auto" || raw === "concise" || raw === "detailed" ? raw : "detailed";
486
- // Unset matches the settings default: off. Only an explicit choice captures.
487
- payloadCaptureEnabled =
488
- preferences?.telemetryPayloads === "full" ||
489
- preferences?.telemetryPayloads === "metadata";
509
+ // Unset matches the settings default: off. Only an explicit choice
510
+ // captures, and at the tenant's own depth/retention — the same resolution
511
+ // `resolvePayloadCapture` performs for dispatched requests, read from the
512
+ // same preferences row this phase already loaded.
513
+ const captureMode = preferences?.telemetryPayloads;
514
+ if (captureMode === "full" || captureMode === "metadata") {
515
+ const resolved = await resolvePayloadCapture(db, tenantId);
516
+ payloadCapture = resolved.ok
517
+ ? {
518
+ enabled: true,
519
+ mode: resolved.mode,
520
+ depth: resolved.depth,
521
+ retentionMs: resolved.retentionMs,
522
+ }
523
+ : // Failed preference read: capture fails closed.
524
+ { enabled: false, mode: "none", depth: "minimum", retentionMs: payloadRetentionMs() };
525
+ }
490
526
  if (wireFamily === "responses" && requestedEffort !== undefined) {
491
527
  probeReasoning = {
492
528
  effort: requestedEffort,
@@ -501,7 +537,7 @@ export async function loadProbePreferences(args: {
501
537
  };
502
538
  }
503
539
  }
504
- return { probeReasoning, payloadCaptureEnabled };
540
+ return { probeReasoning, payloadCapture };
505
541
  }
506
542
 
507
543
  /**
@@ -1,4 +1,12 @@
1
- import { captureProviderExchange, type ProviderExchangeCapture } from "../../transport/dispatch/attempt-finalize";
1
+ import {
2
+ captureProviderExchange,
3
+ providerRequestMetadataOnly,
4
+ type ProviderExchangeCapture,
5
+ } from "../../transport/dispatch/attempt-finalize";
6
+ import {
7
+ captureDepthMaxBytes,
8
+ providerCaptureMaxBytes,
9
+ } from "../../transport/dispatch/capture-policy";
2
10
  import { globalOrOwnedBy } from "../../persistence/tenant-scope";
3
11
  /**
4
12
  * Provider probing and model-discovery orchestration.
@@ -221,7 +229,7 @@ export class ProviderProbingService {
221
229
  };
222
230
  }
223
231
 
224
- const { probeReasoning, payloadCaptureEnabled } = await loadProbePreferences({
232
+ const { probeReasoning, payloadCapture } = await loadProbePreferences({
225
233
  db: this.db,
226
234
  tenantId,
227
235
  wireFamily,
@@ -273,14 +281,19 @@ export class ProviderProbingService {
273
281
  };
274
282
  // The same wrapper a real dispatch uses, so the probe reads the model the
275
283
  // upstream named from the raw bytes rather than from a synthesized event.
284
+ // Body capture follows the tenant's mode: `metadata` tees the request
285
+ // line and stage presence without slicing bodies (the same
286
+ // `captureBody=false` path a live metadata-mode dispatch uses), `full`
287
+ // tees bodies at the tenant's own depth cap. `none` still wraps — the
288
+ // reported-model read is dispatch metadata, not payload retention, and
289
+ // runs regardless of capture mode.
276
290
  const probeFetch = createProbeFetch(
277
- // Body capture on, unlike a live dispatch: a probe is one-shot and
278
- // operator-initiated, so it exists to be inspected. With it off, the
279
- // provider-response tee resolved to null and every probe row reported
280
- // the middle two stages as absent — a constant, not a measurement,
281
- // which made the stage markers useless for the diagnosis they exist
282
- // for. The 256 KiB cap in the tee bounds the cost.
283
- captureProviderExchange(outbound.fetch, probeCapture, true),
291
+ captureProviderExchange(
292
+ outbound.fetch,
293
+ probeCapture,
294
+ payloadCapture.mode === "full",
295
+ providerCaptureMaxBytes(payloadCapture.depth),
296
+ ),
284
297
  );
285
298
  try {
286
299
  if (serviceKind === "websearch") {
@@ -506,29 +519,54 @@ export class ProviderProbingService {
506
519
  ...(usage ? { usage } : {}),
507
520
  ...(tokensPerSec !== undefined ? { tokensPerSec } : {}),
508
521
  });
509
- if (this.telemetryBuffer && payloadCaptureEnabled) {
510
- // All four surfaces, so the row's stage markers mean the same thing here
511
- // as they do on a live request: which hop actually produced bytes.
512
- const providerRequest = probeCapture?.request ?? null;
513
- const providerResponse = await probeCapture?.response.catch(() => null) ?? null;
514
- await this.payloadCapture
515
- .capture({
516
- tenantId,
517
- requestId,
518
- requestBody: capturedRequest,
519
- // `events` is what the *client* receives, so it belongs in the client
520
- // surface. Passing it as `responseBody` lit the client bit on probes
521
- // whose event list was empty, over a body that was never captured.
522
- // The legacy alias is explicitly absent here; `null` leaves bit 8 to
523
- // be decided by the real client body alone.
524
- responseBody: null,
525
- ...(events === undefined ? {} : { clientResponseBody: events }),
526
- ...(providerRequest === null ? {} : { providerRequestBody: providerRequest }),
527
- ...(providerResponse === null ? {} : { providerResponseBody: providerResponse }),
528
- scope: "tenant",
529
- tenantOptIn: true,
530
- })
531
- .catch(() => undefined);
522
+ if (this.telemetryBuffer && payloadCapture.enabled) {
523
+ if (payloadCapture.mode === "metadata") {
524
+ // Stage presence only: the provider request line (method, URL,
525
+ // headers, body_present/body_bytes) is exactly what `metadata` mode
526
+ // keeps for a live request. No bodies anywhere.
527
+ const providerRequest = providerRequestMetadataOnly(probeCapture?.request ?? null);
528
+ if (providerRequest !== null) {
529
+ await this.payloadCapture
530
+ .capture({
531
+ tenantId,
532
+ requestId,
533
+ requestBody: null,
534
+ responseBody: null,
535
+ providerRequestBody: providerRequest,
536
+ retentionMs: payloadCapture.retentionMs,
537
+ scope: "tenant",
538
+ tenantOptIn: true,
539
+ })
540
+ .catch(() => undefined);
541
+ }
542
+ } else {
543
+ // All four surfaces, so the row's stage markers mean the same thing
544
+ // here as they do on a live request: which hop actually produced bytes.
545
+ // Depth and retention are the tenant's own, resolved through the same
546
+ // preference path a dispatched request uses.
547
+ const providerRequest = probeCapture?.request ?? null;
548
+ const providerResponse = await probeCapture?.response.catch(() => null) ?? null;
549
+ await this.payloadCapture
550
+ .capture({
551
+ tenantId,
552
+ requestId,
553
+ requestBody: capturedRequest,
554
+ // `events` is what the *client* receives, so it belongs in the
555
+ // client surface. Passing it as `responseBody` lit the client bit
556
+ // on probes whose event list was empty, over a body that was never
557
+ // captured. The legacy alias is explicitly absent here; `null`
558
+ // leaves bit 8 to be decided by the real client body alone.
559
+ responseBody: null,
560
+ ...(events === undefined ? {} : { clientResponseBody: events }),
561
+ ...(providerRequest === null ? {} : { providerRequestBody: providerRequest }),
562
+ ...(providerResponse === null ? {} : { providerResponseBody: providerResponse }),
563
+ maxBytes: captureDepthMaxBytes(payloadCapture.depth),
564
+ retentionMs: payloadCapture.retentionMs,
565
+ scope: "tenant",
566
+ tenantOptIn: true,
567
+ })
568
+ .catch(() => undefined);
569
+ }
532
570
  }
533
571
 
534
572
  const sample = extractSample(events);
@@ -44,6 +44,7 @@ import {
44
44
  getAntigravityModelWireProfile,
45
45
  getAntigravityUserAgent,
46
46
  loadAntigravityProject,
47
+ normalizeAntigravityToolSchemas,
47
48
  } from "./antigravity-protocol";
48
49
  import type { ImageGenerationOutcome, ProviderDispatchTarget, ProviderAdapter, ProviderDispatchContext, WebSearchOutcome, WebSearchResult } from "../../provider-contracts";
49
50
  import { providerBaseUrl } from "../../provider-metadata";
@@ -878,7 +879,7 @@ export function failoverAntigravityUrl(url: string, baseUrl: string): string | u
878
879
  * envelope `model`, while the Gemini `contents`/`tools`/`generationConfig`
879
880
  * ride inside `request` with Antigravity's `labels` telemetry.
880
881
  */
881
- function buildAntigravityEnvelope(
882
+ export function buildAntigravityEnvelope(
882
883
  request: CanonicalRequest,
883
884
  projectId: string | undefined,
884
885
  wireModelId: string,
@@ -886,7 +887,13 @@ function buildAntigravityEnvelope(
886
887
  state: AntigravitySessionState,
887
888
  sessionSeed: string,
888
889
  ): Record<string, unknown> {
889
- const geminiPayload = buildGeminiPayload(request);
890
+ // Tools first: a declaration whose real schema is nested under
891
+ // `parametersJsonSchema` (the spelling Cloud Code Assist sends) must be
892
+ // unwrapped *before* the shared Gemini builder, whose sanitizer has no entry
893
+ // for that key and would drop both the wrapper and the schema inside it —
894
+ // the tool would ship as `{"type":"object"}` with every property gone.
895
+ // Rewriting after the payload is built leaves nothing to recover.
896
+ const geminiPayload = buildGeminiPayload(normalizeAntigravityToolSchemas(request));
890
897
  const profile = getAntigravityModelWireProfile(wireModelId);
891
898
 
892
899
  const generationConfig = isRecord(geminiPayload["generationConfig"])
@@ -65,6 +65,10 @@ const BUDDY_IMAGE_MODEL_IDS: readonly { id: string; endpoint: string; ctx: numbe
65
65
  { id: "gemini-3.1-flash-image", endpoint: "/chat/completions", ctx: 1_000_000, out: 64_000 },
66
66
  { id: "gpt-image-2", endpoint: "/chat/completions", ctx: 400_000, out: 128_000 },
67
67
  { id: "gpt-image-2.5-sunburst", endpoint: "/chat/completions", ctx: 400_000, out: 128_000 },
68
+ // Published by /v3/config only, tagged `text-to-image` + `image-to-image`.
69
+ // Upstream declares no token limits for it, so the roster floor is used
70
+ // rather than inventing a number the upstream never sent.
71
+ { id: "hy-image-3.5", endpoint: "/chat/completions", ctx: 1_000_000, out: 64_000 },
68
72
  ];
69
73
 
70
74
  /**
@@ -79,6 +83,11 @@ const BUDDY_IMAGE_MODEL_IDS: readonly { id: string; endpoint: string; ctx: numbe
79
83
  */
80
84
  const BUDDY_VIDEO_MODEL_IDS: readonly { id: string; endpoint: string; ctx: number; out: number }[] = [
81
85
  { id: "seedance-2.5", endpoint: "/videos/generations", ctx: 1_000_000, out: 128_000 },
86
+ // Published by /v3/config only, tagged `text-to-video` + `image-to-video`.
87
+ // Upstream declares capabilities in a `videoGeneration` block instead of
88
+ // token limits (720P/1080P/4K, 16:9/9:16/1:1, 3-15s, switchable audio,
89
+ // first/last-frame control), so the token columns carry the roster floor.
90
+ { id: "kling-video-v3", endpoint: "/videos/generations", ctx: 1_000_000, out: 128_000 },
82
91
  ];
83
92
 
84
93
  /**
@@ -92,6 +101,52 @@ export const BUDDY_IMAGE_MODEL_ID_SET: ReadonlySet<string> = new Set(
92
101
  BUDDY_IMAGE_MODEL_IDS.map((entry) => entry.id),
93
102
  );
94
103
 
104
+ /**
105
+ * The CN realm's image-generation ids.
106
+ *
107
+ * Separate from {@link BUDDY_IMAGE_MODEL_IDS} because the realms do not share
108
+ * a roster: `hunyuan-image-alpha` is published by the CN `/v3/config` only, and
109
+ * the intl image ids are not served there. Sharing one list would either leak
110
+ * CN-only ids onto the international catalogs or force a realm check into
111
+ * every consumer.
112
+ *
113
+ * `hunyuan-image-alpha-edit` carries `image-to-image` and is deliberately NOT
114
+ * here: it is not in the CLI roster, so it is not a routable generation model.
115
+ */
116
+ const BUDDY_CN_IMAGE_MODEL_IDS: readonly { id: string; ctx: number; out: number }[] = [
117
+ { id: "hunyuan-image-alpha", ctx: 1_000_000, out: 64_000 },
118
+ ];
119
+
120
+ /** The CN analogue of {@link BUDDY_IMAGE_MODEL_ID_SET}. */
121
+ export const BUDDY_CN_IMAGE_MODEL_ID_SET: ReadonlySet<string> = new Set(
122
+ BUDDY_CN_IMAGE_MODEL_IDS.map((entry) => entry.id),
123
+ );
124
+
125
+ /**
126
+ * Builds the CN image-generation rows for one buddy CN provider.
127
+ *
128
+ * Same shape as {@link makeBuddyImageModels}, scoped to the CN roster.
129
+ */
130
+ export function makeBuddyCnImageModels(
131
+ providerId: string,
132
+ endpoint: string,
133
+ ): readonly ModelDefinition[] {
134
+ return BUDDY_CN_IMAGE_MODEL_IDS.map((entry) =>
135
+ defineModel({
136
+ id: entry.id,
137
+ providerId,
138
+ serviceKind: "imageGeneration",
139
+ wireFamily: "chat",
140
+ endpoint,
141
+ ctx: entry.ctx,
142
+ out: entry.out,
143
+ vision: true,
144
+ output: ["image"],
145
+ toolCall: false,
146
+ }),
147
+ );
148
+ }
149
+
95
150
  /**
96
151
  * Ids the buddy facade refuses on a free plan.
97
152
  *
@@ -124,6 +179,10 @@ export const BUDDY_PRO_ONLY_MODEL_IDS: ReadonlySet<string> = new Set([
124
179
  "grok-4.6",
125
180
  "grok-4.7",
126
181
  "kimi-k3.1-pro-highspeed",
182
+ // The Opus rows: both are refused on free while Sonnet 4.6 at the same
183
+ // 1M window is served, so this is the tier rather than the size.
184
+ "claude-opus-4.6",
185
+ "claude-opus-4.7-1m",
127
186
  ]);
128
187
 
129
188
  /**
@@ -254,11 +313,19 @@ export function makeBuddyModel(
254
313
  * output ceilings), so it keeps its own table.
255
314
  */
256
315
  export const BUDDY_SHARED_RAW: readonly BuddyRawEntry[] = [
257
- ["auto", "Auto", true, true, 168_000, null],
316
+ ["auto", "Auto", false, true, 176_000, 24_000],
317
+ // The three named tiers and `gpt-6-astra` are published by /v3/config and sit
318
+ // in the CLI roster, but had no static row: a client asking for
319
+ // `fast-model` resolved to nothing and the model was invisible. Added with
320
+ // the limits upstream declares for them.
321
+ ["fast-model", "Fast", true, true, 200_000, 32_000, true],
322
+ ["balanced-model", "Balanced", true, true, 256_000, 32_000, true],
323
+ ["primary-model", "Primary", true, true, 272_000, 72_000, true],
324
+ ["gpt-6-astra", "GPT-6 Astra", true, true, 1_000_000, 128_000],
258
325
  ["claude-opus-4.6", "Claude Opus 4.6", true, true, 200_000, 64_000],
259
326
  ["claude-opus-4.7-1m", "Claude Opus 4.7 1M", true, true, 1_000_000, 64_000],
260
327
  ["claude-sonnet-4.6", "Claude Sonnet 4.6", true, true, 200_000, 32_000],
261
- ["deepseek-v4.1-flash", "DeepSeek V4.1 Flash", true, true, 1_000_000, 384_000],
328
+ ["deepseek-v4.1-flash", "DeepSeek V4.1 Flash", true, true, 1_000_000, 128_000],
262
329
  ["deepseek-v4.1-flash-sg", "DeepSeek V4.1 Flash SG", true, true, 1_000_000, 128_000],
263
330
  ["gemini-2.5-flash-image", "Gemini 2.5 Flash Image", true, true, 1_000_000, 64_000],
264
331
  ["gemini-3.0-pro-image", "Gemini 3.0 Pro Image", true, true, 1_000_000, 64_000],
@@ -267,23 +334,23 @@ export const BUDDY_SHARED_RAW: readonly BuddyRawEntry[] = [
267
334
  ["gemini-3.5-flash", "Gemini 3.5 Flash", true, true, 1_048_576, 65_536],
268
335
  ["gemini-3.8-flash", "Gemini 3.8 Flash", true, true, 1_000_000, 65_536, true],
269
336
  ["glm-5.1", "GLM-5.1", true, false, 200_000, 131_072],
270
- ["glm-5.2", "GLM-5.2", true, false, 1_000_000, 131_072],
271
- ["glm-5.3", "GLM-5.3", true, false, 1_000_000, 131_072],
272
- ["glm-5.3-flash", "GLM-5.3 Flash", true, false, 1_000_000, 131_072],
337
+ ["glm-5.2", "GLM-5.2", true, true, 1_000_000, 48_000],
338
+ ["glm-5.3", "GLM-5.3", true, true, 1_000_000, 48_000],
339
+ ["glm-5.3-flash", "GLM-5.3 Flash", true, true, 1_000_000, 32_000],
273
340
  ["glm-5v-turbo", "GLM-5V Turbo", true, true, 200_000, 131_072],
274
341
  ["gpt-5.3-codex", "GPT-5.3 Codex", true, true, 400_000, 128_000],
275
- ["gpt-5.4", "GPT-5.4", true, true, 1_050_000, 128_000],
276
- ["gpt-5.5", "GPT-5.5", true, true, 1_050_000, 128_000],
277
- ["gpt-5.6-luna", "GPT-5.6 Luna", true, true, 1_050_000, 128_000],
278
- ["gpt-5.6-sol", "GPT-5.6 Sol", true, true, 1_050_000, 128_000],
279
- ["gpt-5.6-terra", "GPT-5.6 Terra", true, true, 1_050_000, 128_000],
280
- ["gpt-6-luna", "GPT-6 Luna", true, true, 1_050_000, 128_000],
342
+ ["gpt-5.4", "GPT-5.4", true, true, 272_000, 72_000],
343
+ ["gpt-5.5", "GPT-5.5", true, true, 1_000_000, 128_000],
344
+ ["gpt-5.6-luna", "GPT-5.6 Luna", true, true, 1_000_000, 128_000],
345
+ ["gpt-5.6-sol", "GPT-5.6 Sol", true, true, 1_000_000, 128_000],
346
+ ["gpt-5.6-terra", "GPT-5.6 Terra", true, true, 1_000_000, 128_000],
347
+ ["gpt-6-luna", "GPT-6 Luna", true, true, 1_000_000, 128_000],
281
348
  ["gpt-6-sol", "GPT-6 Sol", true, true, 1_000_000, 128_000, true],
282
- ["gpt-6.1-sol", "GPT-6.1 Sol", true, true, 1_050_000, 128_000],
349
+ ["gpt-6.1-sol", "GPT-6.1 Sol", true, true, 1_000_000, 128_000],
283
350
  ["gpt-image-2", "GPT-Image-2", true, true, 400_000, 128_000],
284
351
  ["grok-4.6", "Grok 4.6", true, true, 500_000, 500_000],
285
- ["grok-4.7", "Grok 4.7", true, true, 500_000, 500_000],
286
- ["hy3", "Hy3", true, false, 192_000, 64_000, true],
352
+ ["grok-4.7", "Grok 4.7", true, true, 500_000, 128_000],
353
+ ["hy3", "Hy3", true, true, 192_000, 64_000, true],
287
354
  ["hy3-preview", "Hy3 Preview", true, false, 262_144, 64_000],
288
355
  ["hy4-preview", "Hy4 Preview", true, true, 1_000_000, 64_000, true],
289
356
  ["hy4-preview-f", "Hy4 Preview F", true, true, 1_000_000, 64_000, true],
@@ -291,9 +358,10 @@ export const BUDDY_SHARED_RAW: readonly BuddyRawEntry[] = [
291
358
  ["kimi-k2.6", "Kimi K2.6", true, false, 256_000, 262_144],
292
359
  ["kimi-k2.7", "Kimi K2.7", true, false, 256_000, 65_536],
293
360
  ["kimi-k2.8-preview", "Kimi K2.8 Preview", true, false, 1_048_576, 65_536],
294
- ["kimi-k3", "Kimi K3", true, false, 1_048_576, 131_072],
295
- ["kimi-k3.1-pro", "Kimi K3.1 Pro", true, true, 1_000_000, 64_000],
296
- ["kimi-k3.1-pro-highspeed", "Kimi K3.1 Pro Highspeed", true, true, 1_000_000, 64_000],
361
+ ["kimi-k3", "Kimi K3", true, true, 1_000_000, 32_000],
362
+ ["kimi-k3.1-pro", "Kimi K3.1 Pro", true, true, 1_000_000, 32_000],
363
+ ["kimi-k3.1-pro-highspeed", "Kimi K3.1 Pro Highspeed", true, true, 1_000_000, 32_000],
297
364
  ["minimax-m3", "MiniMax-M3", true, false, 512_000, 512_000],
365
+ ["minimax-m3.1-flash", "MiniMax-M3.1 Flash", true, true, 1_000_000, 128_000],
298
366
  ["step-5-preview", "Step-5-Preview", true, true, 1_000_000, 64_000, true],
299
367
  ];