mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 12:11:09 +00:00
feat: Implement Plan Mode for Safe Code Planning (#658)
Some checks are pending
Qwen Code CI / Lint (GitHub Actions) (push) Waiting to run
Qwen Code CI / Lint (Javascript) (push) Waiting to run
Qwen Code CI / Lint (Shell) (push) Waiting to run
Qwen Code CI / Lint (YAML) (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker-1 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none-1 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker-2 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none-2 (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
Some checks are pending
Qwen Code CI / Lint (GitHub Actions) (push) Waiting to run
Qwen Code CI / Lint (Javascript) (push) Waiting to run
Qwen Code CI / Lint (Shell) (push) Waiting to run
Qwen Code CI / Lint (YAML) (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker-1 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none-1 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker-2 (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none-2 (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
This commit is contained in:
parent
8379bc4d81
commit
4e7a7e2656
43 changed files with 2895 additions and 281 deletions
|
|
@ -52,6 +52,39 @@ const logger = {
|
|||
error: (...args: any[]) => console.error('[ERROR]', ...args),
|
||||
};
|
||||
|
||||
const VALID_APPROVAL_MODE_VALUES = [
|
||||
'plan',
|
||||
'default',
|
||||
'auto-edit',
|
||||
'yolo',
|
||||
] as const;
|
||||
|
||||
function formatApprovalModeError(value: string): Error {
|
||||
return new Error(
|
||||
`Invalid approval mode: ${value}. Valid values are: ${VALID_APPROVAL_MODE_VALUES.join(
|
||||
', ',
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
function parseApprovalModeValue(value: string): ApprovalMode {
|
||||
const normalized = value.trim().toLowerCase();
|
||||
switch (normalized) {
|
||||
case 'plan':
|
||||
return ApprovalMode.PLAN;
|
||||
case 'default':
|
||||
return ApprovalMode.DEFAULT;
|
||||
case 'yolo':
|
||||
return ApprovalMode.YOLO;
|
||||
case 'auto_edit':
|
||||
case 'autoedit':
|
||||
case 'auto-edit':
|
||||
return ApprovalMode.AUTO_EDIT;
|
||||
default:
|
||||
throw formatApprovalModeError(value);
|
||||
}
|
||||
}
|
||||
|
||||
export interface CliArgs {
|
||||
model: string | undefined;
|
||||
sandbox: boolean | string | undefined;
|
||||
|
|
@ -147,9 +180,9 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
|
|||
})
|
||||
.option('approval-mode', {
|
||||
type: 'string',
|
||||
choices: ['default', 'auto_edit', 'yolo'],
|
||||
choices: ['plan', 'default', 'auto-edit', 'yolo'],
|
||||
description:
|
||||
'Set the approval mode: default (prompt for approval), auto_edit (auto-approve edit tools), yolo (auto-approve all tools)',
|
||||
'Set the approval mode: plan (plan only), default (prompt for approval), auto-edit (auto-approve edit tools), yolo (auto-approve all tools)',
|
||||
})
|
||||
.option('telemetry', {
|
||||
type: 'boolean',
|
||||
|
|
@ -438,30 +471,21 @@ export async function loadCliConfig(
|
|||
// Determine approval mode with backward compatibility
|
||||
let approvalMode: ApprovalMode;
|
||||
if (argv.approvalMode) {
|
||||
// New --approval-mode flag takes precedence
|
||||
switch (argv.approvalMode) {
|
||||
case 'yolo':
|
||||
approvalMode = ApprovalMode.YOLO;
|
||||
break;
|
||||
case 'auto_edit':
|
||||
approvalMode = ApprovalMode.AUTO_EDIT;
|
||||
break;
|
||||
case 'default':
|
||||
approvalMode = ApprovalMode.DEFAULT;
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
`Invalid approval mode: ${argv.approvalMode}. Valid values are: yolo, auto_edit, default`,
|
||||
);
|
||||
}
|
||||
approvalMode = parseApprovalModeValue(argv.approvalMode);
|
||||
} else if (argv.yolo) {
|
||||
approvalMode = ApprovalMode.YOLO;
|
||||
} else if (settings.approvalMode) {
|
||||
approvalMode = parseApprovalModeValue(settings.approvalMode);
|
||||
} else {
|
||||
// Fallback to legacy --yolo flag behavior
|
||||
approvalMode =
|
||||
argv.yolo || false ? ApprovalMode.YOLO : ApprovalMode.DEFAULT;
|
||||
approvalMode = ApprovalMode.DEFAULT;
|
||||
}
|
||||
|
||||
// Force approval mode to default if the folder is not trusted.
|
||||
if (!trustedFolder && approvalMode !== ApprovalMode.DEFAULT) {
|
||||
if (
|
||||
!trustedFolder &&
|
||||
approvalMode !== ApprovalMode.DEFAULT &&
|
||||
approvalMode !== ApprovalMode.PLAN
|
||||
) {
|
||||
logger.warn(
|
||||
`Approval mode overridden to "default" because the current folder is not trusted.`,
|
||||
);
|
||||
|
|
@ -474,6 +498,7 @@ export async function loadCliConfig(
|
|||
const extraExcludes: string[] = [];
|
||||
if (!interactive && !argv.experimentalAcp) {
|
||||
switch (approvalMode) {
|
||||
case ApprovalMode.PLAN:
|
||||
case ApprovalMode.DEFAULT:
|
||||
// In default non-interactive mode, all tools that require approval are excluded.
|
||||
extraExcludes.push(ShellTool.Name, EditTool.Name, WriteFileTool.Name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue