cartethyia 2.7.8 → 2.8.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 (519) hide show
  1. package/.env.example +3 -3
  2. package/README.md +29 -59
  3. package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolDetailPage-BRWKPQPf.js → CliToolDetailPage-Bqj2aa1T.js} +1 -1
  6. package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolsPage-BP-Y5iHN.js → CliToolsPage-CXsaOAO2.js} +1 -1
  8. package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
  17. package/dist/dashboard/assets/{InjectSystemPromptPanel-Cv-2Ol_K.js → InjectSystemPromptPanel-BWFLECmz.js} +2 -2
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
  19. package/dist/dashboard/assets/{LoginPage-bKfz_b1K.js → LoginPage-CgoPc5B9.js} +1 -1
  20. package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-B-WQxx_H.js → ModelPicker-D9bFQern.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +8 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-emlTuxz6.js → ProxyPage-BwNC_-Cx.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-CctTga2C.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
  37. package/dist/dashboard/assets/{SetupPage-CUZrKs9r.js → SetupPage-febLU4r1.js} +1 -1
  38. package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-jWmUdDpy.js → StudioPage-M6fvR5Wz.js} +1 -1
  40. package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
  41. package/dist/dashboard/assets/UsagePage-nyeuRqz9.js +56 -0
  42. package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
  43. package/dist/dashboard/assets/api-keys-BFOlvrJC.js +1 -0
  44. package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
  45. package/dist/dashboard/assets/app-Dx2QgsNj.css +2 -0
  46. package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-CidQVoNo.js → assert-CqTLw5e7.js} +1 -1
  48. package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-DyI_mJfi.js → badge-C83EqLB0.js} +1 -1
  50. package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
  51. package/dist/dashboard/assets/ban-durations-B58FyRxC.js +1 -0
  52. package/dist/dashboard/assets/ban-durations-B58FyRxC.js.gz +0 -0
  53. package/dist/dashboard/assets/{banner-B-yXtCqb.js → banner-D1xn7pIe.js} +1 -1
  54. package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
  55. package/dist/dashboard/assets/brand/bansos_page.webp +0 -0
  56. package/dist/dashboard/assets/brand/denia_bansos.webp +0 -0
  57. package/dist/dashboard/assets/brand/favicon.webp +0 -0
  58. package/dist/dashboard/assets/brand/login_register.webp +0 -0
  59. package/dist/dashboard/assets/brand/login_register_initial.webp +0 -0
  60. package/dist/dashboard/assets/brand/og_bansos.webp +0 -0
  61. package/dist/dashboard/assets/brand/og_image.webp +0 -0
  62. package/dist/dashboard/assets/brand/sidebar_ico.webp +0 -0
  63. package/dist/dashboard/assets/{card-_HwAEqFF.js → card-DU3Lq5Lm.js} +1 -1
  64. package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
  65. package/dist/dashboard/assets/cli-tools-Dw1U_drK.js +1 -0
  66. package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
  67. package/dist/dashboard/assets/{clipboard-button-ByjCk0o9.js → clipboard-button-CEL5Sg_J.js} +1 -1
  68. package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
  69. package/dist/dashboard/assets/{dialog-BZhOlfz-.js → dialog-BjFR5UHy.js} +1 -1
  70. package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
  71. package/dist/dashboard/assets/{drawer-BADqIRYP.js → drawer-HvBW0AjI.js} +1 -1
  72. package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
  73. package/dist/dashboard/assets/entry-BSu3gFlt.js +4 -0
  74. package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
  75. package/dist/dashboard/assets/{entry-COaC-irN.js → entry-CECVELyy.js} +1 -1
  76. package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
  77. package/dist/dashboard/assets/entry-DYYofQ7W.js +1 -0
  78. package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
  79. package/dist/dashboard/assets/{formatters-DcHJyRiu.js → formatters-DLW4i8zK.js} +1 -1
  80. package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
  81. package/dist/dashboard/assets/{index-CgKmFngv.js → index-1-fCqe64.js} +2 -2
  82. package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
  83. package/dist/dashboard/assets/{inline-B2BirKry.js → inline-DGvU2oLK.js} +1 -1
  84. package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
  85. package/dist/dashboard/assets/{input-D-qV9dKY.js → input-iNnO1X2K.js} +1 -1
  86. package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
  87. package/dist/dashboard/assets/{layout-B7tVWhtV.js → layout-0q8UGypb.js} +1 -1
  88. package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
  89. package/dist/dashboard/assets/{list-row-CtkGE3bF.js → list-row-C0w2bQjJ.js} +1 -1
  90. package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
  91. package/dist/dashboard/assets/{live-DGizF06-.js → live-M5aJ_xCa.js} +1 -1
  92. package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
  93. package/dist/dashboard/assets/{mutation-GU7XdEjz.js → mutation-BQ0ccH_A.js} +1 -1
  94. package/dist/dashboard/assets/mutation-BQ0ccH_A.js.gz +0 -0
  95. package/dist/dashboard/assets/{network-C9UE-bOr.js → network-BKeQGT3K.js} +1 -1
  96. package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
  97. package/dist/dashboard/assets/{numbers-BnAd22a_.js → numbers-CivAk3da.js} +1 -1
  98. package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
  99. package/dist/dashboard/assets/{pagination-BAywyMzS.js → pagination-CpzvI5ep.js} +1 -1
  100. package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
  101. package/dist/dashboard/assets/providers/devin.svg +9 -0
  102. package/dist/dashboard/assets/providers/devin.svg.gz +0 -0
  103. package/dist/dashboard/assets/providers/windsurf.svg +10 -0
  104. package/dist/dashboard/assets/providers/windsurf.svg.gz +0 -0
  105. package/dist/dashboard/assets/providers/zro.svg +3 -0
  106. package/dist/dashboard/assets/providers/zro.svg.gz +0 -0
  107. package/dist/dashboard/assets/{query-keys-YSoQOUh6.js → query-keys-IKLh0YFd.js} +1 -1
  108. package/dist/dashboard/assets/query-keys-IKLh0YFd.js.gz +0 -0
  109. package/dist/dashboard/assets/quota-DiPD6UKH.js +1 -0
  110. package/dist/dashboard/assets/quota-DiPD6UKH.js.gz +0 -0
  111. package/dist/dashboard/assets/routing-BFQX2VBc.js +1 -0
  112. package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
  113. package/dist/dashboard/assets/{select-BCOcv8WK.js → select-CXbck0jG.js} +2 -2
  114. package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
  115. package/dist/dashboard/assets/settings-C_XvMHh9.js +1 -0
  116. package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
  117. package/dist/dashboard/assets/{stack-ByKt3Q1g.js → stack-DggRiCxE.js} +1 -1
  118. package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
  119. package/dist/dashboard/assets/{state-DXbGTx7N.js → state-ClFzfbYp.js} +1 -1
  120. package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
  121. package/dist/dashboard/assets/story/25817331.webp +0 -0
  122. package/dist/dashboard/assets/story/Shorekeeper.webp +0 -0
  123. package/dist/dashboard/assets/story/cartethyia-god.webp +0 -0
  124. package/dist/dashboard/assets/story/fleurdelys_plus.webp +0 -0
  125. package/dist/dashboard/assets/story/jinhsi-blossom.webp +0 -0
  126. package/dist/dashboard/assets/story/phrolova-a.webp +0 -0
  127. package/dist/dashboard/assets/story/requestdeniawokkjpg.webp +0 -0
  128. package/dist/dashboard/assets/story/wuthering-waves-hiyuki-aemeath-hiyuki-rover.webp +0 -0
  129. package/dist/dashboard/assets/{switch-ZeTsW623.js → switch-CTIFxKqS.js} +1 -1
  130. package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
  131. package/dist/dashboard/assets/{useMutation-CbCP4w1o.js → useMutation-BClG3yWj.js} +1 -1
  132. package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
  133. package/dist/dashboard/console-backgrounds.webp +0 -0
  134. package/dist/dashboard/console-backgrounds_initial.webp +0 -0
  135. package/dist/dashboard/donation/qris-risun-marke.webp +0 -0
  136. package/dist/dashboard/index.html +3 -3
  137. package/dist/dashboard/index.html.gz +0 -0
  138. package/dist/dashboard/precompressed-assets.json +59 -56
  139. package/migrations/full-postgres/0044_add_models_warning_metadata.sql +10 -0
  140. package/migrations/full-postgres/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
  141. package/migrations/full-postgres/0046_add_accounts_quota_plan_fetched_at.sql +7 -0
  142. package/migrations/lite-sqlite3/0044_add_models_warning_metadata.sql +11 -0
  143. package/migrations/lite-sqlite3/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
  144. package/migrations/lite-sqlite3/0046_add_accounts_quota_plan_fetched_at.sql +4 -0
  145. package/package.json +1 -1
  146. package/src/boot/app.ts +10 -13
  147. package/src/boot/dependencies.ts +12 -4
  148. package/src/boot/flush.ts +20 -0
  149. package/src/boot/lifecycle.ts +7 -5
  150. package/src/config/cooldowns.ts +1 -1
  151. package/src/config/routing.ts +26 -0
  152. package/src/config/spec-metadata.ts +72 -0
  153. package/src/config/spec.ts +20 -6
  154. package/src/console/api-keys/contracts.ts +12 -1
  155. package/src/console/api-keys/routes.ts +50 -31
  156. package/src/console/auth/account-reset.ts +7 -9
  157. package/src/console/backup/contracts.ts +4 -0
  158. package/src/console/backup/export-endpoint.ts +7 -5
  159. package/src/console/cli-tools/service.ts +6 -12
  160. package/src/console/console-router-guards.ts +23 -16
  161. package/src/console/console-router.ts +7 -0
  162. package/src/console/dashboard-assets.ts +5 -5
  163. package/src/console/domain-registration.ts +27 -2
  164. package/src/console/inferhub/normalize.ts +24 -28
  165. package/src/console/inferhub/types.ts +3 -0
  166. package/src/console/ip-bans/routes.ts +93 -0
  167. package/src/console/observability/store.ts +0 -53
  168. package/src/console/providers/catalog/catalog-projections.ts +5 -2
  169. package/src/console/providers/catalog/contracts.ts +123 -0
  170. package/src/console/providers/catalog/discover-constants.ts +6 -0
  171. package/src/console/providers/catalog/model-operations.ts +122 -10
  172. package/src/console/providers/catalog/provider-operations.ts +116 -8
  173. package/src/console/providers/catalog/public-model-store.ts +0 -0
  174. package/src/console/providers/catalog/routes.ts +65 -4
  175. package/src/console/providers/catalog/store-helpers.ts +30 -1
  176. package/src/console/providers/catalog/store.ts +249 -4
  177. package/src/console/quota/account-quota-global.ts +97 -19
  178. package/src/console/quota/account-quota-shared.ts +49 -0
  179. package/src/console/quota/account-quota-tenant.ts +6 -18
  180. package/src/console/quota/native-identity.ts +2 -0
  181. package/src/console/quota/quota-view.ts +19 -3
  182. package/src/console/routing/pools/operations.ts +31 -46
  183. package/src/console/settings/contracts.ts +18 -0
  184. package/src/console/settings/store.ts +32 -0
  185. package/src/console/shared/errors.ts +33 -6
  186. package/src/console/system-prompt/contracts.ts +0 -1
  187. package/src/main.ts +3 -3
  188. package/src/network/pool/byte-accounting.ts +3 -2
  189. package/src/network/pool/selector.ts +182 -39
  190. package/src/network/pool-cooldown-store.ts +89 -14
  191. package/src/network/pool-health.ts +49 -61
  192. package/src/network/rate-limit-verdict.ts +1 -1
  193. package/src/network/ssrf.ts +6 -6
  194. package/src/observability/event-log.ts +7 -361
  195. package/src/observability/event-query.ts +18 -4
  196. package/src/observability/performance-metrics.ts +9 -0
  197. package/src/observability/runtime-metrics.ts +14 -9
  198. package/src/observability/telemetry-buffer.ts +15 -25
  199. package/src/observability/telemetry-reconciliation.ts +9 -37
  200. package/src/observability/telemetry-row.ts +125 -0
  201. package/src/persistence/db-mode.ts +4 -1
  202. package/src/persistence/dialect.ts +30 -0
  203. package/src/persistence/migrate.ts +6 -3
  204. package/src/persistence/schema.ts +28 -2
  205. package/src/persistence/ttl-cache.ts +20 -2
  206. package/src/protocol/codecs.ts +1 -1
  207. package/src/protocol/dsml.ts +35 -87
  208. package/src/protocol/gateway-error.ts +1 -0
  209. package/src/protocol/markup-stream-parser.ts +195 -0
  210. package/src/protocol/reasoning-text.ts +19 -0
  211. package/src/protocol/reasoning.ts +1 -1
  212. package/src/protocol/request/chat.ts +14 -14
  213. package/src/protocol/request/gemini.ts +8 -2
  214. package/src/protocol/request/messages.ts +4 -5
  215. package/src/protocol/response/chat.ts +12 -20
  216. package/src/protocol/response/gemini.ts +6 -1
  217. package/src/protocol/response/omp-tool-call-markup.ts +43 -86
  218. package/src/protocol/response/responses.ts +18 -2
  219. package/src/protocol/sse-decoder.ts +25 -8
  220. package/src/protocol/stop-reason.ts +23 -1
  221. package/src/protocol/stream-error-frames.ts +13 -3
  222. package/src/protocol/think-split.ts +112 -0
  223. package/src/protocol/translation/dialect/qwen.ts +26 -58
  224. package/src/protocol/translation/quirks.ts +1 -1
  225. package/src/protocol/translation/tool-repair.ts +2 -2
  226. package/src/protocol/upstream/send-claude-messages.ts +15 -4
  227. package/src/protocol/upstream-parsing.ts +1 -1
  228. package/src/providers/adapters/compatible-adapter.ts +78 -17
  229. package/src/providers/authentication/oauth-client.ts +1 -1
  230. package/src/providers/authentication/oauth-device-flow.ts +98 -8
  231. package/src/providers/authentication/oauth-refresh-service.ts +153 -59
  232. package/src/providers/configured-provider.ts +148 -0
  233. package/src/providers/default-registry.ts +117 -27
  234. package/src/providers/discovery/discovery-types.ts +12 -0
  235. package/src/providers/discovery/probe-phases.ts +74 -33
  236. package/src/providers/discovery/probing-service.ts +293 -165
  237. package/src/providers/integrations/alibabacp/alibabacp-models.ts +1 -2
  238. package/src/providers/integrations/{dashscope-models.ts → alibabacp/dashscope-models.ts} +2 -2
  239. package/src/providers/integrations/antigravity/antigravity-protocol.ts +121 -2
  240. package/src/providers/integrations/antigravity/antigravity.ts +13 -2
  241. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +72 -34
  242. package/src/providers/integrations/buddy/buddy-chat-shared.ts +191 -35
  243. package/src/providers/integrations/buddy/buddy-checkin.ts +17 -39
  244. package/src/providers/integrations/buddy/buddy-conversation-headers.ts +2 -2
  245. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +5 -5
  246. package/src/providers/integrations/buddy/buddy-identity.ts +89 -6
  247. package/src/providers/integrations/buddy/buddy-media.ts +4 -5
  248. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +2 -2
  249. package/src/providers/integrations/buddy/buddy-quota-shared.ts +1 -1
  250. package/src/providers/integrations/buddy/buddy-usage-shared.ts +1 -3
  251. package/src/providers/integrations/buddy/capabilities.ts +6 -43
  252. package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +2 -1
  253. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +23 -1
  254. package/src/providers/integrations/buddy/codebuddy/provider.ts +6 -2
  255. package/src/providers/integrations/buddy/codebuddy/shared.ts +38 -27
  256. package/src/providers/integrations/claude/claude-quota.ts +14 -17
  257. package/src/providers/integrations/cline/cline.ts +2 -2
  258. package/src/providers/integrations/commandcode/quota.ts +22 -28
  259. package/src/providers/integrations/cursor/cursor-auth.ts +0 -8
  260. package/src/providers/integrations/cursor/cursor-catalog.ts +2 -0
  261. package/src/providers/integrations/cursor/cursor-exec.ts +745 -0
  262. package/src/providers/integrations/cursor/cursor-http2.ts +2 -0
  263. package/src/providers/integrations/cursor/cursor-request.ts +35 -20
  264. package/src/providers/integrations/cursor/cursor-shared.ts +26 -5
  265. package/src/providers/integrations/cursor/cursor.ts +139 -70
  266. package/src/providers/integrations/cursor/protocol/messages.ts +22 -29
  267. package/src/providers/integrations/cursor/protocol/protobuf-schema.ts +37 -0
  268. package/src/providers/integrations/cursor/protocol/tool-canonical.ts +26 -100
  269. package/src/providers/integrations/devin/devin-auth.ts +353 -0
  270. package/src/providers/integrations/devin/devin-catalog.ts +207 -0
  271. package/src/providers/integrations/devin/devin-http.ts +91 -0
  272. package/src/providers/integrations/devin/devin-quota.ts +214 -0
  273. package/src/providers/integrations/devin/devin-shared.ts +111 -0
  274. package/src/providers/integrations/devin/devin.ts +539 -0
  275. package/src/providers/integrations/devin/protocol/devin-proto.ts +558 -0
  276. package/src/providers/integrations/devin/protocol/framing.ts +124 -0
  277. package/src/providers/integrations/factory/factory-oauth.ts +17 -44
  278. package/src/providers/integrations/factory/factory.ts +2 -2
  279. package/src/providers/integrations/freebuff/assets/official-system-manager.txt +88 -0
  280. package/src/providers/integrations/freebuff/assets/official-system-worker.txt +57 -0
  281. package/src/providers/integrations/freebuff/assets/official-tools.json +1070 -0
  282. package/src/providers/integrations/freebuff/freebuff-catalog.ts +120 -0
  283. package/src/providers/integrations/freebuff/freebuff-constants.ts +1233 -0
  284. package/src/providers/integrations/freebuff/freebuff-discovery.ts +108 -0
  285. package/src/providers/integrations/freebuff/freebuff-oauth.ts +240 -0
  286. package/src/providers/integrations/freebuff/freebuff-quota.ts +260 -0
  287. package/src/providers/integrations/freebuff/freebuff-virtual.ts +89 -0
  288. package/src/providers/integrations/freebuff/freebuff.ts +682 -0
  289. package/src/providers/integrations/freepi/freepi-catalog.ts +60 -0
  290. package/src/providers/integrations/freepi/freepi-discovery.ts +82 -0
  291. package/src/providers/integrations/freepi/freepi-headers.ts +21 -0
  292. package/src/providers/integrations/freepi/freepi-oauth.ts +142 -0
  293. package/src/providers/integrations/freepi/freepi-protocol.ts +242 -0
  294. package/src/providers/integrations/freepi/freepi-quota.ts +126 -0
  295. package/src/providers/integrations/freepi/freepi-realm.ts +35 -0
  296. package/src/providers/integrations/freepi/freepi.ts +292 -0
  297. package/src/providers/integrations/gemini.ts +2 -2
  298. package/src/providers/integrations/grok/grok-oauth.ts +48 -45
  299. package/src/providers/integrations/grok/grok-ratelimit-store.ts +10 -17
  300. package/src/providers/integrations/grok/grok-turn-index.ts +11 -16
  301. package/src/providers/integrations/hermes/hermes-oauth.ts +94 -0
  302. package/src/providers/integrations/{hermes.ts → hermes/hermes.ts} +13 -21
  303. package/src/providers/integrations/hermes/index.ts +2 -0
  304. package/src/providers/integrations/kiro/kiro-catalog.ts +17 -1
  305. package/src/providers/integrations/kiro/kiro-discovery.ts +10 -12
  306. package/src/providers/integrations/kiro/kiro-quota.ts +8 -4
  307. package/src/providers/integrations/kiro/kiro.ts +15 -19
  308. package/src/providers/integrations/ollamacloud/index.ts +2 -0
  309. package/src/providers/integrations/{ollamacloud-models.ts → ollamacloud/models.ts} +2 -2
  310. package/src/providers/integrations/{ollamacloud-quota.ts → ollamacloud/quota.ts} +3 -3
  311. package/src/providers/integrations/opencode/fingerprint.ts +1 -1
  312. package/src/providers/integrations/opencode/opencode-go-quota.ts +2 -8
  313. package/src/providers/integrations/perch/perch-catalog.ts +105 -0
  314. package/src/providers/integrations/perch/perch-credential.ts +25 -0
  315. package/src/providers/integrations/perch/perch-oauth.ts +170 -0
  316. package/src/providers/integrations/perch/perch-protocol.ts +208 -0
  317. package/src/providers/integrations/perch/perch-quota.ts +123 -0
  318. package/src/providers/integrations/perch/perch-realm.ts +82 -0
  319. package/src/providers/integrations/perch/perch-system-prompt.ts +13 -0
  320. package/src/providers/integrations/perch/perch.ts +305 -0
  321. package/src/providers/integrations/perch/saffron-system-prompt.txt +8 -0
  322. package/src/providers/integrations/qoder/chat-proto.ts +328 -328
  323. package/src/providers/integrations/qoder/claim-qoder-credits.ts +19 -60
  324. package/src/providers/integrations/qoder/qoder-adapter.ts +90 -40
  325. package/src/providers/integrations/qoder/qoder-auth.ts +101 -29
  326. package/src/providers/integrations/qoder/qoder-cache.ts +32 -0
  327. package/src/providers/integrations/qoder/qoder-catalog.ts +26 -6
  328. package/src/providers/integrations/qoder/qoder-chat.ts +7 -21
  329. package/src/providers/integrations/qoder/qoder-checkin.ts +6 -6
  330. package/src/providers/integrations/qoder/qoder-grpc.ts +210 -7
  331. package/src/providers/integrations/qoder/qoder-ide.ts +5 -108
  332. package/src/providers/integrations/qoder/qoder-identity-cache.ts +184 -0
  333. package/src/providers/integrations/qoder/qoder-native-identity-store.ts +83 -18
  334. package/src/providers/integrations/qoder/qoder-realm.ts +9 -6
  335. package/src/providers/integrations/qoder/qoder-umid.ts +109 -342
  336. package/src/providers/integrations/qoder/qoder-virtual.ts +33 -1
  337. package/src/providers/integrations/qoder/qoder.ts +3 -7
  338. package/src/providers/integrations/trae/trae-catalog.ts +9 -14
  339. package/src/providers/integrations/trae/trae-headers.ts +36 -11
  340. package/src/providers/integrations/trae/trae-oauth.ts +14 -17
  341. package/src/providers/integrations/trae/trae-protocol.ts +12 -11
  342. package/src/providers/integrations/trae/trae-quota.ts +96 -36
  343. package/src/providers/integrations/trae/trae-realm.ts +74 -15
  344. package/src/providers/integrations/trae/trae.ts +99 -26
  345. package/src/providers/integrations/zcode-start-plan/provider.ts +226 -23
  346. package/src/providers/integrations/zcode-start-plan/quota.ts +19 -2
  347. package/src/providers/integrations/zro/zro.ts +204 -0
  348. package/src/providers/operations/account-error-classification.ts +235 -278
  349. package/src/providers/operations/account-health-service.ts +273 -26
  350. package/src/providers/operations/account-refresh-status.ts +269 -0
  351. package/src/providers/operations/account-tier.ts +66 -0
  352. package/src/providers/operations/client-version-resolver.ts +1 -1
  353. package/src/providers/operations/client-versions.ts +42 -150
  354. package/src/providers/operations/cooldown-rules.ts +56 -0
  355. package/src/providers/operations/{model-catalog-cache.ts → provider-caches.ts} +68 -16
  356. package/src/providers/operations/provider-catalog-seeder.ts +4 -0
  357. package/src/providers/operations/provider-catalog-service.ts +1 -1
  358. package/src/providers/operations/provider-credential-service.ts +102 -32
  359. package/src/providers/operations/provider-rules/github.ts +48 -0
  360. package/src/providers/operations/provider-rules/grok.ts +33 -0
  361. package/src/providers/operations/provider-rules/inception.ts +49 -0
  362. package/src/providers/operations/provider-rules/index.ts +32 -0
  363. package/src/providers/operations/provider-rules/perch.ts +37 -0
  364. package/src/providers/operations/provider-rules/qoder.ts +70 -0
  365. package/src/providers/operations/provider-rules/trae.ts +81 -0
  366. package/src/providers/provider-contracts.ts +33 -2
  367. package/src/providers/{provider-credential-resolver.ts → provider-credentials.ts} +40 -3
  368. package/src/providers/provider-metadata.ts +99 -14
  369. package/src/providers/provider-model-definition.ts +36 -0
  370. package/src/providers/provider-probe.ts +15 -1
  371. package/src/providers/provider-registry.ts +42 -33
  372. package/src/providers/quota/quota-limit-windows.ts +16 -5
  373. package/src/providers/quota/quota-support.ts +1 -1
  374. package/src/providers/quota/quota-window-parser.ts +90 -18
  375. package/src/providers/quota/refresh.ts +96 -18
  376. package/src/security/abuse.ts +71 -0
  377. package/src/security/api-key-auth-cache.ts +1 -1
  378. package/src/security/api-key-auth.ts +6 -2
  379. package/src/transport/dispatch/attempt-finalize.ts +14 -13
  380. package/src/transport/dispatch/attempt-loop.ts +71 -17
  381. package/src/transport/dispatch/generation.ts +2 -8
  382. package/src/transport/dispatch/native-shared.ts +25 -0
  383. package/src/transport/dispatch/proxy-request.ts +9 -46
  384. package/src/transport/dispatch/responses-compact.ts +2 -8
  385. package/src/transport/dispatch/streaming/finalize.ts +9 -6
  386. package/src/transport/dispatch/streaming/stream.ts +9 -36
  387. package/src/transport/dispatch/systemone.ts +2 -8
  388. package/src/transport/dispatch/token-count.ts +2 -6
  389. package/src/transport/dispatch/upstream.ts +67 -1
  390. package/src/transport/drain-endpoint.ts +31 -4
  391. package/src/transport/failure-policy.ts +129 -37
  392. package/src/transport/guards/body-policy.ts +7 -1
  393. package/src/transport/guards/error-lifecycle.ts +13 -1
  394. package/src/transport/guards/request-context.ts +22 -14
  395. package/src/transport/request/preparer.ts +81 -71
  396. package/src/transport/routing/bounded-lru.ts +14 -0
  397. package/src/transport/routing/drain-reserve.ts +129 -0
  398. package/src/transport/routing/plan-gate.ts +7 -1
  399. package/src/transport/routing/round-robin.ts +60 -0
  400. package/src/transport/routing/route-catalog.ts +123 -111
  401. package/src/transport/routing/route-model.ts +51 -9
  402. package/src/transport/routing/router.ts +418 -33
  403. package/src/transport/surface/adapters.ts +11 -2
  404. package/src/transport/surface/chat/adapter.ts +2 -2
  405. package/src/transport/surface/chat/encode.ts +47 -4
  406. package/src/transport/surface/chat/parse.ts +2 -12
  407. package/src/transport/surface/completion.ts +44 -33
  408. package/src/transport/surface/content-parts.ts +21 -0
  409. package/src/transport/surface/messages/adapter.ts +9 -2
  410. package/src/transport/surface/messages/encode.ts +11 -3
  411. package/src/transport/surface/messages/parse.ts +2 -1
  412. package/src/transport/surface/messages/stream.ts +33 -17
  413. package/src/transport/surface/responses/encode.ts +34 -6
  414. package/src/transport/surface/responses/parse.ts +3 -11
  415. package/src/workers/daily-checkin.ts +1 -1
  416. package/src/workers/quota-refresh-sweep.ts +1 -1
  417. package/src/workers/scheduler.ts +22 -4
  418. package/dist/dashboard/assets/BannedPage-DeIbIiBU.js +0 -1
  419. package/dist/dashboard/assets/BannedPage-DeIbIiBU.js.gz +0 -0
  420. package/dist/dashboard/assets/CliToolDetailPage-BRWKPQPf.js.gz +0 -0
  421. package/dist/dashboard/assets/CliToolsPage-BP-Y5iHN.js.gz +0 -0
  422. package/dist/dashboard/assets/CombosPage-B7JHozVa.js +0 -1
  423. package/dist/dashboard/assets/CombosPage-B7JHozVa.js.gz +0 -0
  424. package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js +0 -1
  425. package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js.gz +0 -0
  426. package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js +0 -1
  427. package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js.gz +0 -0
  428. package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js +0 -1
  429. package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js.gz +0 -0
  430. package/dist/dashboard/assets/InjectSystemPromptPanel-Cv-2Ol_K.js.gz +0 -0
  431. package/dist/dashboard/assets/LoginPage-bKfz_b1K.js.gz +0 -0
  432. package/dist/dashboard/assets/ModelPicker-B-WQxx_H.js.gz +0 -0
  433. package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js +0 -1
  434. package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js.gz +0 -0
  435. package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js +0 -7
  436. package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js.gz +0 -0
  437. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +0 -1
  438. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  439. package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js +0 -1
  440. package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js.gz +0 -0
  441. package/dist/dashboard/assets/ProxyPage-emlTuxz6.js.gz +0 -0
  442. package/dist/dashboard/assets/QuotaPage-CMJKNYWb.js +0 -1
  443. package/dist/dashboard/assets/QuotaPage-CMJKNYWb.js.gz +0 -0
  444. package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js +0 -1
  445. package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js.gz +0 -0
  446. package/dist/dashboard/assets/SetupPage-CUZrKs9r.js.gz +0 -0
  447. package/dist/dashboard/assets/StudioPage-jWmUdDpy.js.gz +0 -0
  448. package/dist/dashboard/assets/UsagePage-5F9tGVGG.js +0 -56
  449. package/dist/dashboard/assets/UsagePage-5F9tGVGG.js.gz +0 -0
  450. package/dist/dashboard/assets/api-keys-KvX83mRe.js +0 -1
  451. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  452. package/dist/dashboard/assets/app-BEsU8hKs.css +0 -2
  453. package/dist/dashboard/assets/app-BEsU8hKs.css.gz +0 -0
  454. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  455. package/dist/dashboard/assets/badge-DyI_mJfi.js.gz +0 -0
  456. package/dist/dashboard/assets/banner-B-yXtCqb.js.gz +0 -0
  457. package/dist/dashboard/assets/brand/bansos_page.png +0 -0
  458. package/dist/dashboard/assets/brand/denia_bansos.jpg +0 -0
  459. package/dist/dashboard/assets/brand/favicon.jpg +0 -0
  460. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  461. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  462. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  463. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  464. package/dist/dashboard/assets/brand/sidebar_ico.jpg +0 -0
  465. package/dist/dashboard/assets/card-_HwAEqFF.js.gz +0 -0
  466. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +0 -1
  467. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  468. package/dist/dashboard/assets/clipboard-button-ByjCk0o9.js.gz +0 -0
  469. package/dist/dashboard/assets/dialog-BZhOlfz-.js.gz +0 -0
  470. package/dist/dashboard/assets/drawer-BADqIRYP.js.gz +0 -0
  471. package/dist/dashboard/assets/entry-COaC-irN.js.gz +0 -0
  472. package/dist/dashboard/assets/entry-Ca7LSCet.js +0 -4
  473. package/dist/dashboard/assets/entry-Ca7LSCet.js.gz +0 -0
  474. package/dist/dashboard/assets/entry-PDd27uCd.js +0 -1
  475. package/dist/dashboard/assets/entry-PDd27uCd.js.gz +0 -0
  476. package/dist/dashboard/assets/formatters-DcHJyRiu.js.gz +0 -0
  477. package/dist/dashboard/assets/index-CgKmFngv.js.gz +0 -0
  478. package/dist/dashboard/assets/inline-B2BirKry.js.gz +0 -0
  479. package/dist/dashboard/assets/input-D-qV9dKY.js.gz +0 -0
  480. package/dist/dashboard/assets/layout-B7tVWhtV.js.gz +0 -0
  481. package/dist/dashboard/assets/list-row-CtkGE3bF.js.gz +0 -0
  482. package/dist/dashboard/assets/live-DGizF06-.js.gz +0 -0
  483. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +0 -1
  484. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
  485. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  486. package/dist/dashboard/assets/network-C9UE-bOr.js.gz +0 -0
  487. package/dist/dashboard/assets/numbers-BnAd22a_.js.gz +0 -0
  488. package/dist/dashboard/assets/pagination-BAywyMzS.js.gz +0 -0
  489. package/dist/dashboard/assets/query-keys-YSoQOUh6.js.gz +0 -0
  490. package/dist/dashboard/assets/quota-DJ1QlAOq.js +0 -1
  491. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  492. package/dist/dashboard/assets/routing-fnCsxgNO.js +0 -1
  493. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  494. package/dist/dashboard/assets/select-BCOcv8WK.js.gz +0 -0
  495. package/dist/dashboard/assets/settings-BxslsErn.js +0 -1
  496. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  497. package/dist/dashboard/assets/stack-ByKt3Q1g.js.gz +0 -0
  498. package/dist/dashboard/assets/state-DXbGTx7N.js.gz +0 -0
  499. package/dist/dashboard/assets/switch-ZeTsW623.js.gz +0 -0
  500. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  501. package/dist/dashboard/console-backgrounds.jpg +0 -0
  502. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  503. package/dist/dashboard/donation/qris-risun-marke.png +0 -0
  504. package/src/providers/bundled-discovery-providers.ts +0 -98
  505. package/src/providers/configured-openai-providers.ts +0 -120
  506. package/src/providers/integrations/buddy/turing-device-token.ts +0 -262
  507. package/src/providers/integrations/buddy/workbuddy/cn-oauth.ts +0 -30
  508. package/src/providers/integrations/buddy/workbuddy/cn-provider.ts +0 -58
  509. package/src/providers/integrations/buddy/workbuddy/oauth.ts +0 -31
  510. package/src/providers/integrations/buddy/workbuddy/provider.ts +0 -209
  511. package/src/providers/integrations/buddy/workbuddy/quota.ts +0 -161
  512. package/src/providers/integrations/buddy/workbuddy/shared.ts +0 -285
  513. package/src/providers/operations/model-discovery-cache.ts +0 -34
  514. package/src/providers/operations/probe-fetch.ts +0 -15
  515. package/src/providers/operations/provider-version-cache.ts +0 -30
  516. package/src/providers/provider-capabilities.ts +0 -33
  517. package/src/providers/provider-credential-envelope.ts +0 -43
  518. /package/dist/dashboard/assets/{app-CTxoqyYB.js → app-DIXLjojg.js} +0 -0
  519. /package/dist/dashboard/assets/{app-CTxoqyYB.js.gz → app-DIXLjojg.js.gz} +0 -0
