@@ -2202,7 +2202,7 @@ it.layer(McpProviderSessions.layer)("OpenCode2 adapter", (it) => {
22022202 . interruptTurn ( { providerThread : thread , providerTurnId : yield * providerTurnId } )
22032203 . pipe ( Effect . forkScoped ) ;
22042204 yield * TestClock . adjust ( "11 seconds" ) ;
2205- yield * Fiber . join ( interrupt ) ;
2205+ yield * Fiber . join ( interrupt ) . pipe ( Effect . flip ) ;
22062206 } ) ;
22072207 const terminals = ( runtime : ProviderAdapter . ProviderAdapterV2SessionRuntime , count : number ) =>
22082208 runtime . events . pipe (
@@ -2237,21 +2237,37 @@ it.layer(McpProviderSessions.layer)("OpenCode2 adapter", (it) => {
22372237
22382238 it . effect ( "never lets a timed-out Stop's late end finish the next turn" , ( ) =>
22392239 Effect . gen ( function * ( ) {
2240- const { runtime, thread } = yield * resumed ( [
2241- ...stopTimedOut ,
2242- out ( "session.active" ) ,
2243- reply ( "session.active" , { data : { } } ) ,
2244- out ( "session.prompt" , { sessionID : SESSION , text : "<any>" } ) ,
2245- promptAccepted ,
2246- event ( "session.execution.succeeded" , { sessionID : SESSION } ) ,
2247- event ( "session.execution.started" , { sessionID : SESSION } ) ,
2248- event ( "session.execution.failed" , {
2249- sessionID : SESSION ,
2250- error : { type : "provider" , message : "second turn failed" } ,
2251- } ) ,
2252- ] ) ;
2253- const ended = yield * terminals ( runtime , 2 ) ;
2240+ const gate = makeProviderReplayGate ( [ "late-end" ] ) ;
2241+ const { runtime, thread } = yield * resumed (
2242+ [
2243+ ...stopTimedOut ,
2244+ event ( "session.execution.succeeded" , { sessionID : SESSION } , "late-end" ) ,
2245+ out ( "session.prompt" , { sessionID : SESSION , text : "<any>" } ) ,
2246+ promptAccepted ,
2247+ event ( "session.execution.started" , { sessionID : SESSION } ) ,
2248+ event ( "session.execution.failed" , {
2249+ sessionID : SESSION ,
2250+ error : { type : "provider" , message : "second turn failed" } ,
2251+ } ) ,
2252+ ] ,
2253+ { replayGate : gate } ,
2254+ ) ;
2255+ const lateEnd = yield * Deferred . make < void > ( ) ;
2256+ const ended = yield * runtime . events . pipe (
2257+ Stream . filter (
2258+ (
2259+ event ,
2260+ ) : event is Extract < ProviderAdapter . ProviderAdapterV2Event , { type : "turn.terminal" } > =>
2261+ event . type === "turn.terminal" ,
2262+ ) ,
2263+ Stream . tap ( ( ) => Deferred . succeed ( lateEnd , undefined ) ) ,
2264+ Stream . take ( 2 ) ,
2265+ Stream . runCollect ,
2266+ Effect . forkScoped ,
2267+ ) ;
22542268 yield * stopFirstTurn ( runtime , thread ) ;
2269+ gate . release ( "late-end" ) ;
2270+ yield * Deferred . await ( lateEnd ) ;
22552271 yield * runtime . startTurn ( secondTurn ( thread ) ) ;
22562272 const [ first , second ] = yield * Fiber . join ( ended ) ;
22572273 assert . equal ( first ?. status , "interrupted" ) ;
@@ -2323,15 +2339,15 @@ it.layer(McpProviderSessions.layer)("OpenCode2 adapter", (it) => {
23232339 ...backgroundLaunch ( CHILD ) ,
23242340 out ( "session.interrupt" , { sessionID : SESSION } ) ,
23252341 reply ( "session.interrupt" , "<hang>" ) ,
2326- out ( "session.active" ) ,
2327- replyData ( "session.active" , { [ SESSION ] : { type : "running" } } ) ,
23282342 out ( "session.interrupt" , { sessionID : SESSION } ) ,
23292343 reply ( "session.interrupt" , { interrupted : true } ) ,
23302344 event ( "session.usage.updated" , { sessionID : SESSION } , "drop" ) ,
23312345 { type : "runtime_exit" , status : "success" } as const ,
23322346 out ( "event.subscribe" ) ,
23332347 out ( "session.active" ) ,
23342348 replyData ( "session.active" , { [ CHILD ] : { type : "running" } } ) ,
2349+ out ( "message.list" , "<any>" ) ,
2350+ reply ( "message.list" , { data : [ ] , cursor : { } } ) ,
23352351 out ( "permission.list" , { sessionID : CHILD } ) ,
23362352 replyData ( "permission.list" , [ ] ) ,
23372353 out ( "session.form.list" , { sessionID : CHILD } ) ,
@@ -2393,23 +2409,22 @@ it.layer(McpProviderSessions.layer)("OpenCode2 adapter", (it) => {
23932409 ) ;
23942410 yield * runtime . startTurn ( withLineage ( thread ) ) ;
23952411 yield * Deferred . await ( attached ) ;
2396- const interrupt = yield * runtime
2397- . interruptTurn ( { providerThread : thread , providerTurnId : yield * providerTurnId } )
2398- . pipe ( Effect . forkScoped ) ;
2412+ const stop = { providerThread : thread , providerTurnId : yield * providerTurnId } ;
2413+ const interrupt = yield * runtime . interruptTurn ( stop ) . pipe ( Effect . flip , Effect . forkScoped ) ;
23992414 yield * TestClock . adjust ( "11 seconds" ) ;
24002415 yield * Fiber . join ( interrupt ) ;
2401- yield * runtime . startTurn ( { ... secondTurn ( thread ) , appThread : withLineage ( thread ) . appThread } ) ;
2416+ yield * runtime . interruptTurn ( stop ) ;
24022417 gate . release ( "drop" ) ;
24032418 yield * runtime . startTurn ( {
24042419 ...continuationTurn ( thread , yield * Deferred . await ( offered ) ) ,
2405- runOrdinal : 3 ,
2406- providerTurnOrdinal : 3 ,
2420+ runOrdinal : 2 ,
2421+ providerTurnOrdinal : 2 ,
24072422 } ) ;
24082423 gate . release ( "reply" ) ;
24092424 const events = [ ...( yield * Fiber . join ( collected ) ) ] ;
24102425 assert . deepEqual (
24112426 events . flatMap ( ( event ) => ( event . type === "turn.terminal" ? [ event . status ] : [ ] ) ) ,
2412- [ "interrupted" , "failed" , " completed"] ,
2427+ [ "interrupted" , "completed" ] ,
24132428 ) ;
24142429 assert . include (
24152430 events . flatMap ( ( event ) =>
0 commit comments