@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
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentExecutor.cjs","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":["nanoid","executeHooks","HumanMessage","GraphEvents","BaseCallbackHandler","Callback"],"mappings":";;;;;;;;;AAsBA,MAAM,iBAAiB,GAAG,EAAE;AAC5B,MAAM,oBAAoB,GAAG,CAAC;AAC9B,MAAM,uBAAuB,GAAG,GAAG;AAEnC,MAAM,aAAa,GAAyB,MAAM,CAAC,MAAM,CAAC;AACxD,IAAA,kBAAkB,EAAE,EAAc;AAClC,IAAA,MAAM,EAAE,EAAc;AACvB,CAAA,CAAC;MAwFW,gBAAgB,CAAA;AACV,IAAA,OAAO;AACP,IAAA,YAAY;AACZ,IAAA,YAAY;AACZ,IAAA,WAAW;AACX,IAAA,aAAa;AACb,IAAA,YAAY;AACZ,IAAA,QAAQ;AACR,IAAA,gBAAgB;AAChB,IAAA,4BAA4B;AAI7C,IAAA,WAAA,CAAY,OAAgC,EAAA;AAC1C,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO;AAC9B,QAAA,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;AACxC,QAAA,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;AACxC,QAAA,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW;AACtC,QAAA,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC;AACrC,QAAA,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB;AAChD,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,qBAAqB;AACjD,QAAA,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE;AACrC,YAAA,IAAI,CAAC,4BAA4B,GAAG,WAAW;QACjD;AAAO,aAAA,IAAI,WAAW,IAAI,IAAI,EAAE;AAC9B,YAAA,IAAI,CAAC,4BAA4B,GAAG,MAAuB,WAAW;QACxE;IACF;;IAGQ,wBAAwB,GAAA;AAC9B,QAAA,OAAO,IAAI,CAAC,4BAA4B,IAAI;IAC9C;IAEA,MAAM,OAAO,CAAC,MAA6B,EAAA;QACzC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,MAAM;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAE7C,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACrD,OAAO;AACL,gBAAA,OAAO,EAAE,CAAA,8BAAA,EAAiC,YAAY,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAE;AACxF,gBAAA,QAAQ,EAAE,EAAE;aACb;QACH;AAEA,QAAA,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE;YACtB,OAAO;AACL,gBAAA,OAAO,EAAE,iDAAiD;AAC1D,gBAAA,QAAQ,EAAE,EAAE;aACb;QACH;AAEA,QAAA,MAAM,YAAY,GAChB,MAAM,CAAC,WAAW,CAAC,OAAO;YAC1B,CAAA,EAAG,IAAI,CAAC,aAAa,IAAI,OAAO,CAAA,KAAA,EAAQA,aAAM,CAAC,CAAC,CAAC,CAAA,CAAE;AAErD,QAAA,IACE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EACzE;AACA,YAAA,MAAM,UAAU,GAAG,MAAMC,yBAAY,CAAC;gBACpC,QAAQ,EAAE,IAAI,CAAC,YAAY;AAC3B,gBAAA,KAAK,EAAE;AACL,oBAAA,eAAe,EAAE,eAAe;oBAChC,KAAK,EAAE,IAAI,CAAC,WAAW;oBACvB,QAAQ;oBACR,aAAa,EAAE,IAAI,CAAC,aAAa;AACjC,oBAAA,OAAO,EAAE,YAAY;AACrB,oBAAA,SAAS,EAAE,YAAY;AACvB,oBAAA,MAAM,EAAE,CAAC,IAAIC,qBAAY,CAAC,WAAW,CAAC,CAAC;AACxC,iBAAA;gBACD,SAAS,EAAE,IAAI,CAAC,WAAW;AAC3B,gBAAA,UAAU,EAAE,YAAY;aACzB,CAAC,CAAC,KAAK,CAAC,MAA4B,aAAa,CAAC;AAEnD;;;;AAIG;AACH,YAAA,IAAI,UAAU,CAAC,QAAQ,KAAK,MAAM,IAAI,UAAU,CAAC,QAAQ,KAAK,KAAK,EAAE;gBACnE,OAAO;AACL,oBAAA,OAAO,EAAE,CAAA,SAAA,EAAY,UAAU,CAAC,MAAM,IAAI,iBAAiB,CAAA,CAAE;AAC7D,oBAAA,QAAQ,EAAE,EAAE;iBACb;YACH;QACF;AAEA,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,wBAAwB,EAAE;AACtD,QAAA,MAAM,iBAAiB,GAAG,cAAc,IAAI,IAAI;AAChD;;;;;;;;AAQG;AACH,QAAA,MAAM,qBAAqB,GACzB,cAAc,EAAE,UAAU,CAACC,iBAAW,CAAC,eAAe,CAAC,IAAI,IAAI;QACjE,MAAM,WAAW,GAAG,gBAAgB,CAClC,MAAM,EACN,YAAY,EACZ,IAAI,CAAC,QAAQ;kCACa,qBAAqB,CAChD;AACD,QAAA,MAAM,UAAU,GAAG,CAAA,EAAG,IAAI,CAAC,WAAW,CAAA,KAAA,EAAQH,aAAM,CAAC,CAAC,CAAC,CAAA,CAAE;AACzD,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB;AAErD,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;AACvC,YAAA,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,IAAI,CAAC,YAAY;YACzB,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,YAAY,EAAE,IAAI,CAAC,YAAY;AAChC,SAAA,CAAC;QAEF,MAAM,SAAS,GAAG;AAChB,cAAE,IAAI,CAAC,uBAAuB,CAAC;AAC7B,gBAAA,cAAc,EAAE,cAAe;gBAC/B,YAAY;AACZ,gBAAA,eAAe,EAAE,YAAY;gBAC7B,UAAU;gBACV,gBAAgB;aACjB;cACC,SAAS;QAEb,IAAI,SAAS,EAAE;AACb,YAAA,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAe,EAAE;gBAC7C,UAAU;gBACV,YAAY;AACZ,gBAAA,eAAe,EAAE,YAAY;gBAC7B,gBAAgB;AAChB,gBAAA,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,CAAA,UAAA,EAAa,YAAY,CAAA,SAAA,CAAW;AAC5C,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI,MAAmC;AACvC,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,EAAE;AAC5C;;;;;;;;;;;;;;;;AAgBG;AACH,YAAA,MAAM,SAAS,GAAc,SAAS,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AACH,YAAA,MAAM,qBAAqB,GACzB,MAAM,CAAC,kBAAkB,IAAI,EAAE;AACjC,YAAA,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAC5B,EAAE,QAAQ,EAAE,CAAC,IAAIE,qBAAY,CAAC,WAAW,CAAC,CAAC,EAAE,EAC7C;gBACE,cAAc,EAAE,QAAQ,GAAG,oBAAoB;gBAC/C,MAAM,EAAE,IAAI,CAAC,YAAY;gBACzB,SAAS;gBACT,OAAO,EAAE,CAAA,SAAA,EAAY,YAAY,CAAA,CAAE;AACnC,gBAAA,YAAY,EAAE;AACZ,oBAAA,SAAS,EAAE,UAAU;AACrB,oBAAA,GAAG,qBAAqB;AACzB,iBAAA;AACF,aAAA,CACF;QACH;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,MAAM,YAAY,GAAG,oBAAoB,CAAC,KAAK,CAAC;YAChD,IAAI,SAAS,EAAE;AACb,gBAAA,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAe,EAAE;oBAC7C,UAAU;oBACV,YAAY;AACZ,oBAAA,eAAe,EAAE,YAAY;oBAC7B,gBAAgB;AAChB,oBAAA,KAAK,EAAE,OAAO;AACd,oBAAA,KAAK,EAAE,CAAA,UAAA,EAAa,YAAY,CAAA,WAAA,EAAc,YAAY,CAAA,CAAE;AAC5D,oBAAA,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;AAChC,iBAAA,CAAC;YACJ;YACA,UAAU,CAAC,eAAe,EAAE;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAA,gBAAA,EAAmB,YAAY,CAAA,CAAE;AAC1C,gBAAA,QAAQ,EAAE,EAAE;aACb;QACH;QAEA,MAAM,eAAe,GAAG,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC;AAE7D,QAAA,IACE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EACxE;AACA;;;;;AAKG;AACH,YAAA,MAAMD,yBAAY,CAAC;gBACjB,QAAQ,EAAE,IAAI,CAAC,YAAY;AAC3B,gBAAA,KAAK,EAAE;AACL,oBAAA,eAAe,EAAE,cAAc;oBAC/B,KAAK,EAAE,IAAI,CAAC,WAAW;oBACvB,QAAQ;AACR,oBAAA,OAAO,EAAE,YAAY;AACrB,oBAAA,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;AAC1B,iBAAA;gBACD,SAAS,EAAE,IAAI,CAAC,WAAW;AAC3B,gBAAA,UAAU,EAAE,YAAY;AACzB,aAAA,CAAC,CAAC,KAAK,CAAC,MAAK;;AAEd,YAAA,CAAC,CAAC;QACJ;QAEA,IAAI,SAAS,EAAE;AACb,YAAA,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAe,EAAE;gBAC7C,UAAU;gBACV,YAAY;AACZ,gBAAA,eAAe,EAAE,YAAY;gBAC7B,gBAAgB;AAChB,gBAAA,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,CAAA,UAAA,EAAa,YAAY,CAAA,UAAA,CAAY;AAC7C,aAAA,CAAC;QACJ;QAEA,UAAU,CAAC,eAAe,EAAE;QAE5B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;IAChE;AAEA;;;;AAIG;AACK,IAAA,MAAM,kBAAkB,CAC9B,cAA+B,EAC/B,IAQC,EAAA;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAACE,iBAAW,CAAC,kBAAkB,CAAC;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ;QACF;AACA,QAAA,MAAM,KAAK,GAAwB;YACjC,KAAK,EAAE,IAAI,CAAC,WAAW;YACvB,aAAa,EAAE,IAAI,CAAC,UAAU;YAC9B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,YAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC;AACD,QAAA,IAAI;YACF,MAAM,OAAO,CAAC,MAAM,CAACA,iBAAW,CAAC,kBAAkB,EAAE,KAAK,CAAC;QAC7D;AAAE,QAAA,MAAM;;QAER;IACF;AAEA;;;;;;;;;;;AAWG;AACK,IAAA,uBAAuB,CAAC,IAM/B,EAAA;AACC,QAAA,MAAM,EACJ,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,EACV,gBAAgB,GACjB,GAAG,IAAI;AACR,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW;AACpC,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa;QAExC,MAAM,IAAI,GAAG,OACX,SAAiB,EACjB,KAA0B,EAC1B,IAAa,KACI;YACjB,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAACA,iBAAW,CAAC,kBAAkB,CAAC;YACzE,IAAI,CAAC,OAAO,EAAE;gBACZ;YACF;AACA,YAAA,MAAM,KAAK,GAAwB;AACjC,gBAAA,KAAK,EAAE,WAAW;AAClB,gBAAA,aAAa,EAAE,UAAU;gBACzB,YAAY;gBACZ,eAAe;gBACf,aAAa;gBACb,gBAAgB;gBAChB,KAAK;gBACL,IAAI;AACJ,gBAAA,KAAK,EAAE,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;AACtC,gBAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC;AACD,YAAA,IAAI;gBACF,MAAM,OAAO,CAAC,MAAM,CAACA,iBAAW,CAAC,kBAAkB,EAAE,KAAK,CAAC;YAC7D;AAAE,YAAA,MAAM;;YAER;AACF,QAAA,CAAC;AAED,QAAA,MAAM,OAAO,GAAGC,wBAAmB,CAAC,WAAW,CAAC;YAC9C,CAACC,cAAQ,CAAC,YAAY,GAAG,OACvB,SAAiB,EACjB,IAAa,KACI;AACjB,gBAAA,IAAI,SAAS,KAAKF,iBAAW,CAAC,eAAe,EAAE;oBAC7C,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAC3CA,iBAAW,CAAC,eAAe,CAC5B;oBACD,IAAI,WAAW,EAAE;wBACf,MAAM,WAAW,CAAC,MAAM,CACtBA,iBAAW,CAAC,eAAe,EAC3B,IAA+B,CAChC;oBACH;AACA;;;AAGG;oBACH,MAAM,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;oBACvC;gBACF;AAEA,gBAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,WAAW,EAAE;oBACzC,MAAM,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;oBACvC;gBACF;AACA,gBAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,iBAAiB,EAAE;oBAC/C,MAAM,IAAI,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,CAAC;oBAC7C;gBACF;AACA,gBAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,qBAAqB,EAAE;oBACnD,MAAM,IAAI,CAAC,SAAS,EAAE,oBAAoB,EAAE,IAAI,CAAC;oBACjD;gBACF;AACA,gBAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,gBAAgB,EAAE;oBAC9C,MAAM,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,CAAC;oBAC5C;gBACF;AACA,gBAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,kBAAkB,EAAE;oBAChD,MAAM,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,CAAC;oBAC9C;gBACF;YACF,CAAC;AACF,SAAA,CAAC;AACF;;;;;;;;;AASG;AACH,QAAA,OAAO,CAAC,aAAa,GAAG,IAAI;AAC5B,QAAA,OAAO,OAAO;IAChB;AACD;AAED;;;;AAIG;AACG,SAAU,cAAc,CAAC,SAAiB,EAAE,IAAa,EAAA;AAC7D,IAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,eAAe,EAAE;QAC7C,MAAM,GAAG,GAAG,IAAgD;QAC5D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE;aAC/B,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;aACjB,MAAM,CAAC,CAAC,CAAC,KAAkB,OAAO,CAAC,KAAK,QAAQ,CAAC;QACpD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAA,QAAA,EAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,GAAG,cAAc;IAC1E;AACA,IAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,WAAW,EAAE;QACzC,MAAM,IAAI,GAAG,IAGZ;AACD,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM;AAChE,QAAA,IAAI,UAAU,KAAK,YAAY,EAAE;YAC/B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,IAAI,EAAE;iBAC9C,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;iBACjB,MAAM,CAAC,CAAC,CAAC,KAAkB,OAAO,CAAC,KAAK,QAAQ,CAAC;AACpD,YAAA,OAAO,KAAK,CAAC,MAAM,GAAG;kBAClB,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;kBAC/B,oBAAoB;QAC1B;AACA,QAAA,IAAI,UAAU,KAAK,kBAAkB,EAAE;AACrC,YAAA,OAAO,WAAW;QACpB;QACA,OAAO,CAAA,MAAA,EAAS,UAAU,CAAA,CAAE;IAC9B;AACA,IAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,qBAAqB,EAAE;QACnD,MAAM,IAAI,GAAG,IAKZ;AACD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS;AACnC,QAAA,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,EAAE;AAC1C,YAAA,OAAO,CAAA,KAAA,EAAQ,IAAI,CAAC,IAAI,WAAW;QACrC;AACA,QAAA,OAAO,eAAe;IACxB;AACA,IAAA,IAAI,SAAS,KAAKA,iBAAW,CAAC,gBAAgB,EAAE;AAC9C,QAAA,OAAO,YAAY;IACrB;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;AASG;AACG,SAAU,oBAAoB,CAAC,QAAuB,EAAA;AAC1D,IAAA,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7C,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnC;QACF;QAEA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO;AAEnC,QAAA,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;AAC/B,YAAA,IAAI,OAAO;AAAE,gBAAA,OAAO,OAAO;YAC3B;QACF;QAEA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B;QACF;QAEA,MAAM,SAAS,GAAa,EAAE;AAC9B,QAAA,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;AAC3B,YAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,gBAAA,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;YACvB;AAAO,iBAAA,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE;AACtE,gBAAA,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAc,CAAC;YACtC;QACF;AAEA,QAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,YAAA,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B;IACF;AAEA,IAAA,OAAO,gBAAgB;AACzB;AAEA;;;;AAIG;AACG,SAAU,sBAAsB,CACpC,OAAyB,EACzB,aAA2B,EAAA;IAE3B,MAAM,QAAQ,GAAG;AACd,SAAA,GAAG,CAAC,CAAC,MAAM,KAAI;AACd,QAAA,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE;AAC9B,YAAA,OAAO,MAAgC;QACzC;AACA,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,aAAa,CAAC,aAAa,IAAI,IAAI,EAAE;AAC/D,YAAA,OAAO,IAAI;QACb;QACA,OAAO;AACL,YAAA,GAAG,MAAM;AACT,YAAA,WAAW,EAAE,EAAE,GAAG,aAAa,CAAC,aAAa,EAAE;SACtB;AAC7B,IAAA,CAAC;SACA,MAAM,CAAC,CAAC,CAAC,KAAkC,CAAC,IAAI,IAAI,CAAC;AAExD,IAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU;AACnC,IAAA,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE;QAC7B,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC9B,MAAM,IAAI,KAAK,CACb,CAAA,yBAAA,EAA4B,MAAM,CAAC,IAAI,CAAA,uDAAA,CAAyD,CACjG;QACH;AACA,QAAA,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B;AAEA,IAAA,OAAO,QAAQ;AACjB;AAEA;;;;;;;;;;;;;;;;;;;AAmBG;AACG,SAAU,gBAAgB,CAC9B,MAA8B,EAC9B,YAAoB,EACpB,cAAsB,EACtB,mBAAA,GAA+B,KAAK,EAAA;AAEpC,IAAA,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM;AAC9B,IAAA,MAAM,WAAW,GAAgB;AAC/B,QAAA,GAAG,WAAW;AACd,QAAA,OAAO,EAAE,YAAY;AACrB,QAAA,eAAe,EAAE;cACb,WAAW,CAAC;AACd,cAAE,SAAS;AACb;;;;;;;;AAQG;AACH,QAAA,cAAc,EAAE,SAAS;AACzB,QAAA,eAAe,EAAE,SAAS;KAC3B;AAED,IAAA,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,EAAE;AAC/B,QAAA,WAAW,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC;IAChE;SAAO;AACL,QAAA,WAAW,CAAC,eAAe,GAAG,SAAS;AACvC,QAAA,WAAW,CAAC,gBAAgB,GAAG,SAAS;IAC1C;AAEA,IAAA,OAAO,WAAW;AACpB;AAEA,SAAS,oBAAoB,CAAC,KAAc,EAAA;AAC1C,IAAA,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AACtE,IAAA,IAAI,OAAO,CAAC,MAAM,IAAI,uBAAuB,EAAE;AAC7C,QAAA,OAAO,OAAO;IAChB;IACA,OAAO,CAAA,EAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAA,GAAA,CAAK;AAC1D;;;;;;;;"}
1
+ {"version":3,"file":"SubagentExecutor.cjs","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":["nanoid","executeHooks","HumanMessage","GraphEvents","BaseCallbackHandler","Callback","StepTypes"],"mappings":"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"}
@@ -26,6 +26,13 @@ var truncation = require('../utils/truncation.cjs');
26
26
  * registry pristine means downstream bash/jq piping receives the
