aigetwey 1.4.2 → 1.4.3
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 +20 -0
- package/README.md +8 -1
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/build-manifest.json +3 -3
- package/dashboard/.next/diagnostics/route-bundle-stats.json +26 -26
- package/dashboard/.next/fallback-build-manifest.json +3 -3
- package/dashboard/.next/server/app/(console)/combos/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/config/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/console/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/endpoint/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/keys/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/providers/[id]/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/providers/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/quota/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/tools/[id]/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/tools/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/(console)/usage/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/_global-error.html +1 -1
- package/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/server/app/_not-found.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.html +1 -1
- package/dashboard/.next/server/app/combos.rsc +5 -5
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp/combos.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/combos.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/combos.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/combos.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/combos.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.html +1 -1
- package/dashboard/.next/server/app/config.rsc +5 -5
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp/config.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/config.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/config.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/config.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/config.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.html +1 -1
- package/dashboard/.next/server/app/console.rsc +5 -5
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp/console.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/console.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/console.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/console.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/console.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.html +1 -1
- package/dashboard/.next/server/app/endpoint.rsc +5 -5
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp/endpoint.segment.rsc +1 -1
- package/dashboard/.next/server/app/endpoint.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/endpoint.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/endpoint.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/endpoint.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/endpoint.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/server/app/index.rsc +5 -5
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/keys.html +1 -1
- package/dashboard/.next/server/app/keys.rsc +5 -5
- package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp/keys/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp/keys.segment.rsc +1 -1
- package/dashboard/.next/server/app/keys.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/keys.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/keys.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/keys.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/keys.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/login.html +1 -1
- package/dashboard/.next/server/app/login.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.html +1 -1
- package/dashboard/.next/server/app/providers.rsc +5 -5
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp/providers.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/providers.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/providers.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/providers.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/providers.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.html +1 -1
- package/dashboard/.next/server/app/quota.rsc +5 -5
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp/quota.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/quota.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/quota.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/quota.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/quota.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.html +1 -1
- package/dashboard/.next/server/app/tools.rsc +5 -5
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp/tools.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/!KGNvbnNvbGUp.segment.rsc +3 -3
- package/dashboard/.next/server/app/tools.segments/_full.segment.rsc +5 -5
- package/dashboard/.next/server/app/tools.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/server/app/tools.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/server/app/tools.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0zf4yft._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/_0p90gyy._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/_0p90gyy._.js.map +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js +1 -1
- package/dashboard/.next/server/chunks/ssr/src_components_10h9ide._.js.map +1 -1
- package/dashboard/.next/server/middleware-build-manifest.js +3 -3
- package/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/static/chunks/{40pm83c1_d0jz.js → 0lcp6ibeqkbpk.js} +19 -19
- package/dashboard/.next/static/chunks/{0-qqj0_fg6ef0.js → 0wb0jg5y8b49o.js} +1 -1
- package/dashboard/.next/static/chunks/2ltht8xwlssac.js +1 -0
- package/dashboard/.next/static/chunks/2mpe3tpzx0wtj.css +3 -0
- package/dashboard/.next/trace +1 -1
- package/dashboard/.next/trace-build +1 -1
- package/dashboard/src/components/AreaChart.tsx +88 -19
- package/dashboard/src/components/AutostartToggle.tsx +63 -0
- package/dashboard/src/components/ConfigEditor.tsx +3 -0
- package/dashboard/src/components/TopBar.tsx +1 -1
- package/dist/cli/tray/autostart.js +3 -3
- package/dist/cli/tray/autostart.js.map +1 -1
- package/dist/cli.js +5 -3
- package/dist/cli.js.map +1 -1
- package/dist/core/handler.js +23 -3
- package/dist/core/handler.js.map +1 -1
- package/dist/routes/admin.js +28 -0
- package/dist/routes/admin.js.map +1 -1
- package/dist/routes/v1.js +4 -2
- package/dist/routes/v1.js.map +1 -1
- package/dist/server.js +32 -5
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/tray/autostart.ts +3 -3
- package/src/cli.ts +5 -3
- package/src/core/handler.ts +22 -3
- package/src/routes/admin.ts +27 -0
- package/src/routes/v1.ts +4 -2
- package/src/server.ts +33 -5
- package/dashboard/.next/static/chunks/0347y27liw05t.js +0 -1
- package/dashboard/.next/static/chunks/0iv69e64f1ywa.css +0 -3
- /package/dashboard/.next/static/{jKcczqYA93-Kuqa9A9H9h → 3ctBU8K8tClTVQCiGy65u}/_buildManifest.js +0 -0
- /package/dashboard/.next/static/{jKcczqYA93-Kuqa9A9H9h → 3ctBU8K8tClTVQCiGy65u}/_clientMiddlewareManifest.js +0 -0
- /package/dashboard/.next/static/{jKcczqYA93-Kuqa9A9H9h → 3ctBU8K8tClTVQCiGy65u}/_ssgManifest.js +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module.exports=[7078,a=>{"use strict";var b=a.i(87924);let c={primary:"bg-accent text-accent-ink shadow-warm hover:bg-accent-hover border border-transparent font-semibold",ghost:"bg-transparent text-text-muted border border-border hover:text-text hover:border-text-subtle",danger:"bg-transparent text-text-muted border border-border hover:text-danger hover:border-danger/50"};a.s(["Button",0,function({variant:a="primary",className:d,...e}){return(0,b.jsx)("button",{className:`inline-flex items-center justify-center gap-1.5 rounded-brand px-3.5 py-2 text-[13px] font-medium transition-colors duration-150 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed ${c[a]}${d?` ${d}`:""}`,...e})},"Field",0,function({label:a,hint:c,children:d}){return(0,b.jsxs)("label",{className:"flex flex-col gap-1.5",children:[(0,b.jsxs)("span",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:[a,c&&(0,b.jsxs)("span",{className:"ml-1.5 lowercase tracking-normal text-text-subtle/70",children:["· ",c]})]}),d]})},"Input",0,function({className:a,...c}){return(0,b.jsx)("input",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none transition-colors${a?` ${a}`:""}`,...c})},"Select",0,function({className:a,...c}){return(0,b.jsx)("select",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text focus:border-accent focus:outline-none transition-colors${a?` ${a}`:""}`,...c})}])},56173,a=>{"use strict";async function b(a,b,c){let d;try{d=await fetch(`/api/gw${b}`,{method:a,headers:void 0!==c?{"content-type":"application/json"}:{},body:void 0!==c?JSON.stringify(c):void 0})}catch(a){return{ok:!1,status:0,data:null,error:a.message}}let e=await d.text(),f=null;try{f=e?JSON.parse(e):null}catch{f=null}if(!d.ok){let a=f?.error??`request failed (${d.status})`;return{ok:!1,status:d.status,data:f,error:a}}return{ok:!0,status:d.status,data:f}}async function c(a,b,c){let d;try{d=await fetch(b,{method:a,headers:void 0!==c?{"content-type":"application/json"}:{},body:void 0!==c?JSON.stringify(c):void 0})}catch(a){return{ok:!1,status:0,data:null,error:a.message}}let e=await d.text(),f=e?JSON.parse(e):null;if(!d.ok){let a=f?.error??`request failed (${d.status})`;return{ok:!1,status:d.status,data:f,error:a}}return{ok:!0,status:d.status,data:f}}a.s(["account",0,{changePassword:(a,b)=>c("POST","/api/password",{current:a,next:b})},"adminApi",0,{providers:()=>b("GET","/admin/providers"),budgets:()=>b("GET","/admin/budgets"),models:()=>b("GET","/admin/models"),keys:()=>b("GET","/admin/keys"),keysUsage:()=>b("GET","/admin/keys/usage"),setBudget:a=>b("PUT","/admin/budgets",a),clearBudget:a=>b("DELETE",`/admin/budgets/${encodeURIComponent(a)}`),addProvider:a=>b("POST","/admin/providers",a),editProvider:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}`,c),renameProvider:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/rename`,{id:c}),removeProvider:a=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}`),addKey:(a,c,d)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/keys`,{key:c,name:d}),editKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/${c}`,d),removeKey:(a,c)=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/keys/${c}`),revealKey:(a,c)=>b("GET",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/reveal`),addModel:(a,c,d)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models`,{model:c,...d}),addModels:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models`,{models:c}),removeModel:(a,c)=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/models?model=${encodeURIComponent(c)}`),clearModels:a=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/models`),pricing:()=>b("GET","/admin/pricing"),setModelPrice:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/models/price`,{model:c,...d}),testProvider:a=>b("POST",`/admin/providers/${encodeURIComponent(a)}/test`),testKey:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/test`),testModel:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models/test?model=${encodeURIComponent(c)}`),validateProvider:a=>b("POST","/admin/providers/validate",a),discoverModels:a=>b("POST",`/admin/providers/${encodeURIComponent(a)}/connect`),reorderProvider:(a,c)=>b("PUT","/admin/providers/reorder",{from:a,to:c}),reorderKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/reorder`,{from:c,to:d}),toggleKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/toggle`,{enabled:d}),setProviderStrategy:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/strategy`,{strategy:c,sticky:d}),setProviderDisabled:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/disabled`,{disabled:c}),setRoute:(a,c)=>b("PUT",`/admin/routes/${encodeURIComponent(a)}`,c),removeRoute:a=>b("DELETE",`/admin/routes/${encodeURIComponent(a)}`),endpoint:()=>b("GET","/admin/endpoint"),setRtk:a=>b("PUT","/admin/endpoint/rtk",{enabled:a}),setCaveman:a=>b("PUT","/admin/endpoint/caveman",{level:a}),setPonytail:a=>b("PUT","/admin/endpoint/ponytail",{level:a}),addServerKey:(a,c)=>b("POST","/admin/endpoint/keys",{key:a,name:c}),editServerKey:(a,c)=>b("PUT",`/admin/endpoint/keys/${a}`,{name:c}),setServerKeyScope:(a,c)=>b("PUT",`/admin/endpoint/keys/${a}/scope`,c),removeServerKey:a=>b("DELETE",`/admin/endpoint/keys/${a}`),revealServerKey:a=>b("GET",`/admin/endpoint/keys/${a}/reveal`),setHeadroom:a=>b("PUT","/admin/endpoint/headroom",a),headroomStatus:()=>b("GET","/admin/headroom/status"),headroomStart:()=>b("POST","/admin/headroom/start"),headroomStop:()=>b("POST","/admin/headroom/stop"),putConfig:a=>b("PUT","/admin/config",{text:a}),version:()=>b("GET","/admin/version"),shutdown:()=>b("POST","/admin/shutdown")},"cliConfig",0,{status:a=>c("GET",`/api/cli-detect/${encodeURIComponent(a)}`),apply:(a,b)=>c("POST",`/api/cli-detect/${encodeURIComponent(a)}`,b),reset:a=>c("DELETE",`/api/cli-detect/${encodeURIComponent(a)}`)}])},88644,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"InvariantError",{enumerable:!0,get:function(){return d}});class d extends Error{constructor(a,b){super(`Invariant: ${a.endsWith(".")?a:a+"."} This is a bug in Next.js.`,b),this.name="InvariantError"}}},39118,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={DEFAULT_SEGMENT_KEY:function(){return l},NOT_FOUND_SEGMENT_KEY:function(){return m},PAGE_SEGMENT_KEY:function(){return k},addSearchParamsIfPageSegment:function(){return i},computeSelectedLayoutSegment:function(){return j},getSegmentValue:function(){return f},getSelectedLayoutSegmentPath:function(){return function a(b,c,d=!0,e=[]){let g;if(d)g=b[1][c];else{let a=b[1];g=a.children??Object.values(a)[0]}if(!g)return e;let h=f(g[0]);return!h||h.startsWith(k)?e:(e.push(h),a(g,c,!1,e))}},isGroupSegment:function(){return g},isParallelRouteSegment:function(){return h}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});function f(a){return Array.isArray(a)?a[1]:a}function g(a){return"("===a[0]&&a.endsWith(")")}function h(a){return a.startsWith("@")&&"@children"!==a}function i(a,b){if(a.includes(k)){let a=JSON.stringify(b);return"{}"!==a?k+"?"+a:k}return a}function j(a,b){if(!a||0===a.length)return null;let c="children"===b?a[0]:a[a.length-1];return c===l?null:c}let k="__PAGE__",l="__DEFAULT__",m="/_not-found"},54427,(a,b,c)=>{"use strict";function d(){let a,b,c=new Promise((c,d)=>{a=c,b=d});return{resolve:a,reject:b,promise:c}}Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"createPromiseWithResolvers",{enumerable:!0,get:function(){return d}})},73858,a=>{"use strict";var b=a.i(87924),c=a.i(7078),d=a.i(93026);a.s(["ConfirmModal",0,function({title:a,message:e,confirmLabel:f="Delete",onConfirm:g,onCancel:h,busy:i}){return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:h,children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-2 flex items-center gap-2",children:[(0,b.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,b.jsx)(d.Icon,{name:"warning",size:16})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:a})]}),(0,b.jsx)("p",{className:"mb-4 text-[12.5px] text-text-muted",children:e}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(c.Button,{variant:"ghost",onClick:h,children:"Cancel"}),(0,b.jsx)(c.Button,{variant:"danger",disabled:i,onClick:g,children:f})]})]})})}])},68862,a=>{"use strict";var b=a.i(87924),c=a.i(38246),d=a.i(50944),e=a.i(93026);let f=[{href:"/",label:"Endpoint",icon:"api"},{href:"/keys",label:"Access Keys",icon:"key"},{href:"/providers",label:"Providers",icon:"dns"},{href:"/combos",label:"Combos",icon:"layers"},{href:"/usage",label:"Usage",icon:"bar_chart"},{href:"/quota",label:"Budgets",icon:"data_usage"},{href:"/tools",label:"CLI Tools",icon:"terminal"}],g=[{href:"/console",label:"Server Console",icon:"terminal"},{href:"/config",label:"Settings",icon:"settings"}];a.s(["Rail",0,function(){let a=(0,d.usePathname)(),h=(0,d.useRouter)();async function i(){await fetch("/api/logout",{method:"POST"}),h.replace("/login"),h.refresh()}let j=d=>{let f,g="/"===(f=d.href)?"/"===a||a.startsWith("/endpoint"):a===f||a.startsWith(`${f}/`);return(0,b.jsx)(c.default,{href:d.href,"data-label":d.label,className:`rail-icon${g?" rail-icon-active":""}`,"aria-label":d.label,children:(0,b.jsx)(e.Icon,{name:d.icon,size:20,fill:g})},d.href)};return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(c.default,{href:"/",className:"rail-brand","aria-label":"aigetwey",children:(0,b.jsxs)("svg",{viewBox:"0 0 512 512",width:"26",height:"26","aria-hidden":!0,children:[(0,b.jsx)("text",{x:"120",y:"338",fontFamily:"ui-sans-serif, Arial, sans-serif",fontSize:"260",fontWeight:"800",textAnchor:"middle",fill:"#14140f",children:"a"}),(0,b.jsxs)("g",{fill:"none",stroke:"#14140f",strokeWidth:"34",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,b.jsx)("polyline",{points:"276,182 352,256 276,330"}),(0,b.jsx)("polyline",{points:"346,182 422,256 346,330"})]})]})}),(0,b.jsxs)("nav",{className:"flex flex-col items-center gap-3",children:[f.map(j),(0,b.jsx)("div",{className:"rail-divider"}),g.map(j)]}),(0,b.jsx)("button",{onClick:i,"data-label":"Disconnect",className:"rail-icon","aria-label":"Disconnect",children:(0,b.jsx)(e.Icon,{name:"logout",size:19})})]})}])},8255,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(50944),e=a.i(93026),f=a.i(1221),g=a.i(73858),h=a.i(56173);let i={"":"Endpoint",endpoint:"Endpoint",keys:"Access Keys",providers:"Providers",combos:"Combos",usage:"Usage",quota:"Budgets",tools:"CLI Tools",console:"Server Console",config:"Settings"},j="npm install -g aigetwey@latest";function k({current:a,latest:d,onClose:f,onShutdown:g}){let[h,i]=(0,c.useState)(!1);function l(){navigator.clipboard.writeText(j).then(()=>{i(!0),setTimeout(()=>i(!1),2e3)})}return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:f,children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-4 flex items-start justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,b.jsx)("span",{className:"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-warning/10 text-warning",children:(0,b.jsx)(e.Icon,{name:"arrow_upward",size:19})}),(0,b.jsxs)("div",{children:[(0,b.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:"Update available"}),(0,b.jsxs)("p",{className:"text-[12px] text-text-muted",children:["v",a," → ",(0,b.jsxs)("span",{className:"text-warning font-medium",children:["v",d]})]})]})]}),(0,b.jsx)("button",{onClick:f,className:"text-text-subtle hover:text-text",children:(0,b.jsx)(e.Icon,{name:"close",size:17})})]}),(0,b.jsx)("p",{className:"mb-3 text-[12.5px] text-text-muted",children:"Run this command in your terminal to update:"}),(0,b.jsxs)("div",{className:"flex items-center gap-2 rounded-brand border border-border bg-bg px-3 py-2",children:[(0,b.jsx)("code",{className:"flex-1 text-[12px] text-text",children:j}),(0,b.jsx)("button",{onClick:l,className:"flex-none text-text-subtle transition-colors hover:text-text",title:"Copy command",children:(0,b.jsx)(e.Icon,{name:h?"check":"content_copy",size:14})})]}),(0,b.jsx)("p",{className:"mt-3 text-[11.5px] text-text-subtle",children:"Shut down the gateway first, then run the command above, then restart."}),(0,b.jsxs)("div",{className:"mt-4 flex gap-2",children:[(0,b.jsxs)("button",{onClick:()=>{l(),g()},className:"flex flex-1 items-center justify-center gap-1.5 rounded-brand border border-warning/30 bg-warning/10 px-3 py-2 text-[12.5px] font-medium text-warning transition-colors hover:bg-warning/20",children:[(0,b.jsx)(e.Icon,{name:"content_copy",size:14}),"Copy & Shut down"]}),(0,b.jsx)("button",{onClick:f,className:"rounded-brand border border-border px-3 py-2 text-[12.5px] text-text-muted transition-colors hover:text-text",children:"Later"})]})]})})}a.s(["TopBar",0,function(){let a=(0,d.usePathname)(),{theme:l,toggle:m}=(0,f.useTheme)(),n="/"===a?"":a.split("/")[1]??"",o=i[n]??n,[p,q]=(0,c.useState)(null),[r,s]=(0,c.useState)(!1),[t,u]=(0,c.useState)(!1),[v,w]=(0,c.useState)(!1),[x,y]=(0,c.useState)(!1);async function z(){y(!0),await h.adminApi.shutdown(),w(!0),u(!1),s(!1),y(!1)}return(0,c.useEffect)(()=>{h.adminApi.version().then(a=>{a.ok&&a.data&&q(a.data)})},[]),(0,b.jsxs)("header",{className:"console-topbar",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 text-[13px]",children:[(0,b.jsx)("span",{className:"text-text-subtle",children:"aigetwey"}),(0,b.jsx)("span",{className:"text-text-subtle",children:"/"}),(0,b.jsx)("span",{className:"font-medium text-text",children:o})]}),(0,b.jsxs)("div",{className:"ml-auto flex items-center gap-2.5",children:[p&&(p.updateAvailable?(0,b.jsxs)("button",{onClick:()=>s(!0),className:"flex items-center gap-1.5 rounded-full border border-warning/30 bg-warning/10 px-2.5 py-1 text-[11px] font-medium text-warning transition-colors hover:bg-warning/20",children:[(0,b.jsx)(e.Icon,{name:"arrow_upward",size:12}),"v",p.current," → ",p.latest]}):(0,b.jsxs)("span",{className:"text-[11px] text-text-subtle",title:"You're on the latest version",children:["v",p.current]})),(0,b.jsx)("button",{onClick:m,className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-text","aria-label":"Toggle theme",title:"dark"===l?"Switch to light mode":"Switch to dark mode",children:(0,b.jsx)(e.Icon,{name:"dark"===l?"light_mode":"dark_mode",size:18})}),(0,b.jsx)("button",{onClick:()=>u(!0),className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-danger","aria-label":"Shut down gateway",title:"Shut down the gateway",children:(0,b.jsx)(e.Icon,{name:"power_settings_new",size:18})}),(0,b.jsxs)("div",{className:"flex items-center gap-2 rounded-full border border-border bg-surface py-1 pl-1 pr-3",children:[(0,b.jsx)("span",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-[11px] font-bold text-accent-ink",children:"A"}),(0,b.jsx)("span",{className:"text-[12px] text-text-muted",children:"admin"})]})]}),r&&p?.updateAvailable&&(0,b.jsx)(k,{current:p.current,latest:p.latest,onClose:()=>s(!1),onShutdown:z}),t&&(0,b.jsx)(g.ConfirmModal,{title:"Shut down gateway?",message:"The gateway process will stop and all requests will fail until you restart it. The dashboard stays up but can't reach the gateway.",confirmLabel:"Shut down",busy:x,onConfirm:z,onCancel:()=>u(!1)}),v&&(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6",children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 text-center shadow-elevated",children:[(0,b.jsx)("span",{className:"mx-auto mb-2 flex h-9 w-9 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,b.jsx)(e.Icon,{name:"power_settings_new",size:20})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Gateway stopped"}),(0,b.jsxs)("p",{className:"mt-1 text-[12.5px] text-text-muted",children:["Run ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:j})," then restart with ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"aigetwey"}),"."]})]})})]})}])}];
|
|
1
|
+
module.exports=[7078,a=>{"use strict";var b=a.i(87924);let c={primary:"bg-accent text-accent-ink shadow-warm hover:bg-accent-hover border border-transparent font-semibold",ghost:"bg-transparent text-text-muted border border-border hover:text-text hover:border-text-subtle",danger:"bg-transparent text-text-muted border border-border hover:text-danger hover:border-danger/50"};a.s(["Button",0,function({variant:a="primary",className:d,...e}){return(0,b.jsx)("button",{className:`inline-flex items-center justify-center gap-1.5 rounded-brand px-3.5 py-2 text-[13px] font-medium transition-colors duration-150 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed ${c[a]}${d?` ${d}`:""}`,...e})},"Field",0,function({label:a,hint:c,children:d}){return(0,b.jsxs)("label",{className:"flex flex-col gap-1.5",children:[(0,b.jsxs)("span",{className:"text-[11px] font-medium uppercase tracking-wider text-text-subtle",children:[a,c&&(0,b.jsxs)("span",{className:"ml-1.5 lowercase tracking-normal text-text-subtle/70",children:["· ",c]})]}),d]})},"Input",0,function({className:a,...c}){return(0,b.jsx)("input",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none transition-colors${a?` ${a}`:""}`,...c})},"Select",0,function({className:a,...c}){return(0,b.jsx)("select",{className:`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text focus:border-accent focus:outline-none transition-colors${a?` ${a}`:""}`,...c})}])},56173,a=>{"use strict";async function b(a,b,c){let d;try{d=await fetch(`/api/gw${b}`,{method:a,headers:void 0!==c?{"content-type":"application/json"}:{},body:void 0!==c?JSON.stringify(c):void 0})}catch(a){return{ok:!1,status:0,data:null,error:a.message}}let e=await d.text(),f=null;try{f=e?JSON.parse(e):null}catch{f=null}if(!d.ok){let a=f?.error??`request failed (${d.status})`;return{ok:!1,status:d.status,data:f,error:a}}return{ok:!0,status:d.status,data:f}}async function c(a,b,c){let d;try{d=await fetch(b,{method:a,headers:void 0!==c?{"content-type":"application/json"}:{},body:void 0!==c?JSON.stringify(c):void 0})}catch(a){return{ok:!1,status:0,data:null,error:a.message}}let e=await d.text(),f=e?JSON.parse(e):null;if(!d.ok){let a=f?.error??`request failed (${d.status})`;return{ok:!1,status:d.status,data:f,error:a}}return{ok:!0,status:d.status,data:f}}a.s(["account",0,{changePassword:(a,b)=>c("POST","/api/password",{current:a,next:b})},"adminApi",0,{providers:()=>b("GET","/admin/providers"),budgets:()=>b("GET","/admin/budgets"),models:()=>b("GET","/admin/models"),keys:()=>b("GET","/admin/keys"),keysUsage:()=>b("GET","/admin/keys/usage"),setBudget:a=>b("PUT","/admin/budgets",a),clearBudget:a=>b("DELETE",`/admin/budgets/${encodeURIComponent(a)}`),addProvider:a=>b("POST","/admin/providers",a),editProvider:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}`,c),renameProvider:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/rename`,{id:c}),removeProvider:a=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}`),addKey:(a,c,d)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/keys`,{key:c,name:d}),editKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/${c}`,d),removeKey:(a,c)=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/keys/${c}`),revealKey:(a,c)=>b("GET",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/reveal`),addModel:(a,c,d)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models`,{model:c,...d}),addModels:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models`,{models:c}),removeModel:(a,c)=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/models?model=${encodeURIComponent(c)}`),clearModels:a=>b("DELETE",`/admin/providers/${encodeURIComponent(a)}/models`),pricing:()=>b("GET","/admin/pricing"),setModelPrice:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/models/price`,{model:c,...d}),testProvider:a=>b("POST",`/admin/providers/${encodeURIComponent(a)}/test`),testKey:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/test`),testModel:(a,c)=>b("POST",`/admin/providers/${encodeURIComponent(a)}/models/test?model=${encodeURIComponent(c)}`),validateProvider:a=>b("POST","/admin/providers/validate",a),discoverModels:a=>b("POST",`/admin/providers/${encodeURIComponent(a)}/connect`),reorderProvider:(a,c)=>b("PUT","/admin/providers/reorder",{from:a,to:c}),reorderKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/reorder`,{from:c,to:d}),toggleKey:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/keys/${c}/toggle`,{enabled:d}),setProviderStrategy:(a,c,d)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/strategy`,{strategy:c,sticky:d}),setProviderDisabled:(a,c)=>b("PUT",`/admin/providers/${encodeURIComponent(a)}/disabled`,{disabled:c}),setRoute:(a,c)=>b("PUT",`/admin/routes/${encodeURIComponent(a)}`,c),removeRoute:a=>b("DELETE",`/admin/routes/${encodeURIComponent(a)}`),endpoint:()=>b("GET","/admin/endpoint"),setRtk:a=>b("PUT","/admin/endpoint/rtk",{enabled:a}),setCaveman:a=>b("PUT","/admin/endpoint/caveman",{level:a}),setPonytail:a=>b("PUT","/admin/endpoint/ponytail",{level:a}),addServerKey:(a,c)=>b("POST","/admin/endpoint/keys",{key:a,name:c}),editServerKey:(a,c)=>b("PUT",`/admin/endpoint/keys/${a}`,{name:c}),setServerKeyScope:(a,c)=>b("PUT",`/admin/endpoint/keys/${a}/scope`,c),removeServerKey:a=>b("DELETE",`/admin/endpoint/keys/${a}`),revealServerKey:a=>b("GET",`/admin/endpoint/keys/${a}/reveal`),setHeadroom:a=>b("PUT","/admin/endpoint/headroom",a),headroomStatus:()=>b("GET","/admin/headroom/status"),headroomStart:()=>b("POST","/admin/headroom/start"),headroomStop:()=>b("POST","/admin/headroom/stop"),putConfig:a=>b("PUT","/admin/config",{text:a}),version:()=>b("GET","/admin/version"),shutdown:()=>b("POST","/admin/shutdown")},"cliConfig",0,{status:a=>c("GET",`/api/cli-detect/${encodeURIComponent(a)}`),apply:(a,b)=>c("POST",`/api/cli-detect/${encodeURIComponent(a)}`,b),reset:a=>c("DELETE",`/api/cli-detect/${encodeURIComponent(a)}`)}])},88644,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"InvariantError",{enumerable:!0,get:function(){return d}});class d extends Error{constructor(a,b){super(`Invariant: ${a.endsWith(".")?a:a+"."} This is a bug in Next.js.`,b),this.name="InvariantError"}}},39118,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={DEFAULT_SEGMENT_KEY:function(){return l},NOT_FOUND_SEGMENT_KEY:function(){return m},PAGE_SEGMENT_KEY:function(){return k},addSearchParamsIfPageSegment:function(){return i},computeSelectedLayoutSegment:function(){return j},getSegmentValue:function(){return f},getSelectedLayoutSegmentPath:function(){return function a(b,c,d=!0,e=[]){let g;if(d)g=b[1][c];else{let a=b[1];g=a.children??Object.values(a)[0]}if(!g)return e;let h=f(g[0]);return!h||h.startsWith(k)?e:(e.push(h),a(g,c,!1,e))}},isGroupSegment:function(){return g},isParallelRouteSegment:function(){return h}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});function f(a){return Array.isArray(a)?a[1]:a}function g(a){return"("===a[0]&&a.endsWith(")")}function h(a){return a.startsWith("@")&&"@children"!==a}function i(a,b){if(a.includes(k)){let a=JSON.stringify(b);return"{}"!==a?k+"?"+a:k}return a}function j(a,b){if(!a||0===a.length)return null;let c="children"===b?a[0]:a[a.length-1];return c===l?null:c}let k="__PAGE__",l="__DEFAULT__",m="/_not-found"},54427,(a,b,c)=>{"use strict";function d(){let a,b,c=new Promise((c,d)=>{a=c,b=d});return{resolve:a,reject:b,promise:c}}Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"createPromiseWithResolvers",{enumerable:!0,get:function(){return d}})},73858,a=>{"use strict";var b=a.i(87924),c=a.i(7078),d=a.i(93026);a.s(["ConfirmModal",0,function({title:a,message:e,confirmLabel:f="Delete",onConfirm:g,onCancel:h,busy:i}){return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:h,children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-2 flex items-center gap-2",children:[(0,b.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,b.jsx)(d.Icon,{name:"warning",size:16})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:a})]}),(0,b.jsx)("p",{className:"mb-4 text-[12.5px] text-text-muted",children:e}),(0,b.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,b.jsx)(c.Button,{variant:"ghost",onClick:h,children:"Cancel"}),(0,b.jsx)(c.Button,{variant:"danger",disabled:i,onClick:g,children:f})]})]})})}])},68862,a=>{"use strict";var b=a.i(87924),c=a.i(38246),d=a.i(50944),e=a.i(93026);let f=[{href:"/",label:"Endpoint",icon:"api"},{href:"/keys",label:"Access Keys",icon:"key"},{href:"/providers",label:"Providers",icon:"dns"},{href:"/combos",label:"Combos",icon:"layers"},{href:"/usage",label:"Usage",icon:"bar_chart"},{href:"/quota",label:"Budgets",icon:"data_usage"},{href:"/tools",label:"CLI Tools",icon:"terminal"}],g=[{href:"/console",label:"Server Console",icon:"terminal"},{href:"/config",label:"Settings",icon:"settings"}];a.s(["Rail",0,function(){let a=(0,d.usePathname)(),h=(0,d.useRouter)();async function i(){await fetch("/api/logout",{method:"POST"}),h.replace("/login"),h.refresh()}let j=d=>{let f,g="/"===(f=d.href)?"/"===a||a.startsWith("/endpoint"):a===f||a.startsWith(`${f}/`);return(0,b.jsx)(c.default,{href:d.href,"data-label":d.label,className:`rail-icon${g?" rail-icon-active":""}`,"aria-label":d.label,children:(0,b.jsx)(e.Icon,{name:d.icon,size:20,fill:g})},d.href)};return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(c.default,{href:"/",className:"rail-brand","aria-label":"aigetwey",children:(0,b.jsxs)("svg",{viewBox:"0 0 512 512",width:"26",height:"26","aria-hidden":!0,children:[(0,b.jsx)("text",{x:"120",y:"338",fontFamily:"ui-sans-serif, Arial, sans-serif",fontSize:"260",fontWeight:"800",textAnchor:"middle",fill:"#14140f",children:"a"}),(0,b.jsxs)("g",{fill:"none",stroke:"#14140f",strokeWidth:"34",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,b.jsx)("polyline",{points:"276,182 352,256 276,330"}),(0,b.jsx)("polyline",{points:"346,182 422,256 346,330"})]})]})}),(0,b.jsxs)("nav",{className:"flex flex-col items-center gap-3",children:[f.map(j),(0,b.jsx)("div",{className:"rail-divider"}),g.map(j)]}),(0,b.jsx)("button",{onClick:i,"data-label":"Disconnect",className:"rail-icon","aria-label":"Disconnect",children:(0,b.jsx)(e.Icon,{name:"logout",size:19})})]})}])},8255,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(50944),e=a.i(93026),f=a.i(1221),g=a.i(73858),h=a.i(56173);let i={"":"Endpoint",endpoint:"Endpoint",keys:"Access Keys",providers:"Providers",combos:"Combos",usage:"Usage",quota:"Budgets",tools:"CLI Tools",console:"Server Console",config:"Settings"},j="npm i -g aigetwey@latest --prefer-online";function k({current:a,latest:d,onClose:f,onShutdown:g}){let[h,i]=(0,c.useState)(!1);function l(){navigator.clipboard.writeText(j).then(()=>{i(!0),setTimeout(()=>i(!1),2e3)})}return(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6",onClick:f,children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated",onClick:a=>a.stopPropagation(),children:[(0,b.jsxs)("div",{className:"mb-4 flex items-start justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,b.jsx)("span",{className:"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-warning/10 text-warning",children:(0,b.jsx)(e.Icon,{name:"arrow_upward",size:19})}),(0,b.jsxs)("div",{children:[(0,b.jsx)("h2",{className:"text-[14px] font-semibold text-text",children:"Update available"}),(0,b.jsxs)("p",{className:"text-[12px] text-text-muted",children:["v",a," → ",(0,b.jsxs)("span",{className:"text-warning font-medium",children:["v",d]})]})]})]}),(0,b.jsx)("button",{onClick:f,className:"text-text-subtle hover:text-text",children:(0,b.jsx)(e.Icon,{name:"close",size:17})})]}),(0,b.jsx)("p",{className:"mb-3 text-[12.5px] text-text-muted",children:"Run this command in your terminal to update:"}),(0,b.jsxs)("div",{className:"flex items-center gap-2 rounded-brand border border-border bg-bg px-3 py-2",children:[(0,b.jsx)("code",{className:"flex-1 text-[12px] text-text",children:j}),(0,b.jsx)("button",{onClick:l,className:"flex-none text-text-subtle transition-colors hover:text-text",title:"Copy command",children:(0,b.jsx)(e.Icon,{name:h?"check":"content_copy",size:14})})]}),(0,b.jsx)("p",{className:"mt-3 text-[11.5px] text-text-subtle",children:"Shut down the gateway first, then run the command above, then restart."}),(0,b.jsxs)("div",{className:"mt-4 flex gap-2",children:[(0,b.jsxs)("button",{onClick:()=>{l(),g()},className:"flex flex-1 items-center justify-center gap-1.5 rounded-brand border border-warning/30 bg-warning/10 px-3 py-2 text-[12.5px] font-medium text-warning transition-colors hover:bg-warning/20",children:[(0,b.jsx)(e.Icon,{name:"content_copy",size:14}),"Copy & Shut down"]}),(0,b.jsx)("button",{onClick:f,className:"rounded-brand border border-border px-3 py-2 text-[12.5px] text-text-muted transition-colors hover:text-text",children:"Later"})]})]})})}a.s(["TopBar",0,function(){let a=(0,d.usePathname)(),{theme:l,toggle:m}=(0,f.useTheme)(),n="/"===a?"":a.split("/")[1]??"",o=i[n]??n,[p,q]=(0,c.useState)(null),[r,s]=(0,c.useState)(!1),[t,u]=(0,c.useState)(!1),[v,w]=(0,c.useState)(!1),[x,y]=(0,c.useState)(!1);async function z(){y(!0),await h.adminApi.shutdown(),w(!0),u(!1),s(!1),y(!1)}return(0,c.useEffect)(()=>{h.adminApi.version().then(a=>{a.ok&&a.data&&q(a.data)})},[]),(0,b.jsxs)("header",{className:"console-topbar",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 text-[13px]",children:[(0,b.jsx)("span",{className:"text-text-subtle",children:"aigetwey"}),(0,b.jsx)("span",{className:"text-text-subtle",children:"/"}),(0,b.jsx)("span",{className:"font-medium text-text",children:o})]}),(0,b.jsxs)("div",{className:"ml-auto flex items-center gap-2.5",children:[p&&(p.updateAvailable?(0,b.jsxs)("button",{onClick:()=>s(!0),className:"flex items-center gap-1.5 rounded-full border border-warning/30 bg-warning/10 px-2.5 py-1 text-[11px] font-medium text-warning transition-colors hover:bg-warning/20",children:[(0,b.jsx)(e.Icon,{name:"arrow_upward",size:12}),"v",p.current," → ",p.latest]}):(0,b.jsxs)("span",{className:"text-[11px] text-text-subtle",title:"You're on the latest version",children:["v",p.current]})),(0,b.jsx)("button",{onClick:m,className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-text","aria-label":"Toggle theme",title:"dark"===l?"Switch to light mode":"Switch to dark mode",children:(0,b.jsx)(e.Icon,{name:"dark"===l?"light_mode":"dark_mode",size:18})}),(0,b.jsx)("button",{onClick:()=>u(!0),className:"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-danger","aria-label":"Shut down gateway",title:"Shut down the gateway",children:(0,b.jsx)(e.Icon,{name:"power_settings_new",size:18})}),(0,b.jsxs)("div",{className:"flex items-center gap-2 rounded-full border border-border bg-surface py-1 pl-1 pr-3",children:[(0,b.jsx)("span",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-[11px] font-bold text-accent-ink",children:"A"}),(0,b.jsx)("span",{className:"text-[12px] text-text-muted",children:"admin"})]})]}),r&&p?.updateAvailable&&(0,b.jsx)(k,{current:p.current,latest:p.latest,onClose:()=>s(!1),onShutdown:z}),t&&(0,b.jsx)(g.ConfirmModal,{title:"Shut down gateway?",message:"The gateway process will stop and all requests will fail until you restart it. The dashboard stays up but can't reach the gateway.",confirmLabel:"Shut down",busy:x,onConfirm:z,onCancel:()=>u(!1)}),v&&(0,b.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6",children:(0,b.jsxs)("div",{className:"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 text-center shadow-elevated",children:[(0,b.jsx)("span",{className:"mx-auto mb-2 flex h-9 w-9 items-center justify-center rounded-full bg-danger/10 text-danger",children:(0,b.jsx)(e.Icon,{name:"power_settings_new",size:20})}),(0,b.jsx)("h2",{className:"text-[15px] font-semibold text-text",children:"Gateway stopped"}),(0,b.jsxs)("p",{className:"mt-1 text-[12.5px] text-text-muted",children:["Run ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:j})," then restart with ",(0,b.jsx)("code",{className:"rounded bg-surface-2 px-1",children:"aigetwey"}),"."]})]})})]})}])}];
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=_0p90gyy._.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Button.tsx","../../../../src/lib/client.ts","../../../../node_modules/next/src/shared/lib/invariant-error.ts","../../../../node_modules/next/src/shared/lib/segment.ts","../../../../node_modules/next/src/shared/lib/promise-with-resolvers.ts","../../../../src/components/ConfirmModal.tsx","../../../../src/components/Rail.tsx","../../../../src/components/TopBar.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\n\ntype Variant = \"primary\" | \"ghost\" | \"danger\";\n\nconst VARIANTS: Record<Variant, string> = {\n primary: \"bg-accent text-accent-ink shadow-warm hover:bg-accent-hover border border-transparent font-semibold\",\n ghost: \"bg-transparent text-text-muted border border-border hover:text-text hover:border-text-subtle\",\n danger: \"bg-transparent text-text-muted border border-border hover:text-danger hover:border-danger/50\",\n};\n\nexport function Button({\n variant = \"primary\",\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { variant?: Variant }) {\n return (\n <button\n className={`inline-flex items-center justify-center gap-1.5 rounded-brand px-3.5 py-2 text-[13px] font-medium transition-colors duration-150 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed ${VARIANTS[variant]}${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Input({ className, ...props }: React.InputHTMLAttributes<HTMLInputElement>) {\n return (\n <input\n className={`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none transition-colors${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Select({ className, ...props }: React.SelectHTMLAttributes<HTMLSelectElement>) {\n return (\n <select\n className={`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text focus:border-accent focus:outline-none transition-colors${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Field({\n label,\n hint,\n children,\n}: {\n label: string;\n hint?: string;\n children: React.ReactNode;\n}) {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">\n {label}\n {hint && <span className=\"ml-1.5 lowercase tracking-normal text-text-subtle/70\">· {hint}</span>}\n </span>\n {children}\n </label>\n );\n}\n","\"use client\";\n\n/**\n * Browser-side admin client. Talks to the gateway THROUGH the same-origin proxy\n * (`/api/gw/admin/...`), which injects the admin Bearer server-side — so the\n * password never reaches the browser. Server components read initial data via\n * lib/gateway.ts directly; client components mutate through here.\n */\nimport type {\n BudgetStatus,\n ConfigReply,\n EndpointPayload,\n HeadroomStatusReply,\n InjectLevel,\n KeyUsageRow,\n ModelsPayload,\n PingResult,\n PricingPayload,\n ProviderSnapshot,\n WireFormat,\n} from \"./gateway\";\n\nexport interface ApiResult<T> {\n ok: boolean;\n status: number;\n data: T | null;\n error?: string;\n}\n\nasync function api<T>(method: string, path: string, body?: unknown): Promise<ApiResult<T>> {\n let res: Response;\n try {\n res = await fetch(`/api/gw${path}`, {\n method,\n headers: body !== undefined ? { \"content-type\": \"application/json\" } : {},\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e) {\n return { ok: false, status: 0, data: null, error: (e as Error).message };\n }\n const text = await res.text();\n let data: T | null = null;\n try {\n data = text ? (JSON.parse(text) as T) : null;\n } catch {\n data = null;\n }\n if (!res.ok) {\n const err = (data as { error?: string } | null)?.error ?? `request failed (${res.status})`;\n return { ok: false, status: res.status, data, error: err };\n }\n return { ok: true, status: res.status, data };\n}\n\nexport const adminApi = {\n providers: () => api<{ providers: ProviderSnapshot[] }>(\"GET\", \"/admin/providers\"),\n budgets: () => api<{ budgets: BudgetStatus[] }>(\"GET\", \"/admin/budgets\"),\n models: () => api<ModelsPayload>(\"GET\", \"/admin/models\"),\n keys: () => api<Array<{ fingerprint: string; name: string; masked: string }>>(\"GET\", \"/admin/keys\"),\n keysUsage: () => api<{ keys: KeyUsageRow[] }>(\"GET\", \"/admin/keys/usage\"),\n\n setBudget: (body: {\n scope: { type: \"global\" } | { type: \"provider\"; id: string } | { type: \"model\"; id: string } | { type: \"key\"; id: string };\n unit: \"usd\" | \"tokens\";\n limit: number;\n window: \"5h\" | \"24h\" | \"7day\" | \"30day\";\n alert_at?: number;\n note?: string;\n }) => api<ConfigReply>(\"PUT\", \"/admin/budgets\", body),\n clearBudget: (key: string) => api<ConfigReply>(\"DELETE\", `/admin/budgets/${encodeURIComponent(key)}`),\n\n addProvider: (p: {\n id: string;\n name?: string;\n format: WireFormat;\n base_url: string;\n api_key?: string;\n free?: boolean;\n auto_models?: boolean;\n service_account?: string;\n }) => api<ConfigReply>(\"POST\", \"/admin/providers\", p),\n editProvider: (id: string, patch: { base_url?: string; format?: WireFormat; name?: string }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}`, patch),\n renameProvider: (id: string, newId: string) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/rename`, { id: newId }),\n removeProvider: (id: string) => api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}`),\n addKey: (id: string, key: string, name?: string) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/keys`, { key, name }),\n editKey: (id: string, index: number, patch: { key?: string; name?: string }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}`, patch),\n removeKey: (id: string, index: number) =>\n api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}`),\n revealKey: (id: string, index: number) =>\n api<{ key: string }>(\"GET\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/reveal`),\n addModel: (id: string, model: string, price?: { price_in?: number; price_out?: number }) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/models`, { model, ...price }),\n addModels: (id: string, models: string[]) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/models`, { models }),\n // model id can hold a slash (provider/model); send it as a query param so the\n // proxy's path split doesn't mangle it.\n removeModel: (id: string, model: string) =>\n api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/models?model=${encodeURIComponent(model)}`),\n clearModels: (id: string) => api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/models`),\n pricing: () => api<PricingPayload>(\"GET\", \"/admin/pricing\"),\n setModelPrice: (id: string, model: string, price: { price_in?: number | null; price_out?: number | null }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/models/price`, { model, ...price }),\n testProvider: (id: string) => api<PingResult>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/test`),\n testKey: (id: string, index: number) =>\n api<PingResult>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/test`),\n testModel: (id: string, model: string) =>\n api<{ ok: boolean; status?: number; error?: string }>(\n \"POST\",\n `/admin/providers/${encodeURIComponent(id)}/models/test?model=${encodeURIComponent(model)}`,\n ),\n validateProvider: (b: { format: WireFormat; base_url: string; api_key?: string }) =>\n api<PingResult>(\"POST\", \"/admin/providers/validate\", b),\n // discover: returns the upstream catalog flagged with which ids are in config.\n discoverModels: (id: string) =>\n api<{ ok: boolean; models: Array<{ id: string; added: boolean }> }>(\n \"POST\",\n `/admin/providers/${encodeURIComponent(id)}/connect`,\n ),\n\n reorderProvider: (from: number, to: number) =>\n api<ConfigReply>(\"PUT\", \"/admin/providers/reorder\", { from, to }),\n reorderKey: (id: string, from: number, to: number) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/reorder`, { from, to }),\n toggleKey: (id: string, index: number, enabled: boolean) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/toggle`, { enabled }),\n setProviderStrategy: (id: string, strategy: \"fallback\" | \"round-robin\" | null, sticky?: number) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/strategy`, { strategy, sticky }),\n setProviderDisabled: (id: string, disabled: boolean) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/disabled`, { disabled }),\n\n setRoute: (\n alias: string,\n body: { target: string[]; model?: string | string[]; strategy?: \"fallback\" | \"round-robin\"; price_in?: number; price_out?: number },\n ) => api<ConfigReply>(\"PUT\", `/admin/routes/${encodeURIComponent(alias)}`, body),\n removeRoute: (alias: string) => api<ConfigReply>(\"DELETE\", `/admin/routes/${encodeURIComponent(alias)}`),\n\n endpoint: () => api<EndpointPayload>(\"GET\", \"/admin/endpoint\"),\n setRtk: (enabled: boolean) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/rtk\", { enabled }),\n setCaveman: (level: InjectLevel) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/caveman\", { level }),\n setPonytail: (level: InjectLevel) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/ponytail\", { level }),\n addServerKey: (key: string, name?: string) => api<ConfigReply>(\"POST\", \"/admin/endpoint/keys\", { key, name }),\n editServerKey: (index: number, name: string) => api<ConfigReply>(\"PUT\", `/admin/endpoint/keys/${index}`, { name }),\n setServerKeyScope: (index: number, body: { models?: string[]; rpm?: number | null; expires?: number | null }) =>\n api<ConfigReply>(\"PUT\", `/admin/endpoint/keys/${index}/scope`, body),\n removeServerKey: (index: number) => api<ConfigReply>(\"DELETE\", `/admin/endpoint/keys/${index}`),\n revealServerKey: (index: number) => api<{ key: string }>(\"GET\", `/admin/endpoint/keys/${index}/reveal`),\n\n setHeadroom: (patch: { enabled?: boolean; url?: string; compress_user_messages?: boolean }) =>\n api<ConfigReply>(\"PUT\", \"/admin/endpoint/headroom\", patch),\n headroomStatus: () => api<HeadroomStatusReply>(\"GET\", \"/admin/headroom/status\"),\n headroomStart: () => api<{ success?: boolean; pid?: number; alreadyRunning?: boolean }>(\"POST\", \"/admin/headroom/start\"),\n headroomStop: () => api<{ stopped: boolean; reason?: string; pid?: number }>(\"POST\", \"/admin/headroom/stop\"),\n\n putConfig: (text: string) => api<{ ok: boolean }>(\"PUT\", \"/admin/config\", { text }),\n\n version: () => api<{ current: string; latest: string | null; updateAvailable: boolean }>(\"GET\", \"/admin/version\"),\n shutdown: () => api<{ ok: boolean; message: string }>(\"POST\", \"/admin/shutdown\"),\n};\n\n// Local CLI-tool detection/auto-config. These hit the dashboard's OWN server\n// routes (/api/cli-detect/*), not the gateway proxy — they read/write the tool's\n// config file on this machine. Session-gated by middleware like everything else.\nexport interface CliStatus {\n auto: boolean;\n installed: boolean;\n configured?: boolean;\n path?: string;\n baseUrl?: string | null;\n models?: string[];\n activeModel?: string | null;\n // claude returns its three slot defaults instead of a flat list\n modelSlots?: { opus?: string | null; sonnet?: string | null; haiku?: string | null };\n}\n\nasync function appApi<T>(method: string, url: string, body?: unknown): Promise<ApiResult<T>> {\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: body !== undefined ? { \"content-type\": \"application/json\" } : {},\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e) {\n return { ok: false, status: 0, data: null, error: (e as Error).message };\n }\n const text = await res.text();\n const data = text ? (JSON.parse(text) as T) : null;\n if (!res.ok) {\n const err = (data as { error?: string } | null)?.error ?? `request failed (${res.status})`;\n return { ok: false, status: res.status, data, error: err };\n }\n return { ok: true, status: res.status, data };\n}\n\n/** Admin account actions that hit the dashboard's OWN routes (not the gw proxy). */\nexport const account = {\n changePassword: (current: string, next: string) =>\n appApi<{ ok: boolean }>(\"POST\", \"/api/password\", { current, next }),\n};\n\nexport const cliConfig = {\n status: (tool: string) => appApi<CliStatus>(\"GET\", `/api/cli-detect/${encodeURIComponent(tool)}`),\n apply: (tool: string, body: { base: string; key?: string; models?: string[] | Record<string, string>; active?: string }) =>\n appApi<{ success?: boolean; path?: string }>(\"POST\", `/api/cli-detect/${encodeURIComponent(tool)}`, body),\n reset: (tool: string) => appApi<{ success?: boolean }>(\"DELETE\", `/api/cli-detect/${encodeURIComponent(tool)}`),\n};\n","export class InvariantError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(\n `Invariant: ${message.endsWith('.') ? message : message + '.'} This is a bug in Next.js.`,\n options\n )\n this.name = 'InvariantError'\n }\n}\n","import type { FlightRouterState, Segment } from './app-router-types'\n\nexport function getSegmentValue(segment: Segment) {\n return Array.isArray(segment) ? segment[1] : segment\n}\n\nexport function isGroupSegment(segment: string) {\n // Use array[0] for performant purpose\n return segment[0] === '(' && segment.endsWith(')')\n}\n\nexport function isParallelRouteSegment(segment: string) {\n return segment.startsWith('@') && segment !== '@children'\n}\n\nexport function addSearchParamsIfPageSegment(\n segment: Segment,\n searchParams: Record<string, string | string[] | undefined>\n) {\n const isPageSegment = segment.includes(PAGE_SEGMENT_KEY)\n\n if (isPageSegment) {\n const stringifiedQuery = JSON.stringify(searchParams)\n return stringifiedQuery !== '{}'\n ? PAGE_SEGMENT_KEY + '?' + stringifiedQuery\n : PAGE_SEGMENT_KEY\n }\n\n return segment\n}\n\nexport function computeSelectedLayoutSegment(\n segments: string[] | null,\n parallelRouteKey: string\n): string | null {\n if (!segments || segments.length === 0) {\n return null\n }\n\n // For 'children', use first segment; for other parallel routes, use last segment\n const rawSegment =\n parallelRouteKey === 'children'\n ? segments[0]\n : segments[segments.length - 1]\n\n // If the default slot is showing, return null since it's not technically \"selected\" (it's a fallback)\n // Returning an internal value like `__DEFAULT__` would be confusing\n return rawSegment === DEFAULT_SEGMENT_KEY ? null : rawSegment\n}\n\n/** Get the canonical parameters from the current level to the leaf node. */\nexport function getSelectedLayoutSegmentPath(\n tree: FlightRouterState,\n parallelRouteKey: string,\n first = true,\n segmentPath: string[] = []\n): string[] {\n let node: FlightRouterState\n if (first) {\n // Use the provided parallel route key on the first parallel route\n node = tree[1][parallelRouteKey]\n } else {\n // After first parallel route prefer children, if there's no children pick the first parallel route.\n const parallelRoutes = tree[1]\n node = parallelRoutes.children ?? Object.values(parallelRoutes)[0]\n }\n\n if (!node) return segmentPath\n const segment = node[0]\n\n let segmentValue = getSegmentValue(segment)\n\n if (!segmentValue || segmentValue.startsWith(PAGE_SEGMENT_KEY)) {\n return segmentPath\n }\n\n segmentPath.push(segmentValue)\n\n return getSelectedLayoutSegmentPath(\n node,\n parallelRouteKey,\n false,\n segmentPath\n )\n}\n\nexport const PAGE_SEGMENT_KEY = '__PAGE__'\nexport const DEFAULT_SEGMENT_KEY = '__DEFAULT__'\nexport const NOT_FOUND_SEGMENT_KEY = '/_not-found'\n","export function createPromiseWithResolvers<T>(): PromiseWithResolvers<T> {\n // Shim of Stage 4 Promise.withResolvers proposal\n let resolve: (value: T | PromiseLike<T>) => void\n let reject: (reason: any) => void\n const promise = new Promise<T>((res, rej) => {\n resolve = res\n reject = rej\n })\n return { resolve: resolve!, reject: reject!, promise }\n}\n","\"use client\";\n\nimport { Button } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\n\ninterface ConfirmModalProps {\n title: string;\n message: string;\n confirmLabel?: string;\n onConfirm: () => void;\n onCancel: () => void;\n busy?: boolean;\n}\n\nexport function ConfirmModal({ title, message, confirmLabel = \"Delete\", onConfirm, onCancel, busy }: ConfirmModalProps) {\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6\" onClick={onCancel}>\n <div\n className=\"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-2 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-danger/10 text-danger\">\n <Icon name=\"warning\" size={16} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">{title}</h2>\n </div>\n <p className=\"mb-4 text-[12.5px] text-text-muted\">{message}</p>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button variant=\"danger\" disabled={busy} onClick={onConfirm}>{confirmLabel}</Button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport Link from \"next/link\";\nimport { usePathname, useRouter } from \"next/navigation\";\nimport { Icon } from \"./Icon\";\n\n// Floating icon-rail (user's preferred chrome), carrying aigetwey's IA: Endpoint\n// is the landing, routing lives in Combos, and operational pages sit below a\n// divider. Labels surface as hover tooltips (data-label).\ntype NavItem = { href: string; label: string; icon: string };\n\nconst MAIN: NavItem[] = [\n { href: \"/\", label: \"Endpoint\", icon: \"api\" },\n { href: \"/keys\", label: \"Access Keys\", icon: \"key\" },\n { href: \"/providers\", label: \"Providers\", icon: \"dns\" },\n { href: \"/combos\", label: \"Combos\", icon: \"layers\" },\n { href: \"/usage\", label: \"Usage\", icon: \"bar_chart\" },\n { href: \"/quota\", label: \"Budgets\", icon: \"data_usage\" },\n { href: \"/tools\", label: \"CLI Tools\", icon: \"terminal\" },\n];\n\nconst SYSTEM: NavItem[] = [\n { href: \"/console\", label: \"Server Console\", icon: \"terminal\" },\n { href: \"/config\", label: \"Settings\", icon: \"settings\" },\n];\n\nexport function Rail() {\n const path = usePathname();\n const router = useRouter();\n\n async function logout() {\n await fetch(\"/api/logout\", { method: \"POST\" });\n router.replace(\"/login\");\n router.refresh();\n }\n\n // Endpoint owns both \"/\" (landing) and \"/endpoint\"; others match the segment\n // and its sub-routes (e.g. /providers/[id]).\n const isActive = (href: string) =>\n href === \"/\"\n ? path === \"/\" || path.startsWith(\"/endpoint\")\n : path === href || path.startsWith(`${href}/`);\n\n const link = (item: NavItem) => {\n const active = isActive(item.href);\n return (\n <Link\n key={item.href}\n href={item.href}\n data-label={item.label}\n className={`rail-icon${active ? \" rail-icon-active\" : \"\"}`}\n aria-label={item.label}\n >\n <Icon name={item.icon} size={20} fill={active} />\n </Link>\n );\n };\n\n return (\n <>\n <Link href=\"/\" className=\"rail-brand\" aria-label=\"aigetwey\">\n {/* \"a»\" mark — ink on the lime tile (CSS provides the tile) */}\n <svg viewBox=\"0 0 512 512\" width=\"26\" height=\"26\" aria-hidden>\n <text x=\"120\" y=\"338\" fontFamily=\"ui-sans-serif, Arial, sans-serif\" fontSize=\"260\" fontWeight=\"800\" textAnchor=\"middle\" fill=\"#14140f\">a</text>\n <g fill=\"none\" stroke=\"#14140f\" strokeWidth=\"34\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"276,182 352,256 276,330\" />\n <polyline points=\"346,182 422,256 346,330\" />\n </g>\n </svg>\n </Link>\n\n <nav className=\"flex flex-col items-center gap-3\">\n {MAIN.map(link)}\n <div className=\"rail-divider\" />\n {SYSTEM.map(link)}\n </nav>\n\n <button onClick={logout} data-label=\"Disconnect\" className=\"rail-icon\" aria-label=\"Disconnect\">\n <Icon name=\"logout\" size={19} />\n </button>\n </>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { Icon } from \"./Icon\";\nimport { useTheme } from \"./ThemeProvider\";\nimport { ConfirmModal } from \"./ConfirmModal\";\nimport { adminApi } from \"@/lib/client\";\n\nconst LABELS: Record<string, string> = {\n \"\": \"Endpoint\",\n endpoint: \"Endpoint\",\n keys: \"Access Keys\",\n providers: \"Providers\",\n combos: \"Combos\",\n usage: \"Usage\",\n quota: \"Budgets\",\n tools: \"CLI Tools\",\n console: \"Server Console\",\n config: \"Settings\",\n};\n\nconst CMD = \"npm install -g aigetwey@latest\";\n\nfunction UpdateModal({\n current,\n latest,\n onClose,\n onShutdown,\n}: {\n current: string;\n latest: string;\n onClose: () => void;\n onShutdown: () => void;\n}) {\n const [copied, setCopied] = useState(false);\n\n function copy() {\n void navigator.clipboard.writeText(CMD).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\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-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2.5\">\n <span className=\"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-warning/10 text-warning\">\n <Icon name=\"arrow_upward\" size={19} />\n </span>\n <div>\n <h2 className=\"text-[14px] font-semibold text-text\">Update available</h2>\n <p className=\"text-[12px] text-text-muted\">\n v{current} → <span className=\"text-warning font-medium\">v{latest}</span>\n </p>\n </div>\n </div>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\">\n <Icon name=\"close\" size={17} />\n </button>\n </div>\n\n <p className=\"mb-3 text-[12.5px] text-text-muted\">\n Run this command in your terminal to update:\n </p>\n\n <div className=\"flex items-center gap-2 rounded-brand border border-border bg-bg px-3 py-2\">\n <code className=\"flex-1 text-[12px] text-text\">{CMD}</code>\n <button\n onClick={copy}\n className=\"flex-none text-text-subtle transition-colors hover:text-text\"\n title=\"Copy command\"\n >\n <Icon name={copied ? \"check\" : \"content_copy\"} size={14} />\n </button>\n </div>\n\n <p className=\"mt-3 text-[11.5px] text-text-subtle\">\n Shut down the gateway first, then run the command above, then restart.\n </p>\n\n <div className=\"mt-4 flex gap-2\">\n <button\n onClick={() => { copy(); onShutdown(); }}\n className=\"flex flex-1 items-center justify-center gap-1.5 rounded-brand border border-warning/30 bg-warning/10 px-3 py-2 text-[12.5px] font-medium text-warning transition-colors hover:bg-warning/20\"\n >\n <Icon name=\"content_copy\" size={14} />\n Copy & Shut down\n </button>\n <button\n onClick={onClose}\n className=\"rounded-brand border border-border px-3 py-2 text-[12.5px] text-text-muted transition-colors hover:text-text\"\n >\n Later\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function TopBar() {\n const path = usePathname();\n const { theme, toggle } = useTheme();\n const seg = path === \"/\" ? \"\" : (path.split(\"/\")[1] ?? \"\");\n const current = LABELS[seg] ?? seg;\n\n const [version, setVersion] = useState<{ current: string; latest: string | null; updateAvailable: boolean } | null>(null);\n const [showUpdate, setShowUpdate] = useState(false);\n const [confirmShutdown, setConfirmShutdown] = useState(false);\n const [stopped, setStopped] = useState(false);\n const [busy, setBusy] = useState(false);\n\n useEffect(() => {\n void adminApi.version().then((r) => {\n if (r.ok && r.data) setVersion(r.data);\n });\n }, []);\n\n async function doShutdown() {\n setBusy(true);\n await adminApi.shutdown();\n setStopped(true);\n setConfirmShutdown(false);\n setShowUpdate(false);\n setBusy(false);\n }\n\n return (\n <header className=\"console-topbar\">\n <div className=\"flex items-center gap-2 text-[13px]\">\n <span className=\"text-text-subtle\">aigetwey</span>\n <span className=\"text-text-subtle\">/</span>\n <span className=\"font-medium text-text\">{current}</span>\n </div>\n\n <div className=\"ml-auto flex items-center gap-2.5\">\n {version && (\n version.updateAvailable ? (\n <button\n onClick={() => setShowUpdate(true)}\n className=\"flex items-center gap-1.5 rounded-full border border-warning/30 bg-warning/10 px-2.5 py-1 text-[11px] font-medium text-warning transition-colors hover:bg-warning/20\"\n >\n <Icon name=\"arrow_upward\" size={12} />\n v{version.current} → {version.latest}\n </button>\n ) : (\n <span className=\"text-[11px] text-text-subtle\" title=\"You're on the latest version\">\n v{version.current}\n </span>\n )\n )}\n\n <button\n onClick={toggle}\n className=\"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Toggle theme\"\n title={theme === \"dark\" ? \"Switch to light mode\" : \"Switch to dark mode\"}\n >\n <Icon name={theme === \"dark\" ? \"light_mode\" : \"dark_mode\"} size={18} />\n </button>\n\n <button\n onClick={() => setConfirmShutdown(true)}\n className=\"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-danger\"\n aria-label=\"Shut down gateway\"\n title=\"Shut down the gateway\"\n >\n <Icon name=\"power_settings_new\" size={18} />\n </button>\n\n <div className=\"flex items-center gap-2 rounded-full border border-border bg-surface py-1 pl-1 pr-3\">\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-[11px] font-bold text-accent-ink\">\n A\n </span>\n <span className=\"text-[12px] text-text-muted\">admin</span>\n </div>\n </div>\n\n {showUpdate && version?.updateAvailable && (\n <UpdateModal\n current={version.current}\n latest={version.latest!}\n onClose={() => setShowUpdate(false)}\n onShutdown={doShutdown}\n />\n )}\n\n {confirmShutdown && (\n <ConfirmModal\n title=\"Shut down gateway?\"\n message=\"The gateway process will stop and all requests will fail until you restart it. The dashboard stays up but can't reach the gateway.\"\n confirmLabel=\"Shut down\"\n busy={busy}\n onConfirm={doShutdown}\n onCancel={() => setConfirmShutdown(false)}\n />\n )}\n\n {stopped && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6\">\n <div className=\"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 text-center shadow-elevated\">\n <span className=\"mx-auto mb-2 flex h-9 w-9 items-center justify-center rounded-full bg-danger/10 text-danger\">\n <Icon name=\"power_settings_new\" size={20} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">Gateway stopped</h2>\n <p className=\"mt-1 text-[12.5px] text-text-muted\">\n Run <code className=\"rounded bg-surface-2 px-1\">{CMD}</code> then restart with <code className=\"rounded bg-surface-2 px-1\">aigetwey</code>.\n </p>\n </div>\n </div>\n )}\n </header>\n );\n}\n"],"names":["VARIANTS","primary","ghost","danger","Button","variant","className","props","Input","Select","Field","label","hint","children","api","method","path","body","res","fetch","headers","undefined","JSON","stringify","e","ok","status","data","error","message","text","parse","err","adminApi","providers","budgets","models","keys","keysUsage","setBudget","clearBudget","key","encodeURIComponent","addProvider","p","editProvider","id","patch","renameProvider","newId","removeProvider","addKey","name","editKey","index","removeKey","revealKey","addModel","model","price","addModels","removeModel","clearModels","pricing","setModelPrice","testProvider","testKey","testModel","validateProvider","b","discoverModels","reorderProvider","from","to","reorderKey","toggleKey","enabled","setProviderStrategy","strategy","sticky","setProviderDisabled","disabled","setRoute","alias","removeRoute","endpoint","setRtk","setCaveman","level","setPonytail","addServerKey","editServerKey","setServerKeyScope","removeServerKey","revealServerKey","setHeadroom","headroomStatus","headroomStart","headroomStop","putConfig","version","shutdown","appApi","url","account","changePassword","current","next","cliConfig","tool","apply","reset","InvariantError","Error","constructor","options","endsWith","DEFAULT_SEGMENT_KEY","NOT_FOUND_SEGMENT_KEY","PAGE_SEGMENT_KEY","addSearchParamsIfPageSegment","computeSelectedLayoutSegment","getSegmentValue","getSelectedLayoutSegmentPath","isGroupSegment","isParallelRouteSegment","segment","Array","isArray","startsWith","searchParams","isPageSegment","includes","stringifiedQuery","segments","parallelRouteKey","length","rawSegment","tree","first","segmentPath","node","parallelRoutes","Object","values","segmentValue","push","createPromiseWithResolvers","resolve","reject","promise","Promise","rej","ConfirmModal","title","confirmLabel","onConfirm","onCancel","busy","onClick","stopPropagation","size","MAIN","href","icon","SYSTEM","Rail","router","logout","replace","refresh","isActive","link","item","active","fill","viewBox","width","height","x","y","fontFamily","fontSize","fontWeight","textAnchor","stroke","strokeWidth","strokeLinecap","strokeLinejoin","points","map","LABELS","combos","usage","quota","tools","console","config","CMD","UpdateModal","latest","onClose","onShutdown","copied","setCopied","copy","navigator","clipboard","writeText","then","setTimeout","TopBar","theme","toggle","seg","split","setVersion","showUpdate","setShowUpdate","confirmShutdown","setConfirmShutdown","stopped","setStopped","setBusy","r","doShutdown","updateAvailable"],"mappings":"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","ignoreList":[2,3,4]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Button.tsx","../../../../src/lib/client.ts","../../../../node_modules/next/src/shared/lib/invariant-error.ts","../../../../node_modules/next/src/shared/lib/segment.ts","../../../../node_modules/next/src/shared/lib/promise-with-resolvers.ts","../../../../src/components/ConfirmModal.tsx","../../../../src/components/Rail.tsx","../../../../src/components/TopBar.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\n\ntype Variant = \"primary\" | \"ghost\" | \"danger\";\n\nconst VARIANTS: Record<Variant, string> = {\n primary: \"bg-accent text-accent-ink shadow-warm hover:bg-accent-hover border border-transparent font-semibold\",\n ghost: \"bg-transparent text-text-muted border border-border hover:text-text hover:border-text-subtle\",\n danger: \"bg-transparent text-text-muted border border-border hover:text-danger hover:border-danger/50\",\n};\n\nexport function Button({\n variant = \"primary\",\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { variant?: Variant }) {\n return (\n <button\n className={`inline-flex items-center justify-center gap-1.5 rounded-brand px-3.5 py-2 text-[13px] font-medium transition-colors duration-150 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed ${VARIANTS[variant]}${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Input({ className, ...props }: React.InputHTMLAttributes<HTMLInputElement>) {\n return (\n <input\n className={`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text placeholder:text-text-subtle focus:border-accent focus:outline-none transition-colors${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Select({ className, ...props }: React.SelectHTMLAttributes<HTMLSelectElement>) {\n return (\n <select\n className={`w-full rounded-brand border border-border bg-bg px-3 py-2 text-[13px] text-text focus:border-accent focus:outline-none transition-colors${className ? ` ${className}` : \"\"}`}\n {...props}\n />\n );\n}\n\nexport function Field({\n label,\n hint,\n children,\n}: {\n label: string;\n hint?: string;\n children: React.ReactNode;\n}) {\n return (\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-[11px] font-medium uppercase tracking-wider text-text-subtle\">\n {label}\n {hint && <span className=\"ml-1.5 lowercase tracking-normal text-text-subtle/70\">· {hint}</span>}\n </span>\n {children}\n </label>\n );\n}\n","\"use client\";\n\n/**\n * Browser-side admin client. Talks to the gateway THROUGH the same-origin proxy\n * (`/api/gw/admin/...`), which injects the admin Bearer server-side — so the\n * password never reaches the browser. Server components read initial data via\n * lib/gateway.ts directly; client components mutate through here.\n */\nimport type {\n BudgetStatus,\n ConfigReply,\n EndpointPayload,\n HeadroomStatusReply,\n InjectLevel,\n KeyUsageRow,\n ModelsPayload,\n PingResult,\n PricingPayload,\n ProviderSnapshot,\n WireFormat,\n} from \"./gateway\";\n\nexport interface ApiResult<T> {\n ok: boolean;\n status: number;\n data: T | null;\n error?: string;\n}\n\nasync function api<T>(method: string, path: string, body?: unknown): Promise<ApiResult<T>> {\n let res: Response;\n try {\n res = await fetch(`/api/gw${path}`, {\n method,\n headers: body !== undefined ? { \"content-type\": \"application/json\" } : {},\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e) {\n return { ok: false, status: 0, data: null, error: (e as Error).message };\n }\n const text = await res.text();\n let data: T | null = null;\n try {\n data = text ? (JSON.parse(text) as T) : null;\n } catch {\n data = null;\n }\n if (!res.ok) {\n const err = (data as { error?: string } | null)?.error ?? `request failed (${res.status})`;\n return { ok: false, status: res.status, data, error: err };\n }\n return { ok: true, status: res.status, data };\n}\n\nexport const adminApi = {\n providers: () => api<{ providers: ProviderSnapshot[] }>(\"GET\", \"/admin/providers\"),\n budgets: () => api<{ budgets: BudgetStatus[] }>(\"GET\", \"/admin/budgets\"),\n models: () => api<ModelsPayload>(\"GET\", \"/admin/models\"),\n keys: () => api<Array<{ fingerprint: string; name: string; masked: string }>>(\"GET\", \"/admin/keys\"),\n keysUsage: () => api<{ keys: KeyUsageRow[] }>(\"GET\", \"/admin/keys/usage\"),\n\n setBudget: (body: {\n scope: { type: \"global\" } | { type: \"provider\"; id: string } | { type: \"model\"; id: string } | { type: \"key\"; id: string };\n unit: \"usd\" | \"tokens\";\n limit: number;\n window: \"5h\" | \"24h\" | \"7day\" | \"30day\";\n alert_at?: number;\n note?: string;\n }) => api<ConfigReply>(\"PUT\", \"/admin/budgets\", body),\n clearBudget: (key: string) => api<ConfigReply>(\"DELETE\", `/admin/budgets/${encodeURIComponent(key)}`),\n\n addProvider: (p: {\n id: string;\n name?: string;\n format: WireFormat;\n base_url: string;\n api_key?: string;\n free?: boolean;\n auto_models?: boolean;\n service_account?: string;\n }) => api<ConfigReply>(\"POST\", \"/admin/providers\", p),\n editProvider: (id: string, patch: { base_url?: string; format?: WireFormat; name?: string }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}`, patch),\n renameProvider: (id: string, newId: string) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/rename`, { id: newId }),\n removeProvider: (id: string) => api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}`),\n addKey: (id: string, key: string, name?: string) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/keys`, { key, name }),\n editKey: (id: string, index: number, patch: { key?: string; name?: string }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}`, patch),\n removeKey: (id: string, index: number) =>\n api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}`),\n revealKey: (id: string, index: number) =>\n api<{ key: string }>(\"GET\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/reveal`),\n addModel: (id: string, model: string, price?: { price_in?: number; price_out?: number }) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/models`, { model, ...price }),\n addModels: (id: string, models: string[]) =>\n api<ConfigReply>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/models`, { models }),\n // model id can hold a slash (provider/model); send it as a query param so the\n // proxy's path split doesn't mangle it.\n removeModel: (id: string, model: string) =>\n api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/models?model=${encodeURIComponent(model)}`),\n clearModels: (id: string) => api<ConfigReply>(\"DELETE\", `/admin/providers/${encodeURIComponent(id)}/models`),\n pricing: () => api<PricingPayload>(\"GET\", \"/admin/pricing\"),\n setModelPrice: (id: string, model: string, price: { price_in?: number | null; price_out?: number | null }) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/models/price`, { model, ...price }),\n testProvider: (id: string) => api<PingResult>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/test`),\n testKey: (id: string, index: number) =>\n api<PingResult>(\"POST\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/test`),\n testModel: (id: string, model: string) =>\n api<{ ok: boolean; status?: number; error?: string }>(\n \"POST\",\n `/admin/providers/${encodeURIComponent(id)}/models/test?model=${encodeURIComponent(model)}`,\n ),\n validateProvider: (b: { format: WireFormat; base_url: string; api_key?: string }) =>\n api<PingResult>(\"POST\", \"/admin/providers/validate\", b),\n // discover: returns the upstream catalog flagged with which ids are in config.\n discoverModels: (id: string) =>\n api<{ ok: boolean; models: Array<{ id: string; added: boolean }> }>(\n \"POST\",\n `/admin/providers/${encodeURIComponent(id)}/connect`,\n ),\n\n reorderProvider: (from: number, to: number) =>\n api<ConfigReply>(\"PUT\", \"/admin/providers/reorder\", { from, to }),\n reorderKey: (id: string, from: number, to: number) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/reorder`, { from, to }),\n toggleKey: (id: string, index: number, enabled: boolean) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/keys/${index}/toggle`, { enabled }),\n setProviderStrategy: (id: string, strategy: \"fallback\" | \"round-robin\" | null, sticky?: number) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/strategy`, { strategy, sticky }),\n setProviderDisabled: (id: string, disabled: boolean) =>\n api<ConfigReply>(\"PUT\", `/admin/providers/${encodeURIComponent(id)}/disabled`, { disabled }),\n\n setRoute: (\n alias: string,\n body: { target: string[]; model?: string | string[]; strategy?: \"fallback\" | \"round-robin\"; price_in?: number; price_out?: number },\n ) => api<ConfigReply>(\"PUT\", `/admin/routes/${encodeURIComponent(alias)}`, body),\n removeRoute: (alias: string) => api<ConfigReply>(\"DELETE\", `/admin/routes/${encodeURIComponent(alias)}`),\n\n endpoint: () => api<EndpointPayload>(\"GET\", \"/admin/endpoint\"),\n setRtk: (enabled: boolean) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/rtk\", { enabled }),\n setCaveman: (level: InjectLevel) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/caveman\", { level }),\n setPonytail: (level: InjectLevel) => api<ConfigReply>(\"PUT\", \"/admin/endpoint/ponytail\", { level }),\n addServerKey: (key: string, name?: string) => api<ConfigReply>(\"POST\", \"/admin/endpoint/keys\", { key, name }),\n editServerKey: (index: number, name: string) => api<ConfigReply>(\"PUT\", `/admin/endpoint/keys/${index}`, { name }),\n setServerKeyScope: (index: number, body: { models?: string[]; rpm?: number | null; expires?: number | null }) =>\n api<ConfigReply>(\"PUT\", `/admin/endpoint/keys/${index}/scope`, body),\n removeServerKey: (index: number) => api<ConfigReply>(\"DELETE\", `/admin/endpoint/keys/${index}`),\n revealServerKey: (index: number) => api<{ key: string }>(\"GET\", `/admin/endpoint/keys/${index}/reveal`),\n\n setHeadroom: (patch: { enabled?: boolean; url?: string; compress_user_messages?: boolean }) =>\n api<ConfigReply>(\"PUT\", \"/admin/endpoint/headroom\", patch),\n headroomStatus: () => api<HeadroomStatusReply>(\"GET\", \"/admin/headroom/status\"),\n headroomStart: () => api<{ success?: boolean; pid?: number; alreadyRunning?: boolean }>(\"POST\", \"/admin/headroom/start\"),\n headroomStop: () => api<{ stopped: boolean; reason?: string; pid?: number }>(\"POST\", \"/admin/headroom/stop\"),\n\n putConfig: (text: string) => api<{ ok: boolean }>(\"PUT\", \"/admin/config\", { text }),\n\n version: () => api<{ current: string; latest: string | null; updateAvailable: boolean }>(\"GET\", \"/admin/version\"),\n shutdown: () => api<{ ok: boolean; message: string }>(\"POST\", \"/admin/shutdown\"),\n};\n\n// Local CLI-tool detection/auto-config. These hit the dashboard's OWN server\n// routes (/api/cli-detect/*), not the gateway proxy — they read/write the tool's\n// config file on this machine. Session-gated by middleware like everything else.\nexport interface CliStatus {\n auto: boolean;\n installed: boolean;\n configured?: boolean;\n path?: string;\n baseUrl?: string | null;\n models?: string[];\n activeModel?: string | null;\n // claude returns its three slot defaults instead of a flat list\n modelSlots?: { opus?: string | null; sonnet?: string | null; haiku?: string | null };\n}\n\nasync function appApi<T>(method: string, url: string, body?: unknown): Promise<ApiResult<T>> {\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: body !== undefined ? { \"content-type\": \"application/json\" } : {},\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e) {\n return { ok: false, status: 0, data: null, error: (e as Error).message };\n }\n const text = await res.text();\n const data = text ? (JSON.parse(text) as T) : null;\n if (!res.ok) {\n const err = (data as { error?: string } | null)?.error ?? `request failed (${res.status})`;\n return { ok: false, status: res.status, data, error: err };\n }\n return { ok: true, status: res.status, data };\n}\n\n/** Admin account actions that hit the dashboard's OWN routes (not the gw proxy). */\nexport const account = {\n changePassword: (current: string, next: string) =>\n appApi<{ ok: boolean }>(\"POST\", \"/api/password\", { current, next }),\n};\n\nexport const cliConfig = {\n status: (tool: string) => appApi<CliStatus>(\"GET\", `/api/cli-detect/${encodeURIComponent(tool)}`),\n apply: (tool: string, body: { base: string; key?: string; models?: string[] | Record<string, string>; active?: string }) =>\n appApi<{ success?: boolean; path?: string }>(\"POST\", `/api/cli-detect/${encodeURIComponent(tool)}`, body),\n reset: (tool: string) => appApi<{ success?: boolean }>(\"DELETE\", `/api/cli-detect/${encodeURIComponent(tool)}`),\n};\n","export class InvariantError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(\n `Invariant: ${message.endsWith('.') ? message : message + '.'} This is a bug in Next.js.`,\n options\n )\n this.name = 'InvariantError'\n }\n}\n","import type { FlightRouterState, Segment } from './app-router-types'\n\nexport function getSegmentValue(segment: Segment) {\n return Array.isArray(segment) ? segment[1] : segment\n}\n\nexport function isGroupSegment(segment: string) {\n // Use array[0] for performant purpose\n return segment[0] === '(' && segment.endsWith(')')\n}\n\nexport function isParallelRouteSegment(segment: string) {\n return segment.startsWith('@') && segment !== '@children'\n}\n\nexport function addSearchParamsIfPageSegment(\n segment: Segment,\n searchParams: Record<string, string | string[] | undefined>\n) {\n const isPageSegment = segment.includes(PAGE_SEGMENT_KEY)\n\n if (isPageSegment) {\n const stringifiedQuery = JSON.stringify(searchParams)\n return stringifiedQuery !== '{}'\n ? PAGE_SEGMENT_KEY + '?' + stringifiedQuery\n : PAGE_SEGMENT_KEY\n }\n\n return segment\n}\n\nexport function computeSelectedLayoutSegment(\n segments: string[] | null,\n parallelRouteKey: string\n): string | null {\n if (!segments || segments.length === 0) {\n return null\n }\n\n // For 'children', use first segment; for other parallel routes, use last segment\n const rawSegment =\n parallelRouteKey === 'children'\n ? segments[0]\n : segments[segments.length - 1]\n\n // If the default slot is showing, return null since it's not technically \"selected\" (it's a fallback)\n // Returning an internal value like `__DEFAULT__` would be confusing\n return rawSegment === DEFAULT_SEGMENT_KEY ? null : rawSegment\n}\n\n/** Get the canonical parameters from the current level to the leaf node. */\nexport function getSelectedLayoutSegmentPath(\n tree: FlightRouterState,\n parallelRouteKey: string,\n first = true,\n segmentPath: string[] = []\n): string[] {\n let node: FlightRouterState\n if (first) {\n // Use the provided parallel route key on the first parallel route\n node = tree[1][parallelRouteKey]\n } else {\n // After first parallel route prefer children, if there's no children pick the first parallel route.\n const parallelRoutes = tree[1]\n node = parallelRoutes.children ?? Object.values(parallelRoutes)[0]\n }\n\n if (!node) return segmentPath\n const segment = node[0]\n\n let segmentValue = getSegmentValue(segment)\n\n if (!segmentValue || segmentValue.startsWith(PAGE_SEGMENT_KEY)) {\n return segmentPath\n }\n\n segmentPath.push(segmentValue)\n\n return getSelectedLayoutSegmentPath(\n node,\n parallelRouteKey,\n false,\n segmentPath\n )\n}\n\nexport const PAGE_SEGMENT_KEY = '__PAGE__'\nexport const DEFAULT_SEGMENT_KEY = '__DEFAULT__'\nexport const NOT_FOUND_SEGMENT_KEY = '/_not-found'\n","export function createPromiseWithResolvers<T>(): PromiseWithResolvers<T> {\n // Shim of Stage 4 Promise.withResolvers proposal\n let resolve: (value: T | PromiseLike<T>) => void\n let reject: (reason: any) => void\n const promise = new Promise<T>((res, rej) => {\n resolve = res\n reject = rej\n })\n return { resolve: resolve!, reject: reject!, promise }\n}\n","\"use client\";\n\nimport { Button } from \"@/components/Button\";\nimport { Icon } from \"@/components/Icon\";\n\ninterface ConfirmModalProps {\n title: string;\n message: string;\n confirmLabel?: string;\n onConfirm: () => void;\n onCancel: () => void;\n busy?: boolean;\n}\n\nexport function ConfirmModal({ title, message, confirmLabel = \"Delete\", onConfirm, onCancel, busy }: ConfirmModalProps) {\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-6\" onClick={onCancel}>\n <div\n className=\"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-2 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-danger/10 text-danger\">\n <Icon name=\"warning\" size={16} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">{title}</h2>\n </div>\n <p className=\"mb-4 text-[12.5px] text-text-muted\">{message}</p>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button variant=\"danger\" disabled={busy} onClick={onConfirm}>{confirmLabel}</Button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport Link from \"next/link\";\nimport { usePathname, useRouter } from \"next/navigation\";\nimport { Icon } from \"./Icon\";\n\n// Floating icon-rail (user's preferred chrome), carrying aigetwey's IA: Endpoint\n// is the landing, routing lives in Combos, and operational pages sit below a\n// divider. Labels surface as hover tooltips (data-label).\ntype NavItem = { href: string; label: string; icon: string };\n\nconst MAIN: NavItem[] = [\n { href: \"/\", label: \"Endpoint\", icon: \"api\" },\n { href: \"/keys\", label: \"Access Keys\", icon: \"key\" },\n { href: \"/providers\", label: \"Providers\", icon: \"dns\" },\n { href: \"/combos\", label: \"Combos\", icon: \"layers\" },\n { href: \"/usage\", label: \"Usage\", icon: \"bar_chart\" },\n { href: \"/quota\", label: \"Budgets\", icon: \"data_usage\" },\n { href: \"/tools\", label: \"CLI Tools\", icon: \"terminal\" },\n];\n\nconst SYSTEM: NavItem[] = [\n { href: \"/console\", label: \"Server Console\", icon: \"terminal\" },\n { href: \"/config\", label: \"Settings\", icon: \"settings\" },\n];\n\nexport function Rail() {\n const path = usePathname();\n const router = useRouter();\n\n async function logout() {\n await fetch(\"/api/logout\", { method: \"POST\" });\n router.replace(\"/login\");\n router.refresh();\n }\n\n // Endpoint owns both \"/\" (landing) and \"/endpoint\"; others match the segment\n // and its sub-routes (e.g. /providers/[id]).\n const isActive = (href: string) =>\n href === \"/\"\n ? path === \"/\" || path.startsWith(\"/endpoint\")\n : path === href || path.startsWith(`${href}/`);\n\n const link = (item: NavItem) => {\n const active = isActive(item.href);\n return (\n <Link\n key={item.href}\n href={item.href}\n data-label={item.label}\n className={`rail-icon${active ? \" rail-icon-active\" : \"\"}`}\n aria-label={item.label}\n >\n <Icon name={item.icon} size={20} fill={active} />\n </Link>\n );\n };\n\n return (\n <>\n <Link href=\"/\" className=\"rail-brand\" aria-label=\"aigetwey\">\n {/* \"a»\" mark — ink on the lime tile (CSS provides the tile) */}\n <svg viewBox=\"0 0 512 512\" width=\"26\" height=\"26\" aria-hidden>\n <text x=\"120\" y=\"338\" fontFamily=\"ui-sans-serif, Arial, sans-serif\" fontSize=\"260\" fontWeight=\"800\" textAnchor=\"middle\" fill=\"#14140f\">a</text>\n <g fill=\"none\" stroke=\"#14140f\" strokeWidth=\"34\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"276,182 352,256 276,330\" />\n <polyline points=\"346,182 422,256 346,330\" />\n </g>\n </svg>\n </Link>\n\n <nav className=\"flex flex-col items-center gap-3\">\n {MAIN.map(link)}\n <div className=\"rail-divider\" />\n {SYSTEM.map(link)}\n </nav>\n\n <button onClick={logout} data-label=\"Disconnect\" className=\"rail-icon\" aria-label=\"Disconnect\">\n <Icon name=\"logout\" size={19} />\n </button>\n </>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { Icon } from \"./Icon\";\nimport { useTheme } from \"./ThemeProvider\";\nimport { ConfirmModal } from \"./ConfirmModal\";\nimport { adminApi } from \"@/lib/client\";\n\nconst LABELS: Record<string, string> = {\n \"\": \"Endpoint\",\n endpoint: \"Endpoint\",\n keys: \"Access Keys\",\n providers: \"Providers\",\n combos: \"Combos\",\n usage: \"Usage\",\n quota: \"Budgets\",\n tools: \"CLI Tools\",\n console: \"Server Console\",\n config: \"Settings\",\n};\n\nconst CMD = \"npm i -g aigetwey@latest --prefer-online\";\n\nfunction UpdateModal({\n current,\n latest,\n onClose,\n onShutdown,\n}: {\n current: string;\n latest: string;\n onClose: () => void;\n onShutdown: () => void;\n}) {\n const [copied, setCopied] = useState(false);\n\n function copy() {\n void navigator.clipboard.writeText(CMD).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\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-sm rounded-brand-lg border border-border bg-surface p-5 shadow-elevated\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2.5\">\n <span className=\"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-warning/10 text-warning\">\n <Icon name=\"arrow_upward\" size={19} />\n </span>\n <div>\n <h2 className=\"text-[14px] font-semibold text-text\">Update available</h2>\n <p className=\"text-[12px] text-text-muted\">\n v{current} → <span className=\"text-warning font-medium\">v{latest}</span>\n </p>\n </div>\n </div>\n <button onClick={onClose} className=\"text-text-subtle hover:text-text\">\n <Icon name=\"close\" size={17} />\n </button>\n </div>\n\n <p className=\"mb-3 text-[12.5px] text-text-muted\">\n Run this command in your terminal to update:\n </p>\n\n <div className=\"flex items-center gap-2 rounded-brand border border-border bg-bg px-3 py-2\">\n <code className=\"flex-1 text-[12px] text-text\">{CMD}</code>\n <button\n onClick={copy}\n className=\"flex-none text-text-subtle transition-colors hover:text-text\"\n title=\"Copy command\"\n >\n <Icon name={copied ? \"check\" : \"content_copy\"} size={14} />\n </button>\n </div>\n\n <p className=\"mt-3 text-[11.5px] text-text-subtle\">\n Shut down the gateway first, then run the command above, then restart.\n </p>\n\n <div className=\"mt-4 flex gap-2\">\n <button\n onClick={() => { copy(); onShutdown(); }}\n className=\"flex flex-1 items-center justify-center gap-1.5 rounded-brand border border-warning/30 bg-warning/10 px-3 py-2 text-[12.5px] font-medium text-warning transition-colors hover:bg-warning/20\"\n >\n <Icon name=\"content_copy\" size={14} />\n Copy & Shut down\n </button>\n <button\n onClick={onClose}\n className=\"rounded-brand border border-border px-3 py-2 text-[12.5px] text-text-muted transition-colors hover:text-text\"\n >\n Later\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function TopBar() {\n const path = usePathname();\n const { theme, toggle } = useTheme();\n const seg = path === \"/\" ? \"\" : (path.split(\"/\")[1] ?? \"\");\n const current = LABELS[seg] ?? seg;\n\n const [version, setVersion] = useState<{ current: string; latest: string | null; updateAvailable: boolean } | null>(null);\n const [showUpdate, setShowUpdate] = useState(false);\n const [confirmShutdown, setConfirmShutdown] = useState(false);\n const [stopped, setStopped] = useState(false);\n const [busy, setBusy] = useState(false);\n\n useEffect(() => {\n void adminApi.version().then((r) => {\n if (r.ok && r.data) setVersion(r.data);\n });\n }, []);\n\n async function doShutdown() {\n setBusy(true);\n await adminApi.shutdown();\n setStopped(true);\n setConfirmShutdown(false);\n setShowUpdate(false);\n setBusy(false);\n }\n\n return (\n <header className=\"console-topbar\">\n <div className=\"flex items-center gap-2 text-[13px]\">\n <span className=\"text-text-subtle\">aigetwey</span>\n <span className=\"text-text-subtle\">/</span>\n <span className=\"font-medium text-text\">{current}</span>\n </div>\n\n <div className=\"ml-auto flex items-center gap-2.5\">\n {version && (\n version.updateAvailable ? (\n <button\n onClick={() => setShowUpdate(true)}\n className=\"flex items-center gap-1.5 rounded-full border border-warning/30 bg-warning/10 px-2.5 py-1 text-[11px] font-medium text-warning transition-colors hover:bg-warning/20\"\n >\n <Icon name=\"arrow_upward\" size={12} />\n v{version.current} → {version.latest}\n </button>\n ) : (\n <span className=\"text-[11px] text-text-subtle\" title=\"You're on the latest version\">\n v{version.current}\n </span>\n )\n )}\n\n <button\n onClick={toggle}\n className=\"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-text\"\n aria-label=\"Toggle theme\"\n title={theme === \"dark\" ? \"Switch to light mode\" : \"Switch to dark mode\"}\n >\n <Icon name={theme === \"dark\" ? \"light_mode\" : \"dark_mode\"} size={18} />\n </button>\n\n <button\n onClick={() => setConfirmShutdown(true)}\n className=\"flex h-8 w-8 items-center justify-center rounded-full text-text-subtle transition-colors hover:text-danger\"\n aria-label=\"Shut down gateway\"\n title=\"Shut down the gateway\"\n >\n <Icon name=\"power_settings_new\" size={18} />\n </button>\n\n <div className=\"flex items-center gap-2 rounded-full border border-border bg-surface py-1 pl-1 pr-3\">\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full bg-accent text-[11px] font-bold text-accent-ink\">\n A\n </span>\n <span className=\"text-[12px] text-text-muted\">admin</span>\n </div>\n </div>\n\n {showUpdate && version?.updateAvailable && (\n <UpdateModal\n current={version.current}\n latest={version.latest!}\n onClose={() => setShowUpdate(false)}\n onShutdown={doShutdown}\n />\n )}\n\n {confirmShutdown && (\n <ConfirmModal\n title=\"Shut down gateway?\"\n message=\"The gateway process will stop and all requests will fail until you restart it. The dashboard stays up but can't reach the gateway.\"\n confirmLabel=\"Shut down\"\n busy={busy}\n onConfirm={doShutdown}\n onCancel={() => setConfirmShutdown(false)}\n />\n )}\n\n {stopped && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6\">\n <div className=\"w-full max-w-sm rounded-brand-lg border border-border bg-surface p-5 text-center shadow-elevated\">\n <span className=\"mx-auto mb-2 flex h-9 w-9 items-center justify-center rounded-full bg-danger/10 text-danger\">\n <Icon name=\"power_settings_new\" size={20} />\n </span>\n <h2 className=\"text-[15px] font-semibold text-text\">Gateway stopped</h2>\n <p className=\"mt-1 text-[12.5px] text-text-muted\">\n Run <code className=\"rounded bg-surface-2 px-1\">{CMD}</code> then restart with <code className=\"rounded bg-surface-2 px-1\">aigetwey</code>.\n </p>\n </div>\n </div>\n )}\n </header>\n );\n}\n"],"names":["VARIANTS","primary","ghost","danger","Button","variant","className","props","Input","Select","Field","label","hint","children","api","method","path","body","res","fetch","headers","undefined","JSON","stringify","e","ok","status","data","error","message","text","parse","err","adminApi","providers","budgets","models","keys","keysUsage","setBudget","clearBudget","key","encodeURIComponent","addProvider","p","editProvider","id","patch","renameProvider","newId","removeProvider","addKey","name","editKey","index","removeKey","revealKey","addModel","model","price","addModels","removeModel","clearModels","pricing","setModelPrice","testProvider","testKey","testModel","validateProvider","b","discoverModels","reorderProvider","from","to","reorderKey","toggleKey","enabled","setProviderStrategy","strategy","sticky","setProviderDisabled","disabled","setRoute","alias","removeRoute","endpoint","setRtk","setCaveman","level","setPonytail","addServerKey","editServerKey","setServerKeyScope","removeServerKey","revealServerKey","setHeadroom","headroomStatus","headroomStart","headroomStop","putConfig","version","shutdown","appApi","url","account","changePassword","current","next","cliConfig","tool","apply","reset","InvariantError","Error","constructor","options","endsWith","DEFAULT_SEGMENT_KEY","NOT_FOUND_SEGMENT_KEY","PAGE_SEGMENT_KEY","addSearchParamsIfPageSegment","computeSelectedLayoutSegment","getSegmentValue","getSelectedLayoutSegmentPath","isGroupSegment","isParallelRouteSegment","segment","Array","isArray","startsWith","searchParams","isPageSegment","includes","stringifiedQuery","segments","parallelRouteKey","length","rawSegment","tree","first","segmentPath","node","parallelRoutes","Object","values","segmentValue","push","createPromiseWithResolvers","resolve","reject","promise","Promise","rej","ConfirmModal","title","confirmLabel","onConfirm","onCancel","busy","onClick","stopPropagation","size","MAIN","href","icon","SYSTEM","Rail","router","logout","replace","refresh","isActive","link","item","active","fill","viewBox","width","height","x","y","fontFamily","fontSize","fontWeight","textAnchor","stroke","strokeWidth","strokeLinecap","strokeLinejoin","points","map","LABELS","combos","usage","quota","tools","console","config","CMD","UpdateModal","latest","onClose","onShutdown","copied","setCopied","copy","navigator","clipboard","writeText","then","setTimeout","TopBar","theme","toggle","seg","split","setVersion","showUpdate","setShowUpdate","confirmShutdown","setConfirmShutdown","stopped","setStopped","setBusy","r","doShutdown","updateAvailable"],"mappings":"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","ignoreList":[2,3,4]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module.exports=[42532,a=>{"use strict";var b=a.i(87924),c=a.i(72131);let d=[{key:"tokens",label:"Tokens"},{key:"cost",label:"Cost"},{key:"requests",label:"Requests"}];function e(a,b){return"cost"===b?a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`:a>=1e6?`${(a/1e6).toFixed(1)}M`:a>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a))}function f(a){return new Date(a).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:!1})}function g({series:a}){let[h,i]=(0,c.useState)("tokens"),j=a.map(a=>"tokens"===h?a.tokens_in+a.tokens_out:"cost"===h?a.cost:a.requests),k=Math.max(1,...j),l=a.length,m=a=>l<=1?8:8+a/(l-1)*984,n=a=>224-a/k*208,o=j.map((a,b)=>`${0===b?"M":"L"}${m(b).toFixed(1)},${n(a).toFixed(1)}`).join(" "),p=`${o} L${m(l-1).toFixed(1)},224 L${m(0).toFixed(1)},224 Z`,q=j.length?j.indexOf(Math.max(...j)):-1,r=j.reduce((a,b)=>a+b,0);return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"Over time"}),(0,b.jsxs)("span",{className:"tnum text-[12px] text-text-muted",children:[e(r,h)," total"]})]}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:d.map(a=>(0,b.jsx)("button",{onClick:()=>i(a.key),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${h===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:a.label},a.key))})]}),(0,b.jsx)("div",{className:"px-2 py-3",children:0===l||0===r?(0,b.jsx)("div",{className:"flex h-[200px] items-center justify-center text-[13px] text-text-muted",children:"No activity in this range."}):(0,b.jsxs)("svg",{viewBox:"0 0 1000 240",className:"h-[200px] w-full",preserveAspectRatio:"none",children:[(0,b.jsx)("defs",{children:(0,b.jsxs)("linearGradient",{id:"areaFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[(0,b.jsx)("stop",{offset:"0%",stopColor:"var(--color-accent)",stopOpacity:"0.28"}),(0,b.jsx)("stop",{offset:"100%",stopColor:"var(--color-accent)",stopOpacity:"0"})]})}),(0,b.jsx)("path",{d:p,fill:"url(#areaFill)"}),(0,b.jsx)("path",{d:o,fill:"none",stroke:"var(--color-accent)",strokeWidth:"2",vectorEffect:"non-scaling-stroke"}),q>=0&&(0,b.jsx)("circle",{cx:m(q),cy:n(j[q]),r:"3",fill:"var(--color-accent)",vectorEffect:"non-scaling-stroke"})]})}),l>0&&r>0&&q>=0&&(0,b.jsxs)("div",{className:"flex justify-between border-t border-border-subtle px-4 py-2 tnum text-[10px] text-text-subtle",children:[(0,b.jsx)("span",{children:f(a[0].ts)}),(0,b.jsxs)("span",{children:["peak ",e(j[q],h)," @ ",f(a[q].ts)]}),(0,b.jsx)("span",{children:f(a[l-1].ts)})]})]})}var h=a.i(58918),i=a.i(85732);let j=[{label:"Today",key:"today",bucketMs:36e5},{label:"24h",key:"24h",bucketMs:36e5},{label:"7D",key:"7d",bucketMs:216e5},{label:"30D",key:"30d",bucketMs:864e5},{label:"60D",key:"60d",bucketMs:1728e5}];function k({rows:a,loading:c}){return(0,b.jsx)("div",{className:`table-wrap ${c?"opacity-50":""}`,children:(0,b.jsxs)("table",{className:"w-full border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["","Reqs","In","Out","Cost"].map((a,c)=>(0,b.jsx)("th",{className:`pb-2 text-[10px] font-medium uppercase tracking-wider ${0===c?"text-left":"text-right"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:a.map(a=>(0,b.jsxs)("tr",{className:"border-t border-border-subtle",children:[(0,b.jsx)("td",{className:"py-2 text-[12.5px] text-text",children:a.label}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.int(a.requests)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.compact(a.tokens_in)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:h.fmt.compact(a.tokens_out)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text",children:h.fmt.cost(a.cost)})]},a.label))})]})})}a.s(["UsageView",0,function(){let[a,d]=(0,c.useState)(j[0]),[e,f]=(0,c.useState)(null),[l,m]=(0,c.useState)([]),[n,o]=(0,c.useState)(""),[p,q]=(0,c.useState)(!0),r=(0,c.useCallback)(async a=>{q(!0),o("");let b=function(a){let b=Date.now();switch(a){case"today":{let a=new Date;return a.setHours(0,0,0,0),a.getTime()}case"24h":return b-864e5;case"7d":return b-6048e5;case"30d":return b-2592e6;case"60d":return b-5184e6}}(a.key),[c,d]=await Promise.all([fetch(`/api/gw/admin/usage?since=${b}`),fetch(`/api/gw/admin/usage/series?since=${b}&bucket=${a.bucketMs}`)]);if(!c.ok){o("could not load usage"),q(!1);return}f(await c.json()),m((d.ok?await d.json():{series:[]}).series),q(!1)},[]);(0,c.useEffect)(()=>{r(a)},[a,r]);let s=e?.total;return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6 flex items-center justify-between gap-3",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Usage"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Tokens and cost across providers and models."})]}),(0,b.jsx)("div",{className:"flex items-center gap-1 rounded-full border border-border bg-surface p-1",children:j.map(c=>(0,b.jsx)("button",{onClick:()=>d(c),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${a.label===c.label?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:c.label},c.label))})]}),n?(0,b.jsx)(h.Empty,{children:n}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{className:"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",children:[(0,b.jsx)(h.Stat,{label:"Requests",value:h.fmt.int(s?.requests??0)}),(0,b.jsx)(h.Stat,{label:"Tokens in",value:h.fmt.compact(s?.tokens_in??0)}),(0,b.jsx)(h.Stat,{label:"Tokens out",value:h.fmt.compact(s?.tokens_out??0)}),(0,b.jsx)(h.Stat,{label:"Cost",value:h.fmt.cost(s?.cost??0)})]}),(0,b.jsx)("div",{className:"mb-5",children:(0,b.jsx)(g,{series:l})}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,b.jsx)(i.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By provider"}),children:e?.by_provider.length?(0,b.jsx)(k,{rows:e.by_provider.map(a=>({label:a.provider,...a})),loading:p}):(0,b.jsx)(h.Empty,{children:"No usage in this window."})}),(0,b.jsx)(i.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By model"}),children:e?.by_model.length?(0,b.jsx)(k,{rows:e.by_model.map(a=>({label:`${a.alias} → ${a.model}`,...a})),loading:p}):(0,b.jsx)(h.Empty,{children:"No usage in this window."})})]})]})]})}],42532)},61574,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(47153),e=a.i(2693),f=a.i(93026),g=a.i(58918);let h=[{key:"all",label:"All"},{key:"ok",label:"Success"},{key:"error",label:"Errors"}],i=[{label:"1h",ms:36e5},{label:"6h",ms:216e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"All",ms:null}];function j({label:a,children:c}){return(0,b.jsxs)("label",{className:"flex flex-col gap-1",children:[(0,b.jsx)("span",{className:"text-[10px] font-medium uppercase tracking-wider text-text-subtle",children:a}),c]})}function k({children:a,muted:c,right:d,title:e,className:f,suppressHydrationWarning:g}){return(0,b.jsx)("td",{title:e,suppressHydrationWarning:g,className:`whitespace-nowrap px-4 py-2.5 tnum text-[12.5px] ${d?"text-right":"text-left"} ${c?"text-text-muted":"text-text"}${f?` ${f}`:""}`,children:a})}function l({log:a,onClose:c}){let d=a.status>=200&&a.status<300,e=a.tokens_in+a.tokens_out;return(0,b.jsxs)("div",{className:"border-t border-border-subtle bg-surface-2/40 px-5 py-4",children:[(0,b.jsxs)("div",{className:"mb-3 flex items-center justify-between",children:[(0,b.jsx)("span",{className:"text-[12px] font-semibold text-text",children:"Request Details"}),(0,b.jsx)("button",{onClick:c,className:"text-text-subtle hover:text-text",children:(0,b.jsx)(f.Icon,{name:"close",size:16})})]}),(0,b.jsxs)("div",{className:"grid grid-cols-2 gap-x-8 gap-y-2 text-[12px] sm:grid-cols-4",children:[(0,b.jsx)(m,{label:"Status",value:`${a.status} ${d?"OK":"Error"}`}),(0,b.jsx)(m,{label:"Timestamp",value:new Date(a.ts).toLocaleString()}),(0,b.jsx)(m,{label:"Alias",value:a.alias}),(0,b.jsx)(m,{label:"Provider",value:a.provider}),(0,b.jsx)(m,{label:"Model",value:a.model}),(0,b.jsx)(m,{label:"Mode",value:a.stream?"Streaming":"Unary"}),(0,b.jsx)(m,{label:"Latency",value:`${a.latency_ms}ms`}),(0,b.jsx)(m,{label:"Cost",value:g.fmt.cost(a.cost)}),(0,b.jsx)(m,{label:"Input tokens",value:g.fmt.int(a.tokens_in)}),(0,b.jsx)(m,{label:"Output tokens",value:g.fmt.int(a.tokens_out)}),(0,b.jsx)(m,{label:"Cached tokens",value:g.fmt.int(a.cached_tokens)}),(0,b.jsx)(m,{label:"Total tokens",value:g.fmt.int(e)})]})]})}function m({label:a,value:c}){return(0,b.jsxs)("div",{children:[(0,b.jsx)("span",{className:"text-[10px] uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"tnum text-text",children:c})]})}a.s(["LogTable",0,function({logs:a}){let[m,n]=(0,c.useState)(a),[o,p]=(0,c.useState)("all"),[q,r]=(0,c.useState)("all"),[s,t]=(0,c.useState)(null),[u,v]=(0,c.useState)(!0),[w,x]=(0,c.useState)(!1),[y,z]=(0,c.useState)(null),A=(0,c.useRef)(null),B=(0,c.useCallback)(async()=>{try{let a=await fetch("/api/gw/admin/logs?limit=200");if(a.ok){let b=await a.json();n(b.logs)}}catch{}},[]);(0,c.useEffect)(()=>{if(u)return A.current=setInterval(B,5e3),()=>{A.current&&clearInterval(A.current)};A.current&&clearInterval(A.current)},[u,B]);let C=[...new Set(m.map(a=>a.provider))].sort(),D=m.filter(a=>a.status>=200&&a.status<300).length,E=m.length-D,F=null!==s?Date.now()-s:null,G=m.filter(a=>("ok"!==o||!!(a.status>=200&&a.status<300))&&("error"!==o||!(a.status>=200)||!(a.status<300))&&("all"===q||a.provider===q)&&(null===F||!(a.ts<F))),H="all"!==o||"all"!==q||null!==s;return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex flex-col gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,b.jsx)("button",{onClick:()=>x(a=>!a),className:"flex-none rounded p-0.5 text-text-subtle transition-colors hover:text-text","aria-label":w?"Expand requests":"Collapse requests",title:w?"Expand":"Collapse",children:(0,b.jsx)(f.Icon,{name:w?"chevron_right":"expand_more",size:18})}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:h.map(a=>{let c;return(0,b.jsxs)("button",{onClick:()=>p(a.key),className:`flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[12px] font-medium transition-colors ${o===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:[a.label,(0,b.jsx)("span",{className:"tnum text-text-subtle",children:"all"===(c=a.key)?m.length:"ok"===c?D:E})]},a.key)})})]}),(0,b.jsxs)("button",{onClick:()=>v(a=>!a),className:`flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors ${u?"bg-success/15 text-success":"text-text-muted hover:text-text"}`,title:u?"Auto-refresh ON (5s)":"Auto-refresh OFF",children:[(0,b.jsx)(f.Icon,{name:u?"radio_button_checked":"radio_button_unchecked",size:12}),"Live"]})]}),!w&&(0,b.jsxs)("div",{className:"flex flex-wrap items-end gap-2.5",children:[(0,b.jsx)(j,{label:"Provider",children:(0,b.jsxs)("select",{value:q,onChange:a=>r(a.target.value),className:"h-9 rounded-brand border border-border bg-surface-2 px-2.5 text-[12.5px] text-text focus:border-accent focus:outline-none w-40",children:[(0,b.jsx)("option",{value:"all",children:"All providers"}),C.map(a=>(0,b.jsx)("option",{value:a,children:a},a))]})}),(0,b.jsx)(j,{label:"Since",children:(0,b.jsx)("div",{className:"flex h-9 items-center gap-0.5 rounded-brand border border-border bg-surface-2 px-1",children:i.map(a=>{let c;return(0,b.jsx)("button",{type:"button",onClick:()=>t(a.ms),className:(c=s===a.ms,`rounded-full px-2.5 py-1 text-[12px] font-medium transition-colors ${c?"bg-accent/15 text-accent":"text-text-muted hover:text-text"}`),children:a.label},a.label)})})}),(0,b.jsxs)("button",{onClick:()=>{p("all"),r("all"),t(null)},disabled:!H,className:"flex h-9 items-center gap-1.5 rounded-brand border border-border bg-surface-2 px-3 text-[12.5px] font-medium text-text-muted transition-colors hover:border-text-subtle hover:text-text disabled:opacity-40 disabled:hover:border-border disabled:hover:text-text-muted",title:H?"Reset all filters":"No filters applied",children:[(0,b.jsx)(f.Icon,{name:"filter_alt_off",size:15}),"Clear"]})]})]}),w?null:0===G.length?(0,b.jsx)("div",{className:"px-4 py-8 text-center text-[13px] text-text-muted",children:0===m.length?"No requests recorded yet.":"No requests match this filter."}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("div",{className:"table-wrap",children:(0,b.jsxs)("table",{className:"w-full min-w-[720px] border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["Status","Time","Alias","Provider","Model","In","Out","ms","Mode"].map((a,c)=>(0,b.jsx)("th",{className:`whitespace-nowrap px-4 pb-2.5 pt-3 text-[10px] font-medium uppercase tracking-wider ${c>=5&&c<=7?"text-right":"text-left"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:G.map((a,c)=>{let f=a.status>=200&&a.status<300,h=y===c;return(0,b.jsxs)("tr",{onClick:()=>z(h?null:c),className:`border-t border-border-subtle cursor-pointer transition-colors ${h?"bg-surface-2/60":"hover:bg-surface-2/70"}`,children:[(0,b.jsx)(k,{children:(0,b.jsxs)(e.Badge,{tone:f?"live":"down",children:[(0,b.jsx)(d.Lamp,{state:f?"live":"down"}),a.status]})}),(0,b.jsxs)(k,{muted:!0,title:g.fmt.time(a.ts),suppressHydrationWarning:!0,children:[g.fmt.ago(a.ts)," ago"]}),(0,b.jsx)(k,{className:"text-text",children:a.alias}),(0,b.jsx)(k,{muted:!0,children:a.provider}),(0,b.jsx)(k,{muted:!0,children:a.model}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_in)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_out)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.latency_ms)}),(0,b.jsx)(k,{muted:!0,children:a.stream?"stream":"unary"})]},c)})})]})}),null!==y&&G[y]&&(0,b.jsx)(l,{log:G[y],onClose:()=>z(null)})]})]})}])}];
|
|
1
|
+
module.exports=[42532,a=>{"use strict";var b=a.i(87924),c=a.i(72131);let d=[{key:"tokens",label:"Tokens"},{key:"cost",label:"Cost"},{key:"requests",label:"Requests"}];function e(a,b){return"tokens"===b?a.tokens_in+a.tokens_out:"cost"===b?a.cost:a.requests}function f(a,b){return"cost"===b?a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`:a>=1e6?`${(a/1e6).toFixed(1)}M`:a>=1e3?`${(a/1e3).toFixed(1)}K`:String(Math.round(a))}function g(a){return new Date(a).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:!1})}function h({series:a}){let[i,j]=(0,c.useState)("tokens"),[k,l]=(0,c.useState)(null),m=(0,c.useRef)(null),n=a.map(a=>e(a,i)),o=Math.max(1,...n),p=a.length,q=a=>p<=1?8:8+a/(p-1)*984,r=a=>224-a/o*208,s=n.map((a,b)=>`${0===b?"M":"L"}${q(b).toFixed(1)},${r(a).toFixed(1)}`).join(" "),t=`${s} L${q(p-1).toFixed(1)},224 L${q(0).toFixed(1)},224 Z`,u=n.length?n.indexOf(Math.max(...n)):-1,v=n.reduce((a,b)=>a+b,0),w=(0,c.useCallback)(a=>{if(p<=1||!m.current)return;let b=m.current.getBoundingClientRect(),c=Math.round((a.clientX-b.left)/b.width*(p-1));l(Math.max(0,Math.min(p-1,c)))},[p]),x=(0,c.useCallback)(()=>l(null),[]),y=null!==k?a[k]:null;return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"Over time"}),(0,b.jsxs)("span",{className:"tnum text-[12px] text-text-muted",children:[f(v,i)," total"]})]}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:d.map(a=>(0,b.jsx)("button",{onClick:()=>j(a.key),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${i===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:a.label},a.key))})]}),(0,b.jsx)("div",{className:"relative px-2 py-3",children:0===p||0===v?(0,b.jsx)("div",{className:"flex h-[200px] items-center justify-center text-[13px] text-text-muted",children:"No activity in this range."}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("svg",{ref:m,viewBox:"0 0 1000 240",className:"h-[200px] w-full cursor-crosshair",preserveAspectRatio:"none",onMouseMove:w,onMouseLeave:x,children:[(0,b.jsx)("defs",{children:(0,b.jsxs)("linearGradient",{id:"areaFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[(0,b.jsx)("stop",{offset:"0%",stopColor:"var(--color-accent)",stopOpacity:"0.28"}),(0,b.jsx)("stop",{offset:"100%",stopColor:"var(--color-accent)",stopOpacity:"0"})]})}),(0,b.jsx)("path",{d:t,fill:"url(#areaFill)"}),(0,b.jsx)("path",{d:s,fill:"none",stroke:"var(--color-accent)",strokeWidth:"2",vectorEffect:"non-scaling-stroke"}),u>=0&&null===k&&(0,b.jsx)("circle",{cx:q(u),cy:r(n[u]),r:"3",fill:"var(--color-accent)",vectorEffect:"non-scaling-stroke"}),null!==k&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("line",{x1:q(k),y1:16,x2:q(k),y2:224,stroke:"var(--color-accent)",strokeWidth:"1",strokeDasharray:"4 3",vectorEffect:"non-scaling-stroke",opacity:"0.5"}),(0,b.jsx)("circle",{cx:q(k),cy:r(n[k]),r:"4",fill:"var(--color-accent)",stroke:"var(--color-bg)",strokeWidth:"2",vectorEffect:"non-scaling-stroke"})]})]}),null!==k&&y&&(0,b.jsxs)("div",{className:"pointer-events-none absolute top-2 z-10 rounded-lg border border-border bg-surface-2 px-3 py-2 shadow-lg",style:{left:`${Math.min(85,Math.max(5,k/(p-1)*100))}%`,transform:"translateX(-50%)"},children:[(0,b.jsx)("div",{className:"text-[11px] text-text-muted",children:new Date(y.ts).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1})}),(0,b.jsxs)("div",{className:"mt-1 flex flex-col gap-0.5 tnum text-[12px]",children:[(0,b.jsxs)("span",{className:"text-text",children:[f(e(y,i),i)," ",(0,b.jsx)("span",{className:"text-text-muted",children:i})]}),"tokens"===i&&(0,b.jsxs)("span",{className:"text-text-subtle text-[10px]",children:["in: ",f(y.tokens_in,"tokens")," · out: ",f(y.tokens_out,"tokens")]}),(0,b.jsxs)("span",{className:"text-text-subtle text-[10px]",children:[y.requests," req · $",y.cost.toFixed(4)]})]})]})]})}),p>0&&v>0&&u>=0&&(0,b.jsxs)("div",{className:"flex justify-between border-t border-border-subtle px-4 py-2 tnum text-[10px] text-text-subtle",children:[(0,b.jsx)("span",{children:g(a[0].ts)}),(0,b.jsxs)("span",{children:["peak ",f(n[u],i)," @ ",g(a[u].ts)]}),(0,b.jsx)("span",{children:g(a[p-1].ts)})]})]})}var i=a.i(58918),j=a.i(85732);let k=[{label:"Today",key:"today",bucketMs:36e5},{label:"24h",key:"24h",bucketMs:36e5},{label:"7D",key:"7d",bucketMs:216e5},{label:"30D",key:"30d",bucketMs:864e5},{label:"60D",key:"60d",bucketMs:1728e5}];function l({rows:a,loading:c}){return(0,b.jsx)("div",{className:`table-wrap ${c?"opacity-50":""}`,children:(0,b.jsxs)("table",{className:"w-full border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["","Reqs","In","Out","Cost"].map((a,c)=>(0,b.jsx)("th",{className:`pb-2 text-[10px] font-medium uppercase tracking-wider ${0===c?"text-left":"text-right"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:a.map(a=>(0,b.jsxs)("tr",{className:"border-t border-border-subtle",children:[(0,b.jsx)("td",{className:"py-2 text-[12.5px] text-text",children:a.label}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:i.fmt.int(a.requests)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:i.fmt.compact(a.tokens_in)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text-muted",children:i.fmt.compact(a.tokens_out)}),(0,b.jsx)("td",{className:"py-2 text-right tnum text-[12.5px] text-text",children:i.fmt.cost(a.cost)})]},a.label))})]})})}a.s(["UsageView",0,function(){let[a,d]=(0,c.useState)(k[0]),[e,f]=(0,c.useState)(null),[g,m]=(0,c.useState)([]),[n,o]=(0,c.useState)(""),[p,q]=(0,c.useState)(!0),r=(0,c.useCallback)(async a=>{q(!0),o("");let b=function(a){let b=Date.now();switch(a){case"today":{let a=new Date;return a.setHours(0,0,0,0),a.getTime()}case"24h":return b-864e5;case"7d":return b-6048e5;case"30d":return b-2592e6;case"60d":return b-5184e6}}(a.key),[c,d]=await Promise.all([fetch(`/api/gw/admin/usage?since=${b}`),fetch(`/api/gw/admin/usage/series?since=${b}&bucket=${a.bucketMs}`)]);if(!c.ok){o("could not load usage"),q(!1);return}f(await c.json()),m((d.ok?await d.json():{series:[]}).series),q(!1)},[]);(0,c.useEffect)(()=>{r(a)},[a,r]);let s=e?.total;return(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"mb-6 flex items-center justify-between gap-3",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-[22px] font-semibold tracking-tight text-text",children:"Usage"}),(0,b.jsx)("p",{className:"mt-1 text-[13px] text-text-muted",children:"Tokens and cost across providers and models."})]}),(0,b.jsx)("div",{className:"flex items-center gap-1 rounded-full border border-border bg-surface p-1",children:k.map(c=>(0,b.jsx)("button",{onClick:()=>d(c),className:`rounded-full px-3 py-1 text-[12px] font-medium transition-colors ${a.label===c.label?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:c.label},c.label))})]}),n?(0,b.jsx)(i.Empty,{children:n}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{className:"mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",children:[(0,b.jsx)(i.Stat,{label:"Requests",value:i.fmt.int(s?.requests??0)}),(0,b.jsx)(i.Stat,{label:"Tokens in",value:i.fmt.compact(s?.tokens_in??0)}),(0,b.jsx)(i.Stat,{label:"Tokens out",value:i.fmt.compact(s?.tokens_out??0)}),(0,b.jsx)(i.Stat,{label:"Cost",value:i.fmt.cost(s?.cost??0)})]}),(0,b.jsx)("div",{className:"mb-5",children:(0,b.jsx)(h,{series:g})}),(0,b.jsxs)("div",{className:"grid gap-4 lg:grid-cols-2",children:[(0,b.jsx)(j.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By provider"}),children:e?.by_provider.length?(0,b.jsx)(l,{rows:e.by_provider.map(a=>({label:a.provider,...a})),loading:p}):(0,b.jsx)(i.Empty,{children:"No usage in this window."})}),(0,b.jsx)(j.RichCard,{header:(0,b.jsx)("span",{className:"text-[13px] font-semibold text-text",children:"By model"}),children:e?.by_model.length?(0,b.jsx)(l,{rows:e.by_model.map(a=>({label:`${a.alias} → ${a.model}`,...a})),loading:p}):(0,b.jsx)(i.Empty,{children:"No usage in this window."})})]})]})]})}],42532)},61574,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(47153),e=a.i(2693),f=a.i(93026),g=a.i(58918);let h=[{key:"all",label:"All"},{key:"ok",label:"Success"},{key:"error",label:"Errors"}],i=[{label:"1h",ms:36e5},{label:"6h",ms:216e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"All",ms:null}];function j({label:a,children:c}){return(0,b.jsxs)("label",{className:"flex flex-col gap-1",children:[(0,b.jsx)("span",{className:"text-[10px] font-medium uppercase tracking-wider text-text-subtle",children:a}),c]})}function k({children:a,muted:c,right:d,title:e,className:f,suppressHydrationWarning:g}){return(0,b.jsx)("td",{title:e,suppressHydrationWarning:g,className:`whitespace-nowrap px-4 py-2.5 tnum text-[12.5px] ${d?"text-right":"text-left"} ${c?"text-text-muted":"text-text"}${f?` ${f}`:""}`,children:a})}function l({log:a,onClose:c}){let d=a.status>=200&&a.status<300,e=a.tokens_in+a.tokens_out;return(0,b.jsxs)("div",{className:"border-t border-border-subtle bg-surface-2/40 px-5 py-4",children:[(0,b.jsxs)("div",{className:"mb-3 flex items-center justify-between",children:[(0,b.jsx)("span",{className:"text-[12px] font-semibold text-text",children:"Request Details"}),(0,b.jsx)("button",{onClick:c,className:"text-text-subtle hover:text-text",children:(0,b.jsx)(f.Icon,{name:"close",size:16})})]}),(0,b.jsxs)("div",{className:"grid grid-cols-2 gap-x-8 gap-y-2 text-[12px] sm:grid-cols-4",children:[(0,b.jsx)(m,{label:"Status",value:`${a.status} ${d?"OK":"Error"}`}),(0,b.jsx)(m,{label:"Timestamp",value:new Date(a.ts).toLocaleString()}),(0,b.jsx)(m,{label:"Alias",value:a.alias}),(0,b.jsx)(m,{label:"Provider",value:a.provider}),(0,b.jsx)(m,{label:"Model",value:a.model}),(0,b.jsx)(m,{label:"Mode",value:a.stream?"Streaming":"Unary"}),(0,b.jsx)(m,{label:"Latency",value:`${a.latency_ms}ms`}),(0,b.jsx)(m,{label:"Cost",value:g.fmt.cost(a.cost)}),(0,b.jsx)(m,{label:"Input tokens",value:g.fmt.int(a.tokens_in)}),(0,b.jsx)(m,{label:"Output tokens",value:g.fmt.int(a.tokens_out)}),(0,b.jsx)(m,{label:"Cached tokens",value:g.fmt.int(a.cached_tokens)}),(0,b.jsx)(m,{label:"Total tokens",value:g.fmt.int(e)})]})]})}function m({label:a,value:c}){return(0,b.jsxs)("div",{children:[(0,b.jsx)("span",{className:"text-[10px] uppercase tracking-wider text-text-subtle",children:a}),(0,b.jsx)("div",{className:"tnum text-text",children:c})]})}a.s(["LogTable",0,function({logs:a}){let[m,n]=(0,c.useState)(a),[o,p]=(0,c.useState)("all"),[q,r]=(0,c.useState)("all"),[s,t]=(0,c.useState)(null),[u,v]=(0,c.useState)(!0),[w,x]=(0,c.useState)(!1),[y,z]=(0,c.useState)(null),A=(0,c.useRef)(null),B=(0,c.useCallback)(async()=>{try{let a=await fetch("/api/gw/admin/logs?limit=200");if(a.ok){let b=await a.json();n(b.logs)}}catch{}},[]);(0,c.useEffect)(()=>{if(u)return A.current=setInterval(B,5e3),()=>{A.current&&clearInterval(A.current)};A.current&&clearInterval(A.current)},[u,B]);let C=[...new Set(m.map(a=>a.provider))].sort(),D=m.filter(a=>a.status>=200&&a.status<300).length,E=m.length-D,F=null!==s?Date.now()-s:null,G=m.filter(a=>("ok"!==o||!!(a.status>=200&&a.status<300))&&("error"!==o||!(a.status>=200)||!(a.status<300))&&("all"===q||a.provider===q)&&(null===F||!(a.ts<F))),H="all"!==o||"all"!==q||null!==s;return(0,b.jsxs)("div",{className:"overflow-hidden rounded-brand-lg border border-border bg-surface shadow-soft",children:[(0,b.jsxs)("header",{className:"flex flex-col gap-3 border-b border-border-subtle px-4 py-3",children:[(0,b.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,b.jsx)("button",{onClick:()=>x(a=>!a),className:"flex-none rounded p-0.5 text-text-subtle transition-colors hover:text-text","aria-label":w?"Expand requests":"Collapse requests",title:w?"Expand":"Collapse",children:(0,b.jsx)(f.Icon,{name:w?"chevron_right":"expand_more",size:18})}),(0,b.jsx)("div",{className:"flex items-center gap-1",children:h.map(a=>{let c;return(0,b.jsxs)("button",{onClick:()=>p(a.key),className:`flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[12px] font-medium transition-colors ${o===a.key?"bg-surface-2 text-text":"text-text-muted hover:text-text"}`,children:[a.label,(0,b.jsx)("span",{className:"tnum text-text-subtle",children:"all"===(c=a.key)?m.length:"ok"===c?D:E})]},a.key)})})]}),(0,b.jsxs)("button",{onClick:()=>v(a=>!a),className:`flex items-center gap-1 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors ${u?"bg-success/15 text-success":"text-text-muted hover:text-text"}`,title:u?"Auto-refresh ON (5s)":"Auto-refresh OFF",children:[(0,b.jsx)(f.Icon,{name:u?"radio_button_checked":"radio_button_unchecked",size:12}),"Live"]})]}),!w&&(0,b.jsxs)("div",{className:"flex flex-wrap items-end gap-2.5",children:[(0,b.jsx)(j,{label:"Provider",children:(0,b.jsxs)("select",{value:q,onChange:a=>r(a.target.value),className:"h-9 rounded-brand border border-border bg-surface-2 px-2.5 text-[12.5px] text-text focus:border-accent focus:outline-none w-40",children:[(0,b.jsx)("option",{value:"all",children:"All providers"}),C.map(a=>(0,b.jsx)("option",{value:a,children:a},a))]})}),(0,b.jsx)(j,{label:"Since",children:(0,b.jsx)("div",{className:"flex h-9 items-center gap-0.5 rounded-brand border border-border bg-surface-2 px-1",children:i.map(a=>{let c;return(0,b.jsx)("button",{type:"button",onClick:()=>t(a.ms),className:(c=s===a.ms,`rounded-full px-2.5 py-1 text-[12px] font-medium transition-colors ${c?"bg-accent/15 text-accent":"text-text-muted hover:text-text"}`),children:a.label},a.label)})})}),(0,b.jsxs)("button",{onClick:()=>{p("all"),r("all"),t(null)},disabled:!H,className:"flex h-9 items-center gap-1.5 rounded-brand border border-border bg-surface-2 px-3 text-[12.5px] font-medium text-text-muted transition-colors hover:border-text-subtle hover:text-text disabled:opacity-40 disabled:hover:border-border disabled:hover:text-text-muted",title:H?"Reset all filters":"No filters applied",children:[(0,b.jsx)(f.Icon,{name:"filter_alt_off",size:15}),"Clear"]})]})]}),w?null:0===G.length?(0,b.jsx)("div",{className:"px-4 py-8 text-center text-[13px] text-text-muted",children:0===m.length?"No requests recorded yet.":"No requests match this filter."}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("div",{className:"table-wrap",children:(0,b.jsxs)("table",{className:"w-full min-w-[720px] border-collapse",children:[(0,b.jsx)("thead",{children:(0,b.jsx)("tr",{className:"text-text-subtle",children:["Status","Time","Alias","Provider","Model","In","Out","ms","Mode"].map((a,c)=>(0,b.jsx)("th",{className:`whitespace-nowrap px-4 pb-2.5 pt-3 text-[10px] font-medium uppercase tracking-wider ${c>=5&&c<=7?"text-right":"text-left"}`,children:a},a+c))})}),(0,b.jsx)("tbody",{children:G.map((a,c)=>{let f=a.status>=200&&a.status<300,h=y===c;return(0,b.jsxs)("tr",{onClick:()=>z(h?null:c),className:`border-t border-border-subtle cursor-pointer transition-colors ${h?"bg-surface-2/60":"hover:bg-surface-2/70"}`,children:[(0,b.jsx)(k,{children:(0,b.jsxs)(e.Badge,{tone:f?"live":"down",children:[(0,b.jsx)(d.Lamp,{state:f?"live":"down"}),a.status]})}),(0,b.jsxs)(k,{muted:!0,title:g.fmt.time(a.ts),suppressHydrationWarning:!0,children:[g.fmt.ago(a.ts)," ago"]}),(0,b.jsx)(k,{className:"text-text",children:a.alias}),(0,b.jsx)(k,{muted:!0,children:a.provider}),(0,b.jsx)(k,{muted:!0,children:a.model}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_in)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.tokens_out)}),(0,b.jsx)(k,{right:!0,children:g.fmt.int(a.latency_ms)}),(0,b.jsx)(k,{muted:!0,children:a.stream?"stream":"unary"})]},c)})})]})}),null!==y&&G[y]&&(0,b.jsx)(l,{log:G[y],onClose:()=>z(null)})]})]})}])}];
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=src_components_10h9ide._.js.map
|