cartethyia 2.6.7 → 2.7.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 (335) hide show
  1. package/.env.example +1 -7
  2. package/README.md +25 -2
  3. package/dist/dashboard/assets/{BannedPage-Dskhyp0l.js → BannedPage-D-J75hBM.js} +1 -1
  4. package/dist/dashboard/assets/BannedPage-D-J75hBM.js.gz +0 -0
  5. package/dist/dashboard/assets/{CliToolDetailPage--SJhk7qQ.js → CliToolDetailPage-CVe6RaBH.js} +1 -1
  6. package/dist/dashboard/assets/CliToolDetailPage-CVe6RaBH.js.gz +0 -0
  7. package/dist/dashboard/assets/{CliToolsPage-C203VT-c.js → CliToolsPage-Dd8ZSamp.js} +1 -1
  8. package/dist/dashboard/assets/CliToolsPage-Dd8ZSamp.js.gz +0 -0
  9. package/dist/dashboard/assets/{CombosPage-BcS7kGG1.js → CombosPage-QoJ6foxo.js} +1 -1
  10. package/dist/dashboard/assets/CombosPage-QoJ6foxo.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-DpNRay4C.js.gz +0 -0
  13. package/dist/dashboard/assets/{CustomizationPage-uujbBYwC.js → CustomizationPage-CKUFTcW4.js} +1 -1
  14. package/dist/dashboard/assets/CustomizationPage-CKUFTcW4.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-CzSLiDzr.js.gz +0 -0
  17. package/dist/dashboard/assets/LoginPage-DubdQcvX.js +1 -0
  18. package/dist/dashboard/assets/LoginPage-DubdQcvX.js.gz +0 -0
  19. package/dist/dashboard/assets/{ModelPicker-CA1kLs45.js → ModelPicker-BH8Tehdi.js} +1 -1
  20. package/dist/dashboard/assets/ModelPicker-BH8Tehdi.js.gz +0 -0
  21. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js +1 -0
  22. package/dist/dashboard/assets/OverviewPage-DuWzAQFL.js.gz +0 -0
  23. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js +4 -0
  24. package/dist/dashboard/assets/ProviderDetailPage-BKEKe2Fm.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +1 -0
  26. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  27. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js +1 -0
  28. package/dist/dashboard/assets/ProvidersPage-Bwotu8UJ.js.gz +0 -0
  29. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js +9 -0
  30. package/dist/dashboard/assets/ProxyPage-D7hpWbg9.js.gz +0 -0
  31. package/dist/dashboard/assets/{QuotaPage-BueSWX5D.js → QuotaPage-ATpaxrbl.js} +1 -1
  32. package/dist/dashboard/assets/QuotaPage-ATpaxrbl.js.gz +0 -0
  33. package/dist/dashboard/assets/SettingsPage-CETophpx.js +1 -0
  34. package/dist/dashboard/assets/SettingsPage-CETophpx.js.gz +0 -0
  35. package/dist/dashboard/assets/SetupPage-BdgECjqq.js +1 -0
  36. package/dist/dashboard/assets/SetupPage-BdgECjqq.js.gz +0 -0
  37. package/dist/dashboard/assets/{SortableList-DrKeMcGN.js → SortableList-CAK-EN9z.js} +1 -1
  38. package/dist/dashboard/assets/SortableList-CAK-EN9z.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-qjuYtccc.js → StudioPage-B7W2_RhT.js} +3 -3
  40. package/dist/dashboard/assets/StudioPage-B7W2_RhT.js.gz +0 -0
  41. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js +56 -0
  42. package/dist/dashboard/assets/UsagePage-6T4EFDjW.js.gz +0 -0
  43. package/dist/dashboard/assets/{api-keys-C23S9sgp.js → api-keys-CUi6UXsR.js} +1 -1
  44. package/dist/dashboard/assets/api-keys-CUi6UXsR.js.gz +0 -0
  45. package/dist/dashboard/assets/app-KvsUJUMF.css +2 -0
  46. package/dist/dashboard/assets/app-KvsUJUMF.css.gz +0 -0
  47. package/dist/dashboard/assets/{assert-DU6qrMA_.js → assert-67xXH5rf.js} +1 -1
  48. package/dist/dashboard/assets/assert-67xXH5rf.js.gz +0 -0
  49. package/dist/dashboard/assets/{badge-Bkz_-RrM.js → badge-DC2L43Mj.js} +1 -1
  50. package/dist/dashboard/assets/badge-DC2L43Mj.js.gz +0 -0
  51. package/dist/dashboard/assets/{banner-C-7y3VKV.js → banner-BBVcb0J3.js} +1 -1
  52. package/dist/dashboard/assets/banner-BBVcb0J3.js.gz +0 -0
  53. package/dist/dashboard/assets/{card-BOPBuBzD.js → card-Cca1XC6G.js} +1 -1
  54. package/dist/dashboard/assets/card-Cca1XC6G.js.gz +0 -0
  55. package/dist/dashboard/assets/{cli-tools-BaFUuFFF.js → cli-tools-KvsWa1Jl.js} +1 -1
  56. package/dist/dashboard/assets/cli-tools-KvsWa1Jl.js.gz +0 -0
  57. package/dist/dashboard/assets/{clipboard-button-e-Mlk0FH.js → clipboard-button-DUzEbynq.js} +1 -1
  58. package/dist/dashboard/assets/clipboard-button-DUzEbynq.js.gz +0 -0
  59. package/dist/dashboard/assets/{dialog-Iec_ywbD.js → dialog-DFvWhwTa.js} +1 -1
  60. package/dist/dashboard/assets/dialog-DFvWhwTa.js.gz +0 -0
  61. package/dist/dashboard/assets/{drawer-Bs8MIIHc.js → drawer-CFM2sMX1.js} +1 -1
  62. package/dist/dashboard/assets/drawer-CFM2sMX1.js.gz +0 -0
  63. package/dist/dashboard/assets/{entry-DOddwoc0.js → entry-BLBLxX0h.js} +3 -3
  64. package/dist/dashboard/assets/entry-BLBLxX0h.js.gz +0 -0
  65. package/dist/dashboard/assets/{entry-DcobaKFu.js → entry-Bqy8RFvM.js} +1 -1
  66. package/dist/dashboard/assets/entry-Bqy8RFvM.js.gz +0 -0
  67. package/dist/dashboard/assets/{entry-BRszm4_Z.js → entry-_xHo5x6r.js} +1 -1
  68. package/dist/dashboard/assets/entry-_xHo5x6r.js.gz +0 -0
  69. package/dist/dashboard/assets/formatters-mpBPqAQ8.js +1 -0
  70. package/dist/dashboard/assets/formatters-mpBPqAQ8.js.gz +0 -0
  71. package/dist/dashboard/assets/{github-badge-BuDsrsPn.js → github-badge-C9e8Ts7e.js} +1 -1
  72. package/dist/dashboard/assets/github-badge-C9e8Ts7e.js.gz +0 -0
  73. package/dist/dashboard/assets/{index-BeLRhsmt.js → index-D6QzEC_n.js} +2 -2
  74. package/dist/dashboard/assets/index-D6QzEC_n.js.gz +0 -0
  75. package/dist/dashboard/assets/{inline-DToMICwl.js → inline-BFUcvllj.js} +1 -1
  76. package/dist/dashboard/assets/inline-BFUcvllj.js.gz +0 -0
  77. package/dist/dashboard/assets/{input-WlyHWeG2.js → input-C_ILAvBb.js} +1 -1
  78. package/dist/dashboard/assets/input-C_ILAvBb.js.gz +0 -0
  79. package/dist/dashboard/assets/{layout-DaJ5baJr.js → layout-CBIyT6Rt.js} +1 -1
  80. package/dist/dashboard/assets/layout-CBIyT6Rt.js.gz +0 -0
  81. package/dist/dashboard/assets/{list-row-B3oSK13z.js → list-row-ebJ_-Nsb.js} +1 -1
  82. package/dist/dashboard/assets/list-row-ebJ_-Nsb.js.gz +0 -0
  83. package/dist/dashboard/assets/{live-ta6GMb-8.js → live-D0mm--ME.js} +1 -1
  84. package/dist/dashboard/assets/live-D0mm--ME.js.gz +0 -0
  85. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +1 -0
  86. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  87. package/dist/dashboard/assets/{mutation-g_fduiNw.js → mutation-sMD965oO.js} +1 -1
  88. package/dist/dashboard/assets/mutation-sMD965oO.js.gz +0 -0
  89. package/dist/dashboard/assets/{numbers-Dulqgys5.js → numbers-BO9dKaFr.js} +1 -1
  90. package/dist/dashboard/assets/numbers-BO9dKaFr.js.gz +0 -0
  91. package/dist/dashboard/assets/providers/inception.svg +5 -0
  92. package/dist/dashboard/assets/providers/inception.svg.gz +0 -0
  93. package/dist/dashboard/assets/{query-keys-UETqfytp.js → query-keys-CfL_Zdoh.js} +1 -1
  94. package/dist/dashboard/assets/query-keys-CfL_Zdoh.js.gz +0 -0
  95. package/dist/dashboard/assets/{routing-BPUo-W8d.js → routing-BnIpi1IJ.js} +1 -1
  96. package/dist/dashboard/assets/routing-BnIpi1IJ.js.gz +0 -0
  97. package/dist/dashboard/assets/{select-BfZ3SCTM.js → select-Cj5Nw43g.js} +1 -1
  98. package/dist/dashboard/assets/select-Cj5Nw43g.js.gz +0 -0
  99. package/dist/dashboard/assets/settings-BAFhDgX8.js +1 -0
  100. package/dist/dashboard/assets/settings-BAFhDgX8.js.gz +0 -0
  101. package/dist/dashboard/assets/{stack-B1w5BM0u.js → stack-EMrOMt4I.js} +1 -1
  102. package/dist/dashboard/assets/stack-EMrOMt4I.js.gz +0 -0
  103. package/dist/dashboard/assets/{state-DhZBfWgx.js → state-CWoo7ty5.js} +1 -1
  104. package/dist/dashboard/assets/state-CWoo7ty5.js.gz +0 -0
  105. package/dist/dashboard/assets/{switch-yD7D99Lg.js → switch-CCjT6IkF.js} +1 -1
  106. package/dist/dashboard/assets/switch-CCjT6IkF.js.gz +0 -0
  107. package/dist/dashboard/assets/{useMutation-EDFRkn1i.js → useMutation-DjkLHUcE.js} +1 -1
  108. package/dist/dashboard/assets/useMutation-DjkLHUcE.js.gz +0 -0
  109. package/dist/dashboard/index.html +1 -1
  110. package/dist/dashboard/index.html.gz +0 -0
  111. package/dist/dashboard/precompressed-assets.json +55 -54
  112. package/migrations/full-postgres/0024_add_pool_provider_cooldowns.sql +12 -0
  113. package/migrations/full-postgres/0025_add_pool_random_strategy.sql +3 -0
  114. package/migrations/lite-sqlite3/0024_add_pool_provider_cooldowns.sql +12 -0
  115. package/migrations/lite-sqlite3/0025_add_pool_random_strategy.sql +20 -0
  116. package/package.json +1 -1
  117. package/scripts/cli/console-menu.ts +5 -2
  118. package/scripts/cli/tray.ts +21 -6
  119. package/src/boot/app.ts +24 -62
  120. package/src/boot/dependencies.ts +732 -750
  121. package/src/config/cooldowns.ts +16 -0
  122. package/src/config/providers.ts +13 -1
  123. package/src/config/resources.ts +13 -80
  124. package/src/config/security.ts +2 -38
  125. package/src/config/spec.ts +16 -23
  126. package/src/console/console-router.ts +7 -7
  127. package/src/console/domain-registration.ts +19 -12
  128. package/src/console/providers/catalog/catalog-projections.ts +2 -6
  129. package/src/console/providers/catalog/contracts.ts +19 -0
  130. package/src/console/providers/catalog/provider-operations.ts +38 -0
  131. package/src/console/providers/catalog/routes.ts +14 -0
  132. package/src/console/providers/catalog/store-helpers.ts +326 -0
  133. package/src/console/providers/catalog/store.ts +1292 -1563
  134. package/src/console/quota/account-quota-global.ts +2 -2
  135. package/src/console/quota/account-quota-shared.ts +1 -1
  136. package/src/console/quota/account-quota-tenant.ts +35 -12
  137. package/src/console/quota/quota-view.ts +2 -2
  138. package/src/console/remote-support/contracts.ts +3 -1
  139. package/src/console/remote-support/service.ts +115 -6
  140. package/src/console/routing/pools/contracts.ts +41 -1
  141. package/src/console/routing/pools/operations.ts +183 -4
  142. package/src/console/routing/pools/relay-deploy.ts +17 -4
  143. package/src/console/routing/pools/routes.ts +30 -0
  144. package/src/console/routing/pools/store.ts +98 -8
  145. package/src/main.ts +16 -2
  146. package/src/network/outbound-fetch.ts +226 -365
  147. package/src/network/pool/agent.ts +8 -0
  148. package/src/network/pool/pool-state.ts +7 -0
  149. package/src/network/pool/selector.ts +110 -2
  150. package/src/network/pool-cooldown-store.ts +252 -0
  151. package/src/network/pool-health-machine.ts +5 -3
  152. package/src/network/pool-health.ts +36 -9
  153. package/src/observability/event-query.ts +57 -0
  154. package/src/observability/metrics.ts +15 -5
  155. package/src/observability/runtime-metrics.ts +30 -15
  156. package/src/persistence/health-event-flush.ts +2 -0
  157. package/src/persistence/schema.ts +19 -0
  158. package/src/persistence/usage-flush.ts +8 -3
  159. package/src/protocol/canonical-model.ts +1 -1
  160. package/src/protocol/dsml.ts +377 -0
  161. package/src/protocol/gateway-error.ts +0 -1
  162. package/src/{providers/provider-reasoning.ts → protocol/reasoning.ts} +10 -9
  163. package/src/protocol/request/chat.ts +7 -7
  164. package/src/protocol/request/codex.ts +2 -2
  165. package/src/protocol/request/gemini.ts +1 -1
  166. package/src/protocol/request/messages.ts +6 -6
  167. package/src/protocol/request/responses.ts +7 -7
  168. package/src/protocol/response/dsml.ts +12 -133
  169. package/src/{transport → protocol}/translation/attachment-integrity.ts +2 -2
  170. package/src/{transport → protocol}/translation/cache-controls.ts +1 -1
  171. package/src/{transport → protocol}/translation/capabilities.ts +2 -2
  172. package/src/{transport → protocol}/translation/normalize.ts +1 -1
  173. package/src/{transport → protocol}/translation/quirks.ts +1 -1
  174. package/src/{transport → protocol}/translation/search.ts +1 -1
  175. package/src/{transport → protocol}/translation/thinking.ts +23 -1
  176. package/src/{transport → protocol}/translation/tool-id.ts +1 -1
  177. package/src/{transport → protocol}/translation/tool-repair.ts +2 -2
  178. package/src/protocol/upstream-parsing.ts +176 -0
  179. package/src/providers/adapters/compatible-adapter.ts +11 -2
  180. package/src/providers/authentication/oauth-refresh-service.ts +9 -5
  181. package/src/providers/default-registry.ts +21 -5
  182. package/src/providers/discovery/probe-phases.ts +16 -3
  183. package/src/providers/discovery/probing-service.ts +4 -1
  184. package/src/providers/integrations/anthropic.ts +1 -1
  185. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -4
  186. package/src/providers/integrations/buddy/buddy-chat-shared.ts +141 -8
  187. package/src/providers/integrations/buddy/buddy-checkin.ts +5 -1
  188. package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -82
  189. package/src/providers/integrations/buddy/buddy-identity.ts +25 -0
  190. package/src/providers/integrations/buddy/buddy-server-tools.ts +240 -0
  191. package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +36 -0
  192. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +6 -31
  193. package/src/providers/integrations/buddy/codebuddy/provider.ts +2 -0
  194. package/src/providers/integrations/buddy/codebuddy/shared.ts +19 -4
  195. package/src/providers/integrations/buddy/turing-device-token.ts +262 -0
  196. package/src/providers/integrations/buddy/workbuddy/provider.ts +2 -0
  197. package/src/providers/integrations/buddy/workbuddy/shared.ts +56 -3
  198. package/src/providers/integrations/claude/claude.ts +1 -1
  199. package/src/providers/integrations/cloudflareai/cloudflareai.ts +1 -1
  200. package/src/providers/integrations/codex/codex-errors.ts +1 -1
  201. package/src/providers/integrations/codex/codex.ts +1 -1
  202. package/src/providers/integrations/commandcode/commandcode.ts +134 -104
  203. package/src/providers/integrations/commandcode/discovery.ts +6 -5
  204. package/src/providers/integrations/factory/factory.ts +1 -1
  205. package/src/providers/integrations/github/github.ts +1 -1
  206. package/src/providers/integrations/grok/grok.ts +1 -1
  207. package/src/providers/integrations/inception/provider.ts +91 -0
  208. package/src/providers/integrations/inferhub.ts +1 -1
  209. package/src/providers/integrations/kiro/kiro-request.ts +1 -1
  210. package/src/providers/integrations/mistral.ts +193 -19
  211. package/src/providers/integrations/opencode/fingerprint.ts +19 -2
  212. package/src/providers/integrations/opencode/prompt.ts +111 -0
  213. package/src/providers/integrations/opencode/provider.ts +101 -23
  214. package/src/providers/integrations/opencode/tool-definitions.ts +4 -4
  215. package/src/providers/integrations/qoder/qoder-checkin.ts +303 -0
  216. package/src/providers/integrations/qoder/qoder.ts +1641 -884
  217. package/src/providers/integrations/shared/install-id.ts +2 -1
  218. package/src/providers/integrations/trae/trae-cache.ts +110 -0
  219. package/src/providers/integrations/trae/trae-oauth.ts +29 -4
  220. package/src/providers/integrations/trae/trae-protocol.ts +2 -1
  221. package/src/providers/integrations/trae/trae.ts +106 -23
  222. package/src/providers/operations/account-error-classification.ts +1660 -0
  223. package/src/providers/operations/account-health-service.ts +621 -2097
  224. package/src/providers/operations/account-reset-service.ts +2 -0
  225. package/src/providers/provider-contracts.ts +0 -2
  226. package/src/providers/provider-metadata.ts +25 -4
  227. package/src/providers/provider-probe.ts +2 -2
  228. package/src/{console → providers}/quota/cache.ts +1 -1
  229. package/src/{console → providers}/quota/refresh.ts +5 -5
  230. package/src/security/abuse.ts +17 -0
  231. package/src/transport/dispatch/attempt-finalize.ts +114 -12
  232. package/src/transport/dispatch/attempt-loop.ts +3 -0
  233. package/src/transport/dispatch/empty-stream.ts +224 -217
  234. package/src/transport/dispatch/generation.ts +37 -55
  235. package/src/transport/dispatch/handler-deps.ts +32 -0
  236. package/src/transport/dispatch/leases.ts +9 -4
  237. package/src/transport/dispatch/proxy-request.ts +6 -30
  238. package/src/transport/dispatch/responses-compact.ts +22 -43
  239. package/src/transport/dispatch/streaming/finalize.ts +3 -0
  240. package/src/transport/dispatch/streaming/stream.ts +0 -8
  241. package/src/transport/dispatch/systemone.ts +22 -42
  242. package/src/transport/dispatch/token-count.ts +23 -39
  243. package/src/transport/dispatch/upstream.ts +1 -3
  244. package/src/transport/dispatch/websearch.ts +22 -41
  245. package/src/transport/failure-policy.ts +59 -178
  246. package/src/transport/guards/abuse-guard.ts +10 -0
  247. package/src/transport/guards/auth-guard.ts +0 -18
  248. package/src/transport/guards/error-lifecycle.ts +1 -1
  249. package/src/transport/guards/pipeline.ts +0 -6
  250. package/src/transport/guards/request-context.ts +18 -91
  251. package/src/transport/request/degradation.ts +20 -1
  252. package/src/transport/request/inflight.ts +4 -95
  253. package/src/transport/request/preparer.ts +6 -6
  254. package/src/transport/request/state.ts +66 -38
  255. package/src/transport/request/tenant-preferences.ts +1 -1
  256. package/src/transport/routing/route-catalog.ts +41 -31
  257. package/src/transport/routing/router.ts +2 -2
  258. package/src/transport/surface/messages/parse.ts +1 -1
  259. package/src/workers/buddy-growth-tasks.ts +346 -425
  260. package/src/workers/daily-checkin.ts +17 -6
  261. package/src/workers/quota-refresh-sweep.ts +2 -2
  262. package/src/workers/scheduler.ts +17 -1
  263. package/dist/dashboard/assets/BannedPage-Dskhyp0l.js.gz +0 -0
  264. package/dist/dashboard/assets/CliToolDetailPage--SJhk7qQ.js.gz +0 -0
  265. package/dist/dashboard/assets/CliToolsPage-C203VT-c.js.gz +0 -0
  266. package/dist/dashboard/assets/CombosPage-BcS7kGG1.js.gz +0 -0
  267. package/dist/dashboard/assets/ConsoleLogPage-ChmiSLwO.js +0 -1
  268. package/dist/dashboard/assets/ConsoleLogPage-ChmiSLwO.js.gz +0 -0
  269. package/dist/dashboard/assets/CustomizationPage-uujbBYwC.js.gz +0 -0
  270. package/dist/dashboard/assets/HealthEventsModal-fKAWd-OQ.js +0 -1
  271. package/dist/dashboard/assets/HealthEventsModal-fKAWd-OQ.js.gz +0 -0
  272. package/dist/dashboard/assets/LoginPage-DoOUthbG.js +0 -1
  273. package/dist/dashboard/assets/LoginPage-DoOUthbG.js.gz +0 -0
  274. package/dist/dashboard/assets/ModelPicker-CA1kLs45.js.gz +0 -0
  275. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js +0 -1
  276. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js.gz +0 -0
  277. package/dist/dashboard/assets/ProviderDetailPage-CFu1qGcT.js +0 -3
  278. package/dist/dashboard/assets/ProviderDetailPage-CFu1qGcT.js.gz +0 -0
  279. package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js +0 -1
  280. package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js.gz +0 -0
  281. package/dist/dashboard/assets/ProvidersPage-CnlJZbxF.js +0 -1
  282. package/dist/dashboard/assets/ProvidersPage-CnlJZbxF.js.gz +0 -0
  283. package/dist/dashboard/assets/ProxyPage-B9mBTweh.js +0 -7
  284. package/dist/dashboard/assets/ProxyPage-B9mBTweh.js.gz +0 -0
  285. package/dist/dashboard/assets/QuotaPage-BueSWX5D.js.gz +0 -0
  286. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js +0 -1
  287. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js.gz +0 -0
  288. package/dist/dashboard/assets/SetupPage-DQ9oDRpi.js +0 -1
  289. package/dist/dashboard/assets/SetupPage-DQ9oDRpi.js.gz +0 -0
  290. package/dist/dashboard/assets/SortableList-DrKeMcGN.js.gz +0 -0
  291. package/dist/dashboard/assets/StudioPage-qjuYtccc.js.gz +0 -0
  292. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js +0 -56
  293. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js.gz +0 -0
  294. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  295. package/dist/dashboard/assets/app-BUSiYL6F.css +0 -2
  296. package/dist/dashboard/assets/app-BUSiYL6F.css.gz +0 -0
  297. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  298. package/dist/dashboard/assets/badge-Bkz_-RrM.js.gz +0 -0
  299. package/dist/dashboard/assets/banner-C-7y3VKV.js.gz +0 -0
  300. package/dist/dashboard/assets/card-BOPBuBzD.js.gz +0 -0
  301. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  302. package/dist/dashboard/assets/clipboard-button-e-Mlk0FH.js.gz +0 -0
  303. package/dist/dashboard/assets/cog-CdWhsajs.js +0 -1
  304. package/dist/dashboard/assets/cog-CdWhsajs.js.gz +0 -0
  305. package/dist/dashboard/assets/dialog-Iec_ywbD.js.gz +0 -0
  306. package/dist/dashboard/assets/drawer-Bs8MIIHc.js.gz +0 -0
  307. package/dist/dashboard/assets/entry-BRszm4_Z.js.gz +0 -0
  308. package/dist/dashboard/assets/entry-DOddwoc0.js.gz +0 -0
  309. package/dist/dashboard/assets/entry-DcobaKFu.js.gz +0 -0
  310. package/dist/dashboard/assets/github-badge-BuDsrsPn.js.gz +0 -0
  311. package/dist/dashboard/assets/index-BeLRhsmt.js.gz +0 -0
  312. package/dist/dashboard/assets/inline-DToMICwl.js.gz +0 -0
  313. package/dist/dashboard/assets/input-WlyHWeG2.js.gz +0 -0
  314. package/dist/dashboard/assets/layout-DaJ5baJr.js.gz +0 -0
  315. package/dist/dashboard/assets/list-row-B3oSK13z.js.gz +0 -0
  316. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  317. package/dist/dashboard/assets/model-bans-BmYTmbAk.js +0 -1
  318. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  319. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  320. package/dist/dashboard/assets/numbers-Dulqgys5.js.gz +0 -0
  321. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  322. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  323. package/dist/dashboard/assets/select-BfZ3SCTM.js.gz +0 -0
  324. package/dist/dashboard/assets/settings--3hxSyry.js +0 -1
  325. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  326. package/dist/dashboard/assets/stack-B1w5BM0u.js.gz +0 -0
  327. package/dist/dashboard/assets/state-DhZBfWgx.js.gz +0 -0
  328. package/dist/dashboard/assets/switch-yD7D99Lg.js.gz +0 -0
  329. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  330. package/src/console/admin/model-abuse/contracts.ts +0 -38
  331. package/src/console/admin/model-abuse/routes.ts +0 -97
  332. package/src/security/model-abuse.ts +0 -704
  333. package/src/transport/guards/concurrency-guard.ts +0 -125
  334. /package/dist/dashboard/assets/{app-MdVfwraB.js → app-BaWd0puM.js} +0 -0
  335. /package/dist/dashboard/assets/{app-MdVfwraB.js.gz → app-BaWd0puM.js.gz} +0 -0
