Skip to content

fix(sdk): support "auto" permission mode - #9003

Merged
yiliang114 merged 7 commits into
QwenLM:mainfrom
shenyankm:fix/sdk-python-permission-mode-auto
Aug 22, 2026
Merged

fix(sdk): support "auto" permission mode#9003
yiliang114 merged 7 commits into
QwenLM:mainfrom
shenyankm:fix/sdk-python-permission-mode-auto

Conversation

@shenyankm

@shenyankm shenyankm commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What this PR does

The Python and Java SDKs now accept auto as a permission mode in their startup options, aligning them with the CLI and the TypeScript SDK. In the Python SDK the accepted-values list, its validation error message, the public mode type, and the README are updated accordingly, and the validation tests now cover every accepted mode. In the Java SDK the PermissionMode enum gains the AUTO constant, its protocol type definition and README are updated, and the enum test covers the new value.

Why it's needed

The CLI supports an auto approval mode in which an LLM classifier approves tool calls, and the TypeScript SDK already exposes it end to end. The Python SDK's client-side validation rejected the value before it could reach the CLI, so Python users could not start a session in this mode — only switching modes at runtime worked, because that path skips local validation. The Java SDK's PermissionMode enum had no AUTO constant either. Reported in #9002, where fixing both SDKs in the same pass was requested so they stay consistent.

Reviewer Test Plan

How to verify

This is a non-user-visible change (types + validation). For the Python SDK, install the package with dev extras (pip install -e 'packages/sdk-python[dev]') and run the checks: python -m pytest -c packages/sdk-python/pyproject.toml packages/sdk-python/tests -q, plus ruff format --check and mypy on the package. All 165 tests pass locally, including new cases proving each documented mode is accepted and that an unknown mode is still rejected. Passing permission_mode="auto" no longer raises ValidationError and is forwarded to the CLI as --approval-mode auto. For the Java SDK, run mvn test in packages/sdk-java/qwencode: all 128 tests pass, including the extended PermissionModeTest asserting PermissionMode.AUTO.getValue() is "auto"; the transport layer forwards the mode's value verbatim as --approval-mode, so no transport change was needed.

Evidence (Before & After)

N/A (non-UI change). Before: ValidationError: Invalid permission_mode: 'auto'. Expected one of: default, plan, auto-edit, yolo. After: the option is accepted and passed through to the CLI in both SDKs.

Tested on

OS Status
🍏 macOS ⚠️ not tested
🪟 Windows ⚠️ not tested
🐧 Linux ✅ tested

Environment (optional)

Python 3.12 virtual environment (uv) running pytest, mypy, and ruff against the package; OpenJDK 21 (Temurin) with Maven for the Java SDK.

Risk & Scope

  • Main risks or trade-offs: none identified — the Python change only widens the accepted list to what the CLI already supports, and the Java change only adds an enum constant; behavior for existing values is unchanged.
  • Not verified / out of scope: runtime permission-mode switching paths are unchanged in both SDKs.
  • Breaking changes / migration notes: none.

Linked Issues

Closes #9002

中文说明

本次 PR 内容

Python 和 Java SDK 的启动选项现在都接受 auto 权限模式,与 CLI 和 TypeScript SDK 对齐。Python SDK 的合法值列表、校验报错信息、公开的模式类型以及 README 都相应更新,校验测试现在覆盖了所有合法模式。Java SDK 的 PermissionMode 枚举新增 AUTO 常量,其协议类型定义和 README 同步更新,枚举测试覆盖了新取值。

为什么需要

CLI 支持 auto 审批模式(由 LLM 分类器审批工具调用),TypeScript SDK 已全链路支持。而 Python SDK 的客户端校验在该值到达 CLI 之前就拒绝了它,导致 Python 用户无法以该模式启动会话——只有运行时切换模式可行,因为那条路径跳过了本地校验。Java SDK 的 PermissionMode 枚举同样缺少 AUTO 常量。详见 #9002,其中要求两个 SDK 一并修复以保持一致。

评审者测试计划

如何验证

