Agent Sandbox Registry

agent-sandbox

Decision: Unify the qwen-code session-turns parameter name and semantics

无中文版

.agents/notes/implemented/feature/2026-09-29-qwen-session-turns-param-unification.md

Decision: Unify the qwen-code session-turns parameter name and semantics

Status: implemented Proposed: 2026-09-29 Implemented: 2026-09-29

Problem

The value that caps how long a qwen-code agent run may go on was exposed under three different names with a wrong semantic label:

Layer Old name Actual behaviour
CLI abx deploy --max-tool-calls (default 100, help: "tool-call limit") forwarded to --max-session-turns
SDK Sandbox.deploy() / DeployModule.deploy_project() max_tool_calls (default 100, docstring: "number of tool calls") forwarded to --max-session-turns
qwen-code template (template.yaml arg, commands.py signature) max_turns (defaults 100 / 50 — inconsistent) forwarded to --max-session-turns

Upstream Qwen Code (official headless docs, verified 2026-09-29) defines --max-session-turns (user/model/tool turns, overrun exits with code 53) and --max-tool-calls (cumulative top-level tool calls, overrun exits with code 55) as two distinct budgets. Exposing our session-turns budget as --max-tool-calls therefore collides with a real, different upstream flag and misleads anyone who knows the upstream CLI.

Decision

  1. Single public name: max_session_turns everywhere.
  2. SDK keyword: max_session_turns (Sandbox.deploy, DeployModule.deploy_project, DeployModule._build_qwen_command)
  3. CLI option: --max-session-turns
  4. qwen-code template arg: max_session_turns (default unified to 100)
  5. Semantics documented as "user/model/tool session turns; qwen-code exits with code 53 when exceeded" (mapped to turn_limit_exceeded).
  6. Compatibility strategy: pre-release rename, no runtime aliases — consistent with ADR 2026-09-29 (remove-rename-notices) and ADR 2026-09-23 (overdesign cleanup): the project has no released users, so no deprecation shim is kept. Old names fail loudly:
  7. --max-tool-calls on the CLI → click usage error ("no such option"), locked by test_max_tool_calls_option_rejected.
  8. max_tool_calls= SDK kwarg → TypeError, locked by test_build_qwen_command_rejects_legacy_kwarg_name.
  9. --max-turns (the flag removed by the earlier task-180 fix; never a real upstream flag) must not reappear — locked by test_build_qwen_command_omits_obsolete_flag. No unknown parameter is ever silently ignored.
  10. Stable contract for the NL-create follow-up work (task 168): the host adapter run_qwen_code_headless() / _build_headless_command() in agent/qwen_code.py now accepts keyword-only max_session_turns: int | None = None. None (the default) adds no flag, so current abx create NL behaviour is byte-for-byte unchanged; future callers (clarification loop, diagnose, etc.) get the unified name on the same stable interface.

Alternatives considered

Dependencies

Test Strategy

Files changed

Acceptance criteria