@@ -1,14 +1,13 @@
1
1
  // dynamic-import-ok: lazy per-realm capability map. Each buddy regional
2
- // product (cb/cbcn/workbuddy/workbuddycn) imports its adapter + oauth +
3
- // discovery on first use so a deployment that only serves one realm never
4
- // drags the others into memory.
5
- import type { ProviderModuleCapabilities } from "../../provider-capabilities";
6
- import { oauthCapability, quotaCapability } from "../../provider-capabilities";
2
+ // product (cb/cbcn) imports its adapter + oauth + discovery on first use so a
3
+ // deployment that only serves one realm never drags the others into memory.
4
+ import type { ProviderModuleCapabilities } from "../../provider-registry";
5
+ import { oauthCapability, quotaCapability } from "../../provider-registry";
7
6
 
8
- type BuddyProviderId = "cb" | "cbcn" | "workbuddy" | "workbuddycn";
7
+ type BuddyProviderId = "cb" | "cbcn";
9
8
 
10
9
  /**
11
- * Lazy capability declarations for Buddy's four independently identified
10
+ * Lazy capability declarations for Buddy's two independently identified
12
11
  * regional products.
13
12
  */
14
13
  export const BUDDY_PROVIDER_CAPABILITIES = {
@@ -48,40 +47,4 @@ export const BUDDY_PROVIDER_CAPABILITIES = {
48
47
  "fetchCodeBuddyCnQuota",
49
48
  ),
50
49
  },
