agent-inspect 6.31.21 → 6.31.23

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/packages/cli/dist/{chunk-N5JN26MW.mjs → chunk-P27XTK5U.mjs} +347 -36
  5. package/packages/cli/dist/chunk-P27XTK5U.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +434 -63
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +81 -33
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-VMGRSTG7.mjs → src-EWZYLDST.mjs} +3 -3
  11. package/packages/cli/dist/{src-VMGRSTG7.mjs.map → src-EWZYLDST.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +280 -10
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.mjs +6 -5
  15. package/packages/core/dist/advanced.mjs.map +1 -1
  16. package/packages/core/dist/checks.cjs +185 -27
  17. package/packages/core/dist/checks.cjs.map +1 -1
  18. package/packages/core/dist/checks.mjs +2 -1
  19. package/packages/core/dist/{chunk-JE3TUFAQ.mjs → chunk-77PUPLPG.mjs} +14 -8
  20. package/packages/core/dist/chunk-77PUPLPG.mjs.map +1 -0
  21. package/packages/core/dist/chunk-AN5MOADW.mjs +204 -0
  22. package/packages/core/dist/chunk-AN5MOADW.mjs.map +1 -0
  23. package/packages/core/dist/{chunk-4CDX5GDS.mjs → chunk-IMCM42W6.mjs} +110 -99
  24. package/packages/core/dist/chunk-IMCM42W6.mjs.map +1 -0
  25. package/packages/core/dist/{chunk-YU6XT5A2.mjs → chunk-J2ST4VCX.mjs} +45 -3
  26. package/packages/core/dist/chunk-J2ST4VCX.mjs.map +1 -0
  27. package/packages/core/dist/{chunk-EIP5CNEL.mjs → chunk-JJSL346L.mjs} +58 -3
  28. package/packages/core/dist/chunk-JJSL346L.mjs.map +1 -0
  29. package/packages/core/dist/exporters.cjs +91 -29
  30. package/packages/core/dist/exporters.cjs.map +1 -1
  31. package/packages/core/dist/exporters.mjs +78 -29
  32. package/packages/core/dist/exporters.mjs.map +1 -1
  33. package/packages/core/dist/logs.cjs +206 -1
  34. package/packages/core/dist/logs.cjs.map +1 -1
  35. package/packages/core/dist/logs.mjs +3 -2
  36. package/packages/core/dist/logs.mjs.map +1 -1
  37. package/packages/core/dist/persisted.cjs +226 -8
  38. package/packages/core/dist/persisted.cjs.map +1 -1
  39. package/packages/core/dist/persisted.mjs +9 -5
  40. package/packages/core/dist/persisted.mjs.map +1 -1
  41. package/packages/core/dist/readers.cjs +276 -6
  42. package/packages/core/dist/readers.cjs.map +1 -1
  43. package/packages/core/dist/readers.mjs +4 -3
  44. package/packages/cli/dist/chunk-N5JN26MW.mjs.map +0 -1
  45. package/packages/core/dist/chunk-4CDX5GDS.mjs.map +0 -1
  46. package/packages/core/dist/chunk-EIP5CNEL.mjs.map +0 -1
  47. package/packages/core/dist/chunk-JE3TUFAQ.mjs.map +0 -1
  48. package/packages/core/dist/chunk-YU6XT5A2.mjs.map +0 -1
@@ -1,9 +1,10 @@
1
- import { normalizeTokenUsage } from './chunk-JE3TUFAQ.mjs';
2
- export { persistedInspectEventToInspectEvent, persistedInspectEventsToInspectEvents, persistedInspectEventsToRunTrees, traceEventToPersistedInspectEvent, traceEventsToPersistedInspectEvents, traceEventsToPersistedRunTrees } from './chunk-JE3TUFAQ.mjs';
1
+ import { normalizeTokenUsage } from './chunk-77PUPLPG.mjs';
2
+ export { persistedInspectEventToInspectEvent, persistedInspectEventsToInspectEvents, persistedInspectEventsToRunTrees, traceEventToPersistedInspectEvent, traceEventsToPersistedInspectEvents, traceEventsToPersistedRunTrees } from './chunk-77PUPLPG.mjs';
3
3
  import './chunk-AHUZNHFI.mjs';
4
4
  import './chunk-S4YWKV4G.mjs';
5
5
  import './chunk-S6LQBLX5.mjs';
6
- import './chunk-YU6XT5A2.mjs';
6
+ import './chunk-J2ST4VCX.mjs';
7
+ import { deliveryEventBaseFromIndexedId, DELIVERY_EVENT_BASE_ATTR } from './chunk-AN5MOADW.mjs';
7
8
  export { isPersistedInspectEvent, isPersistedInspectEventV02, isPersistedInspectEventV10, persistedInspectEventToTraceEvents, persistedInspectEventsToTraceEvents } from './chunk-EE5Z2GQ3.mjs';
8
9
 
9
10
  // packages/core/src/persisted/from-inspect-event.ts
@@ -93,19 +94,22 @@ function mapErrorFromAttributes(event) {
93
94
  }
94
95
  function inspectEventToPersistedInspectEvent(event, options) {
95
96
  const eventIndex = options?.eventIndex ?? 0;
96
- const eventId = typeof event.eventId === "string" && event.eventId.length > 0 ? event.eventId : createFallbackEventId(event, eventIndex);
97
+ const mintedFallback = !(typeof event.eventId === "string" && event.eventId.length > 0);
98
+ const eventId = mintedFallback ? createFallbackEventId(event, eventIndex) : event.eventId;
97
99
  const ts = toIsoTimestamp(event.timestamp);
98
100
  const { persistedSource, originalSourceType } = mapInspectSourceToPersisted(
99
101
  event.source,
100
102
  options
101
103
  );
102
104
  const attrsBase = event.attributes !== void 0 ? { ...event.attributes } : {};
105
+ const deliveryBase = mintedFallback ? deliveryEventBaseFromIndexedId(eventId) : void 0;
103
106
  const attributes = compactAttributes({
104
107
  ...attrsBase,
105
108
  sourceFile: event.source.file,
106
109
  sourceLine: event.source.line,
107
110
  originalSourceType,
108
- invalidTimestamp: ts.invalidTimestamp ? true : void 0
111
+ invalidTimestamp: ts.invalidTimestamp ? true : void 0,
112
+ ...deliveryBase !== void 0 ? { [DELIVERY_EVENT_BASE_ATTR]: deliveryBase } : {}
109
113
  });
110
114
  const tokenUsage = mapTokenUsageFromAttributes(event.attributes);
111
115
  const error = mapErrorFromAttributes(event);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/persisted/from-inspect-event.ts"],"names":[],"mappings":"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","file":"persisted.mjs","sourcesContent":["import type { EventSource, InspectEvent } from \"../types/inspect-event.js\";\nimport type {\n PersistedEventSource,\n PersistedEventSourceType,\n PersistedInspectError,\n PersistedInspectEvent,\n PersistedTokenUsage,\n} from \"../types/persisted-inspect-event.js\";\nimport { normalizeTokenUsage } from \"./token-usage.js\";\n\nexport interface InspectEventToPersistedOptions {\n /**\n * Optional source name override.\n * If omitted, derived from event.source.type.\n */\n sourceName?: string;\n\n /**\n * Optional source version override.\n */\n sourceVersion?: string;\n\n /**\n * Stable index for deterministic fallback IDs if needed.\n */\n eventIndex?: number;\n}\n\nfunction sanitizeIdPart(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n}\n\nfunction createFallbackEventId(event: InspectEvent, eventIndex: number): string {\n const runId = sanitizeIdPart(event.runId);\n const kind = sanitizeIdPart(event.kind);\n const name = sanitizeIdPart(event.name);\n return `inspect:${runId}:${kind}:${name}:${eventIndex}`;\n}\n\nfunction toIsoTimestamp(\n ms: number,\n): { iso: string; invalidTimestamp: boolean } {\n if (typeof ms !== \"number\" || !Number.isFinite(ms)) {\n return { iso: new Date(0).toISOString(), invalidTimestamp: true };\n }\n return { iso: new Date(ms).toISOString(), invalidTimestamp: false };\n}\n\nfunction compactAttributes(\n entries: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction mapInspectSourceToPersisted(\n source: EventSource,\n options?: InspectEventToPersistedOptions,\n): {\n persistedSource: PersistedEventSource;\n originalSourceType?: EventSource[\"type\"];\n} {\n const name = options?.sourceName;\n const version = options?.sourceVersion;\n\n switch (source.type) {\n case \"pino\":\n return {\n persistedSource: {\n type: \"json-log\",\n name: name ?? \"pino\",\n version,\n },\n originalSourceType: \"pino\",\n };\n case \"winston\":\n return {\n persistedSource: {\n type: \"json-log\",\n name: name ?? \"winston\",\n version,\n },\n originalSourceType: \"winston\",\n };\n case \"manual\":\n case \"json-log\":\n case \"log4js\":\n case \"adapter\":\n return {\n persistedSource: {\n type: source.type as PersistedEventSourceType,\n name,\n version,\n },\n };\n default:\n return {\n persistedSource: {\n type: \"json-log\",\n name,\n version,\n },\n };\n }\n}\n\nfunction mapTokenUsageFromAttributes(\n attributes: Record<string, unknown> | undefined,\n): PersistedTokenUsage | undefined {\n return normalizeTokenUsage(attributes?.tokens);\n}\n\nfunction mapErrorFromAttributes(\n event: InspectEvent,\n): PersistedInspectError | undefined {\n if (event.status !== \"error\" || !event.attributes) {\n return undefined;\n }\n const message = event.attributes.errorMessage;\n if (typeof message !== \"string\" || message.length === 0) {\n return undefined;\n }\n const err: PersistedInspectError = { message };\n if (typeof event.attributes.errorName === \"string\") {\n err.name = event.attributes.errorName;\n }\n return err;\n}\n\n/**\n * Maps one in-memory {@link InspectEvent} to a v0.2 {@link PersistedInspectEvent}.\n * Does not mutate `event`.\n */\nexport function inspectEventToPersistedInspectEvent(\n event: InspectEvent,\n options?: InspectEventToPersistedOptions,\n): PersistedInspectEvent {\n const eventIndex = options?.eventIndex ?? 0;\n const eventId =\n typeof event.eventId === \"string\" && event.eventId.length > 0\n ? event.eventId\n : createFallbackEventId(event, eventIndex);\n\n const ts = toIsoTimestamp(event.timestamp);\n const { persistedSource, originalSourceType } = mapInspectSourceToPersisted(\n event.source,\n options,\n );\n\n const attrsBase =\n event.attributes !== undefined ? { ...event.attributes } : {};\n\n const attributes = compactAttributes({\n ...attrsBase,\n sourceFile: event.source.file,\n sourceLine: event.source.line,\n originalSourceType,\n invalidTimestamp: ts.invalidTimestamp ? true : undefined,\n });\n\n const tokenUsage = mapTokenUsageFromAttributes(event.attributes);\n const error = mapErrorFromAttributes(event);\n\n const inputPreview = event.attributes?.inputPreview;\n const outputPreview = event.attributes?.outputPreview;\n\n const out: PersistedInspectEvent = {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: event.kind,\n name: event.name,\n timestamp: ts.iso,\n confidence: event.confidence,\n source: persistedSource,\n attributes,\n };\n\n if (event.parentId !== undefined) {\n out.parentId = event.parentId;\n }\n if (event.status !== undefined) {\n out.status = event.status;\n }\n if (\n event.durationMs !== undefined &&\n Number.isFinite(event.durationMs) &&\n event.durationMs >= 0\n ) {\n out.durationMs = event.durationMs;\n }\n if (tokenUsage !== undefined) {\n out.tokenUsage = tokenUsage;\n }\n if (error !== undefined) {\n out.error = error;\n }\n if (inputPreview !== undefined) {\n out.inputSummary = inputPreview;\n }\n if (outputPreview !== undefined) {\n out.outputSummary = outputPreview;\n }\n\n return out;\n}\n\n/**\n * Maps in-memory {@link InspectEvent} rows to persisted v0.2 events.\n */\nexport function inspectEventsToPersistedInspectEvents(\n events: readonly InspectEvent[],\n options?: Omit<InspectEventToPersistedOptions, \"eventIndex\">,\n): PersistedInspectEvent[] {\n return events.map((event, index) =>\n inspectEventToPersistedInspectEvent(event, { ...options, eventIndex: index }),\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/persisted/from-inspect-event.ts"],"names":[],"mappings":"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","file":"persisted.mjs","sourcesContent":["import type { EventSource, InspectEvent } from \"../types/inspect-event.js\";\nimport type {\n PersistedEventSource,\n PersistedEventSourceType,\n PersistedInspectError,\n PersistedInspectEvent,\n PersistedTokenUsage,\n} from \"../types/persisted-inspect-event.js\";\nimport {\n DELIVERY_EVENT_BASE_ATTR,\n deliveryEventBaseFromIndexedId,\n} from \"./delivery-identity.js\";\nimport { normalizeTokenUsage } from \"./token-usage.js\";\n\nexport interface InspectEventToPersistedOptions {\n /**\n * Optional source name override.\n * If omitted, derived from event.source.type.\n */\n sourceName?: string;\n\n /**\n * Optional source version override.\n */\n sourceVersion?: string;\n\n /**\n * Stable index for deterministic fallback IDs if needed.\n */\n eventIndex?: number;\n}\n\nfunction sanitizeIdPart(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n}\n\nfunction createFallbackEventId(event: InspectEvent, eventIndex: number): string {\n const runId = sanitizeIdPart(event.runId);\n const kind = sanitizeIdPart(event.kind);\n const name = sanitizeIdPart(event.name);\n return `inspect:${runId}:${kind}:${name}:${eventIndex}`;\n}\n\nfunction toIsoTimestamp(\n ms: number,\n): { iso: string; invalidTimestamp: boolean } {\n if (typeof ms !== \"number\" || !Number.isFinite(ms)) {\n return { iso: new Date(0).toISOString(), invalidTimestamp: true };\n }\n return { iso: new Date(ms).toISOString(), invalidTimestamp: false };\n}\n\nfunction compactAttributes(\n entries: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction mapInspectSourceToPersisted(\n source: EventSource,\n options?: InspectEventToPersistedOptions,\n): {\n persistedSource: PersistedEventSource;\n originalSourceType?: EventSource[\"type\"];\n} {\n const name = options?.sourceName;\n const version = options?.sourceVersion;\n\n switch (source.type) {\n case \"pino\":\n return {\n persistedSource: {\n type: \"json-log\",\n name: name ?? \"pino\",\n version,\n },\n originalSourceType: \"pino\",\n };\n case \"winston\":\n return {\n persistedSource: {\n type: \"json-log\",\n name: name ?? \"winston\",\n version,\n },\n originalSourceType: \"winston\",\n };\n case \"manual\":\n case \"json-log\":\n case \"log4js\":\n case \"adapter\":\n return {\n persistedSource: {\n type: source.type as PersistedEventSourceType,\n name,\n version,\n },\n };\n default:\n return {\n persistedSource: {\n type: \"json-log\",\n name,\n version,\n },\n };\n }\n}\n\nfunction mapTokenUsageFromAttributes(\n attributes: Record<string, unknown> | undefined,\n): PersistedTokenUsage | undefined {\n return normalizeTokenUsage(attributes?.tokens);\n}\n\nfunction mapErrorFromAttributes(\n event: InspectEvent,\n): PersistedInspectError | undefined {\n if (event.status !== \"error\" || !event.attributes) {\n return undefined;\n }\n const message = event.attributes.errorMessage;\n if (typeof message !== \"string\" || message.length === 0) {\n return undefined;\n }\n const err: PersistedInspectError = { message };\n if (typeof event.attributes.errorName === \"string\") {\n err.name = event.attributes.errorName;\n }\n return err;\n}\n\n/**\n * Maps one in-memory {@link InspectEvent} to a v0.2 {@link PersistedInspectEvent}.\n * Does not mutate `event`.\n */\nexport function inspectEventToPersistedInspectEvent(\n event: InspectEvent,\n options?: InspectEventToPersistedOptions,\n): PersistedInspectEvent {\n const eventIndex = options?.eventIndex ?? 0;\n const mintedFallback = !(\n typeof event.eventId === \"string\" && event.eventId.length > 0\n );\n const eventId = mintedFallback\n ? createFallbackEventId(event, eventIndex)\n : event.eventId;\n\n const ts = toIsoTimestamp(event.timestamp);\n const { persistedSource, originalSourceType } = mapInspectSourceToPersisted(\n event.source,\n options,\n );\n\n const attrsBase =\n event.attributes !== undefined ? { ...event.attributes } : {};\n const deliveryBase = mintedFallback\n ? deliveryEventBaseFromIndexedId(eventId)\n : undefined;\n\n const attributes = compactAttributes({\n ...attrsBase,\n sourceFile: event.source.file,\n sourceLine: event.source.line,\n originalSourceType,\n invalidTimestamp: ts.invalidTimestamp ? true : undefined,\n ...(deliveryBase !== undefined\n ? { [DELIVERY_EVENT_BASE_ATTR]: deliveryBase }\n : {}),\n });\n\n const tokenUsage = mapTokenUsageFromAttributes(event.attributes);\n const error = mapErrorFromAttributes(event);\n\n const inputPreview = event.attributes?.inputPreview;\n const outputPreview = event.attributes?.outputPreview;\n\n const out: PersistedInspectEvent = {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: event.kind,\n name: event.name,\n timestamp: ts.iso,\n confidence: event.confidence,\n source: persistedSource,\n attributes,\n };\n\n if (event.parentId !== undefined) {\n out.parentId = event.parentId;\n }\n if (event.status !== undefined) {\n out.status = event.status;\n }\n if (\n event.durationMs !== undefined &&\n Number.isFinite(event.durationMs) &&\n event.durationMs >= 0\n ) {\n out.durationMs = event.durationMs;\n }\n if (tokenUsage !== undefined) {\n out.tokenUsage = tokenUsage;\n }\n if (error !== undefined) {\n out.error = error;\n }\n if (inputPreview !== undefined) {\n out.inputSummary = inputPreview;\n }\n if (outputPreview !== undefined) {\n out.outputSummary = outputPreview;\n }\n\n return out;\n}\n\n/**\n * Maps in-memory {@link InspectEvent} rows to persisted v0.2 events.\n */\nexport function inspectEventsToPersistedInspectEvents(\n events: readonly InspectEvent[],\n options?: Omit<InspectEventToPersistedOptions, \"eventIndex\">,\n): PersistedInspectEvent[] {\n return events.map((event, index) =>\n inspectEventToPersistedInspectEvent(event, { ...options, eventIndex: index }),\n );\n}\n"]}
