@tangle-network/traces 0.17.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/{chunk-SGQOMHZP.js → chunk-YVCHWHCA.js} +130 -48
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +109 -1
- package/docs/trace-analysts.md +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -566,6 +566,23 @@ Do not pass `--llm`; the command is model-backed by definition.
|
|
|
566
566
|
|
|
567
567
|
## Session facts
|
|
568
568
|
|
|
569
|
+
The SDK also accepts verified retained captures through
|
|
570
|
+
`parseRetainedSession({ harness, nativeSessionId, files, signal? })`.
|
|
571
|
+
Pass files as `{ path, content }` with their original relative layout.
|
|
572
|
+
Runtime or the caller owns custody, digest verification and capture completeness.
|
|
573
|
+
The reader uses existing adapters and selects a file only when native records
|
|
574
|
+
establish the supplied session identity.
|
|
575
|
+
It does not inspect the host session catalog or infer identity from filenames.
|
|
576
|
+
Directory-only stores and formats without a recorded native identity remain unavailable.
|
|
577
|
+
The returned source files, duplicate snapshots and unselected files explain the selection.
|
|
578
|
+
Identical or append-only copies count once; divergent histories remain unavailable.
|
|
579
|
+
Parsing is bounded to 1024 text files, 16 MiB per file, and 64 MiB total.
|
|
580
|
+
No model calls occur.
|
|
581
|
+
Call `buildSessionFactsReport(selection.spans, { includeContent: false })` to
|
|
582
|
+
withhold native bodies from the resulting facts.
|
|
583
|
+
The reader itself returns spans containing native content, for local trusted consumers only.
|
|
584
|
+
|
|
585
|
+
|
|
569
586
|
The same facts sheet includes observed tool outcomes, captured input/output byte
|
|
570
587
|
volumes, call-to-result intervals, compaction boundaries and available context
|
|
571
588
|
sizes, spawn intervals, and existing skill invocation/document-read evidence.
|
|
@@ -1025,8 +1025,8 @@ var OTLP_WRITE_CHUNK_CHARS = 4 * 1024 * 1024;
|
|
|
1025
1025
|
async function writeOtlpFile(spans, outPath) {
|
|
1026
1026
|
const { mkdtemp: mkdtemp8, open: open2 } = await import("fs/promises");
|
|
1027
1027
|
const { tmpdir: tmpdir8 } = await import("os");
|
|
1028
|
-
const { join:
|
|
1029
|
-
const path = outPath ??
|
|
1028
|
+
const { join: join36 } = await import("path");
|
|
1029
|
+
const path = outPath ?? join36(await mkdtemp8(join36(tmpdir8(), "traces-")), "spans.otlp.jsonl");
|
|
1030
1030
|
const handle = await open2(path, "w");
|
|
1031
1031
|
try {
|
|
1032
1032
|
let chunk = "";
|
|
@@ -1488,6 +1488,7 @@ var AmpAdapter = class {
|
|
|
1488
1488
|
const spans = [
|
|
1489
1489
|
span({ traceId, spanId: rootId, parentSpanId: null, name: "session", kind: "AGENT", startTime: start, service: SERVICE, agent: SERVICE })
|
|
1490
1490
|
];
|
|
1491
|
+
if (thread.id) spans[0].attributes["tangle.sessionId"] = thread.id;
|
|
1491
1492
|
const toolByUseId = /* @__PURE__ */ new Map();
|
|
1492
1493
|
let step = 0;
|
|
1493
1494
|
for (const m of messages) {
|
|
@@ -2212,6 +2213,7 @@ function normalizeClaudeIds(spans) {
|
|
|
2212
2213
|
const sourceTraceId = item.trace_id;
|
|
2213
2214
|
const sourceSpanId = item.span_id;
|
|
2214
2215
|
const sourceParentSpanId = item.parent_span_id;
|
|
2216
|
+
item.attributes["tangle.sessionId"] = sourceTraceId;
|
|
2215
2217
|
item.attributes[CLAUDE_SOURCE_TRACE_ID] = sourceTraceId;
|
|
2216
2218
|
item.attributes[CLAUDE_SOURCE_SPAN_ID] = sourceSpanId;
|
|
2217
2219
|
if (sourceParentSpanId !== null) {
|
|
@@ -3985,9 +3987,9 @@ function itemCountsJson(counts) {
|
|
|
3985
3987
|
}
|
|
3986
3988
|
function placeInnerSpans(pending, windows) {
|
|
3987
3989
|
return pending.map((entry) => {
|
|
3988
|
-
const { parent, join:
|
|
3990
|
+
const { parent, join: join36 } = joinItem(windows, entry.startMs, entry.endMs);
|
|
3989
3991
|
if (parent) entry.span.parent_span_id = parent.span_id;
|
|
3990
|
-
entry.span.attributes["traces.codex.item_join"] =
|
|
3992
|
+
entry.span.attributes["traces.codex.item_join"] = join36;
|
|
3991
3993
|
return entry.span;
|
|
3992
3994
|
});
|
|
3993
3995
|
}
|
|
@@ -5130,6 +5132,7 @@ var CodexExecAdapter = class {
|
|
|
5130
5132
|
service: SERVICE4,
|
|
5131
5133
|
agent: SERVICE4,
|
|
5132
5134
|
extra: {
|
|
5135
|
+
"tangle.sessionId": threadId,
|
|
5133
5136
|
"traces.codex.stream_format": "exec-jsonl",
|
|
5134
5137
|
"traces.session.role": "operator"
|
|
5135
5138
|
}
|
|
@@ -5594,6 +5597,7 @@ var FactoryAdapter = class {
|
|
|
5594
5597
|
"session.output_tokens": settings.tokenUsage.outputTokens ?? 0
|
|
5595
5598
|
} : void 0
|
|
5596
5599
|
});
|
|
5600
|
+
if (sessionLine?.id) root.attributes["tangle.sessionId"] = sessionLine.id;
|
|
5597
5601
|
return [root, ...spans];
|
|
5598
5602
|
}
|
|
5599
5603
|
};
|
|
@@ -5653,6 +5657,7 @@ var ForgeAdapter = class {
|
|
|
5653
5657
|
const spans = [
|
|
5654
5658
|
span({ traceId, spanId: rootId, parentSpanId: null, name: "session", kind: "AGENT", startTime: (/* @__PURE__ */ new Date(0)).toISOString(), service: SERVICE7, agent: SERVICE7 })
|
|
5655
5659
|
];
|
|
5660
|
+
if (ctx.conversation_id) spans[0].attributes["tangle.sessionId"] = ctx.conversation_id;
|
|
5656
5661
|
const toolByCallId = /* @__PURE__ */ new Map();
|
|
5657
5662
|
let step = 0;
|
|
5658
5663
|
let lastLlm = rootId;
|
|
@@ -5833,6 +5838,7 @@ var GeminiFamilyAdapter = class {
|
|
|
5833
5838
|
agent: this.service
|
|
5834
5839
|
})
|
|
5835
5840
|
];
|
|
5841
|
+
if (session.sessionId) spans[0].attributes["tangle.sessionId"] = session.sessionId;
|
|
5836
5842
|
let step = 0;
|
|
5837
5843
|
for (const m of messages) {
|
|
5838
5844
|
const mid = m.id ?? `m${step}`;
|
|
@@ -6418,6 +6424,7 @@ var PiAdapter = class {
|
|
|
6418
6424
|
agent: SERVICE9,
|
|
6419
6425
|
extra: { "traces.pi.stop_reason": terminal.stopReason }
|
|
6420
6426
|
});
|
|
6427
|
+
if (sessionLine?.id) root.attributes["tangle.sessionId"] = sessionLine.id;
|
|
6421
6428
|
return [root, ...spans];
|
|
6422
6429
|
}
|
|
6423
6430
|
};
|
|
@@ -15311,6 +15318,7 @@ function assertPositiveInteger(name, value) {
|
|
|
15311
15318
|
import { createHash as createHash14 } from "crypto";
|
|
15312
15319
|
import { request as httpRequest } from "http";
|
|
15313
15320
|
import { request as httpsRequest } from "https";
|
|
15321
|
+
import { join as join25 } from "path";
|
|
15314
15322
|
var DEFAULT_BRIDGE_URL = "http://localhost:4181";
|
|
15315
15323
|
var DEFAULT_MODEL = "prime/zai/glm-5.2";
|
|
15316
15324
|
var DEFAULT_TIMEOUT_MS = 12e5;
|
|
@@ -15326,9 +15334,9 @@ async function fileDelivery(otlpPath, perAttributeCharCap, signal) {
|
|
|
15326
15334
|
signal?.throwIfAborted();
|
|
15327
15335
|
const { copyFile: copyFile2, mkdtemp: mkdtemp8, stat: stat19 } = await import("fs/promises");
|
|
15328
15336
|
const { tmpdir: tmpdir8 } = await import("os");
|
|
15329
|
-
const { join:
|
|
15330
|
-
const cwd = await mkdtemp8(
|
|
15331
|
-
await copyFile2(otlpPath,
|
|
15337
|
+
const { join: join36 } = await import("path");
|
|
15338
|
+
const cwd = await mkdtemp8(join36(tmpdir8(), "traces-prime-"));
|
|
15339
|
+
await copyFile2(otlpPath, join36(cwd, TRAJECTORY_FILE_NAME));
|
|
15332
15340
|
const artifactBytes = (await stat19(otlpPath)).size;
|
|
15333
15341
|
return { mode: "file-cwd", perAttributeCharCap, renderedChars: artifactBytes, cwd, fileName: TRAJECTORY_FILE_NAME };
|
|
15334
15342
|
}
|
|
@@ -15482,9 +15490,15 @@ var FILE_DELIVERY_CONTRACT_LINES = [
|
|
|
15482
15490
|
"Do NOT include a rationale field. Keep every string SHORT \u2014 long strings get corrupted in transport and void your work.",
|
|
15483
15491
|
`Report at most ${MAX_FINDINGS} findings; a finding cites 1..${MAX_SPAN_IDS_PER_FINDING} span_ids, each copied VERBATIM from a span in ${TRAJECTORY_FILE_NAME}.`,
|
|
15484
15492
|
'"findings" is [] only for a clean trajectory.',
|
|
15493
|
+
`PAYLOAD CHANNEL \u2014 do this BEFORE your final message: WRITE the complete JSON object (same schema as`,
|
|
15494
|
+
"the reply contract) to a file named findings.json in your working directory, using your tools (python",
|
|
15495
|
+
"or shell). One assistant message has an output-token cap and a cut reply is discarded unread;",
|
|
15496
|
+
"findings.json is the durable channel a large result must travel on. Write it first, incrementally if",
|
|
15497
|
+
"it is long, THEN send your final message: the fenced ```json block when it is short enough to fit,",
|
|
15498
|
+
"otherwise ONE line only \u2014 `findings written to findings.json`.",
|
|
15485
15499
|
"FINAL MESSAGE RULE: after your REPL work is done, send ONE last message that contains NOTHING BUT the",
|
|
15486
|
-
"fenced ```json block above \u2014 no preamble, no summary, no code identifiers
|
|
15487
|
-
"message is prose or a partial block is discarded unread."
|
|
15500
|
+
"fenced ```json block (or the one-line pointer above) \u2014 no preamble, no summary, no code identifiers",
|
|
15501
|
+
"around it. A reply whose last message is prose or a partial block is discarded unread."
|
|
15488
15502
|
];
|
|
15489
15503
|
function buildPrompt(question, projection) {
|
|
15490
15504
|
if (projection.delivery.mode === "file-cwd") {
|
|
@@ -15521,7 +15535,7 @@ function buildRepairPrompt(parseDefect, previousReply, finishReason) {
|
|
|
15521
15535
|
' "severity": "critical"|"high"|"medium"|"low"|"info", "area": string (max 40 chars),',
|
|
15522
15536
|
' "claim": string (max 200 chars), "action": string (optional, max 200 chars), "confidence": number 0..1}',
|
|
15523
15537
|
"No rationale field. Keep every string SHORT.",
|
|
15524
|
-
truncated ? "Your previous reply was cut off by the output limit
|
|
15538
|
+
truncated ? "Your previous reply was cut off by the output limit. Write the corrected JSON to a file named findings.json in your working directory with your tools (at most 3 findings \u2014 your strongest \u2014 with terse strings, claim and action under 120 chars each), then reply with ONE line: findings written to findings.json." : "Preserve the span ids and verdicts of your previous reply exactly; shorten prose freely.",
|
|
15525
15539
|
"",
|
|
15526
15540
|
"PREVIOUS REPLY:",
|
|
15527
15541
|
previousReply
|
|
@@ -15556,6 +15570,59 @@ function parseDefectOf(parsed) {
|
|
|
15556
15570
|
if (!Array.isArray(parsed.findings)) return 'JSON has no "findings" array';
|
|
15557
15571
|
return null;
|
|
15558
15572
|
}
|
|
15573
|
+
var FINDINGS_FILE_MAX_BYTES = 256 * 1024;
|
|
15574
|
+
var FINDINGS_FILE_NAME = "findings.json";
|
|
15575
|
+
async function readFindingsFile2(cwd, signal) {
|
|
15576
|
+
signal?.throwIfAborted();
|
|
15577
|
+
const path = join25(cwd, FINDINGS_FILE_NAME);
|
|
15578
|
+
let raw;
|
|
15579
|
+
const { readFile: readFile20, stat: stat19 } = await import("fs/promises");
|
|
15580
|
+
try {
|
|
15581
|
+
const size = (await stat19(path)).size;
|
|
15582
|
+
if (size > FINDINGS_FILE_MAX_BYTES) {
|
|
15583
|
+
return { parsed: null, receipt: `${FINDINGS_FILE_NAME} is ${size} bytes (cap ${FINDINGS_FILE_MAX_BYTES}); refused` };
|
|
15584
|
+
}
|
|
15585
|
+
raw = await readFile20(path, "utf8");
|
|
15586
|
+
} catch {
|
|
15587
|
+
return void 0;
|
|
15588
|
+
}
|
|
15589
|
+
const direct = extractJsonObject(raw);
|
|
15590
|
+
if (direct !== null && parseDefectOf(direct) === null) {
|
|
15591
|
+
return { parsed: direct, receipt: `${FINDINGS_FILE_NAME} read (${raw.length} chars)` };
|
|
15592
|
+
}
|
|
15593
|
+
const rows = [];
|
|
15594
|
+
let droppedLines = 0;
|
|
15595
|
+
let answer = null;
|
|
15596
|
+
for (const [index, line] of raw.split("\n").entries()) {
|
|
15597
|
+
const trimmed = line.trim();
|
|
15598
|
+
if (trimmed.length === 0) continue;
|
|
15599
|
+
const row = extractJsonObject(trimmed);
|
|
15600
|
+
if (row === null) {
|
|
15601
|
+
droppedLines += 1;
|
|
15602
|
+
continue;
|
|
15603
|
+
}
|
|
15604
|
+
if (typeof row.answer === "string" && !Array.isArray(row.findings)) {
|
|
15605
|
+
if (answer === null) answer = row.answer;
|
|
15606
|
+
continue;
|
|
15607
|
+
}
|
|
15608
|
+
if (Array.isArray(row.findings)) {
|
|
15609
|
+
rows.push(...row.findings);
|
|
15610
|
+
if (answer === null && typeof row.answer === "string") answer = row.answer;
|
|
15611
|
+
continue;
|
|
15612
|
+
}
|
|
15613
|
+
rows.push(row);
|
|
15614
|
+
}
|
|
15615
|
+
if (rows.length === 0) {
|
|
15616
|
+
return {
|
|
15617
|
+
parsed: null,
|
|
15618
|
+
receipt: `${FINDINGS_FILE_NAME} unreadable (no parseable object${droppedLines > 0 ? `, ${droppedLines} malformed line(s) dropped` : ""})`
|
|
15619
|
+
};
|
|
15620
|
+
}
|
|
15621
|
+
return {
|
|
15622
|
+
parsed: { ...answer !== null ? { answer } : {}, findings: rows },
|
|
15623
|
+
receipt: `${FINDINGS_FILE_NAME} read as JSONL (${rows.length} row(s)${droppedLines > 0 ? `, ${droppedLines} malformed line(s) dropped` : ""})`
|
|
15624
|
+
};
|
|
15625
|
+
}
|
|
15559
15626
|
function findingRowDefect(row, spanTraces) {
|
|
15560
15627
|
if (!row || typeof row !== "object" || Array.isArray(row)) return "row is not an object";
|
|
15561
15628
|
const record2 = row;
|
|
@@ -15779,11 +15846,25 @@ function primeAnalyzer(opts = {}) {
|
|
|
15779
15846
|
parsed = extractJsonObject(repairReply.content);
|
|
15780
15847
|
parseDefect = parseDefectOf(parsed);
|
|
15781
15848
|
}
|
|
15849
|
+
let channel = "reply";
|
|
15850
|
+
let channelReceipt = "";
|
|
15782
15851
|
if (parseDefect !== null) {
|
|
15783
|
-
|
|
15784
|
-
|
|
15785
|
-
|
|
15786
|
-
|
|
15852
|
+
const deliveryCwd2 = projection.delivery.mode === "file-cwd" ? projection.delivery.cwd : void 0;
|
|
15853
|
+
const file = deliveryCwd2 !== void 0 ? await readFindingsFile2(deliveryCwd2, analyzeOpts.signal).catch(() => void 0) : void 0;
|
|
15854
|
+
if (file?.parsed !== null && file !== void 0) {
|
|
15855
|
+
parsed = file.parsed;
|
|
15856
|
+
parseDefect = parseDefectOf(parsed);
|
|
15857
|
+
if (parseDefect === null) {
|
|
15858
|
+
channel = FINDINGS_FILE_NAME;
|
|
15859
|
+
channelReceipt = file.receipt;
|
|
15860
|
+
}
|
|
15861
|
+
}
|
|
15862
|
+
if (parseDefect !== null) {
|
|
15863
|
+
return failure(
|
|
15864
|
+
reply.content,
|
|
15865
|
+
`${parseDefect} in prime reply${repairAttempted ? " even after the bounded repair turn" : ""}` + (file === void 0 ? "; no findings.json in the run directory" : `; ${file.receipt}`) + `; ${renderUsage(usage)}`
|
|
15866
|
+
);
|
|
15867
|
+
}
|
|
15787
15868
|
}
|
|
15788
15869
|
const rows = parsed.findings.slice(0, MAX_FINDINGS);
|
|
15789
15870
|
const overflow = parsed.findings.length - rows.length;
|
|
@@ -15804,6 +15885,7 @@ function primeAnalyzer(opts = {}) {
|
|
|
15804
15885
|
`findings: ${findings.length} mapped, ${rejected.length} rejected` + (overflow > 0 ? `, ${overflow} over the ${MAX_FINDINGS}-finding cap dropped` : ""),
|
|
15805
15886
|
...rejected,
|
|
15806
15887
|
deliveryLine,
|
|
15888
|
+
...channel !== "reply" ? [`reply channel: ${channel} \u2014 ${channelReceipt}; the chat reply was unparseable, the payload file carried the result`] : [],
|
|
15807
15889
|
`repair: ${repairAttempted ? "attempted (succeeded)" : "not needed"}`,
|
|
15808
15890
|
renderUsage(usage),
|
|
15809
15891
|
...findings.length === 0 ? ["zero findings \u2014 an honest null, not a failure"] : []
|
|
@@ -15908,7 +15990,7 @@ async function applyRedactor(spans, redactor) {
|
|
|
15908
15990
|
import { createHash as createHash15 } from "crypto";
|
|
15909
15991
|
import { mkdtemp as mkdtemp6, readFile as readFile12, writeFile as writeFile8 } from "fs/promises";
|
|
15910
15992
|
import { tmpdir as tmpdir6 } from "os";
|
|
15911
|
-
import { join as
|
|
15993
|
+
import { join as join26 } from "path";
|
|
15912
15994
|
import {
|
|
15913
15995
|
firstNumberAttr as firstNumberAttr2,
|
|
15914
15996
|
LLM_CACHED_TOKEN_ATTR_KEYS,
|
|
@@ -16579,7 +16661,7 @@ async function exportTraceEvidenceFile(inputPath, opts = {}) {
|
|
|
16579
16661
|
}
|
|
16580
16662
|
async function writeTraceEvidenceExportFile(inputPath, outPath, opts = {}) {
|
|
16581
16663
|
const result = await exportTraceEvidenceFile(inputPath, opts);
|
|
16582
|
-
const path = outPath ??
|
|
16664
|
+
const path = outPath ?? join26(await mkdtemp6(join26(tmpdir6(), "traces-export-")), "spans.openinference.jsonl");
|
|
16583
16665
|
await writeFile8(path, serializeSpans(result.spans), "utf8");
|
|
16584
16666
|
return { ...result, path };
|
|
16585
16667
|
}
|
|
@@ -16587,7 +16669,7 @@ async function writeTraceEvidenceExportFile(inputPath, outPath, opts = {}) {
|
|
|
16587
16669
|
// src/inspect.ts
|
|
16588
16670
|
import { mkdtemp as mkdtemp7, readFile as readFile13, writeFile as writeFile9 } from "fs/promises";
|
|
16589
16671
|
import { tmpdir as tmpdir7 } from "os";
|
|
16590
|
-
import { basename as basename14, join as
|
|
16672
|
+
import { basename as basename14, join as join27 } from "path";
|
|
16591
16673
|
var severityRank2 = {
|
|
16592
16674
|
high: 0,
|
|
16593
16675
|
medium: 1,
|
|
@@ -16876,7 +16958,7 @@ async function readSessionIndexFile(path) {
|
|
|
16876
16958
|
return parsed;
|
|
16877
16959
|
}
|
|
16878
16960
|
async function writeInspectionReportFile(report, outPath) {
|
|
16879
|
-
const path = outPath ??
|
|
16961
|
+
const path = outPath ?? join27(await mkdtemp7(join27(tmpdir7(), "traces-inspect-")), "inspection-report.md");
|
|
16880
16962
|
await writeFile9(path, renderInspectionReport(report), "utf8");
|
|
16881
16963
|
return path;
|
|
16882
16964
|
}
|
|
@@ -17310,7 +17392,7 @@ async function streamSessions(opts) {
|
|
|
17310
17392
|
|
|
17311
17393
|
// src/supervisor-run-context.ts
|
|
17312
17394
|
import { readFile as readFile14, stat as stat16 } from "fs/promises";
|
|
17313
|
-
import { basename as basename15, join as
|
|
17395
|
+
import { basename as basename15, join as join28 } from "path";
|
|
17314
17396
|
import { materializeTreeView } from "@tangle-network/agent-runtime/kernel";
|
|
17315
17397
|
import {
|
|
17316
17398
|
readRuntimeSupervisorRun
|
|
@@ -17472,14 +17554,14 @@ function parseInstant(v) {
|
|
|
17472
17554
|
}
|
|
17473
17555
|
async function readFileRunContext(runDir, opts = {}) {
|
|
17474
17556
|
const sources = await readRuntimeSupervisorRun(runDir);
|
|
17475
|
-
const coordination = readCoordinationLog(await readMaybe(
|
|
17557
|
+
const coordination = readCoordinationLog(await readMaybe(join28(runDir, COORDINATION_LOG_FILE)));
|
|
17476
17558
|
return {
|
|
17477
17559
|
...sources,
|
|
17478
17560
|
instanceId: opts.instanceId !== void 0 ? opts.instanceId : sources.instanceId,
|
|
17479
17561
|
arm: opts.arm !== void 0 ? opts.arm : basename15(runDir),
|
|
17480
17562
|
workers: sources.workers !== null && coordination.present ? workerSources(sources.workers, coordination) : sources.workers,
|
|
17481
17563
|
...sources.journal !== null ? {
|
|
17482
|
-
rootTranscriptRef:
|
|
17564
|
+
rootTranscriptRef: join28(runDir, SPAWN_JOURNAL_FILE),
|
|
17483
17565
|
traceCommand: `traces watch ${runDir}`
|
|
17484
17566
|
} : {}
|
|
17485
17567
|
};
|
|
@@ -17488,7 +17570,7 @@ function fileRunContextSupervisorRunReader(runDir, opts = {}) {
|
|
|
17488
17570
|
return { runRef: runDir, read: () => readFileRunContext(runDir, opts) };
|
|
17489
17571
|
}
|
|
17490
17572
|
async function isFileRunContextDir(runDir) {
|
|
17491
|
-
return stat16(
|
|
17573
|
+
return stat16(join28(runDir, SPAWN_JOURNAL_FILE)).then((s) => s.isFile()).catch(() => false);
|
|
17492
17574
|
}
|
|
17493
17575
|
function parseJsonObject(text2) {
|
|
17494
17576
|
if (text2 === null) return null;
|
|
@@ -17554,9 +17636,9 @@ function mergeRolls(a, b) {
|
|
|
17554
17636
|
};
|
|
17555
17637
|
}
|
|
17556
17638
|
async function readRunContextSnapshot(runDir) {
|
|
17557
|
-
const journal = readRunContextJournal(await readMaybe(
|
|
17558
|
-
const coordination = readCoordinationLog(await readMaybe(
|
|
17559
|
-
const resultText = await readMaybe(
|
|
17639
|
+
const journal = readRunContextJournal(await readMaybe(join28(runDir, SPAWN_JOURNAL_FILE)));
|
|
17640
|
+
const coordination = readCoordinationLog(await readMaybe(join28(runDir, COORDINATION_LOG_FILE)));
|
|
17641
|
+
const resultText = await readMaybe(join28(runDir, RESULT_FILE));
|
|
17560
17642
|
const result = parseResult(resultText);
|
|
17561
17643
|
const view = safeTreeView(journal.events);
|
|
17562
17644
|
const nodes = view === null ? [] : orderNodes(view, journal);
|
|
@@ -17739,7 +17821,7 @@ function wrap(text2, indent) {
|
|
|
17739
17821
|
|
|
17740
17822
|
// src/run-span-tree.ts
|
|
17741
17823
|
import { readdir as readdir18 } from "fs/promises";
|
|
17742
|
-
import { join as
|
|
17824
|
+
import { join as join29 } from "path";
|
|
17743
17825
|
import {
|
|
17744
17826
|
firstNumberAttr as firstNumberAttr3,
|
|
17745
17827
|
LLM_COST_ATTR_KEYS as LLM_COST_ATTR_KEYS2,
|
|
@@ -18014,7 +18096,7 @@ async function findSpanSourceFiles(dir) {
|
|
|
18014
18096
|
const found = [];
|
|
18015
18097
|
const entries = await readdir18(dir, { withFileTypes: true }).catch(() => []);
|
|
18016
18098
|
for (const entry of entries) {
|
|
18017
|
-
const child =
|
|
18099
|
+
const child = join29(dir, entry.name);
|
|
18018
18100
|
if (entry.isFile()) {
|
|
18019
18101
|
if (SPAN_FILE_PATTERN.test(entry.name)) found.push(child);
|
|
18020
18102
|
continue;
|
|
@@ -18022,7 +18104,7 @@ async function findSpanSourceFiles(dir) {
|
|
|
18022
18104
|
if (!entry.isDirectory()) continue;
|
|
18023
18105
|
const nested = await readdir18(child, { withFileTypes: true }).catch(() => []);
|
|
18024
18106
|
for (const inner of nested) {
|
|
18025
|
-
if (inner.isFile() && SPAN_FILE_PATTERN.test(inner.name)) found.push(
|
|
18107
|
+
if (inner.isFile() && SPAN_FILE_PATTERN.test(inner.name)) found.push(join29(child, inner.name));
|
|
18026
18108
|
}
|
|
18027
18109
|
}
|
|
18028
18110
|
return found.sort();
|
|
@@ -18030,7 +18112,7 @@ async function findSpanSourceFiles(dir) {
|
|
|
18030
18112
|
|
|
18031
18113
|
// src/supervisor-run-watch.ts
|
|
18032
18114
|
import { readdir as readdir19 } from "fs/promises";
|
|
18033
|
-
import { join as
|
|
18115
|
+
import { join as join30 } from "path";
|
|
18034
18116
|
function budget(node) {
|
|
18035
18117
|
const parts = [`${int(node.budget.maxIterations)}it`, `${int(node.budget.maxTokens)}tok`];
|
|
18036
18118
|
if (node.budget.maxUsd !== void 0) parts.push(`$${node.budget.maxUsd.toFixed(2)}`);
|
|
@@ -18174,7 +18256,7 @@ async function resolveRunContextDir(dir) {
|
|
|
18174
18256
|
const candidates = [];
|
|
18175
18257
|
for (const entry of entries) {
|
|
18176
18258
|
if (!entry.isDirectory()) continue;
|
|
18177
|
-
const child =
|
|
18259
|
+
const child = join30(dir, entry.name);
|
|
18178
18260
|
if (await isFileRunContextDir(child)) candidates.push(child);
|
|
18179
18261
|
}
|
|
18180
18262
|
if (candidates.length === 1) return candidates[0];
|
|
@@ -18510,7 +18592,7 @@ function parseJsonAnswer(text2) {
|
|
|
18510
18592
|
|
|
18511
18593
|
// src/ask.ts
|
|
18512
18594
|
import { mkdir as mkdir6, readFile as readFile15, writeFile as writeFile10 } from "fs/promises";
|
|
18513
|
-
import { join as
|
|
18595
|
+
import { join as join31, resolve as resolve11 } from "path";
|
|
18514
18596
|
import { performance } from "perf_hooks";
|
|
18515
18597
|
import { CostCeilingReachedError, CostLedger } from "@tangle-network/agent-eval";
|
|
18516
18598
|
import {
|
|
@@ -19065,8 +19147,8 @@ async function writeTraceQuestionsArtifacts(result, outDir) {
|
|
|
19065
19147
|
await mkdir6(directory, { recursive: true });
|
|
19066
19148
|
const paths = {
|
|
19067
19149
|
directory,
|
|
19068
|
-
result:
|
|
19069
|
-
report:
|
|
19150
|
+
result: join31(directory, "answers.json"),
|
|
19151
|
+
report: join31(directory, "report.md"),
|
|
19070
19152
|
traces: result.otlpPath
|
|
19071
19153
|
};
|
|
19072
19154
|
const { report, ...machine } = result;
|
|
@@ -19130,7 +19212,7 @@ async function watchSessions(opts) {
|
|
|
19130
19212
|
// src/bundle-view.ts
|
|
19131
19213
|
import { createHash as createHash17 } from "crypto";
|
|
19132
19214
|
import { mkdir as mkdir7, readdir as readdir20, readFile as readFile16, writeFile as writeFile11 } from "fs/promises";
|
|
19133
|
-
import { dirname as dirname11, join as
|
|
19215
|
+
import { dirname as dirname11, join as join32, resolve as resolve12 } from "path";
|
|
19134
19216
|
var EVIDENCE_ONLY_ALLOW_LIST = [
|
|
19135
19217
|
{
|
|
19136
19218
|
path: "derived/session-index.json",
|
|
@@ -19254,7 +19336,7 @@ async function findSessionTextLeaks(opts) {
|
|
|
19254
19336
|
const index = /* @__PURE__ */ new Map();
|
|
19255
19337
|
const carried = [];
|
|
19256
19338
|
for (const path of opts.carriedPaths) {
|
|
19257
|
-
const signatures = sessionTextSignatures(await readFile16(
|
|
19339
|
+
const signatures = sessionTextSignatures(await readFile16(join32(opts.viewDir, path), "utf8"));
|
|
19258
19340
|
carried.push({ path, signatures: signatures.size });
|
|
19259
19341
|
for (const signature of signatures) if (!index.has(signature)) index.set(signature, path);
|
|
19260
19342
|
}
|
|
@@ -19262,7 +19344,7 @@ async function findSessionTextLeaks(opts) {
|
|
|
19262
19344
|
const comparedSources = [];
|
|
19263
19345
|
let sourceSignatures = 0;
|
|
19264
19346
|
for (const sourcePath of opts.excludedPaths) {
|
|
19265
|
-
const signatures = sessionTextSignatures(await readFile16(
|
|
19347
|
+
const signatures = sessionTextSignatures(await readFile16(join32(opts.sourceDir, sourcePath), "utf8"));
|
|
19266
19348
|
comparedSources.push(sourcePath);
|
|
19267
19349
|
sourceSignatures += signatures.size;
|
|
19268
19350
|
for (const signature of signatures) {
|
|
@@ -19321,17 +19403,17 @@ async function projectSessionBundle(opts) {
|
|
|
19321
19403
|
const candidates = [];
|
|
19322
19404
|
for (const path of await listSessionBundleFiles(sourceDir)) {
|
|
19323
19405
|
if (path === "manifest.json") continue;
|
|
19324
|
-
const bytes2 = await readFile16(
|
|
19406
|
+
const bytes2 = await readFile16(join32(sourceDir, path));
|
|
19325
19407
|
const sha2562 = createHash17("sha256").update(bytes2).digest("hex");
|
|
19326
19408
|
const recorded = sourceHashes.get(path);
|
|
19327
19409
|
if (!recorded) {
|
|
19328
19410
|
throw new Error(
|
|
19329
|
-
`${
|
|
19411
|
+
`${join32(sourceDir, path)} is not listed in the bundle manifest \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
|
|
19330
19412
|
);
|
|
19331
19413
|
}
|
|
19332
19414
|
if (recorded.sha256 !== sha2562) {
|
|
19333
19415
|
throw new Error(
|
|
19334
|
-
`${
|
|
19416
|
+
`${join32(sourceDir, path)} does not match its manifest hash (${recorded.sha256} recorded, ${sha2562} on disk) \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
|
|
19335
19417
|
);
|
|
19336
19418
|
}
|
|
19337
19419
|
const verdict = classifyEvidenceOnlyPath(path);
|
|
@@ -19367,7 +19449,7 @@ async function projectSessionBundle(opts) {
|
|
|
19367
19449
|
});
|
|
19368
19450
|
continue;
|
|
19369
19451
|
}
|
|
19370
|
-
const target =
|
|
19452
|
+
const target = join32(outDir, candidate.path);
|
|
19371
19453
|
await mkdir7(dirname11(target), { recursive: true });
|
|
19372
19454
|
await writeFile11(target, candidate.bytes);
|
|
19373
19455
|
carriedPaths.push(candidate.path);
|
|
@@ -19384,7 +19466,7 @@ async function projectSessionBundle(opts) {
|
|
|
19384
19466
|
})),
|
|
19385
19467
|
matches: 0
|
|
19386
19468
|
};
|
|
19387
|
-
const sourceManifestBytes = await readFile16(
|
|
19469
|
+
const sourceManifestBytes = await readFile16(join32(sourceDir, "manifest.json"));
|
|
19388
19470
|
const manifest = {
|
|
19389
19471
|
schemaVersion: 2,
|
|
19390
19472
|
kind: "traces.session_bundle",
|
|
@@ -19572,11 +19654,11 @@ function renderRunDiff(report) {
|
|
|
19572
19654
|
// src/upload-state.ts
|
|
19573
19655
|
import { mkdir as mkdir8, readFile as readFile17, writeFile as writeFile12 } from "fs/promises";
|
|
19574
19656
|
import { homedir as homedir12 } from "os";
|
|
19575
|
-
import { dirname as dirname12, join as
|
|
19657
|
+
import { dirname as dirname12, join as join33 } from "path";
|
|
19576
19658
|
import { contentHash } from "@tangle-network/agent-eval";
|
|
19577
19659
|
function stateFile() {
|
|
19578
|
-
const base = process.env.XDG_STATE_HOME ??
|
|
19579
|
-
return
|
|
19660
|
+
const base = process.env.XDG_STATE_HOME ?? join33(homedir12(), ".local", "state");
|
|
19661
|
+
return join33(base, "tangle-traces", "uploaded.json");
|
|
19580
19662
|
}
|
|
19581
19663
|
function uploadKey(harness, sessionId) {
|
|
19582
19664
|
return `${harness}:${sessionId}`;
|
|
@@ -19608,7 +19690,7 @@ function alreadyUploaded(state, harness, sessionId, hash2) {
|
|
|
19608
19690
|
import { readFile as readFile18 } from "fs/promises";
|
|
19609
19691
|
import { createRequire as createRequire2 } from "module";
|
|
19610
19692
|
import { hostname as hostname2 } from "os";
|
|
19611
|
-
import { basename as basename16, join as
|
|
19693
|
+
import { basename as basename16, join as join34 } from "path";
|
|
19612
19694
|
import { hostedClientFromEnv } from "@tangle-network/agent-eval/hosted";
|
|
19613
19695
|
import { assessShareSafety as assessShareSafety2, REDACTION_VERSION, redact as redact2, shareAllowed } from "@tangle-network/agent-eval/traces";
|
|
19614
19696
|
var require2 = createRequire2(import.meta.url);
|
|
@@ -19632,7 +19714,7 @@ async function planUpload(opts = {}) {
|
|
|
19632
19714
|
async function gitBranch(cwd) {
|
|
19633
19715
|
if (!cwd) return void 0;
|
|
19634
19716
|
try {
|
|
19635
|
-
const head = await readFile18(
|
|
19717
|
+
const head = await readFile18(join34(cwd, ".git", "HEAD"), "utf8");
|
|
19636
19718
|
const m = head.match(/^ref:\s*refs\/heads\/(.+)$/m);
|
|
19637
19719
|
return m?.[1]?.trim();
|
|
19638
19720
|
} catch {
|
|
@@ -19808,7 +19890,7 @@ async function executeUpload(plan, opts = {}) {
|
|
|
19808
19890
|
|
|
19809
19891
|
// src/verify-safe.ts
|
|
19810
19892
|
import { lstat as lstat4, readdir as readdir21, readFile as readFile19 } from "fs/promises";
|
|
19811
|
-
import { basename as basename17, extname, join as
|
|
19893
|
+
import { basename as basename17, extname, join as join35, relative as relative7 } from "path";
|
|
19812
19894
|
import {
|
|
19813
19895
|
assessShareSafety as assessShareSafety3,
|
|
19814
19896
|
combineVerdicts as combineVerdicts2
|
|
@@ -19869,7 +19951,7 @@ async function listFiles(target, unreadable) {
|
|
|
19869
19951
|
const out = [];
|
|
19870
19952
|
const walk = async (dir) => {
|
|
19871
19953
|
for (const entry of (await readdir21(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
19872
|
-
const path =
|
|
19954
|
+
const path = join35(dir, entry.name);
|
|
19873
19955
|
if (entry.isDirectory()) await walk(path);
|
|
19874
19956
|
else if (entry.isFile()) out.push(path);
|
|
19875
19957
|
else unreadable.push(`${relative7(target, path)}: not a regular file`);
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -4139,6 +4139,12 @@ interface PrimeAnalyzerOptions {
|
|
|
4139
4139
|
repair?: boolean;
|
|
4140
4140
|
transport?: PrimeTransport;
|
|
4141
4141
|
}
|
|
4142
|
+
interface FindingsFileOutcome {
|
|
4143
|
+
parsed: Record<string, unknown> | null;
|
|
4144
|
+
/** Human-readable receipt for the output: what the file was and what
|
|
4145
|
+
* happened to it. Present whenever a file was found. */
|
|
4146
|
+
receipt: string;
|
|
4147
|
+
}
|
|
4142
4148
|
/** Default transport: plain node:http/https, NOT fetch — undici's fixed 300s
|
|
4143
4149
|
* headers timeout kills prime calls that legitimately run longer; the
|
|
4144
4150
|
* analyzer's AbortSignal is the only deadline. */
|
|
@@ -4934,4 +4940,37 @@ interface ExecuteOptions {
|
|
|
4934
4940
|
/** Send the final, new outbound items (or write their dry-run OTLP). */
|
|
4935
4941
|
declare function executeUpload(plan: UploadPlan, opts?: ExecuteOptions): Promise<UploadResult>;
|
|
4936
4942
|
|
|
4937
|
-
export { ACTOR_ATTR, ATTR, type Actor, type AdoptionOptions, type AdoptionReport, AmpAdapter, type AnalysisEngineFromEnvOptions, type AnalyzeOptions, type AnalyzeResult, type AnswerSchema, type AssembleSessionBundleOptions, BLOBS_DIR, type BuildPolicyEvidenceOptions, type BuildSessionIndexOptions, type BuildTraceFindingPacketOptions, CHANGED_FILE_LIST_CAP, CITATION_NORMALIZATION_VERSION, CONTENT_CAP, COORDINATION_LOG_FILE, CORRECTIVE_REACTIONS, type ChangedFileFact, type ChatTrajectory, type ChatTrajectoryMessage, type ChatTrajectoryOptions, ClaudeAdapter, type CodeTraceBenchFileRef, type CodeTraceBenchImportOptions, type CodeTraceBenchImportReceipt, type CodeTraceBenchImportResult, type CodeTraceBenchImportedTrace, type CodeTraceBenchStep, CodexAdapter, CodexExecAdapter, CodexExecStreamError, CodexTaskScopeError, type CollectOptions, type CollectPolicyEvidenceOptions, type CollectSessionIndexOptions, type CollectSessionSelectionOptions, type CollectSessionWorkflowOptions, type CompactionMeasurement, type ConformanceRenderOptions, type ContentFootprint, type CoordinationLog, type CoordinationQuestion, type CoordinationSteer, CopilotAdapter, type CorruptionMode, type CoveredMeasurement, DEFAULT_ANALYST_MODEL, DEFAULT_ASK_CONCURRENCY, DEFAULT_HARNESS, DEFAULT_SANDBOX_BASE_URL, EMPTY_SPAN_RUN_SNAPSHOT, EXPORT_RULE, EmptySessionError, type EvidenceOnlyVerdict, type ExcludedTurnFact, type ExecuteOptions, type ExportRule, type ExternalAnalysisKind, type ExternalAnalysisPayload, type ExternalAnalysisResult, type ExternalAnalyzer, type ExternalAnalyzerOptions, type ExternalDiscoveryCandidate, FACT_LIST_CAP, FACT_TEXT_CAP, FactoryAdapter, type FailureFollowUp, type FailureFollowUpReport, type FileRunContextReaderOptions, type FinalMessageFact, type FindSessionTextLeaksOptions, type FindingRejectionCounts, type FindingRejectionReasons, type FindingRejectionTally, type FollowUpKind, ForgeAdapter, GeminiAdapter, type HaloAnalyzerOptions, type HaloReasoningEffort, type HarnessTraceAdapter, type HodoscopeAnalyzerOptions, type HodoscopeInput, type HodoscopeMessage, type HodoscopeSourceMapEntry, type HodoscopeTrajectory, INGEST_SOURCE_CLI, INHERITED_SOURCE_ATTR, INHERITED_SPANS_OMITTED_ATTR, INHERITED_SPAN_ATTR, INHERITED_SPAN_COUNT_ATTR, type InheritedSpanSource, type InspectSessionIndexOptions, JsonSourceError, type JsonlCorruptionReceipt, JsonlParseError, type JsonlReadOptions, type LiveBatchOptions, type LocateOptions, type LoopConvergence, type LoopConvergenceReport, type LoopIteration, type LoopTrend, type LoopTrendBasis, MAX_SHELL_DEPTH, MAX_TRACE_QUESTION_CHARS, type ObservedLoop, type ObserverOptions, OpencodeAdapter, type OtlpIngestIssue, type OtlpIngestIssueKind, type OtlpInput, type OtlpInputFile, type OtlpRowConversion, type OtlpSpan, type OtlpSpanKind, type OtlpSpanLink, type OtlpStatusCode, POLICY_EVIDENCE_NOTE, PREPARED_CONTEXT_BYTE_CEILING, type ParentTaskResolution, type ParseOptions, PartialUploadError, PiAdapter, type PiAdapterOptions, type PipelineOptions, type PipelineReport, type PlanOptions, type PolicyEvidenceLoopSummary, type PolicyEvidenceRecord, type PolicyEvidenceToolSummary, type PrimeAnalyzerOptions, type PrimeTransport, type PrimeTransportRequest, type PrimeTransportResponse, type ProjectSessionBundleOptions, type ProjectSessionBundleResult, type PullRequestFact, type PullRequestFacts, type PullRequestReading, QwenAdapter, REACTIONS, RESULT_FILE, RULE, type Reaction, type ReactionReport, type ReactionSessionReport, type RedactSpansOptions, type Redactor, type RefusedSession, type RepoAttrs, type RepoResolution, type RepoResolutionSource, type ResolvedOtlpInput, type RunContextJournal, type RunContextNode, type RunContextResult, type RunContextSnapshot, type RunDiffOptions, type RunDiffReport, type RunDiffSide, type RunResult, type RunWatchSnapshot, type RunWatchTarget, type RuntimeTrace, SESSION_FACTS_MEASUREMENT_VERSION, SESSION_FACTS_VERSION_SUFFIX, SESSION_TOKEN_TOTAL_ATTR, SOURCE_ATTRIBUTE_PREFIX, SPAN_SYNTHESIZED_ATTR, SPAWN_JOURNAL_FILE, STATUS_MARK, SYNTHESIZED_SOURCE_ATTR, SYNTHESIZED_SPAN_ATTR, type SandboxReplayBackendOptions, type ScanOptions, type ScannedSession, type SessionBatch, type SessionBundleAbsence, type SessionBundleCarriedSignatures, type SessionBundleExclusion, type SessionBundleExclusionRule, type SessionBundleFile, type SessionBundleIssue, type SessionBundleIssueKind, type SessionBundleLeakCheck, type SessionBundleLedgerSlice, type SessionBundleManifest, type SessionBundleProjection, type SessionBundleResult, type SessionBundleSliceRule, type SessionBundleVerification, type SessionBundleView, type SessionCorruptionReceipt, type SessionEnvironment, type SessionFact, type SessionFacts, type SessionFactsOptions, type SessionFactsReport, type SessionIdentityConflict, type SessionIdentityIndex, type SessionIntegrity, type SessionMeasurements, type SessionRef, type SessionRelationship, type SessionRole, type SessionSeedGroup, type SessionSelection, type SessionSelectionRow, type SessionSourceFile, type SessionTextLeak, type SessionTextLeakReport, type SessionTurnFact, type SessionWorkflow, SessionWorkflowError, type SessionWorkflowErrorCode, type SessionWorkflowIssue, type SessionWorkflowSession, type SessionWorkflowSummary, type SkippedAnalysis, type SkippedInputFile, type SourceRecordReference, type SpanInput, type SpanNodeStatus, type SpanRedaction, type SpanRunNode, type SpanRunSnapshot, type SpanStructure, type SpawnedChildResolution, type SpendRoll, type SteeringChainReport, type SteeringEdge, type SubagentSpawnFact, TRACE_QUESTION_PREVIEW_HEAD_CHARS, type ToolMeasurement, type TraceAgenticRoute, type TraceAgenticRouteReason, type TraceAgenticRouteReasonCode, type TraceContextIndex, type TraceContextRoot, type TraceEvidenceExportOptions, type TraceEvidenceExportResult, type TraceEvidenceFormatOption, type TraceEvidenceInputFormat, type TraceEvidenceRow, type TraceExecutionOptions, type TraceFindingPacket, type TraceImprovementArtifacts, type TraceImprovementOptions, type TraceImprovementResult, type TraceIndexedFile, type TraceInspectionArea, type TraceInspectionFinding, type TraceInspectionReport, type TraceInspectionSeverity, type TraceInvestigationOptions, type TraceInvestigationResult, type TraceLiveAction, type TraceLiveActionKind, type TraceLiveAnalysisContext, type TraceLiveAnalyst, type TraceLiveBatch, type TraceLiveEvidence, type TraceLiveFinding, type TraceLiveLoop, type TraceLiveSeverity, type TraceQuestion, type TraceQuestionAnswer, type TraceQuestionCitation, type TraceQuestionFailureKind, type TraceQuestionTrace, type TraceQuestionsArtifacts, type TraceQuestionsOptions, type TraceQuestionsResult, type TraceQuestionsTotals, type TraceSessionIndex, type TraceSessionIndexRow, type TraceStoreInvestigationOptions, type TraceStoreInvestigationResult, type TraceStreamEvent, type TraceStreamOptions, type TraceStreamReplayOptions, type TraceStreamSession, type TracesConfig, type TriggerPair, type TurnActorCount, type UnavailableCapabilities, type UploadBackend, type UploadIdentity, type UploadItem, type UploadPlan, type UploadRecord, type UploadResult, type UploadState, type UserPromptInput, type VerifySafeOptions, type VerifySafeResult, type WatchRunTargetOptions, ZERO_ROLL, type ZaiChatCallerOptions, addSpend, alreadyUploaded, analysisEngineFromEnv, analyzeAdoption, analyzeLiveBatch, analyzeLoopConvergence, analyzeReactions, analyzeSpans, analyzeSteeringChain, answerSchemaErrors, applyRedactor, assembleSessionBundle, assertAnswerSchema, assertSandboxReachable, assessSpans, buildPolicyEvidenceRecord, buildSessionFactsReport, buildSessionIndex, buildSessionIndexFromRows, buildSpanRunTree, buildTraceFindingPacket, capText, chatTrajectoryToSpans, classifyEvidenceOnlyPath, classifyFailureFollowUps, classifyLiveActions, classifyReaction, claudeActor, codexActor, collectPolicyEvidence, collectSessionIndex, collectSessionSelection, collectSessionWorkflow, collectSessions, commandAnalyzer, commandRedactor, commandTextFromInput, computeAdoption, computeSessionFacts, conformanceOfSpans, connectors, countSkillRunsJsonl, createBundleSourceReader, createFindingRejectionTally, cwdMatchesSelection, cwdMatchesSelectionResolved, defaultTraceLiveAnalysts, describeSessionRelationship, diffRuns, engineCallReservationFloorUsd, environmentAttributes, environmentFromSpanAttributes, equivalentGitCwds, executeUpload, exportTraceEvidenceFile, exportTraceEvidenceRows, exportTraceEvidenceText, externalFailureMessage, fileRunContextSupervisorRunReader, fileSha256, findContextRoot, findSessionTextLeaks, findSpanSourceFiles, findingRejection, findingRejectionDetail, forEachTreeNode, formatFindingRejections, formatVerdict, haloAnalyzer, hashSessionBundleFiles, hodoscopeAnalyzer, httpJsonTransport, importCodeTraceBench, incompleteInputsNote, indexSessionIdsByTrace, inferRole, inferSpanKind, inspectSessionIndex, int, isBridgeMismatchError, isChatTrajectory, isChatTrajectoryMessage, isFileRunContextDir, isInheritedSpan, isSynthesizedSpan, iterSerializedSpans, knownHarnesses, listAdapters, listSessionBundleFiles, loadState, loadTraceQuestionsFile, loadTracesConfig, locateSessions, looksLikeAgentPrompt, mergeRolls, mergeTracesConfig, ms, normalizeAnalystCitations, normalizeRemote, normalizeTraceQuestions, otlpRowToSpan, outboundHash, parseIsoToEpochMs, parseJsonAnswer, parseSession, parseSince, planTraceAgenticRoute, planUpload, primeAnalyzer, projectSessionBundle, readCoordinationLog, readFileRunContext, readJsonFile, readJsonl, readOtlpInput, readPullRequests, readRunContextJournal, readRunContextSnapshot, readRunSide, readRunWatchSnapshot, readSessionBundleManifest, readSessionIndexFile, readSpanRunSnapshot, recordSessionCorruption, redactSpans, renderConformance, renderInspectionReport, renderRunContextSnapshot, renderRunDiff, renderRunWatchSnapshot, renderSessionFacts, renderSessionFactsContext, renderSpanRunSnapshot, renderTraceQuestionInstructions, renderTraceQuestionPrompt, renderTraceQuestionsReport, renderValidation, resolveAdapter, resolveOtlpInputFiles, resolveRepoAttrs, resolveRunContextDir, resolveRunWatchTarget, resolveSessionRepoAttrs, runCommand, runExternalAnalyzers, runPipelines, runTotals, runTraceImprovement, runTraceInvestigation, runTraceQuestions, runTraceStoreInvestigation, sandboxReplayBackend, saveReport, saveState, scanSessions, selectAdapters, serializeInspectionReport, serializePolicyEvidence, serializeSessionIndex, serializeSpans, serializeTraceStreamEvent, sessionFactsContext, sessionHash, sessionIdFromAttributes, sessionIntegrityAttributes, sessionTextSignatures, shellCommands, skippedAnalyses, span, spanRunTotals, stampEnvironmentAttrs, stampRepoAttrs, stampSessionIdentity, stampSessionIntegrity, stampSpanWorkdirRepoAttrs, streamSessions, summarizeOtlpExecution, summarizeSpanExecution, summarizeSpanStructure, takeJsonl, textIsSynthetic, toOpenInferenceSpan, toRuntimeStore, toTraceSpanEvents, tokens, totalAgenticFailureMessage, totalFindingRejections, traceAgenticKinds, traceCitationsInText, traceStreamEventsFromSpans, unavailableCapabilities, uploadKey, usd, userPromptSpan, validateOtlpSpans, validationExitCode, verdictExitCode, verifyFindingsInSandbox, verifySafe, verifySessionBundle, watchRunTarget, watchSessions, withSessionFactsContext, wrap, writeHodoscopeInput, writeInspectionReportFile, writeOtlpFile, writePolicyEvidenceFile, writeSessionBundleManifest, writeSessionIndexFile, writeTraceEvidenceExportFile, writeTraceImprovementArtifacts, writeTraceQuestionsArtifacts, zaiChatCaller, zeroPricedCost };
|
|
4943
|
+
declare const RETAINED_SESSION_READER_VERSION = "1";
|
|
4944
|
+
interface RetainedSessionFile {
|
|
4945
|
+
readonly path: string;
|
|
4946
|
+
readonly content: string;
|
|
4947
|
+
}
|
|
4948
|
+
interface RetainedSessionSelection {
|
|
4949
|
+
readonly status: 'selected' | 'unavailable';
|
|
4950
|
+
readonly reason: string | null;
|
|
4951
|
+
readonly sessionId: string | null;
|
|
4952
|
+
readonly sourceFiles: readonly {
|
|
4953
|
+
readonly path: string;
|
|
4954
|
+
readonly sha256: string;
|
|
4955
|
+
}[];
|
|
4956
|
+
readonly duplicateFiles: readonly string[];
|
|
4957
|
+
readonly unselectedFiles: readonly {
|
|
4958
|
+
readonly path: string;
|
|
4959
|
+
readonly reason: string;
|
|
4960
|
+
}[];
|
|
4961
|
+
readonly spans: readonly OtlpSpan[];
|
|
4962
|
+
}
|
|
4963
|
+
/**
|
|
4964
|
+
* Parse an explicitly retained capture without consulting the host's session catalog.
|
|
4965
|
+
* Native identity must come from the adapter's records. A path, caller supplied
|
|
4966
|
+
* fallback ID, or worker name never establishes identity. Runtime owns custody,
|
|
4967
|
+
* hash verification, capture completeness, and the binding to its node.
|
|
4968
|
+
*/
|
|
4969
|
+
declare function parseRetainedSession(input: {
|
|
4970
|
+
readonly harness: string;
|
|
4971
|
+
readonly nativeSessionId: string | null;
|
|
4972
|
+
readonly files: readonly RetainedSessionFile[];
|
|
4973
|
+
readonly signal?: AbortSignal;
|
|
4974
|
+
}): Promise<RetainedSessionSelection>;
|
|
4975
|
+
|
|
4976
|
+
export { ACTOR_ATTR, ATTR, type Actor, type AdoptionOptions, type AdoptionReport, AmpAdapter, type AnalysisEngineFromEnvOptions, type AnalyzeOptions, type AnalyzeResult, type AnswerSchema, type AssembleSessionBundleOptions, BLOBS_DIR, type BuildPolicyEvidenceOptions, type BuildSessionIndexOptions, type BuildTraceFindingPacketOptions, CHANGED_FILE_LIST_CAP, CITATION_NORMALIZATION_VERSION, CONTENT_CAP, COORDINATION_LOG_FILE, CORRECTIVE_REACTIONS, type ChangedFileFact, type ChatTrajectory, type ChatTrajectoryMessage, type ChatTrajectoryOptions, ClaudeAdapter, type CodeTraceBenchFileRef, type CodeTraceBenchImportOptions, type CodeTraceBenchImportReceipt, type CodeTraceBenchImportResult, type CodeTraceBenchImportedTrace, type CodeTraceBenchStep, CodexAdapter, CodexExecAdapter, CodexExecStreamError, CodexTaskScopeError, type CollectOptions, type CollectPolicyEvidenceOptions, type CollectSessionIndexOptions, type CollectSessionSelectionOptions, type CollectSessionWorkflowOptions, type CompactionMeasurement, type ConformanceRenderOptions, type ContentFootprint, type CoordinationLog, type CoordinationQuestion, type CoordinationSteer, CopilotAdapter, type CorruptionMode, type CoveredMeasurement, DEFAULT_ANALYST_MODEL, DEFAULT_ASK_CONCURRENCY, DEFAULT_HARNESS, DEFAULT_SANDBOX_BASE_URL, EMPTY_SPAN_RUN_SNAPSHOT, EXPORT_RULE, EmptySessionError, type EvidenceOnlyVerdict, type ExcludedTurnFact, type ExecuteOptions, type ExportRule, type ExternalAnalysisKind, type ExternalAnalysisPayload, type ExternalAnalysisResult, type ExternalAnalyzer, type ExternalAnalyzerOptions, type ExternalDiscoveryCandidate, FACT_LIST_CAP, FACT_TEXT_CAP, FactoryAdapter, type FailureFollowUp, type FailureFollowUpReport, type FileRunContextReaderOptions, type FinalMessageFact, type FindSessionTextLeaksOptions, type FindingRejectionCounts, type FindingRejectionReasons, type FindingRejectionTally, type FindingsFileOutcome, type FollowUpKind, ForgeAdapter, GeminiAdapter, type HaloAnalyzerOptions, type HaloReasoningEffort, type HarnessTraceAdapter, type HodoscopeAnalyzerOptions, type HodoscopeInput, type HodoscopeMessage, type HodoscopeSourceMapEntry, type HodoscopeTrajectory, INGEST_SOURCE_CLI, INHERITED_SOURCE_ATTR, INHERITED_SPANS_OMITTED_ATTR, INHERITED_SPAN_ATTR, INHERITED_SPAN_COUNT_ATTR, type InheritedSpanSource, type InspectSessionIndexOptions, JsonSourceError, type JsonlCorruptionReceipt, JsonlParseError, type JsonlReadOptions, type LiveBatchOptions, type LocateOptions, type LoopConvergence, type LoopConvergenceReport, type LoopIteration, type LoopTrend, type LoopTrendBasis, MAX_SHELL_DEPTH, MAX_TRACE_QUESTION_CHARS, type ObservedLoop, type ObserverOptions, OpencodeAdapter, type OtlpIngestIssue, type OtlpIngestIssueKind, type OtlpInput, type OtlpInputFile, type OtlpRowConversion, type OtlpSpan, type OtlpSpanKind, type OtlpSpanLink, type OtlpStatusCode, POLICY_EVIDENCE_NOTE, PREPARED_CONTEXT_BYTE_CEILING, type ParentTaskResolution, type ParseOptions, PartialUploadError, PiAdapter, type PiAdapterOptions, type PipelineOptions, type PipelineReport, type PlanOptions, type PolicyEvidenceLoopSummary, type PolicyEvidenceRecord, type PolicyEvidenceToolSummary, type PrimeAnalyzerOptions, type PrimeTransport, type PrimeTransportRequest, type PrimeTransportResponse, type ProjectSessionBundleOptions, type ProjectSessionBundleResult, type PullRequestFact, type PullRequestFacts, type PullRequestReading, QwenAdapter, REACTIONS, RESULT_FILE, RETAINED_SESSION_READER_VERSION, RULE, type Reaction, type ReactionReport, type ReactionSessionReport, type RedactSpansOptions, type Redactor, type RefusedSession, type RepoAttrs, type RepoResolution, type RepoResolutionSource, type ResolvedOtlpInput, type RetainedSessionFile, type RetainedSessionSelection, type RunContextJournal, type RunContextNode, type RunContextResult, type RunContextSnapshot, type RunDiffOptions, type RunDiffReport, type RunDiffSide, type RunResult, type RunWatchSnapshot, type RunWatchTarget, type RuntimeTrace, SESSION_FACTS_MEASUREMENT_VERSION, SESSION_FACTS_VERSION_SUFFIX, SESSION_TOKEN_TOTAL_ATTR, SOURCE_ATTRIBUTE_PREFIX, SPAN_SYNTHESIZED_ATTR, SPAWN_JOURNAL_FILE, STATUS_MARK, SYNTHESIZED_SOURCE_ATTR, SYNTHESIZED_SPAN_ATTR, type SandboxReplayBackendOptions, type ScanOptions, type ScannedSession, type SessionBatch, type SessionBundleAbsence, type SessionBundleCarriedSignatures, type SessionBundleExclusion, type SessionBundleExclusionRule, type SessionBundleFile, type SessionBundleIssue, type SessionBundleIssueKind, type SessionBundleLeakCheck, type SessionBundleLedgerSlice, type SessionBundleManifest, type SessionBundleProjection, type SessionBundleResult, type SessionBundleSliceRule, type SessionBundleVerification, type SessionBundleView, type SessionCorruptionReceipt, type SessionEnvironment, type SessionFact, type SessionFacts, type SessionFactsOptions, type SessionFactsReport, type SessionIdentityConflict, type SessionIdentityIndex, type SessionIntegrity, type SessionMeasurements, type SessionRef, type SessionRelationship, type SessionRole, type SessionSeedGroup, type SessionSelection, type SessionSelectionRow, type SessionSourceFile, type SessionTextLeak, type SessionTextLeakReport, type SessionTurnFact, type SessionWorkflow, SessionWorkflowError, type SessionWorkflowErrorCode, type SessionWorkflowIssue, type SessionWorkflowSession, type SessionWorkflowSummary, type SkippedAnalysis, type SkippedInputFile, type SourceRecordReference, type SpanInput, type SpanNodeStatus, type SpanRedaction, type SpanRunNode, type SpanRunSnapshot, type SpanStructure, type SpawnedChildResolution, type SpendRoll, type SteeringChainReport, type SteeringEdge, type SubagentSpawnFact, TRACE_QUESTION_PREVIEW_HEAD_CHARS, type ToolMeasurement, type TraceAgenticRoute, type TraceAgenticRouteReason, type TraceAgenticRouteReasonCode, type TraceContextIndex, type TraceContextRoot, type TraceEvidenceExportOptions, type TraceEvidenceExportResult, type TraceEvidenceFormatOption, type TraceEvidenceInputFormat, type TraceEvidenceRow, type TraceExecutionOptions, type TraceFindingPacket, type TraceImprovementArtifacts, type TraceImprovementOptions, type TraceImprovementResult, type TraceIndexedFile, type TraceInspectionArea, type TraceInspectionFinding, type TraceInspectionReport, type TraceInspectionSeverity, type TraceInvestigationOptions, type TraceInvestigationResult, type TraceLiveAction, type TraceLiveActionKind, type TraceLiveAnalysisContext, type TraceLiveAnalyst, type TraceLiveBatch, type TraceLiveEvidence, type TraceLiveFinding, type TraceLiveLoop, type TraceLiveSeverity, type TraceQuestion, type TraceQuestionAnswer, type TraceQuestionCitation, type TraceQuestionFailureKind, type TraceQuestionTrace, type TraceQuestionsArtifacts, type TraceQuestionsOptions, type TraceQuestionsResult, type TraceQuestionsTotals, type TraceSessionIndex, type TraceSessionIndexRow, type TraceStoreInvestigationOptions, type TraceStoreInvestigationResult, type TraceStreamEvent, type TraceStreamOptions, type TraceStreamReplayOptions, type TraceStreamSession, type TracesConfig, type TriggerPair, type TurnActorCount, type UnavailableCapabilities, type UploadBackend, type UploadIdentity, type UploadItem, type UploadPlan, type UploadRecord, type UploadResult, type UploadState, type UserPromptInput, type VerifySafeOptions, type VerifySafeResult, type WatchRunTargetOptions, ZERO_ROLL, type ZaiChatCallerOptions, addSpend, alreadyUploaded, analysisEngineFromEnv, analyzeAdoption, analyzeLiveBatch, analyzeLoopConvergence, analyzeReactions, analyzeSpans, analyzeSteeringChain, answerSchemaErrors, applyRedactor, assembleSessionBundle, assertAnswerSchema, assertSandboxReachable, assessSpans, buildPolicyEvidenceRecord, buildSessionFactsReport, buildSessionIndex, buildSessionIndexFromRows, buildSpanRunTree, buildTraceFindingPacket, capText, chatTrajectoryToSpans, classifyEvidenceOnlyPath, classifyFailureFollowUps, classifyLiveActions, classifyReaction, claudeActor, codexActor, collectPolicyEvidence, collectSessionIndex, collectSessionSelection, collectSessionWorkflow, collectSessions, commandAnalyzer, commandRedactor, commandTextFromInput, computeAdoption, computeSessionFacts, conformanceOfSpans, connectors, countSkillRunsJsonl, createBundleSourceReader, createFindingRejectionTally, cwdMatchesSelection, cwdMatchesSelectionResolved, defaultTraceLiveAnalysts, describeSessionRelationship, diffRuns, engineCallReservationFloorUsd, environmentAttributes, environmentFromSpanAttributes, equivalentGitCwds, executeUpload, exportTraceEvidenceFile, exportTraceEvidenceRows, exportTraceEvidenceText, externalFailureMessage, fileRunContextSupervisorRunReader, fileSha256, findContextRoot, findSessionTextLeaks, findSpanSourceFiles, findingRejection, findingRejectionDetail, forEachTreeNode, formatFindingRejections, formatVerdict, haloAnalyzer, hashSessionBundleFiles, hodoscopeAnalyzer, httpJsonTransport, importCodeTraceBench, incompleteInputsNote, indexSessionIdsByTrace, inferRole, inferSpanKind, inspectSessionIndex, int, isBridgeMismatchError, isChatTrajectory, isChatTrajectoryMessage, isFileRunContextDir, isInheritedSpan, isSynthesizedSpan, iterSerializedSpans, knownHarnesses, listAdapters, listSessionBundleFiles, loadState, loadTraceQuestionsFile, loadTracesConfig, locateSessions, looksLikeAgentPrompt, mergeRolls, mergeTracesConfig, ms, normalizeAnalystCitations, normalizeRemote, normalizeTraceQuestions, otlpRowToSpan, outboundHash, parseIsoToEpochMs, parseJsonAnswer, parseRetainedSession, parseSession, parseSince, planTraceAgenticRoute, planUpload, primeAnalyzer, projectSessionBundle, readCoordinationLog, readFileRunContext, readJsonFile, readJsonl, readOtlpInput, readPullRequests, readRunContextJournal, readRunContextSnapshot, readRunSide, readRunWatchSnapshot, readSessionBundleManifest, readSessionIndexFile, readSpanRunSnapshot, recordSessionCorruption, redactSpans, renderConformance, renderInspectionReport, renderRunContextSnapshot, renderRunDiff, renderRunWatchSnapshot, renderSessionFacts, renderSessionFactsContext, renderSpanRunSnapshot, renderTraceQuestionInstructions, renderTraceQuestionPrompt, renderTraceQuestionsReport, renderValidation, resolveAdapter, resolveOtlpInputFiles, resolveRepoAttrs, resolveRunContextDir, resolveRunWatchTarget, resolveSessionRepoAttrs, runCommand, runExternalAnalyzers, runPipelines, runTotals, runTraceImprovement, runTraceInvestigation, runTraceQuestions, runTraceStoreInvestigation, sandboxReplayBackend, saveReport, saveState, scanSessions, selectAdapters, serializeInspectionReport, serializePolicyEvidence, serializeSessionIndex, serializeSpans, serializeTraceStreamEvent, sessionFactsContext, sessionHash, sessionIdFromAttributes, sessionIntegrityAttributes, sessionTextSignatures, shellCommands, skippedAnalyses, span, spanRunTotals, stampEnvironmentAttrs, stampRepoAttrs, stampSessionIdentity, stampSessionIntegrity, stampSpanWorkdirRepoAttrs, streamSessions, summarizeOtlpExecution, summarizeSpanExecution, summarizeSpanStructure, takeJsonl, textIsSynthetic, toOpenInferenceSpan, toRuntimeStore, toTraceSpanEvents, tokens, totalAgenticFailureMessage, totalFindingRejections, traceAgenticKinds, traceCitationsInText, traceStreamEventsFromSpans, unavailableCapabilities, uploadKey, usd, userPromptSpan, validateOtlpSpans, validationExitCode, verdictExitCode, verifyFindingsInSandbox, verifySafe, verifySessionBundle, watchRunTarget, watchSessions, withSessionFactsContext, wrap, writeHodoscopeInput, writeInspectionReportFile, writeOtlpFile, writePolicyEvidenceFile, writeSessionBundleManifest, writeSessionIndexFile, writeTraceEvidenceExportFile, writeTraceImprovementArtifacts, writeTraceQuestionsArtifacts, zaiChatCaller, zeroPricedCost };
|
package/dist/index.js
CHANGED
|
@@ -270,7 +270,7 @@ import {
|
|
|
270
270
|
writeTraceQuestionsArtifacts,
|
|
271
271
|
zaiChatCaller,
|
|
272
272
|
zeroPricedCost
|
|
273
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-YVCHWHCA.js";
|
|
274
274
|
|
|
275
275
|
// src/collect.ts
|
|
276
276
|
async function collectSessions(opts = {}) {
|
|
@@ -301,6 +301,112 @@ import {
|
|
|
301
301
|
redactText,
|
|
302
302
|
shareAllowed
|
|
303
303
|
} from "@tangle-network/agent-eval/traces";
|
|
304
|
+
|
|
305
|
+
// src/retained-session.ts
|
|
306
|
+
import { createHash } from "crypto";
|
|
307
|
+
import { mkdir, mkdtemp, rm, writeFile } from "fs/promises";
|
|
308
|
+
import { tmpdir } from "os";
|
|
309
|
+
import { dirname, isAbsolute, join, relative, resolve } from "path";
|
|
310
|
+
var RETAINED_SESSION_READER_VERSION = "1";
|
|
311
|
+
async function parseRetainedSession(input) {
|
|
312
|
+
input.signal?.throwIfAborted();
|
|
313
|
+
const unselectedFiles = [];
|
|
314
|
+
const unavailable = (reason) => ({
|
|
315
|
+
status: "unavailable",
|
|
316
|
+
reason,
|
|
317
|
+
sessionId: input.nativeSessionId,
|
|
318
|
+
sourceFiles: [],
|
|
319
|
+
duplicateFiles: [],
|
|
320
|
+
unselectedFiles,
|
|
321
|
+
spans: []
|
|
322
|
+
});
|
|
323
|
+
if (!input.nativeSessionId) return unavailable("Capture has no recorded native session identity.");
|
|
324
|
+
const adapter = resolveAdapter(input.harness);
|
|
325
|
+
if (!adapter) return unavailable(`No native trace adapter for ${input.harness}.`);
|
|
326
|
+
if (input.files.length > 1024) return unavailable("Retained capture exceeds 1024 text files.");
|
|
327
|
+
let totalBytes = 0;
|
|
328
|
+
for (const file of input.files) {
|
|
329
|
+
const bytes = Buffer.byteLength(file.content);
|
|
330
|
+
totalBytes += bytes;
|
|
331
|
+
if (bytes > 16 * 1024 ** 2 || totalBytes > 64 * 1024 ** 2) {
|
|
332
|
+
return unavailable("Retained capture exceeds the 16 MiB per-file or 64 MiB total text limit.");
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const root = await mkdtemp(join(tmpdir(), "traces-retained-"));
|
|
336
|
+
try {
|
|
337
|
+
const files = /* @__PURE__ */ new Map();
|
|
338
|
+
for (const file of input.files) {
|
|
339
|
+
input.signal?.throwIfAborted();
|
|
340
|
+
const path = resolve(root, file.path);
|
|
341
|
+
const rel = relative(root, path);
|
|
342
|
+
if (!file.path || isAbsolute(file.path) || file.path.includes("\\") || file.path.includes("\0") || rel === "" || rel === ".." || rel.startsWith("../") || files.has(path)) {
|
|
343
|
+
throw new Error("Retained source paths must be unique relative files inside the capture.");
|
|
344
|
+
}
|
|
345
|
+
files.set(path, file);
|
|
346
|
+
}
|
|
347
|
+
for (const [path, file] of files) {
|
|
348
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
349
|
+
await writeFile(path, file.content, { mode: 384, flag: "wx" });
|
|
350
|
+
}
|
|
351
|
+
const selected = [];
|
|
352
|
+
for (const [path, file] of files) {
|
|
353
|
+
input.signal?.throwIfAborted();
|
|
354
|
+
const fallback = `unattributed:${root}:${file.path}`;
|
|
355
|
+
const ref = { harness: adapter.harness, sessionId: fallback, path, cwd: null, mtimeMs: 0 };
|
|
356
|
+
try {
|
|
357
|
+
const sources = adapter.sourcePaths ? await adapter.sourcePaths(ref, { signal: input.signal }) : [path];
|
|
358
|
+
if (sources.some((source) => !files.has(resolve(source)))) {
|
|
359
|
+
throw new Error("Parser requires files outside the supplied retained capture.");
|
|
360
|
+
}
|
|
361
|
+
const spans = validateOtlpSpans(await adapter.parse(ref, {
|
|
362
|
+
corruptionMode: "recover",
|
|
363
|
+
taskScope: "all",
|
|
364
|
+
captureSources: false,
|
|
365
|
+
signal: input.signal
|
|
366
|
+
}), `${adapter.harness} retained adapter output`);
|
|
367
|
+
const roots = spans.filter((span2) => span2.parent_span_id === null);
|
|
368
|
+
const identities = new Set(roots.map((span2) => sessionIdFromAttributes(span2.attributes)));
|
|
369
|
+
if (identities.size !== 1 || !identities.has(input.nativeSessionId)) {
|
|
370
|
+
unselectedFiles.push({ path: file.path, reason: "No unambiguous matching native identity in parser output." });
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
stampSessionIntegrity(ref, spans);
|
|
374
|
+
stampSessionIdentity(spans, input.nativeSessionId);
|
|
375
|
+
for (const span2 of spans) {
|
|
376
|
+
for (const [key, value] of Object.entries(span2.attributes)) {
|
|
377
|
+
if (typeof value === "string" && value.includes(root)) {
|
|
378
|
+
span2.attributes[key] = value.split(root + "/").join("retained://");
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
selected.push({ file, paths: sources, spans });
|
|
383
|
+
} catch (error) {
|
|
384
|
+
input.signal?.throwIfAborted();
|
|
385
|
+
unselectedFiles.push({ path: file.path, reason: `Native parser could not read this file (${error instanceof Error ? error.name : "Error"}).` });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (!selected.length) return unavailable("No retained parser entrypoint established the recorded native session identity.");
|
|
389
|
+
selected.sort((a, b) => b.file.content.length - a.file.content.length || a.file.path.localeCompare(b.file.path));
|
|
390
|
+
const chosen = selected[0];
|
|
391
|
+
if (selected.some((candidate) => !chosen.file.content.startsWith(candidate.file.content))) {
|
|
392
|
+
return unavailable("Retained files contain divergent histories for the same native session.");
|
|
393
|
+
}
|
|
394
|
+
return {
|
|
395
|
+
status: "selected",
|
|
396
|
+
reason: null,
|
|
397
|
+
sessionId: input.nativeSessionId,
|
|
398
|
+
sourceFiles: chosen.paths.map((path) => {
|
|
399
|
+
const file = files.get(resolve(path));
|
|
400
|
+
return { path: file.path, sha256: `sha256:${createHash("sha256").update(file.content).digest("hex")}` };
|
|
401
|
+
}).sort((a, b) => a.path.localeCompare(b.path)),
|
|
402
|
+
duplicateFiles: selected.slice(1).map((candidate) => candidate.file.path),
|
|
403
|
+
unselectedFiles,
|
|
404
|
+
spans: chosen.spans
|
|
405
|
+
};
|
|
406
|
+
} finally {
|
|
407
|
+
await rm(root, { recursive: true, force: true });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
304
410
|
export {
|
|
305
411
|
ACTOR_ATTR,
|
|
306
412
|
ATTR,
|
|
@@ -347,6 +453,7 @@ export {
|
|
|
347
453
|
QwenAdapter,
|
|
348
454
|
REACTIONS,
|
|
349
455
|
RESULT_FILE,
|
|
456
|
+
RETAINED_SESSION_READER_VERSION,
|
|
350
457
|
RULE,
|
|
351
458
|
SESSION_FACTS_MEASUREMENT_VERSION,
|
|
352
459
|
SESSION_FACTS_VERSION_SUFFIX,
|
|
@@ -469,6 +576,7 @@ export {
|
|
|
469
576
|
outboundHash,
|
|
470
577
|
parseIsoToEpochMs,
|
|
471
578
|
parseJsonAnswer,
|
|
579
|
+
parseRetainedSession,
|
|
472
580
|
parseSession,
|
|
473
581
|
parseSince,
|
|
474
582
|
planTraceAgenticRoute,
|
package/docs/trace-analysts.md
CHANGED
|
@@ -425,10 +425,10 @@ What real runs have shown (GLM-5.3 via a coding-plan endpoint, fork at the pinne
|
|
|
425
425
|
tokens); its first reply gets cut by the endpoint's output limit mid-JSON, and the
|
|
426
426
|
truncation-aware repair turn (re-emit at most 3 findings, terse strings) recovers it — ok:true,
|
|
427
427
|
findings grounded, exit 0.
|
|
428
|
-
- **File, ~794 spans / 2.1 MB artifact:**
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
428
|
+
- **File, ~794 spans / 2.1 MB artifact:** the reply channel alone never survived the endpoint's
|
|
429
|
+
output cap. The findings.json payload channel finishes it — the analyzer writes the result with
|
|
430
|
+
its tools before replying — measured live at **8 findings, 0 rejected, exit 0**, 53 model calls,
|
|
431
|
+
~3.1M input tokens of REPL inspection.
|
|
432
432
|
|
|
433
433
|
## Write one analyst
|
|
434
434
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/traces",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi,
|
|
3
|
+
"version": "0.19.0",
|
|
4
|
+
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, \u2026) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite \u2014 observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|