@tonyclaw/llm-inspector 1.9.1 → 1.9.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.
@@ -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-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-BmEH5jeO.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-NbnUMVAa.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-D9uLXa9A.mjs";
2
+ import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-B2hY1uUy.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.9.1";
202
+ const version = "1.9.3";
203
203
  const packageJson = {
204
204
  version
205
205
  };
@@ -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-ByfnNZV_.mjs");
200
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-BGfS8x6m.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-D9uLXa9A.mjs").then((n) => n.r);
769
+ const routerEntry = await import("./router-B2hY1uUy.mjs").then((n) => n.r);
770
770
  const startEntry = await import("./start-HYkvq4Ni.mjs");
771
771
  return { startEntry, routerEntry };
772
772
  }
@@ -3,7 +3,7 @@ import { j as jsxRuntimeExports } from "../_libs/react.mjs";
3
3
  import { S as SWRConfig } from "../_libs/swr.mjs";
4
4
  import { mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, existsSync, readFileSync } from "node:fs";
5
5
  import path, { join, isAbsolute, dirname } from "node:path";
6
- import { mkdir, appendFile, readFile, writeFile, readdir, stat, unlink } from "node:fs/promises";
6
+ import { mkdir, appendFile, readdir, stat, unlink, readFile, writeFile } from "node:fs/promises";
7
7
  import { C as Conf } from "../_libs/conf.mjs";
8
8
  import { randomUUID } from "crypto";
9
9
  import { exec } from "node:child_process";
@@ -68,7 +68,7 @@ function RootDocument({ children }) {
68
68
  ] })
69
69
  ] });
70
70
  }
71
- const $$splitComponentImporter = () => import("./index-D0d6QxPt.mjs");
71
+ const $$splitComponentImporter = () => import("./index-B4OiUMkw.mjs");
72
72
  const Route$f = createFileRoute("/")({
73
73
  component: lazyRouteComponent($$splitComponentImporter, "component")
74
74
  });
@@ -127,7 +127,12 @@ async function initLogger() {
127
127
  console.error("[logger] Failed to initialize log directory:", err);
128
128
  }
129
129
  }
