@librechat/agents 3.2.59 → 3.2.61

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.
@@ -275,6 +275,14 @@ var Graph = class {
275
275
  */
276
276
  eagerEventToolExecution;
277
277
  codeSessionToolNames;
278
+ /**
279
+ * Run-scoped names of tools whose in-process body may raise a LangGraph
280
+ * `interrupt()` (e.g. `ask_user_question`). Threaded from
281
+ * `RunConfig.interruptingToolNames` into every ToolNode this graph
282
+ * compiles so a mid-batch interrupt cannot double-execute non-idempotent
283
+ * siblings on resume. See {@link t.ToolNodeOptions.interruptingToolNames}.
284
+ */
285
+ interruptingToolNames;
278
286
  eagerEventToolExecutions = /* @__PURE__ */ new Map();
279
287
  eagerEventToolUsageCount = /* @__PURE__ */ new Map();
280
288
  eagerEventToolUsageCountsByAgentId = /* @__PURE__ */ new Map();
@@ -321,6 +329,7 @@ var Graph = class {
321
329
  this.toolOutputReferences = void 0;
322
330
  this.eagerEventToolExecution = void 0;
323
331
  this.codeSessionToolNames = void 0;
332
+ this.interruptingToolNames = void 0;
324
333
  this.eagerEventToolExecutions.clear();
325
334
  this.clearEagerEventToolUsageCounts();
326
335
  this.eagerEventToolCallChunks.clear();
@@ -685,6 +694,7 @@ var StandardGraph = class StandardGraph extends Graph {
685
694
  eagerEventToolUsageCount: this.getEagerEventToolUsageCount(agentContext?.agentId),
686
695
  toolExecution: this.toolExecution,
687
696
  directToolNames: directToolNames.size > 0 ? directToolNames : void 0,
697
+ interruptingToolNames: this.interruptingToolNames != null && this.interruptingToolNames.length > 0 ? new Set(this.interruptingToolNames) : void 0,
688
698
  maxContextTokens: agentContext?.maxContextTokens,
689
699
  maxToolResultChars: agentContext?.maxToolResultChars,
690
700
  toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
@@ -709,6 +719,7 @@ var StandardGraph = class StandardGraph extends Graph {
709
719
  sessions: this.sessions,
710
720
  toolExecution: this.toolExecution,
711
721
  codeSessionToolNames: this.codeSessionToolNames,
722
+ interruptingToolNames: this.interruptingToolNames != null && this.interruptingToolNames.length > 0 ? new Set(this.interruptingToolNames) : void 0,
712
723
  hookRegistry: this.hookRegistry,
713
724
  humanInTheLoop: this.humanInTheLoop,
714
725
  maxContextTokens: agentContext?.maxContextTokens,
@@ -1252,6 +1263,7 @@ var StandardGraph = class StandardGraph extends Graph {
1252
1263
  childGraph.toolOutputReferences = this.toolOutputReferences;
1253
1264
  childGraph.eagerEventToolExecution = this.eagerEventToolExecution;
1254
1265
  childGraph.codeSessionToolNames = this.codeSessionToolNames;
1266
+ childGraph.interruptingToolNames = this.interruptingToolNames;
1255
1267
  childGraph.toolExecution = this.toolExecution;
1256
1268
  childGraph.eventToolExecutionAvailable = this.handlerRegistry?.getHandler("on_tool_execute") != null;
1257
1269
  return childGraph;
@@ -1444,19 +1456,28 @@ var StandardGraph = class StandardGraph extends Graph {
1444
1456
  }
1445
1457
  /**
1446
1458
  * Static version of handleToolCallError to avoid creating strong references
1447
- * that prevent garbage collection
1459
+ * that prevent garbage collection.
1460
+ *
1461
+ * Returns whether the error completion event was actually dispatched. A
1462
+ * tool can error before this graph instance has a run step for the call —
1463
+ * on a resume pass the interrupted batch re-executes IMMEDIATELY on graph
1464
+ * re-entry, before any step replay has registered `toolCallStepIds` (a
1465
+ * fast-failing tool, e.g. a schema-validation reject, loses that race).
1466
+ * That is a caller-recoverable condition, not an invariant violation: the
1467
+ * ToolNode falls back to its normal completion dispatch for the error
1468
+ * ToolMessage when this returns `false`, so throwing here would only
1469
+ * replace a recoverable miss with a lost completion event and a scary log.
1448
1470
  */
1449
1471
  static async handleToolCallErrorStatic(graph, data, metadata) {
1450
- if (!graph.config) throw new Error("No config provided");
1451
1472
  if (!data.id) {
1452
1473
  console.warn("No Tool ID provided for Tool Error");
1453
- return;
1474
+ return false;
1454
1475
  }
1455
1476
  const stepId = graph.toolCallStepIds.get(data.id) ?? "";
1456
- if (!stepId) throw new Error(`No stepId found for tool_call_id ${data.id}`);
1477
+ if (!stepId) return false;
1457
1478
  const { name, input: args, error } = data;
1458
1479
  const runStep = graph.getRunStep(stepId);
1459
- if (!runStep) throw new Error(`No run step found for stepId ${stepId}`);
1480
+ if (!runStep) return false;
1460
1481
  const tool_call = {
1461
1482
  id: data.id,
1462
1483
  name: name || "",
@@ -1464,19 +1485,22 @@ var StandardGraph = class StandardGraph extends Graph {
1464
1485
  output: `Error processing tool${error?.message != null ? `: ${error.message}` : ""}`,
1465
1486
  progress: 1
1466
1487
  };
1467
- await graph.handlerRegistry?.getHandler("on_run_step_completed")?.handle("on_run_step_completed", { result: {
1488
+ const handler = graph.handlerRegistry?.getHandler("on_run_step_completed");
1489
+ if (!handler) return false;
1490
+ await handler.handle("on_run_step_completed", { result: {
1468
1491
  id: stepId,
1469
1492
  index: runStep.index,
1470
1493
  type: "tool_call",
1471
1494
  tool_call
1472
1495
  } }, metadata, graph);
1496
+ return true;
1473
1497
  }
1474
1498
  /**
1475
1499
  * Instance method that delegates to the static method
1476
1500
  * Kept for backward compatibility
1477
1501
  */
1478
1502
  async handleToolCallError(data, metadata) {
1479
- await StandardGraph.handleToolCallErrorStatic(this, data, metadata);
1503
+ return StandardGraph.handleToolCallErrorStatic(this, data, metadata);
1480
1504
  }
1481
1505
  async dispatchRunStepDelta(id, delta, metadata) {
1482
1506
  if (!this.config) throw new Error("No config provided");