aigetwey 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +125 -211
  3. package/assets/screenshot-accesskey.png +0 -0
  4. package/assets/screenshot-budgets.png +0 -0
  5. package/assets/screenshot-endpoint.png +0 -0
  6. package/dashboard/.next/BUILD_ID +1 -1
  7. package/dashboard/.next/app-path-routes-manifest.json +1 -0
  8. package/dashboard/.next/build-manifest.json +3 -3
  9. package/dashboard/.next/diagnostics/route-bundle-stats.json +55 -38
  10. package/dashboard/.next/fallback-build-manifest.json +3 -3
  11. package/dashboard/.next/prerender-manifest.json +24 -0
  12. package/dashboard/.next/routes-manifest.json +6 -0
  13. package/dashboard/.next/server/app/(console)/combos/page.js.nft.json +1 -1
  14. package/dashboard/.next/server/app/(console)/combos/page_client-reference-manifest.js +1 -1
  15. package/dashboard/.next/server/app/(console)/config/page.js.nft.json +1 -1
  16. package/dashboard/.next/server/app/(console)/config/page_client-reference-manifest.js +1 -1
  17. package/dashboard/.next/server/app/(console)/console/page.js.nft.json +1 -1
  18. package/dashboard/.next/server/app/(console)/console/page_client-reference-manifest.js +1 -1
  19. package/dashboard/.next/server/app/(console)/endpoint/page.js.nft.json +1 -1
  20. package/dashboard/.next/server/app/(console)/endpoint/page_client-reference-manifest.js +1 -1
  21. package/dashboard/.next/server/app/(console)/keys/page/app-paths-manifest.json +3 -0
  22. package/dashboard/.next/server/app/(console)/keys/page/build-manifest.json +18 -0
  23. package/dashboard/.next/server/app/(console)/keys/page/next-font-manifest.json +11 -0
  24. package/dashboard/.next/server/app/(console)/keys/page/react-loadable-manifest.json +1 -0
  25. package/dashboard/.next/server/app/(console)/keys/page/server-reference-manifest.json +4 -0
  26. package/dashboard/.next/server/app/(console)/keys/page.js +15 -0
  27. package/dashboard/.next/server/app/(console)/keys/page.js.map +5 -0
  28. package/dashboard/.next/server/app/(console)/keys/page.js.nft.json +1 -0
  29. package/dashboard/.next/server/app/(console)/keys/page_client-reference-manifest.js +3 -0
  30. package/dashboard/.next/server/app/(console)/page.js.nft.json +1 -1
  31. package/dashboard/.next/server/app/(console)/page_client-reference-manifest.js +1 -1
  32. package/dashboard/.next/server/app/(console)/providers/[id]/page.js.nft.json +1 -1
  33. package/dashboard/.next/server/app/(console)/providers/[id]/page_client-reference-manifest.js +1 -1
  34. package/dashboard/.next/server/app/(console)/providers/page.js.nft.json +1 -1
  35. package/dashboard/.next/server/app/(console)/providers/page_client-reference-manifest.js +1 -1
  36. package/dashboard/.next/server/app/(console)/quota/page.js.nft.json +1 -1
  37. package/dashboard/.next/server/app/(console)/quota/page_client-reference-manifest.js +1 -1
  38. package/dashboard/.next/server/app/(console)/tools/[id]/page.js.nft.json +1 -1
  39. package/dashboard/.next/server/app/(console)/tools/[id]/page_client-reference-manifest.js +1 -1
  40. package/dashboard/.next/server/app/(console)/tools/page.js.nft.json +1 -1
  41. package/dashboard/.next/server/app/(console)/tools/page_client-reference-manifest.js +1 -1
  42. package/dashboard/.next/server/app/(console)/usage/page.js.nft.json +1 -1
  43. package/dashboard/.next/server/app/(console)/usage/page_client-reference-manifest.js +1 -1
  44. package/dashboard/.next/server/app/_global-error/page.js.nft.json +1 -1
  45. package/dashboard/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  46. package/dashboard/.next/server/app/_global-error.html +1 -1
  47. package/dashboard/.next/server/app/_global-error.rsc +1 -1
  48. package/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  49. package/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  50. package/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  51. package/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  52. package/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  53. package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -1
  54. package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  55. package/dashboard/.next/server/app/_not-found.html +1 -1
  56. package/dashboard/.next/server/app/_not-found.rsc +2 -2
  57. package/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  58. package/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  59. package/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  60. package/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  61. package/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  62. package/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  63. package/dashboard/.next/server/app/combos.html +1 -1
  64. package/dashboard/.next/server/app/combos.rsc +5 -5
  65. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos/__PAGE__.segment.rsc +2 -2
  66. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos.segment.rsc +1 -1
  67. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  68. package/dashboard/.next/server/app/combos.segments/_full.segment.rsc +5 -5
  69. package/dashboard/.next/server/app/combos.segments/_head.segment.rsc +1 -1
  70. package/dashboard/.next/server/app/combos.segments/_index.segment.rsc +2 -2
  71. package/dashboard/.next/server/app/combos.segments/_tree.segment.rsc +2 -2
  72. package/dashboard/.next/server/app/config.html +1 -1
  73. package/dashboard/.next/server/app/config.rsc +5 -5
  74. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config/__PAGE__.segment.rsc +2 -2
  75. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config.segment.rsc +1 -1
  76. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  77. package/dashboard/.next/server/app/config.segments/_full.segment.rsc +5 -5
  78. package/dashboard/.next/server/app/config.segments/_head.segment.rsc +1 -1
  79. package/dashboard/.next/server/app/config.segments/_index.segment.rsc +2 -2
  80. package/dashboard/.next/server/app/config.segments/_tree.segment.rsc +2 -2
  81. package/dashboard/.next/server/app/console.html +1 -1
  82. package/dashboard/.next/server/app/console.rsc +5 -5
  83. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console/__PAGE__.segment.rsc +2 -2
  84. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console.segment.rsc +1 -1
  85. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  86. package/dashboard/.next/server/app/console.segments/_full.segment.rsc +5 -5
  87. package/dashboard/.next/server/app/console.segments/_head.segment.rsc +1 -1
  88. package/dashboard/.next/server/app/console.segments/_index.segment.rsc +2 -2
  89. package/dashboard/.next/server/app/console.segments/_tree.segment.rsc +2 -2
  90. package/dashboard/.next/server/app/endpoint.html +1 -1
  91. package/dashboard/.next/server/app/endpoint.rsc +5 -5
  92. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint/__PAGE__.segment.rsc +2 -2
  93. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint.segment.rsc +1 -1
  94. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  95. package/dashboard/.next/server/app/endpoint.segments/_full.segment.rsc +5 -5
  96. package/dashboard/.next/server/app/endpoint.segments/_head.segment.rsc +1 -1
  97. package/dashboard/.next/server/app/endpoint.segments/_index.segment.rsc +2 -2
  98. package/dashboard/.next/server/app/endpoint.segments/_tree.segment.rsc +2 -2
  99. package/dashboard/.next/server/app/index.html +1 -1
  100. package/dashboard/.next/server/app/index.rsc +5 -5
  101. package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp/__PAGE__.segment.rsc +2 -2
  102. package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  103. package/dashboard/.next/server/app/index.segments/_full.segment.rsc +5 -5
  104. package/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  105. package/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
  106. package/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  107. package/dashboard/.next/server/app/keys.html +1 -0
  108. package/dashboard/.next/server/app/keys.meta +16 -0
  109. package/dashboard/.next/server/app/keys.rsc +25 -0
  110. package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp/keys/__PAGE__.segment.rsc +6 -0
  111. package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp/keys.segment.rsc +5 -0
  112. package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  113. package/dashboard/.next/server/app/keys.segments/_full.segment.rsc +25 -0
  114. package/dashboard/.next/server/app/keys.segments/_head.segment.rsc +6 -0
  115. package/dashboard/.next/server/app/keys.segments/_index.segment.rsc +9 -0
  116. package/dashboard/.next/server/app/keys.segments/_tree.segment.rsc +5 -0
  117. package/dashboard/.next/server/app/login/page.js.nft.json +1 -1
  118. package/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
  119. package/dashboard/.next/server/app/login.html +1 -1
  120. package/dashboard/.next/server/app/login.rsc +2 -2
  121. package/dashboard/.next/server/app/login.segments/_full.segment.rsc +2 -2
  122. package/dashboard/.next/server/app/login.segments/_head.segment.rsc +1 -1
  123. package/dashboard/.next/server/app/login.segments/_index.segment.rsc +2 -2
  124. package/dashboard/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  125. package/dashboard/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  126. package/dashboard/.next/server/app/login.segments/login.segment.rsc +1 -1
  127. package/dashboard/.next/server/app/providers.html +1 -1
  128. package/dashboard/.next/server/app/providers.rsc +5 -5
  129. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers/__PAGE__.segment.rsc +2 -2
  130. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers.segment.rsc +1 -1
  131. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  132. package/dashboard/.next/server/app/providers.segments/_full.segment.rsc +5 -5
  133. package/dashboard/.next/server/app/providers.segments/_head.segment.rsc +1 -1
  134. package/dashboard/.next/server/app/providers.segments/_index.segment.rsc +2 -2
  135. package/dashboard/.next/server/app/providers.segments/_tree.segment.rsc +2 -2
  136. package/dashboard/.next/server/app/quota.html +1 -1
  137. package/dashboard/.next/server/app/quota.rsc +5 -5
  138. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota/__PAGE__.segment.rsc +2 -2
  139. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota.segment.rsc +1 -1
  140. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  141. package/dashboard/.next/server/app/quota.segments/_full.segment.rsc +5 -5
  142. package/dashboard/.next/server/app/quota.segments/_head.segment.rsc +1 -1
  143. package/dashboard/.next/server/app/quota.segments/_index.segment.rsc +2 -2
  144. package/dashboard/.next/server/app/quota.segments/_tree.segment.rsc +2 -2
  145. package/dashboard/.next/server/app/tools.html +1 -1
  146. package/dashboard/.next/server/app/tools.rsc +5 -5
  147. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools/__PAGE__.segment.rsc +2 -2
  148. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools.segment.rsc +1 -1
  149. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
  150. package/dashboard/.next/server/app/tools.segments/_full.segment.rsc +5 -5
  151. package/dashboard/.next/server/app/tools.segments/_head.segment.rsc +1 -1
  152. package/dashboard/.next/server/app/tools.segments/_index.segment.rsc +2 -2
  153. package/dashboard/.next/server/app/tools.segments/_tree.segment.rsc +2 -2
  154. package/dashboard/.next/server/app-paths-manifest.json +1 -0
  155. package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js +1 -1
  156. package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js.map +1 -1
  157. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__006jvp_._.js +3 -0
  158. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__006jvp_._.js.map +1 -0
  159. package/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__0x-617o._.js → [root-of-the-server]__1eeunp8._.js} +2 -2
  160. package/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__0x-617o._.js.map → [root-of-the-server]__1eeunp8._.js.map} +1 -1
  161. package/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__09pxn-h._.js → [root-of-the-server]__1t7z0yw._.js} +2 -2
  162. package/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__09pxn-h._.js.map → [root-of-the-server]__1t7z0yw._.js.map} +1 -1
  163. package/dashboard/.next/server/chunks/ssr/_0p90gyy._.js +3 -0
  164. package/dashboard/.next/server/chunks/ssr/_0p90gyy._.js.map +1 -0
  165. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_keys_page_actions_1--ho2b.js +3 -0
  166. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_keys_page_actions_1--ho2b.js.map +1 -0
  167. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0-auga4.js +4 -0
  168. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0-auga4.js.map +1 -0
  169. package/dashboard/.next/server/chunks/ssr/src_13mfqac._.js +3 -0
  170. package/dashboard/.next/server/chunks/ssr/src_13mfqac._.js.map +1 -0
  171. package/dashboard/.next/server/chunks/ssr/src_16zsfd3._.js +3 -0
  172. package/dashboard/.next/server/chunks/ssr/src_16zsfd3._.js.map +1 -0
  173. package/dashboard/.next/server/chunks/ssr/src_components_0-kkrr9._.js +3 -0
  174. package/dashboard/.next/server/chunks/ssr/src_components_0-kkrr9._.js.map +1 -0
  175. package/dashboard/.next/server/chunks/ssr/src_components_0dgasfb._.js +3 -0
  176. package/dashboard/.next/server/chunks/ssr/src_components_0dgasfb._.js.map +1 -0
  177. package/dashboard/.next/server/chunks/ssr/src_components_0q5pldo._.js +3 -0
  178. package/dashboard/.next/server/chunks/ssr/src_components_0q5pldo._.js.map +1 -0
  179. package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js +1 -1
  180. package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js.map +1 -1
  181. package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js +1 -1
  182. package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js.map +1 -1
  183. package/dashboard/.next/server/chunks/ssr/src_components_11dtfns._.js +3 -0
  184. package/dashboard/.next/server/chunks/ssr/src_components_11dtfns._.js.map +1 -0
  185. package/dashboard/.next/server/chunks/ssr/src_components_1e6kjgr._.js +3 -0
  186. package/dashboard/.next/server/chunks/ssr/src_components_1e6kjgr._.js.map +1 -0
  187. package/dashboard/.next/server/chunks/ssr/src_components_1eg_jit._.js +3 -0
  188. package/dashboard/.next/server/chunks/ssr/src_components_1eg_jit._.js.map +1 -0
  189. package/dashboard/.next/server/chunks/ssr/src_components_1pu8z89._.js +3 -0
  190. package/dashboard/.next/server/chunks/ssr/src_components_1pu8z89._.js.map +1 -0
  191. package/dashboard/.next/server/chunks/ssr/src_components_1z4akp5._.js +3 -0
  192. package/dashboard/.next/server/chunks/ssr/src_components_1z4akp5._.js.map +1 -0
  193. package/dashboard/.next/server/chunks/ssr/src_components_KeyManager_tsx_0r7iyz8._.js +3 -0
  194. package/dashboard/.next/server/chunks/ssr/src_components_KeyManager_tsx_0r7iyz8._.js.map +1 -0
  195. package/dashboard/.next/server/chunks/ssr/src_components_ProviderManager_tsx_09d2dzw._.js +3 -0
  196. package/dashboard/.next/server/chunks/ssr/src_components_ProviderManager_tsx_09d2dzw._.js.map +1 -0
  197. package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js +1 -1
  198. package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js.map +1 -1
  199. package/dashboard/.next/server/middleware-build-manifest.js +3 -3
  200. package/dashboard/.next/server/next-font-manifest.js +1 -1
  201. package/dashboard/.next/server/next-font-manifest.json +4 -0
  202. package/dashboard/.next/server/pages/404.html +1 -1
  203. package/dashboard/.next/server/pages/500.html +1 -1
  204. package/dashboard/.next/static/chunks/0-qqj0_fg6ef0.js +1 -0
  205. package/dashboard/.next/static/chunks/0347y27liw05t.js +1 -0
  206. package/dashboard/.next/static/chunks/0iv69e64f1ywa.css +3 -0
  207. package/dashboard/.next/static/chunks/0mou1p6uwiu19.js +1 -0
  208. package/dashboard/.next/static/chunks/0pf-u__m67vld.js +1 -0
  209. package/dashboard/.next/static/chunks/0zdns9uijk264.js +1 -0
  210. package/dashboard/.next/static/chunks/19nfww990cvv7.js +1 -0
  211. package/dashboard/.next/static/chunks/1t87-rpltg53e.js +1 -0
  212. package/dashboard/.next/static/chunks/1wn1c2w4ibyg_.js +1 -0
  213. package/dashboard/.next/static/chunks/29bgf5j_v6h2z.js +1 -0
  214. package/dashboard/.next/static/chunks/2uvgdots59tjl.js +1 -0
  215. package/dashboard/.next/static/chunks/3chs_cdkdx2h9.js +1 -0
  216. package/dashboard/.next/static/chunks/3y0b8yet0vgwr.js +1 -0
  217. package/dashboard/.next/trace +1 -1
  218. package/dashboard/.next/trace-build +1 -1
  219. package/dashboard/.next/types/routes.d.ts +2 -1
  220. package/dashboard/.next/types/validator.ts +9 -0
  221. package/dashboard/package-lock.json +56 -0
  222. package/dashboard/package.json +3 -0
  223. package/dashboard/src/app/(console)/keys/page.tsx +5 -0
  224. package/dashboard/src/app/api/cli-detect/[tool]/route.ts +0 -1
  225. package/dashboard/src/app/globals.css +1 -0
  226. package/dashboard/src/components/Badge.tsx +2 -1
  227. package/dashboard/src/components/EndpointView.tsx +49 -373
  228. package/dashboard/src/components/KeyManager.tsx +252 -0
  229. package/dashboard/src/components/KeyReveal.tsx +11 -11
  230. package/dashboard/src/components/KeyScopeModal.tsx +184 -0
  231. package/dashboard/src/components/LogTable.tsx +1 -1
  232. package/dashboard/src/components/ProviderManager.tsx +136 -44
  233. package/dashboard/src/components/Rail.tsx +2 -1
  234. package/dashboard/src/components/ToolDetail.tsx +0 -1
  235. package/dashboard/src/components/TopBar.tsx +102 -28
  236. package/dashboard/src/lib/client.ts +2 -0
  237. package/dist/appDirs.js +11 -0
  238. package/dist/appDirs.js.map +1 -0
  239. package/dist/cli.js +35 -7
  240. package/dist/cli.js.map +1 -1
  241. package/dist/config.js +14 -0
  242. package/dist/config.js.map +1 -1
  243. package/dist/core/handler.js +3 -3
  244. package/dist/core/handler.js.map +1 -1
  245. package/dist/db.js +18 -11
  246. package/dist/db.js.map +1 -1
  247. package/dist/headroom/process.js +2 -1
  248. package/dist/headroom/process.js.map +1 -1
  249. package/dist/routes/admin.js +8 -1
  250. package/dist/routes/admin.js.map +1 -1
  251. package/dist/server.js +4 -4
  252. package/dist/server.js.map +1 -1
  253. package/dist/stream/anthropic-stream.js +6 -3
  254. package/dist/stream/anthropic-stream.js.map +1 -1
  255. package/package.json +1 -1
  256. package/src/appDirs.ts +12 -0
  257. package/src/cli.ts +36 -7
  258. package/src/config.ts +12 -0
  259. package/src/core/handler.ts +3 -3
  260. package/src/db.ts +27 -9
  261. package/src/headroom/process.ts +2 -1
  262. package/src/routes/admin.ts +9 -0
  263. package/src/server.ts +3 -3
  264. package/src/stream/anthropic-stream.ts +6 -3
  265. package/assets/screenshot.png +0 -0
  266. package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js +0 -3
  267. package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js.map +0 -1
  268. package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js +0 -3
  269. package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js.map +0 -1
  270. package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js +0 -3
  271. package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js.map +0 -1
  272. package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js +0 -3
  273. package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js.map +0 -1
  274. package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js +0 -3
  275. package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js.map +0 -1
  276. package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js +0 -3
  277. package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js.map +0 -1
  278. package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js +0 -3
  279. package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js.map +0 -1
  280. package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js +0 -3
  281. package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js.map +0 -1
  282. package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js +0 -3
  283. package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js.map +0 -1
  284. package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js +0 -3
  285. package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js.map +0 -1
  286. package/dashboard/.next/static/chunks/063d_vdu_m-g_.js +0 -1
  287. package/dashboard/.next/static/chunks/0tq5u12liycmg.js +0 -1
  288. package/dashboard/.next/static/chunks/1-r9spn081_wo.js +0 -1
  289. package/dashboard/.next/static/chunks/13824732j7-dk.js +0 -1
  290. package/dashboard/.next/static/chunks/16vbdc0g5xea0.js +0 -1
  291. package/dashboard/.next/static/chunks/22r7w355mazs8.js +0 -1
  292. package/dashboard/.next/static/chunks/2zho1fpijk0fu.js +0 -1
  293. package/dashboard/.next/static/chunks/30uw-uiehs39o.js +0 -1
  294. package/dashboard/.next/static/chunks/3mhsmb2ks1vev.js +0 -1
  295. package/dashboard/.next/static/chunks/3nrz6v06gppob.js +0 -1
  296. package/dashboard/.next/static/chunks/452cgglyyo7hp.css +0 -3
  297. /package/dashboard/.next/static/{l0QkSM6jT0jiUc4m4dh6K → WxqdtupTIrBh47rvaXxLB}/_buildManifest.js +0 -0
  298. /package/dashboard/.next/static/{l0QkSM6jT0jiUc4m4dh6K → WxqdtupTIrBh47rvaXxLB}/_clientMiddlewareManifest.js +0 -0
  299. /package/dashboard/.next/static/{l0QkSM6jT0jiUc4m4dh6K → WxqdtupTIrBh47rvaXxLB}/_ssgManifest.js +0 -0
