# Agent 执行计划 水质投诉事件要求 Agent 使用 `publish_execution_plan` 发布完整计划和节点状态。 工具只记录计划,不执行现场操作。前端依据结构化数据呈现主干和并行分枝,不接受模型提供的 HTML、脚本或图形指令。 ## 数据与状态 输入包含幂等 `request_id`、`title`、`reason`、`nodes` 和 `edges`。节点包含稳定 `id`、标题、执行主体 `agent | human`、说明、证据和状态:`pending | running | waiting | completed | failed | skipped | cancelled`。 边包含 `from`、`to`、条件标签 `label`。允许并行和条件分支;重试使用新节点,不形成循环依赖。 最多 40 个节点、80 条边;拒绝重复 ID、悬空依赖和环。完成状态必须提供证据;失败和等待必须说明原因。 工具先通过受信内部桥把计划写入 TJWater Server;后端拒绝会直接成为工具错误,模型必须修正后重试。 仅在后端写入成功且输入校验通过后发送 `execution_plan` 事件,且不会再异步重复写入。服务端分配 `schema_version: execution-plan@1`、`session_id`、递增 `revision` 和 `updated_at`。 更新必须保留原节点;不适用或取消的节点显式标记,已完成节点的标题及证据不能被改写。 更正完成结论时添加复核节点,并在 `reason` 中说明。 节点状态来自 Agent 显式上报,工具成功发布不等于业务动作完成。合成输入必须标识来源, 人工采样、复测、回访不得因 Agent 回复结束而自动完成。前端展示状态计数,不按时间计算百分比。 ## 任务、协作与恢复 计划独立保存在现有 Session UI State 的 `executionPlans` 中,并随消息流发送。 `GET /api/v1/agent/chat/session/:session_id/stream` 的首个 `state` 事件返回运行中快照, 或已保存的 `execution_plans`。主对话断线不影响计划快照保存。前端支持历史版本查看及断线重连。 会话元数据以 `purpose` 区分普通聊天、后台任务执行和任务协作。普通历史列表默认仅返回 `ordinary_chat`;任务执行和协作会话只能用显式 purpose/task 过滤或从对应工况任务进入。 协作会话独立持久化用户与 Agent 的问答文本,由 TJWater Server 授权返回的计划、报告和证据快照解释判断, 不复制后台执行消息、工具调用轨迹或内部推理。 工况任务执行先读取后端 task context,再通过有限、可审计的数据源查询 SCADA、工作台或外围样板数据。 查询结果携带来源、时间、内容引用和 `origin`,合成数据必须明确标识;截断结果不能用来断言完整范围无异常。 计划、精简报告和关键证据写回任务记录。计划可在调查中多次保存,未显式失败的纯计划是中间进度。 动作节点必须先存在于已保存计划;提议成功后把返回的动作编号写回计划。所有计划和动作提议保存后,最后保存本轮报告; 后端只使用当前执行代、当前会话的计划与报告判断进入等待、完成或继续运行。创建工单和下发命令只能生成待人工审批动作,Agent 无执行接口。 执行会话使用两分钟任务租约并定期续租;计划或报告写回也会续租。执行进程中断后由后端租约恢复重新排队。 旧水质样板触发仍可使用事件随附的固定合成输入,但必须表述为外围样板输入,不能冒充实时查询结果。 ## 验证与运行 Agent:`bun run check`,`bun test tests/routes/executionPlan.test.ts tests/routes/chatStream.test.ts tests/sessions`。 前端:`pnpm lint`、`pnpm typecheck`、`pnpm test`、`pnpm build`,以及 `pnpm test:browser tests/browser/peripheral-sample-panel.e2e.ts`。 浏览器覆盖分支图节点、状态更新、版本切换、键盘详情、320/375px、放大和刷新恢复。 运行实例需加载更新后的 Agent 代码和 OpenCode 工具配置。`embedded` 模式自动把内部工具桥密钥传给子进程; `client` 模式要求 Agent 与外部 OpenCode 显式配置相同的 `AGENT_INTERNAL_TOKEN` 并重启两侧。 回退前端不会改变已保存工单;回退 Agent 前先保留 Session UI State 数据,新字段可被旧代码忽略。