@agent-inspect/viewer 6.14.2 → 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.
package/dist/index.mjs CHANGED
@@ -2216,6 +2216,59 @@ async function resolveSuiteCaseTrace(suiteCase, options) {
2216
2216
  };
2217
2217
  }
2218
2218
 
2219
+ // packages/core/src/diagnostics/programmatic.ts
2220
+ var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
2221
+ AI_TRACE_INPUT_INVALID: {
2222
+ code: "AI_TRACE_INPUT_INVALID",
2223
+ summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
2224
+ remediation: "For a file path, use openTraceFile(path).",
2225
+ relatedCodes: ["invalid_input"]
2226
+ },
2227
+ AI_TRACE_FORMAT_UNSUPPORTED: {
2228
+ code: "AI_TRACE_FORMAT_UNSUPPORTED",
2229
+ summary: "No trace reader could detect the input format.",
2230
+ remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
2231
+ relatedCodes: ["unsupported_format"]
2232
+ },
2233
+ AI_TRACE_FORMAT_AMBIGUOUS: {
2234
+ code: "AI_TRACE_FORMAT_AMBIGUOUS",
2235
+ summary: "Multiple trace readers matched the input with equal confidence.",
2236
+ remediation: "Set options.format explicitly to disambiguate the reader.",
2237
+ relatedCodes: ["ambiguous_format"]
2238
+ },
2239
+ AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
2240
+ code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
2241
+ summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
2242
+ remediation: "Use openTraceFile() to normalize a JSONL trace first."
2243
+ },
2244
+ AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
2245
+ code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
2246
+ summary: "Multiple runs are available; select a run before executing checks.",
2247
+ remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
2248
+ relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
2249
+ },
2250
+ AI_TRACE_RELATIONSHIP_SELF_PARENT: {
2251
+ code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2252
+ summary: "A parentId equals its own event/step id.",
2253
+ remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
2254
+ relatedCodes: [
2255
+ "AI_LANGGRAPH_SELF_PARENT_REJECTED",
2256
+ "AI_LOGICAL_SELF_PARENT_REMOVED"
2257
+ ]
2258
+ },
2259
+ AI_TRACE_RELATIONSHIP_CYCLE: {
2260
+ code: "AI_TRACE_RELATIONSHIP_CYCLE",
2261
+ summary: "Trace contains a parentId cycle.",
2262
+ remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
2263
+ relatedCodes: ["structure.cycle"]
2264
+ }
2265
+ });
2266
+ function formatProgrammaticDiagnostic(code, detail) {
2267
+ const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
2268
+ const summary = detail?.trim() ? detail.trim() : spec.summary;
2269
+ return `${code}: ${summary} Remediation: ${spec.remediation}`;
2270
+ }
2271
+
2219
2272
  // packages/core/src/safety/sensitive-key.ts
