agent-inspect 6.21.0 → 6.22.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 (40) 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-CRUHIL5J.mjs → chunk-CHBYF4LE.mjs} +11 -2
  5. package/packages/cli/dist/chunk-CHBYF4LE.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +29 -1
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +4 -4
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-MNJFYW3W.mjs → src-MY5WIBPF.mjs} +3 -3
  11. package/packages/cli/dist/{src-MNJFYW3W.mjs.map → src-MY5WIBPF.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +38 -0
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.d.cts +36 -4
  15. package/packages/core/dist/advanced.d.ts +36 -4
  16. package/packages/core/dist/advanced.mjs +32 -4
  17. package/packages/core/dist/advanced.mjs.map +1 -1
  18. package/packages/core/dist/checks.cjs +230 -72
  19. package/packages/core/dist/checks.cjs.map +1 -1
  20. package/packages/core/dist/checks.d.cts +54 -5
  21. package/packages/core/dist/checks.d.ts +54 -5
  22. package/packages/core/dist/checks.mjs +1 -1
  23. package/packages/core/dist/{chunk-HT54OLPE.mjs → chunk-NDRMIL7Z.mjs} +103 -3
  24. package/packages/core/dist/chunk-NDRMIL7Z.mjs.map +1 -0
  25. package/packages/core/dist/{chunk-43SHIPZM.mjs → chunk-OG3GAWCX.mjs} +178 -21
  26. package/packages/core/dist/chunk-OG3GAWCX.mjs.map +1 -0
  27. package/packages/core/dist/{index-BG-ZBESI.d.cts → index-CR4CCRqP.d.cts} +7 -2
  28. package/packages/core/dist/{index-xevIlqdd.d.ts → index-CtK_p-ps.d.ts} +7 -2
  29. package/packages/core/dist/{index-AMAGuO_i.d.ts → index-D72DPqAF.d.ts} +2 -1
  30. package/packages/core/dist/{index-vqr-g6ev.d.cts → index-DLLz9sce.d.cts} +2 -1
  31. package/packages/core/dist/programmatic-gZTWLObB.d.cts +25 -0
  32. package/packages/core/dist/programmatic-gZTWLObB.d.ts +25 -0
  33. package/packages/core/dist/readers.cjs +105 -0
  34. package/packages/core/dist/readers.cjs.map +1 -1
  35. package/packages/core/dist/readers.d.cts +43 -18
  36. package/packages/core/dist/readers.d.ts +43 -18
  37. package/packages/core/dist/readers.mjs +1 -1
  38. package/packages/cli/dist/chunk-CRUHIL5J.mjs.map +0 -1
  39. package/packages/core/dist/chunk-43SHIPZM.mjs.map +0 -1
  40. package/packages/core/dist/chunk-HT54OLPE.mjs.map +0 -1
@@ -96,11 +96,11 @@ function parseMethod(value) {
96
96
  }
97
97
  function fromPersistedOutcome(event) {
98
98
  if (event.kind !== "OUTCOME") return void 0;
99
- const attrs = event.attributes ?? {};
100
- const statusRaw = attrs[OUTCOME_ATTRIBUTE_STATUS_KEY];
99
+ const attrs2 = event.attributes ?? {};
100
+ const statusRaw = attrs2[OUTCOME_ATTRIBUTE_STATUS_KEY];
101
101
  if (!isOutcomeStatus(statusRaw)) return void 0;
102
- const expectation = typeof attrs[OUTCOME_ATTRIBUTE_EXPECTATION_KEY] === "string" ? attrs[OUTCOME_ATTRIBUTE_EXPECTATION_KEY] : event.name;
103
- const observedAtRaw = attrs[OUTCOME_ATTRIBUTE_OBSERVED_AT_KEY];
102
+ const expectation = typeof attrs2[OUTCOME_ATTRIBUTE_EXPECTATION_KEY] === "string" ? attrs2[OUTCOME_ATTRIBUTE_EXPECTATION_KEY] : event.name;
103
+ const observedAtRaw = attrs2[OUTCOME_ATTRIBUTE_OBSERVED_AT_KEY];
104
104
  const observedAt = typeof observedAtRaw === "string" ? Date.parse(observedAtRaw) : typeof observedAtRaw === "number" && Number.isFinite(observedAtRaw) ? observedAtRaw : Date.parse(event.timestamp);
105
105
  return {
106
106
  outcomeId: event.eventId,
@@ -109,9 +109,9 @@ function fromPersistedOutcome(event) {
109
109
  name: event.name,
110
110
  expectation,
111
111
  status: statusRaw,
112
- ...parseMethod(attrs[OUTCOME_ATTRIBUTE_METHOD_KEY]) !== void 0 ? { method: parseMethod(attrs[OUTCOME_ATTRIBUTE_METHOD_KEY]) } : {},
112
+ ...parseMethod(attrs2[OUTCOME_ATTRIBUTE_METHOD_KEY]) !== void 0 ? { method: parseMethod(attrs2[OUTCOME_ATTRIBUTE_METHOD_KEY]) } : {},
113
113
  ...event.outputSummary !== void 0 ? { actual: event.outputSummary } : {},
114
- ...attrs.evidence !== void 0 ? { evidence: attrs.evidence } : {},
114
+ ...attrs2.evidence !== void 0 ? { evidence: attrs2.evidence } : {},
115
115
  observedAt: Number.isFinite(observedAt) ? observedAt : Date.parse(event.timestamp)
116
116
  };
117
117
  }
@@ -477,10 +477,10 @@ function projectLogicalEvents(events) {
477
477
  };
478
478
  }
479
479
  function resolveCanonicalToolName(event) {
480
- const attrs = event.attributes;
481
- const direct = pickString(attrs, ["toolName", "tool"]);
480
+ const attrs2 = event.attributes;
481
+ const direct = pickString(attrs2, ["toolName", "tool"]);
482
482
  if (direct) return direct;
483
- const metadata = attrs?.metadata;
483
+ const metadata = attrs2?.metadata;
484
484
  if (isRecord(metadata)) {
485
485
  const nested = pickString(metadata, ["toolName", "tool"]);
486
486
  if (nested) return nested;
@@ -522,10 +522,10 @@ function pickNumber(record, keys) {
522
522
  return void 0;
523
523
  }
524
524
  function eventMetadata(event) {
525
- const attrs = isRecord2(event.attributes) ? event.attributes : void 0;
526
- const nested = attrs !== void 0 && isRecord2(attrs.metadata) ? attrs.metadata : void 0;
525
+ const attrs2 = isRecord2(event.attributes) ? event.attributes : void 0;
526
+ const nested = attrs2 !== void 0 && isRecord2(attrs2.metadata) ? attrs2.metadata : void 0;
527
527
  return {
528
- ...attrs ?? {},
528
+ ...attrs2 ?? {},
529
529
  ...nested ?? {}
530
530
  };
531
531
  }
@@ -818,6 +818,208 @@ function deriveFailureFacts(logicalEvents) {
818
818
  };
819
819
  }
820
820
 
821
+ // packages/core/src/sessions/metadata.ts
822
+ function isNonEmptyString(value) {
823
+ return typeof value === "string" && value.trim() !== "";
824
+ }
825
+ function finitePositiveInt(value) {
826
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
827
+ return void 0;
828
+ }
829
+ return Math.trunc(value);
830
+ }
831
+ function extractSessionWorkflowMetadata(record) {
832
+ if (!record) return void 0;
833
+ const out = {};
834
+ let found = false;
835
+ const assignString = (key, value) => {
836
+ if (isNonEmptyString(value)) {
837
+ out[key] = value.trim();
838
+ found = true;
839
+ }
840
+ };
841
+ assignString("sessionId", record.sessionId);
842
+ assignString("conversationId", record.conversationId);
843
+ assignString("groupId", record.groupId);
844
+ assignString("parentGroupId", record.parentGroupId);
845
+ assignString("retryOf", record.retryOf);
846
+ assignString("retryReason", record.retryReason);
847
+ assignString("handoffFrom", record.handoffFrom);
848
+ assignString("handoffTo", record.handoffTo);
849
+ assignString("subAgentId", record.subAgentId);
850
+ assignString("subAgentName", record.subAgentName);
851
+ assignString("jobId", record.jobId);
852
+ assignString("queueName", record.queueName);
853
+ assignString("workflowName", record.workflowName);
854
+ assignString("workflowStep", record.workflowStep);
855
+ assignString("toolCallId", record.toolCallId);
856
+ assignString("mcpToolCallId", record.mcpToolCallId);
857
+ assignString("linkedStepId", record.linkedStepId);
858
+ assignString("operationId", record.operationId);
859
+ assignString("attemptId", record.attemptId);
860
+ assignString("fallbackOf", record.fallbackOf);
861
+ assignString("idempotencyKey", record.idempotencyKey);
862
+ assignString("correlationId", record.correlationId);
863
+ assignString("requestId", record.requestId);
864
+ assignString("decisionId", record.decisionId);
865
+ const attempt = finitePositiveInt(record.attempt);
866
+ if (attempt !== void 0) {
867
+ out.attempt = attempt;
868
+ found = true;
869
+ }
870
+ const attemptNumber = finitePositiveInt(record.attemptNumber);
871
+ if (attemptNumber !== void 0) {
872
+ out.attemptNumber = attemptNumber;
873
+ found = true;
874
+ }
875
+ return found ? out : void 0;
876
+ }
877
+
878
+ // packages/core/src/checks/relationship-facts.ts
879
+ function attrs(event) {
880
+ return event.attributes && typeof event.attributes === "object" ? event.attributes : {};
881
+ }
882
+ function stringAttr(record, key) {
883
+ const value = record[key];
884
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
885
+ }
886
+ function deriveRelationshipFacts(events) {
887
+ const relationships = [];
888
+ const diagnostics = [];
889
+ const byId = new Map(events.map((event) => [event.eventId, event]));
890
+ const seen = /* @__PURE__ */ new Set();
891
+ const push = (edge) => {
892
+ const key = `${edge.type}:${edge.fromEventId}:${edge.toEventId ?? ""}:${edge.externalRef ?? ""}`;
893
+ if (seen.has(key)) return;
894
+ seen.add(key);
895
+ relationships.push(edge);
896
+ };
897
+ for (const event of events) {
898
+ if (event.parentId) {
899
+ push({
900
+ type: "parent-child",
901
+ fromEventId: event.parentId,
902
+ toEventId: event.eventId,
903
+ confidence: byId.has(event.parentId) ? "explicit" : "unknown",
904
+ basis: ["persisted.parentId"]
905
+ });
906
+ if (!byId.has(event.parentId)) {
907
+ diagnostics.push({
908
+ code: "AI_RELATIONSHIP_PARENT_MISSING",
909
+ message: `parentId ${event.parentId} is not present in the event set.`,
910
+ eventId: event.eventId
911
+ });
912
+ }
913
+ }
914
+ const bag = attrs(event);
915
+ const meta = extractSessionWorkflowMetadata(bag) ?? {};
916
+ const nested = bag.metadata && typeof bag.metadata === "object" ? extractSessionWorkflowMetadata(bag.metadata) : void 0;
917
+ const workflow = { ...meta, ...nested };
918
+ if (workflow.retryOf) {
919
+ const target = events.find((candidate) => candidate.runId === workflow.retryOf);
920
+ push({
921
+ type: "retry-of",
922
+ fromEventId: event.eventId,
923
+ ...target ? { toEventId: target.eventId } : {},
924
+ externalRef: workflow.retryOf,
925
+ confidence: target ? "explicit" : "correlated",
926
+ basis: ["attributes.retryOf"]
927
+ });
928
+ }
929
+ const attemptOf = stringAttr(bag, "attemptOf") ?? stringAttr(bag, "operationId");
930
+ if (attemptOf && workflow.attempt !== void 0) {
931
+ push({
932
+ type: "attempt-of",
933
+ fromEventId: event.eventId,
934
+ externalRef: attemptOf,
935
+ confidence: "explicit",
936
+ basis: workflow.attempt !== void 0 ? ["attributes.attempt", "attributes.operationId"] : ["attributes.operationId"]
937
+ });
938
+ }
939
+ const fallbackOf = stringAttr(bag, "fallbackOf");
940
+ if (fallbackOf) {
941
+ push({
942
+ type: "fallback-of",
943
+ fromEventId: event.eventId,
944
+ externalRef: fallbackOf,
945
+ confidence: "explicit",
946
+ basis: ["attributes.fallbackOf"]
947
+ });
948
+ }
949
+ const remediationOf = stringAttr(bag, "remediationOf");
950
+ if (remediationOf) {
951
+ push({
952
+ type: "remediation-of",
953
+ fromEventId: event.eventId,
954
+ externalRef: remediationOf,
955
+ confidence: "explicit",
956
+ basis: ["attributes.remediationOf"]
957
+ });
958
+ }
959
+ const evidenceFor = stringAttr(bag, "evidenceFor");
960
+ if (evidenceFor) {
961
+ push({
962
+ type: "evidence-for",
963
+ fromEventId: event.eventId,
964
+ ...byId.has(evidenceFor) ? { toEventId: evidenceFor } : { externalRef: evidenceFor },
965
+ confidence: byId.has(evidenceFor) ? "explicit" : "correlated",
966
+ basis: ["attributes.evidenceFor"]
967
+ });
968
+ }
969
+ const acceptedBy = stringAttr(bag, "acceptedBy");
970
+ if (acceptedBy) {
971
+ push({
972
+ type: "accepted-by",
973
+ fromEventId: event.eventId,
974
+ ...byId.has(acceptedBy) ? { toEventId: acceptedBy } : { externalRef: acceptedBy },
975
+ confidence: byId.has(acceptedBy) ? "explicit" : "correlated",
976
+ basis: ["attributes.acceptedBy"]
977
+ });
978
+ }
979
+ const supersedes = stringAttr(bag, "supersedes");
980
+ if (supersedes) {
981
+ push({
982
+ type: "supersedes",
983
+ fromEventId: event.eventId,
984
+ ...byId.has(supersedes) ? { toEventId: supersedes } : { externalRef: supersedes },
985
+ confidence: byId.has(supersedes) ? "explicit" : "correlated",
986
+ basis: ["attributes.supersedes"]
987
+ });
988
+ }
989
+ const sourceLineage = stringAttr(bag, "sourceLineage") ?? stringAttr(bag, "sourceEventId");
990
+ if (sourceLineage) {
991
+ push({
992
+ type: "source-lineage",
993
+ fromEventId: event.eventId,
994
+ externalRef: sourceLineage,
995
+ confidence: "explicit",
996
+ basis: ["attributes.sourceLineage"]
997
+ });
998
+ }
999
+ const unsupported = stringAttr(bag, "relationshipType");
1000
+ if (unsupported && unsupported !== "parent-child" && ![
1001
+ "source-lineage",
1002
+ "attempt-of",
1003
+ "retry-of",
1004
+ "fallback-of",
1005
+ "remediation-of",
1006
+ "evidence-for",
1007
+ "accepted-by",
1008
+ "supersedes"
1009
+ ].includes(unsupported)) {
1010
+ diagnostics.push({
1011
+ code: "AI_RELATIONSHIP_UNSUPPORTED_TYPE",
1012
+ message: `Unsupported relationshipType ${unsupported} was reported without flattening.`,
1013
+ eventId: event.eventId
1014
+ });
1015
+ }
1016
+ }
1017
+ return {
1018
+ relationships: Object.freeze(relationships),
1019
+ diagnostics: Object.freeze(diagnostics)
1020
+ };
1021
+ }
1022
+
821
1023
  // packages/core/src/checks/trace-facts.ts
822
1024
  function summarizeSemanticParity(events) {
823
1025
  const projection = projectLogicalEvents(events);
@@ -904,6 +1106,7 @@ function buildTraceFacts(input) {
904
1106
  toolsByName.set(name, Object.freeze([...list]));
905
1107
  }
906
1108
  const derived = deriveFailureFacts(projection.logicalEvents);
1109
+ const relationship = deriveRelationshipFacts(events);
907
1110
  const summary = summarizeSemanticParity(events);
908
1111
  return {
909
1112
  rawEvents: Object.freeze([...events]),
@@ -917,58 +1120,12 @@ function buildTraceFacts(input) {
917
1120
  failureRoleCounts: derived.failureRoleCounts
918
1121
  },
919
1122
  failureFacts: derived.failureFacts,
920
- failuresByRole: derived.failuresByRole
1123
+ failuresByRole: derived.failuresByRole,
1124
+ relationships: relationship.relationships,
1125
+ relationshipDiagnostics: relationship.diagnostics
921
1126
  };
922
1127
  }
923
1128
 
924
- // packages/core/src/sessions/metadata.ts
925
- function isNonEmptyString(value) {
926
- return typeof value === "string" && value.trim() !== "";
927
- }
928
- function finitePositiveInt(value) {
929
- if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
930
- return void 0;
931
- }
932
- return Math.trunc(value);
933
- }
934
- function extractSessionWorkflowMetadata(record) {
935
- if (!record) return void 0;
936
- const out = {};
937
- let found = false;
938
- const assignString = (key, value) => {
939
- if (isNonEmptyString(value)) {
940
- out[key] = value.trim();
941
- found = true;
942
- }
943
- };
944
- assignString("sessionId", record.sessionId);
945
- assignString("conversationId", record.conversationId);
946
- assignString("groupId", record.groupId);
947
- assignString("parentGroupId", record.parentGroupId);
948
- assignString("retryOf", record.retryOf);
949
- assignString("retryReason", record.retryReason);
950
- assignString("handoffFrom", record.handoffFrom);
951
- assignString("handoffTo", record.handoffTo);
952
- assignString("subAgentId", record.subAgentId);
953
- assignString("subAgentName", record.subAgentName);
954
- assignString("jobId", record.jobId);
955
- assignString("queueName", record.queueName);
956
- assignString("workflowName", record.workflowName);
957
- assignString("workflowStep", record.workflowStep);
958
- assignString("toolCallId", record.toolCallId);
959
- assignString("mcpToolCallId", record.mcpToolCallId);
960
- assignString("linkedStepId", record.linkedStepId);
961
- assignString("correlationId", record.correlationId);
962
- assignString("requestId", record.requestId);
963
- assignString("decisionId", record.decisionId);
964
- const attempt = finitePositiveInt(record.attempt);
965
- if (attempt !== void 0) {
966
- out.attempt = attempt;
967
- found = true;
968
- }
969
- return found ? out : void 0;
970
- }
971
-
972
1129
  // packages/core/src/checks/contract-scope.ts
