qwen-code/integration-tests/concurrent-runner
Shaojin Wen 7cd49e063c
refactor(tools): rename TodoWrite tool display name to TodoList (#5319)
* refactor(tools): rename TodoWrite tool display name to TodoList

Rename the todo tool's user-facing display name from "TodoWrite" to "TodoList" across every surface that shows it, keeping the wire/schema name `todo_write` unchanged (model tool calls and existing configs are unaffected).

- core: ToolDisplayNames.TODO_WRITE -> 'TodoList'; add a ToolDisplayNamesMigration alias so coreTools/excludeTools configs referencing the old 'TodoWrite' display name keep resolving.
- cli i18n: rename the toolDisplayName.* locale keys (en/zh/zh-TW) so the localized TUI badge stays correct.
- web-shell / webui: map the todo tool to 'TodoList' in their display layers.
- sdk daemon normalizer: the ACP plan-update path minted toolName 'TodoWrite'; emit the wire name 'todo_write' instead, so the web-shell's existing wire-name-keyed display + i18n render 'TodoList' (zh 任务清单) for plan-routed todos.

desktop keeps 'TodoWrite' as an internal tool identifier (humanized to 'Updating Tasks' / 'Todo List Updated' for users, never shown raw).

* refactor(tools): complete TodoList rename in permission rules, importer, export, examples

Address review feedback on #5319 — three display surfaces still referenced the old name, plus a few non-user-facing spots.

- permissions/rule-parser.ts: add `TodoList` to TOOL_NAME_ALIASES so `allow: ["TodoList"]` resolves (legacy `TodoWrite` kept); rename CANONICAL_TO_RULE_DISPLAY + DISPLAY_NAME_TO_VERB to TodoList. Mirrors the existing Task->Agent handling. Without this a permission rule typed with the new UI label silently did nothing.
- webui selectors.ts: also recognize the `todo_write` wire name (the daemon plan path now emits it) so todo detection no longer relies solely on the toolKind fallback.
- cli export (collect.ts): exported tool-call title TodoWrite -> TodoList (kind discriminator unchanged).
- extension/claude-converter.ts: map Claude's TodoWrite -> qwen TodoList.
- example agent templates + webui stories + integration HTML export: update the displayed name.
- test: resolveToolName('TodoList') and legacy 'TodoWrite' both -> todo_write.

desktop keeps 'TodoWrite' as an internal id (humanized to 'Updating Tasks'/'Todo List Updated' for users); deferred as noted in the PR description.
2026-06-19 08:32:10 +08:00
..
examples feat: remove npm install/build and add keep_worktree option 2026-01-28 16:43:50 +08:00
config.example.json feat(runner): support auth_type for model configuration 2026-02-19 11:55:42 +08:00
export-html-from-chatrecord-jsonl.js refactor(tools): rename TodoWrite tool display name to TodoList (#5319) 2026-06-19 08:32:10 +08:00
README.md feat: add git branch support for worktree creation 2026-01-28 12:36:23 +08:00
render-chat-temp.html style: apply formatting and linting fixes across codebase 2026-03-06 21:58:22 +08:00
requirements.txt feat: add concurrent runner for batch CLI execution 2026-01-28 12:08:56 +08:00
runner.py feat(runner): support auth_type for model configuration 2026-02-19 11:55:42 +08:00

Qwen Concurrent Runner

A Python tool for executing multiple Qwen CLI tasks across different models concurrently using isolated git worktrees.

Overview

This tool enables you to:

  • Run multiple tasks against multiple models in parallel
  • Create isolated git worktrees for each execution
  • Track execution status in real-time
  • Capture and store all outputs (stdout, stderr, and OpenAI logs)
  • Resume or analyze results after completion

Installation

# Install dependencies
pip install -r requirements.txt

Usage

python runner.py config.json

Configuration

Create a JSON configuration file (see config.example.json):

{
  "concurrency": 3,
  "yolo": true,
  "source_repo": ".",
  "worktree_base": "~/.qwen/worktrees",
  "outputs_dir": "./outputs",
  "results_file": "./results.json",
  "tasks": [
    {
      "id": "code-review",
      "name": "Security Code Review",
      "prompts": ["Review the codebase for security vulnerabilities."]
    }
  ],
  "models": ["claude-3-5-sonnet-20241022", "qwen3-coder-plus"]
}

Configuration Options

Option Type Default Description
concurrency int 4 Maximum parallel executions
yolo bool true Auto-approve all actions
source_repo string . Source git repository path
branch string null Git branch to checkout (uses default if null)
worktree_base string ~/.qwen/worktrees Base directory for git worktrees
outputs_dir string ./outputs Directory for captured output
results_file string ./results.json JSON file for run tracking
tasks array [] List of task definitions
models array [] List of model identifiers

Task Definition

Each task has:

  • id: Unique identifier
  • name: Human-readable name
  • prompts: Array of prompt strings (joined with newlines)

Output Structure

Each run creates an isolated output directory:

outputs/
├── {run_id}/
│   ├── stdout.txt        # CLI stdout
│   ├── stderr.txt        # CLI stderr
│   └── logs/             # OpenAI API logs
│       └── openai-*.json

results.json

{
  "updated_at": "2026-01-28T10:30:00",
  "runs": [
    {
      "run_id": "abc123",
      "task_id": "code-review",
      "task_name": "Security Code Review",
      "model": "qwen3-coder-plus",
      "status": "succeeded",
      "worktree_path": "~/.qwen/worktrees/run-abc123",
      "output_dir": "outputs/abc123",
      "logs_dir": "outputs/abc123/logs",
      "started_at": "2026-01-28T10:00:00",
      "ended_at": "2026-01-28T10:05:00",
      "exit_code": 0,
      "stdout_file": "outputs/abc123/stdout.txt",
      "stderr_file": "outputs/abc123/stderr.txt"
    }
  ]
}

Execution Flow

  1. Generate Matrix: Create N×M run combinations (tasks × models)
  2. Create Worktree: Git worktree add from source repo
  3. Initialize: npm install && npm run build
  4. Execute: Run qwen CLI with captured output (logs go to run-specific folder)
  5. Cleanup: Remove git worktree (always executed)

Status Values

  • queued: Waiting to start
  • preparing: Creating git worktree
  • initializing: Running npm install + build
  • running: Executing qwen CLI
  • succeeded: Completed successfully
  • failed: Error occurred

Requirements

  • Python 3.10+
  • Git repository (for worktree operations)
  • Node.js and npm (for build step)
  • qwen CLI in PATH

Exit Codes

  • 0: All runs succeeded
  • 1: One or more runs failed
  • 130: Interrupted by user (Ctrl+C)