@tonyclaw/llm-inspector 1.8.0 → 1.9.0

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 (29) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{index-BLVa7n9b.css → index-DdJSLfxK.css} +1 -1
  3. package/.output/public/assets/{index-DH3FOgcK.js → index-DyKLPMPn.js} +18 -18
  4. package/.output/public/assets/{main-Beo3LJDa.js → main-Cu0oTDfX.js} +1 -1
  5. package/.output/server/_ssr/{index-HkueJ4Un.mjs → index-COIATcfa.mjs} +74 -28
  6. package/.output/server/_ssr/index.mjs +2 -2
  7. package/.output/server/_ssr/{router-DTswxb7l.mjs → router-CwmgKXBJ.mjs} +236 -65
  8. package/.output/server/{_tanstack-start-manifest_v-DhUuivt-.mjs → _tanstack-start-manifest_v-C7hQOzvX.mjs} +1 -1
  9. package/.output/server/index.mjs +23 -23
  10. package/README.md +8 -209
  11. package/package.json +1 -1
  12. package/src/components/ProxyViewerContainer.tsx +10 -1
  13. package/src/components/providers/ProviderCard.tsx +19 -15
  14. package/src/components/providers/ProviderForm.tsx +21 -0
  15. package/src/components/proxy-viewer/LogEntry.tsx +7 -0
  16. package/src/components/proxy-viewer/ResponseView.tsx +32 -6
  17. package/src/proxy/chunkStorage.ts +4 -6
  18. package/src/proxy/formats/anthropic/schemas.ts +9 -0
  19. package/src/proxy/formats/anthropic/stream.ts +11 -0
  20. package/src/proxy/formats/openai/stream.ts +15 -0
  21. package/src/proxy/handler.ts +34 -27
  22. package/src/proxy/logIndex.ts +52 -7
  23. package/src/proxy/logger.ts +60 -10
  24. package/src/proxy/providers.ts +5 -0
  25. package/src/proxy/schemas.ts +2 -0
  26. package/src/proxy/socketTracker.ts +90 -36
  27. package/src/proxy/store.ts +24 -14
  28. package/src/routes/api/providers.$providerId.ts +1 -0
  29. package/src/routes/api/providers.ts +2 -0
@@ -14,4 +14,4 @@ Error generating stack: `+l.message+`
14
14
  `)}else{const p=o.indexOf(`
15
15
  `);if(p>=0){const v=o.slice(0,p).trim();o=o.slice(p+1),v.length>0&&(h=JSON.parse(v),f=!0)}}}return(async()=>{try{for(;;){const{value:y,done:m}=await r.read();y&&(o+=y);const p=o.lastIndexOf(`
16
16
  `);if(p>=0){const v=o.slice(0,p);o=o.slice(p+1);const S=v.split(`
