micro-models-agent 2.18.2 → 2.19.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 CHANGED
@@ -4,6 +4,39 @@ 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
+ ## [Unreleased]
8
+
9
+ ### Fixed
10
+
11
+ - **Compaction progress threshold** (`src/core/agent/compaction.ts`, `src/modules/context/manager.ts`): the significance threshold is now `max(2% history budget, 3% current context)` instead of 2% of the history budget alone, so a marginal shrink (e.g. −1.2% on a 24K context) no longer counts as success and short-circuits stage escalation — it now escalates to `aggressive`/`hard-drop`. `compactAdaptive` reports `reducedBy` as the total reduction from the original context (previously measured incrementally between stages, which could understate real progress to 0). An overflow attempt now consumes the iteration even when it is a no-op, keeping the "one trigger per iteration" guarantee.
12
+
13
+ ## [2.19.0] - 2026-10-05
14
+
15
+ Harness hardening from the live-session post-mortem (`ses_muu8kfbw_nyxkre`): false
16
+ compaction and lost working context, plan/step desync, broken `grep` on Windows,
17
+ background-process leaks. Harness fixes only (no model/task-specific tuning).
18
+
19
+ ### Added
20
+
21
+ - **Context calibration** (`src/core/agent/context-calibration.ts`): the token estimate is calibrated against real provider `prompt_tokens` (baseline+delta, EMA fallback, floor-ratio against silent provider truncation, shadow warmup, stale fallback). `ContextManager.getContextTokens()` is the single input for compaction thresholds; `getEstimatedTokens()` stays raw for cost/prefix/critic. New diagnostic fields (`estimatedTokensRaw`, `contextTokens`, `calibrationRatio`, `calibrationState`) in the `context` session event.
22
+ - **Safety-clamp** (`isImplausibleJump`): an implausible estimate jump (>3× and >20K tokens without message growth) no longer triggers overflow compaction.
23
+ - **Compaction policy v2** (`contextBudget.policy: legacy|v2`, default `v2`): canonical `history` threshold, overflow cooldown, progress guarantee (prune old tool results → aggressive trim → hard drop), pinned task/plan, one trigger per iteration, and reactive compaction on a provider context-length error (circuit-broken once per turn). `legacy` reproduces 2.18.2.
24
+ - **Plan ownership**: `execution.autoAdvance` (default true); auto-archived plans now archive at the turn boundary (not mid-turn) and the model gets an explicit notice; `plan.no_active` reports the last completed plan; plan `checks` are optional and self-certify (`manual:<step>`) when omitted.
25
+ - **Tool portability**: zero-dependency JS `grep` fallback (rg → grep → built-in walker respecting `.gitignore`/`.mmaignore`, size/time/maxFiles limits) with `tools.grepEngine: auto|rg|grep|js`; generic bash redirect for a registered tool invoked as a shell command and a generic `--cwd` → `workdir` hint; `ProcessRegistry` dedups identical running background commands (`force: true` to bypass).
26
+ - **Weak-model UX**: `ToolResult.errorMeta` (`code`/`retryable`/`hint`) delivered to the model without leaking into the chat; fuzzy top-3 `load_skill` suggestions; empty web message returns a localized no-op instead of a hard error.
27
+ - New config keys (registry + i18n en/ru): `contextBudget.policy`, `contextBudget.overflowCooldown`, `contextBudget.toolResultKeep`, `contextBudget.calibrationWarmup`, `contextBudget.ratioFloor`, `execution.autoAdvance`, `tools.grepEngine`.
28
+
29
+ ### Changed
30
+
31
+ - **Compaction** thresholds now use the calibrated estimate; `legacy` policy keeps raw behaviour.
32
+ - **Plan auto-archive** moved from the auto-advance mutation to `onTurnEnd` (web/REPL turns no longer see "no active plan" mid-work).
33
+
34
+ ### Fixed
35
+
36
+ - **Token-estimate cache** (`src/modules/context/manager.ts`): the per-message cache is now keyed by a content signature, so an in-place mutation cannot return a stale estimate (root-cause class of the phantom +44K jump).
37
+ - **`grep` on Windows** no longer fails with `Executable not found in $PATH: "grep"` — the built-in walker runs when neither `rg` nor `grep` exists.
38
+ - **Cost hidden for `deepseek-v4.1-flash`** (`src/modules/pricing/prices.ts`): the Zen/Go price table had `deepseek-v4-flash`/`deepseek-v4-pro` but not `deepseek-v4.1-flash`, so `resolvePrice` returned `undefined` and no cost was shown for the model the `opencode-go` provider remembers. Added the entry and corrected the stale DeepSeek prices/cached-read rates to the current Go off-peak table.
39
+
7
40
  ## [2.18.2] - 2026-10-04
8
41
 
9
42
  ### Fixed
