cartethyia 2.8.0 → 2.8.1

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 (348) hide show
  1. package/.env.example +3 -3
  2. package/dist/dashboard/assets/{BannedPage-Cc0vKpMG.js → BannedPage-Dq530awD.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-Dq530awD.js.gz +0 -0
  4. package/dist/dashboard/assets/{CliToolDetailPage-Bqj2aa1T.js → CliToolDetailPage-DZzaS-7S.js} +1 -1
  5. package/dist/dashboard/assets/CliToolDetailPage-DZzaS-7S.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolsPage-CXsaOAO2.js → CliToolsPage-DaZZ3cqP.js} +1 -1
  7. package/dist/dashboard/assets/CliToolsPage-DaZZ3cqP.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-BeLpJ4ma.js → CombosPage-BlC_xdkX.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-BlC_xdkX.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-DnV0uZ3m.js → ConsoleLogPage-D-rqeVtG.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-D-rqeVtG.js.gz +0 -0
  12. package/dist/dashboard/assets/{CustomizationPage-CBxAjo63.js → CustomizationPage-7xT5yg2E.js} +1 -1
  13. package/dist/dashboard/assets/CustomizationPage-7xT5yg2E.js.gz +0 -0
  14. package/dist/dashboard/assets/{HealthEventsModal-B5yEE0k6.js → HealthEventsModal-Clq8E9cW.js} +1 -1
  15. package/dist/dashboard/assets/HealthEventsModal-Clq8E9cW.js.gz +0 -0
  16. package/dist/dashboard/assets/{InjectSystemPromptPanel-BWFLECmz.js → InjectSystemPromptPanel-6Teoq9Se.js} +1 -1
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-6Teoq9Se.js.gz +0 -0
  18. package/dist/dashboard/assets/{LoginPage-CgoPc5B9.js → LoginPage-CZuI0MAR.js} +1 -1
  19. package/dist/dashboard/assets/LoginPage-CZuI0MAR.js.gz +0 -0
  20. package/dist/dashboard/assets/{ModelPicker-D9bFQern.js → ModelPicker-C1hNTlkr.js} +1 -1
  21. package/dist/dashboard/assets/ModelPicker-C1hNTlkr.js.gz +0 -0
  22. package/dist/dashboard/assets/{OverviewPage-B_p4tL8k.js → OverviewPage-0yfhSI1C.js} +1 -1
  23. package/dist/dashboard/assets/OverviewPage-0yfhSI1C.js.gz +0 -0
  24. package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js +8 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js.gz +0 -0
  26. package/dist/dashboard/assets/{ProviderIcon-D_0PiZtg.js → ProviderIcon-Ddhm1InL.js} +1 -1
  27. package/dist/dashboard/assets/ProviderIcon-Ddhm1InL.js.gz +0 -0
  28. package/dist/dashboard/assets/{ProvidersPage-CLI2bJTK.js → ProvidersPage-C3fYuu6i.js} +1 -1
  29. package/dist/dashboard/assets/ProvidersPage-C3fYuu6i.js.gz +0 -0
  30. package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js +9 -0
  31. package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js.gz +0 -0
  32. package/dist/dashboard/assets/{QuotaPage-DA-a1iSN.js → QuotaPage-D1RV_2BX.js} +1 -1
  33. package/dist/dashboard/assets/QuotaPage-D1RV_2BX.js.gz +0 -0
  34. package/dist/dashboard/assets/{SettingsPage-CctTga2C.js → SettingsPage-BzZAvYSX.js} +1 -1
  35. package/dist/dashboard/assets/SettingsPage-BzZAvYSX.js.gz +0 -0
  36. package/dist/dashboard/assets/{SetupPage-febLU4r1.js → SetupPage--s-EfEIL.js} +1 -1
  37. package/dist/dashboard/assets/SetupPage--s-EfEIL.js.gz +0 -0
  38. package/dist/dashboard/assets/{StudioPage-M6fvR5Wz.js → StudioPage-BjXFGSK4.js} +1 -1
  39. package/dist/dashboard/assets/StudioPage-BjXFGSK4.js.gz +0 -0
  40. package/dist/dashboard/assets/{UsagePage-nyeuRqz9.js → UsagePage-CP8F8BN7.js} +1 -1
  41. package/dist/dashboard/assets/UsagePage-CP8F8BN7.js.gz +0 -0
  42. package/dist/dashboard/assets/{api-keys-BFOlvrJC.js → api-keys-2hc12Uz2.js} +1 -1
  43. package/dist/dashboard/assets/api-keys-2hc12Uz2.js.gz +0 -0
  44. package/dist/dashboard/assets/app-DGXbNfAR.css +2 -0
  45. package/dist/dashboard/assets/app-DGXbNfAR.css.gz +0 -0
  46. package/dist/dashboard/assets/{assert-CqTLw5e7.js → assert-BMcj1xZE.js} +1 -1
  47. package/dist/dashboard/assets/assert-BMcj1xZE.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-C83EqLB0.js → badge-DkRUuVfz.js} +1 -1
  49. package/dist/dashboard/assets/badge-DkRUuVfz.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-D1xn7pIe.js → banner-CDjW841Q.js} +1 -1
  51. package/dist/dashboard/assets/banner-CDjW841Q.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-DU3Lq5Lm.js → card-Bto5UlL9.js} +1 -1
  53. package/dist/dashboard/assets/card-Bto5UlL9.js.gz +0 -0
  54. package/dist/dashboard/assets/{cli-tools-Dw1U_drK.js → cli-tools-DaH6g9hL.js} +1 -1
  55. package/dist/dashboard/assets/cli-tools-DaH6g9hL.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-CEL5Sg_J.js → clipboard-button-BYKBCzjk.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-BYKBCzjk.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-BjFR5UHy.js → dialog-DL0Zftwv.js} +1 -1
  59. package/dist/dashboard/assets/dialog-DL0Zftwv.js.gz +0 -0
  60. package/dist/dashboard/assets/{drawer-HvBW0AjI.js → drawer-Dpx_UXaS.js} +1 -1
  61. package/dist/dashboard/assets/drawer-Dpx_UXaS.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-CECVELyy.js → entry-BV7-1NoM.js} +1 -1
  63. package/dist/dashboard/assets/entry-BV7-1NoM.js.gz +0 -0
  64. package/dist/dashboard/assets/{entry-DYYofQ7W.js → entry-CGvdNU6r.js} +1 -1
  65. package/dist/dashboard/assets/entry-CGvdNU6r.js.gz +0 -0
  66. package/dist/dashboard/assets/{entry-BSu3gFlt.js → entry-DScKYvZj.js} +3 -3
  67. package/dist/dashboard/assets/entry-DScKYvZj.js.gz +0 -0
  68. package/dist/dashboard/assets/{formatters-DLW4i8zK.js → formatters-BS3DZlZj.js} +1 -1
  69. package/dist/dashboard/assets/formatters-BS3DZlZj.js.gz +0 -0
  70. package/dist/dashboard/assets/{index-1-fCqe64.js → index-SQnvvTWX.js} +2 -2
  71. package/dist/dashboard/assets/index-SQnvvTWX.js.gz +0 -0
  72. package/dist/dashboard/assets/{inline-DGvU2oLK.js → inline-Dl-cuLK0.js} +1 -1
  73. package/dist/dashboard/assets/inline-Dl-cuLK0.js.gz +0 -0
  74. package/dist/dashboard/assets/{input-iNnO1X2K.js → input-Bfx0EzRc.js} +1 -1
  75. package/dist/dashboard/assets/input-Bfx0EzRc.js.gz +0 -0
  76. package/dist/dashboard/assets/{layout-0q8UGypb.js → layout-BxhbQ_JS.js} +1 -1
  77. package/dist/dashboard/assets/layout-BxhbQ_JS.js.gz +0 -0
  78. package/dist/dashboard/assets/{list-row-C0w2bQjJ.js → list-row-D49Y4ptn.js} +1 -1
  79. package/dist/dashboard/assets/list-row-D49Y4ptn.js.gz +0 -0
  80. package/dist/dashboard/assets/{live-M5aJ_xCa.js → live-CbVTdX9V.js} +1 -1
  81. package/dist/dashboard/assets/live-CbVTdX9V.js.gz +0 -0
  82. package/dist/dashboard/assets/{network-BKeQGT3K.js → network-JGvDveof.js} +1 -1
  83. package/dist/dashboard/assets/network-JGvDveof.js.gz +0 -0
  84. package/dist/dashboard/assets/{numbers-CivAk3da.js → numbers-Dw6kiew-.js} +1 -1
  85. package/dist/dashboard/assets/numbers-Dw6kiew-.js.gz +0 -0
  86. package/dist/dashboard/assets/{pagination-CpzvI5ep.js → pagination-iUoI8GeE.js} +1 -1
  87. package/dist/dashboard/assets/pagination-iUoI8GeE.js.gz +0 -0
  88. package/dist/dashboard/assets/providers/sensenova-intl.png +0 -0
  89. package/dist/dashboard/assets/providers/sensenova.png +0 -0
  90. package/dist/dashboard/assets/{routing-BFQX2VBc.js → routing-8jZr-3WE.js} +1 -1
  91. package/dist/dashboard/assets/routing-8jZr-3WE.js.gz +0 -0
  92. package/dist/dashboard/assets/{select-CXbck0jG.js → select-oO1FxMVb.js} +1 -1
  93. package/dist/dashboard/assets/select-oO1FxMVb.js.gz +0 -0
  94. package/dist/dashboard/assets/{settings-C_XvMHh9.js → settings-CLr3kdIx.js} +1 -1
  95. package/dist/dashboard/assets/settings-CLr3kdIx.js.gz +0 -0
  96. package/dist/dashboard/assets/{stack-DggRiCxE.js → stack-Y3pDteZr.js} +1 -1
  97. package/dist/dashboard/assets/stack-Y3pDteZr.js.gz +0 -0
  98. package/dist/dashboard/assets/{state-ClFzfbYp.js → state-CArX_Iak.js} +1 -1
  99. package/dist/dashboard/assets/state-CArX_Iak.js.gz +0 -0
  100. package/dist/dashboard/assets/{switch-CTIFxKqS.js → switch-DwlwmDO-.js} +1 -1
  101. package/dist/dashboard/assets/switch-DwlwmDO-.js.gz +0 -0
  102. package/dist/dashboard/assets/{useMutation-BClG3yWj.js → useMutation-DJ9GYEgf.js} +1 -1
  103. package/dist/dashboard/assets/useMutation-DJ9GYEgf.js.gz +0 -0
  104. package/dist/dashboard/index.html +2 -2
  105. package/dist/dashboard/index.html.gz +0 -0
  106. package/dist/dashboard/precompressed-assets.json +51 -51
  107. package/migrations/full-postgres/0047_add_provider_device_flow_proxy.sql +17 -0
  108. package/migrations/lite-sqlite3/0047_add_provider_device_flow_proxy.sql +19 -0
  109. package/package.json +1 -1
  110. package/src/boot/app.ts +1 -1
  111. package/src/boot/dependencies.ts +4 -6
  112. package/src/config/providers.ts +6 -5
  113. package/src/config/spec.ts +8 -8
  114. package/src/console/backup/nine-router.ts +71 -10
  115. package/src/console/backup/service.ts +8 -1
  116. package/src/console/console-router.ts +1 -1
  117. package/src/console/domain-registration.ts +7 -2
  118. package/src/console/inferhub/client.ts +1 -1
  119. package/src/console/observability/live.ts +2 -2
  120. package/src/console/providers/catalog/contracts.ts +9 -3
  121. package/src/console/providers/catalog/model-operations.ts +2 -3
  122. package/src/console/providers/catalog/provider-operations.ts +1 -1
  123. package/src/console/providers/catalog/routes.ts +2 -2
  124. package/src/console/providers/catalog/store.ts +1914 -1907
  125. package/src/console/providers/detail/routes.ts +1 -0
  126. package/src/console/providers/detail/store.ts +4 -0
  127. package/src/console/providers/oauth/callback-listener.ts +30 -11
  128. package/src/console/providers/oauth/device-egress.ts +123 -0
  129. package/src/console/providers/oauth/routes.ts +123 -16
  130. package/src/console/quota/account-quota-tenant.ts +5 -5
  131. package/src/console/quota/account-test-egress.ts +2 -2
  132. package/src/console/quota/daily-growth-job.ts +1 -1
  133. package/src/console/routing/pools/contracts.ts +1 -1
  134. package/src/console/routing/pools/operations.ts +1 -1
  135. package/src/console/routing/pools/probe-verdict.ts +2 -2
  136. package/src/console/routing/pools/relay-deploy.ts +1 -1
  137. package/src/console/routing/pools/store.ts +4 -4
  138. package/src/network/client.ts +67 -0
  139. package/src/network/egress/bidi-session.ts +322 -0
  140. package/src/network/egress/dial.ts +201 -0
  141. package/src/network/egress/factory.ts +191 -0
  142. package/src/network/{outbound-fetch.ts → egress/fetch.ts} +195 -29
  143. package/src/network/egress/tls-profile.ts +123 -0
  144. package/src/network/egress/ws.ts +175 -0
  145. package/src/network/{types.ts → pool/agent-config.ts} +1 -1
  146. package/src/network/pool/agent.ts +2 -2
  147. package/src/network/{pool-cooldown-store.ts → pool/cooldown-store.ts} +7 -7
  148. package/src/network/{pool-health-machine.ts → pool/health.ts} +205 -6
  149. package/src/network/pool/resolver.ts +10 -849
  150. package/src/network/pool/selector.ts +2 -2
  151. package/src/network/ssrf.ts +1 -1
  152. package/src/network/{retry.ts → util/retry.ts} +1 -1
  153. package/src/observability/telemetry-buffer.ts +1 -1
  154. package/src/persistence/schema.ts +9 -0
  155. package/src/persistence/ttl-cache.ts +1 -1
  156. package/src/protocol/codecs.ts +58 -1
  157. package/src/protocol/request/messages.ts +31 -18
  158. package/src/protocol/response/messages.ts +34 -7
  159. package/src/protocol/translation/quirks.ts +15 -0
  160. package/src/protocol/upstream/send-claude-messages.ts +2 -2
  161. package/src/providers/adapters/compatible-adapter.ts +5 -0
  162. package/src/providers/authentication/oauth-client.ts +40 -6
  163. package/src/providers/authentication/oauth-device-flow.ts +7 -3
  164. package/src/providers/authentication/oauth-flow-store.ts +82 -1
  165. package/src/providers/authentication/oauth-refresh-service.ts +766 -739
  166. package/src/providers/default-registry.ts +76 -0
  167. package/src/providers/discovery/discovery-types.ts +7 -0
  168. package/src/providers/discovery/probe-phases.ts +6 -2
  169. package/src/providers/discovery/probing-service.ts +7 -0
  170. package/src/providers/integrations/antigravity/antigravity-protocol.ts +11 -0
  171. package/src/providers/integrations/buddy/account.ts +969 -0
  172. package/src/providers/integrations/buddy/capabilities.ts +10 -10
  173. package/src/providers/integrations/buddy/{buddy-catalog-shared.ts → catalog.ts} +198 -136
  174. package/src/providers/integrations/buddy/{buddy-chat-shared.ts → chat.ts} +5 -5
  175. package/src/providers/integrations/buddy/codebuddy/index.ts +429 -0
  176. package/src/providers/integrations/buddy/codebuddy/shared.ts +4 -4
  177. package/src/providers/integrations/buddy/{buddy-identity.ts → headers.ts} +138 -140
  178. package/src/providers/integrations/buddy/lifecycle.ts +1018 -0
  179. package/src/providers/integrations/buddy/{buddy-media.ts → media.ts} +1 -1
  180. package/src/providers/integrations/cline/cline-oauth.ts +10 -5
  181. package/src/providers/integrations/cline/cline.ts +3 -4
  182. package/src/providers/integrations/clixad/clixad-oauth.ts +98 -0
  183. package/src/providers/integrations/clixad/clixad-quota.ts +132 -0
  184. package/src/providers/integrations/clixad/provider.ts +145 -0
  185. package/src/providers/integrations/codex/codex-oauth.ts +8 -5
  186. package/src/providers/integrations/cursor/cursor-auth.ts +1 -1
  187. package/src/providers/integrations/cursor/cursor-hardening.ts +279 -0
  188. package/src/providers/integrations/cursor/cursor-http2.ts +605 -6
  189. package/src/providers/integrations/cursor/cursor-shared.ts +1 -1
  190. package/src/providers/integrations/cursor/cursor.ts +485 -70
  191. package/src/providers/integrations/deepai/deepai-catalog.ts +149 -0
  192. package/src/providers/integrations/deepai/deepai-common.ts +145 -0
  193. package/src/providers/integrations/deepai/deepai-oauth.ts +129 -0
  194. package/src/providers/integrations/deepai/deepai-quota.ts +97 -0
  195. package/src/providers/integrations/deepai/provider.ts +42 -0
  196. package/src/providers/integrations/devin/devin-auth.ts +7 -0
  197. package/src/providers/integrations/factory/factory-oauth.ts +16 -7
  198. package/src/providers/integrations/freebuff/freebuff.ts +2 -2
  199. package/src/providers/integrations/freepi/freepi-catalog.ts +5 -0
  200. package/src/providers/integrations/freepi/freepi-discovery.ts +2 -2
  201. package/src/providers/integrations/freepi/freepi-headers.ts +2 -2
  202. package/src/providers/integrations/freepi/freepi-protocol.ts +11 -2
  203. package/src/providers/integrations/freepi/freepi-realm.ts +0 -3
  204. package/src/providers/integrations/freepi/freepi-session.ts +158 -0
  205. package/src/providers/integrations/freepi/freepi.ts +80 -54
  206. package/src/providers/integrations/github/github-discovery.ts +30 -13
  207. package/src/providers/integrations/github/github-oauth.ts +217 -44
  208. package/src/providers/integrations/github/github-quota.ts +22 -5
  209. package/src/providers/integrations/github/github.ts +40 -32
  210. package/src/providers/integrations/grok/grok-oauth.ts +4 -4
  211. package/src/providers/integrations/hermes/hermes-oauth.ts +3 -3
  212. package/src/providers/integrations/hermes/hermes.ts +34 -5
  213. package/src/providers/integrations/kilo/kilo-oauth.ts +4 -4
  214. package/src/providers/integrations/kilo/kilo.ts +1 -1
  215. package/src/providers/integrations/kimi/kimi-oauth.ts +3 -3
  216. package/src/providers/integrations/kiro/kiro-oauth.ts +2 -2
  217. package/src/providers/integrations/muse/muse-oauth.ts +5 -5
  218. package/src/providers/integrations/opencode/fingerprint.ts +1 -1
  219. package/src/providers/integrations/openrouter/provider.ts +1 -1
  220. package/src/providers/integrations/perch/perch-protocol.ts +0 -3
  221. package/src/providers/integrations/perch/perch.ts +3 -3
  222. package/src/providers/integrations/qoder/claim-qoder-credits.ts +1 -1
  223. package/src/providers/integrations/qoder/qoder-adapter.ts +19 -113
  224. package/src/providers/integrations/qoder/qoder-auth.ts +8 -1
  225. package/src/providers/integrations/qoder/qoder-catalog.ts +1 -1
  226. package/src/providers/integrations/qoder/qoder-chat.ts +25 -8
  227. package/src/providers/integrations/qoder/qoder-checkin.ts +1 -1
  228. package/src/providers/integrations/qoder/qoder-cosy.ts +37 -9
  229. package/src/providers/integrations/qoder/qoder-oauth.ts +9 -2
  230. package/src/providers/integrations/qoder/qoder-realm.ts +13 -36
  231. package/src/providers/integrations/qoder/qoder-sse.ts +447 -68
  232. package/src/providers/integrations/qoder/qoder-types.ts +9 -0
  233. package/src/providers/integrations/qoder/qoder.ts +3 -25
  234. package/src/providers/integrations/sensenova/provider.ts +144 -0
  235. package/src/providers/integrations/trae/trae-quota.ts +15 -1
  236. package/src/providers/integrations/vercel/provider.ts +117 -0
  237. package/src/providers/integrations/vercel/vercel-quota.ts +96 -0
  238. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  239. package/src/providers/integrations/zcode-start-plan/gifts.ts +1 -1
  240. package/src/providers/integrations/zcode-start-plan/oauth.ts +3 -3
  241. package/src/providers/integrations/zro/zro.ts +2 -1
  242. package/src/providers/operations/account-refresh-status.ts +14 -0
  243. package/src/providers/operations/client-versions.ts +95 -30
  244. package/src/providers/operations/oauth-refresh-lead.ts +46 -22
  245. package/src/providers/operations/provider-caches.ts +1 -1
  246. package/src/providers/operations/provider-credential-service.ts +22 -25
  247. package/src/providers/operations/session-resolution.ts +17 -1
  248. package/src/providers/provider-contracts.ts +2 -2
  249. package/src/providers/provider-metadata.ts +30 -0
  250. package/src/providers/quota/quota-contracts.ts +2 -0
  251. package/src/providers/quota/refresh.ts +25 -3
  252. package/src/security/ip-boundary.ts +1 -1
  253. package/src/transport/dispatch/attempt-finalize.ts +1 -1
  254. package/src/transport/dispatch/attempt-loop.ts +3 -3
  255. package/src/transport/dispatch/handler-deps.ts +1 -1
  256. package/src/transport/dispatch/leases.ts +1 -1
  257. package/src/transport/dispatch/retry-policy.ts +1 -1
  258. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  259. package/src/transport/dispatch/streaming/stream.ts +1 -1
  260. package/src/transport/dispatch/upstream.ts +1 -1
  261. package/src/transport/shutdown-notice.ts +1 -1
  262. package/src/workers/buddy-growth-tasks.ts +8 -8
  263. package/src/workers/daily-checkin.ts +4 -4
  264. package/src/workers/quota-refresh-sweep.ts +1 -1
  265. package/src/workers/zcode-gift-claim.ts +1 -1
  266. package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
  267. package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
  268. package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
  269. package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
  270. package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
  271. package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
  272. package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
  273. package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
  274. package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
  275. package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
  276. package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
  277. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +0 -8
  278. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
  279. package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
  280. package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
  281. package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js +0 -9
  282. package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
  283. package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
  284. package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
  285. package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
  286. package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
  287. package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
  288. package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
  289. package/dist/dashboard/assets/app-Dx2QgsNj.css +0 -2
  290. package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
  291. package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
  292. package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
  293. package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
  294. package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
  295. package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
  296. package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
  297. package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
  298. package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
  299. package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
  300. package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
  301. package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
  302. package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
  303. package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
  304. package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
  305. package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
  306. package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
  307. package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
  308. package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
  309. package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
  310. package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
  311. package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
  312. package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
  313. package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
  314. package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
  315. package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
  316. package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
  317. package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
  318. package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
  319. package/src/console/providers/catalog/discover-constants.ts +0 -6
  320. package/src/network/pool-health.ts +0 -198
  321. package/src/providers/integrations/buddy/buddy-checkin.ts +0 -521
  322. package/src/providers/integrations/buddy/buddy-cli-headers.ts +0 -76
  323. package/src/providers/integrations/buddy/buddy-conversation-headers.ts +0 -130
  324. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +0 -234
  325. package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -496
  326. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +0 -341
  327. package/src/providers/integrations/buddy/buddy-quota-shared.ts +0 -417
  328. package/src/providers/integrations/buddy/buddy-server-tools.ts +0 -240
  329. package/src/providers/integrations/buddy/buddy-usage-shared.ts +0 -221
  330. package/src/providers/integrations/buddy/buddy-usage-store.ts +0 -181
  331. package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +0 -37
  332. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +0 -188
  333. package/src/providers/integrations/buddy/codebuddy/oauth.ts +0 -47
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +0 -179
  335. package/src/providers/integrations/buddy/codebuddy/quota.ts +0 -154
  336. package/src/providers/integrations/qoder/chat-proto.ts +0 -328
  337. package/src/providers/integrations/qoder/qoder-grpc.ts +0 -870
  338. package/src/providers/integrations/qoder/qoder-ide.ts +0 -481
  339. /package/dist/dashboard/assets/{app-DIXLjojg.js → app-C0gTXEoN.js} +0 -0
  340. /package/dist/dashboard/assets/{app-DIXLjojg.js.gz → app-C0gTXEoN.js.gz} +0 -0
  341. /package/src/network/{http2-bidi.ts → bidi.ts} +0 -0
  342. /package/src/network/pool/{byte-accounting.ts → accounting.ts} +0 -0
  343. /package/src/network/pool/{pool-scripts.ts → scripts.ts} +0 -0
  344. /package/src/network/pool/{pool-state.ts → state.ts} +0 -0
  345. /package/src/network/{backoff.ts → util/backoff.ts} +0 -0
  346. /package/src/network/{deduplication.ts → util/dedupe.ts} +0 -0
  347. /package/src/network/{ip-utils.ts → util/ip.ts} +0 -0
  348. /package/src/network/{rate-limit-verdict.ts → verdict.ts} +0 -0
