From dd6271bbf400edb425ef554508de27808ff27b9a Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 15 May 2026 11:30:24 +0900 Subject: [PATCH] fix(babysitter): gate reminder prompts --- .../unstable-agent-babysitter-hook.ts | 39 ++++++++++++------- src/plugin/unstable-agent-babysitter.ts | 22 ++++++++++- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.ts b/src/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.ts index 729192965..30cb01cca 100644 --- a/src/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.ts +++ b/src/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.ts @@ -12,7 +12,7 @@ import { isUnstableTask, THINKING_SUMMARY_MAX_CHARS, } from "./task-message-analyzer" -import { shouldPromptAfterSessionIdle } from "../shared/session-idle-settle" +import { promptAsyncAfterSessionIdle } from "../shared/prompt-async-gate" const HOOK_NAME = "unstable-agent-babysitter" const DEFAULT_TIMEOUT_MS = 120000 @@ -216,22 +216,31 @@ export function createUnstableAgentBabysitterHook(ctx: BabysitterContext, option ? { providerID: model.providerID, modelID: model.modelID } : undefined const launchVariant = model?.variant - if (!(await shouldPromptAfterSessionIdle(ctx.client, mainSessionID, options.idleSettleMs))) { - log(`[${HOOK_NAME}] Reminder skipped because main session is active`, { taskId: task.id, sessionID: mainSessionID }) + const promptResult = await promptAsyncAfterSessionIdle({ + client: ctx.client, + sessionID: mainSessionID, + source: HOOK_NAME, + settleMs: options.idleSettleMs, + input: { + path: { id: mainSessionID }, + body: { + ...(agent ? { agent } : {}), + ...(launchModel ? { model: launchModel } : {}), + ...(launchVariant ? { variant: launchVariant } : {}), + ...(tools ? { tools } : {}), + parts: [createInternalAgentTextPart(reminder)], + }, + query: { directory: ctx.directory }, + }, + }) + if (promptResult.status !== "dispatched") { + log(`[${HOOK_NAME}] Reminder skipped by promptAsync gate`, { + taskId: task.id, + sessionID: mainSessionID, + status: promptResult.status, + }) continue } - - await ctx.client.session.promptAsync({ - path: { id: mainSessionID }, - body: { - ...(agent ? { agent } : {}), - ...(launchModel ? { model: launchModel } : {}), - ...(launchVariant ? { variant: launchVariant } : {}), - ...(tools ? { tools } : {}), - parts: [createInternalAgentTextPart(reminder)], - }, - query: { directory: ctx.directory }, - }) reminderCooldowns.set(task.id, now) log(`[${HOOK_NAME}] Reminder injected`, { taskId: task.id, sessionID: mainSessionID }) } catch (error) { diff --git a/src/plugin/unstable-agent-babysitter.ts b/src/plugin/unstable-agent-babysitter.ts index 6ab73bbd8..040c26d21 100644 --- a/src/plugin/unstable-agent-babysitter.ts +++ b/src/plugin/unstable-agent-babysitter.ts @@ -3,6 +3,7 @@ import type { PluginContext } from "./types" import { createUnstableAgentBabysitterHook } from "../hooks" import type { BackgroundManager } from "../features/background-agent" +import { promptAsyncAfterSessionIdle } from "../hooks/shared/prompt-async-gate" export function createUnstableAgentBabysitter(args: { ctx: PluginContext @@ -24,11 +25,28 @@ export function createUnstableAgentBabysitter(args: { } return [] }, + status: async () => ctx.client.session.status(), prompt: async (promptArgs) => { - await ctx.client.session.promptAsync(promptArgs) + const promptResult = await promptAsyncAfterSessionIdle({ + client: ctx.client, + sessionID: promptArgs.path.id, + source: "unstable-agent-babysitter", + input: promptArgs, + }) + if (promptResult.status === "failed") { + throw promptResult.error + } }, promptAsync: async (promptArgs) => { - await ctx.client.session.promptAsync(promptArgs) + const promptResult = await promptAsyncAfterSessionIdle({ + client: ctx.client, + sessionID: promptArgs.path.id, + source: "unstable-agent-babysitter", + input: promptArgs, + }) + if (promptResult.status === "failed") { + throw promptResult.error + } }, }, },