这是非用户可见的改动(类型 + 校验)。Python SDK:安装开发依赖(pip install -e 'packages/sdk-python[dev]')后运行 python -m pytest -c packages/sdk-python/pyproject.toml packages/sdk-python/tests -q,外加对包执行 ruff format --checkmypy。本地 165 个测试全部通过,其中包括证明每个文档记载的模式都被接受、未知模式仍被拒绝的新用例。传入 permission_mode="auto" 不再抛出 ValidationError,并会作为 --approval-mode auto 转发给 CLI。Java SDK:在 packages/sdk-java/qwencode 下运行 mvn test,128 个测试全部通过,包括扩展后的 PermissionModeTest(断言 PermissionMode.AUTO.getValue()"auto");传输层原样透传模式取值作为 --approval-mode,无需改动。

前后对比

N/A(非 UI 改动)。改动前:ValidationError: Invalid permission_mode: 'auto'. Expected one of: default, plan, auto-edit, yolo.;改动后:两个 SDK 中该选项都被接受并透传给 CLI。

测试平台

仅在 Linux 上验证;macOS、Windows 未测试。

环境(可选)

Python 3.12 虚拟环境(uv),对包运行 pytest、mypy、ruff;Java SDK 使用 OpenJDK 21(Temurin)和 Maven。

风险与范围

  • 主要风险或权衡:未发现——Python 侧只是把合法值列表放宽到 CLI 早已支持的范围,Java 侧只是新增枚举常量,已有取值行为不变。
  • 未验证 / 超出范围:两个 SDK 的运行时切换模式路径均保持原样。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

Closes #9002

@github-actions github-actions Bot added the review/self-reported The linked issue was opened by the PR author (self-reported) label Aug 12, 2026
@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finished — CI landed green on 85dca28 and the deferred approval was posted. finalize run

Qwen Triage 已完成 —— 85dca28 的 CI 全绿,延迟审批已提交。查看 finalize 运行

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

  • Template: complete ✓
  • Problem: observed bug, not theory. Linked issue SDK Python rejects permission_mode="auto" although the CLI supports it #9002 carries the exact ValidationError message, and I confirmed it against the base code: _VALID_PERMISSION_MODES in validation.py lacks auto, while the CLI's --approval-mode flag accepts it and the TypeScript SDK already exposes it end to end.
  • Direction: aligned — this is a parity fix. The CLI supports auto (LLM-classifier approval), the TS SDK accepts it in both its options schema and protocol types, and Python users were blocked only by client-side validation, before the value could ever reach the CLI.
  • Size: no core paths touched; ~11 production lines (validation set + error message, PermissionMode alias, README) and 8 test lines. Well below any threshold.
  • Approach: minimal — one value added to the accepted set, its public type, the error message, and the README, plus a parametrized test covering every accepted mode. Nothing to cut. The runtime set_permission_mode path stays an unvalidated string, as the PR itself notes — pre-existing, out of scope, fine to leave.
  • Risk: no high-risk paths touched; no elevated risk signals.

Moving on to code review. 🔍

中文说明

感谢贡献!

  • 模板:完整 ✓
  • 问题:已观测到的 bug,不是理论问题。关联 issue SDK Python rejects permission_mode="auto" although the CLI supports it #9002 给出了确切的 ValidationError 报错;对照基线代码确认:validation.py_VALID_PERMISSION_MODES 缺少 auto,而 CLI 的 --approval-mode 接受该值,TypeScript SDK 也已全链路支持。
  • 方向:一致——这是一个 parity 修复。CLI 支持 auto(LLM 分类器审批),TS SDK 的 options schema 和 protocol 类型均已接受,Python 用户只是被客户端校验挡在了 CLI 之外。
  • 规模:未触及核心路径;约 11 行生产代码(校验集合 + 报错信息、PermissionMode 别名、README)加 8 行测试,远低于任何阈值。
  • 方案:最小化——合法值集合、公开类型、报错信息和 README 各加一个值,外加一个覆盖全部合法模式的参数化测试。没有可砍的部分。运行时 set_permission_mode 路径仍是未校验字符串,PR 已说明——属既有问题且超出范围,可以不动。
  • 风险:未触及高风险路径;无升级风险信号。

进入代码审查 🔍

Qwen Code · qwen3.8-max

Reviewed at 85dca285cbb76ac7c3e648a902a2894ba53f15f9 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Code review