51
- workbuddy: {
52
- loadAdapter: async () => (await import("./workbuddy/provider")).createWorkBuddyAdapter(),
53
- loadModels: async () => (await import("./workbuddy/provider")).WORKBUDDY_MODELS,
54
- loadModelDiscovery: async () => async ({ credential, fetcher }) =>
55
- (await import("./workbuddy/provider")).discoverWorkBuddyModels({
56
- credential,
57
- ...(fetcher === undefined ? {} : { fetcher }),
58
- }),
59
- loadAuthentication: oauthCapability(
60
- () => import("./workbuddy/oauth"),
61
- "workBuddyOAuthClient",
62
- { withRefresher: true },
63
- ),
64
- loadQuotaCollector: quotaCapability(
65
- () => import("./workbuddy/quota"),
66
- "fetchWorkBuddyQuota",
67
- ),
68
- },
69
- workbuddycn: {
70
- loadAdapter: async () => (await import("./workbuddy/cn-provider")).createWorkBuddyCnAdapter(),
71
- loadModels: async () => (await import("./workbuddy/cn-provider")).WORKBUDDY_CN_MODELS,
72
- loadModelDiscovery: async () => async ({ credential, fetcher }) =>
73
- (await import("./workbuddy/cn-provider")).discoverWorkBuddyCnModels({
74
- credential,
75
- ...(fetcher === undefined ? {} : { fetcher }),
76
- }),
77
- loadAuthentication: oauthCapability(
78
- () => import("./workbuddy/cn-oauth"),
79
- "workBuddyCnOAuthClient",
80
- { withRefresher: true },
81
- ),
82
- loadQuotaCollector: quotaCapability(
83
- () => import("./workbuddy/quota"),
84
- "fetchWorkBuddyCnQuota",
85
- ),
86
- },
87
50
  } satisfies Readonly<Record<BuddyProviderId, ProviderModuleCapabilities>>;
