From d74cd0de5c2efc8cea612bb00df6f6db037e565e Mon Sep 17 00:00:00 2001 From: can1357 Date: Mon, 9 Mar 2026 14:18:21 +0100 Subject: [PATCH] fix handoff system prompt reset --- .../coding-agent/src/session/agent-session.ts | 1 + .../test/agent-session-handoff.test.ts | 96 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/packages/coding-agent/src/session/agent-session.ts b/packages/coding-agent/src/session/agent-session.ts index 009b923d3..8ad0527b6 100644 --- a/packages/coding-agent/src/session/agent-session.ts +++ b/packages/coding-agent/src/session/agent-session.ts @@ -3243,6 +3243,7 @@ export class AgentSession { } this.#promptInFlightCount++; try { + this.agent.setSystemPrompt(this.#baseSystemPrompt); await this.#promptAgentWithIdleRetry([ { role: "developer", diff --git a/packages/coding-agent/test/agent-session-handoff.test.ts b/packages/coding-agent/test/agent-session-handoff.test.ts index 183c5ee88..f98b6886f 100644 --- a/packages/coding-agent/test/agent-session-handoff.test.ts +++ b/packages/coding-agent/test/agent-session-handoff.test.ts @@ -6,6 +6,7 @@ import { getBundledModel } from "@oh-my-pi/pi-ai/models"; import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream"; import { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry"; import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings"; +import type { ExtensionRunner } from "@oh-my-pi/pi-coding-agent/extensibility/extensions"; import { AgentSession, type AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session"; import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage"; import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager"; @@ -433,6 +434,101 @@ describe("AgentSession handoff", () => { }); }); + it("resets to the base system prompt before generating a handoff", async () => { + const model = session.model; + if (!model) { + throw new Error("Expected model to be set"); + } + await session.dispose(); + sessionManager = SessionManager.create(tempDir.path()); + + const emitBeforeAgentStart = vi.fn().mockResolvedValueOnce({ systemPrompt: "Hook override" }); + const extensionRunner = { + emitBeforeAgentStart, + emit: vi.fn().mockResolvedValue(undefined), + } as unknown as ExtensionRunner; + + const observedSystemPrompts: string[] = []; + let streamCallCount = 0; + const agent = new Agent({ + getApiKey: () => "test-key", + initialState: { + model, + systemPrompt: "Test", + tools: [], + messages: [], + }, + streamFn: (_model, context) => { + observedSystemPrompts.push(context.systemPrompt ?? ""); + streamCallCount++; + const stream = new MockAssistantStream(); + queueMicrotask(() => { + const message: AssistantMessage = { + role: "assistant", + content: [ + { + type: "text", + text: streamCallCount === 1 ? "normal response" : "## Goal\nContinue from here", + }, + ], + api: model.api, + provider: model.provider, + model: model.id, + stopReason: "stop", + usage: { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 0, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, + }, + timestamp: Date.now(), + }; + stream.push({ type: "start", partial: message }); + stream.push({ type: "done", reason: "stop", message }); + }); + return stream; + }, + }); + + session = new AgentSession({ + agent, + sessionManager, + settings: Settings.isolated({ "compaction.enabled": false }), + modelRegistry, + extensionRunner, + }); + sessionManager.appendMessage({ + role: "user", + content: [{ type: "text", text: "seed" }], + timestamp: Date.now() - 2, + }); + sessionManager.appendMessage({ + role: "assistant", + content: [{ type: "text", text: "seed response" }], + api: model.api, + provider: model.provider, + model: model.id, + stopReason: "stop", + usage: { + input: 16, + output: 8, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 24, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, + }, + timestamp: Date.now() - 1, + }); + + await session.prompt("hello from user"); + await session.handoff(); + + expect(emitBeforeAgentStart).toHaveBeenCalledTimes(1); + expect(observedSystemPrompts).toEqual(["Hook override", "Test"]); + }); + it("saves auto-handoff document to disk when enabled", async () => { session.settings.set("compaction.handoffSaveToDisk", true);