agent-inspect 6.14.1 → 6.15.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/README.md +1 -1
  3. package/docs/API.md +19 -3
  4. package/docs/KNOWN-ISSUES.md +2 -1
  5. package/package.json +2 -2
  6. package/packages/cli/dist/{chunk-MEO2Z3KE.mjs → chunk-LFSBMUCD.mjs} +316 -41
  7. package/packages/cli/dist/chunk-LFSBMUCD.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +388 -42
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +59 -6
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-6VZNGIF6.mjs → src-5J2HPOJ3.mjs} +3 -3
  13. package/packages/cli/dist/{src-6VZNGIF6.mjs.map → src-5J2HPOJ3.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +268 -24
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +18 -10
  17. package/packages/core/dist/advanced.d.ts +18 -10
  18. package/packages/core/dist/advanced.mjs +7 -6
  19. package/packages/core/dist/advanced.mjs.map +1 -1
  20. package/packages/core/dist/checks.cjs +221 -22
  21. package/packages/core/dist/checks.cjs.map +1 -1
  22. package/packages/core/dist/checks.d.cts +18 -8
  23. package/packages/core/dist/checks.d.ts +18 -8
  24. package/packages/core/dist/checks.mjs +2 -1
  25. package/packages/core/dist/chunk-AK5EN4U2.mjs +174 -0
  26. package/packages/core/dist/chunk-AK5EN4U2.mjs.map +1 -0
  27. package/packages/core/dist/chunk-FWK3Q3OJ.mjs +56 -0
  28. package/packages/core/dist/chunk-FWK3Q3OJ.mjs.map +1 -0
  29. package/packages/core/dist/{chunk-CTA6XNDP.mjs → chunk-HT54OLPE.mjs} +54 -7
  30. package/packages/core/dist/chunk-HT54OLPE.mjs.map +1 -0
  31. package/packages/core/dist/{chunk-BS2QCAJX.mjs → chunk-NF4ZHNTC.mjs} +169 -25
  32. package/packages/core/dist/chunk-NF4ZHNTC.mjs.map +1 -0
  33. package/packages/core/dist/{chunk-UOPVGCOB.mjs → chunk-NXQF73EC.mjs} +3 -3
  34. package/packages/core/dist/{chunk-UOPVGCOB.mjs.map → chunk-NXQF73EC.mjs.map} +1 -1
  35. package/packages/core/dist/{chunk-LFWZEO2L.mjs → chunk-SGL4JGCD.mjs} +3 -3
  36. package/packages/core/dist/{chunk-LFWZEO2L.mjs.map → chunk-SGL4JGCD.mjs.map} +1 -1
  37. package/packages/core/dist/{context-BHAgRjOe.d.cts → context-Ca5yK8Cs.d.cts} +3 -3
  38. package/packages/core/dist/{context-Blyjb5my.d.ts → context-D6cS4XIL.d.ts} +3 -3
  39. package/packages/core/dist/diff.d.cts +3 -3
  40. package/packages/core/dist/diff.d.ts +3 -3
  41. package/packages/core/dist/exporters.d.cts +3 -3
  42. package/packages/core/dist/exporters.d.ts +3 -3
  43. package/packages/core/dist/exporters.mjs +1 -1
  44. package/packages/core/dist/index-B259NKkH.d.cts +102 -0
  45. package/packages/core/dist/index-B9ZGvUVL.d.ts +102 -0
  46. package/packages/core/dist/{index-Bu_vOjql.d.ts → index-BsCcOKxy.d.ts} +4 -4
  47. package/packages/core/dist/{index-CmXMS-MF.d.cts → index-Xk9X-yjY.d.cts} +4 -4
  48. package/packages/core/dist/index.d.cts +6 -6
  49. package/packages/core/dist/index.d.ts +6 -6
  50. package/packages/core/dist/{inspect-event-DVg84S4v.d.cts → inspect-event-DRthdZlf.d.cts} +9 -0
  51. package/packages/core/dist/{inspect-event-DVg84S4v.d.ts → inspect-event-DRthdZlf.d.ts} +9 -0
  52. package/packages/core/dist/{log-config-BG1WmWf2.d.cts → log-config-CFlIJHTf.d.cts} +1 -1
  53. package/packages/core/dist/{log-config-Ck0aT_Ou.d.ts → log-config-OZRfpHED.d.ts} +1 -1
  54. package/packages/core/dist/logs.cjs +95 -15
  55. package/packages/core/dist/logs.cjs.map +1 -1
  56. package/packages/core/dist/logs.d.cts +3 -3
  57. package/packages/core/dist/logs.d.ts +3 -3
  58. package/packages/core/dist/logs.mjs +2 -2
  59. package/packages/core/dist/{persisted-inspect-event-ChE7pGb7.d.ts → persisted-inspect-event-BVucFVrP.d.ts} +1 -1
  60. package/packages/core/dist/{persisted-inspect-event-d-mSP8kd.d.cts → persisted-inspect-event-CVZWZldL.d.cts} +1 -1
  61. package/packages/core/dist/persisted.cjs +95 -15
  62. package/packages/core/dist/persisted.cjs.map +1 -1
  63. package/packages/core/dist/persisted.d.cts +5 -5
  64. package/packages/core/dist/persisted.d.ts +5 -5
  65. package/packages/core/dist/persisted.mjs +3 -3
  66. package/packages/core/dist/readers.cjs +203 -18
  67. package/packages/core/dist/readers.cjs.map +1 -1
  68. package/packages/core/dist/readers.d.cts +27 -78
  69. package/packages/core/dist/readers.d.ts +27 -78
  70. package/packages/core/dist/readers.mjs +4 -3
  71. package/packages/core/dist/{types-MuwXSJ4b.d.ts → types--ainI31J.d.ts} +1 -1
  72. package/packages/core/dist/{types-BLX3tiOW.d.cts → types-UnrNaTo2.d.cts} +1 -1
  73. package/packages/core/dist/writers.d.cts +2 -2
  74. package/packages/core/dist/writers.d.ts +2 -2
  75. package/packages/cli/dist/chunk-MEO2Z3KE.mjs.map +0 -1
  76. package/packages/core/dist/chunk-BS2QCAJX.mjs.map +0 -1
  77. package/packages/core/dist/chunk-CTA6XNDP.mjs.map +0 -1
  78. package/packages/core/dist/chunk-T5MASTIW.mjs +0 -94
  79. package/packages/core/dist/chunk-T5MASTIW.mjs.map +0 -1
@@ -868,6 +868,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
868
868
  function inc(map, key) {
869
869
  map[key] = (map[key] ?? 0) + 1;
870
870
  }
871
+ function confidenceRank(confidence) {
872
+ switch (confidence) {
873
+ case "unknown":
874
+ return 0;
875
+ case "heuristic":
876
+ return 1;
877
+ case "correlated":
878
+ return 2;
879
+ case "explicit":
880
+ return 3;
881
+ default:
882
+ return 0;
883
+ }
884
+ }
871
885
  function computeRunStatus(events) {
872
886
  let runTerminal;
873
887
  let sawRunEvent = false;
@@ -888,6 +902,84 @@ function computeRunStatus(events) {
888
902
  }
889
903
  return hasRunning ? "running" : "ok";
890
904
  }
905
+ function linkNodesVisibilityFirst(nodes) {
906
+ let selfParentCount = 0;
907
+ let unresolvedParentCount = 0;
908
+ let normalizedEdgeCount = 0;
909
+ let cycleCount = 0;
910
+ const pending = [];
911
+ for (const node of nodes.values()) {
912
+ const parentId = node.event.parentId;
913
+ if (!parentId) continue;
914
+ if (parentId === node.event.eventId) {
915
+ selfParentCount += 1;
916
+ normalizedEdgeCount += 1;
917
+ continue;
918
+ }
919
+ if (!nodes.has(parentId)) {
920
+ unresolvedParentCount += 1;
921
+ continue;
922
+ }
923
+ pending.push({
924
+ childId: node.event.eventId,
925
+ parentId,
926
+ childTimestamp: node.event.timestamp,
927
+ childConfidence: node.event.confidence
928
+ });
929
+ }
930
+ pending.sort((a, b) => {
931
+ const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
932
+ if (conf !== 0) return conf;
933
+ return a.childTimestamp - b.childTimestamp;
934
+ });
935
+ const parentOf = /* @__PURE__ */ new Map();
936
+ for (const edge of pending) {
937
+ parentOf.set(edge.childId, edge.parentId);
938
+ let cursor = edge.parentId;
939
+ const seen = /* @__PURE__ */ new Set([edge.childId]);
940
+ let cyclic = false;
941
+ while (cursor) {
942
+ if (seen.has(cursor)) {
943
+ cyclic = true;
944
+ break;
945
+ }
946
+ seen.add(cursor);
947
+ cursor = parentOf.get(cursor);
948
+ }
949
+ if (cyclic) {
950
+ parentOf.delete(edge.childId);
951
+ cycleCount += 1;
952
+ normalizedEdgeCount += 1;
953
+ }
954
+ }
955
+ for (const [childId, parentId] of parentOf) {
956
+ nodes.get(parentId).children.push(nodes.get(childId));
957
+ }
958
+ const roots = [];
959
+ for (const node of nodes.values()) {
960
+ if (!parentOf.has(node.event.eventId)) {
961
+ roots.push(node);
962
+ }
963
+ }
964
+ const assignDepth = (n, depth, stack) => {
965
+ if (stack.has(n.event.eventId)) return;
966
+ n.depth = depth;
967
+ stack.add(n.event.eventId);
968
+ for (const c of n.children) assignDepth(c, depth + 1, stack);
969
+ stack.delete(n.event.eventId);
970
+ };
971
+ for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
972
+ return {
973
+ roots,
974
+ summary: {
975
+ rootCount: roots.length,
976
+ selfParentCount,
977
+ cycleCount,
978
+ unresolvedParentCount,
979
+ normalizedEdgeCount
980
+ }
981
+ };
982
+ }
891
983
  var TreeBuilder = class {
892
984
  constructor(options) {
893
985
  void options?.config;
@@ -905,20 +997,7 @@ var TreeBuilder = class {
905
997
  for (const e of sorted) {
906
998
  nodes.set(e.eventId, { event: e, children: [], depth: 0 });
907
999
  }
908
- const roots = [];
909
- for (const node of nodes.values()) {
910
- const parentId = node.event.parentId;
911
- if (parentId && nodes.has(parentId)) {
912
- nodes.get(parentId).children.push(node);
913
- } else {
914
- roots.push(node);
915
- }
916
- }
917
- const assignDepth = (n, depth) => {
918
- n.depth = depth;
919
- for (const c of n.children) assignDepth(c, depth + 1);
920
- };
921
- for (const r of roots) assignDepth(r, 0);
1000
+ const { roots, summary } = linkNodesVisibilityFirst(nodes);
922
1001
  const confidenceBreakdown = {
923
1002
  explicit: 0,
924
1003
  correlated: 0,
@@ -946,7 +1025,8 @@ var TreeBuilder = class {
946
1025
  metadata: {
947
1026
  totalEvents: sorted.length,
948
1027
  confidenceBreakdown,
949
- kinds
1028
+ kinds,
1029
+ relationshipSummary: summary
950
1030
  }
951
1031
  });
952
1032
  }
@@ -1101,6 +1181,59 @@ function persistedInspectEventsToRunTrees(events, options) {
1101
1181
  return new TreeBuilder().build(inspectEvents);
1102
1182
  }
1103
1183
 
1184
+ // packages/core/src/diagnostics/programmatic.ts
1185
+ var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
1186
+ AI_TRACE_INPUT_INVALID: {
1187
+ code: "AI_TRACE_INPUT_INVALID",
1188
+ summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
1189
+ remediation: "For a file path, use openTraceFile(path).",
1190
+ relatedCodes: ["invalid_input"]
1191
+ },
1192
+ AI_TRACE_FORMAT_UNSUPPORTED: {
1193
+ code: "AI_TRACE_FORMAT_UNSUPPORTED",
1194
+ summary: "No trace reader could detect the input format.",
1195
+ remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
1196
+ relatedCodes: ["unsupported_format"]
1197
+ },
1198
+ AI_TRACE_FORMAT_AMBIGUOUS: {
1199
+ code: "AI_TRACE_FORMAT_AMBIGUOUS",
1200
+ summary: "Multiple trace readers matched the input with equal confidence.",
1201
+ remediation: "Set options.format explicitly to disambiguate the reader.",
1202
+ relatedCodes: ["ambiguous_format"]
1203
+ },
1204
+ AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
1205
+ code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
1206
+ summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
1207
+ remediation: "Use openTraceFile() to normalize a JSONL trace first."
1208
+ },
1209
+ AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
1210
+ code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
1211
+ summary: "Multiple runs are available; select a run before executing checks.",
1212
+ remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
1213
+ relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
1214
+ },
1215
+ AI_TRACE_RELATIONSHIP_SELF_PARENT: {
1216
+ code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
1217
+ summary: "A parentId equals its own event/step id.",
1218
+ remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
1219
+ relatedCodes: [
1220
+ "AI_LANGGRAPH_SELF_PARENT_REJECTED",
1221
+ "AI_LOGICAL_SELF_PARENT_REMOVED"
1222
+ ]
1223
+ },
1224
+ AI_TRACE_RELATIONSHIP_CYCLE: {
1225
+ code: "AI_TRACE_RELATIONSHIP_CYCLE",
1226
+ summary: "Trace contains a parentId cycle.",
1227
+ remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
1228
+ relatedCodes: ["structure.cycle"]
1229
+ }
1230
+ });
1231
+ function formatProgrammaticDiagnostic(code, detail) {
1232
+ const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
1233
+ const summary = detail?.trim() ? detail.trim() : spec.summary;
1234
+ return `${code}: ${summary} Remediation: ${spec.remediation}`;
1235
+ }
1236
+
1104
1237
  // packages/core/src/readers/index.ts
