From e2047e2e851a8f4472bc27b023242f86c31a82bf Mon Sep 17 00:00:00 2001 From: LHMQ878 <72402929@cityu-dg.edu.cn> Date: Sat, 8 Aug 2026 16:48:30 +0800 Subject: [PATCH] fix: detect internal agents from primary system prompt only Bundled internal-agent system prompts in the same API call no longer cause DCP to skip nudge injection on main sessions. --- lib/hooks.ts | 12 +++++-- tests/hooks-permission.test.ts | 63 ++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/lib/hooks.ts b/lib/hooks.ts index 67030f1c..6d6f3862 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -46,6 +46,15 @@ const INTERNAL_AGENT_SIGNATURES = [ "Summarize what was done in this conversation", ] +function isInternalAgentCall(systemPrompts: string[]): boolean { + const primaryPrompt = systemPrompts[0] + if (typeof primaryPrompt !== "string" || primaryPrompt.length === 0) { + return false + } + + return INTERNAL_AGENT_SIGNATURES.some((signature) => primaryPrompt.includes(signature)) +} + export function createSystemPromptHandler( state: SessionState, logger: Logger, @@ -65,8 +74,7 @@ export function createSystemPromptHandler( return } - const systemText = output.system.join("\n") - if (INTERNAL_AGENT_SIGNATURES.some((sig) => systemText.includes(sig))) { + if (isInternalAgentCall(output.system)) { logger.info("Skipping DCP system prompt injection for internal agent") return } diff --git a/tests/hooks-permission.test.ts b/tests/hooks-permission.test.ts index 71be03a4..58d26c83 100644 --- a/tests/hooks-permission.test.ts +++ b/tests/hooks-permission.test.ts @@ -114,6 +114,69 @@ test("system prompt handler caches full model context for percentage thresholds" assert.equal(state.modelContextLimit, 200000) }) +function buildPromptStore() { + return { + reload() {}, + getRuntimePrompts() { + return { + system: "DCP-RUNTIME-PROMPT", + manualExtension: "", + subagentExtension: "", + } + }, + } as any +} + +test("system prompt handler injects nudges for main session with bundled internal prompts", async () => { + const state = createSessionState() + const handler = createSystemPromptHandler( + state, + new Logger(false), + buildConfig("allow"), + buildPromptStore(), + ) + const output = { + system: [ + "You are the primary coding assistant for this repository.", + "You are a title generator for short session names.", + ], + } + + await handler( + { + sessionID: "session-1", + model: { limit: { context: 200000 } }, + } as any, + output, + ) + + assert.match(output.system[output.system.length - 1], /DCP-RUNTIME-PROMPT/) +}) + +test("system prompt handler skips injection for internal agent calls", async () => { + const state = createSessionState() + const handler = createSystemPromptHandler( + state, + new Logger(false), + buildConfig("allow"), + buildPromptStore(), + ) + const output = { + system: ["You are a title generator. Return only a short title."], + } + + await handler( + { + sessionID: "session-1", + model: { limit: { context: 200000 } }, + } as any, + output, + ) + + assert.equal(output.system.length, 1) + assert.doesNotMatch(output.system[0], /DCP-RUNTIME-PROMPT/) +}) + test("chat message transform strips hallucinated tags even when compress is denied", async () => { const state = createSessionState() const logger = new Logger(false)