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
@@ -0,0 +1,94 @@
1
+ // Hermes / Nous Portal OAuth client — RFC 8628 device flow + refresh.
2
+ //
3
+ // The Hermes Agent (Nous Research) offers a portal subscription via OAuth:
4
+ // `hermes setup --portal` runs a device-code flow against Nous Portal, and
5
+ // the resulting access token is an inference-scoped JWT spent on the
6
+ // OpenAI-compatible inference API. API keys still work for the free roster;
7
+ // this OAuth path is the subscription route (300+ models + paid tiers).
8
+ //
9
+ // Wire sourced from the official Hermes Agent source:
10
+ // - start: POST {portal}/api/oauth/device/code (form: client_id, scope)
11
+ // - poll: POST {portal}/api/oauth/token (form: grant_type=device_code,
12
+ // client_id, device_code) → {access_token, refresh_token, …}
13
+ // - refresh: POST {portal}/api/oauth/token (form: grant_type=refresh_token,
14
+ // client_id, refresh_token)
15
+
16
+ import { OAuthDeviceFlow } from "../../authentication/oauth-device-flow";
17
+ import type {
18
+ OAuthDeviceFlowContext,
19
+ OAuthDevicePollResult,
20
+ OAuthDeviceStartResult,
21
+ } from "../../authentication/oauth-flow-store";
22
+ import type { OAuthTokenRefreshResult } from "../../authentication/oauth-refresh-service";
23
+ import { postFormTokenRequest } from "../../authentication/oauth-flow-store";
24
+
25
+ const NOUS_PORTAL_URL = "https://portal.nousresearch.com";
26
+ const NOUS_CLIENT_ID = "hermes-cli";
27
+ const NOUS_SCOPE = "inference:invoke";
28
+ const NOUS_DEVICE_CODE_PATH = "/api/oauth/device/code";
29
+ const NOUS_TOKEN_PATH = "/api/oauth/token";
30
+
31
+ const FORM_HEADERS = { "content-type": "application/x-www-form-urlencoded", accept: "application/json" };
32
+
33
+ export class HermesOAuthClient extends OAuthDeviceFlow {
34
+ readonly supportsDeviceCode = true;
35
+ readonly supportsBrowserCode = false;
36
+ protected readonly providerLabel = "Hermes / Nous Portal";
37
+ protected readonly clientId = NOUS_CLIENT_ID;
38
+ protected readonly tokenUrl = `${NOUS_PORTAL_URL}${NOUS_TOKEN_PATH}`;
39
+ protected readonly scopes = NOUS_SCOPE;
40
+
41
+ override async startDeviceAuth(context?: OAuthDeviceFlowContext): Promise<OAuthDeviceStartResult> {
42
+ const started = await this.startGenericDeviceAuth({
43
+ tokenUrl: this.tokenUrl,
44
+ deviceAuthUrl: `${NOUS_PORTAL_URL}${NOUS_DEVICE_CODE_PATH}`,
45
+ clientId: NOUS_CLIENT_ID,
46
+ scope: NOUS_SCOPE,
47
+ formHeaders: FORM_HEADERS,
48
+ startParams: context?.parameters ?? {},
49
+ });
50
+ return { ...started, providerState: JSON.stringify({ device_code: started.deviceAuthId }) };
51
+ }
52
+
53
+ override async pollDeviceAuth(
54
+ deviceAuthId: string,
55
+ _context?: OAuthDeviceFlowContext,
56
+ ): Promise<OAuthDevicePollResult> {
57
+ // The generic poll posts the device code and parses RFC 8628 error codes
58
+ // (`authorization_pending`/`slow_down` → pending). Its `complete` result
59
+ // is already a normalized OAuthExchangeResult.
60
+ return this.pollGenericDeviceAuth(deviceAuthId, {
61
+ tokenUrl: this.tokenUrl,
62
+ deviceAuthUrl: `${NOUS_PORTAL_URL}${NOUS_DEVICE_CODE_PATH}`,
63
+ clientId: NOUS_CLIENT_ID,
64
+ scope: NOUS_SCOPE,
65
+ formHeaders: FORM_HEADERS,
66
+ });
67
+ }
68
+
69
+ override async refresh(refreshToken: string, signal?: AbortSignal): Promise<OAuthTokenRefreshResult> {
70
+ const payload = await postFormTokenRequest({
71
+ url: this.tokenUrl,
72
+ fetchFn: this.fetchFn,
73
+ params: {
74
+ grant_type: "refresh_token",
75
+ client_id: NOUS_CLIENT_ID,
76
+ refresh_token: refreshToken,
77
+ },
78
+ headers: FORM_HEADERS,
79
+ signal,
80
+ label: "Hermes / Nous Portal token refresh",
81
+ });
82
+ const record = payload as Record<string, unknown>;
83
+ const access = typeof record["access_token"] === "string" ? record["access_token"] : "";
84
+ if (!access) throw new Error("Hermes / Nous Portal refresh returned no access_token");
85
+ const expiresIn = typeof record["expires_in"] === "number" ? record["expires_in"] : 3600;
86
+ return {
87
+ access,
88
+ ...(typeof record["refresh_token"] === "string" ? { refresh: record["refresh_token"] as string } : {}),
89
+ expiresAt: new Date(Date.now() + expiresIn * 1000),
90
+ };
91
+ }
92
+ }
93
+
94
+ export const hermesOAuthClient = new HermesOAuthClient();
@@ -1,10 +1,10 @@
1
- import type { CanonicalRequest } from "../../protocol/canonical-model";
2
- import type { ProviderDispatchTarget } from "../provider-contracts";
3
- import type { ApiKeyProviderSpec } from "../configured-provider";
4
- import { isRecord } from "../../protocol/codecs";
5
- import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../provider-sanitize";
6
- import { getHermesVersion } from "../operations/client-versions";
7
- import { clineReasoningReplayPrepares } from "./buddy/buddy-chat-shared";
1
+ import type { CanonicalRequest } from "../../../protocol/canonical-model";
2
+ import type { ProviderDispatchTarget } from "../../provider-contracts";
3
+ import type { ApiKeyProviderSpec } from "../../configured-provider";
4
+ import { isRecord } from "../../../protocol/codecs";
5
+ import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../../provider-sanitize";
6
+ import { getHermesVersion } from "../../operations/client-versions";
7
+ import { clineReasoningReplayPrepares } from "../buddy/buddy-chat-shared";
8
8
 