17
- `).filter(Boolean);for(const _ of S)try{u(JSON.parse(_))}catch(R){i?.(`Invalid JSON line: ${_}`,R)}}if(m)break}}catch(y){i?.("Stream processing error:",y)}})(),u(h)}async function dR({jsonStream:a,onMessage:u,onError:i}){const r=a.getReader(),{value:o,done:f}=await r.read();if(f||!o)throw new Error("Stream ended before first object");const h=JSON.parse(o);return(async()=>{try{for(;;){const{value:y,done:m}=await r.read();if(m)break;if(y)try{u(JSON.parse(y))}catch(p){i?.(`Invalid JSON: ${y}`,p)}}}catch(y){i?.("Stream processing error:",y)}})(),u(h)}function hR(a){const u="/_serverFn/"+a;return Object.assign((...o)=>{const f=vg()?.serverFns?.fetch;return rR(u,o,f??fetch)},{url:u,serverFnMeta:{id:a},[Zo]:!0})}const mR={key:"$TSS/serverfn",test:a=>typeof a!="function"||!(Zo in a)?!1:!!a[Zo],toSerializable:({serverFnMeta:a})=>({functionId:a.id}),fromSerializable:({functionId:a})=>hR(a)};var lp=cg();const Eg=0,Rg=1,Tg=2,ip=3;var up=Object.prototype.hasOwnProperty;function Ko(a,u){var i,r;if(a===u)return!0;if(a&&u&&(i=a.constructor)===u.constructor){if(i===Date)return a.getTime()===u.getTime();if(i===RegExp)return a.toString()===u.toString();if(i===Array){if((r=a.length)===u.length)for(;r--&&Ko(a[r],u[r]););return r===-1}if(!i||typeof a=="object"){r=0;for(i in a)if(up.call(a,i)&&++r&&!up.call(u,i)||!(i in u)||!Ko(a[i],u[i]))return!1;return Object.keys(u).length===r}}return a!==a&&u!==u}const Bn=new WeakMap,Hn=()=>{},ge=Hn(),Xs=Object,_t=a=>a===ge,sn=a=>typeof a=="function",Gn=(a,u)=>({...a,...u}),Ag=a=>sn(a.then),No={},As={},pf="undefined",lu=typeof window!=pf,Jo=typeof document!=pf,yR=lu&&"Deno"in window,pR=()=>lu&&typeof window.requestAnimationFrame!=pf,Og=(a,u)=>{const i=Bn.get(a);return[()=>!_t(u)&&a.get(u)||No,r=>{if(!_t(u)){const o=a.get(u);u in As||(As[u]=o),i[5](u,Gn(o,r),o||No)}},i[6],()=>!_t(u)&&u in As?As[u]:!_t(u)&&a.get(u)||No]};let ko=!0;const gR=()=>ko,[Fo,Po]=lu&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[Hn,Hn],vR=()=>{const a=Jo&&document.visibilityState;return _t(a)||a!=="hidden"},SR=a=>(Jo&&document.addEventListener("visibilitychange",a),Fo("focus",a),()=>{Jo&&document.removeEventListener("visibilitychange",a),Po("focus",a)}),bR=a=>{const u=()=>{ko=!0,a()},i=()=>{ko=!1};return Fo("online",u),Fo("offline",i),()=>{Po("online",u),Po("offline",i)}},_R={isOnline:gR,isVisible:vR},ER={initFocus:SR,initReconnect:bR},sp=!qn.useId,Fl=!lu||yR,RR=a=>pR()?window.requestAnimationFrame(a):setTimeout(a,1),Ds=Fl?$.useEffect:$.useLayoutEffect,Uo=typeof navigator<"u"&&navigator.connection,rp=!Fl&&Uo&&(["slow-2g","2g"].includes(Uo.effectiveType)||Uo.saveData),Os=new WeakMap,TR=a=>Xs.prototype.toString.call(a),Bo=(a,u)=>a===`[object ${u}]`;let AR=0;const Wo=a=>{const u=typeof a,i=TR(a),r=Bo(i,"Date"),o=Bo(i,"RegExp"),f=Bo(i,"Object");let h,y;if(Xs(a)===a&&!r&&!o){if(h=Os.get(a),h)return h;if(h=++AR+"~",Os.set(a,h),Array.isArray(a)){for(h="@",y=0;y<a.length;y++)h+=Wo(a[y])+",";Os.set(a,h)}if(f){h="#";const m=Xs.keys(a).sort();for(;!_t(y=m.pop());)_t(a[y])||(h+=y+":"+Wo(a[y])+",");Os.set(a,h)}}else h=r?a.toJSON():u=="symbol"?a.toString():u=="string"?JSON.stringify(a):""+a;return h},gf=a=>{if(sn(a))try{a=a()}catch{a=""}const u=a;return a=typeof a=="string"?a:(Array.isArray(a)?a.length:a)?Wo(a):"",[a,u]};let OR=0;const $o=()=>++OR;async function wg(...a){const[u,i,r,o]=a,f=Gn({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let h=f.populateCache;const y=f.rollbackOnError;let m=f.optimisticData;const p=_=>typeof y=="function"?y(_):y!==!1,v=f.throwOnError;if(sn(i)){const _=i,R=[],z=u.keys();for(const A of z)!/^\$(inf|sub)\$/.test(A)&&_(u.get(A)._k)&&R.push(A);return Promise.all(R.map(S))}return S(i);async function S(_){const[R]=gf(_);if(!R)return;const[z,A]=Og(u,R),[x,Y,B,Z]=Bn.get(u),H=()=>{const it=x[R];return(sn(f.revalidate)?f.revalidate(z().data,_):f.revalidate!==!1)&&(delete B[R],delete Z[R],it&&it[0])?it[0](Tg).then(()=>z().data):z().data};if(a.length<3)return H();let k=r,I,Q=!1;const X=$o();Y[R]=[X,0];const K=!_t(m),rt=z(),nt=rt.data,lt=rt._c,ht=_t(lt)?nt:lt;if(K&&(m=sn(m)?m(ht,nt):m,A({data:m,_c:ht})),sn(k))try{k=k(ht)}catch(it){I=it,Q=!0}if(k&&Ag(k))if(k=await k.catch(it=>{I=it,Q=!0}),X!==Y[R][0]){if(Q)throw I;return k}else Q&&K&&p(I)&&(h=!0,A({data:ht,_c:ge}));if(h&&!Q)if(sn(h)){const it=h(k,ht);A({data:it,error:ge,_c:ge})}else A({data:k,error:ge,_c:ge});if(Y[R][1]=$o(),Promise.resolve(H()).then(()=>{A({_c:ge})}),Q){if(v)throw I;return}return k}}const cp=(a,u)=>{for(const i in a)a[i][0]&&a[i][0](u)},Mg=(a,u)=>{if(!Bn.has(a)){const i=Gn(ER,u),r=Object.create(null),o=wg.bind(ge,a);let f=Hn;const h=Object.create(null),y=(v,S)=>{const _=h[v]||[];return h[v]=_,_.push(S),()=>_.splice(_.indexOf(S),1)},m=(v,S,_)=>{a.set(v,S);const R=h[v];if(R)for(const z of R)z(S,_)},p=()=>{if(!Bn.has(a)&&(Bn.set(a,[r,Object.create(null),Object.create(null),Object.create(null),o,m,y]),!Fl)){const v=i.initFocus(setTimeout.bind(ge,cp.bind(ge,r,Eg))),S=i.initReconnect(setTimeout.bind(ge,cp.bind(ge,r,Rg)));f=()=>{v&&v(),S&&S(),Bn.delete(a)}}};return p(),[a,o,p,f]}return[a,Bn.get(a)[4]]},wR=(a,u,i,r,o)=>{const f=i.errorRetryCount,h=o.retryCount,y=~~((Math.random()+.5)*(1<<(h<8?h:8)))*i.errorRetryInterval;!_t(f)&&h>f||setTimeout(r,y,o)},MR=Ko,[vf,xR]=Mg(new Map),xg=Gn({onLoadingSlow:Hn,onSuccess:Hn,onError:Hn,onErrorRetry:wR,onDiscarded:Hn,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:rp?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:rp?5e3:3e3,compare:MR,isPaused:()=>!1,cache:vf,mutate:xR,fallback:{}},_R),zg=(a,u)=>{const i=Gn(a,u);if(u){const{use:r,fallback:o}=a,{use:f,fallback:h}=u;r&&f&&(i.use=r.concat(f)),o&&h&&(i.fallback=Gn(o,h))}return i},Io=$.createContext({}),zR=a=>{const{value:u}=a,i=$.useContext(Io),r=sn(u),o=$.useMemo(()=>r?u(i):u,[r,i,u]),f=$.useMemo(()=>r?o:zg(i,o),[r,i,o]),h=o&&o.provider,y=$.useRef(ge);h&&!y.current&&(y.current=Mg(h(f.cache||vf),o));const m=y.current;return m&&(f.cache=m[0],f.mutate=m[1]),Ds(()=>{if(m)return m[2]&&m[2](),m[3]},[]),$.createElement(Io.Provider,Gn(a,{value:f}))},CR="$inf$",Cg=lu&&window.__SWR_DEVTOOLS_USE__,DR=Cg?window.__SWR_DEVTOOLS_USE__:[],LR=()=>{Cg&&(window.__SWR_DEVTOOLS_REACT__=qn)},NR=a=>sn(a[1])?[a[0],a[1],a[2]||{}]:[a[0],null,(a[1]===null?a[2]:a[1])||{}],UR=()=>{const a=$.useContext(Io);return $.useMemo(()=>Gn(xg,a),[a])},BR=a=>(u,i,r)=>a(u,i&&((...f)=>{const[h]=gf(u),[,,,y]=Bn.get(vf);if(h.startsWith(CR))return i(...f);const m=y[h];return _t(m)?i(...f):(delete y[h],m)}),r),jR=DR.concat(BR),HR=a=>function(...i){const r=UR(),[o,f,h]=NR(i),y=zg(r,h);let m=a;const{use:p}=y,v=(p||[]).concat(jR);for(let S=v.length;S--;)m=v[S](m);return m(o,f||y.fetcher||null,y)},qR=(a,u,i)=>{const r=u[a]||(u[a]=[]);return r.push(i),()=>{const o=r.indexOf(i);o>=0&&(r[o]=r[r.length-1],r.pop())}};LR();const jo=qn.use||(a=>{switch(a.status){case"pending":throw a;case"fulfilled":return a.value;case"rejected":throw a.reason;default:throw a.status="pending",a.then(u=>{a.status="fulfilled",a.value=u},u=>{a.status="rejected",a.reason=u}),a}}),Ho={dedupe:!0},op=Promise.resolve(ge),VR=()=>Hn,YR=(a,u,i)=>{const{cache:r,compare:o,suspense:f,fallbackData:h,revalidateOnMount:y,revalidateIfStale:m,refreshInterval:p,refreshWhenHidden:v,refreshWhenOffline:S,keepPreviousData:_,strictServerPrefetchWarning:R}=i,[z,A,x,Y]=Bn.get(r),[B,Z]=gf(a),H=$.useRef(!1),k=$.useRef(!1),I=$.useRef(B),Q=$.useRef(u),X=$.useRef(i),K=()=>X.current,rt=()=>K().isVisible()&&K().isOnline(),[nt,lt,ht,it]=Og(r,B),jt=$.useRef({}).current,N=_t(h)?_t(i.fallback)?ge:i.fallback[B]:h,F=(Et,Lt)=>{for(const At in jt){const qt=At;if(qt==="data"){if(!o(Et[qt],Lt[qt])&&(!_t(Et[qt])||!o(ot,Lt[qt])))return!1}else if(Lt[qt]!==Et[qt])return!1}return!0},ut=!H.current,Tt=$.useMemo(()=>{const Et=nt(),Lt=it(),At=Jt=>{const Vt=Gn(Jt);return delete Vt._k,(()=>{if(!B||!u||K().isPaused())return!1;if(ut&&!_t(y))return y;const xt=_t(N)?Vt.data:N;return _t(xt)||m})()?{isValidating:!0,isLoading:!0,...Vt}:Vt},qt=At(Et),ve=Et===Lt?qt:At(Lt);let oe=qt;return[()=>{const Jt=At(nt());return F(Jt,oe)?(oe.data=Jt.data,oe.isLoading=Jt.isLoading,oe.isValidating=Jt.isValidating,oe.error=Jt.error,oe):(oe=Jt,Jt)},()=>ve]},[r,B]),pt=lp.useSyncExternalStore($.useCallback(Et=>ht(B,(Lt,At)=>{F(At,Lt)||Et()}),[r,B]),Tt[0],Tt[1]),w=z[B]&&z[B].length>0,q=pt.data,J=_t(q)?N&&Ag(N)?jo(N):N:q,P=pt.error,ct=$.useRef(J),ot=_?_t(q)?_t(ct.current)?J:ct.current:q:J,ft=B&&_t(J),Xt=$.useRef(null);!Fl&&lp.useSyncExternalStore(VR,()=>(Xt.current=!1,Xt),()=>(Xt.current=!0,Xt));const Ht=Xt.current;R&&Ht&&!f&&ft&&console.warn(`Missing pre-initiated data for serialized key "${B}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);const De=!B||!u||K().isPaused()||w&&!_t(P)?!1:ut&&!_t(y)?y:f?_t(J)?!1:m:_t(J)||m,Xe=ut&&De,Qn=_t(pt.isValidating)?Xe:pt.isValidating,Ta=_t(pt.isLoading)?Xe:pt.isLoading,_e=$.useCallback(async Et=>{const Lt=Q.current;if(!B||!Lt||k.current||K().isPaused())return!1;let At,qt,ve=!0;const oe=Et||{},Jt=!x[B]||!oe.dedupe,Vt=()=>sp?!k.current&&B===I.current&&H.current:B===I.current,yn={isValidating:!1,isLoading:!1},xt=()=>{lt(yn)},$t=()=>{const fe=x[B];fe&&fe[1]===qt&&delete x[B]},ae={isValidating:!0};_t(nt().data)&&(ae.isLoading=!0);try{if(Jt&&(lt(ae),i.loadingTimeout&&_t(nt().data)&&setTimeout(()=>{ve&&Vt()&&K().onLoadingSlow(B,i)},i.loadingTimeout),x[B]=[Lt(Z),$o()]),[At,qt]=x[B],At=await At,Jt&&setTimeout($t,i.dedupingInterval),!x[B]||x[B][1]!==qt)return Jt&&Vt()&&K().onDiscarded(B),!1;yn.error=ge;const fe=A[B];if(!_t(fe)&&(qt<=fe[0]||qt<=fe[1]||fe[1]===0))return xt(),Jt&&Vt()&&K().onDiscarded(B),!1;const Qe=nt().data;yn.data=o(Qe,At)?Qe:At,Jt&&Vt()&&K().onSuccess(At,B,i)}catch(fe){$t();const Qe=K(),{shouldRetryOnError:Wl}=Qe;Qe.isPaused()||(yn.error=fe,Jt&&Vt()&&(Qe.onError(fe,B,Qe),(Wl===!0||sn(Wl)&&Wl(fe))&&(!K().revalidateOnFocus||!K().revalidateOnReconnect||rt())&&Qe.onErrorRetry(fe,B,Qe,$s=>{const pn=z[B];pn&&pn[0]&&pn[0](ip,$s)},{retryCount:(oe.retryCount||0)+1,dedupe:!0})))}return ve=!1,xt(),!0},[B,r]),mn=$.useCallback((...Et)=>wg(r,I.current,...Et),[]);if(Ds(()=>{Q.current=u,X.current=i,_t(q)||(ct.current=q)}),Ds(()=>{if(!B)return;const Et=_e.bind(ge,Ho);let Lt=0;K().revalidateOnFocus&&(Lt=Date.now()+K().focusThrottleInterval);const qt=qR(B,z,(ve,oe={})=>{if(ve==Eg){const Jt=Date.now();K().revalidateOnFocus&&Jt>Lt&&rt()&&(Lt=Jt+K().focusThrottleInterval,Et())}else if(ve==Rg)K().revalidateOnReconnect&&rt()&&Et();else{if(ve==Tg)return _e();if(ve==ip)return _e(oe)}});return k.current=!1,I.current=B,H.current=!0,lt({_k:Z}),De&&(x[B]||(_t(J)||Fl?Et():RR(Et))),()=>{k.current=!0,qt()}},[B]),Ds(()=>{let Et;function Lt(){const qt=sn(p)?p(nt().data):p;qt&&Et!==-1&&(Et=setTimeout(At,qt))}function At(){!nt().error&&(v||K().isVisible())&&(S||K().isOnline())?_e(Ho).then(Lt):Lt()}return Lt(),()=>{Et&&(clearTimeout(Et),Et=-1)}},[p,v,S,B]),$.useDebugValue(ot),f){if(!sp&&Fl&&ft)throw new Error("Fallback data is required when using Suspense in SSR.");ft&&(Q.current=u,X.current=i,k.current=!1);const Et=Y[B],Lt=!_t(Et)&&ft?mn(Et):op;if(jo(Lt),!_t(P)&&ft)throw P;const At=ft?_e(Ho):op;!_t(ot)&&ft&&(At.status="fulfilled",At.value=!0),jo(At)}return{mutate:mn,get data(){return jt.data=!0,ot},get error(){return jt.error=!0,P},get isValidating(){return jt.isValidating=!0,Qn},get isLoading(){return jt.isLoading=!0,Ta}}},GR=Xs.defineProperty(zR,"defaultValue",{value:xg}),oT=HR(YR),XR="/assets/index-BLVa7n9b.css",Dg=DE({head:()=>({meta:[{charSet:"utf-8"},{name:"viewport",content:"width=device-width, initial-scale=1"},{title:"llm-inspector"}],links:[{rel:"stylesheet",href:XR}]}),component:QR});function QR(){return W.jsx(ZR,{children:W.jsx(yg,{})})}function ZR({children:a}){return W.jsxs("html",{lang:"en",className:"dark",children:[W.jsx("head",{children:W.jsx(kE,{})}),W.jsxs("body",{children:[W.jsx(GR,{value:{revalidateOnFocus:!1,revalidateIfStale:!1},children:a}),W.jsx(FE,{})]})]})}const KR="modulepreload",JR=function(a){return"/"+a},fp={},kR=function(u,i,r){let o=Promise.resolve();if(i&&i.length>0){let m=function(p){return Promise.all(p.map(v=>Promise.resolve(v).then(S=>({status:"fulfilled",value:S}),S=>({status:"rejected",reason:S}))))};document.getElementsByTagName("link");const h=document.querySelector("meta[property=csp-nonce]"),y=h?.nonce||h?.getAttribute("nonce");o=m(i.map(p=>{if(p=JR(p),p in fp)return;fp[p]=!0;const v=p.endsWith(".css"),S=v?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${S}`))return;const _=document.createElement("link");if(_.rel=v?"stylesheet":KR,v||(_.as="script"),_.crossOrigin="",_.href=p,y&&_.setAttribute("nonce",y),document.head.appendChild(_),v)return new Promise((R,z)=>{_.addEventListener("load",R),_.addEventListener("error",()=>z(new Error(`Unable to preload CSS for ${p}`)))})}))}function f(h){const y=new Event("vite:preloadError",{cancelable:!0});if(y.payload=h,window.dispatchEvent(y),!y.defaultPrevented)throw h}return o.then(h=>{for(const y of h||[])y.status==="rejected"&&f(y.reason);return u().catch(f)})},FR=()=>kR(()=>import("./index-DH3FOgcK.js"),[]),PR=Qo("/")({component:LE(FR,"component")}),WR=PR.update({id:"/",path:"/",getParentRoute:()=>Dg}),$R={IndexRoute:WR},IR=Dg._addFileChildren($R);function tT(){return YE({routeTree:IR,scrollRestoration:!1})}async function eT(){const a=await tT();let u;return u=[],window.__TSS_START_OPTIONS__={serializationAdapters:u},u.push(mR),a.options.serializationAdapters&&u.push(...a.options.serializationAdapters),a.update({basepath:"",serializationAdapters:u}),a.state.matches.length||await WE(a),a}async function nT(){const a=await eT();return window.$_TSR?.h(),a}let qo;function aT(){return qo||(qo=nT()),W.jsx(rE,{promise:qo,children:a=>W.jsx(QE,{router:a})})}$.startTransition(()=>{iS.hydrateRoot(document,W.jsx($.StrictMode,{children:W.jsx(aT,{})}))});export{qn as R,fg as a,I0 as b,lT as c,rT as d,dp as g,W as j,$ as r,oT as u};
17
+ `).filter(Boolean);for(const _ of S)try{u(JSON.parse(_))}catch(R){i?.(`Invalid JSON line: ${_}`,R)}}if(m)break}}catch(y){i?.("Stream processing error:",y)}})(),u(h)}async function dR({jsonStream:a,onMessage:u,onError:i}){const r=a.getReader(),{value:o,done:f}=await r.read();if(f||!o)throw new Error("Stream ended before first object");const h=JSON.parse(o);return(async()=>{try{for(;;){const{value:y,done:m}=await r.read();if(m)break;if(y)try{u(JSON.parse(y))}catch(p){i?.(`Invalid JSON: ${y}`,p)}}}catch(y){i?.("Stream processing error:",y)}})(),u(h)}function hR(a){const u="/_serverFn/"+a;return Object.assign((...o)=>{const f=vg()?.serverFns?.fetch;return rR(u,o,f??fetch)},{url:u,serverFnMeta:{id:a},[Zo]:!0})}const mR={key:"$TSS/serverfn",test:a=>typeof a!="function"||!(Zo in a)?!1:!!a[Zo],toSerializable:({serverFnMeta:a})=>({functionId:a.id}),fromSerializable:({functionId:a})=>hR(a)};var lp=cg();const Eg=0,Rg=1,Tg=2,ip=3;var up=Object.prototype.hasOwnProperty;function Ko(a,u){var i,r;if(a===u)return!0;if(a&&u&&(i=a.constructor)===u.constructor){if(i===Date)return a.getTime()===u.getTime();if(i===RegExp)return a.toString()===u.toString();if(i===Array){if((r=a.length)===u.length)for(;r--&&Ko(a[r],u[r]););return r===-1}if(!i||typeof a=="object"){r=0;for(i in a)if(up.call(a,i)&&++r&&!up.call(u,i)||!(i in u)||!Ko(a[i],u[i]))return!1;return Object.keys(u).length===r}}return a!==a&&u!==u}const Bn=new WeakMap,Hn=()=>{},ge=Hn(),Xs=Object,_t=a=>a===ge,sn=a=>typeof a=="function",Gn=(a,u)=>({...a,...u}),Ag=a=>sn(a.then),No={},As={},pf="undefined",lu=typeof window!=pf,Jo=typeof document!=pf,yR=lu&&"Deno"in window,pR=()=>lu&&typeof window.requestAnimationFrame!=pf,Og=(a,u)=>{const i=Bn.get(a);return[()=>!_t(u)&&a.get(u)||No,r=>{if(!_t(u)){const o=a.get(u);u in As||(As[u]=o),i[5](u,Gn(o,r),o||No)}},i[6],()=>!_t(u)&&u in As?As[u]:!_t(u)&&a.get(u)||No]};let ko=!0;const gR=()=>ko,[Fo,Po]=lu&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[Hn,Hn],vR=()=>{const a=Jo&&document.visibilityState;return _t(a)||a!=="hidden"},SR=a=>(Jo&&document.addEventListener("visibilitychange",a),Fo("focus",a),()=>{Jo&&document.removeEventListener("visibilitychange",a),Po("focus",a)}),bR=a=>{const u=()=>{ko=!0,a()},i=()=>{ko=!1};return Fo("online",u),Fo("offline",i),()=>{Po("online",u),Po("offline",i)}},_R={isOnline:gR,isVisible:vR},ER={initFocus:SR,initReconnect:bR},sp=!qn.useId,Fl=!lu||yR,RR=a=>pR()?window.requestAnimationFrame(a):setTimeout(a,1),Ds=Fl?$.useEffect:$.useLayoutEffect,Uo=typeof navigator<"u"&&navigator.connection,rp=!Fl&&Uo&&(["slow-2g","2g"].includes(Uo.effectiveType)||Uo.saveData),Os=new WeakMap,TR=a=>Xs.prototype.toString.call(a),Bo=(a,u)=>a===`[object ${u}]`;let AR=0;const Wo=a=>{const u=typeof a,i=TR(a),r=Bo(i,"Date"),o=Bo(i,"RegExp"),f=Bo(i,"Object");let h,y;if(Xs(a)===a&&!r&&!o){if(h=Os.get(a),h)return h;if(h=++AR+"~",Os.set(a,h),Array.isArray(a)){for(h="@",y=0;y<a.length;y++)h+=Wo(a[y])+",";Os.set(a,h)}if(f){h="#";const m=Xs.keys(a).sort();for(;!_t(y=m.pop());)_t(a[y])||(h+=y+":"+Wo(a[y])+",");Os.set(a,h)}}else h=r?a.toJSON():u=="symbol"?a.toString():u=="string"?JSON.stringify(a):""+a;return h},gf=a=>{if(sn(a))try{a=a()}catch{a=""}const u=a;return a=typeof a=="string"?a:(Array.isArray(a)?a.length:a)?Wo(a):"",[a,u]};let OR=0;const $o=()=>++OR;async function wg(...a){const[u,i,r,o]=a,f=Gn({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let h=f.populateCache;const y=f.rollbackOnError;let m=f.optimisticData;const p=_=>typeof y=="function"?y(_):y!==!1,v=f.throwOnError;if(sn(i)){const _=i,R=[],z=u.keys();for(const A of z)!/^\$(inf|sub)\$/.test(A)&&_(u.get(A)._k)&&R.push(A);return Promise.all(R.map(S))}return S(i);async function S(_){const[R]=gf(_);if(!R)return;const[z,A]=Og(u,R),[x,Y,B,Z]=Bn.get(u),H=()=>{const it=x[R];return(sn(f.revalidate)?f.revalidate(z().data,_):f.revalidate!==!1)&&(delete B[R],delete Z[R],it&&it[0])?it[0](Tg).then(()=>z().data):z().data};if(a.length<3)return H();let k=r,I,Q=!1;const X=$o();Y[R]=[X,0];const K=!_t(m),rt=z(),nt=rt.data,lt=rt._c,ht=_t(lt)?nt:lt;if(K&&(m=sn(m)?m(ht,nt):m,A({data:m,_c:ht})),sn(k))try{k=k(ht)}catch(it){I=it,Q=!0}if(k&&Ag(k))if(k=await k.catch(it=>{I=it,Q=!0}),X!==Y[R][0]){if(Q)throw I;return k}else Q&&K&&p(I)&&(h=!0,A({data:ht,_c:ge}));if(h&&!Q)if(sn(h)){const it=h(k,ht);A({data:it,error:ge,_c:ge})}else A({data:k,error:ge,_c:ge});if(Y[R][1]=$o(),Promise.resolve(H()).then(()=>{A({_c:ge})}),Q){if(v)throw I;return}return k}}const cp=(a,u)=>{for(const i in a)a[i][0]&&a[i][0](u)},Mg=(a,u)=>{if(!Bn.has(a)){const i=Gn(ER,u),r=Object.create(null),o=wg.bind(ge,a);let f=Hn;const h=Object.create(null),y=(v,S)=>{const _=h[v]||[];return h[v]=_,_.push(S),()=>_.splice(_.indexOf(S),1)},m=(v,S,_)=>{a.set(v,S);const R=h[v];if(R)for(const z of R)z(S,_)},p=()=>{if(!Bn.has(a)&&(Bn.set(a,[r,Object.create(null),Object.create(null),Object.create(null),o,m,y]),!Fl)){const v=i.initFocus(setTimeout.bind(ge,cp.bind(ge,r,Eg))),S=i.initReconnect(setTimeout.bind(ge,cp.bind(ge,r,Rg)));f=()=>{v&&v(),S&&S(),Bn.delete(a)}}};return p(),[a,o,p,f]}return[a,Bn.get(a)[4]]},wR=(a,u,i,r,o)=>{const f=i.errorRetryCount,h=o.retryCount,y=~~((Math.random()+.5)*(1<<(h<8?h:8)))*i.errorRetryInterval;!_t(f)&&h>f||setTimeout(r,y,o)},MR=Ko,[vf,xR]=Mg(new Map),xg=Gn({onLoadingSlow:Hn,onSuccess:Hn,onError:Hn,onErrorRetry:wR,onDiscarded:Hn,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:rp?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:rp?5e3:3e3,compare:MR,isPaused:()=>!1,cache:vf,mutate:xR,fallback:{}},_R),zg=(a,u)=>{const i=Gn(a,u);if(u){const{use:r,fallback:o}=a,{use:f,fallback:h}=u;r&&f&&(i.use=r.concat(f)),o&&h&&(i.fallback=Gn(o,h))}return i},Io=$.createContext({}),zR=a=>{const{value:u}=a,i=$.useContext(Io),r=sn(u),o=$.useMemo(()=>r?u(i):u,[r,i,u]),f=$.useMemo(()=>r?o:zg(i,o),[r,i,o]),h=o&&o.provider,y=$.useRef(ge);h&&!y.current&&(y.current=Mg(h(f.cache||vf),o));const m=y.current;return m&&(f.cache=m[0],f.mutate=m[1]),Ds(()=>{if(m)return m[2]&&m[2](),m[3]},[]),$.createElement(Io.Provider,Gn(a,{value:f}))},CR="$inf$",Cg=lu&&window.__SWR_DEVTOOLS_USE__,DR=Cg?window.__SWR_DEVTOOLS_USE__:[],LR=()=>{Cg&&(window.__SWR_DEVTOOLS_REACT__=qn)},NR=a=>sn(a[1])?[a[0],a[1],a[2]||{}]:[a[0],null,(a[1]===null?a[2]:a[1])||{}],UR=()=>{const a=$.useContext(Io);return $.useMemo(()=>Gn(xg,a),[a])},BR=a=>(u,i,r)=>a(u,i&&((...f)=>{const[h]=gf(u),[,,,y]=Bn.get(vf);if(h.startsWith(CR))return i(...f);const m=y[h];return _t(m)?i(...f):(delete y[h],m)}),r),jR=DR.concat(BR),HR=a=>function(...i){const r=UR(),[o,f,h]=NR(i),y=zg(r,h);let m=a;const{use:p}=y,v=(p||[]).concat(jR);for(let S=v.length;S--;)m=v[S](m);return m(o,f||y.fetcher||null,y)},qR=(a,u,i)=>{const r=u[a]||(u[a]=[]);return r.push(i),()=>{const o=r.indexOf(i);o>=0&&(r[o]=r[r.length-1],r.pop())}};LR();const jo=qn.use||(a=>{switch(a.status){case"pending":throw a;case"fulfilled":return a.value;case"rejected":throw a.reason;default:throw a.status="pending",a.then(u=>{a.status="fulfilled",a.value=u},u=>{a.status="rejected",a.reason=u}),a}}),Ho={dedupe:!0},op=Promise.resolve(ge),VR=()=>Hn,YR=(a,u,i)=>{const{cache:r,compare:o,suspense:f,fallbackData:h,revalidateOnMount:y,revalidateIfStale:m,refreshInterval:p,refreshWhenHidden:v,refreshWhenOffline:S,keepPreviousData:_,strictServerPrefetchWarning:R}=i,[z,A,x,Y]=Bn.get(r),[B,Z]=gf(a),H=$.useRef(!1),k=$.useRef(!1),I=$.useRef(B),Q=$.useRef(u),X=$.useRef(i),K=()=>X.current,rt=()=>K().isVisible()&&K().isOnline(),[nt,lt,ht,it]=Og(r,B),jt=$.useRef({}).current,N=_t(h)?_t(i.fallback)?ge:i.fallback[B]:h,F=(Et,Lt)=>{for(const At in jt){const qt=At;if(qt==="data"){if(!o(Et[qt],Lt[qt])&&(!_t(Et[qt])||!o(ot,Lt[qt])))return!1}else if(Lt[qt]!==Et[qt])return!1}return!0},ut=!H.current,Tt=$.useMemo(()=>{const Et=nt(),Lt=it(),At=Jt=>{const Vt=Gn(Jt);return delete Vt._k,(()=>{if(!B||!u||K().isPaused())return!1;if(ut&&!_t(y))return y;const xt=_t(N)?Vt.data:N;return _t(xt)||m})()?{isValidating:!0,isLoading:!0,...Vt}:Vt},qt=At(Et),ve=Et===Lt?qt:At(Lt);let oe=qt;return[()=>{const Jt=At(nt());return F(Jt,oe)?(oe.data=Jt.data,oe.isLoading=Jt.isLoading,oe.isValidating=Jt.isValidating,oe.error=Jt.error,oe):(oe=Jt,Jt)},()=>ve]},[r,B]),pt=lp.useSyncExternalStore($.useCallback(Et=>ht(B,(Lt,At)=>{F(At,Lt)||Et()}),[r,B]),Tt[0],Tt[1]),w=z[B]&&z[B].length>0,q=pt.data,J=_t(q)?N&&Ag(N)?jo(N):N:q,P=pt.error,ct=$.useRef(J),ot=_?_t(q)?_t(ct.current)?J:ct.current:q:J,ft=B&&_t(J),Xt=$.useRef(null);!Fl&&lp.useSyncExternalStore(VR,()=>(Xt.current=!1,Xt),()=>(Xt.current=!0,Xt));const Ht=Xt.current;R&&Ht&&!f&&ft&&console.warn(`Missing pre-initiated data for serialized key "${B}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);const De=!B||!u||K().isPaused()||w&&!_t(P)?!1:ut&&!_t(y)?y:f?_t(J)?!1:m:_t(J)||m,Xe=ut&&De,Qn=_t(pt.isValidating)?Xe:pt.isValidating,Ta=_t(pt.isLoading)?Xe:pt.isLoading,_e=$.useCallback(async Et=>{const Lt=Q.current;if(!B||!Lt||k.current||K().isPaused())return!1;let At,qt,ve=!0;const oe=Et||{},Jt=!x[B]||!oe.dedupe,Vt=()=>sp?!k.current&&B===I.current&&H.current:B===I.current,yn={isValidating:!1,isLoading:!1},xt=()=>{lt(yn)},$t=()=>{const fe=x[B];fe&&fe[1]===qt&&delete x[B]},ae={isValidating:!0};_t(nt().data)&&(ae.isLoading=!0);try{if(Jt&&(lt(ae),i.loadingTimeout&&_t(nt().data)&&setTimeout(()=>{ve&&Vt()&&K().onLoadingSlow(B,i)},i.loadingTimeout),x[B]=[Lt(Z),$o()]),[At,qt]=x[B],At=await At,Jt&&setTimeout($t,i.dedupingInterval),!x[B]||x[B][1]!==qt)return Jt&&Vt()&&K().onDiscarded(B),!1;yn.error=ge;const fe=A[B];if(!_t(fe)&&(qt<=fe[0]||qt<=fe[1]||fe[1]===0))return xt(),Jt&&Vt()&&K().onDiscarded(B),!1;const Qe=nt().data;yn.data=o(Qe,At)?Qe:At,Jt&&Vt()&&K().onSuccess(At,B,i)}catch(fe){$t();const Qe=K(),{shouldRetryOnError:Wl}=Qe;Qe.isPaused()||(yn.error=fe,Jt&&Vt()&&(Qe.onError(fe,B,Qe),(Wl===!0||sn(Wl)&&Wl(fe))&&(!K().revalidateOnFocus||!K().revalidateOnReconnect||rt())&&Qe.onErrorRetry(fe,B,Qe,$s=>{const pn=z[B];pn&&pn[0]&&pn[0](ip,$s)},{retryCount:(oe.retryCount||0)+1,dedupe:!0})))}return ve=!1,xt(),!0},[B,r]),mn=$.useCallback((...Et)=>wg(r,I.current,...Et),[]);if(Ds(()=>{Q.current=u,X.current=i,_t(q)||(ct.current=q)}),Ds(()=>{if(!B)return;const Et=_e.bind(ge,Ho);let Lt=0;K().revalidateOnFocus&&(Lt=Date.now()+K().focusThrottleInterval);const qt=qR(B,z,(ve,oe={})=>{if(ve==Eg){const Jt=Date.now();K().revalidateOnFocus&&Jt>Lt&&rt()&&(Lt=Jt+K().focusThrottleInterval,Et())}else if(ve==Rg)K().revalidateOnReconnect&&rt()&&Et();else{if(ve==Tg)return _e();if(ve==ip)return _e(oe)}});return k.current=!1,I.current=B,H.current=!0,lt({_k:Z}),De&&(x[B]||(_t(J)||Fl?Et():RR(Et))),()=>{k.current=!0,qt()}},[B]),Ds(()=>{let Et;function Lt(){const qt=sn(p)?p(nt().data):p;qt&&Et!==-1&&(Et=setTimeout(At,qt))}function At(){!nt().error&&(v||K().isVisible())&&(S||K().isOnline())?_e(Ho).then(Lt):Lt()}return Lt(),()=>{Et&&(clearTimeout(Et),Et=-1)}},[p,v,S,B]),$.useDebugValue(ot),f){if(!sp&&Fl&&ft)throw new Error("Fallback data is required when using Suspense in SSR.");ft&&(Q.current=u,X.current=i,k.current=!1);const Et=Y[B],Lt=!_t(Et)&&ft?mn(Et):op;if(jo(Lt),!_t(P)&&ft)throw P;const At=ft?_e(Ho):op;!_t(ot)&&ft&&(At.status="fulfilled",At.value=!0),jo(At)}return{mutate:mn,get data(){return jt.data=!0,ot},get error(){return jt.error=!0,P},get isValidating(){return jt.isValidating=!0,Qn},get isLoading(){return jt.isLoading=!0,Ta}}},GR=Xs.defineProperty(zR,"defaultValue",{value:xg}),oT=HR(YR),XR="/assets/index-DdJSLfxK.css",Dg=DE({head:()=>({meta:[{charSet:"utf-8"},{name:"viewport",content:"width=device-width, initial-scale=1"},{title:"llm-inspector"}],links:[{rel:"stylesheet",href:XR}]}),component:QR});function QR(){return W.jsx(ZR,{children:W.jsx(yg,{})})}function ZR({children:a}){return W.jsxs("html",{lang:"en",className:"dark",children:[W.jsx("head",{children:W.jsx(kE,{})}),W.jsxs("body",{children:[W.jsx(GR,{value:{revalidateOnFocus:!1,revalidateIfStale:!1},children:a}),W.jsx(FE,{})]})]})}const KR="modulepreload",JR=function(a){return"/"+a},fp={},kR=function(u,i,r){let o=Promise.resolve();if(i&&i.length>0){let m=function(p){return Promise.all(p.map(v=>Promise.resolve(v).then(S=>({status:"fulfilled",value:S}),S=>({status:"rejected",reason:S}))))};document.getElementsByTagName("link");const h=document.querySelector("meta[property=csp-nonce]"),y=h?.nonce||h?.getAttribute("nonce");o=m(i.map(p=>{if(p=JR(p),p in fp)return;fp[p]=!0;const v=p.endsWith(".css"),S=v?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${S}`))return;const _=document.createElement("link");if(_.rel=v?"stylesheet":KR,v||(_.as="script"),_.crossOrigin="",_.href=p,y&&_.setAttribute("nonce",y),document.head.appendChild(_),v)return new Promise((R,z)=>{_.addEventListener("load",R),_.addEventListener("error",()=>z(new Error(`Unable to preload CSS for ${p}`)))})}))}function f(h){const y=new Event("vite:preloadError",{cancelable:!0});if(y.payload=h,window.dispatchEvent(y),!y.defaultPrevented)throw h}return o.then(h=>{for(const y of h||[])y.status==="rejected"&&f(y.reason);return u().catch(f)})},FR=()=>kR(()=>import("./index-DyKLPMPn.js"),[]),PR=Qo("/")({component:LE(FR,"component")}),WR=PR.update({id:"/",path:"/",getParentRoute:()=>Dg}),$R={IndexRoute:WR},IR=Dg._addFileChildren($R);function tT(){return YE({routeTree:IR,scrollRestoration:!1})}async function eT(){const a=await tT();let u;return u=[],window.__TSS_START_OPTIONS__={serializationAdapters:u},u.push(mR),a.options.serializationAdapters&&u.push(...a.options.serializationAdapters),a.update({basepath:"",serializationAdapters:u}),a.state.matches.length||await WE(a),a}async function nT(){const a=await eT();return window.$_TSR?.h(),a}let qo;function aT(){return qo||(qo=nT()),W.jsx(rE,{promise:qo,children:a=>W.jsx(QE,{router:a})})}$.startTransition(()=>{iS.hydrateRoot(document,W.jsx($.StrictMode,{children:W.jsx(aT,{})}))});export{qn as R,fg as a,I0 as b,lT as c,rT as d,dp as g,W as j,$ as r,oT as u};
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
2
- import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-DTswxb7l.mjs";
2
+ import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-CwmgKXBJ.mjs";
3
3
  import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
