agent-inspect 6.12.0 → 6.12.2

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 (38) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +27 -6
  3. package/docs/ADOPTION.md +1 -1
  4. package/docs/DEMO-SCRIPT.md +30 -25
  5. package/docs/DESIGN-PARTNER-GUIDE.md +23 -10
  6. package/docs/FIRST-TRACE-IN-5-MINUTES.md +5 -2
  7. package/docs/GOLDEN-PATH.md +2 -2
  8. package/docs/KNOWN-ISSUES.md +1 -0
  9. package/docs/PRE-V7-PILOT-KIT.md +41 -15
  10. package/docs/SUPPORT-LEVELS.md +1 -1
  11. package/docs/TEAM-WORKFLOWS.md +1 -1
  12. package/docs/TECHNICAL-GUIDE.md +2 -2
  13. package/docs/USE-CASES.md +34 -10
  14. package/package.json +2 -2
  15. package/packages/cli/dist/{chunk-XTAA733P.mjs → chunk-4WA7DQCM.mjs} +316 -55
  16. package/packages/cli/dist/chunk-4WA7DQCM.mjs.map +1 -0
  17. package/packages/cli/dist/index.cjs +337 -70
  18. package/packages/cli/dist/index.cjs.map +1 -1
  19. package/packages/cli/dist/index.mjs +4 -4
  20. package/packages/cli/dist/index.mjs.map +1 -1
  21. package/packages/cli/dist/{src-G7PM24W2.mjs → src-YAASTXGE.mjs} +3 -3
  22. package/packages/cli/dist/{src-G7PM24W2.mjs.map → src-YAASTXGE.mjs.map} +1 -1
  23. package/packages/core/dist/advanced.cjs +290 -30
  24. package/packages/core/dist/advanced.cjs.map +1 -1
  25. package/packages/core/dist/advanced.d.cts +1 -1
  26. package/packages/core/dist/advanced.d.ts +1 -1
  27. package/packages/core/dist/advanced.mjs +1 -1
  28. package/packages/core/dist/checks.cjs +295 -30
  29. package/packages/core/dist/checks.cjs.map +1 -1
  30. package/packages/core/dist/checks.d.cts +2 -2
  31. package/packages/core/dist/checks.d.ts +2 -2
  32. package/packages/core/dist/checks.mjs +1 -1
  33. package/packages/core/dist/{chunk-QT6CQ2XA.mjs → chunk-KJICERSD.mjs} +296 -33
  34. package/packages/core/dist/chunk-KJICERSD.mjs.map +1 -0
  35. package/packages/core/dist/{index-mdFcxSOR.d.cts → index-BOP33T4O.d.cts} +72 -1
  36. package/packages/core/dist/{index-BO7l0iAe.d.ts → index-CgCH8NE9.d.ts} +72 -1
  37. package/packages/cli/dist/chunk-XTAA733P.mjs.map +0 -1
  38. package/packages/core/dist/chunk-QT6CQ2XA.mjs.map +0 -1
@@ -7,7 +7,7 @@ import { P as PersistedInspectEvent } from './persisted-inspect-event-d-mSP8kd.c
7
7
  import { Stats } from 'node:fs';
8
8
  import { b as ObservedOutcome } from './types-B562HgN_.cjs';
9
9
  export { O as ObservedOutcomeStatus } from './types-B562HgN_.cjs';
10
- import { a as TraceCheckResult, H as TraceCheckStatus } from './index-mdFcxSOR.cjs';
10
+ import { a as TraceCheckResult, J as TraceCheckStatus } from './index-BOP33T4O.cjs';
11
11
  import './writers.cjs';
12
12
  import './log-config-BG1WmWf2.cjs';
13
13
  import './readers.cjs';
@@ -7,7 +7,7 @@ import { P as PersistedInspectEvent } from './persisted-inspect-event-ChE7pGb7.j
7
7
  import { Stats } from 'node:fs';
8
8
  import { b as ObservedOutcome } from './types-B562HgN_.js';
9
9
  export { O as ObservedOutcomeStatus } from './types-B562HgN_.js';
10
- import { a as TraceCheckResult, H as TraceCheckStatus } from './index-BO7l0iAe.js';
10
+ import { a as TraceCheckResult, J as TraceCheckStatus } from './index-CgCH8NE9.js';
11
11
  import './writers.js';
12
12
  import './log-config-Ck0aT_Ou.js';
13
13
  import './readers.js';
