@agent-inspect/langchain 6.14.1 → 6.15.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.
package/dist/index.cjs CHANGED
@@ -473,6 +473,11 @@ function isSemanticParentLabel(parentLcRunId) {
473
473
  if (WELL_KNOWN_SEMANTIC_PARENTS.has(parentLcRunId)) return true;
474
474
  return parentLcRunId.startsWith("__") && parentLcRunId.endsWith("__");
475
475
  }
476
+ function excludeSelf(stepId, excludeStepId) {
477
+ if (!stepId) return void 0;
478
+ if (excludeStepId && stepId === excludeStepId) return void 0;
479
+ return stepId;
480
+ }
476
481
  var LANGGRAPH_PARENT_KEYS = [
477
482
  "handoffFrom",
478
483
  "taskId",
@@ -485,10 +490,11 @@ function langGraphRecord(attributes) {
485
490
  if (typeof lg !== "object" || lg === null || Array.isArray(lg)) return void 0;
486
491
  return lg;
487
492
  }
488
- function resolveParentRelationship(input, lookup) {
493
+ function resolveParentRelationship(input, lookup, context = {}) {
489
494
  const parentLcRunId = input.parentLcRunId;
495
+ const excludeStepId = context.excludeStepId;
490
496
  if (parentLcRunId) {
491
- const exact = lookup.exactStepByLcRunId(parentLcRunId);
497
+ const exact = excludeSelf(lookup.exactStepByLcRunId(parentLcRunId), excludeStepId);
492
498
  if (exact) {
493
499
  return {
494
500
  parentStepId: exact,
@@ -503,8 +509,14 @@ function resolveParentRelationship(input, lookup) {
503
509
  if (key !== "handoffFrom" && key !== "checkpointNamespace") continue;
504
510
  const raw = lg[key];
505
511
  if (typeof raw !== "string" || !raw.trim()) continue;
506
- const stepId = lookup.uniqueStepByLangGraphKey(key === "handoffFrom" ? "taskId" : key, raw);
507
- const matched = stepId ?? (key === "handoffFrom" ? lookup.uniqueStepByLangGraphKey("nodeName", raw) ?? lookup.uniqueStepByLangGraphKey("nodeId", raw) : void 0);
512
+ const stepId = excludeSelf(
513
+ lookup.uniqueStepByLangGraphKey(key === "handoffFrom" ? "taskId" : key, raw),
514
+ excludeStepId
515
+ );
516
+ const matched = stepId ?? excludeSelf(
517
+ key === "handoffFrom" ? lookup.uniqueStepByLangGraphKey("nodeName", raw) ?? lookup.uniqueStepByLangGraphKey("nodeId", raw) : void 0,
518
+ excludeStepId
519
+ );
508
520
  if (matched) {
509
521
  return {
510
522
  parentStepId: matched,
@@ -516,7 +528,10 @@ function resolveParentRelationship(input, lookup) {
516
528
  }
517
529
  }
518
530
  if (parentLcRunId && isSemanticParentLabel(parentLcRunId)) {
519
- const semantic = lookup.uniqueStepBySemanticLabel(parentLcRunId);
531
+ const semantic = excludeSelf(
532
+ lookup.uniqueStepBySemanticLabel(parentLcRunId),
533
+ excludeStepId
534
+ );
520
535
  if (semantic) {
521
536
  return {
522
537
  parentStepId: semantic,
@@ -544,6 +559,41 @@ function resolveParentRelationship(input, lookup) {
544
559
  parentMapping: "exact"
545
560
  };
546
561
  }
562
+ function rejectSelfParentResolution(resolution, stepId, parentLcRunId) {
563
+ if (resolution.parentStepId !== stepId) return resolution;
564
+ return {
565
+ confidence: "unresolved",
566
+ parentMapping: "unresolved",
567
+ unresolvedParentRunId: parentLcRunId ?? resolution.unresolvedParentRunId,
568
+ ...resolution.semanticParentLabel ? { semanticParentLabel: resolution.semanticParentLabel } : {}
569
+ };
570
+ }
571
+ var AI_LANGGRAPH_SELF_PARENT_REJECTED = "AI_LANGGRAPH_SELF_PARENT_REJECTED";
572
+ var AI_LANGGRAPH_RELATIONSHIP_AMBIGUOUS = "AI_LANGGRAPH_RELATIONSHIP_AMBIGUOUS";
573
+ function applySelfParentCaptureInvariant(stepId, parentStepId, metadata, originalParentRunId) {
574
+ if (!parentStepId || parentStepId !== stepId) {
575
+ return { parentStepId, rejected: false };
576
+ }
577
+ metadata.parentMapping = "self-parent-rejected";
578
+ metadata.parentConfidence = "unresolved";
579
+ metadata.relationshipWarning = "self-parent";
580
+ metadata.diagnosticCode = AI_LANGGRAPH_SELF_PARENT_REJECTED;
581
+ if (originalParentRunId && originalParentRunId.trim()) {
582
+ metadata.originalParentRunId = originalParentRunId.slice(0, 128);
583
+ }
584
+ delete metadata.parentCorrelatedVia;
585
+ return { parentStepId: void 0, rejected: true };
586
+ }
587
+ function applyAmbiguousScaffoldingDiagnostic(resolution, metadata) {
588
+ if (resolution.parentStepId) return false;
589
+ if (resolution.parentMapping !== "unresolved") return false;
590
+ if (metadata.diagnosticCode === AI_LANGGRAPH_SELF_PARENT_REJECTED) return false;
591
+ metadata.diagnosticCode = AI_LANGGRAPH_RELATIONSHIP_AMBIGUOUS;
592
+ if (typeof metadata.relationshipWarning !== "string") {
593
+ metadata.relationshipWarning = "ambiguous-root";
594
+ }
595
+ return true;
596
+ }
547
597
  function applyParentResolutionMetadata(metadata, resolution) {
548
598
  const hasParentSignal = Boolean(resolution.parentStepId) || Boolean(resolution.unresolvedParentRunId) || Boolean(resolution.semanticParentLabel) || Boolean(resolution.correlatedVia);
549
599
  if (!hasParentSignal) return;
@@ -604,6 +654,8 @@ var LangChainTracePersistence = class {
604
654
  /** Count of unresolved semantic-parent children seen per label (this invocation). */
605
655
  #semanticParentCounts = /* @__PURE__ */ new Map();
606
656
  #lateEventCount = 0;
657
+ #selfParentRejectedCount = 0;
658
+ #ambiguousRelationshipCount = 0;
607
659
  constructor(options = {}) {
608
660
  const inContext = advanced.hasActiveContext();
609
661
  this.#standalone = !inContext;
@@ -641,12 +693,28 @@ var LangChainTracePersistence = class {
641
693
  pendingRelationshipCount: this.#lifecycle.pendingRelationships.length,
642
694
  knownRelationshipCount: this.#lifecycle.knownRelationships.size,
643
695
  syntheticGroupCount: this.#syntheticByLabel.size,
696
+ selfParentRejectedCount: this.#selfParentRejectedCount,
697
+ ambiguousRelationshipCount: this.#ambiguousRelationshipCount,
644
698
  envelopeStarted: this.#lifecycle.envelopeStarted,
645
699
  finalized: this.#lifecycle.finalized,
646
700
  completionGeneration: this.#lifecycle.completionGeneration,
647
701
  hasTerminalError: Boolean(this.#lifecycle.terminalError)
648
702
  };
649
703
  }
704
+ #parentIdForPersist(stepId, resolution, metadata, originalParentRunId) {
705
+ const guarded = applySelfParentCaptureInvariant(
706
+ stepId,
707
+ resolution.parentStepId,
708
+ metadata,
709
+ originalParentRunId ?? resolution.unresolvedParentRunId
710
+ );
711
+ if (guarded.rejected) {
712
+ this.#selfParentRejectedCount += 1;
713
+ } else if (applyAmbiguousScaffoldingDiagnostic(resolution, metadata)) {
714
+ this.#ambiguousRelationshipCount += 1;
715
+ }
716
+ return guarded.parentStepId;
717
+ }
650
718
  /**
651
719
  * Start a fresh envelope after a prior invocation finalized (callback reuse).
652
720
  * Allocates a new run id unless still nested in an inspectRun context.
@@ -659,6 +727,8 @@ var LangChainTracePersistence = class {
659
727
  resetInvocationState(this.#lifecycle, this.#runId);
660
728
  this.#clearStepIndexes();
661
729
  this.#lateEventCount = 0;
730
+ this.#selfParentRejectedCount = 0;
731
+ this.#ambiguousRelationshipCount = 0;
662
732
  return;
663
733
  }
664
734
  }
@@ -666,11 +736,15 @@ var LangChainTracePersistence = class {
666
736
  resetInvocationState(this.#lifecycle, this.#runId);
667
737
  this.#clearStepIndexes();
668
738
  this.#lateEventCount = 0;
739
+ this.#selfParentRejectedCount = 0;
740
+ this.#ambiguousRelationshipCount = 0;
669
741
  }
670
742
  reset() {
671
743
  resetInvocationState(this.#lifecycle);
672
744
  this.#clearStepIndexes();
673
745
  this.#lateEventCount = 0;
746
+ this.#selfParentRejectedCount = 0;
747
+ this.#ambiguousRelationshipCount = 0;
674
748
  }
675
749
  #clearStepIndexes() {
676
750
  this.#lcToStepId.clear();
@@ -718,8 +792,8 @@ var LangChainTracePersistence = class {
718
792
  }
719
793
  }
720
794
  }
721
- #resolveParent(parentLcRunId, attributes) {
722
- return resolveParentRelationship(
795
+ #resolveParent(parentLcRunId, attributes, excludeStepId) {
796
+ const resolution = resolveParentRelationship(
723
797
  { parentLcRunId, attributes },
724
798
  {
725
799
  exactStepByLcRunId: (lcRunId) => this.#lcToStepId.get(lcRunId),
@@ -731,8 +805,10 @@ var LangChainTracePersistence = class {
731
805
  const hit = this.#semanticLabelIndex.get(label);
732
806
  return hit === null || hit === void 0 ? void 0 : hit;
733
807
  }
734
- }
808
+ },
809
+ excludeStepId ? { excludeStepId } : {}
735
810
  );
811
+ return excludeStepId ? rejectSelfParentResolution(resolution, excludeStepId, parentLcRunId) : resolution;
736
812
  }
737
813
  /**
738
814
  * When ≥2 steps share the same unresolved semantic parent label, emit one
@@ -810,8 +886,10 @@ var LangChainTracePersistence = class {
810
886
  try {
811
887
  this.#prepareForStart();
812
888
  const stepId = advanced.createStepId();
813
- this.#lcToStepId.set(params.lcRunId, stepId);
814
- this.#registerStepIndexes(stepId, params.name, params.attributes);
889
+ const resolution = await this.#maybeAttachSyntheticGroup(
890
+ this.#resolveParent(params.lcParentRunId, params.attributes, stepId),
891
+ params.startTime
892
+ );
815
893
  beginCallbackRun(this.#lifecycle, {
816
894
  lcRunId: params.lcRunId,
817
895
  parentLcRunId: params.lcParentRunId,
@@ -822,25 +900,29 @@ var LangChainTracePersistence = class {
822
900
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
823
901
  await this.#ensureRunStarted(params.startTime, params.attributes);
824
902
  }
825
- const resolution = await this.#maybeAttachSyntheticGroup(
826
- this.#resolveParent(params.lcParentRunId, params.attributes),
827
- params.startTime
828
- );
829
903
  const metadata = toStepMetadata(params.attributes);
830
904
  applyParentResolutionMetadata(metadata, resolution);
905
+ const parentId = this.#parentIdForPersist(
906
+ stepId,
907
+ resolution,
908
+ metadata,
909
+ params.lcParentRunId
910
+ );
831
911
  const event = {
832
912
  schemaVersion: "0.1",
833
913
  event: "step_started",
834
914
  timestamp: params.startTime,
835
915
  runId: this.#runId,
836
916
  stepId,
837
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
917
+ ...parentId ? { parentId } : {},
838
918
  name: params.name,
839
919
  type: kindToStepType(params.kind),
840
920
  startTime: params.startTime,
841
921
  metadata
842
922
  };
923
+ this.#lcToStepId.set(params.lcRunId, stepId);
843
924
  await this.#write(event);
925
+ this.#registerStepIndexes(stepId, params.name, params.attributes);
844
926
  } catch (err) {
845
927
  this.#warn(err);
846
928
  }
@@ -858,30 +940,38 @@ var LangChainTracePersistence = class {
858
940
  return;
859
941
  }
860
942
  stepId = advanced.createStepId();
861
- this.#lcToStepId.set(params.lcRunId, stepId);
862
943
  const synthName = String(params.completionAttributes.name ?? "llm:llm");
863
- this.#registerStepIndexes(stepId, synthName, params.completionAttributes);
944
+ const startTime = params.endTime - (params.durationMs ?? 0);
945
+ const resolution = await this.#maybeAttachSyntheticGroup(
946
+ this.#resolveParent(
947
+ params.lcParentRunId,
948
+ params.completionAttributes,
949
+ stepId
950
+ ),
951
+ startTime
952
+ );
864
953
  beginCallbackRun(this.#lifecycle, {
865
954
  lcRunId: params.lcRunId,
866
955
  parentLcRunId: params.lcParentRunId,
867
- startedAt: params.endTime - (params.durationMs ?? 0),
956
+ startedAt: startTime,
868
957
  kind: params.completionAttributes.kind ?? "LLM",
869
958
  stepId
870
959
  });
871
- const startTime = params.endTime - (params.durationMs ?? 0);
872
- const resolution = await this.#maybeAttachSyntheticGroup(
873
- this.#resolveParent(params.lcParentRunId, params.completionAttributes),
874
- startTime
875
- );
876
960
  const metadata = toStepMetadata(params.completionAttributes);
877
961
  applyParentResolutionMetadata(metadata, resolution);
962
+ const parentId = this.#parentIdForPersist(
963
+ stepId,
964
+ resolution,
965
+ metadata,
966
+ params.lcParentRunId
967
+ );
878
968
  const started = {
879
969
  schemaVersion: "0.1",
880
970
  event: "step_started",
881
971
  timestamp: startTime,
882
972
  runId: this.#runId,
883
973
  stepId,
884
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
974
+ ...parentId ? { parentId } : {},
885
975
  name: synthName,
886
976
  type: kindToStepType(
887
977
  params.completionAttributes.kind ?? "LLM"
@@ -892,7 +982,9 @@ var LangChainTracePersistence = class {
892
982
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
893
983
  await this.#ensureRunStarted(startTime, params.completionAttributes);
894
984
  }
985
+ this.#lcToStepId.set(params.lcRunId, stepId);
895
986
  await this.#write(started);
987
+ this.#registerStepIndexes(stepId, synthName, params.completionAttributes);
896
988
  }
897
989
  if (!stepId) return;
898
990
  const durationMs = typeof params.durationMs === "number" && Number.isFinite(params.durationMs) ? Math.max(0, Math.floor(params.durationMs)) : Math.max(
@@ -928,8 +1020,10 @@ var LangChainTracePersistence = class {
928
1020
  try {
929
1021
  this.#prepareForStart();
930
1022
  const stepId = advanced.createStepId();
931
- this.#lcToStepId.set(params.lcRunId, stepId);
932
- this.#registerStepIndexes(stepId, params.name, params.attributes);
1023
+ const resolution = await this.#maybeAttachSyntheticGroup(
1024
+ this.#resolveParent(params.lcParentRunId, params.attributes, stepId),
1025
+ params.timestamp
1026
+ );
933
1027
  beginCallbackRun(this.#lifecycle, {
934
1028
  lcRunId: params.lcRunId,
935
1029
  parentLcRunId: params.lcParentRunId,
@@ -940,25 +1034,29 @@ var LangChainTracePersistence = class {
940
1034
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
941
1035
  await this.#ensureRunStarted(params.timestamp, params.attributes);
942
1036
  }
943
- const resolution = await this.#maybeAttachSyntheticGroup(
944
- this.#resolveParent(params.lcParentRunId, params.attributes),
945
- params.timestamp
946
- );
947
1037
  const metadata = toStepMetadata(params.attributes);
948
1038
  applyParentResolutionMetadata(metadata, resolution);
1039
+ const parentId = this.#parentIdForPersist(
1040
+ stepId,
1041
+ resolution,
1042
+ metadata,
1043
+ params.lcParentRunId
1044
+ );
949
1045
  const started = {
950
1046
  schemaVersion: "0.1",
951
1047
  event: "step_started",
952
1048
  timestamp: params.timestamp,
953
1049
  runId: this.#runId,
954
1050
  stepId,
955
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
1051
+ ...parentId ? { parentId } : {},
956
1052
  name: params.name,
957
1053
  type: kindToStepType(params.kind),
958
1054
  startTime: params.timestamp,
959
1055
  metadata
960
1056
  };
1057
+ this.#lcToStepId.set(params.lcRunId, stepId);
961
1058
  await this.#write(started);
1059
+ this.#registerStepIndexes(stepId, params.name, params.attributes);
962
1060
  const completed = {
963
1061
  schemaVersion: "0.1",
964
1062
  event: "step_completed",
@@ -1204,6 +1302,8 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
1204
1302
  pendingRelationshipCount: 0,
1205
1303
  knownRelationshipCount: 0,
1206
1304
  syntheticGroupCount: 0,
1305
+ selfParentRejectedCount: 0,
1306
+ ambiguousRelationshipCount: 0,
1207
1307
  envelopeStarted: false,
1208
1308
  finalized: false,
1209
1309
  completionGeneration: 0,