4
4
  import { J as JSZip } from "../_libs/jszip.mjs";
5
5
  import { c as clsx } from "../_libs/clsx.mjs";
@@ -199,7 +199,7 @@ async function exportLogsAsZip(logs) {
199
199
  document.body.removeChild(anchor);
200
200
  URL.revokeObjectURL(url);
201
201
  }
202
- const version = "1.8.0";
202
+ const version = "1.9.0";
203
203
  const packageJson = {
204
204
  version
205
205
  };
@@ -1509,22 +1509,37 @@ function ResponseView({
1509
1509
  outputTokens,
1510
1510
  cacheCreationInputTokens,
1511
1511
  cacheReadInputTokens,
1512
- apiFormat
1512
+ apiFormat,
1513
+ error
1513
1514
  }) {
1514
- if (responseText === null) {
1515
+ if (responseText === null && error === void 0) {
1515
1516
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-3", children: [
1516
1517
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
1517
1518
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground italic", children: "No response" })
1518
1519
  ] });
1519
1520
  }
1520
- const isError = responseStatus !== null && responseStatus >= 400;
1521
- if (isError) {
1521
+ const isHttpError = responseStatus !== null && responseStatus >= 400;
1522
+ if (isHttpError) {
1522
1523
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1523
1524
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
1524
- /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorResponseView, { text: responseText })
1525
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorResponseView, { text: responseText ?? "" }),
1526
+ error !== void 0 && error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
1527
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
1528
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: error })
1529
+ ] })
1525
1530
  ] });
