agent-inspect 4.3.0 → 4.4.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 (97) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/docs/API.md +3 -0
  3. package/docs/CLI.md +3 -0
  4. package/docs/SCHEMA.md +27 -1
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-BS5LSKZ3.mjs → chunk-ORHDQUT6.mjs} +198 -7
  7. package/packages/cli/dist/chunk-ORHDQUT6.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +409 -17
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +176 -10
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-YFMPWEIS.mjs → src-FJOHPC4X.mjs} +3 -3
  13. package/packages/cli/dist/{src-YFMPWEIS.mjs.map → src-FJOHPC4X.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +201 -9
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +12 -8
  17. package/packages/core/dist/advanced.d.ts +12 -8
  18. package/packages/core/dist/advanced.mjs +30 -13
  19. package/packages/core/dist/advanced.mjs.map +1 -1
  20. package/packages/core/dist/checks.cjs +117 -18
  21. package/packages/core/dist/checks.cjs.map +1 -1
  22. package/packages/core/dist/checks.d.cts +11 -3
  23. package/packages/core/dist/checks.d.ts +11 -3
  24. package/packages/core/dist/checks.mjs +42 -1
  25. package/packages/core/dist/checks.mjs.map +1 -1
  26. package/packages/core/dist/{chunk-2ZXEMWGK.mjs → chunk-3USJVBLA.mjs} +3 -3
  27. package/packages/core/dist/{chunk-2ZXEMWGK.mjs.map → chunk-3USJVBLA.mjs.map} +1 -1
  28. package/packages/core/dist/{chunk-HY7H3CQM.mjs → chunk-CAWPF22J.mjs} +4 -3
  29. package/packages/core/dist/chunk-CAWPF22J.mjs.map +1 -0
  30. package/packages/core/dist/{chunk-XUNJMAPD.mjs → chunk-KNYL56KZ.mjs} +38 -3
  31. package/packages/core/dist/chunk-KNYL56KZ.mjs.map +1 -0
  32. package/packages/core/dist/{chunk-IZBJAZGF.mjs → chunk-P366CCL2.mjs} +34 -3
  33. package/packages/core/dist/chunk-P366CCL2.mjs.map +1 -0
  34. package/packages/core/dist/{chunk-4JVGFNQH.mjs → chunk-ULCGIRTC.mjs} +95 -8
  35. package/packages/core/dist/chunk-ULCGIRTC.mjs.map +1 -0
  36. package/packages/core/dist/chunk-VFO76UH3.mjs +228 -0
  37. package/packages/core/dist/chunk-VFO76UH3.mjs.map +1 -0
  38. package/packages/core/dist/{chunk-NQZPZ2FN.mjs → chunk-WRE4CNPF.mjs} +6 -3
  39. package/packages/core/dist/chunk-WRE4CNPF.mjs.map +1 -0
  40. package/packages/core/dist/{chunk-A4V2H3YU.mjs → chunk-ZWA5RWMV.mjs} +40 -4
  41. package/packages/core/dist/chunk-ZWA5RWMV.mjs.map +1 -0
  42. package/packages/core/dist/{context-DjY-jvQk.d.cts → context-BbfkMYjz.d.cts} +5 -3
  43. package/packages/core/dist/{context-BDZmi53V.d.ts → context-Cp8NRbBX.d.ts} +5 -3
  44. package/packages/core/dist/diff.cjs.map +1 -1
  45. package/packages/core/dist/diff.d.cts +3 -3
  46. package/packages/core/dist/diff.d.ts +3 -3
  47. package/packages/core/dist/diff.mjs +1 -1
  48. package/packages/core/dist/exporters.cjs +137 -1
  49. package/packages/core/dist/exporters.cjs.map +1 -1
  50. package/packages/core/dist/exporters.d.cts +6 -3
  51. package/packages/core/dist/exporters.d.ts +6 -3
  52. package/packages/core/dist/exporters.mjs +71 -6
  53. package/packages/core/dist/exporters.mjs.map +1 -1
  54. package/packages/core/dist/index.cjs +181 -6
  55. package/packages/core/dist/index.cjs.map +1 -1
  56. package/packages/core/dist/index.d.cts +14 -7
  57. package/packages/core/dist/index.d.ts +14 -7
  58. package/packages/core/dist/index.mjs +51 -7
  59. package/packages/core/dist/index.mjs.map +1 -1
  60. package/packages/core/dist/{inspect-event-CYAV7Hxm.d.cts → inspect-event-IqwOHbGo.d.cts} +1 -1
  61. package/packages/core/dist/{inspect-event-CYAV7Hxm.d.ts → inspect-event-IqwOHbGo.d.ts} +1 -1
  62. package/packages/core/dist/{log-config-BNQ9UTmP.d.cts → log-config-CW8w5YQ9.d.cts} +1 -1
  63. package/packages/core/dist/{log-config-D3Yp1SZN.d.ts → log-config-SRA4xTp8.d.ts} +1 -1
  64. package/packages/core/dist/logs.d.cts +3 -3
  65. package/packages/core/dist/logs.d.ts +3 -3
  66. package/packages/core/dist/{persisted-inspect-event-BLvb0jSX.d.ts → persisted-inspect-event-DruwqARZ.d.ts} +1 -1
  67. package/packages/core/dist/{persisted-inspect-event-D5SjBz9b.d.cts → persisted-inspect-event-Gd-W8vB7.d.cts} +1 -1
  68. package/packages/core/dist/persisted.cjs +67 -1
  69. package/packages/core/dist/persisted.cjs.map +1 -1
  70. package/packages/core/dist/persisted.d.cts +5 -5
  71. package/packages/core/dist/persisted.d.ts +5 -5
  72. package/packages/core/dist/persisted.mjs +3 -3
  73. package/packages/core/dist/readers.cjs +72 -3
  74. package/packages/core/dist/readers.cjs.map +1 -1
  75. package/packages/core/dist/readers.d.cts +2 -2
  76. package/packages/core/dist/readers.d.ts +2 -2
  77. package/packages/core/dist/readers.mjs +5 -5
  78. package/packages/core/dist/readers.mjs.map +1 -1
  79. package/packages/core/dist/{types-CQun9LW6.d.ts → types-B1X87dUW.d.cts} +16 -2
  80. package/packages/core/dist/{types-C-llnPH0.d.cts → types-BVkjSd0q.d.ts} +16 -2
  81. package/packages/core/dist/types-CvsKGweN.d.cts +12 -0
  82. package/packages/core/dist/types-CvsKGweN.d.ts +12 -0
  83. package/packages/core/dist/writers.cjs +2 -1
  84. package/packages/core/dist/writers.cjs.map +1 -1
  85. package/packages/core/dist/writers.d.cts +2 -2
  86. package/packages/core/dist/writers.d.ts +2 -2
  87. package/packages/core/dist/writers.mjs +3 -4
  88. package/packages/core/dist/writers.mjs.map +1 -1
  89. package/packages/cli/dist/chunk-BS5LSKZ3.mjs.map +0 -1
  90. package/packages/core/dist/chunk-4JVGFNQH.mjs.map +0 -1
  91. package/packages/core/dist/chunk-A4V2H3YU.mjs.map +0 -1
  92. package/packages/core/dist/chunk-EDTQHZPM.mjs +0 -88
  93. package/packages/core/dist/chunk-EDTQHZPM.mjs.map +0 -1
  94. package/packages/core/dist/chunk-HY7H3CQM.mjs.map +0 -1
  95. package/packages/core/dist/chunk-IZBJAZGF.mjs.map +0 -1
  96. package/packages/core/dist/chunk-NQZPZ2FN.mjs.map +0 -1
  97. package/packages/core/dist/chunk-XUNJMAPD.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, validateEvent, isPersistedInspectEvent, normalizeBundleOutputPath, defaultBundleOutputPath, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, extractCorrelationMetadata, truncateStringForProfile, parseTraceJsonl } from './chunk-BS5LSKZ3.mjs';
