fix(channels): suppress nested subagent output - #6696
Conversation
|
Thanks for the PR! Template looks good ✓ Problem: This is an observed bug, not theoretical. Issue #6694 documents DingTalk channel replies exposing nested subagent intermediate reports — including absolute local file paths. There's a clear description of the observed behavior, evidence (exposed text matched the Explore tool result), and a temporary mitigation (denying agent permissions). The PR also references the prior fix in #6615 whose response-boundary handling didn't cover this nested path. Direction: Clearly aligned — leaking intermediate subagent output (with local paths) to messaging platforms is a real bug with security implications. This is squarely within the channel system's scope. Size: Not applicable — Approach: The fix is minimal and well-scoped. Both bridges get a 2-line guard that checks Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ 问题:这是已观测到的 bug,不是理论性问题。Issue #6694 记录了钉钉 channel 回复中泄露了嵌套子代理的中间报告——包括绝对本地文件路径。有清晰的行为描述、证据(泄露文本与 Explore 工具结果一致)和临时缓解措施(禁用 agent 权限)。PR 还引用了 #6615 的先前修复,其 response-boundary 处理未覆盖此嵌套路径。 方向:明确对齐——向消息平台泄露子代理中间输出(包含本地路径)是一个有安全隐患的真实 bug,完全在 channel 系统范围内。 规模:不适用—— 方案:修复方案最小且范围精准。两个 bridge 各加 2 行守卫代码,通过检查 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewIndependent proposal: the The PR's approach matches this exactly. The fix is 2 production lines per bridge, placed at the top of the No issues found. Clean, minimal, follows established patterns. TestingBuild: Focused tests (57 → 59 with PR): all pass. The two new regression tests directly reproduce the bug scenario — a nested subagent chunk followed by a root-agent chunk — and assert only the root text is delivered. Live DingTalk channel reproduction was not possible (no credentials available in this environment). The unit tests mock the exact event sequence from issue #6694 and verify both bridge paths. Before (main branch, without PR)After (with PR applied)— Qwen Code · qwen3.7-max |
|
This is a clean, focused bugfix that does exactly what it says. The problem is real (issue #6694 documents DingTalk channel replies leaking subagent output including absolute local file paths), the fix is minimal (4 production lines across 2 bridges), and the approach follows an established pattern already used in the webui package's session mappers. The regression tests directly mock the bug scenario and pass on both bridge paths. Build and typecheck are clean. Approving. ✅ 中文说明这是一个干净、聚焦的 bug 修复,完全符合 PR 描述。问题是真实的(issue #6694 记录了钉钉 channel 回复泄露子代理输出,包括绝对本地文件路径),修复方案最小(两个 bridge 共 4 行生产代码),方案遵循了 webui 包 session mappers 中已有的成熟模式。回归测试直接 mock 了 bug 场景,两条 bridge 路径均通过。Build 和 typecheck 均正常。 批准。✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
— qwen3.7-max via Qwen Code /review
✅ Local validation report (maintainer)I built and ran real tests against this PR's own checkout ( Environment
What the fix doesBoth bridges now skip 1) Focused bridge suite — all green2) Regression proof — the new tests genuinely catch the bugI reverted only the 8 production lines (kept the two new tests) to confirm they fail for the right reason, then restored: The leaked 3) Full package sweep + build/typecheck — cleanChannel payload — before vs after
VerdictLGTM — safe to merge. The change is minimal (8 src lines, symmetric across both bridges), correctly scoped to the channel boundary, backed by focused regression tests that fail without it, and it preserves ACP observability. Only caveat, already noted in the PR: live DingTalk delivery with production credentials was not exercised — the fix operates purely at the ACP/channel chunk boundary, which is what these tests cover. 🇨🇳 中文说明(点击展开)✅ 本地验证报告(维护者)我基于该 PR 自身的检出( 环境
这个修复做了什么两个 bridge 现在会跳过 1)聚焦 bridge 测试——全部通过2)回归验证——新测试确实能抓住这个 bug我只回退了那 8 行生产代码(保留新测试),确认测试因正确的原因失败,随后已还原: 泄漏出来的 3)整包测试 + 构建/类型检查——干净Channel 投递内容——修复前后对比
结论LGTM——可以合并。 改动很小(8 行生产代码,两个 bridge 对称处理),准确地落在 channel 边界上,有能在缺失时失败的聚焦回归测试保障,同时保留了 ACP 可观测性。唯一说明(PR 中已注明):未使用生产凭据做真实钉钉投递——但本修复完全作用于 ACP/channel chunk 边界,正是这些测试所覆盖的范围。 |
What this PR does
This PR prevents channel delivery from collecting assistant message chunks that belong to nested subagents. Root-agent chunks continue through the existing response-boundary handling, while nested Agent/Explore reports remain available as ACP session updates for clients that render subagent activity.
Why it's needed
Nested subagent output is emitted as an assistant message chunk with parent-tool metadata. Channel bridges previously treated those chunks as root-agent response text, so an intermediate research report, including absolute local paths, could be delivered to DingTalk before the root agent's final answer. Filtering at the channel boundary preserves ACP observability without exposing intermediate subagent content to messaging platforms.
Reviewer Test Plan
How to verify
Exercise both a direct ACP-backed channel session and a daemon-managed channel session with an Agent/Explore subagent that emits a research report before the root agent responds. Confirm the completed channel response contains only the root agent's final answer. Also confirm ordinary root-agent chunks are still delivered and the raw ACP session update for nested activity remains available to non-channel clients.
Evidence (Before & After)
Before: the focused regression tests returned
Nested research report.Final answer.. After: both paths return onlyFinal answer., and 59 focused bridge tests pass.Tested on
Environment (optional)
Node.js workspace after
npm install; focused Vitest tests plus full build and typecheck.Risk & Scope
Linked Issues
Fixes #6694
中文说明
这个 PR 做了什么
这个 PR 阻止 channel 投递收集属于嵌套子代理的 assistant message chunk。根代理文本仍沿用现有 response boundary 处理;嵌套 Agent/Explore 报告仍作为 ACP session update 保留,供需要展示子代理活动的客户端使用。
为什么需要
嵌套子代理输出会以带有父工具元数据的 assistant message chunk 发出。此前 channel bridge 会把这些 chunk 当作根代理回复文本,因此包含绝对本地路径的中间研究报告可能在根代理最终回复前被投递到钉钉。把过滤放在 channel 边界既保留 ACP 可观测性,又避免向消息平台暴露子代理中间内容。
Reviewer 测试计划
如何验证
分别通过直接 ACP channel session 和 daemon 管理的 channel session 触发 Agent/Explore 子代理,使其在根代理回复前输出研究报告。确认 channel 完整回复只包含根代理最终答案;同时确认普通根代理 chunk 仍正常投递,嵌套活动的原始 ACP session update 仍可供非 channel 客户端使用。
证据(修复前后)
修复前:聚焦回归测试返回
Nested research report.Final answer.。修复后:两条路径都只返回Final answer.,59 个 bridge 聚焦测试全部通过。测试平台
环境(可选)
执行
npm install后的 Node.js 工作区;运行了聚焦 Vitest 测试、完整 build 和 typecheck。风险与范围
关联 Issue
Fixes #6694