agent-inspect 1.1.0 → 1.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.
@@ -1,12 +1,12 @@
1
1
  import { readFile, mkdir, writeFile, readdir, stat, appendFile } from 'fs/promises';
2
- import crypto from 'crypto';
3
- import { nanoid } from 'nanoid';
2
+ import crypto, { webcrypto } from 'crypto';
4
3
  import os from 'os';
5
4
  import path from 'path';
6
5
  import { AsyncLocalStorage } from 'async_hooks';
7
6
  import { createReadStream } from 'fs';
8
7
  import { createInterface } from 'readline';
9
- import chalk2 from 'chalk';
8
+ import process2 from 'process';
9
+ import tty from 'tty';
10
10
 
11
11
  // packages/core/src/types.ts
12
12
  var STEP_TYPES = [
@@ -54,7 +54,793 @@ function isTraceEvent(value) {
54
54
  return false;
55
55
  }
56
56
  }
57
- function isRecord2(v) {
57
+
58
+ // packages/core/src/types/persisted-inspect-event.ts
59
+ var INSPECT_KINDS = [
60
+ "RUN",
61
+ "AGENT",
62
+ "LLM",
63
+ "TOOL",
64
+ "CHAIN",
65
+ "RETRIEVER",
66
+ "DECISION",
67
+ "RESULT",
68
+ "ERROR",
69
+ "LOGIC",
70
+ "LOG"
71
+ ];
72
+ var ATTRIBUTION_CONFIDENCES = [
73
+ "explicit",
74
+ "correlated",
75
+ "heuristic",
76
+ "unknown"
77
+ ];
78
+ var PERSISTED_EVENT_SOURCE_TYPES = [
79
+ "manual",
80
+ "json-log",
81
+ "log4js",
82
+ "adapter",
83
+ "ai-sdk",
84
+ "otel"
85
+ ];
86
+ var PERSISTED_EVENT_STATUSES = [
87
+ "running",
88
+ "ok",
89
+ "error",
90
+ "unknown"
91
+ ];
92
+ function isRecord2(value) {
93
+ return typeof value === "object" && value !== null && !Array.isArray(value);
94
+ }
95
+ function isString(value) {
96
+ return typeof value === "string";
97
+ }
98
+ function isNonEmptyString(value) {
99
+ return typeof value === "string" && value.length > 0;
100
+ }
101
+ function isOptionalString(value) {
102
+ return value === void 0 || isString(value);
103
+ }
104
+ function isNonNegativeNumber(value) {
105
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
106
+ }
107
+ function isOptionalNonNegativeNumber(value) {
108
+ return value === void 0 || isNonNegativeNumber(value);
109
+ }
110
+ function isInspectKind(value) {
111
+ return typeof value === "string" && INSPECT_KINDS.includes(value);
112
+ }
113
+ function isAttributionConfidence(value) {
114
+ return typeof value === "string" && ATTRIBUTION_CONFIDENCES.includes(value);
115
+ }
116
+ function isPersistedEventSourceType(value) {
117
+ return typeof value === "string" && PERSISTED_EVENT_SOURCE_TYPES.includes(value);
118
+ }
119
+ function isPersistedEventStatus(value) {
120
+ return typeof value === "string" && PERSISTED_EVENT_STATUSES.includes(value);
121
+ }
122
+ function isPersistedEventSource(value) {
123
+ if (!isRecord2(value)) return false;
124
+ if (!isPersistedEventSourceType(value.type)) return false;
125
+ if (!isOptionalString(value.name)) return false;
126
+ if (!isOptionalString(value.version)) return false;
127
+ return true;
128
+ }
129
+ function isPersistedInspectError(value) {
130
+ if (!isRecord2(value)) return false;
131
+ if (!isNonEmptyString(value.message)) return false;
132
+ if (!isOptionalString(value.name)) return false;
133
+ if (!isOptionalString(value.code)) return false;
134
+ return true;
135
+ }
136
+ function isPersistedTokenUsage(value) {
137
+ if (!isRecord2(value)) return false;
138
+ if (!isOptionalNonNegativeNumber(value.input)) return false;
139
+ if (!isOptionalNonNegativeNumber(value.output)) return false;
140
+ if (!isOptionalNonNegativeNumber(value.total)) return false;
141
+ return true;
142
+ }
143
+ function isPersistedTraceContext(value) {
144
+ if (!isRecord2(value)) return false;
145
+ if (!isOptionalString(value.traceId)) return false;
146
+ if (!isOptionalString(value.spanId)) return false;
147
+ if (!isOptionalString(value.parentSpanId)) return false;
148
+ return true;
149
+ }
150
+ function isPersistedInspectEvent(value) {
151
+ if (!isRecord2(value)) return false;
152
+ if (value.schemaVersion !== "0.2") return false;
153
+ if (!isNonEmptyString(value.eventId)) return false;
154
+ if (!isNonEmptyString(value.runId)) return false;
155
+ if (!isInspectKind(value.kind)) return false;
156
+ if (!isNonEmptyString(value.name)) return false;
157
+ if (!isNonEmptyString(value.timestamp)) return false;
158
+ if (!isAttributionConfidence(value.confidence)) return false;
159
+ if (!isPersistedEventSource(value.source)) return false;
160
+ if (value.parentId !== void 0 && !isNonEmptyString(value.parentId)) {
161
+ return false;
162
+ }
163
+ if (value.status !== void 0 && !isPersistedEventStatus(value.status)) {
164
+ return false;
165
+ }
166
+ if (!isOptionalString(value.startedAt)) return false;
167
+ if (!isOptionalString(value.endedAt)) return false;
168
+ if (value.durationMs !== void 0 && !isNonNegativeNumber(value.durationMs)) {
169
+ return false;
170
+ }
171
+ if (value.attributes !== void 0 && !isRecord2(value.attributes)) {
172
+ return false;
173
+ }
174
+ if (value.error !== void 0 && !isPersistedInspectError(value.error)) {
175
+ return false;
176
+ }
177
+ if (value.tokenUsage !== void 0 && !isPersistedTokenUsage(value.tokenUsage)) {
178
+ return false;
179
+ }
180
+ if (value.trace !== void 0 && !isPersistedTraceContext(value.trace)) {
181
+ return false;
182
+ }
183
+ return true;
184
+ }
185
+
186
+ // packages/core/src/correlation-metadata.ts
187
+ var TRACE_CORRELATION_KEYS = [
188
+ "correlationId",
189
+ "requestId",
190
+ "decisionId",
191
+ "groupId"
192
+ ];
193
+ function isNonEmptyString2(value) {
194
+ return typeof value === "string" && value.length > 0;
195
+ }
196
+ function extractCorrelationMetadata(record) {
197
+ if (!record) {
198
+ return void 0;
199
+ }
200
+ const out = {};
201
+ let found = false;
202
+ for (const key of TRACE_CORRELATION_KEYS) {
203
+ const value = record[key];
204
+ if (isNonEmptyString2(value)) {
205
+ out[key] = value;
206
+ found = true;
207
+ }
208
+ }
209
+ return found ? out : void 0;
210
+ }
211
+ function buildRunStartedMetadata(options) {
212
+ if (!options) {
213
+ return void 0;
214
+ }
215
+ const merged = options.metadata !== void 0 ? { ...options.metadata } : {};
216
+ if (isNonEmptyString2(options.correlationId)) {
217
+ merged.correlationId = options.correlationId;
218
+ }
219
+ if (isNonEmptyString2(options.requestId)) {
220
+ merged.requestId = options.requestId;
221
+ }
222
+ if (isNonEmptyString2(options.decisionId)) {
223
+ merged.decisionId = options.decisionId;
224
+ }
225
+ if (isNonEmptyString2(options.groupId)) {
226
+ merged.groupId = options.groupId;
227
+ }
228
+ return Object.keys(merged).length > 0 ? merged : void 0;
229
+ }
230
+
231
+ // packages/core/src/persisted/from-trace-event.ts
232
+ function sanitizeIdPart(value) {
233
+ return value.replace(/[^a-zA-Z0-9_-]/g, "_");
234
+ }
235
+ function nodeIdForEvent(event) {
236
+ switch (event.event) {
237
+ case "run_started":
238
+ case "run_completed":
239
+ return event.runId;
240
+ case "step_started":
241
+ case "step_completed":
242
+ return event.stepId;
243
+ default:
244
+ return "unknown";
245
+ }
246
+ }
247
+ function createPersistedEventId(event, eventIndex) {
248
+ const runId = sanitizeIdPart(event.runId);
249
+ const ev = sanitizeIdPart(event.event);
250
+ const node = sanitizeIdPart(nodeIdForEvent(event));
251
+ return `manual:${runId}:${ev}:${node}:${eventIndex}`;
252
+ }
253
+ function toIsoTimestamp(ms) {
254
+ if (typeof ms !== "number" || !Number.isFinite(ms)) {
255
+ return { iso: (/* @__PURE__ */ new Date(0)).toISOString(), invalidTimestamp: true };
256
+ }
257
+ return { iso: new Date(ms).toISOString(), invalidTimestamp: false };
258
+ }
259
+ function buildSource(options) {
260
+ return {
261
+ type: "manual",
262
+ name: options?.sourceName ?? "trace-event",
263
+ version: options?.sourceVersion ?? "0.1"
264
+ };
265
+ }
266
+ function mapStepTypeToInspectKind(type) {
267
+ switch (type) {
268
+ case "run":
269
+ return "RUN";
270
+ case "llm":
271
+ return "LLM";
272
+ case "tool":
273
+ return "TOOL";
274
+ case "decision":
275
+ return "DECISION";
276
+ case "logic":
277
+ case "state":
278
+ case "custom":
279
+ return "LOGIC";
280
+ default:
281
+ return "LOGIC";
282
+ }
283
+ }
284
+ function mapRunOrStepStatus(status) {
285
+ return status === "success" ? "ok" : "error";
286
+ }
287
+ function mapErrorInfo(error) {
288
+ if (!error?.message) {
289
+ return {};
290
+ }
291
+ const out = {
292
+ persisted: {
293
+ message: error.message,
294
+ name: "Error"
295
+ }
296
+ };
297
+ if (typeof error.stack === "string" && error.stack.length > 0) {
298
+ out.errorStack = error.stack;
299
+ }
300
+ return out;
301
+ }
302
+ function mapTokenUsageFromMetadata(metadata) {
303
+ const tokens = metadata?.tokens;
304
+ if (!tokens || typeof tokens !== "object") {
305
+ return void 0;
306
+ }
307
+ const input = typeof tokens.input === "number" && Number.isFinite(tokens.input) && tokens.input >= 0 ? tokens.input : void 0;
308
+ const output = typeof tokens.output === "number" && Number.isFinite(tokens.output) && tokens.output >= 0 ? tokens.output : void 0;
309
+ if (input === void 0 && output === void 0) {
310
+ return void 0;
311
+ }
312
+ const usage = {};
313
+ if (input !== void 0) usage.input = input;
314
+ if (output !== void 0) usage.output = output;
315
+ if (input !== void 0 && output !== void 0) {
316
+ usage.total = input + output;
317
+ }
318
+ return usage;
319
+ }
320
+ function compactAttributes(entries) {
321
+ const out = {};
322
+ for (const [key, value] of Object.entries(entries)) {
323
+ if (value !== void 0) {
324
+ out[key] = value;
325
+ }
326
+ }
327
+ return Object.keys(out).length > 0 ? out : void 0;
328
+ }
329
+ function traceEventToPersistedInspectEvent(event, options) {
330
+ const eventIndex = options?.eventIndex ?? 0;
331
+ const eventId = createPersistedEventId(event, eventIndex);
332
+ const source = buildSource(options);
333
+ const tsMain = toIsoTimestamp(event.timestamp);
334
+ switch (event.event) {
335
+ case "run_started": {
336
+ const tsStart = toIsoTimestamp(event.startTime);
337
+ const correlation = extractCorrelationMetadata(event.metadata);
338
+ const attributes = compactAttributes({
339
+ legacyEvent: "run_started",
340
+ metadata: event.metadata !== void 0 ? { ...event.metadata } : void 0,
341
+ correlationId: correlation?.correlationId,
342
+ requestId: correlation?.requestId,
343
+ decisionId: correlation?.decisionId,
344
+ groupId: correlation?.groupId,
345
+ invalidTimestamp: tsMain.invalidTimestamp || tsStart.invalidTimestamp ? true : void 0
346
+ });
347
+ return {
348
+ schemaVersion: "0.2",
349
+ eventId,
350
+ runId: event.runId,
351
+ kind: "RUN",
352
+ name: event.name,
353
+ status: "running",
354
+ timestamp: tsMain.iso,
355
+ startedAt: tsStart.iso,
356
+ confidence: "explicit",
357
+ source,
358
+ attributes
359
+ };
360
+ }
361
+ case "run_completed": {
362
+ const tsEnd = toIsoTimestamp(event.endTime);
363
+ const { persisted: error, errorStack } = mapErrorInfo(event.error);
364
+ const attributes = compactAttributes({
365
+ legacyEvent: "run_completed",
366
+ errorStack,
367
+ invalidTimestamp: tsMain.invalidTimestamp || tsEnd.invalidTimestamp ? true : void 0
368
+ });
369
+ return {
370
+ schemaVersion: "0.2",
371
+ eventId,
372
+ runId: event.runId,
373
+ kind: "RUN",
374
+ name: "run",
375
+ status: mapRunOrStepStatus(event.status),
376
+ timestamp: tsMain.iso,
377
+ endedAt: tsEnd.iso,
378
+ durationMs: event.durationMs,
379
+ confidence: "explicit",
380
+ source,
381
+ attributes,
382
+ error
383
+ };
384
+ }
385
+ case "step_started": {
386
+ const tsStart = toIsoTimestamp(event.startTime);
387
+ const tokenUsage = mapTokenUsageFromMetadata(event.metadata);
388
+ const attributes = compactAttributes({
389
+ legacyEvent: "step_started",
390
+ stepId: event.stepId,
391
+ stepType: event.type,
392
+ metadata: event.metadata !== void 0 ? { ...event.metadata } : void 0,
393
+ invalidTimestamp: tsMain.invalidTimestamp || tsStart.invalidTimestamp ? true : void 0
394
+ });
395
+ const out = {
396
+ schemaVersion: "0.2",
397
+ eventId,
398
+ runId: event.runId,
399
+ kind: mapStepTypeToInspectKind(event.type),
400
+ name: event.name,
401
+ status: "running",
402
+ timestamp: tsMain.iso,
403
+ startedAt: tsStart.iso,
404
+ confidence: "explicit",
405
+ source,
406
+ attributes
407
+ };
408
+ if (event.parentId !== void 0) {
409
+ out.parentId = event.parentId;
410
+ }
411
+ if (tokenUsage !== void 0) {
412
+ out.tokenUsage = tokenUsage;
413
+ }
414
+ return out;
415
+ }
416
+ case "step_completed": {
417
+ const tsEnd = toIsoTimestamp(event.endTime);
418
+ const { persisted: error, errorStack } = mapErrorInfo(event.error);
419
+ const attributes = compactAttributes({
420
+ legacyEvent: "step_completed",
421
+ stepId: event.stepId,
422
+ errorStack,
423
+ invalidTimestamp: tsMain.invalidTimestamp || tsEnd.invalidTimestamp ? true : void 0
424
+ });
425
+ return {
426
+ schemaVersion: "0.2",
427
+ eventId,
428
+ runId: event.runId,
429
+ kind: "LOGIC",
430
+ name: event.stepId,
431
+ status: mapRunOrStepStatus(event.status),
432
+ timestamp: tsMain.iso,
433
+ endedAt: tsEnd.iso,
434
+ durationMs: event.durationMs,
435
+ confidence: "explicit",
436
+ source,
437
+ attributes,
438
+ error
439
+ };
440
+ }
441
+ default: {
442
+ const _exhaustive = event;
443
+ throw new Error(`Unsupported trace event: ${_exhaustive.event}`);
444
+ }
445
+ }
446
+ }
447
+ function traceEventsToPersistedInspectEvents(events, options) {
448
+ return events.map(
449
+ (event, index) => traceEventToPersistedInspectEvent(event, { ...options, eventIndex: index })
450
+ );
451
+ }
452
+
453
+ // packages/core/src/persisted/from-inspect-event.ts
454
+ function sanitizeIdPart2(value) {
455
+ return value.replace(/[^a-zA-Z0-9_-]/g, "_");
456
+ }
457
+ function createFallbackEventId(event, eventIndex) {
458
+ const runId = sanitizeIdPart2(event.runId);
459
+ const kind = sanitizeIdPart2(event.kind);
460
+ const name = sanitizeIdPart2(event.name);
461
+ return `inspect:${runId}:${kind}:${name}:${eventIndex}`;
462
+ }
463
+ function toIsoTimestamp2(ms) {
464
+ if (typeof ms !== "number" || !Number.isFinite(ms)) {
465
+ return { iso: (/* @__PURE__ */ new Date(0)).toISOString(), invalidTimestamp: true };
466
+ }
467
+ return { iso: new Date(ms).toISOString(), invalidTimestamp: false };
468
+ }
469
+ function compactAttributes2(entries) {
470
+ const out = {};
471
+ for (const [key, value] of Object.entries(entries)) {
472
+ if (value !== void 0) {
473
+ out[key] = value;
474
+ }
475
+ }
476
+ return Object.keys(out).length > 0 ? out : void 0;
477
+ }
478
+ function mapInspectSourceToPersisted(source, options) {
479
+ const name = options?.sourceName;
480
+ const version = options?.sourceVersion;
481
+ switch (source.type) {
482
+ case "pino":
483
+ return {
484
+ persistedSource: {
485
+ type: "json-log",
486
+ name: name ?? "pino",
487
+ version
488
+ },
489
+ originalSourceType: "pino"
490
+ };
491
+ case "winston":
492
+ return {
493
+ persistedSource: {
494
+ type: "json-log",
495
+ name: name ?? "winston",
496
+ version
497
+ },
498
+ originalSourceType: "winston"
499
+ };
500
+ case "manual":
501
+ case "json-log":
502
+ case "log4js":
503
+ case "adapter":
504
+ return {
505
+ persistedSource: {
506
+ type: source.type,
507
+ name,
508
+ version
509
+ }
510
+ };
511
+ default:
512
+ return {
513
+ persistedSource: {
514
+ type: "json-log",
515
+ name,
516
+ version
517
+ }
518
+ };
519
+ }
520
+ }
521
+ function mapTokenUsageFromAttributes(attributes) {
522
+ const tokens = attributes?.tokens;
523
+ if (!tokens || typeof tokens !== "object" || Array.isArray(tokens)) {
524
+ return void 0;
525
+ }
526
+ const rec = tokens;
527
+ const input = typeof rec.input === "number" && Number.isFinite(rec.input) && rec.input >= 0 ? rec.input : void 0;
528
+ const output = typeof rec.output === "number" && Number.isFinite(rec.output) && rec.output >= 0 ? rec.output : void 0;
529
+ if (input === void 0 && output === void 0) {
530
+ return void 0;
531
+ }
532
+ const usage = {};
533
+ if (input !== void 0) usage.input = input;
534
+ if (output !== void 0) usage.output = output;
535
+ if (input !== void 0 && output !== void 0) {
536
+ usage.total = input + output;
537
+ }
538
+ return usage;
539
+ }
540
+ function mapErrorFromAttributes(event) {
541
+ if (event.status !== "error" || !event.attributes) {
542
+ return void 0;
543
+ }
544
+ const message = event.attributes.errorMessage;
545
+ if (typeof message !== "string" || message.length === 0) {
546
+ return void 0;
547
+ }
548
+ const err = { message };
549
+ if (typeof event.attributes.errorName === "string") {
550
+ err.name = event.attributes.errorName;
551
+ }
552
+ return err;
553
+ }
554
+ function inspectEventToPersistedInspectEvent(event, options) {
555
+ const eventIndex = options?.eventIndex ?? 0;
556
+ const eventId = typeof event.eventId === "string" && event.eventId.length > 0 ? event.eventId : createFallbackEventId(event, eventIndex);
557
+ const ts = toIsoTimestamp2(event.timestamp);
558
+ const { persistedSource, originalSourceType } = mapInspectSourceToPersisted(
559
+ event.source,
560
+ options
561
+ );
562
+ const attrsBase = event.attributes !== void 0 ? { ...event.attributes } : {};
563
+ const attributes = compactAttributes2({
564
+ ...attrsBase,
565
+ sourceFile: event.source.file,
566
+ sourceLine: event.source.line,
567
+ originalSourceType,
568
+ invalidTimestamp: ts.invalidTimestamp ? true : void 0
569
+ });
570
+ const tokenUsage = mapTokenUsageFromAttributes(event.attributes);
571
+ const error = mapErrorFromAttributes(event);
572
+ const inputPreview = event.attributes?.inputPreview;
573
+ const outputPreview = event.attributes?.outputPreview;
574
+ const out = {
575
+ schemaVersion: "0.2",
576
+ eventId,
577
+ runId: event.runId,
578
+ kind: event.kind,
579
+ name: event.name,
580
+ timestamp: ts.iso,
581
+ confidence: event.confidence,
582
+ source: persistedSource,
583
+ attributes
584
+ };
585
+ if (event.parentId !== void 0) {
586
+ out.parentId = event.parentId;
587
+ }
588
+ if (event.status !== void 0) {
589
+ out.status = event.status;
590
+ }
591
+ if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
592
+ out.durationMs = event.durationMs;
593
+ }
594
+ if (tokenUsage !== void 0) {
595
+ out.tokenUsage = tokenUsage;
596
+ }
597
+ if (error !== void 0) {
598
+ out.error = error;
599
+ }
600
+ if (inputPreview !== void 0) {
601
+ out.inputSummary = inputPreview;
602
+ }
603
+ if (outputPreview !== void 0) {
604
+ out.outputSummary = outputPreview;
605
+ }
606
+ return out;
607
+ }
608
+ function inspectEventsToPersistedInspectEvents(events, options) {
609
+ return events.map(
610
+ (event, index) => inspectEventToPersistedInspectEvent(event, { ...options, eventIndex: index })
611
+ );
612
+ }
613
+
614
+ // packages/core/src/persisted/to-inspect-event.ts
615
+ function compactAttributes3(entries) {
616
+ const out = {};
617
+ for (const [key, value] of Object.entries(entries)) {
618
+ if (value !== void 0) {
619
+ out[key] = value;
620
+ }
621
+ }
622
+ return Object.keys(out).length > 0 ? out : void 0;
623
+ }
624
+ function parseIsoToMs(iso) {
625
+ const parsed = Date.parse(iso);
626
+ if (!Number.isFinite(parsed)) {
627
+ return { ms: 0, invalidTimestamp: true };
628
+ }
629
+ return { ms: parsed, invalidTimestamp: false };
630
+ }
631
+ function mapPersistedSourceToInspect(event) {
632
+ const attrs = event.attributes ?? {};
633
+ const sourceName = event.source.name;
634
+ if (sourceName === "pino") {
635
+ return {
636
+ type: "pino",
637
+ file: typeof attrs.sourceFile === "string" ? attrs.sourceFile : void 0,
638
+ line: typeof attrs.sourceLine === "number" ? attrs.sourceLine : void 0
639
+ };
640
+ }
641
+ if (sourceName === "winston") {
642
+ return {
643
+ type: "winston",
644
+ file: typeof attrs.sourceFile === "string" ? attrs.sourceFile : void 0,
645
+ line: typeof attrs.sourceLine === "number" ? attrs.sourceLine : void 0
646
+ };
647
+ }
648
+ const mapType = (t) => {
649
+ switch (t) {
650
+ case "manual":
651
+ return "manual";
652
+ case "json-log":
653
+ return "json-log";
654
+ case "log4js":
655
+ return "log4js";
656
+ case "adapter":
657
+ case "ai-sdk":
658
+ case "otel":
659
+ return "adapter";
660
+ default:
661
+ return "json-log";
662
+ }
663
+ };
664
+ return {
665
+ type: mapType(event.source.type),
666
+ file: typeof attrs.sourceFile === "string" ? attrs.sourceFile : void 0,
667
+ line: typeof attrs.sourceLine === "number" ? attrs.sourceLine : void 0
668
+ };
669
+ }
670
+ function buildInspectAttributes(event) {
671
+ const attrs = event.attributes !== void 0 ? { ...event.attributes } : {};
672
+ if (event.inputSummary !== void 0) {
673
+ attrs.inputSummary = event.inputSummary;
674
+ }
675
+ if (event.outputSummary !== void 0) {
676
+ attrs.outputSummary = event.outputSummary;
677
+ }
678
+ if (event.error) {
679
+ if (event.error.name !== void 0) {
680
+ attrs.errorName = event.error.name;
681
+ }
682
+ attrs.errorMessage = event.error.message;
683
+ if (event.error.code !== void 0) {
684
+ attrs.errorCode = event.error.code;
685
+ }
686
+ }
687
+ if (event.tokenUsage) {
688
+ attrs.tokens = { ...event.tokenUsage };
689
+ }
690
+ if (event.source.type === "ai-sdk" || event.source.type === "otel") {
691
+ attrs.originalSourceType = event.source.type;
692
+ }
693
+ if (event.source.name !== void 0) {
694
+ attrs.sourceName = event.source.name;
695
+ }
696
+ if (event.source.version !== void 0) {
697
+ attrs.sourceVersion = event.source.version;
698
+ }
699
+ return attrs;
700
+ }
701
+ function persistedInspectEventToInspectEvent(event) {
702
+ if (!isPersistedInspectEvent(event)) {
703
+ throw new Error("Invalid PersistedInspectEvent: failed isPersistedInspectEvent");
704
+ }
705
+ const ts = parseIsoToMs(event.timestamp);
706
+ const attrs = buildInspectAttributes(event);
707
+ if (ts.invalidTimestamp) {
708
+ attrs.invalidTimestamp = true;
709
+ }
710
+ let status;
711
+ if (event.status === "running" || event.status === "ok" || event.status === "error") {
712
+ status = event.status;
713
+ } else if (event.status === "unknown") {
714
+ attrs.persistedStatus = "unknown";
715
+ }
716
+ const out = {
717
+ eventId: event.eventId,
718
+ runId: event.runId,
719
+ name: event.name,
720
+ kind: event.kind,
721
+ timestamp: ts.ms,
722
+ confidence: event.confidence,
723
+ source: mapPersistedSourceToInspect(event),
724
+ attributes: compactAttributes3(attrs)
725
+ };
726
+ if (event.parentId !== void 0) {
727
+ out.parentId = event.parentId;
728
+ }
729
+ if (status !== void 0) {
730
+ out.status = status;
731
+ }
732
+ if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
733
+ out.durationMs = event.durationMs;
734
+ }
735
+ return out;
736
+ }
737
+ function persistedInspectEventsToInspectEvents(events, options) {
738
+ const skipInvalid = options?.skipInvalid === true;
739
+ const out = [];
740
+ for (const event of events) {
741
+ if (!isPersistedInspectEvent(event)) {
742
+ if (skipInvalid) {
743
+ continue;
744
+ }
745
+ throw new Error("Invalid PersistedInspectEvent: failed isPersistedInspectEvent");
746
+ }
747
+ out.push(persistedInspectEventToInspectEvent(event));
748
+ }
749
+ return out;
750
+ }
751
+
752
+ // packages/core/src/logs/tree-builder.ts
753
+ function inc(map, key) {
754
+ map[key] = (map[key] ?? 0) + 1;
755
+ }
756
+ function computeRunStatus(events) {
757
+ let hasRunning = false;
758
+ for (const e of events) {
759
+ if (e.status === "error") return "error";
760
+ if (e.status === "running") hasRunning = true;
761
+ }
762
+ if (hasRunning) return "running";
763
+ return "ok";
764
+ }
765
+ var TreeBuilder = class {
766
+ constructor(options) {
767
+ void options?.config;
768
+ }
769
+ build(events) {
770
+ const byRun = /* @__PURE__ */ new Map();
771
+ for (const e of events) {
772
+ if (!byRun.has(e.runId)) byRun.set(e.runId, []);
773
+ byRun.get(e.runId).push(e);
774
+ }
775
+ const out = [];
776
+ for (const [runId, runEvents] of byRun.entries()) {
777
+ const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
778
+ const nodes = /* @__PURE__ */ new Map();
779
+ for (const e of sorted) {
780
+ nodes.set(e.eventId, { event: e, children: [], depth: 0 });
781
+ }
782
+ const roots = [];
783
+ for (const node of nodes.values()) {
784
+ const parentId = node.event.parentId;
785
+ if (parentId && nodes.has(parentId)) {
786
+ nodes.get(parentId).children.push(node);
787
+ } else {
788
+ roots.push(node);
789
+ }
790
+ }
791
+ const assignDepth = (n, depth) => {
792
+ n.depth = depth;
793
+ for (const c of n.children) assignDepth(c, depth + 1);
794
+ };
795
+ for (const r of roots) assignDepth(r, 0);
796
+ const confidenceBreakdown = {
797
+ explicit: 0,
798
+ correlated: 0,
799
+ heuristic: 0,
800
+ unknown: 0
801
+ };
802
+ const kinds = {};
803
+ for (const e of sorted) {
804
+ inc(confidenceBreakdown, e.confidence);
805
+ kinds[e.kind] = (kinds[e.kind] ?? 0) + 1;
806
+ }
807
+ const startedAt = sorted.length > 0 ? sorted[0].timestamp : void 0;
808
+ const endedAt = sorted.length > 0 ? sorted[sorted.length - 1].timestamp : void 0;
809
+ const status = computeRunStatus(sorted);
810
+ const durationMs = startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt && status !== "running" ? endedAt - startedAt : void 0;
811
+ const name = sorted.find((e) => e.kind === "RUN")?.name;
812
+ out.push({
813
+ runId,
814
+ name,
815
+ status,
816
+ startedAt,
817
+ endedAt: status === "running" ? void 0 : endedAt,
818
+ durationMs,
819
+ children: roots,
820
+ metadata: {
821
+ totalEvents: sorted.length,
822
+ confidenceBreakdown,
823
+ kinds
824
+ }
825
+ });
826
+ }
827
+ out.sort((a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0));
828
+ return out;
829
+ }
830
+ };
831
+
832
+ // packages/core/src/persisted/tree-bridge.ts
833
+ function persistedInspectEventsToRunTrees(events, options) {
834
+ const inspectEvents = persistedInspectEventsToInspectEvents(events, {
835
+ skipInvalid: options?.skipInvalid
836
+ });
837
+ return new TreeBuilder().build(inspectEvents);
838
+ }
839
+ function traceEventsToPersistedRunTrees(events) {
840
+ const persisted = traceEventsToPersistedInspectEvents(events);
841
+ return persistedInspectEventsToRunTrees(persisted);
842
+ }
843
+ function isRecord3(v) {
58
844
  return typeof v === "object" && v !== null && !Array.isArray(v);
59
845
  }
