From c90cb9c3c95cc2f8e86efead0c9ea05565a85c53 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 9 Apr 2026 05:26:07 +0100 Subject: [PATCH] test: expand helper coverage for memory flush policy --- .../reply/agent-runner-memory.test.ts | 92 +++++++++++++++++++ src/auto-reply/reply/agent-runner-memory.ts | 4 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/auto-reply/reply/agent-runner-memory.test.ts b/src/auto-reply/reply/agent-runner-memory.test.ts index be17c62d528..8196df99d2b 100644 --- a/src/auto-reply/reply/agent-runner-memory.test.ts +++ b/src/auto-reply/reply/agent-runner-memory.test.ts @@ -195,4 +195,96 @@ describe("runMemoryFlushIfNeeded", () => { expect(persisted.main.memoryFlushCompactionCount).toBe(2); expect(persisted.main.memoryFlushAt).toBe(1_700_000_000_000); }); + + it("skips memory flush for CLI providers", async () => { + const sessionEntry: SessionEntry = { + sessionId: "session", + updatedAt: Date.now(), + totalTokens: 80_000, + compactionCount: 1, + }; + + const entry = await runMemoryFlushIfNeeded({ + cfg: { agents: { defaults: { cliBackends: { "codex-cli": { command: "codex" } } } } }, + followupRun: createFollowupRun({ provider: "codex-cli" }), + sessionCtx: { Provider: "whatsapp" } as unknown as TemplateContext, + defaultModel: "codex-cli/gpt-5.4", + agentCfgContextTokens: 100_000, + resolvedVerboseLevel: "off", + sessionEntry, + sessionStore: { main: sessionEntry }, + sessionKey: "main", + isHeartbeat: false, + replyOperation: createReplyOperation(), + }); + + expect(entry).toBe(sessionEntry); + expect(runEmbeddedPiAgentMock).not.toHaveBeenCalled(); + }); + + it("uses configured prompts and stored bootstrap warning signatures", async () => { + const sessionEntry: SessionEntry = { + sessionId: "session", + updatedAt: Date.now(), + totalTokens: 80_000, + compactionCount: 1, + systemPromptReport: { + source: "run", + generatedAt: Date.now(), + systemPrompt: { chars: 1, projectContextChars: 0, nonProjectContextChars: 1 }, + injectedWorkspaceFiles: [], + skills: { promptChars: 0, entries: [] }, + tools: { listChars: 0, schemaChars: 0, entries: [] }, + bootstrapTruncation: { + warningMode: "once", + warningShown: true, + promptWarningSignature: "sig-b", + warningSignaturesSeen: ["sig-a", "sig-b"], + truncatedFiles: 1, + nearLimitFiles: 0, + totalNearLimit: false, + }, + }, + }; + registerMemoryFlushPlanResolver(() => ({ + softThresholdTokens: 4_000, + forceFlushTranscriptBytes: 1_000_000_000, + reserveTokensFloor: 20_000, + prompt: "Write notes.\nNO_REPLY to memory/2023-11-14.md and MEMORY.md", + systemPrompt: "Flush memory now. NO_REPLY memory/YYYY-MM-DD.md MEMORY.md", + relativePath: "memory/2023-11-14.md", + })); + + await runMemoryFlushIfNeeded({ + cfg: { agents: { defaults: { compaction: { memoryFlush: {} } } } }, + followupRun: createFollowupRun({ extraSystemPrompt: "extra system" }), + sessionCtx: { Provider: "whatsapp" } as unknown as TemplateContext, + defaultModel: "anthropic/claude-opus-4-6", + agentCfgContextTokens: 100_000, + resolvedVerboseLevel: "off", + sessionEntry, + sessionStore: { main: sessionEntry }, + sessionKey: "main", + isHeartbeat: false, + replyOperation: createReplyOperation(), + }); + + const flushCall = runEmbeddedPiAgentMock.mock.calls[0]?.[0] as { + prompt?: string; + extraSystemPrompt?: string; + bootstrapPromptWarningSignaturesSeen?: string[]; + bootstrapPromptWarningSignature?: string; + memoryFlushWritePath?: string; + silentExpected?: boolean; + }; + expect(flushCall.prompt).toContain("Write notes."); + expect(flushCall.prompt).toContain("NO_REPLY"); + expect(flushCall.prompt).toContain("MEMORY.md"); + expect(flushCall.extraSystemPrompt).toContain("extra system"); + expect(flushCall.extraSystemPrompt).toContain("Flush memory now."); + expect(flushCall.memoryFlushWritePath).toBe("memory/2023-11-14.md"); + expect(flushCall.silentExpected).toBe(true); + expect(flushCall.bootstrapPromptWarningSignaturesSeen).toEqual(["sig-a", "sig-b"]); + expect(flushCall.bootstrapPromptWarningSignature).toBe("sig-b"); + }); }); diff --git a/src/auto-reply/reply/agent-runner-memory.ts b/src/auto-reply/reply/agent-runner-memory.ts index ce600e3417e..e45c45e57a3 100644 --- a/src/auto-reply/reply/agent-runner-memory.ts +++ b/src/auto-reply/reply/agent-runner-memory.ts @@ -46,6 +46,7 @@ import type { ReplyOperation } from "./reply-run-registry.js"; import { incrementCompactionCount } from "./session-updates.js"; const memoryDeps = { + compactEmbeddedPiSession, runWithModelFallback, runEmbeddedPiAgent, registerAgentRunContext, @@ -59,6 +60,7 @@ const memoryDeps = { export function setAgentRunnerMemoryTestDeps(overrides?: Partial): void { Object.assign(memoryDeps, { runWithModelFallback, + compactEmbeddedPiSession, runEmbeddedPiAgent, registerAgentRunContext, refreshQueuedFollowupSession, @@ -432,7 +434,7 @@ export async function runPreflightCompactionIfNeeded(params: { params.sessionKey ?? params.followupRun.run.sessionKey, { storePath: params.storePath }, ); - const result = await compactEmbeddedPiSession({ + const result = await memoryDeps.compactEmbeddedPiSession({ sessionId: entry.sessionId, sessionKey: params.sessionKey, allowGatewaySubagentBinding: true,