130
+ let loggerInitialized = false;
130
131
  async function writeAppLog(message) {
132
+ if (!loggerInitialized) {
133
+ loggerInitialized = true;
134
+ void initLogger();
135
+ }
131
136
  try {
132
137
  const logPath = getInspectorLogPath();
133
138
  const logDirPath = path.dirname(logPath);
@@ -1902,11 +1907,6 @@ async function getClientInfo(request) {
1902
1907
  setCache(port, info);
1903
1908
  return info;
1904
1909
  }
1905
- initLogger().then(() => {
1906
- logger.info("Proxy handler initialized");
1907
- }).catch((err) => {
1908
- console.error("[handler] Logger initialization failed:", err);
1909
- });
1910
1910
  function buildProxyHeaders(originalHeaders) {
1911
1911
  const rawHeaders = {};
1912
1912
  const headers = new Headers();
@@ -1975,10 +1975,11 @@ function parseRequestPath(req, url) {
1975
1975
  };
1976
1976
  }
1977
1977
  function buildUpstreamUrl$1(upstreamBase, normalizedPath) {
1978
- if (upstreamBase.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
1979
- return upstreamBase + normalizedPath.slice(3);
1978
+ const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
1979
+ if (base.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
1980
+ return base + normalizedPath.slice(3);
1980
1981
  }
1981
- return upstreamBase + normalizedPath;
1982
+ return base + normalizedPath;
1982
1983
  }
1983
1984
  function selectUpstreamBase$1(isChatCompletions, matchedProviderConfig) {
1984
1985
  let upstreamBase;
@@ -2253,6 +2254,7 @@ const Route$a = createFileRoute("/api/logs")({
2253
2254
  }
2254
2255
  }
2255
2256
  });
2257
+ logger.debug("Health endpoint loaded");
2256
2258
  const Route$9 = createFileRoute("/api/health")({
2257
2259
  server: {
2258
2260
  handlers: {
@@ -2529,7 +2531,7 @@ function truncateErrorDetails(details) {
2529
2531
  }
2530
2532
  return details.slice(0, MAX_ERROR_DETAILS_LENGTH) + "...";
2531
2533
  }
2532
- function createErrorResult(error, latencyMs, streaming, responseStatus, requestHeaders) {
2534
+ function createErrorResult(error, latencyMs, streaming, responseStatus) {
2533
2535
  const { type, details } = classifyError(error, responseStatus);
2534
2536
  return {
2535
2537
  success: false,
@@ -2540,8 +2542,7 @@ function createErrorResult(error, latencyMs, streaming, responseStatus, requestH
2540
2542
  hint: ERROR_HINTS[type]
2541
2543
  },
2542
2544
  latencyMs,
2543
- streaming,
2544
- requestHeaders
2545
+ streaming
2545
2546
  };
2546
2547
  }
2547
2548
  function getErrorMessage(type) {
@@ -2618,8 +2619,7 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2618
2619
  `HTTP ${response.status}: ${response.statusText}`,
2619
2620
  latencyMs,
2620
2621
  false,
2621
- response.status,
2622
- requestHeaders
2622
+ response.status
2623
2623
  );
2624
2624
  }
2625
2625
  const responseText = await response.text();
@@ -2676,7 +2676,7 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2676
2676
  }
2677
2677
  } catch (err) {
2678
2678
  clearTimeout(timeoutId);
2679
- return createErrorResult(err, Date.now() - startTime, false, void 0, requestHeaders);
2679
+ return createErrorResult(err, Date.now() - startTime, false);
2680
2680
  }
2681
2681
  }
2682
2682
  async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
@@ -2708,8 +2708,7 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2708
2708
  `HTTP ${response.status}: ${response.statusText}`,
2709
2709
  latencyMs,
2710
2710
  true,
2711
- response.status,
2712
- requestHeaders
2711
+ response.status
2713
2712
  );
2714
2713
  }
2715
2714
  const chunks = [];
@@ -2737,9 +2736,7 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2737
2736
  return createErrorResult(
2738
2737
  "Response too large (exceeded 10MB limit)",
2739
2738
  Date.now() - startTime,
2740
- true,
2741
- void 0,
2742
- requestHeaders
2739
+ true
2743
2740
  );
2744
2741
  }
2745
2742
  const decoded = decoder.decode(value, { stream: true });
@@ -2751,13 +2748,7 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2751
2748
  chunks.push(finalChunk);
2752
2749
  }
2753
2750
  } catch (readErr) {
2754
- return createErrorResult(
2755
- `Stream read error: ${readErr}`,
2756
- latencyMs,
2757
- true,
2758
- void 0,
2759
- requestHeaders
2760
- );
2751
+ return createErrorResult(`Stream read error: ${readErr}`, latencyMs, true);
2761
2752
  }
2762
2753
  const fullResponse = chunks.join("");
2763
2754
  const mockLog = {
@@ -2841,7 +2832,7 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
2841
2832
  }
2842
2833
  } catch (err) {
2843
2834
  clearTimeout(timeoutId);
2844
- return createErrorResult(err, Date.now() - startTime, true, void 0, requestHeaders);
2835
+ return createErrorResult(err, Date.now() - startTime, true);
2845
2836
  }
2846
2837
  }
2847
2838
  function createTestLogEntry(providerName, path2, body, upstreamUrl, result, isTest) {
@@ -3095,7 +3086,8 @@ function getHostFromUrl(urlStr) {
3095
3086
  }
3096
3087
  }
3097
3088
  function buildUpstreamUrl(upstreamBase, apiPath) {
3098
- return upstreamBase + apiPath;
3089
+ const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
3090
+ return base + apiPath;
3099
3091
  }
