fix(stop-continuation): wire backgroundManager to cancel running tasks on stop

Closes #2017
This commit is contained in:
YeonGyu-Kim
2026-02-26 20:59:35 +09:00
parent c505989ad4
commit ccb789e5df
3 changed files with 106 additions and 2 deletions
+42 -1
View File
@@ -1,4 +1,5 @@
import type { PluginInput } from "@opencode-ai/plugin"
import type { BackgroundManager } from "../../features/background-agent"
import {
clearContinuationMarker,
@@ -8,6 +9,11 @@ import { log } from "../../shared/logger"
const HOOK_NAME = "stop-continuation-guard"
type StopContinuationBackgroundManager = Pick<
BackgroundManager,
"getAllDescendantTasks" | "cancelTask"
>
export interface StopContinuationGuard {
event: (input: { event: { type: string; properties?: unknown } }) => Promise<void>
"chat.message": (input: { sessionID?: string }) => Promise<void>
@@ -17,7 +23,10 @@ export interface StopContinuationGuard {
}
export function createStopContinuationGuardHook(
ctx: PluginInput
ctx: PluginInput,
options?: {
backgroundManager?: StopContinuationBackgroundManager
}
): StopContinuationGuard {
const stoppedSessions = new Set<string>()
@@ -25,6 +34,38 @@ export function createStopContinuationGuardHook(
stoppedSessions.add(sessionID)
setContinuationMarkerSource(ctx.directory, sessionID, "stop", "stopped", "continuation stopped")
log(`[${HOOK_NAME}] Continuation stopped for session`, { sessionID })
const backgroundManager = options?.backgroundManager
if (!backgroundManager) {
return
}
const cancellableTasks = backgroundManager
.getAllDescendantTasks(sessionID)
.filter((task) => task.status === "running" || task.status === "pending")
if (cancellableTasks.length === 0) {
return
}
void Promise.allSettled(
cancellableTasks.map(async (task) => {
await backgroundManager.cancelTask(task.id, {
source: "stop-continuation",
reason: "Continuation stopped via /stop-continuation",
abortSession: task.status === "running",
skipNotification: true,
})
})
).then((results) => {
const cancelledCount = results.filter((result) => result.status === "fulfilled").length
const failedCount = results.length - cancelledCount
log(`[${HOOK_NAME}] Cancelled background tasks for stopped session`, {
sessionID,
cancelledCount,
failedCount,
})
})
}
const isStopped = (sessionID: string): boolean => {