Repository navigation
[matrix-channel] Silent turns are labelled 「已完成」 ("Done") — a false completion signal in rooms #1320
Description
[matrix-channel] Silent turns are labelled 「已完成」 ("Done") — a false completion signal in rooms
Problem
When an agent turn ends with no visible final text, the Matrix channel edits the
per-turn placeholder (「处理中...」) to 「已完成」("Done") — unconditionally.
There are two very different situations behind "no visible text", and the current code
conflates them:
- Quiet completion — the turn did real work (tool calls) and simply had nothing to
say. Marking it done is reasonable. - Silent/empty turn — the model produced no tool calls and no meaningful output at
all (observed failure mode: a long reasoning-only response that ends without any
tool call or final text; e.g. generation truncated at the output budget). The turn
did nothing, yet the room is told 「已完成」.
In a production incident, five such silent turns (each ending with tens of KB of
reasoning-only output, zero tool calls) terminated with the 「已完成」 marker. Room
observers and the coordination layer treated them as successful completions — the
silence was upgraded from "invisible" to "believed done", and the failures were only
caught by human intervention hours later.
Where (code chain)
plugins/agentteams-matrix-channel/agentteams_matrix/channel.py →
_on_process_completed() (current main, ~L4450–4510):
- placeholder branch pops
_MATRIX_PLACEHOLDER_THREAD_ROOT_KEYand edits the thread
root with:"已处理"when the final output is theNO_REPLYcontrol line (good, L4472/L4490);"已完成"whenever there is no visible text — three paths:- streaming text present but empty after control-text stripping (L4478);
- pending final message present but empty after stripping (L4502);
- no final text at all (L4506).
- The discriminator that distinguishes "quiet completion" from "did nothing" does not
exist anywhere in the path.
(Historical note: the completion marker was introduced with the QwenPaw 2.0 adaptation,
fb3a40be.)
Impact
- False completion signal: room observers (team leader / humans / coordinating
agents) see 「已完成」 and move on; a turn that produced nothing is recorded as done. - Silent automation: no retry, no escalation, no alert — the failure is masked by
the success marker, and rooms can stay silent for hours. - Observability loss: the marker is the only per-turn outcome the room gets in
the no-output case; it currently always says "done".
Proposal
Keep the marker, make it honest:
- Track per-turn activity in the channel's per-turn state (
send_meta):- whether any tool call / tool output message was routed during the turn
(the channel already observes these events — they drive tool-message rendering); - whether any visible text (final or streamed) was produced.
- whether any tool call / tool output message was routed during the turn
- In the placeholder-finalization branch, when the turn ends with
zero tool calls && visible text ≤ ~10 chars (or empty) → post an explicit
no-output marker (e.g. 「本回合无产出」) instead of 「已完成」.NO_REPLYcontinues to map to 「已处理」 (unchanged);- turns with tool activity keep the current 「已完成」 behavior.
- (Optional, follow-up) emit a machine-readable signal alongside the marker so the
dispatching party can be re-woken automatically — turning multi-hour silent stalls
into seconds-visible events.
Tests
- Unit: empty turn (no tool message + no text) → thread root edited to the no-output
marker, not 「已完成」; - Unit: tool-only turn with no text → 「已完成」 (unchanged);
- Unit:
NO_REPLY→ 「已处理」 (unchanged); - Regression: normal final-text edit unchanged.
空转回合被标「已完成」——房间里的假完成信号
问题:回合结束时若「可见最终文本」为空,Matrix 频道会把占位消息(「处理中...」)无条件改成**「已完成」。但"没有可见文本"背后是两种完全不同的情况:①安静完成**(真干了活、调了工具、只是没话说)——标"已完成"合理;②空转回合(模型零工具调用、无有意义输出——已观测形态:整回合只有超长思维流、无任何工具调用与最终文本,如生成撞输出预算被截断)——什么也没做,房间却收到「已完成」。在生产事故中,5 个此类空转回合均以「已完成」收口:房间观察者与协调层把它当成功完成,静默从"不可见"升级为"被误认为已完成",数小时后才被人工发现。
链条:plugins/agentteams-matrix-channel/agentteams_matrix/channel.py → _on_process_completed()(当前 main ~L4450–4510):占位分支编辑线程根——NO_REPLY → 「已处理」(正确,L4472/L4490);凡无可见文本 → 「已完成」(三条路径:L4478 / L4502 / L4506)。整条路径没有任何"做了事 vs 什么都没做"的判别。
影响:假完成信号 → 观察者(Leader/人类/协调 Agent)以为完成直接走开;无重试、无升级、无告警,房间可静默数小时;每回合唯一的产出标记永远说"完成"。
提案:把标记做诚实——① 在回合状态(send_meta)里记录:本回合是否路由过工具调用/工具输出消息(频道本就观察这些事件)、是否有过可见文本;② 占位收口分支:零工具 且 可见文本 ≤约 10 字(或为空) → 发明确的无产出标记(如「本回合无产出」)而非「已完成」;NO_REPLY 维持「已处理」;有工具活动的回合维持「已完成」。③(可选跟进)随标记发一个机器可读信号,供派发方自动重唤醒——把数小时静默压回秒级可见。
测试:空回合 → 无产出标记(非「已完成」);无文本的工具回合 → 「已完成」不变;NO_REPLY → 「已处理」不变;正常文本收口回归不变。
Activity
fix(matrix-channel): stop labelling silent turns as「已完成」 (#1320) (#1328)
shiyiyue1102 commentedon Oct 16, 2026
Released in v1.2.5. PR #1328 distinguishes an empty turn from tool-only completion and preserves NO_REPLY handling.
The fix is included in the released tag; related regression evidence and required release checks have passed. Closing as delivered.
已随 v1.2.5 正式发布。PR #1328 已区分空转回合与仅调用工具的完成回合,并保留 NO_REPLY 处理。
已核对修复包含于发布标签,相关回归证据及必需发布检查均通过,现按已交付关闭。