@tangle-network/agent-eval 0.98.0 → 0.99.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.
Files changed (40) hide show
  1. package/dist/adapters/http.d.ts +1 -1
  2. package/dist/adapters/langchain.d.ts +1 -1
  3. package/dist/adapters/otel.d.ts +1 -1
  4. package/dist/adversarial-B7loGVVX.d.ts +19 -0
  5. package/dist/analyst/index.js +2 -1
  6. package/dist/analyst/index.js.map +1 -1
  7. package/dist/campaign/index.d.ts +9 -8
  8. package/dist/campaign/index.js +4 -1
  9. package/dist/campaign/index.js.map +1 -1
  10. package/dist/chunk-BUTW4RGG.js +32 -0
  11. package/dist/chunk-BUTW4RGG.js.map +1 -0
  12. package/dist/{chunk-QWV226SL.js → chunk-JHCHEVET.js} +1 -3
  13. package/dist/chunk-OYU4D7FY.js +718 -0
  14. package/dist/chunk-OYU4D7FY.js.map +1 -0
  15. package/dist/{chunk-PSWWQXHF.js → chunk-SJISCGWD.js} +5 -30
  16. package/dist/chunk-SJISCGWD.js.map +1 -0
  17. package/dist/contract/index.d.ts +6 -6
  18. package/dist/fuzz.d.ts +1 -1
  19. package/dist/{gepa-3TG16SYf.d.ts → gepa-H6mlM0KN.d.ts} +1 -1
  20. package/dist/hosted/index.d.ts +1 -1
  21. package/dist/index.d.ts +12 -10
  22. package/dist/index.js +34 -241
  23. package/dist/index.js.map +1 -1
  24. package/dist/matrix/index.d.ts +3 -17
  25. package/dist/matrix/index.js +3 -7
  26. package/dist/multishot/index.d.ts +1 -1
  27. package/dist/multishot/index.js +1 -1
  28. package/dist/openapi.json +1 -1
  29. package/dist/{pre-registration-nfUdc9EQ.d.ts → pre-registration-CMm8cvrh.d.ts} +73 -1
  30. package/dist/{provenance-C5KAhiom.d.ts → provenance-Bg_RttR8.d.ts} +2 -2
  31. package/dist/rl.d.ts +2 -2
  32. package/dist/rl.js +0 -79
  33. package/dist/rl.js.map +1 -1
  34. package/dist/{types-D9tuReDv.d.ts → types-BTI16iFl.d.ts} +1 -1
  35. package/package.json +1 -1
  36. package/dist/adversarial-DIVcDoI_.d.ts +0 -88
  37. package/dist/chunk-HMA63UEO.js +0 -370
  38. package/dist/chunk-HMA63UEO.js.map +0 -1
  39. package/dist/chunk-PSWWQXHF.js.map +0 -1
  40. /package/dist/{chunk-QWV226SL.js.map → chunk-JHCHEVET.js.map} +0 -0
@@ -527,4 +527,4 @@ interface CampaignResult<TArtifact = unknown, TScenario extends Scenario = Scena
527
527
  scenarios: Array<Pick<TScenario, 'id' | 'kind'>>;
528
528
  }
529
529
 