@@ -43,12 +43,10 @@ import { InMemoryIpAbuseStore, IpAbuseProtectionService, RedisIpAbuseStore, type
43
43
  import { checkReadiness } from "../persistence/readiness";
44
44
  import { ProxyRequestPreparer } from "../transport/request/preparer";
45
45
  import { DrizzleNetworkPoolLoader } from "../network/pool/loader";
46
- import {
47
- PoolAgentResolver,
48
- ValidatedNetworkBindingFactory,
49
- } from "../network/pool/resolver";
46
+ import { PoolAgentResolver } from "../network/pool/resolver";
47
+ import { ValidatedNetworkBindingFactory } from "../network/egress/factory";
50
48
  import { NetworkPoolSelector } from "../network/pool/selector";
51
- import { restorePoolProbeVerdicts, restoreProviderCooldownMarkers } from "../network/pool-cooldown-store";
49
+ import { restorePoolProbeVerdicts, restoreProviderCooldownMarkers } from "../network/pool/cooldown-store";
52
50
  import { ScheduledTaskRegistry } from "../workers/scheduler";
53
51
  import { quotaRefreshSweep } from "../workers/quota-refresh-sweep";
54
52
  import { registerZcodeGiftClaimTask } from "../workers/zcode-gift-claim";
@@ -67,7 +65,7 @@ import { preferencesReaderFor } from "../persistence/tenant-preferences";
67
65
  import { sweepExpiredCooldowns } from "../providers/operations/account-health-service";
68
66
  import { DrizzleTelemetryStore } from "../persistence/stores/telemetry-store";
69
67
  import { TelemetryPayloadCapture } from "../observability/payload-capture";
70
- import { sweepExpiredPoolCooldowns } from "../network/pool-health-machine";
68
+ import { sweepExpiredPoolCooldowns } from "../network/pool/health";
71
69
  import { TelemetryBatchBuffer } from "../observability/telemetry-buffer";
72
70
  import { RuntimeMetricsSampler } from "../observability/runtime-metrics";
73
71
  import {
@@ -94,11 +94,12 @@ export function resolveGithubEnterpriseDomain(): string {
94
94
  export type GithubCopilotMode = "opencode-copilot" | "vscode-client-real";
95
95
 
96
96
  /**
97
- * Which GitHub Copilot wire identity the adapter uses. Defaults to
98
- * `opencode-copilot` (raw GitHub OAuth token + minimal OpenCode headers),
99
- * which is the proven-most-stable path (one token, no mint expiry). The
100
- * `vscode-client-real` mode matches the VS Code reference client exactly but
101
- * requires a freshly minted Copilot token.
97
+ * Selects the complete GitHub Copilot profile for OAuth login/refresh,
98
+ * inference, discovery, and quota identity. `opencode-copilot` is the default
99
+ * and uses the raw GitHub OAuth token with OpenCode identity. `vscode-client-real`
100
+ * uses the VS Code OAuth app and a minted Copilot token. Existing accounts must
101
+ * be re-authenticated after changing profiles; the upstream OAuth app binding
102
+ * prevents converting credentials between profiles.
102
103
  */
103
104
  export function resolveGithubCopilotMode(): GithubCopilotMode {
104
105
  const raw = readText(
@@ -326,15 +326,15 @@ export const CONFIG_SPEC = {
326
326
  */
327
327
  CARTETHYIA_GITHUB_ENTERPRISE_DOMAIN: { kind: "text", default: "" },
328
328
  /**
329
- * Which wire identity the GitHub Copilot Auto/chat path presents to the
330
- * upstream:
329
+ * Selects the complete GitHub Copilot OAuth and wire profile:
331
330
  *
332
- * - `opencode-copilot` (default): the long-lived GitHub OAuth token + minimal
333
- * OpenCode headers. One token, no mint step, no short-lived minted-token
334
- * expiry. This is the most stable in practice.
335
- * - `vscode-client-real`: a freshly minted Copilot token + the full VS Code
336
- * reference headers. Matches the VS Code client exactly, but requires the
337
- * minted token (expires ~25 min) and the reference identity.
331
+ * - `opencode-copilot` (default): OpenCode OAuth app, raw GitHub token, and
332
+ * OpenCode identity for login, refresh, inference, discovery, and quota.
333
+ * - `vscode-client-real`: VS Code OAuth app, minted Copilot token, and the
334
+ * VS Code reference identity for those surfaces.
335
+ *
336
+ * Restart after changing this setting and re-authenticate GitHub accounts;
337
+ * OAuth credentials cannot be converted between the two upstream apps.
338
338
  */
339
339
  CARTETHYIA_GITHUB_COPILOT_MODE: { kind: "text", default: "opencode-copilot" },
340
340
  // Only the literal true opts active ZCode accounts into daily gift claims.
@@ -23,6 +23,7 @@ import type { BackupPayload, BackupRow } from "./contracts";
23
23
  import { BACKUP_APP, BACKUP_VERSION } from "./contracts";
24
24
  import { isRecord } from "../../protocol/codecs";
25
25
  import { hashSecret } from "../../security/crypto";
26
+ import { resolveGithubCopilotMode, resolveGithubEnterpriseDomain } from "../../config/providers";
26
27
  import {
27
28
  AUTH_STATE_KEYS,
28
29
  COMBO_STRATEGIES,
@@ -100,6 +101,24 @@ interface ResolvedConnectionCredential {
100
101
  readonly value: string;
101
102
  readonly kind: "api_key" | "oauth";
102
103
  }
104
+
105
+ /** The provider-specific rebinding a router export may need before it becomes our envelope. */
106
+ export interface ImportedProviderCredential {
107
+ readonly credential: string;
108
+ readonly profile: "opencode-copilot" | "vscode-client-real";
109
+ readonly refreshToken?: string;
110
+ readonly expiresAt: Date;
111
+ readonly requiresRefresh: boolean;
112
+ readonly warnings: readonly string[];
113
+ }
114
+
115
+ export type ImportedProviderCredentialBinder = (
116
+ value: string,
117
+ refreshValue: string | null | undefined,
118
+ profile: "opencode-copilot" | "vscode-client-real",
119
+ domain: string,
120
+ expiresAt?: Date,
121
+ ) => ImportedProviderCredential;
103
122
  function credentialOf(entry: Row, provider: string): ResolvedConnectionCredential | null {
104
123
  const apiKey = text(entry.apiKey);
105
124
  const accessToken = text(entry.accessToken);
@@ -128,7 +147,7 @@ function credentialOf(entry: Row, provider: string): ResolvedConnectionCredentia
128
147
  * we have no such provider — a set entry with no provider behind it would
129
148
  * classify a row that can never import.
130
149
  */
131
- const OAUTH_PROVIDERS = new Set(["claude", "codex", "antigravity", "kimi", "cline"]);
150
+ const OAUTH_PROVIDERS = new Set(["claude", "codex", "antigravity", "kimi", "cline", "github"]);
132
151
 
133
152
  /** The non-secret per-account config, as our `auth_state` bag. */
134
153
  function authStateOf(entry: Row): Record<string, unknown> {
@@ -223,7 +242,11 @@ function modelReference(
223
242
  * leaving them null would make them global, i.e. visible to every tenant, which
224
243
  * an import must never do implicitly.
225
244
  */
226
- export function convert9RouterBackup(input: unknown, tenantId: string): ConversionResult {
245
+ export function convert9RouterBackup(
246
+ input: unknown,
247
+ tenantId: string,
248
+ importBinders: Readonly<Record<string, ImportedProviderCredentialBinder>> = {},
249
+ ): ConversionResult {
227
250
  if (typeof input !== "object" || input === null || Array.isArray(input)) {
228
251
  throw new Error("router backup must be a JSON object");
229
252
  }
@@ -273,6 +296,32 @@ export function convert9RouterBackup(input: unknown, tenantId: string): Conversi
273
296
  }
274
297
  const accountId = crypto.randomUUID();
275
298
  const kind = credential.kind;
299
+ const specific = isRecord(entry.providerSpecificData) ? entry.providerSpecificData : {};
300
+ const importedRefresh = text(entry.refreshToken);
301
+ const sourceExpiry = typeof entry.expiresAt === "string" && Number.isFinite(Date.parse(entry.expiresAt))
302
+ ? new Date(entry.expiresAt)
303
+ : undefined;
304
+ const importBinder = provider === "github" && kind === "oauth" ? importBinders.github : undefined;
305
+ let githubBinding: ImportedProviderCredential | undefined;
306
+ if (importBinder !== undefined) {
307
+ try {
308
+ githubBinding = importBinder(
309
+ credential.value,
310
+ importedRefresh,
311
+ resolveGithubCopilotMode(),
312
+ resolveGithubEnterpriseDomain() || "github.com",
313
+ sourceExpiry,
314
+ );
315
+ } catch (error) {
316
+ // One malformed row must not take the rest of the backup down with it.
317
+ // The row is reported and left out; the operator can re-authenticate it.
318
+ skipped.push(`${label}: GitHub Copilot credential could not be bound: ${error instanceof Error ? error.message : String(error)}`);
319
+ return;
320
+ }
321
+ }
322
+ const storedCredential = githubBinding?.credential ?? credential.value;
323
+ const storedRefresh = githubBinding?.refreshToken ?? importedRefresh;
324
+ const storedAuthState = authStateOf(entry).auth_state;
276
325
  accounts.push({
277
326
  id: accountId,
278
327
  provider_id: provider,
@@ -282,7 +331,7 @@ export function convert9RouterBackup(input: unknown, tenantId: string): Conversi
282
331
  // `SEALED_COLUMNS`. The store re-seals it under this instance's key on the
283
332
  // way in; sealing it here would put ciphertext in a payload whose only
284
333
  // portable form is the plaintext, and the restore would drop it.
285
- access_token: credential.value,
334
+ access_token: storedCredential,
286
335
  credential_kind: kind,
287
336
  status: bool(entry.isActive, true) ? "active" : "disabled",
288
337
  consecutive_failures: 0,
@@ -292,29 +341,41 @@ export function convert9RouterBackup(input: unknown, tenantId: string): Conversi
292
341
  // rather than invented — a lower number means the operator wants it used
293
342
  // first, and the column means the same thing.
294
343
  sort_index: typeof entry.priority === "number" && Number.isFinite(entry.priority) ? entry.priority : 0,
295
- ...(authStateOf(entry)),
344
+ ...(githubBinding === undefined
345
+ ? (storedAuthState === undefined ? {} : { auth_state: storedAuthState })
346
+ : {
347
+ auth_state: {
348
+ ...(isRecord(storedAuthState) ? storedAuthState : {}),
349
+ github_copilot_profile: githubBinding.profile,
350
+ },
351
+ }),
296
352
  ...(emailOf(entry)),
297
353
  created_at: { __date: isoDate(entry.createdAt, now) },
298
354
  });
299
355
  connectedProviders.add(provider);
300
356
  // The refresh token is a second secret on the same account, so it gets its
301
357
  // own sealed row rather than being folded into the credential.
302
- const specific = isRecord(entry.providerSpecificData) ? entry.providerSpecificData : {};
303
- const refresh = text(entry.refreshToken);
304
358
  const clientSecret = text(specific.clientSecret);
305
- if (refresh !== null || clientSecret !== null) {
359
+ for (const warning of githubBinding?.warnings ?? []) {
360
+ warnings.push(`account "${label}": ${warning}`);
361
+ }
362
+ if (storedRefresh !== null || clientSecret !== null || githubBinding?.requiresRefresh === true) {
306
363
  // A companion secret authorizes a refresh, so on its own it has nothing to
307
364
  // authorize. It is still carried rather than dropped, and the report says
308
365
  // why it is inert — a secret lost without a word is how an operator
309
366
  // discovers the loss from a failed refresh days later.
310
- if (clientSecret !== null && refresh === null) {
367
+ if (clientSecret !== null && storedRefresh === null) {
311
368
  warnings.push(`account "${label}": carried a client secret with no refresh token; it cannot authorize a refresh`);
312
369
  }
313
370
  oauthStates.push({
314
371
  provider_account_id: accountId,
315
- ...(refresh === null ? {} : { refresh_token: refresh }),
372
+ ...(storedRefresh === null ? {} : { refresh_token: storedRefresh }),
316
373
  ...(clientSecret === null ? {} : { client_secret: clientSecret }),
317
- ...(typeof entry.expiresAt === "string" ? { expires_at: { __date: isoDate(entry.expiresAt, now) } } : {}),
374
+ ...(githubBinding !== undefined
375
+ ? { expires_at: { __date: githubBinding.expiresAt.toISOString() } }
376
+ : typeof entry.expiresAt === "string"
377
+ ? { expires_at: { __date: isoDate(entry.expiresAt, now) } }
378
+ : {}),
318
379
  });
319
380
  }
320
381
  });
@@ -311,7 +311,14 @@ export class BackupService {
311
311
  }
312
312
 
313
313
  if (detected.kind === "nine_router") {
314
- const { payload: converted, report } = convert9RouterBackup(detected.payload, tenantId);
314
+ // dynamic-import: lazy OAuth graph — pulling the Github OAuth client into
315
+ // the console boot graph would make every console route pay for it.
316
+ const { bindImportedGithubCredential } = await import(
317
+ "../../providers/integrations/github/github-oauth"
318
+ );
319
+ const { payload: converted, report } = convert9RouterBackup(detected.payload, tenantId, {
320
+ github: bindImportedGithubCredential,
321
+ });
315
322
  const result = await this.apply(converted, tenantId, selection);
316
323
  return { ...result, report, format: "nine_router" };
317
324
  }
@@ -33,7 +33,7 @@ import { DrizzleCliToolSecretSource } from "./cli-tools/secret-source";
33
33
  import type { ShareLinkStore } from "../persistence/stores/share-store";
34
34
  import type { ProviderRegistry } from "../providers/provider-registry";
35
35
  import type { BundledProviderCatalog } from "../providers/operations/provider-catalog-service";
36
- import type { ValidatedNetworkBindingFactory } from "../network/pool/resolver";
36
+ import type { ValidatedNetworkBindingFactory } from "../network/egress/factory";
37
37
  import type { TrustedProxyBoundary } from "../config/network";
38
38
  import type { IpAbuseStore } from "../security/abuse";
39
39
  import { gzipResponse } from "./response-compression";
@@ -65,7 +65,7 @@ import {
65
65
  } from "../persistence/stores/share-store";
66
66
  import { createShareUsagePort } from "./share/share-usage";
67
67
  import { resolveSsrfPolicy } from "../config/network";
68
- import { createValidatedFetch } from "../network/outbound-fetch";
68
+ import { createValidatedFetch } from "../network/egress/fetch";
69
69
  import type { AuditRecorder } from "./auth/audit-recorder";
70
70
  import type { CliToolService } from "./cli-tools/service";
71
71
  import type { NetworkPoolSelector } from "../network/pool/selector";
@@ -77,7 +77,7 @@ import { resolveRedisBackend } from "../persistence/redis";
77
77
  import type { RedisClient } from "../persistence/redis";
78
78
  import type { ProviderRegistry } from "../providers/provider-registry";
79
79
  import type { BundledProviderCatalog } from "../providers/operations/provider-catalog-service";
80
- import type { ValidatedNetworkBindingFactory } from "../network/pool/resolver";
80
+ import type { ValidatedNetworkBindingFactory } from "../network/egress/factory";
81
81
  import type { CartethyiaDatabase } from "../persistence/db-handle";
82
82
  import type { ConsoleAccessResolver } from "./auth/access";
83
83
 
@@ -434,6 +434,11 @@ export function registerConsoleDomains(
434
434
  accessResolver: ctx.accessResolver,
435
435
  snapshotInvalidator: ctx.routeSnapshotService,
436
436
  callbackListener: oauthCallbackListener,
437
+ deviceEgress: {
438
+ db: ctx.db,
439
+ poolSelector: ctx.poolSelector,
440
+ networkBindingFactory: ctx.networkBindingFactory,
441
+ },
437
442
  };
438
443
  console.use(createOAuthLoginRoutes(oauthConfig));
439
444
  }
@@ -13,7 +13,7 @@
13
13
  * and a failure returns `undefined` — never a half-parsed object that a route
14
14
  * would render as if it were good.
15
15
  */
16
- import { createValidatedFetch, type ValidatedFetch } from "../../network/outbound-fetch";
16
+ import { createValidatedFetch, type ValidatedFetch } from "../../network/egress/fetch";
17
17
 
18
18
  export const INFERHUB_API_BASE = "https://inferhub.dev/api";
19
19
 
@@ -29,8 +29,8 @@ import type { NetworkPoolSelector } from "../../network/pool/selector";
29
29
  import { eq } from "drizzle-orm";
30
30
  import type { CartethyiaDatabase } from "../../persistence/db-handle";
31
31
  import { networkPools } from "../../persistence/schema";
32
- import { subscribePoolHealth } from "../../network/pool-health-machine";
33
- import { poolByteSnapshot } from "../../network/pool/byte-accounting";
32
+ import { subscribePoolHealth } from "../../network/pool/health";
33
+ import { poolByteSnapshot } from "../../network/pool/accounting";
34
34
  import { consoleSseResponse, createConsoleSseStream } from "./sse";
35
35
  import { subscribeRequestCompleted } from "../../observability/request-notify";
36
36
 
@@ -83,9 +83,6 @@ export interface ProviderAccountBulkActionResult {
83
83
  readonly globalSkipped: number;
84
84
  }
85
85
 
86
- /** Cap on one discovery-commit request (D29). Kept pure (no `node:*`) so the dashboard can import it. */
87
- export { DISCOVER_MODEL_COMMIT_MAX } from "./discover-constants";
88
-
89
86
  /**
90
87
  * One model the provider's own listing advertised, projected for the Add-Model
91
88
  * picker. Read-only: `GET .../models/discover` writes nothing. `models`
@@ -610,6 +607,9 @@ export interface ProviderAccountResponse {
610
607
  providerId: string;
611
608
  tenantId: string | null;
612
609
  label: string;
610
+ /** Structured identity learned from an OAuth login, when the provider exposed one. */
611
+ accountEmail?: string;
612
+ accountName?: string;
613
613
  credentialKind: CredentialKind;
614
614
  credentialMode?: CredentialMode;
615
615
  /**
@@ -1056,6 +1056,10 @@ export interface ProviderRoutingResponse {
1056
1056
  * default to skipping because their transport can't route through an HTTP
1057
1057
  * CONNECT proxy; it stays a real, per-tenant-overridable setting. */
1058
1058
  readonly skipProxy: boolean;
1059
+ /** How device-code OAuth flows choose their egress: `random` (default)
1060
+ * routes start+poll through a randomly selected active network pool so the
1061
+ * upstream sees a rotating IP; `direct` always dials direct egress. */
1062
+ readonly deviceFlowProxy: "random" | "direct";
1059
1063
  /** Built-in API-key upstream User-Agent; OAuth and custom providers retain their own identity. */
1060
1064
  readonly userAgent: string;
1061
1065
  /** Operator-set custom User-Agent override; `null` = no override (native identity is used). */
@@ -1089,6 +1093,8 @@ export interface UpdateProviderRoutingRequest {
1089
1093
  readonly enabled?: boolean;
1090
1094
  /** When true, this provider's requests always dial direct. */
1091
1095
  readonly skipProxy?: boolean;
1096
+ /** How device-code OAuth flows choose their egress; absent = keep current. */
1097
+ readonly deviceFlowProxy?: "random" | "direct";
1092
1098
  /** Built-in API-key upstream User-Agent. */
1093
1099
  readonly userAgent?: string;
1094
1100
  /** Operator-set custom User-Agent override; `null` clears it back to native. */
@@ -12,7 +12,6 @@ import type { AccessDecision } from "../../../security/access-control";
12
12
  import { ConsoleDomainError, requireScope, requireTenantAnyScope } from "../../shared/errors";
13
13
  import { GatewayError } from "../../../protocol/gateway-error";
14
14
  import {
15
- DISCOVER_MODEL_COMMIT_MAX,
16
15
  MODEL_READ_SCOPES,
17
16
  MODEL_WRITE_SCOPES,
18
17
  } from "./contracts";
@@ -390,11 +389,11 @@ export function createModelCatalogOperations(config: ProviderCatalogConfig) {
390
389
  "modelIds must be non-empty model ids",
391
390
  );
392
391
  }
393
- if (modelIds.length === 0 || modelIds.length > DISCOVER_MODEL_COMMIT_MAX) {
392
+ if (modelIds.length === 0) {
394
393
  throw new ConsoleDomainError(
395
394
  "invalid_request",
396
395
  400,
397
- `modelIds must contain 1-${DISCOVER_MODEL_COMMIT_MAX} entries`,
396
+ "modelIds must contain at least one entry",
398
397
  );
399
398
  }
400
399
  try {
@@ -892,7 +892,7 @@ export function createProviderCatalogOperations(config: ProviderCatalogConfig) {
892
892
  // dynamic-import: B-02 lazy graph — buddy device-binding materializer, buddy-family only.
893
893
  // The buddy-identity graph is lazy-loaded: the device-binding
894
894
  // materializer only runs for buddy-family accounts (B-02).
895
- ? (await import("../../../providers/integrations/buddy/buddy-identity"))
895
+ ? (await import("../../../providers/integrations/buddy/headers"))
896
896
  .materializeBuddyDeviceBinding(account.id, authState)
897
897
  : undefined;
898
898
  const effectiveAuthState = materialized ?? authState;
@@ -5,7 +5,6 @@ import { SERVICE_KINDS, WIRE_FAMILIES } from "../../../protocol/canonical-model"
5
5
  import { PROBE_MODES, PROBE_REASONING_EFFORTS } from "../../../providers/discovery/discovery-types";
6
6
  import {
7
7
  ACCOUNT_STATUSES,
8
- DISCOVER_MODEL_COMMIT_MAX,
9
8
  CREDENTIAL_KINDS,
10
9
  CREDENTIAL_MODES,
11
10
  } from "./contracts";
@@ -133,7 +132,7 @@ const registerModelsBody = t.Object({
133
132
  metadata: t.Optional(modelMetadataOverrideBody),
134
133
  });
135
134
  const discoverCommitBody = t.Object({
136
- modelIds: t.Array(t.String(), { minItems: 1, maxItems: DISCOVER_MODEL_COMMIT_MAX }),
135
+ modelIds: t.Array(t.String(), { minItems: 1 }),
137
136
  });
138
137
  const probeModelBody = t.Object({
139
138
  modelId: t.String(),
@@ -141,6 +140,7 @@ const probeModelBody = t.Object({
141
140
  route: t.Optional(t.String()),
142
141
  wireFamily: t.Optional(t.String()),
143
142
  accountId: t.Optional(t.String()),
143
+ accountIds: t.Optional(t.Array(t.String(), { maxItems: 100 })),
144
144
  prompt: t.Optional(t.String()),
145
145
  reasoningEffort: t.Optional(literalUnion(PROBE_REASONING_EFFORTS)),
146
146
  maxOutputTokens: t.Optional(t.Integer({ minimum: 1, maximum: 131072 })),