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