@@ -24,7 +24,8 @@ export const CODEBUDDY_CN_RAW: readonly BuddyRawEntry[] = [
24
24
  ["kimi-k2.8-preview", "Kimi K2.8 Preview", true, true, 1_000_000, 64_000],
25
25
  ["kimi-k3.1-pro", "Kimi K3.1 Pro", true, true, 1_000_000, 32_000],
26
26
  ["hy3", "Hy3", true, true, 192_000, 64_000],
27
- ["hy4-preview", "Hy4 Preview", true, true, 960_000, 64_000],
27
+ ["hy4", "Hy4", true, true, 960_000, 64_000],
28
+ ["hy4free", "Hy4 Free", true, true, 960_000, 64_000],
28
29
  ["space-bunny", "Space Bunny", true, true, 1_000_000, 128_000],
29
30
  ["step-5-preview", "Step 5 Preview", true, true, 1_000_000, 64_000],
30
31
  ["deepseek-v4-pro", "DeepSeek V4 Pro", true, true, 1_000_000, 128_000],
@@ -20,7 +20,9 @@ import { CODEBUDDY_CN_RAW } from "./cn-catalog";
20
20
  import { CODEBUDDY_SYSTEM_PROMPT } from "./provider";
21
21
  import {
22
22
  BUDDY_CN_IMAGE_MODEL_ID_SET,
23
+ BUDDY_CN_VIDEO_MODEL_ID_SET,
23
24
  makeBuddyCnImageModels,
25
+ makeBuddyCnVideoModels,
24
26
  makeBuddyModel,
25
27
  } from "../buddy-catalog-shared";
26
28
  import { BUDDY_CN_MODELS_PATH, fetchBuddyDirectoryModels } from "../buddy-discovery-shared";
@@ -115,11 +117,28 @@ export const CODEBUDDY_CN_IMAGE_MODELS: readonly ModelDefinition[] = makeBuddyCn
115
117
  "/images/generations",
116
118
  );
