fix(opencode): keep concurrent task resumes foreground
This commit is contained in:
parent
553b42fcc7
commit
e3d6b7c93f
2 changed files with 72 additions and 6 deletions
|
|
@ -253,7 +253,9 @@ export const TaskTool = Tool.define(
|
|||
)
|
||||
})
|
||||
|
||||
if (yield* background.extend({ id: nextSession.id, run: runTask() })) {
|
||||
const extended = yield* background.extend({ id: nextSession.id, run: runTask() })
|
||||
if (extended && runInBackground) {
|
||||
yield* background.promote(nextSession.id)
|
||||
return {
|
||||
title: params.description,
|
||||
metadata: {
|
||||
|
|
@ -320,11 +322,11 @@ export const TaskTool = Tool.define(
|
|||
}),
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const result = yield* Effect.raceFirst(
|
||||
background.wait({ id: nextSession.id }).pipe(Effect.map((waited) => waited.info)),
|
||||
background.waitForPromotion(nextSession.id),
|
||||
)
|
||||
if (result?.metadata?.background === true) return backgroundResult()
|
||||
const wait = background.wait({ id: nextSession.id }).pipe(Effect.map((waited) => waited.info))
|
||||
const result = yield* (extended
|
||||
? wait
|
||||
: Effect.raceFirst(wait, background.waitForPromotion(nextSession.id)))
|
||||
if (!extended && result?.metadata?.background === true) return backgroundResult()
|
||||
if (result?.status === "error") return yield* Effect.fail(new Error(result.error ?? "Task failed"))
|
||||
if (result?.status === "cancelled") return yield* Effect.fail(new Error("Task cancelled"))
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -255,6 +255,69 @@ describe("tool.task", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.instance("concurrent foreground resumes remain foreground", () =>
|
||||
Effect.gen(function* () {
|
||||
const sessions = yield* Session.Service
|
||||
const { chat, assistant } = yield* seed()
|
||||
const child = yield* sessions.create({ parentID: chat.id, title: "Existing child" })
|
||||
const tool = yield* TaskTool
|
||||
const def = yield* tool.init()
|
||||
const firstStarted = yield* Deferred.make<void>()
|
||||
const firstDone = yield* Deferred.make<void>()
|
||||
const secondStarted = yield* Deferred.make<void>()
|
||||
const secondDone = yield* Deferred.make<void>()
|
||||
let prompts = 0
|
||||
const promptOps: TaskPromptOps = {
|
||||
...stubOps(),
|
||||
prompt: (input) => {
|
||||
prompts++
|
||||
if (prompts === 1)
|
||||
return Deferred.succeed(firstStarted, undefined).pipe(
|
||||
Effect.andThen(Deferred.await(firstDone)),
|
||||
Effect.as(reply(input, "first done")),
|
||||
)
|
||||
return Deferred.succeed(secondStarted, undefined).pipe(
|
||||
Effect.andThen(Deferred.await(secondDone)),
|
||||
Effect.as(reply(input, "second done")),
|
||||
)
|
||||
},
|
||||
}
|
||||
const context = {
|
||||
sessionID: chat.id,
|
||||
messageID: assistant.id,
|
||||
agent: "build",
|
||||
abort: new AbortController().signal,
|
||||
extra: { promptOps },
|
||||
messages: [],
|
||||
metadata: () => Effect.void,
|
||||
ask: () => Effect.void,
|
||||
}
|
||||
const execute = (prompt: string) =>
|
||||
def.execute(
|
||||
{
|
||||
description: prompt,
|
||||
prompt,
|
||||
subagent_type: "general",
|
||||
task_id: child.id,
|
||||
},
|
||||
context,
|
||||
)
|
||||
|
||||
const first = yield* execute("first follow-up").pipe(Effect.forkChild)
|
||||
yield* Deferred.await(firstStarted)
|
||||
const second = yield* execute("second follow-up").pipe(Effect.forkChild)
|
||||
|
||||
yield* Deferred.succeed(firstDone, undefined)
|
||||
yield* Deferred.await(secondStarted)
|
||||
yield* Deferred.succeed(secondDone, undefined)
|
||||
|
||||
const results = yield* Effect.all([Fiber.join(first), Fiber.join(second)])
|
||||
expect(prompts).toBe(2)
|
||||
expect(results.every((result) => result.metadata.background !== true)).toBe(true)
|
||||
expect(results.every((result) => result.output.includes('state="completed"'))).toBe(true)
|
||||
}),
|
||||
)
|
||||
|
||||
it.instance("execute asks by default and skips checks when bypassed", () =>
|
||||
Effect.gen(function* () {
|
||||
const { chat, assistant } = yield* seed()
|
||||
|
|
@ -721,6 +784,7 @@ describe("tool.task", () => {
|
|||
prompt: "also inspect cancellation",
|
||||
subagent_type: "general",
|
||||
task_id: started.metadata.sessionId,
|
||||
background: true,
|
||||
},
|
||||
context,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue