@@ -2117,6 +2117,68 @@ describe("subagent registry seam flow", () => {
21172117 expect ( mocks . runSubagentAnnounceFlow ) . not . toHaveBeenCalled ( ) ;
21182118 } ) ;
21192119
2120+ it ( "cancels a pending grace timer when agent.wait observes the yield after an aborted terminal (#92448)" , async ( ) => {
2121+ let resolveWait : ( value : {
2122+ status : "ok" ;
2123+ startedAt : number ;
2124+ endedAt : number ;
2125+ yielded : true ;
2126+ } ) => void = ( ) => { } ;
2127+ const waitResult = new Promise < {
2128+ status : "ok" ;
2129+ startedAt : number ;
2130+ endedAt : number ;
2131+ yielded : true ;
2132+ } > ( ( resolve ) => {
2133+ resolveWait = resolve ;
2134+ } ) ;
2135+ mocks . callGateway . mockImplementation ( async ( request : { method ?: string } ) => {
2136+ if ( request . method === "agent.wait" ) {
2137+ return waitResult ;
2138+ }
2139+ return { } ;
2140+ } ) ;
2141+
2142+ mod . registerSubagentRun ( {
2143+ runId : "run-wait-yield-after-pending-timeout" ,
2144+ childSessionKey : "agent:main:subagent:pending-wait-timeout" ,
2145+ requesterSessionKey : "agent:main:main" ,
2146+ requesterDisplayKey : "main" ,
2147+ task : "wait for child continuation through wait" ,
2148+ cleanup : "keep" ,
2149+ } ) ;
2150+
2151+ const lastOnAgentEventCall = mocks . onAgentEvent . mock . calls [
2152+ mocks . onAgentEvent . mock . calls . length - 1
2153+ ] as unknown as
2154+ | [ ( evt : { runId : string ; stream : string ; data : Record < string , unknown > } ) => void ]
2155+ | undefined ;
2156+ const lifecycleHandler = lastOnAgentEventCall ?. [ 0 ] ;
2157+ expect ( lifecycleHandler ) . toBeTypeOf ( "function" ) ;
2158+
2159+ lifecycleHandler ?.( {
2160+ runId : "run-wait-yield-after-pending-timeout" ,
2161+ stream : "lifecycle" ,
2162+ data : { phase : "end" , startedAt : 111 , endedAt : 222 , aborted : true } ,
2163+ } ) ;
2164+ resolveWait ( { status : "ok" , startedAt : 111 , endedAt : 333 , yielded : true } ) ;
2165+
2166+ await waitForFast ( ( ) => {
2167+ const run = mod
2168+ . listSubagentRunsForRequester ( "agent:main:main" )
2169+ . find ( ( entry ) => entry . runId === "run-wait-yield-after-pending-timeout" ) ;
2170+ expect ( run ?. pauseReason ) . toBe ( "sessions_yield" ) ;
2171+ } ) ;
2172+
2173+ await vi . advanceTimersByTimeAsync ( 60_000 ) ;
2174+ const run = mod
2175+ . listSubagentRunsForRequester ( "agent:main:main" )
2176+ . find ( ( entry ) => entry . runId === "run-wait-yield-after-pending-timeout" ) ;
2177+ expect ( run ?. pauseReason ) . toBe ( "sessions_yield" ) ;
2178+ expect ( run ?. outcome ?. status ) . not . toBe ( "timeout" ) ;
2179+ expect ( mocks . runSubagentAnnounceFlow ) . not . toHaveBeenCalled ( ) ;
2180+ } ) ;
2181+
21202182 it ( "announces blocked agent.wait snapshots as errors instead of success" , async ( ) => {
21212183 mocks . callGateway . mockImplementation ( async ( request : { method ?: string } ) => {
21222184 if ( request . method === "agent.wait" ) {
0 commit comments