@agent-inspect/mcp-server 4.2.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.
package/dist/index.cjs CHANGED
@@ -78,6 +78,9 @@ function isTraceEvent(value) {
78
78
  case "step_completed": {
79
79
  return typeof value.runId === "string" && typeof value.stepId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
80
80
  }
81
+ case "outcome_observed": {
82
+ return typeof value.runId === "string" && typeof value.outcomeId === "string" && typeof value.name === "string" && typeof value.expectation === "string" && (value.status === "passed" || value.status === "failed" || value.status === "unknown" || value.status === "skipped") && typeof value.observedAt === "number";
83
+ }
81
84
  default:
82
85
  return false;
83
86
  }
@@ -95,7 +98,8 @@ var INSPECT_KINDS = [
95
98
  "RESULT",
96
99
  "ERROR",
97
100
  "LOGIC",
98
- "LOG"
101
+ "LOG",
102
+ "OUTCOME"
99
103
  ];
100
104
  var ATTRIBUTION_CONFIDENCES = [
101
105
  "explicit",
@@ -387,6 +391,32 @@ function fromLegacyStepCompleted(event) {
387
391
  if (error) out.error = error;
388
392
  return out;
389
393
  }
394
+ function fromLegacyOutcomeObserved(event) {
395
+ const attrs = event.attributes ?? {};
396
+ const observedAtRaw = attrs.observedAt;
397
+ const observedAt = typeof observedAtRaw === "string" ? Date.parse(observedAtRaw) : typeof observedAtRaw === "number" && Number.isFinite(observedAtRaw) ? observedAtRaw : resolveTimes(event).timestamp;
398
+ const status = attrs.outcomeStatus;
399
+ const out = {
400
+ schemaVersion: "0.1",
401
+ event: "outcome_observed",
402
+ timestamp: observedAt,
403
+ runId: event.runId,
404
+ outcomeId: typeof attrs.outcomeId === "string" ? attrs.outcomeId : event.eventId,
405
+ name: event.name,
406
+ expectation: typeof attrs.expectation === "string" ? attrs.expectation : event.name,
407
+ status: status === "passed" || status === "failed" || status === "unknown" || status === "skipped" ? status : "unknown",
408
+ observedAt
409
+ };
410
+ if (event.parentId !== void 0) out.parentId = event.parentId;
411
+ if (typeof attrs.method === "string") out.method = attrs.method;
412
+ if (attrs.actual !== void 0) out.actual = attrs.actual;
413
+ if (event.outputSummary !== void 0) out.actual = event.outputSummary;
414
+ if (attrs.evidence !== void 0) out.evidence = attrs.evidence;
415
+ return out;
416
+ }
417
+ function fromNativeOutcome(event) {
418
+ return [fromLegacyOutcomeObserved(event)];
419
+ }
390
420
  function fromNativeRun(event) {
391
421
  const { timestamp, startTime, endTime } = resolveTimes(event);
392
422
  const runStatus = mapPersistedStatusToRunStatus(event.status);
@@ -474,9 +504,13 @@ function persistedInspectEventToTraceEvents(event) {
474
504
  if (legacyEvent === "run_completed") return [fromLegacyRunCompleted(event)];
475
505
  if (legacyEvent === "step_started") return [fromLegacyStepStarted(event)];
476
506
  if (legacyEvent === "step_completed") return [fromLegacyStepCompleted(event)];
507
+ if (legacyEvent === "outcome_observed") return [fromLegacyOutcomeObserved(event)];
477
508
  if (event.kind === "RUN") {
478
509
  return fromNativeRun(event);
479
510
  }
511
+ if (event.kind === "OUTCOME") {
512
+ return fromNativeOutcome(event);
513
+ }
480
514
  return fromNativeStep(event);
481
515
  }
482
516
  function persistedInspectEventsToTraceEvents(events, options) {
@@ -711,6 +745,9 @@ function validateEvent(event) {
711
745
  case "step_completed": {
712
746
  return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
713
747
  }
748
+ case "outcome_observed": {
749
+ return nonEmptyString(event.runId) && nonEmptyString(event.outcomeId) && nonEmptyString(event.name) && nonEmptyString(event.expectation) && (event.status === "passed" || event.status === "failed" || event.status === "unknown" || event.status === "skipped") && finiteNumber(event.observedAt);
750
+ }
714
751
  default:
715
752
  return false;
716
753
  }
@@ -730,6 +767,55 @@ async function readTraceEventsFromFile(filePath) {
730
767
 
731
768
  // packages/core/src/context.ts
732
769
  new async_hooks.AsyncLocalStorage();
770
+
771
+ // packages/core/src/outcomes/types.ts
772
+ var OBSERVED_OUTCOME_STATUSES = [
773
+ "passed",
774
+ "failed",
775
+ "unknown",
776
+ "skipped"
777
+ ];
778
+ var OUTCOME_LEGACY_EVENT = "outcome_observed";
779
+
780
+ // packages/core/src/outcomes/validate.ts
781
+ function parseObservedOutcomeStatus(value) {
782
+ const trimmed = value.trim().toLowerCase();
783
+ if (OBSERVED_OUTCOME_STATUSES.includes(trimmed)) {
784
+ return trimmed;
785
+ }
786
+ throw new Error(
787
+ `Unsupported observation status "${value}". Use passed, failed, unknown, or skipped.`
788
+ );
789
+ }
790
+
791
+ // packages/core/src/outcomes/extract.ts
792
+ function fromOutcomeObservedEvent(event) {
793
+ return {
794
+ outcomeId: event.outcomeId,
795
+ runId: event.runId,
796
+ ...event.parentId !== void 0 ? { parentId: event.parentId } : {},
797
+ name: event.name,
798
+ expectation: event.expectation,
799
+ status: event.status,
800
+ ...event.method !== void 0 ? { method: event.method } : {},
801
+ ...event.actual !== void 0 ? { actual: event.actual } : {},
802
+ ...event.evidence !== void 0 ? { evidence: event.evidence } : {},
803
+ observedAt: event.observedAt
804
+ };
805
+ }
806
+ function extractOutcomesFromTraceEvents(events) {
807
+ const out = [];
808
+ for (const event of events) {
809
+ if (event.event === OUTCOME_LEGACY_EVENT) {
810
+ out.push(fromOutcomeObservedEvent(event));
811
+ }
812
+ }
813
+ return out.sort((a, b) => a.observedAt - b.observedAt || a.name.localeCompare(b.name));
814
+ }
815
+ function parseObservationFilter(value) {
816
+ if (value === void 0 || value.trim() === "") return void 0;
817
+ return parseObservedOutcomeStatus(value);
818
+ }
733
819
  function resolveTraceDir(options = {}) {
734
820
  if (typeof options.dir === "string" && options.dir.trim() !== "") {
735
821
  return options.dir.trim();
@@ -1077,8 +1163,9 @@ async function searchTraces(metas, options) {
1077
1163
  }
1078
1164
  const limit = options.limit;
1079
1165
  const sessionId = options.session?.trim();
1166
+ const observationStatus = parseObservationFilter(options.observation);
1080
1167
  const hasContentFilter = Boolean(
1081
- options.status || stepTypeFilter || nameQuery || toolQuery || durationFilter
1168
+ options.status || stepTypeFilter || nameQuery || toolQuery || durationFilter || observationStatus
1082
1169
  );
1083
1170
  const results = [];
1084
1171
  const sessionLabel = sessionId && sessionId !== "" ? sessionId : void 0;
@@ -1123,6 +1210,22 @@ async function searchTraces(metas, options) {
1123
1210
  statusFilter: options.status
1124
1211
  });
1125
1212
  results.push(...stepMatches);
1213
+ if (observationStatus) {
1214
+ const outcomes = extractOutcomesFromTraceEvents(events);
1215
+ const matched = outcomes.filter((outcome) => outcome.status === observationStatus);
1216
+ for (const outcome of matched) {
1217
+ results.push({
1218
+ runId: m.runId,
1219
+ runName: m.name,
1220
+ runStatus: m.status,
1221
+ stepName: outcome.name,
1222
+ timestamp: outcome.observedAt,
1223
+ matchReason: `observation status=${outcome.status}`,
1224
+ matchedFields: ["outcome.status", "outcome.name"],
1225
+ filePath: m.filePath
1226
+ });
1227
+ }
1228
+ }
1126
1229
  }
1127
1230
  results.sort((a, b) => {
1128
1231
  const ta = a.timestamp ?? 0;
@@ -1429,7 +1532,7 @@ function summarize(findings, diagnostics) {
1429
1532
  errors: diagnostics.filter((item) => item.severity === "error").length
1430
1533
  };
1431
1534
  }
1432
- function eventEvidence(event, path7) {
1535
+ function eventEvidence(event, path8) {
1433
1536
  return {
1434
1537
  runId: event.runId,
1435
1538
  eventId: event.eventId,
@@ -1767,13 +1870,13 @@ function pairSteps(left, right) {
1767
1870
  return pairs;
1768
1871
  }
1769
1872
  function compareLeafSteps(L, R, segments, opts, out) {
1770
- const path7 = buildPath(segments);
1873
+ const path8 = buildPath(segments);
1771
1874
  if (L.name !== R.name) {
1772
1875
  out.push({
1773
1876
  kind: "structure",
1774
1877
  severity: "warning",
1775
1878
  message: "Step name differs",
1776
- path: path7,
1879
+ path: path8,
1777
1880
  left: L.name,
1778
1881
  right: R.name
1779
1882
  });
@@ -1783,7 +1886,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1783
1886
  kind: "step-type",
1784
1887
  severity: "warning",
1785
1888
  message: "Step type differs",
1786
- path: path7,
1889
+ path: path8,
1787
1890
  left: L.type,
1788
1891
  right: R.type
1789
1892
  });
@@ -1793,7 +1896,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1793
1896
  kind: "step-status",
1794
1897
  severity: "warning",
1795
1898
  message: "Step status differs",
1796
- path: path7,
1899
+ path: path8,
1797
1900
  left: L.status,
1798
1901
  right: R.status
1799
1902
  });
@@ -1805,7 +1908,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1805
1908
  kind: "error",
1806
1909
  severity: "error",
1807
1910
  message: "Step error message differs",
1808
- path: path7,
1911
+ path: path8,
1809
1912
  left: le || void 0,
1810
1913
  right: re || void 0
1811
1914
  });
@@ -1823,7 +1926,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1823
1926
  kind: "duration",
1824
1927
  severity: "info",
1825
1928
  message: "Step duration differs",
1826
- path: path7,
1929
+ path: path8,
1827
1930
  left: ld,
1828
1931
  right: rd
1829
1932
  });
@@ -1836,7 +1939,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1836
1939
  kind: "metadata",
1837
1940
  severity: "info",
1838
1941
  message: "Step metadata differs",
1839
- path: path7,
1942
+ path: path8,
1840
1943
  left: L.metadata,
1841
1944
  right: R.metadata
1842
1945
  });
