Qwen Code Approval Mode 跨语言契约设计:core 单一事实来源与 SDK 派生校验 Qwen Code Approval Mode 跨语言契约设计core 单一事实来源与 SDK 派生校验【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-codeApproval Mode审批模式是 Qwen Code 终端 AI 编程代理中控制 AI 对文件编辑与 Shell 命令权限的核心机制。本文基于仓库设计文档 2026-08-23-approval-mode-contract.md完整讲解五种权限模式的取值语义并从源码层面剖析以 core 为运行时单一事实来源、TypeScript/Python/Java SDK 各自派生本地类型、用统一 JSON fixture 做跨语言契约校验这一架构决策帮助你在使用、集成或二次开发 Qwen Code 时准确理解和复用 Approval Mode 契约。一、契约决策总览为什么需要跨语言契约Qwen Code 是一个多语言 SDK 生态的终端 AI 编程代理Approval Mode 的取值域被以下多个层共同使用coreApprovalMode枚举与APPROVAL_MODES数组是运行时的事实来源CLI 与 TypeScript SDK系统消息中的permission_mode字段需要类型化Python SDK 与 Java SDK分别维护原生公共类型PermissionMode别名 / 枚举。如果没有统一契约各包自行定义字符串字面量极易出现拼写漂移、漏加新模式、校验逻辑不一致等问题。设计文档给出的核心决策是KeepApprovalModeandAPPROVAL_MODESin core as the runtime source of truth.TypeScript packages derive their local types and validators from either that core contract or the TypeScript SDKs checked tuple. Python and Java keep native public types, with their accepted values checked against a small JSON fixture that is also checked against core.即core 持有权威枚举TypeScript 侧从 core 或 SDK 的受检元组派生本地类型与校验器Python/Java 保留原生公共类型但通过一份同时与 core 对照的 JSON fixture 校验取值。这样既避免了已发布 SDK 对 core 引入运行时依赖也为一个仅有五个取值的领域避免了引入代码生成。二、core 侧的事实来源枚举、字符串联合与 JSON fixture2.1 枚举定义core 中 Approval Mode 的权威定义位于 packages/core/src/config/approval-mode.tsexport enum ApprovalMode { PLAN plan, DEFAULT default, AUTO_EDIT auto-edit, AUTO auto, YOLO yolo, } export type ApprovalModeValue ${ApprovalMode}; export const APPROVAL_MODES Object.values(ApprovalMode);ApprovalMode枚举定义了五个取值plan、default、auto-edit、auto、yoloApprovalModeValue通过模板字面量类型把枚举投影为字符串联合类型string-union form这正是设计文档中Export the string-union form of coresApprovalMode所指的改动APPROVAL_MODES是取值数组供各消费方做包含性校验与遍历。2.2 JSON fixture跨语言契约的锚点packages/core/src/config/approval-modes.json 是全文唯一的跨语言契约文件[plan, default, auto-edit, auto, yolo]设计文档中Check core, TypeScript, Python, and Java accepted values against one fixture in their existing test suites与Trigger the Python and Java SDK workflows when the fixture changes两条改动均以这份 JSON 为锚点。它不参与运行时逻辑只作为测试期的一致性参照物。2.3 相邻取值域为何不并入本契约设计文档明确划定了边界channel modes、hook permission decisions、desktop cycling preferences 等相邻取值域保持独立因为它们的支持取值与语义有意不同。这提示我们在集成时不要把 Approval Mode 契约泛化到其他权限相关字段以免破坏各自领域的独立演化。三、TypeScript 侧派生core / SDK 双路径设计文档要求Replace repeated TypeScript unions and validation arrays with the core or SDK contract并Type the CLI and TypeScript SDK system-messagepermission_modefields with the shared union。CLI 非交互层permission_mode出现在控制协议中例如 packages/cli/src/nonInteractive/types.ts 定义的permission_mode?: PermissionMode以及set_permission_mode控制请求同文件 L410 附近由 permissionController.ts 在运行时处理set_permission_mode。TypeScript SDKPermissionMode、DAEMON_APPROVAL_MODES等在 packages/sdk-typescript/src/index.ts 导出查询选项层面对其做 schema 校验见 queryOptionsSchema.ts。SDK 侧的校验器与 core 的对照由漂移检测测试保证 packages/sdk-typescript/test/unit/approval-mode-drift.test.ts 读取 core 的approval-modes.json断言core 的APPROVAL_MODES、SDK 的PERMISSION_MODES、acp-bridge 的KNOWN_APPROVAL_MODES三者与 fixture 完全一致DAEMON_APPROVAL_MODES与PERMISSION_MODES指向同一对象。expect([...APPROVAL_MODES]).toEqual(crossLanguageContract); expect([...PERMISSION_MODES]).toEqual(crossLanguageContract); expect([...KNOWN_APPROVAL_MODES]).toEqual(crossLanguageContract); expect(DAEMON_APPROVAL_MODES).toBe(PERMISSION_MODES);这段测试正是TypeScript SDK drift and query-option tests验证项的落地实现一旦任一层级漏加或错写取值测试立即失败。四、Python 侧原生别名 fixture 校验Python SDK 在 packages/sdk-python/src/qwen_code_sdk/types.py 用Literal类型别名声明公共类型PermissionMode: TypeAlias Literal[default, plan, auto-edit, auto, yolo]该别名被用于会话选项permission_mode字段types.py L112、L153在传输层映射为 CLI 的--approval-mode参数packages/sdk-python/src/qwen_code_sdk/transport.pyif options.permission_mode: args.extend([--approval-mode, options.permission_mode])运行时切换则由set_permission_mode控制请求完成query.pyasync def set_permission_mode(self, mode: str) - None: await self._send_control_request(set_permission_mode, {mode: mode})设计文档中Python validation tests指的就是对该Literal取值域与 JSON fixture 的一致性校验。五、Java 侧原生枚举 fixture 校验Java SDK 在 PermissionMode.java 中维护五个常量与 core 取值一一对应public enum PermissionMode { DEFAULT(default), PLAN(plan), AUTO_EDIT(auto-edit), AUTO(auto), YOLO(yolo); // getValue() / fromValue(String) }会话层通过Session.setPermissionMode(PermissionMode)下发控制请求底层将枚举值写入cliControlSetPermissionModeRequest.setMode(...)Session.java系统消息中的permissionMode字段同样使用该字符串取值SDKSystemMessage.java守护进程daemon侧另有 DaemonApprovalMode.java 维护相同取值集。设计文档中Java permission-mode tests即针对该枚举的取值与 fixture 的一致性、fromValue对未知取值的异常行为进行验证。六、五种模式的取值语义与使用场景以 core 契约为准五种approvalMode取值及其对文件编辑与 Shell 命令的权限差异如下表对应 Approval Mode 用户指南取值契约值文件编辑Shell 命令典型场景风险等级plan❌ 只读分析❌ 不执行代码探索、复杂变更规划、安全代码评审最低defaultAsk Permissions✅ 需人工批准✅ 需人工批准新/不熟悉代码库、关键系统、团队协作、教学低auto-edit✅ 自动批准❌ 需人工批准日常开发、重构与代码改进、安全自动化中auto✅ 分类器评估✅ 分类器评估长时自主会话、介于 Auto-Edit 与 YOLO 之间中yolo✅ 自动批准✅ 自动批准可信个人项目、CI/CD 自动化脚本、批处理最高几点值得注意的语义细节用户文档中曾被称为Default的模式已改名为Ask Permissions但底层配置值tools.approvalMode: default与/approval-mode default命令保持不变用于向后兼容——这正是契约值default需要稳定存在的原因之一循环切换顺序为plan → default → auto-edit → auto → yolo → plan → ...可通过ShiftTabWindows 上为Tab快速切换终端状态栏会显示当前模式auto模式由 LLM 分类器评估 Shell 命令、网络调用与工作区外编辑偏向不确定即拦截同时保留硬性规则permissions.deny优先于分类器、失败关闭classifier API 不可达时拦截连续两次不可达后回退人工批准与循环护栏连续三次策略拦截后回退人工批准等安全机制。七、配置与命令实操7.1 会话内切换/approval-mode plan # 进入计划模式只读 /approval-mode default # 回到 Ask Permissions默认 /approval-mode auto-edit # 自动批准文件编辑 /approval-mode auto # 分类器驱动的自动审批 /approval-mode yolo # 全自动谨慎使用也可用/plan快捷进出只读规划模式/plan exit会恢复进入前的模式或在无头模式下用qwen --prompt ...直接以当前默认模式运行。7.2 持久化配置在项目级.qwen/settings.json或用户级~/.qwen/settings.json中写入{ tools: { approvalMode: auto-edit // 可选 plan | default | auto-edit | auto | yolo } }auto模式还支持在permissions.autoMode下配置自然语言 hints、环境描述与可选开关{ tools: { approvalMode: auto }, permissions: { autoMode: { hints: { allow: [Running pytest, mypy, and ruff on this Python repo], deny: [Any network call to intranet.example.com] }, environment: [Open-source monorepo; commits are signed] // classifyAllShell: true, // 可选所有 Shell 命令都过分类器 // mcp: { forwardArguments: false } // 可选仅按名称发送 MCP 工具调用 } } }八、验证矩阵与落地检查设计文档的 Verification 一节给出了完整的验证清单映射到仓库中的具体位置如下验证项仓库落点Core approval-mode testspackages/core/src/config/config.test.ts 等 core 配置相关测试CLI ACP 与非交互类型检查 聚焦测试packages/cli/src/nonInteractive/control/controllers/permissionController.test.ts、packages/cli/src/acp-integration/acpAgent.test.tsTypeScript SDK drift 与 query-option 测试packages/sdk-typescript/test/unit/approval-mode-drift.test.ts、packages/sdk-typescript/test/unit/queryOptionsSchema.test.tsPython validation testspackages/sdk-python/src/qwen_code_sdk/types.py 的PermissionMode别名及对应校验测试Java permission-mode testsPermissionMode.java 及fromValue相关测试lint / typecheck / build仓库根目录 package.json 定义的脚本从源码结构看CI 侧还会在approval-modes.json变更时触发 Python 与 Java SDK 的工作流确保跨语言取值域始终与 core 对齐。九、小结Approval Mode 契约设计的核心价值在于单一事实来源plan/default/auto-edit/auto/yolo五个取值以 core 的枚举与数组为权威杜绝多包各自定义导致的漂移零运行时耦合已发布的 SDK 不依赖 core而是各自维护原生类型TS 字符串联合、PythonLiteral、Java 枚举把一致性检查收敛到测试期轻量不引入代码生成对一个五取值领域而言一份 approval-modes.json 加各语言的 drift/validation 测试是性价比最高的方案。无论你是终端用户通过/approval-mode与 settings.json 使用五种模式、SDK 集成方在 Python/Java/TypeScript 中传入permission_mode还是平台扩展开发者新增或校验取值理解这一契约的core 锚定 派生校验结构都能帮助你避免取值不一致的坑并快速定位校验失败的原因。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考