From a822c497c57af3c8b7a57c743bca2b2eb98be598 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 13 Mar 2026 11:59:41 -0600 Subject: [PATCH] fix: correct dashboard JS field mappings for benchmark API The /api/benchmark response uses total_admitted, total_rejected, total_attempts etc. but the dashboard JS was reading admitted, rejected, attempts. Also fixed fidelity bar reading fidelity_distribution key and the session table to derive context reduction from byte ratio. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/mnemosyne/gateway.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/mnemosyne/gateway.py b/src/mnemosyne/gateway.py index 2bd9dd2..a7d08b4 100644 --- a/src/mnemosyne/gateway.py +++ b/src/mnemosyne/gateway.py @@ -634,8 +634,8 @@ d.nextElementSibling.setAttribute('opacity','.4');$('stip').style.display='none' function updateBars(mem){ const levels=['L0','L1','L2','L3','L4'],counts=[0,0,0,0,0]; const ss=mem&&mem.sessions?mem.sessions:{}; -for(const s of Object.values(ss)){const bf=s.objects_by_fidelity||{}; -levels.forEach((l,i)=>{counts[i]+=bf[l]||bf[i]||bf['l'+i]||0})} +for(const s of Object.values(ss)){const bf=s.fidelity_distribution||s.objects_by_fidelity||{}; +levels.forEach((l,i)=>{counts[i]+=bf[l]||bf[i]||bf[String(i)]||bf['l'+i]||0})} const mx=Math.max(...counts,1); levels.forEach((l,i)=>{$('f'+i).style.width=(counts[i]/mx*100)+'%';$('fv'+i).textContent=F(counts[i])})} @@ -668,32 +668,36 @@ const memS=memory.sessions||{};let tObj=0; for(const s of Object.values(memS))tObj+=s.total_objects||0; $('k-obj').textContent=F(tObj); $('k-deg').textContent=F(fid.total_degradations||0); -const aY=adm.admitted||0,aN=adm.rejected||0,aT=aY+aN; +const aY=adm.total_admitted||adm.admitted||0,aN=adm.total_rejected||adm.rejected||0,aT=aY+aN; const aPct=aT>0?aY/aT*100:0; $('ring').style.strokeDashoffset=201.06-(aPct/100*201.06); $('rpct').textContent=aT>0?P(aPct,0)+'%':'\\u2014'; $('a-y').textContent=F(aY);$('a-n').textContent=F(aN); -$('mf-a').textContent=F(mf.attempts||0);$('mf-s').textContent=F(mf.successes||0); -$('mf-t').textContent=F(mf.tokens_saved||0); -const mfR=(mf.attempts||0)>0?((mf.successes||0)/mf.attempts*100):0; +const mfA=mf.total_attempts||mf.attempts||0,mfS=mf.total_successes||mf.successes||0,mfT=mf.total_tokens_saved||mf.tokens_saved||0; +$('mf-a').textContent=F(mfA);$('mf-s').textContent=F(mfS); +$('mf-t').textContent=F(mfT); +const mfR=mfA>0?(mfS/mfA*100):0; $('mf-r').textContent=mfR>0?P(mfR,1)+'%':'\\u2014'; -$('l-a').textContent=lat.avg_ms!=null?P(lat.avg_ms,1):'\\u2014'; -$('l-i').textContent=lat.min_ms!=null?P(lat.min_ms,1):'\\u2014'; -$('l-x').textContent=lat.max_ms!=null?P(lat.max_ms,1):'\\u2014'; -$('l-p').textContent=lat.p95_ms!=null?P(lat.p95_ms,1):'\\u2014'; +const eL=lat.embedding||{},sL=lat.segmentation||{},gL=lat.goal_classification||{}; +const avgLat=(eL.avg_ms||0)+(sL.avg_ms||0); +$('l-a').textContent=avgLat>0?P(avgLat,1):'\\u2014'; +$('l-i').textContent=sL.min_ms!=null&&sL.min_ms>0?P(sL.min_ms,1):eL.min_ms!=null?P(eL.min_ms,1):'\\u2014'; +$('l-x').textContent=eL.max_ms!=null?P(eL.max_ms+( sL.max_ms||0),1):'\\u2014'; +$('l-p').textContent=gL.avg_ms!=null?P(gL.avg_ms,1):'\\u2014'; updateBars(memory); const ev=eventsResp.events||[]; const req=ev.filter(e=>e.type==='request_metrics'); renderSpark(req.slice(-80).map(r=>Number(r.shrink_ratio||1))); renderEvents(ev); -const hs=health.sessions||{}; const tbody=$('sessions');tbody.innerHTML=''; sEntries.sort((a,b)=>(b[1].request_count||0)-(a[1].request_count||0)); for(const[sid,s]of sEntries){ -const h=hs[sid]||{},m=memS[sid]||{}; -const sE=h.evictions||0,sF=h.faults||0,sFR=sE>0?(sF/sE*100).toFixed(1)+'%':'\\u2014'; +const m=memS[sid]||{}; +const fd=m.fidelity_distribution||{};const topL=Object.keys(fd).sort().pop(); +const shrink=s.incoming_bytes>0?(1-s.outgoing_bytes/s.incoming_bytes)*100:0; +const sE=0,sF=0,sFR='\\u2014'; const tr=document.createElement('tr'); -tr.innerHTML=''+(sid.length>18?sid.slice(0,18)+'\\u2026':sid)+''+F(s.request_count)+''+F(m.total_objects||0)+''+(m.fidelity_level!=null?'L'+m.fidelity_level:'\\u2014')+''+(s.context_reduction?P(s.context_reduction,1)+'%':'\\u2014')+''+F(sE)+''+F(sF)+''+sFR+''+F(s.incoming_bytes)+''+F(s.outgoing_bytes)+''; +tr.innerHTML=''+(sid.length>18?sid.slice(0,18)+'\\u2026':sid)+''+F(s.request_count)+''+F(m.total_objects||0)+''+(topL!=null?'L'+topL:'\\u2014')+''+(shrink>0.01?P(shrink,1)+'%':'\\u2014')+''+F(sE)+''+F(sF)+''+sFR+''+F(s.incoming_bytes)+''+F(s.outgoing_bytes)+''; tbody.appendChild(tr)}} load().catch(e=>{$('sd').className='dot';$('meta').textContent='error: '+e}); setInterval(()=>load().catch(()=>{}),2500);