3100
3092
  function selectUpstreamBase(isChatCompletions, matchedProviderConfig) {
3101
3093
  let upstreamBase;
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-GVpFMVGE.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-BmEH5jeO.js"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.import.ts" }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts" } }, "clientEntry": "/assets/main-GVpFMVGE.js" });
1
+ const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-CFcacdP3.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-NbnUMVAa.js"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.import.ts" }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts" } }, "clientEntry": "/assets/main-CFcacdP3.js" });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };
@@ -100,51 +100,51 @@ const assets = {
100
100
  "/assets/index-DdJSLfxK.css": {
101
101
  "type": "text/css; charset=utf-8",
102
102
  "etag": '"10da0-LYeZ5d/vwqh4bAnuP/9hr6Wka6g"',
103
- "mtime": "2026-06-04T06:33:11.914Z",
103
+ "mtime": "2026-06-04T06:56:43.363Z",
104
104
  "size": 69024,
105
105
  "path": "../public/assets/index-DdJSLfxK.css"
106
106
  },
107
- "/assets/alibaba-TTwafVwX.svg": {
108
- "type": "image/svg+xml",
109
- "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
110
- "mtime": "2026-06-04T06:33:11.914Z",
111
- "size": 5915,
112
- "path": "../public/assets/alibaba-TTwafVwX.svg"
113
- },
114
- "/assets/qwen-CONDcHqt.png": {
115
- "type": "image/png",
116
- "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
117
- "mtime": "2026-06-04T06:33:11.914Z",
118
- "size": 357059,
119
- "path": "../public/assets/qwen-CONDcHqt.png"
120
- },
121
107
  "/assets/minimax-BPMzvuL-.jpeg": {
122
108
  "type": "image/jpeg",
123
109
  "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
124
- "mtime": "2026-06-04T06:33:11.914Z",
110
+ "mtime": "2026-06-04T06:56:43.363Z",
125
111
  "size": 6918,
126
112
  "path": "../public/assets/minimax-BPMzvuL-.jpeg"
127
113
  },
128
- "/assets/main-GVpFMVGE.js": {
114
+ "/assets/alibaba-TTwafVwX.svg": {
115
+ "type": "image/svg+xml",
116
+ "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
117
+ "mtime": "2026-06-04T06:56:43.363Z",
118
+ "size": 5915,
119
+ "path": "../public/assets/alibaba-TTwafVwX.svg"
120
+ },
121
+ "/assets/main-CFcacdP3.js": {
129
122
  "type": "text/javascript; charset=utf-8",
130
- "etag": '"50591-hoJGkyrSE5hjQqC3+NP6Sje9YUs"',
131
- "mtime": "2026-06-04T06:33:11.914Z",
123
+ "etag": '"50591-xV9jHelZVNe5dRZSUrkbygQ5bnk"',
124
+ "mtime": "2026-06-04T06:56:43.363Z",
132
125
  "size": 329105,
133
- "path": "../public/assets/main-GVpFMVGE.js"
126
+ "path": "../public/assets/main-CFcacdP3.js"
134
127
  },
135
128
  "/assets/zhipuai-BPNAnxo-.svg": {
136
129
  "type": "image/svg+xml",
137
130
  "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
138
- "mtime": "2026-06-04T06:33:11.914Z",
131
+ "mtime": "2026-06-04T06:56:43.360Z",
139
132
  "size": 11256,
140
133
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
141
134
  },
142
- "/assets/index-BmEH5jeO.js": {
135
+ "/assets/qwen-CONDcHqt.png": {
136
+ "type": "image/png",
137
+ "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
138
+ "mtime": "2026-06-04T06:56:43.363Z",
139
+ "size": 357059,
140
+ "path": "../public/assets/qwen-CONDcHqt.png"
141
+ },
142
+ "/assets/index-NbnUMVAa.js": {
143
143
  "type": "text/javascript; charset=utf-8",
144
- "etag": '"84a50-Thjv3JmUhqN6aR4NbGQypCxkmgY"',
145
- "mtime": "2026-06-04T06:33:11.914Z",
144
+ "etag": '"84a50-VkcXEmNQ1EKgZ5X7sUio4tEehG0"',
145
+ "mtime": "2026-06-04T06:56:43.363Z",
146
146
  "size": 543312,
147
- "path": "../public/assets/index-BmEH5jeO.js"
147
+ "path": "../public/assets/index-NbnUMVAa.js"
148
148
  }
149
149
  };
150
150
  function readAsset(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/llm-inspector",
3
- "version": "1.9.1",
3
+ "version": "1.9.3",
4
4
  "type": "module",
5
5
  "description": "LLM API proxy inspector — captures and displays requests/responses from AI coding tools in a web UI",
6
6
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import { createLog, emitLogUpdate, type CapturedLog } from "./store";
2
- import { appendLogEntry, initLogger, logger } from "./logger";
2
+ import { appendLogEntry, logger } from "./logger";
3
3
  import { writeChunks } from "./chunkStorage";
4
4
  import { extractModelFromBody, type RequestFormat } from "./schemas";
5
5
  import { registry } from "./formats";
@@ -28,16 +28,6 @@ import {
28
28
  STATUS_BAD_GATEWAY,
29
29
  } from "./constants";
30
30
 
31
- // Initialize logger at startup
32
- initLogger()
33
- .then(() => {
34
- logger.info("Proxy handler initialized");
35
- })
36
- .catch((err) => {
37
- // eslint-disable-next-line no-console
38
- console.error("[handler] Logger initialization failed:", err);
39
- });
40
-
41
31
  /**
42
32
  * Strips all custom/non-standard headers from the request and replaces with
43
33
  * unified proxy identity. Only preserves standard HTTP headers needed for API calls.
@@ -138,12 +128,14 @@ function parseRequestPath(req: Request, url: URL): ParsedRequestPath {
138
128
  }
139
129
 
140
130
  function buildUpstreamUrl(upstreamBase: string, normalizedPath: string): string {
131
+ // Remove trailing slash from upstreamBase to avoid double slashes
132
+ const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
141
133
  // Handle case where upstreamBase already ends with /v1 and normalizedPath starts with /v1/
142
134
  // to avoid double /v1/v1/ duplication
143
- if (upstreamBase.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
144
- return upstreamBase + normalizedPath.slice(3); // Remove leading /v1 from path
135
+ if (base.endsWith("/v1") && normalizedPath.startsWith("/v1/")) {
136
+ return base + normalizedPath.slice(3); // Remove leading /v1 from path
145
137
  }
146
- return upstreamBase + normalizedPath;
138
+ return base + normalizedPath;
147
139
  }
148
140
 
149
141
  function selectUpstreamBase(
@@ -71,7 +71,15 @@ export async function initLogger(): Promise<void> {
71
71
  }
72
72
 
73
73
  // File-based logger for application logs (not log entries)
74
+ let loggerInitialized = false;
75
+
74
76
  async function writeAppLog(message: string): Promise<void> {
77
+ // Auto-initialize on first use if not already initialized
78
+ if (!loggerInitialized) {
79
+ loggerInitialized = true;
80
+ void initLogger();
81
+ }
82
+
75
83
  try {
76
84
  const logPath = getInspectorLogPath();
77
85
  const logDirPath = path.dirname(logPath);
@@ -1,4 +1,8 @@
1
1
  import { createFileRoute } from "@tanstack/react-router";
2
+ import { logger } from "../../proxy/logger";
3
+
4
+ // Trigger logger auto-initialization when this module loads
5
+ logger.debug("Health endpoint loaded");
2
6
 
3
7
  export const Route = createFileRoute("/api/health")({
4
8
  server: {
@@ -55,7 +55,9 @@ function getHostFromUrl(urlStr: string): string {
55
55
  }
56
56
 
57
57
  function buildUpstreamUrl(upstreamBase: string, apiPath: string): string {
58
- return upstreamBase + apiPath;
58
+ // Remove trailing slash from upstreamBase to avoid double slashes
59
+ const base = upstreamBase.endsWith("/") ? upstreamBase.slice(0, -1) : upstreamBase;
60
+ return base + apiPath;
59
61
  }
60
62
 
61
63
  function selectUpstreamBase(