agent-inspect 6.29.6 → 6.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +26 -4
  4. package/docs/TRACE-CONTRACTS.md +25 -0
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-DBRMI7TC.mjs → chunk-Y5Z4BXUO.mjs} +2422 -101
  7. package/packages/cli/dist/chunk-Y5Z4BXUO.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +10313 -7195
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +866 -59
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-6CET2GW2.mjs → src-WTTH5G33.mjs} +3 -3
  13. package/packages/cli/dist/{src-6CET2GW2.mjs.map → src-WTTH5G33.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +12 -1
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +2 -2
  17. package/packages/core/dist/advanced.d.ts +2 -2
  18. package/packages/core/dist/advanced.mjs +2 -2
  19. package/packages/core/dist/checks.cjs +172 -43
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.d.cts +2 -2
  22. package/packages/core/dist/checks.d.ts +2 -2
  23. package/packages/core/dist/checks.mjs +1 -1
  24. package/packages/core/dist/{chunk-OOX25GTH.mjs → chunk-VEQKLWGJ.mjs} +174 -46
  25. package/packages/core/dist/chunk-VEQKLWGJ.mjs.map +1 -0
  26. package/packages/core/dist/{index-7hG_qggp.d.ts → index-CgOAGuM5.d.ts} +111 -1
  27. package/packages/core/dist/{index-CQJUNPPe.d.cts → index-EQihlEei.d.cts} +111 -1
  28. package/packages/cli/dist/chunk-DBRMI7TC.mjs.map +0 -1
  29. package/packages/core/dist/chunk-OOX25GTH.mjs.map +0 -1
@@ -6,8 +6,8 @@ import { a as InspectRunTree } from './inspect-event-ClM5Z8om.cjs';
6
6
  export { b as ATTRIBUTION_CONFIDENCES, c as ATTRIBUTION_CONFIDENCE_RANK, A as AttributionConfidence, E as EventSource, d as InspectEvent, I as InspectKind, e as InspectNode, i as isAttributionConfidence } from './inspect-event-ClM5Z8om.cjs';
7
7
  import { P as PersistedInspectEvent } from './persisted-inspect-event-q2ViiBW6.cjs';
8
8
  import { Stats } from 'node:fs';
9
- import { aR as SessionWorkflowMetadata, aS as SessionRunRecord, aT as EnrichSessionSummaryOptions, aU as SessionStatus, aV as SessionSummary, aW as SessionIndex, aX as BuildActivitySummaryOptions, aY as ActivitySummary, aZ as SessionWarning, a_ as BuildSessionIndexOptions, N as TraceCheckResult, X as TraceCheckStatus, a2 as TraceContractInput, Z as TraceContract } from './index-CQJUNPPe.cjs';
10
- export { a$ as ActivityEntry, b0 as CriticalPathStep, b1 as HandoffEdge, b2 as RetryLink, b3 as SESSION_WORKFLOW_KEYS, b4 as SessionCheckSummary, b5 as SessionConfidence, b6 as SessionEdgeSource, b7 as SessionGroup, b8 as SessionLastError, b9 as SessionWorkflowKey } from './index-CQJUNPPe.cjs';
9
+ import { aZ as SessionWorkflowMetadata, a_ as SessionRunRecord, a$ as EnrichSessionSummaryOptions, b0 as SessionStatus, b1 as SessionSummary, b2 as SessionIndex, b3 as BuildActivitySummaryOptions, b4 as ActivitySummary, b5 as SessionWarning, b6 as BuildSessionIndexOptions, U as TraceCheckResult, _ as TraceCheckStatus, a5 as TraceContractInput, a0 as TraceContract } from './index-EQihlEei.cjs';
10
+ export { b7 as ActivityEntry, b8 as CriticalPathStep, b9 as HandoffEdge, ba as RetryLink, bb as SESSION_WORKFLOW_KEYS, bc as SessionCheckSummary, bd as SessionConfidence, be as SessionEdgeSource, bf as SessionGroup, bg as SessionLastError, bh as SessionWorkflowKey } from './index-EQihlEei.cjs';
11
11
  import { b as ObservedOutcome } from './types-BA_IOdg4.cjs';
12
12
  export { a as ObservedOutcomeStatus } from './types-BA_IOdg4.cjs';
13
13
  import './writers.cjs';
@@ -6,8 +6,8 @@ import { a as InspectRunTree } from './inspect-event-ClM5Z8om.js';
6
6
  export { b as ATTRIBUTION_CONFIDENCES, c as ATTRIBUTION_CONFIDENCE_RANK, A as AttributionConfidence, E as EventSource, d as InspectEvent, I as InspectKind, e as InspectNode, i as isAttributionConfidence } from './inspect-event-ClM5Z8om.js';
7
7
  import { P as PersistedInspectEvent } from './persisted-inspect-event-DG02LhEP.js';
8
8
  import { Stats } from 'node:fs';
9
- import { aR as SessionWorkflowMetadata, aS as SessionRunRecord, aT as EnrichSessionSummaryOptions, aU as SessionStatus, aV as SessionSummary, aW as SessionIndex, aX as BuildActivitySummaryOptions, aY as ActivitySummary, aZ as SessionWarning, a_ as BuildSessionIndexOptions, N as TraceCheckResult, X as TraceCheckStatus, a2 as TraceContractInput, Z as TraceContract } from './index-7hG_qggp.js';
10
- export { a$ as ActivityEntry, b0 as CriticalPathStep, b1 as HandoffEdge, b2 as RetryLink, b3 as SESSION_WORKFLOW_KEYS, b4 as SessionCheckSummary, b5 as SessionConfidence, b6 as SessionEdgeSource, b7 as SessionGroup, b8 as SessionLastError, b9 as SessionWorkflowKey } from './index-7hG_qggp.js';
9
+ import { aZ as SessionWorkflowMetadata, a_ as SessionRunRecord, a$ as EnrichSessionSummaryOptions, b0 as SessionStatus, b1 as SessionSummary, b2 as SessionIndex, b3 as BuildActivitySummaryOptions, b4 as ActivitySummary, b5 as SessionWarning, b6 as BuildSessionIndexOptions, U as TraceCheckResult, _ as TraceCheckStatus, a5 as TraceContractInput, a0 as TraceContract } from './index-CgOAGuM5.js';
10
+ export { b7 as ActivityEntry, b8 as CriticalPathStep, b9 as HandoffEdge, ba as RetryLink, bb as SESSION_WORKFLOW_KEYS, bc as SessionCheckSummary, bd as SessionConfidence, be as SessionEdgeSource, bf as SessionGroup, bg as SessionLastError, bh as SessionWorkflowKey } from './index-CgOAGuM5.js';
11
11
  import { b as ObservedOutcome } from './types-BA_IOdg4.js';
12
12
  export { a as ObservedOutcomeStatus } from './types-BA_IOdg4.js';
13
13
  import './writers.js';
@@ -1,5 +1,5 @@
1
- import { extractSessionWorkflowMetadata, sessionKeyForRun, defineTraceContract, runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-OOX25GTH.mjs';
2
- export { extractSessionWorkflowMetadata, sessionKeyForRun } from './chunk-OOX25GTH.mjs';
1
+ import { extractSessionWorkflowMetadata, sessionKeyForRun, defineTraceContract, runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-VEQKLWGJ.mjs';
2
+ export { extractSessionWorkflowMetadata, sessionKeyForRun } from './chunk-VEQKLWGJ.mjs';
3
3
  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-ZFJ2ICTC.mjs';
4
4
  import { buildRunTimeline, filterTraces, extractMetadata, buildRunSummary } from './chunk-KWBO36PH.mjs';
5
5
  export { buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildTraceStats, extractMetadata, filterTraces, formatStepLabel, renderRunWhat, renderTimeline, renderTraceStats } from './chunk-KWBO36PH.mjs';
@@ -2507,6 +2507,17 @@ function cloneBody(body) {
2507
2507
  }
2508
2508
  } : {},
2509
2509
  ...body.llm ? { llm: { ...body.llm } } : {},
2510
+ ...body.steps ? {
2511
+ steps: {
2512
+ ...body.steps.orderRelations ? {
2513
+ orderRelations: body.steps.orderRelations.map((item) => ({
2514
+ ...item,
2515
+ before: { ...item.before },
2516
+ after: { ...item.after }
2517
+ }))
2518
+ } : {}
2519
+ }
2520
+ } : {},
2510
2521
  ...body.observations ? {
2511
2522
  observations: {
2512
2523
  ...body.observations,
@@ -2546,7 +2557,7 @@ function cloneBody(body) {
2546
2557
  };
2547
2558
  }
2548
2559
  function bodyHasRules(body) {
2549
- return body.run !== void 0 || body.tools !== void 0 || body.llm !== void 0 || body.observations !== void 0 || body.controls !== void 0 || body.retry !== void 0;
2560
+ return body.run !== void 0 || body.tools !== void 0 || body.llm !== void 0 || body.steps !== void 0 || body.observations !== void 0 || body.controls !== void 0 || body.retry !== void 0;
2550
2561
  }
2551
2562
  var MAX_EVIDENCE_EVENT_IDS = 16;
2552
2563
  var METHOD_VOCABULARY = new Set(OBSERVED_OUTCOME_METHODS);
@@ -2889,6 +2900,18 @@ function contractToRules(contract) {
2889
2900
  })
2890
2901
  );
2891
2902
  }
