refactor(background-agent): optimize lifecycle and simplify tools (#1411)
* refactor(background-agent): optimize cache timer lifecycle and result handling Ultraworked with Sisyphus Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * refactor(background-task): simplify tool implementation and expand test coverage Ultraworked with Sisyphus Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(background-task): fix BackgroundCancel tool parameter handling Correct parameter names and types in BackgroundCancel tool to match actual usage patterns. Add comprehensive test coverage for parameter validation. --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { createBackgroundOutput } from "./tools"
|
||||
import type { BackgroundTask } from "../../features/background-agent"
|
||||
import { createBackgroundCancel, createBackgroundOutput } from "./tools"
|
||||
import type { BackgroundManager, BackgroundTask } from "../../features/background-agent"
|
||||
import type { ToolContext } from "@opencode-ai/plugin/tool"
|
||||
import type { BackgroundOutputManager, BackgroundOutputClient } from "./tools"
|
||||
import type { BackgroundCancelClient, BackgroundOutputManager, BackgroundOutputClient } from "./tools"
|
||||
|
||||
const projectDir = "/Users/yeongyu/local-workspaces/oh-my-opencode"
|
||||
|
||||
@@ -253,6 +253,82 @@ describe("background_output full_session", () => {
|
||||
expect(output).not.toContain("y".repeat(2100))
|
||||
})
|
||||
})
|
||||
|
||||
describe("background_cancel", () => {
|
||||
test("cancels a running task via manager", async () => {
|
||||
// #given
|
||||
const task = createTask({ status: "running" })
|
||||
const cancelled: string[] = []
|
||||
const manager = {
|
||||
getTask: (id: string) => (id === task.id ? task : undefined),
|
||||
getAllDescendantTasks: () => [task],
|
||||
cancelTask: async (taskId: string) => {
|
||||
cancelled.push(taskId)
|
||||
task.status = "cancelled"
|
||||
return true
|
||||
},
|
||||
} as unknown as BackgroundManager
|
||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||
const tool = createBackgroundCancel(manager, client)
|
||||
|
||||
// #when
|
||||
const output = await tool.execute({ taskId: task.id }, mockContext)
|
||||
|
||||
// #then
|
||||
expect(cancelled).toEqual([task.id])
|
||||
expect(output).toContain("Task cancelled successfully")
|
||||
})
|
||||
|
||||
test("cancels all running or pending tasks", async () => {
|
||||
// #given
|
||||
const taskA = createTask({ id: "task-a", status: "running" })
|
||||
const taskB = createTask({ id: "task-b", status: "pending" })
|
||||
const cancelled: string[] = []
|
||||
const manager = {
|
||||
getTask: () => undefined,
|
||||
getAllDescendantTasks: () => [taskA, taskB],
|
||||
cancelTask: async (taskId: string) => {
|
||||
cancelled.push(taskId)
|
||||
const task = taskId === taskA.id ? taskA : taskB
|
||||
task.status = "cancelled"
|
||||
return true
|
||||
},
|
||||
} as unknown as BackgroundManager
|
||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||
const tool = createBackgroundCancel(manager, client)
|
||||
|
||||
// #when
|
||||
const output = await tool.execute({ all: true }, mockContext)
|
||||
|
||||
// #then
|
||||
expect(cancelled).toEqual([taskA.id, taskB.id])
|
||||
expect(output).toContain("Cancelled 2 background task(s)")
|
||||
})
|
||||
|
||||
test("preserves original status in cancellation table", async () => {
|
||||
// #given
|
||||
const taskA = createTask({ id: "task-a", status: "running", sessionID: "ses-a", description: "running task" })
|
||||
const taskB = createTask({ id: "task-b", status: "pending", sessionID: undefined, description: "pending task" })
|
||||
const manager = {
|
||||
getTask: () => undefined,
|
||||
getAllDescendantTasks: () => [taskA, taskB],
|
||||
cancelTask: async (taskId: string) => {
|
||||
const task = taskId === taskA.id ? taskA : taskB
|
||||
task.status = "cancelled"
|
||||
return true
|
||||
},
|
||||
} as unknown as BackgroundManager
|
||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||
const tool = createBackgroundCancel(manager, client)
|
||||
|
||||
// #when
|
||||
const output = await tool.execute({ all: true }, mockContext)
|
||||
|
||||
// #then
|
||||
expect(output).toContain("| `task-a` | running task | running | `ses-a` |")
|
||||
expect(output).toContain("| `task-b` | pending task | pending | (not started) |")
|
||||
})
|
||||
})
|
||||
type BackgroundOutputMessage = {
|
||||
id?: string
|
||||
info?: { role?: string; time?: string | { created?: number }; agent?: string }
|
||||
|
||||
Reference in New Issue
Block a user