@agent-inspect/langchain 6.14.1 → 6.14.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.
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,30 @@ 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
+ function applySelfParentCaptureInvariant(stepId, parentStepId, metadata, originalParentRunId) {
573
+ if (!parentStepId || parentStepId !== stepId) {
574
+ return { parentStepId, rejected: false };
575
+ }
576
+ metadata.parentMapping = "self-parent-rejected";
577
+ metadata.parentConfidence = "unresolved";
578
+ metadata.relationshipWarning = "self-parent";
579
+ metadata.diagnosticCode = AI_LANGGRAPH_SELF_PARENT_REJECTED;
580
+ if (originalParentRunId && originalParentRunId.trim()) {
581
+ metadata.originalParentRunId = originalParentRunId.slice(0, 128);
582
+ }
583
+ delete metadata.parentCorrelatedVia;
584
+ return { parentStepId: void 0, rejected: true };
585
+ }
547
586
  function applyParentResolutionMetadata(metadata, resolution) {
548
587
  const hasParentSignal = Boolean(resolution.parentStepId) || Boolean(resolution.unresolvedParentRunId) || Boolean(resolution.semanticParentLabel) || Boolean(resolution.correlatedVia);
549
588
  if (!hasParentSignal) return;
@@ -604,6 +643,7 @@ var LangChainTracePersistence = class {
604
643
  /** Count of unresolved semantic-parent children seen per label (this invocation). */
605
644
  #semanticParentCounts = /* @__PURE__ */ new Map();
606
645
  #lateEventCount = 0;
646
+ #selfParentRejectedCount = 0;
607
647
  constructor(options = {}) {
608
648
  const inContext = advanced.hasActiveContext();
609
649
  this.#standalone = !inContext;
@@ -641,12 +681,25 @@ var LangChainTracePersistence = class {
641
681
  pendingRelationshipCount: this.#lifecycle.pendingRelationships.length,
642
682
  knownRelationshipCount: this.#lifecycle.knownRelationships.size,
643
683
  syntheticGroupCount: this.#syntheticByLabel.size,
684
+ selfParentRejectedCount: this.#selfParentRejectedCount,
644
685
  envelopeStarted: this.#lifecycle.envelopeStarted,
645
686
  finalized: this.#lifecycle.finalized,
646
687
  completionGeneration: this.#lifecycle.completionGeneration,
647
688
  hasTerminalError: Boolean(this.#lifecycle.terminalError)
648
689
  };
649
690
  }
691
+ #parentIdForPersist(stepId, resolution, metadata, originalParentRunId) {
692
+ const guarded = applySelfParentCaptureInvariant(
693
+ stepId,
694
+ resolution.parentStepId,
695
+ metadata,
696
+ originalParentRunId ?? resolution.unresolvedParentRunId
697
+ );
698
+ if (guarded.rejected) {
699
+ this.#selfParentRejectedCount += 1;
700
+ }
701
+ return guarded.parentStepId;
702
+ }
650
703
  /**
651
704
  * Start a fresh envelope after a prior invocation finalized (callback reuse).
652
705
  * Allocates a new run id unless still nested in an inspectRun context.
@@ -659,6 +712,7 @@ var LangChainTracePersistence = class {
659
712
  resetInvocationState(this.#lifecycle, this.#runId);
660
713
  this.#clearStepIndexes();
661
714
  this.#lateEventCount = 0;
715
+ this.#selfParentRejectedCount = 0;
662
716
  return;
663
717
  }
664
718
  }
@@ -666,11 +720,13 @@ var LangChainTracePersistence = class {
666
720
  resetInvocationState(this.#lifecycle, this.#runId);
667
721
  this.#clearStepIndexes();
668
722
  this.#lateEventCount = 0;
723
+ this.#selfParentRejectedCount = 0;
669
724
  }
670
725
  reset() {
671
726
  resetInvocationState(this.#lifecycle);
672
727
  this.#clearStepIndexes();
673
728
  this.#lateEventCount = 0;
729
+ this.#selfParentRejectedCount = 0;
674
730
  }
675
731
  #clearStepIndexes() {
676
732
  this.#lcToStepId.clear();
@@ -718,8 +774,8 @@ var LangChainTracePersistence = class {
718
774
  }
719
775
  }
720
776
  }
721
- #resolveParent(parentLcRunId, attributes) {
722
- return resolveParentRelationship(
777
+ #resolveParent(parentLcRunId, attributes, excludeStepId) {
778
+ const resolution = resolveParentRelationship(
723
779
  { parentLcRunId, attributes },
724
780
  {
725
781
  exactStepByLcRunId: (lcRunId) => this.#lcToStepId.get(lcRunId),
@@ -731,8 +787,10 @@ var LangChainTracePersistence = class {
731
787
  const hit = this.#semanticLabelIndex.get(label);
732
788
  return hit === null || hit === void 0 ? void 0 : hit;
733
789
  }
734
- }
790
+ },
791
+ excludeStepId ? { excludeStepId } : {}
735
792
  );
793
+ return excludeStepId ? rejectSelfParentResolution(resolution, excludeStepId, parentLcRunId) : resolution;
736
794
  }
737
795
  /**
738
796
  * When ≥2 steps share the same unresolved semantic parent label, emit one
@@ -810,8 +868,10 @@ var LangChainTracePersistence = class {
810
868
  try {
811
869
  this.#prepareForStart();
812
870
  const stepId = advanced.createStepId();
813
- this.#lcToStepId.set(params.lcRunId, stepId);
814
- this.#registerStepIndexes(stepId, params.name, params.attributes);
871
+ const resolution = await this.#maybeAttachSyntheticGroup(
872
+ this.#resolveParent(params.lcParentRunId, params.attributes, stepId),
873
+ params.startTime
874
+ );
815
875
  beginCallbackRun(this.#lifecycle, {
816
876
  lcRunId: params.lcRunId,
817
877
  parentLcRunId: params.lcParentRunId,
@@ -822,25 +882,29 @@ var LangChainTracePersistence = class {
822
882
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
823
883
  await this.#ensureRunStarted(params.startTime, params.attributes);
824
884
  }
825
- const resolution = await this.#maybeAttachSyntheticGroup(
826
- this.#resolveParent(params.lcParentRunId, params.attributes),
827
- params.startTime
828
- );
829
885
  const metadata = toStepMetadata(params.attributes);
830
886
  applyParentResolutionMetadata(metadata, resolution);
887
+ const parentId = this.#parentIdForPersist(
888
+ stepId,
889
+ resolution,
890
+ metadata,
891
+ params.lcParentRunId
892
+ );
831
893
  const event = {
832
894
  schemaVersion: "0.1",
833
895
  event: "step_started",
834
896
  timestamp: params.startTime,
835
897
  runId: this.#runId,
836
898
  stepId,
837
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
899
+ ...parentId ? { parentId } : {},
838
900
  name: params.name,
839
901
  type: kindToStepType(params.kind),
840
902
  startTime: params.startTime,
841
903
  metadata
842
904
  };
905
+ this.#lcToStepId.set(params.lcRunId, stepId);
843
906
  await this.#write(event);
907
+ this.#registerStepIndexes(stepId, params.name, params.attributes);
844
908
  } catch (err) {
845
909
  this.#warn(err);
846
910
  }
@@ -858,30 +922,38 @@ var LangChainTracePersistence = class {
858
922
  return;
859
923
  }
860
924
  stepId = advanced.createStepId();
861
- this.#lcToStepId.set(params.lcRunId, stepId);
862
925
  const synthName = String(params.completionAttributes.name ?? "llm:llm");
863
- this.#registerStepIndexes(stepId, synthName, params.completionAttributes);
926
+ const startTime = params.endTime - (params.durationMs ?? 0);
927
+ const resolution = await this.#maybeAttachSyntheticGroup(
928
+ this.#resolveParent(
929
+ params.lcParentRunId,
930
+ params.completionAttributes,
931
+ stepId
932
+ ),
933
+ startTime
934
+ );
864
935
  beginCallbackRun(this.#lifecycle, {
865
936
  lcRunId: params.lcRunId,
866
937
  parentLcRunId: params.lcParentRunId,
867
- startedAt: params.endTime - (params.durationMs ?? 0),
938
+ startedAt: startTime,
868
939
  kind: params.completionAttributes.kind ?? "LLM",
869
940
  stepId
870
941
  });
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
942
  const metadata = toStepMetadata(params.completionAttributes);
877
943
  applyParentResolutionMetadata(metadata, resolution);
944
+ const parentId = this.#parentIdForPersist(
945
+ stepId,
946
+ resolution,
947
+ metadata,
948
+ params.lcParentRunId
949
+ );
878
950
  const started = {
879
951
  schemaVersion: "0.1",
880
952
  event: "step_started",
881
953
  timestamp: startTime,
882
954
  runId: this.#runId,
883
955
  stepId,
884
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
956
+ ...parentId ? { parentId } : {},
885
957
  name: synthName,
886
958
  type: kindToStepType(
887
959
  params.completionAttributes.kind ?? "LLM"
@@ -892,7 +964,9 @@ var LangChainTracePersistence = class {
892
964
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
893
965
  await this.#ensureRunStarted(startTime, params.completionAttributes);
894
966
  }
967
+ this.#lcToStepId.set(params.lcRunId, stepId);
895
968
  await this.#write(started);
969
+ this.#registerStepIndexes(stepId, synthName, params.completionAttributes);
896
970
  }
897
971
  if (!stepId) return;
898
972
  const durationMs = typeof params.durationMs === "number" && Number.isFinite(params.durationMs) ? Math.max(0, Math.floor(params.durationMs)) : Math.max(
@@ -928,8 +1002,10 @@ var LangChainTracePersistence = class {
928
1002
  try {
929
1003
  this.#prepareForStart();
930
1004
  const stepId = advanced.createStepId();
931
- this.#lcToStepId.set(params.lcRunId, stepId);
932
- this.#registerStepIndexes(stepId, params.name, params.attributes);
1005
+ const resolution = await this.#maybeAttachSyntheticGroup(
1006
+ this.#resolveParent(params.lcParentRunId, params.attributes, stepId),
1007
+ params.timestamp
1008
+ );
933
1009
  beginCallbackRun(this.#lifecycle, {
934
1010
  lcRunId: params.lcRunId,
935
1011
  parentLcRunId: params.lcParentRunId,
@@ -940,25 +1016,29 @@ var LangChainTracePersistence = class {
940
1016
  if (this.#standalone && !this.#lifecycle.envelopeStarted) {
941
1017
  await this.#ensureRunStarted(params.timestamp, params.attributes);
942
1018
  }
943
- const resolution = await this.#maybeAttachSyntheticGroup(
944
- this.#resolveParent(params.lcParentRunId, params.attributes),
945
- params.timestamp
946
- );
947
1019
  const metadata = toStepMetadata(params.attributes);
948
1020
  applyParentResolutionMetadata(metadata, resolution);
1021
+ const parentId = this.#parentIdForPersist(
1022
+ stepId,
1023
+ resolution,
1024
+ metadata,
1025
+ params.lcParentRunId
1026
+ );
949
1027
  const started = {
950
1028
  schemaVersion: "0.1",
951
1029
  event: "step_started",
952
1030
  timestamp: params.timestamp,
953
1031
  runId: this.#runId,
954
1032
  stepId,
955
- ...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
1033
+ ...parentId ? { parentId } : {},
956
1034
  name: params.name,
957
1035
  type: kindToStepType(params.kind),
958
1036
  startTime: params.timestamp,
959
1037
  metadata
960
1038
  };
1039
+ this.#lcToStepId.set(params.lcRunId, stepId);
961
1040
  await this.#write(started);
1041
+ this.#registerStepIndexes(stepId, params.name, params.attributes);
962
1042
  const completed = {
963
1043
  schemaVersion: "0.1",
964
1044
  event: "step_completed",
@@ -1204,6 +1284,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
1204
1284
  pendingRelationshipCount: 0,
1205
1285
  knownRelationshipCount: 0,
1206
1286
  syntheticGroupCount: 0,
1287
+ selfParentRejectedCount: 0,
1207
1288
  envelopeStarted: false,
1208
1289
  finalized: false,
1209
1290
  completionGeneration: 0,