cartethyia 2.7.2 → 2.7.4

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 (405) hide show
  1. package/.env.example +2 -0
  2. package/dist/dashboard/assets/{BannedPage-XaUmiBrC.js → BannedPage-ChG5svFb.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  4. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +1 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  6. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +1 -0
  7. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-CXGS_Ct-.js → CombosPage-DCgm5g6g.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  10. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +1 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  12. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +1 -0
  13. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  14. package/dist/dashboard/assets/{HealthEventsModal-BKtAPYVF.js → HealthEventsModal-DzSWzE_j.js} +1 -1
  15. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  16. package/dist/dashboard/assets/{LoginPage-BdmRLnq2.js → LoginPage-U6AKaJcF.js} +1 -1
  17. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  18. package/dist/dashboard/assets/{ModelPicker-BH8Tehdi.js → ModelPicker-BMS2t8BA.js} +1 -1
  19. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  20. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +1 -0
  21. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  22. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +5 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  24. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +1 -0
  25. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  26. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js +9 -0
  27. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  28. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +1 -0
  29. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  30. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +1 -0
  31. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  32. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +1 -0
  33. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  34. package/dist/dashboard/assets/{SortableList-Dqf4zpS-.js → SortableList-ClzpwyET.js} +1 -1
  35. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  36. package/dist/dashboard/assets/{StudioPage-Byj2lAEm.js → StudioPage-Cq5tW7hW.js} +3 -3
  37. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  38. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +56 -0
  39. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  40. package/dist/dashboard/assets/api-keys-C38iXoO4.js +1 -0
  41. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  42. package/dist/dashboard/assets/app-a159k0ub.css +2 -0
  43. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  44. package/dist/dashboard/assets/arrow-up-59ms1iiT.js +1 -0
  45. package/dist/dashboard/assets/arrow-up-59ms1iiT.js.gz +0 -0
  46. package/dist/dashboard/assets/assert-DbRA8EG2.js +15 -0
  47. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-DC2L43Mj.js → badge-D9CS6dZk.js} +1 -1
  49. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-BBVcb0J3.js → banner-DympBNq4.js} +1 -1
  51. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-Cca1XC6G.js → card-ibRWU_uT.js} +1 -1
  53. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  54. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +1 -0
  55. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-DUzEbynq.js → clipboard-button-DJm-9pz7.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-DFvWhwTa.js → dialog-8fiE6tec.js} +1 -1
  59. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  60. package/dist/dashboard/assets/drawer-CqGYeOrd.js +1 -0
  61. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-Bqy8RFvM.js → entry-BSAsYsmV.js} +1 -1
  63. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  64. package/dist/dashboard/assets/entry-CiIQULZD.js +4 -0
  65. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  66. package/dist/dashboard/assets/entry-Daz0lJ-W.js +1 -0
  67. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  68. package/dist/dashboard/assets/{concurrency-BDF0ok7y.js → fingerprint-pattern-BWuHtbW4.js} +1 -1
  69. package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
  70. package/dist/dashboard/assets/{formatters-CWWZ-uCZ.js → formatters-D-MTJxMr.js} +1 -1
  71. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  72. package/dist/dashboard/assets/{github-badge-C9e8Ts7e.js → github-badge-CPK47xQx.js} +1 -1
  73. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  74. package/dist/dashboard/assets/{index-DFVFrnWW.js → index-DBNPOfhV.js} +2 -2
  75. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  76. package/dist/dashboard/assets/{inline-BFUcvllj.js → inline-BT0zntEr.js} +1 -1
  77. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  78. package/dist/dashboard/assets/{input-C_ILAvBb.js → input-Da2ZViWg.js} +1 -1
  79. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  80. package/dist/dashboard/assets/{layout-CBIyT6Rt.js → layout-BXNeLw6M.js} +1 -1
  81. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  82. package/dist/dashboard/assets/{list-row-ebJ_-Nsb.js → list-row-BycOrrIV.js} +1 -1
  83. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  84. package/dist/dashboard/assets/live-DCQNZpF7.js +1 -0
  85. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  86. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +1 -0
  87. package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
  88. package/dist/dashboard/assets/{mutation-sMD965oO.js → mutation-Rr0TIvcj.js} +1 -1
  89. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  90. package/dist/dashboard/assets/network-9Yj2ZyLo.js +1 -0
  91. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  92. package/dist/dashboard/assets/{numbers-BO9dKaFr.js → numbers-CEagj6ZZ.js} +2 -2
  93. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  94. package/dist/dashboard/assets/{query-keys-CfL_Zdoh.js → query-keys-BloKtaXJ.js} +1 -1
  95. package/dist/dashboard/assets/query-keys-BloKtaXJ.js.gz +0 -0
  96. package/dist/dashboard/assets/quota-Caw7wqci.js +1 -0
  97. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  98. package/dist/dashboard/assets/routing-CO9zCUus.js +1 -0
  99. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  100. package/dist/dashboard/assets/{select-DBNVLdUu.js → select-BIYIBkMU.js} +2 -2
  101. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  102. package/dist/dashboard/assets/settings-2-Ds9DQp0t.js +1 -0
  103. package/dist/dashboard/assets/settings-2-Ds9DQp0t.js.gz +0 -0
  104. package/dist/dashboard/assets/settings-jS3-PNSA.js +1 -0
  105. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  106. package/dist/dashboard/assets/{stack-EMrOMt4I.js → stack-DfgnFDWY.js} +1 -1
  107. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  108. package/dist/dashboard/assets/{state-CWoo7ty5.js → state-CkfdYWel.js} +1 -1
  109. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  110. package/dist/dashboard/assets/{switch-CCjT6IkF.js → switch-SYm237HG.js} +1 -1
  111. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  112. package/dist/dashboard/assets/{useMutation-DjkLHUcE.js → useMutation-BQqCRNIi.js} +1 -1
  113. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  114. package/dist/dashboard/index.html +3 -2
  115. package/dist/dashboard/index.html.gz +0 -0
  116. package/dist/dashboard/precompressed-assets.json +118 -115
  117. package/migrations/full-postgres/0026_add_qoder_native_identity.sql +20 -0
  118. package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +21 -0
  119. package/migrations/full-postgres/0028_add_family_template_key_telemetry.sql +40 -0
  120. package/migrations/full-postgres/0029_null_share_child_policy_columns.sql +38 -0
  121. package/migrations/full-postgres/0030_add_api_key_max_children.sql +10 -0
  122. package/migrations/full-postgres/0031_tenant_system_prompts.sql +16 -0
  123. package/migrations/full-postgres/0032_add_provider_pool_accounts.sql +53 -0
  124. package/migrations/full-postgres/0033_add_api_key_ban.sql +9 -0
  125. package/migrations/full-postgres/0034_add_api_key_ban_until.sql +7 -0
  126. package/migrations/full-postgres/0035_align_pool_account_status_enum.sql +21 -0
  127. package/migrations/lite-sqlite3/0026_add_qoder_native_identity.sql +15 -0
  128. package/migrations/lite-sqlite3/0027_qoder_identity_genuine_seed.sql +21 -0
  129. package/migrations/lite-sqlite3/0028_add_family_template_key_telemetry.sql +40 -0
  130. package/migrations/lite-sqlite3/0029_null_share_child_policy_columns.sql +38 -0
  131. package/migrations/lite-sqlite3/0030_add_api_key_max_children.sql +10 -0
  132. package/migrations/lite-sqlite3/0031_tenant_system_prompts.sql +10 -0
  133. package/migrations/lite-sqlite3/0032_add_provider_pool_accounts.sql +44 -0
  134. package/migrations/lite-sqlite3/0033_add_api_key_ban.sql +8 -0
  135. package/migrations/lite-sqlite3/0034_add_api_key_ban_until.sql +5 -0
  136. package/migrations/lite-sqlite3/0035_align_pool_account_status_enum.sql +6 -0
  137. package/package.json +2 -1
  138. package/src/boot/app.ts +9 -8
  139. package/src/config/network.ts +7 -3
  140. package/src/console/api-keys/bucket-spend.ts +7 -7
  141. package/src/console/api-keys/contracts.ts +475 -410
  142. package/src/console/api-keys/routes.ts +211 -23
  143. package/src/console/audit/routes.ts +3 -3
  144. package/src/console/auth/account-reset.ts +4 -4
  145. package/src/console/auth/session.ts +3 -3
  146. package/src/console/backup/contracts.ts +2 -0
  147. package/src/console/backup/export-endpoint.ts +14 -17
  148. package/src/console/backup/routes.ts +43 -11
  149. package/src/console/backup/service.ts +11 -6
  150. package/src/console/backup/store.ts +384 -88
  151. package/src/console/cli-tools/routes.ts +3 -3
  152. package/src/console/console-router-guards.ts +2 -2
  153. package/src/console/console-router.ts +4 -4
  154. package/src/console/dashboard-assets.ts +16 -1
  155. package/src/console/data-management/routes.ts +3 -3
  156. package/src/console/domain-registration.ts +4 -2
  157. package/src/console/observability/contracts.ts +4 -0
  158. package/src/console/observability/live.ts +3 -3
  159. package/src/console/observability/logs.ts +3 -3
  160. package/src/console/observability/performance.ts +3 -3
  161. package/src/console/observability/routes.ts +3 -3
  162. package/src/console/observability/store.ts +16 -16
  163. package/src/console/providers/catalog/contracts.ts +43 -22
  164. package/src/console/providers/catalog/provider-operations.ts +17 -2
  165. package/src/console/providers/catalog/routes.ts +3 -3
  166. package/src/console/providers/catalog/store-helpers.ts +349 -326
  167. package/src/console/providers/catalog/store.ts +1523 -1292
  168. package/src/console/providers/detail/routes.ts +3 -3
  169. package/src/console/providers/oauth/routes.ts +3 -3
  170. package/src/console/quota/account-quota-tenant.ts +34 -2
  171. package/src/console/quota/account-quota.ts +4 -1
  172. package/src/console/quota/account-test-egress.ts +4 -4
  173. package/src/console/quota/native-identity.ts +189 -0
  174. package/src/console/remote-support/contracts.ts +12 -6
  175. package/src/console/remote-support/service.ts +2 -2
  176. package/src/console/routing/model/routes.ts +3 -3
  177. package/src/console/routing/pools/contracts.ts +11 -8
  178. package/src/console/routing/pools/operations.ts +14 -7
  179. package/src/console/routing/pools/probe-verdict.ts +8 -3
  180. package/src/console/routing/pools/relay-deploy.ts +9 -9
  181. package/src/console/routing/pools/routes.ts +3 -3
  182. package/src/console/routing/pools/store.ts +21 -1
  183. package/src/console/settings/routes.ts +3 -3
  184. package/src/console/share/share-router.ts +51 -18
  185. package/src/console/share/share-stats.ts +158 -49
  186. package/src/console/share/share-usage.ts +24 -7
  187. package/src/console/shared/read-through-cache.ts +38 -2
  188. package/src/console/system-prompt/contracts.ts +102 -0
  189. package/src/console/system-prompt/routes.ts +165 -0
  190. package/src/console/updates/routes.ts +7 -4
  191. package/src/main.ts +11 -0
  192. package/src/network/outbound-fetch.ts +75 -4
  193. package/src/network/pool/resolver.ts +39 -39
  194. package/src/network/pool-cooldown-store.ts +71 -16
  195. package/src/network/pool-health-machine.ts +21 -1
  196. package/src/network/rate-limit-verdict.ts +68 -0
  197. package/src/network/ssrf.ts +4 -4
  198. package/src/observability/event-query.ts +437 -22
  199. package/src/observability/telemetry-status.ts +1 -1
  200. package/src/persistence/db-pg.ts +42 -0
  201. package/src/persistence/db-sqlite.ts +7 -2
  202. package/src/persistence/readiness.ts +18 -6
  203. package/src/persistence/schema.ts +162 -1
  204. package/src/persistence/stores/api-key-store.ts +849 -581
  205. package/src/persistence/stores/share-store.ts +65 -13
  206. package/src/persistence/stores/telemetry-store.ts +58 -2
  207. package/src/persistence/system-prompt-store.ts +104 -0
  208. package/src/protocol/codecs.ts +6 -6
  209. package/src/protocol/gateway-error.ts +6 -3
  210. package/src/protocol/image-generation.ts +2 -2
  211. package/src/protocol/reasoning.ts +65 -1
  212. package/src/protocol/request/chat.ts +1 -0
  213. package/src/protocol/response/chat.ts +2 -2
  214. package/src/protocol/response/codex.ts +1 -1
  215. package/src/protocol/response/gemini.ts +1 -1
  216. package/src/protocol/response/messages.ts +5 -5
  217. package/src/protocol/response/responses.ts +2 -2
  218. package/src/protocol/sse-decoder.ts +14 -3
  219. package/src/protocol/translation/capabilities.ts +2 -2
  220. package/src/protocol/upstream/send-claude-messages.ts +3 -3
  221. package/src/providers/adapters/base-adapter.ts +1 -1
  222. package/src/providers/adapters/compatible-adapter.ts +2 -2
  223. package/src/providers/authentication/oauth-refresh-service.ts +2 -2
  224. package/src/providers/configured-provider.ts +1 -1
  225. package/src/providers/discovery/probe-phases.ts +2 -2
  226. package/src/providers/discovery/probing-service.ts +12 -12
  227. package/src/providers/integrations/agentrouter/agentrouter.ts +2 -3
  228. package/src/providers/integrations/alibabacp/alibabacp.ts +2 -2
  229. package/src/providers/integrations/anthropic.ts +4 -11
  230. package/src/providers/integrations/antigravity/antigravity.ts +33 -47
  231. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  232. package/src/providers/integrations/buddy/buddy-chat-shared.ts +30 -2
  233. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +37 -6
  234. package/src/providers/integrations/buddy/buddy-identity.ts +22 -1
  235. package/src/providers/integrations/buddy/buddy-media.ts +21 -17
  236. package/src/providers/integrations/buddy/codebuddy/provider.ts +6 -2
  237. package/src/providers/integrations/buddy/workbuddy/provider.ts +6 -2
  238. package/src/providers/integrations/claude/claude-betas.ts +1 -1
  239. package/src/providers/integrations/claude/claude-credentials.ts +1 -1
  240. package/src/providers/integrations/claude/claude-slow-lane-retry.ts +1 -1
  241. package/src/providers/integrations/claude/claude.ts +3 -10
  242. package/src/providers/integrations/cline/cline.ts +8 -1
  243. package/src/providers/integrations/cloudflareai/cloudflareai.ts +4 -7
  244. package/src/providers/integrations/codex/codex-errors.ts +1 -1
  245. package/src/providers/integrations/codex/codex.ts +14 -15
  246. package/src/providers/integrations/commandcode/commandcode.ts +4 -4
  247. package/src/providers/integrations/commandcode/quota.ts +5 -1
  248. package/src/providers/integrations/cursor/cursor-http2.ts +11 -11
  249. package/src/providers/integrations/cursor/cursor.ts +15 -15
  250. package/src/providers/integrations/factory/factory.ts +4 -4
  251. package/src/providers/integrations/gemini.ts +11 -11
  252. package/src/providers/integrations/github/github.ts +26 -7
  253. package/src/providers/integrations/grok/grok.ts +2 -6
  254. package/src/providers/integrations/hermes.ts +5 -1
  255. package/src/providers/integrations/inferhub.ts +4 -11
  256. package/src/providers/integrations/kilo/kilo.ts +4 -0
  257. package/src/providers/integrations/kimi/kimi.ts +4 -11
  258. package/src/providers/integrations/kiro/kiro.ts +10 -10
  259. package/src/providers/integrations/muse/muse.ts +6 -9
  260. package/src/providers/integrations/openrouter/provider.ts +4 -0
  261. package/src/providers/integrations/perplexity.ts +2 -2
  262. package/src/providers/integrations/qoder/qoder-catalog.ts +47 -9
  263. package/src/providers/integrations/qoder/qoder-checkin.ts +242 -51
  264. package/src/providers/integrations/qoder/qoder-native-identity-store.ts +157 -0
  265. package/src/providers/integrations/qoder/qoder-oauth.ts +12 -3
  266. package/src/providers/integrations/qoder/qoder-realm.ts +15 -0
  267. package/src/providers/integrations/qoder/qoder-umid.ts +287 -0
  268. package/src/providers/integrations/qoder/qoder-virtual.ts +2 -2
  269. package/src/providers/integrations/qoder/qoder.ts +192 -24
  270. package/src/providers/integrations/tokenharbor.ts +2 -2
  271. package/src/providers/integrations/trae/trae.ts +6 -9
  272. package/src/providers/integrations/zcode/oauth.ts +1 -1
  273. package/src/providers/operations/account-error-classification.ts +6 -8
  274. package/src/providers/operations/account-health-service.ts +14 -16
  275. package/src/providers/operations/client-versions.ts +37 -22
  276. package/src/providers/operations/provider-catalog-service.ts +4 -4
  277. package/src/providers/operations/provider-credential-service.ts +16 -4
  278. package/src/providers/operations/upstream-deadline.ts +3 -3
  279. package/src/providers/provider-contracts.ts +55 -3
  280. package/src/providers/provider-credential-resolver.ts +1 -1
  281. package/src/providers/provider-registry.ts +4 -4
  282. package/src/providers/quota/quota-contracts.ts +24 -10
  283. package/src/providers/quota/refresh.ts +2 -2
  284. package/src/providers/search/search-provider.ts +5 -5
  285. package/src/security/abuse.ts +4 -4
  286. package/src/security/access-control.ts +19 -0
  287. package/src/security/admission/reasons.ts +17 -17
  288. package/src/security/api-key-auth.ts +18 -5
  289. package/src/shared/coerce.ts +19 -0
  290. package/src/transport/dispatch/attempt-finalize.ts +4 -3
  291. package/src/transport/dispatch/attempt-loop.ts +10 -7
  292. package/src/transport/dispatch/empty-stream.ts +6 -6
  293. package/src/transport/dispatch/generation.ts +9 -9
  294. package/src/transport/dispatch/leases.ts +8 -8
  295. package/src/transport/dispatch/proxy-request.ts +38 -9
  296. package/src/transport/dispatch/responses-compact.ts +11 -11
  297. package/src/transport/dispatch/retry-policy.ts +4 -67
  298. package/src/transport/dispatch/stream-bridge.ts +1 -1
  299. package/src/transport/dispatch/streaming/finalize.ts +9 -8
  300. package/src/transport/dispatch/streaming/stream.ts +16 -1
  301. package/src/transport/dispatch/systemone.ts +8 -8
  302. package/src/transport/dispatch/token-count.ts +9 -9
  303. package/src/transport/dispatch/upstream.ts +10 -0
  304. package/src/transport/dispatch/websearch.ts +6 -6
  305. package/src/transport/drain-endpoint.ts +2 -2
  306. package/src/transport/failure-policy.ts +13 -6
  307. package/src/transport/guards/auth-guard.ts +6 -5
  308. package/src/transport/guards/body-policy.ts +4 -4
  309. package/src/transport/guards/error-lifecycle.ts +18 -3
  310. package/src/transport/guards/guard-errors.ts +7 -3
  311. package/src/transport/guards/headroom-guard.ts +1 -1
  312. package/src/transport/guards/pipeline.ts +6 -6
  313. package/src/transport/guards/readiness-guard.ts +16 -2
  314. package/src/transport/guards/request-context.ts +3 -3
  315. package/src/transport/request/preparer.ts +37 -21
  316. package/src/transport/request/state.ts +4 -7
  317. package/src/transport/request/system-prompt-injection.ts +89 -0
  318. package/src/transport/request/tenant-preferences.ts +43 -0
  319. package/src/transport/routing/admission.ts +13 -3
  320. package/src/transport/routing/route-catalog.ts +104 -2
  321. package/src/transport/routing/route-model.ts +60 -7
  322. package/src/transport/routing/router.ts +306 -256
  323. package/src/transport/shutdown-notice.ts +19 -7
  324. package/src/transport/surface/completion.ts +1 -1
  325. package/src/transport/surface/messages/encode.ts +1 -1
  326. package/src/workers/daily-checkin.ts +2 -0
  327. package/dist/dashboard/assets/BannedPage-XaUmiBrC.js.gz +0 -0
  328. package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js +0 -1
  329. package/dist/dashboard/assets/CliToolDetailPage-CqD7QiLM.js.gz +0 -0
  330. package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js +0 -1
  331. package/dist/dashboard/assets/CliToolsPage-0XUo4UMn.js.gz +0 -0
  332. package/dist/dashboard/assets/CombosPage-CXGS_Ct-.js.gz +0 -0
  333. package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js +0 -1
  334. package/dist/dashboard/assets/ConsoleLogPage-DGnGNYnM.js.gz +0 -0
  335. package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js +0 -1
  336. package/dist/dashboard/assets/CustomizationPage-DAG5J9EY.js.gz +0 -0
  337. package/dist/dashboard/assets/HealthEventsModal-BKtAPYVF.js.gz +0 -0
  338. package/dist/dashboard/assets/LoginPage-BdmRLnq2.js.gz +0 -0
  339. package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
  340. package/dist/dashboard/assets/OverviewPage-CqMxibJB.js +0 -1
  341. package/dist/dashboard/assets/OverviewPage-CqMxibJB.js.gz +0 -0
  342. package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js +0 -4
  343. package/dist/dashboard/assets/ProviderDetailPage-CqMh2NRX.js.gz +0 -0
  344. package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js +0 -1
  345. package/dist/dashboard/assets/ProvidersPage-B9uWu4Nz.js.gz +0 -0
  346. package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js +0 -9
  347. package/dist/dashboard/assets/ProxyPage-BoWOhpDO.js.gz +0 -0
  348. package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js +0 -1
  349. package/dist/dashboard/assets/QuotaPage-7P2n--Fv.js.gz +0 -0
  350. package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js +0 -1
  351. package/dist/dashboard/assets/SettingsPage-CxZ1fTkN.js.gz +0 -0
  352. package/dist/dashboard/assets/SetupPage-Co12Zzaw.js +0 -1
  353. package/dist/dashboard/assets/SetupPage-Co12Zzaw.js.gz +0 -0
  354. package/dist/dashboard/assets/SortableList-Dqf4zpS-.js.gz +0 -0
  355. package/dist/dashboard/assets/StudioPage-Byj2lAEm.js.gz +0 -0
  356. package/dist/dashboard/assets/UsagePage-CTkLAuRc.js +0 -56
  357. package/dist/dashboard/assets/UsagePage-CTkLAuRc.js.gz +0 -0
  358. package/dist/dashboard/assets/api-keys-CUi6UXsR.js +0 -1
  359. package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
  360. package/dist/dashboard/assets/app-KvsUJUMF.css +0 -2
  361. package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
  362. package/dist/dashboard/assets/assert-67xXH5rf.js +0 -1
  363. package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
  364. package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
  365. package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
  366. package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
  367. package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js +0 -1
  368. package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
  369. package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
  370. package/dist/dashboard/assets/concurrency-BDF0ok7y.js.gz +0 -0
  371. package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
  372. package/dist/dashboard/assets/drawer-CFM2sMX1.js +0 -1
  373. package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
  374. package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
  375. package/dist/dashboard/assets/entry-ClCMCWWQ.js +0 -4
  376. package/dist/dashboard/assets/entry-ClCMCWWQ.js.gz +0 -0
  377. package/dist/dashboard/assets/entry-_xHo5x6r.js +0 -1
  378. package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
  379. package/dist/dashboard/assets/formatters-CWWZ-uCZ.js.gz +0 -0
  380. package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
  381. package/dist/dashboard/assets/index-DFVFrnWW.js.gz +0 -0
  382. package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
  383. package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
  384. package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
  385. package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
  386. package/dist/dashboard/assets/live-D0mm--ME.js +0 -1
  387. package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
  388. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +0 -1
  389. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  390. package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
  391. package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
  392. package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
  393. package/dist/dashboard/assets/quota-DZGyp0N5.js +0 -1
  394. package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
  395. package/dist/dashboard/assets/routing-BnIpi1IJ.js +0 -1
  396. package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
  397. package/dist/dashboard/assets/select-DBNVLdUu.js.gz +0 -0
  398. package/dist/dashboard/assets/settings-BAFhDgX8.js +0 -1
  399. package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
  400. package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
  401. package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
  402. package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
  403. package/dist/dashboard/assets/useMutation-DjkLHUcE.js.gz +0 -0
  404. /package/dist/dashboard/assets/{app-BaWd0puM.js → app-BayTTy01.js} +0 -0
  405. /package/dist/dashboard/assets/{app-BaWd0puM.js.gz → app-BayTTy01.js.gz} +0 -0
