156 lines
11 KiB
Markdown
156 lines
11 KiB
Markdown
# 调查进展与实时展示
|
||
|
||
调查执行中可持续发布正文和完整 Mermaid 图,尚未形成结论时也能发布。
|
||
Server 将阅读进展、业务报告和浏览器展示请求分别保存。运行结束仍要求同轮最终报告,
|
||
进展中的节点状态不参与调度、审批或结束判断。
|
||
|
||
## 进展快照
|
||
|
||
`POST /api/v1/operational-tasks/{task_id}/agent-artifacts` 新增可选 `progress`:
|
||
|
||
```json
|
||
{
|
||
"request_id": "<uuid>",
|
||
"run_id": "<current-run-uuid>",
|
||
"source_session_id": "<claimed-session-id>",
|
||
"progress": {
|
||
"summary": "正在核对投诉时段的监测记录,尚未形成结论。",
|
||
"diagram": {
|
||
"title": "当前调查进展",
|
||
"mermaid": "flowchart LR\nread[核查监测记录] --> judge[判断证据范围]",
|
||
"node_refs": [{
|
||
"node_id": "read",
|
||
"label": "核查监测记录",
|
||
"status": "running",
|
||
"evidence_refs": [],
|
||
"action_refs": [],
|
||
"map_targets": [{"source_id": "pipes", "feature_id": "<known-pipe-id>"}]
|
||
}]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
示例中的编号由实际任务和资产替换。正文最长 20,000 字符,`diagram` 可空。
|
||
图示沿用 [调查报告契约](investigation-report-contract.md) 的 Mermaid 安全限制。
|
||
节点状态可空,或为 `pending/running/completed/waiting_human/failed/skipped/cancelled`。
|
||
`map_targets` 只接受 `junctions/pipes/valves/pumps/tanks/reservoirs/scada` 七类来源和要素编号。
|
||
图中节点引用在本次发布内唯一,证据和动作引用必须属于该任务。跨修订可以修改节点编号、
|
||
分支和文字,Server 不验证依赖执行顺序或节点完工。
|
||
|
||
每次传入 `progress` 都完整替换该 run 的快照,传入 `diagram: null` 清除上一版图示。
|
||
省略 `progress` 保留原快照。同一个请求编号重试只发布一次。
|
||
`workbench.operational_task_progress` 每个任务和 run 保存最新一份快照,独立于七天事件清理。
|
||
任务详情和 Agent 上下文返回 `latest_progress`,包含 `revision/run_id/execution_generation/`
|
||
`published_at/source_session_id/progress`。只读取当前执行代次,新轮次尚未发布时返回空。
|
||
快照更新发出 `operational.progress.changed`,前端据此读取最新内容。
|
||
|
||
## 浏览器实时联动
|
||
|
||
`POST /api/v1/operational-tasks/{task_id}/presentation-events` 接收
|
||
`request_id/run_id/source_session_id/command`,要求任务执行权限。
|
||
Server 校验当前 run、绑定会话、有效租约和幂等身份,记录 `operational.presentation.requested`。
|
||
响应为 `recorded/event_seq/run_id/execution_generation`,表示展示请求已保存,
|
||
不表示浏览器已显示或现场动作已执行。
|
||
|
||
| command.action | 参数 |
|
||
| --- | --- |
|
||
| locate_features | layer、feature_ids |
|
||
| zoom_to_map | center:WGS84 经度纬度、zoom:0–24 |
|
||
| highlight_features | layer、feature_ids、必填 effect:steady 或 pulse |
|
||
| clear_highlights | 无 |
|
||
| open_chart | chart_id、chart、非空 evidence_refs |
|
||
| close_chart | chart_id |
|
||
| set_overlay | overlay_id、title、mode:geometry 或 heatmap、evidence_id,可选 data |
|
||
| clear_overlay | overlay_id |
|
||
| render_scada_analysis | items:device_id 与 high/medium/low/unrated 等级,设备编号不重复 |
|
||
| clear_scada_analysis | 无 |
|
||
|
||
以上十种动作与 Chat 的 `present_view`、Dev JSONL 共用扁平 `command: {action, ...字段}`。Chat 使用 `frontend-action@2` 和执行回执;任务仍只记录展示请求,Dev 只做本地预览。三者使用独立的地图源、SCADA 图层和图表状态。Dev 的动作数据行必须为 `{"record_type":"presentation","command":{...}}`;界面块行使用 `record_type: ui_block`,新示例明确带 `phase: final`。普通调查数据保持来源字段,不执行其中的 action。仓库示例见[前端统一展示夹具](../../next-tjwater-frontend/tests/fixtures/unified-presentation.jsonl),其中编号来自测试夹具。
|
||
|
||
图表限定折线和柱形,包含 `title/chart_type/x_data/series`。最多 100 个横轴值和 8 组有限数值序列,
|
||
序列长度与横轴对齐,引用证据必须属于当前任务。地图高亮来源沿用上述七类。
|
||
覆盖层的权威数据来自不可变证据。省略 `data` 时,Server 从证据快照提取现有 GeoJSON,
|
||
或使用已记录的 `longitude/latitude` 点位,将 `FeatureCollection` 加入事件中的 `command.data`。
|
||
若传入 `data`,必须与同一证据快照解析出的内容一致;Server 始终发布快照解析结果,不能用调用参数覆盖证据。
|
||
热力图只接受记录中的点,权重为有限非负数,未记录权重时取 1。
|
||
没有坐标的地址、空数据、非法几何、模型自绘区域均不能生成覆盖层。该接口不做地址解析、
|
||
范围推算或污染传播计算。展示事件总大小上限为 512 KiB,超限返回 422。
|
||
|
||
`generate_node_coverage` 是独立的节点空间覆盖工具,适用于普通项目聊天和后台调查,
|
||
不绑定爆管、阀门隔离或固定执行顺序。调用者提供需要比较的节点分组,Server 从当前项目
|
||
`gis.node_geometries` 读取真实位置。监测设备、投诉、地址等须先关联模型节点,
|
||
不接受模型自由生成的坐标。具体适用范围和参数见[节点覆盖工具](node-coverage-tool.md)。
|
||
|
||
计算先投影到局部米制坐标,取凹包(默认 ratio=0.25)、加展示缓冲(默认 25 m),
|
||
再以 2 m 容差简化并转回 WGS84;凹包比例与缓冲距离可在有界参数内选择。
|
||
默认展示各组的地理包络,不判断连接关系;需要时可按模型连接拆分,额外指定视为断开的连接。
|
||
少量点、重合点和共线点同样通过缓冲形成面。多组结果一起保存在 `result.map_payload`,
|
||
避免连续 `set_overlay` 覆盖前一组;`result.coverage` 保存来源节点、映射完整性及算法参数。
|
||
该面不推断故障、污染、实际停水、水力影响或用户服务边界,缓冲距离也不是供水服务半径。
|
||
缺失几何时标记 `partial`,没有可用位置时不生成面。输入最多 8 组、合计 10000 个不同节点;
|
||
几何输出遵守覆盖层顶点和大小限制,超限要求缩小范围,不静默抽样或改变原分析结果。
|
||
|
||
MCP 保存完整查询响应作为不可变证据,展示解析器同时支持响应信封中的
|
||
`data.result.map_payload`。Agent 使用 `set_overlay` 引用本次 `evidence_id` 并省略 `data`。
|
||
超过内联返回预算时,响应的 `data.presentation.command` 仍保留可发布的展示命令,
|
||
`data.presentation.groups` 保留覆盖完整性计数,
|
||
完整几何留在证据中,不能把缩略返回误认为没有空间成果。调查按实际步骤同步发布展示:
|
||
地址得到明确坐标后缩放定位,取得候选资产后定位候选,检查影响节点后生成并展示覆盖示意,
|
||
形成或调整关阀方案后定位阀门,读取监测对照后展示点位及序列。
|
||
图表同样随结果返回发布:监测趋势与事件对照用折线图,可比候选评价或方案用柱状图,
|
||
水力及污染传播等模拟按实际返回的时刻、对象和指标画图。压力、流量、浓度等不同单位分图,
|
||
注明来源、范围与实测或模型属性;没有同口径基准时不计算或绘制改善量,缺测不补零。
|
||
过程图表通过 `open_chart` 提供 `chart_id/chart/evidence_refs`,每图最多100个横轴值、8组序列,
|
||
超限时分图或明确说明抽样、聚合范围;单值或无可比数据用文字或表格。
|
||
关键趋势与比较结论保留到报告中,最终报告的图表不替代过程发布。
|
||
业务 Skill 说明本步骤应展示什么,调查指令统一说明发布方法、非空几何检查、去重和失败处理。
|
||
同一阶段批量展示,数据或方案没有变化时不重复请求;不为地图动作增加无关业务分析。
|
||
报告的 `map_targets` 仅为手动定位入口。关键步骤的数据缺失或展示失败需记录具体限制,
|
||
没有浏览器连接也不阻止分析或报告收尾。
|
||
|
||
`GET /api/v1/operational-tasks/{task_id}/presentation-cursor` 在同一事务中读取
|
||
`task_id/execution_generation/active_run/event_cursor`,其中活跃 run 仅返回 `run_id/generation/status`。
|
||
浏览器打开 Dev 联动、切换任务或断线重连时,以此建立新基线,只消费之后的展示事件。
|
||
跟随开关只影响当前浏览器的临时展示,正文和图示更新始终可读,调查仍由后台继续执行。
|
||
关闭 Dev 面板不改变跟随开关。关闭跟随开关、切换任务或断线时清理临时效果,
|
||
执行结束停止执行态动效,已显示的图表与覆盖层保留供阅读。不回放历史请求,不重新执行调查。
|
||
|
||
## 人工反馈续调
|
||
|
||
外围同步器根据动作回执找到关联子工单。样板创建固定为 `revision=1`,首次创建回执不作为
|
||
新的现场反馈入队。后续版本可唤醒已结束调查,旧报告和证据保留,生成新的执行代次。
|
||
现场备注从工单 `activity.kind=feedback` 的记录进入反馈证据,仍标明样板合成来源。
|
||
重复请求或同一源版本重放不增加执行代次,取消调查拒绝新反馈。
|
||
|
||
同步器先送达各父调查反馈,再推进预约工单投影的源版本。定向源事件和动作回执补查保留,
|
||
处理源更新早于回执保存的情况。全量对账只为源版本变化补查已结束调查,本次不回填历史反馈。
|
||
原投诉收到新版本后同步推进其已有来源修订号。数据不足仍正常结束本轮,
|
||
只有新的可信业务输入进入后续轮次,不依赖图示节点制造人工等待。
|
||
|
||
## 部署与验证
|
||
|
||
新增 [023 迁移](../resources/sql/023_operational_task_progress.sql) 仅适用于 `tjwater_v2`,
|
||
增加进展表和两个事件 topic 的 CHECK 取值。2026-10-10 已在目标库完成全库备份、
|
||
迁移事务回滚演练及正式应用,其他项目和旧任务未改动。
|
||
|
||
实际 worker 曾成功投递指定调查,模型发布进展和报告,但因 service 账号的任务权限过滤
|
||
导致 `approved_data_scopes` 为空,误作数据不足结束。这不是业务数据确实不足。
|
||
用户确认开放规则后,任务 API 已移除该额外过滤,沿用账号已有的项目读取权限。
|
||
在线上下文返回七类来源,同一身份实际读取 SCADA 设备和外围系统工单成功;没有新增
|
||
角色权限或放宽跨项目、审批和设备控制边界。旧委托路径保留兼容,已有权限无需委托凭据。
|
||
用户级 `tjwater-operational-worker.service` 已重新启用。旧报告保留,未自动重新调查,
|
||
不能把旧报告视为修复后的业务验收。任务创建时间下界和并发配置见
|
||
[执行 worker](operational-task-workers.md),未回填旧任务。
|
||
进展读接口在表尚未部署时返回空,写入口须在迁移与 Server 更新后启用。
|
||
按现有数据库发布流程应用迁移,再更新 Server、Agent 和前端,运行中的 worker 需要加载更新。
|
||
|
||
聚焦检查:
|
||
|
||
```bash
|
||
conda run -n server python -m pytest tests/unit/test_operational_tasks.py tests/unit/test_operational_presentation.py tests/unit/test_peripheral_task_sync.py tests/unit/test_peripheral_push_sync.py tests/api/test_operational_task_dynamic_flow.py tests/api/test_openapi_contract.py -q
|
||
git diff --check
|
||
```
|
||
|
||
这些检查覆盖隔离 HTTP 与状态机,不代替共享数据库迁移、真实模型运行或现场复测验收。
|