micro-models-agent 2.21.0 → 2.22.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.
- package/CHANGELOG.md +13 -0
- package/dist/assets/app.js +1 -1
- package/dist/assets/js/feed/sidebar.js +1 -1
- package/dist/main.js +166 -166
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to Micro Models Agent (MMA) will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [2.22.0] - 2026-10-06
|
|
8
|
+
|
|
9
|
+
Web sidebar metrics are no longer frozen until a turn ends, and the cache cell no
|
|
10
|
+
longer shows a misleading `0%` on backends that do not report prompt caching.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Live context metrics** (`src/modules/webui/session/run-agent.ts`, `host-state.ts`, `assets/app.ts`): while a turn runs the runner reads the live `ContextManager` snapshot every ~800ms and broadcasts a new `usage` SSE event for the owning session. The sidebar context bar/legend, compaction count and quality now update in real time instead of only at `turn_end`; the client merges it into the tab without a full state re-fetch.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Cache hit-rate on non-reporting backends** (`src/core/agent/cache-stats.ts`, `src/core/agent.ts`, `types.ts`, `src/cli/cache-line.ts`): `hitRate` is now emitted only when the provider actually returned cache tokens. Previously the prefix monitor always supplied `stableRatio`, so `buildCacheStats` fabricated `hitRate: 0` and the web sidebar showed `0%` (and JSON/CLI consumers saw a false miss) on providers without prompt caching; it now renders `—`.
|
|
19
|
+
|
|
7
20
|
## [2.21.0] - 2026-10-06
|
|
8
21
|
|
|
9
22
|
Additive hardening on top of 2.20.0: deterministic grounding for stated figures,
|
package/dist/assets/app.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{msgs as U,inp as m,connStatus as
|
|
1
|
+
import{msgs as U,inp as m,connStatus as L,setIcon as x,icon as T}from"./js/dom.js";import{api as W,token as k}from"./js/api.js";import{I18N as j,t as a,loadI18n as F}from"./js/i18n.js";import{tabs as u,session as o,settings as f,hooks as h}from"./js/store.js";import{onText as z,onReasoning as D,onMeta as J,onPhase as Q,onToolStart as X,onToolEnd as G,onTurnEnd as K,onErrorEvent as V,onCommandOutput as Y,onLog as Z,onPlan as $,onQuestion as ee,onRetract as te,showEmptyFeed as S,renderPlan as ne,renderUsage as w,renderEnvironment as se,renderWorkspace as oe,feedHasContent as ie,loadHistory as ae}from"./js/feed.js";import{openTab as C,updateTabName as re,renderSessionsDropdown as A,reflectBusy as q,loadSessions as _,loadCommands as de,setTabStatus as p,reconcileTabStatuses as R}from"./js/session/tabs.js";import{renderSelectors as I,renderSettings as ce,loadConfig as le,loadModels as ue,loadProviders as fe,loadMemory as be,loadSkills as pe,loadPlugins as ge,applyTheme as me,currentTheme as he,applyFontSize as Se,setConnStatus as v,setStaleBar as B}from"./js/settings.js";import{initRail as we,setPlan as P,railEvent as Ie,applyRailI18n as ve}from"./js/rail.js";import{initSidebar as ye,sidebarSessionChanged as Ee,sidebarMapState as Le,sidebarTraceEvent as y,sidebarTurnEnd as xe,sidebarBusy as N,sidebarMapIndicator as Te,sidebarPullLog as ke,sidebarSessionId as Ce,setSessionLoading as Ae,sidebarLspState as qe,sidebarLspEvent as _e,applySidebarI18n as M}from"./js/sidebar.js";document.querySelectorAll("[data-collapse]").forEach(n=>{const s=n.querySelector(".arrow");s&&(s.textContent="",s.appendChild(T("chevron-down"))),n.addEventListener("click",()=>{const r=n.nextElementSibling;if(!r)return;const i=r.classList.toggle("collapsed");n.setAttribute("aria-expanded",i?"false":"true");const d=n.querySelector(".arrow");d&&(d.textContent="",d.appendChild(T(i?"chevron-right":"chevron-down")))})});const g=document.getElementById("toggleSidebar");g&&(g.addEventListener("click",()=>{const n=document.body.classList.toggle("sb-open");g.setAttribute("aria-expanded",n?"true":"false")}),document.addEventListener("keydown",n=>{if(n.key!=="Escape"||!document.body.classList.contains("sb-open"))return;const s=document.activeElement?String(document.activeElement.tagName):"";s==="TEXTAREA"||s==="INPUT"||(document.body.classList.remove("sb-open"),g.setAttribute("aria-expanded","false"))}));function H(n,s,r){o.host=n||{},o.busy=!!s,o.runningSessionId=r&&r.runningSessionId||null,o.runningSessionIds=r&&r.runningSessionIds||(o.runningSessionId?[o.runningSessionId]:[]),o.queued=r&&r.queued||{},q(),R();const i=o.host.sessionId||null;o.activeSessionId=i,i&&!u.tabs.some(d=>d.id===i)&&C(i,o.host.sessionName||String(i),"session",!1),i&&re(i,o.host.sessionName),u.tabs.length||S(),ne(o.host.plan),P(s&&n?n.plan:null),w(o.host),n&&typeof n.contextWindow=="number"&&f.config&&f.config.contextWindow!==n.contextWindow&&(f.config.contextWindow=n.contextWindow,I()),se(o.host),Le(o.host),Te(o.host),qe(),Ee(i),oe(o.host),A(),Ae(!1),B(!!(n&&n.i18nStale))}async function b(){const n=u.activeTabId,s=n?"/api/state?session="+encodeURIComponent(n):"/api/state",r=await W(s);!r.ok||!r.data||u.activeTabId===n&&H(r.data.state||{},r.data.busy,r.data)}h.applyState=H,h.refreshState=b;function Re(){b();const n=u.tabs.find(s=>s.id===u.activeTabId);n&&n.kind==="session"&&!ie(n.feed)&&(n.historyLoaded=!1,ae(n))}function Be(){const n="/events"+(k?"?token="+encodeURIComponent(k):""),s=new EventSource(n);let r=!1;s.onopen=()=>{r&&(r=!1,v(!1),Re())},s.onerror=e=>{e&&typeof e.data=="string"||(r=!0,v(!0))};const i=e=>{try{return JSON.parse(e.data)}catch{return null}},d=e=>!e.sessionId||e.sessionId===Ce(),c=[["text",e=>z(e.chunk||"",e.sessionId)],["meta",e=>J(e.chunk||"",e.sessionId,e.kind)],["reasoning",e=>D(e.chunk||"",e.sessionId)],["phase",e=>Q(e.phase,e.sessionId)],["tool_start",X],["tool_end",G],["plan",$],["question",ee],["turn_end",e=>{K(e),d(e)&&(xe(e.turnSeq),N(!1),ke())}],["log",Z],["retract",e=>te(e.reason||"",e.sessionId)]];for(const[e,t]of c)s.addEventListener(e,l=>{const E=i(l);E&&t(E)});for(const e of["tool_start","tool_end","text","plan"])s.addEventListener(e,t=>{const l=i(t);l&&(e==="plan"?P(l):Ie(e,l.name))});for(const e of["text","reasoning","phase","tool_start","plan"])s.addEventListener(e,t=>{const l=i(t);l&&l.sessionId&&p(l.sessionId,"working")});s.addEventListener("question",e=>{const t=i(e);t&&t.sessionId&&p(t.sessionId,"waiting")}),s.addEventListener("turn_end",e=>{const t=i(e);t&&t.sessionId&&p(t.sessionId,t.success===!1?"failed":"idle")});for(const e of["tool_start","tool_end","phase","plan","question","meta","log","retract","index"])s.addEventListener(e,t=>{const l=i(t);l&&d(l)&&y(e,l)});s.addEventListener("text",e=>{const t=i(e);t&&d(t)&&y("text",t)}),s.addEventListener("lsp",e=>{const t=i(e);t&&_e(t)}),s.addEventListener("command",e=>{const t=i(e);t&&typeof t.text=="string"&&Y(t.text,t.sessionId)}),s.addEventListener("state",e=>{const t=i(e);t&&(o.busy=!!t.busy,o.runningSessionId=t.runningSessionId||null,o.runningSessionIds=t.runningSessionIds||(o.runningSessionId?[o.runningSessionId]:[]),o.queued=t.queued||{},q(),R(),N(!!t.busy),b(),t.usage&&typeof t.usage=="object"&&(t.usageSessionId==null||t.usageSessionId===o.activeSessionId)&&(o.host=Object.assign({},o.host,t.usage),w(o.host)))}),s.addEventListener("usage",e=>{const t=i(e);t&&t.usage&&typeof t.usage=="object"&&(t.usageSessionId==null||t.usageSessionId===o.activeSessionId)&&(o.host=Object.assign({},o.host,t.usage),w(o.host))}),s.addEventListener("error",e=>{if(!e.data)return;const t=i(e);t&&(t.sessionId&&p(t.sessionId,"failed"),V(t),y("error",t))})}function O(){document.documentElement.lang=j.locale;const n=(d,c)=>{const e=document.getElementById(d);e&&(e.textContent=c)};n("planHeaderLabel",a("web.sidebar.plan")),n("usageHeaderLabel",a("web.sidebar.session")+" · "+a("web.sidebar.usage")),n("envHeaderLabel",a("web.sidebar.env")),n("settingsTitle",a("web.settings.title")),n("sessActiveHeader",a("web.sessions.active")),n("sessRecentHeader",a("web.sessions.recent")),n("hintEnter",a("web.input.enter")),n("hintShift",a("web.input.shift_enter")),n("hintEsc",a("web.input.esc")),n("hintAttach",a("web.input.attach"));const s={newChat:["plus",a("web.topbar.new_chat")],sessBtn:["menu",a("web.topbar.all_sessions")],toggleSidebar:["panel",a("web.topbar.sidebar")],openSettings:["settings",a("web.topbar.settings")],attachBtn:["image",a("web.attach.title")],closeSettings:["x",a("web.topbar.close")],sessNew:["plus",a("web.sessions.new")],sessRefresh:["refresh",a("web.sessions.refresh")],sessPrev:["chevron-left",a("web.sessbar.prev")],sessNext:["chevron-right",a("web.sessbar.next")],sessClose:["x",a("web.topbar.close")]};Object.keys(s).forEach(d=>{const c=document.getElementById(d);if(!c)return;const[e,t]=s[d];x(c,e,d==="closeSettings"||d==="sessNew"||d==="sessRefresh"?t:null),c.title=t,c.setAttribute("aria-label",t)});const r=document.getElementById("settingsIcon");r&&x(r,"settings",null),m&&(m.placeholder=a("web.input.placeholder"),m.setAttribute("aria-label",a("web.input.placeholder"))),document.querySelectorAll("#setMenu .mi").forEach(d=>{const c=d.dataset.p;c&&(d.textContent=a("web.settings."+c))});const i=document.getElementById("setSearch");i&&(i.setAttribute("placeholder",a("web.settings.search_placeholder")),i.setAttribute("aria-label",a("web.settings.search_placeholder"))),document.querySelectorAll(".content-col .panel").forEach(d=>{const c=d.querySelector("h3"),e=d.id.replace(/^p-/,"");c&&e&&(c.textContent=a("web.settings."+e))}),I(),A(),ve(),M(),U.querySelector(".empty")&&S(),L&&!L.hidden&&v(!0),B(void 0,!0)}async function Pe(){const n=new URLSearchParams(location.search).get("session");if(window.MmaSetup)try{if(await window.MmaSetup.maybeOpen())return}catch{}await F(),await de(),me(he()),Se(),O(),S(),I(),ce(),await le(),we(f.config&&f.config.ui?f.config.ui.activityRail:void 0),ye(),M(),await ue(),await fe(),await _(),await be(),await pe(),await ge();try{await b()}catch(s){console.error("initial refresh failed",s)}if(n){const s=o.sessions.find(r=>r.id===n);s&&C(n,s.name||String(n),"session",!0)}Be(),setInterval(()=>{b().catch(s=>console.error("refresh failed",s))},2e3),setInterval(()=>{_()},15e3)}h.applyStaticI18n=O,Pe();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{usageEl as
|
|
1
|
+
import{usageEl as p,envEl as x,wsLine as m,el as s,icon as v,attachTooltip as k}from"../dom.js";import{I18N as S,t as a,pluralCount as y}from"../i18n.js";import{feed as g,settings as E}from"../store.js";import{fmtTokens as b}from"../format.js";import{copyText as L}from"../../md.js";function f(e,o,n){const t=s("div","kv");return t.appendChild(s("span","",e)),t.appendChild(s("b",n||"",o)),t}function _(e){return[["seg-system","web.usage.part_system",e.system],["seg-tools","web.usage.part_tools",e.tools],["seg-history","web.usage.part_history",e.history],["seg-reserve","web.usage.part_reserve",e.reserve],["seg-free","web.usage.part_free",e.free]]}function M(e,o,n,t){const i=document.createDocumentFragment();return i.appendChild(s("i","ctip-dot "+e)),i.appendChild(s("span","ctip-label",a(o))),i.appendChild(s("b","",b(n))),i.appendChild(s("span","ctip-pct",Math.round(n/t*100)+"%")),i}const U=new Map;function A(e,o,n){const t=U.get(o);if(U.set(o,n),t===void 0||t===n){e.style.flexGrow=String(n);return}e.style.flexGrow=String(t);const i=()=>{e.style.flexGrow=String(n)};typeof requestAnimationFrame=="function"?requestAnimationFrame(i):i()}function I(e,o,n){const t=s("div","bar segbar"),i=e.contextBreakdown;if(!i||typeof i.window!="number"||i.window<=0){const d=s("i");return d.style.flex="0 0 "+Math.min(100,Math.round(o/n*100))+"%",t.appendChild(d),t}const r=Math.max(i.window,i.used+i.reserve);for(const[d,l,c]of _(i)){if(!c||c<=0)continue;const u=s("i",d);u.style.flexBasis="0",A(u,d,c),u.tabIndex=0,u.setAttribute("aria-label",[a(l),b(c),Math.round(c/r*100)+"%"].join(" · ")),k(u,()=>M(d,l,c,r)),t.appendChild(u)}return t}function R(e){const o=s("div","seglegend"),n=e.contextBreakdown;if(!n)return o;const t=Math.max(n.window,n.used+n.reserve);for(const[i,r,d]of _(n)){if(!d||d<=0)continue;const l=s("span","segl-item");l.tabIndex=0,l.setAttribute("aria-label",[a(r),b(d),Math.round(d/t*100)+"%"].join(" · ")),l.appendChild(s("i","segl-dot "+i)),l.appendChild(s("span","segl-label",a(r))),l.appendChild(s("b","",b(d))),k(l,()=>M(i,r,d,t)),o.appendChild(l)}return o}function T(e){const o=s("div","kv");o.appendChild(s("span","",a("web.usage.session")));const n=s("span","kv-val");if(!e)n.appendChild(s("b","","—"));else{n.appendChild(s("b","",e));const t=s("button","copy-btn");t.type="button",t.title=a("web.usage.copy_id"),t.setAttribute("aria-label",a("web.usage.copy_id")),t.appendChild(v("copy")),t.addEventListener("click",()=>{L(e).then(i=>{t.replaceChildren(v(i?"check":"copy")),setTimeout(()=>t.replaceChildren(v("copy")),1500)})}),n.appendChild(t)}return o.appendChild(n),o}export function renderUsage(e){const o=E.config||{},n=JSON.stringify([e.sessionId,e.model,e.contextUsed,e.contextLimit,e.cacheHitRate,e.costUsd,e.compactionCount,e.contextQuality,e.contextProbe,e.contextBreakdown,o.model,o.contextWindow,S.locale]);if(n===g.lastUsageSig)return;g.lastUsageSig=n,p.textContent="";const t=e.sessionId?String(e.sessionId):"";p.appendChild(T(t)),p.appendChild(f(a("web.usage.model"),e.model||o.model||"—"));const i=typeof e.contextUsed=="number"?e.contextUsed:null,r=typeof e.contextLimit=="number"?e.contextLimit:o.contextWindow||null;p.appendChild(f(a("web.usage.context"),i!=null&&r?b(i)+" / "+b(r):"—")),i!=null&&r&&(p.appendChild(I(e,i,r)),p.appendChild(R(e)));const d=typeof e.cacheHitRate=="number"?e.cacheHitRate:null;p.appendChild(f(a("web.usage.cache"),d!=null?Math.round(d*100)+"%":"—",d!=null?"":"dim")),p.appendChild(f(a("web.usage.cost"),typeof e.costUsd=="number"?"$"+e.costUsd.toFixed(4):"—")),p.appendChild(f(a("web.usage.compactions"),"⟳ "+(e.compactionCount||0),e.compactionCount?"wn":"dim"));const l=typeof e.contextQuality=="number"?e.contextQuality:null;p.appendChild(f(a("web.usage.quality"),l!=null?Math.round(l)+"%":"—",l!=null?"":"dim"));let c="—",u="dim";const w=e.contextProbe;if(w&&typeof w.actual=="number"){const h=b(w.actual),C=e.contextLimit||o.contextWindow||null;C&&w.actual<C?(c=a("web.usage.probe_low",{actual:h,configured:b(C)}),u="wn"):(c=a("web.usage.probe_loaded",{actual:h}),u="")}p.appendChild(f(a("web.usage.probe"),c,u))}export function renderWorkspace(e){const o=e.workspace||"";if(m.dataset.ws===o||(m.dataset.ws=o,m.textContent="",m.hidden=!o,!o))return;m.appendChild(s("span","ws-k",a("web.env.dir")));const n=s("span","ws-v",o);n.title=o,m.appendChild(n)}function B(e,o){const n=s("div","env-item");return n.appendChild(s("div","env-k",e)),o.forEach(t=>{const i=s("div","env-v",t);i.title=t,n.appendChild(i)}),n}export function renderEnvironment(e){const o=!!(e.instructions&&e.instructions.disabled),n=e.instructions&&!o?e.instructions.files||[]:[],t=e.projectMap||null,i=JSON.stringify([o,n,t,S.locale]);i!==g.lastEnvSig&&(g.lastEnvSig=i,x.textContent="",x.appendChild(B(a("web.env.agents"),o?[a("web.env.agents_disabled")]:n.length?n:[a("web.env.agents_none")])),x.appendChild(B(a("web.env.map"),t&&t.indexed?[[y("web.env.files",t.files),y("web.env.symbols",t.symbols),y("web.env.tokens",t.tokens)].join(" · ")]:[a("web.env.map_not_indexed")])))}
|