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
|
@@ -826,6 +826,159 @@ 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 attemptIdOf(event) {
|
|
835
|
+
const direct = event.attributes?.attemptId;
|
|
836
|
+
if (typeof direct === "string" && direct.trim() !== "") return direct;
|
|
837
|
+
const meta = event.attributes?.metadata;
|
|
838
|
+
if (meta && typeof meta === "object" && !Array.isArray(meta)) {
|
|
839
|
+
const nested = meta.attemptId;
|
|
840
|
+
if (typeof nested === "string" && nested.trim() !== "") return nested;
|
|
841
|
+
}
|
|
842
|
+
return void 0;
|
|
843
|
+
}
|
|
844
|
+
function lifecycleKey(event) {
|
|
845
|
+
if (event.kind === "RUN") return `run:${event.runId}`;
|
|
846
|
+
const stepId = stepIdOf(event);
|
|
847
|
+
if (stepId !== void 0) return `step:${stepId}`;
|
|
848
|
+
return `event:${event.eventId}`;
|
|
849
|
+
}
|
|
850
|
+
function isTerminal(status) {
|
|
851
|
+
return status === "ok" || status === "error";
|
|
852
|
+
}
|
|
853
|
+
function eventTime(event) {
|
|
854
|
+
return typeof event.timestamp === "number" ? event.timestamp : 0;
|
|
855
|
+
}
|
|
856
|
+
function cloneNode(node) {
|
|
857
|
+
return {
|
|
858
|
+
event: {
|
|
859
|
+
...node.event,
|
|
860
|
+
...node.event.attributes !== void 0 ? { attributes: { ...node.event.attributes } } : {}
|
|
861
|
+
},
|
|
862
|
+
children: node.children.map(cloneNode),
|
|
863
|
+
depth: node.depth
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
function joinOnePair(start, terminal) {
|
|
867
|
+
const childMap = /* @__PURE__ */ new Map();
|
|
868
|
+
if (start) {
|
|
869
|
+
for (const child of start.children) {
|
|
870
|
+
childMap.set(child.event.eventId, child);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
for (const child of terminal.children) {
|
|
874
|
+
childMap.set(child.event.eventId, child);
|
|
875
|
+
}
|
|
876
|
+
return {
|
|
877
|
+
event: {
|
|
878
|
+
...terminal.event,
|
|
879
|
+
name: start?.event.name ?? terminal.event.name,
|
|
880
|
+
kind: start?.event.kind ?? terminal.event.kind,
|
|
881
|
+
...start && attemptIdOf(terminal.event) === void 0 && attemptIdOf(start.event) ? {
|
|
882
|
+
attributes: {
|
|
883
|
+
...terminal.event.attributes,
|
|
884
|
+
attemptId: attemptIdOf(start.event)
|
|
885
|
+
}
|
|
886
|
+
} : {}
|
|
887
|
+
},
|
|
888
|
+
children: presentSiblingNodes([...childMap.values()]),
|
|
889
|
+
depth: terminal.depth
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
function joinSiblingGroup(group) {
|
|
893
|
+
if (group.length <= 1) return group;
|
|
894
|
+
const terminals = group.filter((n) => isTerminal(n.event.status)).sort((a, b) => eventTime(a.event) - eventTime(b.event));
|
|
895
|
+
const runnings = group.filter((n) => n.event.status === "running").sort((a, b) => eventTime(a.event) - eventTime(b.event));
|
|
896
|
+
const others = group.filter(
|
|
897
|
+
(n) => !isTerminal(n.event.status) && n.event.status !== "running"
|
|
898
|
+
);
|
|
899
|
+
const terminalStatuses = new Set(terminals.map((n) => n.event.status));
|
|
900
|
+
if (terminalStatuses.size > 1) {
|
|
901
|
+
return group;
|
|
902
|
+
}
|
|
903
|
+
if (terminals.length > 1 && terminals.every((t) => attemptIdOf(t.event) === void 0) && runnings.every((r) => attemptIdOf(r.event) === void 0)) {
|
|
904
|
+
return group;
|
|
905
|
+
}
|
|
906
|
+
const usedRunning = /* @__PURE__ */ new Set();
|
|
907
|
+
const out = [];
|
|
908
|
+
for (const terminal of terminals) {
|
|
909
|
+
const terminalAttempt = attemptIdOf(terminal.event);
|
|
910
|
+
const terminalTs = eventTime(terminal.event);
|
|
911
|
+
const candidate = runnings.find((r) => {
|
|
912
|
+
if (usedRunning.has(r.event.eventId)) return false;
|
|
913
|
+
if (eventTime(r.event) > terminalTs) return false;
|
|
914
|
+
const runningAttempt = attemptIdOf(r.event);
|
|
915
|
+
if (terminalAttempt !== void 0) {
|
|
916
|
+
return runningAttempt === terminalAttempt;
|
|
917
|
+
}
|
|
918
|
+
if (runningAttempt !== void 0) {
|
|
919
|
+
return true;
|
|
920
|
+
}
|
|
921
|
+
return true;
|
|
922
|
+
});
|
|
923
|
+
if (candidate) {
|
|
924
|
+
usedRunning.add(candidate.event.eventId);
|
|
925
|
+
out.push(joinOnePair(candidate, terminal));
|
|
926
|
+
} else {
|
|
927
|
+
out.push({
|
|
928
|
+
...terminal,
|
|
929
|
+
children: presentSiblingNodes(terminal.children)
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
for (const running of runnings) {
|
|
934
|
+
if (usedRunning.has(running.event.eventId)) continue;
|
|
935
|
+
out.push({
|
|
936
|
+
...running,
|
|
937
|
+
children: presentSiblingNodes(running.children)
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
for (const other of others) {
|
|
941
|
+
out.push({
|
|
942
|
+
...other,
|
|
943
|
+
children: presentSiblingNodes(other.children)
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
return out;
|
|
947
|
+
}
|
|
948
|
+
function presentSiblingNodes(nodes) {
|
|
949
|
+
const prepared = nodes.map((n) => ({
|
|
950
|
+
...cloneNode(n),
|
|
951
|
+
children: presentSiblingNodes(n.children)
|
|
952
|
+
}));
|
|
953
|
+
const order = [];
|
|
954
|
+
const groups = /* @__PURE__ */ new Map();
|
|
955
|
+
for (const node of prepared) {
|
|
956
|
+
const key = lifecycleKey(node.event);
|
|
957
|
+
if (!groups.has(key)) {
|
|
958
|
+
groups.set(key, []);
|
|
959
|
+
order.push(key);
|
|
960
|
+
}
|
|
961
|
+
groups.get(key).push(node);
|
|
962
|
+
}
|
|
963
|
+
const out = [];
|
|
964
|
+
for (const key of order) {
|
|
965
|
+
out.push(...joinSiblingGroup(groups.get(key)));
|
|
966
|
+
}
|
|
967
|
+
return out;
|
|
968
|
+
}
|
|
969
|
+
function presentLifecycleJoinedTree(tree) {
|
|
970
|
+
return {
|
|
971
|
+
...tree,
|
|
972
|
+
children: presentSiblingNodes(tree.children),
|
|
973
|
+
metadata: {
|
|
974
|
+
...tree.metadata,
|
|
975
|
+
confidenceBreakdown: { ...tree.metadata.confidenceBreakdown },
|
|
976
|
+
kinds: { ...tree.metadata.kinds },
|
|
977
|
+
...tree.metadata.relationshipSummary !== void 0 ? { relationshipSummary: { ...tree.metadata.relationshipSummary } } : {}
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
|
|
829
982
|
// packages/core/src/exporters/html-exporter.ts
|
|
830
983
|
function renderTreeHtml(nodes, ulClass = "tree") {
|
|
831
984
|
if (nodes.length === 0) return "";
|
|
@@ -853,32 +1006,33 @@ function exportHtml(tree, options) {
|
|
|
853
1006
|
const includeErrors = options?.includeErrors ?? true;
|
|
854
1007
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
855
1008
|
const redacted = options?.redacted ?? true;
|
|
856
|
-
const
|
|
1009
|
+
const view = presentLifecycleJoinedTree(tree);
|
|
1010
|
+
const titleName = escapeHtml(view.name ?? view.runId);
|
|
857
1011
|
const summaryRows = [];
|
|
858
1012
|
summaryRows.push(
|
|
859
|
-
`<tr><th scope="row">runId</th><td><code>${escapeHtml(
|
|
1013
|
+
`<tr><th scope="row">runId</th><td><code>${escapeHtml(view.runId)}</code></td></tr>`
|
|
860
1014
|
);
|
|
861
|
-
if (
|
|
862
|
-
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(
|
|
1015
|
+
if (view.name !== void 0) {
|
|
1016
|
+
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(view.name)}</td></tr>`);
|
|
863
1017
|
}
|
|
864
1018
|
summaryRows.push(
|
|
865
|
-
`<tr><th scope="row">status</th><td>${escapeHtml(String(
|
|
1019
|
+
`<tr><th scope="row">status</th><td>${escapeHtml(String(view.status ?? "unknown"))}</td></tr>`
|
|
866
1020
|
);
|
|
867
1021
|
summaryRows.push(
|
|
868
|
-
`<tr><th scope="row">durationMs</th><td>${
|
|
1022
|
+
`<tr><th scope="row">durationMs</th><td>${view.durationMs !== void 0 ? escapeHtml(String(view.durationMs)) : "\u2014"}</td></tr>`
|
|
869
1023
|
);
|
|
870
1024
|
summaryRows.push(
|
|
871
|
-
`<tr><th scope="row">startedAt</th><td>${
|
|
1025
|
+
`<tr><th scope="row">startedAt</th><td>${view.startedAt !== void 0 ? escapeHtml(String(view.startedAt)) : "\u2014"}</td></tr>`
|
|
872
1026
|
);
|
|
873
1027
|
summaryRows.push(
|
|
874
|
-
`<tr><th scope="row">endedAt</th><td>${
|
|
1028
|
+
`<tr><th scope="row">endedAt</th><td>${view.endedAt !== void 0 ? escapeHtml(String(view.endedAt)) : "\u2014"}</td></tr>`
|
|
875
1029
|
);
|
|
876
1030
|
summaryRows.push(
|
|
877
|
-
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(
|
|
1031
|
+
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(view.metadata.totalEvents))}</td></tr>`
|
|
878
1032
|
);
|
|
879
1033
|
let confidenceHtml = "";
|
|
880
1034
|
if (includeMetadata) {
|
|
881
|
-
const cb =
|
|
1035
|
+
const cb = view.metadata.confidenceBreakdown;
|
|
882
1036
|
confidenceHtml += "<h3>Confidence breakdown</h3><table><thead><tr><th>bucket</th><th>count</th></tr></thead><tbody>";
|
|
883
1037
|
for (const k of Object.keys(cb).sort()) {
|
|
884
1038
|
const key = k;
|
|
@@ -886,14 +1040,14 @@ function exportHtml(tree, options) {
|
|
|
886
1040
|
}
|
|
887
1041
|
confidenceHtml += "</tbody></table>";
|
|
888
1042
|
confidenceHtml += "<h3>Kind breakdown</h3><table><thead><tr><th>kind</th><th>count</th></tr></thead><tbody>";
|
|
889
|
-
for (const k of Object.keys(
|
|
1043
|
+
for (const k of Object.keys(view.metadata.kinds).sort()) {
|
|
890
1044
|
const key = k;
|
|
891
|
-
const c =
|
|
1045
|
+
const c = view.metadata.kinds[key];
|
|
892
1046
|
if (c > 0) confidenceHtml += `<tr><td>${escapeHtml(key)}</td><td>${c}</td></tr>`;
|
|
893
1047
|
}
|
|
894
1048
|
confidenceHtml += "</tbody></table>";
|
|
895
1049
|
}
|
|
896
|
-
const flat = flattenTree(
|
|
1050
|
+
const flat = flattenTree(view);
|
|
897
1051
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
898
1052
|
let errorsHtml = "";
|
|
899
1053
|
if (includeErrors && errors.length > 0) {
|
|
@@ -948,7 +1102,7 @@ footer{margin-top:2rem;font-size:0.85rem;color:#555}
|
|
|
948
1102
|
<header><h1>AgentInspect Run: ${titleName}</h1></header>
|
|
949
1103
|
<p class="note">Generated locally by AgentInspect.</p>
|
|
950
1104
|
${includeMetadata ? `<section class="summary"><h2>Summary</h2><table>${summaryRows.join("")}</table>${confidenceHtml}</section>` : ""}
|
|
951
|
-
<section class="tree"><h2>Execution tree</h2>${
|
|
1105
|
+
<section class="tree"><h2>Execution tree</h2>${view.children.length > 0 ? renderTreeHtml(view.children) : "<p>No steps recorded.</p>"}</section>
|
|
952
1106
|
${errorsHtml}
|
|
953
1107
|
${attrsHtml}
|
|
954
1108
|
<footer>Generated locally by AgentInspect. Review for sensitive data before sharing.</footer>
|
|
@@ -989,7 +1143,8 @@ function exportMarkdown(tree, options) {
|
|
|
989
1143
|
const includeErrors = options?.includeErrors ?? true;
|
|
990
1144
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
991
1145
|
const redacted = options?.redacted ?? true;
|
|
992
|
-
const
|
|
1146
|
+
const view = presentLifecycleJoinedTree(tree);
|
|
1147
|
+
const titleName = view.name ?? view.runId;
|
|
993
1148
|
const lines = [];
|
|
994
1149
|
lines.push(`# AgentInspect Run: ${escapeMarkdown(titleName)}`);
|
|
995
1150
|
lines.push("");
|
|
@@ -998,28 +1153,28 @@ function exportMarkdown(tree, options) {
|
|
|
998
1153
|
if (includeMetadata) {
|
|
999
1154
|
lines.push("## Summary");
|
|
1000
1155
|
lines.push("");
|
|
1001
|
-
lines.push(`- **runId**: ${escapeMarkdown(
|
|
1002
|
-
if (
|
|
1003
|
-
lines.push(`- **status**: ${escapeMarkdown(String(
|
|
1156
|
+
lines.push(`- **runId**: ${escapeMarkdown(view.runId)}`);
|
|
1157
|
+
if (view.name !== void 0) lines.push(`- **name**: ${escapeMarkdown(view.name)}`);
|
|
1158
|
+
lines.push(`- **status**: ${escapeMarkdown(String(view.status ?? "unknown"))}`);
|
|
1004
1159
|
lines.push(
|
|
1005
|
-
`- **durationMs**: ${
|
|
1160
|
+
`- **durationMs**: ${view.durationMs !== void 0 ? escapeMarkdown(String(view.durationMs)) : "-"}`
|
|
1006
1161
|
);
|
|
1007
1162
|
lines.push(
|
|
1008
|
-
`- **startedAt**: ${
|
|
1163
|
+
`- **startedAt**: ${view.startedAt !== void 0 ? escapeMarkdown(String(view.startedAt)) : "-"}`
|
|
1009
1164
|
);
|
|
1010
1165
|
lines.push(
|
|
1011
|
-
`- **endedAt**: ${
|
|
1166
|
+
`- **endedAt**: ${view.endedAt !== void 0 ? escapeMarkdown(String(view.endedAt)) : "-"}`
|
|
1012
1167
|
);
|
|
1013
|
-
lines.push(`- **totalEvents**: ${
|
|
1168
|
+
lines.push(`- **totalEvents**: ${view.metadata.totalEvents}`);
|
|
1014
1169
|
lines.push("");
|
|
1015
1170
|
lines.push("### Confidence breakdown");
|
|
1016
1171
|
lines.push("");
|
|
1017
1172
|
lines.push("| bucket | count |");
|
|
1018
1173
|
lines.push("| --- | --- |");
|
|
1019
|
-
for (const k of Object.keys(
|
|
1174
|
+
for (const k of Object.keys(view.metadata.confidenceBreakdown).sort()) {
|
|
1020
1175
|
const key = k;
|
|
1021
1176
|
lines.push(
|
|
1022
|
-
`| ${escapeMarkdown(key)} | ${
|
|
1177
|
+
`| ${escapeMarkdown(key)} | ${view.metadata.confidenceBreakdown[key]} |`
|
|
1023
1178
|
);
|
|
1024
1179
|
}
|
|
1025
1180
|
lines.push("");
|
|
@@ -1027,9 +1182,9 @@ function exportMarkdown(tree, options) {
|
|
|
1027
1182
|
lines.push("");
|
|
1028
1183
|
lines.push("| kind | count |");
|
|
1029
1184
|
lines.push("| --- | --- |");
|
|
1030
|
-
for (const k of Object.keys(
|
|
1185
|
+
for (const k of Object.keys(view.metadata.kinds).sort()) {
|
|
1031
1186
|
const key = k;
|
|
1032
|
-
const c =
|
|
1187
|
+
const c = view.metadata.kinds[key];
|
|
1033
1188
|
if (c > 0) lines.push(`| ${escapeMarkdown(key)} | ${c} |`);
|
|
1034
1189
|
}
|
|
1035
1190
|
lines.push("");
|
|
@@ -1038,11 +1193,11 @@ function exportMarkdown(tree, options) {
|
|
|
1038
1193
|
lines.push("");
|
|
1039
1194
|
lines.push("```text");
|
|
1040
1195
|
lines.push(
|
|
1041
|
-
|
|
1196
|
+
view.children.length > 0 ? renderTreeAscii(view.children) : "(no steps)"
|
|
1042
1197
|
);
|
|
1043
1198
|
lines.push("```");
|
|
1044
1199
|
lines.push("");
|
|
1045
|
-
const flat = flattenTree(
|
|
1200
|
+
const flat = flattenTree(view);
|
|
1046
1201
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
1047
1202
|
if (includeErrors && errors.length > 0) {
|
|
1048
1203
|
lines.push("## Errors");
|