@@ -17,6 +17,7 @@ import type { UserShellExecute } from "./session-update/UserShellExecuteView";
1717
1818export interface TurnContext {
1919 toolCalls : Map < string , ToolCall > ;
20+ childItems : Map < string , ConversationItem [ ] > ;
2021 turnCancelled : boolean ;
2122 turnComplete : boolean ;
2223}
@@ -154,8 +155,10 @@ function handlePromptRequest(
154155 const toolCalls = new Map < string , ToolCall > ( ) ;
155156 const gitAction = parseGitActionMessage ( userContent ) ;
156157
158+ const childItems = new Map < string , ConversationItem [ ] > ( ) ;
157159 const context : TurnContext = {
158160 toolCalls,
161+ childItems,
159162 turnCancelled : false ,
160163 turnComplete : false ,
161164 } ;
@@ -305,17 +308,93 @@ function extractUserContent(params: unknown): string {
305308 return visibleTextBlocks . map ( ( b ) => b . text ) . join ( "" ) ;
306309}
307310
311+ function getParentToolCallId ( update : SessionUpdate ) : string | undefined {
312+ const meta = ( update as Record < string , unknown > ) ?. _meta as
313+ | { claudeCode ?: { parentToolCallId ?: string } }
314+ | undefined ;
315+ return meta ?. claudeCode ?. parentToolCallId ;
316+ }
317+
318+ function pushChildItem ( b : ItemBuilder , parentId : string , update : RenderItem ) {
319+ const turn = b . currentTurn ;
320+ if ( ! turn ) return ;
321+ let children = turn . context . childItems . get ( parentId ) ;
322+ if ( ! children ) {
323+ children = [ ] ;
324+ turn . context . childItems . set ( parentId , children ) ;
325+ }
326+ turn . itemCount ++ ;
327+ children . push ( {
328+ type : "session_update" ,
329+ id : `${ turn . id } -child-${ b . nextId ( ) } ` ,
330+ update,
331+ turnContext : turn . context ,
332+ } ) ;
333+ }
334+
335+ function appendTextChunkToChildren (
336+ b : ItemBuilder ,
337+ parentId : string ,
338+ update : SessionUpdate & {
339+ sessionUpdate : "agent_message_chunk" | "agent_thought_chunk" ;
340+ } ,
341+ ) {
342+ if ( update . content . type !== "text" ) return ;
343+ const turn = b . currentTurn ;
344+ if ( ! turn ) return ;
345+ let children = turn . context . childItems . get ( parentId ) ;
346+ if ( ! children ) {
347+ children = [ ] ;
348+ turn . context . childItems . set ( parentId , children ) ;
349+ }
350+
351+ const lastChild = children [ children . length - 1 ] ;
352+ if (
353+ lastChild ?. type === "session_update" &&
354+ lastChild . update . sessionUpdate === update . sessionUpdate &&
355+ "content" in lastChild . update &&
356+ lastChild . update . content . type === "text"
357+ ) {
358+ const prevText = (
359+ lastChild . update . content as { type : "text" ; text : string }
360+ ) . text ;
361+ children [ children . length - 1 ] = {
362+ ...lastChild ,
363+ update : {
364+ ...lastChild . update ,
365+ content : {
366+ type : "text" ,
367+ text : prevText + update . content . text ,
368+ } ,
369+ } ,
370+ } ;
371+ } else {
372+ turn . itemCount ++ ;
373+ children . push ( {
374+ type : "session_update" ,
375+ id : `${ turn . id } -child-${ b . nextId ( ) } ` ,
376+ update : { ...update , content : { ...update . content } } ,
377+ turnContext : turn . context ,
378+ } ) ;
379+ }
380+ }
381+
308382function processSessionUpdate ( b : ItemBuilder , update : SessionUpdate ) {
309383 switch ( update . sessionUpdate ) {
310384 case "user_message_chunk" :
311385 break ;
312386
313387 case "agent_message_chunk" :
314- case "agent_thought_chunk" :
315- if ( update . content . type === "text" ) {
388+ case "agent_thought_chunk" : {
389+ if ( update . content . type !== "text" ) break ;
390+ const parentId = getParentToolCallId ( update ) ;
391+ if ( parentId ) {
392+ appendTextChunkToChildren ( b , parentId , update ) ;
393+ } else {
316394 appendTextChunk ( b , update ) ;
317395 }
318396 break ;
397+ }
319398
320399 case "tool_call" : {
321400 const turn = b . currentTurn ! ;
@@ -325,7 +404,12 @@ function processSessionUpdate(b: ItemBuilder, update: SessionUpdate) {
325404 } else {
326405 const toolCall = { ...update } ;
327406 turn . toolCalls . set ( update . toolCallId , toolCall ) ;
328- pushItem ( b , toolCall ) ;
407+ const parentId = getParentToolCallId ( update ) ;
408+ if ( parentId ) {
409+ pushChildItem ( b , parentId , toolCall ) ;
410+ } else {
411+ pushItem ( b , toolCall ) ;
412+ }
329413 }
330414 break ;
331415 }
0 commit comments