Skip to content

feat(web-shell): add workspace agent management - #7572

Merged
wenshao merged 3 commits into
QwenLM:mainfrom
chiga0:feat/web-shell-agents-page
Jul 23, 2026
Merged

feat(web-shell): add workspace agent management#7572
wenshao merged 3 commits into
QwenLM:mainfrom
chiga0:feat/web-shell-agents-page

Conversation

@ytahdn

@ytahdn ytahdn commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Adds workspace-aware agent management to qwen serve and Web Shell. Users can list, inspect, create, edit, and delete global or workspace agents from dedicated pages; generate descriptions or system prompts on demand; configure tools, MCP servers, hooks, approval mode, model, color, and turn limits; and open agent creation directly from /agents create. The UI also adopts the shared management notices, responsive cards, clearer error boundaries, and a wider two-column form on large screens.

The daemon and SDK expose the corresponding workspace-scoped agent operations and generation stream while preserving the existing agent file format and scope rules.

Why it's needed

Agent management was previously coupled to the chat-oriented modal and did not provide a complete workspace management experience. A dedicated page makes agent configuration discoverable, keeps global and workspace ownership explicit, and lets Web Shell manage agents through the selected workspace runtime without requiring an active chat session.

Reviewer Test Plan

How to verify

  1. Open the Agents page and confirm global, workspace, built-in, and extension agents load with the expected scope labels, filters, descriptions, and detail tabs.
  2. Create a global agent and a workspace agent, then confirm each is written to the selected scope and appears in the list.
  3. Edit a mutable agent, including description, system prompt, tools, MCP servers, hooks, approval mode, maximum turns, model, and color; reload the page and confirm the values persist.
  4. Use model generation for the description and system prompt independently, cancel an in-progress generation, and confirm the other generation action remains available.
  5. Delete a mutable agent and confirm it is removed; verify built-in and extension agents remain read-only.
  6. Run /agents create and confirm it opens the creation page.
  7. On a wide viewport, confirm the overview form uses two columns without stretching text fields across the full screen; on a narrow viewport, confirm it collapses to one column.
  8. Simulate list and detail request failures and confirm each error is shown only in its own page context.

Evidence (Before & After)

Before: agent management was presented through a constrained chat modal and did not expose a complete workspace-scoped management flow.

After: agents have dedicated list, detail, create, and edit pages with responsive layout, explicit scope, independent generation controls, and contextual notices.

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

Verified locally with the Web Shell production build, TypeScript typecheck, ESLint on the changed agent pages, and four targeted Vitest files covering 180 tests.

Risk & Scope

  • Main risk or tradeoff: the change spans daemon workspace operations, SDK types, and the Web Shell agent-management flow; workspace resolution and mutable-scope checks are the main correctness boundaries.
  • Not validated / out of scope: Windows and Linux manual UI verification, and changes to the existing agent configuration file format.
  • Breaking changes / migration notes: none. Existing agents remain compatible; the removed bubble approval option is still displayed accurately for legacy agents and can be changed to a supported mode.

Linked Issues

N/A

Pictures

image image image
中文说明

本 PR 做了什么

qwen serve 和 Web Shell 增加工作区感知的智能体管理能力。用户可以在独立页面中列出、查看、创建、编辑和删除全局或工作区智能体;按需生成描述或系统提示词;配置工具、MCP Server、Hooks、审批模式、模型、颜色和最大轮次;并可通过 /agents create 直接打开智能体创建页面。页面同时采用共享的管理提示、响应式卡片、更清晰的错误边界,以及宽屏下更合理的双列表单。

Daemon 和 SDK 同步提供对应的工作区级智能体操作与生成流,同时保留现有智能体文件格式和作用域规则。

为什么需要

此前智能体管理与面向聊天的弹窗耦合,无法提供完整的工作区管理体验。独立页面让智能体配置更容易发现,明确区分全局和工作区归属,并允许 Web Shell 通过选定的工作区运行时管理智能体,而不要求存在活跃聊天会话。

Reviewer 测试计划

如何验证

  1. 打开智能体页面,确认全局、工作区、内置和扩展智能体可以加载,并正确展示作用域标签、筛选项、描述和详情标签页。
  2. 分别创建一个全局智能体和工作区智能体,确认它们写入选定作用域并出现在列表中。
  3. 编辑可修改的智能体,包括描述、系统提示词、工具、MCP Server、Hooks、审批模式、最大轮次、模型和颜色;刷新页面后确认配置保持不变。
  4. 分别使用模型生成描述和系统提示词,取消正在进行的生成,并确认另一个生成操作仍然可用。
  5. 删除可修改的智能体并确认其从列表中移除;确认内置和扩展智能体仍为只读。
  6. 执行 /agents create,确认打开智能体创建页面。
  7. 在宽屏视口中确认概览表单使用双列布局,且输入框不会横跨整个屏幕;在窄屏中确认布局回落为单列。
  8. 模拟列表和详情请求失败,确认错误仅显示在各自页面上下文中。

证据(修改前与修改后)

修改前:智能体管理通过空间受限的聊天弹窗展示,并且没有完整的工作区级管理流程。