@@ -1,3 +0,0 @@
1
- module.exports=[8378,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(56173),e=a.i(2693),f=a.i(85732),g=a.i(7078),h=a.i(93026);function i({masked:a,reveal:d,className:e,align:f="inline"}){let[g,j]=(0,c.useState)(null),[k,l]=(0,c.useState)(!1),[m,n]=(0,c.useState)(!1),[o,p]=(0,c.useState)(!1);async function q(){if(k)return void l(!1);if(null===g){n(!0);let a=await d();if(n(!1),null===a)return;j(a)}l(!0)}let r=k&&null!==g?g:a;return(0,b.jsxs)("span",{className:`flex min-w-0 items-center gap-1.5${e?` ${e}`:""}`,children:[(0,b.jsx)("span",{className:`tnum truncate text-[12.5px] text-text${"right"===f?" flex-1":""}`,children:r}),k&&null!==g&&(0,b.jsx)("button",{type:"button",onClick:()=>{navigator.clipboard.writeText(g),p(!0),setTimeout(()=>p(!1),1200)},className:"flex-none text-text-subtle transition-colors hover:text-text","aria-label":"Copy key",children:(0,b.jsx)(h.Icon,{name:o?"check":"content_copy",size:14})}),(0,b.jsx)("button",{type:"button",onClick:q,disabled:m,className:"flex-none text-text-subtle transition-colors hover:text-text disabled:opacity-40","aria-label":k?"Hide key":"Show key",children:(0,b.jsx)(h.Icon,{name:m?"hourglass_empty":k?"visibility_off":"visibility",size:15})})]})}var j=a.i(58918),k=a.i(47444),l=a.i(73858);let m=["off","lite","full","ultra"],n=a=>`rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${a?"bg-accent/12 text-accent":"bg-surface-2 text-text-muted hover:text-text"}`,o={"24h":864e5,"7day":6048e5,"30day":2592e6};function p({ep:a,hr:i,refresh:j}){let k=a.headroom,[l,m]=(0,c.useState)(k.url),[n,o]=(0,c.useState)(""),[q,r]=(0,c.useState)(""),[t,u]=(0,c.useState)(null);async function v(a,b){o(a),r(""),u(null);let c=await b();o(""),c.ok||r(c.error??"action failed"),await j()}async function w(){o("check"),r(""),u(null);let a=await d.adminApi.headroomStatus();(o(""),await j(),a.ok&&a.data)?u(a.data.running?{ok:!0,text:`proxy is up at ${a.data.url}`}:{ok:!1,text:`no proxy responding at ${a.data.url}`}):u({ok:!1,text:a.error??"could not reach the gateway"})}return(0,c.useEffect)(()=>m(k.url),[k.url]),(0,b.jsx)(f.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(f.CardTitle,{title:"Headroom",sub:"external context-compression proxy"}),children:(0,b.jsxs)("div",{className:"space-y-4",children:[(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-[12px]",children:[(0,b.jsx)(e.Badge,{tone:i?.installed?"live":"neutral",children:i?.installed?"installed":"not installed"}),(0,b.jsx)(e.Badge,{tone:i?.running?"live":"warn",children:i?.running?"proxy running":"proxy down"}),(0,b.jsx)(e.Badge,{tone:i?.python?"info":"neutral",children:i?.python?`python ${i.python}`:"no python ≥3.10"}),i?.managedPid?(0,b.jsxs)("span",{className:"tnum text-text-subtle",children:["pid ",i.managedPid]}):null]}),(0,b.jsx)(s,{label:"Enable headroom",desc:"Compress the full context through the proxy before each request.",on:k.enabled,busy:"enable"===n,disabled:!i?.running&&!k.enabled,onChange:a=>v("enable",()=>d.adminApi.setHeadroom({enabled:a}))}),(0,b.jsx)(s,{label:"Compress user messages",desc:"Also squeeze user turns, not just tool/assistant context.",on:k.compress_user_messages,busy:"cum"===n,onChange:a=>v("cum",()=>d.adminApi.setHeadroom({compress_user_messages:a}))}),(0,b.jsxs)("div",{className:"flex items-end gap-2",children:[(0,b.jsxs)("div",{className:"flex-1",children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Proxy URL"}),(0,b.jsx)(g.Input,{value:l,onChange:a=>m(a.target.value),placeholder:"http://localhost:8787",className:"font-mono text-[12.5px]"})]}),(0,b.jsx)(g.Button,{variant:"ghost",disabled:l.trim()===k.url||"url"===n,onClick:()=>v("url",()=>d.adminApi.setHeadroom({url:l.trim()})),children:"Save URL"})]}),(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,b.jsxs)(g.Button,{disabled:!i?.canStart||i?.running||!!n,onClick:async()=>{await v("start",()=>d.adminApi.headroomStart()),await w()},children:[(0,b.jsx)(h.Icon,{name:"start"===n?"sync":"play_arrow",size:16,className:"start"===n?"animate-spin":""}),"start"===n?"Starting…":"Start proxy"]}),(0,b.jsxs)(g.Button,{variant:"danger",disabled:!i?.managedPid||"stop"===n,onClick:()=>v("stop",()=>d.adminApi.headroomStop()),children:[(0,b.jsx)(h.Icon,{name:"stop",size:16})," Stop"]}),(0,b.jsxs)(g.Button,{variant:"ghost",disabled:"check"===n,onClick:w,children:[(0,b.jsx)(h.Icon,{name:"sync",size:16})," ","check"===n?"Checking…":"Check"]}),i&&!i.installed&&(0,b.jsxs)("span",{className:"text-[11px] text-text-subtle",children:["Headroom isn’t installed. Get it from"," ",(0,b.jsx)("a",{href:"https://github.com/chopratejas/headroom",target:"_blank",rel:"noreferrer",className:"text-accent hover:underline",children:"chopratejas/headroom"})," ","(needs Python ≥ 3.10):"," ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"pipx install git+https://github.com/chopratejas/headroom"})," ","— then re-open this page."]}),i?.installed&&!i.localUrl&&(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"URL isn’t loopback — start that proxy yourself."})]}),q&&(0,b.jsx)("p",{className:"text-[12px] text-danger",children:q}),t&&(0,b.jsxs)("p",{className:`flex items-center gap-1 text-[12px] ${t.ok?"text-success":"text-danger"}`,children:[(0,b.jsx)(h.Icon,{name:t.ok?"check_circle":"error",size:14})," ",t.text]})]})})}function q({name:a,value:d,onClose:e}){let[f,i]=(0,c.useState)(!1);return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:e,children:(0,b.jsxs)("div",{className:"w-full max-w-md rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-1 flex items-center gap-2",children:[(0,b.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-accent",children:(0,b.jsx)(h.Icon,{name:"key",size:16})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Key created"})]}),(0,b.jsxs)("p",{className:"mb-3 text-[12px] text-text-muted",children:["Copy ",(0,b.jsx)("span",{className:"text-text",children:a})," now. You can reveal it again later from this page."]}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(d),i(!0),setTimeout(()=>i(!1),1500)},className:"flex w-full items-center justify-between gap-2 rounded-brand border border-border-subtle bg-bg px-3 py-2.5 text-left hover:border-text-subtle",children:[(0,b.jsx)("span",{className:"tnum truncate text-[12.5px] text-text",children:d}),(0,b.jsx)(h.Icon,{name:f?"check":"content_copy",size:15})]}),(0,b.jsx)("div",{className:"mt-4 flex justify-end",children:(0,b.jsx)(g.Button,{onClick:e,children:"Done"})})]})})}function r({label:a,value:d}){let[e,f]=(0,c.useState)(!1);return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,b.jsx)("span",{className:"text-text-subtle",children:a}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(d),f(!0),setTimeout(()=>f(!1),1200)},className:"flex items-center gap-1.5 rounded-brand border border-border-subtle px-2.5 py-1 tnum text-[12.5px] text-text hover:border-text-subtle",children:[d,(0,b.jsx)(h.Icon,{name:e?"check":"content_copy",size:13})]})]})}function s({label:a,desc:c,on:d,busy:e,disabled:f,onChange:g}){let h=e||f;return(0,b.jsxs)("div",{className:`flex items-center justify-between gap-4 ${h?"opacity-40":""}`,children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"text-[13px] font-semibold text-text",children:a}),(0,b.jsx)("div",{className:"text-[12px] text-text-muted",children:c})]}),(0,b.jsx)("button",{disabled:h,onClick:()=>g(!d),className:`relative h-6 w-11 flex-none rounded-full transition-colors ${d?"bg-accent":"bg-surface-3"}`,"aria-pressed":d,children:(0,b.jsx)("span",{className:`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-bg transition-transform ${d?"translate-x-5":"translate-x-0"}`})})]})}function t({label:a,desc:c,value:d,busy:f,onChange:g}){return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:a}),"off"!==d&&(0,b.jsx)(e.Badge,{tone:"info",children:d})]}),(0,b.jsx)("div",{className:"text-[12px] text-text-muted",children:c})]}),(0,b.jsx)("div",{className:"flex flex-none items-center gap-1 rounded-full border border-border bg-surface p-1",children:m.map(a=>(0,b.jsx)("button",{disabled:f,onClick:()=>g(a),className:`rounded-full px-2.5 py-1 text-[11.5px] font-medium transition-colors ${d===a?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:a},a))})]})}a.s(["EndpointView",0,function(){let[a,e]=(0,c.useState)(null),[m,u]=(0,c.useState)(""),[v,w]=(0,c.useState)(""),[x,y]=(0,c.useState)(""),[z,A]=(0,c.useState)(null),[B,C]=(0,c.useState)(null),[D,E]=(0,c.useState)(null),[F,G]=(0,c.useState)(null),[H,I]=(0,c.useState)(""),[J,K]=(0,c.useState)([]),[L,M]=(0,c.useState)(null),[N,O]=(0,c.useState)([]),[P,Q]=(0,c.useState)(""),[R,S]=(0,c.useState)("never"),[T,U]=(0,c.useState)(""),[V,W]=(0,c.useState)(""),[X,Y]=(0,c.useState)("30day"),[Z,$]=(0,c.useState)({}),[_,aa]=(0,c.useState)(!1),ab=(0,c.useCallback)(async()=>{let a=await d.adminApi.endpoint();a.ok?(u(""),e(a.data)):u(a.error??"could not reach the gateway")},[]),ac=(0,c.useCallback)(async()=>{let a=await d.adminApi.headroomStatus();a.ok&&E(a.data)},[]);if((0,c.useEffect)(()=>{ab(),ac(),(async()=>{try{let a=await fetch("/api/gw/admin/config");if(!a.ok)return;let b=await a.json(),c=[];for(let a of(b.models.length&&c.push({label:"Combos",items:b.models.map(a=>({value:a.alias,label:a.alias}))}),b.providers))a.models.length&&c.push({label:a.id,items:a.models.map(b=>({value:`${a.id}/${b.id}`,label:`${a.id}/${b.id}`}))});K(c)}catch{}})(),d.adminApi.budgets().then(a=>{if(!a.ok||!a.data)return;let b={};for(let c of a.data.budgets)"key"===c.scope.type&&(b[c.scope.id]={limit:c.limit,window:c.window});$(b)})},[ab,ac]),m)return(0,b.jsx)(j.Empty,{children:m});if(!a)return(0,b.jsx)(j.Empty,{children:"Loading…"});let ad=`http://127.0.0.1:${a.port}`;async function ae(a,b){w(a);let c=await b();w(""),c.ok?(u(""),await ab()):u(c.error??"action failed")}async function af(a,b){let c=(a||"Gateway key").trim();w("genkey");let e=await d.adminApi.addServerKey(b,c);(w(""),e.ok)?(u(""),y(""),A({key:b,name:c}),await ab()):u(e.error??"could not add key")}return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6",children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Endpoint & Key"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Gateway address, client keys, and the token-saver toggles."})]}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,b.jsxs)(f.RichCard,{header:(0,b.jsx)(f.CardTitle,{title:"Gateway URL",sub:"one endpoint for every client"}),children:[(0,b.jsx)("div",{className:"text-[13px]",children:(0,b.jsx)(r,{label:"Gateway URL",value:ad})}),(0,b.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["One gateway, both formats. Anthropic clients (Claude Code) use it as-is; OpenAI clients (opencode, Cursor, Codex) append ",(0,b.jsx)("span",{className:"tnum",children:"/v1"}),". The ",(0,b.jsx)("span",{className:"text-text-muted",children:"CLI Tools"})," ","page has copy-ready env per tool."]})]}),(0,b.jsxs)(f.RichCard,{header:(0,b.jsx)(f.CardTitle,{title:"Gateway keys",sub:`${a.keys.length} configured`}),children:[0===a.keys.length?(0,b.jsx)(j.Empty,{children:"No keys — auth is DISABLED (localhost only). Generate one below."}):(0,b.jsx)("div",{className:"space-y-1.5",children:a.keys.map((a,c)=>F===c?(0,b.jsxs)("div",{className:"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5",children:[(0,b.jsx)(g.Input,{value:H,onChange:a=>I(a.target.value),placeholder:"key name (e.g. Claude Code)"}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>G(null),children:"Cancel"}),(0,b.jsx)(g.Button,{disabled:v===`editkey${c}`,onClick:()=>ae(`editkey${c}`,async()=>{let a=await d.adminApi.editServerKey(c,H.trim());return a.ok&&G(null),a}),children:"Save"})]})]},c):(0,b.jsxs)("div",{className:"space-y-0 rounded-brand border border-border-subtle",children:[(0,b.jsxs)("div",{className:"flex items-center justify-between gap-2 px-3 py-2",children:[(0,b.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[a.name&&(0,b.jsx)("span",{className:"text-[12px] font-semibold text-text-muted",children:a.name}),(0,b.jsx)(i,{masked:a.key,reveal:async()=>{let a=await d.adminApi.revealServerKey(c);return a.ok?a.data?.key??null:null}}),(0,b.jsxs)("div",{className:"mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-text-subtle",children:[(0,b.jsx)("span",{children:a.models?.length?`${a.models.length} model${a.models.length>1?"s":""}`:"all models"}),(0,b.jsx)("span",{children:"·"}),(0,b.jsx)("span",{children:a.rpm?`${a.rpm}/min`:"no rate limit"}),(0,b.jsx)("span",{children:"·"}),(0,b.jsx)("span",{children:a.expires?Date.now()>a.expires?(0,b.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${j.fmt.date(a.expires)}`:"no expiry"})]})]}),(0,b.jsxs)("div",{className:"flex flex-none items-center gap-1",children:[(0,b.jsx)("button",{onClick:()=>{M(c),O(a.models??[]),Q(a.rpm?String(a.rpm):""),S(a.expires?"keep":"never"),U("");let b=Z[a.fingerprint];W(b?String(b.limit):""),Y(b?.window??"30day")},className:"text-text-subtle hover:text-text","aria-label":"Edit key scope",title:"Model allowlist + rate limit + budget + expiry",children:(0,b.jsx)(h.Icon,{name:"tune",size:15})}),(0,b.jsx)("button",{onClick:()=>{G(c),I(a.name??"")},className:"text-text-subtle hover:text-text","aria-label":"Rename key",title:"Rename key",children:(0,b.jsx)(h.Icon,{name:"edit",size:15})}),(0,b.jsx)("button",{onClick:()=>C({i:c,label:a.name||a.key}),className:"text-text-subtle hover:text-danger","aria-label":"Remove key",children:(0,b.jsx)(h.Icon,{name:"delete",size:16})})]})]}),L===c&&(0,b.jsxs)("div",{className:"space-y-2 border-t border-border-subtle bg-accent-soft/40 px-3 py-2.5",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Allowed models"}),(0,b.jsx)("div",{className:"flex flex-wrap items-center gap-1.5",children:0===N.length?(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:"All models (unrestricted)"}):N.map(a=>(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded border border-accent bg-accent-soft px-2 py-0.5 text-[12px] text-accent",children:[(0,b.jsx)("span",{className:"tnum",children:a}),(0,b.jsx)("button",{onClick:()=>O(b=>b.filter(b=>b!==a)),className:"hover:text-danger","aria-label":`Remove ${a}`,children:(0,b.jsx)(h.Icon,{name:"close",size:12})})]},a))}),(0,b.jsxs)(g.Button,{type:"button",variant:"ghost",className:"mt-1.5",onClick:()=>aa(!0),children:[(0,b.jsx)(h.Icon,{name:"add",size:15})," Pick models"]})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Rate limit"}),(0,b.jsx)(g.Input,{inputMode:"numeric",value:P,onChange:a=>Q(a.target.value.replace(/[^\d]/g,"")),placeholder:"req/min (blank = unlimited)"})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Access expiry"}),a.expires&&(0,b.jsxs)("div",{className:"mb-1.5 text-[11px] text-text-subtle",children:["currently ",Date.now()>a.expires?(0,b.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${j.fmt.date(a.expires)}`]}),(0,b.jsx)("div",{className:"flex flex-wrap gap-1",children:(a.expires?["keep","never","24h","7day","30day","custom"]:["never","24h","7day","30day","custom"]).map(a=>(0,b.jsx)("button",{type:"button",onClick:()=>S(a),className:n(R===a),children:"never"===a?"no expiry":a},a))}),"custom"===R&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,b.jsx)(g.Input,{inputMode:"numeric",value:T,onChange:a=>U(a.target.value.replace(/[^\d]/g,"")),placeholder:"days",className:"w-24"}),(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"days from now"})]})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Spend cap (USD)"}),(0,b.jsx)(g.Input,{inputMode:"decimal",value:V,onChange:a=>W(a.target.value.replace(/[^\d.]/g,"")),placeholder:"USD (blank = no cap)"}),V&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"resets every"}),["5h","24h","7day","30day"].map(a=>(0,b.jsx)("button",{type:"button",onClick:()=>Y(a),className:n(X===a),children:a},a))]})]}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>M(null),children:"Cancel"}),(0,b.jsx)(g.Button,{disabled:v===`scope${c}`,onClick:()=>ae(`scope${c}`,async()=>{let b="keep"===R?void 0:"never"===R?null:"custom"===R?T?Date.now()+864e5*Number(T):null:Date.now()+o[R],e=await d.adminApi.setServerKeyScope(c,{models:N,rpm:P?Number(P):null,expires:b});if(!e.ok)return e;let f=V?Number(V):0;return f>0?await d.adminApi.setBudget({scope:{type:"key",id:a.fingerprint},unit:"usd",limit:f,window:X}):Z[a.fingerprint]&&await d.adminApi.clearBudget(`key:${a.fingerprint}`),M(null),e}),children:"Save"})]})]})]},c))}),(0,b.jsxs)("div",{className:"mt-3 space-y-2",children:[(0,b.jsxs)("div",{className:"flex gap-2",children:[(0,b.jsx)(g.Input,{value:x,onChange:a=>y(a.target.value),placeholder:"key name (e.g. Claude Code)",className:"flex-1"}),(0,b.jsxs)(g.Button,{disabled:"genkey"===v,onClick:()=>{let a,b;return af(x,(a=new Uint8Array(24),crypto.getRandomValues(a),b=Array.from(a,a=>a.toString(16).padStart(2,"0")).join(""),`aig-${b}`))},children:[(0,b.jsx)(h.Icon,{name:"add",size:16})," ","genkey"===v?"Adding…":"Add key"]})]}),(0,b.jsx)("p",{className:"text-[11px] text-text-subtle",children:"Name it, then click Add key — a key is generated and shown once. Configure its limits after."})]})]}),(0,b.jsx)(f.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(f.CardTitle,{title:"Token savers",sub:"applied to every request before routing"}),children:(0,b.jsxs)("div",{className:"space-y-4",children:[(0,b.jsx)(s,{label:"RTK",desc:"Compress bulky tool_result blocks (diffs, grep, listings) in the request.",on:a.rtk,busy:"rtk"===v,onChange:a=>ae("rtk",()=>d.adminApi.setRtk(a))}),(0,b.jsx)(t,{label:"Caveman",desc:"Terser model output — drops filler, keeps substance.",value:a.caveman,busy:"caveman"===v,onChange:a=>ae("caveman",()=>d.adminApi.setCaveman(a))}),(0,b.jsx)(t,{label:"Ponytail",desc:"Minimal, YAGNI code style — deletion over addition.",value:a.ponytail,busy:"ponytail"===v,onChange:a=>ae("ponytail",()=>d.adminApi.setPonytail(a))})]})}),(0,b.jsx)(p,{ep:a,hr:D,refresh:async()=>{await ab(),await ac()}})]}),z&&(0,b.jsx)(q,{name:z.name,value:z.key,onClose:()=>A(null)}),B&&(0,b.jsx)(l.ConfirmModal,{title:"Remove gateway key",message:`Delete "${B.label}"? Any client using this key stops working immediately.`,confirmLabel:"Remove",busy:v===`rmkey${B.i}`,onCancel:()=>C(null),onConfirm:()=>{let a=B.i;ae(`rmkey${a}`,()=>d.adminApi.removeServerKey(a)).then(()=>C(null))}}),_&&(0,b.jsx)(k.ModelPicker,{title:"Allowed models",note:"Pick the models this key may call. None = all.",groups:J,selected:N,onToggle:a=>O(b=>b.includes(a)?b.filter(b=>b!==a):[...b,a]),onClose:()=>aa(!1),showThinkingHint:!1})]})}],8378)}];
2
-
3
- //# sourceMappingURL=src_components_EndpointView_tsx_0awdzb5._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/components/EndpointView.tsx","../../../../src/components/KeyReveal.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useCallback } from \"react\";\nimport { adminApi } from \"@/lib/client\";\nimport { Badge } from \"@/components/Badge\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { Button, Input } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { KeyReveal } from \"@/components/KeyReveal\";\nimport { Empty, fmt } from \"@/components/ui\";\nimport { ModelPicker, type ModelGroup } from \"@/components/ModelPicker\";\nimport { ConfirmModal } from \"@/components/ConfirmModal\";\nimport type { EndpointPayload, HeadroomStatusReply, InjectLevel, MaskedConfig } from \"@/lib/gateway\";\n\nconst LEVELS: InjectLevel[] = [\"off\", \"lite\", \"full\", \"ultra\"];\n\n/** Segment-pill style — matches the Budgets page pills. */\nconst pill = (active: boolean): string =>\n `rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${\n active ? \"bg-accent/12 text-accent\" : \"bg-surface-2 text-text-muted hover:text-text\"\n }`;\n\nconst DAY_MS = 86_400_000;\nconst EXPIRY_MS: Record<\"24h\" | \"7day\" | \"30day\", number> = {\n \"24h\": DAY_MS,\n \"7day\": 7 * DAY_MS,\n \"30day\": 30 * DAY_MS,\n};\n\n/** Generate a random gateway key client-side (aigetwey's one-click create). */\nfunction generateKey(): string {\n const bytes = new Uint8Array(24);\n crypto.getRandomValues(bytes);\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return `aig-${hex}`;\n}\n\nexport function EndpointView() {\n const [ep, setEp] = useState<EndpointPayload | null>(null);\n const [error, setError] = useState(\"\");\n const [busy, setBusy] = useState(\"\");\n const [keyName, setKeyName] = useState(\"\");\n const [created, setCreated] = useState<{ key: string; name: string } | null>(null);\n const [pendingDelKey, setPendingDelKey] = useState<{ i: number; label: string } | null>(null);\n const [hr, setHr] = useState<HeadroomStatusReply | null>(null);\n const [editKey, setEditKey] = useState<number | null>(null);\n const [editKeyName, setEditKeyName] = useState(\"\");\n const [groups, setGroups] = useState<ModelGroup[]>([]);\n const [scopeKey, setScopeKey] = useState<number | null>(null);\n const [scopeModels, setScopeModels] = useState<string[]>([]);\n const [scopeRpm, setScopeRpm] = useState(\"\");\n const [scopeExpiry, setScopeExpiry] = useState<\"keep\" | \"never\" | \"24h\" | \"7day\" | \"30day\" | \"custom\">(\"never\");\n const [scopeCustomDays, setScopeCustomDays] = useState(\"\");\n const [scopeLimit, setScopeLimit] = useState(\"\"); // USD limit, \"\" = no cap\n const [scopeWindow, setScopeWindow] = useState<\"5h\" | \"24h\" | \"7day\" | \"30day\">(\"30day\");\n const [keyBudgets, setKeyBudgets] = useState<Record<string, { limit: number; window: string }>>({});\n const [pickerOpen, setPickerOpen] = useState(false);\n\n const reload = useCallback(async () => {\n const r = await adminApi.endpoint();\n if (!r.ok) {\n setError(r.error ?? \"could not reach the gateway\");\n return;\n }\n setError(\"\");\n setEp(r.data);\n }, []);\n\n // Headroom status is a live probe (installed/running/python), separate from the\n // endpoint config — reload it on mount and after any headroom action.\n const reloadHr = useCallback(async () => {\n const r = await adminApi.headroomStatus();\n if (r.ok) setHr(r.data);\n }, []);\n\n useEffect(() => {\n void reload();\n void reloadHr();\n // load the model catalog for the per-key scope picker (combos + provider/model refs).\n void (async () => {\n try {\n const res = await fetch(\"/api/gw/admin/config\");\n if (!res.ok) return;\n const cfg = (await res.json()) as MaskedConfig;\n const grps: ModelGroup[] = [];\n if (cfg.models.length) grps.push({ label: \"Combos\", items: cfg.models.map((m) => ({ value: m.alias, label: m.alias })) });\n for (const p of cfg.providers) {\n if (p.models.length) grps.push({ label: p.id, items: p.models.map((m) => ({ value: `${p.id}/${m.id}`, label: `${p.id}/${m.id}` })) });\n }\n setGroups(grps);\n } catch { /* non-critical — picker will just be empty */ }\n })();\n // index existing key-scoped budgets by fingerprint so the modal can prefill.\n void adminApi.budgets().then((r) => {\n if (!r.ok || !r.data) return;\n const map: Record<string, { limit: number; window: string }> = {};\n for (const b of r.data.budgets) {\n if (b.scope.type === \"key\") map[b.scope.id] = { limit: b.limit, window: b.window };\n }\n setKeyBudgets(map);\n });\n }, [reload, reloadHr]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!ep) return <Empty>Loading…</Empty>;\n\n const baseUrl = `http://127.0.0.1:${ep.port}`;\n\n async function run(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setBusy(label);\n const r = await fn();\n setBusy(\"\");\n if (!r.ok) setError(r.error ?? \"action failed\");\n else {\n setError(\"\");\n await reload();\n }\n }\n\n // Create a key (generated or pasted) with its label, then surface it once in a\n // modal — aigetwey, where the full key is shown at creation time.\n async function addKey(label: string, rawKey: string) {\n const name = (label || \"Gateway key\").trim();\n setBusy(\"genkey\");\n const r = await adminApi.addServerKey(rawKey, name);\n setBusy(\"\");\n if (!r.ok) {\n setError(r.error ?? \"could not add key\");\n return;\n }\n setError(\"\");\n setKeyName(\"\");\n setCreated({ key: rawKey, name });\n await reload();\n }\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Endpoint &amp; Key</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">Gateway address, client keys, and the token-saver toggles.</p>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <RichCard header={<CardTitle title=\"Gateway URL\" sub=\"one endpoint for every client\" />}>\n <div className=\"text-[13px]\">\n <CopyRow label=\"Gateway URL\" value={baseUrl} />\n </div>\n <p className=\"mt-3 text-[12px] text-text-subtle\">\n One gateway, both formats. Anthropic clients (Claude Code) use it as-is; OpenAI clients (opencode,\n Cursor, Codex) append <span className=\"tnum\">/v1</span>. The <span className=\"text-text-muted\">CLI Tools</span>{\" \"}\n page has copy-ready env per tool.\n </p>\n </RichCard>\n\n <RichCard header={<CardTitle title=\"Gateway keys\" sub={`${ep.keys.length} configured`} />}>\n {ep.keys.length === 0 ? (\n <Empty>No keys — auth is DISABLED (localhost only). Generate one below.</Empty>\n ) : (\n <div className=\"space-y-1.5\">\n {ep.keys.map((k, i) =>\n editKey === i ? (\n <div key={i} className=\"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5\">\n <Input value={editKeyName} onChange={(e) => setEditKeyName(e.target.value)} placeholder=\"key name (e.g. Claude Code)\" />\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditKey(null)}>Cancel</Button>\n <Button\n disabled={busy === `editkey${i}`}\n onClick={() =>\n run(`editkey${i}`, async () => {\n const r = await adminApi.editServerKey(i, editKeyName.trim());\n if (r.ok) setEditKey(null);\n return r;\n })\n }\n >\n Save\n </Button>\n </div>\n </div>\n ) : (\n <div key={i} className=\"space-y-0 rounded-brand border border-border-subtle\">\n <div className=\"flex items-center justify-between gap-2 px-3 py-2\">\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n {k.name && <span className=\"text-[12px] font-semibold text-text-muted\">{k.name}</span>}\n <KeyReveal\n masked={k.key}\n reveal={async () => {\n const r = await adminApi.revealServerKey(i);\n return r.ok ? r.data?.key ?? null : null;\n }}\n />\n <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-text-subtle\">\n <span>{k.models?.length ? `${k.models.length} model${k.models.length > 1 ? \"s\" : \"\"}` : \"all models\"}</span>\n <span>·</span>\n <span>{k.rpm ? `${k.rpm}/min` : \"no rate limit\"}</span>\n <span>·</span>\n <span>\n {k.expires\n ? (Date.now() > k.expires ? <span className=\"text-danger\">expired</span> : `expires ${fmt.date(k.expires)}`)\n : \"no expiry\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-none items-center gap-1\">\n <button\n onClick={() => {\n setScopeKey(i);\n setScopeModels(k.models ?? []);\n setScopeRpm(k.rpm ? String(k.rpm) : \"\");\n setScopeExpiry(k.expires ? \"keep\" : \"never\");\n setScopeCustomDays(\"\");\n const kb = keyBudgets[k.fingerprint];\n setScopeLimit(kb ? String(kb.limit) : \"\");\n setScopeWindow((kb?.window as \"5h\" | \"24h\" | \"7day\" | \"30day\") ?? \"30day\");\n }}\n className=\"text-text-subtle hover:text-text\"\n aria-label=\"Edit key scope\"\n title=\"Model allowlist + rate limit + budget + expiry\"\n >\n <Icon name=\"tune\" size={15} />\n </button>\n <button\n onClick={() => { setEditKey(i); setEditKeyName(k.name ?? \"\"); }}\n className=\"text-text-subtle hover:text-text\"\n aria-label=\"Rename key\"\n title=\"Rename key\"\n >\n <Icon name=\"edit\" size={15} />\n </button>\n <button onClick={() => setPendingDelKey({ i, label: k.name || k.key })} className=\"text-text-subtle hover:text-danger\" aria-label=\"Remove key\">\n <Icon name=\"delete\" size={16} />\n </button>\n </div>\n </div>\n {scopeKey === i && (\n <div className=\"space-y-2 border-t border-border-subtle bg-accent-soft/40 px-3 py-2.5\">\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Allowed models</div>\n <div className=\"flex flex-wrap items-center gap-1.5\">\n {scopeModels.length === 0 ? (\n <span className=\"text-[12px] text-text-subtle\">All models (unrestricted)</span>\n ) : (\n scopeModels.map((m) => (\n <span key={m} className=\"inline-flex items-center gap-1 rounded border border-accent bg-accent-soft px-2 py-0.5 text-[12px] text-accent\">\n <span className=\"tnum\">{m}</span>\n <button onClick={() => setScopeModels((s) => s.filter((x) => x !== m))} className=\"hover:text-danger\" aria-label={`Remove ${m}`}>\n <Icon name=\"close\" size={12} />\n </button>\n </span>\n ))\n )}\n </div>\n <Button type=\"button\" variant=\"ghost\" className=\"mt-1.5\" onClick={() => setPickerOpen(true)}>\n <Icon name=\"add\" size={15} /> Pick models\n </Button>\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Rate limit</div>\n <Input\n inputMode=\"numeric\"\n value={scopeRpm}\n onChange={(e) => setScopeRpm(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"req/min (blank = unlimited)\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Access expiry</div>\n {k.expires && (\n <div className=\"mb-1.5 text-[11px] text-text-subtle\">\n currently {Date.now() > k.expires ? <span className=\"text-danger\">expired</span> : `expires ${fmt.date(k.expires)}`}\n </div>\n )}\n <div className=\"flex flex-wrap gap-1\">\n {(k.expires\n ? ([\"keep\", \"never\", \"24h\", \"7day\", \"30day\", \"custom\"] as const)\n : ([\"never\", \"24h\", \"7day\", \"30day\", \"custom\"] as const)\n ).map((opt) => (\n <button\n key={opt}\n type=\"button\"\n onClick={() => setScopeExpiry(opt)}\n className={pill(scopeExpiry === opt)}\n >\n {opt === \"never\" ? \"no expiry\" : opt}\n </button>\n ))}\n </div>\n {scopeExpiry === \"custom\" && (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <Input\n inputMode=\"numeric\"\n value={scopeCustomDays}\n onChange={(e) => setScopeCustomDays(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"days\"\n className=\"w-24\"\n />\n <span className=\"text-[11px] text-text-subtle\">days from now</span>\n </div>\n )}\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Spend cap (USD)</div>\n <Input\n inputMode=\"decimal\"\n value={scopeLimit}\n onChange={(e) => setScopeLimit(e.target.value.replace(/[^\\d.]/g, \"\"))}\n placeholder=\"USD (blank = no cap)\"\n />\n {scopeLimit && (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <span className=\"text-[11px] text-text-subtle\">resets every</span>\n {([\"5h\", \"24h\", \"7day\", \"30day\"] as const).map((w) => (\n <button\n key={w}\n type=\"button\"\n onClick={() => setScopeWindow(w)}\n className={pill(scopeWindow === w)}\n >\n {w}\n </button>\n ))}\n </div>\n )}\n </div>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setScopeKey(null)}>Cancel</Button>\n <Button\n disabled={busy === `scope${i}`}\n onClick={() =>\n run(`scope${i}`, async () => {\n // \"keep\" leaves expiry untouched (omit); \"never\" clears; a duration sets now+N.\n const expires =\n scopeExpiry === \"keep\" ? undefined\n : scopeExpiry === \"never\" ? null\n : scopeExpiry === \"custom\" ? (scopeCustomDays ? Date.now() + Number(scopeCustomDays) * DAY_MS : null)\n : Date.now() + EXPIRY_MS[scopeExpiry];\n const r = await adminApi.setServerKeyScope(i, {\n models: scopeModels,\n rpm: scopeRpm ? Number(scopeRpm) : null,\n expires,\n });\n if (!r.ok) return r;\n const limit = scopeLimit ? Number(scopeLimit) : 0;\n if (limit > 0) {\n await adminApi.setBudget({ scope: { type: \"key\", id: k.fingerprint }, unit: \"usd\", limit, window: scopeWindow });\n } else if (keyBudgets[k.fingerprint]) {\n await adminApi.clearBudget(`key:${k.fingerprint}`);\n }\n setScopeKey(null);\n return r;\n })\n }\n >\n Save\n </Button>\n </div>\n </div>\n )}\n </div>\n ),\n )}\n </div>\n )}\n <div className=\"mt-3 space-y-2\">\n <div className=\"flex gap-2\">\n <Input value={keyName} onChange={(e) => setKeyName(e.target.value)} placeholder=\"key name (e.g. Claude Code)\" className=\"flex-1\" />\n <Button disabled={busy === \"genkey\"} onClick={() => addKey(keyName, generateKey())}>\n <Icon name=\"add\" size={16} /> {busy === \"genkey\" ? \"Adding…\" : \"Add key\"}\n </Button>\n </div>\n <p className=\"text-[11px] text-text-subtle\">Name it, then click Add key — a key is generated and shown once. Configure its limits after.</p>\n </div>\n </RichCard>\n\n <RichCard className=\"lg:col-span-2\" header={<CardTitle title=\"Token savers\" sub=\"applied to every request before routing\" />}>\n <div className=\"space-y-4\">\n <Toggle\n label=\"RTK\"\n desc=\"Compress bulky tool_result blocks (diffs, grep, listings) in the request.\"\n on={ep.rtk}\n busy={busy === \"rtk\"}\n onChange={(v) => run(\"rtk\", () => adminApi.setRtk(v))}\n />\n <LevelRow\n label=\"Caveman\"\n desc=\"Terser model output — drops filler, keeps substance.\"\n value={ep.caveman}\n busy={busy === \"caveman\"}\n onChange={(lvl) => run(\"caveman\", () => adminApi.setCaveman(lvl))}\n />\n <LevelRow\n label=\"Ponytail\"\n desc=\"Minimal, YAGNI code style — deletion over addition.\"\n value={ep.ponytail}\n busy={busy === \"ponytail\"}\n onChange={(lvl) => run(\"ponytail\", () => adminApi.setPonytail(lvl))}\n />\n </div>\n </RichCard>\n\n <HeadroomCard\n ep={ep}\n hr={hr}\n refresh={async () => {\n await reload();\n await reloadHr();\n }}\n />\n </div>\n\n {created && <KeyCreatedModal name={created.name} value={created.key} onClose={() => setCreated(null)} />}\n {pendingDelKey && (\n <ConfirmModal\n title=\"Remove gateway key\"\n message={`Delete \"${pendingDelKey.label}\"? Any client using this key stops working immediately.`}\n confirmLabel=\"Remove\"\n busy={busy === `rmkey${pendingDelKey.i}`}\n onCancel={() => setPendingDelKey(null)}\n onConfirm={() => {\n const i = pendingDelKey.i;\n void run(`rmkey${i}`, () => adminApi.removeServerKey(i)).then(() => setPendingDelKey(null));\n }}\n />\n )}\n {pickerOpen && (\n <ModelPicker\n title=\"Allowed models\"\n note=\"Pick the models this key may call. None = all.\"\n groups={groups}\n selected={scopeModels}\n onToggle={(v) => setScopeModels((s) => s.includes(v) ? s.filter((x) => x !== v) : [...s, v])}\n onClose={() => setPickerOpen(false)}\n showThinkingHint={false}\n />\n )}\n </div>\n );\n}\n\n/**\n * Headroom = external context-compression proxy. Status is a live probe; the\n * enable/url/compress fields persist to endpoint config; Start/Stop manage a\n * gateway-spawned proxy when the CLI is installed and the URL is loopback.\n */\nfunction HeadroomCard({\n ep,\n hr,\n refresh,\n}: {\n ep: EndpointPayload;\n hr: HeadroomStatusReply | null;\n refresh: () => Promise<void>;\n}) {\n const h = ep.headroom;\n const [url, setUrl] = useState(h.url);\n const [localBusy, setLocalBusy] = useState(\"\");\n const [msg, setMsg] = useState(\"\");\n const [check, setCheck] = useState<{ ok: boolean; text: string } | null>(null);\n useEffect(() => setUrl(h.url), [h.url]);\n\n async function act(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setLocalBusy(label);\n setMsg(\"\");\n setCheck(null);\n const r = await fn();\n setLocalBusy(\"\");\n if (!r.ok) setMsg(r.error ?? \"action failed\");\n await refresh();\n }\n\n // Live re-probe: ask the gateway whether the proxy at the configured URL\n // actually answers right now, and surface the result inline.\n async function checkProxy() {\n setLocalBusy(\"check\");\n setMsg(\"\");\n setCheck(null);\n const r = await adminApi.headroomStatus();\n setLocalBusy(\"\");\n await refresh();\n if (!r.ok || !r.data) {\n setCheck({ ok: false, text: r.error ?? \"could not reach the gateway\" });\n return;\n }\n setCheck(\n r.data.running\n ? { ok: true, text: `proxy is up at ${r.data.url}` }\n : { ok: false, text: `no proxy responding at ${r.data.url}` },\n );\n }\n\n return (\n <RichCard className=\"lg:col-span-2\" header={<CardTitle title=\"Headroom\" sub=\"external context-compression proxy\" />}>\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2 text-[12px]\">\n <Badge tone={hr?.installed ? \"live\" : \"neutral\"}>{hr?.installed ? \"installed\" : \"not installed\"}</Badge>\n <Badge tone={hr?.running ? \"live\" : \"warn\"}>{hr?.running ? \"proxy running\" : \"proxy down\"}</Badge>\n <Badge tone={hr?.python ? \"info\" : \"neutral\"}>{hr?.python ? `python ${hr.python}` : \"no python ≥3.10\"}</Badge>\n {hr?.managedPid ? <span className=\"tnum text-text-subtle\">pid {hr.managedPid}</span> : null}\n </div>\n\n <Toggle\n label=\"Enable headroom\"\n desc=\"Compress the full context through the proxy before each request.\"\n on={h.enabled}\n busy={localBusy === \"enable\"}\n disabled={!hr?.running && !h.enabled}\n onChange={(v) => act(\"enable\", () => adminApi.setHeadroom({ enabled: v }))}\n />\n <Toggle\n label=\"Compress user messages\"\n desc=\"Also squeeze user turns, not just tool/assistant context.\"\n on={h.compress_user_messages}\n busy={localBusy === \"cum\"}\n onChange={(v) => act(\"cum\", () => adminApi.setHeadroom({ compress_user_messages: v }))}\n />\n\n <div className=\"flex items-end gap-2\">\n <div className=\"flex-1\">\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Proxy URL</div>\n <Input value={url} onChange={(e) => setUrl(e.target.value)} placeholder=\"http://localhost:8787\" className=\"font-mono text-[12.5px]\" />\n </div>\n <Button\n variant=\"ghost\"\n disabled={url.trim() === h.url || localBusy === \"url\"}\n onClick={() => act(\"url\", () => adminApi.setHeadroom({ url: url.trim() }))}\n >\n Save URL\n </Button>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n disabled={!hr?.canStart || hr?.running || !!localBusy}\n onClick={async () => {\n await act(\"start\", () => adminApi.headroomStart());\n await checkProxy();\n }}\n >\n <Icon name={localBusy === \"start\" ? \"sync\" : \"play_arrow\"} size={16} className={localBusy === \"start\" ? \"animate-spin\" : \"\"} />\n {localBusy === \"start\" ? \"Starting…\" : \"Start proxy\"}\n </Button>\n <Button\n variant=\"danger\"\n disabled={!hr?.managedPid || localBusy === \"stop\"}\n onClick={() => act(\"stop\", () => adminApi.headroomStop())}\n >\n <Icon name=\"stop\" size={16} /> Stop\n </Button>\n <Button variant=\"ghost\" disabled={localBusy === \"check\"} onClick={checkProxy}>\n <Icon name=\"sync\" size={16} /> {localBusy === \"check\" ? \"Checking…\" : \"Check\"}\n </Button>\n {hr && !hr.installed && (\n <span className=\"text-[11px] text-text-subtle\">\n Headroom isn’t installed. Get it from{\" \"}\n <a href=\"https://github.com/chopratejas/headroom\" target=\"_blank\" rel=\"noreferrer\" className=\"text-accent hover:underline\">\n chopratejas/headroom\n </a>{\" \"}\n (needs Python ≥ 3.10):{\" \"}\n <code className=\"rounded bg-surface-2 px-1\">pipx install git+https://github.com/chopratejas/headroom</code>{\" \"}\n — then re-open this page.\n </span>\n )}\n {hr?.installed && !hr.localUrl && (\n <span className=\"text-[11px] text-text-subtle\">URL isn’t loopback — start that proxy yourself.</span>\n )}\n </div>\n\n {msg && <p className=\"text-[12px] text-danger\">{msg}</p>}\n {check && (\n <p className={`flex items-center gap-1 text-[12px] ${check.ok ? \"text-success\" : \"text-danger\"}`}>\n <Icon name={check.ok ? \"check_circle\" : \"error\"} size={14} /> {check.text}\n </p>\n )}\n </div>\n </RichCard>\n );\n}\n\n/** Shows a freshly created key once (it's masked everywhere after), with copy. */\nfunction KeyCreatedModal({ name, value, onClose }: { name: string; value: string; onClose: () => void }) {\n const [copied, setCopied] = useState(false);\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6\" onClick={onClose}>\n <div\n className=\"w-full max-w-md rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-1 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-accent\">\n <Icon name=\"key\" size={16} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">Key created</h2>\n </div>\n <p className=\"mb-3 text-[12px] text-text-muted\">\n Copy <span className=\"text-text\">{name}</span> now. You can reveal it again later from this page.\n </p>\n <button\n onClick={() => {\n void navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }}\n className=\"flex w-full items-center justify-between gap-2 rounded-brand border border-border-subtle bg-bg px-3 py-2.5 text-left hover:border-text-subtle\"\n >\n <span className=\"tnum truncate text-[12.5px] text-text\">{value}</span>\n <Icon name={copied ? \"check\" : \"content_copy\"} size={15} />\n </button>\n <div className=\"mt-4 flex justify-end\">\n <Button onClick={onClose}>Done</Button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction CopyRow({ label, value }: { label: string; value: string }) {\n const [copied, setCopied] = useState(false);\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-text-subtle\">{label}</span>\n <button\n onClick={() => {\n void navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n }}\n className=\"flex items-center gap-1.5 rounded-brand border border-border-subtle px-2.5 py-1 tnum text-[12.5px] text-text hover:border-text-subtle\"\n >\n {value}\n <Icon name={copied ? \"check\" : \"content_copy\"} size={13} />\n </button>\n </div>\n );\n}\n\nfunction Toggle({ label, desc, on, busy, disabled, onChange }: { label: string; desc: string; on: boolean; busy: boolean; disabled?: boolean; onChange: (v: boolean) => void }) {\n const off = busy || disabled;\n return (\n <div className={`flex items-center justify-between gap-4 ${off ? \"opacity-40\" : \"\"}`}>\n <div>\n <div className=\"text-[13px] font-semibold text-text\">{label}</div>\n <div className=\"text-[12px] text-text-muted\">{desc}</div>\n </div>\n <button\n disabled={off}\n onClick={() => onChange(!on)}\n className={`relative h-6 w-11 flex-none rounded-full transition-colors ${on ? \"bg-accent\" : \"bg-surface-3\"}`}\n aria-pressed={on}\n >\n <span className={`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-bg transition-transform ${on ? \"translate-x-5\" : \"translate-x-0\"}`} />\n </button>\n </div>\n );\n}\n\nfunction LevelRow({ label, desc, value, busy, onChange }: { label: string; desc: string; value: InjectLevel; busy: boolean; onChange: (l: InjectLevel) => void }) {\n return (\n <div className=\"flex items-center justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-text\">{label}</span>\n {value !== \"off\" && <Badge tone=\"info\">{value}</Badge>}\n </div>\n <div className=\"text-[12px] text-text-muted\">{desc}</div>\n </div>\n <div className=\"flex flex-none items-center gap-1 rounded-full border border-border bg-surface p-1\">\n {LEVELS.map((lvl) => (\n <button\n key={lvl}\n disabled={busy}\n onClick={() => onChange(lvl)}\n className={`rounded-full px-2.5 py-1 text-[11.5px] font-medium transition-colors ${\n value === lvl ? \"bg-surface-2 text-text\" : \"text-text-muted hover:text-text\"\n }`}\n >\n {lvl}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Icon } from \"./Icon\";\n\n/**\n * A masked key with an eye toggle that fetches the raw value on demand — for the\n * local operator who forgot what they pasted. `masked` is the already-masked\n * string the dashboard renders everywhere; `reveal` lazily fetches the real key\n * (admin-gated) the first time it's shown, then we cache it for copy/hide.\n */\n/**\n * `align`: \"inline\" keeps the eye + copy right next to the key text (use in a\n * label/column context like Endpoint). \"right\" lets the text grow so the eye +\n * copy push to the right edge (use in a single-line row like Provider keys).\n */\nexport function KeyReveal({\n masked,\n reveal,\n className,\n align = \"inline\",\n}: {\n masked: string;\n reveal: () => Promise<string | null>;\n className?: string;\n align?: \"inline\" | \"right\";\n}) {\n const [real, setReal] = useState<string | null>(null);\n const [shown, setShown] = useState(false);\n const [loading, setLoading] = useState(false);\n const [copied, setCopied] = useState(false);\n\n async function toggle() {\n if (shown) {\n setShown(false);\n return;\n }\n if (real === null) {\n setLoading(true);\n const k = await reveal();\n setLoading(false);\n if (k === null) return; // reveal failed — stay masked\n setReal(k);\n }\n setShown(true);\n }\n\n const display = shown && real !== null ? real : masked;\n\n return (\n <span className={`flex min-w-0 items-center gap-1.5${className ? ` ${className}` : \"\"}`}>\n <span className={`tnum truncate text-[12.5px] text-text${align === \"right\" ? \" flex-1\" : \"\"}`}>{display}</span>\n {shown && real !== null && (\n <button\n type=\"button\"\n onClick={() => {\n void navigator.clipboard.writeText(real);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n }}\n className=\"flex-none text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Copy key\"\n >\n <Icon name={copied ? \"check\" : \"content_copy\"} size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={toggle}\n disabled={loading}\n className=\"flex-none text-text-subtle transition-colors hover:text-text disabled:opacity-40\"\n aria-label={shown ? \"Hide key\" : \"Show key\"}\n >\n <Icon name={loading ? \"hourglass_empty\" : shown ? \"visibility_off\" : \"visibility\"} size={15} />\n </button>\n </span>\n );\n}\n"],"names":["KeyReveal","masked","reveal","className","align","real","setReal","shown","setShown","loading","setLoading","copied","setCopied","toggle","k","display","type","onClick","navigator","clipboard","writeText","setTimeout","name","size","disabled"],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- module.exports=[47444,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(93026),e=a.i(52065);a.s(["ModelPicker",0,function({title:a="Add models",note:f="Click to add, click again to remove.",searchPlaceholder:g="Search models…",groups:h,selected:i,onToggle:j,onClose:k,showThinkingHint:l=!0}){let[m,n]=(0,c.useState)(""),o=m.trim().toLowerCase(),p=h.map(a=>({...a,items:o?a.items.filter(a=>a.value.toLowerCase().includes(o)):a.items})).filter(a=>a.items.length>0),q=new Set(i);return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/60 p-6 sm:p-10",onClick:k,children:(0,b.jsxs)("div",{className:"flex max-h-[80vh] w-full max-w-lg flex-col rounded-brand-lg border border-border bg-surface shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[(0,b.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:a}),(0,b.jsx)("button",{onClick:k,className:"text-text-subtle hover:text-text","aria-label":"Close",children:(0,b.jsx)(d.Icon,{name:"close",size:18})})]}),(0,b.jsxs)("div",{className:"border-b border-border-subtle px-4 py-3",children:[(0,b.jsx)("p",{className:"mb-2 text-[12px] text-text-muted",children:f}),(0,b.jsxs)("div",{className:"relative",children:[(0,b.jsx)(d.Icon,{name:"search",size:15,className:"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle"}),(0,b.jsx)("input",{autoFocus:!0,value:m,onChange:a=>n(a.target.value),placeholder:g,className:"w-full rounded-brand border border-border bg-bg py-2 pl-8 pr-3 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none"})]})]}),(0,b.jsx)("div",{className:"flex-1 overflow-y-auto px-4 py-3",children:0===p.length?(0,b.jsxs)("p",{className:"py-6 text-center text-[12.5px] text-text-subtle",children:["No models match “",m,"”."]}):(0,b.jsx)("div",{className:"space-y-4",children:p.map(a=>(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-text-subtle",children:[a.label," ",(0,b.jsxs)("span",{className:"tnum text-text-subtle/70",children:["(",a.items.length,")"]})]}),(0,b.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.items.map(a=>{let c=q.has(a.value);return(0,b.jsxs)("button",{type:"button",onClick:()=>j(a.value),className:`inline-flex items-center gap-1 rounded-brand border px-2 py-1 text-[12px] transition-colors ${c?"border-accent bg-accent-soft text-accent":"border-border bg-bg text-text-muted hover:border-text-subtle hover:text-text"}`,children:[c&&(0,b.jsx)(d.Icon,{name:"check",size:12}),(0,b.jsx)("span",{className:"tnum",children:a.label}),(0,b.jsx)(e.CapacityBadges,{model:a.value,size:13}),a.tag&&(0,b.jsx)("span",{className:"rounded bg-surface-2 px-1 text-[10px] text-text-subtle",children:a.tag})]},a.value)})})]},a.label))})}),l&&(0,b.jsxs)("div",{className:"border-t border-border-subtle px-4 py-2 text-[11px] text-text-subtle",children:[(0,b.jsx)(d.Icon,{name:"neurology",size:12,className:"mr-1 inline align-text-bottom text-warning"}),"Reasoning models accept a thinking suffix — call"," ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(high)"})," or"," ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(none)"})," (high·low·medium·minimal·auto·none·or a token budget)."]}),(0,b.jsxs)("div",{className:"flex items-center justify-between border-t border-border-subtle px-4 py-3",children:[(0,b.jsxs)("span",{className:"tnum text-[12px] text-text-subtle",children:[i.length," selected"]}),(0,b.jsx)("button",{onClick:k,className:"rounded-brand bg-accent px-3.5 py-1.5 text-[13px] font-semibold text-accent-ink hover:bg-accent-hover",children:"Done"})]})]})})}])}];
2
-
3
- //# sourceMappingURL=src_components_ModelPicker_tsx_1jisxh6._.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/components/ModelPicker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Icon } from \"@/components/Icon\";\nimport { CapacityBadges } from \"@/components/CapacityBadges\";\n\nexport interface ModelGroup {\n label: string;\n items: { value: string; label: string; tag?: string }[];\n}\n\n/**\n * aigetwey-style model picker: a search box + provider-grouped chips you click to\n * toggle in/out of a selection. Used by the combo form and the CLI-tool model\n * selection so both add models the same way (click to add, click again to drop).\n */\nexport function ModelPicker({\n title = \"Add models\",\n note = \"Click to add, click again to remove.\",\n searchPlaceholder = \"Search models…\",\n groups,\n selected,\n onToggle,\n onClose,\n showThinkingHint = true,\n}: {\n title?: string;\n note?: string;\n searchPlaceholder?: string;\n groups: ModelGroup[];\n selected: string[];\n onToggle: (value: string) => void;\n onClose: () => void;\n /** The \"reasoning models accept a thinking suffix\" footer only makes sense when\n * picking MODELS. Provider/key pickers reuse this component, so they hide it. */\n showThinkingHint?: boolean;\n}) {\n const [q, setQ] = useState(\"\");\n const needle = q.trim().toLowerCase();\n const filtered = groups\n .map((g) => ({\n ...g,\n items: needle ? g.items.filter((i) => i.value.toLowerCase().includes(needle)) : g.items,\n }))\n .filter((g) => g.items.length > 0);\n const sel = new Set(selected);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/60 p-6 sm:p-10\" onClick={onClose}>\n <div\n className=\"flex max-h-[80vh] w-full max-w-lg flex-col rounded-brand-lg border border-border bg-surface shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex items-center justify-between border-b border-border-subtle px-4 py-3\">\n <h2 className=\"text-[14px] font-semibold text-text\">{title}</h2>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\" aria-label=\"Close\">\n <Icon name=\"close\" size={18} />\n </button>\n </div>\n\n <div className=\"border-b border-border-subtle px-4 py-3\">\n <p className=\"mb-2 text-[12px] text-text-muted\">{note}</p>\n <div className=\"relative\">\n <Icon name=\"search\" size={15} className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle\" />\n <input\n autoFocus\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder={searchPlaceholder}\n className=\"w-full rounded-brand border border-border bg-bg py-2 pl-8 pr-3 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none\"\n />\n </div>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-3\">\n {filtered.length === 0 ? (\n <p className=\"py-6 text-center text-[12.5px] text-text-subtle\">No models match “{q}”.</p>\n ) : (\n <div className=\"space-y-4\">\n {filtered.map((g) => (\n <div key={g.label}>\n <div className=\"mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-text-subtle\">\n {g.label} <span className=\"tnum text-text-subtle/70\">({g.items.length})</span>\n </div>\n <div className=\"flex flex-wrap gap-1.5\">\n {g.items.map((it) => {\n const on = sel.has(it.value);\n return (\n <button\n key={it.value}\n type=\"button\"\n onClick={() => onToggle(it.value)}\n className={`inline-flex items-center gap-1 rounded-brand border px-2 py-1 text-[12px] transition-colors ${\n on ? \"border-accent bg-accent-soft text-accent\" : \"border-border bg-bg text-text-muted hover:border-text-subtle hover:text-text\"\n }`}\n >\n {on && <Icon name=\"check\" size={12} />}\n <span className=\"tnum\">{it.label}</span>\n <CapacityBadges model={it.value} size={13} />\n {it.tag && <span className=\"rounded bg-surface-2 px-1 text-[10px] text-text-subtle\">{it.tag}</span>}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {showThinkingHint && (\n <div className=\"border-t border-border-subtle px-4 py-2 text-[11px] text-text-subtle\">\n <Icon name=\"neurology\" size={12} className=\"mr-1 inline align-text-bottom text-warning\" />\n Reasoning models accept a thinking suffix — call{\" \"}\n <code className=\"rounded bg-surface-2 px-1 text-text-muted\">model(high)</code> or{\" \"}\n <code className=\"rounded bg-surface-2 px-1 text-text-muted\">model(none)</code> (high·low·medium·minimal·auto·none·or a token budget).\n </div>\n )}\n\n <div className=\"flex items-center justify-between border-t border-border-subtle px-4 py-3\">\n <span className=\"tnum text-[12px] text-text-subtle\">{selected.length} selected</span>\n <button onClick={onClose} className=\"rounded-brand bg-accent px-3.5 py-1.5 text-[13px] font-semibold text-accent-ink hover:bg-accent-hover\">\n Done\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["ModelPicker","title","note","searchPlaceholder","groups","selected","onToggle","onClose","showThinkingHint","q","setQ","needle","trim","toLowerCase","filtered","map","g","items","filter","i","value","includes","length","sel","Set","className","onClick","e","stopPropagation","name","size","autoFocus","onChange","target","placeholder","label","it","on","has","type","model","tag"],"mappings":"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"}
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,81189,e=>{"use strict";var t=e.i(43476);let a={live:"bg-success/12 text-success",down:"bg-danger/12 text-danger",warn:"bg-warning/12 text-warning",info:"bg-info/12 text-info",neutral:"bg-surface-2 text-text-muted"};function s({tone:e="neutral",children:n,className:r}){return(0,t.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${a[e]}${r?` ${r}`:""}`,children:n})}e.s(["Badge",0,s,"FormatBadge",0,function({format:e}){return(0,t.jsx)(s,{tone:"info",children:e})}])},38286,e=>{"use strict";var t=e.i(43476);e.s(["Empty",0,function({children:e}){return(0,t.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:e})},"Stat",0,function({label:e,value:a,sub:s}){return(0,t.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,t.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:e}),(0,t.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:a}),s&&(0,t.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:s})]})},"fmt",0,{int:e=>e.toLocaleString("en-US"),compact:e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:String(Math.round(e)),cost:e=>0===e?"$0":e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`,time:e=>new Date(e).toLocaleString("en-US",{hour12:!1}),date(e){let t=new Date(e);return`${String(t.getDate()).padStart(2,"0")}/${String(t.getMonth()+1).padStart(2,"0")}/${t.getFullYear()}`},ago(e){let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`},duration(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;if(t<3600)return`${Math.floor(t/60)}m ${t%60}s`;let a=Math.floor(t/3600),s=Math.floor(t%3600/60);if(a<24)return`${a}h ${s}m`;let n=Math.floor(a/24);return`${n}d ${a%24}h`}}])},49080,e=>{"use strict";var t=e.i(43476);e.s(["Lamp",0,function({state:e,title:a}){return(0,t.jsx)("span",{className:`lamp lamp-${e}`,title:a,"aria-label":e})}])},98111,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(51514),n=e.i(38286);e.s(["CooldownTimer",0,function({ms:e,tone:r="danger",icon:i="timer",keepZero:l=!1}){let[o]=(0,a.useState)(()=>Date.now()+e),[d,c]=(0,a.useState)(()=>Math.max(0,e));return((0,a.useEffect)(()=>{let e=()=>c(Math.max(0,o-Date.now()));e();let t=setInterval(e,1e3);return()=>clearInterval(t)},[o]),d<=0&&!l)?null:(0,t.jsxs)("span",{className:`inline-flex items-center gap-1 tnum text-[12px] ${"danger"===r?"text-danger":"text-text-muted"}`,children:[(0,t.jsx)(s.Icon,{name:i,size:13}),d<=0?"now":n.fmt.duration(d)]})}])},70757,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(22016),n=e.i(29481),r=e.i(49080),i=e.i(81189),l=e.i(98111),o=e.i(10007),d=e.i(51514),c=e.i(38286);function x({id:e,disabled:s,onDone:r}){let[i,l]=(0,a.useState)(!1);return(0,t.jsxs)("button",{type:"button",onClick:t=>{t.preventDefault(),t.stopPropagation(),i||(l(!0),n.adminApi.setProviderDisabled(e,!s).then(()=>r()).finally(()=>l(!1)))},className:`inline-flex items-center gap-1.5 text-[11px] font-medium ${s?"text-danger":"text-text-muted"}`,"aria-label":s?"Enable provider":"Disable provider",title:s?"Provider disabled — click to enable":"Provider enabled — click to disable",children:[(0,t.jsx)("span",{className:`relative h-4 w-7 rounded-full transition-colors ${s?"bg-danger":"bg-accent"} ${i?"opacity-60":""}`,children:(0,t.jsx)("span",{className:`absolute left-0.5 top-0.5 h-3 w-3 rounded-full bg-white transition-transform ${s?"translate-x-0":"translate-x-[14px]"}`})}),s?"disabled":"enabled"]})}let u=[{id:"openai",label:"OpenAI compatible",sub:"/v1/chat/completions",icon:"bolt",format:"openai",base_url:"https://api.openai.com/v1",hint:"Base URL ending in /v1 for any OpenAI-compatible API.",modelHint:"e.g. gpt-4o, glm-5.2"},{id:"anthropic",label:"Anthropic compatible",sub:"/v1/messages",icon:"smart_toy",format:"anthropic",base_url:"https://api.anthropic.com",hint:"Base URL of an Anthropic-compatible API; /messages is appended.",modelHint:"e.g. claude-sonnet-4-6"}];function m({onDone:e,onClose:s}){let[r,l]=(0,a.useState)(null),[c,x]=(0,a.useState)(""),[p,h]=(0,a.useState)(""),[b,f]=(0,a.useState)(""),[g,v]=(0,a.useState)(!1),[j,y]=(0,a.useState)(""),[N,w]=(0,a.useState)(!1),[k,$]=(0,a.useState)(!1),[S,C]=(0,a.useState)(null),[I,M]=(0,a.useState)("");if(!r)return(0,t.jsxs)("div",{className:"mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft",children:[(0,t.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:"Add a provider"}),(0,t.jsx)("p",{className:"mt-0.5 text-[12.5px] text-text-muted",children:"Pick the API your endpoint speaks — the rest is prefilled."})]}),(0,t.jsx)("button",{type:"button",onClick:s,className:"flex-none text-text-subtle hover:text-text","aria-label":"Cancel",children:(0,t.jsx)(d.Icon,{name:"close",size:18})})]}),(0,t.jsx)("div",{className:"mt-4 grid gap-3 sm:grid-cols-2",children:u.map(e=>(0,t.jsxs)("button",{type:"button",onClick:()=>{l(e),h(e.base_url),C(null),M("")},className:"group flex items-start gap-3 rounded-brand-lg border border-border bg-bg p-4 text-left transition-colors hover:border-accent hover:bg-accent-soft",children:[(0,t.jsx)("span",{className:"flex h-10 w-10 flex-none items-center justify-center rounded-brand bg-surface-2 text-text-muted group-hover:text-accent",children:(0,t.jsx)(d.Icon,{name:e.icon,size:20})}),(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block text-[13.5px] font-semibold text-text",children:e.label}),(0,t.jsx)("span",{className:"block tnum text-[11.5px] text-text-subtle",children:e.sub}),(0,t.jsx)("span",{className:"mt-1 block text-[11.5px] text-text-muted",children:e.hint})]})]},e.id))})]});async function _(){if(!p||!r)return;$(!0),C(null);let e=await n.adminApi.validateProvider({format:r.format,base_url:p,api_key:b||void 0});$(!1),C(e.data??{ok:!1,reachable:!1,status:0,error:e.error})}async function A(t){if(t.preventDefault(),!r||!c||!p)return void M("name and base URL are required");w(!0),M("");let a=await n.adminApi.addProvider({id:c,format:r.format,base_url:p,api_key:b||void 0,free:!b.trim()});if(!a.ok){w(!1),M(a.error??"failed");return}j.trim()&&await n.adminApi.addModel(c,j.trim()),w(!1),e()}return(0,t.jsx)("div",{className:"mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft",children:(0,t.jsxs)("form",{onSubmit:A,children:[(0,t.jsxs)("div",{className:"mb-4 flex items-center gap-2.5 border-b border-border-subtle pb-4",children:[(0,t.jsx)("span",{className:"flex h-8 w-8 items-center justify-center rounded-brand bg-surface-2 text-text-muted",children:(0,t.jsx)(d.Icon,{name:r.icon,size:17})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-[13.5px] font-semibold text-text",children:r.label}),(0,t.jsx)("div",{className:"tnum text-[11px] text-text-subtle",children:r.sub})]}),(0,t.jsxs)("button",{type:"button",onClick:()=>{l(null),C(null)},className:"ml-auto inline-flex items-center gap-1 text-[12px] text-text-subtle hover:text-text",children:[(0,t.jsx)(d.Icon,{name:"arrow_back",size:14})," change type"]})]}),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)(o.Field,{label:"Name",hint:"a friendly id — also the model prefix (name/model)",children:(0,t.jsx)(o.Input,{value:c,onChange:e=>x(e.target.value),placeholder:"e.g. openai, anthropic"})}),(0,t.jsx)(o.Field,{label:"Base URL",hint:r.hint,children:(0,t.jsx)(o.Input,{value:p,onChange:e=>{h(e.target.value),C(null)},placeholder:r.base_url,className:"font-mono text-[12.5px]"})}),(0,t.jsx)(o.Field,{label:"API Key",hint:"used for Check and live requests — leave blank for a free / no-auth endpoint",children:(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsxs)("div",{className:"relative flex-1",children:[(0,t.jsx)(o.Input,{type:g?"text":"password",value:b,onChange:e=>{f(e.target.value),C(null)},placeholder:"sk-…",className:"pr-9 font-mono text-[12.5px]"}),b&&(0,t.jsx)("button",{type:"button",onClick:()=>v(e=>!e),className:"absolute right-2 top-1/2 -translate-y-1/2 text-text-subtle hover:text-text","aria-label":g?"Hide key":"Show key",children:(0,t.jsx)(d.Icon,{name:g?"visibility_off":"visibility",size:15})})]}),(0,t.jsxs)(o.Button,{type:"button",variant:"ghost",disabled:k||!p,onClick:_,children:[(0,t.jsx)(d.Icon,{name:k?"progress_activity":"wifi_tethering",size:15}),k?"Checking…":"Check"]})]})}),S&&(0,t.jsxs)("div",{className:"flex items-center gap-2 text-[12px]",children:[(0,t.jsx)(i.Badge,{tone:S.ok?"live":S.reachable?"warn":"down",children:S.ok?"valid":S.reachable?`reachable (${S.status})`:"invalid"}),S.error&&(0,t.jsx)("span",{className:"text-text-subtle",children:S.error})]}),(0,t.jsx)(o.Field,{label:"Model ID",hint:"optional — seed one if the provider has no /models endpoint",children:(0,t.jsx)(o.Input,{value:j,onChange:e=>y(e.target.value),placeholder:r.modelHint,className:"font-mono text-[12.5px]"})})]}),I&&(0,t.jsx)("div",{className:"mt-2 text-[12px] text-danger",children:I}),(0,t.jsxs)("div",{className:"mt-4 flex justify-end gap-2",children:[(0,t.jsx)(o.Button,{type:"button",variant:"ghost",onClick:s,children:"Cancel"}),(0,t.jsx)(o.Button,{type:"submit",disabled:N,children:N?"Adding…":"Add provider"})]})]})})}e.s(["ProviderManager",0,function(){let[e,u]=(0,a.useState)(null),[p,h]=(0,a.useState)(""),[b,f]=(0,a.useState)(!1),g=(0,a.useCallback)(async()=>{let[e,t]=await Promise.all([fetch("/api/gw/admin/config"),n.adminApi.providers()]);e.ok&&t.ok?(h(""),u({config:await e.json(),health:t.data?.providers??[]})):h("could not reach the gateway")},[]);if((0,a.useEffect)(()=>{g()},[g]),p)return(0,t.jsx)(c.Empty,{children:p});if(!e)return(0,t.jsx)(c.Empty,{children:"Loading…"});let v=new Map(e.health.map(e=>[e.id,e]));return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-6 flex items-center justify-between gap-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Providers & Keys"}),(0,t.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Upstream providers the gateway routes to."})]}),(0,t.jsxs)(o.Button,{onClick:()=>f(!0),children:[(0,t.jsx)(d.Icon,{name:"add",size:17}),"Add provider"]})]}),b&&(0,t.jsx)(m,{onClose:()=>f(!1),onDone:()=>{f(!1),g()}}),0===e.config.providers.length?(0,t.jsx)(c.Empty,{children:"No providers yet. Add one to start routing."}):(0,t.jsx)("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:e.config.providers.map(e=>{let a=v.get(e.id),n=!a||a.keys.some(e=>e.healthy),o=a?.keys.find(e=>!e.healthy&&e.cooldown_ms>0);return(0,t.jsxs)(s.default,{href:`/providers/${encodeURIComponent(e.id)}`,className:`group rounded-brand-lg border bg-surface p-4 shadow-soft transition-colors ${e.disabled?"border-danger/35 opacity-60 hover:opacity-100 hover:border-danger/60":"border-border hover:border-text-subtle"}`,children:[(0,t.jsxs)("div",{className:"flex items-start justify-between gap-2",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 min-w-0",children:[(0,t.jsx)(r.Lamp,{state:e.disabled?"idle":n?"live":"down"}),(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate text-[14px] font-semibold text-text",children:e.name||e.id}),e.name&&(0,t.jsxs)("span",{className:"block truncate text-[11px] text-text-subtle",children:[e.id,"/"]})]})]}),(0,t.jsx)(i.FormatBadge,{format:e.format})]}),(0,t.jsx)("div",{className:"mt-2 truncate text-[12px] text-text-subtle",children:e.base_url}),(0,t.jsxs)("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[(0,t.jsx)(x,{id:e.id,disabled:!!e.disabled,onDone:g}),e.free&&(0,t.jsx)(i.Badge,{tone:"info",children:"free"}),e.service_account&&(0,t.jsx)(i.Badge,{tone:"info",children:"service-account"}),(0,t.jsx)(i.Badge,{tone:"neutral",children:e.free||e.service_account?`${e.api_keys?.length??0} keys`:`${e.api_keys?.length??+!!e.api_key} keys`}),(0,t.jsxs)(i.Badge,{tone:"neutral",children:[e.models.length," models"]}),o&&(0,t.jsx)(l.CooldownTimer,{ms:o.cooldown_ms})]})]},e.id)})})]})}])}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,81189,e=>{"use strict";var t=e.i(43476);let n={live:"bg-success/12 text-success",down:"bg-danger/12 text-danger",warn:"bg-warning/12 text-warning",info:"bg-info/12 text-info",neutral:"bg-surface-2 text-text-muted"};function a({tone:e="neutral",children:i,className:s}){return(0,t.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${n[e]}${s?` ${s}`:""}`,children:i})}e.s(["Badge",0,a,"FormatBadge",0,function({format:e}){return(0,t.jsx)(a,{tone:"info",children:e})}])},38286,e=>{"use strict";var t=e.i(43476);e.s(["Empty",0,function({children:e}){return(0,t.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:e})},"Stat",0,function({label:e,value:n,sub:a}){return(0,t.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,t.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:e}),(0,t.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:n}),a&&(0,t.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:a})]})},"fmt",0,{int:e=>e.toLocaleString("en-US"),compact:e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:String(Math.round(e)),cost:e=>0===e?"$0":e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`,time:e=>new Date(e).toLocaleString("en-US",{hour12:!1}),date(e){let t=new Date(e);return`${String(t.getDate()).padStart(2,"0")}/${String(t.getMonth()+1).padStart(2,"0")}/${t.getFullYear()}`},ago(e){let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`},duration(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;if(t<3600)return`${Math.floor(t/60)}m ${t%60}s`;let n=Math.floor(t/3600),a=Math.floor(t%3600/60);if(n<24)return`${n}h ${a}m`;let i=Math.floor(n/24);return`${i}d ${n%24}h`}}])},69163,e=>{"use strict";var t=e.i(43476);e.s(["CardTitle",0,function({title:e,sub:n,icon:a}){return(0,t.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[a,(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:e}),n&&(0,t.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:n})]})]})},"RichCard",0,function({header:e,footer:n,children:a,className:i}){return(0,t.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${i?` ${i}`:""}`,children:[e&&(0,t.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:e}),(0,t.jsx)("div",{className:"p-4",children:a}),n&&(0,t.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:n})]})}])},53854,45570,e=>{"use strict";var t=e.i(43476);function n(e,t){return RegExp("^"+e.split("*").map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i").test(t)}let a={vision:!1,pdf:!1,audioInput:!1,videoInput:!1,imageOutput:!1,audioOutput:!1,search:!1,tools:!0,reasoning:!1,thinkingFormat:null,thinkingCanDisable:!0,thinkingRange:null,contextWindow:2e5,maxOutput:64e3},i={"claude-opus-4.6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-opus-4.7":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-opus-4-6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-sonnet-4.6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:64e3},"claude-sonnet-4-6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:64e3},"gpt-image-1":{imageOutput:!0,tools:!1},"glm-4.6v":{vision:!0,reasoning:!0,thinkingFormat:"zai",contextWindow:128e3},"vision-model":{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6},"coder-model":{reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6}},s={"codebuddy-cn":{"glm-5.2":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:48e3},"glm-5.1":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"glm-5.0":{reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:48e3},"glm-5.0-turbo":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"glm-5v-turbo":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:38e3},"glm-4.7":{reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:48e3},"minimax-m3":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:512e3,maxOutput:48e3},"minimax-m2.7":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"kimi-k2.7":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:256e3,maxOutput:32e3},"kimi-k2.6":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:256e3,maxOutput:32e3},"kimi-k2.5":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:164e3,maxOutput:32e3},"hy3-preview":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:192e3,maxOutput:64e3},"deepseek-v4-pro":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:5e4},"deepseek-v4-flash":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:5e4},"deepseek-v3-2-volc":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:96e3,maxOutput:32e3}}},o=[{pattern:"*claude*opus-4.6*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*opus-4.7*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*opus-4.8*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*sonnet-4.6*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*sonnet-4.7*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*haiku*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*opus*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*sonnet*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*fable*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget",contextWindow:1e6,maxOutput:128e3}},{pattern:"*claude*mythos*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget",contextWindow:1e6,maxOutput:128e3}},{pattern:"*claude-3*",caps:{vision:!0}},{pattern:"*claude*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*gemini*image*",caps:{vision:!0,imageOutput:!0,contextWindow:1048576}},{pattern:"*gemini-3*pro*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-level",thinkingCanDisable:!1,contextWindow:1048576,maxOutput:65535}},{pattern:"*gemini-3*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-level",thinkingCanDisable:!1,contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini-2.5*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-budget",thinkingRange:{min:0,max:24576},contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini-2*",caps:{vision:!0,audioInput:!0,videoInput:!0,search:!0,contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini*",caps:{vision:!0,search:!0,contextWindow:1048576}},{pattern:"*gemma*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*nanobanana*",caps:{vision:!0,imageOutput:!0}},{pattern:"*gpt-5*image*",caps:{imageOutput:!0}},{pattern:"*gpt-5*codex*",caps:{reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:4e5,maxOutput:128e3}},{pattern:"*gpt-5*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:4e5,maxOutput:128e3}},{pattern:"*gpt-4o*",caps:{vision:!0,search:!0,contextWindow:128e3,maxOutput:16384}},{pattern:"*gpt-4.1*",caps:{vision:!0,contextWindow:1e6,maxOutput:32768}},{pattern:"*gpt-4-turbo*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*gpt-4*",caps:{contextWindow:128e3}},{pattern:"*gpt-3.5*",caps:{contextWindow:16385,maxOutput:4096}},{pattern:"*gpt-oss*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:128e3}},{pattern:"*o1-mini*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:128e3}},{pattern:"*o1*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*o3*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*o4*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*grok*image*",caps:{imageOutput:!0}},{pattern:"*grok-code*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*grok-4*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*grok-3*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:131072}},{pattern:"*grok*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*qwen*vl*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*qwen*max*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6,maxOutput:65536}},{pattern:"*qwen*plus*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6,maxOutput:65536}},{pattern:"*qwen*235b*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*qwen*coder*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6}},{pattern:"*qwq*",caps:{reasoning:!0,thinkingFormat:"qwen",thinkingCanDisable:!1,contextWindow:131072}},{pattern:"*qwen*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*kimi*k2.7*code*",caps:{vision:!0,reasoning:!0,thinkingFormat:"kimi",thinkingCanDisable:!1,contextWindow:262144,maxOutput:262144}},{pattern:"*kimi*k2*",caps:{vision:!0,reasoning:!0,thinkingFormat:"kimi",contextWindow:262144,maxOutput:262144}},{pattern:"*kimi*",caps:{reasoning:!0,thinkingFormat:"kimi",contextWindow:262144}},{pattern:"*glm-5*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5,maxOutput:128e3}},{pattern:"*glm-4.7*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5,maxOutput:128e3}},{pattern:"*glm-4*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5}},{pattern:"*glm*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5}},{pattern:"*deepseek-v4*",caps:{reasoning:!0,thinkingFormat:"deepseek",contextWindow:1e6,maxOutput:384e3}},{pattern:"*reasoner*",caps:{reasoning:!0,thinkingFormat:"deepseek",thinkingCanDisable:!1,contextWindow:128e3}},{pattern:"*deepseek-r*",caps:{reasoning:!0,thinkingFormat:"deepseek",thinkingCanDisable:!1,contextWindow:128e3}},{pattern:"*deepseek-chat*",caps:{contextWindow:128e3}},{pattern:"*deepseek*",caps:{reasoning:!0,thinkingFormat:"deepseek",contextWindow:128e3}},{pattern:"*minimax*image*",caps:{imageOutput:!0}},{pattern:"*minimax-m3*",caps:{vision:!0,reasoning:!0,thinkingFormat:"minimax",contextWindow:1048576,maxOutput:512e3}},{pattern:"*minimax-m2.7*",caps:{reasoning:!0,thinkingFormat:"minimax",thinkingCanDisable:!1,contextWindow:204800,maxOutput:131072}},{pattern:"*minimax*",caps:{reasoning:!0,thinkingFormat:"minimax",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:131072}},{pattern:"*mimo*v2.5*",caps:{vision:!0,contextWindow:1048576,maxOutput:131072}},{pattern:"*mimo*omni*",caps:{vision:!0,audioInput:!0,contextWindow:262144,maxOutput:131072}},{pattern:"*mimo*",caps:{vision:!0,contextWindow:262144,maxOutput:131072}},{pattern:"*llama-4*",caps:{vision:!0,contextWindow:1e6}},{pattern:"*llama*",caps:{contextWindow:128e3}},{pattern:"*codestral*",caps:{contextWindow:256e3}},{pattern:"*mistral-large*",caps:{vision:!0,contextWindow:256e3}},{pattern:"*mistral*",caps:{contextWindow:128e3}},{pattern:"*command-a-vision*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*command*",caps:{contextWindow:128e3}},{pattern:"*sonar*",caps:{search:!0,contextWindow:128e3}},{pattern:"*pplx*",caps:{search:!0,contextWindow:128e3}},{pattern:"*perplexity*",caps:{search:!0,contextWindow:128e3}},{pattern:"*hunyuan*",caps:{reasoning:!0,thinkingFormat:"hunyuan",contextWindow:262144,maxOutput:262144}},{pattern:"hy3*",caps:{reasoning:!0,thinkingFormat:"hunyuan",contextWindow:262144,maxOutput:262144}},{pattern:"*step-*",caps:{reasoning:!0,thinkingFormat:"step",contextWindow:128e3}},{pattern:"*nemotron*",caps:{reasoning:!0,contextWindow:128e3}},{pattern:"*ling-*",caps:{reasoning:!0,contextWindow:128e3}}];function r(e,t){if(!t)return{...a};if(e&&s[e]?.[t])return{...a,...s[e][t]};let r=(t.includes("/")?t.split("/").pop():t)??t;if(i[r])return{...a,...i[r]};if(i[t])return{...a,...i[t]};for(let{pattern:e,caps:i}of o)if(n(e,r)||n(e,t))return{...a,...i};return{...a}}e.s(["getCapabilitiesForModel",0,r,"modalitiesForModel",0,function(e){let t=e.indexOf("/"),n=r(t>0?e.slice(0,t):null,t>0?e.slice(t+1):e),a=["text"];n.vision&&a.push("image"),n.pdf&&a.push("pdf"),n.audioInput&&a.push("audio"),n.videoInput&&a.push("video");let i=["text"];return n.imageOutput&&i.push("image"),n.audioOutput&&i.push("audio"),{input:a,output:i}}],45570);var l=e.i(51514);let c={vision:{icon:"visibility",label:"Vision",desc:"Supports image input",color:"text-info"},reasoning:{icon:"neurology",label:"Reasoning",desc:"Supports reasoning / thinking",color:"text-warning"}};e.s(["CapacityBadges",0,function({model:e,provider:n=null,size:a=15,className:i=""}){let s=r(n,e),o=Object.keys(c).filter(e=>s[e]);return 0===o.length?null:(0,t.jsx)("span",{className:`inline-flex flex-none items-center gap-0.5 ${i}`,children:o.map(e=>(0,t.jsx)("span",{title:`${c[e].label} — ${c[e].desc}`,className:"leading-none",children:(0,t.jsx)(l.Icon,{name:c[e].icon,size:a,className:c[e].color})},e))})}],53854)},78347,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(51514),i=e.i(53854);e.s(["ModelPicker",0,function({title:e="Add models",note:s="Click to add, click again to remove.",searchPlaceholder:o="Search models…",groups:r,selected:l,onToggle:c,onClose:d,showThinkingHint:x=!0}){let[p,u]=(0,n.useState)(""),m=p.trim().toLowerCase(),h=r.map(e=>({...e,items:m?e.items.filter(e=>e.value.toLowerCase().includes(m)):e.items})).filter(e=>e.items.length>0),g=new Set(l);return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/60 p-6 sm:p-10",onClick:d,children:(0,t.jsxs)("div",{className:"flex max-h-[80vh] w-full max-w-lg flex-col rounded-brand-lg border border-border bg-surface shadow-elevated",onClick:e=>e.stopPropagation(),children:[(0,t.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[(0,t.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:e}),(0,t.jsx)("button",{onClick:d,className:"text-text-subtle hover:text-text","aria-label":"Close",children:(0,t.jsx)(a.Icon,{name:"close",size:18})})]}),(0,t.jsxs)("div",{className:"border-b border-border-subtle px-4 py-3",children:[(0,t.jsx)("p",{className:"mb-2 text-[12px] text-text-muted",children:s}),(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)(a.Icon,{name:"search",size:15,className:"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle"}),(0,t.jsx)("input",{autoFocus:!0,value:p,onChange:e=>u(e.target.value),placeholder:o,className:"w-full rounded-brand border border-border bg-bg py-2 pl-8 pr-3 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none"})]})]}),(0,t.jsx)("div",{className:"flex-1 overflow-y-auto px-4 py-3",children:0===h.length?(0,t.jsxs)("p",{className:"py-6 text-center text-[12.5px] text-text-subtle",children:["No models match “",p,"”."]}):(0,t.jsx)("div",{className:"space-y-4",children:h.map(e=>(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-text-subtle",children:[e.label," ",(0,t.jsxs)("span",{className:"tnum text-text-subtle/70",children:["(",e.items.length,")"]})]}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:e.items.map(e=>{let n=g.has(e.value);return(0,t.jsxs)("button",{type:"button",onClick:()=>c(e.value),className:`inline-flex items-center gap-1 rounded-brand border px-2 py-1 text-[12px] transition-colors ${n?"border-accent bg-accent-soft text-accent":"border-border bg-bg text-text-muted hover:border-text-subtle hover:text-text"}`,children:[n&&(0,t.jsx)(a.Icon,{name:"check",size:12}),(0,t.jsx)("span",{className:"tnum",children:e.label}),(0,t.jsx)(i.CapacityBadges,{model:e.value,size:13}),e.tag&&(0,t.jsx)("span",{className:"rounded bg-surface-2 px-1 text-[10px] text-text-subtle",children:e.tag})]},e.value)})})]},e.label))})}),x&&(0,t.jsxs)("div",{className:"border-t border-border-subtle px-4 py-2 text-[11px] text-text-subtle",children:[(0,t.jsx)(a.Icon,{name:"neurology",size:12,className:"mr-1 inline align-text-bottom text-warning"}),"Reasoning models accept a thinking suffix — call"," ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(high)"})," or"," ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(none)"})," (high·low·medium·minimal·auto·none·or a token budget)."]}),(0,t.jsxs)("div",{className:"flex items-center justify-between border-t border-border-subtle px-4 py-3",children:[(0,t.jsxs)("span",{className:"tnum text-[12px] text-text-subtle",children:[l.length," selected"]}),(0,t.jsx)("button",{onClick:d,className:"rounded-brand bg-accent px-3.5 py-1.5 text-[13px] font-semibold text-accent-ink hover:bg-accent-hover",children:"Done"})]})]})})}])},24644,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(29481),i=e.i(81189),s=e.i(69163),o=e.i(10007),r=e.i(51514);function l({masked:e,reveal:a,className:i,align:s="inline"}){let[o,c]=(0,n.useState)(null),[d,x]=(0,n.useState)(!1),[p,u]=(0,n.useState)(!1),[m,h]=(0,n.useState)(!1);async function g(){if(d)return void x(!1);if(null===o){u(!0);let e=await a();if(u(!1),null===e)return;c(e)}x(!0)}let b=d&&null!==o?o:e;return(0,t.jsxs)("span",{className:`flex min-w-0 items-center gap-1.5${i?` ${i}`:""}`,children:[(0,t.jsx)("span",{className:`tnum truncate text-[12.5px] text-text${"right"===s?" flex-1":""}`,children:b}),d&&null!==o&&(0,t.jsx)("button",{type:"button",onClick:()=>{navigator.clipboard.writeText(o),h(!0),setTimeout(()=>h(!1),1200)},className:"flex-none text-text-subtle transition-colors hover:text-text","aria-label":"Copy key",children:(0,t.jsx)(r.Icon,{name:m?"check":"content_copy",size:14})}),(0,t.jsx)("button",{type:"button",onClick:g,disabled:p,className:"flex-none text-text-subtle transition-colors hover:text-text disabled:opacity-40","aria-label":d?"Hide key":"Show key",children:(0,t.jsx)(r.Icon,{name:p?"hourglass_empty":d?"visibility_off":"visibility",size:15})})]})}var c=e.i(38286),d=e.i(78347),x=e.i(13135);let p=["off","lite","full","ultra"],u=e=>`rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${e?"bg-accent/12 text-accent":"bg-surface-2 text-text-muted hover:text-text"}`,m={"24h":864e5,"7day":6048e5,"30day":2592e6};function h({ep:e,hr:l,refresh:c}){let d=e.headroom,[x,p]=(0,n.useState)(d.url),[u,m]=(0,n.useState)(""),[g,b]=(0,n.useState)(""),[k,f]=(0,n.useState)(null);async function j(e,t){m(e),b(""),f(null);let n=await t();m(""),n.ok||b(n.error??"action failed"),await c()}async function w(){m("check"),b(""),f(null);let e=await a.adminApi.headroomStatus();(m(""),await c(),e.ok&&e.data)?f(e.data.running?{ok:!0,text:`proxy is up at ${e.data.url}`}:{ok:!1,text:`no proxy responding at ${e.data.url}`}):f({ok:!1,text:e.error??"could not reach the gateway"})}return(0,n.useEffect)(()=>p(d.url),[d.url]),(0,t.jsx)(s.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(s.CardTitle,{title:"Headroom",sub:"external context-compression proxy"}),children:(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-[12px]",children:[(0,t.jsx)(i.Badge,{tone:l?.installed?"live":"neutral",children:l?.installed?"installed":"not installed"}),(0,t.jsx)(i.Badge,{tone:l?.running?"live":"warn",children:l?.running?"proxy running":"proxy down"}),(0,t.jsx)(i.Badge,{tone:l?.python?"info":"neutral",children:l?.python?`python ${l.python}`:"no python ≥3.10"}),l?.managedPid?(0,t.jsxs)("span",{className:"tnum text-text-subtle",children:["pid ",l.managedPid]}):null]}),(0,t.jsx)(v,{label:"Enable headroom",desc:"Compress the full context through the proxy before each request.",on:d.enabled,busy:"enable"===u,disabled:!l?.running&&!d.enabled,onChange:e=>j("enable",()=>a.adminApi.setHeadroom({enabled:e}))}),(0,t.jsx)(v,{label:"Compress user messages",desc:"Also squeeze user turns, not just tool/assistant context.",on:d.compress_user_messages,busy:"cum"===u,onChange:e=>j("cum",()=>a.adminApi.setHeadroom({compress_user_messages:e}))}),(0,t.jsxs)("div",{className:"flex items-end gap-2",children:[(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Proxy URL"}),(0,t.jsx)(o.Input,{value:x,onChange:e=>p(e.target.value),placeholder:"http://localhost:8787",className:"font-mono text-[12.5px]"})]}),(0,t.jsx)(o.Button,{variant:"ghost",disabled:x.trim()===d.url||"url"===u,onClick:()=>j("url",()=>a.adminApi.setHeadroom({url:x.trim()})),children:"Save URL"})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsxs)(o.Button,{disabled:!l?.canStart||l?.running||!!u,onClick:async()=>{await j("start",()=>a.adminApi.headroomStart()),await w()},children:[(0,t.jsx)(r.Icon,{name:"start"===u?"sync":"play_arrow",size:16,className:"start"===u?"animate-spin":""}),"start"===u?"Starting…":"Start proxy"]}),(0,t.jsxs)(o.Button,{variant:"danger",disabled:!l?.managedPid||"stop"===u,onClick:()=>j("stop",()=>a.adminApi.headroomStop()),children:[(0,t.jsx)(r.Icon,{name:"stop",size:16})," Stop"]}),(0,t.jsxs)(o.Button,{variant:"ghost",disabled:"check"===u,onClick:w,children:[(0,t.jsx)(r.Icon,{name:"sync",size:16})," ","check"===u?"Checking…":"Check"]}),l&&!l.installed&&(0,t.jsxs)("span",{className:"text-[11px] text-text-subtle",children:["Headroom isn’t installed. Get it from"," ",(0,t.jsx)("a",{href:"https://github.com/chopratejas/headroom",target:"_blank",rel:"noreferrer",className:"text-accent hover:underline",children:"chopratejas/headroom"})," ","(needs Python ≥ 3.10):"," ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"pipx install git+https://github.com/chopratejas/headroom"})," ","— then re-open this page."]}),l?.installed&&!l.localUrl&&(0,t.jsx)("span",{className:"text-[11px] text-text-subtle",children:"URL isn’t loopback — start that proxy yourself."})]}),g&&(0,t.jsx)("p",{className:"text-[12px] text-danger",children:g}),k&&(0,t.jsxs)("p",{className:`flex items-center gap-1 text-[12px] ${k.ok?"text-success":"text-danger"}`,children:[(0,t.jsx)(r.Icon,{name:k.ok?"check_circle":"error",size:14})," ",k.text]})]})})}function g({name:e,value:a,onClose:i}){let[s,l]=(0,n.useState)(!1);return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:i,children:(0,t.jsxs)("div",{className:"w-full max-w-md rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:e=>e.stopPropagation(),children:[(0,t.jsxs)("div",{className:"mb-1 flex items-center gap-2",children:[(0,t.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-accent",children:(0,t.jsx)(r.Icon,{name:"key",size:16})}),(0,t.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Key created"})]}),(0,t.jsxs)("p",{className:"mb-3 text-[12px] text-text-muted",children:["Copy ",(0,t.jsx)("span",{className:"text-text",children:e})," now. You can reveal it again later from this page."]}),(0,t.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(a),l(!0),setTimeout(()=>l(!1),1500)},className:"flex w-full items-center justify-between gap-2 rounded-brand border border-border-subtle bg-bg px-3 py-2.5 text-left hover:border-text-subtle",children:[(0,t.jsx)("span",{className:"tnum truncate text-[12.5px] text-text",children:a}),(0,t.jsx)(r.Icon,{name:s?"check":"content_copy",size:15})]}),(0,t.jsx)("div",{className:"mt-4 flex justify-end",children:(0,t.jsx)(o.Button,{onClick:i,children:"Done"})})]})})}function b({label:e,value:a}){let[i,s]=(0,n.useState)(!1);return(0,t.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,t.jsx)("span",{className:"text-text-subtle",children:e}),(0,t.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(a),s(!0),setTimeout(()=>s(!1),1200)},className:"flex items-center gap-1.5 rounded-brand border border-border-subtle px-2.5 py-1 tnum text-[12.5px] text-text hover:border-text-subtle",children:[a,(0,t.jsx)(r.Icon,{name:i?"check":"content_copy",size:13})]})]})}function v({label:e,desc:n,on:a,busy:i,disabled:s,onChange:o}){let r=i||s;return(0,t.jsxs)("div",{className:`flex items-center justify-between gap-4 ${r?"opacity-40":""}`,children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-[13px] font-semibold text-text",children:e}),(0,t.jsx)("div",{className:"text-[12px] text-text-muted",children:n})]}),(0,t.jsx)("button",{disabled:r,onClick:()=>o(!a),className:`relative h-6 w-11 flex-none rounded-full transition-colors ${a?"bg-accent":"bg-surface-3"}`,"aria-pressed":a,children:(0,t.jsx)("span",{className:`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-bg transition-transform ${a?"translate-x-5":"translate-x-0"}`})})]})}function k({label:e,desc:n,value:a,busy:s,onChange:o}){return(0,t.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"text-[13px] font-semibold text-text",children:e}),"off"!==a&&(0,t.jsx)(i.Badge,{tone:"info",children:a})]}),(0,t.jsx)("div",{className:"text-[12px] text-text-muted",children:n})]}),(0,t.jsx)("div",{className:"flex flex-none items-center gap-1 rounded-full border border-border bg-surface p-1",children:p.map(e=>(0,t.jsx)("button",{disabled:s,onClick:()=>o(e),className:`rounded-full px-2.5 py-1 text-[11.5px] font-medium transition-colors ${a===e?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:e},e))})]})}e.s(["EndpointView",0,function(){let[e,i]=(0,n.useState)(null),[p,f]=(0,n.useState)(""),[j,w]=(0,n.useState)(""),[y,N]=(0,n.useState)(""),[C,W]=(0,n.useState)(null),[F,S]=(0,n.useState)(null),[O,$]=(0,n.useState)(null),[I,A]=(0,n.useState)(null),[D,z]=(0,n.useState)(""),[R,M]=(0,n.useState)([]),[B,q]=(0,n.useState)(null),[T,P]=(0,n.useState)([]),[L,U]=(0,n.useState)(""),[_,E]=(0,n.useState)("never"),[K,G]=(0,n.useState)(""),[H,V]=(0,n.useState)(""),[Y,J]=(0,n.useState)("30day"),[Q,X]=(0,n.useState)({}),[Z,ee]=(0,n.useState)(!1),et=(0,n.useCallback)(async()=>{let e=await a.adminApi.endpoint();e.ok?(f(""),i(e.data)):f(e.error??"could not reach the gateway")},[]),en=(0,n.useCallback)(async()=>{let e=await a.adminApi.headroomStatus();e.ok&&$(e.data)},[]);if((0,n.useEffect)(()=>{et(),en(),(async()=>{try{let e=await fetch("/api/gw/admin/config");if(!e.ok)return;let t=await e.json(),n=[];for(let e of(t.models.length&&n.push({label:"Combos",items:t.models.map(e=>({value:e.alias,label:e.alias}))}),t.providers))e.models.length&&n.push({label:e.id,items:e.models.map(t=>({value:`${e.id}/${t.id}`,label:`${e.id}/${t.id}`}))});M(n)}catch{}})(),a.adminApi.budgets().then(e=>{if(!e.ok||!e.data)return;let t={};for(let n of e.data.budgets)"key"===n.scope.type&&(t[n.scope.id]={limit:n.limit,window:n.window});X(t)})},[et,en]),p)return(0,t.jsx)(c.Empty,{children:p});if(!e)return(0,t.jsx)(c.Empty,{children:"Loading…"});let ea=`http://127.0.0.1:${e.port}`;async function ei(e,t){w(e);let n=await t();w(""),n.ok?(f(""),await et()):f(n.error??"action failed")}async function es(e,t){let n=(e||"Gateway key").trim();w("genkey");let i=await a.adminApi.addServerKey(t,n);(w(""),i.ok)?(f(""),N(""),W({key:t,name:n}),await et()):f(i.error??"could not add key")}return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Endpoint & Key"}),(0,t.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Gateway address, client keys, and the token-saver toggles."})]}),(0,t.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,t.jsxs)(s.RichCard,{header:(0,t.jsx)(s.CardTitle,{title:"Gateway URL",sub:"one endpoint for every client"}),children:[(0,t.jsx)("div",{className:"text-[13px]",children:(0,t.jsx)(b,{label:"Gateway URL",value:ea})}),(0,t.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["One gateway, both formats. Anthropic clients (Claude Code) use it as-is; OpenAI clients (opencode, Cursor, Codex) append ",(0,t.jsx)("span",{className:"tnum",children:"/v1"}),". The ",(0,t.jsx)("span",{className:"text-text-muted",children:"CLI Tools"})," ","page has copy-ready env per tool."]})]}),(0,t.jsxs)(s.RichCard,{header:(0,t.jsx)(s.CardTitle,{title:"Gateway keys",sub:`${e.keys.length} configured`}),children:[0===e.keys.length?(0,t.jsx)(c.Empty,{children:"No keys — auth is DISABLED (localhost only). Generate one below."}):(0,t.jsx)("div",{className:"space-y-1.5",children:e.keys.map((e,n)=>I===n?(0,t.jsxs)("div",{className:"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5",children:[(0,t.jsx)(o.Input,{value:D,onChange:e=>z(e.target.value),placeholder:"key name (e.g. Claude Code)"}),(0,t.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>A(null),children:"Cancel"}),(0,t.jsx)(o.Button,{disabled:j===`editkey${n}`,onClick:()=>ei(`editkey${n}`,async()=>{let e=await a.adminApi.editServerKey(n,D.trim());return e.ok&&A(null),e}),children:"Save"})]})]},n):(0,t.jsxs)("div",{className:"space-y-0 rounded-brand border border-border-subtle",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2 px-3 py-2",children:[(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[e.name&&(0,t.jsx)("span",{className:"text-[12px] font-semibold text-text-muted",children:e.name}),(0,t.jsx)(l,{masked:e.key,reveal:async()=>{let e=await a.adminApi.revealServerKey(n);return e.ok?e.data?.key??null:null}}),(0,t.jsxs)("div",{className:"mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-text-subtle",children:[(0,t.jsx)("span",{children:e.models?.length?`${e.models.length} model${e.models.length>1?"s":""}`:"all models"}),(0,t.jsx)("span",{children:"·"}),(0,t.jsx)("span",{children:e.rpm?`${e.rpm}/min`:"no rate limit"}),(0,t.jsx)("span",{children:"·"}),(0,t.jsx)("span",{children:e.expires?Date.now()>e.expires?(0,t.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${c.fmt.date(e.expires)}`:"no expiry"})]})]}),(0,t.jsxs)("div",{className:"flex flex-none items-center gap-1",children:[(0,t.jsx)("button",{onClick:()=>{q(n),P(e.models??[]),U(e.rpm?String(e.rpm):""),E(e.expires?"keep":"never"),G("");let t=Q[e.fingerprint];V(t?String(t.limit):""),J(t?.window??"30day")},className:"text-text-subtle hover:text-text","aria-label":"Edit key scope",title:"Model allowlist + rate limit + budget + expiry",children:(0,t.jsx)(r.Icon,{name:"tune",size:15})}),(0,t.jsx)("button",{onClick:()=>{A(n),z(e.name??"")},className:"text-text-subtle hover:text-text","aria-label":"Rename key",title:"Rename key",children:(0,t.jsx)(r.Icon,{name:"edit",size:15})}),(0,t.jsx)("button",{onClick:()=>S({i:n,label:e.name||e.key}),className:"text-text-subtle hover:text-danger","aria-label":"Remove key",children:(0,t.jsx)(r.Icon,{name:"delete",size:16})})]})]}),B===n&&(0,t.jsxs)("div",{className:"space-y-2 border-t border-border-subtle bg-accent-soft/40 px-3 py-2.5",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Allowed models"}),(0,t.jsx)("div",{className:"flex flex-wrap items-center gap-1.5",children:0===T.length?(0,t.jsx)("span",{className:"text-[12px] text-text-subtle",children:"All models (unrestricted)"}):T.map(e=>(0,t.jsxs)("span",{className:"inline-flex items-center gap-1 rounded border border-accent bg-accent-soft px-2 py-0.5 text-[12px] text-accent",children:[(0,t.jsx)("span",{className:"tnum",children:e}),(0,t.jsx)("button",{onClick:()=>P(t=>t.filter(t=>t!==e)),className:"hover:text-danger","aria-label":`Remove ${e}`,children:(0,t.jsx)(r.Icon,{name:"close",size:12})})]},e))}),(0,t.jsxs)(o.Button,{type:"button",variant:"ghost",className:"mt-1.5",onClick:()=>ee(!0),children:[(0,t.jsx)(r.Icon,{name:"add",size:15})," Pick models"]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Rate limit"}),(0,t.jsx)(o.Input,{inputMode:"numeric",value:L,onChange:e=>U(e.target.value.replace(/[^\d]/g,"")),placeholder:"req/min (blank = unlimited)"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Access expiry"}),e.expires&&(0,t.jsxs)("div",{className:"mb-1.5 text-[11px] text-text-subtle",children:["currently ",Date.now()>e.expires?(0,t.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${c.fmt.date(e.expires)}`]}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:(e.expires?["keep","never","24h","7day","30day","custom"]:["never","24h","7day","30day","custom"]).map(e=>(0,t.jsx)("button",{type:"button",onClick:()=>E(e),className:u(_===e),children:"never"===e?"no expiry":e},e))}),"custom"===_&&(0,t.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,t.jsx)(o.Input,{inputMode:"numeric",value:K,onChange:e=>G(e.target.value.replace(/[^\d]/g,"")),placeholder:"days",className:"w-24"}),(0,t.jsx)("span",{className:"text-[11px] text-text-subtle",children:"days from now"})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Spend cap (USD)"}),(0,t.jsx)(o.Input,{inputMode:"decimal",value:H,onChange:e=>V(e.target.value.replace(/[^\d.]/g,"")),placeholder:"USD (blank = no cap)"}),H&&(0,t.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,t.jsx)("span",{className:"text-[11px] text-text-subtle",children:"resets every"}),["5h","24h","7day","30day"].map(e=>(0,t.jsx)("button",{type:"button",onClick:()=>J(e),className:u(Y===e),children:e},e))]})]}),(0,t.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>q(null),children:"Cancel"}),(0,t.jsx)(o.Button,{disabled:j===`scope${n}`,onClick:()=>ei(`scope${n}`,async()=>{let t="keep"===_?void 0:"never"===_?null:"custom"===_?K?Date.now()+864e5*Number(K):null:Date.now()+m[_],i=await a.adminApi.setServerKeyScope(n,{models:T,rpm:L?Number(L):null,expires:t});if(!i.ok)return i;let s=H?Number(H):0;return s>0?await a.adminApi.setBudget({scope:{type:"key",id:e.fingerprint},unit:"usd",limit:s,window:Y}):Q[e.fingerprint]&&await a.adminApi.clearBudget(`key:${e.fingerprint}`),q(null),i}),children:"Save"})]})]})]},n))}),(0,t.jsxs)("div",{className:"mt-3 space-y-2",children:[(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(o.Input,{value:y,onChange:e=>N(e.target.value),placeholder:"key name (e.g. Claude Code)",className:"flex-1"}),(0,t.jsxs)(o.Button,{disabled:"genkey"===j,onClick:()=>{let e,t;return es(y,(e=new Uint8Array(24),crypto.getRandomValues(e),t=Array.from(e,e=>e.toString(16).padStart(2,"0")).join(""),`aig-${t}`))},children:[(0,t.jsx)(r.Icon,{name:"add",size:16})," ","genkey"===j?"Adding…":"Add key"]})]}),(0,t.jsx)("p",{className:"text-[11px] text-text-subtle",children:"Name it, then click Add key — a key is generated and shown once. Configure its limits after."})]})]}),(0,t.jsx)(s.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(s.CardTitle,{title:"Token savers",sub:"applied to every request before routing"}),children:(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)(v,{label:"RTK",desc:"Compress bulky tool_result blocks (diffs, grep, listings) in the request.",on:e.rtk,busy:"rtk"===j,onChange:e=>ei("rtk",()=>a.adminApi.setRtk(e))}),(0,t.jsx)(k,{label:"Caveman",desc:"Terser model output — drops filler, keeps substance.",value:e.caveman,busy:"caveman"===j,onChange:e=>ei("caveman",()=>a.adminApi.setCaveman(e))}),(0,t.jsx)(k,{label:"Ponytail",desc:"Minimal, YAGNI code style — deletion over addition.",value:e.ponytail,busy:"ponytail"===j,onChange:e=>ei("ponytail",()=>a.adminApi.setPonytail(e))})]})}),(0,t.jsx)(h,{ep:e,hr:O,refresh:async()=>{await et(),await en()}})]}),C&&(0,t.jsx)(g,{name:C.name,value:C.key,onClose:()=>W(null)}),F&&(0,t.jsx)(x.ConfirmModal,{title:"Remove gateway key",message:`Delete "${F.label}"? Any client using this key stops working immediately.`,confirmLabel:"Remove",busy:j===`rmkey${F.i}`,onCancel:()=>S(null),onConfirm:()=>{let e=F.i;ei(`rmkey${e}`,()=>a.adminApi.removeServerKey(e)).then(()=>S(null))}}),Z&&(0,t.jsx)(d.ModelPicker,{title:"Allowed models",note:"Pick the models this key may call. None = all.",groups:R,selected:T,onToggle:e=>P(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),onClose:()=>ee(!1),showThinkingHint:!1})]})}],24644)}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,81189,e=>{"use strict";var t=e.i(43476);let a={live:"bg-success/12 text-success",down:"bg-danger/12 text-danger",warn:"bg-warning/12 text-warning",info:"bg-info/12 text-info",neutral:"bg-surface-2 text-text-muted"};function s({tone:e="neutral",children:n,className:o}){return(0,t.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${a[e]}${o?` ${o}`:""}`,children:n})}e.s(["Badge",0,s,"FormatBadge",0,function({format:e}){return(0,t.jsx)(s,{tone:"info",children:e})}])},38286,e=>{"use strict";var t=e.i(43476);e.s(["Empty",0,function({children:e}){return(0,t.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:e})},"Stat",0,function({label:e,value:a,sub:s}){return(0,t.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,t.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:e}),(0,t.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:a}),s&&(0,t.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:s})]})},"fmt",0,{int:e=>e.toLocaleString("en-US"),compact:e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:String(Math.round(e)),cost:e=>0===e?"$0":e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`,time:e=>new Date(e).toLocaleString("en-US",{hour12:!1}),date(e){let t=new Date(e);return`${String(t.getDate()).padStart(2,"0")}/${String(t.getMonth()+1).padStart(2,"0")}/${t.getFullYear()}`},ago(e){let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`},duration(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;if(t<3600)return`${Math.floor(t/60)}m ${t%60}s`;let a=Math.floor(t/3600),s=Math.floor(t%3600/60);if(a<24)return`${a}h ${s}m`;let n=Math.floor(a/24);return`${n}d ${a%24}h`}}])},70789,e=>{"use strict";let t=[{id:"claude-code",name:"Claude Code",icon:"smart_toy",format:"anthropic",blurb:"Anthropic CLI. Point its base URL + key at the gateway.",autoConfig:!0,install:"npm i -g @anthropic-ai/claude-code",slots:[{label:"Opus · heavy",alias:"claude-opus-4-1"},{label:"Sonnet · default",alias:"claude-sonnet-4-6"},{label:"Haiku · fast",alias:"claude-haiku-4-5"}],env:(e,t)=>[{name:"ANTHROPIC_BASE_URL",value:e},{name:"ANTHROPIC_API_KEY",value:t||"<your-gateway-key>"}],steps:["Export the two variables in the shell you run `claude` from.","Create a combo named like each slot above so Claude Code's model ids resolve.","The gateway translates Anthropic ↔ provider format, so any provider works behind it."]},{id:"opencode",name:"opencode",icon:"code_blocks",format:"openai",blurb:"OpenAI-compatible provider. Set base_url to /v1.",autoConfig:!0,install:"curl -fsSL https://opencode.ai/install | bash",slots:[{label:"Model",alias:"gpt-5"}],env:(e,t)=>[{name:"OPENAI_BASE_URL",value:`${e}/v1`},{name:"OPENAI_API_KEY",value:t||"<your-gateway-key>"}],steps:["Add an OpenAI-compatible provider with the gateway /v1 base URL.","Pick a combo alias as the model."]}];e.s(["CLI_TOOLS",0,t,"toolById",0,function(e){return t.find(t=>t.id===e)}])},51166,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(22016),n=e.i(81189),o=e.i(51514),r=e.i(38286),i=e.i(70789);e.s(["CliToolConfig",0,function(){let[e,l]=(0,a.useState)(null),[d,c]=(0,a.useState)("");return((0,a.useEffect)(()=>{(async()=>{let e=await fetch("/api/gw/admin/endpoint");if(!e.ok)return c("could not reach the gateway");l((await e.json()).port)})()},[]),d)?(0,t.jsx)(r.Empty,{children:d}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"CLI Tools"}),(0,t.jsxs)("p",{className:"mt-1 text-[13px] text-text-muted",children:["Point your coding tools at the gateway. ",e?`Listening on port ${e}.`:""]})]}),(0,t.jsx)("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:i.CLI_TOOLS.map(e=>(0,t.jsxs)(s.default,{href:`/tools/${e.id}`,className:"group rounded-brand-lg border border-border bg-surface p-4 shadow-soft transition-colors hover:border-text-subtle",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsxs)("span",{className:"flex items-center gap-2.5",children:[(0,t.jsx)("span",{className:"flex h-8 w-8 items-center justify-center rounded-brand bg-surface-2 text-text-muted group-hover:text-text",children:(0,t.jsx)(o.Icon,{name:e.icon,size:18})}),(0,t.jsx)("span",{className:"text-[14px] font-semibold text-text",children:e.name})]}),(0,t.jsx)(n.Badge,{tone:"info",children:e.format})]}),(0,t.jsx)("p",{className:"mt-2 text-[12.5px] text-text-muted",children:e.blurb}),(0,t.jsxs)("span",{className:"mt-3 inline-flex items-center gap-1 text-[12px] text-text-subtle group-hover:text-text",children:["Setup ",(0,t.jsx)(o.Icon,{name:"arrow_forward",size:14})]})]},e.id))})]})}])}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,10007,e=>{"use strict";var t=e.i(43476);let r={primary:"bg-accent text-accent-ink shadow-warm hover:bg-accent-hover border border-transparent font-semibold",ghost:"bg-transparent text-text-muted border border-border hover:text-text hover:border-text-subtle",danger:"bg-transparent text-text-muted border border-border hover:text-danger hover:border-danger/50"};e.s(["Button",0,function({variant:e="primary",className:n,...o}){return(0,t.jsx)("button",{className:`inline-flex items-center justify-center gap-1.5 rounded-brand px-3.5 py-2 text-[13px] font-medium transition-colors duration-150 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed ${r[e]}${n?` ${n}`:""}`,...o})},"Field",0,function({label:e,hint:r,children:n}){return(0,t.jsxs)("label",{className:"flex flex-col gap-1.5",children:[(0,t.jsxs)("span",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:[e,r&&(0,t.jsxs)("span",{className:"ml-1.5 lowercase tracking-normal text-text-subtle/70",children:["· ",r]})]}),n]})},"Input",0,function({className:e,...r}){return(0,t.jsx)("input",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none transition-colors${e?` ${e}`:""}`,...r})},"Select",0,function({className:e,...r}){return(0,t.jsx)("select",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text focus:border-accent focus:outline-none transition-colors${e?` ${e}`:""}`,...r})}])},29481,e=>{"use strict";async function t(e,t,r){let n;try{n=await fetch(`/api/gw${t}`,{method:e,headers:void 0!==r?{"content-type":"application/json"}:{},body:void 0!==r?JSON.stringify(r):void 0})}catch(e){return{ok:!1,status:0,data:null,error:e.message}}let o=await n.text(),a=null;try{a=o?JSON.parse(o):null}catch{a=null}if(!n.ok){let e=a?.error??`request failed (${n.status})`;return{ok:!1,status:n.status,data:a,error:e}}return{ok:!0,status:n.status,data:a}}async function r(e,t,r){let n;try{n=await fetch(t,{method:e,headers:void 0!==r?{"content-type":"application/json"}:{},body:void 0!==r?JSON.stringify(r):void 0})}catch(e){return{ok:!1,status:0,data:null,error:e.message}}let o=await n.text(),a=o?JSON.parse(o):null;if(!n.ok){let e=a?.error??`request failed (${n.status})`;return{ok:!1,status:n.status,data:a,error:e}}return{ok:!0,status:n.status,data:a}}e.s(["account",0,{changePassword:(e,t)=>r("POST","/api/password",{current:e,next:t})},"adminApi",0,{providers:()=>t("GET","/admin/providers"),budgets:()=>t("GET","/admin/budgets"),models:()=>t("GET","/admin/models"),keys:()=>t("GET","/admin/keys"),keysUsage:()=>t("GET","/admin/keys/usage"),setBudget:e=>t("PUT","/admin/budgets",e),clearBudget:e=>t("DELETE",`/admin/budgets/${encodeURIComponent(e)}`),addProvider:e=>t("POST","/admin/providers",e),editProvider:(e,r)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}`,r),renameProvider:(e,r)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/rename`,{id:r}),removeProvider:e=>t("DELETE",`/admin/providers/${encodeURIComponent(e)}`),addKey:(e,r,n)=>t("POST",`/admin/providers/${encodeURIComponent(e)}/keys`,{key:r,name:n}),editKey:(e,r,n)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/keys/${r}`,n),removeKey:(e,r)=>t("DELETE",`/admin/providers/${encodeURIComponent(e)}/keys/${r}`),revealKey:(e,r)=>t("GET",`/admin/providers/${encodeURIComponent(e)}/keys/${r}/reveal`),addModel:(e,r,n)=>t("POST",`/admin/providers/${encodeURIComponent(e)}/models`,{model:r,...n}),addModels:(e,r)=>t("POST",`/admin/providers/${encodeURIComponent(e)}/models`,{models:r}),removeModel:(e,r)=>t("DELETE",`/admin/providers/${encodeURIComponent(e)}/models?model=${encodeURIComponent(r)}`),clearModels:e=>t("DELETE",`/admin/providers/${encodeURIComponent(e)}/models`),pricing:()=>t("GET","/admin/pricing"),setModelPrice:(e,r,n)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/models/price`,{model:r,...n}),testProvider:e=>t("POST",`/admin/providers/${encodeURIComponent(e)}/test`),testKey:(e,r)=>t("POST",`/admin/providers/${encodeURIComponent(e)}/keys/${r}/test`),testModel:(e,r)=>t("POST",`/admin/providers/${encodeURIComponent(e)}/models/test?model=${encodeURIComponent(r)}`),validateProvider:e=>t("POST","/admin/providers/validate",e),discoverModels:e=>t("POST",`/admin/providers/${encodeURIComponent(e)}/connect`),reorderKey:(e,r,n)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/keys/reorder`,{from:r,to:n}),toggleKey:(e,r,n)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/keys/${r}/toggle`,{enabled:n}),setProviderStrategy:(e,r,n)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/strategy`,{strategy:r,sticky:n}),setProviderDisabled:(e,r)=>t("PUT",`/admin/providers/${encodeURIComponent(e)}/disabled`,{disabled:r}),setRoute:(e,r)=>t("PUT",`/admin/routes/${encodeURIComponent(e)}`,r),removeRoute:e=>t("DELETE",`/admin/routes/${encodeURIComponent(e)}`),endpoint:()=>t("GET","/admin/endpoint"),setRtk:e=>t("PUT","/admin/endpoint/rtk",{enabled:e}),setCaveman:e=>t("PUT","/admin/endpoint/caveman",{level:e}),setPonytail:e=>t("PUT","/admin/endpoint/ponytail",{level:e}),addServerKey:(e,r)=>t("POST","/admin/endpoint/keys",{key:e,name:r}),editServerKey:(e,r)=>t("PUT",`/admin/endpoint/keys/${e}`,{name:r}),setServerKeyScope:(e,r)=>t("PUT",`/admin/endpoint/keys/${e}/scope`,r),removeServerKey:e=>t("DELETE",`/admin/endpoint/keys/${e}`),revealServerKey:e=>t("GET",`/admin/endpoint/keys/${e}/reveal`),setHeadroom:e=>t("PUT","/admin/endpoint/headroom",e),headroomStatus:()=>t("GET","/admin/headroom/status"),headroomStart:()=>t("POST","/admin/headroom/start"),headroomStop:()=>t("POST","/admin/headroom/stop"),putConfig:e=>t("PUT","/admin/config",{text:e}),version:()=>t("GET","/admin/version"),shutdown:()=>t("POST","/admin/shutdown")},"cliConfig",0,{status:e=>r("GET",`/api/cli-detect/${encodeURIComponent(e)}`),apply:(e,t)=>r("POST",`/api/cli-detect/${encodeURIComponent(e)}`,t),reset:e=>r("DELETE",`/api/cli-detect/${encodeURIComponent(e)}`)}])},13135,e=>{"use strict";var t=e.i(43476),r=e.i(10007),n=e.i(51514);e.s(["ConfirmModal",0,function({title:e,message:o,confirmLabel:a="Delete",onConfirm:s,onCancel:i,busy:l}){return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:i,children:(0,t.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:e=>e.stopPropagation(),children:[(0,t.jsxs)("div",{className:"mb-2 flex items-center gap-2",children:[(0,t.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,t.jsx)(n.Icon,{name:"warning",size:16})}),(0,t.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:e})]}),(0,t.jsx)("p",{className:"mb-4 text-[12.5px] text-text-muted",children:o}),(0,t.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,t.jsx)(r.Button,{variant:"ghost",onClick:i,children:"Cancel"}),(0,t.jsx)(r.Button,{variant:"danger",disabled:l,onClick:s,children:a})]})]})})}])},18566,(e,t,r)=>{t.exports=e.r(76562)},95057,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={formatUrl:function(){return i},formatWithValidation:function(){return d},urlObjectKeys:function(){return l}};for(var o in n)Object.defineProperty(r,o,{enumerable:!0,get:n[o]});let a=e.r(90809)._(e.r(98183)),s=/https?|ftp|gopher|file/;function i(e){let{auth:t,hostname:r}=e,n=e.protocol||"",o=e.pathname||"",i=e.hash||"",l=e.query||"",d=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?d=t+e.host:r&&(d=t+(~r.indexOf(":")?`[${r}]`:r),e.port&&(d+=":"+e.port)),l&&"object"==typeof l&&(l=String(a.urlQueryToSearchParams(l)));let c=e.search||l&&`?${l}`||"";return n&&!n.endsWith(":")&&(n+=":"),e.slashes||(!n||s.test(n))&&!1!==d?(d="//"+(d||""),o&&"/"!==o[0]&&(o="/"+o)):d||(d=""),i&&"#"!==i[0]&&(i="#"+i),c&&"?"!==c[0]&&(c="?"+c),o=o.replace(/[?#]/g,encodeURIComponent),c=c.replace("#","%23"),`${n}${d}${o}${c}${i}`}let l=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"];function d(e){return i(e)}},18581,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useMergedRef",{enumerable:!0,get:function(){return o}});let n=e.r(71645);function o(e,t){let r=(0,n.useRef)(null),o=(0,n.useRef)(null);return(0,n.useCallback)(n=>{if(null===n){let e=r.current;e&&(r.current=null,e());let t=o.current;t&&(o.current=null,t())}else e&&(r.current=a(e,n)),t&&(o.current=a(t,n))},[e,t])}function a(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let r=e(t);return"function"==typeof r?r:()=>e(null)}}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},73668,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"isLocalURL",{enumerable:!0,get:function(){return a}});let n=e.r(18967),o=e.r(52817);function a(e){if(!(0,n.isAbsoluteUrl)(e))return!0;try{let t=(0,n.getLocationOrigin)(),r=new URL(e,t);return r.origin===t&&(0,o.hasBasePath)(r.pathname)}catch(e){return!1}}},84508,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"errorOnce",{enumerable:!0,get:function(){return n}});let n=e=>{}},22016,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={default:function(){return b},useLinkStatus:function(){return v}};for(var o in n)Object.defineProperty(r,o,{enumerable:!0,get:n[o]});let a=e.r(90809),s=e.r(43476),i=a._(e.r(71645)),l=e.r(95057),d=e.r(8372),c=e.r(18581),u=e.r(18967),p=e.r(5550);e.r(33525);let m=e.r(88540),f=e.r(91949),h=e.r(73668),x=e.r(9396);function b(t){var r,n;let o,a,b,[v,y]=(0,i.useOptimistic)(f.IDLE_LINK_STATUS),j=(0,i.useRef)(null),{href:T,as:w,children:P,prefetch:C=null,passHref:S,replace:k,shallow:U,scroll:$,onClick:E,onMouseEnter:R,onTouchStart:N,legacyBehavior:I=!1,onNavigate:O,transitionTypes:_,ref:L,unstable_dynamicOnHover:K,...M}=t;o=P,I&&("string"==typeof o||"number"==typeof o)&&(o=(0,s.jsx)("a",{children:o}));let D=i.default.useContext(d.AppRouterContext),A=!1!==C,B=!1!==C?null===(n=C)||"auto"===n?x.FetchStrategy.PPR:x.FetchStrategy.Full:x.FetchStrategy.PPR,z="string"==typeof(r=w||T)?r:(0,l.formatUrl)(r);if(I){if(o?.$$typeof===Symbol.for("react.lazy"))throw Object.defineProperty(Error("`<Link legacyBehavior>` received a direct child that is either a Server Component, or JSX that was loaded with React.lazy(). This is not supported. Either remove legacyBehavior, or make the direct child a Client Component that renders the Link's `<a>` tag."),"__NEXT_ERROR_CODE",{value:"E863",enumerable:!1,configurable:!0});a=i.default.Children.only(o)}let G=I?a&&"object"==typeof a&&a.ref:L,F=i.default.useCallback(e=>(null!==D&&(j.current=(0,f.mountLinkInstance)(e,z,D,B,A,y)),()=>{j.current&&((0,f.unmountLinkForCurrentNavigation)(j.current),j.current=null),(0,f.unmountPrefetchableInstance)(e)}),[A,z,D,B,y]),q={ref:(0,c.useMergedRef)(F,G),onClick(t){I||"function"!=typeof E||E(t),I&&a.props&&"function"==typeof a.props.onClick&&a.props.onClick(t),!D||t.defaultPrevented||function(t,r,n,o,a,s,l){if("u">typeof window){let d,{nodeName:c}=t.currentTarget;if("A"===c.toUpperCase()&&((d=t.currentTarget.getAttribute("target"))&&"_self"!==d||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.nativeEvent&&2===t.nativeEvent.which)||t.currentTarget.hasAttribute("download"))return;if(!(0,h.isLocalURL)(r)){o&&(t.preventDefault(),location.replace(r));return}if(t.preventDefault(),s){let e=!1;if(s({preventDefault:()=>{e=!0}}),e)return}let{dispatchNavigateAction:u}=e.r(99781);i.default.startTransition(()=>{u(r,o?"replace":"push",!1===a?m.ScrollBehavior.NoScroll:m.ScrollBehavior.Default,n.current,l)})}}(t,z,j,k,$,O,_)},onMouseEnter(e){I||"function"!=typeof R||R(e),I&&a.props&&"function"==typeof a.props.onMouseEnter&&a.props.onMouseEnter(e),D&&A&&(0,f.onNavigationIntent)(e.currentTarget,!0===K)},onTouchStart:function(e){I||"function"!=typeof N||N(e),I&&a.props&&"function"==typeof a.props.onTouchStart&&a.props.onTouchStart(e),D&&A&&(0,f.onNavigationIntent)(e.currentTarget,!0===K)}};return(0,u.isAbsoluteUrl)(z)?q.href=z:I&&!S&&("a"!==a.type||"href"in a.props)||(q.href=(0,p.addBasePath)(z)),b=I?i.default.cloneElement(a,q):(0,s.jsx)("a",{...M,...q,children:o}),(0,s.jsx)(g.Provider,{value:v,children:b})}e.r(84508);let g=(0,i.createContext)(f.IDLE_LINK_STATUS),v=()=>(0,i.useContext)(g);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},94434,e=>{"use strict";var t=e.i(43476),r=e.i(22016),n=e.i(18566),o=e.i(51514);let a=[{href:"/",label:"Endpoint & Key",icon:"api"},{href:"/providers",label:"Providers",icon:"dns"},{href:"/combos",label:"Combos",icon:"layers"},{href:"/usage",label:"Usage",icon:"bar_chart"},{href:"/quota",label:"Budgets",icon:"data_usage"},{href:"/tools",label:"CLI Tools",icon:"terminal"}],s=[{href:"/console",label:"Server Console",icon:"terminal"},{href:"/config",label:"Settings",icon:"settings"}];e.s(["Rail",0,function(){let e=(0,n.usePathname)(),i=(0,n.useRouter)();async function l(){await fetch("/api/logout",{method:"POST"}),i.replace("/login"),i.refresh()}let d=n=>{let a,s="/"===(a=n.href)?"/"===e||e.startsWith("/endpoint"):e===a||e.startsWith(`${a}/`);return(0,t.jsx)(r.default,{href:n.href,"data-label":n.label,className:`rail-icon${s?" rail-icon-active":""}`,"aria-label":n.label,children:(0,t.jsx)(o.Icon,{name:n.icon,size:20,fill:s})},n.href)};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.default,{href:"/",className:"rail-brand","aria-label":"aigetwey",children:(0,t.jsxs)("svg",{viewBox:"0 0 512 512",width:"26",height:"26","aria-hidden":!0,children:[(0,t.jsx)("text",{x:"120",y:"338",fontFamily:"ui-sans-serif, Arial, sans-serif",fontSize:"260",fontWeight:"800",textAnchor:"middle",fill:"#14140f",children:"a"}),(0,t.jsxs)("g",{fill:"none",stroke:"#14140f",strokeWidth:"34",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("polyline",{points:"276,182 352,256 276,330"}),(0,t.jsx)("polyline",{points:"346,182 422,256 346,330"})]})]})}),(0,t.jsxs)("nav",{className:"flex flex-col items-center gap-3",children:[a.map(d),(0,t.jsx)("div",{className:"rail-divider"}),s.map(d)]}),(0,t.jsx)("button",{onClick:l,"data-label":"Disconnect",className:"rail-icon","aria-label":"Disconnect",children:(0,t.jsx)(o.Icon,{name:"logout",size:19})})]})}])},18993,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(18566),o=e.i(51514),a=e.i(59919),s=e.i(13135),i=e.i(29481);let l={"":"Endpoint & Key",endpoint:"Endpoint & Key",providers:"Providers",combos:"Combos",usage:"Usage",quota:"Budgets",tools:"CLI Tools",console:"Server Console",config:"Settings"};function d({version:e}){let[n,a]=(0,r.useState)(!1),s=`npm install -g aigetwey@${e}`;return(0,t.jsx)("button",{onClick:()=>{navigator.clipboard.writeText(s).then(()=>{a(!0),setTimeout(()=>a(!1),1800)})},className:"flex h-6 w-6 items-center justify-center rounded-full text-warning/70 transition-colors hover:bg-warning/10 hover:text-warning",title:`Copy: ${s}`,children:(0,t.jsx)(o.Icon,{name:n?"check":"content_copy",size:13})})}e.s(["TopBar",0,function(){let e=(0,n.usePathname)(),{theme:c,toggle:u}=(0,a.useTheme)(),p="/"===e?"":e.split("/")[1]??"",m=l[p]??p,[f,h]=(0,r.useState)(null),[x,b]=(0,r.useState)(!1),[g,v]=(0,r.useState)(!1),[y,j]=(0,r.useState)(!1);async function T(){j(!0),await i.adminApi.shutdown(),v(!0),b(!1),j(!1)}return(0,r.useEffect)(()=>{i.adminApi.version().then(e=>{e.ok&&e.data&&h(e.data)})},[]),(0,t.jsxs)("header",{className:"console-topbar",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 text-[13px]",children:[(0,t.jsx)("span",{className:"text-text-subtle",children:"aigetwey"}),(0,t.jsx)("span",{className:"text-text-subtle",children:"/"}),(0,t.jsx)("span",{className:"font-medium text-text",children:m})]}),(0,t.jsxs)("div",{className:"ml-auto flex items-center gap-2.5",children:[f&&(f.updateAvailable?(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsxs)("a",{href:"https://github.com/xk1ko/aigetwey/releases",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-1.5 rounded-full border border-warning/30 bg-warning/10 px-2.5 py-1 text-[11px] font-medium text-warning transition-colors hover:bg-warning/20",title:`Update available — v${f.latest} is out (you have v${f.current})`,children:[(0,t.jsx)(o.Icon,{name:"arrow_upward",size:12}),"v",f.latest," available"]}),(0,t.jsx)(d,{version:f.latest})]}):(0,t.jsxs)("span",{className:"text-[11px] text-text-subtle",title:"You're on the latest version",children:["v",f.current]})),(0,t.jsx)("button",{onClick:u,className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-text","aria-label":"Toggle theme",title:"dark"===c?"Switch to light mode":"Switch to dark mode",children:(0,t.jsx)(o.Icon,{name:"dark"===c?"light_mode":"dark_mode",size:18})}),(0,t.jsx)("button",{onClick:()=>b(!0),className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-danger","aria-label":"Shut down gateway",title:"Shut down the gateway",children:(0,t.jsx)(o.Icon,{name:"power_settings_new",size:18})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-full border border-border bg-surface py-1 pl-1 pr-3",children:[(0,t.jsx)("span",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-[11px] font-bold text-accent-ink",children:"A"}),(0,t.jsx)("span",{className:"text-[12px] text-text-muted",children:"admin"})]})]}),x&&(0,t.jsx)(s.ConfirmModal,{title:"Shut down gateway?",message:"The gateway process will stop and all requests will fail until you restart it (run.sh). The dashboard stays up but can't reach the gateway.",confirmLabel:"Shut down",busy:y,onConfirm:T,onCancel:()=>b(!1)}),g&&(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6",children:(0,t.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 text-center shadow-elevated",children:[(0,t.jsx)("span",{className:"mx-auto mb-2 flex h-9 w-9 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,t.jsx)(o.Icon,{name:"power_settings_new",size:20})}),(0,t.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Gateway stopped"}),(0,t.jsxs)("p",{className:"mt-1 text-[12.5px] text-text-muted",children:["Restart it with ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"run.sh"}),", then reload this page."]})]})})]})}])}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,81189,e=>{"use strict";var t=e.i(43476);let n={live:"bg-success/12 text-success",down:"bg-danger/12 text-danger",warn:"bg-warning/12 text-warning",info:"bg-info/12 text-info",neutral:"bg-surface-2 text-text-muted"};function a({tone:e="neutral",children:i,className:s}){return(0,t.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${n[e]}${s?` ${s}`:""}`,children:i})}e.s(["Badge",0,a,"FormatBadge",0,function({format:e}){return(0,t.jsx)(a,{tone:"info",children:e})}])},38286,e=>{"use strict";var t=e.i(43476);e.s(["Empty",0,function({children:e}){return(0,t.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:e})},"Stat",0,function({label:e,value:n,sub:a}){return(0,t.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,t.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:e}),(0,t.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:n}),a&&(0,t.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:a})]})},"fmt",0,{int:e=>e.toLocaleString("en-US"),compact:e=>Math.abs(e)>=1e6?`${(e/1e6).toFixed(1)}M`:Math.abs(e)>=1e3?`${(e/1e3).toFixed(1)}K`:String(Math.round(e)),cost:e=>0===e?"$0":e<.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`,time:e=>new Date(e).toLocaleString("en-US",{hour12:!1}),date(e){let t=new Date(e);return`${String(t.getDate()).padStart(2,"0")}/${String(t.getMonth()+1).padStart(2,"0")}/${t.getFullYear()}`},ago(e){let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`},duration(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;if(t<3600)return`${Math.floor(t/60)}m ${t%60}s`;let n=Math.floor(t/3600),a=Math.floor(t%3600/60);if(n<24)return`${n}h ${a}m`;let i=Math.floor(n/24);return`${i}d ${n%24}h`}}])},69163,e=>{"use strict";var t=e.i(43476);e.s(["CardTitle",0,function({title:e,sub:n,icon:a}){return(0,t.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[a,(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:e}),n&&(0,t.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:n})]})]})},"RichCard",0,function({header:e,footer:n,children:a,className:i}){return(0,t.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${i?` ${i}`:""}`,children:[e&&(0,t.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:e}),(0,t.jsx)("div",{className:"p-4",children:a}),n&&(0,t.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:n})]})}])},53854,45570,e=>{"use strict";var t=e.i(43476);function n(e,t){return RegExp("^"+e.split("*").map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i").test(t)}let a={vision:!1,pdf:!1,audioInput:!1,videoInput:!1,imageOutput:!1,audioOutput:!1,search:!1,tools:!0,reasoning:!1,thinkingFormat:null,thinkingCanDisable:!0,thinkingRange:null,contextWindow:2e5,maxOutput:64e3},i={"claude-opus-4.6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-opus-4.7":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-opus-4-6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:128e3},"claude-sonnet-4.6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:64e3},"claude-sonnet-4-6":{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive",contextWindow:1e6,maxOutput:64e3},"gpt-image-1":{imageOutput:!0,tools:!1},"glm-4.6v":{vision:!0,reasoning:!0,thinkingFormat:"zai",contextWindow:128e3},"vision-model":{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6},"coder-model":{reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6}},s={"codebuddy-cn":{"glm-5.2":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:48e3},"glm-5.1":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"glm-5.0":{reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:48e3},"glm-5.0-turbo":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"glm-5v-turbo":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:38e3},"glm-4.7":{reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:48e3},"minimax-m3":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:512e3,maxOutput:48e3},"minimax-m2.7":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:48e3},"kimi-k2.7":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:256e3,maxOutput:32e3},"kimi-k2.6":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:256e3,maxOutput:32e3},"kimi-k2.5":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:164e3,maxOutput:32e3},"hy3-preview":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:192e3,maxOutput:64e3},"deepseek-v4-pro":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:5e4},"deepseek-v4-flash":{vision:!0,reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:1e6,maxOutput:5e4},"deepseek-v3-2-volc":{reasoning:!0,thinkingFormat:"openai",thinkingCanDisable:!1,contextWindow:96e3,maxOutput:32e3}}},o=[{pattern:"*claude*opus-4.6*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*opus-4.7*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*opus-4.8*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*sonnet-4.6*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*sonnet-4.7*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-adaptive"}},{pattern:"*claude*haiku*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*opus*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*sonnet*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*claude*fable*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget",contextWindow:1e6,maxOutput:128e3}},{pattern:"*claude*mythos*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget",contextWindow:1e6,maxOutput:128e3}},{pattern:"*claude-3*",caps:{vision:!0}},{pattern:"*claude*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"claude-budget"}},{pattern:"*gemini*image*",caps:{vision:!0,imageOutput:!0,contextWindow:1048576}},{pattern:"*gemini-3*pro*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-level",thinkingCanDisable:!1,contextWindow:1048576,maxOutput:65535}},{pattern:"*gemini-3*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-level",thinkingCanDisable:!1,contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini-2.5*",caps:{vision:!0,audioInput:!0,videoInput:!0,reasoning:!0,search:!0,thinkingFormat:"gemini-budget",thinkingRange:{min:0,max:24576},contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini-2*",caps:{vision:!0,audioInput:!0,videoInput:!0,search:!0,contextWindow:1048576,maxOutput:65536}},{pattern:"*gemini*",caps:{vision:!0,search:!0,contextWindow:1048576}},{pattern:"*gemma*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*nanobanana*",caps:{vision:!0,imageOutput:!0}},{pattern:"*gpt-5*image*",caps:{imageOutput:!0}},{pattern:"*gpt-5*codex*",caps:{reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:4e5,maxOutput:128e3}},{pattern:"*gpt-5*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:4e5,maxOutput:128e3}},{pattern:"*gpt-4o*",caps:{vision:!0,search:!0,contextWindow:128e3,maxOutput:16384}},{pattern:"*gpt-4.1*",caps:{vision:!0,contextWindow:1e6,maxOutput:32768}},{pattern:"*gpt-4-turbo*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*gpt-4*",caps:{contextWindow:128e3}},{pattern:"*gpt-3.5*",caps:{contextWindow:16385,maxOutput:4096}},{pattern:"*gpt-oss*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:128e3}},{pattern:"*o1-mini*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:128e3}},{pattern:"*o1*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*o3*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*o4*",caps:{vision:!0,reasoning:!0,thinkingFormat:"openai",contextWindow:2e5,maxOutput:1e5}},{pattern:"*grok*image*",caps:{imageOutput:!0}},{pattern:"*grok-code*",caps:{reasoning:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*grok-4*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*grok-3*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:131072}},{pattern:"*grok*",caps:{vision:!0,reasoning:!0,search:!0,thinkingFormat:"openai",contextWindow:256e3}},{pattern:"*qwen*vl*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*qwen*max*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6,maxOutput:65536}},{pattern:"*qwen*plus*",caps:{vision:!0,reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6,maxOutput:65536}},{pattern:"*qwen*235b*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*qwen*coder*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:1e6}},{pattern:"*qwq*",caps:{reasoning:!0,thinkingFormat:"qwen",thinkingCanDisable:!1,contextWindow:131072}},{pattern:"*qwen*",caps:{reasoning:!0,thinkingFormat:"qwen",contextWindow:262144}},{pattern:"*kimi*k2.7*code*",caps:{vision:!0,reasoning:!0,thinkingFormat:"kimi",thinkingCanDisable:!1,contextWindow:262144,maxOutput:262144}},{pattern:"*kimi*k2*",caps:{vision:!0,reasoning:!0,thinkingFormat:"kimi",contextWindow:262144,maxOutput:262144}},{pattern:"*kimi*",caps:{reasoning:!0,thinkingFormat:"kimi",contextWindow:262144}},{pattern:"*glm-5*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5,maxOutput:128e3}},{pattern:"*glm-4.7*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5,maxOutput:128e3}},{pattern:"*glm-4*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5}},{pattern:"*glm*",caps:{reasoning:!0,thinkingFormat:"zai",contextWindow:2e5}},{pattern:"*deepseek-v4*",caps:{reasoning:!0,thinkingFormat:"deepseek",contextWindow:1e6,maxOutput:384e3}},{pattern:"*reasoner*",caps:{reasoning:!0,thinkingFormat:"deepseek",thinkingCanDisable:!1,contextWindow:128e3}},{pattern:"*deepseek-r*",caps:{reasoning:!0,thinkingFormat:"deepseek",thinkingCanDisable:!1,contextWindow:128e3}},{pattern:"*deepseek-chat*",caps:{contextWindow:128e3}},{pattern:"*deepseek*",caps:{reasoning:!0,thinkingFormat:"deepseek",contextWindow:128e3}},{pattern:"*minimax*image*",caps:{imageOutput:!0}},{pattern:"*minimax-m3*",caps:{vision:!0,reasoning:!0,thinkingFormat:"minimax",contextWindow:1048576,maxOutput:512e3}},{pattern:"*minimax-m2.7*",caps:{reasoning:!0,thinkingFormat:"minimax",thinkingCanDisable:!1,contextWindow:204800,maxOutput:131072}},{pattern:"*minimax*",caps:{reasoning:!0,thinkingFormat:"minimax",thinkingCanDisable:!1,contextWindow:2e5,maxOutput:131072}},{pattern:"*mimo*v2.5*",caps:{vision:!0,contextWindow:1048576,maxOutput:131072}},{pattern:"*mimo*omni*",caps:{vision:!0,audioInput:!0,contextWindow:262144,maxOutput:131072}},{pattern:"*mimo*",caps:{vision:!0,contextWindow:262144,maxOutput:131072}},{pattern:"*llama-4*",caps:{vision:!0,contextWindow:1e6}},{pattern:"*llama*",caps:{contextWindow:128e3}},{pattern:"*codestral*",caps:{contextWindow:256e3}},{pattern:"*mistral-large*",caps:{vision:!0,contextWindow:256e3}},{pattern:"*mistral*",caps:{contextWindow:128e3}},{pattern:"*command-a-vision*",caps:{vision:!0,contextWindow:128e3}},{pattern:"*command*",caps:{contextWindow:128e3}},{pattern:"*sonar*",caps:{search:!0,contextWindow:128e3}},{pattern:"*pplx*",caps:{search:!0,contextWindow:128e3}},{pattern:"*perplexity*",caps:{search:!0,contextWindow:128e3}},{pattern:"*hunyuan*",caps:{reasoning:!0,thinkingFormat:"hunyuan",contextWindow:262144,maxOutput:262144}},{pattern:"hy3*",caps:{reasoning:!0,thinkingFormat:"hunyuan",contextWindow:262144,maxOutput:262144}},{pattern:"*step-*",caps:{reasoning:!0,thinkingFormat:"step",contextWindow:128e3}},{pattern:"*nemotron*",caps:{reasoning:!0,contextWindow:128e3}},{pattern:"*ling-*",caps:{reasoning:!0,contextWindow:128e3}}];function r(e,t){if(!t)return{...a};if(e&&s[e]?.[t])return{...a,...s[e][t]};let r=(t.includes("/")?t.split("/").pop():t)??t;if(i[r])return{...a,...i[r]};if(i[t])return{...a,...i[t]};for(let{pattern:e,caps:i}of o)if(n(e,r)||n(e,t))return{...a,...i};return{...a}}e.s(["getCapabilitiesForModel",0,r,"modalitiesForModel",0,function(e){let t=e.indexOf("/"),n=r(t>0?e.slice(0,t):null,t>0?e.slice(t+1):e),a=["text"];n.vision&&a.push("image"),n.pdf&&a.push("pdf"),n.audioInput&&a.push("audio"),n.videoInput&&a.push("video");let i=["text"];return n.imageOutput&&i.push("image"),n.audioOutput&&i.push("audio"),{input:a,output:i}}],45570);var l=e.i(51514);let c={vision:{icon:"visibility",label:"Vision",desc:"Supports image input",color:"text-info"},reasoning:{icon:"neurology",label:"Reasoning",desc:"Supports reasoning / thinking",color:"text-warning"}};e.s(["CapacityBadges",0,function({model:e,provider:n=null,size:a=15,className:i=""}){let s=r(n,e),o=Object.keys(c).filter(e=>s[e]);return 0===o.length?null:(0,t.jsx)("span",{className:`inline-flex flex-none items-center gap-0.5 ${i}`,children:o.map(e=>(0,t.jsx)("span",{title:`${c[e].label} — ${c[e].desc}`,className:"leading-none",children:(0,t.jsx)(l.Icon,{name:c[e].icon,size:a,className:c[e].color})},e))})}],53854)},78347,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(51514),i=e.i(53854);e.s(["ModelPicker",0,function({title:e="Add models",note:s="Click to add, click again to remove.",searchPlaceholder:o="Search models…",groups:r,selected:l,onToggle:c,onClose:d,showThinkingHint:p=!0}){let[x,u]=(0,n.useState)(""),m=x.trim().toLowerCase(),g=r.map(e=>({...e,items:m?e.items.filter(e=>e.value.toLowerCase().includes(m)):e.items})).filter(e=>e.items.length>0),h=new Set(l);return(0,t.jsx)("div",{className:"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/60 p-6 sm:p-10",onClick:d,children:(0,t.jsxs)("div",{className:"flex max-h-[80vh] w-full max-w-lg flex-col rounded-brand-lg border border-border bg-surface shadow-elevated",onClick:e=>e.stopPropagation(),children:[(0,t.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[(0,t.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:e}),(0,t.jsx)("button",{onClick:d,className:"text-text-subtle hover:text-text","aria-label":"Close",children:(0,t.jsx)(a.Icon,{name:"close",size:18})})]}),(0,t.jsxs)("div",{className:"border-b border-border-subtle px-4 py-3",children:[(0,t.jsx)("p",{className:"mb-2 text-[12px] text-text-muted",children:s}),(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)(a.Icon,{name:"search",size:15,className:"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle"}),(0,t.jsx)("input",{autoFocus:!0,value:x,onChange:e=>u(e.target.value),placeholder:o,className:"w-full rounded-brand border border-border bg-bg py-2 pl-8 pr-3 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none"})]})]}),(0,t.jsx)("div",{className:"flex-1 overflow-y-auto px-4 py-3",children:0===g.length?(0,t.jsxs)("p",{className:"py-6 text-center text-[12.5px] text-text-subtle",children:["No models match “",x,"”."]}):(0,t.jsx)("div",{className:"space-y-4",children:g.map(e=>(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-text-subtle",children:[e.label," ",(0,t.jsxs)("span",{className:"tnum text-text-subtle/70",children:["(",e.items.length,")"]})]}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:e.items.map(e=>{let n=h.has(e.value);return(0,t.jsxs)("button",{type:"button",onClick:()=>c(e.value),className:`inline-flex items-center gap-1 rounded-brand border px-2 py-1 text-[12px] transition-colors ${n?"border-accent bg-accent-soft text-accent":"border-border bg-bg text-text-muted hover:border-text-subtle hover:text-text"}`,children:[n&&(0,t.jsx)(a.Icon,{name:"check",size:12}),(0,t.jsx)("span",{className:"tnum",children:e.label}),(0,t.jsx)(i.CapacityBadges,{model:e.value,size:13}),e.tag&&(0,t.jsx)("span",{className:"rounded bg-surface-2 px-1 text-[10px] text-text-subtle",children:e.tag})]},e.value)})})]},e.label))})}),p&&(0,t.jsxs)("div",{className:"border-t border-border-subtle px-4 py-2 text-[11px] text-text-subtle",children:[(0,t.jsx)(a.Icon,{name:"neurology",size:12,className:"mr-1 inline align-text-bottom text-warning"}),"Reasoning models accept a thinking suffix — call"," ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(high)"})," or"," ",(0,t.jsx)("code",{className:"rounded bg-surface-2 px-1 text-text-muted",children:"model(none)"})," (high·low·medium·minimal·auto·none·or a token budget)."]}),(0,t.jsxs)("div",{className:"flex items-center justify-between border-t border-border-subtle px-4 py-3",children:[(0,t.jsxs)("span",{className:"tnum text-[12px] text-text-subtle",children:[l.length," selected"]}),(0,t.jsx)("button",{onClick:d,className:"rounded-brand bg-accent px-3.5 py-1.5 text-[13px] font-semibold text-accent-ink hover:bg-accent-hover",children:"Done"})]})]})})}])},70789,e=>{"use strict";let t=[{id:"claude-code",name:"Claude Code",icon:"smart_toy",format:"anthropic",blurb:"Anthropic CLI. Point its base URL + key at the gateway.",autoConfig:!0,install:"npm i -g @anthropic-ai/claude-code",slots:[{label:"Opus · heavy",alias:"claude-opus-4-1"},{label:"Sonnet · default",alias:"claude-sonnet-4-6"},{label:"Haiku · fast",alias:"claude-haiku-4-5"}],env:(e,t)=>[{name:"ANTHROPIC_BASE_URL",value:e},{name:"ANTHROPIC_API_KEY",value:t||"<your-gateway-key>"}],steps:["Export the two variables in the shell you run `claude` from.","Create a combo named like each slot above so Claude Code's model ids resolve.","The gateway translates Anthropic ↔ provider format, so any provider works behind it."]},{id:"opencode",name:"opencode",icon:"code_blocks",format:"openai",blurb:"OpenAI-compatible provider. Set base_url to /v1.",autoConfig:!0,install:"curl -fsSL https://opencode.ai/install | bash",slots:[{label:"Model",alias:"gpt-5"}],env:(e,t)=>[{name:"OPENAI_BASE_URL",value:`${e}/v1`},{name:"OPENAI_API_KEY",value:t||"<your-gateway-key>"}],steps:["Add an OpenAI-compatible provider with the gateway /v1 base URL.","Pick a combo alias as the model."]}];e.s(["CLI_TOOLS",0,t,"toolById",0,function(e){return t.find(t=>t.id===e)}])},61092,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(18566),i=e.i(69163),s=e.i(81189),o=e.i(10007),r=e.i(78347),l=e.i(51514),c=e.i(38286),d=e.i(29481),p=e.i(70789),x=e.i(45570);function u({label:e,children:n,top:a}){return(0,t.jsxs)("div",{className:`grid grid-cols-[7rem_1fr] gap-3 ${a?"items-start":"items-center"}`,children:[(0,t.jsx)("span",{className:`text-[12px] font-medium text-text-subtle ${a?"pt-1.5":""}`,children:e}),(0,t.jsx)("div",{className:"min-w-0",children:n})]})}function m({text:e}){let[a,i]=(0,n.useState)(!1);return(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)("pre",{className:"overflow-x-auto rounded-brand border border-border-subtle bg-bg px-3 py-2.5 font-mono text-[12.5px] leading-relaxed text-text",children:e}),(0,t.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(e),i(!0),setTimeout(()=>i(!1),1200)},className:"absolute right-2 top-2 flex items-center gap-1 rounded-brand border border-border bg-surface px-2 py-1 text-[11px] text-text-muted hover:text-text",children:[(0,t.jsx)(l.Icon,{name:a?"check":"content_copy",size:13})," ",a?"copied":"copy"]})]})}e.s(["ToolDetail",0,function({id:e}){let g=(0,a.useRouter)(),h=(0,p.toolById)(e),[b,v]=(0,n.useState)(null),[f,k]=(0,n.useState)([]),[j,w]=(0,n.useState)(0),[y,N]=(0,n.useState)(""),[C,F]=(0,n.useState)([]),[O,W]=(0,n.useState)(""),[S,I]=(0,n.useState)(""),[$,_]=(0,n.useState)(!1),[A,T]=(0,n.useState)(""),[D,R]=(0,n.useState)(!1),[M,E]=(0,n.useState)("");(0,n.useEffect)(()=>{F(JSON.parse(localStorage.getItem(`cli-saved-bases-${e}`)??"[]")),W(localStorage.getItem(`cli-selected-base-${e}`)??""),T(localStorage.getItem(`cli-custom-key-${e}`)??"")},[e]);let[z,P]=(0,n.useState)(""),[L,B]=(0,n.useState)(null),[U,q]=(0,n.useState)(""),[K,H]=(0,n.useState)(""),[J,Y]=(0,n.useState)([]),[V,G]=(0,n.useState)([]),[Q,X]=(0,n.useState)(!1),[Z,ee]=(0,n.useState)(null),[et,en]=(0,n.useState)([]),[ea,ei]=(0,n.useState)(""),[es,eo]=(0,n.useState)({opus:"",sonnet:"",haiku:""}),er=h?.format==="anthropic",el=(0,n.useCallback)(async()=>{h?.autoConfig&&B((await d.cliConfig.status(h.id)).data)},[h]);function ec(t){let n=t.trim();if(!n)return;let a=[n,...C.filter(e=>e!==n)];F(a),W(n),localStorage.setItem(`cli-saved-bases-${e}`,JSON.stringify(a)),localStorage.setItem(`cli-selected-base-${e}`,n),I(""),_(!1)}async function ed(){if(!h||!b)return;H(""),localStorage.setItem(`cli-selected-base-${e}`,O),A.trim()?localStorage.setItem(`cli-custom-key-${e}`,A.trim()):localStorage.removeItem(`cli-custom-key-${e}`);let t=`http://127.0.0.1:${b.port}`,n=O||t,a=A.trim()||b.keys.length&&y||void 0;if(er){let e={};es.opus&&(e.opus=es.opus),es.sonnet&&(e.sonnet=es.sonnet),es.haiku&&(e.haiku=es.haiku),q("apply");let t=await d.cliConfig.apply(h.id,{base:n,key:a,models:e});q(""),H(t.ok?"Wrote config ✓":t.error??"failed"),t.ok&&el();return}if(0===et.length)return void H("add at least one model");q("apply");let i=await d.cliConfig.apply(h.id,{base:n,key:a,models:et,active:ea});q(""),H(i.ok?"Wrote config ✓":i.error??"failed"),i.ok&&el()}async function ep(){if(!h)return;q("reset"),H("");let e=await d.cliConfig.reset(h.id);q(""),e.ok?(H("Removed gateway config ✓"),el()):H(e.error??"failed")}if((0,n.useEffect)(()=>{el()},[el]),(0,n.useEffect)(()=>{L?.installed&&(er&&L.modelSlots?eo({opus:L.modelSlots.opus??"",sonnet:L.modelSlots.sonnet??"",haiku:L.modelSlots.haiku??""}):!er&&L.models&&L.models.length>0&&(en(L.models),ei(L.activeModel??L.models[0]??"")))},[L,er]),(0,n.useEffect)(()=>{(async()=>{let[e,t]=await Promise.all([fetch("/api/gw/admin/endpoint"),fetch("/api/gw/admin/config")]);if(!e.ok)return P("could not reach the gateway");if(v(await e.json()),t.ok){let e=await t.json(),n=e.models.map(e=>e.alias);k(n);let a=e.providers.filter(e=>!e.disabled);Y([...n,...a.flatMap(e=>e.models.map(t=>`${e.id}/${t.id}`))]);let i=[];for(let e of(n.length&&i.push({label:"Combos",items:n.map(e=>({value:e,label:e}))}),a))e.models.length&&i.push({label:e.id,items:e.models.map(t=>({value:`${e.id}/${t.id}`,label:`${e.id}/${t.id}`}))});G(i)}})()},[]),(0,n.useEffect)(()=>{b&&0!==b.keys.length&&d.adminApi.revealServerKey(j).then(e=>N(e.ok?e.data?.key??"":""))},[b,j]),!h)return(0,t.jsx)(c.Empty,{children:"Unknown tool."});if(z)return(0,t.jsx)(c.Empty,{children:z});if(!b)return(0,t.jsx)(c.Empty,{children:"Loading…"});let ex=`http://127.0.0.1:${b.port}`,eu=O||ex,em=A.trim()||y,eg=h.env(eu,em).map(e=>`export ${e.name}="${e.value}"`).join("\n"),eh=et.length?et:L?.models??[],eb="opencode"===h.id?JSON.stringify({provider:{aigetwey:{npm:"@ai-sdk/openai-compatible",options:{baseURL:`${eu}/v1`,apiKey:y||"aigetwey"},models:Object.fromEntries(eh.map(e=>[e,{name:e,modalities:(0,x.modalitiesForModel)(e)}]))}},model:`aigetwey/${ea||eh[0]||""}`},null,2):null,ev="claude-code"===h.id?JSON.stringify({hasCompletedOnboarding:!0,env:{ANTHROPIC_BASE_URL:eu,API_TIMEOUT_MS:"600000",...y?{ANTHROPIC_AUTH_TOKEN:y}:{},...es.opus?{ANTHROPIC_DEFAULT_OPUS_MODEL:es.opus}:{},...es.sonnet?{ANTHROPIC_DEFAULT_SONNET_MODEL:es.sonnet}:{},...es.haiku?{ANTHROPIC_DEFAULT_HAIKU_MODEL:es.haiku}:{}}},null,2):null;return(0,t.jsxs)("div",{children:[(0,t.jsxs)("button",{onClick:()=>g.push("/tools"),className:"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text",children:[(0,t.jsx)(l.Icon,{name:"arrow_back",size:15})," CLI Tools"]}),(0,t.jsxs)("div",{className:"mb-6 flex items-center gap-3",children:[(0,t.jsx)("span",{className:"flex h-9 w-9 items-center justify-center rounded-brand bg-surface-2 text-text-muted",children:(0,t.jsx)(l.Icon,{name:h.icon,size:20})}),(0,t.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:h.name}),(0,t.jsx)(s.Badge,{tone:"info",children:h.format})]}),(0,t.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[h.autoConfig&&(0,t.jsx)(i.RichCard,{className:"lg:col-span-2",header:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.CardTitle,{title:"Local setup",sub:"detect this tool on your machine and write its config for you"}),L&&(0,t.jsx)(s.Badge,{tone:L.installed?L.configured?"live":"warn":"neutral",children:L.installed?L.configured?"configured":"detected":"not detected"})]}),children:L?L.installed?(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)(u,{label:"Endpoint",children:(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsxs)(o.Select,{value:O||"__auto__",onChange:t=>{let n=t.target.value;if("__custom__"===n)return void _(!0);let a="__auto__"===n?"":n;W(a),localStorage.setItem(`cli-selected-base-${e}`,a)},className:"flex-1",children:[(0,t.jsxs)("option",{value:"__auto__",children:[ex," (auto)"]}),C.map(e=>(0,t.jsx)("option",{value:e,children:e},e)),(0,t.jsx)("option",{value:"__custom__",children:"Custom URL…"})]}),O&&(0,t.jsx)(o.Button,{variant:"ghost",className:"px-2 py-1 flex-none",title:"remove this URL",onClick:()=>{let t=C.filter(e=>e!==O);F(t),localStorage.setItem(`cli-saved-bases-${e}`,JSON.stringify(t)),W(""),localStorage.setItem(`cli-selected-base-${e}`,"")},children:(0,t.jsx)(l.Icon,{name:"delete",size:15})})]}),$&&(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("input",{autoFocus:!0,value:S,onChange:e=>I(e.target.value),onKeyDown:e=>"Enter"===e.key&&ec(S),placeholder:"https://your-gateway.example.com",className:"flex-1 rounded-brand border border-accent bg-bg px-2.5 py-1.5 font-mono text-[12px] text-text outline-none placeholder:text-text-subtle"}),(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>ec(S),children:"Add"}),(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>{_(!1),I("")},children:"Cancel"})]})]})}),(0,t.jsx)(u,{label:"API Key",children:(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsxs)(o.Select,{value:A?"__custom__":String(j),onChange:t=>{let n=t.target.value;"__custom__"===n?R(!0):(T(""),w(Number(n)),localStorage.removeItem(`cli-custom-key-${e}`))},className:"flex-1",children:[b.keys.map((e,n)=>(0,t.jsx)("option",{value:n,children:e.name||`key ${n+1}`},n)),A&&(0,t.jsxs)("option",{value:"__custom__",children:[A.slice(0,12),"… (custom)"]}),!A&&(0,t.jsx)("option",{value:"__custom__",children:"Custom key…"})]}),A&&(0,t.jsx)(o.Button,{variant:"ghost",className:"px-2 py-1 flex-none",title:"remove custom key",onClick:()=>{T(""),localStorage.removeItem(`cli-custom-key-${e}`)},children:(0,t.jsx)(l.Icon,{name:"delete",size:15})})]}),D&&(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("input",{autoFocus:!0,value:M,onChange:e=>E(e.target.value),onKeyDown:t=>{"Enter"===t.key&&(T(M.trim()),localStorage.setItem(`cli-custom-key-${e}`,M.trim()),R(!1),E(""))},placeholder:"paste API key…",className:"flex-1 rounded-brand border border-accent bg-bg px-2.5 py-1.5 font-mono text-[12px] text-text outline-none placeholder:text-text-subtle"}),(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>{T(M.trim()),localStorage.setItem(`cli-custom-key-${e}`,M.trim()),R(!1),E("")},children:"Add"}),(0,t.jsx)(o.Button,{variant:"ghost",onClick:()=>{R(!1),E("")},children:"Cancel"})]})]})}),er?(0,t.jsx)(u,{label:"Models",top:!0,children:(0,t.jsx)("div",{className:"flex flex-col gap-2",children:["opus","sonnet","haiku"].map(e=>(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"w-16 flex-none text-[12px] capitalize text-text-subtle",children:e}),es[e]?(0,t.jsxs)("span",{className:"flex flex-1 items-center gap-1.5 rounded border border-accent bg-accent-soft px-2 py-1 font-mono text-[12px] text-accent",children:[(0,t.jsx)("span",{className:"flex-1 truncate",children:es[e]}),(0,t.jsx)("button",{onClick:()=>eo(t=>({...t,[e]:""})),className:"flex-none hover:text-danger","aria-label":"clear",children:(0,t.jsx)(l.Icon,{name:"close",size:12})})]}):(0,t.jsxs)("button",{onClick:()=>{ee(e),X(!0)},className:"flex items-center gap-1 rounded border border-dashed border-border px-2.5 py-1 text-[12px] text-text-subtle hover:border-accent hover:text-accent",children:[(0,t.jsx)(l.Icon,{name:"add",size:13})," Add model"]})]},e))})}):(0,t.jsx)(u,{label:"Models",top:!0,children:(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"flex min-h-[34px] flex-wrap gap-1.5 rounded-brand border border-border-subtle bg-bg px-2 py-1.5",children:0===et.length?(0,t.jsx)("span",{className:"text-[12px] text-text-subtle",children:"No models — add one below."}):et.map(e=>(0,t.jsxs)("span",{onClick:()=>ei(t=>t===e?"":e),title:e===ea?"active model — click to clear":"click to set active",className:`inline-flex cursor-pointer items-center gap-1 rounded px-2 py-0.5 text-[12px] transition-colors ${e===ea?"border border-accent bg-accent-soft text-accent":"border border-transparent bg-surface-2 text-text-muted hover:border-border"}`,children:[e===ea&&(0,t.jsx)(l.Icon,{name:"star",size:11}),(0,t.jsx)("span",{className:"tnum",children:e}),(0,t.jsx)("button",{onClick:t=>{t.stopPropagation(),en(t=>t.filter(t=>t!==e)),ei(t=>t===e?"":t)},className:"hover:text-danger","aria-label":`Remove ${e}`,children:(0,t.jsx)(l.Icon,{name:"close",size:12})})]},e))}),(0,t.jsxs)("div",{className:"mt-1.5 flex items-center gap-2",children:[(0,t.jsxs)(o.Button,{type:"button",variant:"ghost",onClick:()=>X(!0),children:[(0,t.jsx)(l.Icon,{name:"add",size:15})," Add models"]}),(0,t.jsx)("span",{className:"text-[11.5px] text-text-subtle",children:ea?(0,t.jsxs)(t.Fragment,{children:["active: ",(0,t.jsx)("span",{className:"tnum text-accent",children:ea})]}):et.length?"click a chip to set active":""})]})]})}),L.configured&&L.baseUrl&&(0,t.jsx)(u,{label:"Current",children:(0,t.jsx)("span",{className:"tnum text-[11.5px] text-text-subtle",children:L.baseUrl})}),(0,t.jsxs)("div",{className:"flex items-center gap-2 border-t border-border-subtle pt-3",children:[(0,t.jsxs)(o.Button,{onClick:ed,disabled:"apply"===U,children:[(0,t.jsx)(l.Icon,{name:"apply"===U?"progress_activity":"bolt",size:15}),"apply"===U?"Applying…":L.configured?"Re-apply":"Apply config"]}),L.configured&&(0,t.jsx)(o.Button,{variant:"ghost",onClick:ep,disabled:"reset"===U,children:"reset"===U?"Removing…":"Reset"}),K&&(0,t.jsx)("span",{className:"text-[12px] text-text-subtle",children:K}),L.path&&(0,t.jsx)("span",{className:"ml-auto truncate tnum text-[11px] text-text-subtle",children:L.path})]})]}):(0,t.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Not found on this machine. Install it (above) or paste the manual env below — then re-open this page."}):(0,t.jsx)("p",{className:"text-[12.5px] text-text-subtle",children:"Checking your machine…"})}),h.install&&(0,t.jsx)(i.RichCard,{header:(0,t.jsx)(i.CardTitle,{title:"Install"}),children:(0,t.jsx)(m,{text:h.install})}),(0,t.jsxs)(i.RichCard,{className:h.install?"":"lg:col-span-2",header:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.CardTitle,{title:"Environment",sub:"copy into your shell"}),b.keys.length>1&&(0,t.jsx)(o.Select,{value:String(j),onChange:e=>w(Number(e.target.value)),className:"max-w-[180px]",children:b.keys.map((e,n)=>(0,t.jsx)("option",{value:n,children:e.name||`key ${n+1}`},n))})]}),children:[(0,t.jsx)(m,{text:eg}),0===b.keys.length?(0,t.jsx)("p",{className:"mt-3 text-[12px] text-warning",children:"No gateway key set — auth is disabled. Add one under Endpoint, then it appears here."}):(0,t.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["Using key ",(0,t.jsx)("span",{className:"text-text-muted",children:b.keys[j]?.name||`#${j+1}`}),". The real value is filled in above."]})]}),eb&&(0,t.jsxs)(i.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(i.CardTitle,{title:"Manual config",sub:"merge into ~/.config/opencode/opencode.json — every model listed"}),children:[0===eh.length?(0,t.jsx)("p",{className:"text-[12.5px] text-text-muted",children:"Add models above to see them listed here."}):(0,t.jsx)(m,{text:eb}),(0,t.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps any other providers and existing models, only adding these."})]}),ev&&(0,t.jsxs)(i.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(i.CardTitle,{title:"Manual config",sub:"merge the env block into ~/.claude/settings.json"}),children:[(0,t.jsx)(m,{text:ev}),(0,t.jsx)("p",{className:"mt-3 text-[12px] text-text-subtle",children:"Apply does the same merge for you — it keeps the rest of your settings, only writing these env keys."})]}),!h.autoConfig&&(0,t.jsxs)(i.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(i.CardTitle,{title:"Models to call",sub:"name a combo exactly this — the tool will hit it"}),children:[(0,t.jsx)("div",{className:"space-y-1.5",children:h.slots.map(e=>{let n=f.includes(e.alias);return(0,t.jsxs)("div",{className:"flex items-center gap-3 rounded-brand border border-border-subtle px-3 py-2",children:[(0,t.jsx)("span",{className:"w-32 flex-none text-[12px] text-text-subtle",children:e.label}),(0,t.jsx)(l.Icon,{name:"arrow_forward",size:14,className:"flex-none text-text-subtle"}),(0,t.jsx)("span",{className:"tnum truncate text-[13px] text-text",children:e.alias}),(0,t.jsx)("span",{className:"ml-auto flex flex-none items-center gap-2",children:n?(0,t.jsx)(s.Badge,{tone:"live",children:"ready"}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.Badge,{tone:"warn",children:"missing"}),(0,t.jsxs)("button",{type:"button",onClick:()=>g.push("/combos"),className:"inline-flex items-center gap-1 text-[12px] text-accent hover:underline",children:[(0,t.jsx)(l.Icon,{name:"add",size:13})," create"]})]})})]},e.alias)})}),f.length>0&&(0,t.jsxs)("p",{className:"mt-2.5 text-[11px] text-text-subtle",children:["Your combos: ",(0,t.jsx)("span",{className:"tnum text-text-muted",children:f.join(", ")})]})]}),(0,t.jsx)(i.RichCard,{className:"lg:col-span-2",header:(0,t.jsx)(i.CardTitle,{title:"Steps"}),children:(0,t.jsx)("ol",{className:"space-y-2.5",children:h.steps.map((e,n)=>(0,t.jsxs)("li",{className:"flex gap-2.5 text-[13px] text-text-muted",children:[(0,t.jsx)("span",{className:"flex h-5 w-5 flex-none items-center justify-center rounded-full bg-surface-2 tnum text-[11px] text-text",children:n+1}),e]},n))})})]}),Q&&Z&&(0,t.jsx)(r.ModelPicker,{title:`Pick model — ${Z}`,note:"Click a model to select it for this slot.",groups:V,selected:es[Z]?[es[Z]]:[],onToggle:e=>{eo(t=>({...t,[Z]:t[Z]===e?"":e})),X(!1),ee(null)},onClose:()=>{X(!1),ee(null)}}),Q&&!Z&&(0,t.jsx)(r.ModelPicker,{title:"Add models",note:"Click a model to add it, click again to remove. Then hit Apply.",groups:V,selected:et,onToggle:function(e){et.includes(e)?(en(t=>t.filter(t=>t!==e)),ea===e&&ei("")):(en(t=>[...t,e]),ea||ei(e))},onClose:()=>X(!1)})]})}])}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,81189,t=>{"use strict";var e=t.i(43476);let r={live:"bg-success/12 text-success",down:"bg-danger/12 text-danger",warn:"bg-warning/12 text-warning",info:"bg-info/12 text-info",neutral:"bg-surface-2 text-text-muted"};function n({tone:t="neutral",children:a,className:s}){return(0,e.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${r[t]}${s?` ${s}`:""}`,children:a})}t.s(["Badge",0,n,"FormatBadge",0,function({format:t}){return(0,e.jsx)(n,{tone:"info",children:t})}])},38286,t=>{"use strict";var e=t.i(43476);t.s(["Empty",0,function({children:t}){return(0,e.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:t})},"Stat",0,function({label:t,value:r,sub:n}){return(0,e.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,e.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:t}),(0,e.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:r}),n&&(0,e.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:n})]})},"fmt",0,{int:t=>t.toLocaleString("en-US"),compact:t=>Math.abs(t)>=1e6?`${(t/1e6).toFixed(1)}M`:Math.abs(t)>=1e3?`${(t/1e3).toFixed(1)}K`:String(Math.round(t)),cost:t=>0===t?"$0":t<.01?`$${t.toFixed(4)}`:`$${t.toFixed(2)}`,time:t=>new Date(t).toLocaleString("en-US",{hour12:!1}),date(t){let e=new Date(t);return`${String(e.getDate()).padStart(2,"0")}/${String(e.getMonth()+1).padStart(2,"0")}/${e.getFullYear()}`},ago(t){let e=Math.max(0,Math.round((Date.now()-t)/1e3));return e<60?`${e}s`:e<3600?`${Math.floor(e/60)}m`:e<86400?`${Math.floor(e/3600)}h`:`${Math.floor(e/86400)}d`},duration(t){let e=Math.max(0,Math.round(t/1e3));if(e<60)return`${e}s`;if(e<3600)return`${Math.floor(e/60)}m ${e%60}s`;let r=Math.floor(e/3600),n=Math.floor(e%3600/60);if(r<24)return`${r}h ${n}m`;let a=Math.floor(r/24);return`${a}d ${r%24}h`}}])},69163,t=>{"use strict";var e=t.i(43476);t.s(["CardTitle",0,function({title:t,sub:r,icon:n}){return(0,e.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[n,(0,e.jsxs)("div",{className:"min-w-0",children:[(0,e.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:t}),r&&(0,e.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:r})]})]})},"RichCard",0,function({header:t,footer:r,children:n,className:a}){return(0,e.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${a?` ${a}`:""}`,children:[t&&(0,e.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:t}),(0,e.jsx)("div",{className:"p-4",children:n}),r&&(0,e.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:r})]})}])}]);