@@ -604,6 +604,176 @@ function extractCorrelationMetadata(record) {
604
604
  return found ? out : void 0;
605
605
  }
606
606
 
607
+ // packages/core/src/checks/canonical-equality.ts
608
+ var DEFAULT_MAX_DEPTH = 8;
609
+ var DEFAULT_MAX_BYTES = 16384;
610
+ function sortKeysDeep(input, depth, maxDepth) {
611
+ if (depth > maxDepth) {
612
+ throw new Error("AI_CHECK_CANONICAL_DEPTH_EXCEEDED");
613
+ }
614
+ if (input === null || typeof input !== "object") return input;
615
+ if (Array.isArray(input)) {
616
+ return input.map((item) => sortKeysDeep(item, depth + 1, maxDepth));
617
+ }
618
+ const record = input;
619
+ const out = {};
620
+ for (const key of Object.keys(record).sort()) {
621
+ out[key] = sortKeysDeep(record[key], depth + 1, maxDepth);
622
+ }
623
+ return out;
624
+ }
625
+ function encodeCanonicalStructured(value, limits) {
626
+ const maxDepth = DEFAULT_MAX_DEPTH;
627
+ const maxBytes = DEFAULT_MAX_BYTES;
628
+ try {
629
+ const sorted = sortKeysDeep(value, 0, maxDepth);
630
+ const encoded = JSON.stringify(sorted);
631
+ if (encoded === void 0) {
632
+ return {
633
+ ok: false,
634
+ reason: "Value is not JSON-serializable for canonical comparison.",
635
+ code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
636
+ };
637
+ }
638
+ if (Buffer.byteLength(encoded, "utf8") > maxBytes) {
639
+ return {
640
+ ok: false,
641
+ reason: "Canonical structured value exceeds bounded size limit.",
642
+ code: "AI_CHECK_CANONICAL_SIZE_EXCEEDED"
643
+ };
644
+ }
645
+ return { ok: true, value: encoded };
646
+ } catch (error) {
647
+ const message = error instanceof Error ? error.message : String(error);
648
+ if (message === "AI_CHECK_CANONICAL_DEPTH_EXCEEDED") {
649
+ return {
650
+ ok: false,
651
+ reason: "Canonical structured value exceeds bounded depth limit.",
652
+ code: "AI_CHECK_CANONICAL_DEPTH_EXCEEDED"
653
+ };
654
+ }
655
+ return {
656
+ ok: false,
657
+ reason: "Canonical structured encoding failed.",
658
+ code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
659
+ };
660
+ }
661
+ }
662
+
663
+ // packages/core/src/persisted/delivery-identity.ts
664
+ var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
665
+ var DELIVERY_EVENT_BASE_ATTR = "agent_inspect.delivery_event_base";
666
+ var MAX_DELIVERY_BASE_LEN = 500;
667
+ function stripReaderDeliveryDiscriminator(eventId, attributes) {
668
+ if (!eventId) return eventId;
669
+ const rawBase = attributes?.[DELIVERY_EVENT_BASE_ATTR];
670
+ if (typeof rawBase !== "string" || rawBase.trim() === "") return eventId;
671
+ const base = rawBase.trim().slice(0, MAX_DELIVERY_BASE_LEN);
672
+ if (eventId === base) return base;
673
+ const prefix = `${base}:`;
674
+ if (!eventId.startsWith(prefix)) return eventId;
675
+ const suffix = eventId.slice(prefix.length);
676
+ if (/^\d+$/.test(suffix)) return base;
677
+ return eventId;
678
+ }
679
+ function deliveryEventBaseFromIndexedId(eventId) {
680
+ if (!/:\d+$/.test(eventId)) return void 0;
681
+ const base = eventId.replace(/:\d+$/, "");
682
+ return base.length > 0 ? base.slice(0, MAX_DELIVERY_BASE_LEN) : void 0;
683
+ }
684
+ function canonicalDigest(value) {
685
+ if (value === void 0) return null;
686
+ const encoded = encodeCanonicalStructured(value);
687
+ return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
688
+ }
689
+ function capturedContentDigest(attributes) {
690
+ if (!attributes || typeof attributes !== "object") {
691
+ return { args: null, result: null };
692
+ }
693
+ const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
694
+ const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
695
+ const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
696
+ return {
697
+ args: args === void 0 ? null : canonicalDigest(args),
698
+ result: result === void 0 ? null : canonicalDigest(result)
699
+ };
700
+ }
701
+ function timeKey(fields) {
702
+ if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
703
+ return fields.startedAt;
704
+ }
705
+ if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
706
+ return fields.timestamp;
707
+ }
708
+ if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
709
+ return String(fields.timestamp);
710
+ }
711
+ return null;
712
+ }
713
+ function deliverySemanticFingerprint(fields) {
714
+ const content = capturedContentDigest(fields.attributes);
715
+ return JSON.stringify({
716
+ stableEventId: stripReaderDeliveryDiscriminator(fields.eventId, fields.attributes),
717
+ runId: fields.runId,
718
+ kind: fields.kind,
719
+ name: fields.name,
720
+ status: fields.status ?? null,
721
+ parentId: fields.parentId ?? null,
722
+ sourceType: fields.sourceType ?? null,
723
+ time: timeKey(fields),
724
+ operationId: fields.operationId ?? null,
725
+ attemptId: fields.attemptId ?? null,
726
+ attemptNumber: fields.attemptNumber ?? null,
727
+ retryOf: fields.retryOf ?? null,
728
+ argsDigest: content.args,
729
+ resultDigest: content.result
730
+ });
731
+ }
732
+ function identityFieldsFromAttributes(attributes) {
733
+ if (!attributes || typeof attributes !== "object") {
734
+ return {
735
+ operationId: null,
736
+ attemptId: null,
737
+ attemptNumber: null,
738
+ retryOf: null
739
+ };
740
+ }
741
+ const nested = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? attributes.metadata : void 0;
742
+ const pickString = (key) => {
743
+ const direct = attributes[key];
744
+ if (typeof direct === "string" && direct.trim() !== "") return direct.trim();
745
+ const nestedValue = nested?.[key];
746
+ if (typeof nestedValue === "string" && nestedValue.trim() !== "") {
747
+ return nestedValue.trim();
748
+ }
749
+ return null;
750
+ };
751
+ const pickNumber = () => {
752
+ const direct = attributes.attemptNumber ?? attributes.attempt;
753
+ if (typeof direct === "number" && Number.isFinite(direct)) return direct;
754
+ const nestedValue = nested?.attemptNumber ?? nested?.attempt;
755
+ if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) {
756
+ return nestedValue;
757
+ }
758
+ return null;
759
+ };
760
+ return {
761
+ operationId: pickString("operationId"),
762
+ attemptId: pickString("attemptId"),
763
+ retryOf: pickString("retryOf"),
764
+ attemptNumber: pickNumber()
765
+ };
766
+ }
767
+ function stampDeliveryConflict(event) {
768
+ return {
769
+ ...event,
770
+ attributes: {
771
+ ...event.attributes ?? {},
772
+ [DELIVERY_CONFLICT_ATTR]: true
773
+ }
774
+ };
775
+ }
776
+
607
777
  // packages/core/src/persisted/token-usage.ts
