@@ -18,6 +18,7 @@ import { SessionStatus } from "@/session/status"
1818
1919import { Interrupt } from "../../src/session/interrupt"
2020import { TaskTool , renderOutput , Event as TaskEventDef , type TaskPromptOps , childResultBlock } from "../../src/tool/task"
21+ import { TaskReturnTool } from "../../src/tool/task-return"
2122import { Truncate } from "@/tool/truncate"
2223import { ToolRegistry } from "@/tool/registry"
2324import { RuntimeFlags } from "@/effect/runtime-flags"
@@ -276,6 +277,60 @@ describe("tool.task", () => {
276277 } ) ,
277278 )
278279
280+ it . instance ( "does not replay a prior task_return result when resuming a task session" , ( ) =>
281+ Effect . gen ( function * ( ) {
282+ const events = yield * EventV2Bridge . Service
283+ const sessions = yield * Session . Service
284+ const { chat, assistant } = yield * seed ( )
285+ const child = yield * sessions . create ( { parentID : chat . id , title : "Existing child" } )
286+ const taskReturn = yield * TaskReturnTool
287+ const taskReturnDef = yield * taskReturn . init ( )
288+ const staleResult = { verdict : "OLD" }
289+
290+ yield * taskReturnDef . execute ( { result : staleResult } , {
291+ sessionID : child . id ,
292+ messageID : MessageID . ascending ( ) ,
293+ agent : "general" ,
294+ abort : new AbortController ( ) . signal ,
295+ messages : [ ] ,
296+ metadata : ( ) => Effect . void ,
297+ ask : ( ) => Effect . void ,
298+ } )
299+
300+ const captured = yield * Deferred . make < any > ( )
301+ yield * events . listen ( ( event ) => {
302+ if ( event . type === TaskEventDef . Completed . type ) return Deferred . succeed ( captured , event )
303+ return Effect . void
304+ } )
305+
306+ const tool = yield * TaskTool
307+ const def = yield * tool . init ( )
308+ const result = yield * def . execute (
309+ {
310+ description : "continue investigation" ,
311+ prompt : "continue the investigation without returning a structured result" ,
312+ subagent_type : "general" ,
313+ task_id : child . id ,
314+ } ,
315+ {
316+ sessionID : chat . id ,
317+ messageID : assistant . id ,
318+ agent : "build" ,
319+ abort : new AbortController ( ) . signal ,
320+ extra : { promptOps : stubOps ( { text : "round two" } ) } ,
321+ messages : [ ] ,
322+ metadata : ( ) => Effect . void ,
323+ ask : ( ) => Effect . void ,
324+ } ,
325+ )
326+
327+ expect ( result . output ) . not . toContain ( JSON . stringify ( staleResult , null , 2 ) )
328+ expect ( result . output ) . not . toContain ( "<task_return>" )
329+ const event = yield * Deferred . await ( captured )
330+ expect ( event . data . result ) . toBeUndefined ( )
331+ } ) ,
332+ )
333+
279334 it . instance ( "execute asks by default and skips checks when bypassed" , ( ) =>
280335 Effect . gen ( function * ( ) {
281336 const { chat, assistant } = yield * seed ( )
0 commit comments