2903
+ const orderRelations = contract.steps?.orderRelations ?? [];
2904
+ for (const [index, relation] of orderRelations.entries()) {
2905
+ rules.push(
2906
+ createStepOrderingRule({
2907
+ before: { kind: relation.before.kind, name: relation.before.name },
2908
+ after: { kind: relation.after.kind, name: relation.after.name },
2909
+ id: `contract.step.orderRelation.${index}`,
2910
+ mode: relation.mode ?? "first-occurrence",
2911
+ requireEndpoints: relation.requireEndpoints !== false
2912
+ })
2913
+ );
2914
+ }
2892
2915
  if (contract.observations) {
2893
2916
  const required = contract.observations.required ?? [];
2894
2917
  if (required.length > 0) {
@@ -3442,6 +3465,13 @@ function explainTraceContract(contract) {
3442
3465
  lines.push(`Base: LLM allowedModels [${contract.llm.allowedModels.join(", ")}].`);
3443
3466
  }
3444
3467
  }
3468
+ if ((contract.steps?.orderRelations?.length ?? 0) > 0) {
3469
+ const relations = contract.steps.orderRelations;
3470
+ const summary = relations.map(
3471
+ (relation) => `${relation.before.kind}:${relation.before.name} \u2192 ${relation.after.kind}:${relation.after.name} mode=${relation.mode ?? "first-occurrence"}`
3472
+ ).join("; ");
3473
+ lines.push(`Base: ${relations.length} steps.orderRelations [${summary}].`);
3474
+ }
3445
3475
  if (contract.observations?.required?.length) {
3446
3476
  lines.push(`Base: required observations [${contract.observations.required.join(", ")}].`);
3447
3477
  }
@@ -3856,6 +3886,31 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
3856
3886
  function toolName(event) {
3857
3887
  return resolveCanonicalToolName(event);
3858
3888
  }
3889
+ function stepEndpointName(event, kind) {
3890
+ if (kind === "TOOL") return resolveCanonicalToolName(event);
3891
+ for (const prefix of ["llm:", "generation:", "transcription:", "speech:"]) {
3892
+ if (event.name.startsWith(prefix)) return event.name.slice(prefix.length);
3893
+ }
3894
+ return event.name;
3895
+ }
3896
+ function formatStepEndpoint(endpoint) {
3897
+ return `${endpoint.kind} ${endpoint.name}`;
3898
+ }
3899
+ function otherKindsForStepName(context, expectedKind, name) {
3900
+ return [
3901
+ ...new Set(
3902
+ semanticEvents(context).filter((event) => {
3903
+ const kind = typeof event.kind === "string" ? event.kind.toUpperCase() : "";
3904
+ if (kind === expectedKind) return false;
3905
+ if (kind === "TOOL") return resolveCanonicalToolName(event) === name;
3906
+ if (kind === "LLM") return stepEndpointName(event, "LLM") === name;
3907
+ return event.name === name || event.name === `tool:${name}` || event.name === `llm:${name}` || event.name.endsWith(`:${name}`);
3908
+ }).map(
3909
+ (event) => typeof event.kind === "string" ? event.kind.toUpperCase() : "UNKNOWN"
3910
+ )
3911
+ )
3912
+ ].sort();
3913
+ }
3859
3914
  function semanticEvents(context) {
3860
3915
  return context.logicalEvents ?? context.events;
3861
3916
  }
@@ -3882,14 +3937,6 @@ function finishedEvents(context, kind) {
3882
3937
  function toolInvocationEvents(context) {
3883
3938
  return semanticEvents(context).filter((event) => event.kind === "TOOL");
3884
3939
  }
3885
- function firstIndexByName(events) {
3886
- const index = /* @__PURE__ */ new Map();
3887
- for (const [position, event] of events.entries()) {
3888
- const name = toolName(event);
3889
- if (!index.has(name)) index.set(name, position);
3890
- }
3891
- return index;
3892
- }
3893
3940
  function isRecord3(value) {
3894
3941
  return typeof value === "object" && value !== null && !Array.isArray(value);
3895
3942
  }
@@ -4399,18 +4446,85 @@ function createToolUsageRule(options) {
4399
4446
  }
4400
4447
  };
4401
4448
  }
