@librechat/agents 3.1.89 → 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 (77) hide show
  1. package/dist/cjs/graphs/Graph.cjs +7 -0
  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/tools/BashExecutor.cjs +10 -9
  12. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  13. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +12 -8
  14. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  15. package/dist/cjs/tools/CodeExecutor.cjs +35 -11
  16. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  17. package/dist/cjs/tools/CodeSessionFileSummary.cjs +63 -0
  18. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -0
  19. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +16 -12
  20. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  21. package/dist/cjs/tools/ToolNode.cjs +8 -5
  22. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  23. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +319 -29
  24. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  25. package/dist/esm/graphs/Graph.mjs +7 -0
  26. package/dist/esm/graphs/Graph.mjs.map +1 -1
  27. package/dist/esm/hooks/executeHooks.mjs +14 -7
  28. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  29. package/dist/esm/llm/anthropic/index.mjs +9 -3
  30. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  31. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +33 -1
  32. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  33. package/dist/esm/main.mjs +2 -1
  34. package/dist/esm/main.mjs.map +1 -1
  35. package/dist/esm/tools/BashExecutor.mjs +11 -10
  36. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  37. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +13 -9
  38. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  39. package/dist/esm/tools/CodeExecutor.mjs +29 -12
  40. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  41. package/dist/esm/tools/CodeSessionFileSummary.mjs +60 -0
  42. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -0
  43. package/dist/esm/tools/ProgrammaticToolCalling.mjs +17 -13
  44. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  45. package/dist/esm/tools/ToolNode.mjs +8 -5
  46. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  47. package/dist/esm/tools/subagent/SubagentExecutor.mjs +320 -31
  48. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  49. package/dist/types/llm/anthropic/index.d.ts +3 -1
  50. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +4 -0
  51. package/dist/types/tools/BashExecutor.d.ts +3 -3
  52. package/dist/types/tools/CodeExecutor.d.ts +10 -3
  53. package/dist/types/tools/CodeSessionFileSummary.d.ts +3 -0
  54. package/dist/types/tools/ProgrammaticToolCalling.d.ts +4 -4
  55. package/dist/types/tools/subagent/SubagentExecutor.d.ts +8 -5
  56. package/dist/types/types/tools.d.ts +2 -3
  57. package/package.json +1 -1
  58. package/src/graphs/Graph.ts +7 -0
  59. package/src/hooks/__tests__/executeHooks.test.ts +38 -0
  60. package/src/hooks/executeHooks.ts +27 -7
  61. package/src/llm/anthropic/index.ts +27 -3
  62. package/src/llm/anthropic/llm.spec.ts +60 -1
  63. package/src/llm/anthropic/utils/message_inputs.ts +46 -0
  64. package/src/tools/BashExecutor.ts +21 -10
  65. package/src/tools/BashProgrammaticToolCalling.ts +21 -9
  66. package/src/tools/CodeExecutor.ts +55 -12
  67. package/src/tools/CodeSessionFileSummary.ts +80 -0
  68. package/src/tools/ProgrammaticToolCalling.ts +25 -12
  69. package/src/tools/ToolNode.ts +8 -5
  70. package/src/tools/__tests__/BashExecutor.test.ts +9 -0
  71. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +43 -0
  72. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +100 -16
  73. package/src/tools/__tests__/SubagentExecutor.test.ts +540 -6
  74. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +52 -0
  75. package/src/tools/__tests__/subagentHooks.test.ts +237 -0
  76. package/src/tools/subagent/SubagentExecutor.ts +514 -36
  77. package/src/types/tools.ts +2 -3
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentExecutor.mjs","sources":["../../../../src/tools/subagent/SubagentExecutor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type {\n AgentInputs,\n StandardGraphInput,\n ResolvedSubagentConfig,\n SubagentConfig,\n SubagentUpdateEvent,\n SubagentUpdatePhase,\n ToolExecuteBatchRequest,\n TokenCounter,\n} from '@/types';\nimport type { AggregatedHookResult, HookRegistry } from '@/hooks';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type { StandardGraph } from '@/graphs/Graph';\nimport { GraphEvents, Callback } from '@/common';\nimport type { HandlerRegistry } from '@/events';\nimport { executeHooks } from '@/hooks';\n\nconst DEFAULT_MAX_TURNS = 25;\nconst RECURSION_MULTIPLIER = 3;\nconst ERROR_MESSAGE_MAX_CHARS = 200;\n\nconst HOOK_FALLBACK: AggregatedHookResult = Object.freeze({\n additionalContexts: [] as string[],\n errors: [] as string[],\n});\n\nexport type SubagentExecuteParams = {\n description: string;\n subagentType: string;\n threadId?: string;\n /**\n * Parent-side `tool_call_id` of the `subagent` tool invocation that\n * triggered this execution. Surfaced on {@link SubagentUpdateEvent} so\n * hosts can correlate child updates back to the originating tool call\n * without relying on event ordering heuristics.\n */\n parentToolCallId?: string;\n /**\n * Snapshot of the parent invocation's `config.configurable` at the\n * spawn-tool call site. Inherited verbatim into the child workflow's\n * `configurable` so host-set fields (`requestBody`, `user`,\n * `userMCPAuthMap`, etc.) propagate — fixing MCP body-placeholder\n * substitution and per-user lookups for subagent tool calls.\n *\n * Inheritance details (verified empirically against LangGraph):\n * - host-set keys propagate as-is into the child's tool dispatches;\n * - `thread_id` propagates (with `childRunId` as a fallback when\n * parent did not supply one) — matches the \"subagent is part of\n * the same conversation\" mental model and aligns with the\n * `sessionId: this.parentRunId` convention this executor already\n * uses for `SubagentStart` / `SubagentStop` hooks;\n * - `parent_run_id` propagates when the host put it on parent's\n * configurable;\n * - `run_id` is *overwritten by the LangGraph runtime* at child\n * invoke time regardless of what we forward — child's tool\n * dispatches see the child graph's runtime runId in\n * `configurable.run_id`, not the parent's. Hosts that need\n * parent-scoped run identity for downstream consumers should\n * plumb it via a host-defined key (e.g. `requestBody.messageId`),\n * not `run_id`.\n *\n * A future revision will likely make this inheritance configurable\n * per spawn type — background / async subagents may want isolation\n * rather than sharing parent's host context.\n */\n parentConfigurable?: Record<string, unknown>;\n};\n\nexport type SubagentExecuteResult = {\n content: string;\n messages: BaseMessage[];\n};\n\n/**\n * Factory that constructs a child graph for subagent execution. Injected\n * rather than imported so that `SubagentExecutor` does not have a runtime\n * dependency on `StandardGraph` — this avoids a circular dependency between\n * `src/graphs/Graph.ts` and `src/tools/subagent/` that would otherwise break\n * Rollup's chunking under `preserveModules`.\n */\nexport type ChildGraphFactory = (input: StandardGraphInput) => StandardGraph;\n\nexport type SubagentExecutorOptions = {\n configs: Map<string, ResolvedSubagentConfig>;\n parentSignal?: AbortSignal;\n hookRegistry?: HookRegistry;\n parentRunId: string;\n parentAgentId?: string;\n tokenCounter?: TokenCounter;\n /** Remaining nesting budget. 0 or negative blocks execution. */\n maxDepth?: number;\n /**\n * Factory for constructing the isolated child graph. Callers pass\n * `(input) => new StandardGraph(input)` — injected to break a circular\n * module dependency.\n */\n createChildGraph: ChildGraphFactory;\n /**\n * Parent's event handler registry. When provided, child-graph events are\n * forwarded through this registry so hosts can:\n * (a) execute event-driven tools (`ON_TOOL_EXECUTE` routed to parent's handler),\n * (b) surface child activity to a UI via wrapped {@link GraphEvents.ON_SUBAGENT_UPDATE}.\n * When omitted, the child runs fully isolated (legacy behavior).\n *\n * Can be a direct `HandlerRegistry` or a zero-arg getter — use the getter\n * form when the registry is assigned to the graph AFTER the executor is\n * constructed (the current `Run.create` flow sets `handlerRegistry`\n * post-`createWorkflow`, so `createAgentNode` must capture lazily).\n */\n parentHandlerRegistry?: HandlerRegistry | (() => HandlerRegistry | undefined);\n};\n\nexport class SubagentExecutor {\n private readonly configs: Map<string, ResolvedSubagentConfig>;\n private readonly parentSignal?: AbortSignal;\n private readonly hookRegistry?: HookRegistry;\n private readonly parentRunId: string;\n private readonly parentAgentId?: string;\n private readonly tokenCounter?: TokenCounter;\n private readonly maxDepth: number;\n private readonly createChildGraph: ChildGraphFactory;\n private readonly resolveParentHandlerRegistry?: () =>\n | HandlerRegistry\n | undefined;\n\n constructor(options: SubagentExecutorOptions) {\n this.configs = options.configs;\n this.parentSignal = options.parentSignal;\n this.hookRegistry = options.hookRegistry;\n this.parentRunId = options.parentRunId;\n this.parentAgentId = options.parentAgentId;\n this.tokenCounter = options.tokenCounter;\n this.maxDepth = options.maxDepth ?? 1;\n this.createChildGraph = options.createChildGraph;\n const rawRegistry = options.parentHandlerRegistry;\n if (typeof rawRegistry === 'function') {\n this.resolveParentHandlerRegistry = rawRegistry;\n } else if (rawRegistry != null) {\n this.resolveParentHandlerRegistry = (): HandlerRegistry => rawRegistry;\n }\n }\n\n /** Snapshot of the parent's registry at the moment a subagent is dispatched. */\n private getParentHandlerRegistry(): HandlerRegistry | undefined {\n return this.resolveParentHandlerRegistry?.();\n }\n\n async execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult> {\n const { description, subagentType, threadId, parentToolCallId } = params;\n const config = this.configs.get(subagentType);\n\n if (!config) {\n const available = [...this.configs.keys()].join(', ');\n return {\n content: `Error: Unknown subagent type \"${subagentType}\". Available types: ${available}`,\n messages: [],\n };\n }\n\n if (this.maxDepth <= 0) {\n return {\n content: 'Error: Maximum subagent nesting depth exceeded.',\n messages: [],\n };\n }\n\n const childAgentId =\n config.agentInputs.agentId ||\n `${this.parentAgentId ?? 'agent'}_sub_${nanoid(8)}`;\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStart', this.parentRunId) === true\n ) {\n const hookResult = await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStart',\n runId: this.parentRunId,\n threadId,\n parentAgentId: this.parentAgentId,\n agentId: childAgentId,\n agentType: subagentType,\n inputs: [new HumanMessage(description)],\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch((): AggregatedHookResult => HOOK_FALLBACK);\n\n /**\n * `ask` is treated identically to `deny` in the subagent context:\n * subagents are non-interactive, so there is no prompt path for `ask`.\n * Both decisions block execution and return a \"Blocked\" tool result.\n */\n if (hookResult.decision === 'deny' || hookResult.decision === 'ask') {\n return {\n content: `Blocked: ${hookResult.reason ?? 'Blocked by hook'}`,\n messages: [],\n };\n }\n }\n\n const parentRegistry = this.getParentHandlerRegistry();\n const forwardingEnabled = parentRegistry != null;\n /**\n * Keep `toolDefinitions` only when the host has actually wired an\n * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,\n * so treating any registry as \"forwarding enabled\" would leak\n * `toolDefinitions` into children whose hosts cannot execute them — the\n * child's `ToolNode` batch promise would hang forever with no handler to\n * resolve/reject. Gating on the tool-execute handler preserves the\n * recoverable \"no tools\" path for registry-but-no-handler configs.\n */\n const hasToolExecuteHandler =\n parentRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) != null;\n const childInputs = buildChildInputs(\n config,\n childAgentId,\n this.maxDepth,\n /* keepToolDefinitions */ hasToolExecuteHandler\n );\n const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;\n const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;\n\n const childGraph = this.createChildGraph({\n runId: childRunId,\n signal: this.parentSignal,\n agents: [childInputs],\n tokenCounter: this.tokenCounter,\n });\n\n const forwarder = forwardingEnabled\n ? this.createForwarderCallback({\n parentRegistry: parentRegistry!,\n subagentType,\n subagentAgentId: childAgentId,\n childRunId,\n parentToolCallId,\n })\n : undefined;\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'start',\n label: `Subagent \"${subagentType}\" started`,\n });\n }\n\n let result: { messages: BaseMessage[] };\n try {\n const workflow = childGraph.createWorkflow();\n /**\n * When `parentHandlerRegistry` is provided (forwarding mode), attach a\n * lightweight callback that intercepts the child's `on_custom_event`\n * dispatches and routes them to the parent's registry — either as\n * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE\n * envelopes. Native LangChain streaming events (on_chat_model_stream,\n * etc.) still do NOT propagate to the parent's outer streamEvents\n * iterator — the `callbacks` array REPLACES the inherited chain, so\n * parent handlers won't receive child stream chunks and raise \"No\n * agent context found\" lookups on the parent's agentContexts map.\n *\n * When no registry is provided (legacy isolation), `callbacks: []`\n * fully detaches the child.\n *\n * `runName` gives the child a distinct LangSmith trace root (avoids\n * nested trace pollution).\n */\n const callbacks: Callbacks = forwarder ? [forwarder] : [];\n /**\n * Inherit the parent's `configurable` verbatim — host-set fields\n * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-\n * identity fields (`run_id`, `parent_run_id`, `thread_id`) all\n * propagate.\n *\n * Run-identity propagation is intentional and matches the\n * convention this executor itself already uses for `SubagentStart`\n * / `SubagentStop` hooks (`sessionId: this.parentRunId`): the\n * subagent runs under the parent's session scope, not its own.\n * Forwarding `run_id` / `parent_run_id` / `thread_id` makes\n * `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),\n * `ToolOutputReferenceRegistry` keying, and trace lineage all\n * resolve to the parent's session for tools dispatched from the\n * subagent — so `PreToolUse` / `PostToolUse` hooks the host\n * registered against the parent's run fire for subagent tool\n * calls too. \"Same run\" matches the user-perceptual mental model.\n *\n * `thread_id` falls back to `childRunId` only when the parent\n * didn't supply one (legacy behavior preserved for hosts that\n * never set thread_id).\n *\n * NOTE: a future revision will likely make this configurable per\n * spawn type — e.g. a background / async subagent that runs after\n * the parent's run completes wants isolation, not inheritance.\n * For now the inheritance path matches LibreChat's primary use\n * case (synchronous subagents within a single user turn).\n */\n const inheritedConfigurable: Record<string, unknown> =\n params.parentConfigurable ?? {};\n result = await workflow.invoke(\n { messages: [new HumanMessage(description)] },\n {\n recursionLimit: maxTurns * RECURSION_MULTIPLIER,\n signal: this.parentSignal,\n callbacks,\n runName: `subagent:${subagentType}`,\n configurable: {\n thread_id: childRunId,\n ...inheritedConfigurable,\n },\n }\n );\n } catch (error) {\n const errorMessage = truncateErrorMessage(error);\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'error',\n label: `Subagent \"${subagentType}\" errored: ${errorMessage}`,\n data: { message: errorMessage },\n });\n }\n childGraph.clearHeavyState();\n return {\n content: `Subagent error: ${errorMessage}`,\n messages: [],\n };\n }\n\n const filteredContent = filterSubagentResult(result.messages);\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStop', this.parentRunId) === true\n ) {\n /**\n * Awaited (not fire-and-forget) for deterministic test synchronization\n * and consistency with PostCompact. The parent is already waiting on the\n * tool result, so the small extra latency is acceptable. Errors are\n * swallowed — SubagentStop is observational.\n */\n await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStop',\n runId: this.parentRunId,\n threadId,\n agentId: childAgentId,\n agentType: subagentType,\n messages: result.messages,\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch(() => {\n /* SubagentStop is observational — swallow errors */\n });\n }\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'stop',\n label: `Subagent \"${subagentType}\" finished`,\n });\n }\n\n childGraph.clearHeavyState();\n\n return { content: filteredContent, messages: result.messages };\n }\n\n /**\n * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the\n * parent's handler registry. Silent no-op when no parent registry is set.\n * Errors are swallowed — update events are observational.\n */\n private async emitSubagentUpdate(\n parentRegistry: HandlerRegistry,\n args: {\n childRunId: string;\n subagentType: string;\n subagentAgentId: string;\n parentToolCallId?: string;\n phase: SubagentUpdatePhase;\n data?: unknown;\n label?: string;\n }\n ): Promise<void> {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: this.parentRunId,\n subagentRunId: args.childRunId,\n subagentType: args.subagentType,\n subagentAgentId: args.subagentAgentId,\n parentAgentId: this.parentAgentId,\n parentToolCallId: args.parentToolCallId,\n phase: args.phase,\n data: args.data,\n label: args.label,\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n }\n\n /**\n * Builds a BaseCallbackHandler that intercepts the child graph's custom\n * events. Routing rules:\n * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE\n * handler (so event-driven tools work identically for child and parent).\n * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /\n * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a\n * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable\n * label, delivered to the parent's subagent-update handler.\n * - Everything else → ignored (keeps parent's UI scoped to the events it\n * cares about; host apps can extend by registering more phases).\n */\n private createForwarderCallback(args: {\n parentRegistry: HandlerRegistry;\n subagentType: string;\n subagentAgentId: string;\n childRunId: string;\n parentToolCallId?: string;\n }): BaseCallbackHandler {\n const {\n parentRegistry,\n subagentType,\n subagentAgentId,\n childRunId,\n parentToolCallId,\n } = args;\n const parentRunId = this.parentRunId;\n const parentAgentId = this.parentAgentId;\n\n const wrap = async (\n eventName: string,\n phase: SubagentUpdatePhase,\n data: unknown\n ): Promise<void> => {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: parentRunId,\n subagentRunId: childRunId,\n subagentType,\n subagentAgentId,\n parentAgentId,\n parentToolCallId,\n phase,\n data,\n label: summarizeEvent(eventName, data),\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n };\n\n const handler = BaseCallbackHandler.fromMethods({\n [Callback.CUSTOM_EVENT]: async (\n eventName: string,\n data: unknown\n ): Promise<void> => {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const toolHandler = parentRegistry.getHandler(\n GraphEvents.ON_TOOL_EXECUTE\n );\n if (toolHandler) {\n await toolHandler.handle(\n GraphEvents.ON_TOOL_EXECUTE,\n data as ToolExecuteBatchRequest\n );\n }\n /**\n * We also surface a short notice in the subagent-update stream so\n * the UI can show \"calling <tool>\" for each tool the child spawns.\n */\n await wrap(eventName, 'run_step', data);\n return;\n }\n\n if (eventName === GraphEvents.ON_RUN_STEP) {\n await wrap(eventName, 'run_step', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {\n await wrap(eventName, 'run_step_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n await wrap(eventName, 'run_step_completed', data);\n return;\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n await wrap(eventName, 'message_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_REASONING_DELTA) {\n await wrap(eventName, 'reasoning_delta', data);\n return;\n }\n },\n });\n /**\n * `awaitHandlers = true` is required so the child's `ToolNode` actually\n * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves\n * the batch request. The same flag applies to observational events\n * (message_delta, run_step, …), which means a slow\n * `ON_SUBAGENT_UPDATE` handler on the host serializes the child\n * stream. If host-side latency becomes a concern, a future\n * refinement could split operational and observational events into\n * separate callback handlers with distinct await semantics.\n */\n handler.awaitHandlers = true;\n return handler;\n }\n}\n\n/**\n * Produces a short single-line label for an arbitrary forwarded child event.\n * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show\n * a compact status ticker without parsing the raw payload.\n */\nexport function summarizeEvent(eventName: string, data: unknown): string {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const req = data as { toolCalls?: Array<{ name?: string }> };\n const names = (req.toolCalls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0 ? `Calling ${names.join(', ')}` : 'Calling tool';\n }\n if (eventName === GraphEvents.ON_RUN_STEP) {\n const step = data as {\n type?: string;\n stepDetails?: { type?: string; tool_calls?: Array<{ name?: string }> };\n };\n const detailType = step.stepDetails?.type ?? step.type ?? 'step';\n if (detailType === 'tool_calls') {\n const names = (step.stepDetails?.tool_calls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0\n ? `Using tool: ${names.join(', ')}`\n : 'Planning tool call';\n }\n if (detailType === 'message_creation') {\n return 'Thinking…';\n }\n return `Step: ${detailType}`;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const step = data as {\n result?: {\n type?: string;\n tool_call?: { name?: string; output?: string };\n };\n };\n const tool = step.result?.tool_call;\n if (tool?.name != null && tool.name !== '') {\n return `Tool ${tool.name} complete`;\n }\n return 'Step complete';\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n return 'Streaming…';\n }\n return eventName;\n}\n\n/**\n * Walk messages from last to first, returning the text content of the most\n * recent AIMessage that has any. Non-text blocks (tool_use, thinking,\n * redacted_thinking, tool_result) are stripped. If the last AIMessage is\n * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk\n * continues to earlier AIMessages so partial progress is salvaged — this\n * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.\n * Returns \"Task completed\" only when no AIMessage in the history contains\n * any text.\n */\nexport function filterSubagentResult(messages: BaseMessage[]): string {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]._getType() !== 'ai') {\n continue;\n }\n\n const content = messages[i].content;\n\n if (typeof content === 'string') {\n if (content) return content;\n continue;\n }\n\n if (!Array.isArray(content)) {\n continue;\n }\n\n const textParts: string[] = [];\n for (const block of content) {\n if (typeof block === 'string') {\n textParts.push(block);\n } else if ('type' in block && block.type === 'text' && 'text' in block) {\n textParts.push(block.text as string);\n }\n }\n\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return 'Task completed';\n}\n\n/**\n * Resolve self-spawn configs by filling in agentInputs from the parent context.\n * Returns configs with agentInputs guaranteed present. Throws on duplicate\n * `type` values to prevent silent config shadowing.\n */\nexport function resolveSubagentConfigs(\n configs: SubagentConfig[],\n parentContext: AgentContext\n): ResolvedSubagentConfig[] {\n const resolved = configs\n .map((config) => {\n if (config.agentInputs != null) {\n return config as ResolvedSubagentConfig;\n }\n if (config.self !== true || parentContext._sourceInputs == null) {\n return null;\n }\n return {\n ...config,\n agentInputs: { ...parentContext._sourceInputs },\n } as ResolvedSubagentConfig;\n })\n .filter((c): c is ResolvedSubagentConfig => c != null);\n\n const seenTypes = new Set<string>();\n for (const config of resolved) {\n if (seenTypes.has(config.type)) {\n throw new Error(\n `Duplicate subagent type \"${config.type}\". Each SubagentConfig must have a unique \"type\" field.`\n );\n }\n seenTypes.add(config.type);\n }\n\n return resolved;\n}\n\n/**\n * Build child AgentInputs from a resolved config, stripping nesting and\n * (optionally) event-driven fields. When `allowNested: true`, the child's\n * `maxSubagentDepth` is decremented so that depth is consumed as the call\n * chain deepens across graph boundaries — the parent's executor-level check\n * alone cannot see into the child graph's separate executor.\n *\n * When `keepToolDefinitions` is `true`, the child retains the parent's\n * `toolDefinitions` so event-driven tools remain usable. This is only safe\n * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a\n * registered handler — otherwise the child will hang on tool dispatch.\n *\n * @remarks Advanced utility: exported primarily for testing and by\n * {@link SubagentExecutor}. Host applications configuring subagents should\n * not need to call this directly — it is invoked internally when a subagent\n * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,\n * child's decremented `maxSubagentDepth` on the returned inputs) is the\n * mechanism that bounds nesting across graph boundaries; callers must\n * respect it.\n */\nexport function buildChildInputs(\n config: ResolvedSubagentConfig,\n childAgentId: string,\n parentMaxDepth: number,\n keepToolDefinitions: boolean = false\n): AgentInputs {\n const { agentInputs } = config;\n const childInputs: AgentInputs = {\n ...agentInputs,\n agentId: childAgentId,\n toolDefinitions: keepToolDefinitions\n ? agentInputs.toolDefinitions\n : undefined,\n /**\n * Subagents run in an isolated context by contract. Parent-run-scoped\n * fields that would otherwise survive the shallow-spread clone — the\n * cross-run conversation summary and the prior-turn tool-discovery\n * set — are cleared here so the child starts fresh. Host applications\n * that want a subagent to see parent context must thread it in\n * explicitly (e.g. via the `description` argument to the subagent\n * tool), not via inherited state.\n */\n initialSummary: undefined,\n discoveredTools: undefined,\n };\n\n if (config.allowNested === true) {\n childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);\n } else {\n childInputs.subagentConfigs = undefined;\n childInputs.maxSubagentDepth = undefined;\n }\n\n return childInputs;\n}\n\nfunction truncateErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n if (message.length <= ERROR_MESSAGE_MAX_CHARS) {\n return message;\n }\n return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubagentExecutor.mjs","sources":["../../../../src/tools/subagent/SubagentExecutor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type {\n AgentInputs,\n MessageDeltaEvent,\n ProcessedToolCall,\n ReasoningDeltaEvent,\n RunStep,\n RunStepDeltaEvent,\n StandardGraphInput,\n ResolvedSubagentConfig,\n StepCompleted,\n SubagentConfig,\n SubagentUpdateEvent,\n SubagentUpdatePhase,\n ToolExecuteBatchRequest,\n ToolCallDelta,\n TokenCounter,\n} from '@/types';\nimport type { AggregatedHookResult, HookRegistry } from '@/hooks';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type { StandardGraph } from '@/graphs/Graph';\nimport { GraphEvents, Callback, StepTypes } from '@/common';\nimport type { HandlerRegistry } from '@/events';\nimport { executeHooks } from '@/hooks';\n\nconst DEFAULT_MAX_TURNS = 25;\nconst RECURSION_MULTIPLIER = 3;\nconst ERROR_MESSAGE_MAX_CHARS = 200;\nconst MAX_PENDING_SUBAGENT_UPDATES = 64;\n\nconst HOOK_FALLBACK: AggregatedHookResult = Object.freeze({\n additionalContexts: [] as string[],\n errors: [] as string[],\n});\n\ntype SanitizedSubagentToolCall = {\n id: string;\n name: string;\n args?: ToolExecuteBatchRequest['toolCalls'][number]['args'];\n};\n\ntype SanitizedSubagentToolExecuteData = {\n toolCalls: SanitizedSubagentToolCall[];\n agentId?: string;\n};\n\ntype SanitizedRunStep = Partial<\n Pick<\n RunStep,\n | 'agentId'\n | 'groupId'\n | 'id'\n | 'index'\n | 'runId'\n | 'stepIndex'\n | 'summary'\n | 'type'\n | 'usage'\n >\n> & {\n stepDetails?: SanitizedStepDetails;\n};\n\ntype SanitizedStepDetails =\n | {\n type: StepTypes.MESSAGE_CREATION;\n message_creation?: {\n message_id?: string;\n };\n }\n | {\n type: StepTypes.TOOL_CALLS;\n tool_calls?: SanitizedAgentToolCall[];\n };\n\ntype SanitizedAgentToolCall = {\n id?: string;\n name?: string;\n args?: string | object;\n type?: string;\n function?: {\n name?: string;\n arguments?: string | object;\n };\n};\n\ntype SanitizedRunStepDelta = Partial<Pick<RunStepDeltaEvent, 'id'>> & {\n delta?: SanitizedToolCallDelta;\n};\n\ntype SanitizedToolCallDelta = Partial<\n Pick<ToolCallDelta, 'auth' | 'expires_at' | 'summary' | 'type'>\n> & {\n tool_calls?: SanitizedAgentToolCall[];\n};\n\ntype SanitizedStepCompleted =\n | {\n id?: string;\n index?: number;\n type: 'tool_call';\n tool_call?: SanitizedProcessedToolCall;\n }\n | {\n type: 'summary';\n summary?: Extract<StepCompleted, { type: 'summary' }>['summary'];\n };\n\ntype SanitizedProcessedToolCall = Partial<\n Pick<ProcessedToolCall, 'args' | 'id' | 'name' | 'output' | 'progress'>\n>;\n\ntype SanitizedRunStepCompleted = {\n result?: SanitizedStepCompleted;\n};\n\ntype SanitizedMessageDelta = Partial<Pick<MessageDeltaEvent, 'id'>> & {\n delta?: {\n content?: MessageDeltaEvent['delta']['content'];\n tool_call_ids?: MessageDeltaEvent['delta']['tool_call_ids'];\n };\n};\n\ntype SanitizedReasoningDelta = Partial<Pick<ReasoningDeltaEvent, 'id'>> & {\n delta?: {\n content?: ReasoningDeltaEvent['delta']['content'];\n };\n};\n\ntype QueuedSubagentUpdate = {\n eventName: string;\n phase: SubagentUpdatePhase;\n data: unknown;\n};\n\ntype ForwarderCallback = {\n handler: BaseCallbackHandler;\n drain: () => Promise<void>;\n};\n\nconst LANGGRAPH_RUNTIME_CONFIG_PREFIX = '__pregel_';\nconst LANGGRAPH_CHECKPOINT_CONFIG_KEYS = new Set([\n 'checkpoint_id',\n 'checkpoint_map',\n 'checkpoint_ns',\n]);\n\nexport type SubagentExecuteParams = {\n description: string;\n subagentType: string;\n threadId?: string;\n /**\n * Parent-side `tool_call_id` of the `subagent` tool invocation that\n * triggered this execution. Surfaced on {@link SubagentUpdateEvent} so\n * hosts can correlate child updates back to the originating tool call\n * without relying on event ordering heuristics.\n */\n parentToolCallId?: string;\n /**\n * Snapshot of the parent invocation's host `config.configurable` at\n * the spawn-tool call site. Host-set fields (`requestBody`, `user`,\n * `userMCPAuthMap`, etc.) propagate into the child workflow's\n * `configurable` — fixing MCP body-placeholder substitution and\n * per-user lookups for subagent tool calls. LangGraph runtime keys\n * (`__pregel_*`, checkpoint bookkeeping) are intentionally not\n * inherited; the child graph recreates its own runtime config.\n *\n * Inheritance details (verified empirically against LangGraph):\n * - host-set keys propagate as-is into the child's tool dispatches;\n * - `thread_id` propagates (with `childRunId` as a fallback when\n * parent did not supply one) — matches the \"subagent is part of\n * the same conversation\" mental model and aligns with the\n * `sessionId: this.parentRunId` convention this executor already\n * uses for `SubagentStart` / `SubagentStop` hooks;\n * - `parent_run_id` propagates when the host put it on parent's\n * configurable;\n * - `run_id` is *overwritten by the LangGraph runtime* at child\n * invoke time regardless of what we forward — child's tool\n * dispatches see the child graph's runtime runId in\n * `configurable.run_id`, not the parent's. Hosts that need\n * parent-scoped run identity for downstream consumers should\n * plumb it via a host-defined key (e.g. `requestBody.messageId`),\n * not `run_id`.\n *\n * A future revision will likely make this inheritance configurable\n * per spawn type — background / async subagents may want isolation\n * rather than sharing parent's host context.\n */\n parentConfigurable?: Record<string, unknown>;\n};\n\nexport type SubagentExecuteResult = {\n content: string;\n messages: BaseMessage[];\n};\n\n/**\n * Factory that constructs a child graph for subagent execution. Injected\n * rather than imported so that `SubagentExecutor` does not have a runtime\n * dependency on `StandardGraph` — this avoids a circular dependency between\n * `src/graphs/Graph.ts` and `src/tools/subagent/` that would otherwise break\n * Rollup's chunking under `preserveModules`.\n */\nexport type ChildGraphFactory = (input: StandardGraphInput) => StandardGraph;\n\nexport type SubagentExecutorOptions = {\n configs: Map<string, ResolvedSubagentConfig>;\n parentSignal?: AbortSignal;\n hookRegistry?: HookRegistry;\n parentRunId: string;\n parentAgentId?: string;\n tokenCounter?: TokenCounter;\n /** Remaining nesting budget. 0 or negative blocks execution. */\n maxDepth?: number;\n /**\n * Factory for constructing the isolated child graph. Callers pass\n * `(input) => new StandardGraph(input)` — injected to break a circular\n * module dependency.\n */\n createChildGraph: ChildGraphFactory;\n /**\n * Parent's event handler registry. When provided, child-graph events are\n * forwarded through this registry so hosts can:\n * (a) execute event-driven tools (`ON_TOOL_EXECUTE` routed to parent's handler),\n * (b) surface child activity to a UI via wrapped {@link GraphEvents.ON_SUBAGENT_UPDATE}.\n * When omitted, the child runs fully isolated (legacy behavior).\n *\n * Can be a direct `HandlerRegistry` or a zero-arg getter — use the getter\n * form when the registry is assigned to the graph AFTER the executor is\n * constructed (the current `Run.create` flow sets `handlerRegistry`\n * post-`createWorkflow`, so `createAgentNode` must capture lazily).\n */\n parentHandlerRegistry?: HandlerRegistry | (() => HandlerRegistry | undefined);\n};\n\nexport class SubagentExecutor {\n private readonly configs: Map<string, ResolvedSubagentConfig>;\n private readonly parentSignal?: AbortSignal;\n private readonly hookRegistry?: HookRegistry;\n private readonly parentRunId: string;\n private readonly parentAgentId?: string;\n private readonly tokenCounter?: TokenCounter;\n private readonly maxDepth: number;\n private readonly createChildGraph: ChildGraphFactory;\n private readonly resolveParentHandlerRegistry?: () =>\n | HandlerRegistry\n | undefined;\n\n constructor(options: SubagentExecutorOptions) {\n this.configs = options.configs;\n this.parentSignal = options.parentSignal;\n this.hookRegistry = options.hookRegistry;\n this.parentRunId = options.parentRunId;\n this.parentAgentId = options.parentAgentId;\n this.tokenCounter = options.tokenCounter;\n this.maxDepth = options.maxDepth ?? 1;\n this.createChildGraph = options.createChildGraph;\n const rawRegistry = options.parentHandlerRegistry;\n if (typeof rawRegistry === 'function') {\n this.resolveParentHandlerRegistry = rawRegistry;\n } else if (rawRegistry != null) {\n this.resolveParentHandlerRegistry = (): HandlerRegistry => rawRegistry;\n }\n }\n\n /** Snapshot of the parent's registry at the moment a subagent is dispatched. */\n private getParentHandlerRegistry(): HandlerRegistry | undefined {\n return this.resolveParentHandlerRegistry?.();\n }\n\n async execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult> {\n const { description, subagentType, threadId, parentToolCallId } = params;\n const config = this.configs.get(subagentType);\n\n if (!config) {\n const available = [...this.configs.keys()].join(', ');\n return {\n content: `Error: Unknown subagent type \"${subagentType}\". Available types: ${available}`,\n messages: [],\n };\n }\n\n if (this.maxDepth <= 0) {\n return {\n content: 'Error: Maximum subagent nesting depth exceeded.',\n messages: [],\n };\n }\n\n const childAgentId =\n config.agentInputs.agentId ||\n `${this.parentAgentId ?? 'agent'}_sub_${nanoid(8)}`;\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStart', this.parentRunId) === true\n ) {\n const hookResult = await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStart',\n runId: this.parentRunId,\n threadId,\n parentAgentId: this.parentAgentId,\n agentId: childAgentId,\n agentType: subagentType,\n inputs: [new HumanMessage(description)],\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch((): AggregatedHookResult => HOOK_FALLBACK);\n\n /**\n * `ask` is treated identically to `deny` in the subagent context:\n * subagents are non-interactive, so there is no prompt path for `ask`.\n * Both decisions block execution and return a \"Blocked\" tool result.\n */\n if (hookResult.decision === 'deny' || hookResult.decision === 'ask') {\n return {\n content: `Blocked: ${hookResult.reason ?? 'Blocked by hook'}`,\n messages: [],\n };\n }\n }\n\n const parentRegistry = this.getParentHandlerRegistry();\n const forwardingEnabled = parentRegistry != null;\n /**\n * Keep `toolDefinitions` only when the host has actually wired an\n * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,\n * so treating any registry as \"forwarding enabled\" would leak\n * `toolDefinitions` into children whose hosts cannot execute them — the\n * child's `ToolNode` batch promise would hang forever with no handler to\n * resolve/reject. Gating on the tool-execute handler preserves the\n * recoverable \"no tools\" path for registry-but-no-handler configs.\n */\n const hasToolExecuteHandler =\n parentRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) != null;\n const childInputs = buildChildInputs(\n config,\n childAgentId,\n this.maxDepth,\n /* keepToolDefinitions */ hasToolExecuteHandler\n );\n const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;\n const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;\n\n const childGraph = this.createChildGraph({\n runId: childRunId,\n signal: this.parentSignal,\n agents: [childInputs],\n tokenCounter: this.tokenCounter,\n });\n\n const forwarding = forwardingEnabled\n ? this.createForwarderCallback({\n parentRegistry: parentRegistry!,\n subagentType,\n subagentAgentId: childAgentId,\n childRunId,\n parentToolCallId,\n })\n : undefined;\n const forwarder = forwarding?.handler;\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'start',\n label: `Subagent \"${subagentType}\" started`,\n });\n }\n\n let result: { messages: BaseMessage[] };\n try {\n const workflow = childGraph.createWorkflow();\n /**\n * When `parentHandlerRegistry` is provided (forwarding mode), attach a\n * lightweight callback that intercepts the child's `on_custom_event`\n * dispatches and routes them to the parent's registry — either as\n * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE\n * envelopes. Native LangChain streaming events (on_chat_model_stream,\n * etc.) still do NOT propagate to the parent's outer streamEvents\n * iterator — the `callbacks` array REPLACES the inherited chain, so\n * parent handlers won't receive child stream chunks and raise \"No\n * agent context found\" lookups on the parent's agentContexts map.\n *\n * When no registry is provided (legacy isolation), `callbacks: []`\n * fully detaches the child.\n *\n * `runName` gives the child a distinct LangSmith trace root (avoids\n * nested trace pollution).\n */\n const callbacks: Callbacks = forwarder ? [forwarder] : [];\n /**\n * Inherit the parent's host `configurable` — host-set fields\n * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-\n * identity fields (`run_id`, `parent_run_id`, `thread_id`) all\n * propagate. LangGraph's own runtime keys are excluded because the\n * child graph creates its own scratchpad/checkpoint/abort plumbing.\n *\n * Run-identity propagation is intentional and matches the\n * convention this executor itself already uses for `SubagentStart`\n * / `SubagentStop` hooks (`sessionId: this.parentRunId`): the\n * subagent runs under the parent's session scope, not its own.\n * Forwarding `run_id` / `parent_run_id` / `thread_id` makes\n * `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),\n * `ToolOutputReferenceRegistry` keying, and trace lineage all\n * resolve to the parent's session for tools dispatched from the\n * subagent — so `PreToolUse` / `PostToolUse` hooks the host\n * registered against the parent's run fire for subagent tool\n * calls too. \"Same run\" matches the user-perceptual mental model.\n *\n * `thread_id` falls back to `childRunId` only when the parent\n * didn't supply one (legacy behavior preserved for hosts that\n * never set thread_id).\n *\n * NOTE: a future revision will likely make this configurable per\n * spawn type — e.g. a background / async subagent that runs after\n * the parent's run completes wants isolation, not inheritance.\n * For now the inheritance path matches LibreChat's primary use\n * case (synchronous subagents within a single user turn).\n */\n const inheritedConfigurable: Record<string, unknown> =\n sanitizeChildConfigurable(params.parentConfigurable);\n result = await workflow.invoke(\n { messages: [new HumanMessage(description)] },\n {\n recursionLimit: maxTurns * RECURSION_MULTIPLIER,\n signal: this.parentSignal,\n callbacks,\n runName: `subagent:${subagentType}`,\n configurable: {\n thread_id: childRunId,\n ...inheritedConfigurable,\n },\n }\n );\n } catch (error) {\n const errorMessage = truncateErrorMessage(error);\n if (forwarder) {\n await forwarding.drain();\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'error',\n label: `Subagent \"${subagentType}\" errored: ${errorMessage}`,\n data: { message: errorMessage },\n });\n }\n childGraph.clearHeavyState();\n return {\n content: `Subagent error: ${errorMessage}`,\n messages: [],\n };\n }\n\n const filteredContent = filterSubagentResult(result.messages);\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStop', this.parentRunId) === true\n ) {\n /**\n * Awaited (not fire-and-forget) for deterministic test synchronization\n * and consistency with PostCompact. The parent is already waiting on the\n * tool result, so the small extra latency is acceptable. Errors are\n * swallowed — SubagentStop is observational.\n */\n await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStop',\n runId: this.parentRunId,\n threadId,\n agentId: childAgentId,\n agentType: subagentType,\n messages: result.messages,\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch(() => {\n /* SubagentStop is observational — swallow errors */\n });\n }\n\n if (forwarder) {\n await forwarding.drain();\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'stop',\n label: `Subagent \"${subagentType}\" finished`,\n });\n }\n\n childGraph.clearHeavyState();\n\n return { content: filteredContent, messages: result.messages };\n }\n\n /**\n * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the\n * parent's handler registry. Silent no-op when no parent registry is set.\n * Errors are swallowed — update events are observational.\n */\n private async emitSubagentUpdate(\n parentRegistry: HandlerRegistry,\n args: {\n childRunId: string;\n subagentType: string;\n subagentAgentId: string;\n parentToolCallId?: string;\n phase: SubagentUpdatePhase;\n data?: unknown;\n label?: string;\n }\n ): Promise<void> {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: this.parentRunId,\n subagentRunId: args.childRunId,\n subagentType: args.subagentType,\n subagentAgentId: args.subagentAgentId,\n parentAgentId: this.parentAgentId,\n parentToolCallId: args.parentToolCallId,\n phase: args.phase,\n data: args.data,\n label: args.label,\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n }\n\n /**\n * Builds a BaseCallbackHandler that intercepts the child graph's custom\n * events. Routing rules:\n * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE\n * handler (so event-driven tools work identically for child and parent).\n * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /\n * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a\n * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable\n * label, delivered to the parent's subagent-update handler.\n * - Everything else → ignored (keeps parent's UI scoped to the events it\n * cares about; host apps can extend by registering more phases).\n */\n private createForwarderCallback(args: {\n parentRegistry: HandlerRegistry;\n subagentType: string;\n subagentAgentId: string;\n childRunId: string;\n parentToolCallId?: string;\n }): ForwarderCallback {\n const {\n parentRegistry,\n subagentType,\n subagentAgentId,\n childRunId,\n parentToolCallId,\n } = args;\n const parentRunId = this.parentRunId;\n const parentAgentId = this.parentAgentId;\n\n const wrap = async (\n eventName: string,\n phase: SubagentUpdatePhase,\n data: unknown\n ): Promise<void> => {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n try {\n const event: SubagentUpdateEvent = {\n runId: parentRunId,\n subagentRunId: childRunId,\n subagentType,\n subagentAgentId,\n parentAgentId,\n parentToolCallId,\n phase,\n data: sanitizeForwardedSubagentUpdateData(eventName, data),\n label: summarizeEvent(eventName, data),\n timestamp: new Date().toISOString(),\n };\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n };\n\n const queuedUpdates: QueuedSubagentUpdate[] = [];\n let drainPromise: Promise<void> | undefined;\n\n const enqueue = (update: QueuedSubagentUpdate): void => {\n if (queuedUpdates.length >= MAX_PENDING_SUBAGENT_UPDATES) {\n const dropIndex = queuedUpdates.findIndex((queued) =>\n isDroppableSubagentUpdatePhase(queued.phase)\n );\n if (dropIndex >= 0) {\n queuedUpdates.splice(dropIndex, 1);\n } else if (isDroppableSubagentUpdatePhase(update.phase)) {\n return;\n }\n }\n queuedUpdates.push(update);\n };\n\n const drain = async (): Promise<void> => {\n if (drainPromise != null) {\n await drainPromise;\n return;\n }\n drainPromise = (async (): Promise<void> => {\n while (queuedUpdates.length > 0) {\n const update = queuedUpdates.shift();\n if (update == null) {\n continue;\n }\n await wrap(update.eventName, update.phase, update.data);\n }\n })();\n try {\n await drainPromise;\n } finally {\n drainPromise = undefined;\n if (queuedUpdates.length > 0) {\n await drain();\n }\n }\n };\n\n const scheduleWrap = (\n eventName: string,\n phase: SubagentUpdatePhase,\n data: unknown\n ): void => {\n enqueue({ eventName, phase, data });\n void drain();\n };\n\n const handler = BaseCallbackHandler.fromMethods({\n [Callback.CUSTOM_EVENT]: async (\n eventName: string,\n data: unknown\n ): Promise<void> => {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const toolHandler = parentRegistry.getHandler(\n GraphEvents.ON_TOOL_EXECUTE\n );\n if (toolHandler) {\n await toolHandler.handle(\n GraphEvents.ON_TOOL_EXECUTE,\n data as ToolExecuteBatchRequest\n );\n }\n /**\n * We also surface a short notice in the subagent-update stream so\n * the UI can show \"calling <tool>\" for each tool the child spawns.\n */\n scheduleWrap(eventName, 'run_step', data);\n return;\n }\n\n if (eventName === GraphEvents.ON_RUN_STEP) {\n scheduleWrap(eventName, 'run_step', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {\n scheduleWrap(eventName, 'run_step_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n scheduleWrap(eventName, 'run_step_completed', data);\n return;\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n scheduleWrap(eventName, 'message_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_REASONING_DELTA) {\n scheduleWrap(eventName, 'reasoning_delta', data);\n return;\n }\n },\n });\n /**\n * `awaitHandlers = true` is required so the child's `ToolNode` actually\n * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves\n * the batch request. Observational `ON_SUBAGENT_UPDATE` calls are queued\n * behind a bounded sequential dispatcher so host UI publication cannot\n * backpressure each child emission or run unbounded concurrent publishes.\n * The executor drains this queue before terminal stop/error envelopes to\n * preserve phase ordering.\n */\n handler.awaitHandlers = true;\n return { handler, drain };\n }\n}\n\nfunction sanitizeChildConfigurable(\n parentConfigurable: Record<string, unknown> | undefined\n): Record<string, unknown> {\n if (parentConfigurable == null) {\n return {};\n }\n return Object.fromEntries(\n Object.entries(parentConfigurable).filter(\n ([key]) => !isLangGraphRuntimeConfigKey(key)\n )\n );\n}\n\nfunction isLangGraphRuntimeConfigKey(key: string): boolean {\n return (\n key.startsWith(LANGGRAPH_RUNTIME_CONFIG_PREFIX) ||\n LANGGRAPH_CHECKPOINT_CONFIG_KEYS.has(key)\n );\n}\n\nexport function sanitizeForwardedSubagentUpdateData(\n eventName: string,\n data: unknown\n): unknown {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n return sanitizeToolExecuteUpdateData(data);\n }\n if (eventName === GraphEvents.ON_RUN_STEP) {\n return sanitizeRunStepUpdateData(data);\n }\n if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {\n return sanitizeRunStepDeltaUpdateData(data);\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n return sanitizeRunStepCompletedUpdateData(data);\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n return sanitizeMessageDeltaUpdateData(data);\n }\n if (eventName === GraphEvents.ON_REASONING_DELTA) {\n return sanitizeReasoningDeltaUpdateData(data);\n }\n return undefined;\n}\n\nfunction isDroppableSubagentUpdatePhase(phase: SubagentUpdatePhase): boolean {\n return (\n phase === 'message_delta' ||\n phase === 'reasoning_delta' ||\n phase === 'run_step_delta'\n );\n}\n\nfunction sanitizeToolExecuteUpdateData(\n data: unknown\n): SanitizedSubagentToolExecuteData {\n const request = data as Partial<ToolExecuteBatchRequest>;\n const toolCalls = Array.isArray(request.toolCalls)\n ? request.toolCalls.map(sanitizeToolCallForUpdate)\n : [];\n const sanitized: SanitizedSubagentToolExecuteData = { toolCalls };\n if (typeof request.agentId === 'string') {\n sanitized.agentId = request.agentId;\n }\n return sanitized;\n}\n\nfunction sanitizeToolCallForUpdate(\n call: ToolExecuteBatchRequest['toolCalls'][number]\n): SanitizedSubagentToolCall {\n const sanitized: SanitizedSubagentToolCall = {\n id: call.id,\n name: call.name,\n args: call.args,\n };\n return sanitized;\n}\n\nfunction sanitizeRunStepUpdateData(data: unknown): SanitizedRunStep | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const step = data as Partial<RunStep>;\n const sanitized: SanitizedRunStep = {};\n assignString(sanitized, 'agentId', step.agentId);\n assignNumber(sanitized, 'groupId', step.groupId);\n assignString(sanitized, 'id', step.id);\n assignNumber(sanitized, 'index', step.index);\n assignString(sanitized, 'runId', step.runId);\n assignNumber(sanitized, 'stepIndex', step.stepIndex);\n assignString(sanitized, 'type', step.type);\n if (step.summary !== undefined) {\n sanitized.summary = step.summary;\n }\n if (step.usage !== undefined) {\n sanitized.usage = step.usage;\n }\n sanitized.stepDetails = sanitizeStepDetails(step.stepDetails);\n return sanitized;\n}\n\nfunction sanitizeRunStepDeltaUpdateData(\n data: unknown\n): SanitizedRunStepDelta | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const event = data as Partial<RunStepDeltaEvent>;\n const sanitized: SanitizedRunStepDelta = {};\n assignString(sanitized, 'id', event.id);\n sanitized.delta = sanitizeToolCallDelta(event.delta);\n return sanitized;\n}\n\nfunction sanitizeRunStepCompletedUpdateData(\n data: unknown\n): SanitizedRunStepCompleted | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const event = data as { result?: unknown };\n return { result: sanitizeStepCompleted(event.result) };\n}\n\nfunction sanitizeMessageDeltaUpdateData(\n data: unknown\n): SanitizedMessageDelta | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const event = data as Partial<MessageDeltaEvent>;\n const sanitized: SanitizedMessageDelta = {};\n assignString(sanitized, 'id', event.id);\n if (event.delta != null) {\n sanitized.delta = {};\n if (event.delta.content !== undefined) {\n sanitized.delta.content = event.delta.content;\n }\n if (event.delta.tool_call_ids !== undefined) {\n sanitized.delta.tool_call_ids = event.delta.tool_call_ids;\n }\n }\n return sanitized;\n}\n\nfunction sanitizeReasoningDeltaUpdateData(\n data: unknown\n): SanitizedReasoningDelta | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const event = data as Partial<ReasoningDeltaEvent>;\n const sanitized: SanitizedReasoningDelta = {};\n assignString(sanitized, 'id', event.id);\n if (event.delta?.content !== undefined) {\n sanitized.delta = { content: event.delta.content };\n }\n return sanitized;\n}\n\nfunction sanitizeStepDetails(stepDetails: unknown): SanitizedStepDetails | undefined {\n if (!isObjectLike(stepDetails)) {\n return undefined;\n }\n const rawDetails = stepDetails as {\n message_creation?: { message_id?: unknown };\n tool_calls?: unknown[];\n type?: unknown;\n };\n if (rawDetails.type === StepTypes.MESSAGE_CREATION) {\n const sanitized: SanitizedStepDetails = {\n type: StepTypes.MESSAGE_CREATION,\n };\n const messageId = rawDetails.message_creation?.message_id;\n if (typeof messageId === 'string') {\n sanitized.message_creation = { message_id: messageId };\n }\n return sanitized;\n }\n if (rawDetails.type === StepTypes.TOOL_CALLS) {\n const sanitized: SanitizedStepDetails = {\n type: StepTypes.TOOL_CALLS,\n };\n if (Array.isArray(rawDetails.tool_calls)) {\n sanitized.tool_calls = rawDetails.tool_calls.map(sanitizeAgentToolCall);\n }\n return sanitized;\n }\n return undefined;\n}\n\nfunction sanitizeToolCallDelta(\n delta: ToolCallDelta | undefined\n): SanitizedToolCallDelta | undefined {\n if (!isObjectLike(delta)) {\n return undefined;\n }\n const sanitized: SanitizedToolCallDelta = {};\n assignString(sanitized, 'auth', delta.auth);\n assignNumber(sanitized, 'expires_at', delta.expires_at);\n assignString(sanitized, 'type', delta.type);\n if (delta.summary !== undefined) {\n sanitized.summary = delta.summary;\n }\n if (Array.isArray(delta.tool_calls)) {\n sanitized.tool_calls = delta.tool_calls.map(sanitizeAgentToolCall);\n }\n return sanitized;\n}\n\nfunction sanitizeStepCompleted(data: unknown): SanitizedStepCompleted | undefined {\n if (!isObjectLike(data)) {\n return undefined;\n }\n const completed = data as Partial<StepCompleted> & {\n id?: unknown;\n index?: unknown;\n tool_call?: unknown;\n };\n if (completed.type === 'summary') {\n return {\n type: 'summary',\n summary: completed.summary,\n };\n }\n if (completed.type !== 'tool_call') {\n return undefined;\n }\n const sanitized: SanitizedStepCompleted = { type: 'tool_call' };\n assignString(sanitized, 'id', completed.id);\n assignNumber(sanitized, 'index', completed.index);\n sanitized.tool_call = sanitizeProcessedToolCall(completed.tool_call);\n return sanitized;\n}\n\nfunction sanitizeProcessedToolCall(\n toolCall: unknown\n): SanitizedProcessedToolCall | undefined {\n if (!isObjectLike(toolCall)) {\n return undefined;\n }\n const call = toolCall as Partial<ProcessedToolCall>;\n const sanitized: SanitizedProcessedToolCall = {};\n assignString(sanitized, 'id', call.id);\n assignString(sanitized, 'name', call.name);\n if (call.args !== undefined) {\n sanitized.args = call.args;\n }\n assignString(sanitized, 'output', call.output);\n assignNumber(sanitized, 'progress', call.progress);\n return sanitized;\n}\n\nfunction sanitizeAgentToolCall(toolCall: unknown): SanitizedAgentToolCall {\n if (!isObjectLike(toolCall)) {\n return {};\n }\n const call = toolCall as SanitizedAgentToolCall;\n const sanitized: SanitizedAgentToolCall = {};\n assignString(sanitized, 'id', call.id);\n assignString(sanitized, 'name', call.name);\n assignString(sanitized, 'type', call.type);\n if (call.args !== undefined) {\n sanitized.args = call.args;\n }\n if (isObjectLike(call.function)) {\n const fn: SanitizedAgentToolCall['function'] = {};\n assignString(fn, 'name', call.function.name);\n if (\n typeof call.function.arguments === 'string' ||\n isObjectLike(call.function.arguments)\n ) {\n fn.arguments = call.function.arguments;\n }\n sanitized.function = fn;\n }\n return sanitized;\n}\n\nfunction isObjectLike(value: unknown): value is object {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction assignString<T extends object, K extends keyof T>(\n target: T,\n key: K,\n value: unknown\n): void {\n if (typeof value === 'string') {\n target[key] = value as T[K];\n }\n}\n\nfunction assignNumber<T extends object, K extends keyof T>(\n target: T,\n key: K,\n value: unknown\n): void {\n if (typeof value === 'number') {\n target[key] = value as T[K];\n }\n}\n\n/**\n * Produces a short single-line label for an arbitrary forwarded child event.\n * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show\n * a compact status ticker without parsing the raw payload.\n */\nexport function summarizeEvent(eventName: string, data: unknown): string {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const req = data as { toolCalls?: Array<{ name?: string }> };\n const names = (req.toolCalls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0 ? `Calling ${names.join(', ')}` : 'Calling tool';\n }\n if (eventName === GraphEvents.ON_RUN_STEP) {\n const step = data as {\n type?: string;\n stepDetails?: { type?: string; tool_calls?: Array<{ name?: string }> };\n };\n const detailType = step.stepDetails?.type ?? step.type ?? 'step';\n if (detailType === 'tool_calls') {\n const names = (step.stepDetails?.tool_calls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0\n ? `Using tool: ${names.join(', ')}`\n : 'Planning tool call';\n }\n if (detailType === 'message_creation') {\n return 'Thinking…';\n }\n return `Step: ${detailType}`;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const step = data as {\n result?: {\n type?: string;\n tool_call?: { name?: string; output?: string };\n };\n };\n const tool = step.result?.tool_call;\n if (tool?.name != null && tool.name !== '') {\n return `Tool ${tool.name} complete`;\n }\n return 'Step complete';\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n return 'Streaming…';\n }\n return eventName;\n}\n\n/**\n * Walk messages from last to first, returning the text content of the most\n * recent AIMessage that has any. Non-text blocks (tool_use, thinking,\n * redacted_thinking, tool_result) are stripped. If the last AIMessage is\n * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk\n * continues to earlier AIMessages so partial progress is salvaged — this\n * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.\n * Returns \"Task completed\" only when no AIMessage in the history contains\n * any text.\n */\nexport function filterSubagentResult(messages: BaseMessage[]): string {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]._getType() !== 'ai') {\n continue;\n }\n\n const content = messages[i].content;\n\n if (typeof content === 'string') {\n if (content) return content;\n continue;\n }\n\n if (!Array.isArray(content)) {\n continue;\n }\n\n const textParts: string[] = [];\n for (const block of content) {\n if (typeof block === 'string') {\n textParts.push(block);\n } else if ('type' in block && block.type === 'text' && 'text' in block) {\n textParts.push(block.text as string);\n }\n }\n\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return 'Task completed';\n}\n\n/**\n * Resolve self-spawn configs by filling in agentInputs from the parent context.\n * Returns configs with agentInputs guaranteed present. Throws on duplicate\n * `type` values to prevent silent config shadowing.\n */\nexport function resolveSubagentConfigs(\n configs: SubagentConfig[],\n parentContext: AgentContext\n): ResolvedSubagentConfig[] {\n const resolved = configs\n .map((config) => {\n if (config.agentInputs != null) {\n return config as ResolvedSubagentConfig;\n }\n if (config.self !== true || parentContext._sourceInputs == null) {\n return null;\n }\n return {\n ...config,\n agentInputs: { ...parentContext._sourceInputs },\n } as ResolvedSubagentConfig;\n })\n .filter((c): c is ResolvedSubagentConfig => c != null);\n\n const seenTypes = new Set<string>();\n for (const config of resolved) {\n if (seenTypes.has(config.type)) {\n throw new Error(\n `Duplicate subagent type \"${config.type}\". Each SubagentConfig must have a unique \"type\" field.`\n );\n }\n seenTypes.add(config.type);\n }\n\n return resolved;\n}\n\n/**\n * Build child AgentInputs from a resolved config, stripping nesting and\n * (optionally) event-driven fields. When `allowNested: true`, the child's\n * `maxSubagentDepth` is decremented so that depth is consumed as the call\n * chain deepens across graph boundaries — the parent's executor-level check\n * alone cannot see into the child graph's separate executor.\n *\n * When `keepToolDefinitions` is `true`, the child retains the parent's\n * `toolDefinitions` so event-driven tools remain usable. This is only safe\n * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a\n * registered handler — otherwise the child will hang on tool dispatch.\n *\n * @remarks Advanced utility: exported primarily for testing and by\n * {@link SubagentExecutor}. Host applications configuring subagents should\n * not need to call this directly — it is invoked internally when a subagent\n * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,\n * child's decremented `maxSubagentDepth` on the returned inputs) is the\n * mechanism that bounds nesting across graph boundaries; callers must\n * respect it.\n */\nexport function buildChildInputs(\n config: ResolvedSubagentConfig,\n childAgentId: string,\n parentMaxDepth: number,\n keepToolDefinitions: boolean = false\n): AgentInputs {\n const { agentInputs } = config;\n const childInputs: AgentInputs = {\n ...agentInputs,\n agentId: childAgentId,\n toolDefinitions: keepToolDefinitions\n ? agentInputs.toolDefinitions\n : undefined,\n /**\n * Subagents run in an isolated context by contract. Parent-run-scoped\n * fields that would otherwise survive the shallow-spread clone — the\n * cross-run conversation summary and the prior-turn tool-discovery\n * set — are cleared here so the child starts fresh. Host applications\n * that want a subagent to see parent context must thread it in\n * explicitly (e.g. via the `description` argument to the subagent\n * tool), not via inherited state.\n */\n initialSummary: undefined,\n discoveredTools: undefined,\n };\n\n if (config.allowNested === true) {\n childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);\n } else {\n childInputs.subagentConfigs = undefined;\n childInputs.maxSubagentDepth = undefined;\n }\n\n return childInputs;\n}\n\nfunction truncateErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n if (message.length <= ERROR_MESSAGE_MAX_CHARS) {\n return message;\n }\n return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;\n}\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import type { BaseMessage } from '@langchain/core/messages';
5
5
  import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