27
27
  * complete, verbatim output with no injected fields.
28
28
  */
29
+ /**
30
+ * Non-global matcher for a single `{{tool<i>turn<n>}}` placeholder.
31
+ * Exported for consumers that want to detect references (e.g., syntax
32
+ * highlighting, docs). The stateful `g` variant lives inside the
33
+ * registry so nobody trips on `lastIndex`.
34
+ */
35
+ const TOOL_OUTPUT_REF_PATTERN = /\{\{(tool\d+turn\d+)\}\}/;
29
36
  /** Object key used when a parsed-object output has `_ref` injected. */
30
37
  const TOOL_OUTPUT_REF_KEY = '_ref';
31
38
  /**
@@ -661,6 +668,7 @@ function stripFrameworkRefMetadata(kwargs) {
661
668
  }
662
669
 
663
670
  exports.TOOL_OUTPUT_REF_KEY = TOOL_OUTPUT_REF_KEY;
671
+ exports.TOOL_OUTPUT_REF_PATTERN = TOOL_OUTPUT_REF_PATTERN;
664
672
  exports.TOOL_OUTPUT_UNRESOLVED_KEY = TOOL_OUTPUT_UNRESOLVED_KEY;
665
673
  exports.ToolOutputReferenceRegistry = ToolOutputReferenceRegistry;
666
674
  exports.annotateMessagesForLLM = annotateMessagesForLLM;
@@ -1 +1 @@
1
- {"version":3,"file":"toolOutputReferences.cjs","sources":["../../../src/tools/toolOutputReferences.ts"],"sourcesContent":["/**\n * Tool output reference registry.\n *\n * When enabled via `RunConfig.toolOutputReferences.enabled`, ToolNode\n * stores each successful tool output under a stable key\n * (`tool<idx>turn<turn>`) where `idx` is the tool's position within a\n * ToolNode batch and `turn` is the batch index within the run\n * (incremented once per ToolNode invocation).\n *\n * Subsequent tool calls can pipe a previous output into their args by\n * embedding `{{tool<idx>turn<turn>}}` inside any string argument;\n * {@link ToolOutputReferenceRegistry.resolve} walks the args and\n * substitutes the placeholders immediately before invocation.\n *\n * The registry stores the *raw, untruncated* tool output so a later\n * `{{…}}` substitution pipes the full payload into the next tool —\n * even when the LLM only saw a head+tail-truncated preview in\n * `ToolMessage.content`. Outputs are stored without any annotation\n * (the `_ref` key or the `[ref: ...]` prefix seen by the LLM is\n * strictly a UX signal attached to `ToolMessage.content`). Keeping the\n * registry pristine means downstream bash/jq piping receives the\n * complete, verbatim output with no injected fields.\n */\n\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport {\n calculateMaxTotalToolOutputSize,\n HARD_MAX_TOOL_RESULT_CHARS,\n HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE,\n} from '@/utils/truncation';\n\n/**\n * Non-global matcher for a single `{{tool<i>turn<n>}}` placeholder.\n * Exported for consumers that want to detect references (e.g., syntax\n * highlighting, docs). The stateful `g` variant lives inside the\n * registry so nobody trips on `lastIndex`.\n */\nexport const TOOL_OUTPUT_REF_PATTERN = /\\{\\{(tool\\d+turn\\d+)\\}\\}/;\n\n/** Object key used when a parsed-object output has `_ref` injected. */\nexport const TOOL_OUTPUT_REF_KEY = '_ref';\n\n/**\n * Object key used to carry unresolved reference warnings on a parsed-\n * object output. Using a dedicated field instead of a trailing text\n * line keeps the annotated `ToolMessage.content` parseable as JSON for\n * downstream consumers that rely on the object shape.\n */\nexport const TOOL_OUTPUT_UNRESOLVED_KEY = '_unresolved_refs';\n\n/** Single-line prefix prepended to non-object tool outputs so the LLM sees the reference key. */\nexport function buildReferencePrefix(key: string): string {\n return `[ref: ${key}]`;\n}\n\n/** Stable registry key for a tool output. */\nexport function buildReferenceKey(toolIndex: number, turn: number): string {\n return `tool${toolIndex}turn${turn}`;\n}\n\nexport type ToolOutputReferenceRegistryOptions = {\n /** Maximum characters stored per registered output. */\n maxOutputSize?: number;\n /** Maximum total characters retained across all registered outputs. */\n maxTotalSize?: number;\n /**\n * Upper bound on the number of concurrently-tracked runs. When\n * exceeded, the oldest run bucket is evicted (FIFO). Defaults to 32.\n */\n maxActiveRuns?: number;\n};\n\n/**\n * Result of resolving placeholders in tool args.\n */\nexport type ResolveResult<T> = {\n /** Arguments with placeholders replaced. Same shape as the input. */\n resolved: T;\n /** Reference keys that were referenced but had no stored value. */\n unresolved: string[];\n};\n\n/**\n * Read-only view over a frozen registry snapshot. Returned by\n * {@link ToolOutputReferenceRegistry.snapshot} for callers that need\n * to resolve placeholders against the registry state at a specific\n * point in time, ignoring any subsequent registrations.\n */\nexport interface ToolOutputResolveView {\n resolve<T>(args: T): ResolveResult<T>;\n}\n\n/**\n * Pre-resolved arg map keyed by `toolCallId`. Used by the mixed\n * direct+event dispatch path to feed event calls' resolved args\n * (captured pre-batch) into the dispatcher without re-resolving\n * against the now-stale live registry.\n */\nexport type PreResolvedArgsMap = Map<\n string,\n { resolved: Record<string, unknown>; unresolved: string[] }\n>;\n\n/**\n * Per-call sink for resolved args, keyed by `toolCallId`. Threaded\n * as a per-batch local map so concurrent `ToolNode.run()` calls do\n * not race on shared sink state.\n */\nexport type ResolvedArgsByCallId = Map<string, Record<string, unknown>>;\n\nconst EMPTY_ENTRIES: ReadonlyMap<string, string> = new Map<string, string>();\n\n/**\n * Per-run state bucket held inside the registry. Each distinct\n * `run_id` gets its own bucket so overlapping concurrent runs on a\n * shared registry cannot leak outputs, turn counters, or warn-memos\n * into one another.\n */\nclass RunStateBucket {\n entries: Map<string, string> = new Map();\n totalSize: number = 0;\n turnCounter: number = 0;\n warnedNonStringTools: Set<string> = new Set();\n}\n\n/**\n * Anonymous (`run_id` absent) bucket key. Anonymous batches are\n * treated as fresh runs on every invocation — see `nextTurn`.\n */\nconst ANON_RUN_KEY = '\\0anon';\n\n/**\n * Default upper bound on the number of concurrently-tracked runs per\n * registry. When exceeded, the oldest run's bucket (by insertion\n * order) is evicted. Keeps memory bounded when a ToolNode is reused\n * across many runs without explicit `releaseRun` calls.\n */\nconst DEFAULT_MAX_ACTIVE_RUNS = 32;\n\n/**\n * Ordered map of reference-key → stored output, partitioned by run so\n * concurrent / interleaved runs sharing one registry cannot leak\n * outputs between each other.\n *\n * Each public method takes a `runId` which selects the run's bucket.\n * Hosts typically get one registry per run via `Graph`, in which\n * case only a single bucket is ever populated; the partitioning\n * exists so the registry also behaves correctly when a single\n * instance is reused directly.\n */\nexport class ToolOutputReferenceRegistry {\n private runStates: Map<string, RunStateBucket> = new Map();\n private readonly maxOutputSize: number;\n private readonly maxTotalSize: number;\n private readonly maxActiveRuns: number;\n /**\n * Local stateful matcher used only by `replaceInString`. Kept\n * off-module so callers of the exported `TOOL_OUTPUT_REF_PATTERN`\n * never see a stale `lastIndex`.\n */\n private static readonly PLACEHOLDER_MATCHER = /\\{\\{(tool\\d+turn\\d+)\\}\\}/g;\n\n constructor(options: ToolOutputReferenceRegistryOptions = {}) {\n /**\n * Per-output default is the same ~400 KB budget as the standard\n * tool-result truncation (`HARD_MAX_TOOL_RESULT_CHARS`). This\n * keeps a single `{{…}}` substitution at a size that is safe to\n * pass through typical shell `ARG_MAX` limits and matches what\n * the LLM would otherwise have seen. Hosts that want larger per-\n * output payloads (API consumers, long JSON streams) can raise\n * the cap explicitly up to the 5 MB total budget.\n */\n const perOutput =\n options.maxOutputSize != null && options.maxOutputSize > 0\n ? options.maxOutputSize\n : HARD_MAX_TOOL_RESULT_CHARS;\n /**\n * Clamp a caller-supplied `maxTotalSize` to\n * `HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE` (5 MB) so the documented\n * absolute cap is enforced regardless of host config —\n * `calculateMaxTotalToolOutputSize` already applies the same\n * upper bound on its computed default, but the user-provided\n * branch was bypassing it.\n */\n const totalRaw =\n options.maxTotalSize != null && options.maxTotalSize > 0\n ? Math.min(options.maxTotalSize, HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE)\n : calculateMaxTotalToolOutputSize(perOutput);\n this.maxTotalSize = totalRaw;\n /**\n * The per-output cap can never exceed the per-run aggregate cap:\n * if a single entry were allowed to be larger than `maxTotalSize`,\n * the eviction loop would either blow the cap (to keep the entry)\n * or self-evict a just-stored value. Clamping here turns\n * `maxTotalSize` into a hard upper bound on *any* state the\n * registry retains per run.\n */\n this.maxOutputSize = Math.min(perOutput, totalRaw);\n this.maxActiveRuns =\n options.maxActiveRuns != null && options.maxActiveRuns > 0\n ? options.maxActiveRuns\n : DEFAULT_MAX_ACTIVE_RUNS;\n }\n\n private keyFor(runId: string | undefined): string {\n return runId ?? ANON_RUN_KEY;\n }\n\n private getOrCreate(runId: string | undefined): RunStateBucket {\n const key = this.keyFor(runId);\n let state = this.runStates.get(key);\n if (state == null) {\n state = new RunStateBucket();\n this.runStates.set(key, state);\n if (this.runStates.size > this.maxActiveRuns) {\n const oldest = this.runStates.keys().next().value;\n if (oldest != null && oldest !== key) {\n this.runStates.delete(oldest);\n }\n }\n }\n return state;\n }\n\n /** Registers (or replaces) the output stored under `key` for `runId`. */\n set(runId: string | undefined, key: string, value: string): void {\n const bucket = this.getOrCreate(runId);\n const clipped =\n value.length > this.maxOutputSize\n ? value.slice(0, this.maxOutputSize)\n : value;\n const existing = bucket.entries.get(key);\n if (existing != null) {\n bucket.totalSize -= existing.length;\n bucket.entries.delete(key);\n }\n bucket.entries.set(key, clipped);\n bucket.totalSize += clipped.length;\n this.evictWithinBucket(bucket);\n }\n\n /** Returns the stored value for `key` in `runId`'s bucket, or `undefined`. */\n get(runId: string | undefined, key: string): string | undefined {\n return this.runStates.get(this.keyFor(runId))?.entries.get(key);\n }\n\n /**\n * Returns `true` when `key` is currently stored in `runId`'s bucket.\n * Used by {@link annotateMessagesForLLM} to gate transient annotation\n * on whether the registry still owns the referenced output (a stale\n * `_refKey` from a prior run silently no-ops here).\n */\n has(runId: string | undefined, key: string): boolean {\n return this.runStates.get(this.keyFor(runId))?.entries.has(key) ?? false;\n }\n\n /** Total number of registered outputs across every run bucket. */\n get size(): number {\n let n = 0;\n for (const bucket of this.runStates.values()) {\n n += bucket.entries.size;\n }\n return n;\n }\n\n /** Maximum characters retained per output (post-clip). */\n get perOutputLimit(): number {\n return this.maxOutputSize;\n }\n\n /** Maximum total characters retained *per run*. */\n get totalLimit(): number {\n return this.maxTotalSize;\n }\n\n /** Drops every run's state. */\n clear(): void {\n this.runStates.clear();\n }\n\n /**\n * Explicitly release `runId`'s state. Safe to call when a run has\n * finished. Hosts sharing one registry across runs should call this\n * to reclaim memory deterministically; otherwise LRU eviction kicks\n * in when `maxActiveRuns` runs accumulate.\n */\n releaseRun(runId: string | undefined): void {\n this.runStates.delete(this.keyFor(runId));\n }\n\n /**\n * Claims the next batch turn synchronously from `runId`'s bucket.\n *\n * Must be called once at the start of each ToolNode batch before\n * any `await`, so concurrent invocations within the same run see\n * distinct turn values (reads are effectively atomic by JS's\n * single-threaded execution of the sync prefix).\n *\n * If `runId` is missing the anonymous bucket is dropped and a\n * fresh one created so each anonymous call behaves as its own run.\n */\n nextTurn(runId: string | undefined): number {\n if (runId == null) {\n this.runStates.delete(ANON_RUN_KEY);\n }\n const bucket = this.getOrCreate(runId);\n return bucket.turnCounter++;\n }\n\n /**\n * Records that `toolName` has been warned about in `runId` (returns\n * `true` on the first call per run, `false` after). Used by\n * ToolNode to emit one log line per offending tool per run when a\n * `ToolMessage.content` isn't a string.\n */\n claimWarnOnce(runId: string | undefined, toolName: string): boolean {\n const bucket = this.getOrCreate(runId);\n if (bucket.warnedNonStringTools.has(toolName)) {\n return false;\n }\n bucket.warnedNonStringTools.add(toolName);\n return true;\n }\n\n /**\n * Walks `args` and replaces every `{{tool<i>turn<n>}}` placeholder in\n * string values with the stored output *from `runId`'s bucket*. Non-\n * string values and object keys are left untouched. Unresolved\n * references are left in-place and reported so the caller can\n * surface them to the LLM. When no placeholder appears anywhere in\n * the serialized args, the original input is returned without\n * walking the tree.\n */\n resolve<T>(runId: string | undefined, args: T): ResolveResult<T> {\n if (!hasAnyPlaceholder(args)) {\n return { resolved: args, unresolved: [] };\n }\n const bucket = this.runStates.get(this.keyFor(runId));\n return this.resolveAgainst(bucket?.entries ?? EMPTY_ENTRIES, args);\n }\n\n /**\n * Captures a frozen snapshot of `runId`'s current entries and\n * returns a view that resolves placeholders against *only* that\n * snapshot. The snapshot is decoupled from the live registry, so\n * subsequent `set()` calls (for example, same-turn direct outputs\n * registering while an event branch is still in flight) are\n * invisible to the snapshot's `resolve`. Used by the mixed\n * direct+event dispatch path to preserve same-turn isolation when\n * a `PreToolUse` hook rewrites event args after directs have\n * completed.\n */\n snapshot(runId: string | undefined): ToolOutputResolveView {\n const bucket = this.runStates.get(this.keyFor(runId));\n const entries: ReadonlyMap<string, string> = bucket\n ? new Map(bucket.entries)\n : EMPTY_ENTRIES;\n return {\n resolve: <T>(args: T): ResolveResult<T> =>\n this.resolveAgainst(entries, args),\n };\n }\n\n private resolveAgainst<T>(\n entries: ReadonlyMap<string, string>,\n args: T\n ): ResolveResult<T> {\n if (!hasAnyPlaceholder(args)) {\n return { resolved: args, unresolved: [] };\n }\n const unresolved = new Set<string>();\n const resolved = this.transform(entries, args, unresolved) as T;\n return { resolved, unresolved: Array.from(unresolved) };\n }\n\n private transform(\n entries: ReadonlyMap<string, string>,\n value: unknown,\n unresolved: Set<string>\n ): unknown {\n if (typeof value === 'string') {\n return this.replaceInString(entries, value, unresolved);\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.transform(entries, item, unresolved));\n }\n if (value !== null && typeof value === 'object') {\n const source = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(source)) {\n next[key] = this.transform(entries, item, unresolved);\n }\n return next;\n }\n return value;\n }\n\n private replaceInString(\n entries: ReadonlyMap<string, string>,\n input: string,\n unresolved: Set<string>\n ): string {\n if (input.indexOf('{{tool') === -1) {\n return input;\n }\n return input.replace(\n ToolOutputReferenceRegistry.PLACEHOLDER_MATCHER,\n (match, key: string) => {\n const stored = entries.get(key);\n if (stored == null) {\n unresolved.add(key);\n return match;\n }\n return stored;\n }\n );\n }\n\n private evictWithinBucket(bucket: RunStateBucket): void {\n if (bucket.totalSize <= this.maxTotalSize) {\n return;\n }\n for (const key of bucket.entries.keys()) {\n if (bucket.totalSize <= this.maxTotalSize) {\n return;\n }\n const entry = bucket.entries.get(key);\n if (entry == null) {\n continue;\n }\n bucket.totalSize -= entry.length;\n bucket.entries.delete(key);\n }\n }\n}\n\n/**\n * Cheap pre-check: returns true if any string value in `args` contains\n * the `{{tool` substring. Lets `resolve()` skip the deep tree walk (and\n * its object allocations) for the common case of plain args.\n */\nfunction hasAnyPlaceholder(value: unknown): boolean {\n if (typeof value === 'string') {\n return value.indexOf('{{tool') !== -1;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n if (hasAnyPlaceholder(item)) {\n return true;\n }\n }\n return false;\n }\n if (value !== null && typeof value === 'object') {\n for (const item of Object.values(value as Record<string, unknown>)) {\n if (hasAnyPlaceholder(item)) {\n return true;\n }\n }\n return false;\n }\n return false;\n}\n\n/**\n * Annotates `content` with a reference key and/or unresolved-ref\n * warnings so the LLM sees both alongside the tool output.\n *\n * Behavior:\n * - If `content` parses as a plain (non-array, non-null) JSON object\n * and the object does not already have a conflicting `_ref` key,\n * the reference key and (when present) `_unresolved_refs` array\n * are injected as object fields, preserving JSON validity for\n * downstream consumers that parse the output.\n * - Otherwise (string output, JSON array/primitive, parse failure,\n * or `_ref` collision), a `[ref: <key>]\\n` prefix line is\n * prepended and unresolved refs are appended as a trailing\n * `[unresolved refs: …]` line.\n *\n * The annotated string is what the LLM sees as `ToolMessage.content`.\n * The *original* (un-annotated) value is what gets stored in the\n * registry, so downstream piping remains pristine.\n *\n * @param content Raw (post-truncation) tool output.\n * @param key Reference key for this output, or undefined when\n * there is nothing to register (errors etc.).\n * @param unresolved Reference keys that failed to resolve during\n * argument substitution. Surfaced so the LLM can\n * self-correct its next tool call.\n */\nexport function annotateToolOutputWithReference(\n content: string,\n key: string | undefined,\n unresolved: string[] = []\n): string {\n const hasRefKey = key != null;\n const hasUnresolved = unresolved.length > 0;\n if (!hasRefKey && !hasUnresolved) {\n return content;\n }\n const trimmed = content.trimStart();\n if (trimmed.startsWith('{')) {\n const annotated = tryInjectRefIntoJsonObject(content, key, unresolved);\n if (annotated != null) {\n return annotated;\n }\n }\n const prefix = hasRefKey ? `${buildReferencePrefix(key!)}\\n` : '';\n const trailer = hasUnresolved\n ? `\\n[unresolved refs: ${unresolved.join(', ')}]`\n : '';\n return `${prefix}${content}${trailer}`;\n}\n\nfunction tryInjectRefIntoJsonObject(\n content: string,\n key: string | undefined,\n unresolved: string[]\n): string | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n\n const obj = parsed as Record<string, unknown>;\n const injectingRef = key != null;\n const injectingUnresolved = unresolved.length > 0;\n\n /**\n * Reject the JSON-injection path (fall back to prefix form) when\n * either of our keys collides with real payload data:\n * - `_ref` collision: existing value is non-null and differs from\n * the key we're about to inject.\n * - `_unresolved_refs` collision: existing value is non-null and\n * is not a deep-equal match for the array we'd inject.\n * This keeps us from silently overwriting legitimate tool output.\n */\n if (\n injectingRef &&\n TOOL_OUTPUT_REF_KEY in obj &&\n obj[TOOL_OUTPUT_REF_KEY] !== key &&\n obj[TOOL_OUTPUT_REF_KEY] != null\n ) {\n return null;\n }\n if (\n injectingUnresolved &&\n TOOL_OUTPUT_UNRESOLVED_KEY in obj &&\n obj[TOOL_OUTPUT_UNRESOLVED_KEY] != null &&\n !arraysShallowEqual(obj[TOOL_OUTPUT_UNRESOLVED_KEY], unresolved)\n ) {\n return null;\n }\n\n /**\n * Only strip the framework-owned key we're actually injecting —\n * leave everything else (including a pre-existing `_ref` on the\n * unresolved-only path, or a pre-existing `_unresolved_refs` on a\n * plain-annotation path) untouched so we annotate rather than\n * mutate downstream payload data. Our injected keys land first in\n * the serialized JSON so the LLM sees them before the body.\n */\n const omitKeys = new Set<string>();\n if (injectingRef) omitKeys.add(TOOL_OUTPUT_REF_KEY);\n if (injectingUnresolved) omitKeys.add(TOOL_OUTPUT_UNRESOLVED_KEY);\n const rest: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!omitKeys.has(k)) {\n rest[k] = v;\n }\n }\n const injected: Record<string, unknown> = {};\n if (injectingRef) {\n injected[TOOL_OUTPUT_REF_KEY] = key;\n }\n if (injectingUnresolved) {\n injected[TOOL_OUTPUT_UNRESOLVED_KEY] = unresolved;\n }\n Object.assign(injected, rest);\n\n const pretty = /^\\{\\s*\\n/.test(content);\n return pretty ? JSON.stringify(injected, null, 2) : JSON.stringify(injected);\n}\n\nfunction arraysShallowEqual(a: unknown, b: readonly string[]): boolean {\n if (!Array.isArray(a) || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Lazy projection that, given a registry and a runId, returns a new\n * `messages` array where each `ToolMessage` carrying ref metadata is\n * projected into a transient copy with annotated content (when the ref\n * is live in the registry) and with the framework-owned `additional_\n * kwargs` keys (`_refKey`, `_refScope`, `_unresolvedRefs`) stripped\n * regardless of whether annotation applied. The original input array\n * and its messages are never mutated.\n *\n * Annotation is gated on registry presence: a stale `_refKey` from a\n * prior run (e.g. one that survived in persisted history) silently\n * no-ops on the *content* side. The strip-metadata side still runs so\n * stale framework keys never leak onto the wire under any custom or\n * future provider serializer that might transmit `additional_kwargs`.\n * `_unresolvedRefs` is always meaningful and is not gated.\n *\n * **Feature-disabled fast path:** when the host hasn't enabled the\n * tool-output-reference feature, the registry is `undefined` and this\n * function returns the input array reference-equal *without iterating\n * a single message*. The loop is exclusive to the feature-enabled\n * code path.\n */\nexport function annotateMessagesForLLM(\n messages: BaseMessage[],\n registry: ToolOutputReferenceRegistry | undefined,\n runId: string | undefined\n): BaseMessage[] {\n if (registry == null) return messages;\n\n /**\n * Lazy-allocate the output array so the common case (no ToolMessage\n * carries framework metadata) returns the input reference-equal with\n * zero allocations beyond the per-message predicate checks.\n */\n let out: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m._getType() !== 'tool') continue;\n /**\n * `additional_kwargs` is untyped at the LangChain layer\n * (`Record<string, unknown>`), so persisted or client-supplied\n * ToolMessages can carry arbitrary shapes — including primitives\n * (a malformed serializer might write a string, or `null`).\n * Guard with a runtime object check before the `in` probes\n * because the `in` operator throws `TypeError` on primitives.\n * A single malformed message must never crash the provider call\n * path; skip its annotation/strip and continue.\n */\n const rawMeta = m.additional_kwargs as unknown;\n if (rawMeta == null || typeof rawMeta !== 'object') continue;\n const meta = rawMeta as Record<string, unknown>;\n const hasRefKey = '_refKey' in meta;\n const hasRefScope = '_refScope' in meta;\n const hasUnresolvedField = '_unresolvedRefs' in meta;\n if (!hasRefKey && !hasRefScope && !hasUnresolvedField) continue;\n\n const refKey = readRefKey(meta);\n const unresolved = readUnresolvedRefs(meta);\n\n /**\n * Prefer the message-stamped `_refScope` for the registry lookup.\n * For named runs it equals the current `runId`; for anonymous\n * invocations it carries the per-batch synthetic scope minted by\n * ToolNode (`\\0anon-<n>`), which `runId` from config cannot\n * recover. Falling back to `runId` keeps backward compatibility\n * with messages stamped before this field existed.\n */\n const lookupScope = readRefScope(meta) ?? runId;\n const liveRef =\n refKey != null && registry.has(lookupScope, refKey) ? refKey : undefined;\n const annotates = liveRef != null || unresolved.length > 0;\n\n const tm = m as ToolMessage;\n let nextContent: ToolMessage['content'] = tm.content;\n\n if (annotates && typeof tm.content === 'string') {\n nextContent = annotateToolOutputWithReference(\n tm.content,\n liveRef,\n unresolved\n );\n } else if (\n annotates &&\n Array.isArray(tm.content) &&\n unresolved.length > 0\n ) {\n const warningBlock = {\n type: 'text' as const,\n text: `[unresolved refs: ${unresolved.join(', ')}]`,\n };\n /**\n * `as unknown as ToolMessage['content']` is unavoidable here:\n * LangChain's content union (`MessageContentComplex[] |\n * DataContentBlock[] | string`) does not accept a freshly built\n * mixed array literal even though the structural shape is valid\n * at runtime. The double-cast is structurally safe — we\n * preserve every block from `tm.content` and prepend a single\n * `{ type: 'text', text }` block that all providers accept.\n */\n nextContent = [\n warningBlock,\n ...tm.content,\n ] as unknown as ToolMessage['content'];\n }\n\n /**\n * Project unconditionally: even when no annotation applies (stale\n * `_refKey` or non-annotatable content), `cloneToolMessageWithContent`\n * runs `stripFrameworkRefMetadata` on `additional_kwargs` so the\n * framework-owned keys never reach the wire.\n */\n out ??= messages.slice();\n out[i] = cloneToolMessageWithContent(tm, nextContent);\n }\n\n return out ?? messages;\n}\n\n/**\n * Reads `_refKey` defensively from untyped `additional_kwargs`. Returns\n * undefined for non-string values so a malformed field cannot poison\n * the registry lookup or downstream string operations.\n */\nfunction readRefKey(\n meta: Record<string, unknown> | undefined\n): string | undefined {\n const v = meta?._refKey;\n return typeof v === 'string' ? v : undefined;\n}\n\n/**\n * Reads `_refScope` defensively from untyped `additional_kwargs`.\n * Mirrors {@link readRefKey} — non-string scopes are dropped (the\n * caller falls back to the run-derived scope) rather than passed into\n * the registry as a malformed key.\n */\nfunction readRefScope(\n meta: Record<string, unknown> | undefined\n): string | undefined {\n const v = meta?._refScope;\n return typeof v === 'string' ? v : undefined;\n}\n\n/**\n * Reads `_unresolvedRefs` defensively from untyped `additional_kwargs`.\n * Returns an empty array for any non-array value, and filters out\n * non-string entries from a real array. Without this guard, a hydrated\n * ToolMessage carrying e.g. `_unresolvedRefs: 'tool0turn0'` would crash\n * `attemptInvoke` on the eventual `.length` / `.join(...)` call.\n */\nfunction readUnresolvedRefs(\n meta: Record<string, unknown> | undefined\n): string[] {\n const v = meta?._unresolvedRefs;\n if (!Array.isArray(v)) return [];\n const out: string[] = [];\n for (const item of v) {\n if (typeof item === 'string') out.push(item);\n }\n return out;\n}\n\n/**\n * Builds a fresh `ToolMessage` that mirrors `tm`'s identity fields with\n * the supplied `content`. Every `ToolMessage` field but `content` is\n * carried over so the projection is structurally identical to the\n * original from a LangChain serializer's perspective.\n *\n * `additional_kwargs` is rebuilt with the framework-owned ref keys\n * stripped. Defensive: LangChain's standard provider serializers do not\n * transmit `additional_kwargs` to provider HTTP APIs, but a custom\n * adapter or future LangChain change could. Stripping keeps the\n * implementation correct under any serializer behavior at the cost of a\n * shallow object spread per annotated message.\n */\nfunction cloneToolMessageWithContent(\n tm: ToolMessage,\n content: ToolMessage['content']\n): ToolMessage {\n return new ToolMessage({\n id: tm.id,\n name: tm.name,\n status: tm.status,\n artifact: tm.artifact,\n tool_call_id: tm.tool_call_id,\n response_metadata: tm.response_metadata,\n additional_kwargs: stripFrameworkRefMetadata(tm.additional_kwargs),\n content,\n });\n}\n\n/**\n * Returns a copy of `kwargs` with `_refKey`, `_refScope`, and\n * `_unresolvedRefs` removed. Returns the input reference-equal when\n * none of those keys are present so the no-strip path stays cheap;\n * returns `undefined` when stripping leaves the object empty so the\n * caller can drop the field entirely.\n */\nfunction stripFrameworkRefMetadata(\n kwargs: Record<string, unknown> | undefined\n): Record<string, unknown> | undefined {\n if (kwargs == null) return undefined;\n if (\n !('_refKey' in kwargs) &&\n !('_refScope' in kwargs) &&\n !('_unresolvedRefs' in kwargs)\n ) {\n return kwargs;\n }\n const { _refKey, _refScope, _unresolvedRefs, ...rest } = kwargs as Record<\n string,\n unknown\n > & {\n _refKey?: unknown;\n _refScope?: unknown;\n _unresolvedRefs?: unknown;\n };\n void _refKey;\n void _refScope;\n void _unresolvedRefs;\n return Object.keys(rest).length === 0 ? undefined : rest;\n}\n"],"names":["HARD_MAX_TOOL_RESULT_CHARS","HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE","calculateMaxTotalToolOutputSize","ToolMessage"],"mappings":"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"}
1
+ {"version":3,"file":"toolOutputReferences.cjs","sources":["../../../src/tools/toolOutputReferences.ts"],"sourcesContent":["/**\n * Tool output reference registry.\n *\n * When enabled via `RunConfig.toolOutputReferences.enabled`, ToolNode\n * stores each successful tool output under a stable key\n * (`tool<idx>turn<turn>`) where `idx` is the tool's position within a\n * ToolNode batch and `turn` is the batch index within the run\n * (incremented once per ToolNode invocation).\n *\n * Subsequent tool calls can pipe a previous output into their args by\n * embedding `{{tool<idx>turn<turn>}}` inside any string argument;\n * {@link ToolOutputReferenceRegistry.resolve} walks the args and\n * substitutes the placeholders immediately before invocation.\n *\n * The registry stores the *raw, untruncated* tool output so a later\n * `{{…}}` substitution pipes the full payload into the next tool —\n * even when the LLM only saw a head+tail-truncated preview in\n * `ToolMessage.content`. Outputs are stored without any annotation\n * (the `_ref` key or the `[ref: ...]` prefix seen by the LLM is\n * strictly a UX signal attached to `ToolMessage.content`). Keeping the\n * registry pristine means downstream bash/jq piping receives the\n * complete, verbatim output with no injected fields.\n */\n\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport {\n calculateMaxTotalToolOutputSize,\n HARD_MAX_TOOL_RESULT_CHARS,\n HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE,\n} from '@/utils/truncation';\n\n/**\n * Non-global matcher for a single `{{tool<i>turn<n>}}` placeholder.\n * Exported for consumers that want to detect references (e.g., syntax\n * highlighting, docs). The stateful `g` variant lives inside the\n * registry so nobody trips on `lastIndex`.\n */\nexport const TOOL_OUTPUT_REF_PATTERN = /\\{\\{(tool\\d+turn\\d+)\\}\\}/;\n\n/** Object key used when a parsed-object output has `_ref` injected. */\nexport const TOOL_OUTPUT_REF_KEY = '_ref';\n\n/**\n * Object key used to carry unresolved reference warnings on a parsed-\n * object output. Using a dedicated field instead of a trailing text\n * line keeps the annotated `ToolMessage.content` parseable as JSON for\n * downstream consumers that rely on the object shape.\n */\nexport const TOOL_OUTPUT_UNRESOLVED_KEY = '_unresolved_refs';\n\n/** Single-line prefix prepended to non-object tool outputs so the LLM sees the reference key. */\nexport function buildReferencePrefix(key: string): string {\n return `[ref: ${key}]`;\n}\n\n/** Stable registry key for a tool output. */\nexport function buildReferenceKey(toolIndex: number, turn: number): string {\n return `tool${toolIndex}turn${turn}`;\n}\n\nexport type ToolOutputReferenceRegistryOptions = {\n /** Maximum characters stored per registered output. */\n maxOutputSize?: number;\n /** Maximum total characters retained across all registered outputs. */\n maxTotalSize?: number;\n /**\n * Upper bound on the number of concurrently-tracked runs. When\n * exceeded, the oldest run bucket is evicted (FIFO). Defaults to 32.\n */\n maxActiveRuns?: number;\n};\n\n/**\n * Result of resolving placeholders in tool args.\n */\nexport type ResolveResult<T> = {\n /** Arguments with placeholders replaced. Same shape as the input. */\n resolved: T;\n /** Reference keys that were referenced but had no stored value. */\n unresolved: string[];\n};\n\n/**\n * Read-only view over a frozen registry snapshot. Returned by\n * {@link ToolOutputReferenceRegistry.snapshot} for callers that need\n * to resolve placeholders against the registry state at a specific\n * point in time, ignoring any subsequent registrations.\n */\nexport interface ToolOutputResolveView {\n resolve<T>(args: T): ResolveResult<T>;\n}\n\n/**\n * Pre-resolved arg map keyed by `toolCallId`. Used by the mixed\n * direct+event dispatch path to feed event calls' resolved args\n * (captured pre-batch) into the dispatcher without re-resolving\n * against the now-stale live registry.\n */\nexport type PreResolvedArgsMap = Map<\n string,\n { resolved: Record<string, unknown>; unresolved: string[] }\n>;\n\n/**\n * Per-call sink for resolved args, keyed by `toolCallId`. Threaded\n * as a per-batch local map so concurrent `ToolNode.run()` calls do\n * not race on shared sink state.\n */\nexport type ResolvedArgsByCallId = Map<string, Record<string, unknown>>;\n\nconst EMPTY_ENTRIES: ReadonlyMap<string, string> = new Map<string, string>();\n\n/**\n * Per-run state bucket held inside the registry. Each distinct\n * `run_id` gets its own bucket so overlapping concurrent runs on a\n * shared registry cannot leak outputs, turn counters, or warn-memos\n * into one another.\n */\nclass RunStateBucket {\n entries: Map<string, string> = new Map();\n totalSize: number = 0;\n turnCounter: number = 0;\n warnedNonStringTools: Set<string> = new Set();\n}\n\n/**\n * Anonymous (`run_id` absent) bucket key. Anonymous batches are\n * treated as fresh runs on every invocation — see `nextTurn`.\n */\nconst ANON_RUN_KEY = '\\0anon';\n\n/**\n * Default upper bound on the number of concurrently-tracked runs per\n * registry. When exceeded, the oldest run's bucket (by insertion\n * order) is evicted. Keeps memory bounded when a ToolNode is reused\n * across many runs without explicit `releaseRun` calls.\n */\nconst DEFAULT_MAX_ACTIVE_RUNS = 32;\n\n/**\n * Ordered map of reference-key → stored output, partitioned by run so\n * concurrent / interleaved runs sharing one registry cannot leak\n * outputs between each other.\n *\n * Each public method takes a `runId` which selects the run's bucket.\n * Hosts typically get one registry per run via `Graph`, in which\n * case only a single bucket is ever populated; the partitioning\n * exists so the registry also behaves correctly when a single\n * instance is reused directly.\n */\nexport class ToolOutputReferenceRegistry {\n private runStates: Map<string, RunStateBucket> = new Map();\n private readonly maxOutputSize: number;\n private readonly maxTotalSize: number;\n private readonly maxActiveRuns: number;\n /**\n * Local stateful matcher used only by `replaceInString`. Kept\n * off-module so callers of the exported `TOOL_OUTPUT_REF_PATTERN`\n * never see a stale `lastIndex`.\n */\n private static readonly PLACEHOLDER_MATCHER = /\\{\\{(tool\\d+turn\\d+)\\}\\}/g;\n\n constructor(options: ToolOutputReferenceRegistryOptions = {}) {\n /**\n * Per-output default is the same ~400 KB budget as the standard\n * tool-result truncation (`HARD_MAX_TOOL_RESULT_CHARS`). This\n * keeps a single `{{…}}` substitution at a size that is safe to\n * pass through typical shell `ARG_MAX` limits and matches what\n * the LLM would otherwise have seen. Hosts that want larger per-\n * output payloads (API consumers, long JSON streams) can raise\n * the cap explicitly up to the 5 MB total budget.\n */\n const perOutput =\n options.maxOutputSize != null && options.maxOutputSize > 0\n ? options.maxOutputSize\n : HARD_MAX_TOOL_RESULT_CHARS;\n /**\n * Clamp a caller-supplied `maxTotalSize` to\n * `HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE` (5 MB) so the documented\n * absolute cap is enforced regardless of host config —\n * `calculateMaxTotalToolOutputSize` already applies the same\n * upper bound on its computed default, but the user-provided\n * branch was bypassing it.\n */\n const totalRaw =\n options.maxTotalSize != null && options.maxTotalSize > 0\n ? Math.min(options.maxTotalSize, HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE)\n : calculateMaxTotalToolOutputSize(perOutput);\n this.maxTotalSize = totalRaw;\n /**\n * The per-output cap can never exceed the per-run aggregate cap:\n * if a single entry were allowed to be larger than `maxTotalSize`,\n * the eviction loop would either blow the cap (to keep the entry)\n * or self-evict a just-stored value. Clamping here turns\n * `maxTotalSize` into a hard upper bound on *any* state the\n * registry retains per run.\n */\n this.maxOutputSize = Math.min(perOutput, totalRaw);\n this.maxActiveRuns =\n options.maxActiveRuns != null && options.maxActiveRuns > 0\n ? options.maxActiveRuns\n : DEFAULT_MAX_ACTIVE_RUNS;\n }\n\n private keyFor(runId: string | undefined): string {\n return runId ?? ANON_RUN_KEY;\n }\n\n private getOrCreate(runId: string | undefined): RunStateBucket {\n const key = this.keyFor(runId);\n let state = this.runStates.get(key);\n if (state == null) {\n state = new RunStateBucket();\n this.runStates.set(key, state);\n if (this.runStates.size > this.maxActiveRuns) {\n const oldest = this.runStates.keys().next().value;\n if (oldest != null && oldest !== key) {\n this.runStates.delete(oldest);\n }\n }\n }\n return state;\n }\n\n /** Registers (or replaces) the output stored under `key` for `runId`. */\n set(runId: string | undefined, key: string, value: string): void {\n const bucket = this.getOrCreate(runId);\n const clipped =\n value.length > this.maxOutputSize\n ? value.slice(0, this.maxOutputSize)\n : value;\n const existing = bucket.entries.get(key);\n if (existing != null) {\n bucket.totalSize -= existing.length;\n bucket.entries.delete(key);\n }\n bucket.entries.set(key, clipped);\n bucket.totalSize += clipped.length;\n this.evictWithinBucket(bucket);\n }\n\n /** Returns the stored value for `key` in `runId`'s bucket, or `undefined`. */\n get(runId: string | undefined, key: string): string | undefined {\n return this.runStates.get(this.keyFor(runId))?.entries.get(key);\n }\n\n /**\n * Returns `true` when `key` is currently stored in `runId`'s bucket.\n * Used by {@link annotateMessagesForLLM} to gate transient annotation\n * on whether the registry still owns the referenced output (a stale\n * `_refKey` from a prior run silently no-ops here).\n */\n has(runId: string | undefined, key: string): boolean {\n return this.runStates.get(this.keyFor(runId))?.entries.has(key) ?? false;\n }\n\n /** Total number of registered outputs across every run bucket. */\n get size(): number {\n let n = 0;\n for (const bucket of this.runStates.values()) {\n n += bucket.entries.size;\n }\n return n;\n }\n\n /** Maximum characters retained per output (post-clip). */\n get perOutputLimit(): number {\n return this.maxOutputSize;\n }\n\n /** Maximum total characters retained *per run*. */\n get totalLimit(): number {\n return this.maxTotalSize;\n }\n\n /** Drops every run's state. */\n clear(): void {\n this.runStates.clear();\n }\n\n /**\n * Explicitly release `runId`'s state. Safe to call when a run has\n * finished. Hosts sharing one registry across runs should call this\n * to reclaim memory deterministically; otherwise LRU eviction kicks\n * in when `maxActiveRuns` runs accumulate.\n */\n releaseRun(runId: string | undefined): void {\n this.runStates.delete(this.keyFor(runId));\n }\n\n /**\n * Claims the next batch turn synchronously from `runId`'s bucket.\n *\n * Must be called once at the start of each ToolNode batch before\n * any `await`, so concurrent invocations within the same run see\n * distinct turn values (reads are effectively atomic by JS's\n * single-threaded execution of the sync prefix).\n *\n * If `runId` is missing the anonymous bucket is dropped and a\n * fresh one created so each anonymous call behaves as its own run.\n */\n nextTurn(runId: string | undefined): number {\n if (runId == null) {\n this.runStates.delete(ANON_RUN_KEY);\n }\n const bucket = this.getOrCreate(runId);\n return bucket.turnCounter++;\n }\n\n /**\n * Records that `toolName` has been warned about in `runId` (returns\n * `true` on the first call per run, `false` after). Used by\n * ToolNode to emit one log line per offending tool per run when a\n * `ToolMessage.content` isn't a string.\n */\n claimWarnOnce(runId: string | undefined, toolName: string): boolean {\n const bucket = this.getOrCreate(runId);\n if (bucket.warnedNonStringTools.has(toolName)) {\n return false;\n }\n bucket.warnedNonStringTools.add(toolName);\n return true;\n }\n\n /**\n * Walks `args` and replaces every `{{tool<i>turn<n>}}` placeholder in\n * string values with the stored output *from `runId`'s bucket*. Non-\n * string values and object keys are left untouched. Unresolved\n * references are left in-place and reported so the caller can\n * surface them to the LLM. When no placeholder appears anywhere in\n * the serialized args, the original input is returned without\n * walking the tree.\n */\n resolve<T>(runId: string | undefined, args: T): ResolveResult<T> {\n if (!hasAnyPlaceholder(args)) {\n return { resolved: args, unresolved: [] };\n }\n const bucket = this.runStates.get(this.keyFor(runId));\n return this.resolveAgainst(bucket?.entries ?? EMPTY_ENTRIES, args);\n }\n\n /**\n * Captures a frozen snapshot of `runId`'s current entries and\n * returns a view that resolves placeholders against *only* that\n * snapshot. The snapshot is decoupled from the live registry, so\n * subsequent `set()` calls (for example, same-turn direct outputs\n * registering while an event branch is still in flight) are\n * invisible to the snapshot's `resolve`. Used by the mixed\n * direct+event dispatch path to preserve same-turn isolation when\n * a `PreToolUse` hook rewrites event args after directs have\n * completed.\n */\n snapshot(runId: string | undefined): ToolOutputResolveView {\n const bucket = this.runStates.get(this.keyFor(runId));\n const entries: ReadonlyMap<string, string> = bucket\n ? new Map(bucket.entries)\n : EMPTY_ENTRIES;\n return {\n resolve: <T>(args: T): ResolveResult<T> =>\n this.resolveAgainst(entries, args),\n };\n }\n\n private resolveAgainst<T>(\n entries: ReadonlyMap<string, string>,\n args: T\n ): ResolveResult<T> {\n if (!hasAnyPlaceholder(args)) {\n return { resolved: args, unresolved: [] };\n }\n const unresolved = new Set<string>();\n const resolved = this.transform(entries, args, unresolved) as T;\n return { resolved, unresolved: Array.from(unresolved) };\n }\n\n private transform(\n entries: ReadonlyMap<string, string>,\n value: unknown,\n unresolved: Set<string>\n ): unknown {\n if (typeof value === 'string') {\n return this.replaceInString(entries, value, unresolved);\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.transform(entries, item, unresolved));\n }\n if (value !== null && typeof value === 'object') {\n const source = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(source)) {\n next[key] = this.transform(entries, item, unresolved);\n }\n return next;\n }\n return value;\n }\n\n private replaceInString(\n entries: ReadonlyMap<string, string>,\n input: string,\n unresolved: Set<string>\n ): string {\n if (input.indexOf('{{tool') === -1) {\n return input;\n }\n return input.replace(\n ToolOutputReferenceRegistry.PLACEHOLDER_MATCHER,\n (match, key: string) => {\n const stored = entries.get(key);\n if (stored == null) {\n unresolved.add(key);\n return match;\n }\n return stored;\n }\n );\n }\n\n private evictWithinBucket(bucket: RunStateBucket): void {\n if (bucket.totalSize <= this.maxTotalSize) {\n return;\n }\n for (const key of bucket.entries.keys()) {\n if (bucket.totalSize <= this.maxTotalSize) {\n return;\n }\n const entry = bucket.entries.get(key);\n if (entry == null) {\n continue;\n }\n bucket.totalSize -= entry.length;\n bucket.entries.delete(key);\n }\n }\n}\n\n/**\n * Cheap pre-check: returns true if any string value in `args` contains\n * the `{{tool` substring. Lets `resolve()` skip the deep tree walk (and\n * its object allocations) for the common case of plain args.\n */\nfunction hasAnyPlaceholder(value: unknown): boolean {\n if (typeof value === 'string') {\n return value.indexOf('{{tool') !== -1;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n if (hasAnyPlaceholder(item)) {\n return true;\n }\n }\n return false;\n }\n if (value !== null && typeof value === 'object') {\n for (const item of Object.values(value as Record<string, unknown>)) {\n if (hasAnyPlaceholder(item)) {\n return true;\n }\n }\n return false;\n }\n return false;\n}\n\n/**\n * Annotates `content` with a reference key and/or unresolved-ref\n * warnings so the LLM sees both alongside the tool output.\n *\n * Behavior:\n * - If `content` parses as a plain (non-array, non-null) JSON object\n * and the object does not already have a conflicting `_ref` key,\n * the reference key and (when present) `_unresolved_refs` array\n * are injected as object fields, preserving JSON validity for\n * downstream consumers that parse the output.\n * - Otherwise (string output, JSON array/primitive, parse failure,\n * or `_ref` collision), a `[ref: <key>]\\n` prefix line is\n * prepended and unresolved refs are appended as a trailing\n * `[unresolved refs: …]` line.\n *\n * The annotated string is what the LLM sees as `ToolMessage.content`.\n * The *original* (un-annotated) value is what gets stored in the\n * registry, so downstream piping remains pristine.\n *\n * @param content Raw (post-truncation) tool output.\n * @param key Reference key for this output, or undefined when\n * there is nothing to register (errors etc.).\n * @param unresolved Reference keys that failed to resolve during\n * argument substitution. Surfaced so the LLM can\n * self-correct its next tool call.\n */\nexport function annotateToolOutputWithReference(\n content: string,\n key: string | undefined,\n unresolved: string[] = []\n): string {\n const hasRefKey = key != null;\n const hasUnresolved = unresolved.length > 0;\n if (!hasRefKey && !hasUnresolved) {\n return content;\n }\n const trimmed = content.trimStart();\n if (trimmed.startsWith('{')) {\n const annotated = tryInjectRefIntoJsonObject(content, key, unresolved);\n if (annotated != null) {\n return annotated;\n }\n }\n const prefix = hasRefKey ? `${buildReferencePrefix(key!)}\\n` : '';\n const trailer = hasUnresolved\n ? `\\n[unresolved refs: ${unresolved.join(', ')}]`\n : '';\n return `${prefix}${content}${trailer}`;\n}\n\nfunction tryInjectRefIntoJsonObject(\n content: string,\n key: string | undefined,\n unresolved: string[]\n): string | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n\n const obj = parsed as Record<string, unknown>;\n const injectingRef = key != null;\n const injectingUnresolved = unresolved.length > 0;\n\n /**\n * Reject the JSON-injection path (fall back to prefix form) when\n * either of our keys collides with real payload data:\n * - `_ref` collision: existing value is non-null and differs from\n * the key we're about to inject.\n * - `_unresolved_refs` collision: existing value is non-null and\n * is not a deep-equal match for the array we'd inject.\n * This keeps us from silently overwriting legitimate tool output.\n */\n if (\n injectingRef &&\n TOOL_OUTPUT_REF_KEY in obj &&\n obj[TOOL_OUTPUT_REF_KEY] !== key &&\n obj[TOOL_OUTPUT_REF_KEY] != null\n ) {\n return null;\n }\n if (\n injectingUnresolved &&\n TOOL_OUTPUT_UNRESOLVED_KEY in obj &&\n obj[TOOL_OUTPUT_UNRESOLVED_KEY] != null &&\n !arraysShallowEqual(obj[TOOL_OUTPUT_UNRESOLVED_KEY], unresolved)\n ) {\n return null;\n }\n\n /**\n * Only strip the framework-owned key we're actually injecting —\n * leave everything else (including a pre-existing `_ref` on the\n * unresolved-only path, or a pre-existing `_unresolved_refs` on a\n * plain-annotation path) untouched so we annotate rather than\n * mutate downstream payload data. Our injected keys land first in\n * the serialized JSON so the LLM sees them before the body.\n */\n const omitKeys = new Set<string>();\n if (injectingRef) omitKeys.add(TOOL_OUTPUT_REF_KEY);\n if (injectingUnresolved) omitKeys.add(TOOL_OUTPUT_UNRESOLVED_KEY);\n const rest: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!omitKeys.has(k)) {\n rest[k] = v;\n }\n }\n const injected: Record<string, unknown> = {};\n if (injectingRef) {\n injected[TOOL_OUTPUT_REF_KEY] = key;\n }\n if (injectingUnresolved) {\n injected[TOOL_OUTPUT_UNRESOLVED_KEY] = unresolved;\n }\n Object.assign(injected, rest);\n\n const pretty = /^\\{\\s*\\n/.test(content);\n return pretty ? JSON.stringify(injected, null, 2) : JSON.stringify(injected);\n}\n\nfunction arraysShallowEqual(a: unknown, b: readonly string[]): boolean {\n if (!Array.isArray(a) || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Lazy projection that, given a registry and a runId, returns a new\n * `messages` array where each `ToolMessage` carrying ref metadata is\n * projected into a transient copy with annotated content (when the ref\n * is live in the registry) and with the framework-owned `additional_\n * kwargs` keys (`_refKey`, `_refScope`, `_unresolvedRefs`) stripped\n * regardless of whether annotation applied. The original input array\n * and its messages are never mutated.\n *\n * Annotation is gated on registry presence: a stale `_refKey` from a\n * prior run (e.g. one that survived in persisted history) silently\n * no-ops on the *content* side. The strip-metadata side still runs so\n * stale framework keys never leak onto the wire under any custom or\n * future provider serializer that might transmit `additional_kwargs`.\n * `_unresolvedRefs` is always meaningful and is not gated.\n *\n * **Feature-disabled fast path:** when the host hasn't enabled the\n * tool-output-reference feature, the registry is `undefined` and this\n * function returns the input array reference-equal *without iterating\n * a single message*. The loop is exclusive to the feature-enabled\n * code path.\n */\nexport function annotateMessagesForLLM(\n messages: BaseMessage[],\n registry: ToolOutputReferenceRegistry | undefined,\n runId: string | undefined\n): BaseMessage[] {\n if (registry == null) return messages;\n\n /**\n * Lazy-allocate the output array so the common case (no ToolMessage\n * carries framework metadata) returns the input reference-equal with\n * zero allocations beyond the per-message predicate checks.\n */\n let out: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m._getType() !== 'tool') continue;\n /**\n * `additional_kwargs` is untyped at the LangChain layer\n * (`Record<string, unknown>`), so persisted or client-supplied\n * ToolMessages can carry arbitrary shapes — including primitives\n * (a malformed serializer might write a string, or `null`).\n * Guard with a runtime object check before the `in` probes\n * because the `in` operator throws `TypeError` on primitives.\n * A single malformed message must never crash the provider call\n * path; skip its annotation/strip and continue.\n */\n const rawMeta = m.additional_kwargs as unknown;\n if (rawMeta == null || typeof rawMeta !== 'object') continue;\n const meta = rawMeta as Record<string, unknown>;\n const hasRefKey = '_refKey' in meta;\n const hasRefScope = '_refScope' in meta;\n const hasUnresolvedField = '_unresolvedRefs' in meta;\n if (!hasRefKey && !hasRefScope && !hasUnresolvedField) continue;\n\n const refKey = readRefKey(meta);\n const unresolved = readUnresolvedRefs(meta);\n\n /**\n * Prefer the message-stamped `_refScope` for the registry lookup.\n * For named runs it equals the current `runId`; for anonymous\n * invocations it carries the per-batch synthetic scope minted by\n * ToolNode (`\\0anon-<n>`), which `runId` from config cannot\n * recover. Falling back to `runId` keeps backward compatibility\n * with messages stamped before this field existed.\n */\n const lookupScope = readRefScope(meta) ?? runId;\n const liveRef =\n refKey != null && registry.has(lookupScope, refKey) ? refKey : undefined;\n const annotates = liveRef != null || unresolved.length > 0;\n\n const tm = m as ToolMessage;\n let nextContent: ToolMessage['content'] = tm.content;\n\n if (annotates && typeof tm.content === 'string') {\n nextContent = annotateToolOutputWithReference(\n tm.content,\n liveRef,\n unresolved\n );\n } else if (\n annotates &&\n Array.isArray(tm.content) &&\n unresolved.length > 0\n ) {\n const warningBlock = {\n type: 'text' as const,\n text: `[unresolved refs: ${unresolved.join(', ')}]`,\n };\n /**\n * `as unknown as ToolMessage['content']` is unavoidable here:\n * LangChain's content union (`MessageContentComplex[] |\n * DataContentBlock[] | string`) does not accept a freshly built\n * mixed array literal even though the structural shape is valid\n * at runtime. The double-cast is structurally safe — we\n * preserve every block from `tm.content` and prepend a single\n * `{ type: 'text', text }` block that all providers accept.\n */\n nextContent = [\n warningBlock,\n ...tm.content,\n ] as unknown as ToolMessage['content'];\n }\n\n /**\n * Project unconditionally: even when no annotation applies (stale\n * `_refKey` or non-annotatable content), `cloneToolMessageWithContent`\n * runs `stripFrameworkRefMetadata` on `additional_kwargs` so the\n * framework-owned keys never reach the wire.\n */\n out ??= messages.slice();\n out[i] = cloneToolMessageWithContent(tm, nextContent);\n }\n\n return out ?? messages;\n}\n\n/**\n * Reads `_refKey` defensively from untyped `additional_kwargs`. Returns\n * undefined for non-string values so a malformed field cannot poison\n * the registry lookup or downstream string operations.\n */\nfunction readRefKey(\n meta: Record<string, unknown> | undefined\n): string | undefined {\n const v = meta?._refKey;\n return typeof v === 'string' ? v : undefined;\n}\n\n/**\n * Reads `_refScope` defensively from untyped `additional_kwargs`.\n * Mirrors {@link readRefKey} — non-string scopes are dropped (the\n * caller falls back to the run-derived scope) rather than passed into\n * the registry as a malformed key.\n */\nfunction readRefScope(\n meta: Record<string, unknown> | undefined\n): string | undefined {\n const v = meta?._refScope;\n return typeof v === 'string' ? v : undefined;\n}\n\n/**\n * Reads `_unresolvedRefs` defensively from untyped `additional_kwargs`.\n * Returns an empty array for any non-array value, and filters out\n * non-string entries from a real array. Without this guard, a hydrated\n * ToolMessage carrying e.g. `_unresolvedRefs: 'tool0turn0'` would crash\n * `attemptInvoke` on the eventual `.length` / `.join(...)` call.\n */\nfunction readUnresolvedRefs(\n meta: Record<string, unknown> | undefined\n): string[] {\n const v = meta?._unresolvedRefs;\n if (!Array.isArray(v)) return [];\n const out: string[] = [];\n for (const item of v) {\n if (typeof item === 'string') out.push(item);\n }\n return out;\n}\n\n/**\n * Builds a fresh `ToolMessage` that mirrors `tm`'s identity fields with\n * the supplied `content`. Every `ToolMessage` field but `content` is\n * carried over so the projection is structurally identical to the\n * original from a LangChain serializer's perspective.\n *\n * `additional_kwargs` is rebuilt with the framework-owned ref keys\n * stripped. Defensive: LangChain's standard provider serializers do not\n * transmit `additional_kwargs` to provider HTTP APIs, but a custom\n * adapter or future LangChain change could. Stripping keeps the\n * implementation correct under any serializer behavior at the cost of a\n * shallow object spread per annotated message.\n */\nfunction cloneToolMessageWithContent(\n tm: ToolMessage,\n content: ToolMessage['content']\n): ToolMessage {\n return new ToolMessage({\n id: tm.id,\n name: tm.name,\n status: tm.status,\n artifact: tm.artifact,\n tool_call_id: tm.tool_call_id,\n response_metadata: tm.response_metadata,\n additional_kwargs: stripFrameworkRefMetadata(tm.additional_kwargs),\n content,\n });\n}\n\n/**\n * Returns a copy of `kwargs` with `_refKey`, `_refScope`, and\n * `_unresolvedRefs` removed. Returns the input reference-equal when\n * none of those keys are present so the no-strip path stays cheap;\n * returns `undefined` when stripping leaves the object empty so the\n * caller can drop the field entirely.\n */\nfunction stripFrameworkRefMetadata(\n kwargs: Record<string, unknown> | undefined\n): Record<string, unknown> | undefined {\n if (kwargs == null) return undefined;\n if (\n !('_refKey' in kwargs) &&\n !('_refScope' in kwargs) &&\n !('_unresolvedRefs' in kwargs)\n ) {\n return kwargs;\n }\n const { _refKey, _refScope, _unresolvedRefs, ...rest } = kwargs as Record<\n string,\n unknown\n > & {\n _refKey?: unknown;\n _refScope?: unknown;\n _unresolvedRefs?: unknown;\n };\n void _refKey;\n void _refScope;\n void _unresolvedRefs;\n return Object.keys(rest).length === 0 ? undefined : rest;\n}\n"],"names":["HARD_MAX_TOOL_RESULT_CHARS","HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE","calculateMaxTotalToolOutputSize","ToolMessage"],"mappings":"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"}
@@ -12,6 +12,7 @@ var _enum = require('../common/enum.cjs');
12
12
  async function safeDispatchCustomEvent(event, payload, config) {
13
13
  try {
14
14
  await dispatch.dispatchCustomEvent(event, payload, config);
15
+ return true;
15
16
  }
16
17
  catch (e) {
17
18
  // Check if this is the known EventStreamCallbackHandler error
@@ -21,10 +22,11 @@ async function safeDispatchCustomEvent(event, payload, config) {
21
22
  // Suppress this specific error - it's expected during parallel execution
22
23
  // when EventStreamCallbackHandler loses track of run IDs
23
24
  // console.debug('Suppressed error dispatching custom event:', e);
24
- return;
25
+ return false;
25
26
  }
26
27
  // Log other errors
27
28
  console.error('Error dispatching custom event:', e);
29
+ return false;
28
30
  }
29
31
  }
