# 超时任务的延迟交付 收到 `harness-reply-timeout` 表示前台停止等待,并不证明 Harness 回合已经结束。飞书、微信、企业微信、钉钉、QQ、Telegram、Discord、Slack、WhatsApp 共用同一套延迟交付逻辑,继续跟踪原回合并补发其最终文字或终态通知,不会再次提交用户问题。 ## 实现范围 - 沿用每个机器人现有状态文件中的 `deferred` 字段,保存会话路由、Session、Turn、原始 prompt RPC ID 和渠道收件目标。兼容 #153 的旧飞书记录,无需迁移器或数据库。 - 只在 `askInWorkspaceSession` 捕获到回复停滞超时时登记;正常问答、流式、图片/文件、审批、问题和命令继续走原有流程。补发目标也只在超时后提取。 - 复用 Harness 事件监听、历史分页读取、`AssistantTextAccumulator` 和原生发送接口。飞书保留卡片和托管话题;钉钉优先卡片,回退现有机器人主动消息;其他渠道保留各自聊天、线程和 Markdown 呈现。 - 微信不保存临时 context token;QQ 不保存已过期的被动回复 msg ID;钉钉不保存临时 session webhook;WhatsApp 不保存完整原始引用消息。 - 同一 Session 的历史检查、发送、删除和后台停止依次执行,处理前重新读取待交付记录。实时事件、重连检查和定时检查不会同时发送同一条记录。 - 启动、重连和 `turn/end` 触发历史检查。待完成记录每 30 秒复查;终态历史暂未可见时先在 1 秒后复查。每次历史读取最多 20 页、30 秒,读取失败不消耗发送次数。 - 每个会话路由最多保留四条待交付任务,沿用 #153 的上限;超出时丢弃最旧待交付记录并写日志。 ## 停止与换绑 `/stop` 先复用原有当前任务控制。没有前台任务时,再处理该聊天的待交付记录:已完成的回合直接补发;未完成的回合通过原有 Host 控制执行器同时校验 Session、Turn、prompt RPC ID 后停止。没有这个原子校验能力的 Host 会提示在 Harness 中检查并停止,不回退为无回合约束的 `session.cancel`。 发送前必须仍绑定到原 Session。聊天换绑、清除会话或机器人停止后,不向新会话发送旧结果。正常退出保留待交付记录以便下次启动恢复。 ## 失败与限制 明确发送失败最多尝试三次,间隔 1 秒、2 秒;达到上限保留 `failed` 记录供排查。渠道返回发送结果不确定,或发送异常无法证明未送达时,保留带 `deliveryOutcome: unknown` 的失败记录,不自动重试。任务结果仍可在原 Harness Session 中查看。 没有跨平台消息事务,不能承诺严格恰好一次:平台已经收下消息、进程却在删除本地记录之前崩溃,重启仍可能重复补发。平台权限、主动消息配额、过期/已删除的引用和原生长消息分片能力也仍会影响最终交付。 本次只恢复可从历史重建的最终文字和终态通知,不恢复超时后产生的文件产物、问题或审批。旧记录没有 prompt RPC ID 时可补发可定位的终态,但无法安全停止尚未完成的回合。 ## 验证 - 九渠道真实 Bridge 入口配合模拟平台接口,覆盖超时登记、精确停止、状态文件重载、线程/聊天目标和并发事件去重。 - 共用协调器覆盖历史延迟、历史分页、未知回合的 prompt 匹配、重试上限、不确定发送、换绑和退出竞争。 - 原有飞书回归覆盖托管话题根、卡片/文字回退,以及旧记录兼容。正常渠道能力由完整 `npm run check` 回归覆盖。 - 自动化测试不等同于九个平台真实账号联调。