@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.cjs CHANGED
@@ -2223,6 +2223,59 @@ async function resolveSuiteCaseTrace(suiteCase, options) {
2223
2223
  };
2224
2224
  }
2225
2225
 
2226
+ // packages/core/src/diagnostics/programmatic.ts
2227
+ var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
2228
+ AI_TRACE_INPUT_INVALID: {
2229
+ code: "AI_TRACE_INPUT_INVALID",
2230
+ summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
2231
+ remediation: "For a file path, use openTraceFile(path).",
2232
+ relatedCodes: ["invalid_input"]
2233
+ },
2234
+ AI_TRACE_FORMAT_UNSUPPORTED: {
2235
+ code: "AI_TRACE_FORMAT_UNSUPPORTED",
2236
+ summary: "No trace reader could detect the input format.",
2237
+ remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
2238
+ relatedCodes: ["unsupported_format"]
2239
+ },
2240
+ AI_TRACE_FORMAT_AMBIGUOUS: {
2241
+ code: "AI_TRACE_FORMAT_AMBIGUOUS",
2242
+ summary: "Multiple trace readers matched the input with equal confidence.",
2243
+ remediation: "Set options.format explicitly to disambiguate the reader.",
2244
+ relatedCodes: ["ambiguous_format"]
2245
+ },
2246
+ AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
2247
+ code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
2248
+ summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
2249
+ remediation: "Use openTraceFile() to normalize a JSONL trace first."
2250
+ },
2251
+ AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
2252
+ code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
2253
+ summary: "Multiple runs are available; select a run before executing checks.",
2254
+ remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
2255
+ relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
2256
+ },
2257
+ AI_TRACE_RELATIONSHIP_SELF_PARENT: {
2258
+ code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2259
+ summary: "A parentId equals its own event/step id.",
2260
+ remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
2261
+ relatedCodes: [
2262
+ "AI_LANGGRAPH_SELF_PARENT_REJECTED",
2263
+ "AI_LOGICAL_SELF_PARENT_REMOVED"
2264
+ ]
2265
+ },
2266
+ AI_TRACE_RELATIONSHIP_CYCLE: {
2267
+ code: "AI_TRACE_RELATIONSHIP_CYCLE",
2268
+ summary: "Trace contains a parentId cycle.",
2269
+ remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
2270
+ relatedCodes: ["structure.cycle"]
2271
+ }
2272
+ });
2273
+ function formatProgrammaticDiagnostic(code, detail) {
2274
+ const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
2275
+ const summary = detail?.trim() ? detail.trim() : spec.summary;
2276
+ return `${code}: ${summary} Remediation: ${spec.remediation}`;
2277
+ }
2278
+
2226
2279
  // packages/core/src/safety/sensitive-key.ts