@@ -1,4 +1,4 @@
1
- import { runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-QT6CQ2XA.mjs';
1
+ import { runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-KJICERSD.mjs';
2
2
  export { MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, TERMINAL_INDENT, TraceDirectory, createInspector, createInspectorRuntime, formatTerminalName, getCurrentContext, getCurrentCorrelationMetadata, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getIndent, getParentStepId, getTraceDirFromContext, getTraceSafetyFromContext, hasActiveContext, isAgentInspectEnabled, isSilentContext, maybeInspectRun, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, renderErrorLine, renderRunSummary, renderStepLine, resolveTraceDir, runWithContext, runWithStepContext } from './chunk-ZWA5RWMV.mjs';
3
3
  import { buildRunTimeline, filterTraces, extractMetadata, buildRunSummary } from './chunk-LFWZEO2L.mjs';
4
4
  export { buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildTraceStats, extractMetadata, filterTraces, renderRunWhat, renderTimeline, renderTraceStats } from './chunk-LFWZEO2L.mjs';
@@ -64,6 +64,260 @@ function outcomesMatchingStatus(outcomes, statuses) {
64
64
  return outcomes.filter((outcome) => set.has(outcome.status));
65
65
  }
66
66
 
67
+ // packages/core/src/checks/logical-events.ts
68
+ function isRecord(value) {
69
+ return typeof value === "object" && value !== null && !Array.isArray(value);
70
+ }
71
+ function legacyEvent(event) {
72
+ const value = event.attributes?.legacyEvent;
73
+ return typeof value === "string" ? value : void 0;
74
+ }
75
+ function stepIdOf(event) {
76
+ const value = event.attributes?.stepId;
77
+ if (typeof value === "string" && value.trim() !== "") return value;
78
+ return void 0;
79
+ }
80
+ function cloneEvent(event) {
81
+ return {
82
+ ...event,
83
+ ...event.attributes !== void 0 ? { attributes: { ...event.attributes } } : {},
84
+ ...event.error !== void 0 ? { error: { ...event.error } } : {},
85
+ ...event.tokenUsage !== void 0 ? { tokenUsage: { ...event.tokenUsage } } : {},
86
+ ...event.source !== void 0 ? { source: { ...event.source } } : {}
87
+ };
88
+ }
89
+ function mergeAttributes(start, complete) {
90
+ const merged = {
91
+ ...isRecord(complete.attributes) ? complete.attributes : {},
92
+ ...isRecord(start.attributes) ? start.attributes : {}
93
+ };
94
+ merged.legacyEvent = start.attributes?.legacyEvent ?? complete.attributes?.legacyEvent;
95
+ merged.legacyCompleteEvent = complete.attributes?.legacyEvent;
96
+ if (complete.attributes?.errorStack !== void 0) {
97
+ merged.errorStack = complete.attributes.errorStack;
98
+ }
99
+ return Object.keys(merged).length > 0 ? merged : void 0;
100
+ }
101
+ function pairStartComplete(start, complete) {
102
+ const attributes = mergeAttributes(start, complete);
103
+ const paired = {
104
+ ...cloneEvent(start),
105
+ status: complete.status,
106
+ timestamp: complete.timestamp ?? start.timestamp,
107
+ ...complete.endedAt !== void 0 ? { endedAt: complete.endedAt } : {},
108
+ ...complete.durationMs !== void 0 ? { durationMs: complete.durationMs } : {},
109
+ ...complete.error !== void 0 ? { error: { ...complete.error } } : {},
110
+ ...complete.tokenUsage !== void 0 && start.tokenUsage === void 0 ? { tokenUsage: { ...complete.tokenUsage } } : {},
111
+ ...attributes !== void 0 ? { attributes } : {}
112
+ };
113
+ return {
114
+ ...paired,
115
+ sourceEventIds: Object.freeze([start.eventId, complete.eventId]),
116
+ projection: {
117
+ paired: true,
118
+ absorbedEventIds: Object.freeze([complete.eventId]),
119
+ parentNormalized: false,
120
+ ...start.parentId !== void 0 ? { originalParentId: start.parentId } : {}
121
+ }
122
+ };
123
+ }
124
+ function asLogical(event, extras) {
125
+ return {
126
+ ...cloneEvent(event),
127
+ sourceEventIds: Object.freeze([event.eventId]),
128
+ projection: {
129
+ paired: false,
130
+ absorbedEventIds: Object.freeze([]),
131
+ parentNormalized: extras?.parentNormalized === true,
132
+ ...{}
133
+ }
134
+ };
135
+ }
136
+ function projectLogicalEvents(events) {
137
+ const diagnostics = [];
138
+ const byRun = /* @__PURE__ */ new Map();
139
+ for (const event of events) {
140
+ const list = byRun.get(event.runId) ?? [];
141
+ list.push(event);
142
+ byRun.set(event.runId, list);
143
+ }
144
+ const absorbedIds = /* @__PURE__ */ new Set();
145
+ const logicalByRawId = /* @__PURE__ */ new Map();
146
+ const stepIdToLogicalId = /* @__PURE__ */ new Map();
147
+ const logical = [];
148
+ const orderedRuns = [...byRun.keys()].sort((a, b) => a.localeCompare(b));
149
+ for (const runId of orderedRuns) {
150
+ const runEvents = byRun.get(runId) ?? [];
151
+ const starts = [];
152
+ const completes = [];
153
+ const others = [];
154
+ for (const event of runEvents) {
155
+ const legacy = legacyEvent(event);
156
+ if (legacy === "step_started" || legacy === "run_started" && event.status === "running") {
157
+ starts.push(event);
158
+ } else if (legacy === "step_completed" || legacy === "run_completed") {
159
+ completes.push(event);
160
+ } else {
161
+ others.push(event);
162
+ }
163
+ }
164
+ const usedCompletes = /* @__PURE__ */ new Set();
165
+ for (const start of starts) {
166
+ const stepId = stepIdOf(start);
167
+ let match;
168
+ if (legacyEvent(start) === "run_started") {
169
+ const candidates = completes.filter(
170
+ (c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "run_completed"
171
+ );
172
+ if (candidates.length > 1) {
173
+ diagnostics.push({
174
+ code: "AI_LOGICAL_PAIR_AMBIGUOUS",
175
+ message: `Multiple run_completed rows for run ${runId}; 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
+ } else if (stepId) {
182
+ const candidates = completes.filter(
183
+ (c) => !usedCompletes.has(c.eventId) && legacyEvent(c) === "step_completed" && stepIdOf(c) === stepId
184
+ );
185
+ if (candidates.length > 1) {
186
+ diagnostics.push({
187
+ code: "AI_LOGICAL_PAIR_AMBIGUOUS",
188
+ message: `Multiple step_completed rows for stepId ${stepId}; using first by eventId.`,
189
+ eventIds: candidates.map((c) => c.eventId)
190
+ });
191
+ candidates.sort((a, b) => a.eventId.localeCompare(b.eventId));
192
+ }
193
+ match = candidates[0];
194
+ }
195
+ if (match) {
196
+ usedCompletes.add(match.eventId);
197
+ absorbedIds.add(match.eventId);
198
+ const paired = pairStartComplete(start, match);
199
+ logical.push(paired);
200
+ logicalByRawId.set(start.eventId, paired);
201
+ logicalByRawId.set(match.eventId, paired);
202
+ if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, paired.eventId);
203
+ } else {
204
+ diagnostics.push({
205
+ code: "AI_LOGICAL_PAIR_UNMATCHED_START",
206
+ message: `No matching complete for start ${start.eventId}.`,
207
+ eventIds: [start.eventId]
208
+ });
209
+ const alone = asLogical(start);
210
+ logical.push(alone);
211
+ logicalByRawId.set(start.eventId, alone);
212
+ if (stepId) stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
213
+ }
214
+ }
215
+ for (const complete of completes) {
216
+ if (usedCompletes.has(complete.eventId)) continue;
217
+ diagnostics.push({
218
+ code: "AI_LOGICAL_PAIR_UNMATCHED_COMPLETE",
219
+ message: `No matching start for complete ${complete.eventId}.`,
220
+ eventIds: [complete.eventId]
221
+ });
222
+ const alone = asLogical(complete);
223
+ logical.push(alone);
224
+ logicalByRawId.set(complete.eventId, alone);
225
+ const stepId = stepIdOf(complete);
226
+ if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
227
+ stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
228
+ }
229
+ }
230
+ for (const event of others) {
231
+ const alone = asLogical(event);
232
+ logical.push(alone);
233
+ logicalByRawId.set(event.eventId, alone);
234
+ const stepId = stepIdOf(event);
235
+ if (stepId && !stepIdToLogicalId.has(`${runId}:${stepId}`)) {
236
+ stepIdToLogicalId.set(`${runId}:${stepId}`, alone.eventId);
237
+ }
238
+ }
239
+ }
240
+ const logicalById = new Map(logical.map((e) => [e.eventId, e]));
241
+ const normalized = [];
242
+ for (const event of logical) {
243
+ const originalParentId = event.parentId;
244
+ if (!originalParentId) {
245
+ normalized.push(event);
246
+ continue;
247
+ }
248
+ let nextParent = originalParentId;
249
+ let remapped = false;
250
+ const viaAbsorbed = logicalByRawId.get(originalParentId);
251
+ if (viaAbsorbed && viaAbsorbed.eventId !== originalParentId) {
252
+ nextParent = viaAbsorbed.eventId;
253
+ remapped = true;
254
+ } else if (!logicalById.has(originalParentId)) {
255
+ const viaStep = stepIdToLogicalId.get(`${event.runId}:${originalParentId}`);
256
+ if (viaStep) {
257
+ nextParent = viaStep;
258
+ remapped = true;
259
+ }
260
+ }
261
+ if (!remapped) {
262
+ if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
263
+ diagnostics.push({
264
+ code: "AI_LOGICAL_PARENT_UNRESOLVED",
265
+ message: `Parent ${originalParentId} unresolved for ${event.eventId}.`,
266
+ eventIds: [event.eventId]
267
+ });
268
+ }
269
+ normalized.push(event);
270
+ continue;
271
+ }
272
+ diagnostics.push({
273
+ code: "AI_LOGICAL_PARENT_REMAPPED",
274
+ message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
275
+ eventIds: [event.eventId]
276
+ });
277
+ normalized.push({
278
+ ...event,
279
+ parentId: nextParent,
280
+ projection: {
281
+ ...event.projection,
282
+ parentNormalized: true,
283
+ originalParentId
284
+ }
285
+ });
286
+ }
287
+ const rawIndex = new Map(events.map((e, i) => [e.eventId, i]));
288
+ normalized.sort((a, b) => {
289
+ const ai = rawIndex.get(a.sourceEventIds[0]) ?? 0;
290
+ const bi = rawIndex.get(b.sourceEventIds[0]) ?? 0;
291
+ return ai - bi || a.eventId.localeCompare(b.eventId);
292
+ });
293
+ return {
294
+ logicalEvents: Object.freeze(normalized),
295
+ diagnostics: Object.freeze(diagnostics)
296
+ };
297
+ }
298
+ function resolveCanonicalToolName(event) {
299
+ const attrs = event.attributes;
300
+ const direct = pickString(attrs, ["toolName", "tool"]);
301
+ if (direct) return direct;
302
+ const metadata = attrs?.metadata;
303
+ if (isRecord(metadata)) {
304
+ const nested = pickString(metadata, ["toolName", "tool"]);
305
+ if (nested) return nested;
306
+ }
307
+ for (const prefix of ["tool:", "function:", "mcp-tools:"]) {
308
+ if (event.name.startsWith(prefix)) return event.name.slice(prefix.length);
309
+ }
310
+ return event.name;
311
+ }
312
+ function pickString(record, keys) {
313
+ if (!record) return void 0;
314
+ for (const key of keys) {
315
+ const value = record[key];
316
+ if (typeof value === "string" && value.trim() !== "") return value.trim();
317
+ }
318
+ return void 0;
319
+ }
320
+
67
321
  // packages/core/src/checks/contract.ts
68
322
  function contractFailFinding(ruleId, message, evidence, expected, actual) {
69
323
  return {
@@ -121,7 +375,9 @@ function contractToRules(contract) {
121
375
  );
122
376
  }
123
377
  if (!allowIncomplete) {
124
- const running = context.events.filter((event) => event.status === "running");
378
+ const running = (context.logicalEvents ?? context.events).filter(
379
+ (event) => event.status === "running"
380
+ );
125
381
  if (running.length > 0) {
126
382
  findings.push(
127
383
  contractFailFinding(
@@ -285,7 +541,11 @@ var DEFAULT_RAW_CONTENT_KEYS = [
285
541
  "conversationtext",
286
542
  "conversation_text"
287
543
  ];
288
- var DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES = ["tokenUsage", "usage"];
544
+ var DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES = [
545
+ "tokenUsage",
546
+ "usage",
547
+ "tokens"
548
+ ];
289
549
  var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
290
550
  "input",
291
551
  "output",
@@ -361,10 +621,13 @@ function buildFacts(input, selectedRun) {
361
621
  childrenByParentId.set(parentId, children);
362
622
  }
363
623
  }
624
+ const projection = projectLogicalEvents(scopedEvents);
364
625
  return {
365
626
  format: input.read.format,
366
627
  runs: Object.freeze([...input.read.runs]),
367
628
  events: Object.freeze([...scopedEvents]),
629
+ logicalEvents: projection.logicalEvents,
630
+ logicalProjectionDiagnostics: projection.diagnostics,
368
631
  readerWarnings: Object.freeze([...input.read.warnings]),
369
632
  unsupportedFields: Object.freeze([...input.read.unsupportedFields]),
370
633
  sourceFiles: Object.freeze([...input.read.sourceFiles]),
@@ -557,7 +820,10 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
557
820
  };
558
821
  }
559
822
  function toolName(event) {
560
- return stringAttr(event, ["toolName", "tool"]) ?? stripPrefix(event.name, ["tool:", "function:", "mcp-tools:"]);
823
+ return resolveCanonicalToolName(event);
824
+ }
825
+ function semanticEvents(context) {
826
+ return context.logicalEvents ?? context.events;
561
827
  }
562
828
  function llmModel(event) {
563
829
  return stringAttr(event, ["model", "modelId", "responseModelId", "modelName", "model_name"]) ?? stripPrefix(event.name, ["llm:", "generation:", "transcription:", "speech:"]);
@@ -572,7 +838,7 @@ function retryCount(event) {
572
838
  return numericAttr(event, ["retryCount", "retryAttempt", "retry_attempt", "attempt"]);
573
839
  }
574
840
  function finishedEvents(context, kind) {
575
- return context.events.filter(
841
+ return semanticEvents(context).filter(
576
842
  (event) => (kind === void 0 || event.kind === kind) && event.status !== "running"
577
843
  );
578
844
  }
@@ -584,7 +850,7 @@ function firstIndexByName(events) {
584
850
  }
585
851
  return index;
586
852
  }
587
- function isRecord(value) {
853
+ function isRecord2(value) {
588
854
  return typeof value === "object" && value !== null && !Array.isArray(value);
589
855
  }
590
856
  function eventMap(events) {
@@ -638,7 +904,7 @@ function pushValueEntries(entries, event, value, path3, key, depth = 0) {
638
904
  }
639
905
  return;
640
906
  }
641
- if (!isRecord(value)) return;
907
+ if (!isRecord2(value)) return;
642
908
  for (const nestedKey of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
643
909
  pushValueEntries(
644
910
  entries,
@@ -718,14 +984,11 @@ function signalName(event, attributeKeys, prefixes) {
718
984
  return stringAttr(event, attributeKeys) ?? stripPrefix(event.name, prefixes);
719
985
  }
720
986
  function guardrailEvents(context) {
721
- return finishedEvents2().filter((event) => {
987
+ return finishedEvents(context).filter((event) => {
722
988
  const name = event.name.toLowerCase();
723
989
  if (name.startsWith("guardrail:") || name.includes(".guardrail.")) return true;
724
990
  return stringAttr(event, ["guardrailName", "guardrail", "guardrailId"]) !== void 0;
725
991
  });
726
- function finishedEvents2() {
727
- return context.events.filter((event) => event.status !== "running");
728
- }
729
992
  }
730
993
  function retryValue(event) {
731
994
  return retryCount(event) ?? 0;
@@ -746,7 +1009,7 @@ function treeShape(nodes) {
746
1009
  return lines;
747
1010
  }
748
1011
  function statusShape(context) {
749
- return context.events.map((event) => `${event.kind}:${event.name}:${event.status ?? "unknown"}`).sort((a, b) => a.localeCompare(b));
1012
+ return semanticEvents(context).map((event) => `${event.kind}:${event.name}:${event.status ?? "unknown"}`).sort((a, b) => a.localeCompare(b));
750
1013
  }
751
1014
  function toolShape(context) {
752
1015
  return finishedEvents(context, "TOOL").map(
@@ -772,7 +1035,7 @@ function llmShape(context) {
772
1035
  );
773
1036
  }
774
1037
  function errorShape(context) {
775
- return context.events.filter((event) => event.status === "error" || event.error !== void 0).map(
1038
+ return semanticEvents(context).filter((event) => event.status === "error" || event.error !== void 0).map(
776
1039
  (event) => [
777
1040
  event.kind,
778
1041
  event.name,
@@ -790,7 +1053,7 @@ function guardrailShape(context) {
790
1053
  return guardrailEvents(context).map((event) => signalName(event, ["guardrailName", "guardrail", "guardrailId"], ["guardrail:"])).sort((a, b) => a.localeCompare(b));
791
1054
  }
792
1055
  function firstEvidenceForKind(context, kind, path3) {
793
- const event = context.events.find((candidate) => candidate.kind === kind);
1056
+ const event = semanticEvents(context).find((candidate) => candidate.kind === kind);
794
1057
  return event ? [eventEvidence(event, path3)] : runEvidence(context.selectedRun);
795
1058
  }
796
1059
  function baselineDiffFinding(message, evidence, expected, actual) {
@@ -818,7 +1081,7 @@ function createRunStatusRule(options = {}) {
818
1081
  );
819
1082
  }
820
1083
  if (!allowIncomplete) {
821
- const running = context.events.filter((event) => event.status === "running");
1084
+ const running = semanticEvents(context).filter((event) => event.status === "running");
822
1085
  if (running.length > 0) {
823
1086
  findings.push(
824
1087
  failFinding(
@@ -861,7 +1124,7 @@ function createMaxStepDurationRule(options) {
861
1124
  category: "run",
862
1125
  defaultSeverity: "error",
863
1126
  evaluate(context) {
864
- const over = context.events.filter((event) => {
1127
+ const over = semanticEvents(context).filter((event) => {
865
1128
  const duration = eventDurationMs(event);
866
1129
  return duration !== void 0 && duration > options.maxDurationMs;
867
1130
  });
@@ -890,7 +1153,7 @@ function createStallDetectionRule(options = {}) {
890
1153
  defaultSeverity: "warning",
891
1154
  evaluate(context) {
892
1155
  const findings = [];
893
- const running = context.events.filter((event) => event.status === "running");
1156
+ const running = semanticEvents(context).filter((event) => event.status === "running");
894
1157
  if (running.length > 0) {
895
1158
  findings.push(
896
1159
  failFinding(
@@ -903,7 +1166,7 @@ function createStallDetectionRule(options = {}) {
903
1166
  );
904
1167
  }
905
1168
  if (requireEndedAt) {
906
- const incomplete = context.events.filter(
1169
+ const incomplete = semanticEvents(context).filter(
907
1170
  (event) => event.startedAt !== void 0 && event.endedAt === void 0 && event.status !== "running"
908
1171
  );
909
1172
  if (incomplete.length > 0) {
@@ -941,7 +1204,7 @@ function createRequireCompletedRule() {
941
1204
  )
942
1205
  );
943
1206
  }
944
- const running = context.events.filter((event) => event.status === "running");
1207
+ const running = semanticEvents(context).filter((event) => event.status === "running");
945
1208
  if (running.length > 0) {
946
1209
  findings.push(
947
1210
  failFinding(
@@ -963,7 +1226,7 @@ function createRunEventCountRule(options) {
963
1226
  category: "run",
964
1227
  defaultSeverity: "error",
965
1228
  evaluate(context) {
966
- const count = context.events.filter(
1229
+ const count = semanticEvents(context).filter(
967
1230
  (event) => options.kind === void 0 || event.kind === options.kind
968
1231
  ).length;
969
1232
  const findings = [];
@@ -1214,7 +1477,7 @@ function createStructureIncompleteRule(options = {}) {
1214
1477
  evaluate(context) {
1215
1478
  const findings = [];
1216
1479
  if (!options.allowRunning) {
1217
- const running = context.events.filter((event) => event.status === "running");
1480
+ const running = semanticEvents(context).filter((event) => event.status === "running");
1218
1481
  if (running.length > 0) {
1219
1482
  findings.push(
1220
1483
  failFinding(
@@ -1228,7 +1491,7 @@ function createStructureIncompleteRule(options = {}) {
1228
1491
  }
1229
1492
  }
1230
1493
  if (options.requireEndedAtForStarted) {
1231
- const missingEndedAt = context.events.filter(
1494
+ const missingEndedAt = semanticEvents(context).filter(
1232
1495
  (event) => event.startedAt !== void 0 && event.endedAt === void 0 && event.status !== "running"
1233
1496
  );
1234
1497
  if (missingEndedAt.length > 0) {
@@ -1254,8 +1517,8 @@ function createStructureOrphanRule(options = {}) {
1254
1517
  category: "structure",
1255
1518
  defaultSeverity: "error",
1256
1519
  evaluate(context) {
1257
- const byId = eventMap(context.events);
1258
- const orphans = context.events.filter((event) => {
1520
+ const byId = eventMap(semanticEvents(context));
1521
+ const orphans = semanticEvents(context).filter((event) => {
1259
1522
  if (!event.parentId || byId.has(event.parentId)) return false;
1260
1523
  return !(allowMarkedUnresolved && parentMarkedUnresolved(event));
1261
1524
  });
@@ -1278,10 +1541,10 @@ function createStructureCycleRule() {
1278
1541
  category: "structure",
1279
1542
  defaultSeverity: "error",
1280
1543
  evaluate(context) {
1281
- const byId = eventMap(context.events);
1544
+ const byId = eventMap(semanticEvents(context));
1282
1545
  const seenCycles = /* @__PURE__ */ new Set();
1283
1546
  const findings = [];
1284
- for (const event of [...context.events].sort((a, b) => a.eventId.localeCompare(b.eventId))) {
1547
+ for (const event of [...semanticEvents(context)].sort((a, b) => a.eventId.localeCompare(b.eventId))) {
1285
1548
  const path3 = [];
1286
1549
  const seenAt = /* @__PURE__ */ new Map();
1287
1550
  let current = event;
@@ -1319,10 +1582,10 @@ function createStructureRelationshipRule(options = {}) {
1319
1582
  category: "structure",
1320
1583
  defaultSeverity: "error",
1321
1584
  evaluate(context) {
1322
- const byId = eventMap(context.events);
1585
+ const byId = eventMap(semanticEvents(context));
1323
1586
  const findings = [];
1324
1587
  const minConfidence = options.minConfidence;
1325
- for (const event of context.events) {
1588
+ for (const event of semanticEvents(context)) {
1326
1589
  if (minConfidence && CONFIDENCE_RANK[event.confidence] < CONFIDENCE_RANK[minConfidence]) {
1327
1590
  findings.push(
1328
1591
  failFinding(
@@ -1390,7 +1653,7 @@ function createStructureParallelWidthRule(options) {
1390
1653
  defaultSeverity: "error",
1391
1654
  evaluate(context) {
1392
1655
  const findings = [];
1393
- const byId = eventMap(context.events);
1656
+ const byId = eventMap(semanticEvents(context));
1394
1657
  if (options.maxChildren !== void 0) {
1395
1658
  for (const [parentId, children] of context.childrenByParentId.entries()) {
1396
1659
  if (children.length <= options.maxChildren) continue;
@@ -1417,7 +1680,7 @@ function createStructureParallelWidthRule(options) {
1417
1680
  }
1418
1681
  }
1419
1682
  if (options.maxConcurrent !== void 0) {
1420
- const intervals = context.events.map((event) => ({ event, start: eventStartMs(event), end: eventEndMs(event) })).filter(
1683
+ const intervals = semanticEvents(context).map((event) => ({ event, start: eventStartMs(event), end: eventEndMs(event) })).filter(
1421
1684
  (item) => item.start !== void 0 && item.end !== void 0 && item.end > item.start
1422
1685
  );
1423
1686
  const points = intervals.flatMap((item) => [
@@ -1713,7 +1976,7 @@ function createSafetyOversizedAttributeRule(options) {
1713
1976
  )
1714
1977
  );
1715
1978
  }
1716
- if (isRecord(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
1979
+ if (isRecord2(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
1717
1980
  findings.push(
1718
1981
  failFinding(
1719
1982
  "safety.oversizedAttribute",
@@ -1990,6 +2253,8 @@ exports.createToolOrderingRule = createToolOrderingRule;
1990
2253
  exports.createToolUsageRule = createToolUsageRule;
1991
2254
  exports.defineTraceContract = defineTraceContract;
1992
2255
  exports.evaluateTraceContract = evaluateTraceContract;
2256
+ exports.projectLogicalEvents = projectLogicalEvents;
2257
+ exports.resolveCanonicalToolName = resolveCanonicalToolName;
1993
2258
  exports.runTraceChecks = runTraceChecks;
1994
2259
  //# sourceMappingURL=checks.cjs.map
1995
2260
  //# sourceMappingURL=checks.cjs.map