608
778
  function isRecord4(value) {
609
779
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -719,6 +889,11 @@ function compactAttributes(entries) {
719
889
  }
720
890
  return Object.keys(out).length > 0 ? out : void 0;
721
891
  }
892
+ function stampDeliveryEventBase(eventId, attributes) {
893
+ const base = deliveryEventBaseFromIndexedId(eventId);
894
+ if (!base) return attributes;
895
+ return { ...attributes ?? {}, [DELIVERY_EVENT_BASE_ATTR]: base };
896
+ }
722
897
  function traceEventToPersistedInspectEvent(event, options) {
723
898
  const eventIndex = options?.eventIndex ?? 0;
724
899
  const eventId = createPersistedEventId(event, eventIndex);
@@ -748,7 +923,7 @@ function traceEventToPersistedInspectEvent(event, options) {
748
923
  startedAt: tsStart.iso,
749
924
  confidence: "explicit",
750
925
  source,
751
- attributes
926
+ attributes: stampDeliveryEventBase(eventId, attributes)
752
927
  };
753
928
  }
754
929
  case "run_completed": {
@@ -771,7 +946,7 @@ function traceEventToPersistedInspectEvent(event, options) {
771
946
  durationMs: event.durationMs,
772
947
  confidence: "explicit",
773
948
  source,
774
- attributes,
949
+ attributes: stampDeliveryEventBase(eventId, attributes),
775
950
  error
776
951
  };
777
952
  }
