@tangle-network/traces 0.11.4 → 0.11.5
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/README.md +7 -0
- package/dist/{chunk-AGPOIWPQ.js → chunk-VTYOCFGF.js} +1019 -85
- package/dist/cli.js +64 -5
- package/dist/index.d.ts +288 -4
- package/dist/index.js +36 -74
- package/docs/replay-verify.md +17 -0
- package/docs/trace-analysts.md +28 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
CodexTaskScopeError,
|
|
15
15
|
CopilotAdapter,
|
|
16
16
|
DEFAULT_HARNESS,
|
|
17
|
+
DEFAULT_SANDBOX_BASE_URL,
|
|
17
18
|
EMPTY_SPAN_RUN_SNAPSHOT,
|
|
18
19
|
EXPORT_RULE,
|
|
19
20
|
EmptySessionError,
|
|
@@ -46,8 +47,10 @@ import {
|
|
|
46
47
|
analyzeSpans,
|
|
47
48
|
analyzeSteeringChain,
|
|
48
49
|
applyRedactor,
|
|
50
|
+
assertSandboxReachable,
|
|
49
51
|
buildFixPrompt,
|
|
50
52
|
buildPolicyEvidenceRecord,
|
|
53
|
+
buildRetryFixPrompt,
|
|
51
54
|
buildSessionIndex,
|
|
52
55
|
buildSessionIndexFromRows,
|
|
53
56
|
buildSpanRunTree,
|
|
@@ -56,9 +59,12 @@ import {
|
|
|
56
59
|
chatTrajectoryToSpans,
|
|
57
60
|
classifyLiveActions,
|
|
58
61
|
classifyReaction,
|
|
62
|
+
classifyVerdict,
|
|
59
63
|
claudeActor,
|
|
64
|
+
clipText,
|
|
60
65
|
cmdReplayVerify,
|
|
61
66
|
cmdReplayVerifyBatch,
|
|
67
|
+
cmdVerifyFindings,
|
|
62
68
|
codexActor,
|
|
63
69
|
collectPolicyEvidence,
|
|
64
70
|
collectSessionIndex,
|
|
@@ -68,6 +74,7 @@ import {
|
|
|
68
74
|
commandRedactor,
|
|
69
75
|
conformanceOfSpans,
|
|
70
76
|
connectors,
|
|
77
|
+
countScriptCommands,
|
|
71
78
|
countSkillRunsJsonl,
|
|
72
79
|
cwdMatchesSelection,
|
|
73
80
|
defaultTraceLiveAnalysts,
|
|
@@ -84,6 +91,8 @@ import {
|
|
|
84
91
|
extractFixCommand,
|
|
85
92
|
fileRunContextSupervisorRunReader,
|
|
86
93
|
findSpanSourceFiles,
|
|
94
|
+
findingReplayStep,
|
|
95
|
+
findingTrajectoryId,
|
|
87
96
|
forEachTreeNode,
|
|
88
97
|
generateFixCommand,
|
|
89
98
|
goldIncorrectSteps,
|
|
@@ -114,6 +123,7 @@ import {
|
|
|
114
123
|
otlpRowToSpan,
|
|
115
124
|
outboundHash,
|
|
116
125
|
parseCorpusFlag,
|
|
126
|
+
parseIncorrectStepsSubject,
|
|
117
127
|
parseIsoToEpochMs,
|
|
118
128
|
parseObservationOutput,
|
|
119
129
|
parseRecordedReturncode,
|
|
@@ -121,10 +131,12 @@ import {
|
|
|
121
131
|
parseReplayVerifyArgs,
|
|
122
132
|
parseSession,
|
|
123
133
|
parseSince,
|
|
134
|
+
parseVerifyFindingsArgs,
|
|
124
135
|
planTraceAgenticRoute,
|
|
125
136
|
planUpload,
|
|
126
137
|
readCoordinationLog,
|
|
127
138
|
readFileRunContext,
|
|
139
|
+
readFindingsFile,
|
|
128
140
|
readJsonFile,
|
|
129
141
|
readJsonl,
|
|
130
142
|
readLabelEntries,
|
|
@@ -143,11 +155,15 @@ import {
|
|
|
143
155
|
renderRunWatchSnapshot,
|
|
144
156
|
renderSpanRunSnapshot,
|
|
145
157
|
renderValidation,
|
|
158
|
+
renderVerifiedFindingsSection,
|
|
146
159
|
replayBatchUsage,
|
|
147
160
|
replayVerify,
|
|
161
|
+
replayVerifyFinding,
|
|
148
162
|
replayVerifyUsage,
|
|
149
163
|
resolveAdapter,
|
|
150
164
|
resolveCaseResources,
|
|
165
|
+
resolveFindingInvocation,
|
|
166
|
+
resolveFindingReplayability,
|
|
151
167
|
resolveOtlpInputFiles,
|
|
152
168
|
resolveRepoAttrs,
|
|
153
169
|
resolveRunContextDir,
|
|
@@ -155,6 +171,7 @@ import {
|
|
|
155
171
|
resolveSessionRepoAttrs,
|
|
156
172
|
runCommand,
|
|
157
173
|
runExternalAnalyzers,
|
|
174
|
+
runFixLoop,
|
|
158
175
|
runPipelines,
|
|
159
176
|
runReplayBatch,
|
|
160
177
|
runTotals,
|
|
@@ -201,6 +218,8 @@ import {
|
|
|
201
218
|
userPromptSpan,
|
|
202
219
|
validateOtlpSpans,
|
|
203
220
|
validationExitCode,
|
|
221
|
+
verifyFindings,
|
|
222
|
+
verifyFindingsUsage,
|
|
204
223
|
watchRunTarget,
|
|
205
224
|
watchSessions,
|
|
206
225
|
wrap,
|
|
@@ -214,7 +233,7 @@ import {
|
|
|
214
233
|
writeTraceImprovementArtifacts,
|
|
215
234
|
zaiChatCaller,
|
|
216
235
|
zeroPricedCost
|
|
217
|
-
} from "./chunk-
|
|
236
|
+
} from "./chunk-VTYOCFGF.js";
|
|
218
237
|
|
|
219
238
|
// src/collect.ts
|
|
220
239
|
async function collectSessions(opts = {}) {
|
|
@@ -230,79 +249,6 @@ async function collectSessions(opts = {}) {
|
|
|
230
249
|
return out;
|
|
231
250
|
}
|
|
232
251
|
|
|
233
|
-
// src/replay-wire.ts
|
|
234
|
-
var SUBJECT_PATTERN = /^incorrect-steps-(\d+)-(\d+)-(escaped|unescaped)-consequence-(\d+)$/;
|
|
235
|
-
function parseIncorrectStepsSubject(subject) {
|
|
236
|
-
const match = SUBJECT_PATTERN.exec(subject);
|
|
237
|
-
if (!match) return null;
|
|
238
|
-
return {
|
|
239
|
-
firstStep: Number(match[1]),
|
|
240
|
-
lastStep: Number(match[2]),
|
|
241
|
-
escapeStatus: match[3],
|
|
242
|
-
consequenceStep: Number(match[4])
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
function resolveFindingInvocation(finding, corpora) {
|
|
246
|
-
const subject = parseIncorrectStepsSubject(finding.subject);
|
|
247
|
-
if (!subject) {
|
|
248
|
-
throw new Error(
|
|
249
|
-
`replay-wire: subject '${finding.subject}' is not incorrect-steps-<first>-<last>-<escaped|unescaped>-consequence-<step>`
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
const failures = [];
|
|
253
|
-
for (const corpus of corpora) {
|
|
254
|
-
const resolution = resolveCaseResources(corpus, finding.trajId);
|
|
255
|
-
if (resolution.resolved) {
|
|
256
|
-
const at = subject.firstStep;
|
|
257
|
-
const step = resolution.resources.steps.find((s) => s.step_id === at);
|
|
258
|
-
if (!step) {
|
|
259
|
-
throw new Error(
|
|
260
|
-
`replay-wire: finding step ${at} is outside ${finding.trajId} (${resolution.resources.steps.length} steps)`
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
return { resources: resolution.resources, subject, at };
|
|
264
|
-
}
|
|
265
|
-
failures.push(`${corpus.name}: ${resolution.reason}`);
|
|
266
|
-
}
|
|
267
|
-
throw new Error(
|
|
268
|
-
`replay-wire: trajectory ${finding.trajId} is not replayable in any corpus \u2014 ${failures.join("; ")}`
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
async function replayVerifyFinding(finding, options) {
|
|
272
|
-
if (options.fixCaller && options.fixCommand !== void 0) {
|
|
273
|
-
throw new Error("replay-wire: pass fixCaller or fixCommand, not both");
|
|
274
|
-
}
|
|
275
|
-
const invocation = resolveFindingInvocation(finding, options.corpora);
|
|
276
|
-
let fixCommand = options.fixCommand ?? null;
|
|
277
|
-
if (options.fixCaller) {
|
|
278
|
-
const generated = await generateFixCommand(options.fixCaller, {
|
|
279
|
-
taskStatement: invocation.resources.taskStatement,
|
|
280
|
-
steps: invocation.resources.steps,
|
|
281
|
-
k: invocation.at
|
|
282
|
-
});
|
|
283
|
-
if (!generated.succeeded) {
|
|
284
|
-
throw new Error(`replay-wire: fix generation failed \u2014 ${generated.error}`);
|
|
285
|
-
}
|
|
286
|
-
fixCommand = generated.value.command;
|
|
287
|
-
}
|
|
288
|
-
const verdict = await replayVerify({
|
|
289
|
-
stepsPath: invocation.resources.stepsPath,
|
|
290
|
-
image: invocation.resources.image,
|
|
291
|
-
at: invocation.at,
|
|
292
|
-
fixCommand: fixCommand ?? void 0,
|
|
293
|
-
cwd: invocation.resources.cwd,
|
|
294
|
-
out: options.out,
|
|
295
|
-
caseId: invocation.resources.trajId,
|
|
296
|
-
stepTimeoutMs: options.stepTimeoutMs ?? invocation.resources.recordedStepTimeoutMs ?? void 0,
|
|
297
|
-
prefixLimit: options.prefixLimit,
|
|
298
|
-
backend: options.backend,
|
|
299
|
-
apiKey: options.apiKey,
|
|
300
|
-
baseUrl: options.baseUrl,
|
|
301
|
-
onProgress: options.onProgress
|
|
302
|
-
});
|
|
303
|
-
return { invocation, fixCommand, verdict };
|
|
304
|
-
}
|
|
305
|
-
|
|
306
252
|
// src/index.ts
|
|
307
253
|
import {
|
|
308
254
|
AnalystRegistry,
|
|
@@ -329,6 +275,7 @@ export {
|
|
|
329
275
|
CopilotAdapter,
|
|
330
276
|
DEFAULT_HARNESS,
|
|
331
277
|
DEFAULT_REDACTION_RULES,
|
|
278
|
+
DEFAULT_SANDBOX_BASE_URL,
|
|
332
279
|
EMPTY_SPAN_RUN_SNAPSHOT,
|
|
333
280
|
EXPORT_RULE,
|
|
334
281
|
EmptySessionError,
|
|
@@ -361,9 +308,11 @@ export {
|
|
|
361
308
|
analyzeSpans,
|
|
362
309
|
analyzeSteeringChain,
|
|
363
310
|
applyRedactor,
|
|
311
|
+
assertSandboxReachable,
|
|
364
312
|
buildDefaultAnalystRegistry,
|
|
365
313
|
buildFixPrompt,
|
|
366
314
|
buildPolicyEvidenceRecord,
|
|
315
|
+
buildRetryFixPrompt,
|
|
367
316
|
buildSessionIndex,
|
|
368
317
|
buildSessionIndexFromRows,
|
|
369
318
|
buildSpanRunTree,
|
|
@@ -372,9 +321,12 @@ export {
|
|
|
372
321
|
chatTrajectoryToSpans,
|
|
373
322
|
classifyLiveActions,
|
|
374
323
|
classifyReaction,
|
|
324
|
+
classifyVerdict,
|
|
375
325
|
claudeActor,
|
|
326
|
+
clipText,
|
|
376
327
|
cmdReplayVerify,
|
|
377
328
|
cmdReplayVerifyBatch,
|
|
329
|
+
cmdVerifyFindings,
|
|
378
330
|
codexActor,
|
|
379
331
|
collectPolicyEvidence,
|
|
380
332
|
collectSessionIndex,
|
|
@@ -385,6 +337,7 @@ export {
|
|
|
385
337
|
commandRedactor,
|
|
386
338
|
conformanceOfSpans,
|
|
387
339
|
connectors,
|
|
340
|
+
countScriptCommands,
|
|
388
341
|
countSkillRunsJsonl,
|
|
389
342
|
createHostedClient,
|
|
390
343
|
cwdMatchesSelection,
|
|
@@ -402,6 +355,8 @@ export {
|
|
|
402
355
|
extractFixCommand,
|
|
403
356
|
fileRunContextSupervisorRunReader,
|
|
404
357
|
findSpanSourceFiles,
|
|
358
|
+
findingReplayStep,
|
|
359
|
+
findingTrajectoryId,
|
|
405
360
|
forEachTreeNode,
|
|
406
361
|
generateFixCommand,
|
|
407
362
|
goldIncorrectSteps,
|
|
@@ -442,10 +397,12 @@ export {
|
|
|
442
397
|
parseReplayVerifyArgs,
|
|
443
398
|
parseSession,
|
|
444
399
|
parseSince,
|
|
400
|
+
parseVerifyFindingsArgs,
|
|
445
401
|
planTraceAgenticRoute,
|
|
446
402
|
planUpload,
|
|
447
403
|
readCoordinationLog,
|
|
448
404
|
readFileRunContext,
|
|
405
|
+
readFindingsFile,
|
|
449
406
|
readJsonFile,
|
|
450
407
|
readJsonl,
|
|
451
408
|
readLabelEntries,
|
|
@@ -466,6 +423,7 @@ export {
|
|
|
466
423
|
renderRunWatchSnapshot,
|
|
467
424
|
renderSpanRunSnapshot,
|
|
468
425
|
renderValidation,
|
|
426
|
+
renderVerifiedFindingsSection,
|
|
469
427
|
replayBatchUsage,
|
|
470
428
|
replayVerify,
|
|
471
429
|
replayVerifyFinding,
|
|
@@ -473,6 +431,7 @@ export {
|
|
|
473
431
|
resolveAdapter,
|
|
474
432
|
resolveCaseResources,
|
|
475
433
|
resolveFindingInvocation,
|
|
434
|
+
resolveFindingReplayability,
|
|
476
435
|
resolveOtlpInputFiles,
|
|
477
436
|
resolveRepoAttrs,
|
|
478
437
|
resolveRunContextDir,
|
|
@@ -480,6 +439,7 @@ export {
|
|
|
480
439
|
resolveSessionRepoAttrs,
|
|
481
440
|
runCommand,
|
|
482
441
|
runExternalAnalyzers,
|
|
442
|
+
runFixLoop,
|
|
483
443
|
runPipelines,
|
|
484
444
|
runReplayBatch,
|
|
485
445
|
runTotals,
|
|
@@ -526,6 +486,8 @@ export {
|
|
|
526
486
|
userPromptSpan,
|
|
527
487
|
validateOtlpSpans,
|
|
528
488
|
validationExitCode,
|
|
489
|
+
verifyFindings,
|
|
490
|
+
verifyFindingsUsage,
|
|
529
491
|
watchRunTarget,
|
|
530
492
|
watchSessions,
|
|
531
493
|
wrap,
|
package/docs/replay-verify.md
CHANGED
|
@@ -77,6 +77,17 @@ A corpus is a gold label file plus a prepared directory (`normalized/<traj_id>/s
|
|
|
77
77
|
|
|
78
78
|
Fix generation (`--fix generate`) runs ONE chat completion per arm-A-reproduced case against an OpenAI-compatible endpoint (default: glm-5.2 on z.ai). The prompt carries the gold step's action and observation, ±3 surrounding steps, and the task statement; the reply must be a single corrected shell command. Cases beyond `--max-fix-cases` are excluded by a seeded random sample and marked `sampled-out` in the report. Arm B replays the prefix in its own fresh sandbox and executes the corrected command; `failureVanished` = exit 0 with the failure signature absent.
|
|
79
79
|
|
|
80
|
+
### Iterative fix loop (`--fix loop`)
|
|
81
|
+
|
|
82
|
+
`--fix loop` (in `src/replay-fix-loop.ts`) replaces the single shot with an execution-feedback loop of up to `--fix-attempts` attempts (default 3) per case:
|
|
83
|
+
|
|
84
|
+
- Attempt 1 is byte-identical to the one-shot prompt, so the report's `fixFlipAttempt1` stays directly comparable to `--fix generate`.
|
|
85
|
+
- When an arm fails (nonzero exit or the failure signature persists) or the model call itself fails, the next prompt carries every prior command with its REAL executed stdout/stderr (clipped tails), never a paraphrase.
|
|
86
|
+
- Retries may answer with a short script — at most 5 commands in one fenced block — executed as ONE `/bin/sh` unit; a longer script is rejected as a failed attempt and the rejection feeds the next prompt.
|
|
87
|
+
- Every attempt runs in its own fresh sandbox with the same replayed prefix. A used sandbox is never mutated mid-arm, so a flip always proves the corrected step against the recorded prefix state, not against debris from an earlier attempt. Wall-time cost is one extra prefix replay per attempt.
|
|
88
|
+
|
|
89
|
+
The report adds `fixFlipAttempt1` (flips at attempt 1 over cases whose attempt 1 executed), `flipsByAttempt`, the full per-attempt trail on each case row (`fix.attempts`), and one `armB-attempt<N>-result.json` per executed attempt (`armB-result.json` keeps the last executed attempt — the flipped one when the loop flips).
|
|
90
|
+
|
|
80
91
|
Honest-reporting notes baked into the report:
|
|
81
92
|
|
|
82
93
|
- A gold step whose recorded observation carries **no returncode** can never satisfy "arm A reproduces the recorded returncode": it counts against the replayability rate and the per-case table says why.
|
|
@@ -99,6 +110,12 @@ const { invocation, fixCommand, verdict } = await replayVerifyFinding(
|
|
|
99
110
|
|
|
100
111
|
The subject grammar is the analyst benchmark's `incorrect-steps-<first>-<last>-<escaped|unescaped>-consequence-<step>`; `--at` is the finding's **first** incorrect step (the finding's claim, which may differ from the gold label). The wire resolves the trajectory across the given corpora, generates the arm-B fix through the same one-call generator (or accepts a pre-supplied `fixCommand`), and returns the full `ReplayVerdict`. It throws with a precise reason when the finding cannot be replayed (malformed subject, unknown trajectory, non-SWE case, step out of range) — the product surfaces that reason instead of a proof.
|
|
101
112
|
|
|
113
|
+
## Product surface — verified findings
|
|
114
|
+
|
|
115
|
+
`traces verify-findings` (and `traces analyze --verify-findings`) runs this proof per recorded analyst finding and annotates each with `reproduced | fix-flipped | divergent | not-replayable` plus a receipt directory.
|
|
116
|
+
Unlike the wire above it accepts the shapes analysts actually emit (`incorrect-step-<n>` subjects, `metadata.block_first_step`, `trace://` evidence refs) and never throws on a finding-shaped dead end — the dead end becomes the finding's honest `not-replayable` receipt.
|
|
117
|
+
See [Verified findings](./trace-analysts.md#verified-findings-executed-replay).
|
|
118
|
+
|
|
102
119
|
## Orchestrator prerequisites
|
|
103
120
|
|
|
104
121
|
replay-verify talks to a sandbox API (`--base-url`); in local development that is the sandbox SDK adapter in front of an orchestrator running the docker driver.
|
package/docs/trace-analysts.md
CHANGED
|
@@ -210,6 +210,34 @@ console.log(renderAnalystBenchmarkMarkdown(result))
|
|
|
210
210
|
Public labels test the measurement code, not the quality of every built-in analyst automatically.
|
|
211
211
|
A real quality claim requires running the analyst over the corresponding trajectories, retaining all rows, and comparing it with named alternatives at equal model and request limits.
|
|
212
212
|
|
|
213
|
+
## Verified findings (executed replay)
|
|
214
|
+
|
|
215
|
+
An analyst finding is a cited claim until something executes it.
|
|
216
|
+
`traces analyze --verify-findings` (and the standalone `traces verify-findings`) replays each finding's trajectory prefix in a real sandbox, re-runs the accused step, and annotates every finding with an executed verdict:
|
|
217
|
+
|
|
218
|
+
| Verdict | Meaning |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `reproduced` | the recorded failure signature (returncode + stable output substring) reproduced when the accused step re-ran |
|
|
221
|
+
| `fix-flipped` | reproduced, and a supplied corrected command made the failure vanish in a fresh replay |
|
|
222
|
+
| `divergent` | the step executed but the recorded failure did not reproduce — evidence against the finding, or against replay fidelity (the receipt carries prefix divergences so you can tell which) |
|
|
223
|
+
| `not-replayable` | the finding could not be executed; the receipt names the precise reason (no step subject, unknown trajectory, no docker image, submit step, …) |
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# Verify the findings an analyze run produced (marks each finding in the report):
|
|
227
|
+
traces analyze --last 1 --llm --verify-findings \
|
|
228
|
+
--replay-corpus holdout=labels.json::prepared/ --verify-out ./receipts
|
|
229
|
+
|
|
230
|
+
# Verify findings recorded earlier (e.g. extracted from an eval result.json):
|
|
231
|
+
traces verify-findings --findings findings.json --out ./receipts \
|
|
232
|
+
--steps normalized/<traj>/steps.json --image <replay-ready-image> --cwd /app
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Findings are matched by the shape analysts emit: subject `incorrect-step-<n>` (or the wire form `incorrect-steps-<f>-<l>-…`), `metadata.block_first_step`, and `trace://<trajectory>/…` evidence refs.
|
|
236
|
+
Findings accusing the same step share one executed proof; each finding still gets its own receipt directory (`receipt.json` plus, when executed, `replay-verdict.json` and `report.md` with real stdout/stderr).
|
|
237
|
+
Verification is execution, not generation: no LLM is involved unless you pass `--fix-command`.
|
|
238
|
+
A missing sandbox is an error when any finding is replayable — verification never silently skips.
|
|
239
|
+
Sandbox setup, execution semantics, and honest limits are in [Replay verification](./replay-verify.md).
|
|
240
|
+
|
|
213
241
|
## Turn findings into improvement
|
|
214
242
|
|
|
215
243
|
Do not train or rewrite policy from an analyst's own prose alone.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/traces",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
4
4
|
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"node": ">=22"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@tangle-network/agent-eval": "0.
|
|
51
|
-
"@tangle-network/agent-runtime": "0.
|
|
50
|
+
"@tangle-network/agent-eval": "0.143.0",
|
|
51
|
+
"@tangle-network/agent-runtime": "0.126.0",
|
|
52
52
|
"@tangle-network/agent-trace-contract": "^1.0.2",
|
|
53
53
|
"@tangle-network/sandbox": "0.17.2"
|
|
54
54
|
},
|