117
119
 
120
+ /**
121
+ * CN's video-generation rows (`kling-video-v3`, `minimax-video-h3`).
122
+ *
123
+ * Reached through the native video route like the intl rows. The video ids
124
+ * are filtered out of the chat pass so one id never appears under two service
125
+ * kinds.
126
+ */
127
+ export const CODEBUDDY_CN_VIDEO_MODELS: readonly ModelDefinition[] = makeBuddyCnVideoModels(
128
+ CODEBUDDY_CN_PROVIDER_ID,
129
+ "/videos/generations",
130
+ );
131
+
118
132
  export const CODEBUDDY_CN_MODELS: readonly ModelDefinition[] = [
119
- ...CODEBUDDY_CN_RAW.filter((entry) => !BUDDY_CN_IMAGE_MODEL_ID_SET.has(entry[0])).map((entry) =>
133
+ ...CODEBUDDY_CN_RAW.filter(
134
+ (entry) =>
135
+ !BUDDY_CN_IMAGE_MODEL_ID_SET.has(entry[0]) &&
136
+ !BUDDY_CN_VIDEO_MODEL_ID_SET.has(entry[0]),
137
+ ).map((entry) =>
120
138
  makeBuddyModel(entry, CODEBUDDY_CN_PROVIDER_ID, undefined, "cn"),
121
139
  ),
122
140
  ...CODEBUDDY_CN_IMAGE_MODELS,
141
+ ...CODEBUDDY_CN_VIDEO_MODELS,
123
142
  ];
124
143
 
125
144
  /** Reads the CodeBuddy CN console directory (same envelope as the intl site). */
@@ -149,6 +168,9 @@ export function createCodeBuddyCnAdapter(fetchImpl?: typeof fetch): ProviderAdap
149
168
  baseUrl: CODEBUDDY_CN_BASE_URL,
150
169
  variant: "CLI",
151
170
  prePayload: codeBuddyCnPrePayload,
171
+ // The CN CLI profile gzips the chat body (donor behavior). The console
172
+ // channel fallback is an intl-only recovery; CN has no second endpoint.
173
+ requestCompression: "gzip",
152
174
  ...(fetchImpl ? { fetchImpl } : {}),
153
175
  }),
