omnigateway 0.7.0 → 0.7.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.
Files changed (48) hide show
  1. package/README.md +21 -6
  2. package/bin/omni.js +6035 -5841
  3. package/gateway.js +6326 -5555
  4. package/package.json +1 -1
  5. package/public/assets/{Chip-BWxO0uV7.js → Chip-BOyBT5TP.js} +1 -1
  6. package/public/assets/{CopyValue-DIR5A6PG.js → CopyValue-DRHHQlN_.js} +3 -3
  7. package/public/assets/{Field-DI5YTYOX.js → Field-DK5zaBVA.js} +1 -1
  8. package/public/assets/Lamp-ZlMzNs5N.js +25 -0
  9. package/public/assets/{Panel-BCpZVY4U.js → Panel-CYQvfI3L.js} +19 -19
  10. package/public/assets/Rack-D798XvPQ.js +466 -0
  11. package/public/assets/{Readout-B0TZE8aA.js → Readout-D6-aurU8.js} +1 -1
  12. package/public/assets/{RequestTable-D4z82uxG.js → RequestTable-CEBhwDs7.js} +2 -2
  13. package/public/assets/{SummaryDeck-CzozuXOu.js → SummaryDeck-DBCSHihY.js} +2 -2
  14. package/public/assets/{Toggle-ByxBCMfb.js → Toggle-CdCCoDEo.js} +1 -1
  15. package/public/assets/{TokenBreakdown-BMEiZhRX.js → TokenBreakdown-DDI9uTPW.js} +1 -1
  16. package/public/assets/{WindowChart-nxC4SCRC.js → WindowChart-C-Y6U3WF.js} +2 -2
  17. package/public/assets/_app-BWNEo1e-.js +1 -0
  18. package/public/assets/_app.accounts-CLLLwN77.js +59 -0
  19. package/public/assets/{_app.console-D6lrTxJt.js → _app.console-Dr9qxU7J.js} +3 -3
  20. package/public/assets/{_app.database-Y3lFDxoP.js → _app.database-D0W0pcxC.js} +4 -4
  21. package/public/assets/{_app.index-DUFa7RRT.js → _app.index-CyxnfhVX.js} +8 -8
  22. package/public/assets/{_app.keys-DRfXCzMJ.js → _app.keys-D9qmw9Tj.js} +11 -11
  23. package/public/assets/{_app.logs-BQT3kFZr.js → _app.logs-DtXUZETW.js} +4 -4
  24. package/public/assets/{_app.models-CDpbIYHW.js → _app.models-CNxwXyFl.js} +11 -11
  25. package/public/assets/{_app.plugins._pluginId-jaswB8Z5.js → _app.plugins._pluginId-87Ox_hkW.js} +1 -1
  26. package/public/assets/_app.plugins._pluginId-CZWipH1n.js +2 -0
  27. package/public/assets/_app.settings-DjiMSl1Y.js +88 -0
  28. package/public/assets/{_app.usage-BaT54Vee.js → _app.usage-CZz9raYR.js} +6 -6
  29. package/public/assets/{chevron-right-0adI8395.js → chevron-right-CPoaXYHw.js} +1 -1
  30. package/public/assets/client-CZnyYbay.js +39 -0
  31. package/public/assets/{index-BRrBGt1i.js → index-DNSPtYpM.js} +3 -3
  32. package/public/assets/{login-BSWCo_Fz.js → login-BtlMmyKj.js} +3 -3
  33. package/public/assets/login-dV42ZQIA.js +2 -0
  34. package/public/assets/plus-_zo43Lvf.js +1 -0
  35. package/public/assets/{preload-helper-CD37DT-E.js → preload-helper-4wSmu2-E.js} +1 -1
  36. package/public/assets/{shared-dShKzjig.js → shared-OJcoRCqT.js} +1 -1
  37. package/public/assets/{stream-BD4FhzLn.js → stream-CEb81tzM.js} +1 -1
  38. package/public/assets/{trash-2-DrDlpCqO.js → trash-2-BjpqTubo.js} +1 -1
  39. package/public/index.html +8 -8
  40. package/public/assets/Lamp-DN2EKL4m.js +0 -25
  41. package/public/assets/Rack-B03tpeW-.js +0 -466
  42. package/public/assets/_app-D9B6OIjd.js +0 -1
  43. package/public/assets/_app.accounts-BiRGhH3s.js +0 -59
  44. package/public/assets/_app.plugins._pluginId-CtEAGvad.js +0 -2
  45. package/public/assets/_app.settings-CG63splg.js +0 -58
  46. package/public/assets/client-_6YMm6vh.js +0 -39
  47. package/public/assets/login-C7v-Fr28.js +0 -2
  48. package/public/assets/plus-B_f8M9yB.js +0 -1
@@ -1,58 +0,0 @@
1
- import{Ft as e,J as t,K as n,Pt as r,Y as i,jt as a,xt as o,zt as s}from"./Lamp-DN2EKL4m.js";import{E as c,S as l,_ as u,a as d,g as f,i as p,o as m,t as h,x as g,y as _}from"./Panel-BCpZVY4U.js";import{t as v}from"./Rack-B03tpeW-.js";import{t as y}from"./Toggle-ByxBCMfb.js";import{i as b,n as x,t as S}from"./Field-DI5YTYOX.js";import{t as C}from"./Meter-stpt3vQu.js";import{n as w}from"./reasons-Du1OBWAM.js";import{useEffect as T,useState 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=12,M=A.p`
2
- font-size: 12px;
3
- color: ${({theme:e})=>e.color.inkDim};
4
- max-width: 62ch;
5
- `,N=A.p`
6
- font-size: 12px;
7
- color: ${({theme:e})=>e.color.down};
8
- `,P=A.p`
9
- font-size: 12px;
10
- color: ${({theme:e})=>e.color.ok};
11
- `,F=A(x)`
12
- width: 260px;
13
- `;function I(){let e=i(),[t,n]=E(``),[r,a]=E(``),[o,s]=E(``),[u,d]=E(null);return k(l,{$gap:2,children:[O(M,{children:`Changing this signs every session out, including this one, and you will be asked to sign in again with the new password.`}),k(_,{$gap:2,$wrap:!0,$align:`end`,children:[O(S,{label:`Current password`,children:e=>O(F,{...e,type:`password`,autoComplete:`current-password`,value:t,onChange:e=>n(e.target.value)})}),O(S,{label:`New password`,hint:`At least ${j} characters.`,children:e=>O(F,{...e,type:`password`,autoComplete:`new-password`,value:r,onChange:e=>a(e.target.value)})}),O(S,{label:`Repeat new password`,children:e=>O(F,{...e,type:`password`,autoComplete:`new-password`,value:o,onChange:e=>s(e.target.value)})}),O(c,{type:`button`,$variant:`primary`,onClick:()=>{if(r.length<j){d(`A password must be at least ${j} characters.`);return}if(r!==o){d(`The two new passwords do not match.`);return}d(null),e.mutate({current:t,password:r},{onSuccess:()=>w(`password-changed`),onError:e=>d(m(e))})},disabled:e.isPending||t.length===0||r.length===0,children:`Change password`})]}),u===null?null:O(N,{role:`alert`,children:u})]})}function L(){let e=s(),t=r(),[n,i]=E(``),[a,o]=E(null),[u,d]=E(null),f=e.data?.viewerConfigured===!0;return k(l,{$gap:2,children:[k(M,{children:[`A second password that signs in to a read-only console: every screen the operator sees, without mutations, snapshot downloads, or request bodies. Hand it to someone who needs to watch this gateway without being able to change it.`,` `,e.isPending?`Reading whether one is set…`:f?`One is set. Entering a new one replaces it; withdrawing it ends any read-only session immediately.`:`None is set, so nobody can sign in read-only. There is no default password.`]}),k(_,{$gap:2,$wrap:!0,$align:`end`,children:[O(S,{label:f?`Replace read-only password`:`Set read-only password`,hint:`At least ${j} characters.`,children:e=>O(F,{...e,type:`password`,autoComplete:`new-password`,value:n,onChange:e=>i(e.target.value)})}),O(c,{type:`button`,$variant:`primary`,onClick:()=>{if(n.length<j){o(`A password must be at least ${j} characters.`);return}o(null),t.mutate(n,{onSuccess:()=>{i(``),d(f?`Read-only password replaced.`:`Read-only access granted.`)},onError:e=>o(m(e))})},disabled:t.isPending||n.length===0,children:f?`Replace`:`Set`}),f?O(c,{type:`button`,$variant:`danger`,onClick:()=>{o(null),t.mutate(null,{onSuccess:()=>d(`Read-only access withdrawn.`),onError:e=>o(m(e))})},disabled:t.isPending,children:`Withdraw access`}):null]}),a===null?null:O(N,{role:`alert`,children:a}),u===null||a!==null?null:O(P,{role:`status`,children:u})]})}function R(){return O(h,{legend:`Access`,children:k(l,{$gap:4,children:[O(I,{}),O(L,{})]})})}var z=[{id:`claude`,label:`Claude Code`,where:`settings.json under ~/.claude`},{id:`opencode`,label:`opencode`,where:`opencode.json in your project`}],B=A(u)`
14
- display: block;
15
- white-space: pre;
16
- overflow-x: auto;
17
- padding: 0.75rem;
18
- background: ${({theme:e})=>e.color.panelSunk};
19
- border: 1px solid ${({theme:e})=>e.color.rule};
20
- border-radius: 4px;
21
- font-size: 0.8125rem;
22
- line-height: 1.5;
23
- `,V=A.div`
24
- color: ${({theme:e})=>e.color.inkDim};
25
- font-size: 0.8125rem;
26
- margin-bottom: 0.25rem;
27
- `,H=A.p`
28
- color: ${({theme:e})=>e.color.inkDim};
29
- font-size: 0.8125rem;
30
- margin: 0;
31
- `,U=A.div`
32
- display: grid;
33
- grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
34
- gap: ${({theme:e})=>e.space(2)};
35
- `,W=[{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 G(){let[e,t]=E(`claude`),[r,i]=E(()=>({claude:{},opencode:{}})),a=o(),s=r[e],f=typeof s.defaultModel==`string`&&s.defaultModel!==``?s:void 0,g=n(e,f),v=z.find(t=>t.id===e);return O(h,{legend:`Agent setup`,children:k(l,{children:[O(_,{children:z.map(n=>O(c,{type:`button`,$variant:n.id===e?`primary`:`ghost`,onClick:()=>t(n.id),children:n.label},n.id))}),k(H,{children:[v?.where,`. The key is a placeholder — paste your own over it. Or run`,` `,k(u,{children:[`omni setup `,e]}),` to write these files directly.`]}),(a.data?.length??0)>0?O(U,{children:W.map(t=>O(S,{label:t.label,children:n=>k(b,{...n,value:s[t.key]??``,onChange:n=>i(r=>({...r,[e]:{...r[e],[t.key]:n.target.value||void 0}})),children:[O(`option`,{value:``,children:t.required?`Choose a pool`:`Not mapped`}),a.data?.map(e=>O(`option`,{value:e.id,children:e.id},e.id))]})},t.key))}):null,a.isLoading?O(d,{rows:2}):g.isError?O(p,{error:g.error,onRetry:()=>void g.refetch()}):g.isLoading?O(d,{rows:4}):(a.data?.length??0)===0?O(H,{children:`No virtual models configured yet, so there is nothing to point a client at.`}):f===void 0?k(H,{children:[`Choose a default model to generate `,v?.label,` settings.`]}):g.data===void 0||g.data.length===0?O(H,{children:`No virtual models configured yet, so there is nothing to point a client at.`}):g.data.map(e=>k(`div`,{children:[O(V,{children:e.path}),O(B,{as:`pre`,children:e.contents.trimEnd()})]},e.path)),g.isError?O(H,{children:m(g.error)}):null]})})}var K={off:`Off`,lite:`Lite — names the lazier option`,full:`Full — the ladder enforced`,ultra:`Ultra — challenges the requirement`},q=[{id:`tier`,label:`Tier`,blurb:`How strongly a lower tier is preferred.`},{id:`health`,label:`Health`,blurb:`Penalty for recent failures and an open breaker.`},{id:`quota`,label:`Quota`,blurb:`Preference for accounts keeping ahead of their window's burn rate.`},{id:`cost`,label:`Cost`,blurb:`Preference for the cheaper target of the candidates.`},{id:`latency`,label:`Latency`,blurb:`Preference for the faster observed first token.`},{id:`load`,label:`Load`,blurb:`Preference for accounts with fewer requests in flight right now.`}],J=[{id:`maxAttempts`,label:`Attempts per request`,hint:`How many candidates dispatch may try before giving up. 1 disables failover.`,unit:`attempts`,step:1,min:1},{id:`requestDeadlineMs`,label:`Request deadline`,hint:`How long a request may take across all attempts. 0 disables only OmniGateway's deadline.`,unit:`ms`,step:1e3,min:0},{id:`breakerThreshold`,label:`Breaker threshold`,hint:`Consecutive failures on one account and model before it is taken out of rotation.`,unit:`failures`,step:1,min:1},{id:`breakerCooldownMs`,label:`Breaker cooldown`,hint:`Base wait before a tripped account is probed again. Doubles per extra failure.`,unit:`ms`,step:1e3,min:1},{id:`logRetentionDays`,label:`Log retention`,hint:`How long request rows are kept before maintenance prunes them.`,unit:`days`,step:1,min:1},{id:`quotaPollIntervalMs`,label:`Quota poll interval`,hint:`How often each account's provider is asked for its remaining quota. 0 disables polling. Takes effect on restart.`,unit:`ms`,step:6e4,min:0}],Y=A.div`
36
- display: grid;
37
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
38
- gap: ${({theme:e})=>e.space(3)};
39
- `,X=A(l)`
40
- gap: 6px;
41
- `,Z=A.p`
42
- font-size: 11px;
43
- color: ${({theme:e})=>e.color.inkDim};
44
- `,Q=A.p`
45
- font-size: 12px;
46
- color: ${({theme:e})=>e.color.down};
47
- `,$=A.p`
48
- font-size: 12px;
49
- color: ${({theme:e})=>e.color.ok};
50
- `,ee=A.p`
51
- font-size: 12px;
52
- color: ${({theme:e})=>e.color.warn};
53
- max-width: 72ch;
54
-
55
- code {
56
- font-family: ${({theme:e})=>e.font.mono};
57
- }
58
- `;function te(e){let t={};for(let n of q)t[`w.${n.id}`]=String(e.weights[n.id]);for(let n of J)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}function ne(e){let t={};for(let n of q){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 J){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.`};n[t.id]=i}return n.maxAttempts>10?{ok:!1,problem:`Attempts per request cannot exceed 10.`}:{ok:!0,settings:{weights:t,...n,rtkEnabled:e.rtkEnabled===`true`,autoCacheEnabled:e.autoCacheEnabled===`true`,ponytailMode:e.ponytailMode!==void 0&&Object.hasOwn(K,e.ponytailMode)?e.ponytailMode:`off`,bodyLoggingEnabled:e.bodyLoggingEnabled===`true`,bodyLoggingCaptureStreamChunks:e.bodyLoggingCaptureStreamChunks===`true`}}}function re(){let n=e(),r=t(),i=a(),[o,s]=E({}),[w,A]=E(null),[j,M]=E(!1);T(()=>{n.data!==void 0&&s(te(n.data))},[n.data]);let N=Math.max(1e-4,...q.map(e=>Math.abs(Number(o[`w.${e.id}`])||0)));return k(D,{children:[O(v,{legend:`Settings`,title:`Routing and retention`,summary:`These apply to every request the gateway routes. Changes take effect on the next request; nothing is restarted.`,actions:O(c,{type:`button`,$variant:`primary`,disabled:i.isPending||n.isLoading,onClick:()=>{M(!1);let e=ne(o);if(!e.ok){A(e.problem);return}A(null),i.mutate(e.settings,{onSuccess:()=>M(!0),onError:e=>A(m(e))})},children:i.isPending?`Saving…`:`Save changes`})}),n.isError?O(h,{legend:`Settings`,children:O(p,{error:n.error,onRetry:()=>void n.refetch()})}):n.isLoading?O(h,{legend:`Settings`,children:O(d,{rows:6})}):k(l,{$gap:4,children:[O(h,{legend:`Scoring weights`,meta:`relative to each other`,footer:k(_,{children:[O(f,{children:`A candidate's score is the sum of each term times its weight, then multiplied by the account and target weights.`}),O(g,{})]}),children:O(Y,{children:q.map(e=>{let t=Number(o[`w.${e.id}`])||0;return k(X,{children:[O(S,{label:e.label,children:t=>O(x,{...t,type:`number`,step:.5,value:o[`w.${e.id}`]??``,onChange:t=>s({...o,[`w.${e.id}`]:t.target.value})})}),O(C,{fraction:Math.abs(t)/N,height:4,tone:`var(--accent)`,label:`${e.label} weight ${t}`}),O(Z,{children:e.blurb})]},e.id)})})}),O(h,{legend:`Limits`,children:O(Y,{children:J.map(e=>O(X,{children:O(S,{label:e.label,hint:e.hint,children:t=>k(_,{$gap:2,children:[O(x,{...t,type:`number`,min:e.min,step:e.step,value:o[e.id]??``,onChange:t=>s({...o,[e.id]:t.target.value})}),O(f,{children:e.unit})]})})},e.id))})}),O(h,{legend:`Historical tool results`,children:k(_,{$gap:3,$align:`start`,children:[O(y,{checked:o.rtkEnabled===`true`,onCheckedChange:e=>s({...o,rtkEnabled:String(e)}),label:`Enable RTK compression`}),O(Z,{children:`Compress recognized historical non-error tool results before provider dispatch. Confirmed non-shell tools are excluded; unknown-origin results may be compressed only when a built-in detector recognizes a high-confidence shell-output format. Compression is deterministic and lossy. Disabled by default.`})]})}),O(h,{legend:`Prompt caching`,children:k(_,{$gap:3,$align:`start`,children:[O(y,{checked:o.autoCacheEnabled===`true`,onCheckedChange:e=>s({...o,autoCacheEnabled:String(e)}),label:`Add a cache breakpoint when a client sends none`}),O(Z,{children:`Anthropic only caches a prompt the request marks, so a client that marks nothing pays full price to resend the same prefix every turn. This marks the end of the system prompt on Anthropic requests that carry no breakpoint of their own. Requests that already mark one are left exactly as they arrived, and prompts too short to be cacheable are skipped. Enabled by default.`})]})}),O(h,{legend:`Coding style`,children:k(_,{$gap:3,$align:`start`,children:[O(S,{label:`Lazy senior dev mode`,children:e=>O(b,{...e,value:o.ponytailMode??`off`,onChange:e=>s({...o,ponytailMode:e.target.value}),children:Object.entries(K).map(([e,t])=>O(`option`,{value:e,children:t},e))})}),O(Z,{children:`Appends the ponytail ruleset to the system prompt of every request, so a coding agent builds the smallest thing that works whether or not it has the skill installed locally. About 1,240 tokens, cached along with the prompt it joins when the request marks a breakpoint at the end of its system prompt or marks none at all. A request that already carries the ruleset is left alone. Off by default.`})]})}),O(h,{legend:`Request and response bodies`,meta:r.data===!0?`permitted by the environment`:`not permitted`,children:k(l,{$gap:3,children:[r.data===!0?null:k(ee,{children:[`This gateway was started without `,O(`code`,{children:`OMNI_BODY_LOGGING_ALLOWED`}),`, so nothing below can record anything. Set it in the installation's `,O(`code`,{children:`.env`}),` `,`and restart before turning capture on. Two keys mean an admin session on its own cannot start recording prompts.`]}),k(_,{$gap:3,$align:`start`,children:[O(y,{checked:o.bodyLoggingEnabled===`true`,disabled:r.data!==!0,onCheckedChange:e=>s({...o,bodyLoggingEnabled:String(e)}),label:`Capture request and response bodies`}),O(Z,{children:`Stores what each client sent and what each provider returned, encrypted under OMNI_ENCRYPTION_KEY beside the database. Bearer tokens and API keys are masked first and headers are never captured. Bodies expire on the log retention window above, and the newest 100,000 requests are kept whatever that window says. Off by default.`})]}),k(_,{$gap:3,$align:`start`,children:[O(y,{checked:o.bodyLoggingCaptureStreamChunks===`true`,disabled:r.data!==!0||o.bodyLoggingEnabled!==`true`,onCheckedChange:e=>s({...o,bodyLoggingCaptureStreamChunks:String(e)}),label:`Also keep raw stream frames`}),O(Z,{children:`Retains the raw SSE frames of each attempt as well as the reassembled response. The only way to debug stream framing itself, and by far the most expensive thing capture can store, so it is gated separately rather than implied.`})]})]})}),w===null?null:O(Q,{role:`alert`,children:w}),j&&w===null?O($,{role:`status`,children:`Settings saved.`}):null,O(G,{}),O(R,{}),O(h,{legend:`Known limits`,children:k(l,{$gap:2,children:[k(_,{$gap:2,children:[O(u,{$dim:!0,children:`rate limits`}),O(Z,{children:`Per-key rate limits are counted inside one gateway process and reset when it restarts. They are not shared across instances.`})]}),k(_,{$gap:2,children:[O(u,{$dim:!0,children:`logs`}),O(Z,{children:`Request rows record routing and token counts only. Prompts and responses are written only when body capture above is on, and to a separate encrypted store; credentials are never written to either.`})]})]})})]})]})}var ie=re;export{ie as component};
@@ -1,39 +0,0 @@
1
- import{_ as e,h as t,i as n}from"./shared-dShKzjig.js";import{$ as r,A as i,B as ee,F as a,I as o,P as s,Q as te,X as c,Z as ne,et as re,g as l,l as ie,r as u,tt as ae,u as oe}from"./Lamp-DN2EKL4m.js";import{D as d,E as se,S as f,_ as p,a as ce,b as m,g as h,i as le,t as ue,v as g,y as _}from"./Panel-BCpZVY4U.js";import{_ as de,d as v,i as fe,t as pe}from"./Rack-B03tpeW-.js";import{n as me,t as y}from"./chevron-right-0adI8395.js";import{n as b,t as x}from"./stream-BD4FhzLn.js";import{i as S,n as he}from"./Field-DI5YTYOX.js";import{t as C}from"./Meter-stpt3vQu.js";import{i as w,n as T,r as E,t as D}from"./Table-CVDZ69Zx.js";import{n as ge,r as O}from"./WindowChart-nxC4SCRC.js";import{i as _e,n as ve,r as ye,t as be}from"./RequestTable-D4z82uxG.js";import{i as k,n as A,r as xe,t as Se}from"./SummaryDeck-CzozuXOu.js";import{Fragment as Ce,useMemo as j,useState as M}from"react";import{jsx as N,jsxs as P}from"react/jsx-runtime";import F from"styled-components";var I=F.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
- `,L=F.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 R({children:e}){let{cadence:t}=de(),n=c(),r=ne(200,t(1e4,`res:logs`));return P(I,{"data-testid":`client-shell`,children:[N(v,{logs:r.data??[],logsFailed:r.isError,signOut:{pending:n.isPending,run:()=>{n.mutate(void 0,{onSuccess:()=>window.location.assign(`/login`)})}}}),N(L,{children:e})]})}var z=[20,50,100,250],B={"1m":`per minute`,"5h":`per 5 hours`,"1w":`per week`};function we({reading:e}){let t=e.window===null?`concurrent requests`:`${e.dimension} ${B[e.window]??e.window}`,n=e.dimension===`spend`?o:i,r=e.used===null?null:e.limit===0?1:e.used/e.limit;return P(w,{children:[N(T,{children:t}),N(T,{$align:`right`,$mono:!0,children:e.used===null?N(g,{children:`unknown`}):n(e.used)}),N(T,{$align:`right`,$mono:!0,children:n(e.limit)}),N(T,{children:r===null?null:N(C,{fraction:r,label:`${t}, ${Math.round(Math.min(1,r)*100)}% used`})})]})}function V(e){return{observedAt:e.observedAt,windowType:e.windowType,windowMs:e.windowMs,resetsAt:e.resetsAt,usedRatio:e.usedRatio}}function H(e){return{stale:e.stale,rolledOver:e.rolledOver,estimateStale:e.stale||e.rolledOver,survives:e.survives,exhaustsAt:e.exhaustsAt}}var U=F.div`
25
- display: flex;
26
- flex-direction: column;
27
- gap: 4px;
28
- `,W=F.div`
29
- display: grid;
30
- /* Bar, figure, legend — the accounts page's own three columns, so the two
31
- screens read the same way and the legends stay aligned down the stack. */
32
- grid-template-columns: 96px 34px 1fr;
33
- align-items: center;
34
- min-width: 208px;
35
- gap: 6px;
36
- `,G=F(p)`
37
- font-size: 11px;
38
- text-align: right;
39
- `;function Te({windows:e,open:t,onToggle:n}){let r=e[0],i=e.filter(e=>e.usedRatio!==null);return P(w,{children:[N(T,{children:r.label}),N(T,{children:i.length===0?N(g,{children:`unknown`}):N(U,{children:i.map(e=>P(W,{children:[N(C,{fraction:e.usedRatio,label:`${e.label} ${e.windowType} window, ${Math.round(e.usedRatio*100)}% used`}),N(G,{children:s(e.usedRatio,0)}),N(h,{children:l(e,H(e),Date.now(),a)})]},e.windowType))})}),N(T,{$align:`right`,children:N(d,{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:N(t?me:y,{})})})]})}function K(){let{cadence:a,live:c}=de(),[l,d]=M(`24h`),[v,me]=M(`all`),[y,b]=M(``),[x,C]=M(z[0]),[F,I]=M(null),[L,R]=M(null),B=t(l),H=j(()=>B.grain===`daily`?e(Date.now()-B.ms):Math.floor((Date.now()-B.ms)/6e4)*6e4,[B]),U=j(()=>H+B.ms,[H,B]),W=re(),G={since:H,grain:B.grain},K=ae({...G,groupBy:B.by},a(6e4,`res:usage`)),q=ae({...G,groupBy:`model`},a(6e4,`res:usage`)),J=ne(x,a(ee,`res:logs`)),Y=te(6e4),X=Y.data??[],Ee=j(()=>{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)=>u[e.windowType]-u[t.windowType])}))])},[X]),Z=X.map(e=>O(V(e))).filter(e=>e!==null),De=Z.length===0?0:Math.floor(Math.min(...Z)/6e4)*6e4,Oe=r({since:De},L!==null&&Z.length>0),ke=(J.data??[]).some(oe),Ae=_e(c&&ke),Q=ye(J.data??[],v,y),je=(J.data??[]).filter(ie).length,$=K.data??[],Me=$.reduce((e,t)=>e+t.requests,0),Ne=$.reduce((e,t)=>e+t.costUsd,0);return P(f,{$gap:4,children:[N(pe,{legend:`Client`,title:`Your usage`,summary:K.isLoading?`Reading your usage…`:`${i(Me)} requests and ${o(Ne)} over the last ${B.label}.`,actions:N(A,{children:n.map(e=>N(xe,{type:`button`,$size:`sm`,$on:e.id===l,"aria-pressed":e.id===l,onClick:()=>d(e.id),children:e.id},e.id))})}),N(ue,{legend:`Your key`,meta:W.data===void 0?void 0:P(p,{$dim:!0,children:[W.data.prefix,`…`]}),children:W.isPending?N(ce,{rows:2}):W.isError?N(le,{legend:`Could not read your key`,error:W.error}):P(f,{$gap:2,children:[P(_,{$gap:2,$wrap:!0,children:[N(h,{children:W.data.label}),W.data.bodyLoggingOptOut?N(g,{children:`Request bodies are never stored for this key.`}):null]}),W.data.modelAllowlist===null?N(g,{children:`Every model this gateway serves.`}):W.data.modelAllowlist.length===0?N(g,{children:`No models. This key cannot serve a request.`}):N(_,{$gap:1,$wrap:!0,children:W.data.modelAllowlist.map(e=>N(p,{children:e},e))})]})}),N(Se,{buckets:$,since:H,until:U,by:B.by,rangeLabel:B.label}),N(k,{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:N(m,{children:P(D,{children:[N(`thead`,{children:P(`tr`,{children:[N(E,{children:`Model`}),N(E,{$align:`right`,children:`Requests`}),N(E,{$align:`right`,children:`Tokens`}),N(E,{$align:`right`,children:`Spend`})]})}),N(`tbody`,{children:(q.data??[]).map(e=>P(w,{children:[N(T,{$mono:!0,children:e.key}),N(T,{$align:`right`,$mono:!0,children:i(e.requests)}),N(T,{$align:`right`,$mono:!0,children:i(e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheWriteTokens)}),N(T,{$align:`right`,$mono:!0,children:o(e.costUsd)})]},e.key))})]})})}),N(k,{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:N(g,{children:`Counted from completed requests, so a burst in flight right now may not be included yet.`}),children:N(m,{children:P(D,{children:[N(`thead`,{children:P(`tr`,{children:[N(E,{children:`Limit`}),N(E,{$align:`right`,children:`Used`}),N(E,{$align:`right`,children:`Ceiling`}),N(E,{$width:`30%`,children:`Consumption`})]})}),N(`tbody`,{children:(W.data?.limitUsage??[]).map(e=>N(we,{reading:e},`${e.dimension}:${e.window??`gauge`}`))})]})})}),N(k,{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:N(g,{children:`What each account serving this gateway has left. A request is served by whichever account of a provider can take it.`}),children:N(f,{$gap:4,children:Ee.map(([e,t])=>P(f,{$gap:1,children:[N(h,{children:e}),N(m,{children:P(D,{children:[N(`thead`,{children:P(`tr`,{children:[N(E,{children:`Account`}),N(E,{$width:`60%`,children:`Quota`}),N(E,{})]})}),N(`tbody`,{children:t.map(({credentialId:e,windows:t})=>P(Ce,{children:[N(Te,{windows:t,open:L===e,onToggle:()=>R(L===e?null:e)}),L===e?N(w,{children:N(T,{colSpan:3,children:N(f,{$gap:4,children:t.map(e=>{let t=V(e),n=O(t),r=(Oe.data?.samples??[]).filter(t=>t.credentialId===e.credentialId&&t.windowType===e.windowType&&t.observedAt>=(n??0));return N(ge,{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:Oe.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`:`${s(e.usedRatio,0)} used`,rateText:e.ratePerHourRatio===null?`unknown`:`${s(e.ratePerHourRatio,1)}/h`},e.windowType)})})})}):null]},e))})]})})]},e))})}),N(k,{legend:`Recent requests`,meta:`${Q.length} shown`,actions:P(A,{children:[N(he,{value:y,placeholder:`Filter by model or error`,"aria-label":`Filter requests`,style:{width:200},onChange:e=>b(e.target.value)}),P(S,{value:v,"aria-label":`Show which requests`,style:{width:`auto`},onChange:e=>me(e.target.value),children:[N(`option`,{value:`all`,children:`All requests`}),N(`option`,{value:`failed`,children:`Failed only`})]}),N(S,{value:x,"aria-label":`How many requests to fetch`,style:{width:`auto`},onChange:e=>C(Number(e.target.value)),children:z.map(e=>P(`option`,{value:e,children:[`last `,e]},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:(J.data??[]).length===0?`Nothing served through this key yet.`:`No request in this window matches the filter. Clear it to see everything.`},isEmpty:Q.length===0,footer:P(g,{children:[i(je),` of the last `,i((J.data??[]).length),` failed.`]}),children:N(m,{children:N(ve,{rows:Q,now:Ae,onOpen:I})})}),N(fe,{open:F!==null,onOpenChange:e=>{e||I(null)},title:`Request detail`,width:`640px`,footer:N(se,{type:`button`,onClick:()=>I(null),children:`Close`}),children:F===null?null:N(be,{log:F})})]})}var q=()=>N(x,{children:N(b,{children:N(R,{children:N(K,{})})})});export{q as component};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/login-BSWCo_Fz.js","assets/Lamp-DN2EKL4m.js","assets/Panel-BCpZVY4U.js","assets/Field-DI5YTYOX.js","assets/reasons-Du1OBWAM.js"])))=>i.map(i=>d[i]);
2
- import{n as e,r as t,t as n}from"./preload-helper-CD37DT-E.js";var r=t(`/login`)({validateSearch:e=>({...typeof e.next==`string`?{next:e.next}:{},...typeof e.reason==`string`?{reason:e.reason}:{}}),component:e(()=>n(()=>import(`./login-BSWCo_Fz.js`),__vite__mapDeps([0,1,2,3,4])),`component`)});export{r as t};
@@ -1 +0,0 @@
1
- import{b as e}from"./Rack-B03tpeW-.js";var t=e(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]);export{t};