aigetwey 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dashboard/.next/BUILD_ID +1 -0
  3. package/dashboard/.next/app-path-routes-manifest.json +22 -0
  4. package/dashboard/.next/build/56416d4ae4ce586f.js +6 -0
  5. package/dashboard/.next/build/56416d4ae4ce586f.js.map +5 -0
  6. package/dashboard/.next/build/chunks/[root-of-the-server]__0oj80bi._.js +206 -0
  7. package/dashboard/.next/build/chunks/[root-of-the-server]__0oj80bi._.js.map +8 -0
  8. package/dashboard/.next/build/chunks/[root-of-the-server]__1f933tp._.js +500 -0
  9. package/dashboard/.next/build/chunks/[root-of-the-server]__1f933tp._.js.map +11 -0
  10. package/dashboard/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js +13 -0
  11. package/dashboard/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js.map +5 -0
  12. package/dashboard/.next/build/chunks/[turbopack]_runtime.js +890 -0
  13. package/dashboard/.next/build/chunks/[turbopack]_runtime.js.map +11 -0
  14. package/dashboard/.next/build/chunks/node_modules_20v-8wl._.js +6824 -0
  15. package/dashboard/.next/build/chunks/node_modules_20v-8wl._.js.map +47 -0
  16. package/dashboard/.next/build/package.json +1 -0
  17. package/dashboard/.next/build-manifest.json +22 -0
  18. package/dashboard/.next/cache/.previewinfo +1 -0
  19. package/dashboard/.next/cache/.rscinfo +1 -0
  20. package/dashboard/.next/diagnostics/build-diagnostics.json +6 -0
  21. package/dashboard/.next/diagnostics/framework.json +1 -0
  22. package/dashboard/.next/diagnostics/route-bundle-stats.json +208 -0
  23. package/dashboard/.next/export-marker.json +6 -0
  24. package/dashboard/.next/fallback-build-manifest.json +13 -0
  25. package/dashboard/.next/images-manifest.json +68 -0
  26. package/dashboard/.next/next-minimal-server.js.nft.json +1 -0
  27. package/dashboard/.next/next-server.js.nft.json +1 -0
  28. package/dashboard/.next/package.json +1 -0
  29. package/dashboard/.next/prerender-manifest.json +306 -0
  30. package/dashboard/.next/required-server-files.js +337 -0
  31. package/dashboard/.next/required-server-files.json +337 -0
  32. package/dashboard/.next/routes-manifest.json +174 -0
  33. package/dashboard/.next/server/app/(console)/combos/page/app-paths-manifest.json +3 -0
  34. package/dashboard/.next/server/app/(console)/combos/page/build-manifest.json +18 -0
  35. package/dashboard/.next/server/app/(console)/combos/page/next-font-manifest.json +11 -0
  36. package/dashboard/.next/server/app/(console)/combos/page/react-loadable-manifest.json +1 -0
  37. package/dashboard/.next/server/app/(console)/combos/page/server-reference-manifest.json +4 -0
  38. package/dashboard/.next/server/app/(console)/combos/page.js +15 -0
  39. package/dashboard/.next/server/app/(console)/combos/page.js.map +5 -0
  40. package/dashboard/.next/server/app/(console)/combos/page.js.nft.json +1 -0
  41. package/dashboard/.next/server/app/(console)/combos/page_client-reference-manifest.js +3 -0
  42. package/dashboard/.next/server/app/(console)/config/page/app-paths-manifest.json +3 -0
  43. package/dashboard/.next/server/app/(console)/config/page/build-manifest.json +18 -0
  44. package/dashboard/.next/server/app/(console)/config/page/next-font-manifest.json +11 -0
  45. package/dashboard/.next/server/app/(console)/config/page/react-loadable-manifest.json +1 -0
  46. package/dashboard/.next/server/app/(console)/config/page/server-reference-manifest.json +4 -0
  47. package/dashboard/.next/server/app/(console)/config/page.js +15 -0
  48. package/dashboard/.next/server/app/(console)/config/page.js.map +5 -0
  49. package/dashboard/.next/server/app/(console)/config/page.js.nft.json +1 -0
  50. package/dashboard/.next/server/app/(console)/config/page_client-reference-manifest.js +3 -0
  51. package/dashboard/.next/server/app/(console)/console/page/app-paths-manifest.json +3 -0
  52. package/dashboard/.next/server/app/(console)/console/page/build-manifest.json +18 -0
  53. package/dashboard/.next/server/app/(console)/console/page/next-font-manifest.json +11 -0
  54. package/dashboard/.next/server/app/(console)/console/page/react-loadable-manifest.json +1 -0
  55. package/dashboard/.next/server/app/(console)/console/page/server-reference-manifest.json +4 -0
  56. package/dashboard/.next/server/app/(console)/console/page.js +15 -0
  57. package/dashboard/.next/server/app/(console)/console/page.js.map +5 -0
  58. package/dashboard/.next/server/app/(console)/console/page.js.nft.json +1 -0
  59. package/dashboard/.next/server/app/(console)/console/page_client-reference-manifest.js +3 -0
  60. package/dashboard/.next/server/app/(console)/endpoint/page/app-paths-manifest.json +3 -0
  61. package/dashboard/.next/server/app/(console)/endpoint/page/build-manifest.json +18 -0
  62. package/dashboard/.next/server/app/(console)/endpoint/page/next-font-manifest.json +11 -0
  63. package/dashboard/.next/server/app/(console)/endpoint/page/react-loadable-manifest.json +1 -0
  64. package/dashboard/.next/server/app/(console)/endpoint/page/server-reference-manifest.json +4 -0
  65. package/dashboard/.next/server/app/(console)/endpoint/page.js +15 -0
  66. package/dashboard/.next/server/app/(console)/endpoint/page.js.map +5 -0
  67. package/dashboard/.next/server/app/(console)/endpoint/page.js.nft.json +1 -0
  68. package/dashboard/.next/server/app/(console)/endpoint/page_client-reference-manifest.js +3 -0
  69. package/dashboard/.next/server/app/(console)/page/app-paths-manifest.json +3 -0
  70. package/dashboard/.next/server/app/(console)/page/build-manifest.json +18 -0
  71. package/dashboard/.next/server/app/(console)/page/next-font-manifest.json +11 -0
  72. package/dashboard/.next/server/app/(console)/page/react-loadable-manifest.json +1 -0
  73. package/dashboard/.next/server/app/(console)/page/server-reference-manifest.json +4 -0
  74. package/dashboard/.next/server/app/(console)/page.js +15 -0
  75. package/dashboard/.next/server/app/(console)/page.js.map +5 -0
  76. package/dashboard/.next/server/app/(console)/page.js.nft.json +1 -0
  77. package/dashboard/.next/server/app/(console)/page_client-reference-manifest.js +3 -0
  78. package/dashboard/.next/server/app/(console)/providers/[id]/page/app-paths-manifest.json +3 -0
  79. package/dashboard/.next/server/app/(console)/providers/[id]/page/build-manifest.json +18 -0
  80. package/dashboard/.next/server/app/(console)/providers/[id]/page/next-font-manifest.json +11 -0
  81. package/dashboard/.next/server/app/(console)/providers/[id]/page/react-loadable-manifest.json +1 -0
  82. package/dashboard/.next/server/app/(console)/providers/[id]/page/server-reference-manifest.json +4 -0
  83. package/dashboard/.next/server/app/(console)/providers/[id]/page.js +15 -0
  84. package/dashboard/.next/server/app/(console)/providers/[id]/page.js.map +5 -0
  85. package/dashboard/.next/server/app/(console)/providers/[id]/page.js.nft.json +1 -0
  86. package/dashboard/.next/server/app/(console)/providers/[id]/page_client-reference-manifest.js +3 -0
  87. package/dashboard/.next/server/app/(console)/providers/page/app-paths-manifest.json +3 -0
  88. package/dashboard/.next/server/app/(console)/providers/page/build-manifest.json +18 -0
  89. package/dashboard/.next/server/app/(console)/providers/page/next-font-manifest.json +11 -0
  90. package/dashboard/.next/server/app/(console)/providers/page/react-loadable-manifest.json +1 -0
  91. package/dashboard/.next/server/app/(console)/providers/page/server-reference-manifest.json +4 -0
  92. package/dashboard/.next/server/app/(console)/providers/page.js +15 -0
  93. package/dashboard/.next/server/app/(console)/providers/page.js.map +5 -0
  94. package/dashboard/.next/server/app/(console)/providers/page.js.nft.json +1 -0
  95. package/dashboard/.next/server/app/(console)/providers/page_client-reference-manifest.js +3 -0
  96. package/dashboard/.next/server/app/(console)/quota/page/app-paths-manifest.json +3 -0
  97. package/dashboard/.next/server/app/(console)/quota/page/build-manifest.json +18 -0
  98. package/dashboard/.next/server/app/(console)/quota/page/next-font-manifest.json +11 -0
  99. package/dashboard/.next/server/app/(console)/quota/page/react-loadable-manifest.json +1 -0
  100. package/dashboard/.next/server/app/(console)/quota/page/server-reference-manifest.json +4 -0
  101. package/dashboard/.next/server/app/(console)/quota/page.js +15 -0
  102. package/dashboard/.next/server/app/(console)/quota/page.js.map +5 -0
  103. package/dashboard/.next/server/app/(console)/quota/page.js.nft.json +1 -0
  104. package/dashboard/.next/server/app/(console)/quota/page_client-reference-manifest.js +3 -0
  105. package/dashboard/.next/server/app/(console)/tools/[id]/page/app-paths-manifest.json +3 -0
  106. package/dashboard/.next/server/app/(console)/tools/[id]/page/build-manifest.json +18 -0
  107. package/dashboard/.next/server/app/(console)/tools/[id]/page/next-font-manifest.json +11 -0
  108. package/dashboard/.next/server/app/(console)/tools/[id]/page/react-loadable-manifest.json +1 -0
  109. package/dashboard/.next/server/app/(console)/tools/[id]/page/server-reference-manifest.json +4 -0
  110. package/dashboard/.next/server/app/(console)/tools/[id]/page.js +15 -0
  111. package/dashboard/.next/server/app/(console)/tools/[id]/page.js.map +5 -0
  112. package/dashboard/.next/server/app/(console)/tools/[id]/page.js.nft.json +1 -0
  113. package/dashboard/.next/server/app/(console)/tools/[id]/page_client-reference-manifest.js +3 -0
  114. package/dashboard/.next/server/app/(console)/tools/page/app-paths-manifest.json +3 -0
  115. package/dashboard/.next/server/app/(console)/tools/page/build-manifest.json +18 -0
  116. package/dashboard/.next/server/app/(console)/tools/page/next-font-manifest.json +11 -0
  117. package/dashboard/.next/server/app/(console)/tools/page/react-loadable-manifest.json +1 -0
  118. package/dashboard/.next/server/app/(console)/tools/page/server-reference-manifest.json +4 -0
  119. package/dashboard/.next/server/app/(console)/tools/page.js +15 -0
  120. package/dashboard/.next/server/app/(console)/tools/page.js.map +5 -0
  121. package/dashboard/.next/server/app/(console)/tools/page.js.nft.json +1 -0
  122. package/dashboard/.next/server/app/(console)/tools/page_client-reference-manifest.js +3 -0
  123. package/dashboard/.next/server/app/(console)/usage/page/app-paths-manifest.json +3 -0
  124. package/dashboard/.next/server/app/(console)/usage/page/build-manifest.json +18 -0
  125. package/dashboard/.next/server/app/(console)/usage/page/next-font-manifest.json +11 -0
  126. package/dashboard/.next/server/app/(console)/usage/page/react-loadable-manifest.json +1 -0
  127. package/dashboard/.next/server/app/(console)/usage/page/server-reference-manifest.json +4 -0
  128. package/dashboard/.next/server/app/(console)/usage/page.js +16 -0
  129. package/dashboard/.next/server/app/(console)/usage/page.js.map +5 -0
  130. package/dashboard/.next/server/app/(console)/usage/page.js.nft.json +1 -0
  131. package/dashboard/.next/server/app/(console)/usage/page_client-reference-manifest.js +3 -0
  132. package/dashboard/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
  133. package/dashboard/.next/server/app/_global-error/page/build-manifest.json +18 -0
  134. package/dashboard/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
  135. package/dashboard/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
  136. package/dashboard/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
  137. package/dashboard/.next/server/app/_global-error/page.js +9 -0
  138. package/dashboard/.next/server/app/_global-error/page.js.map +5 -0
  139. package/dashboard/.next/server/app/_global-error/page.js.nft.json +1 -0
  140. package/dashboard/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
  141. package/dashboard/.next/server/app/_global-error.html +1 -0
  142. package/dashboard/.next/server/app/_global-error.meta +15 -0
  143. package/dashboard/.next/server/app/_global-error.rsc +14 -0
  144. package/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
  145. package/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
  146. package/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  147. package/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
  148. package/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  149. package/dashboard/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
  150. package/dashboard/.next/server/app/_not-found/page/build-manifest.json +18 -0
  151. package/dashboard/.next/server/app/_not-found/page/next-font-manifest.json +11 -0
  152. package/dashboard/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
  153. package/dashboard/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
  154. package/dashboard/.next/server/app/_not-found/page.js +13 -0
  155. package/dashboard/.next/server/app/_not-found/page.js.map +5 -0
  156. package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -0
  157. package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
  158. package/dashboard/.next/server/app/_not-found.html +1 -0
  159. package/dashboard/.next/server/app/_not-found.meta +16 -0
  160. package/dashboard/.next/server/app/_not-found.rsc +20 -0
  161. package/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +20 -0
  162. package/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
  163. package/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +9 -0
  164. package/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
  165. package/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
  166. package/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -0
  167. package/dashboard/.next/server/app/api/cli-detect/[tool]/route/app-paths-manifest.json +3 -0
  168. package/dashboard/.next/server/app/api/cli-detect/[tool]/route/build-manifest.json +9 -0
  169. package/dashboard/.next/server/app/api/cli-detect/[tool]/route/server-reference-manifest.json +4 -0
  170. package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js +7 -0
  171. package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js.map +5 -0
  172. package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js.nft.json +1 -0
  173. package/dashboard/.next/server/app/api/cli-detect/[tool]/route_client-reference-manifest.js +3 -0
  174. package/dashboard/.next/server/app/api/gw/[...path]/route/app-paths-manifest.json +3 -0
  175. package/dashboard/.next/server/app/api/gw/[...path]/route/build-manifest.json +9 -0
  176. package/dashboard/.next/server/app/api/gw/[...path]/route/server-reference-manifest.json +4 -0
  177. package/dashboard/.next/server/app/api/gw/[...path]/route.js +7 -0
  178. package/dashboard/.next/server/app/api/gw/[...path]/route.js.map +5 -0
  179. package/dashboard/.next/server/app/api/gw/[...path]/route.js.nft.json +1 -0
  180. package/dashboard/.next/server/app/api/gw/[...path]/route_client-reference-manifest.js +3 -0
  181. package/dashboard/.next/server/app/api/login/route/app-paths-manifest.json +3 -0
  182. package/dashboard/.next/server/app/api/login/route/build-manifest.json +9 -0
  183. package/dashboard/.next/server/app/api/login/route/server-reference-manifest.json +4 -0
  184. package/dashboard/.next/server/app/api/login/route.js +7 -0
  185. package/dashboard/.next/server/app/api/login/route.js.map +5 -0
  186. package/dashboard/.next/server/app/api/login/route.js.nft.json +1 -0
  187. package/dashboard/.next/server/app/api/login/route_client-reference-manifest.js +3 -0
  188. package/dashboard/.next/server/app/api/logout/route/app-paths-manifest.json +3 -0
  189. package/dashboard/.next/server/app/api/logout/route/build-manifest.json +9 -0
  190. package/dashboard/.next/server/app/api/logout/route/server-reference-manifest.json +4 -0
  191. package/dashboard/.next/server/app/api/logout/route.js +7 -0
  192. package/dashboard/.next/server/app/api/logout/route.js.map +5 -0
  193. package/dashboard/.next/server/app/api/logout/route.js.nft.json +1 -0
  194. package/dashboard/.next/server/app/api/logout/route_client-reference-manifest.js +3 -0
  195. package/dashboard/.next/server/app/api/password/route/app-paths-manifest.json +3 -0
  196. package/dashboard/.next/server/app/api/password/route/build-manifest.json +9 -0
  197. package/dashboard/.next/server/app/api/password/route/server-reference-manifest.json +4 -0
  198. package/dashboard/.next/server/app/api/password/route.js +7 -0
  199. package/dashboard/.next/server/app/api/password/route.js.map +5 -0
  200. package/dashboard/.next/server/app/api/password/route.js.nft.json +1 -0
  201. package/dashboard/.next/server/app/api/password/route_client-reference-manifest.js +3 -0
  202. package/dashboard/.next/server/app/combos.html +1 -0
  203. package/dashboard/.next/server/app/combos.meta +16 -0
  204. package/dashboard/.next/server/app/combos.rsc +25 -0
  205. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos/__PAGE__.segment.rsc +6 -0
  206. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos.segment.rsc +5 -0
  207. package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  208. package/dashboard/.next/server/app/combos.segments/_full.segment.rsc +25 -0
  209. package/dashboard/.next/server/app/combos.segments/_head.segment.rsc +6 -0
  210. package/dashboard/.next/server/app/combos.segments/_index.segment.rsc +9 -0
  211. package/dashboard/.next/server/app/combos.segments/_tree.segment.rsc +5 -0
  212. package/dashboard/.next/server/app/config.html +1 -0
  213. package/dashboard/.next/server/app/config.meta +16 -0
  214. package/dashboard/.next/server/app/config.rsc +25 -0
  215. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config/__PAGE__.segment.rsc +6 -0
  216. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config.segment.rsc +5 -0
  217. package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  218. package/dashboard/.next/server/app/config.segments/_full.segment.rsc +25 -0
  219. package/dashboard/.next/server/app/config.segments/_head.segment.rsc +6 -0
  220. package/dashboard/.next/server/app/config.segments/_index.segment.rsc +9 -0
  221. package/dashboard/.next/server/app/config.segments/_tree.segment.rsc +5 -0
  222. package/dashboard/.next/server/app/console.html +1 -0
  223. package/dashboard/.next/server/app/console.meta +16 -0
  224. package/dashboard/.next/server/app/console.rsc +28 -0
  225. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console/__PAGE__.segment.rsc +9 -0
  226. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console.segment.rsc +5 -0
  227. package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  228. package/dashboard/.next/server/app/console.segments/_full.segment.rsc +28 -0
  229. package/dashboard/.next/server/app/console.segments/_head.segment.rsc +6 -0
  230. package/dashboard/.next/server/app/console.segments/_index.segment.rsc +9 -0
  231. package/dashboard/.next/server/app/console.segments/_tree.segment.rsc +5 -0
  232. package/dashboard/.next/server/app/endpoint.html +1 -0
  233. package/dashboard/.next/server/app/endpoint.meta +16 -0
  234. package/dashboard/.next/server/app/endpoint.rsc +25 -0
  235. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint/__PAGE__.segment.rsc +6 -0
  236. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint.segment.rsc +5 -0
  237. package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  238. package/dashboard/.next/server/app/endpoint.segments/_full.segment.rsc +25 -0
  239. package/dashboard/.next/server/app/endpoint.segments/_head.segment.rsc +6 -0
  240. package/dashboard/.next/server/app/endpoint.segments/_index.segment.rsc +9 -0
  241. package/dashboard/.next/server/app/endpoint.segments/_tree.segment.rsc +5 -0
  242. package/dashboard/.next/server/app/icon.svg/route/app-paths-manifest.json +3 -0
  243. package/dashboard/.next/server/app/icon.svg/route/build-manifest.json +9 -0
  244. package/dashboard/.next/server/app/icon.svg/route.js +6 -0
  245. package/dashboard/.next/server/app/icon.svg/route.js.map +5 -0
  246. package/dashboard/.next/server/app/icon.svg/route.js.nft.json +1 -0
  247. package/dashboard/.next/server/app/icon.svg.body +8 -0
  248. package/dashboard/.next/server/app/icon.svg.meta +1 -0
  249. package/dashboard/.next/server/app/index.html +1 -0
  250. package/dashboard/.next/server/app/index.meta +15 -0
  251. package/dashboard/.next/server/app/index.rsc +23 -0
  252. package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp/__PAGE__.segment.rsc +6 -0
  253. package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  254. package/dashboard/.next/server/app/index.segments/_full.segment.rsc +23 -0
  255. package/dashboard/.next/server/app/index.segments/_head.segment.rsc +6 -0
  256. package/dashboard/.next/server/app/index.segments/_index.segment.rsc +9 -0
  257. package/dashboard/.next/server/app/index.segments/_tree.segment.rsc +5 -0
  258. package/dashboard/.next/server/app/login/page/app-paths-manifest.json +3 -0
  259. package/dashboard/.next/server/app/login/page/build-manifest.json +18 -0
  260. package/dashboard/.next/server/app/login/page/next-font-manifest.json +11 -0
  261. package/dashboard/.next/server/app/login/page/react-loadable-manifest.json +1 -0
  262. package/dashboard/.next/server/app/login/page/server-reference-manifest.json +4 -0
  263. package/dashboard/.next/server/app/login/page.js +14 -0
  264. package/dashboard/.next/server/app/login/page.js.map +5 -0
  265. package/dashboard/.next/server/app/login/page.js.nft.json +1 -0
  266. package/dashboard/.next/server/app/login/page_client-reference-manifest.js +3 -0
  267. package/dashboard/.next/server/app/login.html +1 -0
  268. package/dashboard/.next/server/app/login.meta +15 -0
  269. package/dashboard/.next/server/app/login.rsc +26 -0
  270. package/dashboard/.next/server/app/login.segments/_full.segment.rsc +26 -0
  271. package/dashboard/.next/server/app/login.segments/_head.segment.rsc +6 -0
  272. package/dashboard/.next/server/app/login.segments/_index.segment.rsc +9 -0
  273. package/dashboard/.next/server/app/login.segments/_tree.segment.rsc +5 -0
  274. package/dashboard/.next/server/app/login.segments/login/__PAGE__.segment.rsc +9 -0
  275. package/dashboard/.next/server/app/login.segments/login.segment.rsc +5 -0
  276. package/dashboard/.next/server/app/providers.html +1 -0
  277. package/dashboard/.next/server/app/providers.meta +16 -0
  278. package/dashboard/.next/server/app/providers.rsc +25 -0
  279. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers/__PAGE__.segment.rsc +6 -0
  280. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers.segment.rsc +5 -0
  281. package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  282. package/dashboard/.next/server/app/providers.segments/_full.segment.rsc +25 -0
  283. package/dashboard/.next/server/app/providers.segments/_head.segment.rsc +6 -0
  284. package/dashboard/.next/server/app/providers.segments/_index.segment.rsc +9 -0
  285. package/dashboard/.next/server/app/providers.segments/_tree.segment.rsc +5 -0
  286. package/dashboard/.next/server/app/quota.html +1 -0
  287. package/dashboard/.next/server/app/quota.meta +16 -0
  288. package/dashboard/.next/server/app/quota.rsc +25 -0
  289. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota/__PAGE__.segment.rsc +6 -0
  290. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota.segment.rsc +5 -0
  291. package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  292. package/dashboard/.next/server/app/quota.segments/_full.segment.rsc +25 -0
  293. package/dashboard/.next/server/app/quota.segments/_head.segment.rsc +6 -0
  294. package/dashboard/.next/server/app/quota.segments/_index.segment.rsc +9 -0
  295. package/dashboard/.next/server/app/quota.segments/_tree.segment.rsc +5 -0
  296. package/dashboard/.next/server/app/tools.html +1 -0
  297. package/dashboard/.next/server/app/tools.meta +16 -0
  298. package/dashboard/.next/server/app/tools.rsc +25 -0
  299. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools/__PAGE__.segment.rsc +6 -0
  300. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools.segment.rsc +5 -0
  301. package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
  302. package/dashboard/.next/server/app/tools.segments/_full.segment.rsc +25 -0
  303. package/dashboard/.next/server/app/tools.segments/_head.segment.rsc +6 -0
  304. package/dashboard/.next/server/app/tools.segments/_index.segment.rsc +9 -0
  305. package/dashboard/.next/server/app/tools.segments/_tree.segment.rsc +5 -0
  306. package/dashboard/.next/server/app-paths-manifest.json +22 -0
  307. package/dashboard/.next/server/chunks/[externals]__1j91pjf._.js +3 -0
  308. package/dashboard/.next/server/chunks/[externals]__1j91pjf._.js.map +1 -0
  309. package/dashboard/.next/server/chunks/[externals]__1v5t_x8._.js +3 -0
  310. package/dashboard/.next/server/chunks/[externals]__1v5t_x8._.js.map +1 -0
  311. package/dashboard/.next/server/chunks/[root-of-the-server]__0-6ukjk._.js +3 -0
  312. package/dashboard/.next/server/chunks/[root-of-the-server]__0-6ukjk._.js.map +1 -0
  313. package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js +20 -0
  314. package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js.map +1 -0
  315. package/dashboard/.next/server/chunks/[root-of-the-server]__07euc03._.js +3 -0
  316. package/dashboard/.next/server/chunks/[root-of-the-server]__07euc03._.js.map +1 -0
  317. package/dashboard/.next/server/chunks/[root-of-the-server]__082azhr._.js +3 -0
  318. package/dashboard/.next/server/chunks/[root-of-the-server]__082azhr._.js.map +1 -0
  319. package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js +3 -0
  320. package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js.map +1 -0
  321. package/dashboard/.next/server/chunks/[root-of-the-server]__0pp7rn-._.js +3 -0
  322. package/dashboard/.next/server/chunks/[root-of-the-server]__0pp7rn-._.js.map +1 -0
  323. package/dashboard/.next/server/chunks/[root-of-the-server]__0uqpr_c._.js +3 -0
  324. package/dashboard/.next/server/chunks/[root-of-the-server]__0uqpr_c._.js.map +1 -0
  325. package/dashboard/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +13 -0
  326. package/dashboard/.next/server/chunks/[root-of-the-server]__0xuaoik._.js.map +1 -0
  327. package/dashboard/.next/server/chunks/[turbopack]_runtime.js +903 -0
  328. package/dashboard/.next/server/chunks/[turbopack]_runtime.js.map +11 -0
  329. package/dashboard/.next/server/chunks/_0digmky._.js +3 -0
  330. package/dashboard/.next/server/chunks/_0digmky._.js.map +1 -0
  331. package/dashboard/.next/server/chunks/_next-internal_server_app_api_cli-detect_[tool]_route_actions_0ffw-gg.js +3 -0
  332. package/dashboard/.next/server/chunks/_next-internal_server_app_api_cli-detect_[tool]_route_actions_0ffw-gg.js.map +1 -0
  333. package/dashboard/.next/server/chunks/_next-internal_server_app_api_gw_[___path]_route_actions_0ytl4km.js +3 -0
  334. package/dashboard/.next/server/chunks/_next-internal_server_app_api_gw_[___path]_route_actions_0ytl4km.js.map +1 -0
  335. package/dashboard/.next/server/chunks/_next-internal_server_app_api_login_route_actions_1apjjct.js +3 -0
  336. package/dashboard/.next/server/chunks/_next-internal_server_app_api_login_route_actions_1apjjct.js.map +1 -0
  337. package/dashboard/.next/server/chunks/_next-internal_server_app_api_logout_route_actions_0gzx3on.js +3 -0
  338. package/dashboard/.next/server/chunks/_next-internal_server_app_api_logout_route_actions_0gzx3on.js.map +1 -0
  339. package/dashboard/.next/server/chunks/_next-internal_server_app_api_password_route_actions_0xecc0j.js +3 -0
  340. package/dashboard/.next/server/chunks/_next-internal_server_app_api_password_route_actions_0xecc0j.js.map +1 -0
  341. package/dashboard/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js +3 -0
  342. package/dashboard/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js.map +1 -0
  343. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0559wxx._.js +3 -0
  344. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0559wxx._.js.map +1 -0
  345. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09pxn-h._.js +33 -0
  346. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09pxn-h._.js.map +1 -0
  347. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0_fihdn._.js +3 -0
  348. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0_fihdn._.js.map +1 -0
  349. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0cx5pj3._.js +3 -0
  350. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0cx5pj3._.js.map +1 -0
  351. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0d-itp1._.js +3 -0
  352. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0d-itp1._.js.map +1 -0
  353. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0dk7lif._.js +3 -0
  354. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0dk7lif._.js.map +1 -0
  355. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0qvkt1y._.js +3 -0
  356. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0qvkt1y._.js.map +1 -0
  357. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0unr06k._.js +3 -0
  358. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0unr06k._.js.map +1 -0
  359. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0x-617o._.js +3 -0
  360. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0x-617o._.js.map +1 -0
  361. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js +27 -0
  362. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js.map +1 -0
  363. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__11t16qi._.js +3 -0
  364. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__11t16qi._.js.map +1 -0
  365. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__12q01a8._.js +3 -0
  366. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__12q01a8._.js.map +1 -0
  367. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__179ut8i._.js +3 -0
  368. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__179ut8i._.js.map +1 -0
  369. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js +33 -0
  370. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js.map +1 -0
  371. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1inj1w-._.js +3 -0
  372. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1inj1w-._.js.map +1 -0
  373. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1jidl81._.js +3 -0
  374. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1jidl81._.js.map +1 -0
  375. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1mg2t8f._.js +3 -0
  376. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1mg2t8f._.js.map +1 -0
  377. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w2pq2s._.js +3 -0
  378. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w2pq2s._.js.map +1 -0
  379. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w31jjb._.js +3 -0
  380. package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w31jjb._.js.map +1 -0
  381. package/dashboard/.next/server/chunks/ssr/[turbopack]_runtime.js +903 -0
  382. package/dashboard/.next/server/chunks/ssr/[turbopack]_runtime.js.map +11 -0
  383. package/dashboard/.next/server/chunks/ssr/_0g1n0z2._.js +3 -0
  384. package/dashboard/.next/server/chunks/ssr/_0g1n0z2._.js.map +1 -0
  385. package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js +3 -0
  386. package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js.map +1 -0
  387. package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js +6 -0
  388. package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js.map +1 -0
  389. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_combos_page_actions_07o3lus.js +3 -0
  390. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_combos_page_actions_07o3lus.js.map +1 -0
  391. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_config_page_actions_1d2383s.js +3 -0
  392. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_config_page_actions_1d2383s.js.map +1 -0
  393. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_console_page_actions_0w-3r_g.js +3 -0
  394. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_console_page_actions_0w-3r_g.js.map +1 -0
  395. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_endpoint_page_actions_00tzpzh.js +3 -0
  396. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_endpoint_page_actions_00tzpzh.js.map +1 -0
  397. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_page_actions_0u8zxvt.js +3 -0
  398. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_page_actions_0u8zxvt.js.map +1 -0
  399. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_[id]_page_actions_20yozi-.js +3 -0
  400. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_[id]_page_actions_20yozi-.js.map +1 -0
  401. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_page_actions_1bdc8gv.js +3 -0
  402. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_page_actions_1bdc8gv.js.map +1 -0
  403. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_quota_page_actions_02l-zu_.js +3 -0
  404. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_quota_page_actions_02l-zu_.js.map +1 -0
  405. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_[id]_page_actions_01qi9of.js +3 -0
  406. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_[id]_page_actions_01qi9of.js.map +1 -0
  407. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_page_actions_18gis7c.js +3 -0
  408. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_page_actions_18gis7c.js.map +1 -0
  409. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_usage_page_actions_1twl-ym.js +3 -0
  410. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_usage_page_actions_1twl-ym.js.map +1 -0
  411. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js +3 -0
  412. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js.map +1 -0
  413. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js +3 -0
  414. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js.map +1 -0
  415. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_login_page_actions_04fnjo0.js +3 -0
  416. package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_login_page_actions_04fnjo0.js.map +1 -0
  417. package/dashboard/.next/server/chunks/ssr/node_modules_1ivn_d-._.js +3 -0
  418. package/dashboard/.next/server/chunks/ssr/node_modules_1ivn_d-._.js.map +1 -0
  419. package/dashboard/.next/server/chunks/ssr/node_modules_next_1iemwhs._.js +6 -0
  420. package/dashboard/.next/server/chunks/ssr/node_modules_next_1iemwhs._.js.map +1 -0
  421. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js +6 -0
  422. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js.map +1 -0
  423. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1enzot_._.js +3 -0
  424. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1enzot_._.js.map +1 -0
  425. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1map00z._.js +19 -0
  426. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1map00z._.js.map +1 -0
  427. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0bew68i._.js +33 -0
  428. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0bew68i._.js.map +1 -0
  429. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js +3 -0
  430. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js.map +1 -0
  431. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js +3 -0
  432. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js.map +1 -0
  433. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js +3 -0
  434. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js.map +1 -0
  435. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js +3 -0
  436. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js.map +1 -0
  437. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_00x0c-2.js +4 -0
  438. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_00x0c-2.js.map +1 -0
  439. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_01n345n.js +4 -0
  440. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_01n345n.js.map +1 -0
  441. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02jwx28.js +4 -0
  442. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02jwx28.js.map +1 -0
  443. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_08g_4le.js +4 -0
  444. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_08g_4le.js.map +1 -0
  445. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js +4 -0
  446. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js.map +1 -0
  447. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0tx5zxe.js +4 -0
  448. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0tx5zxe.js.map +1 -0
  449. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_15dprgl.js +4 -0
  450. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_15dprgl.js.map +1 -0
  451. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18twt8j.js +4 -0
  452. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18twt8j.js.map +1 -0
  453. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js +4 -0
  454. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js.map +1 -0
  455. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1bycsv3.js +4 -0
  456. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1bycsv3.js.map +1 -0
  457. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1i1atml.js +4 -0
  458. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1i1atml.js.map +1 -0
  459. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1n7v8np.js +4 -0
  460. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1n7v8np.js.map +1 -0
  461. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1q72yyr.js +4 -0
  462. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1q72yyr.js.map +1 -0
  463. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_20gk3id.js +4 -0
  464. package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_20gk3id.js.map +1 -0
  465. package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js +3 -0
  466. package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js.map +1 -0
  467. package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js +3 -0
  468. package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js.map +1 -0
  469. package/dashboard/.next/server/chunks/ssr/src_0wrskl4._.js +3 -0
  470. package/dashboard/.next/server/chunks/ssr/src_0wrskl4._.js.map +1 -0
  471. package/dashboard/.next/server/chunks/ssr/src_app_(console)_console_page_tsx_1g8gnmy._.js +3 -0
  472. package/dashboard/.next/server/chunks/ssr/src_app_(console)_console_page_tsx_1g8gnmy._.js.map +1 -0
  473. package/dashboard/.next/server/chunks/ssr/src_components_0kr-r_t._.js +3 -0
  474. package/dashboard/.next/server/chunks/ssr/src_components_0kr-r_t._.js.map +1 -0
  475. package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js +3 -0
  476. package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js.map +1 -0
  477. package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js +3 -0
  478. package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js.map +1 -0
  479. package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js +3 -0
  480. package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js.map +1 -0
  481. package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js +3 -0
  482. package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js.map +1 -0
  483. package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js +3 -0
  484. package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js.map +1 -0
  485. package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js +3 -0
  486. package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js.map +1 -0
  487. package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js +3 -0
  488. package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js.map +1 -0
  489. package/dashboard/.next/server/chunks/ssr/src_components_BudgetTracker_tsx_1-xevea._.js +3 -0
  490. package/dashboard/.next/server/chunks/ssr/src_components_BudgetTracker_tsx_1-xevea._.js.map +1 -0
  491. package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js +3 -0
  492. package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js.map +1 -0
  493. package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js +3 -0
  494. package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js.map +1 -0
  495. package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js +3 -0
  496. package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js.map +1 -0
  497. package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js +3 -0
  498. package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js.map +1 -0
  499. package/dashboard/.next/server/functions-config-manifest.json +14 -0
  500. package/dashboard/.next/server/interception-route-rewrite-manifest.js +1 -0
  501. package/dashboard/.next/server/middleware/middleware-manifest.json +6 -0
  502. package/dashboard/.next/server/middleware-build-manifest.js +22 -0
  503. package/dashboard/.next/server/middleware-manifest.json +6 -0
  504. package/dashboard/.next/server/middleware.js +5 -0
  505. package/dashboard/.next/server/middleware.js.map +5 -0
  506. package/dashboard/.next/server/middleware.js.nft.json +1 -0
  507. package/dashboard/.next/server/next-font-manifest.js +1 -0
  508. package/dashboard/.next/server/next-font-manifest.json +59 -0
  509. package/dashboard/.next/server/pages/404.html +1 -0
  510. package/dashboard/.next/server/pages/500.html +1 -0
  511. package/dashboard/.next/server/pages-manifest.json +4 -0
  512. package/dashboard/.next/server/prefetch-hints.json +1 -0
  513. package/dashboard/.next/server/server-reference-manifest.js +1 -0
  514. package/dashboard/.next/server/server-reference-manifest.json +5 -0
  515. package/dashboard/.next/static/chunks/00415cmd3ji2s.js +1 -0
  516. package/dashboard/.next/static/chunks/05-c3ty_6dwfk.js +1 -0
  517. package/dashboard/.next/static/chunks/05i93ivai9obr.js +1 -0
  518. package/dashboard/.next/static/chunks/0_fo_1xhw25rd.js +1 -0
  519. package/dashboard/.next/static/chunks/0cz1d0mv5g_q7.js +1 -0
  520. package/dashboard/.next/static/chunks/0mk1g55o6kl1e.js +2 -0
  521. package/dashboard/.next/static/chunks/0mr7sg_sr6f99.js +1 -0
  522. package/dashboard/.next/static/chunks/1-r9spn081_wo.js +1 -0
  523. package/dashboard/.next/static/chunks/13ge_ybuj8rl3.js +1 -0
  524. package/dashboard/.next/static/chunks/14mrh2-p_w84d.js +1 -0
  525. package/dashboard/.next/static/chunks/17nxt0zmkvdgv.js +1 -0
  526. package/dashboard/.next/static/chunks/2284qz1hy9776.css +3 -0
  527. package/dashboard/.next/static/chunks/22r7w355mazs8.js +1 -0
  528. package/dashboard/.next/static/chunks/27jktro2p5rq9.js +4 -0
  529. package/dashboard/.next/static/chunks/2t3rqr0rkspb7.js +1 -0
  530. package/dashboard/.next/static/chunks/2zho1fpijk0fu.js +1 -0
  531. package/dashboard/.next/static/chunks/30uw-uiehs39o.js +1 -0
  532. package/dashboard/.next/static/chunks/36ssnkm0cjgq6.js +31 -0
  533. package/dashboard/.next/static/chunks/3i6nr2y3h_7s2.js +1 -0
  534. package/dashboard/.next/static/chunks/3j9pm5otqxm82.js +1 -0
  535. package/dashboard/.next/static/chunks/3jat3x6f_2a6o.js +1 -0
  536. package/dashboard/.next/static/chunks/3nrz6v06gppob.js +1 -0
  537. package/dashboard/.next/static/chunks/40pm83c1_d0jz.js +25 -0
  538. package/dashboard/.next/static/chunks/turbopack-28-wpvvyttgwq.js +1 -0
  539. package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_buildManifest.js +11 -0
  540. package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_clientMiddlewareManifest.js +6 -0
  541. package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_ssgManifest.js +1 -0
  542. package/dashboard/.next/static/media/13bf9871fe164e7f-s.2f7nqdagzwx2-.woff2 +0 -0
  543. package/dashboard/.next/static/media/1bffadaabf893a1e-s.3-6t-g6q0vh0a.woff2 +0 -0
  544. package/dashboard/.next/static/media/2bbe8d2671613f1f-s.0k62hbripvv8p.woff2 +0 -0
  545. package/dashboard/.next/static/media/2c55a0e60120577a-s.0-dom-5bn10r2.woff2 +0 -0
  546. package/dashboard/.next/static/media/3fe682a82f50d426-s.0vfdmo25voy_0.woff2 +0 -0
  547. package/dashboard/.next/static/media/5476f68d60460930-s.2uwcyprjm3xu3.woff2 +0 -0
  548. package/dashboard/.next/static/media/70bc3e132a0a741e-s.p.3t6q91iet4nsy.woff2 +0 -0
  549. package/dashboard/.next/static/media/71b036adf157cdcf-s.0bp8oijd_gu96.woff2 +0 -0
  550. package/dashboard/.next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2 +0 -0
  551. package/dashboard/.next/static/media/89b21bb081cb7469-s.1fby2rem9ngyr.woff2 +0 -0
  552. package/dashboard/.next/static/media/9c72aa0f40e4eef8-s.1y4-pdgsjb-pw.woff2 +0 -0
  553. package/dashboard/.next/static/media/ad66f9afd8947f86-s.3lvt2whj97whp.woff2 +0 -0
  554. package/dashboard/.next/static/media/cc545e633e20c56d-s.176arc174-8zp.woff2 +0 -0
  555. package/dashboard/.next/static/media/icon.43yv9zw_mes0x.svg +8 -0
  556. package/dashboard/.next/trace +1 -0
  557. package/dashboard/.next/trace-build +1 -0
  558. package/dashboard/.next/turbopack +0 -0
  559. package/dashboard/.next/types/cache-life.d.ts +145 -0
  560. package/dashboard/.next/types/routes.d.ts +88 -0
  561. package/dashboard/.next/types/validator.ts +223 -0
  562. package/dist/cli.js +16 -5
  563. package/dist/cli.js.map +1 -1
  564. package/package.json +3 -1
  565. package/scripts/postinstall.cjs +66 -0
  566. package/src/cli.ts +16 -5
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Badge.tsx","../../../../src/components/ui.tsx","../../../../src/components/Lamp.tsx","../../../../src/components/CooldownTimer.tsx","../../../../src/components/ProviderManager.tsx"],"sourcesContent":["type Tone = \"live\" | \"down\" | \"warn\" | \"info\" | \"neutral\";\n\nconst TONES: Record<Tone, string> = {\n live: \"bg-success/12 text-success\",\n down: \"bg-danger/12 text-danger\",\n warn: \"bg-warning/12 text-warning\",\n info: \"bg-info/12 text-info\",\n neutral: \"bg-surface-2 text-text-muted\",\n};\n\nexport function Badge({\n tone = \"neutral\",\n children,\n className,\n}: {\n tone?: Tone;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${TONES[tone]}${className ? ` ${className}` : \"\"}`}\n >\n {children}\n </span>\n );\n}\n\n/** Format badge for a provider's wire format. */\nexport function FormatBadge({ format }: { format: \"openai\" | \"anthropic\" | \"gemini\" }) {\n return <Badge tone=\"info\">{format}</Badge>;\n}\n","/** Small formatting helpers shared across the console. */\nexport const fmt = {\n int(n: number): string {\n return n.toLocaleString(\"en-US\");\n },\n /** compact number: 1.2K, 3.4M */\n compact(n: number): string {\n if (Math.abs(n) >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (Math.abs(n) >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return String(Math.round(n));\n },\n cost(n: number): string {\n if (n === 0) return \"$0\";\n return n < 0.01 ? `$${n.toFixed(4)}` : `$${n.toFixed(2)}`;\n },\n time(ts: number): string {\n return new Date(ts).toLocaleString(\"en-US\", { hour12: false });\n },\n /** DD/MM/YYYY (local) */\n date(ts: number): string {\n const d = new Date(ts);\n return `${String(d.getDate()).padStart(2, \"0\")}/${String(d.getMonth() + 1).padStart(2, \"0\")}/${d.getFullYear()}`;\n },\n /** \"3m\", \"2h\", \"5d\" — coarse relative age */\n ago(ts: number): string {\n const s = Math.max(0, Math.round((Date.now() - ts) / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n if (s < 86400) return `${Math.floor(s / 3600)}h`;\n return `${Math.floor(s / 86400)}d`;\n },\n /** ms duration -> \"Xs\", \"Xm Ys\", \"Xh Ym\" for budget/cooldown countdowns */\n duration(ms: number): string {\n const s = Math.max(0, Math.round(ms / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`;\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n if (h < 24) return `${h}h ${m}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n },\n};\n\n/** A labelled stat block — number over a caption. */\nexport function Stat({ label, value, sub }: { label: string; value: React.ReactNode; sub?: string }) {\n return (\n <div className=\"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft\">\n <div className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">{label}</div>\n <div className=\"mt-1 tnum text-[22px] font-semibold tracking-tight text-text\">{value}</div>\n {sub && <div className=\"mt-0.5 text-[12px] text-text-muted\">{sub}</div>}\n </div>\n );\n}\n\n/** Empty-state hint inside a card body. */\nexport function Empty({ children }: { children: React.ReactNode }) {\n return <div className=\"px-1 py-8 text-center text-[13px] text-text-muted\">{children}</div>;\n}\n","/** Status lamp — green when serving, red pulse on cooldown, grey when idle. */\nexport function Lamp({ state, title }: { state: \"live\" | \"idle\" | \"down\"; title?: string }) {\n return <span className={`lamp lamp-${state}`} title={title} aria-label={state} />;\n}\n\nexport function lampFor(healthy: boolean): \"live\" | \"down\" {\n return healthy ? \"live\" : \"down\";\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Icon } from \"./Icon\";\nimport { fmt } from \"./ui\";\n\n/**\n * Live countdown from a gateway-snapshot remaining-ms. Counts down locally each\n * second from render. Used for both key cooldowns (danger tone) and budget window\n * resets (muted tone). Renders nothing once it hits zero unless `keepZero`.\n */\nexport function CooldownTimer({\n ms,\n tone = \"danger\",\n icon = \"timer\",\n keepZero = false,\n}: {\n ms: number;\n tone?: \"danger\" | \"muted\";\n icon?: string;\n keepZero?: boolean;\n}) {\n const [until] = useState(() => Date.now() + ms);\n const [remaining, setRemaining] = useState(() => Math.max(0, ms));\n\n useEffect(() => {\n const tick = () => setRemaining(Math.max(0, until - Date.now()));\n tick();\n const id = setInterval(tick, 1000);\n return () => clearInterval(id);\n }, [until]);\n\n if (remaining <= 0 && !keepZero) return null;\n\n const color = tone === \"danger\" ? \"text-danger\" : \"text-text-muted\";\n return (\n <span className={`inline-flex items-center gap-1 tnum text-[12px] ${color}`}>\n <Icon name={icon} size={13} />\n {remaining <= 0 ? \"now\" : fmt.duration(remaining)}\n </span>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState, useCallback } from \"react\";\nimport Link from \"next/link\";\nimport { adminApi } from \"@/lib/client\";\nimport { Lamp } from \"@/components/Lamp\";\nimport { Badge, FormatBadge } from \"@/components/Badge\";\nimport { CooldownTimer } from \"@/components/CooldownTimer\";\nimport { Button, Input, Field } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { Empty } from \"@/components/ui\";\nimport type { MaskedConfig, PingResult, ProviderSnapshot, WireFormat } from \"@/lib/gateway\";\n\ninterface Loaded {\n config: MaskedConfig;\n health: ProviderSnapshot[];\n}\n\nexport function ProviderManager() {\n const [data, setData] = useState<Loaded | null>(null);\n const [error, setError] = useState(\"\");\n const [adding, setAdding] = useState(false);\n\n const reload = useCallback(async () => {\n const [cfg, prov] = await Promise.all([\n fetch(\"/api/gw/admin/config\"),\n adminApi.providers(),\n ]);\n if (!cfg.ok || !prov.ok) {\n setError(\"could not reach the gateway\");\n return;\n }\n setError(\"\");\n setData({\n config: (await cfg.json()) as MaskedConfig,\n health: prov.data?.providers ?? [],\n });\n }, []);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!data) return <Empty>Loading…</Empty>;\n\n const healthById = new Map(data.health.map((h) => [h.id, h]));\n\n return (\n <div>\n <div className=\"mb-6 flex items-center justify-between gap-3\">\n <div>\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Providers &amp; Keys</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">Upstream providers the gateway routes to.</p>\n </div>\n <Button onClick={() => setAdding(true)}>\n <Icon name=\"add\" size={17} />\n Add provider\n </Button>\n </div>\n\n {adding && (\n <AddProviderForm\n onClose={() => setAdding(false)}\n onDone={() => { setAdding(false); void reload(); }}\n />\n )}\n\n {data.config.providers.length === 0 ? (\n <Empty>No providers yet. Add one to start routing.</Empty>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {data.config.providers.map((p) => {\n const health = healthById.get(p.id);\n const healthy = health ? health.keys.some((k) => k.healthy) : true;\n const cooling = health?.keys.find((k) => !k.healthy && k.cooldown_ms > 0);\n return (\n <Link\n key={p.id}\n href={`/providers/${encodeURIComponent(p.id)}`}\n className={`group rounded-brand-lg border bg-surface p-4 shadow-soft transition-colors ${\n p.disabled\n ? \"border-danger/35 opacity-60 hover:opacity-100 hover:border-danger/60\"\n : \"border-border hover:border-text-subtle\"\n }`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <Lamp state={p.disabled ? \"idle\" : healthy ? \"live\" : \"down\"} />\n <div className=\"min-w-0\">\n <span className=\"block truncate text-[14px] font-semibold text-text\">{p.name || p.id}</span>\n {p.name && <span className=\"block truncate text-[11px] text-text-subtle\">{p.id}/</span>}\n </div>\n </div>\n <FormatBadge format={p.format} />\n </div>\n <div className=\"mt-2 truncate text-[12px] text-text-subtle\">{p.base_url}</div>\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n <ProviderToggle id={p.id} disabled={!!p.disabled} onDone={reload} />\n {p.free && <Badge tone=\"info\">free</Badge>}\n {p.service_account && <Badge tone=\"info\">service-account</Badge>}\n <Badge tone=\"neutral\">\n {p.free || p.service_account ? `${(p.api_keys?.length ?? 0)} keys` : `${p.api_keys?.length ?? (p.api_key ? 1 : 0)} keys`}\n </Badge>\n <Badge tone=\"neutral\">{p.models.length} models</Badge>\n {cooling && <CooldownTimer ms={cooling.cooldown_ms} />}\n </div>\n </Link>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Inline enable/disable switch shown on each provider card. The card is a <Link>,\n * so the button swallows the click (preventDefault + stopPropagation) to toggle in\n * place instead of navigating into the provider. `busy` ignores double-clicks.\n */\nfunction ProviderToggle({ id, disabled, onDone }: { id: string; disabled: boolean; onDone: () => void }) {\n const [busy, setBusy] = useState(false);\n return (\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (busy) return;\n setBusy(true);\n void adminApi.setProviderDisabled(id, !disabled).then(() => onDone()).finally(() => setBusy(false));\n }}\n className={`inline-flex items-center gap-1.5 text-[11px] font-medium ${disabled ? \"text-danger\" : \"text-text-muted\"}`}\n aria-label={disabled ? \"Enable provider\" : \"Disable provider\"}\n title={disabled ? \"Provider disabled — click to enable\" : \"Provider enabled — click to disable\"}\n >\n <span className={`relative h-4 w-7 rounded-full transition-colors ${disabled ? \"bg-danger\" : \"bg-accent\"} ${busy ? \"opacity-60\" : \"\"}`}>\n <span className={`absolute left-0.5 top-0.5 h-3 w-3 rounded-full bg-white transition-transform ${disabled ? \"translate-x-0\" : \"translate-x-[14px]\"}`} />\n </span>\n {disabled ? \"disabled\" : \"enabled\"}\n </button>\n );\n}\n\n// Provider presets — pick a type first, which prefills Base URL + API Type, then\n// you only fill Name + Key. Matches aigetwey's per-type forms but friendlier; the\n// fields below are still aigetwey's (Name, API Type, Base URL, Key + Check, Model\n// ID), minus the separate Prefix — our Name is the id and the model prefix.\ntype Preset = { id: string; label: string; sub: string; icon: string; format: WireFormat; base_url: string; hint: string; modelHint: string };\nconst PRESETS: Preset[] = [\n {\n id: \"openai\", label: \"OpenAI compatible\", sub: \"/v1/chat/completions\", icon: \"bolt\",\n format: \"openai\", base_url: \"https://api.openai.com/v1\",\n hint: \"Base URL ending in /v1 for any OpenAI-compatible API.\", modelHint: \"e.g. gpt-4o, glm-5.2\",\n },\n {\n id: \"anthropic\", label: \"Anthropic compatible\", sub: \"/v1/messages\", icon: \"smart_toy\",\n format: \"anthropic\", base_url: \"https://api.anthropic.com\",\n hint: \"Base URL of an Anthropic-compatible API; /messages is appended.\", modelHint: \"e.g. claude-sonnet-4-6\",\n },\n];\n\nfunction AddProviderForm({ onDone, onClose }: { onDone: () => void; onClose: () => void }) {\n const [preset, setPreset] = useState<Preset | null>(null);\n const [id, setId] = useState(\"\");\n const [baseUrl, setBaseUrl] = useState(\"\");\n const [apiKey, setApiKey] = useState(\"\");\n const [showKey, setShowKey] = useState(false);\n const [modelId, setModelId] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [checking, setChecking] = useState(false);\n const [checkRes, setCheckRes] = useState<PingResult | null>(null);\n const [err, setErr] = useState(\"\");\n\n function choosePreset(p: Preset) {\n setPreset(p);\n setBaseUrl(p.base_url);\n setCheckRes(null);\n setErr(\"\");\n }\n\n // step 1: pick a type (OpenAI- or Anthropic-compatible) — this sets the wire\n // format + base URL, exactly aigetwey's \"Add OpenAI/Anthropic Compatible\".\n if (!preset) {\n return (\n <div className=\"mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-[14px] font-semibold text-text\">Add a provider</h2>\n <p className=\"mt-0.5 text-[12.5px] text-text-muted\">Pick the API your endpoint speaks — the rest is prefilled.</p>\n </div>\n <button type=\"button\" onClick={onClose} className=\"flex-none text-text-subtle hover:text-text\" aria-label=\"Cancel\">\n <Icon name=\"close\" size={18} />\n </button>\n </div>\n <div className=\"mt-4 grid gap-3 sm:grid-cols-2\">\n {PRESETS.map((p) => (\n <button\n key={p.id}\n type=\"button\"\n onClick={() => choosePreset(p)}\n 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\"\n >\n <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\">\n <Icon name={p.icon} size={20} />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-[13.5px] font-semibold text-text\">{p.label}</span>\n <span className=\"block tnum text-[11.5px] text-text-subtle\">{p.sub}</span>\n <span className=\"mt-1 block text-[11.5px] text-text-muted\">{p.hint}</span>\n </span>\n </button>\n ))}\n </div>\n </div>\n );\n }\n\n async function check() {\n if (!baseUrl || !preset) return;\n setChecking(true);\n setCheckRes(null);\n const r = await adminApi.validateProvider({ format: preset.format, base_url: baseUrl, api_key: apiKey || undefined });\n setChecking(false);\n setCheckRes(r.data ?? { ok: false, reachable: false, status: 0, error: r.error });\n }\n\n async function submit(e: React.FormEvent) {\n e.preventDefault();\n if (!preset || !id || !baseUrl) {\n setErr(\"name and base URL are required\");\n return;\n }\n setBusy(true);\n setErr(\"\");\n const res = await adminApi.addProvider({ id, format: preset.format, base_url: baseUrl, api_key: apiKey || undefined, free: !apiKey.trim() });\n if (!res.ok) {\n setBusy(false);\n setErr(res.error ?? \"failed\");\n return;\n }\n if (modelId.trim()) await adminApi.addModel(id, modelId.trim());\n setBusy(false);\n onDone();\n }\n\n // step 2: the aigetwey field set — Name, Base URL, API Key (for Check), Model ID.\n return (\n <div className=\"mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft\">\n <form onSubmit={submit}>\n <div className=\"mb-4 flex items-center gap-2.5 border-b border-border-subtle pb-4\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-brand bg-surface-2 text-text-muted\">\n <Icon name={preset.icon} size={17} />\n </span>\n <div>\n <div className=\"text-[13.5px] font-semibold text-text\">{preset.label}</div>\n <div className=\"tnum text-[11px] text-text-subtle\">{preset.sub}</div>\n </div>\n <button\n type=\"button\"\n onClick={() => { setPreset(null); setCheckRes(null); }}\n className=\"ml-auto inline-flex items-center gap-1 text-[12px] text-text-subtle hover:text-text\"\n >\n <Icon name=\"arrow_back\" size={14} /> change type\n </button>\n </div>\n\n <div className=\"space-y-3\">\n <Field label=\"Name\" hint=\"a friendly id — also the model prefix (name/model)\">\n <Input value={id} onChange={(e) => setId(e.target.value)} placeholder=\"e.g. openai, huki\" />\n </Field>\n <Field label=\"Base URL\" hint={preset.hint}>\n <Input value={baseUrl} onChange={(e) => { setBaseUrl(e.target.value); setCheckRes(null); }} placeholder={preset.base_url} className=\"font-mono text-[12.5px]\" />\n </Field>\n <Field label=\"API Key\" hint=\"used for Check and live requests — leave blank for a free / no-auth endpoint\">\n <div className=\"flex gap-2\">\n <div className=\"relative flex-1\">\n <Input\n type={showKey ? \"text\" : \"password\"}\n value={apiKey}\n onChange={(e) => { setApiKey(e.target.value); setCheckRes(null); }}\n placeholder=\"sk-…\"\n className=\"pr-9 font-mono text-[12.5px]\"\n />\n {apiKey && (\n <button type=\"button\" onClick={() => setShowKey((v) => !v)} className=\"absolute right-2 top-1/2 -translate-y-1/2 text-text-subtle hover:text-text\" aria-label={showKey ? \"Hide key\" : \"Show key\"}>\n <Icon name={showKey ? \"visibility_off\" : \"visibility\"} size={15} />\n </button>\n )}\n </div>\n <Button type=\"button\" variant=\"ghost\" disabled={checking || !baseUrl} onClick={check}>\n <Icon name={checking ? \"progress_activity\" : \"wifi_tethering\"} size={15} />\n {checking ? \"Checking…\" : \"Check\"}\n </Button>\n </div>\n </Field>\n {checkRes && (\n <div className=\"flex items-center gap-2 text-[12px]\">\n <Badge tone={checkRes.ok ? \"live\" : checkRes.reachable ? \"warn\" : \"down\"}>\n {checkRes.ok ? \"valid\" : checkRes.reachable ? `reachable (${checkRes.status})` : \"invalid\"}\n </Badge>\n {checkRes.error && <span className=\"text-text-subtle\">{checkRes.error}</span>}\n </div>\n )}\n <Field label=\"Model ID\" hint=\"optional — seed one if the provider has no /models endpoint\">\n <Input value={modelId} onChange={(e) => setModelId(e.target.value)} placeholder={preset.modelHint} className=\"font-mono text-[12.5px]\" />\n </Field>\n </div>\n\n {err && <div className=\"mt-2 text-[12px] text-danger\">{err}</div>}\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose}>Cancel</Button>\n <Button type=\"submit\" disabled={busy}>{busy ? \"Adding…\" : \"Add provider\"}</Button>\n </div>\n </form>\n </div>\n );\n}\n"],"names":["TONES","live","down","warn","info","neutral","Badge","tone","children","className","FormatBadge","format","fmt","int","n","toLocaleString","compact","Math","abs","toFixed","String","round","cost","time","ts","Date","hour12","date","d","getDate","padStart","getMonth","getFullYear","ago","s","max","now","floor","duration","ms","h","m","Stat","label","value","sub","Empty","Lamp","state","title","lampFor","healthy","CooldownTimer","icon","keepZero","until","remaining","setRemaining","tick","id","setInterval","clearInterval","color","name","size","ProviderManager","data","setData","error","setError","adding","setAdding","reload","cfg","prov","Promise","all","fetch","providers","ok","config","json","health","healthById","Map","map","onClick","AddProviderForm","onClose","onDone","length","p","get","keys","some","k","cooling","find","cooldown_ms","href","encodeURIComponent","disabled","base_url","ProviderToggle","free","service_account","api_keys","api_key","models","busy","setBusy","type","e","preventDefault","stopPropagation","setProviderDisabled","then","finally","PRESETS","hint","modelHint","preset","setPreset","setId","baseUrl","setBaseUrl","apiKey","setApiKey","showKey","setShowKey","modelId","setModelId","checking","setChecking","checkRes","setCheckRes","err","setErr","choosePreset","check","r","validateProvider","undefined","reachable","status","submit","res","addProvider","trim","addModel","onSubmit","onChange","target","placeholder","v","variant"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ module.exports=[42532,a=>{"use strict";var b=a.i(87924),c=a.i(72131);let d=[{key:"tokens",label:"Tokens"},{key:"cost",label:"Cost"},{key:"requests",label:"Requests"}];function e(a,b){return"cost"===b?a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`:a>=1e6?`${(a/1e6).toFixed(1)}M`:a>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a))}function f(a){return new Date(a).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:!1})}function g({series:a}){let[h,i]=(0,c.useState)("tokens"),j=a.map(a=>"tokens"===h?a.tokens_in+a.tokens_out:"cost"===h?a.cost:a.requests),k=Math.max(1,...j),l=a.length,m=a=>l<=1?8:8+a/(l-1)*984,n=a=>224-a/k*208,o=j.map((a,b)=>`${0===b?"M":"L"}${m(b).toFixed(1)},${n(a).toFixed(1)}`).join(" "),p=`${o} L${m(l-1).toFixed(1)},224 L${m(0).toFixed(1)},224 Z`,q=j.length?j.indexOf(Math.max(...j)):-1,r=j.reduce((a,b)=>a+b,0);return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"Over time"}),(0,b.jsxs)("span",{className:"tnum text-[12px] text-text-muted",children:[e(r,h)," total"]})]}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:d.map(a=>(0,b.jsx)("button",{onClick:()=>i(a.key),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${h===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:a.label},a.key))})]}),(0,b.jsx)("div",{className:"px-2 py-3",children:0===l||0===r?(0,b.jsx)("div",{className:"flex h-[200px] items-center justify-center text-[13px] text-text-muted",children:"No activity in this range."}):(0,b.jsxs)("svg",{viewBox:"0 0 1000 240",className:"h-[200px] w-full",preserveAspectRatio:"none",children:[(0,b.jsx)("defs",{children:(0,b.jsxs)("linearGradient",{id:"areaFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[(0,b.jsx)("stop",{offset:"0%",stopColor:"var(--color-accent)",stopOpacity:"0.28"}),(0,b.jsx)("stop",{offset:"100%",stopColor:"var(--color-accent)",stopOpacity:"0"})]})}),(0,b.jsx)("path",{d:p,fill:"url(#areaFill)"}),(0,b.jsx)("path",{d:o,fill:"none",stroke:"var(--color-accent)",strokeWidth:"2",vectorEffect:"non-scaling-stroke"}),q>=0&&(0,b.jsx)("circle",{cx:m(q),cy:n(j[q]),r:"3",fill:"var(--color-accent)",vectorEffect:"non-scaling-stroke"})]})}),l>0&&r>0&&q>=0&&(0,b.jsxs)("div",{className:"flex justify-between border-t border-border-subtle px-4 py-2 tnum text-[10px] text-text-subtle",children:[(0,b.jsx)("span",{children:f(a[0].ts)}),(0,b.jsxs)("span",{children:["peak ",e(j[q],h)," @ ",f(a[q].ts)]}),(0,b.jsx)("span",{children:f(a[l-1].ts)})]})]})}var h=a.i(58918),i=a.i(85732);let j=[{label:"Today",key:"today",bucketMs:36e5},{label:"24h",key:"24h",bucketMs:36e5},{label:"7D",key:"7d",bucketMs:216e5},{label:"30D",key:"30d",bucketMs:864e5},{label:"60D",key:"60d",bucketMs:1728e5}];function k({rows:a,loading:c}){return(0,b.jsx)("div",{className:`table-wrap ${c?"opacity-50":""}`,children:(0,b.jsxs)("table",{className:"w-full border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["","Reqs","In","Out","Cost"].map((a,c)=>(0,b.jsx)("th",{className:`pb-2 text-[10px] font-medium uppercase tracking-wider ${0===c?"text-left":"text-right"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:a.map(a=>(0,b.jsxs)("tr",{className:"border-t border-border-subtle",children:[(0,b.jsx)("td",{className:"py-2 text-[12.5px] text-text",children:a.label}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.int(a.requests)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.compact(a.tokens_in)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.compact(a.tokens_out)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text",children:h.fmt.cost(a.cost)})]},a.label))})]})})}a.s(["UsageView",0,function(){let[a,d]=(0,c.useState)(j[0]),[e,f]=(0,c.useState)(null),[l,m]=(0,c.useState)([]),[n,o]=(0,c.useState)(""),[p,q]=(0,c.useState)(!0),r=(0,c.useCallback)(async a=>{q(!0),o("");let b=function(a){let b=Date.now();switch(a){case"today":{let a=new Date;return a.setHours(0,0,0,0),a.getTime()}case"24h":return b-864e5;case"7d":return b-6048e5;case"30d":return b-2592e6;case"60d":return b-5184e6}}(a.key),[c,d]=await Promise.all([fetch(`/api/gw/admin/usage?since=${b}`),fetch(`/api/gw/admin/usage/series?since=${b}&bucket=${a.bucketMs}`)]);if(!c.ok){o("could not load usage"),q(!1);return}f(await c.json()),m((d.ok?await d.json():{series:[]}).series),q(!1)},[]);(0,c.useEffect)(()=>{r(a)},[a,r]);let s=e?.total;return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6 flex items-center justify-between gap-3",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Usage"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Tokens and cost across providers and models."})]}),(0,b.jsx)("div",{className:"flex items-center gap-1 rounded-full border border-border bg-surface p-1",children:j.map(c=>(0,b.jsx)("button",{onClick:()=>d(c),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${a.label===c.label?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:c.label},c.label))})]}),n?(0,b.jsx)(h.Empty,{children:n}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{className:"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",children:[(0,b.jsx)(h.Stat,{label:"Requests",value:h.fmt.int(s?.requests??0)}),(0,b.jsx)(h.Stat,{label:"Tokens in",value:h.fmt.compact(s?.tokens_in??0)}),(0,b.jsx)(h.Stat,{label:"Tokens out",value:h.fmt.compact(s?.tokens_out??0)}),(0,b.jsx)(h.Stat,{label:"Cost",value:h.fmt.cost(s?.cost??0)})]}),(0,b.jsx)("div",{className:"mb-5",children:(0,b.jsx)(g,{series:l})}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,b.jsx)(i.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By provider"}),children:e?.by_provider.length?(0,b.jsx)(k,{rows:e.by_provider.map(a=>({label:a.provider,...a})),loading:p}):(0,b.jsx)(h.Empty,{children:"No usage in this window."})}),(0,b.jsx)(i.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By model"}),children:e?.by_model.length?(0,b.jsx)(k,{rows:e.by_model.map(a=>({label:`${a.alias} → ${a.model}`,...a})),loading:p}):(0,b.jsx)(h.Empty,{children:"No usage in this window."})})]})]})]})}],42532)},61574,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(47153),e=a.i(2693),f=a.i(93026),g=a.i(58918);let h=[{key:"all",label:"All"},{key:"ok",label:"Success"},{key:"error",label:"Errors"}],i=[{label:"1h",ms:36e5},{label:"6h",ms:216e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"All",ms:null}];function j({label:a,children:c}){return(0,b.jsxs)("label",{className:"flex flex-col gap-1",children:[(0,b.jsx)("span",{className:"text-[10px] font-medium uppercase tracking-wider text-text-subtle",children:a}),c]})}function k({children:a,muted:c,right:d,title:e,className:f,suppressHydrationWarning:g}){return(0,b.jsx)("td",{title:e,suppressHydrationWarning:g,className:`whitespace-nowrap px-4 py-2.5 tnum text-[12.5px] ${d?"text-right":"text-left"} ${c?"text-text-muted":"text-text"}${f?` ${f}`:""}`,children:a})}function l({log:a,onClose:c}){let d=a.status>=200&&a.status<300,e=a.tokens_in+a.tokens_out;return(0,b.jsxs)("div",{className:"border-t border-border-subtle bg-surface-2/40 px-5 py-4",children:[(0,b.jsxs)("div",{className:"mb-3 flex items-center justify-between",children:[(0,b.jsx)("span",{className:"text-[12px] font-semibold text-text",children:"Request Details"}),(0,b.jsx)("button",{onClick:c,className:"text-text-subtle hover:text-text",children:(0,b.jsx)(f.Icon,{name:"close",size:16})})]}),(0,b.jsxs)("div",{className:"grid grid-cols-2 gap-x-8 gap-y-2 text-[12px] sm:grid-cols-4",children:[(0,b.jsx)(m,{label:"Status",value:`${a.status} ${d?"OK":"Error"}`}),(0,b.jsx)(m,{label:"Timestamp",value:new Date(a.ts).toLocaleString()}),(0,b.jsx)(m,{label:"Alias",value:a.alias}),(0,b.jsx)(m,{label:"Provider",value:a.provider}),(0,b.jsx)(m,{label:"Model",value:a.model}),(0,b.jsx)(m,{label:"Mode",value:a.stream?"Streaming":"Unary"}),(0,b.jsx)(m,{label:"Latency",value:`${a.latency_ms}ms`}),(0,b.jsx)(m,{label:"Cost",value:g.fmt.cost(a.cost)}),(0,b.jsx)(m,{label:"Input tokens",value:g.fmt.int(a.tokens_in)}),(0,b.jsx)(m,{label:"Output tokens",value:g.fmt.int(a.tokens_out)}),(0,b.jsx)(m,{label:"Cached tokens",value:g.fmt.int(a.cached_tokens)}),(0,b.jsx)(m,{label:"Total tokens",value:g.fmt.int(e)})]})]})}function m({label:a,value:c}){return(0,b.jsxs)("div",{children:[(0,b.jsx)("span",{className:"text-[10px] uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"tnum text-text",children:c})]})}a.s(["LogTable",0,function({logs:a}){let[m,n]=(0,c.useState)(a),[o,p]=(0,c.useState)("all"),[q,r]=(0,c.useState)("all"),[s,t]=(0,c.useState)(null),[u,v]=(0,c.useState)(!0),[w,x]=(0,c.useState)(!1),[y,z]=(0,c.useState)(null),A=(0,c.useRef)(null),B=(0,c.useCallback)(async()=>{try{let a=await fetch("/api/gw/admin/logs?limit=200");if(a.ok){let b=await a.json();n(b.logs)}}catch{}},[]);(0,c.useEffect)(()=>{if(u)return A.current=setInterval(B,5e3),()=>{A.current&&clearInterval(A.current)};A.current&&clearInterval(A.current)},[u,B]);let C=[...new Set(m.map(a=>a.provider))].sort(),D=m.filter(a=>a.status>=200&&a.status<300).length,E=m.length-D,F=null!==s?Date.now()-s:null,G=m.filter(a=>("ok"!==o||!!(a.status>=200&&a.status<300))&&("error"!==o||!(a.status>=200)||!(a.status<300))&&("all"===q||a.provider===q)&&(null===F||!(a.ts<F))),H="all"!==o||"all"!==q||null!==s;return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex flex-col gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,b.jsx)("button",{onClick:()=>x(a=>!a),className:"flex-none rounded p-0.5 text-text-subtle transition-colors hover:text-text","aria-label":w?"Expand requests":"Collapse requests",title:w?"Expand":"Collapse",children:(0,b.jsx)(f.Icon,{name:w?"chevron_right":"expand_more",size:18})}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:h.map(a=>{let c;return(0,b.jsxs)("button",{onClick:()=>p(a.key),className:`flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[12px] font-medium transition-colors ${o===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:[a.label,(0,b.jsx)("span",{className:"tnum text-text-subtle",children:"all"===(c=a.key)?m.length:"ok"===c?D:E})]},a.key)})})]}),(0,b.jsxs)("button",{onClick:()=>v(a=>!a),className:`flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors ${u?"bg-success/15 text-success":"text-text-muted hover:text-text"}`,title:u?"Auto-refresh ON (5s)":"Auto-refresh OFF",children:[(0,b.jsx)(f.Icon,{name:u?"radio_button_checked":"radio_button_unchecked",size:12}),"Live"]})]}),!w&&(0,b.jsxs)("div",{className:"flex flex-wrap items-end gap-2.5",children:[(0,b.jsx)(j,{label:"Provider",children:(0,b.jsxs)("select",{value:q,onChange:a=>r(a.target.value),className:"h-9 rounded-brand border border-border bg-surface-2 px-2.5 text-[12.5px] text-text focus:border-accent focus:outline-none w-40",children:[(0,b.jsx)("option",{value:"all",children:"All providers"}),C.map(a=>(0,b.jsx)("option",{value:a,children:a},a))]})}),(0,b.jsx)(j,{label:"Since",children:(0,b.jsx)("div",{className:"flex h-9 items-center gap-0.5 rounded-brand border border-border bg-surface-2 px-1",children:i.map(a=>{let c;return(0,b.jsx)("button",{type:"button",onClick:()=>t(a.ms),className:(c=s===a.ms,`rounded-full px-2.5 py-1 text-[12px] font-medium transition-colors ${c?"bg-accent/15 text-accent":"text-text-muted hover:text-text"}`),children:a.label},a.label)})})}),(0,b.jsxs)("button",{onClick:()=>{p("all"),r("all"),t(null)},disabled:!H,className:"flex h-9 items-center gap-1.5 rounded-brand border border-border bg-surface-2 px-3 text-[12.5px] font-medium text-text-muted transition-colors hover:border-text-subtle hover:text-text disabled:opacity-40 disabled:hover:border-border disabled:hover:text-text-muted",title:H?"Reset all filters":"No filters applied",children:[(0,b.jsx)(f.Icon,{name:"filter_alt_off",size:15}),"Clear"]})]})]}),w?null:0===G.length?(0,b.jsx)("div",{className:"px-4 py-8 text-center text-[13px] text-text-muted",children:0===m.length?"No requests recorded yet.":"No requests match this filter."}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("div",{className:"table-wrap",children:(0,b.jsxs)("table",{className:"w-full min-w-[720px] border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["Status","Time","Alias","Provider","Model","In","Out","ms","Mode"].map((a,c)=>(0,b.jsx)("th",{className:`whitespace-nowrap px-4 pb-2.5 pt-3 text-[10px] font-medium uppercase tracking-wider ${c>=5&&c<=7?"text-right":"text-left"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:G.map((a,c)=>{let f=a.status>=200&&a.status<300,h=y===c;return(0,b.jsxs)("tr",{onClick:()=>z(h?null:c),className:`border-t border-border-subtle cursor-pointer transition-colors ${h?"bg-surface-2/60":"hover:bg-surface-2/40"}`,children:[(0,b.jsx)(k,{children:(0,b.jsxs)(e.Badge,{tone:f?"live":"down",children:[(0,b.jsx)(d.Lamp,{state:f?"live":"down"}),a.status]})}),(0,b.jsxs)(k,{muted:!0,title:g.fmt.time(a.ts),suppressHydrationWarning:!0,children:[g.fmt.ago(a.ts)," ago"]}),(0,b.jsx)(k,{className:"text-text",children:a.alias}),(0,b.jsx)(k,{muted:!0,children:a.provider}),(0,b.jsx)(k,{muted:!0,children:a.model}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_in)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_out)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.latency_ms)}),(0,b.jsx)(k,{muted:!0,children:a.stream?"stream":"unary"})]},c)})})]})}),null!==y&&G[y]&&(0,b.jsx)(l,{log:G[y],onClose:()=>z(null)})]})]})}])}];
2
+
3
+ //# sourceMappingURL=src_components_10h9ide._.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/UsageView.tsx","../../../../src/components/AreaChart.tsx","../../../../src/components/LogTable.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useCallback } from \"react\";\nimport { AreaChart, type SeriesPoint } from \"@/components/AreaChart\";\nimport { Stat, fmt, Empty } from \"@/components/ui\";\nimport { RichCard } from \"@/components/RichCard\";\nimport type { UsageSummary } from \"@/lib/gateway\";\n\ntype Window = { label: string; key: \"today\" | \"24h\" | \"7d\" | \"30d\" | \"60d\"; bucketMs: number };\n\n// window -> chart bucket size. Buckets keep ~24-60 points per range.\nconst WINDOWS: Window[] = [\n { label: \"Today\", key: \"today\", bucketMs: 3600_000 },\n { label: \"24h\", key: \"24h\", bucketMs: 3600_000 },\n { label: \"7D\", key: \"7d\", bucketMs: 6 * 3600_000 },\n { label: \"30D\", key: \"30d\", bucketMs: 86400_000 },\n { label: \"60D\", key: \"60d\", bucketMs: 2 * 86400_000 },\n];\n\n/** Lookback start (ms epoch) for a window. \"Today\" is since local midnight; the\n * rest are rolling lookbacks from now. */\nfunction sinceFor(key: Window[\"key\"]): number {\n const now = Date.now();\n switch (key) {\n case \"today\": {\n const d = new Date();\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n }\n case \"24h\": return now - 24 * 3600_000;\n case \"7d\": return now - 7 * 86400_000;\n case \"30d\": return now - 30 * 86400_000;\n case \"60d\": return now - 60 * 86400_000;\n }\n}\n\nexport function UsageView() {\n const [win, setWin] = useState<Window>(WINDOWS[0]!);\n const [summary, setSummary] = useState<UsageSummary | null>(null);\n const [series, setSeries] = useState<SeriesPoint[]>([]);\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(true);\n\n const load = useCallback(async (w: Window) => {\n setLoading(true);\n setError(\"\");\n const since = sinceFor(w.key);\n const [sumRes, serRes] = await Promise.all([\n fetch(`/api/gw/admin/usage?since=${since}`),\n fetch(`/api/gw/admin/usage/series?since=${since}&bucket=${w.bucketMs}`),\n ]);\n if (!sumRes.ok) {\n setError(\"could not load usage\");\n setLoading(false);\n return;\n }\n setSummary((await sumRes.json()) as UsageSummary);\n const ser = serRes.ok ? ((await serRes.json()) as { series: SeriesPoint[] }) : { series: [] };\n setSeries(ser.series);\n setLoading(false);\n }, []);\n\n useEffect(() => {\n void load(win);\n }, [win, load]);\n\n const total = summary?.total;\n\n return (\n <div>\n <div className=\"mb-6 flex items-center justify-between gap-3\">\n <div>\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Usage</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">Tokens and cost across providers and models.</p>\n </div>\n <div className=\"flex items-center gap-1 rounded-full border border-border bg-surface p-1\">\n {WINDOWS.map((w) => (\n <button\n key={w.label}\n onClick={() => setWin(w)}\n className={`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${\n win.label === w.label ? \"bg-surface-2 text-text\" : \"text-text-muted hover:text-text\"\n }`}\n >\n {w.label}\n </button>\n ))}\n </div>\n </div>\n\n {error ? (\n <Empty>{error}</Empty>\n ) : (\n <>\n <div className=\"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <Stat label=\"Requests\" value={fmt.int(total?.requests ?? 0)} />\n <Stat label=\"Tokens in\" value={fmt.compact(total?.tokens_in ?? 0)} />\n <Stat label=\"Tokens out\" value={fmt.compact(total?.tokens_out ?? 0)} />\n <Stat label=\"Cost\" value={fmt.cost(total?.cost ?? 0)} />\n </div>\n\n <div className=\"mb-5\">\n <AreaChart series={series} />\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <RichCard header={<span className=\"text-[13px] font-semibold text-text\">By provider</span>}>\n {summary?.by_provider.length ? (\n <BreakdownTable\n rows={summary.by_provider.map((p) => ({ label: p.provider, ...p }))}\n loading={loading}\n />\n ) : (\n <Empty>No usage in this window.</Empty>\n )}\n </RichCard>\n <RichCard header={<span className=\"text-[13px] font-semibold text-text\">By model</span>}>\n {summary?.by_model.length ? (\n <BreakdownTable\n rows={summary.by_model.map((m) => ({ label: `${m.alias} → ${m.model}`, ...m }))}\n loading={loading}\n />\n ) : (\n <Empty>No usage in this window.</Empty>\n )}\n </RichCard>\n </div>\n </>\n )}\n </div>\n );\n}\n\nfunction BreakdownTable({\n rows,\n loading,\n}: {\n rows: Array<{ label: string; requests: number; tokens_in: number; tokens_out: number; cost: number }>;\n loading: boolean;\n}) {\n return (\n <div className={`table-wrap ${loading ? \"opacity-50\" : \"\"}`}>\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"text-text-subtle\">\n {[\"\", \"Reqs\", \"In\", \"Out\", \"Cost\"].map((h, i) => (\n <th\n key={h + i}\n className={`pb-2 text-[10px] font-medium uppercase tracking-wider ${i === 0 ? \"text-left\" : \"text-right\"}`}\n >\n {h}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr key={r.label} className=\"border-t border-border-subtle\">\n <td className=\"py-2 text-[12.5px] text-text\">{r.label}</td>\n <td className=\"py-2 text-right tnum text-[12.5px] text-text-muted\">{fmt.int(r.requests)}</td>\n <td className=\"py-2 text-right tnum text-[12.5px] text-text-muted\">{fmt.compact(r.tokens_in)}</td>\n <td className=\"py-2 text-right tnum text-[12.5px] text-text-muted\">{fmt.compact(r.tokens_out)}</td>\n <td className=\"py-2 text-right tnum text-[12.5px] text-text\">{fmt.cost(r.cost)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\n\nexport interface SeriesPoint {\n ts: number;\n requests: number;\n tokens_in: number;\n tokens_out: number;\n cost: number;\n}\n\ntype Metric = \"tokens\" | \"cost\" | \"requests\";\n\nconst METRICS: { key: Metric; label: string }[] = [\n { key: \"tokens\", label: \"Tokens\" },\n { key: \"cost\", label: \"Cost\" },\n { key: \"requests\", label: \"Requests\" },\n];\n\nfunction valueOf(p: SeriesPoint, m: Metric): number {\n if (m === \"tokens\") return p.tokens_in + p.tokens_out;\n if (m === \"cost\") return p.cost;\n return p.requests;\n}\n\nfunction fmtVal(v: number, m: Metric): string {\n if (m === \"cost\") return v < 0.01 ? `$${v.toFixed(4)}` : `$${v.toFixed(2)}`;\n if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;\n if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`;\n return String(Math.round(v));\n}\n\nfunction fmtTime(ts: number): string {\n return new Date(ts).toLocaleTimeString(\"en-US\", { hour: \"2-digit\", minute: \"2-digit\", hour12: false });\n}\n\n/** Inline-SVG area chart with a metric toggle. No charting dependency. */\nexport function AreaChart({ series }: { series: SeriesPoint[] }) {\n const [metric, setMetric] = useState<Metric>(\"tokens\");\n\n const W = 1000;\n const H = 240;\n const padX = 8;\n const padY = 16;\n\n const vals = series.map((p) => valueOf(p, metric));\n const max = Math.max(1, ...vals);\n const n = series.length;\n\n const x = (i: number) => (n <= 1 ? padX : padX + (i / (n - 1)) * (W - padX * 2));\n const y = (v: number) => H - padY - (v / max) * (H - padY * 2);\n\n const line = vals.map((v, i) => `${i === 0 ? \"M\" : \"L\"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(\" \");\n const area = `${line} L${x(n - 1).toFixed(1)},${H - padY} L${x(0).toFixed(1)},${H - padY} Z`;\n\n const peak = vals.length ? vals.indexOf(Math.max(...vals)) : -1;\n const total = vals.reduce((a, b) => a + b, 0);\n\n return (\n <div className=\"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft\">\n <header className=\"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3\">\n <div className=\"flex items-center gap-2.5\">\n <span className=\"text-[13px] font-semibold text-text\">Over time</span>\n <span className=\"tnum text-[12px] text-text-muted\">{fmtVal(total, metric)} total</span>\n </div>\n <div className=\"flex items-center gap-1\">\n {METRICS.map((m) => (\n <button\n key={m.key}\n onClick={() => setMetric(m.key)}\n className={`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${\n metric === m.key ? \"bg-surface-2 text-text\" : \"text-text-muted hover:text-text\"\n }`}\n >\n {m.label}\n </button>\n ))}\n </div>\n </header>\n\n <div className=\"px-2 py-3\">\n {n === 0 || total === 0 ? (\n <div className=\"flex h-[200px] items-center justify-center text-[13px] text-text-muted\">\n No activity in this range.\n </div>\n ) : (\n <svg viewBox={`0 0 ${W} ${H}`} className=\"h-[200px] w-full\" preserveAspectRatio=\"none\">\n <defs>\n <linearGradient id=\"areaFill\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"var(--color-accent)\" stopOpacity=\"0.28\" />\n <stop offset=\"100%\" stopColor=\"var(--color-accent)\" stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n <path d={area} fill=\"url(#areaFill)\" />\n <path d={line} fill=\"none\" stroke=\"var(--color-accent)\" strokeWidth=\"2\" vectorEffect=\"non-scaling-stroke\" />\n {peak >= 0 && (\n <circle cx={x(peak)} cy={y(vals[peak]!)} r=\"3\" fill=\"var(--color-accent)\" vectorEffect=\"non-scaling-stroke\" />\n )}\n </svg>\n )}\n </div>\n\n {n > 0 && total > 0 && peak >= 0 && (\n <div className=\"flex justify-between border-t border-border-subtle px-4 py-2 tnum text-[10px] text-text-subtle\">\n <span>{fmtTime(series[0]!.ts)}</span>\n <span>\n peak {fmtVal(vals[peak]!, metric)} @ {fmtTime(series[peak]!.ts)}\n </span>\n <span>{fmtTime(series[n - 1]!.ts)}</span>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef, useCallback } from \"react\";\nimport { Lamp } from \"@/components/Lamp\";\nimport { Badge } from \"@/components/Badge\";\nimport { Icon } from \"@/components/Icon\";\nimport { fmt } from \"@/components/ui\";\nimport type { UsageLog } from \"@/lib/gateway\";\n\ntype StatusFilter = \"all\" | \"ok\" | \"error\";\n\nconst FILTERS: { key: StatusFilter; label: string }[] = [\n { key: \"all\", label: \"All\" },\n { key: \"ok\", label: \"Success\" },\n { key: \"error\", label: \"Errors\" },\n];\n\n// shared control style for the filter row — bordered surface chip, accent on focus.\nconst ctrl = \"h-9 rounded-brand border border-border bg-surface-2 px-2.5 text-[12.5px] text-text focus:border-accent focus:outline-none\";\n\n// recency presets for the request log (a live 200-row buffer, so relative\n// windows fit better than absolute dates). null = no time filter.\nconst SINCE_PRESETS: { label: string; ms: number | null }[] = [\n { label: \"1h\", ms: 3600_000 },\n { label: \"6h\", ms: 6 * 3600_000 },\n { label: \"24h\", ms: 24 * 3600_000 },\n { label: \"7d\", ms: 7 * 86400_000 },\n { label: \"All\", ms: null },\n];\nconst sincePill = (active: boolean): string =>\n `rounded-full px-2.5 py-1 text-[12px] font-medium transition-colors ${\n active ? \"bg-accent/15 text-accent\" : \"text-text-muted hover:text-text\"\n }`;\n\nexport function LogTable({ logs: initial }: { logs: UsageLog[] }) {\n const [logs, setLogs] = useState(initial);\n const [filter, setFilter] = useState<StatusFilter>(\"all\");\n const [provFilter, setProvFilter] = useState<string>(\"all\");\n const [sinceMs, setSinceMs] = useState<number | null>(null);\n const [live, setLive] = useState(true);\n const [collapsed, setCollapsed] = useState(false);\n const [expandedIdx, setExpandedIdx] = useState<number | null>(null);\n const timer = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const refresh = useCallback(async () => {\n try {\n const res = await fetch(\"/api/gw/admin/logs?limit=200\");\n if (res.ok) {\n const data = (await res.json()) as { logs: UsageLog[] };\n setLogs(data.logs);\n }\n } catch { /* ignore */ }\n }, []);\n\n useEffect(() => {\n if (live) {\n timer.current = setInterval(refresh, 5000);\n return () => { if (timer.current) clearInterval(timer.current); };\n }\n if (timer.current) clearInterval(timer.current);\n }, [live, refresh]);\n\n const providers = [...new Set(logs.map((l) => l.provider))].sort();\n\n const okCount = logs.filter((l) => l.status >= 200 && l.status < 300).length;\n const errCount = logs.length - okCount;\n\n const sinceFloor = sinceMs !== null ? Date.now() - sinceMs : null;\n\n const shown = logs.filter((l) => {\n if (filter === \"ok\" && !(l.status >= 200 && l.status < 300)) return false;\n if (filter === \"error\" && l.status >= 200 && l.status < 300) return false;\n if (provFilter !== \"all\" && l.provider !== provFilter) return false;\n if (sinceFloor !== null && l.ts < sinceFloor) return false;\n return true;\n });\n\n const hasFilters = filter !== \"all\" || provFilter !== \"all\" || sinceMs !== null;\n const clearFilters = () => { setFilter(\"all\"); setProvFilter(\"all\"); setSinceMs(null); };\n\n const count = (k: StatusFilter) => (k === \"all\" ? logs.length : k === \"ok\" ? okCount : errCount);\n\n return (\n <div className=\"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft\">\n <header className=\"flex flex-col gap-3 border-b border-border-subtle px-4 py-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-1.5\">\n <button\n onClick={() => setCollapsed((v) => !v)}\n className=\"flex-none rounded p-0.5 text-text-subtle transition-colors hover:text-text\"\n aria-label={collapsed ? \"Expand requests\" : \"Collapse requests\"}\n title={collapsed ? \"Expand\" : \"Collapse\"}\n >\n <Icon name={collapsed ? \"chevron_right\" : \"expand_more\"} size={18} />\n </button>\n <div className=\"flex items-center gap-1\">\n {FILTERS.map((f) => (\n <button\n key={f.key}\n onClick={() => setFilter(f.key)}\n className={`flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[12px] font-medium transition-colors ${\n filter === f.key ? \"bg-surface-2 text-text\" : \"text-text-muted hover:text-text\"\n }`}\n >\n {f.label}\n <span className=\"tnum text-text-subtle\">{count(f.key)}</span>\n </button>\n ))}\n </div>\n </div>\n <button\n onClick={() => setLive((v) => !v)}\n className={`flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors ${\n live ? \"bg-success/15 text-success\" : \"text-text-muted hover:text-text\"\n }`}\n title={live ? \"Auto-refresh ON (5s)\" : \"Auto-refresh OFF\"}\n >\n <Icon name={live ? \"radio_button_checked\" : \"radio_button_unchecked\"} size={12} />\n Live\n </button>\n </div>\n\n {!collapsed && (\n <div className=\"flex flex-wrap items-end gap-2.5\">\n <FilterField label=\"Provider\">\n <select\n value={provFilter}\n onChange={(e) => setProvFilter(e.target.value)}\n className={ctrl + \" w-40\"}\n >\n <option value=\"all\">All providers</option>\n {providers.map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n </FilterField>\n <FilterField label=\"Since\">\n <div className=\"flex h-9 items-center gap-0.5 rounded-brand border border-border bg-surface-2 px-1\">\n {SINCE_PRESETS.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => setSinceMs(p.ms)}\n className={sincePill(sinceMs === p.ms)}\n >\n {p.label}\n </button>\n ))}\n </div>\n </FilterField>\n <button\n onClick={clearFilters}\n disabled={!hasFilters}\n className=\"flex h-9 items-center gap-1.5 rounded-brand border border-border bg-surface-2 px-3 text-[12.5px] font-medium text-text-muted transition-colors hover:border-text-subtle hover:text-text disabled:opacity-40 disabled:hover:border-border disabled:hover:text-text-muted\"\n title={hasFilters ? \"Reset all filters\" : \"No filters applied\"}\n >\n <Icon name=\"filter_alt_off\" size={15} />\n Clear\n </button>\n </div>\n )}\n </header>\n\n {collapsed ? null : shown.length === 0 ? (\n <div className=\"px-4 py-8 text-center text-[13px] text-text-muted\">\n {logs.length === 0 ? \"No requests recorded yet.\" : \"No requests match this filter.\"}\n </div>\n ) : (\n <>\n <div className=\"table-wrap\">\n <table className=\"w-full min-w-[720px] border-collapse\">\n <thead>\n <tr className=\"text-text-subtle\">\n {[\"Status\", \"Time\", \"Alias\", \"Provider\", \"Model\", \"In\", \"Out\", \"ms\", \"Mode\"].map((h, i) => (\n <th\n key={h + i}\n className={`whitespace-nowrap px-4 pb-2.5 pt-3 text-[10px] font-medium uppercase tracking-wider ${\n i >= 5 && i <= 7 ? \"text-right\" : \"text-left\"\n }`}\n >\n {h}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {shown.map((l, i) => {\n const ok = l.status >= 200 && l.status < 300;\n const isExpanded = expandedIdx === i;\n return (\n <tr key={i} onClick={() => setExpandedIdx(isExpanded ? null : i)} className={`border-t border-border-subtle cursor-pointer transition-colors ${isExpanded ? \"bg-surface-2/60\" : \"hover:bg-surface-2/40\"}`}>\n <Td>\n <Badge tone={ok ? \"live\" : \"down\"}>\n <Lamp state={ok ? \"live\" : \"down\"} />\n {l.status}\n </Badge>\n </Td>\n <Td muted title={fmt.time(l.ts)} suppressHydrationWarning>\n {fmt.ago(l.ts)} ago\n </Td>\n <Td className=\"text-text\">{l.alias}</Td>\n <Td muted>{l.provider}</Td>\n <Td muted>{l.model}</Td>\n <Td right>{fmt.int(l.tokens_in)}</Td>\n <Td right>{fmt.int(l.tokens_out)}</Td>\n <Td right>{fmt.int(l.latency_ms)}</Td>\n <Td muted>{l.stream ? \"stream\" : \"unary\"}</Td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {expandedIdx !== null && shown[expandedIdx] && (\n <RequestDetail log={shown[expandedIdx]} onClose={() => setExpandedIdx(null)} />\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction FilterField({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wider text-text-subtle\">{label}</span>\n {children}\n </label>\n );\n}\n\nfunction Td({\n children,\n muted,\n right,\n title,\n className,\n suppressHydrationWarning,\n}: {\n children: React.ReactNode;\n muted?: boolean;\n right?: boolean;\n title?: string;\n className?: string;\n suppressHydrationWarning?: boolean;\n}) {\n return (\n <td\n title={title}\n suppressHydrationWarning={suppressHydrationWarning}\n className={`whitespace-nowrap px-4 py-2.5 tnum text-[12.5px] ${right ? \"text-right\" : \"text-left\"} ${\n muted ? \"text-text-muted\" : \"text-text\"\n }${className ? ` ${className}` : \"\"}`}\n >\n {children}\n </td>\n );\n}\n\nfunction RequestDetail({ log, onClose }: { log: UsageLog; onClose: () => void }) {\n const ok = log.status >= 200 && log.status < 300;\n const totalTokens = log.tokens_in + log.tokens_out;\n\n return (\n <div className=\"border-t border-border-subtle bg-surface-2/40 px-5 py-4\">\n <div className=\"mb-3 flex items-center justify-between\">\n <span className=\"text-[12px] font-semibold text-text\">Request Details</span>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\">\n <Icon name=\"close\" size={16} />\n </button>\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2 text-[12px] sm:grid-cols-4\">\n <DetailCell label=\"Status\" value={`${log.status} ${ok ? \"OK\" : \"Error\"}`} />\n <DetailCell label=\"Timestamp\" value={new Date(log.ts).toLocaleString()} />\n <DetailCell label=\"Alias\" value={log.alias} />\n <DetailCell label=\"Provider\" value={log.provider} />\n <DetailCell label=\"Model\" value={log.model} />\n <DetailCell label=\"Mode\" value={log.stream ? \"Streaming\" : \"Unary\"} />\n <DetailCell label=\"Latency\" value={`${log.latency_ms}ms`} />\n <DetailCell label=\"Cost\" value={fmt.cost(log.cost)} />\n <DetailCell label=\"Input tokens\" value={fmt.int(log.tokens_in)} />\n <DetailCell label=\"Output tokens\" value={fmt.int(log.tokens_out)} />\n <DetailCell label=\"Cached tokens\" value={fmt.int(log.cached_tokens)} />\n <DetailCell label=\"Total tokens\" value={fmt.int(totalTokens)} />\n </div>\n </div>\n );\n}\n\nfunction DetailCell({ label, value }: { label: string; value: string }) {\n return (\n <div>\n <span className=\"text-[10px] uppercase tracking-wider text-text-subtle\">{label}</span>\n <div className=\"tnum text-text\">{value}</div>\n </div>\n );\n}\n"],"names":["METRICS","key","label","valueOf","p","m","tokens_in","tokens_out","cost","requests","fmtVal","v","toFixed","String","Math","round","fmtTime","ts","Date","toLocaleTimeString","hour","minute","hour12","AreaChart","series","metric","setMetric","W","H","padX","padY","vals","map","max","n","length","x","i","y","line","join","area","peak","indexOf","total","reduce","a","b","className","onClick","viewBox","preserveAspectRatio","id","x1","y1","x2","y2","offset","stopColor","stopOpacity","d","fill","stroke","strokeWidth","vectorEffect","cx","cy","r","FILTERS","ctrl","SINCE_PRESETS","ms","sincePill","active","LogTable","logs","initial","setLogs","filter","setFilter","provFilter","setProvFilter","sinceMs","setSinceMs","live","setLive","collapsed","setCollapsed","expandedIdx","setExpandedIdx","timer","refresh","res","fetch","ok","data","json","current","setInterval","clearInterval","providers","Set","l","provider","sort","okCount","status","errCount","sinceFloor","now","shown","hasFilters","clearFilters","count","k","title","name","size","f","FilterField","value","onChange","e","target","type","disabled","h","isExpanded","Td","tone","state","muted","time","suppressHydrationWarning","ago","alias","model","right","int","latency_ms","stream","RequestDetail","log","onClose","children","totalTokens","DetailCell","toLocaleString","cached_tokens"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ module.exports=[58918,a=>{"use strict";var b=a.i(87924);a.s(["Empty",0,function({children:a}){return(0,b.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:a})},"Stat",0,function({label:a,value:c,sub:d}){return(0,b.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,b.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:c}),d&&(0,b.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:d})]})},"fmt",0,{int:a=>a.toLocaleString("en-US"),compact:a=>Math.abs(a)>=1e6?`${(a/1e6).toFixed(1)}M`:Math.abs(a)>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a)),cost:a=>0===a?"$0":a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`,time:a=>new Date(a).toLocaleString("en-US",{hour12:!1}),date(a){let b=new Date(a);return`${String(b.getDate()).padStart(2,"0")}/${String(b.getMonth()+1).padStart(2,"0")}/${b.getFullYear()}`},ago(a){let b=Math.max(0,Math.round((Date.now()-a)/1e3));return b<60?`${b}s`:b<3600?`${Math.floor(b/60)}m`:b<86400?`${Math.floor(b/3600)}h`:`${Math.floor(b/86400)}d`},duration(a){let b=Math.max(0,Math.round(a/1e3));if(b<60)return`${b}s`;if(b<3600)return`${Math.floor(b/60)}m ${b%60}s`;let c=Math.floor(b/3600),d=Math.floor(b%3600/60);if(c<24)return`${c}h ${d}m`;let e=Math.floor(c/24);return`${e}d ${c%24}h`}}])},2693,a=>{"use strict";var b=a.i(87924);let c={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 d({tone:a="neutral",children:e,className:f}){return(0,b.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${c[a]}${f?` ${f}`:""}`,children:e})}a.s(["Badge",0,d,"FormatBadge",0,function({format:a}){return(0,b.jsx)(d,{tone:"info",children:a})}])},85732,a=>{"use strict";var b=a.i(87924);a.s(["CardTitle",0,function({title:a,sub:c,icon:d}){return(0,b.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[d,(0,b.jsxs)("div",{className:"min-w-0",children:[(0,b.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:a}),c&&(0,b.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:c})]})]})},"RichCard",0,function({header:a,footer:c,children:d,className:e}){return(0,b.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${e?` ${e}`:""}`,children:[a&&(0,b.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:a}),(0,b.jsx)("div",{className:"p-4",children:d}),c&&(0,b.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:c})]})}])},47153,a=>{"use strict";var b=a.i(87924);a.s(["Lamp",0,function({state:a,title:c}){return(0,b.jsx)("span",{className:`lamp lamp-${a}`,title:c,"aria-label":a})}])}];
2
+
3
+ //# sourceMappingURL=src_components_11ckzq_._.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/ui.tsx","../../../../src/components/Badge.tsx","../../../../src/components/RichCard.tsx","../../../../src/components/Lamp.tsx"],"sourcesContent":["/** Small formatting helpers shared across the console. */\nexport const fmt = {\n int(n: number): string {\n return n.toLocaleString(\"en-US\");\n },\n /** compact number: 1.2K, 3.4M */\n compact(n: number): string {\n if (Math.abs(n) >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (Math.abs(n) >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return String(Math.round(n));\n },\n cost(n: number): string {\n if (n === 0) return \"$0\";\n return n < 0.01 ? `$${n.toFixed(4)}` : `$${n.toFixed(2)}`;\n },\n time(ts: number): string {\n return new Date(ts).toLocaleString(\"en-US\", { hour12: false });\n },\n /** DD/MM/YYYY (local) */\n date(ts: number): string {\n const d = new Date(ts);\n return `${String(d.getDate()).padStart(2, \"0\")}/${String(d.getMonth() + 1).padStart(2, \"0\")}/${d.getFullYear()}`;\n },\n /** \"3m\", \"2h\", \"5d\" — coarse relative age */\n ago(ts: number): string {\n const s = Math.max(0, Math.round((Date.now() - ts) / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n if (s < 86400) return `${Math.floor(s / 3600)}h`;\n return `${Math.floor(s / 86400)}d`;\n },\n /** ms duration -> \"Xs\", \"Xm Ys\", \"Xh Ym\" for budget/cooldown countdowns */\n duration(ms: number): string {\n const s = Math.max(0, Math.round(ms / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`;\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n if (h < 24) return `${h}h ${m}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n },\n};\n\n/** A labelled stat block — number over a caption. */\nexport function Stat({ label, value, sub }: { label: string; value: React.ReactNode; sub?: string }) {\n return (\n <div className=\"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft\">\n <div className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">{label}</div>\n <div className=\"mt-1 tnum text-[22px] font-semibold tracking-tight text-text\">{value}</div>\n {sub && <div className=\"mt-0.5 text-[12px] text-text-muted\">{sub}</div>}\n </div>\n );\n}\n\n/** Empty-state hint inside a card body. */\nexport function Empty({ children }: { children: React.ReactNode }) {\n return <div className=\"px-1 py-8 text-center text-[13px] text-text-muted\">{children}</div>;\n}\n","type Tone = \"live\" | \"down\" | \"warn\" | \"info\" | \"neutral\";\n\nconst TONES: Record<Tone, string> = {\n live: \"bg-success/12 text-success\",\n down: \"bg-danger/12 text-danger\",\n warn: \"bg-warning/12 text-warning\",\n info: \"bg-info/12 text-info\",\n neutral: \"bg-surface-2 text-text-muted\",\n};\n\nexport function Badge({\n tone = \"neutral\",\n children,\n className,\n}: {\n tone?: Tone;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${TONES[tone]}${className ? ` ${className}` : \"\"}`}\n >\n {children}\n </span>\n );\n}\n\n/** Format badge for a provider's wire format. */\nexport function FormatBadge({ format }: { format: \"openai\" | \"anthropic\" | \"gemini\" }) {\n return <Badge tone=\"info\">{format}</Badge>;\n}\n","/**\n * Rich content card — header (title slot + trailing slot), body, optional footer.\n * Softly rounded, subtle border, warm surface. The Haulix-style workhorse.\n */\nexport function RichCard({\n header,\n footer,\n children,\n className,\n}: {\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <section\n className={`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${className ? ` ${className}` : \"\"}`}\n >\n {header && (\n <header className=\"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3\">\n {header}\n </header>\n )}\n <div className=\"p-4\">{children}</div>\n {footer && (\n <footer className=\"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5\">\n {footer}\n </footer>\n )}\n </section>\n );\n}\n\n/** Title + optional subtitle, for the header slot. */\nexport function CardTitle({ title, sub, icon }: { title: string; sub?: string; icon?: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2.5 min-w-0\">\n {icon}\n <div className=\"min-w-0\">\n <div className=\"truncate text-[14px] font-semibold tracking-tight text-text\">{title}</div>\n {sub && <div className=\"truncate text-[12px] text-text-muted\">{sub}</div>}\n </div>\n </div>\n );\n}\n","/** Status lamp — green when serving, red pulse on cooldown, grey when idle. */\nexport function Lamp({ state, title }: { state: \"live\" | \"idle\" | \"down\"; title?: string }) {\n return <span className={`lamp lamp-${state}`} title={title} aria-label={state} />;\n}\n\nexport function lampFor(healthy: boolean): \"live\" | \"down\" {\n return healthy ? \"live\" : \"down\";\n}\n"],"names":["fmt","int","n","toLocaleString","compact","Math","abs","toFixed","String","round","cost","time","ts","Date","hour12","date","d","getDate","padStart","getMonth","getFullYear","ago","s","max","now","floor","duration","ms","h","m","Stat","label","value","sub","className","Empty","children","TONES","live","down","warn","info","neutral","Badge","tone","FormatBadge","format","RichCard","header","footer","CardTitle","title","icon","Lamp","state","lampFor","healthy"],"mappings":"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"}
@@ -0,0 +1,3 @@
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"})]})]})})}])},47153,a=>{"use strict";var b=a.i(87924);a.s(["Lamp",0,function({state:a,title:c}){return(0,b.jsx)("span",{className:`lamp lamp-${a}`,title:c,"aria-label":a})}])},1829,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(56173),e=a.i(47153),f=a.i(2693),g=a.i(85732),h=a.i(7078),i=a.i(47444),j=a.i(93026),k=a.i(73858),l=a.i(58918);function m({providers:a,onDone:e,initial:f,onCancel:g}){let k=!!f,[l,n]=(0,c.useState)(f?.alias??""),[o,p]=(0,c.useState)(()=>f?f.target.map((a,b)=>{let c=Array.isArray(f.model)?f.model[b]??f.model[0]:f.model??f.alias;return`${a}/${c}`}):[]),[q,r]=(0,c.useState)(!1),[s,t]=(0,c.useState)(f?.strategy??"fallback"),[u,v]=(0,c.useState)(f?.price_in?.toString()??""),[w,x]=(0,c.useState)(f?.price_out?.toString()??""),[y,z]=(0,c.useState)(!1),[A,B]=(0,c.useState)(""),[C,D]=(0,c.useState)(null),E=a.filter(a=>a.models.length>0).map(a=>({label:a.id,items:a.models.map(b=>({value:`${a.id}/${b.id}`,label:`${a.id}/${b.id}`}))}));async function F(a){if(a.preventDefault(),!l||0===o.length)return void B("a name and at least one model are required");z(!0),B("");let b=o.map(a=>a.slice(0,a.indexOf("/"))),c=o.map(a=>a.slice(a.indexOf("/")+1)),g=await d.adminApi.setRoute(l,{target:b,model:c,strategy:s,price_in:u?Number(u):void 0,price_out:w?Number(w):void 0});g.ok&&k&&f.alias!==l&&await d.adminApi.removeRoute(f.alias),z(!1),g.ok?e():B(g.error??"failed")}return(0,b.jsxs)("form",{onSubmit:F,className:"mb-5 rounded-brand-lg border border-border bg-surface p-4 shadow-soft",children:[(0,b.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2",children:[(0,b.jsx)(h.Field,{label:"Alias",hint:"the name your CLI requests as a model",children:(0,b.jsx)(h.Input,{value:l,onChange:a=>n(a.target.value),placeholder:"my-claude"})}),(0,b.jsx)(h.Field,{label:"Strategy",hint:"how the chain is tried",children:(0,b.jsxs)(h.Select,{value:s,onChange:a=>t(a.target.value),children:[(0,b.jsx)("option",{value:"fallback",children:"Fallback — try in order, next on failure"}),(0,b.jsx)("option",{value:"round-robin",children:"Round Robin — rotate to spread load"})]})}),(0,b.jsx)(h.Field,{label:"Price in",hint:"per 1M, optional",children:(0,b.jsx)(h.Input,{value:u,onChange:a=>v(a.target.value),placeholder:"3"})}),(0,b.jsx)(h.Field,{label:"Price out",hint:"per 1M, optional",children:(0,b.jsx)(h.Input,{value:w,onChange:a=>x(a.target.value),placeholder:"15"})})]}),(0,b.jsxs)("div",{className:"mt-3",children:[(0,b.jsxs)("div",{className:"flex items-center justify-between",children:[(0,b.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Models — fallback order (drag to reorder)"}),(0,b.jsxs)(h.Button,{type:"button",variant:"ghost",onClick:()=>r(!0),children:[(0,b.jsx)(j.Icon,{name:"add",size:16})," Add models"]})]}),0===o.length?(0,b.jsxs)("div",{className:"mt-2 rounded-brand border border-dashed border-border-subtle px-3 py-4 text-center text-[12px] text-text-subtle",children:["No models yet. Click ",(0,b.jsx)("span",{className:"text-text-muted",children:"Add models"})," and pick from your providers."]}):(0,b.jsx)("ul",{className:"mt-2 space-y-1.5",children:o.map((a,c)=>(0,b.jsxs)("li",{draggable:!0,onDragStart:()=>D(c),onDragOver:a=>a.preventDefault(),onDrop:()=>{null!==C&&C!==c&&p(a=>{let b=[...a],[d]=b.splice(C,1);return b.splice(c,0,d),b}),D(null)},onDragEnd:()=>D(null),className:`flex cursor-grab items-center gap-2.5 rounded-brand border px-3 py-2 active:cursor-grabbing ${C===c?"border-accent bg-accent-soft":"border-border-subtle"}`,children:[(0,b.jsx)(j.Icon,{name:"drag_indicator",size:16,className:"text-text-subtle"}),(0,b.jsx)("span",{className:"tnum text-[11px] text-text-subtle",children:0===c?"primary":`#${c+1}`}),(0,b.jsx)("span",{className:"tnum truncate text-[13px] text-text",children:a}),(0,b.jsx)("button",{type:"button",onClick:()=>p(a=>a.filter((a,b)=>b!==c)),className:"ml-auto flex-none text-text-subtle hover:text-danger","aria-label":`Remove ${a}`,children:(0,b.jsx)(j.Icon,{name:"close",size:14})})]},a))})]}),A&&(0,b.jsx)("div",{className:"mt-2 text-[12px] text-danger",children:A}),(0,b.jsxs)("div",{className:"mt-3 flex justify-end gap-2",children:[g&&(0,b.jsx)(h.Button,{type:"button",variant:"ghost",onClick:g,children:"Cancel"}),(0,b.jsx)(h.Button,{type:"submit",disabled:y,children:y?"Saving…":k?"Update combo":"Save combo"})]}),q&&(0,b.jsx)(i.ModelPicker,{title:"Add models to the chain",note:"Click a model to add it, click again to remove. Drag to reorder after.",groups:E,selected:o,onToggle:function(a){B(""),p(b=>b.includes(a)?b.filter(b=>b!==a):[...b,a])},onClose:()=>r(!1)})]})}a.s(["RoutingView",0,function(){let[a,i]=(0,c.useState)(null),[n,o]=(0,c.useState)([]),[p,q]=(0,c.useState)(""),[r,s]=(0,c.useState)(!1),[t,u]=(0,c.useState)(""),[v,w]=(0,c.useState)({}),[x,y]=(0,c.useState)(null),[z,A]=(0,c.useState)(null),[B,C]=(0,c.useState)(null),D=(0,c.useCallback)(async()=>{let[a,b]=await Promise.all([fetch("/api/gw/admin/config"),d.adminApi.providers()]);a.ok?(q(""),i(await a.json()),o(b.data?.providers??[])):q("could not reach the gateway")},[]);if((0,c.useEffect)(()=>{D()},[D]),p)return(0,b.jsx)(l.Empty,{children:p});if(!a)return(0,b.jsx)(l.Empty,{children:"Loading…"});async function E(a){u(a);let b=await d.adminApi.removeRoute(a);u(""),b.ok?await D():q(b.error??"failed")}async function F(a){y(a.alias),w(b=>({...b,[a.alias]:{}}));for(let b=0;b<a.target.length;b++){w(c=>({...c,[a.alias]:{...c[a.alias],[b]:"testing"}}));let c=await d.adminApi.testProvider(a.target[b]),e=c.ok&&c.data?.ok;w(c=>({...c,[a.alias]:{...c[a.alias],[b]:e?"ok":"fail"}})),b<a.target.length-1&&await new Promise(a=>setTimeout(a,400))}y(null)}return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-5 flex items-center justify-between gap-3",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Combos & Routing"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"A combo is an alias your CLI tool calls, routed to a chain of providers. Fallback tries them in order; round-robin spreads load."})]}),(0,b.jsxs)(h.Button,{onClick:()=>s(a=>!a),children:[(0,b.jsx)(j.Icon,{name:r?"close":"add",size:17}),r?"Cancel":"Add combo"]})]}),r&&(0,b.jsx)(m,{providers:a.providers.filter(a=>!a.disabled),onDone:()=>{s(!1),D()}}),B&&!r&&(0,b.jsx)(m,{providers:a.providers.filter(a=>!a.disabled),initial:B,onDone:()=>{C(null),D()},onCancel:()=>C(null)}),0===a.models.length?(0,b.jsx)(l.Empty,{children:"No combos yet. Add one to expose a model alias to your CLI tools."}):(0,b.jsx)("div",{className:"grid gap-3 lg:grid-cols-2",children:a.models.map(a=>(0,b.jsx)(g.RichCard,{header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(g.CardTitle,{title:a.alias,sub:`${a.target.length} in chain`}),(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsxs)("button",{onClick:()=>F(a),disabled:x===a.alias,className:"flex items-center gap-1 rounded px-2 py-1 text-[11px] text-text-subtle transition-colors hover:bg-surface-2 hover:text-text disabled:opacity-60",title:"Test each provider in this chain",children:[(0,b.jsx)(j.Icon,{name:x===a.alias?"progress_activity":"sync",size:14}),"Test"]}),(0,b.jsx)(f.Badge,{tone:"round-robin"===a.strategy?"info":"neutral",children:a.strategy}),(void 0!==a.price_in||void 0!==a.price_out)&&(0,b.jsxs)(f.Badge,{tone:"neutral",children:[l.fmt.cost(a.price_in??0),"/",l.fmt.cost(a.price_out??0)," per 1M"]}),(0,b.jsx)("button",{onClick:()=>C(a),className:"text-text-subtle hover:text-text","aria-label":"Edit combo",children:(0,b.jsx)(j.Icon,{name:"edit",size:16})}),(0,b.jsx)("button",{onClick:()=>A(a.alias),disabled:t===a.alias,className:"text-text-subtle hover:text-danger","aria-label":"Remove alias",children:(0,b.jsx)(j.Icon,{name:"delete",size:16})})]})]}),children:(0,b.jsx)("ol",{className:"space-y-1.5",children:a.target.map((c,d)=>{let f,g=v[a.alias]?.[d];return(0,b.jsxs)("li",{className:"flex items-center gap-2.5 rounded-brand border border-border-subtle px-3 py-2",children:[(0,b.jsx)("span",{className:"tnum text-[11px] text-text-subtle",children:0===d?"primary":`#${d+1}`}),(0,b.jsx)(e.Lamp,{state:("ok"===g?"live":"fail"===g?"down":"testing"===g?"idle":null)??(!(f=n.find(a=>a.id===c))||f.keys.some(a=>a.healthy)?"live":"down")}),(0,b.jsx)("span",{className:"text-[13px] text-text",children:c}),(0,b.jsx)("span",{className:"ml-auto tnum text-[12px] text-text-muted",children:Array.isArray(a.model)?a.model[d]??a.model[0]??a.alias:"string"==typeof a.model?a.model:a.alias}),"ok"===g&&(0,b.jsx)(j.Icon,{name:"check_circle",size:14,className:"text-success"}),"fail"===g&&(0,b.jsx)(j.Icon,{name:"cancel",size:14,className:"text-danger"}),"testing"===g&&(0,b.jsx)(j.Icon,{name:"progress_activity",size:14,className:"text-text-subtle"})]},c+d)})})},a.alias))}),z&&(0,b.jsx)(k.ConfirmModal,{title:"Remove combo",message:`Delete "${z}"? CLI tools using this alias will stop working.`,confirmLabel:"Remove",busy:t===z,onCancel:()=>A(null),onConfirm:()=>{E(z).then(()=>A(null))}})]})}])}];
2
+
3
+ //# sourceMappingURL=src_components_12gk6sc._.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/ModelPicker.tsx","../../../../src/components/Lamp.tsx","../../../../src/components/RoutingView.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","/** Status lamp — green when serving, red pulse on cooldown, grey when idle. */\nexport function Lamp({ state, title }: { state: \"live\" | \"idle\" | \"down\"; title?: string }) {\n return <span className={`lamp lamp-${state}`} title={title} aria-label={state} />;\n}\n\nexport function lampFor(healthy: boolean): \"live\" | \"down\" {\n return healthy ? \"live\" : \"down\";\n}\n","\"use client\";\n\nimport { useEffect, useState, useCallback } from \"react\";\nimport { adminApi } from \"@/lib/client\";\nimport { Lamp } from \"@/components/Lamp\";\nimport { Badge } from \"@/components/Badge\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { Button, Input, Select, Field } from \"@/components/Button\";\nimport { ModelPicker, type ModelGroup } from \"@/components/ModelPicker\";\nimport { Icon } from \"@/components/Icon\";\nimport { ConfirmModal } from \"@/components/ConfirmModal\";\nimport { fmt, Empty } from \"@/components/ui\";\nimport type { MaskedConfig, MaskedRoute, ProviderSnapshot } from \"@/lib/gateway\";\n\n/** Upstream model id for the i-th target of a route (mirrors GatewayConfig). */\nfunction modelFor(route: MaskedRoute, i: number): string {\n if (Array.isArray(route.model)) return route.model[i] ?? route.model[0] ?? route.alias;\n if (typeof route.model === \"string\") return route.model;\n return route.alias;\n}\n\nexport function RoutingView() {\n const [config, setConfig] = useState<MaskedConfig | null>(null);\n const [health, setHealth] = useState<ProviderSnapshot[]>([]);\n const [error, setError] = useState(\"\");\n const [adding, setAdding] = useState(false);\n const [busy, setBusy] = useState(\"\");\n const [chainTest, setChainTest] = useState<Record<string, Record<number, \"testing\" | \"ok\" | \"fail\">>>({});\n const [chainBusy, setChainBusy] = useState<string | null>(null);\n const [pendingDelete, setPendingDelete] = useState<string | null>(null);\n const [editing, setEditing] = useState<MaskedRoute | null>(null);\n\n const reload = useCallback(async () => {\n const [cfgRes, prov] = await Promise.all([fetch(\"/api/gw/admin/config\"), adminApi.providers()]);\n if (!cfgRes.ok) {\n setError(\"could not reach the gateway\");\n return;\n }\n setError(\"\");\n setConfig((await cfgRes.json()) as MaskedConfig);\n setHealth(prov.data?.providers ?? []);\n }, []);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!config) return <Empty>Loading…</Empty>;\n\n const healthy = (pid: string) => {\n const h = health.find((x) => x.id === pid);\n return h ? h.keys.some((k) => k.healthy) : true;\n };\n\n async function del(alias: string) {\n setBusy(alias);\n const r = await adminApi.removeRoute(alias);\n setBusy(\"\");\n if (!r.ok) setError(r.error ?? \"failed\");\n else await reload();\n }\n\n async function testChain(route: MaskedRoute) {\n setChainBusy(route.alias);\n setChainTest((prev) => ({ ...prev, [route.alias]: {} }));\n for (let i = 0; i < route.target.length; i++) {\n setChainTest((prev) => ({ ...prev, [route.alias]: { ...prev[route.alias], [i]: \"testing\" } }));\n const r = await adminApi.testProvider(route.target[i]!);\n const ok = r.ok && r.data?.ok;\n setChainTest((prev) => ({ ...prev, [route.alias]: { ...prev[route.alias], [i]: ok ? \"ok\" : \"fail\" } }));\n if (i < route.target.length - 1) await new Promise((resolve) => setTimeout(resolve, 400));\n }\n setChainBusy(null);\n }\n\n return (\n <div>\n <div className=\"mb-5 flex items-center justify-between gap-3\">\n <div>\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Combos &amp; Routing</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">\n A combo is an alias your CLI tool calls, routed to a chain of providers. Fallback tries them in order; round-robin spreads load.\n </p>\n </div>\n <Button onClick={() => setAdding((v) => !v)}>\n <Icon name={adding ? \"close\" : \"add\"} size={17} />\n {adding ? \"Cancel\" : \"Add combo\"}\n </Button>\n </div>\n\n {adding && (\n <RouteForm\n providers={config.providers.filter((p) => !p.disabled)}\n onDone={() => { setAdding(false); void reload(); }}\n />\n )}\n\n {editing && !adding && (\n <RouteForm\n providers={config.providers.filter((p) => !p.disabled)}\n initial={editing}\n onDone={() => { setEditing(null); void reload(); }}\n onCancel={() => setEditing(null)}\n />\n )}\n\n {config.models.length === 0 ? (\n <Empty>No combos yet. Add one to expose a model alias to your CLI tools.</Empty>\n ) : (\n <div className=\"grid gap-3 lg:grid-cols-2\">\n {config.models.map((route) => (\n <RichCard\n key={route.alias}\n header={\n <>\n <CardTitle title={route.alias} sub={`${route.target.length} in chain`} />\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => testChain(route)}\n disabled={chainBusy === route.alias}\n className=\"flex items-center gap-1 rounded px-2 py-1 text-[11px] text-text-subtle transition-colors hover:bg-surface-2 hover:text-text disabled:opacity-60\"\n title=\"Test each provider in this chain\"\n >\n <Icon name={chainBusy === route.alias ? \"progress_activity\" : \"sync\"} size={14} />\n Test\n </button>\n <Badge tone={route.strategy === \"round-robin\" ? \"info\" : \"neutral\"}>{route.strategy}</Badge>\n {(route.price_in !== undefined || route.price_out !== undefined) && (\n <Badge tone=\"neutral\">\n {fmt.cost(route.price_in ?? 0)}/{fmt.cost(route.price_out ?? 0)} per 1M\n </Badge>\n )}\n <button onClick={() => setEditing(route)} className=\"text-text-subtle hover:text-text\" aria-label=\"Edit combo\">\n <Icon name=\"edit\" size={16} />\n </button>\n <button onClick={() => setPendingDelete(route.alias)} disabled={busy === route.alias} className=\"text-text-subtle hover:text-danger\" aria-label=\"Remove alias\">\n <Icon name=\"delete\" size={16} />\n </button>\n </div>\n </>\n }\n >\n <ol className=\"space-y-1.5\">\n {route.target.map((pid, i) => {\n const ct = chainTest[route.alias]?.[i];\n const testLamp = ct === \"ok\" ? \"live\" : ct === \"fail\" ? \"down\" : ct === \"testing\" ? \"idle\" : null;\n return (\n <li key={pid + i} className=\"flex items-center gap-2.5 rounded-brand border border-border-subtle px-3 py-2\">\n <span className=\"tnum text-[11px] text-text-subtle\">{i === 0 ? \"primary\" : `#${i + 1}`}</span>\n <Lamp state={testLamp ?? (healthy(pid) ? \"live\" : \"down\")} />\n <span className=\"text-[13px] text-text\">{pid}</span>\n <span className=\"ml-auto tnum text-[12px] text-text-muted\">{modelFor(route, i)}</span>\n {ct === \"ok\" && <Icon name=\"check_circle\" size={14} className=\"text-success\" />}\n {ct === \"fail\" && <Icon name=\"cancel\" size={14} className=\"text-danger\" />}\n {ct === \"testing\" && <Icon name=\"progress_activity\" size={14} className=\"text-text-subtle\" />}\n </li>\n );\n })}\n </ol>\n </RichCard>\n ))}\n </div>\n )}\n\n {pendingDelete && (\n <ConfirmModal\n title=\"Remove combo\"\n message={`Delete \"${pendingDelete}\"? CLI tools using this alias will stop working.`}\n confirmLabel=\"Remove\"\n busy={busy === pendingDelete}\n onCancel={() => setPendingDelete(null)}\n onConfirm={() => {\n void del(pendingDelete).then(() => setPendingDelete(null));\n }}\n />\n )}\n </div>\n );\n}\n\n// Combo create form, for aigetwey's ComboFormModal: a name + ONE ordered\n// list of concrete `provider/model` entries (fallback priority), picked from the\n// providers' catalogs. On save each entry splits into target[i]/model[i].\ntype ProviderOption = { id: string; models: { id: string }[] };\n\nfunction RouteForm({ providers, onDone, initial, onCancel }: { providers: ProviderOption[]; onDone: () => void; initial?: MaskedRoute; onCancel?: () => void }) {\n const isEdit = !!initial;\n const [alias, setAlias] = useState(initial?.alias ?? \"\");\n const [entries, setEntries] = useState<string[]>(() => {\n if (!initial) return [];\n return initial.target.map((pid, i) => {\n const m = Array.isArray(initial.model) ? initial.model[i] ?? initial.model[0] : initial.model ?? initial.alias;\n return `${pid}/${m}`;\n });\n });\n const [pickerOpen, setPickerOpen] = useState(false);\n const [strategy, setStrategy] = useState<\"fallback\" | \"round-robin\">(initial?.strategy ?? \"fallback\");\n const [priceIn, setPriceIn] = useState(initial?.price_in?.toString() ?? \"\");\n const [priceOut, setPriceOut] = useState(initial?.price_out?.toString() ?? \"\");\n const [busy, setBusy] = useState(false);\n const [err, setErr] = useState(\"\");\n const [dragIdx, setDragIdx] = useState<number | null>(null);\n\n // aigetwey-style picker: provider-grouped, click a model to add/remove it.\n const groups: ModelGroup[] = providers\n .filter((p) => p.models.length > 0)\n .map((p) => ({ label: p.id, items: p.models.map((m) => ({ value: `${p.id}/${m.id}`, label: `${p.id}/${m.id}` })) }));\n\n function toggle(v: string) {\n setErr(\"\");\n setEntries((e) => (e.includes(v) ? e.filter((x) => x !== v) : [...e, v]));\n }\n\n // reorder fallback priority: dropping entry #from onto slot #to\n function move(from: number, to: number) {\n setEntries((e) => {\n const next = [...e];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n return next;\n });\n }\n\n async function submit(e: React.FormEvent) {\n e.preventDefault();\n if (!alias || entries.length === 0) {\n setErr(\"a name and at least one model are required\");\n return;\n }\n setBusy(true);\n setErr(\"\");\n const target = entries.map((x) => x.slice(0, x.indexOf(\"/\")));\n const model = entries.map((x) => x.slice(x.indexOf(\"/\") + 1));\n const r = await adminApi.setRoute(alias, {\n target,\n model,\n strategy,\n price_in: priceIn ? Number(priceIn) : undefined,\n price_out: priceOut ? Number(priceOut) : undefined,\n });\n // rename: the new alias is saved above; drop the old one so it doesn't linger.\n if (r.ok && isEdit && initial!.alias !== alias) {\n await adminApi.removeRoute(initial!.alias);\n }\n setBusy(false);\n if (r.ok) onDone();\n else setErr(r.error ?? \"failed\");\n }\n\n return (\n <form onSubmit={submit} className=\"mb-5 rounded-brand-lg border border-border bg-surface p-4 shadow-soft\">\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <Field label=\"Alias\" hint=\"the name your CLI requests as a model\">\n <Input value={alias} onChange={(e) => setAlias(e.target.value)} placeholder=\"my-claude\" />\n </Field>\n <Field label=\"Strategy\" hint=\"how the chain is tried\">\n <Select value={strategy} onChange={(e) => setStrategy(e.target.value as \"fallback\" | \"round-robin\")}>\n <option value=\"fallback\">Fallback — try in order, next on failure</option>\n <option value=\"round-robin\">Round Robin — rotate to spread load</option>\n </Select>\n </Field>\n <Field label=\"Price in\" hint=\"per 1M, optional\"><Input value={priceIn} onChange={(e) => setPriceIn(e.target.value)} placeholder=\"3\" /></Field>\n <Field label=\"Price out\" hint=\"per 1M, optional\"><Input value={priceOut} onChange={(e) => setPriceOut(e.target.value)} placeholder=\"15\" /></Field>\n </div>\n\n <div className=\"mt-3\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">\n Models — fallback order (drag to reorder)\n </span>\n <Button type=\"button\" variant=\"ghost\" onClick={() => setPickerOpen(true)}>\n <Icon name=\"add\" size={16} /> Add models\n </Button>\n </div>\n\n {entries.length === 0 ? (\n <div className=\"mt-2 rounded-brand border border-dashed border-border-subtle px-3 py-4 text-center text-[12px] text-text-subtle\">\n No models yet. Click <span className=\"text-text-muted\">Add models</span> and pick from your providers.\n </div>\n ) : (\n <ul className=\"mt-2 space-y-1.5\">\n {entries.map((entry, i) => (\n <li\n key={entry}\n draggable\n onDragStart={() => setDragIdx(i)}\n onDragOver={(e) => e.preventDefault()}\n onDrop={() => {\n if (dragIdx !== null && dragIdx !== i) move(dragIdx, i);\n setDragIdx(null);\n }}\n onDragEnd={() => setDragIdx(null)}\n className={`flex cursor-grab items-center gap-2.5 rounded-brand border px-3 py-2 active:cursor-grabbing ${\n dragIdx === i ? \"border-accent bg-accent-soft\" : \"border-border-subtle\"\n }`}\n >\n <Icon name=\"drag_indicator\" size={16} className=\"text-text-subtle\" />\n <span className=\"tnum text-[11px] text-text-subtle\">{i === 0 ? \"primary\" : `#${i + 1}`}</span>\n <span className=\"tnum truncate text-[13px] text-text\">{entry}</span>\n <button\n type=\"button\"\n onClick={() => setEntries((e) => e.filter((_, idx) => idx !== i))}\n className=\"ml-auto flex-none text-text-subtle hover:text-danger\"\n aria-label={`Remove ${entry}`}\n >\n <Icon name=\"close\" size={14} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n\n {err && <div className=\"mt-2 text-[12px] text-danger\">{err}</div>}\n <div className=\"mt-3 flex justify-end gap-2\">\n {onCancel && <Button type=\"button\" variant=\"ghost\" onClick={onCancel}>Cancel</Button>}\n <Button type=\"submit\" disabled={busy}>{busy ? \"Saving…\" : isEdit ? \"Update combo\" : \"Save combo\"}</Button>\n </div>\n\n {pickerOpen && (\n <ModelPicker\n title=\"Add models to the chain\"\n note=\"Click a model to add it, click again to remove. Drag to reorder after.\"\n groups={groups}\n selected={entries}\n onToggle={toggle}\n onClose={() => setPickerOpen(false)}\n />\n )}\n </form>\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","Lamp","state","lampFor","healthy","modelFor","route","Array","isArray","alias","RoutingView","config","setConfig","health","setHealth","error","setError","adding","setAdding","busy","setBusy","chainTest","setChainTest","chainBusy","setChainBusy","pendingDelete","setPendingDelete","editing","setEditing","reload","cfgRes","prov","Promise","all","fetch","providers","ok","json","data","pid","h","find","x","id","keys","some","k","del","r","removeRoute","testChain","prev","testProvider","resolve","setTimeout","v","RouteForm","p","disabled","onDone","initial","onCancel","models","header","sub","tone","strategy","price_in","undefined","price_out","cost","ct","testLamp","message","confirmLabel","onConfirm","then","isEdit","setAlias","entries","setEntries","m","pickerOpen","setPickerOpen","setStrategy","priceIn","setPriceIn","toString","priceOut","setPriceOut","err","setErr","dragIdx","setDragIdx","toggle","move","from","to","next","moved","splice","submit","preventDefault","slice","indexOf","setRoute","Number","onSubmit","hint","variant","entry","draggable","onDragStart","onDragOver","onDrop","onDragEnd","_","idx"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ module.exports=[2693,a=>{"use strict";var b=a.i(87924);let c={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 d({tone:a="neutral",children:e,className:f}){return(0,b.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${c[a]}${f?` ${f}`:""}`,children:e})}a.s(["Badge",0,d,"FormatBadge",0,function({format:a}){return(0,b.jsx)(d,{tone:"info",children:a})}])},58918,a=>{"use strict";var b=a.i(87924);a.s(["Empty",0,function({children:a}){return(0,b.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:a})},"Stat",0,function({label:a,value:c,sub:d}){return(0,b.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,b.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:c}),d&&(0,b.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:d})]})},"fmt",0,{int:a=>a.toLocaleString("en-US"),compact:a=>Math.abs(a)>=1e6?`${(a/1e6).toFixed(1)}M`:Math.abs(a)>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a)),cost:a=>0===a?"$0":a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`,time:a=>new Date(a).toLocaleString("en-US",{hour12:!1}),date(a){let b=new Date(a);return`${String(b.getDate()).padStart(2,"0")}/${String(b.getMonth()+1).padStart(2,"0")}/${b.getFullYear()}`},ago(a){let b=Math.max(0,Math.round((Date.now()-a)/1e3));return b<60?`${b}s`:b<3600?`${Math.floor(b/60)}m`:b<86400?`${Math.floor(b/3600)}h`:`${Math.floor(b/86400)}d`},duration(a){let b=Math.max(0,Math.round(a/1e3));if(b<60)return`${b}s`;if(b<3600)return`${Math.floor(b/60)}m ${b%60}s`;let c=Math.floor(b/3600),d=Math.floor(b%3600/60);if(c<24)return`${c}h ${d}m`;let e=Math.floor(c/24);return`${e}d ${c%24}h`}}])},85732,a=>{"use strict";var b=a.i(87924);a.s(["CardTitle",0,function({title:a,sub:c,icon:d}){return(0,b.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[d,(0,b.jsxs)("div",{className:"min-w-0",children:[(0,b.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:a}),c&&(0,b.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:c})]})]})},"RichCard",0,function({header:a,footer:c,children:d,className:e}){return(0,b.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${e?` ${e}`:""}`,children:[a&&(0,b.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:a}),(0,b.jsx)("div",{className:"p-4",children:d}),c&&(0,b.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:c})]})}])}];
2
+
3
+ //# sourceMappingURL=src_components_17nnhsa._.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/Badge.tsx","../../../../src/components/ui.tsx","../../../../src/components/RichCard.tsx"],"sourcesContent":["type Tone = \"live\" | \"down\" | \"warn\" | \"info\" | \"neutral\";\n\nconst TONES: Record<Tone, string> = {\n live: \"bg-success/12 text-success\",\n down: \"bg-danger/12 text-danger\",\n warn: \"bg-warning/12 text-warning\",\n info: \"bg-info/12 text-info\",\n neutral: \"bg-surface-2 text-text-muted\",\n};\n\nexport function Badge({\n tone = \"neutral\",\n children,\n className,\n}: {\n tone?: Tone;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${TONES[tone]}${className ? ` ${className}` : \"\"}`}\n >\n {children}\n </span>\n );\n}\n\n/** Format badge for a provider's wire format. */\nexport function FormatBadge({ format }: { format: \"openai\" | \"anthropic\" | \"gemini\" }) {\n return <Badge tone=\"info\">{format}</Badge>;\n}\n","/** Small formatting helpers shared across the console. */\nexport const fmt = {\n int(n: number): string {\n return n.toLocaleString(\"en-US\");\n },\n /** compact number: 1.2K, 3.4M */\n compact(n: number): string {\n if (Math.abs(n) >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (Math.abs(n) >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return String(Math.round(n));\n },\n cost(n: number): string {\n if (n === 0) return \"$0\";\n return n < 0.01 ? `$${n.toFixed(4)}` : `$${n.toFixed(2)}`;\n },\n time(ts: number): string {\n return new Date(ts).toLocaleString(\"en-US\", { hour12: false });\n },\n /** DD/MM/YYYY (local) */\n date(ts: number): string {\n const d = new Date(ts);\n return `${String(d.getDate()).padStart(2, \"0\")}/${String(d.getMonth() + 1).padStart(2, \"0\")}/${d.getFullYear()}`;\n },\n /** \"3m\", \"2h\", \"5d\" — coarse relative age */\n ago(ts: number): string {\n const s = Math.max(0, Math.round((Date.now() - ts) / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n if (s < 86400) return `${Math.floor(s / 3600)}h`;\n return `${Math.floor(s / 86400)}d`;\n },\n /** ms duration -> \"Xs\", \"Xm Ys\", \"Xh Ym\" for budget/cooldown countdowns */\n duration(ms: number): string {\n const s = Math.max(0, Math.round(ms / 1000));\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`;\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n if (h < 24) return `${h}h ${m}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n },\n};\n\n/** A labelled stat block — number over a caption. */\nexport function Stat({ label, value, sub }: { label: string; value: React.ReactNode; sub?: string }) {\n return (\n <div className=\"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft\">\n <div className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">{label}</div>\n <div className=\"mt-1 tnum text-[22px] font-semibold tracking-tight text-text\">{value}</div>\n {sub && <div className=\"mt-0.5 text-[12px] text-text-muted\">{sub}</div>}\n </div>\n );\n}\n\n/** Empty-state hint inside a card body. */\nexport function Empty({ children }: { children: React.ReactNode }) {\n return <div className=\"px-1 py-8 text-center text-[13px] text-text-muted\">{children}</div>;\n}\n","/**\n * Rich content card — header (title slot + trailing slot), body, optional footer.\n * Softly rounded, subtle border, warm surface. The Haulix-style workhorse.\n */\nexport function RichCard({\n header,\n footer,\n children,\n className,\n}: {\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <section\n className={`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${className ? ` ${className}` : \"\"}`}\n >\n {header && (\n <header className=\"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3\">\n {header}\n </header>\n )}\n <div className=\"p-4\">{children}</div>\n {footer && (\n <footer className=\"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5\">\n {footer}\n </footer>\n )}\n </section>\n );\n}\n\n/** Title + optional subtitle, for the header slot. */\nexport function CardTitle({ title, sub, icon }: { title: string; sub?: string; icon?: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2.5 min-w-0\">\n {icon}\n <div className=\"min-w-0\">\n <div className=\"truncate text-[14px] font-semibold tracking-tight text-text\">{title}</div>\n {sub && <div className=\"truncate text-[12px] text-text-muted\">{sub}</div>}\n </div>\n </div>\n );\n}\n"],"names":["TONES","live","down","warn","info","neutral","Badge","tone","children","className","FormatBadge","format","fmt","int","n","toLocaleString","compact","Math","abs","toFixed","String","round","cost","time","ts","Date","hour12","date","d","getDate","padStart","getMonth","getFullYear","ago","s","max","now","floor","duration","ms","h","m","Stat","label","value","sub","Empty","RichCard","header","footer","CardTitle","title","icon"],"mappings":"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"}
@@ -0,0 +1,3 @@
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"})]})]})})}])},2799,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(93026),e=a.i(58918);a.s(["CooldownTimer",0,function({ms:a,tone:f="danger",icon:g="timer",keepZero:h=!1}){let[i]=(0,c.useState)(()=>Date.now()+a),[j,k]=(0,c.useState)(()=>Math.max(0,a));return((0,c.useEffect)(()=>{let a=()=>k(Math.max(0,i-Date.now()));a();let b=setInterval(a,1e3);return()=>clearInterval(b)},[i]),j<=0&&!h)?null:(0,b.jsxs)("span",{className:`inline-flex items-center gap-1 tnum text-[12px] ${"danger"===f?"text-danger":"text-text-muted"}`,children:[(0,b.jsx)(d.Icon,{name:g,size:13}),j<=0?"now":e.fmt.duration(j)]})}])}];
2
+
3
+ //# sourceMappingURL=src_components_1kc5vh2._.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/ModelPicker.tsx","../../../../src/components/CooldownTimer.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","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Icon } from \"./Icon\";\nimport { fmt } from \"./ui\";\n\n/**\n * Live countdown from a gateway-snapshot remaining-ms. Counts down locally each\n * second from render. Used for both key cooldowns (danger tone) and budget window\n * resets (muted tone). Renders nothing once it hits zero unless `keepZero`.\n */\nexport function CooldownTimer({\n ms,\n tone = \"danger\",\n icon = \"timer\",\n keepZero = false,\n}: {\n ms: number;\n tone?: \"danger\" | \"muted\";\n icon?: string;\n keepZero?: boolean;\n}) {\n const [until] = useState(() => Date.now() + ms);\n const [remaining, setRemaining] = useState(() => Math.max(0, ms));\n\n useEffect(() => {\n const tick = () => setRemaining(Math.max(0, until - Date.now()));\n tick();\n const id = setInterval(tick, 1000);\n return () => clearInterval(id);\n }, [until]);\n\n if (remaining <= 0 && !keepZero) return null;\n\n const color = tone === \"danger\" ? \"text-danger\" : \"text-text-muted\";\n return (\n <span className={`inline-flex items-center gap-1 tnum text-[12px] ${color}`}>\n <Icon name={icon} size={13} />\n {remaining <= 0 ? \"now\" : fmt.duration(remaining)}\n </span>\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","CooldownTimer","ms","tone","icon","keepZero","until","Date","now","remaining","setRemaining","Math","max","tick","id","setInterval","clearInterval","color","duration"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ module.exports=[2693,a=>{"use strict";var b=a.i(87924);let c={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 d({tone:a="neutral",children:e,className:f}){return(0,b.jsx)("span",{className:`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium ${c[a]}${f?` ${f}`:""}`,children:e})}a.s(["Badge",0,d,"FormatBadge",0,function({format:a}){return(0,b.jsx)(d,{tone:"info",children:a})}])},58918,a=>{"use strict";var b=a.i(87924);a.s(["Empty",0,function({children:a}){return(0,b.jsx)("div",{className:"px-1 py-8 text-center text-[13px] text-text-muted",children:a})},"Stat",0,function({label:a,value:c,sub:d}){return(0,b.jsxs)("div",{className:"rounded-brand-lg border border-border bg-surface px-4 py-3.5 shadow-soft",children:[(0,b.jsx)("div",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"mt-1 tnum text-[22px] font-semibold tracking-tight text-text",children:c}),d&&(0,b.jsx)("div",{className:"mt-0.5 text-[12px] text-text-muted",children:d})]})},"fmt",0,{int:a=>a.toLocaleString("en-US"),compact:a=>Math.abs(a)>=1e6?`${(a/1e6).toFixed(1)}M`:Math.abs(a)>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a)),cost:a=>0===a?"$0":a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`,time:a=>new Date(a).toLocaleString("en-US",{hour12:!1}),date(a){let b=new Date(a);return`${String(b.getDate()).padStart(2,"0")}/${String(b.getMonth()+1).padStart(2,"0")}/${b.getFullYear()}`},ago(a){let b=Math.max(0,Math.round((Date.now()-a)/1e3));return b<60?`${b}s`:b<3600?`${Math.floor(b/60)}m`:b<86400?`${Math.floor(b/3600)}h`:`${Math.floor(b/86400)}d`},duration(a){let b=Math.max(0,Math.round(a/1e3));if(b<60)return`${b}s`;if(b<3600)return`${Math.floor(b/60)}m ${b%60}s`;let c=Math.floor(b/3600),d=Math.floor(b%3600/60);if(c<24)return`${c}h ${d}m`;let e=Math.floor(c/24);return`${e}d ${c%24}h`}}])},85732,a=>{"use strict";var b=a.i(87924);a.s(["CardTitle",0,function({title:a,sub:c,icon:d}){return(0,b.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0",children:[d,(0,b.jsxs)("div",{className:"min-w-0",children:[(0,b.jsx)("div",{className:"truncate text-[14px] font-semibold tracking-tight text-text",children:a}),c&&(0,b.jsx)("div",{className:"truncate text-[12px] text-text-muted",children:c})]})]})},"RichCard",0,function({header:a,footer:c,children:d,className:e}){return(0,b.jsxs)("section",{className:`overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft${e?` ${e}`:""}`,children:[a&&(0,b.jsx)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:a}),(0,b.jsx)("div",{className:"p-4",children:d}),c&&(0,b.jsx)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:c})]})}])},52065,55690,a=>{"use strict";var b=a.i(87924);function c(a,b){return RegExp("^"+a.split("*").map(a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i").test(b)}let d={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},e={"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}},f={"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}}},g=[{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 h(a,b){if(!b)return{...d};if(a&&f[a]?.[b])return{...d,...f[a][b]};let h=(b.includes("/")?b.split("/").pop():b)??b;if(e[h])return{...d,...e[h]};if(e[b])return{...d,...e[b]};for(let{pattern:a,caps:e}of g)if(c(a,h)||c(a,b))return{...d,...e};return{...d}}a.s(["getCapabilitiesForModel",0,h,"modalitiesForModel",0,function(a){let b=a.indexOf("/"),c=h(b>0?a.slice(0,b):null,b>0?a.slice(b+1):a),d=["text"];c.vision&&d.push("image"),c.pdf&&d.push("pdf"),c.audioInput&&d.push("audio"),c.videoInput&&d.push("video");let e=["text"];return c.imageOutput&&e.push("image"),c.audioOutput&&e.push("audio"),{input:d,output:e}}],55690);var i=a.i(93026);let j={vision:{icon:"visibility",label:"Vision",desc:"Supports image input",color:"text-info"},reasoning:{icon:"neurology",label:"Reasoning",desc:"Supports reasoning / thinking",color:"text-warning"}};a.s(["CapacityBadges",0,function({model:a,provider:c=null,size:d=15,className:e=""}){let f=h(c,a),g=Object.keys(j).filter(a=>f[a]);return 0===g.length?null:(0,b.jsx)("span",{className:`inline-flex flex-none items-center gap-0.5 ${e}`,children:g.map(a=>(0,b.jsx)("span",{title:`${j[a].label} — ${j[a].desc}`,className:"leading-none",children:(0,b.jsx)(i.Icon,{name:j[a].icon,size:d,className:j[a].color})},a))})}],52065)}];
2
+
3
+ //# sourceMappingURL=src_components_1zwow63._.js.map