154
176
  {
@@ -84,7 +84,7 @@ function codeBuddyIntlPrePayload(
84
84
  void request;
85
85
  }
86
86
 
87
- // Model catalog — shared CodeBuddy / WorkBuddy international roster
87
+ // Model catalog — shared CodeBuddy international roster
88
88
 
89
89
  const CODEBUDDY_INTL_RAW: readonly BuddyRawEntry[] = BUDDY_SHARED_RAW;
90
90
 
@@ -95,7 +95,7 @@ const CODEBUDDY_INTL_RAW: readonly BuddyRawEntry[] = BUDDY_SHARED_RAW;
95
95
  * why they were unreachable as image models: nothing downstream could tell a
96
96
  * chat model from one that returns an image, so `mediaGeneration` was false for
97
97
  * every catalog row. The roster and the declared capabilities come from
98
- * {@link makeBuddyImageModels} so cb and WorkBuddy cannot drift.
98
+ * {@link makeBuddyImageModels} so cb and cbcn cannot drift.
99
99
  */
100
100
  export const CODEBUDDY_IMAGE_MODELS: readonly ModelDefinition[] = makeBuddyImageModels(
101
101
  "cb",
@@ -160,6 +160,10 @@ export function createCodeBuddyAdapter(fetchImpl?: typeof fetch): ProviderAdapte
160
160
  variant: "IDE",
161
161
  cliIdentity: true,
162
162
  prePayload: codeBuddyIntlPrePayload,
163
+ // The intl CLI profile gzips the chat body and recovers a channel-check
164
+ // 400 by retrying once on the console chat endpoint (donor behavior).
165
+ requestCompression: "gzip",
166
+ channelFallbackPath: "/console/chat/completions",
163
167
  ...(fetchImpl ? { fetchImpl } : {}),
164
168
  }),
165
169
  {
@@ -13,8 +13,7 @@ import {
13
13
  resolveBuddyIdentity,
14
14
  } from "../buddy-identity";
15
15
  import { buildCodeBuddyUserAgent, getCodeBuddyCnVersion, getCodeBuddyVersion } from "../../../operations/client-versions";
16
- import { buddyDeviceTokenHeaders } from "../workbuddy/shared";
17
- import { CODEBUDDY_TURING_CONFIG } from "../turing-device-token";
16
+ import { buddyDeviceTokenHeaders } from "../buddy-identity";
18
17
  import { buddyCliHeaders, buddyCliTraceHeaders } from "../buddy-cli-headers";
19
18
 
20
19
  /** Client identity variant behind the per-request CodeBuddy headers. */
@@ -88,7 +87,7 @@ export async function codebuddyHeaders(
88
87
  };
89
88
  }
90
89
  const purpose = buddyAgentPurpose(context, request);
