omnigateway 0.15.2 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/bin/omni.js +1 -1
  2. package/gateway.js +1 -1
  3. package/package.json +1 -1
  4. package/public/assets/{Chip-C3dIFd8s.js → Chip-B2iXmJJC.js} +1 -1
  5. package/public/assets/CopyValue-CWSTp4v8.js +27 -0
  6. package/public/assets/{Field-EvdVyEqx.js → Field-CUEEy19T.js} +5 -28
  7. package/public/assets/{Rack-DMrfn4-H.js → Rack-1lijWt5h.js} +32 -32
  8. package/public/assets/RequestTable-uRTmuPwB.js +93 -0
  9. package/public/assets/Select-C0c13SKD.js +141 -0
  10. package/public/assets/{SummaryDeck-DHsYYpYO.js → SummaryDeck-DnQnRmQ8.js} +1 -1
  11. package/public/assets/Toggle-BvVa_jla.js +39 -0
  12. package/public/assets/{TokenBreakdown-Bf0zsKcd.js → TokenBreakdown-B8cSaOOr.js} +2 -2
  13. package/public/assets/_app.accounts-DmJhe6QV.js +70 -0
  14. package/public/assets/_app.console-DQlcBpSu.js +24 -0
  15. package/public/assets/{_app.database-BCwEMrEA.js → _app.database-DoDu8HOG.js} +1 -1
  16. package/public/assets/{_app.index-DW6wain4.js → _app.index-BEeD4XSS.js} +2 -2
  17. package/public/assets/_app.keys-MXvgkBUB.js +120 -0
  18. package/public/assets/{_app.logs-CRC5qDK3.js → _app.logs-CjUjeVHg.js} +3 -3
  19. package/public/assets/_app.models-mNIL-1oS.js +148 -0
  20. package/public/assets/{_app.plugins._pluginId-CD9KXknf.js → _app.plugins._pluginId-CsJXQg6X.js} +1 -1
  21. package/public/assets/_app.settings-CYMwWA8D.js +88 -0
  22. package/public/assets/{_app.usage-BR6a92zI.js → _app.usage-Dd33vB8x.js} +3 -3
  23. package/public/assets/chevron-right-ocqzquMZ.js +1 -0
  24. package/public/assets/client-KUNw8ZtZ.js +48 -0
  25. package/public/assets/{index-6rZSWe9j.js → index-B9izdV6t.js} +3 -3
  26. package/public/assets/{login-NuwPF5SS.js → login-DrbTJF6e.js} +1 -1
  27. package/public/assets/plus-D_lvSfDL.js +1 -0
  28. package/public/assets/{rotate-ccw-Dionx_MW.js → rotate-ccw-CwTftDdz.js} +1 -1
  29. package/public/assets/{trash-Bsi60qJc.js → trash-CmuxOGpN.js} +1 -1
  30. package/public/index.html +2 -2
  31. package/public/assets/CopyValue-DG88CWpN.js +0 -27
  32. package/public/assets/RequestTable-CtuuMOT2.js +0 -93
  33. package/public/assets/Toggle-BTie3NY8.js +0 -39
  34. package/public/assets/_app.accounts-xCJhRd32.js +0 -70
  35. package/public/assets/_app.console-DS37cfIu.js +0 -24
  36. package/public/assets/_app.keys-CCU2NB3-.js +0 -120
  37. package/public/assets/_app.models-B4brzRdK.js +0 -148
  38. package/public/assets/_app.settings-NJSb_L2B.js +0 -88
  39. package/public/assets/chevron-down-3tlYNJqZ.js +0 -1
  40. package/public/assets/chevron-right-kvaJRnfj.js +0 -1
  41. package/public/assets/client-B9t0CsmA.js +0 -46
  42. package/public/assets/dist-B8iuo_hI.js +0 -1
  43. package/public/assets/plus-CVqm87L-.js +0 -1
