omnigateway 0.11.2 → 0.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/omni.js +1533 -751
- package/gateway.js +2040 -1258
- package/package.json +2 -4
- package/public/assets/{Chip-77Q04h7S.js → Chip-roGX6zyg.js} +5 -1
- package/public/assets/CopyValue-FO5yNkRC.js +27 -0
- package/public/assets/{Field-56pmSGrh.js → Field-BYBri2NV.js} +1 -1
- package/public/assets/Lamp-DsUSnxN4.js +26 -0
- package/public/assets/{Panel-BV18WuL1.js → Panel-CWmOTDAP.js} +5 -0
- package/public/assets/Rack-CSpeYQ1D.js +483 -0
- package/public/assets/{Readout-Dxwka1JI.js → Readout-BTh732hP.js} +1 -1
- package/public/assets/{RequestTable-I395emqH.js → RequestTable-xpG3dPST.js} +1 -1
- package/public/assets/{SummaryDeck-pAZ93jBW.js → SummaryDeck-DwRGp7mB.js} +1 -1
- package/public/assets/{Toggle-y17mtXCV.js → Toggle-BTJVC9Se.js} +1 -1
- package/public/assets/TokenBreakdown-DT7or6C9.js +32 -0
- package/public/assets/{WindowChart-DWZtz4Ps.js → WindowChart-C-oJo3fW.js} +1 -1
- package/public/assets/{_app-0fHLZIC7.js → _app-Drf03PWk.js} +1 -1
- package/public/assets/{_app.accounts-DBlImnPw.js → _app.accounts-D8eynNaM.js} +12 -12
- package/public/assets/{_app.console-in_iVnep.js → _app.console-DbM7Zbgu.js} +1 -1
- package/public/assets/{_app.database-CPj-Juag.js → _app.database-Bj4UJUBZ.js} +7 -7
- package/public/assets/{_app.index-DGz9njXx.js → _app.index-2hdPR1Le.js} +1 -1
- package/public/assets/_app.keys-BYk7HsiW.js +92 -0
- package/public/assets/{_app.logs-C7BhBRjg.js → _app.logs-sG1w9y1i.js} +1 -1
- package/public/assets/_app.models-BqdGSdg4.js +148 -0
- package/public/assets/{_app.plugins._pluginId-Bx1LgcDj.js → _app.plugins._pluginId-Bf9D8Qiz.js} +1 -1
- package/public/assets/{_app.settings-s6K98CA2.js → _app.settings-TzCc7Sd3.js} +1 -1
- package/public/assets/{_app.usage-Bp45JtBe.js → _app.usage-XQHmzx-j.js} +1 -1
- package/public/assets/chevron-right-DgdKbG-g.js +1 -0
- package/public/assets/{client-Bl_FA5jI.js → client-B_g7bcxd.js} +1 -1
- package/public/assets/index-C_8ChaGY.js +14 -0
- package/public/assets/{login-Qc9iIepG.js → login-Dgd5jBoq.js} +1 -1
- package/public/assets/plus-UgaZwucC.js +1 -0
- package/public/assets/preload-helper-CvG2RSKd.js +1 -0
- package/public/assets/{shared-ChaZCaBz.js → shared-wEQ9LHZa.js} +1 -1
- package/public/assets/trash-IE0YvGCJ.js +1 -0
- package/public/index.html +5 -5
- package/public/shared/chunks/react-DK6rpPfu.js +1 -0
- package/public/shared/chunks/react-dom-Wr82bmbV.js +1 -0
- package/public/shared/dashboard-sdk.js +1 -1
- package/public/shared/react-dom-client.js +5 -5
- package/public/shared/react-dom.js +1 -1
- package/public/shared/react-query.js +1 -1
- package/public/shared/react.js +1 -1
- package/public/shared/styled-components.js +1 -1
- package/public/assets/CopyValue-DDJId-Zo.js +0 -27
- package/public/assets/Lamp-Drd1fFwQ.js +0 -25
- package/public/assets/Rack-D3iFlR6e.js +0 -482
- package/public/assets/TokenBreakdown-BIwuEVs8.js +0 -32
- package/public/assets/_app.keys-C-Fk39-U.js +0 -92
- package/public/assets/_app.models-BuiRrOrz.js +0 -148
- package/public/assets/chevron-right-BE-3EQR5.js +0 -1
- package/public/assets/index-nvJxJ9Gp.js +0 -13
- package/public/assets/plus-DhyoE7aH.js +0 -1
- package/public/assets/preload-helper-DYShfVEU.js +0 -1
- package/public/assets/trash-2-zGGJ7VE_.js +0 -1
- package/public/shared/chunks/react-GitiQ0dt.js +0 -1
- package/public/shared/chunks/react-dom-BFxyned6.js +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import{j as e}from"./Lamp-DsUSnxN4.js";import{b as t,y as n}from"./Rack-CSpeYQ1D.js";import{jsx as r,jsxs as i}from"react/jsx-runtime";import a,{keyframes as o}from"styled-components";var s={name:`arrow-down`,size:24,node:[[`path`,{d:`M12 5v14`,key:`s699le`}],[`path`,{d:`m19 12-7 7-7-7`,key:`1idqje`}]]};s.node;var c=t(s),l={name:`arrow-up`,size:24,node:[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]};l.node;var u=t(l),d=new Intl.NumberFormat(`en-US`);function f(e){return`${d.format(e.inputTokens)} input, ${d.format(e.outputTokens)} output, ${d.format(e.cacheReadTokens)} cache read, ${d.format(e.cacheWriteTokens)} cache write tokens`}var p=a.span`
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
flex-wrap: wrap;
|
|
5
|
+
gap: 6px;
|
|
6
|
+
/* Wrapping happens between the four classes, never inside one: a count
|
|
7
|
+
broken across lines from its own arrow reads as a different number. */
|
|
8
|
+
white-space: nowrap;
|
|
9
|
+
`,m=a.span`
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
line-height: 1;
|
|
13
|
+
gap: 2px;
|
|
14
|
+
|
|
15
|
+
svg {
|
|
16
|
+
width: 12px;
|
|
17
|
+
height: 12px;
|
|
18
|
+
stroke-width: 1.75;
|
|
19
|
+
}
|
|
20
|
+
`,h=o`
|
|
21
|
+
from { clip-path: inset(0 2ch 0 0); }
|
|
22
|
+
to { clip-path: inset(0 0 0 0); }
|
|
23
|
+
`,g=a.span`
|
|
24
|
+
display: inline-block;
|
|
25
|
+
width: 3ch;
|
|
26
|
+
vertical-align: bottom;
|
|
27
|
+
animation: ${h} 1.5s steps(2, end) infinite;
|
|
28
|
+
|
|
29
|
+
@media (prefers-reduced-motion: reduce) {
|
|
30
|
+
animation: none;
|
|
31
|
+
}
|
|
32
|
+
`;function _(){return i(`span`,{"aria-hidden":`true`,children:[`processing`,r(g,{children:`...`})]})}function v({tokens:t}){let a=f(t);return i(p,{role:`img`,"aria-label":a,title:a,children:[i(m,{"aria-hidden":`true`,children:[r(c,{}),e(t.inputTokens)]}),i(m,{"aria-hidden":`true`,children:[r(u,{}),e(t.outputTokens)]}),i(m,{"aria-hidden":`true`,children:[r(n,{}),r(c,{}),e(t.cacheReadTokens)]}),i(m,{"aria-hidden":`true`,children:[r(n,{}),r(u,{}),e(t.cacheWriteTokens)]})]})}export{v as n,f as r,_ as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as e,C as t,E as n,J as r,T as i,Y as a,dt as o,o as s,t as c,w as l}from"./shared-
|
|
1
|
+
import{A as e,C as t,E as n,J as r,T as i,Y as a,dt as o,o as s,t as c,w as l}from"./shared-wEQ9LHZa.js";import{C as u,E as d,M as f,N as p,R as m,S as h,_ as g,a as _,k as v,m as y,n as b}from"./Lamp-DsUSnxN4.js";import{C as x,_ as S,b as C,v as w}from"./Panel-CWmOTDAP.js";import*as T from"react";import{forwardRef as E}from"react";import{Fragment as D,jsx as O,jsxs as k}from"react/jsx-runtime";import A from"styled-components";var j=[`axis`],M=E((e,n)=>T.createElement(t,{chartName:`LineChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:j,tooltipPayloadSearcher:a,categoricalChartProps:e,ref:n})),N=A(C)`
|
|
2
2
|
gap: ${({theme:e})=>e.space(5)};
|
|
3
3
|
flex-wrap: wrap;
|
|
4
4
|
`,P=A.div`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,k as t,t as n}from"./Panel-
|
|
1
|
+
import{i as e,k as t,t as n}from"./Panel-CWmOTDAP.js";import{jsx as r}from"react/jsx-runtime";function i({error:i}){let a=t();return r(n,{legend:`Console unavailable`,children:r(e,{legend:`The gateway did not answer`,error:i,onRetry:()=>void a.invalidate()})})}export{i as errorComponent};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{F as e,I as t,Kt as n,Ot as r,T as i,Tt as a,U as o,Vt as s,W as c,at as l,b as u,c as d,ct as f,d as p,dt as ee,ft as m,h as te,ht as h,j as g,kt as _,n as v,o as y,ot as b,s as x,t as S,v as C,y as w}from"./Lamp-
|
|
1
|
+
import{F as e,I as t,Kt as n,Ot as r,T as i,Tt as a,U as o,Vt as s,W as c,at as l,b as u,c as d,ct as f,d as p,dt as ee,ft as m,h as te,ht as h,j as g,kt as _,n as v,o as y,ot as b,s as x,t as S,v as C,y as w}from"./Lamp-DsUSnxN4.js";import{C as T,D as E,O as D,_ as O,a as k,b as A,i as j,o as M,r as ne,t as N,v as P,x as re}from"./Panel-CWmOTDAP.js";import{_ as F,b as I,i as ie,m as L,r as R,t as z}from"./Rack-CSpeYQ1D.js";import{t as B}from"./CopyValue-FO5yNkRC.js";import{n as V,t as H}from"./chevron-right-DgdKbG-g.js";import{t as ae}from"./plus-UgaZwucC.js";import{t as oe}from"./trash-IE0YvGCJ.js";import{t as se}from"./Toggle-BTJVC9Se.js";import{t as ce}from"./Chip-roGX6zyg.js";import{i as U,n as W,r as le,t as G}from"./Field-BYBri2NV.js";import{t as ue}from"./Meter-stpt3vQu.js";import{i as de,n as K,r as q,t as fe}from"./Table-CVDZ69Zx.js";import{n as pe,r as me,t as he}from"./WindowChart-C-oJo3fW.js";import{Fragment as ge,useCallback as J,useEffect as _e,useState as Y}from"react";import{Fragment as X,jsx as Z,jsxs as Q}from"react/jsx-runtime";import $ from"styled-components";var ve={name:`external-link`,size:24,node:[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]};ve.node;var ye=I(ve);function be(e){return e?.authTypes??[]}function xe(e){return be(e).includes(`oauth`)?`oauth`:`apiKey`}function Se(e){return e[0]?.id??`anthropic`}var Ce={oauth:`Authorize in the browser`,apiKey:`Paste an API key`};function we(e){let t=e?.callback;return t===void 0?`code#state`:`${t.uri}?code=…`}var Te=$.ol`
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
gap: ${({theme:e})=>e.space(3)};
|
|
5
|
-
`,
|
|
5
|
+
`,Ee=$.div`
|
|
6
6
|
font-family: ${({theme:e})=>e.font.mono};
|
|
7
7
|
font-size: 26px;
|
|
8
8
|
letter-spacing: 0.22em;
|
|
@@ -11,15 +11,15 @@ import{F as e,I as t,Kt as n,Ot as r,T as i,Tt as a,U as o,Vt as s,W as c,at as
|
|
|
11
11
|
background: ${({theme:e})=>e.color.panelSunk};
|
|
12
12
|
border: 1px solid ${({theme:e})=>e.color.ruleStrong};
|
|
13
13
|
border-radius: ${({theme:e})=>e.radius.control};
|
|
14
|
-
`,
|
|
14
|
+
`,De=$.p`
|
|
15
15
|
font-size: 12px;
|
|
16
16
|
color: ${({theme:e})=>e.color.down};
|
|
17
|
-
`,
|
|
17
|
+
`,Oe=$.p`
|
|
18
18
|
font-size: 12px;
|
|
19
19
|
color: ${({theme:e})=>e.color.inkDim};
|
|
20
|
-
`;function
|
|
20
|
+
`;function ke({open:e,credentials:t,onOpenChange:n,onConnected:i}){let a=r().data??[],[s,u]=Y(()=>Se(a)),d=o(a,s),[p,ee]=Y(()=>xe(o(a,Se(a)))),[m,te]=Y(``),h=d?.label??s,[g,_]=Y(null),[v,y]=Y(``),[x,S]=Y(``),C=(t??[]).filter((e,t,n)=>e.provider===`custom`&&n.findIndex(t=>t.provider===`custom`&&t.providerData.endpointId===e.providerData.endpointId)===t),[w,D]=Y(``),[k,j]=Y(``),[ne,N]=Y(`chat_completions`),[P,re]=Y(``),[F,I]=Y(null),L=b(),R=l(),z=f(),V=J(()=>{_(null),y(``),S(``),D(``),j(``),N(`chat_completions`),re(``),I(null),te(``),L.reset(),R.reset(),z.reset()},[L,R,z]),H=J(e=>{e||V(),n(e)},[n,V]);return _e(()=>{if(g===null||g.kind!==`device`)return;let e=!1,t=async()=>{try{let t=await c(g.flowId);if(e)return;if(t.status===`complete`){V(),n(!1),i();return}}catch(t){if(e)return;I(M(t)),_(null);return}e||(r=setTimeout(()=>void t(),g.pollIntervalMs))},r=setTimeout(()=>void t(),g.pollIntervalMs);return()=>{e=!0,clearTimeout(r)}},[g,i,n,V]),Z(ie,{open:e,onOpenChange:H,title:`Connect an account`,description:`The gateway stores the resulting token encrypted. It is never shown again after this dialog.`,footer:g===null?Q(X,{children:[Z(E,{type:`button`,onClick:()=>H(!1),children:`Cancel`}),Z(E,{type:`button`,$variant:`primary`,disabled:L.isPending||z.isPending,onClick:()=>{if(I(null),p===`apiKey`){z.mutate({provider:s,apiKey:P,label:m.trim()||void 0,...s===`custom`?{endpointId:x,endpointLabel:w,origin:k,protocol:ne}:{}},{onSuccess:()=>{V(),n(!1),i()},onError:e=>I(M(e))});return}L.mutate({provider:s,label:m.trim().length===0?h:m.trim()},{onSuccess:e=>_(e),onError:e=>I(M(e))})},children:p===`apiKey`?z.isPending?`Adding…`:`Add API key`:L.isPending?`Starting…`:`Start authorization`})]}):g.kind===`device`?Z(E,{type:`button`,onClick:()=>H(!1),children:`Cancel`}):Q(X,{children:[Z(E,{type:`button`,onClick:()=>H(!1),children:`Cancel`}),Z(E,{type:`button`,$variant:`primary`,disabled:R.isPending||v.trim().length===0,onClick:()=>{g!==null&&(I(null),R.mutate({flowId:g.flowId,code:v.trim()},{onSuccess:()=>{V(),n(!1),i()},onError:e=>I(M(e))}))},children:R.isPending?`Finishing…`:`Finish connecting`})]}),children:Q(Te,{children:[g===null?Q(T,{$gap:3,children:[Z(G,{label:`Provider`,children:e=>Z(U,{...e,value:s,onChange:e=>{let t=e.target.value;u(t),ee(xe(o(a,t)))},children:a.map(e=>Z(`option`,{value:e.id,children:e.label},e.id))})}),be(d).length>1?Z(G,{label:`How to connect`,children:e=>Z(U,{...e,value:p,onChange:e=>ee(e.target.value),children:be(d).map(e=>Z(`option`,{value:e,children:Ce[e]},e))})}):null,s===`custom`?Q(X,{children:[C.length===0?null:Z(G,{label:`Existing endpoint`,children:e=>Q(U,{...e,value:x,onChange:e=>{let t=C.find(t=>t.providerData.endpointId===e.target.value);if(t===void 0){S(``),D(``),j(``),N(`chat_completions`);return}S(String(t.providerData.endpointId)),D(String(t.providerData.endpointLabel)),j(String(t.providerData.origin)+String(t.providerData.basePath??``)),N(t.providerData.protocol===`responses`?`responses`:`chat_completions`)},children:[Z(`option`,{value:``,children:`Create new endpoint`}),C.map(e=>Z(`option`,{value:String(e.providerData.endpointId),children:String(e.providerData.endpointLabel)},String(e.providerData.endpointId)))]})}),Z(G,{label:`Endpoint ID`,children:e=>Z(W,{...e,value:x,onChange:e=>S(e.target.value)})}),Z(G,{label:`Endpoint label`,children:e=>Z(W,{...e,value:w,onChange:e=>D(e.target.value)})}),Z(G,{label:`Server URL`,children:e=>Z(W,{...e,value:k,placeholder:`https://server.example/api`,onChange:e=>j(e.target.value)})}),k.trim().toLowerCase().startsWith(`http://`)?Z(De,{children:`Plaintext transport sends prompts and API keys without TLS.`}):null,Z(G,{label:`Protocol`,children:e=>Q(U,{...e,value:ne,onChange:e=>N(e.target.value),children:[Z(`option`,{value:`chat_completions`,children:`Chat Completions (/v1/chat/completions)`}),Z(`option`,{value:`responses`,children:`Responses (/v1/responses)`})]})})]}):null,p===`apiKey`?Z(G,{label:`API key`,children:e=>Z(W,{...e,type:`password`,value:P,autoComplete:`off`,onChange:e=>re(e.target.value)})}):null,Z(G,{label:`Label`,hint:`How this account is named in the rack. Defaults to the provider.`,children:e=>Z(W,{...e,value:m,placeholder:h,onChange:e=>te(e.target.value)})})]}):Q(T,{$gap:3,children:[Q(T,{$gap:1,children:[Z(O,{children:`Step 1 — authorize`}),Z(A,{$gap:2,children:Q(E,{as:`a`,href:g.authorizeUrl,target:`_blank`,rel:`noreferrer noopener`,$variant:`primary`,$size:`sm`,children:[Z(ye,{}),`Open `,h]})}),Z(B,{value:g.authorizeUrl,label:`Copy authorization link`})]}),g.userCode===null?null:Q(T,{$gap:1,children:[Z(O,{children:`Step 2 — enter this code`}),Z(Ee,{children:g.userCode})]}),g.kind===`device`?Q(Oe,{children:[d?.pasteHint??``,` Waiting for authorization…`]}):Z(G,{label:`Authorization code`,hint:d?.pasteHint??``,...F===null?{}:{problem:F},children:e=>Z(W,{...e,value:v,autoFocus:!0,placeholder:we(d),onChange:e=>y(e.target.value)})})]}),F===null||g?.kind===`pkce`?null:Z(De,{children:F})]})})}function Ae({credentialId:e,windows:t,burn:n,pollIntervalMs:r,now:i}){let a=t.map(e=>({window:e,estimate:y(n,e.windowType),since:me(u(e))})),o=a.map(e=>e.since).filter(e=>e!==null),s=o.length===0?0:Math.min(...o),c=_({credentialId:e,since:s},o.length>0),l=c.data?.samples??[],d=c.data?.gatewayRates??[],f=c.data?.truncated===!0;return Z(T,{$gap:4,children:a.map(e=>Z(je,{window:e.window,estimate:e.estimate,since:e.since,samples:l.filter(t=>t.windowType===e.window.windowType&&t.observedAt>=(e.since??0)),gatewayRate:d.find(t=>t.windowType===e.window.windowType),truncated:f,pollIntervalMs:r,now:i},e.window.windowType))})}function je({window:e,estimate:t,since:n,samples:r,gatewayRate:a,truncated:o,pollIntervalMs:s,now:c}){let l=e.limit===null?`${g(e.used)} used`:`${g(e.used)} of ${g(e.limit)} used`,d=i(e,c),f=t===void 0||p(e,c,s)||t.stale&&!d;return Z(pe,{live:u(e),samples:r.map(u),since:n,now:c,truncated:o&&n!==null&&r.length>0&&(r[0]?.observedAt??0)>n,ratePerHourRatio:w(e,t),exhaustsAt:t?.exhaustsAt??null,survives:t?.survives??null,stale:f,rolledOver:d,spent:l,rateText:t?.ratePerHour===void 0||t.ratePerHour===null?`unknown`:`${g(t.ratePerHour)}/h`,extraFact:Z(he,{legend:`This gateway accounts for`,value:a?.gatewayRatePerHour===void 0||a.gatewayRatePerHour===null?`unknown`:`${g(a.gatewayRatePerHour)} tokens/h`})})}var Me=$(N)`
|
|
21
21
|
border-left: 3px solid ${({$provider:e})=>L(e)};
|
|
22
|
-
`,
|
|
22
|
+
`,Ne=$(W)`
|
|
23
23
|
width: 100%;
|
|
24
24
|
min-width: 140px;
|
|
25
25
|
height: 26px;
|
|
@@ -33,15 +33,15 @@ import{F as e,I as t,Kt as n,Ot as r,T as i,Tt as a,U as o,Vt as s,W as c,at as
|
|
|
33
33
|
background: ${({theme:e})=>e.color.panelSunk};
|
|
34
34
|
border-color: ${({theme:e})=>e.color.ruleStrong};
|
|
35
35
|
}
|
|
36
|
-
`,
|
|
36
|
+
`,Pe=$(le)`
|
|
37
37
|
width: 62px;
|
|
38
38
|
height: 26px;
|
|
39
|
-
`,
|
|
39
|
+
`,Fe=$.span`
|
|
40
40
|
display: block;
|
|
41
41
|
padding-left: 9px;
|
|
42
42
|
font-size: 11px;
|
|
43
43
|
color: ${({theme:e})=>e.color.inkDim};
|
|
44
|
-
`,
|
|
44
|
+
`,Ie=$.div`
|
|
45
45
|
display: grid;
|
|
46
46
|
/* Bar, figure, legend. The figure has a column of its own so the legends stay
|
|
47
47
|
aligned down the stack whether a window reads 4% or 100%. */
|
|
@@ -49,11 +49,11 @@ import{F as e,I as t,Kt as n,Ot as r,T as i,Tt as a,U as o,Vt as s,W as c,at as
|
|
|
49
49
|
align-items: center;
|
|
50
50
|
min-width: 208px;
|
|
51
51
|
gap: 6px;
|
|
52
|
-
`,
|
|
52
|
+
`,Le=$(P)`
|
|
53
53
|
font-size: 11px;
|
|
54
54
|
text-align: right;
|
|
55
|
-
`,
|
|
55
|
+
`,Re=$.div`
|
|
56
56
|
display: flex;
|
|
57
57
|
flex-direction: column;
|
|
58
58
|
gap: 4px;
|
|
59
|
-
`;function
|
|
59
|
+
`;function ze(){let e=n();return{pending:e.isPending,commit:(t,n)=>{e.mutate({id:t,patch:n})}}}function Be(e,t){if(t===void 0)return` The list of models could not be read, so whether any target is pinned to this account is unknown.`;let n=t.filter(t=>t.targets.some(t=>t.credentialId===e.id)).map(e=>e.id);return n.length===0?``:` ${n.length===1?`The model`:`The models`} ${n.join(`, `)} ${n.length===1?`pins a target`:`pin targets`} to this account. Those targets will fail rather than fall back to another account.`}function Ve(){let{cadence:n}=F(),i=m(),c=ee(n(1e4,`res:credentials`)),l=s(),u=a(),f=r(),p=h(),{commit:g}=ze(),[_,b]=Y(!1),[w,M]=Y(null),[P,I]=Y(new Set),ie=e=>I(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),L=Date.now(),B=i.data??[],U=f.data??[],W=e=>o(U,e)?.order??1/0,le=[...new Set(B.map(e=>e.provider))].sort((e,t)=>W(e)-W(t)),G=e=>o(U,e)?.label??e,pe=d(c.data?.health??[],e=>e.credentialId),me=d(c.data?.quota??[],e=>e.credentialId),he=d(c.data?.burn??[],e=>e.credentialId),J=l.data?.quotaPollIntervalMs??3e5,_e=B.filter(e=>e.enabled).length,$=i.isLoading?`Reading connected accounts…`:B.length===0?`No provider credentials are connected, so every request fails at the router.`:`${_e} of ${B.length} accounts are enabled and eligible for routing.`;return Q(X,{children:[Z(z,{legend:`Accounts`,title:`Provider accounts`,summary:$,actions:Q(E,{type:`button`,$variant:`primary`,onClick:()=>b(!0),children:[Z(ae,{}),`Connect an account`]})}),i.isError?Z(N,{legend:`Accounts`,children:Z(j,{error:i.error,onRetry:()=>void i.refetch()})}):i.isLoading?Z(N,{legend:`Accounts`,children:Z(k,{rows:5})}):B.length===0?Z(N,{legend:`Accounts`,children:Z(ne,{legend:`Nothing connected`,message:`Connect a provider account to give the router something to dispatch to. Tokens are encrypted at rest and never shown again.`,action:Z(E,{type:`button`,$variant:`primary`,$size:`sm`,onClick:()=>b(!0),children:`Connect an account`})})}):Z(T,{$gap:4,children:le.map(n=>{let r=B.filter(e=>e.provider===n);return Z(Me,{$provider:n,legend:G(n),meta:`${r.length} account${r.length===1?``:`s`}`,flush:!0,children:Z(re,{children:Q(fe,{children:[Z(`thead`,{children:Q(`tr`,{children:[Z(q,{$width:`24%`,children:`Account`}),Z(q,{$width:`20%`,children:`Sign-in`}),Z(q,{$align:`right`,$width:`86px`,children:`Tier`}),Z(q,{$align:`right`,$width:`94px`,children:`Weight`}),Z(q,{$align:`center`,$width:`86px`,children:`Enabled`}),Z(q,{$width:`240px`,children:`Quota`}),Z(q,{$align:`right`,$width:`130px`,children:`Token expires`}),Z(q,{$width:`76px`})]})}),Z(`tbody`,{children:r.map(n=>{let r=x(pe.get(n.id)??[],L,n.enabled,n.disabledReason),i=me.get(n.id)??[],a=he.get(n.id)??[],o=C(i),s=P.has(n.id);return Q(ge,{children:[Q(de,{children:[Q(K,{children:[Q(A,{$gap:2,children:[Z(S,{state:r.state,label:r.note===``?`healthy`:r.note}),Z(Ne,{defaultValue:n.label,"aria-label":`Label for ${n.label}`,onBlur:e=>{let t=e.target.value.trim();if(t.length===0||t===n.label){e.target.value=n.label;return}g(n.id,{label:t})}})]}),r.note===``?null:Z(Fe,{children:r.note})]}),Z(K,{children:Q(A,{$gap:1,children:[Z(ce,{children:n.authType===`oauth`?`oauth`:`api key`}),n.accountEmail===null?null:Z(O,{children:n.accountEmail})]})}),Z(K,{$align:`right`,children:Z(Pe,{min:1,step:1,defaultValue:n.tier,"aria-label":`Tier for ${n.label}`,onBlur:e=>{let t=Number(e.target.value);if(!Number.isInteger(t)||t<1||t===n.tier){e.target.value=String(n.tier);return}g(n.id,{tier:t})}})}),Z(K,{$align:`right`,children:Z(Pe,{min:.1,step:.1,defaultValue:n.weight,"aria-label":`Weight for ${n.label}`,onBlur:e=>{let t=Number(e.target.value);if(!Number.isFinite(t)||t<=0||t===n.weight){e.target.value=String(n.weight);return}g(n.id,{weight:t})}})}),Z(K,{$align:`center`,children:Z(se,{checked:n.enabled,label:`Route to ${n.label}`,onCheckedChange:e=>g(n.id,{enabled:e})})}),Z(K,{children:o.length===0?Z(O,{children:`unknown`}):Z(Re,{children:o.map(({window:n,fraction:r})=>Q(Ie,{children:[Z(ue,{fraction:r,label:`${v[n.windowType]} window, ${Math.round(r*100)}% used`}),Z(Le,{children:e(r,0)}),Z(O,{children:te(n,L,J,t,y(a,n.windowType))})]},n.windowType))})}),Z(K,{$align:`right`,$mono:!0,children:n.expiresAt===null?`never`:t(n.expiresAt,L)}),Z(K,{$align:`right`,children:Q(A,{$gap:1,$justify:`flex-end`,children:[i.length===0?null:Z(D,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-expanded":s,"aria-label":`${s?`Hide`:`Show`} quota history for ${n.label}`,title:`${s?`Hide`:`Show`} quota history for ${n.label}`,onClick:()=>ie(n.id),children:Z(s?V:H,{})}),Z(D,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-label":`Remove ${n.label}`,title:`Remove ${n.label}`,onClick:()=>M(n),children:Z(oe,{})})]})})]}),s?Z(de,{children:Z(K,{colSpan:9,children:Z(Ae,{credentialId:n.id,windows:i,burn:a,pollIntervalMs:J,now:L})})}):null]},n.id)})})]})})},n)})}),Z(ke,{open:_,credentials:i.data??[],onOpenChange:b,onConnected:()=>void i.refetch()}),Z(R,{open:w!==null,onOpenChange:e=>{e||M(null)},title:`Remove account`,body:w===null?``:`Removing "${w.label}" deletes its stored token. Any model target pointing at ${G(w.provider)} loses this account, and reconnecting means authorizing again.`+Be(w,u.data),confirmLabel:`Remove account`,busy:p.isPending,onConfirm:()=>{w!==null&&p.mutate(w.id,{onSettled:()=>M(null)})}})]})}var He=Ve;export{He as component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{B as e,Et as t,j as n,st as r}from"./Lamp-
|
|
1
|
+
import{B as e,Et as t,j as n,st as r}from"./Lamp-DsUSnxN4.js";import{a as i,b as a,i as o,r as s,t as c,y as ee}from"./Panel-CWmOTDAP.js";import{_ as l,t as u}from"./Rack-CSpeYQ1D.js";import{a as d,c as f,o as p,s as m}from"./index-C_8ChaGY.js";import{i as h}from"./Field-BYBri2NV.js";import{useQueryClient as g}from"@tanstack/react-query";import{useLayoutEffect as te,useMemo as _,useRef as v,useState as y}from"react";import{jsx as b,jsxs as x}from"react/jsx-runtime";import S from"styled-components";var C={debug:10,info:20,warn:30,error:40};function w(e){return typeof e==`string`&&e in C}function T(e,t){return!w(t)||e.level===null||C[e.level]>=C[t]}function E(e){if(typeof e!=`object`||!e)return null;let{raw:t,at:n,level:r,msg:i}=e;return typeof t!=`string`||n!==null&&typeof n!=`number`||r!==null&&!w(r)||i!==null&&typeof i!=`string`?null:{raw:t,at:n,level:r,msg:i}}function D(e){if(typeof e!=`object`||!e)return null;let{lines:t}=e;if(!Array.isArray(t))return null;let n=[];for(let e of t){let t=E(e);if(t===null)return null;n.push(t)}return n}var O=[100,200,500],ne=[{value:``,label:`All levels`},{value:`debug`,label:`Debug and above`},{value:`info`,label:`Info and above`},{value:`warn`,label:`Warnings and errors`},{value:`error`,label:`Errors only`}],re=S(a)`
|
|
2
2
|
gap: ${({theme:e})=>e.space(2)};
|
|
3
3
|
flex-wrap: wrap;
|
|
4
4
|
`,k=S(h)`
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import{F as e,Ft as t,Jt as n,K as r,M as i,Mt as a,O as o,P as s,Wt as c,Z as l,_t as u,j as d,pt as f,ut as p,yt as m}from"./Lamp-
|
|
1
|
+
import{F as e,Ft as t,Jt as n,K as r,M as i,Mt as a,O as o,P as s,Wt as c,Z as l,_t as u,j as d,pt as f,ut as p,yt as m}from"./Lamp-DsUSnxN4.js";import{C as h,D as g,_,a as v,b as y,g as b,i as x,o as S,r as ee,t as C,w,x as T}from"./Panel-CWmOTDAP.js";import{b as E,r as D,t as O}from"./Rack-CSpeYQ1D.js";import{t as k}from"./trash-IE0YvGCJ.js";import{r as A,t as j}from"./Field-BYBri2NV.js";import{t as M}from"./Meter-stpt3vQu.js";import{i as N,n as P,r as F,t as I}from"./Table-CVDZ69Zx.js";import{t as L}from"./Readout-BTh732hP.js";import{n as R}from"./reasons-Du1OBWAM.js";import{useQueryClient as z}from"@tanstack/react-query";import{useCallback as B,useState as V}from"react";import{Fragment as H,jsx as U,jsxs as W}from"react/jsx-runtime";import G from"styled-components";var K={name:`camera`,size:24,node:[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`,key:`18u6gg`}],[`circle`,{cx:`12`,cy:`13`,r:`3`,key:`1vg3eu`}]]};K.node;var q=E(K),J={name:`minimize-2`,size:24,node:[[`path`,{d:`m14 10 7-7`,key:`oa77jy`}],[`path`,{d:`M20 10h-6V4`,key:`mjg0md`}],[`path`,{d:`m3 21 7-7`,key:`tjx5ai`}],[`path`,{d:`M4 14h6v6`,key:`rmj7iw`}]]};J.node;var Y=E(J),X=[{id:`keepLatest`,label:`Snapshots kept`,hint:`How many survive regardless of age. The newest is always kept, whatever both numbers say.`,unit:`files`,max:100},{id:`maxAgeDays`,label:`Maximum age`,hint:`Older snapshots are pruned after every new one and on the hourly maintenance sweep.`,unit:`days`,max:3650}],te=G.p`
|
|
2
2
|
font-size: 12px;
|
|
3
3
|
color: ${({theme:e})=>e.color.down};
|
|
4
|
-
`,
|
|
4
|
+
`,ne=G.p`
|
|
5
5
|
font-size: 12px;
|
|
6
6
|
color: ${({theme:e})=>e.color.ok};
|
|
7
|
-
`,
|
|
7
|
+
`,re=G.div`
|
|
8
8
|
display: grid;
|
|
9
9
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
10
10
|
gap: ${({theme:e})=>e.space(3)};
|
|
11
|
-
`;function
|
|
11
|
+
`;function ie(e){let t={};for(let n of X){let r=e[n.id].trim(),i=Number(r);if(r.length===0||!Number.isInteger(i)||i<1)return{ok:!1,problem:`${n.label} must be a whole number of 1 or more.`};if(i>n.max)return{ok:!1,problem:`${n.label} cannot exceed ${n.max}.`};t[n.id]=i}return{ok:!0,policy:t}}function ae({retention:e}){let n=t(),[r,i]=V({}),[a,o]=V(null),[s,c]=V(!1),l={keepLatest:r.keepLatest??(e===void 0?``:String(e.keepLatest)),maxAgeDays:r.maxAgeDays??(e===void 0?``:String(e.maxAgeDays))};return U(C,{legend:`Retention`,actions:U(g,{type:`button`,$size:`sm`,disabled:n.isPending||e===void 0,onClick:()=>{c(!1);let e=ie(l);if(!e.ok){o(e.problem);return}o(null),n.mutate(e.policy,{onSuccess:()=>{c(!0),i({})},onError:e=>o(S(e))})},children:n.isPending?`Saving…`:`Save retention`}),children:W(h,{$gap:3,children:[U(re,{children:X.map(e=>U(j,{label:e.label,hint:e.hint,children:t=>W(y,{$gap:2,children:[U(A,{...t,min:1,max:e.max,step:1,value:l[e.id],onChange:t=>i({...r,[e.id]:t.target.value})}),U(_,{children:e.unit})]})},e.id))}),a===null?null:U(te,{role:`alert`,children:a}),s&&a===null?U(ne,{role:`status`,children:`Retention saved.`}):null]})})}function oe(){let e=z();return B(t=>{if(t.adminPasswordChanged){R(`admin-password-changed`);return}e.invalidateQueries()},[e])}var Z=G.p`
|
|
12
12
|
font-size: 12px;
|
|
13
13
|
color: ${({theme:e})=>e.color.down};
|
|
14
|
-
`,
|
|
14
|
+
`,se=G.input`
|
|
15
15
|
font-size: 12px;
|
|
16
16
|
color: ${({theme:e})=>e.color.inkDim};
|
|
17
17
|
max-width: 40ch;
|
|
18
|
-
`;function
|
|
18
|
+
`;function ce(){let e=c(),t=p(),n=a(),s=oe(),l=u(),d=m(),[f,_]=V(null),[b,E]=V(null),[O,k]=V(null),[A,M]=V(!1),L=e.data??[],R=W(g,{type:`button`,$variant:`primary`,$size:`sm`,disabled:t.isPending,onClick:()=>t.mutate(),children:[U(q,{}),t.isPending?`Copying…`:`Take a snapshot`]}),z=W(h,{$gap:2,children:[W(y,{$gap:2,$wrap:!0,children:[U(j,{label:`Database file to import`,hint:`A snapshot taken from this or another OmniGateway. It is checked for integrity and rejected if it is not one of ours.`,children:e=>U(se,{...e,type:`file`,accept:`.sqlite,.db,application/octet-stream`,onChange:e=>k(e.target.files?.[0]??null)})}),U(g,{type:`button`,$variant:`danger`,$size:`sm`,disabled:O===null||d.isPending,onClick:()=>M(!0),children:d.isPending?`Replacing…`:`Import`})]}),d.isError?U(Z,{role:`alert`,children:S(d.error)}):null,n.isError?U(Z,{role:`alert`,children:S(n.error)}):null,t.isError?U(Z,{role:`alert`,children:S(t.error)}):null]});return W(C,{legend:`Snapshots`,meta:`${L.length}`,actions:R,footer:z,flush:!0,children:[e.isError?U(x,{error:e.error,onRetry:()=>void e.refetch()}):e.isLoading?U(`div`,{style:{padding:12},children:U(v,{rows:3})}):L.length===0?U(ee,{legend:`No snapshots`,message:`Nothing has been copied yet, so there is nothing to go back to. Take one before a migration or a settings change you are unsure of.`,action:U(g,{type:`button`,$variant:`primary`,$size:`sm`,disabled:t.isPending,onClick:()=>t.mutate(),children:`Take the first snapshot`})}):U(T,{children:W(I,{children:[U(`thead`,{children:W(`tr`,{children:[U(F,{children:`File`}),U(F,{children:`Reason`}),U(F,{$align:`right`,children:`Size`}),U(F,{$align:`right`,children:`Taken`}),U(F,{})]})}),U(`tbody`,{children:L.map(e=>W(N,{children:[U(P,{$mono:!0,children:U(w,{style:{maxWidth:`38ch`,display:`block`},children:e.filename})}),U(P,{children:e.reason}),U(P,{$align:`right`,$mono:!0,children:o(e.sizeBytes)}),U(P,{$align:`right`,$mono:!0,children:i(e.createdAt)}),U(P,{$align:`right`,children:W(y,{$gap:1,$justify:`flex-end`,children:[U(g,{as:`a`,$size:`sm`,href:r(e.id),download:e.filename,children:`Download`}),U(g,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>_(e),children:`Restore`}),U(g,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>E(e),children:`Delete`})]})})]},e.id))})]})}),U(D,{open:f!==null,onOpenChange:e=>{e||_(null)},title:`Restore database`,body:f===null?``:`Replacing the live database with ${f.filename}. Client requests are refused while the file is swapped, and a copy of the current database is taken first so this can be undone. Captured request bodies are not part of a snapshot and are left where they are.`,confirmLabel:`Restore database`,busy:n.isPending,onConfirm:()=>{f!==null&&n.mutate(f.id,{onSuccess:s,onSettled:()=>_(null)})}}),U(D,{open:b!==null,onOpenChange:e=>{e||E(null)},title:`Delete snapshot`,body:b===null?``:`Deleting ${b.filename} from disk. Download it first if it is the copy you would go back to; there is no other one of it.`,confirmLabel:`Delete snapshot`,busy:l.isPending,onConfirm:()=>{b!==null&&l.mutate(b.id,{onSettled:()=>E(null)})}}),U(D,{open:A,onOpenChange:M,title:`Import database`,body:O===null?``:`Replacing the live database with ${O.name}. It is validated before anything is touched, and a copy of the current database is taken first. If the file carries a different admin password, every session ends and you will be asked to sign in again.`,confirmLabel:`Replace database`,busy:d.isPending,onConfirm:()=>{O!==null&&d.mutate(O,{onSuccess:s,onSettled:()=>M(!1)})}})]})}var Q=G.p`
|
|
19
19
|
font-size: 12px;
|
|
20
20
|
color: ${({theme:e})=>e.color.ok};
|
|
21
21
|
`,$=G.p`
|
|
22
22
|
font-size: 12px;
|
|
23
23
|
color: ${({theme:e})=>e.color.down};
|
|
24
|
-
`;function
|
|
24
|
+
`;function le(e){try{let{hostname:t,port:n}=new URL(e);return n===``?t:`${t}:${n}`}catch{return e}}function ue(e){try{return new URL(e).pathname.replace(/^\//,``)||`—`}catch{return`—`}}function de(){let t=f(),r=n(),[i,a]=V(!1),c=l(),[u,p]=V(!1),m=t.data,h=m?.engine===`postgres`,_=m===void 0||m.logicalBytes===0?0:m.freePageBytes/m.logicalBytes;return W(H,{children:[U(O,{legend:`Database`,title:`Storage, snapshots, and retention`,summary:t.isLoading?`Measuring the database…`:h?`The Postgres database every replica of this cluster runs from. Back it up with pg_dump; nothing here copies or replaces it.`:`The one SQLite file this gateway runs from, the copies taken of it, and how long they are kept.`}),U(C,{legend:`Size`,meta:m===void 0?void 0:`schema v${m.stats.schemaVersion}`,actions:W(H,{children:[W(g,{type:`button`,$size:`sm`,disabled:c.isPending||m===void 0||m.bodiesBytes===0,onClick:()=>p(!0),children:[U(k,{}),c.isPending?`Clearing…`:`Clear bodies`]}),h?null:W(g,{type:`button`,$size:`sm`,disabled:r.isPending||m===void 0,onClick:()=>a(!0),children:[U(Y,{}),r.isPending?`Compacting…`:`Compact`]})]}),footer:r.isError?U($,{role:`alert`,children:S(r.error)}):c.isError?U($,{role:`alert`,children:S(c.error)}):r.data===void 0?c.data===void 0?void 0:U(Q,{role:`status`,children:`Cleared ${d(c.data.removed)} captured bodies.`}):U(Q,{role:`status`,children:`Compacted, reclaiming ${o(r.data.reclaimedBytes)} in ${s(r.data.durationMs)}.`}),children:t.isError?U(x,{error:t.error,onRetry:()=>void t.refetch()}):m===void 0?U(v,{rows:3}):h?W(b,{$min:`180px`,$stretch:!0,children:[U(L,{legend:`Database`,value:o(m.logicalBytes),unit:`${m.stats.pageCount} blocks of ${o(m.stats.pageSize)}`}),U(L,{legend:`Server`,value:le(m.location),unit:`database ${ue(m.location)}`}),U(L,{legend:`Captured bodies`,value:o(m.bodiesBytes),unit:`the request_bodies table`})]}):W(b,{$min:`180px`,$stretch:!0,children:[U(L,{legend:`Database file`,value:o(m.fileBytes),unit:`${m.stats.pageCount} pages of ${o(m.stats.pageSize)}`,trace:U(M,{fraction:_,label:`${e(_,0)} of the file is reclaimable`})}),U(L,{legend:`Reclaimable`,value:o(m.freePageBytes),unit:`${m.stats.freelistCount} free pages`}),U(L,{legend:`Write-ahead log`,value:o(m.walBytes),unit:`folded into every snapshot`}),U(L,{legend:`Captured bodies`,value:o(m.bodiesBytes),unit:`never in a snapshot`}),U(L,{legend:`Snapshots`,value:o(m.snapshots.totalBytes),unit:`${m.snapshots.count} kept`}),U(L,{legend:`Free disk`,value:o(m.freeDiskBytes),unit:m.freeDiskBytes===null?`not readable here`:`on this filesystem`})]})}),U(C,{legend:`Tables`,meta:h?`row counts are the planner's estimates; dead rows await autovacuum`:`size includes each table's indexes`,children:m===void 0?U(v,{rows:4}):W(I,{children:[U(`thead`,{children:W(N,{children:[U(F,{children:`Table`}),U(F,{$align:`right`,children:`Size`}),U(F,{$align:`right`,children:`Rows`}),h?U(F,{$align:`right`,children:`Dead rows`}):null]})}),U(`tbody`,{children:m.tables.map(e=>W(N,{children:[U(P,{children:e.name}),U(P,{$align:`right`,children:o(e.bytes)}),U(P,{$align:`right`,children:d(e.rows)}),h?U(P,{$align:`right`,children:d(e.deadRows??0)}):null]},e.name))})]})}),h?null:W(H,{children:[U(ce,{}),U(ae,{retention:m?.retention})]}),U(D,{open:u,onOpenChange:p,title:`Clear every captured body?`,body:`Every stored prompt and completion is deleted. The requests themselves stay in the log, with their bodies marked pruned. There is no undo: bodies are never in a snapshot.`,confirmLabel:`Clear captured bodies`,busy:c.isPending,onConfirm:()=>c.mutate(void 0,{onSettled:()=>p(!1)})}),U(D,{open:i,onOpenChange:a,title:`Compact database`,body:`Running VACUUM rewrites the database to give back its free pages. It holds the write lock for as long as it takes, so requests in flight will wait, and it needs room on disk for a second copy while it runs.`,confirmLabel:`Compact database`,busy:r.isPending,onConfirm:()=>r.mutate(void 0,{onSettled:()=>a(!1)})})]})}var fe=de;export{fe as component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as e,F as t,I as n,L as r,P as i,Tt as a,Vt as o,Yt as s,bt as c,c as l,dt as u,f as d,ft as f,h as p,i as m,j as h,n as g,o as _,p as v,qt as y,s as b,t as x,u as S,v as C,wt as w,x as T,z as ee}from"./Lamp-
|
|
1
|
+
import{A as e,F as t,I as n,L as r,P as i,Tt as a,Vt as o,Yt as s,bt as c,c as l,dt as u,f as d,ft as f,h as p,i as m,j as h,n as g,o as _,p as v,qt as y,s as b,t as x,u as S,v as C,wt as w,x as T,z as ee}from"./Lamp-DsUSnxN4.js";import{C as E,D,S as O,_ as k,b as A,g as te,i as ne,r as j,t as M,v as N,w as P,x as F}from"./Panel-CWmOTDAP.js";import{_ as re,f as I,m as L,t as ie}from"./Rack-CSpeYQ1D.js";import{n as R,t as ae}from"./TokenBreakdown-DT7or6C9.js";import{n as oe,t as z}from"./Chip-roGX6zyg.js";import{t as B}from"./Meter-stpt3vQu.js";import{i as V,n as H,r as U,t as W}from"./Table-CVDZ69Zx.js";import{t as G}from"./Readout-BTh732hP.js";import{useMemo as K}from"react";import{Fragment as q,jsx as J,jsxs as Y}from"react/jsx-runtime";import X from"styled-components";var se=X(P)`
|
|
2
2
|
font-weight: 500;
|
|
3
3
|
display: block;
|
|
4
4
|
max-width: 24ch;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import{Lt as e,M as t,Nt as n,Rt as r,Tt as i,bt as a,lt as o,w as s,zt as c}from"./Lamp-DsUSnxN4.js";import{C as l,D as u,O as d,_ as f,a as p,b as m,i as h,o as g,r as _,t as v,v as y,w as b,x}from"./Panel-CWmOTDAP.js";import{b as S,i as C,r as w,t as T,v as E}from"./Rack-CSpeYQ1D.js";import{t as ee}from"./CopyValue-FO5yNkRC.js";import{n as D,t as O}from"./chevron-right-DgdKbG-g.js";import{t as k}from"./plus-UgaZwucC.js";import{t as A}from"./Toggle-BTJVC9Se.js";import{t as j}from"./Chip-roGX6zyg.js";import{n as M,r as N,t as P}from"./Field-BYBri2NV.js";import{t as F}from"./Meter-stpt3vQu.js";import{i as I,n as L,r as R,t as te}from"./Table-CVDZ69Zx.js";import{Fragment as z,useState as B}from"react";import{Fragment as V,jsx as H,jsxs as U}from"react/jsx-runtime";import W from"styled-components";var G={name:`calendar-clock`,size:24,node:[[`path`,{d:`M16 14v2.2l1.6 1`,key:`fo4ql5`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`path`,{d:`M21 7.338V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h2.338`,key:`7hb8p4`}],[`path`,{d:`M3 9h5.859`,key:`numkqi`}],[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`circle`,{cx:`16`,cy:`16`,r:`6`,key:`qoo3c4`}]]};G.node;var ne=S(G),K={name:`list-checks`,size:24,node:[[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}],[`path`,{d:`m3 17 2 2 4-4`,key:`1jhpwq`}],[`path`,{d:`m3 7 2 2 4-4`,key:`1obspn`}]]};K.node;var re=S(K);function q(e,t){return e.revokedAt===null?s(e,t)?`active`:`expired`:`revoked`}function ie(e){if(e===null)return``;let t=new Date(e-new Date(e).getTimezoneOffset()*6e4);return Number.isNaN(t.getTime())?``:t.toISOString().slice(0,16)}function ae(e){let t=e.trim();if(t.length===0)return{at:null};let n=new Date(t).getTime();return Number.isFinite(n)?{at:n}:{problem:`"${e}" is not a date`}}var oe=W.p`
|
|
2
|
+
font-size: 12px;
|
|
3
|
+
color: ${({theme:e})=>e.color.down};
|
|
4
|
+
`,se=W.p`
|
|
5
|
+
font-size: 12px;
|
|
6
|
+
color: ${({theme:e})=>e.color.warn};
|
|
7
|
+
`;function ce({apiKey:t,onOpenChange:n}){let r=e(),[i,a]=B(()=>ie(t?.expiresAt??null)),[o,s]=B(null),c=()=>{if(t===null)return;let e=ae(i);if(`problem`in e){s(e.problem);return}s(null),r.mutate({id:t.id,expiresAt:e.at},{onSuccess:()=>n(!1),onError:e=>s(g(e))})},d=t!==null&&q(t,Date.now())===`expired`;return H(C,{open:t!==null,onOpenChange:n,title:`Edit expiry`,description:t===null?void 0:`When "${t.label}" stops being accepted. Leave it blank for never.`,width:`480px`,footer:U(V,{children:[H(u,{type:`button`,onClick:()=>n(!1),children:`Cancel`}),H(u,{type:`button`,$variant:`primary`,disabled:r.isPending,onClick:c,children:r.isPending?`Saving…`:`Save expiry`})]}),children:U(l,{$gap:3,children:[d?H(se,{role:`status`,children:`This key has expired and the gateway is refusing it. Moving the date forward, or clearing it, brings it back.`}):null,H(P,{label:`Expires`,hint:`Your local time. Blank means the key never expires; a date already past expires it now.`,children:e=>H(M,{...e,type:`datetime-local`,value:i,disabled:r.isPending,onChange:e=>a(e.target.value)})}),o===null?null:H(oe,{role:`alert`,children:o})]})})}var J=[{dimension:`requests`,window:`1m`},{dimension:`requests`,window:`5h`},{dimension:`requests`,window:`1w`},{dimension:`tokens`,window:`1m`},{dimension:`tokens`,window:`5h`},{dimension:`tokens`,window:`1w`},{dimension:`spend`,window:`5h`},{dimension:`spend`,window:`1w`},{dimension:`concurrency`,window:null}];function Y(e){return e.window===null?e.dimension:`${e.dimension}:${e.window}`}var le={requests:`Requests`,tokens:`Tokens`,spend:`Spend`,concurrency:`Concurrent`},ue={"1m":`per minute`,"5h":`per 5 hours`,"1w":`per week`};function X(e){let t=le[e.dimension];return e.window===null?t:`${t} ${ue[e.window]}`}function Z(e,t){return e===`spend`?`$${t<1?t.toFixed(4):t.toFixed(2)}`:t.toLocaleString(`en-US`)}function Q(e){return e.used===null||e.limit<=0?null:Math.max(0,e.used/e.limit)}function de(e){let t=null,n=-1;for(let r of e){let e=Q(r);e!==null&&e>n&&(t=r,n=e)}return t}function $(e){let t={};for(let e of J)t[Y(e)]=``;if(e===null)return t;for(let n of J){let r=n.window===null?e.concurrency:n.dimension===`requests`?e.requests?.[n.window]:n.dimension===`tokens`?e.tokens?.[n.window]:n.window===`1m`?void 0:e.spend?.[n.window];r!=null&&(t[Y(n)]=String(r))}return t}function fe(e){let t={},n={},r={},i;for(let a of J){let o=(e[Y(a)]??``).trim();if(o.length===0)continue;let s=Number(o),c=a.dimension===`spend`;if(!Number.isFinite(s)||s<=0||!c&&!Number.isInteger(s))return{problem:c?`${X(a)} must be an amount above zero, or blank for no limit.`:`${X(a)} must be a whole number above zero, or blank for no limit.`};a.window===null?i=s:a.dimension===`requests`?t[a.window]=s:a.dimension===`tokens`?n[a.window]=s:a.window!==`1m`&&(r[a.window]=s)}return{limits:{...Object.keys(t).length>0?{requests:t}:{},...Object.keys(n).length>0?{tokens:n}:{},...Object.keys(r).length>0?{spend:r}:{},...i===void 0?{}:{concurrency:i}}}}var pe=W.div`
|
|
8
|
+
display: grid;
|
|
9
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
10
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
11
|
+
`,me=W.p`
|
|
12
|
+
font-size: 11px;
|
|
13
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
14
|
+
`;function he({draft:e,onChange:t,disabled:n=!1}){return U(l,{$gap:2,children:[H(pe,{children:J.map(r=>{let i=Y(r);return H(P,{label:X(r),children:a=>H(N,{...a,min:r.dimension===`spend`?void 0:1,step:r.dimension===`spend`?`any`:1,disabled:n,value:e[i]??``,placeholder:`none`,onChange:n=>t({...e,[i]:n.target.value})})},i)})}),H(me,{children:`Blank means no limit. Token and spend ceilings are debited after a response completes, so a key at its ceiling is refused on its next request rather than its current one. Concurrency counts requests in flight right now and resets when the gateway restarts.`})]})}var ge=W.p`
|
|
15
|
+
font-size: 12px;
|
|
16
|
+
color: ${({theme:e})=>e.color.down};
|
|
17
|
+
`,_e=W.p`
|
|
18
|
+
font-size: 12px;
|
|
19
|
+
color: ${({theme:e})=>e.color.warn};
|
|
20
|
+
`;function ve({apiKey:e,onOpenChange:t}){let n=r(),[i,a]=B(()=>$(e?.limits??{})),[o,s]=B(null);return H(C,{open:e!==null,onOpenChange:t,title:`Edit limits`,description:e===null?void 0:`What "${e.label}" may do per minute, per five hours, and per week. Every field is a ceiling; blank is no limit.`,width:`640px`,footer:U(V,{children:[H(u,{type:`button`,onClick:()=>t(!1),children:`Cancel`}),H(u,{type:`button`,$variant:`primary`,disabled:n.isPending,onClick:()=>{if(e===null)return;let r=fe(i);if(`problem`in r){s(r.problem);return}s(null),n.mutate({id:e.id,limits:r.limits},{onSuccess:()=>t(!1),onError:e=>s(g(e))})},children:n.isPending?`Saving…`:`Save limits`})]}),children:U(l,{$gap:3,children:[e?.limits===null?H(_e,{role:`status`,children:`The stored limits for this key cannot be read, so the gateway refuses it. Saving here replaces them.`}):null,H(he,{draft:i,onChange:a,disabled:n.isPending}),o===null?null:H(ge,{role:`alert`,children:o})]})})}var ye=W.div`
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
gap: 2px;
|
|
24
|
+
max-height: 190px;
|
|
25
|
+
overflow-y: auto;
|
|
26
|
+
padding: ${({theme:e})=>e.space(1)};
|
|
27
|
+
border: 1px solid ${({theme:e})=>e.color.ruleStrong};
|
|
28
|
+
border-radius: ${({theme:e})=>e.radius.control};
|
|
29
|
+
background: ${({theme:e})=>e.color.panelSunk};
|
|
30
|
+
`,be=W.label`
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
34
|
+
padding: 4px 6px;
|
|
35
|
+
border-radius: 2px;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
font-family: ${({theme:e})=>e.font.mono};
|
|
38
|
+
font-size: 12px;
|
|
39
|
+
|
|
40
|
+
&:hover {
|
|
41
|
+
background: ${({theme:e})=>e.color.panelRaised};
|
|
42
|
+
}
|
|
43
|
+
`,xe=W.p`
|
|
44
|
+
font-size: 11px;
|
|
45
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
46
|
+
`;function Se({configured:e,checked:t,onChange:n,disabled:r}){let i=[...new Set([...e,...t])].sort(),a=(e,r)=>{n(r?[...t,e]:t.filter(t=>t!==e))},o=t.filter(t=>!e.includes(t));return U(`div`,{children:[H(ye,{children:i.map(e=>U(be,{children:[H(`input`,{type:`checkbox`,disabled:r,"aria-label":e,checked:t.includes(e),onChange:t=>a(e,t.target.checked)}),e]},e))}),o.length>0?H(xe,{children:`Some listed models are no longer configured. They stay until you clear them.`}):null,t.length===0?H(f,{children:`With nothing selected this key is allowed no model.`}):null]})}var Ce=W.p`
|
|
47
|
+
font-size: 12px;
|
|
48
|
+
color: ${({theme:e})=>e.color.down};
|
|
49
|
+
`;function we({apiKey:e,onOpenChange:t}){let n=c(),r=i(),[a,o]=B(e?.modelAllowlist===null),[s,d]=B(()=>e?.modelAllowlist===null?[]:e?.modelAllowlist??[]),[p,h]=B(null),_=(r.data??[]).map(e=>e.id);return H(C,{open:e!==null,onOpenChange:t,title:`Edit models`,description:e===null?void 0:`Which models "${e.label}" may ask the gateway for. Sent whole on save.`,width:`640px`,footer:U(V,{children:[H(u,{type:`button`,onClick:()=>t(!1),children:`Cancel`}),H(u,{type:`button`,$variant:`primary`,disabled:n.isPending,onClick:()=>{e!==null&&(h(null),n.mutate({id:e.id,modelAllowlist:a?null:s},{onSuccess:()=>t(!1),onError:e=>h(g(e))}))},children:n.isPending?`Saving…`:`Save models`})]}),children:U(l,{$gap:3,children:[U(l,{$gap:2,children:[U(m,{$gap:2,children:[H(A,{checked:a,label:`Allow every model`,onCheckedChange:e=>{o(e),e&&d([])}}),H(f,{as:`span`,children:`Allow every model`})]}),a?null:H(Se,{configured:_,checked:s,onChange:d,disabled:n.isPending})]}),p===null?null:H(Ce,{role:`alert`,children:p})]})})}var Te=W.div`
|
|
50
|
+
display: grid;
|
|
51
|
+
grid-template-columns: minmax(0, 11rem) minmax(0, 12rem) minmax(0, 1fr) minmax(0, 3.5rem);
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: ${({theme:e})=>e.space(2)} ${({theme:e})=>e.space(4)};
|
|
54
|
+
`,Ee=W.span`
|
|
55
|
+
font-size: 11.5px;
|
|
56
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
57
|
+
`,De=W.p`
|
|
58
|
+
font-size: 11px;
|
|
59
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
60
|
+
`;function Oe({label:e,readings:t}){return U(l,{$gap:3,children:[H(Te,{children:t.map(t=>{let n=X({dimension:t.dimension,window:t.window}),r=Q(t),i=Z(t.dimension,t.limit);return U(z,{children:[H(f,{as:`span`,children:n}),H(y,{children:t.used===null?i:`${Z(t.dimension,t.used)} of ${i}`}),r===null?H(Ee,{children:`in flight now, counted in the gateway process`}):H(F,{fraction:Math.min(1,r),label:`${e}, ${n}, ${Math.round(r*100)}% used`}),H(y,{children:r===null?`—`:`${Math.round(r*100)}%`})]},n)})}),H(De,{children:`Usage counts completed requests still inside each window. Requests in flight are added by the gateway itself and are not shown here.`})]})}var ke=W.p`
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
color: ${({theme:e})=>e.color.warn};
|
|
63
|
+
`,Ae=W.p`
|
|
64
|
+
font-size: 11px;
|
|
65
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
66
|
+
`,je=W.p`
|
|
67
|
+
font-size: 12px;
|
|
68
|
+
color: ${({theme:e})=>e.color.down};
|
|
69
|
+
`,Me=W.p`
|
|
70
|
+
font-size: 12px;
|
|
71
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
72
|
+
`,Ne=W(u)`
|
|
73
|
+
gap: 4px;
|
|
74
|
+
`;function Pe({open:e,onOpenChange:t}){let n=i(),r=o(),[a,s]=B(``),[c,d]=B(!0),[p,h]=B([]),[_,v]=B(()=>$({})),[b,x]=B(!1),[S,w]=B(``),[T,E]=B(!1),[k,j]=B(null),[N,F]=B(null),I=()=>{s(``),d(!0),h([]),v($({})),x(!1),w(``),E(!1),j(null),F(null),r.reset()},L=e=>{e||I(),t(e)},R=Object.values(_).filter(e=>e.trim().length>0).length;return H(C,{open:e,onOpenChange:L,title:k===null?`Create an API key`:`Key created`,description:k===null?`Clients send this key as a bearer token or as x-api-key on every /v1 request.`:void 0,footer:k===null?U(V,{children:[H(u,{type:`button`,onClick:()=>L(!1),children:`Cancel`}),H(u,{type:`button`,$variant:`primary`,disabled:r.isPending,onClick:()=>{let e=fe(_);if(`problem`in e){x(!0),F(e.problem);return}let t=ae(S);if(`problem`in t){F(t.problem);return}F(null),r.mutate({label:a.trim().length===0?`api key`:a.trim(),modelAllowlist:c?null:p,limits:e.limits,bodyLoggingOptOut:T,expiresAt:t.at},{onSuccess:e=>j(e),onError:e=>F(g(e))})},children:r.isPending?`Creating…`:`Create key`})]}):H(u,{type:`button`,$variant:`primary`,onClick:()=>L(!1),children:`I have copied the key`}),children:k===null?U(l,{$gap:3,children:[H(P,{label:`Label`,hint:`Names the client this key belongs to, e.g. laptop or CI.`,children:e=>H(M,{...e,value:a,placeholder:`api key`,onChange:e=>s(e.target.value)})}),U(l,{$gap:2,children:[U(m,{$gap:2,children:[H(A,{checked:c,label:`Allow every model`,onCheckedChange:d}),H(f,{as:`span`,children:`Allow every model`})]}),c?null:U(V,{children:[H(Se,{configured:(n.data??[]).map(e=>e.id),checked:p,onChange:h}),p.length===0?H(ke,{children:`With no model selected this key is allowed nothing and every request it makes will be refused.`}):null]})]}),U(l,{$gap:2,children:[U(m,{$gap:2,children:[U(Ne,{type:`button`,$size:`sm`,"aria-expanded":b,onClick:()=>x(e=>!e),children:[H(b?D:O,{}),`Limits`]}),H(f,{as:`span`,children:R===0?`no limits; this key is unbounded`:`${R} limit${R===1?``:`s`} set`})]}),b?H(he,{draft:_,onChange:v}):null]}),H(P,{label:`Expires`,hint:`Optional. Your local time; blank means the key never expires.`,children:e=>H(M,{...e,type:`datetime-local`,value:S,onChange:e=>w(e.target.value)})}),U(l,{$gap:2,children:[U(m,{$gap:2,children:[H(A,{checked:T,label:`Never record this key's bodies`,onCheckedChange:E}),H(f,{as:`span`,children:`Never record this key's bodies`})]}),H(Ae,{children:`Suppresses body capture for this key whatever the gateway setting says. Choose it for a client whose payloads must not be retained. It cannot be changed after the key is created — issue a new key instead.`})]}),N===null?null:H(je,{role:`alert`,children:N})]}):U(l,{$gap:3,children:[H(Me,{children:`This is the only time the key is shown. The gateway keeps a hash, so a lost key has to be replaced rather than recovered.`}),H(ee,{value:k.key,label:`Copy API key`}),U(m,{$gap:2,children:[H(f,{children:`Label`}),H(y,{children:k.label}),H(f,{children:`Prefix`}),H(y,{children:k.prefix})]})]})})}var Fe=W(m)`
|
|
75
|
+
gap: 4px;
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
max-width: 34ch;
|
|
78
|
+
`,Ie=W.span`
|
|
79
|
+
color: ${({theme:e})=>e.color.inkFaint};
|
|
80
|
+
`,Le=W.span`
|
|
81
|
+
display: block;
|
|
82
|
+
font-size: 11px;
|
|
83
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
84
|
+
`,Re=W.span`
|
|
85
|
+
font-size: 11px;
|
|
86
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
87
|
+
`,ze=W.div`
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
align-items: flex-end;
|
|
91
|
+
gap: 2px;
|
|
92
|
+
`;function Be(e){if(e===null)return`usage not counted here`;let t=Q(e);return`${X({dimension:e.dimension,window:e.window})} ${Z(e.dimension,e.limit)}, ${t===null?`—`:Math.round(t*100)}% used`}function Ve(){let e=a(),r=n(),[i,o]=B(!1),[s,c]=B(null),[l,g]=B(null),[y,S]=B(null),[C,ee]=B(null),[A,M]=B(null),N=Date.now(),P=e.data??[],F=P.filter(e=>q(e,N)===`active`),W=e.isLoading?`Reading issued keys…`:P.length===0?`No keys exist, so nothing can call this gateway yet.`:`${F.length} active key${F.length===1?``:`s`} of ${P.length} ever issued.`;return U(V,{children:[H(T,{legend:`Keys`,title:`Gateway API keys`,summary:W,actions:U(u,{type:`button`,$variant:`primary`,onClick:()=>o(!0),children:[H(k,{}),`Create a key`]})}),H(v,{legend:`Issued keys`,meta:`${P.length}`,flush:!0,children:e.isError?H(h,{error:e.error,onRetry:()=>void e.refetch()}):e.isLoading?H(`div`,{style:{padding:12},children:H(p,{rows:4})}):P.length===0?H(_,{legend:`No keys`,message:`Create a key and give it to a client. The key is shown once, at creation.`,action:H(u,{type:`button`,$variant:`primary`,$size:`sm`,onClick:()=>o(!0),children:`Create a key`})}):H(x,{children:U(te,{children:[H(`thead`,{children:U(`tr`,{children:[H(R,{children:`Label`}),H(R,{children:`Prefix`}),H(R,{children:`Allowed models`}),H(R,{$align:`right`,children:`Limits`}),H(R,{$align:`right`,children:`Created`}),H(R,{children:`Body capture`}),H(R,{children:`Status`}),H(R,{})]})}),H(`tbody`,{children:P.map(e=>{let n=C===e.id,r=de(e.limitUsage),i=q(e,N);return U(z,{children:[U(I,{children:[H(L,{children:H(b,{style:{maxWidth:`24ch`,display:`block`},children:e.label})}),U(L,{$mono:!0,children:[e.prefix,`…`]}),H(L,{children:e.modelAllowlist===null?H(f,{children:`every model`}):e.modelAllowlist.length===0?H(j,{$tone:`down`,children:`no models`}):H(Fe,{children:e.modelAllowlist.map(e=>H(j,{children:e},e))})}),H(L,{$align:`right`,children:e.limits===null?H(j,{$tone:`down`,children:`unreadable`}):e.limitUsage.length===0?H(f,{children:`no limits`}):U(ze,{children:[U(`span`,{children:[e.limitUsage.length,` limit`,e.limitUsage.length===1?``:`s`]}),H(Re,{children:Be(r)})]})}),H(L,{$align:`right`,$mono:!0,children:t(e.createdAt)}),H(L,{children:e.bodyLoggingOptOut?H(j,{children:`no bodies`}):H(f,{children:`—`})}),U(L,{children:[i===`revoked`?H(Ie,{title:t(e.revokedAt??0),children:H(j,{children:`revoked`})}):i===`expired`?H(j,{$tone:`down`,children:`expired`}):H(j,{$tone:`ok`,children:`active`}),e.expiresAt===null?null:U(Le,{children:[i===`expired`?`expired`:`expires`,` `,t(e.expiresAt)]})]}),H(L,{$align:`right`,children:U(m,{$gap:1,$justify:`flex-end`,children:[e.limitUsage.length===0?null:H(d,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-expanded":n,"aria-label":`${n?`Hide`:`Show`} limits for ${e.label}`,title:`${n?`Hide`:`Show`} limits for ${e.label}`,onClick:()=>ee(n?null:e.id),children:H(n?D:O,{})}),e.revokedAt===null?U(V,{children:[H(d,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-label":`Edit models for ${e.label}`,title:`Edit models for ${e.label}`,onClick:()=>g(e),children:H(re,{})}),H(d,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-label":`Edit limits for ${e.label}`,title:`Edit limits for ${e.label}`,onClick:()=>c(e),children:H(E,{})}),H(d,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-label":`Edit expiry for ${e.label}`,title:`Edit expiry for ${e.label}`,onClick:()=>S(e),children:H(ne,{})}),H(u,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>M(e),children:`Revoke`})]}):null]})})]}),n?H(I,{children:H(L,{colSpan:8,children:H(Oe,{label:e.label,readings:e.limitUsage})})}):null]},e.id)})})]})})}),H(Pe,{open:i,onOpenChange:o}),H(ve,{apiKey:s,onOpenChange:e=>{e||c(null)}},s?.id??`none`),H(we,{apiKey:l,onOpenChange:e=>{e||g(null)}},l?.id??`none`),H(ce,{apiKey:y,onOpenChange:e=>{e||S(null)}},y?.id??`none`),H(w,{open:A!==null,onOpenChange:e=>{e||M(null)},title:`Revoke key`,body:A===null?``:`Revoking "${A.label}" refuses its next request. The key stays listed so past usage keeps its attribution, and it cannot be un-revoked.`,confirmLabel:`Revoke key`,busy:r.isPending,onConfirm:()=>{A!==null&&r.mutate(A.id,{onSettled:()=>M(null)})}})]})}var He=Ve;export{He as component};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{At as e,J as t,V as n,bt as r,ft as i,j as a,l as o,u as s,wt as c}from"./Lamp-
|
|
1
|
+
import{At as e,J as t,V as n,bt as r,ft as i,j as a,l as o,u as s,wt as c}from"./Lamp-DsUSnxN4.js";import{C as l,D as u,_ as d,a as f,b as p,i as m,r as h,t as g,x as _}from"./Panel-CWmOTDAP.js";import{_ as v,i as y,t as b}from"./Rack-CSpeYQ1D.js";import{t as x}from"./Chip-roGX6zyg.js";import{i as S,n as C}from"./Field-BYBri2NV.js";import{i as w,n as T,r as E,t as D}from"./RequestTable-xpG3dPST.js";import{useMemo as O,useState as k}from"react";import{Fragment as A,jsx as j,jsxs as M}from"react/jsx-runtime";import N from"styled-components";var P={none:{legend:`Not captured`,message:`Body capture was not running for this request. It needs OMNI_BODY_LOGGING_ALLOWED in the environment and the body logging setting turned on, and the calling key must not have opted out.`},missing:{legend:`Captured, then lost`,message:`This request was captured, but its artifact is no longer on disk. Retention or the row cap has since pruned it, or something removed the file underneath the gateway.`},corrupt:{legend:`Captured, but unreadable`,message:`This request was captured and the artifact is still on disk, but it failed its checksum or would not decrypt. Changing OMNI_ENCRYPTION_KEY invalidates every artifact written under the old one.`}},F=new Intl.NumberFormat(`en-US`),I=N.p`
|
|
2
2
|
font-size: 12px;
|
|
3
3
|
color: ${({theme:e})=>e.color.inkDim};
|
|
4
4
|
max-width: 62ch;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import{D as e,Ot as t,Pt as n,Tt as r,U as i,Vt as a,ft as o,gt as s,vt as c}from"./Lamp-DsUSnxN4.js";import{C as l,D as u,O as d,S as f,_ as p,a as m,b as h,i as g,o as _,r as v,t as y,v as b,w as x}from"./Panel-CWmOTDAP.js";import{b as S,m as C,r as w,t as T}from"./Rack-CSpeYQ1D.js";import{t as E}from"./plus-UgaZwucC.js";import{t as D}from"./trash-IE0YvGCJ.js";import{t as O}from"./Toggle-BTJVC9Se.js";import{n as ee,t as k}from"./Chip-roGX6zyg.js";import{i as A,n as j,r as M,t as te}from"./Field-BYBri2NV.js";import{t as N}from"./Meter-stpt3vQu.js";import{useEffect as ne,useId as re,useState as P}from"react";import{Fragment as F,jsx as I,jsxs as L}from"react/jsx-runtime";import R from"styled-components";var ie={name:`play`,size:24,node:[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]};ie.node;var ae=S(ie),oe={name:`rotate-ccw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]};oe.node;var se=S(oe),z=[`tier`,`health`,`quota`,`cost`,`latency`,`load`],ce={tier:`How preferred this tier is`,health:`Consecutive failures and breaker state`,quota:`Headroom in the tightest window, against how much of it is left`,cost:`Price of this request against the other candidates`,latency:`Observed time to first token`,load:`Requests in flight on this pair right now`},le=R.li`
|
|
2
|
+
padding: ${({theme:e})=>e.space(2)} 0;
|
|
3
|
+
border-bottom: 1px solid ${({theme:e})=>e.color.rule};
|
|
4
|
+
|
|
5
|
+
&:last-child {
|
|
6
|
+
border-bottom: 0;
|
|
7
|
+
}
|
|
8
|
+
`,ue=R(b)`
|
|
9
|
+
width: 22px;
|
|
10
|
+
color: ${({theme:e})=>e.color.inkFaint};
|
|
11
|
+
flex: none;
|
|
12
|
+
`,de=R(k)`
|
|
13
|
+
border-color: ${({theme:e})=>e.color.ok};
|
|
14
|
+
color: ${({theme:e})=>e.color.ok};
|
|
15
|
+
background: ${({theme:e})=>e.color.okWash};
|
|
16
|
+
`,fe=R.div`
|
|
17
|
+
display: grid;
|
|
18
|
+
grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
|
|
19
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
20
|
+
margin-top: ${({theme:e})=>e.space(2)};
|
|
21
|
+
padding-left: 30px;
|
|
22
|
+
`,pe=R.div`
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: 3px;
|
|
26
|
+
min-width: 0;
|
|
27
|
+
`,me=R.div`
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: baseline;
|
|
30
|
+
justify-content: space-between;
|
|
31
|
+
gap: 6px;
|
|
32
|
+
`,he=R.li`
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
36
|
+
padding: 5px 0;
|
|
37
|
+
`,ge=R(h)`
|
|
38
|
+
gap: ${({theme:e})=>e.space(3)};
|
|
39
|
+
flex-wrap: wrap;
|
|
40
|
+
`,B=R.label`
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: 6px;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
font-size: 12.5px;
|
|
46
|
+
`,_e=R.p`
|
|
47
|
+
font-size: 12px;
|
|
48
|
+
color: ${({theme:e})=>e.color.down};
|
|
49
|
+
`;function V(e,t,n){return(e[t]??0)*n[t]}function ve({modelId:e}){let[t,n]=P({tools:!1,images:!1,reasoning:!1}),[r,i]=P(null),[o,s]=P(null),d=a(),m=c(),g=d.data?.weights,S=()=>{e!==null&&(s(null),m.mutate({modelId:e,need:t},{onSuccess:e=>i(e),onError:e=>{i(null),s(_(e))}}))},C=new Map(z.map(e=>[e,Math.max(1e-4,...(r?.candidates??[]).map(t=>g===void 0?0:Math.abs(V(t.reasons,e,g))))]));return I(y,{legend:`Explain`,meta:e??`no model selected`,actions:L(u,{type:`button`,$size:`sm`,$variant:`primary`,disabled:e===null||m.isPending,onClick:S,children:[I(ae,{}),m.isPending?`Ranking…`:`Rank candidates`]}),children:L(l,{$gap:3,children:[L(l,{$gap:1,children:[I(p,{children:`Pretend the request needs`}),L(ge,{children:[L(B,{children:[I(O,{checked:t.tools,label:`Probe request uses tools`,onCheckedChange:e=>n({...t,tools:e})}),`Tools`]}),L(B,{children:[I(O,{checked:t.images,label:`Probe request includes an image`,onCheckedChange:e=>n({...t,images:e})}),`Images`]}),L(B,{children:[I(O,{checked:t.reasoning,label:`Probe request asks for reasoning`,onCheckedChange:e=>n({...t,reasoning:e})}),`Reasoning`]})]})]}),o===null?null:I(_e,{children:o}),r===null?I(v,{legend:`Not ranked yet`,message:e===null?`Select a model to see which account the router would pick for it.`:`Run the ranking to see which account wins, by how much, and what was filtered out.`}):L(l,{$gap:3,children:[L(h,{$gap:2,$wrap:!0,children:[I(k,{$tone:`accent`,children:r.strategy}),r.deterministic?null:I(k,{$tone:`warn`,children:`order varies per request`}),I(f,{}),L(p,{children:[r.candidates.length,` eligible · `,r.excluded.length,` filtered out`]})]}),r.candidates.length===0?I(v,{legend:`Nothing eligible`,message:`Every target was filtered out. The reasons below say which rule removed each one.`}):I(`ul`,{children:r.candidates.map((e,t)=>L(le,{children:[L(h,{$gap:2,children:[I(ue,{children:t+1}),I(ee,{provider:e.provider}),I(x,{style:{maxWidth:`22ch`},children:e.credentialLabel}),I(b,{$dim:!0,children:e.model}),L(k,{children:[`tier `,e.tier]}),I(f,{}),t===0?I(de,{children:`would be used`}):null,I(b,{children:e.score.toFixed(2)})]}),g===void 0?null:I(fe,{children:z.map(t=>{let n=V(e.reasons,t,g),r=C.get(t)??1;return L(pe,{title:ce[t],children:[L(me,{children:[I(p,{children:t}),I(b,{$dim:!0,$size:`10.5px`,children:n.toFixed(2)})]}),I(N,{fraction:Math.abs(n)/r,height:4,tone:`var(--accent)`,label:`${t} contributes ${n.toFixed(2)} of ${e.score.toFixed(2)}`})]},t)})})]},`${e.credentialId}:${e.model}`))}),r.excluded.length===0?null:L(l,{$gap:1,children:[I(p,{children:`Filtered out`}),I(`ul`,{children:r.excluded.map(e=>L(he,{children:[I(b,{$dim:!0,children:e.model}),I(b,{$dim:!0,children:e.credentialId}),I(f,{}),I(k,{$tone:e.reason.startsWith(`capability`)?`warn`:`down`,children:e.reason})]},`${e.credentialId}:${e.model}:${e.reason}`))})]})]})]})})}function H(e,t,n){return i(e,t)?.models.find(e=>e.id===n)}function U(e,t,n){let r=i(e,t);return r===void 0?null:r.models.find(e=>e.id===n)?.auth??r.authTypes}var W=[{id:`score`,label:`Best score`,blurb:`Rank every eligible target by the routing weights and take the best one.`},{id:`priority`,label:`Lowest tier`,blurb:`Always prefer the lowest tier. Score only breaks ties inside a tier.`},{id:`roundRobin`,label:`Round robin`,blurb:`Take whichever eligible target has been idle longest, to spread load evenly.`},{id:`weighted`,label:`Weighted draw`,blurb:`Pick at random, biased by weight. The order differs from request to request.`}],G=0;function K(){return G+=1,`target-${G}`}function q(e,t,n){let r=H(e,t,n)?.pricing;return r===void 0?null:{costInput:String(r.input),costOutput:String(r.output),costCacheRead:String(r.cacheRead),costCacheWrite5m:String(r.cacheWrite5m),costCacheWrite1h:String(r.cacheWrite1h)}}function ye(e,t,n){let r=H(e,t,n)?.limits;return r===void 0?null:{contextWindow:String(r.contextWindow),maxOutputTokens:String(r.maxOutputTokens)}}var be={oauth:`OAuth`,apiKey:`an API key`};function J(e){return e.map(e=>be[e]).join(` or `)}function xe(e){let t=Object.create(null);for(let n of e){let e=t[n.provider]??[];e.includes(n.authType)||e.push(n.authType),t[n.provider]=e}return t}function Y(e,t,n,r){let i=r[t];if(i===void 0||i.length===0)return!0;let a=U(e,t,n);return a===null||a.some(e=>i.includes(e))}function Se(e,t,n){let r=i(e,t);return r===void 0?[]:r.models.filter(r=>Y(e,t,r.id,n))}function Ce(e,t,n,r){if(n.trim().length===0||Y(e,t,n,r))return null;let i=r[t]??[];return`${t} serves this model to ${J(U(e,t,n)??[])} only, and every ${t} account here is ${J(i)}. Requests routed here will fail.`}function we(t,n){let r={provider:t.provider,endpointId:t.endpointId};return n.filter(t=>e(r,t)).map(e=>({id:e.id,label:e.accountEmail??e.label}))}function Te(e,t,n){return e.length===0||n.length===0||we(t,n).some(t=>t.id===e)?null:`No connected account has this id. Requests routed here will fail rather than falling back to another account.`}function Ee(e,t){return{...e,endpointId:t,...t===e.endpointId?{}:{credentialId:``}}}function De(e,t,n){return{...t,...n,...q(e,n.provider,n.model)??{},...n.provider===t.provider?{}:{credentialId:``},contextWindow:``,maxOutputTokens:``}}function Oe(e,t){let n=t??e[0]?.id??`anthropic`,r=i(e,n)?.defaultModel??``,a=q(e,n,r);return{key:K(),provider:n,endpointId:``,model:r,tier:`1`,weight:`1`,costInput:a?.costInput??`0`,costOutput:a?.costOutput??`0`,costCacheRead:a?.costCacheRead??``,costCacheWrite5m:a?.costCacheWrite5m??``,costCacheWrite1h:a?.costCacheWrite1h??``,contextWindow:``,maxOutputTokens:``,credentialId:``,tools:!0,images:!0,reasoning:!0}}function ke(e){return{id:``,strategy:`score`,isAlias:!1,targets:[Oe(e)]}}function Ae(e){return{id:e.id,strategy:e.strategy,isAlias:e.isAlias,targets:e.targets.map(e=>({key:K(),provider:e.provider,endpointId:e.provider===`custom`?e.endpointId??``:``,model:e.model,tier:String(e.tier),weight:String(e.weight),costInput:String(e.costPerMTok.input),costOutput:String(e.costPerMTok.output),costCacheRead:e.costPerMTok.cacheRead===void 0?``:String(e.costPerMTok.cacheRead),costCacheWrite5m:e.costPerMTok.cacheWrite5m===void 0?``:String(e.costPerMTok.cacheWrite5m),costCacheWrite1h:e.costPerMTok.cacheWrite1h===void 0?``:String(e.costPerMTok.cacheWrite1h),contextWindow:e.contextWindow===void 0?``:String(e.contextWindow),maxOutputTokens:e.maxOutputTokens===void 0?``:String(e.maxOutputTokens),credentialId:e.credentialId??``,tools:e.capabilities.tools,images:e.capabilities.images,reasoning:e.capabilities.reasoning}))}}function je(e){let t=e.id.trim();if(t.length===0)return{ok:!1,problem:`Give the model a name clients will ask for.`};if(e.targets.length===0)return{ok:!1,problem:`A model needs at least one target to route to.`};let n=[];for(let[t,r]of e.targets.entries()){let e=`Target ${t+1}`,i=r.endpointId.trim(),a=r.credentialId.trim();if(r.provider===`custom`&&i.length===0)return{ok:!1,problem:`${e} needs a custom endpoint.`};let o=r.model.trim();if(o.length===0)return{ok:!1,problem:`${e} needs a provider model name.`};let s=Number(r.tier);if(!Number.isInteger(s)||s<1)return{ok:!1,problem:`${e}: tier must be a whole number of 1 or more.`};let c=Number(r.weight);if(!Number.isFinite(c)||c<=0)return{ok:!1,problem:`${e}: weight must be greater than zero.`};let l=Number(r.costInput),u=Number(r.costOutput);if(!Number.isFinite(l)||l<0||!Number.isFinite(u)||u<0)return{ok:!1,problem:`${e}: prices cannot be negative.`};let d=r.costCacheRead.trim().length>0,f=Number(r.costCacheRead);if(d&&(!Number.isFinite(f)||f<0))return{ok:!1,problem:`${e}: the cache-read price cannot be negative.`};let p=r.costCacheWrite5m.trim().length>0,m=Number(r.costCacheWrite5m);if(p&&(!Number.isFinite(m)||m<0))return{ok:!1,problem:`${e}: the 5m cache-write price must be a number of 0 or more.`};let h=r.costCacheWrite1h.trim().length>0,g=Number(r.costCacheWrite1h);if(h&&(!Number.isFinite(g)||g<0))return{ok:!1,problem:`${e}: the 1h cache-write price must be a number of 0 or more.`};let _=r.contextWindow.trim().length>0,v=Number(r.contextWindow);if(_&&(!Number.isInteger(v)||v<1))return{ok:!1,problem:`${e}: the context window must be a whole number of tokens.`};let y=r.maxOutputTokens.trim().length>0,b=Number(r.maxOutputTokens);if(y&&(!Number.isInteger(b)||b<1))return{ok:!1,problem:`${e}: the output limit must be a whole number of tokens.`};n.push({provider:r.provider,...r.provider===`custom`?{endpointId:i}:{},model:o,tier:s,weight:c,costPerMTok:{input:l,output:u,...d?{cacheRead:f}:{},...p?{cacheWrite5m:m}:{},...h?{cacheWrite1h:g}:{}},..._?{contextWindow:v}:{},...y?{maxOutputTokens:b}:{},...a.length>0?{credentialId:a}:{},capabilities:{tools:r.tools,images:r.images,reasoning:r.reasoning}})}return{ok:!0,model:{id:t,strategy:e.strategy,isAlias:e.isAlias,targets:n}}}var Me=R.fieldset`
|
|
50
|
+
border: 1px solid ${({theme:e})=>e.color.rule};
|
|
51
|
+
border-left: 3px solid ${({$provider:e})=>C(e)};
|
|
52
|
+
border-radius: ${({theme:e})=>e.radius.control};
|
|
53
|
+
padding: ${({theme:e})=>e.space(3)};
|
|
54
|
+
margin: 0;
|
|
55
|
+
background: ${({theme:e})=>e.color.panelSunk};
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
gap: ${({theme:e})=>e.space(3)};
|
|
59
|
+
min-width: 0;
|
|
60
|
+
`,Ne=R.div`
|
|
61
|
+
display: grid;
|
|
62
|
+
grid-template-columns: minmax(140px, 1.4fr) minmax(160px, 2fr) 72px 72px;
|
|
63
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
64
|
+
align-items: end;
|
|
65
|
+
|
|
66
|
+
@media (max-width: 720px) {
|
|
67
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
68
|
+
}
|
|
69
|
+
`,X=R.div`
|
|
70
|
+
display: grid;
|
|
71
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
72
|
+
gap: ${({theme:e})=>e.space(2)};
|
|
73
|
+
align-items: end;
|
|
74
|
+
`,Z=R.div`
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
gap: 4px;
|
|
78
|
+
min-width: 0;
|
|
79
|
+
`,Pe=R(h)`
|
|
80
|
+
gap: ${({theme:e})=>e.space(3)};
|
|
81
|
+
flex-wrap: wrap;
|
|
82
|
+
`,Fe=R.p`
|
|
83
|
+
font-size: 11.5px;
|
|
84
|
+
color: ${({theme:e})=>e.color.down};
|
|
85
|
+
margin: 0;
|
|
86
|
+
`,Q=R.label`
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 6px;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
`;function Ie({target:e,index:t,onChange:n,onRemove:r,removable:a,catalog:o,endpoints:s,held:c,credentials:m}){let g=re(),_=i(o,e.provider),v=Se(o,e.provider,c),y=Ce(o,e.provider,e.model,c),b=we(e,m),x=Te(e.credentialId,e,m),S=(t,r)=>{n({...e,[t]:r})},C=q(o,e.provider,e.model),w=ye(o,e.provider,e.model),T=t=>{n(De(o,e,t))};return L(Me,{$provider:e.provider,children:[L(h,{$gap:2,children:[L(p,{as:`legend`,children:[`Target `,t+1]}),I(f,{}),I(d,{type:`button`,$variant:`ghost`,$size:`sm`,disabled:!a,"aria-label":`Remove target ${t+1}`,title:a?`Remove target ${t+1}`:`A model needs at least one target`,onClick:r,children:I(D,{})})]}),L(Ne,{children:[L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-provider`,children:`Provider`}),L(A,{id:`${g}-provider`,value:e.provider,onChange:t=>{let n=t.target.value,r=i(o,n),a=r?.models.some(t=>t.id===e.model)??!1;T({provider:n,model:a?e.model:r?.defaultModel??``})},children:[o.map(e=>I(`option`,{value:e.id,children:e.label},e.id)),_===void 0?L(`option`,{value:e.provider,children:[e.provider,` (not in the catalog)`]}):null]})]}),e.provider===`custom`?L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-endpoint`,children:`Endpoint`}),L(A,{id:`${g}-endpoint`,value:e.endpointId,onChange:t=>n(Ee(e,t.target.value)),children:[I(`option`,{value:``,children:`Choose endpoint`}),s.map(e=>I(`option`,{value:e.id,children:e.label},e.id))]})]}):null,L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-model`,children:`Provider model`}),I(j,{id:`${g}-model`,list:`${g}-catalog`,value:e.model,placeholder:_?.defaultModel??``,onChange:t=>T({provider:e.provider,model:t.target.value})}),I(`datalist`,{id:`${g}-catalog`,children:v.map(e=>I(`option`,{value:e.id,children:e.label},e.id))}),y===null?null:I(Fe,{role:`note`,children:y})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-tier`,children:`Tier`}),I(M,{id:`${g}-tier`,min:1,step:1,value:e.tier,onChange:e=>S(`tier`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-weight`,children:`Weight`}),I(M,{id:`${g}-weight`,min:0,step:.1,value:e.weight,onChange:e=>S(`weight`,e.target.value)})]})]}),I(l,{$gap:1,children:L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-account`,children:`Account`}),L(A,{id:`${g}-account`,value:e.credentialId,onChange:e=>S(`credentialId`,e.target.value),children:[I(`option`,{value:``,children:`Any account`}),b.map(e=>I(`option`,{value:e.id,children:e.label},e.id)),x===null?null:L(`option`,{value:e.credentialId,children:[e.credentialId,` (removed)`]})]}),x===null?null:I(Fe,{role:`note`,children:x})]})}),L(l,{$gap:1,children:[L(h,{$gap:2,children:[I(p,{children:`Price per million tokens`}),I(f,{}),C===null?I(p,{as:`span`,children:`not in the catalog — price it yourself`}):L(u,{type:`button`,$size:`sm`,$variant:`ghost`,disabled:e.costInput===C.costInput&&e.costOutput===C.costOutput&&e.costCacheRead===C.costCacheRead&&e.costCacheWrite5m===C.costCacheWrite5m&&e.costCacheWrite1h===C.costCacheWrite1h,onClick:()=>n({...e,...C}),children:[I(se,{}),`Use list price`]})]}),L(X,{children:[L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-in`,children:`Input`}),I(M,{id:`${g}-in`,min:0,step:.01,value:e.costInput,onChange:e=>S(`costInput`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-out`,children:`Output`}),I(M,{id:`${g}-out`,min:0,step:.01,value:e.costOutput,onChange:e=>S(`costOutput`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-cache`,children:`Cache read`}),I(M,{id:`${g}-cache`,min:0,step:.01,placeholder:`same as input`,value:e.costCacheRead,onChange:e=>S(`costCacheRead`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-write5m`,children:`Cache write 5m`}),I(M,{id:`${g}-write5m`,min:0,step:.01,placeholder:`1.25x input`,value:e.costCacheWrite5m,onChange:e=>S(`costCacheWrite5m`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-write1h`,children:`Cache write 1h`}),I(M,{id:`${g}-write1h`,min:0,step:.01,placeholder:`2x input`,value:e.costCacheWrite1h,onChange:e=>S(`costCacheWrite1h`,e.target.value)})]})]})]}),L(l,{$gap:1,children:[L(h,{$gap:2,children:[I(p,{children:`Token limits`}),I(f,{}),w===null?I(p,{as:`span`,children:`not in the catalog — state them yourself`}):I(p,{as:`span`,children:`left empty, the published figures are used — and for an OpenAI target, the narrower ones its OAuth backend allows`})]}),L(X,{children:[L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-context`,children:`Context window`}),I(M,{id:`${g}-context`,min:1,step:1024,placeholder:w?.contextWindow??`published`,value:e.contextWindow,onChange:e=>S(`contextWindow`,e.target.value)})]}),L(Z,{children:[I(p,{as:`label`,htmlFor:`${g}-maxout`,children:`Max output`}),I(M,{id:`${g}-maxout`,min:1,step:1024,placeholder:w?.maxOutputTokens??`published`,value:e.maxOutputTokens,onChange:e=>S(`maxOutputTokens`,e.target.value)})]})]})]}),L(l,{$gap:1,children:[I(p,{children:`Capabilities`}),L(Pe,{children:[L(Q,{children:[I(O,{checked:e.tools,label:`Target ${t+1} supports tools`,onCheckedChange:e=>S(`tools`,e)}),`Tools`]}),L(Q,{children:[I(O,{checked:e.images,label:`Target ${t+1} supports images`,onCheckedChange:e=>S(`images`,e)}),`Images`]}),L(Q,{children:[I(O,{checked:e.reasoning,label:`Target ${t+1} supports reasoning`,onCheckedChange:e=>S(`reasoning`,e)}),`Reasoning`]})]})]})]})}var Le=R.p`
|
|
92
|
+
font-size: 11.5px;
|
|
93
|
+
color: ${({theme:e})=>e.color.inkDim};
|
|
94
|
+
`,Re=R.p`
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
color: ${({theme:e})=>e.color.down};
|
|
97
|
+
`,ze=R.p`
|
|
98
|
+
font-size: 12px;
|
|
99
|
+
color: ${({theme:e})=>e.color.ok};
|
|
100
|
+
`,Be=R(h)`
|
|
101
|
+
gap: 8px;
|
|
102
|
+
`;function Ve({model:e,onSaved:r,onDeleted:i}){let a=t().data??[],[c,d]=P(()=>e===null?ke(a):Ae(e)),[m,g]=P(null),[v,b]=P(!1),[x,S]=P(!1),C=n(),T=s(),D=o(),ee=xe(D.data??[]),k=(D.data??[]).filter(e=>e.provider===`custom`).map(e=>({id:String(e.providerData.endpointId??``),label:String(e.providerData.endpointLabel??e.providerData.endpointId??``)})).filter((e,t,n)=>e.id.length>0&&n.findIndex(t=>t.id===e.id)===t),M=e?.id??null;ne(()=>{d(e===null?ke(a):Ae(e)),g(null),b(!1)},[M]);let N=W.find(e=>e.id===c.strategy);return L(F,{children:[I(y,{legend:e===null?`New model`:`Edit model`,meta:e===null?void 0:e.id,actions:L(F,{children:[e===null?null:I(u,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>S(!0),children:`Delete`}),I(u,{type:`button`,$variant:`primary`,$size:`sm`,disabled:C.isPending,onClick:()=>{b(!1);let e=je(c);if(!e.ok){g(e.problem);return}g(null),C.mutate(e.model,{onSuccess:()=>{b(!0),r(e.model.id)},onError:e=>g(_(e))})},children:C.isPending?`Saving…`:e===null?`Create model`:`Save changes`})]}),children:L(l,{$gap:3,children:[I(te,{label:`Model name`,hint:e===null?`What clients send as the model. Anything not listed here is rejected.`:`Fixed once created. To rename, create a model under the new name and delete this one.`,children:t=>I(j,{...t,value:c.id,disabled:e!==null,placeholder:`fast`,onChange:e=>d({...c,id:e.target.value})})}),I(te,{label:`Routing strategy`,children:e=>I(A,{...e,value:c.strategy,onChange:e=>d({...c,strategy:e.target.value}),children:W.map(e=>I(`option`,{value:e.id,children:e.label},e.id))})}),N===void 0?null:I(Le,{children:N.blurb}),L(Be,{children:[I(O,{checked:c.isAlias,label:`This model is an alias for a provider model name`,onCheckedChange:e=>d({...c,isAlias:e})}),L(l,{$gap:0,children:[I(p,{as:`span`,children:`Alias`}),I(Le,{children:`Mark this when the name mirrors a provider's own model name.`})]})]}),L(l,{$gap:2,children:[L(h,{children:[I(p,{children:`Targets`}),I(f,{}),L(u,{type:`button`,$size:`sm`,onClick:()=>d({...c,targets:[...c.targets,Oe(a,c.targets.at(-1)?.provider)]}),children:[I(E,{}),`Add target`]})]}),c.targets.map((e,t)=>I(Ie,{target:e,index:t,removable:c.targets.length>1,catalog:a,endpoints:k,held:ee,credentials:D.data??[],onChange:t=>d({...c,targets:c.targets.map(n=>n.key===e.key?t:n)}),onRemove:()=>d({...c,targets:c.targets.filter(t=>t.key!==e.key)})},e.key))]}),m===null?null:I(Re,{role:`alert`,children:m}),v&&m===null?I(ze,{role:`status`,children:`Saved.`}):null]})}),I(w,{open:x,onOpenChange:S,title:`Delete model`,body:e===null?``:`Deleting "${e.id}" makes it unroutable. Clients asking for it will get a model-unavailable error, and any key allowlisting it keeps a name that no longer resolves.`,confirmLabel:`Delete model`,busy:T.isPending,onConfirm:()=>{e!==null&&T.mutate(e.id,{onSuccess:()=>{S(!1),i()},onError:e=>{S(!1),g(_(e))}})}})]})}var He=R.div`
|
|
103
|
+
display: grid;
|
|
104
|
+
grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
|
|
105
|
+
gap: ${({theme:e})=>e.space(4)};
|
|
106
|
+
align-items: start;
|
|
107
|
+
|
|
108
|
+
@media (max-width: 980px) {
|
|
109
|
+
grid-template-columns: minmax(0, 1fr);
|
|
110
|
+
}
|
|
111
|
+
`,Ue=R(l)`
|
|
112
|
+
gap: ${({theme:e})=>e.space(4)};
|
|
113
|
+
min-width: 0;
|
|
114
|
+
`,We=R.button`
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
gap: 4px;
|
|
118
|
+
width: 100%;
|
|
119
|
+
padding: ${({theme:e})=>`${e.space(2)} ${e.space(3)}`};
|
|
120
|
+
text-align: left;
|
|
121
|
+
background: ${({theme:e,$selected:t})=>t?e.color.accentWash:`transparent`};
|
|
122
|
+
border: 0;
|
|
123
|
+
border-left: 2px solid
|
|
124
|
+
${({theme:e,$selected:t})=>t?e.color.accent:`transparent`};
|
|
125
|
+
border-bottom: 1px solid ${({theme:e})=>e.color.rule};
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
|
|
128
|
+
&:hover {
|
|
129
|
+
background: ${({theme:e,$selected:t})=>t?e.color.accentWash:e.color.panelSunk};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&:last-child {
|
|
133
|
+
border-bottom: 0;
|
|
134
|
+
}
|
|
135
|
+
`,Ge=R(x)`
|
|
136
|
+
font-family: ${({theme:e})=>e.font.mono};
|
|
137
|
+
font-size: 12.5px;
|
|
138
|
+
display: block;
|
|
139
|
+
max-width: 100%;
|
|
140
|
+
`,Ke=R.div`
|
|
141
|
+
display: flex;
|
|
142
|
+
gap: 2px;
|
|
143
|
+
`,qe=R.span`
|
|
144
|
+
width: 12px;
|
|
145
|
+
height: 3px;
|
|
146
|
+
border-radius: 1px;
|
|
147
|
+
background: ${({$provider:e})=>C(e)};
|
|
148
|
+
`,$=`\0new`;function Je(){let e=r(),[t,n]=P(null),i=e.data??[],a=t===$?null:i.find(e=>e.id===t)??null,o=t===$||t===null&&!e.isLoading&&i.length===0;ne(()=>{t===null&&i.length!==0&&n(i[0]?.id??null)},[i,t]);let s=e.isLoading?`Reading configured models…`:i.length===0?`No virtual models exist yet, so no client request can resolve to an upstream.`:`${i.length} model${i.length===1?``:`s`} routing to ${i.reduce((e,t)=>e+t.targets.length,0)} targets.`;return L(F,{children:[I(T,{legend:`Models`,title:`Virtual models`,summary:s,actions:L(u,{type:`button`,$variant:`primary`,onClick:()=>n($),children:[I(E,{}),`New model`]})}),L(He,{children:[I(y,{legend:`Configured`,meta:`${i.length}`,flush:!0,children:e.isError?I(g,{error:e.error,onRetry:()=>void e.refetch()}):e.isLoading?I(`div`,{style:{padding:12},children:I(m,{rows:4})}):i.length===0?I(v,{legend:`No models`,message:`Create a model to give clients something to ask for.`,action:I(u,{type:`button`,$size:`sm`,$variant:`primary`,onClick:()=>n($),children:`New model`})}):I(`div`,{children:i.map(e=>{let r=[...new Set(e.targets.map(e=>e.provider))];return L(We,{type:`button`,$selected:e.id===t,"aria-pressed":e.id===t,onClick:()=>n(e.id),children:[L(h,{$gap:2,style:{width:`100%`},children:[I(Ge,{title:e.id,children:e.id}),I(f,{}),e.isAlias?I(k,{children:`alias`}):null]}),L(h,{$gap:2,style:{width:`100%`},children:[I(Ke,{children:r.map(e=>I(qe,{$provider:e,title:e},e))}),I(p,{children:e.strategy}),I(f,{}),L(b,{$dim:!0,$size:`11px`,children:[e.targets.length,` target`,e.targets.length===1?``:`s`]})]})]},e.id)})})}),L(Ue,{children:[a===null&&!o?I(y,{legend:`Editor`,children:e.isLoading?I(m,{rows:5}):I(v,{legend:`Nothing selected`,message:`Pick a model on the left to change its targets, or create a new one.`})}):I(Ve,{model:a,onSaved:t=>{n(t),e.refetch()},onDeleted:()=>{n(null),e.refetch()}}),I(ve,{modelId:a?.id??null})]})]})]})}var Ye=Je;export{Ye as component};
|
package/public/assets/{_app.plugins._pluginId-Bx1LgcDj.js → _app.plugins._pluginId-Bf9D8Qiz.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Dt as e}from"./Lamp-
|
|
1
|
+
import{Dt as e}from"./Lamp-DsUSnxN4.js";import{t}from"./preload-helper-CvG2RSKd.js";import{C as n,a as r,c as i,d as a,f as o,i as s,l as c,r as l,t as u}from"./Panel-CWmOTDAP.js";import{t as d}from"./Rack-CSpeYQ1D.js";import{t as f}from"./index-C_8ChaGY.js";import{Component as p,Suspense as m,createContext as h,lazy as g,useContext as _,useMemo as v}from"react";import{Fragment as y,jsx as b,jsxs as x}from"react/jsx-runtime";import S from"styled-components";import{pluginApiPath as C}from"@omnigateway/dashboard-sdk";var w=new Map;function T(e){let t=w.get(e);if(t!==void 0)return t;let n={get:(t,n)=>c(C(e,t),n),post:(t,n)=>a(C(e,t),n),put:(t,n)=>o(C(e,t),n),del:t=>i(C(e,t))};return w.set(e,n),n}var E=h(e=>t(()=>import(e),[]));E.Provider;function D(){return _(E)}function O(e,t){let n=e?.default;if(n==null)throw Error(`plugin ${t} has no default export from definePluginUI`);if(typeof n.mount!=`function`)throw Error(`plugin ${t} exported a default without a mount function`);return n}function k(e,t,n){return g(async()=>{let r=O(await n(t),e);return{default:()=>r.mount({pluginId:e,api:T(e)})}})}var A=S.p`
|
|
2
2
|
font-size: 13px;
|
|
3
3
|
color: ${({theme:e})=>e.color.down};
|
|
4
4
|
`,j=S.p`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Bt as e,Gt as t,It as n,Tt as r,Vt as i,X as a,Y as o,q as s}from"./Lamp-
|
|
1
|
+
import{Bt as e,Gt as t,It as n,Tt as r,Vt as i,X as a,Y as o,q as s}from"./Lamp-DsUSnxN4.js";import{C as c,D as l,S as u,_ as d,a as f,b as p,g as m,h,i as g,o as _,t as v,v as y}from"./Panel-CWmOTDAP.js";import{t as b}from"./Rack-CSpeYQ1D.js";import{t as x}from"./Toggle-BTJVC9Se.js";import{i as S,n as C,t as w}from"./Field-BYBri2NV.js";import{t as T}from"./Meter-stpt3vQu.js";import{n as E}from"./reasons-Du1OBWAM.js";import{useEffect as ee,useId as D,useState as O}from"react";import{Fragment as te,jsx as k,jsxs as A}from"react/jsx-runtime";import j from"styled-components";var M=j.p`
|
|
2
2
|
font-size: 12px;
|
|
3
3
|
color: ${({theme:e})=>e.color.inkDim};
|
|
4
4
|
max-width: 62ch;
|