@@ -335,10 +335,19 @@ export class QoderOAuthClient extends OAuthDeviceFlow {
335
335
  const expireTime = parseQoderExpiry(body?.expires_at, body?.expires_in);
336
336
  const info = await this.fetchUserInfo(accessToken);
337
337
  const label = info.name || info.email || undefined;
338
- // The token response does not always name the user id; the profile
339
- // endpoint does, so it is the fallback before giving up on the identity
340
- // dispatch needs for COSY signing.
338
+ // The poll body carries user_id; the profile endpoint is only a fallback.
339
+ // Dispatch needs the id for COSY signing, and an empty one would store an
340
+ // account that 401s on every request ("missing its user identity") — so a
341
+ // login that cannot resolve the id fails loudly here instead, while the
342
+ // user is still in front of the approval screen and can just retry.
341
343
  const resolvedUserId = nonEmptyTrimmedString(body?.user_id) ?? info.id;
344
+ if (resolvedUserId === "") {
345
+ return {
346
+ status: "failed",
347
+ reason:
348
+ "Qoder login could not resolve the user id (poll had no user_id and the profile lookup returned none); try again",
349
+ };
350
+ }
342
351
  const result: OAuthExchangeResult = {
343
352
  access: accessToken,
344
353
  // No refresh grant exists, so the upstream refresh token (when present)
@@ -39,6 +39,21 @@ export const QODER_CHAT_PATH =
39
39
  "/algo/api/v2/service/pro/sse/agent_chat_generation?FetchKeys=llm_model_result&AgentId=agent_common&Encode=1";
40
40
  export const QODER_MODELS_PATH = "/algo/api/v2/model/list?Encode=1";
41
41
 
42
+ /**
43
+ * The modern model-server surface used by the IDE / QoderWake (OpenAI-shaped
44
+ * chunks, plain bearer auth). This surface streams immediately — the legacy
45
+ * `/algo` chat endpoint answers `10605 isQueued` and parks requests in a
46
+ * server-side queue, so dispatch prefers this surface when it is available.
47
+ */
48
+ export const QODER_IDE_CHAT_PATH = "/model/v1/chat/completions";
49
+
50
+ /** The model-server host for one realm (intl: `api2-v2`, cn: gateway). */
51
+ export function qoderIdeChatUrl(realm: QoderRealm): string {
52
+ return realm === "cn"
53
+ ? `https://gateway.qoder.com.cn${QODER_IDE_CHAT_PATH}`
54
+ : `https://api2-v2.qoder.sh${QODER_IDE_CHAT_PATH}`;
55
+ }
56
+
42
57
  /**
43
58
  * Realm → deployment.
44
59
  *
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Qoder native machine identity (UMID) — the genuine SG bridge via umidpack.
3
+ *
4
+ * Research record (2026-10-30): same-account controls found that the daily
5
+ * CREDITS campaign does not gate grants on machine identity. This module
6
+ * prefers the vendor bridge for stable native identity and seed replay, with
7
+ * a deterministic generated fallback when no bridge is available.
8
+ *
9
+ * Seed semantics (verified live): the Linux ELF resolves the user home via
10
+ * the passwd entry — it ignores `$HOME`/`XDG_CONFIG_HOME`, so the seed file
11
+ * is always `/home/<user>/.config/.locale_cfg`, one global file per Linux
12
+ * user. Per-account isolation therefore lives in the DATABASE (each account
13
+ * stores its own 350-byte seed) plus a flock-serialized bridge section:
14
+ * mint = wipe → run → capture seed+token; replay = write stored seed → run.
15
+ * Verified cycle (umidpack ELF under WSL): mint A, mint B (distinct),
16
+ * replay A ✓, replay B ✓, replay A again ✓.
17
+ *
18
+ * Platform behavior:
19
+ * win32 — the exe is hardware-bound: one identity per machine, no seed.
20
+ * linux — direct spawn of the umidpack ELF, serialized seed file.
21
+ * darwin — the Mach-O runs directly; seed path is the macOS user home.
22
+ * win32 + WSL (this repo's primary deployment) — the ELF runs via WSL with
23
+ * flock serialization; the bridge binary is staged into /tmp once.
24
+ *
25
+ * The generated path remains a fallback for hosts with no usable bridge. It
26
+ * produces deterministic, well-shaped tokens but is not an SG identity. Live
27
+ * controls showed that machine identity does not gate daily CREDITS grants.
28
+ *
29
+ * Bridge CLI (donor-verified):
30
+ * linux : runtime-info <env>
31
+ * darwin: printf '{"account":"<uid>"}\n' | runtime-info <env> --account-stdin
32
+ * win32 : runtime-info.exe <env> [--account-stdin]
33
+ */
34
+ import { spawnSync } from "node:child_process";
35
+ import { createHash } from "node:crypto";
36
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
37
+ import { join } from "node:path";
38
+ import { log } from "../../../observability/logger";
39
+
40
+ /** Valid environment codes (kept for validation/console surface). */
41
+ export const QODER_ENV_CODES = ["0", "3", "4", "5", "6", "7"] as const;
42
+
43
+ /** Environment code: an upstream "region/flavor", not a device identity. */
44
+ const ENV_CODE = "3";
45
+
46
+ /** One native identity sample (same shape the bridge prints). */
47
+ export interface QoderNativeIdentity {
48
+ readonly machineToken: string;
49
+ readonly machineType: string;
50
+ readonly machineCode: string;
51
+ readonly isVm: boolean;
52
+ readonly source: "runtime-info" | "generated";
53
+ }
54
+
55
+ /** Length of the base64url payload after the `P1gA` prefix (token total 88). */
56
+ const TOKEN_PAYLOAD_LENGTH = 84;
57
+ /** Hex length of machineType / machineCode in the bridge's output. */
58
+ const MACHINE_TYPE_LENGTH = 18;
59
+ const MACHINE_CODE_LENGTH = 18;
60
+
61
+ /** Where the umidpack binaries live, relative to the repo root. */
62
+ export function umidpackDir(): string {
63
+ return join(process.cwd(), "vendor", "qoder-umid", "umidpack");
64
+ }
65
+
66
+ /** WSL-side staging/seed paths for the Linux bridge on a Windows host. */
67
+ const WSL_BIN = "/tmp/umidpack/runtime-info";
68
+ const WSL_SEED = "/home/risun/.config/.locale_cfg";
69
+ const WSL_LOCK = "/tmp/umidpack/bridge.lock";
70
+
71
+ type Bridge = { kind: "elf" | "macho" | "pe" | "wsl-elf" };
72
+
73
+ /** Picks the bridge for this host; `null` when nothing genuine can run. */
74
+ function pickBridge(): Bridge | null {
75
+ if (process.platform === "win32") {
76
+ // Prefer the WSL ELF (seed-capable → per-account identities); fall back
77
+ // to the Windows exe pair (hardware-bound, one identity per machine).
78
+ const elf = join(umidpackDir(), "elf-x86_64", "runtime-info");
79
+ if (existsSync(elf)) return { kind: "wsl-elf" };
80
+ const exe = join(umidpackDir(), "runtime-info.exe");
81
+ const dll = join(umidpackDir(), "sgsdk.dll");
82
+ if (existsSync(exe) && existsSync(dll)) return { kind: "pe" };
83
+ return null;
84
+ }
85
+ if (process.platform === "darwin") {
86
+ const arch = process.arch === "arm64" ? "macho-arm64" : "macho-x86_64";
87
+ return existsSync(join(umidpackDir(), arch, "runtime-info")) ? { kind: "macho" } : null;
88
+ }
89
+ const arch = process.arch === "arm64" ? "elf-aarch64" : "elf-x86_64";
90
+ if (existsSync(join(umidpackDir(), arch, "runtime-info"))) return { kind: "elf" };
91
+ return existsSync(join(umidpackDir(), "elf-x86_64", "runtime-info")) ? { kind: "elf" } : null;
92
+ }
93
+
94
+ /** True when a genuine bridge can run on this host. */
95
+ export function hasGenuineBridge(): boolean {
96
+ return pickBridge() !== null;
97
+ }
98
+
99
+ /** Generated (software) identity — deterministic per account id, NOT SG-signed. */
100
+ export function mintQoderGeneratedIdentity(accountId: string): QoderNativeIdentity {
101
+ const first = createHash("sha256").update(accountId).digest("base64url");
102
+ const second = createHash("sha256").update(`${accountId}:${first}`).digest("base64url");
103
+ const token = `P1gA${`${first}${second}`.slice(0, TOKEN_PAYLOAD_LENGTH)}`;
104
+ return {
105
+ machineToken: token,
106
+ machineType: createHash("sha256").update(`${accountId}:type`).digest("hex").slice(0, MACHINE_TYPE_LENGTH),
107
+ machineCode: createHash("sha256").update(`${accountId}:code`).digest("hex").slice(0, MACHINE_CODE_LENGTH),
108
+ isVm: false,
109
+ source: "generated",
110
+ };
111
+ }
112
+
113
+ /** Parse one bridge JSON line into an identity; null on any mismatch. */
114
+ function parseBridgeLine(stdout: string): QoderNativeIdentity | null {
115
+ const line = stdout.split(/\r?\n/).find((l) => l.startsWith("{"));
116
+ if (!line) return null;
117
+ try {
118
+ const rec = JSON.parse(line) as Record<string, unknown>;
119
+ const machineToken = String(rec.machineToken ?? "").trim();
120
+ const machineType = String(rec.machineType ?? "").trim();
121
+ const machineCode = String(rec.machineCode ?? "").trim();
122
+ if (!machineToken || !machineType || !machineCode) return null;
123
+ const vmInfo = rec.vmInfo;
124
+ const isVm = typeof vmInfo === "object" && vmInfo !== null && (vmInfo as Record<string, unknown>).isVm === true;
125
+ return { machineToken, machineType, machineCode, isVm, source: "runtime-info" };
126
+ } catch {
127
+ return null;
128
+ }
129
+ }
130
+
131
+ /** Stage the ELF into the WSL filesystem once (idempotent, fast after first). */
132
+ function ensureWslStaged(): void {
133
+ const src = join(umidpackDir(), "elf-x86_64", "runtime-info").replace(/\\/g, "/");
134
+ const drive = /^([A-Za-z]):/.exec(src);
135
+ const wslSrc = drive ? `/mnt/${drive[1]!.toLowerCase()}${src.slice(2)}` : src;
136
+ wsl(
137
+ `mkdir -p /tmp/umidpack && cp "${wslSrc}" ${WSL_BIN} && chmod +x ${WSL_BIN} && ` +
138
+ `mkdir -p $(dirname ${WSL_SEED})`,
139
+ );
140
+ }
141
+
142
+ function wsl(script: string, timeout = 120_000): string {
143
+ const r = spawnSync("wsl", ["-e", "bash", "-lc", script], { encoding: "utf8", timeout, windowsHide: true });
144
+ return String(r.stdout ?? "");
145
+ }
146
+
147
+ /** Run the bridge inside WSL under flock; returns the identity or null. */
148
+
149
+ function seedPath(): string {
150
+ if (process.platform === "win32") return WSL_SEED;
151
+ const home = process.env.HOME ?? "";
152
+ return join(home, ".config", ".locale_cfg");
153
+ }
154
+
155
+ /**
156
+ * Mints a fresh native identity: wipe the seed (under the lock), run the
157
+ * bridge, capture the identity AND the seed it wrote. The seed is required
158
+ * for later replay of this same native identity. Returns `null` when the
159
+ * bridge fails; falls back to the generated identity only when no bridge
160
+ * exists.
161
+ */
162
+ export function mintQoderNativeIdentity(accountId: string): { identity: QoderNativeIdentity; seed: string } | null {
163
+ const bridge = pickBridge();
164
+ if (!bridge) {
165
+ log.warn("[qoder] no native bridge for this host — using generated identity fallback");
166
+ return { identity: mintQoderGeneratedIdentity(accountId), seed: "" };
167
+ }
168
+
169
+ if (bridge.kind === "wsl-elf") {
170
+ ensureWslStaged();
171
+ const out = wsl(
172
+ `exec 9>${WSL_LOCK}; flock 9; rm -f ${WSL_SEED}; ${WSL_BIN} ${ENV_CODE}`,
173
+ );
174
+ const identity = parseBridgeLine(out);
175
+ if (!identity) { log.warn("[qoder] wsl mint failed"); return null; }
176
+ const seed = wsl(`cat ${WSL_SEED}`);
177
+ return { identity, seed };
178
+ }
179
+
180
+ if (bridge.kind === "elf") {
181
+ const exe = join(umidpackDir(), process.arch === "arm64" ? "elf-aarch64" : "elf-x86_64", "runtime-info");
182
+ const seed = seedPath();
183
+ const dir = seed.slice(0, seed.lastIndexOf("/"));
184
+ mkdirSync(dir, { recursive: true });
185
+ try { spawnSync("rm", ["-f", seed]); } catch { /* ignore */ }
186
+ const r = spawnSync(exe, [ENV_CODE], { encoding: "utf8", timeout: 25_000 });
187
+ const identity = parseBridgeLine(String(r.stdout ?? ""));
188
+ if (!identity) { log.warn("[qoder] elf mint failed"); return null; }
189
+ return { identity, seed: existsSync(seed) ? readFileSync(seed, "utf8") : "" };
190
+ }
191
+
192
+ if (bridge.kind === "macho") {
193
+ const arch = process.arch === "arm64" ? "macho-arm64" : "macho-x86_64";
194
+ const exe = join(umidpackDir(), arch, "runtime-info");
195
+ const seed = seedPath();
196
+ const dir = seed.slice(0, seed.lastIndexOf("/"));
197
+ mkdirSync(dir, { recursive: true });
198
+ try { spawnSync("rm", ["-f", seed]); } catch { /* ignore */ }
199
+ const r = spawnSync(exe, [ENV_CODE, "--account-stdin"], {
200
+ input: `${JSON.stringify({ account: accountId })}\n`,
201
+ encoding: "utf8",
202
+ timeout: 25_000,
203
+ });
204
+ const identity = parseBridgeLine(String(r.stdout ?? ""));
205
+ if (!identity) { log.warn("[qoder] macho mint failed"); return null; }
206
+ return { identity, seed: existsSync(seed) ? readFileSync(seed, "utf8") : "" };
207
+ }
208
+
209
+ // pe — hardware-bound; no seed concept on Windows.
210
+ const exe = join(umidpackDir(), "runtime-info.exe");
211
+ const r = spawnSync(exe, [ENV_CODE], { encoding: "utf8", timeout: 30_000, windowsHide: true, cwd: umidpackDir() });
212
+ const identity = parseBridgeLine(String(r.stdout ?? ""));
213
+ if (!identity) { log.warn("[qoder] pe mint failed"); return null; }
214
+ return { identity, seed: "" };
215
+ }
216
+
217
+ /**
218
+ * Replays an identity from a stored seed: materialize the seed at the bridge's
219
+ * fixed path (under the lock) and re-run — the caller verifies the token
220
+ * matches the stored record. Returns `null` when no seed is available, the
221
+ * host cannot replay (Windows exe), or the bridge failed.
222
+ */
223
+ export function replayQoderNativeIdentity(seed: string, accountId: string): QoderNativeIdentity | null {
224
+ if (!seed) return null;
225
+ const bridge = pickBridge();
226
+ if (!bridge) return null;
227
+
228
+ if (bridge.kind === "wsl-elf") {
229
+ ensureWslStaged();
230
+ const quoted = seed.replace(/'/g, `'\\''`);
231
+ const out = wsl(
232
+ `exec 9>${WSL_LOCK}; flock 9; printf '%s' '${quoted}' > ${WSL_SEED}; ${WSL_BIN} ${ENV_CODE}`,
233
+ );
234
+ return parseBridgeLine(out);
235
+ }
236
+
237
+ if (bridge.kind === "elf") {
238
+ const exe = join(umidpackDir(), process.arch === "arm64" ? "elf-aarch64" : "elf-x86_64", "runtime-info");
239
+ const seed = seedPath();
240
+ writeFileSync(seed, seed, "utf8");
241
+ const r = spawnSync(exe, [ENV_CODE], { encoding: "utf8", timeout: 25_000 });
242
+ return parseBridgeLine(String(r.stdout ?? ""));
243
+ }
244
+
245
+ if (bridge.kind === "macho") {
246
+ const arch = process.arch === "arm64" ? "macho-arm64" : "macho-x86_64";
247
+ const exe = join(umidpackDir(), arch, "runtime-info");
248
+ const seedPathStr = seedPath();
249
+ writeFileSync(seedPathStr, seed, "utf8");
250
+ const r = spawnSync(exe, [ENV_CODE, "--account-stdin"], {
251
+ input: `${JSON.stringify({ account: accountId })}\n`,
252
+ encoding: "utf8",
253
+ timeout: 25_000,
254
+ });
255
+ return parseBridgeLine(String(r.stdout ?? ""));
256
+ }
257
+
258
+ return null; // pe: cannot replay a seed on a hardware-bound identity
259
+ }
260
+
261
+ /** Reads the current seed file content (diagnostics). */
262
+ export function readCurrentQoderSeed(): string {
263
+ const path = seedPath();
264
+ try {
265
+ if (process.platform === "win32") return wsl(`cat ${WSL_SEED} 2>/dev/null`);
266
+ return existsSync(path) ? readFileSync(path, "utf8") : "";
267
+ } catch {
268
+ return "";
269
+ }
270
+ }
271
+
272
+ /** The six native machine headers for one identity. */
273
+ export function qoderMachineHeaders(identity: QoderNativeIdentity): Record<string, string> {
274
+ return {
275
+ "cosy-machineid": identity.machineToken,
276
+ "cosy-machinetoken": identity.machineToken,
277
+ "cosy-machinetype": identity.machineType,
278
+ "cosy-machinecode": identity.machineCode,
279
+ "cosy-machineos": "x86_64_linux",
280
+ "cosy-machinehostname": "DESKTOP-QODER",
281
+ };
282
+ }
283
+
284
+ /** For tests: force re-mint (identities are pure functions of their seed). */
285
+ export function resetQoderNativeIdentityCache(): void {
286
+ // no persistent in-process identity cache remains
287
+ }
@@ -37,11 +37,11 @@ export const QODER_VIRTUAL_MODELS: readonly QoderVirtualModel[] = [
37
37
  { id: "qwen3.8-flash", target: "qfmodel", displayName: "Qwen3.8-Flash" },
38
38
  { id: "qwen3.7-max", target: "qmodel_latest", displayName: "Qwen3.7-Max" },
39
39
  { id: "qwen3.7-plus", target: "qmodel", displayName: "Qwen3.7-Plus" },
40
- { id: "kimi-k3", target: "kmodel_latest", displayName: "Kimi-K3" },
40
+ { id: "kimi-k3", target: "kmodel_latest", displayName: "Kimi-K3.1-Pro" },
41
41
  { id: "kimi-k2.8-preview", target: "kmodel", displayName: "Kimi-K2.8-Preview" },
42
42
  { id: "glm-5.3", target: "gmodel", displayName: "GLM-5.3" },
43
43
  { id: "glm-5.3-flash", target: "gfmodel", displayName: "GLM-5.3-Flash" },
44
- { id: "minimax-m3", target: "mmodel", displayName: "MiniMax-M3" },
44
+ { id: "minimax-m3", target: "mmodel", displayName: "MiniMax-M3.1-Flash" },
45
45
  ];
46
46
 
47
47
  /** Virtual id → roster key. */