agent-inspect 6.31.28 → 6.31.30

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.
@@ -826,6 +826,96 @@ function zeroKinds() {
826
826
  };
827
827
  }
828
828
 
829
+ // packages/core/src/exporters/presentation-lifecycle.ts
830
+ function stepIdOf(event) {
831
+ const value = event.attributes?.stepId;
832
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
833
+ }
834
+ function lifecycleKey(event) {
835
+ if (event.kind === "RUN") return `run:${event.runId}`;
836
+ const stepId = stepIdOf(event);
837
+ if (stepId !== void 0) return `step:${stepId}`;
838
+ return `event:${event.eventId}`;
839
+ }
840
+ function isTerminal(status) {
841
+ return status === "ok" || status === "error";
842
+ }
843
+ function cloneNode(node) {
844
+ return {
845
+ event: {
846
+ ...node.event,
847
+ ...node.event.attributes !== void 0 ? { attributes: { ...node.event.attributes } } : {}
848
+ },
849
+ children: node.children.map(cloneNode),
850
+ depth: node.depth
851
+ };
852
+ }
853
+ function joinSiblingGroup(group) {
854
+ if (group.length <= 1) return group;
855
+ const terminals = group.filter((n) => isTerminal(n.event.status));
856
+ const runnings = group.filter((n) => n.event.status === "running");
857
+ const terminalStatuses = new Set(terminals.map((n) => n.event.status));
858
+ if (terminalStatuses.size > 1) {
859
+ return group;
860
+ }
861
+ if (terminals.length >= 1) {
862
+ const terminal = terminals[terminals.length - 1];
863
+ const start = runnings[0];
864
+ const childMap = /* @__PURE__ */ new Map();
865
+ for (const n of group) {
866
+ for (const child of n.children) {
867
+ childMap.set(child.event.eventId, child);
868
+ }
869
+ }
870
+ return [
871
+ {
872
+ event: {
873
+ ...terminal.event,
874
+ name: start?.event.name ?? terminal.event.name,
875
+ kind: start?.event.kind ?? terminal.event.kind,
876
+ ...start?.event.timestamp !== void 0 && terminal.event.durationMs === void 0 ? {} : {}
877
+ },
878
+ children: presentSiblingNodes([...childMap.values()]),
879
+ depth: terminal.depth
880
+ }
881
+ ];
882
+ }
883
+ return group;
884
+ }
885
+ function presentSiblingNodes(nodes) {
886
+ const prepared = nodes.map((n) => ({
887
+ ...cloneNode(n),
888
+ children: presentSiblingNodes(n.children)
889
+ }));
890
+ const order = [];
891
+ const groups = /* @__PURE__ */ new Map();
892
+ for (const node of prepared) {
893
+ const key = lifecycleKey(node.event);
894
+ if (!groups.has(key)) {
895
+ groups.set(key, []);
896
+ order.push(key);
897
+ }
898
+ groups.get(key).push(node);
899
+ }
900
+ const out = [];
901
+ for (const key of order) {
902
+ out.push(...joinSiblingGroup(groups.get(key)));
903
+ }
904
+ return out;
905
+ }
906
+ function presentLifecycleJoinedTree(tree) {
907
+ return {
908
+ ...tree,
909
+ children: presentSiblingNodes(tree.children),
910
+ metadata: {
911
+ ...tree.metadata,
912
+ confidenceBreakdown: { ...tree.metadata.confidenceBreakdown },
913
+ kinds: { ...tree.metadata.kinds },
914
+ ...tree.metadata.relationshipSummary !== void 0 ? { relationshipSummary: { ...tree.metadata.relationshipSummary } } : {}
915
+ }
916
+ };
917
+ }
918
+
829
919
  // packages/core/src/exporters/html-exporter.ts
830
920
  function renderTreeHtml(nodes, ulClass = "tree") {
831
921
  if (nodes.length === 0) return "";
@@ -853,32 +943,33 @@ function exportHtml(tree, options) {
853
943
  const includeErrors = options?.includeErrors ?? true;
854
944
  const maxLen = options?.maxAttributeLength ?? 500;
855
945
  const redacted = options?.redacted ?? true;
856
- const titleName = escapeHtml(tree.name ?? tree.runId);
946
+ const view = presentLifecycleJoinedTree(tree);
947
+ const titleName = escapeHtml(view.name ?? view.runId);
857
948
  const summaryRows = [];
858
949
  summaryRows.push(
859
- `<tr><th scope="row">runId</th><td><code>${escapeHtml(tree.runId)}</code></td></tr>`
950
+ `<tr><th scope="row">runId</th><td><code>${escapeHtml(view.runId)}</code></td></tr>`
860
951
  );
861
- if (tree.name !== void 0) {
862
- summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(tree.name)}</td></tr>`);
952
+ if (view.name !== void 0) {
953
+ summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(view.name)}</td></tr>`);
863
954
  }