1105
1238
  var DEFAULT_MAX_TRACE_INPUT_BYTES = 10 * 1024 * 1024;
1106
1239
  var MIN_DETECTION_CONFIDENCE = 0.5;
@@ -1175,6 +1308,38 @@ var TraceReadError = class extends Error {
1175
1308
  this.warnings = warnings;
1176
1309
  }
1177
1310
  };
1311
+ var TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
1312
+ "AI_TRACE_INPUT_INVALID"
1313
+ );
1314
+ function isTraceInput(input) {
1315
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
1316
+ return false;
1317
+ }
1318
+ const record = input;
1319
+ switch (record.type) {
1320
+ case "file":
1321
+ case "directory":
1322
+ return typeof record.path === "string";
1323
+ case "string":
1324
+ return typeof record.content === "string";
1325
+ case "buffer":
1326
+ return Buffer.isBuffer(record.content);
1327
+ case "stdin":
1328
+ return true;
1329
+ default:
1330
+ return false;
1331
+ }
1332
+ }
1333
+ function assertTraceInput(input) {
1334
+ if (isTraceInput(input)) return;
1335
+ throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
1336
+ {
1337
+ code: "AI_TRACE_INPUT_INVALID",
1338
+ message: TRACE_INPUT_INVALID_MESSAGE,
1339
+ severity: "error"
1340
+ }
1341
+ ]);
1342
+ }
1178
1343
  function normalizeCandidate(reader, candidate) {
1179
1344
  const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
1180
1345
  return {
@@ -2529,6 +2694,7 @@ var DEFAULT_TRACE_READERS = [
2529
2694
  otlpJsonReader
2530
2695
  ];
2531
2696
  async function detectTraceFormat(input, options = {}) {
2697
+ assertTraceInput(input);
2532
2698
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
2533
2699
  if (options.format !== void 0) {
2534
2700
  const reader = findReaderByFormat(options.format, readers);
@@ -2625,19 +2791,20 @@ async function detectTraceFormat(input, options = {}) {
2625
2791
  };
2626
2792
  }
2627
2793
  async function readTrace(input, options = {}) {
2794
+ assertTraceInput(input);
2628
2795
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
2629
2796
  const detection = await detectTraceFormat(input, options);
2630
2797
  if (detection.status === "unsupported" || detection.format === void 0) {
2631
2798
  throw new TraceReadError(
2632
2799
  "unsupported_format",
2633
- "No trace reader could detect the input format.",
2800
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
2634
2801
  detection.warnings
2635
2802
  );
2636
2803
  }
2637
2804
  if (detection.status === "ambiguous") {
2638
2805
  throw new TraceReadError(
2639
2806
  "ambiguous_format",
2640
- "Multiple trace readers matched the input with equal confidence.",
2807
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
2641
2808
  detection.warnings
2642
2809
  );
2643
2810
  }
@@ -2645,7 +2812,10 @@ async function readTrace(input, options = {}) {
2645
2812
  if (!reader) {
2646
2813
  throw new TraceReadError(
2647
2814
  "unsupported_format",
2648
- `No trace reader is registered for format "${detection.format}".`,
2815
+ formatProgrammaticDiagnostic(
2816
+ "AI_TRACE_FORMAT_UNSUPPORTED",
2817
+ `No trace reader is registered for format "${detection.format}".`
2818
+ ),
2649
2819
  detection.warnings
2650
2820
  );
2651
2821
  }
@@ -2674,13 +2844,28 @@ async function readTrace(input, options = {}) {
2674
2844
  function openTrace(input, options = {}) {
2675
2845
  return readTrace(input, options);
2676
2846
  }
2847
+ function openTraceFile(filePath, options = {}) {
2848
+ return openTrace({ type: "file", path: filePath }, options);
2849
+ }
2850
+ function openTraceDirectory(dirPath, options = {}) {
2851
+ return openTrace({ type: "directory", path: dirPath }, options);
2852
+ }
2853
+ function openTraceText(content, options = {}) {
2854
+ return openTrace({ type: "string", content }, options);
2855
+ }
2677
2856
 
2678
2857
  exports.DEFAULT_TRACE_READERS = DEFAULT_TRACE_READERS;
2858
+ exports.PROGRAMMATIC_DIAGNOSTIC_SPECS = PROGRAMMATIC_DIAGNOSTIC_SPECS;
2679
2859
  exports.TraceReadError = TraceReadError;
2680
2860
  exports.agentInspectJsonlReader = agentInspectJsonlReader;
2861
+ exports.assertTraceInput = assertTraceInput;
2681
2862
  exports.detectTraceFormat = detectTraceFormat;
2863
+ exports.formatProgrammaticDiagnostic = formatProgrammaticDiagnostic;
2682
2864
  exports.openInferenceJsonReader = openInferenceJsonReader;
2683
2865
  exports.openTrace = openTrace;
2866
+ exports.openTraceDirectory = openTraceDirectory;
2867
+ exports.openTraceFile = openTraceFile;
2868
+ exports.openTraceText = openTraceText;
2684
2869
  exports.otlpJsonReader = otlpJsonReader;
2685
2870
  exports.readTrace = readTrace;
2686
2871
  //# sourceMappingURL=readers.cjs.map