@@ -1848,7 +1951,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
1848
1951
  kind: "output",
1849
1952
  severity: "info",
1850
1953
  message: "Output preview differs",
1851
- path: path7,
1954
+ path: path8,
1852
1955
  left: L.outputPreview,
1853
1956
  right: R.outputPreview
1854
1957
  });
@@ -2145,6 +2248,8 @@ function nodeIdForEvent(event) {
2145
2248
  case "step_started":
2146
2249
  case "step_completed":
2147
2250
  return event.stepId;
2251
+ case "outcome_observed":
2252
+ return event.outcomeId;
2148
2253
  default:
2149
2254
  return "unknown";
2150
2255
  }
@@ -2328,6 +2433,39 @@ function traceEventToPersistedInspectEvent(event, options) {
2328
2433
  error
2329
2434
  };
2330
2435
  }
2436
+ case "outcome_observed": {
2437
+ const tsObserved = toIsoTimestamp(event.observedAt);
2438
+ const attributes = compactAttributes2({
2439
+ legacyEvent: "outcome_observed",
2440
+ outcomeId: event.outcomeId,
2441
+ outcomeStatus: event.status,
2442
+ expectation: event.expectation,
2443
+ method: event.method,
2444
+ actual: event.actual,
2445
+ evidence: event.evidence,
2446
+ observedAt: tsObserved.iso,
2447
+ invalidTimestamp: tsMain.invalidTimestamp || tsObserved.invalidTimestamp ? true : void 0
2448
+ });
2449
+ const out = {
2450
+ schemaVersion: "0.2",
2451
+ eventId,
2452
+ runId: event.runId,
2453
+ kind: "OUTCOME",
2454
+ name: event.name,
2455
+ status: event.status === "failed" ? "error" : "ok",
2456
+ timestamp: tsMain.iso,
2457
+ confidence: "explicit",
2458
+ source,
2459
+ attributes
2460
+ };
2461
+ if (event.parentId !== void 0) {
2462
+ out.parentId = event.parentId;
2463
+ }
2464
+ if (event.actual !== void 0) {
2465
+ out.outputSummary = event.actual;
2466
+ }
2467
+ return out;
2468
+ }
2331
2469
  default: {
2332
2470
  const _exhaustive = event;
2333
2471
  throw new Error(`Unsupported trace event: ${_exhaustive.event}`);
@@ -3057,7 +3195,7 @@ function sanitizeOpenInferenceAttributes(attributes, pathPrefix) {
3057
3195
  function mapOpenInferenceKind(span, attributes, pathPrefix) {
3058
3196
  const warnings = [];
3059
3197
  const agentInspectKind = attributes["agent_inspect.kind"];
3060
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
3198
+ 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") {
3061
3199
  return { kind: agentInspectKind, warnings };
3062
3200
  }
3063
3201
  const rawKind = readStringField(span, ["kind", "span_kind", "spanKind"]) ?? (typeof attributes["openinference.span.kind"] === "string" ? attributes["openinference.span.kind"] : void 0);
@@ -3578,7 +3716,7 @@ function mapOtlpStatus(status) {
3578
3716
  function readOtlpKind(attributes, pathPrefix) {
3579
3717
  const warnings = [];
3580
3718
  const agentInspectKind = attributes["agent_inspect.kind"];
3581
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
3719
+ 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") {
3582
3720
  return { kind: agentInspectKind, warnings };
3583
3721
  }
3584
3722
  const operation = attributes["gen_ai.operation.name"];