1526
1531
  }
1527
- const parsed = parseResponse(responseText, apiFormat);
1532
+ if (error !== void 0 && error !== null) {
1533
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1534
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
1535
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
1536
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
1537
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: error })
1538
+ ] }),
1539
+ responseText !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorResponseView, { text: responseText }) })
1540
+ ] });
1541
+ }
1542
+ const parsed = responseText !== null ? parseResponse(responseText, apiFormat) : null;
1528
1543
  if (parsed !== null) {
1529
1544
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1530
1545
  /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
@@ -1553,7 +1568,7 @@ function ResponseView({
1553
1568
  ] })
1554
1569
  ] })
1555
1570
  ] }),
1556
- /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownFallbackView, { text: responseText })
1571
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownFallbackView, { text: responseText ?? "" })
1557
1572
  ] });
1558
1573
  }
1559
1574
  const ReplayResultSchema = object({
@@ -1936,6 +1951,10 @@ const LogEntry = reactExports.memo(function LogEntry2({
1936
1951
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", title: value, children: value })
1937
1952
  ] }, key)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "No raw headers captured" }) }) }),
1938
1953
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 space-y-3", children: [
1954
+ log.error !== void 0 && log.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
1955
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
1956
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: log.error })
1957
+ ] }),
1939
1958
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1940
1959
  CopyButton,
