From 55f35708e181a43aad8e636af5526ac34bf64ef7 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:09:03 -0500 Subject: [PATCH] fix: use target session for bash sandbox hints --- .../reply/bash-command.stop.test.ts | 51 +++++++++++++++++++ src/auto-reply/reply/bash-command.ts | 4 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/auto-reply/reply/bash-command.stop.test.ts b/src/auto-reply/reply/bash-command.stop.test.ts index d9ce97b8b68..fbf53f9235c 100644 --- a/src/auto-reply/reply/bash-command.stop.test.ts +++ b/src/auto-reply/reply/bash-command.stop.test.ts @@ -43,6 +43,24 @@ function buildParams(commandBody: string) { }; } +function buildElevatedDeniedParams(commandBody: string) { + const base = buildParams(commandBody); + return { + ...base, + ctx: { + ...base.ctx, + SessionKey: "agent:main:telegram:slash-session", + } as MsgContext, + agentId: "main", + sessionKey: "agent:target:telegram:direct:target-session", + elevated: { + enabled: true, + allowed: false, + failures: [], + }, + }; +} + function buildRunningSession(overrides?: Record) { return { id: "session-1", @@ -116,4 +134,37 @@ describe("handleBashChatCommand stop", () => { expect(result.text).toContain("!poll session-1"); expect(killProcessTreeMock).not.toHaveBeenCalled(); }); + + it("uses the canonical target session for elevated sandbox explanation", async () => { + const sandboxRuntime = await import("../../agents/sandbox.js"); + const resolveSandboxRuntimeStatusSpy = vi + .spyOn(sandboxRuntime, "resolveSandboxRuntimeStatus") + .mockReturnValue({ + agentId: "target", + sessionKey: "agent:target:telegram:direct:target-session", + mainSessionKey: "agent:target:main", + mode: "non-main", + sandboxed: true, + toolPolicy: { + allowReadOutsideWorkspace: false, + allowReadInsideWorkspace: true, + allowWriteOutsideWorkspace: false, + allowWriteInsideWorkspace: true, + allowShell: true, + }, + }); + + const result = await handleBashChatCommand(buildElevatedDeniedParams("/bash pwd")); + + expect(resolveSandboxRuntimeStatusSpy).toHaveBeenCalledWith({ + cfg: expect.any(Object), + sessionKey: "agent:target:telegram:direct:target-session", + }); + expect(result.text).toContain( + "openclaw sandbox explain --session agent:target:telegram:direct:target-session", + ); + expect(result.text).not.toContain( + "openclaw sandbox explain --session agent:main:telegram:slash-session", + ); + }); }); diff --git a/src/auto-reply/reply/bash-command.ts b/src/auto-reply/reply/bash-command.ts index a4250d3a791..0d9fb93e99d 100644 --- a/src/auto-reply/reply/bash-command.ts +++ b/src/auto-reply/reply/bash-command.ts @@ -210,13 +210,13 @@ export async function handleBashChatCommand(params: { if (!params.elevated.enabled || !params.elevated.allowed) { const runtimeSandboxed = resolveSandboxRuntimeStatus({ cfg: params.cfg, - sessionKey: params.ctx.SessionKey, + sessionKey: params.sessionKey, }).sandboxed; return { text: formatElevatedUnavailableMessage({ runtimeSandboxed, failures: params.elevated.failures, - sessionKey: params.ctx.SessionKey, + sessionKey: params.sessionKey, }), }; }