91
- return {
90
+ const headers: Record<string, string> = {
92
91
  accept: "text/event-stream",
93
92
  "User-Agent": ua,
94
93
  "X-Product": "SaaS",
@@ -101,31 +100,29 @@ export async function codebuddyHeaders(
101
100
  "X-Domain": codebuddyDomain(variant),
102
101
  "x-requested-with": "XMLHttpRequest",
103
102
  "x-codebuddy-request": "1",
104
- // The effective agent purpose, matching the reference's dynamic value.
105
- // The reference does not invent `conversation`; it sends the purpose only
106
- // when one exists.
107
- ...(purpose === undefined ? {} : { "X-Agent-Purpose": purpose }),
108
- // Same family WorkBuddy sends: the upstream's channel check reads the
109
- // turn-level aggregation key, and a chat request without it is refused for a
110
- // missing conversation id.
111
- ...conversation,
112
- // Per-account device binding (qimei36) — distinct device per account.
113
- ...(() => {
114
- const binding = resolveBuddyDeviceBinding(context);
115
- return binding === undefined ? {} : { "X-Device-Id-List": JSON.stringify({ qimei36: binding }) };
116
- })(),
117
- // The desktop client sends the device-token pair on both realms. SDK
118
- // token when configured, captured token otherwise, or the official failure
119
- // placeholder. CodeBuddy uses its own SDK payload profile (same SDK,
120
- // distinct product identity). (CLI branch above already returned without
121
- // device headers.)
122
- ...(await buddyDeviceTokenHeaders({
123
- realm: identity === "IDE" ? "intl" : "cn",
124
- context,
125
- cliIdentity,
126
- turingConfig: CODEBUDDY_TURING_CONFIG,
127
- })),
128
103
  };
104
+ // The effective agent purpose, matching the reference's dynamic value.
105
+ // The reference does not invent `conversation`; it sends the purpose only
106
+ // when one exists.
107
+ if (purpose !== undefined) headers["X-Agent-Purpose"] = purpose;
108
+ // The upstream's channel check reads the turn-level aggregation key, and a
109
+ // chat request without it is refused for a missing conversation id.
110
+ Object.assign(headers, conversation);
111
+ // Per-account device binding (qimei36) — distinct device per account.
112
+ const binding = resolveBuddyDeviceBinding(context);
113
+ if (binding !== undefined) {
114
+ headers["X-Device-Id-List"] = JSON.stringify({ qimei36: binding });
115
+ }
116
+ // The desktop client sends the device-token pair on both realms. Captured
117
+ // token (auth_state / device-token file) when present, otherwise the
118
+ // official failure placeholder. (CLI branch above already returned without
119
+ // device headers.)
120
+ Object.assign(headers, await buddyDeviceTokenHeaders({
121
+ realm: identity === "IDE" ? "intl" : "cn",
122
+ context,
123
+ cliIdentity,
124
+ }));
125
+ return headers;
129
126
  }
130
127
 
131
128
  /**
@@ -144,6 +141,14 @@ export function codebuddyAdapterConfig(args: {
144
141
  ) => void;
145
142
  fetchImpl?: typeof fetch;
146
143
  cliIdentity?: boolean;
144
+ /**
145
+ * Body compression for chat dispatches. The CodeBuddy CLI contract (donor
146
+ * `codebuddy2api`) gzips the JSON body for the CLI profiles and sends
147
+ * `Accept-Encoding: identity`. `"json"` (default) keeps plain JSON.
148
+ */
149
+ requestCompression?: "json" | "gzip";
150
+ /** When set, retry a channel-check 400 against this path (console fallback). */
151
+ channelFallbackPath?: string;
147
152
  }): OpenAICompatibleAdapterConfig {
148
153
  return withBearerAuthentication({
149
154
  provider_id: args.providerId,
@@ -151,6 +156,12 @@ export function codebuddyAdapterConfig(args: {
151
156
  buildExtraHeaders: (context, request) =>
152
157
  codebuddyHeaders(args.variant, context, request, args.cliIdentity),
153
158
  prePayload: args.prePayload,
159
+ ...(args.requestCompression === undefined
160
+ ? {}
161
+ : { request_compression: args.requestCompression }),
162
+ ...(args.channelFallbackPath === undefined
163
+ ? {}
164
+ : { channel_fallback_path: args.channelFallbackPath }),
154
165
  ...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),
155
166
  });
156
167
  }
@@ -102,9 +102,13 @@ export async function fetchClaudeQuota(
102
102
  credential: string,
103
103
  fetcher: FetchLike,
104
104
  ): Promise<ProviderQuotaResult> {
105
+ // No module-local quota cache: the shared two-tier quota cache owns
106
+ // cross-call dedup, and a local tier keyed by credential only is never
107
+ // invalidated by `debitCachedQuota`, so a sweep within its TTL could
108
+ // resurrect a spent balance over the shared cache. Every call here is a
109
+ // fresh upstream read; the shared cache's in-flight dedup prevents
110
+ // duplicate traffic.
105
111
  const key = sha256Hex(credential);
106
- const cached = quotaCache.get(key);
107
- if (cached !== undefined) return cached;
108
112
  if (quotaCooldown.get(key) !== undefined) {
109
113
  throw new Error("Quota endpoint rejected request: rate limited (cooled down)");
110
114
  }
@@ -131,9 +135,7 @@ export async function fetchClaudeQuota(
131
135
  },
132
136
  observing,
133
137
  );
134
- const result = parseClaudeQuota(body);
135
- quotaCache.set(key, result);
136
- return result;
138
+ return parseClaudeQuota(body);
137
139
  } catch (error: unknown) {
138
140
  // Hammering the usage endpoint on every call is its own rate-limit
139
141
  // risk: back off briefly after a 429 instead of retrying into it.
@@ -143,21 +145,16 @@ export async function fetchClaudeQuota(
143
145
  }
144
146
 
145
147
  /**
146
- * Bounded per-credential quota cache (5 min) plus a short 429 cooldown
147
- * (3 min). Keys are credential hashes, never raw secrets; both caches are
148
+ * Short 429 cooldown (3 min). Keys are credential hashes, never raw secrets;
148
149
  * capped so credential fan-out cannot pin memory.
150
+ *
151
+ * The cooldown is an absolute window (`until = now + QUOTA_COOLDOWN_MS`), not a
152
+ * TTL from read time, so it is a sentinel whose own TTL *is* that window: the
153
+ * entry lives for exactly the cooldown and is gone the moment it closes.
149
154
  */
150
- const QUOTA_CACHE_TTL_MS = 5 * 60_000;
151
155
  const QUOTA_COOLDOWN_MS = 3 * 60_000;
152
- const QUOTA_CACHE_MAX_ENTRIES = 256;
153
- const quotaCache = new TtlCache<ProviderQuotaResult>({
154
- ttlMs: QUOTA_CACHE_TTL_MS,
155
- maxEntries: QUOTA_CACHE_MAX_ENTRIES,
156
- });
157
- // The cooldown is an absolute window (`until = now + QUOTA_COOLDOWN_MS`), not a
158
- // TTL from read time, so it is a sentinel whose own TTL *is* that window: the
159
- // entry lives for exactly the cooldown and is gone the moment it closes.
156
+ const QUOTA_COOLDOWN_MAX_ENTRIES = 256;
160
157
  const quotaCooldown = new TtlCache<true>({
161
158
  ttlMs: QUOTA_COOLDOWN_MS,
162
- maxEntries: QUOTA_CACHE_MAX_ENTRIES,
159
+ maxEntries: QUOTA_COOLDOWN_MAX_ENTRIES,
163
160
  });
@@ -1,12 +1,12 @@
1
1
  import { createApiKeyAdapter } from "../../configured-provider";
2
2
  import type { ProviderDispatchTarget, ProviderAdapter, ProviderDispatchContext } from "../../provider-contracts";
3
3
  import type { ModelDefinition } from "../../provider-model-definition";
4
- import { unwrapProviderToken } from "../../provider-credential-envelope";
4
+ import { unwrapProviderToken } from "../../provider-credentials";
5
5
  import { GatewayError } from "../../../protocol/gateway-error";
6
6
  import type { CanonicalRequest } from "../../../protocol/canonical-model";
7
7
  import { completeRequiredSchema, isRecord } from "../../../protocol/codecs";
8
8
  import { providerBaseUrl } from "../../provider-metadata";
9
- import { getCachedModelDiscovery } from "../../operations/model-discovery-cache";
9
+ import { getCachedModelDiscovery } from "../../operations/provider-caches";
10
10
  import { defineModel } from "../../provider-model-definition";
11
11
  import { clineReasoningReplayPrepares } from "../buddy/buddy-chat-shared";
12
12
  import { clinePlatform, clinePlatformVersion } from "../../operations/cli-platform";
@@ -15,6 +15,8 @@
15
15
  * independent: retain the balance or subscription when the other is unavailable.
16
16
  */
17
17
  import type { FetchLike, ProviderQuotaResult, ProviderQuotaWindow } from "../../quota/quota-contracts";
18
+ import { isoDate } from "../../quota/quota-contracts";
19
+ import { asCoercedNumber, asRecord } from "../../../shared/coerce";
18
20
 
19
21
  const COMMANDCODE_API_BASE = "https://api.commandcode.ai" as const;
20
22
  const REQUEST_TIMEOUT_MS = 15_000;
@@ -73,29 +75,21 @@ async function readJson(
73
75
  }
74
76
  }