1941
1960
  {
@@ -1964,7 +1983,8 @@ const LogEntry = reactExports.memo(function LogEntry2({
1964
1983
  outputTokens: log.outputTokens,
1965
1984
  cacheCreationInputTokens: log.cacheCreationInputTokens,
1966
1985
  cacheReadInputTokens: log.cacheReadInputTokens,
1967
- apiFormat: log.apiFormat
1986
+ apiFormat: log.apiFormat,
1987
+ error: log.error
1968
1988
  }
1969
1989
  ) }) })
1970
1990
  ] }) })
@@ -2207,25 +2227,25 @@ function ProviderCard({
2207
2227
  onTest
2208
2228
  }) {
2209
2229
  const [showApiKey, setShowApiKey] = reactExports.useState(false);
2230
+ const docsUrl = provider.apiDocsUrl ?? Object.entries(KNOWN_PROVIDER_DOCS).find(
2231
+ ([keyword]) => provider.name.toLowerCase().includes(keyword)
2232
+ )?.[1];
2210
2233
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border rounded-lg p-4 flex flex-col gap-3 bg-card", children: [
2211
2234
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
2212
2235
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 min-w-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: provider.model !== void 0 && provider.model !== "" ? `${provider.model} (${provider.name})` : provider.name }) }),
2213
- Object.entries(KNOWN_PROVIDER_DOCS).map(
2214
- ([keyword, url]) => provider.name.toLowerCase().includes(keyword) ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
2215
- "a",
2216
- {
2217
- href: url,
2218
- target: "_blank",
2219
- rel: "noopener noreferrer",
2220
- className: "text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1 text-xs",
2221
- title: "View API documentation",
2222
- children: [
2223
- /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
2224
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Docs" })
2225
- ]
2226
- },
2227
- keyword
2228
- ) : null
2236
+ docsUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
2237
+ "a",
2238
+ {
2239
+ href: docsUrl,
2240
+ target: "_blank",
2241
+ rel: "noopener noreferrer",
2242
+ className: "text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1 text-xs",
2243
+ title: "View API documentation",
2244
+ children: [
2245
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
2246
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Docs" })
2247
+ ]
2248
+ }
2229
2249
  )
