Skip to content

fix: enforce plan mode in ACP session to block non-read-only tools (#1806) - #1839

Closed
echoVic wants to merge 1 commit into
QwenLM:mainfrom
echoVic:fix/acp-plan-mode-enforcement
Closed

fix: enforce plan mode in ACP session to block non-read-only tools (#1806)#1839
echoVic wants to merge 1 commit into
QwenLM:mainfrom
echoVic:fix/acp-plan-mode-enforcement

Conversation

@echoVic

@echoVic echoVic commented Feb 14, 2026

Copy link
Copy Markdown
Contributor

Problem

When using Qwen Code via ACP protocol (qwen --acp), calling session/set_mode with modeId: "plan" returns success but does not actually enforce plan mode restrictions. The agent still executes file edits and shell commands as if in default mode.

Root Cause

The ACP Session.runTool() method in packages/cli/src/acp-integration/session/Session.ts lacks the plan mode check that exists in coreToolScheduler.ts.

In coreToolScheduler.ts (interactive CLI mode):

if (isPlanMode && !isExitPlanModeTool) {
    // Block tool and return plan mode reminder
}

In ACP Session.runTool() (before this fix):

if (confirmationDetails) {
    // Directly request user permission — no plan mode check!
}

So when a tool requires confirmation (e.g., file edit, shell command), the ACP path would ask the user for permission instead of blocking it outright in plan mode.

Fix

Add plan mode enforcement in Session.runTool() that mirrors the logic in coreToolScheduler.ts:

if (isPlanMode && !isExitPlanModeTool && confirmationDetails) {
    return convertToFunctionResponse(fc.name, callId, getPlanModeSystemReminder());
}

When in plan mode, non-read-only tools (except exit_plan_mode) are blocked and return the plan mode system reminder to the model, instead of requesting user permission.

All 10 existing Session tests pass.

Fixes #1806

…wenLM#1806)

When using Qwen Code via ACP protocol (--acp), calling session/set_mode
with modeId 'plan' returned success but did not actually enforce plan
mode restrictions. The agent would still execute file edits and shell
commands.

Root cause: The ACP Session.runTool() method lacked the plan mode check
that exists in coreToolScheduler.ts. When a tool required confirmation
(confirmationDetails was truthy), it would proceed to requestPermission
instead of blocking the tool in plan mode.

Fix: Add plan mode enforcement in Session.runTool() that mirrors the
logic in coreToolScheduler.ts — when in plan mode, non-read-only tools
(except exit_plan_mode) are blocked and return the plan mode system
reminder instead of requesting user permission.

Fixes QwenLM#1806
@tanzhenxin

Copy link
Copy Markdown
Collaborator

@echoVic Thanks for your contribution! It is a clean and well-written PR. We'd glad to merge it, but it turned out we merged another PR #1812 for the same issue already. Looking forward to your next PR!

@tanzhenxin tanzhenxin closed this Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACP session/set_mode("plan") returns success but does not enforce plan mode behavior

2 participants