@agent-inspect/langchain 6.7.3 → 6.7.5

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/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';
@@ -349,6 +350,11 @@ var LangChainTracePersistence = class {
349
350
  #runCompleted = false;
350
351
  #runStartTime;
351
352
  #rootLcRunId;
353
+ /** Live LangChain callback runIds for standalone envelope finalization. */
354
+ #activeLcRunIds = /* @__PURE__ */ new Set();
355
+ #sawError = false;
356
+ #lastErrorMessage;
357
+ #finalizationToken = 0;
352
358
  #lcToStepId = /* @__PURE__ */ new Map();
353
359
  constructor(options = {}) {
354
360
  const inContext = hasActiveContext();
@@ -369,10 +375,14 @@ var LangChainTracePersistence = class {
369
375
  return this.#traceDir;
370
376
  }
371
377
  reset() {
378
+ this.#finalizationToken += 1;
372
379
  this.#runStarted = false;
373
380
  this.#runCompleted = false;
374
381
  this.#runStartTime = void 0;
375
382
  this.#rootLcRunId = void 0;
383
+ this.#activeLcRunIds.clear();
384
+ this.#sawError = false;
385
+ this.#lastErrorMessage = void 0;
376
386
  this.#lcToStepId.clear();
377
387
  }
378
388
  noteRoot(lcRunId, parentRunId) {
@@ -386,7 +396,9 @@ var LangChainTracePersistence = class {
386
396
  }
387
397
  async onStepStart(params) {
388
398
  try {
399
+ this.#finalizationToken += 1;
389
400
  this.noteRoot(params.lcRunId, params.lcParentRunId);
401
+ this.#activeLcRunIds.add(params.lcRunId);
390
402
  if (this.#standalone && !this.#runStarted) {
391
403
  await this.#ensureRunStarted(params.startTime, params.attributes);
392
404
  }
@@ -458,13 +470,12 @@ var LangChainTracePersistence = class {
458
470
  ...params.status === "error" && params.errorMessage ? { error: { message: params.errorMessage } } : {}
459
471
  };
460
472
  await this.#write(event);
461
- if (this.#standalone && !this.#runCompleted && this.#rootLcRunId === params.lcRunId && !params.lcParentRunId) {
462
- await this.#ensureRunCompleted(
463
- params.endTime,
464
- params.status,
465
- params.errorMessage
466
- );
473
+ if (params.status === "error") {
474
+ this.#sawError = true;
475
+ if (params.errorMessage) this.#lastErrorMessage = params.errorMessage;
467
476
  }
477
+ this.#activeLcRunIds.delete(params.lcRunId);
478
+ await this.#scheduleStandaloneFinalization(params.endTime);
468
479
  } catch (err) {
469
480
  this.#warn(err);
470
481
  }
@@ -472,7 +483,9 @@ var LangChainTracePersistence = class {
472
483
  /** Point-in-time adapter events (e.g. agent action) — writes start + completed pair. */
473
484
  async onInstantStep(params) {
474
485
  try {
486
+ this.#finalizationToken += 1;
475
487
  this.noteRoot(params.lcRunId, params.lcParentRunId);
488
+ this.#activeLcRunIds.add(params.lcRunId);
476
489
  if (this.#standalone && !this.#runStarted) {
477
490
  await this.#ensureRunStarted(params.timestamp, params.attributes);
478
491
  }
@@ -509,10 +522,37 @@ var LangChainTracePersistence = class {
509
522
  ...params.status === "error" && params.errorMessage ? { error: { message: params.errorMessage } } : {}
510
523
  };
511
524
  await this.#write(completed);
525
+ if (params.status === "error") {
526
+ this.#sawError = true;
527
+ if (params.errorMessage) this.#lastErrorMessage = params.errorMessage;
528
+ }
529
+ this.#activeLcRunIds.delete(params.lcRunId);
530
+ await this.#scheduleStandaloneFinalization(params.timestamp);
512
531
  } catch (err) {
513
532
  this.#warn(err);
514
533
  }
515
534
  }
535
+ /**
536
+ * When the last active LangChain callback ends, yield one microtask so a
537
+ * same-turn sibling start can cancel finalization, then write run_completed
538
+ * before the callback promise settles. Unresolved external parents do not
539
+ * block the envelope.
540
+ */
541
+ async #scheduleStandaloneFinalization(endTime) {
542
+ if (!this.#standalone || this.#runCompleted || !this.#runStarted) return;
543
+ if (this.#activeLcRunIds.size > 0) return;
544
+ const token = ++this.#finalizationToken;
545
+ await Promise.resolve();
546
+ if (token !== this.#finalizationToken) return;
547
+ if (!this.#standalone || this.#runCompleted || !this.#runStarted) return;
548
+ if (this.#activeLcRunIds.size > 0) return;
549
+ const status = this.#sawError ? "error" : "success";
550
+ await this.#ensureRunCompleted(
551
+ endTime,
552
+ status,
553
+ status === "error" ? this.#lastErrorMessage : void 0
554
+ );
555
+ }
516
556
  async #ensureRunStarted(startTime, attrs) {
517
557
  if (this.#runStarted) return;
518
558
  this.#runStarted = true;
@@ -573,6 +613,15 @@ function serializedLabel(s) {
573
613
  if (Array.isArray(s.id) && s.id.length > 0) return s.id[s.id.length - 1];
574
614
  return s.type;
575
615
  }
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
+ }
576
625
  function errorShape(err) {
577
626
  if (err instanceof Error) {
578
627
  return { errorName: err.name, errorMessage: err.message };
@@ -720,7 +769,11 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
720
769
  if (parentRunId) out.parentRunId = parentRunId;
721
770
  if (this.#opts.runName) out.adapterRunName = this.#opts.runName;
722
771
  if (runNameArg) out.runName = runNameArg;
723
- if (this.#opts.traceDir) out.traceDir = this.#opts.traceDir;
772
+ if (this.#opts.persist) out.traceStorage = "local";
773
+ const configuredTraceDir = this.#opts.traceDir?.trim();
774
+ if (configuredTraceDir && !path.isAbsolute(configuredTraceDir) && !/^[A-Za-z]:[\\/]/.test(configuredTraceDir)) {
775
+ out.workspaceRelativeTraceDir = configuredTraceDir;
776
+ }
724
777
  const cap = this.#opts.capture;
725
778
  if (cap !== "none" && tags?.length) out.tags = [...tags];
726
779
  return out;
@@ -1017,7 +1070,7 @@ var AgentInspectCallback = class extends BaseCallbackHandler {
1017
1070
  async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, _toolCallId) {
1018
1071
  this.#ensureRoot(runId, parentRunId);
1019
1072
  this.#rememberStart(runId, "TOOL");
1020
- const toolName = serializedLabel(tool) ?? "tool";
1073
+ const toolName = resolveToolDisplayName(tool, runName, metadata);
1021
1074
  const previews = {};
1022
1075
  if (this.#opts.capture === "preview") previews.inputPreview = input;
1023
1076
  const attrs = {