From 24a7f333a2c3a60df8148296213fdc056ca8f33f Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 11 Dec 2025 17:29:20 +0900 Subject: [PATCH] refactor(background-agent): remove file persistence, use memory-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove background_tasks.json persistence (race condition with multiple instances) - Pure memory-based task management - Add logging for promptAsync errors - Remove unused persist/restore methods 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/features/background-agent/manager.ts | 97 +++--------------------- src/index.ts | 6 +- src/tools/background-task/tools.ts | 2 - 3 files changed, 10 insertions(+), 95 deletions(-) diff --git a/src/features/background-agent/manager.ts b/src/features/background-agent/manager.ts index 585157f..2415654 100644 --- a/src/features/background-agent/manager.ts +++ b/src/features/background-agent/manager.ts @@ -1,9 +1,9 @@ import type { PluginInput } from "@opencode-ai/plugin" import type { BackgroundTask, - BackgroundTaskStatus, LaunchInput, } from "./types" +import { log } from "../../shared/logger" type OpencodeClient = PluginInput["client"] @@ -34,15 +34,12 @@ export class BackgroundManager { private tasks: Map private notifications: Map private client: OpencodeClient - private storePath: string - private persistTimer?: Timer private pollingInterval?: Timer - constructor(client: OpencodeClient, storePath: string) { + constructor(client: OpencodeClient) { this.tasks = new Map() this.notifications = new Map() this.client = client - this.storePath = storePath } async launch(input: LaunchInput): Promise { @@ -75,7 +72,6 @@ export class BackgroundManager { } this.tasks.set(task.id, task) - this.persist() this.startPolling() this.client.session.promptAsync({ @@ -85,12 +81,12 @@ export class BackgroundManager { parts: [{ type: "text", text: input.prompt }], }, }).catch((error) => { + log("[background-agent] promptAsync error:", error) const existingTask = this.findBySession(sessionID) if (existingTask) { existingTask.status = "error" existingTask.error = String(error) existingTask.completedAt = new Date() - this.persist() } }) @@ -142,7 +138,6 @@ export class BackgroundManager { task.progress.toolCalls += 1 task.progress.lastTool = partInfo.tool task.progress.lastUpdate = new Date() - this.persist() } } @@ -159,7 +154,6 @@ export class BackgroundManager { task.status = "completed" task.completedAt = new Date() this.markForNotification(task) - this.persist() } } @@ -178,8 +172,6 @@ export class BackgroundManager { } this.tasks.delete(task.id) - this.persist() - this.clearNotificationsForTask(task.id) } } @@ -237,13 +229,17 @@ export class BackgroundManager { Use \`background_result\` tool with taskId="${task.id}" to retrieve the full result.` + log("[background-agent] Notifying parent session:", task.parentSessionID) + this.client.session.promptAsync({ path: { id: task.parentSessionID }, body: { parts: [{ type: "text", text: message }], }, - }).catch(() => { - void 0 + }).then(() => { + log("[background-agent] Parent session notified successfully") + }).catch((error) => { + log("[background-agent] Failed to notify parent session:", error) }) } @@ -283,7 +279,6 @@ Use \`background_result\` tool with taskId="${task.id}" to retrieve the full res task.status = "error" task.error = "Session not found" task.completedAt = new Date() - this.persist() } continue } @@ -294,7 +289,6 @@ Use \`background_result\` tool with taskId="${task.id}" to retrieve the full res task.status = "completed" task.completedAt = new Date() this.markForNotification(task) - this.persist() this.notifyParentSession(task) continue } @@ -341,77 +335,4 @@ Use \`background_result\` tool with taskId="${task.id}" to retrieve the full res this.stopPolling() } } - - persist(): void { - if (this.persistTimer) { - clearTimeout(this.persistTimer) - } - - this.persistTimer = setTimeout(() => { - const data = Array.from(this.tasks.values()) - const serialized = data.map((task) => ({ - ...task, - startedAt: task.startedAt.toISOString(), - completedAt: task.completedAt?.toISOString(), - progress: task.progress - ? { - ...task.progress, - lastUpdate: task.progress.lastUpdate.toISOString(), - } - : undefined, - })) - Bun.write(this.storePath, JSON.stringify(serialized, null, 2)).catch(() => { - void 0 - }) - }, 500) - } - - async restore(): Promise { - try { - const file = Bun.file(this.storePath) - const exists = await file.exists() - if (!exists) return - - const content = await file.text() - const data = JSON.parse(content) as Array<{ - id: string - sessionID: string - parentSessionID: string - parentMessageID: string - description: string - agent: string - status: BackgroundTaskStatus - startedAt: string - completedAt?: string - result?: string - error?: string - progress?: { - toolCalls: number - lastTool?: string - lastUpdate: string - } - }> - - for (const item of data) { - const task: BackgroundTask = { - ...item, - startedAt: new Date(item.startedAt), - completedAt: item.completedAt ? new Date(item.completedAt) : undefined, - progress: item.progress - ? { - ...item.progress, - lastUpdate: new Date(item.progress.lastUpdate), - } - : undefined, - } - this.tasks.set(task.id, task) - } - - if (this.hasRunningTasks()) { - this.startPolling() - } - } catch { - void 0 - } - } } diff --git a/src/index.ts b/src/index.ts index 7342d97..75a1ca2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -164,11 +164,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { updateTerminalTitle({ sessionId: "main" }); - const backgroundManager = new BackgroundManager( - ctx.client, - path.join(ctx.directory, ".opencode", "background-tasks.json") - ); - await backgroundManager.restore(); + const backgroundManager = new BackgroundManager(ctx.client); const backgroundNotificationHook = createBackgroundNotificationHook(backgroundManager); const backgroundTools = createBackgroundTools(backgroundManager, ctx.client); diff --git a/src/tools/background-task/tools.ts b/src/tools/background-task/tools.ts index 368a2e8..7731e97 100644 --- a/src/tools/background-task/tools.ts +++ b/src/tools/background-task/tools.ts @@ -207,8 +207,6 @@ Only running tasks can be cancelled.` task.status = "cancelled" task.completedAt = new Date() - manager.persist() - return `✅ Task cancelled successfully Task ID: ${task.id}