@@ -6,10 +6,10 @@ import * as CrossSpawnSpawner from "../../src/effect/cross-spawn-spawner"
66import { Instance } from "../../src/project/instance"
77import { Session } from "../../src/session"
88import { MessageV2 } from "../../src/session/message-v2"
9- import { SessionPrompt } from "../../src/session/prompt"
9+ import type { SessionPrompt } from "../../src/session/prompt"
1010import { MessageID , PartID } from "../../src/session/schema"
1111import { ModelID , ProviderID } from "../../src/provider/schema"
12- import { TaskTool } from "../../src/tool/task"
12+ import { TaskTool , type TaskPromptOps } from "../../src/tool/task"
1313import { ToolRegistry } from "../../src/tool/registry"
1414import { provideTmpdirInstance } from "../fixture/fixture"
1515import { testEffect } from "../lib/effect"
@@ -62,6 +62,17 @@ const seed = Effect.fn("TaskToolTest.seed")(function* (title = "Pinned") {
6262 return { chat, assistant }
6363} )
6464
65+ function stubOps ( opts ?: { onPrompt ?: ( input : SessionPrompt . PromptInput ) => void ; text ?: string } ) : TaskPromptOps {
66+ return {
67+ cancel ( ) { } ,
68+ resolvePromptParts : async ( template ) => [ { type : "text" , text : template } ] ,
69+ prompt : async ( input ) => {
70+ opts ?. onPrompt ?.( input )
71+ return reply ( input , opts ?. text ?? "done" )
72+ } ,
73+ }
74+ }
75+
6576function reply ( input : Parameters < typeof SessionPrompt . prompt > [ 0 ] , text : string ) : MessageV2 . WithParts {
6677 const id = MessageID . ascending ( )
6778 return {
@@ -180,21 +191,8 @@ describe("tool.task", () => {
180191 const child = yield * sessions . create ( { parentID : chat . id , title : "Existing child" } )
181192 const tool = yield * TaskTool
182193 const def = yield * Effect . promise ( ( ) => tool . init ( ) )
183- const resolve = SessionPrompt . resolvePromptParts
184- const prompt = SessionPrompt . prompt
185- let seen : Parameters < typeof SessionPrompt . prompt > [ 0 ] | undefined
186-
187- SessionPrompt . resolvePromptParts = async ( template ) => [ { type : "text" , text : template } ]
188- SessionPrompt . prompt = async ( input ) => {
189- seen = input
190- return reply ( input , "resumed" )
191- }
192- yield * Effect . addFinalizer ( ( ) =>
193- Effect . sync ( ( ) => {
194- SessionPrompt . resolvePromptParts = resolve
195- SessionPrompt . prompt = prompt
196- } ) ,
197- )
194+ let seen : SessionPrompt . PromptInput | undefined
195+ const promptOps = stubOps ( { text : "resumed" , onPrompt : ( input ) => ( seen = input ) } )
198196
199197 const result = yield * Effect . promise ( ( ) =>
200198 def . execute (
@@ -209,6 +207,7 @@ describe("tool.task", () => {
209207 messageID : assistant . id ,
210208 agent : "build" ,
211209 abort : new AbortController ( ) . signal ,
210+ extra : { promptOps } ,
212211 messages : [ ] ,
213212 metadata ( ) { } ,
214213 ask : async ( ) => { } ,
@@ -232,20 +231,10 @@ describe("tool.task", () => {
232231 const { chat, assistant } = yield * seed ( )
233232 const tool = yield * TaskTool
234233 const def = yield * Effect . promise ( ( ) => tool . init ( ) )
235- const resolve = SessionPrompt . resolvePromptParts
236- const prompt = SessionPrompt . prompt
237234 const calls : unknown [ ] = [ ]
235+ const promptOps = stubOps ( )
238236
239- SessionPrompt . resolvePromptParts = async ( template ) => [ { type : "text" , text : template } ]
240- SessionPrompt . prompt = async ( input ) => reply ( input , "done" )
241- yield * Effect . addFinalizer ( ( ) =>
242- Effect . sync ( ( ) => {
243- SessionPrompt . resolvePromptParts = resolve
244- SessionPrompt . prompt = prompt
245- } ) ,
246- )
247-
248- const exec = ( extra ?: { bypassAgentCheck ?: boolean } ) =>
237+ const exec = ( extra ?: Record < string , any > ) =>
249238 Effect . promise ( ( ) =>
250239 def . execute (
251240 {
@@ -258,7 +247,7 @@ describe("tool.task", () => {
258247 messageID : assistant . id ,
259248 agent : "build" ,
260249 abort : new AbortController ( ) . signal ,
261- extra,
250+ extra : { promptOps , ... extra } ,
262251 messages : [ ] ,
263252 metadata ( ) { } ,
264253 ask : async ( input ) => {
@@ -292,21 +281,8 @@ describe("tool.task", () => {
292281 const { chat, assistant } = yield * seed ( )
293282 const tool = yield * TaskTool
294283 const def = yield * Effect . promise ( ( ) => tool . init ( ) )
295- const resolve = SessionPrompt . resolvePromptParts
296- const prompt = SessionPrompt . prompt
297- let seen : Parameters < typeof SessionPrompt . prompt > [ 0 ] | undefined
298-
299- SessionPrompt . resolvePromptParts = async ( template ) => [ { type : "text" , text : template } ]
300- SessionPrompt . prompt = async ( input ) => {
301- seen = input
302- return reply ( input , "created" )
303- }
304- yield * Effect . addFinalizer ( ( ) =>
305- Effect . sync ( ( ) => {
306- SessionPrompt . resolvePromptParts = resolve
307- SessionPrompt . prompt = prompt
308- } ) ,
309- )
284+ let seen : SessionPrompt . PromptInput | undefined
285+ const promptOps = stubOps ( { text : "created" , onPrompt : ( input ) => ( seen = input ) } )
310286
311287 const result = yield * Effect . promise ( ( ) =>
312288 def . execute (
@@ -321,6 +297,7 @@ describe("tool.task", () => {
321297 messageID : assistant . id ,
322298 agent : "build" ,
323299 abort : new AbortController ( ) . signal ,
300+ extra : { promptOps } ,
324301 messages : [ ] ,
325302 metadata ( ) { } ,
326303 ask : async ( ) => { } ,
@@ -346,21 +323,8 @@ describe("tool.task", () => {
346323 const { chat, assistant } = yield * seed ( )
347324 const tool = yield * TaskTool
348325 const def = yield * Effect . promise ( ( ) => tool . init ( ) )
349- const resolve = SessionPrompt . resolvePromptParts
350- const prompt = SessionPrompt . prompt
351- let seen : Parameters < typeof SessionPrompt . prompt > [ 0 ] | undefined
352-
353- SessionPrompt . resolvePromptParts = async ( template ) => [ { type : "text" , text : template } ]
354- SessionPrompt . prompt = async ( input ) => {
355- seen = input
356- return reply ( input , "done" )
357- }
358- yield * Effect . addFinalizer ( ( ) =>
359- Effect . sync ( ( ) => {
360- SessionPrompt . resolvePromptParts = resolve
361- SessionPrompt . prompt = prompt
362- } ) ,
363- )
326+ let seen : SessionPrompt . PromptInput | undefined
327+ const promptOps = stubOps ( { onPrompt : ( input ) => ( seen = input ) } )
364328
365329 const result = yield * Effect . promise ( ( ) =>
366330 def . execute (
@@ -374,6 +338,7 @@ describe("tool.task", () => {
374338 messageID : assistant . id ,
375339 agent : "build" ,
376340 abort : new AbortController ( ) . signal ,
341+ extra : { promptOps } ,
377342 messages : [ ] ,
378343 metadata ( ) { } ,
379344 ask : async ( ) => { } ,
0 commit comments