@@ -192,6 +192,7 @@ export async function runProgrammaticStep(
192192 agentType : string
193193 chunk : string
194194 prompt ?: string
195+ forwardToPrompt ?: boolean
195196 } ) => {
196197 sendAction ( {
197198 action : {
@@ -275,15 +276,18 @@ export async function runProgrammaticStep(
275276 role : 'assistant' as const ,
276277 content : toolCallString ,
277278 } )
278- state . sendSubagentChunk ( {
279+ // Optional call handles both top-level and nested agents
280+ state . sendSubagentChunk ?.( {
279281 userInputId,
280282 agentId : state . agentState . agentId ,
281283 agentType : state . agentState . agentType ! ,
282284 chunk : toolCallString ,
285+ forwardToPrompt : ! state . agentState . parentId ,
283286 } )
284287 }
285288
286289 // Execute the tool synchronously and get the result immediately
290+ // Wrap onResponseChunk to add parentAgentId to nested agent events
287291 await executeToolCall ( {
288292 ...params ,
289293 toolName : toolCall . toolName ,
@@ -299,6 +303,70 @@ export async function runProgrammaticStep(
299303 autoInsertEndStepParam : true ,
300304 excludeToolFromMessageHistory,
301305 fromHandleSteps : true ,
306+ onResponseChunk : ( chunk : string | PrintModeEvent ) => {
307+ if ( typeof chunk === 'string' ) {
308+ onResponseChunk ( chunk )
309+ return
310+ }
311+
312+ // Only add parentAgentId if this programmatic agent has a parent (i.e., it's nested)
313+ // This ensures we don't add parentAgentId to top-level spawns
314+ if ( state . agentState . parentId ) {
315+ const parentAgentId = state . agentState . agentId
316+
317+ switch ( chunk . type ) {
318+ case 'subagent_start' :
319+ case 'subagent_finish' :
320+ if ( ! chunk . parentAgentId ) {
321+ logger . debug (
322+ {
323+ eventType : chunk . type ,
324+ agentId : chunk . agentId ,
325+ parentId : parentAgentId ,
326+ } ,
327+ `run-programmatic-step: Adding parentAgentId to ${ chunk . type } event` ,
328+ )
329+ onResponseChunk ( {
330+ ...chunk ,
331+ parentAgentId,
332+ } )
333+ return
334+ }
335+ break
336+ case 'tool_call' :
337+ case 'tool_result' : {
338+ if ( ! chunk . parentAgentId ) {
339+ const debugPayload =
340+ chunk . type === 'tool_call'
341+ ? {
342+ eventType : chunk . type ,
343+ agentId : chunk . agentId ,
344+ parentId : parentAgentId ,
345+ }
346+ : {
347+ eventType : chunk . type ,
348+ parentId : parentAgentId ,
349+ }
350+ logger . debug (
351+ debugPayload ,
352+ `run-programmatic-step: Adding parentAgentId to ${ chunk . type } event` ,
353+ )
354+ onResponseChunk ( {
355+ ...chunk ,
356+ parentAgentId,
357+ } )
358+ return
359+ }
360+ break
361+ }
362+ default :
363+ break
364+ }
365+ }
366+
367+ // For other events or top-level spawns, send as-is
368+ onResponseChunk ( chunk )
369+ } ,
302370 } )
303371
304372 // TODO: Remove messages from state and always use agentState.messageHistory.
0 commit comments