@@ -474,6 +474,73 @@ describe('SlackExecutionStreamController', () => {
474474 . join ( '' )
475475 }
476476
477+ it . each ( [ true , false ] ) (
478+ 'delivers identical Agent and Mship thinking updates with thinking enabled: %s' ,
479+ async ( includeThinking ) => {
480+ const agentEvents : AgentStreamEvent [ ] = [
481+ { type : 'thinking_delta' , text : 'Checking ' } ,
482+ { type : 'thinking_delta' , text : 'the source.' } ,
483+ { type : 'turn_end' , turn : 'intermediate' } ,
484+ { type : 'tool_call_start' , id : 'read' , name : 'read_file' } ,
485+ { type : 'tool_call_end' , id : 'read' , name : 'read_file' , status : 'success' } ,
486+ { type : 'thinking_delta' , text : 'Verifying the answer.' } ,
487+ { type : 'text_delta' , text : 'The complete answer.' , turn : 'pending' } ,
488+ { type : 'turn_end' , turn : 'final' } ,
489+ ]
490+ const mshipEvents : AgentStreamEvent [ ] = [ ]
491+ const projection = new ExecuteEventProjection ( ( event ) => mshipEvents . push ( event ) )
492+ for ( const text of [ 'Checking ' , 'the source.' ] ) {
493+ projection . accept ( { type : 'text' , payload : { channel : 'thinking' , text } } )
494+ }
495+ for ( const phase of [ 'call' , 'result' ] as const ) {
496+ projection . accept ( {
497+ type : 'tool' ,
498+ payload : {
499+ phase,
500+ toolCallId : 'read' ,
501+ toolName : 'read_file' ,
502+ executor : 'go' ,
503+ mode : 'sync' ,
504+ success : true ,
505+ } ,
506+ } )
507+ }
508+ projection . accept ( {
509+ type : 'text' ,
510+ payload : { channel : 'thinking' , text : 'Verifying the answer.' } ,
511+ } )
512+ projection . accept ( {
513+ type : 'text' ,
514+ payload : { channel : 'assistant' , text : 'The complete answer.' } ,
515+ } )
516+ projection . finish ( 'success' )
517+
518+ const config = { ...BASE_CONFIG , includeThinking }
519+ const agent = await deliver ( agentEvents , 'The complete answer.' , config )
520+ agent . controller . assertSucceeded ( )
521+ const agentChunks = mockAppendSlackAgentStream . mock . calls . flatMap ( ( call ) => call [ 3 ] )
522+ mockAppendSlackAgentStream . mockClear ( )
523+ const mship = await deliver ( mshipEvents , 'The complete answer.' , config )
524+ mship . controller . assertSucceeded ( )
525+ const mshipChunks = mockAppendSlackAgentStream . mock . calls . flatMap ( ( call ) => call [ 3 ] )
526+
527+ expect ( mshipChunks ) . toEqual ( agentChunks )
528+ expect ( sentText ( ) ) . toBe ( 'The complete answer.' )
529+ expect (
530+ mshipChunks
531+ . filter ( ( chunk ) => chunk . type === 'task_update' && chunk . title === 'Thinking' )
532+ . map ( ( chunk ) => ( { status : chunk . status , details : chunk . details } ) )
533+ ) . toEqual (
534+ includeThinking
535+ ? [
536+ { status : 'complete' , details : 'Checking the source.' } ,
537+ { status : 'complete' , details : 'Verifying the answer.' } ,
538+ ]
539+ : [ ]
540+ )
541+ }
542+ )
543+
477544 it . each ( [ true , false ] ) (
478545 'delivers Mship text and honors the same tool toggle as Agent: %s' ,
479546 async ( includeToolCalls ) => {
0 commit comments