agent-inspect 1.8.0 → 1.9.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/CHANGELOG.md +8 -0
- package/README.md +137 -18
- package/docs/ADAPTERS.md +41 -6
- package/docs/API.md +98 -12
- package/docs/CLI.md +35 -1
- package/docs/GETTING-STARTED.md +71 -16
- package/docs/LOG-TO-TREE-QUICKSTART.md +1 -2
- package/docs/MIGRATION.md +67 -0
- package/package.json +2 -2
- package/packages/cli/dist/index.cjs +338 -48
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +338 -48
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/core/dist/index.cjs +146 -0
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.d.cts +39 -2
- package/packages/core/dist/index.d.ts +39 -2
- package/packages/core/dist/index.mjs +148 -1
- package/packages/core/dist/index.mjs.map +1 -1
|
@@ -4613,6 +4613,151 @@ ${attrsSection}
|
|
|
4613
4613
|
};
|
|
4614
4614
|
}
|
|
4615
4615
|
|
|
4616
|
+
// packages/core/src/explain.ts
|
|
4617
|
+
function flatten(nodes, out = []) {
|
|
4618
|
+
for (const node of nodes) {
|
|
4619
|
+
out.push({ node, index: out.length + 1 });
|
|
4620
|
+
flatten(node.children, out);
|
|
4621
|
+
}
|
|
4622
|
+
return out;
|
|
4623
|
+
}
|
|
4624
|
+
function redactValue(redactor, key, value) {
|
|
4625
|
+
return redactor.redactValue(key, value);
|
|
4626
|
+
}
|
|
4627
|
+
function fact(id, label, value, redactor) {
|
|
4628
|
+
return {
|
|
4629
|
+
id,
|
|
4630
|
+
label,
|
|
4631
|
+
value: redactValue(redactor, id.split(".").at(-1) ?? id, value),
|
|
4632
|
+
source: "trace",
|
|
4633
|
+
confidence: "observed"
|
|
4634
|
+
};
|
|
4635
|
+
}
|
|
4636
|
+
function topKinds(run) {
|
|
4637
|
+
return Object.entries(run.metadata.kinds).filter(([, count]) => count > 0).sort((a, b) => {
|
|
4638
|
+
if (b[1] !== a[1]) return b[1] - a[1];
|
|
4639
|
+
return a[0].localeCompare(b[0]);
|
|
4640
|
+
}).slice(0, 5).map(([kind, count]) => `${kind}:${count}`);
|
|
4641
|
+
}
|
|
4642
|
+
function countErrorNodes(nodes) {
|
|
4643
|
+
return nodes.filter((entry) => entry.node.event.status === "error").length;
|
|
4644
|
+
}
|
|
4645
|
+
function slowestNode(nodes) {
|
|
4646
|
+
return nodes.filter((entry) => entry.node.event.durationMs !== void 0).sort((a, b) => {
|
|
4647
|
+
const delta = (b.node.event.durationMs ?? 0) - (a.node.event.durationMs ?? 0);
|
|
4648
|
+
return delta !== 0 ? delta : a.index - b.index;
|
|
4649
|
+
})[0];
|
|
4650
|
+
}
|
|
4651
|
+
function attributeFacts(nodes, redactor) {
|
|
4652
|
+
const facts = [];
|
|
4653
|
+
for (const entry of nodes) {
|
|
4654
|
+
const attrs = entry.node.event.attributes;
|
|
4655
|
+
if (attrs === void 0) continue;
|
|
4656
|
+
for (const key of Object.keys(attrs).sort()) {
|
|
4657
|
+
facts.push({
|
|
4658
|
+
id: `node.${entry.index}.attributes.${key}`,
|
|
4659
|
+
label: `${entry.node.event.name} attribute ${key}`,
|
|
4660
|
+
value: redactValue(redactor, key, attrs[key]),
|
|
4661
|
+
source: "trace",
|
|
4662
|
+
confidence: "observed"
|
|
4663
|
+
});
|
|
4664
|
+
if (facts.length >= 8) return facts;
|
|
4665
|
+
}
|
|
4666
|
+
}
|
|
4667
|
+
return facts;
|
|
4668
|
+
}
|
|
4669
|
+
function buildFacts(run, redactor) {
|
|
4670
|
+
const nodes = flatten(run.children);
|
|
4671
|
+
const facts = [
|
|
4672
|
+
fact("run.id", "Run id", run.runId, redactor),
|
|
4673
|
+
fact("run.name", "Run name", run.name ?? run.runId, redactor),
|
|
4674
|
+
fact("run.status", "Run status", run.status ?? "unknown", redactor),
|
|
4675
|
+
fact("run.totalEvents", "Total events", run.metadata.totalEvents, redactor),
|
|
4676
|
+
fact("run.stepCount", "Top-level step count", run.children.length, redactor),
|
|
4677
|
+
fact("run.nodeCount", "Total node count", nodes.length, redactor),
|
|
4678
|
+
fact("run.errorNodeCount", "Error node count", countErrorNodes(nodes), redactor),
|
|
4679
|
+
fact("run.kinds", "Observed kind mix", topKinds(run), redactor)
|
|
4680
|
+
];
|
|
4681
|
+
if (run.durationMs !== void 0) {
|
|
4682
|
+
facts.push(fact("run.durationMs", "Run duration milliseconds", run.durationMs, redactor));
|
|
4683
|
+
}
|
|
4684
|
+
const slowest = slowestNode(nodes);
|
|
4685
|
+
if (slowest !== void 0) {
|
|
4686
|
+
facts.push(
|
|
4687
|
+
fact("run.slowestNode", "Slowest observed node", {
|
|
4688
|
+
name: slowest.node.event.name,
|
|
4689
|
+
kind: slowest.node.event.kind,
|
|
4690
|
+
durationMs: slowest.node.event.durationMs
|
|
4691
|
+
}, redactor)
|
|
4692
|
+
);
|
|
4693
|
+
}
|
|
4694
|
+
facts.push(...attributeFacts(nodes, redactor));
|
|
4695
|
+
return facts;
|
|
4696
|
+
}
|
|
4697
|
+
function buildInferences(run, facts) {
|
|
4698
|
+
const inferences = [];
|
|
4699
|
+
const errorFact = facts.find((item) => item.id === "run.errorNodeCount");
|
|
4700
|
+
const kindFact = facts.find((item) => item.id === "run.kinds");
|
|
4701
|
+
const durationFact = facts.find((item) => item.id === "run.durationMs");
|
|
4702
|
+
const errorNodeCount = typeof errorFact?.value === "number" ? errorFact.value : 0;
|
|
4703
|
+
if (run.status === "error" || errorNodeCount > 0) {
|
|
4704
|
+
inferences.push({
|
|
4705
|
+
id: "outcome.error",
|
|
4706
|
+
label: "Outcome",
|
|
4707
|
+
text: "The run recorded an error status or at least one error node.",
|
|
4708
|
+
evidence: ["run.status", "run.errorNodeCount"],
|
|
4709
|
+
confidence: "deterministic"
|
|
4710
|
+
});
|
|
4711
|
+
} else if (run.status === "ok") {
|
|
4712
|
+
inferences.push({
|
|
4713
|
+
id: "outcome.success",
|
|
4714
|
+
label: "Outcome",
|
|
4715
|
+
text: "The run completed without observed error nodes.",
|
|
4716
|
+
evidence: ["run.status", "run.errorNodeCount"],
|
|
4717
|
+
confidence: "deterministic"
|
|
4718
|
+
});
|
|
4719
|
+
}
|
|
4720
|
+
if (kindFact !== void 0) {
|
|
4721
|
+
inferences.push({
|
|
4722
|
+
id: "shape.kind-mix",
|
|
4723
|
+
label: "Trace shape",
|
|
4724
|
+
text: "The explanation is based on the observed event kind mix, not generated content.",
|
|
4725
|
+
evidence: [kindFact.id],
|
|
4726
|
+
confidence: "deterministic"
|
|
4727
|
+
});
|
|
4728
|
+
}
|
|
4729
|
+
if (durationFact !== void 0) {
|
|
4730
|
+
inferences.push({
|
|
4731
|
+
id: "timing.duration",
|
|
4732
|
+
label: "Timing",
|
|
4733
|
+
text: "Timing claims are limited to persisted duration fields in the trace.",
|
|
4734
|
+
evidence: [durationFact.id],
|
|
4735
|
+
confidence: "deterministic"
|
|
4736
|
+
});
|
|
4737
|
+
}
|
|
4738
|
+
return inferences;
|
|
4739
|
+
}
|
|
4740
|
+
function buildLocalExplanation(run, options = {}) {
|
|
4741
|
+
const redactionProfile = options.redactionProfile ?? "local";
|
|
4742
|
+
const resolved = resolveRedactionProfile(redactionProfile);
|
|
4743
|
+
const redactor = new Redactor({ extraKeys: resolved.extraKeys });
|
|
4744
|
+
const mode = options.mode ?? "local";
|
|
4745
|
+
const facts = buildFacts(run, redactor);
|
|
4746
|
+
return {
|
|
4747
|
+
mode,
|
|
4748
|
+
runId: String(redactValue(redactor, "runId", run.runId)),
|
|
4749
|
+
...run.name !== void 0 ? { name: String(redactValue(redactor, "name", run.name)) } : {},
|
|
4750
|
+
...run.status !== void 0 ? { status: run.status } : {},
|
|
4751
|
+
redactionProfile,
|
|
4752
|
+
facts,
|
|
4753
|
+
inferences: mode === "dry-run" ? [] : buildInferences(run, facts),
|
|
4754
|
+
notes: [
|
|
4755
|
+
"Generated locally without provider or network calls.",
|
|
4756
|
+
"Facts are observed from normalized trace data; inferences are deterministic labels."
|
|
4757
|
+
]
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
|
|
4616
4761
|
// packages/core/src/stats.ts
|
|
4617
4762
|
function percentile(sorted, p) {
|
|
4618
4763
|
if (sorted.length === 0) return void 0;
|
|
@@ -9214,6 +9359,7 @@ exports.TraceReadError = TraceReadError;
|
|
|
9214
9359
|
exports.TreeBuilder = TreeBuilder;
|
|
9215
9360
|
exports.agentInspectJsonlReader = agentInspectJsonlReader;
|
|
9216
9361
|
exports.bufferedFileWriter = bufferedFileWriter;
|
|
9362
|
+
exports.buildLocalExplanation = buildLocalExplanation;
|
|
9217
9363
|
exports.buildRunReport = buildRunReport;
|
|
9218
9364
|
exports.buildRunSummary = buildRunSummary;
|
|
9219
9365
|
exports.buildRunTimeline = buildRunTimeline;
|