@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 +186 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +185 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var http = require('http');
|
|
4
|
-
var
|
|
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
|
|
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 =
|
|
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
|
|
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 ?
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
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,
|
|
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) =>
|
|
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:
|
|
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:
|
|
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:
|
|
4015
|
+
traceDir: path7__default.default.resolve(traceDir),
|
|
3852
4016
|
url: `http://${host}:${resolvedPort}`
|
|
3853
4017
|
});
|
|
3854
4018
|
});
|