@@ -2217,6 +2217,90 @@ describe("Task persistence", () => {
22172217 } )
22182218
22192219 describe ( "resumeTaskFromHistory" , ( ) => {
2220+ const userMessageBlock = { type : "text" , text : "<user_message>\nAlso fix the tests\n</user_message>" }
2221+ const imageBlock = { type : "image" , source : { type : "base64" , media_type : "image/png" , data : "AAA" } }
2222+
2223+ it . each ( [
2224+ {
2225+ name : "text and image via Continue" ,
2226+ response : "yesButtonClicked" as const ,
2227+ text : "Also fix the tests" ,
2228+ images : [ "data:image/png;base64,AAA" ] ,
2229+ expected : [ userMessageBlock , imageBlock ] ,
2230+ } ,
2231+ {
2232+ name : "text only via Continue" ,
2233+ response : "yesButtonClicked" as const ,
2234+ text : "Also fix the tests" ,
2235+ images : [ ] ,
2236+ expected : [ userMessageBlock ] ,
2237+ } ,
2238+ {
2239+ name : "image only via Continue" ,
2240+ response : "yesButtonClicked" as const ,
2241+ text : "" ,
2242+ images : [ "data:image/png;base64,AAA" ] ,
2243+ expected : [ imageBlock ] ,
2244+ } ,
2245+ {
2246+ name : "text and image via Send" ,
2247+ response : "messageResponse" as const ,
2248+ text : "Also fix the tests" ,
2249+ images : [ "data:image/png;base64,AAA" ] ,
2250+ expected : [ userMessageBlock , imageBlock ] ,
2251+ } ,
2252+ ] ) ( "forwards chat box input ($name) to the resumed task" , async ( { response, text, images, expected } ) => {
2253+ mockReadApiMessages . mockResolvedValue ( [ { role : "assistant" , content : [ { type : "text" , text : "Working" } ] } ] )
2254+ const task = new Task ( {
2255+ provider : mockProvider ,
2256+ apiConfiguration : mockApiConfig ,
2257+ historyItem : {
2258+ id : "resume-with-input" ,
2259+ number : 1 ,
2260+ ts : Date . now ( ) ,
2261+ task : "Original task" ,
2262+ tokensIn : 10 ,
2263+ tokensOut : 5 ,
2264+ totalCost : 0.001 ,
2265+ } ,
2266+ startTask : false ,
2267+ } )
2268+ vi . spyOn ( task , "ask" ) . mockResolvedValue ( { response, text, images } )
2269+ const say = vi . spyOn ( task , "say" ) . mockResolvedValue ( undefined )
2270+ const initiate = vi . spyOn ( getTaskPersistenceAccess ( task ) , "initiateTaskLoop" ) . mockResolvedValue ( undefined )
2271+
2272+ await getTaskPersistenceAccess ( task ) . resumeTaskFromHistory ( )
2273+
2274+ expect ( say ) . toHaveBeenCalledWith ( "user_feedback" , text , images )
2275+ expect ( initiate ) . toHaveBeenCalledWith ( expected )
2276+ } )
2277+
2278+ it ( "resumes without user feedback when Continue is clicked with an empty chat box" , async ( ) => {
2279+ mockReadApiMessages . mockResolvedValue ( [ { role : "assistant" , content : [ { type : "text" , text : "Working" } ] } ] )
2280+ const task = new Task ( {
2281+ provider : mockProvider ,
2282+ apiConfiguration : mockApiConfig ,
2283+ historyItem : {
2284+ id : "resume-without-input" ,
2285+ number : 1 ,
2286+ ts : Date . now ( ) ,
2287+ task : "Original task" ,
2288+ tokensIn : 10 ,
2289+ tokensOut : 5 ,
2290+ totalCost : 0.001 ,
2291+ } ,
2292+ startTask : false ,
2293+ } )
2294+ vi . spyOn ( task , "ask" ) . mockResolvedValue ( { response : "yesButtonClicked" } )
2295+ const say = vi . spyOn ( task , "say" ) . mockResolvedValue ( undefined )
2296+ const initiate = vi . spyOn ( getTaskPersistenceAccess ( task ) , "initiateTaskLoop" ) . mockResolvedValue ( undefined )
2297+
2298+ await getTaskPersistenceAccess ( task ) . resumeTaskFromHistory ( )
2299+
2300+ expect ( say . mock . calls . filter ( ( [ type ] ) => type === "user_feedback" ) ) . toEqual ( [ ] )
2301+ expect ( initiate ) . toHaveBeenCalledWith ( [ { type : "text" , text : "[TASK RESUMPTION] Resuming task..." } ] )
2302+ } )
2303+
22202304 it . each ( [ "not_found" , "invalid" , "io_error" ] as const ) (
22212305 "does not persist when hydration fails with %s" ,
22222306 async ( kind ) => {
0 commit comments