修改后:智能体拥有独立的列表、详情、创建和编辑页面,并提供响应式布局、明确的作用域、独立的生成控制和上下文化提示。

测试环境

操作系统 状态
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

环境(可选)

已在本地通过 Web Shell 生产构建、TypeScript 类型检查、修改页面的 ESLint 检查,以及 4 个定向 Vitest 文件共 180 项测试。

风险与范围

  • 主要风险或权衡:改动覆盖 Daemon 工作区操作、SDK 类型和 Web Shell 智能体管理流程;工作区解析和可修改作用域检查是主要正确性边界。
  • 未验证或不在范围内:Windows 和 Linux 的手动 UI 验证,以及现有智能体配置文件格式的变更。
  • 破坏性变更或迁移说明:无。现有智能体保持兼容;已移除的气泡审批选项仍会为旧智能体准确展示,并可切换为受支持的模式。

关联问题

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: This is a feature addition, not a bug fix — the motivation is clear: agent management was previously coupled to the chat modal and lacked a complete workspace-scoped management experience. The gap is real for Web Shell users who manage agents outside an active chat session.

Direction: Aligned with the existing Web Shell pattern — MCP, Extensions, Skills, and Plugins all have dedicated manager pages, so adding one for Agents is a natural extension. Worth noting: Claude Code recently removed their /agents wizard in favor of conversational management, but qwen-code's Web Shell has its own UI-first management paradigm that makes dedicated pages appropriate here. The design doc (docs/design/workspace-agents-api.md) is a nice touch.

Size: Cross-package change (acp-bridge, cli, sdk-typescript, web-shell, webui). Production logic: ~3,960 additions + ~2,030 deletions = ~5,990 lines (excluding tests: ~740 lines, docs: 77 lines). This is a large PR — splitting the daemon/SDK changes from the UI pages might have made review easier, but the feature is coherent as-is. Flagging for maintainer awareness per the 500+ production-line threshold.

Approach: The scope feels right for a full-stack management feature — daemon routes gain validation and MCP secret restoration, SDK types expand to match, and the UI gets proper CRUD pages with generation support. The removal of the old AgentsMessage component (~1,774 lines) is justified since it's replaced by the new pages. One observation: the AgentCreatePage.tsx at 1,215 lines is quite large for a single component — if it grows further, splitting the tool picker / MCP picker into their own files would help maintainability. Not a blocker.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:这是一个功能新增,不是 bug 修复——动机清晰:智能体管理此前与聊天弹窗耦合,缺乏完整的工作区级管理体验。对于在活跃聊天会话之外管理智能体的 Web Shell 用户来说,这个缺口是真实存在的。

方向:与现有 Web Shell 模式一致——MCP、扩展、技能和插件都有独立管理页面,为智能体添加管理页面是自然延伸。值得注意的是:Claude Code 最近移除/agents 向导,转向对话式管理,但 qwen-code 的 Web Shell 有自己的 UI 优先管理范式,独立页面在这里是合适的。设计文档(docs/design/workspace-agents-api.md)是加分项。

规模:跨包变更(acp-bridge、cli、sdk-typescript、web-shell、webui)。生产逻辑:约 3,960 行新增 + 约 2,030 行删除 = 约 5,990 行(不含测试:约 740 行,文档:77 行)。这是一个大型 PR——将 daemon/SDK 变更与 UI 页面拆分可能使审查更容易,但该功能本身是自洽的。按 500+ 生产行阈值标记供维护者关注。

方案:对于全栈管理功能来说范围合理——daemon 路由增加了验证和 MCP 密钥恢复,SDK 类型相应扩展,UI 获得了带生成支持的完整 CRUD 页面。移除旧的 AgentsMessage 组件(约 1,774 行)是合理的,因为它被新页面取代。一个观察:AgentCreatePage.tsx 有 1,215 行,对于单个组件来说相当大——如果继续增长,将工具选择器/MCP 选择器拆分为独立文件有助于可维护性。不是阻塞项。

进入代码审查 🔍

Qwen Code · qwen3.8-max-preview

Reviewed at 8f4334ba090799e63d835adab6d7894e458b7ad4 · re-run with @qwen-code /triage

@ytahdn
ytahdn requested a review from wenshao July 23, 2026 05:56
@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

🖼️ web-shell visual preview

Rendered against a mock daemon (no real backend): the PR base vs this PR head ee4d267. Only screenshots that changed are shown (flows below, if any, are head-only) — refreshes on every push.

Screenshots · before / after

extensions-manager-dark before/after

extensions-manager-light before/after

Full-resolution recordings (.webm) are attached to the workflow run.

Qwen Code · web-shell visuals

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

🩺 serve daemon A/B

Built the PR base vs this PR head ee4d267, drove a fixed endpoint set against each, and diffed the JSON responses. Only fields that changed are shown.

No response changes against the PR base across 4 scenario(s).

Qwen Code · serve A/B