4402
- function createToolOrderingRule(options) {
4403
- const ruleId = options.id ?? "tool.order";
4449
+ function createStepOrderingRule(options) {
4450
+ const bothTools = options.before.kind === "TOOL" && options.after.kind === "TOOL";
4451
+ const ruleId = options.id ?? (bothTools ? "tool.order" : "step.order");
4404
4452
  const mode = options.mode ?? "first-occurrence";
4453
+ const requireEndpoints = options.requireEndpoints === true;
4454
+ const beforeLabel = bothTools ? options.before.name : formatStepEndpoint(options.before);
4455
+ const afterLabel = bothTools ? options.after.name : formatStepEndpoint(options.after);
4456
+ const subject = bothTools ? "Tool" : "Step";
4405
4457
  return {
4406
4458
  id: ruleId,
4407
- category: "tool",
4459
+ category: bothTools ? "tool" : "structure",
4408
4460
  defaultSeverity: "error",
4409
4461
  evaluate(context) {
4410
- const tools = finishedEvents(context, "TOOL");
4411
- const index = firstIndexByName(tools);
4412
- const beforeIndex = index.get(options.before);
4413
- const afterIndex = index.get(options.after);
4462
+ const beforeEvents = finishedEvents(context, options.before.kind).filter(
4463
+ (event) => stepEndpointName(event, options.before.kind) === options.before.name
4464
+ );
4465
+ const afterEvents = finishedEvents(context, options.after.kind).filter(
4466
+ (event) => stepEndpointName(event, options.after.kind) === options.after.name
4467
+ );
4468
+ if (beforeEvents.length === 0 || afterEvents.length === 0) {
4469
+ if (!requireEndpoints) return [];
4470
+ const findings = [];
4471
+ if (beforeEvents.length === 0) {
4472
+ const otherKinds = otherKindsForStepName(
4473
+ context,
4474
+ options.before.kind,
4475
+ options.before.name
4476
+ );
4477
+ const hint = otherKinds.length > 0 ? ` Required name appears under non-${options.before.kind} kind(s): ${otherKinds.join(", ")}.` : "";
4478
+ findings.push(
4479
+ failFinding(
4480
+ ruleId,
4481
+ `Required ${formatStepEndpoint(options.before)} did not appear.${hint}`,
4482
+ runEvidence(context.selectedRun),
4483
+ options.before,
4484
+ {
4485
+ code: bothTools ? "tool.order.missing-endpoint" : "step.order.missing-endpoint",
4486
+ endpoint: "before",
4487
+ otherKinds
4488
+ }
4489
+ )
4490
+ );
4491
+ }
4492
+ if (afterEvents.length === 0) {
4493
+ const otherKinds = otherKindsForStepName(
4494
+ context,
4495
+ options.after.kind,
4496
+ options.after.name
4497
+ );
4498
+ const hint = otherKinds.length > 0 ? ` Required name appears under non-${options.after.kind} kind(s): ${otherKinds.join(", ")}.` : "";
4499
+ findings.push(
4500
+ failFinding(
4501
+ ruleId,
4502
+ `Required ${formatStepEndpoint(options.after)} did not appear.${hint}`,
4503
+ runEvidence(context.selectedRun),
4504
+ options.after,
4505
+ {
4506
+ code: bothTools ? "tool.order.missing-endpoint" : "step.order.missing-endpoint",
4507
+ endpoint: "after",
4508
+ otherKinds
4509
+ }
4510
+ )
4511
+ );
4512
+ }
4513
+ return findings;
4514
+ }
4515
+ const encounter = finishedEvents(context).filter(
4516
+ (event) => event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name || event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name
4517
+ );
4518
+ let beforeIndex;
4519
+ let afterIndex;
4520
+ for (const [position, event] of encounter.entries()) {
4521
+ if (beforeIndex === void 0 && event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name) {
4522
+ beforeIndex = position;
4523
+ }
4524
+ if (afterIndex === void 0 && event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name) {
4525
+ afterIndex = position;
4526
+ }
4527
+ }
4414
4528
  if (beforeIndex === void 0 || afterIndex === void 0) {
4415
4529
  return [];
4416
4530
  }
@@ -4418,32 +4532,37 @@ function createToolOrderingRule(options) {
4418
4532
  return [
4419
4533
  failFinding(
4420
4534
  ruleId,
4421
- `Tool ${options.before} must appear before ${options.after}.`,
4422
- [eventEvidence3(tools[beforeIndex]), eventEvidence3(tools[afterIndex])],
4423
- { before: options.before, after: options.after },
4424
- tools.map(toolName)
4535
+ `${subject} ${beforeLabel} must appear before ${afterLabel}.`,
4536
+ [
4537
+ eventEvidence3(encounter[beforeIndex]),
4538
+ eventEvidence3(encounter[afterIndex])
4539
+ ],
4540
+ bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after },
4541
+ bothTools ? finishedEvents(context, "TOOL").map(toolName) : encounter.map(
4542
+ (event) => event.kind === "TOOL" || event.kind === "LLM" ? `${event.kind}:${stepEndpointName(event, event.kind)}` : event.name
4543
+ )
4425
4544
  )
4426
4545
  ];
4427
4546
  }
4428
- const beforeEvent = tools[beforeIndex];
4429
- const afterEvent = tools[afterIndex];
4547
+ const beforeEvent = beforeEvents[0];
4548
+ const afterEvent = afterEvents[0];
4430
4549
  const beforeEnd = eventEndMs(beforeEvent);
4431
4550
  const afterStart = eventStartMs(afterEvent);
4551
+ const endpointExpected = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
4432
4552
  if (mode === "happens-before") {
4433
4553
  const expected = {
4434
- before: options.before,
4435
- after: options.after,
4554
+ ...endpointExpected,
4436
4555
  mode,
4437
4556
  relation: "before.end <= after.start"
4438
4557
  };
4439
- if (options.before === options.after) {
4558
+ if (options.before.kind === options.after.kind && options.before.name === options.after.name) {
4440
4559
  return [
4441
4560
  failFinding(
4442
4561
  ruleId,
4443
- `Tool ${options.before} cannot causally happen before itself.`,
4562
+ `${subject} ${beforeLabel} cannot causally happen before itself.`,
4444
4563
  [eventEvidence3(beforeEvent)],
4445
4564
  expected,
4446
- { code: "tool.order.same-tool" }
4565
+ { code: bothTools ? "tool.order.same-tool" : "step.order.same-step" }
4447
4566
  )
4448
4567
  ];
4449
4568
  }
@@ -4451,11 +4570,11 @@ function createToolOrderingRule(options) {
4451
4570
  return [
4452
4571
  failFinding(
4453
4572
  ruleId,
4454
- `Tool order ${options.before} before ${options.after} could not establish causal timing.`,
4573
+ `${subject} order ${beforeLabel} before ${afterLabel} could not establish causal timing.`,
4455
4574
  [eventEvidence3(beforeEvent), eventEvidence3(afterEvent)],
4456
4575
  expected,
4457
4576
  {
4458
- code: "tool.order.interval-unresolved",
4577
+ code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
4459
4578
  beforeEndResolved: beforeEnd !== void 0,
4460
4579
  afterStartResolved: afterStart !== void 0
4461
4580
  }
@@ -4466,7 +4585,7 @@ function createToolOrderingRule(options) {
4466
4585
  return [
4467
4586
  failFinding(
4468
4587
  ruleId,
4469
- `Tool ${options.before} must finish before ${options.after} starts.`,
4588
+ `${subject} ${beforeLabel} must finish before ${afterLabel} starts.`,
4470
4589
  [eventEvidence3(beforeEvent), eventEvidence3(afterEvent)],
4471
4590
  expected,
4472
4591
  {
@@ -4479,22 +4598,19 @@ function createToolOrderingRule(options) {
4479
4598
  return [];
4480
4599
  }
4481
4600
  if (mode === "all-occurrences") {
4482
- const beforeEvents = tools.filter((event) => toolName(event) === options.before);
4483
- const afterEvents = tools.filter((event) => toolName(event) === options.after);
4484
4601
  const expected = {
4485
- before: options.before,
4486
- after: options.after,
4602
+ ...endpointExpected,
4487
4603
  mode,
4488
4604
  relation: "max(before.end) <= min(after.start)"
4489
4605
  };
4490
- if (options.before === options.after) {
4606
+ if (options.before.kind === options.after.kind && options.before.name === options.after.name) {
4491
4607
  return [
4492
4608
  failFinding(
4493
4609
  ruleId,
4494
- `Tool ${options.before} cannot causally happen before itself.`,
4610
+ `${subject} ${beforeLabel} cannot causally happen before itself.`,
4495
4611
  [eventEvidence3(beforeEvent)],
4496
4612
  expected,
4497
- { code: "tool.order.same-tool" }
4613
+ { code: bothTools ? "tool.order.same-tool" : "step.order.same-step" }
4498
4614
  )
4499
4615
  ];
4500
4616
  }
@@ -4526,11 +4642,11 @@ function createToolOrderingRule(options) {
4526
4642
  return [
4527
4643
  failFinding(
4528
4644
  ruleId,
4529
- `Tool order ${options.before} before ${options.after} could not establish all causal intervals.`,
4645
+ `${subject} order ${beforeLabel} before ${afterLabel} could not establish all causal intervals.`,
4530
4646
  [firstMissingBefore, firstMissingAfter].filter((event) => event !== void 0).map((event) => eventEvidence3(event)),
4531
4647
  expected,
4532
4648
  {
4533
- code: "tool.order.interval-unresolved",
4649
+ code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
4534
4650
  missingBeforeEnds,
4535
4651
  missingAfterStarts
4536
4652
  }
@@ -4541,7 +4657,7 @@ function createToolOrderingRule(options) {
4541
4657
  return [
4542
4658
  failFinding(
4543
4659
  ruleId,
4544
- `Every ${options.before} tool call must finish before any ${options.after} tool call starts.`,
4660
+ bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`,
4545
4661
  [eventEvidence3(latestBefore.event), eventEvidence3(earliestAfter.event)],
4546
4662
  expected,
4547
4663
  {
@@ -4559,10 +4675,13 @@ function createToolOrderingRule(options) {
4559
4675
  ruleId,
4560
4676
  severity: "warning",
4561
4677
  status: "warning",
4562
- message: `Tool order ${options.before} before ${options.after} satisfied start/encounter order, but intervals overlap so causal completion before the next tool was not established.`,
4563
- expected: { before: options.before, after: options.after, mode: "first-occurrence" },
4678
+ message: `${subject} order ${beforeLabel} before ${afterLabel} satisfied start/encounter order, but intervals overlap so causal completion before the next ${bothTools ? "tool" : "step"} was not established.`,
4679
+ expected: {
4680
+ ...endpointExpected,
4681
+ mode: "first-occurrence"
4682
+ },
4564
4683
  actual: {
4565
- code: "tool.order.overlap",
4684
+ code: bothTools ? "tool.order.overlap" : "step.order.overlap",
4566
4685
  beforeEndedAt: beforeEvent.endedAt,
4567
4686
  afterStartedAt: afterEvent.startedAt ?? afterEvent.timestamp
4568
4687
  },
@@ -4574,6 +4693,15 @@ function createToolOrderingRule(options) {
4574
4693
  }
4575
4694
  };
4576
4695
  }
4696
+ function createToolOrderingRule(options) {
4697
+ return createStepOrderingRule({
4698
+ before: { kind: "TOOL", name: options.before },
4699
+ after: { kind: "TOOL", name: options.after },
4700
+ ...options.id !== void 0 ? { id: options.id } : {},
4701
+ ...options.mode !== void 0 ? { mode: options.mode } : {},
4702
+ requireEndpoints: false
4703
+ });
4704
+ }
4577
4705
  function createToolFailureRule(options) {
4578
4706
  return {
4579
4707
  id: "tool.failures",
@@ -5517,6 +5645,7 @@ exports.createSafetyRawContentRule = createSafetyRawContentRule;
5517
5645
  exports.createSafetyRedactionRule = createSafetyRedactionRule;
5518
5646
  exports.createSafetySecretPatternRule = createSafetySecretPatternRule;
5519
5647
  exports.createStallDetectionRule = createStallDetectionRule;
5648
+ exports.createStepOrderingRule = createStepOrderingRule;
5520
5649
  exports.createStructureCycleRule = createStructureCycleRule;
5521
5650
  exports.createStructureIncompleteRule = createStructureIncompleteRule;
5522
5651
  exports.createStructureOrphanRule = createStructureOrphanRule;