864
955
  summaryRows.push(
865
- `<tr><th scope="row">status</th><td>${escapeHtml(String(tree.status ?? "unknown"))}</td></tr>`
956
+ `<tr><th scope="row">status</th><td>${escapeHtml(String(view.status ?? "unknown"))}</td></tr>`
866
957
  );
867
958
  summaryRows.push(
868
- `<tr><th scope="row">durationMs</th><td>${tree.durationMs !== void 0 ? escapeHtml(String(tree.durationMs)) : "\u2014"}</td></tr>`
959
+ `<tr><th scope="row">durationMs</th><td>${view.durationMs !== void 0 ? escapeHtml(String(view.durationMs)) : "\u2014"}</td></tr>`
869
960
  );
870
961
  summaryRows.push(
871
- `<tr><th scope="row">startedAt</th><td>${tree.startedAt !== void 0 ? escapeHtml(String(tree.startedAt)) : "\u2014"}</td></tr>`
962
+ `<tr><th scope="row">startedAt</th><td>${view.startedAt !== void 0 ? escapeHtml(String(view.startedAt)) : "\u2014"}</td></tr>`
872
963
  );
873
964
  summaryRows.push(
874
- `<tr><th scope="row">endedAt</th><td>${tree.endedAt !== void 0 ? escapeHtml(String(tree.endedAt)) : "\u2014"}</td></tr>`
965
+ `<tr><th scope="row">endedAt</th><td>${view.endedAt !== void 0 ? escapeHtml(String(view.endedAt)) : "\u2014"}</td></tr>`
875
966
  );
876
967
  summaryRows.push(
877
- `<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(tree.metadata.totalEvents))}</td></tr>`
968
+ `<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(view.metadata.totalEvents))}</td></tr>`
878
969
  );
879
970
  let confidenceHtml = "";