2
+ import { resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, validateEvent, isPersistedInspectEvent, normalizeBundleOutputPath, defaultBundleOutputPath, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, extractCorrelationMetadata, extractOutcomesFromPersistedEvents, outcomesMatchingStatus, truncateStringForProfile, parseTraceJsonl } from './chunk-ORHDQUT6.mjs';
3
3
  import { realpathSync, constants as constants$1 } from 'fs';
4
4
  import path13 from 'path';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
@@ -11,7 +11,7 @@ import { createServer } from 'http';
11
11
  import { createRequire } from 'module';
12
12
 
13
13
  // package.json
14
- var version = "4.3.0";
14
+ var version = "4.4.0";
15
15
 
16
16
  // packages/cli/src/trace-dir-scale.ts
17
17
  var TRACE_COUNT_WARN = 1e3;
@@ -353,6 +353,8 @@ function nodeIdForEvent(event) {
353
353
  case "step_started":
354
354
  case "step_completed":
355
355
  return event.stepId;
356
+ case "outcome_observed":
357
+ return event.outcomeId;
356
358
  default:
357
359
  return "unknown";
358
360
  }
@@ -536,6 +538,39 @@ function traceEventToPersistedInspectEvent(event, options) {
536
538
  error
537
539
  };
538
540
  }