6
6
  import type { AnthropicInput } from '@langchain/anthropic';
7
7
  import type { Anthropic } from '@anthropic-ai/sdk';
8
- import type { AnthropicMessageCreateParams, AnthropicStreamingMessageCreateParams, AnthropicOutputConfig, AnthropicBeta, AnthropicMCPServerURLDefinition, AnthropicContextManagementConfigParam } from '@/llm/anthropic/types';
8
+ import type { AnthropicMessageCreateParams, AnthropicStreamingMessageCreateParams, AnthropicOutputConfig, AnthropicBeta, AnthropicMCPServerURLDefinition, AnthropicContextManagementConfigParam, AnthropicRequestOptions } from '@/llm/anthropic/types';
9
9
  export declare function _documentsInParams(params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams): boolean;
10
10
  export type CustomAnthropicInput = AnthropicInput & {
11
11
  _lc_stream_delay?: number;
@@ -45,6 +45,8 @@ export declare class CustomAnthropic extends ChatAnthropicMessages {
45
45
  resetTokenEvents(): void;
46
46
  setDirectFields(fields?: CustomAnthropicInput): void;
47
47
  private createGenerationChunk;
48
+ protected createStreamWithRetry(request: AnthropicStreamingMessageCreateParams, options?: AnthropicRequestOptions): ReturnType<ChatAnthropicMessages['createStreamWithRetry']>;
49
+ protected completionWithRetry(request: AnthropicMessageCreateParams, options: AnthropicRequestOptions): ReturnType<ChatAnthropicMessages['completionWithRetry']>;
48
50
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
49
51
  }
50
52
  export {};
@@ -24,3 +24,7 @@ export declare function _convertLangChainToolCallToAnthropic(toolCall: ToolCall)
24
24
  * @returns The formatted prompt.
25
25
  */
26
26
  export declare function _convertMessagesToAnthropicPayload(messages: BaseMessage[]): AnthropicMessageCreateParams;
27
+ export declare function modelDisallowsAssistantPrefill(model?: string): boolean;
28
+ export declare function stripUnsupportedAssistantPrefill<T extends Pick<AnthropicMessageCreateParams, 'messages'> & {
29
+ model?: string;
30
+ }>(request: T): T;
@@ -6,7 +6,7 @@ export declare const BashExecutionToolSchema: {
6
6
  readonly properties: {
7
7
  readonly command: {
8
8
  readonly type: "string";
9
- readonly description: "The bash command or script to execute.\n- The environment is stateless; variables and state don't persist between executions.\n- Generated files from previous executions are automatically available in \"/mnt/data/\".\n- Files from previous executions are automatically available and can be modified in place.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- Use `echo`, `printf`, or `cat` for all outputs.";
9
+ readonly description: "The bash command or script to execute.\n- The environment is stateless; variables and state don't persist between executions.\n- Prior /mnt/data files are available and can be modified in place.\n- Persist handoff artifacts in `/mnt/data` with standard extensions (.json/.txt/.csv/.tsv/.log/.parquet/.png/.jpg/.pdf/.xlsx); failed executions do not register new files; `/tmp` and odd extensions are same-call scratch only, not later-call storage.\n- Bash: multi-line files use heredoc/printf; run Python via python3 -c/heredoc, not bare Python.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- Use `echo`, `printf`, or `cat` for all outputs.";
10
10
  };
11
11
  readonly args: {
12
12
  readonly type: "array";
@@ -59,7 +59,7 @@ export declare const BashExecutionToolDefinition: {
59
59
  readonly properties: {
60
60
  readonly command: {
61
61
  readonly type: "string";
62
- readonly description: "The bash command or script to execute.\n- The environment is stateless; variables and state don't persist between executions.\n- Generated files from previous executions are automatically available in \"/mnt/data/\".\n- Files from previous executions are automatically available and can be modified in place.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- Use `echo`, `printf`, or `cat` for all outputs.";
62
+ readonly description: "The bash command or script to execute.\n- The environment is stateless; variables and state don't persist between executions.\n- Prior /mnt/data files are available and can be modified in place.\n- Persist handoff artifacts in `/mnt/data` with standard extensions (.json/.txt/.csv/.tsv/.log/.parquet/.png/.jpg/.pdf/.xlsx); failed executions do not register new files; `/tmp` and odd extensions are same-call scratch only, not later-call storage.\n- Bash: multi-line files use heredoc/printf; run Python via python3 -c/heredoc, not bare Python.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- Use `echo`, `printf`, or `cat` for all outputs.";
63
63
  };
64
64
  readonly args: {
65
65
  readonly type: "array";
@@ -72,5 +72,5 @@ export declare const BashExecutionToolDefinition: {
72
72
  readonly required: readonly ["command"];
73
73
  };
74
74
  };
75
- declare function createBashExecutionTool(params?: t.BashExecutionToolParams): DynamicStructuredTool;
75
+ declare function createBashExecutionTool(params?: t.BashExecutionToolParams | null): DynamicStructuredTool;
76
76
  export { createBashExecutionTool };
@@ -1,8 +1,15 @@
1
1
  import { DynamicStructuredTool } from '@langchain/core/tools';
2
2
  import type * as t from '@/types';
3
3
  import { Constants } from '@/common';
4
+ export { appendCodeSessionFileSummary, stripCodeSessionFileSummary, } from '@/tools/CodeSessionFileSummary';
4
5
  export declare const getCodeBaseURL: () => string;
5
6
  export declare const emptyOutputMessage = "stdout: Empty. Ensure you're writing output explicitly.\n";
7
+ export declare const CODE_ARTIFACT_PATH_GUIDANCE = "Persist handoff artifacts in `/mnt/data` with standard extensions (.json/.txt/.csv/.tsv/.log/.parquet/.png/.jpg/.pdf/.xlsx); failed executions do not register new files; `/tmp` and odd extensions are same-call scratch only, not later-call storage.";
8
+ export declare const BASH_SHELL_GUIDANCE = "Bash: multi-line files use heredoc/printf; run Python via python3 -c/heredoc, not bare Python.";
9
+ export declare const TMP_SCRATCH_OUTPUT_REMINDER = "Note: /tmp files are same-call scratch only and were not persisted; use /mnt/data for files needed later.";
10
+ export declare const FAILED_EXECUTION_FILE_REMINDER = "Note: any files written during this failed call were not registered for later calls; fix the error and rerun before relying on them.";
11
+ export declare function appendTmpScratchReminder(output: string, code: string): string;
12
+ export declare function appendFailedExecutionFileReminder(output: string, code: string): string;
6
13
  export declare const CodeExecutionToolSchema: {
7
14
  readonly type: "object";
8
15
  readonly properties: {
@@ -13,7 +20,7 @@ export declare const CodeExecutionToolSchema: {
13
20
  };
14
21
  readonly code: {
15
22
  readonly type: "string";
16
- readonly description: "The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Generated files from previous executions are automatically available in \"/mnt/data/\".\n- Files from previous executions are automatically available and can be modified in place.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use `print()` for all outputs.\n- py: Matplotlib: Use `plt.savefig()` to save plots as files.\n- js: use the `console` or `process` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.";
23
+ readonly description: "The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Prior /mnt/data files are available and can be modified in place.\n- Persist handoff artifacts in `/mnt/data` with standard extensions (.json/.txt/.csv/.tsv/.log/.parquet/.png/.jpg/.pdf/.xlsx); failed executions do not register new files; `/tmp` and odd extensions are same-call scratch only, not later-call storage.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use `print()` for all outputs.\n- py: Matplotlib: Use `plt.savefig()` to save plots as files.\n- js: use the `console` or `process` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.";
17
24
  };
18
25
  readonly args: {
19
26
  readonly type: "array";
@@ -45,7 +52,7 @@ export declare const CodeExecutionToolDefinition: {
45
52
  };
46
53
  readonly code: {
47
54
  readonly type: "string";
48
- readonly description: "The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Generated files from previous executions are automatically available in \"/mnt/data/\".\n- Files from previous executions are automatically available and can be modified in place.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use `print()` for all outputs.\n- py: Matplotlib: Use `plt.savefig()` to save plots as files.\n- js: use the `console` or `process` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.";
55
+ readonly description: "The complete, self-contained code to execute, without any truncation or minimization.\n- The environment is stateless; variables and imports don't persist between executions.\n- Prior /mnt/data files are available and can be modified in place.\n- Persist handoff artifacts in `/mnt/data` with standard extensions (.json/.txt/.csv/.tsv/.log/.parquet/.png/.jpg/.pdf/.xlsx); failed executions do not register new files; `/tmp` and odd extensions are same-call scratch only, not later-call storage.\n- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.\n- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.\n- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.\n- py: This is not a Jupyter notebook environment. Use `print()` for all outputs.\n- py: Matplotlib: Use `plt.savefig()` to save plots as files.\n- js: use the `console` or `process` methods for all outputs.\n- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).\n- Other languages: use appropriate output functions.";
49
56
  };
50
57
  readonly args: {
51
58
  readonly type: "array";
@@ -58,5 +65,5 @@ export declare const CodeExecutionToolDefinition: {
58
65
  readonly required: readonly ["lang", "code"];
59
66
  };
60
67
  };
61
- declare function createCodeExecutionTool(params?: t.CodeExecutionToolParams): DynamicStructuredTool;
68
+ declare function createCodeExecutionTool(params?: t.CodeExecutionToolParams | null): DynamicStructuredTool;
62
69
  export { createCodeExecutionTool };
@@ -0,0 +1,3 @@
1
+ import type * as t from '@/types';
2
+ export declare function stripCodeSessionFileSummary(output: string): string;
3
+ export declare function appendCodeSessionFileSummary(output: string, files: t.FileRefs | undefined): string;
@@ -87,14 +87,14 @@ export declare function executeTools(toolCalls: t.PTCToolCall[], toolMap: t.Tool
87
87
  /**
88
88
  * Formats the completed response for the agent.
89
89
  *
90
- * Output is stdout/stderr only see `CodeExecutor.ts`. The
91
- * artifact still carries every file so the host's session map
92
- * stays in sync; the LLM doesn't see them in the tool result text.
90
+ * Output includes stdout/stderr plus a compact session-file summary
91
+ * when artifacts were persisted. The artifact still carries every
92
+ * file so the host's session map stays in sync.
93
93
  *
94
94
  * @param response - The completed API response
95
95
  * @returns Tuple of [formatted string, artifact]
96
96
  */
97
- export declare function formatCompletedResponse(response: t.ProgrammaticExecutionResponse): [string, t.ProgrammaticExecutionArtifact];
97
+ export declare function formatCompletedResponse(response: t.ProgrammaticExecutionResponse, sourceCode?: string): [string, t.ProgrammaticExecutionArtifact];
98
98
  /**
99
99
  * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.
100
100
  *
@@ -16,11 +16,13 @@ export type SubagentExecuteParams = {
16
16
  */
17
17
  parentToolCallId?: string;
18
18
  /**
19
- * Snapshot of the parent invocation's `config.configurable` at the
20
- * spawn-tool call site. Inherited verbatim into the child workflow's
21
- * `configurable` so host-set fields (`requestBody`, `user`,
22
- * `userMCPAuthMap`, etc.) propagate — fixing MCP body-placeholder
23
- * substitution and per-user lookups for subagent tool calls.
19
+ * Snapshot of the parent invocation's host `config.configurable` at
20
+ * the spawn-tool call site. Host-set fields (`requestBody`, `user`,
21
+ * `userMCPAuthMap`, etc.) propagate into the child workflow's
22
+ * `configurable` — fixing MCP body-placeholder substitution and
23
+ * per-user lookups for subagent tool calls. LangGraph runtime keys
24
+ * (`__pregel_*`, checkpoint bookkeeping) are intentionally not
25
+ * inherited; the child graph recreates its own runtime config.
24
26
  *
25
27
  * Inheritance details (verified empirically against LangGraph):
26
28
  * - host-set keys propagate as-is into the child's tool dispatches;
@@ -120,6 +122,7 @@ export declare class SubagentExecutor {
120
122
  */
121
123
  private createForwarderCallback;
122
124
  }
125
+ export declare function sanitizeForwardedSubagentUpdateData(eventName: string, data: unknown): unknown;
123
126
  /**
124
127
  * Produces a short single-line label for an arbitrary forwarded child event.
125
128
  * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show
@@ -284,9 +284,8 @@ export type FileRef = {
284
284
  * `true` when the codeapi sandbox echoed this entry as an unchanged
285
285
  * passthrough of an input the caller already owns (skill files,
286
286
  * downloaded inputs whose hash matched the baseline, inherited
287
- * `.dirkeep` markers). The tool-result formatter renders these as
288
- * "Available files" rather than "Generated files" so the LLM doesn't
289
- * conflate infrastructure inputs with newly-produced outputs.
287
+ * `.dirkeep` markers). The host can use this flag to skip
288
+ * post-processing work for files the caller already owns.
290
289
  */
291
290
  inherited?: true;
292
291
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.1.89",
3
+ "version": "3.1.90",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -1562,6 +1562,13 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1562
1562
  maxDepth: effectiveSubagentDepth,
1563
1563
  createChildGraph: (input): StandardGraph => {
1564
1564
  const childGraph = new StandardGraph(input);
1565
+ childGraph.hookRegistry = this.hookRegistry;
1566
+ /**
1567
+ * Do not propagate `humanInTheLoop` into the child graph yet:
1568
+ * nested subagent interrupts need a stable child checkpoint and
1569
+ * resume bridge. Child hooks still fire; `ask` decisions fail
1570
+ * closed inside the subagent until that flow is implemented.
1571
+ */
1565
1572
  childGraph.toolOutputReferences = this.toolOutputReferences;
1566
1573
  childGraph.eagerEventToolExecution = this.eagerEventToolExecution;
1567
1574
  childGraph.toolExecution = this.toolExecution;
@@ -109,6 +109,44 @@ describe('executeHooks', () => {
109
109
  consoleWarnSpy.mockRestore();
110
110
  });
111
111
 
112
+ describe('abort listener management', () => {
113
+ it('uses one abort listener for many hooks on one matcher', async () => {
114
+ const registry = new HookRegistry();
115
+ const listenerCounts = new Map<AbortSignal, number>();
116
+ let maxAbortListeners = 0;
117
+ const addEventListenerSpy = jest
118
+ .spyOn(AbortSignal.prototype, 'addEventListener')
119
+ .mockImplementation(function (
120
+ this: AbortSignal,
121
+ type: string,
122
+ _listener: EventListenerOrEventListenerObject | null
123
+ ): void {
124
+ if (type !== 'abort') {
125
+ return;
126
+ }
127
+ const count = (listenerCounts.get(this) ?? 0) + 1;
128
+ listenerCounts.set(this, count);
129
+ maxAbortListeners = Math.max(maxAbortListeners, count);
130
+ });
131
+ const hooks = Array.from({ length: 12 }, () =>
132
+ runStartHook(async (): Promise<RunStartHookOutput> => ({}))
133
+ );
134
+
135
+ try {
136
+ registry.register('RunStart', { hooks });
137
+
138
+ await executeHooks({
139
+ registry,
140
+ input: runStartInput(),
141
+ timeoutMs: 1000,
142
+ });
143
+ expect(maxAbortListeners).toBe(1);
144
+ } finally {
145
+ addEventListenerSpy.mockRestore();
146
+ }
147
+ });
148
+ });
149
+
112
150
  describe('empty matcher set', () => {
113
151
  it('returns an empty aggregated result when no matchers are registered', async () => {
114
152
  const registry = new HookRegistry();
@@ -46,6 +46,11 @@ interface HookOutcome {
46
46
  timedOut: boolean;
47
47
  }
48
48
 
49
+ interface AbortRace {
50
+ promise: Promise<never>;
51
+ cleanup: () => void;
52
+ }
53
+
49
54
  function freshResult(): AggregatedHookResult {
50
55
  return {
51
56
  additionalContexts: [],
@@ -110,10 +115,10 @@ async function runHook(
110
115
  hook: WideCallback,
111
116
  input: HookInput,
112
117
  signal: AbortSignal,
118
+ abortPromise: Promise<never>,
113
119
  matcher: WideMatcher
114
120
  ): Promise<HookOutcome> {
115
121
  const hookPromise = Promise.resolve().then(() => hook(input, signal));
116
- const { promise: abortPromise, cleanup } = makeAbortPromise(signal);
117
122
  try {
118
123
  const output = await Promise.race([hookPromise, abortPromise]);
119
124
  return { matcher, output, error: null, timedOut: false };
@@ -124,8 +129,22 @@ async function runHook(
124
129
  error: describeError(err),
125
130
  timedOut: isTimeout(err),
126
131
  };
132
+ }
133
+ }
134
+
135
+ async function runMatcherHooks(
136
+ matcher: WideMatcher,
137
+ input: HookInput,
138
+ signal: AbortSignal
139
+ ): Promise<HookOutcome[]> {
140
+ const abortRace: AbortRace = makeAbortPromise(signal);
141
+ const tasks = matcher.hooks.map((hook) =>
142
+ runHook(hook, input, signal, abortRace.promise, matcher)
143
+ );
144
+ try {
145
+ return await Promise.all(tasks);
127
146
  } finally {
128
- cleanup();
147
+ abortRace.cleanup();
129
148
  }
130
149
  }
131
150
 
@@ -373,7 +392,7 @@ export async function executeHooks(
373
392
  }
374
393
 
375
394
  // --- SYNC CRITICAL SECTION: once-matcher removal must complete before any await ---
376
- const tasks: Promise<HookOutcome>[] = [];
395
+ const tasks: Promise<HookOutcome[]>[] = [];
377
396
  for (const matcher of matchers) {
378
397
  if (!matchesQuery(matcher.pattern, matchQuery)) {
379
398
  continue;
@@ -381,18 +400,19 @@ export async function executeHooks(
381
400
  if (matcher.once === true) {
382
401
  registry.removeMatcher(event, matcher, sessionId);
383
402
  }
403
+ if (matcher.hooks.length === 0) {
404
+ continue;
405
+ }
384
406
  const perHookTimeout = matcher.timeout ?? timeoutMs;
385
407
  const matcherSignal = combineSignals(signal, perHookTimeout);
386
- for (const hook of matcher.hooks) {
387
- tasks.push(runHook(hook, input, matcherSignal, matcher));
388
- }
408
+ tasks.push(runMatcherHooks(matcher, input, matcherSignal));
389
409
  }
390
410
  // --- END SYNC CRITICAL SECTION ---
391
411
  if (tasks.length === 0) {
392
412
  return freshResult();
393
413
  }
394
414
 
395
- const outcomes = await Promise.all(tasks);
415
+ const outcomes = (await Promise.all(tasks)).flat();
396
416
  reportErrors(outcomes, event, logger);
397
417
  const aggregated = fold(outcomes);
398
418
  /**