@agent-inspect/mcp-server 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.
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;
@@ -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"];