@mutagent/evaluator 0.1.0-alpha.5 → 0.2.0-alpha.1
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/.claude/skills/mutagent-evaluator/SKILL.md +28 -30
- package/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +6 -5
- package/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +93 -30
- package/.claude/skills/mutagent-evaluator/assets/code-quality-criteria.yaml +75 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/discover-report.template.html +397 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/eval-report.template.html +594 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/review-report.template.html +560 -0
- package/.claude/skills/mutagent-evaluator/golden/judge-trajectory.prose.md +69 -0
- package/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +1 -1
- package/.claude/skills/mutagent-evaluator/references/data-registry.md +43 -0
- package/.claude/skills/mutagent-evaluator/references/edd-loop.md +6 -6
- package/.claude/skills/mutagent-evaluator/references/eval-layers.md +52 -0
- package/.claude/skills/mutagent-evaluator/references/eval-stage.md +37 -4
- package/.claude/skills/mutagent-evaluator/references/memory-format.md +1 -1
- package/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
- package/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +254 -9
- package/.claude/skills/mutagent-evaluator/scripts/audience.ts +84 -0
- package/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +320 -6
- package/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +32 -2
- package/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/code-eval-library.ts +201 -0
- package/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +60 -68
- package/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +3 -3
- package/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +101 -39
- package/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +326 -3
- package/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +30 -4
- package/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +8 -0
- package/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +2 -2
- package/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +144 -15
- package/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +130 -68
- package/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +219 -1
- package/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/memory/ratify.ts +165 -0
- package/.claude/skills/mutagent-evaluator/scripts/merge-criteria.ts +849 -0
- package/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +15 -4
- package/.claude/skills/mutagent-evaluator/scripts/read-manifest.ts +120 -0
- package/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +34 -2
- package/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +37 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-discover-report-v3.ts +1155 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-eval-report-v3.ts +610 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +11 -92
- package/.claude/skills/mutagent-evaluator/scripts/render-review-report-v3.ts +691 -0
- package/.claude/skills/mutagent-evaluator/scripts/report-fragments.ts +173 -0
- package/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +12 -9
- package/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +46 -1
- package/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +39 -4
- package/.claude/skills/mutagent-evaluator/scripts/run-review.ts +266 -0
- package/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +82 -0
- package/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +2 -2
- package/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +64 -21
- package/.claude/skills/mutagent-evaluator/scripts/verify-render.ts +728 -0
- package/bin/mutagent-cli.mjs +9 -5
- package/package.json +2 -2
|
@@ -69,6 +69,14 @@ import { assessEmitCompleteness, type EmitCompleteness } from "./emit-completene
|
|
|
69
69
|
import type { Scorecard } from "./evaluate.ts";
|
|
70
70
|
import type { SourceMap } from "./source-map.ts";
|
|
71
71
|
import { routeFailures, type FailureRef, type HandoverBundle } from "./route-failures.ts";
|
|
72
|
+
// EV-3 — the step<->criterion side-by-side render fns (`cvRefs` + `critiqueBlock`
|
|
73
|
+
// + `sideBySide`, the last carrying its local `refExaminesStep` + `covEntry`) are
|
|
74
|
+
// EXTRACTED VERBATIM into report-fragments.ts and spliced back into the client
|
|
75
|
+
// script IN PLACE below, so this report's emitted HTML is byte-identical to
|
|
76
|
+
// before the extraction. The review UI (`build-review-ui.ts`) imports the SAME
|
|
77
|
+
// constant to render the identical view. Byte-identity is guarded by this file's
|
|
78
|
+
// render tests + a before/after HTML diff.
|
|
79
|
+
import { SIDE_BY_SIDE_FRAGMENT_JS } from "./report-fragments.ts";
|
|
72
80
|
|
|
73
81
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
74
82
|
const BRAND_DIR = join(HERE, "..", "assets", "brand");
|
|
@@ -136,7 +144,8 @@ export interface JudgeStep {
|
|
|
136
144
|
/** One target-agent step (the left lane of the §2 side-by-side). */
|
|
137
145
|
export interface AgentStep {
|
|
138
146
|
n: number;
|
|
139
|
-
tool
|
|
147
|
+
/** TOLERANT: explicit `null` = an honest "no tool call this step" (live-judge shape). */
|
|
148
|
+
tool?: string | null;
|
|
140
149
|
/** ok | error | warn | false-success */
|
|
141
150
|
status?: string;
|
|
142
151
|
detail?: string;
|
|
@@ -3319,97 +3328,7 @@ function render(){var qi=document.getElementById('q');if(!qi)return;var q=(qi.va
|
|
|
3319
3328
|
// critique-before-verdict + grounding refs, read off the verdict file's verdicts[].
|
|
3320
3329
|
// Shared by BOTH the side-by-side drill (walk traces) and the per-trajectory
|
|
3321
3330
|
// scorecard drill (no-walk traces) so NO judged trace renders an empty panel.
|
|
3322
|
-
|
|
3323
|
-
return '<div class="cvrefs">'+refs.map(function(rf){var s=(typeof rf==='string')?rf:[rf.obs,rf.path,rf.value].filter(Boolean).join(' · ');return s?'<span class="cvref">'+esc(s)+'</span>':'';}).join('')+'</div>';}
|
|
3324
|
-
function critiqueBlock(cvs){if(!cvs||!cvs.length)return '';
|
|
3325
|
-
var order={fail:0,uncertain:1,indeterminate:1,pass:2,na:3};
|
|
3326
|
-
var rows=cvs.slice().sort(function(a,b){return (order[a.result]==null?9:order[a.result])-(order[b.result]==null?9:order[b.result]);}).map(function(v){
|
|
3327
|
-
var res=v.result||'na';var disp=res==='uncertain'?'indeterminate':res;
|
|
3328
|
-
var conf=(v.confidence!=null)?'<span class="cvconf">conf '+esc(v.confidence)+(v.confidenceBand?' · '+esc(v.confidenceBand):'')+'</span>':'';
|
|
3329
|
-
var crit=v.critique?'<div class="cvcrit">'+esc(v.critique)+'</div>':'<div class="cvcrit dim">— no critique recorded for this criterion</div>';
|
|
3330
|
-
return '<div class="cvrow '+esc(res)+'"><div class="cvh"><span class="cvb '+esc(res)+'">'+esc(disp)+'</span><span class="cvid">'+esc(v.criterionId||'')+'</span>'+conf+'</div>'+crit+cvRefs(v.refs)+'</div>';}).join('');
|
|
3331
|
-
return '<div class="ctx cvblock"><div class="ctx-h">◇ how the judge reasoned — per-criterion verdict · critique-before-verdict · grounding refs ('+cvs.length+')</div><div class="cvbody">'+rows+'</div></div>';}
|
|
3332
|
-
function sideBySide(d){var ctx=d.context||{};
|
|
3333
|
-
// Gap A — the §2 "input + scenario" cell renders the RAW triggering INPUT (the
|
|
3334
|
-
// thing that fired the agent) ABOVE the judge's scenario LABEL. Long inputs
|
|
3335
|
-
// collapse into a <details> (lean, no JS) so the cell stays compact; short ones
|
|
3336
|
-
// render inline (clamped). ABSENT input ⇒ the cell shows the scenario alone (or
|
|
3337
|
-
// "—"). Font stays at the --fs-2xs (11px) floor + brand mono.
|
|
3338
|
-
var inputCell=function(raw,scen){
|
|
3339
|
-
var sc=scen?'<div class="iscn">scenario · '+esc(scen)+'</div>':'';
|
|
3340
|
-
if(!raw)return (scen?'<div class="ival">'+esc(scen)+'</div>':'—');
|
|
3341
|
-
var long=String(raw).length>180;
|
|
3342
|
-
var body=long
|
|
3343
|
-
? '<details class="iexp"><summary>raw input · '+String(raw).length+' chars</summary><pre class="iraw">'+esc(raw)+'</pre></details>'
|
|
3344
|
-
: '<pre class="iraw clamp">'+esc(raw)+'</pre>';
|
|
3345
|
-
return body+sc;};
|
|
3346
|
-
var refStr=function(rf){if(!rf)return '';if(typeof rf==='string')return rf;return [rf.obs,rf.path,rf.value].filter(Boolean).join(':');};
|
|
3347
|
-
// UI-4 — surface the judge's REASONING (why the verdict + why the exit-states were
|
|
3348
|
-
// concluded) from the EXISTING judge walk: an ordered why-chain band + the decide/bind
|
|
3349
|
-
// text inlined where it explains a conclusion. No emit-contract change — read-only over
|
|
3350
|
-
// the judge_steps already on the verdict file.
|
|
3351
|
-
var KORD={gather:0,context:1,examine:2,detect:3,bind:4,ground:5,critique:6,decide:7,verify:8};
|
|
3352
|
-
var allJs=(d.judgeSteps||[]).slice();
|
|
3353
|
-
var stepText=function(kind){return allJs.filter(function(s){return s.kind===kind;}).map(function(s){return s.text||'';}).filter(Boolean).join(' · ');};
|
|
3354
|
-
var decideWhy=stepText('decide')||stepText('critique');
|
|
3355
|
-
var stateWhy=[stepText('bind'),stepText('gather')].filter(Boolean).join(' · ');
|
|
3356
|
-
var chainSteps=allJs.slice().sort(function(a,b){var x=KORD[a.kind];var y=KORD[b.kind];return (x==null?9:x)-(y==null?9:y);});
|
|
3357
|
-
var whyChain=chainSteps.length?('<div class="ctx whychain"><div class="ctx-h">◇ judge reasoning — full why-chain (gather → bind → ground → decide)</div><div class="wc-body">'+chainSteps.map(function(s){var rs=refStr(s.ref);return '<div class="jstep"><span class="k '+esc(s.kind)+'">'+esc(s.kind)+'</span><span class="t">'+esc(s.text||'')+(rs?' <span class=ref>'+esc(rs)+'</span>':'')+'</span></div>';}).join('')+'</div></div>'):'';
|
|
3358
|
-
var verdictWhy=decideWhy?('<div class="band whyverdict"><div class="bh" style="color:var(--primary-soft)">◇ why this verdict</div><div class="wv-t">'+esc(decideWhy)+'</div></div>'):'';
|
|
3359
|
-
// -- §2 judge lane = per-step EVAL COVERAGE --
|
|
3360
|
-
// The judge lane (.step-r) used to filter judgeSteps by anchor === a.n -- but
|
|
3361
|
-
// judges never emit an anchor, so EVERY step rendered a bare dash. Instead we
|
|
3362
|
-
// map each agent step -> the per-criterion verdicts (d.criterionVerdicts) whose
|
|
3363
|
-
// grounding refs EXAMINED that step: a precise ref.obs === step.obs match plus
|
|
3364
|
-
// the tool-name fallback (ref.path === 'name' && ref.value === step.tool).
|
|
3365
|
-
// Each examining criterion renders one compact entry -- result + CODE/JUDGE tag
|
|
3366
|
-
// + criterionId + the judge reasoning (critique). A step no criterion references
|
|
3367
|
-
// says 'not examined by any eval' (honest), never a bare dash. Any judge step
|
|
3368
|
-
// that DOES carry a real anchor is still honored (future-proof).
|
|
3369
|
-
var cvAll=(d.criterionVerdicts||[]);
|
|
3370
|
-
var refExaminesStep=function(rf,a){
|
|
3371
|
-
if(!rf||typeof rf==='string')return false;
|
|
3372
|
-
if(a.obs&&rf.obs&&String(rf.obs)===String(a.obs))return true;
|
|
3373
|
-
if(rf.path==='name'&&rf.value!=null&&a.tool&&String(rf.value)===String(a.tool))return true;
|
|
3374
|
-
return false;};
|
|
3375
|
-
var covEntry=function(v,a){
|
|
3376
|
-
var res=v.result||'na';var disp=res==='uncertain'?'indeterminate':res;
|
|
3377
|
-
// the router carries TWO vocabularies: matrix-derived ('deterministic') and
|
|
3378
|
-
// mined ('code-based'); 'hybrid' is shared. A '[code-eval ...]'-prefixed critique
|
|
3379
|
-
// is the deterministic-logic fallback when the method is unset.
|
|
3380
|
-
var method=((typeof C!=='undefined'&&C[v.criterionId])||{}).m||'';
|
|
3381
|
-
var isCode=method==='deterministic'||method==='code-based'||method==='hybrid'||String(v.critique||'').trim().indexOf('[code-eval')===0;
|
|
3382
|
-
var tag=method==='hybrid'?'HYBRID':(isCode?'CODE':'JUDGE');
|
|
3383
|
-
var matched=(v.refs||[]).filter(function(rf){return typeof rf!=='string'&&refExaminesStep(rf,a);});
|
|
3384
|
-
var crit=v.critique?esc(v.critique):'<span class="dim">— no critique recorded</span>';
|
|
3385
|
-
return '<div class="jcov '+esc(res)+'"><div class="jcov-h"><span class="cvb '+esc(res)+'">'+esc(disp)+'</span><span class="jm '+(isCode?'code':'judge')+'" title="'+(isCode?'deterministically checked by a code-eval (not LLM-judged)':'reasoned by the LLM judge')+'">'+esc(tag)+'</span><span class="jcid">'+esc(v.criterionId||'')+'</span></div><div class="jcrit">'+crit+'</div>'+cvRefs(matched)+'</div>';};
|
|
3386
|
-
var rowsHtml='';(d.agentSteps||[]).forEach(function(a){
|
|
3387
|
-
// future-proof: a judge step that carries a REAL anchor still renders.
|
|
3388
|
-
var js=(d.judgeSteps||[]).filter(function(s){return s.anchor!=null&&String(s.anchor)===String(a.n)&&s.kind!=='context';});
|
|
3389
|
-
var anchoredHtml=js.map(function(s){var rs=refStr(s.ref);return '<div class="jstep"><span class="k '+esc(s.kind)+'">'+esc(s.kind)+'</span><span class="t">'+esc(s.text||'')+' '+(rs?'<span class=ref>'+esc(rs)+'</span>':'')+'</span></div>';}).join('');
|
|
3390
|
-
var examiners=cvAll.filter(function(v){return (v.refs||[]).some(function(rf){return refExaminesStep(rf,a);});});
|
|
3391
|
-
var covHtml=examiners.map(function(v){return covEntry(v,a);}).join('');
|
|
3392
|
-
var jhtml=anchoredHtml+covHtml;
|
|
3393
|
-
if(!jhtml)jhtml='<div class="jstep noexam"><span class="t">— not examined by any eval</span></div>';
|
|
3394
|
-
rowsHtml+='<div class="step-l"><div class="evb"><div class="top"><span class="tool">'+esc(a.tool||'')+'</span><span class="st '+esc(a.status||'')+'">'+esc(a.status||'')+'</span></div><div class="det">'+esc(a.detail||'')+'</div></div></div><div class="node '+esc(a.status||'')+'"><div class="ln"></div><div class="n">'+esc(a.n)+'</div><div class="ln"></div></div><div class="step-r"><div class="evb r">'+jhtml+'</div></div>';});
|
|
3395
|
-
var h=d.health||{};
|
|
3396
|
-
var sp=d.subjectProfile;
|
|
3397
|
-
var spHtml=sp?'<div class="ctx"><div class="ctx-h">◇ judge · subject profile (M1) · '+esc(sp.provenance||'')+'</div><div class="ctx-g"><div class="ctx-c"><div class="l">identity</div><div class="v">'+esc(sp.identity||'—')+'</div></div><div class="ctx-c"><div class="l">purpose</div><div class="v">'+esc(sp.purpose||'—')+'</div></div><div class="ctx-c"><div class="l">scope · harness</div><div class="v">'+esc((sp.scope||'—'))+' · harness: '+esc(sp.harness||'—')+'</div></div></div></div>':'';
|
|
3398
|
-
var u=d.understanding;
|
|
3399
|
-
var uHtml=u?'<div class="band"><div class="bh" style="color:var(--cyan)">◇ node-0 GATHER — understanding (M2)</div><div class="re-rephrase" style="margin-top:4px">“'+esc(u.rephrase||'')+'”</div></div>':'';
|
|
3400
|
-
var et=d.expectedTrajectory||[];
|
|
3401
|
-
var etHtml=et.length?'<div class="band"><div class="bh" style="color:var(--primary-soft)">◇ node-0.5 EXPECTED-TRAJECTORY (M3) — how it SHOULD have acted</div><ol class="re-ul" style="margin-top:4px">'+et.map(function(s,i){return '<li><b>'+esc(s.step||i+1)+'.</b> '+esc(s.expected||'')+(s.rationale?' <span class=re-rat>— '+esc(s.rationale)+'</span>':'')+'</li>';}).join('')+'</ol></div>':'';
|
|
3402
|
-
return '<div class="drillbox"><div style="display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:6px"><b class="mono">'+esc(d.traceId)+'</b><span class="chip">'+esc(d.route||'all')+'</span><span class="verd '+(d.verdict=='FAIL'?'fail':d.verdict=='PASS'?'pass':'inc')+'">'+esc(d.verdict)+'</span></div>'+
|
|
3403
|
-
resRouting(d.res||'judge-walk')+
|
|
3404
|
-
spHtml+
|
|
3405
|
-
verdictWhy+
|
|
3406
|
-
critiqueBlock(d.criterionVerdicts)+
|
|
3407
|
-
'<div class="ctx"><div class="ctx-h">◇ judge · gather context</div><div class="ctx-g"><div class="ctx-c"><div class="l">harness</div><div class="v">'+esc(ctx.harness||'—')+'</div></div><div class="ctx-c"><div class="l">input + scenario</div><div class="v">'+inputCell(d.input,ctx.scenario)+'</div></div><div class="ctx-c"><div class="l">exit states</div><div class="v">'+esc(ctx.exitStates||'—')+(stateWhy?'<div class="why-note"><span class="ref">why concluded:</span> '+esc(stateWhy)+'</div>':'')+'</div></div></div></div>'+
|
|
3408
|
-
whyChain+
|
|
3409
|
-
uHtml+etHtml+
|
|
3410
|
-
'<div class="lanehdr"><div class="a">target agent — what it did</div><div class="x">step</div><div class="j">judge — eval coverage (which criteria examined this step)</div></div>'+
|
|
3411
|
-
'<div class="grid2">'+rowsHtml+'<div class="band loc"><div class="bh">↯ localize (root, not symptom)</div><div style="font-size:var(--fs-sm);margin-top:4px">'+esc(d.localize||'—')+'</div></div></div>'+
|
|
3412
|
-
'<div class="health"><div class="hc"><div class="l">context</div><div class="v good">'+(h.contextGathered?'✓':'—')+'</div></div><div class="hc"><div class="l">grounded</div><div class="v good">'+esc(h.grounded||0)+'</div></div><div class="hc"><div class="l">assumed</div><div class="v '+((h.assumed||0)>0?'warn':'good')+'">'+esc(h.assumed||0)+'</div></div><div class="hc"><div class="l">root vs symptom</div><div class="v good">'+(h.stoppedAtSymptom?'symptom':'✓ root')+'</div></div></div></div>';}
|
|
3331
|
+
${SIDE_BY_SIDE_FRAGMENT_JS}
|
|
3413
3332
|
function scorecard(r){var order={fail:0,uncertain:1,indeterminate:1,pass:2,na:3};
|
|
3414
3333
|
var cells=Object.keys(r.c).sort(function(a,b){return (order[r.c[a]]||9)-(order[r.c[b]]||9);}).map(function(k){var v=r.c[k];var disp=v=='uncertain'?'indeterminate':v;
|
|
3415
3334
|
return '<div class="scc '+esc(v)+'"><span class="nm" title="'+esc((C[k]||{}).n||k)+'">'+esc(k)+'</span><span style="margin-left:auto;color:var(--muted)">'+esc(disp)+'</span></div>';}).join('');
|