@@ -1,3 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{t as a}from"./arrow-left-CpBxkoxI.js";import{n as o,t as s}from"./brain-Cwed_72z.js";import{n as c,r as l,t as u}from"./concurrency-BDF0ok7y.js";import{C as d,E as f,O as p,T as m,a as h,c as g,l as _,m as v,s as y,v as b,w as x,x as S}from"./numbers-Dulqgys5.js";import{t as C}from"./circle-alert-CntYHV5v.js";import{t as w}from"./circle-check-BU3v_mFW.js";import{t as T}from"./cog-CdWhsajs.js";import{t as E}from"./eye-off-Bk5g2luF.js";import{t as D}from"./eye-C_hawfH4.js";import{t as O}from"./gauge-BbIMy7MB.js";import{t as ee}from"./image-BPaouViG.js";import{n as k,r as A,t as j}from"./state-DhZBfWgx.js";import{t as te}from"./key-round-UkavsGxp.js";import{t as M}from"./layers-2-glBbjl.js";import{r as ne}from"./use-modal-focus-By7oJoGd.js";import{n as N,t as P}from"./dialog-Iec_ywbD.js";import{t as F}from"./pencil-768ysRAr.js";import{t as I}from"./plus-DIdX_g-x.js";import{t as re}from"./power-off-Yjw9GMJh.js";import{t as ie}from"./refresh-cw-BqJFk4sU.js";import{t as ae}from"./rotate-ccw-CufcqITi.js";import{t as oe}from"./search-JOKus9rb.js";import{t as se}from"./trash-Cppn5c3R.js";import{t as ce}from"./wrench-B6E1oEuY.js";import{C as le,T as ue,v as de}from"./assert-DU6qrMA_.js";import{i as fe,l as pe,o as me,t as L}from"./query-keys-UETqfytp.js";import{$ as he,C as R,D as ge,E as _e,O as ve,S as ye,a as be,b as xe,c as Se,ct as Ce,d as z,et as we,f as Te,g as Ee,h as De,k as Oe,l as ke,lt as Ae,m as je,o as Me,p as Ne,r as Pe,t as B,tt as Fe,u as Ie,w as Le,x as V,y as Re,z as ze}from"./entry-DOddwoc0.js";import{n as H,r as U,t as W}from"./card-BOPBuBzD.js";import{n as Be}from"./download-dRFo5_Wu.js";import{f as G,i as Ve,l as He,n as Ue,r as We,s as Ge}from"./tokens-COzario9.js";import{t as K}from"./badge-Bkz_-RrM.js";import{n as q}from"./input-WlyHWeG2.js";import{t as J}from"./select-BfZ3SCTM.js";import{t as Ke}from"./ProviderIcon-CmfzxpVM.js";import{t as qe}from"./switch-yD7D99Lg.js";import{t as Y}from"./stack-B1w5BM0u.js";import{n as X,t as Je}from"./inline-DToMICwl.js";import{i as Ye}from"./quota-DZGyp0N5.js";import{t as Xe}from"./list-row-B3oSK13z.js";import{c as Ze,l as Qe,m as $e}from"./routing-BPUo-W8d.js";import{t as et}from"./banner-C-7y3VKV.js";import{o as tt,s as nt,t as rt}from"./HealthEventsModal-fKAWd-OQ.js";import{r as it}from"./privacy-mode-GM8bej85.js";import{n as at,t as ot}from"./AccountCooldown-Bjo92Qat.js";import{t as st}from"./use-timeout-BwcBBRrT.js";var ct=e(`cable`,[[`path`,{d:`M17 19a1 1 0 0 1-1-1v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2a1 1 0 0 1-1 1z`,key:`trhst0`}],[`path`,{d:`M17 21v-2`,key:`ds4u3f`}],[`path`,{d:`M19 14V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V10`,key:`1mo9zo`}],[`path`,{d:`M21 21v-2`,key:`eo0ou`}],[`path`,{d:`M3 5V3`,key:`1k5hjh`}],[`path`,{d:`M4 10a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2z`,key:`1dd30t`}],[`path`,{d:`M7 5V3`,key:`1t1388`}]]),lt=e(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),ut=e(`lock-open`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 9.9-1`,key:`1mm8w8`}]]),dt=e(`package-x`,[[`path`,{d:`M12 22V12`,key:`d0xqtd`}],[`path`,{d:`m16.5 14.5 5 5`,key:`ozpm51`}],[`path`,{d:`m16.5 19.5 5-5`,key:`syf6b9`}],[`path`,{d:`M21 10.5V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l.13-.074`,key:`isw6gs`}],[`path`,{d:`M3.29 7 12 12l8.71-5`,key:`19ckod`}],[`path`,{d:`m7.5 4.27 8.997 5.148`,key:`9yrvtv`}]]),ft=e(`repeat`,[[`path`,{d:`m17 2 4 4-4 4`,key:`nntrym`}],[`path`,{d:`M3 11v-1a4 4 0 0 1 4-4h14`,key:`84bu3i`}],[`path`,{d:`m7 22-4-4 4-4`,key:`1wqhfi`}],[`path`,{d:`M21 13v1a4 4 0 0 1-4 4H3`,key:`1rx37r`}]]),pt=e(`save`,[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]]),mt=e(`video`,[[`path`,{d:`m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5`,key:`ftymec`}],[`rect`,{x:`2`,y:`6`,width:`14`,height:`12`,rx:`2`,key:`158x01`}]]),ht=e(`waypoints`,[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]),gt=[`auto`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];function _t(e,t){return t===null?e:`${e}(${t})`}var Z=t(n(),1),Q=r();function vt({to:e,label:t}){let n=he();return(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>{window.history.length>1?n(-1):n(e)},className:`inline-flex items-center gap-3 text-accent text-caption bg-transparent border-0 p-0 cursor-pointer`,children:[(0,Q.jsx)(a,{size:14,"aria-hidden":`true`}),t]})}function yt({title:e,description:t,icon:n,badges:r,actions:i,back:a}){return(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[a?(0,Q.jsx)(vt,{...a}):null,(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-6 flex-wrap`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-5 min-w-0`,children:[n?(0,Q.jsx)(`div`,{className:`card-header-icon`,children:n}):null,(0,Q.jsxs)(`div`,{className:`min-w-0`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,Q.jsx)(`h1`,{className:`text-lead font-bold`,children:e}),r]}),t?(0,Q.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:t}):null]})]}),i?(0,Q.jsx)(`div`,{className:v(`flex items-center gap-4 flex-wrap min-w-0 max-w-full`),children:i}):null]})]})}function bt(e){return e.isBuiltIn&&e.requiresAccount&&e.oauthFlows===void 0&&!e.hasAdapterUserAgent}function xt(e,t=600){let n=(0,Z.useRef)(void 0);return(0,Z.useEffect)(()=>()=>clearTimeout(n.current),[]),r=>{clearTimeout(n.current),n.current=setTimeout(()=>e(r),t)}}var St={fallback:`Failover`,roundRobin:`Round robin`},Ct=new Set([`inferhub`,`cline`]);function wt(e,t){let n=Qe(e),r=$e(),[i,a]=(0,Z.useState)(`fallback`),[o,s]=(0,Z.useState)(1),[c,l]=(0,Z.useState)(null),[u,d]=(0,Z.useState)(null),[f,p]=(0,Z.useState)(null),[m,h]=(0,Z.useState)(`percent`),[g,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(``);(0,Z.useEffect)(()=>{n.data&&(a(n.data.strategy),s(n.data.rotateCount),l(n.data.maxInflight),d(n.data.maxInflightPerProxy??null),p(n.data.usageFloor),h(n.data.usageFloorUnit),_(n.data.skipProxy),y(n.data.userAgent))},[n.data]);let b=i=>{r.mutate({providerId:e,request:{enabled:!0,strategy:i.strategy,rotateCount:i.rotateCount,maxInflight:i.maxInflight,maxInflightPerProxy:i.maxInflightPerProxy,usageFloor:i.usageFloor,usageFloorUnit:i.usageFloorUnit,skipProxy:i.skipProxy,...t?{userAgent:i.userAgent}:{}}},{onError:()=>{n.data&&(a(n.data.strategy),s(n.data.rotateCount),l(n.data.maxInflight),d(n.data.maxInflightPerProxy??null),p(n.data.usageFloor),h(n.data.usageFloorUnit),_(n.data.skipProxy),y(n.data.userAgent))}})},x=xt(e=>b({strategy:i,rotateCount:o,maxInflight:e,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),S=xt(e=>b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:e,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),C=xt(e=>b({strategy:i,rotateCount:e,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})),w=xt(e=>b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:e}));return{strategy:i,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,setUsageFloor:(e,t)=>{p(e),h(t),b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:e,usageFloorUnit:t,skipProxy:g,userAgent:v})},skipProxy:g,userAgent:v,isLoading:n.isPending,isError:n.isError,isSaving:r.isPending,saveFailed:r.isError,refetch:()=>n.refetch(),setMaxInflight:e=>{l(e),x(e)},setMaxInflightPerProxy:e=>{d(e),S(e)},setUserAgent:e=>{y(e),w(e)},setSkipProxy:e=>{_(e),b({strategy:i,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:e,userAgent:v})},roundRobinEnabled:i===`round_robin`,setRoundRobinEnabled:e=>{let t=e?`round_robin`:`fallback`;a(t),b({strategy:t,rotateCount:o,maxInflight:c,maxInflightPerProxy:u,usageFloor:f,usageFloorUnit:m,skipProxy:g,userAgent:v})},rotateCount:o,setRotateCount:e=>{s(e),C(e)}}}var Tt=50,Et=100;function Dt(e,t,n){return[{value:``,label:`None`},{value:`Cartethyia/${e}`,label:`Cartethyia ${e}`},{value:`codex_cli_rs/${t}`,label:`Codex`},{value:`claude-cli/${n} (external, cli)`,label:`Claude Code`}]}function Ot({children:e,action:t}){return(0,Q.jsx)(Xe,{actions:t,children:e})}function kt({providerId:e,clientVersion:t,routeIdentityVersions:n,userAgentEditable:r}){let i=wt(e,r),[a,o]=(0,Z.useState)(!1),s=Ct.has(e),l=Dt(B,n.codex,n.claude),u=l.some(e=>e.value===i.userAgent)?l:[...l,{value:i.userAgent,label:`Custom`}];if(i.isLoading)return(0,Q.jsx)(A,{label:`Loading routing...`});if(i.isError)return(0,Q.jsx)(k,{message:`Failed to load routing`,onRetry:i.refetch});let d=i.roundRobinEnabled?`${St.roundRobin} · ${i.rotateCount} account${i.rotateCount===1?``:`s`} per rotation`:St.fallback,f=i.isSaving?`Saving...`:i.saveFailed?`Save failed — reverted to last saved value`:`Active: ${d}`,p=i.maxInflight===null,m=p?51:Math.min(51,Math.max(1,i.maxInflight)),h=p?`∞`:String(i.maxInflight),_=i.maxInflightPerProxy===null,v=_?51:Math.min(51,Math.max(1,i.maxInflightPerProxy)),b=_?`∞`:String(i.maxInflightPerProxy),x=i.skipProxy,S=e=>{i.setRotateCount(Math.min(1e3,Math.max(1,i.rotateCount+e)))},C=e=>{if(e===i.userAgent)return;i.setUserAgent(e);let t=u.find(t=>t.value===e)?.label??e;y.success(`Client identity updated`,t)},w=t?`${t.client} ${t.version}`:`Provider default`;return(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Routing Strategy`,subtitle:f,icon:(0,Q.jsx)(M,{size:16})}),(0,Q.jsx)(H,{children:(0,Q.jsxs)(`div`,{className:`grid gap-5 w-full min-w-0`,children:[(0,Q.jsx)(Ot,{action:(0,Q.jsxs)(Q.Fragment,{children:[i.roundRobinEnabled?(0,Q.jsxs)(`div`,{role:`group`,"aria-label":`Accounts per rotation`,className:`inline-flex items-center gap-1 rounded-control border border-inner-border bg-surface-1 p-1`,children:[(0,Q.jsx)(`span`,{className:`px-2 text-badge text-text-secondary`,children:`Accounts/rotation`}),(0,Q.jsx)(g,{variant:`ghost`,size:`icon`,className:`size-9 rounded-tiny`,"aria-label":`Decrease accounts per rotation`,disabled:i.rotateCount<=1,icon:(0,Q.jsx)(N,{size:14}),onClick:()=>S(-1)}),(0,Q.jsx)(`output`,{className:`min-w-8 text-center text-body font-semibold tabular-nums`,"aria-live":`polite`,children:i.rotateCount}),(0,Q.jsx)(g,{variant:`ghost`,size:`icon`,className:`size-9 rounded-tiny`,"aria-label":`Increase accounts per rotation`,disabled:i.rotateCount>=1e3,icon:(0,Q.jsx)(I,{size:14}),onClick:()=>S(1)})]}):null,(0,Q.jsx)(qe,{checked:i.roundRobinEnabled,onChange:i.setRoundRobinEnabled,id:`routing-round-robin`})]}),children:(0,Q.jsxs)(`div`,{className:`min-w-0`,children:[(0,Q.jsx)(`label`,{htmlFor:`routing-round-robin`,children:(0,Q.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,Q.jsx)(ft,{size:15,"aria-hidden":`true`,className:`shrink-0 ${i.roundRobinEnabled?`text-accent`:`text-text-tertiary`}`}),`Round robin`]})}),(0,Q.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Off uses priority order with failover. On rotates requests across this provider's accounts.`})]})}),(0,Q.jsx)(Ot,{action:(0,Q.jsx)(qe,{checked:i.skipProxy,onChange:i.setSkipProxy,id:`routing-skip-proxy`}),children:(0,Q.jsxs)(`div`,{className:`min-w-0`,children:[(0,Q.jsx)(`label`,{htmlFor:`routing-skip-proxy`,children:(0,Q.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,Q.jsx)(ct,{size:15,"aria-hidden":`true`,className:`shrink-0 ${i.skipProxy?`text-accent`:`text-text-tertiary`}`}),`Always direct`]})}),(0,Q.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Bypass automatic proxy-pool routing for this provider and always dial direct`})]})}),(0,Q.jsxs)(`div`,{className:`routing-controls-grid grid gap-5 min-w-0 w-full`,children:[(0,Q.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0`,children:[(0,Q.jsxs)(X,{gap:`6px`,className:`text-body font-semibold mb-3`,children:[(0,Q.jsx)(c,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Client identity`]}),r?(0,Q.jsx)(J,{id:`routing-user-agent-preset`,"aria-label":`Client identity`,value:i.userAgent,options:u,onValueChange:C}):(0,Q.jsx)(J,{id:`routing-user-agent-fixed`,"aria-label":`Client identity`,disabled:!0,value:w,options:[{value:w,label:w}]}),(0,Q.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:r?`None sends the request as-is — whatever the runtime or egress sets, with no identity stamped by the gateway. A chosen value overrides it.`:`Set by the provider. It cannot be changed.`})]}),(0,Q.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0`,children:[(0,Q.jsx)(`label`,{htmlFor:`routing-max-inflight`,className:`form-label`,children:(0,Q.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,Q.jsx)(O,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Max inflight / account`]})}),(0,Q.jsxs)(`div`,{className:`text-badge text-text-tertiary mb-3`,children:[`Per-account ceiling, not a provider-wide one: each account enforces its own limit, so a full account spills to the next. One step past `,Tt,` is unlimited.`]}),(0,Q.jsxs)(X,{gap:`10px`,className:`mt-3`,children:[(0,Q.jsx)(`input`,{id:`routing-max-inflight`,type:`range`,className:`routing-slider flex-1 min-w-0`,"data-unlimited":p?`true`:void 0,min:1,max:51,step:1,value:m,"aria-valuetext":p?`Unlimited`:String(i.maxInflight),onChange:e=>{let t=Number(e.target.value);Number.isFinite(t)&&i.setMaxInflight(t>Tt?null:Math.round(t))},style:{"--slider-pct":`${m/51*100}%`}}),(0,Q.jsx)(`input`,{type:`text`,inputMode:`numeric`,"aria-label":`Max inflight per account`,value:h,onChange:e=>{let t=e.target.value.trim();if(t===``||t===`∞`){i.setMaxInflight(null);return}let n=Number(t);Number.isFinite(n)&&n>=1&&i.setMaxInflight(Math.min(Et,Math.round(n)))},className:`form-input w-26 shrink-0 px-2 py-3 text-center text-body ${p?`text-status-success`:``}`})]})]})]}),(0,Q.jsxs)(`div`,{className:`px-6 py-5 rounded-control border border-inner-border bg-surface-2 min-w-0${x?` opacity-60`:``}`,children:[(0,Q.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,Q.jsxs)(`label`,{htmlFor:`routing-max-inflight-per-proxy`,className:`min-w-0`,children:[(0,Q.jsxs)(X,{gap:`6px`,className:`text-body font-semibold`,children:[(0,Q.jsx)(ht,{size:15,"aria-hidden":`true`,className:`text-text-tertiary shrink-0`}),`Max inflight / proxy`]}),(0,Q.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Each proxy pool carries at most this many concurrent requests for this provider. Other providers on the same pool are unaffected.`})]}),(0,Q.jsx)(g,{variant:`ghost`,size:`sm`,className:`shrink-0`,"aria-label":`How per-proxy limits work`,onClick:()=>o(!0),children:`How it works`})]}),(0,Q.jsxs)(X,{gap:`10px`,className:`mt-3`,children:[(0,Q.jsx)(`input`,{id:`routing-max-inflight-per-proxy`,type:`range`,className:`routing-slider flex-1 min-w-0`,"data-unlimited":_?`true`:void 0,min:1,max:51,step:1,disabled:x,value:v,"aria-valuetext":_?`Unlimited`:String(i.maxInflightPerProxy),onChange:e=>{let t=Number(e.target.value);Number.isFinite(t)&&i.setMaxInflightPerProxy(t>Tt?null:Math.round(t))},style:{"--slider-pct":`${v/51*100}%`}}),(0,Q.jsx)(`input`,{type:`text`,inputMode:`numeric`,"aria-label":`Max inflight per proxy`,disabled:x,value:b,onChange:e=>{let t=e.target.value.trim();if(t===``||t===`∞`){i.setMaxInflightPerProxy(null);return}let n=Number(t);Number.isFinite(n)&&n>=1&&i.setMaxInflightPerProxy(Math.min(Et,Math.round(n)))},className:`form-input w-26 shrink-0 px-2 py-3 text-center text-body ${_?`text-status-success`:``}`})]}),(0,Q.jsx)(`div`,{className:`mt-2 text-badge text-text-tertiary`,children:x?`Always direct is on, so this provider never dials a pool. The limit is kept for when a pool is used again.`:`One step past ${Tt} is unlimited.`})]}),(0,Q.jsx)(P,{open:a,onClose:()=>o(!1),title:`How concurrency limits stack`,size:`md`,children:(0,Q.jsxs)(`div`,{className:`grid gap-4 text-body`,children:[(0,Q.jsx)(`p`,{className:`text-text-secondary`,children:`Three limits apply at once. Each one bounds a different thing; none replaces another.`}),(0,Q.jsxs)(`dl`,{className:`grid gap-3`,children:[(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`dt`,{className:`font-semibold`,children:`Max inflight / account`}),(0,Q.jsx)(`dd`,{className:`text-badge text-text-tertiary`,children:`One account of this provider, across every proxy. Set here, above.`})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`dt`,{className:`font-semibold`,children:`Max inflight / proxy`}),(0,Q.jsxs)(`dd`,{className:`text-badge text-text-tertiary`,children:[`One proxy pool's concurrent requests `,(0,Q.jsx)(`em`,{children:`for this provider`}),`. The same number applies to every pool; each pool counts separately. This is the field above.`]})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`dt`,{className:`font-semibold`,children:`Pool capacity`}),(0,Q.jsx)(`dd`,{className:`text-badge text-text-tertiary`,children:`Everything through one pool, all providers combined. Set on the proxy itself, on the Proxies page.`})]})]}),(0,Q.jsxs)(`p`,{className:`text-badge text-text-tertiary`,children:[`A request must clear all three. When a pool is full for this provider, the request moves to another pool that still has room; it only fails with`,` `,(0,Q.jsx)(`code`,{children:`429`}),` when every pool is full.`]}),(0,Q.jsx)(`p`,{className:`text-badge text-text-tertiary`,children:`Unlimited means no counter is kept for this provider, so the limit costs nothing until you set one.`})]})}),s&&(0,Q.jsxs)(X,{gap:`6px`,align:`flex-start`,className:`mt-1 text-badge text-text-tertiary`,children:[(0,Q.jsx)(lt,{size:12,className:`shrink-0 mt-0.5`}),(0,Q.jsx)(`span`,{children:`This provider doesn't reliably work through a plain HTTP/S proxy — use a SOCKS5 or proxy pool instead if you need to route it.`})]})]})})]})}function At(e){if(typeof e!=`object`||!e)throw{status:500,code:`invalid_response`,message:`Invalid InferHub summary`};let t=e;return{models:Array.isArray(t.models)?t.models:[],providers:Array.isArray(t.providers)?t.providers:[],pricingConfig:t.pricingConfig??null,meta:t.meta??{fetchedAt:0,ageSeconds:0,stale:!0},error:t.error??null}}function jt(e=!0){return le({queryKey:L.inferhub.summary,queryFn:e=>me(`/inferhub/summary`,{signal:de(e)}).then(At),enabled:e,...fe,staleTime:6e4})}function Mt(e){return e===null?`—`:`$${e.toFixed(4)}`}function Nt(e){return e===null?`—`:`${e}%`}function Pt(e){return e<60?`${e}s ago`:e<3600?`${Math.floor(e/60)}m ago`:`${Math.floor(e/3600)}h ago`}var Ft={provider:`Provider (A–Z)`,availability:`Highest availability`,sustainable:`Sustainable price`,price:`Lowest price`,discount:`Biggest discount`};function It(e,t){return(n,r)=>{let i=e(n),a=e(r);return i===null&&a===null?0:i===null?1:a===null?-1:t===`asc`?i-a:a-i}}function Lt(e){switch(e){case`provider`:return(e,t)=>e.family.localeCompare(t.family,void 0,{sensitivity:`base`})||e.prefix.localeCompare(t.prefix);case`availability`:return(e,t)=>t.providersLive-e.providersLive||It(e=>e.health.successRatePct,`desc`)(e,t);case`sustainable`:return It(e=>e.capacityPriceIn,`asc`);case`price`:return It(e=>e.minAskIn,`asc`);case`discount`:return It(e=>e.tiersIn[0]?.discountPct??null,`desc`)}}function Rt(e){return e===`operational`?`ok`:e===`degraded`?`warn`:e===`major_outage`?`err`:`default`}function zt(e,t){return e.providers.find(e=>e.prefix===t)}function Bt(e){return e.providersLive>0&&e.routable&&e.minAskIn!==null}function Vt(){let e=jt(),t=e.data,[n,r]=(0,Z.useState)(!1),[i,a]=(0,Z.useState)(!1),[o,s]=(0,Z.useState)(!0),[c,l]=(0,Z.useState)(`provider`),u=t?.models??[],d=u.filter(Bt),f=(0,Z.useMemo)(()=>{let e=[...i?u:d].sort(Lt(c)),t=new Map;for(let n of e){let e=t.get(n.prefix);e===void 0?t.set(n.prefix,[n]):e.push(n)}return[...t.entries()].map(([e,t])=>({prefix:e,family:t[0]?.family??e,models:t}))},[u,d,i,c]),p=(0,Q.jsxs)(g,{variant:`secondary`,size:`sm`,onClick:()=>void e.refetch(),disabled:e.isFetching,title:`Re-read InferHub market data now`,children:[(0,Q.jsx)(ie,{size:14}),e.isFetching?`Refreshing…`:`Refresh`]});if(t===void 0&&!e.isError)return(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`InferHub market`,subtitle:e.isPending?`Reading market data…`:void 0,icon:(0,Q.jsx)(ie,{size:16})}),(0,Q.jsx)(H,{children:e.isError?(0,Q.jsx)(et,{tone:`danger`,surface:`raised`,live:`none`,children:`InferHub market data could not be read.`}):null})]});if(t===void 0)return(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`InferHub market`,icon:(0,Q.jsx)(ie,{size:16}),action:p}),(0,Q.jsx)(H,{children:(0,Q.jsx)(et,{tone:`danger`,surface:`raised`,live:`none`,children:`InferHub market data could not be read.`})})]});let m=f,h=m.reduce((e,t)=>e+t.models.length,0),_=u.length-h;return(0,Q.jsxs)(W,{children:[(0,Q.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,Q.jsxs)(`button`,{type:`button`,"aria-expanded":n,"aria-label":n?`Collapse InferHub market`:`Expand InferHub market`,onClick:()=>r(e=>!e),className:`flex min-w-0 flex-1 items-start gap-3 border-0 bg-transparent p-0 text-left text-inherit`,children:[(0,Q.jsx)(Ae,{size:15,"aria-hidden":`true`,className:v(`mt-1 shrink-0 transition-transform`,!n&&`-rotate-90`)}),(0,Q.jsxs)(Y,{gap:`1px`,children:[(0,Q.jsx)(`h2`,{className:`text-body font-bold`,children:`InferHub market`}),t.meta.fetchedAt>0?(0,Q.jsxs)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Updated `,Pt(t.meta.ageSeconds)]}):null]})]}),(0,Q.jsx)(`div`,{className:`flex items-center gap-2`,children:n?p:null})]}),n?(0,Q.jsxs)(H,{children:[(0,Q.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,Q.jsx)(Ut,{onSaved:()=>void e.refetch()}),(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,Q.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary`,children:[`Sort`,(0,Q.jsx)(J,{value:c,onValueChange:e=>l(e),options:Object.keys(Ft).map(e=>({value:e,label:Ft[e]})),"aria-label":`Sort InferHub models`})]}),(0,Q.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary cursor-pointer`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,checked:o,onChange:e=>s(e.target.checked),className:`cursor-pointer`}),`Show availability`]})]})]}),t.error===`no_config_key`?(0,Q.jsxs)(et,{tone:`warning`,surface:`raised`,live:`none`,children:[`No InferHub `,(0,Q.jsx)(`code`,{children:`config_read`}),` key is configured, so the marketplace catalog cannot be read. Add one above.`]}):null,t.error===`upstream_unavailable`?(0,Q.jsxs)(et,{tone:`warning`,surface:`raised`,live:`none`,children:[`InferHub did not answer. Showing the last snapshot that was read`,t.meta.fetchedAt>0?` (${Pt(t.meta.ageSeconds)})`:``,`.`]}):null,t.meta.stale&&t.error===null?(0,Q.jsxs)(et,{tone:`warning`,surface:`raised`,live:`none`,children:[`This snapshot is `,Pt(t.meta.ageSeconds),` — press Refresh for current prices.`]}):null,(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Q.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[h,` of `,u.length,` models`]}),(0,Q.jsxs)(`label`,{className:`flex items-center gap-2 text-caption text-text-secondary cursor-pointer`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,checked:i,onChange:e=>a(e.target.checked),className:`cursor-pointer`}),`Show all`,_>0?(0,Q.jsxs)(`span`,{className:`text-micro text-text-tertiary`,children:[`(includes `,_,` hidden)`]}):null]})]}),m.length===0?(0,Q.jsx)(`p`,{className:`mt-3 text-caption text-text-secondary`,children:`No models to show.`}):(0,Q.jsx)(`div`,{className:`mt-3 flex flex-col gap-3`,children:m.map(e=>(0,Q.jsx)(Ht,{group:e,showUpstreams:o,summary:t},e.prefix))})]}):null]})}function Ht({group:e,showUpstreams:t,summary:n}){let[r,i]=(0,Z.useState)(!0),a=zt(n,e.prefix),o=a?.familyState??null,s=e.models.find(e=>e.systemPromptNote!==null)?.systemPromptNote??null;return(0,Q.jsxs)(`div`,{className:`rounded-card border border-inner-border bg-surface-2`,children:[(0,Q.jsxs)(`button`,{type:`button`,"aria-expanded":r,"aria-label":`${r?`Collapse`:`Expand`} ${e.family} models`,onClick:()=>i(e=>!e),className:`flex w-full items-center gap-2 border-0 bg-transparent px-3 py-2 text-left text-inherit`,children:[(0,Q.jsx)(Ae,{size:14,"aria-hidden":`true`,className:v(`shrink-0 transition-transform`,!r&&`-rotate-90`)}),(0,Q.jsx)(`span`,{className:`text-caption font-bold`,children:e.family}),(0,Q.jsxs)(`span`,{className:`font-mono text-micro text-text-tertiary`,children:[e.prefix,`/`]}),o===null?null:(0,Q.jsx)(K,{tone:Rt(o),dot:!0,children:o.replace(/_/g,` `)}),t&&a!==void 0?(0,Q.jsxs)(`span`,{className:`text-micro text-text-tertiary tabular-nums`,children:[`24h `,Nt(a.availability24hPct),` · 7d`,` `,Nt(a.availability7dPct)]}):null,(0,Q.jsxs)(`span`,{className:`ml-auto text-micro text-text-tertiary`,children:[e.models.length,` model`,e.models.length===1?``:`s`]})]}),r?(0,Q.jsxs)(`div`,{className:`px-3 pb-3`,children:[s===null?null:(0,Q.jsx)(`p`,{className:`mb-2 text-micro text-text-secondary`,children:s}),(0,Q.jsx)(`div`,{className:`overflow-x-auto`,children:(0,Q.jsxs)(`table`,{className:`w-full text-caption`,children:[(0,Q.jsx)(`thead`,{children:(0,Q.jsxs)(`tr`,{className:`text-left text-text-secondary`,children:[(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:`Model`}),(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:`Input`}),(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:`Output`}),(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:`Discount`}),(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:`Live`}),(0,Q.jsx)(`th`,{className:`py-1 pr-3`,children:t?`24h`:`Success`})]})}),(0,Q.jsx)(`tbody`,{children:e.models.map(e=>(0,Q.jsxs)(`tr`,{className:`border-t border-inner-border`,children:[(0,Q.jsx)(`td`,{className:`py-1 pr-3 font-mono`,children:e.id}),(0,Q.jsxs)(`td`,{className:`py-1 pr-3 tabular-nums`,children:[Mt(e.minAskIn),e.capacityPriceIn!==null&&e.capacityPriceIn!==e.minAskIn?(0,Q.jsxs)(`div`,{className:`text-micro text-text-secondary`,children:[Mt(e.capacityPriceIn),` sustainable`]}):null]}),(0,Q.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:Mt(e.minAskOut)}),(0,Q.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:e.tiersIn[0]?.discountPct===void 0||e.tiersIn[0]?.discountPct===null?`—`:`−${e.tiersIn[0].discountPct}%`}),(0,Q.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:e.providersLive===0?(0,Q.jsx)(K,{children:`none`}):e.providersLive}),(0,Q.jsx)(`td`,{className:`py-1 pr-3 tabular-nums`,children:Nt(t?a?.availability24hPct??null:e.health.successRatePct)})]},e.id))})]})})]}):null]})}function Ut({onSaved:e}){let[t,n]=(0,Z.useState)(``),[r,i]=(0,Z.useState)(null),[a,o]=(0,Z.useState)(!1),[s,c]=(0,Z.useState)(null),l=async()=>{if(t.trim().length!==0){o(!0),c(null);try{await me(`/inferhub/key`,{method:`PUT`,body:JSON.stringify({key:t.trim()})}),n(``),i({configured:!0,last4:null}),e()}catch{c(`Could not save the key.`)}finally{o(!1)}}},u=async()=>{o(!0),c(null);try{await me(`/inferhub/key`,{method:`DELETE`}),i({configured:!1,last4:null}),e()}catch{c(`Could not remove the key.`)}finally{o(!1)}};return(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2`,children:[(0,Q.jsx)(`div`,{className:`min-w-64 flex-1`,children:(0,Q.jsx)(q,{type:`password`,value:t,onChange:e=>n(e.target.value),placeholder:`sk-airo-… (config_read key)`,"aria-label":`InferHub config_read key`,autoComplete:`off`})}),(0,Q.jsx)(g,{size:`sm`,onClick:()=>void l(),disabled:a||t.trim().length===0,children:a?`Saving…`:`Save key`}),r?.configured?(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,onClick:()=>void u(),disabled:a,children:`Remove`}):null]}),(0,Q.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[`Stored encrypted beside the market settings, never in this provider's accounts. Must be a`,` `,(0,Q.jsx)(`code`,{children:`config_read`}),` key — never an inference key.`]}),s===null?null:(0,Q.jsx)(et,{tone:`danger`,surface:`raised`,live:`alert`,children:s})]})}function Wt({providerId:e}){let t=wt(e,!1),n=tt(),r=Ze(e),i=(0,Z.useMemo)(()=>Kt(n.data?.accounts??[],e),[n.data,e]),a=(0,Z.useRef)(null),o=(0,Z.useMemo)(()=>[...r.data?.values()??[]].reduce((e,t)=>e+t,0),[r.data]);(0,Z.useEffect)(()=>{if(a.current===null){a.current=o;return}a.current!==o&&(a.current=o,n.refetch())},[o,n]);let[s,c]=(0,Z.useState)(`40`),[l,u]=(0,Z.useState)(`percent`),d=t.usageFloor!==null;(0,Z.useEffect)(()=>{t.usageFloor!==null&&c(String(t.usageFloor)),u(t.usageFloorUnit)},[t.usageFloor,t.usageFloorUnit]);let f=Number(s),p=Number.isInteger(f)&&f>=0&&f<=1e6,m=i===null||i.remaining<=0?`text-status-danger`:i.percent<=10?`text-status-warning`:`text-status-success`,h=(e,n)=>{(e===null||p)&&t.setUsageFloor(e,n)};return(0,Q.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,Q.jsxs)(`section`,{className:`usage-floor-panel flex flex-col gap-4 px-5 py-4 border border-inner-border rounded-narrow bg-surface-2`,children:[(0,Q.jsxs)(`div`,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-3 text-body font-semibold text-text-primary`,children:[(0,Q.jsx)(O,{size:14}),(0,Q.jsx)(`span`,{children:`Usage floor`}),(0,Q.jsx)(`span`,{className:`badge border border-warning-line bg-surface-2 text-micro tracking-label text-status-warning`,children:`BETA`})]}),(0,Q.jsx)(`p`,{className:`mt-0.5 text-badge leading-normal text-text-tertiary`,children:`Per account. Skip an account once its remaining allowance reaches this, and send the request to the next one.`})]}),(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[i!==null&&(0,Q.jsxs)(`div`,{className:`flex min-h-24 min-w-0 flex-[1_1_20rem] flex-col justify-center gap-2 py-2`,children:[(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 text-micro font-semibold tracking-label uppercase text-text-tertiary`,children:[(0,Q.jsx)(`span`,{children:`Pooled credits`}),(0,Q.jsx)(`span`,{className:`text-text-primary`,children:i.accounts}),(0,Q.jsx)(`span`,{children:i.accounts===1?`active account`:`active accounts`}),i.inactiveAccounts>0?(0,Q.jsxs)(`span`,{className:`badge border border-warning-line text-status-warning normal-case tracking-normal`,title:`Disabled or cooled accounts hold credits this provider cannot route to. Enable or recover them to add their balance.`,children:[i.inactiveAccounts,` inactive`]}):null]}),(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2 gap-y-1 text-caption font-semibold tabular-nums text-text-primary`,title:`Combined allowance across active accounts; the usage floor is evaluated per account`,children:[(0,Q.jsx)(`strong`,{className:`font-bold ${m}`,children:qt(i.remaining)}),(0,Q.jsx)(`span`,{className:`font-medium text-text-secondary`,children:`credits available`}),(0,Q.jsxs)(`span`,{className:`font-medium opacity-75`,children:[`of `,qt(i.total)]}),(0,Q.jsxs)(`span`,{className:`font-bold ${m}`,children:[i.percent,`%`]})]}),(0,Q.jsx)(`p`,{className:`text-micro leading-normal text-text-tertiary`,children:t.usageFloor===null?`Floor off · exhausted quota windows are still skipped`:`Floor ${qt(t.usageFloor)} ${t.usageFloorUnit===`credit`?`credits`:`%`} per account`})]}),i===null&&(0,Q.jsxs)(`p`,{className:`flex min-h-24 min-w-0 flex-[1_1_20rem] flex-col justify-center gap-2 py-2 text-badge leading-normal text-text-tertiary`,children:[(0,Q.jsx)(`span`,{children:`No combined credit balance is available. Separate quota windows are not added together, and exhausted windows are still skipped.`}),(0,Q.jsx)(`span`,{className:`text-micro`,children:t.usageFloor===null?`Floor off · exhausted quota windows are still skipped`:`Floor ${qt(t.usageFloor)} ${t.usageFloorUnit===`credit`?`credits`:`%`} per account`})]}),(0,Q.jsxs)(`div`,{className:`ml-auto flex max-w-full shrink-0 flex-col items-end justify-center gap-2`,children:[(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-x-3 gap-y-2`,children:[(0,Q.jsx)(`span`,{className:`text-micro font-semibold tracking-label uppercase text-text-tertiary`,children:`Floor threshold`}),(0,Q.jsxs)(`label`,{className:`flex h-12 max-w-full items-center overflow-hidden rounded-tiny border border-inner-border bg-surface-1 focus-within:border-text-tertiary`,children:[(0,Q.jsx)(`input`,{type:`number`,min:0,max:1e6,value:d?s:``,placeholder:`40`,disabled:!d,"aria-label":`Usage floor amount`,className:`h-full w-24 border-0 bg-transparent px-3 text-right font-mono text-body font-semibold tabular-nums text-text-primary disabled:text-text-tertiary`,onChange:e=>c(e.target.value),onBlur:()=>{d&&h(f,l)}}),(0,Q.jsxs)(`select`,{value:l,disabled:!d,"aria-label":`Usage floor unit`,className:`h-full border-0 border-l border-inner-border bg-hover px-3 text-body font-semibold text-text-secondary disabled:cursor-default disabled:opacity-60`,onChange:e=>{let t=e.target.value===`credit`?`credit`:`percent`;u(t),d&&h(f,t)},children:[(0,Q.jsx)(`option`,{value:`percent`,children:`%`}),(0,Q.jsx)(`option`,{value:`credit`,children:`credits`})]})]}),(0,Q.jsx)(qe,{checked:d,label:`Enabled`,"aria-label":`Usage floor`,className:`usage-floor-switch`,onChange:e=>h(e?p?f:40:null,l)})]}),t.saveFailed?(0,Q.jsx)(`p`,{role:`alert`,className:`text-right text-micro leading-normal text-status-danger`,children:`Usage floor save failed. The last saved setting has been restored.`}):null]})]})]}),(0,Q.jsx)(Gt,{providerId:e})]})}function Gt({providerId:e}){let{enabled:t,setEnabled:n}=it(e);return(0,Q.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-6 px-6 py-5 border border-inner-border rounded-control bg-surface-2`,children:[(0,Q.jsxs)(`div`,{className:`min-w-0 flex-auto basis-110`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-3 text-body font-semibold text-text-primary`,children:[(0,Q.jsx)(E,{size:14}),(0,Q.jsx)(`span`,{children:`Mysterious accounts`})]}),(0,Q.jsx)(`p`,{className:`mt-0.5 text-badge leading-normal text-text-tertiary`,children:`Hide this provider's emails and usernames. Stored in this browser only.`})]}),(0,Q.jsx)(`div`,{className:`flex items-center gap-4 shrink-0`,children:(0,Q.jsx)(qe,{checked:t,"aria-label":`Mysterious accounts`,onChange:n})})]})}function Kt(e,t){let n=0,r=0,i=0,a=0,o=!1;for(let s of e)if(s.provider===t){if(!s.active){a+=1;continue}if(i+=1,s.quota!==null)for(let e of s.quota.windows){if(e.accounting!==`pooled`)continue;let t=typeof e.limit==`number`&&Number.isFinite(e.limit)?e.limit:null;if(t===null)continue;let i=typeof e.remaining==`number`&&Number.isFinite(e.remaining)?e.remaining:typeof e.used==`number`&&Number.isFinite(e.used)?t-e.used:null;i!==null&&(n+=Math.min(t,Math.max(0,i)),r+=t,o=!0)}}return i>0&&o?{accounts:i,inactiveAccounts:a,remaining:n,total:r,percent:r>0?Math.round(n/r*100):0}:null}function qt(e){return e.toLocaleString(void 0,{maximumFractionDigits:1})}function Jt({provider:e}){let t=e.credentialUrl,n=e.credentialHint,r=e.operatorNotice;if(!t&&!n&&!r)return null;let i=e.oauthFlows?.browser===!0||e.oauthFlows?.device===!0,a=n??(i?`This provider authorizes through its own login flow; there is no key to paste.`:e.requiresAccount?`Create a credential on the provider site, then add it as an account below.`:`This provider needs no credential.`);return(0,Q.jsx)(W,{density:`compact`,children:(0,Q.jsx)(H,{children:(0,Q.jsxs)(X,{gap:`12px`,className:`items-center flex-wrap`,children:[(0,Q.jsxs)(`span`,{className:`min-w-110 flex-1 text-caption text-text-secondary`,children:[a,r?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`br`,{}),r]}):null]}),t?(0,Q.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,title:t,className:_({size:`sm`,className:`shrink-0 no-underline`}),children:[(0,Q.jsx)(`span`,{className:`btn-icon-wrapper`,"aria-hidden":`true`,children:(0,Q.jsx)(Ce,{size:13})}),i?`Sign in`:`Get API Key`]}):null]})})})}function Yt({provider:e}){let t=ve(),[n,r]=(0,Z.useState)(!1),[i,a]=(0,Z.useState)(e.baseUrl??``);(0,Z.useEffect)(()=>{a(e.baseUrl??``)},[e.providerId,e.baseUrl]);let o=(e.baseUrl??``).replace(/\/+$/,``),s=i.trim().replace(/\/+$/,``),c=s!==o,l=s.length>0&&c&&!t.isPending;return(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Custom Provider Endpoint`,subtitle:`Upstream base URL`,icon:(0,Q.jsx)(d,{size:16})}),(0,Q.jsx)(H,{children:(0,Q.jsxs)(Y,{gap:`12px`,children:[n?(0,Q.jsx)(q,{label:`Base URL`,id:`custom-provider-base-url`,type:`url`,value:i,onChange:e=>a(e.target.value),placeholder:`https://api.example.com/v1`,autoFocus:!0}):(0,Q.jsxs)(`div`,{className:`min-w-0`,children:[(0,Q.jsx)(`div`,{className:`text-micro font-semibold uppercase tracking-label text-text-tertiary`,children:`Base URL`}),(0,Q.jsx)(`code`,{className:`mt-1 block min-w-0 break-all font-mono text-caption text-text-primary`,children:e.baseUrl??`Not configured`})]}),(0,Q.jsxs)(X,{gap:`8px`,className:`w-full flex-wrap`,justify:`end`,children:[n?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{size:`sm`,variant:`primary`,icon:(0,Q.jsx)(pt,{size:13}),disabled:!l,loading:t.isPending,onClick:()=>{l&&t.mutate({providerId:e.providerId,request:{baseUrl:s}},{onSuccess:()=>r(!1)})},children:`Save endpoint`}),(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(ne,{size:13}),disabled:t.isPending,onClick:()=>{a(e.baseUrl??``),r(!1)},children:`Cancel`})]}):(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(F,{size:13}),onClick:()=>r(!0),children:`Edit endpoint`}),e.requiresAccount?(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(te,{size:13}),onClick:()=>{let e=document.getElementById(`provider-accounts`);e?.scrollIntoView({behavior:`smooth`,block:`start`}),e?.focus({preventScroll:!0})},children:`Manage API keys`}):null]})]})})]})}var Xt={quota_fetch_failed:`Quota unreachable`,quota_exhausted:`Quota exhausted`,policy_blocked:`Policy blocked`,rate_limit_transient:`Rate limited`,missing_credential:`No credential`},Zt=new Set([`quota_fetch_failed`]);function Qt(e){return e===void 0||e.length===0?!1:!Zt.has(e)}function $t(e){return e===`oauth`?`Re-login required`:`Replace API key`}function en(e,t){return e===`auth_invalidated`?$t(t):Xt[e]??e}var tn=[`access`,`accessToken`,`access_token`,`sessionToken`,`session_token`,`token`,`apiKey`,`api_key`,`key`,`credential`,`pat`,`secret`],nn=[`refresh`,`refreshToken`,`refresh_token`],rn=[`credentialKind`,`providerId`,`accessToken`],an=[`accounts`,`items`,`connections`],on=[`email`,`name`,`accountId`,`account_id`,`id`,`login`,`username`];function $(e){if(typeof e==`object`&&e&&!Array.isArray(e))return Object.fromEntries(Object.entries(e))}function sn(e){let t=e.data;if(typeof t==`string`)try{return $(JSON.parse(t))}catch{return}return $(t)}function cn(e){for(let t of tn){let n=e[t];if(typeof n==`string`&&n.trim().length>0)return{value:n.trim(),extracted:!0,source:t}}let t=sn(e);if(t)for(let e of tn){let n=t[e];if(typeof n==`string`&&n.trim().length>0)return{value:n.trim(),extracted:!0,source:`data.${e}`}}}function ln(e){for(let t of on){let n=e[t];if(typeof n==`string`&&n.trim().length>0)return n.trim()}let t=sn(e);if(t)for(let e of on){let n=t[e];if(typeof n==`string`&&n.trim().length>0)return n.trim()}}function un(e){let t=(e,t)=>t.some(t=>typeof e[t]==`string`||typeof e[t]==`number`),n=e=>t(e,nn);if(n(e))return!0;let r=sn(e);return r?n(r):!1}function dn(e){let t=e.trim().split(`.`);if(t.length===3)try{let e=t[1].replaceAll(`-`,`+`).replaceAll(`_`,`/`),n=e.padEnd(e.length+(4-e.length%4)%4,`=`);return $(JSON.parse(atob(n)))}catch{return}}function fn(e){let t=dn(e)?.exp;if(typeof t!=`number`||!Number.isFinite(t))return;let n=new Date(t*1e3);return Number.isFinite(n.getTime())?n.toISOString():void 0}function pn(e){let t={},n=0;for(let r of e.split(/\r?\n/)){let e=/^\s*([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(r),i=e?.[1],a=e?.[2];i!==void 0&&a!==void 0&&(t[i]=a.trim(),n+=1)}return n>0?t:void 0}function mn(e){if(e.startsWith(`{`)||e.startsWith(`[`))try{return JSON.parse(e)}catch{return}}var hn=[{id:`codebuddy`,counterpart:`WorkBuddy`},{id:`workbuddy`,counterpart:`CodeBuddy`}];function gn(e,t){let n=`${e} ${t}`.toLowerCase().replace(/[^a-z]/g,``);for(let e of hn)if(n.includes(e.id))return{provider:e.id,counterpart:e.counterpart}}function _n(e){let t=e.trim(),n=$(mn(t))??pn(t);return n&&un(n)?`oauth`:dn((n?cn(n)?.value:void 0)??t)===void 0?`api_key`:`jwt`}function vn(e){return e.length!==0&&!!(e.some(e=>Array.isArray(e.cookies)&&(typeof e.domain==`string`||typeof e.originalUrl==`string`))||e.every(e=>typeof e.name==`string`&&typeof e.value==`string`&&(e.domain!==void 0||e.path!==void 0||e.expirationDate!==void 0)))}function yn(e,t){let n,r=!1,i=(e,t)=>{let i=e.toLowerCase();(i===`userid`||i===`uid`||i===`accountid`||i===`cuserid`)&&(n||=t.replace(/^"|"$/g,``).trim()),(i.includes(`token`)||i.includes(`ph`)||i.includes(`auth`)||i.includes(`session`))&&(r=!0)};for(let e of t)if(Array.isArray(e.cookies)){for(let t of e.cookies)if(t&&typeof t==`object`){let e=t;typeof e.name==`string`&&typeof e.value==`string`&&i(e.name,e.value)}}else typeof e.name==`string`&&typeof e.value==`string`&&i(e.name,e.value);return{value:e,kind:r?`oauth`:`api_key`,...n?{identity:n}:{}}}function bn(e){let t=e.credentialKind;if(typeof t==`string`&&typeof e.accessToken==`string`&&rn.every(t=>t in e)){let n=typeof e.label==`string`&&e.label.trim().length>0?e.label.trim():void 0,r=e.accessToken,i=t===`oauth`&&un(e);return{value:i?JSON.stringify(e):r,kind:i?`oauth`:`api_key`,...n?{identity:n}:{}}}let n=cn(e),r=un(e)?`oauth`:_n(n?.value??JSON.stringify(e)),i=r===`oauth`?JSON.stringify(e):n?.value??JSON.stringify(e),a=ln(e);return a?{value:i,kind:r,identity:a}:{value:i,kind:r}}function xn(e){for(let t of an){let n=e[t];if(!Array.isArray(n))continue;let r=n.map(e=>$(e)).filter(e=>e!==void 0);if(r.length>0)return r}}function Sn(e){let t=e.trim();if(!t)return[];let n=mn(t);if(Array.isArray(n)){let e=n.map(e=>$(e)).filter(e=>e!==void 0);if(e.length>0)return vn(e)?[yn(t,e)]:e.map(bn)}else{let e=$(n);if(e){let t=xn(e);return t?t.map(bn):[bn(e)]}}let r=t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0);if(r.length===0)return[];if(r.length===1){let e=pn(r[0]);return e?[bn(e)]:Cn(r[0])}let i=pn(t);return i&&(cn(i)||Object.keys(i).length===r.length)?[bn(i)]:r.flatMap(Cn)}function Cn(e){let t=$(mn(e));if(t){let e=xn(t);return e?e.map(bn):[bn(t)]}return[{value:e,kind:_n(e)}]}function wn(e,t,n){let r=new Set(n),i=1;return e.map(e=>{let n=e.identity;if(!n){for(;r.has(`${t}-${i}`);)i+=1;n=`${t}-${i}`,i+=1}let a=n,o=2;for(;r.has(a);)a=`${n} (${o++})`;return r.add(a),a})}function Tn(e,t=50){if(t<1)throw RangeError(`chunk size must be at least 1`);let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}function En(e){return e===`active`?0:e===`cooldown`?2:3}function Dn(e){if(e===void 0)return;let t=new Date(e).getTime();if(Number.isFinite(t))return t<=Date.now()?`Expired ${new Date(e).toLocaleDateString()}`:Ye(e,!1)}function On({cooldowns:e,reason:t}){if(!e)return null;let n=Ye(e.until),r=`Soonest: ${e.modelId} — ${n}`;return(0,Q.jsxs)(K,{tone:`warn`,dot:!0,title:t?`${t} — ${r}`:r,children:[e.count,` model`,e.count===1?``:`s`,` cooling · `,n]})}function kn(e){if(e.credentialKind===`oauth`)return`OAuth`;if(e.credentialMode===`jwt`)return`JWT`}function An(e){return e.credentialKind===`oauth`?`blue`:`ok`}function jn({account:e}){let t=e.cooldownUntil?new Date(e.cooldownUntil).getTime():NaN,n=Number.isFinite(t)&&t>Date.now(),r=ot(e);if(e.status===`disabled`){let t=kn(e),n=e.lastErrorCategory===`auth_invalidated`;return(0,Q.jsxs)(X,{gap:`4px`,children:[(0,Q.jsxs)(K,{tone:`disabled`,dot:!0,title:e.lastError,children:[`Disabled`,t?` - ${t}`:``]}),n?(0,Q.jsx)(K,{tone:`warn`,title:e.lastError,children:$t(e.credentialKind)}):Qt(e.lastErrorCategory)&&!(e.lastErrorCategory===`quota_exhausted`&&r)?(0,Q.jsx)(K,{tone:`warn`,title:e.lastError??e.lastErrorCategory,children:en(e.lastErrorCategory,e.credentialKind)}):null,(0,Q.jsx)(On,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]})}return e.status===`active`?(0,Q.jsxs)(X,{gap:`4px`,children:[(0,Q.jsxs)(K,{tone:An(e),dot:!0,children:[`Active`,kn(e)?` - ${kn(e)}`:``]}),Qt(e.lastErrorCategory)&&!(e.lastErrorCategory===`quota_exhausted`&&r)?(0,Q.jsx)(K,{tone:`warn`,title:e.lastError??e.lastErrorCategory,children:en(e.lastErrorCategory,e.credentialKind)}):null,(0,Q.jsx)(On,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]}):e.status===`cooldown`||n?(0,Q.jsxs)(X,{gap:`4px`,children:[(0,Q.jsxs)(K,{tone:`warn`,dot:!0,children:[`Cooldown`,kn(e)?` - ${kn(e)}`:``,` `,e.cooldownUntil?`(${Ye(e.cooldownUntil)})`:``]}),Qt(e.lastErrorCategory)&&!(e.lastErrorCategory===`quota_exhausted`&&r)?(0,Q.jsx)(K,{tone:`warn`,title:e.lastError??e.lastErrorCategory,children:en(e.lastErrorCategory,e.credentialKind)}):null,(0,Q.jsx)(On,{cooldowns:r,reason:e.lastErrorCategory===`quota_exhausted`?e.lastError:void 0})]}):(0,Q.jsx)(K,{tone:`disabled`,children:`Disabled`})}function Mn({windows:e}){if(e===void 0||e.length===0)return null;let t=0,n=0,r=!1,i=null;for(let a of e){if(a.accounting!==`pooled`){typeof a.remainingPercent==`number`&&Number.isFinite(a.remainingPercent)&&(i=i===null?a.remainingPercent:Math.min(i,a.remainingPercent));continue}let e=typeof a.limit==`number`&&Number.isFinite(a.limit)?a.limit:null,o=typeof a.remaining==`number`&&Number.isFinite(a.remaining)?a.remaining:e!==null&&typeof a.used==`number`&&Number.isFinite(a.used)?e-a.used:null;o!==null&&e!==null&&(t+=Math.max(0,o),n+=e,r=!0)}let a=null;return r?a=`${Nn(t)} of ${Nn(n)}`:i!==null&&(a=`${Math.round(i)}% left`),a===null?null:(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,"data-tone":r&&t<=0||(i??100)<=10?`warn`:void 0,title:r?`${Nn(t)} credits available of ${Nn(n)}`:`Lowest remaining percent across this account's quota windows`,children:[(0,Q.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Quota`}),a]})}function Nn(e){return e.toLocaleString(void 0,{maximumFractionDigits:1})}function Pn({providerId:e,account:t,onClose:n}){let r=Oe(),[i,a]=(0,Z.useState)(``),o=t.label||t.id.slice(0,8),s=r.isPending,c=i.trim().length>0&&!s,l=async()=>{try{a(await navigator.clipboard.readText())}catch{y.error(`Clipboard access denied`)}};return(0,Q.jsx)(P,{open:!0,onClose:n,title:`Replace API key — ${o}`,width:560,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:s,children:`Cancel`}),(0,Q.jsx)(g,{size:`sm`,variant:`primary`,disabled:!c,onClick:()=>{let a=i.trim();a&&r.mutate({providerId:e,accountId:t.id,request:{secret:a}},{onSuccess:()=>{y.success(`API key replaced`,o),n()},onError:e=>{let t=e instanceof Error?e.message:`Unable to update account`;y.error(`Failed to replace key`,t)}})},children:s?`Saving…`:`Replace key`})]}),children:(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,Q.jsx)(`p`,{className:`m-0 text-caption text-text-secondary`,children:`Paste the new key for this account. The old key stops working immediately; the account keeps its label, history, and routing.`}),(0,Q.jsxs)(Y,{gap:`6px`,className:`min-w-0`,children:[(0,Q.jsx)(`label`,{className:`text-caption font-semibold text-text-secondary`,children:`New API key`}),(0,Q.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),placeholder:`Paste the replacement key…`,rows:4,spellCheck:!1,autoFocus:!0,className:`font-mono tabular-nums w-full min-w-0 min-h-65 rounded-control border border-inner-border bg-input-bg px-6 py-5 text-caption text-text-primary resize-y box-border`}),(0,Q.jsx)(X,{gap:`8px`,className:`justify-end`,children:(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void l(),children:`Paste`})})]})]})})}function Fn({providerId:e,account:t,inflight:n,quota:r,selected:a,onToggleSelect:o,onDelete:s}){let c=Oe(),l=Re(),u=nt(t.id),d=t.status===`disabled`,f=t.cooldownUntil?new Date(t.cooldownUntil).getTime():NaN,p=Number.isFinite(f)&&f>Date.now(),m=t.status===`cooldown`||p,[h,_]=(0,Z.useState)(!1),[v,b]=(0,Z.useState)(!1),[,C]=(0,Z.useState)(0),[w,T]=(0,Z.useState)(!1),[E,D]=(0,Z.useState)(``),O=it(e),ee=(t.label?.match(/[^\s@]+@[^\s@]+/)?.[0]??t.label)||t.id.slice(0,8),k=O.enabled?`Mysterious accounts`:ee,A=Dn(t.tokenExpiresAt),j=at(t),M=Math.max(p&&t.cooldownUntil?f:0,j??0);(0,Z.useEffect)(()=>{if(M<=Date.now())return;let e=setInterval(()=>C(e=>e+1),1e3);return()=>clearInterval(e)},[M]);let ne=()=>{let n=E.trim();T(!1),n&&n!==(t.label??``)&&c.mutate({providerId:e,accountId:t.id,request:{label:n}},{onSuccess:()=>y.success(`Account renamed`,n),onError:e=>y.error(`Rename failed`,e.message??`Unable to rename account`)})};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`account-row account-row-grid grid items-center gap-5 px-5 py-4 border rounded-control bg-surface-2 ${a?`border-accent`:`border-inner-border`} hover:bg-hover`,role:`listitem`,"data-selected":a?`true`:void 0,style:{opacity:d?.62:1},children:[(0,Q.jsx)(`div`,{className:`flex items-center`,children:(0,Q.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(t.id,e.target.checked),"aria-label":`Select ${k}`,className:`cursor-pointer`})}),(0,Q.jsxs)(`div`,{className:`min-w-0 flex flex-col gap-1.5`,children:[(0,Q.jsx)(`div`,{className:`flex items-center gap-3 min-w-0`,children:w?(0,Q.jsx)(q,{value:E,onChange:e=>D(e.target.value),onKeyDown:e=>{e.key===`Enter`&&ne(),e.key===`Escape`&&T(!1)},onBlur:ne,autoFocus:!0,"aria-label":`Account label`,className:`text-body max-w-120`}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`span`,{className:`text-body font-semibold text-text-primary min-w-0 overflow-hidden text-ellipsis whitespace-nowrap`,title:t.label||t.id,children:k}),(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 grid place-items-center w-10 h-10 p-0 border-0 bg-transparent text-text-tertiary cursor-pointer rounded-tiny hover:bg-inner-border hover:text-text-primary`,title:`Rename account`,"aria-label":`Rename ${k}`,onClick:()=>{D(t.label??``),T(!0)},children:(0,Q.jsx)(F,{size:11})})]})}),(0,Q.jsxs)(`div`,{className:`flex items-center flex-nowrap gap-2 min-w-0 overflow-hidden`,children:[(0,Q.jsx)(jn,{account:t}),A?(0,Q.jsx)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:A,children:A}):null]}),(0,Q.jsxs)(`div`,{className:`flex items-center flex-wrap gap-2 min-w-0`,children:[(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Today: ${t.usageToday.totalTokens.toLocaleString()} tokens, ${t.usageToday.requests.toLocaleString()} requests`,children:[(0,Q.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Today`}),t.usageToday.totalTokens.toLocaleString(),` tok · `,t.usageToday.requests.toLocaleString(),` req`]}),(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Lifetime totals are backfilled from telemetry still retained when tracking starts; new totals survive telemetry cleanup.`,children:[(0,Q.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`All time`}),t.usageAllTime.totalTokens.toLocaleString(),` tok · `,t.usageAllTime.requests.toLocaleString(),` req`]}),(0,Q.jsx)(Mn,{windows:r}),(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 max-w-full px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap`,title:`Concurrency comes from this provider’s Routing Strategy; accounts carry no manual ceilings.`,children:[(0,Q.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`In flight`}),n?.toLocaleString()??`—`]})]})]}),(0,Q.jsxs)(`div`,{className:`account-row-actions flex items-center justify-end gap-3 flex-wrap`,children:[(0,Q.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,Q.jsx)(i,{size:12}),label:`Health`,"aria-label":`Health for ${k}`,onClick:()=>_(!0),title:`View Health & Error History`}),(0,Q.jsx)(g,{size:`icon`,variant:`secondary`,icon:u.isPending?(0,Q.jsx)(S,{size:12,className:`animate-spin`}):(0,Q.jsx)(x,{size:12}),label:u.isPending?`Testing…`:`Test`,"aria-label":`Test ${k}`,disabled:u.isPending,onClick:()=>{u.mutate(void 0,{onSuccess:e=>{e?.ok?y.success(`Account test passed`,k):y.error(`Account test failed`,e?.message??`Provider reported an error`)},onError:e=>y.error(`Account test failed`,e.message??`Unable to test account`)})},title:`Refresh quota and health for this account`}),(0,Q.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,Q.jsx)(te,{size:12}),label:`Edit key`,"aria-label":`Replace API key for ${k}`,onClick:()=>b(!0),title:`Replace API key`}),(0,Q.jsx)(g,{size:`icon`,variant:`secondary`,icon:d?(0,Q.jsx)(ut,{size:12}):(0,Q.jsx)(re,{size:12}),label:d?`Enable`:`Disable`,"aria-label":d?`Enable ${k}`:`Disable ${k}`,disabled:c.isPending,onClick:()=>{let n=d;c.mutate({providerId:e,accountId:t.id,request:{status:n?`active`:`disabled`}},{onSuccess:()=>y.success(n?`Account enabled`:`Account disabled`,k),onError:e=>y.error(`Update failed`,e.message??`Unable to update account`)})},title:d?`Enable account`:`Disable account`}),m?(0,Q.jsx)(g,{size:`icon`,variant:`secondary`,icon:(0,Q.jsx)(ae,{size:12,className:l.isPending?`animate-spin`:``}),label:l.isPending?`Recovering…`:`Recover`,"aria-label":`Recover ${k}`,disabled:l.isPending,onClick:()=>l.mutate({providerId:e,accountId:t.id}),title:`Clear cooldown / restore active status`}):null,(0,Q.jsx)(g,{size:`icon`,variant:`danger`,icon:(0,Q.jsx)(se,{size:12}),label:`Delete`,"aria-label":`Delete ${k}`,onClick:()=>s(t),title:`Delete account`})]})]}),h&&(0,Q.jsx)(rt,{summary:{providerId:e,accountId:t.id,title:t.label||t.id.slice(0,8),status:t.status,errorCategory:t.lastErrorCategory??void 0,errorMessage:t.lastError??void 0,emptyMessage:`Status transitions, rate limits, and auto-recoveries will appear here.`,staticToken:t.staticToken===!0,credentialKind:t.credentialKind,credentialMode:t.credentialMode,jwtIssuer:t.jwtIssuer},onClose:()=>_(!1)}),v&&(0,Q.jsx)(Pn,{providerId:e,account:t,onClose:()=>b(!1)})]})}var In=[{value:`added-asc`,label:`Added · oldest`},{value:`added-desc`,label:`Added · newest`},{value:`label-asc`,label:`Name · A–Z`},{value:`label-desc`,label:`Name · Z–A`},{value:`status-asc`,label:`Status · active first`},{value:`status-desc`,label:`Status · disabled first`},{value:`lastCheck-desc`,label:`Last check · newest`},{value:`lastCheck-asc`,label:`Last check · oldest`}];function Ln(e,t,n){let r=(e,t)=>(e.label||e.id).localeCompare(t.label||t.id)||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id);if(n===`added`)return e.sortIndex-t.sortIndex||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id);if(n===`label`)return r(e,t);if(n===`status`){let n=En(e.status)-En(t.status);return n===0?r(e,t):n}let i=new Date(e.lastSuccessAt??e.createdAt).getTime();return new Date(t.lastSuccessAt??t.createdAt).getTime()-i||r(e,t)}function Rn({providerId:e,accounts:t,onDelete:n,showGrokProbe:r=!1,grokProbePending:i=!1,onGrokProbe:a}){let o=ue(),s=Oe(),c=Re(),l=ke(),d=Ze(e).data??new Map,f=tt(),p=(0,Z.useMemo)(()=>{let t=new Map;for(let n of f.data?.accounts??[])n.provider===e&&n.quota&&t.set(n.id,n.quota.windows);return t},[f.data,e]),[h,_]=(0,Z.useState)(``),[v,b]=(0,Z.useState)(new Set),[S,C]=(0,Z.useState)(`added-asc`),[w,T]=(0,Z.useState)(!1),[E,D]=(0,Z.useState)(null),[O,ee]=(0,Z.useState)(!1),k=h.trim().toLowerCase(),A=(0,Z.useMemo)(()=>k?t.filter(e=>{let t=`${e.label??``} ${e.id} ${e.credentialKind} ${e.status}`.toLowerCase();return k.split(/\s+/).every(e=>t.includes(e))}):t,[t,k]),te=(0,Z.useMemo)(()=>{let e=S.slice(0,S.lastIndexOf(`-`)),t=S.endsWith(`-desc`)?-1:1,n=[...A];return n.sort((n,r)=>t*Ln(n,r,e)),n},[A,S]),M=(0,Z.useMemo)(()=>t.filter(e=>v.has(e.id)),[t,v]),N=A.length>0&&A.every(e=>v.has(e.id)),P=M.some(e=>e.status===`disabled`),F=M.some(e=>e.status!==`disabled`),I=M.length===0,ie=(e,t)=>{b(n=>{let r=new Set(n);return t?r.add(e):r.delete(e),r})},ce=()=>{b(e=>{let t=new Set(e);if(N)for(let e of A)t.delete(e.id);else for(let e of A)t.add(e.id);return t})},le=async(e,t)=>{if(M.length===0)return;T(!0);let n=await Promise.allSettled(M.map(e=>t(e))),r=n.filter(e=>e.status===`rejected`).length,i=n.length-r;T(!1),r===0?y.success(`${e} complete`,`${i} account${i===1?``:`s`}`):y.error(`${e} partially failed`,`${i} succeeded, ${r} failed`)},de=()=>le(`Recover`,t=>c.mutateAsync({providerId:e,accountId:t.id})),fe=async()=>{t.length!==0&&(T(!0),D({done:0,total:t.length}),await u(t,3,async(e,n)=>{let r=await me(`/accounts/${encodeURIComponent(e.id)}/quota/refresh`,{method:`POST`});return D({done:n+1,total:t.length}),r}),await Promise.all([o.invalidateQueries({queryKey:L.quota.all}),o.invalidateQueries({queryKey:L.providers.all})]),T(!1),D(null),y.success(`Test complete`,`${t.length} account${t.length===1?``:`s`} tested`))},pe=t=>le(t?`Enable`:`Disable`,n=>s.mutateAsync({providerId:e,accountId:n.id,request:{status:t?`active`:`disabled`}})),he=async()=>{if(M.length!==0){T(!0);try{let t=await l.mutateAsync({providerId:e,accountIds:M.map(e=>e.id)}),n=new Date().toISOString().replace(/[:.]/g,`-`);Be(`${e}-accounts-${n}.json`,JSON.stringify(t,null,2),`application/json`),y.success(`Accounts exported`,`${t.accounts.length} account${t.accounts.length===1?``:`s`} — contains plaintext credentials`)}catch(e){y.error(`Export failed`,e.message??`Unable to export accounts`)}finally{T(!1)}}};return(0,Q.jsxs)(Y,{gap:`8px`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2 p-3 border border-inner-border rounded-control bg-surface-2`,children:[(0,Q.jsxs)(`label`,{className:`relative w-full`,children:[(0,Q.jsx)(oe,{size:13,"aria-hidden":`true`,className:`pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary`}),(0,Q.jsx)(q,{id:`accounts-search`,value:h,onChange:e=>_(e.target.value),placeholder:`Search accounts...`,"aria-label":`Search accounts`,className:`pl-9`})]}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Q.jsx)(g,{size:`sm`,variant:`primary`,icon:(0,Q.jsx)(x,{size:12}),disabled:w||t.length===0,onClick:fe,"aria-label":E===null?`Test all accounts`:`Testing accounts, ${E.done} of ${E.total} tested`,title:`Test every account, regardless of selection or filters`,children:E===null?`Test all`:`Tested ${E.done}/${E.total}`}),(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(ae,{size:12}),disabled:w||I,title:I?`Select at least one account to recover it`:`Clear cooldowns and retry-wait states on the selected accounts`,onClick:()=>void de(),children:`Recover`}),(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(ut,{size:12}),disabled:w||!P,title:I?`Select at least one disabled account to enable it`:P?`Enable the selected accounts`:`No selected account is currently disabled`,onClick:()=>void pe(!0),children:`Enable`}),(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(re,{size:12}),disabled:w||!F,title:I?`Select at least one enabled account to disable it`:F?`Disable the selected accounts`:`No selected account is currently enabled`,onClick:()=>void pe(!1),children:`Disable`}),(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(m,{size:12}),disabled:w||I,title:I?`Select at least one account to export`:`Download the selected accounts as JSON`,onClick:()=>void he(),children:`Export`}),(0,Q.jsx)(g,{size:`sm`,variant:`danger`,icon:(0,Q.jsx)(se,{size:12}),disabled:w||I,title:I?`Select at least one account to delete`:`Delete ${M.length} selected account${M.length===1?``:`s`}`,onClick:()=>ee(!0),children:`Delete`}),r?(0,Q.jsx)(g,{size:`sm`,variant:`secondary`,icon:(0,Q.jsx)(x,{size:12,className:i?`animate-spin`:``}),disabled:i||t.length===0,onClick:a,title:`Probe every Grok account with the live 407 streaming request`,children:i?`Testing…`:`Test 407`}):null,(0,Q.jsx)(`label`,{className:`inline-flex h-15 shrink-0 items-center gap-2 text-caption font-semibold text-text-secondary [&_.radix-select-trigger]:font-semibold [&_.radix-select-trigger]:bg-hover [&_.radix-select-trigger]:text-text-primary`,children:(0,Q.jsx)(J,{size:`sm`,value:S,onValueChange:e=>C(e),options:In,"aria-label":`Sort accounts by`})}),(0,Q.jsxs)(`label`,{className:`inline-flex h-15 shrink-0 items-center gap-2 text-caption font-semibold text-text-secondary`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,checked:N,onChange:ce,"aria-label":`Select accounts`}),(0,Q.jsx)(`span`,{children:`Select`})]}),I?null:(0,Q.jsxs)(`button`,{type:`button`,onClick:()=>b(new Set),className:`inline-flex h-15 shrink-0 items-center gap-1 rounded-control border border-inner-border px-3 text-badge font-semibold text-text-secondary hover:bg-hover`,title:`Clear selection`,children:[M.length,` selected`,(0,Q.jsx)(ne,{size:11,"aria-hidden":`true`})]})]})]}),(0,Q.jsx)(`div`,{className:`account-list flex flex-col gap-3 max-h-230 overflow-y-auto pr-1 [container-type:inline-size] [container-name:account-list]`,role:`list`,"aria-label":`Provider accounts`,children:te.length===0?(0,Q.jsx)(j,{compact:!0,icon:(0,Q.jsx)(oe,{size:20}),title:`No matching accounts`,message:k?`Nothing matches “${k}”. Clear the filter to see all ${t.length} account${t.length===1?``:`s`}.`:`This provider has no accounts yet.`}):te.map(t=>(0,Q.jsx)(Fn,{providerId:e,account:t,inflight:d.get(t.id)??t.inflight,quota:p.get(t.id),selected:v.has(t.id),onToggleSelect:ie,onDelete:n},t.id))}),(0,Q.jsx)(`div`,{className:`flex items-center justify-between text-badge text-text-tertiary`,children:(0,Q.jsxs)(`span`,{children:[`Showing `,A.length,` account`,A.length===1?``:`s`,k?` (filtered from ${t.length})`:``]})}),(0,Q.jsx)(ze,{open:O,onClose:()=>{w||ee(!1)},onConfirm:async()=>{await le(`Delete`,async e=>{let t=e.tenantId===null?`/global/accounts/${encodeURIComponent(e.id)}`:`/accounts/${encodeURIComponent(e.id)}`;await me(t,{method:`DELETE`}),o.removeQueries({queryKey:L.quota.account(e.id),exact:!0})}),b(new Set),ee(!1),await Promise.all([o.invalidateQueries({queryKey:L.providers.accounts(e)}),o.invalidateQueries({queryKey:L.providers.all}),o.invalidateQueries({queryKey:L.quota.all})])},title:`Delete ${M.length} account${M.length===1?``:`s`}?`,message:`This permanently removes the selected accounts and their credentials. This cannot be undone.`,confirmLabel:`Delete`,danger:!0})]})}var zn=2097152,Bn=zn/1048576;function Vn({providerId:e,accounts:t,onClose:n}){let r=be(),i=Me(),[a,o]=(0,Z.useState)(``),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(!1),[d,f]=(0,Z.useState)(`auto`),[p,m]=(0,Z.useState)(void 0),h=Sn(s),v=h.length>1,b=h.length===1?h[0]:void 0,x=d===`auto`?b?.kind:d,S=b&&x===`jwt`?fn(b.value):void 0,C=h.length>0?gn(e,s):void 0,w=C!==void 0&&p!==s,T=t.map(e=>e.label),E=v?wn(h,e,T):[],D=e=>{let t=d===`auto`?e.kind===`jwt`?`jwt`:`auto`:d;return{credentialKind:t===`auto`&&e.kind===`oauth`?`oauth`:`api_key`,credentialMode:t,secret:e.value}},O=r.isPending||l,ee=async()=>{try{let e=await navigator.clipboard.readText();c(e);let t=Sn(e);if(t.length>1)y.success(`Pasted from clipboard`,`Detected ${t.length} credentials`);else{let e=t[0]?.kind??`api_key`,n=e===`oauth`?`OAuth export`:e===`jwt`?`Static JWT`:`API key`;y.success(`Pasted from clipboard`,`Detected: ${n}`)}}catch{y.error(`Clipboard access denied`)}},k=e=>{if(e.size>zn){y.error(`File too large`,`Credential files must be ${Bn} MB or smaller.`);return}let t=new FileReader;t.onload=()=>{let n=typeof t.result==`string`?t.result:``;c(n);let r=Sn(n);if(r.length===0){y.error(`Nothing to import`,`That file held no credential the gateway recognises.`);return}y.success(`Imported ${e.name}`,r.length>1?`Detected ${r.length} credentials`:r[0]?.kind===`oauth`?`Detected: OAuth export`:`Detected: API key`)},t.onerror=()=>y.error(`Could not read that file`),t.readAsText(e)},A=async()=>{if(h.length!==0&&!w){if(h.length===1){let t=h[0];r.mutate({providerId:e,request:{label:(a.trim()||t.identity)??void 0,...D(t)}},{onSuccess:()=>{y.success(`Account connected`,`New ${t.kind===`oauth`?`OAuth`:t.kind===`jwt`?`Static JWT`:`API key`} account registered successfully`),n()},onError:e=>y.error(`Failed to add account`,e.message??`Invalid credentials`)});return}u(!0);try{let t=Tn(h.map((e,t)=>({label:E[t],...D(e)}))),r=0,a=[],o=!1;for(let[n,s]of t.entries())try{let t=await i.mutateAsync({providerId:e,accounts:s});r+=t.created;let o=n*50;for(let e of t.results)e.ok||a.push(`${E[o+e.index]??o+e.index}: ${e.error??`rejected`}`)}catch(e){o=!0,a.push(`chunk ${n+1}/${t.length}: ${pe(e,`request failed`)}`);break}let s=a.length;r>0&&y.success(`${r} account${r===1?``:`s`} added`,o?`stopped partway; ${s} failed`:s>0?`${s} skipped`:void 0),s>0&&y.error(`${s} account${s===1?``:`s`} skipped`,a.slice(0,5).join(`
2
- `)+(s>5?`\n…and ${s-5} more`:``)),r>0&&n()}finally{u(!1)}}};return(0,Q.jsx)(P,{open:!0,onClose:n,title:`Add Account (API key / JSON)`,width:560,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:O,children:`Cancel`}),(0,Q.jsx)(g,{size:`sm`,variant:`primary`,disabled:O||h.length===0,onClick:()=>void A(),children:O?`Connecting...`:w?`Confirm below`:v?`Add ${h.length} Accounts`:`Add Account`})]}),children:(0,Q.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[!v&&(0,Q.jsx)(q,{label:`Account label (optional)`,value:a,onChange:e=>o(e.target.value),placeholder:b?.identity??`${e} account`}),(0,Q.jsx)(J,{label:`Credential type`,id:`credential-mode`,value:d,onValueChange:e=>f(e===`jwt`||e===`api_key`?e:`auto`),options:[{value:`auto`,label:`Auto — detect JWT, OAuth, or API key`},{value:`jwt`,label:`JWT — static, no refresh`},{value:`api_key`,label:`API key — do not decode as JWT`}]}),(0,Q.jsxs)(Y,{gap:`6px`,className:`min-w-0`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,Q.jsx)(`label`,{className:`text-caption font-semibold text-text-secondary`,children:`API key, OAuth token, or exported JSON — one or many`}),v?(0,Q.jsxs)(K,{tone:`accent`,children:[`Detected: `,h.length,` accounts`]}):b?(0,Q.jsxs)(K,{tone:x===`oauth`||x===`jwt`?`accent`:`default`,children:[`Detected:`,` `,x===`oauth`?`OAuth`:x===`jwt`?`Static JWT`:`API key`,b.identity?` · ${b.identity}`:``]}):null,b&&x===`jwt`?(0,Q.jsxs)(`p`,{className:`text-micro text-text-tertiary`,children:[`Static JWT · no refresh token`,S?` · expires ${new Date(S).toLocaleString()}`:` · no expiry claim`]}):null]}),(0,Q.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),placeholder:`Paste one credential, or many — one per line, a JSON array, or newline-delimited OAuth exports. Kind and account naming are detected automatically…`,rows:6,spellCheck:!1,className:`font-mono tabular-nums w-full min-w-0 min-h-65 rounded-control border border-inner-border bg-input-bg px-6 py-5 text-caption text-text-primary resize-y box-border`}),(0,Q.jsxs)(X,{gap:`8px`,className:`justify-end`,children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void ee(),children:`Paste`}),(0,Q.jsxs)(`label`,{className:_({size:`sm`,className:`cursor-pointer`}),children:[(0,Q.jsx)(`input`,{type:`file`,accept:`.json,.txt,.jsonl,.ndjson,application/json,text/plain`,"aria-label":`Import credentials from a file`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&k(t)}}),`Import file`]})]})]}),v&&(0,Q.jsx)(`div`,{className:`flex flex-col gap-2 max-h-75 overflow-y-auto rounded-control border border-inner-border bg-surface-2 px-4 py-5`,children:h.map((e,t)=>(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-4 text-badge`,children:[(0,Q.jsx)(`span`,{className:`truncate min-w-0`,children:E[t]}),(0,Q.jsx)(K,{tone:e.kind===`oauth`?`accent`:`default`,children:e.kind===`oauth`?`OAuth`:`API key`})]},t))}),C&&(0,Q.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-control border border-warning-line bg-surface-2 px-4 py-5`,role:`alert`,children:[(0,Q.jsx)(`div`,{className:`flex items-start gap-3`,children:(0,Q.jsx)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:`Cross-channel credential`})}),(0,Q.jsxs)(`p`,{className:`text-caption text-text-primary`,children:[`This looks like a `,C.provider,` credential.`,` `,C.provider,` and `,C.counterpart,` tokens are interchangeable — one works in the other — but using a token on a channel it was not issued for can raise the risk of the account being banned, because it appears active somewhere it never authenticated. The same applies in reverse.`]}),w?(0,Q.jsxs)(X,{gap:`8px`,className:`justify-end`,children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>{c(``),n()},children:`Cancel`}),(0,Q.jsx)(g,{size:`sm`,variant:`primary`,onClick:()=>m(s),children:`Add anyway`})]}):(0,Q.jsx)(`p`,{className:`text-micro text-text-tertiary`,children:`Acknowledged — you can add this account now.`})]})]})})}function Hn(e){let t=e.trim(),n=e=>{try{return new URL(e).searchParams}catch{return}},r=n(t)??new URLSearchParams(t.startsWith(`?`)?t.slice(1):t),i=r.get(`code`);if(i)return{code:i};let a=r.get(`error_description`)??r.get(`error`);return a?{error:`The provider refused the login: ${a}`}:r.has(`authCodeInfo`)||r.has(`refreshToken`)||r.has(`refresh_token`)?{code:r.toString()}:n(t)!==void 0||t.startsWith(`?`)?{error:`That redirect URL carries no authorization code — copy the full URL from the address bar.`}:{code:t}}function Un({providerId:e,authorizeUrl:t,state:n,popup:r,onClose:i}){let[a,o]=(0,Z.useState)(!1),[s,c]=(0,Z.useState)(``),l=Pe(),u=st(),d=ue(),m=je(e),h=(0,Z.useRef)(null),_=(0,Z.useRef)(!1);(0,Z.useEffect)(()=>{let t=setInterval(()=>{d.invalidateQueries({queryKey:L.providers.accounts(e)})},1500);return()=>clearInterval(t)},[d,e]),(0,Z.useEffect)(()=>{let e=m.data?.map(e=>e.id)??null;if(e!==null){if(h.current===null){h.current=new Set(e);return}_.current||e.find(e=>!h.current.has(e))!==void 0&&(_.current=!0,r.close(),y.success(`Account connected`,`OAuth login completed successfully`),i(!0))}},[m.data,r,i]);let v=()=>{r.close(),i(!1)},[b,x]=(0,Z.useState)(!1),C=()=>{x(!0),d.invalidateQueries({queryKey:L.providers.accounts(e)}).finally(()=>x(!1))},w=async()=>{try{let e=await navigator.clipboard.readText();if(!e.trim()){y.error(`Clipboard is empty`);return}c(e),y.success(`Pasted redirect URL`)}catch{y.error(`Clipboard unavailable on this origin`)}};return(0,Q.jsx)(P,{open:!0,onClose:v,title:`Connect via OAuth`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:v,disabled:l.isPending,children:`Cancel`}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:C,disabled:l.isPending||b,title:`You already approved in the popup — check now instead of waiting`,children:b?`Checking…`:`Complete`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,disabled:l.isPending||s.trim().length===0,onClick:()=>{let t=Hn(s);if(`error`in t){y.error(`OAuth callback failed`,t.error);return}l.mutate({providerId:e,code:t.code,state:n},{onSuccess:()=>{r.close(),y.success(`Account connected`,`OAuth login completed successfully`),i(!0)},onError:e=>y.error(`OAuth callback failed`,e.message??`Invalid or expired authorization code`)})},children:l.isPending?`Connecting…`:`Connect`})]}),children:(0,Q.jsxs)(Y,{gap:`14px`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,Q.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,Q.jsx)(`span`,{className:`text-body font-semibold`,children:`Waiting for popup authorization…`})]}),(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Q.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 1: Open this URL in your browser`}),(0,Q.jsxs)(X,{gap:`8px`,children:[(0,Q.jsx)(`a`,{className:`min-w-0 flex-1 font-mono text-badge text-accent overflow-hidden text-ellipsis whitespace-nowrap px-2.5 py-2 rounded-control bg-input-bg border border-inner-border`,href:t,target:`_blank`,rel:`noreferrer`,title:t,children:t}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:a?(0,Q.jsx)(p,{size:12}):(0,Q.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(t),o(!0),u(()=>o(!1),1500)},className:`shrink-0`,children:a?`Copied`:`Copy`})]}),(0,Q.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:`A popup should open automatically. If it was blocked, open the URL above manually.`})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2.5 text-micro font-bold uppercase tracking-label text-text-tertiary`,children:[(0,Q.jsx)(`span`,{"aria-hidden":`true`,className:`flex-1 h-px bg-inner-border`}),(0,Q.jsx)(`span`,{children:`Or complete manually`}),(0,Q.jsx)(`span`,{"aria-hidden":`true`,className:`flex-1 h-px bg-inner-border`})]}),(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Q.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 2: Paste the redirect URL here`}),(0,Q.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:`If the redirect lands on an unreachable address, copy that page's full URL from your browser and paste it below — this works from any machine, not just localhost.`}),(0,Q.jsxs)(X,{gap:`8px`,align:`flex-start`,children:[(0,Q.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),placeholder:`http://127.0.0.1:59653/callback?code=…&state=… (or just the code)`,rows:2,spellCheck:!1,className:`w-full min-h-16 resize-y rounded-control border border-inner-border bg-input-bg px-2.5 py-2 font-mono text-badge text-text-primary box-border focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-1 flex-1`}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void w(),className:`shrink-0`,children:`Paste`})]})]})]})})}function Wn(e){try{return new URL(e).host}catch{return e}}function Gn({providerId:e,parameters:t,onClose:n}){let r=R(),i=z(),[a,o]=(0,Z.useState)(null),[s,c]=(0,Z.useState)(!1),[l,u]=(0,Z.useState)(!1),d=st();(0,Z.useEffect)(()=>{let i=!1;return r.mutate({providerId:e,...t===void 0||Object.keys(t).length===0?{}:{parameters:t}},{onSuccess:e=>{i||o(e)},onError:e=>{i||(y.error(`Failed to start device login`,e.message??`Unable to start device authorization`),n())}}),()=>{i=!0}},[]);let m=(0,Z.useRef)(null),[h,_]=(0,Z.useState)(!1);return(0,Z.useEffect)(()=>{if(!a)return;let e=window.open(a.verificationUri,`cartethyia-device`,`popup,width=720,height=820`);return e?m.current=e:_(!0),()=>{let e=m.current;m.current=null,e&&!e.closed&&e.close()}},[a]),(0,Z.useEffect)(()=>{if(!a)return;let t=Date.now(),r=Math.max(1,a.expiresInSeconds)*1e3,o=!1,s=Math.max(1,a.intervalSeconds)*1e3,c=!1,l=0,u=()=>window.clearTimeout(l),d=e=>{u(),l=window.setTimeout(f,e)},f=()=>{if(!c){if(Date.now()-t>r){u(),y.error(`Device login expired`,`Please try again.`),n();return}o||(o=!0,i.mutate({providerId:e,deviceAuthId:a.deviceAuthId},{onSuccess:e=>{if(o=!1,!c){if(e.status===`complete`){u();let e=m.current;e&&!e.closed&&e.close(),y.success(`OAuth account connected`,`Device authorization complete`),n()}else e.status===`failed`?(u(),y.error(`Device login failed`,e.reason),n()):e.status===`slow_down`?(s=(e.retryAfterSeconds===void 0?s+5e3:Math.max(1,e.retryAfterSeconds)*1e3)+1e3,d(s)):(e.status===`pending`&&e.retryAfterSeconds!==void 0&&(s=Math.max(1,e.retryAfterSeconds)*1e3+1e3),d(s))}},onError:()=>{o=!1,c||d(s)}}))}};return d(s+1e3),()=>{c=!0,u()}},[a]),(0,Q.jsx)(P,{open:!0,onClose:n,title:`Login with OAuth (device code)`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,children:`Cancel`}),null]}),children:(0,Q.jsx)(Y,{gap:`14px`,children:a?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,Q.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,Q.jsx)(`span`,{className:`text-body font-semibold`,children:`Waiting for authorization…`})]}),a.userCode?(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Q.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:`Step 1: Enter this code`}),(0,Q.jsxs)(`div`,{className:`rounded-card border border-inner-border bg-surface-2 p-3.5 flex flex-col gap-1.5 items-center text-center`,children:[(0,Q.jsx)(`div`,{className:`text-micro font-bold uppercase tracking-label text-text-tertiary`,children:`Device code`}),(0,Q.jsx)(`div`,{className:`font-mono text-display font-bold tracking-code text-text-primary`,children:a.userCode}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:l?(0,Q.jsx)(p,{size:12}):(0,Q.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(a.userCode),u(!0),d(()=>u(!1),1500)},children:l?`Copied`:`Copy code`})]})]}):null,(0,Q.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Q.jsx)(`div`,{className:`text-body font-semibold text-text-primary`,children:a.userCode?`Step 2: Open the verification page`:`Open the verification page to authorize`}),(0,Q.jsxs)(X,{gap:`8px`,children:[(0,Q.jsx)(`a`,{className:`min-w-0 flex-1 font-mono text-badge text-accent overflow-hidden text-ellipsis whitespace-nowrap px-2.5 py-2 rounded-control bg-input-bg border border-inner-border`,href:a.verificationUri,target:`_blank`,rel:`noreferrer`,title:a.verificationUri,children:Wn(a.verificationUri)}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,Q.jsx)(Ce,{size:12}),onClick:()=>window.open(a.verificationUri,`_blank`,`noopener`),className:`shrink-0`,children:`Open`}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:s?(0,Q.jsx)(p,{size:12}):(0,Q.jsx)(f,{size:12}),onClick:()=>{navigator.clipboard?.writeText(a.verificationUri),c(!0),d(()=>c(!1),1500)},className:`shrink-0`,children:s?`Copied`:`Copy`})]}),(0,Q.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:h?`The popup was blocked — open the page with Open above, finish signing in there, then press Check now.`:`The page opened in a popup. Finish signing in there — this dialog closes automatically once the account connects, or press Check now.`})]})]}):(0,Q.jsxs)(`div`,{className:`flex items-center gap-2.5 px-3.5 py-2.5 rounded-card border border-inner-border bg-surface-2`,children:[(0,Q.jsx)(S,{size:16,className:`animate-spin text-accent shrink-0`}),(0,Q.jsx)(`span`,{className:`text-body font-semibold`,children:`Starting device authorization…`})]})})})}function Kn(e){let t={};for(let n of e)t[n.key]=n.defaultValue??``;return t}function qn(e,t){return e.filter(e=>e.required===!0&&(t[e.key]??``).trim().length===0).map(e=>e.key)}function Jn({fields:e,values:t,onChange:n,idPrefix:r}){return e.length===0?null:(0,Q.jsx)(Y,{gap:`10px`,children:e.map(e=>{let i=`${r}-${e.key}`,a=t[e.key]??``;return e.options&&e.options.length>0?(0,Q.jsx)(J,{id:i,label:e.label,value:a,onValueChange:t=>n(e.key,t),options:e.options.map(e=>({value:e.value,label:e.label}))},e.key):(0,Q.jsx)(q,{id:i,label:e.label,value:a,placeholder:e.placeholder??``,type:e.secret===!0?`password`:`text`,autoComplete:`off`,onChange:t=>n(e.key,t.target.value)},e.key)})})}function Yn({providerId:e,providerName:t,fields:n,onClose:r}){let i=Ie(),[a,o]=(0,Z.useState)(``),[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(()=>Kn(n)),d=(0,Z.useMemo)(()=>qn(n,l),[n,l]);return(0,Q.jsx)(P,{open:!0,onClose:r,title:`Import a ${t} credential`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:r,disabled:i.isPending,children:`Cancel`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,onClick:()=>{if(a.trim().length===0){y.error(`Credential required`,`Paste the token, key or exported JSON to import.`);return}if(d.length>0){y.error(`Missing required fields`,`Fill in: ${d.join(`, `)}`);return}i.mutate({providerId:e,credential:a.trim(),...Object.keys(l).length>0?{fields:l}:{},...s.trim().length>0?{accountLabel:s.trim()}:{}},{onSuccess:()=>{y.success(`Account imported`,`The credential was validated and saved`),r()},onError:e=>y.error(`Import failed`,e.message??`The provider rejected this credential`)})},disabled:i.isPending,icon:i.isPending?(0,Q.jsx)(S,{size:13,className:`animate-spin`}):void 0,children:i.isPending?`Validating…`:`Import`})]}),children:(0,Q.jsxs)(Y,{gap:`12px`,children:[(0,Q.jsxs)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:[`The credential is checked against `,t,` before it is saved, so one that no longer works is reported here instead of being stored.`]}),(0,Q.jsx)(Jn,{fields:n,values:l,idPrefix:`import`,onChange:(e,t)=>u(n=>({...n,[e]:t}))}),(0,Q.jsx)(q,{id:`import-account-label`,label:`Account label`,hint:`optional`,value:s,placeholder:e,onChange:e=>c(e.target.value)}),(0,Q.jsx)(q,{id:`import-credential`,label:`Credential`,value:a,placeholder:`Paste the token, key, or exported JSON`,type:`password`,autoComplete:`off`,onChange:e=>o(e.target.value)})]})})}function Xn(e,t,n){let r=n?.trim()??``,i=r.indexOf(` — `),a=i>0?r.slice(0,i):``,o=i>0?r.slice(i+3):r;return{title:`${e}/${t} probe failed${a.length>0?` via ${a}`:``}`,detail:o.length>0?o:`Unknown error`}}function Zn(e,t,n){let{title:r,detail:i}=Xn(e,t,n);return[r,i]}function Qn(e){return e===`builtin`?`Built-in model`:e===`auto_free`?`Free tier, discovered from the provider`:e===`discovered`?`Fetched from provider`:`Added manually`}function $n(e){return e===`auto_free`?`Free tier`:e===`discovered`?`Fetched`:`Manual`}var er=[{key:`builtin`,label:`Built-in models`,hint:`Compiled catalog — can be disabled, not deleted`,matches:e=>e===null||e===`builtin`},{key:`auto_free`,label:`Free models (auto)`,hint:`Discovered from the provider's free tier`,matches:e=>e===`auto_free`},{key:`manual`,label:`Manually added`,hint:`Added by hand from the Add Model dialog`,matches:e=>e===`manual`},{key:`fetched`,label:`Fetched from provider`,hint:`Listed by the provider's /v1/models`,matches:e=>e!==null&&e!==`builtin`&&e!==`auto_free`&&e!==`manual`}],tr={key:`disabled`,label:`Disabled models`,hint:`Turned off — not routable until re-enabled`};function nr(){return gt.map(e=>({value:e,label:e===`auto`?`Thinking: auto`:e.charAt(0).toUpperCase()+e.slice(1)}))}function rr({value:e,onChange:t,disabled:n,id:r=`probe-thinking-effort`}){return(0,Q.jsx)(`div`,{title:`Reasoning effort every test in this section sends. Auto leaves the model's own reasoning default in place.`,className:`min-w-74 shrink-0`,children:(0,Q.jsx)(J,{id:r,"aria-label":`Thinking effort`,value:e,disabled:n,onValueChange:e=>t(e),options:nr()})})}function ir({providerId:e,provider:t,onClose:n}){let r=Ne(),i=xe(),[a,o]=(0,Z.useState)(``),s=t?.supportedWireFamilies,c=t?.wireFamilyDefault!==void 0&&(s===void 0||s.includes(t.wireFamilyDefault))?t.wireFamilyDefault:s?.[0],l=(0,Z.useMemo)(()=>{let e=[`chat`,`responses`,`messages`],t=(s??[]).filter(t=>e.includes(t));return[...t,...e.filter(e=>!t.includes(e))]},[s]),[u,d]=(0,Z.useState)(c??`chat`),[f,p]=(0,Z.useState)(`auto`),[m,h]=(0,Z.useState)(`idle`),[_,v]=(0,Z.useState)(``),[b,C]=(0,Z.useState)(cr),w=a.trim(),T=w.toLowerCase().startsWith(`${e.toLowerCase()}/`)&&w.length>e.length+1?w.slice(e.length+1):w,E=T!==w,D=()=>{T&&(h(`testing`),v(``),r.mutate({providerId:e,request:{modelId:T,wireFamily:u,reasoningEffort:f,serviceKind:`llm`}},{onSuccess:e=>{e.ok?h(`passed`):(h(`failed`),v(e.error??`Model probe failed`))},onError:e=>{h(`failed`),v(e.message??`Model probe failed`)}}))};return(0,Q.jsx)(P,{open:!0,onClose:n,title:`Add Custom Model`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:i.isPending,children:`Cancel`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,disabled:i.isPending||T.length===0,onClick:()=>{if(!T)return;let t=G(b.contextLimit),r=G(b.outputLimit);if(t===null||r===null){y.error(`Invalid limits`,`Use a token count such as 512k, 200000, or 1.5m.`);return}i.mutate({providerId:e,modelIds:[T],wireFamily:u,metadata:{contextLimit:t??null,outputLimit:r??null,passthrough:b.passthrough,image:b.passthrough?!0:b.image,reasoning:b.passthrough?!0:b.reasoning,toolCall:b.passthrough?!0:b.toolCall}},{onSuccess:()=>{y.success(`Custom model added`,`Sent to ${e}/${T}`),n()},onError:e=>y.error(`Failed to add model`,e.message??`Unable to register model`)})},children:i.isPending?`Adding...`:`Add Model`})]}),children:(0,Q.jsxs)(Y,{gap:`10px`,children:[(0,Q.jsxs)(X,{gap:`8px`,align:`flex-end`,children:[(0,Q.jsx)(q,{label:`Model ID`,autoFocus:!0,placeholder:`e.g. gpt-4o, free-model-id`,value:a,onChange:e=>{o(e.target.value),h(`idle`),v(``)},onKeyDown:e=>{e.key===`Enter`&&T.length>0&&D()},className:`flex-1`}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:m===`testing`?(0,Q.jsx)(S,{size:13,className:`animate-spin`}):(0,Q.jsx)(x,{size:13}),disabled:r.isPending||T.length===0,onClick:D,className:`shrink-0`,children:m===`testing`?`Testing...`:`Test`})]}),E&&(0,Q.jsxs)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Using `,(0,Q.jsx)(`span`,{className:`font-mono tabular-nums`,children:T}),` (provider prefix removed).`]}),(0,Q.jsx)(J,{label:`Wire family`,id:`add-model-wire-family`,value:u,onValueChange:e=>{d(e),h(`idle`),v(``)},options:l.map(e=>({value:e,label:mr(e)}))}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Thinking`}),(0,Q.jsx)(rr,{id:`add-model-thinking-effort`,value:f,onChange:e=>{p(e),h(`idle`),v(``)},disabled:r.isPending}),(0,Q.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:`Sent with the test. Auto leaves the model's own reasoning default in place.`})]}),(0,Q.jsx)(lr,{draft:b,onChange:C,idPrefix:`add-model`,disabled:i.isPending}),s!==void 0&&!s.includes(u)&&(0,Q.jsxs)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:[`This provider does not declare the`,` `,(0,Q.jsx)(`span`,{className:`font-mono tabular-nums`,children:mr(u)}),` wire. The request is sent as chosen; the upstream decides whether it answers.`]}),m===`passed`&&(0,Q.jsx)(et,{tone:`success`,live:`status`,children:`Model test passed — ready to add.`}),m===`failed`&&(0,Q.jsx)(et,{tone:`danger`,live:`alert`,children:_||`Model test failed.`})]})})}function ar(){return{contextLimit:``,outputLimit:``,passthrough:!1,image:!0,reasoning:!0,toolCall:!0}}var or=String(We),sr=String(Ve);function cr(){return{...ar(),contextLimit:or,outputLimit:sr}}function lr({draft:e,onChange:t,idPrefix:n,disabled:r=!1}){let i=e.passthrough;return(0,Q.jsxs)(Y,{gap:`10px`,children:[(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Limits`}),(0,Q.jsxs)(X,{gap:`8px`,children:[(0,Q.jsx)(q,{label:`Context`,id:`${n}-context`,placeholder:or,value:e.contextLimit,disabled:r,onChange:n=>t({...e,contextLimit:n.target.value}),className:`flex-1`}),(0,Q.jsx)(q,{label:`Output`,id:`${n}-output`,placeholder:sr,value:e.outputLimit,disabled:r,onChange:n=>t({...e,outputLimit:n.target.value}),className:`flex-1`})]}),(0,Q.jsxs)(`label`,{className:`inline-flex items-center gap-2 mt-2 text-badge text-text-secondary cursor-pointer`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,id:`${n}-fallback-limits`,checked:e.contextLimit===or&&e.outputLimit===sr,disabled:r,onChange:n=>t(n.target.checked?{...e,contextLimit:or,outputLimit:sr}:{...e,contextLimit:``,outputLimit:``})}),`Use fallback — `,He(We),` ctx ·`,` `,He(Ve),` out`]})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`div`,{className:`text-badge font-semibold text-text-secondary mb-2`,children:`Capabilities`}),(0,Q.jsx)(Y,{gap:`6px`,children:[[`image`,`Can image`,e.image],[`reasoning`,`Reasoning`,e.reasoning],[`toolCall`,`Tools`,e.toolCall]].map(([a,o,s])=>(0,Q.jsxs)(`label`,{className:`inline-flex items-center gap-2 text-badge text-text-secondary`,style:i?{opacity:.5}:void 0,children:[(0,Q.jsx)(`input`,{type:`checkbox`,id:`${n}-${a}`,checked:i?!0:s,disabled:r||i,onChange:n=>t({...e,[a]:n.target.checked})}),o]},a))}),(0,Q.jsxs)(`label`,{className:`inline-flex items-center gap-2 mt-2 text-badge text-text-secondary cursor-pointer`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,id:`${n}-passthrough`,checked:e.passthrough,disabled:r,onChange:n=>t({...e,passthrough:n.target.checked})}),`Passthrough — accept every capability`]}),i?(0,Q.jsx)(`div`,{className:`text-badge text-text-tertiary mt-2`,children:`Passthrough grants all of the above, so they are locked on. Uncheck it to restore your own choices.`}):null]})]})}function ur({providerId:e,model:t,onClose:n}){let r=ge(),[i,a]=(0,Z.useState)(()=>({contextLimit:t.contextLimit?String(t.contextLimit):``,outputLimit:t.outputLimit?String(t.outputLimit):``,passthrough:!1,image:t.vision===!0,reasoning:t.reasoning===!0,toolCall:t.toolCall===!0}));return(0,Q.jsx)(P,{open:!0,onClose:n,title:`Edit Model`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:n,disabled:r.isPending,children:`Cancel`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,disabled:r.isPending,onClick:()=>{let a=G(i.contextLimit),o=G(i.outputLimit);if(a===null||o===null){y.error(`Invalid limits`,`Use a token count such as 512k, 200000, or 1.5m.`);return}r.mutate({providerId:e,modelId:t.modelId,route:t.route??``,metadata:{contextLimit:a??null,outputLimit:o??null,passthrough:i.passthrough,image:i.passthrough?!0:i.image,reasoning:i.passthrough?!0:i.reasoning,toolCall:i.passthrough?!0:i.toolCall}},{onSuccess:()=>n(),onError:e=>y.error(`Failed to update model`,e.message??`Unable to update model`)})},children:r.isPending?`Saving...`:`Save`})]}),children:(0,Q.jsxs)(Y,{gap:`10px`,children:[(0,Q.jsxs)(`div`,{className:`text-badge text-text-tertiary`,children:[`Editing `,(0,Q.jsx)(`span`,{className:`font-mono tabular-nums`,children:t.modelId})]}),(0,Q.jsx)(lr,{draft:i,onChange:a,idPrefix:`edit-model`,disabled:r.isPending})]})})}function dr({providerId:e,model:t,serviceKind:n,searchCapable:r,thinkingEffort:i,onDeleteRequest:a,onEditRequest:c,deletePending:l}){let u=Ne(),m=V(),[_,v]=(0,Z.useState)(!1),[E,O]=(0,Z.useState)(null),ee=st(),k=n===`llm`?_t(t.modelId,i===`auto`?null:i):t.modelId,A=`${e}/${k}`,j=n===`websearch`?`Searching…`:`Thinking…`,te=()=>{u.mutate({providerId:e,request:{modelId:t.modelId,route:t.route,...n===`llm`?{reasoningEffort:i}:{},serviceKind:n}},{onSuccess:t=>{if(O({ok:t.ok,latencyMs:t.latencyMs}),!t.ok){let{title:n,detail:r}=Xn(e,k,t.error);y.error(n,r);return}let n=t.sample?.trim()??``,r=t.reportedModel?.trim()??``;y.successRich(`${k} · END ${h(t.latencyMs)}`,(0,Q.jsxs)(`span`,{className:`grid gap-2 min-w-0`,children:[r?(0,Q.jsxs)(X,{gap:`6px`,align:`center`,className:`min-w-0`,children:[(0,Q.jsx)(T,{size:12,"aria-hidden":`true`,className:`shrink-0 text-text-tertiary`}),(0,Q.jsx)(`span`,{className:`truncate font-mono text-badge text-text-secondary`,title:r,children:r})]}):null,(0,Q.jsx)(`span`,{children:n||`No sample text in the response.`})]}),[r,n].filter(Boolean).join(`
3
- `)||`No sample text in the response.`)},onError:t=>{O({ok:!1,latencyMs:0}),y.error(...Zn(e,k,t.message))}})},M=()=>{let n=!t.enabled;m.mutate({providerId:e,request:{modelId:t.modelId,route:t.route,enabled:n}},{onSuccess:()=>y.success(n?`Model enabled`:`Model disabled`,t.modelId),onError:e=>y.error(`Failed to update model`,e.message??`Unable to update model`)})};return(0,Q.jsx)(Q.Fragment,{children:(0,Q.jsxs)(`div`,{className:`model-card box-border flex w-full min-w-0 flex-1-auto flex-col gap-5 rounded-panel border border-inner-border p-6 ${t.enabled?`bg-surface-2`:`bg-surface-1 opacity-72`}`,children:[(0,Q.jsxs)(`div`,{className:`flex items-start gap-4 min-w-0`,children:[(0,Q.jsx)(`span`,{className:`inline-flex items-center justify-center w-13 h-13 rounded-inset bg-teal-soft text-teal shrink-0`,children:(0,Q.jsx)(o,{size:14})}),(0,Q.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-1`,children:[(0,Q.jsx)(`div`,{title:A,className:`font-mono tabular-nums min-w-0 truncate text-caption font-semibold leading-[1.35]`,children:k}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0 text-micro text-text-tertiary`,children:[(0,Q.jsx)(`span`,{title:`${t.wireFamily} · ${t.route??e}`,className:`shrink-0 rounded-tiny px-3.5 py-0.5 text-micro font-bold`,style:{...pr(t.wireFamily)},children:mr(t.wireFamily)}),t.source!==null&&t.source!==`builtin`?(0,Q.jsx)(`span`,{title:Qn(t.source),className:`shrink-0 rounded-pill border border-teal-soft px-3 py-0.5 text-micro font-bold tracking-[0.04em] text-teal`,children:$n(t.source)}):null,t.proOnly===!0?(0,Q.jsx)(`span`,{title:`Refused on a free plan. Nothing in the provider's model directory predicts it, so this comes from a real dispatch: the upstream answers that the model is not allowed for a free user type.`,className:`shrink-0 rounded-tiny border border-orange bg-orange-soft px-3.5 py-0.5 text-micro font-bold uppercase tracking-[0.04em] text-orange`,children:`Pro`}):null,t.freeTier===!0&&t.source!==`auto_free`?(0,Q.jsx)(`span`,{title:`Free on this provider's plan. Taken from the provider's own model directory, not a hardcoded list, so it tracks plan changes.`,className:`shrink-0 rounded-pill border border-teal-soft px-3 py-0.5 text-micro font-bold text-teal`,children:`Free tier`}):null,t.enabled?null:(0,Q.jsx)(`span`,{className:`shrink-0 rounded-pill bg-red-soft px-3 py-0.5 text-micro font-bold tracking-[0.04em] text-red`,children:`Off`})]})]}),(0,Q.jsx)(g,{variant:`ghost`,size:`sm`,icon:_?(0,Q.jsx)(p,{size:12}):(0,Q.jsx)(f,{size:12}),"aria-label":`Copy ${A}`,title:`Copy ${A}`,onClick:()=>{navigator.clipboard?.writeText(A),v(!0),ee(()=>v(!1),1500)},className:`shrink-0 p-2 opacity-70`})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0 text-badge text-text-secondary`,children:[(0,Q.jsxs)(`span`,{className:`inline-flex gap-2.5`,children:[t.reasoning?(0,Q.jsx)(`span`,{title:`Reasoning`,"aria-label":`Reasoning`,className:`inline-flex text-purple`,children:(0,Q.jsx)(s,{size:12})}):null,t.vision?(0,Q.jsx)(`span`,{title:`Vision`,"aria-label":`Vision`,className:`inline-flex text-status-info`,children:(0,Q.jsx)(D,{size:12})}):null,t.toolCall?(0,Q.jsx)(`span`,{title:`Tool calling`,"aria-label":`Tool calling`,className:`inline-flex text-orange`,children:(0,Q.jsx)(ce,{size:12})}):null,r?(0,Q.jsx)(`span`,{title:`Web search`,"aria-label":`Web search`,className:`inline-flex text-teal`,children:(0,Q.jsx)(d,{size:12})}):null]}),(0,Q.jsxs)(`span`,{className:`whitespace-nowrap`,children:[t.limitsEstimated?(0,Q.jsx)(`span`,{title:Ue,"aria-label":`Limits are a fallback estimate`,className:`estimate-dot inline-flex items-center justify-center rounded-full border border-inner-border bg-surface-2 text-orange cursor-help mr-1 align-middle`,children:(0,Q.jsx)(C,{size:9,"aria-hidden":`true`})}):null,t.contextLimit?`${He(t.contextLimit)} ctx`:(0,Q.jsx)(`span`,{title:Ge,className:`cursor-help`,children:`n/a ctx`}),t.outputLimit?` · ${He(t.outputLimit)} out`:(0,Q.jsx)(`span`,{title:Ge,className:`cursor-help`,children:` · n/a out`})]}),c?(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 grid place-items-center w-6 h-6 p-0 border-0 bg-transparent text-text-tertiary cursor-pointer rounded-tiny hover:bg-inner-border hover:text-text-primary`,title:`Edit limits and capabilities`,"aria-label":`Edit ${t.modelId} limits and capabilities`,onClick:()=>c(t),children:(0,Q.jsx)(F,{size:11})}):null]}),(0,Q.jsxs)(`div`,{className:`flex gap-3 items-center flex-wrap`,children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,disabled:u.isPending,onClick:te,"aria-label":`Test ${k}`,title:u.isPending?`Probing ${k}…`:E?.ok?`Last probe OK in ${h(E.latencyMs)} — click to re-test`:E?`Last probe failed — click to retry`:`Test ${k}`,className:`flex-1 justify-center`,icon:u.isPending?(0,Q.jsx)(S,{size:12,className:`animate-spin`}):E?E.ok?(0,Q.jsx)(`span`,{className:`inline-flex text-green`,children:(0,Q.jsx)(w,{size:12})}):(0,Q.jsx)(`span`,{className:`inline-flex text-red`,children:(0,Q.jsx)(b,{size:12})}):(0,Q.jsx)(x,{size:12}),children:u.isPending?j:E?.ok?h(E.latencyMs):E?`Fail`:`Test`}),(0,Q.jsx)(g,{variant:`ghost`,size:`sm`,disabled:m.isPending,onClick:M,icon:t.enabled?(0,Q.jsx)(re,{size:12}):(0,Q.jsx)(ut,{size:12}),"aria-label":t.enabled?`Disable ${t.modelId}`:`Enable ${t.modelId}`,title:t.enabled?`Disable model`:`Enable model`,className:`flex-1 justify-center ${t.enabled?`text-red`:`text-green`}`,children:t.enabled?`Disable`:`Enable`}),t.source===`builtin`?null:(0,Q.jsx)(g,{variant:`ghost`,size:`sm`,disabled:l,onClick:()=>a(t),icon:(0,Q.jsx)(se,{size:12}),"aria-label":`Delete ${t.modelId}`,title:`Delete model`,className:`model-card-delete shrink-0 px-4 py-3 text-text-tertiary`})]})]})})}var fr=(0,Z.memo)(dr);function pr(e){return e===`responses`?{color:`var(--purple)`,background:`var(--purple-soft)`}:e===`messages`?{color:`var(--orange)`,background:`color-mix(in srgb, var(--orange) 14%, transparent)`}:{color:`var(--teal)`,background:`var(--teal-soft)`}}function mr(e){let t=e.toLowerCase();return t===`responses`?`Responses`:t===`messages`?`Messages`:`Chat`}function hr({providerId:e,models:t,thinkingEffort:n,serviceKind:r=`llm`,searchCapable:i=!1}){let a=Se(),[o,s]=(0,Z.useState)(null),[c,l]=(0,Z.useState)(null),u=e=>e.enabled!==!1,d=er.map(e=>({...e,rows:t.filter(t=>u(t)&&e.matches(t.source))})).filter(e=>e.rows.length>0),f=t.filter(e=>!u(e)),p=t=>(0,Q.jsx)(fr,{providerId:e,model:t,serviceKind:r,searchCapable:i,thinkingEffort:n,deletePending:a.isPending,onDeleteRequest:s,onEditRequest:t.source===`builtin`?void 0:l},`${t.modelId}::${t.route}`);return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(Y,{gap:`16px`,children:[d.map(e=>(0,Q.jsxs)(`section`,{className:`flex flex-col gap-4`,children:[(0,Q.jsxs)(`div`,{className:`flex items-baseline gap-4 min-w-0`,children:[(0,Q.jsx)(`span`,{className:`text-caption font-bold text-text-secondary`,children:e.label}),(0,Q.jsx)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:e.rows.length}),(0,Q.jsxs)(`span`,{title:e.hint,className:`text-micro text-text-tertiary overflow-hidden truncate`,children:[`· `,e.hint]})]}),(0,Q.jsx)(`div`,{className:`provider-grid grid gap-4 items-stretch`,children:e.rows.map(p)})]},e.key)),f.length===0?null:(0,Q.jsxs)(`section`,{className:`flex flex-col gap-4`,children:[(0,Q.jsxs)(`div`,{className:`flex items-baseline gap-4 min-w-0`,children:[(0,Q.jsx)(`span`,{className:`text-caption font-bold text-text-secondary`,children:tr.label}),(0,Q.jsx)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:f.length}),(0,Q.jsxs)(`span`,{title:tr.hint,className:`text-micro text-text-tertiary overflow-hidden truncate`,children:[`· `,tr.hint]})]}),(0,Q.jsx)(`div`,{className:`provider-grid grid gap-4 items-stretch`,children:f.map(p)})]})]}),(0,Q.jsx)(ze,{open:o!==null,onClose:()=>{a.isPending||s(null)},onConfirm:async()=>{o!==null&&(await a.mutateAsync({providerId:e,request:{modelId:o.modelId,route:o.route}}),y.success(`Model deleted`,`${e}/${o.modelId}`),s(null))},title:`Delete model?`,message:`Delete ${e}/${o?.modelId??``} from the provider catalog?`,confirmLabel:`Delete`,danger:!0}),c===null?null:(0,Q.jsx)(ur,{providerId:e,model:c,onClose:()=>l(null)})]})}function gr(e){return e===`llm`?`LLM`:e===`websearch`?`Search`:e===`imageGeneration`?`Image`:e===`videoGeneration`?`Video`:e}function _r(e){let t=e.serviceKinds;return Array.isArray(t)&&t.length>0?t:[`llm`]}function vr(){let{providerId:e}=we(),[t]=Fe(),n=e??``,r=t.get(`service`),[i,a]=(0,Z.useState)(r===`websearch`||r===`imageGeneration`||r===`videoGeneration`?r:`llm`),o=De(n),s=Ee(n),c=je(n),u=Le(),f=Le({silent:!0}),[p,h]=(0,Z.useState)(!1),_=Te(),v=_e(),b=ye(),x=ue(),[S,C]=(0,Z.useState)(!1),[w,T]=(0,Z.useState)(!1),E=Ne(),[D,O]=(0,Z.useState)(``),[M,ne]=(0,Z.useState)(``),[N,F]=(0,Z.useState)(null),ae=e=>`cartethyia:provider:${e}:thinking-effort`,oe=e=>{if(typeof window>`u`||!window.localStorage)return`auto`;let t=window.localStorage.getItem(ae(e));if(t===null)return`auto`;let n=t.trim().toLowerCase();return gt.includes(n)?n:`auto`},[ce,le]=(0,Z.useState)(()=>oe(n));(0,Z.useEffect)(()=>{if(!n)return;let e=oe(n);e!==ce&&le(e)},[n]),(0,Z.useEffect)(()=>{typeof window>`u`||!window.localStorage||!n||window.localStorage.setItem(ae(n),ce)},[n,ce]);let[de,fe]=(0,Z.useState)(!1),[pe,he]=(0,Z.useState)(!1),[R,ge]=(0,Z.useState)(null),[ve,be]=(0,Z.useState)({}),[xe,Se]=(0,Z.useState)({}),[z,Oe]=(0,Z.useState)(null),[ke,Ae]=(0,Z.useState)(!1),[Me,Pe]=(0,Z.useState)(null),B=(0,Z.useRef)(null),Ie=(0,Z.useRef)(null);(0,Z.useEffect)(()=>()=>{let e=B.current;B.current=null,e&&!e.closed&&e.close()},[]);let V=o.data,Re=n===`opencode`||n===`cline`,Be=V===void 0?[`llm`]:_r(V),G=[];for(let e of Be)(e===`llm`||e===`websearch`||e===`imageGeneration`||e===`videoGeneration`)&&G.push(e);(0,Z.useEffect)(()=>{if(V===void 0)return;let e=r===`websearch`||r===`imageGeneration`||r===`videoGeneration`||r===`llm`?r:void 0,t=G[0];if(e!==void 0&&G.includes(e)){i!==e&&a(e);return}!G.includes(i)&&t!==void 0&&a(t)},[V,r,i,G.join(`|`)]),(0,Z.useEffect)(()=>{Re&&V!==void 0&&V.supportsModelDiscovery!==!1&&Ie.current!==n&&(Ie.current=n,f.mutate(n))},[Re,f,n,V?.supportsModelDiscovery]);let Ve=c.data??[],He=s.data??[],Ue=(()=>{let e=new Map;for(let t of He){let n=`${t.serviceKind??`llm`}:${t.modelId}`,r=e.get(n);if(!r)e.set(n,t);else{let i=r.contextLimit??0;(t.contextLimit??0)>i&&e.set(n,t)}}return[...e.values()].sort((e,t)=>e.modelId.localeCompare(t.modelId))})(),We=Ue.filter(e=>e.serviceKind===`llm`||e.serviceKind===void 0),Ge=Ue.filter(e=>e.serviceKind===`websearch`),K=Ue.filter(e=>e.serviceKind===`imageGeneration`),q=Ue.filter(e=>e.serviceKind===`videoGeneration`),J=G.includes(i)?i:G[0],qe=M||Ge[0]?.modelId||``,Ye=()=>{let e=D.trim();qe&&e&&(F(null),E.mutate({providerId:n,request:{modelId:qe,serviceKind:`websearch`,prompt:e}},{onSuccess:e=>F({ok:e.ok,latencyMs:e.latencyMs,...e.searchResults?{results:e.searchResults,count:e.searchResults.length}:{},...e.error?{error:e.error}:{}}),onError:e=>F({ok:!1,error:e instanceof Error?e.message:`Search test failed`})}))};if(o.isPending)return(0,Q.jsx)(A,{label:`Loading provider...`});if(o.isError)return(0,Q.jsx)(k,{title:`Unable to load providers`,message:`The provider details could not be read, so this page cannot resolve its endpoint settings.`,onRetry:()=>void o.refetch(),retrying:o.isFetching,action:(0,Q.jsx)(vt,{to:`/providers`,label:`Back to providers`})});if(!V)return(0,Q.jsx)(j,{icon:(0,Q.jsx)(dt,{size:20}),title:`Provider not found`,message:`No provider named “${n}”. It may have been removed, or the link is stale.`,action:(0,Q.jsx)(vt,{to:`/providers`,label:`Back to providers`})});let Xe=Ve.filter(e=>e.status===`active`).length,Ze=e=>{let t=e===`browser`?V?.oauthFlows?.browserLoginFields??[]:V?.oauthFlows?.deviceLoginFields??[];if(t.length===0){e===`browser`?$e():fe(!0);return}be(Kn(t)),ge(e)},Qe=()=>{if(R===null)return;let e=qn(R===`browser`?V?.oauthFlows?.browserLoginFields??[]:V?.oauthFlows?.deviceLoginFields??[],ve);if(e.length>0){y.error(`Missing required fields`,`Fill in: ${e.join(`, `)}`);return}let t=R;ge(null),t===`browser`?$e(ve):(Se(ve),fe(!0))},$e=e=>{let t=window.open(`about:blank`,`cartethyia-oauth`,`popup,width=720,height=820`);t&&(t.opener=null,B.current=t),b.mutate({providerId:n,...e===void 0?{}:{parameters:e}},{onSuccess:({authorizeUrl:e,state:n})=>{let r=null;if(t&&!t.closed?(t.location.href=e,r=t):(r=window.open(e,`cartethyia-oauth`,`popup,width=720,height=820`),r&&(r.opener=null,B.current=r)),!r){y.error(`Popup blocked`,`Allow popups to complete OAuth login.`);return}Pe({authorizeUrl:e,state:n,popup:r})},onError:e=>{t&&!t.closed&&t.close(),B.current===t&&(B.current=null),y.error(`Failed to start OAuth`,e.message??`Unable to start authorization`)}})};return(0,Q.jsxs)(Y,{gap:`16px`,children:[(0,Q.jsx)(yt,{title:`${V.label||V.displayName}${J?` (${gr(J)})`:``}`,description:`${V.providerId}/${V.baseUrl?` · ${V.baseUrl}`:``}`,icon:(0,Q.jsx)(Ke,{icon:V.providerId,name:V.label||V.displayName,size:28}),back:{to:`/providers`,label:`Back to Providers`},actions:(0,Q.jsx)(X,{gap:`8px`,className:`flex-wrap w-full max-w-full min-w-0`,children:V.isBuiltIn?(0,Q.jsx)(g,{variant:V.enabled?`danger`:`secondary`,icon:V.enabled?(0,Q.jsx)(re,{size:13}):(0,Q.jsx)(ut,{size:13}),loading:v.isPending,onClick:()=>v.mutate({providerId:n,enabled:!V.enabled},{onSuccess:e=>y.success(e.enabled?`Provider enabled`:`Provider disabled`,V.label||V.displayName),onError:e=>y.error(`Provider update failed`,e.message??`Unable to change provider availability`)}),title:V.enabled?`Disable provider globally`:`Enable provider globally`,children:V.enabled?`Disable`:`Enable`}):null})}),(0,Q.jsx)(Jt,{provider:V}),V.isBuiltIn?null:(0,Q.jsx)(Yt,{provider:V}),J===`llm`?(0,Q.jsx)(kt,{providerId:n,clientVersion:V.clientVersion,routeIdentityVersions:V.routeIdentityVersions,userAgentEditable:bt(V)}):null,(0,Q.jsx)(`div`,{id:`provider-accounts`,tabIndex:-1,children:V.requiresAccount===!1?(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Accounts`,icon:(0,Q.jsx)(ct,{size:16})}),(0,Q.jsx)(H,{children:(0,Q.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`This provider is a public, unauthenticated route — no account or credential is needed. Routing already works without any setup here.`})})]}):(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Accounts`,subtitle:`${Ve.length} total · ${Xe} active · ${Ve.length-Xe} disabled`,icon:(0,Q.jsx)(ct,{size:16}),action:(0,Q.jsxs)(Je,{children:[V.oauthFlows?.browser&&(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,Q.jsx)(Ce,{size:13}),disabled:b.isPending,onClick:()=>Ze(`browser`),title:`Browser OAuth login — opens the provider authorize page in a popup`,children:b.isPending?`Starting...`:`Login with browser`}),V.oauthFlows?.device&&(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,Q.jsx)(te,{size:13}),onClick:()=>Ze(`device`),title:`Device-code login — enter the shown code on the provider site`,children:`Login with device code`}),V.oauthFlows?.import&&(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,Q.jsx)(m,{size:13}),onClick:()=>he(!0),title:V.oauthFlows.browser||V.oauthFlows.device||V.oauthFlows.refreshable?`Import a credential you already hold — a refresh token, an exported auth blob, or an API key`:`Add and validate an API key`,children:V.oauthFlows.browser||V.oauthFlows.device||V.oauthFlows.refreshable?`Import credential`:`Add API key`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,Q.jsx)(I,{size:13}),onClick:()=>C(!0),children:`Add Account`})]})}),(0,Q.jsxs)(H,{className:`flex flex-col gap-5`,children:[(0,Q.jsx)(Wt,{providerId:n}),c.isPending?(0,Q.jsx)(A,{label:`Loading accounts...`}):c.isError?(0,Q.jsx)(k,{message:`Failed to load accounts`,onRetry:()=>c.refetch()}):Ve.length===0?(0,Q.jsx)(j,{title:`No accounts connected`,message:`Add an API key or OAuth credential to route requests to this provider.`}):(0,Q.jsx)(Rn,{providerId:n,accounts:Ve,onDelete:e=>Oe(e),showGrokProbe:J===`llm`&&n===`grok`,grokProbePending:_.isPending,onGrokProbe:()=>{_.mutate({providerId:n,request:{modelId:`grok-4.6`,prompt:`reply my message with exact number 407`,stream:!0,serviceKind:`llm`}},{onSuccess:e=>{let t=e.results.filter(e=>e.ok).length,n=e.results.filter(e=>e.statusCode===202).length,r=e.results.length-t-n;y.success(`Grok account probe complete`,`${t} passed · ${n} returned 202 and were parked in cooldown · ${r} other failures`)},onError:e=>y.error(`Grok account probe failed`,e.message??`Unable to probe Grok accounts`)})}})]})]})}),J===`llm`?(0,Q.jsxs)(Q.Fragment,{children:[n===`inferhub`?(0,Q.jsx)(Vt,{}):null,(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Models`,subtitle:`${We.length} model${We.length===1?``:`s`} registered`,icon:(0,Q.jsx)(l,{size:16}),action:(0,Q.jsxs)(X,{gap:`6px`,className:`flex-wrap items-center`,children:[(0,Q.jsx)(rr,{id:`models-section-thinking-effort`,value:ce,onChange:le}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,Q.jsx)(ie,{size:13,className:u.isPending||f.isPending?`animate-spin`:``}),disabled:u.isPending||f.isPending,onClick:()=>u.mutate(n),children:u.isPending||f.isPending?`Fetching...`:`Fetch models`}),(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,Q.jsx)(se,{size:13,className:p?`animate-spin`:``}),disabled:u.isPending||f.isPending||p||We.filter(e=>e.source!==`builtin`&&e.source!==null).length===0,onClick:async()=>{let e=We.filter(e=>e.source!==`builtin`&&e.source!==null);if(e.length!==0&&confirm(`Delete ${e.length} fetched/manual model(s) for ${n}?`)){h(!0);try{let t=await me(`/providers/${encodeURIComponent(n)}/models/bulk`,{method:`DELETE`,body:JSON.stringify({items:e.map(e=>({modelId:e.modelId,route:e.route}))})});await Promise.all([x.invalidateQueries({queryKey:L.providers.models(n)}),x.invalidateQueries({queryKey:L.providers.all})]);let r=t.failures.length;y.success(`Fetched models deleted`,r>0?`${t.deleted}/${t.total} removed, ${r} failed`:`${t.deleted}/${t.total} removed`)}catch(e){y.error(`Failed to delete fetched models`,e.message??`Unable to delete models`)}finally{h(!1)}}},children:p?`Deleting…`:`Delete fetched`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,icon:(0,Q.jsx)(I,{size:13}),onClick:()=>T(!0),children:`Add Model`})]})}),(0,Q.jsx)(H,{className:`flex flex-col gap-8`,children:s.isPending?(0,Q.jsx)(A,{label:`Loading models...`}):s.isError?(0,Q.jsx)(k,{message:`Failed to load models`,onRetry:()=>s.refetch()}):We.length===0?(0,Q.jsx)(j,{title:`No LLM models found`,message:`No LLM models published by this provider yet. Sync or add a custom model above.`}):(0,Q.jsx)(hr,{providerId:n,models:We,serviceKind:`llm`,thinkingEffort:ce,searchCapable:V?.supportsWebSearch===!0})})]})]}):J===`websearch`?(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:`Web Search`,subtitle:`Run a real search request through the selected provider.`,icon:(0,Q.jsx)(d,{size:16})}),(0,Q.jsx)(H,{className:`flex flex-col gap-6`,children:s.isPending?(0,Q.jsx)(A,{label:`Loading search models...`}):s.isError?(0,Q.jsx)(k,{message:`Failed to load search models`,onRetry:()=>s.refetch()}):Ge.length===0?(0,Q.jsx)(j,{title:`No Search models found`,message:`This provider advertises Search, but no websearch model is registered yet.`}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`label`,{className:`flex flex-col gap-2.5 text-badge text-text-secondary`,children:[`Search model`,(0,Q.jsx)(`select`,{value:qe,onChange:e=>{ne(e.target.value),F(null)},className:`w-full min-h-17 rounded-inset border border-inner-border bg-surface-1 text-text-primary px-4.5 py-0`,children:Ge.map(e=>(0,Q.jsx)(`option`,{value:e.modelId,children:e.modelId},`${e.modelId}:${e.route}`))})]}),(0,Q.jsxs)(`label`,{className:`flex flex-col gap-2.5 text-badge text-text-secondary`,children:[`Query`,(0,Q.jsx)(`input`,{value:D,onChange:e=>O(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Ye())},placeholder:`What is the latest news about AI?`,className:`w-full min-h-17 rounded-inset border border-inner-border bg-surface-1 text-text-primary px-4.5 py-0`})]}),(0,Q.jsxs)(X,{gap:`8px`,className:`items-center flex-wrap`,children:[(0,Q.jsx)(g,{variant:`primary`,size:`sm`,disabled:E.isPending||D.trim().length===0,loading:E.isPending,onClick:Ye,children:`Test search`}),N?(0,Q.jsx)(`span`,{className:`text-badge`,style:{color:N.ok?`var(--green)`:`var(--red)`},children:N.ok?`Search ok · ${N.latencyMs}ms · ${N.count??0} result(s)`:N.error??`Search failed.`}):null]}),N&&N.results&&N.results.length>0?(0,Q.jsx)(`div`,{className:`flex max-h-110 flex-col gap-4 overflow-y-auto rounded-inset border border-inner-border bg-surface-1 p-4`,children:N.results.map((e,t)=>(0,Q.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Q.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noreferrer`,className:`text-caption text-text-primary font-semibold`,children:e.title||e.url}),(0,Q.jsx)(`span`,{className:`text-badge text-text-tertiary break-all`,children:e.url}),e.snippet?(0,Q.jsx)(`span`,{className:`text-badge text-text-secondary`,children:e.snippet}):null]},`${e.url}:${t}`))}):null]})})]}):J===`imageGeneration`||J===`videoGeneration`?(0,Q.jsxs)(W,{children:[(0,Q.jsx)(U,{title:gr(J),subtitle:J===`imageGeneration`?`Models that return an image rather than text.`:`Models that return a video. Wired and routable; not yet verified against a live account.`,icon:J===`imageGeneration`?(0,Q.jsx)(ee,{size:16}):(0,Q.jsx)(mt,{size:16})}),(0,Q.jsx)(H,{className:`flex flex-col gap-6`,children:s.isPending?(0,Q.jsx)(A,{label:`Loading ${gr(J).toLowerCase()} models...`}):s.isError?(0,Q.jsx)(k,{message:`Failed to load ${gr(J).toLowerCase()} models`,onRetry:()=>s.refetch()}):(J===`imageGeneration`?K:q).length===0?(0,Q.jsx)(j,{title:`No ${gr(J)} models found`,message:`This provider advertises ${gr(J)}, but no ${J} model is registered yet.`}):(0,Q.jsx)(hr,{providerId:n,models:J===`imageGeneration`?K:q,serviceKind:`llm`,searchCapable:!1,thinkingEffort:`auto`})})]}):(0,Q.jsx)(W,{children:(0,Q.jsx)(H,{children:(0,Q.jsx)(j,{title:`Service not available`,message:`This provider advertises ${Be.map(gr).join(`, `)}, but the dashboard has no controls for the selected service yet.`})})}),S&&(0,Q.jsx)(Vn,{providerId:n,accounts:Ve,onClose:()=>C(!1)}),J===`llm`&&w?(0,Q.jsx)(ir,{providerId:n,provider:V,onClose:()=>T(!1)}):null,(0,Q.jsx)(ze,{open:z!==null,onClose:()=>{ke||Oe(null)},onConfirm:async()=>{if(z){Ae(!0);try{let e=z.tenantId===null?`/global/accounts/${encodeURIComponent(z.id)}`:`/accounts/${encodeURIComponent(z.id)}`;await me(e,{method:`DELETE`}),x.removeQueries({queryKey:L.quota.account(z.id),exact:!0}),await Promise.all([x.invalidateQueries({queryKey:L.providers.accounts(n)}),x.invalidateQueries({queryKey:L.providers.healthEvents(n,z.id)}),x.invalidateQueries({queryKey:L.providers.all}),x.invalidateQueries({queryKey:L.quota.all})]),y.success(`Account deleted`,z.label||z.id.slice(0,8)),Oe(null)}catch(e){throw y.error(`Failed to delete account`,e.message??`Unable to delete account`),e}finally{Ae(!1)}}},title:`Delete account?`,message:`Delete "${z?.label||z?.id.slice(0,8)}"? This cannot be undone.`,confirmLabel:`Delete`,danger:!0}),de&&(0,Q.jsx)(Gn,{providerId:n,parameters:xe,onClose:()=>{fe(!1),Se({})}}),R!==null&&(0,Q.jsx)(P,{open:!0,onClose:()=>ge(null),title:R===`browser`?`Sign in with`:`Device sign-in details`,size:`sm`,footer:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>ge(null),children:`Cancel`}),(0,Q.jsx)(g,{variant:`primary`,size:`sm`,onClick:Qe,children:`Continue`})]}),children:(0,Q.jsxs)(Y,{gap:`12px`,children:[(0,Q.jsx)(`p`,{className:`text-badge leading-snug text-text-tertiary`,children:R===`browser`?`Choose how ${V.label||V.displayName} should identify you, then continue to its sign-in page.`:`These decide which organization the device code is issued for.`}),(0,Q.jsx)(Jn,{fields:R===`browser`?V?.oauthFlows?.browserLoginFields??[]:V?.oauthFlows?.deviceLoginFields??[],values:ve,idPrefix:`flow-${R}`,onChange:(e,t)=>be(n=>({...n,[e]:t}))})]})}),pe&&V?.oauthFlows?.import===!0&&(0,Q.jsx)(Yn,{providerId:n,providerName:V.label||V.displayName,fields:V.oauthFlows.importFields,onClose:()=>he(!1)}),Me&&(0,Q.jsx)(Un,{providerId:n,authorizeUrl:Me.authorizeUrl,state:Me.state,popup:Me.popup,onClose:e=>{B.current=null,Pe(null),e&&x.invalidateQueries({queryKey:L.providers.accounts(n)})}})]})}export{vr as default};
@@ -1 +0,0 @@
1
- import{o as e,r as t,t as n}from"./jsx-runtime-CXUMngI_.js";var r=e(t(),1),i=n(),a=new Set,o={claude:{file:`claude-code`,ext:`svg`},anthropic:{file:`anthropics`,ext:`webp`},openai:{file:`openai-light`,ext:`svg`},codex:{file:`codex`,ext:`webp`},opencode:{file:`opencode`,ext:`webp`},"opencode-zen":{file:`opencode`,ext:`webp`},"opencode-go":{file:`opencode-go`,ext:`webp`},"google-antigravity":{file:`antigravity`,ext:`svg`},antigravity:{file:`antigravity`,ext:`svg`},blackbox:{file:`blackbox`,ext:`svg`},blackboxai:{file:`blackbox`,ext:`svg`},grok:{file:`grok-build`,ext:`webp`},"grok-build":{file:`grok-build`,ext:`webp`},xai:{file:`grok-build`,ext:`webp`},inferhub:{file:`inferhub`,ext:`svg`},gemini:{file:`gemini`,ext:`webp`},alibaba:{file:`alibaba`,ext:`svg`},alibabacp:{file:`alibaba`,ext:`svg`},dashscope:{file:`alibaba`,ext:`svg`},fireworks:{file:`fireworks`,ext:`webp`},exa:{file:`exa`,ext:`svg`},perplexity:{file:`perplexity`,ext:`webp`},tokenharbor:{file:`tokenharbor`,ext:`svg`},aihubmix:{file:`aihubmix`,ext:`svg`},zcode:{file:`zai-coding-plan`,ext:`svg`},"kimi-code":{file:`kimi-code`,ext:`webp`},kimi:{file:`kimi-code`,ext:`webp`},github:{file:`github`,ext:`webp`},copilot:{file:`copilot`,ext:`webp`},xiaomipg:{file:`mimo`,ext:`webp`},xiaomitp:{file:`mimo`,ext:`webp`},mimo:{file:`mimo`,ext:`webp`},cb:{file:`codebuddy`,ext:`webp`},cbcn:{file:`codebuddy`,ext:`webp`},workbuddy:{file:`codebuddy`,ext:`webp`},workbuddycn:{file:`codebuddy`,ext:`webp`},agentrouter:{file:`agentrouter`,ext:`svg`},parallel:{file:`parallel`,ext:`svg`},gmi:{file:`gmi-cloud`,ext:`svg`},hermes:{file:`hermes`,ext:`webp`},nous:{file:`nous-research`,ext:`svg`},bai:{file:`bai`,ext:`svg`},cline:{file:`cline`,ext:`webp`},cerebras:{file:`cerebras`,ext:`webp`},qoder:{file:`qoder`,ext:`webp`},qodercn:{file:`qoder`,ext:`webp`},mistral:{file:`mistral`,ext:`webp`},muse:{file:`muse`,ext:`svg`},meta:{file:`muse`,ext:`svg`},openrouter:{file:`openrouter`,ext:`webp`},ollama:{file:`ollama`,ext:`webp`},ollamacloud:{file:`ollama-cloud`,ext:`webp`},nvidia:{file:`nvidia`,ext:`webp`},deepseek:{file:`deepseek`,ext:`webp`},"deepseek-tui":{file:`deepseek-tui`,ext:`webp`},droid:{file:`droid`,ext:`webp`},jcode:{file:`jcode`,ext:`webp`},kilo:{file:`kilocode`,ext:`webp`},"kilo-gateway":{file:`kilocode-gateway`,ext:`webp`},openclaw:{file:`openclaw`,ext:`webp`},cowork:{file:`claude`,ext:`webp`},roo:{file:`roo`,ext:`webp`},continue:{file:`continue`,ext:`webp`},amp:{file:`amp`,ext:`webp`},qwen:{file:`qwen`,ext:`webp`},kiro:{file:`kiro`,ext:`webp`},kimchi:{file:`kimchi`,ext:`webp`},commandcode:{file:`commandcode`,ext:`webp`},cursor:{file:`cursor`,ext:`webp`},trae:{file:`trae`,ext:`webp`},traecn:{file:`trae`,ext:`webp`}};function s(e){let t=e.toLowerCase().trim();return o[t]??{file:t,ext:`webp`}}function c(e){let t=e.trim().split(/[\s-]+/).filter(Boolean);return t.length>=2?(t[0][0]+t[1][0]).toUpperCase():e.slice(0,2).toUpperCase()}var l=(0,r.memo)(function({icon:e,name:t,size:n=32,imageSize:o,style:l,className:u}){let[d,f]=(0,r.useState)(()=>a.has(e)),p=s(e),m=o??n;return(0,i.jsx)(`div`,{className:u,style:{width:`${n}px`,height:`${n}px`,borderRadius:`8px`,background:`var(--surface-2)`,display:`grid`,placeItems:`center`,flexShrink:0,overflow:`hidden`,border:`1px solid var(--inner-border)`,...l},role:`img`,"aria-label":`${t} provider`,children:d?(0,i.jsx)(`span`,{style:{fontSize:`${Math.max(10,Math.floor(n*.35))}px`,fontWeight:700,color:`var(--text-secondary)`},children:c(t)}):(0,i.jsx)(`img`,{src:`/assets/providers/${p.file}.${p.ext}`,alt:``,width:m,height:m,loading:`lazy`,decoding:`async`,style:{width:`${m}px`,height:`${m}px`,objectFit:`contain`,padding:p.ext===`svg`?`1px`:`2px`},onError:()=>{a.add(e),f(!0)}})})});export{l as t};
@@ -1 +0,0 @@
1
- import{o as e,r as t,t as n}from"./jsx-runtime-CXUMngI_.js";import{c as r,m as i}from"./numbers-Dulqgys5.js";import{t as a}from"./eye-off-Bk5g2luF.js";import{t as o}from"./eye-C_hawfH4.js";import{n as s,r as c,t as l}from"./state-DhZBfWgx.js";import{t as u}from"./dialog-Iec_ywbD.js";import{t as d}from"./plus-DIdX_g-x.js";import{t as f}from"./trash-Cppn5c3R.js";import{l as p}from"./query-keys-UETqfytp.js";import{t as m}from"./dialog-actions-B1axpEg7.js";import{Q as h,T as g,_,a as v,g as y,i as ee,it as b,lt as x,m as S,s as C,tt as w,w as te}from"./entry-DOddwoc0.js";import{n as T,r as E,t as D}from"./card-BOPBuBzD.js";import{t as O}from"./badge-Bkz_-RrM.js";import{n as k}from"./input-WlyHWeG2.js";import{t as A}from"./select-BfZ3SCTM.js";import{t as j}from"./ProviderIcon-CmfzxpVM.js";import{t as M}from"./switch-yD7D99Lg.js";import{t as N}from"./stack-B1w5BM0u.js";import{n as P}from"./inline-DToMICwl.js";import{t as ne}from"./list-row-B3oSK13z.js";import{t as F}from"./privacy-mode-GM8bej85.js";import{t as I}from"./AccountCooldown-Bjo92Qat.js";var L=e(t(),1),R=n();function re(e){let t={};for(let[n,r]of e)n.trim()&&(t[n.trim()]=r);return t}function ie({pairs:e,onChange:t}){let n=(n,r)=>t(e.map((e,t)=>t===n?r:e)),i=n=>t(e.filter((e,t)=>t!==n));return(0,R.jsxs)(`div`,{className:`form-group`,children:[(0,R.jsxs)(`label`,{className:`form-label block`,children:[(0,R.jsx)(`span`,{className:`block`,children:`Custom Headers`}),(0,R.jsx)(`span`,{className:`form-hint block mt-1`,children:`Optional — sent with every request, override built-in headers on a name collision`})]}),(0,R.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map(([e,t],a)=>(0,R.jsxs)(`div`,{className:`flex min-w-0 gap-3`,children:[(0,R.jsx)(k,{placeholder:`Header-Name`,value:e,onChange:e=>n(a,[e.target.value,t]),className:`font-mono tabular-nums min-w-0 flex-1 text-caption`}),(0,R.jsx)(k,{placeholder:`value`,value:t,onChange:t=>n(a,[e,t.target.value]),className:`font-mono tabular-nums min-w-0 flex-1 text-caption`}),(0,R.jsx)(r,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Remove ${e||`header`}`,onClick:()=>i(a),children:(0,R.jsx)(f,{size:13})})]},a)),(0,R.jsxs)(r,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>t([...e,[``,``]]),children:[(0,R.jsx)(d,{size:13}),` Add header`]})]})]})}function z({children:e}){return(0,R.jsx)(`div`,{className:`provider-grid grid gap-6 w-full min-w-0`,children:e})}var B=i(`relative flex flex-col min-w-0 border border-inner-border rounded-card`,`transition-[transform,border-color,box-shadow]`),V=i(`block flex-1 p-6 no-underline text-inherit`),H=i(`text-body font-semibold overflow-hidden text-ellipsis whitespace-nowrap`);function U(e){let t=e.serviceKinds;return Array.isArray(t)&&t.length>0?t:[`llm`]}var W=/\/(?:v\d+\/)?(?:messages|chat\/completions|responses|completions|embeddings|images\/generations)$/;function ae(e){let t=e.trim().replace(/\/+$/,``);if(t===``)return null;let n,r;try{n=new URL(t),r=n.pathname.replace(/\/+$/,``)}catch{return null}return W.test(r)?n.origin:null}function G({variant:e,open:t,onClose:n}){let a=ee(),o=v(),s=te(),c=g(),[l,d]=(0,L.useState)(``),[f,m]=(0,L.useState)(``),[h,_]=(0,L.useState)(``),[y,b]=(0,L.useState)(``),[x,S]=(0,L.useState)(!1),[C,w]=(0,L.useState)(!0),[T,E]=(0,L.useState)([]),[D,O]=(0,L.useState)(null),[j,N]=(0,L.useState)(!1),[F,I]=(0,L.useState)(null),[z,B]=(0,L.useState)(!1),V=e===`anthropic-compatible`,H=V?`messages`:`chat`,[U,W]=(0,L.useState)(H),G=(0,L.useMemo)(()=>ae(h),[h]);(0,L.useEffect)(()=>{t&&(d(``),b(``),W(H),_(``),S(!1),w(!0),E([]),O(null),I(null))},[t]);let K=async e=>{try{let t=await navigator.clipboard.readText();t.trim()&&e(t.trim())}catch{O(`Clipboard access denied — paste manually instead.`)}},q=async()=>{if(!h.trim()){I({ok:!1,message:`Base URL is required to test the connection.`});return}B(!0),I(null),O(null);try{let e=re(T),t=await c.mutateAsync({baseUrl:h.trim(),apiKey:y.trim(),wireFamily:U,cliIdentity:C,...Object.keys(e).length>0?{extraHeaders:e}:{}});if(t.ok){let e=typeof t.modelCount==`number`?` — upstream advertised ${t.modelCount} model(s)`:``;I({ok:!0,message:`Connected successfully (${t.latencyMs}ms)${e}.`,...t.warning===void 0?{}:{warning:t.warning}})}else I({ok:!1,message:t.error??`Connection failed.`,...t.warning===void 0?{}:{warning:t.warning}})}catch(e){I({ok:!1,message:p(e,`Connection test failed`)})}finally{B(!1)}};return(0,R.jsx)(u,{open:t,onClose:n,title:V?`Add Custom Anthropic Provider`:`Add Custom OpenAI Provider`,footer:(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(r,{variant:`secondary`,type:`button`,onClick:n,children:`Cancel`}),(0,R.jsx)(r,{variant:`primary`,type:`submit`,form:`add-compatible-provider`,disabled:j,children:j?`Creating...`:`Add Provider`})]}),children:(0,R.jsxs)(`form`,{id:`add-compatible-provider`,onSubmit:async e=>{if(e.preventDefault(),!l.trim()){O(`Display Name is required`);return}if(!f.trim()){O(`Provider ID (slug) is required`);return}if(!h.trim()){O(`Base URL is required`);return}let t=re(T),r=f.trim().toLowerCase();N(!0),O(null);try{let e={providerId:r,label:l.trim(),baseUrl:h.trim(),wireFamily:U,compatibilityProfile:{cli_identity:C,...Object.keys(t).length>0?{extra_headers:t}:{}}};await a.mutateAsync(e),y.trim()&&await o.mutateAsync({providerId:r,request:{credentialKind:`api_key`,secret:y.trim()}}),x&&await s.mutateAsync(r),n()}catch(e){O(p(e,`Failed to create provider`))}finally{N(!1)}},className:`flex flex-col gap-6`,children:[D?(0,R.jsx)(`div`,{className:`text-red text-caption`,children:D}):null,(0,R.jsx)(k,{label:`Display Name`,hint:`Required. A friendly label for this node.`,id:`compat-label`,value:l,onChange:e=>d(e.target.value),placeholder:V?`Anthropic Compatible (Prod)`:`OpenAI Compatible (Prod)`,required:!0}),(0,R.jsx)(k,{label:`Provider ID / Slug`,hint:`Required. Used as the provider prefix for model IDs.`,id:`compat-slug`,value:f,onChange:e=>m(e.target.value),placeholder:V?`ac-prod`:`oc-prod`,required:!0}),(0,R.jsxs)(`div`,{className:`form-group`,children:[(0,R.jsxs)(`label`,{className:`form-label`,htmlFor:`compat-url`,children:[(0,R.jsx)(`span`,{children:`Base URL`}),(0,R.jsxs)(`span`,{className:`form-hint`,children:[`The root only. Do not paste the full endpoint — leave off`,V?" `/v1/messages`.":" `/chat/completions`."]})]}),(0,R.jsxs)(P,{gap:`8px`,children:[(0,R.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,R.jsx)(k,{id:`compat-url`,value:h,onChange:e=>_(e.target.value),placeholder:V?`https://api.anthropic.com/v1`:`https://api.openai.com/v1`,required:!0})}),(0,R.jsx)(r,{type:`button`,variant:`secondary`,onClick:()=>K(_),children:`Paste`})]}),G===null?null:(0,R.jsxs)(`p`,{className:`mt-1.5 text-caption text-orange`,children:[`That looks like a full endpoint. Use`,` `,(0,R.jsx)(`code`,{className:`font-mono`,children:G}),` instead — Cartethyia appends the endpoint path itself.`]})]}),V?null:(0,R.jsx)(A,{id:`compat-wire`,label:`API format`,value:U,onValueChange:e=>W(e),options:[{value:`chat`,label:`Chat completions`},{value:`responses`,label:`Responses`}]}),(0,R.jsxs)(`div`,{className:`form-group`,children:[(0,R.jsxs)(`label`,{className:`form-label`,htmlFor:`compat-credential`,children:[(0,R.jsx)(`span`,{children:`API Key`}),(0,R.jsx)(`span`,{className:`form-hint`,children:`Optional — saved with this provider and used to authenticate every request.`})]}),(0,R.jsxs)(P,{gap:`8px`,children:[(0,R.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,R.jsx)(k,{id:`compat-credential`,type:`password`,placeholder:`sk-...`,value:y,onChange:e=>b(e.target.value)})}),(0,R.jsx)(r,{type:`button`,variant:`secondary`,disabled:z,onClick:()=>void q(),children:z?`Testing...`:`Test connection`}),(0,R.jsx)(r,{type:`button`,variant:`secondary`,onClick:()=>K(b),children:`Paste`})]}),F?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:i(`mt-3 text-caption leading-[1.4] break-words`,F.ok?`text-green`:`text-red`),children:[F.ok?`✓ `:`✗ `,F.message]}),F.warning?(0,R.jsxs)(`div`,{className:`mt-2 text-caption leading-snug break-words text-orange`,children:[`⚠ `,F.warning]}):null]}):null]}),(0,R.jsx)(ne,{actions:(0,R.jsx)(M,{checked:x,onChange:S,id:`compat-autofetch`}),children:(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-body font-semibold`,children:`Auto-fetch models`}),(0,R.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Discover this provider's model list automatically after creation`})]})}),(0,R.jsx)(ne,{actions:(0,R.jsx)(M,{checked:C,onChange:w,id:`compat-cli-identity`}),children:(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`div`,{className:`text-body font-semibold`,children:V?`Send request as Claude CLI`:`Send request as Codex CLI`}),(0,R.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:V?`Emits official Claude CLI User-Agent and Stainless headers to upstream`:`Emits official codex_cli_rs User-Agent and originator headers to upstream`})]})}),(0,R.jsx)(ie,{pairs:T,onChange:E})]})})}function K({customProvider:e}){let t=C(),[n,a]=(0,L.useState)(!1),o=y(e.providerId),s=o.data?.length,c=S(e.providerId),l=c.data,d=Q(l??[]);return(0,R.jsxs)(D,{className:B,children:[(0,R.jsx)(ce,{clientVersion:e.clientVersion}),(0,R.jsx)(h,{to:`/providers/${encodeURIComponent(e.providerId)}`,className:i(V,`pr-20 min-h-38`),children:(0,R.jsxs)(P,{gap:`10px`,children:[(0,R.jsx)(j,{icon:e.wireFamilyDefault===`messages`?`anthropic`:`openai`,name:e.label||e.providerId,size:32,imageSize:24}),(0,R.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,R.jsx)(`div`,{className:H,children:e.label||e.providerId}),e.baseUrl?(0,R.jsxs)(`div`,{className:`mt-1 min-w-0 truncate font-mono text-micro text-text-tertiary`,title:e.baseUrl,children:[(0,R.jsx)(`span`,{className:`font-semibold text-text-secondary`,children:`Base URL`}),` `,e.baseUrl]}):null,(0,R.jsxs)(`div`,{className:`mt-1.5 flex flex-wrap gap-2`,children:[l===void 0?(0,R.jsx)($,{kind:`accounts`,isPending:c.isPending,isError:c.isError,hasData:!1}):l.length===0?e.requiresAccount===!1?(0,R.jsx)(O,{tone:`ok`,children:`Free Endpoint`}):(0,R.jsx)(O,{children:`No connections`}):(0,R.jsx)(se,{counts:d,total:l.length}),c.isError&&l!==void 0?(0,R.jsx)(O,{tone:`warn`,children:`Connections unavailable`}):null]})]}),(0,R.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5 shrink-0`,children:[(0,R.jsxs)(`span`,{className:`font-mono tabular-nums text-micro font-semibold bg-kbd-bg px-2.5 py-0.5 rounded-chip text-text-secondary`,children:[e.providerId,`/`]}),s!==void 0&&s>0?(0,R.jsxs)(O,{tone:`info`,children:[s,` models`]}):null,o.isError?(0,R.jsx)(O,{tone:`warn`,children:`Models unavailable`}):s===void 0?(0,R.jsx)($,{kind:`models`,isPending:o.isPending,isError:!1,hasData:!1}):s===0?(0,R.jsx)($,{kind:`models`,isPending:!1,isError:!1,hasData:!0,isEmpty:!0}):null]})]})}),(0,R.jsx)(r,{variant:`ghost`,size:`sm`,icon:(0,R.jsx)(f,{size:12}),onClick:()=>a(!0),className:`absolute top-2 right-2 p-2 text-text-tertiary`,title:`Delete ${e.label||e.providerId}`}),(0,R.jsx)(u,{open:n,onClose:()=>a(!1),title:`Delete Custom Provider`,children:(0,R.jsxs)(N,{gap:`12px`,children:[(0,R.jsxs)(`p`,{className:`text-body text-text-secondary`,children:[`Are you sure you want to delete custom provider`,` `,(0,R.jsx)(`strong`,{children:e.label||e.providerId}),`? Its models, accounts, and routing preferences are deleted together, and requests to this provider will no longer route.`]}),t.isError?(0,R.jsx)(`p`,{className:`text-caption text-red`,children:p(t.error,`Delete failed`)}):null,(0,R.jsxs)(m,{children:[(0,R.jsx)(r,{variant:`secondary`,onClick:()=>a(!1),children:`Cancel`}),(0,R.jsx)(r,{variant:`danger`,onClick:()=>{t.mutate(e.providerId,{onSuccess:()=>a(!1),onError:()=>void 0})},disabled:t.isPending,children:t.isPending?`Deleting...`:`Delete Provider`})]})]})})]})}function q({customProviders:e}){let[t,n]=(0,L.useState)(!1),[i,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(()=>{try{return window.localStorage.getItem(`cartethyia.customProvidersHidden`)===`1`}catch{return!1}});function u(){l(e=>{let t=!e;try{window.localStorage.setItem(`cartethyia.customProvidersHidden`,t?`1`:`0`)}catch{}return t})}return(0,R.jsxs)(`section`,{className:`flex flex-col gap-5`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-4`,children:[(0,R.jsxs)(`button`,{type:`button`,onClick:u,"aria-expanded":!c,title:c?`Show custom providers`:`Hide custom providers`,className:`inline-flex items-center gap-3 bg-transparent border-none p-0 cursor-pointer text-inherit`,children:[(0,R.jsxs)(`h2`,{className:`text-body-lg font-bold tracking-[-0.01em]`,children:[`Custom Providers`,e.length>0?` (${e.length})`:``]}),(0,R.jsx)(x,{size:14,className:`text-text-tertiary transition-transform`,style:{transform:c?`rotate(-90deg)`:void 0}})]}),(0,R.jsxs)(P,{gap:`8px`,children:[(0,R.jsx)(r,{size:`sm`,variant:`ghost`,icon:c?(0,R.jsx)(o,{size:13}):(0,R.jsx)(a,{size:13}),onClick:u,title:c?`Show custom providers`:`Hide custom providers`,children:c?`Show`:`Hide`}),(0,R.jsx)(r,{size:`sm`,variant:`secondary`,icon:(0,R.jsx)(d,{size:13}),onClick:()=>n(!0),children:`Custom Anthropic`}),(0,R.jsx)(r,{size:`sm`,variant:`secondary`,icon:(0,R.jsx)(d,{size:13}),onClick:()=>s(!0),children:`Custom OpenAI`})]})]}),c?null:e.length===0?(0,R.jsx)(D,{children:(0,R.jsxs)(T,{className:`text-center px-7 py-10 border border-dashed border-inner-border rounded-card`,children:[(0,R.jsx)(`p`,{className:`text-body font-semibold text-text-primary`,children:`No custom providers yet`}),(0,R.jsx)(`p`,{className:`text-badge text-text-tertiary mt-1`,children:`Add an OpenAI- or Anthropic-compatible endpoint with the buttons above.`})]})}):(0,R.jsx)(z,{children:e.map(e=>(0,R.jsx)(K,{customProvider:e},e.providerId))}),(0,R.jsx)(G,{variant:`anthropic-compatible`,open:t,onClose:()=>n(!1)}),(0,R.jsx)(G,{variant:`openai-compatible`,open:i,onClose:()=>s(!1)})]})}var J=new Set([`inferhub`]),Y=new Set([`grok`,`opencode`,`cline`,`hermes`,`kilo`]),oe=new Set([`anthropic`,`openai`,`gemini`,`alibabacp`,`ollamacloud`,`opencode-zen`,`opencode-go`,`mistral`,`meta`,`deepseek`,`commandcode`,`dashscope`]);function X(e){return e.oauthFlows?.browser===!0||e.oauthFlows?.device===!0}function Z(e){return e.oauthFlows?.refreshable===!0}function Q(e){let t=e=>e.status===`cooldown`||I(e)!==void 0;return{healthy:e.filter(e=>e.status===`active`&&!t(e)).length,throttled:e.filter(t).length,disabled:e.filter(e=>e.status===`disabled`).length,cooling:e.filter(e=>e.status!==`cooldown`&&I(e)!==void 0).length}}function se({counts:e,total:t}){if(!(e.healthy>0||e.throttled>0||e.disabled>0))return(0,R.jsxs)(O,{tone:`warn`,dot:!0,children:[t,` Connected`]});let n=e.throttled===e.cooling?`Cooling`:`Cooldown`;return(0,R.jsxs)(R.Fragment,{children:[e.healthy>0?(0,R.jsxs)(O,{tone:`ok`,dot:!0,children:[e.healthy,` Healthy`]}):null,e.throttled>0?(0,R.jsxs)(O,{tone:`warn`,dot:!0,children:[e.throttled,` `,n]}):null,e.disabled>0?(0,R.jsxs)(O,{tone:`warn`,dot:!0,children:[e.disabled,` Unhealthy`]}):null]})}function $({kind:e,isPending:t,isError:n,hasData:r,isEmpty:i=!1}){let a=e===`models`?`Models`:`Connections`;return n?(0,R.jsxs)(O,{tone:`warn`,children:[a,` unavailable`]}):t&&!r?(0,R.jsxs)(O,{tone:`info`,children:[`Loading `,a.toLowerCase(),`…`]}):i?(0,R.jsx)(O,{children:e===`models`?`No models`:`No connections`}):null}function ce({clientVersion:e}){return e?(0,R.jsxs)(O,{className:`provider-version-badge absolute -top-4.5 left-5 right-auto z-chip max-w-[calc(100%-var(--spacing)*10)] truncate px-3 py-1 text-micro leading-[1.15] shadow-card max-small:left-4 max-small:max-w-[calc(100%-var(--spacing)*8)]`,tone:e.source===`latest`?`teal`:`default`,title:e.source===`latest`?`Latest discovered client version`:`Pinned fallback; background discovery has not succeeded yet`,children:[`v`,e.version,` · `,e.source]}):null}var le=(0,L.memo)(function({provider:e,serviceKind:t}){let n=J.has(e.providerId.toLowerCase()),r=e.label||e.displayName,a=y(e.providerId),o=a.data?.filter(e=>t===void 0||e.serviceKind===t||t===`llm`&&e.serviceKind===void 0).length,s=S(e.providerId),c=s.data,l=Q(c??[]);return(0,R.jsxs)(D,{className:B,children:[(0,R.jsx)(ce,{clientVersion:e.clientVersion}),n?(0,R.jsx)(`span`,{"aria-label":`Friend sponsor`,title:`Friend sponsor`,className:`absolute top-0 right-0 z-2 w-36 h-36 overflow-hidden pointer-events-none`,children:(0,R.jsx)(`span`,{className:i(`absolute top-9 -right-11 w-38 py-1 rotate-45 bg-accent-soft`,`text-accent text-micro font-extrabold tracking-tight leading-[1.05]`,`text-center uppercase shadow-ribbon`),children:`Friend`})}):null,(0,R.jsx)(h,{to:`/providers/${encodeURIComponent(e.providerId)}${t===void 0?``:`?service=${t}`}`,className:V,children:(0,R.jsxs)(P,{gap:`10px`,children:[(0,R.jsx)(j,{icon:e.providerId,name:r,size:32,imageSize:24}),(0,R.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,R.jsx)(`div`,{className:H,children:r}),(0,R.jsxs)(`div`,{className:`mt-1.5 flex flex-wrap gap-2`,children:[c===void 0?(0,R.jsx)($,{kind:`accounts`,isPending:s.isPending,isError:s.isError,hasData:!1}):c.length===0?e.requiresAccount===!1?(0,R.jsx)(O,{tone:`ok`,children:`Free Endpoint`}):(0,R.jsx)(O,{children:`No connections`}):(0,R.jsx)(se,{counts:l,total:c.length}),s.isError&&c!==void 0?(0,R.jsx)(O,{tone:`warn`,children:`Connections unavailable`}):null]})]}),(0,R.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5 shrink-0`,children:[(0,R.jsxs)(`span`,{className:`font-mono tabular-nums text-micro font-semibold bg-kbd-bg px-2.5 py-0.5 rounded-chip text-text-secondary`,children:[e.providerId,`/`]}),o!==void 0&&o>0?(0,R.jsxs)(O,{tone:`info`,children:[o,` models`]}):null,a.isError?(0,R.jsx)(O,{tone:`warn`,children:`Models unavailable`}):o===void 0?(0,R.jsx)($,{kind:`models`,isPending:a.isPending,isError:!1,hasData:!1}):o===0?(0,R.jsx)($,{kind:`models`,isPending:!1,isError:!1,hasData:!0,isEmpty:!0}):null]})]})})]})});function ue(e,t){let n=Number(!!t.configured)-Number(!!e.configured);return n===0?(e.label||e.displayName).localeCompare(t.label||t.displayName):n}var de=`cartethyia.providerSectionsCollapsed`;function fe(){try{let e=window.localStorage.getItem(de),t=e?JSON.parse(e):[];return new Set(Array.isArray(t)?t.filter(e=>typeof e==`string`):[])}catch{return new Set}}var pe=`text-body font-bold tracking-[-0.01em]`,me=[{title:`Founding Friend & Sponsors`,subtitle:`Super Cheap inference pool`,filter:e=>J.has(e.providerId.toLowerCase())},{title:`Free Limited Providers`,filter:e=>Y.has(e.providerId.toLowerCase())},{title:`OAuth & Agent Providers`,filter:e=>(X(e)||Z(e))&&!Y.has(e.providerId.toLowerCase())},{title:`Well Known API Key Providers`,subtitle:`The household names — sign up with a key and go`,filter:e=>e.isBuiltIn&&oe.has(e.providerId.toLowerCase())&&!J.has(e.providerId.toLowerCase())&&!Y.has(e.providerId.toLowerCase())&&!X(e)&&!Z(e)},{title:`Other API Key Providers`,subtitle:`Free tier friendly — no credit card`,filter:e=>e.isBuiltIn&&!oe.has(e.providerId.toLowerCase())&&!J.has(e.providerId.toLowerCase())&&!Y.has(e.providerId.toLowerCase())&&!X(e)&&!Z(e)}];function he(){let[e,t]=(0,L.useState)(fe),n=_(),u=F(),d=u.enabled,f=e=>!d||e.configured===!0||e.requiresAccount===!1,m=(0,L.useMemo)(()=>n.data??[],[n.data]),h=(0,L.useMemo)(()=>[...m.filter(e=>!e.isBuiltIn&&f(e))].sort(ue),[m,d]),g=(0,L.useMemo)(()=>m.filter(e=>U(e).includes(`websearch`)&&f(e)),[m,d]),v=(0,L.useMemo)(()=>m.filter(e=>U(e).includes(`llm`)&&f(e)),[m,d]),[y,ee]=w(),S=y.get(`tab`),C=S===`search`||S===`media`?S:`llm`,te=e=>{ee(t=>{let n=new URLSearchParams(t);return e===`llm`?n.delete(`tab`):n.set(`tab`,e),n})},O=(0,L.useMemo)(()=>m.filter(e=>(U(e).includes(`imageGeneration`)||U(e).includes(`videoGeneration`))&&f(e)),[m,d]),k=(0,L.useMemo)(()=>[...g].sort((e,t)=>(e.label||e.displayName).localeCompare(t.label||t.displayName)),[g]),A=(e,t)=>{let n=Number(!!t.configured)-Number(!!e.configured);return n===0?(e.label||e.displayName).localeCompare(t.label||t.displayName):n},j=(0,L.useMemo)(()=>{if(C===`media`)return[{title:`Media Generation`,subtitle:`Providers that can return an image or a video`,providers:O}].filter(e=>e.providers.length>0);if(C===`search`)return[{title:`Search Providers`,subtitle:`Providers that can answer a web search request`,providers:k}].filter(e=>e.providers.length>0);let e=v;return me.map(t=>({...t,providers:e.filter(t.filter).sort(A)})).filter(e=>e.providers.length>0)},[v,k,O,C]),M=n.isPending&&!n.data?(0,R.jsx)(c,{label:`Loading providers...`}):n.isError?(0,R.jsx)(s,{message:p(n.error,`Failed to load providers`),onRetry:()=>n.refetch()}):null;return M?(0,R.jsxs)(D,{children:[(0,R.jsx)(E,{title:`Providers`,icon:(0,R.jsx)(b,{size:16})}),(0,R.jsx)(T,{className:`flex flex-1`,children:M})]}):(0,R.jsx)(N,{gap:`24px`,children:(0,R.jsxs)(D,{children:[(0,R.jsx)(E,{title:`Providers`,subtitle:`Connected pinned first · A–Z`,icon:(0,R.jsx)(b,{size:16})}),(0,R.jsxs)(T,{className:`flex flex-col gap-8`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,R.jsx)(`div`,{className:`flex gap-2`,children:[`llm`,`search`,`media`].map(e=>(0,R.jsxs)(`button`,{onClick:()=>te(e),className:i(`px-6 py-3 rounded-inset text-caption font-semibold border cursor-pointer`,C===e?`border-accent bg-accent-soft text-accent`:`border-inner-border bg-surface-1 text-text-secondary`),children:[e===`llm`?`LLM`:e===`search`?`Search`:`Media`,e===`search`?` (${g.length})`:e===`media`?` (${O.length})`:` (${v.length})`]},e))}),(0,R.jsx)(r,{variant:`ghost`,size:`sm`,icon:d?(0,R.jsx)(a,{size:12}):(0,R.jsx)(o,{size:12}),onClick:()=>u.setEnabled(!d),title:d?`Show providers that have no account yet`:`Hide providers that have no account yet`,children:d?`Show unconfigured`:`Hide unconfigured`}),(0,R.jsx)(`span`,{className:`ml-auto text-micro text-text-tertiary`,children:C===`search`?`Fallback runs only when the model invokes Websearch`:C===`media`?`Image and video generation`:`Connected pinned first · A–Z`})]}),C===`llm`?(0,R.jsx)(q,{customProviders:h}):null,j.length===0?(0,R.jsx)(D,{children:(0,R.jsx)(T,{children:(0,R.jsx)(l,{title:`No providers found`,message:`No providers available.`})})}):j.map(n=>{let r=e.has(n.title);return(0,R.jsxs)(`section`,{className:`flex flex-col gap-6`,children:[(0,R.jsxs)(`button`,{type:`button`,className:`flex items-start gap-4 border-0 bg-transparent p-0 text-left text-inherit`,"aria-expanded":!r,onClick:()=>t(e=>{let t=new Set(e);t.has(n.title)?t.delete(n.title):t.add(n.title);try{window.localStorage.setItem(de,JSON.stringify([...t]))}catch{}return t}),children:[(0,R.jsx)(x,{size:15,className:i(`mt-1 shrink-0 transition-transform`,r&&`-rotate-90`)}),(0,R.jsxs)(N,{gap:`1px`,children:[(0,R.jsxs)(`h2`,{className:pe,children:[n.title,` (`,n.providers.length,`)`,r?` (Hidden)`:``]}),!r&&n.subtitle?(0,R.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:n.subtitle}):null]})]}),r?null:(0,R.jsx)(z,{children:n.providers.map(e=>(0,R.jsx)(le,{provider:e,serviceKind:C===`search`?`websearch`:C===`media`?U(e).includes(`imageGeneration`)?`imageGeneration`:`videoGeneration`:`llm`},e.providerId))})]},n.title)})]})]})})}export{he as default,Q as summarizeAccounts};
@@ -1,7 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-0_IjPWTk.js";import{T as a,c as o,s,t as c,v as l,w as u,x as d}from"./numbers-Dulqgys5.js";import{t as f}from"./eye-off-Bk5g2luF.js";import{t as p}from"./eye-C_hawfH4.js";import{t as m}from"./gauge-BbIMy7MB.js";import{n as h,r as g,t as _}from"./state-DhZBfWgx.js";import{t as v}from"./dialog-Iec_ywbD.js";import{t as y}from"./pencil-768ysRAr.js";import{t as ee}from"./plus-DIdX_g-x.js";import{t as b}from"./power-off-Yjw9GMJh.js";import{t as x}from"./rotate-ccw-CufcqITi.js";import{t as S}from"./shield-check-DVS0Foqh.js";import{t as C}from"./trash-Cppn5c3R.js";import{C as w,T,c as E,v as D,y as O}from"./assert-DU6qrMA_.js";import{a as k,i as A,l as j,o as M,t as N}from"./query-keys-UETqfytp.js";import{t as P}from"./useMutation-EDFRkn1i.js";import{it as te,z as ne}from"./entry-DOddwoc0.js";import{n as re,r as ie,t as ae}from"./card-BOPBuBzD.js";import{n as oe}from"./download-dRFo5_Wu.js";import{t as F}from"./badge-Bkz_-RrM.js";import{n as I}from"./input-WlyHWeG2.js";import{t as se}from"./select-BfZ3SCTM.js";import{t as L}from"./switch-yD7D99Lg.js";import{t as ce}from"./stack-B1w5BM0u.js";import{n as le}from"./inline-DToMICwl.js";import{r as R,t as ue}from"./layout-DaJ5baJr.js";import{i as de,n as fe}from"./privacy-mode-GM8bej85.js";import{n as z}from"./live-ta6GMb-8.js";var pe=e(`cloud`,[[`path`,{d:`M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z`,key:`p7xjir`}]]),me=e(`power`,[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]),he=1e6,B=1e8,ge=5e6,_e=`sin1`,ve=[{label:`Asia Pacific`,regions:[{id:`sin1`,label:`Singapore`},{id:`hkg1`,label:`Hong Kong`},{id:`icn1`,label:`Seoul`},{id:`hnd1`,label:`Tokyo`},{id:`kix1`,label:`Osaka`},{id:`bom1`,label:`Mumbai`},{id:`syd1`,label:`Sydney`}]},{label:`Europe`,regions:[{id:`fra1`,label:`Frankfurt`},{id:`cdg1`,label:`Paris`},{id:`lhr1`,label:`London`},{id:`arn1`,label:`Stockholm`},{id:`dub1`,label:`Dublin`}]},{label:`North America`,regions:[{id:`iad1`,label:`Washington, D.C.`},{id:`sfo1`,label:`San Francisco`},{id:`pdx1`,label:`Portland`},{id:`cle1`,label:`Cleveland`},{id:`yul1`,label:`Montréal`}]},{label:`Other`,regions:[{id:`gru1`,label:`São Paulo`},{id:`cpt1`,label:`Cape Town`},{id:`dxb1`,label:`Dubai`}]}];function ye(){return w({queryKey:N.network.pools,queryFn:e=>M(`/network/pools`,{signal:D(e)}).then(E),staleTime:A.staleTime,gcTime:A.gcTime})}function be(){let e=T();return P({mutationFn:e=>M(`/network/pools`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool created`)},onError:e=>{s.error(`Could not create the proxy pool.`,j(e))}})}function xe(){let e=T();return P({mutationFn:e=>M(`/network/pools/relay/deploy`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Se(){return P({mutationFn:e=>M(`/network/pools/test-batch`,{method:`POST`,body:JSON.stringify({targets:e})})})}function Ce(){let e=T();return P({mutationFn:({poolId:e,request:t})=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify(t)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy updated`)},onError:e=>{s.error(`Could not update the proxy pool.`,j(e))}})}function we(e){return w({queryKey:[...N.network.pools,e,`health-events`],queryFn:t=>M(`/network/pools/${encodeURIComponent(e??``)}/health-events`,{signal:D(t)}),enabled:!!e,...A,refetchInterval:k.status})}function Te(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/recover`,{method:`POST`,body:`{}`}),onSuccess:async(t,n)=>{await Promise.all([e.invalidateQueries({queryKey:N.network.pools}),e.invalidateQueries({queryKey:[...N.network.pools,n,`health-events`]})]),s.success(`Proxy pool recovered`)},onError:e=>{s.error(`Could not recover the proxy pool.`,j(e))}})}function Ee(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}`,{method:`DELETE`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Proxy pool deleted`)},onError:e=>{s.error(`Could not delete the proxy pool.`,j(e))}})}function De(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/provider-probe`,{method:`POST`,body:JSON.stringify({providerId:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function Oe(){return P({mutationFn:({providerId:e,targets:t})=>M(`/network/pools/test-batch/provider`,{method:`POST`,body:JSON.stringify({providerId:e,targets:t})})})}function ke(){let e=T();return P({mutationFn:e=>M(`/network/pools/${encodeURIComponent(e)}/health-check`,{method:`POST`,body:`{}`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Health check complete`)},onError:e=>{s.error(`Health check failed.`,j(e))}})}function Ae(){let e=T();return P({mutationFn:({poolId:e,bytes:t})=>M(`/network/pools/${encodeURIComponent(e)}/speed-test`,{method:`POST`,body:JSON.stringify({bytes:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools})}})}function je(){let e=T();return P({mutationFn:({poolId:e,providerId:t})=>M(`/network/pools/${encodeURIComponent(e)}/cooldowns/clear`,{method:`POST`,body:JSON.stringify(t?{providerId:t}:{})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:N.network.pools}),s.success(`Provider cooldowns cleared`)},onError:e=>{s.error(`Could not clear provider cooldowns.`,j(e))}})}var V=t(n(),1),H=r(),U={cloudflare:{label:`Cloudflare Workers`,tokenLabel:`Cloudflare API token`,needsAccount:!0,host:`*.workers.dev`,hasRegion:!1},vercel:{label:`Vercel`,tokenLabel:`Vercel API token`,needsAccount:!1,host:`*.vercel.app`,hasRegion:!0},deno:{label:`Deno Deploy`,tokenLabel:`Deno Deploy token`,needsAccount:!1,host:`*.deno.dev`,hasRegion:!1}},Me=ve.flatMap(e=>e.regions.map(t=>({value:t.id,label:`${e.label} — ${t.label}`})));function Ne({onClose:e}){let t=xe(),[n,r]=(0,V.useState)(`cloudflare`),[i,a]=(0,V.useState)(_e),[c,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),_=U[n],y=c.trim().length>0&&(!_.needsAccount||d.trim().length>0);return(0,H.jsx)(v,{open:!0,onClose:e,title:`Deploy Relay`,description:`Run outbound traffic through a hosted relay (Cloudflare, Vercel, Deno).`,size:`md`,children:(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsxs)(`p`,{className:`text-badge text-text-tertiary m-0 flex gap-3`,children:[(0,H.jsx)(te,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsxs)(`span`,{children:[`Deploys a small relay worker to your own `,_.label,` account and registers its URL (`,(0,H.jsx)(`code`,{children:_.host}),`) as an active HTTP pool. Your API token is used only for the deploy and is never stored.`]})]}),(0,H.jsx)(se,{label:`Relay host`,id:`relay-target`,value:n,onValueChange:e=>r(e),options:O.map(e=>({value:e,label:U[e].label}))}),(0,H.jsx)(I,{label:_.tokenLabel,id:`relay-token`,type:`password`,value:c,placeholder:`Paste a deploy token`,onChange:e=>u(e.target.value)}),_.needsAccount?(0,H.jsx)(I,{label:`Account ID`,id:`relay-account`,value:d,placeholder:`Cloudflare account id`,onChange:e=>f(e.target.value)}):null,(0,H.jsx)(I,{label:`Project name (optional)`,id:`relay-project`,value:p,placeholder:`e.g. cartethyia-relay`,onChange:e=>m(e.target.value)}),_.hasRegion?(0,H.jsx)(se,{label:`Deploy region`,id:`relay-region`,value:i,onValueChange:e=>a(e),options:Me}):null,_.hasRegion?(0,H.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`Sets the region on the Vercel project, which is what decides the country outbound traffic leaves from. A region sent on the deployment alone is accepted but does not move the Function.`}):null,(0,H.jsxs)(`div`,{className:`flex items-center gap-5`,children:[(0,H.jsx)(o,{variant:`primary`,size:`sm`,onClick:()=>{y&&t.mutate({target:n,token:c.trim(),..._.needsAccount&&d.trim()?{accountId:d.trim()}:{},...p.trim()?{projectName:p.trim()}:{},..._.hasRegion?{region:i}:{}},{onSuccess:e=>{g(e.relayUrl),u(``),s.success(`Relay deployed to ${e.relayUrl} and registered as a pool.`)},onError:e=>s.error(j(e,`Relay deploy failed.`))})},disabled:!y||t.isPending,children:t.isPending?`Deploying…`:`Deploy relay`}),h?(0,H.jsxs)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Registered pool at `,(0,H.jsx)(`code`,{children:h})]}):null]}),t.isError?(0,H.jsxs)(`p`,{className:`text-badge text-red m-0 flex gap-3`,children:[(0,H.jsx)(l,{size:13,className:`shrink-0 mt-0.5`}),(0,H.jsx)(`span`,{children:j(t.error,`Relay deploy failed.`)})]}):null]})})}function Pe(e,t){if(e!==void 0)return e.endpoint===``||e.endpoint===(t??``)?e.result:void 0}function Fe(e,t,n){switch(t){case`name`:return(e.label||e.endpoint).toLowerCase();case`family`:return e.family===void 0||e.family===null||e.family===``?null:e.family.toLowerCase();case`address`:return e.egressIp??null;case`load`:return n??null}}function Ie(e,t,n,r){let i=n===`asc`?1:-1;return[...e].sort((e,n)=>{let a=Fe(e,t,r(e)),o=Fe(n,t,r(n));return a===null&&o===null?0:a===null?1:o===null?-1:typeof a==`number`&&typeof o==`number`?(a-o)*i:String(a).localeCompare(String(o))*i})}function W(e,t){let n=e.filter(e=>e.status===`active`),r=n.reduce((e,t)=>e+t.maxInflight,0),i=t===void 0?n.reduce((e,t)=>e+(t.inflight??0),0):n.reduce((e,n)=>e+(t.get(n.id)??0),0),a=0,o=0;for(let e of n)(t===void 0?e.inflight??0:t.get(e.id)??0)>=e.maxInflight?o+=1:a+=1;let s=null,c=Date.now(),l=e=>{if(!e)return;let t=Date.parse(e);if(Number.isNaN(t))return;let n=t-c;n<=0||(s===null||n<s)&&(s=n)};for(let t of e){l(t.cooldownUntil);for(let e of t.providerCooldowns??[])l(e.until)}let u=n.filter(e=>e.lastLatencyMs!==void 0&&Number.isFinite(e.lastLatencyMs)),d=u.length===0?null:Math.round(u.reduce((e,t)=>e+(t.lastLatencyMs??0),0)/u.length);return{totalPools:e.length,active:n.length,cooldown:e.filter(e=>e.status===`cooldown`).length,totalMaxConcurrency:r,usedInflight:i,availableCapacity:Math.max(0,r-i),routablePools:a,saturatedPools:o,soonestCooldownMs:s,avgLatencyMs:d,measuredPools:u.length}}var G=[`http`,`https`,`socks5`];function K(e){return/^[a-z][a-z0-9+.-]*:\/\//i.test(e.trim())}function Le(e,t){let n=e.trim();return t===null||K(n)?n:`${t}://${n}`}function q(e){return e.find(e=>e.trim()!==``)}function J(e){let t=e.trim().toLowerCase();return t.startsWith(`https://`)?`https`:t.startsWith(`socks5://`)||t.startsWith(`socks://`)?`socks5`:`http`}var Re=1024**3;function ze(e){let t=e.trim();if(t===``)return null;let n=Number(t);return!Number.isFinite(n)||n<=0?null:Math.max(1,Math.round(n*Re))}function Y(e,t,n){let r=new Map;if(t.trim().toLowerCase()===``||n<=0)return r;let i=Math.floor(e/n),a=e-i*n;for(let e=0;e<n;e+=1){let t=e===n-1?a:0;r.set(e,i+t)}return r}var Be=4,Ve=`cartethyia_proxy_test_payload`,He=`cartethyia_proxy_check_results`,Ue=[{value:`url`,label:`Test URL`},{value:`opencode`,label:`Test OpenCode`}],We=`opencode`,Ge=4,Ke=`Mysterious Proxy`;function X(e){return e.avgLatencyMs===null?`no measurement yet`:`avg across ${e.measuredPools} enabled ${e.measuredPools===1?`pool`:`pools`}`}function qe(e){let t=e.endpoint||``,n=t.includes(`://`)?t:`${e.kind}://${t}`,r={"https:":`443`,"http:":`80`,"socks5:":`1080`,"socks:":`1080`};try{let e=new URL(n),t=e.port||r[e.protocol]||``,i=`${e.hostname}${t?`:${t}`:``}`;return{name:i,endpoint:`${e.protocol}//${i}${e.pathname===`/`?``:e.pathname}${e.search}`}}catch{return{name:e.label||t,endpoint:t}}}function Z(e){return e.label||qe(e).name||e.id}var Q=1024**3;function Je(e){if(e.lastSpeedtestStatus===void 0||e.lastSpeedtestAt===void 0)return;let t=e.lastSpeedtestDurationMs??0,n=e.lastSpeedtestBytes??0,r=t>0?n/(t/1e3):void 0;return{poolId:e.id,status:e.lastSpeedtestStatus,bytes:n,durationMs:t,...r===void 0?{}:{bytesPerSecond:r,megabitsPerSecond:r*8/1e6},...e.lastSpeedtestError?{errorMessage:e.lastSpeedtestError}:{},measuredAt:e.lastSpeedtestAt}}function Ye(e,t){if(!e)return t;if(!t)return e;let n=e.measuredAt?new Date(e.measuredAt).getTime():0;return(t.measuredAt?new Date(t.measuredAt).getTime():0)>=n?t:e}var Xe=[{value:String(he),label:`1 MB`},{value:String(ge),label:`5 MB`},{value:`50000000`,label:`50 MB`},{value:String(B),label:`100 MB`}];function Ze({pool:e,onClose:t,actionsRef:n}){let r=Ce(),i=Oe(),a=ke(),[l,f]=(0,V.useState)(e.label??``),[p,m]=(0,V.useState)(e.family??``),[h,g]=(0,V.useState)(e.endpoint??``),[_,v]=(0,V.useState)(String(e.maxInflight??10)),[y,ee]=(0,V.useState)(String(e.weight??100)),[b,x]=(0,V.useState)(e.quotaBytes?String(Math.round(e.quotaBytes/Q*1e3)/1e3):``),[S,C]=(0,V.useState)(null),[w,T]=(0,V.useState)(!1),E=h.trim()===e.endpoint,D=async()=>{T(!0),C(null);try{if(E){let t=await a.mutateAsync(e.id),n=t.status===`healthy`||t.status===`reachable`;C({ok:n,message:t.status===`healthy`?`Connected in ${t.latencyMs??0}ms`:t.errorMessage??`Connection failed`});return}let t=[{kind:e.kind,endpoint:h.trim(),...e.family===null||e.family===void 0?{}:{family:e.family}}],[n]=await i.mutateAsync({providerId:We,targets:t}),r=n?.result;if(!r){C({ok:!1,message:`Probe returned no result`});return}let o=r.status===`allowed`||r.status===`throttled`;C({ok:o,message:r.reason??(r.status===`allowed`?`Reachable${r.latencyMs===void 0?``:` in ${r.latencyMs}ms`}`:r.status===`throttled`?`Reachable; rate limit spent`:`Probe could not complete`)})}catch(e){C({ok:!1,message:j(e,`Connection failed`)})}finally{T(!1)}},O=ze(b),k=async()=>{await r.mutateAsync({poolId:e.id,request:{...l.trim()===e.label?{}:{label:l.trim()||void 0},...p.trim()===(e.family??``)?{}:{family:p.trim()||null},...h.trim()!==e.endpoint&&h.trim()!==``?{endpoint:h.trim()}:{},...Number(_)===e.maxInflight?{}:{maxInflight:Number(_)},...Number(y)===e.weight?{}:{weight:Number(y)},...O===(e.quotaBytes??null)?{}:{quotaBytes:O}}}),s.success(`Proxy updated`),t()};return(0,V.useEffect)(()=>{n?.((0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,onClick:t,children:`Cancel`}),(0,H.jsx)(o,{variant:`primary`,size:`sm`,disabled:r.isPending||!h.trim(),onClick:()=>void k(),children:`Save`})]}))}),(0,H.jsxs)(ce,{gap:`12px`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Name`,value:l,onChange:e=>f(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Family`,value:p,placeholder:`e.g. residential-id`,onChange:e=>m(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Endpoint`,value:h,onChange:e=>g(e.target.value),className:`font-mono tabular-nums`})}),(0,H.jsxs)(`div`,{className:`grid grid-cols-2 gap-5`,children:[(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Max concurrent`,type:`number`,min:1,value:_,onChange:e=>v(e.target.value)})}),(0,H.jsx)(`div`,{children:(0,H.jsx)(I,{label:`Weight`,type:`number`,min:1,value:y,onChange:e=>ee(e.target.value)})})]}),(0,H.jsxs)(`div`,{children:[(0,H.jsx)(I,{label:`Bandwidth quota (GB, blank = unmetered)`,type:`number`,min:.001,step:`0.1`,value:b,onChange:e=>x(e.target.value)}),(0,H.jsx)(`div`,{className:`text-micro text-text-tertiary mt-2`,children:O===null?`No quota — the bar shows a running total only.`:`Bar turns orange at 80% and red once ${c(O)} is exceeded.`})]}),S&&(0,H.jsx)(`div`,{className:`rounded-inset px-6 py-4 text-badge font-semibold ${S.ok?`bg-green-soft text-green`:`bg-red-soft text-red`}`,children:S.message}),(0,H.jsx)(`div`,{children:(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:w,icon:w?(0,H.jsx)(d,{size:13,className:`animate-spin`}):(0,H.jsx)(u,{size:13}),onClick:()=>void D(),children:w?`Testing…`:`Test connection`})})]})}function Qe({endpoint:e,chip:t,onChipChange:n}){return(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,role:`group`,"aria-label":`Scheme for the first endpoint`,children:[(0,H.jsx)(`span`,{className:`text-badge text-text-secondary`,children:`Scheme`}),G.map(r=>{let i=t===r;return(0,H.jsxs)(o,{type:`button`,variant:i?`primary`:`secondary`,size:`sm`,disabled:e===void 0,"aria-pressed":i,"data-scheme":r,onClick:()=>n(i?null:r),className:`font-mono`,children:[r,`://`]},r)}),t!==null&&(0,H.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[`→ `,Le(e??``,t)]})]})}function $e({onClose:e,actionsRef:t,onProbeResult:n,onHealthResult:r}){let i=be(),a=Se(),c=Oe(),[l,u]=(0,V.useState)(``),[d,f]=(0,V.useState)(``),[p,m]=(0,V.useState)(``),[h,g]=(0,V.useState)(null),[_,v]=(0,V.useState)([]),[y,ee]=(0,V.useState)({}),[b,x]=(0,V.useState)({}),[S,C]=(0,V.useState)(!1),[w,T]=(0,V.useState)(null),E=l.split(`
2
- `).map(e=>e.trim()).filter(Boolean),D=q(E),O=(0,V.useMemo)(()=>w===null||D===void 0?E:E.map((e,t)=>e===D&&t===0?Le(e,w):e),[E,w,D]),k=E.length>100,A=ze(p),M=(0,V.useMemo)(()=>O.map(e=>({kind:J(e),endpoint:e})),[O]),N=async()=>{try{let e=await navigator.clipboard.readText();e&&u(t=>t?`${t}\n${e}`:e)}catch{s.error(`Paste failed`,`Clipboard access denied`)}},P=async()=>{if(M.length!==0){v([`Testing ${M.length} proxy target(s)…`]);try{let e=await a.mutateAsync(M),t=e.map(e=>{let t=e.result.status===`healthy`||e.result.status===`reachable`,n=e.result.latencyMs===void 0?``:` · ${e.result.latencyMs}ms`,r=e.result.egressIp?` · ${e.result.egressIp}`:``,i=t?``:` · ${e.result.errorMessage??e.result.status}`;return`${t?`OK `:`FAIL`} ${e.endpoint}${n}${r}${i}`}),n=e.filter(e=>e.result.status===`healthy`||e.result.status===`reachable`).length;x(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n}),v([`${n}/${e.length} reachable`,...t]),n===e.length?s.success(`All ${e.length} proxies reachable`):s.error(`${e.length-n} of ${e.length} proxies failed`)}catch(e){v([`Test failed: ${j(e,`batch probe failed`)}`]),s.error(`Test failed`,j(e,`batch probe failed`))}}},te=async()=>{if(M.length!==0){v([`Testing ${M.length} proxy target(s) against OpenCode…`]);try{let e=await c.mutateAsync({providerId:We,targets:M}),t=e.map(e=>{let{status:t,latencyMs:n,reason:r}=e.result,i=n===void 0?``:` · ${n}ms`,a=r===void 0?``:` · ${r}`;return`${t===`allowed`?`OK `:t===`blocked`?`BLOCK`:`FAIL`} ${e.endpoint}${i}${a}`});ee(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n});let n=e.filter(e=>e.result.status===`allowed`).length,r=e.filter(e=>e.result.status===`blocked`).length;v([`${n}/${e.length} allowed · ${r} blocked`,...t]),r===0&&n===e.length?s.success(`OpenCode accepted all ${e.length} proxies`):s.error(`OpenCode: ${n} allowed · ${r} blocked`)}catch(e){v([`Test failed: ${j(e,`provider probe failed`)}`]),s.error(`Test failed`,j(e,`provider probe failed`))}}};return(0,V.useEffect)(()=>{t?.((0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(o,{variant:`secondary`,type:`button`,onClick:e,children:`Cancel`}),(0,H.jsx)(o,{variant:`primary`,type:`submit`,form:`add-proxy-form`,disabled:S||E.length===0,children:S?`Adding…`:`Add ${E.length} Prox${E.length===1?`y`:`ies`}`})]}))},[t,S,E.length,e]),(0,H.jsxs)(`form`,{id:`add-proxy-form`,onSubmit:async t=>{if(t.preventDefault(),E.length!==0){g(null),C(!0);try{let t=A===null?new Map:Y(A,d,O.length),a=Array(E.length),o=0,c=async()=>{for(;o<E.length;){let e=o++,s=O[e];try{let o=await i.mutateAsync({kind:J(s),endpoint:s,...t.has(e)?{quotaBytes:t.get(e)}:{},...d.trim()===``?{}:{family:d.trim()}}),c=y[s],l=b[s];o?.id&&(l!==void 0&&r?.(o.id,l),c!==void 0&&n?.(o.id,c)),a[e]={ok:!0}}catch(t){a[e]={ok:!1,error:j(t,`Proxy pool creation failed`)}}}};await Promise.all(Array.from({length:Math.min(Be,E.length)},()=>c()));let l=[],f=0;for(let[e,t]of a.entries())t.ok?f++:l.length<3&&l.push(`${E[e].slice(0,48)}…: ${t.error}`);let p=E.length-f,m=a.find(e=>!e.ok)?.error;f>0&&s.success(`Added ${f} proxy pool(s)`,p?`${p} failed: ${m??`see the import details`}`:void 0),p>0&&f===0&&s.error(`Failed to create pool`,m??`See the import details`),p>0&&g(l.join(`
3
- `)),f>0&&(u(``),e())}finally{C(!1)}}},className:`flex flex-col gap-4`,children:[(0,H.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,H.jsx)(`label`,{htmlFor:`proxy-endpoints`,className:`text-caption font-semibold text-text-primary`,children:`Proxy endpoints`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,type:`button`,onClick:N,children:`Paste`})]}),(0,H.jsx)(`textarea`,{id:`proxy-endpoints`,value:l,onChange:e=>u(e.target.value),placeholder:`http://proxy.example:8080
4
- https://proxy.example:8443
5
- socks5://proxy.example:1080`,rows:5,"aria-describedby":`proxy-format-hint proxy-line-count`,"aria-invalid":!!h,className:`w-full min-h-32 max-h-64 resize-y overflow-y-auto rounded-control border border-inner-border bg-surface-1 p-3 font-mono text-caption text-text-primary outline-none transition-[border-color,box-shadow] duration-(--dur-micro) ease-spring focus:border-accent focus:shadow-focus`}),(0,H.jsx)(Qe,{endpoint:D,chip:w,onChipChange:T}),(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-x-4 gap-y-2`,children:[(0,H.jsx)(`p`,{id:`proxy-format-hint`,className:`m-0 text-badge leading-normal text-text-secondary`,children:`HTTP, HTTPS, or SOCKS5 | one per line | authentication optional`}),(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,H.jsxs)(`span`,{id:`proxy-line-count`,role:`status`,"aria-live":`polite`,className:`text-badge ${k?`text-red`:`text-text-tertiary`}`,children:[E.length===1?`1 proxy detected`:`${E.length} proxies detected`,k?` · max 100 per test`:``]}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>void P(),disabled:a.isPending||c.isPending||E.length===0||k,children:a.isPending?`Testing…`:`Test URL`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>void te(),disabled:a.isPending||c.isPending||E.length===0||k,children:c.isPending?`Testing…`:`Test OpenCode`})]})]}),h&&(0,H.jsx)(`div`,{role:`alert`,className:`max-h-28 overflow-y-auto rounded-inset bg-red-soft px-4 py-3 text-badge text-red whitespace-pre-wrap break-words`,children:h}),_.length>0&&(0,H.jsx)(`div`,{role:`log`,"aria-label":`Proxy test results`,"aria-live":`polite`,className:`scroll-region max-h-40 overflow-y-auto whitespace-pre-wrap break-all rounded-inset border border-inner-border bg-surface-1 px-3 py-2 font-mono text-badge leading-[1.5] text-text-secondary`,children:_.join(`
6
- `)}),(0,H.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,H.jsx)(I,{id:`proxy-family`,label:`Family`,hint:`Optional`,value:d,placeholder:`e.g. residential-id`,onChange:e=>f(e.target.value),className:`w-full`}),(0,H.jsx)(I,{id:`proxy-quota`,label:`Bandwidth quota (GB)`,hint:`Optional`,type:`number`,min:.001,step:`0.1`,value:p,onChange:e=>m(e.target.value),className:`w-full`})]})]})}function et(e,t){if(t?.status===`healthy`||t?.status===`reachable`)return t.latencyMs;if(e.lastSuccessAt)return e.lastLatencyMs??void 0}function tt(e){if(e===`proxy_payment_required`)return`HTTP 402 Payment Required`;if(e===`proxy_auth_required`)return`HTTP 407 Proxy Authentication Required`}var $=(0,V.createContext)({byId:new Map,live:!1});function nt({children:e}){let t=z(),n=(0,V.useMemo)(()=>new Map((t.pools??[]).map(e=>[e.poolId,e])),[t.pools]),r=(0,V.useMemo)(()=>({byId:n,live:t.live&&t.pools!==null}),[n,t.live,t.pools]);return(0,H.jsx)($.Provider,{value:r,children:e})}function rt({pools:e}){let{byId:t,live:n}=(0,V.useContext)($),r=(0,V.useMemo)(()=>W(e,n?new Map([...t].map(([e,t])=>[e,t.currentInflight])):void 0),[e,t,n]),a=(0,V.useMemo)(()=>{let r=0,i=0;for(let a of e){let e=n?t.get(a.id):void 0,o=(a.bytesSentTotal??0)+(a.bytesReceivedTotal??0),s=(e?.bytesSent??0)+(e?.bytesReceived??0);r+=Math.max(o,s),a.quotaBytes&&(i+=a.quotaBytes)}return{used:r,allowance:i}},[e,t,n]);return(0,H.jsxs)(`div`,{className:`signal-grid grid gap-7 w-full min-w-0 mb-7`,children:[(0,H.jsx)(R,{label:`Enabled pool`,value:String(r.active),detail:`/ ${r.totalPools} total`,tone:`accent`,icon:(0,H.jsx)(S,{size:13})}),(0,H.jsx)(R,{label:`Route capacity`,value:String(r.totalMaxConcurrency),detail:`${r.usedInflight} inflight · ${r.availableCapacity} available`,tone:r.availableCapacity===0?`orange`:`teal`,icon:(0,H.jsx)(m,{size:13})}),(0,H.jsx)(R,{label:`Latency`,value:r.avgLatencyMs===null?`—`:`${r.avgLatencyMs}ms`,detail:X(r),tone:r.avgLatencyMs===null?`accent`:r.avgLatencyMs>2e3?`orange`:`teal`,icon:(0,H.jsx)(i,{size:13})}),(0,H.jsx)(R,{label:`Quota usage`,value:c(a.used),detail:a.allowance>0?`of ${c(a.allowance)} allowance · ${e.length} pools`:`${e.length} pools · no allowance set`,tone:a.allowance>0&&a.used>a.allowance?`red`:a.allowance>0&&a.used/a.allowance>=.8?`orange`:`teal`,icon:(0,H.jsx)(pe,{size:13})})]})}function it(e,t,n,r,i){let a=qe(e),o=Z(e),s=e.status!==`disabled`,c=tt(e.lastErrorCategory),l=e.status===`disabled`&&c!==void 0,u=e.lastSuccessAt?new Date(e.lastSuccessAt).getTime():0,d=e.lastErrorAt?new Date(e.lastErrorAt).getTime():0,f=!t&&(u>0||d>0)?u>=d:null,p=n?`default`:l?`warn`:t?t.status===`healthy`?`ok`:t.status===`reachable`?`warn`:`err`:f===!0?`ok`:f===!1?`err`:`default`,m=l?e.lastError??c:t?.errorMessage??(f===null?void 0:`last check ${(e.lastHealthCheckAt?new Date(e.lastHealthCheckAt):new Date).toLocaleString()}`),h=et(e,t),g=r?.currentInflight??e.inflight,_=e.maxInflight>0?Math.min(1,g/e.maxInflight):1,v=e.providerCooldowns??[],y=v.filter(e=>e.blocked===!0),ee=v.filter(e=>e.blocked!==!0),b=v.slice(0,2).map(e=>e.blocked===!0?`${e.providerId} blocked: ${e.reason}`:`${e.providerId} until ${new Date(e.until).toLocaleTimeString()}: ${e.reason}`).join(` · `),x=n?`Testing…`:l?`Proxy reachable`:t?t.status===`healthy`?`Connected`:t.status===`reachable`?`Proxy reachable`:t.status===`timeout`?`Timeout`:`Unhealthy`:f===!0?`Connected`:f===!1?e.lastErrorCategory===`timeout`?`Timeout`:`Unhealthy`:`Untested`,S=(e.bytesSentTotal??0)+(e.bytesReceivedTotal??0),C=(r?.bytesSent??0)+(r?.bytesReceived??0);return{display:a,poolLabel:o,isEnabled:s,checkTone:p,checkTooltip:m,statusText:x,latency:h,inflight:g,load:_,cooldowns:v,blocked:y,cooldownOnly:ee,cooldownText:b,...i===void 0?{}:{probe:i},metered:S,session:C,used:Math.max(S,C),proxyFailureLabel:c}}function at({pool:e,view:t,maskValues:n}){return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(`span`,{className:`block text-caption font-semibold overflow-hidden truncate whitespace-nowrap`,title:n?Ke:t.poolLabel,children:n?Ke:t.poolLabel}),(0,H.jsxs)(`div`,{className:`flex items-center gap-3 mt-1.5 min-w-0 flex-wrap`,children:[e.status===`disabled`?(0,H.jsxs)(F,{tone:`disabled`,title:e.lastError,children:[`Disabled`,t.proxyFailureLabel?` · ${t.proxyFailureLabel}`:``]}):(0,H.jsx)(F,{tone:t.checkTone,title:t.checkTooltip,children:t.latency===void 0?t.statusText:`${t.statusText} · ${t.latency}ms`}),t.blocked.length>0?(0,H.jsxs)(F,{tone:`disabled`,title:t.cooldownText,children:[t.blocked.length,` blocked`]}):null,t.probe?(0,H.jsx)(F,{tone:t.probe.status===`blocked`?`disabled`:t.probe.status===`allowed`?`ok`:`warn`,title:t.probe.reason??(t.probe.status===`allowed`?t.probe.httpStatus!==void 0&&t.probe.httpStatus>=400?`Reachable — upstream answered ${t.probe.httpStatus} for the probe body`:`OpenCode served a probe through this pool`:t.probe.status===`throttled`?`OpenCode accepted this egress; the rate is spent`:`The probe could not complete`),children:t.probe.status===`blocked`?`OpenCode blocked`:t.probe.status===`allowed`?t.probe.httpStatus!==void 0&&t.probe.httpStatus>=400?`OpenCode reachable`:`OpenCode OK`:t.probe.status===`throttled`?`OpenCode rate-limited`:`OpenCode unreachable`}):null,t.cooldownOnly.length>0?(0,H.jsxs)(F,{tone:`warn`,title:t.cooldownText,children:[t.cooldownOnly.length,` cooldown`,t.cooldownOnly.length>1?`s`:``]}):null]})]})}function ot({pool:e,view:t,speedResult:n,isSpeedTesting:r,maskIp:i}){return(0,H.jsxs)(H.Fragment,{children:[e.egressIp?(0,H.jsx)(`span`,{className:`font-mono tabular-nums block overflow-hidden text-ellipsis whitespace-nowrap text-badge`,title:i?`IP masked`:`egress ${e.egressIp} · ${t.display.endpoint}`,children:i?`IP masked`:e.egressIp}):(0,H.jsx)(`span`,{className:`text-badge text-text-tertiary`,title:`Test the pool to read its egress address`,children:`not probed`}),(r||n)&&(0,H.jsx)(`div`,{className:`mt-1.5`,children:(0,H.jsx)(F,{tone:r?`default`:n?.status===`ok`?`ok`:`err`,title:r?`Measuring download throughput`:n?.status===`ok`?`${c(n.bytes)} in ${n.durationMs}ms${n.measuredAt?` · last measured ${new Date(n.measuredAt).toLocaleString()}`:``}`:`${n?.errorMessage??`Speed test failed`}${n?.measuredAt?` · last measured ${new Date(n.measuredAt).toLocaleString()}`:``}`,children:r?`Speed…`:n?.status===`ok`?`${(n.megabitsPerSecond??0).toFixed(1)} Mbps`:`Speed failed`})})]})}function st({pool:e,view:t}){let n=e.quotaBytes,r=n&&n>0?Math.min(1,t.used/n):0,i=n!==void 0&&n>0&&t.used>n;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(`div`,{title:`${t.inflight}/${e.maxInflight} inflight`,className:`flex items-center gap-3`,children:[(0,H.jsx)(`div`,{className:`flex-1 h-3 rounded-micro overflow-hidden`,children:(0,H.jsx)(`div`,{className:`h-full rounded-micro`,style:{width:`${Math.round(t.load*100)}%`,background:t.load>=.8?`var(--orange)`:`var(--green)`}})}),(0,H.jsxs)(`span`,{className:`font-mono tabular-nums text-micro text-text-secondary whitespace-nowrap`,children:[t.inflight,`/`,e.maxInflight]})]}),(0,H.jsxs)(`div`,{title:n?`${c(t.used)} of ${c(n)} used · ${c(t.metered)} metered lifetime`:`${c(t.used)} carried (no quota set) · ${c(t.session)} this session`,className:`flex items-center gap-3 mt-2`,children:[(0,H.jsx)(`div`,{className:`flex-1 h-3 rounded-micro overflow-hidden`,children:(0,H.jsx)(`div`,{className:`h-full rounded-micro`,style:{width:`${Math.round(r*100)}%`,background:i?`var(--red)`:r>=.8?`var(--orange)`:`var(--teal)`}})}),(0,H.jsxs)(`span`,{className:`font-mono tabular-nums whitespace-nowrap text-micro ${i?`text-red`:`text-text-secondary`}`,children:[c(t.used),n?` / ${c(n)}`:``]})]})]})}function ct({pool:e,view:t,isTesting:n,onDelete:r,onEdit:a,onHealthCheck:s,onActivity:c}){let l=Ce(),f=je(),p=Te();return(0,H.jsxs)(H.Fragment,{children:[t.cooldowns.length>0&&(0,H.jsx)(o,{size:`icon`,variant:`secondary`,disabled:f.isPending,icon:f.isPending?(0,H.jsx)(d,{size:12,className:`animate-spin`}):(0,H.jsx)(x,{size:12}),onClick:()=>f.mutate({poolId:e.id}),title:`Clear provider cooldowns — ${t.cooldownText}`,label:`Clear`}),(0,H.jsx)(o,{size:`icon`,variant:`secondary`,icon:(0,H.jsx)(i,{size:12}),onClick:()=>c(e),title:`Health and error activity`,label:`Activity`}),e.status===`cooldown`&&(0,H.jsx)(o,{size:`icon`,variant:`secondary`,disabled:p.isPending,icon:(0,H.jsx)(x,{size:12,className:p.isPending?`animate-spin`:``}),onClick:()=>p.mutate(e.id),title:`Recover pool`,children:`Recover`}),!(!t.isEnabled&&t.cooldowns.length>0)&&(0,H.jsx)(o,{size:`icon`,variant:`secondary`,disabled:n,icon:n?(0,H.jsx)(d,{size:12,className:`animate-spin`}):(0,H.jsx)(u,{size:12}),onClick:()=>s(e),title:t.checkTooltip??`Run health check`,label:`Test`}),(0,H.jsx)(o,{size:`icon`,variant:`secondary`,icon:(0,H.jsx)(y,{size:12}),onClick:()=>a(e),title:`Edit pool`,label:`Edit`}),(0,H.jsx)(o,{size:`icon`,variant:`secondary`,icon:(0,H.jsx)(C,{size:12}),onClick:()=>r(e.id),title:`Delete pool`,label:`Delete`}),(0,H.jsx)(L,{className:`ml-3`,checked:t.isEnabled,disabled:l.isPending,onChange:t=>l.mutate({poolId:e.id,request:{status:t?`active`:`disabled`}})})]})}var lt=(0,V.memo)(function({pool:e,isSelected:t,onToggleSelect:n,checkResult:r,isTesting:i,onDelete:a,onEdit:o,onHealthCheck:s,onActivity:c,speedResult:l,isSpeedTesting:u,maskValues:d,maskIp:f,probe:p}){let m=(0,V.useContext)($),h=it(e,r,i,(m.live?m.byId.get(e.id):void 0)??null,p);return(0,H.jsxs)(`tr`,{className:h.isEnabled?``:`opacity-60`,children:[(0,H.jsx)(`td`,{className:`w-13`,children:(0,H.jsx)(`input`,{type:`checkbox`,checked:t,onChange:()=>n(e.id),"aria-label":`Select ${h.poolLabel}`})}),(0,H.jsx)(`td`,{className:`min-w-0 max-w-150`,children:(0,H.jsx)(at,{pool:e,view:h,maskValues:d})}),(0,H.jsx)(`td`,{className:`min-w-0 max-w-90`,children:e.family?(0,H.jsx)(`span`,{className:`truncate text-caption font-semibold text-text-secondary`,title:e.family,children:e.family}):(0,H.jsx)(`span`,{className:`text-badge text-text-tertiary`,children:`—`})}),(0,H.jsx)(`td`,{className:`max-w-110`,children:(0,H.jsx)(ot,{pool:e,view:h,speedResult:l,isSpeedTesting:u,maskIp:f})}),(0,H.jsx)(`td`,{className:`min-w-55`,children:(0,H.jsx)(st,{pool:e,view:h})}),(0,H.jsx)(`td`,{className:`whitespace-nowrap pl-36 text-right`,children:(0,H.jsx)(le,{gap:`4px`,justify:`end`,children:(0,H.jsx)(ct,{pool:e,view:h,isTesting:i,onDelete:a,onEdit:o,onHealthCheck:s,onActivity:c})})})]})});function ut({pool:e,onClose:t}){let n=we(e.id),r=Te(),i=n.data??[],a=tt(e.lastErrorCategory),s=e.status===`disabled`&&a!==void 0,c=e.status===`active`?`ok`:e.status===`disabled`?`disabled`:`warn`;return(0,H.jsx)(v,{open:!0,onClose:t,title:`Health & Activity — ${Z(e)}`,children:(0,H.jsxs)(ce,{gap:`14px`,children:[(0,H.jsxs)(`div`,{className:`flex items-center gap-8 rounded-panel border bg-surface-2 p-8 ${s?`border-orange`:`border-inner-border`}`,children:[(0,H.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,H.jsx)(`div`,{className:`mb-2.5 text-text-tertiary text-micro font-bold tracking-label uppercase`,children:`Proxy health`}),(0,H.jsx)(`div`,{className:`text-title font-bold leading-[1.3]`,children:s?`Proxy reachable`:`Proxy ${e.status}`}),(0,H.jsx)(`p`,{className:`mt-3 mx-0 mb-0 text-text-secondary text-caption leading-normal wrap-anywhere`,children:s?`${a} · disabled from routing`:e.lastError??`No recent proxy errors.`})]}),(0,H.jsx)(F,{tone:c,dot:!0,children:e.status})]}),e.status===`cooldown`&&(0,H.jsx)(`div`,{className:`flex justify-end`,children:(0,H.jsx)(o,{size:`sm`,variant:`secondary`,disabled:r.isPending,onClick:()=>r.mutate(e.id),icon:(0,H.jsx)(x,{size:12,className:r.isPending?`animate-spin`:``}),children:`Recover Now`})}),n.isPending?(0,H.jsx)(g,{compact:!0,label:`Loading pool activity…`}):null,n.isError?(0,H.jsx)(h,{compact:!0,message:`Failed to load pool activity`,onRetry:()=>void n.refetch()}):null,!n.isPending&&!n.isError&&i.length===0?(0,H.jsx)(_,{compact:!0,title:`No pool activity`,message:`Proxy checks, disable events, and recoveries will appear here.`}):null,i.length>0?(0,H.jsx)(`div`,{className:`grid gap-4 max-h-190 overflow-y-auto pr-1`,children:i.map(e=>(0,H.jsxs)(`div`,{className:`p-6 border border-inner-border rounded-control bg-surface-1`,children:[(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-4`,children:[(0,H.jsxs)(le,{gap:`6px`,children:[(0,H.jsxs)(F,{tone:e.toStatus===`active`?`ok`:e.toStatus===`disabled`?`disabled`:`warn`,children:[e.fromStatus??`new`,` → `,e.toStatus]}),e.errorCategory?(0,H.jsx)(F,{tone:e.errorCategory.startsWith(`proxy_`)?`warn`:`err`,children:e.errorCategory}):null]}),(0,H.jsx)(`time`,{className:`text-text-tertiary text-badge tabular-nums`,children:new Date(e.createdAt).toLocaleString()})]}),(0,H.jsx)(`p`,{className:`mt-4 mx-0 mb-0 text-text-secondary text-caption leading-normal wrap-anywhere`,children:e.reason??`No additional details`})]},e.id))}):null]})})}function dt(){let e=ye(),t=Ee(),n=Ce(),r=ke(),[i,c]=(0,V.useState)(!1),l=(0,V.useCallback)(()=>c(!1),[]),[y,x]=(0,V.useState)(null),[w,T]=(0,V.useState)(null),[E,D]=(0,V.useState)(!1),[O,k]=(0,V.useState)(null),[A,M]=(0,V.useState)(new Set),N=de(),P=N.enabled,te=fe(),I=te.enabled,[L,R]=(0,V.useState)(new Set),[z,he]=(0,V.useState)(()=>{try{return localStorage.getItem(Ve)===`opencode`?`opencode`:`url`}catch{return`url`}});(0,V.useEffect)(()=>{try{localStorage.setItem(Ve,z)}catch{}},[z]);let[B,_e]=(0,V.useState)(new Set),[ve,be]=(0,V.useState)({}),xe=De(),Se=Ae(),[we,Te]=(0,V.useState)(ge),[Oe,je]=(0,V.useState)(()=>{try{let e=localStorage.getItem(`cartethyia_proxy_speed_results`);return e?JSON.parse(e):{}}catch{return{}}}),[U,Me]=(0,V.useState)(new Set),Fe=(0,V.useCallback)((e,t)=>{let n={...t,measuredAt:new Date().toISOString()};je(t=>{let r={...t,[e]:n};try{localStorage.setItem(`cartethyia_proxy_speed_results`,JSON.stringify(r))}catch{}return r})},[]),[W,G]=(0,V.useState)(()=>{try{let e=localStorage.getItem(He);return e?JSON.parse(e):{}}catch{return{}}}),[K,Le]=(0,V.useState)({key:`name`,direction:`asc`}),[q,J]=(0,V.useState)(null),[Re,ze]=(0,V.useState)(null),Y=e.data??[],Be=(0,V.useMemo)(()=>Ie(Y,K.key,K.direction,e=>et(e,W[e.id])),[Y,K,W]),Ke=(0,V.useCallback)(e=>{let t=e;Le(e=>e.key===t?{key:t,direction:e.direction===`asc`?`desc`:`asc`}:{key:t,direction:`asc`})},[]),X=e.isPending,Q=e.isError,Qe=Y.length>0&&Y.every(e=>A.has(e.id)),tt=()=>{M(Qe?new Set:new Set(Y.map(e=>e.id)))},$=(0,V.useCallback)(e=>{M(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);(0,V.useEffect)(()=>{try{localStorage.setItem(He,JSON.stringify(W))}catch{}},[W]);let it=Object.values(W),at=it.length,ot=it.filter(e=>e.status===`healthy`||e.status===`reachable`).length,st=it.filter(e=>e.status!==`healthy`&&e.status!==`reachable`).length,ct=(0,V.useCallback)(e=>{R(t=>new Set(t).add(e.id)),r.mutate(e.id,{onSuccess:t=>{G(n=>({...n,[e.id]:t}));let n=Z(e);t.status===`healthy`?s.success(`${n}: connected`,`${t.latencyMs??0}ms`):t.status===`reachable`?s.error(`${n}: proxy reachable · disabled`,t.errorMessage):s.error(`${n}: ${t.status===`timeout`?`timeout`:`unhealthy`}`,t.errorMessage)},onError:t=>{let n=Z(e);s.error(`${n}: check failed`,j(t,`Health check failed`))},onSettled:()=>{R(t=>{let n=new Set(t);return n.delete(e.id),n})}})},[r]),dt=async()=>{let e=Y;if(e.length===0)return;let t=0,n=0,i=0,a=async()=>{for(;;){let a=e[i++];if(!a)return;R(e=>new Set(e).add(a.id));try{let e=await r.mutateAsync(a.id);G(t=>({...t,[a.id]:e})),e.status===`healthy`?t+=1:n+=1}catch(e){n+=1;let t={poolId:a.id,status:`timeout`,errorMessage:j(e,`Health check failed`)};G(e=>({...e,[a.id]:t}))}finally{R(e=>{let t=new Set(e);return t.delete(a.id),t})}}};await Promise.all(Array.from({length:Math.min(8,e.length)},()=>a())),s.success(`Tested ${e.length} pools · ${t} healthy · ${n} failed`)},ft=async()=>{let e=Y.filter(e=>A.has(e.id));if(e.length===0)return;let t=0,n=0,i=0,a=async()=>{for(;;){let a=e[i++];if(!a)return;R(e=>new Set(e).add(a.id));try{let e=await r.mutateAsync(a.id);G(t=>({...t,[a.id]:e})),e.status===`healthy`?t+=1:n+=1}catch(e){n+=1;let t={poolId:a.id,status:`timeout`,errorMessage:j(e,`Health check failed`)};G(e=>({...e,[a.id]:t}))}finally{R(e=>{let t=new Set(e);return t.delete(a.id),t})}}};await Promise.all(Array.from({length:Math.min(8,e.length)},()=>a())),s.success(`Tested ${e.length} pools · ${t} healthy · ${n} failed`)},pt=async()=>{let e=Y.filter(e=>A.has(e.id));if(e.length===0)return;let t=0,n=0,r=0,i=0,a=0,o=async()=>{for(;;){let o=e[a++];if(!o)return;_e(e=>new Set(e).add(o.id));try{let e=await xe.mutateAsync({poolId:o.id,providerId:We});be(t=>({...t,[o.id]:{endpoint:o.endpoint??``,result:e}})),e.status===`allowed`?t+=1:e.status===`blocked`?n+=1:e.status===`throttled`?r+=1:i+=1}catch(e){i+=1,be(t=>({...t,[o.id]:{endpoint:o.endpoint??``,result:{poolId:o.id,providerId:We,status:`unreachable`,reason:j(e,`Provider probe failed`)}}}))}finally{_e(e=>{let t=new Set(e);return t.delete(o.id),t})}}};await Promise.all(Array.from({length:Math.min(Ge,e.length)},()=>o())),s.success(`OpenCode: ${t} allowed · ${n} blocked`+(r>0?` · ${r} rate-limited`:``)+(i>0?` · ${i} unreachable`:``))},mt=async()=>{let e=Y.filter(e=>A.has(e.id));if(e.length===0)return;let t=0;await(async()=>{for(;;){let n=e[t++];if(!n)return;Me(e=>new Set(e).add(n.id));try{let e=await Se.mutateAsync({poolId:n.id,bytes:we});Fe(n.id,e)}catch(e){Fe(n.id,{poolId:n.id,status:`failed`,bytes:0,durationMs:0,errorMessage:j(e,`Speed test failed`)})}finally{Me(e=>{let t=new Set(e);return t.delete(n.id),t})}}})(),s.success(`Speed tested ${e.length} pool(s)`)},ht=async()=>{let e=Y.filter(e=>A.has(e.id));e.length!==0&&(await Promise.all(e.map(e=>n.mutateAsync({poolId:e.id,request:{status:`active`}}))),M(new Set),s.success(`Enabled ${e.length} pool(s)`))},gt=async()=>{let e=Y.filter(e=>A.has(e.id));e.length!==0&&(await Promise.all(e.map(e=>n.mutateAsync({poolId:e.id,request:{status:`disabled`}}))),M(new Set),s.success(`Disabled ${e.length} pool(s)`))},_t=()=>{let e=A.size>0?Y.filter(e=>A.has(e.id)):Y;if(e.length===0)return;let t=e.map(e=>qe(e).endpoint||e.endpoint).join(`
7
- `);oe(`cartethyia-proxies.txt`,t,`text/plain;charset=utf-8`),s.success(`Exported ${e.length} pool(s)`)},vt=(0,V.useCallback)(e=>{let t=Y.find(t=>t.id===e);t&&J([t])},[Y]);return(0,H.jsx)(nt,{children:(0,H.jsxs)(ce,{gap:`16px`,children:[(0,H.jsx)(v,{open:i,onClose:l,title:`Add Proxy`,footer:y,children:(0,H.jsx)($e,{onClose:l,actionsRef:x,onProbeResult:(e,t)=>{let n=Y.find(t=>t.id===e);be(r=>({...r,[e]:{endpoint:n?.endpoint??``,result:t}}))},onHealthResult:(e,t)=>{G(n=>({...n,[e]:t}))}})}),(0,H.jsx)(v,{open:O!==null,onClose:()=>k(null),title:`Edit pool`,footer:w,children:O&&(0,H.jsx)(Ze,{pool:O,onClose:()=>k(null),actionsRef:T},O.id)}),(0,H.jsxs)(ae,{style:Y.length===0&&!X&&!Q?{minHeight:`min(78dvh, calc(100dvh - 160px))`,display:`flex`,flexDirection:`column`}:void 0,children:[(0,H.jsx)(ie,{title:`Proxy Pool`,subtitle:`Outbound proxy servers — HTTP, HTTPS, and SOCKS5`,icon:(0,H.jsx)(S,{size:16}),action:(0,H.jsxs)(le,{gap:`8px`,children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,icon:(0,H.jsx)(pe,{size:13}),onClick:()=>D(!0),children:`Deploy relay`}),(0,H.jsx)(o,{variant:`primary`,size:`sm`,icon:(0,H.jsx)(ee,{size:13}),onClick:()=>c(!0),children:`Add proxies`})]})}),(0,H.jsxs)(re,{style:Y.length===0&&!X&&!Q?{flex:1,display:`flex`,flexDirection:`column`,gap:`16px`}:void 0,children:[(0,H.jsx)(rt,{pools:Y}),Y.length>0&&(0,H.jsxs)(`div`,{className:`nested-panel flex flex-wrap items-center justify-start overflow-x-auto rounded-card border border-inner-border bg-surface-2 p-4 text-badge`,children:[(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-5`,children:[(0,H.jsxs)(`label`,{className:`flex items-center gap-3 cursor-pointer text-text-secondary`,children:[(0,H.jsx)(`input`,{type:`checkbox`,checked:Qe,onChange:tt,"aria-label":`Select all proxies`}),`Select all`,A.size>0&&(0,H.jsxs)(`span`,{className:`text-text-tertiary`,children:[`(`,A.size,`)`]})]}),at>0&&(0,H.jsxs)(le,{gap:`6px`,children:[(0,H.jsxs)(`span`,{className:`text-text-tertiary`,children:[`Tested `,at,`/`,Y.length]}),ot>0&&(0,H.jsxs)(F,{tone:`ok`,children:[ot,` success`]}),st>0&&(0,H.jsxs)(F,{tone:`err`,children:[st,` errors`]})]})]}),(0,H.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,H.jsx)(o,{variant:`ghost`,size:`sm`,icon:P?(0,H.jsx)(f,{size:12}):(0,H.jsx)(p,{size:12}),onClick:()=>N.setEnabled(!P),title:P?`Show proxy names and addresses`:`Hide proxy names and addresses`,children:P?`Unmask`:`Mask`}),(0,H.jsx)(o,{variant:`ghost`,size:`sm`,icon:I?(0,H.jsx)(f,{size:12}):(0,H.jsx)(p,{size:12}),onClick:()=>te.setEnabled(!I),title:I?`Show egress addresses`:`Hide egress addresses`,children:I?`Show IP`:`Mask IP`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:L.size>0||Y.length===0,icon:L.size>0?(0,H.jsx)(d,{size:12,className:`animate-spin`}):(0,H.jsx)(u,{size:12}),onClick:()=>void dt(),children:`Test all`}),(0,H.jsxs)(`div`,{className:`inline-flex items-stretch h-15`,children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,className:`rounded-tr-none rounded-br-none`,disabled:L.size>0||B.size>0||A.size===0,icon:L.size>0||B.size>0?(0,H.jsx)(d,{size:12,className:`animate-spin`}):(0,H.jsx)(u,{size:12}),onClick:()=>void(z===`opencode`?pt():ft()),children:z===`opencode`?`Test OpenCode`:`Test URL`}),(0,H.jsx)(se,{"aria-label":`Test payload`,value:z,onValueChange:e=>he(e),options:Ue,disabled:L.size>0||B.size>0,className:`w-auto min-w-38 h-15 rounded-tl-none rounded-bl-none -ml-0.5`})]}),(0,H.jsxs)(`div`,{className:`inline-flex items-stretch h-15`,children:[(0,H.jsx)(o,{variant:`secondary`,size:`sm`,className:`rounded-tr-none rounded-br-none`,disabled:A.size===0||U.size>0||Se.isPending,icon:U.size>0?(0,H.jsx)(d,{size:12,className:`animate-spin`}):(0,H.jsx)(m,{size:12}),onClick:()=>void mt(),children:`Speedtest selected`}),(0,H.jsx)(se,{"aria-label":`Speed test payload size`,value:String(we),onValueChange:e=>Te(Number(e)),options:Xe,disabled:U.size>0||Se.isPending,className:`w-auto min-w-38 h-15 rounded-tl-none rounded-bl-none -ml-0.5`})]}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:Y.length===0,icon:(0,H.jsx)(a,{size:12}),onClick:_t,children:`Export`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:A.size===0||n.isPending,icon:(0,H.jsx)(me,{size:12}),onClick:()=>void ht(),children:`Enable selected`}),(0,H.jsx)(o,{variant:`secondary`,size:`sm`,disabled:A.size===0||n.isPending,icon:(0,H.jsx)(b,{size:12}),onClick:()=>void gt(),children:`Disable selected`}),(0,H.jsx)(o,{variant:`danger`,size:`sm`,disabled:A.size===0||t.isPending,icon:(0,H.jsx)(C,{size:12}),onClick:()=>{let e=Y.filter(e=>A.has(e.id));e.length!==0&&J(e)},children:`Delete selected`})]})]}),X&&(0,H.jsx)(g,{}),Q&&(0,H.jsx)(h,{title:`Error`,message:`Failed to load network pools`}),!X&&!Q&&Y.length===0&&(0,H.jsx)(`div`,{className:`flex-1 flex items-center justify-center p-12 border border-dashed border-transparent rounded-card bg-transparent text-center`,children:(0,H.jsx)(_,{title:`No proxy pools configured`,message:`The summary above is empty because nothing is routing yet. Use Add proxies or Deploy relay in the header to start one.`})}),!X&&!Q&&Y.length>0&&(0,H.jsx)(`div`,{className:`proxy-table-scroll rounded-control border border-inner-border bg-surface-1`,children:(0,H.jsx)(ue,{maxHeight:460,scrollRegion:!0,headers:[``,{key:`name`,label:`Proxy`,sortable:!0},{key:`family`,label:`Family`,sortable:!0},{key:`address`,label:`Address`,sortable:!0},{key:`load`,label:`Load`,sortable:!0},`Actions`],sortKey:K.key,sortDirection:K.direction,onSort:Ke,children:Be.map(e=>(0,H.jsx)(lt,{pool:e,isSelected:A.has(e.id),onToggleSelect:$,checkResult:W[e.id],probe:e.providerProbe===void 0?Pe(ve[e.id],e.endpoint):{poolId:e.id,providerId:e.providerProbe.providerId,status:e.providerProbe.status,...e.providerProbe.httpStatus===void 0?{}:{httpStatus:e.providerProbe.httpStatus},...e.providerProbe.reason===void 0?{}:{reason:e.providerProbe.reason},...e.providerProbe.latencyMs===void 0?{}:{latencyMs:e.providerProbe.latencyMs}},isTesting:L.has(e.id),onDelete:vt,onEdit:k,onHealthCheck:ct,onActivity:ze,speedResult:Ye(Oe[e.id],Je(e)),isSpeedTesting:U.has(e.id),maskValues:P,maskIp:I},e.id))})})]})]}),(0,H.jsx)(ne,{open:q!==null,onClose:()=>J(null),onConfirm:async()=>{q&&(await Promise.all(q.map(e=>t.mutateAsync(e.id))),M(new Set),s.success(`Deleted ${q.length} pool(s)`),J(null))},title:`Delete proxy pool?`,message:q&&q.length===1?`Delete "${Z(q[0])}"? This cannot be undone.`:q?`Delete ${q.length} proxy pools? This cannot be undone.`:`Delete this proxy pool? This cannot be undone.`,confirmLabel:`Delete`,danger:!0}),Re?(0,H.jsx)(ut,{pool:Re,onClose:()=>ze(null)}):null,E?(0,H.jsx)(Ne,{onClose:()=>D(!1)}):null]})})}export{$e as ProxyBulkForm,nt as ProxyLiveProvider,Qe as SchemeChipRow,dt as default};
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i,r as a}from"./terminal-0_IjPWTk.js";import{T as o,c as s,i as c,s as l,t as u}from"./numbers-Dulqgys5.js";import{t as d}from"./database-Dz9N3zGd.js";import{t as f}from"./eye-C_hawfH4.js";import{n as p,r as m}from"./state-DhZBfWgx.js";import{t as h}from"./layers-2-glBbjl.js";import{t as ee}from"./dialog-Iec_ywbD.js";import{n as g,r as te,t as _}from"./settings--3hxSyry.js";import{t as v}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{C as b,T as x,v as S}from"./assert-DU6qrMA_.js";import{a as C,i as w,l as T,o as E,s as D,t as O}from"./query-keys-UETqfytp.js";import{t as k}from"./useMutation-EDFRkn1i.js";import{it as A}from"./entry-DOddwoc0.js";import{n as j,r as M,t as N}from"./card-BOPBuBzD.js";import{n as ne,t as re}from"./download-dRFo5_Wu.js";import{n as P}from"./input-WlyHWeG2.js";import{t as F}from"./select-BfZ3SCTM.js";import{t as ie}from"./switch-yD7D99Lg.js";import{t as I}from"./stack-B1w5BM0u.js";import{t as L}from"./banner-C-7y3VKV.js";import{t as ae}from"./backup-file-gdKIlg8U.js";var oe=e(`archive`,[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]),se=e(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),ce=e(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),R=e(`hard-drive-download`,[[`path`,{d:`M12 2v8`,key:`1q4o3n`}],[`path`,{d:`m16 6-4 4-4-4`,key:`6wukr`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,key:`w68u3i`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M10 18h.01`,key:`h775k`}]]),z=e(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),le=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),B=t(n(),1);function ue(){return k({mutationFn:async({password:e,sections:t,compressed:n,onProgress:r})=>{let i=new URLSearchParams({password:e});t!==void 0&&t.length>0&&i.set(`sections`,t),n===!0&&i.set(`compressed`,`1`);let a=`/backup/export?${i.toString()}`;if(n!==!0)return E(a);let o=await E(a),s=atob(o.bytes),c=Uint8Array.from(s,e=>e.charCodeAt(0));return r?.({loaded:c.byteLength,total:c.byteLength}),c}})}function de(){let e=x();return k({mutationFn:({password:e,scopes:t})=>E(`/backup/delete-all`,{method:`POST`,body:JSON.stringify({password:e,scopes:t})}),onSuccess:async()=>{await e.invalidateQueries()}})}function fe(){let e=x();return k({mutationFn:({password:e,backup:t,tables:n,onProgress:r})=>D(`/backup/import`,JSON.stringify({password:e,backup:t,...n===void 0||n.length===0?{}:{tables:[...n]}}),r),onSuccess:async()=>{await e.invalidateQueries()}})}function pe(){return k({mutationFn:({backup:e})=>E(`/backup/inspect`,{method:`POST`,body:JSON.stringify({backup:e})})})}var V=r();function me({title:e,description:t}){return(0,V.jsxs)(`div`,{className:`mb-6 min-w-0`,children:[(0,V.jsx)(`h3`,{className:`text-body-lg font-bold text-text-primary`,children:e}),(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-secondary`,children:t})]})}function H({icon:e,label:t,description:n,checked:r,onChange:i}){return(0,V.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,V.jsx)(`input`,{type:`checkbox`,checked:r,onChange:i}),(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(e,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,V.jsx)(`strong`,{children:t}),(0,V.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:n})]})]})}function he(e){return e===`providers`?A:e===`proxies`?a:h}function ge({report:e}){let t=Object.entries(e.imported).filter(([,e])=>e>0);return(0,V.jsxs)(I,{gap:`8px`,children:[t.length>0?(0,V.jsxs)(`p`,{className:`text-caption`,children:[`Imported:`,` `,t.map(([e,t])=>`${t} ${e}`).join(`, `)]}):null,e.remapped.length>0?(0,V.jsxs)(`p`,{className:`text-caption text-text-secondary`,children:[`Remapped provider ids: `,e.remapped.join(`, `)]}):null,e.skipped.length>0?(0,V.jsxs)(`div`,{children:[(0,V.jsxs)(`p`,{className:`text-caption text-yellow`,children:[`Skipped (`,e.skipped.length,`) — nothing was guessed:`]}),(0,V.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.skipped.map(e=>(0,V.jsx)(`li`,{children:e},e))})]}):null,e.warnings.length>0?(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`Warnings:`}),(0,V.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.warnings.map(e=>(0,V.jsx)(`li`,{children:e},e))})]}):null]})}function _e({warnings:e}){return e.length===0?null:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,V.jsxs)(`strong`,{children:[`Restore completed with `,e.length,` warning`,e.length===1?``:`s`]}),(0,V.jsx)(`ul`,{className:`mt-2 ml-8`,children:e.map((e,t)=>(0,V.jsxs)(`li`,{children:[e.table?`${e.table}${e.column?`.${e.column}`:``}: `:``,e.reason]},`${e.table??`backup`}:${e.column??`general`}:${t}`))})]})}function U(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function ve(e,t){if(e===null)return t;let n=Math.max((Date.now()-e.startedAt)/1e3,.1),r=U(e.loaded/n);return`${e.total===null?U(e.loaded):`${U(e.loaded)} / ${U(e.total)}`} · ${r}/s`}function W(){let[e,t]=(0,B.useState)(``),[n,r]=(0,B.useState)(null),[i,a]=(0,B.useState)(!0),[c,u]=(0,B.useState)(!1),[f,p]=(0,B.useState)(!0),[m,h]=(0,B.useState)(null),[g,te]=(0,B.useState)(null),[_,y]=(0,B.useState)(null),[b,x]=(0,B.useState)(null),[S,C]=(0,B.useState)(null),[w,E]=(0,B.useState)(null),[D,O]=(0,B.useState)(new Set),[k,A]=(0,B.useState)(null),[j,M]=(0,B.useState)(null),[N,F]=(0,B.useState)(new Set),[oe,se]=(0,B.useState)(null),R=(0,B.useRef)(null),z=ue(),U=fe(),W=de(),ye=pe(),be=e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},G=()=>{r(null),t(``)},xe=()=>{D.size!==0&&(t(``),r(`delete`))},Se=async()=>{if(e.length===0)return;let t=await W.mutateAsync({password:e,scopes:[...D]});O(new Set),G(),l.success(`Selected configuration deleted.`,Object.entries(t.deleted).map(([e,t])=>`${e}: ${t}`).join(` · `))},K=()=>{let t=[...i?[`config`]:[],...c?[`telemetry`]:[]].join(`,`);if(t.length===0){l.error(`Select at least one backup section.`);return}z.mutate({password:e,sections:t,compressed:f,onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))},{onSuccess:e=>{let t=new Date().toISOString().slice(0,19).replace(/[:T]/g,`-`);e instanceof Uint8Array?re(`cartethyia_backup_${t}.json.gz`,e,`application/gzip`):ne(`cartethyia_backup_${t}.json`,JSON.stringify(e,null,2),`application/json`),G(),l.success(`Backup downloaded.`)},onError:e=>l.error(T(e,`Backup export failed.`))})},q=async e=>{te(null),y(null),x(null),C(null),E(null),se(null),M(null),F(new Set),A(e);try{let t=await ae(e),n=await ye.mutateAsync({backup:t});M(n),F(new Set(n.rows.filter(e=>e.supported).map(e=>e.table)))}catch(e){A(null),l.error(`Could not read that backup`,T(e,`The file is not a readable backup.`))}},Ce=e=>{F(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},J=()=>{M(null),A(null),se(null)},we=()=>{k!==null&&N.size!==0&&(t(``),x(null),r(`restore`))},Te=async()=>{let t=k;if(t!==null){x(null);try{let n=await ae(t),r=await U.mutateAsync({password:e,backup:n,tables:[...N],onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))});te(r.restored),y(r.warnings),C(r.report??null),E(r.format),G(),A(null),M(null),l.success(r.warnings.length===0?`Restore complete.`:`Restore completed with warnings.`,r.warnings.length===0?null:`${r.warnings.length} item(s) need attention. See the restore report below.`)}catch(e){let t=T(e,`Backup restore failed.`);x(t),l.error(`Backup restore failed`,t)}}},Ee=g===null?[]:Object.entries(g);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,V.jsxs)(`section`,{"aria-label":`Backup`,className:`min-w-0`,children:[(0,V.jsx)(me,{title:`Export and restore`,description:`Download a JSON snapshot, or restore one you already trust.`}),(0,V.jsxs)(I,{gap:`14px`,children:[(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-2 gap-5 min-w-0 border-0 m-0 p-0 max-medium:grid-cols-1`,children:[(0,V.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Include in the download`}),(0,V.jsx)(H,{icon:d,label:`Account, proxy & settings`,description:`Credentials, API-key hashes, routing, and settings`,checked:i,onChange:()=>a(!i)}),(0,V.jsx)(H,{icon:ce,label:`Telemetry history`,description:`Status, tokens, cost, latency — never prompt bodies`,checked:c,onChange:()=>u(!c)})]}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,V.jsxs)(`span`,{children:[(0,V.jsx)(`strong`,{className:`block text-body`,children:`Highly Compress Backup`}),(0,V.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Makes the download smaller.`})]}),(0,V.jsx)(ie,{checked:f,onChange:p,"aria-label":`Highly Compress Backup`})]}),(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`The file contains provider credentials. Treat it like the database. Prompt and response bodies, health-event history, and console sessions are left out.`}),(0,V.jsxs)(`div`,{className:`mt-auto flex justify-end gap-4`,children:[(0,V.jsx)(s,{variant:`primary`,size:`sm`,onClick:()=>{t(``),r(`download`)},disabled:!i&&!c,icon:(0,V.jsx)(o,{size:13}),children:`Download backup`}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:()=>R.current?.click(),icon:(0,V.jsx)(le,{size:13}),children:`Restore from file`}),(0,V.jsx)(`input`,{ref:R,type:`file`,accept:`application/json,.json,.gz,application/gzip`,className:`sr-only`,onChange:e=>{let t=e.target.files?.[0];t&&q(t),e.target.value=``}})]}),w===null?null:(0,V.jsxs)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:[`Detected format:`,` `,w===`nine_router`?`router export`:`Cartethyia backup`]}),g===null?null:(0,V.jsxs)(L,{tone:`success`,surface:`raised`,live:`status`,children:[(0,V.jsx)(`strong`,{children:`Restore complete`}),Ee.length>0?(0,V.jsx)(`ul`,{children:Ee.map(([e,t])=>(0,V.jsxs)(`li`,{children:[e,`: `,t]},e))}):(0,V.jsx)(`p`,{children:`No rows were imported.`})]}),_===null?null:(0,V.jsx)(_e,{warnings:_}),S===null?null:(0,V.jsx)(ge,{report:S})]})]}),(0,V.jsxs)(`section`,{"aria-label":`Delete data`,className:`min-w-0`,children:[(0,V.jsx)(me,{title:`Delete data`,description:`Removes the scopes you check. Console users, sessions, and audit history stay.`}),(0,V.jsxs)(I,{gap:`12px`,children:[(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-5 min-w-0 border-0 m-0 p-0`,children:[(0,V.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Delete`}),[[`providers`,`Providers`,`Accounts, credentials, tenant models, routing, and account health`],[`proxies`,`Proxies`,`Network pools, pool settings, and pool health`],[`configuration`,`All configuration`,`Providers, proxies, aliases, combos, API keys, CLI tools, and settings`]].map(([e,t,n])=>(0,V.jsx)(H,{icon:he(e),label:t,description:n,checked:D.has(e),onChange:()=>be(e)},e))]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end gap-4 flex-wrap`,children:(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:D.size===0,onClick:xe,children:`Delete selected`})})]})]})]}),(0,V.jsx)(ee,{open:j!==null,onClose:J,title:`Restore from backup`,description:`Choose which parts of this file to restore, then confirm with your console password.`,size:`md`,footer:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:J,children:`Cancel`}),(0,V.jsx)(s,{variant:`primary`,size:`sm`,disabled:N.size===0,onClick:we,children:`Restore now`})]}),children:(0,V.jsx)(I,{gap:`12px`,children:j===null?null:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:j.format===`nine_router`?`Router export — it is converted at restore time, so every table it produces is restored.`:`${j.total} rows · exported ${j.exportedAt||`unknown date`}`}),j.rows.length>0?(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-4 min-w-0 border-0 m-0 p-0`,children:[(0,V.jsx)(`legend`,{className:`mb-3 text-text-secondary text-caption font-semibold`,children:`Restore these tables`}),(0,V.jsxs)(`div`,{className:`flex justify-end gap-4`,children:[(0,V.jsx)(`button`,{type:`button`,className:`text-badge text-accent hover:underline`,onClick:()=>F(new Set(j.rows.filter(e=>e.supported).map(e=>e.table))),children:`Select all`}),(0,V.jsx)(`button`,{type:`button`,className:`text-badge text-text-secondary hover:underline`,onClick:()=>F(new Set),children:`Select none`})]}),j.rows.map(e=>(0,V.jsxs)(`label`,{className:`flex items-start gap-4 px-5 py-4 border border-inner-border rounded-control bg-surface-2 text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,V.jsx)(`input`,{type:`checkbox`,checked:N.has(e.table),disabled:!e.supported,onChange:()=>Ce(e.table)}),(0,V.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,V.jsx)(`strong`,{className:`text-text-primary`,children:e.table}),(0,V.jsxs)(`small`,{className:`text-text-tertiary text-badge`,children:[e.count,` rows · `,e.section,e.supported?``:` · not in the current schema, will be skipped`]})]})]},`${e.section}:${e.table}`))]}):null,oe===null?null:(0,V.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:oe})]})})}),(0,V.jsx)(ee,{open:n!==null,onClose:G,title:n===`delete`?`Confirm deletion`:n===`restore`?`Restore backup`:`Download backup`,description:`The console password is checked again before this runs.`,size:`sm`,footer:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:G,children:`Cancel`}),(0,V.jsx)(s,{variant:n===`delete`?`danger`:`primary`,size:`sm`,loading:z.isPending||U.isPending||W.isPending,disabled:e.length===0||z.isPending||U.isPending||W.isPending,onClick:()=>{h(null),n===`download`?K():n===`restore`?Te():Se()},children:z.isPending?ve(m,`Downloading…`):U.isPending?ve(m,`Uploading…`):W.isPending?`Working…`:n===`delete`?`Delete permanently`:n===`restore`?`Restore`:`Download`})]}),children:(0,V.jsxs)(I,{gap:`10px`,children:[n===`restore`&&b!==null?(0,V.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:b}):null,(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:n===`delete`?`This cannot be undone. The password is verified again before anything is removed.`:n===`restore`?`Restore replaces the tenant configuration in this file. Continue only if the file is trusted.`:`The export is plain JSON and contains provider credentials.`}),(0,V.jsx)(P,{label:`Console password`,type:`password`,value:e,onChange:e=>t(e.target.value),autoComplete:`current-password`,"data-autofocus":!0})]})})]})}function ye(){return b({queryKey:O.settings.diskUsage,queryFn:e=>E(`/data-management/usage`,{signal:S(e)}),...w,staleTime:C.status})}function be(){let e=x();return k({mutationFn:e=>E(`/data-management/reclaim`,{method:`POST`,body:JSON.stringify({action:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function G(){return k({mutationFn:()=>E(`/data-management/flush`,{method:`POST`})})}function xe(){let e=x();return k({mutationFn:()=>E(`/data-management/purge`,{method:`POST`,body:JSON.stringify({target:`health_events`})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function Se(){let e=ye(),t=be(),n=G(),r=xe(),[a,o]=(0,B.useState)(null),[d,f]=(0,B.useState)(!1);if(e.isPending)return(0,V.jsx)(m,{label:`Measuring disk usage…`});if(e.isError||!e.data)return(0,V.jsx)(p,{message:T(e.error,`Failed to measure disk usage`),onRetry:()=>void e.refetch()});let h=e.data,ee=e=>{e!==null&&(o(null),t.mutate(e,{onSuccess:e=>{if(e.deletedFiles===0){l.success(`Nothing to reclaim.`);return}l.success(`Reclaimed ${u(e.reclaimedBytes)} across ${c(e.deletedFiles)} file${e.deletedFiles===1?``:`s`}.`)},onError:e=>l.error(T(e,`Reclaim failed.`))}))},g=h.healthEventCount;return(0,V.jsxs)(I,{gap:`14px`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-4 flex-wrap`,children:[(0,V.jsxs)(`span`,{className:`text-caption text-text-tertiary`,children:[u(h.totalBytes),` on disk across`,` `,c(h.buckets.reduce((e,t)=>e+t.files,0)),` files`]}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(z,{size:14}),onClick:()=>void e.refetch(),disabled:e.isFetching,children:e.isFetching?`Measuring…`:`Refresh`})]}),(0,V.jsxs)(`div`,{className:`settings-bucket-grid`,children:[h.buckets.map(e=>{let n=q(e);return(0,V.jsx)(J,{bucket:e,busy:t.isPending,confirming:n!==null&&a===n,onAsk:()=>o(n),onCancel:()=>o(null),onConfirm:()=>ee(n)},e.id)}),(0,V.jsx)(K,{icon:i,title:`Health & Error Log`,note:g===void 0?`Purging is not offered in this deployment's console composition.`:`${c(g)} recorded transition${g===1?``:`s`} across accounts and pools. Purge clears only this audit trail — account statuses and cooldowns stay as they are, and this cannot be undone.`,testId:`health_events`,children:g===void 0?null:d?(0,V.jsx)(`span`,{className:`flex flex-col gap-3`,children:(0,V.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:()=>f(!1),disabled:r.isPending,children:`Cancel`}),(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:r.isPending,onClick:()=>r.mutate(void 0,{onSuccess:e=>{f(!1),l.success(e.deleted===0?`Health & error log was already empty.`:`Purged ${c(e.deleted)} health event${e.deleted===1?``:`s`}.`)},onError:e=>l.error(T(e,`Purge failed.`))}),children:`Delete`})]})}):(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:r.isPending||g===0,onClick:()=>f(!0),children:`Purge`})}),(0,V.jsx)(K,{icon:R,title:`Flush pending writes`,note:`Write queued telemetry, usage, and health events now instead of waiting for the interval. Nothing is deleted.`,testId:`flush`,children:(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(y,{size:14}),disabled:n.isPending,onClick:()=>n.mutate(void 0,{onSuccess:()=>l.success(`Buffers flushed.`),onError:e=>l.error(T(e,`Flush failed.`))}),children:n.isPending?`Flushing…`:`Flush`})})]}),t.isError?(0,V.jsx)(L,{tone:`danger`,surface:`raised`,live:`status`,children:T(t.error,`Reclaim failed.`)}):null]})}function K({icon:e,title:t,note:n,children:r,testId:i}){return(0,V.jsxs)(`div`,{"data-panel":i,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,V.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(e,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`min-w-0`,children:[(0,V.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:t}),(0,V.jsx)(`span`,{className:`mt-1 block text-caption text-text-tertiary`,children:n})]})]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end pt-5`,children:r})]})}function q(e){return e.id===`payload_frames`?`payload_frames`:e.id===`telemetry_events`?`telemetry_retention`:null}function Ce(e){return e.id===`payload_frames`?se:ce}function J({bucket:e,busy:t,confirming:n,onAsk:r,onCancel:i,onConfirm:a}){let o=q(e),l=e.reclaimableBytes!==null,d=e.reclaimableBytes??0,f=e.reclaimableFiles??0,p=l&&d===0,m=Ce(e);return(0,V.jsxs)(`div`,{"data-bucket":e.id,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,V.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(m,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`min-w-0`,children:[(0,V.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:e.label}),(0,V.jsx)(`span`,{className:`mt-1 block text-lead font-semibold text-text-primary`,children:u(e.bytes)}),(0,V.jsxs)(`span`,{className:`block text-caption text-text-tertiary`,children:[c(e.files),` file`,e.files===1?``:`s`,` · `,e.note]})]})]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end pt-5`,children:o===null?(0,V.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:`Kept — no other copy.`}):n?(0,V.jsxs)(`span`,{className:`flex flex-col gap-3`,children:[(0,V.jsx)(`span`,{className:`text-caption text-text-secondary`,children:l?`Delete ${c(f)} file${f===1?``:`s`}, ${u(d)}?`:`Delete raw event files past the retention window?`}),(0,V.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:i,disabled:t,children:`Cancel`}),(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),onClick:a,disabled:t,children:`Delete`})]})]}):(0,V.jsxs)(`span`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,V.jsx)(`span`,{className:`text-caption text-text-tertiary`,children:l?p?`Clean`:`${u(d)} free`:`Expired events only`}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),onClick:r,disabled:t||p,children:`Reclaim`})]})})]})}function we(){return k({mutationFn:e=>E(`/auth/change-password`,{method:`POST`,body:JSON.stringify(e)})})}var Te=[5,15,30,60,120,300,600],Ee=[5,15,30,60,180,720,1440],De=[1,5,10,25,50,100];function Oe({name:e}){let t={size:16};return e===`privacy`?(0,V.jsx)(f,{...t}):e===`operations`?(0,V.jsx)(y,{...t}):e===`data`?(0,V.jsx)(oe,{...t}):e===`data-management`?(0,V.jsx)(d,{...t}):(0,V.jsx)(te,{...t})}function Y(e,t,n){return(t===null||e.includes(t)?[...e]:[...e,t].sort((e,t)=>e-t)).map(e=>({value:String(e),label:n(e)}))}var ke=[{id:`security`,title:`Security`,description:`Change the password used to sign in to this console.`},{id:`privacy`,title:`Privacy`,description:`What request telemetry stores, and how client addresses are shown.`},{id:`backup`,title:`Backup`,description:`Export or restore this tenant's configuration and history.`},{id:`operations`,title:`Operations`,description:`Routing, admission, request handling, and response shaping for this tenant.`},{id:`data-management`,title:`Data Management`,description:`See what the gateway keeps on disk, reclaim space, and flush queued writes.`}];function X(e){if(e%1440==0){let t=e/1440;return`${t} day${t===1?``:`s`}`}if(e%60==0){let t=e/60;return`${t} hour${t===1?``:`s`}`}return`${e} min`}function Z(e){return`Deployment default (${e})`}function Ae(e){return`${Math.round(e/1048576)} MB`}function Q({label:e,hint:t,labelFor:n,control:r}){return(0,V.jsxs)(`div`,{className:`settings-row`,children:[(0,V.jsxs)(`div`,{className:`settings-row-text`,children:[n?(0,V.jsx)(`label`,{className:`settings-row-label`,htmlFor:n,children:e}):(0,V.jsx)(`span`,{className:`settings-row-label`,children:e}),t?(0,V.jsx)(`p`,{className:`settings-row-hint`,children:t}):null]}),(0,V.jsx)(`div`,{className:`settings-row-control`,children:r})]})}function $({title:e}){return(0,V.jsx)(`p`,{className:`settings-group-head`,children:e})}function je({id:e,title:t,description:n,children:r}){return(0,V.jsxs)(N,{id:e,"aria-label":t,className:`min-w-0`,children:[(0,V.jsx)(M,{title:t,subtitle:n,icon:(0,V.jsx)(Oe,{name:e})}),(0,V.jsx)(j,{className:`flex flex-col gap-0`,children:r})]})}function Me(){let e=_(),t=g(),n=e.data;return e.isPending?(0,V.jsx)(m,{label:`Loading privacy settings…`}):e.isError||!n?(0,V.jsx)(p,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Telemetry payloads`,labelFor:`privacy-payloads`,hint:`Request metadata is always kept. Bodies stay off until you turn them on, and anything captured is redacted and deleted when the Request detail window in Operations runs out.`,control:(0,V.jsx)(F,{"aria-label":`Telemetry payloads`,id:`privacy-payloads`,value:n.telemetryPayloads,onValueChange:e=>t.mutate({telemetryPayloads:e===`full`||e===`metadata`?e:`none`},{onSuccess:()=>l.success(`Payload capture updated`),onError:e=>l.error(T(e,`Could not update payload capture.`))}),options:[{value:`none`,label:`Off — no payload capture`},{value:`metadata`,label:`Metadata — method and headers only`},{value:`full`,label:`Full — redacted bodies`}]})}),n.telemetryPayloads===`full`?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Capture depth`,labelFor:`privacy-payload-depth`,hint:`Size cap for each captured body.`,control:(0,V.jsx)(F,{"aria-label":`Capture depth`,id:`privacy-payload-depth`,value:n.telemetryPayloadDepth,onValueChange:e=>t.mutate({telemetryPayloadDepth:e===`moderate`||e===`maximum`?e:`minimum`},{onSuccess:()=>l.success(`Capture depth updated`),onError:e=>l.error(T(e,`Could not update capture depth.`))}),options:[{value:`minimum`,label:`Minimum — 1 MiB cap`},{value:`moderate`,label:`Moderate — 8 MiB cap`},{value:`maximum`,label:`Maximum — 16 MiB cap`}]})}),n.telemetryPayloadDepth===`minimum`?null:(0,V.jsx)(`div`,{className:`settings-row-banner`,children:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,V.jsx)(`strong`,{children:`High CPU and memory while this is on.`}),` Use it to debug, then switch back to Metadata or Minimum.`]})})]}):null,(0,V.jsx)(Q,{label:`Client IP display`,labelFor:`privacy-ip`,hint:`Raw addresses stay stored and are still written to telemetry. This only changes how they are shown in the console.`,control:(0,V.jsx)(F,{"aria-label":`Client IP display`,id:`privacy-ip`,value:n.privacyMode,onValueChange:e=>t.mutate({privacyMode:e===`full`?`full`:`masked`},{onSuccess:()=>l.success(`IP display updated`),onError:e=>l.error(T(e,`Could not update IP display.`))}),options:[{value:`masked`,label:`Masked — recommended`},{value:`full`,label:`Show full IP`}]})})]})}function Ne(){let e=_(),t=g(),n=e.data;if(e.isPending)return(0,V.jsx)(m,{label:`Loading operational settings…`});if(e.isError||!n)return(0,V.jsx)(p,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()});let r=(e,n)=>{t.mutate(e,{onSuccess:()=>l.success(n),onError:e=>l.error(T(e,`Could not update settings.`))})};return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{title:`Routing`}),(0,V.jsx)(Q,{label:`Ignore cooldowns`,labelFor:`ignore-cooldowns`,hint:`Route to accounts that are cooling down, including ones already parked. Off by default: a cooling account stays out of the rotation until it resets. On dials it anyway, which is what the warning below is about.`,control:(0,V.jsx)(F,{"aria-label":`Ignore cooldowns`,id:`ignore-cooldowns`,value:n.forceDisableCooldown?`on`:`off`,onValueChange:e=>{let t=e===`on`;r({forceDisableCooldown:t},t?`Cooldowns are ignored.`:`Cooldowns are enforced again.`)},options:[{value:`off`,label:`Off — default`},{value:`on`,label:`On`}]})}),n.forceDisableCooldown?(0,V.jsx)(`div`,{className:`settings-row-banner`,children:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,V.jsx)(`strong`,{children:`This may cause admission failure.`}),` A cooled-down account was parked because the upstream refused it, so dialing it anyway reproduces that refusal on every attempt — and if every candidate is cooling, the request fails instead of waiting for a reset. The cooldown is still recorded and still recovered by the sweep, so turning this back off needs no cleanup. Per-model cooldowns are still enforced.`]})}):null,(0,V.jsx)($,{title:`Admission`}),(0,V.jsx)(Q,{label:`Tenant concurrency limit`,labelFor:`tenant-concurrency-limit`,hint:`Ceiling on requests in flight across every key in this tenant at once. Empty means no tenant-wide ceiling — each key is then bounded only by its own limit.`,control:(0,V.jsx)(P,{id:`tenant-concurrency-limit`,"aria-label":`Tenant concurrency limit`,type:`number`,min:`1`,step:`1`,inputMode:`numeric`,placeholder:`No ceiling`,value:n.tenantConcurrencyLimit?.toString()??``,onChange:e=>{let t=e.target.value.trim();if(t===``){r({tenantConcurrencyLimit:null},`Tenant ceiling removed.`);return}let n=Number(t);!Number.isInteger(n)||n<1||r({tenantConcurrencyLimit:n},`Tenant concurrency limit updated.`)}})}),(0,V.jsx)(Q,{label:`Concurrency tolerance`,labelFor:`concurrency-tolerance`,hint:`Slack added above a key's own concurrency limit. The effective ceiling is the key's limit plus this, so a run landing a few over is not refused at the number it was told.`,control:(0,V.jsx)(P,{id:`concurrency-tolerance`,"aria-label":`Concurrency tolerance`,type:`number`,min:`0`,max:`1024`,step:`1`,inputMode:`numeric`,placeholder:`None`,value:n.concurrencyTolerance?.toString()??``,onChange:e=>{let t=e.target.value.trim();if(t===``){r({concurrencyTolerance:null},`Tolerance removed.`);return}let n=Number(t);!Number.isInteger(n)||n<0||n>1024||r({concurrencyTolerance:n},`Concurrency tolerance updated.`)}})}),(0,V.jsx)($,{title:`Request handling`}),(0,V.jsx)(Q,{label:`Upstream timeout`,labelFor:`upstream-timeout`,hint:`5–600 seconds, ${n.defaults.upstreamTimeoutSeconds}s when unset. Applied when the request is dispatched, so it can only shorten a deadline that has already started.`,control:(0,V.jsx)(F,{"aria-label":`Upstream timeout`,id:`upstream-timeout`,value:n.upstreamTimeoutSeconds?.toString()??``,placeholder:Z(`${n.defaults.upstreamTimeoutSeconds} seconds`),onValueChange:e=>r({upstreamTimeoutSeconds:e===``?null:Number(e)},`Upstream timeout updated.`),options:[...Y(Te,n.upstreamTimeoutSeconds,e=>`${e} seconds`),{value:``,label:Z(`${n.defaults.upstreamTimeoutSeconds} seconds`)}]})}),(0,V.jsx)(Q,{label:`Request detail window`,labelFor:`telemetry-window-minutes`,hint:`1–1440 minutes, ${X(n.defaults.telemetryWindowMinutes)} when unset. Controls how long captured payload frames are kept — the same number Data Management reports as what payload frames expire after. Raw request events follow the ${n.defaults.telemetryRetentionDays}-day server retention instead.`,control:(0,V.jsx)(F,{"aria-label":`Request detail window`,id:`telemetry-window-minutes`,value:n.telemetryWindowMinutes?.toString()??``,placeholder:Z(X(n.defaults.telemetryWindowMinutes)),onValueChange:e=>r({telemetryWindowMinutes:e===``?null:Number(e)},`Detail window updated.`),options:[...Y(Ee,n.telemetryWindowMinutes,X),{value:``,label:Z(X(n.defaults.telemetryWindowMinutes))}]})}),(0,V.jsx)(Q,{label:`Max attachment size`,labelFor:`image-clamp-max-bytes`,hint:`Per image, ${Ae(n.defaults.imageClampMaxBytes)} when unset. An oversized attachment is refused before send rather than after the upstream rejects it — a block too large poisons every retry and every replayed turn. Raising this asserts your upstreams accept more; lowering it is the safer direction. Applies to the Messages and Gemini wires.`,control:(0,V.jsx)(F,{"aria-label":`Max attachment size`,id:`image-clamp-max-bytes`,value:n.imageClampMaxBytes===null?``:String(Math.round(n.imageClampMaxBytes/1048576)),placeholder:Z(Ae(n.defaults.imageClampMaxBytes)),onValueChange:e=>r({imageClampMaxBytes:e===``?null:Number(e)*1024*1024},`Attachment size limit updated.`),options:[...Y(De,n.imageClampMaxBytes===null?null:Math.round(n.imageClampMaxBytes/1048576),e=>`${e} MB`),{value:``,label:Z(Ae(n.defaults.imageClampMaxBytes))}]})}),(0,V.jsx)($,{title:`Response shaping`}),(0,V.jsx)(Q,{label:`Thinking normalization`,labelFor:`thinking-normalization`,hint:`Rewrite a provider's native thinking config into the canonical shape on turns where the user is not the final reader. Off by default: the upstream's own config is passed through untouched.`,control:(0,V.jsx)(F,{"aria-label":`Thinking normalization`,id:`thinking-normalization`,value:n.thinkingNormalizationEnabled?`on`:`off`,onValueChange:e=>{let t=e===`on`;r({thinkingNormalizationEnabled:t},t?`Thinking config will be normalized.`:`Upstream thinking config is left as sent.`)},options:[{value:`off`,label:`Off — default`},{value:`on`,label:`On`}]})}),(0,V.jsx)(Q,{label:`Reasoning summary`,labelFor:`responses-reasoning-summary`,hint:`Verbosity of the reasoning summary on the Responses wire, forced even when a request carries no reasoning block. Applies when the routed model is Responses and the client called a Chat surface.`,control:(0,V.jsx)(F,{"aria-label":`Reasoning summary`,id:`responses-reasoning-summary`,value:n.responsesReasoningSummary,onValueChange:e=>r({responsesReasoningSummary:e===`concise`||e===`detailed`?e:`auto`},`Reasoning summary updated.`),options:[{value:`auto`,label:`Auto — follow the request`},{value:`concise`,label:`Concise`},{value:`detailed`,label:`Detailed — default`}]})})]})}function Pe(){let e=we(),[t,n]=(0,B.useState)(``),[r,i]=(0,B.useState)(``),[a,o]=(0,B.useState)(``),[c,l]=(0,B.useState)(null),[u,d]=(0,B.useState)(!1);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Current password`,labelFor:`current-password`,hint:`This is the password for this console, not for any upstream provider. Provider credentials live on each provider in Providers.`,control:(0,V.jsx)(P,{id:`current-password`,"aria-label":`Current password`,type:`password`,value:t,onChange:e=>n(e.target.value),autoComplete:`current-password`})}),(0,V.jsx)(Q,{label:`New password`,labelFor:`new-password`,hint:`Minimum 8 characters. A passphrase is easier to remember and harder to guess.`,control:(0,V.jsx)(P,{id:`new-password`,"aria-label":`New password`,type:`password`,value:r,onChange:e=>i(e.target.value),autoComplete:`new-password`})}),(0,V.jsx)(Q,{label:`Confirm new password`,labelFor:`confirm-password`,control:(0,V.jsx)(P,{id:`confirm-password`,"aria-label":`Confirm new password`,type:`password`,value:a,onChange:e=>o(e.target.value),autoComplete:`new-password`})}),c?(0,V.jsx)(`p`,{role:`alert`,className:`settings-feedback`,"data-tone":`err`,children:c}):null,u?(0,V.jsx)(`p`,{role:`status`,className:`settings-feedback`,"data-tone":`ok`,children:`Password updated.`}):null,(0,V.jsx)(`div`,{className:`settings-actions`,children:(0,V.jsx)(s,{variant:`primary`,size:`sm`,onClick:()=>{if(d(!1),r.length<8){l(`New password must be at least 8 characters.`);return}if(r!==a){l(`New password and confirmation do not match.`);return}l(null),e.mutate({currentPassword:t,newPassword:r},{onSuccess:()=>{d(!0),n(``),i(``),o(``)},onError:e=>l(T(e,`Password change failed.`))})},disabled:e.isPending||!t||!r||!a,children:e.isPending?`Updating…`:`Update password`})})]})}var Fe={security:(0,V.jsx)(Pe,{}),privacy:(0,V.jsx)(Me,{}),operations:(0,V.jsx)(Ne,{}),backup:(0,V.jsx)(W,{}),"data-management":(0,V.jsx)(Se,{})},Ie=[`security`,`privacy`];function Le(){return(0,V.jsxs)(`div`,{className:`settings-page`,children:[(0,V.jsx)(`div`,{className:`settings-grid`,children:Ie.map(e=>{let t=ke.find(t=>t.id===e);return t?(0,V.jsx)(je,{id:t.id,title:t.title,description:t.description,children:Fe[t.id]},e):null})}),ke.filter(e=>!Ie.includes(e.id)).map(e=>(0,V.jsx)(je,{id:e.id,title:e.title,description:e.description,children:Fe[e.id]},e.id))]})}export{Y as boundedOptions,Le as default};