@agent-inspect/langchain 6.7.4 → 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 +704 -95
- 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 +700 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var path = require('path');
|
|
3
4
|
var base = require('@langchain/core/callbacks/base');
|
|
4
5
|
var advanced = require('agent-inspect/advanced');
|
|
5
6
|
var logs = require('agent-inspect/logs');
|
|
6
7
|
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
11
|
+
|
|
7
12
|
// packages/langchain/src/agent-inspect-callback.ts
|
|
8
13
|
|
|
9
14
|
// packages/langchain/src/metadata.ts
|
|
@@ -318,6 +323,247 @@ function streamMetadataFromState(state, options) {
|
|
|
318
323
|
}
|
|
319
324
|
return out;
|
|
320
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
|
|
321
567
|
function kindToStepType(kind) {
|
|
322
568
|
switch (kind) {
|
|
323
569
|
case "LLM":
|
|
@@ -347,27 +593,30 @@ var LangChainTracePersistence = class {
|
|
|
347
593
|
#standalone;
|
|
348
594
|
#silent;
|
|
349
595
|
#safety;
|
|
350
|
-
#
|
|
351
|
-
#runCompleted = false;
|
|
352
|
-
#runStartTime;
|
|
353
|
-
#rootLcRunId;
|
|
354
|
-
/** Live LangChain callback runIds for standalone envelope finalization. */
|
|
355
|
-
#activeLcRunIds = /* @__PURE__ */ new Set();
|
|
356
|
-
#sawError = false;
|
|
357
|
-
#lastErrorMessage;
|
|
358
|
-
#finalizationToken = 0;
|
|
596
|
+
#lifecycle;
|
|
359
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;
|
|
360
607
|
constructor(options = {}) {
|
|
361
608
|
const inContext = advanced.hasActiveContext();
|
|
362
609
|
this.#standalone = !inContext;
|
|
363
610
|
this.#silent = options.silent ?? false;
|
|
364
611
|
this.#traceDir = inContext ? advanced.getTraceDirFromContext() ?? advanced.resolveTraceDir({ dir: options.traceDir }) : advanced.resolveTraceDir({ dir: options.traceDir });
|
|
365
|
-
|
|
612
|
+
const contextRunId = inContext ? advanced.getCurrentRunId() : void 0;
|
|
613
|
+
this.#runId = contextRunId ?? options.runId ?? advanced.createRunId();
|
|
366
614
|
this.#runName = options.runName ?? "langchain-agent";
|
|
367
615
|
this.#safety = advanced.resolveTraceSafetyOptions({
|
|
368
616
|
redact: options.redact ? { rules: options.redact } : true,
|
|
369
617
|
maxPreviewLength: options.maxPreviewChars
|
|
370
618
|
});
|
|
619
|
+
this.#lifecycle = createInvocationState(this.#runId);
|
|
371
620
|
}
|
|
372
621
|
get runId() {
|
|
373
622
|
return this.#runId;
|
|
@@ -375,21 +624,183 @@ var LangChainTracePersistence = class {
|
|
|
375
624
|
get traceDir() {
|
|
376
625
|
return this.#traceDir;
|
|
377
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
|
+
}
|
|
378
670
|
reset() {
|
|
379
|
-
this.#
|
|
380
|
-
this.#
|
|
381
|
-
this.#
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
this.#activeLcRunIds.clear();
|
|
385
|
-
this.#sawError = false;
|
|
386
|
-
this.#lastErrorMessage = void 0;
|
|
671
|
+
resetInvocationState(this.#lifecycle);
|
|
672
|
+
this.#clearStepIndexes();
|
|
673
|
+
this.#lateEventCount = 0;
|
|
674
|
+
}
|
|
675
|
+
#clearStepIndexes() {
|
|
387
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}`;
|
|
388
693
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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);
|
|
392
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
|
+
};
|
|
792
|
+
}
|
|
793
|
+
/** Rotate when a prior standalone invocation already finalized. */
|
|
794
|
+
#prepareForStart() {
|
|
795
|
+
if (this.#standalone && this.#lifecycle.finalized) {
|
|
796
|
+
this.beginNewInvocation();
|
|
797
|
+
}
|
|
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) {
|
|
393
804
|
}
|
|
394
805
|
resolveParentId(lcParentRunId) {
|
|
395
806
|
if (!lcParentRunId) return void 0;
|
|
@@ -397,27 +808,33 @@ var LangChainTracePersistence = class {
|
|
|
397
808
|
}
|
|
398
809
|
async onStepStart(params) {
|
|
399
810
|
try {
|
|
400
|
-
this.#
|
|
401
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
402
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
403
|
-
if (this.#standalone && !this.#runStarted) {
|
|
404
|
-
await this.#ensureRunStarted(params.startTime, params.attributes);
|
|
405
|
-
}
|
|
811
|
+
this.#prepareForStart();
|
|
406
812
|
const stepId = advanced.createStepId();
|
|
407
813
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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);
|
|
413
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);
|
|
414
831
|
const event = {
|
|
415
832
|
schemaVersion: "0.1",
|
|
416
833
|
event: "step_started",
|
|
417
834
|
timestamp: params.startTime,
|
|
418
835
|
runId: this.#runId,
|
|
419
836
|
stepId,
|
|
420
|
-
...
|
|
837
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
421
838
|
name: params.name,
|
|
422
839
|
type: kindToStepType(params.kind),
|
|
423
840
|
startTime: params.startTime,
|
|
@@ -430,35 +847,58 @@ var LangChainTracePersistence = class {
|
|
|
430
847
|
}
|
|
431
848
|
async onStepEnd(params) {
|
|
432
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
|
+
}
|
|
433
854
|
let stepId = this.#lcToStepId.get(params.lcRunId);
|
|
434
855
|
if (!stepId && params.completionAttributes) {
|
|
856
|
+
if (this.#lifecycle.finalized) {
|
|
857
|
+
this.#lateEventCount += 1;
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
435
860
|
stepId = advanced.createStepId();
|
|
436
861
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
+
});
|
|
443
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);
|
|
444
878
|
const started = {
|
|
445
879
|
schemaVersion: "0.1",
|
|
446
880
|
event: "step_started",
|
|
447
881
|
timestamp: startTime,
|
|
448
882
|
runId: this.#runId,
|
|
449
883
|
stepId,
|
|
450
|
-
...
|
|
451
|
-
name:
|
|
884
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
885
|
+
name: synthName,
|
|
452
886
|
type: kindToStepType(
|
|
453
887
|
params.completionAttributes.kind ?? "LLM"
|
|
454
888
|
),
|
|
455
889
|
startTime,
|
|
456
890
|
metadata
|
|
457
891
|
};
|
|
892
|
+
if (this.#standalone && !this.#lifecycle.envelopeStarted) {
|
|
893
|
+
await this.#ensureRunStarted(startTime, params.completionAttributes);
|
|
894
|
+
}
|
|
458
895
|
await this.#write(started);
|
|
459
896
|
}
|
|
460
897
|
if (!stepId) return;
|
|
461
|
-
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
|
+
);
|
|
462
902
|
const event = {
|
|
463
903
|
schemaVersion: "0.1",
|
|
464
904
|
event: "step_completed",
|
|
@@ -472,10 +912,12 @@ var LangChainTracePersistence = class {
|
|
|
472
912
|
};
|
|
473
913
|
await this.#write(event);
|
|
474
914
|
if (params.status === "error") {
|
|
475
|
-
|
|
476
|
-
|
|
915
|
+
noteTerminalError(
|
|
916
|
+
this.#lifecycle,
|
|
917
|
+
params.errorMessage ?? "adapter step error"
|
|
918
|
+
);
|
|
477
919
|
}
|
|
478
|
-
this.#
|
|
920
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
479
921
|
await this.#scheduleStandaloneFinalization(params.endTime);
|
|
480
922
|
} catch (err) {
|
|
481
923
|
this.#warn(err);
|
|
@@ -484,27 +926,33 @@ var LangChainTracePersistence = class {
|
|
|
484
926
|
/** Point-in-time adapter events (e.g. agent action) — writes start + completed pair. */
|
|
485
927
|
async onInstantStep(params) {
|
|
486
928
|
try {
|
|
487
|
-
this.#
|
|
488
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
489
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
490
|
-
if (this.#standalone && !this.#runStarted) {
|
|
491
|
-
await this.#ensureRunStarted(params.timestamp, params.attributes);
|
|
492
|
-
}
|
|
929
|
+
this.#prepareForStart();
|
|
493
930
|
const stepId = advanced.createStepId();
|
|
494
931
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
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);
|
|
500
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);
|
|
501
949
|
const started = {
|
|
502
950
|
schemaVersion: "0.1",
|
|
503
951
|
event: "step_started",
|
|
504
952
|
timestamp: params.timestamp,
|
|
505
953
|
runId: this.#runId,
|
|
506
954
|
stepId,
|
|
507
|
-
...
|
|
955
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
508
956
|
name: params.name,
|
|
509
957
|
type: kindToStepType(params.kind),
|
|
510
958
|
startTime: params.timestamp,
|
|
@@ -524,15 +972,71 @@ var LangChainTracePersistence = class {
|
|
|
524
972
|
};
|
|
525
973
|
await this.#write(completed);
|
|
526
974
|
if (params.status === "error") {
|
|
527
|
-
|
|
528
|
-
|
|
975
|
+
noteTerminalError(
|
|
976
|
+
this.#lifecycle,
|
|
977
|
+
params.errorMessage ?? "adapter step error"
|
|
978
|
+
);
|
|
529
979
|
}
|
|
530
|
-
this.#
|
|
980
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
531
981
|
await this.#scheduleStandaloneFinalization(params.timestamp);
|
|
532
982
|
} catch (err) {
|
|
533
983
|
this.#warn(err);
|
|
534
984
|
}
|
|
535
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
|
+
}
|
|
536
1040
|
/**
|
|
537
1041
|
* When the last active LangChain callback ends, yield one microtask so a
|
|
538
1042
|
* same-turn sibling start can cancel finalization, then write run_completed
|
|
@@ -540,24 +1044,20 @@ var LangChainTracePersistence = class {
|
|
|
540
1044
|
* block the envelope.
|
|
541
1045
|
*/
|
|
542
1046
|
async #scheduleStandaloneFinalization(endTime) {
|
|
543
|
-
if (!this.#standalone ||
|
|
544
|
-
|
|
545
|
-
const token = ++this.#finalizationToken;
|
|
1047
|
+
if (!this.#standalone || !canScheduleFinalize(this.#lifecycle)) return;
|
|
1048
|
+
const generation = this.#lifecycle.completionGeneration;
|
|
546
1049
|
await Promise.resolve();
|
|
547
|
-
if (
|
|
548
|
-
if (!this.#standalone ||
|
|
549
|
-
|
|
550
|
-
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";
|
|
551
1053
|
await this.#ensureRunCompleted(
|
|
552
1054
|
endTime,
|
|
553
1055
|
status,
|
|
554
|
-
status === "error" ? this.#
|
|
1056
|
+
status === "error" ? this.#lifecycle.terminalError?.message : void 0
|
|
555
1057
|
);
|
|
556
1058
|
}
|
|
557
1059
|
async #ensureRunStarted(startTime, attrs) {
|
|
558
|
-
if (this.#
|
|
559
|
-
this.#runStarted = true;
|
|
560
|
-
this.#runStartTime = startTime;
|
|
1060
|
+
if (!markEnvelopeStarted(this.#lifecycle, startTime)) return;
|
|
561
1061
|
await advanced.initializeTraceFile(this.#runId, this.#traceDir);
|
|
562
1062
|
const metadata = {
|
|
563
1063
|
adapter: "langchain",
|
|
@@ -577,9 +1077,21 @@ var LangChainTracePersistence = class {
|
|
|
577
1077
|
await this.#write(event);
|
|
578
1078
|
}
|
|
579
1079
|
async #ensureRunCompleted(endTime, stepStatus, errorMessage) {
|
|
580
|
-
if (
|
|
581
|
-
this.#
|
|
582
|
-
|
|
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;
|
|
583
1095
|
const durationMs = Math.max(0, endTime - startTime);
|
|
584
1096
|
const runStatus = stepStatus === "error" ? "error" : "success";
|
|
585
1097
|
const event = {
|
|
@@ -609,20 +1121,11 @@ var LangChainTracePersistence = class {
|
|
|
609
1121
|
function isRecord2(v) {
|
|
610
1122
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
611
1123
|
}
|
|
612
|
-
function
|
|
1124
|
+
function serializedLabel2(s) {
|
|
613
1125
|
if (typeof s.name === "string" && s.name.trim()) return s.name;
|
|
614
1126
|
if (Array.isArray(s.id) && s.id.length > 0) return s.id[s.id.length - 1];
|
|
615
1127
|
return s.type;
|
|
616
1128
|
}
|
|
617
|
-
function resolveToolDisplayName(tool, runName, metadata) {
|
|
618
|
-
const fromRun = typeof runName === "string" ? runName.trim() : "";
|
|
619
|
-
if (fromRun) return fromRun;
|
|
620
|
-
const metaName = metadata?.toolName;
|
|
621
|
-
if (typeof metaName === "string" && metaName.trim()) return metaName.trim();
|
|
622
|
-
const metaTool = metadata?.tool;
|
|
623
|
-
if (typeof metaTool === "string" && metaTool.trim()) return metaTool.trim();
|
|
624
|
-
return serializedLabel(tool) ?? "tool";
|
|
625
|
-
}
|
|
626
1129
|
function errorShape(err) {
|
|
627
1130
|
if (err instanceof Error) {
|
|
628
1131
|
return { errorName: err.name, errorMessage: err.message };
|
|
@@ -631,6 +1134,11 @@ function errorShape(err) {
|
|
|
631
1134
|
}
|
|
632
1135
|
var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
633
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;
|
|
634
1142
|
#opts;
|
|
635
1143
|
#redactor;
|
|
636
1144
|
#persistence;
|
|
@@ -641,16 +1149,22 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
641
1149
|
#rootRunId;
|
|
642
1150
|
constructor(options = {}) {
|
|
643
1151
|
super({});
|
|
1152
|
+
const intent = resolvePersistIntent(options);
|
|
644
1153
|
this.#opts = {
|
|
645
1154
|
capture: options.capture ?? "metadata-only",
|
|
646
1155
|
silent: options.silent ?? false,
|
|
647
1156
|
maxPreviewChars: options.maxPreviewChars ?? 200,
|
|
648
|
-
persist: options.persist ?? false,
|
|
649
1157
|
runName: options.runName ?? "langchain-agent",
|
|
650
|
-
...options
|
|
1158
|
+
...options,
|
|
1159
|
+
persist: intent.persist
|
|
651
1160
|
};
|
|
652
1161
|
this.#redactor = new logs.Redactor({ rules: this.#opts.redact });
|
|
653
|
-
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) {
|
|
654
1168
|
this.#persistence = new LangChainTracePersistence({
|
|
655
1169
|
runName: this.#opts.runName,
|
|
656
1170
|
traceDir: this.#opts.traceDir,
|
|
@@ -676,6 +1190,91 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
676
1190
|
this.#rootRunId = void 0;
|
|
677
1191
|
this.#persistence?.reset();
|
|
678
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
|
+
}
|
|
679
1278
|
#streamPreviewLimit() {
|
|
680
1279
|
if (this.#opts.capture !== "preview") return 0;
|
|
681
1280
|
return this.#opts.maxStreamPreviewChars ?? this.#opts.maxPreviewChars ?? 200;
|
|
@@ -770,7 +1369,11 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
770
1369
|
if (parentRunId) out.parentRunId = parentRunId;
|
|
771
1370
|
if (this.#opts.runName) out.adapterRunName = this.#opts.runName;
|
|
772
1371
|
if (runNameArg) out.runName = runNameArg;
|
|
773
|
-
if (this.#opts.
|
|
1372
|
+
if (this.#opts.persist) out.traceStorage = "local";
|
|
1373
|
+
const configuredTraceDir = this.#opts.traceDir?.trim();
|
|
1374
|
+
if (configuredTraceDir && !path__default.default.isAbsolute(configuredTraceDir) && !/^[A-Za-z]:[\\/]/.test(configuredTraceDir)) {
|
|
1375
|
+
out.workspaceRelativeTraceDir = configuredTraceDir;
|
|
1376
|
+
}
|
|
774
1377
|
const cap = this.#opts.capture;
|
|
775
1378
|
if (cap !== "none" && tags?.length) out.tags = [...tags];
|
|
776
1379
|
return out;
|
|
@@ -833,9 +1436,10 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
833
1436
|
});
|
|
834
1437
|
}
|
|
835
1438
|
async handleChainStart(chain, inputs, runId, runType, tags, metadata, runName, parentRunId, _extra) {
|
|
1439
|
+
this.#prepareCallbackInvocation();
|
|
836
1440
|
this.#ensureRoot(runId, parentRunId);
|
|
837
1441
|
this.#rememberStart(runId, "CHAIN");
|
|
838
|
-
const label =
|
|
1442
|
+
const label = serializedLabel2(chain) ?? "chain";
|
|
839
1443
|
const previews = {};
|
|
840
1444
|
if (this.#opts.capture === "preview") previews.inputPreview = inputs;
|
|
841
1445
|
const attrs = {
|
|
@@ -914,6 +1518,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
914
1518
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
915
1519
|
}
|
|
916
1520
|
async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1521
|
+
this.#prepareCallbackInvocation();
|
|
917
1522
|
this.#ensureRoot(runId, parentRunId);
|
|
918
1523
|
this.#rememberStart(runId, "LLM");
|
|
919
1524
|
const model = extractModelName(llm);
|
|
@@ -946,6 +1551,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
946
1551
|
await this.#persistLlmStepStart(runId, parentRunId, stepName, "LLM", ts, attrs);
|
|
947
1552
|
}
|
|
948
1553
|
async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1554
|
+
this.#prepareCallbackInvocation();
|
|
949
1555
|
this.#ensureRoot(runId, parentRunId);
|
|
950
1556
|
this.#rememberStart(runId, "LLM");
|
|
951
1557
|
const model = extractModelName(llm);
|
|
@@ -1064,21 +1670,22 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1064
1670
|
});
|
|
1065
1671
|
this.#clearStreamState(runId);
|
|
1066
1672
|
}
|
|
1067
|
-
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName,
|
|
1673
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
|
|
1674
|
+
this.#prepareCallbackInvocation();
|
|
1068
1675
|
this.#ensureRoot(runId, parentRunId);
|
|
1069
1676
|
this.#rememberStart(runId, "TOOL");
|
|
1070
|
-
const
|
|
1677
|
+
const identity = resolveToolIdentity(tool, runName, metadata, toolCallId);
|
|
1071
1678
|
const previews = {};
|
|
1072
1679
|
if (this.#opts.capture === "preview") previews.inputPreview = input;
|
|
1073
1680
|
const attrs = {
|
|
1074
|
-
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1075
|
-
tool: toolName
|
|
1681
|
+
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1076
1682
|
};
|
|
1683
|
+
applyToolIdentityAttributes(attrs, identity);
|
|
1077
1684
|
this.#mergeMetadata(attrs, metadata);
|
|
1078
1685
|
this.#applyPreview(attrs, previews);
|
|
1079
1686
|
this.#rememberStartMetadata(runId, attrs);
|
|
1080
1687
|
const ts = Date.now();
|
|
1081
|
-
const stepName = `tool:${
|
|
1688
|
+
const stepName = `tool:${identity.displayName}`;
|
|
1082
1689
|
this.#pushEvent({
|
|
1083
1690
|
eventId: `${runId}:TOOL:start`,
|
|
1084
1691
|
runId: this.#traceRunId(runId),
|
|
@@ -1148,9 +1755,10 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1148
1755
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1149
1756
|
}
|
|
1150
1757
|
async handleRetrieverStart(retriever, _query, runId, parentRunId, tags, metadata, name) {
|
|
1758
|
+
this.#prepareCallbackInvocation();
|
|
1151
1759
|
this.#ensureRoot(runId, parentRunId);
|
|
1152
1760
|
this.#rememberStart(runId, "RETRIEVER");
|
|
1153
|
-
const rname = name ??
|
|
1761
|
+
const rname = name ?? serializedLabel2(retriever) ?? "retriever";
|
|
1154
1762
|
const attrs = {
|
|
1155
1763
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|
|
1156
1764
|
retriever: rname
|
|
@@ -1231,6 +1839,7 @@ var AgentInspectCallback = class extends base.BaseCallbackHandler {
|
|
|
1231
1839
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1232
1840
|
}
|
|
1233
1841
|
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
1842
|
+
this.#prepareCallbackInvocation();
|
|
1234
1843
|
this.#ensureRoot(runId, parentRunId);
|
|
1235
1844
|
const attrs = {
|
|
1236
1845
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|