Merge pull request #1536 from code-yeongyu/feat/task-continuation-enforcer

feat(hooks): implement task-continuation-enforcer
This commit is contained in:
YeonGyu-Kim
2026-02-08 16:43:42 +09:00
committed by GitHub
6 changed files with 1319 additions and 6 deletions
+23 -6
View File
@@ -2,6 +2,7 @@ import type { Plugin, ToolDefinition } from "@opencode-ai/plugin";
import type { AvailableSkill } from "./agents/dynamic-agent-prompt-builder";
import {
createTodoContinuationEnforcer,
createTaskContinuationEnforcer,
createContextWindowMonitorHook,
createSessionRecoveryHook,
createSessionNotification,
@@ -403,12 +404,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
), { enabled: safeHookEnabled })
: null;
if (sessionRecovery && todoContinuationEnforcer) {
sessionRecovery.setOnAbortCallback(todoContinuationEnforcer.markRecovering);
sessionRecovery.setOnRecoveryCompleteCallback(
todoContinuationEnforcer.markRecoveryComplete,
);
}
// sessionRecovery callbacks are setters; compose callbacks so both enforcers are notified.
const backgroundNotificationHook = isHookEnabled("background-notification")
? safeCreateHook("background-notification", () => createBackgroundNotificationHook(backgroundManager), { enabled: safeHookEnabled })
@@ -544,6 +540,25 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
});
const taskSystemEnabled = pluginConfig.experimental?.task_system ?? false;
const taskContinuationEnforcer = isHookEnabled("task-continuation-enforcer") && taskSystemEnabled
? createTaskContinuationEnforcer(ctx, pluginConfig, {
backgroundManager,
isContinuationStopped: stopContinuationGuard?.isStopped,
})
: null;
if (sessionRecovery && (todoContinuationEnforcer || taskContinuationEnforcer)) {
sessionRecovery.setOnAbortCallback((sessionID) => {
todoContinuationEnforcer?.markRecovering(sessionID);
taskContinuationEnforcer?.markRecovering(sessionID);
});
sessionRecovery.setOnRecoveryCompleteCallback((sessionID) => {
todoContinuationEnforcer?.markRecoveryComplete(sessionID);
taskContinuationEnforcer?.markRecoveryComplete(sessionID);
});
}
const taskToolsRecord: Record<string, ToolDefinition> = taskSystemEnabled
? {
task_create: createTaskCreateTool(pluginConfig, ctx),
@@ -727,6 +742,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
await backgroundNotificationHook?.event(input);
await sessionNotification?.(input);
await todoContinuationEnforcer?.handler(input);
await taskContinuationEnforcer?.handler(input);
await unstableAgentBabysitter?.event(input);
await contextWindowMonitor?.event(input);
await directoryAgentsInjector?.event(input);
@@ -906,6 +922,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
if (command === "stop-continuation" && sessionID) {
stopContinuationGuard?.stop(sessionID);
todoContinuationEnforcer?.cancelAllCountdowns();
taskContinuationEnforcer?.cancelAllCountdowns();
ralphLoop?.cancelLoop(sessionID);
clearBoulderState(ctx.directory);
log("[stop-continuation] All continuation mechanisms stopped", {