diff --git a/packages/server/src/server/agent/providers/pi/agent.test.ts b/packages/server/src/server/agent/providers/pi/agent.test.ts index 039d3eaf22..c04683bec2 100644 --- a/packages/server/src/server/agent/providers/pi/agent.test.ts +++ b/packages/server/src/server/agent/providers/pi/agent.test.ts @@ -2183,6 +2183,25 @@ describe("PiRpcAgentSession", () => { ]); }); + test.each([false, true])( + "closing Pi releases an active turn without publishing a terminal outcome (autonomous=%s)", + async (autonomous) => { + const { pi, session, events } = await createSession(); + if (autonomous) { + pi.latestSession().emit({ type: "agent_start" }); + pi.latestSession().emit({ type: "turn_start" }); + } else { + await session.startTurn("keep working"); + } + const before = events.turnLifecycleEvents(); + + await session.close(); + + expect(pi.latestSession().closeCalls).toBe(1); + expect(events.turnLifecycleEvents()).toEqual(before); + }, + ); + test("fails the active turn when the Pi process exits mid-turn", async () => { const { pi, session, events } = await createSession(); diff --git a/packages/server/src/server/agent/providers/pi/agent.ts b/packages/server/src/server/agent/providers/pi/agent.ts index 198d596c9b..89276b199f 100644 --- a/packages/server/src/server/agent/providers/pi/agent.ts +++ b/packages/server/src/server/agent/providers/pi/agent.ts @@ -2204,12 +2204,16 @@ export class PiRpcAgentSession implements AgentSession { this.pendingSettledMessages = null; this.pendingSteerSubmissions.length = 0; this.clearNoTurnBuffers(); - this.emit({ - type: "turn_failed", - provider: this.provider, - turnId, - error, - }); + // Releasing the runtime is not a failed turn: restart recovery still owns + // unfinished work after the session has been intentionally closed. + if (!this.closed) { + this.emit({ + type: "turn_failed", + provider: this.provider, + turnId, + error, + }); + } } private handleSessionEvent(event: PiAgentSessionEvent): void { diff --git a/packages/server/src/server/agent/providers/pi/test-utils/fake-pi.ts b/packages/server/src/server/agent/providers/pi/test-utils/fake-pi.ts index 770f24625c..b375b291a1 100644 --- a/packages/server/src/server/agent/providers/pi/test-utils/fake-pi.ts +++ b/packages/server/src/server/agent/providers/pi/test-utils/fake-pi.ts @@ -427,6 +427,10 @@ export class FakePiSession implements PiRuntimeSession { async close(): Promise { this.closeCalls += 1; + this.emit({ + type: "process_exit", + error: "Pi RPC process exited with code 0 and signal null", + }); } emit(event: PiRuntimeEvent): void {