From 79797249f4ee80e439a41f734f2201de21e11662 Mon Sep 17 00:00:00 2001 From: Pejman Pour-Moezzi <481729+pejmanjohn@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:36:42 -0700 Subject: [PATCH] fix: guard resumeSessionId against non-ACP runtime Add early-return error when resumeSessionId is passed without runtime="acp" (mirrors existing streamTo guard). Without this, the parameter is silently ignored and the agent gets a fresh session instead of resuming. Also update schema description to note the runtime=acp requirement. Addresses Greptile review feedback. --- src/agents/tools/sessions-spawn-tool.test.ts | 15 +++++++++++++++ src/agents/tools/sessions-spawn-tool.ts | 9 ++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/agents/tools/sessions-spawn-tool.test.ts b/src/agents/tools/sessions-spawn-tool.test.ts index d406ccb1759..4fe106a7ebd 100644 --- a/src/agents/tools/sessions-spawn-tool.test.ts +++ b/src/agents/tools/sessions-spawn-tool.test.ts @@ -185,6 +185,21 @@ describe("sessions_spawn tool", () => { ); }); + it("rejects resumeSessionId without runtime=acp", async () => { + const tool = createSessionsSpawnTool({ + agentSessionKey: "agent:main:main", + }); + + const result = await tool.execute("call-guard", { + task: "resume prior work", + resumeSessionId: "7f4a78e0-f6be-43fe-855c-c1c4fd229bc4", + }); + + expect(JSON.stringify(result)).toContain("resumeSessionId is only supported for runtime=acp"); + expect(hoisted.spawnSubagentDirectMock).not.toHaveBeenCalled(); + expect(hoisted.spawnAcpDirectMock).not.toHaveBeenCalled(); + }); + it("rejects attachments for ACP runtime", async () => { const tool = createSessionsSpawnTool({ agentSessionKey: "agent:main:main", diff --git a/src/agents/tools/sessions-spawn-tool.ts b/src/agents/tools/sessions-spawn-tool.ts index 30ca08bc306..b735084d2b0 100644 --- a/src/agents/tools/sessions-spawn-tool.ts +++ b/src/agents/tools/sessions-spawn-tool.ts @@ -28,7 +28,7 @@ const SessionsSpawnToolSchema = Type.Object({ resumeSessionId: Type.Optional( Type.String({ description: - "Resume an existing agent session by its ID (e.g. a Codex session UUID from ~/.codex/sessions/). The agent replays conversation history via session/load instead of starting fresh.", + 'Resume an existing agent session by its ID (e.g. a Codex session UUID from ~/.codex/sessions/). Requires runtime="acp". The agent replays conversation history via session/load instead of starting fresh.', }), ), model: Type.Optional(Type.String()), @@ -134,6 +134,13 @@ export function createSessionsSpawnTool( }); } + if (resumeSessionId && runtime !== "acp") { + return jsonResult({ + status: "error", + error: `resumeSessionId is only supported for runtime=acp; got runtime=${runtime}`, + }); + } + if (runtime === "acp") { if (Array.isArray(attachments) && attachments.length > 0) { return jsonResult({