@tangle-network/agent-eval 0.90.0 → 0.91.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/dist/fuzz.d.ts +72 -9
- package/dist/fuzz.js +124 -53
- package/dist/fuzz.js.map +1 -1
- package/dist/openapi.json +1 -1
- package/package.json +1 -1
package/dist/fuzz.d.ts
CHANGED
|
@@ -52,6 +52,9 @@ interface Evaluation extends DefaultVerdict {
|
|
|
52
52
|
runId?: string;
|
|
53
53
|
/** Structured labels, e.g. failure classes (`hallucination`, `refusal`). */
|
|
54
54
|
labels?: string[];
|
|
55
|
+
/** Wall-clock for the evaluation, when the consumer measures it more precisely
|
|
56
|
+
* than the engine can (e.g. excluding judge time). Engine-measured otherwise. */
|
|
57
|
+
latencyMs?: number;
|
|
55
58
|
}
|
|
56
59
|
/** Run the target against one scenario in a cell. */
|
|
57
60
|
type Evaluator<S> = (scenario: S, cell: Cell) => Promise<Evaluation>;
|
|
@@ -123,16 +126,34 @@ interface ArchiveEntry<S> {
|
|
|
123
126
|
evaluation: Evaluation;
|
|
124
127
|
interest: number;
|
|
125
128
|
}
|
|
129
|
+
/** Summary of a sample — every aggregate carries its spread, never a bare mean. */
|
|
130
|
+
interface Distribution {
|
|
131
|
+
mean: number;
|
|
132
|
+
median: number;
|
|
133
|
+
p90: number;
|
|
134
|
+
min: number;
|
|
135
|
+
max: number;
|
|
136
|
+
n: number;
|
|
137
|
+
}
|
|
126
138
|
/** Per-INPUT-cell coverage — the planned-vs-covered map. */
|
|
127
139
|
interface CoverageCell {
|
|
128
140
|
cell: Cell;
|
|
129
141
|
runs: number;
|
|
130
|
-
/**
|
|
131
|
-
|
|
142
|
+
/** Headline score distribution in [0,1]; `null` when the cell was never run
|
|
143
|
+
* (honestly uncovered — never a fabricated zero). */
|
|
144
|
+
score: Distribution | null;
|
|
132
145
|
/** Fraction of runs the objective flagged as notable. */
|
|
133
146
|
findingRate: number;
|
|
134
|
-
/**
|
|
135
|
-
|
|
147
|
+
/** Per-dimension score distributions — surfaces WHICH dimension is weak and
|
|
148
|
+
* how consistently. */
|
|
149
|
+
dimensions: Record<string, Distribution>;
|
|
150
|
+
/** Evaluation wall-clock per run; engine-measured unless the evaluation
|
|
151
|
+
* carried its own `latencyMs`. `null` when the cell was never run. */
|
|
152
|
+
latencyMs: Distribution | null;
|
|
153
|
+
/** Known dollars spent in this cell — present only when cost tracking was
|
|
154
|
+
* wired; runs with unknown cost are counted apart, never folded in as $0. */
|
|
155
|
+
costUsd?: number;
|
|
156
|
+
costUnknownRuns?: number;
|
|
136
157
|
}
|
|
137
158
|
/** The artifact every exploration produces. */
|
|
138
159
|
interface CapsuleData<S> {
|
|
@@ -160,13 +181,29 @@ interface CapsuleData<S> {
|
|
|
160
181
|
behaviorBinsObserved: number;
|
|
161
182
|
candidateFindings: number;
|
|
162
183
|
verifiedFindings: number;
|
|
163
|
-
|
|
184
|
+
/** Distribution of per-cell mean scores across covered cells (cells weigh
|
|
185
|
+
* equally — variance steering sends more runs to weak cells, so a
|
|
186
|
+
* run-weighted average would bias low). `null` when nothing ran. */
|
|
187
|
+
robustness: Distribution | null;
|
|
188
|
+
/** Evaluation wall-clock across all runs. `null` when nothing ran. */
|
|
189
|
+
latencyMs: Distribution | null;
|
|
164
190
|
/** Known dollars spent on this exploration's runs. Present only when cost
|
|
165
191
|
* tracking was wired (`costOf`) — absent means "not tracked", never $0. */
|
|
166
192
|
costUsd?: number;
|
|
167
193
|
/** Runs whose cost was unknown (`costOf` returned null) — counted apart,
|
|
168
194
|
* never folded into `costUsd` as a fabricated $0. */
|
|
169
195
|
costUnknownRuns?: number;
|
|
196
|
+
/** Evaluations that threw (transport/backend failures). They consumed no
|
|
197
|
+
* run budget and scored nothing — an infra axis, never folded into
|
|
198
|
+
* robustness or reported as findings. */
|
|
199
|
+
evalErrors: number;
|
|
200
|
+
/** Present when the run stopped before its budget because consecutive
|
|
201
|
+
* eval errors tripped the circuit breaker (a dead backend must not burn
|
|
202
|
+
* the remaining budget). The capsule-so-far is complete and honest. */
|
|
203
|
+
stoppedEarly?: {
|
|
204
|
+
reason: 'eval-errors';
|
|
205
|
+
detail: string;
|
|
206
|
+
};
|
|
170
207
|
};
|
|
171
208
|
}
|
|
172
209
|
/**
|
|
@@ -190,6 +227,11 @@ type ExploreEvent<S> = {
|
|
|
190
227
|
} | {
|
|
191
228
|
type: 'finding';
|
|
192
229
|
finding: Finding<S>;
|
|
230
|
+
} | {
|
|
231
|
+
type: 'eval-error';
|
|
232
|
+
cell: Cell;
|
|
233
|
+
scenarioId: string;
|
|
234
|
+
message: string;
|
|
193
235
|
} | {
|
|
194
236
|
type: 'round';
|
|
195
237
|
runsUsed: number;
|
|
@@ -226,6 +268,9 @@ interface ExploreOptions<S> {
|
|
|
226
268
|
minimize?: (scenario: S, evaluate: Evaluator<S>, cell: Cell) => Promise<S> | S;
|
|
227
269
|
/** Max concurrent `evaluate` calls. Default 1. */
|
|
228
270
|
concurrency?: number;
|
|
271
|
+
/** Stop the run after this many CONSECUTIVE eval errors (a dead backend must
|
|
272
|
+
* not burn the remaining budget). Successes reset the streak. Default 5. */
|
|
273
|
+
maxConsecutiveEvalErrors?: number;
|
|
229
274
|
/** Cooperative cancellation. */
|
|
230
275
|
signal?: AbortSignal;
|
|
231
276
|
/** Progress stream. */
|
|
@@ -266,9 +311,10 @@ interface ExploreOptions<S> {
|
|
|
266
311
|
*
|
|
267
312
|
* Cells are the cartesian product of the input axes — the stratification plan,
|
|
268
313
|
* enumerable up front so the planned-vs-covered denominator is honest. Coverage
|
|
269
|
-
* is projected from the evaluation log: per cell,
|
|
270
|
-
*
|
|
271
|
-
*
|
|
314
|
+
* is projected from the evaluation log: per cell, the full DISTRIBUTION of the
|
|
315
|
+
* headline score, of each scored dimension, and of evaluation latency — a bare
|
|
316
|
+
* mean hides outliers, so every aggregate carries its spread. Per-cell cost is
|
|
317
|
+
* split known-dollars vs unknown-runs, never folded into a fabricated $0.
|
|
272
318
|
*/
|
|
273
319
|
|
|
274
320
|
/** One recorded evaluation — the unit coverage and the capsule are built from. */
|
|
@@ -277,6 +323,11 @@ interface EvalRecord {
|
|
|
277
323
|
ev: Evaluation;
|
|
278
324
|
/** The objective's interest score for this evaluation. */
|
|
279
325
|
interest: number;
|
|
326
|
+
/** Evaluation wall-clock — engine-measured unless `ev.latencyMs` overrode it. */
|
|
327
|
+
latencyMs: number;
|
|
328
|
+
/** Known dollars for this run. `null` = cost tracking was wired but this
|
|
329
|
+
* run's cost was unknowable (counted apart). Absent = not tracked at all. */
|
|
330
|
+
costUsd?: number | null;
|
|
280
331
|
}
|
|
281
332
|
/** Enumerate every input cell (cartesian product of the axes), in stable order. */
|
|
282
333
|
declare function enumerateCells(space: BehaviorSpace): Cell[];
|
|
@@ -284,7 +335,7 @@ declare function enumerateCells(space: BehaviorSpace): Cell[];
|
|
|
284
335
|
declare function cellId(space: BehaviorSpace, coords: Record<string, string>): string;
|
|
285
336
|
/**
|
|
286
337
|
* Project the evaluation log into the per-input-cell coverage map. A cell with
|
|
287
|
-
* no evaluations reports `
|
|
338
|
+
* no evaluations reports `score: null` (honestly uncovered), never zeros.
|
|
288
339
|
*/
|
|
289
340
|
declare function buildCoverage(cells: Cell[], log: EvalRecord[], threshold: number): CoverageCell[];
|
|
290
341
|
|
|
@@ -315,6 +366,13 @@ interface BuildCapsuleInput<S> {
|
|
|
315
366
|
costUsd: number;
|
|
316
367
|
costUnknownRuns: number;
|
|
317
368
|
};
|
|
369
|
+
/** Evaluations that threw — infra outcomes, never folded into robustness. */
|
|
370
|
+
evalErrors: number;
|
|
371
|
+
/** Set when the consecutive-error circuit breaker stopped the run early. */
|
|
372
|
+
stoppedEarly?: {
|
|
373
|
+
reason: 'eval-errors';
|
|
374
|
+
detail: string;
|
|
375
|
+
};
|
|
318
376
|
}
|
|
319
377
|
declare function buildCapsule<S>(input: BuildCapsuleInput<S>): CapsuleData<S>;
|
|
320
378
|
interface RenderCapsuleOptions {
|
|
@@ -356,6 +414,9 @@ declare class BehaviorExplorer<S> {
|
|
|
356
414
|
private readonly _findings;
|
|
357
415
|
private runsUsed;
|
|
358
416
|
private candidateFindings;
|
|
417
|
+
private evalErrors;
|
|
418
|
+
private consecutiveEvalErrors;
|
|
419
|
+
private stoppedEarly;
|
|
359
420
|
private rngState;
|
|
360
421
|
/** Accumulated KNOWN dollars — unknown-cost runs never inflate it. */
|
|
361
422
|
private spentKnownUsd;
|
|
@@ -369,6 +430,8 @@ declare class BehaviorExplorer<S> {
|
|
|
369
430
|
private costExhausted;
|
|
370
431
|
/** Fold one run's cost in: null counts as unknown (never $0); a known cost
|
|
371
432
|
* accrues toward the budget, lands in the ledger, and fires `onCost`. */
|
|
433
|
+
/** Returns the run's known cost, `null` when tracked-but-unknown, `undefined`
|
|
434
|
+
* when cost tracking is not wired — the log row mirrors this exactly. */
|
|
372
435
|
private recordRunCost;
|
|
373
436
|
/** Elites whose INPUT cell matches — what the proposer mutates/deepens from. */
|
|
374
437
|
private elitesFor;
|
package/dist/fuzz.js
CHANGED
|
@@ -22,7 +22,24 @@ function enumerateCells(space) {
|
|
|
22
22
|
function cellId(space, coords) {
|
|
23
23
|
return space.axes.map((a) => `${a.name}=${coords[a.name]}`).join("|");
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
function percentile(sorted, p) {
|
|
26
|
+
const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1));
|
|
27
|
+
return sorted[idx];
|
|
28
|
+
}
|
|
29
|
+
function distribution(values) {
|
|
30
|
+
if (values.length === 0)
|
|
31
|
+
throw new Error("distribution: empty sample \u2014 represent missing data as null, not zeros");
|
|
32
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
33
|
+
const mean = sorted.reduce((a, b) => a + b, 0) / sorted.length;
|
|
34
|
+
return {
|
|
35
|
+
mean,
|
|
36
|
+
median: percentile(sorted, 0.5),
|
|
37
|
+
p90: percentile(sorted, 0.9),
|
|
38
|
+
min: sorted[0],
|
|
39
|
+
max: sorted[sorted.length - 1],
|
|
40
|
+
n: sorted.length
|
|
41
|
+
};
|
|
42
|
+
}
|
|
26
43
|
function buildCoverage(cells, log, threshold) {
|
|
27
44
|
const byCell = /* @__PURE__ */ new Map();
|
|
28
45
|
for (const r of log) {
|
|
@@ -33,19 +50,27 @@ function buildCoverage(cells, log, threshold) {
|
|
|
33
50
|
return cells.map((cell) => {
|
|
34
51
|
const recs = byCell.get(cell.id) ?? [];
|
|
35
52
|
const runs = recs.length;
|
|
36
|
-
if (runs === 0)
|
|
37
|
-
|
|
53
|
+
if (runs === 0)
|
|
54
|
+
return { cell, runs: 0, score: null, findingRate: 0, dimensions: {}, latencyMs: null };
|
|
55
|
+
const score = distribution(recs.map((r) => r.ev.score));
|
|
56
|
+
const latencyMs = distribution(recs.map((r) => r.latencyMs));
|
|
38
57
|
const findingRate = recs.filter((r) => r.interest >= threshold).length / runs;
|
|
39
|
-
const
|
|
58
|
+
const dimSamples = {};
|
|
40
59
|
for (const r of recs) {
|
|
41
60
|
for (const [k, v] of Object.entries(r.ev.scores ?? {})) {
|
|
42
61
|
;
|
|
43
|
-
(
|
|
62
|
+
(dimSamples[k] ??= []).push(v);
|
|
44
63
|
}
|
|
45
64
|
}
|
|
46
65
|
const dimensions = {};
|
|
47
|
-
for (const [k, xs] of Object.entries(
|
|
48
|
-
|
|
66
|
+
for (const [k, xs] of Object.entries(dimSamples)) dimensions[k] = distribution(xs);
|
|
67
|
+
const tracked = recs.filter((r) => r.costUsd !== void 0);
|
|
68
|
+
const known = tracked.filter((r) => r.costUsd !== null);
|
|
69
|
+
const cost = tracked.length > 0 ? {
|
|
70
|
+
costUsd: known.reduce((a, r) => a + r.costUsd, 0),
|
|
71
|
+
...tracked.length > known.length ? { costUnknownRuns: tracked.length - known.length } : {}
|
|
72
|
+
} : {};
|
|
73
|
+
return { cell, runs, score, findingRate, dimensions, latencyMs, ...cost };
|
|
49
74
|
});
|
|
50
75
|
}
|
|
51
76
|
|
|
@@ -53,7 +78,8 @@ function buildCoverage(cells, log, threshold) {
|
|
|
53
78
|
function buildCapsule(input) {
|
|
54
79
|
const coverage = buildCoverage(input.cells, input.log, input.threshold);
|
|
55
80
|
const covered = coverage.filter((c) => c.runs > 0);
|
|
56
|
-
const
|
|
81
|
+
const robustness = covered.length === 0 ? null : distribution(covered.map((c) => c.score.mean));
|
|
82
|
+
const latencyMs = input.log.length === 0 ? null : distribution(input.log.map((r) => r.latencyMs));
|
|
57
83
|
const behaviorBinsObserved = input.archive.filter((e) => e.binId !== e.cell.id).length;
|
|
58
84
|
return {
|
|
59
85
|
target: input.target,
|
|
@@ -68,8 +94,11 @@ function buildCapsule(input) {
|
|
|
68
94
|
behaviorBinsObserved,
|
|
69
95
|
candidateFindings: input.candidateFindings,
|
|
70
96
|
verifiedFindings: input.findings.length,
|
|
71
|
-
|
|
72
|
-
|
|
97
|
+
robustness,
|
|
98
|
+
latencyMs,
|
|
99
|
+
...input.cost ? { costUsd: input.cost.costUsd, costUnknownRuns: input.cost.costUnknownRuns } : {},
|
|
100
|
+
evalErrors: input.evalErrors,
|
|
101
|
+
...input.stoppedEarly ? { stoppedEarly: input.stoppedEarly } : {}
|
|
73
102
|
}
|
|
74
103
|
};
|
|
75
104
|
}
|
|
@@ -101,7 +130,7 @@ function deriveAxes(coverage) {
|
|
|
101
130
|
return order.map((name) => ({ name, values: [...seen.get(name) ?? []] }));
|
|
102
131
|
}
|
|
103
132
|
function weakestDim(c) {
|
|
104
|
-
const entries = Object.entries(c.dimensions);
|
|
133
|
+
const entries = Object.entries(c.dimensions).map(([k, d]) => [k, d.mean]);
|
|
105
134
|
if (entries.length === 0) return "";
|
|
106
135
|
const sorted = entries.sort((a, b) => a[1] - b[1]);
|
|
107
136
|
const w = sorted[0];
|
|
@@ -112,8 +141,8 @@ function heatmapHtml(coverage) {
|
|
|
112
141
|
const axes = deriveAxes(coverage);
|
|
113
142
|
const byId = new Map(coverage.map((c) => [c.cell.id, c]));
|
|
114
143
|
const tile = (c, label) => {
|
|
115
|
-
const r = c?.
|
|
116
|
-
const title = c ? `${pct(
|
|
144
|
+
const r = c?.score?.mean ?? null;
|
|
145
|
+
const title = c?.score ? `${pct(c.score.mean)} robust (median ${pct(c.score.median)}, min ${pct(c.score.min)}) \xB7 ${c.runs} runs \xB7 ${pct(c.findingRate)} flagged${c.latencyMs ? ` \xB7 ${(c.latencyMs.median / 1e3).toFixed(1)}s median` : ""}${c.costUsd !== void 0 ? ` \xB7 $${c.costUsd.toFixed(2)}` : ""}` : "not covered";
|
|
117
146
|
return `<div class="tile" style="background:${robustnessColor(r)}" title="${esc(title)}">${label ? `<span class="tl">${esc(label)}</span>` : ""}<span class="tv">${c && r != null ? pct(r) : "\u2014"}</span>${c ? weakestDim(c) : ""}</div>`;
|
|
118
147
|
};
|
|
119
148
|
const rowAxis = axes[0];
|
|
@@ -129,7 +158,7 @@ function heatmapHtml(coverage) {
|
|
|
129
158
|
}).join("");
|
|
130
159
|
return `<div class="axis-label">rows: <b>${esc(rowAxis.name)}</b> \xB7 cols: <b>${esc(colAxis.name)}</b></div><table class="heat">${head}${rows}</table>`;
|
|
131
160
|
}
|
|
132
|
-
const sorted = [...coverage].sort((a, b) => (a.
|
|
161
|
+
const sorted = [...coverage].sort((a, b) => (a.score?.mean ?? 2) - (b.score?.mean ?? 2));
|
|
133
162
|
return `<div class="grid">${sorted.map((c) => tile(c, Object.values(c.cell.coords).join(" \xB7 "))).join("")}</div>`;
|
|
134
163
|
}
|
|
135
164
|
function findingsHtml(findings, limit) {
|
|
@@ -196,13 +225,17 @@ table.heat th.rh{text-align:right}
|
|
|
196
225
|
<h1>${esc(capsule.objective)} exploration \xB7 ${esc(capsule.target)}</h1>
|
|
197
226
|
<div class="sub">${s.totalRuns} scenarios across ${s.cellsCovered}/${s.cellsTotal} planned cells${s.behaviorBinsObserved > 0 ? ` \xB7 ${s.behaviorBinsObserved} measured behavior bins` : ""}${stamp ? ` \xB7 ${esc(stamp)}` : ""}</div>
|
|
198
227
|
<div class="kpis">
|
|
199
|
-
${kpi("
|
|
228
|
+
${s.robustness ? kpi("robustness", `${pct(s.robustness.mean)}`, s.robustness.mean < 0.6 ? "#e58a96" : "#5ad17a") : ""}
|
|
229
|
+
${s.robustness ? kpi("cell spread", `${pct(s.robustness.min)}\u2013${pct(s.robustness.max)}`) : ""}
|
|
230
|
+
${s.latencyMs ? kpi("median latency", `${(s.latencyMs.median / 1e3).toFixed(1)}s`, s.latencyMs.p90 > 4 * s.latencyMs.median ? "#e5b566" : "#e6e6e6") : ""}
|
|
200
231
|
${kpi("verified findings", String(s.verifiedFindings), s.verifiedFindings > 0 ? "#e58a96" : "#5ad17a")}
|
|
201
232
|
${kpi("cells covered", `${s.cellsCovered}/${s.cellsTotal}`)}
|
|
202
233
|
${kpi("scenarios run", String(s.totalRuns))}
|
|
203
234
|
${cost}
|
|
235
|
+
${s.evalErrors > 0 ? kpi("eval errors", String(s.evalErrors), "#e5b566") : ""}
|
|
204
236
|
${lift}
|
|
205
237
|
</div>
|
|
238
|
+
${s.stoppedEarly ? `<div class="sub" style="color:#e5b566">stopped early: ${esc(s.stoppedEarly.detail)} \u2014 coverage below reflects the completed portion only</div>` : ""}
|
|
206
239
|
<h2>Coverage map</h2>
|
|
207
240
|
${heatmapHtml(capsule.coverage)}
|
|
208
241
|
<h2>Verified findings${s.candidateFindings > s.verifiedFindings ? ` \xB7 ${s.verifiedFindings} of ${s.candidateFindings} candidates passed the validity gates` : ""}</h2>
|
|
@@ -317,6 +350,9 @@ var BehaviorExplorer = class {
|
|
|
317
350
|
_findings = [];
|
|
318
351
|
runsUsed = 0;
|
|
319
352
|
candidateFindings = 0;
|
|
353
|
+
evalErrors = 0;
|
|
354
|
+
consecutiveEvalErrors = 0;
|
|
355
|
+
stoppedEarly;
|
|
320
356
|
rngState;
|
|
321
357
|
/** Accumulated KNOWN dollars — unknown-cost runs never inflate it. */
|
|
322
358
|
spentKnownUsd = 0;
|
|
@@ -363,12 +399,14 @@ var BehaviorExplorer = class {
|
|
|
363
399
|
}
|
|
364
400
|
/** Fold one run's cost in: null counts as unknown (never $0); a known cost
|
|
365
401
|
* accrues toward the budget, lands in the ledger, and fires `onCost`. */
|
|
402
|
+
/** Returns the run's known cost, `null` when tracked-but-unknown, `undefined`
|
|
403
|
+
* when cost tracking is not wired — the log row mirrors this exactly. */
|
|
366
404
|
recordRunCost(scenario, cell, ev) {
|
|
367
|
-
if (!this.opts.costOf) return;
|
|
405
|
+
if (!this.opts.costOf) return void 0;
|
|
368
406
|
const cost = this.opts.costOf(scenario, cell, ev);
|
|
369
407
|
if (cost === null) {
|
|
370
408
|
this.costUnknownRuns++;
|
|
371
|
-
return;
|
|
409
|
+
return null;
|
|
372
410
|
}
|
|
373
411
|
if (typeof cost.usd !== "number" || !Number.isFinite(cost.usd) || cost.usd < 0) {
|
|
374
412
|
throw new RangeError(
|
|
@@ -384,6 +422,7 @@ var BehaviorExplorer = class {
|
|
|
384
422
|
tags: { target: this.opts.target, cell: cell.id }
|
|
385
423
|
});
|
|
386
424
|
this.opts.onCost?.({ usd: cost.usd, channel: "agent" });
|
|
425
|
+
return cost.usd;
|
|
387
426
|
}
|
|
388
427
|
/** Elites whose INPUT cell matches — what the proposer mutates/deepens from. */
|
|
389
428
|
elitesFor(cellId2) {
|
|
@@ -400,7 +439,7 @@ var BehaviorExplorer = class {
|
|
|
400
439
|
const newFindings = [];
|
|
401
440
|
let runsThisStep = 0;
|
|
402
441
|
for (const alloc of allocations) {
|
|
403
|
-
if (this.runsUsed >= this.opts.budget || this.costExhausted() || this.opts.signal?.aborted)
|
|
442
|
+
if (this.runsUsed >= this.opts.budget || this.costExhausted() || this.stoppedEarly !== void 0 || this.opts.signal?.aborted)
|
|
404
443
|
break;
|
|
405
444
|
const cell = this.cellById.get(alloc.cellId);
|
|
406
445
|
if (!cell) continue;
|
|
@@ -422,39 +461,69 @@ var BehaviorExplorer = class {
|
|
|
422
461
|
await pMap(
|
|
423
462
|
toEval,
|
|
424
463
|
async (scenario) => {
|
|
425
|
-
if (this.runsUsed >= this.opts.budget || this.costExhausted() || this.opts.signal?.aborted)
|
|
426
|
-
return;
|
|
427
|
-
const ev = await this.opts.evaluate(scenario, cell);
|
|
428
|
-
this.runsUsed++;
|
|
429
|
-
runsThisStep++;
|
|
430
|
-
this.recordRunCost(scenario, cell, ev);
|
|
431
|
-
const interest = this.objective.interest(ev, this.objectiveContext());
|
|
432
|
-
this.log.push({ cell, ev, interest, scenarioId: this.opts.scenarioId(scenario) });
|
|
433
|
-
this.opts.onProgress?.({ type: "evaluated", cell, scenario, evaluation: ev });
|
|
434
|
-
const bin = this.binId(cell, ev.descriptor);
|
|
435
|
-
const cur = this.archiveByBin.get(bin);
|
|
436
|
-
if (!cur || interest > cur.interest)
|
|
437
|
-
this.archiveByBin.set(bin, { binId: bin, cell, scenario, evaluation: ev, interest });
|
|
438
|
-
if (interest < this.threshold) return;
|
|
439
|
-
this.candidateFindings++;
|
|
440
|
-
if (this.opts.gates?.isValid && !await this.opts.gates.isValid(scenario, ev, cell))
|
|
441
|
-
return;
|
|
442
|
-
if (this.opts.gates?.isUncontaminated && !await this.opts.gates.isUncontaminated(scenario, ev, cell))
|
|
464
|
+
if (this.runsUsed >= this.opts.budget || this.costExhausted() || this.stoppedEarly !== void 0 || this.opts.signal?.aborted)
|
|
443
465
|
return;
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
interest,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
466
|
+
try {
|
|
467
|
+
const startedAt = performance.now();
|
|
468
|
+
const ev = await this.opts.evaluate(scenario, cell);
|
|
469
|
+
const latencyMs = ev.latencyMs ?? performance.now() - startedAt;
|
|
470
|
+
this.runsUsed++;
|
|
471
|
+
runsThisStep++;
|
|
472
|
+
this.consecutiveEvalErrors = 0;
|
|
473
|
+
const costUsd = this.recordRunCost(scenario, cell, ev);
|
|
474
|
+
const interest = this.objective.interest(ev, this.objectiveContext());
|
|
475
|
+
this.log.push({
|
|
476
|
+
cell,
|
|
477
|
+
ev,
|
|
478
|
+
interest,
|
|
479
|
+
latencyMs,
|
|
480
|
+
...costUsd !== void 0 ? { costUsd } : {},
|
|
481
|
+
scenarioId: this.opts.scenarioId(scenario)
|
|
482
|
+
});
|
|
483
|
+
this.opts.onProgress?.({ type: "evaluated", cell, scenario, evaluation: ev });
|
|
484
|
+
const bin = this.binId(cell, ev.descriptor);
|
|
485
|
+
const cur = this.archiveByBin.get(bin);
|
|
486
|
+
if (!cur || interest > cur.interest)
|
|
487
|
+
this.archiveByBin.set(bin, { binId: bin, cell, scenario, evaluation: ev, interest });
|
|
488
|
+
if (interest < this.threshold) return;
|
|
489
|
+
this.candidateFindings++;
|
|
490
|
+
if (this.opts.gates?.isValid && !await this.opts.gates.isValid(scenario, ev, cell))
|
|
491
|
+
return;
|
|
492
|
+
if (this.opts.gates?.isUncontaminated && !await this.opts.gates.isUncontaminated(scenario, ev, cell))
|
|
493
|
+
return;
|
|
494
|
+
const minimized = this.opts.minimize ? await this.opts.minimize(scenario, this.opts.evaluate, cell) : scenario;
|
|
495
|
+
const finding = {
|
|
496
|
+
id: this.opts.scenarioId(scenario),
|
|
497
|
+
cell,
|
|
498
|
+
scenario,
|
|
499
|
+
minimized,
|
|
500
|
+
text: this.opts.scenarioText?.(minimized),
|
|
501
|
+
evaluation: ev,
|
|
502
|
+
interest,
|
|
503
|
+
objective: this.objective.kind
|
|
504
|
+
};
|
|
505
|
+
this._findings.push(finding);
|
|
506
|
+
newFindings.push(finding);
|
|
507
|
+
this.opts.onProgress?.({ type: "finding", finding });
|
|
508
|
+
} catch (err) {
|
|
509
|
+
if (err instanceof RangeError) throw err;
|
|
510
|
+
this.evalErrors++;
|
|
511
|
+
this.consecutiveEvalErrors++;
|
|
512
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
513
|
+
this.opts.onProgress?.({
|
|
514
|
+
type: "eval-error",
|
|
515
|
+
cell,
|
|
516
|
+
scenarioId: this.opts.scenarioId(scenario),
|
|
517
|
+
message
|
|
518
|
+
});
|
|
519
|
+
const limit = this.opts.maxConsecutiveEvalErrors ?? 5;
|
|
520
|
+
if (this.consecutiveEvalErrors >= limit) {
|
|
521
|
+
this.stoppedEarly = {
|
|
522
|
+
reason: "eval-errors",
|
|
523
|
+
detail: `${this.consecutiveEvalErrors} consecutive eval errors (last: ${message})`
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
}
|
|
458
527
|
},
|
|
459
528
|
this.opts.concurrency ?? 1,
|
|
460
529
|
this.opts.signal
|
|
@@ -466,9 +535,9 @@ var BehaviorExplorer = class {
|
|
|
466
535
|
/** Loop `step()` until the run or dollar budget is spent, the signal aborts,
|
|
467
536
|
* or no progress is made. */
|
|
468
537
|
async run() {
|
|
469
|
-
while (this.runsUsed < this.opts.budget && !this.costExhausted() && !this.opts.signal?.aborted) {
|
|
538
|
+
while (this.runsUsed < this.opts.budget && !this.costExhausted() && this.stoppedEarly === void 0 && !this.opts.signal?.aborted) {
|
|
470
539
|
const { runs } = await this.step();
|
|
471
|
-
if (runs === 0) break;
|
|
540
|
+
if (runs === 0 && this.stoppedEarly === void 0) break;
|
|
472
541
|
}
|
|
473
542
|
return this.capsule();
|
|
474
543
|
}
|
|
@@ -489,7 +558,9 @@ var BehaviorExplorer = class {
|
|
|
489
558
|
findings: this._findings,
|
|
490
559
|
candidateFindings: this.candidateFindings,
|
|
491
560
|
runsUsed: this.runsUsed,
|
|
492
|
-
cost: this.opts.costOf ? { costUsd: this.spentKnownUsd, costUnknownRuns: this.costUnknownRuns } : void 0
|
|
561
|
+
cost: this.opts.costOf ? { costUsd: this.spentKnownUsd, costUnknownRuns: this.costUnknownRuns } : void 0,
|
|
562
|
+
evalErrors: this.evalErrors,
|
|
563
|
+
stoppedEarly: this.stoppedEarly
|
|
493
564
|
});
|
|
494
565
|
}
|
|
495
566
|
};
|
package/dist/fuzz.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fuzz/cube.ts","../src/fuzz/capsule.ts","../src/fuzz/policies.ts","../src/fuzz/explorer.ts","../src/fuzz/fuzz-agent.ts","../src/fuzz/gates.ts","../src/fuzz/tools.ts"],"sourcesContent":["/**\n * Input-space tiling + coverage projection.\n *\n * Cells are the cartesian product of the input axes — the stratification plan,\n * enumerable up front so the planned-vs-covered denominator is honest. Coverage\n * is projected from the evaluation log: per cell, mean headline robustness, the\n * mean of each scored dimension (so the map shows WHICH dimension is weak), and\n * the rate at which the active objective flagged a candidate.\n */\n\nimport type { BehaviorSpace, Cell, CoverageCell, Evaluation } from './types'\n\n/** One recorded evaluation — the unit coverage and the capsule are built from. */\nexport interface EvalRecord {\n cell: Cell\n ev: Evaluation\n /** The objective's interest score for this evaluation. */\n interest: number\n}\n\n/** Enumerate every input cell (cartesian product of the axes), in stable order. */\nexport function enumerateCells(space: BehaviorSpace): Cell[] {\n if (space.axes.length === 0) return []\n let partials: Array<Record<string, string>> = [{}]\n for (const axis of space.axes) {\n const next: Array<Record<string, string>> = []\n for (const partial of partials) {\n for (const value of axis.values) next.push({ ...partial, [axis.name]: value })\n }\n partials = next\n }\n return partials.map((coords) => ({ id: cellId(space, coords), coords }))\n}\n\n/** Deterministic id for a coordinate map, e.g. `matterType=nda|difficulty=hard`. */\nexport function cellId(space: BehaviorSpace, coords: Record<string, string>): string {\n return space.axes.map((a) => `${a.name}=${coords[a.name]}`).join('|')\n}\n\nconst mean = (xs: number[]): number =>\n xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length\n\n/**\n * Project the evaluation log into the per-input-cell coverage map. A cell with\n * no evaluations reports `robustness: null` (honestly uncovered), never 0.\n */\nexport function buildCoverage(cells: Cell[], log: EvalRecord[], threshold: number): CoverageCell[] {\n const byCell = new Map<string, EvalRecord[]>()\n for (const r of log) {\n const arr = byCell.get(r.cell.id) ?? []\n arr.push(r)\n byCell.set(r.cell.id, arr)\n }\n return cells.map((cell) => {\n const recs = byCell.get(cell.id) ?? []\n const runs = recs.length\n if (runs === 0) return { cell, runs: 0, robustness: null, findingRate: 0, dimensions: {} }\n const robustness = mean(recs.map((r) => r.ev.score))\n const findingRate = recs.filter((r) => r.interest >= threshold).length / runs\n const dims: Record<string, number[]> = {}\n for (const r of recs) {\n for (const [k, v] of Object.entries(r.ev.scores ?? {})) {\n ;(dims[k] ??= []).push(v)\n }\n }\n const dimensions: Record<string, number> = {}\n for (const [k, xs] of Object.entries(dims)) dimensions[k] = mean(xs)\n return { cell, runs, robustness, findingRate, dimensions }\n })\n}\n","/**\n * The capsule — the artifact every exploration produces.\n *\n * `buildCapsule` assembles coverage + verified findings + the QD archive into a\n * pure `CapsuleData` (no clock, no I/O — deterministic and snapshot-testable).\n * `renderCapsuleHtml` turns it into a standalone page: the input-cell heat-map\n * (planned vs covered), per-dimension weakness chips, and the minimized finding\n * exemplars. One artifact — the hardening map and the shareable proof object.\n */\n\nimport type { EvalRecord } from './cube'\nimport { buildCoverage } from './cube'\nimport type { ArchiveEntry, CapsuleData, Cell, CoverageCell, Finding } from './types'\n\nexport interface BuildCapsuleInput<S> {\n target: string\n objective: string\n cells: Cell[]\n log: EvalRecord[]\n /** The objective's notable threshold — drives findingRate. */\n threshold: number\n archive: ArchiveEntry<S>[]\n findings: Finding<S>[]\n candidateFindings: number\n runsUsed: number\n /** Known-dollar / unknown-run split — present only when cost tracking was\n * wired; the capsule never fabricates a $0 total. */\n cost?: { costUsd: number; costUnknownRuns: number }\n}\n\nexport function buildCapsule<S>(input: BuildCapsuleInput<S>): CapsuleData<S> {\n const coverage = buildCoverage(input.cells, input.log, input.threshold)\n const covered = coverage.filter((c) => c.runs > 0)\n const meanRobustness =\n covered.length === 0 ? 0 : covered.reduce((a, c) => a + (c.robustness ?? 0), 0) / covered.length\n // Measured-descriptor bins beyond the bare input cell — observed, never planned.\n const behaviorBinsObserved = input.archive.filter((e) => e.binId !== e.cell.id).length\n\n return {\n target: input.target,\n objective: input.objective,\n coverage,\n findings: [...input.findings].sort((a, b) => b.interest - a.interest),\n archive: [...input.archive].sort((a, b) => b.interest - a.interest),\n stats: {\n totalRuns: input.runsUsed,\n cellsTotal: input.cells.length,\n cellsCovered: covered.length,\n behaviorBinsObserved,\n candidateFindings: input.candidateFindings,\n verifiedFindings: input.findings.length,\n meanRobustness,\n ...(input.cost\n ? { costUsd: input.cost.costUsd, costUnknownRuns: input.cost.costUnknownRuns }\n : {}),\n },\n }\n}\n\n// ── HTML capsule ──────────────────────────────────────────────────────────────\n\nfunction esc(s: string): string {\n return s.replace(\n /[&<>\"]/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c] as string,\n )\n}\n\n/** red (0) → amber (.5) → green (1); uncovered cells render gray. */\nfunction robustnessColor(r: number | null): string {\n if (r == null) return '#2a2a2e'\n return `hsl(${Math.round(r * 120)} 70% 42%)`\n}\n\nfunction pct(x: number): string {\n return `${Math.round(x * 100)}%`\n}\n\nfunction deriveAxes(coverage: CoverageCell[]): Array<{ name: string; values: string[] }> {\n const order: string[] = []\n const seen = new Map<string, Set<string>>()\n for (const c of coverage) {\n for (const [k, v] of Object.entries(c.cell.coords)) {\n if (!seen.has(k)) {\n seen.set(k, new Set())\n order.push(k)\n }\n seen.get(k)?.add(v)\n }\n }\n return order.map((name) => ({ name, values: [...(seen.get(name) ?? [])] }))\n}\n\n/** The weakest dimension chip for a cell, e.g. `safety 32%` — shown when scores exist. */\nfunction weakestDim(c: CoverageCell): string {\n const entries = Object.entries(c.dimensions)\n if (entries.length === 0) return ''\n const sorted = entries.sort((a, b) => a[1] - b[1])\n const w = sorted[0]\n if (!w) return ''\n return `<span class=\"dim\">${esc(w[0])} ${pct(w[1])}</span>`\n}\n\nfunction heatmapHtml(coverage: CoverageCell[]): string {\n const axes = deriveAxes(coverage)\n const byId = new Map(coverage.map((c) => [c.cell.id, c]))\n const tile = (c: CoverageCell | undefined, label: string): string => {\n const r = c?.robustness ?? null\n const title = c\n ? `${pct(r ?? 0)} robust · ${c.runs} runs · ${pct(c.findingRate)} flagged`\n : 'not covered'\n return `<div class=\"tile\" style=\"background:${robustnessColor(r)}\" title=\"${esc(title)}\">${label ? `<span class=\"tl\">${esc(label)}</span>` : ''}<span class=\"tv\">${c && r != null ? pct(r) : '—'}</span>${c ? weakestDim(c) : ''}</div>`\n }\n\n const rowAxis = axes[0]\n const colAxis = axes[1]\n if (axes.length === 2 && rowAxis && colAxis) {\n const head = `<tr><th></th>${colAxis.values.map((v) => `<th>${esc(v)}</th>`).join('')}</tr>`\n const rows = rowAxis.values\n .map((rv) => {\n const cells = colAxis.values\n .map((cv) => {\n const id = `${rowAxis.name}=${rv}|${colAxis.name}=${cv}`\n return `<td>${tile(byId.get(id), '')}</td>`\n })\n .join('')\n return `<tr><th class=\"rh\">${esc(rv)}</th>${cells}</tr>`\n })\n .join('')\n return `<div class=\"axis-label\">rows: <b>${esc(rowAxis.name)}</b> · cols: <b>${esc(colAxis.name)}</b></div><table class=\"heat\">${head}${rows}</table>`\n }\n\n const sorted = [...coverage].sort((a, b) => (a.robustness ?? 2) - (b.robustness ?? 2))\n return `<div class=\"grid\">${sorted.map((c) => tile(c, Object.values(c.cell.coords).join(' · '))).join('')}</div>`\n}\n\nfunction findingsHtml<S>(findings: Finding<S>[], limit: number): string {\n if (findings.length === 0)\n return `<p class=\"none\">No verified findings — the target held across every covered cell.</p>`\n return findings\n .slice(0, limit)\n .map((f) => {\n const coords = Object.entries(f.cell.coords)\n .map(([k, v]) => `${k}:${v}`)\n .join(' · ')\n const labels = (f.evaluation.labels ?? [])\n .map((l) => `<span class=\"fclass\">${esc(l)}</span>`)\n .join('')\n const dims = Object.entries(f.evaluation.scores ?? {})\n .sort((a, b) => a[1] - b[1])\n .slice(0, 3)\n .map(([k, v]) => `<span class=\"dim\">${esc(k)} ${pct(v)}</span>`)\n .join('')\n return `<div class=\"fail\"><div class=\"fmeta\"><span class=\"fcell\">${esc(coords)}</span>${labels}<span class=\"fsev\">interest ${pct(f.interest)}</span></div><div class=\"sevbar\"><div class=\"sevfill\" style=\"width:${pct(f.interest)}\"></div></div><div class=\"ftext\">${esc(f.text ?? '(scenario text not captured)')}</div>${dims ? `<div class=\"fdims\">${dims}</div>` : ''}</div>`\n })\n .join('')\n}\n\nexport interface RenderCapsuleOptions {\n /** Max finding exemplars to show. Default 8. */\n maxFindings?: number\n /** ISO timestamp to stamp into the page (keeps the pure capsule clock-free). */\n generatedAt?: string\n}\n\n/** Render a self-contained HTML capsule — heat-map + per-dimension chips + verified findings. */\nexport function renderCapsuleHtml<S>(\n capsule: CapsuleData<S>,\n opts: RenderCapsuleOptions = {},\n): string {\n const s = capsule.stats\n const kpi = (label: string, value: string, accent = '#e6e6e6'): string =>\n `<div class=\"kpi\"><div class=\"kv\" style=\"color:${accent}\">${esc(value)}</div><div class=\"kl\">${esc(label)}</div></div>`\n const lift = capsule.lift\n ? kpi(\n 'hardening lift',\n `${capsule.lift.before.toFixed(2)} → ${capsule.lift.after.toFixed(2)}`,\n '#5ad17a',\n )\n : ''\n // Cost KPI only when tracking was wired — an untracked run never shows $0.\n // Unpriced runs are named in the label (amber): the total is a lower bound.\n const cost =\n s.costUsd !== undefined\n ? kpi(\n s.costUnknownRuns ? `cost · ${s.costUnknownRuns} runs unpriced` : 'cost',\n `$${s.costUsd.toFixed(2)}`,\n s.costUnknownRuns ? '#e5c07b' : '#e6e6e6',\n )\n : ''\n const stamp = opts.generatedAt ?? capsule.generatedAt ?? ''\n\n return `<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(capsule.objective)} capsule — ${esc(capsule.target)}</title>\n<style>\n:root{color-scheme:dark}\n*{box-sizing:border-box}\nbody{margin:0;background:#0c0c0f;color:#e6e6e6;font:14px/1.5 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}\n.wrap{max-width:980px;margin:0 auto;padding:40px 24px}\nh1{font-size:22px;margin:0 0 2px;letter-spacing:-.01em}\n.sub{color:#8a8a93;font-size:13px;margin-bottom:28px}\n.kpis{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:32px}\n.kpi{background:#16161b;border:1px solid #24242b;border-radius:12px;padding:14px 18px;min-width:120px}\n.kv{font-size:24px;font-weight:650;letter-spacing:-.02em}\n.kl{color:#8a8a93;font-size:12px;margin-top:2px}\nh2{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:#8a8a93;margin:34px 0 14px}\n.axis-label{color:#8a8a93;font-size:12px;margin-bottom:10px}\ntable.heat{border-collapse:separate;border-spacing:6px}\ntable.heat th{font-weight:500;color:#a8a8b0;font-size:12px;padding:4px 8px;text-align:center}\ntable.heat th.rh{text-align:right}\n.tile{position:relative;width:104px;height:66px;border-radius:10px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:1px;color:#06120a;font-weight:600}\n.tile .tv{font-size:17px}\n.tile .tl{font-size:10px;font-weight:600;opacity:.9;padding:0 6px;text-align:center}\n.tile .dim{font-size:9px;font-weight:600;opacity:.85;background:rgba(0,0,0,.22);padding:0 6px;border-radius:999px}\n.grid{display:flex;flex-wrap:wrap;gap:8px}\n.grid .tile{width:138px;height:74px}\n.fail{background:#16161b;border:1px solid #24242b;border-left:3px solid #d1495b;border-radius:10px;padding:12px 14px;margin-bottom:10px}\n.fmeta{display:flex;gap:10px;align-items:center;font-size:12px;color:#a8a8b0;margin-bottom:8px}\n.fcell{color:#cfcfd6}\n.fclass{background:#2a1a1d;color:#e58a96;padding:1px 8px;border-radius:999px;font-size:11px}\n.fsev{margin-left:auto;color:#e58a96}\n.sevbar{height:4px;background:#24242b;border-radius:2px;overflow:hidden;margin-bottom:10px}\n.sevfill{height:100%;background:#d1495b}\n.ftext{font-size:13px;color:#d8d8df;white-space:pre-wrap}\n.fdims{display:flex;gap:6px;margin-top:8px}\n.fdims .dim{background:#1d2530;color:#9fc1e8;padding:1px 8px;border-radius:999px;font-size:11px}\n.none{color:#5ad17a}\n.foot{color:#5a5a63;font-size:11px;margin-top:36px}\n</style></head><body><div class=\"wrap\">\n<h1>${esc(capsule.objective)} exploration · ${esc(capsule.target)}</h1>\n<div class=\"sub\">${s.totalRuns} scenarios across ${s.cellsCovered}/${s.cellsTotal} planned cells${s.behaviorBinsObserved > 0 ? ` · ${s.behaviorBinsObserved} measured behavior bins` : ''}${stamp ? ` · ${esc(stamp)}` : ''}</div>\n<div class=\"kpis\">\n${kpi('mean robustness', pct(s.meanRobustness), s.meanRobustness < 0.6 ? '#e58a96' : '#5ad17a')}\n${kpi('verified findings', String(s.verifiedFindings), s.verifiedFindings > 0 ? '#e58a96' : '#5ad17a')}\n${kpi('cells covered', `${s.cellsCovered}/${s.cellsTotal}`)}\n${kpi('scenarios run', String(s.totalRuns))}\n${cost}\n${lift}\n</div>\n<h2>Coverage map</h2>\n${heatmapHtml(capsule.coverage)}\n<h2>Verified findings${s.candidateFindings > s.verifiedFindings ? ` · ${s.verifiedFindings} of ${s.candidateFindings} candidates passed the validity gates` : ''}</h2>\n${findingsHtml(capsule.findings, opts.maxFindings ?? 8)}\n<div class=\"foot\">Findings are gate-verified: each is a fair, answerable task that reproduces under a meaning-preserving rephrase, minimized to the smallest trigger.</div>\n</div></body></html>`\n}\n","/**\n * Shipped policies for the exploration engine.\n *\n * `Proposer` is a plain function type — an agent running a generator skill IS a\n * proposer (`(ctx) => dispatchToSkill(ctx)`), no wrapper needed. `mutationProposer`\n * builds the deterministic, LLM-free one from mutation operators. Objectives are\n * interfaces because the engine reads `kind` + `threshold` off them.\n */\n\nimport type { AdversarialMutation } from '../rl/adversarial'\nimport type {\n Cell,\n Evaluation,\n Objective,\n ObjectiveContext,\n ProposeContext,\n Proposer,\n} from './types'\n\nconst clamp01 = (x: number): number => Math.max(0, Math.min(1, x))\n\n// ── proposers ─────────────────────────────────────────────────────────────────\n\n/**\n * Perturbation-based search: apply the cell's mutation operators to the current\n * elites + seeds, deduping by id. Elites first — mutating the most interesting\n * scenario found so far is what makes the search deepen across rounds.\n */\nexport function mutationProposer<S>(opts: {\n mutationsFor: (cell: Cell) => AdversarialMutation<S>[]\n scenarioId: (s: S) => string\n}): Proposer<S> {\n return async (ctx: ProposeContext<S>): Promise<S[]> => {\n const mutations = opts.mutationsFor(ctx.cell)\n const parents = [...ctx.elites, ...ctx.seeds]\n const seen = new Set(parents.map(opts.scenarioId))\n const out: S[] = []\n for (const parent of parents) {\n if (out.length >= ctx.count) break\n for (const m of mutations) {\n const children = await m.mutate(parent, ctx.rng)\n for (const child of children) {\n const id = opts.scenarioId(child)\n if (seen.has(id)) continue\n seen.add(id)\n out.push(child)\n if (out.length >= ctx.count) break\n }\n if (out.length >= ctx.count) break\n }\n }\n return out\n }\n}\n\n// ── objectives ────────────────────────────────────────────────────────────────\n\n/** Adversarial: a low headline score is interesting — find where the agent fails. */\nexport function adversarialObjective(threshold = 0.5): Objective {\n return { kind: 'adversarial', threshold, interest: (ev) => clamp01(1 - ev.score) }\n}\n\nfunction hamming(\n a: Record<string, string> | undefined,\n b: Record<string, string> | undefined,\n): number {\n if (!a || !b) return 1\n const keys = new Set([...Object.keys(a), ...Object.keys(b)])\n if (keys.size === 0) return 0\n let diff = 0\n for (const k of keys) if (a[k] !== b[k]) diff++\n return diff / keys.size\n}\n\n/**\n * Novelty: interesting when far from the archive in score AND measured behavior\n * descriptor — quality-diversity's diversity pressure; drives corpus growth\n * rather than re-finding the same hole.\n */\nexport function noveltyObjective(threshold = 0.3): Objective {\n return {\n kind: 'novelty',\n threshold,\n interest: (ev: Evaluation, ctx: ObjectiveContext) => {\n const scoreNovelty =\n ctx.archiveScores.length === 0\n ? 1\n : Math.min(...ctx.archiveScores.map((s) => Math.abs(s - ev.score)))\n const descNovelty =\n ctx.archiveDescriptors.length === 0\n ? 1\n : Math.min(...ctx.archiveDescriptors.map((d) => hamming(d, ev.descriptor)))\n return clamp01(0.5 * scoreNovelty + 0.5 * descNovelty)\n },\n }\n}\n","/**\n * The exploration engine — a stateful session over a behavior space.\n *\n * Each `step()`: allocate budget across INPUT cells (floor first, then variance\n * steering toward the least-certain cells), propose candidates (the proposer\n * reads current elites + findings, so the search deepens generationally),\n * evaluate with bounded concurrency, archive the most interesting scenario per\n * input×measured bin, and admit notable candidates that pass the validity gates.\n * `run()` loops to budget. `coverage()`/`findings()`/`capsule()` read live state —\n * the surface `makeExploreTools` exposes so an agent can drive the session.\n *\n * One evaluation log (`EvalRecord[]`) is the source of truth; allocation\n * observations and coverage are projections of it.\n */\n\nimport { ValidationError } from '../errors'\nimport { varianceBasedCurriculum } from '../rl/active-curriculum'\nimport { buildCapsule } from './capsule'\nimport type { EvalRecord } from './cube'\nimport { enumerateCells } from './cube'\nimport { adversarialObjective } from './policies'\nimport type {\n ArchiveEntry,\n CapsuleData,\n Cell,\n CoverageCell,\n Evaluation,\n ExploreOptions,\n Finding,\n Objective,\n} from './types'\n\nasync function pMap<T>(\n items: T[],\n fn: (item: T) => Promise<void>,\n concurrency: number,\n signal?: AbortSignal,\n): Promise<void> {\n let i = 0\n const workers = Array.from(\n { length: Math.max(1, Math.min(concurrency, items.length)) },\n async () => {\n while (i < items.length) {\n if (signal?.aborted) return\n const item = items[i++]\n if (item === undefined) return\n await fn(item)\n }\n },\n )\n await Promise.all(workers)\n}\n\nexport class BehaviorExplorer<S> {\n private readonly cells: Cell[]\n private readonly cellById: Map<string, Cell>\n private readonly objective: Objective\n private readonly threshold: number\n private readonly floorPerCell: number\n private readonly perRoundBudget: number\n\n /** The single evaluation log — coverage + allocation are projections of it. */\n private readonly log: Array<EvalRecord & { scenarioId: string }> = []\n /** binId (input × measured coords) → the most interesting entry seen. */\n private readonly archiveByBin = new Map<string, ArchiveEntry<S>>()\n private readonly _findings: Finding<S>[] = []\n private runsUsed = 0\n private candidateFindings = 0\n private rngState: number\n /** Accumulated KNOWN dollars — unknown-cost runs never inflate it. */\n private spentKnownUsd = 0\n private costUnknownRuns = 0\n\n constructor(private readonly opts: ExploreOptions<S>) {\n this.cells = enumerateCells(opts.space)\n if (this.cells.length === 0)\n throw new Error('BehaviorExplorer: space has no cells — every axis needs ≥1 value')\n if (opts.costBudgetUsd !== undefined) {\n if (\n typeof opts.costBudgetUsd !== 'number' ||\n !Number.isFinite(opts.costBudgetUsd) ||\n opts.costBudgetUsd < 0\n ) {\n throw new RangeError(\n `BehaviorExplorer: costBudgetUsd must be a nonnegative finite number, got ${String(opts.costBudgetUsd)}`,\n )\n }\n }\n if (!opts.costOf && (opts.costBudgetUsd !== undefined || opts.ledger || opts.onCost)) {\n throw new ValidationError(\n 'BehaviorExplorer: costBudgetUsd/ledger/onCost require costOf — the explorer ' +\n 'cannot know run cost without it; supply costOf or drop the cost options',\n )\n }\n this.cellById = new Map(this.cells.map((c) => [c.id, c]))\n this.objective = opts.objective ?? adversarialObjective(0.5)\n this.threshold = this.objective.threshold ?? 0.5\n this.floorPerCell = opts.floorPerCell ?? 2\n this.perRoundBudget = Math.max(\n this.cells.length * this.floorPerCell,\n Math.ceil(opts.budget / 4),\n )\n this.rngState = (opts.seed ?? 1) >>> 0\n }\n\n // mulberry32 — deterministic per session.\n private rng = (): number => {\n this.rngState = (this.rngState + 0x6d2b79f5) | 0\n let t = this.rngState\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n private binId(cell: Cell, descriptor: Record<string, string> | undefined): string {\n if (!descriptor || Object.keys(descriptor).length === 0) return cell.id\n const measured = Object.keys(descriptor)\n .sort()\n .map((k) => `${k}=${descriptor[k]}`)\n .join('|')\n return `${cell.id}|${measured}`\n }\n\n private allocate(budget: number): Array<{ cellId: string; count: number }> {\n if ((this.opts.allocation ?? 'variance') === 'uniform') {\n const per = Math.max(this.floorPerCell, Math.floor(budget / this.cells.length))\n return this.cells.map((c) => ({ cellId: c.id, count: per }))\n }\n return varianceBasedCurriculum(\n this.log.map((r) => ({\n variantId: r.cell.id,\n scenarioId: r.scenarioId,\n score: r.ev.score,\n pass: r.ev.valid && r.ev.score >= 0.5,\n })),\n this.cells.map((c) => ({ variantId: c.id, scenarioId: '*' })),\n { budget, floorPerCell: this.floorPerCell },\n ).map((a) => ({ cellId: a.variantId, count: a.count }))\n }\n\n private objectiveContext() {\n const entries = [...this.archiveByBin.values()]\n return {\n archiveScores: entries.map((e) => e.evaluation.score),\n archiveDescriptors: entries.map((e) => e.evaluation.descriptor),\n }\n }\n\n /** Mirrors control-runtime: stop once accumulated KNOWN cost ≥ the ceiling. */\n private costExhausted(): boolean {\n return this.opts.costBudgetUsd !== undefined && this.spentKnownUsd >= this.opts.costBudgetUsd\n }\n\n /** Fold one run's cost in: null counts as unknown (never $0); a known cost\n * accrues toward the budget, lands in the ledger, and fires `onCost`. */\n private recordRunCost(scenario: S, cell: Cell, ev: Evaluation): void {\n if (!this.opts.costOf) return\n const cost = this.opts.costOf(scenario, cell, ev)\n if (cost === null) {\n this.costUnknownRuns++\n return\n }\n if (typeof cost.usd !== 'number' || !Number.isFinite(cost.usd) || cost.usd < 0) {\n throw new RangeError(\n `BehaviorExplorer: costOf returned an invalid usd (${String(cost?.usd)}) — ` +\n 'return null when cost is unknown, never a fabricated number',\n )\n }\n this.spentKnownUsd += cost.usd\n this.opts.ledger?.record({\n model: cost.model ?? 'unattributed',\n channel: 'agent',\n usage: { inputTokens: 0, outputTokens: 0 },\n actualCostUsd: cost.usd,\n tags: { target: this.opts.target, cell: cell.id },\n })\n this.opts.onCost?.({ usd: cost.usd, channel: 'agent' })\n }\n\n /** Elites whose INPUT cell matches — what the proposer mutates/deepens from. */\n private elitesFor(cellId: string): S[] {\n const out: S[] = []\n for (const e of this.archiveByBin.values()) if (e.cell.id === cellId) out.push(e.scenario)\n return out\n }\n\n /** One allocate → propose → evaluate → gate → archive round. */\n async step(): Promise<{ runs: number; findings: Finding<S>[] }> {\n const remaining = this.opts.budget - this.runsUsed\n if (remaining <= 0 || this.costExhausted() || this.opts.signal?.aborted)\n return { runs: 0, findings: [] }\n\n const allocations = this.allocate(Math.min(this.perRoundBudget, remaining))\n const newFindings: Finding<S>[] = []\n let runsThisStep = 0\n\n for (const alloc of allocations) {\n if (this.runsUsed >= this.opts.budget || this.costExhausted() || this.opts.signal?.aborted)\n break\n const cell = this.cellById.get(alloc.cellId)\n if (!cell) continue\n const cap = Math.min(alloc.count, this.opts.budget - this.runsUsed)\n if (cap <= 0) continue\n this.opts.onProgress?.({ type: 'cell-allocated', cell, count: cap })\n\n const seeds = await this.opts.seedsFor(cell)\n const elites = this.elitesFor(cell.id)\n const proposed = await this.opts.proposer({\n cell,\n seeds,\n elites,\n findings: this._findings,\n count: cap,\n rng: this.rng,\n })\n // Cold cells evaluate their seeds first (the coverage floor); warm cells\n // trust the proposer, which already saw the elites.\n const cold = this.log.every((r) => r.cell.id !== cell.id)\n const toEval = [...(cold ? seeds : []), ...proposed].slice(0, cap)\n\n await pMap(\n toEval,\n async (scenario) => {\n if (\n this.runsUsed >= this.opts.budget ||\n this.costExhausted() ||\n this.opts.signal?.aborted\n )\n return\n const ev = await this.opts.evaluate(scenario, cell)\n this.runsUsed++\n runsThisStep++\n this.recordRunCost(scenario, cell, ev)\n const interest = this.objective.interest(ev, this.objectiveContext())\n this.log.push({ cell, ev, interest, scenarioId: this.opts.scenarioId(scenario) })\n this.opts.onProgress?.({ type: 'evaluated', cell, scenario, evaluation: ev })\n\n const bin = this.binId(cell, ev.descriptor)\n const cur = this.archiveByBin.get(bin)\n if (!cur || interest > cur.interest)\n this.archiveByBin.set(bin, { binId: bin, cell, scenario, evaluation: ev, interest })\n\n if (interest < this.threshold) return\n this.candidateFindings++\n if (this.opts.gates?.isValid && !(await this.opts.gates.isValid(scenario, ev, cell)))\n return\n if (\n this.opts.gates?.isUncontaminated &&\n !(await this.opts.gates.isUncontaminated(scenario, ev, cell))\n )\n return\n\n const minimized = this.opts.minimize\n ? await this.opts.minimize(scenario, this.opts.evaluate, cell)\n : scenario\n const finding: Finding<S> = {\n id: this.opts.scenarioId(scenario),\n cell,\n scenario,\n minimized,\n text: this.opts.scenarioText?.(minimized),\n evaluation: ev,\n interest,\n objective: this.objective.kind,\n }\n this._findings.push(finding)\n newFindings.push(finding)\n this.opts.onProgress?.({ type: 'finding', finding })\n },\n this.opts.concurrency ?? 1,\n this.opts.signal,\n )\n }\n\n this.opts.onProgress?.({ type: 'round', runsUsed: this.runsUsed, budget: this.opts.budget })\n return { runs: runsThisStep, findings: newFindings }\n }\n\n /** Loop `step()` until the run or dollar budget is spent, the signal aborts,\n * or no progress is made. */\n async run(): Promise<CapsuleData<S>> {\n while (\n this.runsUsed < this.opts.budget &&\n !this.costExhausted() &&\n !this.opts.signal?.aborted\n ) {\n const { runs } = await this.step()\n if (runs === 0) break\n }\n return this.capsule()\n }\n\n coverage(): CoverageCell[] {\n return this.capsule().coverage\n }\n\n findings(): Finding<S>[] {\n return [...this._findings].sort((a, b) => b.interest - a.interest)\n }\n\n capsule(): CapsuleData<S> {\n return buildCapsule({\n target: this.opts.target,\n objective: this.objective.kind,\n cells: this.cells,\n log: this.log,\n threshold: this.threshold,\n archive: [...this.archiveByBin.values()],\n findings: this._findings,\n candidateFindings: this.candidateFindings,\n runsUsed: this.runsUsed,\n cost: this.opts.costOf\n ? { costUsd: this.spentKnownUsd, costUnknownRuns: this.costUnknownRuns }\n : undefined,\n })\n }\n}\n","/**\n * `fuzzAgent` — the adversarial batch preset over `BehaviorExplorer`.\n *\n * One call: explore the space to budget with the adversarial objective and\n * return the capsule. For agent-driven, incremental, or multi-objective use,\n * construct a `BehaviorExplorer` and drive it via `makeExploreTools`.\n */\n\nimport { BehaviorExplorer } from './explorer'\nimport { adversarialObjective } from './policies'\nimport type { CapsuleData, ExploreOptions } from './types'\n\nexport type FuzzAgentOptions<S> = Omit<ExploreOptions<S>, 'objective'> & {\n /** Score strictly below this is a candidate failure. Default 0.5. */\n failureThreshold?: number\n}\n\nexport async function fuzzAgent<S>(\n opts: FuzzAgentOptions<S>,\n): Promise<{ capsule: CapsuleData<S> }> {\n const { failureThreshold, ...rest } = opts\n const explorer = new BehaviorExplorer<S>({\n ...rest,\n objective: adversarialObjective(failureThreshold ?? 0.5),\n })\n return { capsule: await explorer.run() }\n}\n","/**\n * Validity gates — what separates a fuzzer from a slop generator.\n *\n * A notable candidate is admitted only when it is fair and reproducible. None of\n * these are on by default: the live wiring opts in, so reported findings carry\n * their proof.\n */\n\nimport type { Cell, Evaluation, Evaluator, ValidityGates } from './types'\n\n/** Combine gate sets; a candidate must pass every gate in every set. */\nexport function composeGates<S>(...sets: Array<ValidityGates<S> | undefined>): ValidityGates<S> {\n const present = sets.filter((s): s is ValidityGates<S> => s != null)\n return {\n isValid: async (scenario, ev, cell) => {\n for (const g of present) {\n if (g.isValid && !(await g.isValid(scenario, ev, cell))) return false\n }\n return true\n },\n isUncontaminated: async (scenario, ev, cell) => {\n for (const g of present) {\n if (g.isUncontaminated && !(await g.isUncontaminated(scenario, ev, cell))) return false\n }\n return true\n },\n }\n}\n\n/**\n * Reproducibility gate. Re-run the target on a meaning-preserving rephrase of the\n * flagged scenario; keep the finding only when the rephrase ALSO scores below the\n * threshold. A finding that flips under a cosmetic rewrite was keyed to surface\n * form, not the task — a false signal we must not report. Costs one extra\n * evaluation per candidate (candidates are rare, so cheap).\n */\nexport function perturbationStabilityGate<S>(opts: {\n evaluate: Evaluator<S>\n /** Produce a semantic-preserving rephrase. Return null to skip (treated as pass). */\n perturb: (scenario: S) => S | null\n /** Score strictly below this still counts as failing. Default 0.5. */\n failureThreshold?: number\n}): ValidityGates<S> {\n const threshold = opts.failureThreshold ?? 0.5\n return {\n isUncontaminated: async (scenario: S, _ev: Evaluation, cell: Cell) => {\n const rephrased = opts.perturb(scenario)\n if (rephrased == null) return true\n const re = await opts.evaluate(rephrased, cell)\n return re.score < threshold\n },\n }\n}\n\n/**\n * Severity-floor gate. Reject borderline candidates whose score sits in a band\n * just under the threshold — judge noise, not a real defect.\n */\nexport function severityFloorGate<S>(opts: {\n failureThreshold?: number\n margin?: number\n}): ValidityGates<S> {\n const threshold = opts.failureThreshold ?? 0.5\n const margin = opts.margin ?? 0.1\n return {\n isValid: (_scenario, ev: Evaluation) => ev.score <= threshold - margin,\n }\n}\n","/**\n * Agent-drivable surface over a live exploration session.\n *\n * Framework-neutral tool defs ({name, description, parameters: JSON Schema,\n * handler}) so the on-demand agent — not a batch script — drives the search:\n * step it, read coverage, inspect findings, render the capsule. Transport\n * encodings (OpenAI function shape, MCP) are one-line mappings the host owns.\n */\n\nimport { renderCapsuleHtml } from './capsule'\nimport type { BehaviorExplorer } from './explorer'\n\nexport interface ExploreToolDef {\n name: string\n description: string\n /** JSON Schema (draft-07+) for the arguments. */\n parameters: Record<string, unknown>\n handler: (args: unknown, ctx?: { signal?: AbortSignal }) => Promise<unknown>\n}\n\nconst NO_ARGS = { type: 'object', properties: {}, additionalProperties: false }\n\nexport function makeExploreTools<S>(explorer: BehaviorExplorer<S>): ExploreToolDef[] {\n return [\n {\n name: 'explore_step',\n description:\n 'Run one exploration round: allocate budget across cells, propose + evaluate scenarios, archive elites, admit gate-verified findings. Returns runs spent and new findings.',\n parameters: NO_ARGS,\n handler: async () => {\n const { runs, findings } = await explorer.step()\n return { runs, newFindings: findings.length, findings }\n },\n },\n {\n name: 'explore_coverage',\n description:\n 'Read the live coverage map: per planned cell — runs, robustness (null = uncovered), finding rate, per-dimension means.',\n parameters: NO_ARGS,\n handler: async () => explorer.coverage(),\n },\n {\n name: 'explore_findings',\n description: 'List gate-verified findings so far, sorted by descending interest.',\n parameters: {\n type: 'object',\n properties: { limit: { type: 'number', description: 'max findings to return' } },\n additionalProperties: false,\n },\n handler: async (args) => {\n const limit = (args as { limit?: number } | undefined)?.limit\n const all = explorer.findings()\n return typeof limit === 'number' ? all.slice(0, limit) : all\n },\n },\n {\n name: 'explore_capsule',\n description:\n 'Build the capsule artifact from the current session state. format \"data\" returns the structured CapsuleData; \"html\" returns the standalone page.',\n parameters: {\n type: 'object',\n properties: {\n format: { type: 'string', enum: ['data', 'html'] },\n generatedAt: { type: 'string', description: 'ISO timestamp to stamp into the page' },\n },\n additionalProperties: false,\n },\n handler: async (args) => {\n const a = (args ?? {}) as { format?: string; generatedAt?: string }\n const capsule = explorer.capsule()\n if (a.format === 'html') return renderCapsuleHtml(capsule, { generatedAt: a.generatedAt })\n return capsule\n },\n },\n ]\n}\n"],"mappings":"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","names":["cellId"]}
|
|
1
|
+
{"version":3,"sources":["../src/fuzz/cube.ts","../src/fuzz/capsule.ts","../src/fuzz/policies.ts","../src/fuzz/explorer.ts","../src/fuzz/fuzz-agent.ts","../src/fuzz/gates.ts","../src/fuzz/tools.ts"],"sourcesContent":["/**\n * Input-space tiling + coverage projection.\n *\n * Cells are the cartesian product of the input axes — the stratification plan,\n * enumerable up front so the planned-vs-covered denominator is honest. Coverage\n * is projected from the evaluation log: per cell, the full DISTRIBUTION of the\n * headline score, of each scored dimension, and of evaluation latency — a bare\n * mean hides outliers, so every aggregate carries its spread. Per-cell cost is\n * split known-dollars vs unknown-runs, never folded into a fabricated $0.\n */\n\nimport type { BehaviorSpace, Cell, CoverageCell, Distribution, Evaluation } from './types'\n\n/** One recorded evaluation — the unit coverage and the capsule are built from. */\nexport interface EvalRecord {\n cell: Cell\n ev: Evaluation\n /** The objective's interest score for this evaluation. */\n interest: number\n /** Evaluation wall-clock — engine-measured unless `ev.latencyMs` overrode it. */\n latencyMs: number\n /** Known dollars for this run. `null` = cost tracking was wired but this\n * run's cost was unknowable (counted apart). Absent = not tracked at all. */\n costUsd?: number | null\n}\n\n/** Enumerate every input cell (cartesian product of the axes), in stable order. */\nexport function enumerateCells(space: BehaviorSpace): Cell[] {\n if (space.axes.length === 0) return []\n let partials: Array<Record<string, string>> = [{}]\n for (const axis of space.axes) {\n const next: Array<Record<string, string>> = []\n for (const partial of partials) {\n for (const value of axis.values) next.push({ ...partial, [axis.name]: value })\n }\n partials = next\n }\n return partials.map((coords) => ({ id: cellId(space, coords), coords }))\n}\n\n/** Deterministic id for a coordinate map, e.g. `matterType=nda|difficulty=hard`. */\nexport function cellId(space: BehaviorSpace, coords: Record<string, string>): string {\n return space.axes.map((a) => `${a.name}=${coords[a.name]}`).join('|')\n}\n\n/** Nearest-rank percentile on a pre-sorted ascending sample. */\nfunction percentile(sorted: number[], p: number): number {\n const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1))\n return sorted[idx] as number\n}\n\n/** Summarize a sample. Throws on an empty sample — callers represent \"no data\"\n * as `null`, never as a zeroed distribution. */\nexport function distribution(values: number[]): Distribution {\n if (values.length === 0)\n throw new Error('distribution: empty sample — represent missing data as null, not zeros')\n const sorted = [...values].sort((a, b) => a - b)\n const mean = sorted.reduce((a, b) => a + b, 0) / sorted.length\n return {\n mean,\n median: percentile(sorted, 0.5),\n p90: percentile(sorted, 0.9),\n min: sorted[0] as number,\n max: sorted[sorted.length - 1] as number,\n n: sorted.length,\n }\n}\n\n/**\n * Project the evaluation log into the per-input-cell coverage map. A cell with\n * no evaluations reports `score: null` (honestly uncovered), never zeros.\n */\nexport function buildCoverage(cells: Cell[], log: EvalRecord[], threshold: number): CoverageCell[] {\n const byCell = new Map<string, EvalRecord[]>()\n for (const r of log) {\n const arr = byCell.get(r.cell.id) ?? []\n arr.push(r)\n byCell.set(r.cell.id, arr)\n }\n return cells.map((cell) => {\n const recs = byCell.get(cell.id) ?? []\n const runs = recs.length\n if (runs === 0)\n return { cell, runs: 0, score: null, findingRate: 0, dimensions: {}, latencyMs: null }\n\n const score = distribution(recs.map((r) => r.ev.score))\n const latencyMs = distribution(recs.map((r) => r.latencyMs))\n const findingRate = recs.filter((r) => r.interest >= threshold).length / runs\n\n const dimSamples: Record<string, number[]> = {}\n for (const r of recs) {\n for (const [k, v] of Object.entries(r.ev.scores ?? {})) {\n ;(dimSamples[k] ??= []).push(v)\n }\n }\n const dimensions: Record<string, Distribution> = {}\n for (const [k, xs] of Object.entries(dimSamples)) dimensions[k] = distribution(xs)\n\n // Cost fields appear only when tracking was wired: known dollars sum, and\n // tracked-but-unknown runs counted apart — never folded in as $0.\n const tracked = recs.filter((r) => r.costUsd !== undefined)\n const known = tracked.filter((r) => r.costUsd !== null)\n const cost =\n tracked.length > 0\n ? {\n costUsd: known.reduce((a, r) => a + (r.costUsd as number), 0),\n ...(tracked.length > known.length\n ? { costUnknownRuns: tracked.length - known.length }\n : {}),\n }\n : {}\n\n return { cell, runs, score, findingRate, dimensions, latencyMs, ...cost }\n })\n}\n","/**\n * The capsule — the artifact every exploration produces.\n *\n * `buildCapsule` assembles coverage + verified findings + the QD archive into a\n * pure `CapsuleData` (no clock, no I/O — deterministic and snapshot-testable).\n * `renderCapsuleHtml` turns it into a standalone page: the input-cell heat-map\n * (planned vs covered), per-dimension weakness chips, and the minimized finding\n * exemplars. One artifact — the hardening map and the shareable proof object.\n */\n\nimport type { EvalRecord } from './cube'\nimport { buildCoverage, distribution } from './cube'\nimport type { ArchiveEntry, CapsuleData, Cell, CoverageCell, Distribution, Finding } from './types'\n\nexport interface BuildCapsuleInput<S> {\n target: string\n objective: string\n cells: Cell[]\n log: EvalRecord[]\n /** The objective's notable threshold — drives findingRate. */\n threshold: number\n archive: ArchiveEntry<S>[]\n findings: Finding<S>[]\n candidateFindings: number\n runsUsed: number\n /** Known-dollar / unknown-run split — present only when cost tracking was\n * wired; the capsule never fabricates a $0 total. */\n cost?: { costUsd: number; costUnknownRuns: number }\n /** Evaluations that threw — infra outcomes, never folded into robustness. */\n evalErrors: number\n /** Set when the consecutive-error circuit breaker stopped the run early. */\n stoppedEarly?: { reason: 'eval-errors'; detail: string }\n}\n\nexport function buildCapsule<S>(input: BuildCapsuleInput<S>): CapsuleData<S> {\n const coverage = buildCoverage(input.cells, input.log, input.threshold)\n const covered = coverage.filter((c) => c.runs > 0)\n // Cells weigh equally: variance steering sends more runs to weak cells, so a\n // run-weighted average would bias the headline low.\n const robustness =\n covered.length === 0 ? null : distribution(covered.map((c) => (c.score as Distribution).mean))\n const latencyMs = input.log.length === 0 ? null : distribution(input.log.map((r) => r.latencyMs))\n // Measured-descriptor bins beyond the bare input cell — observed, never planned.\n const behaviorBinsObserved = input.archive.filter((e) => e.binId !== e.cell.id).length\n\n return {\n target: input.target,\n objective: input.objective,\n coverage,\n findings: [...input.findings].sort((a, b) => b.interest - a.interest),\n archive: [...input.archive].sort((a, b) => b.interest - a.interest),\n stats: {\n totalRuns: input.runsUsed,\n cellsTotal: input.cells.length,\n cellsCovered: covered.length,\n behaviorBinsObserved,\n candidateFindings: input.candidateFindings,\n verifiedFindings: input.findings.length,\n robustness,\n latencyMs,\n ...(input.cost\n ? { costUsd: input.cost.costUsd, costUnknownRuns: input.cost.costUnknownRuns }\n : {}),\n evalErrors: input.evalErrors,\n ...(input.stoppedEarly ? { stoppedEarly: input.stoppedEarly } : {}),\n },\n }\n}\n\n// ── HTML capsule ──────────────────────────────────────────────────────────────\n\nfunction esc(s: string): string {\n return s.replace(\n /[&<>\"]/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c] as string,\n )\n}\n\n/** red (0) → amber (.5) → green (1); uncovered cells render gray. */\nfunction robustnessColor(r: number | null): string {\n if (r == null) return '#2a2a2e'\n return `hsl(${Math.round(r * 120)} 70% 42%)`\n}\n\nfunction pct(x: number): string {\n return `${Math.round(x * 100)}%`\n}\n\nfunction deriveAxes(coverage: CoverageCell[]): Array<{ name: string; values: string[] }> {\n const order: string[] = []\n const seen = new Map<string, Set<string>>()\n for (const c of coverage) {\n for (const [k, v] of Object.entries(c.cell.coords)) {\n if (!seen.has(k)) {\n seen.set(k, new Set())\n order.push(k)\n }\n seen.get(k)?.add(v)\n }\n }\n return order.map((name) => ({ name, values: [...(seen.get(name) ?? [])] }))\n}\n\n/** The weakest dimension chip for a cell, e.g. `safety 32%` — shown when scores exist. */\nfunction weakestDim(c: CoverageCell): string {\n const entries = Object.entries(c.dimensions).map(([k, d]) => [k, d.mean] as [string, number])\n if (entries.length === 0) return ''\n const sorted = entries.sort((a, b) => a[1] - b[1])\n const w = sorted[0]\n if (!w) return ''\n return `<span class=\"dim\">${esc(w[0])} ${pct(w[1])}</span>`\n}\n\nfunction heatmapHtml(coverage: CoverageCell[]): string {\n const axes = deriveAxes(coverage)\n const byId = new Map(coverage.map((c) => [c.cell.id, c]))\n const tile = (c: CoverageCell | undefined, label: string): string => {\n const r = c?.score?.mean ?? null\n const title = c?.score\n ? `${pct(c.score.mean)} robust (median ${pct(c.score.median)}, min ${pct(c.score.min)}) · ${c.runs} runs · ${pct(c.findingRate)} flagged${c.latencyMs ? ` · ${(c.latencyMs.median / 1000).toFixed(1)}s median` : ''}${c.costUsd !== undefined ? ` · $${c.costUsd.toFixed(2)}` : ''}`\n : 'not covered'\n return `<div class=\"tile\" style=\"background:${robustnessColor(r)}\" title=\"${esc(title)}\">${label ? `<span class=\"tl\">${esc(label)}</span>` : ''}<span class=\"tv\">${c && r != null ? pct(r) : '—'}</span>${c ? weakestDim(c) : ''}</div>`\n }\n\n const rowAxis = axes[0]\n const colAxis = axes[1]\n if (axes.length === 2 && rowAxis && colAxis) {\n const head = `<tr><th></th>${colAxis.values.map((v) => `<th>${esc(v)}</th>`).join('')}</tr>`\n const rows = rowAxis.values\n .map((rv) => {\n const cells = colAxis.values\n .map((cv) => {\n const id = `${rowAxis.name}=${rv}|${colAxis.name}=${cv}`\n return `<td>${tile(byId.get(id), '')}</td>`\n })\n .join('')\n return `<tr><th class=\"rh\">${esc(rv)}</th>${cells}</tr>`\n })\n .join('')\n return `<div class=\"axis-label\">rows: <b>${esc(rowAxis.name)}</b> · cols: <b>${esc(colAxis.name)}</b></div><table class=\"heat\">${head}${rows}</table>`\n }\n\n const sorted = [...coverage].sort((a, b) => (a.score?.mean ?? 2) - (b.score?.mean ?? 2))\n return `<div class=\"grid\">${sorted.map((c) => tile(c, Object.values(c.cell.coords).join(' · '))).join('')}</div>`\n}\n\nfunction findingsHtml<S>(findings: Finding<S>[], limit: number): string {\n if (findings.length === 0)\n return `<p class=\"none\">No verified findings — the target held across every covered cell.</p>`\n return findings\n .slice(0, limit)\n .map((f) => {\n const coords = Object.entries(f.cell.coords)\n .map(([k, v]) => `${k}:${v}`)\n .join(' · ')\n const labels = (f.evaluation.labels ?? [])\n .map((l) => `<span class=\"fclass\">${esc(l)}</span>`)\n .join('')\n const dims = Object.entries(f.evaluation.scores ?? {})\n .sort((a, b) => a[1] - b[1])\n .slice(0, 3)\n .map(([k, v]) => `<span class=\"dim\">${esc(k)} ${pct(v)}</span>`)\n .join('')\n return `<div class=\"fail\"><div class=\"fmeta\"><span class=\"fcell\">${esc(coords)}</span>${labels}<span class=\"fsev\">interest ${pct(f.interest)}</span></div><div class=\"sevbar\"><div class=\"sevfill\" style=\"width:${pct(f.interest)}\"></div></div><div class=\"ftext\">${esc(f.text ?? '(scenario text not captured)')}</div>${dims ? `<div class=\"fdims\">${dims}</div>` : ''}</div>`\n })\n .join('')\n}\n\nexport interface RenderCapsuleOptions {\n /** Max finding exemplars to show. Default 8. */\n maxFindings?: number\n /** ISO timestamp to stamp into the page (keeps the pure capsule clock-free). */\n generatedAt?: string\n}\n\n/** Render a self-contained HTML capsule — heat-map + per-dimension chips + verified findings. */\nexport function renderCapsuleHtml<S>(\n capsule: CapsuleData<S>,\n opts: RenderCapsuleOptions = {},\n): string {\n const s = capsule.stats\n const kpi = (label: string, value: string, accent = '#e6e6e6'): string =>\n `<div class=\"kpi\"><div class=\"kv\" style=\"color:${accent}\">${esc(value)}</div><div class=\"kl\">${esc(label)}</div></div>`\n const lift = capsule.lift\n ? kpi(\n 'hardening lift',\n `${capsule.lift.before.toFixed(2)} → ${capsule.lift.after.toFixed(2)}`,\n '#5ad17a',\n )\n : ''\n // Cost KPI only when tracking was wired — an untracked run never shows $0.\n // Unpriced runs are named in the label (amber): the total is a lower bound.\n const cost =\n s.costUsd !== undefined\n ? kpi(\n s.costUnknownRuns ? `cost · ${s.costUnknownRuns} runs unpriced` : 'cost',\n `$${s.costUsd.toFixed(2)}`,\n s.costUnknownRuns ? '#e5c07b' : '#e6e6e6',\n )\n : ''\n const stamp = opts.generatedAt ?? capsule.generatedAt ?? ''\n\n return `<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${esc(capsule.objective)} capsule — ${esc(capsule.target)}</title>\n<style>\n:root{color-scheme:dark}\n*{box-sizing:border-box}\nbody{margin:0;background:#0c0c0f;color:#e6e6e6;font:14px/1.5 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}\n.wrap{max-width:980px;margin:0 auto;padding:40px 24px}\nh1{font-size:22px;margin:0 0 2px;letter-spacing:-.01em}\n.sub{color:#8a8a93;font-size:13px;margin-bottom:28px}\n.kpis{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:32px}\n.kpi{background:#16161b;border:1px solid #24242b;border-radius:12px;padding:14px 18px;min-width:120px}\n.kv{font-size:24px;font-weight:650;letter-spacing:-.02em}\n.kl{color:#8a8a93;font-size:12px;margin-top:2px}\nh2{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:#8a8a93;margin:34px 0 14px}\n.axis-label{color:#8a8a93;font-size:12px;margin-bottom:10px}\ntable.heat{border-collapse:separate;border-spacing:6px}\ntable.heat th{font-weight:500;color:#a8a8b0;font-size:12px;padding:4px 8px;text-align:center}\ntable.heat th.rh{text-align:right}\n.tile{position:relative;width:104px;height:66px;border-radius:10px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:1px;color:#06120a;font-weight:600}\n.tile .tv{font-size:17px}\n.tile .tl{font-size:10px;font-weight:600;opacity:.9;padding:0 6px;text-align:center}\n.tile .dim{font-size:9px;font-weight:600;opacity:.85;background:rgba(0,0,0,.22);padding:0 6px;border-radius:999px}\n.grid{display:flex;flex-wrap:wrap;gap:8px}\n.grid .tile{width:138px;height:74px}\n.fail{background:#16161b;border:1px solid #24242b;border-left:3px solid #d1495b;border-radius:10px;padding:12px 14px;margin-bottom:10px}\n.fmeta{display:flex;gap:10px;align-items:center;font-size:12px;color:#a8a8b0;margin-bottom:8px}\n.fcell{color:#cfcfd6}\n.fclass{background:#2a1a1d;color:#e58a96;padding:1px 8px;border-radius:999px;font-size:11px}\n.fsev{margin-left:auto;color:#e58a96}\n.sevbar{height:4px;background:#24242b;border-radius:2px;overflow:hidden;margin-bottom:10px}\n.sevfill{height:100%;background:#d1495b}\n.ftext{font-size:13px;color:#d8d8df;white-space:pre-wrap}\n.fdims{display:flex;gap:6px;margin-top:8px}\n.fdims .dim{background:#1d2530;color:#9fc1e8;padding:1px 8px;border-radius:999px;font-size:11px}\n.none{color:#5ad17a}\n.foot{color:#5a5a63;font-size:11px;margin-top:36px}\n</style></head><body><div class=\"wrap\">\n<h1>${esc(capsule.objective)} exploration · ${esc(capsule.target)}</h1>\n<div class=\"sub\">${s.totalRuns} scenarios across ${s.cellsCovered}/${s.cellsTotal} planned cells${s.behaviorBinsObserved > 0 ? ` · ${s.behaviorBinsObserved} measured behavior bins` : ''}${stamp ? ` · ${esc(stamp)}` : ''}</div>\n<div class=\"kpis\">\n${s.robustness ? kpi('robustness', `${pct(s.robustness.mean)}`, s.robustness.mean < 0.6 ? '#e58a96' : '#5ad17a') : ''}\n${s.robustness ? kpi('cell spread', `${pct(s.robustness.min)}–${pct(s.robustness.max)}`) : ''}\n${s.latencyMs ? kpi('median latency', `${(s.latencyMs.median / 1000).toFixed(1)}s`, s.latencyMs.p90 > 4 * s.latencyMs.median ? '#e5b566' : '#e6e6e6') : ''}\n${kpi('verified findings', String(s.verifiedFindings), s.verifiedFindings > 0 ? '#e58a96' : '#5ad17a')}\n${kpi('cells covered', `${s.cellsCovered}/${s.cellsTotal}`)}\n${kpi('scenarios run', String(s.totalRuns))}\n${cost}\n${s.evalErrors > 0 ? kpi('eval errors', String(s.evalErrors), '#e5b566') : ''}\n${lift}\n</div>\n${s.stoppedEarly ? `<div class=\"sub\" style=\"color:#e5b566\">stopped early: ${esc(s.stoppedEarly.detail)} — coverage below reflects the completed portion only</div>` : ''}\n<h2>Coverage map</h2>\n${heatmapHtml(capsule.coverage)}\n<h2>Verified findings${s.candidateFindings > s.verifiedFindings ? ` · ${s.verifiedFindings} of ${s.candidateFindings} candidates passed the validity gates` : ''}</h2>\n${findingsHtml(capsule.findings, opts.maxFindings ?? 8)}\n<div class=\"foot\">Findings are gate-verified: each is a fair, answerable task that reproduces under a meaning-preserving rephrase, minimized to the smallest trigger.</div>\n</div></body></html>`\n}\n","/**\n * Shipped policies for the exploration engine.\n *\n * `Proposer` is a plain function type — an agent running a generator skill IS a\n * proposer (`(ctx) => dispatchToSkill(ctx)`), no wrapper needed. `mutationProposer`\n * builds the deterministic, LLM-free one from mutation operators. Objectives are\n * interfaces because the engine reads `kind` + `threshold` off them.\n */\n\nimport type { AdversarialMutation } from '../rl/adversarial'\nimport type {\n Cell,\n Evaluation,\n Objective,\n ObjectiveContext,\n ProposeContext,\n Proposer,\n} from './types'\n\nconst clamp01 = (x: number): number => Math.max(0, Math.min(1, x))\n\n// ── proposers ─────────────────────────────────────────────────────────────────\n\n/**\n * Perturbation-based search: apply the cell's mutation operators to the current\n * elites + seeds, deduping by id. Elites first — mutating the most interesting\n * scenario found so far is what makes the search deepen across rounds.\n */\nexport function mutationProposer<S>(opts: {\n mutationsFor: (cell: Cell) => AdversarialMutation<S>[]\n scenarioId: (s: S) => string\n}): Proposer<S> {\n return async (ctx: ProposeContext<S>): Promise<S[]> => {\n const mutations = opts.mutationsFor(ctx.cell)\n const parents = [...ctx.elites, ...ctx.seeds]\n const seen = new Set(parents.map(opts.scenarioId))\n const out: S[] = []\n for (const parent of parents) {\n if (out.length >= ctx.count) break\n for (const m of mutations) {\n const children = await m.mutate(parent, ctx.rng)\n for (const child of children) {\n const id = opts.scenarioId(child)\n if (seen.has(id)) continue\n seen.add(id)\n out.push(child)\n if (out.length >= ctx.count) break\n }\n if (out.length >= ctx.count) break\n }\n }\n return out\n }\n}\n\n// ── objectives ────────────────────────────────────────────────────────────────\n\n/** Adversarial: a low headline score is interesting — find where the agent fails. */\nexport function adversarialObjective(threshold = 0.5): Objective {\n return { kind: 'adversarial', threshold, interest: (ev) => clamp01(1 - ev.score) }\n}\n\nfunction hamming(\n a: Record<string, string> | undefined,\n b: Record<string, string> | undefined,\n): number {\n if (!a || !b) return 1\n const keys = new Set([...Object.keys(a), ...Object.keys(b)])\n if (keys.size === 0) return 0\n let diff = 0\n for (const k of keys) if (a[k] !== b[k]) diff++\n return diff / keys.size\n}\n\n/**\n * Novelty: interesting when far from the archive in score AND measured behavior\n * descriptor — quality-diversity's diversity pressure; drives corpus growth\n * rather than re-finding the same hole.\n */\nexport function noveltyObjective(threshold = 0.3): Objective {\n return {\n kind: 'novelty',\n threshold,\n interest: (ev: Evaluation, ctx: ObjectiveContext) => {\n const scoreNovelty =\n ctx.archiveScores.length === 0\n ? 1\n : Math.min(...ctx.archiveScores.map((s) => Math.abs(s - ev.score)))\n const descNovelty =\n ctx.archiveDescriptors.length === 0\n ? 1\n : Math.min(...ctx.archiveDescriptors.map((d) => hamming(d, ev.descriptor)))\n return clamp01(0.5 * scoreNovelty + 0.5 * descNovelty)\n },\n }\n}\n","/**\n * The exploration engine — a stateful session over a behavior space.\n *\n * Each `step()`: allocate budget across INPUT cells (floor first, then variance\n * steering toward the least-certain cells), propose candidates (the proposer\n * reads current elites + findings, so the search deepens generationally),\n * evaluate with bounded concurrency, archive the most interesting scenario per\n * input×measured bin, and admit notable candidates that pass the validity gates.\n * `run()` loops to budget. `coverage()`/`findings()`/`capsule()` read live state —\n * the surface `makeExploreTools` exposes so an agent can drive the session.\n *\n * One evaluation log (`EvalRecord[]`) is the source of truth; allocation\n * observations and coverage are projections of it.\n */\n\nimport { ValidationError } from '../errors'\nimport { varianceBasedCurriculum } from '../rl/active-curriculum'\nimport { buildCapsule } from './capsule'\nimport type { EvalRecord } from './cube'\nimport { enumerateCells } from './cube'\nimport { adversarialObjective } from './policies'\nimport type {\n ArchiveEntry,\n CapsuleData,\n Cell,\n CoverageCell,\n Evaluation,\n ExploreOptions,\n Finding,\n Objective,\n} from './types'\n\nasync function pMap<T>(\n items: T[],\n fn: (item: T) => Promise<void>,\n concurrency: number,\n signal?: AbortSignal,\n): Promise<void> {\n let i = 0\n const workers = Array.from(\n { length: Math.max(1, Math.min(concurrency, items.length)) },\n async () => {\n while (i < items.length) {\n if (signal?.aborted) return\n const item = items[i++]\n if (item === undefined) return\n await fn(item)\n }\n },\n )\n await Promise.all(workers)\n}\n\nexport class BehaviorExplorer<S> {\n private readonly cells: Cell[]\n private readonly cellById: Map<string, Cell>\n private readonly objective: Objective\n private readonly threshold: number\n private readonly floorPerCell: number\n private readonly perRoundBudget: number\n\n /** The single evaluation log — coverage + allocation are projections of it. */\n private readonly log: Array<EvalRecord & { scenarioId: string }> = []\n /** binId (input × measured coords) → the most interesting entry seen. */\n private readonly archiveByBin = new Map<string, ArchiveEntry<S>>()\n private readonly _findings: Finding<S>[] = []\n private runsUsed = 0\n private candidateFindings = 0\n private evalErrors = 0\n private consecutiveEvalErrors = 0\n private stoppedEarly: { reason: 'eval-errors'; detail: string } | undefined\n private rngState: number\n /** Accumulated KNOWN dollars — unknown-cost runs never inflate it. */\n private spentKnownUsd = 0\n private costUnknownRuns = 0\n\n constructor(private readonly opts: ExploreOptions<S>) {\n this.cells = enumerateCells(opts.space)\n if (this.cells.length === 0)\n throw new Error('BehaviorExplorer: space has no cells — every axis needs ≥1 value')\n if (opts.costBudgetUsd !== undefined) {\n if (\n typeof opts.costBudgetUsd !== 'number' ||\n !Number.isFinite(opts.costBudgetUsd) ||\n opts.costBudgetUsd < 0\n ) {\n throw new RangeError(\n `BehaviorExplorer: costBudgetUsd must be a nonnegative finite number, got ${String(opts.costBudgetUsd)}`,\n )\n }\n }\n if (!opts.costOf && (opts.costBudgetUsd !== undefined || opts.ledger || opts.onCost)) {\n throw new ValidationError(\n 'BehaviorExplorer: costBudgetUsd/ledger/onCost require costOf — the explorer ' +\n 'cannot know run cost without it; supply costOf or drop the cost options',\n )\n }\n this.cellById = new Map(this.cells.map((c) => [c.id, c]))\n this.objective = opts.objective ?? adversarialObjective(0.5)\n this.threshold = this.objective.threshold ?? 0.5\n this.floorPerCell = opts.floorPerCell ?? 2\n this.perRoundBudget = Math.max(\n this.cells.length * this.floorPerCell,\n Math.ceil(opts.budget / 4),\n )\n this.rngState = (opts.seed ?? 1) >>> 0\n }\n\n // mulberry32 — deterministic per session.\n private rng = (): number => {\n this.rngState = (this.rngState + 0x6d2b79f5) | 0\n let t = this.rngState\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n private binId(cell: Cell, descriptor: Record<string, string> | undefined): string {\n if (!descriptor || Object.keys(descriptor).length === 0) return cell.id\n const measured = Object.keys(descriptor)\n .sort()\n .map((k) => `${k}=${descriptor[k]}`)\n .join('|')\n return `${cell.id}|${measured}`\n }\n\n private allocate(budget: number): Array<{ cellId: string; count: number }> {\n if ((this.opts.allocation ?? 'variance') === 'uniform') {\n const per = Math.max(this.floorPerCell, Math.floor(budget / this.cells.length))\n return this.cells.map((c) => ({ cellId: c.id, count: per }))\n }\n return varianceBasedCurriculum(\n this.log.map((r) => ({\n variantId: r.cell.id,\n scenarioId: r.scenarioId,\n score: r.ev.score,\n pass: r.ev.valid && r.ev.score >= 0.5,\n })),\n this.cells.map((c) => ({ variantId: c.id, scenarioId: '*' })),\n { budget, floorPerCell: this.floorPerCell },\n ).map((a) => ({ cellId: a.variantId, count: a.count }))\n }\n\n private objectiveContext() {\n const entries = [...this.archiveByBin.values()]\n return {\n archiveScores: entries.map((e) => e.evaluation.score),\n archiveDescriptors: entries.map((e) => e.evaluation.descriptor),\n }\n }\n\n /** Mirrors control-runtime: stop once accumulated KNOWN cost ≥ the ceiling. */\n private costExhausted(): boolean {\n return this.opts.costBudgetUsd !== undefined && this.spentKnownUsd >= this.opts.costBudgetUsd\n }\n\n /** Fold one run's cost in: null counts as unknown (never $0); a known cost\n * accrues toward the budget, lands in the ledger, and fires `onCost`. */\n /** Returns the run's known cost, `null` when tracked-but-unknown, `undefined`\n * when cost tracking is not wired — the log row mirrors this exactly. */\n private recordRunCost(scenario: S, cell: Cell, ev: Evaluation): number | null | undefined {\n if (!this.opts.costOf) return undefined\n const cost = this.opts.costOf(scenario, cell, ev)\n if (cost === null) {\n this.costUnknownRuns++\n return null\n }\n if (typeof cost.usd !== 'number' || !Number.isFinite(cost.usd) || cost.usd < 0) {\n throw new RangeError(\n `BehaviorExplorer: costOf returned an invalid usd (${String(cost?.usd)}) — ` +\n 'return null when cost is unknown, never a fabricated number',\n )\n }\n this.spentKnownUsd += cost.usd\n this.opts.ledger?.record({\n model: cost.model ?? 'unattributed',\n channel: 'agent',\n usage: { inputTokens: 0, outputTokens: 0 },\n actualCostUsd: cost.usd,\n tags: { target: this.opts.target, cell: cell.id },\n })\n this.opts.onCost?.({ usd: cost.usd, channel: 'agent' })\n return cost.usd\n }\n\n /** Elites whose INPUT cell matches — what the proposer mutates/deepens from. */\n private elitesFor(cellId: string): S[] {\n const out: S[] = []\n for (const e of this.archiveByBin.values()) if (e.cell.id === cellId) out.push(e.scenario)\n return out\n }\n\n /** One allocate → propose → evaluate → gate → archive round. */\n async step(): Promise<{ runs: number; findings: Finding<S>[] }> {\n const remaining = this.opts.budget - this.runsUsed\n if (remaining <= 0 || this.costExhausted() || this.opts.signal?.aborted)\n return { runs: 0, findings: [] }\n\n const allocations = this.allocate(Math.min(this.perRoundBudget, remaining))\n const newFindings: Finding<S>[] = []\n let runsThisStep = 0\n\n for (const alloc of allocations) {\n if (\n this.runsUsed >= this.opts.budget ||\n this.costExhausted() ||\n this.stoppedEarly !== undefined ||\n this.opts.signal?.aborted\n )\n break\n const cell = this.cellById.get(alloc.cellId)\n if (!cell) continue\n const cap = Math.min(alloc.count, this.opts.budget - this.runsUsed)\n if (cap <= 0) continue\n this.opts.onProgress?.({ type: 'cell-allocated', cell, count: cap })\n\n const seeds = await this.opts.seedsFor(cell)\n const elites = this.elitesFor(cell.id)\n const proposed = await this.opts.proposer({\n cell,\n seeds,\n elites,\n findings: this._findings,\n count: cap,\n rng: this.rng,\n })\n // Cold cells evaluate their seeds first (the coverage floor); warm cells\n // trust the proposer, which already saw the elites.\n const cold = this.log.every((r) => r.cell.id !== cell.id)\n const toEval = [...(cold ? seeds : []), ...proposed].slice(0, cap)\n\n await pMap(\n toEval,\n async (scenario) => {\n if (\n this.runsUsed >= this.opts.budget ||\n this.costExhausted() ||\n this.stoppedEarly !== undefined ||\n this.opts.signal?.aborted\n )\n return\n // evaluate/gates/minimize cross an external boundary (router, backend,\n // judge). A throw there is an infra outcome: record it as a typed\n // eval-error and keep exploring — one 5xx must not kill a campaign.\n // Consecutive failures trip the circuit breaker instead, so a dead\n // backend stops the run rather than burning the remaining budget.\n try {\n const startedAt = performance.now()\n const ev = await this.opts.evaluate(scenario, cell)\n // Consumer-measured latency wins (it can exclude judge time); the\n // engine's wall-clock is the default so latency is never missing.\n const latencyMs = ev.latencyMs ?? performance.now() - startedAt\n this.runsUsed++\n runsThisStep++\n this.consecutiveEvalErrors = 0\n const costUsd = this.recordRunCost(scenario, cell, ev)\n const interest = this.objective.interest(ev, this.objectiveContext())\n this.log.push({\n cell,\n ev,\n interest,\n latencyMs,\n ...(costUsd !== undefined ? { costUsd } : {}),\n scenarioId: this.opts.scenarioId(scenario),\n })\n this.opts.onProgress?.({ type: 'evaluated', cell, scenario, evaluation: ev })\n\n const bin = this.binId(cell, ev.descriptor)\n const cur = this.archiveByBin.get(bin)\n if (!cur || interest > cur.interest)\n this.archiveByBin.set(bin, { binId: bin, cell, scenario, evaluation: ev, interest })\n\n if (interest < this.threshold) return\n this.candidateFindings++\n if (this.opts.gates?.isValid && !(await this.opts.gates.isValid(scenario, ev, cell)))\n return\n if (\n this.opts.gates?.isUncontaminated &&\n !(await this.opts.gates.isUncontaminated(scenario, ev, cell))\n )\n return\n\n const minimized = this.opts.minimize\n ? await this.opts.minimize(scenario, this.opts.evaluate, cell)\n : scenario\n const finding: Finding<S> = {\n id: this.opts.scenarioId(scenario),\n cell,\n scenario,\n minimized,\n text: this.opts.scenarioText?.(minimized),\n evaluation: ev,\n interest,\n objective: this.objective.kind,\n }\n this._findings.push(finding)\n newFindings.push(finding)\n this.opts.onProgress?.({ type: 'finding', finding })\n } catch (err) {\n // Internal validation errors (e.g. a fabricated costOf number) are\n // programming mistakes, not backend outcomes — they stay loud.\n if (err instanceof RangeError) throw err\n this.evalErrors++\n this.consecutiveEvalErrors++\n const message = err instanceof Error ? err.message : String(err)\n this.opts.onProgress?.({\n type: 'eval-error',\n cell,\n scenarioId: this.opts.scenarioId(scenario),\n message,\n })\n const limit = this.opts.maxConsecutiveEvalErrors ?? 5\n if (this.consecutiveEvalErrors >= limit) {\n this.stoppedEarly = {\n reason: 'eval-errors',\n detail: `${this.consecutiveEvalErrors} consecutive eval errors (last: ${message})`,\n }\n }\n }\n },\n this.opts.concurrency ?? 1,\n this.opts.signal,\n )\n }\n\n this.opts.onProgress?.({ type: 'round', runsUsed: this.runsUsed, budget: this.opts.budget })\n return { runs: runsThisStep, findings: newFindings }\n }\n\n /** Loop `step()` until the run or dollar budget is spent, the signal aborts,\n * or no progress is made. */\n async run(): Promise<CapsuleData<S>> {\n while (\n this.runsUsed < this.opts.budget &&\n !this.costExhausted() &&\n this.stoppedEarly === undefined &&\n !this.opts.signal?.aborted\n ) {\n const { runs } = await this.step()\n if (runs === 0 && this.stoppedEarly === undefined) break\n }\n return this.capsule()\n }\n\n coverage(): CoverageCell[] {\n return this.capsule().coverage\n }\n\n findings(): Finding<S>[] {\n return [...this._findings].sort((a, b) => b.interest - a.interest)\n }\n\n capsule(): CapsuleData<S> {\n return buildCapsule({\n target: this.opts.target,\n objective: this.objective.kind,\n cells: this.cells,\n log: this.log,\n threshold: this.threshold,\n archive: [...this.archiveByBin.values()],\n findings: this._findings,\n candidateFindings: this.candidateFindings,\n runsUsed: this.runsUsed,\n cost: this.opts.costOf\n ? { costUsd: this.spentKnownUsd, costUnknownRuns: this.costUnknownRuns }\n : undefined,\n evalErrors: this.evalErrors,\n stoppedEarly: this.stoppedEarly,\n })\n }\n}\n","/**\n * `fuzzAgent` — the adversarial batch preset over `BehaviorExplorer`.\n *\n * One call: explore the space to budget with the adversarial objective and\n * return the capsule. For agent-driven, incremental, or multi-objective use,\n * construct a `BehaviorExplorer` and drive it via `makeExploreTools`.\n */\n\nimport { BehaviorExplorer } from './explorer'\nimport { adversarialObjective } from './policies'\nimport type { CapsuleData, ExploreOptions } from './types'\n\nexport type FuzzAgentOptions<S> = Omit<ExploreOptions<S>, 'objective'> & {\n /** Score strictly below this is a candidate failure. Default 0.5. */\n failureThreshold?: number\n}\n\nexport async function fuzzAgent<S>(\n opts: FuzzAgentOptions<S>,\n): Promise<{ capsule: CapsuleData<S> }> {\n const { failureThreshold, ...rest } = opts\n const explorer = new BehaviorExplorer<S>({\n ...rest,\n objective: adversarialObjective(failureThreshold ?? 0.5),\n })\n return { capsule: await explorer.run() }\n}\n","/**\n * Validity gates — what separates a fuzzer from a slop generator.\n *\n * A notable candidate is admitted only when it is fair and reproducible. None of\n * these are on by default: the live wiring opts in, so reported findings carry\n * their proof.\n */\n\nimport type { Cell, Evaluation, Evaluator, ValidityGates } from './types'\n\n/** Combine gate sets; a candidate must pass every gate in every set. */\nexport function composeGates<S>(...sets: Array<ValidityGates<S> | undefined>): ValidityGates<S> {\n const present = sets.filter((s): s is ValidityGates<S> => s != null)\n return {\n isValid: async (scenario, ev, cell) => {\n for (const g of present) {\n if (g.isValid && !(await g.isValid(scenario, ev, cell))) return false\n }\n return true\n },\n isUncontaminated: async (scenario, ev, cell) => {\n for (const g of present) {\n if (g.isUncontaminated && !(await g.isUncontaminated(scenario, ev, cell))) return false\n }\n return true\n },\n }\n}\n\n/**\n * Reproducibility gate. Re-run the target on a meaning-preserving rephrase of the\n * flagged scenario; keep the finding only when the rephrase ALSO scores below the\n * threshold. A finding that flips under a cosmetic rewrite was keyed to surface\n * form, not the task — a false signal we must not report. Costs one extra\n * evaluation per candidate (candidates are rare, so cheap).\n */\nexport function perturbationStabilityGate<S>(opts: {\n evaluate: Evaluator<S>\n /** Produce a semantic-preserving rephrase. Return null to skip (treated as pass). */\n perturb: (scenario: S) => S | null\n /** Score strictly below this still counts as failing. Default 0.5. */\n failureThreshold?: number\n}): ValidityGates<S> {\n const threshold = opts.failureThreshold ?? 0.5\n return {\n isUncontaminated: async (scenario: S, _ev: Evaluation, cell: Cell) => {\n const rephrased = opts.perturb(scenario)\n if (rephrased == null) return true\n const re = await opts.evaluate(rephrased, cell)\n return re.score < threshold\n },\n }\n}\n\n/**\n * Severity-floor gate. Reject borderline candidates whose score sits in a band\n * just under the threshold — judge noise, not a real defect.\n */\nexport function severityFloorGate<S>(opts: {\n failureThreshold?: number\n margin?: number\n}): ValidityGates<S> {\n const threshold = opts.failureThreshold ?? 0.5\n const margin = opts.margin ?? 0.1\n return {\n isValid: (_scenario, ev: Evaluation) => ev.score <= threshold - margin,\n }\n}\n","/**\n * Agent-drivable surface over a live exploration session.\n *\n * Framework-neutral tool defs ({name, description, parameters: JSON Schema,\n * handler}) so the on-demand agent — not a batch script — drives the search:\n * step it, read coverage, inspect findings, render the capsule. Transport\n * encodings (OpenAI function shape, MCP) are one-line mappings the host owns.\n */\n\nimport { renderCapsuleHtml } from './capsule'\nimport type { BehaviorExplorer } from './explorer'\n\nexport interface ExploreToolDef {\n name: string\n description: string\n /** JSON Schema (draft-07+) for the arguments. */\n parameters: Record<string, unknown>\n handler: (args: unknown, ctx?: { signal?: AbortSignal }) => Promise<unknown>\n}\n\nconst NO_ARGS = { type: 'object', properties: {}, additionalProperties: false }\n\nexport function makeExploreTools<S>(explorer: BehaviorExplorer<S>): ExploreToolDef[] {\n return [\n {\n name: 'explore_step',\n description:\n 'Run one exploration round: allocate budget across cells, propose + evaluate scenarios, archive elites, admit gate-verified findings. Returns runs spent and new findings.',\n parameters: NO_ARGS,\n handler: async () => {\n const { runs, findings } = await explorer.step()\n return { runs, newFindings: findings.length, findings }\n },\n },\n {\n name: 'explore_coverage',\n description:\n 'Read the live coverage map: per planned cell — runs, robustness (null = uncovered), finding rate, per-dimension means.',\n parameters: NO_ARGS,\n handler: async () => explorer.coverage(),\n },\n {\n name: 'explore_findings',\n description: 'List gate-verified findings so far, sorted by descending interest.',\n parameters: {\n type: 'object',\n properties: { limit: { type: 'number', description: 'max findings to return' } },\n additionalProperties: false,\n },\n handler: async (args) => {\n const limit = (args as { limit?: number } | undefined)?.limit\n const all = explorer.findings()\n return typeof limit === 'number' ? all.slice(0, limit) : all\n },\n },\n {\n name: 'explore_capsule',\n description:\n 'Build the capsule artifact from the current session state. format \"data\" returns the structured CapsuleData; \"html\" returns the standalone page.',\n parameters: {\n type: 'object',\n properties: {\n format: { type: 'string', enum: ['data', 'html'] },\n generatedAt: { type: 'string', description: 'ISO timestamp to stamp into the page' },\n },\n additionalProperties: false,\n },\n handler: async (args) => {\n const a = (args ?? {}) as { format?: string; generatedAt?: string }\n const capsule = explorer.capsule()\n if (a.format === 'html') return renderCapsuleHtml(capsule, { generatedAt: a.generatedAt })\n return capsule\n },\n },\n ]\n}\n"],"mappings":"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","names":["cellId"]}
|
package/dist/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "@tangle-network/agent-eval — wire protocol",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.91.0",
|
|
6
6
|
"description": "HTTP and stdio RPC interface to agent-eval. The TypeScript runtime is the source of truth; this spec is the contract that cross-language clients (Python, Rust, Go) generate from.\n\nWire-protocol version: 1.0.0. Bumps on breaking changes to request/response schemas.",
|
|
7
7
|
"contact": {
|
|
8
8
|
"name": "Tangle Network",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-eval",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.91.0",
|
|
4
4
|
"description": "Evaluate and improve AI agents from runs, traces, judges, and feedback. Compare candidates, cluster failures, measure lift, and gate releases.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-eval#readme",
|
|
6
6
|
"repository": {
|