530
- export { type JudgeAggregate as A, type ScenarioAggregate as B, type CampaignResult as C, type DispatchFn as D, isProposedCandidate as E, labelTrustRank as F, type GateResult as G, type JudgeScore as J, type LabeledScenarioStore as L, type MutableSurface as M, type OptimizationProposer as O, type ParetoParent as P, type RedactionStatus as R, type Scenario as S, type TraceSpan as T, type JudgeConfig as a, type DispatchContext as b, type CampaignTraceWriter as c, type GenerationRecord as d, type SurfaceProposer as e, type Gate as f, type GateContext as g, type Mutator as h, type GateDecision as i, type CampaignAggregates as j, type CampaignArtifactWriter as k, type CampaignCellResult as l, type CampaignCostMeter as m, type CodeSurface as n, type GenerationCandidate as o, type JudgeDimension as p, type OptimizerConfig as q, type SessionScript as r, type LabeledScenarioWrite as s, type LabeledScenarioSampleArgs as t, type LabeledScenarioRecord as u, type LabelTrust as v, type ProposedCandidate as w, type ProposeContext as x, type LabeledScenarioSource as y, type CampaignTokenUsage as z };
530
+ export { type JudgeAggregate as A, type ScenarioAggregate as B, type CampaignResult as C, type DispatchFn as D, isProposedCandidate as E, labelTrustRank as F, type GateResult as G, type JudgeScore as J, type LabeledScenarioStore as L, type MutableSurface as M, type OptimizationProposer as O, type ParetoParent as P, type RedactionStatus as R, type Scenario as S, type TraceSpan as T, type JudgeConfig as a, type DispatchContext as b, type JudgeDimension as c, type CampaignTraceWriter as d, type GenerationRecord as e, type SurfaceProposer as f, type Gate as g, type GateContext as h, type Mutator as i, type GateDecision as j, type CampaignAggregates as k, type CampaignArtifactWriter as l, type CampaignCellResult as m, type CampaignCostMeter as n, type CodeSurface as o, type GenerationCandidate as p, type OptimizerConfig as q, type SessionScript as r, type LabeledScenarioWrite as s, type LabeledScenarioSampleArgs as t, type LabeledScenarioRecord as u, type LabelTrust as v, type ProposedCandidate as w, type ProposeContext as x, type LabeledScenarioSource as y, type CampaignTokenUsage as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-eval",
3
- "version": "0.98.0",
3
+ "version": "0.99.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": {
@@ -1,88 +0,0 @@
1
- /**
2
- * Adversarial scenario search.
3
- *
4
- * Capability evaluation on a fixed scenario set measures performance on
5
- * the distribution someone curated. Production failure modes live in the
6
- * tail — inputs the curator didn't think of, or actively avoided. The
7
- * adversarial-search primitive actively looks for them: starting from a
8
- * pool of scenarios where the policy already passes, it mutates them
9
- * (paraphrase, edge-case substitution, compositional combination) and
10
- * keeps the mutations that *break* the policy.
11
- *
12
- * This is not magic. It's the simplest version of the loop that AdA
13
- * (Open-Ended Adaptation, DeepMind 2023), POET, and Anthropic's
14
- * auto-jailbreak rigs all run: hill-climb against a failure indicator,
15
- * keep the survivors, repeat. We ship the harness; consumers supply the
16
- * mutation strategies and the failure detector.
17
- *
18
- * Why ship this in agent-eval and not as a separate red-team tool: every
19
- * piece of the standard adversarial loop is already in this package
20
- * (`runEvalCampaign` for the matrix run, `RawProviderSink` for capture,
21
- * `assertRunCaptured` for integrity, `pairedEvalueSequence` for stop
22
- * criteria). The adversarial primitive is just the *scenario-mutation
23
- * meta-loop* on top of that machinery.
24
- */
25
- interface AdversarialScenario<S> {
26
- /** Stable id — used for deduplication and lineage tracking. */
27
- id: string;
28
- /** Generation index — 0 for seeds, 1 for first round of mutations, etc. */
29
- generation: number;
30
- /** Lineage — id of the parent scenario this was mutated from, if any. */
31
- parentId: string | null;
32
- scenario: S;
33
- /** Score on the policy under test. Lower = adversarial signal. */
34
- score: number | null;
35
- /** Strategy that produced this mutation, for diagnostics. */
36
- mutationStrategy: string | null;
37
- }
38
- interface AdversarialMutation<S> {
39
- id: string;
40
- /**
41
- * Mutate one scenario. Return null to skip; return one or more new
42
- * scenarios. The harness deduplicates by `mutateScenarioId(scenario)`.
43
- */
44
- mutate(parent: S, rng: () => number): Promise<S[]> | S[];
45
- }
46
- interface AdversarialSearchOptions<S> {
47
- /** Initial scenarios — typically those the policy currently passes. */
48
- seeds: S[];
49
- /** Stable identifier extraction. */
50
- mutateScenarioId: (s: S) => string;
51
- /** Mutation strategies. */
52
- mutations: AdversarialMutation<S>[];
53
- /**
54
- * Run the policy under test against one scenario, return a scalar score
55
- * in [0, 1]. Lower = adversarial signal.
56
- */
57
- scoreFn: (s: S) => Promise<number>;
58
- /**
59
- * Threshold below which a scenario counts as a "failure" worth keeping.
60
- * Default 0.5.
61
- */
62
- failureThreshold?: number;
63
- /** Number of mutation rounds. Default 3. */
64
- rounds?: number;
65
- /** Children per parent per round. Default 4. */
66
- childrenPerParent?: number;
67
- /** Maximum total scenarios examined. Default Infinity. */
68
- budget?: number;
69
- /** Seed for the deterministic RNG. Default 1. */
70
- seed?: number;
71
- }
72
- interface AdversarialSearchReport<S> {
73
- scenarios: AdversarialScenario<S>[];
74
- /** Discovered failures sorted by score ascending. */
75
- failures: AdversarialScenario<S>[];
76
- /** Round-by-round counts. */
77
- byGeneration: Array<{
78
- generation: number;
79
- total: number;
80
- failures: number;
81
- meanScore: number;
82
- }>;
83
- /** Total scoreFn invocations consumed. */
84
- scoreCalls: number;
85
- }
86
- declare function adversarialScenarioSearch<S>(opts: AdversarialSearchOptions<S>): Promise<AdversarialSearchReport<S>>;
87
-
88
- export { type AdversarialMutation as A, type AdversarialScenario as a, type AdversarialSearchOptions as b, type AdversarialSearchReport as c, adversarialScenarioSearch as d };
@@ -1,370 +0,0 @@
1
- import {
2
- canonicalize
3
- } from "./chunk-VSMTAMNK.js";
4
- import {
5
- ValidationError
6
- } from "./chunk-3BFEG2F6.js";
7
-
8
- // src/completion-verifier.ts
9
- function completionVerdict(input) {
10
- if (input.requirements.length === 0) {
11
- throw new Error(
12
- `completionVerdict: task '${input.taskId}' has no requirement checks \u2014 nothing to derive a verdict from`
13
- );
14
- }
15
- const satisfiedCount = input.requirements.filter((r) => r.satisfied).length;
16
- const completionRate = satisfiedCount / input.requirements.length;
17
- const fullyComplete = satisfiedCount === input.requirements.length;
18
- return {
19
- taskId: input.taskId,
20
- requirements: input.requirements,
21
- completionRate,
22
- fullyComplete,
23
- valid: fullyComplete,
24
- score: completionRate
25
- };
26
- }
27
- var STOPWORDS = /* @__PURE__ */ new Set([
28
- "the",
29
- "a",
30
- "an",
31
- "of",
32
- "for",
33
- "and",
34
- "or",
35
- "to",
36
- "in",
37
- "on",
38
- "with",
39
- "by"
40
- ]);
41
- var REQUIREMENT_FORM_STOPWORDS = /* @__PURE__ */ new Set([
42
- "generated",
43
- "generate",
44
- "view",
45
- "render",
46
- "rendered",
47
- "persisted",
48
- "persist",
49
- "artifact",
50
- "file",
51
- "document",
52
- "note",
53
- "proposal",
54
- "deliverable",
55
- "output",
56
- "created",
57
- "create",
58
- "produce",
59
- "produced",
60
- "flag"
61
- ]);
62
- var MATCH_THRESHOLD = 0.5;
63
- var MIN_CONTENT_CHARS = 50;
64
- function tokens(s, extraStop) {
65
- return new Set(
66
- s.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 1 && !STOPWORDS.has(t) && !extraStop?.has(t))
67
- );
68
- }
69
- function tokenRecall(requirementText, candidateText) {
70
- const req = tokens(requirementText, REQUIREMENT_FORM_STOPWORDS);
71
- if (req.size === 0) return 0;
72
- const cand = tokens(candidateText);
73
- let hit = 0;
74
- for (const t of req) if (cand.has(t)) hit++;
75
- return hit / req.size;
76
- }
77
- function artifactCandidates(req, reqIndex, artifacts) {
78
- const reqText = `${req.title} ${req.category ?? ""}`;
79
- const out = [];
80
- artifacts.forEach((a, i) => {
81
- if ((a.content ?? "").trim().length < MIN_CONTENT_CHARS) return;
82
- let score = tokenRecall(
83
- reqText,
84
- `${a.path ?? ""} ${a.kind} ${(a.content ?? "").slice(0, 4e3)}`
85
- );
86
- if (req.category && a.kind && req.category.toLowerCase() === a.kind.toLowerCase()) {
87
- score = Math.max(score, 1);
88
- }
89
- if (score < MATCH_THRESHOLD) return;
90
- out.push({
91
- reqIndex,
92
- itemKey: `artifact:${i}`,
93
- score,
94
- evidence: `artifact '${a.path ?? a.kind}' matched (token recall ${score.toFixed(2)})`,
95
- content: a.content ?? null
96
- });
97
- });
98
- return out;
99
- }
100
- function proposalCandidates(req, reqIndex, proposals) {
101
- const reqText = `${req.title} ${req.category ?? ""}`;
102
- const out = [];
103
- for (const p of proposals) {
104
- if (p.status !== "approved") continue;
105
- const body = (p.content ?? "").trim();
106
- if (body.length < MIN_CONTENT_CHARS) continue;
107
- const score = tokenRecall(reqText, `${p.title} ${body}`);
108
- if (score < MATCH_THRESHOLD) continue;
109
- out.push({
110
- reqIndex,
111
- itemKey: `proposal:${p.id}`,
112
- score,
113
- evidence: `approved proposal '${p.title}' matched (token recall ${score.toFixed(2)})`,
114
- content: body
115
- });
116
- }
117
- return out;
118
- }
119
- function toolCallCandidates(req, reqIndex, toolCalls) {
120
- const out = [];
121
- toolCalls.forEach((name, i) => {
122
- const score = tokenRecall(req.title, name);
123
- if (score < MATCH_THRESHOLD) return;
124
- out.push({
125
- reqIndex,
126
- itemKey: `tool:${i}`,
127
- score,
128
- evidence: `tool call '${name}' matched (token recall ${score.toFixed(2)})`,
129
- content: null
130
- });
131
- });
132
- return out;
133
- }
134
- async function verifyCompletion(gold, state, checkCorrectness) {
135
- if (gold.requirements.length === 0) {
136
- throw new Error(
137
- `verifyCompletion: task '${gold.taskId}' has no requirements \u2014 malformed gold spec`
138
- );
139
- }
140
- const candidates = [];
141
- gold.requirements.forEach((req, i) => {
142
- const by = req.satisfiedBy ?? "any";
143
- if (by === "artifact" || by === "any") {
144
- candidates.push(...artifactCandidates(req, i, state.artifacts));
145
- }
146
- if (by === "proposal" || by === "any") {
147
- candidates.push(...proposalCandidates(req, i, state.proposals));
148
- }
149
- if (by === "tool-call" || by === "any") {
150
- candidates.push(...toolCallCandidates(req, i, state.toolCalls));
151
- }
152
- });
153
- candidates.sort((a, b) => b.score - a.score);
154
- const assigned = /* @__PURE__ */ new Map();
155
- const itemTaken = /* @__PURE__ */ new Set();
156
- for (const c of candidates) {
157
- if (assigned.has(c.reqIndex) || itemTaken.has(c.itemKey)) continue;
158
- assigned.set(c.reqIndex, c);
159
- itemTaken.add(c.itemKey);
160
- }
161
- const requirements = [];
162
- for (let i = 0; i < gold.requirements.length; i++) {
163
- const req = gold.requirements[i];
164
- const match = assigned.get(i);
165
- const evidence = [];
166
- let correct = null;
167
- if (match) {
168
- evidence.push(match.evidence);
169
- if (match.content !== null) {
170
- const r = await checkCorrectness(req, match.content);
171
- correct = r.correct;
172
- evidence.push(`correctness: ${r.correct ? "pass" : "fail"} \u2014 ${r.reason}`);
173
- } else {
174
- evidence.push("correctness: not assessed \u2014 matched item carries no content");
175
- }
176
- } else {
177
- const by = req.satisfiedBy ?? "any";
178
- const kind = by === "any" ? "artifact/proposal/tool-call" : by;
179
- evidence.push(`no produced ${kind} matched this requirement`);
180
- }
181
- const structurallyPresent = match !== void 0;
182
- const satisfied = structurallyPresent && correct !== false;
183
- requirements.push({
184
- reqId: req.reqId,
185
- title: req.title,
186
- structurallyPresent,
187
- correct,
188
- satisfied,
189
- evidence
190
- });
191
- }
192
- return completionVerdict({ taskId: gold.taskId, requirements });
193
- }
194
- function parseCorrectnessResponse(raw) {
195
- const match = raw.match(/\{[\s\S]*\}/);
196
- if (!match) {
197
- throw new Error(`correctness checker: no JSON object in model response: ${raw.slice(0, 200)}`);
198
- }
199
- const parsed = JSON.parse(match[0]);
200
- if (typeof parsed.correct !== "boolean") {
201
- throw new Error(`correctness checker: 'correct' is not a boolean in: ${match[0].slice(0, 200)}`);
202
- }
203
- return { correct: parsed.correct, reason: typeof parsed.reason === "string" ? parsed.reason : "" };
204
- }
205
- function createLlmCorrectnessChecker(tc, opts = {}) {
206
- const model = opts.model ?? "claude-sonnet-4-6";
207
- const maxContentChars = opts.maxContentChars ?? 8e3;
208
- return async (requirement, content) => {
209
- const resp = await tc.chat({
210
- model,
211
- messages: [
212
- {
213
- role: "system",
214
- content: 'You verify whether a produced work artifact actually fulfils a stated requirement. Judge fulfilment only \u2014 is the deliverable substantively present and on-point \u2014 not polish. A plan to do it later, a vague gesture, or a description of what should be done does NOT fulfil a requirement; the artifact must BE the deliverable. Respond with a single JSON object: {"correct": boolean, "reason": string (<= 30 words)}.'
215
- },
216
- {
217
- role: "user",
218
- content: `Requirement: ${requirement.title}
219
- ${requirement.category ? `Category: ${requirement.category}
220
- ` : ""}
221
- Produced artifact:
222
- ${content.slice(0, maxContentChars)}`
223
- }
224
- ],
225
- temperature: 0,
226
- maxTokens: 200
227
- });
228
- const raw = resp.choices?.[0]?.message?.content ?? "";
229
- return parseCorrectnessResponse(raw);
230
- };
231
- }
232
- var TITLE_STOPWORDS = /* @__PURE__ */ new Set([
233
- "the",
234
- "a",
235
- "an",
236
- "and",
237
- "or",
238
- "for",
239
- "to",
240
- "of",
241
- "in",
242
- "on",
243
- "with",
244
- "review",
245
- "update",
246
- "new",
247
- "proposed"
248
- ]);
249
- function createTokenRecallChecker(opts = {}) {
250
- const minRecall = opts.minRecall ?? 0.5;
251
- const minLen = opts.minContentLength ?? 120;
252
- return async (requirement, content) => {
253
- const body = content.trim();
254
- if (body.length < minLen)
255
- return {
256
- correct: false,
257
- reason: `content too thin (${body.length} chars) to be the deliverable`
258
- };
259
- const titleTokens = requirement.title.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length > 2 && !TITLE_STOPWORDS.has(t));
260
- if (titleTokens.length === 0)
261
- return {
262
- correct: true,
263
- reason: "requirement title has no significant tokens \u2014 structural match accepted"
264
- };
265
- const lower = body.toLowerCase();
266
- const hits = titleTokens.filter((t) => lower.includes(t)).length;
267
- const recall = hits / titleTokens.length;
268
- return recall >= minRecall ? {
269
- correct: true,
270
- reason: `content recalls ${hits}/${titleTokens.length} requirement tokens`
271
- } : {
272
- correct: false,
273
- reason: `content recalls only ${hits}/${titleTokens.length} requirement tokens`
274
- };
275
- };
276
- }
277
-
278
- // src/produced-state.ts
279
- function artifactKind(mimeType) {
280
- if (!mimeType) return "file";
281
- if (mimeType.includes("json")) return "json";
282
- if (mimeType.startsWith("text/")) return "text";
283
- return "file";
284
- }
285
- function extractProducedState(events) {
286
- const artifacts = [];
287
- const proposals = [];
288
- const toolCalls = [];
289
- const seenTools = /* @__PURE__ */ new Set();
290
- for (const ev of events) {
291
- if (ev.type === "tool_call") {
292
- const name = ev.toolName;
293
- if (name && !seenTools.has(name)) {
294
- seenTools.add(name);
295
- toolCalls.push(name);
296
- }
297
- } else if (ev.type === "artifact") {
298
- const a = ev;
299
- artifacts.push({
300
- kind: artifactKind(a.mimeType),
301
- path: a.name ?? a.uri ?? a.artifactId,
302
- content: a.content ?? ""
303
- });
304
- } else if (ev.type === "proposal_created") {
305
- const p = ev;
306
- proposals.push({
307
- id: p.proposalId,
308
- title: p.title,
309
- status: p.status ?? "pending",
310
- ...p.content !== void 0 ? { content: p.content } : {}
311
- });
312
- }
313
- }
314
- return { artifacts, proposals, toolCalls };
315
- }
316
-
317
- // src/agent-profile.ts
318
- import { createHash } from "crypto";
319
- function agentProfileId(profile) {
320
- const label = pathSafeProfileLabel(agentProfileDisplayLabel(profile)) ?? "profile";
321
- return `${label}-${agentProfileHash(profile).slice(0, 16)}`;
322
- }
323
- function agentProfileModelId(profile) {
324
- const model = profile.model?.default?.trim();
325
- if (!model) {
326
- const label = agentProfileDisplayLabel(profile) ?? "unnamed profile";
327
- throw new ValidationError(
328
- `AgentProfile "${label}" has no model.default \u2014 cannot record eval run`
329
- );
330
- }
331
- return model;
332
- }
333
- function agentProfileDisplayLabel(profile) {
334
- return profile.name?.trim() || profile.version?.trim() || void 0;
335
- }
336
- function pathSafeProfileLabel(label) {
337
- const safe = label?.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
338
- return safe || void 0;
339
- }
340
- function compact(input) {
341
- const out = {};
342
- for (const [key, value] of Object.entries(input)) {
343
- if (value !== void 0) out[key] = value;
344
- }
345
- return out;
346
- }
347
- function agentProfileHash(profile) {
348
- const model = agentProfileModelId(profile);
349
- const behaviour = {
350
- ...profile,
351
- name: void 0,
352
- description: void 0,
353
- tags: profile.tags ? [...profile.tags].sort() : void 0,
354
- model: compact({ ...profile.model, default: model })
355
- };
356
- return createHash("sha256").update(JSON.stringify(canonicalize(behaviour))).digest("hex");
357
- }
358
-
359
- export {
360
- completionVerdict,
361
- verifyCompletion,
362
- parseCorrectnessResponse,
363
- createLlmCorrectnessChecker,
364
- createTokenRecallChecker,
365
- extractProducedState,
366
- agentProfileId,
367
- agentProfileModelId,
368
- agentProfileHash
369
- };
370
- //# sourceMappingURL=chunk-HMA63UEO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/completion-verifier.ts","../src/produced-state.ts","../src/agent-profile.ts"],"sourcesContent":["/**\n * Completion verifier — the task-completion oracle.\n *\n * Answers the only eval question that is not a proxy: did the agent actually\n * COMPLETE the task — produce every required deliverable, persisted and\n * correct — rather than describe what should be done. A fluent transcript\n * that never produces the artifact scores zero here.\n *\n * Per requirement, a two-stage check:\n * 1. Structural — a produced item (vault artifact / approved proposal /\n * tool call) of the right kind is matched against the requirement and\n * carries non-empty content. Deterministic; no LLM.\n * 2. Correctness — only if structurally present AND the matched item\n * carries content, one targeted check decides whether that item\n * actually fulfils the requirement. A hallucinated artifact fails here;\n * an absent one already failed stage 1.\n *\n * `completionRate` is satisfied / total. Quality dimensions are meaningless\n * on an incomplete task — callers gate on `fullyComplete` / `completionRate`\n * before scoring quality.\n */\n\nimport type { TCloud } from '@tangle-network/tcloud'\nimport type { Artifact } from './artifact-validator'\nimport type { DefaultVerdict } from './verdict'\n\n/** What kind of produced state can satisfy a requirement structurally. */\nexport type SatisfiedBy = 'artifact' | 'proposal' | 'tool-call' | 'any'\n\nexport interface CompletionRequirement {\n /** Stable id from the task gold (e.g. a persona's `expected_requirements[].req_id`). */\n reqId: string\n /** Human-readable description of the required deliverable. */\n title: string\n /** Optional kind/category hint, matched against a produced item's kind. */\n category?: string\n /** What produced state satisfies this requirement. Defaults to 'any'. */\n satisfiedBy?: SatisfiedBy\n}\n\nexport interface TaskGold {\n taskId: string\n requirements: CompletionRequirement[]\n}\n\nexport interface ProducedProposal {\n id: string\n title: string\n status: 'pending' | 'approved' | 'rejected'\n /** Optional persisted body — when present, enables a correctness check. */\n content?: string\n}\n\n/** Everything observable about what a run actually produced. */\nexport interface ProducedState {\n /** Persisted vault artifacts. Reuses the shared `Artifact` shape. */\n artifacts: Artifact[]\n /** Proposals / filings the agent created. */\n proposals: ProducedProposal[]\n /** Names of tools the agent invoked. */\n toolCalls: string[]\n}\n\nexport interface RequirementCheck {\n reqId: string\n title: string\n /** A produced item of the right kind matched the requirement, non-empty. */\n structurallyPresent: boolean\n /**\n * Whether the matched item actually fulfils the requirement. `null` when\n * not structurally present, or when the matched item carries no content\n * to assess.\n */\n correct: boolean | null\n /** structurallyPresent && correct !== false. */\n satisfied: boolean\n /** Human-readable evidence for the verdict. */\n evidence: string[]\n}\n\n/** Extends the substrate verdict spine: `valid` = `fullyComplete` and\n * `score` = `completionRate` — derived in `completionVerdict()`, the one\n * place those equalities hold by construction. */\nexport interface CompletionVerdict extends DefaultVerdict {\n taskId: string\n requirements: RequirementCheck[]\n /** satisfied / total requirements. */\n completionRate: number\n /** Every requirement satisfied. */\n fullyComplete: boolean\n}\n\n/**\n * Construct a `CompletionVerdict` from the per-requirement checks, deriving\n * `completionRate` / `fullyComplete` and the spine fields (`valid` =\n * `fullyComplete`, `score` = `completionRate`) in one place. Throws on zero\n * requirements — a verdict over nothing is a misconfiguration, mirroring\n * `verifyCompletion`'s gold-spec guard.\n */\nexport function completionVerdict(input: {\n taskId: string\n requirements: RequirementCheck[]\n}): CompletionVerdict {\n if (input.requirements.length === 0) {\n throw new Error(\n `completionVerdict: task '${input.taskId}' has no requirement checks — nothing to derive a verdict from`,\n )\n }\n const satisfiedCount = input.requirements.filter((r) => r.satisfied).length\n const completionRate = satisfiedCount / input.requirements.length\n const fullyComplete = satisfiedCount === input.requirements.length\n return {\n taskId: input.taskId,\n requirements: input.requirements,\n completionRate,\n fullyComplete,\n valid: fullyComplete,\n score: completionRate,\n }\n}\n\n/**\n * Decides whether a produced item's content actually fulfils a requirement.\n * Injected so the structural verifier stays pure and unit-testable; the\n * production implementation is `createLlmCorrectnessChecker`.\n */\nexport type CorrectnessChecker = (\n requirement: CompletionRequirement,\n content: string,\n) => Promise<{ correct: boolean; reason: string }>\n\nconst STOPWORDS = new Set([\n 'the',\n 'a',\n 'an',\n 'of',\n 'for',\n 'and',\n 'or',\n 'to',\n 'in',\n 'on',\n 'with',\n 'by',\n])\n\n// Deliverable-FORM vocabulary — words that name the SHAPE of an output, not its\n// domain content. A correct \"swap-comparison view persisted as a ui/** artifact\"\n// is an OpenUI JSON whose body says nothing about \"artifact\" / \"persisted\" /\n// \"view\"; the discriminative tokens are the domain nouns (swap, comparison).\n// Stripped from the REQUIREMENT side of structural recall so a deliverable is\n// matched on what it IS about, not on the boilerplate describing its form. The\n// correctness checker strips the same class via TITLE_STOPWORDS. Anti-game holds:\n// the distinctive domain tokens remain, so an off-topic item still fails.\nconst REQUIREMENT_FORM_STOPWORDS = new Set([\n 'generated',\n 'generate',\n 'view',\n 'render',\n 'rendered',\n 'persisted',\n 'persist',\n 'artifact',\n 'file',\n 'document',\n 'note',\n 'proposal',\n 'deliverable',\n 'output',\n 'created',\n 'create',\n 'produce',\n 'produced',\n 'flag',\n])\n\nconst MATCH_THRESHOLD = 0.5\nconst MIN_CONTENT_CHARS = 50\n\nfunction tokens(s: string, extraStop?: Set<string>): Set<string> {\n return new Set(\n s\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 1 && !STOPWORDS.has(t) && !extraStop?.has(t)),\n )\n}\n\n/**\n * Recall of the requirement's tokens within a candidate's identifying text.\n * Recall, not Jaccard — a candidate's path/id legitimately carries extra\n * tokens the requirement does not name. The requirement side drops\n * deliverable-FORM vocabulary so recall keys on the distinctive domain tokens.\n */\nfunction tokenRecall(requirementText: string, candidateText: string): number {\n const req = tokens(requirementText, REQUIREMENT_FORM_STOPWORDS)\n if (req.size === 0) return 0\n const cand = tokens(candidateText)\n let hit = 0\n for (const t of req) if (cand.has(t)) hit++\n return hit / req.size\n}\n\ninterface Candidate {\n reqIndex: number\n /** Unique key for a produced item — each item satisfies at most one requirement. */\n itemKey: string\n score: number\n evidence: string\n /** Content to correctness-check, or null when the matched item has none. */\n content: string | null\n}\n\nfunction artifactCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n artifacts: Artifact[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n artifacts.forEach((a, i) => {\n if ((a.content ?? '').trim().length < MIN_CONTENT_CHARS) return\n // Match against the artifact CONTENT too, not just its path + kind — a\n // generated view / note whose path is generic still satisfies a requirement\n // when its body covers it (e.g. an OpenUI comparison grounded in the on-file\n // figures). Bounded slice keeps the recall text cheap; MATCH_THRESHOLD holds.\n let score = tokenRecall(\n reqText,\n `${a.path ?? ''} ${a.kind} ${(a.content ?? '').slice(0, 4000)}`,\n )\n if (req.category && a.kind && req.category.toLowerCase() === a.kind.toLowerCase()) {\n score = Math.max(score, 1)\n }\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `artifact:${i}`,\n score,\n evidence: `artifact '${a.path ?? a.kind}' matched (token recall ${score.toFixed(2)})`,\n content: a.content ?? null,\n })\n })\n return out\n}\n\nfunction proposalCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n proposals: ProducedProposal[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n for (const p of proposals) {\n // Pending or rejected work is not a completed deliverable.\n if (p.status !== 'approved') continue\n // A proposal needs an assessable BODY to be a deliverable. A bare title is\n // not completion: correctness cannot be judged on it, so a title-only match\n // would auto-pass the oracle (structurallyPresent && correct===null →\n // satisfied) with no verifiable content. Tool calls are the only\n // legitimately content-less deliverable (`toolCallCandidates`).\n const body = (p.content ?? '').trim()\n if (body.length < MIN_CONTENT_CHARS) continue\n // Match against the body as well as the (often short) title — a refusal /\n // flag / analysis proposal whose title is a label still satisfies a\n // descriptively-worded requirement when its content covers it. MATCH_THRESHOLD\n // + the requirement's distinctive tokens keep an off-topic proposal out;\n // correctness (a SEMANTIC checker, NOT this lexical pass) then judges\n // polarity/fulfilment, so a negation that merely contains the tokens fails.\n // Structural and correctness must use different evidence or the two-stage\n // check collapses to one lexical gate.\n const score = tokenRecall(reqText, `${p.title} ${body}`)\n if (score < MATCH_THRESHOLD) continue\n out.push({\n reqIndex,\n itemKey: `proposal:${p.id}`,\n score,\n evidence: `approved proposal '${p.title}' matched (token recall ${score.toFixed(2)})`,\n content: body,\n })\n }\n return out\n}\n\nfunction toolCallCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n toolCalls: string[],\n): Candidate[] {\n const out: Candidate[] = []\n toolCalls.forEach((name, i) => {\n const score = tokenRecall(req.title, name)\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `tool:${i}`,\n score,\n evidence: `tool call '${name}' matched (token recall ${score.toFixed(2)})`,\n content: null,\n })\n })\n return out\n}\n\n/**\n * Verify whether a run completed the task. `checkCorrectness` is injected —\n * `createLlmCorrectnessChecker` for production, a deterministic stub in tests.\n *\n * Throws on a gold spec with no requirements: an eval task that requires\n * nothing is a misconfiguration, not a vacuously-complete task.\n */\nexport async function verifyCompletion(\n gold: TaskGold,\n state: ProducedState,\n checkCorrectness: CorrectnessChecker,\n): Promise<CompletionVerdict> {\n if (gold.requirements.length === 0) {\n throw new Error(\n `verifyCompletion: task '${gold.taskId}' has no requirements — malformed gold spec`,\n )\n }\n\n // Collect every above-threshold (requirement, produced-item) candidate, then\n // assign greedily by descending score: each requirement and each produced\n // item is used at most once. One deliverable fulfils one requirement.\n const candidates: Candidate[] = []\n gold.requirements.forEach((req, i) => {\n const by = req.satisfiedBy ?? 'any'\n if (by === 'artifact' || by === 'any') {\n candidates.push(...artifactCandidates(req, i, state.artifacts))\n }\n if (by === 'proposal' || by === 'any') {\n candidates.push(...proposalCandidates(req, i, state.proposals))\n }\n if (by === 'tool-call' || by === 'any') {\n candidates.push(...toolCallCandidates(req, i, state.toolCalls))\n }\n })\n candidates.sort((a, b) => b.score - a.score)\n\n const assigned = new Map<number, Candidate>()\n const itemTaken = new Set<string>()\n for (const c of candidates) {\n if (assigned.has(c.reqIndex) || itemTaken.has(c.itemKey)) continue\n assigned.set(c.reqIndex, c)\n itemTaken.add(c.itemKey)\n }\n\n const requirements: RequirementCheck[] = []\n for (let i = 0; i < gold.requirements.length; i++) {\n const req = gold.requirements[i]!\n const match = assigned.get(i)\n const evidence: string[] = []\n let correct: boolean | null = null\n\n if (match) {\n evidence.push(match.evidence)\n if (match.content !== null) {\n const r = await checkCorrectness(req, match.content)\n correct = r.correct\n evidence.push(`correctness: ${r.correct ? 'pass' : 'fail'} — ${r.reason}`)\n } else {\n evidence.push('correctness: not assessed — matched item carries no content')\n }\n } else {\n const by = req.satisfiedBy ?? 'any'\n const kind = by === 'any' ? 'artifact/proposal/tool-call' : by\n evidence.push(`no produced ${kind} matched this requirement`)\n }\n\n const structurallyPresent = match !== undefined\n const satisfied = structurallyPresent && correct !== false\n requirements.push({\n reqId: req.reqId,\n title: req.title,\n structurallyPresent,\n correct,\n satisfied,\n evidence,\n })\n }\n\n return completionVerdict({ taskId: gold.taskId, requirements })\n}\n\nexport interface LlmCorrectnessCheckerOpts {\n model?: string\n /** Max chars of artifact content sent to the checker. */\n maxContentChars?: number\n}\n\n/** Parse the correctness checker's model response. Fails loud on a bad shape. */\nexport function parseCorrectnessResponse(raw: string): { correct: boolean; reason: string } {\n const match = raw.match(/\\{[\\s\\S]*\\}/)\n if (!match) {\n throw new Error(`correctness checker: no JSON object in model response: ${raw.slice(0, 200)}`)\n }\n const parsed = JSON.parse(match[0]) as { correct?: unknown; reason?: unknown }\n if (typeof parsed.correct !== 'boolean') {\n throw new Error(`correctness checker: 'correct' is not a boolean in: ${match[0].slice(0, 200)}`)\n }\n return { correct: parsed.correct, reason: typeof parsed.reason === 'string' ? parsed.reason : '' }\n}\n\n/**\n * Production `CorrectnessChecker` — one LLM call per matched artifact,\n * deterministic (temperature 0), structured JSON out. Judges fulfilment\n * only: a plan, a gesture, or a description of what should be done does not\n * fulfil a requirement — the artifact must BE the deliverable.\n */\nexport function createLlmCorrectnessChecker(\n tc: TCloud,\n opts: LlmCorrectnessCheckerOpts = {},\n): CorrectnessChecker {\n const model = opts.model ?? 'claude-sonnet-4-6'\n const maxContentChars = opts.maxContentChars ?? 8000\n return async (requirement, content) => {\n const resp = await tc.chat({\n model,\n messages: [\n {\n role: 'system',\n content:\n 'You verify whether a produced work artifact actually fulfils a stated requirement. Judge fulfilment only — is the deliverable substantively present and on-point — not polish. A plan to do it later, a vague gesture, or a description of what should be done does NOT fulfil a requirement; the artifact must BE the deliverable. Respond with a single JSON object: {\"correct\": boolean, \"reason\": string (<= 30 words)}.',\n },\n {\n role: 'user',\n content: `Requirement: ${requirement.title}\\n${\n requirement.category ? `Category: ${requirement.category}\\n` : ''\n }\\nProduced artifact:\\n${content.slice(0, maxContentChars)}`,\n },\n ],\n temperature: 0,\n maxTokens: 200,\n })\n const raw =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n return parseCorrectnessResponse(raw)\n }\n}\n\n/** Stopwords for requirement-title tokenization — drops the imperative verbs\n * ('review', 'update', …) common to deliverable titles so recall keys on the\n * substantive nouns, not the boilerplate ask. */\nconst TITLE_STOPWORDS = new Set([\n 'the',\n 'a',\n 'an',\n 'and',\n 'or',\n 'for',\n 'to',\n 'of',\n 'in',\n 'on',\n 'with',\n 'review',\n 'update',\n 'new',\n 'proposed',\n])\n\n/**\n * Deterministic `CorrectnessChecker` — the no-LLM counterpart to\n * `createLlmCorrectnessChecker`. A produced item fulfils a requirement when its\n * content is substantive (≥ `minContentLength` chars) AND recalls ≥ `minRecall`\n * of the requirement title's significant tokens. No network.\n *\n * Polarity-blind: token recall credits a negation that contains the\n * requirement's tokens (\"I will NOT produce the comparison\" recalls every token\n * of \"produce the comparison\"). The structural match stage is ALSO lexical, so\n * pairing the two collapses to a single gameable gate. Use this only as an\n * opt-in structural pre-filter or for tasks whose requirements have no polarity\n * to invert; for produced-state grading the correctness checker MUST be semantic\n * (`createLlmCorrectnessChecker`). See the anti-game fixtures in the test suite.\n */\nexport function createTokenRecallChecker(\n opts: { minRecall?: number; minContentLength?: number } = {},\n): CorrectnessChecker {\n const minRecall = opts.minRecall ?? 0.5\n const minLen = opts.minContentLength ?? 120\n return async (requirement, content) => {\n const body = content.trim()\n if (body.length < minLen)\n return {\n correct: false,\n reason: `content too thin (${body.length} chars) to be the deliverable`,\n }\n const titleTokens = requirement.title\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 2 && !TITLE_STOPWORDS.has(t))\n if (titleTokens.length === 0)\n return {\n correct: true,\n reason: 'requirement title has no significant tokens — structural match accepted',\n }\n const lower = body.toLowerCase()\n const hits = titleTokens.filter((t) => lower.includes(t)).length\n const recall = hits / titleTokens.length\n return recall >= minRecall\n ? {\n correct: true,\n reason: `content recalls ${hits}/${titleTokens.length} requirement tokens`,\n }\n : {\n correct: false,\n reason: `content recalls only ${hits}/${titleTokens.length} requirement tokens`,\n }\n }\n}\n","/**\n * Produced-state extraction — normalize a run's runtime event stream into the\n * typed `ProducedState` the completion oracle consumes.\n *\n * `ProducedState` answers \"what did the agent actually produce\" — vault\n * artifacts, proposals, tool calls. The runtime emits these as a stream of\n * events; this module is the single normalization point from that stream to\n * the shape `verifyCompletion` expects.\n *\n * Input is structurally typed (`RuntimeEventLike`) so this module does not\n * depend on agent-runtime — agent-runtime's `RuntimeStreamEvent` satisfies it\n * structurally. The `content` on `ArtifactEventLike` and the whole\n * `proposal_created` variant are the runtime-side enrichments this contract\n * requires; the runtime emits them, this module consumes them.\n */\n\nimport type { Artifact } from './artifact-validator'\nimport type { ProducedProposal, ProducedState } from './completion-verifier'\n\n/** A tool the agent invoked. */\nexport interface ToolCallEventLike {\n type: 'tool_call'\n toolName: string\n}\n\n/**\n * An artifact the agent produced. `content` is the enriched field — the\n * runtime's base `artifact` event carries only metadata; the completion\n * oracle needs the body to verify the deliverable, so the runtime emits it.\n */\nexport interface ArtifactEventLike {\n type: 'artifact'\n artifactId: string\n name?: string\n mimeType?: string\n uri?: string\n content?: string\n}\n\n/** A proposal / filing the agent created. */\nexport interface ProposalEventLike {\n type: 'proposal_created'\n proposalId: string\n title: string\n status?: 'pending' | 'approved' | 'rejected'\n // body of the proposal (e.g. a submit_proposal `description`). When present,\n // the completion oracle correctness-checks it like artifact content; absent,\n // the proposal is graded presence-only.\n content?: string\n}\n\n/**\n * The subset of runtime stream events `extractProducedState` consumes.\n * agent-runtime's full `RuntimeStreamEvent` union satisfies this structurally;\n * the `{ type: string }` catch-all keeps the input permissive so callers can\n * pass the whole unfiltered telemetry stream — unrecognized events are skipped.\n */\nexport type RuntimeEventLike =\n | ToolCallEventLike\n | ArtifactEventLike\n | ProposalEventLike\n | { type: string }\n\nfunction artifactKind(mimeType: string | undefined): string {\n if (!mimeType) return 'file'\n if (mimeType.includes('json')) return 'json'\n if (mimeType.startsWith('text/')) return 'text'\n return 'file'\n}\n\n/**\n * Normalize a run's runtime event stream into `ProducedState`.\n *\n * Pure and total — unrecognized event types are skipped. `toolCalls` is\n * deduplicated by name in first-seen order (completion cares about a tool's\n * presence, not its call count). An artifact with neither a name nor a uri\n * still yields an entry keyed by its `artifactId` so it is never silently\n * dropped; an artifact with no `content` yields empty content, which the\n * completion oracle's structural check then rejects on its own.\n */\nexport function extractProducedState(events: readonly RuntimeEventLike[]): ProducedState {\n const artifacts: Artifact[] = []\n const proposals: ProducedProposal[] = []\n const toolCalls: string[] = []\n const seenTools = new Set<string>()\n\n for (const ev of events) {\n if (ev.type === 'tool_call') {\n const name = (ev as ToolCallEventLike).toolName\n if (name && !seenTools.has(name)) {\n seenTools.add(name)\n toolCalls.push(name)\n }\n } else if (ev.type === 'artifact') {\n const a = ev as ArtifactEventLike\n artifacts.push({\n kind: artifactKind(a.mimeType),\n path: a.name ?? a.uri ?? a.artifactId,\n content: a.content ?? '',\n })\n } else if (ev.type === 'proposal_created') {\n const p = ev as ProposalEventLike\n proposals.push({\n id: p.proposalId,\n title: p.title,\n status: p.status ?? 'pending',\n ...(p.content !== undefined ? { content: p.content } : {}),\n })\n }\n }\n\n return { artifacts, proposals, toolCalls }\n}\n","import { createHash } from 'node:crypto'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ValidationError } from './errors'\nimport { canonicalize } from './pre-registration'\n\nexport type { AgentProfile } from '@tangle-network/agent-interface'\n\n/**\n * Collision-resistant, path-safe, human-readable profile id for eval artifacts.\n * Scorecard joins still use `agentProfileHash`; this id is for run ids, matrix\n * keys, and directory names where two profiles must not collapse onto one row.\n * The suffix is the first 64 bits of the behaviour hash, enough for ordinary\n * eval matrices while keeping filenames readable.\n */\nexport function agentProfileId(profile: AgentProfile): string {\n const label = pathSafeProfileLabel(agentProfileDisplayLabel(profile)) ?? 'profile'\n return `${label}-${agentProfileHash(profile).slice(0, 16)}`\n}\n\n/**\n * Model snapshot used for `RunRecord.model`. Eval surfaces require a concrete\n * model id because run records reject bare/missing model aliases.\n */\nexport function agentProfileModelId(profile: AgentProfile): string {\n const model = profile.model?.default?.trim()\n if (!model) {\n const label = agentProfileDisplayLabel(profile) ?? 'unnamed profile'\n throw new ValidationError(\n `AgentProfile \"${label}\" has no model.default — cannot record eval run`,\n )\n }\n return model\n}\n\nfunction agentProfileDisplayLabel(profile: AgentProfile): string | undefined {\n return profile.name?.trim() || profile.version?.trim() || undefined\n}\n\nfunction pathSafeProfileLabel(label: string | undefined): string | undefined {\n const safe = label\n ?.trim()\n .replace(/[^A-Za-z0-9._-]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n return safe || undefined\n}\n\nfunction compact<T extends Record<string, unknown>>(input: T): Partial<T> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) out[key] = value\n }\n return out as Partial<T>\n}\n\n/**\n * Deterministic behaviour identity for the canonical\n * `@tangle-network/agent-interface` AgentProfile.\n *\n * `name` and `description` are labels and do not affect the hash. Profile\n * `version`, prompt, model hints, tools, resources, hooks, modes, permissions,\n * and extensions do affect the hash. Resource array order is hash-bearing\n * because mount order can change agent behaviour. Undefined fields are treated\n * as absent; explicit `null` fields remain hash-bearing.\n */\nexport function agentProfileHash(profile: AgentProfile): string {\n const model = agentProfileModelId(profile)\n const behaviour = {\n ...profile,\n name: undefined,\n description: undefined,\n tags: profile.tags ? [...profile.tags].sort() : undefined,\n model: compact({ ...profile.model, default: model }),\n }\n return createHash('sha256')\n .update(JSON.stringify(canonicalize(behaviour)))\n .digest('hex')\n}\n"],"mappings":"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","names":[]}