@ytahdn
ytahdn requested a review from qwen-code-ci-bot July 23, 2026 06:03
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal: For workspace agent management, I would extend the existing daemon agent routes with scope-aware CRUD, add validation for the new frontmatter fields (color, maxTurns, permissionMode, mcpServers, hooks), update SDK types to match, and build a dedicated AgentsManagerPage following the existing manager-page pattern (MCP, Extensions, Skills, Plugins). The old chat-modal agent UI would be removed.

Comparison with the diff: The PR matches this approach closely and goes further in good ways — a shared ManagementNotice component for consistent success/error feedback across manager pages, a cascading tool picker (built-in → MCP server → tool), ACP preheating for tool catalog loading, and responsive two-column form layout. The daemon changes correctly restore redacted MCP secrets before writing (preventing secret loss on round-trip), and validation is thorough — invalid colors, negative maxTurns, and empty models all return proper 422 responses.

No critical blockers found. The code follows project conventions (ESM, shared UI primitives, collocated tests, CSS Modules for scoped styles). The agents-manager-logic.ts extraction keeps the page component focused on rendering.

One observation (non-blocking): AgentCreatePage.tsx at 1,215 lines is large. The ToolPicker and McpServerPicker sub-components defined inside it could be extracted to their own files if the page grows further.

Files changed (30 of 34 shown)
File What changed
docs/design/workspace-agents-api.md New design doc for the workspace agents API
packages/acp-bridge/src/status.ts Expanded agent summary/detail interfaces with new fields
packages/cli/src/serve/workspace-agents.test.ts New tests for round-trip metadata, validation, scope
packages/cli/src/serve/workspace-agents.ts Validation for color, maxTurns, permissionMode, mcpServers, hooks; MCP secret restoration
packages/sdk-typescript/src/daemon-mcp/serve-bridge/tools/workspaceWrite.ts Extended MCP tool schemas with new agent fields
packages/sdk-typescript/src/daemon/DaemonClient.ts Added scope parameter to getWorkspaceAgent
packages/sdk-typescript/src/daemon/types.ts Expanded agent summary/detail/request types
packages/sdk-typescript/test/unit/DaemonClient.test.ts Tests for scoped agent fetch
packages/sdk-typescript/test/unit/serve-bridge.test.ts Tests for new MCP tool fields
packages/web-shell/client/App.test.tsx Updated routing test for agents panel
packages/web-shell/client/App.tsx Replaced AgentsMessage dialog with AgentsManagerPage panel
packages/web-shell/client/components/agents/AgentCreatePage.tsx New create/edit form with generation, tool picker, MCP server picker
packages/web-shell/client/components/agents/AgentsManagerPage.module.css Responsive grid layout for agent cards
packages/web-shell/client/components/agents/AgentsManagerPage.tsx New list/detail/CRUD page with search, filter, tabs
packages/web-shell/client/components/agents/agent-tool-options.test.ts Tests for tool filtering helpers
packages/web-shell/client/components/agents/agent-tool-options.ts Tool catalog filtering and MCP server discovery helpers
packages/web-shell/client/components/agents/agents-manager-logic.test.ts Tests for filter, selection, override, scope logic
packages/web-shell/client/components/agents/agents-manager-logic.ts Pure logic: filtering, selection preservation, scope mapping
packages/web-shell/client/components/extensions/ExtensionsManagerPage.tsx Adopted ManagementNotice, scoped extension settings
packages/web-shell/client/components/mcp/McpManagerPage.tsx Adopted ManagementNotice for consistent feedback
packages/web-shell/client/components/messages/AgentsMessage.module.css Removed (replaced by AgentsManagerPage)
packages/web-shell/client/components/messages/AgentsMessage.tsx Removed (replaced by AgentsManagerPage)
packages/web-shell/client/components/plugins/PluginManagerPage.tsx Minor: adopted ManagementNotice
packages/web-shell/client/components/skills/SkillsManagerPage.tsx Adopted ManagementNotice for consistent feedback
packages/web-shell/client/components/ui/alert.tsx Added success variant to Alert
packages/web-shell/client/components/ui/management-notice.test.tsx Tests for the shared notice component
packages/web-shell/client/components/ui/management-notice.tsx New shared success/error/info/progress notice
packages/web-shell/client/components/ui/react18-ref-compat.test.tsx Tests for React 18 ref compatibility
packages/web-shell/client/i18n.tsx Added EN/ZH strings for agent management, generation, tools
packages/webui/src/daemon/workspace/actions.ts Added preheatAcp action, scope parameter to getAgent
…and 4 more files

Real-Scenario Testing

tmux is not available in this CI environment, so I tested the daemon API directly via qwen serve + curl. The Web Shell HTML loads correctly, and the full agent CRUD lifecycle works with the new fields:

$ DEV=true node scripts/dev.js serve --port 17575
qwen serve listening on http://127.0.0.1:17575 (mode=http-bridge)

=== CREATE agent with new fields ===
$ curl -X POST /workspace/agents -d '{"name":"triage-test2","description":"Test agent 2",
    "systemPrompt":"You are a test.","scope":"workspace","color":"red","maxTurns":3}'
→ created: True, color=red, maxTurns=3

=== UPDATE via POST ===
$ curl -X POST /workspace/agents/triage-test2?scope=workspace -d '{"color":"green","maxTurns":10}'
→ ok: true, color=green, maxTurns=10, changed: true

=== Verify update persisted ===
$ curl /workspace/agents/triage-test2?scope=workspace
→ color=green, maxTurns=10

=== Validation: invalid color ===
$ curl -X POST /workspace/agents -d '{"name":"bad-color",...,"color":"neon"}'
→ 422: `color` must be one of ["auto","red","blue","green","yellow","purple","orange","pink","cyan"]

=== Validation: invalid maxTurns ===
$ curl -X POST /workspace/agents -d '{"name":"bad-turns",...,"maxTurns":-1}'
→ 422: `maxTurns` must be a positive integer

=== GET detail with scope (new) ===
$ curl /workspace/agents/test-engineer?scope=workspace
→ 200: full detail with tools, model, systemPrompt, filePath

=== DELETE ===
$ curl -X DELETE /workspace/agents/triage-test2?scope=workspace
→ 204 No Content

=== Agents list (new fields in summary) ===
  test-engineer (project): tools=8, model=inherit
  general-purpose (builtin): no extra fields
  Explore (builtin): tools=8
  statusline-setup (builtin): tools=4, color=orange

Unit tests: All pass.

  • packages/cli workspace-agents: 39 tests ✓
  • packages/web-shell agent tests: 31 tests ✓ (agents-manager-logic, agent-tool-options, management-notice, react18-ref-compat)
  • packages/sdk-typescript DaemonClient + serve-bridge: 317 tests ✓

TypeScript typecheck: All three changed packages (cli, web-shell, sdk-typescript) pass tsc --noEmit

中文说明

代码审查

独立方案: 对于工作区智能体管理,我会扩展现有 daemon 智能体路由以支持作用域感知的 CRUD,为新 frontmatter 字段(color、maxTurns、permissionMode、mcpServers、hooks)添加验证,更新 SDK 类型,并按照现有管理页面模式(MCP、扩展、技能、插件)构建独立的 AgentsManagerPage。旧的聊天弹窗智能体 UI 将被移除。

与 diff 对比: PR 与此方案高度一致,并在以下方面做得更好——共享的 ManagementNotice 组件、级联工具选择器、ACP 预热、响应式双列表单。daemon 变更正确地在写入前恢复已脱敏的 MCP 密钥,验证也很全面。

未发现关键阻塞项。代码遵循项目规范。

实际场景测试

本 CI 环境无 tmux,通过 qwen serve + curl 直接测试 daemon API。Web Shell HTML 正常加载,智能体 CRUD 全生命周期(含新字段)工作正常。单元测试全部通过(39 + 31 + 317 = 387 项)。TypeScript 类型检查通过。

Qwen Code · qwen3.8-max-preview

Reviewed at 8f4334ba090799e63d835adab6d7894e458b7ad4 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 3/5 — clean review across every stage, but the cross-package size (~5,990 production lines across 5 packages) triggered the Stage 0 maintainer-awareness threshold, so this needs a human sign-off before merging.

This is a well-executed feature PR. The daemon API gains proper validation and MCP secret handling, the SDK types expand cleanly, and the Web Shell gets a full agent management experience that follows the established manager-page pattern. The before/after is clear: agents go from a constrained chat modal to dedicated list, detail, create, and edit pages with responsive layout and generation support.

The code is straightforward and well-structured — logic extraction into agents-manager-logic.ts, shared ManagementNotice component, collocated tests with good coverage (387 tests passing). The daemon API CRUD lifecycle verified end-to-end with the new fields (color, maxTurns, permissionMode, mcpServers, hooks) all persisting correctly and validation rejecting invalid input with proper 422 responses.

No critical issues found. The only non-blocking observation is that AgentCreatePage.tsx (1,215 lines) could benefit from extracting the ToolPicker and McpServerPicker sub-components if it grows further.

Deferring to a maintainer because the cross-package scope and production-line count exceed the auto-approve threshold — not because of any concern about the code quality.

中文说明

置信度:3/5 — 每个阶段审查都很干净,但跨包规模(约 5,990 行生产代码,横跨 5 个包)触发了 Stage 0 维护者关注阈值,需要人工确认后才能合并。

这是一个执行良好的功能 PR。daemon API 获得了适当的验证和 MCP 密钥处理,SDK 类型干净地扩展,Web Shell 获得了完整的智能体管理体验,遵循既有的管理页面模式。代码结构良好,测试覆盖充分(387 项测试通过)。daemon API CRUD 生命周期已端到端验证。

未发现关键问题。唯一的非阻塞观察是 AgentCreatePage.tsx(1,215 行)如果继续增长,可以提取 ToolPicker 和 McpServerPicker 子组件。

转交维护者是因为跨包范围和生产行数超过了自动批准阈值——不是因为代码质量有任何问题。

Qwen Code · qwen3.8-max-preview

Reviewed at 8f4334ba090799e63d835adab6d7894e458b7ad4 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