30
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"events.cjs","sources":["../../../src/utils/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/utils/events.ts\nimport { dispatchCustomEvent } from '@langchain/core/callbacks/dispatch';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type { AgentLogEvent } from '@/types/graph';\nimport { GraphEvents } from '@/common';\n\n/**\n * Safely dispatches a custom event and properly awaits it to avoid\n * race conditions where events are dispatched after run cleanup.\n */\nexport async function safeDispatchCustomEvent(\n event: string,\n payload: unknown,\n config?: RunnableConfig\n): Promise<void> {\n try {\n await dispatchCustomEvent(event, payload, config);\n } catch (e) {\n // Check if this is the known EventStreamCallbackHandler error\n if (\n e instanceof Error &&\n e.message.includes('handleCustomEvent: Run ID') &&\n e.message.includes('not found in run map')\n ) {\n // Suppress this specific error - it's expected during parallel execution\n // when EventStreamCallbackHandler loses track of run IDs\n // console.debug('Suppressed error dispatching custom event:', e);\n return;\n }\n // Log other errors\n console.error('Error dispatching custom event:', e);\n }\n}\n\n/**\n * Fire-and-forget diagnostic log event.\n * Debug-level logs are gated behind AGENT_DEBUG_LOGGING=true to avoid\n * overhead in production. Info/warn/error always flow through.\n * Pass `force: true` to bypass the env-var gate (e.g. invoke timing).\n */\nexport function emitAgentLog(\n config: RunnableConfig | undefined,\n level: AgentLogEvent['level'],\n scope: AgentLogEvent['scope'],\n message: string,\n data?: Record<string, unknown>,\n meta?: { runId?: string; agentId?: string },\n options?: { force?: boolean }\n): void {\n if (!config) return;\n if (\n level === 'debug' &&\n !(options?.force ?? false) &&\n process.env.AGENT_DEBUG_LOGGING !== 'true'\n )\n return;\n void safeDispatchCustomEvent(\n GraphEvents.ON_AGENT_LOG,\n { level, scope, message, data, ...meta } satisfies AgentLogEvent,\n config\n );\n}\n"],"names":["dispatchCustomEvent","GraphEvents"],"mappings":";;;;;AAAA;AACA;AAMA;;;AAGG;AACI,eAAe,uBAAuB,CAC3C,KAAa,EACb,OAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,IAAI;QACF,MAAMA,4BAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC;IACnD;IAAE,OAAO,CAAC,EAAE;;QAEV,IACE,CAAC,YAAY,KAAK;AAClB,YAAA,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC/C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAC1C;;;;YAIA;QACF;;AAEA,QAAA,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC;IACrD;AACF;AAEA;;;;;AAKG;AACG,SAAU,YAAY,CAC1B,MAAkC,EAClC,KAA6B,EAC7B,KAA6B,EAC7B,OAAe,EACf,IAA8B,EAC9B,IAA2C,EAC3C,OAA6B,EAAA;AAE7B,IAAA,IAAI,CAAC,MAAM;QAAE;IACb,IACE,KAAK,KAAK,OAAO;AACjB,QAAA,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;AAC1B,QAAA,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM;QAE1C;IACF,KAAK,uBAAuB,CAC1BC,iBAAW,CAAC,YAAY,EACxB,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,EAA0B,EAChE,MAAM,CACP;AACH;;;;;"}
1
+ {"version":3,"file":"events.cjs","sources":["../../../src/utils/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/utils/events.ts\nimport { dispatchCustomEvent } from '@langchain/core/callbacks/dispatch';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type { AgentLogEvent } from '@/types/graph';\nimport { GraphEvents } from '@/common';\n\n/**\n * Safely dispatches a custom event and properly awaits it to avoid\n * race conditions where events are dispatched after run cleanup.\n */\nexport async function safeDispatchCustomEvent(\n event: string,\n payload: unknown,\n config?: RunnableConfig\n): Promise<boolean | void> {\n try {\n await dispatchCustomEvent(event, payload, config);\n return true;\n } catch (e) {\n // Check if this is the known EventStreamCallbackHandler error\n if (\n e instanceof Error &&\n e.message.includes('handleCustomEvent: Run ID') &&\n e.message.includes('not found in run map')\n ) {\n // Suppress this specific error - it's expected during parallel execution\n // when EventStreamCallbackHandler loses track of run IDs\n // console.debug('Suppressed error dispatching custom event:', e);\n return false;\n }\n // Log other errors\n console.error('Error dispatching custom event:', e);\n return false;\n }\n}\n\n/**\n * Fire-and-forget diagnostic log event.\n * Debug-level logs are gated behind AGENT_DEBUG_LOGGING=true to avoid\n * overhead in production. Info/warn/error always flow through.\n * Pass `force: true` to bypass the env-var gate (e.g. invoke timing).\n */\nexport function emitAgentLog(\n config: RunnableConfig | undefined,\n level: AgentLogEvent['level'],\n scope: AgentLogEvent['scope'],\n message: string,\n data?: Record<string, unknown>,\n meta?: { runId?: string; agentId?: string },\n options?: { force?: boolean }\n): void {\n if (!config) return;\n if (\n level === 'debug' &&\n !(options?.force ?? false) &&\n process.env.AGENT_DEBUG_LOGGING !== 'true'\n )\n return;\n void safeDispatchCustomEvent(\n GraphEvents.ON_AGENT_LOG,\n { level, scope, message, data, ...meta } satisfies AgentLogEvent,\n config\n );\n}\n"],"names":["dispatchCustomEvent","GraphEvents"],"mappings":";;;;;AAAA;AACA;AAMA;;;AAGG;AACI,eAAe,uBAAuB,CAC3C,KAAa,EACb,OAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,IAAI;QACF,MAAMA,4BAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC;AACjD,QAAA,OAAO,IAAI;IACb;IAAE,OAAO,CAAC,EAAE;;QAEV,IACE,CAAC,YAAY,KAAK;AAClB,YAAA,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC/C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAC1C;;;;AAIA,YAAA,OAAO,KAAK;QACd;;AAEA,QAAA,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC;AACnD,QAAA,OAAO,KAAK;IACd;AACF;AAEA;;;;;AAKG;AACG,SAAU,YAAY,CAC1B,MAAkC,EAClC,KAA6B,EAC7B,KAA6B,EAC7B,OAAe,EACf,IAA8B,EAC9B,IAA2C,EAC3C,OAA6B,EAAA;AAE7B,IAAA,IAAI,CAAC,MAAM;QAAE;IACb,IACE,KAAK,KAAK,OAAO;AACjB,QAAA,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;AAC1B,QAAA,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM;QAE1C;IACF,KAAK,uBAAuB,CAC1BC,iBAAW,CAAC,YAAY,EACxB,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,EAA0B,EAChE,MAAM,CACP;AACH;;;;;"}
@@ -75,6 +75,14 @@ class Graph {
75
75
  /** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
76
76
  invokedToolIds;
77
77
  handlerRegistry;
78
+ /**
79
+ * True when event-driven tool execution can be routed through callbacks even
80
+ * though this graph intentionally does not own the full handler registry.
81
+ * Self-spawned subagent graphs use this shape: their callback forwarder sends
82
+ * `ON_TOOL_EXECUTE` to the parent's handler, while child run-step events stay
83
+ * wrapped as `ON_SUBAGENT_UPDATE` instead of leaking as parent events.
84
+ */
85
+ eventToolExecutionAvailable = false;
78
86
  hookRegistry;
79
87
  /**
80
88
  * Run-scoped HITL configuration. When `humanInTheLoop?.enabled` is
@@ -1125,7 +1133,23 @@ class StandardGraph extends Graph {
1125
1133
  parentAgentId: agentContext.agentId,
1126
1134
  tokenCounter: agentContext.tokenCounter,
1127
1135
  maxDepth: effectiveSubagentDepth,
1128
- createChildGraph: (input) => new StandardGraph(input),
1136
+ createChildGraph: (input) => {
1137
+ const childGraph = new StandardGraph(input);
1138
+ childGraph.hookRegistry = this.hookRegistry;
1139
+ /**
1140
+ * Do not propagate `humanInTheLoop` into the child graph yet:
1141
+ * nested subagent interrupts need a stable child checkpoint and
1142
+ * resume bridge. Child hooks still fire; `ask` decisions fail
1143
+ * closed inside the subagent until that flow is implemented.
1144
+ */
1145
+ childGraph.toolOutputReferences = this.toolOutputReferences;
1146
+ childGraph.eagerEventToolExecution = this.eagerEventToolExecution;
1147
+ childGraph.toolExecution = this.toolExecution;
1148
+ childGraph.eventToolExecutionAvailable =
1149
+ this.handlerRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) !=
1150
+ null;
1151
+ return childGraph;
1152
+ },
1129
1153
  });
1130
1154
  const subagentTool = tool(async (rawInput, config) => {
1131
1155
  const input = rawInput;