From c91ec2aab7a593e45c614ef487ea776b3e51abb8 Mon Sep 17 00:00:00 2001 From: Adam Holt Date: Sat, 10 Jan 2026 12:52:54 +1300 Subject: [PATCH] fix: only inject heartbeat prompt for default agent The heartbeat prompt from agents.defaults.heartbeat.prompt was being injected into the system prompt for ALL agents, causing non-default agents to read the default agent's identity files and adopt its persona. Now the heartbeat prompt is only included when the session's agent ID matches the configured default agent. Other agents receive no heartbeat section in their system prompt. Co-Authored-By: Claude Opus 4.5 --- src/agents/pi-embedded-runner.ts | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/agents/pi-embedded-runner.ts b/src/agents/pi-embedded-runner.ts index 5baf03776..b3b604cfc 100644 --- a/src/agents/pi-embedded-runner.ts +++ b/src/agents/pi-embedded-runner.ts @@ -33,9 +33,11 @@ import { type enqueueCommand, enqueueCommandInLane, } from "../process/command-queue.js"; +import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; import { normalizeMessageProvider } from "../utils/message-provider.js"; import { resolveUserPath } from "../utils.js"; import { resolveClawdbotAgentDir } from "./agent-paths.js"; +import { resolveDefaultAgentId } from "./agent-scope.js"; import { markAuthProfileFailure, markAuthProfileGood, @@ -882,15 +884,21 @@ export async function compactEmbeddedPiSession(params: { params.config?.agents?.defaults?.userTimezone, ); const userTime = formatUserTime(new Date(), userTimezone); + // Only include heartbeat prompt for the default agent + const sessionAgentId = resolveAgentIdFromSessionKey(params.sessionKey); + const defaultAgentId = resolveDefaultAgentId(params.config ?? {}); + const isDefaultAgent = sessionAgentId === defaultAgentId; const appendPrompt = buildEmbeddedSystemPrompt({ workspaceDir: effectiveWorkspace, defaultThinkLevel: params.thinkLevel, extraSystemPrompt: params.extraSystemPrompt, ownerNumbers: params.ownerNumbers, reasoningTagHint, - heartbeatPrompt: resolveHeartbeatPrompt( - params.config?.agents?.defaults?.heartbeat?.prompt, - ), + heartbeatPrompt: isDefaultAgent + ? resolveHeartbeatPrompt( + params.config?.agents?.defaults?.heartbeat?.prompt, + ) + : undefined, skillsPrompt, runtimeInfo, sandboxInfo, @@ -1245,15 +1253,23 @@ export async function runEmbeddedPiAgent(params: { params.config?.agents?.defaults?.userTimezone, ); const userTime = formatUserTime(new Date(), userTimezone); + // Only include heartbeat prompt for the default agent + const sessionAgentId = resolveAgentIdFromSessionKey( + params.sessionKey, + ); + const defaultAgentId = resolveDefaultAgentId(params.config ?? {}); + const isDefaultAgent = sessionAgentId === defaultAgentId; const appendPrompt = buildEmbeddedSystemPrompt({ workspaceDir: effectiveWorkspace, defaultThinkLevel: thinkLevel, extraSystemPrompt: params.extraSystemPrompt, ownerNumbers: params.ownerNumbers, reasoningTagHint, - heartbeatPrompt: resolveHeartbeatPrompt( - params.config?.agents?.defaults?.heartbeat?.prompt, - ), + heartbeatPrompt: isDefaultAgent + ? resolveHeartbeatPrompt( + params.config?.agents?.defaults?.heartbeat?.prompt, + ) + : undefined, skillsPrompt, runtimeInfo, sandboxInfo,