Skip to content

feat(manager): migrate Manager runtime from copaw to qwenpaw 2.0 - #1095

Open
LUOSENGWA wants to merge 9 commits into
agentscope-ai:codex/qwenpaw-2-startupfrom
LUOSENGWA:manager-qwenpaw-2.0
Open

feat(manager): migrate Manager runtime from copaw to qwenpaw 2.0#1095
LUOSENGWA wants to merge 9 commits into
agentscope-ai:codex/qwenpaw-2-startupfrom
LUOSENGWA:manager-qwenpaw-2.0

Conversation

@LUOSENGWA

@LUOSENGWA LUOSENGWA commented Jul 28, 2026

Copy link
Copy Markdown

Summary

Migrate the Manager container from copaw 1.0.2 to QwenPaw 2.0.1, following the same plugin-based architecture that PR #1077 established for Workers.

What changed

Manager runtime — separate venv for QwenPaw 2.0.1 to avoid agentscope version conflicts with copaw 1.0.2 (used only by bridge.py for config conversion). Manager tools (projectflow, taskflow, message, filesync) registered via a QwenPaw plugin instead of monkey-patching CoPawAgent._create_toolkit.

Matrix channel — physical overlay replaced with the agentteams-matrix-channel plugin (same as Workers). CMS observability packages installed in the QwenPaw venv (aligned with Worker).

ConfigurationQWENPAW_WORKING_DIR set alongside legacy COPAW_WORKING_DIR. Session-file privacy policy injected into prompts. approval_level=AUTO at top level of agent template. YOLO mode bridged to approval_level=OFF. Built-in QA Agent disabled. Dead PYTHONPATH entries removed.

Tool compatibilitymessage and taskflow tools read Matrix credentials directly from agent.json instead of importing copaw.config.config (not available in qwenpaw venv). Working directory resolution handles both QWENPAW_WORKING_DIR and qwenpaw.constant fallback.

CI — pgrep health check remains copaw(_worker\.run_copaw_app)? app (Manager process cmdline is unchanged).

Plugins at runtime — stored image-local and copied to working dir on startup, since the workspace is a host-mounted volume.

Stack