@@ -796,7 +971,7 @@ function traceEventToPersistedInspectEvent(event, options) {
796
971
  startedAt: tsStart.iso,
797
972
  confidence: "explicit",
798
973
  source,
799
- attributes
974
+ attributes: stampDeliveryEventBase(eventId, attributes)
800
975
  };
801
976
  if (event.parentId !== void 0) {
802
977
  out.parentId = event.parentId;
@@ -827,7 +1002,7 @@ function traceEventToPersistedInspectEvent(event, options) {
827
1002
  durationMs: event.durationMs,
828
1003
  confidence: "explicit",
829
1004
  source,
830
- attributes,
1005
+ attributes: stampDeliveryEventBase(eventId, attributes),
831
1006
  error
832
1007
  };
833
1008
  }
@@ -854,7 +1029,7 @@ function traceEventToPersistedInspectEvent(event, options) {
854
1029
  timestamp: tsMain.iso,
855
1030
  confidence: "explicit",
856
1031
  source,
857
- attributes
1032
+ attributes: stampDeliveryEventBase(eventId, attributes)
858
1033
  };
859
1034
  if (event.parentId !== void 0) {
860
1035
  out.parentId = event.parentId;
@@ -1348,7 +1523,47 @@ var TreeBuilder = class {
1348
1523
  const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
1349
1524
  const nodes = /* @__PURE__ */ new Map();
1350
1525
  for (const e of sorted) {
1351
- nodes.set(e.eventId, { event: e, children: [], depth: 0 });
1526
+ const existing = nodes.get(e.eventId);
1527
+ if (!existing) {
1528
+ nodes.set(e.eventId, { event: e, children: [], depth: 0 });
1529
+ continue;
1530
+ }
1531
+ const existingAttrs = existing.event.attributes && typeof existing.event.attributes === "object" ? existing.event.attributes : void 0;
1532
+ const nextAttrs = e.attributes && typeof e.attributes === "object" ? e.attributes : void 0;
1533
+ const existingIdentity = identityFieldsFromAttributes(existingAttrs);
1534
+ const nextIdentity = identityFieldsFromAttributes(nextAttrs);
1535
+ const existingFp = deliverySemanticFingerprint({
1536
+ eventId: existing.event.eventId,
1537
+ runId: existing.event.runId,
1538
+ kind: existing.event.kind,
1539
+ name: existing.event.name,
1540
+ status: existing.event.status,
1541
+ parentId: existing.event.parentId,
1542
+ timestamp: existing.event.timestamp,
1543
+ sourceType: existing.event.source?.type,
1544
+ attributes: existingAttrs,
1545
+ ...existingIdentity
1546
+ });
1547
+ const nextFp = deliverySemanticFingerprint({
1548
+ eventId: e.eventId,
1549
+ runId: e.runId,
1550
+ kind: e.kind,
1551
+ name: e.name,
1552
+ status: e.status,
1553
+ parentId: e.parentId,
1554
+ timestamp: e.timestamp,
1555
+ sourceType: e.source?.type,
1556
+ attributes: nextAttrs,
1557
+ ...nextIdentity
1558
+ });
1559
+ if (existingFp === nextFp) {
1560
+ continue;
1561
+ }
1562
+ nodes.set(e.eventId, {
1563
+ event: stampDeliveryConflict(e),
1564
+ children: [],
1565
+ depth: 0
1566
+ });
1352
1567
  }
1353
1568
  const { roots, summary } = linkNodesVisibilityFirst(nodes);
1354
1569
  const confidenceBreakdown = {
@@ -2914,6 +3129,12 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
2914
3129
  ["agent_inspect.retry_of", "retryOf", "string"],
2915
3130
  ["agent_inspect.attempt_number", "attemptNumber", "int"]
2916
3131
  ];
3132
+ const conflictMapping = [
3133
+ ["agent_inspect.identity_conflict.operation_id", "operationId", "string"],
3134
+ ["agent_inspect.identity_conflict.attempt_id", "attemptId", "string"],
3135
+ ["agent_inspect.identity_conflict.retry_of", "retryOf", "string"],
3136
+ ["agent_inspect.identity_conflict.attempt_number", "attemptNumber", "int"]
3137
+ ];
2917
3138
  const metadata = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? { ...attributes.metadata } : {};
2918
3139
  for (const [dotted, camel, kind] of mapping) {
2919
3140
  const raw = attributes[dotted];
@@ -2965,6 +3186,55 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
2965
3186
  if (direct === void 0) attributes[camel] = promoted;
2966
3187
  if (nested === void 0) metadata[camel] = promoted;
2967
3188
  }
3189
+ for (const [dotted, camel, kind] of conflictMapping) {
3190
+ const raw = attributes[dotted];
3191
+ if (raw === void 0 || raw === null) continue;
3192
+ let alternate;
3193
+ if (kind === "int") {
3194
+ const n = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : NaN;
3195
+ if (!Number.isFinite(n) || n < 1) {
3196
+ warnings.push({
3197
+ code: "otlp_identity_invalid",
3198
+ message: `Ignoring invalid ${dotted} identity conflict value.`,
3199
+ severity: "warning",
3200
+ field: `${pathPrefix}.${dotted}`
3201
+ });
3202
+ continue;
3203
+ }
3204
+ alternate = Math.trunc(n);
3205
+ } else if (typeof raw === "string" && raw.trim() !== "") {
3206
+ alternate = raw.trim();
3207
+ } else {
3208
+ warnings.push({
3209
+ code: "otlp_identity_invalid",
3210
+ message: `Ignoring non-string ${dotted} identity conflict value.`,
3211
+ severity: "warning",
3212
+ field: `${pathPrefix}.${dotted}`
3213
+ });
3214
+ continue;
3215
+ }
3216
+ const preferred = attributes[camel];
3217
+ if (preferred !== void 0 && preferred !== alternate) {
3218
+ metadata[camel] = alternate;
3219
+ warnings.push({
3220
+ code: "otlp_identity_conflict",
3221
+ message: `Conflicting ${camel}: attributes.${camel} vs nested alternate from ${dotted}; retaining both.`,
3222
+ severity: "warning",
3223
+ field: `${pathPrefix}.${dotted}`
3224
+ });
3225
+ } else if (preferred === void 0) {
3226
+ metadata[camel] = alternate;
3227
+ }
3228
+ }
3229
+ const conflictFields = attributes["agent_inspect.identity_conflict.fields"];
3230
+ if (typeof conflictFields === "string" && conflictFields.trim() !== "") {
3231
+ warnings.push({
3232
+ code: "otlp_identity_conflict",
3233
+ message: `Identity representation conflict fields retained after OTLP bounding: ${conflictFields.trim().slice(0, 200)}.`,
3234
+ severity: "warning",
3235
+ field: `${pathPrefix}.agent_inspect.identity_conflict.fields`
3236
+ });
3237
+ }
2968
3238
  if (Object.keys(metadata).length > 0) {
2969
3239
  attributes.metadata = metadata;
2970
3240
  }