541
+ case "outcome_observed": {
542
+ const tsObserved = toIsoTimestamp(event.observedAt);
543
+ const attributes = compactAttributes({
544
+ legacyEvent: "outcome_observed",
545
+ outcomeId: event.outcomeId,
546
+ outcomeStatus: event.status,
547
+ expectation: event.expectation,
548
+ method: event.method,
549
+ actual: event.actual,
550
+ evidence: event.evidence,
551
+ observedAt: tsObserved.iso,
552
+ invalidTimestamp: tsMain.invalidTimestamp || tsObserved.invalidTimestamp ? true : void 0
553
+ });
554
+ const out = {
555
+ schemaVersion: "0.2",
556
+ eventId,
557
+ runId: event.runId,
558
+ kind: "OUTCOME",
559
+ name: event.name,
560
+ status: event.status === "failed" ? "error" : "ok",
561
+ timestamp: tsMain.iso,
562
+ confidence: "explicit",
563
+ source,
564
+ attributes
565
+ };
566
+ if (event.parentId !== void 0) {
567
+ out.parentId = event.parentId;
568
+ }
569
+ if (event.actual !== void 0) {
570
+ out.outputSummary = event.actual;
571
+ }
572
+ return out;
573
+ }
539
574
  default: {
540
575
  const _exhaustive = event;
541
576
  throw new Error(`Unsupported trace event: ${_exhaustive.event}`);
@@ -1265,7 +1300,7 @@ function sanitizeOpenInferenceAttributes(attributes, pathPrefix) {
1265
1300
  function mapOpenInferenceKind(span, attributes, pathPrefix) {
1266
1301
  const warnings = [];
1267
1302
  const agentInspectKind = attributes["agent_inspect.kind"];
1268
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
1303
+ if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG" || agentInspectKind === "OUTCOME") {
1269
1304
  return { kind: agentInspectKind, warnings };
1270
1305
  }
1271
1306
  const rawKind = readStringField(span, ["kind", "span_kind", "spanKind"]) ?? (typeof attributes["openinference.span.kind"] === "string" ? attributes["openinference.span.kind"] : void 0);
@@ -1786,7 +1821,7 @@ function mapOtlpStatus(status) {
1786
1821
  function readOtlpKind(attributes, pathPrefix) {
1787
1822
  const warnings = [];
1788
1823
  const agentInspectKind = attributes["agent_inspect.kind"];
1789
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
1824
+ if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG" || agentInspectKind === "OUTCOME") {
1790
1825
  return { kind: agentInspectKind, warnings };
1791
1826
  }
1792
1827
  const operation = attributes["gen_ai.operation.name"];
@@ -3914,6 +3949,40 @@ function redactTraceEventsForReport(events, options) {
3914
3949
  )
3915
3950
  } : {}
3916
3951
  };
3952
+ case "outcome_observed": {
3953
+ const actualAttrs = event.actual !== void 0 ? redactEventAttributes(
3954
+ { value: event.actual },
3955
+ redactor,
3956
+ maxMetadataValueLength,
3957
+ maxPreviewLength
3958
+ ) : void 0;
3959
+ const redactedActual = actualAttrs !== void 0 && "value" in actualAttrs ? actualAttrs.value : void 0;
3960
+ const redactedEvidence = event.evidence !== void 0 ? redactEventAttributes(
3961
+ isRecord6(event.evidence) ? event.evidence : { value: event.evidence },
3962
+ redactor,
3963
+ maxMetadataValueLength,
3964
+ maxPreviewLength
3965
+ ) : void 0;
3966
+ return {
3967
+ ...event,
3968
+ name: truncateStringForProfile(
3969
+ event.name,
3970
+ "name",
3971
+ maxMetadataValueLength,
3972
+ maxPreviewLength
3973
+ ),
3974
+ expectation: truncateStringForProfile(
3975
+ event.expectation,
3976
+ "expectation",
3977
+ maxMetadataValueLength,
3978
+ maxPreviewLength
3979
+ ),
3980
+ ...redactedActual !== void 0 ? { actual: redactedActual } : {},
3981
+ ...redactedEvidence !== void 0 ? { evidence: redactedEvidence } : {}
3982
+ };
3983
+ }
3984
+ default:
3985
+ return event;
3917
3986
  }
