@@ -29,7 +29,7 @@ import type { Provider } from "@/provider/provider"
2929import { Permission } from "@/permission"
3030import { Global } from "@/global"
3131import type { LanguageModelV2Usage } from "@ai-sdk/provider"
32- import { Effect , Layer , Context } from "effect"
32+ import { Effect , Layer , Option , Context } from "effect"
3333import { makeRuntime } from "@/effect/run-service"
3434
3535export namespace Session {
@@ -352,6 +352,11 @@ export namespace Session {
352352 field : string
353353 delta : string
354354 } ) => Effect . Effect < void >
355+ /** Finds the first message matching the predicate, searching newest-first. */
356+ readonly findMessage : (
357+ sessionID : SessionID ,
358+ predicate : ( msg : MessageV2 . WithParts ) => boolean ,
359+ ) => Effect . Effect < Option . Option < MessageV2 . WithParts > >
355360 }
356361
357362 export class Service extends Context . Service < Service , Interface > ( ) ( "@opencode/Session" ) { }
@@ -636,6 +641,17 @@ export namespace Session {
636641 yield * bus . publish ( MessageV2 . Event . PartDelta , input )
637642 } )
638643
644+ /** Finds the first message matching the predicate, searching newest-first. */
645+ const findMessage = Effect . fn ( "Session.findMessage" ) ( function * (
646+ sessionID : SessionID ,
647+ predicate : ( msg : MessageV2 . WithParts ) => boolean ,
648+ ) {
649+ for ( const item of MessageV2 . stream ( sessionID ) ) {
650+ if ( predicate ( item ) ) return Option . some ( item )
651+ }
652+ return Option . none < MessageV2 . WithParts > ( )
653+ } )
654+
639655 return Service . of ( {
640656 create,
641657 fork,
@@ -657,6 +673,7 @@ export namespace Session {
657673 updatePart,
658674 getPart,
659675 updatePartDelta,
676+ findMessage,
660677 } )
661678 } ) ,
662679 )
0 commit comments