agent-inspect 6.31.7 → 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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/packages/cli/dist/{chunk-QV73NM25.mjs → chunk-6FE47XSF.mjs} +24 -11
  5. package/packages/cli/dist/chunk-6FE47XSF.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +176 -42
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +156 -36
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-KFOBXFPN.mjs → src-NXAYHG34.mjs} +3 -3
  11. package/packages/cli/dist/{src-KFOBXFPN.mjs.map → src-NXAYHG34.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +22 -9
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.mjs +5 -5
  15. package/packages/core/dist/checks.mjs +2 -2
  16. package/packages/core/dist/{chunk-LXYPM2ZO.mjs → chunk-2CCRUI42.mjs} +19 -318
  17. package/packages/core/dist/chunk-2CCRUI42.mjs.map +1 -0
  18. package/packages/core/dist/{chunk-QLYUWKK7.mjs → chunk-2IRRUNIN.mjs} +11 -5
  19. package/packages/core/dist/chunk-2IRRUNIN.mjs.map +1 -0
  20. package/packages/core/dist/{chunk-3RV3JILQ.mjs → chunk-IJJSPJXV.mjs} +20 -12
  21. package/packages/core/dist/chunk-IJJSPJXV.mjs.map +1 -0
  22. package/packages/core/dist/chunk-L5WLVBW4.mjs +355 -0
  23. package/packages/core/dist/chunk-L5WLVBW4.mjs.map +1 -0
  24. package/packages/core/dist/exporters.cjs +110 -18
  25. package/packages/core/dist/exporters.cjs.map +1 -1
  26. package/packages/core/dist/exporters.mjs +110 -18
  27. package/packages/core/dist/exporters.mjs.map +1 -1
  28. package/packages/core/dist/persisted.cjs +344 -9
  29. package/packages/core/dist/persisted.cjs.map +1 -1
  30. package/packages/core/dist/persisted.d.cts +8 -1
  31. package/packages/core/dist/persisted.d.ts +8 -1
  32. package/packages/core/dist/persisted.mjs +3 -2
  33. package/packages/core/dist/persisted.mjs.map +1 -1
  34. package/packages/core/dist/readers.cjs +377 -87
  35. package/packages/core/dist/readers.cjs.map +1 -1
  36. package/packages/core/dist/readers.mjs +3 -3
  37. package/packages/cli/dist/chunk-QV73NM25.mjs.map +0 -1
  38. package/packages/core/dist/chunk-3RV3JILQ.mjs.map +0 -1
  39. package/packages/core/dist/chunk-FWK3Q3OJ.mjs +0 -56
  40. package/packages/core/dist/chunk-FWK3Q3OJ.mjs.map +0 -1
  41. package/packages/core/dist/chunk-LXYPM2ZO.mjs.map +0 -1
  42. package/packages/core/dist/chunk-QLYUWKK7.mjs.map +0 -1
@@ -0,0 +1,355 @@
1
+ // packages/core/src/diagnostics/programmatic.ts
2
+ var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
3
+ AI_TRACE_INPUT_INVALID: {
4
+ code: "AI_TRACE_INPUT_INVALID",
5
+ summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
6
+ remediation: "For a file path, use openTraceFile(path).",
7
+ relatedCodes: ["invalid_input"]
8
+ },
9
+ AI_TRACE_FORMAT_UNSUPPORTED: {
10
+ code: "AI_TRACE_FORMAT_UNSUPPORTED",
11
+ summary: "No trace reader could detect the input format.",
12
+ remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
13
+ relatedCodes: ["unsupported_format"]
14
+ },
15
+ AI_TRACE_FORMAT_AMBIGUOUS: {
16
+ code: "AI_TRACE_FORMAT_AMBIGUOUS",
17
+ summary: "Multiple trace readers matched the input with equal confidence.",
18
+ remediation: "Set options.format explicitly to disambiguate the reader.",
19
+ relatedCodes: ["ambiguous_format"]
20
+ },
21
+ AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
22
+ code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
23
+ summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
24
+ remediation: "Use openTraceFile() to normalize a JSONL trace first."
25
+ },
26
+ AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
27
+ code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
28
+ summary: "Multiple runs are available; select a run before executing checks.",
29
+ remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
30
+ relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
31
+ },
32
+ AI_TRACE_RELATIONSHIP_SELF_PARENT: {
33
+ code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
34
+ summary: "A parentId equals its own event/step id.",
35
+ remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
36
+ relatedCodes: [
37
+ "AI_LANGGRAPH_SELF_PARENT_REJECTED",
38
+ "AI_LOGICAL_SELF_PARENT_REMOVED"
39
+ ]
40
+ },
41
+ AI_TRACE_RELATIONSHIP_CYCLE: {
42
+ code: "AI_TRACE_RELATIONSHIP_CYCLE",
43
+ summary: "Trace contains a parentId cycle.",
44
+ remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
45
+ relatedCodes: ["structure.cycle"]
46
+ }
47
+ });
48
+ function formatProgrammaticDiagnostic(code, detail) {
49
+ const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
50
+ const summary = detail?.trim() ? detail.trim() : spec.summary;
51
+ return `${code}: ${summary} Remediation: ${spec.remediation}`;
52
+ }
53
+
54
+ // packages/core/src/checks/logical-events.ts
55
+ function isRecord(value) {
56
+ return typeof value === "object" && value !== null && !Array.isArray(value);
57
+ }
58
+ function legacyEvent(event) {
59
+ const value = event.attributes?.legacyEvent;
60
+ return typeof value === "string" ? value : void 0;
61
+ }
62
+ function stepIdOf(event) {
63
+ const value = event.attributes?.stepId;
64
+ if (typeof value === "string" && value.trim() !== "") return value;
65
+ return void 0;
66
+ }
67
+ function cloneEvent(event) {
68
+ return {
69
+ ...event,
70
+ ...event.attributes !== void 0 ? { attributes: { ...event.attributes } } : {},
71
+ ...event.error !== void 0 ? { error: { ...event.error } } : {},
72
+ ...event.tokenUsage !== void 0 ? { tokenUsage: { ...event.tokenUsage } } : {},
73
+ ...event.source !== void 0 ? { source: { ...event.source } } : {}
74
+ };
75
+ }
76
+ function mergeAttributes(start, complete) {
77
+ const merged = {
78
+ ...isRecord(complete.attributes) ? complete.attributes : {},
79
+ ...isRecord(start.attributes) ? start.attributes : {}
80
+ };
81
+ merged.legacyEvent = start.attributes?.legacyEvent ?? complete.attributes?.legacyEvent;
82
+ merged.legacyCompleteEvent = complete.attributes?.legacyEvent;
83
+ if (complete.attributes?.errorStack !== void 0) {
84
+ merged.errorStack = complete.attributes.errorStack;
85
+ }
86
+ return Object.keys(merged).length > 0 ? merged : void 0;
87
+ }
88
+ function pairStartComplete(start, complete) {
89
+ const attributes = mergeAttributes(start, complete);
90
+ const paired = {
91
+ ...cloneEvent(start),
92
+ status: complete.status,
93
+ timestamp: complete.timestamp ?? start.timestamp,
94
+ ...complete.endedAt !== void 0 ? { endedAt: complete.endedAt } : {},
95
+ ...complete.durationMs !== void 0 ? { durationMs: complete.durationMs } : {},
96
+ ...complete.error !== void 0 ? { error: { ...complete.error } } : {},
97
+ ...complete.tokenUsage !== void 0 && start.tokenUsage === void 0 ? { tokenUsage: { ...complete.tokenUsage } } : {},
98
+ ...attributes !== void 0 ? { attributes } : {}
99
+ };
100
+ return {
101
+ ...paired,
102
+ sourceEventIds: Object.freeze([start.eventId, complete.eventId]),
103
+ projection: {
104
+ paired: true,
105
+ absorbedEventIds: Object.freeze([complete.eventId]),
106
+ parentNormalized: false,
107
+ ...start.parentId !== void 0 ? { originalParentId: start.parentId } : {}
108
+ }
109
+ };
110
+ }
111
+ function asLogical(event, extras) {
112
+ return {
113
+ ...cloneEvent(event),
114
+ sourceEventIds: Object.freeze([event.eventId]),
115
+ projection: {
116
+ paired: false,
117
+ absorbedEventIds: Object.freeze([]),
118
+ parentNormalized: extras?.parentNormalized === true,
119
+ ...{}
120
+ }
121
+ };
122
+ }
123
+ function projectLogicalEvents(events) {
124
+ const diagnostics = [];
125
+ const byRun = /* @__PURE__ */ new Map();
126
+ for (const event of events) {
127
+ const list = byRun.get(event.runId) ?? [];
128
+ list.push(event);
129
+ byRun.set(event.runId, list);
130
+ }
131
+ const absorbedIds = /* @__PURE__ */ new Set();
132
+ const logicalByRawId = /* @__PURE__ */ new Map();
133
+ const stepIdToLogicalId = /* @__PURE__ */ new Map();
134
+ const logical = [];
135
+ const orderedRuns = [...byRun.keys()].sort((a, b) => a.localeCompare(b));
136
+ for (const runId of orderedRuns) {
137
+ const runEvents = byRun.get(runId) ?? [];
138
+ const starts = [];
139
+ const completes = [];
140
+ const others = [];
141
+ for (const event of runEvents) {
142
+ const legacy = legacyEvent(event);
143
+ if (legacy === "step_started" || legacy === "run_started" && event.status === "running") {
144
+ starts.push(event);
145
+ } else if (legacy === "step_completed" || legacy === "run_completed") {
146
+ completes.push(event);
147
+ } else {
148
+ others.push(event);
149
+ }
150
+ }
151
+ const usedCompletes = /* @__PURE__ */ new Set();
152
+ for (const start of starts) {
153
+ const stepId = stepIdOf(start);
154
+ let match;
155
+ if (legacyEvent(start) === "run_started") {
156
+ const candidates = completes.filter(
157
+ (c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "run_completed"
158
+ );
159
+ if (candidates.length > 1) {
160
+ diagnostics.push({
161
+ code: "AI_LOGICAL_PAIR_AMBIGUOUS",
162
+ message: `Multiple run_completed rows for run ${runId}; using first by eventId.`,
163
+ eventIds: candidates.map((c) => c.eventId)
164
+ });
165
+ candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));
166
+ }
167
+ match = candidates[0];
168
+ } else if (stepId) {
169
+ const candidates = completes.filter(
170
+ (c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "step_completed" && stepIdOf(c) === stepId
171
+ );
172
+ if (candidates.length > 1) {
173
+ diagnostics.push({
174
+ code: "AI_LOGICAL_PAIR_AMBIGUOUS",
175
+ message: `Multiple step_completed rows for stepId ${stepId}; using first by eventId.`,
176
+ eventIds: candidates.map((c) => c.eventId)
177
+ });
178
+ candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));
179
+ }
180
+ match = candidates[0];
181
+ }
182
+ if (match) {
183
+ usedCompletes.add(match.eventId);
184
+ absorbedIds.add(match.eventId);
185
+ const paired = pairStartComplete(start, match);
186
+ logical.push(paired);
187
+ logicalByRawId.set(start.eventId, paired);
188
+ logicalByRawId.set(match.eventId, paired);
189
+ if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, paired.eventId);
190
+ } else {
191
+ diagnostics.push({
192
+ code: "AI_LOGICAL_PAIR_UNMATCHED_START",
193
+ message: `No matching complete for start ${start.eventId}.`,
194
+ eventIds: [start.eventId]
195
+ });
196
+ const alone = asLogical(start);
197
+ logical.push(alone);
198
+ logicalByRawId.set(start.eventId, alone);
199
+ if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
200
+ }
201
+ }
202
+ for (const complete of completes) {
203
+ if (usedCompletes.has(complete.eventId)) continue;
204
+ diagnostics.push({
205
+ code: "AI_LOGICAL_PAIR_UNMATCHED_COMPLETE",
206
+ message: `No matching start for complete ${complete.eventId}.`,
207
+ eventIds: [complete.eventId]
208
+ });
209
+ const alone = asLogical(complete);
210
+ logical.push(alone);
211
+ logicalByRawId.set(complete.eventId, alone);
212
+ const stepId = stepIdOf(complete);
213
+ if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
214
+ stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
215
+ }
216
+ }
217
+ for (const event of others) {
218
+ const alone = asLogical(event);
219
+ logical.push(alone);
220
+ logicalByRawId.set(event.eventId, alone);
221
+ const stepId = stepIdOf(event);
222
+ if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
223
+ stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
224
+ }
225
+ }
226
+ }
227
+ const logicalById = new Map(logical.map((e) => [e.eventId, e]));
228
+ const normalized = [];
229
+ for (const event of logical) {
230
+ const originalParentId = event.parentId;
231
+ if (!originalParentId) {
232
+ normalized.push(event);
233
+ continue;
234
+ }
235
+ let nextParent = originalParentId;
236
+ let remapped = false;
237
+ const viaAbsorbed = logicalByRawId.get(originalParentId);
238
+ if (viaAbsorbed && viaAbsorbed.eventId !== originalParentId) {
239
+ nextParent = viaAbsorbed.eventId;
240
+ remapped = true;
241
+ } else if (!logicalById.has(originalParentId)) {
242
+ const viaStep = stepIdToLogicalId.get(`${event.runId}:${originalParentId}`);
243
+ if (viaStep) {
244
+ nextParent = viaStep;
245
+ remapped = true;
246
+ }
247
+ }
248
+ if (!remapped) {
249
+ if (originalParentId === event.eventId) {
250
+ diagnostics.push({
251
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
252
+ message: formatProgrammaticDiagnostic(
253
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
254
+ `Removed self-parent edge on ${event.eventId}.`
255
+ ),
256
+ eventIds: [event.eventId]
257
+ });
258
+ const { parentId: _drop, ...rest } = event;
259
+ normalized.push({
260
+ ...rest,
261
+ projection: {
262
+ ...event.projection,
263
+ parentNormalized: true,
264
+ originalParentId
265
+ }
266
+ });
267
+ continue;
268
+ }
269
+ if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
270
+ const mapping = event.attributes?.parentMapping;
271
+ const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
272
+ /^LangGraph$/i.test(originalParentId) || originalParentId.startsWith("unresolved:");
273
+ if (!unresolved) {
274
+ diagnostics.push({
275
+ code: "AI_LOGICAL_PARENT_UNRESOLVED",
276
+ message: `Parent ${originalParentId} unresolved for ${event.eventId}.`,
277
+ eventIds: [event.eventId]
278
+ });
279
+ }
280
+ }
281
+ normalized.push(event);
282
+ continue;
283
+ }
284
+ if (nextParent === event.eventId) {
285
+ diagnostics.push({
286
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
287
+ message: formatProgrammaticDiagnostic(
288
+ "AI_TRACE_RELATIONSHIP_SELF_PARENT",
289
+ `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
290
+ ),
291
+ eventIds: [event.eventId]
292
+ });
293
+ const { parentId: _drop, ...rest } = event;
294
+ normalized.push({
295
+ ...rest,
296
+ projection: {
297
+ ...event.projection,
298
+ parentNormalized: true,
299
+ originalParentId
300
+ }
301
+ });
302
+ continue;
303
+ }
304
+ diagnostics.push({
305
+ code: "AI_LOGICAL_PARENT_REMAPPED",
306
+ message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
307
+ eventIds: [event.eventId]
308
+ });
309
+ normalized.push({
310
+ ...event,
311
+ parentId: nextParent,
312
+ projection: {
313
+ ...event.projection,
314
+ parentNormalized: true,
315
+ originalParentId
316
+ }
317
+ });
318
+ }
319
+ const rawIndex = new Map(events.map((e, i) => [e.eventId, i]));
320
+ normalized.sort((a, b) => {
321
+ const ai = rawIndex.get(a.sourceEventIds[0]) ?? 0;
322
+ const bi = rawIndex.get(b.sourceEventIds[0]) ?? 0;
323
+ return ai - bi || a.eventId.localeCompare(b.eventId);
324
+ });
325
+ return {
326
+ logicalEvents: Object.freeze(normalized),
327
+ diagnostics: Object.freeze(diagnostics)
328
+ };
329
+ }
330
+ function resolveCanonicalToolName(event) {
331
+ const attrs = event.attributes;
332
+ const direct = pickString(attrs, ["toolName", "tool"]);
333
+ if (direct) return direct;
334
+ const metadata = attrs?.metadata;
335
+ if (isRecord(metadata)) {
336
+ const nested = pickString(metadata, ["toolName", "tool"]);
337
+ if (nested) return nested;
338
+ }
339
+ for (const prefix of ["tool:", "function:", "mcp-tools:"]) {
340
+ if (event.name.startsWith(prefix)) return event.name.slice(prefix.length);
341
+ }
342
+ return event.name;
343
+ }
344
+ function pickString(record, keys) {
345
+ if (!record) return void 0;
346
+ for (const key of keys) {
347
+ const value = record[key];
348
+ if (typeof value === "string" && value.trim() !== "") return value.trim();
349
+ }
350
+ return void 0;
351
+ }
352
+
353
+ export { PROGRAMMATIC_DIAGNOSTIC_SPECS, formatProgrammaticDiagnostic, projectLogicalEvents, resolveCanonicalToolName };
354
+ //# sourceMappingURL=chunk-L5WLVBW4.mjs.map
355
+ //# sourceMappingURL=chunk-L5WLVBW4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/diagnostics/programmatic.ts","../src/checks/logical-events.ts"],"names":[],"mappings":"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","file":"chunk-L5WLVBW4.mjs","sourcesContent":["/**\n * Stable programmatic diagnostic codes for readers / TraceFacts / TraceContract.\n *\n * Lowercase `TraceReadError.code` values remain the published reader error codes.\n * These `AI_*` identifiers appear in messages and catalogs for actionable remediation.\n *\n * @experimental Additive in 6.15.0; do not replace published lowercase reader codes.\n */\n\nexport type ProgrammaticDiagnosticCode =\n | \"AI_TRACE_INPUT_INVALID\"\n | \"AI_TRACE_FORMAT_UNSUPPORTED\"\n | \"AI_TRACE_FORMAT_AMBIGUOUS\"\n | \"AI_TRACE_FACTS_INPUT_NOT_NORMALIZED\"\n | \"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED\"\n | \"AI_TRACE_RELATIONSHIP_SELF_PARENT\"\n | \"AI_TRACE_RELATIONSHIP_CYCLE\";\n\nexport interface ProgrammaticDiagnosticSpec {\n readonly code: ProgrammaticDiagnosticCode;\n /** Short problem statement (without the code prefix). */\n readonly summary: string;\n /** Actionable remediation hint (always included in formatted messages). */\n readonly remediation: string;\n /** Related published / capture codes that must remain valid. */\n readonly relatedCodes?: readonly string[];\n}\n\nexport const PROGRAMMATIC_DIAGNOSTIC_SPECS: Readonly<\n Record<ProgrammaticDiagnosticCode, ProgrammaticDiagnosticSpec>\n> = Object.freeze({\n AI_TRACE_INPUT_INVALID: {\n code: \"AI_TRACE_INPUT_INVALID\",\n summary:\n 'Expected { type: \"file\", path }, { type: \"directory\", path }, { type: \"string\", content }, { type: \"buffer\", content }, or { type: \"stdin\" }.',\n remediation: \"For a file path, use openTraceFile(path).\",\n relatedCodes: [\"invalid_input\"],\n },\n AI_TRACE_FORMAT_UNSUPPORTED: {\n code: \"AI_TRACE_FORMAT_UNSUPPORTED\",\n summary: \"No trace reader could detect the input format.\",\n remediation:\n \"Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.\",\n relatedCodes: [\"unsupported_format\"],\n },\n AI_TRACE_FORMAT_AMBIGUOUS: {\n code: \"AI_TRACE_FORMAT_AMBIGUOUS\",\n summary: \"Multiple trace readers matched the input with equal confidence.\",\n remediation: \"Set options.format explicitly to disambiguate the reader.\",\n relatedCodes: [\"ambiguous_format\"],\n },\n AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {\n code: \"AI_TRACE_FACTS_INPUT_NOT_NORMALIZED\",\n summary: \"TraceFacts requires TraceReadResult or PersistedInspectEvent[].\",\n remediation: \"Use openTraceFile() to normalize a JSONL trace first.\",\n },\n AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {\n code: \"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED\",\n summary: \"Multiple runs are available; select a run before executing checks.\",\n remediation: \"Pass options.runId or TraceCheckInput.selectedRun.\",\n relatedCodes: [\"AI_CHECK_RUN_SELECTION_REQUIRED\"],\n },\n AI_TRACE_RELATIONSHIP_SELF_PARENT: {\n code: \"AI_TRACE_RELATIONSHIP_SELF_PARENT\",\n summary: \"A parentId equals its own event/step id.\",\n remediation:\n \"Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.\",\n relatedCodes: [\n \"AI_LANGGRAPH_SELF_PARENT_REJECTED\",\n \"AI_LOGICAL_SELF_PARENT_REMOVED\",\n ],\n },\n AI_TRACE_RELATIONSHIP_CYCLE: {\n code: \"AI_TRACE_RELATIONSHIP_CYCLE\",\n summary: \"Trace contains a parentId cycle.\",\n remediation:\n \"Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.\",\n relatedCodes: [\"structure.cycle\"],\n },\n});\n\n/**\n * Format `CODE: summary Remediation: …` for thrown errors and diagnostics.\n */\nexport function formatProgrammaticDiagnostic(\n code: ProgrammaticDiagnosticCode,\n detail?: string,\n): string {\n const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];\n const summary = detail?.trim() ? detail.trim() : spec.summary;\n return `${code}: ${summary} Remediation: ${spec.remediation}`;\n}\n","/**\n * Logical lifecycle projection for trace checks.\n *\n * Projects raw persisted rows (including v0.1 start/complete bridges) into\n * completed lifecycle events for semantic/structure rules. Does not mutate\n * input; does not replace public experimental `events` (raw rows).\n *\n * @experimental Available through `agent-inspect/checks`; may evolve.\n */\n\nimport type { PersistedInspectEvent } from \"../types/persisted-inspect-event.js\";\nimport { formatProgrammaticDiagnostic } from \"../diagnostics/programmatic.js\";\n\n/**\n * Diagnostic emitted while projecting logical lifecycle events.\n *\n * @experimental\n */\nexport interface LogicalProjectionDiagnostic {\n code:\n | \"AI_LOGICAL_PAIR_AMBIGUOUS\"\n | \"AI_LOGICAL_PAIR_UNMATCHED_START\"\n | \"AI_LOGICAL_PAIR_UNMATCHED_COMPLETE\"\n | \"AI_LOGICAL_PARENT_REMAPPED\"\n | \"AI_LOGICAL_PARENT_UNRESOLVED\"\n | \"AI_LOGICAL_SELF_PARENT_REMOVED\";\n message: string;\n eventIds?: readonly string[];\n}\n\n/**\n * A persisted event after lifecycle pairing and parent normalization.\n * Compatible with rule helpers that read PersistedInspectEvent fields.\n *\n * @experimental\n */\nexport type LogicalTraceEvent = PersistedInspectEvent & {\n /** Raw event ids merged into this logical row (start first when paired). */\n readonly sourceEventIds: readonly string[];\n readonly projection: {\n readonly paired: boolean;\n readonly absorbedEventIds: readonly string[];\n readonly parentNormalized: boolean;\n readonly originalParentId?: string;\n };\n};\n\nexport interface ProjectLogicalEventsResult {\n readonly logicalEvents: readonly LogicalTraceEvent[];\n readonly diagnostics: readonly LogicalProjectionDiagnostic[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction legacyEvent(event: PersistedInspectEvent): string | undefined {\n const value = event.attributes?.legacyEvent;\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction stepIdOf(event: PersistedInspectEvent): string | undefined {\n const value = event.attributes?.stepId;\n if (typeof value === \"string\" && value.trim() !== \"\") return value;\n return undefined;\n}\n\nfunction cloneEvent(event: PersistedInspectEvent): PersistedInspectEvent {\n return {\n ...event,\n ...(event.attributes !== undefined\n ? { attributes: { ...event.attributes } }\n : {}),\n ...(event.error !== undefined ? { error: { ...event.error } } : {}),\n ...(event.tokenUsage !== undefined\n ? { tokenUsage: { ...event.tokenUsage } }\n : {}),\n ...(event.source !== undefined ? { source: { ...event.source } } : {}),\n };\n}\n\nfunction mergeAttributes(\n start: PersistedInspectEvent,\n complete: PersistedInspectEvent,\n): Record<string, unknown> | undefined {\n const merged: Record<string, unknown> = {\n ...(isRecord(complete.attributes) ? complete.attributes : {}),\n ...(isRecord(start.attributes) ? start.attributes : {}),\n };\n // Prefer start kind/name identity; keep completion markers for debugging.\n merged.legacyEvent = start.attributes?.legacyEvent ?? complete.attributes?.legacyEvent;\n merged.legacyCompleteEvent = complete.attributes?.legacyEvent;\n if (complete.attributes?.errorStack !== undefined) {\n merged.errorStack = complete.attributes.errorStack;\n }\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction pairStartComplete(\n start: PersistedInspectEvent,\n complete: PersistedInspectEvent,\n): LogicalTraceEvent {\n const attributes = mergeAttributes(start, complete);\n const paired: PersistedInspectEvent = {\n ...cloneEvent(start),\n status: complete.status,\n timestamp: complete.timestamp ?? start.timestamp,\n ...(complete.endedAt !== undefined ? { endedAt: complete.endedAt } : {}),\n ...(complete.durationMs !== undefined\n ? { durationMs: complete.durationMs }\n : {}),\n ...(complete.error !== undefined ? { error: { ...complete.error } } : {}),\n ...(complete.tokenUsage !== undefined && start.tokenUsage === undefined\n ? { tokenUsage: { ...complete.tokenUsage } }\n : {}),\n ...(attributes !== undefined ? { attributes } : {}),\n };\n\n return {\n ...paired,\n sourceEventIds: Object.freeze([start.eventId, complete.eventId]),\n projection: {\n paired: true,\n absorbedEventIds: Object.freeze([complete.eventId]),\n parentNormalized: false,\n ...(start.parentId !== undefined\n ? { originalParentId: start.parentId }\n : {}),\n },\n };\n}\n\nfunction asLogical(\n event: PersistedInspectEvent,\n extras?: { parentNormalized?: boolean; originalParentId?: string },\n): LogicalTraceEvent {\n return {\n ...cloneEvent(event),\n sourceEventIds: Object.freeze([event.eventId]),\n projection: {\n paired: false,\n absorbedEventIds: Object.freeze([]),\n parentNormalized: extras?.parentNormalized === true,\n ...(extras?.originalParentId !== undefined\n ? { originalParentId: extras.originalParentId }\n : {}),\n },\n };\n}\n\n/**\n * Pair v0.1 run/step start+complete rows and normalize parent references.\n *\n * - Keeps start kind/name; applies terminal status/timing/error from complete.\n * - Absorbs matching complete rows (not emitted as separate logical events).\n * - Remaps parentId from stepId or absorbed complete eventId → logical eventId.\n */\nexport function projectLogicalEvents(\n events: readonly PersistedInspectEvent[],\n): ProjectLogicalEventsResult {\n const diagnostics: LogicalProjectionDiagnostic[] = [];\n const byRun = new Map<string, PersistedInspectEvent[]>();\n for (const event of events) {\n const list = byRun.get(event.runId) ?? [];\n list.push(event);\n byRun.set(event.runId, list);\n }\n\n const absorbedIds = new Set<string>();\n const logicalByRawId = new Map<string, LogicalTraceEvent>();\n const stepIdToLogicalId = new Map<string, string>();\n const logical: LogicalTraceEvent[] = [];\n\n const orderedRuns = [...byRun.keys()].sort((a, b) => a.localeCompare(b));\n for (const runId of orderedRuns) {\n const runEvents = byRun.get(runId) ?? [];\n const starts: PersistedInspectEvent[] = [];\n const completes: PersistedInspectEvent[] = [];\n const others: PersistedInspectEvent[] = [];\n\n for (const event of runEvents) {\n const legacy = legacyEvent(event);\n if (\n legacy === \"step_started\" ||\n (legacy === \"run_started\" && event.status === \"running\")\n ) {\n starts.push(event);\n } else if (legacy === \"step_completed\" || legacy === \"run_completed\") {\n completes.push(event);\n } else {\n others.push(event);\n }\n }\n\n const usedCompletes = new Set<string>();\n\n for (const start of starts) {\n const stepId = stepIdOf(start);\n let match: PersistedInspectEvent | undefined;\n\n if (legacyEvent(start) === \"run_started\") {\n const candidates = completes.filter(\n (c) =>\n !usedCompletes.has(c.eventId) && legacyEvent(c) === \"run_completed\",\n );\n if (candidates.length > 1) {\n diagnostics.push({\n code: \"AI_LOGICAL_PAIR_AMBIGUOUS\",\n message: `Multiple run_completed rows for run ${runId}; using first by eventId.`,\n eventIds: candidates.map((c) => c.eventId),\n });\n candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));\n }\n match = candidates[0];\n } else if (stepId) {\n const candidates = completes.filter(\n (c) =>\n !usedCompletes.has(c.eventId) &&\n legacyEvent(c) === \"step_completed\" &&\n stepIdOf(c) === stepId,\n );\n if (candidates.length > 1) {\n diagnostics.push({\n code: \"AI_LOGICAL_PAIR_AMBIGUOUS\",\n message: `Multiple step_completed rows for stepId ${stepId}; using first by eventId.`,\n eventIds: candidates.map((c) => c.eventId),\n });\n candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));\n }\n match = candidates[0];\n }\n\n if (match) {\n usedCompletes.add(match.eventId);\n absorbedIds.add(match.eventId);\n const paired = pairStartComplete(start, match);\n logical.push(paired);\n logicalByRawId.set(start.eventId, paired);\n logicalByRawId.set(match.eventId, paired);\n if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, paired.eventId);\n } else {\n diagnostics.push({\n code: \"AI_LOGICAL_PAIR_UNMATCHED_START\",\n message: `No matching complete for start ${start.eventId}.`,\n eventIds: [start.eventId],\n });\n const alone = asLogical(start);\n logical.push(alone);\n logicalByRawId.set(start.eventId, alone);\n if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);\n }\n }\n\n for (const complete of completes) {\n if (usedCompletes.has(complete.eventId)) continue;\n diagnostics.push({\n code: \"AI_LOGICAL_PAIR_UNMATCHED_COMPLETE\",\n message: `No matching start for complete ${complete.eventId}.`,\n eventIds: [complete.eventId],\n });\n const alone = asLogical(complete);\n logical.push(alone);\n logicalByRawId.set(complete.eventId, alone);\n const stepId = stepIdOf(complete);\n if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {\n stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);\n }\n }\n\n for (const event of others) {\n const alone = asLogical(event);\n logical.push(alone);\n logicalByRawId.set(event.eventId, alone);\n const stepId = stepIdOf(event);\n if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {\n stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);\n }\n }\n }\n\n // Parent / forest normalization over the logical set.\n const logicalById = new Map(logical.map((e) => [e.eventId, e]));\n const normalized: LogicalTraceEvent[] = [];\n\n for (const event of logical) {\n const originalParentId = event.parentId;\n if (!originalParentId) {\n normalized.push(event);\n continue;\n }\n\n let nextParent = originalParentId;\n let remapped = false;\n\n // Absorbed complete eventId → paired start eventId\n const viaAbsorbed = logicalByRawId.get(originalParentId);\n if (viaAbsorbed && viaAbsorbed.eventId !== originalParentId) {\n nextParent = viaAbsorbed.eventId;\n remapped = true;\n } else if (!logicalById.has(originalParentId)) {\n // Treat parentId as stepId within the same run\n const viaStep = stepIdToLogicalId.get(`${event.runId}:${originalParentId}`);\n if (viaStep) {\n nextParent = viaStep;\n remapped = true;\n }\n }\n\n if (!remapped) {\n if (originalParentId === event.eventId) {\n diagnostics.push({\n code: \"AI_LOGICAL_SELF_PARENT_REMOVED\",\n message: formatProgrammaticDiagnostic(\n \"AI_TRACE_RELATIONSHIP_SELF_PARENT\",\n `Removed self-parent edge on ${event.eventId}.`,\n ),\n eventIds: [event.eventId],\n });\n const { parentId: _drop, ...rest } = event;\n normalized.push({\n ...rest,\n projection: {\n ...event.projection,\n parentNormalized: true,\n originalParentId,\n },\n });\n continue;\n }\n if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {\n const mapping = event.attributes?.parentMapping;\n const unresolved =\n mapping === \"unresolved\" ||\n event.attributes?.parentUnresolved === true ||\n event.attributes?.unresolvedParent === true ||\n // LangGraph/framework scaffolding sentinel labels are not event ids.\n /^LangGraph$/i.test(originalParentId) ||\n originalParentId.startsWith(\"unresolved:\");\n if (!unresolved) {\n diagnostics.push({\n code: \"AI_LOGICAL_PARENT_UNRESOLVED\",\n message: `Parent ${originalParentId} unresolved for ${event.eventId}.`,\n eventIds: [event.eventId],\n });\n }\n }\n normalized.push(event);\n continue;\n }\n\n if (nextParent === event.eventId) {\n diagnostics.push({\n code: \"AI_LOGICAL_SELF_PARENT_REMOVED\",\n message: formatProgrammaticDiagnostic(\n \"AI_TRACE_RELATIONSHIP_SELF_PARENT\",\n `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,\n ),\n eventIds: [event.eventId],\n });\n const { parentId: _drop, ...rest } = event;\n normalized.push({\n ...rest,\n projection: {\n ...event.projection,\n parentNormalized: true,\n originalParentId,\n },\n });\n continue;\n }\n\n diagnostics.push({\n code: \"AI_LOGICAL_PARENT_REMAPPED\",\n message: `Remapped parent ${originalParentId} → ${nextParent} for ${event.eventId}.`,\n eventIds: [event.eventId],\n });\n\n normalized.push({\n ...event,\n parentId: nextParent,\n projection: {\n ...event.projection,\n parentNormalized: true,\n originalParentId,\n },\n });\n }\n\n // Stable order: original raw encounter order by first source event index.\n const rawIndex = new Map(events.map((e, i) => [e.eventId, i]));\n normalized.sort((a, b) => {\n const ai = rawIndex.get(a.sourceEventIds[0]!) ?? 0;\n const bi = rawIndex.get(b.sourceEventIds[0]!) ?? 0;\n return ai - bi || a.eventId.localeCompare(b.eventId);\n });\n\n return {\n logicalEvents: Object.freeze(normalized),\n diagnostics: Object.freeze(diagnostics),\n };\n}\n\n/**\n * Resolve a human-meaningful tool name from a (logical or raw) event.\n * Precedence: toolName → tool → metadata.toolName → metadata.tool → name prefixes.\n *\n * @experimental\n */\nexport function resolveCanonicalToolName(event: PersistedInspectEvent): string {\n const attrs = event.attributes;\n const direct = pickString(attrs, [\"toolName\", \"tool\"]);\n if (direct) return direct;\n\n const metadata = attrs?.metadata;\n if (isRecord(metadata)) {\n const nested = pickString(metadata, [\"toolName\", \"tool\"]);\n if (nested) return nested;\n }\n\n for (const prefix of [\"tool:\", \"function:\", \"mcp-tools:\"] as const) {\n if (event.name.startsWith(prefix)) return event.name.slice(prefix.length);\n }\n return event.name;\n}\n\nfunction pickString(\n record: Record<string, unknown> | undefined,\n keys: readonly string[],\n): string | undefined {\n if (!record) return undefined;\n for (const key of keys) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim() !== \"\") return value.trim();\n }\n return undefined;\n}\n"]}
@@ -1146,11 +1146,13 @@ function exportOpenInference(tree, options) {
1146
1146
  endNs = startNs + unixNano(ev.durationMs);
1147
1147
  }