3918
3987
  });
3919
3988
  }
@@ -4052,7 +4121,8 @@ function zeroKinds() {
4052
4121
  RESULT: 0,
4053
4122
  ERROR: 0,
4054
4123
  LOGIC: 0,
4055
- LOG: 0
4124
+ LOG: 0,
4125
+ OUTCOME: 0
4056
4126
  };
4057
4127
  }
4058
4128
 
@@ -4855,9 +4925,34 @@ footer{margin-top:2rem;font-size:0.85rem;color:#555}
4855
4925
  `.trim();
4856
4926
  function buildRunReport(events, options) {
4857
4927
  const profile = options.redactionProfile ?? "local";
4928
+ const section = options.section ?? "all";
4858
4929
  const safeEvents = redactTraceEventsForReport(events, {
4859
4930
  redactionProfile: profile
4860
4931
  });
4932
+ const outcomes = summarizeObservedOutcomes(
4933
+ extractOutcomesFromTraceEvents(safeEvents)
4934
+ );
4935
+ const observationsMarkdown = renderObservedOutcomesMarkdown(outcomes);
4936
+ const observationsHtml = renderObservedOutcomesHtml(outcomes);
4937
+ if (section === "observations") {
4938
+ if (options.format === "markdown") {
4939
+ return {
4940
+ format: "markdown",
4941
+ content: `## Observed outcomes
4942
+
4943
+ ${observationsMarkdown}
4944
+ `,
4945
+ contentType: "text/markdown",
4946
+ fileExtension: ".md"
4947
+ };
4948
+ }
4949
+ return {
4950
+ format: "html",
4951
+ content: `<!doctype html><html lang="en"><head><meta charset="utf-8"/><title>Observed outcomes</title><style>${REPORT_HTML_CSS}</style></head><body><h1>Observed outcomes</h1>${observationsHtml}</body></html>`,
4952
+ contentType: "text/html",
4953
+ fileExtension: ".html"
4954
+ };
4955
+ }
4861
4956
  const whatSummary = buildRunWhatSummary(safeEvents);
4862
4957
  const whatText = renderRunWhat(whatSummary, {
4863
4958
  correlation: options.correlation !== false
@@ -4891,6 +4986,10 @@ function buildRunReport(events, options) {
4891
4986
  "```text",
4892
4987
  timelineText,
4893
4988
  "```",
4989
+ "",
4990
+ "## Observed outcomes",
4991
+ "",
4992
+ observationsMarkdown,
4894
4993
  ""
4895
4994
  ];
