# 对话暂停
日期:2026-08-14
# 目标
让用户能安全停止当前 Agent 任务,而不是仅让前端停止读取 SSE 后留下后端继续执行的幽灵任务。
# 变更
AgentLoop.LoopOptions新增可选isCancelled信号,并在每轮开始、模型返回后、每一个工具调用前检查。- 命中信号时写入
AssistantMessage(..., StopReason.ABORTED),发送完整消息生命周期,并以agent_end.status=cancelled结束。 WebMain维护按会话隔离的AtomicBoolean运行信号,新增POST /api/chat/pause。暂停请求不竞争被长运行占用的会话锁,因此能即时被接收。- React 在运行时展示“暂停对话”按钮;请求提交后显示“暂停请求中”,最终以 SSE 的取消状态恢复可发送状态。
# 行为边界
这是协作式暂停:已经发出的模型 HTTP 请求或已启动的工具不能被本次改动强杀;当前步骤结束后不会再进入下一轮模型调用或下一个工具。这样避免截断 JSONL、遗留半个工具结果或把页面状态误报成完成。
/api/chat/pause 在尚未出现运行 SSE 事件的极小启动窗口会返回 409;前端按钮只会在收到运行状态后出现,因此正常交互不会触发该分支。
# 验证
mvn -pl pi-agent-v1 clean test:通过(当前项目没有测试源码)。web/下npm run build:TypeScript 检查与 Vite 生产构建通过。- 后端 Mock 冒烟:执行
sleep 4后调用暂停接口,工具结束后 SSE 返回“本次任务已暂停”,agent_end.status=cancelled。 - 浏览器验收:创建新会话,发送
执行 sleep 12,运行中看到“暂停对话”,点击后页面最终显示“Agent 已取消”和暂停消息,控制台无 error/warning。