@agent-inspect/viewer 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
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var http = require('http');
4
- var path6 = require('path');
4
+ var path7 = require('path');
5
5
  var async_hooks = require('async_hooks');
6
6
  require('crypto');
7
7
  var promises = require('fs/promises');
@@ -13,7 +13,7 @@ require('readline');
13
13
 
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
16
- var path6__default = /*#__PURE__*/_interopDefault(path6);
16
+ var path7__default = /*#__PURE__*/_interopDefault(path7);
17
17
  var os__default = /*#__PURE__*/_interopDefault(os);
18
18
 
19
19
  // packages/viewer/src/server.ts
@@ -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) {
@@ -490,7 +524,7 @@ function persistedInspectEventsToTraceEvents(events, options) {
490
524
  }
491
525
  var DEFAULT_TRACE_DIR_NAME = ".agent-inspect";
492
526
  var RUNS_DIR_NAME = "runs";
493
- var FALLBACK_TRACE_DIR = path6__default.default.join(
527
+ var FALLBACK_TRACE_DIR = path7__default.default.join(
494
528
  os__default.default.tmpdir(),
495
529
  "agent-inspect",
496
530
  RUNS_DIR_NAME
@@ -505,7 +539,7 @@ function getDefaultTraceDir() {
505
539
  if (typeof home !== "string" || home.trim() === "") {
506
540
  return FALLBACK_TRACE_DIR;
507
541
  }
508
- return path6__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
542
+ return path7__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
509
543
  } catch {
510
544
  return FALLBACK_TRACE_DIR;
511
545
  }
@@ -676,6 +710,9 @@ function validateEvent(event) {
676
710
  case "step_completed": {
677
711
  return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
678
712
  }
713
+ case "outcome_observed": {
714
+ 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);
715
+ }
679
716
  default:
680
717
  return false;
681
718
  }
@@ -711,7 +748,7 @@ var TraceDirectory = class {
711
748
  this.#dir = resolveTraceDir(options);
712
749
  }
713
750
  getPath(filename) {
714
- return filename ? path6__default.default.join(this.#dir, filename) : this.#dir;
751
+ return filename ? path7__default.default.join(this.#dir, filename) : this.#dir;
715
752
  }
716
753
  async list() {
717
754
  try {
@@ -738,7 +775,7 @@ function parseIsoToMs2(value) {
738
775
  }
739
776
  async function extractMetadata(filePath, _quickScan) {
740
777
  const stats = await promises.stat(filePath);
741
- let runIdFromFile = path6__default.default.basename(filePath);
778
+ let runIdFromFile = path7__default.default.basename(filePath);
742
779
  if (runIdFromFile.endsWith(".jsonl")) {
743
780
  runIdFromFile = runIdFromFile.slice(0, -".jsonl".length);
744
781
  }
@@ -1348,12 +1385,12 @@ function buildCriticalPath(runs, handoffs) {
1348
1385
  handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
1349
1386
  );
1350
1387
  const ordered = [...runs].sort(compareRuns);
1351
- const path7 = [];
1388
+ const path8 = [];
1352
1389
  const visited = /* @__PURE__ */ new Set();
1353
1390
  const pushRun = (run, confidence, source) => {
1354
1391
  if (visited.has(run.runId)) return;
1355
1392
  visited.add(run.runId);
1356
- path7.push({
1393
+ path8.push({
1357
1394
  runId: run.runId,
1358
1395
  name: run.name,
1359
1396
  startedAt: run.startedAt,
@@ -1378,7 +1415,7 @@ function buildCriticalPath(runs, handoffs) {
1378
1415
  const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
1379
1416
  pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
1380
1417
  }
1381
- return path7;
1418
+ return path8;
1382
1419
  }
1383
1420
  function metaRunIdMatches(run, token, runById) {
1384
1421
  const meta = extractSessionWorkflowMetadata(run.metadata);
@@ -1651,7 +1688,7 @@ function summarize(findings, diagnostics) {
1651
1688
  errors: diagnostics.filter((item) => item.severity === "error").length
1652
1689
  };
1653
1690
  }
1654
- function eventEvidence(event, path7) {
1691
+ function eventEvidence(event, path8) {
1655
1692
  return {
1656
1693
  runId: event.runId,
1657
1694
  eventId: event.eventId,
@@ -1800,6 +1837,8 @@ function nodeIdForEvent(event) {
1800
1837
  case "step_started":
1801
1838
  case "step_completed":
1802
1839
  return event.stepId;
1840
+ case "outcome_observed":
1841
+ return event.outcomeId;
1803
1842
  default:
1804
1843
  return "unknown";
1805
1844
  }
@@ -1983,6 +2022,39 @@ function traceEventToPersistedInspectEvent(event, options) {
1983
2022
  error
1984
2023
  };
1985
2024
  }
2025
+ case "outcome_observed": {
2026
+ const tsObserved = toIsoTimestamp(event.observedAt);
2027
+ const attributes = compactAttributes({
2028
+ legacyEvent: "outcome_observed",
2029
+ outcomeId: event.outcomeId,
2030
+ outcomeStatus: event.status,
2031
+ expectation: event.expectation,
2032
+ method: event.method,
2033
+ actual: event.actual,
2034
+ evidence: event.evidence,
2035
+ observedAt: tsObserved.iso,
2036
+ invalidTimestamp: tsMain.invalidTimestamp || tsObserved.invalidTimestamp ? true : void 0
2037
+ });
2038
+ const out = {
2039
+ schemaVersion: "0.2",
2040
+ eventId,
2041
+ runId: event.runId,
2042
+ kind: "OUTCOME",
2043
+ name: event.name,
2044
+ status: event.status === "failed" ? "error" : "ok",
2045
+ timestamp: tsMain.iso,
2046
+ confidence: "explicit",
2047
+ source,
2048
+ attributes
2049
+ };
2050
+ if (event.parentId !== void 0) {
2051
+ out.parentId = event.parentId;
2052
+ }
2053
+ if (event.actual !== void 0) {
2054
+ out.outputSummary = event.actual;
2055
+ }
2056
+ return out;
2057
+ }
1986
2058
  default: {
1987
2059
  const _exhaustive = event;
1988
2060
  throw new Error(`Unsupported trace event: ${_exhaustive.event}`);
@@ -2342,7 +2414,7 @@ function findReaderByFormat(format, readers) {
2342
2414
  }
2343
2415
  async function jsonlFilesInDirectory(dirPath) {
2344
2416
  const entries = await promises.readdir(dirPath, { withFileTypes: true });
2345
- return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path6__default.default.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
2417
+ return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path7__default.default.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
2346
2418
  }
2347
2419
  async function resolveInput(input) {
2348
2420
  const cached = resolvedInputCache.get(input);
@@ -2712,7 +2784,7 @@ function sanitizeOpenInferenceAttributes(attributes, pathPrefix) {
2712
2784
  function mapOpenInferenceKind(span, attributes, pathPrefix) {
2713
2785
  const warnings = [];
2714
2786
  const agentInspectKind = attributes["agent_inspect.kind"];
2715
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
2787
+ 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") {
2716
2788
  return { kind: agentInspectKind, warnings };
2717
2789
  }
2718
2790
  const rawKind = readStringField(span, ["kind", "span_kind", "spanKind"]) ?? (typeof attributes["openinference.span.kind"] === "string" ? attributes["openinference.span.kind"] : void 0);
@@ -3233,7 +3305,7 @@ function mapOtlpStatus(status) {
3233
3305
  function readOtlpKind(attributes, pathPrefix) {
3234
3306
  const warnings = [];
3235
3307
  const agentInspectKind = attributes["agent_inspect.kind"];
3236
- if (agentInspectKind === "RUN" || agentInspectKind === "AGENT" || agentInspectKind === "LLM" || agentInspectKind === "TOOL" || agentInspectKind === "CHAIN" || agentInspectKind === "RETRIEVER" || agentInspectKind === "DECISION" || agentInspectKind === "RESULT" || agentInspectKind === "ERROR" || agentInspectKind === "LOGIC" || agentInspectKind === "LOG") {
3308
+ 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") {
3237
3309
  return { kind: agentInspectKind, warnings };
3238
3310
  }
3239
3311
  const operation = attributes["gen_ai.operation.name"];
@@ -3879,7 +3951,7 @@ function createViewerServer(options = {}) {
3879
3951
  return sendJson(res, 200, {
3880
3952
  ok: true,
3881
3953
  readOnly: true,
3882
- traceDir: path6__default.default.resolve(traceDir)
3954
+ traceDir: path7__default.default.resolve(traceDir)
3883
3955
  });
3884
3956
  }
3885
3957
  const td = new TraceDirectory({ dir: traceDir });
@@ -3897,7 +3969,7 @@ function createViewerServer(options = {}) {
3897
3969
  runId: meta.runId,
3898
3970
  name: meta.name,
3899
3971
  status: meta.status,
3900
- file: path6__default.default.basename(meta.filePath),
3972
+ file: path7__default.default.basename(meta.filePath),
3901
3973
  startedAt: meta.startedAt,
3902
3974
  durationMs: meta.durationMs
3903
3975
  }))
@@ -4012,7 +4084,7 @@ function startViewerServer(options = {}) {
4012
4084
  resolve({
4013
4085
  host,
4014
4086
  port: resolvedPort,
4015
- traceDir: path6__default.default.resolve(traceDir),
4087
+ traceDir: path7__default.default.resolve(traceDir),
4016
4088
  url: `http://${host}:${resolvedPort}`
4017
4089
  });
4018
4090
  });