880
971
  if (includeMetadata) {
881
- const cb = tree.metadata.confidenceBreakdown;
972
+ const cb = view.metadata.confidenceBreakdown;
882
973
  confidenceHtml += "<h3>Confidence breakdown</h3><table><thead><tr><th>bucket</th><th>count</th></tr></thead><tbody>";
883
974
  for (const k of Object.keys(cb).sort()) {
884
975
  const key = k;
@@ -886,14 +977,14 @@ function exportHtml(tree, options) {
886
977
  }
887
978
  confidenceHtml += "</tbody></table>";
888
979
  confidenceHtml += "<h3>Kind breakdown</h3><table><thead><tr><th>kind</th><th>count</th></tr></thead><tbody>";
889
- for (const k of Object.keys(tree.metadata.kinds).sort()) {
980
+ for (const k of Object.keys(view.metadata.kinds).sort()) {
890
981
  const key = k;
891
- const c = tree.metadata.kinds[key];
982
+ const c = view.metadata.kinds[key];
892
983
  if (c > 0) confidenceHtml += `<tr><td>${escapeHtml(key)}</td><td>${c}</td></tr>`;
893
984
  }
894
985
  confidenceHtml += "</tbody></table>";
895
986
  }
896
- const flat = flattenTree(tree);
987
+ const flat = flattenTree(view);
897
988
  const errors = flat.filter((n) => n.event.status === "error");
898
989
  let errorsHtml = "";
899
990
  if (includeErrors && errors.length > 0) {
@@ -948,7 +1039,7 @@ footer{margin-top:2rem;font-size:0.85rem;color:#555}
948
1039
  <header><h1>AgentInspect Run: ${titleName}</h1></header>
949
1040
  <p class="note">Generated locally by AgentInspect.</p>
950
1041
  ${includeMetadata ? `<section class="summary"><h2>Summary</h2><table>${summaryRows.join("")}</table>${confidenceHtml}</section>` : ""}
951
- <section class="tree"><h2>Execution tree</h2>${tree.children.length > 0 ? renderTreeHtml(tree.children) : "<p>No steps recorded.</p>"}</section>
1042
+ <section class="tree"><h2>Execution tree</h2>${view.children.length > 0 ? renderTreeHtml(view.children) : "<p>No steps recorded.</p>"}</section>
952
1043
  ${errorsHtml}
953
1044
  ${attrsHtml}
954
1045
  <footer>Generated locally by AgentInspect. Review for sensitive data before sharing.</footer>
@@ -989,7 +1080,8 @@ function exportMarkdown(tree, options) {
989
1080
  const includeErrors = options?.includeErrors ?? true;
990
1081
  const maxLen = options?.maxAttributeLength ?? 500;
991
1082
  const redacted = options?.redacted ?? true;
992
- const titleName = tree.name ?? tree.runId;
1083
+ const view = presentLifecycleJoinedTree(tree);
1084
+ const titleName = view.name ?? view.runId;
993
1085
  const lines = [];
994
1086
  lines.push(`# AgentInspect Run: ${escapeMarkdown(titleName)}`);
995
1087
  lines.push("");
@@ -998,28 +1090,28 @@ function exportMarkdown(tree, options) {
998
1090
  if (includeMetadata) {
999
1091
  lines.push("## Summary");
1000
1092
  lines.push("");
1001
- lines.push(`- **runId**: ${escapeMarkdown(tree.runId)}`);
1002
- if (tree.name !== void 0) lines.push(`- **name**: ${escapeMarkdown(tree.name)}`);
1003
- lines.push(`- **status**: ${escapeMarkdown(String(tree.status ?? "unknown"))}`);
1093
+ lines.push(`- **runId**: ${escapeMarkdown(view.runId)}`);
1094
+ if (view.name !== void 0) lines.push(`- **name**: ${escapeMarkdown(view.name)}`);
1095
+ lines.push(`- **status**: ${escapeMarkdown(String(view.status ?? "unknown"))}`);
1004
1096
  lines.push(
1005
- `- **durationMs**: ${tree.durationMs !== void 0 ? escapeMarkdown(String(tree.durationMs)) : "-"}`
1097
+ `- **durationMs**: ${view.durationMs !== void 0 ? escapeMarkdown(String(view.durationMs)) : "-"}`
1006
1098
  );
1007
1099
  lines.push(
1008
- `- **startedAt**: ${tree.startedAt !== void 0 ? escapeMarkdown(String(tree.startedAt)) : "-"}`
1100
+ `- **startedAt**: ${view.startedAt !== void 0 ? escapeMarkdown(String(view.startedAt)) : "-"}`
1009
1101
  );
1010
1102
  lines.push(
1011
- `- **endedAt**: ${tree.endedAt !== void 0 ? escapeMarkdown(String(tree.endedAt)) : "-"}`
1103
+ `- **endedAt**: ${view.endedAt !== void 0 ? escapeMarkdown(String(view.endedAt)) : "-"}`
1012
1104
  );
1013
- lines.push(`- **totalEvents**: ${tree.metadata.totalEvents}`);
1105
+ lines.push(`- **totalEvents**: ${view.metadata.totalEvents}`);
1014
1106
  lines.push("");
1015
1107
  lines.push("### Confidence breakdown");
1016
1108
  lines.push("");
1017
1109
  lines.push("| bucket | count |");
1018
1110
  lines.push("| --- | --- |");
1019
- for (const k of Object.keys(tree.metadata.confidenceBreakdown).sort()) {
1111
+ for (const k of Object.keys(view.metadata.confidenceBreakdown).sort()) {
1020
1112
  const key = k;
1021
1113
  lines.push(
1022
- `| ${escapeMarkdown(key)} | ${tree.metadata.confidenceBreakdown[key]} |`
1114
+ `| ${escapeMarkdown(key)} | ${view.metadata.confidenceBreakdown[key]} |`
1023
1115
  );
1024
1116
  }
1025
1117
  lines.push("");
@@ -1027,9 +1119,9 @@ function exportMarkdown(tree, options) {
1027
1119
  lines.push("");
1028
1120
  lines.push("| kind | count |");
1029
1121
  lines.push("| --- | --- |");
1030
- for (const k of Object.keys(tree.metadata.kinds).sort()) {
1122
+ for (const k of Object.keys(view.metadata.kinds).sort()) {
1031
1123
  const key = k;
1032
- const c = tree.metadata.kinds[key];
1124
+ const c = view.metadata.kinds[key];
1033
1125
  if (c > 0) lines.push(`| ${escapeMarkdown(key)} | ${c} |`);
1034
1126
  }
1035
1127
  lines.push("");
@@ -1038,11 +1130,11 @@ function exportMarkdown(tree, options) {
1038
1130
  lines.push("");
1039
1131
  lines.push("```text");
1040
1132
  lines.push(
1041
- tree.children.length > 0 ? renderTreeAscii(tree.children) : "(no steps)"
1133
+ view.children.length > 0 ? renderTreeAscii(view.children) : "(no steps)"
1042
1134
  );
1043
1135
  lines.push("```");
1044
1136
  lines.push("");
1045
- const flat = flattenTree(tree);
1137
+ const flat = flattenTree(view);
1046
1138
  const errors = flat.filter((n) => n.event.status === "error");
1047
1139
  if (includeErrors && errors.length > 0) {
1048
1140
  lines.push("## Errors");