swayrouter 1.0.2 → 1.0.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 +8 -0
- package/dashboard/dist/assets/{CliTools-Ch3gKuNw.js → CliTools-CIzQMDvM.js} +1 -1
- package/dashboard/dist/assets/{Combo-BBCldjWi.js → Combo-BBa-P9l6.js} +1 -1
- package/dashboard/dist/assets/{ConsoleLog-wywAYcPT.js → ConsoleLog-BIFP_It7.js} +4 -4
- package/dashboard/dist/assets/{Dashboard-DxzyF41b.js → Dashboard-DItnNbII.js} +1 -1
- package/dashboard/dist/assets/{Header-C_9Su9BF.js → Header-CbIOa7_e.js} +1 -1
- package/dashboard/dist/assets/{Keys-D0ufgcsc.js → Keys-CxIo6VrX.js} +1 -1
- package/dashboard/dist/assets/Login-2dTCShcL.js +1 -0
- package/dashboard/dist/assets/{ManageApiKey-CVXsmW2B.js → ManageApiKey-g53tPOTe.js} +1 -1
- package/dashboard/dist/assets/{OAuthCallback-D_UZYcF6.js → OAuthCallback-DXHFIYHc.js} +1 -1
- package/dashboard/dist/assets/Provider-DJ9tTh9c.js +4 -0
- package/dashboard/dist/assets/{ProviderModelAccordion-BAifkfVR.js → ProviderModelAccordion-DMYEp7Us.js} +1 -1
- package/dashboard/dist/assets/{Proxy-CU15VJ--.js → Proxy-DK8e-v6V.js} +1 -1
- package/dashboard/dist/assets/QuotaMonitor-DOsLNAZu.js +1 -0
- package/dashboard/dist/assets/{Settings-Dt4y2dC0.js → Settings-PqMTQhIT.js} +1 -1
- package/dashboard/dist/assets/{Setup-DSDUwU7N.js → Setup-ywvY1myG.js} +1 -1
- package/dashboard/dist/assets/{StatusBadge-1nAOyHU2.js → StatusBadge-jJWHijDc.js} +1 -1
- package/dashboard/dist/assets/{SwayChat-Bup7up6D.js → SwayChat-DlDVoUJo.js} +2 -2
- package/dashboard/dist/assets/Usage-Dx5T_I2z.js +4 -0
- package/dashboard/dist/assets/{accordion-DOOPDDgt.js → accordion-BEa5M9JP.js} +1 -1
- package/dashboard/dist/assets/{admin-extras-api-CCdu5TFM.js → admin-extras-api-DwBdGPVg.js} +1 -1
- package/dashboard/dist/assets/{api-keys-api-ifAC2Ok3.js → api-keys-api-Dw9L6TTr.js} +1 -1
- package/dashboard/dist/assets/{card-CC0Omjcv.js → card-BL-4tjF7.js} +1 -1
- package/dashboard/dist/assets/{checkbox-7SZBrmbN.js → checkbox-Cd9rSRkt.js} +1 -1
- package/dashboard/dist/assets/{connections-api-_N54UD3S.js → connections-api-DjGgrsW9.js} +1 -1
- package/dashboard/dist/assets/{copy-button-qBvM6H9z.js → copy-button-qyO_CuV_.js} +1 -1
- package/dashboard/dist/assets/{currency-api-SV9CBf5e.js → currency-api-C007t85X.js} +1 -1
- package/dashboard/dist/assets/{flip-button-BGgkjtl0.js → flip-button-B2KSTFMN.js} +1 -1
- package/dashboard/dist/assets/{frame-cUiti6Lq.js → frame-1zkYd9EK.js} +1 -1
- package/dashboard/dist/assets/{index-B6j-9zHy.js → index-BCs8FaU-.js} +3 -3
- package/dashboard/dist/assets/index-CN-Y5gO6.css +1 -0
- package/dashboard/dist/assets/{ripple-button-l8aMiVVG.js → ripple-button-CrrjyO-q.js} +1 -1
- package/dashboard/dist/assets/{segmented-CqmEnQjZ.js → segmented-CH2xd56I.js} +1 -1
- package/dashboard/dist/assets/select-MRNgLN6P.js +1 -0
- package/dashboard/dist/assets/{skeleton-7uJDiIXe.js → skeleton-BeyFFj7e.js} +1 -1
- package/dashboard/dist/assets/{table-D0M60Tu1.js → table-DBwhoFaJ.js} +1 -1
- package/dashboard/dist/assets/{tabs-C6YkuulG.js → tabs-YNKZguh-.js} +1 -1
- package/dashboard/dist/assets/{tunnel-api-DDPsBaDV.js → tunnel-api-CCeqJWO5.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/package.json +1 -1
- package/dashboard/dist/assets/Login-BeKpipS_.js +0 -1
- package/dashboard/dist/assets/Provider-BU7JfTqm.js +0 -4
- package/dashboard/dist/assets/QuotaMonitor-HzGK7bcc.js +0 -1
- package/dashboard/dist/assets/Usage-eWnrPQ_v.js +0 -4
- package/dashboard/dist/assets/index-C-_l0yYz.css +0 -1
- package/dashboard/dist/assets/select-D8pUtMXp.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Sway Router are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.0.3] - 2026-09-13
|
|
6
|
+
|
|
7
|
+
- Improve mobile and tablet responsiveness across the dashboard.
|
|
8
|
+
- Fix provider connection and model lists being clipped or difficult to scroll on iOS.
|
|
9
|
+
- Improve mobile status visibility and Sway Chat layout behavior.
|
|
10
|
+
|
|
11
|
+
[1.0.3]: https://github.com/envielxyz/SwayRouter/releases/tag/v1.0.3
|
|
12
|
+
|
|
5
13
|
## [1.0.1] - 2026-09-12
|
|
6
14
|
|
|
7
15
|
- Publish the Sway Router package as `swayrouter` on npm.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as p,j as e}from"./react-vendor-xnYrwzsL.js";import{u as Xe,a as ee}from"./query-vendor-DVevaSVS.js";import{m as ce,A as Ke}from"./motion-vendor-g5fpGzmJ.js";import{H as Ze}from"./Header-
|
|
1
|
+
import{r as p,j as e}from"./react-vendor-xnYrwzsL.js";import{u as Xe,a as ee}from"./query-vendor-DVevaSVS.js";import{m as ce,A as Ke}from"./motion-vendor-g5fpGzmJ.js";import{H as Ze}from"./Header-CbIOa7_e.js";import{R as I}from"./ripple-button-CrrjyO-q.js";import{a as de,P as De}from"./ProviderModelAccordion-DMYEp7Us.js";import{S as ke}from"./StatusBadge-jJWHijDc.js";import{F as Me,a as Se,c as Ae}from"./frame-1zkYd9EK.js";import{y as be,J as et,I as B,S as ue,c as O,D as me,m as fe,n as pe,o as he,s as xe,F as Ue,e as z,q as ge,g as te,t as se}from"./index-BCs8FaU-.js";import{C as ne}from"./copy-button-qyO_CuV_.js";import{S as tt}from"./skeleton-BeyFFj7e.js";import{S as st,a as nt,b as ot,c as at}from"./select-MRNgLN6P.js";import{p as oe}from"./live-mode-CHShLY4E.js";import{b as rt,g as lt,d as Oe,l as it}from"./api-keys-api-Dw9L6TTr.js";import{aa as ae,q as ve,ax as ct,ay as Ee,a8 as dt,a9 as ut,D as mt,r as ft,i as pt,ag as Fe,ac as Ie,az as _e,X as ht}from"./icons-vendor-CUx7SB5V.js";import"./accordion-BEa5M9JP.js";import"./ui-vendor-BuM9f2NY.js";const D={claude:{name:"Claude Code",tier:"config"},codex:{name:"Codex CLI",tier:"config"},opencode:{name:"OpenCode",tier:"config"},hermes:{name:"Hermes Agent",tier:"config"},cowork:{name:"Claude Cowork",tier:"config"},kilo:{name:"Kilo Code",tier:"config"},"grok-build":{name:"Grok Build",tier:"config"},omp:{name:"OMP (oh-my-pi)",tier:"config"}},xt=Object.keys(D);function gt(s,...n){return n.some(r=>s[r]===!0)}function yt(s,n){var r,l,o;if(n){if(s==="claude"){const i=(r=n.settings)==null?void 0:r.env,f=["FABLE","OPUS","SONNET","HAIKU"].map(h=>i==null?void 0:i[`ANTHROPIC_DEFAULT_${h}_MODEL`]).filter(h=>typeof h=="string"&&h.length>0);return f.length?f:void 0}if(s==="hermes"){const i=(o=(l=n.settings)==null?void 0:l.model)==null?void 0:o.default;return typeof i=="string"&&i?[i]:void 0}if(s==="codex"){const c=(typeof n.config=="string"?n.config:"").match(/^model\s*=\s*["']([^"'\r\n]+)["']/m);return c?[c[1].trim()]:void 0}if(Array.isArray(n.models))return n.models.filter(i=>typeof i=="string")}}async function bt(){const{data:s}=await be.get("/cli-tools/all-statuses");return{tools:xt.map(r=>{const l=(s==null?void 0:s[r])??null,o=D[r];if(!l)return{id:r,name:o.name,tier:o.tier,installed:!1,connected:!1,available:!1,detail:"Status unavailable"};const i=l.installed!==!1,c=gt(l,"hasSwayRouter","connected");return{id:r,name:o.name,tier:o.tier,installed:i,connected:c,available:!0,configPath:et(typeof l.settingsPath=="string"?l.settingsPath:typeof l.configPath=="string"?l.configPath:void 0),detail:typeof l.message=="string"?l.message:void 0,version:typeof l.version=="string"?l.version:void 0,models:yt(r,l),raw:l}}),origin:typeof window<"u"?window.location.origin:"",apiKey:""}}function vt(s){return s.trim().replace(/\/$/,"")}function jt(s){return s==="claude"?"claude/claude-sonnet-5":s==="codex"?"openai/gpt-5":""}function Nt(s,n){var i;const r=vt(n.baseUrl||""),l=((i=n.models)==null?void 0:i.filter(Boolean))??[],o=n.primaryModel||l[0]||jt(s);switch(s){case"claude":return{env:{ANTHROPIC_BASE_URL:r,ANTHROPIC_AUTH_TOKEN:n.apiKey||"",ANTHROPIC_DEFAULT_FABLE_MODEL:n.fableModel||o,ANTHROPIC_DEFAULT_OPUS_MODEL:n.opusModel||o,ANTHROPIC_DEFAULT_SONNET_MODEL:n.sonnetModel||o,ANTHROPIC_DEFAULT_HAIKU_MODEL:n.haikuModel||o,API_TIMEOUT_MS:"600000"},exaMcpEnabled:n.exaMcpEnabled!==!1};case"codex":return{baseUrl:r,apiKey:n.apiKey||"",model:o,subagentModel:n.subagentModel||o};case"opencode":return{baseUrl:r,apiKey:n.apiKey||"",models:l.length?l:[o],activeModel:o,subagentModel:n.subagentModel||o};case"omp":return{baseUrl:r,apiKey:n.apiKey||"",models:l,primaryModel:n.primaryModel||o};case"cowork":return{baseUrl:r,apiKey:n.apiKey||"",models:l.length?l:[o]};case"grok-build":return{baseUrl:r,apiKey:n.apiKey||"",model:o};default:return{baseUrl:r,apiKey:n.apiKey||"",model:o}}}async function wt(s,n){var l,o;const{data:r}=await be.post(`/cli-tools/${encodeURIComponent(s)}-settings`,Nt(s,n));if(r.success===!1)throw new Error(r.message||"Configuration failed");return{id:s,name:((l=D[s])==null?void 0:l.name)??s,tier:((o=D[s])==null?void 0:o.tier)??"config",installed:!0,connected:!0,available:!0,detail:r.message}}async function Ct(s){return $e(s)}async function $e(s){var r,l;const{data:n}=await be.delete(`/cli-tools/${encodeURIComponent(s)}-settings`);if(n.success===!1)throw new Error(n.message||"Reset failed");return{id:s,name:((r=D[s])==null?void 0:r.name)??s,tier:((l=D[s])==null?void 0:l.tier)??"config",installed:!0,connected:!1,available:!0,detail:n.message}}async function kt(){const s=await rt().catch(()=>""),n={Accept:"application/json"};s&&(n.Authorization=`Bearer ${s}`);const r=await fetch("/v1/models",{credentials:"include",headers:n});return r.ok?((await r.json()).data??[]).flatMap(o=>{var f;const i=typeof o.id=="string"?o.id.trim():"";if(!i)return[];const c=typeof o.owned_by=="string"&&o.owned_by?o.owned_by:i.includes("/")?i.split("/",1)[0]:"other";return[{id:i,name:((f=o.name)==null?void 0:f.trim())||i,provider:c,capabilities:o.capabilities}]}):[]}function ye(s){const n=s.trim().replace(/\/$/,"");return!n||n==="—"?"":n.endsWith("/v1")?n:`${n}/v1`}function Mt(s){return[...new Set((s.models??[]).filter(n=>!!(n!=null&&n.trim())).map(n=>n.trim()))]}function He(s,n){var r;return((r=s.primaryModel)==null?void 0:r.trim())||n[0]||""}function re(s){return JSON.stringify(s,null,2)}function F(s){return JSON.stringify(s)}function St(s,n,r){var c;const l=He(s,r),o=((c=s.subagentModel)==null?void 0:c.trim())||l,i={provider:{swayrouter:{npm:"@ai-sdk/openai-compatible",options:{baseURL:ye(s.baseUrl),apiKey:n},...r.length?{models:Object.fromEntries(r.map(f=>[f,{name:f,modalities:{input:["text","image"],output:["text"]}}]))}:{}}}};return l&&(i.model=`swayrouter/${l}`),o&&(i.agent={explorer:{description:"Fast explorer subagent for codebase exploration",mode:"subagent",model:`swayrouter/${o}`}}),i}function At(s){return s?s.length<=8?"•".repeat(s.length):`${s.slice(0,4)}${"•".repeat(Math.min(16,s.length-4))}`:""}function Ot(s,n=!1){var h,w,N,k,x,M;const r=Mt(s),l=n?s.apiKey:At(s.apiKey),o=ye(s.baseUrl),i=He(s,r),c=s.toolId==="omp"?!!o:!!(o&&s.apiKey),f=c?void 0:s.toolId==="omp"?"Ensure the OMP gateway endpoint is available.":"Ensure an endpoint and API key are available.";switch(s.toolId){case"opencode":return{format:"json",fileName:"opencode.json",content:re(St(s,l,r)),modelCount:r.length,complete:c,message:f};case"omp":{const d=r.length?` models:
|
|
2
2
|
${r.map(g=>` - id: ${JSON.stringify(g)}
|
|
3
3
|
name: ${JSON.stringify(g)}`).join(`
|
|
4
4
|
`)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as e,a as de}from"./react-vendor-xnYrwzsL.js";import{u as me,a as B}from"./query-vendor-DVevaSVS.js";import{H as ue}from"./Header-C_9Su9BF.js";import{R as P}from"./ripple-button-l8aMiVVG.js";import{P as xe,a as pe}from"./ProviderModelAccordion-BAifkfVR.js";import{I as O,h as U,e as z,D as V,m as W,n as X,o as Y,F as fe,q as Z,s as he,g as G,a as ee,S as be,t as $,E as ge}from"./index-B6j-9zHy.js";import{F as je,c as ve}from"./frame-cUiti6Lq.js";import{S as ye}from"./segmented-CqmEnQjZ.js";import{S as Ne}from"./skeleton-7uJDiIXe.js";import{T as we,a as Se,b as te,c as K,d as ke,e as T}from"./table-D0M60Tu1.js";import{b as Ce,e as Me,f as De,g as Ee}from"./admin-extras-api-CCdu5TFM.js";import{g as qe}from"./chatStudio-C0zPz_Z_.js";import{b as Pe}from"./api-keys-api-ifAC2Ok3.js";import{p as se}from"./live-mode-CHShLY4E.js";import{ac as ae,q as le,h as re,af as oe,i as ze,X as Ae,a as Fe,ag as Le}from"./icons-vendor-CUx7SB5V.js";import"./accordion-DOOPDDgt.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";async function Re(){const u=await Pe().catch(()=>""),c={Accept:"application/json"};u&&(c.Authorization=`Bearer ${u}`);const h=await fetch("/v1/models",{credentials:"include",headers:c});if(!h.ok){const n=await h.json().catch(()=>null),l=n==null?void 0:n.error,p=typeof l=="string"?l:(l==null?void 0:l.message)||(n==null?void 0:n.message)||`Models request failed (${h.status})`;throw new Error(p)}return((await h.json()).data??[]).flatMap(n=>{var m;const l=typeof n.id=="string"?n.id.trim():"";if(!l)return[];const p=typeof n.owned_by=="string"&&n.owned_by?n.owned_by:l.includes("/")?l.split("/",1)[0]:"other";return[{id:l,name:((m=n.name)==null?void 0:m.trim())||l,provider:p}]})}function ne({models:u,selected:c,onChange:h,loading:A=!1,error:n,multiple:l=!0,placeholder:p="Select models"}){const[m,g]=i.useState(!1),[f,N]=i.useState(""),w=i.useRef(null),S=i.useRef(null),F=i.useRef(null),[b,v]=i.useState(null);function k(){const s=S.current;if(!s)return;const o=s.getBoundingClientRect(),r=12,x=6,C=window.innerHeight-o.bottom-r,M=o.top-r,D=C<230&&M>C,j=Math.max(144,D?M:C),E=Math.max(120,Math.min(256,j-54)),q=o.width,R=Math.min(Math.max(r,o.left),Math.max(r,window.innerWidth-q-r));v(D?{left:R,bottom:window.innerHeight-o.top+x,width:q,listHeight:E}:{left:R,top:o.bottom+x,width:q,listHeight:E})}i.useEffect(()=>{if(!m)return;function s(o){var x;const r=o.target;w.current&&!w.current.contains(r)&&!((x=F.current)!=null&&x.contains(r))&&g(!1)}return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[m]),i.useEffect(()=>{if(!m){v(null);return}k();const s=()=>k();return window.addEventListener("resize",s),window.addEventListener("scroll",s,!0),()=>{window.removeEventListener("resize",s),window.removeEventListener("scroll",s,!0)}},[m]);const y=i.useMemo(()=>{const s=new Set(u.map(r=>r.id)),o=c.filter(r=>r&&!s.has(r)).map(r=>{const x=r.split("/").filter(Boolean);return{id:r,name:x[x.length-1]||r,provider:x.length>1?x[0]:"other"}});return[...u,...o]},[u,c]),L=i.useMemo(()=>qe(y,f),[y,f]);function Q(s){if(!l){h([s]),g(!1);return}h(c.includes(s)?c.filter(o=>o!==s):[...c,s])}return e.jsxs("div",{ref:w,className:"relative",children:[e.jsxs("button",{ref:S,type:"button",onClick:()=>g(s=>!s),className:"flex min-h-9 w-full items-center gap-2 rounded-md border border-input bg-surface px-2.5 py-1.5 text-left text-sm transition-colors hover:bg-surface-hover","aria-haspopup":"listbox","aria-expanded":m,children:[e.jsx("span",{className:"min-w-0 flex-1 truncate text-xs text-foreground",children:c.length===0?p:l?`${c.length} model${c.length===1?"":"s"} selected`:c[0]}),e.jsx(ze,{className:`size-4 shrink-0 text-muted-foreground transition-transform ${m?"rotate-180":""}`})]}),c.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:c.map(s=>e.jsxs("span",{className:"inline-flex max-w-full items-center gap-1 rounded-md border border-border bg-muted/45 px-2 py-1 text-[11px] text-foreground",children:[e.jsx(z,{label:s,children:e.jsx("span",{className:"max-w-[15rem] truncate font-mono",children:s})}),e.jsx("button",{type:"button",onClick:()=>h(c.filter(o=>o!==s)),className:"shrink-0 rounded p-0.5 text-muted-foreground hover:bg-surface-hover hover:text-foreground","aria-label":`Remove ${s}`,children:e.jsx(Ae,{className:"size-3"})})]},s))}):null,m&&b?de.createPortal(e.jsxs("div",{ref:F,className:"fixed z-[100] overflow-hidden rounded-xl border border-border bg-card",style:{left:b.left,top:b.top,bottom:b.bottom,width:b.width},children:[e.jsx("div",{className:"border-b border-border p-1.5",children:e.jsxs("div",{className:"relative",children:[e.jsx(le,{className:"pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground"}),e.jsx(O,{autoFocus:!0,value:f,onChange:s=>N(s.target.value),placeholder:"Search models…","aria-label":"Search models",className:"h-8 pl-7 text-xs"})]})}),A?e.jsx("p",{className:"px-3 py-5 text-center text-xs text-muted-foreground",children:"Loading models…"}):n?e.jsxs("div",{className:"flex items-start gap-2 px-3 py-4 text-xs text-destructive",children:[e.jsx(Fe,{className:"mt-0.5 size-3.5 shrink-0"}),e.jsx("span",{children:G(n,"Unable to load models")})]}):e.jsx(be,{className:"min-h-0",style:{height:b.listHeight},overscrollContain:!0,children:e.jsx("div",{role:"listbox","aria-multiselectable":l,className:"py-1",children:e.jsx(xe,{groups:L,query:f,empty:e.jsx("p",{className:"px-3 py-5 text-center text-xs text-muted-foreground",children:y.length?"No models match":"No provider models available"}),renderItem:(s,o)=>{const r=c.includes(s.id);return e.jsxs("button",{type:"button",role:"option","aria-selected":r,onClick:()=>Q(s.id),className:"flex w-full items-start gap-2 rounded-md px-2.5 py-1.5 text-left text-foreground transition-colors hover:bg-surface-hover",children:[e.jsx(pe,{provider:o,className:"mt-0.5 size-5"}),e.jsx(z,{label:s.id,children:e.jsx("span",{className:"min-w-0 flex-1 break-all font-mono text-[11px] leading-4",children:s.id})}),r?e.jsx(Le,{className:"mt-0.5 size-3.5 shrink-0 text-primary"}):null]})}})})})]}),document.body):null]})}function tt(){var _;const u=me(),[c,h]=i.useState(""),[A,n]=i.useState(!1),[l,p]=i.useState(null),[m,g]=i.useState(null),[f,N]=i.useState(!1),[w,S]=i.useState(""),[F,b]=i.useState([]),[v,k]=i.useState("fallback"),[y,L]=i.useState(""),Q=B({queryKey:["combos"],queryFn:Ee,enabled:se(),retry:!1}),s=B({queryKey:["settings"],queryFn:ge,enabled:se(),retry:!1}),o=B({queryKey:["combos","models"],queryFn:Re,enabled:A,retry:1}),r=Q.data??[],x=Q.isLoading,C=i.useMemo(()=>(o.data??[]).filter(t=>t.provider!=="combo"),[o.data]),M=((_=s.data)==null?void 0:_.comboStrategies)??{},D=i.useMemo(()=>{const t=c.trim().toLowerCase();return t?r.filter(a=>a.name.toLowerCase().includes(t)||a.models.some(d=>d.toLowerCase().includes(t))):r},[r,c]);function j(t,a="default"){a==="success"?$.success(t):a==="error"?$.error(t):$(t)}function E(){S(""),b([]),k("fallback"),L("")}function q(){E(),p(null),n(!0)}function R(t){p(t),S(t.name),b(t.models);const a=M[t.name]||{};k(a.fallbackStrategy==="round-robin"||a.fallbackStrategy==="fusion"||a.fallbackStrategy==="fallback"?a.fallbackStrategy:"fallback"),L(a.judgeModel||""),n(!0)}async function I(t,a,d){const J=(d||s.data||{}).comboStrategies||{};await ee({comboStrategies:{...J,[t]:{...J[t],...a}}}),await u.invalidateQueries({queryKey:["settings"]})}async function ie(){const t=w.trim(),a=F;if(!t)return j("Name required","error");if(!a.length)return j("Add at least one model","error");N(!0);try{const d={fallbackStrategy:v,judgeModel:v==="fusion"&&y.trim()||void 0};l?(await Ce(l.id||l.name,{models:a,name:t!==l.name?t:void 0}),await I(t,d,s.data),await u.invalidateQueries({queryKey:["combos"]}),j("Combo updated","success")):(await Me({name:t,models:a}),await I(t,d,s.data),await u.invalidateQueries({queryKey:["combos"]}),j("Combo created","success")),n(!1),p(null),E()}catch(d){j(G(d,"Save failed"),"error")}finally{N(!1)}}async function ce(){const t=m;if(t){N(!0);try{await De(t.id||t.name);const d=(s.data||{}).comboStrategies||{};if(d[t.name]){const H={...d};delete H[t.name],await ee({comboStrategies:H}),await u.invalidateQueries({queryKey:["settings"]})}await u.invalidateQueries({queryKey:["combos"]}),j("Combo deleted","success"),g(null)}catch(a){j(G(a,"Delete failed"),"error")}finally{N(!1)}}}return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ue,{title:"Combos",actions:r.length>0?e.jsxs(P,{size:"sm",onClick:q,children:[e.jsx(ae,{className:"h-4 w-4"}),"Add combo"]}):null}),e.jsxs("div",{className:"relative max-w-md",children:[e.jsx(le,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(O,{value:c,onChange:t=>h(t.target.value),placeholder:"Search combos…",className:"pl-9"})]}),e.jsx(je,{className:"overflow-hidden",children:e.jsx(ve,{className:"p-0",children:x?e.jsx("div",{className:"space-y-2 p-4",children:Array.from({length:3}).map((t,a)=>e.jsx(Ne,{className:"h-12 w-full"},a))}):r.length===0?e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-16 text-center",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"No combos yet"}),e.jsxs(P,{size:"sm",onClick:q,children:[e.jsx(ae,{className:"h-4 w-4"}),"Create first combo"]})]}):D.length===0?e.jsx("div",{className:"px-4 py-16 text-center text-sm text-muted-foreground",children:"No combos match your search."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"divide-y divide-border/70 rounded-xl border border-border/70 bg-card sm:hidden",children:D.map(t=>{const a=M[t.name]||{},d=a.fallbackStrategy||"fallback";return e.jsxs("article",{className:"min-w-0 space-y-2.5 p-3",children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium",children:t.name}),e.jsx(U,{variant:"outline",className:"mt-1 text-[10px]",children:d})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsx(z,{label:"Edit",children:e.jsx("button",{type:"button",className:"inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-surface-hover hover:text-foreground",onClick:()=>R(t),"aria-label":"Edit combo",children:e.jsx(re,{className:"h-3.5 w-3.5"})})}),e.jsx(z,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>g(t),"aria-label":"Delete combo",children:e.jsx(oe,{className:"h-3.5 w-3.5"})})})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-medium uppercase tracking-wide text-muted-foreground",children:"Models"}),e.jsx("p",{className:"mt-1 break-words font-mono text-[11px] leading-4 text-muted-foreground",children:t.models.join(" → ")}),d==="fusion"&&a.judgeModel?e.jsxs("p",{className:"mt-1 break-words text-[10px] text-muted-foreground",children:["Judge: ",a.judgeModel]}):null]})]},t.id||t.name)})}),e.jsx("div",{className:"hidden sm:block",children:e.jsxs(we,{className:"min-w-[40rem] text-[13px]",children:[e.jsx(Se,{className:"sticky top-0 z-10 bg-background text-[10px] uppercase text-muted-foreground",children:e.jsxs(te,{className:"border-b border-border/80",children:[e.jsx(K,{className:"px-4 py-2 font-medium",children:"Name"}),e.jsx(K,{className:"px-2 py-2 font-medium",children:"Strategy"}),e.jsx(K,{className:"px-2 py-2 font-medium",children:"Models"}),e.jsx(K,{className:"px-4 py-2 font-medium text-right",children:"Actions"})]})}),e.jsx(ke,{children:D.map(t=>{const a=M[t.name]||{},d=a.fallbackStrategy||"fallback";return e.jsxs(te,{className:"border-b border-border/60 last:border-0 hover:bg-muted/30",children:[e.jsx(T,{className:"max-w-[12rem] truncate px-4 py-2 font-medium",children:t.name}),e.jsx(T,{className:"px-2 py-2",children:e.jsx(U,{variant:"outline",className:"text-[10px]",children:d})}),e.jsx(T,{className:"px-2 py-2",children:e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"max-w-[24rem] truncate font-mono text-[11px] text-muted-foreground",children:t.models.join(" → ")}),d==="fusion"&&a.judgeModel?e.jsxs("p",{className:"mt-0.5 text-[10px] text-muted-foreground",children:["judge: ",a.judgeModel]}):null]})}),e.jsx(T,{className:"px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",children:[e.jsx(z,{label:"Edit",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-surface-hover hover:text-foreground",onClick:()=>R(t),"aria-label":"Edit combo",children:e.jsx(re,{className:"h-3.5 w-3.5"})})}),e.jsx(z,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>g(t),"aria-label":"Delete combo",children:e.jsx(oe,{className:"h-3.5 w-3.5"})})})]})})]},t.id||t.name)})})]})})]})})}),e.jsx(V,{open:A,onOpenChange:t=>{t||(n(!1),p(null),E())},children:e.jsxs(W,{className:"max-h-[90vh]",children:[e.jsx(X,{children:e.jsx(Y,{children:l?"Edit combo":"Create combo"})}),e.jsxs(fe,{className:"space-y-4",children:[e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Name"}),e.jsx(O,{value:w,onChange:t=>S(t.target.value),placeholder:"smart"})]}),e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Models"}),e.jsx(ne,{models:C,selected:F,onChange:b,loading:o.isLoading,error:o.error,placeholder:"Select provider models"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("span",{className:"block text-xs text-muted-foreground",children:"Strategy"}),e.jsx(ye,{size:"sm",value:v,onChange:k,options:[{value:"fallback",label:"Fallback"},{value:"round-robin",label:"Round-robin"},{value:"fusion",label:"Fusion"}]})]}),v==="fusion"?e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Judge model"}),e.jsx(ne,{models:C,selected:y?[y]:[],onChange:t=>L(t[0]||""),loading:o.isLoading,error:o.error,multiple:!1,placeholder:"Select judge model"})]}):null]}),e.jsxs(Z,{children:[e.jsx(P,{variant:"outline",onClick:()=>{n(!1),p(null)},disabled:f,children:"Cancel"}),e.jsx(P,{onClick:ie,disabled:f,children:f?"Saving…":l?"Save":"Create"})]})]})}),e.jsx(V,{open:!!m,onOpenChange:t=>{t||g(null)},children:e.jsxs(W,{children:[e.jsxs(X,{children:[e.jsx(Y,{children:"Delete combo?"}),e.jsxs(he,{children:[e.jsx("span",{className:"font-medium text-foreground",children:m==null?void 0:m.name})," ","and its strategy override will be removed."]})]}),e.jsxs(Z,{children:[e.jsx(P,{variant:"outline",onClick:()=>g(null),disabled:f,children:"Cancel"}),e.jsx(P,{variant:"destructive",onClick:ce,disabled:f,children:f?"Deleting…":"Delete"})]})]})})]})}export{tt as default};
|
|
1
|
+
import{r as i,j as e,a as de}from"./react-vendor-xnYrwzsL.js";import{u as me,a as B}from"./query-vendor-DVevaSVS.js";import{H as ue}from"./Header-CbIOa7_e.js";import{R as P}from"./ripple-button-CrrjyO-q.js";import{P as xe,a as pe}from"./ProviderModelAccordion-DMYEp7Us.js";import{I as O,h as U,e as z,D as V,m as W,n as X,o as Y,F as fe,q as Z,s as he,g as G,a as ee,S as be,t as $,E as ge}from"./index-BCs8FaU-.js";import{F as je,c as ve}from"./frame-1zkYd9EK.js";import{S as ye}from"./segmented-CH2xd56I.js";import{S as Ne}from"./skeleton-BeyFFj7e.js";import{T as we,a as Se,b as te,c as K,d as ke,e as T}from"./table-DBwhoFaJ.js";import{b as Ce,e as Me,f as De,g as Ee}from"./admin-extras-api-DwBdGPVg.js";import{g as qe}from"./chatStudio-C0zPz_Z_.js";import{b as Pe}from"./api-keys-api-Dw9L6TTr.js";import{p as se}from"./live-mode-CHShLY4E.js";import{ac as ae,q as le,h as re,af as oe,i as ze,X as Ae,a as Fe,ag as Le}from"./icons-vendor-CUx7SB5V.js";import"./accordion-BEa5M9JP.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";async function Re(){const u=await Pe().catch(()=>""),c={Accept:"application/json"};u&&(c.Authorization=`Bearer ${u}`);const h=await fetch("/v1/models",{credentials:"include",headers:c});if(!h.ok){const n=await h.json().catch(()=>null),l=n==null?void 0:n.error,p=typeof l=="string"?l:(l==null?void 0:l.message)||(n==null?void 0:n.message)||`Models request failed (${h.status})`;throw new Error(p)}return((await h.json()).data??[]).flatMap(n=>{var m;const l=typeof n.id=="string"?n.id.trim():"";if(!l)return[];const p=typeof n.owned_by=="string"&&n.owned_by?n.owned_by:l.includes("/")?l.split("/",1)[0]:"other";return[{id:l,name:((m=n.name)==null?void 0:m.trim())||l,provider:p}]})}function ne({models:u,selected:c,onChange:h,loading:A=!1,error:n,multiple:l=!0,placeholder:p="Select models"}){const[m,g]=i.useState(!1),[f,N]=i.useState(""),w=i.useRef(null),S=i.useRef(null),F=i.useRef(null),[b,v]=i.useState(null);function k(){const s=S.current;if(!s)return;const o=s.getBoundingClientRect(),r=12,x=6,C=window.innerHeight-o.bottom-r,M=o.top-r,D=C<230&&M>C,j=Math.max(144,D?M:C),E=Math.max(120,Math.min(256,j-54)),q=o.width,R=Math.min(Math.max(r,o.left),Math.max(r,window.innerWidth-q-r));v(D?{left:R,bottom:window.innerHeight-o.top+x,width:q,listHeight:E}:{left:R,top:o.bottom+x,width:q,listHeight:E})}i.useEffect(()=>{if(!m)return;function s(o){var x;const r=o.target;w.current&&!w.current.contains(r)&&!((x=F.current)!=null&&x.contains(r))&&g(!1)}return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[m]),i.useEffect(()=>{if(!m){v(null);return}k();const s=()=>k();return window.addEventListener("resize",s),window.addEventListener("scroll",s,!0),()=>{window.removeEventListener("resize",s),window.removeEventListener("scroll",s,!0)}},[m]);const y=i.useMemo(()=>{const s=new Set(u.map(r=>r.id)),o=c.filter(r=>r&&!s.has(r)).map(r=>{const x=r.split("/").filter(Boolean);return{id:r,name:x[x.length-1]||r,provider:x.length>1?x[0]:"other"}});return[...u,...o]},[u,c]),L=i.useMemo(()=>qe(y,f),[y,f]);function Q(s){if(!l){h([s]),g(!1);return}h(c.includes(s)?c.filter(o=>o!==s):[...c,s])}return e.jsxs("div",{ref:w,className:"relative",children:[e.jsxs("button",{ref:S,type:"button",onClick:()=>g(s=>!s),className:"flex min-h-9 w-full items-center gap-2 rounded-md border border-input bg-surface px-2.5 py-1.5 text-left text-sm transition-colors hover:bg-surface-hover","aria-haspopup":"listbox","aria-expanded":m,children:[e.jsx("span",{className:"min-w-0 flex-1 truncate text-xs text-foreground",children:c.length===0?p:l?`${c.length} model${c.length===1?"":"s"} selected`:c[0]}),e.jsx(ze,{className:`size-4 shrink-0 text-muted-foreground transition-transform ${m?"rotate-180":""}`})]}),c.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:c.map(s=>e.jsxs("span",{className:"inline-flex max-w-full items-center gap-1 rounded-md border border-border bg-muted/45 px-2 py-1 text-[11px] text-foreground",children:[e.jsx(z,{label:s,children:e.jsx("span",{className:"max-w-[15rem] truncate font-mono",children:s})}),e.jsx("button",{type:"button",onClick:()=>h(c.filter(o=>o!==s)),className:"shrink-0 rounded p-0.5 text-muted-foreground hover:bg-surface-hover hover:text-foreground","aria-label":`Remove ${s}`,children:e.jsx(Ae,{className:"size-3"})})]},s))}):null,m&&b?de.createPortal(e.jsxs("div",{ref:F,className:"fixed z-[100] overflow-hidden rounded-xl border border-border bg-card",style:{left:b.left,top:b.top,bottom:b.bottom,width:b.width},children:[e.jsx("div",{className:"border-b border-border p-1.5",children:e.jsxs("div",{className:"relative",children:[e.jsx(le,{className:"pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground"}),e.jsx(O,{autoFocus:!0,value:f,onChange:s=>N(s.target.value),placeholder:"Search models…","aria-label":"Search models",className:"h-8 pl-7 text-xs"})]})}),A?e.jsx("p",{className:"px-3 py-5 text-center text-xs text-muted-foreground",children:"Loading models…"}):n?e.jsxs("div",{className:"flex items-start gap-2 px-3 py-4 text-xs text-destructive",children:[e.jsx(Fe,{className:"mt-0.5 size-3.5 shrink-0"}),e.jsx("span",{children:G(n,"Unable to load models")})]}):e.jsx(be,{className:"min-h-0",style:{height:b.listHeight},overscrollContain:!0,children:e.jsx("div",{role:"listbox","aria-multiselectable":l,className:"py-1",children:e.jsx(xe,{groups:L,query:f,empty:e.jsx("p",{className:"px-3 py-5 text-center text-xs text-muted-foreground",children:y.length?"No models match":"No provider models available"}),renderItem:(s,o)=>{const r=c.includes(s.id);return e.jsxs("button",{type:"button",role:"option","aria-selected":r,onClick:()=>Q(s.id),className:"flex w-full items-start gap-2 rounded-md px-2.5 py-1.5 text-left text-foreground transition-colors hover:bg-surface-hover",children:[e.jsx(pe,{provider:o,className:"mt-0.5 size-5"}),e.jsx(z,{label:s.id,children:e.jsx("span",{className:"min-w-0 flex-1 break-all font-mono text-[11px] leading-4",children:s.id})}),r?e.jsx(Le,{className:"mt-0.5 size-3.5 shrink-0 text-primary"}):null]})}})})})]}),document.body):null]})}function tt(){var _;const u=me(),[c,h]=i.useState(""),[A,n]=i.useState(!1),[l,p]=i.useState(null),[m,g]=i.useState(null),[f,N]=i.useState(!1),[w,S]=i.useState(""),[F,b]=i.useState([]),[v,k]=i.useState("fallback"),[y,L]=i.useState(""),Q=B({queryKey:["combos"],queryFn:Ee,enabled:se(),retry:!1}),s=B({queryKey:["settings"],queryFn:ge,enabled:se(),retry:!1}),o=B({queryKey:["combos","models"],queryFn:Re,enabled:A,retry:1}),r=Q.data??[],x=Q.isLoading,C=i.useMemo(()=>(o.data??[]).filter(t=>t.provider!=="combo"),[o.data]),M=((_=s.data)==null?void 0:_.comboStrategies)??{},D=i.useMemo(()=>{const t=c.trim().toLowerCase();return t?r.filter(a=>a.name.toLowerCase().includes(t)||a.models.some(d=>d.toLowerCase().includes(t))):r},[r,c]);function j(t,a="default"){a==="success"?$.success(t):a==="error"?$.error(t):$(t)}function E(){S(""),b([]),k("fallback"),L("")}function q(){E(),p(null),n(!0)}function R(t){p(t),S(t.name),b(t.models);const a=M[t.name]||{};k(a.fallbackStrategy==="round-robin"||a.fallbackStrategy==="fusion"||a.fallbackStrategy==="fallback"?a.fallbackStrategy:"fallback"),L(a.judgeModel||""),n(!0)}async function I(t,a,d){const J=(d||s.data||{}).comboStrategies||{};await ee({comboStrategies:{...J,[t]:{...J[t],...a}}}),await u.invalidateQueries({queryKey:["settings"]})}async function ie(){const t=w.trim(),a=F;if(!t)return j("Name required","error");if(!a.length)return j("Add at least one model","error");N(!0);try{const d={fallbackStrategy:v,judgeModel:v==="fusion"&&y.trim()||void 0};l?(await Ce(l.id||l.name,{models:a,name:t!==l.name?t:void 0}),await I(t,d,s.data),await u.invalidateQueries({queryKey:["combos"]}),j("Combo updated","success")):(await Me({name:t,models:a}),await I(t,d,s.data),await u.invalidateQueries({queryKey:["combos"]}),j("Combo created","success")),n(!1),p(null),E()}catch(d){j(G(d,"Save failed"),"error")}finally{N(!1)}}async function ce(){const t=m;if(t){N(!0);try{await De(t.id||t.name);const d=(s.data||{}).comboStrategies||{};if(d[t.name]){const H={...d};delete H[t.name],await ee({comboStrategies:H}),await u.invalidateQueries({queryKey:["settings"]})}await u.invalidateQueries({queryKey:["combos"]}),j("Combo deleted","success"),g(null)}catch(a){j(G(a,"Delete failed"),"error")}finally{N(!1)}}}return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ue,{title:"Combos",actions:r.length>0?e.jsxs(P,{size:"sm",onClick:q,children:[e.jsx(ae,{className:"h-4 w-4"}),"Add combo"]}):null}),e.jsxs("div",{className:"relative max-w-md",children:[e.jsx(le,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(O,{value:c,onChange:t=>h(t.target.value),placeholder:"Search combos…",className:"pl-9"})]}),e.jsx(je,{className:"overflow-hidden",children:e.jsx(ve,{className:"p-0",children:x?e.jsx("div",{className:"space-y-2 p-4",children:Array.from({length:3}).map((t,a)=>e.jsx(Ne,{className:"h-12 w-full"},a))}):r.length===0?e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-16 text-center",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"No combos yet"}),e.jsxs(P,{size:"sm",onClick:q,children:[e.jsx(ae,{className:"h-4 w-4"}),"Create first combo"]})]}):D.length===0?e.jsx("div",{className:"px-4 py-16 text-center text-sm text-muted-foreground",children:"No combos match your search."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"divide-y divide-border/70 rounded-xl border border-border/70 bg-card sm:hidden",children:D.map(t=>{const a=M[t.name]||{},d=a.fallbackStrategy||"fallback";return e.jsxs("article",{className:"min-w-0 space-y-2.5 p-3",children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium",children:t.name}),e.jsx(U,{variant:"outline",className:"mt-1 text-[10px]",children:d})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsx(z,{label:"Edit",children:e.jsx("button",{type:"button",className:"inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-surface-hover hover:text-foreground",onClick:()=>R(t),"aria-label":"Edit combo",children:e.jsx(re,{className:"h-3.5 w-3.5"})})}),e.jsx(z,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>g(t),"aria-label":"Delete combo",children:e.jsx(oe,{className:"h-3.5 w-3.5"})})})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-medium uppercase tracking-wide text-muted-foreground",children:"Models"}),e.jsx("p",{className:"mt-1 break-words font-mono text-[11px] leading-4 text-muted-foreground",children:t.models.join(" → ")}),d==="fusion"&&a.judgeModel?e.jsxs("p",{className:"mt-1 break-words text-[10px] text-muted-foreground",children:["Judge: ",a.judgeModel]}):null]})]},t.id||t.name)})}),e.jsx("div",{className:"hidden sm:block",children:e.jsxs(we,{className:"min-w-[40rem] text-[13px]",children:[e.jsx(Se,{className:"sticky top-0 z-10 bg-background text-[10px] uppercase text-muted-foreground",children:e.jsxs(te,{className:"border-b border-border/80",children:[e.jsx(K,{className:"px-4 py-2 font-medium",children:"Name"}),e.jsx(K,{className:"px-2 py-2 font-medium",children:"Strategy"}),e.jsx(K,{className:"px-2 py-2 font-medium",children:"Models"}),e.jsx(K,{className:"px-4 py-2 font-medium text-right",children:"Actions"})]})}),e.jsx(ke,{children:D.map(t=>{const a=M[t.name]||{},d=a.fallbackStrategy||"fallback";return e.jsxs(te,{className:"border-b border-border/60 last:border-0 hover:bg-muted/30",children:[e.jsx(T,{className:"max-w-[12rem] truncate px-4 py-2 font-medium",children:t.name}),e.jsx(T,{className:"px-2 py-2",children:e.jsx(U,{variant:"outline",className:"text-[10px]",children:d})}),e.jsx(T,{className:"px-2 py-2",children:e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"max-w-[24rem] truncate font-mono text-[11px] text-muted-foreground",children:t.models.join(" → ")}),d==="fusion"&&a.judgeModel?e.jsxs("p",{className:"mt-0.5 text-[10px] text-muted-foreground",children:["judge: ",a.judgeModel]}):null]})}),e.jsx(T,{className:"px-4 py-2",children:e.jsxs("div",{className:"flex items-center justify-end gap-1.5",children:[e.jsx(z,{label:"Edit",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-surface-hover hover:text-foreground",onClick:()=>R(t),"aria-label":"Edit combo",children:e.jsx(re,{className:"h-3.5 w-3.5"})})}),e.jsx(z,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>g(t),"aria-label":"Delete combo",children:e.jsx(oe,{className:"h-3.5 w-3.5"})})})]})})]},t.id||t.name)})})]})})]})})}),e.jsx(V,{open:A,onOpenChange:t=>{t||(n(!1),p(null),E())},children:e.jsxs(W,{className:"max-h-[90vh]",children:[e.jsx(X,{children:e.jsx(Y,{children:l?"Edit combo":"Create combo"})}),e.jsxs(fe,{className:"space-y-4",children:[e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Name"}),e.jsx(O,{value:w,onChange:t=>S(t.target.value),placeholder:"smart"})]}),e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Models"}),e.jsx(ne,{models:C,selected:F,onChange:b,loading:o.isLoading,error:o.error,placeholder:"Select provider models"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("span",{className:"block text-xs text-muted-foreground",children:"Strategy"}),e.jsx(ye,{size:"sm",value:v,onChange:k,options:[{value:"fallback",label:"Fallback"},{value:"round-robin",label:"Round-robin"},{value:"fusion",label:"Fusion"}]})]}),v==="fusion"?e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Judge model"}),e.jsx(ne,{models:C,selected:y?[y]:[],onChange:t=>L(t[0]||""),loading:o.isLoading,error:o.error,multiple:!1,placeholder:"Select judge model"})]}):null]}),e.jsxs(Z,{children:[e.jsx(P,{variant:"outline",onClick:()=>{n(!1),p(null)},disabled:f,children:"Cancel"}),e.jsx(P,{onClick:ie,disabled:f,children:f?"Saving…":l?"Save":"Create"})]})]})}),e.jsx(V,{open:!!m,onOpenChange:t=>{t||g(null)},children:e.jsxs(W,{children:[e.jsxs(X,{children:[e.jsx(Y,{children:"Delete combo?"}),e.jsxs(he,{children:[e.jsx("span",{className:"font-medium text-foreground",children:m==null?void 0:m.name})," ","and its strategy override will be removed."]})]}),e.jsxs(Z,{children:[e.jsx(P,{variant:"outline",onClick:()=>g(null),disabled:f,children:"Cancel"}),e.jsx(P,{variant:"destructive",onClick:ce,disabled:f,children:f?"Deleting…":"Delete"})]})]})})]})}export{tt as default};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{j as s,r as d}from"./react-vendor-xnYrwzsL.js";import{H as Te}from"./Header-
|
|
1
|
+
import{j as s,r as d}from"./react-vendor-xnYrwzsL.js";import{H as Te}from"./Header-CbIOa7_e.js";import{c as x,I as Ne,e as V,S as Ce,h as Ae,D as ve,m as we,n as ye,o as Oe,s as Le,q as je,y as Fe,t as k,g as Z}from"./index-BCs8FaU-.js";import{R as y}from"./ripple-button-CrrjyO-q.js";import{F as De,a as _e,c as Y}from"./frame-1zkYd9EK.js";import{af as ke,q as Me,aI as Pe,ag as Ue,ad as Be}from"./icons-vendor-CUx7SB5V.js";import"./query-vendor-DVevaSVS.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";const J={healthy:"bg-success",active:"bg-success",degraded:"bg-warning",down:"bg-destructive",inactive:"bg-muted-foreground",unknown:"bg-muted-foreground"};function Ie({status:t="unknown",className:e,pulse:r=!0}){return s.jsxs("span",{className:x("relative inline-flex h-2.5 w-2.5",e),children:[r&&(t==="healthy"||t==="active")&&s.jsx("span",{className:x("absolute inline-flex h-full w-full animate-ping rounded-full opacity-40",J[t])}),s.jsx("span",{className:x("relative inline-flex h-2.5 w-2.5 rounded-full",J[t])})]})}const Q={AUTH:"Account routing",Auth:"Authentication",API:"API request",A4_3:"Compatibility retry",A4_4:"Compatibility retry",AutoPing:"Quota monitor",BG_TOKEN_REFRESH:"Token refresh",CHAT:"Chat request",CLIENT:"Client detection",CODEX:"Codex",COMBO:"Model fallback",CTRL:"Connection",DATA_DIR:"Data directory",DB:"Database",FETCH:"Provider",FORMAT:"Format conversion",FUSION:"Model fusion",InitApp:"Server startup",LOCK:"Account",MODALITY:"Input processing",NetworkMonitor:"Network monitor",PASSTHROUGH:"Provider passthrough",ProjectId:"Project setup",PROTOBUF:"Data encoding",ProxyFetch:"Proxy connection",RESPONSE:"Provider",RTK:"Token optimization",SSE:"Streaming",STREAM:"Streaming",TLS:"Secure connection",TOKEN:"Token refresh",TOKEN_REFRESH:"Token refresh",TOOLDEDUP:"Tool processing",Tunnel:"Cloudflare tunnel"},He={DEBUG:"Details",DONE:"Request",ERROR:"Error",FALLBACK:"Fallback",FETCH:"Provider",LOCK:"Account",REQUEST:"HTTP request",RESPONSE:"Provider",RETRY:"Retry",START:"Request",STREAM:"Streaming",WARN:"Warning"};function Ke(t){return t.replace(/\r\n/g,`
|
|
2
2
|
`).split(`
|
|
3
3
|
`).map(e=>e.replace(/[ \t]+/g," ").trim()).join(`
|
|
4
|
-
`).trim()}function O(t){if(!t.includes("@"))return t;const[e,r]=t.split("@",2);return!e||!r?t:`${e.slice(0,3)}…@${r}`}function u(t){const e=Number(t.replace(/,/g,""));return Number.isFinite(e)?e.toLocaleString("en-US"):t}function v(t){const e=Number(t.replace(/,/g,"").replace(/B$/i,""));return Number.isFinite(e)?e<1024?`${e} bytes`:e<1024*1024?`${(e/1024).toFixed(e<10*1024?1:0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`:t}function x(t){const e=Number(t.replace(/,/g,""));return Number.isFinite(e)?e>=1e3?`${(e/1e3).toFixed(2).replace(/\.00$/,"")}s`:`${e}ms`:t}function Ge(t,e){return e.toLowerCase().includes("account")||e.toLowerCase()==="acc"?O(t):/^(?:in|out|input|output|active|due|excluded|emitted|recvLines|chunks|messages|tools)$/i.test(e)?u(t):/^(?:body|bytes|size)$/i.test(e)&&/^\d+(?:B)?$/i.test(t)?v(t):/^(?:dur|duration|ttft|connectTimeout|stallTimeout)$/i.test(e)&&/^(?:\d+)(?:ms)?$/i.test(t)?x(t.replace(/ms$/i,"")):t}function ue(t){return t.replace(new RegExp("(?<![?&/:])\\b([A-Za-z][A-Za-z0-9_-]*)=([^ |·,]+)(?=\\s*(?:\\||·|,|$))","g"),(e,r,n)=>`${r}: ${Ge(n,r)}`)}function b(t){return t.split(/\s+·\s+|\s*\|\s*/).map(e=>e.trim()).filter(Boolean).map(e=>{if(/^FMT:\s*/i.test(e))return e.replace(/^FMT:\s*/i,"Format: ").replace(/→/g," → ");if(/^THINK:/i.test(e))return e.replace(/^THINK:/i,"Reasoning: ");if(/^ACC:/i.test(e))return`Account: ${O(e.replace(/^ACC:/i,"").trim())}`;if(/^(?:STREAM|stream)$/i.test(e))return"Streaming response";if(/^JSON$/i.test(e))return"JSON response";const r=e.match(/^(\d+)\s+MSG$/i);if(r)return`${u(r[1])} messages`;const n=e.match(/^(\d+)\s+TOOL$/i);if(n)return`${u(n[1])} tools`;if(/^attempt=/i.test(e))return e.replace(/^attempt=/i,"Attempt: ");if(/^reason=/i.test(e)){const l=e.replace(/^reason=/i,"").trim();return`Reason: ${l==="initial"?"initial request":l}`}if(/^TTFT\s+\d+ms$/i.test(e))return e.replace(/^TTFT\s+/i,"First token: ").replace(/^(First token:\s*)(\d+)ms$/i,(l,g,S)=>`${g}${x(S)}`);const a=e.match(/^IN\s+(\d+)$/i);if(a)return`Input tokens: ${u(a[1])}`;const c=e.match(/^OUT\s+(\d+)$/i);return c?`Output tokens: ${u(c[1])}`:/^\d+ms$/i.test(e)?`Duration: ${x(e.slice(0,-2))}`:ue(e).replace(/\bttft:/gi,"First token:").replace(/\bct:/gi,"Content type:").replace(/\bcl:/gi,"Content length:").replace(/\bdur:/gi,"Duration:").replace(/\bchunks:/gi,"Chunks:").replace(/\bbytes:/gi,"Bytes:").replace(/\bstallTimeout:/gi,"Stall timeout:").replace(/\bconnectTimeout:/gi,"Connection timeout:")}).join(" · ")}function X(t){var l,g,S;const e=t.match(/^POST\s+(.+?)\s+→\s+(.+?)(?:\s+·\s+([\s\S]+))?$/i);if(!e)return b(t);const a=`${((S=(g=(l=e[3])==null?void 0:l.match(/\b(?:STREAM|JSON)\b/i))==null?void 0:g[0])==null?void 0:S.toLowerCase())==="stream"?"Sent streaming request":"Sent request"}: ${e[1]} → ${e[2]}`,c=e[3]?b(e[3]):"";return c?`${a} · ${c}`:a}function qe(t){const e=t.match(/^([A-Z0-9_-]+)\s+→\s+([^·|]+)(?:\s+(?:·|\|)\s+([\s\S]+))?$/i);if(!e)return b(t);const r=e[3]?b(e[3]):"";return`Connecting to ${e[1]} at ${e[2].trim()}${r?` · ${r}`:""}`}function ze(t){const e=t.match(/^([A-Z0-9_-]+)\s+(\d{3})(?:\s+·\s+([\s\S]+))?$/i);if(!e)return b(t);const r=e[3]?b(e[3]):"";return`Provider response: ${e[1]} returned ${e[2]}${r?` · ${r}`:""}`}function We(t){const e=t.split(/\s+·\s+/).map(a=>a.trim()).filter(Boolean);if(!e.length||!/^\d+ms$/i.test(e[0]))return b(t);const[r,...n]=e;return`Request completed in ${x(r.slice(0,-2))}${n.length?` · ${b(n.join(" · "))}`:""}`}function de(t){const e=t.match(/^A4\.[34](?:\s+)?(?:·\s+)?(.+)$/i);return e?`Compatibility retry · ${e[1].replace(/^pre-content\s+/i,"before response content: ").replace(/\bauth-error\b/gi,"provider authentication failed").replace(/socket close/gi,"connection closed").replace(/^reactive refresh\s*/i,"refreshing provider credentials: ").replace(/^without\s+/i,"without unsupported field ").replace(/socket retry succeeded/i,"connection retry succeeded").replace(/retry succeeded/i,"retry succeeded")}`:/^TOKEN REFRESHED/i.test(t)?t.replace(/^TOKEN REFRESHED/i,"Provider credentials refreshed"):/^pre-stripped\s+\(cached\)/i.test(t)?t.replace(/^pre-stripped\s+\(cached\)\s*/i,"Compatibility settings applied · removed ").replace(/:\s*/," fields: "):/^retry after strip/i.test(t)?t.replace(/^retry after strip/i,"Compatibility retry failed after removing"):/^preview failed/i.test(t)?t.replace(/^preview failed/i,"Response preview failed").replace(/\s*\(non-fatal\)/i,""):/^FALLBACK/i.test(t)?b(t.replace(/^FALLBACK\s*/i,"")):b(t)}function Ve(t){const e=t.match(/^⇄\s*ACC:([^\s]+)\s+UNAVAILABLE\s+\((\d{3})\)\s+→\s+NEXT ACCOUNT/i);return e?`Account ${O(e[1])} is unavailable (${e[2]}); trying the next account`:de(t)}function Ze(t){let e=t.match(/^([^|]+)\|\s*total connections:\s*(\d+),\s*(?:excludeIds|excluded accounts):\s*([^,]+),\s*model:\s*(.+)$/i);return e?`${e[1].trim()} has ${u(e[2])} accounts · excluded: ${e[3].trim()} · model: ${e[4].trim()}`:(e=t.match(/^([^|]+)\|\s*available:\s*(\d+)\/(\d+)$/i),e?`${e[1].trim()} account availability: ${u(e[2])} of ${u(e[3])}`:(e=t.match(/^([^|]+)\|\s*pinned to\s+([^\s]+)\s+\(([^)]+)\)/i),e?`${e[1].trim()} is using account ${e[3]} (${e[2]})`:(e=t.match(/^([^|]+)\|\s*cache-affine\(([^)]+)\)\s+→\s+(.+)$/i),e?`${e[1].trim()} selected a sticky account (${e[2]}) · ${e[3]}`:(e=t.match(/^([^|]+)\|\s*all\s+(\d+)\s+accounts locked for\s+(.+?)\s+\(([^)]+)\)/i),e?`${e[1].trim()}: all ${u(e[2])} accounts are locked for ${e[3]} · available ${e[4]}`:(e=t.match(/^([^|]+)\|\s*account pool busy\s+\((\d+) candidates,\s*queue=(\d+)\)/i),e?`${e[1].trim()}: account pool is busy · ${u(e[2])} candidates · queue limit ${u(e[3])}`:/^No credentials for/i.test(t)?t.replace(/^No credentials for/i,"No credentials are configured for"):/^No active credentials for provider:/i.test(t)?t.replace(/^No active credentials for provider:/i,"No active credentials are available for provider:"):P(t))))))}function ee(t){let e=t.match(/^flush\s*·\s*provider=([^·]+)\s*·\s*model=([^·]+)\s*·\s*recvLines=(\d+)\s*·\s*emitted=(\d+)\s*·\s*events=\[([^\]]*)\]/i);return e?`Stream summary: ${e[1].trim()} · model ${e[2].trim()} · received ${u(e[3])} lines · emitted ${u(e[4])} events · events: ${e[5]||"none"}`:(e=t.match(/^pipe start\s*·\s*stallTimeout=(\d+)ms/i),e?`Stream started · stall timeout: ${x(e[1])}`:(e=t.match(/^chunk\s+#(\d+)\s*·\s*size=(\d+)B\s*·\s*gap=(\d+)ms\s*·\s*total=(\d+)B/i),e?`Received stream chunk ${e[1]} · ${v(e[2])} · ${x(e[3])} since previous · ${v(e[4])} total`:(e=t.match(/^upstream EOF\s*·\s*chunks=(\d+)\s*·\s*bytes=(\d+)\s*·\s*dur=(\d+)ms/i),e?`Provider stream ended · ${u(e[1])} chunks · ${v(e[2])} · ${x(e[3])}`:(e=t.match(/^STALL TIMEOUT\s+(\d+)ms\s+\|\s+chunks=(\d+)\s+\|\s+bytes=(\d+)\s+\|\s+sinceLast=(\d+)ms/i),e?`Stream stalled for ${x(e[4])} · timeout ${x(e[1])} · ${u(e[2])} chunks · ${v(e[3])}`:(e=t.match(/^(complete|error|disconnect)(?::\s*)?(.+)$/i),e?`Stream ${e[1].toLowerCase()}: ${b(e[2])}`:b(t))))))}function Ye(t){const e=t.match(/^TRANSFORM\s*·\s*(.*)$/i);return e?`Token optimization applied · ${e[1].split(/\s+·\s+/).map(n=>n.replace(/^CAVEMAN:/i,"Caveman prompt: ").replace(/^PONYTAIL:/i,"Ponytail prompt: ")).join(" · ")}`:b(t)}function P(t){return ue(t).replace(/^RESPONSE_ERROR\s+(\d{3})/i,"Provider response failed with status $1").replace(/^REQUEST\s+/i,"Received request ").replace(/\bFMT:/gi,"Format:").replace(/\bTHINK:/gi,"Reasoning:").replace(/\bACC:/gi,"Account:").replace(/\bTTFT\s+(\d+)ms/gi,(e,r)=>`First token: ${x(r)}`).replace(/\bIN\s+(\d+)\b/gi,(e,r)=>`Input tokens: ${u(r)}`).replace(/\bOUT\s+(\d+)\b/gi,(e,r)=>`Output tokens: ${u(r)}`).replace(/\bCAVEMAN:/gi,"Caveman prompt:").replace(/\bPONYTAIL:/gi,"Ponytail prompt:").replace(/\bSSE overloaded\b/gi,"Provider temporarily overloaded").replace(/\b(?:cache-affine|cache affinity)\b/gi,"sticky cache routing").replace(/\bmodelLocked\b/gi,"model temporarily locked").replace(/\bexcludeIds\b/gi,"excluded accounts").replace(/\binputItems\b/gi,"input items").replace(/\bprefetchImages\b/gi,"image preparation").replace(/\bstraggler\/timeout\b/gi,"slow or timed-out response").replace(/\bpanel=/gi,"panel: ").replace(/\bjudge=/gi,"reviewer: ").replace(/\bquorum=/gi,"minimum responses: ").replace(/\bsticky=/gi,"sticky limit: ").replace(/\bstrategy:/gi,"routing strategy:").replace(/\bfan-out collected\b/gi,"parallel model responses collected").replace(/\breturned empty content\b/gi,"returned an empty response").replace(/\bpanicked\b/gi,"failed").replace(/\bSTREAM\b/gi,"Streaming response").replace(/\b(\d+)\s+MSG\b/gi,(e,r)=>`${u(r)} messages`).replace(/\b(\d+)\s+TOOL\b/gi,(e,r)=>`${u(r)} tools`).replace(/\s{2,}/g," ").replace(/(Account:\s+)([^\s·|]+@[^\s·|]+)/gi,(e,r,n)=>`${r}${O(n)}`).trim()}function te(t,e={}){var l,g;const r=Ke(t);if(!r)return"";const n=((l=e.label)==null?void 0:l.toUpperCase())||"",a=((g=e.source)==null?void 0:g.toUpperCase())||"";if(n==="START")return X(r);if(n==="FETCH"||a==="FETCH")return qe(r);if(n==="RESPONSE"||a==="RESPONSE")return ze(r);if(n==="DONE")return We(r);if(n==="REQUEST")return P(r);const c=a.replace(/\./g,"_");return n==="RETRY"||c==="A4_3"||c==="A4_4"?de(r):n==="FALLBACK"||a==="FALLBACK"?Ve(r):a==="AUTH"?Ze(r):n==="STREAM"||a==="SSE"||a==="STREAM"||a==="CTRL"?ee(r):/^POST\s+/i.test(r)?X(r):/^TRANSFORM\s*·/i.test(r)?Ye(r):/^(?:flush|pipe start|chunk\s+#|upstream EOF|STALL TIMEOUT|complete|error|disconnect)/i.test(r)?ee(r):P(r)}function Je(t){const e=t.trim();return e?He[e.toUpperCase()]||Q[e]||Q[e.toUpperCase().replace(/\./g,"_")]||e.replace(/[_:-]+/g," ").replace(/\b\w/g,r=>r.toUpperCase()):"Runtime"}const re=1e3,pe=["LOG","INFO","SUCCESS","WARN","ERROR","DEBUG"],Qe=/^\s*\[([A-Za-z]+)\]/,Xe=/^\s*([A-Za-z]+)\b/,se=/(?:\bERROR\b|\b(?:Reference|Type|Syntax|Range|URI)Error\b|\b(?:Error|Exception):|\bstatus\s*[=:]\s*5\d\d\b|\bHTTP\s+5\d\d\b)/i,et=/(?:\bWARN(?:ING)?\b|\bstatus\s*[=:]\s*4\d\d\b|\bHTTP\s+4\d\d\b)/i,tt=/(?:\b(?:HTTP\s*)?2\d\d\b|\bstatus\s*[=:]\s*2\d\d\b|\b(?:OK|SUCCESS|PASSED|HEALTHY)\b)/i,rt=/[\p{Emoji_Presentation}\p{Extended_Pictographic}�️]/gu,st=/(?:[A-Za-z]:[\\/]|\/)[^|]*?\.swayrouter[\\/]+db[\\/]+data\.sqlite/gi,nt=/^(?:(\w[\w-]*)\s+)?(START|FETCH|RESPONSE|RETRY|DONE|WARN|ERROR|FALLBACK|LOCK|REQUEST|STREAM)\s+([\s\S]+)$/i,it=/^(?:(\w[\w-]*)\s+)?DEBUG\s+([A-Z][A-Z0-9_-]*)\s*(?:·\s*)?([\s\S]*)$/i;function me(t){return t.split(/\r?\n/).map(e=>e.replace(/[ \t]+/g," ").trimEnd()).filter((e,r,n)=>e.length>0||r<n.length-1).join(`
|
|
5
|
-
`).trim()}function ne(t){return
|
|
6
|
-
`);try{await navigator.clipboard.writeText(i),H(!0),C.current&&clearTimeout(C.current),C.current=setTimeout(()=>H(!1),1600)}catch(o){
|
|
4
|
+
`).trim()}function O(t){if(!t.includes("@"))return t;const[e,r]=t.split("@",2);return!e||!r?t:`${e.slice(0,3)}…@${r}`}function u(t){const e=Number(t.replace(/,/g,""));return Number.isFinite(e)?e.toLocaleString("en-US"):t}function v(t){const e=Number(t.replace(/,/g,"").replace(/B$/i,""));return Number.isFinite(e)?e<1024?`${e} bytes`:e<1024*1024?`${(e/1024).toFixed(e<10*1024?1:0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`:t}function R(t){const e=Number(t.replace(/,/g,""));return Number.isFinite(e)?e>=1e3?`${(e/1e3).toFixed(2).replace(/\.00$/,"")}s`:`${e}ms`:t}function Ge(t,e){return e.toLowerCase().includes("account")||e.toLowerCase()==="acc"?O(t):/^(?:in|out|input|output|active|due|excluded|emitted|recvLines|chunks|messages|tools)$/i.test(e)?u(t):/^(?:body|bytes|size)$/i.test(e)&&/^\d+(?:B)?$/i.test(t)?v(t):/^(?:dur|duration|ttft|connectTimeout|stallTimeout)$/i.test(e)&&/^(?:\d+)(?:ms)?$/i.test(t)?R(t.replace(/ms$/i,"")):t}function ue(t){return t.replace(new RegExp("(?<![?&/:])\\b([A-Za-z][A-Za-z0-9_-]*)=([^ |·,]+)(?=\\s*(?:\\||·|,|$))","g"),(e,r,n)=>`${r}: ${Ge(n,r)}`)}function b(t){return t.split(/\s+·\s+|\s*\|\s*/).map(e=>e.trim()).filter(Boolean).map(e=>{if(/^FMT:\s*/i.test(e))return e.replace(/^FMT:\s*/i,"Format: ").replace(/→/g," → ");if(/^THINK:/i.test(e))return e.replace(/^THINK:/i,"Reasoning: ");if(/^ACC:/i.test(e))return`Account: ${O(e.replace(/^ACC:/i,"").trim())}`;if(/^(?:STREAM|stream)$/i.test(e))return"Streaming response";if(/^JSON$/i.test(e))return"JSON response";const r=e.match(/^(\d+)\s+MSG$/i);if(r)return`${u(r[1])} messages`;const n=e.match(/^(\d+)\s+TOOL$/i);if(n)return`${u(n[1])} tools`;if(/^attempt=/i.test(e))return e.replace(/^attempt=/i,"Attempt: ");if(/^reason=/i.test(e)){const l=e.replace(/^reason=/i,"").trim();return`Reason: ${l==="initial"?"initial request":l}`}if(/^TTFT\s+\d+ms$/i.test(e))return e.replace(/^TTFT\s+/i,"First token: ").replace(/^(First token:\s*)(\d+)ms$/i,(l,g,S)=>`${g}${R(S)}`);const a=e.match(/^IN\s+(\d+)$/i);if(a)return`Input tokens: ${u(a[1])}`;const c=e.match(/^OUT\s+(\d+)$/i);return c?`Output tokens: ${u(c[1])}`:/^\d+ms$/i.test(e)?`Duration: ${R(e.slice(0,-2))}`:ue(e).replace(/\bttft:/gi,"First token:").replace(/\bct:/gi,"Content type:").replace(/\bcl:/gi,"Content length:").replace(/\bdur:/gi,"Duration:").replace(/\bchunks:/gi,"Chunks:").replace(/\bbytes:/gi,"Bytes:").replace(/\bstallTimeout:/gi,"Stall timeout:").replace(/\bconnectTimeout:/gi,"Connection timeout:")}).join(" · ")}function X(t){var l,g,S;const e=t.match(/^POST\s+(.+?)\s+→\s+(.+?)(?:\s+·\s+([\s\S]+))?$/i);if(!e)return b(t);const a=`${((S=(g=(l=e[3])==null?void 0:l.match(/\b(?:STREAM|JSON)\b/i))==null?void 0:g[0])==null?void 0:S.toLowerCase())==="stream"?"Sent streaming request":"Sent request"}: ${e[1]} → ${e[2]}`,c=e[3]?b(e[3]):"";return c?`${a} · ${c}`:a}function qe(t){const e=t.match(/^([A-Z0-9_-]+)\s+→\s+([^·|]+)(?:\s+(?:·|\|)\s+([\s\S]+))?$/i);if(!e)return b(t);const r=e[3]?b(e[3]):"";return`Connecting to ${e[1]} at ${e[2].trim()}${r?` · ${r}`:""}`}function ze(t){const e=t.match(/^([A-Z0-9_-]+)\s+(\d{3})(?:\s+·\s+([\s\S]+))?$/i);if(!e)return b(t);const r=e[3]?b(e[3]):"";return`Provider response: ${e[1]} returned ${e[2]}${r?` · ${r}`:""}`}function We(t){const e=t.split(/\s+·\s+/).map(a=>a.trim()).filter(Boolean);if(!e.length||!/^\d+ms$/i.test(e[0]))return b(t);const[r,...n]=e;return`Request completed in ${R(r.slice(0,-2))}${n.length?` · ${b(n.join(" · "))}`:""}`}function de(t){const e=t.match(/^A4\.[34](?:\s+)?(?:·\s+)?(.+)$/i);return e?`Compatibility retry · ${e[1].replace(/^pre-content\s+/i,"before response content: ").replace(/\bauth-error\b/gi,"provider authentication failed").replace(/socket close/gi,"connection closed").replace(/^reactive refresh\s*/i,"refreshing provider credentials: ").replace(/^without\s+/i,"without unsupported field ").replace(/socket retry succeeded/i,"connection retry succeeded").replace(/retry succeeded/i,"retry succeeded")}`:/^TOKEN REFRESHED/i.test(t)?t.replace(/^TOKEN REFRESHED/i,"Provider credentials refreshed"):/^pre-stripped\s+\(cached\)/i.test(t)?t.replace(/^pre-stripped\s+\(cached\)\s*/i,"Compatibility settings applied · removed ").replace(/:\s*/," fields: "):/^retry after strip/i.test(t)?t.replace(/^retry after strip/i,"Compatibility retry failed after removing"):/^preview failed/i.test(t)?t.replace(/^preview failed/i,"Response preview failed").replace(/\s*\(non-fatal\)/i,""):/^FALLBACK/i.test(t)?b(t.replace(/^FALLBACK\s*/i,"")):b(t)}function Ve(t){const e=t.match(/^⇄\s*ACC:([^\s]+)\s+UNAVAILABLE\s+\((\d{3})\)\s+→\s+NEXT ACCOUNT/i);return e?`Account ${O(e[1])} is unavailable (${e[2]}); trying the next account`:de(t)}function Ze(t){let e=t.match(/^([^|]+)\|\s*total connections:\s*(\d+),\s*(?:excludeIds|excluded accounts):\s*([^,]+),\s*model:\s*(.+)$/i);return e?`${e[1].trim()} has ${u(e[2])} accounts · excluded: ${e[3].trim()} · model: ${e[4].trim()}`:(e=t.match(/^([^|]+)\|\s*available:\s*(\d+)\/(\d+)$/i),e?`${e[1].trim()} account availability: ${u(e[2])} of ${u(e[3])}`:(e=t.match(/^([^|]+)\|\s*pinned to\s+([^\s]+)\s+\(([^)]+)\)/i),e?`${e[1].trim()} is using account ${e[3]} (${e[2]})`:(e=t.match(/^([^|]+)\|\s*cache-affine\(([^)]+)\)\s+→\s+(.+)$/i),e?`${e[1].trim()} selected a sticky account (${e[2]}) · ${e[3]}`:(e=t.match(/^([^|]+)\|\s*all\s+(\d+)\s+accounts locked for\s+(.+?)\s+\(([^)]+)\)/i),e?`${e[1].trim()}: all ${u(e[2])} accounts are locked for ${e[3]} · available ${e[4]}`:(e=t.match(/^([^|]+)\|\s*account pool busy\s+\((\d+) candidates,\s*queue=(\d+)\)/i),e?`${e[1].trim()}: account pool is busy · ${u(e[2])} candidates · queue limit ${u(e[3])}`:/^No credentials for/i.test(t)?t.replace(/^No credentials for/i,"No credentials are configured for"):/^No active credentials for provider:/i.test(t)?t.replace(/^No active credentials for provider:/i,"No active credentials are available for provider:"):P(t))))))}function ee(t){let e=t.match(/^flush\s*·\s*provider=([^·]+)\s*·\s*model=([^·]+)\s*·\s*recvLines=(\d+)\s*·\s*emitted=(\d+)\s*·\s*events=\[([^\]]*)\]/i);return e?`Stream summary: ${e[1].trim()} · model ${e[2].trim()} · received ${u(e[3])} lines · emitted ${u(e[4])} events · events: ${e[5]||"none"}`:(e=t.match(/^pipe start\s*·\s*stallTimeout=(\d+)ms/i),e?`Stream started · stall timeout: ${R(e[1])}`:(e=t.match(/^chunk\s+#(\d+)\s*·\s*size=(\d+)B\s*·\s*gap=(\d+)ms\s*·\s*total=(\d+)B/i),e?`Received stream chunk ${e[1]} · ${v(e[2])} · ${R(e[3])} since previous · ${v(e[4])} total`:(e=t.match(/^upstream EOF\s*·\s*chunks=(\d+)\s*·\s*bytes=(\d+)\s*·\s*dur=(\d+)ms/i),e?`Provider stream ended · ${u(e[1])} chunks · ${v(e[2])} · ${R(e[3])}`:(e=t.match(/^STALL TIMEOUT\s+(\d+)ms\s+\|\s+chunks=(\d+)\s+\|\s+bytes=(\d+)\s+\|\s+sinceLast=(\d+)ms/i),e?`Stream stalled for ${R(e[4])} · timeout ${R(e[1])} · ${u(e[2])} chunks · ${v(e[3])}`:(e=t.match(/^(complete|error|disconnect)(?::\s*)?(.+)$/i),e?`Stream ${e[1].toLowerCase()}: ${b(e[2])}`:b(t))))))}function Ye(t){const e=t.match(/^TRANSFORM\s*·\s*(.*)$/i);return e?`Token optimization applied · ${e[1].split(/\s+·\s+/).map(n=>n.replace(/^CAVEMAN:/i,"Caveman prompt: ").replace(/^PONYTAIL:/i,"Ponytail prompt: ")).join(" · ")}`:b(t)}function P(t){return ue(t).replace(/^RESPONSE_ERROR\s+(\d{3})/i,"Provider response failed with status $1").replace(/^REQUEST\s+/i,"Received request ").replace(/\bFMT:/gi,"Format:").replace(/\bTHINK:/gi,"Reasoning:").replace(/\bACC:/gi,"Account:").replace(/\bTTFT\s+(\d+)ms/gi,(e,r)=>`First token: ${R(r)}`).replace(/\bIN\s+(\d+)\b/gi,(e,r)=>`Input tokens: ${u(r)}`).replace(/\bOUT\s+(\d+)\b/gi,(e,r)=>`Output tokens: ${u(r)}`).replace(/\bCAVEMAN:/gi,"Caveman prompt:").replace(/\bPONYTAIL:/gi,"Ponytail prompt:").replace(/\bSSE overloaded\b/gi,"Provider temporarily overloaded").replace(/\b(?:cache-affine|cache affinity)\b/gi,"sticky cache routing").replace(/\bmodelLocked\b/gi,"model temporarily locked").replace(/\bexcludeIds\b/gi,"excluded accounts").replace(/\binputItems\b/gi,"input items").replace(/\bprefetchImages\b/gi,"image preparation").replace(/\bstraggler\/timeout\b/gi,"slow or timed-out response").replace(/\bpanel=/gi,"panel: ").replace(/\bjudge=/gi,"reviewer: ").replace(/\bquorum=/gi,"minimum responses: ").replace(/\bsticky=/gi,"sticky limit: ").replace(/\bstrategy:/gi,"routing strategy:").replace(/\bfan-out collected\b/gi,"parallel model responses collected").replace(/\breturned empty content\b/gi,"returned an empty response").replace(/\bpanicked\b/gi,"failed").replace(/\bSTREAM\b/gi,"Streaming response").replace(/\b(\d+)\s+MSG\b/gi,(e,r)=>`${u(r)} messages`).replace(/\b(\d+)\s+TOOL\b/gi,(e,r)=>`${u(r)} tools`).replace(/\s{2,}/g," ").replace(/(Account:\s+)([^\s·|]+@[^\s·|]+)/gi,(e,r,n)=>`${r}${O(n)}`).trim()}function te(t,e={}){var l,g;const r=Ke(t);if(!r)return"";const n=((l=e.label)==null?void 0:l.toUpperCase())||"",a=((g=e.source)==null?void 0:g.toUpperCase())||"";if(n==="START")return X(r);if(n==="FETCH"||a==="FETCH")return qe(r);if(n==="RESPONSE"||a==="RESPONSE")return ze(r);if(n==="DONE")return We(r);if(n==="REQUEST")return P(r);const c=a.replace(/\./g,"_");return n==="RETRY"||c==="A4_3"||c==="A4_4"?de(r):n==="FALLBACK"||a==="FALLBACK"?Ve(r):a==="AUTH"?Ze(r):n==="STREAM"||a==="SSE"||a==="STREAM"||a==="CTRL"?ee(r):/^POST\s+/i.test(r)?X(r):/^TRANSFORM\s*·/i.test(r)?Ye(r):/^(?:flush|pipe start|chunk\s+#|upstream EOF|STALL TIMEOUT|complete|error|disconnect)/i.test(r)?ee(r):P(r)}function Je(t){const e=t.trim();return e?He[e.toUpperCase()]||Q[e]||Q[e.toUpperCase().replace(/\./g,"_")]||e.replace(/[_:-]+/g," ").replace(/\b\w/g,r=>r.toUpperCase()):"Runtime"}const re=1e3,me=["LOG","INFO","SUCCESS","WARN","ERROR","DEBUG"],Qe=/^\s*\[([A-Za-z]+)\]/,Xe=/^\s*([A-Za-z]+)\b/,se=/(?:\bERROR\b|\b(?:Reference|Type|Syntax|Range|URI)Error\b|\b(?:Error|Exception):|\bstatus\s*[=:]\s*5\d\d\b|\bHTTP\s+5\d\d\b)/i,et=/(?:\bWARN(?:ING)?\b|\bstatus\s*[=:]\s*4\d\d\b|\bHTTP\s+4\d\d\b)/i,tt=/(?:\b(?:HTTP\s*)?2\d\d\b|\bstatus\s*[=:]\s*2\d\d\b|\b(?:OK|SUCCESS|PASSED|HEALTHY)\b)/i,rt=/[\p{Emoji_Presentation}\p{Extended_Pictographic}�️]/gu,st=/(?:[A-Za-z]:[\\/]|\/)[^|]*?\.swayrouter[\\/]+db[\\/]+data\.sqlite/gi,nt=/^(?:(\w[\w-]*)\s+)?(START|FETCH|RESPONSE|RETRY|DONE|WARN|ERROR|FALLBACK|LOCK|REQUEST|STREAM)\s+([\s\S]+)$/i,it=/^(?:(\w[\w-]*)\s+)?DEBUG\s+([A-Z][A-Z0-9_-]*)\s*(?:·\s*)?([\s\S]*)$/i;function pe(t){return t.split(/\r?\n/).map(e=>e.replace(/[ \t]+/g," ").trimEnd()).filter((e,r,n)=>e.length>0||r<n.length-1).join(`
|
|
5
|
+
`).trim()}function ne(t){return pe(t.replace(rt,"").replace(st,".swayrouter\\db\\data.sqlite").replace(/^\s*\[\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?\]\s*/,""))}function L(t){const e=t.match(/^\s*\[(?:LOG|INFO|WARN|ERROR|DEBUG)\]\s*/i);if(e)return t.slice(e[0].length);const r=t.match(/^\s*(?:LOG|INFO|WARN|ERROR|DEBUG)\b\s*/i);return r?t.slice(r[0].length):t}function U(t){const e=L(t).trim(),r=e.match(it);if(r)return{tag:r[1]??null,label:r[2].toUpperCase(),message:r[3].trim()};const n=e.match(nt);return n?{tag:n[1]??null,label:n[2].toUpperCase(),message:n[3]}:null}function ie(t){const e=pe(t),r=e.match(/^(.*?)(?:\s+)(\{[\s\S]*\})$/);if(!r)return e;try{const n=JSON.parse(r[2]);if(!n||typeof n!="object"||Array.isArray(n))return e;const a=Object.entries(n).map(([c,l])=>{if(typeof l=="string")return`${c}=${l}`;if(l===null)return`${c}=null`;try{return`${c}=${JSON.stringify(l)}`}catch{return`${c}=${String(l)}`}});return a.length?`${r[1].trim()} · ${a.join(" · ")}`:r[1].trim()}catch{return e}}function oe(t){var c;const e=U(t);if(se.test(t))return"ERROR";if(tt.test(t)||(e==null?void 0:e.label)==="DONE")return"SUCCESS";const r=t.match(Qe),a=(r?r[1]:((c=t.match(Xe))==null?void 0:c[1])??"").toUpperCase();return me.includes(a)?a:/^(?:\w[\w-]*\s+)?DEBUG\b/i.test(L(t).trim())?"DEBUG":e?e.label==="ERROR"?"ERROR":["WARN","RETRY","FALLBACK"].includes(e.label)?"WARN":"INFO":se.test(t)?"ERROR":et.test(t)?"WARN":"LOG"}function ot(t){var n;const e=U(t);if(e)return e.label;const r=(n=L(t).match(/^\s*(?:\[([^\]]+)\]\s*)+/))==null?void 0:n[1];return r?r.trim().slice(0,32):"runtime"}function at(t){return Je(t)}function ct(t){var c;const e=U(t);if(e)return te(ie(e.message),{label:e.label,source:e.label});const r=L(t),n=((c=r.match(/^\s*(?:\[([^\]]+)\]\s*)+/))==null?void 0:c[1])||"",a=r.replace(/^\s*(?:\[[^\]]+\]\s*)+/,"");return te(ie(a),{source:n})}function M(t){return t.length>re?t.slice(-re):t}function lt(t){const e=Date.now();return t.map(r=>({line:r,ts:e}))}function ae(t){const e=Date.now();return t.filter(r=>typeof(r==null?void 0:r.line)=="string").map(r=>({line:r.line,ts:r.ts>0&&Number.isFinite(r.ts)?r.ts:e}))}function ce(t){const e=new Date(t),r=n=>String(n).padStart(2,"0");return`${r(e.getHours())}:${r(e.getMinutes())}:${r(e.getSeconds())}`}function fe(t){switch(t){case"SUCCESS":return"bg-success";case"ERROR":return"bg-destructive";case"WARN":return"bg-warning";case"INFO":return"bg-info";case"DEBUG":return"bg-debug";default:return"bg-muted-foreground/55"}}function ut(t){switch(t){case"SUCCESS":return"success";case"ERROR":return"error";case"WARN":return"warning";case"INFO":return"info";case"DEBUG":return"debug";default:return"outline"}}function le({label:t,value:e,count:r,active:n,onClick:a}){const c=e==="all"?null:e;return s.jsxs("button",{type:"button","aria-pressed":n,onClick:()=>a(e),className:x("inline-flex shrink-0 items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs transition-colors",n?"border-border bg-white/[0.08] text-foreground":"border-transparent text-muted-foreground hover:border-border/70 hover:bg-white/[0.04] hover:text-foreground"),children:[s.jsx("span",{"aria-hidden":"true",className:x("size-1.5 rounded-full",c?fe(c):"bg-foreground/80")}),s.jsx("span",{children:t}),s.jsx("span",{className:"tabular-nums text-[11px] text-muted-foreground",children:r})]})}function St(){const[t,e]=d.useState(!1),[r,n]=d.useState(!1),[a,c]=d.useState(!1),[l,g]=d.useState([]),[S,he]=d.useState(""),[T,B]=d.useState("all"),[N,ge]=d.useState(!0),[I,be]=d.useState(!0),[j,H]=d.useState(!1),F=d.useRef(null),C=d.useRef(null),K=d.useDeferredValue(S);d.useEffect(()=>{let i=!1,o=null,m=null,p=null,f=1e3,$=0;const q=25e3*2+5e3,D=()=>{p&&clearTimeout(p),p=null},z=()=>{if(i||m)return;const E=Math.floor(Math.random()*Math.min(500,f/2));m=setTimeout(()=>{m=null,W()},f+E),f=Math.min(f*2,1e4)},w=()=>{D(),p=setTimeout(()=>{if(!(i||!o)){if(Date.now()-$<q){w();return}o.close(),o=null,e(!1),z()}},q)},W=()=>{if(i||o)return;const E=new EventSource("/api/translator/console-logs/stream");o=E,$=Date.now(),w(),E.onopen=()=>{i||o!==E||(f=1e3,$=Date.now(),e(!0),w())},E.onerror=()=>{o===E&&(D(),e(!1),E.close(),o=null,z())},E.onmessage=Se=>{if(i||o!==E)return;$=Date.now(),w();let h;try{h=JSON.parse(Se.data)}catch{return}if(h.type==="init")g(M(ae(h.entries)));else if(h.type==="line")g(_=>M([..._,{line:h.line,ts:typeof h.ts=="number"&&Number.isFinite(h.ts)?h.ts:Date.now()}]));else if(h.type==="lines"){const _=Array.isArray(h.lines)&&typeof h.lines[0]=="object"?ae(h.lines):lt(h.lines);g($e=>M([...$e,..._]))}else h.type==="clear"&&g([])}};return W(),()=>{i=!0,m&&clearTimeout(m),m=null,D(),o==null||o.close(),o=null}},[]),d.useEffect(()=>{const i=F.current;if(!i)return;const o=()=>{const m=i.scrollHeight-i.scrollTop-i.clientHeight;be(m<28)};return i.addEventListener("scroll",o,{passive:!0}),o(),()=>i.removeEventListener("scroll",o)},[]),d.useEffect(()=>{if(!I)return;const i=F.current;i&&(i.scrollTop=i.scrollHeight)},[l,I]),d.useEffect(()=>()=>{C.current&&clearTimeout(C.current)},[]);async function xe(){c(!1),n(!0);try{await Fe.delete("/translator/console-logs"),g([]),k.success("Console logs cleared")}catch(i){k.error(Z(i,"Clear failed"))}finally{n(!1)}}const Ee=d.useMemo(()=>{const i={LOG:0,INFO:0,SUCCESS:0,WARN:0,ERROR:0,DEBUG:0};for(const o of l)i[oe(ne(o.line))]+=1;return i},[l]),A=d.useMemo(()=>{const i=K.trim().toLowerCase();return l.map(({line:o,ts:m},p)=>{const f=ne(o);return{raw:f,message:ct(f),source:at(ot(f)),level:oe(f),ts:m,index:p}}).filter(({level:o})=>T==="all"||T===o).filter(({raw:o,message:m,source:p})=>!i||`${o} ${m} ${p}`.toLowerCase().includes(i))},[T,K,l]);async function Re(){const i=A.map(({message:o,source:m,level:p,ts:f})=>`${ce(f)} ${p} ${m} — ${o}`).join(`
|
|
6
|
+
`);try{await navigator.clipboard.writeText(i),H(!0),C.current&&clearTimeout(C.current),C.current=setTimeout(()=>H(!1),1600)}catch(o){k.error(Z(o,"Copy failed"))}}const G=A.length;return s.jsxs("div",{className:"flex min-h-full min-w-0 max-w-full flex-col gap-4 overflow-x-hidden lg:h-full",children:[s.jsx(Te,{title:"Console Logs",actions:s.jsxs(y,{size:"sm",variant:"outline",onClick:()=>c(!0),disabled:r,children:[s.jsx(ke,{className:"h-3.5 w-3.5"}),r?"Clearing…":"Clear"]})}),s.jsxs(De,{className:"flex min-h-[24rem] min-w-0 flex-1 flex-col overflow-hidden",children:[s.jsx(_e,{className:"shrink-0 gap-3 border-b border-border px-3 py-3 sm:px-4",children:s.jsxs("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(Ie,{status:t?"active":"down",pulse:t}),s.jsx("span",{className:x("text-xs font-medium",t?"text-emerald-400":"text-destructive"),children:t?"Live":"Reconnecting"}),s.jsxs("span",{className:"text-xs text-muted-foreground",children:[l.length.toLocaleString()," ",l.length===1?"event":"events"]}),G!==l.length?s.jsxs("span",{className:"text-xs text-muted-foreground/70",children:[G.toLocaleString()," shown"]}):null]}),s.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:[s.jsxs("div",{className:"relative min-w-0 flex-1 sm:w-56 sm:flex-none",children:[s.jsx(Me,{className:"pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground"}),s.jsx(Ne,{value:S,onChange:i=>he(i.target.value),placeholder:"Search logs","aria-label":"Search console logs",className:"h-8 w-full pl-8 text-xs"})]}),s.jsx(V,{label:N?"Long lines wrap":"Long lines scroll horizontally",children:s.jsx("button",{type:"button","aria-pressed":N,onClick:()=>ge(i=>!i),"aria-label":"Toggle line wrapping",className:x("inline-flex size-8 items-center justify-center rounded-md border transition-colors",N?"border-border bg-white/[0.08] text-foreground":"border-border text-muted-foreground hover:bg-white/[0.04] hover:text-foreground"),children:s.jsx(Pe,{className:"h-3.5 w-3.5"})})}),s.jsx(V,{label:j?"Copied":"Copy visible logs",children:s.jsxs(y,{size:"sm",variant:"outline",onClick:()=>void Re(),disabled:A.length===0,"aria-label":"Copy visible logs",children:[j?s.jsx(Ue,{className:"h-3.5 w-3.5"}):s.jsx(Be,{className:"h-3.5 w-3.5"}),s.jsx("span",{className:"hidden sm:inline",children:j?"Copied":"Copy"})]})})]})]})}),s.jsx(Y,{className:"shrink-0 border-b border-border p-2",children:s.jsxs("div",{className:"flex gap-1 overflow-x-auto",role:"group","aria-label":"Filter logs by level",children:[s.jsx(le,{label:"All",value:"all",count:l.length,active:T==="all",onClick:B}),me.map(i=>s.jsx(le,{label:i,value:i,count:Ee[i],active:T===i,onClick:B},i))]})}),s.jsx(Y,{className:"flex min-h-0 min-w-0 flex-1 p-0",children:s.jsx(Ce,{overscrollContain:!0,scrollFade:!0,scrollbarGutter:!0,viewportRef:F,className:"min-h-0 flex-1",children:s.jsx("div",{className:"font-mono text-xs leading-relaxed",children:A.length===0?s.jsx("div",{className:"flex min-h-[20rem] items-center justify-center px-6 text-center",children:s.jsxs("div",{children:[s.jsx("div",{className:"text-sm font-medium text-foreground",children:l.length===0?"No logs yet":"No matching logs"}),s.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:l.length===0?"New runtime logs will appear here.":"Try another level or search term."})]})}):s.jsx("div",{className:"divide-y divide-border/45",children:A.map(({raw:i,message:o,source:m,level:p,ts:f,index:$})=>s.jsxs("div",{className:x("grid min-w-0 grid-cols-[4rem_3.75rem_5rem_minmax(0,1fr)] items-start gap-x-2 px-3 py-2.5 transition-colors hover:bg-white/[0.035] sm:grid-cols-[4.5rem_4rem_6rem_minmax(0,1fr)] sm:gap-x-3 sm:px-4",p==="ERROR"&&"bg-destructive/[0.035]"),children:[s.jsx("span",{className:"pt-1 text-[10px] tabular-nums text-muted-foreground/70",children:ce(f)}),s.jsxs(Ae,{variant:ut(p),size:"sm",className:"w-fit font-sans",children:[s.jsx("span",{"aria-hidden":"true",className:x("mr-1 inline-block size-1.5 rounded-full",fe(p))}),p]}),s.jsx("span",{className:x("min-w-0 pt-1 text-[10px] text-muted-foreground",N?"break-words whitespace-normal [overflow-wrap:anywhere]":"overflow-x-auto whitespace-nowrap"),title:m,children:m}),s.jsx("span",{className:x("min-w-0 text-foreground/90 [overflow-wrap:anywhere]",N?"whitespace-pre-wrap break-words":"overflow-x-auto whitespace-pre"),title:o||i,children:o||i})]},`${$}-${f}-${i}`))})})})})]}),s.jsx(ve,{open:a,onOpenChange:c,children:s.jsxs(we,{children:[s.jsxs(ye,{children:[s.jsx(Oe,{children:"Clear console logs?"}),s.jsx(Le,{children:"This removes the current in-memory log buffer. New logs will continue to appear."})]}),s.jsxs(je,{children:[s.jsx(y,{variant:"outline",onClick:()=>c(!1),children:"Cancel"}),s.jsx(y,{variant:"destructive",onClick:()=>void xe(),children:"Clear logs"})]})]})})]})}export{St as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as d,j as e}from"./react-vendor-xnYrwzsL.js";import{a as P}from"./query-vendor-DVevaSVS.js";import{d as De,p as Re,e as S,c as N,S as Ce,B as le,h as ie,i as Le,j as He,k as qe}from"./index-B6j-9zHy.js";import{H as $e}from"./Header-C_9Su9BF.js";import{u as ze,n as Fe,F as Ae,f as Ee,S as Z,a as Pe,g as oe,b as We}from"./currency-api-SV9CBf5e.js";import{S as Ie}from"./segmented-CqmEnQjZ.js";import{S as U}from"./skeleton-7uJDiIXe.js";import{F as ee,a as ce,b as te,c as ve}from"./frame-cUiti6Lq.js";import{T as Ue,a as _e,b as W,c as T,d as Ke,e as j}from"./table-D0M60Tu1.js";import{l as Oe}from"./admin-extras-api-CCdu5TFM.js";import{p as I}from"./live-mode-CHShLY4E.js";import{aa as de,a8 as me,a9 as ue,ab as Be,A as Qe}from"./icons-vendor-CUx7SB5V.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";const Xe=De(t=>({stats:null,history:[],setStats:n=>t({stats:n}),setHistory:n=>t({history:n})})),Ye=[{value:"today",label:"Today"},{value:"7d",label:"7d"},{value:"30d",label:"30d"},{value:"90d",label:"90d"},{value:"1y",label:"1y"}];function xe(t){switch(t){case"today":return 100;case"7d":return 250;case"30d":return 400;case"90d":return 500;case"1y":return 500;default:return 200}}function M(t){return Number.isFinite(t)?Math.round(t).toLocaleString("id-ID"):"0"}function Ne(t){return Number.isFinite(t)?Math.round(t).toLocaleString("id-ID"):"0"}function he(t){const n=t==null?void 0:t.trim();if(!n)return"—";const i=n.lastIndexOf("/");return i>=0?n.slice(i+1):n}function pe(t){return t.status==="ok"||t.status==="success"?"bg-emerald-500":t.status==="error"||t.error?"bg-red-500":t.status==="pending"||t.status==="processing"?"bg-amber-500":"bg-muted-foreground/64"}function fe(t){return t.status?t.status.toUpperCase():t.error?"ERROR":"—"}function G(t){if(!t)return"—";try{return new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function ge(t,n=Date.now()){if(!t)return"—";const i=Date.parse(t);if(!Number.isFinite(i))return G(t);const o=Math.max(0,Math.floor((n-i)/1e3));if(o<1)return"now";if(o<60)return`${o}s ago`;const u=Math.floor(o/60);if(u<60)return`${u}m ago`;const h=Math.floor(u/60);if(h<24)return`${h}h ago`;const f=Math.floor(h/24);return f<7?`${f}d ago`:G(t)}function Ge(t,n,i,o){const u=Math.min(Math.max(t/n,0),1),h=o>0?Math.min(Math.max(i/o,0),1):u,f=(u+h)/2;return f<=0?"bg-muted/45":f<=.25?"bg-primary/30":f<=.5?"bg-primary/55":f<=.75?"bg-primary/80":"bg-primary"}function we(t){const n=new Date(`${t}T12:00:00`);return Number.isNaN(n.getTime())?t:n.toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric",year:"numeric"})}function be(t,n){const i=new Date(`${t}T12:00:00`);return Number.isNaN(i.getTime())?t:(i.setDate(i.getDate()+n),[i.getFullYear(),String(i.getMonth()+1).padStart(2,"0"),String(i.getDate()).padStart(2,"0")].join("-"))}function je(t){return{date:t,key:t,requests:0,tokens:0,promptTokens:0,completionTokens:0,cachedTokens:0,cost:0,errors:0}}function Je(t){return`${we(t.date)} · ${Ne(t.requests)} requests · ${M(t.tokens)} total tokens`}function Ve(t){return e.jsxs("div",{className:"min-w-40 space-y-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:we(t.date)}),e.jsxs("div",{className:"mt-0.5 text-[11px] text-muted-foreground",children:[Ne(t.requests)," requests"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 border-t border-border/70 pt-1.5 text-[11px]",children:[e.jsx("span",{className:"text-muted-foreground",children:"Total tokens"}),e.jsx("span",{className:"text-right font-semibold tabular-nums",children:M(t.tokens)})]})]})}function Ze({children:t}){const n=d.useRef(null),i=d.useRef(null),o=d.useRef(!1),[u,h]=d.useState({ratio:1,progress:0}),[f,C]=d.useState(!1),_=r=>{const l=r.scrollWidth,c=r.clientWidth,g=Math.max(l-c,0),w=l>0?Math.min(c/l,1):1,x=g>0?Math.min(Math.max(r.scrollLeft/g,0),1):0;h({ratio:w,progress:x})};d.useEffect(()=>{const r=n.current;if(!r)return;const l=()=>_(r);l();const c=new ResizeObserver(l);return c.observe(r),r.firstElementChild&&c.observe(r.firstElementChild),()=>c.disconnect()},[]);const L=r=>{const l=n.current,c=i.current;if(!l||!c)return;const g=l.scrollWidth,w=l.clientWidth,x=Math.max(g-w,0);if(!x)return;const H=c.clientWidth,q=Math.min(w/g,1),$=H*q,D=H-$;if(!D)return;const R=Math.min(Math.max(r-c.getBoundingClientRect().left-$/2,0),D);l.scrollLeft=R/D*x},K=r=>{o.current=!0,C(!0),r.currentTarget.setPointerCapture(r.pointerId),L(r.clientX)},O=r=>{o.current&&L(r.clientX)},y=r=>{o.current=!1,C(!1),r.currentTarget.hasPointerCapture(r.pointerId)&&r.currentTarget.releasePointerCapture(r.pointerId)},B=r=>{const l=n.current;if(!l)return;const c=Math.max(l.scrollWidth-l.clientWidth,0);if(!c)return;const g=Math.abs(r.deltaX)>Math.abs(r.deltaY)?r.deltaX:r.deltaY,w=r.deltaMode===1?g*16:g,x=Math.min(Math.max(l.scrollLeft+w,0),c);x!==l.scrollLeft&&(r.preventDefault(),l.scrollLeft=x)};return e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{ref:n,id:"router-activity-heatmap","data-custom-scrollbar":"true",className:"w-full min-w-0 max-w-full touch-pan-x overflow-x-auto overscroll-x-contain pb-1",onScroll:r=>_(r.currentTarget),onWheel:B,children:t}),u.ratio<1?e.jsx("div",{ref:i,role:"scrollbar","aria-label":"Router activity horizontal scroll","aria-controls":"router-activity-heatmap","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(u.progress*100),"aria-orientation":"horizontal",tabIndex:0,className:N("relative mt-1.5 h-1.5 w-full cursor-grab touch-none select-none rounded-full active:cursor-grabbing",f?"bg-foreground/10":"bg-foreground/5"),onPointerDown:K,onPointerMove:O,onPointerUp:y,onPointerCancel:y,onKeyDown:r=>{const l=n.current;if(!l)return;const c=l.scrollWidth-l.clientWidth;r.key==="ArrowLeft"||r.key==="ArrowRight"?(r.preventDefault(),l.scrollLeft+=r.key==="ArrowLeft"?-96:96):r.key==="Home"?(r.preventDefault(),l.scrollLeft=0):r.key==="End"&&(r.preventDefault(),l.scrollLeft=c)},children:e.jsx("div",{className:N("absolute inset-y-0 left-0 rounded-full",f?"bg-foreground/20":"bg-foreground/10"),style:{width:`${u.ratio*100}%`,left:`${u.progress*(1-u.ratio)*100}%`}})}):null]})}const ye=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function Y({label:t,value:n,detail:i,loading:o}){return e.jsx(ee,{className:"h-full min-w-0 w-full rounded-xl p-0.5 sm:rounded-2xl sm:p-1",children:e.jsxs(ve,{className:"h-full min-w-0 rounded-lg p-2 sm:rounded-xl sm:p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-baseline justify-between gap-x-2 gap-y-1 sm:block",children:[e.jsx(te,{className:"min-w-0 truncate text-[10px] font-medium leading-tight text-muted-foreground sm:min-h-0 sm:text-[13px]",children:t}),e.jsx("div",{className:"min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap text-lg font-semibold leading-none tracking-tight tabular-nums sm:mt-2 sm:text-[1.5rem]",children:o?e.jsx(U,{className:"h-6 w-16 sm:h-7 sm:w-20"}):n})]}),i?e.jsx("div",{className:"mt-1 min-h-4 min-w-0 text-[10px] leading-tight text-muted-foreground sm:mt-2 sm:min-h-0 sm:text-[12px]",children:i}):null]})})}function ht(){var se,re;const t=Xe(s=>s.setStats),[n,i]=d.useState("today"),[o,u]=d.useState(!1),[h,f]=d.useState(!1),[C,_]=d.useState(()=>Date.now());ze(),d.useEffect(()=>{const s=window.setInterval(()=>_(Date.now()),1e3);return()=>window.clearInterval(s)},[]);const L=P({queryKey:["usage-stats",n],queryFn:()=>Le({range:n}),enabled:I(),retry:!1}),K=P({queryKey:["currency-settings"],queryFn:We,enabled:I(),staleTime:720*60*1e3,retry:!1}),O=P({queryKey:["usage-heatmap","year"],queryFn:()=>He("year"),enabled:I(),retry:!1}),y=P({queryKey:["usage-history",n,xe(n)],queryFn:()=>qe({limit:xe(n),range:n}),enabled:I(),retry:!1}),B=P({queryKey:["nodes"],queryFn:Oe,enabled:I(),retry:!1}),r=L.data,l=y.data??[],c=L.isLoading,g=y.isLoading,w=O.isLoading,x=Fe((se=K.data)==null?void 0:se.currency),H=((re=K.data)==null?void 0:re.usdToIdr)??Ae,q=(r==null?void 0:r.totalCost)??0,$=Ee(q,x,H);d.useEffect(()=>{r&&t({total:r.total??0,totalCost:r.totalCost??0,byProvider:r.byProvider??{}})},[r,t]);const D=d.useMemo(()=>{const s=new Map;for(const a of B.data??[])s.set(a.id,a.name||a.id),a.prefix&&s.set(a.prefix,a.name||a.prefix);return a=>a?s.has(a)?s.get(a):Re(a)||a:"—"},[B.data]),R=d.useMemo(()=>l.slice(0,8),[l]),z=d.useMemo(()=>{const s=l.map(a=>a.latencyMs).filter(a=>typeof a=="number"&&Number.isFinite(a));return s.length?Math.round(s.reduce((a,m)=>a+m,0)/s.length):null},[l]),Q=d.useMemo(()=>z===null?null:z<1e3?{value:z,unit:"ms"}:{value:Number((z/1e3).toFixed(1)),unit:"s"},[z]),p=O.data??[],Se=d.useMemo(()=>Math.max(...p.map(s=>s.requests),1),[p]),ke=d.useMemo(()=>Math.max(...p.map(s=>s.tokens),1),[p]),J=d.useMemo(()=>{var ne;if(!p.length)return[];const s=new Date(`${p[0].date}T12:00:00`),a=p[0].date,m=Number.isNaN(s.getTime())?0:(s.getDay()+6)%7,k=[...Array.from({length:m},(v,A)=>je(be(a,A-m))),...p],b=((ne=p[p.length-1])==null?void 0:ne.date)||a;for(;k.length%7!==0;){const v=k.length-m-p.length+1;k.push(je(be(b,v)))}const X=new Set(p.map(v=>v.date));let F="";const ae=[];for(let v=0;v<k.length;v+=7){const A=k.slice(v,v+7),E=A.find(Me=>X.has(Me.date))||A[0],V=(E==null?void 0:E.date.slice(0,7))||"",Te=E&&V!==F?new Date(`${E.date}T12:00:00`).toLocaleDateString(void 0,{month:"short"}):"";V&&(F=V),ae.push({monthLabel:Te,cells:A})}return ae},[p]);return e.jsxs("div",{className:"flex w-full flex-col gap-2.5 pb-6 lg:h-full lg:min-h-0 lg:overflow-hidden lg:pb-0",children:[e.jsx($e,{className:"mb-0 sm:mb-0 shrink-0 gap-2 sm:items-end",title:"Dashboard",actions:e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsx("div",{className:"min-w-[16rem] sm:min-w-[18rem]",children:e.jsx(Ie,{size:"sm",value:n,onChange:i,options:Ye,className:"w-full"})})})}),e.jsxs("div",{className:"grid shrink-0 grid-cols-2 gap-2 sm:gap-2.5 lg:grid-cols-4",children:[e.jsx(Y,{label:"Requests",loading:c,value:e.jsx(Z,{value:(r==null?void 0:r.total)??0,decimals:0})}),e.jsx(Y,{label:"Total Tokens",loading:c,value:e.jsx("span",{className:"tabular-nums",children:M(((r==null?void 0:r.totalPromptTokens)??0)+((r==null?void 0:r.totalCompletionTokens)??0))})}),e.jsx(Y,{label:`Cost (${x})`,loading:c,value:e.jsx(S,{label:$,children:e.jsx("span",{className:"block min-w-0 max-w-full truncate",title:$,children:e.jsx(Z,{value:Pe(q,x,H),prefix:x==="IDR"?"Rp":"$",locale:x==="IDR"?"id-ID":"en-US",decimals:x==="IDR"?0:q<.01?4:2,className:"text-[clamp(1rem,4vw,1.5rem)]"})})})}),e.jsx(Y,{label:"Latency",loading:c,value:Q!==null?e.jsx(Z,{value:Q.value,decimals:Q.unit==="s"?1:0,suffix:` ${Q.unit}`}):"—"})]}),e.jsx("div",{className:"w-full min-w-0",children:e.jsxs(ee,{className:"flex min-w-0 shrink-0 flex-col overflow-hidden",children:[e.jsx(ce,{className:"gap-3 border-b border-border/80",children:e.jsx("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:e.jsx("div",{children:e.jsx(te,{className:"text-[15px] font-medium tracking-tight",children:"Router Activity"})})})}),e.jsxs(ve,{className:"flex min-w-0 flex-col overflow-hidden",children:[e.jsx("div",{className:"mb-1 flex shrink-0 flex-wrap items-center justify-end gap-2",children:e.jsxs("div",{className:"inline-flex items-center gap-2 text-[10px] text-muted-foreground","aria-label":"Activity intensity: less to more",children:[e.jsx("span",{children:"Less"}),e.jsxs("span",{className:"flex items-center gap-1","aria-hidden":"true",children:[e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-muted/45"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/30"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/55"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/80"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary"})]}),e.jsx("span",{children:"More"})]})}),e.jsx("div",{children:w?e.jsx(U,{className:"h-56 w-full rounded-xl"}):e.jsx("div",{className:"min-w-0 rounded-xl border border-border/70 bg-background/25 p-2.5 sm:p-3",children:e.jsx(Ze,{children:e.jsxs("div",{className:"grid w-max min-w-full grid-cols-[2.75rem_max-content] items-start 2xl:w-full 2xl:grid-cols-[2.75rem_minmax(0,1fr)]",style:{columnGap:"0.25rem"},children:[e.jsxs("div",{className:"sticky left-0 z-10 grid h-max w-[calc(100%+0.25rem)] grid-rows-[1rem_repeat(7,1rem)] gap-y-2 bg-background",children:[e.jsx("span",{className:"h-4","aria-hidden":"true"}),ye.map(s=>e.jsx("span",{className:"h-4 whitespace-nowrap pr-1 text-left font-sans font-semibold text-[9px] tabular-nums text-muted-foreground",children:s},s))]}),e.jsxs("div",{className:"grid w-max grid-cols-[repeat(var(--heatmap-columns),1.25rem)] items-center justify-items-center gap-x-1 gap-y-2 2xl:w-full 2xl:grid-cols-[repeat(var(--heatmap-columns),minmax(0,1fr))]",style:{"--heatmap-columns":J.length},children:[J.map((s,a)=>e.jsx("span",{className:"flex h-4 items-end justify-center font-sans font-semibold text-[9px] tabular-nums text-muted-foreground",children:s.monthLabel},`${s.monthLabel}-${a}`)),ye.map((s,a)=>e.jsx(d.Fragment,{children:J.map((m,k)=>{const b=m.cells[a],X=b.requests>0,F=X?Je(b):"No activity on this day";return e.jsx(S,{label:X?Ve(b):F,children:e.jsx("span",{role:"img","aria-label":F,className:N("size-4 rounded-[3px] border border-border/40",Ge((b==null?void 0:b.requests)||0,Se,(b==null?void 0:b.tokens)||0,ke))})},`${k}-${a}`)})},s))]})]})})})})]})]})}),e.jsxs(ee,{className:"flex min-h-[240px] w-full flex-col lg:min-h-0 lg:flex-1 lg:overflow-hidden",children:[e.jsx(ce,{className:"border-b border-border/80",children:e.jsx(te,{className:"text-[15px]",children:"Recent requests"})}),e.jsx("div",{className:"min-h-0 flex-1 pb-1",children:e.jsxs(Ce,{overscrollContain:!0,className:"h-full",children:[e.jsx("div",{className:"w-full min-w-0 divide-y divide-border/70 rounded-xl border border-border/70 bg-card sm:hidden",children:g?Array.from({length:5}).map((s,a)=>e.jsxs("div",{className:"px-3 py-3",children:[e.jsx(U,{className:"h-3.5 w-2/3"}),e.jsx(U,{className:"mt-2 h-3 w-full"})]},a)):y.isError?e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-10 text-center text-sm text-muted-foreground",children:[e.jsx("span",{children:"Unable to load recent requests."}),e.jsxs(le,{type:"button",size:"xs",variant:"outline",onClick:()=>void y.refetch(),children:[e.jsx(de,{"aria-hidden":!0}),"Retry"]})]}):R.length===0?e.jsx("div",{className:"px-4 py-10 text-center text-sm text-muted-foreground",children:"No requests yet"}):R.map((s,a)=>{const m=oe(s);return e.jsx("article",{className:"flex min-w-0 items-center gap-2.5 px-3 py-3",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("p",{className:N("min-w-0 flex-1 truncate text-xs font-medium",o&&"font-normal italic text-muted-foreground"),children:o?"Hidden":D(s.provider)}),e.jsxs(ie,{variant:"outline",className:"shrink-0 text-[10px] font-normal",children:[e.jsx("span",{"aria-hidden":"true",className:N("size-1.5 rounded-full",pe(s))}),fe(s)]})]}),e.jsx("p",{className:"mt-0.5 max-w-full truncate font-mono text-[11px] text-muted-foreground",children:h?he(s.model):s.model||"—"}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-center gap-1.5 truncate text-[10px] tabular-nums text-muted-foreground",children:[e.jsx(S,{label:G(s.timestamp),children:e.jsx("span",{className:"shrink-0",children:ge(s.timestamp,C)})}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsxs("span",{className:"shrink-0 text-success",children:["In ",M(s.promptTokens||0)]}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsxs("span",{className:"shrink-0 text-destructive",children:["Out ",M(s.completionTokens||0)]}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsx(S,{label:m.title,children:e.jsx("span",{className:N("shrink-0",m.hit?"text-warning":"text-muted-foreground"),children:m.label})})]})]})},s.id??`${s.timestamp}-${a}`)})}),e.jsx("div",{className:"hidden sm:block",children:e.jsxs(Ue,{variant:"card",className:"min-w-[32rem] text-[13px]",children:[e.jsx(_e,{children:e.jsxs(W,{children:[e.jsx(T,{className:"px-5 py-2.5",children:"Time"}),e.jsx(T,{className:"px-3 py-2.5",children:e.jsxs("div",{className:"group/column flex items-center gap-1.5",children:[e.jsx("span",{children:"Provider"}),e.jsx(S,{label:o?"Show provider names":"Hide provider names",children:e.jsx("button",{type:"button","aria-label":o?"Show provider names":"Hide provider names",onClick:()=>u(s=>!s),className:"inline-flex size-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-surface-hover hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/column:opacity-100",children:o?e.jsx(me,{className:"size-3.5","aria-hidden":"true"}):e.jsx(ue,{className:"size-3.5","aria-hidden":"true"})})})]})}),e.jsx(T,{className:"px-3 py-2.5",children:e.jsxs("div",{className:"group/column flex items-center gap-1.5",children:[e.jsx("span",{children:"Model"}),e.jsx(S,{label:h?"Show full model names":"Hide provider prefixes from models",children:e.jsx("button",{type:"button","aria-label":h?"Show full model names":"Hide provider prefixes from models",onClick:()=>f(s=>!s),className:"inline-flex size-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-surface-hover hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/column:opacity-100",children:h?e.jsx(me,{className:"size-3.5","aria-hidden":"true"}):e.jsx(ue,{className:"size-3.5","aria-hidden":"true"})})})]})}),e.jsx(T,{className:"px-3 py-2.5 text-success",children:"In"}),e.jsx(T,{className:"px-3 py-2.5 text-destructive",children:"Out"}),e.jsx(T,{className:"px-3 py-2.5",children:"Cache"}),e.jsx(T,{className:"px-5 py-2.5",children:"Status"})]})}),e.jsx(Ke,{children:g?Array.from({length:5}).map((s,a)=>e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-3",children:e.jsx(U,{className:"h-4 w-full"})})},a)):y.isError?e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-10 text-center text-muted-foreground",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("span",{children:"Unable to load recent requests."}),e.jsxs(le,{type:"button",size:"xs",variant:"outline",onClick:()=>void y.refetch(),children:[e.jsx(de,{"aria-hidden":!0}),"Retry"]})]})})}):R.length===0?e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-12 text-center text-muted-foreground",children:"No requests yet"})}):R.map((s,a)=>e.jsxs(W,{children:[e.jsx(j,{className:"whitespace-nowrap px-5 py-2.5 text-muted-foreground",children:e.jsx(S,{label:G(s.timestamp),children:e.jsx("span",{children:ge(s.timestamp,C)})})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5 font-medium",children:(()=>{const m=D(s.provider);return e.jsx("span",{className:N("truncate",o&&"font-normal italic text-muted-foreground"),children:o?"Hidden":m})})()}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:(()=>{const m=s.model||"—";return e.jsx("span",{className:"block min-w-0 truncate font-mono text-[12px] text-muted-foreground",children:h?he(s.model):m})})()}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:e.jsxs("span",{className:"inline-flex items-center gap-1 tabular-nums text-success",children:[e.jsx(Be,{className:"h-3 w-3 shrink-0","aria-hidden":!0}),M(s.promptTokens||0)]})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:e.jsxs("span",{className:"inline-flex items-center gap-1 tabular-nums text-destructive",children:[e.jsx(Qe,{className:"h-3 w-3 shrink-0","aria-hidden":!0}),M(s.completionTokens||0)]})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:(()=>{const m=oe(s);return e.jsx(S,{label:m.title,children:e.jsx("span",{className:N("text-[11px] font-medium tabular-nums",m.hit?"text-warning":"text-muted-foreground"),children:m.label})})})()}),e.jsx(j,{className:"whitespace-nowrap px-5 py-2.5",children:e.jsxs(ie,{variant:"outline",className:"font-normal",children:[e.jsx("span",{"aria-hidden":"true",className:N("size-1.5 rounded-full",pe(s))}),fe(s)]})})]},s.id??`${s.timestamp}-${a}`))})]})})]})})]})]})}export{ht as default};
|
|
1
|
+
import{r as d,j as e}from"./react-vendor-xnYrwzsL.js";import{a as P}from"./query-vendor-DVevaSVS.js";import{d as De,p as Re,e as S,c as N,S as Ce,B as le,h as ie,i as Le,j as He,k as qe}from"./index-BCs8FaU-.js";import{H as $e}from"./Header-CbIOa7_e.js";import{u as ze,n as Fe,F as Ae,f as Ee,S as Z,a as Pe,g as oe,b as We}from"./currency-api-C007t85X.js";import{S as Ie}from"./segmented-CH2xd56I.js";import{S as U}from"./skeleton-BeyFFj7e.js";import{F as ee,a as ce,b as te,c as ve}from"./frame-1zkYd9EK.js";import{T as Ue,a as _e,b as W,c as T,d as Ke,e as j}from"./table-DBwhoFaJ.js";import{l as Oe}from"./admin-extras-api-DwBdGPVg.js";import{p as I}from"./live-mode-CHShLY4E.js";import{aa as de,a8 as me,a9 as ue,ab as Be,A as Qe}from"./icons-vendor-CUx7SB5V.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";const Xe=De(t=>({stats:null,history:[],setStats:n=>t({stats:n}),setHistory:n=>t({history:n})})),Ye=[{value:"today",label:"Today"},{value:"7d",label:"7d"},{value:"30d",label:"30d"},{value:"90d",label:"90d"},{value:"1y",label:"1y"}];function xe(t){switch(t){case"today":return 100;case"7d":return 250;case"30d":return 400;case"90d":return 500;case"1y":return 500;default:return 200}}function M(t){return Number.isFinite(t)?Math.round(t).toLocaleString("id-ID"):"0"}function Ne(t){return Number.isFinite(t)?Math.round(t).toLocaleString("id-ID"):"0"}function he(t){const n=t==null?void 0:t.trim();if(!n)return"—";const i=n.lastIndexOf("/");return i>=0?n.slice(i+1):n}function pe(t){return t.status==="ok"||t.status==="success"?"bg-emerald-500":t.status==="error"||t.error?"bg-red-500":t.status==="pending"||t.status==="processing"?"bg-amber-500":"bg-muted-foreground/64"}function fe(t){return t.status?t.status.toUpperCase():t.error?"ERROR":"—"}function G(t){if(!t)return"—";try{return new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function ge(t,n=Date.now()){if(!t)return"—";const i=Date.parse(t);if(!Number.isFinite(i))return G(t);const o=Math.max(0,Math.floor((n-i)/1e3));if(o<1)return"now";if(o<60)return`${o}s ago`;const u=Math.floor(o/60);if(u<60)return`${u}m ago`;const h=Math.floor(u/60);if(h<24)return`${h}h ago`;const f=Math.floor(h/24);return f<7?`${f}d ago`:G(t)}function Ge(t,n,i,o){const u=Math.min(Math.max(t/n,0),1),h=o>0?Math.min(Math.max(i/o,0),1):u,f=(u+h)/2;return f<=0?"bg-muted/45":f<=.25?"bg-primary/30":f<=.5?"bg-primary/55":f<=.75?"bg-primary/80":"bg-primary"}function we(t){const n=new Date(`${t}T12:00:00`);return Number.isNaN(n.getTime())?t:n.toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric",year:"numeric"})}function be(t,n){const i=new Date(`${t}T12:00:00`);return Number.isNaN(i.getTime())?t:(i.setDate(i.getDate()+n),[i.getFullYear(),String(i.getMonth()+1).padStart(2,"0"),String(i.getDate()).padStart(2,"0")].join("-"))}function je(t){return{date:t,key:t,requests:0,tokens:0,promptTokens:0,completionTokens:0,cachedTokens:0,cost:0,errors:0}}function Je(t){return`${we(t.date)} · ${Ne(t.requests)} requests · ${M(t.tokens)} total tokens`}function Ve(t){return e.jsxs("div",{className:"min-w-40 space-y-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:we(t.date)}),e.jsxs("div",{className:"mt-0.5 text-[11px] text-muted-foreground",children:[Ne(t.requests)," requests"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 border-t border-border/70 pt-1.5 text-[11px]",children:[e.jsx("span",{className:"text-muted-foreground",children:"Total tokens"}),e.jsx("span",{className:"text-right font-semibold tabular-nums",children:M(t.tokens)})]})]})}function Ze({children:t}){const n=d.useRef(null),i=d.useRef(null),o=d.useRef(!1),[u,h]=d.useState({ratio:1,progress:0}),[f,C]=d.useState(!1),_=r=>{const l=r.scrollWidth,c=r.clientWidth,g=Math.max(l-c,0),w=l>0?Math.min(c/l,1):1,x=g>0?Math.min(Math.max(r.scrollLeft/g,0),1):0;h({ratio:w,progress:x})};d.useEffect(()=>{const r=n.current;if(!r)return;const l=()=>_(r);l();const c=new ResizeObserver(l);return c.observe(r),r.firstElementChild&&c.observe(r.firstElementChild),()=>c.disconnect()},[]);const L=r=>{const l=n.current,c=i.current;if(!l||!c)return;const g=l.scrollWidth,w=l.clientWidth,x=Math.max(g-w,0);if(!x)return;const H=c.clientWidth,q=Math.min(w/g,1),$=H*q,D=H-$;if(!D)return;const R=Math.min(Math.max(r-c.getBoundingClientRect().left-$/2,0),D);l.scrollLeft=R/D*x},K=r=>{o.current=!0,C(!0),r.currentTarget.setPointerCapture(r.pointerId),L(r.clientX)},O=r=>{o.current&&L(r.clientX)},y=r=>{o.current=!1,C(!1),r.currentTarget.hasPointerCapture(r.pointerId)&&r.currentTarget.releasePointerCapture(r.pointerId)},B=r=>{const l=n.current;if(!l)return;const c=Math.max(l.scrollWidth-l.clientWidth,0);if(!c)return;const g=Math.abs(r.deltaX)>Math.abs(r.deltaY)?r.deltaX:r.deltaY,w=r.deltaMode===1?g*16:g,x=Math.min(Math.max(l.scrollLeft+w,0),c);x!==l.scrollLeft&&(r.preventDefault(),l.scrollLeft=x)};return e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{ref:n,id:"router-activity-heatmap","data-custom-scrollbar":"true",className:"w-full min-w-0 max-w-full touch-pan-x overflow-x-auto overscroll-x-contain pb-1",onScroll:r=>_(r.currentTarget),onWheel:B,children:t}),u.ratio<1?e.jsx("div",{ref:i,role:"scrollbar","aria-label":"Router activity horizontal scroll","aria-controls":"router-activity-heatmap","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(u.progress*100),"aria-orientation":"horizontal",tabIndex:0,className:N("relative mt-1.5 h-1.5 w-full cursor-grab touch-none select-none rounded-full active:cursor-grabbing",f?"bg-foreground/10":"bg-foreground/5"),onPointerDown:K,onPointerMove:O,onPointerUp:y,onPointerCancel:y,onKeyDown:r=>{const l=n.current;if(!l)return;const c=l.scrollWidth-l.clientWidth;r.key==="ArrowLeft"||r.key==="ArrowRight"?(r.preventDefault(),l.scrollLeft+=r.key==="ArrowLeft"?-96:96):r.key==="Home"?(r.preventDefault(),l.scrollLeft=0):r.key==="End"&&(r.preventDefault(),l.scrollLeft=c)},children:e.jsx("div",{className:N("absolute inset-y-0 left-0 rounded-full",f?"bg-foreground/20":"bg-foreground/10"),style:{width:`${u.ratio*100}%`,left:`${u.progress*(1-u.ratio)*100}%`}})}):null]})}const ye=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function Y({label:t,value:n,detail:i,loading:o}){return e.jsx(ee,{className:"h-full min-w-0 w-full rounded-xl p-0.5 sm:rounded-2xl sm:p-1",children:e.jsxs(ve,{className:"h-full min-w-0 rounded-lg p-2 sm:rounded-xl sm:p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-baseline justify-between gap-x-2 gap-y-1 sm:block",children:[e.jsx(te,{className:"min-w-0 truncate text-[10px] font-medium leading-tight text-muted-foreground sm:min-h-0 sm:text-[13px]",children:t}),e.jsx("div",{className:"min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap text-lg font-semibold leading-none tracking-tight tabular-nums sm:mt-2 sm:text-[1.5rem]",children:o?e.jsx(U,{className:"h-6 w-16 sm:h-7 sm:w-20"}):n})]}),i?e.jsx("div",{className:"mt-1 min-h-4 min-w-0 text-[10px] leading-tight text-muted-foreground sm:mt-2 sm:min-h-0 sm:text-[12px]",children:i}):null]})})}function ht(){var se,re;const t=Xe(s=>s.setStats),[n,i]=d.useState("today"),[o,u]=d.useState(!1),[h,f]=d.useState(!1),[C,_]=d.useState(()=>Date.now());ze(),d.useEffect(()=>{const s=window.setInterval(()=>_(Date.now()),1e3);return()=>window.clearInterval(s)},[]);const L=P({queryKey:["usage-stats",n],queryFn:()=>Le({range:n}),enabled:I(),retry:!1}),K=P({queryKey:["currency-settings"],queryFn:We,enabled:I(),staleTime:720*60*1e3,retry:!1}),O=P({queryKey:["usage-heatmap","year"],queryFn:()=>He("year"),enabled:I(),retry:!1}),y=P({queryKey:["usage-history",n,xe(n)],queryFn:()=>qe({limit:xe(n),range:n}),enabled:I(),retry:!1}),B=P({queryKey:["nodes"],queryFn:Oe,enabled:I(),retry:!1}),r=L.data,l=y.data??[],c=L.isLoading,g=y.isLoading,w=O.isLoading,x=Fe((se=K.data)==null?void 0:se.currency),H=((re=K.data)==null?void 0:re.usdToIdr)??Ae,q=(r==null?void 0:r.totalCost)??0,$=Ee(q,x,H);d.useEffect(()=>{r&&t({total:r.total??0,totalCost:r.totalCost??0,byProvider:r.byProvider??{}})},[r,t]);const D=d.useMemo(()=>{const s=new Map;for(const a of B.data??[])s.set(a.id,a.name||a.id),a.prefix&&s.set(a.prefix,a.name||a.prefix);return a=>a?s.has(a)?s.get(a):Re(a)||a:"—"},[B.data]),R=d.useMemo(()=>l.slice(0,8),[l]),z=d.useMemo(()=>{const s=l.map(a=>a.latencyMs).filter(a=>typeof a=="number"&&Number.isFinite(a));return s.length?Math.round(s.reduce((a,m)=>a+m,0)/s.length):null},[l]),Q=d.useMemo(()=>z===null?null:z<1e3?{value:z,unit:"ms"}:{value:Number((z/1e3).toFixed(1)),unit:"s"},[z]),p=O.data??[],Se=d.useMemo(()=>Math.max(...p.map(s=>s.requests),1),[p]),ke=d.useMemo(()=>Math.max(...p.map(s=>s.tokens),1),[p]),J=d.useMemo(()=>{var ne;if(!p.length)return[];const s=new Date(`${p[0].date}T12:00:00`),a=p[0].date,m=Number.isNaN(s.getTime())?0:(s.getDay()+6)%7,k=[...Array.from({length:m},(v,A)=>je(be(a,A-m))),...p],b=((ne=p[p.length-1])==null?void 0:ne.date)||a;for(;k.length%7!==0;){const v=k.length-m-p.length+1;k.push(je(be(b,v)))}const X=new Set(p.map(v=>v.date));let F="";const ae=[];for(let v=0;v<k.length;v+=7){const A=k.slice(v,v+7),E=A.find(Me=>X.has(Me.date))||A[0],V=(E==null?void 0:E.date.slice(0,7))||"",Te=E&&V!==F?new Date(`${E.date}T12:00:00`).toLocaleDateString(void 0,{month:"short"}):"";V&&(F=V),ae.push({monthLabel:Te,cells:A})}return ae},[p]);return e.jsxs("div",{className:"flex w-full flex-col gap-2.5 pb-6 lg:h-full lg:min-h-0 lg:overflow-hidden lg:pb-0",children:[e.jsx($e,{className:"mb-0 sm:mb-0 shrink-0 gap-2 sm:items-end",title:"Dashboard",actions:e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsx("div",{className:"min-w-[16rem] sm:min-w-[18rem]",children:e.jsx(Ie,{size:"sm",value:n,onChange:i,options:Ye,className:"w-full"})})})}),e.jsxs("div",{className:"grid shrink-0 grid-cols-2 gap-2 sm:gap-2.5 lg:grid-cols-4",children:[e.jsx(Y,{label:"Requests",loading:c,value:e.jsx(Z,{value:(r==null?void 0:r.total)??0,decimals:0})}),e.jsx(Y,{label:"Total Tokens",loading:c,value:e.jsx("span",{className:"tabular-nums",children:M(((r==null?void 0:r.totalPromptTokens)??0)+((r==null?void 0:r.totalCompletionTokens)??0))})}),e.jsx(Y,{label:`Cost (${x})`,loading:c,value:e.jsx(S,{label:$,children:e.jsx("span",{className:"block min-w-0 max-w-full truncate",title:$,children:e.jsx(Z,{value:Pe(q,x,H),prefix:x==="IDR"?"Rp":"$",locale:x==="IDR"?"id-ID":"en-US",decimals:x==="IDR"?0:q<.01?4:2,className:"text-[clamp(1rem,4vw,1.5rem)]"})})})}),e.jsx(Y,{label:"Latency",loading:c,value:Q!==null?e.jsx(Z,{value:Q.value,decimals:Q.unit==="s"?1:0,suffix:` ${Q.unit}`}):"—"})]}),e.jsx("div",{className:"w-full min-w-0",children:e.jsxs(ee,{className:"flex min-w-0 shrink-0 flex-col overflow-hidden",children:[e.jsx(ce,{className:"gap-3 border-b border-border/80",children:e.jsx("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:e.jsx("div",{children:e.jsx(te,{className:"text-[15px] font-medium tracking-tight",children:"Router Activity"})})})}),e.jsxs(ve,{className:"flex min-w-0 flex-col overflow-hidden",children:[e.jsx("div",{className:"mb-1 flex shrink-0 flex-wrap items-center justify-end gap-2",children:e.jsxs("div",{className:"inline-flex items-center gap-2 text-[10px] text-muted-foreground","aria-label":"Activity intensity: less to more",children:[e.jsx("span",{children:"Less"}),e.jsxs("span",{className:"flex items-center gap-1","aria-hidden":"true",children:[e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-muted/45"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/30"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/55"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary/80"}),e.jsx("span",{className:"size-3 rounded-[3px] border border-border/40 bg-primary"})]}),e.jsx("span",{children:"More"})]})}),e.jsx("div",{children:w?e.jsx(U,{className:"h-56 w-full rounded-xl"}):e.jsx("div",{className:"min-w-0 rounded-xl border border-border/70 bg-background/25 p-2.5 sm:p-3",children:e.jsx(Ze,{children:e.jsxs("div",{className:"grid w-max min-w-full grid-cols-[2.75rem_max-content] items-start 2xl:w-full 2xl:grid-cols-[2.75rem_minmax(0,1fr)]",style:{columnGap:"0.25rem"},children:[e.jsxs("div",{className:"sticky left-0 z-10 grid h-max w-[calc(100%+0.25rem)] grid-rows-[1rem_repeat(7,1rem)] gap-y-2 bg-background",children:[e.jsx("span",{className:"h-4","aria-hidden":"true"}),ye.map(s=>e.jsx("span",{className:"h-4 whitespace-nowrap pr-1 text-left font-sans font-semibold text-[9px] tabular-nums text-muted-foreground",children:s},s))]}),e.jsxs("div",{className:"grid w-max grid-cols-[repeat(var(--heatmap-columns),1.25rem)] items-center justify-items-center gap-x-1 gap-y-2 2xl:w-full 2xl:grid-cols-[repeat(var(--heatmap-columns),minmax(0,1fr))]",style:{"--heatmap-columns":J.length},children:[J.map((s,a)=>e.jsx("span",{className:"flex h-4 items-end justify-center font-sans font-semibold text-[9px] tabular-nums text-muted-foreground",children:s.monthLabel},`${s.monthLabel}-${a}`)),ye.map((s,a)=>e.jsx(d.Fragment,{children:J.map((m,k)=>{const b=m.cells[a],X=b.requests>0,F=X?Je(b):"No activity on this day";return e.jsx(S,{label:X?Ve(b):F,children:e.jsx("span",{role:"img","aria-label":F,className:N("size-4 rounded-[3px] border border-border/40",Ge((b==null?void 0:b.requests)||0,Se,(b==null?void 0:b.tokens)||0,ke))})},`${k}-${a}`)})},s))]})]})})})})]})]})}),e.jsxs(ee,{className:"flex min-h-[240px] w-full flex-col lg:min-h-0 lg:flex-1 lg:overflow-hidden",children:[e.jsx(ce,{className:"border-b border-border/80",children:e.jsx(te,{className:"text-[15px]",children:"Recent requests"})}),e.jsx("div",{className:"min-h-0 flex-1 pb-1",children:e.jsxs(Ce,{overscrollContain:!0,className:"h-full",children:[e.jsx("div",{className:"w-full min-w-0 divide-y divide-border/70 rounded-xl border border-border/70 bg-card sm:hidden",children:g?Array.from({length:5}).map((s,a)=>e.jsxs("div",{className:"px-3 py-3",children:[e.jsx(U,{className:"h-3.5 w-2/3"}),e.jsx(U,{className:"mt-2 h-3 w-full"})]},a)):y.isError?e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-10 text-center text-sm text-muted-foreground",children:[e.jsx("span",{children:"Unable to load recent requests."}),e.jsxs(le,{type:"button",size:"xs",variant:"outline",onClick:()=>void y.refetch(),children:[e.jsx(de,{"aria-hidden":!0}),"Retry"]})]}):R.length===0?e.jsx("div",{className:"px-4 py-10 text-center text-sm text-muted-foreground",children:"No requests yet"}):R.map((s,a)=>{const m=oe(s);return e.jsx("article",{className:"flex min-w-0 items-center gap-2.5 px-3 py-3",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("p",{className:N("min-w-0 flex-1 truncate text-xs font-medium",o&&"font-normal italic text-muted-foreground"),children:o?"Hidden":D(s.provider)}),e.jsxs(ie,{variant:"outline",className:"shrink-0 text-[10px] font-normal",children:[e.jsx("span",{"aria-hidden":"true",className:N("size-1.5 rounded-full",pe(s))}),fe(s)]})]}),e.jsx("p",{className:"mt-0.5 max-w-full truncate font-mono text-[11px] text-muted-foreground",children:h?he(s.model):s.model||"—"}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-center gap-1.5 truncate text-[10px] tabular-nums text-muted-foreground",children:[e.jsx(S,{label:G(s.timestamp),children:e.jsx("span",{className:"shrink-0",children:ge(s.timestamp,C)})}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsxs("span",{className:"shrink-0 text-success",children:["In ",M(s.promptTokens||0)]}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsxs("span",{className:"shrink-0 text-destructive",children:["Out ",M(s.completionTokens||0)]}),e.jsx("span",{"aria-hidden":"true",children:"·"}),e.jsx(S,{label:m.title,children:e.jsx("span",{className:N("shrink-0",m.hit?"text-warning":"text-muted-foreground"),children:m.label})})]})]})},s.id??`${s.timestamp}-${a}`)})}),e.jsx("div",{className:"hidden sm:block",children:e.jsxs(Ue,{variant:"card",className:"min-w-[32rem] text-[13px]",children:[e.jsx(_e,{children:e.jsxs(W,{children:[e.jsx(T,{className:"px-5 py-2.5",children:"Time"}),e.jsx(T,{className:"px-3 py-2.5",children:e.jsxs("div",{className:"group/column flex items-center gap-1.5",children:[e.jsx("span",{children:"Provider"}),e.jsx(S,{label:o?"Show provider names":"Hide provider names",children:e.jsx("button",{type:"button","aria-label":o?"Show provider names":"Hide provider names",onClick:()=>u(s=>!s),className:"inline-flex size-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-surface-hover hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/column:opacity-100",children:o?e.jsx(me,{className:"size-3.5","aria-hidden":"true"}):e.jsx(ue,{className:"size-3.5","aria-hidden":"true"})})})]})}),e.jsx(T,{className:"px-3 py-2.5",children:e.jsxs("div",{className:"group/column flex items-center gap-1.5",children:[e.jsx("span",{children:"Model"}),e.jsx(S,{label:h?"Show full model names":"Hide provider prefixes from models",children:e.jsx("button",{type:"button","aria-label":h?"Show full model names":"Hide provider prefixes from models",onClick:()=>f(s=>!s),className:"inline-flex size-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-surface-hover hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/column:opacity-100",children:h?e.jsx(me,{className:"size-3.5","aria-hidden":"true"}):e.jsx(ue,{className:"size-3.5","aria-hidden":"true"})})})]})}),e.jsx(T,{className:"px-3 py-2.5 text-success",children:"In"}),e.jsx(T,{className:"px-3 py-2.5 text-destructive",children:"Out"}),e.jsx(T,{className:"px-3 py-2.5",children:"Cache"}),e.jsx(T,{className:"px-5 py-2.5",children:"Status"})]})}),e.jsx(Ke,{children:g?Array.from({length:5}).map((s,a)=>e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-3",children:e.jsx(U,{className:"h-4 w-full"})})},a)):y.isError?e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-10 text-center text-muted-foreground",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("span",{children:"Unable to load recent requests."}),e.jsxs(le,{type:"button",size:"xs",variant:"outline",onClick:()=>void y.refetch(),children:[e.jsx(de,{"aria-hidden":!0}),"Retry"]})]})})}):R.length===0?e.jsx(W,{children:e.jsx(j,{colSpan:7,className:"px-5 py-12 text-center text-muted-foreground",children:"No requests yet"})}):R.map((s,a)=>e.jsxs(W,{children:[e.jsx(j,{className:"whitespace-nowrap px-5 py-2.5 text-muted-foreground",children:e.jsx(S,{label:G(s.timestamp),children:e.jsx("span",{children:ge(s.timestamp,C)})})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5 font-medium",children:(()=>{const m=D(s.provider);return e.jsx("span",{className:N("truncate",o&&"font-normal italic text-muted-foreground"),children:o?"Hidden":m})})()}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:(()=>{const m=s.model||"—";return e.jsx("span",{className:"block min-w-0 truncate font-mono text-[12px] text-muted-foreground",children:h?he(s.model):m})})()}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:e.jsxs("span",{className:"inline-flex items-center gap-1 tabular-nums text-success",children:[e.jsx(Be,{className:"h-3 w-3 shrink-0","aria-hidden":!0}),M(s.promptTokens||0)]})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:e.jsxs("span",{className:"inline-flex items-center gap-1 tabular-nums text-destructive",children:[e.jsx(Qe,{className:"h-3 w-3 shrink-0","aria-hidden":!0}),M(s.completionTokens||0)]})}),e.jsx(j,{className:"whitespace-nowrap px-3 py-2.5",children:(()=>{const m=oe(s);return e.jsx(S,{label:m.title,children:e.jsx("span",{className:N("text-[11px] font-medium tabular-nums",m.hit?"text-warning":"text-muted-foreground"),children:m.label})})})()}),e.jsx(j,{className:"whitespace-nowrap px-5 py-2.5",children:e.jsxs(ie,{variant:"outline",className:"font-normal",children:[e.jsx("span",{"aria-hidden":"true",className:N("size-1.5 rounded-full",pe(s))}),fe(s)]})})]},s.id??`${s.timestamp}-${a}`))})]})})]})})]})]})}export{ht as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./react-vendor-xnYrwzsL.js";import{c as x}from"./index-
|
|
1
|
+
import{j as e}from"./react-vendor-xnYrwzsL.js";import{c as x}from"./index-BCs8FaU-.js";function n({title:m,description:s,actions:t,className:l}){return e.jsxs("div",{className:x("mb-3 flex flex-col gap-2 sm:mb-4 sm:flex-row sm:items-center sm:justify-between",l),children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-xl font-semibold tracking-tight sm:text-2xl",children:m}),s?e.jsx("p",{className:"mt-0.5 text-xs text-muted-foreground sm:text-sm",children:s}):null]}),t?e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:t}):null]})}export{n as H};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as l,j as e}from"./react-vendor-xnYrwzsL.js";import{u as ne,a as ie}from"./query-vendor-DVevaSVS.js";import{H as le}from"./Header-C_9Su9BF.js";import{C as B}from"./copy-button-qBvM6H9z.js";import{F as oe}from"./flip-button-BGgkjtl0.js";import{R as d}from"./ripple-button-l8aMiVVG.js";import{S as q}from"./StatusBadge-1nAOyHU2.js";import{d as ce,I as V,c as U,e as F,D as b,m as N,n as k,o as w,s as _,q as C,t as m,g as K}from"./index-B6j-9zHy.js";import{S as de}from"./skeleton-7uJDiIXe.js";import{g as ue,c as me,u as xe,a as he,l as ye}from"./api-keys-api-ifAC2Ok3.js";import{p as pe}from"./live-mode-CHShLY4E.js";import{m as A}from"./tunnel-api-DDPsBaDV.js";import{ac as $,q as fe,ah as je,a8 as G,a9 as J,ad as ge,af as W}from"./icons-vendor-CUx7SB5V.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";const ve=ce(n=>({keys:[],setKeys:i=>n({keys:i}),upsertKey:i=>n(u=>{const x=u.keys.findIndex(D=>D.id===i.id);if(x===-1)return{keys:[i,...u.keys]};const o=u.keys.slice();return o[x]={...o[x],...i},{keys:o}}),removeKey:i=>n(u=>({keys:u.keys.filter(x=>x.id!==i)}))}));function X(n){if(!n)return"—";try{return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}catch{return n}}function Ee(){const n=ne(),i=ve(s=>s.setKeys),[u,x]=l.useState(""),[o,D]=l.useState("active"),[Z,j]=l.useState(!1),[p,L]=l.useState(""),[h,g]=l.useState(!1),[S,I]=l.useState(null),[c,f]=l.useState(null),[a,v]=l.useState(null),[R,E]=l.useState(null),[P,ee]=l.useState(new Set),O=ie({queryKey:["api-keys",o],queryFn:()=>ye({includeRevoked:o==="paused"||o==="all"}),enabled:pe(),retry:!1}),y=O.data??[],se=O.isLoading;l.useEffect(()=>{i(y)},[y,i]);const Q=l.useMemo(()=>{const s=u.trim().toLowerCase();return y.filter(t=>{const r=t.isActive===!1;if(o==="active"&&r||o==="paused"&&!r)return!1;if(!s)return!0;const re=A(t.key||"");return t.name.toLowerCase().includes(s)||re.toLowerCase().includes(s)||(t.id||"").toLowerCase().includes(s)})},[y,u,o]);async function te(s){E(s.id);try{const t=await ue(s.id);if(!t){m.error("No stored secret for this key — create a new key to copy it.");return}await navigator.clipboard.writeText(t),m.success("Key copied to clipboard")}catch(t){m.error(K(t,"Failed to copy key"))}finally{E(null)}}function T(s){ee(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})}function H(){L(""),j(!0)}async function M(){if(p.trim()){g(!0);try{const s=await me({name:p.trim()});I(s.key.key||""),j(!1),await n.invalidateQueries({queryKey:["api-keys"]})}catch(s){m.error(K(s,"Failed to create key"))}finally{g(!1)}}}async function z(s){const t=!s.isActive;try{await xe(s.id,{isActive:t}),await n.invalidateQueries({queryKey:["api-keys"]}),m.success(t?"Key resumed":"Key paused")}catch(r){m.error(K(r,"Failed to update key"))}}async function ae(){if(c){g(!0);try{await he(c.id),await n.invalidateQueries({queryKey:["api-keys"]}),m.success("Key deleted"),f(null),(a==null?void 0:a.id)===c.id&&v(null)}catch(s){m.error(K(s,"Failed to delete key"))}finally{g(!1)}}}return e.jsxs("div",{className:"space-y-4",children:[e.jsx(le,{title:"API Keys",actions:y.length>0?e.jsxs(d,{size:"sm",onClick:H,children:[e.jsx($,{className:"h-4 w-4"}),"Create key"]}):null}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(fe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(V,{value:u,onChange:s=>x(s.target.value),placeholder:"Search name, key, id…",className:"pl-9"})]}),e.jsx("div",{className:"flex gap-1 rounded-lg border border-border bg-surface p-1",children:[["all","All"],["active","Active"],["paused","Paused"]].map(([s,t])=>e.jsx("button",{type:"button",onClick:()=>D(s),className:U("rounded-md px-3 py-1.5 text-xs font-medium transition-colors",o===s?"bg-white/15 text-foreground":"text-muted-foreground hover:text-foreground"),children:t},s))})]}),se?e.jsx("div",{className:"space-y-2",children:Array.from({length:3}).map((s,t)=>e.jsx(de,{className:"h-24 w-full rounded-xl"},t))}):y.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-2 rounded-xl border border-border px-4 py-16 text-center",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"No API keys found"}),e.jsxs(d,{size:"sm",onClick:H,children:[e.jsx($,{className:"h-4 w-4"}),"Create first key"]})]}):Q.length===0?e.jsx("div",{className:"rounded-xl border border-border px-4 py-16 text-center text-sm text-muted-foreground",children:"No API keys match the current filter."}):e.jsx("div",{className:"space-y-2",children:Q.map(s=>{const t=s.isActive===!1,r=P.has(s.id);return e.jsx("div",{className:U("group rounded-xl border border-border bg-card transition-colors hover:bg-card/80",t&&"opacity-60"),children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10",children:e.jsx(je,{className:"h-5 w-5 text-primary"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",className:"truncate text-sm font-medium hover:underline",onClick:()=>v(s),children:s.name}),e.jsx(q,{tone:t?"warn":"ok",className:"shrink-0",children:t?"Paused":"Active"}),s.isDefault?e.jsx(q,{tone:"muted",className:"shrink-0",children:"Default"}):null]}),e.jsxs("div",{className:"mt-1 flex items-center gap-1.5",children:[e.jsx("code",{className:"rounded bg-surface px-2 py-0.5 font-mono text-[11px] text-muted-foreground",children:r?s.key:A(s.key||"")}),e.jsx(F,{label:r?"Hide key":"Show key",children:e.jsx("button",{type:"button",onClick:()=>T(s.id),className:"rounded p-1 text-muted-foreground transition-colors hover:text-primary","aria-label":r?"Hide key":"Show key",children:r?e.jsx(G,{className:"h-3.5 w-3.5"}):e.jsx(J,{className:"h-3.5 w-3.5"})})}),e.jsx(F,{label:"Copy key",children:e.jsx("button",{type:"button",onClick:()=>void te(s),disabled:R===s.id,className:"rounded p-1 text-muted-foreground transition-colors hover:text-primary disabled:opacity-50","aria-label":"Copy key",children:R===s.id?e.jsx("span",{className:"text-[10px]",children:"…"}):e.jsx(ge,{className:"h-3.5 w-3.5"})})})]}),e.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["Created ",X(s.createdAt),s.machineId?` · machine ${s.machineId}`:""]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(oe,{active:!t,onToggle:()=>void z(s),activeLabel:"",inactiveLabel:""}),s.isDefault?null:e.jsx(F,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>f(s),"aria-label":"Delete",children:e.jsx(W,{className:"h-3.5 w-3.5"})})})]})]})},s.id)})}),e.jsx(b,{open:Z,onOpenChange:s=>{s||j(!1)},children:e.jsxs(N,{children:[e.jsxs(k,{children:[e.jsx(w,{children:"Create API key"}),e.jsx(_,{children:"The full key is shown once after creation — store it securely."})]}),e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Key name"}),e.jsx(V,{value:p,onChange:s=>L(s.target.value),placeholder:"my-app",autoFocus:!0,onKeyDown:s=>{s.key==="Enter"&&p.trim()&&!h&&M()}})]}),e.jsxs(C,{children:[e.jsx(d,{variant:"outline",onClick:()=>j(!1),disabled:h,children:"Cancel"}),e.jsx(d,{onClick:()=>void M(),disabled:!p.trim()||h,children:h?"Creating…":"Create key"})]})]})}),e.jsx(b,{open:!!S,onOpenChange:()=>I(null),children:e.jsxs(N,{children:[e.jsx(k,{children:e.jsx(w,{children:"API Key Created"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-warning/40 bg-warning/10 p-4",children:[e.jsx("p",{className:"mb-2 text-sm font-medium text-warning",children:"Save this key now!"}),e.jsx("p",{className:"text-sm text-warning/80",children:"This is the only time you will see the full key."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all rounded-md border border-border bg-surface px-3 py-2 font-mono text-sm",children:S}),e.jsx(B,{value:S||"",label:""})]}),e.jsx(C,{children:e.jsx(d,{onClick:()=>I(null),children:"Done"})})]})]})}),e.jsx(b,{open:!!c,onOpenChange:s=>{s||f(null)},children:e.jsxs(N,{children:[e.jsxs(k,{children:[e.jsx(w,{children:"Delete API key?"}),e.jsxs(_,{children:[e.jsx("span",{className:"font-medium text-foreground",children:c==null?void 0:c.name})," ","(",A((c==null?void 0:c.key)||""),") will be permanently removed."]})]}),e.jsxs(C,{children:[e.jsx(d,{variant:"outline",onClick:()=>f(null),disabled:h,children:"Cancel"}),e.jsx(d,{variant:"destructive",onClick:()=>void ae(),disabled:h,children:h?"Deleting…":"Delete permanently"})]})]})}),e.jsx(b,{open:!!a,onOpenChange:s=>{s||v(null)},children:e.jsx(N,{children:a?e.jsxs(e.Fragment,{children:[e.jsx(k,{children:e.jsxs(w,{className:"flex items-center gap-2",children:[a.name,e.jsx(q,{tone:a.isActive===!1?"warn":"ok",children:a.isActive===!1?"Paused":"Active"})]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(Y,{label:"Created",value:X(a.createdAt)}),e.jsx(Y,{label:"Machine",value:a.machineId||"—"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground",children:"Key"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all rounded-md border border-border bg-surface px-3 py-2 font-mono text-xs",children:P.has(a.id)?a.key:A(a.key||"")}),e.jsx(d,{variant:"outline",size:"sm",onClick:()=>T(a.id),children:P.has(a.id)?e.jsx(G,{className:"h-3.5 w-3.5"}):e.jsx(J,{className:"h-3.5 w-3.5"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{value:a.key||"",label:"Copy key"}),e.jsx(d,{variant:"outline",size:"sm",onClick:()=>void z(a),children:a.isActive===!1?"Resume":"Pause"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Use this key with the gateway endpoint to route LLM requests. Requests without a valid key are rejected when "Require API key" is on.'})]}),e.jsx(C,{children:a.isDefault?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Default keys cannot be deleted. Revoke or rotate the secret instead."}):e.jsxs(d,{variant:"destructive",onClick:()=>{f(a),v(null)},children:[e.jsx(W,{className:"h-3.5 w-3.5"}),"Delete"]})})]}):null})})]})}function Y({label:n,value:i}){return e.jsxs("div",{className:"rounded-md border border-border bg-surface px-3 py-2",children:[e.jsx("div",{className:"text-[11px] text-muted-foreground",children:n}),e.jsx("div",{className:"truncate text-sm font-medium",children:i})]})}export{Ee as default};
|
|
1
|
+
import{r as l,j as e}from"./react-vendor-xnYrwzsL.js";import{u as ne,a as ie}from"./query-vendor-DVevaSVS.js";import{H as le}from"./Header-CbIOa7_e.js";import{C as B}from"./copy-button-qyO_CuV_.js";import{F as oe}from"./flip-button-B2KSTFMN.js";import{R as d}from"./ripple-button-CrrjyO-q.js";import{S as q}from"./StatusBadge-jJWHijDc.js";import{d as ce,I as V,c as U,e as F,D as b,m as N,n as k,o as w,s as _,q as C,t as m,g as K}from"./index-BCs8FaU-.js";import{S as de}from"./skeleton-BeyFFj7e.js";import{g as ue,c as me,u as xe,a as he,l as ye}from"./api-keys-api-Dw9L6TTr.js";import{p as pe}from"./live-mode-CHShLY4E.js";import{m as A}from"./tunnel-api-CCeqJWO5.js";import{ac as $,q as fe,ah as je,a8 as G,a9 as J,ad as ge,af as W}from"./icons-vendor-CUx7SB5V.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";const ve=ce(n=>({keys:[],setKeys:i=>n({keys:i}),upsertKey:i=>n(u=>{const x=u.keys.findIndex(D=>D.id===i.id);if(x===-1)return{keys:[i,...u.keys]};const o=u.keys.slice();return o[x]={...o[x],...i},{keys:o}}),removeKey:i=>n(u=>({keys:u.keys.filter(x=>x.id!==i)}))}));function X(n){if(!n)return"—";try{return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}catch{return n}}function Ee(){const n=ne(),i=ve(s=>s.setKeys),[u,x]=l.useState(""),[o,D]=l.useState("active"),[Z,j]=l.useState(!1),[p,L]=l.useState(""),[h,g]=l.useState(!1),[S,I]=l.useState(null),[c,f]=l.useState(null),[a,v]=l.useState(null),[R,E]=l.useState(null),[P,ee]=l.useState(new Set),O=ie({queryKey:["api-keys",o],queryFn:()=>ye({includeRevoked:o==="paused"||o==="all"}),enabled:pe(),retry:!1}),y=O.data??[],se=O.isLoading;l.useEffect(()=>{i(y)},[y,i]);const Q=l.useMemo(()=>{const s=u.trim().toLowerCase();return y.filter(t=>{const r=t.isActive===!1;if(o==="active"&&r||o==="paused"&&!r)return!1;if(!s)return!0;const re=A(t.key||"");return t.name.toLowerCase().includes(s)||re.toLowerCase().includes(s)||(t.id||"").toLowerCase().includes(s)})},[y,u,o]);async function te(s){E(s.id);try{const t=await ue(s.id);if(!t){m.error("No stored secret for this key — create a new key to copy it.");return}await navigator.clipboard.writeText(t),m.success("Key copied to clipboard")}catch(t){m.error(K(t,"Failed to copy key"))}finally{E(null)}}function T(s){ee(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})}function H(){L(""),j(!0)}async function M(){if(p.trim()){g(!0);try{const s=await me({name:p.trim()});I(s.key.key||""),j(!1),await n.invalidateQueries({queryKey:["api-keys"]})}catch(s){m.error(K(s,"Failed to create key"))}finally{g(!1)}}}async function z(s){const t=!s.isActive;try{await xe(s.id,{isActive:t}),await n.invalidateQueries({queryKey:["api-keys"]}),m.success(t?"Key resumed":"Key paused")}catch(r){m.error(K(r,"Failed to update key"))}}async function ae(){if(c){g(!0);try{await he(c.id),await n.invalidateQueries({queryKey:["api-keys"]}),m.success("Key deleted"),f(null),(a==null?void 0:a.id)===c.id&&v(null)}catch(s){m.error(K(s,"Failed to delete key"))}finally{g(!1)}}}return e.jsxs("div",{className:"space-y-4",children:[e.jsx(le,{title:"API Keys",actions:y.length>0?e.jsxs(d,{size:"sm",onClick:H,children:[e.jsx($,{className:"h-4 w-4"}),"Create key"]}):null}),e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(fe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(V,{value:u,onChange:s=>x(s.target.value),placeholder:"Search name, key, id…",className:"pl-9"})]}),e.jsx("div",{className:"flex gap-1 rounded-lg border border-border bg-surface p-1",children:[["all","All"],["active","Active"],["paused","Paused"]].map(([s,t])=>e.jsx("button",{type:"button",onClick:()=>D(s),className:U("rounded-md px-3 py-1.5 text-xs font-medium transition-colors",o===s?"bg-white/15 text-foreground":"text-muted-foreground hover:text-foreground"),children:t},s))})]}),se?e.jsx("div",{className:"space-y-2",children:Array.from({length:3}).map((s,t)=>e.jsx(de,{className:"h-24 w-full rounded-xl"},t))}):y.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-2 rounded-xl border border-border px-4 py-16 text-center",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"No API keys found"}),e.jsxs(d,{size:"sm",onClick:H,children:[e.jsx($,{className:"h-4 w-4"}),"Create first key"]})]}):Q.length===0?e.jsx("div",{className:"rounded-xl border border-border px-4 py-16 text-center text-sm text-muted-foreground",children:"No API keys match the current filter."}):e.jsx("div",{className:"space-y-2",children:Q.map(s=>{const t=s.isActive===!1,r=P.has(s.id);return e.jsx("div",{className:U("group rounded-xl border border-border bg-card transition-colors hover:bg-card/80",t&&"opacity-60"),children:e.jsxs("div",{className:"flex items-center gap-4 p-4",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10",children:e.jsx(je,{className:"h-5 w-5 text-primary"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",className:"truncate text-sm font-medium hover:underline",onClick:()=>v(s),children:s.name}),e.jsx(q,{tone:t?"warn":"ok",className:"shrink-0",children:t?"Paused":"Active"}),s.isDefault?e.jsx(q,{tone:"muted",className:"shrink-0",children:"Default"}):null]}),e.jsxs("div",{className:"mt-1 flex items-center gap-1.5",children:[e.jsx("code",{className:"rounded bg-surface px-2 py-0.5 font-mono text-[11px] text-muted-foreground",children:r?s.key:A(s.key||"")}),e.jsx(F,{label:r?"Hide key":"Show key",children:e.jsx("button",{type:"button",onClick:()=>T(s.id),className:"rounded p-1 text-muted-foreground transition-colors hover:text-primary","aria-label":r?"Hide key":"Show key",children:r?e.jsx(G,{className:"h-3.5 w-3.5"}):e.jsx(J,{className:"h-3.5 w-3.5"})})}),e.jsx(F,{label:"Copy key",children:e.jsx("button",{type:"button",onClick:()=>void te(s),disabled:R===s.id,className:"rounded p-1 text-muted-foreground transition-colors hover:text-primary disabled:opacity-50","aria-label":"Copy key",children:R===s.id?e.jsx("span",{className:"text-[10px]",children:"…"}):e.jsx(ge,{className:"h-3.5 w-3.5"})})})]}),e.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["Created ",X(s.createdAt),s.machineId?` · machine ${s.machineId}`:""]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(oe,{active:!t,onToggle:()=>void z(s),activeLabel:"",inactiveLabel:""}),s.isDefault?null:e.jsx(F,{label:"Delete",children:e.jsx("button",{type:"button",className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border text-muted-foreground hover:border-destructive/40 hover:bg-destructive/10 hover:text-destructive",onClick:()=>f(s),"aria-label":"Delete",children:e.jsx(W,{className:"h-3.5 w-3.5"})})})]})]})},s.id)})}),e.jsx(b,{open:Z,onOpenChange:s=>{s||j(!1)},children:e.jsxs(N,{children:[e.jsxs(k,{children:[e.jsx(w,{children:"Create API key"}),e.jsx(_,{children:"The full key is shown once after creation — store it securely."})]}),e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Key name"}),e.jsx(V,{value:p,onChange:s=>L(s.target.value),placeholder:"my-app",autoFocus:!0,onKeyDown:s=>{s.key==="Enter"&&p.trim()&&!h&&M()}})]}),e.jsxs(C,{children:[e.jsx(d,{variant:"outline",onClick:()=>j(!1),disabled:h,children:"Cancel"}),e.jsx(d,{onClick:()=>void M(),disabled:!p.trim()||h,children:h?"Creating…":"Create key"})]})]})}),e.jsx(b,{open:!!S,onOpenChange:()=>I(null),children:e.jsxs(N,{children:[e.jsx(k,{children:e.jsx(w,{children:"API Key Created"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-warning/40 bg-warning/10 p-4",children:[e.jsx("p",{className:"mb-2 text-sm font-medium text-warning",children:"Save this key now!"}),e.jsx("p",{className:"text-sm text-warning/80",children:"This is the only time you will see the full key."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all rounded-md border border-border bg-surface px-3 py-2 font-mono text-sm",children:S}),e.jsx(B,{value:S||"",label:""})]}),e.jsx(C,{children:e.jsx(d,{onClick:()=>I(null),children:"Done"})})]})]})}),e.jsx(b,{open:!!c,onOpenChange:s=>{s||f(null)},children:e.jsxs(N,{children:[e.jsxs(k,{children:[e.jsx(w,{children:"Delete API key?"}),e.jsxs(_,{children:[e.jsx("span",{className:"font-medium text-foreground",children:c==null?void 0:c.name})," ","(",A((c==null?void 0:c.key)||""),") will be permanently removed."]})]}),e.jsxs(C,{children:[e.jsx(d,{variant:"outline",onClick:()=>f(null),disabled:h,children:"Cancel"}),e.jsx(d,{variant:"destructive",onClick:()=>void ae(),disabled:h,children:h?"Deleting…":"Delete permanently"})]})]})}),e.jsx(b,{open:!!a,onOpenChange:s=>{s||v(null)},children:e.jsx(N,{children:a?e.jsxs(e.Fragment,{children:[e.jsx(k,{children:e.jsxs(w,{className:"flex items-center gap-2",children:[a.name,e.jsx(q,{tone:a.isActive===!1?"warn":"ok",children:a.isActive===!1?"Paused":"Active"})]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(Y,{label:"Created",value:X(a.createdAt)}),e.jsx(Y,{label:"Machine",value:a.machineId||"—"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground",children:"Key"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all rounded-md border border-border bg-surface px-3 py-2 font-mono text-xs",children:P.has(a.id)?a.key:A(a.key||"")}),e.jsx(d,{variant:"outline",size:"sm",onClick:()=>T(a.id),children:P.has(a.id)?e.jsx(G,{className:"h-3.5 w-3.5"}):e.jsx(J,{className:"h-3.5 w-3.5"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{value:a.key||"",label:"Copy key"}),e.jsx(d,{variant:"outline",size:"sm",onClick:()=>void z(a),children:a.isActive===!1?"Resume":"Pause"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Use this key with the gateway endpoint to route LLM requests. Requests without a valid key are rejected when "Require API key" is on.'})]}),e.jsx(C,{children:a.isDefault?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Default keys cannot be deleted. Revoke or rotate the secret instead."}):e.jsxs(d,{variant:"destructive",onClick:()=>{f(a),v(null)},children:[e.jsx(W,{className:"h-3.5 w-3.5"}),"Delete"]})})]}):null})})]})}function Y({label:n,value:i}){return e.jsxs("div",{className:"rounded-md border border-border bg-surface px-3 py-2",children:[e.jsx("div",{className:"text-[11px] text-muted-foreground",children:n}),e.jsx("div",{className:"truncate text-sm font-medium",children:i})]})}export{Ee as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as b,r as t,j as e}from"./react-vendor-xnYrwzsL.js";import{u as d,f as j,I as v,T as N,l as y,g as S}from"./index-BCs8FaU-.js";import{R as P}from"./ripple-button-CrrjyO-q.js";import{C,a as A,b as E,c as T}from"./card-BL-4tjF7.js";import{a8 as R,a9 as k}from"./icons-vendor-CUx7SB5V.js";import"./query-vendor-DVevaSVS.js";import"./ui-vendor-BuM9f2NY.js";import"./motion-vendor-g5fpGzmJ.js";function B(){const n=b(),m=d(s=>s.setToken),f=d(s=>s.setAuthMeta),[l,h]=t.useState(""),[a,x]=t.useState(!1),[i,u]=t.useState(!1),[o,c]=t.useState(null),[p,g]=t.useState(!1);t.useEffect(()=>{let s=!1;return j().then(r=>{s||g(r.defaultPasswordActive)}).catch(()=>{}),()=>{s=!0}},[]);async function w(s){s.preventDefault(),u(!0),c(null);try{if((await y(l)).mustChangePassword){n("/setup",{replace:!0});return}m("dashboard-session"),f({authenticated:!0,hasPassword:!0}),n("/dashboard",{replace:!0})}catch(r){c(S(r,"Login failed"))}finally{u(!1)}}return e.jsx("div",{className:"flex min-h-svh w-full items-center justify-center bg-background p-4",children:e.jsxs(C,{className:"w-full max-w-sm border-border bg-card",children:[e.jsxs(A,{className:"text-center",children:[e.jsx("img",{src:"/logo/sway.svg",alt:"Sway Router",className:"mx-auto mb-2 h-12 w-12 rounded-xl object-contain"}),e.jsx(E,{className:"text-xl",children:"Sway Router"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Dashboard login"})]}),e.jsx(T,{children:e.jsxs("form",{onSubmit:w,className:"space-y-4",children:[e.jsxs("div",{className:"relative",children:[e.jsx(v,{type:a?"text":"password",placeholder:"Password",value:l,onChange:s=>h(s.target.value),autoComplete:"current-password",autoFocus:!0,required:!0,className:"pr-10"}),e.jsx("button",{type:"button",onClick:()=>x(!a),className:"absolute right-1 top-1/2 grid size-8 -translate-y-1/2 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-surface-hover hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring","aria-label":a?"Hide password":"Show password","aria-pressed":a,children:a?e.jsx(R,{className:"h-4 w-4"}):e.jsx(k,{className:"h-4 w-4"})})]}),p&&!o?e.jsxs("p",{className:"text-xs text-muted-foreground",children:["First login? The default password is"," ",e.jsx("code",{className:"rounded bg-surface px-1 py-0.5 font-mono text-xs",children:"123456"}),". Set a new one after signing in."]}):null,o?e.jsx("p",{className:"text-sm text-destructive",children:o}):null,e.jsx(P,{type:"submit",className:"w-full",disabled:i,children:i?e.jsx(N,{children:"Authenticating…"}):"Login"})]})})]})})}export{B as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,r as i}from"./react-vendor-xnYrwzsL.js";import{u as se,a as te}from"./query-vendor-DVevaSVS.js";import{H as ae}from"./Header-C_9Su9BF.js";import{C as re}from"./copy-button-qBvM6H9z.js";import{F as ie}from"./flip-button-BGgkjtl0.js";import{R as c}from"./ripple-button-l8aMiVVG.js";import{S as M}from"./StatusBadge-1nAOyHU2.js";import{F as ne,a as le,b as oe,c as de}from"./frame-cUiti6Lq.js";import{c as z,e as h,D as C,m as K,n as A,o as k,I as ce,q as R,s as me,t as o,g as m}from"./index-B6j-9zHy.js";import{K as xe}from"./ui-vendor-BuM9f2NY.js";import{S as ue}from"./skeleton-7uJDiIXe.js";import{p as pe}from"./live-mode-CHShLY4E.js";import{d as he,c as ye,a as fe,u as je,r as ge,g as be,l as ve}from"./api-keys-api-ifAC2Ok3.js";import{ac as we,ad as Q,L as U,ae as Ne,af as Ce,a8 as Ke,a9 as Ae,ag as ke}from"./icons-vendor-CUx7SB5V.js";import"./motion-vendor-g5fpGzmJ.js";function Re({className:y,orientation:x="horizontal",...d}){return e.jsx(xe,{className:z("shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:not-[[class^='h-']]:not-[[class*='_h-']]:self-stretch",y),"data-slot":"separator",orientation:x,...d})}function ze(){const y=se(),[x,d]=i.useState([]),[O,D]=i.useState(!0),[G,u]=i.useState(!1),[f,I]=i.useState(""),[b,j]=i.useState(null),[v,S]=i.useState(!1),[P,F]=i.useState(null),[r,l]=i.useState(null),[V,g]=i.useState(new Set),[w,L]=i.useState({}),[T,E]=i.useState(null),[N,q]=i.useState(null),[B,_]=i.useState("/v1"),p=te({queryKey:["api-keys-endpoint"],queryFn:()=>ve({includeRevoked:!0}),enabled:pe(),retry:!1});i.useEffect(()=>{typeof window<"u"&&_(`${window.location.origin}/v1`)},[]),i.useEffect(()=>{p.data?(d(p.data),D(!1)):p.isLoading&&D(!0)},[p.data,p.isLoading]);const J=async()=>{if(f.trim()){S(!0);try{const s=await ye({name:f.trim()});d(t=>[s.key,...t]),j(s.key.key||""),I(""),u(!1),await y.invalidateQueries({queryKey:["api-keys-endpoint"]})}catch(s){o.error(m(s,"Failed to create key"))}finally{S(!1)}}},W=s=>{if(s.isDefault){o.info("The default key cannot be deleted. Revoke or rotate it instead.");return}l({title:"Delete API key",message:`Permanently remove “${s.name}”? Any clients using it will stop working.`,confirmLabel:"Delete permanently",destructive:!0,onConfirm:async()=>{l(null);try{await fe(s.id),d(t=>t.filter(a=>a.id!==s.id))}catch(t){o.error(m(t,"Failed to delete key"))}}})},X=s=>l({title:s.isActive?"Revoke API key":"Restore API key",message:s.isActive?`Revoke “${s.name}”? Requests using this key will be rejected, but the key can be restored later.`:`Restore “${s.name}”? Requests using this key will be accepted again.`,confirmLabel:s.isActive?"Revoke key":"Restore key",destructive:s.isActive,onConfirm:async()=>{l(null);const t=!s.isActive;try{await je(s.id,{isActive:t}),d(a=>a.map(n=>n.id===s.id?{...n,isActive:t}:n))}catch(a){o.error(m(a,"Failed to update key"))}}}),Y=s=>l({title:"Rotate API key",message:`Generate a new secret for “${s.name}”? The old secret will stop working immediately while the key identity stays the same.`,confirmLabel:"Rotate secret",destructive:!0,onConfirm:async()=>{l(null),F(s.id);try{const t=await ge(s.id);d(a=>a.map(n=>n.id===s.id?t:n)),L(a=>{const n={...a};return delete n[s.id],n}),g(a=>{const n=new Set(a);return n.delete(s.id),n}),j(t.key||""),await y.invalidateQueries({queryKey:["api-keys-endpoint"]}),o.success("Key rotated — replace the old secret in your clients.")}catch(t){o.error(m(t,"Failed to rotate key"))}finally{F(null)}}}),H=async s=>{const t=await be(s.id);if(!t)throw new Error("This key has no stored secret.");return L(a=>({...a,[s.id]:t})),t},Z=async s=>{if(w[s.id]){g(t=>new Set(t).add(s.id));return}try{await H(s),g(t=>new Set(t).add(s.id))}catch(t){o.error(m(t,"Failed to reveal key"))}},ee=async s=>{q(s.id);try{await navigator.clipboard.writeText(w[s.id]||await H(s)),E(s.id),window.setTimeout(()=>E(null),1500)}catch(t){o.error(m(t,"Failed to copy key"))}finally{q(null)}};return e.jsxs("div",{className:"space-y-5",children:[e.jsx(ae,{title:"API Keys",actions:x.length>0?e.jsxs(c,{onClick:()=>u(!0),children:[e.jsx(we,{className:"h-4 w-4"}),"Create key"]}):null}),e.jsxs(ne,{className:"w-full",children:[e.jsx(le,{className:"px-3 py-3 sm:px-5 sm:py-4",children:e.jsx(oe,{children:"Manage API Keys"})}),e.jsxs(de,{className:"p-0",children:[e.jsxs("div",{className:"flex flex-col gap-2.5 p-3 sm:flex-row sm:items-center sm:justify-between sm:gap-4 sm:p-5",children:[e.jsx("div",{className:"min-w-0",children:e.jsx("p",{className:"text-sm font-semibold",children:"Base URL"})}),e.jsxs("div",{className:"flex min-w-0 items-center gap-2 rounded-lg border border-border bg-surface px-2.5 py-1.5 sm:px-3 sm:py-2",children:[e.jsx("code",{className:"min-w-0 flex-1 truncate font-mono text-[11px] sm:text-xs",children:B}),e.jsx(h,{label:"Copy gateway URL",children:e.jsx("button",{type:"button",onClick:()=>void navigator.clipboard.writeText(B),className:"shrink-0 rounded-md p-1.5 text-muted-foreground hover:bg-surface-hover hover:text-primary","aria-label":"Copy gateway URL",children:e.jsx(Q,{className:"h-3.5 w-3.5"})})})]})]}),e.jsx(Re,{}),e.jsxs("div",{className:"p-3 sm:p-5",children:[e.jsx("div",{className:"min-w-0",children:e.jsx("p",{className:"text-sm font-semibold",children:"List API Keys"})}),e.jsx("div",{className:"mt-3 sm:mt-4",children:O?e.jsx("div",{className:"space-y-2",children:[0,1].map(s=>e.jsx(ue,{className:"h-16 rounded-xl sm:h-20"},s))}):x.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed border-border px-4 py-8 text-center sm:px-5 sm:py-10",children:[e.jsx("p",{className:"text-sm font-medium",children:"No API keys yet"}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground sm:text-sm",children:"Create an API key to connect your AI tools to this gateway."}),e.jsx(c,{className:"mt-4",size:"sm",onClick:()=>u(!0),children:"Create first key"})]}):e.jsx("div",{className:"space-y-1.5 sm:space-y-2",children:x.map(s=>{const t=s.isActive===!1,a=V.has(s.id);return e.jsxs("div",{className:z("rounded-lg border border-border bg-surface p-2.5 sm:p-3",t&&"opacity-65"),children:[e.jsxs("div",{className:"flex items-start justify-between gap-2.5 sm:gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 sm:gap-2",children:[e.jsx("p",{className:"truncate text-xs font-medium sm:text-sm",children:s.name}),s.isDefault?e.jsx(M,{tone:"muted",className:"text-[10px] sm:text-xs",children:"Default"}):null,e.jsx(M,{tone:t?"warn":"ok",className:"text-[10px] sm:text-xs",children:t?"Revoked":"Active"})]}),e.jsxs("p",{className:"mt-0.5 text-[10px] text-muted-foreground sm:mt-1 sm:text-xs",children:["Created ",new Date(s.createdAt||Date.now()).toLocaleDateString()]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-0.5 sm:gap-1",children:[e.jsx(ie,{active:!t,onToggle:()=>X(s)}),e.jsx(h,{label:"Rotate secret",children:e.jsx("button",{type:"button",onClick:()=>Y(s),disabled:P===s.id,className:"rounded-md p-1.5 text-muted-foreground hover:bg-surface-hover hover:text-primary disabled:opacity-50 sm:p-2","aria-label":"Rotate secret",children:P===s.id?e.jsx(U,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ne,{className:"h-3.5 w-3.5"})})}),s.isDefault?null:e.jsx(h,{label:"Delete key",children:e.jsx("button",{type:"button",onClick:()=>W(s),className:"rounded-md p-1.5 text-muted-foreground hover:bg-destructive/10 hover:text-destructive sm:p-2","aria-label":"Delete key",children:e.jsx(Ce,{className:"h-3.5 w-3.5"})})})]})]}),e.jsxs("div",{className:"mt-2 flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1 sm:mt-3 sm:gap-2 sm:px-2.5 sm:py-1.5",children:[e.jsx("code",{className:"min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground sm:text-xs",children:a?w[s.id]||s.key:he(s)}),e.jsx(h,{label:a?"Hide key":"Show key",children:e.jsx("button",{type:"button",onClick:()=>a?g(n=>{const $=new Set(n);return $.delete(s.id),$}):void Z(s),className:"rounded-md p-1 text-muted-foreground hover:bg-surface-hover hover:text-primary sm:p-1.5","aria-label":a?"Hide key":"Show key",children:a?e.jsx(Ke,{className:"h-3.5 w-3.5"}):e.jsx(Ae,{className:"h-3.5 w-3.5"})})}),e.jsx(h,{label:N===s.id?"Copying key":T===s.id?"Copied":"Copy key",children:e.jsx("button",{type:"button",onClick:()=>void ee(s),disabled:N===s.id,className:"rounded-md p-1 text-muted-foreground hover:bg-surface-hover hover:text-primary sm:p-1.5","aria-label":"Copy key",children:N===s.id?e.jsx(U,{className:"h-3.5 w-3.5 animate-spin"}):T===s.id?e.jsx(ke,{className:"h-3.5 w-3.5 text-success"}):e.jsx(Q,{className:"h-3.5 w-3.5"})})})]})]},s.id)})})})]})]})]}),e.jsx(C,{open:G,onOpenChange:u,children:e.jsxs(K,{children:[e.jsx(A,{className:"pb-2",children:e.jsx(k,{children:"Create API key"})}),e.jsx("div",{className:"px-6 pb-2",children:e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Key name"}),e.jsx(ce,{value:f,onChange:s=>I(s.target.value),placeholder:"Production",autoFocus:!0})]})}),e.jsxs(R,{children:[e.jsx(c,{variant:"outline",onClick:()=>u(!1),disabled:v,children:"Cancel"}),e.jsx(c,{onClick:()=>void J(),disabled:!f.trim()||v,children:v?"Creating…":"Create"})]})]})}),e.jsx(C,{open:!!b,onOpenChange:()=>j(null),children:e.jsxs(K,{children:[e.jsxs(A,{children:[e.jsx(k,{children:"API key ready"}),e.jsx(me,{children:"Copy this secret now and update your clients. It is the current secret for this key."})]}),e.jsx("div",{className:"space-y-3 px-6 pb-2",children:e.jsxs("div",{className:"flex items-center gap-2 rounded-xl border border-primary/20 bg-primary/5 p-3",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all font-mono text-sm",children:b}),e.jsx(re,{value:b||"",label:""})]})}),e.jsx(R,{children:e.jsx(c,{onClick:()=>j(null),children:"Done"})})]})}),e.jsx(C,{open:!!r,onOpenChange:s=>!s&&l(null),children:e.jsxs(K,{children:[e.jsx(A,{children:e.jsx(k,{children:(r==null?void 0:r.title)||"Confirm"})}),e.jsx("p",{className:"px-6 pb-3 text-sm leading-relaxed text-muted-foreground",children:r==null?void 0:r.message}),e.jsxs(R,{children:[e.jsx(c,{variant:"outline",onClick:()=>l(null),children:"Cancel"}),e.jsx(c,{variant:r!=null&&r.destructive?"destructive":"default",onClick:()=>r==null?void 0:r.onConfirm(),children:(r==null?void 0:r.confirmLabel)||"Confirm"})]})]})})]})}export{ze as default};
|
|
1
|
+
import{j as e,r as i}from"./react-vendor-xnYrwzsL.js";import{u as se,a as te}from"./query-vendor-DVevaSVS.js";import{H as ae}from"./Header-CbIOa7_e.js";import{C as re}from"./copy-button-qyO_CuV_.js";import{F as ie}from"./flip-button-B2KSTFMN.js";import{R as c}from"./ripple-button-CrrjyO-q.js";import{S as M}from"./StatusBadge-jJWHijDc.js";import{F as ne,a as le,b as oe,c as de}from"./frame-1zkYd9EK.js";import{c as z,e as h,D as C,m as K,n as A,o as k,I as ce,q as R,s as me,t as o,g as m}from"./index-BCs8FaU-.js";import{K as xe}from"./ui-vendor-BuM9f2NY.js";import{S as ue}from"./skeleton-BeyFFj7e.js";import{p as pe}from"./live-mode-CHShLY4E.js";import{d as he,c as ye,a as fe,u as je,r as ge,g as be,l as ve}from"./api-keys-api-Dw9L6TTr.js";import{ac as we,ad as Q,L as U,ae as Ne,af as Ce,a8 as Ke,a9 as Ae,ag as ke}from"./icons-vendor-CUx7SB5V.js";import"./motion-vendor-g5fpGzmJ.js";function Re({className:y,orientation:x="horizontal",...d}){return e.jsx(xe,{className:z("shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:not-[[class^='h-']]:not-[[class*='_h-']]:self-stretch",y),"data-slot":"separator",orientation:x,...d})}function ze(){const y=se(),[x,d]=i.useState([]),[O,D]=i.useState(!0),[G,u]=i.useState(!1),[f,I]=i.useState(""),[b,j]=i.useState(null),[v,S]=i.useState(!1),[P,F]=i.useState(null),[r,l]=i.useState(null),[V,g]=i.useState(new Set),[w,L]=i.useState({}),[T,E]=i.useState(null),[N,q]=i.useState(null),[B,_]=i.useState("/v1"),p=te({queryKey:["api-keys-endpoint"],queryFn:()=>ve({includeRevoked:!0}),enabled:pe(),retry:!1});i.useEffect(()=>{typeof window<"u"&&_(`${window.location.origin}/v1`)},[]),i.useEffect(()=>{p.data?(d(p.data),D(!1)):p.isLoading&&D(!0)},[p.data,p.isLoading]);const J=async()=>{if(f.trim()){S(!0);try{const s=await ye({name:f.trim()});d(t=>[s.key,...t]),j(s.key.key||""),I(""),u(!1),await y.invalidateQueries({queryKey:["api-keys-endpoint"]})}catch(s){o.error(m(s,"Failed to create key"))}finally{S(!1)}}},W=s=>{if(s.isDefault){o.info("The default key cannot be deleted. Revoke or rotate it instead.");return}l({title:"Delete API key",message:`Permanently remove “${s.name}”? Any clients using it will stop working.`,confirmLabel:"Delete permanently",destructive:!0,onConfirm:async()=>{l(null);try{await fe(s.id),d(t=>t.filter(a=>a.id!==s.id))}catch(t){o.error(m(t,"Failed to delete key"))}}})},X=s=>l({title:s.isActive?"Revoke API key":"Restore API key",message:s.isActive?`Revoke “${s.name}”? Requests using this key will be rejected, but the key can be restored later.`:`Restore “${s.name}”? Requests using this key will be accepted again.`,confirmLabel:s.isActive?"Revoke key":"Restore key",destructive:s.isActive,onConfirm:async()=>{l(null);const t=!s.isActive;try{await je(s.id,{isActive:t}),d(a=>a.map(n=>n.id===s.id?{...n,isActive:t}:n))}catch(a){o.error(m(a,"Failed to update key"))}}}),Y=s=>l({title:"Rotate API key",message:`Generate a new secret for “${s.name}”? The old secret will stop working immediately while the key identity stays the same.`,confirmLabel:"Rotate secret",destructive:!0,onConfirm:async()=>{l(null),F(s.id);try{const t=await ge(s.id);d(a=>a.map(n=>n.id===s.id?t:n)),L(a=>{const n={...a};return delete n[s.id],n}),g(a=>{const n=new Set(a);return n.delete(s.id),n}),j(t.key||""),await y.invalidateQueries({queryKey:["api-keys-endpoint"]}),o.success("Key rotated — replace the old secret in your clients.")}catch(t){o.error(m(t,"Failed to rotate key"))}finally{F(null)}}}),H=async s=>{const t=await be(s.id);if(!t)throw new Error("This key has no stored secret.");return L(a=>({...a,[s.id]:t})),t},Z=async s=>{if(w[s.id]){g(t=>new Set(t).add(s.id));return}try{await H(s),g(t=>new Set(t).add(s.id))}catch(t){o.error(m(t,"Failed to reveal key"))}},ee=async s=>{q(s.id);try{await navigator.clipboard.writeText(w[s.id]||await H(s)),E(s.id),window.setTimeout(()=>E(null),1500)}catch(t){o.error(m(t,"Failed to copy key"))}finally{q(null)}};return e.jsxs("div",{className:"space-y-5",children:[e.jsx(ae,{title:"API Keys",actions:x.length>0?e.jsxs(c,{onClick:()=>u(!0),children:[e.jsx(we,{className:"h-4 w-4"}),"Create key"]}):null}),e.jsxs(ne,{className:"w-full",children:[e.jsx(le,{className:"px-3 py-3 sm:px-5 sm:py-4",children:e.jsx(oe,{children:"Manage API Keys"})}),e.jsxs(de,{className:"p-0",children:[e.jsxs("div",{className:"flex flex-col gap-2.5 p-3 sm:flex-row sm:items-center sm:justify-between sm:gap-4 sm:p-5",children:[e.jsx("div",{className:"min-w-0",children:e.jsx("p",{className:"text-sm font-semibold",children:"Base URL"})}),e.jsxs("div",{className:"flex min-w-0 items-center gap-2 rounded-lg border border-border bg-surface px-2.5 py-1.5 sm:px-3 sm:py-2",children:[e.jsx("code",{className:"min-w-0 flex-1 truncate font-mono text-[11px] sm:text-xs",children:B}),e.jsx(h,{label:"Copy gateway URL",children:e.jsx("button",{type:"button",onClick:()=>void navigator.clipboard.writeText(B),className:"shrink-0 rounded-md p-1.5 text-muted-foreground hover:bg-surface-hover hover:text-primary","aria-label":"Copy gateway URL",children:e.jsx(Q,{className:"h-3.5 w-3.5"})})})]})]}),e.jsx(Re,{}),e.jsxs("div",{className:"p-3 sm:p-5",children:[e.jsx("div",{className:"min-w-0",children:e.jsx("p",{className:"text-sm font-semibold",children:"List API Keys"})}),e.jsx("div",{className:"mt-3 sm:mt-4",children:O?e.jsx("div",{className:"space-y-2",children:[0,1].map(s=>e.jsx(ue,{className:"h-16 rounded-xl sm:h-20"},s))}):x.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed border-border px-4 py-8 text-center sm:px-5 sm:py-10",children:[e.jsx("p",{className:"text-sm font-medium",children:"No API keys yet"}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground sm:text-sm",children:"Create an API key to connect your AI tools to this gateway."}),e.jsx(c,{className:"mt-4",size:"sm",onClick:()=>u(!0),children:"Create first key"})]}):e.jsx("div",{className:"space-y-1.5 sm:space-y-2",children:x.map(s=>{const t=s.isActive===!1,a=V.has(s.id);return e.jsxs("div",{className:z("rounded-lg border border-border bg-surface p-2.5 sm:p-3",t&&"opacity-65"),children:[e.jsxs("div",{className:"flex items-start justify-between gap-2.5 sm:gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 sm:gap-2",children:[e.jsx("p",{className:"truncate text-xs font-medium sm:text-sm",children:s.name}),s.isDefault?e.jsx(M,{tone:"muted",className:"text-[10px] sm:text-xs",children:"Default"}):null,e.jsx(M,{tone:t?"warn":"ok",className:"text-[10px] sm:text-xs",children:t?"Revoked":"Active"})]}),e.jsxs("p",{className:"mt-0.5 text-[10px] text-muted-foreground sm:mt-1 sm:text-xs",children:["Created ",new Date(s.createdAt||Date.now()).toLocaleDateString()]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-0.5 sm:gap-1",children:[e.jsx(ie,{active:!t,onToggle:()=>X(s)}),e.jsx(h,{label:"Rotate secret",children:e.jsx("button",{type:"button",onClick:()=>Y(s),disabled:P===s.id,className:"rounded-md p-1.5 text-muted-foreground hover:bg-surface-hover hover:text-primary disabled:opacity-50 sm:p-2","aria-label":"Rotate secret",children:P===s.id?e.jsx(U,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ne,{className:"h-3.5 w-3.5"})})}),s.isDefault?null:e.jsx(h,{label:"Delete key",children:e.jsx("button",{type:"button",onClick:()=>W(s),className:"rounded-md p-1.5 text-muted-foreground hover:bg-destructive/10 hover:text-destructive sm:p-2","aria-label":"Delete key",children:e.jsx(Ce,{className:"h-3.5 w-3.5"})})})]})]}),e.jsxs("div",{className:"mt-2 flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1 sm:mt-3 sm:gap-2 sm:px-2.5 sm:py-1.5",children:[e.jsx("code",{className:"min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground sm:text-xs",children:a?w[s.id]||s.key:he(s)}),e.jsx(h,{label:a?"Hide key":"Show key",children:e.jsx("button",{type:"button",onClick:()=>a?g(n=>{const $=new Set(n);return $.delete(s.id),$}):void Z(s),className:"rounded-md p-1 text-muted-foreground hover:bg-surface-hover hover:text-primary sm:p-1.5","aria-label":a?"Hide key":"Show key",children:a?e.jsx(Ke,{className:"h-3.5 w-3.5"}):e.jsx(Ae,{className:"h-3.5 w-3.5"})})}),e.jsx(h,{label:N===s.id?"Copying key":T===s.id?"Copied":"Copy key",children:e.jsx("button",{type:"button",onClick:()=>void ee(s),disabled:N===s.id,className:"rounded-md p-1 text-muted-foreground hover:bg-surface-hover hover:text-primary sm:p-1.5","aria-label":"Copy key",children:N===s.id?e.jsx(U,{className:"h-3.5 w-3.5 animate-spin"}):T===s.id?e.jsx(ke,{className:"h-3.5 w-3.5 text-success"}):e.jsx(Q,{className:"h-3.5 w-3.5"})})})]})]},s.id)})})})]})]})]}),e.jsx(C,{open:G,onOpenChange:u,children:e.jsxs(K,{children:[e.jsx(A,{className:"pb-2",children:e.jsx(k,{children:"Create API key"})}),e.jsx("div",{className:"px-6 pb-2",children:e.jsxs("label",{className:"block space-y-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Key name"}),e.jsx(ce,{value:f,onChange:s=>I(s.target.value),placeholder:"Production",autoFocus:!0})]})}),e.jsxs(R,{children:[e.jsx(c,{variant:"outline",onClick:()=>u(!1),disabled:v,children:"Cancel"}),e.jsx(c,{onClick:()=>void J(),disabled:!f.trim()||v,children:v?"Creating…":"Create"})]})]})}),e.jsx(C,{open:!!b,onOpenChange:()=>j(null),children:e.jsxs(K,{children:[e.jsxs(A,{children:[e.jsx(k,{children:"API key ready"}),e.jsx(me,{children:"Copy this secret now and update your clients. It is the current secret for this key."})]}),e.jsx("div",{className:"space-y-3 px-6 pb-2",children:e.jsxs("div",{className:"flex items-center gap-2 rounded-xl border border-primary/20 bg-primary/5 p-3",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all font-mono text-sm",children:b}),e.jsx(re,{value:b||"",label:""})]})}),e.jsx(R,{children:e.jsx(c,{onClick:()=>j(null),children:"Done"})})]})}),e.jsx(C,{open:!!r,onOpenChange:s=>!s&&l(null),children:e.jsxs(K,{children:[e.jsx(A,{children:e.jsx(k,{children:(r==null?void 0:r.title)||"Confirm"})}),e.jsx("p",{className:"px-6 pb-3 text-sm leading-relaxed text-muted-foreground",children:r==null?void 0:r.message}),e.jsxs(R,{children:[e.jsx(c,{variant:"outline",onClick:()=>l(null),children:"Cancel"}),e.jsx(c,{variant:r!=null&&r.destructive?"destructive":"default",onClick:()=>r==null?void 0:r.onConfirm(),children:(r==null?void 0:r.confirmLabel)||"Confirm"})]})]})})]})}export{ze as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as r}from"./react-vendor-xnYrwzsL.js";import{C as A,b as S}from"./card-
|
|
1
|
+
import{r as i,j as r}from"./react-vendor-xnYrwzsL.js";import{C as A,b as S}from"./card-BL-4tjF7.js";import{r as O,p as R,b as P}from"./index-BCs8FaU-.js";import{p as D,r as f,s as E,c as I,a as M,g as T}from"./oauth-callback-CqYQzyd7.js";import{a as z,L}from"./icons-vendor-CUx7SB5V.js";import"./ui-vendor-BuM9f2NY.js";import"./query-vendor-DVevaSVS.js";import"./motion-vendor-g5fpGzmJ.js";const b=3e3;function v({className:e}){return r.jsx("svg",{viewBox:"0 0 18 18",className:e,fill:"none","aria-hidden":"true",children:r.jsx("path",{className:"oauth-checkmark",d:"M2.5 9.25 6.5 13.25 15.5 5",pathLength:"1"})})}function K(){const e=i.useMemo(()=>D(window.location.search),[]),[a,s]=i.useState("processing"),[j,o]=i.useState("Returning to Sway Router…"),[h,y]=i.useState(()=>e.provider||(e.state?f(e.state):void 0)),n=h?O(h):void 0,p=n?R(n):"OAuth",c=n?P(n):null;i.useEffect(()=>{const u=window.opener;if(!!!(e.code||e.error)){s("manual"),o("No OAuth result was returned. Close this tab and try again.");return}const l=e.provider||(e.state?f(e.state):void 0);l&&y(l);const g=l?{...e,provider:l}:e,x=E(g);if(e.state&&I(e.state),!u||u.closed){if(!x){s("manual"),o(e.errorDescription||e.error?"Authorization failed. Close this tab and retry from the provider dialog.":"Authorization completed. Close this tab and return to the provider dialog.");return}s(e.error?"error":"success"),o(e.errorDescription||e.error?e.errorDescription||e.error||"Authorization failed.":"You can close this window.");const m=window.setTimeout(()=>{window.closed||window.close()},b);return()=>window.clearTimeout(m)}try{const m=M(g),w=T(window.location.origin);if(w.length===0)throw new Error("Invalid callback origin");for(const k of w)u.postMessage(m,k);e.error?(s("error"),o(e.errorDescription||e.error||"Authorization failed.")):(s("success"),o("You can close this window."))}catch{if(!x){s("manual"),o("The callback could not reach the provider dialog. Close this tab and retry.");return}s(e.error?"error":"success"),o(e.errorDescription||e.error?e.errorDescription||e.error||"Authorization failed.":"You can close this window.")}const N=window.setTimeout(()=>{window.closed||window.close()},b);return()=>window.clearTimeout(N)},[e]);const C=a==="success"?"Connected successfully":a==="error"?"Connection could not be completed":a==="manual"?"Return to Sway Router":"Completing authorization",t=a==="success",d=a==="error";return r.jsx("div",{className:"flex min-h-svh w-full items-center justify-center bg-background p-4 text-foreground",children:r.jsxs(A,{className:"w-full max-w-[420px] items-stretch border-border bg-card p-4 text-center",children:[r.jsxs("div",{className:"inline-flex self-start items-center gap-2 text-[13px] font-semibold tracking-[0.01em] text-foreground",children:[r.jsx("img",{src:"/logo/sway.svg",alt:"Sway Router",className:"h-6 w-6 rounded-md object-contain"}),r.jsx("span",{children:"Sway Router"})]}),r.jsxs("div",{className:"relative mt-7 self-center",children:[r.jsx("div",{className:t&&c?"flex h-14 w-14 items-center justify-center rounded-2xl border border-white/30 bg-white outline outline-1 outline-white/15 outline-offset-2":`flex h-14 w-14 items-center justify-center rounded-2xl border ${d?"border-destructive/35 bg-destructive/10 text-destructive":t?"border-success/35 bg-success/10 text-success":"border-primary/35 bg-primary/10 text-primary"}`,"aria-label":t?p:void 0,children:t&&c?r.jsx("img",{src:c,alt:p,className:"h-8 w-8 object-contain invert"}):t?r.jsx(v,{className:"h-7 w-7"}):d?r.jsx(z,{className:"h-7 w-7","aria-hidden":"true"}):r.jsx(L,{className:"h-7 w-7 animate-spin","aria-hidden":"true"})}),t&&c?r.jsx("span",{className:"absolute -bottom-2 -right-2 flex h-6 w-6 items-center justify-center rounded-full border-2 border-card bg-[#16a34a] text-white",children:r.jsx(v,{className:"h-4.5 w-4.5"})}):null]}),r.jsx(S,{className:"mt-5 text-[21px] leading-tight tracking-[-0.02em]",children:C}),t?null:r.jsx("p",{className:"mt-2.5 text-sm leading-6 text-muted-foreground",children:j}),r.jsxs("div",{className:"mt-5 inline-flex self-center items-center gap-1.5 rounded-full border border-border bg-muted px-2.5 py-1.5 text-[11px] leading-none text-foreground",children:[r.jsx("span",{className:`relative top-px h-1.5 w-1.5 shrink-0 rounded-full ${d?"bg-destructive":t?"bg-success":"bg-primary"}`,"aria-hidden":"true"}),r.jsx("span",{className:"leading-4",children:"OAuth Success"})]}),r.jsx("p",{className:"mt-4 text-xs leading-5 text-muted-foreground/70",children:t?"You can close this window manually.":"Return to the provider dialog to continue."})]})})}export{K as default};
|