4896
4995
  if (tail2) {
@@ -4934,6 +5033,7 @@ function buildRunReport(events, options) {
4934
5033
  <p class="note">Generated locally by AgentInspect. Review for sensitive data before sharing.</p>
4935
5034
  <section class="what"><h2>What happened</h2><pre>${escapeHtml(whatText)}</pre></section>
4936
5035
  <section class="timeline"><h2>Timeline</h2><pre>${escapeHtml(timelineText)}</pre></section>
5036
+ <section class="observations"><h2>Observed outcomes</h2>${observationsHtml}</section>
4937
5037
  ${treeSection || '<section class="tree"><h2>Execution tree</h2><p>No steps recorded.</p></section>'}
4938
5038
  ${errorsSection}
4939
5039
  ${attrsSection}
@@ -5785,7 +5885,8 @@ async function searchCommand(options = {}) {
5785
5885
  duration: options.duration,
5786
5886
  limit: parseLimit2(options.limit),
5787
5887
  ...sessionId ? { session: sessionId } : {},
5788
- ...options.correlateGroup ? { correlateGroup: true } : {}
5888
+ ...options.correlateGroup ? { correlateGroup: true } : {},
5889
+ ...options.observation ? { observation: options.observation } : {}
5789
5890
  });
5790
5891
  if (options.json) {
5791
5892
  console.log(JSON.stringify(results, null, 2));
@@ -5857,7 +5958,7 @@ async function newestTraceMtimeMs(traceDir) {
5857
5958
  }
5858
5959
  async function loadSessionRuns(traceDir) {
5859
5960
  try {
5860
- const mod = await import('./src-YFMPWEIS.mjs');
5961
+ const mod = await import('./src-FJOHPC4X.mjs');
5861
5962
  const dbPath = mod.resolveIndexDbPath(traceDir);
5862
5963
  const status = mod.indexStatus(dbPath);
5863
5964
  if (!status.healthy) {
@@ -6302,7 +6403,8 @@ async function reportCommand(runId, options = {}) {
6302
6403
  includeAttributes: options.includeAttributes === true,
6303
6404
  includeErrors: options.noErrors !== true,
6304
6405
  redactionProfile,
6305
- correlation: !options.noCorrelation
6406
+ correlation: !options.noCorrelation,
6407
+ ...options.section ? { section: options.section } : {}
6306
6408
  });
6307
6409
  const outPath = options.output !== void 0 && options.output.trim() !== "" ? path13.resolve(options.output.trim()) : void 0;
6308
6410
  if (outPath !== void 0) {
@@ -8606,6 +8708,40 @@ function createBaselineRegressionRule(options) {
8606
8708
  }
8607
8709
  };
8608
8710
  }
8711
+ function createObservedOutcomeRule(options = {}) {
8712
+ const failOn = options.failOn ?? ["failed"];
8713
+ return {
8714
+ id: "outcome.status",
8715
+ category: "run",
8716
+ defaultSeverity: "error",
8717
+ evaluate(context) {
8718
+ const outcomes = extractOutcomesFromPersistedEvents(context.events);
8719
+ const matching = outcomesMatchingStatus(outcomes, failOn);
8720
+ if (matching.length === 0) return [];
8721
+ return [
8722
+ failFinding(
8723
+ "outcome.status",
8724
+ `Observed outcome count ${matching.length} matched [${failOn.join(", ")}].`,
8725
+ matching.map((outcome) => ({
8726
+ runId: outcome.runId,
8727
+ eventId: outcome.outcomeId,
8728
+ ...outcome.parentId !== void 0 ? { parentId: outcome.parentId } : {},
8729
+ kind: "OUTCOME",
8730
+ name: outcome.name,
8731
+ status: outcome.status,
8732
+ path: `outcome.${outcome.name}`
8733
+ })),
8734
+ { failOn },
8735
+ matching.map((outcome) => ({
8736
+ name: outcome.name,
8737
+ status: outcome.status,
8738
+ expectation: outcome.expectation
8739
+ }))
8740
+ )
8741
+ ];
8742
+ }
8743
+ };
8744
+ }
8609
8745
  function runTraceChecks(input3, options = {}) {
8610
8746
  const selected = resolveSelectedRun(input3, options.runId);
8611
8747
  if (selected.diagnostics.length > 0) {
@@ -9377,6 +9513,22 @@ function buildRules(config, options) {
9377
9513
  if (options.detectStalls) {
9378
9514
  rules.push(createStallDetectionRule({ requireEndedAt: true }));
9379
9515
  }
9516
+ if (options.failOnObservation !== void 0 && options.failOnObservation.trim() !== "") {
9517
+ try {
9518
+ const statuses = options.failOnObservation.split(",").map((value) => value.trim()).filter((value) => value !== "").map((value) => {
9519
+ if (value === "passed" || value === "failed" || value === "unknown" || value === "skipped") {
9520
+ return value;
9521
+ }
9522
+ throw new Error(`unsupported status "${value}"`);
9523
+ });
9524
+ rules.push(createObservedOutcomeRule({ failOn: statuses }));
9525
+ } catch (error) {
9526
+ const message = error instanceof Error ? error.message : String(error);
9527
+ diagnostics.push(
9528
+ diagnostic2("AI_CHECK_INVALID_ARGUMENTS", `--fail-on-observation: ${message}`)
9529
+ );
9530
+ }
9531
+ }
9380
9532
  if (run.maxDepth !== void 0) {
9381
9533
  rules.push(createRunDepthRule({ maxDepth: run.maxDepth }));
9382
9534
  }
@@ -13100,7 +13252,7 @@ function isModuleNotFound3(e) {
13100
13252
  }
13101
13253
  async function loadIndexSqlite() {
13102
13254
  try {
13103
- return await import('./src-YFMPWEIS.mjs');
13255
+ return await import('./src-FJOHPC4X.mjs');
13104
13256
  } catch (e) {
13105
13257
  if (isModuleNotFound3(e)) {
13106
13258
  console.error(
@@ -13505,7 +13657,10 @@ function createCliProgram() {
13505
13657
  ]).option("--max-total-tokens <number>", "add llm.usage with a max total-token budget").option(
13506
13658
  "--max-step-duration <duration>",
13507
13659
  "add run.maxStepDuration (e.g. 30s, 5m)"
13508
- ).option("--require-completed", "add run.requireCompleted").option("--detect-stalls", "add run.stall for running or incomplete events").option("--session <id>", "check all runs in a workflow session (requires --dir)").option("--group <id>", "check all runs sharing a groupId (requires --dir)").option(
13660
+ ).option("--require-completed", "add run.requireCompleted").option("--detect-stalls", "add run.stall for running or incomplete events").option(
13661
+ "--fail-on-observation <status>",
13662
+ "fail when observed outcomes match status (passed, failed, unknown, skipped; comma-separated)"
13663
+ ).option("--session <id>", "check all runs in a workflow session (requires --dir)").option("--group <id>", "check all runs sharing a groupId (requires --dir)").option(
13509
13664
  "--correlate-group",
13510
13665
  "when using --session, also match synthetic group: session keys"
13511
13666
  ).option(
@@ -13626,6 +13781,9 @@ function createCliProgram() {
13626
13781
  "unknown"
13627
13782
  ])
13628
13783
  ).option("--kind <kind>", "filter by step kind/type (llm, tool, logic, \u2026)").option("--type <type>", "alias for --kind on manual trace step type").option("--name <query>", "substring match on run or step name").option("--tool <query>", "substring match on tool step name or metadata.toolName").option(
13784
+ "--observation <status>",
13785
+ "filter by observed outcome status (passed, failed, unknown, skipped)"
13786
+ ).option(
13629
13787
  "--duration <expr>",
13630
13788
  "duration filter on run or step (e.g. >5s, >=500ms)"
13631
13789
  ).option("--limit <number>", "max results (default 50)").option("--session <id>", "limit search to one workflow session").option(
@@ -13672,6 +13830,14 @@ function createCliProgram() {
13672
13830
  "html"
13673
13831
  ])
13674
13832
  ).option("-o, --output <path>", "write report to file (creates parent dirs)").option("--json", "emit JSON wrapper (includes content when writing to stdout)").option("--include-attributes", "include bounded step attributes in tree section").option("--no-errors", "omit error details from tree section").option("--no-correlation", "omit correlation metadata from what section").addOption(
13833
+ new Option("--section <section>", "report section (default: all)").choices([
13834
+ "all",
13835
+ "observations",
13836
+ "what",
13837
+ "timeline",
13838
+ "tree"
13839
+ ])
13840
+ ).addOption(
13675
13841
  new Option(
13676
13842
  "--redaction-profile <profile>",
13677
13843
  "redaction profile for entire report: local, share, strict (default: local)"