60
846
  function isNonEmptyStringArray(v) {
@@ -66,7 +852,7 @@ function validateRedact(redact) {
66
852
  }
67
853
  for (const r of redact) {
68
854
  if (typeof r === "string") continue;
69
- if (!isRecord2(r)) {
855
+ if (!isRecord3(r)) {
70
856
  throw new Error("Invalid config: redact entries must be strings or objects");
71
857
  }
72
858
  if (typeof r.key !== "string" || r.key.trim() === "") {
@@ -85,7 +871,7 @@ function validateRedact(redact) {
85
871
  }
86
872
  }
87
873
  function validateMappings(mappings) {
88
- if (!isRecord2(mappings)) {
874
+ if (!isRecord3(mappings)) {
89
875
  throw new Error("Invalid config: mappings must be an object");
90
876
  }
91
877
  }
@@ -135,7 +921,7 @@ async function loadLogIngestConfig(configPath) {
135
921
  const msg = e instanceof Error ? e.message : String(e);
136
922
  throw new Error(`Invalid JSON in config file: ${configPath} (${msg})`);
137
923
  }
138
- if (!isRecord2(parsed)) {
924
+ if (!isRecord3(parsed)) {
139
925
  throw new Error("Invalid config: expected a JSON object at top-level");
140
926
  }
141
927
  const user = parsed;
@@ -172,7 +958,7 @@ async function loadLogIngestConfig(configPath) {
172
958
  }
173
959
  return mergeLogIngestConfig(DEFAULT_LOG_INGEST_CONFIG, user);
174
960
  }
175
- function isRecord3(v) {
961
+ function isRecord4(v) {
176
962
  return typeof v === "object" && v !== null && !Array.isArray(v);
177
963
  }
178
964
  var JsonLogParser = class {
@@ -197,7 +983,7 @@ var JsonLogParser = class {
197
983
  });
198
984
  continue;
199
985
  }
200
- if (!isRecord3(parsed)) {
986
+ if (!isRecord4(parsed)) {
201
987
  warnings.push({
202
988
  code: "MALFORMED_JSON",
203
989
  message: "JSON log line must be an object",
@@ -228,7 +1014,7 @@ var JsonLogParser = class {
228
1014
  return this.parseLines(lines, filePath);
229
1015
  }
230
1016
  };
231
- function isRecord4(v) {
1017
+ function isRecord5(v) {
232
1018
  return typeof v === "object" && v !== null && !Array.isArray(v);
233
1019
  }
234
1020
  function findLastJsonObjectSubstring(line) {
@@ -304,7 +1090,7 @@ var Log4jsParser = class {
304
1090
  });
305
1091
  continue;
306
1092
  }
307
- if (!isRecord4(parsed)) {
1093
+ if (!isRecord5(parsed)) {
308
1094
  warnings.push({
309
1095
  code: "UNSUPPORTED_LOG4JS_PAYLOAD",
310
1096
  message: "Embedded JSON payload must be an object",
@@ -382,7 +1168,7 @@ var DEFAULT_REDACT_KEYS = [
382
1168
  "secret",
383
1169
  "email"
384
1170
  ];
385
- function isRecord5(v) {
1171
+ function isRecord6(v) {
386
1172
  return typeof v === "object" && v !== null && !Array.isArray(v);
387
1173
  }
388
1174
  function toKey(s) {
@@ -392,7 +1178,7 @@ function stableHash(value) {
392
1178
  const h = crypto.createHash("sha256").update(value, "utf8").digest("hex");
393
1179
  return h.slice(0, 8);
394
1180
  }
395
- function compileRules(rules) {
1181
+ function compileRules(rules, extraKeys) {
396
1182
  const out = /* @__PURE__ */ new Map();
397
1183
  const set = (r) => {
398
1184
  const k = toKey(r.key);
@@ -401,6 +1187,11 @@ function compileRules(rules) {
401
1187
  for (const k of DEFAULT_REDACT_KEYS) {
402
1188
  set({ key: k, strategy: "full" });
403
1189
  }
1190
+ for (const k of extraKeys ?? []) {
1191
+ if (typeof k === "string" && k.length > 0) {
1192
+ set({ key: k, strategy: "full" });
1193
+ }
1194
+ }
404
1195
  for (const r of rules ?? []) {
405
1196
  if (typeof r === "string") {
406
1197
  set({ key: r, strategy: "full" });
@@ -418,7 +1209,7 @@ function compileRules(rules) {
418
1209
  var Redactor = class {
419
1210
  #rules;
420
1211
  constructor(options) {
421
- this.#rules = compileRules(options?.rules);
1212
+ this.#rules = compileRules(options?.rules, options?.extraKeys);
422
1213
  }
423
1214
  redactValue(key, value) {
424
1215
  const k = toKey(key);
@@ -450,7 +1241,7 @@ var Redactor = class {
450
1241
  if (Array.isArray(value)) {
451
1242
  return value.map((v) => this.#redactNested(v));
452
1243
  }
453
- if (isRecord5(value)) {
1244
+ if (isRecord6(value)) {
454
1245
  const out = {};
455
1246
  for (const [k, v] of Object.entries(value)) {
456
1247
  out[k] = this.redactValue(k, v);
@@ -460,6 +1251,36 @@ var Redactor = class {
460
1251
  return value;
461
1252
  }
462
1253
  };
1254
+
1255
+ // node_modules/.pnpm/nanoid@5.1.11/node_modules/nanoid/url-alphabet/index.js
1256
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
1257
+
1258
+ // node_modules/.pnpm/nanoid@5.1.11/node_modules/nanoid/index.js
1259
+ var POOL_SIZE_MULTIPLIER = 128;
1260
+ var pool;
1261
+ var poolOffset;
1262
+ function fillPool(bytes) {
1263
+ if (bytes < 0 || bytes > 1024) throw new RangeError("Wrong ID size");
1264
+ if (!pool || pool.length < bytes) {
1265
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
1266
+ webcrypto.getRandomValues(pool);
1267
+ poolOffset = 0;
1268
+ } else if (poolOffset + bytes > pool.length) {
1269
+ webcrypto.getRandomValues(pool);
1270
+ poolOffset = 0;
1271
+ }
1272
+ poolOffset += bytes;
1273
+ }
1274
+ function nanoid(size = 21) {
1275
+ fillPool(size |= 0);
1276
+ let id = "";
1277
+ for (let i = poolOffset - size; i < poolOffset; i++) {
1278
+ id += urlAlphabet[pool[i] & 63];
1279
+ }
1280
+ return id;
1281
+ }
1282
+
1283
+ // packages/core/src/logs/normalizer.ts
463
1284
  function isFiniteNumber(v) {
464
1285
  return typeof v === "number" && Number.isFinite(v);
465
1286
  }
@@ -640,86 +1461,6 @@ var EventNormalizer = class {
640
1461
  }
641
1462
  };
642
1463
 
643
- // packages/core/src/logs/tree-builder.ts
644
- function inc(map, key) {
645
- map[key] = (map[key] ?? 0) + 1;
646
- }
647
- function computeRunStatus(events) {
648
- let hasRunning = false;
649
- for (const e of events) {
650
- if (e.status === "error") return "error";
651
- if (e.status === "running") hasRunning = true;
652
- }
653
- if (hasRunning) return "running";
654
- return "ok";
655
- }
656
- var TreeBuilder = class {
657
- constructor(options) {
658
- void options?.config;
659
- }
660
- build(events) {
661
- const byRun = /* @__PURE__ */ new Map();
662
- for (const e of events) {
663
- if (!byRun.has(e.runId)) byRun.set(e.runId, []);
664
- byRun.get(e.runId).push(e);
665
- }
666
- const out = [];
667
- for (const [runId, runEvents] of byRun.entries()) {
668
- const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
669
- const nodes = /* @__PURE__ */ new Map();
670
- for (const e of sorted) {
671
- nodes.set(e.eventId, { event: e, children: [], depth: 0 });
672
- }
673
- const roots = [];
674
- for (const node of nodes.values()) {
675
- const parentId = node.event.parentId;
676
- if (parentId && nodes.has(parentId)) {
677
- nodes.get(parentId).children.push(node);
678
- } else {
679
- roots.push(node);
680
- }
681
- }
682
- const assignDepth = (n, depth) => {
683
- n.depth = depth;
684
- for (const c of n.children) assignDepth(c, depth + 1);
685
- };
686
- for (const r of roots) assignDepth(r, 0);
687
- const confidenceBreakdown = {
688
- explicit: 0,
689
- correlated: 0,
690
- heuristic: 0,
691
- unknown: 0
692
- };
693
- const kinds = {};
694
- for (const e of sorted) {
695
- inc(confidenceBreakdown, e.confidence);
696
- kinds[e.kind] = (kinds[e.kind] ?? 0) + 1;
697
- }
698
- const startedAt = sorted.length > 0 ? sorted[0].timestamp : void 0;
699
- const endedAt = sorted.length > 0 ? sorted[sorted.length - 1].timestamp : void 0;
700
- const status = computeRunStatus(sorted);
701
- const durationMs = startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt && status !== "running" ? endedAt - startedAt : void 0;
702
- const name = sorted.find((e) => e.kind === "RUN")?.name;
703
- out.push({
704
- runId,
705
- name,
706
- status,
707
- startedAt,
708
- endedAt: status === "running" ? void 0 : endedAt,
709
- durationMs,
710
- children: roots,
711
- metadata: {
712
- totalEvents: sorted.length,
713
- confidenceBreakdown,
714
- kinds
715
- }
716
- });
717
- }
718
- out.sort((a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0));
719
- return out;
720
- }
721
- };
722
-
723
1464
  // packages/core/src/logs/tree-renderer.ts
724
1465
  function truncate(v, max) {
725
1466
  if (v.length <= max) return v;
@@ -1173,7 +1914,92 @@ function warn(message, error) {
1173
1914
  }
1174
1915
  console.warn(`${base}: ${formatError(error).message}`);
1175
1916
  }
1176
- function isRecord6(value) {
1917
+
1918
+ // packages/core/src/redaction-profiles.ts
1919
+ var SHARE_PROFILE_EXTRA_KEYS = [
1920
+ "userEmail",
1921
+ "customerEmail",
1922
+ "phone",
1923
+ "phoneNumber",
1924
+ "address",
1925
+ "ip",
1926
+ "ipAddress",
1927
+ "sessionId",
1928
+ "requestId",
1929
+ "correlationId",
1930
+ "decisionId",
1931
+ "groupId",
1932
+ "customerId",
1933
+ "userId",
1934
+ "accountId",
1935
+ "tenantId",
1936
+ "orgId",
1937
+ "organizationId",
1938
+ "traceId",
1939
+ "spanId",
1940
+ "parentSpanId"
1941
+ ];
1942
+ var STRICT_PROFILE_EXTRA_KEYS = [
1943
+ "prompt",
1944
+ "completion",
1945
+ "input",
1946
+ "output",
1947
+ "inputPreview",
1948
+ "outputPreview",
1949
+ "message",
1950
+ "messages",
1951
+ "transcript",
1952
+ "context",
1953
+ "document",
1954
+ "documents",
1955
+ "chunk",
1956
+ "chunks",
1957
+ "retrieval",
1958
+ "query"
1959
+ ];
1960
+ function resolveRedactionProfile(profile = "local") {
1961
+ switch (profile) {
1962
+ case "local":
1963
+ return { profile: "local", extraKeys: [] };
1964
+ case "share":
1965
+ return {
1966
+ profile: "share",
1967
+ extraKeys: SHARE_PROFILE_EXTRA_KEYS,
1968
+ maxMetadataValueLengthCap: 500,
1969
+ maxPreviewLengthCap: 200
1970
+ };
1971
+ case "strict":
1972
+ return {
1973
+ profile: "strict",
1974
+ extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],
1975
+ maxMetadataValueLengthCap: 200,
1976
+ maxPreviewLengthCap: 80
1977
+ };
1978
+ default:
1979
+ return { profile: "local", extraKeys: [] };
1980
+ }
1981
+ }
1982
+ function isPreviewKey(key) {
1983
+ return key.toLowerCase().includes("preview");
1984
+ }
1985
+ function applyProfileMetadataCaps(maxMetadataValueLength, maxPreviewLength, resolved) {
1986
+ let meta = maxMetadataValueLength;
1987
+ let preview = maxPreviewLength;
1988
+ if (resolved.maxMetadataValueLengthCap !== void 0) {
1989
+ meta = Math.min(meta, resolved.maxMetadataValueLengthCap);
1990
+ }
1991
+ if (resolved.maxPreviewLengthCap !== void 0) {
1992
+ preview = Math.min(preview, resolved.maxPreviewLengthCap);
1993
+ }
1994
+ return { maxMetadataValueLength: meta, maxPreviewLength: preview };
1995
+ }
1996
+ function truncateStringForProfile(value, key, maxMetadataValueLength, maxPreviewLength) {
1997
+ const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;
1998
+ if (max <= 0) return "\u2026";
1999
+ if (value.length <= max) return value;
2000
+ return `${value.slice(0, max)}\u2026`;
2001
+ }
2002
+ function isRecord7(value) {
1177
2003
  return typeof value === "object" && value !== null && !Array.isArray(value);
1178
2004
  }
1179
2005
  function nonEmptyString(value) {
@@ -1184,7 +2010,7 @@ function finiteNumber(value) {
1184
2010
  }
1185
2011
  function optionalErrorInfo(value) {
1186
2012
  if (value === void 0) return true;
1187
- if (!isRecord6(value)) return false;
2013
+ if (!isRecord7(value)) return false;
1188
2014
  if (typeof value.message !== "string") return false;
1189
2015
  if ("stack" in value && value.stack !== void 0) {
1190
2016
  if (typeof value.stack !== "string") return false;
@@ -1192,7 +2018,7 @@ function optionalErrorInfo(value) {
1192
2018
  return true;
1193
2019
  }
1194
2020
  function validateEvent(event) {
1195
- if (!isRecord6(event)) return false;
2021
+ if (!isRecord7(event)) return false;
1196
2022
  if (event.schemaVersion !== "0.1") return false;
1197
2023
  if (!finiteNumber(event.timestamp)) return false;
1198
2024
  if (typeof event.event !== "string") return false;
@@ -1201,7 +2027,7 @@ function validateEvent(event) {
1201
2027
  if (!nonEmptyString(event.runId) || !nonEmptyString(event.name) || !finiteNumber(event.startTime)) {
1202
2028
  return false;
1203
2029
  }
1204
- if (event.metadata !== void 0 && !isRecord6(event.metadata)) {
2030
+ if (event.metadata !== void 0 && !isRecord7(event.metadata)) {
1205
2031
  return false;
1206
2032
  }
1207
2033
  return true;
@@ -1216,7 +2042,7 @@ function validateEvent(event) {
1216
2042
  if (event.parentId !== void 0 && typeof event.parentId !== "string") {
1217
2043
  return false;
1218
2044
  }
1219
- if (event.metadata !== void 0 && !isRecord6(event.metadata)) {
2045
+ if (event.metadata !== void 0 && !isRecord7(event.metadata)) {
1220
2046
  return false;
1221
2047
  }
1222
2048
  return true;
@@ -1373,10 +2199,10 @@ function getRunIdFromTraceFileName(fileName) {
1373
2199
  var DEFAULT_MAX_METADATA_VALUE_LENGTH = 2e3;
1374
2200
  var DEFAULT_MAX_PREVIEW_LENGTH = 500;
1375
2201
  var DEFAULT_MAX_EVENT_BYTES = 65536;
1376
- function isRecord7(value) {
2202
+ function isRecord8(value) {
1377
2203
  return typeof value === "object" && value !== null && !Array.isArray(value);
1378
2204
  }
1379
- function isPreviewKey(key) {
2205
+ function isPreviewKey2(key) {
1380
2206
  return key.toLowerCase().includes("preview");
1381
2207
  }
1382
2208
  function truncateString(value, maxLen) {
@@ -1395,15 +2221,32 @@ function resolveTraceSafetyOptions(options) {
1395
2221
  redactEnabled = false;
1396
2222
  } else if (redact === true || redact === void 0) {
1397
2223
  redactEnabled = true;
1398
- } else if (isRecord7(redact)) {
2224
+ } else if (isRecord8(redact)) {
1399
2225
  redactEnabled = true;
1400
2226
  redactionRules = redact.rules;
1401
2227
  }
2228
+ const profile = options?.redactionProfile ?? "local";
2229
+ const resolvedProfile = resolveRedactionProfile(profile);
2230
+ const userMaxMetadata = typeof options?.maxMetadataValueLength === "number" && Number.isFinite(options.maxMetadataValueLength) && options.maxMetadataValueLength >= 0 ? Math.floor(options.maxMetadataValueLength) : void 0;
2231
+ const userMaxPreview = typeof options?.maxPreviewLength === "number" && Number.isFinite(options.maxPreviewLength) && options.maxPreviewLength >= 0 ? Math.floor(options.maxPreviewLength) : void 0;
2232
+ let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;
2233
+ let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;
2234
+ if (redactEnabled && profile !== "local") {
2235
+ const capped = applyProfileMetadataCaps(
2236
+ maxMetadataValueLength,
2237
+ maxPreviewLength,
2238
+ resolvedProfile
2239
+ );
2240
+ maxMetadataValueLength = capped.maxMetadataValueLength;
2241
+ maxPreviewLength = capped.maxPreviewLength;
2242
+ }
1402
2243
  return {
1403
2244
  redactEnabled,
1404
2245
  redactionRules,
1405
- maxMetadataValueLength: typeof options?.maxMetadataValueLength === "number" && Number.isFinite(options.maxMetadataValueLength) && options.maxMetadataValueLength >= 0 ? Math.floor(options.maxMetadataValueLength) : DEFAULT_MAX_METADATA_VALUE_LENGTH,
1406
- maxPreviewLength: typeof options?.maxPreviewLength === "number" && Number.isFinite(options.maxPreviewLength) && options.maxPreviewLength >= 0 ? Math.floor(options.maxPreviewLength) : DEFAULT_MAX_PREVIEW_LENGTH,
2246
+ redactionProfile: profile,
2247
+ profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],
2248
+ maxMetadataValueLength,
2249
+ maxPreviewLength,
1407
2250
  maxEventBytes: typeof options?.maxEventBytes === "number" && Number.isFinite(options.maxEventBytes) && options.maxEventBytes > 0 ? Math.floor(options.maxEventBytes) : DEFAULT_MAX_EVENT_BYTES
1408
2251
  };
1409
2252
  }
@@ -1411,7 +2254,7 @@ function boundMetadataValue(key, value, opts, seen, depth) {
1411
2254
  if (depth > 32) return "[MaxDepth]";
1412
2255
  if (value === null || typeof value !== "object") {
1413
2256
  if (typeof value === "string") {
1414
- const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;
2257
+ const max = isPreviewKey2(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;
1415
2258
  return truncateString(value, max);
1416
2259
  }
1417
2260
  return value;
@@ -1437,7 +2280,10 @@ function boundMetadataValue(key, value, opts, seen, depth) {
1437
2280
  }
1438
2281
  function redactMetadata(metadata, opts) {
1439
2282
  if (!opts.redactEnabled) return { ...metadata };
1440
- const redactor = new Redactor({ rules: opts.redactionRules });
2283
+ const redactor = new Redactor({
2284
+ rules: opts.redactionRules,
2285
+ extraKeys: opts.profileExtraKeys
2286
+ });
1441
2287
  return redactor.redactRecord(metadata);
1442
2288
  }
1443
2289
  function prepareMetadataForDisk(metadata, opts) {
@@ -1451,7 +2297,7 @@ function prepareMetadataForDisk(metadata, opts) {
1451
2297
  seen,
1452
2298
  0
1453
2299
  );
1454
- return isRecord7(bounded) ? bounded : {};
2300
+ return isRecord8(bounded) ? bounded : {};
1455
2301
  } catch {
1456
2302
  return { truncated: true, reason: "metadataPreparationFailed" };
1457
2303
  }
@@ -1609,6 +2455,13 @@ function getCurrentRunId() {
1609
2455
  return void 0;
1610
2456
  }
1611
2457
  }
2458
+ function getCurrentCorrelationMetadata() {
2459
+ try {
2460
+ return extractCorrelationMetadata(storage.getStore()?.metadata);
2461
+ } catch {
2462
+ return void 0;
2463
+ }
2464
+ }
1612
2465
  function getCurrentRunName() {
1613
2466
  try {
1614
2467
  return storage.getStore()?.runName;
@@ -1977,7 +2830,7 @@ var KNOWN_EVENTS = /* @__PURE__ */ new Set([
1977
2830
  "step_started",
1978
2831
  "step_completed"
1979
2832
  ]);
1980
- function isRecord8(value) {
2833
+ function isRecord9(value) {
1981
2834
  return typeof value === "object" && value !== null && !Array.isArray(value);
1982
2835
  }
1983
2836
  function safeParse(line) {
@@ -1999,7 +2852,7 @@ async function isAgentInspectTrace(filePath) {
1999
2852
  if (trimmed === "") continue;
2000
2853
  const parsed = safeParse(trimmed);
2001
2854
  if (!parsed) continue;
2002
- if (!isRecord8(parsed)) continue;
2855
+ if (!isRecord9(parsed)) continue;
2003
2856
  checked += 1;
2004
2857
  if (isTraceEvent(parsed)) return true;
2005
2858
  const ev = parsed.event;
@@ -2162,7 +3015,7 @@ function stableJson(value, pretty) {
2162
3015
  const sorted = sortKeysDeep(value);
2163
3016
  return pretty === true ? JSON.stringify(sorted, null, 2) : JSON.stringify(sorted);
2164
3017
  }
2165
- function compactAttributes(attrs, options) {
3018
+ function compactAttributes4(attrs, options) {
2166
3019
  if (attrs === void 0) return {};
2167
3020
  const maxLen = options?.maxLength ?? 500;
2168
3021
  const redacted = options?.redacted ?? true;
@@ -2517,6 +3370,498 @@ function diffRuns(left, right, options) {
2517
3370
  };
2518
3371
  return { summary, differences };
2519
3372
  }
3373
+
3374
+ // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
3375
+ var ANSI_BACKGROUND_OFFSET = 10;
3376
+ var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
3377
+ var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
3378
+ var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
3379
+ var styles = {
3380
+ modifier: {
3381
+ reset: [0, 0],
3382
+ // 21 isn't widely supported and 22 does the same thing
3383
+ bold: [1, 22],
3384
+ dim: [2, 22],
3385
+ italic: [3, 23],
3386
+ underline: [4, 24],
3387
+ overline: [53, 55],
3388
+ inverse: [7, 27],
3389
+ hidden: [8, 28],
3390
+ strikethrough: [9, 29]
3391
+ },
3392
+ color: {
3393
+ black: [30, 39],
3394
+ red: [31, 39],
3395
+ green: [32, 39],
3396
+ yellow: [33, 39],
3397
+ blue: [34, 39],
3398
+ magenta: [35, 39],
3399
+ cyan: [36, 39],
3400
+ white: [37, 39],
3401
+ // Bright color
3402
+ blackBright: [90, 39],
3403
+ gray: [90, 39],
3404
+ // Alias of `blackBright`
3405
+ grey: [90, 39],
3406
+ // Alias of `blackBright`
3407
+ redBright: [91, 39],
3408
+ greenBright: [92, 39],
3409
+ yellowBright: [93, 39],
3410
+ blueBright: [94, 39],
3411
+ magentaBright: [95, 39],
3412
+ cyanBright: [96, 39],
3413
+ whiteBright: [97, 39]
3414
+ },
3415
+ bgColor: {
3416
+ bgBlack: [40, 49],
3417
+ bgRed: [41, 49],
3418
+ bgGreen: [42, 49],
3419
+ bgYellow: [43, 49],
3420
+ bgBlue: [44, 49],
3421
+ bgMagenta: [45, 49],
3422
+ bgCyan: [46, 49],
3423
+ bgWhite: [47, 49],
3424
+ // Bright color
3425
+ bgBlackBright: [100, 49],
3426
+ bgGray: [100, 49],
3427
+ // Alias of `bgBlackBright`
3428
+ bgGrey: [100, 49],
3429
+ // Alias of `bgBlackBright`
3430
+ bgRedBright: [101, 49],
3431
+ bgGreenBright: [102, 49],
3432
+ bgYellowBright: [103, 49],
3433
+ bgBlueBright: [104, 49],
3434
+ bgMagentaBright: [105, 49],
3435
+ bgCyanBright: [106, 49],
3436
+ bgWhiteBright: [107, 49]
3437
+ }
3438
+ };
3439
+ Object.keys(styles.modifier);
3440
+ var foregroundColorNames = Object.keys(styles.color);
3441
+ var backgroundColorNames = Object.keys(styles.bgColor);
3442
+ [...foregroundColorNames, ...backgroundColorNames];
3443
+ function assembleStyles() {
3444
+ const codes = /* @__PURE__ */ new Map();
3445
+ for (const [groupName, group] of Object.entries(styles)) {
3446
+ for (const [styleName, style] of Object.entries(group)) {
3447
+ styles[styleName] = {
3448
+ open: `\x1B[${style[0]}m`,
3449
+ close: `\x1B[${style[1]}m`
3450
+ };
3451
+ group[styleName] = styles[styleName];
3452
+ codes.set(style[0], style[1]);
3453
+ }
3454
+ Object.defineProperty(styles, groupName, {
3455
+ value: group,
3456
+ enumerable: false
3457
+ });
3458
+ }
3459
+ Object.defineProperty(styles, "codes", {
3460
+ value: codes,
3461
+ enumerable: false
3462
+ });
3463
+ styles.color.close = "\x1B[39m";
3464
+ styles.bgColor.close = "\x1B[49m";
3465
+ styles.color.ansi = wrapAnsi16();
3466
+ styles.color.ansi256 = wrapAnsi256();
3467
+ styles.color.ansi16m = wrapAnsi16m();
3468
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
3469
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
3470
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
3471
+ Object.defineProperties(styles, {
3472
+ rgbToAnsi256: {
3473
+ value(red, green, blue) {
3474
+ if (red === green && green === blue) {
3475
+ if (red < 8) {
3476
+ return 16;
3477
+ }
3478
+ if (red > 248) {
3479
+ return 231;
3480
+ }
3481
+ return Math.round((red - 8) / 247 * 24) + 232;
3482
+ }
3483
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
3484
+ },
3485
+ enumerable: false
3486
+ },
3487
+ hexToRgb: {
3488
+ value(hex) {
3489
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
3490
+ if (!matches) {
3491
+ return [0, 0, 0];
3492
+ }
3493
+ let [colorString] = matches;
3494
+ if (colorString.length === 3) {
3495
+ colorString = [...colorString].map((character) => character + character).join("");
3496
+ }
3497
+ const integer = Number.parseInt(colorString, 16);
3498
+ return [
3499
+ /* eslint-disable no-bitwise */
3500
+ integer >> 16 & 255,
3501
+ integer >> 8 & 255,
3502
+ integer & 255
3503
+ /* eslint-enable no-bitwise */
3504
+ ];
3505
+ },
3506
+ enumerable: false
3507
+ },
3508
+ hexToAnsi256: {
3509
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
3510
+ enumerable: false
3511
+ },
3512
+ ansi256ToAnsi: {
3513
+ value(code) {
3514
+ if (code < 8) {
3515
+ return 30 + code;
3516
+ }
3517
+ if (code < 16) {
3518
+ return 90 + (code - 8);
3519
+ }
3520
+ let red;
3521
+ let green;
3522
+ let blue;
3523
+ if (code >= 232) {
3524
+ red = ((code - 232) * 10 + 8) / 255;
3525
+ green = red;
3526
+ blue = red;
3527
+ } else {
3528
+ code -= 16;
3529
+ const remainder = code % 36;
3530
+ red = Math.floor(code / 36) / 5;
3531
+ green = Math.floor(remainder / 6) / 5;
3532
+ blue = remainder % 6 / 5;
3533
+ }
3534
+ const value = Math.max(red, green, blue) * 2;
3535
+ if (value === 0) {
3536
+ return 30;
3537
+ }
3538
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
3539
+ if (value === 2) {
3540
+ result += 60;
3541
+ }
3542
+ return result;
3543
+ },
3544
+ enumerable: false
3545
+ },
3546
+ rgbToAnsi: {
3547
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
3548
+ enumerable: false
3549
+ },
3550
+ hexToAnsi: {
3551
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
3552
+ enumerable: false
3553
+ }
3554
+ });
3555
+ return styles;
3556
+ }
3557
+ var ansiStyles = assembleStyles();
3558
+ var ansi_styles_default = ansiStyles;
3559
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
3560
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
3561
+ const position = argv.indexOf(prefix + flag);
3562
+ const terminatorPosition = argv.indexOf("--");
3563
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
3564
+ }
3565
+ var { env } = process2;
3566
+ var flagForceColor;
3567
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
3568
+ flagForceColor = 0;
3569
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
3570
+ flagForceColor = 1;
3571
+ }
3572
+ function envForceColor() {
3573
+ if ("FORCE_COLOR" in env) {
3574
+ if (env.FORCE_COLOR === "true") {
3575
+ return 1;
3576
+ }
3577
+ if (env.FORCE_COLOR === "false") {
3578
+ return 0;
3579
+ }
3580
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
3581
+ }
3582
+ }
3583
+ function translateLevel(level) {
3584
+ if (level === 0) {
3585
+ return false;
3586
+ }
3587
+ return {
3588
+ level,
3589
+ hasBasic: true,
3590
+ has256: level >= 2,
3591
+ has16m: level >= 3
3592
+ };
3593
+ }
3594
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
3595
+ const noFlagForceColor = envForceColor();
3596
+ if (noFlagForceColor !== void 0) {
3597
+ flagForceColor = noFlagForceColor;
3598
+ }
3599
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
3600
+ if (forceColor === 0) {
3601
+ return 0;
3602
+ }
3603
+ if (sniffFlags) {
3604
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
3605
+ return 3;
3606
+ }
3607
+ if (hasFlag("color=256")) {
3608
+ return 2;
3609
+ }
3610
+ }
3611
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
3612
+ return 1;
3613
+ }
3614
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
3615
+ return 0;
3616
+ }
3617
+ const min = forceColor || 0;
3618
+ if (env.TERM === "dumb") {
3619
+ return min;
3620
+ }
3621
+ if (process2.platform === "win32") {
3622
+ const osRelease = os.release().split(".");
3623
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
3624
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
3625
+ }
3626
+ return 1;
3627
+ }
3628
+ if ("CI" in env) {
3629
+ if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
3630
+ return 3;
3631
+ }
3632
+ if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
3633
+ return 1;
3634
+ }
3635
+ return min;
3636
+ }
3637
+ if ("TEAMCITY_VERSION" in env) {
3638
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
3639
+ }
3640
+ if (env.COLORTERM === "truecolor") {
3641
+ return 3;
3642
+ }
3643
+ if (env.TERM === "xterm-kitty") {
3644
+ return 3;
3645
+ }
3646
+ if (env.TERM === "xterm-ghostty") {
3647
+ return 3;
3648
+ }
3649
+ if (env.TERM === "wezterm") {
3650
+ return 3;
3651
+ }
3652
+ if ("TERM_PROGRAM" in env) {
3653
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
3654
+ switch (env.TERM_PROGRAM) {
3655
+ case "iTerm.app": {
3656
+ return version >= 3 ? 3 : 2;
3657
+ }
3658
+ case "Apple_Terminal": {
3659
+ return 2;
3660
+ }
3661
+ }
3662
+ }
3663
+ if (/-256(color)?$/i.test(env.TERM)) {
3664
+ return 2;
3665
+ }
3666
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
3667
+ return 1;
3668
+ }
3669
+ if ("COLORTERM" in env) {
3670
+ return 1;
3671
+ }
3672
+ return min;
3673
+ }
3674
+ function createSupportsColor(stream, options = {}) {
3675
+ const level = _supportsColor(stream, {
3676
+ streamIsTTY: stream && stream.isTTY,
3677
+ ...options
3678
+ });
3679
+ return translateLevel(level);
3680
+ }
3681
+ var supportsColor = {
3682
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
3683
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
3684
+ };
3685
+ var supports_color_default = supportsColor;
3686
+
3687
+ // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js
3688
+ function stringReplaceAll(string, substring, replacer) {
3689
+ let index = string.indexOf(substring);
3690
+ if (index === -1) {
3691
+ return string;
3692
+ }
3693
+ const substringLength = substring.length;
3694
+ let endIndex = 0;
3695
+ let returnValue = "";
3696
+ do {
3697
+ returnValue += string.slice(endIndex, index) + substring + replacer;
3698
+ endIndex = index + substringLength;
3699
+ index = string.indexOf(substring, endIndex);
3700
+ } while (index !== -1);
3701
+ returnValue += string.slice(endIndex);
3702
+ return returnValue;
3703
+ }
3704
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
3705
+ let endIndex = 0;
3706
+ let returnValue = "";
3707
+ do {
3708
+ const gotCR = string[index - 1] === "\r";
3709
+ returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
3710
+ endIndex = index + 1;
3711
+ index = string.indexOf("\n", endIndex);
3712
+ } while (index !== -1);
3713
+ returnValue += string.slice(endIndex);
3714
+ return returnValue;
3715
+ }
3716
+
3717
+ // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js
3718
+ var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
3719
+ var GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
3720
+ var STYLER = /* @__PURE__ */ Symbol("STYLER");
3721
+ var IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
3722
+ var levelMapping = [
3723
+ "ansi",
3724
+ "ansi",
3725
+ "ansi256",
3726
+ "ansi16m"
3727
+ ];
3728
+ var styles2 = /* @__PURE__ */ Object.create(null);
3729
+ var applyOptions = (object, options = {}) => {
3730
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
3731
+ throw new Error("The `level` option should be an integer from 0 to 3");
3732
+ }
3733
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
3734
+ object.level = options.level === void 0 ? colorLevel : options.level;
3735
+ };
3736
+ var chalkFactory = (options) => {
3737
+ const chalk2 = (...strings) => strings.join(" ");
3738
+ applyOptions(chalk2, options);
3739
+ Object.setPrototypeOf(chalk2, createChalk.prototype);
3740
+ return chalk2;
3741
+ };
3742
+ function createChalk(options) {
3743
+ return chalkFactory(options);
3744
+ }
3745
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
3746
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
3747
+ styles2[styleName] = {
3748
+ get() {
3749
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
3750
+ Object.defineProperty(this, styleName, { value: builder });
3751
+ return builder;
3752
+ }
3753
+ };
3754
+ }
3755
+ styles2.visible = {
3756
+ get() {
3757
+ const builder = createBuilder(this, this[STYLER], true);
3758
+ Object.defineProperty(this, "visible", { value: builder });
3759
+ return builder;
3760
+ }
3761
+ };
3762
+ var getModelAnsi = (model, level, type, ...arguments_) => {
3763
+ if (model === "rgb") {
3764
+ if (level === "ansi16m") {
3765
+ return ansi_styles_default[type].ansi16m(...arguments_);
3766
+ }
3767
+ if (level === "ansi256") {
3768
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
3769
+ }
3770
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
3771
+ }
3772
+ if (model === "hex") {
3773
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
3774
+ }
3775
+ return ansi_styles_default[type][model](...arguments_);
3776
+ };
3777
+ var usedModels = ["rgb", "hex", "ansi256"];
3778
+ for (const model of usedModels) {
3779
+ styles2[model] = {
3780
+ get() {
3781
+ const { level } = this;
3782
+ return function(...arguments_) {
3783
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
3784
+ return createBuilder(this, styler, this[IS_EMPTY]);
3785
+ };
3786
+ }
3787
+ };
3788
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
3789
+ styles2[bgModel] = {
3790
+ get() {
3791
+ const { level } = this;
3792
+ return function(...arguments_) {
3793
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
3794
+ return createBuilder(this, styler, this[IS_EMPTY]);
3795
+ };
3796
+ }
3797
+ };
3798
+ }
3799
+ var proto = Object.defineProperties(() => {
3800
+ }, {
3801
+ ...styles2,
3802
+ level: {
3803
+ enumerable: true,
3804
+ get() {
3805
+ return this[GENERATOR].level;
3806
+ },
3807
+ set(level) {
3808
+ this[GENERATOR].level = level;
3809
+ }
3810
+ }
3811
+ });
3812
+ var createStyler = (open, close, parent) => {
3813
+ let openAll;
3814
+ let closeAll;
3815
+ if (parent === void 0) {
3816
+ openAll = open;
3817
+ closeAll = close;
3818
+ } else {
3819
+ openAll = parent.openAll + open;
3820
+ closeAll = close + parent.closeAll;
3821
+ }
3822
+ return {
3823
+ open,
3824
+ close,
3825
+ openAll,
3826
+ closeAll,
3827
+ parent
3828
+ };
3829
+ };
3830
+ var createBuilder = (self, _styler, _isEmpty) => {
3831
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
3832
+ Object.setPrototypeOf(builder, proto);
3833
+ builder[GENERATOR] = self;
3834
+ builder[STYLER] = _styler;
3835
+ builder[IS_EMPTY] = _isEmpty;
3836
+ return builder;
3837
+ };
3838
+ var applyStyle = (self, string) => {
3839
+ if (self.level <= 0 || !string) {
3840
+ return self[IS_EMPTY] ? "" : string;
3841
+ }
3842
+ let styler = self[STYLER];
3843
+ if (styler === void 0) {
3844
+ return string;
3845
+ }
3846
+ const { openAll, closeAll } = styler;
3847
+ if (string.includes("\x1B")) {
3848
+ while (styler !== void 0) {
3849
+ string = stringReplaceAll(string, styler.close, styler.open);
3850
+ styler = styler.parent;
3851
+ }
3852
+ }
3853
+ const lfIndex = string.indexOf("\n");
3854
+ if (lfIndex !== -1) {
3855
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
3856
+ }
3857
+ return openAll + string + closeAll;
3858
+ };
3859
+ Object.defineProperties(createChalk.prototype, styles2);
3860
+ var chalk = createChalk();
3861
+ createChalk({ level: stderrColor ? stderrColor.level : 0 });
3862
+ var source_default = chalk;
3863
+
3864
+ // packages/core/src/diff/renderer.ts
2520
3865
  function formatPath(path5) {
2521
3866
  if (path5 === void 0 || path5.path.length === 0) {
2522
3867
  return "(run)";
@@ -2540,9 +3885,9 @@ function renderRunDiff(result, options) {
2540
3885
  }
2541
3886
  const sev = (s, level) => {
2542
3887
  if (!color) return s;
2543
- if (level === "error") return chalk2.red(s);
2544
- if (level === "warning") return chalk2.yellow(s);
2545
- return chalk2.gray(s);
3888
+ if (level === "error") return source_default.red(s);
3889
+ if (level === "warning") return source_default.yellow(s);
3890
+ return source_default.gray(s);
2546
3891
  };
2547
3892
  const lines = [];
2548
3893
  const { summary } = result;
@@ -2605,6 +3950,8 @@ function diffTraceEvents(leftEvents, rightEvents, options) {
2605
3950
  const right = manualTraceEventsToComparableRun(rightEvents);
2606
3951
  return diffRuns(left, right, options);
2607
3952
  }
3953
+
3954
+ // packages/core/src/terminal.ts
2608
3955
  var TERMINAL_INDENT = " ";
2609
3956
  var MAX_TERMINAL_NAME_LENGTH = 80;
2610
3957
  var MAX_TERMINAL_DEPTH = 10;
@@ -2630,24 +3977,24 @@ function formatTerminalName(name) {
2630
3977
  return truncateName(name, MAX_TERMINAL_NAME_LENGTH);
2631
3978
  }
2632
3979
  function getStatusIcon(status) {
2633
- if (status === "success") return chalk2.green("\u2714");
2634
- if (status === "error") return chalk2.red("\u2716");
2635
- return chalk2.yellow("\u23F3");
3980
+ if (status === "success") return source_default.green("\u2714");
3981
+ if (status === "error") return source_default.red("\u2716");
3982
+ return source_default.yellow("\u23F3");
2636
3983
  }
2637
3984
  function renderStepLine(name, durationMs, status, depth) {
2638
3985
  try {
2639
3986
  const nm = formatTerminalName(name);
2640
3987
  const ind = getIndent(depth ?? 0);
2641
3988
  if (status === "running" && durationMs === void 0) {
2642
- return `${ind}${chalk2.yellow("\u23F3")} ${nm}`;
3989
+ return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
2643
3990
  }
2644
3991
  const hasDur = durationMs !== void 0 && Number.isFinite(durationMs);
2645
3992
  const dur = hasDur ? formatDuration2(durationMs) : void 0;
2646
3993
  if (status === "running") {
2647
- return dur !== void 0 ? `${ind}${chalk2.yellow("\u23F3")} ${nm} (${dur})` : `${ind}${chalk2.yellow("\u23F3")} ${nm}`;
3994
+ return dur !== void 0 ? `${ind}${source_default.yellow("\u23F3")} ${nm} (${dur})` : `${ind}${source_default.yellow("\u23F3")} ${nm}`;
2648
3995
  }
2649
3996
  if (!hasDur || dur === void 0) {
2650
- return `${ind}${chalk2.yellow("\u23F3")} ${nm}`;
3997
+ return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
2651
3998
  }
2652
3999
  if (status === "success") {
2653
4000
  return `${ind}${getStatusIcon("success")} ${nm} (${dur})`;
@@ -2683,7 +4030,7 @@ function printRunStart(runId, name) {
2683
4030
  if (isSilentContext()) return;
2684
4031
  try {
2685
4032
  safePrint("");
2686
- const header = `${chalk2.cyan.bold("\u{1F50D} AgentInspect:")} ${formatTerminalName(name)} ${chalk2.dim(`(${runId})`)}`;
4033
+ const header = `${source_default.cyan.bold("\u{1F50D} AgentInspect:")} ${formatTerminalName(name)} ${source_default.dim(`(${runId})`)}`;
2687
4034
  safePrint(header);
2688
4035
  } catch {
2689
4036
  }
@@ -2716,10 +4063,10 @@ function printRunComplete(_name, _runId, durationMs, status, traceFilePath) {
2716
4063
  for (let i = 0; i < lines.length; i++) {
2717
4064
  const line = lines[i];
2718
4065
  if (i === 0) {
2719
- const color = status === "error" ? chalk2.red : status === "running" ? chalk2.yellow : chalk2.green;
4066
+ const color = status === "error" ? source_default.red : status === "running" ? source_default.yellow : source_default.green;
2720
4067
  safePrint(color(line));
2721
4068
  } else {
2722
- safePrint(chalk2.dim(line));
4069
+ safePrint(source_default.dim(line));
2723
4070
  }
2724
4071
  }
2725
4072
  } catch {
@@ -2758,12 +4105,13 @@ async function inspectRun(name, fn, options) {
2758
4105
  const runId = createRunId();
2759
4106
  const traceDir = resolveTraceDir({ dir: options?.traceDir });
2760
4107
  const traceSafety = resolveTraceSafetyOptions(options);
4108
+ const runMetadata = buildRunStartedMetadata(options);
2761
4109
  const context = {
2762
4110
  runId,
2763
4111
  runName,
2764
4112
  traceDir,
2765
4113
  silent: options?.silent ?? false,
2766
- metadata: options?.metadata
4114
+ metadata: runMetadata
2767
4115
  };
2768
4116
  return runWithContext(context, async () => {
2769
4117
  const startTime = Date.now();
@@ -2779,7 +4127,7 @@ async function inspectRun(name, fn, options) {
2779
4127
  runId,
2780
4128
  name: runName,
2781
4129
  startTime,
2782
- ...options?.metadata !== void 0 ? { metadata: options.metadata } : {}
4130
+ ...runMetadata !== void 0 ? { metadata: runMetadata } : {}
2783
4131
  };
2784
4132
  await writeTraceEvent(
2785
4133
  prepareTraceEventForDisk(started, traceSafety),
@@ -3064,6 +4412,134 @@ function observe(agent, options) {
3064
4412
  // packages/core/src/exporters/types.ts
3065
4413
  var EXPORT_PAYLOAD_VERSION = "0.1.2";
3066
4414
 
4415
+ // packages/core/src/exporters/redact-export.ts
4416
+ function isRecord10(value) {
4417
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4418
+ }
4419
+ function deepClone(value) {
4420
+ if (value === null || typeof value !== "object") {
4421
+ return value;
4422
+ }
4423
+ if (Array.isArray(value)) {
4424
+ return value.map((item) => deepClone(item));
4425
+ }
4426
+ const out = {};
4427
+ for (const [k, v] of Object.entries(value)) {
4428
+ out[k] = deepClone(v);
4429
+ }
4430
+ return out;
4431
+ }
4432
+ function boundAttributeValues(record, maxMetadataValueLength, maxPreviewLength, seen, depth) {
4433
+ if (depth > 32) {
4434
+ return { truncated: true, reason: "maxDepth" };
4435
+ }
4436
+ const out = {};
4437
+ for (const [key, value] of Object.entries(record)) {
4438
+ out[key] = boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen, depth);
4439
+ }
4440
+ return out;
4441
+ }
4442
+ function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen, depth) {
4443
+ if (value === null || typeof value !== "object") {
4444
+ if (typeof value === "string") {
4445
+ return truncateStringForProfile(
4446
+ value,
4447
+ key,
4448
+ maxMetadataValueLength,
4449
+ maxPreviewLength
4450
+ );
4451
+ }
4452
+ return value;
4453
+ }
4454
+ if (seen.has(value)) return "[Circular]";
4455
+ seen.add(value);
4456
+ if (Array.isArray(value)) {
4457
+ return value.slice(0, 50).map(
4458
+ (item, index) => boundValue(
4459
+ item,
4460
+ String(index),
4461
+ maxMetadataValueLength,
4462
+ maxPreviewLength,
4463
+ seen,
4464
+ depth + 1
4465
+ )
4466
+ );
4467
+ }
4468
+ return boundAttributeValues(
4469
+ value,
4470
+ maxMetadataValueLength,
4471
+ maxPreviewLength,
4472
+ seen,
4473
+ depth + 1
4474
+ );
4475
+ }
4476
+ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPreviewLength) {
4477
+ if (!attrs || Object.keys(attrs).length === 0) {
4478
+ return attrs;
4479
+ }
4480
+ const redacted = redactor.redactRecord(attrs);
4481
+ const seen = /* @__PURE__ */ new WeakSet();
4482
+ const bounded = boundAttributeValues(
4483
+ redacted,
4484
+ maxMetadataValueLength,
4485
+ maxPreviewLength,
4486
+ seen,
4487
+ 0
4488
+ );
4489
+ const err = bounded.error;
4490
+ if (isRecord10(err) && typeof err.message === "string") {
4491
+ bounded.error = {
4492
+ ...err,
4493
+ message: truncateStringForProfile(
4494
+ err.message,
4495
+ "message",
4496
+ maxMetadataValueLength,
4497
+ maxPreviewLength
4498
+ ),
4499
+ ...typeof err.stack === "string" ? {
4500
+ stack: truncateStringForProfile(
4501
+ err.stack,
4502
+ "stack",
4503
+ maxMetadataValueLength,
4504
+ maxPreviewLength
4505
+ )
4506
+ } : {}
4507
+ };
4508
+ }
4509
+ return bounded;
4510
+ }
4511
+ function redactRunTreeForExport(tree, options) {
4512
+ const profile = options?.redactionProfile ?? "local";
4513
+ if (profile === "local") {
4514
+ return deepClone(tree);
4515
+ }
4516
+ const resolved = resolveRedactionProfile(profile);
4517
+ const { maxMetadataValueLength, maxPreviewLength } = applyProfileMetadataCaps(
4518
+ 2e3,
4519
+ 500,
4520
+ resolved
4521
+ );
4522
+ const redactor = new Redactor({ extraKeys: resolved.extraKeys });
4523
+ const clone = deepClone(tree);
4524
+ function walk(nodes) {
4525
+ for (const node of nodes) {
4526
+ if (node.event.attributes !== void 0) {
4527
+ node.event.attributes = redactEventAttributes(
4528
+ node.event.attributes,
4529
+ redactor,
4530
+ maxMetadataValueLength,
4531
+ maxPreviewLength
4532
+ );
4533
+ }
4534
+ if (node.children.length > 0) {
4535
+ walk(node.children);
4536
+ }
4537
+ }
4538
+ }
4539
+ walk(clone.children);
4540
+ return clone;
4541
+ }
4542
+
3067
4543
  // packages/core/src/exporters/html-exporter.ts
3068
4544
  function renderTreeHtml(nodes, ulClass = "tree") {
3069
4545
  if (nodes.length === 0) return "";
@@ -3150,7 +4626,7 @@ function exportHtml(tree, options) {
3150
4626
  attrsHtml += "<h2>Attributes (bounded)</h2>";
3151
4627
  for (const n of flat) {
3152
4628
  if (!n.event.attributes || Object.keys(n.event.attributes).length === 0) continue;
3153
- const compact = compactAttributes(n.event.attributes, {
4629
+ const compact = compactAttributes4(n.event.attributes, {
3154
4630
  maxLength: maxLen,
3155
4631
  redacted
3156
4632
  });
@@ -3301,7 +4777,7 @@ function exportMarkdown(tree, options) {
3301
4777
  lines.push("");
3302
4778
  for (const n of flat) {
3303
4779
  if (!n.event.attributes || Object.keys(n.event.attributes).length === 0) continue;
3304
- const compact = compactAttributes(n.event.attributes, {
4780
+ const compact = compactAttributes4(n.event.attributes, {
3305
4781
  maxLength: maxLen,
3306
4782
  redacted
3307
4783
  });
@@ -3800,20 +5276,22 @@ function mergeExportDefaults(options) {
3800
5276
  includeErrors: options.includeErrors ?? true,
3801
5277
  pretty: options.pretty ?? true,
3802
5278
  redacted: options.redacted ?? true,
3803
- maxAttributeLength: options.maxAttributeLength ?? 500
5279
+ maxAttributeLength: options.maxAttributeLength ?? 500,
5280
+ redactionProfile: options.redactionProfile ?? "local"
3804
5281
  };
3805
5282
  }
3806
5283
  function exportRunTree(tree, options) {
3807
5284
  const opts = mergeExportDefaults(options);
5285
+ const exportTree = opts.redactionProfile === "local" ? tree : redactRunTreeForExport(tree, { redactionProfile: opts.redactionProfile });
3808
5286
  switch (opts.format) {
3809
5287
  case "markdown":
3810
- return exportMarkdown(tree, opts);
5288
+ return exportMarkdown(exportTree, opts);
3811
5289
  case "html":
3812
- return exportHtml(tree, opts);
5290
+ return exportHtml(exportTree, opts);
3813
5291
  case "openinference":
3814
- return exportOpenInference(tree, opts);
5292
+ return exportOpenInference(exportTree, opts);
3815
5293
  case "otlp-json":
3816
- return exportOtlpJson(tree, opts);
5294
+ return exportOtlpJson(exportTree, opts);
3817
5295
  default: {
3818
5296
  const _x = opts.format;
3819
5297
  throw new Error(`Unsupported export format: ${String(_x)}`);
@@ -3830,6 +5308,6 @@ function validateExport(result) {
3830
5308
  };
3831
5309
  }
3832
5310
 
3833
- export { DEFAULT_LOG_INGEST_CONFIG, DEFAULT_MAX_EVENT_BYTES, DEFAULT_MAX_METADATA_VALUE_LENGTH, DEFAULT_MAX_PREVIEW_LENGTH, DEFAULT_REDACT_KEYS, DEFAULT_TRACE_DIR_NAME, EXPORT_PAYLOAD_VERSION, EventNormalizer, FALLBACK_TRACE_DIR, JsonLogParser, LiveLogAccumulator, Log4jsParser, MAX_NAME_LENGTH, MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, RUNS_DIR_NAME, Redactor, TERMINAL_INDENT, TraceDirectory, TreeBuilder, buildRunSummary, compactAttributes, createRunId, createStepId, diffRuns, diffTraceEvents, ensureTraceDir, escapeHtml, escapeMarkdown, exportHtml, exportMarkdown, exportOpenInference, exportOtlpJson, exportRunTree, extractMetadata, filterTraces, flattenTree, formatDuration2 as formatDuration, formatError, formatTerminalName, formatTimestamp, getCurrentContext, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getDefaultTraceDir, getIndent, getParentStepId, getRunIdFromTraceFileName, getTraceDirFromContext, getTraceFilePath, getTraceSafetyFromContext, hasActiveContext, initializeTraceFile, inspectRun, isAgentInspectEnabled, isAgentInspectTrace, isSilentContext, isStepStatus, isStepType, isTraceEvent, listTraceFiles, loadLogIngestConfig, manualTraceEventsToComparableRun, manualTraceEventsToRunTree, matchMapping, maybeInspectRun, mergeExportDefaults, mergeLogIngestConfig, observe, parseDuration, parseLogLine, parseLogsToTrees, prepareMetadataForDisk, prepareTraceEventForDisk, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, readTraceEvents, readTraceFile, renderErrorLine, renderRunDiff, renderRunSummary, renderRunTree, renderRunTrees, renderStepLine, resolveTraceDir, resolveTraceSafetyOptions, runWithContext, runWithStepContext, safeString2 as safeString, serializeEvent, stableJson, step, summarizeTree, truncateName, validateEvent, validateExport, validateExportContent, warn, wildcardMatch, writeTraceEvent };
5311
+ export { DEFAULT_LOG_INGEST_CONFIG, DEFAULT_MAX_EVENT_BYTES, DEFAULT_MAX_METADATA_VALUE_LENGTH, DEFAULT_MAX_PREVIEW_LENGTH, DEFAULT_REDACT_KEYS, DEFAULT_TRACE_DIR_NAME, EXPORT_PAYLOAD_VERSION, EventNormalizer, FALLBACK_TRACE_DIR, JsonLogParser, LiveLogAccumulator, Log4jsParser, MAX_NAME_LENGTH, MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, RUNS_DIR_NAME, Redactor, TERMINAL_INDENT, TraceDirectory, TreeBuilder, buildRunSummary, compactAttributes4 as compactAttributes, createRunId, createStepId, diffRuns, diffTraceEvents, ensureTraceDir, escapeHtml, escapeMarkdown, exportHtml, exportMarkdown, exportOpenInference, exportOtlpJson, exportRunTree, extractMetadata, filterTraces, flattenTree, formatDuration2 as formatDuration, formatError, formatTerminalName, formatTimestamp, getCurrentContext, getCurrentCorrelationMetadata, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getDefaultTraceDir, getIndent, getParentStepId, getRunIdFromTraceFileName, getTraceDirFromContext, getTraceFilePath, getTraceSafetyFromContext, hasActiveContext, initializeTraceFile, inspectEventToPersistedInspectEvent, inspectEventsToPersistedInspectEvents, inspectRun, isAgentInspectEnabled, isAgentInspectTrace, isPersistedInspectEvent, isSilentContext, isStepStatus, isStepType, isTraceEvent, listTraceFiles, loadLogIngestConfig, manualTraceEventsToComparableRun, manualTraceEventsToRunTree, matchMapping, maybeInspectRun, mergeExportDefaults, mergeLogIngestConfig, observe, parseDuration, parseLogLine, parseLogsToTrees, persistedInspectEventToInspectEvent, persistedInspectEventsToInspectEvents, persistedInspectEventsToRunTrees, prepareMetadataForDisk, prepareTraceEventForDisk, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, readTraceEvents, readTraceFile, redactRunTreeForExport, renderErrorLine, renderRunDiff, renderRunSummary, renderRunTree, renderRunTrees, renderStepLine, resolveRedactionProfile, resolveTraceDir, resolveTraceSafetyOptions, runWithContext, runWithStepContext, safeString2 as safeString, serializeEvent, stableJson, step, summarizeTree, traceEventToPersistedInspectEvent, traceEventsToPersistedInspectEvents, traceEventsToPersistedRunTrees, truncateName, validateEvent, validateExport, validateExportContent, warn, wildcardMatch, writeTraceEvent };
3834
5312
  //# sourceMappingURL=index.mjs.map
3835
5313
  //# sourceMappingURL=index.mjs.map