@agent-inspect/viewer 4.1.0 → 4.3.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
@@ -490,7 +490,7 @@ function persistedInspectEventsToTraceEvents(events, options) {
490
490
  }
491
491
  var DEFAULT_TRACE_DIR_NAME = ".agent-inspect";
492
492
  var RUNS_DIR_NAME = "runs";
493
- var FALLBACK_TRACE_DIR = path6__default.default.join(
493
+ var FALLBACK_TRACE_DIR = path7__default.default.join(
494
494
  os__default.default.tmpdir(),
495
495
  "agent-inspect",
496
496
  RUNS_DIR_NAME
@@ -505,7 +505,7 @@ function getDefaultTraceDir() {
505
505
  if (typeof home !== "string" || home.trim() === "") {
506
506
  return FALLBACK_TRACE_DIR;
507
507
  }
508
- return path6__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
508
+ return path7__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
509
509
  } catch {
510
510
  return FALLBACK_TRACE_DIR;
511
511
  }
@@ -711,7 +711,7 @@ var TraceDirectory = class {
711
711
  this.#dir = resolveTraceDir(options);
712
712
  }
713
713
  getPath(filename) {
714
- return filename ? path6__default.default.join(this.#dir, filename) : this.#dir;
714
+ return filename ? path7__default.default.join(this.#dir, filename) : this.#dir;
715
715
  }
716
716
  async list() {
717
717
  try {
@@ -738,7 +738,7 @@ function parseIsoToMs2(value) {
738
738
  }
739
739
  async function extractMetadata(filePath, _quickScan) {
740
740
  const stats = await promises.stat(filePath);
741
- let runIdFromFile = path6__default.default.basename(filePath);
741
+ let runIdFromFile = path7__default.default.basename(filePath);
742
742
  if (runIdFromFile.endsWith(".jsonl")) {
743
743
  runIdFromFile = runIdFromFile.slice(0, -".jsonl".length);
744
744
  }
@@ -1031,6 +1031,163 @@ function sessionKeyForRun(meta, options) {
1031
1031
  return void 0;
1032
1032
  }
1033
1033
 
1034
+ // packages/core/src/sessions/status.ts
1035
+ var DEFAULT_STALE_THRESHOLD_MS = 864e5;
1036
+ var EXPLICIT_STATUS_PRIORITY = {
1037
+ error: 5,
1038
+ waiting_input: 4,
1039
+ idle: 3,
1040
+ stale: 2,
1041
+ completed: 1
1042
+ };
1043
+ var EXPLICIT_SESSION_STATUSES = /* @__PURE__ */ new Set([
1044
+ "running",
1045
+ "waiting_input",
1046
+ "idle",
1047
+ "completed",
1048
+ "error",
1049
+ "stale",
1050
+ "unknown"
1051
+ ]);
1052
+ function isExplicitSessionStatus(value) {
1053
+ return typeof value === "string" && EXPLICIT_SESSION_STATUSES.has(value);
1054
+ }
1055
+ function activityMs(run) {
1056
+ return run.endedAt ?? run.startedAt ?? 0;
1057
+ }
1058
+ function latestActivityMs(runs) {
1059
+ let latest = 0;
1060
+ for (const run of runs) {
1061
+ const ms = activityMs(run);
1062
+ if (ms > latest) latest = ms;
1063
+ }
1064
+ return latest;
1065
+ }
1066
+ function earliestStart(runs) {
1067
+ let earliest;
1068
+ for (const run of runs) {
1069
+ if (run.startedAt === void 0) continue;
1070
+ if (earliest === void 0 || run.startedAt < earliest) {
1071
+ earliest = run.startedAt;
1072
+ }
1073
+ }
1074
+ return earliest;
1075
+ }
1076
+ function latestEndWhenAllEnded(runs) {
1077
+ if (runs.length === 0) return void 0;
1078
+ let latest;
1079
+ for (const run of runs) {
1080
+ if (run.endedAt === void 0) return void 0;
1081
+ if (latest === void 0 || run.endedAt > latest) latest = run.endedAt;
1082
+ }
1083
+ return latest;
1084
+ }
1085
+ function pickExplicitStatus(runs) {
1086
+ let best;
1087
+ let bestPriority = 0;
1088
+ for (const run of runs) {
1089
+ const raw = run.metadata?.sessionStatus;
1090
+ if (!isExplicitSessionStatus(raw)) continue;
1091
+ const priority = EXPLICIT_STATUS_PRIORITY[raw] ?? 0;
1092
+ if (priority > bestPriority) {
1093
+ bestPriority = priority;
1094
+ best = raw;
1095
+ }
1096
+ }
1097
+ return best;
1098
+ }
1099
+ function deriveLastError(runs) {
1100
+ const errorRuns = runs.filter((run) => run.status === "error").sort((a, b) => activityMs(b) - activityMs(a));
1101
+ const latest = errorRuns[0];
1102
+ if (!latest) return void 0;
1103
+ const meta = latest.metadata ?? {};
1104
+ const message = typeof meta.errorMessage === "string" && meta.errorMessage.trim() !== "" ? meta.errorMessage.trim() : latest.name ?? latest.runId;
1105
+ const code = typeof meta.errorCode === "string" && meta.errorCode.trim() !== "" ? meta.errorCode.trim() : void 0;
1106
+ return { runId: latest.runId, message, code };
1107
+ }
1108
+ function deriveCheckSummary(runs) {
1109
+ let pass = 0;
1110
+ let fail = 0;
1111
+ let warn2 = 0;
1112
+ let found = false;
1113
+ for (const run of runs) {
1114
+ const summary = run.metadata?.checkSummary;
1115
+ if (!summary || typeof summary !== "object") continue;
1116
+ const record = summary;
1117
+ if (typeof record.pass === "number") {
1118
+ pass += record.pass;
1119
+ found = true;
1120
+ }
1121
+ if (typeof record.fail === "number") {
1122
+ fail += record.fail;
1123
+ found = true;
1124
+ }
1125
+ if (typeof record.warn === "number") {
1126
+ warn2 += record.warn;
1127
+ found = true;
1128
+ }
1129
+ }
1130
+ return found ? { pass, fail, warn: warn2 } : void 0;
1131
+ }
1132
+ function deriveObservationSummary(runs) {
1133
+ for (const run of [...runs].sort((a, b) => activityMs(b) - activityMs(a))) {
1134
+ const value = run.metadata?.observationSummary;
1135
+ if (typeof value === "string" && value.trim() !== "") {
1136
+ return value.trim();
1137
+ }
1138
+ }
1139
+ return void 0;
1140
+ }
1141
+ function deriveSessionStatus(runs, options = {}) {
1142
+ if (runs.length === 0) return "unknown";
1143
+ if (runs.some((run) => run.status === "running")) return "running";
1144
+ const explicit = pickExplicitStatus(runs);
1145
+ if (explicit && explicit !== "running") return explicit;
1146
+ if (runs.some((run) => run.status === "error")) return "error";
1147
+ if (runs.every((run) => run.status === "success")) return "completed";
1148
+ const nowMs = options.nowMs ?? Date.now();
1149
+ const staleThresholdMs = options.staleThresholdMs ?? DEFAULT_STALE_THRESHOLD_MS;
1150
+ const lastMs = latestActivityMs(runs);
1151
+ if (lastMs > 0 && nowMs - lastMs > staleThresholdMs) return "stale";
1152
+ return "unknown";
1153
+ }
1154
+ function enrichSessionSummary(summary, runs, options = {}) {
1155
+ const sessionRuns = runs.filter((run) => summary.runIds.includes(run.runId)).sort((a, b) => a.runId.localeCompare(b.runId));
1156
+ const startedAt = earliestStart(sessionRuns);
1157
+ const endedAt = latestEndWhenAllEnded(sessionRuns);
1158
+ const durationMs = startedAt !== void 0 && endedAt !== void 0 ? endedAt - startedAt : void 0;
1159
+ let correlationId;
1160
+ let jobId;
1161
+ let workflowId;
1162
+ for (const run of sessionRuns) {
1163
+ const meta = extractSessionWorkflowMetadata(run.metadata);
1164
+ if (!correlationId && meta?.correlationId) correlationId = meta.correlationId;
1165
+ if (!jobId && meta?.jobId) jobId = meta.jobId;
1166
+ if (!workflowId && meta?.workflowName) workflowId = meta.workflowName;
1167
+ else if (!workflowId && meta?.workflowStep) workflowId = meta.workflowStep;
1168
+ }
1169
+ const lastMs = latestActivityMs(sessionRuns);
1170
+ const lastActivity = lastMs > 0 ? new Date(lastMs).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
1171
+ const retryCount = summary.retries.filter(
1172
+ (retry) => retry.retryOf !== void 0 || (retry.attempt ?? 0) > 1
1173
+ ).length;
1174
+ return {
1175
+ ...summary,
1176
+ status: deriveSessionStatus(sessionRuns, options),
1177
+ startedAt,
1178
+ endedAt,
1179
+ durationMs,
1180
+ correlationId,
1181
+ jobId,
1182
+ workflowId,
1183
+ lastError: deriveLastError(sessionRuns),
1184
+ lastActivity,
1185
+ retryCount,
1186
+ observationSummary: deriveObservationSummary(sessionRuns),
1187
+ checkSummary: deriveCheckSummary(sessionRuns)
1188
+ };
1189
+ }
1190
+
1034
1191
  // packages/core/src/sessions/load.ts
1035
1192
  async function enrichSessionRunRecord(meta) {
1036
1193
  let metadata;
@@ -1191,12 +1348,12 @@ function buildCriticalPath(runs, handoffs) {
1191
1348
  handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
1192
1349
  );
1193
1350
  const ordered = [...runs].sort(compareRuns);
1194
- const path7 = [];
1351
+ const path8 = [];
1195
1352
  const visited = /* @__PURE__ */ new Set();
1196
1353
  const pushRun = (run, confidence, source) => {
1197
1354
  if (visited.has(run.runId)) return;
1198
1355
  visited.add(run.runId);
1199
- path7.push({
1356
+ path8.push({
1200
1357
  runId: run.runId,
1201
1358
  name: run.name,
1202
1359
  startedAt: run.startedAt,
@@ -1221,7 +1378,7 @@ function buildCriticalPath(runs, handoffs) {
1221
1378
  const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
1222
1379
  pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
1223
1380
  }
1224
- return path7;
1381
+ return path8;
1225
1382
  }
1226
1383
  function metaRunIdMatches(run, token, runById) {
1227
1384
  const meta = extractSessionWorkflowMetadata(run.metadata);
@@ -1263,14 +1420,21 @@ function buildSessionIndex(inputRuns, options = {}) {
1263
1420
  sessionId
1264
1421
  });
1265
1422
  }
1266
- return {
1267
- sessionId,
1268
- runIds,
1269
- groups,
1270
- handoffs,
1271
- retries,
1272
- criticalPath
1273
- };
1423
+ return enrichSessionSummary(
1424
+ {
1425
+ sessionId,
1426
+ runIds,
1427
+ groups,
1428
+ handoffs,
1429
+ retries,
1430
+ criticalPath
1431
+ },
1432
+ runs,
1433
+ {
1434
+ nowMs: options.nowMs,
1435
+ staleThresholdMs: options.staleThresholdMs
1436
+ }
1437
+ );
1274
1438
  });
1275
1439
  if (sessions.length === 0 && runs.length > 0) {
1276
1440
  warnings.push({
@@ -1487,7 +1651,7 @@ function summarize(findings, diagnostics) {
1487
1651
  errors: diagnostics.filter((item) => item.severity === "error").length
1488
1652
  };
1489
1653
  }
1490
- function eventEvidence(event, path7) {
1654
+ function eventEvidence(event, path8) {
1491
1655
  return {
1492
1656
  runId: event.runId,
1493
1657
  eventId: event.eventId,
@@ -2178,7 +2342,7 @@ function findReaderByFormat(format, readers) {
2178
2342
  }
2179
2343
  async function jsonlFilesInDirectory(dirPath) {
2180
2344
  const entries = await promises.readdir(dirPath, { withFileTypes: true });
2181
- 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));
2345
+ 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));
2182
2346
  }
2183
2347
  async function resolveInput(input) {
2184
2348
  const cached = resolvedInputCache.get(input);
@@ -3715,7 +3879,7 @@ function createViewerServer(options = {}) {
3715
3879
  return sendJson(res, 200, {
3716
3880
  ok: true,
3717
3881
  readOnly: true,
3718
- traceDir: path6__default.default.resolve(traceDir)
3882
+ traceDir: path7__default.default.resolve(traceDir)
3719
3883
  });
3720
3884
  }
3721
3885
  const td = new TraceDirectory({ dir: traceDir });
@@ -3733,7 +3897,7 @@ function createViewerServer(options = {}) {
3733
3897
  runId: meta.runId,
3734
3898
  name: meta.name,
3735
3899
  status: meta.status,
3736
- file: path6__default.default.basename(meta.filePath),
3900
+ file: path7__default.default.basename(meta.filePath),
3737
3901
  startedAt: meta.startedAt,
3738
3902
  durationMs: meta.durationMs
3739
3903
  }))
@@ -3848,7 +4012,7 @@ function startViewerServer(options = {}) {
3848
4012
  resolve({
3849
4013
  host,
3850
4014
  port: resolvedPort,
3851
- traceDir: path6__default.default.resolve(traceDir),
4015
+ traceDir: path7__default.default.resolve(traceDir),
3852
4016
  url: `http://${host}:${resolvedPort}`
3853
4017
  });
3854
4018
  });