@@ -1 +1 @@
1
- import{inp as o,imgPicker as g,attachStrip as E,attachErr as B,sendBtn as p,el as u,icon as _}from"../dom.js";import{api as I}from"../api.js";import{t as c}from"../i18n.js";import{tabs as i,session as f,settings as v,MAX_IMAGES as k,MAX_IMAGE_BYTES as z}from"../store.js";import{contextLabel as W}from"../format.js";import{clearEmpty as N,activeFeed as Y,liveFeed as j,appendTo as y,scrollToBottom as P,clearFeed as J,finishMd as Q,resetTurnText as V,finishThink as Z,showBusy as $}from"../feed.js";import{setBusy as ee}from"../rail.js";import"../core/menus.js";import{openSessionsMenu as te}from"./sessions-menu.js";import{closeCmdk as F,updateCmdk as ne,cmdkKeydown as se,initCmdk as ae}from"./cmdk.js";let r={activeTab:()=>null,setTabStatus:()=>{},newChatTab:async()=>{},markTabDead:()=>{},openTab:()=>{},closeTab:()=>{},statusTitle:()=>""};export function initComposer(e){r={...r,...e}}ae({autogrow:C});const ie=200;function C(){o&&(o.style.height="auto",o.style.height=Math.min(o.scrollHeight,ie)+"px")}function oe(e){B&&(B.textContent=e,B.hidden=!1,clearTimeout(i.attachErrTimer),i.attachErrTimer=setTimeout(()=>{B.hidden=!0},4e3))}export function renderAttachments(){if(!E)return;E.textContent="",E.hidden=i.attachments.length===0,i.attachments.forEach((t,n)=>{const s=u("div","thumb"),a=document.createElement("img");a.alt="",a.src=t,s.appendChild(a);const d=u("button","rm");d.type="button",d.title=c("web.attach.remove"),d.setAttribute("aria-label",c("web.attach.remove")),d.appendChild(_("x")),d.addEventListener("click",()=>{i.attachments.splice(n,1),renderAttachments()}),s.appendChild(d),E.appendChild(s)});const e=r.activeTab();e&&(e.attachments=i.attachments.slice())}function re(e){return new Promise((t,n)=>{const s=new FileReader;s.onload=()=>t(String(s.result)),s.onerror=()=>n(s.error||new Error("read failed")),s.readAsDataURL(e)})}async function S(e){let t="";for(const n of e){if(!n||typeof n.type!="string"||n.type.indexOf("image/")!==0){t=c("web.attach.only_images");continue}if(i.attachments.length>=k){t=c("web.attach.too_many",{max:k});break}if(n.size>z){t=c("web.attach.too_large");continue}try{const s=await re(n);if(s.indexOf("data:image/")!==0){t=c("web.attach.invalid");continue}if(i.attachments.length>=k){t=c("web.attach.too_many",{max:k});break}i.attachments.push(s)}catch{t=c("web.attach.read_failed")}}renderAttachments(),t&&oe(t)}function ce(e,t){const n=u("div","u",e);return(t||[]).forEach(s=>{const a=document.createElement("img");a.className="uimg",a.alt="",a.src=s,n.appendChild(a)}),n}export function saveComposer(){const e=r.activeTab();!e||!o||(e.draft=o.value,e.attachments=i.attachments.slice())}export function restoreComposer(e){!e||!o||(o.value=e.draft||"",i.attachments=(e.attachments||[]).slice(),renderAttachments(),C(),F())}const de=document.getElementById("sessBar"),x=document.getElementById("sessNameBtn"),le=document.getElementById("sessName"),L=document.getElementById("sessPrev"),A=document.getElementById("sessNext"),D=document.getElementById("sessClose"),O=document.getElementById("sessTools"),q=document.getElementById("sessDD"),T=document.querySelector(".bar-top"),w=document.getElementById("newChat"),M=document.createComment("top-tools");T&&w&&T.insertBefore(M,w);function X(e){if(i.tabs.length<2)return;const t=i.tabs.findIndex(a=>a.id===i.activeTabId),n=t===-1?0:(t+e+i.tabs.length)%i.tabs.length,s=i.tabs[n];s&&r.openTab(s.id,s.name,s.kind,!0)}export function renderSessBar(){if(!de)return;const e=i.tabs.find(s=>s.id===i.activeTabId),t=e?e.name||String(e.id):"—";le.textContent=t,x.title=t+(e&&e.status&&e.status!=="idle"?" · "+r.statusTitle(e.status):"");const n=i.tabs.length>0;L.disabled=i.tabs.length<2,A.disabled=i.tabs.length<2,D.disabled=!n,x.disabled=!n}function U(){!T||!O||!w||!q||(window.matchMedia("(max-width: 760px)").matches?O.append(w,q):(T.insertBefore(w,M),T.insertBefore(q,M)))}if(L&&L.addEventListener("click",()=>X(-1)),A&&A.addEventListener("click",()=>X(1)),D&&D.addEventListener("click",()=>{i.activeTabId&&r.closeTab(i.activeTabId)}),x&&x.addEventListener("click",e=>{e.stopPropagation(),te()}),typeof window.matchMedia=="function"){const e=window.matchMedia("(max-width: 760px)");typeof e.addEventListener=="function"&&e.addEventListener("change",U),U()}g&&g.addEventListener("change",()=>{S(Array.from(g.files||[])),g.value=""});const G=document.getElementById("attachBtn");G&&g&&G.addEventListener("click",()=>g.click()),o.addEventListener("paste",e=>{const t=e.clipboardData&&e.clipboardData.items;if(!t)return;const n=[];for(const s of t)if(s.kind==="file"&&s.type&&s.type.indexOf("image/")===0){const a=s.getAsFile();a&&n.push(a)}n.length&&(e.preventDefault(),S(n))});const h=document.querySelector(".input-area");h&&(["dragenter","dragover"].forEach(e=>{h.addEventListener(e,t=>{t.preventDefault(),h.classList.add("dragover")})}),h.addEventListener("dragleave",e=>{const t=e;t.relatedTarget&&h.contains(t.relatedTarget)||h.classList.remove("dragover")}),h.addEventListener("drop",e=>{e.preventDefault(),h.classList.remove("dragover");const t=e.dataTransfer;t&&t.files&&t.files.length&&S(Array.from(t.files))}));function H(){o.value="",C(),F()}o&&o.addEventListener("input",()=>{const e=r.activeTab();e&&(e.draft=o.value),C(),ne()});async function K(){const e=o.value.trim(),t=i.attachments.slice();if(!e&&!t.length)return;const n=r.activeTab(),s=n&&n.kind==="session"?n.id:null,a=j()||Y();if(n&&n.dead){N(a),r.markTabDead(n.id);return}if(N(a),Q(),V(),Z(),e.startsWith("/")){y(a,u("div","u",e)),P(),n&&(n.draft="",n.attachments=[]),i.attachments=[],renderAttachments(),H();const l=e.slice(1).split(/\s+/)[0].toLowerCase();if(l==="clear"){J(a);return}if(l==="new"){r.newChatTab();return}const b={line:e};s&&(b.sessionId=s),(await I("/api/command",{method:"POST",body:b})).ok||y(a,u("div","detail","↳ "+c("web.misc.command_unavailable")));return}if(a&&a.querySelector(".startbanner")===null&&a.querySelector(".u")===null){const l=u("div","startbanner");l.appendChild(document.createTextNode(c("web.start.label")+" ")),l.appendChild(u("b","",v.config&&v.config.model||f.host.model||"—"));const b=f.host.sessionId?" · "+c("web.start.session")+" "+String(f.host.sessionId):"";l.appendChild(document.createTextNode(" · "+(f.host.provider||v.config&&v.config.provider&&v.config.provider.active||"—")+" · "+W()+b)),a.insertBefore(l,a.firstChild)}y(a,ce(e,t)),P(),n&&(n.draft="",n.attachments=[]),i.attachments=[],renderAttachments(),H(),s&&r.setTabStatus(s,"working");const d={text:e};t.length&&(d.images=t),s&&(d.sessionId=s);const m=await I("/api/message",{method:"POST",body:d});if(m.ok)if(m.data&&m.data.queued){const l=m.data.queuedForSession||m.data.queued;y(a,u("div","detail","↳ "+c("web.input.queued",{n:l}))),s&&r.setTabStatus(s,"queued")}else window.setTimeout(()=>$(a),180);else{const l=m.data&&m.data.error||m.status,b=l==="queue_full"?c("web.input.queue_full"):l;y(a,u("div","warnline","⚠ "+b)),s&&r.setTabStatus(s,"failed")}}async function R(){const e=r.activeTab(),t=e&&e.kind==="session"?e.id:null,n=f.runningSessionIds||[];t&&!n.includes(t)||!t&&!f.busy||await I("/api/interrupt",{method:"POST",body:t?{sessionId:t}:{}})}o.addEventListener("keydown",e=>{e.isComposing||e.keyCode===229||se(e)||(e.key==="Enter"&&!e.shiftKey?(e.preventDefault(),K()):e.key==="Escape"&&(e.preventDefault(),R()))}),p&&p.addEventListener("click",()=>{const e=r.activeTab();e&&e.kind==="session"&&f.runningSessionIds.includes(e.id)?R():K()});export function reflectBusy(){const e=r.activeTab(),t=f.runningSessionIds||[],n=!!(e&&e.kind==="session"&&t.includes(e.id));o&&o.setAttribute("aria-busy",n?"true":"false");const s=document.querySelector(".input-area");if(s&&s.classList.toggle("busy",n),p){const d=n?c("web.input.stop"):c("web.input.send");p.textContent="",p.appendChild(_(n?"square":"arrow-up")),p.classList.toggle("busy",n),p.title=d,p.setAttribute("aria-label",d)}const a=document.getElementById("hintEsc");a&&(a.hidden=!n),ee(f.busy)}
1
+ import{inp as o,imgPicker as g,attachStrip as E,attachErr as B,sendBtn as p,el as f,icon as _}from"../dom.js";import{api as I}from"../api.js";import{t as d}from"../i18n.js";import{tabs as i,session as m,settings as y,MAX_IMAGES as k,MAX_IMAGE_BYTES as z}from"../store.js";import{contextLabel as W}from"../format.js";import{clearEmpty as N,activeFeed as Y,liveFeed as j,appendTo as v,scrollToBottom as P,clearFeed as J,finishMd as Q,resetTurnText as V,finishThink as Z,showBusy as $}from"../feed.js";import{setBusy as tt}from"../rail.js";import"../core/menus.js";import{openSessionsMenu as et}from"./sessions-menu.js";import{closeCmdk as F,updateCmdk as nt,cmdkKeydown as st,initCmdk as at}from"./cmdk.js";let r={activeTab:()=>null,setTabStatus:()=>{},newChatTab:async()=>{},markTabDead:()=>{},openTab:()=>{},closeTab:()=>{},statusTitle:()=>""};export function initComposer(t){r={...r,...t}}at({autogrow:C});const it=200;function C(){o&&(o.style.height="auto",o.style.height=Math.min(o.scrollHeight,it)+"px")}function ot(t){B&&(B.textContent=t,B.hidden=!1,clearTimeout(i.attachErrTimer),i.attachErrTimer=setTimeout(()=>{B.hidden=!0},4e3))}export function renderAttachments(){if(!E)return;E.textContent="",E.hidden=i.attachments.length===0,i.attachments.forEach((e,n)=>{const s=f("div","thumb"),a=document.createElement("img");a.alt="",a.src=e,s.appendChild(a);const c=f("button","rm");c.type="button",c.title=d("web.attach.remove"),c.setAttribute("aria-label",d("web.attach.remove")),c.appendChild(_("x")),c.addEventListener("click",()=>{i.attachments.splice(n,1),renderAttachments()}),s.appendChild(c),E.appendChild(s)});const t=r.activeTab();t&&(t.attachments=i.attachments.slice())}function rt(t){return new Promise((e,n)=>{const s=new FileReader;s.onload=()=>e(String(s.result)),s.onerror=()=>n(s.error||new Error("read failed")),s.readAsDataURL(t)})}async function S(t){let e="";for(const n of t){if(!n||typeof n.type!="string"||n.type.indexOf("image/")!==0){e=d("web.attach.only_images");continue}if(i.attachments.length>=k){e=d("web.attach.too_many",{max:k});break}if(n.size>z){e=d("web.attach.too_large");continue}try{const s=await rt(n);if(s.indexOf("data:image/")!==0){e=d("web.attach.invalid");continue}if(i.attachments.length>=k){e=d("web.attach.too_many",{max:k});break}i.attachments.push(s)}catch{e=d("web.attach.read_failed")}}renderAttachments(),e&&ot(e)}function dt(t,e){const n=f("div","u",t);return(e||[]).forEach(s=>{const a=document.createElement("img");a.className="uimg",a.alt="",a.src=s,n.appendChild(a)}),n}export function saveComposer(){const t=r.activeTab();!t||!o||(t.draft=o.value,t.attachments=i.attachments.slice())}export function restoreComposer(t){!t||!o||(o.value=t.draft||"",i.attachments=(t.attachments||[]).slice(),renderAttachments(),C(),F())}const ct=document.getElementById("sessBar"),x=document.getElementById("sessNameBtn"),lt=document.getElementById("sessName"),L=document.getElementById("sessPrev"),A=document.getElementById("sessNext"),D=document.getElementById("sessClose"),O=document.getElementById("sessTools"),q=document.getElementById("sessDD"),T=document.querySelector(".bar-top"),w=document.getElementById("newChat"),M=document.createComment("top-tools");T&&w&&T.insertBefore(M,w);function X(t){if(i.tabs.length<2)return;const e=i.tabs.findIndex(a=>a.id===i.activeTabId),n=e===-1?0:(e+t+i.tabs.length)%i.tabs.length,s=i.tabs[n];s&&r.openTab(s.id,s.name,s.kind,!0)}export function renderSessBar(){if(!ct)return;const t=i.tabs.find(s=>s.id===i.activeTabId),e=t?t.name||String(t.id):"—";lt.textContent=e,x.title=e+(t&&t.status&&t.status!=="idle"?" · "+r.statusTitle(t.status):"");const n=i.tabs.length>0;L.disabled=i.tabs.length<2,A.disabled=i.tabs.length<2,D.disabled=!n,x.disabled=!n}function U(){!T||!O||!w||!q||(window.matchMedia("(max-width: 760px)").matches?O.append(w,q):(T.insertBefore(w,M),T.insertBefore(q,M)))}if(L&&L.addEventListener("click",()=>X(-1)),A&&A.addEventListener("click",()=>X(1)),D&&D.addEventListener("click",()=>{i.activeTabId&&r.closeTab(i.activeTabId)}),x&&x.addEventListener("click",t=>{t.stopPropagation(),et()}),typeof window.matchMedia=="function"){const t=window.matchMedia("(max-width: 760px)");typeof t.addEventListener=="function"&&t.addEventListener("change",U),U()}g&&g.addEventListener("change",()=>{S(Array.from(g.files||[])),g.value=""});const G=document.getElementById("attachBtn");G&&g&&G.addEventListener("click",()=>g.click()),o.addEventListener("paste",t=>{const e=t.clipboardData&&t.clipboardData.items;if(!e)return;const n=[];for(const s of e)if(s.kind==="file"&&s.type&&s.type.indexOf("image/")===0){const a=s.getAsFile();a&&n.push(a)}n.length&&(t.preventDefault(),S(n))});const h=document.querySelector(".input-area");h&&(["dragenter","dragover"].forEach(t=>{h.addEventListener(t,e=>{e.preventDefault(),h.classList.add("dragover")})}),h.addEventListener("dragleave",t=>{const e=t;e.relatedTarget&&h.contains(e.relatedTarget)||h.classList.remove("dragover")}),h.addEventListener("drop",t=>{t.preventDefault(),h.classList.remove("dragover");const e=t.dataTransfer;e&&e.files&&e.files.length&&S(Array.from(e.files))}));function H(){o.value="",C(),F()}o&&o.addEventListener("input",()=>{const t=r.activeTab();t&&(t.draft=o.value),C(),nt()});async function K(){const t=o.value.trim(),e=i.attachments.slice();if(!t&&!e.length)return;const n=r.activeTab(),s=n&&n.kind==="session"?n.id:null,a=j()||Y();if(n&&n.dead){N(a),r.markTabDead(n.id);return}if(N(a),Q(),V(),Z(),t.startsWith("/")){v(a,f("div","u",t)),P(),n&&(n.draft="",n.attachments=[]),i.attachments=[],renderAttachments(),H();const u=t.slice(1).split(/\s+/)[0].toLowerCase();if(u==="clear"){J(a);return}if(u==="new"){r.newChatTab();return}const b={line:t};s&&(b.sessionId=s),(await I("/api/command",{method:"POST",body:b})).ok||v(a,f("div","detail","↳ "+d("web.misc.command_unavailable")));return}if(a&&a.querySelector(".startbanner")===null&&a.querySelector(".u")===null){const u=f("div","startbanner");u.appendChild(document.createTextNode(d("web.start.label")+" ")),u.appendChild(f("b","",y.config&&y.config.model||m.host.model||"—"));const b=m.host.sessionId?" · "+d("web.start.session")+" "+String(m.host.sessionId):"";u.appendChild(document.createTextNode(" · "+(m.host.provider||y.config&&y.config.provider&&y.config.provider.active||"—")+" · "+W()+b)),a.insertBefore(u,a.firstChild)}v(a,dt(t,e)),P(),n&&(n.draft="",n.attachments=[]),i.attachments=[],renderAttachments(),H(),s&&r.setTabStatus(s,"working");const c={text:t};e.length&&(c.images=e),s&&(c.sessionId=s);const l=await I("/api/message",{method:"POST",body:c});if(l.ok)if(l.data&&l.data.noop)l.data.notice&&v(a,f("div","detail",String(l.data.notice)));else if(l.data&&l.data.queued){const u=l.data.queuedForSession||l.data.queued;v(a,f("div","detail","↳ "+d("web.input.queued",{n:u}))),s&&r.setTabStatus(s,"queued")}else window.setTimeout(()=>$(a),180);else{const u=l.data&&l.data.error||l.status,b=u==="queue_full"?d("web.input.queue_full"):u;v(a,f("div","warnline","⚠ "+b)),s&&r.setTabStatus(s,"failed")}}async function R(){const t=r.activeTab(),e=t&&t.kind==="session"?t.id:null,n=m.runningSessionIds||[];e&&!n.includes(e)||!e&&!m.busy||await I("/api/interrupt",{method:"POST",body:e?{sessionId:e}:{}})}o.addEventListener("keydown",t=>{t.isComposing||t.keyCode===229||st(t)||(t.key==="Enter"&&!t.shiftKey?(t.preventDefault(),K()):t.key==="Escape"&&(t.preventDefault(),R()))}),p&&p.addEventListener("click",()=>{const t=r.activeTab();t&&t.kind==="session"&&m.runningSessionIds.includes(t.id)?R():K()});export function reflectBusy(){const t=r.activeTab(),e=m.runningSessionIds||[],n=!!(t&&t.kind==="session"&&e.includes(t.id));o&&o.setAttribute("aria-busy",n?"true":"false");const s=document.querySelector(".input-area");if(s&&s.classList.toggle("busy",n),p){const c=n?d("web.input.stop"):d("web.input.send");p.textContent="",p.appendChild(_(n?"square":"arrow-up")),p.classList.toggle("busy",n),p.title=c,p.setAttribute("aria-label",c)}const a=document.getElementById("hintEsc");a&&(a.hidden=!n),tt(m.busy)}
@@ -1 +1 @@
1
- import{el as c,makeToggle as y}from"../dom.js";import{tagsEditor as u,checkboxEditor as g,tableEditor as b}from"./editors.js";export function validateJson(i){const e=String(i??"").trim();if(!e)return{ok:!1,error:"required"};try{return JSON.parse(e),{ok:!0}}catch(t){return{ok:!1,error:t instanceof Error?t.message:"invalid JSON"}}}function l(i,e){const t=c("input");return t.setAttribute("aria-label",i),t.value=e,t}export function controlFor(i,e,t){if(i.readOnly){const s=c("span","val dim",e==null?"—":String(e));return e!=null&&(s.title=String(e)),s}if(i.valueType==="bool")return y(!!e,s=>(t.post(s),!0));if(i.valueType==="enum"){const s=c("select");return s.setAttribute("aria-label",t.label),(i.enum||[]).forEach(n=>{const o=c("option","",t.enumLabel(n));o.value=n,n===e&&(o.selected=!0),s.appendChild(o)}),s.addEventListener("change",()=>t.post(s.value)),s}if(i.valueType==="int"){const s=l(t.label,e==null?"":String(e));return s.type="number",i.min!=null&&(s.min=String(i.min)),i.max!=null&&(s.max=String(i.max)),i.step!=null&&(s.step=String(i.step)),s.addEventListener("change",()=>t.post(s.value)),s}if(i.valueType==="share"){const s=l(t.label,e==null?"":Math.round(Number(e)*100)+"%");return s.addEventListener("change",()=>t.post(s.value)),s}const r=i.editor;if(r&&r.kind==="tags"&&(i.valueType==="list"||i.valueType==="json"))return u(e,t,r);if(r&&r.kind==="checkboxes")return g(e,t,r);if(r&&r.kind==="table")return b(e,t,r);if(i.valueType==="list"){const s=Array.isArray(e)?e.join(", "):e==null?"":String(e),n=l(t.label,s);return n.placeholder="a, b, c",n.addEventListener("change",()=>t.post(n.value)),n}if(i.valueType==="json"){const s=c("div","jsonctl"),n=c("textarea");n.setAttribute("aria-label",t.label),n.rows=3,n.value=e==null?"":JSON.stringify(e,null,2);const o=c("div","json-err");return o.hidden=!0,n.addEventListener("input",()=>{const d=validateJson(n.value);o.hidden=d.ok,o.textContent=d.ok?"":String(d.error||"invalid JSON")}),n.addEventListener("change",()=>{validateJson(n.value).ok?t.post(n.value.trim()):n.focus()}),s.appendChild(n),s.appendChild(o),s}const a=l(t.label,e==null?"":String(e));return a.addEventListener("change",()=>t.post(a.value)),a}export const PANEL_SECTIONS={general:[{id:"general.interface",titleKey:"web.settings.sec.general.interface",keys:["locale","ui.verbosity"]},{id:"general.agent",titleKey:"web.settings.sec.general.agent",descKey:"web.settings.sec.general.agent.desc",keys:["maxToolIterations","stuckThreshold","autoPlan"]},{id:"general.provider",titleKey:"web.settings.sec.general.provider",keys:["provider.fallback"]}],model:[{id:"model.tuning",titleKey:"web.settings.sec.model.tuning",descKey:"web.settings.sec.model.tuning.desc",keys:["provider.maxCompletionTokens","modelLoad.autoLoad","modelLoad.flashAttention","modelLoad.evalBatchSize","modelLoad.offloadKvCacheToGpu"]},{id:"model.capabilities",titleKey:"web.settings.sec.model.capabilities",descKey:"web.settings.sec.model.capabilities.desc",keys:["modelCapabilities"]}],context:[{id:"context.window",titleKey:"web.settings.sec.context.window",descKey:"web.settings.sec.context.window.desc",keys:["contextWindow","contextBudget.systemPrompt","contextBudget.responseReserve"]},{id:"context.compaction",titleKey:"web.settings.sec.context.compaction",descKey:"web.settings.sec.context.compaction.desc",keys:["contextBudget.compactionThreshold","contextBudget.compactionMinLoad"]},{id:"context.instructions",titleKey:"web.settings.sec.context.instructions",descKey:"web.settings.sec.context.instructions.desc",keys:["instructions.summarize"]},{id:"context.indexer",titleKey:"web.settings.sec.context.indexer",descKey:"web.settings.sec.context.indexer.desc",keys:["indexer.maxFiles","indexer.respectGitignore","indexer.mapTokenBudget"]},{id:"context.log",titleKey:"web.settings.sec.context.log",descKey:"web.settings.sec.context.log.desc",keys:["contextLog.enabled","contextLog.redact"]}],reasoning:[{id:"reasoning.display",titleKey:"web.settings.sec.reasoning.display",keys:["showReasoning"]},{id:"reasoning.effort",titleKey:"web.settings.sec.reasoning.effort",descKey:"web.settings.sec.reasoning.effort.desc",keys:["reasoning.mode","reasoning.min","reasoning.max","reasoning.baseline","reasoning.overrideCooldown"]}],agent:[{id:"agent.moe",titleKey:"web.settings.sec.agent.moe",descKey:"web.settings.sec.agent.moe.desc",keys:["moe.enabled","moe.maxReplanCycles","experts"]},{id:"agent.critic",titleKey:"web.settings.sec.agent.critic",descKey:"web.settings.sec.agent.critic.desc",keys:["critic.enabled","critic.model","critic.provider","critic.tools","critic.maxCalls","critic.maxRepairCycles","critic.timeoutMs"]},{id:"agent.tools",titleKey:"web.settings.sec.agent.tools",descKey:"web.settings.sec.agent.tools.desc",keys:["tools.enableOnDemand","tools.defaultTags","skills.budget"]},{id:"agent.subagent",titleKey:"web.settings.sec.agent.subagent",descKey:"web.settings.sec.agent.subagent.desc",keys:["subagent.resultMode","subagent.maxSummaryChars","subagent.maxParallelChunkQueries","subagent.stableSystemPrompt"]},{id:"agent.hallucination",titleKey:"web.settings.sec.agent.hallucination",descKey:"web.settings.sec.agent.hallucination.desc",keys:["hallucination.judge.enabled"]}],network:[{id:"network.web",titleKey:"web.settings.sec.network.web",descKey:"web.settings.sec.network.web.desc",keys:["webSearch.enabled"]},{id:"network.error",titleKey:"web.settings.sec.network.error",descKey:"web.settings.sec.network.error.desc",keys:["errorWebSearch.enabled","errorWebSearch.threshold","errorWebSearch.maxResults","errorWebSearch.maxQueryChars","errorWebSearch.maxSearchesPerSession","errorWebSearch.requestTimeoutMs"]}],browser:[{id:"browser.main",titleKey:"web.settings.sec.browser.main",keys:["browser.enabled","browser.headless"]},{id:"browser.limits",titleKey:"web.settings.sec.browser.limits",descKey:"web.settings.sec.browser.limits.desc",keys:["browser.maxElements","browser.maxContentChars","browser.maxConsoleEntries","browser.maxConsoleLineChars"]},{id:"browser.viewport",titleKey:"web.settings.sec.browser.viewport",keys:["browser.viewportWidth","browser.viewportHeight","browser.navigationTimeout"]}],sessions:[{id:"sessions.main",titleKey:"web.settings.sec.sessions.main",descKey:"web.settings.sec.sessions.main.desc",keys:["session.autoSave","session.autoName","session.maxSessions","session.isolateMemory"]},{id:"sessions.isolation",titleKey:"web.settings.sec.sessions.isolation",descKey:"web.settings.sec.sessions.isolation.desc",keys:["sessionIsolation.enabled","sessionIsolation.isolatePlugins","sessionIsolation.isolateTempFiles"]}],ui:[{id:"ui.chat",titleKey:"web.settings.sec.ui.chat",descKey:"web.settings.sec.ui.chat.desc",keys:["ui.fontSize","ui.activityRail","ui.spinner","ui.showContextStats","ui.showCompaction"]}],security:[{id:"security.switches",titleKey:"web.settings.sec.security.switches",descKey:"web.settings.sec.security.switches.desc",keys:["security.enabled","security.bash.enabled","security.bash.blockDangerousFlags","security.paths.enabled","security.contentScan.enabled","security.network.enabled","security.sessionEncryption.enabled"]},{id:"security.limits",titleKey:"web.settings.sec.security.limits",descKey:"web.settings.sec.security.limits.desc",keys:["security.maxRecursionDepth","security.maxFileOperations","security.rateLimits.maxRequestsPerMinute","security.rateLimits.maxParallelTasks","security.network.requestTimeout","security.network.maxResponseSize"]},{id:"security.bash",titleKey:"web.settings.sec.security.bash",descKey:"web.settings.sec.security.bash.desc",keys:["security.bash.blacklist","security.bash.whitelist","security.bash.dangerousFlags","security.bash.dangerousOperators"]},{id:"security.paths",titleKey:"web.settings.sec.security.paths",descKey:"web.settings.sec.security.paths.desc",keys:["security.paths.denied","security.paths.allowed"]},{id:"security.network",titleKey:"web.settings.sec.security.network",descKey:"web.settings.sec.security.network.desc",keys:["security.network.deniedDomains","security.network.allowedDomains"]},{id:"security.scan",titleKey:"web.settings.sec.security.scan",descKey:"web.settings.sec.security.scan.desc",keys:["security.contentScan.dangerousPatterns"]},{id:"security.audit",titleKey:"web.settings.sec.security.audit",descKey:"web.settings.sec.security.audit.desc",keys:["security.auditNotifier.enabled","security.auditNotifier.filePath","security.auditNotifier.webhookUrl","security.auditNotifier.webhookTimeout","security.auditNotifier.minSeverity","security.auditNotifier.maxRetries","security.auditNotifier.eventTypes"]},{id:"security.encryption",titleKey:"web.settings.sec.security.encryption",descKey:"web.settings.sec.security.encryption.desc",keys:["security.sessionEncryption.encryptHistory","security.sessionEncryption.encryptSessionLog","security.sessionEncryption.keyPath"]}],advanced:[{id:"advanced.diagnostics",titleKey:"web.settings.sec.advanced.diagnostics",descKey:"web.settings.sec.advanced.diagnostics.desc",keys:["logLevel","version"]},{id:"advanced.retry",titleKey:"web.settings.sec.advanced.retry",descKey:"web.settings.sec.advanced.retry.desc",keys:["retry.maxRetries","retry.baseDelay","retry.maxDelay","retry.maxStreamRetries","retry.noDataTimeoutMs"]},{id:"advanced.service",titleKey:"web.settings.sec.advanced.service",descKey:"web.settings.sec.advanced.service.desc",keys:["pricing.enabled","pricing.overrides","updater.enabled","updater.checkOnStart","updater.autoInstall","updater.intervalMs"]}],plugins:[{id:"plugins.lsp",titleKey:"web.settings.sec.plugins.lsp",descKey:"web.settings.sec.plugins.lsp.desc",keys:["lsp.enabled","lsp.offline"]}]};export function keyToPanel(){const i=new Map;for(const[e,t]of Object.entries(PANEL_SECTIONS))for(const r of t)for(const a of r.keys)i.set(a,e);return i}
1
+ import{el as c,makeToggle as y}from"../dom.js";import{tagsEditor as u,checkboxEditor as g,tableEditor as b}from"./editors.js";export function validateJson(i){const e=String(i??"").trim();if(!e)return{ok:!1,error:"required"};try{return JSON.parse(e),{ok:!0}}catch(s){return{ok:!1,error:s instanceof Error?s.message:"invalid JSON"}}}function l(i,e){const s=c("input");return s.setAttribute("aria-label",i),s.value=e,s}export function controlFor(i,e,s){if(i.readOnly){const t=c("span","val dim",e==null?"—":String(e));return e!=null&&(t.title=String(e)),t}if(i.valueType==="bool")return y(!!e,t=>(s.post(t),!0));if(i.valueType==="enum"){const t=c("select");return t.setAttribute("aria-label",s.label),(i.enum||[]).forEach(n=>{const o=c("option","",s.enumLabel(n));o.value=n,n===e&&(o.selected=!0),t.appendChild(o)}),t.addEventListener("change",()=>s.post(t.value)),t}if(i.valueType==="int"){const t=l(s.label,e==null?"":String(e));return t.type="number",i.min!=null&&(t.min=String(i.min)),i.max!=null&&(t.max=String(i.max)),i.step!=null&&(t.step=String(i.step)),t.addEventListener("change",()=>s.post(t.value)),t}if(i.valueType==="share"){const t=l(s.label,e==null?"":Math.round(Number(e)*100)+"%");return t.addEventListener("change",()=>s.post(t.value)),t}const r=i.editor;if(r&&r.kind==="tags"&&(i.valueType==="list"||i.valueType==="json"))return u(e,s,r);if(r&&r.kind==="checkboxes")return g(e,s,r);if(r&&r.kind==="table")return b(e,s,r);if(i.valueType==="list"){const t=Array.isArray(e)?e.join(", "):e==null?"":String(e),n=l(s.label,t);return n.placeholder="a, b, c",n.addEventListener("change",()=>s.post(n.value)),n}if(i.valueType==="json"){const t=c("div","jsonctl"),n=c("textarea");n.setAttribute("aria-label",s.label),n.rows=3,n.value=e==null?"":JSON.stringify(e,null,2);const o=c("div","json-err");return o.hidden=!0,n.addEventListener("input",()=>{const d=validateJson(n.value);o.hidden=d.ok,o.textContent=d.ok?"":String(d.error||"invalid JSON")}),n.addEventListener("change",()=>{validateJson(n.value).ok?s.post(n.value.trim()):n.focus()}),t.appendChild(n),t.appendChild(o),t}const a=l(s.label,e==null?"":String(e));return a.addEventListener("change",()=>s.post(a.value)),a}export const PANEL_SECTIONS={general:[{id:"general.interface",titleKey:"web.settings.sec.general.interface",keys:["locale","ui.verbosity"]},{id:"general.agent",titleKey:"web.settings.sec.general.agent",descKey:"web.settings.sec.general.agent.desc",keys:["maxToolIterations","stuckThreshold","autoPlan","execution.autoAdvance"]},{id:"general.provider",titleKey:"web.settings.sec.general.provider",keys:["provider.fallback"]}],model:[{id:"model.tuning",titleKey:"web.settings.sec.model.tuning",descKey:"web.settings.sec.model.tuning.desc",keys:["provider.maxCompletionTokens","modelLoad.autoLoad","modelLoad.flashAttention","modelLoad.evalBatchSize","modelLoad.offloadKvCacheToGpu"]},{id:"model.capabilities",titleKey:"web.settings.sec.model.capabilities",descKey:"web.settings.sec.model.capabilities.desc",keys:["modelCapabilities"]}],context:[{id:"context.window",titleKey:"web.settings.sec.context.window",descKey:"web.settings.sec.context.window.desc",keys:["contextWindow","contextBudget.systemPrompt","contextBudget.responseReserve"]},{id:"context.compaction",titleKey:"web.settings.sec.context.compaction",descKey:"web.settings.sec.context.compaction.desc",keys:["contextBudget.compactionThreshold","contextBudget.compactionMinLoad","contextBudget.policy","contextBudget.overflowCooldown","contextBudget.toolResultKeep","contextBudget.calibrationWarmup","contextBudget.ratioFloor"]},{id:"context.instructions",titleKey:"web.settings.sec.context.instructions",descKey:"web.settings.sec.context.instructions.desc",keys:["instructions.summarize"]},{id:"context.indexer",titleKey:"web.settings.sec.context.indexer",descKey:"web.settings.sec.context.indexer.desc",keys:["indexer.maxFiles","indexer.respectGitignore","indexer.mapTokenBudget"]},{id:"context.log",titleKey:"web.settings.sec.context.log",descKey:"web.settings.sec.context.log.desc",keys:["contextLog.enabled","contextLog.redact"]}],reasoning:[{id:"reasoning.display",titleKey:"web.settings.sec.reasoning.display",keys:["showReasoning"]},{id:"reasoning.effort",titleKey:"web.settings.sec.reasoning.effort",descKey:"web.settings.sec.reasoning.effort.desc",keys:["reasoning.mode","reasoning.min","reasoning.max","reasoning.baseline","reasoning.overrideCooldown"]}],agent:[{id:"agent.moe",titleKey:"web.settings.sec.agent.moe",descKey:"web.settings.sec.agent.moe.desc",keys:["moe.enabled","moe.maxReplanCycles","experts"]},{id:"agent.critic",titleKey:"web.settings.sec.agent.critic",descKey:"web.settings.sec.agent.critic.desc",keys:["critic.enabled","critic.model","critic.provider","critic.tools","critic.maxCalls","critic.maxRepairCycles","critic.timeoutMs"]},{id:"agent.tools",titleKey:"web.settings.sec.agent.tools",descKey:"web.settings.sec.agent.tools.desc",keys:["tools.enableOnDemand","tools.defaultTags","tools.grepEngine","skills.budget"]},{id:"agent.subagent",titleKey:"web.settings.sec.agent.subagent",descKey:"web.settings.sec.agent.subagent.desc",keys:["subagent.resultMode","subagent.maxSummaryChars","subagent.maxParallelChunkQueries","subagent.stableSystemPrompt"]},{id:"agent.hallucination",titleKey:"web.settings.sec.agent.hallucination",descKey:"web.settings.sec.agent.hallucination.desc",keys:["hallucination.judge.enabled"]}],network:[{id:"network.web",titleKey:"web.settings.sec.network.web",descKey:"web.settings.sec.network.web.desc",keys:["webSearch.enabled"]},{id:"network.error",titleKey:"web.settings.sec.network.error",descKey:"web.settings.sec.network.error.desc",keys:["errorWebSearch.enabled","errorWebSearch.threshold","errorWebSearch.maxResults","errorWebSearch.maxQueryChars","errorWebSearch.maxSearchesPerSession","errorWebSearch.requestTimeoutMs"]}],browser:[{id:"browser.main",titleKey:"web.settings.sec.browser.main",keys:["browser.enabled","browser.headless"]},{id:"browser.limits",titleKey:"web.settings.sec.browser.limits",descKey:"web.settings.sec.browser.limits.desc",keys:["browser.maxElements","browser.maxContentChars","browser.maxConsoleEntries","browser.maxConsoleLineChars"]},{id:"browser.viewport",titleKey:"web.settings.sec.browser.viewport",keys:["browser.viewportWidth","browser.viewportHeight","browser.navigationTimeout"]}],sessions:[{id:"sessions.main",titleKey:"web.settings.sec.sessions.main",descKey:"web.settings.sec.sessions.main.desc",keys:["session.autoSave","session.autoName","session.maxSessions","session.isolateMemory"]},{id:"sessions.isolation",titleKey:"web.settings.sec.sessions.isolation",descKey:"web.settings.sec.sessions.isolation.desc",keys:["sessionIsolation.enabled","sessionIsolation.isolatePlugins","sessionIsolation.isolateTempFiles"]}],ui:[{id:"ui.chat",titleKey:"web.settings.sec.ui.chat",descKey:"web.settings.sec.ui.chat.desc",keys:["ui.fontSize","ui.activityRail","ui.spinner","ui.showContextStats","ui.showCompaction"]}],security:[{id:"security.switches",titleKey:"web.settings.sec.security.switches",descKey:"web.settings.sec.security.switches.desc",keys:["security.enabled","security.bash.enabled","security.bash.blockDangerousFlags","security.paths.enabled","security.contentScan.enabled","security.network.enabled","security.sessionEncryption.enabled"]},{id:"security.limits",titleKey:"web.settings.sec.security.limits",descKey:"web.settings.sec.security.limits.desc",keys:["security.maxRecursionDepth","security.maxFileOperations","security.rateLimits.maxRequestsPerMinute","security.rateLimits.maxParallelTasks","security.network.requestTimeout","security.network.maxResponseSize"]},{id:"security.bash",titleKey:"web.settings.sec.security.bash",descKey:"web.settings.sec.security.bash.desc",keys:["security.bash.blacklist","security.bash.whitelist","security.bash.dangerousFlags","security.bash.dangerousOperators"]},{id:"security.paths",titleKey:"web.settings.sec.security.paths",descKey:"web.settings.sec.security.paths.desc",keys:["security.paths.denied","security.paths.allowed"]},{id:"security.network",titleKey:"web.settings.sec.security.network",descKey:"web.settings.sec.security.network.desc",keys:["security.network.deniedDomains","security.network.allowedDomains"]},{id:"security.scan",titleKey:"web.settings.sec.security.scan",descKey:"web.settings.sec.security.scan.desc",keys:["security.contentScan.dangerousPatterns"]},{id:"security.audit",titleKey:"web.settings.sec.security.audit",descKey:"web.settings.sec.security.audit.desc",keys:["security.auditNotifier.enabled","security.auditNotifier.filePath","security.auditNotifier.webhookUrl","security.auditNotifier.webhookTimeout","security.auditNotifier.minSeverity","security.auditNotifier.maxRetries","security.auditNotifier.eventTypes"]},{id:"security.encryption",titleKey:"web.settings.sec.security.encryption",descKey:"web.settings.sec.security.encryption.desc",keys:["security.sessionEncryption.encryptHistory","security.sessionEncryption.encryptSessionLog","security.sessionEncryption.keyPath"]}],advanced:[{id:"advanced.diagnostics",titleKey:"web.settings.sec.advanced.diagnostics",descKey:"web.settings.sec.advanced.diagnostics.desc",keys:["logLevel","version"]},{id:"advanced.retry",titleKey:"web.settings.sec.advanced.retry",descKey:"web.settings.sec.advanced.retry.desc",keys:["retry.maxRetries","retry.baseDelay","retry.maxDelay","retry.maxStreamRetries","retry.noDataTimeoutMs"]},{id:"advanced.service",titleKey:"web.settings.sec.advanced.service",descKey:"web.settings.sec.advanced.service.desc",keys:["pricing.enabled","pricing.overrides","updater.enabled","updater.checkOnStart","updater.autoInstall","updater.intervalMs"]}],plugins:[{id:"plugins.lsp",titleKey:"web.settings.sec.plugins.lsp",descKey:"web.settings.sec.plugins.lsp.desc",keys:["lsp.enabled","lsp.offline"]}]};export function keyToPanel(){const i=new Map;for(const[e,s]of Object.entries(PANEL_SECTIONS))for(const r of s)for(const a of r.keys)i.set(a,e);return i}