2220
2273
  function normalizeSensitiveKey(value) {
2221
2274
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
@@ -2436,7 +2489,10 @@ function projectLogicalEvents(events) {
2436
2489
  if (originalParentId === event.eventId) {
2437
2490
  diagnostics.push({
2438
2491
  code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2439
- message: `Removed self-parent edge on ${event.eventId}.`,
2492
+ message: formatProgrammaticDiagnostic(
2493
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2494
+ `Removed self-parent edge on ${event.eventId}.`
2495
+ ),
2440
2496
  eventIds: [event.eventId]
2441
2497
  });
2442
2498
  const { parentId: _drop, ...rest } = event;
@@ -2468,7 +2524,10 @@ function projectLogicalEvents(events) {
2468
2524
  if (nextParent === event.eventId) {
2469
2525
  diagnostics.push({
2470
2526
  code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2471
- message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
2527
+ message: formatProgrammaticDiagnostic(
2528
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2529
+ `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
2530
+ ),
2472
2531
  eventIds: [event.eventId]
2473
2532
  });
2474
2533
  const { parentId: _drop, ...rest } = event;
@@ -2531,6 +2590,11 @@ function pickString(record, keys) {
2531
2590
  return void 0;
2532
2591
  }
2533
2592
 
2593
+ // packages/core/src/checks/trace-facts.ts
2594
+ formatProgrammaticDiagnostic(
2595
+ "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED"
2596
+ );
2597
+
2534
2598
  // packages/core/src/checks/index.ts
2535
2599
  var SEVERITY_RANK = {
2536
2600
  error: 0,
@@ -2640,7 +2704,13 @@ function resolveSelectedRun(input, runId) {
2640
2704
  if (input.read.runs.length === 0) {
2641
2705
  return {
2642
2706
  diagnostics: [
2643
- diagnostic3("AI_CHECK_RUN_SELECTION_REQUIRED", "No runs are available for checks.")
2707
+ diagnostic3(
2708
+ "AI_CHECK_RUN_SELECTION_REQUIRED",
2709
+ formatProgrammaticDiagnostic(
2710
+ "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
2711
+ "No runs are available for checks."
2712
+ )
2713
+ )
2644
2714
  ]
2645
2715
  };
2646
2716
  }
@@ -2648,7 +2718,7 @@ function resolveSelectedRun(input, runId) {
2648
2718
  diagnostics: [
2649
2719
  diagnostic3(
2650
2720
  "AI_CHECK_RUN_SELECTION_REQUIRED",
2651
- "Multiple runs are available; select a run before executing checks."
2721
+ formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
2652
2722
  )
2653
2723
  ]
2654
2724
  };
@@ -3715,6 +3785,38 @@ var TraceReadError = class extends Error {
3715
3785
  this.warnings = warnings;
3716
3786
  }
3717
3787
  };
3788
+ var TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
3789
+ "AI_TRACE_INPUT_INVALID"
3790
+ );
3791
+ function isTraceInput(input) {
3792
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
3793
+ return false;
3794
+ }
3795
+ const record = input;
3796
+ switch (record.type) {
3797
+ case "file":
3798
+ case "directory":
3799
+ return typeof record.path === "string";
3800
+ case "string":
3801
+ return typeof record.content === "string";
3802
+ case "buffer":
3803
+ return Buffer.isBuffer(record.content);
3804
+ case "stdin":
3805
+ return true;
3806
+ default:
3807
+ return false;
3808
+ }
3809
+ }
3810
+ function assertTraceInput(input) {
3811
+ if (isTraceInput(input)) return;
3812
+ throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
3813
+ {
3814
+ code: "AI_TRACE_INPUT_INVALID",
3815
+ message: TRACE_INPUT_INVALID_MESSAGE,
3816
+ severity: "error"
3817
+ }
3818
+ ]);
3819
+ }
3718
3820
  function normalizeCandidate(reader, candidate) {
3719
3821
  const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
3720
3822
  return {
@@ -5069,6 +5171,7 @@ var DEFAULT_TRACE_READERS = [
5069
5171
  otlpJsonReader
5070
5172
  ];
5071
5173
  async function detectTraceFormat(input, options = {}) {
5174
+ assertTraceInput(input);
5072
5175
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
5073
5176
  if (options.format !== void 0) {
5074
5177
  const reader = findReaderByFormat(options.format, readers);
@@ -5165,19 +5268,20 @@ async function detectTraceFormat(input, options = {}) {
5165
5268
  };
5166
5269
  }
5167
5270
  async function readTrace(input, options = {}) {
5271
+ assertTraceInput(input);
5168
5272
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
5169
5273
  const detection = await detectTraceFormat(input, options);
5170
5274
  if (detection.status === "unsupported" || detection.format === void 0) {
5171
5275
  throw new TraceReadError(
5172
5276
  "unsupported_format",
5173
- "No trace reader could detect the input format.",
5277
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
5174
5278
  detection.warnings
5175
5279
  );
5176
5280
  }
5177
5281
  if (detection.status === "ambiguous") {
5178
5282
  throw new TraceReadError(
5179
5283
  "ambiguous_format",
5180
- "Multiple trace readers matched the input with equal confidence.",
5284
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
5181
5285
  detection.warnings
5182
5286
  );
5183
5287
  }
@@ -5185,7 +5289,10 @@ async function readTrace(input, options = {}) {
5185
5289
  if (!reader) {
5186
5290
  throw new TraceReadError(
5187
5291
  "unsupported_format",
5188
- `No trace reader is registered for format "${detection.format}".`,
5292
+ formatProgrammaticDiagnostic(
5293
+ "AI_TRACE_FORMAT_UNSUPPORTED",
5294
+ `No trace reader is registered for format "${detection.format}".`
5295
+ ),
5189
5296
  detection.warnings
5190
5297
  );
5191
5298
  }