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.
- package/CHANGELOG.md +23 -0
- package/dashboard/.next/BUILD_ID +1 -0
- package/dashboard/.next/app-path-routes-manifest.json +22 -0
- package/dashboard/.next/build/56416d4ae4ce586f.js +6 -0
- package/dashboard/.next/build/56416d4ae4ce586f.js.map +5 -0
- package/dashboard/.next/build/chunks/[root-of-the-server]__0oj80bi._.js +206 -0
- package/dashboard/.next/build/chunks/[root-of-the-server]__0oj80bi._.js.map +8 -0
- package/dashboard/.next/build/chunks/[root-of-the-server]__1f933tp._.js +500 -0
- package/dashboard/.next/build/chunks/[root-of-the-server]__1f933tp._.js.map +11 -0
- package/dashboard/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js +13 -0
- package/dashboard/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_0b7xl6g._.js.map +5 -0
- package/dashboard/.next/build/chunks/[turbopack]_runtime.js +890 -0
- package/dashboard/.next/build/chunks/[turbopack]_runtime.js.map +11 -0
- package/dashboard/.next/build/chunks/node_modules_20v-8wl._.js +6824 -0
- package/dashboard/.next/build/chunks/node_modules_20v-8wl._.js.map +47 -0
- package/dashboard/.next/build/package.json +1 -0
- package/dashboard/.next/build-manifest.json +22 -0
- package/dashboard/.next/cache/.previewinfo +1 -0
- package/dashboard/.next/cache/.rscinfo +1 -0
- package/dashboard/.next/diagnostics/build-diagnostics.json +6 -0
- package/dashboard/.next/diagnostics/framework.json +1 -0
- package/dashboard/.next/diagnostics/route-bundle-stats.json +208 -0
- package/dashboard/.next/export-marker.json +6 -0
- package/dashboard/.next/fallback-build-manifest.json +13 -0
- package/dashboard/.next/images-manifest.json +68 -0
- package/dashboard/.next/next-minimal-server.js.nft.json +1 -0
- package/dashboard/.next/next-server.js.nft.json +1 -0
- package/dashboard/.next/package.json +1 -0
- package/dashboard/.next/prerender-manifest.json +306 -0
- package/dashboard/.next/required-server-files.js +337 -0
- package/dashboard/.next/required-server-files.json +337 -0
- package/dashboard/.next/routes-manifest.json +174 -0
- package/dashboard/.next/server/app/(console)/combos/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/combos/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/combos/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/combos/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/combos/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/combos/page.js +15 -0
- package/dashboard/.next/server/app/(console)/combos/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/combos/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/combos/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/config/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/config/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/config/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/config/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/config/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/config/page.js +15 -0
- package/dashboard/.next/server/app/(console)/config/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/config/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/config/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/console/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/console/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/console/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/console/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/console/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/console/page.js +15 -0
- package/dashboard/.next/server/app/(console)/console/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/console/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/console/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/endpoint/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/endpoint/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/endpoint/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/endpoint/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/endpoint/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/endpoint/page.js +15 -0
- package/dashboard/.next/server/app/(console)/endpoint/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/endpoint/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/endpoint/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/page.js +15 -0
- package/dashboard/.next/server/app/(console)/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page.js +15 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/providers/[id]/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/providers/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/providers/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/providers/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/providers/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/providers/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/providers/page.js +15 -0
- package/dashboard/.next/server/app/(console)/providers/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/providers/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/providers/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/quota/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/quota/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/quota/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/quota/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/quota/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/quota/page.js +15 -0
- package/dashboard/.next/server/app/(console)/quota/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/quota/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/quota/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page.js +15 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/tools/[id]/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/tools/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/tools/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/tools/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/tools/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/tools/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/tools/page.js +15 -0
- package/dashboard/.next/server/app/(console)/tools/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/tools/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/tools/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/(console)/usage/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/(console)/usage/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/(console)/usage/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/(console)/usage/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/(console)/usage/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/(console)/usage/page.js +16 -0
- package/dashboard/.next/server/app/(console)/usage/page.js.map +5 -0
- package/dashboard/.next/server/app/(console)/usage/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/(console)/usage/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/_global-error/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
- package/dashboard/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/_global-error/page.js +9 -0
- package/dashboard/.next/server/app/_global-error/page.js.map +5 -0
- package/dashboard/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/_global-error.html +1 -0
- package/dashboard/.next/server/app/_global-error.meta +15 -0
- package/dashboard/.next/server/app/_global-error.rsc +14 -0
- package/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
- package/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
- package/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
- package/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/dashboard/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/_not-found/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/_not-found/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/_not-found/page.js +13 -0
- package/dashboard/.next/server/app/_not-found/page.js.map +5 -0
- package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/_not-found.html +1 -0
- package/dashboard/.next/server/app/_not-found.meta +16 -0
- package/dashboard/.next/server/app/_not-found.rsc +20 -0
- package/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +20 -0
- package/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
- package/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
- package/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js +7 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js.map +5 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/cli-detect/[tool]/route_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route.js +7 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route.js.map +5 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/gw/[...path]/route_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/api/login/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/api/login/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/api/login/route/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/api/login/route.js +7 -0
- package/dashboard/.next/server/app/api/login/route.js.map +5 -0
- package/dashboard/.next/server/app/api/login/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/login/route_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/api/logout/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/api/logout/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/api/logout/route/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/api/logout/route.js +7 -0
- package/dashboard/.next/server/app/api/logout/route.js.map +5 -0
- package/dashboard/.next/server/app/api/logout/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/logout/route_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/api/password/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/api/password/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/api/password/route/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/api/password/route.js +7 -0
- package/dashboard/.next/server/app/api/password/route.js.map +5 -0
- package/dashboard/.next/server/app/api/password/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/password/route_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/combos.html +1 -0
- package/dashboard/.next/server/app/combos.meta +16 -0
- package/dashboard/.next/server/app/combos.rsc +25 -0
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos.segment.rsc +5 -0
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/combos.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/combos.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/combos.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/combos.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/config.html +1 -0
- package/dashboard/.next/server/app/config.meta +16 -0
- package/dashboard/.next/server/app/config.rsc +25 -0
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config.segment.rsc +5 -0
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/config.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/config.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/config.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/config.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/console.html +1 -0
- package/dashboard/.next/server/app/console.meta +16 -0
- package/dashboard/.next/server/app/console.rsc +28 -0
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console/__PAGE__.segment.rsc +9 -0
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console.segment.rsc +5 -0
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/console.segments/_full.segment.rsc +28 -0
- package/dashboard/.next/server/app/console.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/console.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/console.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/endpoint.html +1 -0
- package/dashboard/.next/server/app/endpoint.meta +16 -0
- package/dashboard/.next/server/app/endpoint.rsc +25 -0
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint.segment.rsc +5 -0
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/endpoint.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/endpoint.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/endpoint.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/endpoint.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/icon.svg/route/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/icon.svg/route/build-manifest.json +9 -0
- package/dashboard/.next/server/app/icon.svg/route.js +6 -0
- package/dashboard/.next/server/app/icon.svg/route.js.map +5 -0
- package/dashboard/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/icon.svg.body +8 -0
- package/dashboard/.next/server/app/icon.svg.meta +1 -0
- package/dashboard/.next/server/app/index.html +1 -0
- package/dashboard/.next/server/app/index.meta +15 -0
- package/dashboard/.next/server/app/index.rsc +23 -0
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/index.segments/_full.segment.rsc +23 -0
- package/dashboard/.next/server/app/index.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/index.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/index.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/login/page/app-paths-manifest.json +3 -0
- package/dashboard/.next/server/app/login/page/build-manifest.json +18 -0
- package/dashboard/.next/server/app/login/page/next-font-manifest.json +11 -0
- package/dashboard/.next/server/app/login/page/react-loadable-manifest.json +1 -0
- package/dashboard/.next/server/app/login/page/server-reference-manifest.json +4 -0
- package/dashboard/.next/server/app/login/page.js +14 -0
- package/dashboard/.next/server/app/login/page.js.map +5 -0
- package/dashboard/.next/server/app/login/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/login/page_client-reference-manifest.js +3 -0
- package/dashboard/.next/server/app/login.html +1 -0
- package/dashboard/.next/server/app/login.meta +15 -0
- package/dashboard/.next/server/app/login.rsc +26 -0
- package/dashboard/.next/server/app/login.segments/_full.segment.rsc +26 -0
- package/dashboard/.next/server/app/login.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/login.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/login.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/login.segments/login/__PAGE__.segment.rsc +9 -0
- package/dashboard/.next/server/app/login.segments/login.segment.rsc +5 -0
- package/dashboard/.next/server/app/providers.html +1 -0
- package/dashboard/.next/server/app/providers.meta +16 -0
- package/dashboard/.next/server/app/providers.rsc +25 -0
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers.segment.rsc +5 -0
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/providers.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/providers.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/providers.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/providers.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/quota.html +1 -0
- package/dashboard/.next/server/app/quota.meta +16 -0
- package/dashboard/.next/server/app/quota.rsc +25 -0
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota.segment.rsc +5 -0
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/quota.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/quota.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/quota.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/quota.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app/tools.html +1 -0
- package/dashboard/.next/server/app/tools.meta +16 -0
- package/dashboard/.next/server/app/tools.rsc +25 -0
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools/__PAGE__.segment.rsc +6 -0
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools.segment.rsc +5 -0
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp.segment.rsc +6 -0
- package/dashboard/.next/server/app/tools.segments/_full.segment.rsc +25 -0
- package/dashboard/.next/server/app/tools.segments/_head.segment.rsc +6 -0
- package/dashboard/.next/server/app/tools.segments/_index.segment.rsc +9 -0
- package/dashboard/.next/server/app/tools.segments/_tree.segment.rsc +5 -0
- package/dashboard/.next/server/app-paths-manifest.json +22 -0
- package/dashboard/.next/server/chunks/[externals]__1j91pjf._.js +3 -0
- package/dashboard/.next/server/chunks/[externals]__1j91pjf._.js.map +1 -0
- package/dashboard/.next/server/chunks/[externals]__1v5t_x8._.js +3 -0
- package/dashboard/.next/server/chunks/[externals]__1v5t_x8._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0-6ukjk._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0-6ukjk._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js +20 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__043un18._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__07euc03._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__07euc03._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__082azhr._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__082azhr._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0das32e._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0pp7rn-._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0pp7rn-._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0uqpr_c._.js +3 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0uqpr_c._.js.map +1 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +13 -0
- package/dashboard/.next/server/chunks/[root-of-the-server]__0xuaoik._.js.map +1 -0
- package/dashboard/.next/server/chunks/[turbopack]_runtime.js +903 -0
- package/dashboard/.next/server/chunks/[turbopack]_runtime.js.map +11 -0
- package/dashboard/.next/server/chunks/_0digmky._.js +3 -0
- package/dashboard/.next/server/chunks/_0digmky._.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_cli-detect_[tool]_route_actions_0ffw-gg.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_cli-detect_[tool]_route_actions_0ffw-gg.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_gw_[___path]_route_actions_0ytl4km.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_gw_[___path]_route_actions_0ytl4km.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_login_route_actions_1apjjct.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_login_route_actions_1apjjct.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_logout_route_actions_0gzx3on.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_logout_route_actions_0gzx3on.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_password_route_actions_0xecc0j.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_api_password_route_actions_0xecc0j.js.map +1 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js +3 -0
- package/dashboard/.next/server/chunks/_next-internal_server_app_icon_svg_route_actions_1r2h_ub.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0559wxx._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0559wxx._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09pxn-h._.js +33 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09pxn-h._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0_fihdn._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0_fihdn._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0cx5pj3._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0cx5pj3._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0d-itp1._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0d-itp1._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0dk7lif._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0dk7lif._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0qvkt1y._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0qvkt1y._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0unr06k._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0unr06k._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0x-617o._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0x-617o._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js +27 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__11t16qi._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__11t16qi._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__12q01a8._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__12q01a8._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__179ut8i._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__179ut8i._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js +33 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1inj1w-._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1inj1w-._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1jidl81._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1jidl81._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1mg2t8f._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1mg2t8f._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w2pq2s._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w2pq2s._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w31jjb._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__1w31jjb._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/[turbopack]_runtime.js +903 -0
- package/dashboard/.next/server/chunks/ssr/[turbopack]_runtime.js.map +11 -0
- package/dashboard/.next/server/chunks/ssr/_0g1n0z2._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_0g1n0z2._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_1jt-_lv._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js +6 -0
- package/dashboard/.next/server/chunks/ssr/_1mumvwn._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_combos_page_actions_07o3lus.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_combos_page_actions_07o3lus.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_config_page_actions_1d2383s.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_config_page_actions_1d2383s.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_console_page_actions_0w-3r_g.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_console_page_actions_0w-3r_g.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_endpoint_page_actions_00tzpzh.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_endpoint_page_actions_00tzpzh.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_page_actions_0u8zxvt.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_page_actions_0u8zxvt.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_[id]_page_actions_20yozi-.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_[id]_page_actions_20yozi-.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_page_actions_1bdc8gv.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_providers_page_actions_1bdc8gv.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_quota_page_actions_02l-zu_.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_quota_page_actions_02l-zu_.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_[id]_page_actions_01qi9of.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_[id]_page_actions_01qi9of.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_page_actions_18gis7c.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_tools_page_actions_18gis7c.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_usage_page_actions_1twl-ym.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_(console)_usage_page_actions_1twl-ym.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yr.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_login_page_actions_04fnjo0.js +3 -0
- package/dashboard/.next/server/chunks/ssr/_next-internal_server_app_login_page_actions_04fnjo0.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_1ivn_d-._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_1ivn_d-._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_1iemwhs._.js +6 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_1iemwhs._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js +6 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_0uboya6._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1enzot_._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1enzot_._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1map00z._.js +19 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_1map00z._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0bew68i._.js +33 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0bew68i._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js +3 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_00x0c-2.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_00x0c-2.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_01n345n.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_01n345n.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02jwx28.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02jwx28.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_08g_4le.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_08g_4le.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0_xbpm0.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0tx5zxe.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0tx5zxe.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_15dprgl.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_15dprgl.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18twt8j.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_18twt8j.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1bycsv3.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1bycsv3.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1i1atml.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1i1atml.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1n7v8np.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1n7v8np.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1q72yyr.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1q72yyr.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_20gk3id.js +4 -0
- package/dashboard/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_20gk3id.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_02ocd5c._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_0az41dg._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_0wrskl4._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_0wrskl4._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_app_(console)_console_page_tsx_1g8gnmy._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_app_(console)_console_page_tsx_1g8gnmy._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_0kr-r_t._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_0kr-r_t._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_0nuo5yx._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_11ckzq_._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_12gk6sc._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_17nnhsa._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_1kc5vh2._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_1zwow63._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_BudgetTracker_tsx_1-xevea._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_BudgetTracker_tsx_1-xevea._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_EndpointView_tsx_0awdzb5._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ModelPicker_tsx_1jisxh6._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ProviderDetail_tsx_06sxu0r._.js.map +1 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js +3 -0
- package/dashboard/.next/server/chunks/ssr/src_components_ToolDetail_tsx_0qperd-._.js.map +1 -0
- package/dashboard/.next/server/functions-config-manifest.json +14 -0
- package/dashboard/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/dashboard/.next/server/middleware/middleware-manifest.json +6 -0
- package/dashboard/.next/server/middleware-build-manifest.js +22 -0
- package/dashboard/.next/server/middleware-manifest.json +6 -0
- package/dashboard/.next/server/middleware.js +5 -0
- package/dashboard/.next/server/middleware.js.map +5 -0
- package/dashboard/.next/server/middleware.js.nft.json +1 -0
- package/dashboard/.next/server/next-font-manifest.js +1 -0
- package/dashboard/.next/server/next-font-manifest.json +59 -0
- package/dashboard/.next/server/pages/404.html +1 -0
- package/dashboard/.next/server/pages/500.html +1 -0
- package/dashboard/.next/server/pages-manifest.json +4 -0
- package/dashboard/.next/server/prefetch-hints.json +1 -0
- package/dashboard/.next/server/server-reference-manifest.js +1 -0
- package/dashboard/.next/server/server-reference-manifest.json +5 -0
- package/dashboard/.next/static/chunks/00415cmd3ji2s.js +1 -0
- package/dashboard/.next/static/chunks/05-c3ty_6dwfk.js +1 -0
- package/dashboard/.next/static/chunks/05i93ivai9obr.js +1 -0
- package/dashboard/.next/static/chunks/0_fo_1xhw25rd.js +1 -0
- package/dashboard/.next/static/chunks/0cz1d0mv5g_q7.js +1 -0
- package/dashboard/.next/static/chunks/0mk1g55o6kl1e.js +2 -0
- package/dashboard/.next/static/chunks/0mr7sg_sr6f99.js +1 -0
- package/dashboard/.next/static/chunks/1-r9spn081_wo.js +1 -0
- package/dashboard/.next/static/chunks/13ge_ybuj8rl3.js +1 -0
- package/dashboard/.next/static/chunks/14mrh2-p_w84d.js +1 -0
- package/dashboard/.next/static/chunks/17nxt0zmkvdgv.js +1 -0
- package/dashboard/.next/static/chunks/2284qz1hy9776.css +3 -0
- package/dashboard/.next/static/chunks/22r7w355mazs8.js +1 -0
- package/dashboard/.next/static/chunks/27jktro2p5rq9.js +4 -0
- package/dashboard/.next/static/chunks/2t3rqr0rkspb7.js +1 -0
- package/dashboard/.next/static/chunks/2zho1fpijk0fu.js +1 -0
- package/dashboard/.next/static/chunks/30uw-uiehs39o.js +1 -0
- package/dashboard/.next/static/chunks/36ssnkm0cjgq6.js +31 -0
- package/dashboard/.next/static/chunks/3i6nr2y3h_7s2.js +1 -0
- package/dashboard/.next/static/chunks/3j9pm5otqxm82.js +1 -0
- package/dashboard/.next/static/chunks/3jat3x6f_2a6o.js +1 -0
- package/dashboard/.next/static/chunks/3nrz6v06gppob.js +1 -0
- package/dashboard/.next/static/chunks/40pm83c1_d0jz.js +25 -0
- package/dashboard/.next/static/chunks/turbopack-28-wpvvyttgwq.js +1 -0
- package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_buildManifest.js +11 -0
- package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_clientMiddlewareManifest.js +6 -0
- package/dashboard/.next/static/dkqYdDLx-R5NmenO8DP0C/_ssgManifest.js +1 -0
- package/dashboard/.next/static/media/13bf9871fe164e7f-s.2f7nqdagzwx2-.woff2 +0 -0
- package/dashboard/.next/static/media/1bffadaabf893a1e-s.3-6t-g6q0vh0a.woff2 +0 -0
- package/dashboard/.next/static/media/2bbe8d2671613f1f-s.0k62hbripvv8p.woff2 +0 -0
- package/dashboard/.next/static/media/2c55a0e60120577a-s.0-dom-5bn10r2.woff2 +0 -0
- package/dashboard/.next/static/media/3fe682a82f50d426-s.0vfdmo25voy_0.woff2 +0 -0
- package/dashboard/.next/static/media/5476f68d60460930-s.2uwcyprjm3xu3.woff2 +0 -0
- package/dashboard/.next/static/media/70bc3e132a0a741e-s.p.3t6q91iet4nsy.woff2 +0 -0
- package/dashboard/.next/static/media/71b036adf157cdcf-s.0bp8oijd_gu96.woff2 +0 -0
- package/dashboard/.next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2 +0 -0
- package/dashboard/.next/static/media/89b21bb081cb7469-s.1fby2rem9ngyr.woff2 +0 -0
- package/dashboard/.next/static/media/9c72aa0f40e4eef8-s.1y4-pdgsjb-pw.woff2 +0 -0
- package/dashboard/.next/static/media/ad66f9afd8947f86-s.3lvt2whj97whp.woff2 +0 -0
- package/dashboard/.next/static/media/cc545e633e20c56d-s.176arc174-8zp.woff2 +0 -0
- package/dashboard/.next/static/media/icon.43yv9zw_mes0x.svg +8 -0
- package/dashboard/.next/trace +1 -0
- package/dashboard/.next/trace-build +1 -0
- package/dashboard/.next/turbopack +0 -0
- package/dashboard/.next/types/cache-life.d.ts +145 -0
- package/dashboard/.next/types/routes.d.ts +88 -0
- package/dashboard/.next/types/validator.ts +223 -0
- package/dist/cli.js +16 -5
- package/dist/cli.js.map +1 -1
- package/package.json +3 -1
- package/scripts/postinstall.cjs +66 -0
- package/src/cli.ts +16 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Badge.tsx","../../../../src/components/ui.tsx","../../../../src/components/RichCard.tsx","../../../../src/lib/capabilities.ts","../../../../src/components/CapacityBadges.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","// Model capabilities — what each model can read/do beyond plain text.\n//\n// Fallback order (first match wins), result merged over DEFAULT_CAPABILITIES:\n// 1. PROVIDER_CAPABILITIES[provider][model] — provider-specific override\n// 2. MODEL_CAPABILITIES[model] — canonical exact id (handles exceptions)\n// 3. PATTERN_CAPABILITIES — glob match, ordered specific -> generic\n// 4. DEFAULT_CAPABILITIES — safe floor (always returned)\n//\n// ── HOW TO ADD / UPDATE A MODEL ──────────────────────────────────────\n// Authoritative data source: https://models.dev/api.json (145 providers, 4000+\n// models, MIT). Each model exposes the exact fields we map below:\n// modalities.input [\"text\",\"image\",\"pdf\",\"audio\",\"video\"] -> vision / pdf / audioInput / videoInput\n// modalities.output [\"text\",\"image\",\"audio\"] -> imageOutput / audioOutput\n// reasoning -> reasoning tool_call -> tools\n// limit.context -> contextWindow limit.output -> maxOutput\n// Look up the model id, then:\n// • If a PATTERN below already covers it correctly -> nothing to do.\n// • If it is an exception (pattern would mis-match) -> add an exact entry to\n// MODEL_CAPABILITIES (only the fields that differ from DEFAULT).\n// • If a whole new family -> add an ordered PATTERN (specific before generic).\n// NOTE: models.dev has NO \"search\" flag (web search is a runtime tool, not a\n// model spec); set `search` from vendor docs (Claude 4.x+, GPT-5.x/4o, Gemini\n// 2.0+, Grok, Perplexity). Verify with: curl -s https://models.dev/api.json\n\n\n/**\n * Safe floor — every resolved result is merged over this so consumers\n * never need null-checks. Most modern LLMs meet these limits.\n */\nexport interface Caps {\n vision: boolean;\n pdf: boolean;\n audioInput: boolean;\n videoInput: boolean;\n imageOutput: boolean;\n audioOutput: boolean;\n search: boolean;\n tools: boolean;\n reasoning: boolean;\n thinkingFormat: string | null;\n thinkingCanDisable: boolean;\n thinkingRange: { min: number; max: number } | null;\n contextWindow: number;\n maxOutput: number;\n}\n\n/**\n * Glob (* = wildcard) match, anchored + case-insensitive. aigetwey's\n * pricing.matchPattern so capabilities resolve identically.\n */\nexport function matchPattern(pattern: string, model: string): boolean {\n const regex = new RegExp(\n \"^\" + pattern.split(\"*\").map((s) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\".*\") + \"$\",\n \"i\",\n );\n return regex.test(model);\n}\n\nexport const DEFAULT_CAPABILITIES: Caps = {\n // input modalities\n vision: false, // read images\n pdf: false, // read PDF / documents\n audioInput: false, // read audio\n videoInput: false, // read video\n // output modalities\n imageOutput: false, // generate images\n audioOutput: false, // generate audio\n // features\n search: false, // built-in web search tool / grounding\n tools: true, // function / tool calling\n reasoning: false, // thinking / reasoning\n // thinking wire format (only meaningful when reasoning:true). null → derive from transport.format.\n // enum: openai|claude-adaptive|claude-budget|gemini-level|gemini-budget|zai|qwen|deepseek|kimi|minimax|hunyuan|step\n thinkingFormat: null,\n thinkingCanDisable: true, // false → model cannot turn thinking off (clamp to min instead of disable)\n thinkingRange: null, // { min, max } for budget formats; null = no clamp\n // limits (tokens)\n contextWindow: 200000,\n maxOutput: 64000,\n};\n\n// User-added model metadata can carry dashboard service kinds instead of the\n// runtime capability names used here. Map those typed model kinds into input /\n// output capabilities so custom vision models are not treated as text-only.\nconst SERVICE_KIND_CAPABILITIES: Record<string, Partial<Caps>> = {\n imageToText: { vision: true },\n image: { imageOutput: true },\n stt: { audioInput: true },\n tts: { audioOutput: true },\n embedding: { tools: false },\n};\n\nexport function capabilitiesFromServiceKind(kind: string): Partial<Caps> | null {\n return SERVICE_KIND_CAPABILITIES[kind] || null;\n}\n\n/**\n * Canonical exact-id overrides — used for exceptions that patterns would\n * otherwise mis-match. Only declare deltas vs DEFAULT.\n */\nexport const MODEL_CAPABILITIES: Record<string, Partial<Caps>> = {\n // Claude 4.6/4.7 have 1M context + adaptive thinking (override generic claude pattern)\n \"claude-opus-4.6\": { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\", contextWindow: 1000000, maxOutput: 128000 },\n \"claude-opus-4.7\": { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\", contextWindow: 1000000, maxOutput: 128000 },\n \"claude-opus-4-6\": { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\", contextWindow: 1000000, maxOutput: 128000 },\n \"claude-sonnet-4.6\": { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\", contextWindow: 1000000, maxOutput: 64000 },\n \"claude-sonnet-4-6\": { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\", contextWindow: 1000000, maxOutput: 64000 },\n\n // Gemini image-gen / OpenAI image / xai image variants\n \"gpt-image-1\": { imageOutput: true, tools: false },\n\n // GLM vision variant (text GLM has no vision)\n \"glm-4.6v\": { vision: true, reasoning: true, thinkingFormat: \"zai\", contextWindow: 128000 },\n\n // Qwen plain coder/text (no vision) — registry \"vision-model\" / \"coder-model\" aliases\n \"vision-model\": { vision: true, reasoning: true, thinkingFormat: \"qwen\", contextWindow: 1000000 },\n \"coder-model\": { reasoning: true, thinkingFormat: \"qwen\", contextWindow: 1000000 },\n};\n\n/**\n * Provider-specific capability overrides. Keyed by provider alias/id.\n */\nexport const PROVIDER_CAPABILITIES: Record<string, Record<string, Partial<Caps>>> = {\n // CodeBuddy.cn — authoritative per-model metadata from the gateway's model\n // config (contextWindow=maxInputTokens, maxOutput=maxOutputTokens, vision=\n // supportsImages). Every model reasons via OpenAI-style reasoning_effort\n // (see registry thinkingFormat). `onlyReasoning` models can't turn thinking\n // off → thinkingCanDisable:false (clamped to minimal instead of disabled).\n \"codebuddy-cn\": {\n \"glm-5.2\": { reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 1000000, maxOutput: 48000 },\n \"glm-5.1\": { reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 48000 },\n \"glm-5.0\": { reasoning: true, thinkingFormat: \"openai\", contextWindow: 200000, maxOutput: 48000 },\n \"glm-5.0-turbo\": { reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 48000 },\n \"glm-5v-turbo\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 38000 },\n \"glm-4.7\": { reasoning: true, thinkingFormat: \"openai\", contextWindow: 200000, maxOutput: 48000 },\n \"minimax-m3\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 512000, maxOutput: 48000 },\n \"minimax-m2.7\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 48000 },\n \"kimi-k2.7\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 256000, maxOutput: 32000 },\n \"kimi-k2.6\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 256000, maxOutput: 32000 },\n \"kimi-k2.5\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 164000, maxOutput: 32000 },\n \"hy3-preview\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 192000, maxOutput: 64000 },\n \"deepseek-v4-pro\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 1000000, maxOutput: 50000 },\n \"deepseek-v4-flash\": { vision: true, reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 1000000, maxOutput: 50000 },\n \"deepseek-v3-2-volc\": { reasoning: true, thinkingFormat: \"openai\", thinkingCanDisable: false, contextWindow: 96000, maxOutput: 32000 },\n },\n};\n\n/**\n * Pattern fallback — glob (* = wildcard), matched case-insensitively and\n * anchored (^...$) so a pattern must match the full model id. ORDER MATTERS:\n * vision/specific variants first, text-only/generic families last, to avoid\n * a broad family pattern swallowing an exception (e.g. glm-4.6v vs glm-5).\n */\nexport const PATTERN_CAPABILITIES: Array<{ pattern: string; caps: Partial<Caps> }> = [\n // ── Claude (4.6+ = adaptive thinking; older/haiku = budget) ──────\n { pattern: \"*claude*opus-4.6*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\" } },\n { pattern: \"*claude*opus-4.7*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\" } },\n { pattern: \"*claude*opus-4.8*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\" } },\n { pattern: \"*claude*sonnet-4.6*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\" } },\n { pattern: \"*claude*sonnet-4.7*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-adaptive\" } },\n { pattern: \"*claude*haiku*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\" } },\n { pattern: \"*claude*opus*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\" } },\n { pattern: \"*claude*sonnet*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\" } },\n { pattern: \"*claude*fable*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\", contextWindow: 1000000, maxOutput: 128000 } },\n { pattern: \"*claude*mythos*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\", contextWindow: 1000000, maxOutput: 128000 } },\n { pattern: \"*claude-3*\", caps: { vision: true } },\n { pattern: \"*claude*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"claude-budget\" } },\n\n // ── Gemini (all 2.0+ multimodal + google_search grounding, 1M ctx) ─\n { pattern: \"*gemini*image*\", caps: { vision: true, imageOutput: true, contextWindow: 1048576 } },\n { pattern: \"*gemini-3*pro*\", caps: { vision: true, audioInput: true, videoInput: true, reasoning: true, search: true, thinkingFormat: \"gemini-level\", thinkingCanDisable: false, contextWindow: 1048576, maxOutput: 65535 } },\n { pattern: \"*gemini-3*\", caps: { vision: true, audioInput: true, videoInput: true, reasoning: true, search: true, thinkingFormat: \"gemini-level\", thinkingCanDisable: false, contextWindow: 1048576, maxOutput: 65536 } },\n { pattern: \"*gemini-2.5*\", caps: { vision: true, audioInput: true, videoInput: true, reasoning: true, search: true, thinkingFormat: \"gemini-budget\", thinkingRange: { min: 0, max: 24576 }, contextWindow: 1048576, maxOutput: 65536 } },\n { pattern: \"*gemini-2*\", caps: { vision: true, audioInput: true, videoInput: true, search: true, contextWindow: 1048576, maxOutput: 65536 } },\n { pattern: \"*gemini*\", caps: { vision: true, search: true, contextWindow: 1048576 } },\n { pattern: \"*gemma*\", caps: { vision: true, contextWindow: 128000 } },\n { pattern: \"*nanobanana*\", caps: { vision: true, imageOutput: true } },\n\n // ── OpenAI GPT-5.x (vision + thinking + web search) ──────────────\n { pattern: \"*gpt-5*image*\", caps: { imageOutput: true } },\n { pattern: \"*gpt-5*codex*\", caps: { reasoning: true, search: true, thinkingFormat: \"openai\", contextWindow: 400000, maxOutput: 128000 } },\n { pattern: \"*gpt-5*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"openai\", contextWindow: 400000, maxOutput: 128000 } },\n { pattern: \"*gpt-4o*\", caps: { vision: true, search: true, contextWindow: 128000, maxOutput: 16384 } },\n { pattern: \"*gpt-4.1*\", caps: { vision: true, contextWindow: 1000000, maxOutput: 32768 } },\n { pattern: \"*gpt-4-turbo*\", caps: { vision: true, contextWindow: 128000 } },\n { pattern: \"*gpt-4*\", caps: { contextWindow: 128000 } },\n { pattern: \"*gpt-3.5*\", caps: { contextWindow: 16385, maxOutput: 4096 } },\n { pattern: \"*gpt-oss*\", caps: { reasoning: true, thinkingFormat: \"openai\", contextWindow: 128000 } },\n\n // ── OpenAI o-series (reasoning, vision) ──────────────────────────\n { pattern: \"*o1-mini*\", caps: { reasoning: true, thinkingFormat: \"openai\", contextWindow: 128000 } },\n { pattern: \"*o1*\", caps: { vision: true, reasoning: true, thinkingFormat: \"openai\", contextWindow: 200000, maxOutput: 100000 } },\n { pattern: \"*o3*\", caps: { vision: true, reasoning: true, thinkingFormat: \"openai\", contextWindow: 200000, maxOutput: 100000 } },\n { pattern: \"*o4*\", caps: { vision: true, reasoning: true, thinkingFormat: \"openai\", contextWindow: 200000, maxOutput: 100000 } },\n\n // ── Grok (vision + Live Search) ──────────────────────────────────\n { pattern: \"*grok*image*\", caps: { imageOutput: true } },\n { pattern: \"*grok-code*\", caps: { reasoning: true, thinkingFormat: \"openai\", contextWindow: 256000 } },\n { pattern: \"*grok-4*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"openai\", contextWindow: 256000 } },\n { pattern: \"*grok-3*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"openai\", contextWindow: 131072 } },\n { pattern: \"*grok*\", caps: { vision: true, reasoning: true, search: true, thinkingFormat: \"openai\", contextWindow: 256000 } },\n\n // ── Qwen (enable_thinking + thinking_budget; QwQ = thinking-only) ─\n { pattern: \"*qwen*vl*\", caps: { vision: true, reasoning: true, thinkingFormat: \"qwen\", contextWindow: 262144 } },\n { pattern: \"*qwen*max*\", caps: { vision: true, reasoning: true, thinkingFormat: \"qwen\", contextWindow: 1000000, maxOutput: 65536 } },\n { pattern: \"*qwen*plus*\", caps: { vision: true, reasoning: true, thinkingFormat: \"qwen\", contextWindow: 1000000, maxOutput: 65536 } },\n { pattern: \"*qwen*235b*\", caps: { reasoning: true, thinkingFormat: \"qwen\", contextWindow: 262144 } },\n { pattern: \"*qwen*coder*\", caps: { reasoning: true, thinkingFormat: \"qwen\", contextWindow: 1000000 } },\n { pattern: \"*qwq*\", caps: { reasoning: true, thinkingFormat: \"qwen\", thinkingCanDisable: false, contextWindow: 131072 } },\n { pattern: \"*qwen*\", caps: { reasoning: true, thinkingFormat: \"qwen\", contextWindow: 262144 } },\n\n // ── Kimi (enabled→reasoning_effort; K2.7-code cannot disable) ─────\n { pattern: \"*kimi*k2.7*code*\", caps: { vision: true, reasoning: true, thinkingFormat: \"kimi\", thinkingCanDisable: false, contextWindow: 262144, maxOutput: 262144 } },\n { pattern: \"*kimi*k2*\", caps: { vision: true, reasoning: true, thinkingFormat: \"kimi\", contextWindow: 262144, maxOutput: 262144 } },\n { pattern: \"*kimi*\", caps: { reasoning: true, thinkingFormat: \"kimi\", contextWindow: 262144 } },\n\n // ── GLM / Z.ai (thinking.enabled; disable via enable_thinking:false) ─\n { pattern: \"*glm-5*\", caps: { reasoning: true, thinkingFormat: \"zai\", contextWindow: 200000, maxOutput: 128000 } },\n { pattern: \"*glm-4.7*\", caps: { reasoning: true, thinkingFormat: \"zai\", contextWindow: 200000, maxOutput: 128000 } },\n { pattern: \"*glm-4*\", caps: { reasoning: true, thinkingFormat: \"zai\", contextWindow: 200000 } },\n { pattern: \"*glm*\", caps: { reasoning: true, thinkingFormat: \"zai\", contextWindow: 200000 } },\n\n // ── DeepSeek (thinking.enabled + reasoning_effort; r1 = thinking-only) ─\n { pattern: \"*deepseek-v4*\", caps: { reasoning: true, thinkingFormat: \"deepseek\", contextWindow: 1000000, maxOutput: 384000 } },\n { pattern: \"*reasoner*\", caps: { reasoning: true, thinkingFormat: \"deepseek\", thinkingCanDisable: false, contextWindow: 128000 } },\n { pattern: \"*deepseek-r*\", caps: { reasoning: true, thinkingFormat: \"deepseek\", thinkingCanDisable: false, contextWindow: 128000 } },\n { pattern: \"*deepseek-chat*\", caps: { contextWindow: 128000 } },\n { pattern: \"*deepseek*\", caps: { reasoning: true, thinkingFormat: \"deepseek\", contextWindow: 128000 } },\n\n // ── MiniMax (M3 = adaptive; M2.x cannot disable) ─────────────────\n { pattern: \"*minimax*image*\", caps: { imageOutput: true } },\n { pattern: \"*minimax-m3*\", caps: { vision: true, reasoning: true, thinkingFormat: \"minimax\", contextWindow: 1048576, maxOutput: 512000 } },\n { pattern: \"*minimax-m2.7*\", caps: { reasoning: true, thinkingFormat: \"minimax\", thinkingCanDisable: false, contextWindow: 204800, maxOutput: 131072 } },\n { pattern: \"*minimax*\", caps: { reasoning: true, thinkingFormat: \"minimax\", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 131072 } },\n\n // ── Xiaomi MiMo (vision, 1M / 262K ctx) ──────────────────────────\n { pattern: \"*mimo*v2.5*\", caps: { vision: true, contextWindow: 1048576, maxOutput: 131072 } },\n { pattern: \"*mimo*omni*\", caps: { vision: true, audioInput: true, contextWindow: 262144, maxOutput: 131072 } },\n { pattern: \"*mimo*\", caps: { vision: true, contextWindow: 262144, maxOutput: 131072 } },\n\n // ── Llama (4 = vision/1M; 3.x = text-only/128K) ──────────────────\n { pattern: \"*llama-4*\", caps: { vision: true, contextWindow: 1000000 } },\n { pattern: \"*llama*\", caps: { contextWindow: 128000 } },\n\n // ── Mistral (Large 3 = vision/256K; codestral text) ──────────────\n { pattern: \"*codestral*\", caps: { contextWindow: 256000 } },\n { pattern: \"*mistral-large*\", caps: { vision: true, contextWindow: 256000 } },\n { pattern: \"*mistral*\", caps: { contextWindow: 128000 } },\n\n // ── Cohere (Command A Vision = vision; others text) ──────────────\n { pattern: \"*command-a-vision*\", caps: { vision: true, contextWindow: 128000 } },\n { pattern: \"*command*\", caps: { contextWindow: 128000 } },\n\n // ── Perplexity (web search native) ───────────────────────────────\n { pattern: \"*sonar*\", caps: { search: true, contextWindow: 128000 } },\n { pattern: \"*pplx*\", caps: { search: true, contextWindow: 128000 } },\n { pattern: \"*perplexity*\", caps: { search: true, contextWindow: 128000 } },\n\n // ── Others ───────────────────────────────────────────────────────\n { pattern: \"*hunyuan*\", caps: { reasoning: true, thinkingFormat: \"hunyuan\", contextWindow: 262144, maxOutput: 262144 } },\n { pattern: \"hy3*\", caps: { reasoning: true, thinkingFormat: \"hunyuan\", contextWindow: 262144, maxOutput: 262144 } },\n { pattern: \"*step-*\", caps: { reasoning: true, thinkingFormat: \"step\", contextWindow: 128000 } },\n { pattern: \"*nemotron*\", caps: { reasoning: true, contextWindow: 128000 } },\n { pattern: \"*ling-*\", caps: { reasoning: true, contextWindow: 128000 } },\n];\n\n/**\n * Resolve capabilities for a model using the 4-step fallback chain,\n * merged over DEFAULT_CAPABILITIES so the result is always complete.\n *\n * @param {string} provider\n * @param {string} model\n * @returns {object} full capabilities object\n */\n/**\n * models.dev-style modalities for a model ref, derived from its capabilities.\n * Ref may be a `provider/model` (vendor prefix tolerated) or a bare combo alias.\n * Mirrors what opencode/aigetwey store per model in opencode.json.\n */\nexport function modalitiesForModel(ref: string): { input: string[]; output: string[] } {\n const slash = ref.indexOf(\"/\");\n const provider = slash > 0 ? ref.slice(0, slash) : null;\n const model = slash > 0 ? ref.slice(slash + 1) : ref;\n const c = getCapabilitiesForModel(provider, model);\n const input = [\"text\"];\n if (c.vision) input.push(\"image\");\n if (c.pdf) input.push(\"pdf\");\n if (c.audioInput) input.push(\"audio\");\n if (c.videoInput) input.push(\"video\");\n const output = [\"text\"];\n if (c.imageOutput) output.push(\"image\");\n if (c.audioOutput) output.push(\"audio\");\n return { input, output };\n}\n\nexport function getCapabilitiesForModel(provider: string | null, model: string): Caps {\n if (!model) return { ...DEFAULT_CAPABILITIES };\n\n // 1. Provider-specific override\n if (provider && PROVIDER_CAPABILITIES[provider]?.[model]) {\n return { ...DEFAULT_CAPABILITIES, ...PROVIDER_CAPABILITIES[provider][model] };\n }\n\n // 2. Canonical exact (strip vendor prefix: \"anthropic/claude-opus-4.7\" -> \"claude-opus-4.7\")\n const baseModel = (model.includes(\"/\") ? model.split(\"/\").pop() : model) ?? model;\n if (MODEL_CAPABILITIES[baseModel]) return { ...DEFAULT_CAPABILITIES, ...MODEL_CAPABILITIES[baseModel] };\n if (MODEL_CAPABILITIES[model]) return { ...DEFAULT_CAPABILITIES, ...MODEL_CAPABILITIES[model] };\n\n // 3. Pattern match (first match wins)\n for (const { pattern, caps } of PATTERN_CAPABILITIES) {\n if (matchPattern(pattern, baseModel) || matchPattern(pattern, model)) {\n return { ...DEFAULT_CAPABILITIES, ...caps };\n }\n }\n\n // 4. Floor\n return { ...DEFAULT_CAPABILITIES };\n}\n","\"use client\";\n\nimport { getCapabilitiesForModel, type Caps } from \"@/lib/capabilities\";\nimport { Icon } from \"@/components/Icon\";\n\n/**\n * Per-model capability icons, aigetwey's own CapacityBadges + CAPACITY_META.\n * Caps are DERIVED from the model id (not stored per-model) via the same resolver\n * aigetwey uses, so badges match wherever the model appears. Only set caps render.\n */\nconst CAPACITY_META: Record<string, { icon: string; label: string; desc: string; color: string }> = {\n vision: { icon: \"visibility\", label: \"Vision\", desc: \"Supports image input\", color: \"text-info\" },\n reasoning: { icon: \"neurology\", label: \"Reasoning\", desc: \"Supports reasoning / thinking\", color: \"text-warning\" },\n};\n\nexport function CapacityBadges({\n model,\n provider = null,\n size = 15,\n className = \"\",\n}: {\n model: string;\n provider?: string | null;\n size?: number;\n className?: string;\n}) {\n const caps = getCapabilitiesForModel(provider, model);\n const active = Object.keys(CAPACITY_META).filter((k) => caps[k as keyof Caps]);\n if (active.length === 0) return null;\n\n return (\n <span className={`inline-flex flex-none items-center gap-0.5 ${className}`}>\n {active.map((k) => (\n <span key={k} title={`${CAPACITY_META[k]!.label} — ${CAPACITY_META[k]!.desc}`} className=\"leading-none\">\n <Icon name={CAPACITY_META[k]!.icon} size={size} className={CAPACITY_META[k]!.color} />\n </span>\n ))}\n </span>\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","matchPattern","pattern","model","regex","RegExp","split","map","replace","join","test","DEFAULT_CAPABILITIES","vision","pdf","audioInput","videoInput","imageOutput","audioOutput","search","tools","reasoning","thinkingFormat","thinkingCanDisable","thinkingRange","contextWindow","maxOutput","SERVICE_KIND_CAPABILITIES","imageToText","image","stt","tts","embedding","capabilitiesFromServiceKind","kind","MODEL_CAPABILITIES","PROVIDER_CAPABILITIES","PATTERN_CAPABILITIES","caps","min","modalitiesForModel","ref","slash","indexOf","provider","slice","c","getCapabilitiesForModel","input","push","output","baseModel","includes","pop"],"mappings":"uDAEA,IAAMA,EAA8B,CAClCC,KAAM,6BACNC,KAAM,2BACNC,KAAM,6BACNC,KAAM,uBACNC,QAAS,8BACX,EAEO,SAASC,EAAM,MACpBC,EAAO,SAAS,UAChBC,CAAQ,WACRC,CAAS,CAKV,EACC,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACCA,UAAW,CAAC,gFAAgF,EAAET,CAAK,CAACO,EAAK,CAAA,EAAGE,EAAY,CAAC,CAAC,EAAEA,EAAAA,CAAW,CAAG,GAAA,CAAI,UAE7ID,GAGP,kCAGO,SAASE,AAAY,QAAEC,CAAM,CAAiD,EACnF,MAAO,CAAA,EAAA,EAAA,GAAA,EAACL,EAAAA,CAAMC,KAAK,gBAAQI,GAC7B,4BC/BwD,IAAA,EAAA,EAAA,CAAA,CAAA,sBAwDjD,SAASmC,AAAM,UAAEtC,CAAQ,CAAiC,EAC/D,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIC,UAAU,6DAAqDD,GAC7E,WAbO,SAASkC,AAAK,OAAEC,CAAK,OAAEC,CAAK,CAAEC,KAAG,CAA2D,EACjG,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAIpC,UAAU,qFACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIA,UAAU,6EAAqEkC,IACpF,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIlC,UAAU,wEAAgEmC,IAC9EC,GAAO,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIpC,UAAU,8CAAsCoC,MAGnE,UApDmB,KACjBhC,AAAIC,CAAS,EACJA,EAAEC,cAAc,CAAC,iBAG1BC,AAAQF,CAAS,EACf,AAAIG,KAAKC,GAAG,CAACJ,IAAM,IAAkB,CAAA,EAAG,CAACA,EAAI,CAAf,EAAe,CAAS,CAAEK,OAAO,CAAC,GAAG,CAAC,CAAC,CACjEF,KAAKC,GAAG,CAACJ,IAAM,IAAc,CAAA,EAAP,AAAU,CAACA,EAAI,GAAA,CAAK,CAAEK,OAAO,CAAC,GAAG,CAAC,CAAC,CACtDC,OAAOH,KAAKI,KAAK,CAACP,SAE3BQ,AAAKR,CAAS,EACZ,AAAU,GAAG,CAATA,EAAgB,KACbA,EAAI,IAAO,CAAC,CAAC,EAAEA,EAAEK,OAAO,CAAC,GAAA,CAAI,CAAG,CAAC,CAAC,EAAEL,EAAEK,OAAO,CAAC,GAAA,CAAI,MAE3DI,AAAKC,EAAU,CACN,IAAIC,KAAKD,GAAIT,cAAc,CAAC,QAAS,CAAEW,QAAQ,CAAM,GAG9DC,KAAKH,CAAU,EACb,IAAMI,EAAI,IAAIH,KAAKD,GACnB,MAAO,CAAA,EAAGJ,OAAOQ,EAAEC,OAAO,IAAIC,QAAQ,CAAC,EAAG,KAAK,CAAC,EAAEV,OAAOQ,EAAEG,QAAQ,GAAK,GAAGD,QAAQ,CAAC,EAAG,KAAK,CAAC,EAAEF,EAAEI,WAAW,GAAA,CAAI,AAClH,EAEAC,IAAIT,CAAU,EACZ,IAAMU,EAAIjB,KAAKkB,GAAG,CAAC,EAAGlB,KAAKI,KAAK,CAAC,CAACI,KAAKW,GAAG,GAAKZ,CAAAA,CAAE,CAAI,aACjDU,AAAJ,EAAQ,GAAW,CAAP,AAAO,EAAGA,EAAE,CAAC,CAAC,CACtBA,EAAI,KAAa,CAAP,AAAO,EAAGjB,KAAKoB,KAAK,CAACH,EAAI,IAAI,CAAC,CAAC,CACzCA,EAAI,MAAc,CAAP,AAAO,EAAGjB,KAAKoB,KAAK,CAACH,EAAI,MAAM,CAAC,CAAC,CACzC,CAAA,EAAGjB,KAAKoB,KAAK,CAACH,EAAI,OAAO,CAAC,CAAC,AACpC,EAEAI,SAASC,CAAU,EACjB,IAAML,EAAIjB,KAAKkB,GAAG,CAAC,EAAGlB,KAAKI,KAAK,CAACkB,EAAK,MACtC,GAAIL,EAAI,GAAI,MAAO,CAAA,EAAGA,EAAE,CAAC,CAAC,CAC1B,GAAIA,EAAI,KAAM,MAAO,CAAA,EAAGjB,KAAKoB,KAAK,CAACH,EAAI,IAAI,EAAE,EAAEA,EAAI,GAAG,CAAC,CAAC,CACxD,IAAMM,EAAIvB,KAAKoB,KAAK,CAACH,EAAI,MACnBO,EAAIxB,KAAKoB,KAAK,CAAEH,EAAI,KAAQ,IAClC,GAAIM,EAAI,GAAI,MAAO,CAAA,EAAGA,EAAE,EAAE,EAAEC,EAAE,CAAC,CAAC,CAChC,IAAMb,EAAIX,KAAKoB,KAAK,CAACG,EAAI,IACzB,MAAO,CAAA,EAAGZ,EAAE,EAAE,EAAEY,EAAI,GAAG,CAAC,CAC1B,AAD2B,CAE7B,4BCvCC,IAAA,EAAA,EAAA,CAAA,CAAA,0BAgCM,SAASU,AAAU,OAAEC,CAAK,KAAEN,CAAG,MAAEO,CAAI,CAA2D,EACrG,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI3C,UAAU,8CACZ2C,EACD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI3C,UAAU,oBACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIA,UAAU,uEAA+D0C,IAC7EN,GAAO,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIpC,UAAU,gDAAwCoC,SAIvE,eAzCO,SAASE,AAAS,QACvBC,CAAM,QACNC,CAAM,UACNzC,CAAQ,WACRC,CAAS,CAMV,EACC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,UAAA,CACCA,UAAW,CAAC,4EAA4E,EAAEA,EAAY,CAAC,CAAC,EAAEA,EAAAA,CAAW,CAAG,GAAA,CAAI,WAE3HuC,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAAOvC,UAAU,2FACfuC,IAGL,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAIvC,UAAU,eAAOD,IACrByC,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAAOxC,UAAU,uGACfwC,MAKX,mDCkBO,SAASI,EAAaC,CAAe,CAAEC,CAAa,EAKzD,OAJc,AAAIE,AAIXD,OAHL,IAAMF,EAAQI,KAAK,CAAC,KAAKC,GAAG,CAAC,AAACzB,GAAMA,EAAE0B,OAAO,CAAC,sBAAuB,SAASC,IAAI,CAAC,MAAQ,IAC3F,KAEWC,IAAI,CAACP,EACpB,CAEO,IAAMQ,EAA6B,CAExCC,OAAQ,GACRC,IAAK,GACLC,YAAY,EACZC,YAAY,EAEZC,aAAa,EACbC,aAAa,EAEbC,QAAQ,EACRC,OAAO,EACPC,WAAW,EAGXC,eAAgB,KAChBC,oBAAoB,EACpBC,cAAe,KAEfC,cAAe,IACfC,UAAW,IACb,EAqBaS,EAAoD,CAE/D,kBAAqB,CAAEtB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,kBAAmBG,cAAe,IAASC,UAAW,KAAO,EACjJ,kBAAqB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,kBAAmBG,cAAe,IAASC,UAAW,KAAO,EACjJ,kBAAqB,CAAEb,OAAQ,GAAMQ,UAAW,GAAMF,QAAQ,EAAMG,eAAgB,kBAAmBG,cAAe,IAASC,UAAW,KAAO,EACjJ,oBAAqB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMF,OAAQ,GAAMG,eAAgB,kBAAmBG,cAAe,IAASC,UAAW,IAAM,EAChJ,oBAAqB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,kBAAmBG,cAAe,IAASC,UAAW,IAAM,EAGhJ,cAAqB,CAAET,aAAa,EAAMG,OAAO,CAAM,EAGvD,WAAqB,CAAEP,QAAQ,EAAMQ,UAAW,GAAMC,eAAgB,MAAOG,cAAe,KAAO,EAGnG,eAAqB,CAAEZ,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,GAAQ,EACrG,cAAqB,CAAEJ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,GAAQ,CACzF,EAKaW,EAAuE,CAMlF,eAAgB,CACd,UAAsB,CAAEf,UAAW,GAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAASC,UAAW,IAAM,EACvI,UAAsB,CAAEL,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAAQC,UAAW,IAAM,EACtI,UAAsB,CAAEL,WAAW,EAAMC,eAAgB,SAAUG,cAAe,IAAQC,UAAW,IAAM,EAC3G,gBAAsB,CAAEL,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAAQC,UAAW,IAAM,EACtI,eAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAAQC,UAAW,IAAM,EACpJ,UAAsB,CAAEL,WAAW,EAAMC,eAAgB,SAAUG,cAAe,IAAQC,UAAW,IAAM,EAC3G,aAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,MAAQC,UAAW,IAAM,EACpJ,eAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAAQC,UAAW,IAAM,EACpJ,YAAsB,CAAEb,OAAQ,GAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,MAAQC,UAAW,IAAM,EACpJ,YAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,MAAQC,UAAW,IAAM,EACpJ,YAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,MAAQC,UAAW,IAAM,EACpJ,cAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,MAAQC,UAAW,IAAM,EACpJ,kBAAsB,CAAEb,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAASC,UAAW,GAAM,EACrJ,oBAAsB,CAAEb,QAAQ,EAAMQ,UAAW,GAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,IAASC,UAAW,GAAM,EACrJ,qBAAsB,CAAEL,WAAW,EAAMC,eAAgB,SAAUC,oBAAoB,EAAOE,cAAe,KAAOC,UAAW,IAAM,CACvI,CACF,EAQaW,EAAwE,CAEnF,CAAElC,QAAS,oBAAuBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,iBAAkB,CAAE,EAC3H,CAAEnB,QAAS,oBAAuBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,iBAAkB,CAAE,EAC3H,CAAEnB,QAAS,oBAAuBmC,KAAM,CAAEzB,QAAQ,EAAMQ,UAAW,GAAMF,QAAQ,EAAMG,eAAgB,iBAAkB,CAAE,EAC3H,CAAEnB,QAAS,sBAAuBmC,KAAM,CAAEzB,OAAQ,GAAMQ,UAAW,GAAMF,QAAQ,EAAMG,eAAgB,iBAAkB,CAAE,EAC3H,CAAEnB,QAAS,sBAAuBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,iBAAkB,CAAE,EAC3H,CAAEnB,QAAS,iBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,OAAQ,GAAMG,eAAgB,eAAgB,CAAE,EACrH,CAAEnB,QAAS,gBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,OAAQ,GAAMG,eAAgB,eAAgB,CAAE,EACrH,CAAEnB,QAAS,kBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,OAAQ,GAAMG,eAAgB,eAAgB,CAAE,EACrH,CAAEnB,QAAS,iBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,gBAAiBG,cAAe,IAASC,UAAW,KAAO,CAAE,EAChK,CAAEvB,QAAS,kBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,gBAAiBG,cAAe,IAASC,UAAW,KAAO,CAAE,EAChK,CAAEvB,QAAS,aAAmBmC,KAAM,CAAEzB,QAAQ,CAAK,CAAE,EACrD,CAAEV,QAAS,WAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,eAAgB,CAAE,EAGrH,CAAEnB,QAAS,iBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMI,aAAa,EAAMQ,cAAe,OAAQ,CAAE,EAChG,CAAEtB,QAAS,iBAAmBmC,KAAM,CAAEzB,QAAQ,EAAME,YAAY,EAAMC,YAAY,EAAMK,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,eAAgBC,oBAAoB,EAAOE,cAAe,QAASC,UAAW,KAAM,CAAE,EAC7N,CAAEvB,QAAS,aAAmBmC,KAAM,CAAEzB,QAAQ,EAAME,YAAY,EAAMC,YAAY,EAAMK,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,eAAgBC,oBAAoB,EAAOE,cAAe,QAASC,UAAW,KAAM,CAAE,EAC7N,CAAEvB,QAAS,eAAmBmC,KAAM,CAAEzB,QAAQ,EAAME,WAAY,GAAMC,WAAY,GAAMK,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,gBAAiBE,cAAe,CAAEe,IAAK,EAAGvD,IAAK,KAAM,EAAGyC,cAAe,QAASC,UAAW,KAAM,CAAE,EAC1O,CAAEvB,QAAS,aAAmBmC,KAAM,CAAEzB,QAAQ,EAAME,YAAY,EAAMC,YAAY,EAAMG,QAAQ,EAAMM,cAAe,QAASC,UAAW,KAAM,CAAE,EACjJ,CAAEvB,QAAS,WAAmBmC,KAAM,CAAEzB,QAAQ,EAAMM,QAAQ,EAAMM,cAAe,OAAQ,CAAE,EAC3F,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,KAAO,CAAE,EAC5E,CAAEtB,QAAS,eAAmBmC,KAAM,CAAEzB,QAAQ,EAAMI,aAAa,CAAK,CAAE,EAGxE,CAAEd,QAAS,gBAAmBmC,KAAM,CAAErB,aAAa,CAAK,CAAE,EAC1D,CAAEd,QAAS,gBAAmBmC,KAAM,CAAEjB,UAAW,GAAMF,QAAQ,EAAMG,eAAgB,SAAUG,cAAe,IAAQC,UAAW,KAAO,CAAE,EAC1I,CAAEvB,QAAS,UAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,SAAUG,cAAe,IAAQC,UAAW,KAAO,CAAE,EACxJ,CAAEvB,QAAS,WAAmBmC,KAAM,CAAEzB,QAAQ,EAAMM,QAAQ,EAAMM,cAAe,MAAQC,UAAW,KAAM,CAAE,EAC5G,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,IAASC,UAAW,KAAM,CAAE,EAC/F,CAAEvB,QAAS,gBAAmBmC,KAAM,CAAEzB,OAAQ,GAAMY,cAAe,KAAO,CAAE,EAC5E,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAC9D,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEb,cAAe,MAAOC,UAAW,IAAK,CAAE,EAC9E,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEjB,UAAW,GAAMC,eAAgB,SAAUG,cAAe,KAAO,CAAE,EAGzG,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,SAAUG,cAAe,KAAO,CAAE,EACzG,CAAEtB,QAAS,OAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUG,cAAe,IAAQC,UAAW,GAAO,CAAE,EAC1I,CAAEvB,QAAS,OAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,UAAW,GAAMC,eAAgB,SAAUG,cAAe,IAAQC,UAAW,GAAO,CAAE,EAC1I,CAAEvB,QAAS,OAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,SAAUG,cAAe,IAAQC,UAAW,GAAO,CAAE,EAG1I,CAAEvB,QAAS,eAAmBmC,KAAM,CAAErB,aAAa,CAAK,CAAE,EAC1D,CAAEd,QAAS,cAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,SAAUG,cAAe,KAAO,CAAE,EACzG,CAAEtB,QAAS,WAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,SAAUG,cAAe,KAAO,CAAE,EACrI,CAAEtB,QAAS,WAAmBmC,KAAM,CAAEzB,OAAQ,GAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,SAAUG,cAAe,MAAO,CAAE,EACrI,CAAEtB,QAAS,SAAmBmC,KAAM,CAAEzB,OAAQ,GAAMQ,WAAW,EAAMF,QAAQ,EAAMG,eAAgB,SAAUG,cAAe,KAAO,CAAE,EAGrI,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,MAAO,CAAE,EACrH,CAAEtB,QAAS,aAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,IAASC,UAAW,KAAM,CAAE,EACxI,CAAEvB,QAAS,cAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,IAASC,UAAW,KAAM,CAAE,EACxI,CAAEvB,QAAS,cAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQG,cAAe,MAAO,CAAE,EACvG,CAAEtB,QAAS,eAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQG,cAAe,GAAQ,CAAE,EACxG,CAAEtB,QAAS,QAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQC,oBAAoB,EAAOE,cAAe,MAAO,CAAE,EAClI,CAAEtB,QAAS,SAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQG,cAAe,MAAO,CAAE,EAGvG,CAAEtB,QAAS,mBAAoBmC,KAAM,CAAEzB,OAAQ,GAAMQ,UAAW,GAAMC,eAAgB,OAAQC,oBAAoB,EAAOE,cAAe,OAAQC,UAAW,MAAO,CAAE,EACpK,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,WAAW,EAAMC,eAAgB,OAAQG,cAAe,OAAQC,UAAW,MAAO,CAAE,EACxI,CAAEvB,QAAS,SAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQG,cAAe,MAAO,CAAE,EAGvG,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,MAAOG,cAAe,IAAQC,UAAW,KAAO,CAAE,EACzH,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,MAAOG,cAAe,IAAQC,UAAW,KAAO,CAAE,EACzH,CAAEvB,QAAS,UAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,MAAOG,cAAe,GAAO,CAAE,EACtG,CAAEtB,QAAS,QAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,MAAOG,cAAe,GAAO,CAAE,EAGtG,CAAEtB,QAAS,gBAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,WAAYG,cAAe,IAASC,UAAW,KAAO,CAAE,EAC/H,CAAEvB,QAAS,aAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,WAAYC,oBAAoB,EAAOE,cAAe,KAAO,CAAE,EACtI,CAAEtB,QAAS,eAAmBmC,KAAM,CAAEjB,UAAW,GAAMC,eAAgB,WAAYC,oBAAoB,EAAOE,cAAe,KAAO,CAAE,EACtI,CAAEtB,QAAS,kBAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAC9D,CAAEtB,QAAS,aAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,WAAYG,cAAe,KAAO,CAAE,EAG3G,CAAEtB,QAAS,kBAAmBmC,KAAM,CAAErB,aAAa,CAAK,CAAE,EAC1D,CAAEd,QAAS,eAAmBmC,KAAM,CAAEzB,QAAQ,EAAMQ,UAAW,GAAMC,eAAgB,UAAWG,cAAe,QAASC,UAAW,KAAO,CAAE,EAC5I,CAAEvB,QAAS,iBAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,UAAWC,oBAAoB,EAAOE,cAAe,OAAQC,UAAW,MAAO,CAAE,EACxJ,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,UAAWC,oBAAoB,EAAOE,cAAe,IAAQC,UAAW,MAAO,CAAE,EAGxJ,CAAEvB,QAAS,cAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,QAASC,UAAW,MAAO,CAAE,EAChG,CAAEvB,QAAS,cAAmBmC,KAAM,CAAEzB,QAAQ,EAAME,YAAY,EAAMU,cAAe,OAAQC,UAAW,MAAO,CAAE,EACjH,CAAEvB,QAAS,SAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,OAAQC,UAAW,MAAO,CAAE,EAG/F,CAAEvB,QAAS,YAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,GAAQ,CAAE,EAC7E,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAG9D,CAAEtB,QAAS,cAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAC9D,CAAEtB,QAAS,kBAAmBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,KAAO,CAAE,EAC5E,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAG9D,CAAEtB,QAAS,qBAAsBmC,KAAM,CAAEzB,QAAQ,EAAMY,cAAe,KAAO,CAAE,EAC/E,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEb,cAAe,KAAO,CAAE,EAG9D,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEnB,QAAQ,EAAMM,cAAe,KAAO,CAAE,EAC5E,CAAEtB,QAAS,SAAmBmC,KAAM,CAAEnB,QAAQ,EAAMM,cAAe,KAAO,CAAE,EAC5E,CAAEtB,QAAS,eAAmBmC,KAAM,CAAEnB,QAAQ,EAAMM,cAAe,KAAO,CAAE,EAG5E,CAAEtB,QAAS,YAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,UAAWG,cAAe,OAAQC,UAAW,MAAO,CAAE,EAC7H,CAAEvB,QAAS,OAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,UAAWG,cAAe,OAAQC,UAAW,MAAO,CAAE,EAC7H,CAAEvB,QAAS,UAAmBmC,KAAM,CAAEjB,WAAW,EAAMC,eAAgB,OAAQG,cAAe,KAAO,CAAE,EACvG,CAAEtB,QAAS,aAAmBmC,KAAM,CAAEjB,WAAW,EAAMI,cAAe,KAAO,CAAE,EAC/E,CAAEtB,QAAS,UAAmBmC,KAAM,CAAEjB,WAAW,EAAMI,cAAe,KAAO,CAAE,EAChF,CA+BM,SAASsB,EAAwBH,CAAuB,CAAExC,CAAa,EAC5E,GAAI,CAACA,EAAO,MAAO,CAAE,GAAGQ,CAAoB,AAAC,EAG7C,GAAIgC,GAAYR,CAAqB,CAACQ,EAAS,EAAE,CAACxC,EAAM,CACtD,CADwD,KACjD,CAAE,GAAGQ,CAAoB,CAAE,GAAGwB,CAAqB,CAACQ,EAAS,CAACxC,EAAM,AAAC,EAI9E,IAAM+C,EAAY,CAAC/C,EAAMgD,QAAQ,CAAC,KAAOhD,EAAMG,KAAK,CAAC,KAAK8C,GAAG,GAAKjD,CAAAA,CAAK,EAAKA,EAC5E,GAAI+B,CAAkB,CAACgB,EAAU,CAAE,MAAO,CAAE,GAAGvC,CAAoB,CAAE,GAAGuB,CAAkB,CAACgB,EAAU,AAAC,EACtG,GAAIhB,CAAkB,CAAC/B,EAAM,CAAE,MAAO,CAAE,GAAGQ,CAAoB,CAAE,GAAGuB,CAAkB,CAAC/B,EAAM,AAAC,EAG9F,IAAK,GAAM,SAAED,CAAO,MAAEmC,CAAI,CAAE,GAAID,EAC9B,GAAInC,EAAaC,EAASgD,IAAcjD,EAAaC,EAASC,GAC5D,CAFkD,IACkB,CAC7D,CAAE,GAAGQ,CAAoB,CAAE,GAAG0B,CAAI,AAAC,EAK9C,MAAO,CAAE,GAAG1B,CAAoB,AAAC,CACnC,2DAtCO,SAAS4B,AAAmBC,CAAW,EAC5C,IAAMC,EAAQD,EAAIE,OAAO,CAAC,KAGpBG,EAAIC,EAFOL,EAAQ,EAAID,EAAII,KAAK,CAAC,EAAGH,GAAS,KACrCA,AACoBE,EADZ,EAAIH,EAAII,IACczC,CADT,CAACsC,EAAQ,GAAKD,GAE3CO,EAAQ,CAAC,OAAO,AAClBF,GAAEjC,MAAM,EAAEmC,EAAMC,IAAI,CAAC,SACrBH,EAAEhC,GAAG,EAAEkC,EAAMC,IAAI,CAAC,OAClBH,EAAE/B,UAAU,EAAEiC,EAAMC,IAAI,CAAC,SACzBH,EAAE9B,UAAU,EAAEgC,EAAMC,IAAI,CAAC,SAC7B,IAAMC,EAAS,CAAC,OAAO,CAGvB,OAFIJ,EAAE7B,WAAW,EAAEiC,EAAOD,IAAI,CAAC,SAC3BH,EAAE5B,WAAW,EAAEgC,EAAOD,IAAI,CAAC,SACxB,OAAED,SAAOE,CAAO,CACzB,UClSA,IAAA,EAAA,EAAA,CAAA,CAAA,OAOA,IAAM,EAA8F,CAClG,OAAQ,CAAE,KAAM,aAAc,MAAO,SAAU,KAAM,uBAAwB,MAAO,WAAY,EAChG,UAAW,CAAE,KAAM,YAAa,MAAO,YAAa,KAAM,gCAAiC,MAAO,cAAe,CACnH,0BAEO,SAAS,AAAe,OAC7B,CAAK,UACL,EAAW,IAAI,MACf,EAAO,EAAE,WACT,EAAY,EAAE,CAMf,EACC,IAAM,EAAO,EAAwB,EAAU,GACzC,EAAS,OAAO,IAAI,CAAC,GAAe,MAAM,CAAC,AAAC,GAAM,CAAI,CAAC,EAAgB,SACvD,AAAtB,GAAyB,CAArB,EAAO,MAAM,CAAe,KAG9B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAC,2CAA2C,EAAE,EAAA,CAAW,UACvE,EAAO,GAAG,CAAC,AAAC,GACX,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAa,MAAO,CAAA,EAAG,CAAa,CAAC,EAAE,CAAE,KAAK,CAAC,GAAG,EAAE,CAAa,CAAC,EAAE,CAAE,IAAI,CAAA,CAAE,CAAE,UAAU,wBACvF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,KAAM,CAAa,CAAC,EAAE,CAAE,IAAI,CAAE,KAAM,EAAM,UAAW,CAAa,CAAC,EAAE,CAAE,KAAK,IADzE,KAMnB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports=[58002,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(56173),e=a.i(2693),f=a.i(85732),g=a.i(2799),h=a.i(58918),i=a.i(7078),j=a.i(93026),k=a.i(47444);let l=["5h","24h","7day","30day"],m=a=>`rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${a?"bg-accent/12 text-accent":"bg-surface-2 text-text-muted hover:text-text"}`;function n({label:a,children:c}){return(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:a}),c]})}let o=[{id:"global",icon:"public",label:"Global",hint:"Cap total spend across the whole gateway."},{id:"provider",icon:"dns",label:"Per provider",hint:"Cap one provider's spend."},{id:"model",icon:"neurology",label:"Per model",hint:"Cap one upstream model's spend."}];function p({initial:a,onSaved:e,onCancel:f}){let g=null!==a,[h,q]=(0,c.useState)(a&&"key"!==a.scope.type?a.scope.type:null),[r,s]=(0,c.useState)(a&&"global"!==a.scope.type&&"key"!==a.scope.type?a.scope.id:""),[t,u]=(0,c.useState)(null),[v,w]=(0,c.useState)(!1),[x,y]=(0,c.useState)(a?.unit??"usd"),[z,A]=(0,c.useState)(String(a?.limit??"")),[B,C]=(0,c.useState)(a?.window??"30day"),[D,E]=(0,c.useState)(a?String(Math.round(100*a.alert_at)):"80"),[F,G]=(0,c.useState)(a?.note??""),[H,I]=(0,c.useState)(""),[J,K]=(0,c.useState)(!1);(0,c.useEffect)(()=>{d.adminApi.models().then(a=>{a.ok&&a.data&&u(a.data)})},[]);let L=t?.providers.length?[{label:"Providers",items:t.providers.map(a=>({value:a.id,label:a.id}))}]:[],M=(t?.providers??[]).filter(a=>a.models.length>0).map(a=>({label:a.id,items:a.models.map(a=>({value:a.id,label:a.id}))}));async function N(){let a=Number(z);if(!Number.isFinite(a)||a<=0)return I("limit must be a positive number");let b=Number(D);if(!Number.isFinite(b)||b<=0||b>100)return I("alert % must be 1–100");if("global"!==h&&!r.trim())return I(`pick a ${h}`);let c="global"===h?{type:"global"}:{type:h,id:r.trim()};K(!0),I("");try{let f=await d.adminApi.setBudget({scope:c,unit:x,limit:a,window:B,alert_at:b/100,note:F.trim()||void 0});if(!f.ok)return I(f.error??"could not save budget");e()}finally{K(!1)}}let O="mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft";if(null===h)return(0,b.jsxs)("div",{className:O,children:[(0,b.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:"Add a budget"}),(0,b.jsx)("p",{className:"mt-0.5 text-[12.5px] text-text-muted",children:"Pick what this budget caps — the rest is one short form."})]}),(0,b.jsx)("button",{type:"button",onClick:f,className:"flex-none text-text-subtle hover:text-text","aria-label":"Cancel",children:(0,b.jsx)(j.Icon,{name:"close",size:18})})]}),(0,b.jsx)("div",{className:"mt-4 grid gap-3 sm:grid-cols-3",children:o.map(a=>(0,b.jsxs)("button",{type:"button",onClick:()=>{q(a.id),s("")},className:"group flex items-start gap-3 rounded-brand-lg border border-border bg-bg p-4 text-left transition-colors hover:border-accent hover:bg-accent-soft",children:[(0,b.jsx)("span",{className:"flex h-10 w-10 flex-none items-center justify-center rounded-brand bg-surface-2 text-text-muted group-hover:text-accent",children:(0,b.jsx)(j.Icon,{name:a.icon,size:20})}),(0,b.jsxs)("span",{className:"min-w-0",children:[(0,b.jsx)("span",{className:"block text-[13.5px] font-semibold text-text",children:a.label}),(0,b.jsx)("span",{className:"mt-1 block text-[11.5px] text-text-muted",children:a.hint})]})]},a.id))})]});let P=o.find(a=>a.id===h);return(0,b.jsxs)("div",{className:O,children:[(0,b.jsxs)("div",{className:"mb-4 flex items-center gap-2.5 border-b border-border-subtle pb-4",children:[(0,b.jsx)("span",{className:"flex h-8 w-8 items-center justify-center rounded-brand bg-surface-2 text-text-muted",children:(0,b.jsx)(j.Icon,{name:P.icon,size:17})}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"text-[13.5px] font-semibold text-text",children:g?"Edit budget":P.label}),(0,b.jsx)("div",{className:"tnum text-[11px] text-text-subtle",children:"global"===h?"whole gateway":`${h} \xb7 ${g?a.label:r||"—"}`})]}),g?null:(0,b.jsxs)("button",{type:"button",onClick:()=>{q(null),I("")},className:"ml-auto inline-flex items-center gap-1 text-[12px] text-text-subtle hover:text-text",children:[(0,b.jsx)(j.Icon,{name:"arrow_back",size:14})," change scope"]})]}),(0,b.jsxs)("div",{className:"space-y-3",children:[!g&&"global"!==h&&(0,b.jsx)(n,{label:"provider"===h?"Provider":"model"===h?"Model":"API key",children:(0,b.jsxs)("button",{type:"button",onClick:()=>w(!0),className:"flex w-full items-center justify-between rounded-brand border border-border bg-bg px-3 py-2 text-left text-[13px] transition-colors hover:border-accent",children:[(0,b.jsx)("span",{className:r?"text-text":"text-text-subtle",children:r||("provider"===h?"Choose a provider…":"model"===h?"Choose a model…":"Choose an API key…")}),(0,b.jsx)(j.Icon,{name:"search",size:15,className:"text-text-subtle"})]})}),(0,b.jsx)(n,{label:"Unit",children:(0,b.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,b.jsx)("button",{type:"button",onClick:()=>y("usd"),className:m("usd"===x),children:"USD"}),(0,b.jsx)("button",{type:"button",onClick:()=>y("tokens"),className:m("tokens"===x),children:"Tokens"})]})}),(0,b.jsx)(i.Field,{label:"Limit",hint:"usd"===x?"$":"tokens",children:(0,b.jsx)(i.Input,{value:z,onChange:a=>A(a.target.value),inputMode:"decimal",placeholder:"usd"===x?"50.00":"1000000"})}),(0,b.jsx)(n,{label:"Window",children:(0,b.jsx)("div",{className:"flex flex-wrap gap-2",children:l.map(a=>(0,b.jsx)("button",{type:"button",onClick:()=>C(a),className:m(B===a),children:a},a))})}),(0,b.jsxs)(n,{label:"Alert at",children:[(0,b.jsxs)("div",{className:"flex items-center gap-3",children:[(0,b.jsx)("input",{type:"range",min:0,max:100,step:1,value:Math.max(0,Math.min(100,Number(D)||0)),onChange:a=>E(a.target.value),className:"range-accent flex-1",style:{background:`linear-gradient(to right, var(--color-accent) ${Math.max(0,Math.min(100,Number(D)||0))}%, var(--color-surface-2) ${Math.max(0,Math.min(100,Number(D)||0))}%)`},"aria-label":"Alert threshold percent"}),(0,b.jsxs)("div",{className:"relative w-16 flex-none",children:[(0,b.jsx)(i.Input,{value:D,onChange:a=>{let b=a.target.value.replace(/[^\d]/g,"");if(""===b)return E("");E(String(Math.max(0,Math.min(100,Number(b)))))},inputMode:"numeric",className:"pr-5 text-center tnum","aria-label":"Alert threshold percent (type)"}),(0,b.jsx)("span",{className:"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[12px] text-text-subtle",children:"%"})]})]}),(0,b.jsx)("p",{className:"text-[11px] text-text-subtle",children:"Warn once spend crosses this share of the limit."})]}),(0,b.jsx)(i.Field,{label:"Note",hint:"optional",children:(0,b.jsx)(i.Input,{value:F,onChange:a=>G(a.target.value),maxLength:200,placeholder:"e.g. client X cap"})})]}),H&&(0,b.jsx)("div",{className:"mt-2 text-[12px] text-danger",children:H}),(0,b.jsxs)("div",{className:"mt-4 flex justify-end gap-2",children:[(0,b.jsx)(i.Button,{type:"button",variant:"ghost",onClick:f,children:"Cancel"}),(0,b.jsx)(i.Button,{type:"button",disabled:J,onClick:N,children:J?"Saving…":g?"Save changes":"Add budget"})]}),v&&"global"!==h&&(0,b.jsx)(k.ModelPicker,{title:"provider"===h?"Select a provider":"Select a model",note:`Click a ${h} to scope this budget to it.`,searchPlaceholder:"provider"===h?"Search providers…":"Search models…",groups:"provider"===h?L:M,selected:r?[r]:[],onToggle:a=>{s(a),w(!1)},onClose:()=>w(!1),showThinkingHint:"model"===h})]})}a.s(["BudgetTracker",0,function(){let[a,k]=(0,c.useState)([]),[l,m]=(0,c.useState)([]),[n,o]=(0,c.useState)(!1),[q,r]=(0,c.useState)({open:!1,initial:null}),[s,t]=(0,c.useState)(""),u=()=>{d.adminApi.budgets().then(a=>{a.ok?k(a.data?.budgets??[]):t(a.error??"could not reach the gateway"),o(!0)}),d.adminApi.keysUsage().then(a=>{a.ok&&m(a.data?.keys??[])})};return((0,c.useEffect)(()=>{u()},[]),s)?(0,b.jsx)(h.Empty,{children:s}):n?(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6",children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Budgets"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Spend caps (USD or tokens) with live reset countdowns."})]}),(0,b.jsxs)("div",{className:"mb-6",children:[(0,b.jsxs)("div",{className:"mb-3 flex items-center justify-between",children:[(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Overall"}),!q.open&&(0,b.jsxs)(i.Button,{onClick:()=>r({open:!0,initial:null}),children:[(0,b.jsx)(j.Icon,{name:"add",size:16})," Add budget"]})]}),q.open&&(0,b.jsx)(p,{initial:q.initial,onSaved:()=>{r({open:!1,initial:null}),u()},onCancel:()=>r({open:!1,initial:null})},q.initial?.key??"new"),0===a.filter(a=>"key"!==a.scope.type).length?!q.open&&(0,b.jsx)(h.Empty,{children:"No budgets yet. Add one to cap spend globally, per provider, or per model."}):(0,b.jsx)("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:a.filter(a=>"key"!==a.scope.type).map(a=>(0,b.jsx)(f.RichCard,{header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(f.CardTitle,{title:a.label,sub:`${a.scope.type} \xb7 ${a.window}`}),(0,b.jsx)(e.Badge,{tone:a.exhausted?"down":a.alert?"warn":"live",children:a.exhausted?"exhausted":a.alert?"alert":"active"})]}),children:(0,b.jsxs)("div",{className:"space-y-2.5",children:[a.note&&(0,b.jsx)("p",{className:"text-[12px] text-text-muted",children:a.note}),(0,b.jsx)("div",{className:"h-1.5 overflow-hidden rounded-full bg-surface-2",children:(0,b.jsx)("div",{className:`h-full rounded-full transition-all ${a.exhausted?"bg-danger":a.alert?"bg-warning":"bg-accent"}`,style:{width:`${Math.min(100,Math.round(100*a.pct))}%`}})}),(0,b.jsxs)("div",{className:"flex items-center justify-between text-[12px]",children:[(0,b.jsxs)("span",{className:"tnum text-text-muted",children:["usd"===a.unit?`$${a.spent.toFixed(2)} / $${a.limit.toFixed(2)}`:`${h.fmt.compact(a.spent)} / ${h.fmt.compact(a.limit)} tokens`,null!=a.est_converse?"usd"===a.unit?` \xb7 ~${h.fmt.compact(a.est_converse)} tok`:` \xb7 ~$${a.est_converse.toFixed(2)}`:" · —"]}),(0,b.jsx)(g.CooldownTimer,{ms:a.reset_in_ms,tone:"muted",icon:"restart_alt",keepZero:!0})]}),(0,b.jsxs)("div",{className:"flex items-center gap-2 border-t border-border-subtle pt-2.5",children:[(0,b.jsxs)(i.Button,{variant:"ghost",className:"px-2.5 py-1 text-[12px]",onClick:()=>r({open:!0,initial:a}),children:[(0,b.jsx)(j.Icon,{name:"edit",size:14})," Edit"]}),(0,b.jsxs)(i.Button,{variant:"danger",className:"px-2.5 py-1 text-[12px]",onClick:async()=>{let b=await d.adminApi.clearBudget(a.key);b.ok||t(b.error??"could not remove budget"),u()},children:[(0,b.jsx)(j.Icon,{name:"delete",size:14})," Remove"]})]})]})},a.key))})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("h2",{className:"mb-3 text-[15px] font-semibold text-text",children:"Keys"}),0===l.length?(0,b.jsx)(h.Empty,{children:"No gateway keys yet. Add one on the Endpoint page."}):(0,b.jsx)("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:l.map(a=>(0,b.jsx)(f.RichCard,{header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(f.CardTitle,{title:a.name,sub:a.budget?`key \xb7 ${a.budget.window}`:"key · no limit"}),a.expires&&Date.now()>a.expires?(0,b.jsx)(e.Badge,{tone:"down",children:"expired"}):a.budget?.exhausted?(0,b.jsx)(e.Badge,{tone:"down",children:"exhausted"}):(0,b.jsx)(e.Badge,{tone:"live",children:"active"})]}),children:(0,b.jsxs)("div",{className:"space-y-2.5",children:[a.budget?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("div",{className:"h-1.5 overflow-hidden rounded-full bg-surface-2",children:(0,b.jsx)("div",{className:`h-full rounded-full transition-all ${a.budget.exhausted?"bg-danger":a.budget.alert?"bg-warning":"bg-accent"}`,style:{width:`${Math.min(100,Math.round(100*a.budget.pct))}%`}})}),(0,b.jsxs)("div",{className:"flex items-center justify-between text-[12px]",children:[(0,b.jsx)("span",{className:"tnum text-text-muted",children:"usd"===a.budget.unit?`$${a.budget.spent.toFixed(2)} / $${a.budget.limit.toFixed(2)}`:`${h.fmt.compact(a.budget.spent)} / ${h.fmt.compact(a.budget.limit)} tokens`}),(0,b.jsx)(g.CooldownTimer,{ms:a.budget.reset_in_ms,tone:"muted",icon:"restart_alt",keepZero:!0})]})]}):(0,b.jsxs)("div",{className:"flex items-center justify-between text-[12px]",children:[(0,b.jsxs)("span",{className:"tnum text-text-muted",children:["$",a.spent.toFixed(2)," spent"]}),(0,b.jsx)("span",{className:"text-text-subtle",children:"no limit"})]}),(0,b.jsx)("div",{className:"text-[11px] text-text-subtle",children:a.expires?`expires ${h.fmt.date(a.expires)}`:"no expiry"})]})},a.fingerprint))})]})]}):(0,b.jsx)(h.Empty,{children:"Loading..."})}],58002)}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=src_components_BudgetTracker_tsx_1-xevea._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/BudgetTracker.tsx","../../../../src/components/BudgetForm.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { adminApi } from \"@/lib/client\";\nimport { Badge } from \"@/components/Badge\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { CooldownTimer } from \"@/components/CooldownTimer\";\nimport { fmt, Empty } from \"@/components/ui\";\nimport { BudgetForm } from \"@/components/BudgetForm\";\nimport { Button } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport type { BudgetStatus, KeyUsageRow } from \"@/lib/gateway\";\n\n/**\n * Budget Tracker — scoped spend budgets (global / per-provider / per-model /\n * per-key) with an Add / Edit / Remove flow: consumption vs limit, a fill bar,\n * and a live reset countdown.\n */\nexport function BudgetTracker() {\n const [budgets, setBudgets] = useState<BudgetStatus[]>([]);\n const [keys, setKeys] = useState<KeyUsageRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [form, setForm] = useState<{ open: boolean; initial: BudgetStatus | null }>({ open: false, initial: null });\n const [error, setError] = useState(\"\");\n\n const refresh = () => {\n void adminApi.budgets().then((r) => {\n if (!r.ok) setError(r.error ?? \"could not reach the gateway\");\n else { setBudgets(r.data?.budgets ?? []); }\n setLoaded(true);\n });\n void adminApi.keysUsage().then((r) => { if (r.ok) setKeys(r.data?.keys ?? []); });\n };\n\n useEffect(() => { refresh(); }, []);\n\n if (error) return <Empty>{error}</Empty>;\n if (!loaded) return <Empty>Loading...</Empty>;\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Budgets</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">\n Spend caps (USD or tokens) with live reset countdowns.\n </p>\n </div>\n\n {/* -- Budgets -- */}\n <div className=\"mb-6\">\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-[15px] font-semibold text-text\">Overall</h2>\n {!form.open && (\n <Button onClick={() => setForm({ open: true, initial: null })}>\n <Icon name=\"add\" size={16} /> Add budget\n </Button>\n )}\n </div>\n\n {form.open && (\n <BudgetForm\n key={form.initial?.key ?? \"new\"}\n initial={form.initial}\n onSaved={() => { setForm({ open: false, initial: null }); refresh(); }}\n onCancel={() => setForm({ open: false, initial: null })}\n />\n )}\n\n {budgets.filter((b) => b.scope.type !== \"key\").length === 0 ? (\n !form.open && <Empty>No budgets yet. Add one to cap spend globally, per provider, or per model.</Empty>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {budgets.filter((b) => b.scope.type !== \"key\").map((b) => (\n <RichCard\n key={b.key}\n header={\n <>\n <CardTitle title={b.label} sub={`${b.scope.type} · ${b.window}`} />\n <Badge tone={b.exhausted ? \"down\" : b.alert ? \"warn\" : \"live\"}>\n {b.exhausted ? \"exhausted\" : b.alert ? \"alert\" : \"active\"}\n </Badge>\n </>\n }\n >\n <div className=\"space-y-2.5\">\n {b.note && <p className=\"text-[12px] text-text-muted\">{b.note}</p>}\n <div className=\"h-1.5 overflow-hidden rounded-full bg-surface-2\">\n <div\n className={`h-full rounded-full transition-all ${b.exhausted ? \"bg-danger\" : b.alert ? \"bg-warning\" : \"bg-accent\"}`}\n style={{ width: `${Math.min(100, Math.round(b.pct * 100))}%` }}\n />\n </div>\n <div className=\"flex items-center justify-between text-[12px]\">\n <span className=\"tnum text-text-muted\">\n {b.unit === \"usd\"\n ? `$${b.spent.toFixed(2)} / $${b.limit.toFixed(2)}`\n : `${fmt.compact(b.spent)} / ${fmt.compact(b.limit)} tokens`}\n {b.est_converse != null\n ? b.unit === \"usd\" ? ` · ~${fmt.compact(b.est_converse)} tok` : ` · ~$${b.est_converse.toFixed(2)}`\n : \" · —\"}\n </span>\n <CooldownTimer ms={b.reset_in_ms} tone=\"muted\" icon=\"restart_alt\" keepZero />\n </div>\n <div className=\"flex items-center gap-2 border-t border-border-subtle pt-2.5\">\n <Button variant=\"ghost\" className=\"px-2.5 py-1 text-[12px]\" onClick={() => setForm({ open: true, initial: b })}>\n <Icon name=\"edit\" size={14} /> Edit\n </Button>\n <Button\n variant=\"danger\"\n className=\"px-2.5 py-1 text-[12px]\"\n onClick={async () => { const r = await adminApi.clearBudget(b.key); if (!r.ok) setError(r.error ?? \"could not remove budget\"); refresh(); }}\n >\n <Icon name=\"delete\" size={14} /> Remove\n </Button>\n </div>\n </div>\n </RichCard>\n ))}\n </div>\n )}\n </div>\n\n {/* -- Keys -- */}\n <div>\n <h2 className=\"mb-3 text-[15px] font-semibold text-text\">Keys</h2>\n {keys.length === 0 ? (\n <Empty>No gateway keys yet. Add one on the Endpoint page.</Empty>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {keys.map((k) => (\n <RichCard\n key={k.fingerprint}\n header={\n <>\n <CardTitle title={k.name} sub={k.budget ? `key · ${k.budget.window}` : \"key · no limit\"} />\n {k.expires && Date.now() > k.expires ? (\n <Badge tone=\"down\">expired</Badge>\n ) : k.budget?.exhausted ? (\n <Badge tone=\"down\">exhausted</Badge>\n ) : (\n <Badge tone=\"live\">active</Badge>\n )}\n </>\n }\n >\n <div className=\"space-y-2.5\">\n {k.budget ? (\n <>\n <div className=\"h-1.5 overflow-hidden rounded-full bg-surface-2\">\n <div\n className={`h-full rounded-full transition-all ${k.budget.exhausted ? \"bg-danger\" : k.budget.alert ? \"bg-warning\" : \"bg-accent\"}`}\n style={{ width: `${Math.min(100, Math.round(k.budget.pct * 100))}%` }}\n />\n </div>\n <div className=\"flex items-center justify-between text-[12px]\">\n <span className=\"tnum text-text-muted\">\n {k.budget.unit === \"usd\"\n ? `$${k.budget.spent.toFixed(2)} / $${k.budget.limit.toFixed(2)}`\n : `${fmt.compact(k.budget.spent)} / ${fmt.compact(k.budget.limit)} tokens`}\n </span>\n <CooldownTimer ms={k.budget.reset_in_ms} tone=\"muted\" icon=\"restart_alt\" keepZero />\n </div>\n </>\n ) : (\n <div className=\"flex items-center justify-between text-[12px]\">\n <span className=\"tnum text-text-muted\">${k.spent.toFixed(2)} spent</span>\n <span className=\"text-text-subtle\">no limit</span>\n </div>\n )}\n <div className=\"text-[11px] text-text-subtle\">\n {k.expires ? `expires ${fmt.date(k.expires)}` : \"no expiry\"}\n </div>\n </div>\n </RichCard>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { adminApi } from \"@/lib/client\";\nimport { Button, Input, Field } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { ModelPicker, type ModelGroup } from \"@/components/ModelPicker\";\nimport type { BudgetStatus, ModelsPayload } from \"@/lib/gateway\";\n\nconst WINDOWS = [\"5h\", \"24h\", \"7day\", \"30day\"] as const;\ntype ScopeType = \"global\" | \"provider\" | \"model\";\n\n/** Segment-pill button style — selected = accent, matches the Unit toggle. */\nconst pill = (active: boolean): string =>\n `rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${\n active ? \"bg-accent/12 text-accent\" : \"bg-surface-2 text-text-muted hover:text-text\"\n }`;\n\n/**\n * A labelled field group for BUTTON controls. Unlike `Field` (a <label>, which\n * forwards a pointer click to its first control and would swallow pill clicks),\n * this is a plain <div> so each pill button receives its own click.\n */\nfunction Group({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">{label}</span>\n {children}\n </div>\n );\n}\n\nconst SCOPES: { id: ScopeType; icon: string; label: string; hint: string }[] = [\n { id: \"global\", icon: \"public\", label: \"Global\", hint: \"Cap total spend across the whole gateway.\" },\n { id: \"provider\", icon: \"dns\", label: \"Per provider\", hint: \"Cap one provider's spend.\" },\n { id: \"model\", icon: \"neurology\", label: \"Per model\", hint: \"Cap one upstream model's spend.\" },\n];\n\n/**\n * Inline Add / Edit panel for a scoped budget — same shape as the \"Add a\n * provider\" flow: step 1 picks the scope (card grid, add only), step 2 is the\n * field set. Editing jumps straight to step 2 with the scope locked (the scope\n * is the budget's identity); every other field stays editable.\n */\nexport function BudgetForm({\n initial,\n onSaved,\n onCancel,\n}: {\n initial: BudgetStatus | null;\n onSaved: () => void;\n onCancel: () => void;\n}) {\n const editing = initial !== null;\n const [scopeType, setScopeType] = useState<ScopeType | null>(\n initial && initial.scope.type !== \"key\" ? initial.scope.type : null,\n );\n const [scopeId, setScopeId] = useState(\n initial && initial.scope.type !== \"global\" && initial.scope.type !== \"key\" ? initial.scope.id : \"\",\n );\n const [catalog, setCatalog] = useState<ModelsPayload | null>(null);\n const [pickerOpen, setPickerOpen] = useState(false);\n const [unit, setUnit] = useState<\"usd\" | \"tokens\">(initial?.unit ?? \"usd\");\n const [limit, setLimit] = useState(String(initial?.limit ?? \"\"));\n const [window, setWindow] = useState<(typeof WINDOWS)[number]>(initial?.window ?? \"30day\");\n const [alertAt, setAlertAt] = useState(initial ? String(Math.round(initial.alert_at * 100)) : \"80\");\n const [note, setNote] = useState(initial?.note ?? \"\");\n const [error, setError] = useState(\"\");\n const [saving, setSaving] = useState(false);\n\n useEffect(() => {\n void adminApi.models().then((r) => { if (r.ok && r.data) setCatalog(r.data); });\n }, []);\n\n const providerGroups: ModelGroup[] = catalog?.providers.length\n ? [{ label: \"Providers\", items: catalog.providers.map((p) => ({ value: p.id, label: p.id })) }]\n : [];\n // one entry per distinct upstream model id (a budget keys on usage.model), grouped by provider.\n const modelGroups: ModelGroup[] = (catalog?.providers ?? [])\n .filter((p) => p.models.length > 0)\n .map((p) => ({ label: p.id, items: p.models.map((m) => ({ value: m.id, label: m.id })) }));\n const scopeIdLabel = scopeId;\n\n async function save() {\n const limitNum = Number(limit);\n if (!Number.isFinite(limitNum) || limitNum <= 0) return setError(\"limit must be a positive number\");\n const alertPct = Number(alertAt);\n if (!Number.isFinite(alertPct) || alertPct <= 0 || alertPct > 100) return setError(\"alert % must be 1–100\");\n if (scopeType !== \"global\" && !scopeId.trim()) return setError(`pick a ${scopeType}`);\n const scope =\n scopeType === \"global\" ? { type: \"global\" as const } : { type: scopeType!, id: scopeId.trim() };\n setSaving(true);\n setError(\"\");\n try {\n const r = await adminApi.setBudget({ scope, unit, limit: limitNum, window, alert_at: alertPct / 100, note: note.trim() || undefined });\n if (!r.ok) return setError(r.error ?? \"could not save budget\");\n onSaved();\n } finally {\n setSaving(false);\n }\n }\n\n const panel = \"mb-5 rounded-brand-lg border border-border bg-surface p-5 shadow-soft\";\n\n // step 1 (add only): pick the scope.\n if (scopeType === null) {\n return (\n <div className={panel}>\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-[14px] font-semibold text-text\">Add a budget</h2>\n <p className=\"mt-0.5 text-[12.5px] text-text-muted\">Pick what this budget caps — the rest is one short form.</p>\n </div>\n <button type=\"button\" onClick={onCancel} 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-3\">\n {SCOPES.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n onClick={() => { setScopeType(s.id); setScopeId(\"\"); }}\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={s.icon} size={20} />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-[13.5px] font-semibold text-text\">{s.label}</span>\n <span className=\"mt-1 block text-[11.5px] text-text-muted\">{s.hint}</span>\n </span>\n </button>\n ))}\n </div>\n </div>\n );\n }\n\n const scopeMeta = SCOPES.find((s) => s.id === scopeType)!;\n\n // step 2: the field set.\n return (\n <div className={panel}>\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={scopeMeta.icon} size={17} />\n </span>\n <div>\n <div className=\"text-[13.5px] font-semibold text-text\">{editing ? \"Edit budget\" : scopeMeta.label}</div>\n <div className=\"tnum text-[11px] text-text-subtle\">\n {scopeType === \"global\" ? \"whole gateway\" : `${scopeType} · ${editing ? initial!.label : scopeIdLabel || \"—\"}`}\n </div>\n </div>\n {editing ? null : (\n <button\n type=\"button\"\n onClick={() => { setScopeType(null); setError(\"\"); }}\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 scope\n </button>\n )}\n </div>\n\n <div className=\"space-y-3\">\n {/* scope target — only when adding; editing locks the scope (shown in the header) */}\n {!editing && scopeType !== \"global\" && (\n <Group label={scopeType === \"provider\" ? \"Provider\" : scopeType === \"model\" ? \"Model\" : \"API key\"}>\n <button\n type=\"button\"\n onClick={() => setPickerOpen(true)}\n className=\"flex w-full items-center justify-between rounded-brand border border-border bg-bg px-3 py-2 text-left text-[13px] transition-colors hover:border-accent\"\n >\n <span className={scopeId ? \"text-text\" : \"text-text-subtle\"}>\n {scopeId ? scopeIdLabel : scopeType === \"provider\" ? \"Choose a provider…\" : scopeType === \"model\" ? \"Choose a model…\" : \"Choose an API key…\"}\n </span>\n <Icon name=\"search\" size={15} className=\"text-text-subtle\" />\n </button>\n </Group>\n )}\n\n <Group label=\"Unit\">\n <div className=\"flex flex-wrap gap-2\">\n <button type=\"button\" onClick={() => setUnit(\"usd\")} className={pill(unit === \"usd\")}>USD</button>\n <button type=\"button\" onClick={() => setUnit(\"tokens\")} className={pill(unit === \"tokens\")}>Tokens</button>\n </div>\n </Group>\n <Field label=\"Limit\" hint={unit === \"usd\" ? \"$\" : \"tokens\"}>\n <Input value={limit} onChange={(e) => setLimit(e.target.value)} inputMode=\"decimal\" placeholder={unit === \"usd\" ? \"50.00\" : \"1000000\"} />\n </Field>\n <Group label=\"Window\">\n <div className=\"flex flex-wrap gap-2\">\n {WINDOWS.map((w) => (\n <button key={w} type=\"button\" onClick={() => setWindow(w)} className={pill(window === w)}>{w}</button>\n ))}\n </div>\n </Group>\n <Group label=\"Alert at\">\n <div className=\"flex items-center gap-3\">\n <input\n type=\"range\"\n min={0}\n max={100}\n step={1}\n value={Math.max(0, Math.min(100, Number(alertAt) || 0))}\n onChange={(e) => setAlertAt(e.target.value)}\n className=\"range-accent flex-1\"\n style={{\n background: `linear-gradient(to right, var(--color-accent) ${Math.max(0, Math.min(100, Number(alertAt) || 0))}%, var(--color-surface-2) ${Math.max(0, Math.min(100, Number(alertAt) || 0))}%)`,\n }}\n aria-label=\"Alert threshold percent\"\n />\n <div className=\"relative w-16 flex-none\">\n <Input\n value={alertAt}\n onChange={(e) => {\n const v = e.target.value.replace(/[^\\d]/g, \"\");\n if (v === \"\") return setAlertAt(\"\");\n setAlertAt(String(Math.max(0, Math.min(100, Number(v)))));\n }}\n inputMode=\"numeric\"\n className=\"pr-5 text-center tnum\"\n aria-label=\"Alert threshold percent (type)\"\n />\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[12px] text-text-subtle\">%</span>\n </div>\n </div>\n <p className=\"text-[11px] text-text-subtle\">Warn once spend crosses this share of the limit.</p>\n </Group>\n <Field label=\"Note\" hint=\"optional\">\n <Input value={note} onChange={(e) => setNote(e.target.value)} maxLength={200} placeholder=\"e.g. client X cap\" />\n </Field>\n </div>\n\n {error && <div className=\"mt-2 text-[12px] text-danger\">{error}</div>}\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button type=\"button\" disabled={saving} onClick={save}>{saving ? \"Saving…\" : editing ? \"Save changes\" : \"Add budget\"}</Button>\n </div>\n\n {pickerOpen && scopeType !== \"global\" && (\n <ModelPicker\n title={scopeType === \"provider\" ? \"Select a provider\" : \"Select a model\"}\n note={`Click a ${scopeType} to scope this budget to it.`}\n searchPlaceholder={scopeType === \"provider\" ? \"Search providers…\" : \"Search models…\"}\n groups={scopeType === \"provider\" ? providerGroups : modelGroups}\n selected={scopeId ? [scopeId] : []}\n onToggle={(v) => { setScopeId(v); setPickerOpen(false); }}\n onClose={() => setPickerOpen(false)}\n showThinkingHint={scopeType === \"model\"}\n />\n )}\n </div>\n );\n}\n"],"names":["WINDOWS","pill","active","Group","label","children","className","SCOPES","id","icon","hint","BudgetForm","initial","onSaved","onCancel","editing","scopeType","setScopeType","scope","type","scopeId","setScopeId","catalog","setCatalog","pickerOpen","setPickerOpen","unit","setUnit","limit","setLimit","String","window","setWindow","alertAt","setAlertAt","Math","round","alert_at","note","setNote","error","setError","saving","setSaving","models","then","r","ok","data","providerGroups","providers","length","items","map","p","value","modelGroups","filter","m","scopeIdLabel","save","limitNum","Number","isFinite","alertPct","trim","setBudget","undefined","panel","onClick","name","size","s","scopeMeta","find","onChange","e","target","inputMode","placeholder","w","min","max","step","style","background","v","replace","maxLength","variant","disabled","title","searchPlaceholder","groups","selected","onToggle","onClose","showThinkingHint"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports=[8378,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(56173),e=a.i(2693),f=a.i(85732),g=a.i(7078),h=a.i(93026);function i({masked:a,reveal:d,className:e,align:f="inline"}){let[g,j]=(0,c.useState)(null),[k,l]=(0,c.useState)(!1),[m,n]=(0,c.useState)(!1),[o,p]=(0,c.useState)(!1);async function q(){if(k)return void l(!1);if(null===g){n(!0);let a=await d();if(n(!1),null===a)return;j(a)}l(!0)}let r=k&&null!==g?g:a;return(0,b.jsxs)("span",{className:`flex min-w-0 items-center gap-1.5${e?` ${e}`:""}`,children:[(0,b.jsx)("span",{className:`tnum truncate text-[12.5px] text-text${"right"===f?" flex-1":""}`,children:r}),k&&null!==g&&(0,b.jsx)("button",{type:"button",onClick:()=>{navigator.clipboard.writeText(g),p(!0),setTimeout(()=>p(!1),1200)},className:"flex-none text-text-subtle transition-colors hover:text-text","aria-label":"Copy key",children:(0,b.jsx)(h.Icon,{name:o?"check":"content_copy",size:14})}),(0,b.jsx)("button",{type:"button",onClick:q,disabled:m,className:"flex-none text-text-subtle transition-colors hover:text-text disabled:opacity-40","aria-label":k?"Hide key":"Show key",children:(0,b.jsx)(h.Icon,{name:m?"hourglass_empty":k?"visibility_off":"visibility",size:15})})]})}var j=a.i(58918),k=a.i(47444),l=a.i(73858);let m=["off","lite","full","ultra"],n=a=>`rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${a?"bg-accent/12 text-accent":"bg-surface-2 text-text-muted hover:text-text"}`,o={"24h":864e5,"7day":6048e5,"30day":2592e6};function p({ep:a,hr:i,refresh:j}){let k=a.headroom,[l,m]=(0,c.useState)(k.url),[n,o]=(0,c.useState)(""),[q,r]=(0,c.useState)(""),[t,u]=(0,c.useState)(null);async function v(a,b){o(a),r(""),u(null);let c=await b();o(""),c.ok||r(c.error??"action failed"),await j()}async function w(){o("check"),r(""),u(null);let a=await d.adminApi.headroomStatus();(o(""),await j(),a.ok&&a.data)?u(a.data.running?{ok:!0,text:`proxy is up at ${a.data.url}`}:{ok:!1,text:`no proxy responding at ${a.data.url}`}):u({ok:!1,text:a.error??"could not reach the gateway"})}return(0,c.useEffect)(()=>m(k.url),[k.url]),(0,b.jsx)(f.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(f.CardTitle,{title:"Headroom",sub:"external context-compression proxy"}),children:(0,b.jsxs)("div",{className:"space-y-4",children:[(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-[12px]",children:[(0,b.jsx)(e.Badge,{tone:i?.installed?"live":"neutral",children:i?.installed?"installed":"not installed"}),(0,b.jsx)(e.Badge,{tone:i?.running?"live":"warn",children:i?.running?"proxy running":"proxy down"}),(0,b.jsx)(e.Badge,{tone:i?.python?"info":"neutral",children:i?.python?`python ${i.python}`:"no python ≥3.10"}),i?.managedPid?(0,b.jsxs)("span",{className:"tnum text-text-subtle",children:["pid ",i.managedPid]}):null]}),(0,b.jsx)(s,{label:"Enable headroom",desc:"Compress the full context through the proxy before each request (fail-open if it's down).",on:k.enabled,busy:"enable"===n,onChange:a=>v("enable",()=>d.adminApi.setHeadroom({enabled:a}))}),(0,b.jsx)(s,{label:"Compress user messages",desc:"Also squeeze user turns, not just tool/assistant context.",on:k.compress_user_messages,busy:"cum"===n,onChange:a=>v("cum",()=>d.adminApi.setHeadroom({compress_user_messages:a}))}),(0,b.jsxs)("div",{className:"flex items-end gap-2",children:[(0,b.jsxs)("div",{className:"flex-1",children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Proxy URL"}),(0,b.jsx)(g.Input,{value:l,onChange:a=>m(a.target.value),placeholder:"http://localhost:8787",className:"font-mono text-[12.5px]"})]}),(0,b.jsx)(g.Button,{variant:"ghost",disabled:l.trim()===k.url||"url"===n,onClick:()=>v("url",()=>d.adminApi.setHeadroom({url:l.trim()})),children:"Save URL"})]}),(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,b.jsxs)(g.Button,{disabled:!i?.canStart||i?.running||"start"===n,onClick:()=>v("start",()=>d.adminApi.headroomStart()),children:[(0,b.jsx)(h.Icon,{name:"play_arrow",size:16})," ","start"===n?"Starting…":"Start proxy"]}),(0,b.jsxs)(g.Button,{variant:"danger",disabled:!i?.managedPid||"stop"===n,onClick:()=>v("stop",()=>d.adminApi.headroomStop()),children:[(0,b.jsx)(h.Icon,{name:"stop",size:16})," Stop"]}),(0,b.jsxs)(g.Button,{variant:"ghost",disabled:"check"===n,onClick:w,children:[(0,b.jsx)(h.Icon,{name:"sync",size:16})," ","check"===n?"Checking…":"Check"]}),i&&!i.installed&&(0,b.jsxs)("span",{className:"text-[11px] text-text-subtle",children:["Headroom isn’t installed. Get it from"," ",(0,b.jsx)("a",{href:"https://github.com/chopratejas/headroom",target:"_blank",rel:"noreferrer",className:"text-accent hover:underline",children:"chopratejas/headroom"})," ","(needs Python ≥ 3.10):"," ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"pipx install git+https://github.com/chopratejas/headroom"})," ","— then re-open this page."]}),i?.installed&&!i.localUrl&&(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"URL isn’t loopback — start that proxy yourself."})]}),q&&(0,b.jsx)("p",{className:"text-[12px] text-danger",children:q}),t&&(0,b.jsxs)("p",{className:`flex items-center gap-1 text-[12px] ${t.ok?"text-success":"text-danger"}`,children:[(0,b.jsx)(h.Icon,{name:t.ok?"check_circle":"error",size:14})," ",t.text]})]})})}function q({name:a,value:d,onClose:e}){let[f,i]=(0,c.useState)(!1);return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:e,children:(0,b.jsxs)("div",{className:"w-full max-w-md rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-1 flex items-center gap-2",children:[(0,b.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-accent",children:(0,b.jsx)(h.Icon,{name:"key",size:16})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Key created"})]}),(0,b.jsxs)("p",{className:"mb-3 text-[12px] text-text-muted",children:["Copy ",(0,b.jsx)("span",{className:"text-text",children:a})," now. You can reveal it again later from this page."]}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(d),i(!0),setTimeout(()=>i(!1),1500)},className:"flex w-full items-center justify-between gap-2 rounded-brand border border-border-subtle bg-bg px-3 py-2.5 text-left hover:border-text-subtle",children:[(0,b.jsx)("span",{className:"tnum truncate text-[12.5px] text-text",children:d}),(0,b.jsx)(h.Icon,{name:f?"check":"content_copy",size:15})]}),(0,b.jsx)("div",{className:"mt-4 flex justify-end",children:(0,b.jsx)(g.Button,{onClick:e,children:"Done"})})]})})}function r({label:a,value:d}){let[e,f]=(0,c.useState)(!1);return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,b.jsx)("span",{className:"text-text-subtle",children:a}),(0,b.jsxs)("button",{onClick:()=>{navigator.clipboard.writeText(d),f(!0),setTimeout(()=>f(!1),1200)},className:"flex items-center gap-1.5 rounded-brand border border-border-subtle px-2.5 py-1 tnum text-[12.5px] text-text hover:border-text-subtle",children:[d,(0,b.jsx)(h.Icon,{name:e?"check":"content_copy",size:13})]})]})}function s({label:a,desc:c,on:d,busy:e,onChange:f}){return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"text-[13px] font-semibold text-text",children:a}),(0,b.jsx)("div",{className:"text-[12px] text-text-muted",children:c})]}),(0,b.jsx)("button",{disabled:e,onClick:()=>f(!d),className:`relative h-6 w-11 flex-none rounded-full transition-colors ${d?"bg-accent":"bg-surface-3"}`,"aria-pressed":d,children:(0,b.jsx)("span",{className:`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-bg transition-transform ${d?"translate-x-5":"translate-x-0"}`})})]})}function t({label:a,desc:c,value:d,busy:f,onChange:g}){return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:a}),"off"!==d&&(0,b.jsx)(e.Badge,{tone:"info",children:d})]}),(0,b.jsx)("div",{className:"text-[12px] text-text-muted",children:c})]}),(0,b.jsx)("div",{className:"flex flex-none items-center gap-1 rounded-full border border-border bg-surface p-1",children:m.map(a=>(0,b.jsx)("button",{disabled:f,onClick:()=>g(a),className:`rounded-full px-2.5 py-1 text-[11.5px] font-medium transition-colors ${d===a?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:a},a))})]})}a.s(["EndpointView",0,function(){let[a,e]=(0,c.useState)(null),[m,u]=(0,c.useState)(""),[v,w]=(0,c.useState)(""),[x,y]=(0,c.useState)(""),[z,A]=(0,c.useState)(null),[B,C]=(0,c.useState)(null),[D,E]=(0,c.useState)(null),[F,G]=(0,c.useState)(null),[H,I]=(0,c.useState)(""),[J,K]=(0,c.useState)([]),[L,M]=(0,c.useState)(null),[N,O]=(0,c.useState)([]),[P,Q]=(0,c.useState)(""),[R,S]=(0,c.useState)("never"),[T,U]=(0,c.useState)(""),[V,W]=(0,c.useState)(""),[X,Y]=(0,c.useState)("30day"),[Z,$]=(0,c.useState)({}),[_,aa]=(0,c.useState)(!1),ab=(0,c.useCallback)(async()=>{let a=await d.adminApi.endpoint();a.ok?(u(""),e(a.data)):u(a.error??"could not reach the gateway")},[]),ac=(0,c.useCallback)(async()=>{let a=await d.adminApi.headroomStatus();a.ok&&E(a.data)},[]);if((0,c.useEffect)(()=>{ab(),ac(),(async()=>{try{let a=await fetch("/api/gw/admin/config");if(!a.ok)return;let b=await a.json(),c=[];for(let a of(b.models.length&&c.push({label:"Combos",items:b.models.map(a=>({value:a.alias,label:a.alias}))}),b.providers))a.models.length&&c.push({label:a.id,items:a.models.map(b=>({value:`${a.id}/${b.id}`,label:`${a.id}/${b.id}`}))});K(c)}catch{}})(),d.adminApi.budgets().then(a=>{if(!a.ok||!a.data)return;let b={};for(let c of a.data.budgets)"key"===c.scope.type&&(b[c.scope.id]={limit:c.limit,window:c.window});$(b)})},[ab,ac]),m)return(0,b.jsx)(j.Empty,{children:m});if(!a)return(0,b.jsx)(j.Empty,{children:"Loading…"});let ad=`http://127.0.0.1:${a.port}`;async function ae(a,b){w(a);let c=await b();w(""),c.ok?(u(""),await ab()):u(c.error??"action failed")}async function af(a,b){let c=(a||"Gateway key").trim();w("genkey");let e=await d.adminApi.addServerKey(b,c);(w(""),e.ok)?(u(""),y(""),A({key:b,name:c}),await ab()):u(e.error??"could not add key")}return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6",children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Endpoint & Key"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Gateway address, client keys, and the token-saver toggles."})]}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,b.jsxs)(f.RichCard,{header:(0,b.jsx)(f.CardTitle,{title:"Gateway URL",sub:"one endpoint for every client"}),children:[(0,b.jsx)("div",{className:"text-[13px]",children:(0,b.jsx)(r,{label:"Gateway URL",value:ad})}),(0,b.jsxs)("p",{className:"mt-3 text-[12px] text-text-subtle",children:["One gateway, both formats. Anthropic clients (Claude Code) use it as-is; OpenAI clients (opencode, Cursor, Codex) append ",(0,b.jsx)("span",{className:"tnum",children:"/v1"}),". The ",(0,b.jsx)("span",{className:"text-text-muted",children:"CLI Tools"})," ","page has copy-ready env per tool."]})]}),(0,b.jsxs)(f.RichCard,{header:(0,b.jsx)(f.CardTitle,{title:"Gateway keys",sub:`${a.keys.length} configured`}),children:[0===a.keys.length?(0,b.jsx)(j.Empty,{children:"No keys — auth is DISABLED (localhost only). Generate one below."}):(0,b.jsx)("div",{className:"space-y-1.5",children:a.keys.map((a,c)=>F===c?(0,b.jsxs)("div",{className:"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5",children:[(0,b.jsx)(g.Input,{value:H,onChange:a=>I(a.target.value),placeholder:"key name (e.g. Claude Code)"}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>G(null),children:"Cancel"}),(0,b.jsx)(g.Button,{disabled:v===`editkey${c}`,onClick:()=>ae(`editkey${c}`,async()=>{let a=await d.adminApi.editServerKey(c,H.trim());return a.ok&&G(null),a}),children:"Save"})]})]},c):(0,b.jsxs)("div",{className:"space-y-0 rounded-brand border border-border-subtle",children:[(0,b.jsxs)("div",{className:"flex items-center justify-between gap-2 px-3 py-2",children:[(0,b.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[a.name&&(0,b.jsx)("span",{className:"text-[12px] font-semibold text-text-muted",children:a.name}),(0,b.jsx)(i,{masked:a.key,reveal:async()=>{let a=await d.adminApi.revealServerKey(c);return a.ok?a.data?.key??null:null}}),(0,b.jsxs)("div",{className:"mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-text-subtle",children:[(0,b.jsx)("span",{children:a.models?.length?`${a.models.length} model${a.models.length>1?"s":""}`:"all models"}),(0,b.jsx)("span",{children:"·"}),(0,b.jsx)("span",{children:a.rpm?`${a.rpm}/min`:"no rate limit"}),(0,b.jsx)("span",{children:"·"}),(0,b.jsx)("span",{children:a.expires?Date.now()>a.expires?(0,b.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${j.fmt.date(a.expires)}`:"no expiry"})]})]}),(0,b.jsxs)("div",{className:"flex flex-none items-center gap-1",children:[(0,b.jsx)("button",{onClick:()=>{M(c),O(a.models??[]),Q(a.rpm?String(a.rpm):""),S(a.expires?"keep":"never"),U("");let b=Z[a.fingerprint];W(b?String(b.limit):""),Y(b?.window??"30day")},className:"text-text-subtle hover:text-text","aria-label":"Edit key scope",title:"Model allowlist + rate limit + budget + expiry",children:(0,b.jsx)(h.Icon,{name:"tune",size:15})}),(0,b.jsx)("button",{onClick:()=>{G(c),I(a.name??"")},className:"text-text-subtle hover:text-text","aria-label":"Rename key",title:"Rename key",children:(0,b.jsx)(h.Icon,{name:"edit",size:15})}),(0,b.jsx)("button",{onClick:()=>C({i:c,label:a.name||a.key}),className:"text-text-subtle hover:text-danger","aria-label":"Remove key",children:(0,b.jsx)(h.Icon,{name:"delete",size:16})})]})]}),L===c&&(0,b.jsxs)("div",{className:"space-y-2 border-t border-border-subtle bg-accent-soft/40 px-3 py-2.5",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Allowed models"}),(0,b.jsx)("div",{className:"flex flex-wrap items-center gap-1.5",children:0===N.length?(0,b.jsx)("span",{className:"text-[12px] text-text-subtle",children:"All models (unrestricted)"}):N.map(a=>(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded border border-accent bg-accent-soft px-2 py-0.5 text-[12px] text-accent",children:[(0,b.jsx)("span",{className:"tnum",children:a}),(0,b.jsx)("button",{onClick:()=>O(b=>b.filter(b=>b!==a)),className:"hover:text-danger","aria-label":`Remove ${a}`,children:(0,b.jsx)(h.Icon,{name:"close",size:12})})]},a))}),(0,b.jsxs)(g.Button,{type:"button",variant:"ghost",className:"mt-1.5",onClick:()=>aa(!0),children:[(0,b.jsx)(h.Icon,{name:"add",size:15})," Pick models"]})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Rate limit"}),(0,b.jsx)(g.Input,{inputMode:"numeric",value:P,onChange:a=>Q(a.target.value.replace(/[^\d]/g,"")),placeholder:"req/min (blank = unlimited)"})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Access expiry"}),a.expires&&(0,b.jsxs)("div",{className:"mb-1.5 text-[11px] text-text-subtle",children:["currently ",Date.now()>a.expires?(0,b.jsx)("span",{className:"text-danger",children:"expired"}):`expires ${j.fmt.date(a.expires)}`]}),(0,b.jsx)("div",{className:"flex flex-wrap gap-1",children:(a.expires?["keep","never","24h","7day","30day","custom"]:["never","24h","7day","30day","custom"]).map(a=>(0,b.jsx)("button",{type:"button",onClick:()=>S(a),className:n(R===a),children:"never"===a?"no expiry":a},a))}),"custom"===R&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,b.jsx)(g.Input,{inputMode:"numeric",value:T,onChange:a=>U(a.target.value.replace(/[^\d]/g,"")),placeholder:"days",className:"w-24"}),(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"days from now"})]})]}),(0,b.jsxs)("div",{children:[(0,b.jsx)("div",{className:"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:"Spend cap (USD)"}),(0,b.jsx)(g.Input,{inputMode:"decimal",value:V,onChange:a=>W(a.target.value.replace(/[^\d.]/g,"")),placeholder:"USD (blank = no cap)"}),V&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-1.5",children:[(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"resets every"}),["5h","24h","7day","30day"].map(a=>(0,b.jsx)("button",{type:"button",onClick:()=>Y(a),className:n(X===a),children:a},a))]})]}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(g.Button,{variant:"ghost",onClick:()=>M(null),children:"Cancel"}),(0,b.jsx)(g.Button,{disabled:v===`scope${c}`,onClick:()=>ae(`scope${c}`,async()=>{let b="keep"===R?void 0:"never"===R?null:"custom"===R?T?Date.now()+864e5*Number(T):null:Date.now()+o[R],e=await d.adminApi.setServerKeyScope(c,{models:N,rpm:P?Number(P):null,expires:b});if(!e.ok)return e;let f=V?Number(V):0;return f>0?await d.adminApi.setBudget({scope:{type:"key",id:a.fingerprint},unit:"usd",limit:f,window:X}):Z[a.fingerprint]&&await d.adminApi.clearBudget(`key:${a.fingerprint}`),M(null),e}),children:"Save"})]})]})]},c))}),(0,b.jsxs)("div",{className:"mt-3 space-y-2",children:[(0,b.jsxs)("div",{className:"flex gap-2",children:[(0,b.jsx)(g.Input,{value:x,onChange:a=>y(a.target.value),placeholder:"key name (e.g. Claude Code)",className:"flex-1"}),(0,b.jsxs)(g.Button,{disabled:"genkey"===v,onClick:()=>{let a,b;return af(x,(a=new Uint8Array(24),crypto.getRandomValues(a),b=Array.from(a,a=>a.toString(16).padStart(2,"0")).join(""),`aig-${b}`))},children:[(0,b.jsx)(h.Icon,{name:"add",size:16})," ","genkey"===v?"Adding…":"Add key"]})]}),(0,b.jsx)("p",{className:"text-[11px] text-text-subtle",children:"Name it, then click Add key — a key is generated and shown once. Configure its limits after."})]})]}),(0,b.jsx)(f.RichCard,{className:"lg:col-span-2",header:(0,b.jsx)(f.CardTitle,{title:"Token savers",sub:"applied to every request before routing"}),children:(0,b.jsxs)("div",{className:"space-y-4",children:[(0,b.jsx)(s,{label:"RTK",desc:"Compress bulky tool_result blocks (diffs, grep, listings) in the request.",on:a.rtk,busy:"rtk"===v,onChange:a=>ae("rtk",()=>d.adminApi.setRtk(a))}),(0,b.jsx)(t,{label:"Caveman",desc:"Terser model output — drops filler, keeps substance.",value:a.caveman,busy:"caveman"===v,onChange:a=>ae("caveman",()=>d.adminApi.setCaveman(a))}),(0,b.jsx)(t,{label:"Ponytail",desc:"Minimal, YAGNI code style — deletion over addition.",value:a.ponytail,busy:"ponytail"===v,onChange:a=>ae("ponytail",()=>d.adminApi.setPonytail(a))})]})}),(0,b.jsx)(p,{ep:a,hr:D,refresh:async()=>{await ab(),await ac()}})]}),z&&(0,b.jsx)(q,{name:z.name,value:z.key,onClose:()=>A(null)}),B&&(0,b.jsx)(l.ConfirmModal,{title:"Remove gateway key",message:`Delete "${B.label}"? Any client using this key stops working immediately.`,confirmLabel:"Remove",busy:v===`rmkey${B.i}`,onCancel:()=>C(null),onConfirm:()=>{let a=B.i;ae(`rmkey${a}`,()=>d.adminApi.removeServerKey(a)).then(()=>C(null))}}),_&&(0,b.jsx)(k.ModelPicker,{title:"Allowed models",note:"Pick the models this key may call. None = all.",groups:J,selected:N,onToggle:a=>O(b=>b.includes(a)?b.filter(b=>b!==a):[...b,a]),onClose:()=>aa(!1),showThinkingHint:!1})]})}],8378)}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=src_components_EndpointView_tsx_0awdzb5._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/EndpointView.tsx","../../../../src/components/KeyReveal.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useCallback } from \"react\";\nimport { adminApi } from \"@/lib/client\";\nimport { Badge } from \"@/components/Badge\";\nimport { RichCard, CardTitle } from \"@/components/RichCard\";\nimport { Button, Input } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\nimport { KeyReveal } from \"@/components/KeyReveal\";\nimport { Empty, fmt } from \"@/components/ui\";\nimport { ModelPicker, type ModelGroup } from \"@/components/ModelPicker\";\nimport { ConfirmModal } from \"@/components/ConfirmModal\";\nimport type { EndpointPayload, HeadroomStatusReply, InjectLevel, MaskedConfig } from \"@/lib/gateway\";\n\nconst LEVELS: InjectLevel[] = [\"off\", \"lite\", \"full\", \"ultra\"];\n\n/** Segment-pill style — matches the Budgets page pills. */\nconst pill = (active: boolean): string =>\n `rounded-brand px-3 py-1.5 text-[13px] font-medium transition-colors ${\n active ? \"bg-accent/12 text-accent\" : \"bg-surface-2 text-text-muted hover:text-text\"\n }`;\n\nconst DAY_MS = 86_400_000;\nconst EXPIRY_MS: Record<\"24h\" | \"7day\" | \"30day\", number> = {\n \"24h\": DAY_MS,\n \"7day\": 7 * DAY_MS,\n \"30day\": 30 * DAY_MS,\n};\n\n/** Generate a random gateway key client-side (aigetwey's one-click create). */\nfunction generateKey(): string {\n const bytes = new Uint8Array(24);\n crypto.getRandomValues(bytes);\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return `aig-${hex}`;\n}\n\nexport function EndpointView() {\n const [ep, setEp] = useState<EndpointPayload | null>(null);\n const [error, setError] = useState(\"\");\n const [busy, setBusy] = useState(\"\");\n const [keyName, setKeyName] = useState(\"\");\n const [created, setCreated] = useState<{ key: string; name: string } | null>(null);\n const [pendingDelKey, setPendingDelKey] = useState<{ i: number; label: string } | null>(null);\n const [hr, setHr] = useState<HeadroomStatusReply | null>(null);\n const [editKey, setEditKey] = useState<number | null>(null);\n const [editKeyName, setEditKeyName] = useState(\"\");\n const [groups, setGroups] = useState<ModelGroup[]>([]);\n const [scopeKey, setScopeKey] = useState<number | null>(null);\n const [scopeModels, setScopeModels] = useState<string[]>([]);\n const [scopeRpm, setScopeRpm] = useState(\"\");\n const [scopeExpiry, setScopeExpiry] = useState<\"keep\" | \"never\" | \"24h\" | \"7day\" | \"30day\" | \"custom\">(\"never\");\n const [scopeCustomDays, setScopeCustomDays] = useState(\"\");\n const [scopeLimit, setScopeLimit] = useState(\"\"); // USD limit, \"\" = no cap\n const [scopeWindow, setScopeWindow] = useState<\"5h\" | \"24h\" | \"7day\" | \"30day\">(\"30day\");\n const [keyBudgets, setKeyBudgets] = useState<Record<string, { limit: number; window: string }>>({});\n const [pickerOpen, setPickerOpen] = useState(false);\n\n const reload = useCallback(async () => {\n const r = await adminApi.endpoint();\n if (!r.ok) {\n setError(r.error ?? \"could not reach the gateway\");\n return;\n }\n setError(\"\");\n setEp(r.data);\n }, []);\n\n // Headroom status is a live probe (installed/running/python), separate from the\n // endpoint config — reload it on mount and after any headroom action.\n const reloadHr = useCallback(async () => {\n const r = await adminApi.headroomStatus();\n if (r.ok) setHr(r.data);\n }, []);\n\n useEffect(() => {\n void reload();\n void reloadHr();\n // load the model catalog for the per-key scope picker (combos + provider/model refs).\n void (async () => {\n try {\n const res = await fetch(\"/api/gw/admin/config\");\n if (!res.ok) return;\n const cfg = (await res.json()) as MaskedConfig;\n const grps: ModelGroup[] = [];\n if (cfg.models.length) grps.push({ label: \"Combos\", items: cfg.models.map((m) => ({ value: m.alias, label: m.alias })) });\n for (const p of cfg.providers) {\n if (p.models.length) grps.push({ label: p.id, items: p.models.map((m) => ({ value: `${p.id}/${m.id}`, label: `${p.id}/${m.id}` })) });\n }\n setGroups(grps);\n } catch { /* non-critical — picker will just be empty */ }\n })();\n // index existing key-scoped budgets by fingerprint so the modal can prefill.\n void adminApi.budgets().then((r) => {\n if (!r.ok || !r.data) return;\n const map: Record<string, { limit: number; window: string }> = {};\n for (const b of r.data.budgets) {\n if (b.scope.type === \"key\") map[b.scope.id] = { limit: b.limit, window: b.window };\n }\n setKeyBudgets(map);\n });\n }, [reload, reloadHr]);\n\n if (error) return <Empty>{error}</Empty>;\n if (!ep) return <Empty>Loading…</Empty>;\n\n const baseUrl = `http://127.0.0.1:${ep.port}`;\n\n async function run(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setBusy(label);\n const r = await fn();\n setBusy(\"\");\n if (!r.ok) setError(r.error ?? \"action failed\");\n else {\n setError(\"\");\n await reload();\n }\n }\n\n // Create a key (generated or pasted) with its label, then surface it once in a\n // modal — aigetwey, where the full key is shown at creation time.\n async function addKey(label: string, rawKey: string) {\n const name = (label || \"Gateway key\").trim();\n setBusy(\"genkey\");\n const r = await adminApi.addServerKey(rawKey, name);\n setBusy(\"\");\n if (!r.ok) {\n setError(r.error ?? \"could not add key\");\n return;\n }\n setError(\"\");\n setKeyName(\"\");\n setCreated({ key: rawKey, name });\n await reload();\n }\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"text-[22px] font-semibold tracking-tight text-text\">Endpoint & Key</h1>\n <p className=\"mt-1 text-[13px] text-text-muted\">Gateway address, client keys, and the token-saver toggles.</p>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <RichCard header={<CardTitle title=\"Gateway URL\" sub=\"one endpoint for every client\" />}>\n <div className=\"text-[13px]\">\n <CopyRow label=\"Gateway URL\" value={baseUrl} />\n </div>\n <p className=\"mt-3 text-[12px] text-text-subtle\">\n One gateway, both formats. Anthropic clients (Claude Code) use it as-is; OpenAI clients (opencode,\n Cursor, Codex) append <span className=\"tnum\">/v1</span>. The <span className=\"text-text-muted\">CLI Tools</span>{\" \"}\n page has copy-ready env per tool.\n </p>\n </RichCard>\n\n <RichCard header={<CardTitle title=\"Gateway keys\" sub={`${ep.keys.length} configured`} />}>\n {ep.keys.length === 0 ? (\n <Empty>No keys — auth is DISABLED (localhost only). Generate one below.</Empty>\n ) : (\n <div className=\"space-y-1.5\">\n {ep.keys.map((k, i) =>\n editKey === i ? (\n <div key={i} className=\"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5\">\n <Input value={editKeyName} onChange={(e) => setEditKeyName(e.target.value)} placeholder=\"key name (e.g. Claude Code)\" />\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setEditKey(null)}>Cancel</Button>\n <Button\n disabled={busy === `editkey${i}`}\n onClick={() =>\n run(`editkey${i}`, async () => {\n const r = await adminApi.editServerKey(i, editKeyName.trim());\n if (r.ok) setEditKey(null);\n return r;\n })\n }\n >\n Save\n </Button>\n </div>\n </div>\n ) : (\n <div key={i} className=\"space-y-0 rounded-brand border border-border-subtle\">\n <div className=\"flex items-center justify-between gap-2 px-3 py-2\">\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n {k.name && <span className=\"text-[12px] font-semibold text-text-muted\">{k.name}</span>}\n <KeyReveal\n masked={k.key}\n reveal={async () => {\n const r = await adminApi.revealServerKey(i);\n return r.ok ? r.data?.key ?? null : null;\n }}\n />\n <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-text-subtle\">\n <span>{k.models?.length ? `${k.models.length} model${k.models.length > 1 ? \"s\" : \"\"}` : \"all models\"}</span>\n <span>·</span>\n <span>{k.rpm ? `${k.rpm}/min` : \"no rate limit\"}</span>\n <span>·</span>\n <span>\n {k.expires\n ? (Date.now() > k.expires ? <span className=\"text-danger\">expired</span> : `expires ${fmt.date(k.expires)}`)\n : \"no expiry\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-none items-center gap-1\">\n <button\n onClick={() => {\n setScopeKey(i);\n setScopeModels(k.models ?? []);\n setScopeRpm(k.rpm ? String(k.rpm) : \"\");\n setScopeExpiry(k.expires ? \"keep\" : \"never\");\n setScopeCustomDays(\"\");\n const kb = keyBudgets[k.fingerprint];\n setScopeLimit(kb ? String(kb.limit) : \"\");\n setScopeWindow((kb?.window as \"5h\" | \"24h\" | \"7day\" | \"30day\") ?? \"30day\");\n }}\n className=\"text-text-subtle hover:text-text\"\n aria-label=\"Edit key scope\"\n title=\"Model allowlist + rate limit + budget + expiry\"\n >\n <Icon name=\"tune\" size={15} />\n </button>\n <button\n onClick={() => { setEditKey(i); setEditKeyName(k.name ?? \"\"); }}\n className=\"text-text-subtle hover:text-text\"\n aria-label=\"Rename key\"\n title=\"Rename key\"\n >\n <Icon name=\"edit\" size={15} />\n </button>\n <button onClick={() => setPendingDelKey({ i, label: k.name || k.key })} className=\"text-text-subtle hover:text-danger\" aria-label=\"Remove key\">\n <Icon name=\"delete\" size={16} />\n </button>\n </div>\n </div>\n {scopeKey === i && (\n <div className=\"space-y-2 border-t border-border-subtle bg-accent-soft/40 px-3 py-2.5\">\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Allowed models</div>\n <div className=\"flex flex-wrap items-center gap-1.5\">\n {scopeModels.length === 0 ? (\n <span className=\"text-[12px] text-text-subtle\">All models (unrestricted)</span>\n ) : (\n scopeModels.map((m) => (\n <span key={m} className=\"inline-flex items-center gap-1 rounded border border-accent bg-accent-soft px-2 py-0.5 text-[12px] text-accent\">\n <span className=\"tnum\">{m}</span>\n <button onClick={() => setScopeModels((s) => s.filter((x) => x !== m))} className=\"hover:text-danger\" aria-label={`Remove ${m}`}>\n <Icon name=\"close\" size={12} />\n </button>\n </span>\n ))\n )}\n </div>\n <Button type=\"button\" variant=\"ghost\" className=\"mt-1.5\" onClick={() => setPickerOpen(true)}>\n <Icon name=\"add\" size={15} /> Pick models\n </Button>\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Rate limit</div>\n <Input\n inputMode=\"numeric\"\n value={scopeRpm}\n onChange={(e) => setScopeRpm(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"req/min (blank = unlimited)\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Access expiry</div>\n {k.expires && (\n <div className=\"mb-1.5 text-[11px] text-text-subtle\">\n currently {Date.now() > k.expires ? <span className=\"text-danger\">expired</span> : `expires ${fmt.date(k.expires)}`}\n </div>\n )}\n <div className=\"flex flex-wrap gap-1\">\n {(k.expires\n ? ([\"keep\", \"never\", \"24h\", \"7day\", \"30day\", \"custom\"] as const)\n : ([\"never\", \"24h\", \"7day\", \"30day\", \"custom\"] as const)\n ).map((opt) => (\n <button\n key={opt}\n type=\"button\"\n onClick={() => setScopeExpiry(opt)}\n className={pill(scopeExpiry === opt)}\n >\n {opt === \"never\" ? \"no expiry\" : opt}\n </button>\n ))}\n </div>\n {scopeExpiry === \"custom\" && (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <Input\n inputMode=\"numeric\"\n value={scopeCustomDays}\n onChange={(e) => setScopeCustomDays(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"days\"\n className=\"w-24\"\n />\n <span className=\"text-[11px] text-text-subtle\">days from now</span>\n </div>\n )}\n </div>\n <div>\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Spend cap (USD)</div>\n <Input\n inputMode=\"decimal\"\n value={scopeLimit}\n onChange={(e) => setScopeLimit(e.target.value.replace(/[^\\d.]/g, \"\"))}\n placeholder=\"USD (blank = no cap)\"\n />\n {scopeLimit && (\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <span className=\"text-[11px] text-text-subtle\">resets every</span>\n {([\"5h\", \"24h\", \"7day\", \"30day\"] as const).map((w) => (\n <button\n key={w}\n type=\"button\"\n onClick={() => setScopeWindow(w)}\n className={pill(scopeWindow === w)}\n >\n {w}\n </button>\n ))}\n </div>\n )}\n </div>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={() => setScopeKey(null)}>Cancel</Button>\n <Button\n disabled={busy === `scope${i}`}\n onClick={() =>\n run(`scope${i}`, async () => {\n // \"keep\" leaves expiry untouched (omit); \"never\" clears; a duration sets now+N.\n const expires =\n scopeExpiry === \"keep\" ? undefined\n : scopeExpiry === \"never\" ? null\n : scopeExpiry === \"custom\" ? (scopeCustomDays ? Date.now() + Number(scopeCustomDays) * DAY_MS : null)\n : Date.now() + EXPIRY_MS[scopeExpiry];\n const r = await adminApi.setServerKeyScope(i, {\n models: scopeModels,\n rpm: scopeRpm ? Number(scopeRpm) : null,\n expires,\n });\n if (!r.ok) return r;\n const limit = scopeLimit ? Number(scopeLimit) : 0;\n if (limit > 0) {\n await adminApi.setBudget({ scope: { type: \"key\", id: k.fingerprint }, unit: \"usd\", limit, window: scopeWindow });\n } else if (keyBudgets[k.fingerprint]) {\n await adminApi.clearBudget(`key:${k.fingerprint}`);\n }\n setScopeKey(null);\n return r;\n })\n }\n >\n Save\n </Button>\n </div>\n </div>\n )}\n </div>\n ),\n )}\n </div>\n )}\n <div className=\"mt-3 space-y-2\">\n <div className=\"flex gap-2\">\n <Input value={keyName} onChange={(e) => setKeyName(e.target.value)} placeholder=\"key name (e.g. Claude Code)\" className=\"flex-1\" />\n <Button disabled={busy === \"genkey\"} onClick={() => addKey(keyName, generateKey())}>\n <Icon name=\"add\" size={16} /> {busy === \"genkey\" ? \"Adding…\" : \"Add key\"}\n </Button>\n </div>\n <p className=\"text-[11px] text-text-subtle\">Name it, then click Add key — a key is generated and shown once. Configure its limits after.</p>\n </div>\n </RichCard>\n\n <RichCard className=\"lg:col-span-2\" header={<CardTitle title=\"Token savers\" sub=\"applied to every request before routing\" />}>\n <div className=\"space-y-4\">\n <Toggle\n label=\"RTK\"\n desc=\"Compress bulky tool_result blocks (diffs, grep, listings) in the request.\"\n on={ep.rtk}\n busy={busy === \"rtk\"}\n onChange={(v) => run(\"rtk\", () => adminApi.setRtk(v))}\n />\n <LevelRow\n label=\"Caveman\"\n desc=\"Terser model output — drops filler, keeps substance.\"\n value={ep.caveman}\n busy={busy === \"caveman\"}\n onChange={(lvl) => run(\"caveman\", () => adminApi.setCaveman(lvl))}\n />\n <LevelRow\n label=\"Ponytail\"\n desc=\"Minimal, YAGNI code style — deletion over addition.\"\n value={ep.ponytail}\n busy={busy === \"ponytail\"}\n onChange={(lvl) => run(\"ponytail\", () => adminApi.setPonytail(lvl))}\n />\n </div>\n </RichCard>\n\n <HeadroomCard\n ep={ep}\n hr={hr}\n refresh={async () => {\n await reload();\n await reloadHr();\n }}\n />\n </div>\n\n {created && <KeyCreatedModal name={created.name} value={created.key} onClose={() => setCreated(null)} />}\n {pendingDelKey && (\n <ConfirmModal\n title=\"Remove gateway key\"\n message={`Delete \"${pendingDelKey.label}\"? Any client using this key stops working immediately.`}\n confirmLabel=\"Remove\"\n busy={busy === `rmkey${pendingDelKey.i}`}\n onCancel={() => setPendingDelKey(null)}\n onConfirm={() => {\n const i = pendingDelKey.i;\n void run(`rmkey${i}`, () => adminApi.removeServerKey(i)).then(() => setPendingDelKey(null));\n }}\n />\n )}\n {pickerOpen && (\n <ModelPicker\n title=\"Allowed models\"\n note=\"Pick the models this key may call. None = all.\"\n groups={groups}\n selected={scopeModels}\n onToggle={(v) => setScopeModels((s) => s.includes(v) ? s.filter((x) => x !== v) : [...s, v])}\n onClose={() => setPickerOpen(false)}\n showThinkingHint={false}\n />\n )}\n </div>\n );\n}\n\n/**\n * Headroom = external context-compression proxy. Status is a live probe; the\n * enable/url/compress fields persist to endpoint config; Start/Stop manage a\n * gateway-spawned proxy when the CLI is installed and the URL is loopback.\n */\nfunction HeadroomCard({\n ep,\n hr,\n refresh,\n}: {\n ep: EndpointPayload;\n hr: HeadroomStatusReply | null;\n refresh: () => Promise<void>;\n}) {\n const h = ep.headroom;\n const [url, setUrl] = useState(h.url);\n const [localBusy, setLocalBusy] = useState(\"\");\n const [msg, setMsg] = useState(\"\");\n const [check, setCheck] = useState<{ ok: boolean; text: string } | null>(null);\n useEffect(() => setUrl(h.url), [h.url]);\n\n async function act(label: string, fn: () => Promise<{ ok: boolean; error?: string }>) {\n setLocalBusy(label);\n setMsg(\"\");\n setCheck(null);\n const r = await fn();\n setLocalBusy(\"\");\n if (!r.ok) setMsg(r.error ?? \"action failed\");\n await refresh();\n }\n\n // Live re-probe: ask the gateway whether the proxy at the configured URL\n // actually answers right now, and surface the result inline.\n async function checkProxy() {\n setLocalBusy(\"check\");\n setMsg(\"\");\n setCheck(null);\n const r = await adminApi.headroomStatus();\n setLocalBusy(\"\");\n await refresh();\n if (!r.ok || !r.data) {\n setCheck({ ok: false, text: r.error ?? \"could not reach the gateway\" });\n return;\n }\n setCheck(\n r.data.running\n ? { ok: true, text: `proxy is up at ${r.data.url}` }\n : { ok: false, text: `no proxy responding at ${r.data.url}` },\n );\n }\n\n return (\n <RichCard className=\"lg:col-span-2\" header={<CardTitle title=\"Headroom\" sub=\"external context-compression proxy\" />}>\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2 text-[12px]\">\n <Badge tone={hr?.installed ? \"live\" : \"neutral\"}>{hr?.installed ? \"installed\" : \"not installed\"}</Badge>\n <Badge tone={hr?.running ? \"live\" : \"warn\"}>{hr?.running ? \"proxy running\" : \"proxy down\"}</Badge>\n <Badge tone={hr?.python ? \"info\" : \"neutral\"}>{hr?.python ? `python ${hr.python}` : \"no python ≥3.10\"}</Badge>\n {hr?.managedPid ? <span className=\"tnum text-text-subtle\">pid {hr.managedPid}</span> : null}\n </div>\n\n <Toggle\n label=\"Enable headroom\"\n desc=\"Compress the full context through the proxy before each request (fail-open if it's down).\"\n on={h.enabled}\n busy={localBusy === \"enable\"}\n onChange={(v) => act(\"enable\", () => adminApi.setHeadroom({ enabled: v }))}\n />\n <Toggle\n label=\"Compress user messages\"\n desc=\"Also squeeze user turns, not just tool/assistant context.\"\n on={h.compress_user_messages}\n busy={localBusy === \"cum\"}\n onChange={(v) => act(\"cum\", () => adminApi.setHeadroom({ compress_user_messages: v }))}\n />\n\n <div className=\"flex items-end gap-2\">\n <div className=\"flex-1\">\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wider text-text-subtle\">Proxy URL</div>\n <Input value={url} onChange={(e) => setUrl(e.target.value)} placeholder=\"http://localhost:8787\" className=\"font-mono text-[12.5px]\" />\n </div>\n <Button\n variant=\"ghost\"\n disabled={url.trim() === h.url || localBusy === \"url\"}\n onClick={() => act(\"url\", () => adminApi.setHeadroom({ url: url.trim() }))}\n >\n Save URL\n </Button>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n disabled={!hr?.canStart || hr?.running || localBusy === \"start\"}\n onClick={() => act(\"start\", () => adminApi.headroomStart())}\n >\n <Icon name=\"play_arrow\" size={16} /> {localBusy === \"start\" ? \"Starting…\" : \"Start proxy\"}\n </Button>\n <Button\n variant=\"danger\"\n disabled={!hr?.managedPid || localBusy === \"stop\"}\n onClick={() => act(\"stop\", () => adminApi.headroomStop())}\n >\n <Icon name=\"stop\" size={16} /> Stop\n </Button>\n <Button variant=\"ghost\" disabled={localBusy === \"check\"} onClick={checkProxy}>\n <Icon name=\"sync\" size={16} /> {localBusy === \"check\" ? \"Checking…\" : \"Check\"}\n </Button>\n {hr && !hr.installed && (\n <span className=\"text-[11px] text-text-subtle\">\n Headroom isn’t installed. Get it from{\" \"}\n <a href=\"https://github.com/chopratejas/headroom\" target=\"_blank\" rel=\"noreferrer\" className=\"text-accent hover:underline\">\n chopratejas/headroom\n </a>{\" \"}\n (needs Python ≥ 3.10):{\" \"}\n <code className=\"rounded bg-surface-2 px-1\">pipx install git+https://github.com/chopratejas/headroom</code>{\" \"}\n — then re-open this page.\n </span>\n )}\n {hr?.installed && !hr.localUrl && (\n <span className=\"text-[11px] text-text-subtle\">URL isn’t loopback — start that proxy yourself.</span>\n )}\n </div>\n\n {msg && <p className=\"text-[12px] text-danger\">{msg}</p>}\n {check && (\n <p className={`flex items-center gap-1 text-[12px] ${check.ok ? \"text-success\" : \"text-danger\"}`}>\n <Icon name={check.ok ? \"check_circle\" : \"error\"} size={14} /> {check.text}\n </p>\n )}\n </div>\n </RichCard>\n );\n}\n\n/** Shows a freshly created key once (it's masked everywhere after), with copy. */\nfunction KeyCreatedModal({ name, value, onClose }: { name: string; value: string; onClose: () => void }) {\n const [copied, setCopied] = useState(false);\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6\" onClick={onClose}>\n <div\n className=\"w-full max-w-md rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-1 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-accent-soft text-accent\">\n <Icon name=\"key\" size={16} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">Key created</h2>\n </div>\n <p className=\"mb-3 text-[12px] text-text-muted\">\n Copy <span className=\"text-text\">{name}</span> now. You can reveal it again later from this page.\n </p>\n <button\n onClick={() => {\n void navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }}\n className=\"flex w-full items-center justify-between gap-2 rounded-brand border border-border-subtle bg-bg px-3 py-2.5 text-left hover:border-text-subtle\"\n >\n <span className=\"tnum truncate text-[12.5px] text-text\">{value}</span>\n <Icon name={copied ? \"check\" : \"content_copy\"} size={15} />\n </button>\n <div className=\"mt-4 flex justify-end\">\n <Button onClick={onClose}>Done</Button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction CopyRow({ label, value }: { label: string; value: string }) {\n const [copied, setCopied] = useState(false);\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-text-subtle\">{label}</span>\n <button\n onClick={() => {\n void navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n }}\n className=\"flex items-center gap-1.5 rounded-brand border border-border-subtle px-2.5 py-1 tnum text-[12.5px] text-text hover:border-text-subtle\"\n >\n {value}\n <Icon name={copied ? \"check\" : \"content_copy\"} size={13} />\n </button>\n </div>\n );\n}\n\nfunction Toggle({ label, desc, on, busy, onChange }: { label: string; desc: string; on: boolean; busy: boolean; onChange: (v: boolean) => void }) {\n return (\n <div className=\"flex items-center justify-between gap-4\">\n <div>\n <div className=\"text-[13px] font-semibold text-text\">{label}</div>\n <div className=\"text-[12px] text-text-muted\">{desc}</div>\n </div>\n <button\n disabled={busy}\n onClick={() => onChange(!on)}\n className={`relative h-6 w-11 flex-none rounded-full transition-colors ${on ? \"bg-accent\" : \"bg-surface-3\"}`}\n aria-pressed={on}\n >\n <span className={`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-bg transition-transform ${on ? \"translate-x-5\" : \"translate-x-0\"}`} />\n </button>\n </div>\n );\n}\n\nfunction LevelRow({ label, desc, value, busy, onChange }: { label: string; desc: string; value: InjectLevel; busy: boolean; onChange: (l: InjectLevel) => void }) {\n return (\n <div className=\"flex items-center justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-text\">{label}</span>\n {value !== \"off\" && <Badge tone=\"info\">{value}</Badge>}\n </div>\n <div className=\"text-[12px] text-text-muted\">{desc}</div>\n </div>\n <div className=\"flex flex-none items-center gap-1 rounded-full border border-border bg-surface p-1\">\n {LEVELS.map((lvl) => (\n <button\n key={lvl}\n disabled={busy}\n onClick={() => onChange(lvl)}\n className={`rounded-full px-2.5 py-1 text-[11.5px] font-medium transition-colors ${\n value === lvl ? \"bg-surface-2 text-text\" : \"text-text-muted hover:text-text\"\n }`}\n >\n {lvl}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Icon } from \"./Icon\";\n\n/**\n * A masked key with an eye toggle that fetches the raw value on demand — for the\n * local operator who forgot what they pasted. `masked` is the already-masked\n * string the dashboard renders everywhere; `reveal` lazily fetches the real key\n * (admin-gated) the first time it's shown, then we cache it for copy/hide.\n */\n/**\n * `align`: \"inline\" keeps the eye + copy right next to the key text (use in a\n * label/column context like Endpoint). \"right\" lets the text grow so the eye +\n * copy push to the right edge (use in a single-line row like Provider keys).\n */\nexport function KeyReveal({\n masked,\n reveal,\n className,\n align = \"inline\",\n}: {\n masked: string;\n reveal: () => Promise<string | null>;\n className?: string;\n align?: \"inline\" | \"right\";\n}) {\n const [real, setReal] = useState<string | null>(null);\n const [shown, setShown] = useState(false);\n const [loading, setLoading] = useState(false);\n const [copied, setCopied] = useState(false);\n\n async function toggle() {\n if (shown) {\n setShown(false);\n return;\n }\n if (real === null) {\n setLoading(true);\n const k = await reveal();\n setLoading(false);\n if (k === null) return; // reveal failed — stay masked\n setReal(k);\n }\n setShown(true);\n }\n\n const display = shown && real !== null ? real : masked;\n\n return (\n <span className={`flex min-w-0 items-center gap-1.5${className ? ` ${className}` : \"\"}`}>\n <span className={`tnum truncate text-[12.5px] text-text${align === \"right\" ? \" flex-1\" : \"\"}`}>{display}</span>\n {shown && real !== null && (\n <button\n type=\"button\"\n onClick={() => {\n void navigator.clipboard.writeText(real);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n }}\n className=\"flex-none text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Copy key\"\n >\n <Icon name={copied ? \"check\" : \"content_copy\"} size={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={toggle}\n disabled={loading}\n className=\"flex-none text-text-subtle transition-colors hover:text-text disabled:opacity-40\"\n aria-label={shown ? \"Hide key\" : \"Show key\"}\n >\n <Icon name={loading ? \"hourglass_empty\" : shown ? \"visibility_off\" : \"visibility\"} size={15} />\n </button>\n </span>\n );\n}\n"],"names":["KeyReveal","masked","reveal","className","align","real","setReal","shown","setShown","loading","setLoading","copied","setCopied","toggle","k","display","type","onClick","navigator","clipboard","writeText","setTimeout","name","size","disabled"],"mappings":"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"}
|
|
@@ -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"})]})]})})}])}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=src_components_ModelPicker_tsx_1jisxh6._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ModelPicker.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Icon } from \"@/components/Icon\";\nimport { CapacityBadges } from \"@/components/CapacityBadges\";\n\nexport interface ModelGroup {\n label: string;\n items: { value: string; label: string; tag?: string }[];\n}\n\n/**\n * aigetwey-style model picker: a search box + provider-grouped chips you click to\n * toggle in/out of a selection. Used by the combo form and the CLI-tool model\n * selection so both add models the same way (click to add, click again to drop).\n */\nexport function ModelPicker({\n title = \"Add models\",\n note = \"Click to add, click again to remove.\",\n searchPlaceholder = \"Search models…\",\n groups,\n selected,\n onToggle,\n onClose,\n showThinkingHint = true,\n}: {\n title?: string;\n note?: string;\n searchPlaceholder?: string;\n groups: ModelGroup[];\n selected: string[];\n onToggle: (value: string) => void;\n onClose: () => void;\n /** The \"reasoning models accept a thinking suffix\" footer only makes sense when\n * picking MODELS. Provider/key pickers reuse this component, so they hide it. */\n showThinkingHint?: boolean;\n}) {\n const [q, setQ] = useState(\"\");\n const needle = q.trim().toLowerCase();\n const filtered = groups\n .map((g) => ({\n ...g,\n items: needle ? g.items.filter((i) => i.value.toLowerCase().includes(needle)) : g.items,\n }))\n .filter((g) => g.items.length > 0);\n const sel = new Set(selected);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/60 p-6 sm:p-10\" onClick={onClose}>\n <div\n className=\"flex max-h-[80vh] w-full max-w-lg flex-col rounded-brand-lg border border-border bg-surface shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex items-center justify-between border-b border-border-subtle px-4 py-3\">\n <h2 className=\"text-[14px] font-semibold text-text\">{title}</h2>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\" aria-label=\"Close\">\n <Icon name=\"close\" size={18} />\n </button>\n </div>\n\n <div className=\"border-b border-border-subtle px-4 py-3\">\n <p className=\"mb-2 text-[12px] text-text-muted\">{note}</p>\n <div className=\"relative\">\n <Icon name=\"search\" size={15} className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-text-subtle\" />\n <input\n autoFocus\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder={searchPlaceholder}\n className=\"w-full rounded-brand border border-border bg-bg py-2 pl-8 pr-3 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none\"\n />\n </div>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-3\">\n {filtered.length === 0 ? (\n <p className=\"py-6 text-center text-[12.5px] text-text-subtle\">No models match “{q}”.</p>\n ) : (\n <div className=\"space-y-4\">\n {filtered.map((g) => (\n <div key={g.label}>\n <div className=\"mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-text-subtle\">\n {g.label} <span className=\"tnum text-text-subtle/70\">({g.items.length})</span>\n </div>\n <div className=\"flex flex-wrap gap-1.5\">\n {g.items.map((it) => {\n const on = sel.has(it.value);\n return (\n <button\n key={it.value}\n type=\"button\"\n onClick={() => onToggle(it.value)}\n className={`inline-flex items-center gap-1 rounded-brand border px-2 py-1 text-[12px] transition-colors ${\n on ? \"border-accent bg-accent-soft text-accent\" : \"border-border bg-bg text-text-muted hover:border-text-subtle hover:text-text\"\n }`}\n >\n {on && <Icon name=\"check\" size={12} />}\n <span className=\"tnum\">{it.label}</span>\n <CapacityBadges model={it.value} size={13} />\n {it.tag && <span className=\"rounded bg-surface-2 px-1 text-[10px] text-text-subtle\">{it.tag}</span>}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {showThinkingHint && (\n <div className=\"border-t border-border-subtle px-4 py-2 text-[11px] text-text-subtle\">\n <Icon name=\"neurology\" size={12} className=\"mr-1 inline align-text-bottom text-warning\" />\n Reasoning models accept a thinking suffix — call{\" \"}\n <code className=\"rounded bg-surface-2 px-1 text-text-muted\">model(high)</code> or{\" \"}\n <code className=\"rounded bg-surface-2 px-1 text-text-muted\">model(none)</code> (high·low·medium·minimal·auto·none·or a token budget).\n </div>\n )}\n\n <div className=\"flex items-center justify-between border-t border-border-subtle px-4 py-3\">\n <span className=\"tnum text-[12px] text-text-subtle\">{selected.length} selected</span>\n <button onClick={onClose} className=\"rounded-brand bg-accent px-3.5 py-1.5 text-[13px] font-semibold text-accent-ink hover:bg-accent-hover\">\n Done\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["ModelPicker","title","note","searchPlaceholder","groups","selected","onToggle","onClose","showThinkingHint","q","setQ","needle","trim","toLowerCase","filtered","map","g","items","filter","i","value","includes","length","sel","Set","className","onClick","e","stopPropagation","name","size","autoFocus","onChange","target","placeholder","label","it","on","has","type","model","tag"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports=[33410,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(50944),e=a.i(56173),f=a.i(47153),g=a.i(2693),h=a.i(2799),i=a.i(85732),j=a.i(7078),k=a.i(93026),l=a.i(58918);function m({checked:a,indeterminate:c,onChange:d,className:e,ariaLabel:f}){let g=a||c;return(0,b.jsx)("button",{type:"button",role:"checkbox","aria-checked":c?"mixed":a,"aria-label":f,onClick:a=>{a.stopPropagation(),d()},className:`flex h-[18px] w-[18px] flex-none items-center justify-center rounded-[5px] border transition-colors ${g?"border-accent bg-accent text-accent-ink":"border-border bg-bg text-transparent hover:border-text-subtle"}${e?` ${e}`:""}`,children:(0,b.jsx)(k.Icon,{name:c?"remove":"check",size:13})})}function n({models:a,busy:d,onAdd:e,onClose:f}){let[g,h]=(0,c.useState)(""),[i,l]=(0,c.useState)(()=>new Set(a.filter(a=>!a.added).map(a=>a.id))),o=(0,c.useMemo)(()=>{let b=g.trim().toLowerCase();return b?a.filter(a=>a.id.toLowerCase().includes(b)):a},[a,g]);function p(a){l(b=>{let c=new Set(b);return c.has(a)?c.delete(a):c.add(a),c})}let q=o.filter(a=>i.has(a.id)).length,r=o.length>0&&q===o.length;function s(){l(a=>{let b=new Set(a);return r?o.forEach(a=>b.delete(a.id)):o.forEach(a=>b.add(a.id)),b})}return(0,b.jsx)("div",{className:"fixed inset-0 z-50 grid place-items-center bg-black/50 p-6",onClick:f,children:(0,b.jsxs)("div",{className:"flex max-h-[80vh] w-full max-w-[480px] flex-col overflow-hidden rounded-brand-lg border border-border bg-surface shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("header",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("span",{className:"text-[14px] font-semibold text-text",children:[a.length," models found"]}),(0,b.jsx)("button",{onClick:f,className:"text-text-subtle hover:text-text","aria-label":"Close",children:(0,b.jsx)(k.Icon,{name:"close",size:18})})]}),(0,b.jsx)("div",{className:"border-b border-border-subtle px-4 py-2.5",children:(0,b.jsx)(j.Input,{value:g,onChange:a=>h(a.target.value),placeholder:"filter…",autoFocus:!0})}),o.length>0&&(0,b.jsxs)("button",{onClick:s,className:"flex items-center gap-2.5 border-b border-border-subtle px-4 py-2 text-left hover:bg-surface-2",children:[(0,b.jsx)(m,{checked:r,indeterminate:q>0&&!r,onChange:s,ariaLabel:"Select all"}),(0,b.jsxs)("span",{className:"text-[12.5px] font-medium text-text",children:["Select all",g?" (filtered)":""]}),(0,b.jsxs)("span",{className:"ml-auto tnum text-[11px] text-text-subtle",children:[q,"/",o.length]})]}),(0,b.jsx)("div",{className:"flex-1 overflow-y-auto px-2 py-2",children:0===o.length?(0,b.jsx)("div",{className:"px-2 py-6 text-center text-[13px] text-text-muted",children:"No matches."}):o.map(a=>{let c=i.has(a.id);return(0,b.jsxs)("button",{onClick:()=>p(a.id),className:`flex w-full items-center gap-2.5 rounded-brand border px-2.5 py-2 text-left transition-colors ${c?"border-accent/40 bg-accent-soft":"border-transparent hover:bg-surface-2"}`,children:[(0,b.jsx)(m,{checked:c,onChange:()=>p(a.id),ariaLabel:a.id}),(0,b.jsx)("span",{className:"flex-1 truncate text-[12.5px] text-text",children:a.id}),a.added&&(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"in catalog"})]},a.id)})}),(0,b.jsxs)("footer",{className:"flex items-center justify-between gap-3 border-t border-border-subtle bg-bg-alt px-4 py-2.5",children:[(0,b.jsxs)("span",{className:"tnum text-[12px] text-text-muted",children:[i.size," selected"]}),(0,b.jsxs)("div",{className:"flex gap-2",children:[(0,b.jsx)(j.Button,{variant:"ghost",onClick:f,children:"Cancel"}),(0,b.jsx)(j.Button,{disabled:0===i.size||d,onClick:()=>e([...i]),children:d?"Adding…":`Add ${i.size}`})]})]})]})})}var o=a.i(52065),p=a.i(73858);function q({k:a,v:c}){return(0,b.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,b.jsx)("span",{className:"text-text-subtle",children:a}),(0,b.jsx)("span",{className:"truncate text-text",children:c})]})}a.s(["ProviderDetail",0,function({id:a}){let m=(0,d.useRouter)(),[r,s]=(0,c.useState)(null),[t,u]=(0,c.useState)(null),[v,w]=(0,c.useState)(""),[x,y]=(0,c.useState)(null),[z,A]=(0,c.useState)(""),[B,C]=(0,c.useState)(""),[D,E]=(0,c.useState)(""),[F,G]=(0,c.useState)(null),[H,I]=(0,c.useState)(""),[J,K]=(0,c.useState)(""),[L,M]=(0,c.useState)(""),[N,O]=(0,c.useState)(""),[P,Q]=(0,c.useState)(null),[R,S]=(0,c.useState)({}),[T,U]=(0,c.useState)({}),[V,W]=(0,c.useState)(!1),[X,Y]=(0,c.useState)(null),Z=(0,c.useRef)(!1),[$,_]=(0,c.useState)(!1),[aa,ab]=(0,c.useState)(""),[ac,ad]=(0,c.useState)(""),[ae,af]=(0,c.useState)({}),[ag,ah]=(0,c.useState)(!1);async function ai(b){S(a=>({...a,[b]:"testing"}));let c=await e.adminApi.testModel(a,b);S(a=>({...a,[b]:c.ok&&c.data?.ok?"ok":"fail"}))}async function aj(b){U(a=>({...a,[b]:"testing"}));let c=await e.adminApi.testKey(a,b);U(a=>({...a,[b]:c.data??{ok:!1,reachable:!1,status:0,error:c.error}}))}async function ak(b){Z.current=!1,W(!0),Y(null),U({});let c=0,d=0;for(let f=0;f<b&&!Z.current;f++){U(a=>({...a,[f]:"testing"}));let g=await e.adminApi.testKey(a,f),h=g.data??{ok:!1,reachable:!1,status:0,error:g.error};U(a=>({...a,[f]:h})),h.ok?c++:d++,f<b-1&&!Z.current&&await new Promise(a=>setTimeout(a,500))}W(!1),Y({total:b,passed:c,failed:d})}let al=(0,c.useCallback)(async()=>{let[b,c]=await Promise.all([fetch("/api/gw/admin/config"),e.adminApi.providers()]);if(!b.ok)return void w("could not reach the gateway");let d=(await b.json()).providers.find(b=>b.id===a)??null;d?(w(""),s(d),u(c.data?.providers.find(b=>b.id===a)??null)):w(`provider "${a}" not found`)},[a]);if((0,c.useEffect)(()=>{al()},[al]),v)return(0,b.jsx)(l.Empty,{children:v});if(!r)return(0,b.jsx)(l.Empty,{children:"Loading…"});let am=r.api_keys??(r.api_key?[r.api_key]:[]),an=N.trim().toLowerCase(),ao=an?r.models.filter(a=>a.id.toLowerCase().includes(an)):r.models;async function ap(a,b){A(a);let c=await b();A(""),c.ok?(w(""),await al()):w(c.error??"action failed")}return(0,b.jsxs)("div",{children:[(0,b.jsxs)("button",{onClick:()=>m.push("/providers"),className:"mb-4 inline-flex items-center gap-1 text-[12px] text-text-muted hover:text-text",children:[(0,b.jsx)(k.Icon,{name:"arrow_back",size:15})," Providers"]}),(0,b.jsxs)("div",{className:"mb-6 flex items-center gap-3",children:[(0,b.jsx)(f.Lamp,{state:r.disabled?"idle":t?.keys.some(a=>a.healthy)??!0?"live":"down"}),(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:r.name||r.id}),r.name&&(0,b.jsxs)("span",{className:"text-[12px] text-text-subtle",children:[r.id,"/"]})]}),(0,b.jsx)(g.FormatBadge,{format:r.format}),r.free&&(0,b.jsx)(g.Badge,{tone:"info",children:"free"}),r.service_account&&(0,b.jsx)(g.Badge,{tone:"info",children:"service-account"}),r.disabled&&(0,b.jsx)(g.Badge,{tone:"down",children:"disabled"})]}),(0,b.jsxs)("div",{className:`grid gap-4 lg:grid-cols-2 transition-opacity ${r.disabled?"opacity-50":""}`,children:[(0,b.jsx)(i.RichCard,{header:(0,b.jsx)(i.CardTitle,{title:"Connection"}),children:$?(0,b.jsxs)("div",{className:"space-y-3",children:[(0,b.jsx)(j.Field,{label:"Name",hint:"the id — also the call prefix (name/model) & combos",children:(0,b.jsx)(j.Input,{value:ac,onChange:a=>ad(a.target.value),placeholder:"e.g. huki",className:"font-mono text-[12.5px]"})}),ac.trim()&&ac.trim()!==a&&(0,b.jsxs)("p",{className:"flex items-start gap-1.5 rounded-brand border border-warning/40 bg-warning/8 px-2.5 py-2 text-[11.5px] text-warning",children:[(0,b.jsx)(k.Icon,{name:"warning",size:14,className:"mt-0.5 flex-none"}),(0,b.jsxs)("span",{children:["Renaming rewrites the call string. CLI tools pointing at"," ",(0,b.jsxs)("code",{className:"tnum",children:[a,"/…"]})," will break until repointed; combos that target it are updated automatically."]})]}),(0,b.jsx)(j.Field,{label:"Base URL",children:(0,b.jsx)(j.Input,{value:aa,onChange:a=>ab(a.target.value),placeholder:"https://...",className:"font-mono text-[12.5px]"})}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(j.Button,{variant:"ghost",onClick:()=>_(!1),children:"Cancel"}),(0,b.jsx)(j.Button,{disabled:"editconn"===z,onClick:()=>ap("editconn",async()=>{let b=ac.trim(),c=a;if(b&&b!==a){let d=await e.adminApi.renameProvider(a,b);if(!d.ok)return d;c=b}let d=await e.adminApi.editProvider(c,{base_url:aa.trim()||void 0});return d.ok&&(_(!1),c!==a&&m.push(`/providers/${encodeURIComponent(c)}`)),d}),children:"Save"})]})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{className:"space-y-2 text-[13px]",children:[(0,b.jsx)(q,{k:"Base URL",v:r.base_url}),(0,b.jsx)(q,{k:"Format",v:r.format}),(0,b.jsx)(q,{k:"Cooldown base",v:`${r.cooldown_base_ms}ms`}),(0,b.jsx)(q,{k:"Max retries",v:String(r.max_retries)})]}),(0,b.jsxs)("div",{className:"mt-4 flex items-center gap-2",children:[(0,b.jsxs)(j.Button,{variant:"ghost",onClick:()=>{_(!0),ab(r.base_url),ad(r.id)},children:[(0,b.jsx)(k.Icon,{name:"edit",size:15})," Edit"]}),(0,b.jsxs)(j.Button,{variant:"ghost",disabled:"test"===z,onClick:()=>ap("test",async()=>{let b=await e.adminApi.testProvider(a);return b.ok&&y(b.data),b}),children:[(0,b.jsx)(k.Icon,{name:"wifi_tethering",size:16})," ","test"===z?"Testing…":"Test connection"]}),(0,b.jsxs)(j.Button,{variant:"ghost",disabled:"discover"===z,onClick:()=>ap("discover",async()=>{let b=await e.adminApi.discoverModels(a);return b.ok&&Q(b.data?.models??[]),b}),children:[(0,b.jsx)(k.Icon,{name:"sync",size:16})," ","discover"===z?"Fetching…":"Fetch models"]})]}),x&&(0,b.jsxs)("div",{className:"mt-3 text-[12px]",children:[(0,b.jsx)(g.Badge,{tone:x.ok?"live":x.reachable?"warn":"down",children:x.ok?`ok (${x.status})`:x.reachable?`reachable (${x.status})`:"unreachable"}),x.error&&(0,b.jsx)("span",{className:"ml-2 text-text-subtle",children:x.error})]})]})}),(0,b.jsxs)(i.RichCard,{header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(i.CardTitle,{title:"Keys",sub:`${am.length} configured`}),(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-3",children:[am.length>1&&(0,b.jsxs)(j.Button,{variant:"ghost",disabled:V,onClick:()=>ak(am.length),children:[(0,b.jsx)(k.Icon,{name:V?"progress_activity":"sync",size:15}),V?"Testing…":"Test All"]}),V&&(0,b.jsxs)(j.Button,{variant:"ghost",onClick:()=>{Z.current=!0},children:[(0,b.jsx)(k.Icon,{name:"stop",size:15})," Stop"]}),(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"Round Robin"}),(0,b.jsx)("button",{onClick:()=>{let b="round-robin"===r.strategy?null:"round-robin";e.adminApi.setProviderStrategy(a,b,r.sticky??1).then(()=>al())},className:`relative h-5 w-9 rounded-full transition-colors ${"round-robin"===r.strategy?"bg-accent":"bg-border-subtle"}`,"aria-label":"Toggle round-robin",children:(0,b.jsx)("span",{className:`absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-white transition-transform ${"round-robin"===r.strategy?"translate-x-[18px]":"translate-x-0"}`})}),"round-robin"===r.strategy&&(0,b.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,b.jsx)("span",{className:"text-[11px] text-text-subtle",children:"Sticky:"}),(0,b.jsxs)("div",{className:"flex items-center rounded-brand border border-border-subtle",children:[(0,b.jsx)("button",{type:"button",disabled:(r.sticky??1)<=1,onClick:()=>void e.adminApi.setProviderStrategy(a,"round-robin",Math.max(1,(r.sticky??1)-1)).then(()=>al()),className:"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text disabled:opacity-30","aria-label":"Decrease sticky",children:(0,b.jsx)(k.Icon,{name:"remove",size:13})}),(0,b.jsx)("span",{className:"tnum w-6 text-center text-[11px] text-text",children:r.sticky??1}),(0,b.jsx)("button",{type:"button",onClick:()=>void e.adminApi.setProviderStrategy(a,"round-robin",(r.sticky??1)+1).then(()=>al()),className:"px-1.5 py-0.5 text-text-subtle transition-colors hover:text-text","aria-label":"Increase sticky",children:(0,b.jsx)(k.Icon,{name:"add",size:13})})]})]})]})]}),children:[X&&(0,b.jsx)("div",{className:"mb-3 flex items-center gap-2 text-[11.5px]",children:(0,b.jsxs)(g.Badge,{tone:0===X.failed?"live":"warn",children:[X.total," tested: ",X.passed," valid, ",X.failed," failed"]})}),0===am.length?(0,b.jsx)(l.Empty,{children:"No keys (free / service-account provider)."}):(0,b.jsx)("div",{className:"space-y-1.5",children:am.map((c,d)=>{let i=t?.keys[d],l=T[d],m=l&&"testing"!==l?l:null,n=m?m.ok?"live":m.reachable?"idle":"down":i?i.healthy?"live":"down":"idle",o=r.key_names?.[c],p=r.disabled_keys?.includes(d)??!1;return F===d?(0,b.jsxs)("div",{className:"space-y-2 rounded-brand border border-accent bg-accent-soft/40 px-3 py-2.5",children:[(0,b.jsx)(j.Input,{value:H,onChange:a=>I(a.target.value),placeholder:"key name (optional)"}),(0,b.jsx)(j.Input,{value:J,onChange:a=>K(a.target.value),placeholder:"new key value (leave blank to keep)",className:"font-mono text-[12.5px]"}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(j.Button,{variant:"ghost",onClick:()=>G(null),children:"Cancel"}),(0,b.jsx)(j.Button,{disabled:z===`editkey${d}`,onClick:()=>ap(`editkey${d}`,async()=>{let b=await e.adminApi.editKey(a,d,{name:H,key:J.trim()||void 0});return b.ok&&G(null),b}),children:"Save"})]})]},d):(0,b.jsxs)("div",{className:`rounded-brand border border-border-subtle px-3 py-2${p?" opacity-60":""}`,children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[(0,b.jsxs)("div",{className:"flex flex-col",children:[(0,b.jsx)("button",{onClick:()=>ap(`reorder${d}up`,()=>e.adminApi.reorderKey(a,d,d-1)),disabled:0===d,className:"p-0.5 text-text-subtle hover:text-text disabled:opacity-30","aria-label":"Move up",children:(0,b.jsx)(k.Icon,{name:"keyboard_arrow_up",size:14})}),(0,b.jsx)("button",{onClick:()=>ap(`reorder${d}dn`,()=>e.adminApi.reorderKey(a,d,d+1)),disabled:d===am.length-1,className:"p-0.5 text-text-subtle hover:text-text disabled:opacity-30","aria-label":"Move down",children:(0,b.jsx)(k.Icon,{name:"keyboard_arrow_down",size:14})})]}),(0,b.jsx)(f.Lamp,{state:n}),(0,b.jsxs)("div",{className:"min-w-0 flex-1",children:[o&&(0,b.jsx)("div",{className:"text-[12px] font-semibold text-text-muted",children:o}),(0,b.jsx)("span",{className:"block truncate font-mono text-[12.5px] text-text",children:ae[d]??c})]}),ae[d]&&(0,b.jsx)("button",{onClick:()=>{navigator.clipboard.writeText(ae[d])},className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text","aria-label":"Copy key",title:"Copy to clipboard",children:(0,b.jsx)(k.Icon,{name:"content_copy",size:14})}),i&&i.cooldown_ms>0&&(0,b.jsx)(h.CooldownTimer,{ms:i.cooldown_ms}),(0,b.jsx)("button",{onClick:async()=>{if(ae[d])return void af(a=>{let b={...a};return delete b[d],b});let b=await e.adminApi.revealKey(a,d);b.ok&&b.data?.key&&af(a=>({...a,[d]:b.data.key}))},className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text","aria-label":ae[d]?"Hide key":"Show key",title:ae[d]?"Hide key":"Show key",children:(0,b.jsx)(k.Icon,{name:ae[d]?"visibility_off":"visibility",size:15})}),(0,b.jsx)("button",{onClick:()=>ap(`toggle${d}`,()=>e.adminApi.toggleKey(a,d,p)),className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text","aria-label":p?"Enable key":"Disable key",title:p?"Enable this key":"Disable this key",children:(0,b.jsx)(k.Icon,{name:p?"toggle_off":"toggle_on",size:20,className:p?"text-text-subtle":"text-success"})}),(0,b.jsx)("button",{onClick:()=>aj(d),disabled:"testing"===l,className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text disabled:opacity-60","aria-label":`Check key ${d+1}`,title:"Check this key against the base URL",children:(0,b.jsx)(k.Icon,{name:"testing"===l?"progress_activity":"wifi_tethering",size:15})}),(0,b.jsx)("button",{onClick:()=>{G(d),I(o??""),K("")},className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-text","aria-label":`Edit key ${d+1}`,title:"Rename or replace this key",children:(0,b.jsx)(k.Icon,{name:"edit",size:15})}),(0,b.jsx)("button",{onClick:()=>ap(`rmkey${d}`,()=>e.adminApi.removeKey(a,d)),className:"flex-none rounded p-1 text-text-subtle transition-colors hover:text-danger","aria-label":"Remove key",children:(0,b.jsx)(k.Icon,{name:"delete",size:15})})]}),m&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]",children:[(0,b.jsx)(g.Badge,{tone:m.ok?"live":m.reachable?"warn":"down",children:m.ok?"valid":m.reachable?`reachable (${m.status})`:"invalid"}),m.error&&(0,b.jsx)("span",{className:"truncate text-danger",children:m.error})]}),!m&&i?.last_error&&(0,b.jsxs)("div",{className:"mt-1.5 flex items-center gap-2 pl-8 text-[11.5px]",children:[(0,b.jsxs)("span",{className:"text-danger",children:[i.last_error.status?`${i.last_error.status}: `:"",i.last_error.message]}),(0,b.jsx)("span",{className:"text-text-subtle",children:new Date(i.last_error.at).toLocaleTimeString()})]})]},d)})}),(0,b.jsxs)("div",{className:"mt-3 space-y-2",children:[(0,b.jsx)(j.Input,{value:D,onChange:a=>E(a.target.value),placeholder:"key name (optional, e.g. primary)"}),(0,b.jsxs)("div",{className:"flex gap-2",children:[(0,b.jsx)(j.Input,{value:B,onChange:a=>C(a.target.value),placeholder:"add a key…",className:"font-mono text-[12.5px]"}),(0,b.jsx)(j.Button,{disabled:!B||"addkey"===z,onClick:()=>ap("addkey",async()=>{let b=await e.adminApi.addKey(a,B,D.trim()||void 0);return b.ok&&(C(""),E("")),b}),children:"Add"})]})]})]}),(0,b.jsxs)(i.RichCard,{className:"lg:col-span-2",header:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(i.CardTitle,{title:"Models served",sub:`${r.models.length} in catalog`}),r.models.length>0&&(0,b.jsx)("button",{onClick:()=>ap("clear",()=>e.adminApi.clearModels(a)),disabled:"clear"===z,className:"text-[12px] text-text-subtle hover:text-danger",children:"Clear all"})]}),children:[0===r.models.length?(0,b.jsx)(l.Empty,{children:"No models. Add one below, or fetch them for a free/auto provider."}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("p",{className:"mb-2.5 text-[12px] text-text-subtle",children:["Call any of these as ",(0,b.jsxs)("span",{className:"tnum text-text-muted",children:[r.id,"/<model>"]}),", as a combo alias, or by the bare id."]}),r.models.length>8&&(0,b.jsxs)("div",{className:"mb-2.5 flex items-center gap-2",children:[(0,b.jsxs)("div",{className:"relative flex-1",children:[(0,b.jsx)(k.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)(j.Input,{value:N,onChange:a=>O(a.target.value),placeholder:"filter models…",className:"pl-8"})]}),(0,b.jsx)("span",{className:"tnum whitespace-nowrap text-[12px] text-text-subtle",children:an?`${ao.length} of ${r.models.length}`:`${r.models.length}`})]}),0===ao.length?(0,b.jsxs)(l.Empty,{children:["No model matches “",N,"”."]}):(0,b.jsx)("div",{className:"max-h-[360px] divide-y divide-border-subtle overflow-y-auto rounded-brand border border-border-subtle",children:ao.map(c=>{let d=R[c.id];return(0,b.jsxs)("div",{className:"group flex items-center justify-between gap-3 px-3 py-2 hover:bg-bg",children:[(0,b.jsxs)("div",{className:"flex min-w-0 items-center gap-2",children:[(0,b.jsx)(k.Icon,{name:"ok"===d?"check_circle":"fail"===d?"cancel":"smart_toy",size:15,className:`flex-none ${"ok"===d?"text-success":"fail"===d?"text-danger":"text-text-subtle"}`}),(0,b.jsxs)("span",{className:"tnum truncate text-[12.5px]",children:[(0,b.jsxs)("span",{className:"text-text-subtle",children:[r.id,"/"]}),(0,b.jsx)("span",{className:"text-text",children:c.id})]}),(0,b.jsx)(o.CapacityBadges,{model:c.id,provider:r.id}),(void 0!==c.price_in||void 0!==c.price_out)&&(0,b.jsxs)("span",{className:"tnum whitespace-nowrap text-[11px] text-text-subtle",children:[l.fmt.cost(c.price_in??0),"/",l.fmt.cost(c.price_out??0)," per 1M"]})]}),(0,b.jsxs)("div",{className:"flex flex-none items-center gap-0.5",children:[(0,b.jsx)("button",{onClick:()=>ai(c.id),disabled:"testing"===d,className:"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-accent disabled:opacity-60","aria-label":`Test ${c.id}`,title:"fail"===d?"Test failed — click to retry":"Test this model",children:(0,b.jsx)(k.Icon,{name:"testing"===d?"progress_activity":"science",size:15})}),(0,b.jsx)("button",{onClick:()=>ap(`rmmodel${c.id}`,()=>e.adminApi.removeModel(a,c.id)),disabled:z===`rmmodel${c.id}`,className:"rounded p-1 text-text-subtle transition-colors hover:bg-surface hover:text-danger disabled:opacity-40","aria-label":`Remove ${c.id}`,children:(0,b.jsx)(k.Icon,{name:"delete",size:16})})]})]},c.id)})})]}),(0,b.jsxs)("div",{className:"mt-3 flex gap-2",children:[(0,b.jsx)(j.Input,{value:L,onChange:a=>M(a.target.value),placeholder:"add a model id…"}),(0,b.jsx)(j.Button,{disabled:!L||"addmodel"===z,onClick:()=>ap("addmodel",async()=>{let b=await e.adminApi.addModel(a,L);return b.ok&&M(""),b}),children:"Add"})]})]})]}),P&&(0,b.jsx)(n,{models:P,busy:"addmodels"===z,onClose:()=>Q(null),onAdd:b=>ap("addmodels",async()=>{let c=await e.adminApi.addModels(a,b);return c.ok&&Q(null),c})}),(0,b.jsx)("div",{className:"mt-6",children:(0,b.jsxs)(j.Button,{variant:"danger",onClick:()=>ah(!0),children:[(0,b.jsx)(k.Icon,{name:"delete",size:16})," Remove provider"]})}),ag&&(0,b.jsx)(p.ConfirmModal,{title:"Remove provider",message:`Delete "${r.name??a}"? All keys and model associations will be lost.`,confirmLabel:"Remove",busy:"rmprov"===z,onCancel:()=>ah(!1),onConfirm:()=>ap("rmprov",async()=>{let b=await e.adminApi.removeProvider(a);return b.ok?m.push("/providers"):ah(!1),b})})]})}],33410)}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=src_components_ProviderDetail_tsx_06sxu0r._.js.map
|