跳到正文
FunCoding

搜索

搜索文档、Skill 和 MCP

流式 MessageDisplay

按累计快照处理回复,正确处理最终投递、并发完成顺序和取消。

MessageDisplay 在回复流式输出期间重复触发,适合实时显示或增量记录。它不支持 matcher,也不接受控制输出,返回值和退出码都被忽略。

输入是累计文本

字段含义
message_id整条流式消息稳定标识
displayed_text到当前时刻的完整累计文本,不是增量
is_final该消息最后一次投递为 true

中途事件最多约每 200ms 一次,最终事件不受该防抖窗口延迟。包含工具的轮次可能有多条消息,每次模型调用各有 ID 和最终事件;只有工具调用、没有显示文本的响应不发出此事件。

慢消费者会跳过中间快照

每条消息最多一个中途执行在进行中;运行期间新快照替换待发旧快照,不排成长队列。由于每次是累计文本,不需要拼接遗漏的片段。

最终事件在消息结束时立即发送,即使中途执行尚未完成,两者也可以重叠。结束顺序不保证:旧中途执行可能比 final 更晚完成,甚至晚于 Stop。消费者应按 message_id 把 is_final 当作终态,不要用“最后完成的进程”覆盖最新文本。

五秒等待不是无限交付保证

轮次结束和 Stop 最多等最终投递完成五秒。五秒内完成时,无头进程会等待它,Stop 在其后执行;更慢时会向 stderr 警告,TUI/ACP 后台继续,无头进程则先退出。

普通退出不会杀死这条已派发的最终 Hook,它可自行完成。因此 shell 中后续命令可能在慢 Hook 仍写文件时启动,不能以 Qwen 退出码作为“Hook 已写完”的唯一信号。

取消的两个时点

final 派发前已取消时不会发 final;即使文本实际已流完,只要轮末检查前收到 abort,也可能没有最终事件。只在 final 时刷新的消费者应为这种情况设计超时丢弃或明确取消处理。

final 已派发、仍在等待完成时取消,执行进程可能被 SIGTERM 中断。输入已交付不代表副作用已完成。中途 displayed_text 始终是暂定显示状态,只有 final 才代表该消息的最终文本。

TUI、无头和 ACP 使用同一字段契约。记录侧应同时考虑重复快照、旧进程晚完成、缺 final 和已派发但被中断四种情况。