973
1130
  function diagnostic(code, message, ruleId) {
974
1131
  return {
@@ -1008,10 +1165,10 @@ function workflowMetadataForRun(events, runId) {
1008
1165
  const fallback = {};
1009
1166
  for (const event of events) {
1010
1167
  if (event.runId !== runId) continue;
1011
- const attrs = event.attributes;
1012
- if (!attrs || typeof attrs !== "object") continue;
1013
- const direct = extractSessionWorkflowMetadata(attrs);
1014
- const nested = attrs.metadata && typeof attrs.metadata === "object" ? extractSessionWorkflowMetadata(attrs.metadata) : void 0;
1168
+ const attrs2 = event.attributes;
1169
+ if (!attrs2 || typeof attrs2 !== "object") continue;
1170
+ const direct = extractSessionWorkflowMetadata(attrs2);
1171
+ const nested = attrs2.metadata && typeof attrs2.metadata === "object" ? extractSessionWorkflowMetadata(attrs2.metadata) : void 0;
1015
1172
  const bag = {};
1016
1173
  mergeWorkflowMeta(bag, direct);
1017
1174
  mergeWorkflowMeta(bag, nested);
@@ -2227,7 +2384,7 @@ function classifyRuleExecution(findings, threw) {
2227
2384
  }
2228
2385
  return "pass";
2229
2386
  }
2230
- function stringAttr(event, keys) {
2387
+ function stringAttr2(event, keys) {
2231
2388
  for (const key of keys) {
2232
2389
  const value = event.attributes?.[key];
2233
2390
  if (typeof value === "string" && value.trim() !== "") return value;
@@ -2305,15 +2462,15 @@ function semanticEvents(context) {
2305
2462
  }
2306
2463
  function llmModel(event) {
2307
2464
  const keys = ["model", "modelId", "responseModelId", "modelName", "model_name"];
2308
- return stringAttr(event, keys) ?? metadataStringAttr(event, keys) ?? stripPrefix(event.name, ["llm:", "generation:", "transcription:", "speech:"]);
2465
+ return stringAttr2(event, keys) ?? metadataStringAttr(event, keys) ?? stripPrefix(event.name, ["llm:", "generation:", "transcription:", "speech:"]);
2309
2466
  }
2310
2467
  function llmProvider(event) {
2311
2468
  const keys = ["provider", "providerName", "provider_name"];
2312
- return stringAttr(event, keys) ?? metadataStringAttr(event, keys);
2469
+ return stringAttr2(event, keys) ?? metadataStringAttr(event, keys);
2313
2470
  }
2314
2471
  function llmFinishReason(event) {
2315
2472
  const keys = ["finishReason", "rawFinishReason", "finish_reason"];
2316
- return stringAttr(event, keys) ?? metadataStringAttr(event, keys);
2473
+ return stringAttr2(event, keys) ?? metadataStringAttr(event, keys);
2317
2474
  }
2318
2475
  function retryCount(event) {
2319
2476
  return numericAttr(event, ["retryCount", "retryAttempt", "retry_attempt", "attempt"]);
@@ -2455,7 +2612,7 @@ function parentMarkedUnresolved(event) {
2455
2612
  ]) === true) {
2456
2613
  return true;
2457
2614
  }
2458
- const resolution = stringAttr(event, [
2615
+ const resolution = stringAttr2(event, [
2459
2616
  "parentResolution",
2460
2617
  "relationshipResolution",
2461
2618
  "relationshipStatus"
@@ -2463,13 +2620,13 @@ function parentMarkedUnresolved(event) {
2463
2620
  return resolution === "unresolved" || resolution === "missing-parent";
2464
2621
  }
2465
2622
  function signalName(event, attributeKeys, prefixes) {
2466
- return stringAttr(event, attributeKeys) ?? stripPrefix(event.name, prefixes);
2623
+ return stringAttr2(event, attributeKeys) ?? stripPrefix(event.name, prefixes);
2467
2624
  }
2468
2625
  function guardrailEvents(context) {
2469
2626
  return finishedEvents(context).filter((event) => {
2470
2627
  const name = event.name.toLowerCase();
2471
2628
  if (name.startsWith("guardrail:") || name.includes(".guardrail.")) return true;
2472
- return stringAttr(event, ["guardrailName", "guardrail", "guardrailId"]) !== void 0;
2629
+ return stringAttr2(event, ["guardrailName", "guardrail", "guardrailId"]) !== void 0;
2473
2630
  });
2474
2631
  }
2475
2632
  function retryValue(event) {
@@ -3928,6 +4085,7 @@ exports.createToolOrderingRule = createToolOrderingRule;
3928
4085
  exports.createToolUsageRule = createToolUsageRule;
3929
4086
  exports.defineTraceContract = defineTraceContract;
3930
4087
  exports.deriveFailureFacts = deriveFailureFacts;
4088
+ exports.deriveRelationshipFacts = deriveRelationshipFacts;
3931
4089
  exports.evaluateTraceContract = evaluateTraceContract;
3932
4090
  exports.evaluateTraceContractRead = evaluateTraceContractRead;
3933
4091
  exports.explainTraceContract = explainTraceContract;