The approach matches what I'd have done independently: add auto to the validation set, the error message, the public PermissionMode alias, and the README — nothing more. Details I checked:

  • transport.py forwards permission_mode verbatim as --approval-mode, and the CLI already accepts auto there, so widening the accepted set is the entire fix — no transport change needed.
  • The widened PermissionMode alias flows into protocol.py's CLIControlSetPermissionModeRequest automatically; there is no second call site to update.
  • The new parametrized test covers all five modes, so any future drift between the accepted set and the documented list fails loudly; the existing rejection test still pins unknown modes.
  • Mode ordering matches the TS SDK's enum. No blockers, no convention violations.

One non-blocking note: the QueryOptions table in docs/developers/sdk-python.md still lists only default, plan, auto-edit, yolo (its TS counterpart page includes auto). Worth a one-line update here or in a follow-up.

Test evidence (the PR's own CI — fork code is never run here)

The SDK Python job installs the package with dev extras and runs Ruff, Ruff format, Mypy, and the full pytest suite on packages/sdk-python/tests. All three Python legs are green on this commit, which is the load-bearing signal: if validation still rejected auto, test_accepts_valid_permission_modes[auto] would have failed. The Node unit suite is still running — unrelated to a Python-only diff, but reported as pending rather than assumed. The macOS/Windows unit legs and the integration leg are skipped. The author's "165 tests pass locally" is their own claim; the green CI jobs below are the evidence.

Final CI results for 85dca28 (auto-updated by the triage finalize job after CI completed):

Check Conclusion
Classify PR ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
SDK Python (3.10) ✅ success
SDK Python (3.11) ✅ success
SDK Python (3.12) ✅ success
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。

中文说明

代码审查

方案与我独立设想的一致:把 auto 加入校验集合、报错信息、公开的 PermissionMode 别名和 README——仅此而已。核对过的细节:

  • transport.pypermission_mode 原样转发为 --approval-mode,CLI 端已接受 auto,所以放宽合法值集合就是全部修复——transport 无需改动。
  • 放宽后的 PermissionMode 别名会自动传导到 protocol.pyCLIControlSetPermissionModeRequest,没有第二个需要更新的调用点。
  • 新的参数化测试覆盖全部五种模式,未来合法集合与文档列表若再漂移会直接失败;既有的拒绝测试仍钉住未知模式。
  • 模式顺序与 TS SDK 的 enum 一致。无阻塞项,无规范违规。

一条非阻塞提醒:docs/developers/sdk-python.mdQueryOptions 表格仍只列出 default, plan, auto-edit, yolo(TS 对应页面已包含 auto)。建议顺手一行更新,或留作后续 PR。

测试证据(来自 PR 自身的 CI——此处不运行 fork 代码)

SDK Python 任务安装带 dev 依赖的包并运行 Ruff、Ruff format、Mypy 以及 packages/sdk-python/tests 的完整 pytest。三个 Python 版本在本提交上全绿,这是关键证据:如果校验仍拒绝 autotest_accepts_valid_permission_modes[auto] 会失败。Node 单测套件仍在运行——与纯 Python 改动无关,但如实记为 pending 而非假定通过。macOS/Windows 单测腿与集成腿为 skipped。作者"本地 165 个测试通过"是其自述;下方绿色的 CI 任务才是证据。

Qwen Code · qwen3.8-max

Reviewed at 85dca285cbb76ac7c3e648a902a2894ba53f15f9 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean, minimal parity fix with the change pinned by green CI; the only nit is the stale mode table in docs/developers/sdk-python.md (flagged above, non-blocking).

Stepping back: the problem was real — reported with the exact error message and confirmed against the base code — and the fix is the smallest possible one: widen the accepted set, its public type, the error message, and the README. That matches my independent proposal exactly; nothing in the diff is unnecessary. The new parametrized test genuinely pins the behavior, and the SDK Python jobs (3.10/3.11/3.12) ran it green on this commit, which is the signal that matters for a Python-only change. The Node unit suite is still running, so I'm not approving this second — approval is deferred until CI lands green on 85dca285cbb76ac7c3e648a902a2894ba53f15f9, and the finalize step will post it automatically. If anything lands red, it flags the status instead.

In six months this reads as a one-line fix with a test covering it — nothing to curse the author for.

中文说明

置信度:4/5 —— 干净的最小 parity 修复,改动已被绿色的 CI 钉住;唯一的瑕疵是 docs/developers/sdk-python.md 里过时的模式表格(已在上方指出,非阻塞)。

退一步看:问题真实存在——报告里带了确切的报错信息,且已对照基线代码确认——修复也是最小可行方案:放宽合法值集合、公开类型、报错信息与 README。这与我独立设想的方案完全一致,diff 中没有多余内容。新的参数化测试确实钉住了行为,SDK Python 任务(3.10/3.11/3.12)在本提交上跑绿,对纯 Python 改动而言这就是关键信号。Node 单测套件仍在运行,所以此刻不批准——批准推迟到 CI 在 85dca285cbb76ac7c3e648a902a2894ba53f15f9 上全绿,finalize 步骤会自动补上批准;若有任务变红,它会改为标记状态。

六个月后回头看,这是一行修复加一个覆盖它的测试——没什么可抱怨的。

Qwen Code · qwen3.8-max

Reviewed at 85dca285cbb76ac7c3e648a902a2894ba53f15f9 · re-run with @qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. Suggestions are inline.

Not explored to full depth (tool budget reached): This PR adds auto permission mode support to the Python...: none — all checks I started were completed within budget..

中文说明

已审查。 建议见行内评论。

未探索到全部深度(达到工具调用预算):This PR adds auto permission mode support to the Python...:none — all checks I started were completed within budget.

— qwen3.8-max via Qwen Code /review (v0.21.10)

Comment thread packages/sdk-python/src/qwen_code_sdk/validation.py Outdated
Comment thread packages/sdk-python/src/qwen_code_sdk/validation.py Outdated

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship — CI landed green after the review. ✅

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Qwen precheck requires maintainer approval before automated triage/review.

Head SHA: 9e82d4f8811fa3de18015e380327a44228207e39

Reason:

  • prompt_injection:system_prompt

A maintainer with write access can inspect the PR and manually request a run with @qwen-code /triage or @qwen-code /review. A new push requires a fresh precheck.

@shenyankm shenyankm changed the title fix(sdk-python): support "auto" permission mode fix(sdk-python,sdk-java): support "auto" permission mode Aug 13, 2026
@shenyankm shenyankm changed the title fix(sdk-python,sdk-java): support "auto" permission mode fix(sdk): support "auto" permission mode Aug 13, 2026

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. The accepted set now derives from the public PermissionMode type via set(get_args(PermissionMode)), so it can no longer drift from the documented list, and the parametrized test pins every mode. CI is green on the latest head (Python Ruff/Mypy/pytest plus the Node unit suite). Thanks for the parity fix.

@chiga0 chiga0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tier: Standard — Targeted addition of "auto" permission mode across Python and Java SDKs, with a validation refactor.

What I verified

Area Check Result
Python types "auto" added to PermissionMode Literal
Python validation _VALID_PERMISSION_MODES = set(get_args(PermissionMode)) — no hand-maintained copy, cannot drift
Python transport transport.py:215-216args.extend(["--approval-mode", options.permission_mode]) forwards verbatim
Java enum AUTO("auto") in PermissionMode.java, .getValue() returns "auto"
Java transport TransportOptionsAdapter.java:76-78args.add(getPermissionMode().getValue())--approval-mode auto
Python tests Parametrized test covers all 5 modes; rejection test uses dynamic expected message with re.escape()
Java tests assertEquals("auto", PermissionMode.AUTO.getValue())
CI Python 3.10/3.11/3.12, Java 11/17/21, Desktop Shell, Real daemon E2E, web-shell E2E — all green

The get_args() refactor (addresses the CI bot's round-1 concern) is a clear improvement: the accepted set and the error message now derive directly from the public type alias, making the three-way drift the previous approach had structurally impossible.

No blockers found.

@yiliang114
yiliang114 added this pull request to the merge queue Aug 22, 2026
Merged via the queue into QwenLM:main with commit 867ded5 Aug 22, 2026
67 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.22.0.

@shenyankm
shenyankm deleted the fix/sdk-python-permission-mode-auto branch August 22, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/self-reported The linked issue was opened by the PR author (self-reported)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SDK Python rejects permission_mode="auto" although the CLI supports it

4 participants