@@ -1,148 +0,0 @@
1
- import{G as e,Pt as t,St as n,Ut as r,Zt as i,bt as a,gt as o,jt as s,k as c}from"./Lamp-CL0i4yaa.js";import{A as l,E as u,S as d,T as f,a as p,b as m,c as h,k as g,o as _,r as v,s as y,w as b,y as x}from"./Panel-CsovmtxF.js";import{A as S,r as C,t as w,w as T}from"./Rack-DMrfn4-H.js";import{t as ee}from"./plus-CVqm87L-.js";import{t as E}from"./rotate-ccw-Dionx_MW.js";import{t as te}from"./trash-Bsi60qJc.js";import{t as D}from"./Toggle-BTie3NY8.js";import{n as O,t as k}from"./Chip-C3dIFd8s.js";import{i as A,n as ne,r as j,t as M}from"./Field-EvdVyEqx.js";import{t as re}from"./Meter-stpt3vQu.js";import{useEffect as N,useId as ie,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 ae={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`}]]};ae.node;var oe=S(ae),se=[`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(m)`
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(d)`
38
- gap: ${({theme:e})=>e.space(3)};
39
- flex-wrap: wrap;
40
- `,z=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 B(e,t,n){return(e[t]??0)*n[t]}function ve({modelId:e}){let[t,r]=P({tools:!1,images:!1,reasoning:!1}),[a,o]=P(null),[s,c]=P(null),l=i(),_=n(),y=l.data?.weights,S=()=>{e!==null&&(c(null),_.mutate({modelId:e,need:t},{onSuccess:e=>o(e),onError:e=>{o(null),c(h(e))}}))},C=new Map(se.map(e=>[e,Math.max(1e-4,...(a?.candidates??[]).map(t=>y===void 0?0:Math.abs(B(t.reasons,e,y))))]));return I(v,{legend:`Explain`,meta:e??`no model selected`,actions:L(g,{type:`button`,$size:`sm`,$variant:`primary`,disabled:e===null||_.isPending,onClick:S,children:[I(oe,{}),_.isPending?`Ranking…`:`Rank candidates`]}),children:L(f,{$gap:3,children:[L(f,{$gap:1,children:[I(x,{children:`Pretend the request needs`}),L(ge,{children:[L(z,{children:[I(D,{checked:t.tools,label:`Probe request uses tools`,onCheckedChange:e=>r({...t,tools:e})}),`Tools`]}),L(z,{children:[I(D,{checked:t.images,label:`Probe request includes an image`,onCheckedChange:e=>r({...t,images:e})}),`Images`]}),L(z,{children:[I(D,{checked:t.reasoning,label:`Probe request asks for reasoning`,onCheckedChange:e=>r({...t,reasoning:e})}),`Reasoning`]})]})]}),s===null?null:I(_e,{children:s}),a===null?I(p,{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(f,{$gap:3,children:[L(d,{$gap:2,$wrap:!0,children:[I(k,{$tone:`accent`,children:a.strategy}),a.deterministic?null:I(k,{$tone:`warn`,children:`order varies per request`}),I(b,{}),L(x,{children:[a.candidates.length,` eligible · `,a.excluded.length,` filtered out`]})]}),a.candidates.length===0?I(p,{legend:`Nothing eligible`,message:`Every target was filtered out. The reasons below say which rule removed each one.`}):I(`ul`,{children:a.candidates.map((e,t)=>L(le,{children:[L(d,{$gap:2,children:[I(ue,{children:t+1}),I(O,{provider:e.provider}),I(u,{style:{maxWidth:`22ch`},children:e.credentialLabel}),I(m,{$dim:!0,children:e.model}),L(k,{children:[`tier `,e.tier]}),I(b,{}),t===0?I(de,{children:`would be used`}):null,I(m,{children:e.score.toFixed(2)})]}),y===void 0?null:I(fe,{children:se.map(t=>{let n=B(e.reasons,t,y),r=C.get(t)??1;return L(pe,{title:ce[t],children:[L(me,{children:[I(x,{children:t}),I(m,{$dim:!0,$size:`10.5px`,children:n.toFixed(2)})]}),I(re,{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}`))}),a.excluded.length===0?null:L(f,{$gap:1,children:[I(x,{children:`Filtered out`}),I(`ul`,{children:a.excluded.map(e=>L(he,{children:[I(m,{$dim:!0,children:e.model}),I(m,{$dim:!0,children:e.credentialId}),I(b,{}),I(k,{$tone:e.reason.startsWith(`capability`)?`warn`:`down`,children:e.reason})]},`${e.credentialId}:${e.model}:${e.reason}`))})]})]})]})})}function V(t,n,r){return e(t,n)?.models.find(e=>e.id===r)}function H(t,n,r){let i=e(t,n);return i===void 0?null:i.models.find(e=>e.id===r)?.auth??i.authTypes}var U=[{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.`}],W=0;function G(){return W+=1,`target-${W}`}function K(e,t,n){let r=V(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=V(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 q(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 J(e,t,n,r){let i=r[t];if(i===void 0||i.length===0)return!0;let a=H(e,t,n);return a===null||a.some(e=>i.includes(e))}function Se(t,n,r){let i=e(t,n);return i===void 0?[]:i.models.filter(e=>J(t,n,e.id,r))}function Ce(e,t,n,r){if(n.trim().length===0||J(e,t,n,r))return null;let i=r[t]??[];return`${t} serves this model to ${q(H(e,t,n)??[])} only, and every ${t} account here is ${q(i)}. Requests routed here will fail.`}function Y(e,t){let n={provider:e.provider,endpointId:e.endpointId};return t.filter(e=>c(n,e)).map(e=>({id:e.id,label:e.accountEmail??e.label}))}function we(e,t,n){return e.length===0||n.length===0||Y(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 Te(e,t){return{...e,endpointId:t,...t===e.endpointId?{}:{credentialId:``}}}function Ee(e,t,n){return{...t,...n,...K(e,n.provider,n.model)??{},...n.provider===t.provider?{}:{credentialId:``},contextWindow:``,maxOutputTokens:``}}function De(t,n){let r=n??t[0]?.id??`anthropic`,i=e(t,r)?.defaultModel??``,a=K(t,r,i);return{key:G(),provider:r,endpointId:``,model:i,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 Oe(e){return{id:``,strategy:`score`,isAlias:!1,targets:[De(e)]}}function X(e){return{id:e.id,strategy:e.strategy,isAlias:e.isAlias,targets:e.targets.map(e=>({key:G(),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 ke(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 Ae=R.fieldset`
50
- border: 1px solid ${({theme:e})=>e.color.rule};
51
- border-left: 3px solid ${({$provider:e})=>T(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
- `,je=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
- `,Me=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
- `,Ne=R(d)`
80
- gap: ${({theme:e})=>e.space(3)};
81
- flex-wrap: wrap;
82
- `,Pe=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 Fe({target:t,index:n,onChange:r,onRemove:i,removable:a,catalog:o,endpoints:s,held:c,credentials:u}){let p=ie(),m=e(o,t.provider),h=Se(o,t.provider,c),_=Ce(o,t.provider,t.model,c),v=Y(t,u),y=we(t.credentialId,t,u),S=(e,n)=>{r({...t,[e]:n})},C=K(o,t.provider,t.model),w=ye(o,t.provider,t.model),T=e=>{r(Ee(o,t,e))};return L(Ae,{$provider:t.provider,children:[L(d,{$gap:2,children:[L(x,{as:`legend`,children:[`Target `,n+1]}),I(b,{}),I(l,{type:`button`,$variant:`ghost`,$size:`sm`,disabled:!a,"aria-label":`Remove target ${n+1}`,title:a?`Remove target ${n+1}`:`A model needs at least one target`,onClick:i,children:I(te,{})})]}),L(je,{children:[L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-provider`,children:`Provider`}),L(A,{id:`${p}-provider`,value:t.provider,onChange:n=>{let r=n.target.value,i=e(o,r),a=i?.models.some(e=>e.id===t.model)??!1;T({provider:r,model:a?t.model:i?.defaultModel??``})},children:[o.map(e=>I(`option`,{value:e.id,children:e.label},e.id)),m===void 0?L(`option`,{value:t.provider,children:[t.provider,` (not in the catalog)`]}):null]})]}),t.provider===`custom`?L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-endpoint`,children:`Endpoint`}),L(A,{id:`${p}-endpoint`,value:t.endpointId,onChange:e=>r(Te(t,e.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(x,{as:`label`,htmlFor:`${p}-model`,children:`Provider model`}),I(ne,{id:`${p}-model`,list:`${p}-catalog`,value:t.model,placeholder:m?.defaultModel??``,onChange:e=>T({provider:t.provider,model:e.target.value})}),I(`datalist`,{id:`${p}-catalog`,children:h.map(e=>I(`option`,{value:e.id,children:e.label},e.id))}),_===null?null:I(Pe,{role:`note`,children:_})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-tier`,children:`Tier`}),I(j,{id:`${p}-tier`,min:1,step:1,value:t.tier,onChange:e=>S(`tier`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-weight`,children:`Weight`}),I(j,{id:`${p}-weight`,min:0,step:.1,value:t.weight,onChange:e=>S(`weight`,e.target.value)})]})]}),I(f,{$gap:1,children:L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-account`,children:`Account`}),L(A,{id:`${p}-account`,value:t.credentialId,onChange:e=>S(`credentialId`,e.target.value),children:[I(`option`,{value:``,children:`Any account`}),v.map(e=>I(`option`,{value:e.id,children:e.label},e.id)),y===null?null:L(`option`,{value:t.credentialId,children:[t.credentialId,` (removed)`]})]}),y===null?null:I(Pe,{role:`note`,children:y})]})}),L(f,{$gap:1,children:[L(d,{$gap:2,children:[I(x,{children:`Price per million tokens`}),I(b,{}),C===null?I(x,{as:`span`,children:`not in the catalog — price it yourself`}):L(g,{type:`button`,$size:`sm`,$variant:`ghost`,disabled:t.costInput===C.costInput&&t.costOutput===C.costOutput&&t.costCacheRead===C.costCacheRead&&t.costCacheWrite5m===C.costCacheWrite5m&&t.costCacheWrite1h===C.costCacheWrite1h,onClick:()=>r({...t,...C}),children:[I(E,{}),`Use list price`]})]}),L(Me,{children:[L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-in`,children:`Input`}),I(j,{id:`${p}-in`,min:0,step:.01,value:t.costInput,onChange:e=>S(`costInput`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-out`,children:`Output`}),I(j,{id:`${p}-out`,min:0,step:.01,value:t.costOutput,onChange:e=>S(`costOutput`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-cache`,children:`Cache read`}),I(j,{id:`${p}-cache`,min:0,step:.01,placeholder:`same as input`,value:t.costCacheRead,onChange:e=>S(`costCacheRead`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-write5m`,children:`Cache write 5m`}),I(j,{id:`${p}-write5m`,min:0,step:.01,placeholder:`1.25x input`,value:t.costCacheWrite5m,onChange:e=>S(`costCacheWrite5m`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-write1h`,children:`Cache write 1h`}),I(j,{id:`${p}-write1h`,min:0,step:.01,placeholder:`2x input`,value:t.costCacheWrite1h,onChange:e=>S(`costCacheWrite1h`,e.target.value)})]})]})]}),L(f,{$gap:1,children:[L(d,{$gap:2,children:[I(x,{children:`Token limits`}),I(b,{}),w===null?I(x,{as:`span`,children:`not in the catalog — state them yourself`}):I(x,{as:`span`,children:`left empty, the published figures are used — and for an OpenAI target, the narrower ones its OAuth backend allows`})]}),L(Me,{children:[L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-context`,children:`Context window`}),I(j,{id:`${p}-context`,min:1,step:1024,placeholder:w?.contextWindow??`published`,value:t.contextWindow,onChange:e=>S(`contextWindow`,e.target.value)})]}),L(Z,{children:[I(x,{as:`label`,htmlFor:`${p}-maxout`,children:`Max output`}),I(j,{id:`${p}-maxout`,min:1,step:1024,placeholder:w?.maxOutputTokens??`published`,value:t.maxOutputTokens,onChange:e=>S(`maxOutputTokens`,e.target.value)})]})]})]}),L(f,{$gap:1,children:[I(x,{children:`Capabilities`}),L(Ne,{children:[L(Q,{children:[I(D,{checked:t.tools,label:`Target ${n+1} supports tools`,onCheckedChange:e=>S(`tools`,e)}),`Tools`]}),L(Q,{children:[I(D,{checked:t.images,label:`Target ${n+1} supports images`,onCheckedChange:e=>S(`images`,e)}),`Images`]}),L(Q,{children:[I(D,{checked:t.reasoning,label:`Target ${n+1} supports reasoning`,onCheckedChange:e=>S(`reasoning`,e)}),`Reasoning`]})]})]})]})}var Ie=R.p`
92
- font-size: 11.5px;
93
- color: ${({theme:e})=>e.color.inkDim};
94
- `,Le=R.p`
95
- font-size: 12px;
96
- color: ${({theme:e})=>e.color.down};
97
- `,Re=R.p`
98
- font-size: 12px;
99
- color: ${({theme:e})=>e.color.ok};
100
- `,ze=R(d)`
101
- gap: 8px;
102
- `;function Be({model:e,onSaved:n,onDeleted:i}){let s=t().data??[],[c,l]=P(()=>e===null?Oe(s):X(e)),[u,p]=P(null),[m,_]=P(!1),[y,S]=P(!1),w=r(),T=a(),E=o(),te=xe(E.data??[]),O=(E.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),k=e?.id??null;N(()=>{l(e===null?Oe(s):X(e)),p(null),_(!1)},[k]);let j=U.find(e=>e.id===c.strategy);return L(F,{children:[I(v,{legend:e===null?`New model`:`Edit model`,meta:e===null?void 0:e.id,actions:L(F,{children:[e===null?null:I(g,{type:`button`,$variant:`danger`,$size:`sm`,onClick:()=>S(!0),children:`Delete`}),I(g,{type:`button`,$variant:`primary`,$size:`sm`,disabled:w.isPending,onClick:()=>{_(!1);let e=ke(c);if(!e.ok){p(e.problem);return}p(null),w.mutate(e.model,{onSuccess:()=>{_(!0),n(e.model.id)},onError:e=>p(h(e))})},children:w.isPending?`Saving…`:e===null?`Create model`:`Save changes`})]}),children:L(f,{$gap:3,children:[I(M,{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(ne,{...t,value:c.id,disabled:e!==null,placeholder:`fast`,onChange:e=>l({...c,id:e.target.value})})}),I(M,{label:`Routing strategy`,children:e=>I(A,{...e,value:c.strategy,onChange:e=>l({...c,strategy:e.target.value}),children:U.map(e=>I(`option`,{value:e.id,children:e.label},e.id))})}),j===void 0?null:I(Ie,{children:j.blurb}),L(ze,{children:[I(D,{checked:c.isAlias,label:`This model is an alias for a provider model name`,onCheckedChange:e=>l({...c,isAlias:e})}),L(f,{$gap:0,children:[I(x,{as:`span`,children:`Alias`}),I(Ie,{children:`Mark this when the name mirrors a provider's own model name.`})]})]}),L(f,{$gap:2,children:[L(d,{children:[I(x,{children:`Targets`}),I(b,{}),L(g,{type:`button`,$size:`sm`,onClick:()=>l({...c,targets:[...c.targets,De(s,c.targets.at(-1)?.provider)]}),children:[I(ee,{}),`Add target`]})]}),c.targets.map((e,t)=>I(Fe,{target:e,index:t,removable:c.targets.length>1,catalog:s,endpoints:O,held:te,credentials:E.data??[],onChange:t=>l({...c,targets:c.targets.map(n=>n.key===e.key?t:n)}),onRemove:()=>l({...c,targets:c.targets.filter(t=>t.key!==e.key)})},e.key))]}),u===null?null:I(Le,{role:`alert`,children:u}),m&&u===null?I(Re,{role:`status`,children:`Saved.`}):null]})}),I(C,{open:y,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),p(h(e))}})}})]})}var Ve=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
- `,He=R(f)`
112
- gap: ${({theme:e})=>e.space(4)};
113
- min-width: 0;
114
- `,Ue=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
- `,We=R(u)`
136
- font-family: ${({theme:e})=>e.font.mono};
137
- font-size: 12.5px;
138
- display: block;
139
- max-width: 100%;
140
- `,Ge=R.div`
141
- display: flex;
142
- gap: 2px;
143
- `,Ke=R.span`
144
- width: 12px;
145
- height: 3px;
146
- border-radius: 1px;
147
- background: ${({$provider:e})=>T(e)};
148
- `,$=`\0new`;function qe(){let e=s(),[t,n]=P(null),r=e.data??[],i=t===$?null:r.find(e=>e.id===t)??null,a=t===$||t===null&&!e.isLoading&&r.length===0;N(()=>{t===null&&r.length!==0&&n(r[0]?.id??null)},[r,t]);let o=e.isLoading?`Reading configured models…`:r.length===0?`No virtual models exist yet, so no client request can resolve to an upstream.`:`${r.length} model${r.length===1?``:`s`} routing to ${r.reduce((e,t)=>e+t.targets.length,0)} targets.`;return L(F,{children:[I(w,{legend:`Models`,title:`Virtual models`,summary:o,actions:L(g,{type:`button`,$variant:`primary`,onClick:()=>n($),children:[I(ee,{}),`New model`]})}),L(Ve,{children:[I(v,{legend:`Configured`,meta:`${r.length}`,flush:!0,children:e.isError?I(_,{error:e.error,onRetry:()=>void e.refetch()}):e.isLoading?I(`div`,{style:{padding:12},children:I(y,{rows:4})}):r.length===0?I(p,{legend:`No models`,message:`Create a model to give clients something to ask for.`,action:I(g,{type:`button`,$size:`sm`,$variant:`primary`,onClick:()=>n($),children:`New model`})}):I(`div`,{children:r.map(e=>{let r=[...new Set(e.targets.map(e=>e.provider))];return L(Ue,{type:`button`,$selected:e.id===t,"aria-pressed":e.id===t,onClick:()=>n(e.id),children:[L(d,{$gap:2,style:{width:`100%`},children:[I(We,{title:e.id,children:e.id}),I(b,{}),e.isAlias?I(k,{children:`alias`}):null]}),L(d,{$gap:2,style:{width:`100%`},children:[I(Ge,{children:r.map(e=>I(Ke,{$provider:e,title:e},e))}),I(x,{children:e.strategy}),I(b,{}),L(m,{$dim:!0,$size:`11px`,children:[e.targets.length,` target`,e.targets.length===1?``:`s`]})]})]},e.id)})})}),L(He,{children:[i===null&&!a?I(v,{legend:`Editor`,children:e.isLoading?I(y,{rows:5}):I(p,{legend:`Nothing selected`,message:`Pick a model on the left to change its targets, or create a new one.`})}):I(Be,{model:i,onSaved:t=>{n(t),e.refetch()},onDeleted:()=>{n(null),e.refetch()}}),I(ve,{modelId:i?.id??null})]})]})]})}var Je=qe;export{Je as component};
@@ -1,88 +0,0 @@
1
- import{$ as e,Gt as t,Q as n,X as r,Xt as i,Zt as a,jt as o,tn as s,w as c}from"./Lamp-CL0i4yaa.js";import{S as l,T as u,_ as d,b as f,c as p,k as m,o as h,r as g,s as _,v,w as ee,y}from"./Panel-CsovmtxF.js";import{t as te}from"./Rack-DMrfn4-H.js";import{t as b}from"./Toggle-BTie3NY8.js";import{i as x,n as S,t as C}from"./Field-EvdVyEqx.js";import{t as w}from"./Meter-stpt3vQu.js";import{n as T}from"./reasons-Du1OBWAM.js";import{useEffect as ne,useId as E,useState as D}from"react";import{Fragment as O,jsx as k,jsxs as A}from"react/jsx-runtime";import j from"styled-components";var M=j.p`
2
- font-size: 12px;
3
- color: ${({theme:e})=>e.color.inkDim};
4
- max-width: 62ch;
5
- `,N=j.p`
6
- font-size: 12px;
7
- color: ${({theme:e})=>e.color.down};
8
- `,P=j.p`
9
- font-size: 12px;
10
- color: ${({theme:e})=>e.color.ok};
11
- `,F=j(u)`
12
- max-width: 320px;
13
- `,I=j(y)`
14
- color: ${({theme:e})=>e.color.inkDim};
15
- `;function L(){let t=e(),[n,r]=D(``),[i,a]=D(``),[o,s]=D(``),[c,d]=D(null);return A(u,{$gap:2,children:[k(I,{children:`Admin password`}),k(M,{children:`Changing this signs every session out, including this one.`}),A(F,{$gap:2,children:[k(C,{label:`Current password`,children:e=>k(S,{...e,type:`password`,autoComplete:`current-password`,value:n,onChange:e=>r(e.target.value)})}),k(C,{label:`New password`,hint:`At least 12 characters.`,children:e=>k(S,{...e,type:`password`,autoComplete:`new-password`,value:i,onChange:e=>a(e.target.value)})}),k(C,{label:`Repeat new password`,children:e=>k(S,{...e,type:`password`,autoComplete:`new-password`,value:o,onChange:e=>s(e.target.value)})}),k(l,{$gap:2,children:k(m,{type:`button`,$variant:`primary`,onClick:()=>{if(i.length<12){d(`A password must be at least 12 characters.`);return}if(i!==o){d(`The two new passwords do not match.`);return}d(null),t.mutate({current:n,password:i},{onSuccess:()=>T(`password-changed`),onError:e=>d(p(e))})},disabled:t.isPending||n.length===0||i.length===0,children:`Change password`})})]}),c===null?null:k(N,{role:`alert`,children:c})]})}function R(){let e=s(),t=i(),[n,r]=D(``),[a,o]=D(null),[c,d]=D(null),f=e.data?.viewerConfigured===!0;return A(u,{$gap:2,children:[k(I,{children:`Read-only password`}),A(M,{children:[`Opens a read-only console: every screen, without mutations, snapshot downloads, or request bodies.`,` `,e.isPending?`Checking whether one is set…`:f?`One is set. A new one replaces it; withdrawing ends read-only sessions at once.`:`None is set, so nobody can sign in read-only. There is no default password.`]}),A(F,{$gap:2,children:[k(C,{label:f?`Replace read-only password`:`Set read-only password`,hint:`At least 12 characters.`,children:e=>k(S,{...e,type:`password`,autoComplete:`new-password`,value:n,onChange:e=>r(e.target.value)})}),A(l,{$gap:2,children:[k(m,{type:`button`,$variant:`primary`,onClick:()=>{if(n.length<12){o(`A password must be at least 12 characters.`);return}o(null),t.mutate(n,{onSuccess:()=>{r(``),d(f?`Read-only password replaced.`:`Read-only access granted.`)},onError:e=>o(p(e))})},disabled:t.isPending||n.length===0,children:f?`Replace`:`Set`}),f?k(m,{type:`button`,$variant:`danger`,onClick:()=>{o(null),t.mutate(null,{onSuccess:()=>d(`Read-only access withdrawn.`),onError:e=>o(p(e))})},disabled:t.isPending,children:`Withdraw access`}):null]})]}),a===null?null:k(N,{role:`alert`,children:a}),c===null||a!==null?null:k(P,{role:`status`,children:c})]})}function z(){return k(g,{legend:`Access`,children:A(u,{$gap:3,children:[k(L,{}),k(d,{}),k(R,{})]})})}var B=[{id:`claude`,label:`Claude Code`,where:`settings.json under ~/.claude`},{id:`opencode`,label:`opencode`,where:`opencode.json in your project`}],re=j(f)`
16
- display: block;
17
- white-space: pre;
18
- overflow-x: auto;
19
- padding: 0.75rem;
20
- background: ${({theme:e})=>e.color.panelSunk};
21
- border: 1px solid ${({theme:e})=>e.color.rule};
22
- border-radius: 4px;
23
- font-size: 0.8125rem;
24
- line-height: 1.5;
25
- `,ie=j.div`
26
- color: ${({theme:e})=>e.color.inkDim};
27
- font-size: 0.8125rem;
28
- margin-bottom: 0.25rem;
29
- `,V=j.p`
30
- color: ${({theme:e})=>e.color.inkDim};
31
- font-size: 0.8125rem;
32
- margin: 0;
33
- `,ae=j.div`
34
- display: grid;
35
- grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
36
- gap: ${({theme:e})=>e.space(2)};
37
- `,oe=[{key:`defaultModel`,label:`Default model`,required:!0},{key:`fableModel`,label:`Fable model`,required:!1},{key:`opusModel`,label:`Opus model`,required:!1},{key:`sonnetModel`,label:`Sonnet model`,required:!1},{key:`haikuModel`,label:`Haiku model`,required:!1}];function H(){let[e,t]=D(`claude`),[n,i]=D(()=>({claude:{},opencode:{}})),a=o(),s=n[e],c=typeof s.defaultModel==`string`&&s.defaultModel!==``?s:void 0,d=r(e,c),v=B.find(t=>t.id===e);return k(g,{legend:`Agent setup`,children:A(u,{children:[k(l,{children:B.map(n=>k(m,{type:`button`,$variant:n.id===e?`primary`:`ghost`,onClick:()=>t(n.id),children:n.label},n.id))}),A(V,{children:[v?.where,`. The key is a placeholder — paste your own over it. Or run`,` `,A(f,{children:[`omni setup `,e]}),` to write these files directly.`]}),e===`claude`?A(V,{children:[`Claude Code cannot read a window from this gateway, so it assumes 200k for a pool id it does not recognise and auto-compacts there. For a pool whose models hold 1M, append`,` `,k(f,{children:`[1m]`}),` to the model name — `,k(f,{children:`--model 'pool[1m]'`}),` — which lifts it per invocation. The suffix is stripped before the request is sent, so the pool id arrives unchanged.`]}):null,(a.data?.length??0)>0?k(ae,{children:oe.map(t=>k(C,{label:t.label,children:n=>A(x,{...n,value:s[t.key]??``,onChange:n=>i(r=>({...r,[e]:{...r[e],[t.key]:n.target.value||void 0}})),children:[k(`option`,{value:``,children:t.required?`Choose a pool`:`Not mapped`}),a.data?.map(e=>k(`option`,{value:e.id,children:e.id},e.id))]})},t.key))}):null,a.isLoading?k(_,{rows:2}):d.isError?k(h,{error:d.error,onRetry:()=>void d.refetch()}):d.isLoading?k(_,{rows:4}):(a.data?.length??0)===0?k(V,{children:`No virtual models configured yet, so there is nothing to point a client at.`}):c===void 0?A(V,{children:[`Choose a default model to generate `,v?.label,` settings.`]}):d.data===void 0||d.data.length===0?k(V,{children:`No virtual models configured yet, so there is nothing to point a client at.`}):d.data.map(e=>A(`div`,{children:[k(ie,{children:e.path}),k(re,{as:`pre`,children:e.contents.trimEnd()})]},e.path)),d.isError?k(V,{children:p(d.error)}):null]})})}var U={off:`Off`,lite:`Lite — names the lazier option`,full:`Full — the ladder enforced`,ultra:`Ultra — challenges the requirement`},W=[{id:`tier`,label:`Tier`,blurb:`Prefers a lower tier.`},{id:`health`,label:`Health`,blurb:`Penalises recent failures and an open breaker.`},{id:`quota`,label:`Quota`,blurb:`Prefers accounts ahead of their window's burn rate.`},{id:`cost`,label:`Cost`,blurb:`Prefers the cheaper candidate.`},{id:`latency`,label:`Latency`,blurb:`Prefers the faster observed first token.`},{id:`load`,label:`Load`,blurb:`Prefers accounts with fewer requests in flight.`}],G=[{id:`maxAttempts`,label:`Attempts per request`,hint:`Candidates dispatch may try. 1 disables failover.`,unit:`attempts`,step:1,min:1},{id:`requestDeadlineMs`,label:`Request deadline`,hint:`Across all attempts. 0 disables only OmniGateway's deadline.`,unit:`ms`,step:1e3,min:0},{id:`breakerThreshold`,label:`Breaker threshold`,hint:`Consecutive failures before an account and model leaves rotation.`,unit:`failures`,step:1,min:1},{id:`breakerCooldownMs`,label:`Breaker cooldown`,hint:`Wait before a tripped account is probed. Doubles per extra failure.`,unit:`ms`,step:1e3,min:1},{id:`logRetentionDays`,label:`Log retention`,hint:`How long request rows are kept before pruning.`,unit:`days`,step:1,min:1},{id:`bodyRetentionDays`,label:`Body retention`,hint:`Captured bodies only. Never longer than log retention; swept hourly.`,unit:`days`,step:1,min:1,max:3650},{id:`quotaPollIntervalMs`,label:`Quota poll interval`,hint:`How often a provider is asked for remaining quota. 0 disables. Needs a restart.`,unit:`ms`,step:6e4,min:0}],K=j.div`
38
- display: grid;
39
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
40
- gap: ${({theme:e})=>e.space(3)};
41
- `,q=j(u)`
42
- gap: 6px;
43
- `,J=j.p`
44
- font-size: 11px;
45
- color: ${({theme:e})=>e.color.inkDim};
46
- `,Y=j.div`
47
- display: grid;
48
- grid-template-columns: 1fr;
49
- gap: ${({theme:e})=>e.space(2)};
50
- align-items: start;
51
- `,X=j.div`
52
- display: grid;
53
- grid-template-columns: auto 1fr;
54
- column-gap: ${({theme:e})=>e.space(2)};
55
- row-gap: 4px;
56
- align-items: center;
57
- padding: ${({theme:e})=>e.space(2)};
58
- background: ${({theme:e})=>e.color.panelSunk};
59
- border: 1px solid ${({theme:e})=>e.color.rule};
60
- border-radius: 3px;
61
- `,Z=j(J)`
62
- grid-column: 2;
63
- `,Q=j.label`
64
- font-size: 12px;
65
- font-weight: 600;
66
- color: ${({theme:e})=>e.color.ink};
67
- cursor: pointer;
68
- `,se=j(X)`
69
- grid-template-columns: 1fr;
70
-
71
- ${Z} {
72
- grid-column: 1;
73
- }
74
- `;function ce({label:e,children:t,blurb:n}){let r=E();return A(se,{children:[k(Q,{htmlFor:r,children:e}),t({id:r}),k(Z,{children:n})]})}function $({label:e,checked:t,disabled:n,onCheckedChange:r,children:i}){let a=E();return A(X,{children:[k(b,{id:a,checked:t,onCheckedChange:r,label:e,...n===void 0?{}:{disabled:n}}),k(Q,{htmlFor:a,children:e}),k(Z,{children:i})]})}var le=j.p`
75
- font-size: 12px;
76
- color: ${({theme:e})=>e.color.down};
77
- `,ue=j.p`
78
- font-size: 12px;
79
- color: ${({theme:e})=>e.color.ok};
80
- `,de=j.p`
81
- font-size: 12px;
82
- color: ${({theme:e})=>e.color.warn};
83
- max-width: 72ch;
84
-
85
- code {
86
- font-family: ${({theme:e})=>e.font.mono};
87
- }
88
- `;function fe(e){let t={};for(let n of W)t[`w.${n.id}`]=String(e.weights[n.id]);for(let n of G)t[n.id]=String(e[n.id]);return t.rtkEnabled=String(e.rtkEnabled),t.autoCacheEnabled=String(e.autoCacheEnabled),t.ponytailMode=e.ponytailMode,t.bodyLoggingEnabled=String(e.bodyLoggingEnabled),t.bodyLoggingCaptureStreamChunks=String(e.bodyLoggingCaptureStreamChunks),t.guardrailModel=e.guardrailModel??``,t.guardrailTimeoutMs=String(e.guardrailTimeoutMs),t.guardrailHistoryTurns=String(e.guardrailHistoryTurns),t}function pe(e){let t={};for(let n of W){let r=(e[`w.${n.id}`]??``).trim(),i=Number(r);if(r.length===0||!Number.isFinite(i))return{ok:!1,problem:`${n.label} must be a number.`};t[n.id]=i}let n={};for(let t of G){let r=(e[t.id]??``).trim(),i=Number(r);if(r.length===0||!Number.isInteger(i)||i<t.min)return{ok:!1,problem:`${t.label} must be a whole number of ${t.min} or more.`};if(t.max!==void 0&&i>t.max)return{ok:!1,problem:`${t.label} cannot exceed ${t.max}.`};n[t.id]=i}if(n.maxAttempts>10)return{ok:!1,problem:`Attempts per request cannot exceed 10.`};let r=(e.guardrailTimeoutMs??``).trim(),i=Number(r);if(r.length===0||!Number.isInteger(i)||i<1||i>6e4)return{ok:!1,problem:`Usage policy check timeout must be a whole number from 1 to ${c}.`};let a=(e.guardrailHistoryTurns??``).trim(),o=Number(a);if(a.length===0||!Number.isInteger(o)||o<1||o>10)return{ok:!1,problem:`Messages judged must be a whole number from 1 to 10.`};let s=(e.guardrailModel??``).trim();return{ok:!0,settings:{weights:t,...n,rtkEnabled:e.rtkEnabled===`true`,autoCacheEnabled:e.autoCacheEnabled===`true`,ponytailMode:e.ponytailMode!==void 0&&Object.hasOwn(U,e.ponytailMode)?e.ponytailMode:`off`,bodyLoggingEnabled:e.bodyLoggingEnabled===`true`,bodyLoggingCaptureStreamChunks:e.bodyLoggingCaptureStreamChunks===`true`,guardrailModel:s.length===0?null:s,guardrailTimeoutMs:i,guardrailHistoryTurns:o}}}function me(){let e=a(),r=n(),i=o(),s=E(),d=t(),[b,T]=D({}),[j,M]=D(null),[N,P]=D(!1);ne(()=>{e.data!==void 0&&T(fe(e.data))},[e.data]);let F=Math.max(1e-4,...W.map(e=>Math.abs(Number(b[`w.${e.id}`])||0)));return A(O,{children:[k(te,{legend:`Settings`,title:`Routing and retention`,summary:`Applied to every request the gateway routes. Changes take effect on the next request; nothing restarts.`,actions:k(m,{type:`button`,$variant:`primary`,disabled:d.isPending||e.isLoading,onClick:()=>{P(!1);let e=pe(b);if(!e.ok){M(e.problem);return}M(null),d.mutate(e.settings,{onSuccess:()=>P(!0),onError:e=>M(p(e))})},children:d.isPending?`Saving…`:`Save changes`})}),e.isError?k(g,{legend:`Settings`,children:k(h,{error:e.error,onRetry:()=>void e.refetch()})}):e.isLoading?k(g,{legend:`Settings`,children:k(_,{rows:6})}):A(u,{$gap:4,children:[k(g,{legend:`Scoring weights`,meta:`relative to each other`,footer:A(l,{children:[k(y,{children:`Score is the sum of each term times its weight, then multiplied by the account and target weights.`}),k(ee,{})]}),children:k(K,{children:W.map(e=>{let t=Number(b[`w.${e.id}`])||0;return A(q,{children:[k(C,{label:e.label,children:t=>k(S,{...t,type:`number`,step:.5,value:b[`w.${e.id}`]??``,onChange:t=>T({...b,[`w.${e.id}`]:t.target.value})})}),k(w,{fraction:Math.abs(t)/F,height:4,tone:`var(--accent)`,label:`${e.label} weight ${t}`}),k(J,{children:e.blurb})]},e.id)})})}),k(g,{legend:`Limits`,children:k(K,{children:G.map(e=>k(q,{children:k(C,{label:e.label,hint:e.hint,children:t=>A(l,{$gap:2,children:[k(S,{...t,type:`number`,min:e.min,max:e.max,step:e.step,value:b[e.id]??``,onChange:t=>T({...b,[e.id]:t.target.value})}),k(y,{children:e.unit})]})})},e.id))})}),A(v,{$min:`380px`,$stretch:!0,children:[k(g,{legend:`Request handling`,meta:`applied before dispatch`,children:A(Y,{children:[k($,{label:`Enable RTK compression`,checked:b.rtkEnabled===`true`,onCheckedChange:e=>T({...b,rtkEnabled:String(e)}),children:`Compresses recognized historical tool results. Confirmed non-shell tools are excluded; unknown-origin results may be compressed only when a detector recognizes shell output. Lossy.`}),k($,{label:`Add a cache breakpoint when a client sends none`,checked:b.autoCacheEnabled===`true`,onCheckedChange:e=>T({...b,autoCacheEnabled:String(e)}),children:`Marks the end of the system prompt on Anthropic requests carrying no breakpoint of their own. Requests that mark one are untouched.`}),k(ce,{label:`Lazy senior dev mode`,blurb:`Appends the ponytail ruleset, about 1,240 tokens, to every system prompt. A request already carrying it is left alone.`,children:e=>k(x,{...e,value:b.ponytailMode??`off`,onChange:e=>T({...b,ponytailMode:e.target.value}),children:Object.entries(U).map(([e,t])=>k(`option`,{value:e,children:t},e))})})]})}),k(g,{legend:`Request and response bodies`,meta:r.data===!0?`permitted by the environment`:`not permitted`,children:A(u,{$gap:2,children:[r.data===!0?null:A(de,{children:[`This gateway started without `,k(`code`,{children:`OMNI_BODY_LOGGING_ALLOWED`}),`, so nothing below can record anything. Set it in the installation's `,k(`code`,{children:`.env`}),` and restart first.`]}),A(Y,{children:[k($,{label:`Capture request and response bodies`,checked:b.bodyLoggingEnabled===`true`,disabled:r.data!==!0,onCheckedChange:e=>T({...b,bodyLoggingEnabled:String(e)}),children:`Stores what each client sent and each provider returned, encrypted beside the database. Tokens and keys are masked; headers are never captured. Expires on the body retention window above, never later than the request log.`}),k($,{label:`Also keep raw stream frames`,checked:b.bodyLoggingCaptureStreamChunks===`true`,disabled:r.data!==!0||b.bodyLoggingEnabled!==`true`,onCheckedChange:e=>T({...b,bodyLoggingCaptureStreamChunks:String(e)}),children:`Also keeps the raw SSE frames of each attempt. The most expensive thing capture stores.`})]})]})})]}),k(g,{legend:`Usage policies`,meta:`per-key guardrails`,children:A(u,{$gap:2,children:[k(J,{children:`Keys carrying a usage policy have each request judged by this model first. While it is blank, every request from such a key is refused. A guardrail against ordinary misuse, not a security boundary.`}),A(K,{children:[k(q,{children:k(C,{label:`Classifier model`,hint:`A configured model, or provider/model. Blank means none.`,children:e=>A(O,{children:[k(S,{...e,type:`text`,list:s,placeholder:`none`,spellCheck:!1,value:b.guardrailModel??``,onChange:e=>T({...b,guardrailModel:e.target.value})}),k(`datalist`,{id:s,children:(i.data??[]).map(e=>k(`option`,{value:e.id},e.id))})]})})}),k(q,{children:k(C,{label:`Check timeout`,hint:`A slower check refuses the request it was judging.`,children:e=>A(l,{$gap:2,children:[k(S,{...e,type:`number`,min:1,max:c,step:1e3,value:b.guardrailTimeoutMs??``,onChange:e=>T({...b,guardrailTimeoutMs:e.target.value})}),k(y,{children:`ms`})]})})}),k(q,{children:k(C,{label:`Messages judged`,hint:`How many of the latest human messages are judged together. 1 is the last alone.`,children:e=>A(l,{$gap:2,children:[k(S,{...e,type:`number`,min:1,max:10,step:1,value:b.guardrailHistoryTurns??``,onChange:e=>T({...b,guardrailHistoryTurns:e.target.value})}),k(y,{children:`messages`})]})})})]})]})}),j===null?null:k(le,{role:`alert`,children:j}),N&&j===null?k(ue,{role:`status`,children:`Settings saved.`}):null,A(v,{$min:`380px`,$stretch:!0,children:[k(H,{}),k(z,{})]}),k(g,{legend:`Known limits`,children:A(u,{$gap:2,children:[A(l,{$gap:2,$align:`start`,children:[k(f,{$dim:!0,children:`rate limits`}),k(J,{children:`Counted per gateway process and reset when it restarts. Not shared across instances.`})]}),A(l,{$gap:2,$align:`start`,children:[k(f,{$dim:!0,children:`logs`}),k(J,{children:`Request rows record routing and token counts only. Prompts and responses only when body capture is on, to a separate encrypted store. Credentials to neither.`})]})]})})]})]})}var he=me;export{he as component};
@@ -1 +0,0 @@
1
- import{A as e}from"./Rack-DMrfn4-H.js";var t={name:`chevron-down`,size:24,node:[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]};t.node;var n=e(t);export{n as t};
@@ -1 +0,0 @@
1
- import{A as e}from"./Rack-DMrfn4-H.js";var t={name:`chevron-right`,size:24,node:[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]};t.node;var n=e(t);export{n as t};
@@ -1,46 +0,0 @@
1
- import{_ as e,i as t,y as n}from"./shared-HVgLEGgl.js";import{J as r,K as i,L as a,N as o,R as s,U as ee,at as te,ct as ne,g as re,it as c,l as ie,nn as ae,nt as oe,ot as se,r as l,rt as u,st as ce,tt as le,u as ue,z as d}from"./Lamp-CL0i4yaa.js";import{A as f,C as p,S as m,T as h,b as g,k as _,o as de,r as fe,s as pe,x as v,y}from"./Panel-CsovmtxF.js";import{D as b,i as me,t as he,x}from"./Rack-DMrfn4-H.js";import{a as ge,i as _e,n as ve,r as ye,t as be}from"./RequestTable-CtuuMOT2.js";import{t as S}from"./chevron-down-3tlYNJqZ.js";import{t as C}from"./chevron-right-kvaJRnfj.js";import{i as w,r as T}from"./index-6rZSWe9j.js";import{i as xe}from"./Field-EvdVyEqx.js";import{t as E}from"./Meter-stpt3vQu.js";import{i as D,n as O,r as k,t as A}from"./Table-CVDZ69Zx.js";import{n as Se,r as j}from"./WindowChart-CaPUJ4GJ.js";import{c as Ce}from"./limits-iRyDMg04.js";import{i as M,n as N,r as we,t as Te}from"./SummaryDeck-DHsYYpYO.js";import{Fragment as P,useMemo as F,useState as I}from"react";import{Fragment as Ee,jsx as L,jsxs as R}from"react/jsx-runtime";import z from"styled-components";var B=z.div`
2
- display: grid;
3
- grid-template-areas:
4
- "chassis"
5
- "main";
6
- grid-template-columns: minmax(0, 1fr);
7
- grid-template-rows: auto minmax(0, 1fr);
8
- height: 100vh;
9
- min-height: 0;
10
- overflow: hidden;
11
- `,V=z.main`
12
- grid-area: main;
13
- padding: ${({theme:e})=>e.space(4)};
14
- display: flex;
15
- flex-direction: column;
16
- gap: ${({theme:e})=>e.space(4)};
17
- min-width: 0;
18
- min-height: 0;
19
- overflow-y: auto;
20
-
21
- @media (max-width: 720px) {
22
- padding: ${({theme:e})=>e.space(3)};
23
- }
24
- `;function H({children:e}){let{cadence:t}=b(),n=u(),r=c(200,t(1e4,`res:logs`));return R(B,{"data-testid":`client-shell`,children:[L(x,{logs:r.data??[],logsFailed:r.isError,signOut:{pending:n.isPending,run:()=>{n.mutate(void 0,{onSuccess:()=>window.location.assign(`/login`)})}}}),L(V,{children:e})]})}var U=[20,50,100,250],De={"1m":`per minute`,"5h":`per 5 hours`,"1w":`per week`};function Oe({reading:e}){let t=e.window===null?`concurrent requests`:`${e.dimension} ${De[e.window]??e.window}`,n=e.model===null?t:`${t} for ${e.model}`,r=e.dimension===`spend`?d:o,i=e.used===null?null:e.limit===0?1:e.used/e.limit;return R(D,{children:[L(O,{children:t}),L(O,{$align:`right`,$mono:!0,children:e.used===null?L(v,{children:`unknown`}):r(e.used)}),L(O,{$align:`right`,$mono:!0,children:r(e.limit)}),L(O,{children:i===null?null:L(E,{fraction:i,label:`${n}, ${Math.round(Math.min(1,i)*100)}% used`})})]})}function ke(e){return{observedAt:e.observedAt,windowType:e.windowType,windowMs:e.windowMs,resetsAt:e.resetsAt,usedRatio:e.usedRatio}}function W(e){return{stale:e.stale,rolledOver:e.rolledOver,estimateStale:e.stale||e.rolledOver,survives:e.survives,exhaustsAt:e.exhaustsAt}}var Ae=z.p`
25
- font-size: 12px;
26
- line-height: 1.5;
27
- color: ${({theme:e})=>e.color.ink};
28
- white-space: pre-wrap;
29
- overflow-wrap: anywhere;
30
- max-width: 80ch;
31
- `,G=z.div`
32
- display: flex;
33
- flex-direction: column;
34
- gap: 4px;
35
- `,K=z.div`
36
- display: grid;
37
- /* Bar, figure, legend — the accounts page's own three columns, so the two
38
- screens read the same way and the legends stay aligned down the stack. */
39
- grid-template-columns: 96px 34px 1fr;
40
- align-items: center;
41
- min-width: 208px;
42
- gap: 6px;
43
- `,q=z(g)`
44
- font-size: 11px;
45
- text-align: right;
46
- `;function je({windows:e,open:t,onToggle:n}){let r=e[0],i=e.filter(e=>e.usedRatio!==null);return R(D,{children:[L(O,{children:r.label}),L(O,{children:i.length===0?L(v,{children:`unknown`}):L(G,{children:i.map(e=>R(K,{children:[L(E,{fraction:e.usedRatio,label:`${e.label} ${e.windowType} window, ${Math.round(e.usedRatio*100)}% used`}),L(q,{children:a(e.usedRatio,0)}),L(y,{children:re(e,W(e),Date.now(),s)})]},e.windowType))})}),L(O,{$align:`right`,children:L(f,{type:`button`,$variant:`ghost`,$size:`sm`,"aria-expanded":t,"aria-label":`${t?`Hide`:`Show`} quota history for ${r.label}`,title:`${t?`Hide`:`Show`} quota history for ${r.label}`,onClick:n,children:L(t?S:C,{})})})]})}function J(){let{cadence:s,live:re}=b(),[c,u]=I(`24h`),[f,x]=I(ge),[S,C]=I(U[0]),[w,T]=I(null),[E,z]=I(null),B=e(c),V=le().data??null,H=F(()=>B.grain===`daily`?n(Date.now()-B.ms,V):Math.floor((Date.now()-B.ms)/6e4)*6e4,[B,V]),De=F(()=>H+B.ms,[H,B]),W=ce(),G={since:H,grain:B.grain},K=ne({...G,groupBy:B.by},s(6e4,`res:usage`)),q=ne({...G,groupBy:`model`},s(6e4,`res:usage`)),J=oe(f,S,s(ee,`res:logs`)),Me=!i(J.data),Ne=ae(r.clientLogPages(f,S)),Y=te(6e4),X=Y.data??[],Pe=Ce(W.data?.limitUsage??[]),Fe=Pe.some(e=>e.model!==null),Ie=F(()=>{let e=new Map;for(let t of X){let n=e.get(t.provider)??new Map,r=n.get(t.credentialId);r===void 0?n.set(t.credentialId,[t]):r.push(t),e.set(t.provider,n)}return[...e.entries()].map(([e,t])=>[e,[...t.entries()].map(([e,t])=>({credentialId:e,windows:[...t].sort((e,t)=>l[e.windowType]-l[t.windowType])}))])},[X]),Z=X.map(e=>j(ke(e))).filter(e=>e!==null),Le=Z.length===0?0:Math.floor(Math.min(...Z)/6e4)*6e4,Re=se({since:Le},E!==null&&Z.length>0),Q=F(()=>(J.data?.pages??[]).flatMap(e=>e.logs),[J.data?.pages]),ze=ye(re&&Q.some(ue)),Be=Q.filter(ie).length,$=K.data??[],Ve=$.reduce((e,t)=>e+t.requests,0),He=$.reduce((e,t)=>e+t.costUsd,0);return R(h,{$gap:4,children:[L(he,{legend:`Client`,title:`Your usage`,summary:K.isLoading?`Reading your usage…`:`${o(Ve)} requests and ${d(He)} over the last ${B.label}.`,actions:L(N,{children:t.map(e=>L(we,{type:`button`,$size:`sm`,$on:e.id===c,"aria-pressed":e.id===c,onClick:()=>u(e.id),children:e.id},e.id))})}),L(fe,{legend:`Your key`,meta:W.data===void 0?void 0:R(g,{$dim:!0,children:[W.data.prefix,`…`]}),children:W.isPending?L(pe,{rows:2}):W.isError?L(de,{legend:`Could not read your key`,error:W.error}):R(h,{$gap:2,children:[R(m,{$gap:2,$wrap:!0,children:[L(y,{children:W.data.label}),W.data.bodyLoggingOptOut?L(v,{children:`Request bodies are never stored for this key.`}):null]}),W.data.modelAllowlist===null?L(v,{children:`Every model this gateway serves.`}):W.data.modelAllowlist.length===0?L(v,{children:`No models. This key cannot serve a request.`}):L(m,{$gap:1,$wrap:!0,children:W.data.modelAllowlist.map(e=>L(g,{children:e},e))}),W.data.guardrailPolicy===null?null:R(h,{$gap:1,children:[L(y,{children:`Usage policy`}),L(Ae,{children:W.data.guardrailPolicy}),L(v,{children:`Each request is checked against this before it is served, and the check is billed to this key. Requests outside it are refused.`})]})]})}),L(Te,{buckets:$,since:H,until:De,by:B.by,rangeLabel:B.label,dayOffsetMinutes:V}),L(M,{legend:`By model`,meta:B.label,query:{isLoading:q.isLoading,isError:q.isError,error:q.error,refetch:()=>void q.refetch()},failure:`Could not read usage`,empty:{legend:`No traffic`,message:`Nothing served in this window.`},isEmpty:(q.data??[]).length===0,children:L(p,{children:R(A,{children:[L(`thead`,{children:R(`tr`,{children:[L(k,{children:`Model`}),L(k,{$align:`right`,children:`Requests`}),L(k,{$align:`right`,children:`Tokens`}),L(k,{$align:`right`,children:`Spend`})]})}),L(`tbody`,{children:(q.data??[]).map(e=>R(D,{children:[L(O,{$mono:!0,children:e.key}),L(O,{$align:`right`,$mono:!0,children:o(e.requests)}),L(O,{$align:`right`,$mono:!0,children:o(e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheWriteTokens)}),L(O,{$align:`right`,$mono:!0,children:d(e.costUsd)})]},e.key))})]})})}),L(M,{legend:`Your limits`,query:{isLoading:W.isLoading,isError:W.isError,error:W.error,refetch:()=>void W.refetch()},failure:`Could not read your limits`,empty:W.data?.limits===null?{legend:`Limits unreadable`,message:`This key's limits could not be read. Requests are refused until an operator repairs it.`}:{legend:`No limits`,message:`This key is not rate limited.`},isEmpty:W.data?.limits===null||(W.data?.limitUsage.length??0)===0,footer:L(v,{children:`Counted from completed requests, so a burst in flight right now may not be included yet.`}),children:L(p,{children:R(A,{children:[L(`thead`,{children:R(`tr`,{children:[L(k,{children:`Limit`}),L(k,{$align:`right`,children:`Used`}),L(k,{$align:`right`,children:`Ceiling`}),L(k,{$width:`30%`,children:`Consumption`})]})}),L(`tbody`,{children:Pe.map(e=>R(P,{children:[Fe?L(D,{children:L(k,{scope:`rowgroup`,colSpan:4,children:e.model??`Every model`})}):null,e.readings.map(e=>L(Oe,{reading:e},`${e.dimension}:${e.window??`gauge`}`))]},e.model??``))})]})})}),L(M,{legend:`Provider headroom`,query:{isLoading:Y.isLoading,isError:Y.isError,error:Y.error,refetch:()=>void Y.refetch()},failure:`Could not read provider headroom`,empty:{legend:`No data`,message:`No provider has reported a usage window.`},isEmpty:X.length===0,footer:L(v,{children:`What each account serving this gateway has left. A request is served by whichever account of a provider can take it.`}),children:L(h,{$gap:4,children:Ie.map(([e,t])=>R(h,{$gap:1,children:[L(y,{children:e}),L(p,{children:R(A,{children:[L(`thead`,{children:R(`tr`,{children:[L(k,{children:`Account`}),L(k,{$width:`60%`,children:`Quota`}),L(k,{})]})}),L(`tbody`,{children:t.map(({credentialId:e,windows:t})=>R(P,{children:[L(je,{windows:t,open:E===e,onToggle:()=>z(E===e?null:e)}),E===e?L(D,{children:L(O,{colSpan:3,children:L(h,{$gap:4,children:t.map(e=>{let t=ke(e),n=j(t),r=(Re.data?.samples??[]).filter(t=>t.credentialId===e.credentialId&&t.windowType===e.windowType&&t.observedAt>=(n??0));return L(Se,{live:t,samples:r.map(e=>({observedAt:e.observedAt,windowType:e.windowType,windowMs:e.windowMs,resetsAt:e.resetsAt,usedRatio:e.usedRatio})),since:n,now:Date.now(),truncated:Re.data?.truncated===!0&&n!==null&&r.length>0&&(r[0]?.observedAt??0)>n,ratePerHourRatio:e.ratePerHourRatio,exhaustsAt:e.exhaustsAt,survives:e.survives,stale:e.stale,rolledOver:e.rolledOver,spent:e.usedRatio===null?`no ceiling reported`:`${a(e.usedRatio,0)} used`,rateText:e.ratePerHourRatio===null?`unknown`:`${a(e.ratePerHourRatio,1)}/h`},e.windowType)})})})}):null]},e))})]})})]},e))})}),L(M,{legend:`Recent requests`,meta:`${Q.length} shown`,actions:R(N,{children:[L(_e,{filters:f,onChange:x}),L(xe,{value:S,"aria-label":`How many requests per page`,style:{width:`auto`},onChange:e=>C(Number(e.target.value)),children:U.map(e=>R(`option`,{value:e,children:[e,` per page`]},e))})]}),query:{isLoading:J.isLoading,isError:J.isError,error:J.error,refetch:()=>void J.refetch()},failure:`Could not read your requests`,empty:{legend:`No requests`,message:Object.keys(f).length===0?`Nothing served through this key yet.`:`No request served through this key matches these filters.`},isEmpty:Q.length===0,footer:R(m,{$gap:2,$wrap:!0,children:[R(v,{children:[o(Be),` of the `,o(Q.length),` loaded failed.`]}),J.hasNextPage?L(_,{type:`button`,$size:`sm`,disabled:J.isFetchingNextPage,onClick:()=>void J.fetchNextPage(),children:J.isFetchingNextPage?`Loading…`:`Load older`}):null,Me?R(Ee,{children:[L(v,{children:`Live updates are paused while older pages are loaded.`}),L(_,{type:`button`,$size:`sm`,onClick:Ne,children:`Back to live`})]}):null]}),children:L(p,{children:L(ve,{rows:Q,now:ze,onOpen:T})})}),L(me,{open:w!==null,onOpenChange:e=>{e||T(null)},title:`Request detail`,width:`640px`,footer:L(_,{type:`button`,onClick:()=>T(null),children:`Close`}),children:w===null?null:L(be,{log:w})})]})}var Me=()=>L(T,{children:L(w,{children:L(H,{children:L(J,{})})})});export{Me as component};
@@ -1 +0,0 @@
1
- import{h as e}from"./Rack-DMrfn4-H.js";import*as t from"react";var n=Object.defineProperty,r=(e,t)=>n(e,`name`,{value:t,configurable:!0});function i(n){let[r,i]=t.useState(void 0);return e(()=>{if(n){i({width:n.offsetWidth,height:n.offsetHeight});let e=new ResizeObserver(e=>{if(!Array.isArray(e)||!e.length)return;let t=e[0],r,a;if(`borderBoxSize`in t){let e=t.borderBoxSize,n=Array.isArray(e)?e[0]:e;r=n.inlineSize,a=n.blockSize}else r=n.offsetWidth,a=n.offsetHeight;i({width:r,height:a})});return e.observe(n,{box:`border-box`}),()=>e.unobserve(n)}i(void 0)},[n]),r}r(i,`useSize`);export{i as t};
@@ -1 +0,0 @@
1
- import{A as e}from"./Rack-DMrfn4-H.js";var t={name:`plus`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]};t.node;var n=e(t);export{n as t};