75
77
 
76
- function recordValue(value: unknown): Record<string, unknown> | undefined {
77
- return typeof value === "object" && value !== null && !Array.isArray(value)
78
- ? (value as Record<string, unknown>)
79
- : undefined;
80
- }
81
-
78
+ /** Numeric value coerced via the shared helper, or `null` (shared sentinel). */
82
79
  function numberOrNull(value: unknown): number | null {
83
- if (typeof value === "number" && Number.isFinite(value)) return value;
84
- if (typeof value === "string" && value.trim() && Number.isFinite(Number(value))) {
85
- return Number(value);
86
- }
87
- return null;
80
+ return asCoercedNumber(value) ?? null;
88
81
  }
89
82
 
83
+ /**
84
+ * ISO timestamp from a numeric epoch (seconds vs ms via the 1e12 boundary) or
85
+ * a parseable date string, else `null` — the shared `isoDate` semantics. The
86
+ * one local delta kept: a non-positive numeric is `null` (no deadline) rather
87
+ * than an epoch 0/negative instant.
88
+ */
90
89
  function isoTimestamp(value: unknown): string | null {
91
90
  const numeric = numberOrNull(value);
92
- if (numeric !== null) {
93
- if (numeric <= 0) return null;
94
- const date = new Date(numeric > 1_000_000_000_000 ? numeric : numeric * 1000);
95
- return Number.isFinite(date.getTime()) ? date.toISOString() : null;
96
- }
97
- if (typeof value !== "string" || !Number.isFinite(Date.parse(value))) return null;
98
- return new Date(value).toISOString();
91
+ if (numeric !== null && numeric <= 0) return null;
92
+ return isoDate(value);
99
93
  }
100
94
 
101
95
  function withQuery(path: string, params: Readonly<Record<string, string | null>>): string {
@@ -149,8 +143,8 @@ function windowLimits(
149
143
  limits: Record<string, unknown>,
150
144
  ): readonly ProviderQuotaWindow[] {
151
145
  const out: ProviderQuotaWindow[] = [];
152
- const fiveHour = recordValue(limits["fiveHour"]);
153
- const weekly = recordValue(limits["weekly"]);
146
+ const fiveHour = asRecord(limits["fiveHour"]);
147
+ const weekly = asRecord(limits["weekly"]);
154
148
  const push = (source: Record<string, unknown> | undefined, kind: string, label: string) => {
155
149
  if (source === undefined) return;
156
150
  const used = numberOrNull(source["used"]) ?? 0;
@@ -191,9 +185,9 @@ export async function fetchCommandCodeQuota(
191
185
  };
192
186
  }
193
187
 
194
- const whoamiBody = whoami.ok ? recordValue(whoami.value) : undefined;
195
- const user = recordValue(whoamiBody?.["user"]);
196
- const organization = recordValue(whoamiBody?.["org"]);
188
+ const whoamiBody = whoami.ok ? asRecord(whoami.value) : undefined;
189
+ const user = asRecord(whoamiBody?.["user"]);
190
+ const organization = asRecord(whoamiBody?.["org"]);
197
191
  const orgId = typeof organization?.["id"] === "string" ? organization["id"] : null;
198
192
  const accountLabel =
199
193
  (typeof user?.["email"] === "string" && user["email"]) ||
@@ -215,8 +209,8 @@ export async function fetchCommandCodeQuota(
215
209
  };
216
210
  }
217
211
 
218
- const subscriptionBody = subscriptionRaw.ok ? recordValue(subscriptionRaw.value) : undefined;
219
- const planRecord = recordValue(subscriptionBody?.["data"]);
212
+ const subscriptionBody = subscriptionRaw.ok ? asRecord(subscriptionRaw.value) : undefined;
213
+ const planRecord = asRecord(subscriptionBody?.["data"]);
220
214
  const planId = typeof planRecord?.["planId"] === "string" ? planRecord["planId"] : null;
221
215
  const parsedPlan = planId === null ? null : commandCodePlan(planId);
222
216
  const plan =
@@ -225,12 +219,12 @@ export async function fetchCommandCodeQuota(
225
219
  (creditsRaw.ok ? "Credits" : null);
226
220
  const periodEnd = isoTimestamp(planRecord?.["currentPeriodEnd"]);
227
221
 
228
- const creditsBody = creditsRaw.ok ? recordValue(creditsRaw.value) : undefined;
222
+ const creditsBody = creditsRaw.ok ? asRecord(creditsRaw.value) : undefined;
229
223
  const windows: ProviderQuotaWindow[] = [];
230
224
  if (creditsBody !== undefined) {
231
- const credits = recordValue(creditsBody["credits"]);
225
+ const credits = asRecord(creditsBody["credits"]);
232
226
  if (credits !== undefined) windows.push(...creditWindows(credits, parsedPlan?.cap ?? null, periodEnd));
233
- const limits = recordValue(creditsBody["windowLimits"]);
227
+ const limits = asRecord(creditsBody["windowLimits"]);
234
228
  if (limits !== undefined) windows.push(...windowLimits(limits));
235
229
  }
236
230
 
@@ -41,7 +41,6 @@ import {
41
41
  CURSOR_WEBSITE_URL,
42
42
  SESSION_REFRESH_TIMEOUT_MS,
43
43
  SIGN_IN_POLICY_VIOLATION,
44
- TOKEN_EXPIRY_THRESHOLD_S,
45
44
  isExchangeableApiKey,
46
45
  } from "./cursor-shared";
47
46
 
@@ -92,13 +91,6 @@ export function decodeJwtExpiryMs(token: string): number | undefined {
92
91
  return exp * 1000;
93
92
  }
94
93
 
95
- /** True when a JWT expires within the refresh threshold. */
96
- export function isExpiringSoon(token: string, thresholdSeconds = TOKEN_EXPIRY_THRESHOLD_S): boolean {
97
- const expiry = decodeJwtExpiryMs(token);
98
- if (expiry === undefined) return false;
99
- return expiry - Date.now() < thresholdSeconds * 1000;
100
- }
101
-
102
94
  /**
103
95
  * The account identity Cursor itself asserts, from the access token's `sub`.
104
96
  *
@@ -19,6 +19,7 @@ import {
19
19
  FALLBACK_CLIENT_VERSION,
20
20
  SERVER_CONFIG_PATH,
21
21
  normalizeAgentRunOrigin,
22
+ resolveCursorTimezone,
22
23
  } from "./cursor-shared";
23
24
  import { createCursorChecksumHeader, resolveCursorDeviceIds } from "./cursor-identity";
24
25
 
@@ -66,6 +67,7 @@ async function unaryHeaders(
66
67
  "x-cursor-checksum": createCursorChecksumHeader(machineId, macMachineId),
67
68
  "x-ghost-mode": "true",
68
69
  "x-request-id": crypto.randomUUID(),
70
+ ...(resolveCursorTimezone() === "" ? {} : { "x-cursor-timezone": resolveCursorTimezone() }),
69
71
  };
70
72
  }
71
73