@librechat/agents 3.1.88 → 3.1.90

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.
Files changed (96) hide show
  1. package/dist/cjs/graphs/Graph.cjs +25 -1
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/hooks/executeHooks.cjs +14 -7
  4. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  5. package/dist/cjs/llm/anthropic/index.cjs +8 -2
  6. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +34 -0
  8. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  9. package/dist/cjs/main.cjs +9 -0
  10. package/dist/cjs/main.cjs.map +1 -1
  11. package/dist/cjs/stream.cjs +115 -8
  12. package/dist/cjs/stream.cjs.map +1 -1
  13. package/dist/cjs/tools/BashExecutor.cjs +10 -9
  14. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  15. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +12 -8
  16. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  17. package/dist/cjs/tools/CodeExecutor.cjs +35 -11
  18. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  19. package/dist/cjs/tools/CodeSessionFileSummary.cjs +63 -0
  20. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -0
  21. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +16 -12
  22. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  23. package/dist/cjs/tools/ToolNode.cjs +32 -12
  24. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  25. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +319 -29
  26. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  27. package/dist/cjs/tools/toolOutputReferences.cjs +8 -0
  28. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  29. package/dist/cjs/utils/events.cjs +3 -1
  30. package/dist/cjs/utils/events.cjs.map +1 -1
  31. package/dist/esm/graphs/Graph.mjs +25 -1
  32. package/dist/esm/graphs/Graph.mjs.map +1 -1
  33. package/dist/esm/hooks/executeHooks.mjs +14 -7
  34. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  35. package/dist/esm/llm/anthropic/index.mjs +9 -3
  36. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  37. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +33 -1
  38. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  39. package/dist/esm/main.mjs +2 -1
  40. package/dist/esm/main.mjs.map +1 -1
  41. package/dist/esm/stream.mjs +115 -8
  42. package/dist/esm/stream.mjs.map +1 -1
  43. package/dist/esm/tools/BashExecutor.mjs +11 -10
  44. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  45. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +13 -9
  46. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  47. package/dist/esm/tools/CodeExecutor.mjs +29 -12
  48. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  49. package/dist/esm/tools/CodeSessionFileSummary.mjs +60 -0
  50. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -0
  51. package/dist/esm/tools/ProgrammaticToolCalling.mjs +17 -13
  52. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  53. package/dist/esm/tools/ToolNode.mjs +32 -12
  54. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  55. package/dist/esm/tools/subagent/SubagentExecutor.mjs +320 -31
  56. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  57. package/dist/esm/tools/toolOutputReferences.mjs +8 -1
  58. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  59. package/dist/esm/utils/events.mjs +3 -1
  60. package/dist/esm/utils/events.mjs.map +1 -1
  61. package/dist/types/graphs/Graph.d.ts +8 -0
  62. package/dist/types/llm/anthropic/index.d.ts +3 -1
  63. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +4 -0
  64. package/dist/types/tools/BashExecutor.d.ts +3 -3
  65. package/dist/types/tools/CodeExecutor.d.ts +10 -3
  66. package/dist/types/tools/CodeSessionFileSummary.d.ts +3 -0
  67. package/dist/types/tools/ProgrammaticToolCalling.d.ts +4 -4
  68. package/dist/types/tools/subagent/SubagentExecutor.d.ts +8 -5
  69. package/dist/types/types/tools.d.ts +11 -3
  70. package/dist/types/utils/events.d.ts +1 -1
  71. package/package.json +1 -1
  72. package/src/__tests__/stream.eagerEventExecution.test.ts +1073 -221
  73. package/src/graphs/Graph.ts +27 -5
  74. package/src/hooks/__tests__/executeHooks.test.ts +38 -0
  75. package/src/hooks/executeHooks.ts +27 -7
  76. package/src/llm/anthropic/index.ts +27 -3
  77. package/src/llm/anthropic/llm.spec.ts +60 -1
  78. package/src/llm/anthropic/utils/message_inputs.ts +46 -0
  79. package/src/specs/subagent.test.ts +87 -1
  80. package/src/stream.ts +163 -12
  81. package/src/tools/BashExecutor.ts +21 -10
  82. package/src/tools/BashProgrammaticToolCalling.ts +21 -9
  83. package/src/tools/CodeExecutor.ts +55 -12
  84. package/src/tools/CodeSessionFileSummary.ts +80 -0
  85. package/src/tools/ProgrammaticToolCalling.ts +25 -12
  86. package/src/tools/ToolNode.ts +142 -116
  87. package/src/tools/__tests__/BashExecutor.test.ts +9 -0
  88. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +43 -0
  89. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +100 -16
  90. package/src/tools/__tests__/SubagentExecutor.test.ts +540 -6
  91. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +278 -14
  92. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +52 -0
  93. package/src/tools/__tests__/subagentHooks.test.ts +237 -0
  94. package/src/tools/subagent/SubagentExecutor.ts +514 -36
  95. package/src/types/tools.ts +11 -3
  96. package/src/utils/events.ts +4 -2
@@ -10,10 +10,17 @@ require('../../hooks/createWorkspacePolicyHook.cjs');
10
10
  const DEFAULT_MAX_TURNS = 25;
11
11
  const RECURSION_MULTIPLIER = 3;
12
12
  const ERROR_MESSAGE_MAX_CHARS = 200;
13
+ const MAX_PENDING_SUBAGENT_UPDATES = 64;
13
14
  const HOOK_FALLBACK = Object.freeze({
14
15
  additionalContexts: [],
15
16
  errors: [],
16
17
  });
18
+ const LANGGRAPH_RUNTIME_CONFIG_PREFIX = '__pregel_';
19
+ const LANGGRAPH_CHECKPOINT_CONFIG_KEYS = new Set([
20
+ 'checkpoint_id',
21
+ 'checkpoint_map',
22
+ 'checkpoint_ns',
23
+ ]);
17
24
  class SubagentExecutor {
18
25
  configs;
19
26
  parentSignal;
@@ -112,7 +119,7 @@ class SubagentExecutor {
112
119
  agents: [childInputs],
113
120
  tokenCounter: this.tokenCounter,
114
121
  });
115
- const forwarder = forwardingEnabled
122
+ const forwarding = forwardingEnabled
116
123
  ? this.createForwarderCallback({
117
124
  parentRegistry: parentRegistry,
118
125
  subagentType,
@@ -121,6 +128,7 @@ class SubagentExecutor {
121
128
  parentToolCallId,
122
129
  })
123
130
  : undefined;
131
+ const forwarder = forwarding?.handler;
124
132
  if (forwarder) {
125
133
  await this.emitSubagentUpdate(parentRegistry, {
126
134
  childRunId,
@@ -153,10 +161,11 @@ class SubagentExecutor {
153
161
  */
154
162
  const callbacks = forwarder ? [forwarder] : [];
155
163
  /**
156
- * Inherit the parent's `configurable` verbatim — host-set fields
164
+ * Inherit the parent's host `configurable` — host-set fields
157
165
  * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-
158
166
  * identity fields (`run_id`, `parent_run_id`, `thread_id`) all
159
- * propagate.
167
+ * propagate. LangGraph's own runtime keys are excluded because the
168
+ * child graph creates its own scratchpad/checkpoint/abort plumbing.
160
169
  *
161
170
  * Run-identity propagation is intentional and matches the
162
171
  * convention this executor itself already uses for `SubagentStart`
@@ -180,7 +189,7 @@ class SubagentExecutor {
180
189
  * For now the inheritance path matches LibreChat's primary use
181
190
  * case (synchronous subagents within a single user turn).
182
191
  */
183
- const inheritedConfigurable = params.parentConfigurable ?? {};
192
+ const inheritedConfigurable = sanitizeChildConfigurable(params.parentConfigurable);
184
193
  result = await workflow.invoke({ messages: [new messages.HumanMessage(description)] }, {
185
194
  recursionLimit: maxTurns * RECURSION_MULTIPLIER,
186
195
  signal: this.parentSignal,
@@ -195,6 +204,7 @@ class SubagentExecutor {
195
204
  catch (error) {
196
205
  const errorMessage = truncateErrorMessage(error);
197
206
  if (forwarder) {
207
+ await forwarding.drain();
198
208
  await this.emitSubagentUpdate(parentRegistry, {
199
209
  childRunId,
200
210
  subagentType,
@@ -236,6 +246,7 @@ class SubagentExecutor {
236
246
  });
237
247
  }
238
248
  if (forwarder) {
249
+ await forwarding.drain();
239
250
  await this.emitSubagentUpdate(parentRegistry, {
240
251
  childRunId,
241
252
  subagentType,
@@ -298,25 +309,67 @@ class SubagentExecutor {
298
309
  if (!handler) {
299
310
  return;
300
311
  }
301
- const event = {
302
- runId: parentRunId,
303
- subagentRunId: childRunId,
304
- subagentType,
305
- subagentAgentId,
306
- parentAgentId,
307
- parentToolCallId,
308
- phase,
309
- data,
310
- label: summarizeEvent(eventName, data),
311
- timestamp: new Date().toISOString(),
312
- };
313
312
  try {
313
+ const event = {
314
+ runId: parentRunId,
315
+ subagentRunId: childRunId,
316
+ subagentType,
317
+ subagentAgentId,
318
+ parentAgentId,
319
+ parentToolCallId,
320
+ phase,
321
+ data: sanitizeForwardedSubagentUpdateData(eventName, data),
322
+ label: summarizeEvent(eventName, data),
323
+ timestamp: new Date().toISOString(),
324
+ };
314
325
  await handler.handle(_enum.GraphEvents.ON_SUBAGENT_UPDATE, event);
315
326
  }
316
327
  catch {
317
328
  /* observational — swallow */
318
329
  }
319
330
  };
331
+ const queuedUpdates = [];
332
+ let drainPromise;
333
+ const enqueue = (update) => {
334
+ if (queuedUpdates.length >= MAX_PENDING_SUBAGENT_UPDATES) {
335
+ const dropIndex = queuedUpdates.findIndex((queued) => isDroppableSubagentUpdatePhase(queued.phase));
336
+ if (dropIndex >= 0) {
337
+ queuedUpdates.splice(dropIndex, 1);
338
+ }
339
+ else if (isDroppableSubagentUpdatePhase(update.phase)) {
340
+ return;
341
+ }
342
+ }
343
+ queuedUpdates.push(update);
344
+ };
345
+ const drain = async () => {
346
+ if (drainPromise != null) {
347
+ await drainPromise;
348
+ return;
349
+ }
350
+ drainPromise = (async () => {
351
+ while (queuedUpdates.length > 0) {
352
+ const update = queuedUpdates.shift();
353
+ if (update == null) {
354
+ continue;
355
+ }
356
+ await wrap(update.eventName, update.phase, update.data);
357
+ }
358
+ })();
359
+ try {
360
+ await drainPromise;
361
+ }
362
+ finally {
363
+ drainPromise = undefined;
364
+ if (queuedUpdates.length > 0) {
365
+ await drain();
366
+ }
367
+ }
368
+ };
369
+ const scheduleWrap = (eventName, phase, data) => {
370
+ enqueue({ eventName, phase, data });
371
+ void drain();
372
+ };
320
373
  const handler = base.BaseCallbackHandler.fromMethods({
321
374
  [_enum.Callback.CUSTOM_EVENT]: async (eventName, data) => {
322
375
  if (eventName === _enum.GraphEvents.ON_TOOL_EXECUTE) {
@@ -328,27 +381,27 @@ class SubagentExecutor {
328
381
  * We also surface a short notice in the subagent-update stream so
329
382
  * the UI can show "calling <tool>" for each tool the child spawns.
330
383
  */
331
- await wrap(eventName, 'run_step', data);
384
+ scheduleWrap(eventName, 'run_step', data);
332
385
  return;
333
386
  }
334
387
  if (eventName === _enum.GraphEvents.ON_RUN_STEP) {
335
- await wrap(eventName, 'run_step', data);
388
+ scheduleWrap(eventName, 'run_step', data);
336
389
  return;
337
390
  }
338
391
  if (eventName === _enum.GraphEvents.ON_RUN_STEP_DELTA) {
339
- await wrap(eventName, 'run_step_delta', data);
392
+ scheduleWrap(eventName, 'run_step_delta', data);
340
393
  return;
341
394
  }
342
395
  if (eventName === _enum.GraphEvents.ON_RUN_STEP_COMPLETED) {
343
- await wrap(eventName, 'run_step_completed', data);
396
+ scheduleWrap(eventName, 'run_step_completed', data);
344
397
  return;
345
398
  }
346
399
  if (eventName === _enum.GraphEvents.ON_MESSAGE_DELTA) {
347
- await wrap(eventName, 'message_delta', data);
400
+ scheduleWrap(eventName, 'message_delta', data);
348
401
  return;
349
402
  }
350
403
  if (eventName === _enum.GraphEvents.ON_REASONING_DELTA) {
351
- await wrap(eventName, 'reasoning_delta', data);
404
+ scheduleWrap(eventName, 'reasoning_delta', data);
352
405
  return;
353
406
  }
354
407
  },
@@ -356,15 +409,251 @@ class SubagentExecutor {
356
409
  /**
357
410
  * `awaitHandlers = true` is required so the child's `ToolNode` actually
358
411
  * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves
359
- * the batch request. The same flag applies to observational events
360
- * (message_delta, run_step, …), which means a slow
361
- * `ON_SUBAGENT_UPDATE` handler on the host serializes the child
362
- * stream. If host-side latency becomes a concern, a future
363
- * refinement could split operational and observational events into
364
- * separate callback handlers with distinct await semantics.
412
+ * the batch request. Observational `ON_SUBAGENT_UPDATE` calls are queued
413
+ * behind a bounded sequential dispatcher so host UI publication cannot
414
+ * backpressure each child emission or run unbounded concurrent publishes.
415
+ * The executor drains this queue before terminal stop/error envelopes to
416
+ * preserve phase ordering.
365
417
  */
366
418
  handler.awaitHandlers = true;
367
- return handler;
419
+ return { handler, drain };
420
+ }
421
+ }
422
+ function sanitizeChildConfigurable(parentConfigurable) {
423
+ if (parentConfigurable == null) {
424
+ return {};
425
+ }
426
+ return Object.fromEntries(Object.entries(parentConfigurable).filter(([key]) => !isLangGraphRuntimeConfigKey(key)));
427
+ }
428
+ function isLangGraphRuntimeConfigKey(key) {
429
+ return (key.startsWith(LANGGRAPH_RUNTIME_CONFIG_PREFIX) ||
430
+ LANGGRAPH_CHECKPOINT_CONFIG_KEYS.has(key));
431
+ }
432
+ function sanitizeForwardedSubagentUpdateData(eventName, data) {
433
+ if (eventName === _enum.GraphEvents.ON_TOOL_EXECUTE) {
434
+ return sanitizeToolExecuteUpdateData(data);
435
+ }
436
+ if (eventName === _enum.GraphEvents.ON_RUN_STEP) {
437
+ return sanitizeRunStepUpdateData(data);
438
+ }
439
+ if (eventName === _enum.GraphEvents.ON_RUN_STEP_DELTA) {
440
+ return sanitizeRunStepDeltaUpdateData(data);
441
+ }
442
+ if (eventName === _enum.GraphEvents.ON_RUN_STEP_COMPLETED) {
443
+ return sanitizeRunStepCompletedUpdateData(data);
444
+ }
445
+ if (eventName === _enum.GraphEvents.ON_MESSAGE_DELTA) {
446
+ return sanitizeMessageDeltaUpdateData(data);
447
+ }
448
+ if (eventName === _enum.GraphEvents.ON_REASONING_DELTA) {
449
+ return sanitizeReasoningDeltaUpdateData(data);
450
+ }
451
+ return undefined;
452
+ }
453
+ function isDroppableSubagentUpdatePhase(phase) {
454
+ return (phase === 'message_delta' ||
455
+ phase === 'reasoning_delta' ||
456
+ phase === 'run_step_delta');
457
+ }
458
+ function sanitizeToolExecuteUpdateData(data) {
459
+ const request = data;
460
+ const toolCalls = Array.isArray(request.toolCalls)
461
+ ? request.toolCalls.map(sanitizeToolCallForUpdate)
462
+ : [];
463
+ const sanitized = { toolCalls };
464
+ if (typeof request.agentId === 'string') {
465
+ sanitized.agentId = request.agentId;
466
+ }
467
+ return sanitized;
468
+ }
469
+ function sanitizeToolCallForUpdate(call) {
470
+ const sanitized = {
471
+ id: call.id,
472
+ name: call.name,
473
+ args: call.args,
474
+ };
475
+ return sanitized;
476
+ }
477
+ function sanitizeRunStepUpdateData(data) {
478
+ if (!isObjectLike(data)) {
479
+ return undefined;
480
+ }
481
+ const step = data;
482
+ const sanitized = {};
483
+ assignString(sanitized, 'agentId', step.agentId);
484
+ assignNumber(sanitized, 'groupId', step.groupId);
485
+ assignString(sanitized, 'id', step.id);
486
+ assignNumber(sanitized, 'index', step.index);
487
+ assignString(sanitized, 'runId', step.runId);
488
+ assignNumber(sanitized, 'stepIndex', step.stepIndex);
489
+ assignString(sanitized, 'type', step.type);
490
+ if (step.summary !== undefined) {
491
+ sanitized.summary = step.summary;
492
+ }
493
+ if (step.usage !== undefined) {
494
+ sanitized.usage = step.usage;
495
+ }
496
+ sanitized.stepDetails = sanitizeStepDetails(step.stepDetails);
497
+ return sanitized;
498
+ }
499
+ function sanitizeRunStepDeltaUpdateData(data) {
500
+ if (!isObjectLike(data)) {
501
+ return undefined;
502
+ }
503
+ const event = data;
504
+ const sanitized = {};
505
+ assignString(sanitized, 'id', event.id);
506
+ sanitized.delta = sanitizeToolCallDelta(event.delta);
507
+ return sanitized;
508
+ }
509
+ function sanitizeRunStepCompletedUpdateData(data) {
510
+ if (!isObjectLike(data)) {
511
+ return undefined;
512
+ }
513
+ const event = data;
514
+ return { result: sanitizeStepCompleted(event.result) };
515
+ }
516
+ function sanitizeMessageDeltaUpdateData(data) {
517
+ if (!isObjectLike(data)) {
518
+ return undefined;
519
+ }
520
+ const event = data;
521
+ const sanitized = {};
522
+ assignString(sanitized, 'id', event.id);
523
+ if (event.delta != null) {
524
+ sanitized.delta = {};
525
+ if (event.delta.content !== undefined) {
526
+ sanitized.delta.content = event.delta.content;
527
+ }
528
+ if (event.delta.tool_call_ids !== undefined) {
529
+ sanitized.delta.tool_call_ids = event.delta.tool_call_ids;
530
+ }
531
+ }
532
+ return sanitized;
533
+ }
534
+ function sanitizeReasoningDeltaUpdateData(data) {
535
+ if (!isObjectLike(data)) {
536
+ return undefined;
537
+ }
538
+ const event = data;
539
+ const sanitized = {};
540
+ assignString(sanitized, 'id', event.id);
541
+ if (event.delta?.content !== undefined) {
542
+ sanitized.delta = { content: event.delta.content };
543
+ }
544
+ return sanitized;
545
+ }
546
+ function sanitizeStepDetails(stepDetails) {
547
+ if (!isObjectLike(stepDetails)) {
548
+ return undefined;
549
+ }
550
+ const rawDetails = stepDetails;
551
+ if (rawDetails.type === _enum.StepTypes.MESSAGE_CREATION) {
552
+ const sanitized = {
553
+ type: _enum.StepTypes.MESSAGE_CREATION,
554
+ };
555
+ const messageId = rawDetails.message_creation?.message_id;
556
+ if (typeof messageId === 'string') {
557
+ sanitized.message_creation = { message_id: messageId };
558
+ }
559
+ return sanitized;
560
+ }
561
+ if (rawDetails.type === _enum.StepTypes.TOOL_CALLS) {
562
+ const sanitized = {
563
+ type: _enum.StepTypes.TOOL_CALLS,
564
+ };
565
+ if (Array.isArray(rawDetails.tool_calls)) {
566
+ sanitized.tool_calls = rawDetails.tool_calls.map(sanitizeAgentToolCall);
567
+ }
568
+ return sanitized;
569
+ }
570
+ return undefined;
571
+ }
572
+ function sanitizeToolCallDelta(delta) {
573
+ if (!isObjectLike(delta)) {
574
+ return undefined;
575
+ }
576
+ const sanitized = {};
577
+ assignString(sanitized, 'auth', delta.auth);
578
+ assignNumber(sanitized, 'expires_at', delta.expires_at);
579
+ assignString(sanitized, 'type', delta.type);
580
+ if (delta.summary !== undefined) {
581
+ sanitized.summary = delta.summary;
582
+ }
583
+ if (Array.isArray(delta.tool_calls)) {
584
+ sanitized.tool_calls = delta.tool_calls.map(sanitizeAgentToolCall);
585
+ }
586
+ return sanitized;
587
+ }
588
+ function sanitizeStepCompleted(data) {
589
+ if (!isObjectLike(data)) {
590
+ return undefined;
591
+ }
592
+ const completed = data;
593
+ if (completed.type === 'summary') {
594
+ return {
595
+ type: 'summary',
596
+ summary: completed.summary,
597
+ };
598
+ }
599
+ if (completed.type !== 'tool_call') {
600
+ return undefined;
601
+ }
602
+ const sanitized = { type: 'tool_call' };
603
+ assignString(sanitized, 'id', completed.id);
604
+ assignNumber(sanitized, 'index', completed.index);
605
+ sanitized.tool_call = sanitizeProcessedToolCall(completed.tool_call);
606
+ return sanitized;
607
+ }
608
+ function sanitizeProcessedToolCall(toolCall) {
609
+ if (!isObjectLike(toolCall)) {
610
+ return undefined;
611
+ }
612
+ const call = toolCall;
613
+ const sanitized = {};
614
+ assignString(sanitized, 'id', call.id);
615
+ assignString(sanitized, 'name', call.name);
616
+ if (call.args !== undefined) {
617
+ sanitized.args = call.args;
618
+ }
619
+ assignString(sanitized, 'output', call.output);
620
+ assignNumber(sanitized, 'progress', call.progress);
621
+ return sanitized;
622
+ }
623
+ function sanitizeAgentToolCall(toolCall) {
624
+ if (!isObjectLike(toolCall)) {
625
+ return {};
626
+ }
627
+ const call = toolCall;
628
+ const sanitized = {};
629
+ assignString(sanitized, 'id', call.id);
630
+ assignString(sanitized, 'name', call.name);
631
+ assignString(sanitized, 'type', call.type);
632
+ if (call.args !== undefined) {
633
+ sanitized.args = call.args;
634
+ }
635
+ if (isObjectLike(call.function)) {
636
+ const fn = {};
637
+ assignString(fn, 'name', call.function.name);
638
+ if (typeof call.function.arguments === 'string' ||
639
+ isObjectLike(call.function.arguments)) {
640
+ fn.arguments = call.function.arguments;
641
+ }
642
+ sanitized.function = fn;
643
+ }
644
+ return sanitized;
645
+ }
646
+ function isObjectLike(value) {
647
+ return value != null && typeof value === 'object' && !Array.isArray(value);
648
+ }
649
+ function assignString(target, key, value) {
650
+ if (typeof value === 'string') {
651
+ target[key] = value;
652
+ }
653
+ }
654
+ function assignNumber(target, key, value) {
655
+ if (typeof value === 'number') {
656
+ target[key] = value;
368
657
  }
369
658
  }
370
659
  /**
@@ -538,5 +827,6 @@ exports.SubagentExecutor = SubagentExecutor;
538
827
  exports.buildChildInputs = buildChildInputs;
539
828
  exports.filterSubagentResult = filterSubagentResult;
540
829
  exports.resolveSubagentConfigs = resolveSubagentConfigs;
830
+ exports.sanitizeForwardedSubagentUpdateData = sanitizeForwardedSubagentUpdateData;
541
831
  exports.summarizeEvent = summarizeEvent;
542
832
  //# sourceMappingURL=SubagentExecutor.cjs.map