From 6ece7476efe656a3b06b48cb600b9e6835737042 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 8 Dec 2025 16:54:44 +0900 Subject: [PATCH] feat(hooks): add empty-task-response-detector hook --- src/hooks/empty-task-response-detector.ts | 27 +++++++++++++++++++++++ src/index.ts | 3 +++ 2 files changed, 30 insertions(+) create mode 100644 src/hooks/empty-task-response-detector.ts diff --git a/src/hooks/empty-task-response-detector.ts b/src/hooks/empty-task-response-detector.ts new file mode 100644 index 0000000..01ea0bc --- /dev/null +++ b/src/hooks/empty-task-response-detector.ts @@ -0,0 +1,27 @@ +import type { PluginInput } from "@opencode-ai/plugin" + +const EMPTY_RESPONSE_WARNING = `[Task Empty Response Warning] + +Task invocation completed but returned no response. This indicates the agent either: +- Failed to execute properly +- Did not terminate correctly +- Returned an empty result + +Note: The call has already completed - you are NOT waiting for a response. Proceed accordingly.` + +export function createEmptyTaskResponseDetectorHook(_ctx: PluginInput) { + return { + "tool.execute.after": async ( + input: { tool: string; sessionID: string; callID: string }, + output: { title: string; output: string; metadata: unknown } + ) => { + if (input.tool !== "Task") return + + const responseText = output.output?.trim() ?? "" + + if (responseText === "") { + output.output = EMPTY_RESPONSE_WARNING + } + }, + } +} diff --git a/src/index.ts b/src/index.ts index 88e9005..94a0141 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { createGrepOutputTruncatorHook, createPulseMonitorHook, createDirectoryAgentsInjectorHook, + createEmptyTaskResponseDetectorHook, } from "./hooks"; import { updateTerminalTitle } from "./features/terminal"; import { builtinTools } from "./tools"; @@ -57,6 +58,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { const commentChecker = createCommentCheckerHooks(); const grepOutputTruncator = createGrepOutputTruncatorHook(ctx); const directoryAgentsInjector = createDirectoryAgentsInjectorHook(ctx); + const emptyTaskResponseDetector = createEmptyTaskResponseDetectorHook(ctx); updateTerminalTitle({ sessionId: "main" }); @@ -212,6 +214,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { await contextWindowMonitor["tool.execute.after"](input, output); await commentChecker["tool.execute.after"](input, output); await directoryAgentsInjector["tool.execute.after"](input, output); + await emptyTaskResponseDetector["tool.execute.after"](input, output); if (input.sessionID === mainSessionID) { updateTerminalTitle({