Based on codex/qwenpaw-2-startup (PR #1077). Will retarget to main after #1077 merges.

Follow-up

Controller/install/Makefile runtime identifier migration (copawqwenpaw for Manager) is tracked for a separate PR — it touches Go controller code that #1077 also modifies, and should follow the same pattern (add qwenpaw alongside copaw, then deprecate).

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@LUOSENGWA
LUOSENGWA force-pushed the manager-qwenpaw-2.0 branch from aa3c80e to 0676a69 Compare July 28, 2026 14:16
Manager now runs on QwenPaw 2.0.1 alongside PR agentscope-ai#1077's Worker migration.

Key changes:
- Separate venvs: /opt/copaw-venv (copaw 1.0.2 for bridge.py) and
  /opt/venv/qwenpaw (qwenpaw 2.0.1 for Manager runtime), avoiding
  agentscope version conflict (1.0.20 vs 2.0.4)
- Replace copaw hooks (monkey-patch CoPawAgent._create_toolkit) with
  agentteams-manager-tools QwenPaw plugin (api.register_tool()) for
  projectflow/taskflow/message/filesync
- Delete Matrix channel physical overlay; use QwenPaw plugin system
  (agentteams-matrix-channel) symlinked into WORKING_DIR/plugins/
- run_copaw_app.py simplified to runpy.run_module('qwenpaw')
- bridge.py invoked with /opt/copaw-venv/bin/python3 (pure stdlib,
  copaw 1.0.2 deps preserved)
- CI pgrep pattern accepts both 'copaw app' and 'qwenpaw app'
@LUOSENGWA
LUOSENGWA force-pushed the manager-qwenpaw-2.0 branch from 0676a69 to 9e293b2 Compare July 28, 2026 14:26
The message and taskflow tools deferred-imported copaw.config.config to
read Matrix credentials (homeserver, access_token, user_id).  In the
QwenPaw 2.0 venv copaw 1.0.2 is absent, so _matrix_config_for_agent()
raised ImportError — the message tool could not send any Matrix messages.

Fix: read workspaces/<id>/agent.json directly (framework-agnostic).
bridge.py already writes the Matrix channel config there.  Also add
QWENPAW_WORKING_DIR fallback to _resolve_copaw_working_dir() and
_current_actor().
copaw is the predecessor of qwenpaw (renamed package). In the qwenpaw
2.0 venv the copaw package does not exist, so the try/except in
_resolve_copaw_working_dir() should attempt qwenpaw first.
Systematic alignment with PR agentscope-ai#1077 Worker Dockerfile and QwenPaw 2.0
conventions:

Dockerfile:
- CMS observability: loongsuite-instrumentation-copaw → -qwenpaw
  + add loongsuite-otel-util-genai (matches Worker Dockerfile)

start-copaw-manager.sh:
- Add QWENPAW_SECRET_DIR, QWENPAW_RUNNING_IN_CONTAINER,
  QWENPAW_LOG_LEVEL env vars (matches Worker entrypoint)
- CMS bootstrap: replace python3 heredoc script with direct heredoc
  (matches Worker), add LOONGSUITE_PYTHON_SITE_BOOTSTRAP_LOG_SUCCESS
  export
- Inject session file privacy policy into AGENTS.md/SOUL.md (matches
  Worker _ensure_session_file_prompt_policy)
- Remove dead PYTHONPATH=/opt/agentteams/copaw/src (path never existed
  in the image; modules are in site-packages)

agent.manager.json:
- Move approval_level into running section (matches QwenPaw 2.0
  AgentProfileConfig schema, default AUTO)
QA Agent: Worker disables QwenPaw_QA_Agent_0.2 via API client.
Manager runs QwenPaw in-process with no API client, so set
enabled=false in config.json agents.profiles before startup.
QwenPaw's ensure_qa_agent_exists() skips agents already in profiles,
so our preset is preserved. start_all_configured_agents() skips
enabled=false agents.

approval_level: Move from running{} to top-level in agent.manager.json.
QwenPaw 2.0 AgentProfileConfig.approval_level is a top-level field,
not inside AgentsRunningConfig (which has extra='ignore' and would
silently drop it).
OpenClaw Manager sets tools.exec.ask=off for YOLO mode. QwenPaw 2.0's
equivalent is approval_level=OFF (short-circuits the governance
pipeline to ALLOW-all). start-manager-agent.sh promotes the yolo-mode
marker file to AGENTTEAMS_YOLO=1 before calling this script; we translate
that to agent.json approval_level=OFF here.
After PR agentscope-ai#1095 the Manager runs QwenPaw 2.0, not copaw. The script
name should reflect reality.

start-manager-agent.sh now accepts both 'copaw' (legacy runtime
identifier used by controller/installer/CI) and 'qwenpaw' (forward-
looking name). Both map to the same start-qwenpaw-manager.sh.

Controller, installer, CI, Makefile, and Docker image name still use
'copaw' as the runtime identifier — changing those is a separate PR
(the controller already defines RuntimeQwenPaw='qwenpaw' for Workers;
adding a qwenpaw Manager runtime requires new config fields, image
selection logic, and CI matrix entries).
…disable

Six issues found during deep audit with CI script and PR agentscope-ai#1077 cross-reference:

1. pgrep pattern: \|qwenpaw app was a literal pipe in ERE, breaking
   the original copaw pattern. Manager process cmdline is still
   'python3 -m copaw_worker.run_copaw_app app' (runpy.run_module does
   not change /proc/cmdline), so the original agentscope-ai#1077 pattern works.
   Reverted to 'copaw(_worker\.run_copaw_app)? app'.

2. Plugins invisible at runtime: Dockerfile copied plugins to
   /root/manager-workspace/.copaw/plugins/ (build-time), but the
   install script mounts a host volume at /root/manager-workspace,
   hiding build-time files. Now stores plugins in image-local
   /opt/agentteams/plugins/ and copies them at runtime in
   start-qwenpaw-manager.sh (mirrors Worker's _prepare_builtin_plugin).

3. CMS packages in wrong venv: pip install ran while PATH pointed to
   copaw-venv, but Manager runs from qwenpaw venv. Moved CMS install
   after qwenpaw venv creation with /opt/venv/qwenpaw/bin/pip.

4. QA Agent disable silently fails: jq wrote {"enabled": false} but
   AgentProfileRef requires id + workspace_dir. Pydantic validation
   stripped the incomplete profile, then ensure_qa_agent_exists()
   recreated it with enabled=true. Now writes a complete profile.

5. taskflow._current_actor() working dir resolution inconsistent with
   message.py: only checked env vars, no qwenpaw.constant fallback.
   Added _resolve_working_dir() mirroring message.py's logic.

6. plugin.py docstring stale: claimed taskflow/message still import
   copaw.config.config, but commit 974cdf6 already removed that.
   plugin.json type changed from 'general' to 'tool'.
…migration overwrite

The QA Agent disable jq only injected agents.profiles['QwenPaw_QA_Agent_0.2']
without the 'default' profile.  On first boot, QwenPaw's
migrate_legacy_workspace_to_default_agent() sees len(profiles)==1 and
'default' not in profiles → runs legacy migration → replaces config.agents
entirely → QA profile lost → ensure_qa_agent_exists() re-creates it with
enabled=True, defeating the disable.

Fix: inject both 'default' and QA profiles so len(profiles)>=2, which
causes the migration to be skipped (multi-agent config detected).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant