@@ -20,7 +20,6 @@ import PROMPT_PLAN from "../session/prompt/plan.txt"
2020import BUILD_SWITCH from "../session/prompt/build-switch.txt"
2121import MAX_STEPS from "../session/prompt/max-steps.txt"
2222import { ToolRegistry } from "../tool/registry"
23- import { Runner } from "@/effect/runner"
2423import { MCP } from "../mcp"
2524import { LSP } from "../lsp"
2625import { FileTime } from "../file/time"
@@ -48,6 +47,7 @@ import { Cause, Effect, Exit, Layer, Option, Scope, ServiceMap } from "effect"
4847import { InstanceState } from "@/effect/instance-state"
4948import { makeRuntime } from "@/effect/run-service"
5049import { TaskTool } from "@/tool/task"
50+ import { SessionRunState } from "./run-state"
5151
5252// @ts -ignore
5353globalThis . AI_SDK_LOG_WARNINGS = false
@@ -66,7 +66,6 @@ export namespace SessionPrompt {
6666 const log = Log . create ( { service : "session.prompt" } )
6767
6868 export interface Interface {
69- readonly assertNotBusy : ( sessionID : SessionID ) => Effect . Effect < void , Session . BusyError >
7069 readonly cancel : ( sessionID : SessionID ) => Effect . Effect < void >
7170 readonly prompt : ( input : PromptInput ) => Effect . Effect < MessageV2 . WithParts >
7271 readonly loop : ( input : z . infer < typeof LoopInput > ) => Effect . Effect < MessageV2 . WithParts >
@@ -99,55 +98,11 @@ export namespace SessionPrompt {
9998 const spawner = yield * ChildProcessSpawner . ChildProcessSpawner
10099 const scope = yield * Scope . Scope
101100 const instruction = yield * Instruction . Service
102-
103- const state = yield * InstanceState . make (
104- Effect . fn ( "SessionPrompt.state" ) ( function * ( ) {
105- const runners = new Map < string , Runner < MessageV2 . WithParts > > ( )
106- yield * Effect . addFinalizer (
107- Effect . fnUntraced ( function * ( ) {
108- yield * Effect . forEach ( runners . values ( ) , ( r ) => r . cancel , { concurrency : "unbounded" , discard : true } )
109- runners . clear ( )
110- } ) ,
111- )
112- return { runners }
113- } ) ,
114- )
115-
116- const getRunner = ( runners : Map < string , Runner < MessageV2 . WithParts > > , sessionID : SessionID ) => {
117- const existing = runners . get ( sessionID )
118- if ( existing ) return existing
119- const runner = Runner . make < MessageV2 . WithParts > ( scope , {
120- onIdle : Effect . gen ( function * ( ) {
121- runners . delete ( sessionID )
122- yield * status . set ( sessionID , { type : "idle" } )
123- } ) ,
124- onBusy : status . set ( sessionID , { type : "busy" } ) ,
125- onInterrupt : lastAssistant ( sessionID ) ,
126- busy : ( ) => {
127- throw new Session . BusyError ( sessionID )
128- } ,
129- } )
130- runners . set ( sessionID , runner )
131- return runner
132- }
133-
134- const assertNotBusy : ( sessionID : SessionID ) => Effect . Effect < void , Session . BusyError > = Effect . fn (
135- "SessionPrompt.assertNotBusy" ,
136- ) ( function * ( sessionID : SessionID ) {
137- const s = yield * InstanceState . get ( state )
138- const runner = s . runners . get ( sessionID )
139- if ( runner ?. busy ) throw new Session . BusyError ( sessionID )
140- } )
101+ const state = yield * SessionRunState . Service
141102
142103 const cancel = Effect . fn ( "SessionPrompt.cancel" ) ( function * ( sessionID : SessionID ) {
143104 log . info ( "cancel" , { sessionID } )
144- const s = yield * InstanceState . get ( state )
145- const runner = s . runners . get ( sessionID )
146- if ( ! runner || ! runner . busy ) {
147- yield * status . set ( sessionID , { type : "idle" } )
148- return
149- }
150- yield * runner . cancel
105+ yield * state . cancel ( sessionID )
151106 } )
152107
153108 const resolvePromptParts = Effect . fn ( "SessionPrompt.resolvePromptParts" ) ( function * ( template : string ) {
@@ -1574,16 +1529,12 @@ NOTE: At any point in time through this workflow you should feel free to ask the
15741529 const loop : ( input : z . infer < typeof LoopInput > ) => Effect . Effect < MessageV2 . WithParts > = Effect . fn (
15751530 "SessionPrompt.loop" ,
15761531 ) ( function * ( input : z . infer < typeof LoopInput > ) {
1577- const s = yield * InstanceState . get ( state )
1578- const runner = getRunner ( s . runners , input . sessionID )
1579- return yield * runner . ensureRunning ( runLoop ( input . sessionID ) )
1532+ return yield * state . ensureRunning ( input . sessionID , lastAssistant ( input . sessionID ) , runLoop ( input . sessionID ) )
15801533 } )
15811534
15821535 const shell : ( input : ShellInput ) => Effect . Effect < MessageV2 . WithParts > = Effect . fn ( "SessionPrompt.shell" ) (
15831536 function * ( input : ShellInput ) {
1584- const s = yield * InstanceState . get ( state )
1585- const runner = getRunner ( s . runners , input . sessionID )
1586- return yield * runner . startShell ( shellImpl ( input ) )
1537+ return yield * state . startShell ( input . sessionID , lastAssistant ( input . sessionID ) , shellImpl ( input ) )
15871538 } ,
15881539 )
15891540
@@ -1704,7 +1655,6 @@ NOTE: At any point in time through this workflow you should feel free to ask the
17041655 } )
17051656
17061657 return Service . of ( {
1707- assertNotBusy,
17081658 cancel,
17091659 prompt,
17101660 loop,
@@ -1718,6 +1668,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
17181668 const defaultLayer = Layer . unwrap (
17191669 Effect . sync ( ( ) =>
17201670 layer . pipe (
1671+ Layer . provide ( SessionRunState . layer ) ,
17211672 Layer . provide ( SessionStatus . layer ) ,
17221673 Layer . provide ( SessionCompaction . defaultLayer ) ,
17231674 Layer . provide ( SessionProcessor . defaultLayer ) ,
@@ -1741,10 +1692,6 @@ NOTE: At any point in time through this workflow you should feel free to ask the
17411692 )
17421693 const { runPromise } = makeRuntime ( Service , defaultLayer )
17431694
1744- export async function assertNotBusy ( sessionID : SessionID ) {
1745- return runPromise ( ( svc ) => svc . assertNotBusy ( SessionID . zod . parse ( sessionID ) ) )
1746- }
1747-
17481695 export const PromptInput = z . object ( {
17491696 sessionID : SessionID . zod ,
17501697 messageID : MessageID . zod . optional ( ) ,
0 commit comments