omnigateway 0.2.0 → 0.2.2
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/README.md +94 -7
- package/bin/omni.js +4954 -2939
- package/gateway.js +3132 -1164
- package/package.json +1 -1
- package/public/assets/{Chip-BB_5C1Zp.js → Chip-DJwp7gBu.js} +2 -2
- package/public/assets/{Confirm-B6aAiVbT.js → Confirm-CVLz9F7a.js} +1 -1
- package/public/assets/CopyValue-CNZbWS59.js +27 -0
- package/public/assets/{Field-uHZxl4fI.js → Field-BDtp692L.js} +8 -8
- package/public/assets/Lamp-B65uWKbW.js +25 -0
- package/public/assets/{Meter-DI_BRUKt.js → Meter-BREBUFGX.js} +2 -2
- package/public/assets/{Modal-CI6jk2D4.js → Modal-DbydSAlp.js} +8 -8
- package/public/assets/Rack-Bbo4JfEX.js +151 -0
- package/public/assets/{Readout-BocZ2HXP.js → Readout-CEAoN5hu.js} +9 -5
- package/public/assets/{States-Bbiu5cHE.js → States-BEKLros0.js} +10 -10
- package/public/assets/{Table-CdPWxYaz.js → Table-BBypbVWj.js} +1 -1
- package/public/assets/{Toggle-CiLC67Dw.js → Toggle-BUr71O4J.js} +2 -2
- package/public/assets/{TokenBreakdown-B96iPBm9.js → TokenBreakdown-C1ziK9d1.js} +6 -3
- package/public/assets/_app-ByQ1bPbe.js +1 -0
- package/public/assets/_app.accounts-BTug_Xfo.js +64 -0
- package/public/assets/{_app.console-Daz4aKhf.js → _app.console-DKyGL9xx.js} +10 -10
- package/public/assets/_app.index-CSw9gmMf.js +62 -0
- package/public/assets/_app.keys-07Kbw4RS.js +39 -0
- package/public/assets/_app.logs-C9QiV39p.js +32 -0
- package/public/assets/_app.models-CDqVrAeF.js +148 -0
- package/public/assets/{_app.settings-a0FKyQAi.js → _app.settings-DmUEeTaP.js} +10 -10
- package/public/assets/_app.usage-B1WuMGRr.js +83 -0
- package/public/assets/catalog-BBKm8Ih8.js +1 -0
- package/public/assets/{dist-C-IbPRiV.js → dist-Bka7ErcH.js} +1 -1
- package/public/assets/index-DJfb1i4P.js +186 -0
- package/public/assets/{login-CTvH_KAd.js → login-DKZYqRh0.js} +8 -8
- package/public/assets/queries-D8LJNQpL.js +144 -0
- package/public/assets/shared-CIhZ6FCO.js +84 -0
- package/public/assets/{trash-2-BcZb-sCT.js → trash-2-CLYNAAJA.js} +1 -1
- package/public/index.html +2 -2
- package/public/assets/CopyValue-CRQDLo7k.js +0 -27
- package/public/assets/Lamp-B-5SjXbG.js +0 -25
- package/public/assets/Rack-D1WJswv3.js +0 -151
- package/public/assets/_app-BBOF6A0T.js +0 -1
- package/public/assets/_app.accounts-BNkhpvaB.js +0 -54
- package/public/assets/_app.index-LO6d38oe.js +0 -62
- package/public/assets/_app.keys-kBqLqoFf.js +0 -39
- package/public/assets/_app.logs-_wYNS47N.js +0 -32
- package/public/assets/_app.models-Cjng8ohC.js +0 -144
- package/public/assets/_app.usage-D3KtgLrC.js +0 -166
- package/public/assets/catalog-C_OQ0icG.js +0 -1
- package/public/assets/index-PW6EvVh5.js +0 -170
- package/public/assets/queries-D2o-X8Pj.js +0 -144
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import{B as e,C as t,G as n,I as r,L as i,M as a,Mt as o,Nt as s,P as c,R as l,V as u,Zt as d,j as f,m as p,p as m,x as h,y as g}from"./queries-D2o-X8Pj.js";import{h as _,t as v}from"./Rack-D1WJswv3.js";import{n as y,t as b}from"./Confirm-B6aAiVbT.js";import{t as x}from"./trash-2-BcZb-sCT.js";import{t as S}from"./Toggle-CiLC67Dw.js";import{n as C,t as w}from"./Chip-BB_5C1Zp.js";import{i as T,n as E,r as D,t as O}from"./Field-uHZxl4fI.js";import{t as ee}from"./Meter-DI_BRUKt.js";import{a as k,i as A,n as te,r as j,t as M}from"./States-Bbiu5cHE.js";import{n as ne,r as re,t as N}from"./catalog-C_OQ0icG.js";var P=_(`play`,[[`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=_(`rotate-ccw`,[[`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`}]]),F=d(s(),1),I=o(),L=[`tier`,`health`,`quota`,`cost`,`latency`,`recency`],ae={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 against the other candidates`,latency:`Observed time to first token`,recency:`How long this pair has been idle`},oe=n.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
|
-
`,se=n(a)`
|
|
9
|
-
width: 22px;
|
|
10
|
-
color: ${({theme:e})=>e.color.inkFaint};
|
|
11
|
-
flex: none;
|
|
12
|
-
`,ce=n(w)`
|
|
13
|
-
border-color: ${({theme:e})=>e.color.ok};
|
|
14
|
-
color: ${({theme:e})=>e.color.ok};
|
|
15
|
-
background: ${({theme:e})=>e.color.okWash};
|
|
16
|
-
`,le=n.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
|
-
`,ue=n.div`
|
|
23
|
-
display: flex;
|
|
24
|
-
flex-direction: column;
|
|
25
|
-
gap: 3px;
|
|
26
|
-
min-width: 0;
|
|
27
|
-
`,de=n.div`
|
|
28
|
-
display: flex;
|
|
29
|
-
align-items: baseline;
|
|
30
|
-
justify-content: space-between;
|
|
31
|
-
gap: 6px;
|
|
32
|
-
`,fe=n.li`
|
|
33
|
-
display: flex;
|
|
34
|
-
align-items: center;
|
|
35
|
-
gap: ${({theme:e})=>e.space(2)};
|
|
36
|
-
padding: 5px 0;
|
|
37
|
-
`,pe=n(c)`
|
|
38
|
-
gap: ${({theme:e})=>e.space(3)};
|
|
39
|
-
flex-wrap: wrap;
|
|
40
|
-
`,R=n.label`
|
|
41
|
-
display: flex;
|
|
42
|
-
align-items: center;
|
|
43
|
-
gap: 6px;
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
font-size: 12.5px;
|
|
46
|
-
`,z=n.p`
|
|
47
|
-
font-size: 12px;
|
|
48
|
-
color: ${({theme:e})=>e.color.down};
|
|
49
|
-
`;function B(e,t,n){return(e[t]??0)*n[t]}function me({modelId:n}){let[o,s]=(0,F.useState)({tools:!1,images:!1,reasoning:!1}),[u,d]=(0,F.useState)(null),[m,h]=(0,F.useState)(null),g=t(),_=p(),v=g.data?.weights,y=()=>{n!==null&&(h(null),_.mutate({modelId:n,need:o},{onSuccess:e=>d(e),onError:e=>{d(null),h(A(e))}}))},b=new Map(L.map(e=>[e,Math.max(1e-4,...(u?.candidates??[]).map(t=>v===void 0?0:Math.abs(B(t.reasons,e,v))))]));return(0,I.jsx)(k,{legend:`Explain`,meta:n??`no model selected`,actions:(0,I.jsxs)(e,{type:`button`,$size:`sm`,$variant:`primary`,disabled:n===null||_.isPending,onClick:y,children:[(0,I.jsx)(P,{}),_.isPending?`Ranking…`:`Rank candidates`]}),children:(0,I.jsxs)(i,{$gap:3,children:[(0,I.jsxs)(i,{$gap:1,children:[(0,I.jsx)(f,{children:`Pretend the request needs`}),(0,I.jsxs)(pe,{children:[(0,I.jsxs)(R,{children:[(0,I.jsx)(S,{checked:o.tools,label:`Probe request uses tools`,onCheckedChange:e=>s({...o,tools:e})}),`Tools`]}),(0,I.jsxs)(R,{children:[(0,I.jsx)(S,{checked:o.images,label:`Probe request includes an image`,onCheckedChange:e=>s({...o,images:e})}),`Images`]}),(0,I.jsxs)(R,{children:[(0,I.jsx)(S,{checked:o.reasoning,label:`Probe request asks for reasoning`,onCheckedChange:e=>s({...o,reasoning:e})}),`Reasoning`]})]})]}),m===null?null:(0,I.jsx)(z,{children:m}),u===null?(0,I.jsx)(M,{legend:`Not ranked yet`,message:n===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.`}):(0,I.jsxs)(i,{$gap:3,children:[(0,I.jsxs)(c,{$gap:2,$wrap:!0,children:[(0,I.jsx)(w,{$tone:`accent`,children:u.strategy}),u.deterministic?null:(0,I.jsx)(w,{$tone:`warn`,children:`order varies per request`}),(0,I.jsx)(r,{}),(0,I.jsxs)(f,{children:[u.candidates.length,` eligible · `,u.excluded.length,` filtered out`]})]}),u.candidates.length===0?(0,I.jsx)(M,{legend:`Nothing eligible`,message:`Every target was filtered out. The reasons below say which rule removed each one.`}):(0,I.jsx)(`ul`,{children:u.candidates.map((e,t)=>(0,I.jsxs)(oe,{children:[(0,I.jsxs)(c,{$gap:2,children:[(0,I.jsx)(se,{children:t+1}),(0,I.jsx)(C,{provider:e.provider}),(0,I.jsx)(l,{style:{maxWidth:`22ch`},children:e.credentialLabel}),(0,I.jsx)(a,{$dim:!0,children:e.model}),(0,I.jsxs)(w,{children:[`tier `,e.tier]}),(0,I.jsx)(r,{}),t===0?(0,I.jsx)(ce,{children:`would be used`}):null,(0,I.jsx)(a,{children:e.score.toFixed(2)})]}),v===void 0?null:(0,I.jsx)(le,{children:L.map(t=>{let n=B(e.reasons,t,v),r=b.get(t)??1;return(0,I.jsxs)(ue,{title:ae[t],children:[(0,I.jsxs)(de,{children:[(0,I.jsx)(f,{children:t}),(0,I.jsx)(a,{$dim:!0,$size:`10.5px`,children:n.toFixed(2)})]}),(0,I.jsx)(ee,{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}`))}),u.excluded.length===0?null:(0,I.jsxs)(i,{$gap:1,children:[(0,I.jsx)(f,{children:`Filtered out`}),(0,I.jsx)(`ul`,{children:u.excluded.map(e=>(0,I.jsxs)(fe,{children:[(0,I.jsx)(a,{$dim:!0,children:e.model}),(0,I.jsx)(r,{}),(0,I.jsx)(w,{$tone:e.reason.startsWith(`capability`)?`warn`:`down`,children:e.reason})]},`${e.credentialId}:${e.model}:${e.reason}`))})]})]})]})})}var V=[{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.`}],H=0;function U(){return H+=1,`target-${H}`}function W(e,t){let n=re(e,t);return n===null?null:{costInput:String(n.input),costOutput:String(n.output),costCacheRead:String(n.cacheRead),costCacheWrite5m:String(n.cacheWrite5m),costCacheWrite1h:String(n.cacheWrite1h)}}function he(e,t){let n=ne(e,t);return n===null?null:{contextWindow:String(n.contextWindow),maxOutputTokens:String(n.maxOutputTokens)}}function ge(e,t){return{...e,...t,...W(t.provider,t.model)??{},contextWindow:``,maxOutputTokens:``}}function G(e=`anthropic`){let t=N[e].defaultModel,n=W(e,t);return{key:U(),provider:e,model:t,tier:`1`,weight:`1`,costInput:n?.costInput??`0`,costOutput:n?.costOutput??`0`,costCacheRead:n?.costCacheRead??``,costCacheWrite5m:n?.costCacheWrite5m??``,costCacheWrite1h:n?.costCacheWrite1h??``,contextWindow:``,maxOutputTokens:``,tools:!0,images:!0,reasoning:!0}}function K(){return{id:``,strategy:`score`,isAlias:!1,targets:[G()]}}function q(e){return{id:e.id,strategy:e.strategy,isAlias:e.isAlias,targets:e.targets.map(e=>({key:U(),provider:e.provider,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),tools:e.capabilities.tools,images:e.capabilities.images,reasoning:e.capabilities.reasoning}))}}function _e(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.model.trim();if(i.length===0)return{ok:!1,problem:`${e} needs a provider model name.`};let a=Number(r.tier);if(!Number.isInteger(a)||a<1)return{ok:!1,problem:`${e}: tier must be a whole number of 1 or more.`};let o=Number(r.weight);if(!Number.isFinite(o)||o<=0)return{ok:!1,problem:`${e}: weight must be greater than zero.`};let s=Number(r.costInput),c=Number(r.costOutput);if(!Number.isFinite(s)||s<0||!Number.isFinite(c)||c<0)return{ok:!1,problem:`${e}: prices cannot be negative.`};let l=r.costCacheRead.trim().length>0,u=Number(r.costCacheRead);if(l&&(!Number.isFinite(u)||u<0))return{ok:!1,problem:`${e}: the cache-read price cannot be negative.`};let d=r.costCacheWrite5m.trim().length>0,f=Number(r.costCacheWrite5m);if(d&&(!Number.isFinite(f)||f<0))return{ok:!1,problem:`${e}: the 5m cache-write price must be a number of 0 or more.`};let p=r.costCacheWrite1h.trim().length>0,m=Number(r.costCacheWrite1h);if(p&&(!Number.isFinite(m)||m<0))return{ok:!1,problem:`${e}: the 1h cache-write price must be a number of 0 or more.`};let h=r.contextWindow.trim().length>0,g=Number(r.contextWindow);if(h&&(!Number.isInteger(g)||g<1))return{ok:!1,problem:`${e}: the context window must be a whole number of tokens.`};let _=r.maxOutputTokens.trim().length>0,v=Number(r.maxOutputTokens);if(_&&(!Number.isInteger(v)||v<1))return{ok:!1,problem:`${e}: the output limit must be a whole number of tokens.`};n.push({provider:r.provider,model:i,tier:a,weight:o,costPerMTok:{input:s,output:c,...l?{cacheRead:u}:{},...d?{cacheWrite5m:f}:{},...p?{cacheWrite1h:m}:{}},...h?{contextWindow:g}:{},..._?{maxOutputTokens:v}:{},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 ve=Object.keys(N),ye=n.fieldset`
|
|
50
|
-
border: 1px solid ${({theme:e})=>e.color.rule};
|
|
51
|
-
border-left: 3px solid ${({theme:e,$provider:t})=>e.provider[t]};
|
|
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
|
-
`,be=n.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
|
-
`,J=n.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
|
-
`,Y=n.div`
|
|
75
|
-
display: flex;
|
|
76
|
-
flex-direction: column;
|
|
77
|
-
gap: 4px;
|
|
78
|
-
min-width: 0;
|
|
79
|
-
`,xe=n(c)`
|
|
80
|
-
gap: ${({theme:e})=>e.space(3)};
|
|
81
|
-
flex-wrap: wrap;
|
|
82
|
-
`,X=n.label`
|
|
83
|
-
display: flex;
|
|
84
|
-
align-items: center;
|
|
85
|
-
gap: 6px;
|
|
86
|
-
cursor: pointer;
|
|
87
|
-
`;function Se({target:t,index:n,onChange:a,onRemove:o,removable:s}){let l=(0,F.useId)(),d=N[t.provider],p=(e,n)=>{a({...t,[e]:n})},m=W(t.provider,t.model),h=he(t.provider,t.model),g=e=>{a(ge(t,e))};return(0,I.jsxs)(ye,{$provider:t.provider,children:[(0,I.jsxs)(c,{$gap:2,children:[(0,I.jsxs)(f,{as:`legend`,children:[`Target `,n+1]}),(0,I.jsx)(r,{}),(0,I.jsx)(u,{type:`button`,$variant:`ghost`,$size:`sm`,disabled:!s,"aria-label":`Remove target ${n+1}`,title:s?`Remove target ${n+1}`:`A model needs at least one target`,onClick:o,children:(0,I.jsx)(x,{})})]}),(0,I.jsxs)(be,{children:[(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-provider`,children:`Provider`}),(0,I.jsx)(T,{id:`${l}-provider`,value:t.provider,onChange:e=>{let n=e.target.value,r=N[n].models.some(e=>e.id===t.model);g({provider:n,model:r?t.model:N[n].defaultModel})},children:ve.map(e=>(0,I.jsx)(`option`,{value:e,children:e},e))})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-model`,children:`Provider model`}),(0,I.jsx)(E,{id:`${l}-model`,list:`${l}-catalog`,value:t.model,placeholder:d.defaultModel,onChange:e=>g({provider:t.provider,model:e.target.value})}),(0,I.jsx)(`datalist`,{id:`${l}-catalog`,children:d.models.map(e=>(0,I.jsx)(`option`,{value:e.id,children:e.label},e.id))})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-tier`,children:`Tier`}),(0,I.jsx)(D,{id:`${l}-tier`,min:1,step:1,value:t.tier,onChange:e=>p(`tier`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-weight`,children:`Weight`}),(0,I.jsx)(D,{id:`${l}-weight`,min:0,step:.1,value:t.weight,onChange:e=>p(`weight`,e.target.value)})]})]}),(0,I.jsxs)(i,{$gap:1,children:[(0,I.jsxs)(c,{$gap:2,children:[(0,I.jsx)(f,{children:`Price per million tokens`}),(0,I.jsx)(r,{}),m===null?(0,I.jsx)(f,{as:`span`,children:`not in the catalog — price it yourself`}):(0,I.jsxs)(e,{type:`button`,$size:`sm`,$variant:`ghost`,disabled:t.costInput===m.costInput&&t.costOutput===m.costOutput&&t.costCacheRead===m.costCacheRead&&t.costCacheWrite5m===m.costCacheWrite5m&&t.costCacheWrite1h===m.costCacheWrite1h,onClick:()=>a({...t,...m}),children:[(0,I.jsx)(ie,{}),`Use list price`]})]}),(0,I.jsxs)(J,{children:[(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-in`,children:`Input`}),(0,I.jsx)(D,{id:`${l}-in`,min:0,step:.01,value:t.costInput,onChange:e=>p(`costInput`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-out`,children:`Output`}),(0,I.jsx)(D,{id:`${l}-out`,min:0,step:.01,value:t.costOutput,onChange:e=>p(`costOutput`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-cache`,children:`Cache read`}),(0,I.jsx)(D,{id:`${l}-cache`,min:0,step:.01,placeholder:`same as input`,value:t.costCacheRead,onChange:e=>p(`costCacheRead`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-write5m`,children:`Cache write 5m`}),(0,I.jsx)(D,{id:`${l}-write5m`,min:0,step:.01,placeholder:`1.25x input`,value:t.costCacheWrite5m,onChange:e=>p(`costCacheWrite5m`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-write1h`,children:`Cache write 1h`}),(0,I.jsx)(D,{id:`${l}-write1h`,min:0,step:.01,placeholder:`2x input`,value:t.costCacheWrite1h,onChange:e=>p(`costCacheWrite1h`,e.target.value)})]})]})]}),(0,I.jsxs)(i,{$gap:1,children:[(0,I.jsxs)(c,{$gap:2,children:[(0,I.jsx)(f,{children:`Token limits`}),(0,I.jsx)(r,{}),h===null?(0,I.jsx)(f,{as:`span`,children:`not in the catalog — state them yourself`}):(0,I.jsx)(f,{as:`span`,children:`left empty, the published figures are used — and for an OpenAI target, the narrower ones its OAuth backend allows`})]}),(0,I.jsxs)(J,{children:[(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-context`,children:`Context window`}),(0,I.jsx)(D,{id:`${l}-context`,min:1,step:1024,placeholder:h?.contextWindow??`published`,value:t.contextWindow,onChange:e=>p(`contextWindow`,e.target.value)})]}),(0,I.jsxs)(Y,{children:[(0,I.jsx)(f,{as:`label`,htmlFor:`${l}-maxout`,children:`Max output`}),(0,I.jsx)(D,{id:`${l}-maxout`,min:1,step:1024,placeholder:h?.maxOutputTokens??`published`,value:t.maxOutputTokens,onChange:e=>p(`maxOutputTokens`,e.target.value)})]})]})]}),(0,I.jsxs)(i,{$gap:1,children:[(0,I.jsx)(f,{children:`Capabilities`}),(0,I.jsxs)(xe,{children:[(0,I.jsxs)(X,{children:[(0,I.jsx)(S,{checked:t.tools,label:`Target ${n+1} supports tools`,onCheckedChange:e=>p(`tools`,e)}),`Tools`]}),(0,I.jsxs)(X,{children:[(0,I.jsx)(S,{checked:t.images,label:`Target ${n+1} supports images`,onCheckedChange:e=>p(`images`,e)}),`Images`]}),(0,I.jsxs)(X,{children:[(0,I.jsx)(S,{checked:t.reasoning,label:`Target ${n+1} supports reasoning`,onCheckedChange:e=>p(`reasoning`,e)}),`Reasoning`]})]})]})]})}var Z=n.p`
|
|
88
|
-
font-size: 11.5px;
|
|
89
|
-
color: ${({theme:e})=>e.color.inkDim};
|
|
90
|
-
`,Ce=n.p`
|
|
91
|
-
font-size: 12px;
|
|
92
|
-
color: ${({theme:e})=>e.color.down};
|
|
93
|
-
`,we=n.p`
|
|
94
|
-
font-size: 12px;
|
|
95
|
-
color: ${({theme:e})=>e.color.ok};
|
|
96
|
-
`,Te=n(c)`
|
|
97
|
-
gap: 8px;
|
|
98
|
-
`;function Ee({model:t,onSaved:n,onDeleted:a}){let[o,s]=(0,F.useState)(()=>t===null?K():q(t)),[l,u]=(0,F.useState)(null),[d,p]=(0,F.useState)(!1),[g,_]=(0,F.useState)(!1),v=h(),x=m(),C=t?.id??null;(0,F.useEffect)(()=>{s(t===null?K():q(t)),u(null),p(!1)},[C]);let w=V.find(e=>e.id===o.strategy);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(k,{legend:t===null?`New model`:`Edit model`,meta:t===null?void 0:t.id,actions:(0,I.jsxs)(I.Fragment,{children:[t===null?null:(0,I.jsx)(e,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>_(!0),children:`Delete`}),(0,I.jsx)(e,{type:`button`,$variant:`primary`,$size:`sm`,disabled:v.isPending,onClick:()=>{p(!1);let e=_e(o);if(!e.ok){u(e.problem);return}u(null),v.mutate(e.model,{onSuccess:()=>{p(!0),n(e.model.id)},onError:e=>u(A(e))})},children:v.isPending?`Saving…`:t===null?`Create model`:`Save changes`})]}),children:(0,I.jsxs)(i,{$gap:3,children:[(0,I.jsx)(O,{label:`Model name`,hint:t===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:e=>(0,I.jsx)(E,{...e,value:o.id,disabled:t!==null,placeholder:`fast`,onChange:e=>s({...o,id:e.target.value})})}),(0,I.jsx)(O,{label:`Routing strategy`,children:e=>(0,I.jsx)(T,{...e,value:o.strategy,onChange:e=>s({...o,strategy:e.target.value}),children:V.map(e=>(0,I.jsx)(`option`,{value:e.id,children:e.label},e.id))})}),w===void 0?null:(0,I.jsx)(Z,{children:w.blurb}),(0,I.jsxs)(Te,{children:[(0,I.jsx)(S,{checked:o.isAlias,label:`This model is an alias for a provider model name`,onCheckedChange:e=>s({...o,isAlias:e})}),(0,I.jsxs)(i,{$gap:0,children:[(0,I.jsx)(f,{as:`span`,children:`Alias`}),(0,I.jsx)(Z,{children:`Mark this when the name mirrors a provider's own model name.`})]})]}),(0,I.jsxs)(i,{$gap:2,children:[(0,I.jsxs)(c,{children:[(0,I.jsx)(f,{children:`Targets`}),(0,I.jsx)(r,{}),(0,I.jsxs)(e,{type:`button`,$size:`sm`,onClick:()=>s({...o,targets:[...o.targets,G(o.targets.at(-1)?.provider??`anthropic`)]}),children:[(0,I.jsx)(y,{}),`Add target`]})]}),o.targets.map((e,t)=>(0,I.jsx)(Se,{target:e,index:t,removable:o.targets.length>1,onChange:t=>s({...o,targets:o.targets.map(n=>n.key===e.key?t:n)}),onRemove:()=>s({...o,targets:o.targets.filter(t=>t.key!==e.key)})},e.key))]}),l===null?null:(0,I.jsx)(Ce,{role:`alert`,children:l}),d&&l===null?(0,I.jsx)(we,{role:`status`,children:`Saved.`}):null]})}),(0,I.jsx)(b,{open:g,onOpenChange:_,title:`Delete model`,body:t===null?``:`Deleting "${t.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:x.isPending,onConfirm:()=>{t!==null&&x.mutate(t.id,{onSuccess:()=>{_(!1),a()},onError:e=>{_(!1),u(A(e))}})}})]})}var De=n.div`
|
|
99
|
-
display: grid;
|
|
100
|
-
grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
|
|
101
|
-
gap: ${({theme:e})=>e.space(4)};
|
|
102
|
-
align-items: start;
|
|
103
|
-
|
|
104
|
-
@media (max-width: 980px) {
|
|
105
|
-
grid-template-columns: minmax(0, 1fr);
|
|
106
|
-
}
|
|
107
|
-
`,Oe=n(i)`
|
|
108
|
-
gap: ${({theme:e})=>e.space(4)};
|
|
109
|
-
min-width: 0;
|
|
110
|
-
`,Q=n.button`
|
|
111
|
-
display: flex;
|
|
112
|
-
flex-direction: column;
|
|
113
|
-
gap: 4px;
|
|
114
|
-
width: 100%;
|
|
115
|
-
padding: ${({theme:e})=>`${e.space(2)} ${e.space(3)}`};
|
|
116
|
-
text-align: left;
|
|
117
|
-
background: ${({theme:e,$selected:t})=>t?e.color.accentWash:`transparent`};
|
|
118
|
-
border: 0;
|
|
119
|
-
border-left: 2px solid
|
|
120
|
-
${({theme:e,$selected:t})=>t?e.color.accent:`transparent`};
|
|
121
|
-
border-bottom: 1px solid ${({theme:e})=>e.color.rule};
|
|
122
|
-
cursor: pointer;
|
|
123
|
-
|
|
124
|
-
&:hover {
|
|
125
|
-
background: ${({theme:e,$selected:t})=>t?e.color.accentWash:e.color.panelSunk};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
&:last-child {
|
|
129
|
-
border-bottom: 0;
|
|
130
|
-
}
|
|
131
|
-
`,ke=n(l)`
|
|
132
|
-
font-family: ${({theme:e})=>e.font.mono};
|
|
133
|
-
font-size: 12.5px;
|
|
134
|
-
display: block;
|
|
135
|
-
max-width: 100%;
|
|
136
|
-
`,Ae=n.div`
|
|
137
|
-
display: flex;
|
|
138
|
-
gap: 2px;
|
|
139
|
-
`,je=n.span`
|
|
140
|
-
width: 12px;
|
|
141
|
-
height: 3px;
|
|
142
|
-
border-radius: 1px;
|
|
143
|
-
background: ${({$provider:e})=>`var(--p-${e})`};
|
|
144
|
-
`,$=`\0new`;function Me(){let t=g(),[n,i]=(0,F.useState)(null),o=t.data??[],s=n===$?null:o.find(e=>e.id===n)??null,l=n===$||n===null&&!t.isLoading&&o.length===0;(0,F.useEffect)(()=>{n===null&&o.length!==0&&i(o[0]?.id??null)},[o,n]);let u=t.isLoading?`Reading configured models…`:o.length===0?`No virtual models exist yet, so no client request can resolve to an upstream.`:`${o.length} model${o.length===1?``:`s`} routing to ${o.reduce((e,t)=>e+t.targets.length,0)} targets.`;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(v,{legend:`Models`,title:`Virtual models`,summary:u,actions:(0,I.jsxs)(e,{type:`button`,$variant:`primary`,onClick:()=>i($),children:[(0,I.jsx)(y,{}),`New model`]})}),(0,I.jsxs)(De,{children:[(0,I.jsx)(k,{legend:`Configured`,meta:`${o.length}`,flush:!0,children:t.isError?(0,I.jsx)(te,{error:t.error,onRetry:()=>void t.refetch()}):t.isLoading?(0,I.jsx)(`div`,{style:{padding:12},children:(0,I.jsx)(j,{rows:4})}):o.length===0?(0,I.jsx)(M,{legend:`No models`,message:`Create a model to give clients something to ask for.`,action:(0,I.jsx)(e,{type:`button`,$size:`sm`,$variant:`primary`,onClick:()=>i($),children:`New model`})}):(0,I.jsx)(`div`,{children:o.map(e=>{let t=[...new Set(e.targets.map(e=>e.provider))];return(0,I.jsxs)(Q,{type:`button`,$selected:e.id===n,"aria-pressed":e.id===n,onClick:()=>i(e.id),children:[(0,I.jsxs)(c,{$gap:2,style:{width:`100%`},children:[(0,I.jsx)(ke,{title:e.id,children:e.id}),(0,I.jsx)(r,{}),e.isAlias?(0,I.jsx)(w,{children:`alias`}):null]}),(0,I.jsxs)(c,{$gap:2,style:{width:`100%`},children:[(0,I.jsx)(Ae,{children:t.map(e=>(0,I.jsx)(je,{$provider:e,title:e},e))}),(0,I.jsx)(f,{children:e.strategy}),(0,I.jsx)(r,{}),(0,I.jsxs)(a,{$dim:!0,$size:`11px`,children:[e.targets.length,` target`,e.targets.length===1?``:`s`]})]})]},e.id)})})}),(0,I.jsxs)(Oe,{children:[s===null&&!l?(0,I.jsx)(k,{legend:`Editor`,children:t.isLoading?(0,I.jsx)(j,{rows:5}):(0,I.jsx)(M,{legend:`Nothing selected`,message:`Pick a model on the left to change its targets, or create a new one.`})}):(0,I.jsx)(Ee,{model:s,onSaved:e=>{i(e),t.refetch()},onDeleted:()=>{i(null),t.refetch()}}),(0,I.jsx)(me,{modelId:s?.id??null})]})]})]})}var Ne=Me;export{Ne as component};
|