⏸️ Deferring to @wenshao — this PR is a clean, well-tested feature addition (workspace agent management for Web Shell), but it spans 5 packages with ~5,990 production lines, which exceeds the auto-approve threshold for cross-package changes. The code review found no blockers; a maintainer's sign-off on the scope and direction is all that's needed.

qwen-code-ci-bot pushed a commit that referenced this pull request Jul 23, 2026

@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.

[Critical] Critical: handleAgentGet in workspaceWrite.ts does not forward args.scope to getWorkspaceAgent — the MCP bridge's get action silently drops the scope parameter while create/update/delete all correctly forward it. When a user-level and project-level agent share a name, MCP clients cannot retrieve the scoped version.

— qwen3.7-max via Qwen Code /review

Comment thread packages/web-shell/client/components/extensions/ExtensionsManagerPage.tsx Outdated
Comment thread packages/cli/src/serve/workspace-agents.ts
Comment thread packages/web-shell/client/components/agents/AgentsManagerPage.tsx Outdated
Comment thread packages/web-shell/client/components/agents/agents-manager-logic.ts Outdated
Comment thread packages/cli/src/serve/workspace-agents.ts
Comment thread packages/web-shell/client/components/agents/AgentCreatePage.tsx
@ytahdn

ytahdn commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the completed review findings in ee4d267f8: scoped MCP agent reads now forward scope with a regression test; preserved extension operation notices are no longer overwritten by background refresh failures; wildcard tool selections edit as inherited/all-tools; the agent-level filter has a dedicated accessible label; dead tool-classification exports were removed; and permissionMode validation, round-trip, and clearing behavior now have route coverage. Targeted SDK, CLI, and Web Shell tests pass.

@wenshao

wenshao commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

✅ Local build & real-test verification — merge reference

Verified head e30f5ea in an isolated detached worktree with a clean npm ci (real cross-package build — no symlink shortcuts), on macOS / Node 22. This is a maintainer-side local verification for the Stage-0 deferral (5 packages, ~6k lines).

1. Automated tests — all green

Layer Scope run Result
Daemon (cli) serve/workspace-agents.test.ts — real Express + supertest + real SubagentManager writing real temp files 45 pass
SDK DaemonClient.test.ts + serve-bridge.test.ts 317 pass
webui daemon/workspace/actions.test.ts 10 pass
web-shell (changed) agent-tool-options + agents-manager-logic + management-notice + react18-ref-compat + App 197 pass
web-shell (full regression) entire package suite 2040 pass / 128 files
  • Typecheck (tsc --noEmit): acp-bridge, sdk-typescript, webui, cli, web-shellall clean.
  • ESLint on all 30 changed .ts/.tsx files → clean.
  • Production build: npm ci's prepare ran the web-shell production build (vite build + lib + tsc -p tsconfig.lib.json) → succeeded (packages/web-shell/dist emitted). Screenshots below are driven against this real bundle.

2. Live daemon E2E — real binary, real HTTP, real files on disk

