agent-inspect 6.31.29 → 6.31.31
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 +14 -0
- package/README.md +1 -1
- package/docs/CLI.md +26 -1
- package/package.json +2 -2
- package/packages/cli/dist/index.cjs +205 -36
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +204 -37
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/core/dist/exporters.cjs +183 -28
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +183 -28
- package/packages/core/dist/exporters.mjs.map +1 -1
|
@@ -418,6 +418,159 @@ function redactRunTreeForExport(tree, options) {
|
|
|
418
418
|
return clone;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
+
// packages/core/src/exporters/presentation-lifecycle.ts
|
|
422
|
+
function stepIdOf(event) {
|
|
423
|
+
const value = event.attributes?.stepId;
|
|
424
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
425
|
+
}
|
|
426
|
+
function attemptIdOf(event) {
|
|
427
|
+
const direct = event.attributes?.attemptId;
|
|
428
|
+
if (typeof direct === "string" && direct.trim() !== "") return direct;
|
|
429
|
+
const meta = event.attributes?.metadata;
|
|
430
|
+
if (meta && typeof meta === "object" && !Array.isArray(meta)) {
|
|
431
|
+
const nested = meta.attemptId;
|
|
432
|
+
if (typeof nested === "string" && nested.trim() !== "") return nested;
|
|
433
|
+
}
|
|
434
|
+
return void 0;
|
|
435
|
+
}
|
|
436
|
+
function lifecycleKey(event) {
|
|
437
|
+
if (event.kind === "RUN") return `run:${event.runId}`;
|
|
438
|
+
const stepId = stepIdOf(event);
|
|
439
|
+
if (stepId !== void 0) return `step:${stepId}`;
|
|
440
|
+
return `event:${event.eventId}`;
|
|
441
|
+
}
|
|
442
|
+
function isTerminal(status) {
|
|
443
|
+
return status === "ok" || status === "error";
|
|
444
|
+
}
|
|
445
|
+
function eventTime(event) {
|
|
446
|
+
return typeof event.timestamp === "number" ? event.timestamp : 0;
|
|
447
|
+
}
|
|
448
|
+
function cloneNode(node) {
|
|
449
|
+
return {
|
|
450
|
+
event: {
|
|
451
|
+
...node.event,
|
|
452
|
+
...node.event.attributes !== void 0 ? { attributes: { ...node.event.attributes } } : {}
|
|
453
|
+
},
|
|
454
|
+
children: node.children.map(cloneNode),
|
|
455
|
+
depth: node.depth
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function joinOnePair(start, terminal) {
|
|
459
|
+
const childMap = /* @__PURE__ */ new Map();
|
|
460
|
+
if (start) {
|
|
461
|
+
for (const child of start.children) {
|
|
462
|
+
childMap.set(child.event.eventId, child);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
for (const child of terminal.children) {
|
|
466
|
+
childMap.set(child.event.eventId, child);
|
|
467
|
+
}
|
|
468
|
+
return {
|
|
469
|
+
event: {
|
|
470
|
+
...terminal.event,
|
|
471
|
+
name: start?.event.name ?? terminal.event.name,
|
|
472
|
+
kind: start?.event.kind ?? terminal.event.kind,
|
|
473
|
+
...start && attemptIdOf(terminal.event) === void 0 && attemptIdOf(start.event) ? {
|
|
474
|
+
attributes: {
|
|
475
|
+
...terminal.event.attributes,
|
|
476
|
+
attemptId: attemptIdOf(start.event)
|
|
477
|
+
}
|
|
478
|
+
} : {}
|
|
479
|
+
},
|
|
480
|
+
children: presentSiblingNodes([...childMap.values()]),
|
|
481
|
+
depth: terminal.depth
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function joinSiblingGroup(group) {
|
|
485
|
+
if (group.length <= 1) return group;
|
|
486
|
+
const terminals = group.filter((n) => isTerminal(n.event.status)).sort((a, b) => eventTime(a.event) - eventTime(b.event));
|
|
487
|
+
const runnings = group.filter((n) => n.event.status === "running").sort((a, b) => eventTime(a.event) - eventTime(b.event));
|
|
488
|
+
const others = group.filter(
|
|
489
|
+
(n) => !isTerminal(n.event.status) && n.event.status !== "running"
|
|
490
|
+
);
|
|
491
|
+
const terminalStatuses = new Set(terminals.map((n) => n.event.status));
|
|
492
|
+
if (terminalStatuses.size > 1) {
|
|
493
|
+
return group;
|
|
494
|
+
}
|
|
495
|
+
if (terminals.length > 1 && terminals.every((t) => attemptIdOf(t.event) === void 0) && runnings.every((r) => attemptIdOf(r.event) === void 0)) {
|
|
496
|
+
return group;
|
|
497
|
+
}
|
|
498
|
+
const usedRunning = /* @__PURE__ */ new Set();
|
|
499
|
+
const out = [];
|
|
500
|
+
for (const terminal of terminals) {
|
|
501
|
+
const terminalAttempt = attemptIdOf(terminal.event);
|
|
502
|
+
const terminalTs = eventTime(terminal.event);
|
|
503
|
+
const candidate = runnings.find((r) => {
|
|
504
|
+
if (usedRunning.has(r.event.eventId)) return false;
|
|
505
|
+
if (eventTime(r.event) > terminalTs) return false;
|
|
506
|
+
const runningAttempt = attemptIdOf(r.event);
|
|
507
|
+
if (terminalAttempt !== void 0) {
|
|
508
|
+
return runningAttempt === terminalAttempt;
|
|
509
|
+
}
|
|
510
|
+
if (runningAttempt !== void 0) {
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
return true;
|
|
514
|
+
});
|
|
515
|
+
if (candidate) {
|
|
516
|
+
usedRunning.add(candidate.event.eventId);
|
|
517
|
+
out.push(joinOnePair(candidate, terminal));
|
|
518
|
+
} else {
|
|
519
|
+
out.push({
|
|
520
|
+
...terminal,
|
|
521
|
+
children: presentSiblingNodes(terminal.children)
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
for (const running of runnings) {
|
|
526
|
+
if (usedRunning.has(running.event.eventId)) continue;
|
|
527
|
+
out.push({
|
|
528
|
+
...running,
|
|
529
|
+
children: presentSiblingNodes(running.children)
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
for (const other of others) {
|
|
533
|
+
out.push({
|
|
534
|
+
...other,
|
|
535
|
+
children: presentSiblingNodes(other.children)
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
return out;
|
|
539
|
+
}
|
|
540
|
+
function presentSiblingNodes(nodes) {
|
|
541
|
+
const prepared = nodes.map((n) => ({
|
|
542
|
+
...cloneNode(n),
|
|
543
|
+
children: presentSiblingNodes(n.children)
|
|
544
|
+
}));
|
|
545
|
+
const order = [];
|
|
546
|
+
const groups = /* @__PURE__ */ new Map();
|
|
547
|
+
for (const node of prepared) {
|
|
548
|
+
const key = lifecycleKey(node.event);
|
|
549
|
+
if (!groups.has(key)) {
|
|
550
|
+
groups.set(key, []);
|
|
551
|
+
order.push(key);
|
|
552
|
+
}
|
|
553
|
+
groups.get(key).push(node);
|
|
554
|
+
}
|
|
555
|
+
const out = [];
|
|
556
|
+
for (const key of order) {
|
|
557
|
+
out.push(...joinSiblingGroup(groups.get(key)));
|
|
558
|
+
}
|
|
559
|
+
return out;
|
|
560
|
+
}
|
|
561
|
+
function presentLifecycleJoinedTree(tree) {
|
|
562
|
+
return {
|
|
563
|
+
...tree,
|
|
564
|
+
children: presentSiblingNodes(tree.children),
|
|
565
|
+
metadata: {
|
|
566
|
+
...tree.metadata,
|
|
567
|
+
confidenceBreakdown: { ...tree.metadata.confidenceBreakdown },
|
|
568
|
+
kinds: { ...tree.metadata.kinds },
|
|
569
|
+
...tree.metadata.relationshipSummary !== void 0 ? { relationshipSummary: { ...tree.metadata.relationshipSummary } } : {}
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
421
574
|
// packages/core/src/exporters/html-exporter.ts
|
|
422
575
|
function renderTreeHtml(nodes, ulClass = "tree") {
|
|
423
576
|
if (nodes.length === 0) return "";
|
|
@@ -445,32 +598,33 @@ function exportHtml(tree, options) {
|
|
|
445
598
|
const includeErrors = options?.includeErrors ?? true;
|
|
446
599
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
447
600
|
const redacted = options?.redacted ?? true;
|
|
448
|
-
const
|
|
601
|
+
const view = presentLifecycleJoinedTree(tree);
|
|
602
|
+
const titleName = escapeHtml(view.name ?? view.runId);
|
|
449
603
|
const summaryRows = [];
|
|
450
604
|
summaryRows.push(
|
|
451
|
-
`<tr><th scope="row">runId</th><td><code>${escapeHtml(
|
|
605
|
+
`<tr><th scope="row">runId</th><td><code>${escapeHtml(view.runId)}</code></td></tr>`
|
|
452
606
|
);
|
|
453
|
-
if (
|
|
454
|
-
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(
|
|
607
|
+
if (view.name !== void 0) {
|
|
608
|
+
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(view.name)}</td></tr>`);
|
|
455
609
|
}
|
|
456
610
|
summaryRows.push(
|
|
457
|
-
`<tr><th scope="row">status</th><td>${escapeHtml(String(
|
|
611
|
+
`<tr><th scope="row">status</th><td>${escapeHtml(String(view.status ?? "unknown"))}</td></tr>`
|
|
458
612
|
);
|
|
459
613
|
summaryRows.push(
|
|
460
|
-
`<tr><th scope="row">durationMs</th><td>${
|
|
614
|
+
`<tr><th scope="row">durationMs</th><td>${view.durationMs !== void 0 ? escapeHtml(String(view.durationMs)) : "\u2014"}</td></tr>`
|
|
461
615
|
);
|
|
462
616
|
summaryRows.push(
|
|
463
|
-
`<tr><th scope="row">startedAt</th><td>${
|
|
617
|
+
`<tr><th scope="row">startedAt</th><td>${view.startedAt !== void 0 ? escapeHtml(String(view.startedAt)) : "\u2014"}</td></tr>`
|
|
464
618
|
);
|
|
465
619
|
summaryRows.push(
|
|
466
|
-
`<tr><th scope="row">endedAt</th><td>${
|
|
620
|
+
`<tr><th scope="row">endedAt</th><td>${view.endedAt !== void 0 ? escapeHtml(String(view.endedAt)) : "\u2014"}</td></tr>`
|
|
467
621
|
);
|
|
468
622
|
summaryRows.push(
|
|
469
|
-
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(
|
|
623
|
+
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(view.metadata.totalEvents))}</td></tr>`
|
|
470
624
|
);
|
|
471
625
|
let confidenceHtml = "";
|
|
472
626
|
if (includeMetadata) {
|
|
473
|
-
const cb =
|
|
627
|
+
const cb = view.metadata.confidenceBreakdown;
|
|
474
628
|
confidenceHtml += "<h3>Confidence breakdown</h3><table><thead><tr><th>bucket</th><th>count</th></tr></thead><tbody>";
|
|
475
629
|
for (const k of Object.keys(cb).sort()) {
|
|
476
630
|
const key = k;
|
|
@@ -478,14 +632,14 @@ function exportHtml(tree, options) {
|
|
|
478
632
|
}
|
|
479
633
|
confidenceHtml += "</tbody></table>";
|
|
480
634
|
confidenceHtml += "<h3>Kind breakdown</h3><table><thead><tr><th>kind</th><th>count</th></tr></thead><tbody>";
|
|
481
|
-
for (const k of Object.keys(
|
|
635
|
+
for (const k of Object.keys(view.metadata.kinds).sort()) {
|
|
482
636
|
const key = k;
|
|
483
|
-
const c =
|
|
637
|
+
const c = view.metadata.kinds[key];
|
|
484
638
|
if (c > 0) confidenceHtml += `<tr><td>${escapeHtml(key)}</td><td>${c}</td></tr>`;
|
|
485
639
|
}
|
|
486
640
|
confidenceHtml += "</tbody></table>";
|
|
487
641
|
}
|
|
488
|
-
const flat = flattenTree(
|
|
642
|
+
const flat = flattenTree(view);
|
|
489
643
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
490
644
|
let errorsHtml = "";
|
|
491
645
|
if (includeErrors && errors.length > 0) {
|
|
@@ -540,7 +694,7 @@ footer{margin-top:2rem;font-size:0.85rem;color:#555}
|
|
|
540
694
|
<header><h1>AgentInspect Run: ${titleName}</h1></header>
|
|
541
695
|
<p class="note">Generated locally by AgentInspect.</p>
|
|
542
696
|
${includeMetadata ? `<section class="summary"><h2>Summary</h2><table>${summaryRows.join("")}</table>${confidenceHtml}</section>` : ""}
|
|
543
|
-
<section class="tree"><h2>Execution tree</h2>${
|
|
697
|
+
<section class="tree"><h2>Execution tree</h2>${view.children.length > 0 ? renderTreeHtml(view.children) : "<p>No steps recorded.</p>"}</section>
|
|
544
698
|
${errorsHtml}
|
|
545
699
|
${attrsHtml}
|
|
546
700
|
<footer>Generated locally by AgentInspect. Review for sensitive data before sharing.</footer>
|
|
@@ -581,7 +735,8 @@ function exportMarkdown(tree, options) {
|
|
|
581
735
|
const includeErrors = options?.includeErrors ?? true;
|
|
582
736
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
583
737
|
const redacted = options?.redacted ?? true;
|
|
584
|
-
const
|
|
738
|
+
const view = presentLifecycleJoinedTree(tree);
|
|
739
|
+
const titleName = view.name ?? view.runId;
|
|
585
740
|
const lines = [];
|
|
586
741
|
lines.push(`# AgentInspect Run: ${escapeMarkdown(titleName)}`);
|
|
587
742
|
lines.push("");
|
|
@@ -590,28 +745,28 @@ function exportMarkdown(tree, options) {
|
|
|
590
745
|
if (includeMetadata) {
|
|
591
746
|
lines.push("## Summary");
|
|
592
747
|
lines.push("");
|
|
593
|
-
lines.push(`- **runId**: ${escapeMarkdown(
|
|
594
|
-
if (
|
|
595
|
-
lines.push(`- **status**: ${escapeMarkdown(String(
|
|
748
|
+
lines.push(`- **runId**: ${escapeMarkdown(view.runId)}`);
|
|
749
|
+
if (view.name !== void 0) lines.push(`- **name**: ${escapeMarkdown(view.name)}`);
|
|
750
|
+
lines.push(`- **status**: ${escapeMarkdown(String(view.status ?? "unknown"))}`);
|
|
596
751
|
lines.push(
|
|
597
|
-
`- **durationMs**: ${
|
|
752
|
+
`- **durationMs**: ${view.durationMs !== void 0 ? escapeMarkdown(String(view.durationMs)) : "-"}`
|
|
598
753
|
);
|
|
599
754
|
lines.push(
|
|
600
|
-
`- **startedAt**: ${
|
|
755
|
+
`- **startedAt**: ${view.startedAt !== void 0 ? escapeMarkdown(String(view.startedAt)) : "-"}`
|
|
601
756
|
);
|
|
602
757
|
lines.push(
|
|
603
|
-
`- **endedAt**: ${
|
|
758
|
+
`- **endedAt**: ${view.endedAt !== void 0 ? escapeMarkdown(String(view.endedAt)) : "-"}`
|
|
604
759
|
);
|
|
605
|
-
lines.push(`- **totalEvents**: ${
|
|
760
|
+
lines.push(`- **totalEvents**: ${view.metadata.totalEvents}`);
|
|
606
761
|
lines.push("");
|
|
607
762
|
lines.push("### Confidence breakdown");
|
|
608
763
|
lines.push("");
|
|
609
764
|
lines.push("| bucket | count |");
|
|
610
765
|
lines.push("| --- | --- |");
|
|
611
|
-
for (const k of Object.keys(
|
|
766
|
+
for (const k of Object.keys(view.metadata.confidenceBreakdown).sort()) {
|
|
612
767
|
const key = k;
|
|
613
768
|
lines.push(
|
|
614
|
-
`| ${escapeMarkdown(key)} | ${
|
|
769
|
+
`| ${escapeMarkdown(key)} | ${view.metadata.confidenceBreakdown[key]} |`
|
|
615
770
|
);
|
|
616
771
|
}
|
|
617
772
|
lines.push("");
|
|
@@ -619,9 +774,9 @@ function exportMarkdown(tree, options) {
|
|
|
619
774
|
lines.push("");
|
|
620
775
|
lines.push("| kind | count |");
|
|
621
776
|
lines.push("| --- | --- |");
|
|
622
|
-
for (const k of Object.keys(
|
|
777
|
+
for (const k of Object.keys(view.metadata.kinds).sort()) {
|
|
623
778
|
const key = k;
|
|
624
|
-
const c =
|
|
779
|
+
const c = view.metadata.kinds[key];
|
|
625
780
|
if (c > 0) lines.push(`| ${escapeMarkdown(key)} | ${c} |`);
|
|
626
781
|
}
|
|
627
782
|
lines.push("");
|
|
@@ -630,11 +785,11 @@ function exportMarkdown(tree, options) {
|
|
|
630
785
|
lines.push("");
|
|
631
786
|
lines.push("```text");
|
|
632
787
|
lines.push(
|
|
633
|
-
|
|
788
|
+
view.children.length > 0 ? renderTreeAscii(view.children) : "(no steps)"
|
|
634
789
|
);
|
|
635
790
|
lines.push("```");
|
|
636
791
|
lines.push("");
|
|
637
|
-
const flat = flattenTree(
|
|
792
|
+
const flat = flattenTree(view);
|
|
638
793
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
639
794
|
if (includeErrors && errors.length > 0) {
|
|
640
795
|
lines.push("## Errors");
|