@agent-inspect/langchain 6.14.0 → 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/README.md +1 -0
- package/dist/index.cjs +112 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +112 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ LangChain callback handler → local AgentInspect traces.
|
|
|
9
9
|
|
|
10
10
|
- LangChain or LangGraph apps using `@langchain/core` callbacks
|
|
11
11
|
- You want `persist: true` local JSONL without a hosted backend
|
|
12
|
+
- Evidence-first CI / TraceContract gates over LangGraph runs (`init --framework langgraph`)
|
|
12
13
|
|
|
13
14
|
## When not to use
|
|
14
15
|
|
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 =
|
|
507
|
-
|
|
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 =
|
|
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
|
-
|
|
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.#
|
|
814
|
-
|
|
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
|
-
...
|
|
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
|
-
|
|
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:
|
|
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
|
-
...
|
|
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.#
|
|
932
|
-
|
|
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
|
-
...
|
|
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,
|