@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.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'path';
|
|
1
2
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
3
|
import { getCurrentCorrelationMetadata, hasActiveContext, getTraceDirFromContext, resolveTraceDir, getCurrentRunId, createRunId, resolveTraceSafetyOptions, createStepId, initializeTraceFile, prepareTraceEventForDisk, writeTraceEvent } from 'agent-inspect/advanced';
|
|
3
4
|
import { Redactor } from 'agent-inspect/logs';
|
|
@@ -316,6 +317,247 @@ function streamMetadataFromState(state, options) {
|
|
|
316
317
|
}
|
|
317
318
|
return out;
|
|
318
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
|
|
319
561
|
function kindToStepType(kind) {
|
|
320
562
|
switch (kind) {
|
|
321
563
|
case "LLM":
|
|
@@ -345,27 +587,30 @@ var LangChainTracePersistence = class {
|
|
|
345
587
|
#standalone;
|
|
346
588
|
#silent;
|
|
347
589
|
#safety;
|
|
348
|
-
#
|
|
349
|
-
#runCompleted = false;
|
|
350
|
-
#runStartTime;
|
|
351
|
-
#rootLcRunId;
|
|
352
|
-
/** Live LangChain callback runIds for standalone envelope finalization. */
|
|
353
|
-
#activeLcRunIds = /* @__PURE__ */ new Set();
|
|
354
|
-
#sawError = false;
|
|
355
|
-
#lastErrorMessage;
|
|
356
|
-
#finalizationToken = 0;
|
|
590
|
+
#lifecycle;
|
|
357
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;
|
|
358
601
|
constructor(options = {}) {
|
|
359
602
|
const inContext = hasActiveContext();
|
|
360
603
|
this.#standalone = !inContext;
|
|
361
604
|
this.#silent = options.silent ?? false;
|
|
362
605
|
this.#traceDir = inContext ? getTraceDirFromContext() ?? resolveTraceDir({ dir: options.traceDir }) : resolveTraceDir({ dir: options.traceDir });
|
|
363
|
-
|
|
606
|
+
const contextRunId = inContext ? getCurrentRunId() : void 0;
|
|
607
|
+
this.#runId = contextRunId ?? options.runId ?? createRunId();
|
|
364
608
|
this.#runName = options.runName ?? "langchain-agent";
|
|
365
609
|
this.#safety = resolveTraceSafetyOptions({
|
|
366
610
|
redact: options.redact ? { rules: options.redact } : true,
|
|
367
611
|
maxPreviewLength: options.maxPreviewChars
|
|
368
612
|
});
|
|
613
|
+
this.#lifecycle = createInvocationState(this.#runId);
|
|
369
614
|
}
|
|
370
615
|
get runId() {
|
|
371
616
|
return this.#runId;
|
|
@@ -373,49 +618,217 @@ var LangChainTracePersistence = class {
|
|
|
373
618
|
get traceDir() {
|
|
374
619
|
return this.#traceDir;
|
|
375
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
|
+
}
|
|
376
664
|
reset() {
|
|
377
|
-
this.#
|
|
378
|
-
this.#
|
|
379
|
-
this.#
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
this.#activeLcRunIds.clear();
|
|
383
|
-
this.#sawError = false;
|
|
384
|
-
this.#lastErrorMessage = void 0;
|
|
665
|
+
resetInvocationState(this.#lifecycle);
|
|
666
|
+
this.#clearStepIndexes();
|
|
667
|
+
this.#lateEventCount = 0;
|
|
668
|
+
}
|
|
669
|
+
#clearStepIndexes() {
|
|
385
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}`;
|
|
386
687
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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
|
+
}
|
|
390
713
|
}
|
|
391
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
|
+
};
|
|
786
|
+
}
|
|
787
|
+
/** Rotate when a prior standalone invocation already finalized. */
|
|
788
|
+
#prepareForStart() {
|
|
789
|
+
if (this.#standalone && this.#lifecycle.finalized) {
|
|
790
|
+
this.beginNewInvocation();
|
|
791
|
+
}
|
|
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
|
+
}
|
|
392
799
|
resolveParentId(lcParentRunId) {
|
|
393
800
|
if (!lcParentRunId) return void 0;
|
|
394
801
|
return this.#lcToStepId.get(lcParentRunId);
|
|
395
802
|
}
|
|
396
803
|
async onStepStart(params) {
|
|
397
804
|
try {
|
|
398
|
-
this.#
|
|
399
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
400
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
401
|
-
if (this.#standalone && !this.#runStarted) {
|
|
402
|
-
await this.#ensureRunStarted(params.startTime, params.attributes);
|
|
403
|
-
}
|
|
805
|
+
this.#prepareForStart();
|
|
404
806
|
const stepId = createStepId();
|
|
405
807
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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);
|
|
411
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);
|
|
412
825
|
const event = {
|
|
413
826
|
schemaVersion: "0.1",
|
|
414
827
|
event: "step_started",
|
|
415
828
|
timestamp: params.startTime,
|
|
416
829
|
runId: this.#runId,
|
|
417
830
|
stepId,
|
|
418
|
-
...
|
|
831
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
419
832
|
name: params.name,
|
|
420
833
|
type: kindToStepType(params.kind),
|
|
421
834
|
startTime: params.startTime,
|
|
@@ -428,35 +841,58 @@ var LangChainTracePersistence = class {
|
|
|
428
841
|
}
|
|
429
842
|
async onStepEnd(params) {
|
|
430
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
|
+
}
|
|
431
848
|
let stepId = this.#lcToStepId.get(params.lcRunId);
|
|
432
849
|
if (!stepId && params.completionAttributes) {
|
|
850
|
+
if (this.#lifecycle.finalized) {
|
|
851
|
+
this.#lateEventCount += 1;
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
433
854
|
stepId = createStepId();
|
|
434
855
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
+
});
|
|
441
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);
|
|
442
872
|
const started = {
|
|
443
873
|
schemaVersion: "0.1",
|
|
444
874
|
event: "step_started",
|
|
445
875
|
timestamp: startTime,
|
|
446
876
|
runId: this.#runId,
|
|
447
877
|
stepId,
|
|
448
|
-
...
|
|
449
|
-
name:
|
|
878
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
879
|
+
name: synthName,
|
|
450
880
|
type: kindToStepType(
|
|
451
881
|
params.completionAttributes.kind ?? "LLM"
|
|
452
882
|
),
|
|
453
883
|
startTime,
|
|
454
884
|
metadata
|
|
455
885
|
};
|
|
886
|
+
if (this.#standalone && !this.#lifecycle.envelopeStarted) {
|
|
887
|
+
await this.#ensureRunStarted(startTime, params.completionAttributes);
|
|
888
|
+
}
|
|
456
889
|
await this.#write(started);
|
|
457
890
|
}
|
|
458
891
|
if (!stepId) return;
|
|
459
|
-
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
|
+
);
|
|
460
896
|
const event = {
|
|
461
897
|
schemaVersion: "0.1",
|
|
462
898
|
event: "step_completed",
|
|
@@ -470,10 +906,12 @@ var LangChainTracePersistence = class {
|
|
|
470
906
|
};
|
|
471
907
|
await this.#write(event);
|
|
472
908
|
if (params.status === "error") {
|
|
473
|
-
|
|
474
|
-
|
|
909
|
+
noteTerminalError(
|
|
910
|
+
this.#lifecycle,
|
|
911
|
+
params.errorMessage ?? "adapter step error"
|
|
912
|
+
);
|
|
475
913
|
}
|
|
476
|
-
this.#
|
|
914
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
477
915
|
await this.#scheduleStandaloneFinalization(params.endTime);
|
|
478
916
|
} catch (err) {
|
|
479
917
|
this.#warn(err);
|
|
@@ -482,27 +920,33 @@ var LangChainTracePersistence = class {
|
|
|
482
920
|
/** Point-in-time adapter events (e.g. agent action) — writes start + completed pair. */
|
|
483
921
|
async onInstantStep(params) {
|
|
484
922
|
try {
|
|
485
|
-
this.#
|
|
486
|
-
this.noteRoot(params.lcRunId, params.lcParentRunId);
|
|
487
|
-
this.#activeLcRunIds.add(params.lcRunId);
|
|
488
|
-
if (this.#standalone && !this.#runStarted) {
|
|
489
|
-
await this.#ensureRunStarted(params.timestamp, params.attributes);
|
|
490
|
-
}
|
|
923
|
+
this.#prepareForStart();
|
|
491
924
|
const stepId = createStepId();
|
|
492
925
|
this.#lcToStepId.set(params.lcRunId, stepId);
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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);
|
|
498
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);
|
|
499
943
|
const started = {
|
|
500
944
|
schemaVersion: "0.1",
|
|
501
945
|
event: "step_started",
|
|
502
946
|
timestamp: params.timestamp,
|
|
503
947
|
runId: this.#runId,
|
|
504
948
|
stepId,
|
|
505
|
-
...
|
|
949
|
+
...resolution.parentStepId ? { parentId: resolution.parentStepId } : {},
|
|
506
950
|
name: params.name,
|
|
507
951
|
type: kindToStepType(params.kind),
|
|
508
952
|
startTime: params.timestamp,
|
|
@@ -522,15 +966,71 @@ var LangChainTracePersistence = class {
|
|
|
522
966
|
};
|
|
523
967
|
await this.#write(completed);
|
|
524
968
|
if (params.status === "error") {
|
|
525
|
-
|
|
526
|
-
|
|
969
|
+
noteTerminalError(
|
|
970
|
+
this.#lifecycle,
|
|
971
|
+
params.errorMessage ?? "adapter step error"
|
|
972
|
+
);
|
|
527
973
|
}
|
|
528
|
-
this.#
|
|
974
|
+
endCallbackRun(this.#lifecycle, params.lcRunId);
|
|
529
975
|
await this.#scheduleStandaloneFinalization(params.timestamp);
|
|
530
976
|
} catch (err) {
|
|
531
977
|
this.#warn(err);
|
|
532
978
|
}
|
|
533
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
|
+
}
|
|
534
1034
|
/**
|
|
535
1035
|
* When the last active LangChain callback ends, yield one microtask so a
|
|
536
1036
|
* same-turn sibling start can cancel finalization, then write run_completed
|
|
@@ -538,24 +1038,20 @@ var LangChainTracePersistence = class {
|
|
|
538
1038
|
* block the envelope.
|
|
539
1039
|
*/
|
|
540
1040
|
async #scheduleStandaloneFinalization(endTime) {
|
|
541
|
-
if (!this.#standalone ||
|
|
542
|
-
|
|
543
|
-
const token = ++this.#finalizationToken;
|
|
1041
|
+
if (!this.#standalone || !canScheduleFinalize(this.#lifecycle)) return;
|
|
1042
|
+
const generation = this.#lifecycle.completionGeneration;
|
|
544
1043
|
await Promise.resolve();
|
|
545
|
-
if (
|
|
546
|
-
if (!this.#standalone ||
|
|
547
|
-
|
|
548
|
-
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";
|
|
549
1047
|
await this.#ensureRunCompleted(
|
|
550
1048
|
endTime,
|
|
551
1049
|
status,
|
|
552
|
-
status === "error" ? this.#
|
|
1050
|
+
status === "error" ? this.#lifecycle.terminalError?.message : void 0
|
|
553
1051
|
);
|
|
554
1052
|
}
|
|
555
1053
|
async #ensureRunStarted(startTime, attrs) {
|
|
556
|
-
if (this.#
|
|
557
|
-
this.#runStarted = true;
|
|
558
|
-
this.#runStartTime = startTime;
|
|
1054
|
+
if (!markEnvelopeStarted(this.#lifecycle, startTime)) return;
|
|
559
1055
|
await initializeTraceFile(this.#runId, this.#traceDir);
|
|
560
1056
|
const metadata = {
|
|
561
1057
|
adapter: "langchain",
|
|
@@ -575,9 +1071,21 @@ var LangChainTracePersistence = class {
|
|
|
575
1071
|
await this.#write(event);
|
|
576
1072
|
}
|
|
577
1073
|
async #ensureRunCompleted(endTime, stepStatus, errorMessage) {
|
|
578
|
-
if (
|
|
579
|
-
this.#
|
|
580
|
-
|
|
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;
|
|
581
1089
|
const durationMs = Math.max(0, endTime - startTime);
|
|
582
1090
|
const runStatus = stepStatus === "error" ? "error" : "success";
|
|
583
1091
|
const event = {
|
|
@@ -607,20 +1115,11 @@ var LangChainTracePersistence = class {
|
|
|
607
1115
|
function isRecord2(v) {
|
|
608
1116
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
609
1117
|
}
|
|
610
|
-
function
|
|
1118
|
+
function serializedLabel2(s) {
|
|
611
1119
|
if (typeof s.name === "string" && s.name.trim()) return s.name;
|
|
612
1120
|
if (Array.isArray(s.id) && s.id.length > 0) return s.id[s.id.length - 1];
|
|
613
1121
|
return s.type;
|
|
614
1122
|
}
|
|
615
|
-
function resolveToolDisplayName(tool, runName, metadata) {
|
|
616
|
-
const fromRun = typeof runName === "string" ? runName.trim() : "";
|
|
617
|
-
if (fromRun) return fromRun;
|
|
618
|
-
const metaName = metadata?.toolName;
|
|
619
|
-
if (typeof metaName === "string" && metaName.trim()) return metaName.trim();
|
|
620
|
-
const metaTool = metadata?.tool;
|
|
621
|
-
if (typeof metaTool === "string" && metaTool.trim()) return metaTool.trim();
|
|
622
|
-
return serializedLabel(tool) ?? "tool";
|
|
623
|
-
}
|
|
624
1123
|
function errorShape(err) {
|
|
625
1124
|
if (err instanceof Error) {
|
|
626
1125
|
return { errorName: err.name, errorMessage: err.message };
|
|
@@ -629,6 +1128,11 @@ function errorShape(err) {
|
|
|
629
1128
|
}
|
|
630
1129
|
var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
631
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;
|
|
632
1136
|
#opts;
|
|
633
1137
|
#redactor;
|
|
634
1138
|
#persistence;
|
|
@@ -639,16 +1143,22 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
639
1143
|
#rootRunId;
|
|
640
1144
|
constructor(options = {}) {
|
|
641
1145
|
super({});
|
|
1146
|
+
const intent = resolvePersistIntent(options);
|
|
642
1147
|
this.#opts = {
|
|
643
1148
|
capture: options.capture ?? "metadata-only",
|
|
644
1149
|
silent: options.silent ?? false,
|
|
645
1150
|
maxPreviewChars: options.maxPreviewChars ?? 200,
|
|
646
|
-
persist: options.persist ?? false,
|
|
647
1151
|
runName: options.runName ?? "langchain-agent",
|
|
648
|
-
...options
|
|
1152
|
+
...options,
|
|
1153
|
+
persist: intent.persist
|
|
649
1154
|
};
|
|
650
1155
|
this.#redactor = new Redactor({ rules: this.#opts.redact });
|
|
651
|
-
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) {
|
|
652
1162
|
this.#persistence = new LangChainTracePersistence({
|
|
653
1163
|
runName: this.#opts.runName,
|
|
654
1164
|
traceDir: this.#opts.traceDir,
|
|
@@ -674,6 +1184,91 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
674
1184
|
this.#rootRunId = void 0;
|
|
675
1185
|
this.#persistence?.reset();
|
|
676
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
|
+
}
|
|
677
1272
|
#streamPreviewLimit() {
|
|
678
1273
|
if (this.#opts.capture !== "preview") return 0;
|
|
679
1274
|
return this.#opts.maxStreamPreviewChars ?? this.#opts.maxPreviewChars ?? 200;
|
|
@@ -768,7 +1363,11 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
768
1363
|
if (parentRunId) out.parentRunId = parentRunId;
|
|
769
1364
|
if (this.#opts.runName) out.adapterRunName = this.#opts.runName;
|
|
770
1365
|
if (runNameArg) out.runName = runNameArg;
|
|
771
|
-
if (this.#opts.
|
|
1366
|
+
if (this.#opts.persist) out.traceStorage = "local";
|
|
1367
|
+
const configuredTraceDir = this.#opts.traceDir?.trim();
|
|
1368
|
+
if (configuredTraceDir && !path.isAbsolute(configuredTraceDir) && !/^[A-Za-z]:[\\/]/.test(configuredTraceDir)) {
|
|
1369
|
+
out.workspaceRelativeTraceDir = configuredTraceDir;
|
|
1370
|
+
}
|
|
772
1371
|
const cap = this.#opts.capture;
|
|
773
1372
|
if (cap !== "none" && tags?.length) out.tags = [...tags];
|
|
774
1373
|
return out;
|
|
@@ -831,9 +1430,10 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
831
1430
|
});
|
|
832
1431
|
}
|
|
833
1432
|
async handleChainStart(chain, inputs, runId, runType, tags, metadata, runName, parentRunId, _extra) {
|
|
1433
|
+
this.#prepareCallbackInvocation();
|
|
834
1434
|
this.#ensureRoot(runId, parentRunId);
|
|
835
1435
|
this.#rememberStart(runId, "CHAIN");
|
|
836
|
-
const label =
|
|
1436
|
+
const label = serializedLabel2(chain) ?? "chain";
|
|
837
1437
|
const previews = {};
|
|
838
1438
|
if (this.#opts.capture === "preview") previews.inputPreview = inputs;
|
|
839
1439
|
const attrs = {
|
|
@@ -912,6 +1512,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
912
1512
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
913
1513
|
}
|
|
914
1514
|
async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1515
|
+
this.#prepareCallbackInvocation();
|
|
915
1516
|
this.#ensureRoot(runId, parentRunId);
|
|
916
1517
|
this.#rememberStart(runId, "LLM");
|
|
917
1518
|
const model = extractModelName(llm);
|
|
@@ -944,6 +1545,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
944
1545
|
await this.#persistLlmStepStart(runId, parentRunId, stepName, "LLM", ts, attrs);
|
|
945
1546
|
}
|
|
946
1547
|
async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
|
|
1548
|
+
this.#prepareCallbackInvocation();
|
|
947
1549
|
this.#ensureRoot(runId, parentRunId);
|
|
948
1550
|
this.#rememberStart(runId, "LLM");
|
|
949
1551
|
const model = extractModelName(llm);
|
|
@@ -1062,21 +1664,22 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
1062
1664
|
});
|
|
1063
1665
|
this.#clearStreamState(runId);
|
|
1064
1666
|
}
|
|
1065
|
-
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName,
|
|
1667
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
|
|
1668
|
+
this.#prepareCallbackInvocation();
|
|
1066
1669
|
this.#ensureRoot(runId, parentRunId);
|
|
1067
1670
|
this.#rememberStart(runId, "TOOL");
|
|
1068
|
-
const
|
|
1671
|
+
const identity = resolveToolIdentity(tool, runName, metadata, toolCallId);
|
|
1069
1672
|
const previews = {};
|
|
1070
1673
|
if (this.#opts.capture === "preview") previews.inputPreview = input;
|
|
1071
1674
|
const attrs = {
|
|
1072
|
-
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1073
|
-
tool: toolName
|
|
1675
|
+
...this.#baseAttrs(runId, parentRunId, tags, runName)
|
|
1074
1676
|
};
|
|
1677
|
+
applyToolIdentityAttributes(attrs, identity);
|
|
1075
1678
|
this.#mergeMetadata(attrs, metadata);
|
|
1076
1679
|
this.#applyPreview(attrs, previews);
|
|
1077
1680
|
this.#rememberStartMetadata(runId, attrs);
|
|
1078
1681
|
const ts = Date.now();
|
|
1079
|
-
const stepName = `tool:${
|
|
1682
|
+
const stepName = `tool:${identity.displayName}`;
|
|
1080
1683
|
this.#pushEvent({
|
|
1081
1684
|
eventId: `${runId}:TOOL:start`,
|
|
1082
1685
|
runId: this.#traceRunId(runId),
|
|
@@ -1146,9 +1749,10 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
1146
1749
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1147
1750
|
}
|
|
1148
1751
|
async handleRetrieverStart(retriever, _query, runId, parentRunId, tags, metadata, name) {
|
|
1752
|
+
this.#prepareCallbackInvocation();
|
|
1149
1753
|
this.#ensureRoot(runId, parentRunId);
|
|
1150
1754
|
this.#rememberStart(runId, "RETRIEVER");
|
|
1151
|
-
const rname = name ??
|
|
1755
|
+
const rname = name ?? serializedLabel2(retriever) ?? "retriever";
|
|
1152
1756
|
const attrs = {
|
|
1153
1757
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|
|
1154
1758
|
retriever: rname
|
|
@@ -1229,6 +1833,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
|
|
|
1229
1833
|
await this.#persistStepEnd(runId, parentRunId, "error", ts, durationMs, errorMessage);
|
|
1230
1834
|
}
|
|
1231
1835
|
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
1836
|
+
this.#prepareCallbackInvocation();
|
|
1232
1837
|
this.#ensureRoot(runId, parentRunId);
|
|
1233
1838
|
const attrs = {
|
|
1234
1839
|
...this.#baseAttrs(runId, parentRunId, tags, void 0),
|