cartethyia 2.7.4 → 2.7.6

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 (595) hide show
  1. package/.env.example +5 -0
  2. package/README.md +18 -6
  3. package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js +899 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-DxjvUzSD.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-DRPavCdU.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
  42. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
  43. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js +56 -0
  44. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
  45. package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
  46. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  47. package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
  48. package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
  49. package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
  50. package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
  51. package/dist/dashboard/assets/assert-CidQVoNo.js +1 -0
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-DympBNq4.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  58. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  59. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  60. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  61. package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CxDw0lK6.js} +1 -1
  62. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  63. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  64. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  65. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  66. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  67. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +1 -0
  68. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  69. package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-DfS1ntiq.js} +1 -1
  70. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  71. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  72. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  73. package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-QqPul6sC.js} +1 -1
  74. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  75. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  76. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  77. package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
  78. package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
  79. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  80. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  81. package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-u7JPB5BX.js} +1 -1
  82. package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
  83. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  84. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  85. package/dist/dashboard/assets/{index-DBNPOfhV.js → index-Ko4dLRnV.js} +2 -2
  86. package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
  87. package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-CHJQwxLa.js} +1 -1
  88. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  89. package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BlmlizVV.js} +1 -1
  90. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  91. package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-Bz93I-yE.js} +1 -1
  92. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  93. package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Ml16KCfu.js} +1 -1
  94. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  95. package/dist/dashboard/assets/live-7_QpnYGu.js +1 -0
  96. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  97. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  98. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  99. package/dist/dashboard/assets/network-CuMDaTzT.js +1 -0
  100. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  101. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  102. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  103. package/dist/dashboard/assets/pagination-B5aOoweZ.js +1 -0
  104. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  105. package/dist/dashboard/assets/providers/zai.webp +0 -0
  106. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  107. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  108. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  109. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  110. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  111. package/dist/dashboard/assets/routing-fnCsxgNO.js +1 -0
  112. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  113. package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BHqpd-bg.js} +2 -2
  114. package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
  115. package/dist/dashboard/assets/settings-BxslsErn.js +1 -0
  116. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  117. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  118. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  119. package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-j7cXjgYX.js} +1 -1
  120. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  121. package/dist/dashboard/assets/{state-CkfdYWel.js → state-DHmEnLa2.js} +1 -1
  122. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  123. package/dist/dashboard/assets/{switch-SYm237HG.js → switch-DmZcyTIC.js} +1 -1
  124. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  125. package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-CbCP4w1o.js} +1 -1
  126. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  127. package/dist/dashboard/console-backgrounds.jpg +0 -0
  128. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  129. package/dist/dashboard/index.html +2 -2
  130. package/dist/dashboard/index.html.gz +0 -0
  131. package/dist/dashboard/precompressed-assets.json +60 -59
  132. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  133. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  134. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  135. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  136. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  137. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  138. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  139. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  140. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  141. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  142. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  143. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  144. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  145. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  146. package/package.json +4 -6
  147. package/scripts/cli/update.ts +15 -41
  148. package/src/boot/app.ts +58 -2
  149. package/src/boot/dependencies.ts +794 -732
  150. package/src/boot/lifecycle.ts +11 -12
  151. package/src/config/cooldowns.ts +34 -55
  152. package/src/config/network.ts +1 -1
  153. package/src/config/package-paths.ts +1 -1
  154. package/src/config/providers.ts +19 -14
  155. package/src/config/resources.ts +0 -5
  156. package/src/config/runtime.ts +2 -5
  157. package/src/config/spec.ts +33 -6
  158. package/src/config/usage.ts +27 -0
  159. package/src/console/api-keys/ban-constants.ts +38 -0
  160. package/src/console/api-keys/contracts.ts +71 -62
  161. package/src/console/api-keys/routes.ts +56 -24
  162. package/src/console/auth/access.ts +4 -4
  163. package/src/console/auth/account-reset.ts +1 -1
  164. package/src/console/auth/audit-recorder.ts +1 -1
  165. package/src/console/auth/lockout.ts +7 -3
  166. package/src/console/auth/row-coercion.ts +57 -12
  167. package/src/console/auth/session-resolver.ts +1 -1
  168. package/src/console/auth/session-service.ts +8 -2
  169. package/src/console/auth/session.ts +37 -31
  170. package/src/console/auth/setup-service.ts +4 -3
  171. package/src/console/auth/user-store.ts +1 -1
  172. package/src/console/backup/9router-map.ts +0 -3
  173. package/src/console/backup/contracts.ts +9 -9
  174. package/src/console/backup/export-endpoint.ts +5 -6
  175. package/src/console/backup/nine-router.ts +1 -7
  176. package/src/console/backup/routes.ts +29 -33
  177. package/src/console/backup/service.ts +468 -468
  178. package/src/console/backup/store.ts +47 -29
  179. package/src/console/backup/validate.ts +11 -1
  180. package/src/console/cli-tools/contracts.ts +43 -299
  181. package/src/console/cli-tools/fs-ops.ts +29 -0
  182. package/src/console/cli-tools/injectors/claude.ts +3 -3
  183. package/src/console/cli-tools/injectors/codex.ts +181 -181
  184. package/src/console/cli-tools/injectors/driver.ts +150 -247
  185. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  186. package/src/console/cli-tools/injectors/opencode.ts +176 -153
  187. package/src/console/cli-tools/routes.ts +7 -1
  188. package/src/console/cli-tools/service.ts +8 -7
  189. package/src/console/cli-tools/store.ts +2 -2
  190. package/src/console/console-router.ts +32 -0
  191. package/src/console/dashboard-assets.ts +9 -9
  192. package/src/console/domain-registration.ts +16 -2
  193. package/src/console/inferhub/client.ts +0 -7
  194. package/src/console/inferhub/key-store.ts +1 -1
  195. package/src/console/inferhub/normalize.ts +2 -2
  196. package/src/console/inferhub/routes.ts +1 -1
  197. package/src/console/inferhub/types.ts +1 -1
  198. package/src/console/observability/contracts.ts +7 -1
  199. package/src/console/observability/live.ts +31 -18
  200. package/src/console/observability/logs.ts +1 -1
  201. package/src/console/observability/sse.ts +62 -8
  202. package/src/console/observability/store.ts +23 -4
  203. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  204. package/src/console/providers/catalog/contracts.ts +39 -0
  205. package/src/console/providers/catalog/model-operations.ts +1 -1
  206. package/src/console/providers/catalog/provider-operations.ts +95 -17
  207. package/src/console/providers/catalog/public-model-store.ts +0 -0
  208. package/src/console/providers/catalog/routes.ts +27 -3
  209. package/src/console/providers/catalog/store.ts +147 -8
  210. package/src/console/providers/detail/routes.ts +1 -1
  211. package/src/console/providers/oauth/callback-listener.ts +100 -18
  212. package/src/console/providers/oauth/routes.ts +92 -13
  213. package/src/console/quota/account-quota-global.ts +41 -3
  214. package/src/console/quota/account-quota-shared.ts +10 -3
  215. package/src/console/quota/account-quota-tenant.ts +259 -66
  216. package/src/console/quota/daily-growth-job.ts +308 -0
  217. package/src/console/quota/native-identity.ts +2 -2
  218. package/src/console/quota/quota-view.ts +1 -1
  219. package/src/console/remote-support/routes.ts +1 -1
  220. package/src/console/remote-support/service.ts +2 -2
  221. package/src/console/routing/model/contracts.ts +1 -1
  222. package/src/console/routing/pools/contracts.ts +2 -2
  223. package/src/console/routing/pools/import-parse.ts +3 -3
  224. package/src/console/routing/pools/relay-deploy.ts +3 -3
  225. package/src/console/settings/contracts.ts +29 -2
  226. package/src/console/settings/store.ts +20 -0
  227. package/src/console/share/share-router.ts +100 -32
  228. package/src/console/share/share-stats.ts +11 -13
  229. package/src/console/share/share-usage.ts +1 -1
  230. package/src/console/shared/errors.ts +2 -2
  231. package/src/console/shared/object.ts +18 -0
  232. package/src/console/shared/read-through-cache.ts +4 -4
  233. package/src/console/shared/transaction.ts +14 -0
  234. package/src/console/system-prompt/contracts.ts +89 -12
  235. package/src/console/system-prompt/routes.ts +98 -45
  236. package/src/console/updates/apply-update.ts +244 -0
  237. package/src/console/updates/routes.ts +252 -97
  238. package/src/main.ts +11 -5
  239. package/src/network/http2-bidi.ts +1 -1
  240. package/src/network/ip-utils.ts +298 -0
  241. package/src/network/outbound-fetch.ts +1 -1
  242. package/src/network/pool/agent.ts +7 -6
  243. package/src/network/pool/byte-accounting.ts +1 -1
  244. package/src/network/pool/resolver.ts +16 -12
  245. package/src/network/pool/selector.ts +150 -136
  246. package/src/network/pool-health-machine.ts +1 -1
  247. package/src/network/rate-limit-verdict.ts +1 -1
  248. package/src/network/retry.ts +1 -1
  249. package/src/network/ssrf.ts +20 -71
  250. package/src/observability/event-log.ts +9 -2
  251. package/src/observability/event-query.ts +61 -291
  252. package/src/observability/log-sanitize.ts +1 -1
  253. package/src/observability/metrics.ts +4 -4
  254. package/src/observability/payload-capture.ts +6 -5
  255. package/src/observability/payload-store.ts +1 -1
  256. package/src/observability/runtime-metrics.ts +1 -1
  257. package/src/observability/telemetry-buffer.ts +19 -3
  258. package/src/observability/telemetry-reconciliation.ts +3 -3
  259. package/src/observability/token-speed.ts +1 -1
  260. package/src/persistence/connection-url.ts +1 -1
  261. package/src/persistence/db-handle.ts +1 -1
  262. package/src/persistence/db-pg.ts +2 -2
  263. package/src/persistence/db-sqlite.ts +3 -3
  264. package/src/persistence/dialect.ts +5 -1
  265. package/src/persistence/readiness.ts +1 -1
  266. package/src/persistence/redis.ts +1 -1
  267. package/src/persistence/schema.ts +121 -40
  268. package/src/persistence/shared-cache.ts +2 -2
  269. package/src/persistence/sort-order.ts +1 -1
  270. package/src/persistence/stores/api-key-store.ts +29 -2
  271. package/src/persistence/stores/share-store.ts +20 -8
  272. package/src/persistence/system-prompt-store.ts +63 -18
  273. package/src/persistence/tenant-preferences.ts +1 -1
  274. package/src/persistence/ttl-cache.ts +3 -3
  275. package/src/persistence/usage-flush.ts +7 -2
  276. package/src/protocol/canonical-model.ts +1 -1
  277. package/src/protocol/codecs.ts +6 -10
  278. package/src/protocol/dsml.ts +8 -125
  279. package/src/protocol/image-clamp.ts +2 -2
  280. package/src/protocol/reasoning-text.ts +1 -1
  281. package/src/protocol/reasoning.ts +7 -52
  282. package/src/protocol/registry.ts +50 -15
  283. package/src/protocol/request/chat.ts +46 -19
  284. package/src/protocol/request/codex.ts +1 -1
  285. package/src/protocol/request/messages.ts +46 -14
  286. package/src/protocol/request/responses.ts +19 -10
  287. package/src/protocol/response/chat.ts +25 -10
  288. package/src/protocol/response/codex.ts +1 -1
  289. package/src/protocol/response/messages.ts +1 -1
  290. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  291. package/src/protocol/response/responses.ts +1 -1
  292. package/src/protocol/sse-decoder.ts +50 -1
  293. package/src/protocol/stop-reason.ts +2 -2
  294. package/src/protocol/think-split.ts +347 -0
  295. package/src/protocol/translation/attachment-integrity.ts +3 -3
  296. package/src/protocol/translation/cache-controls.ts +8 -20
  297. package/src/protocol/translation/capabilities.ts +6 -6
  298. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  299. package/src/protocol/translation/dialect/inband.ts +39 -0
  300. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  301. package/src/protocol/translation/dialect/qwen.ts +114 -0
  302. package/src/protocol/translation/dialect/resolver.ts +83 -0
  303. package/src/protocol/translation/dialect/rules.ts +93 -0
  304. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  305. package/src/protocol/translation/dialect/types.ts +58 -0
  306. package/src/protocol/translation/quirks.ts +18 -4
  307. package/src/protocol/translation/thinking.ts +12 -252
  308. package/src/protocol/translation/tool-id.ts +3 -3
  309. package/src/protocol/translation/tool-repair.ts +1 -1
  310. package/src/protocol/upstream/post-json.ts +6 -1
  311. package/src/providers/adapters/compatible-adapter.ts +71 -4
  312. package/src/providers/authentication/jwt-validator.ts +0 -5
  313. package/src/providers/authentication/oauth-client.ts +254 -253
  314. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  315. package/src/providers/bundled-discovery-providers.ts +6 -30
  316. package/src/providers/configured-openai-providers.ts +82 -97
  317. package/src/providers/default-registry.ts +35 -37
  318. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  319. package/src/providers/discovery/discovery-types.ts +0 -1
  320. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  321. package/src/providers/discovery/probe-phases.ts +48 -13
  322. package/src/providers/discovery/probing-service.ts +6 -8
  323. package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
  324. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  325. package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -28
  326. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  327. package/src/providers/integrations/antigravity/antigravity.ts +22 -13
  328. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  329. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  330. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  331. package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
  332. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  333. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
  335. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  336. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
  337. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  338. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  339. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  340. package/src/providers/integrations/cline/cline.ts +1 -1
  341. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  342. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  343. package/src/providers/integrations/commandcode/commandcode.ts +75 -115
  344. package/src/providers/integrations/commandcode/quota.ts +131 -51
  345. package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
  346. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  347. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  348. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  349. package/src/providers/integrations/cursor/cursor.ts +35 -3
  350. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  351. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  352. package/src/providers/integrations/factory/factory.ts +9 -9
  353. package/src/providers/integrations/github/github-discovery.ts +70 -12
  354. package/src/providers/integrations/github/github-oauth.ts +184 -14
  355. package/src/providers/integrations/github/github.ts +134 -26
  356. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  357. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  358. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  359. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  360. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  361. package/src/providers/integrations/grok/grok.ts +86 -36
  362. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  363. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  364. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  365. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  366. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  367. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  368. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  369. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  370. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  371. package/src/providers/integrations/kiro/kiro.ts +80 -68
  372. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  373. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  374. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  375. package/src/providers/integrations/opencode/provider.ts +17 -24
  376. package/src/providers/integrations/qoder/qoder-catalog.ts +94 -11
  377. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  378. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  379. package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
  380. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  381. package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
  382. package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
  383. package/src/providers/integrations/qoder/qoder.ts +422 -71
  384. package/src/providers/integrations/shared/connect.ts +0 -54
  385. package/src/providers/integrations/shared/hash.ts +15 -0
  386. package/src/providers/integrations/shared/session-cache.ts +136 -0
  387. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  388. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  389. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  390. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  391. package/src/providers/integrations/trae/trae.ts +51 -8
  392. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  393. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  394. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  395. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  396. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  397. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  398. package/src/providers/operations/account-error-classification.ts +198 -133
  399. package/src/providers/operations/account-health-service.ts +31 -39
  400. package/src/providers/operations/account-reset-service.ts +58 -1
  401. package/src/providers/operations/byok-wire-profile.ts +19 -15
  402. package/src/providers/operations/cli-platform.ts +31 -5
  403. package/src/providers/operations/client-version-resolver.ts +4 -6
  404. package/src/providers/operations/client-versions.ts +10 -7
  405. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  406. package/src/providers/operations/provider-catalog-service.ts +18 -2
  407. package/src/providers/operations/provider-credential-service.ts +19 -2
  408. package/src/providers/provider-contracts.ts +18 -7
  409. package/src/providers/provider-metadata.ts +17 -2
  410. package/src/providers/provider-model-definition.ts +22 -1
  411. package/src/providers/provider-probe.ts +4 -2
  412. package/src/providers/provider-usage.ts +50 -19
  413. package/src/providers/quota/cache.ts +29 -0
  414. package/src/providers/quota/quota-contracts.ts +4 -0
  415. package/src/providers/quota/refresh.ts +27 -4
  416. package/src/providers/quota/snapshot.ts +94 -0
  417. package/src/providers/search/search-provider.ts +1 -3
  418. package/src/providers/search/search-providers.ts +2 -1
  419. package/src/security/abuse.ts +4 -4
  420. package/src/security/admission/service.ts +13 -6
  421. package/src/security/admission/ttl.ts +61 -61
  422. package/src/security/api-key-auth.ts +17 -3
  423. package/src/security/client-router-fingerprint.ts +4 -4
  424. package/src/security/credential-codec.ts +3 -3
  425. package/src/security/csrf.ts +2 -2
  426. package/src/security/ip-boundary.ts +16 -189
  427. package/src/security/model-access-rule.ts +1 -1
  428. package/src/security/outbound-headers.ts +18 -0
  429. package/src/shared/invoke-guard.ts +47 -0
  430. package/src/transport/contracts.ts +13 -4
  431. package/src/transport/dispatch/attempt-finalize.ts +70 -22
  432. package/src/transport/dispatch/attempt-loop.ts +22 -0
  433. package/src/transport/dispatch/capture-policy.ts +34 -37
  434. package/src/transport/dispatch/empty-stream.ts +23 -20
  435. package/src/transport/dispatch/generation.ts +25 -45
  436. package/src/transport/dispatch/native-shared.ts +127 -0
  437. package/src/transport/dispatch/proxy-request.ts +3 -1
  438. package/src/transport/dispatch/responses-compact.ts +25 -46
  439. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  440. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  441. package/src/transport/dispatch/streaming/stream.ts +7 -3
  442. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  443. package/src/transport/dispatch/systemone.ts +20 -48
  444. package/src/transport/dispatch/token-count.ts +41 -38
  445. package/src/transport/dispatch/websearch.ts +19 -45
  446. package/src/transport/drain-endpoint.ts +1 -1
  447. package/src/transport/failure-policy.ts +21 -1
  448. package/src/transport/guards/auth-guard.ts +0 -6
  449. package/src/transport/guards/body-policy.ts +3 -3
  450. package/src/transport/guards/error-lifecycle.ts +4 -0
  451. package/src/transport/guards/headroom-guard.ts +1 -1
  452. package/src/transport/guards/pipeline.ts +1 -1
  453. package/src/transport/guards/request-context.ts +12 -17
  454. package/src/transport/request/preparer.ts +286 -7
  455. package/src/transport/request/rtk/compress-request.ts +3 -3
  456. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  457. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  458. package/src/transport/request/state.ts +7 -13
  459. package/src/transport/request/system-prompt-injection.ts +74 -11
  460. package/src/transport/request/tenant-preferences.ts +22 -0
  461. package/src/transport/routing/candidate-index.ts +2 -2
  462. package/src/transport/routing/round-robin.ts +1 -1
  463. package/src/transport/routing/route-catalog.ts +17 -18
  464. package/src/transport/routing/route-model.ts +126 -33
  465. package/src/transport/routing/router.ts +159 -37
  466. package/src/transport/shutdown-notice.ts +2 -2
  467. package/src/transport/surface/adapters.ts +3 -3
  468. package/src/transport/surface/chat/encode.ts +7 -7
  469. package/src/transport/surface/chat/parse.ts +7 -7
  470. package/src/transport/surface/completion.ts +2 -2
  471. package/src/transport/surface/content-parts.ts +1 -1
  472. package/src/transport/surface/dialects.ts +2 -2
  473. package/src/transport/surface/messages/parse.ts +3 -3
  474. package/src/transport/surface/reasoning-summary.ts +9 -14
  475. package/src/transport/surface/responses/adapter.ts +1 -1
  476. package/src/transport/surface/responses/errors.ts +0 -9
  477. package/src/transport/vision-handoff-cache.ts +58 -0
  478. package/src/transport/vision-handoff.ts +431 -0
  479. package/src/workers/account-identity-sweep.ts +2 -2
  480. package/src/workers/buddy-growth-tasks.ts +392 -346
  481. package/src/workers/daily-checkin.ts +102 -49
  482. package/src/workers/maintenance-lease.ts +2 -35
  483. package/src/workers/oauth-refresh-sweep.ts +8 -1
  484. package/src/workers/quota-refresh-sweep.ts +120 -82
  485. package/src/workers/scheduler.ts +67 -4
  486. package/src/workers/sweep-runner.ts +24 -5
  487. package/src/workers/zcode-gift-claim.ts +108 -0
  488. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  489. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  490. package/dist/dashboard/assets/BannedPage-ChG5svFb.js +0 -1
  491. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  492. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +0 -1
  493. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  494. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +0 -1
  495. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  496. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
  497. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  498. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
  499. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  500. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +0 -1
  501. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  502. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
  503. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  504. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js +0 -1
  505. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  506. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  507. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
  508. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  509. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
  510. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  511. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  512. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  513. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
  514. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  515. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  516. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
  517. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  518. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
  519. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  520. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +0 -1
  521. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  522. package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
  523. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  524. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  525. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  526. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  527. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
  528. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  529. package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
  530. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  531. package/dist/dashboard/assets/app-BayTTy01.js +0 -9
  532. package/dist/dashboard/assets/app-BayTTy01.js.gz +0 -0
  533. package/dist/dashboard/assets/app-a159k0ub.css +0 -2
  534. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  535. package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
  536. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  537. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  538. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  539. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  540. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
  541. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  542. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  543. package/dist/dashboard/assets/dialog-8fiE6tec.js +0 -1
  544. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  545. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  546. package/dist/dashboard/assets/entry-BSAsYsmV.js +0 -1
  547. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  548. package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
  549. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  550. package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
  551. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  552. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  553. package/dist/dashboard/assets/github-badge-CPK47xQx.js +0 -1
  554. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  555. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  556. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  557. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  558. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  559. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  560. package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
  561. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  562. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  563. package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
  564. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  565. package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
  566. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  567. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  568. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  569. package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
  570. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  571. package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
  572. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  573. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  574. package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
  575. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  576. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  577. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  578. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  579. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  580. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  581. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  582. package/src/console/cli-tools/injectors/cline.ts +0 -110
  583. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  584. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  585. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  586. package/src/console/cli-tools/injectors/droid.ts +0 -96
  587. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  588. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  589. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  590. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
  591. package/src/network/response-headers.ts +0 -39
  592. package/src/protocol/response/dsml.ts +0 -38
  593. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  594. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  595. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -106,7 +106,7 @@ function factoryClientHeaders(orgId: string): Record<string, string> {
106
106
  * (`packages/ai/src/providers/factory-droid.ts:271` — `"x-api-provider":
107
107
  * input.upstream`), so a value outside it has no meaning on this wire.
108
108
  */
109
- export const FACTORY_DROID_UPSTREAMS = [
109
+ const FACTORY_DROID_UPSTREAMS = [
110
110
  "fireworks",
111
111
  "baseten",
112
112
  "mistral",
@@ -123,7 +123,7 @@ export const FACTORY_DROID_UPSTREAMS = [
123
123
  "databricks",
124
124
  ] as const;
125
125
 
126
- export type FactoryDroidUpstream = (typeof FACTORY_DROID_UPSTREAMS)[number];
126
+ type FactoryDroidUpstream = (typeof FACTORY_DROID_UPSTREAMS)[number];
127
127
 
128
128
  const FACTORY_DROID_UPSTREAM_SET: ReadonlySet<string> = new Set(FACTORY_DROID_UPSTREAMS);
129
129
 
@@ -154,7 +154,7 @@ function logDroppedUpstream(reason: string, value: string): void {
154
154
  * unmapped failure. Omitting falls back to Factory's default routing, which is
155
155
  * the behavior a request that names no upstream already gets.
156
156
  */
157
- export function factoryApiProviderHeader(
157
+ function factoryApiProviderHeader(
158
158
  options: Readonly<Record<string, unknown>> | undefined,
159
159
  ): Record<string, string> {
160
160
  const value = options?.["factory_api_provider"];
@@ -179,7 +179,7 @@ export function factoryApiProviderHeader(
179
179
  * `/api/cli/whoami` reported. An account with no recorded residency is the
180
180
  * global host, which is Factory's default.
181
181
  */
182
- export function factoryBaseUrl(context: ProviderDispatchContext): string {
182
+ function factoryBaseUrl(context: ProviderDispatchContext): string {
183
183
  const region = context.credential.auth_state?.["region"];
184
184
  return region === "eu" ? FACTORY_DROID_EU_BASE_URL : FACTORY_DROID_BASE_URL;
185
185
  }
@@ -200,7 +200,7 @@ export function factoryBaseUrl(context: ProviderDispatchContext): string {
200
200
  * operator wrote into `auth_state`. The two-axis read is kept because the donor
201
201
  * needs it, not because we currently populate the second axis.
202
202
  */
203
- export function factoryInferenceRegion(
203
+ function factoryInferenceRegion(
204
204
  context: ProviderDispatchContext,
205
205
  ): "global" | "us" | "eu" {
206
206
  const state = context.credential.auth_state;
@@ -266,7 +266,7 @@ const REGION_UPSTREAMS: Readonly<Record<"global" | "us" | "eu", readonly Factory
266
266
  * is, which is a property of the route rather than of the request. The donor's
267
267
  * own message text is preserved as the `reason` so the mapping is traceable.
268
268
  */
269
- export function factoryRegionUnavailable(modelId: string, region: string): GatewayError {
269
+ function factoryRegionUnavailable(modelId: string, region: string): GatewayError {
270
270
  return new GatewayError(
271
271
  "capability_unsupported",
272
272
  400,
@@ -294,7 +294,7 @@ export function factoryRegionUnavailable(modelId: string, region: string): Gatew
294
294
  * Sending `configured_order` without that discovery would claim a rotation we
295
295
  * never resolved.
296
296
  */
297
- export function factoryRoutingSourceHeader(request: CanonicalRequest): Record<string, string> {
297
+ function factoryRoutingSourceHeader(request: CanonicalRequest): Record<string, string> {
298
298
  const continuing = request.messages.some((message) => message.role === "assistant");
299
299
  return { "x-provider-routing-source": continuing ? "session_lock" : "registry_default" };
300
300
  }
@@ -313,7 +313,7 @@ export function factoryRoutingSourceHeader(request: CanonicalRequest): Record<st
313
313
  * donor's own region-unavailable error rather than an upstream 4xx this layer
314
314
  * cannot explain.
315
315
  */
316
- export function factoryRegionCheckedApiProviderHeader(
316
+ function factoryRegionCheckedApiProviderHeader(
317
317
  request: CanonicalRequest,
318
318
  context: ProviderDispatchContext,
319
319
  ): Record<string, string> {
@@ -330,7 +330,7 @@ export function factoryRegionCheckedApiProviderHeader(
330
330
  }
331
331
 
332
332
  /** The two routing headers together, as every Factory wire sends them. */
333
- export function factoryRoutingHeaders(
333
+ function factoryRoutingHeaders(
334
334
  request: CanonicalRequest,
335
335
  context: ProviderDispatchContext,
336
336
  ): Record<string, string> {
@@ -29,10 +29,12 @@ import {
29
29
  GITHUB_PROVIDER_ID,
30
30
  GITHUB_ENDPOINT_PATH,
31
31
  GITHUB_RESPONSES_ENDPOINT_PATH,
32
+ GITHUB_MESSAGES_ENDPOINT_PATH,
32
33
  GITHUB_AUTO_MODELS,
33
34
  recordGithubModelRoutes,
34
35
  } from "./github";
35
- import { GITHUB_REQUEST_HEADERS, parseGithubCredential } from "./github-oauth";
36
+ import { GITHUB_REQUEST_HEADERS, githubCopilotClientIds, parseGithubCredential } from "./github-oauth";
37
+ import { createHash } from "node:crypto";
36
38
 
37
39
  /** A context window above this is unsatisfiable headroom, not a real limit. */
38
40
  const MAX_CONTEXT = 1_000_000_000;
@@ -47,12 +49,11 @@ function positiveLimit(value: unknown): number | undefined {
47
49
  * The surfaces a row answers on, normalized to the canonical paths this
48
50
  * gateway registers.
49
51
  *
50
- * A row that supports neither chat nor responses is skipped rather than
51
- * defaulted: Copilot also serves a native Anthropic `/v1/messages` surface for
52
- * some SKUs, and this adapter speaks only the OpenAI wire. Registering such a
53
- * row as chat would publish a route that fails on first dispatch.
52
+ * Copilot serves three OpenAI/Anthropic surfaces: `/chat/completions`,
53
+ * `/responses`, and `/v1/messages`. A row that supports none of them is
54
+ * skipped rather than defaulted.
54
55
  */
55
- function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | undefined {
56
+ function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | "messages" | undefined {
56
57
  const declared = boundedUpstreamArray(entry.supported_endpoints);
57
58
  if (!declared) return "chat";
58
59
  const endpoints = new Set<string>();
@@ -60,11 +61,12 @@ function wireFamilyFor(entry: Record<string, unknown>): "chat" | "responses" | u
60
61
  const label = sanitizeUpstreamLabel(value);
61
62
  if (label !== undefined) endpoints.add(label.replace(/^\/v1(?=\/)/, ""));
62
63
  }
63
- // Chat is preferred when a row supports both: it is the surface every
64
- // OpenAI-compatible client already speaks, and the upstream answers it for
65
- // the same SKU. Responses is used only when chat is absent.
64
+ // Chat is preferred when a row supports it: it is the surface every
65
+ // OpenAI-compatible client already speaks. Responses and Messages are used
66
+ // only when chat is absent, in that order.
66
67
  if (endpoints.has("/chat/completions")) return "chat";
67
68
  if (endpoints.has("/responses")) return "responses";
69
+ if (endpoints.has("/messages")) return "messages";
68
70
  return undefined;
69
71
  }
70
72
 
@@ -75,6 +77,34 @@ function supports(entry: Record<string, unknown>, key: string): boolean {
75
77
  return declared?.[key] === true;
76
78
  }
77
79
 
80
+ /**
81
+ * Price deltas from the account's `/models` row when it publishes `token_prices`
82
+ * (dollars per 1M tokens). This is the real per-account price Copilot serves,
83
+ * which the shared models.dev catalog cannot know; when absent the base-catalog
84
+ * estimate is used instead.
85
+ */
86
+ function copilotCost(entry: Record<string, unknown>): ModelDefinition["cost"] {
87
+ const billing = isRecord(entry.billing) ? entry.billing : undefined;
88
+ const prices = isRecord(billing?.token_prices) ? billing.token_prices : undefined;
89
+ const defaultTier = isRecord(prices?.default) ? prices.default : undefined;
90
+ const input = positiveLimit(defaultTier?.input_price);
91
+ const output = positiveLimit(defaultTier?.output_price);
92
+ if (input === undefined && output === undefined) {
93
+ return modelsDevCatalog.costFor(GITHUB_PROVIDER_ID, String(entry.id ?? ""));
94
+ }
95
+ return {
96
+ input: input ?? null,
97
+ output: output ?? null,
98
+ ...(typeof (defaultTier as Record<string, unknown> | undefined)?.cache_read_price === "number"
99
+ ? { cache_read: (defaultTier as { cache_read_price?: number }).cache_read_price }
100
+ : {}),
101
+ ...(typeof (defaultTier as Record<string, unknown> | undefined)?.cache_write_price === "number"
102
+ ? { cache_write: (defaultTier as { cache_write_price?: number }).cache_write_price }
103
+ : {}),
104
+ pricing_model: "pay-per-use",
105
+ };
106
+ }
107
+
78
108
  function toModelDefinition(entry: Record<string, unknown>): ModelDefinition | undefined {
79
109
  const modelId = sanitizeUpstreamLabel(entry.id);
80
110
  if (modelId === undefined) return undefined;
@@ -89,16 +119,32 @@ function toModelDefinition(entry: Record<string, unknown>): ModelDefinition | un
89
119
  // clamped the same way every other catalog row is.
90
120
  const outputLimit = Math.min(declaredOutput, contextLimit);
91
121
  const vision = supports(entry, "vision");
122
+ // `reasoning_effort` is a list (e.g. ["low","medium","high","xhigh","max"])
123
+ // when the model supports effort levels; absence means the model does not
124
+ // expose an effort knob. Carrying it lets routing clamp to the model's real
125
+ // ladder instead of the provider-wide `max→high` cap.
126
+ const supportsObj = isRecord(capabilities?.supports) ? capabilities.supports : undefined;
127
+ const reasoningEfforts = Array.isArray(supportsObj?.reasoning_effort)
128
+ ? (supportsObj.reasoning_effort as unknown[])
129
+ .filter((level): level is string => typeof level === "string" && level.length > 0)
130
+ : undefined;
131
+ const cost = copilotCost(entry);
92
132
  return {
93
133
  modelId,
94
134
  wireFamily,
95
- endpointPath: wireFamily === "responses" ? GITHUB_RESPONSES_ENDPOINT_PATH : GITHUB_ENDPOINT_PATH,
135
+ endpointPath:
136
+ wireFamily === "responses"
137
+ ? GITHUB_RESPONSES_ENDPOINT_PATH
138
+ : wireFamily === "messages"
139
+ ? GITHUB_MESSAGES_ENDPOINT_PATH
140
+ : GITHUB_ENDPOINT_PATH,
96
141
  contextLimit,
97
142
  outputLimit,
98
143
  modalities: { input: vision ? ["text", "image"] : ["text"], output: ["text"] },
99
144
  reasoning: true,
145
+ ...(reasoningEfforts === undefined ? {} : { reasoningEfforts }),
100
146
  toolCall: true,
101
- cost: modelsDevCatalog.costFor(GITHUB_PROVIDER_ID, modelId),
147
+ cost,
102
148
  };
103
149
  }
104
150
 
@@ -125,8 +171,20 @@ export async function discoverGithubModels(
125
171
  const signal =
126
172
  input.signal === undefined ? timeoutSignal : AbortSignal.any([input.signal, timeoutSignal]);
127
173
  try {
174
+ // The reference client stamps its Copilot identity on `/models` too
175
+ // (`_mixinHeaders` covers the Models request type): session + machine ids.
176
+ // Machine id is per-account — see `githubCopilotClientIds`.
177
+ const accountKey = createHash("sha256").update(`${apiHost}:${access}`).digest("hex");
178
+ const { sessionId, machineId } = await githubCopilotClientIds(accountKey);
128
179
  const response = await fetcher(`https://${apiHost}/models`, {
129
- headers: { accept: "application/json", authorization: `Bearer ${access}`, ...GITHUB_REQUEST_HEADERS },
180
+ headers: {
181
+ accept: "application/json",
182
+ authorization: `Bearer ${access}`,
183
+ ...GITHUB_REQUEST_HEADERS,
184
+ "VScode-SessionId": sessionId,
185
+ "VScode-MachineId": machineId,
186
+ "editor-device-id": machineId,
187
+ },
130
188
  signal,
131
189
  });
132
190
  if (!response.ok) return null;
@@ -29,13 +29,31 @@ import type { OAuthTokenRefreshResult } from "../../authentication/oauth-refresh
29
29
  import { OAuthDeviceFlow } from "../../authentication/oauth-device-flow";
30
30
  import type { FetchLike } from "../../authentication/oauth-client";
31
31
  import { resolveGithubEnterpriseDomain } from "../../../config/providers";
32
+ import { randomUUID, createHash } from "node:crypto";
33
+ import { getOrCreateInstallId } from "../shared/install-id";
32
34
 
33
35
 
34
36
  /** Public GitHub OAuth app id the Copilot clients use; not a secret. */
35
37
  export const GITHUB_CLIENT_ID = "Iv1.b507a08c87ecfe98" as const;
38
+ /** The OpenCode desktop client's own GitHub OAuth app id (used by its Copilot integration). */
39
+ export const GITHUB_OPENCODE_CLIENT_ID = "Ov23li8tweQw6odWQebz" as const;
36
40
  export const GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token" as const;
37
41
  /** Default API host when a token carries no `proxy-ep` claim. */
38
42
  export const GITHUB_DEFAULT_API_HOST = "api.individual.githubcopilot.com" as const;
43
+ /**
44
+ * The Copilot API host OpenCode's integration uses. The reference plugin always
45
+ * dials `api.githubcopilot.com` for GitHub.com (never the per-claim
46
+ * `api.individual.*` host the VS Code minted tokens carry), so an OpenCode
47
+ * login pins this host rather than falling back to the VS Code default.
48
+ */
49
+ export const GITHUB_OPENCODE_API_HOST = "api.githubcopilot.com" as const;
50
+ /**
51
+ * How long an OpenCode login's credential is treated as valid before the
52
+ * refresh sweep revisits it. The raw GitHub OAuth token has no Copilot token
53
+ * expiry (there is no minted token), so this is a far-future safeguard, not a
54
+ * real lifetime: a re-login or upstream expiry is what actually rotates it.
55
+ */
56
+ const GITHUB_OPENCODE_TOKEN_LIFETIME_MS = 365 * 24 * 60 * 60 * 1000;
39
57
 
40
58
  /**
41
59
  * Headers every Copilot inference and policy request must carry.
@@ -43,17 +61,64 @@ export const GITHUB_DEFAULT_API_HOST = "api.individual.githubcopilot.com" as con
43
61
  * The API rejects a request that does not identify a Copilot client, so these
44
62
  * are a protocol requirement rather than cosmetic fingerprinting — unlike the
45
63
  * Codex/Claude CLI identities elsewhere in this repository, which exist to look
46
- * like a first-party client. The version pair is the Copilot Chat extension's,
47
- * which is what the upstream expects for this client id.
64
+ * like a first-party client. The version pair is the Copilot Chat extension's
65
+ * (0.72.0 on VS Code 1.144), which is what the upstream expects for this
66
+ * client id.
48
67
  */
49
68
  export const GITHUB_REQUEST_HEADERS: Readonly<Record<string, string>> = Object.freeze({
50
- "user-agent": "GitHubCopilotChat/0.70.0",
51
- "editor-version": "vscode/1.142.0",
52
- "editor-plugin-version": "copilot-chat/0.70.0",
69
+ "user-agent": "GitHubCopilotChat/0.72.0",
70
+ "editor-version": "vscode/1.144.0",
71
+ "editor-plugin-version": "copilot-chat/0.72.0",
53
72
  "copilot-integration-id": "vscode-chat",
54
73
  "x-github-api-version": "2026-08-01",
55
74
  });
56
75
 
76
+ /**
77
+ * Stable per-process Copilot session id.
78
+ *
79
+ * The reference extension (`_mixinHeaders`) stamps `VScode-SessionId` with the
80
+ * VS Code window session and `VScode-MachineId` with the machine id. There is
81
+ * no VS Code window here, so the closest 1:1 shapes are: a session id minted
82
+ * once per gateway process (a new window = a new process in the reference), and
83
+ * a stable per-installation identity for the machine id.
84
+ */
85
+ export const GITHUB_COPILOT_SESSION_ID = randomUUID();
86
+
87
+ /**
88
+ * Resolves the Copilot client identity headers shared by chat/auto/discovery.
89
+ *
90
+ * The machine id is derived deterministically from the persisted install id and
91
+ * an account fingerprint when one is provided. The reference extension uses one
92
+ * machine id per VS Code installation for every account, but this gateway pools
93
+ * many accounts on one host — sharing one id across all of them makes every
94
+ * account look like a single device (an easy clustering/abuse signal). A
95
+ * per-account machine id keeps each account looking like its own device while
96
+ * staying stable across restarts for the same account. Without an account key
97
+ * (e.g. credential could not be parsed) the raw install id is used.
98
+ */
99
+ export async function githubCopilotClientIds(
100
+ accountKey?: string,
101
+ ): Promise<{
102
+ readonly sessionId: string;
103
+ readonly machineId: string;
104
+ }> {
105
+ const installId = await getOrCreateInstallId("github");
106
+ const machineId =
107
+ accountKey === undefined || accountKey.length === 0
108
+ ? installId
109
+ : deterministicMachineId(installId, accountKey);
110
+ return {
111
+ sessionId: GITHUB_COPILOT_SESSION_ID,
112
+ machineId,
113
+ };
114
+ }
115
+
116
+ /** Stable UUID-shaped machine id derived from the install id and an account key. */
117
+ export function deterministicMachineId(installId: string, accountKey: string): string {
118
+ const digest = createHash("sha256").update(`${installId}:${accountKey}`).digest("hex");
119
+ return `${digest.slice(0, 8)}-${digest.slice(8, 12)}-${digest.slice(12, 16)}-${digest.slice(16, 20)}-${digest.slice(20, 32)}`;
120
+ }
121
+
57
122
  const DEVICE_INTERVAL_SECONDS = 5;
58
123
  const DEVICE_EXPIRY_SECONDS = 900;
59
124
  /** Copilot tokens are short-lived; a missing `expires_at` falls back to 25 minutes. */
@@ -195,17 +260,80 @@ async function fetchGitHubLogin(
195
260
  }
196
261
  }
197
262
 
263
+ interface CopilotUserProfile {
264
+ readonly chat_enabled?: boolean;
265
+ readonly can_signup_for_limited?: boolean;
266
+ }
267
+
268
+ /**
269
+ * Reads the Copilot entitlement profile for a freshly approved GitHub token.
270
+ *
271
+ * OAuth itself succeeds for any GitHub account; entitlement is the only signal
272
+ * that the account can chat. Mirrors the reference OpenCode provider: an
273
+ * explicit `chat_enabled: false` is a denial (the account is not signed up or
274
+ * has no seat), and a failed/malformed lookup must not turn a GitHub hiccup
275
+ * into a denial — only an explicit answer blocks login.
276
+ */
277
+ async function fetchGitHubCopilotEntitlement(
278
+ githubAccessToken: string,
279
+ domain: string,
280
+ fetchFn: FetchLike,
281
+ signal: AbortSignal,
282
+ ): Promise<{ denied: string } | { denied?: undefined }> {
283
+ try {
284
+ const endpoint =
285
+ domain === "github.com"
286
+ ? "https://api.github.com/copilot_internal/user"
287
+ : `https://api.${domain}/copilot_internal/user`;
288
+ const response = await fetchFn(endpoint, {
289
+ headers: {
290
+ accept: "application/json",
291
+ authorization: `Bearer ${githubAccessToken}`,
292
+ "user-agent": GITHUB_REQUEST_HEADERS["user-agent"]!,
293
+ "x-github-api-version": "2025-04-01",
294
+ },
295
+ signal,
296
+ });
297
+ if (!response.ok) return { denied: undefined };
298
+ const profile = record(await response.json()) as CopilotUserProfile | undefined;
299
+ if (profile?.chat_enabled === false) {
300
+ if (profile.can_signup_for_limited) {
301
+ return {
302
+ denied:
303
+ "This GitHub account is not signed up for GitHub Copilot. Sign up for Copilot Free at https://github.com/features/copilot/plans and connect again.",
304
+ };
305
+ }
306
+ return {
307
+ denied:
308
+ "This GitHub account does not have GitHub Copilot access. It needs an active Copilot subscription or a seat assigned by an organization.",
309
+ };
310
+ }
311
+ return { denied: undefined };
312
+ } catch {
313
+ // Entitlement is a gate, not a reliability dependency: a network glitch
314
+ // here must not lock out an account that did approve the login.
315
+ return { denied: undefined };
316
+ }
317
+ }
318
+
198
319
  export class GithubOAuthClient extends OAuthDeviceFlow {
199
320
  override readonly supportsDeviceCode = true;
200
321
  override readonly supportsBrowserCode = false;
201
322
 
202
323
  protected override readonly providerLabel = "GitHub Copilot";
203
- protected override readonly clientId = GITHUB_CLIENT_ID;
204
324
  protected override readonly tokenUrl = GITHUB_ACCESS_TOKEN_URL;
205
325
  protected override readonly scopes = "read:user";
206
326
 
207
- constructor(fetchFn: FetchLike = globalThis.fetch) {
327
+ /** Which GitHub OAuth app this flow presents. Defaults to the Copilot Chat
328
+ * extension's app; OpenCode's own app differs (`GITHUB_OPENCODE_CLIENT_ID`). */
329
+ protected override readonly clientId: string;
330
+
331
+ constructor(
332
+ fetchFn: FetchLike = globalThis.fetch,
333
+ clientId: string = GITHUB_CLIENT_ID,
334
+ ) {
208
335
  super(fetchFn);
336
+ this.clientId = clientId;
209
337
  }
210
338
 
211
339
  override async startDeviceAuth(_context?: OAuthDeviceFlowContext): Promise<OAuthDeviceStartResult> {
@@ -217,7 +345,7 @@ export class GithubOAuthClient extends OAuthDeviceFlow {
217
345
  "content-type": "application/x-www-form-urlencoded",
218
346
  "user-agent": GITHUB_REQUEST_HEADERS["user-agent"]!,
219
347
  },
220
- body: new URLSearchParams({ client_id: GITHUB_CLIENT_ID, scope: "read:user" }),
348
+ body: new URLSearchParams({ client_id: this.clientId, scope: "read:user" }),
221
349
  });
222
350
  const body = record(await readJsonResponse(response, "GitHub device authorization"));
223
351
  const deviceCode = nonEmptyTrimmedString(body?.device_code);
@@ -271,7 +399,7 @@ export class GithubOAuthClient extends OAuthDeviceFlow {
271
399
  "user-agent": GITHUB_REQUEST_HEADERS["user-agent"]!,
272
400
  },
273
401
  body: new URLSearchParams({
274
- client_id: GITHUB_CLIENT_ID,
402
+ client_id: this.clientId,
275
403
  device_code: deviceAuthId,
276
404
  grant_type: "urn:ietf:params:oauth:grant-type:device_code",
277
405
  }),
@@ -314,21 +442,48 @@ export class GithubOAuthClient extends OAuthDeviceFlow {
314
442
  : `GitHub device polling failed (${response.status})`;
315
443
  return { status: "failed", reason };
316
444
  }
317
- let minted;
445
+ let minted: Awaited<ReturnType<typeof mintGithubToken>> | undefined;
318
446
  try {
319
- minted = await mintGithubToken(githubToken, domain, this.fetchFn);
447
+ // OAuth succeeds for any GitHub account; the entitlement profile is the
448
+ // only signal that the account can actually chat. An explicit denial is
449
+ // surfaced as a failed verdict before any token is minted or stored,
450
+ // mirroring the reference OpenCode provider.
451
+ const entitlement = await fetchGitHubCopilotEntitlement(
452
+ githubToken,
453
+ domain,
454
+ this.fetchFn,
455
+ AbortSignal.timeout(10_000),
456
+ );
457
+ if (entitlement.denied !== undefined) {
458
+ return { status: "failed", reason: entitlement.denied };
459
+ }
460
+ // OpenCode's OAuth app is the client the `opencode-copilot` wire mode
461
+ // presents upstream, and that mode uses the raw GitHub token directly —
462
+ // no minted Copilot token. The VS Code mint endpoint
463
+ // (`/copilot_internal/v2/token`) rejects non-VS-Code client ids with 403
464
+ // (GitHub's anti-scraping gate), so an OpenCode login must not mint.
465
+ if (this.clientId !== GITHUB_OPENCODE_CLIENT_ID) {
466
+ minted = await mintGithubToken(githubToken, domain, this.fetchFn);
467
+ }
320
468
  } catch (error) {
321
469
  // The mint runs after approval: surface its reason as a failed verdict,
322
470
  // not an exception that escapes the dashboard's poll request.
323
471
  return { status: "failed", reason: error instanceof Error ? error.message : "GitHub Copilot token mint failed" };
324
472
  }
325
473
  const label = await fetchGitHubLogin(githubToken, domain, this.fetchFn, AbortSignal.timeout(10_000));
474
+ const access = minted === undefined ? githubToken : minted.access;
475
+ const apiHost = minted === undefined ? GITHUB_OPENCODE_API_HOST : minted.apiHost;
476
+ const expiresAt =
477
+ minted === undefined
478
+ ? new Date(Date.now() + GITHUB_OPENCODE_TOKEN_LIFETIME_MS)
479
+ : minted.expiresAt;
326
480
  const result: OAuthExchangeResult = {
327
- access: encodeGithubCredential(minted.access, minted.apiHost, githubToken),
481
+ access: encodeGithubCredential(access, apiHost, githubToken),
328
482
  // The GitHub token is the refresh value: it is what re-mints the Copilot
329
- // token, which expires on its own much shorter clock.
483
+ // token (VS Code app) or is the raw credential itself (OpenCode app),
484
+ // depending on which app the flow presented.
330
485
  refresh: githubToken,
331
- expiresAt: minted.expiresAt,
486
+ expiresAt,
332
487
  ...(label === undefined ? {} : { accountLabel: label }),
333
488
  };
334
489
  return { status: "complete", result };
@@ -336,6 +491,21 @@ export class GithubOAuthClient extends OAuthDeviceFlow {
336
491
 
337
492
 
338
493
  override async refresh(refreshToken: string, signal?: AbortSignal): Promise<OAuthTokenRefreshResult> {
494
+ // OpenCode's app uses the raw GitHub token directly — there is no minted
495
+ // Copilot token to re-mint, and the VS Code mint endpoint rejects the
496
+ // OpenCode client id. Refresh is then a no-op that keeps the credential
497
+ // valid on its far-future lifetime.
498
+ if (this.clientId === GITHUB_OPENCODE_CLIENT_ID) {
499
+ return {
500
+ access: encodeGithubCredential(
501
+ refreshToken,
502
+ GITHUB_OPENCODE_API_HOST,
503
+ refreshToken,
504
+ ),
505
+ refresh: refreshToken,
506
+ expiresAt: new Date(Date.now() + GITHUB_OPENCODE_TOKEN_LIFETIME_MS),
507
+ };
508
+ }
339
509
  const minted = await mintGithubToken(
340
510
  refreshToken,
341
511
  copilotGitHubDomain(),