agent-inspect 1.3.0 → 1.5.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/CHANGELOG.md +47 -4
- package/README.md +59 -37
- package/docs/ADAPTERS.md +117 -31
- package/docs/API.md +24 -6
- package/docs/CLI.md +126 -1
- package/docs/DIFF.md +8 -0
- package/docs/EXPORTS.md +86 -15
- package/docs/GETTING-STARTED.md +48 -2
- package/docs/KNOWN-ISSUES.md +6 -0
- package/docs/LIMITATIONS.md +11 -3
- package/docs/LOGS.md +22 -0
- package/docs/SCHEMA.md +8 -5
- package/docs/SCREENSHOTS.md +190 -9
- package/package.json +51 -1
- package/packages/cli/dist/index.cjs +3253 -1662
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +3253 -1662
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/core/dist/advanced.cjs +1437 -0
- package/packages/core/dist/advanced.cjs.map +1 -0
- package/packages/core/dist/advanced.d.cts +159 -0
- package/packages/core/dist/advanced.d.ts +159 -0
- package/packages/core/dist/advanced.mjs +8 -0
- package/packages/core/dist/advanced.mjs.map +1 -0
- package/packages/core/dist/chunk-5EMIZZXD.mjs +907 -0
- package/packages/core/dist/chunk-5EMIZZXD.mjs.map +1 -0
- package/packages/core/dist/chunk-7TGZLWEE.mjs +35 -0
- package/packages/core/dist/chunk-7TGZLWEE.mjs.map +1 -0
- package/packages/core/dist/chunk-BT7CATSD.mjs +497 -0
- package/packages/core/dist/chunk-BT7CATSD.mjs.map +1 -0
- package/packages/core/dist/chunk-E5F2LQCX.mjs +83 -0
- package/packages/core/dist/chunk-E5F2LQCX.mjs.map +1 -0
- package/packages/core/dist/chunk-EDTQHZPM.mjs +88 -0
- package/packages/core/dist/chunk-EDTQHZPM.mjs.map +1 -0
- package/packages/core/dist/chunk-HY7H3CQM.mjs +127 -0
- package/packages/core/dist/chunk-HY7H3CQM.mjs.map +1 -0
- package/packages/core/dist/chunk-Q6EPNB3V.mjs +539 -0
- package/packages/core/dist/chunk-Q6EPNB3V.mjs.map +1 -0
- package/packages/core/dist/chunk-QPAU2TPA.mjs +785 -0
- package/packages/core/dist/chunk-QPAU2TPA.mjs.map +1 -0
- package/packages/core/dist/chunk-QX3ZMPUF.mjs +451 -0
- package/packages/core/dist/chunk-QX3ZMPUF.mjs.map +1 -0
- package/packages/core/dist/chunk-VU6O5QAH.mjs +99 -0
- package/packages/core/dist/chunk-VU6O5QAH.mjs.map +1 -0
- package/packages/core/dist/chunk-XDBND27A.mjs +975 -0
- package/packages/core/dist/chunk-XDBND27A.mjs.map +1 -0
- package/packages/core/dist/chunk-YWAOOXLR.mjs +475 -0
- package/packages/core/dist/chunk-YWAOOXLR.mjs.map +1 -0
- package/packages/core/dist/diff.cjs +993 -0
- package/packages/core/dist/diff.cjs.map +1 -0
- package/packages/core/dist/diff.d.cts +81 -0
- package/packages/core/dist/diff.d.ts +81 -0
- package/packages/core/dist/diff.mjs +5 -0
- package/packages/core/dist/diff.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +1228 -0
- package/packages/core/dist/exporters.cjs.map +1 -0
- package/packages/core/dist/exporters.d.cts +113 -0
- package/packages/core/dist/exporters.d.ts +113 -0
- package/packages/core/dist/exporters.mjs +6 -0
- package/packages/core/dist/exporters.mjs.map +1 -0
- package/packages/core/dist/index.cjs +2982 -1829
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.d.cts +201 -892
- package/packages/core/dist/index.d.ts +201 -892
- package/packages/core/dist/index.mjs +780 -4620
- package/packages/core/dist/index.mjs.map +1 -1
- package/packages/core/dist/log-config-BzGmDYum.d.cts +71 -0
- package/packages/core/dist/log-config-BzGmDYum.d.ts +71 -0
- package/packages/core/dist/logs.cjs +1007 -0
- package/packages/core/dist/logs.cjs.map +1 -0
- package/packages/core/dist/logs.d.cts +137 -0
- package/packages/core/dist/logs.d.ts +137 -0
- package/packages/core/dist/logs.mjs +6 -0
- package/packages/core/dist/logs.mjs.map +1 -0
- package/packages/core/dist/persisted.cjs +1057 -0
- package/packages/core/dist/persisted.cjs.map +1 -0
- package/packages/core/dist/persisted.d.cts +160 -0
- package/packages/core/dist/persisted.d.ts +160 -0
- package/packages/core/dist/persisted.mjs +5 -0
- package/packages/core/dist/persisted.mjs.map +1 -0
- package/packages/core/dist/types-Bkt7LS01.d.ts +226 -0
- package/packages/core/dist/types-CNbheSdk.d.cts +226 -0
|
@@ -0,0 +1,975 @@
|
|
|
1
|
+
import { isPersistedInspectEvent, persistedInspectEventsToTraceEvents, extractCorrelationMetadata } from './chunk-QX3ZMPUF.mjs';
|
|
2
|
+
import { nanoid } from './chunk-7TGZLWEE.mjs';
|
|
3
|
+
import { resolveRedactionProfile, applyProfileMetadataCaps } from './chunk-EDTQHZPM.mjs';
|
|
4
|
+
import { Redactor } from './chunk-VU6O5QAH.mjs';
|
|
5
|
+
import { source_default } from './chunk-BT7CATSD.mjs';
|
|
6
|
+
import { mkdir, writeFile, readFile, readdir, stat, appendFile } from 'fs/promises';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
10
|
+
|
|
11
|
+
// packages/core/src/types.ts
|
|
12
|
+
var STEP_TYPES = [
|
|
13
|
+
"run",
|
|
14
|
+
"llm",
|
|
15
|
+
"tool",
|
|
16
|
+
"decision",
|
|
17
|
+
"logic",
|
|
18
|
+
"state",
|
|
19
|
+
"custom"
|
|
20
|
+
];
|
|
21
|
+
var STEP_STATUSES = [
|
|
22
|
+
"running",
|
|
23
|
+
"success",
|
|
24
|
+
"error"
|
|
25
|
+
];
|
|
26
|
+
function isRecord(value) {
|
|
27
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28
|
+
}
|
|
29
|
+
function isStepType(value) {
|
|
30
|
+
return typeof value === "string" && STEP_TYPES.includes(value);
|
|
31
|
+
}
|
|
32
|
+
function isStepStatus(value) {
|
|
33
|
+
return typeof value === "string" && STEP_STATUSES.includes(value);
|
|
34
|
+
}
|
|
35
|
+
function isTraceEvent(value) {
|
|
36
|
+
if (!isRecord(value)) return false;
|
|
37
|
+
if (value.schemaVersion !== "0.1") return false;
|
|
38
|
+
if (typeof value.timestamp !== "number") return false;
|
|
39
|
+
if (typeof value.event !== "string") return false;
|
|
40
|
+
switch (value.event) {
|
|
41
|
+
case "run_started": {
|
|
42
|
+
return typeof value.runId === "string" && typeof value.name === "string" && typeof value.startTime === "number";
|
|
43
|
+
}
|
|
44
|
+
case "run_completed": {
|
|
45
|
+
return typeof value.runId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
|
|
46
|
+
}
|
|
47
|
+
case "step_started": {
|
|
48
|
+
return typeof value.runId === "string" && typeof value.stepId === "string" && typeof value.name === "string" && isStepType(value.type) && typeof value.startTime === "number";
|
|
49
|
+
}
|
|
50
|
+
case "step_completed": {
|
|
51
|
+
return typeof value.runId === "string" && typeof value.stepId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// packages/core/src/utils/duration.ts
|
|
59
|
+
function parseDuration(duration) {
|
|
60
|
+
const raw = typeof duration === "string" ? duration.trim() : "";
|
|
61
|
+
const match = raw.match(/^(\d+)(ms|[smhd])$/);
|
|
62
|
+
if (!match) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const amount = Number.parseInt(match[1], 10);
|
|
68
|
+
const unit = match[2];
|
|
69
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Invalid duration amount: ${duration}. Amount must be a positive integer.`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
switch (unit) {
|
|
75
|
+
case "ms":
|
|
76
|
+
return amount;
|
|
77
|
+
case "s":
|
|
78
|
+
return amount * 1e3;
|
|
79
|
+
case "m":
|
|
80
|
+
return amount * 60 * 1e3;
|
|
81
|
+
case "h":
|
|
82
|
+
return amount * 60 * 60 * 1e3;
|
|
83
|
+
case "d":
|
|
84
|
+
return amount * 24 * 60 * 60 * 1e3;
|
|
85
|
+
default: {
|
|
86
|
+
throw new Error(`Unknown duration unit: ${unit}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function formatDuration(ms) {
|
|
91
|
+
if (!Number.isFinite(ms)) {
|
|
92
|
+
return "0ms";
|
|
93
|
+
}
|
|
94
|
+
if (ms < 0) {
|
|
95
|
+
throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);
|
|
96
|
+
}
|
|
97
|
+
if (ms < 1e3) {
|
|
98
|
+
return `${Math.floor(ms)}ms`;
|
|
99
|
+
}
|
|
100
|
+
if (ms < 6e4) {
|
|
101
|
+
return `${(ms / 1e3).toFixed(2)}s`;
|
|
102
|
+
}
|
|
103
|
+
if (ms < 36e5) {
|
|
104
|
+
return `${(ms / 6e4).toFixed(1)}m`;
|
|
105
|
+
}
|
|
106
|
+
return `${(ms / 36e5).toFixed(1)}h`;
|
|
107
|
+
}
|
|
108
|
+
var DEFAULT_TRACE_DIR_NAME = ".agent-inspect";
|
|
109
|
+
var RUNS_DIR_NAME = "runs";
|
|
110
|
+
var FALLBACK_TRACE_DIR = path.join(
|
|
111
|
+
os.tmpdir(),
|
|
112
|
+
"agent-inspect",
|
|
113
|
+
RUNS_DIR_NAME
|
|
114
|
+
);
|
|
115
|
+
var MAX_NAME_LENGTH = 100;
|
|
116
|
+
function createRunId() {
|
|
117
|
+
return `run_${nanoid(10)}`;
|
|
118
|
+
}
|
|
119
|
+
function createStepId() {
|
|
120
|
+
return `step_${nanoid(10)}`;
|
|
121
|
+
}
|
|
122
|
+
function formatDuration2(ms) {
|
|
123
|
+
return formatDuration(ms);
|
|
124
|
+
}
|
|
125
|
+
function formatTimestamp(timestamp) {
|
|
126
|
+
if (!Number.isFinite(timestamp)) {
|
|
127
|
+
return "Invalid date";
|
|
128
|
+
}
|
|
129
|
+
const d = new Date(timestamp);
|
|
130
|
+
if (Number.isNaN(d.getTime())) {
|
|
131
|
+
return "Invalid date";
|
|
132
|
+
}
|
|
133
|
+
const y = d.getFullYear();
|
|
134
|
+
const mo = String(d.getMonth() + 1).padStart(2, "0");
|
|
135
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
136
|
+
const h = String(d.getHours()).padStart(2, "0");
|
|
137
|
+
const min = String(d.getMinutes()).padStart(2, "0");
|
|
138
|
+
const s = String(d.getSeconds()).padStart(2, "0");
|
|
139
|
+
return `${y}-${mo}-${day} ${h}:${min}:${s}`;
|
|
140
|
+
}
|
|
141
|
+
function getDefaultTraceDir() {
|
|
142
|
+
const envDir = process.env.AGENT_INSPECT_TRACE_DIR;
|
|
143
|
+
if (typeof envDir === "string" && envDir.trim() !== "") {
|
|
144
|
+
return envDir.trim();
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const home = os.homedir();
|
|
148
|
+
if (typeof home !== "string" || home.trim() === "") {
|
|
149
|
+
return FALLBACK_TRACE_DIR;
|
|
150
|
+
}
|
|
151
|
+
return path.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
|
|
152
|
+
} catch {
|
|
153
|
+
return FALLBACK_TRACE_DIR;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function getTraceFilePath(runId, traceDir) {
|
|
157
|
+
const baseDir = traceDir ?? getDefaultTraceDir();
|
|
158
|
+
let safeId = typeof runId === "string" && runId.trim() !== "" ? runId.trim() : "run_unknown";
|
|
159
|
+
safeId = path.basename(safeId);
|
|
160
|
+
if (safeId === "" || safeId === "." || safeId === "..") {
|
|
161
|
+
safeId = "run_unknown";
|
|
162
|
+
}
|
|
163
|
+
return path.join(baseDir, `${safeId}.jsonl`);
|
|
164
|
+
}
|
|
165
|
+
async function ensureTraceDir(traceDir) {
|
|
166
|
+
const primary = path.resolve(traceDir);
|
|
167
|
+
try {
|
|
168
|
+
await mkdir(primary, { recursive: true });
|
|
169
|
+
return primary;
|
|
170
|
+
} catch {
|
|
171
|
+
warn(`Failed to create trace directory: ${primary}`);
|
|
172
|
+
const fallback = path.resolve(FALLBACK_TRACE_DIR);
|
|
173
|
+
try {
|
|
174
|
+
await mkdir(fallback, { recursive: true });
|
|
175
|
+
return fallback;
|
|
176
|
+
} catch {
|
|
177
|
+
warn(`Failed to create fallback trace directory: ${fallback}`);
|
|
178
|
+
return primary;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function formatError(error) {
|
|
183
|
+
if (error instanceof Error) {
|
|
184
|
+
const out = { message: error.message };
|
|
185
|
+
if (typeof error.stack === "string" && error.stack.length > 0) {
|
|
186
|
+
out.stack = error.stack;
|
|
187
|
+
}
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
if (typeof error === "string") {
|
|
191
|
+
return { message: error };
|
|
192
|
+
}
|
|
193
|
+
if (error === null) {
|
|
194
|
+
return { message: "Unknown error: null" };
|
|
195
|
+
}
|
|
196
|
+
if (error === void 0) {
|
|
197
|
+
return { message: "Unknown error: undefined" };
|
|
198
|
+
}
|
|
199
|
+
if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint") {
|
|
200
|
+
return { message: String(error) };
|
|
201
|
+
}
|
|
202
|
+
if (typeof error === "object") {
|
|
203
|
+
try {
|
|
204
|
+
return { message: JSON.stringify(error) };
|
|
205
|
+
} catch {
|
|
206
|
+
return { message: "Unknown error" };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { message: "Unknown error" };
|
|
210
|
+
}
|
|
211
|
+
function truncateName(name, maxLength = MAX_NAME_LENGTH) {
|
|
212
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
213
|
+
return "unnamed";
|
|
214
|
+
}
|
|
215
|
+
const trimmed = name.trim();
|
|
216
|
+
if (trimmed.length <= maxLength) {
|
|
217
|
+
return trimmed;
|
|
218
|
+
}
|
|
219
|
+
const ellipsis = "...";
|
|
220
|
+
const head = Math.max(0, maxLength - ellipsis.length);
|
|
221
|
+
return `${trimmed.slice(0, head)}${ellipsis}`;
|
|
222
|
+
}
|
|
223
|
+
function warn(message, error) {
|
|
224
|
+
const base = `[AgentInspect] ${message}`;
|
|
225
|
+
if (error === void 0) {
|
|
226
|
+
console.warn(base);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
console.warn(`${base}: ${formatError(error).message}`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// packages/core/src/read-trace.ts
|
|
233
|
+
function isRecord2(value) {
|
|
234
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
235
|
+
}
|
|
236
|
+
function detectLineFormat(parsed) {
|
|
237
|
+
if (!isRecord2(parsed)) return "unknown";
|
|
238
|
+
if (parsed.schemaVersion === "0.1") return "0.1";
|
|
239
|
+
if (parsed.schemaVersion === "0.2") return "0.2";
|
|
240
|
+
return "unknown";
|
|
241
|
+
}
|
|
242
|
+
function parseTraceJsonl(raw, options = {}) {
|
|
243
|
+
const validate = options.validate ?? isTraceEvent;
|
|
244
|
+
const persisted = [];
|
|
245
|
+
const traceEvents = [];
|
|
246
|
+
let saw01 = false;
|
|
247
|
+
let saw02 = false;
|
|
248
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
249
|
+
const trimmed = line.trim();
|
|
250
|
+
if (trimmed === "") continue;
|
|
251
|
+
let parsed;
|
|
252
|
+
try {
|
|
253
|
+
parsed = JSON.parse(trimmed);
|
|
254
|
+
} catch {
|
|
255
|
+
warn("Skipped invalid JSON line in trace file");
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const format2 = detectLineFormat(parsed);
|
|
259
|
+
if (format2 === "0.1") {
|
|
260
|
+
saw01 = true;
|
|
261
|
+
if (validate(parsed)) {
|
|
262
|
+
traceEvents.push(parsed);
|
|
263
|
+
} else {
|
|
264
|
+
warn("Skipped invalid trace event line in trace file");
|
|
265
|
+
}
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (format2 === "0.2") {
|
|
269
|
+
saw02 = true;
|
|
270
|
+
if (isPersistedInspectEvent(parsed)) {
|
|
271
|
+
persisted.push(parsed);
|
|
272
|
+
} else {
|
|
273
|
+
warn("Skipped invalid persisted inspect event line in trace file");
|
|
274
|
+
}
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
warn("Skipped trace line with unknown schemaVersion");
|
|
278
|
+
}
|
|
279
|
+
if (saw01 && saw02) {
|
|
280
|
+
warn("Trace file mixes schemaVersion 0.1 and 0.2 lines; normalizing all rows");
|
|
281
|
+
}
|
|
282
|
+
const converted = persisted.length > 0 ? persistedInspectEventsToTraceEvents(persisted) : [];
|
|
283
|
+
const events = [...traceEvents, ...converted];
|
|
284
|
+
let format = "empty";
|
|
285
|
+
if (saw01 && saw02) format = "mixed";
|
|
286
|
+
else if (saw01) format = "0.1";
|
|
287
|
+
else if (saw02) format = "0.2";
|
|
288
|
+
return { format, events, persisted };
|
|
289
|
+
}
|
|
290
|
+
function unknownTraceFormatMessage() {
|
|
291
|
+
return "Unsupported trace format. Expected schemaVersion 0.1 (TraceEvent) or 0.2 (PersistedInspectEvent).";
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// packages/core/src/trace-event-safety.ts
|
|
295
|
+
var DEFAULT_MAX_METADATA_VALUE_LENGTH = 2e3;
|
|
296
|
+
var DEFAULT_MAX_PREVIEW_LENGTH = 500;
|
|
297
|
+
var DEFAULT_MAX_EVENT_BYTES = 65536;
|
|
298
|
+
function isRecord3(value) {
|
|
299
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
300
|
+
}
|
|
301
|
+
function isPreviewKey(key) {
|
|
302
|
+
return key.toLowerCase().includes("preview");
|
|
303
|
+
}
|
|
304
|
+
function truncateString(value, maxLen) {
|
|
305
|
+
if (maxLen <= 0) return "\u2026";
|
|
306
|
+
if (value.length <= maxLen) return value;
|
|
307
|
+
return `${value.slice(0, maxLen)}\u2026`;
|
|
308
|
+
}
|
|
309
|
+
function byteLength(text) {
|
|
310
|
+
return Buffer.byteLength(text, "utf8");
|
|
311
|
+
}
|
|
312
|
+
function resolveTraceSafetyOptions(options) {
|
|
313
|
+
const redact = options?.redact;
|
|
314
|
+
let redactEnabled = true;
|
|
315
|
+
let redactionRules;
|
|
316
|
+
if (redact === false) {
|
|
317
|
+
redactEnabled = false;
|
|
318
|
+
} else if (redact === true || redact === void 0) {
|
|
319
|
+
redactEnabled = true;
|
|
320
|
+
} else if (isRecord3(redact)) {
|
|
321
|
+
redactEnabled = true;
|
|
322
|
+
redactionRules = redact.rules;
|
|
323
|
+
}
|
|
324
|
+
const profile = options?.redactionProfile ?? "local";
|
|
325
|
+
const resolvedProfile = resolveRedactionProfile(profile);
|
|
326
|
+
const userMaxMetadata = typeof options?.maxMetadataValueLength === "number" && Number.isFinite(options.maxMetadataValueLength) && options.maxMetadataValueLength >= 0 ? Math.floor(options.maxMetadataValueLength) : void 0;
|
|
327
|
+
const userMaxPreview = typeof options?.maxPreviewLength === "number" && Number.isFinite(options.maxPreviewLength) && options.maxPreviewLength >= 0 ? Math.floor(options.maxPreviewLength) : void 0;
|
|
328
|
+
let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;
|
|
329
|
+
let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;
|
|
330
|
+
if (redactEnabled && profile !== "local") {
|
|
331
|
+
const capped = applyProfileMetadataCaps(
|
|
332
|
+
maxMetadataValueLength,
|
|
333
|
+
maxPreviewLength,
|
|
334
|
+
resolvedProfile
|
|
335
|
+
);
|
|
336
|
+
maxMetadataValueLength = capped.maxMetadataValueLength;
|
|
337
|
+
maxPreviewLength = capped.maxPreviewLength;
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
redactEnabled,
|
|
341
|
+
redactionRules,
|
|
342
|
+
redactionProfile: profile,
|
|
343
|
+
profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],
|
|
344
|
+
maxMetadataValueLength,
|
|
345
|
+
maxPreviewLength,
|
|
346
|
+
maxEventBytes: typeof options?.maxEventBytes === "number" && Number.isFinite(options.maxEventBytes) && options.maxEventBytes > 0 ? Math.floor(options.maxEventBytes) : DEFAULT_MAX_EVENT_BYTES
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function boundMetadataValue(key, value, opts, seen, depth) {
|
|
350
|
+
if (depth > 32) return "[MaxDepth]";
|
|
351
|
+
if (value === null || typeof value !== "object") {
|
|
352
|
+
if (typeof value === "string") {
|
|
353
|
+
const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;
|
|
354
|
+
return truncateString(value, max);
|
|
355
|
+
}
|
|
356
|
+
return value;
|
|
357
|
+
}
|
|
358
|
+
if (seen.has(value)) return "[Circular]";
|
|
359
|
+
seen.add(value);
|
|
360
|
+
if (Array.isArray(value)) {
|
|
361
|
+
const maxItems = 50;
|
|
362
|
+
const out2 = value.slice(0, maxItems).map(
|
|
363
|
+
(item, index) => boundMetadataValue(String(index), item, opts, seen, depth + 1)
|
|
364
|
+
);
|
|
365
|
+
if (value.length > maxItems) {
|
|
366
|
+
out2.push(`\u2026(+${value.length - maxItems} more)`);
|
|
367
|
+
}
|
|
368
|
+
return out2;
|
|
369
|
+
}
|
|
370
|
+
const record = value;
|
|
371
|
+
const out = {};
|
|
372
|
+
for (const [k, v] of Object.entries(record)) {
|
|
373
|
+
out[k] = boundMetadataValue(k, v, opts, seen, depth + 1);
|
|
374
|
+
}
|
|
375
|
+
return out;
|
|
376
|
+
}
|
|
377
|
+
function redactMetadata(metadata, opts) {
|
|
378
|
+
if (!opts.redactEnabled) return { ...metadata };
|
|
379
|
+
const redactor = new Redactor({
|
|
380
|
+
rules: opts.redactionRules,
|
|
381
|
+
extraKeys: opts.profileExtraKeys
|
|
382
|
+
});
|
|
383
|
+
return redactor.redactRecord(metadata);
|
|
384
|
+
}
|
|
385
|
+
function prepareMetadataForDisk(metadata, opts) {
|
|
386
|
+
try {
|
|
387
|
+
const redacted = redactMetadata(metadata, opts);
|
|
388
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
389
|
+
const bounded = boundMetadataValue(
|
|
390
|
+
"metadata",
|
|
391
|
+
redacted,
|
|
392
|
+
opts,
|
|
393
|
+
seen,
|
|
394
|
+
0
|
|
395
|
+
);
|
|
396
|
+
return isRecord3(bounded) ? bounded : {};
|
|
397
|
+
} catch {
|
|
398
|
+
return { truncated: true, reason: "metadataPreparationFailed" };
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function truncateErrorStack(event, maxLen) {
|
|
402
|
+
if (event.event !== "run_completed" && event.event !== "step_completed") {
|
|
403
|
+
return event;
|
|
404
|
+
}
|
|
405
|
+
if (!event.error?.stack || typeof event.error.stack !== "string") {
|
|
406
|
+
return event;
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
...event,
|
|
410
|
+
error: {
|
|
411
|
+
...event.error,
|
|
412
|
+
stack: truncateString(event.error.stack, maxLen)
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function replaceMetadataWithTruncationMarker(event, originalApproxBytes) {
|
|
417
|
+
const marker = {
|
|
418
|
+
truncated: true,
|
|
419
|
+
reason: "maxEventBytes",
|
|
420
|
+
originalApproxBytes
|
|
421
|
+
};
|
|
422
|
+
if (event.event === "run_started") {
|
|
423
|
+
return { ...event, metadata: marker };
|
|
424
|
+
}
|
|
425
|
+
if (event.event === "step_started") {
|
|
426
|
+
return { ...event, metadata: marker };
|
|
427
|
+
}
|
|
428
|
+
return event;
|
|
429
|
+
}
|
|
430
|
+
function shrinkMetadataLimits(opts, factor) {
|
|
431
|
+
return {
|
|
432
|
+
...opts,
|
|
433
|
+
maxMetadataValueLength: Math.max(32, Math.floor(opts.maxMetadataValueLength * factor)),
|
|
434
|
+
maxPreviewLength: Math.max(16, Math.floor(opts.maxPreviewLength * factor))
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
function applyMetadataToEvent(event, metadata) {
|
|
438
|
+
if (event.event === "run_started") {
|
|
439
|
+
return { ...event, metadata };
|
|
440
|
+
}
|
|
441
|
+
if (event.event === "step_started") {
|
|
442
|
+
return { ...event, metadata };
|
|
443
|
+
}
|
|
444
|
+
return event;
|
|
445
|
+
}
|
|
446
|
+
function eventHasMetadata(event) {
|
|
447
|
+
return (event.event === "run_started" || event.event === "step_started") && event.metadata !== void 0;
|
|
448
|
+
}
|
|
449
|
+
function getEventMetadata(event) {
|
|
450
|
+
if (event.event === "run_started" || event.event === "step_started") {
|
|
451
|
+
return event.metadata;
|
|
452
|
+
}
|
|
453
|
+
return void 0;
|
|
454
|
+
}
|
|
455
|
+
function prepareTraceEventForDisk(event, opts) {
|
|
456
|
+
try {
|
|
457
|
+
let working = { ...event };
|
|
458
|
+
const rawMetadata = getEventMetadata(working);
|
|
459
|
+
if (rawMetadata !== void 0) {
|
|
460
|
+
const safe = prepareMetadataForDisk(rawMetadata, opts);
|
|
461
|
+
working = applyMetadataToEvent(working, safe);
|
|
462
|
+
}
|
|
463
|
+
let serialized = serializeEvent(working);
|
|
464
|
+
if (serialized === "") {
|
|
465
|
+
return working;
|
|
466
|
+
}
|
|
467
|
+
let bytes = byteLength(serialized);
|
|
468
|
+
if (bytes <= opts.maxEventBytes) {
|
|
469
|
+
return working;
|
|
470
|
+
}
|
|
471
|
+
if (rawMetadata !== void 0) {
|
|
472
|
+
for (const factor of [0.5, 0.25, 0.1]) {
|
|
473
|
+
const tighter = shrinkMetadataLimits(opts, factor);
|
|
474
|
+
const shrunk = prepareMetadataForDisk(rawMetadata, tighter);
|
|
475
|
+
working = applyMetadataToEvent(working, shrunk);
|
|
476
|
+
serialized = serializeEvent(working);
|
|
477
|
+
if (serialized !== "" && byteLength(serialized) <= opts.maxEventBytes) {
|
|
478
|
+
return working;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
working = replaceMetadataWithTruncationMarker(working, bytes);
|
|
482
|
+
serialized = serializeEvent(working);
|
|
483
|
+
if (serialized !== "" && byteLength(serialized) <= opts.maxEventBytes) {
|
|
484
|
+
return working;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
working = truncateErrorStack(working, Math.min(opts.maxMetadataValueLength, 500));
|
|
488
|
+
serialized = serializeEvent(working);
|
|
489
|
+
if (serialized !== "" && byteLength(serialized) <= opts.maxEventBytes) {
|
|
490
|
+
return working;
|
|
491
|
+
}
|
|
492
|
+
if (eventHasMetadata(working)) {
|
|
493
|
+
working = replaceMetadataWithTruncationMarker(working, bytes);
|
|
494
|
+
serialized = serializeEvent(working);
|
|
495
|
+
if (serialized !== "" && byteLength(serialized) <= opts.maxEventBytes) {
|
|
496
|
+
return working;
|
|
497
|
+
}
|
|
498
|
+
if (working.event === "run_started") {
|
|
499
|
+
const { metadata: _meta, ...rest } = working;
|
|
500
|
+
working = rest;
|
|
501
|
+
} else if (working.event === "step_started") {
|
|
502
|
+
const { metadata: _meta, ...rest } = working;
|
|
503
|
+
working = rest;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return working;
|
|
507
|
+
} catch {
|
|
508
|
+
if (event.event === "run_started" || event.event === "step_started") {
|
|
509
|
+
return applyMetadataToEvent(event, {
|
|
510
|
+
truncated: true,
|
|
511
|
+
reason: "prepareTraceEventFailed"
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
return event;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// packages/core/src/storage.ts
|
|
519
|
+
function isRecord4(value) {
|
|
520
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
521
|
+
}
|
|
522
|
+
function nonEmptyString(value) {
|
|
523
|
+
return typeof value === "string" && value.trim() !== "";
|
|
524
|
+
}
|
|
525
|
+
function finiteNumber(value) {
|
|
526
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
527
|
+
}
|
|
528
|
+
function optionalErrorInfo(value) {
|
|
529
|
+
if (value === void 0) return true;
|
|
530
|
+
if (!isRecord4(value)) return false;
|
|
531
|
+
if (typeof value.message !== "string") return false;
|
|
532
|
+
if ("stack" in value && value.stack !== void 0) {
|
|
533
|
+
if (typeof value.stack !== "string") return false;
|
|
534
|
+
}
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
function validateEvent(event) {
|
|
538
|
+
if (!isRecord4(event)) return false;
|
|
539
|
+
if (event.schemaVersion !== "0.1") return false;
|
|
540
|
+
if (!finiteNumber(event.timestamp)) return false;
|
|
541
|
+
if (typeof event.event !== "string") return false;
|
|
542
|
+
switch (event.event) {
|
|
543
|
+
case "run_started": {
|
|
544
|
+
if (!nonEmptyString(event.runId) || !nonEmptyString(event.name) || !finiteNumber(event.startTime)) {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
if (event.metadata !== void 0 && !isRecord4(event.metadata)) {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
case "run_completed": {
|
|
553
|
+
return nonEmptyString(event.runId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
|
|
554
|
+
}
|
|
555
|
+
case "step_started": {
|
|
556
|
+
if (!nonEmptyString(event.runId) || !nonEmptyString(event.stepId) || !nonEmptyString(event.name) || !isStepType(event.type) || !finiteNumber(event.startTime)) {
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
if (event.parentId !== void 0 && typeof event.parentId !== "string") {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
if (event.metadata !== void 0 && !isRecord4(event.metadata)) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
return true;
|
|
566
|
+
}
|
|
567
|
+
case "step_completed": {
|
|
568
|
+
return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
|
|
569
|
+
}
|
|
570
|
+
default:
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function serializeEvent(event) {
|
|
575
|
+
try {
|
|
576
|
+
return JSON.stringify(event);
|
|
577
|
+
} catch {
|
|
578
|
+
return "";
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
async function initializeTraceFile(runId, traceDir) {
|
|
582
|
+
try {
|
|
583
|
+
const usable = await ensureTraceDir(traceDir);
|
|
584
|
+
const filePath = getTraceFilePath(runId, usable);
|
|
585
|
+
await writeFile(filePath, "", "utf-8");
|
|
586
|
+
return filePath;
|
|
587
|
+
} catch (e) {
|
|
588
|
+
warn("Failed to initialize trace file", e);
|
|
589
|
+
}
|
|
590
|
+
try {
|
|
591
|
+
const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);
|
|
592
|
+
const filePath = getTraceFilePath(runId, usable);
|
|
593
|
+
await writeFile(filePath, "", "utf-8");
|
|
594
|
+
return filePath;
|
|
595
|
+
} catch (e) {
|
|
596
|
+
warn("Failed to initialize trace file on fallback directory", e);
|
|
597
|
+
return void 0;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function ensureEventWithinBounds(event) {
|
|
601
|
+
const line = serializeEvent(event);
|
|
602
|
+
if (line === "") return event;
|
|
603
|
+
const bytes = Buffer.byteLength(line, "utf8");
|
|
604
|
+
if (bytes <= DEFAULT_MAX_EVENT_BYTES) return event;
|
|
605
|
+
return prepareTraceEventForDisk(event, resolveTraceSafetyOptions());
|
|
606
|
+
}
|
|
607
|
+
async function writeTraceEvent(event, traceDir) {
|
|
608
|
+
const bounded = ensureEventWithinBounds(event);
|
|
609
|
+
if (!validateEvent(bounded)) {
|
|
610
|
+
warn("Skipped invalid trace event (validation failed)");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const line = serializeEvent(bounded);
|
|
614
|
+
if (line === "") {
|
|
615
|
+
warn("Skipped trace event (serialization failed)");
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const payload = `${line}
|
|
619
|
+
`;
|
|
620
|
+
const tryAppend = async (dir) => {
|
|
621
|
+
try {
|
|
622
|
+
const usable = await ensureTraceDir(dir);
|
|
623
|
+
const filePath = getTraceFilePath(event.runId, usable);
|
|
624
|
+
await appendFile(filePath, payload, "utf-8");
|
|
625
|
+
return true;
|
|
626
|
+
} catch {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
if (await tryAppend(traceDir)) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
warn(`Failed to append trace event for run ${event.runId}`);
|
|
634
|
+
if (await tryAppend(FALLBACK_TRACE_DIR)) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
warn("Failed to append trace event to fallback directory");
|
|
638
|
+
}
|
|
639
|
+
async function readTraceFile(runId, traceDir) {
|
|
640
|
+
try {
|
|
641
|
+
const filePath = getTraceFilePath(runId, traceDir);
|
|
642
|
+
return await readFile(filePath, "utf-8");
|
|
643
|
+
} catch (e) {
|
|
644
|
+
if (e && typeof e === "object" && "code" in e && e.code === "ENOENT") {
|
|
645
|
+
return void 0;
|
|
646
|
+
}
|
|
647
|
+
warn("Unexpected error reading trace file", e);
|
|
648
|
+
return void 0;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
async function readTraceEvents(runId, traceDir) {
|
|
652
|
+
try {
|
|
653
|
+
const raw = await readTraceFile(runId, traceDir);
|
|
654
|
+
if (raw === void 0) {
|
|
655
|
+
return [];
|
|
656
|
+
}
|
|
657
|
+
return parseTraceJsonl(raw, { validate: validateEvent }).events;
|
|
658
|
+
} catch (e) {
|
|
659
|
+
warn("Failed to read trace events", e);
|
|
660
|
+
return [];
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
async function listTraceFiles(traceDir) {
|
|
664
|
+
try {
|
|
665
|
+
const usable = path.resolve(traceDir);
|
|
666
|
+
const names = await readdir(usable);
|
|
667
|
+
const jsonl = names.filter((n) => n.endsWith(".jsonl"));
|
|
668
|
+
const withStat = await Promise.all(
|
|
669
|
+
jsonl.map(async (name) => {
|
|
670
|
+
try {
|
|
671
|
+
const st = await stat(path.join(usable, name));
|
|
672
|
+
return { name, mtime: st.mtimeMs };
|
|
673
|
+
} catch {
|
|
674
|
+
return { name, mtime: 0 };
|
|
675
|
+
}
|
|
676
|
+
})
|
|
677
|
+
);
|
|
678
|
+
withStat.sort((a, b) => {
|
|
679
|
+
if (b.mtime !== a.mtime) return b.mtime - a.mtime;
|
|
680
|
+
return a.name.localeCompare(b.name);
|
|
681
|
+
});
|
|
682
|
+
return withStat.map((x) => x.name);
|
|
683
|
+
} catch {
|
|
684
|
+
return [];
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
function getRunIdFromTraceFileName(fileName) {
|
|
688
|
+
try {
|
|
689
|
+
const base = path.basename(fileName);
|
|
690
|
+
if (!base.endsWith(".jsonl")) return void 0;
|
|
691
|
+
const id = base.slice(0, -".jsonl".length);
|
|
692
|
+
return id === "" ? void 0 : id;
|
|
693
|
+
} catch {
|
|
694
|
+
return void 0;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
var storage = new AsyncLocalStorage();
|
|
698
|
+
function toPublicContext(ctx) {
|
|
699
|
+
return {
|
|
700
|
+
runId: ctx.runId,
|
|
701
|
+
runName: ctx.runName,
|
|
702
|
+
traceDir: ctx.traceDir,
|
|
703
|
+
silent: ctx.silent,
|
|
704
|
+
metadata: ctx.metadata
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
function invoke(fn) {
|
|
708
|
+
return new Promise((resolve, reject) => {
|
|
709
|
+
try {
|
|
710
|
+
Promise.resolve(fn()).then(resolve, reject);
|
|
711
|
+
} catch (e) {
|
|
712
|
+
reject(e);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
function getCurrentContext() {
|
|
717
|
+
try {
|
|
718
|
+
const s = storage.getStore();
|
|
719
|
+
if (!s) return void 0;
|
|
720
|
+
return toPublicContext(s);
|
|
721
|
+
} catch {
|
|
722
|
+
return void 0;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function getCurrentRunId() {
|
|
726
|
+
try {
|
|
727
|
+
return storage.getStore()?.runId;
|
|
728
|
+
} catch {
|
|
729
|
+
return void 0;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
function getCurrentCorrelationMetadata() {
|
|
733
|
+
try {
|
|
734
|
+
return extractCorrelationMetadata(storage.getStore()?.metadata);
|
|
735
|
+
} catch {
|
|
736
|
+
return void 0;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
function getCurrentRunName() {
|
|
740
|
+
try {
|
|
741
|
+
return storage.getStore()?.runName;
|
|
742
|
+
} catch {
|
|
743
|
+
return void 0;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
function getCurrentStepId() {
|
|
747
|
+
try {
|
|
748
|
+
return storage.getStore()?.currentStepId;
|
|
749
|
+
} catch {
|
|
750
|
+
return void 0;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function getParentStepId() {
|
|
754
|
+
return getCurrentStepId();
|
|
755
|
+
}
|
|
756
|
+
function getCurrentDepth() {
|
|
757
|
+
try {
|
|
758
|
+
const d = storage.getStore()?.currentDepth;
|
|
759
|
+
return typeof d === "number" && Number.isFinite(d) ? d : 0;
|
|
760
|
+
} catch {
|
|
761
|
+
return 0;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
function hasActiveContext() {
|
|
765
|
+
try {
|
|
766
|
+
return storage.getStore() !== void 0;
|
|
767
|
+
} catch {
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function getTraceDirFromContext() {
|
|
772
|
+
try {
|
|
773
|
+
return storage.getStore()?.traceDir;
|
|
774
|
+
} catch {
|
|
775
|
+
return void 0;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function isSilentContext() {
|
|
779
|
+
try {
|
|
780
|
+
const s = storage.getStore();
|
|
781
|
+
return s ? s.silent : false;
|
|
782
|
+
} catch {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
function getTraceSafetyFromContext() {
|
|
787
|
+
try {
|
|
788
|
+
return storage.getStore()?.traceSafety;
|
|
789
|
+
} catch {
|
|
790
|
+
return void 0;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
function runWithContext(context, fn, traceSafety = resolveTraceSafetyOptions()) {
|
|
794
|
+
const runtime = {
|
|
795
|
+
runId: context.runId,
|
|
796
|
+
runName: context.runName,
|
|
797
|
+
traceDir: context.traceDir,
|
|
798
|
+
silent: context.silent,
|
|
799
|
+
metadata: context.metadata,
|
|
800
|
+
traceSafety,
|
|
801
|
+
currentDepth: 0
|
|
802
|
+
};
|
|
803
|
+
return new Promise((resolve, reject) => {
|
|
804
|
+
storage.run(runtime, () => {
|
|
805
|
+
try {
|
|
806
|
+
Promise.resolve(fn()).then(resolve, reject);
|
|
807
|
+
} catch (e) {
|
|
808
|
+
reject(e);
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
function runWithStepContext(stepId, fn) {
|
|
814
|
+
let parent;
|
|
815
|
+
try {
|
|
816
|
+
parent = storage.getStore();
|
|
817
|
+
} catch {
|
|
818
|
+
parent = void 0;
|
|
819
|
+
}
|
|
820
|
+
if (!parent) {
|
|
821
|
+
return invoke(fn);
|
|
822
|
+
}
|
|
823
|
+
const derived = {
|
|
824
|
+
runId: parent.runId,
|
|
825
|
+
runName: parent.runName,
|
|
826
|
+
traceDir: parent.traceDir,
|
|
827
|
+
silent: parent.silent,
|
|
828
|
+
metadata: parent.metadata,
|
|
829
|
+
traceSafety: parent.traceSafety,
|
|
830
|
+
currentStepId: stepId,
|
|
831
|
+
currentDepth: parent.currentDepth + 1
|
|
832
|
+
};
|
|
833
|
+
return new Promise((resolve, reject) => {
|
|
834
|
+
storage.run(derived, () => {
|
|
835
|
+
try {
|
|
836
|
+
Promise.resolve(fn()).then(resolve, reject);
|
|
837
|
+
} catch (e) {
|
|
838
|
+
reject(e);
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// packages/core/src/terminal.ts
|
|
845
|
+
var TERMINAL_INDENT = " ";
|
|
846
|
+
var MAX_TERMINAL_NAME_LENGTH = 80;
|
|
847
|
+
var MAX_TERMINAL_DEPTH = 10;
|
|
848
|
+
function normalizeDepth(depth) {
|
|
849
|
+
if (!Number.isFinite(depth) || depth < 0) {
|
|
850
|
+
return 0;
|
|
851
|
+
}
|
|
852
|
+
return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);
|
|
853
|
+
}
|
|
854
|
+
function safePrint(line = "") {
|
|
855
|
+
try {
|
|
856
|
+
console.log(line);
|
|
857
|
+
} catch {
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
function getIndent(depth) {
|
|
861
|
+
return TERMINAL_INDENT.repeat(normalizeDepth(depth));
|
|
862
|
+
}
|
|
863
|
+
function formatTerminalName(name) {
|
|
864
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
865
|
+
return "unnamed";
|
|
866
|
+
}
|
|
867
|
+
return truncateName(name, MAX_TERMINAL_NAME_LENGTH);
|
|
868
|
+
}
|
|
869
|
+
function getStatusIcon(status) {
|
|
870
|
+
if (status === "success") return source_default.green("\u2714");
|
|
871
|
+
if (status === "error") return source_default.red("\u2716");
|
|
872
|
+
return source_default.yellow("\u23F3");
|
|
873
|
+
}
|
|
874
|
+
function renderStepLine(name, durationMs, status, depth) {
|
|
875
|
+
try {
|
|
876
|
+
const nm = formatTerminalName(name);
|
|
877
|
+
const ind = getIndent(depth ?? 0);
|
|
878
|
+
if (status === "running" && durationMs === void 0) {
|
|
879
|
+
return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
|
|
880
|
+
}
|
|
881
|
+
const hasDur = durationMs !== void 0 && Number.isFinite(durationMs);
|
|
882
|
+
const dur = hasDur ? formatDuration2(durationMs) : void 0;
|
|
883
|
+
if (status === "running") {
|
|
884
|
+
return dur !== void 0 ? `${ind}${source_default.yellow("\u23F3")} ${nm} (${dur})` : `${ind}${source_default.yellow("\u23F3")} ${nm}`;
|
|
885
|
+
}
|
|
886
|
+
if (!hasDur || dur === void 0) {
|
|
887
|
+
return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
|
|
888
|
+
}
|
|
889
|
+
if (status === "success") {
|
|
890
|
+
return `${ind}${getStatusIcon("success")} ${nm} (${dur})`;
|
|
891
|
+
}
|
|
892
|
+
return `${ind}${getStatusIcon("error")} ${nm} (${dur})`;
|
|
893
|
+
} catch {
|
|
894
|
+
return "";
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function renderErrorLine(error, depth) {
|
|
898
|
+
try {
|
|
899
|
+
const msg = typeof error.message === "string" ? error.message : "";
|
|
900
|
+
const ind = getIndent((depth ?? 0) + 1);
|
|
901
|
+
return `${ind}Error: ${msg}`;
|
|
902
|
+
} catch {
|
|
903
|
+
return "";
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
function renderRunSummary(durationMs, status, traceFilePath) {
|
|
907
|
+
try {
|
|
908
|
+
const dur = Number.isFinite(durationMs) ? formatDuration2(durationMs) : formatDuration2(0);
|
|
909
|
+
const head = status === "error" ? `Failed in ${dur}` : `Completed in ${dur}`;
|
|
910
|
+
const lines = [head];
|
|
911
|
+
if (traceFilePath !== void 0 && traceFilePath.trim() !== "") {
|
|
912
|
+
lines.push(`Trace: ${traceFilePath}`);
|
|
913
|
+
}
|
|
914
|
+
return lines;
|
|
915
|
+
} catch {
|
|
916
|
+
return [];
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
function printRunStart(runId, name) {
|
|
920
|
+
if (isSilentContext()) return;
|
|
921
|
+
try {
|
|
922
|
+
safePrint("");
|
|
923
|
+
const header = `${source_default.cyan.bold("\u{1F50D} AgentInspect:")} ${formatTerminalName(name)} ${source_default.dim(`(${runId})`)}`;
|
|
924
|
+
safePrint(header);
|
|
925
|
+
} catch {
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
function printStepStart(name, depth = 0) {
|
|
929
|
+
if (isSilentContext()) return;
|
|
930
|
+
try {
|
|
931
|
+
safePrint(renderStepLine(name, void 0, "running", depth));
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
function printStepComplete(name, durationMs, status, depth = 0) {
|
|
936
|
+
if (isSilentContext()) return;
|
|
937
|
+
try {
|
|
938
|
+
safePrint(renderStepLine(name, durationMs, status, depth));
|
|
939
|
+
} catch {
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
function printError(error, depth = 0) {
|
|
943
|
+
if (isSilentContext()) return;
|
|
944
|
+
try {
|
|
945
|
+
safePrint(renderErrorLine(error, depth));
|
|
946
|
+
} catch {
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
function printRunComplete(_name, _runId, durationMs, status, traceFilePath) {
|
|
950
|
+
if (isSilentContext()) return;
|
|
951
|
+
try {
|
|
952
|
+
const lines = renderRunSummary(durationMs, status, traceFilePath);
|
|
953
|
+
for (let i = 0; i < lines.length; i++) {
|
|
954
|
+
const line = lines[i];
|
|
955
|
+
if (i === 0) {
|
|
956
|
+
const color = status === "error" ? source_default.red : status === "running" ? source_default.yellow : source_default.green;
|
|
957
|
+
safePrint(color(line));
|
|
958
|
+
} else {
|
|
959
|
+
safePrint(source_default.dim(line));
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
} catch {
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
function printFailedAt(stepName) {
|
|
966
|
+
if (isSilentContext()) return;
|
|
967
|
+
try {
|
|
968
|
+
safePrint(`Failed at: ${formatTerminalName(stepName)}`);
|
|
969
|
+
} catch {
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
export { DEFAULT_MAX_EVENT_BYTES, DEFAULT_MAX_METADATA_VALUE_LENGTH, DEFAULT_MAX_PREVIEW_LENGTH, DEFAULT_TRACE_DIR_NAME, FALLBACK_TRACE_DIR, MAX_NAME_LENGTH, MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, RUNS_DIR_NAME, TERMINAL_INDENT, createRunId, createStepId, ensureTraceDir, formatDuration2 as formatDuration, formatError, formatTerminalName, formatTimestamp, getCurrentContext, getCurrentCorrelationMetadata, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getDefaultTraceDir, getIndent, getParentStepId, getRunIdFromTraceFileName, getTraceDirFromContext, getTraceFilePath, getTraceSafetyFromContext, hasActiveContext, initializeTraceFile, isSilentContext, isStepStatus, isStepType, isTraceEvent, listTraceFiles, parseDuration, parseTraceJsonl, prepareMetadataForDisk, prepareTraceEventForDisk, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, readTraceEvents, readTraceFile, renderErrorLine, renderRunSummary, renderStepLine, resolveTraceSafetyOptions, runWithContext, runWithStepContext, serializeEvent, truncateName, unknownTraceFormatMessage, validateEvent, warn, writeTraceEvent };
|
|
974
|
+
//# sourceMappingURL=chunk-XDBND27A.mjs.map
|
|
975
|
+
//# sourceMappingURL=chunk-XDBND27A.mjs.map
|