@agent-inspect/langchain 6.7.5 → 6.8.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/README.md +17 -5
- package/dist/index.cjs +694 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -3
- package/dist/index.d.ts +77 -3
- package/dist/index.mjs +694 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -323,6 +323,247 @@ function streamMetadataFromState(state, options) {
|
|
|
323
323
|
}
|
|
324
324
|
return out;
|
|
325
325
|
}
|
|
326
|
+
|
|
327
|
+
// packages/langchain/src/tool-identity.ts
|
|
328
|
+
function serializedLabel(s) {
|
|
329
|
+
if (typeof s.name === "string" && s.name.trim()) return s.name.trim();
|
|
330
|
+
if (Array.isArray(s.id) && s.id.length > 0) {
|
|
331
|
+
const last = s.id[s.id.length - 1];
|
|
332
|
+
if (typeof last === "string" && last.trim()) return last.trim();
|
|
333
|
+
}
|
|
334
|
+
return typeof s.type === "string" && s.type.trim() ? s.type.trim() : void 0;
|
|
335
|
+
}
|
|
336
|
+
function nonEmpty(value) {
|
|
337
|
+
if (typeof value !== "string") return void 0;
|
|
338
|
+
const trimmed = value.trim();
|
|
339
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
340
|
+
}
|
|
341
|
+
function resolveToolIdentity(tool, runName, metadata, toolCallId) {
|
|
342
|
+
const frameworkRunName = nonEmpty(runName);
|
|
343
|
+
const metaToolName = nonEmpty(metadata?.toolName);
|
|
344
|
+
const metaTool = nonEmpty(metadata?.tool);
|
|
345
|
+
const classLabel = serializedLabel(tool);
|
|
346
|
+
const callId = nonEmpty(toolCallId) ?? nonEmpty(metadata?.toolCallId) ?? nonEmpty(metadata?.tool_call_id);
|
|
347
|
+
const displayName = frameworkRunName ?? metaToolName ?? metaTool ?? classLabel ?? "unknown-tool";
|
|
348
|
+
return {
|
|
349
|
+
displayName,
|
|
350
|
+
toolName: displayName,
|
|
351
|
+
...classLabel && classLabel !== displayName ? { toolClass: classLabel } : {},
|
|
352
|
+
...callId ? { toolCallId: callId } : {},
|
|
353
|
+
...frameworkRunName ? { frameworkRunName } : {}
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function applyToolIdentityAttributes(attrs, identity) {
|
|
357
|
+
attrs.tool = identity.displayName;
|
|
358
|
+
attrs.toolName = identity.toolName;
|
|
359
|
+
if (identity.toolClass) attrs.toolClass = identity.toolClass;
|
|
360
|
+
if (identity.toolCallId) attrs.toolCallId = identity.toolCallId;
|
|
361
|
+
if (identity.frameworkRunName) attrs.frameworkRunName = identity.frameworkRunName;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// packages/langchain/src/persist-intent.ts
|
|
365
|
+
function resolvePersistIntent(input) {
|
|
366
|
+
const hasTraceDir = typeof input.traceDir === "string" && input.traceDir.trim().length > 0;
|
|
367
|
+
const explicit = input.persist;
|
|
368
|
+
if (explicit === false) {
|
|
369
|
+
return { persist: false, contradictory: hasTraceDir };
|
|
370
|
+
}
|
|
371
|
+
if (explicit === true) {
|
|
372
|
+
return { persist: true, contradictory: false };
|
|
373
|
+
}
|
|
374
|
+
return { persist: hasTraceDir, contradictory: false };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// packages/langchain/src/invocation-state.ts
|
|
378
|
+
function createInvocationState(envelopeRunId) {
|
|
379
|
+
return {
|
|
380
|
+
envelopeRunId,
|
|
381
|
+
activeRuns: /* @__PURE__ */ new Map(),
|
|
382
|
+
endedRuns: /* @__PURE__ */ new Set(),
|
|
383
|
+
knownRelationships: /* @__PURE__ */ new Map(),
|
|
384
|
+
pendingRelationships: [],
|
|
385
|
+
completionGeneration: 0,
|
|
386
|
+
envelopeStarted: false,
|
|
387
|
+
finalized: false
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function isObservedCallbackRun(state, parentLcRunId) {
|
|
391
|
+
return state.activeRuns.has(parentLcRunId) || state.endedRuns.has(parentLcRunId);
|
|
392
|
+
}
|
|
393
|
+
function beginCallbackRun(state, input) {
|
|
394
|
+
state.completionGeneration += 1;
|
|
395
|
+
const run = {
|
|
396
|
+
lcRunId: input.lcRunId,
|
|
397
|
+
...input.parentLcRunId !== void 0 ? { parentLcRunId: input.parentLcRunId } : {},
|
|
398
|
+
startedAt: input.startedAt,
|
|
399
|
+
...input.kind !== void 0 ? { kind: input.kind } : {},
|
|
400
|
+
...input.stepId !== void 0 ? { stepId: input.stepId } : {}
|
|
401
|
+
};
|
|
402
|
+
state.activeRuns.set(input.lcRunId, run);
|
|
403
|
+
if (input.parentLcRunId !== void 0) {
|
|
404
|
+
if (isObservedCallbackRun(state, input.parentLcRunId)) {
|
|
405
|
+
state.knownRelationships.set(input.lcRunId, input.parentLcRunId);
|
|
406
|
+
} else {
|
|
407
|
+
state.pendingRelationships.push({
|
|
408
|
+
childLcRunId: input.lcRunId,
|
|
409
|
+
parentLcRunId: input.parentLcRunId,
|
|
410
|
+
reason: "unobserved-parent"
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return run;
|
|
415
|
+
}
|
|
416
|
+
function endCallbackRun(state, lcRunId) {
|
|
417
|
+
const active = state.activeRuns.get(lcRunId);
|
|
418
|
+
if (active === void 0) {
|
|
419
|
+
if (state.endedRuns.has(lcRunId) || state.finalized) {
|
|
420
|
+
return { ended: false, late: true };
|
|
421
|
+
}
|
|
422
|
+
return { ended: false, late: true };
|
|
423
|
+
}
|
|
424
|
+
state.completionGeneration += 1;
|
|
425
|
+
state.activeRuns.delete(lcRunId);
|
|
426
|
+
state.endedRuns.add(lcRunId);
|
|
427
|
+
return { ended: true, late: false };
|
|
428
|
+
}
|
|
429
|
+
function markEnvelopeStarted(state, startTime) {
|
|
430
|
+
if (state.envelopeStarted) return false;
|
|
431
|
+
state.envelopeStarted = true;
|
|
432
|
+
state.runStartTime = startTime;
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
function markFinalized(state) {
|
|
436
|
+
if (state.finalized) return false;
|
|
437
|
+
if (!state.envelopeStarted) return false;
|
|
438
|
+
state.finalized = true;
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
function noteTerminalError(state, message) {
|
|
442
|
+
state.terminalError = { message };
|
|
443
|
+
}
|
|
444
|
+
function canScheduleFinalize(state) {
|
|
445
|
+
return state.envelopeStarted && !state.finalized && state.activeRuns.size === 0;
|
|
446
|
+
}
|
|
447
|
+
function bumpCompletionGeneration(state) {
|
|
448
|
+
state.completionGeneration += 1;
|
|
449
|
+
return state.completionGeneration;
|
|
450
|
+
}
|
|
451
|
+
function resetInvocationState(state, nextEnvelopeRunId) {
|
|
452
|
+
state.activeRuns.clear();
|
|
453
|
+
state.endedRuns.clear();
|
|
454
|
+
state.knownRelationships.clear();
|
|
455
|
+
state.pendingRelationships.length = 0;
|
|
456
|
+
state.terminalError = void 0;
|
|
457
|
+
state.completionGeneration += 1;
|
|
458
|
+
state.envelopeStarted = false;
|
|
459
|
+
state.finalized = false;
|
|
460
|
+
state.runStartTime = void 0;
|
|
461
|
+
if (nextEnvelopeRunId !== void 0) {
|
|
462
|
+
state.envelopeRunId = nextEnvelopeRunId;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// packages/langchain/src/parent-reconciliation.ts
|
|
467
|
+
var WELL_KNOWN_SEMANTIC_PARENTS = /* @__PURE__ */ new Set([
|
|
468
|
+
"LangGraph",
|
|
469
|
+
"__start__",
|
|
470
|
+
"__end__"
|
|
471
|
+
]);
|
|
472
|
+
function isSemanticParentLabel(parentLcRunId) {
|
|
473
|
+
if (WELL_KNOWN_SEMANTIC_PARENTS.has(parentLcRunId)) return true;
|
|
474
|
+
return parentLcRunId.startsWith("__") && parentLcRunId.endsWith("__");
|
|
475
|
+
}
|
|
476
|
+
var LANGGRAPH_PARENT_KEYS = [
|
|
477
|
+
"handoffFrom",
|
|
478
|
+
"taskId",
|
|
479
|
+
"nodeId",
|
|
480
|
+
"nodeName",
|
|
481
|
+
"checkpointNamespace"
|
|
482
|
+
];
|
|
483
|
+
function langGraphRecord(attributes) {
|
|
484
|
+
const lg = attributes?.langGraph;
|
|
485
|
+
if (typeof lg !== "object" || lg === null || Array.isArray(lg)) return void 0;
|
|
486
|
+
return lg;
|
|
487
|
+
}
|
|
488
|
+
function resolveParentRelationship(input, lookup) {
|
|
489
|
+
const parentLcRunId = input.parentLcRunId;
|
|
490
|
+
if (parentLcRunId) {
|
|
491
|
+
const exact = lookup.exactStepByLcRunId(parentLcRunId);
|
|
492
|
+
if (exact) {
|
|
493
|
+
return {
|
|
494
|
+
parentStepId: exact,
|
|
495
|
+
confidence: "explicit",
|
|
496
|
+
parentMapping: "exact"
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
const lg = langGraphRecord(input.attributes);
|
|
501
|
+
if (lg) {
|
|
502
|
+
for (const key of LANGGRAPH_PARENT_KEYS) {
|
|
503
|
+
if (key !== "handoffFrom" && key !== "checkpointNamespace") continue;
|
|
504
|
+
const raw = lg[key];
|
|
505
|
+
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);
|
|
508
|
+
if (matched) {
|
|
509
|
+
return {
|
|
510
|
+
parentStepId: matched,
|
|
511
|
+
confidence: "correlated",
|
|
512
|
+
parentMapping: "langgraph-metadata",
|
|
513
|
+
correlatedVia: key
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (parentLcRunId && isSemanticParentLabel(parentLcRunId)) {
|
|
519
|
+
const semantic = lookup.uniqueStepBySemanticLabel(parentLcRunId);
|
|
520
|
+
if (semantic) {
|
|
521
|
+
return {
|
|
522
|
+
parentStepId: semantic,
|
|
523
|
+
confidence: "correlated",
|
|
524
|
+
parentMapping: "semantic-name",
|
|
525
|
+
semanticParentLabel: parentLcRunId
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
return {
|
|
529
|
+
confidence: "unresolved",
|
|
530
|
+
parentMapping: "unresolved",
|
|
531
|
+
semanticParentLabel: parentLcRunId,
|
|
532
|
+
unresolvedParentRunId: parentLcRunId
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
if (parentLcRunId) {
|
|
536
|
+
return {
|
|
537
|
+
confidence: "unresolved",
|
|
538
|
+
parentMapping: "unresolved",
|
|
539
|
+
unresolvedParentRunId: parentLcRunId
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
return {
|
|
543
|
+
confidence: "explicit",
|
|
544
|
+
parentMapping: "exact"
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
function applyParentResolutionMetadata(metadata, resolution) {
|
|
548
|
+
const hasParentSignal = Boolean(resolution.parentStepId) || Boolean(resolution.unresolvedParentRunId) || Boolean(resolution.semanticParentLabel) || Boolean(resolution.correlatedVia);
|
|
549
|
+
if (!hasParentSignal) return;
|
|
550
|
+
metadata.parentMapping = resolution.parentMapping;
|
|
551
|
+
metadata.parentConfidence = resolution.confidence;
|
|
552
|
+
if (resolution.semanticParentLabel) {
|
|
553
|
+
metadata.semanticParentLabel = resolution.semanticParentLabel;
|
|
554
|
+
}
|
|
555
|
+
if (resolution.unresolvedParentRunId) {
|
|
556
|
+
metadata.unresolvedParentRunId = resolution.unresolvedParentRunId;
|
|
557
|
+
}
|
|
558
|
+
if (resolution.correlatedVia) {
|
|
559
|
+
metadata.parentCorrelatedVia = resolution.correlatedVia;
|
|
560
|
+
}
|
|
561
|
+
if (resolution.parentMapping === "synthetic-group") {
|
|
562
|
+
metadata.synthetic = true;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// packages/langchain/src/trace-persistence.ts
|
|
326
567
|
function kindToStepType(kind) {
|
|
327
568
|
switch (kind) {
|
|
328
569
|
case "LLM":
|
|
@@ -352,27 +593,30 @@ var LangChainTracePersistence = class {
|
|
|
352
593
|
#standalone;
|
|
353
594
|
#silent;
|
|
354
595
|
#safety;
|
|
355
|
-
#
|
|
356
|
-
#runCompleted = false;
|
|
357
|
-
#runStartTime;
|
|
358
|
-
#rootLcRunId;
|
|
359
|
-
/** Live LangChain callback runIds for standalone envelope finalization. */
|
|
360
|
-
#activeLcRunIds = /* @__PURE__ */ new Set();
|
|
361
|
-
#sawError = false;
|
|
362
|
-
#lastErrorMessage;
|
|
363
|
-
#finalizationToken = 0;
|
|
596
|
+
#lifecycle;
|
|
364
597
|
#lcToStepId = /* @__PURE__ */ new Map();
|
|
598
|
+
/** `${field}\0${value}` → stepId, or null when ambiguous. */
|
|
599
|
+
#langGraphIndex = /* @__PURE__ */ new Map();
|
|
600
|
+
/** Semantic / display label → stepId, or null when ambiguous. */
|
|
601
|
+
#semanticLabelIndex = /* @__PURE__ */ new Map();
|
|
602
|
+
/** Semantic label → synthetic step id (created once ≥2 siblings share the label). */
|
|
603
|
+
#syntheticByLabel = /* @__PURE__ */ new Map();
|
|
604
|
+
/** Count of unresolved semantic-parent children seen per label (this invocation). */
|
|
605
|
+
#semanticParentCounts = /* @__PURE__ */ new Map();
|
|
606
|
+
#lateEventCount = 0;
|
|
365
607
|
constructor(options = {}) {
|
|
366
608
|
const inContext = advanced.hasActiveContext();
|
|
367
609
|
this.#standalone = !inContext;
|
|
368
610
|
this.#silent = options.silent ?? false;
|
|
369
611
|
this.#traceDir = inContext ? advanced.getTraceDirFromContext() ?? advanced.resolveTraceDir({ dir: options.traceDir }) : advanced.resolveTraceDir({ dir: options.traceDir });
|
|
370
|
-
|
|
612
|
+
const contextRunId = inContext ? advanced.getCurrentRunId() : void 0;
|
|
613
|
+
this.#runId = contextRunId ?? options.runId ?? advanced.createRunId();
|
|
371
614
|
this.#runName = options.runName ?? "langchain-agent";
|
|
372
615
|
this.#safety = advanced.resolveTraceSafetyOptions({
|
|
373
616
|
redact: options.redact ? { rules: options.redact } : true,
|
|
374
617
|
maxPreviewLength: options.maxPreviewChars
|
|
375
618
|
});
|
|
619
|
+
this.#lifecycle = createInvocationState(this.#runId);
|
|
376
620
|
}
|
|
377
621
|
get runId() {
|
|
378
622
|
return this.#runId;
|
|
@@ -380,49 +624,217 @@ var LangChainTracePersistence = class {
|
|
|
380
624
|
get traceDir() {
|
|
381
625
|
return this.#traceDir;
|
|
382
626
|
}
|
|
627
|
+
/** @internal Test / diagnostics access to per-invocation lifecycle. */
|
|
628
|
+
get lifecycle() {
|
|
629
|
+
return this.#lifecycle;
|
|
630
|
+
}
|
|
631
|
+
/** Count of end/start events ignored after finalize (diagnostics). */
|
|
632
|
+
get lateEventCount() {
|
|
633
|
+
return this.#lateEventCount;
|
|
634
|
+
}
|
|
635
|
+
/** Bounded adapter diagnostics for CLI/MCP summaries (no filesystem paths). */
|
|
636
|
+
getDiagnostics() {
|
|
637
|
+
return {
|
|
638
|
+
lateEventCount: this.#lateEventCount,
|
|
639
|
+
activeRunCount: this.#lifecycle.activeRuns.size,
|
|
640
|
+
endedRunCount: this.#lifecycle.endedRuns.size,
|
|
641
|
+
pendingRelationshipCount: this.#lifecycle.pendingRelationships.length,
|
|
642
|
+
knownRelationshipCount: this.#lifecycle.knownRelationships.size,
|
|
643
|
+
syntheticGroupCount: this.#syntheticByLabel.size,
|
|
644
|
+
envelopeStarted: this.#lifecycle.envelopeStarted,
|
|
645
|
+
finalized: this.#lifecycle.finalized,
|
|
646
|
+
completionGeneration: this.#lifecycle.completionGeneration,
|
|
647
|
+
hasTerminalError: Boolean(this.#lifecycle.terminalError)
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Start a fresh envelope after a prior invocation finalized (callback reuse).
|
|
652
|
+
* Allocates a new run id unless still nested in an inspectRun context.
|
|
653
|
+
*/
|
|
654
|
+
beginNewInvocation() {
|
|
655
|
+
if (advanced.hasActiveContext()) {
|
|
656
|
+
const ctxId = advanced.getCurrentRunId();
|
|
657
|
+
if (ctxId) {
|
|
658
|
+
this.#runId = ctxId;
|
|
659
|
+
resetInvocationState(this.#lifecycle, this.#runId);
|
|
660
|
+
this.#clearStepIndexes();
|
|
661
|
+
this.#lateEventCount = 0;
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
this.#runId = advanced.createRunId();
|
|
666
|
+
resetInvocationState(this.#lifecycle, this.#runId);
|
|
667
|
+
this.#clearStepIndexes();
|
|
668
|
+
this.#lateEventCount = 0;
|
|
669
|
+
}
|
|
383
670
|
reset() {
|
|
384
|
-
this.#
|
|
385
|
-
this.#
|
|
386
|
-
this.#
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
this.#activeLcRunIds.clear();
|
|
390
|
-
this.#sawError = false;
|
|
391
|
-
this.#lastErrorMessage = void 0;
|
|
671
|
+
resetInvocationState(this.#lifecycle);
|
|
672
|
+
this.#clearStepIndexes();
|
|
673
|
+
this.#lateEventCount = 0;
|
|
674
|
+
}
|
|
675
|
+
#clearStepIndexes() {
|
|
392
676
|
this.#lcToStepId.clear();
|
|
677
|
+
this.#langGraphIndex.clear();
|
|
678
|
+
this.#semanticLabelIndex.clear();
|
|
679
|
+
this.#syntheticByLabel.clear();
|
|
680
|
+
this.#semanticParentCounts.clear();
|
|
681
|
+
}
|
|
682
|
+
#registerUnique(index, key, stepId) {
|
|
683
|
+
if (!index.has(key)) {
|
|
684
|
+
index.set(key, stepId);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (index.get(key) !== stepId) {
|
|
688
|
+
index.set(key, null);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
#langGraphIndexKey(field, value) {
|
|
692
|
+
return `${field}\0${value}`;
|
|
693
|
+
}
|
|
694
|
+
#registerStepIndexes(stepId, name, attributes) {
|
|
695
|
+
const labels = /* @__PURE__ */ new Set([name]);
|
|
696
|
+
const stripped = name.replace(/^(chain|tool|llm|retriever|agent):/, "");
|
|
697
|
+
if (stripped) labels.add(stripped);
|
|
698
|
+
for (const label of labels) {
|
|
699
|
+
this.#registerUnique(this.#semanticLabelIndex, label, stepId);
|
|
700
|
+
}
|
|
701
|
+
const lg = attributes.langGraph;
|
|
702
|
+
if (typeof lg === "object" && lg !== null && !Array.isArray(lg)) {
|
|
703
|
+
const record = lg;
|
|
704
|
+
for (const field of [
|
|
705
|
+
"taskId",
|
|
706
|
+
"nodeId",
|
|
707
|
+
"nodeName",
|
|
708
|
+
"checkpointNamespace"
|
|
709
|
+
]) {
|
|
710
|
+
const raw = record[field];
|
|
711
|
+
if (typeof raw === "string" && raw.trim()) {
|
|
712
|
+
this.#registerUnique(
|
|
713
|
+
this.#langGraphIndex,
|
|
714
|
+
this.#langGraphIndexKey(field, raw),
|
|
715
|
+
stepId
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
#resolveParent(parentLcRunId, attributes) {
|
|
722
|
+
return resolveParentRelationship(
|
|
723
|
+
{ parentLcRunId, attributes },
|
|
724
|
+
{
|
|
725
|
+
exactStepByLcRunId: (lcRunId) => this.#lcToStepId.get(lcRunId),
|
|
726
|
+
uniqueStepByLangGraphKey: (key, value) => {
|
|
727
|
+
const hit = this.#langGraphIndex.get(this.#langGraphIndexKey(key, value));
|
|
728
|
+
return hit === null || hit === void 0 ? void 0 : hit;
|
|
729
|
+
},
|
|
730
|
+
uniqueStepBySemanticLabel: (label) => {
|
|
731
|
+
const hit = this.#semanticLabelIndex.get(label);
|
|
732
|
+
return hit === null || hit === void 0 ? void 0 : hit;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* When ≥2 steps share the same unresolved semantic parent label, emit one
|
|
739
|
+
* synthetic grouping node and attach this (and later) siblings under it.
|
|
740
|
+
* The first sibling remains unresolved (append-only JSONL cannot rewrite it).
|
|
741
|
+
*/
|
|
742
|
+
async #maybeAttachSyntheticGroup(resolution, startTime) {
|
|
743
|
+
const label = resolution.semanticParentLabel;
|
|
744
|
+
if (resolution.parentMapping !== "unresolved" || !label || resolution.parentStepId) {
|
|
745
|
+
return resolution;
|
|
746
|
+
}
|
|
747
|
+
const existing = this.#syntheticByLabel.get(label);
|
|
748
|
+
if (existing) {
|
|
749
|
+
return {
|
|
750
|
+
parentStepId: existing,
|
|
751
|
+
confidence: "synthetic",
|
|
752
|
+
parentMapping: "synthetic-group",
|
|
753
|
+
semanticParentLabel: label,
|
|
754
|
+
unresolvedParentRunId: label
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
const nextCount = (this.#semanticParentCounts.get(label) ?? 0) + 1;
|
|
758
|
+
this.#semanticParentCounts.set(label, nextCount);
|
|
759
|
+
if (nextCount < 2) {
|
|
760
|
+
return resolution;
|
|
761
|
+
}
|
|
762
|
+
const syntheticStepId = advanced.createStepId();
|
|
763
|
+
this.#syntheticByLabel.set(label, syntheticStepId);
|
|
764
|
+
const metadata = {
|
|
765
|
+
adapter: "langchain",
|
|
766
|
+
confidence: "synthetic",
|
|
767
|
+
synthetic: true,
|
|
768
|
+
parentMapping: "synthetic-group",
|
|
769
|
+
parentConfidence: "synthetic",
|
|
770
|
+
semanticParentLabel: label,
|
|
771
|
+
unresolvedParentRunId: label
|
|
772
|
+
};
|
|
773
|
+
const event = {
|
|
774
|
+
schemaVersion: "0.1",
|
|
775
|
+
event: "step_started",
|
|
776
|
+
timestamp: startTime,
|
|
777
|
+
runId: this.#runId,
|
|
778
|
+
stepId: syntheticStepId,
|
|
779
|
+
name: `synthetic:${label}`,
|
|
780
|
+
type: "logic",
|
|
781
|
+
startTime,
|
|
782
|
+
metadata
|
|
783
|
+
};
|
|
784
|
+
await this.#write(event);
|
|
785
|
+
return {
|
|
786
|
+
parentStepId: syntheticStepId,
|
|
787
|
+
confidence: "synthetic",
|
|
788
|
+
parentMapping: "synthetic-group",
|
|
789
|
+
semanticParentLabel: label,
|
|
790
|
+
unresolvedParentRunId: label
|
|
791
|
+
};
|
|
393
792
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
793
|
+
/** Rotate when a prior standalone invocation already finalized. */
|
|
794
|
+
#prepareForStart() {
|
|
795
|
+
if (this.#standalone && this.#lifecycle.finalized) {
|
|
796
|
+
this.beginNewInvocation();
|
|
397
797
|
}
|
|
398
798
|
}
|
|
799
|
+
/**
|
|
800
|
+
* @deprecated Root-ID heuristics are no longer used for envelope completion.
|
|
801
|
+
* Retained as a no-op for call-site compatibility during the v6.8 train.
|
|
802
|
+
*/
|
|
803
|
+
noteRoot(_lcRunId, _parentRunId) {
|
|
804
|
+
}
|
|
399
805
|
resolveParentId(lcParentRunId) {
|
|
400
806
|
if (!lcParentRunId) return void 0;
|
|
401
807
|
return this.#lcToStepId.get(lcParentRunId);
|
|
402
808
|
}
|
|
403
809
|
async onStepStart(params) {
|
|
404
810
|
try {
|
|
405
|
-
this.#
|
|
406
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
407
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
408
|
-
if (this.#standalone && !this.#runStarted) {
|
|
409
|
-
await this.#ensureRunStarted(params.startTime, params.attributes);
|
|
410
|
-
}
|
|
811
|
+
this.#prepareForStart();
|
|
411
812
|
const stepId = advanced.createStepId();
|
|
412
813
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
814
|
+
this.#registerStepIndexes(stepId, params.name, params.attributes);
|
|
815
|
+
beginCallbackRun(this.#lifecycle, {
|
|
816
|
+
lcRunId: params.lcRunId,
|
|
817
|
+
parentLcRunId: params.lcParentRunId,
|
|
818
|
+
startedAt: params.startTime,
|
|
819
|
+
kind: params.kind,
|
|
820
|
+
stepId
|
|
821
|
+
});
|
|
822
|
+
if (this.#standalone && !this.#lifecycle.envelopeStarted) {
|
|
823
|
+
await this.#ensureRunStarted(params.startTime, params.attributes);
|
|
418
824
|
}
|
|
825
|
+
const resolution = await this.#maybeAttachSyntheticGroup(
|
|
826
|
+
this.#resolveParent(params.lcParentRunId, params.attributes),
|
|
827
|
+
params.startTime
|
|
828
|
+
);
|
|
829
|
+
const metadata = toStepMetadata(params.attributes);
|
|
830
|
+
applyParentResolutionMetadata(metadata, resolution);
|
|
419
831
|
const event = {
|
|
420
832
|
schemaVersion: "0.1",
|
|
421
833
|
event: "step_started",
|
|
422
834
|
timestamp: params.startTime,
|
|
423
835
|
runId: this.#runId,
|
|
424
836
|
stepId,
|
|
425
|
-
...
|
|
837
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
426
838
|
name: params.name,
|
|
427
839
|
type: kindToStepType(params.kind),
|
|
428
840
|
startTime: params.startTime,
|
|
@@ -435,35 +847,58 @@ var LangChainTracePersistence = class {
|
|
|
435
847
|
}
|
|
436
848
|
async onStepEnd(params) {
|
|
437
849
|
try {
|
|
850
|
+
if (this.#lifecycle.finalized && !this.#lifecycle.activeRuns.has(params.lcRunId) && !this.#lcToStepId.has(params.lcRunId)) {
|
|
851
|
+
this.#lateEventCount += 1;
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
438
854
|
let stepId = this.#lcToStepId.get(params.lcRunId);
|
|
439
855
|
if (!stepId && params.completionAttributes) {
|
|
856
|
+
if (this.#lifecycle.finalized) {
|
|
857
|
+
this.#lateEventCount += 1;
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
440
860
|
stepId = advanced.createStepId();
|
|
441
861
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
862
|
+
const synthName = String(params.completionAttributes.name ?? "llm:llm");
|
|
863
|
+
this.#registerStepIndexes(stepId, synthName, params.completionAttributes);
|
|
864
|
+
beginCallbackRun(this.#lifecycle, {
|
|
865
|
+
lcRunId: params.lcRunId,
|
|
866
|
+
parentLcRunId: params.lcParentRunId,
|
|
867
|
+
startedAt: params.endTime - (params.durationMs ?? 0),
|
|
868
|
+
kind: params.completionAttributes.kind ?? "LLM",
|
|
869
|
+
stepId
|
|
870
|
+
});
|
|
448
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
|
+
const metadata = toStepMetadata(params.completionAttributes);
|
|
877
|
+
applyParentResolutionMetadata(metadata, resolution);
|
|
449
878
|
const started = {
|
|
450
879
|
schemaVersion: "0.1",
|
|
451
880
|
event: "step_started",
|
|
452
881
|
timestamp: startTime,
|
|
453
882
|
runId: this.#runId,
|
|
454
883
|
stepId,
|
|
455
|
-
...
|
|
456
|
-
name:
|
|
884
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
885
|
+
name: synthName,
|
|
457
886
|
type: kindToStepType(
|
|
458
887
|
params.completionAttributes.kind ?? "LLM"
|
|
459
888
|
),
|
|
460
889
|
startTime,
|
|
461
890
|
metadata
|
|
462
891
|
};
|
|
892
|
+
if (this.#standalone && !this.#lifecycle.envelopeStarted) {
|
|
893
|
+
await this.#ensureRunStarted(startTime, params.completionAttributes);
|
|
894
|
+
}
|
|
463
895
|
await this.#write(started);
|
|
464
896
|
}
|
|
465
897
|
if (!stepId) return;
|
|
466
|
-
const durationMs = typeof params.durationMs === "number" && Number.isFinite(params.durationMs) ? Math.max(0, Math.floor(params.durationMs)) : Math.max(
|
|
898
|
+
const durationMs = typeof params.durationMs === "number" && Number.isFinite(params.durationMs) ? Math.max(0, Math.floor(params.durationMs)) : Math.max(
|
|
899
|
+
0,
|
|
900
|
+
params.endTime - (this.#lifecycle.runStartTime ?? params.endTime)
|
|
901
|
+
);
|
|
467
902
|
const event = {
|
|
468
903
|
schemaVersion: "0.1",
|
|
469
904
|
event: "step_completed",
|
|
@@ -477,10 +912,12 @@ var LangChainTracePersistence = class {
|
|
|
477
912
|
};
|
|
478
913
|
await this.#write(event);
|
|
479
914
|
if (params.status === "error") {
|
|
480
|
-
|
|
481
|
-
|
|
915
|
+
noteTerminalError(
|
|
916
|
+
this.#lifecycle,
|
|
917
|
+
params.errorMessage ?? "adapter step error"
|
|
918
|
+
);
|
|
482
919
|
}
|
|
483
|
-
this.#
|
|
920
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
484
921
|
await this.#scheduleStandaloneFinalization(params.endTime);
|
|
485
922
|
} catch (err) {
|
|
486
923
|
this.#warn(err);
|
|
@@ -489,27 +926,33 @@ var LangChainTracePersistence = class {
|
|
|
489
926
|
/** Point-in-time adapter events (e.g. agent action) — writes start + completed pair. */
|
|
490
927
|
async onInstantStep(params) {
|
|
491
928
|
try {
|
|
492
|
-
this.#
|
|
493
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
494
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
495
|
-
if (this.#standalone && !this.#runStarted) {
|
|
496
|
-
await this.#ensureRunStarted(params.timestamp, params.attributes);
|
|
497
|
-
}
|
|
929
|
+
this.#prepareForStart();
|
|
498
930
|
const stepId = advanced.createStepId();
|
|
499
931
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
932
|
+
this.#registerStepIndexes(stepId, params.name, params.attributes);
|
|
933
|
+
beginCallbackRun(this.#lifecycle, {
|
|
934
|
+
lcRunId: params.lcRunId,
|
|
935
|
+
parentLcRunId: params.lcParentRunId,
|
|
936
|
+
startedAt: params.timestamp,
|
|
937
|
+
kind: params.kind,
|
|
938
|
+
stepId
|
|
939
|
+
});
|
|
940
|
+
if (this.#standalone && !this.#lifecycle.envelopeStarted) {
|
|
941
|
+
await this.#ensureRunStarted(params.timestamp, params.attributes);
|
|
505
942
|
}
|
|
943
|
+
const resolution = await this.#maybeAttachSyntheticGroup(
|
|
944
|
+
this.#resolveParent(params.lcParentRunId, params.attributes),
|
|
945
|
+
params.timestamp
|
|
946
|
+
);
|
|
947
|
+
const metadata = toStepMetadata(params.attributes);
|
|
948
|
+
applyParentResolutionMetadata(metadata, resolution);
|
|
506
949
|
const started = {
|
|
507
950
|
schemaVersion: "0.1",
|
|
508
951
|
event: "step_started",
|
|
509
952
|
timestamp: params.timestamp,
|
|
510
953
|
runId: this.#runId,
|
|
511
954
|
stepId,
|
|
512
|
-
...
|
|
955
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
513
956
|
name: params.name,
|
|
514
957
|
type: kindToStepType(params.kind),
|
|
515
958
|
startTime: params.timestamp,
|
|
@@ -529,15 +972,71 @@ var LangChainTracePersistence = class {
|
|
|
529
972
|
};
|
|
530
973
|
await this.#write(completed);
|
|
531
974
|
if (params.status === "error") {
|
|
532
|
-
|
|
533
|
-
|
|
975
|
+
noteTerminalError(
|
|
976
|
+
this.#lifecycle,
|
|
977
|
+
params.errorMessage ?? "adapter step error"
|
|
978
|
+
);
|
|
534
979
|
}
|
|
535
|
-
this.#
|
|
980
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
536
981
|
await this.#scheduleStandaloneFinalization(params.timestamp);
|
|
537
982
|
} catch (err) {
|
|
538
983
|
this.#warn(err);
|
|
539
984
|
}
|
|
540
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* Drain deferred microtask finalization. Idempotent; never throws to callers.
|
|
988
|
+
* @experimental
|
|
989
|
+
*/
|
|
990
|
+
async flush() {
|
|
991
|
+
try {
|
|
992
|
+
await Promise.resolve();
|
|
993
|
+
await Promise.resolve();
|
|
994
|
+
} catch (err) {
|
|
995
|
+
this.#warn(err);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Force-complete the standalone envelope when safe/started.
|
|
1000
|
+
* Works even if active callback runs remain (unusual framework shapes / serverless).
|
|
1001
|
+
* Idempotent; never throws to callers.
|
|
1002
|
+
* @experimental
|
|
1003
|
+
*/
|
|
1004
|
+
async finalize(options = {}) {
|
|
1005
|
+
try {
|
|
1006
|
+
if (!this.#standalone) return false;
|
|
1007
|
+
if (this.#lifecycle.finalized) return false;
|
|
1008
|
+
if (!this.#lifecycle.envelopeStarted) return false;
|
|
1009
|
+
bumpCompletionGeneration(this.#lifecycle);
|
|
1010
|
+
const status = options.status ?? (this.#lifecycle.terminalError ? "error" : "success");
|
|
1011
|
+
if (status === "error") {
|
|
1012
|
+
noteTerminalError(
|
|
1013
|
+
this.#lifecycle,
|
|
1014
|
+
options.errorMessage ?? this.#lifecycle.terminalError?.message ?? "adapter finalize error"
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
await this.#ensureRunCompleted(
|
|
1018
|
+
options.endTime ?? Date.now(),
|
|
1019
|
+
status,
|
|
1020
|
+
status === "error" ? options.errorMessage ?? this.#lifecycle.terminalError?.message : void 0
|
|
1021
|
+
);
|
|
1022
|
+
return this.#lifecycle.finalized;
|
|
1023
|
+
} catch (err) {
|
|
1024
|
+
this.#warn(err);
|
|
1025
|
+
return false;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Flush + finalize. Idempotent; never throws to callers.
|
|
1030
|
+
* @experimental
|
|
1031
|
+
*/
|
|
1032
|
+
async close() {
|
|
1033
|
+
try {
|
|
1034
|
+
await this.flush();
|
|
1035
|
+
await this.finalize();
|
|
1036
|
+
} catch (err) {
|
|
1037
|
+
this.#warn(err);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
541
1040
|
/**
|
|
542
1041
|
* When the last active LangChain callback ends, yield one microtask so a
|
|
543
1042
|
* same-turn sibling start can cancel finalization, then write run_completed
|
|
@@ -545,24 +1044,20 @@ var LangChainTracePersistence = class {
|
|
|
545
1044
|
* block the envelope.
|
|
546
1045
|
*/
|
|
547
1046
|
async #scheduleStandaloneFinalization(endTime) {
|
|
548
|
-
if (!this.#standalone ||
|
|
549
|
-
|
|
550
|
-
const token = ++this.#finalizationToken;
|
|
1047
|
+
if (!this.#standalone || !canScheduleFinalize(this.#lifecycle)) return;
|
|
1048
|
+
const generation = this.#lifecycle.completionGeneration;
|
|
551
1049
|
await Promise.resolve();
|
|
552
|
-
if (
|
|
553
|
-
if (!this.#standalone ||
|
|
554
|
-
|
|
555
|
-
const status = this.#sawError ? "error" : "success";
|
|
1050
|
+
if (this.#lifecycle.completionGeneration !== generation) return;
|
|
1051
|
+
if (!this.#standalone || !canScheduleFinalize(this.#lifecycle)) return;
|
|
1052
|
+
const status = this.#lifecycle.terminalError ? "error" : "success";
|
|
556
1053
|
await this.#ensureRunCompleted(
|
|
557
1054
|
endTime,
|
|
558
1055
|
status,
|
|
559
|
-
status === "error" ? this.#
|
|
1056
|
+
status === "error" ? this.#lifecycle.terminalError?.message : void 0
|
|
560
1057
|
);
|
|
561
1058
|
}
|
|
562
1059
|
async #ensureRunStarted(startTime, attrs) {
|
|
563
|
-
if (this.#
|
|
564
|
-
this.#runStarted = true;
|
|
565
|
-
this.#runStartTime = startTime;
|
|
1060
|
+
if (!markEnvelopeStarted(this.#lifecycle, startTime)) return;
|
|
566
1061
|
await advanced.initializeTraceFile(this.#runId, this.#traceDir);
|
|
567
1062
|
const metadata = {
|
|
568
1063
|
adapter: "langchain",
|
|
@@ -582,9 +1077,21 @@ var LangChainTracePersistence = class {
|
|
|
582
1077
|
await this.#write(event);
|
|
583
1078
|
}
|
|
584
1079
|
async #ensureRunCompleted(endTime, stepStatus, errorMessage) {
|
|
585
|
-
if (
|
|
586
|
-
this.#
|
|
587
|
-
|
|
1080
|
+
if (!markFinalized(this.#lifecycle)) return;
|
|
1081
|
+
for (const [, syntheticStepId] of this.#syntheticByLabel) {
|
|
1082
|
+
const completed = {
|
|
1083
|
+
schemaVersion: "0.1",
|
|
1084
|
+
event: "step_completed",
|
|
1085
|
+
timestamp: endTime,
|
|
1086
|
+
runId: this.#runId,
|
|
1087
|
+
stepId: syntheticStepId,
|
|
1088
|
+
status: "success",
|
|
1089
|
+
endTime,
|
|
1090
|
+
durationMs: Math.max(0, endTime - (this.#lifecycle.runStartTime ?? endTime))
|
|
1091
|
+
};
|
|
1092
|
+
await this.#write(completed);
|
|
1093
|
+
}
|
|
1094
|
+
const startTime = this.#lifecycle.runStartTime ?? endTime;
|
|
588
1095
|
const durationMs = Math.max(0, endTime - startTime);
|
|
589
1096
|
const runStatus = stepStatus === "error" ? "error" : "success";
|
|
590
1097
|
const event = {
|
|
@@ -614,20 +1121,11 @@ var LangChainTracePersistence = class {
|
|
|
614
1121
|
function isRecord2(v) {
|
|
615
1122
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
616
1123
|
}
|
|
617
|
-
function
|
|
1124
|
+
function serializedLabel2(s) {
|
|
618
1125
|
if (typeof s.name === "string" && s.name.trim()) return s.name;
|
|
619
1126
|
if (Array.isArray(s.id) && s.id.length > 0) return s.id[s.id.length - 1];
|
|
620
1127
|
return s.type;
|
|
621
1128
|
}
|
|
622
|
-
function resolveToolDisplayName(tool, runName, metadata) {
|
|
623
|
-
const fromRun = typeof runName === "string" ? runName.trim() : "";
|
|
624
|
-
if (fromRun) return fromRun;
|
|
625
|
-
const metaName = metadata?.toolName;
|
|
626
|
-
if (typeof metaName === "string" && metaName.trim()) return metaName.trim();
|
|
627
|
-
const metaTool = metadata?.tool;
|
|
628
|
-
if (typeof metaTool === "string" && metaTool.trim()) return metaTool.trim();
|
|
629
|
-
return serializedLabel(tool) ?? "tool";
|
|
630
|
-
}
|
|
631
1129
|
function errorShape(err) {
|
|
632
1130
|
if (err instanceof Error) {
|
|
633
1131
|
return { errorName: err.name, errorMessage: err.message };
|
|
@@ -636,6 +1134,11 @@ function errorShape(err) {
|
|
|
636
1134
|
}
|
|
637
1135
|
var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
638
1136
|
name = "agent-inspect";
|
|
1137
|
+
/**
|
|
1138
|
+
* Ensure LangGraph/LangChain awaits async handler work (persistence) before
|
|
1139
|
+
* invoke/stream settles. Required for deterministic standalone envelopes.
|
|
1140
|
+
*/
|
|
1141
|
+
awaitHandlers = true;
|
|
639
1142
|
#opts;
|
|
640
1143
|
#redactor;
|
|
641
1144
|
#persistence;
|
|
@@ -646,16 +1149,22 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
646
1149
|
#rootRunId;
|
|
647
1150
|
constructor(options = {}) {
|
|
648
1151
|
super({});
|
|
1152
|
+
const intent = resolvePersistIntent(options);
|
|
649
1153
|
this.#opts = {
|
|
650
1154
|
capture: options.capture ?? "metadata-only",
|
|
651
1155
|
silent: options.silent ?? false,
|
|
652
1156
|
maxPreviewChars: options.maxPreviewChars ?? 200,
|
|
653
|
-
persist: options.persist ?? false,
|
|
654
1157
|
runName: options.runName ?? "langchain-agent",
|
|
655
|
-
...options
|
|
1158
|
+
...options,
|
|
1159
|
+
persist: intent.persist
|
|
656
1160
|
};
|
|
657
1161
|
this.#redactor = new logs.Redactor({ rules: this.#opts.redact });
|
|
658
|
-
if (this.#opts.
|
|
1162
|
+
if (intent.contradictory && !this.#opts.silent) {
|
|
1163
|
+
console.error(
|
|
1164
|
+
"[agent-inspect:langchain] persist:false with traceDir set \u2014 traces stay in-memory; remove traceDir or set persist:true"
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
if (intent.persist) {
|
|
659
1168
|
this.#persistence = new LangChainTracePersistence({
|
|
660
1169
|
runName: this.#opts.runName,
|
|
661
1170
|
traceDir: this.#opts.traceDir,
|
|
@@ -681,6 +1190,91 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
681
1190
|
this.#rootRunId = void 0;
|
|
682
1191
|
this.#persistence?.reset();
|
|
683
1192
|
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Bounded adapter diagnostics for the current invocation (counts only).
|
|
1195
|
+
* Safe for CLI/MCP summaries — no absolute paths or payloads.
|
|
1196
|
+
*
|
|
1197
|
+
* @experimental
|
|
1198
|
+
*/
|
|
1199
|
+
getDiagnostics() {
|
|
1200
|
+
const base = this.#persistence?.getDiagnostics() ?? {
|
|
1201
|
+
lateEventCount: 0,
|
|
1202
|
+
activeRunCount: 0,
|
|
1203
|
+
endedRunCount: 0,
|
|
1204
|
+
pendingRelationshipCount: 0,
|
|
1205
|
+
knownRelationshipCount: 0,
|
|
1206
|
+
syntheticGroupCount: 0,
|
|
1207
|
+
envelopeStarted: false,
|
|
1208
|
+
finalized: false,
|
|
1209
|
+
completionGeneration: 0,
|
|
1210
|
+
hasTerminalError: false
|
|
1211
|
+
};
|
|
1212
|
+
return {
|
|
1213
|
+
...base,
|
|
1214
|
+
inMemoryEventCount: this.#events.length,
|
|
1215
|
+
deferredPersistStartCount: this.#deferredPersistStart.size
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Drain deferred completion work (microtask finalization).
|
|
1220
|
+
* Idempotent. Failures are isolated and never thrown to user code.
|
|
1221
|
+
*
|
|
1222
|
+
* @experimental Additive finalization API for serverless / unusual callback shapes.
|
|
1223
|
+
*/
|
|
1224
|
+
async flush() {
|
|
1225
|
+
try {
|
|
1226
|
+
await this.#persistence?.flush();
|
|
1227
|
+
} catch (err) {
|
|
1228
|
+
if (!this.#opts.silent) {
|
|
1229
|
+
console.error("[agent-inspect:langchain]", err);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Complete the standalone envelope when started. Fallback when automatic
|
|
1235
|
+
* completion cannot run (e.g. process shutdown). Idempotent.
|
|
1236
|
+
* Failures are isolated and never thrown to user code.
|
|
1237
|
+
*
|
|
1238
|
+
* @experimental Additive finalization API for serverless / unusual callback shapes.
|
|
1239
|
+
*/
|
|
1240
|
+
async finalize(options) {
|
|
1241
|
+
try {
|
|
1242
|
+
await this.#persistence?.finalize(options);
|
|
1243
|
+
} catch (err) {
|
|
1244
|
+
if (!this.#opts.silent) {
|
|
1245
|
+
console.error("[agent-inspect:langchain]", err);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* `flush()` then `finalize()`. Idempotent. Failures are isolated.
|
|
1251
|
+
*
|
|
1252
|
+
* @experimental Additive finalization API for serverless / unusual callback shapes.
|
|
1253
|
+
*/
|
|
1254
|
+
async close() {
|
|
1255
|
+
try {
|
|
1256
|
+
await this.flush();
|
|
1257
|
+
await this.finalize();
|
|
1258
|
+
} catch (err) {
|
|
1259
|
+
if (!this.#opts.silent) {
|
|
1260
|
+
console.error("[agent-inspect:langchain]", err);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* When persist mode has already finalized an envelope, rotate to a new
|
|
1266
|
+
* invocation before the next start so reused handlers do not mix runs.
|
|
1267
|
+
*/
|
|
1268
|
+
#prepareCallbackInvocation() {
|
|
1269
|
+
const persistence = this.#persistence;
|
|
1270
|
+
if (!persistence?.lifecycle.finalized) return;
|
|
1271
|
+
this.#events = [];
|
|
1272
|
+
this.#starts.clear();
|
|
1273
|
+
this.#streamState.clear();
|
|
1274
|
+
this.#deferredPersistStart.clear();
|
|
1275
|
+
this.#rootRunId = void 0;
|
|
1276
|
+
persistence.beginNewInvocation();
|
|
1277
|
+
}
|
|
684
1278
|
#streamPreviewLimit() {
|
|
685
1279
|
if (this.#opts.capture !== "preview") return 0;
|
|
686
1280
|
return this.#opts.maxStreamPreviewChars ?? this.#opts.maxPreviewChars ?? 200;
|
|
@@ -842,9 +1436,10 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
842
1436
|
});
|
|
843
1437
|
}
|
|
844
1438
|
async handleChainStart(chain, inputs, runId, runType, tags, metadata, runName, parentRunId, _extra) {
|
|
1439
|
+
this.#prepareCallbackInvocation();
|
|
845
1440
|
this.#ensureRoot(runId, parentRunId);
|
|
846
1441
|
this.#rememberStart(runId, "CHAIN");
|
|
847
|
-
const label =
|
|
1442
|
+
const label = serializedLabel2(chain) ?? "chain";
|
|
848
1443
|
const previews = {};
|
|
849
1444
|
if (this.#opts.capture === "preview") previews.inputPreview = inputs;
|
|
850
1445
|
const attrs = {
|
|
@@ -923,6 +1518,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
923
1518
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
924
1519
|
}
|
|
925
1520
|
async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1521
|
+
this.#prepareCallbackInvocation();
|
|
926
1522
|
this.#ensureRoot(runId, parentRunId);
|
|
927
1523
|
this.#rememberStart(runId, "LLM");
|
|
928
1524
|
const model = extractModelName(llm);
|
|
@@ -955,6 +1551,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
955
1551
|
await this.#persistLlmStepStart(runId, parentRunId, stepName, "LLM", ts, attrs);
|
|
956
1552
|
}
|
|
957
1553
|
async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1554
|
+
this.#prepareCallbackInvocation();
|
|
958
1555
|
this.#ensureRoot(runId, parentRunId);
|
|
959
1556
|
this.#rememberStart(runId, "LLM");
|
|
960
1557
|
const model = extractModelName(llm);
|
|
@@ -1073,21 +1670,22 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1073
1670
|
});
|
|
1074
1671
|
this.#clearStreamState(runId);
|
|
1075
1672
|
}
|
|
1076
|
-
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName,
|
|
1673
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
|
|
1674
|
+
this.#prepareCallbackInvocation();
|
|
1077
1675
|
this.#ensureRoot(runId, parentRunId);
|
|
1078
1676
|
this.#rememberStart(runId, "TOOL");
|
|
1079
|
-
const
|
|
1677
|
+
const identity = resolveToolIdentity(tool, runName, metadata, toolCallId);
|
|
1080
1678
|
const previews = {};
|
|
1081
1679
|
if (this.#opts.capture === "preview") previews.inputPreview = input;
|
|
1082
1680
|
const attrs = {
|
|
1083
|
-
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1084
|
-
tool: toolName
|
|
1681
|
+
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1085
1682
|
};
|
|
1683
|
+
applyToolIdentityAttributes(attrs, identity);
|
|
1086
1684
|
this.#mergeMetadata(attrs, metadata);
|
|
1087
1685
|
this.#applyPreview(attrs, previews);
|
|
1088
1686
|
this.#rememberStartMetadata(runId, attrs);
|
|
1089
1687
|
const ts = Date.now();
|
|
1090
|
-
const stepName = `tool:${
|
|
1688
|
+
const stepName = `tool:${identity.displayName}`;
|
|
1091
1689
|
this.#pushEvent({
|
|
1092
1690
|
eventId: `${runId}:TOOL:start`,
|
|
1093
1691
|
runId: this.#traceRunId(runId),
|
|
@@ -1157,9 +1755,10 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1157
1755
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1158
1756
|
}
|
|
1159
1757
|
async handleRetrieverStart(retriever, _query, runId, parentRunId, tags, metadata, name) {
|
|
1758
|
+
this.#prepareCallbackInvocation();
|
|
1160
1759
|
this.#ensureRoot(runId, parentRunId);
|
|
1161
1760
|
this.#rememberStart(runId, "RETRIEVER");
|
|
1162
|
-
const rname = name ??
|
|
1761
|
+
const rname = name ?? serializedLabel2(retriever) ?? "retriever";
|
|
1163
1762
|
const attrs = {
|
|
1164
1763
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|
|
1165
1764
|
retriever: rname
|
|
@@ -1240,6 +1839,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1240
1839
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1241
1840
|
}
|
|
1242
1841
|
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
1842
|
+
this.#prepareCallbackInvocation();
|
|
1243
1843
|
this.#ensureRoot(runId, parentRunId);
|
|
1244
1844
|
const attrs = {
|
|
1245
1845
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|