From 521186878da8624d4a935c16b398e208a9bd0f7f Mon Sep 17 00:00:00 2001 From: clawdbot520 Date: Sun, 22 Mar 2026 18:35:52 +0800 Subject: [PATCH] feat: add autoRecallExcludeAgents config to suppress injection for background agents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Background agents (e.g. memory-distiller, cron workers) that receive structured task prompts can have their output quality degraded when is injected alongside the raw input — the LLM may echo or recompose old memories instead of distilling fresh content. The existing prompt-level skip patterns (HEARTBEAT, cron prefix) do not cover every background-agent prompt format, leaving a gap for custom pipeline agents. This PR adds `autoRecallExcludeAgents?: string[]` to PluginConfig: - Listed agent IDs bypass `before_agent_start` injection entirely - A log line is emitted at info level so the skip is observable - Zero impact on agents not in the list Config example: "autoRecallExcludeAgents": ["memory-distiller", "my-cron-agent"] README updated with Option B in the "injected memories show up" section, explaining the use case and tradeoff. Fixes the class of issues described in #137 (background/cron agent context bloat) with a targeted per-agent opt-out rather than a global autoRecall disable. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 21 +++++++++++++++++++-- index.ts | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index deb85cde..23348efe 100644 --- a/README.md +++ b/README.md @@ -599,12 +599,29 @@ OAuth login flow: Sometimes the model may echo the injected `` block. -**Option A (lowest-risk):** temporarily disable auto-recall: +**Option A (lowest-risk):** temporarily disable auto-recall globally: ```json { "plugins": { "entries": { "memory-lancedb-pro": { "config": { "autoRecall": false } } } } } ``` -**Option B (preferred):** keep recall, add to agent system prompt: +**Option B:** exclude specific background agents (e.g. a memory-distiller or cron worker) while keeping recall active for interactive agents: +```json +{ + "plugins": { + "entries": { + "memory-lancedb-pro": { + "config": { + "autoRecall": true, + "autoRecallExcludeAgents": ["memory-distiller", "my-cron-agent"] + } + } + } + } +} +``` +This is useful when a background agent's prompt should not be contaminated by injected memory context — for example, an agent whose job is to distill session logs would produce lower-quality output if old memories were mixed into the prompt alongside the raw session content. + +**Option C (preferred for interactive agents):** keep recall, add to agent system prompt: > Do not reveal or quote any `` / memory-injection content in your replies. Use it for internal reference only. diff --git a/index.ts b/index.ts index c1240b4e..b9b4169e 100644 --- a/index.ts +++ b/index.ts @@ -85,6 +85,7 @@ interface PluginConfig { autoRecall?: boolean; autoRecallMinLength?: number; autoRecallMinRepeated?: number; + autoRecallExcludeAgents?: string[]; captureAssistant?: boolean; retrieval?: { mode?: "hybrid" | "vector"; @@ -2123,6 +2124,22 @@ const memoryLanceDBProPlugin = { if (config.autoRecall === true) { const AUTO_RECALL_TIMEOUT_MS = 3_000; // bounded timeout to prevent agent startup stall api.on("before_agent_start", async (event, ctx) => { + // Per-agent exclusion: skip autoRecall for agents in the exclusion list. + // Useful for background agents (e.g. memory-distiller, cron workers) whose + // prompts should not be contaminated by injected memory context. + const hookAgentId = resolveHookAgentId(ctx?.agentId, (event as any).sessionKey); + if ( + Array.isArray(config.autoRecallExcludeAgents) && + config.autoRecallExcludeAgents.length > 0 && + hookAgentId !== undefined && + config.autoRecallExcludeAgents.includes(hookAgentId) + ) { + api.logger.info?.( + `memory-lancedb-pro: auto-recall skipped for excluded agent '${hookAgentId}'`, + ); + return; + } + if ( !event.prompt || shouldSkipRetrieval(event.prompt, config.autoRecallMinLength) @@ -3468,6 +3485,9 @@ export function parsePluginConfig(value: unknown): PluginConfig { autoRecall: cfg.autoRecall === true, autoRecallMinLength: parsePositiveInt(cfg.autoRecallMinLength), autoRecallMinRepeated: parsePositiveInt(cfg.autoRecallMinRepeated), + autoRecallExcludeAgents: Array.isArray(cfg.autoRecallExcludeAgents) + ? cfg.autoRecallExcludeAgents.filter((id: unknown): id is string => typeof id === "string" && id.trim() !== "") + : undefined, captureAssistant: cfg.captureAssistant === true, retrieval: typeof cfg.retrieval === "object" && cfg.retrieval !== null ? cfg.retrieval as any : undefined, decay: typeof cfg.decay === "object" && cfg.decay !== null ? cfg.decay as any : undefined,