From 2ba26bc4e94bc7e5e59499c4052db4d623d3b5e4 Mon Sep 17 00:00:00 2001 From: Zarian Lewis Date: Wed, 28 Jan 2026 09:30:57 -0600 Subject: [PATCH] fix: skip heartbeat wake for subagent exec completions When sub-agents run many exec commands (e.g., during builds), each completion triggers requestHeartbeatNow() which wakes the main session. With only 250ms coalesce, this causes heartbeat spam in the main session. This change skips the heartbeat wake when the exec belongs to a subagent session (sessionKey contains ":subagent:"). The system event is still enqueued for the subagent session, but the main session is not woken. Fixes heartbeat spam when sub-agents run background builds or other multi-exec workflows. --- src/agents/bash-tools.exec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/agents/bash-tools.exec.ts b/src/agents/bash-tools.exec.ts index b9de81872..0b37ba9bc 100644 --- a/src/agents/bash-tools.exec.ts +++ b/src/agents/bash-tools.exec.ts @@ -318,7 +318,10 @@ function maybeNotifyOnExit(session: ProcessSession, status: "completed" | "faile ? `Exec ${status} (${session.id.slice(0, 8)}, ${exitLabel}) :: ${output}` : `Exec ${status} (${session.id.slice(0, 8)}, ${exitLabel})`; enqueueSystemEvent(summary, { sessionKey }); - requestHeartbeatNow({ reason: `exec:${session.id}:exit` }); + // Skip heartbeat for subagent exec completions - prevents main session spam + if (!sessionKey.includes(":subagent:")) { + requestHeartbeatNow({ reason: `exec:${session.id}:exit` }); + } } function createApprovalSlug(id: string) { @@ -337,7 +340,10 @@ function emitExecSystemEvent(text: string, opts: { sessionKey?: string; contextK const sessionKey = opts.sessionKey?.trim(); if (!sessionKey) return; enqueueSystemEvent(text, { sessionKey, contextKey: opts.contextKey }); - requestHeartbeatNow({ reason: "exec-event" }); + // Skip heartbeat for subagent exec events + if (!sessionKey.includes(":subagent:")) { + requestHeartbeatNow({ reason: "exec-event" }); + } } async function runExecProcess(opts: {