2227
2280
  function normalizeSensitiveKey(value) {
2228
2281
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
@@ -2443,7 +2496,10 @@ function projectLogicalEvents(events) {
2443
2496
  if (originalParentId === event.eventId) {
2444
2497
  diagnostics.push({
2445
2498
  code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2446
- message: `Removed self-parent edge on ${event.eventId}.`,
2499
+ message: formatProgrammaticDiagnostic(
2500
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2501
+ `Removed self-parent edge on ${event.eventId}.`
2502
+ ),
2447
2503
  eventIds: [event.eventId]
2448
2504
  });
2449
2505
  const { parentId: _drop, ...rest } = event;
@@ -2475,7 +2531,10 @@ function projectLogicalEvents(events) {
2475
2531
  if (nextParent === event.eventId) {
2476
2532
  diagnostics.push({
2477
2533
  code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2478
- message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
2534
+ message: formatProgrammaticDiagnostic(
2535
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
2536
+ `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
2537
+ ),
2479
2538
  eventIds: [event.eventId]
2480
2539
  });
2481
2540
  const { parentId: _drop, ...rest } = event;
@@ -2538,6 +2597,11 @@ function pickString(record, keys) {
2538
2597
  return void 0;
2539
2598
  }
2540
2599
 
2600
+ // packages/core/src/checks/trace-facts.ts
2601
+ formatProgrammaticDiagnostic(
2602
+ "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED"
2603
+ );
2604
+
2541
2605
  // packages/core/src/checks/index.ts
2542
2606
  var SEVERITY_RANK = {
2543
2607
  error: 0,
@@ -2647,7 +2711,13 @@ function resolveSelectedRun(input, runId) {
2647
2711
  if (input.read.runs.length === 0) {
2648
2712
  return {
2649
2713
  diagnostics: [
2650
- diagnostic3("AI_CHECK_RUN_SELECTION_REQUIRED", "No runs are available for checks.")
2714
+ diagnostic3(
2715
+ "AI_CHECK_RUN_SELECTION_REQUIRED",
2716
+ formatProgrammaticDiagnostic(
2717
+ "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
2718
+ "No runs are available for checks."
2719
+ )
2720
+ )
2651
2721
  ]
2652
2722
  };
2653
2723
  }
@@ -2655,7 +2725,7 @@ function resolveSelectedRun(input, runId) {
2655
2725
  diagnostics: [
2656
2726
  diagnostic3(
2657
2727
  "AI_CHECK_RUN_SELECTION_REQUIRED",
2658
- "Multiple runs are available; select a run before executing checks."
2728
+ formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
2659
2729
  )
2660
2730
  ]
2661
2731
  };
@@ -3722,6 +3792,38 @@ var TraceReadError = class extends Error {
3722
3792
  this.warnings = warnings;
3723
3793
  }
3724
3794
  };
3795
+ var TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
3796
+ "AI_TRACE_INPUT_INVALID"
3797
+ );
3798
+ function isTraceInput(input) {
3799
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
3800
+ return false;
3801
+ }
3802
+ const record = input;
3803
+ switch (record.type) {
3804
+ case "file":
3805
+ case "directory":
3806
+ return typeof record.path === "string";
3807
+ case "string":
3808
+ return typeof record.content === "string";
3809
+ case "buffer":
3810
+ return Buffer.isBuffer(record.content);
3811
+ case "stdin":
3812
+ return true;
3813
+ default:
3814
+ return false;
3815
+ }
3816
+ }
3817
+ function assertTraceInput(input) {
3818
+ if (isTraceInput(input)) return;
3819
+ throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
3820
+ {
3821
+ code: "AI_TRACE_INPUT_INVALID",
3822
+ message: TRACE_INPUT_INVALID_MESSAGE,
3823
+ severity: "error"
3824
+ }
3825
+ ]);
3826
+ }
3725
3827
  function normalizeCandidate(reader, candidate) {
3726
3828
  const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
3727
3829
  return {
@@ -5076,6 +5178,7 @@ var DEFAULT_TRACE_READERS = [
5076
5178
  otlpJsonReader
5077
5179
  ];
5078
5180
  async function detectTraceFormat(input, options = {}) {
5181
+ assertTraceInput(input);
5079
5182
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
5080
5183
  if (options.format !== void 0) {
5081
5184
  const reader = findReaderByFormat(options.format, readers);
@@ -5172,19 +5275,20 @@ async function detectTraceFormat(input, options = {}) {
5172
5275
  };
5173
5276
  }
5174
5277
  async function readTrace(input, options = {}) {
5278
+ assertTraceInput(input);
5175
5279
  const readers = options.readers ?? DEFAULT_TRACE_READERS;
5176
5280
  const detection = await detectTraceFormat(input, options);
5177
5281
  if (detection.status === "unsupported" || detection.format === void 0) {
5178
5282
  throw new TraceReadError(
5179
5283
  "unsupported_format",
5180
- "No trace reader could detect the input format.",
5284
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
5181
5285
  detection.warnings
5182
5286
  );
5183
5287
  }
5184
5288
  if (detection.status === "ambiguous") {
5185
5289
  throw new TraceReadError(
5186
5290
  "ambiguous_format",
5187
- "Multiple trace readers matched the input with equal confidence.",
5291
+ formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
5188
5292
  detection.warnings
5189
5293
  );
5190
5294
  }
@@ -5192,7 +5296,10 @@ async function readTrace(input, options = {}) {
5192
5296
  if (!reader) {
5193
5297
  throw new TraceReadError(
5194
5298
  "unsupported_format",
5195
- `No trace reader is registered for format "${detection.format}".`,
5299
+ formatProgrammaticDiagnostic(
5300
+ "AI_TRACE_FORMAT_UNSUPPORTED",
5301
+ `No trace reader is registered for format "${detection.format}".`
5302
+ ),
5196
5303
  detection.warnings
5197
5304
  );
5198
5305
  }