agent-inspect 6.31.6 → 6.31.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +1 -1
- package/docs/AI-SDK-ADOPTION.md +62 -34
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-YXDNWHNJ.mjs → chunk-6FE47XSF.mjs} +119 -34
- package/packages/cli/dist/chunk-6FE47XSF.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +569 -102
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +454 -74
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-H22KNWAZ.mjs → src-NXAYHG34.mjs} +3 -3
- package/packages/cli/dist/{src-H22KNWAZ.mjs.map → src-NXAYHG34.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +116 -31
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +7 -7
- package/packages/core/dist/checks.mjs +2 -2
- package/packages/core/dist/{chunk-LXYPM2ZO.mjs → chunk-2CCRUI42.mjs} +19 -318
- package/packages/core/dist/chunk-2CCRUI42.mjs.map +1 -0
- package/packages/core/dist/{chunk-Q5SLKV2Y.mjs → chunk-2IRRUNIN.mjs} +28 -5
- package/packages/core/dist/chunk-2IRRUNIN.mjs.map +1 -0
- package/packages/core/dist/{chunk-EXGQLMVB.mjs → chunk-7YYS742B.mjs} +49 -12
- package/packages/core/dist/chunk-7YYS742B.mjs.map +1 -0
- package/packages/core/dist/{chunk-OSGNGRHF.mjs → chunk-IJJSPJXV.mjs} +51 -25
- package/packages/core/dist/chunk-IJJSPJXV.mjs.map +1 -0
- package/packages/core/dist/chunk-L5WLVBW4.mjs +355 -0
- package/packages/core/dist/chunk-L5WLVBW4.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +327 -58
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +281 -49
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/persisted.cjs +361 -9
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.d.cts +8 -1
- package/packages/core/dist/persisted.d.ts +8 -1
- package/packages/core/dist/persisted.mjs +3 -2
- package/packages/core/dist/persisted.mjs.map +1 -1
- package/packages/core/dist/readers.cjs +425 -100
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +3 -3
- package/packages/cli/dist/chunk-YXDNWHNJ.mjs.map +0 -1
- package/packages/core/dist/chunk-EXGQLMVB.mjs.map +0 -1
- package/packages/core/dist/chunk-FWK3Q3OJ.mjs +0 -56
- package/packages/core/dist/chunk-FWK3Q3OJ.mjs.map +0 -1
- package/packages/core/dist/chunk-LXYPM2ZO.mjs.map +0 -1
- package/packages/core/dist/chunk-OSGNGRHF.mjs.map +0 -1
- package/packages/core/dist/chunk-Q5SLKV2Y.mjs.map +0 -1
|
@@ -430,12 +430,12 @@ function persistedInspectEventToTraceEvents(event) {
|
|
|
430
430
|
if (!isPersistedInspectEvent(event)) {
|
|
431
431
|
throw new Error("Invalid PersistedInspectEvent: failed isPersistedInspectEvent");
|
|
432
432
|
}
|
|
433
|
-
const
|
|
434
|
-
if (
|
|
435
|
-
if (
|
|
436
|
-
if (
|
|
437
|
-
if (
|
|
438
|
-
if (
|
|
433
|
+
const legacyEvent2 = event.attributes?.legacyEvent;
|
|
434
|
+
if (legacyEvent2 === "run_started") return [fromLegacyRunStarted(event)];
|
|
435
|
+
if (legacyEvent2 === "run_completed") return [fromLegacyRunCompleted(event)];
|
|
436
|
+
if (legacyEvent2 === "step_started") return [fromLegacyStepStarted(event)];
|
|
437
|
+
if (legacyEvent2 === "step_completed") return [fromLegacyStepCompleted(event)];
|
|
438
|
+
if (legacyEvent2 === "outcome_observed") return [fromLegacyOutcomeObserved(event)];
|
|
439
439
|
if (event.kind === "RUN") {
|
|
440
440
|
return fromNativeRun(event);
|
|
441
441
|
}
|
|
@@ -876,6 +876,336 @@ function traceEventsToPersistedInspectEvents(events, options) {
|
|
|
876
876
|
);
|
|
877
877
|
}
|
|
878
878
|
|
|
879
|
+
// packages/core/src/diagnostics/programmatic.ts
|
|
880
|
+
var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
|
|
881
|
+
AI_TRACE_INPUT_INVALID: {
|
|
882
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
883
|
+
summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
|
|
884
|
+
remediation: "For a file path, use openTraceFile(path).",
|
|
885
|
+
relatedCodes: ["invalid_input"]
|
|
886
|
+
},
|
|
887
|
+
AI_TRACE_FORMAT_UNSUPPORTED: {
|
|
888
|
+
code: "AI_TRACE_FORMAT_UNSUPPORTED",
|
|
889
|
+
summary: "No trace reader could detect the input format.",
|
|
890
|
+
remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
|
|
891
|
+
relatedCodes: ["unsupported_format"]
|
|
892
|
+
},
|
|
893
|
+
AI_TRACE_FORMAT_AMBIGUOUS: {
|
|
894
|
+
code: "AI_TRACE_FORMAT_AMBIGUOUS",
|
|
895
|
+
summary: "Multiple trace readers matched the input with equal confidence.",
|
|
896
|
+
remediation: "Set options.format explicitly to disambiguate the reader.",
|
|
897
|
+
relatedCodes: ["ambiguous_format"]
|
|
898
|
+
},
|
|
899
|
+
AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
|
|
900
|
+
code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
|
|
901
|
+
summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
|
|
902
|
+
remediation: "Use openTraceFile() to normalize a JSONL trace first."
|
|
903
|
+
},
|
|
904
|
+
AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
|
|
905
|
+
code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
906
|
+
summary: "Multiple runs are available; select a run before executing checks.",
|
|
907
|
+
remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
|
|
908
|
+
relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
|
|
909
|
+
},
|
|
910
|
+
AI_TRACE_RELATIONSHIP_SELF_PARENT: {
|
|
911
|
+
code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
912
|
+
summary: "A parentId equals its own event/step id.",
|
|
913
|
+
remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
|
|
914
|
+
relatedCodes: [
|
|
915
|
+
"AI_LANGGRAPH_SELF_PARENT_REJECTED",
|
|
916
|
+
"AI_LOGICAL_SELF_PARENT_REMOVED"
|
|
917
|
+
]
|
|
918
|
+
},
|
|
919
|
+
AI_TRACE_RELATIONSHIP_CYCLE: {
|
|
920
|
+
code: "AI_TRACE_RELATIONSHIP_CYCLE",
|
|
921
|
+
summary: "Trace contains a parentId cycle.",
|
|
922
|
+
remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
|
|
923
|
+
relatedCodes: ["structure.cycle"]
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
function formatProgrammaticDiagnostic(code, detail) {
|
|
927
|
+
const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
|
|
928
|
+
const summary = detail?.trim() ? detail.trim() : spec.summary;
|
|
929
|
+
return `${code}: ${summary} Remediation: ${spec.remediation}`;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// packages/core/src/checks/logical-events.ts
|
|
933
|
+
function isRecord5(value) {
|
|
934
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
935
|
+
}
|
|
936
|
+
function legacyEvent(event) {
|
|
937
|
+
const value = event.attributes?.legacyEvent;
|
|
938
|
+
return typeof value === "string" ? value : void 0;
|
|
939
|
+
}
|
|
940
|
+
function stepIdOf(event) {
|
|
941
|
+
const value = event.attributes?.stepId;
|
|
942
|
+
if (typeof value === "string" && value.trim() !== "") return value;
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
function cloneEvent(event) {
|
|
946
|
+
return {
|
|
947
|
+
...event,
|
|
948
|
+
...event.attributes !== void 0 ? { attributes: { ...event.attributes } } : {},
|
|
949
|
+
...event.error !== void 0 ? { error: { ...event.error } } : {},
|
|
950
|
+
...event.tokenUsage !== void 0 ? { tokenUsage: { ...event.tokenUsage } } : {},
|
|
951
|
+
...event.source !== void 0 ? { source: { ...event.source } } : {}
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function mergeAttributes(start, complete) {
|
|
955
|
+
const merged = {
|
|
956
|
+
...isRecord5(complete.attributes) ? complete.attributes : {},
|
|
957
|
+
...isRecord5(start.attributes) ? start.attributes : {}
|
|
958
|
+
};
|
|
959
|
+
merged.legacyEvent = start.attributes?.legacyEvent ?? complete.attributes?.legacyEvent;
|
|
960
|
+
merged.legacyCompleteEvent = complete.attributes?.legacyEvent;
|
|
961
|
+
if (complete.attributes?.errorStack !== void 0) {
|
|
962
|
+
merged.errorStack = complete.attributes.errorStack;
|
|
963
|
+
}
|
|
964
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
965
|
+
}
|
|
966
|
+
function pairStartComplete(start, complete) {
|
|
967
|
+
const attributes = mergeAttributes(start, complete);
|
|
968
|
+
const paired = {
|
|
969
|
+
...cloneEvent(start),
|
|
970
|
+
status: complete.status,
|
|
971
|
+
timestamp: complete.timestamp ?? start.timestamp,
|
|
972
|
+
...complete.endedAt !== void 0 ? { endedAt: complete.endedAt } : {},
|
|
973
|
+
...complete.durationMs !== void 0 ? { durationMs: complete.durationMs } : {},
|
|
974
|
+
...complete.error !== void 0 ? { error: { ...complete.error } } : {},
|
|
975
|
+
...complete.tokenUsage !== void 0 && start.tokenUsage === void 0 ? { tokenUsage: { ...complete.tokenUsage } } : {},
|
|
976
|
+
...attributes !== void 0 ? { attributes } : {}
|
|
977
|
+
};
|
|
978
|
+
return {
|
|
979
|
+
...paired,
|
|
980
|
+
sourceEventIds: Object.freeze([start.eventId, complete.eventId]),
|
|
981
|
+
projection: {
|
|
982
|
+
paired: true,
|
|
983
|
+
absorbedEventIds: Object.freeze([complete.eventId]),
|
|
984
|
+
parentNormalized: false,
|
|
985
|
+
...start.parentId !== void 0 ? { originalParentId: start.parentId } : {}
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
function asLogical(event, extras) {
|
|
990
|
+
return {
|
|
991
|
+
...cloneEvent(event),
|
|
992
|
+
sourceEventIds: Object.freeze([event.eventId]),
|
|
993
|
+
projection: {
|
|
994
|
+
paired: false,
|
|
995
|
+
absorbedEventIds: Object.freeze([]),
|
|
996
|
+
parentNormalized: extras?.parentNormalized === true,
|
|
997
|
+
...{}
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function projectLogicalEvents(events) {
|
|
1002
|
+
const diagnostics = [];
|
|
1003
|
+
const byRun = /* @__PURE__ */ new Map();
|
|
1004
|
+
for (const event of events) {
|
|
1005
|
+
const list = byRun.get(event.runId) ?? [];
|
|
1006
|
+
list.push(event);
|
|
1007
|
+
byRun.set(event.runId, list);
|
|
1008
|
+
}
|
|
1009
|
+
const absorbedIds = /* @__PURE__ */ new Set();
|
|
1010
|
+
const logicalByRawId = /* @__PURE__ */ new Map();
|
|
1011
|
+
const stepIdToLogicalId = /* @__PURE__ */ new Map();
|
|
1012
|
+
const logical = [];
|
|
1013
|
+
const orderedRuns = [...byRun.keys()].sort((a, b) => a.localeCompare(b));
|
|
1014
|
+
for (const runId of orderedRuns) {
|
|
1015
|
+
const runEvents = byRun.get(runId) ?? [];
|
|
1016
|
+
const starts = [];
|
|
1017
|
+
const completes = [];
|
|
1018
|
+
const others = [];
|
|
1019
|
+
for (const event of runEvents) {
|
|
1020
|
+
const legacy = legacyEvent(event);
|
|
1021
|
+
if (legacy === "step_started" || legacy === "run_started" && event.status === "running") {
|
|
1022
|
+
starts.push(event);
|
|
1023
|
+
} else if (legacy === "step_completed" || legacy === "run_completed") {
|
|
1024
|
+
completes.push(event);
|
|
1025
|
+
} else {
|
|
1026
|
+
others.push(event);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
const usedCompletes = /* @__PURE__ */ new Set();
|
|
1030
|
+
for (const start of starts) {
|
|
1031
|
+
const stepId = stepIdOf(start);
|
|
1032
|
+
let match;
|
|
1033
|
+
if (legacyEvent(start) === "run_started") {
|
|
1034
|
+
const candidates = completes.filter(
|
|
1035
|
+
(c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "run_completed"
|
|
1036
|
+
);
|
|
1037
|
+
if (candidates.length > 1) {
|
|
1038
|
+
diagnostics.push({
|
|
1039
|
+
code: "AI_LOGICAL_PAIR_AMBIGUOUS",
|
|
1040
|
+
message: `Multiple run_completed rows for run ${runId}; using first by eventId.`,
|
|
1041
|
+
eventIds: candidates.map((c) => c.eventId)
|
|
1042
|
+
});
|
|
1043
|
+
candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));
|
|
1044
|
+
}
|
|
1045
|
+
match = candidates[0];
|
|
1046
|
+
} else if (stepId) {
|
|
1047
|
+
const candidates = completes.filter(
|
|
1048
|
+
(c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "step_completed" && stepIdOf(c) === stepId
|
|
1049
|
+
);
|
|
1050
|
+
if (candidates.length > 1) {
|
|
1051
|
+
diagnostics.push({
|
|
1052
|
+
code: "AI_LOGICAL_PAIR_AMBIGUOUS",
|
|
1053
|
+
message: `Multiple step_completed rows for stepId ${stepId}; using first by eventId.`,
|
|
1054
|
+
eventIds: candidates.map((c) => c.eventId)
|
|
1055
|
+
});
|
|
1056
|
+
candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));
|
|
1057
|
+
}
|
|
1058
|
+
match = candidates[0];
|
|
1059
|
+
}
|
|
1060
|
+
if (match) {
|
|
1061
|
+
usedCompletes.add(match.eventId);
|
|
1062
|
+
absorbedIds.add(match.eventId);
|
|
1063
|
+
const paired = pairStartComplete(start, match);
|
|
1064
|
+
logical.push(paired);
|
|
1065
|
+
logicalByRawId.set(start.eventId, paired);
|
|
1066
|
+
logicalByRawId.set(match.eventId, paired);
|
|
1067
|
+
if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, paired.eventId);
|
|
1068
|
+
} else {
|
|
1069
|
+
diagnostics.push({
|
|
1070
|
+
code: "AI_LOGICAL_PAIR_UNMATCHED_START",
|
|
1071
|
+
message: `No matching complete for start ${start.eventId}.`,
|
|
1072
|
+
eventIds: [start.eventId]
|
|
1073
|
+
});
|
|
1074
|
+
const alone = asLogical(start);
|
|
1075
|
+
logical.push(alone);
|
|
1076
|
+
logicalByRawId.set(start.eventId, alone);
|
|
1077
|
+
if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
for (const complete of completes) {
|
|
1081
|
+
if (usedCompletes.has(complete.eventId)) continue;
|
|
1082
|
+
diagnostics.push({
|
|
1083
|
+
code: "AI_LOGICAL_PAIR_UNMATCHED_COMPLETE",
|
|
1084
|
+
message: `No matching start for complete ${complete.eventId}.`,
|
|
1085
|
+
eventIds: [complete.eventId]
|
|
1086
|
+
});
|
|
1087
|
+
const alone = asLogical(complete);
|
|
1088
|
+
logical.push(alone);
|
|
1089
|
+
logicalByRawId.set(complete.eventId, alone);
|
|
1090
|
+
const stepId = stepIdOf(complete);
|
|
1091
|
+
if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
|
|
1092
|
+
stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
for (const event of others) {
|
|
1096
|
+
const alone = asLogical(event);
|
|
1097
|
+
logical.push(alone);
|
|
1098
|
+
logicalByRawId.set(event.eventId, alone);
|
|
1099
|
+
const stepId = stepIdOf(event);
|
|
1100
|
+
if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
|
|
1101
|
+
stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
const logicalById = new Map(logical.map((e) => [e.eventId, e]));
|
|
1106
|
+
const normalized = [];
|
|
1107
|
+
for (const event of logical) {
|
|
1108
|
+
const originalParentId = event.parentId;
|
|
1109
|
+
if (!originalParentId) {
|
|
1110
|
+
normalized.push(event);
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
let nextParent = originalParentId;
|
|
1114
|
+
let remapped = false;
|
|
1115
|
+
const viaAbsorbed = logicalByRawId.get(originalParentId);
|
|
1116
|
+
if (viaAbsorbed && viaAbsorbed.eventId !== originalParentId) {
|
|
1117
|
+
nextParent = viaAbsorbed.eventId;
|
|
1118
|
+
remapped = true;
|
|
1119
|
+
} else if (!logicalById.has(originalParentId)) {
|
|
1120
|
+
const viaStep = stepIdToLogicalId.get(`${event.runId}:${originalParentId}`);
|
|
1121
|
+
if (viaStep) {
|
|
1122
|
+
nextParent = viaStep;
|
|
1123
|
+
remapped = true;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (!remapped) {
|
|
1127
|
+
if (originalParentId === event.eventId) {
|
|
1128
|
+
diagnostics.push({
|
|
1129
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
1130
|
+
message: formatProgrammaticDiagnostic(
|
|
1131
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
1132
|
+
`Removed self-parent edge on ${event.eventId}.`
|
|
1133
|
+
),
|
|
1134
|
+
eventIds: [event.eventId]
|
|
1135
|
+
});
|
|
1136
|
+
const { parentId: _drop, ...rest } = event;
|
|
1137
|
+
normalized.push({
|
|
1138
|
+
...rest,
|
|
1139
|
+
projection: {
|
|
1140
|
+
...event.projection,
|
|
1141
|
+
parentNormalized: true,
|
|
1142
|
+
originalParentId
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
|
|
1148
|
+
const mapping = event.attributes?.parentMapping;
|
|
1149
|
+
const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
|
|
1150
|
+
/^LangGraph$/i.test(originalParentId) || originalParentId.startsWith("unresolved:");
|
|
1151
|
+
if (!unresolved) {
|
|
1152
|
+
diagnostics.push({
|
|
1153
|
+
code: "AI_LOGICAL_PARENT_UNRESOLVED",
|
|
1154
|
+
message: `Parent ${originalParentId} unresolved for ${event.eventId}.`,
|
|
1155
|
+
eventIds: [event.eventId]
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
normalized.push(event);
|
|
1160
|
+
continue;
|
|
1161
|
+
}
|
|
1162
|
+
if (nextParent === event.eventId) {
|
|
1163
|
+
diagnostics.push({
|
|
1164
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
1165
|
+
message: formatProgrammaticDiagnostic(
|
|
1166
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
1167
|
+
`Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
|
|
1168
|
+
),
|
|
1169
|
+
eventIds: [event.eventId]
|
|
1170
|
+
});
|
|
1171
|
+
const { parentId: _drop, ...rest } = event;
|
|
1172
|
+
normalized.push({
|
|
1173
|
+
...rest,
|
|
1174
|
+
projection: {
|
|
1175
|
+
...event.projection,
|
|
1176
|
+
parentNormalized: true,
|
|
1177
|
+
originalParentId
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
diagnostics.push({
|
|
1183
|
+
code: "AI_LOGICAL_PARENT_REMAPPED",
|
|
1184
|
+
message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
|
|
1185
|
+
eventIds: [event.eventId]
|
|
1186
|
+
});
|
|
1187
|
+
normalized.push({
|
|
1188
|
+
...event,
|
|
1189
|
+
parentId: nextParent,
|
|
1190
|
+
projection: {
|
|
1191
|
+
...event.projection,
|
|
1192
|
+
parentNormalized: true,
|
|
1193
|
+
originalParentId
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
const rawIndex = new Map(events.map((e, i) => [e.eventId, i]));
|
|
1198
|
+
normalized.sort((a, b) => {
|
|
1199
|
+
const ai = rawIndex.get(a.sourceEventIds[0]) ?? 0;
|
|
1200
|
+
const bi = rawIndex.get(b.sourceEventIds[0]) ?? 0;
|
|
1201
|
+
return ai - bi || a.eventId.localeCompare(b.eventId);
|
|
1202
|
+
});
|
|
1203
|
+
return {
|
|
1204
|
+
logicalEvents: Object.freeze(normalized),
|
|
1205
|
+
diagnostics: Object.freeze(diagnostics)
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
|
|
879
1209
|
// packages/core/src/logs/tree-builder.ts
|
|
880
1210
|
function inc(map, key) {
|
|
881
1211
|
map[key] = (map[key] ?? 0) + 1;
|
|
@@ -1168,6 +1498,23 @@ function persistedInspectEventToInspectEvent(event) {
|
|
|
1168
1498
|
if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
|
|
1169
1499
|
out.durationMs = event.durationMs;
|
|
1170
1500
|
}
|
|
1501
|
+
if (event.startedAt !== void 0) {
|
|
1502
|
+
const started = parseIsoToMs2(event.startedAt);
|
|
1503
|
+
if (!started.invalidTimestamp) {
|
|
1504
|
+
attrs.startedAtMs = started.ms;
|
|
1505
|
+
out.timestamp = started.ms;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (event.endedAt !== void 0) {
|
|
1509
|
+
const ended = parseIsoToMs2(event.endedAt);
|
|
1510
|
+
if (!ended.invalidTimestamp) {
|
|
1511
|
+
attrs.endedAtMs = ended.ms;
|
|
1512
|
+
if (out.durationMs === void 0 && typeof attrs.startedAtMs === "number" && ended.ms >= attrs.startedAtMs) {
|
|
1513
|
+
out.durationMs = ended.ms - attrs.startedAtMs;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
out.attributes = compactAttributes2(attrs);
|
|
1171
1518
|
return out;
|
|
1172
1519
|
}
|
|
1173
1520
|
function persistedInspectEventsToInspectEvents(events, options) {
|
|
@@ -1186,66 +1533,18 @@ function persistedInspectEventsToInspectEvents(events, options) {
|
|
|
1186
1533
|
}
|
|
1187
1534
|
|
|
1188
1535
|
// packages/core/src/persisted/tree-bridge.ts
|
|
1536
|
+
function logicalToPersisted(event) {
|
|
1537
|
+
const { sourceEventIds: _sourceEventIds, projection: _projection, ...rest } = event;
|
|
1538
|
+
return rest;
|
|
1539
|
+
}
|
|
1189
1540
|
function persistedInspectEventsToRunTrees(events, options) {
|
|
1190
|
-
const
|
|
1541
|
+
const sourceEvents = options?.coalesceLifecycle === true ? projectLogicalEvents(events).logicalEvents.map(logicalToPersisted) : events;
|
|
1542
|
+
const inspectEvents = persistedInspectEventsToInspectEvents(sourceEvents, {
|
|
1191
1543
|
skipInvalid: options?.skipInvalid
|
|
1192
1544
|
});
|
|
1193
1545
|
return new TreeBuilder().build(inspectEvents);
|
|
1194
1546
|
}
|
|
1195
1547
|
|
|
1196
|
-
// packages/core/src/diagnostics/programmatic.ts
|
|
1197
|
-
var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
|
|
1198
|
-
AI_TRACE_INPUT_INVALID: {
|
|
1199
|
-
code: "AI_TRACE_INPUT_INVALID",
|
|
1200
|
-
summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
|
|
1201
|
-
remediation: "For a file path, use openTraceFile(path).",
|
|
1202
|
-
relatedCodes: ["invalid_input"]
|
|
1203
|
-
},
|
|
1204
|
-
AI_TRACE_FORMAT_UNSUPPORTED: {
|
|
1205
|
-
code: "AI_TRACE_FORMAT_UNSUPPORTED",
|
|
1206
|
-
summary: "No trace reader could detect the input format.",
|
|
1207
|
-
remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
|
|
1208
|
-
relatedCodes: ["unsupported_format"]
|
|
1209
|
-
},
|
|
1210
|
-
AI_TRACE_FORMAT_AMBIGUOUS: {
|
|
1211
|
-
code: "AI_TRACE_FORMAT_AMBIGUOUS",
|
|
1212
|
-
summary: "Multiple trace readers matched the input with equal confidence.",
|
|
1213
|
-
remediation: "Set options.format explicitly to disambiguate the reader.",
|
|
1214
|
-
relatedCodes: ["ambiguous_format"]
|
|
1215
|
-
},
|
|
1216
|
-
AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
|
|
1217
|
-
code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
|
|
1218
|
-
summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
|
|
1219
|
-
remediation: "Use openTraceFile() to normalize a JSONL trace first."
|
|
1220
|
-
},
|
|
1221
|
-
AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
|
|
1222
|
-
code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
1223
|
-
summary: "Multiple runs are available; select a run before executing checks.",
|
|
1224
|
-
remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
|
|
1225
|
-
relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
|
|
1226
|
-
},
|
|
1227
|
-
AI_TRACE_RELATIONSHIP_SELF_PARENT: {
|
|
1228
|
-
code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
1229
|
-
summary: "A parentId equals its own event/step id.",
|
|
1230
|
-
remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
|
|
1231
|
-
relatedCodes: [
|
|
1232
|
-
"AI_LANGGRAPH_SELF_PARENT_REJECTED",
|
|
1233
|
-
"AI_LOGICAL_SELF_PARENT_REMOVED"
|
|
1234
|
-
]
|
|
1235
|
-
},
|
|
1236
|
-
AI_TRACE_RELATIONSHIP_CYCLE: {
|
|
1237
|
-
code: "AI_TRACE_RELATIONSHIP_CYCLE",
|
|
1238
|
-
summary: "Trace contains a parentId cycle.",
|
|
1239
|
-
remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
|
|
1240
|
-
relatedCodes: ["structure.cycle"]
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
function formatProgrammaticDiagnostic(code, detail) {
|
|
1244
|
-
const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
|
|
1245
|
-
const summary = detail?.trim() ? detail.trim() : spec.summary;
|
|
1246
|
-
return `${code}: ${summary} Remediation: ${spec.remediation}`;
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
1548
|
// packages/core/src/readers/mapping-ledger.ts
|
|
1250
1549
|
var OPENINFERENCE_MAPPING_LEDGER = {
|
|
1251
1550
|
id: "openinference-to-agent-inspect",
|
|
@@ -1651,7 +1950,7 @@ function persistedEventsForParsedTrace(parsed) {
|
|
|
1651
1950
|
sourceName: "agent-inspect-jsonl-reader"
|
|
1652
1951
|
});
|
|
1653
1952
|
}
|
|
1654
|
-
function
|
|
1953
|
+
function isRecord6(value) {
|
|
1655
1954
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1656
1955
|
}
|
|
1657
1956
|
function isNonEmptyString3(value) {
|
|
@@ -1666,13 +1965,13 @@ function readStringField(record, keys) {
|
|
|
1666
1965
|
}
|
|
1667
1966
|
function readRecordField(record, key) {
|
|
1668
1967
|
const value = record[key];
|
|
1669
|
-
return
|
|
1968
|
+
return isRecord6(value) ? value : void 0;
|
|
1670
1969
|
}
|
|
1671
1970
|
function parseJsonDocument(content) {
|
|
1672
1971
|
return JSON.parse(content);
|
|
1673
1972
|
}
|
|
1674
1973
|
function looksLikeOpenInferenceSpan(value) {
|
|
1675
|
-
if (!
|
|
1974
|
+
if (!isRecord6(value)) return false;
|
|
1676
1975
|
const attributes = readRecordField(value, "attributes");
|
|
1677
1976
|
return readStringField(value, ["trace_id", "traceId"]) !== void 0 && readStringField(value, ["span_id", "spanId"]) !== void 0 && (readStringField(value, ["name"]) !== void 0 || attributes?.["openinference.span.kind"] !== void 0);
|
|
1678
1977
|
}
|
|
@@ -1697,7 +1996,7 @@ function extractOpenInferenceDocument(root) {
|
|
|
1697
1996
|
unsupportedFields
|
|
1698
1997
|
};
|
|
1699
1998
|
}
|
|
1700
|
-
if (!
|
|
1999
|
+
if (!isRecord6(root)) return void 0;
|
|
1701
2000
|
const rootFormat = root.format;
|
|
1702
2001
|
const rootCompatibility = root.compatibility;
|
|
1703
2002
|
const version = typeof root.version === "string" && root.version.trim() !== "" ? root.version : void 0;
|
|
@@ -1837,7 +2136,7 @@ function summarizeAttributeValue(value) {
|
|
|
1837
2136
|
if (Array.isArray(value)) {
|
|
1838
2137
|
return { type: "array", length: value.length };
|
|
1839
2138
|
}
|
|
1840
|
-
if (
|
|
2139
|
+
if (isRecord6(value)) {
|
|
1841
2140
|
return { type: "object", keyCount: Object.keys(value).length };
|
|
1842
2141
|
}
|
|
1843
2142
|
if (value === null) {
|
|
@@ -1924,7 +2223,7 @@ function mapOpenInferenceKind(span, attributes, pathPrefix) {
|
|
|
1924
2223
|
}
|
|
1925
2224
|
}
|
|
1926
2225
|
function mapOpenInferenceStatus(status) {
|
|
1927
|
-
if (!
|
|
2226
|
+
if (!isRecord6(status)) return void 0;
|
|
1928
2227
|
const rawCode = status.code;
|
|
1929
2228
|
if (typeof rawCode !== "string") return void 0;
|
|
1930
2229
|
switch (rawCode.toUpperCase()) {
|
|
@@ -2032,10 +2331,10 @@ function mapOpenInferenceSpan(span, index, version) {
|
|
|
2032
2331
|
warnings.push(...kindWarnings);
|
|
2033
2332
|
const status = mapOpenInferenceStatus(span.status);
|
|
2034
2333
|
const tokenUsage = readOpenInferenceTokenUsage(rawAttributes);
|
|
2035
|
-
const errorMessage =
|
|
2334
|
+
const errorMessage = isRecord6(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
|
|
2036
2335
|
const event = {
|
|
2037
2336
|
schemaVersion: "0.2",
|
|
2038
|
-
eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId
|
|
2337
|
+
eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
|
|
2039
2338
|
runId: typeof rawAttributes["agent_inspect.run_id"] === "string" ? rawAttributes["agent_inspect.run_id"] : traceId,
|
|
2040
2339
|
kind,
|
|
2041
2340
|
name,
|
|
@@ -2086,12 +2385,16 @@ function mapOpenInferenceEvents(document) {
|
|
|
2086
2385
|
const mapped = document.spans.map(
|
|
2087
2386
|
(span, index) => mapOpenInferenceSpan(span, index, document.version)
|
|
2088
2387
|
);
|
|
2089
|
-
const
|
|
2090
|
-
mapped.map((span) =>
|
|
2388
|
+
const spanKeyToEventId = new Map(
|
|
2389
|
+
mapped.map((span) => {
|
|
2390
|
+
const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
|
|
2391
|
+
return [`${traceId}:${span.spanId}`, span.event.eventId];
|
|
2392
|
+
})
|
|
2091
2393
|
);
|
|
2092
2394
|
for (const span of mapped) {
|
|
2093
2395
|
if (span.parentSpanId === void 0) continue;
|
|
2094
|
-
span.event.
|
|
2396
|
+
const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
|
|
2397
|
+
span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
|
|
2095
2398
|
}
|
|
2096
2399
|
return {
|
|
2097
2400
|
events: mapped.map((span) => span.event),
|
|
@@ -2178,7 +2481,7 @@ var openInferenceJsonReader = {
|
|
|
2178
2481
|
}
|
|
2179
2482
|
};
|
|
2180
2483
|
function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
|
|
2181
|
-
if (!
|
|
2484
|
+
if (!isRecord6(value)) {
|
|
2182
2485
|
unsupportedFields.push(field);
|
|
2183
2486
|
warnings.push({
|
|
2184
2487
|
code: "otlp_attribute_value_invalid",
|
|
@@ -2200,15 +2503,15 @@ function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
|
|
|
2200
2503
|
if (typeof value.doubleValue === "number" && Number.isFinite(value.doubleValue)) {
|
|
2201
2504
|
return value.doubleValue;
|
|
2202
2505
|
}
|
|
2203
|
-
if (
|
|
2506
|
+
if (isRecord6(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
|
|
2204
2507
|
return value.arrayValue.values.map(
|
|
2205
2508
|
(item, index) => parseOtlpAnyValue(item, `${field}.arrayValue.values[${index}]`, warnings, unsupportedFields)
|
|
2206
2509
|
);
|
|
2207
2510
|
}
|
|
2208
|
-
if (
|
|
2511
|
+
if (isRecord6(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
|
|
2209
2512
|
const out = {};
|
|
2210
2513
|
for (const [index, item] of value.kvlistValue.values.entries()) {
|
|
2211
|
-
if (!
|
|
2514
|
+
if (!isRecord6(item) || typeof item.key !== "string") {
|
|
2212
2515
|
unsupportedFields.push(`${field}.kvlistValue.values[${index}]`);
|
|
2213
2516
|
continue;
|
|
2214
2517
|
}
|
|
@@ -2259,7 +2562,7 @@ function parseOtlpAttributes(value, pathPrefix) {
|
|
|
2259
2562
|
}
|
|
2260
2563
|
for (const [index, item] of value.entries()) {
|
|
2261
2564
|
const field = `${pathPrefix}[${index}]`;
|
|
2262
|
-
if (!
|
|
2565
|
+
if (!isRecord6(item) || typeof item.key !== "string") {
|
|
2263
2566
|
unsupportedFields.push(field);
|
|
2264
2567
|
warnings.push({
|
|
2265
2568
|
code: "otlp_attribute_invalid",
|
|
@@ -2282,16 +2585,16 @@ function parseOtlpAttributes(value, pathPrefix) {
|
|
|
2282
2585
|
return { attributes, warnings, unsupportedFields };
|
|
2283
2586
|
}
|
|
2284
2587
|
function looksLikeOtlpSpan(value) {
|
|
2285
|
-
return
|
|
2588
|
+
return isRecord6(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
|
|
2286
2589
|
}
|
|
2287
2590
|
function extractOtlpDocument(root) {
|
|
2288
|
-
if (!
|
|
2591
|
+
if (!isRecord6(root) || !Array.isArray(root.resourceSpans)) return void 0;
|
|
2289
2592
|
const spans = [];
|
|
2290
2593
|
const warnings = [];
|
|
2291
2594
|
const unsupportedFields = [];
|
|
2292
2595
|
for (const [resourceIndex, resourceSpan] of root.resourceSpans.entries()) {
|
|
2293
2596
|
const resourcePath = `resourceSpans[${resourceIndex}]`;
|
|
2294
|
-
if (!
|
|
2597
|
+
if (!isRecord6(resourceSpan)) {
|
|
2295
2598
|
unsupportedFields.push(resourcePath);
|
|
2296
2599
|
continue;
|
|
2297
2600
|
}
|
|
@@ -2314,7 +2617,7 @@ function extractOtlpDocument(root) {
|
|
|
2314
2617
|
}
|
|
2315
2618
|
for (const [scopeIndex, scopeSpan] of resourceSpan.scopeSpans.entries()) {
|
|
2316
2619
|
const scopePath = `${resourcePath}.scopeSpans[${scopeIndex}]`;
|
|
2317
|
-
if (!
|
|
2620
|
+
if (!isRecord6(scopeSpan)) {
|
|
2318
2621
|
unsupportedFields.push(scopePath);
|
|
2319
2622
|
continue;
|
|
2320
2623
|
}
|
|
@@ -2381,22 +2684,40 @@ function extractOtlpDocument(root) {
|
|
|
2381
2684
|
};
|
|
2382
2685
|
}
|
|
2383
2686
|
function mapOtlpStatus(status) {
|
|
2384
|
-
if (!
|
|
2687
|
+
if (!isRecord6(status)) return void 0;
|
|
2385
2688
|
const rawCode = status.code;
|
|
2386
|
-
if (typeof rawCode
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2689
|
+
if (typeof rawCode === "number" && Number.isFinite(rawCode)) {
|
|
2690
|
+
switch (rawCode) {
|
|
2691
|
+
case 0:
|
|
2692
|
+
return "unknown";
|
|
2693
|
+
case 1:
|
|
2694
|
+
return "ok";
|
|
2695
|
+
case 2:
|
|
2696
|
+
return "error";
|
|
2697
|
+
default:
|
|
2698
|
+
return "unknown";
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
if (typeof rawCode === "string") {
|
|
2702
|
+
const trimmed = rawCode.trim();
|
|
2703
|
+
if (/^\d+$/.test(trimmed)) {
|
|
2704
|
+
return mapOtlpStatus({ code: Number(trimmed) });
|
|
2705
|
+
}
|
|
2706
|
+
switch (trimmed.toUpperCase()) {
|
|
2707
|
+
case "STATUS_CODE_OK":
|
|
2708
|
+
case "OK":
|
|
2709
|
+
return "ok";
|
|
2710
|
+
case "STATUS_CODE_ERROR":
|
|
2711
|
+
case "ERROR":
|
|
2712
|
+
return "error";
|
|
2713
|
+
case "STATUS_CODE_UNSET":
|
|
2714
|
+
case "UNSET":
|
|
2715
|
+
return "unknown";
|
|
2716
|
+
default:
|
|
2717
|
+
return "unknown";
|
|
2718
|
+
}
|
|
2399
2719
|
}
|
|
2720
|
+
return void 0;
|
|
2400
2721
|
}
|
|
2401
2722
|
function readOtlpKind(attributes, pathPrefix) {
|
|
2402
2723
|
const warnings = [];
|
|
@@ -2481,7 +2802,7 @@ function mapOtlpEvents(value, pathPrefix) {
|
|
|
2481
2802
|
const events = [];
|
|
2482
2803
|
for (const [index, event] of value.entries()) {
|
|
2483
2804
|
const eventPath = `${pathPrefix}[${index}]`;
|
|
2484
|
-
if (!
|
|
2805
|
+
if (!isRecord6(event)) {
|
|
2485
2806
|
unsupportedFields.push(eventPath);
|
|
2486
2807
|
continue;
|
|
2487
2808
|
}
|
|
@@ -2619,10 +2940,10 @@ function mapOtlpSpan(context) {
|
|
|
2619
2940
|
warnings.push(...kindWarnings);
|
|
2620
2941
|
const status = mapOtlpStatus(span.status);
|
|
2621
2942
|
const tokenUsage = readOtlpTokenUsage(parsedSpanAttributes.attributes);
|
|
2622
|
-
const errorMessage =
|
|
2943
|
+
const errorMessage = isRecord6(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
|
|
2623
2944
|
const event = {
|
|
2624
2945
|
schemaVersion: "0.2",
|
|
2625
|
-
eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId
|
|
2946
|
+
eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : `${traceId}:${spanId}`,
|
|
2626
2947
|
runId: typeof parsedSpanAttributes.attributes["agent_inspect.run_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.run_id"] : traceId,
|
|
2627
2948
|
kind,
|
|
2628
2949
|
name: readStringField(span, ["name"]) ?? spanId,
|
|
@@ -2671,12 +2992,16 @@ function mapOtlpSpan(context) {
|
|
|
2671
2992
|
}
|
|
2672
2993
|
function mapOtlpEventsToPersisted(document) {
|
|
2673
2994
|
const mapped = document.spans.map((span) => mapOtlpSpan(span));
|
|
2674
|
-
const
|
|
2675
|
-
mapped.map((span) =>
|
|
2995
|
+
const spanKeyToEventId = new Map(
|
|
2996
|
+
mapped.map((span) => {
|
|
2997
|
+
const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
|
|
2998
|
+
return [`${traceId}:${span.spanId}`, span.event.eventId];
|
|
2999
|
+
})
|
|
2676
3000
|
);
|
|
2677
3001
|
for (const span of mapped) {
|
|
2678
3002
|
if (span.parentSpanId === void 0) continue;
|
|
2679
|
-
span.event.
|
|
3003
|
+
const traceId = typeof span.event.trace?.traceId === "string" ? span.event.trace.traceId : "";
|
|
3004
|
+
span.event.parentId = spanKeyToEventId.get(`${traceId}:${span.parentSpanId}`) ?? span.parentSpanId;
|
|
2680
3005
|
}
|
|
2681
3006
|
return {
|
|
2682
3007
|
events: mapped.map((span) => span.event),
|