1148
1148
  const { openInferenceKind } = mapInspectKindToOI(ev.kind, warnings);
1149
+ const meta = ev.attributes;
1150
+ const originalSource = typeof meta?.originalSourceType === "string" && meta.originalSourceType.trim() !== "" ? meta.originalSourceType.trim() : ev.source.type;
1149
1151
  const attrs = {
1150
1152
  "openinference.span.kind": openInferenceKind,
1151
1153
  "agent_inspect.kind": ev.kind,
1152
1154
  "agent_inspect.confidence": ev.confidence,
1153
- "agent_inspect.source.type": ev.source.type,
1155
+ "agent_inspect.source.type": originalSource,
1154
1156
  "agent_inspect.run_id": tree.runId,
1155
1157
  "agent_inspect.event_id": ev.eventId,
1156
1158
  "agent_inspect.status": ev.status ?? "unset"
@@ -1158,9 +1160,9 @@ function exportOpenInference(tree, options) {
1158
1160
  if (ev.durationMs !== void 0) {
1159
1161
  attrs["agent_inspect.duration_ms"] = ev.durationMs;
1160
1162
  }
1161
- const meta = ev.attributes;
1162
- if (meta?.model !== void 0 && typeof meta.model === "string") {
1163
- attrs["llm.model_name"] = meta.model;
1163
+ const requestModel = (typeof meta?.model === "string" && meta.model.trim() !== "" ? meta.model : void 0) ?? (typeof meta?.modelId === "string" && meta.modelId.trim() !== "" ? meta.modelId : void 0);
1164
+ if (requestModel !== void 0) {
1165
+ attrs["llm.model_name"] = requestModel;
1164
1166
  }
1165
1167
  const tokens = meta?.tokens;
1166
1168
  if (tokens && typeof tokens === "object" && tokens !== null) {
@@ -1170,8 +1172,9 @@ function exportOpenInference(tree, options) {
1170
1172
  if (typeof outp === "number") attrs["llm.token_count.completion"] = outp;
1171
1173
  }
1172
1174
  if (includeAttributes && meta && typeof meta === "object") {
1175
+ const skipKeys = /* @__PURE__ */ new Set(["tokens", "model", "modelId", "originalSourceType"]);
1173
1176
  for (const [k, v] of Object.entries(meta)) {
1174
- if (k === "tokens" || k === "model") continue;
1177
+ if (skipKeys.has(k)) continue;
1175
1178
  if (v !== void 0 && v !== null && typeof v !== "object") {
1176
1179
  attrs[`agent_inspect.preview.${k}`] = typeof v === "string" ? v.slice(0, maxLen) : v;
1177
1180
  }
@@ -1289,24 +1292,33 @@ function exportOtlpJson(tree, options) {
1289
1292
  const spanId = hexFrom2(`${tree.runId}:${ev.eventId}`, 8);
1290
1293
  const parentSpanId = ev.parentId ? hexFrom2(`${tree.runId}:${ev.parentId}`, 8) : void 0;
1291
1294
  const { startNs, endNs } = resolveSpanTimes(ev);
1295
+ const meta = ev.attributes;
1296
+ const originalSource = typeof meta?.originalSourceType === "string" && meta.originalSourceType.trim() !== "" ? meta.originalSourceType.trim() : ev.source.type;
1292
1297
  const attrs = [
1293
1298
  stringAttr("agent_inspect.kind", ev.kind),
1294
1299
  stringAttr("agent_inspect.confidence", ev.confidence),
1295
- stringAttr("agent_inspect.source.type", ev.source.type),
1300
+ stringAttr("agent_inspect.source.type", originalSource),
1296
1301
  stringAttr("agent_inspect.run_id", tree.runId),
1297
1302
  stringAttr("agent_inspect.event_id", ev.eventId),
1298
1303
  stringAttr("agent_inspect.status", ev.status ?? "unset")
1299
1304
  ];
1300
1305
  if (ev.durationMs !== void 0) {
1301
- attrs.push(intAttr("agent_inspect.duration_ms", ev.durationMs));
1306
+ attrs.push(numberAttr("agent_inspect.duration_ms", ev.durationMs));
1302
1307
  }
1303
1308
  const op = genAiOperationName(ev.kind);
1304
1309
  if (op !== void 0) {
1305
1310
  attrs.push(stringAttr("gen_ai.operation.name", op));
1306
1311
  }
1307
- const meta = ev.attributes;
1308
- if (meta?.model !== void 0 && typeof meta.model === "string") {
1309
- attrs.push(stringAttr("gen_ai.request.model", meta.model.slice(0, maxLen)));
1312
+ const requestModel = (typeof meta?.model === "string" && meta.model.trim() !== "" ? meta.model : void 0) ?? (typeof meta?.modelId === "string" && meta.modelId.trim() !== "" ? meta.modelId : void 0);
1313
+ if (requestModel !== void 0) {
1314
+ attrs.push(stringAttr("gen_ai.request.model", requestModel.slice(0, maxLen)));
1315
+ }
1316
+ const responseModel = typeof meta?.responseModelId === "string" && meta.responseModelId.trim() !== "" ? meta.responseModelId : typeof meta?.responseModel === "string" && meta.responseModel.trim() !== "" ? meta.responseModel : void 0;
1317
+ if (responseModel !== void 0) {
1318
+ attrs.push(stringAttr("gen_ai.response.model", responseModel.slice(0, maxLen)));
1319
+ }
1320
+ if (typeof meta?.provider === "string" && meta.provider.trim() !== "") {
1321
+ attrs.push(stringAttr("gen_ai.provider.name", meta.provider.slice(0, maxLen)));
1310
1322
  }
1311
1323
  const tokens = meta?.tokens;
1312
1324
  if (tokens && typeof tokens === "object" && tokens !== null) {
@@ -1316,8 +1328,17 @@ function exportOtlpJson(tree, options) {
1316
1328
  if (typeof outp === "number") attrs.push(intAttr("gen_ai.usage.output_tokens", outp));
1317
1329
  }
1318
1330
  if (includeAttributes && meta && typeof meta === "object") {
1331
+ const skipKeys = /* @__PURE__ */ new Set([
1332
+ "tokens",
1333
+ "model",
1334
+ "modelId",
1335
+ "responseModel",
1336
+ "responseModelId",
1337
+ "provider",
1338
+ "originalSourceType"
1339
+ ]);
1319
1340
  for (const [k, v] of Object.entries(meta)) {
1320
- if (k === "tokens" || k === "model") continue;
1341
+ if (skipKeys.has(k)) continue;
1321
1342
  if (typeof v === "string") {
1322
1343
  attrs.push(stringAttr(`agent_inspect.preview.${k}`, v.slice(0, maxLen)));
1323
1344
  } else if (typeof v === "number" && Number.isFinite(v)) {
@@ -1387,12 +1408,42 @@ function pushPath(errors, path4, message) {
1387
1408
  function isRecord3(value) {
1388
1409
  return value !== null && typeof value === "object" && !Array.isArray(value);
1389
1410
  }
1411
+ function isHexId(value, byteLen) {
1412
+ return typeof value === "string" && new RegExp(`^[0-9a-fA-F]{${byteLen * 2}}$`).test(value);
1413
+ }
1414
+ function validateAnyValue(errors, path4, value) {
1415
+ if (!isRecord3(value)) {
1416
+ pushPath(errors, path4, "must be an AnyValue object");
1417
+ return;
1418
+ }
1419
+ const variants = [
1420
+ "stringValue",
1421
+ "boolValue",
1422
+ "intValue",
1423
+ "doubleValue",
1424
+ "bytesValue",
1425
+ "arrayValue",
1426
+ "kvlistValue"
1427
+ ].filter((key) => value[key] !== void 0);
1428
+ if (variants.length !== 1) {
1429
+ pushPath(
1430
+ errors,
1431
+ path4,
1432
+ `AnyValue must set exactly one variant (found ${variants.length}: ${variants.join(",")})`
1433
+ );
1434
+ }
1435
+ if (value.intValue !== void 0) {
1436
+ if (typeof value.intValue !== "string" || !/^-?\d+$/.test(value.intValue)) {
1437
+ pushPath(errors, `${path4}.intValue`, "must be a decimal integer string");
1438
+ }
1439
+ }
1440
+ }
1390
1441
  function validateOtlpJson(content) {
1391
1442
  const errors = [];
1392
1443
  const warnings = [
1393
1444
  EXPERIMENTAL,
1394
1445
  "OTLP JSON mapping uses OTel GenAI-aligned attributes where applicable; collectors may require transformation.",
1395
- "protocol-valid \u2260 profile-complete \u2260 fixture-complete \u2014 nested path diagnostics report protocol shape only."
1446
+ "producer-profile checks IDs, timing, and AnyValue shape; historical string enums are reader-compat warnings only."
1396
1447
  ];
1397
1448
  let parsed;
1398
1449
  try {
@@ -1435,11 +1486,26 @@ function validateOtlpJson(content) {
1435
1486
  pushPath(errors, spanPath, "must be an object");
1436
1487
  return;
1437
1488
  }
1438
- if (typeof span.traceId !== "string" || span.traceId.length === 0) {
1439
- pushPath(errors, `${spanPath}.traceId`, "must be a non-empty string");
1489
+ if (!isHexId(span.traceId, 16)) {
1490
+ pushPath(
1491
+ errors,
1492
+ `${spanPath}.traceId`,
1493
+ "must be a 32-char hex trace id (16 bytes)"
1494
+ );
1495
+ }
1496
+ if (!isHexId(span.spanId, 8)) {
1497
+ pushPath(
1498
+ errors,
1499
+ `${spanPath}.spanId`,
1500
+ "must be a 16-char hex span id (8 bytes)"
1501
+ );
1440
1502
  }
1441
- if (typeof span.spanId !== "string" || span.spanId.length === 0) {
1442
- pushPath(errors, `${spanPath}.spanId`, "must be a non-empty string");
1503
+ if (span.parentSpanId !== void 0 && !isHexId(span.parentSpanId, 8)) {
1504
+ pushPath(
1505
+ errors,
1506
+ `${spanPath}.parentSpanId`,
1507
+ "must be a 16-char hex span id when present"
1508
+ );
1443
1509
  }
1444
1510
  if (typeof span.name !== "string") {
1445
1511
  pushPath(errors, `${spanPath}.name`, "must be a string");
@@ -1458,13 +1524,39 @@ function validateOtlpJson(content) {
1458
1524
  "must be a decimal-string 64-bit integer when present"
1459
1525
  );
1460
1526
  }
1527
+ if (typeof span.startTimeUnixNano === "string" && /^\d+$/.test(span.startTimeUnixNano) && typeof span.endTimeUnixNano === "string" && /^\d+$/.test(span.endTimeUnixNano)) {
1528
+ try {
1529
+ if (BigInt(span.endTimeUnixNano) < BigInt(span.startTimeUnixNano)) {
1530
+ pushPath(
1531
+ errors,
1532
+ `${spanPath}.endTimeUnixNano`,
1533
+ "must be >= startTimeUnixNano"
1534
+ );
1535
+ }
1536
+ } catch {
1537
+ pushPath(errors, `${spanPath}.endTimeUnixNano`, "out of integer range");
1538
+ }
1539
+ }
1540
+ if (Array.isArray(span.attributes)) {
1541
+ span.attributes.forEach((attr, ai) => {
1542
+ const attrPath = `${spanPath}.attributes[${ai}]`;
1543
+ if (!isRecord3(attr)) {
1544
+ pushPath(errors, attrPath, "must be an object");
1545
+ return;
1546
+ }
1547
+ if (typeof attr.key !== "string") {
1548
+ pushPath(errors, `${attrPath}.key`, "must be a string");
1549
+ }
1550
+ validateAnyValue(errors, `${attrPath}.value`, attr.value);
1551
+ });
1552
+ }
1461
1553
  if (typeof span.kind === "number") {
1462
1554
  if (!Number.isInteger(span.kind)) {
1463
1555
  pushPath(errors, `${spanPath}.kind`, "must be an integer SpanKind enum");
1464
1556
  }
1465
1557
  } else if (typeof span.kind === "string") {
1466
1558
  warnings.push(
1467
- `${spanPath}.kind: string SpanKind enum is legacy; prefer numeric (INTERNAL=1)`
1559
+ `${spanPath}.kind: string SpanKind is historical reader-compat only; producer wire format uses numeric enums`
1468
1560
  );
1469
1561
  } else if (span.kind !== void 0) {
1470
1562
  pushPath(
@@ -1495,7 +1587,7 @@ function validateOtlpJson(content) {
1495
1587
  );
1496
1588
  } else {
1497
1589
  warnings.push(
1498
- `${spanPath}.status.code: string StatusCode is legacy; prefer numeric 0/1/2`
1590
+ `${spanPath}.status.code: string StatusCode is historical reader-compat only; producer wire format uses numeric 0/1/2`
1499
1591
  );
1500
1592
  }
1501
1593
  } else {