9
9
  const HERMES_PROVIDER_ID = "hermes" as const;
10
10
 
@@ -57,8 +57,8 @@ function injectHermesTags(
57
57
 
58
58
 
59
59
 
60
- import { defineModel } from "../provider-model-definition";
61
- import type { ModelDefinition } from "../provider-model-definition";
60
+ import { defineModel } from "../../provider-model-definition";
61
+ import type { ModelDefinition } from "../../provider-model-definition";
62
62
 
63
63
  /**
64
64
  * Offline fallback: the free rows as the live catalog last reported them.
@@ -78,28 +78,20 @@ export const HERMES_MODELS: readonly ModelDefinition[] = [
78
78
  //
79
79
  // `meituan/longcat-2.0:free` is excluded: the catalog still lists the id, but
80
80
  // dispatching it answers 404 "This model is no longer free", so listing it
81
- // would be a card that can only ever fail. `meituan/longcat-2.5-preview:free`
81
+ // would be a card that can only ever fail. `meituan/longcat-2.5:free`
82
82
  // is listed instead and answers 200.
83
83
  //
84
84
  // `stepfun/step-5-preview:free` is excluded: it is absent from the live catalog
85
85
  // entirely and dispatching it answers 404 "This model's free period has
86
86
  // ended" — a retired row, not a capacity blip, so it cannot be left in.
87
87
  //
88
- // Output caps are the catalog's own `top_provider.max_completion_tokens`,
89
- // which differ per row: `poolside/laguna-xs-2.1:free` is 32768 while its
90
- // sibling `laguna-s` is 131072, so a uniform value overstates one of them.
91
- defineModel({ id: "poolside/laguna-s-2.1:free", ctx: 262144, out: 131072, reasoning: true, free: true, freeTier: true }),
92
- defineModel({ id: "poolside/laguna-xs-2.1:free", ctx: 262144, out: 32768, reasoning: true, free: true, freeTier: true }),
93
- defineModel({ id: "stepfun/step-3.7-flash:free", ctx: 262144, out: 256000, vision: true, reasoning: true, free: true, freeTier: true }),
88
+ // `poolside/laguna-s-2.1:free`, `poolside/laguna-xs-2.1:free`, and
89
+ // `stepfun/step-3.7-flash:free` are removed too: they fail at dispatch.
94
90
  defineModel({ id: "upstage/solar-mini4:free", ctx: 524288, out: 131072, reasoning: true, free: true, freeTier: true }),
95
91
  defineModel({ id: "reflection/beam-1.0-501b-a23b:free", ctx: 262144, out: 131072, reasoning: true, free: true, freeTier: true }),
96
92
  // Vision-corrected against the live catalog: `architecture.input_modalities`
97
93
  // lists `image` for this row, so it was published without vision it has.
98
- defineModel({ id: "meituan/longcat-2.5-preview:free", ctx: 1048576, out: 131072, vision: true, reasoning: true, free: true, freeTier: true }),
99
- // Added after a live read: the catalog carries it, it is free, and a dispatch
100
- // answers 200 — it was simply absent from this list, so a client asking for
101
- // it resolved to nothing. 262144 out is the catalog's own cap.
102
- defineModel({ id: "ornith/ornith-1.5-122b:free", ctx: 262144, out: 262144, vision: true, reasoning: true, free: true, freeTier: true }),
94
+ defineModel({ id: "meituan/longcat-2.5:free", ctx: 1048576, out: 131072, vision: true, reasoning: true, free: true, freeTier: true }),
103
95
  ];
104
96
 
105
97
 
@@ -0,0 +1,2 @@
1
+ export * from "./hermes";
2
+ export * from "./hermes-oauth";
@@ -15,6 +15,22 @@ export const KIRO_GENERATE_PATH = "/generateAssistantResponse" as const;
15
15
  /** AWS region shape, checked before a region is interpolated into a URL. */
16
16
  export const AWS_REGION_PATTERN = /^[a-z]{2}-[a-z]+-\d{1,2}$/;
17
17
 
18
+ /**
19
+ * Maps an auth method onto the `TokenType` header the 1.4.62 client sends.
20
+ *
21
+ * Observed map (`qje`): `api_key → API_KEY`, `external_idp → EXTERNAL_IDP`,
22
+ * `idc → SSO_OIDC`, `machine_token → KIRO_MACHINE_TOKEN`. Google/GitHub/
23
+ * Builder-ID sessions send no `TokenType` header. Every surface (dispatch,
24
+ * usage, discovery) must classify the same account identically or the upstream
25
+ * sees one credential as different token types across surfaces.
26
+ */
27
+ export function kiroTokenTypeHeader(authMethod: string | undefined): string | undefined {
28
+ if (authMethod === "api_key") return "API_KEY";
29
+ if (authMethod === "external_idp") return "EXTERNAL_IDP";
30
+ if (authMethod === "idc") return "SSO_OIDC";
31
+ return undefined;
32
+ }
33
+
18
34
  /** Fallback region when no (or an invalid) region is configured. */
19
35
  export const KIRO_DEFAULT_REGION = "us-east-1" as const;
20
36
 
@@ -37,7 +53,7 @@ export const KIRO_MANAGEMENT_HOST_TEMPLATE = "https://management.{region}.kiro.d
37
53
  * The upstream has no `minimal` or `max` tier on either schema, so the ladder
38
54
  * stops at `xhigh` and the builder maps the canonical extremes onto it.
39
55
  */
40
- const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
56
+ export const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
41
57
 
42
58
  /**
43
59
  * One Kiro model row.
@@ -22,14 +22,19 @@ import {
22
22
  } from "../../operations/client-versions";
23
23
  import { machineIdForAuthState } from "./kiro-machine-id";
24
24
  import { resolveKiroProfileArn } from "./kiro-profile";
25
- import { AWS_REGION_PATTERN, KIRO_DEFAULT_REGION, KIRO_GENERATE_PATH, KIRO_MODELS, KIRO_MANAGEMENT_HOST_TEMPLATE } from "./kiro-catalog";
25
+ import {
26
+ AWS_REGION_PATTERN,
27
+ KIRO_DEFAULT_REGION,
28
+ KIRO_EFFORTS,
29
+ KIRO_GENERATE_PATH,
30
+ KIRO_MODELS,
31
+ KIRO_MANAGEMENT_HOST_TEMPLATE,
32
+ kiroTokenTypeHeader,
33
+ } from "./kiro-catalog";
26
34
 
27
35
  /** Longest model list this will read; the upstream sends a few dozen at most. */
28
36
  const MAX_DISCOVERED_MODELS = 500;
29
37
 
30
- /** Effort tiers the models that accept an effort field advertise. */
31
- const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
32
-
33
38
  /** The management service target used in `x-amz-target`. */
34
39
  const KIRO_MANAGEMENT_TARGET = "KiroControlPlaneBearerService.ListAvailableModels" as const;
35
40
 
@@ -105,14 +110,7 @@ export async function fetchKiroModels(
105
110
  // `TokenType`; social/Builder-ID sessions send none. Mirror the client's
106
111
  // `qje` map and the probe verified against the live service.
107
112
  const authMethod = options.authState?.["authMethod"];
108
- const tokenType =
109
- authMethod === "api_key"
110
- ? "API_KEY"
111
- : authMethod === "external_idp"
112
- ? "EXTERNAL_IDP"
113
- : authMethod === "idc"
114
- ? "SSO_OIDC"
115
- : undefined;
113
+ const tokenType = kiroTokenTypeHeader(typeof authMethod === "string" ? authMethod : undefined);
116
114
  if (tokenType !== undefined) headers["TokenType"] = tokenType;
117
115
  response = await fetcher(`${host}/List-Available-Models?${params.toString()}`, {
118
116
  headers,
@@ -34,7 +34,12 @@ import {
34
34
  } from "../../operations/client-versions";
35
35
  import { machineIdForAuthState } from "./kiro-machine-id";
36
36
  import { resolveKiroProfileArn } from "./kiro-profile";
37
- import { AWS_REGION_PATTERN, KIRO_DEFAULT_REGION, KIRO_MANAGEMENT_HOST_TEMPLATE } from "./kiro-catalog";
37
+ import {
38
+ AWS_REGION_PATTERN,
39
+ KIRO_DEFAULT_REGION,
40
+ KIRO_MANAGEMENT_HOST_TEMPLATE,
41
+ kiroTokenTypeHeader,
42
+ } from "./kiro-catalog";
38
43
 
39
44
  /**
40
45
  * The fetcher shape this module needs: a plain callable. `FetchLike` from the
@@ -82,9 +87,8 @@ function usageHeaders(credential: string, auth: KiroQuotaAuth): Record<string, s
82
87
  "user-agent": buildKiroRuntimeUserAgent(version, auth.machineId),
83
88
  "x-kiro-machineid": auth.machineId,
84
89
  };
85
- if (auth.authMethod === "api_key") headers["TokenType"] = "API_KEY";
86
- else if (auth.authMethod === "external_idp") headers["TokenType"] = "EXTERNAL_IDP";
87
- else if (auth.authMethod === "idc") headers["TokenType"] = "SSO_OIDC";
90
+ const tokenType = kiroTokenTypeHeader(auth.authMethod);
91
+ if (tokenType !== undefined) headers["TokenType"] = tokenType;
88
92
  return headers;
89
93
  }
90
94
 
@@ -59,6 +59,7 @@ import {
59
59
  kiroContextWindow,
60
60
  KIRO_GENERATE_PATH,
61
61
  KIRO_RUNTIME_HOST_TEMPLATE,
62
+ kiroTokenTypeHeader,
62
63
  } from "./kiro-catalog";
63
64
  import { resolveInboundSessionId } from "../../operations/session-resolution";
64
65
  import { KiroStreamDecoder, isKiroTruncationReason, type KiroUsage } from "./kiro-stream";
@@ -180,19 +181,6 @@ export function kiroEndpoint(authState: KiroAuthState | undefined): string {
180
181
  */
181
182
  export const KIRO_RUNTIME_AWS_JSON_TARGET = "KiroRuntimeService.GenerateAssistantResponse" as const;
182
183
 
183
- /**
184
- * Maps an auth method onto the `TokenType` header the 1.4.62 client sends.
185
- *
186
- * Observed map (`qje`): `api_key → API_KEY`, `external_idp → EXTERNAL_IDP`,
187
- * `idc → SSO_OIDC`, `machine_token → KIRO_MACHINE_TOKEN`. Google/GitHub/
188
- * Builder-ID sessions send no `TokenType` header.
189
- */
190
- const KIRO_TOKEN_TYPE: Readonly<Record<string, string>> = {
191
- api_key: "API_KEY",
192
- external_idp: "EXTERNAL_IDP",
193
- idc: "SSO_OIDC",
194
- };
195
-
196
184
  /**
197
185
  * Builds the request headers.
198
186
  *
@@ -230,7 +218,7 @@ export function kiroHeaders(
230
218
  "x-amz-user-agent": buildKiroAmzUserAgent(version, machineId),
231
219
  authorization: `Bearer ${secret}`,
232
220
  };
233
- const tokenType = authMethod === undefined ? undefined : KIRO_TOKEN_TYPE[authMethod];
221
+ const tokenType = kiroTokenTypeHeader(authMethod);
234
222
  if (tokenType !== undefined) {
235
223
  headers["TokenType"] = tokenType;
236
224
  }
@@ -377,9 +365,17 @@ class KiroAdapter implements ProviderAdapter {
377
365
  effortPath !== undefined
378
366
  ? undefined
379
367
  : (request.reasoning?.budget_tokens ?? kiroThinkingBudgetForEffort(requestedEffort));
368
+ // One resolution per dispatch: the resolver mints a fresh UUID only when
369
+ // the request carries no session, conversation id, or derivable opening
370
+ // turn, so resolving twice here would give `conversationId` and
371
+ // `rootConversationId` two different UUIDs — contradicting the client rule
372
+ // (`rootConversationId ?? conversationId`). The same id feeds the session
373
+ // cache estimator at stream end, so its key matches what the request
374
+ // presented upstream.
375
+ const conversationId = resolveKiroConversationId(request, context);
380
376
  const built = buildKiroWireRequest(request, {
381
- conversationId: resolveKiroConversationId(request, context),
382
- rootConversationId: resolveKiroConversationId(request, context),
377
+ conversationId,
378
+ rootConversationId: conversationId,
383
379
  modelId,
384
380
  profileArn: resolveProfileArn(context),
385
381
  ...(effortPath === undefined || effort === undefined ? {} : { effortPath, effort }),
@@ -414,7 +410,7 @@ class KiroAdapter implements ProviderAdapter {
414
410
  }, "upstream");
415
411
  }
416
412
 
417
- yield* this.#stream(response.body, built.value, request, context);
413
+ yield* this.#stream(response.body, built.value, request, conversationId);
418
414
  }
419
415
 
420
416
  /**
@@ -471,7 +467,7 @@ class KiroAdapter implements ProviderAdapter {
471
467
  stream: ReadableStream<Uint8Array>,
472
468
  built: KiroWireRequest,
473
469
  request: CanonicalRequest,
474
- context: ProviderDispatchContext,
470
+ conversationId: string,
475
471
  ): AsyncIterable<CanonicalEvent> {
476
472
  const decoder = new KiroStreamDecoder();
477
473
  const reader = stream.getReader();
@@ -605,7 +601,7 @@ class KiroAdapter implements ProviderAdapter {
605
601
  reader.releaseLock();
606
602
  }
607
603
 
608
- const finalUsage = kiroUsage(usage, request.model, outputText, request.messages, resolveKiroConversationId(request, context));
604
+ const finalUsage = kiroUsage(usage, request.model, outputText, request.messages, conversationId);
609
605
  yield {
610
606
  type: "usage",
611
607
  sequence_number: sequence++,
@@ -0,0 +1,2 @@
1
+ export * from "./models";
2
+ export * from "./quota";
@@ -16,8 +16,8 @@
16
16
  * All six serve the chat wire (none is a Responses-native id), and all report
17
17
  * `supported_in_api: true` on the live roster.
18
18
  */
19
- import { defineModel } from "../provider-model-definition";
20
- import type { ModelDefinition } from "../provider-model-definition";
19
+ import { defineModel } from "../../provider-model-definition";
20
+ import type { ModelDefinition } from "../../provider-model-definition";
21
21
 
22
22
  export const OLLAMACLOUD_PROVIDER_ID = "ollamacloud" as const;
23
23
 
@@ -1,6 +1,6 @@
1
- import type { FetchLike, ProviderQuotaResult } from "../quota/quota-contracts";
2
- import { getJson, record, text } from "../quota/quota-contracts";
3
- import { parseQuotaWindows } from "../quota/quota-window-parser";
1
+ import type { FetchLike, ProviderQuotaResult } from "../../quota/quota-contracts";
2
+ import { getJson, record, text } from "../../quota/quota-contracts";
3
+ import { parseQuotaWindows } from "../../quota/quota-window-parser";
4
4
 
5
5
  async function fetchPlan(fetcher: FetchLike, headers: Record<string, string>): Promise<string> {
6
6
  try {
@@ -9,7 +9,7 @@ import { createHash, randomBytes } from "node:crypto";
9
9
  * can pin the exact identity sent before discovery resolves. Keep both in
10
10
  * lockstep when the CLI releases.
11
11
  */
12
- export const OPENCODE_CLIENT_VERSION = "2.2.5";
12
+ export const OPENCODE_CLIENT_VERSION = "2.2.6";
13
13
 
14
14
  let lastTimestamp = 0;
15
15
  let sequenceCounter = 0;
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  getJson,
3
+ isoDate,
3
4
  type FetchLike,
4
5
  type ProviderQuotaResult,
5
6
  type ProviderQuotaWindow,
@@ -42,13 +43,6 @@ function labelFor(kind: string): string {
42
43
  return kind.charAt(0).toUpperCase() + kind.slice(1);
43
44
  }
44
45
 
45
- function resetIso(value: string | null | undefined): string | null {
46
- if (typeof value !== "string" || value.trim() === "") return null;
47
- const parsed = Date.parse(value);
48
- if (!Number.isFinite(parsed)) return null;
49
- return new Date(parsed).toISOString();
50
- }
51
-
52
46
  /**
53
47
  * One window, or `undefined` when the upstream omitted what makes it usable.
54
48
  *
@@ -75,7 +69,7 @@ function windowFor(
75
69
  accounting: "independent",
76
70
  usedPercent: percent,
77
71
  remainingPercent: 100 - percent,
78
- resetsAt: resetIso(raw.resetsAt),
72
+ resetsAt: isoDate(raw.resetsAt),
79
73
  };
80
74
  }
81
75
 
@@ -0,0 +1,105 @@
1
+ // Perch model roster.
2
+ //
3
+ // Perch's hosted model layer ("Roost") exposes tier labels rather than raw
4
+ // model ids: `standard` and `standard_max` are the tiers included in the free
5
+ // Starter plan. In addition, the plan pins a small "Starter" model pool
6
+ // (`PERCH_STARTER_PINS`) whose pins are verified live 2026-11-08:
7
+ // `glm-5.3-flash-starter`, `deepseek-flash-starter`, and `crouton-alpha`
8
+ // answer 200 and the server reports the pinned backing model; `beam` was not
9
+ // verified (turn rate limit). Paid `pro` tiers are deliberately absent.
10
+ //
11
+ // Model ids here are the gateway-facing ids; the adapter maps them to the
12
+ // upstream wire (Roost tier + backing pin) via `PERCH_STARTER_PINS` /
13
+ // `roostModelChoice` — the upstream itself hides real model names.
14
+
15
+ import { defineModel, type ModelDefinition } from "../../provider-model-definition";
16
+ import {
17
+ PERCH_CONTEXT_STANDARD,
18
+ PERCH_CONTEXT_STANDARD_1M,
19
+ PERCH_PROVIDER_ID,
20
+ PERCH_STARTER_PINS,
21
+ } from "./perch-realm";
22
+
23
+ interface PerchRow {
24
+ readonly id: string;
25
+ readonly displayName: string;
26
+ readonly ctx: number;
27
+ /**
28
+ * Output ceiling. When absent it falls back to the CLI's `sUr` resolution
29
+ * (`perchOutputTokens`); starter-pool rows carry the client card's own
30
+ * `maxOutputTokens` (2.4.125) so a big request is not clamped below what
31
+ * the upstream actually serves.
32
+ */
33
+ readonly out?: number;
34
+ /** `undefined` = plain Roost tier; else starter-pool pin id. */
35
+ readonly pin?: string;
36
+ }
37
+
38
+ /** Roost tier sent for the plain tier rows (CLI canonical tier ids). */
39
+ const TIER_ROOST_TIERS: Readonly<Record<string, string>> = {
40
+ standard: "standard",
41
+ "standard 1m": "standard_max",
42
+ };
43
+
44
+ const PERCH_ROWS: readonly PerchRow[] = [
45
+ { id: "standard", displayName: "Roost Standard", ctx: PERCH_CONTEXT_STANDARD },
46
+ { id: "standard 1m", displayName: "Roost Standard 1M", ctx: PERCH_CONTEXT_STANDARD_1M },
47
+ // Starter-pool pins — context/output per the client's published cards
48
+ // (2.4.125): glm-5.3-flash 1048576, crouton-alpha 1048576 / 943718,
49
+ // beam-1.0 1048576 / 131072, deepseek-v4.1-flash-1017-starter 1048576 /
50
+ // 131072.
51
+ { id: "glm-5.3-flash-starter", displayName: "GLM 5.3 Flash (Starter)", ctx: PERCH_CONTEXT_STANDARD_1M, out: 131_072, pin: "glm-5.3-flash-starter" },
52
+ { id: "deepseek-flash-starter", displayName: "DeepSeek V4.1 Flash 1017 (Starter)", ctx: PERCH_CONTEXT_STANDARD_1M, out: 131_072, pin: "deepseek-flash-starter" },
53
+ { id: "crouton-alpha", displayName: "Crouton Alpha (Stealth)", ctx: PERCH_CONTEXT_STANDARD_1M, out: 943_718, pin: "crouton-alpha" },
54
+ { id: "beam-1.0-starter", displayName: "Beam 1.0 (Starter)", ctx: PERCH_CONTEXT_STANDARD_1M, out: 131_072, pin: "beam-1.0-starter" },
55
+ // Pinned 1M tier: the CLI normalizes `standard 1m` → `standard_max`; the
56
+ // adapter keys `roostModelChoice` off the catalog id so the right tier is
57
+ // sent even though the id is a label.
58
+ { id: "standard 1m", displayName: "Roost Standard 1M", ctx: PERCH_CONTEXT_STANDARD_1M, pin: "standard-max" },
59
+ ];
60
+
61
+ /**
62
+ * Output cap per model, mirroring the CLI's own resolution (`sUr` in the
63
+ * bundled `perch.mjs`): up to 8k context → 4096, up to 32k → 8192, above
64
+ * 32k → 32768. Derive per model from its context window, never hardcode.
65
+ */
66
+ function perchOutputTokens(contextWindow: number): number {
67
+ if (contextWindow <= 8_000) return 4_096;
68
+ if (contextWindow <= 32_000) return 8_192;
69
+ return 32_768;
70
+ }
71
+
72
+ export const PERCH_MODELS: readonly ModelDefinition[] = PERCH_ROWS.map((row) =>
73
+ defineModel({
74
+ id: row.id,
75
+ providerId: PERCH_PROVIDER_ID,
76
+ wireFamily: "chat",
77
+ endpoint: "/api/perch-terminal/model-call",
78
+ ctx: row.ctx,
79
+ out: row.out ?? perchOutputTokens(row.ctx),
80
+ // The tier surfaces are chat-text; no modality claims beyond that. No
81
+ // `free`/`freeTier` flag is set: the upstream does not expose a
82
+ // per-model plan list (cli-plan only reports planRequired), and a free
83
+ // claim would be an unverified assertion rather than upstream truth.
84
+ vision: false,
85
+ reasoning: false,
86
+ toolCall: false,
87
+ }),
88
+ );
89
+
90
+ /** Model-id → starter pin, for the adapter's dispatch-time lookup. */
91
+ export const PERCH_MODEL_PINS: Readonly<Record<string, string | undefined>> = Object.fromEntries(
92
+ PERCH_ROWS.map((row) => [row.id, row.pin]),
93
+ );
94
+
95
+ /** Model-id → Roost tier, for the adapter's dispatch-time lookup. */
96
+ export const PERCH_MODEL_ROOST_TIERS: Readonly<Record<string, string>> = Object.fromEntries(
97
+ PERCH_ROWS.map((row) => [
98
+ row.id,
99
+ row.pin === undefined
100
+ ? TIER_ROOST_TIERS[row.id] ?? "standard"
101
+ : row.pin === "standard-max"
102
+ ? "standard_max"
103
+ : PERCH_STARTER_PINS[row.pin]?.roostTier ?? "standard",
104
+ ]),
105
+ );
@@ -0,0 +1,25 @@
1
+ // Perch credential-envelope parsing.
2
+ //
3
+ // Perch accounts authenticate via Supabase OAuth (PKCE), and the stored secret
4
+ // is the OAuth envelope JSON with `accessToken` (or `access_token`). Both the
5
+ // dispatch adapter and the quota collector need the access token out of that
6
+ // envelope; the parse is shared here and each surface keeps its own fallback
7
+ // for a secret that is not an envelope.
8
+
9
+ /**
10
+ * Reads the access token out of a stored Perch OAuth envelope.
11
+ *
12
+ * Returns the token when the secret parses as JSON and carries `accessToken`
13
+ * (or `access_token`) as a string; `null` when it is not such an envelope
14
+ * (not JSON, or JSON without a token field). The caller decides what a
15
+ * `null` means for its surface.
16
+ */
17
+ export function parsePerchCredentialToken(secret: string): string | null {
18
+ try {
19
+ const parsed = JSON.parse(secret) as Record<string, unknown>;
20
+ const found = parsed["accessToken"] ?? parsed["access_token"];
21
+ return typeof found === "string" ? found : null;
22
+ } catch {
23
+ return null;
24
+ }
25
+ }