@@ -132,12 +132,14 @@ async function executeSpawnAndExpectAccepted(params: {
132132 callId : string ;
133133 cleanup ?: "delete" | "keep" ;
134134 label ?: string ;
135+ expectsCompletionMessage ?: boolean ;
135136} ) {
136137 const result = await params . tool . execute ( params . callId , {
137138 task : "do thing" ,
138139 runTimeoutSeconds : RUN_TIMEOUT_SECONDS ,
139140 ...( params . cleanup ? { cleanup : params . cleanup } : { } ) ,
140141 ...( params . label ? { label : params . label } : { } ) ,
142+ ...( params . expectsCompletionMessage === false ? { expectsCompletionMessage : false } : { } ) ,
141143 } ) ;
142144 expect ( result . details ) . toMatchObject ( {
143145 status : "accepted" ,
@@ -390,6 +392,28 @@ describe("openclaw-tools: subagents (sessions_spawn lifecycle)", () => {
390392 } ) ;
391393
392394 it ( "sessions_spawn reports timed out when agent.wait returns timeout" , async ( ) => {
395+ let announcedStatus : string | undefined ;
396+ setSessionsSpawnAnnounceFlowOverride ( async ( params ) => {
397+ announcedStatus = params . outcome ?. status ;
398+ const requesterSessionKey = resolveRequesterStoreKey (
399+ loadConfig ( ) ,
400+ params . requesterSessionKey ,
401+ ) ;
402+
403+ await callGatewayMock ( {
404+ method : "agent" ,
405+ params : {
406+ sessionKey : requesterSessionKey ,
407+ message : `subagent task ${
408+ params . outcome ?. status === "timeout" ? "timed out" : "completed successfully"
409+ } `,
410+ deliver : false ,
411+ } ,
412+ } ) ;
413+
414+ return true ;
415+ } ) ;
416+
393417 const ctx = setupSessionsSpawnGatewayMock ( {
394418 includeChatHistory : true ,
395419 chatHistoryText : "still working" ,
@@ -401,20 +425,22 @@ describe("openclaw-tools: subagents (sessions_spawn lifecycle)", () => {
401425 tool,
402426 callId : "call-timeout" ,
403427 cleanup : "keep" ,
428+ expectsCompletionMessage : false ,
404429 } ) ;
405430
406- await waitFor ( ( ) => ctx . calls . filter ( ( call ) => call . method === "agent" ) . length >= 2 ) ;
431+ await waitFor ( ( ) => announcedStatus === "timeout" ) ;
407432
408- const mainAgentCall = ctx . calls
433+ const mainMessages = ctx . calls
409434 . filter ( ( call ) => call . method === "agent" )
410- . find ( ( call ) => {
435+ . filter ( ( call ) => {
411436 const params = call . params as { lane ?: string } | undefined ;
412437 return params ?. lane !== "subagent" ;
413- } ) ;
414- const mainMessage = ( mainAgentCall ? .params as { message ?: string } | undefined ) ?. message ?? "" ;
438+ } )
439+ . map ( ( call ) => ( call . params as { message ?: string } | undefined ) ?. message ?? "" ) ;
415440
416- expect ( mainMessage ) . toContain ( "timed out" ) ;
417- expect ( mainMessage ) . not . toContain ( "completed successfully" ) ;
441+ expect ( announcedStatus ) . toBe ( "timeout" ) ;
442+ expect ( mainMessages . some ( ( message ) => message . includes ( "timed out" ) ) ) . toBe ( true ) ;
443+ expect ( mainMessages . some ( ( message ) => message . includes ( "completed successfully" ) ) ) . toBe ( false ) ;
418444 } ) ;
419445
420446 it ( "sessions_spawn announces with requester accountId" , async ( ) => {
0 commit comments