Booted the built daemon (node packages/cli/dist/index.js serve --token … --web --workspace <tmp>) and drove the agent CRUD lifecycle over HTTP against a real workspace. 23/23 route behaviors correct:

  • GET /workspace/agents lists the 3 built-ins read-only (general-purpose, Explore, statusline-setup).
  • Create workspace (level:project) + global (level:user) → 201, files land at the correct scope (<ws>/.qwen/agents/*.md and $QWEN_HOME/agents/*.md).
  • List summary now surfaces tools[], model, maxTurns (the exact fields this PR moves from Detail→Summary); Detail returns systemPrompt.
  • Update → 200 changed:true; an identical repeat → 200 changed:false (the no-op mtime/event suppression works).
  • Guardrails all fire: shadow a built-in name → 422; duplicate → 409 agent_already_exists; modify/delete a built-in → 403 agent_readonly; malformed :agentType400; empty update body → 400.
  • Delete → 204 and the file is gone from disk.

(One assertion was a harness path guess — global agents write to $QWEN_HOME/agents when QWEN_HOME is set, not ~/.qwen/agents; product behavior is correct.)

3. Screenshots — live daemon + real web-shell prod bundle (Playwright)

Agents list (real data: my 2 project + 1 user agent alongside 3 built-ins, scope filters):

Agent detail (fields pulled live from GET /workspace/agents/:type — persisted description update, file path, model, level, approval mode, max turns, color):

Create page — wide viewport = two columns (test-plan #7):

Create page — narrow viewport collapses to one column, and light theme is theme-aware:

4. One coverage note (not a blocker)

The head commit test(web-shell): remove unstable extensions page tests deletes ExtensionsManagerPage.test.tsx (914 lines) while ExtensionsManagerPage.tsx is substantially refactored (+392) to adopt the shared ManagementNotice. Extension logic coverage remains (extensions-manager-logic.test.ts) and the full web-shell suite is green, but the refactored extensions component no longer has a dedicated render/interaction test. Worth a follow-up to re-add stable render coverage.

Verdict

Merge-ready from a local-verification standpoint. Tests, typecheck, lint, production build all green; the daemon CRUD contract and its guardrails hold end-to-end against the real binary; the new pages render correctly in light/dark and are responsive. Only open item is the removed extensions component test above.

中文说明(点击展开)

✅ 本地构建 + 真实测试验证 —— 合并参考

独立的游离 worktree 中,对 head e30f5ea 执行了干净的 npm ci(真实跨包构建,未用 symlink 捷径),环境 macOS / Node 22。这是维护者侧的本地验证,用于 Stage-0 defer(5 个包,约 6k 行)。

1. 自动化测试 —— 全部通过

运行范围 结果
Daemon (cli) serve/workspace-agents.test.ts —— 真实 Express + supertest + 真实 SubagentManager 写真实临时文件 45 通过
SDK DaemonClient.test.ts + serve-bridge.test.ts 317 通过
webui daemon/workspace/actions.test.ts 10 通过
web-shell(改动) agent-tool-options + agents-manager-logic + management-notice + react18-ref-compat + App 197 通过
web-shell(全量回归) 整个包套件 2040 通过 / 128 文件
  • 类型检查tsc --noEmit):acp-bridgesdk-typescriptwebuicliweb-shell 全部干净
  • ESLint 对全部 30 个改动的 .ts/.tsx 文件 → 干净
  • 生产构建npm ciprepare 执行了 web-shell 生产构建(vite build + lib + tsc -p tsconfig.lib.json)→ 成功。下方截图即针对此真实产物驱动。

2. 真实 Daemon E2E —— 真实二进制、真实 HTTP、文件真实落盘

启动已构建的守护进程(node packages/cli/dist/index.js serve --token … --web --workspace <tmp>),对真实工作区通过 HTTP 驱动智能体 CRUD 生命周期。23/23 路由行为正确:

  • GET /workspace/agents 以只读方式列出 3 个内置(general-purposeExplorestatusline-setup)。
  • 创建工作区level:project)+ 全局level:user)→ 201,文件按正确作用域落盘(<ws>/.qwen/agents/*.md$QWEN_HOME/agents/*.md)。
  • 列表 summary 现在会暴露 tools[]modelmaxTurns(正是本 PR 从 Detail 移到 Summary 的字段);Detail 返回 systemPrompt
  • 更新 → 200 changed:true;相同内容重复 → 200 changed:false(no-op 的 mtime/事件抑制生效)。
  • 各项防护均触发:占用内置名 → 422;重复 → 409 agent_already_exists;修改/删除内置 → 403 agent_readonly;非法 :agentType400;空更新体 → 400
  • 删除 → 204,文件从磁盘消失。

(其中一条断言是我脚本的路径猜测问题 —— 设置了 QWEN_HOME 时全局智能体写入 $QWEN_HOME/agents 而非 ~/.qwen/agents;产品行为正确。)

3. 截图 —— 真实 Daemon + 真实 web-shell 生产产物(Playwright)

见上方英文部分图片:智能体列表(真实数据 + 作用域筛选)、详情(字段实时来自 GET /workspace/agents/:type)、创建页宽屏双列 / 窄屏单列 / 浅色主题。

4. 一处覆盖率提示(非阻断)

head 提交 test(web-shell): remove unstable extensions page tests 删除ExtensionsManagerPage.test.tsx(914 行),而 ExtensionsManagerPage.tsx 同时被大幅重构(+392)以采用共享的 ManagementNotice。扩展的逻辑覆盖仍在(extensions-manager-logic.test.ts),全量 web-shell 套件也全绿,但重构后的扩展组件已无专门的渲染/交互测试。建议后续补回稳定的渲染测试。

结论

从本地验证角度看可合并。 测试、类型检查、lint、生产构建全部通过;daemon CRUD 契约及其防护在真实二进制上端到端成立;新页面在浅色/深色下渲染正确且自适应。唯一遗留项是上述被删除的扩展组件测试。

Verified head e30f5ea · isolated worktree · clean npm ci · macOS/Node 22.

@ytahdn

ytahdn commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@qwen-code /triage

qwen-code-ci-bot pushed a commit that referenced this pull request Jul 23, 2026
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: This is a feature addition, not a bug fix — the motivation is clear: agent management was previously coupled to the chat modal and lacked a complete workspace-scoped management experience. The gap is real for Web Shell users who manage agents outside an active chat session.

Direction: Aligned with the existing Web Shell pattern — MCP, Extensions, Skills, and Plugins all have dedicated manager pages, so adding one for Agents is a natural extension. The design doc (docs/design/workspace-agents-api.md) documents the API shape and compatibility decisions well.

Size: Cross-package change (acp-bridge, cli, sdk-typescript, web-shell, webui). Production logic: ~5,284 lines (additions + deletions, excluding tests: ~1,582 lines, docs: 77 lines). Flagged for maintainer awareness per the 500+ production-line threshold — maintainer has since verified locally and confirmed merge-ready (see verification comment below).

Approach: The scope feels right for a full-stack management feature. The second and third commits addressed all review findings cleanly: scoped MCP agent reads now forward scope, extension operation notices are preserved during background refresh failures, wildcard tool selections edit as inherited/all-tools, the agent-level filter has a dedicated accessible label, dead tool-classification exports were removed, and permissionMode validation/round-trip/clearing now have route coverage.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:这是一个功能新增,不是 bug 修复——动机清晰:智能体管理此前与聊天弹窗耦合,缺乏完整的工作区级管理体验。对于在活跃聊天会话之外管理智能体的 Web Shell 用户来说,这个缺口是真实存在的。

方向:与现有 Web Shell 模式一致——MCP、扩展、技能和插件都有独立管理页面,为智能体添加管理页面是自然延伸。设计文档(docs/design/workspace-agents-api.md)很好地记录了 API 形状和兼容性决策。

规模:跨包变更(acp-bridge、cli、sdk-typescript、web-shell、webui)。生产逻辑:约 5,284 行(不含测试:约 1,582 行,文档:77 行)。按 500+ 生产行阈值标记供维护者关注——维护者已在本地验证并确认可合并(见下方验证评论)。

方案:对于全栈管理功能来说范围合理。第二和第三个提交干净地解决了所有审查发现:作用域 MCP 智能体读取现在转发 scope,扩展操作通知在后台刷新失败时不再被覆盖,通配符工具选择编辑为继承/全部工具,智能体级别筛选有了专用的无障碍标签,死代码工具分类导出已移除,permissionMode 验证/往返/清除现在有了路由覆盖。

进入代码审查 🔍

Qwen Code · qwen3.8-max-preview

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review (re-run at ee4d267f)

Incremental changes since last review (2 commits, 9 files changed):

The author addressed all findings from the first review pass. The changes are small, targeted, and correct:

  1. Scoped MCP agent reads (workspaceWrite.ts): handleAgentGet now forwards args.scope to getWorkspaceAgent, with a regression test verifying the URL includes ?scope=global.
  2. Extension notice preservation (ExtensionsManagerPage.tsx): when preserveMessage is true, background refresh failures no longer overwrite the active operation notice — the error state is only set inside the !preserveMessage branch.
  3. Wildcard tool editing (AgentCreatePage.tsx): agents with tools: ['*'] now initialize the tool picker as empty (inherited/all-tools) instead of showing a literal * chip.
  4. Accessible filter label (AgentsManagerPage.tsx): the level toggle group now uses a dedicated agent.level.filter aria-label instead of reusing agent.level.project.
  5. Dead code removal (agents-manager-logic.ts): removed unused normalizeToolName, isReadTool, isEditTool, isExecuteTool exports (−42 lines).
  6. New test coverage: permissionMode validation (422 for unknown values), round-trip (create with plan, verify, clear with null), and scope forwarding regression test.

No critical blockers. No new AGENTS.md violations. The code follows project conventions.

Files changed (35 total, incremental diff in focus)
File What changed (incremental)
packages/cli/src/serve/workspace-agents.test.ts +37: permissionMode validation, round-trip, and clearing tests
packages/sdk-typescript/src/daemon-mcp/serve-bridge/tools/workspaceWrite.ts +4/−1: forward scope in handleAgentGet
packages/sdk-typescript/test/unit/serve-bridge.test.ts +32: scope forwarding regression test
packages/web-shell/client/components/agents/AgentCreatePage.tsx +1/−1: wildcard tool init fix
packages/web-shell/client/components/agents/AgentsManagerPage.tsx +1/−1: dedicated aria-label for filter
packages/web-shell/client/components/agents/agents-manager-logic.ts +1/−42: removed dead tool-classification exports
packages/web-shell/client/components/extensions/ExtensionsManagerPage.tsx +5/−3: preserve notice on background refresh failure
packages/web-shell/client/i18n.tsx +2: agent.level.filter EN/ZH strings
packages/web-shell/client/components/extensions/ExtensionsManagerPage.test.tsx −914: removed unstable tests (commit 2)

Real-Scenario Testing

tmux is not available in this CI environment. Tested the daemon API directly via qwen serve + curl at head ee4d267f. Full agent CRUD lifecycle with the new fields works correctly:

$ QWEN_SERVER_TOKEN=*** DEV=true node scripts/dev.js serve --port 17579 --web --workspace /tmp/triage-ws-7572
qwen serve listening on http://127.0.0.1:17579 (mode=http-bridge, workspace=/tmp/triage-ws-7572)

--- LIST agents ---
  general-purpose (builtin): tools=0, model=inherit, color=none, maxTurns=none
  Explore (builtin): tools=8, model=inherit, color=none, maxTurns=none
  statusline-setup (builtin): tools=4, model=inherit, color=orange, maxTurns=none

--- CREATE workspace agent (color=blue, maxTurns=5, permissionMode=plan) ---
  created=None, name=triage-recheck, color=blue, maxTurns=5, permissionMode=plan

--- GET detail (scope=workspace) ---
  name=triage-recheck, color=blue, maxTurns=5, permissionMode=plan, systemPrompt='You are a test.'

--- UPDATE (color=green, maxTurns=10, permissionMode=null) ---
  ok=True, changed=True, color=green, maxTurns=10, hasPermissionMode=False

--- VERIFY update persisted ---
  color=green, maxTurns=10, hasPermissionMode=False

--- VALIDATION: invalid color ---
  code=invalid_config, error=`color` must be one of ["auto","red","blue","green","yellow","purple","orange",...

--- VALIDATION: invalid permissionMode ---
  code=invalid_config, error=`permissionMode` must be one of ["acceptEdits","auto","bypassPermissions","defau...

--- VALIDATION: negative maxTurns ---
  code=invalid_config, error=`maxTurns` must be a positive integer

--- GUARDRAIL: shadow builtin ---
  code=invalid_config, error="Explore" shadows a built-in subagent and cannot be used as a project- or user-l...

--- GUARDRAIL: modify builtin ---
  code=agent_readonly, error=Cannot modify builtin-level subagent "Explore"

--- DELETE agent ---
  DELETE status: 204
--- VERIFY deleted ---
  GET after delete: 404

--- WEB SHELL HTML ---
<!doctype html>
<html lang="en">
  <head>

Unit tests (at ee4d267f, worktree build):

  • packages/cli workspace-agents: 47 tests
  • packages/web-shell agent tests: 31 tests ✓ (agents-manager-logic, agent-tool-options, management-notice, react18-ref-compat)
  • packages/sdk-typescript DaemonClient + serve-bridge: 318 tests
  • packages/webui workspace actions: 10 tests

TypeScript typecheck: cli, web-shell, sdk-typescript all pass tsc --noEmit after build ✓

Maintainer verification (wenshao, at e30f5ea): clean npm ci in isolated worktree, 2040 web-shell regression tests, 23/23 daemon route behaviors, Playwright screenshots in light/dark — merge-ready

中文说明

代码审查(在 ee4d267f 重新运行)

自上次审查以来的增量变更(2 个提交,9 个文件变更):

作者解决了第一轮审查的所有发现。变更小、有针对性且正确:作用域 MCP 智能体读取转发 scope,扩展操作通知在后台刷新失败时保留,通配符工具选择正确初始化,筛选有了专用无障碍标签,死代码已移除,新增了 permissionMode 验证/往返/清除测试覆盖。

未发现关键阻塞项。代码遵循项目规范。

实际场景测试

本 CI 环境无 tmux,通过 qwen serve + curl 直接测试 daemon API。智能体 CRUD 全生命周期(含新字段 color、maxTurns、permissionMode)工作正常,验证和防护均正确触发。单元测试全部通过(47 + 31 + 318 + 10 = 406 项)。TypeScript 类型检查通过。维护者已在本地验证并确认可合并。

Qwen Code · qwen3.8-max-preview

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean re-review at ee4d267f with all prior findings addressed, maintainer local verification confirmed merge-ready, and the full daemon CRUD lifecycle verified end-to-end. The remaining point is the cross-package scope (~5,284 production lines across 5 packages), which the maintainer has explicitly signed off on.

The author's follow-up commits are exactly what you want to see: each review finding gets a targeted fix with a regression test, no scope creep, no unrelated changes. The permissionMode validation/round-trip/clearing coverage, the scope-forwarding fix with its URL assertion, and the extension notice preservation fix are all clean and minimal.

The maintainer's local verification (clean npm ci, 2040 web-shell regression tests, 23/23 daemon route behaviors, Playwright screenshots) covers the breadth this CI environment can't exercise without tmux. Combined with the 406 targeted unit tests passing here and the full E2E CRUD lifecycle verified against the real daemon, the test evidence is strong.

One non-blocking observation carried forward: AgentCreatePage.tsx (1,215 lines) could benefit from extracting the ToolPicker and McpServerPicker sub-components if it grows further. The removed ExtensionsManagerPage.test.tsx (914 lines) is worth a follow-up to re-add stable render coverage, as the maintainer noted.

Approving — the code is clean, well-tested, and maintainer-verified. ✅

中文说明

置信度:4/5 — 在 ee4d267f 的重新审查中所有先前发现均已解决,维护者本地验证确认可合并,daemon CRUD 全生命周期已端到端验证。剩余一分是跨包范围(约 5,284 行生产代码,横跨 5 个包),维护者已明确签字确认。

作者的后续提交正是你期望看到的:每个审查发现都有针对性的修复和回归测试,没有范围蔓延,没有无关变更。维护者的本地验证(干净 npm ci、2040 项 web-shell 回归测试、23/23 daemon 路由行为、Playwright 截图)覆盖了本 CI 环境无法在没有 tmux 的情况下验证的广度。结合此处通过的 406 项定向单元测试和针对真实 daemon 验证的完整 E2E CRUD 生命周期,测试证据充分。

批准——代码干净、测试充分、维护者已验证。✅

Qwen Code · qwen3.8-max-preview

Reviewed at ee4d267f868123e6d0fd8a89c5e322002f57f1f8 · 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.

LGTM, looks ready to ship. ✅

@wenshao
wenshao added this pull request to the merge queue Jul 23, 2026
Merged via the queue into QwenLM:main with commit c0fee1b Jul 23, 2026
46 of 47 checks passed
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.

3 participants