2230
2250
  ] }),
2231
2251
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -2331,6 +2351,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
2331
2351
  const [model, setModel] = reactExports.useState(provider?.model ?? "");
2332
2352
  const [format, setFormat] = reactExports.useState(provider?.format ?? "anthropic");
2333
2353
  const [baseUrl, setBaseUrl] = reactExports.useState(provider?.baseUrl ?? "");
2354
+ const [apiDocsUrl, setApiDocsUrl] = reactExports.useState(provider?.apiDocsUrl ?? "");
2334
2355
  const [errors, setErrors] = reactExports.useState({});
2335
2356
  const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
2336
2357
  const [manualBaseUrlOverride, setManualBaseUrlOverride] = reactExports.useState(false);
@@ -2343,6 +2364,7 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
2343
2364
  setModel(provider.model ?? "");
2344
2365
  setFormat(provider.format ?? "anthropic");
2345
2366
  setBaseUrl(provider.baseUrl ?? "");
2367
+ setApiDocsUrl(provider.apiDocsUrl ?? "");
2346
2368
  setManualBaseUrlOverride(false);
2347
2369
  }
2348
2370
  }, [provider]);
@@ -2401,7 +2423,8 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
2401
2423
  apiKey: apiKey.trim(),
2402
2424
  model: model.trim() || void 0,
2403
2425
  format,
2404
- baseUrl: baseUrl.trim() || void 0
2426
+ baseUrl: baseUrl.trim() || void 0,
2427
+ apiDocsUrl: apiDocsUrl.trim() || void 0
2405
2428
  });
2406
2429
  } finally {
2407
2430
  setIsSubmitting(false);
@@ -2513,6 +2536,21 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
2513
2536
  errors.baseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.baseUrl }),
2514
2537
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Base URL for the provider API." })
2515
2538
  ] }),
2539
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
2540
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-api-docs-url", className: "text-sm font-medium", children: "API Docs URL" }),
2541
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
2542
+ "input",
2543
+ {
2544
+ id: "provider-api-docs-url",
2545
+ type: "text",
2546
+ value: apiDocsUrl,
2547
+ onChange: (e) => setApiDocsUrl(e.target.value),
2548
+ placeholder: "https://api.example.com/docs",
2549
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
2550
+ }
2551
+ ),
2552
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Optional API documentation URL. If not set, uses known provider docs." })
2553
+ ] }),
2516
2554
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 justify-end pt-2", children: [
2517
2555
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isSubmitting, children: "Cancel" }),
2518
2556
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? "Saving..." : provider ? "Update Provider" : "Add Provider" })
@@ -3291,6 +3329,7 @@ function ProxyViewerContainer() {
3291
3329
  const [viewMode, setViewMode] = reactExports.useState("simple");
3292
3330
  const [error, setError] = reactExports.useState(null);
3293
3331
  const eventSourceRef = reactExports.useRef(null);
3332
+ const reconnectTimeoutRef = reactExports.useRef(null);
3294
3333
  const fetchSessionsAndModels = reactExports.useCallback(async () => {
3295
3334
  try {
3296
3335
  const [sessionsRes, modelsRes] = await Promise.all([
@@ -3365,7 +3404,10 @@ function ProxyViewerContainer() {
3365
3404
  es.onerror = () => {
3366
3405
  setError("SSE connection lost, reconnecting...");
3367
3406
  es.close();
3368
- setTimeout(connectSSE, 3e3);
3407
+ if (reconnectTimeoutRef.current !== null) {
3408
+ clearTimeout(reconnectTimeoutRef.current);
3409
+ }
3410
+ reconnectTimeoutRef.current = setTimeout(connectSSE, 3e3);
3369
3411
  };
3370
3412
  void fetchSessionsAndModels();
3371
3413
  }, [selectedSession, selectedModel, fetchSessionsAndModels]);
@@ -3376,6 +3418,10 @@ function ProxyViewerContainer() {
3376
3418
  eventSourceRef.current.close();
3377
3419
  eventSourceRef.current = null;
3378
3420
  }
3421
+ if (reconnectTimeoutRef.current !== null) {
3422
+ clearTimeout(reconnectTimeoutRef.current);
3423
+ reconnectTimeoutRef.current = null;
3424
+ }
3379
3425
  };
3380
3426
  }, [connectSSE]);
3381
3427
  const handleClearAll = reactExports.useCallback(() => {
@@ -197,7 +197,7 @@ function getResponse() {
197
197
  return event.res;
198
198
  }
199
199
  async function getStartManifest(matchedRoutes) {
200
- const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DhUuivt-.mjs");
200
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-C7hQOzvX.mjs");
201
201
  const startManifest = tsrStartManifest();
202
202
  const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
203
203
  rootRoute.assets = rootRoute.assets || [];
@@ -766,7 +766,7 @@ let entriesPromise;
766
766
  let baseManifestPromise;
767
767
  let cachedFinalManifestPromise;
768
768
  async function loadEntries() {
769
- const routerEntry = await import("./router-DTswxb7l.mjs").then((n) => n.r);
769
+ const routerEntry = await import("./router-CwmgKXBJ.mjs").then((n) => n.r);
770
770
  const startEntry = await import("./start-HYkvq4Ni.mjs");
771
771
  return { startEntry, routerEntry };
772
772
  }