15 KiB
调查任务展示与 Dev 测试
可直接打开顶部 Dev 入口载入、编辑、校验并执行本地测试案例,无需先选择调查或开启实时跟随。纯数据和界面块可独立预览,包含地图或图表展示指令时需等待地图就绪。验证实际调查联动时,在“工况任务 → 调查任务”选择一项任务,再打开 Dev。Dev 默认打开“调查测试”页签,保留当前选择,显示调查代次、实时图表数、已保存报告中的图表/表格/地图入口数,以及最近的展示动作。上一轮报告会明确标注,不当成本轮新成果。
Dev 分为“调查测试”和“地图调试”两个页签:前者按“准备数据 → 校验与执行 → 检查结果”组织 JSONL 流程,后者保留要素定位、水流、图层和标注工具。切换页签保留输入与展示状态,不清除当前预览。地图重置操作仅显示在地图调试页。
当前识别链路
| 内容 | 来源和行为 |
|---|---|
| 实时地图、图表和覆盖层 | 从工作台事件流读取 operational.presentation.requested,核对所选 task、run 和 generation,验证命令后使用调查展示控制器执行 |
| 已保存的结构化界面 | 任务报告的 ui_blocks 使用既有 answer-ui@1 校验及 json-render 组件;未知或不合法的内容不作为可执行界面 |
| JSONL 数据 | Dev 中显式载入、校验后在展示面板预览;调查数据行仅展示,只有受控展示指令行会在点击“执行本地预览”后操作地图或图表 |
选中调查任务时,通过只读 GET /api/v1/operational-tasks/{task_id}/presentation-events 分页读取该任务保存的展示事件,并载入左下列表;同时载入本轮最新报告中已保存的有效界面块。已完成任务、关闭实时跟随时也可读取。历史报告仍在任务详情可读。开启跟随或重连时先建立固定事件游标,载入不超过该游标的历史,期间到达的新事件暂存,历史完成后再顺序消费,避免间隙或重复。“载入当前报告”加载该任务最新保存的报告界面块,供本地检查,不重新发布报告。
Dev 与工况详情共用右侧工具位置,切换调查时先关闭 Dev 回到任务列表,再打开 Dev 检查新的选择。实时展示面板位于地图左下方,打开 Dev 后仍可看见。新图表进入其滚动区时会滚动到图表,保留标题;手动收起面板后仍接收指令,展开再查看。切换项目、调查或执行代次会清理临时效果并取消未完成的本地预览。上述清理保留本次页面会话内的动作快照,只有切换项目会同时清空历史。已绑定调查时关闭跟随也会清理该调查的当前临时展示;未选择调查的本地预览不受跟随开关影响。面板外仍可操作地图,手动拖拽或滚轮暂停镜头自动跟随。
本地测试步骤
- 在默认展开的“调查测试”页签准备数据。“载入合成样例”在当前地图中心生成合成空间展示、压力曲线、候选表格和一条候选数据;所选调查进度存在地图目标时,另加入该目标的高亮测试。所有合成结果均有明确标记。
- 可选:点击“校验 JSONL”单独查看识别出的展示指令、界面块、调查数据数量。也可直接执行本地预览,执行入口会自动校验当前全部内容。
- 点击“执行本地预览”,自动校验通过后对照地图和左下展示面板中的图表、结构化界面与数据摘要;Dev 的“原始数据检查”可点击对象查看原始行内容。动作记录区分“实时指令”和“本地测试”,显示应用或失败结果。
- 按需“下载测试 JSONL”保存当前已校验输入;“清除临时展示”清除当前浏览器的高亮、图表和覆盖层。测试不改变服务端事件游标,不发起调查、审批、工单或设备写入。
样例与导出仅存在当前页面或用户下载的文件中,不写 Agent 工作区,不伪造已保存证据。Dev 不会自动枚举 Agent 生成的本地文件;要检查已有 JSONL,可将通过受控入口取得的文件内容粘贴到编辑区。当前最多 200 KB、40 行、8 个界面块;地图与图表继续遵守原展示协议的数量、几何及序列约束。
可切换测试案例
“JSONL 测试案例”选择框不依赖调查选择;地图就绪后即可切换并载入内容,显示该案例的预期结果。本地预览无需选择调查或开启跟随,表格、卡片、数据摘要、图表与范围统一在地图左下方的“本地预览展示”中显示,Dev 只保留输入、校验、原始数据检查与执行记录;“载入合成样例”重新生成当前案例,尚未选择时载入组合联动。修改输入会重置案例选择与校验状态,仍可继续手工测试。“载入当前报告”继续加载所选任务已保存的界面块。
| 案例 | 核对内容 |
|---|---|
| 组合联动 | 地图点、调查现有目标高亮、压力曲线、候选表格与数据 |
| 地图定位与高亮 | 有目标时高亮真实关联目标;无目标时只显示合成点,不虚构资产查询编号 |
| 压力趋势对比 | 两条合成压力曲线、时间轴、单位与图例 |
| 影响用户统计 | 合成用户数柱状图,不作为真实停水统计 |
| 合成影响范围 | 当前地图中心附近的合成 Polygon |
| 投诉热力分布 | 三个具有非负权重的合成投诉点 |
| 候选管段对比 | 合成候选表格及两条 candidate 数据,不查询虚拟管段 |
| 隔离阀门清单 | 合成阀门表格及两条 valve 数据,不执行关阀 |
| 纯 JSONL 数据 | 只显示数据;内嵌 action 字段不作为动作执行 |
| 错误:JSON 语法 | 第二行语法错误时整批拒绝,不执行第一行合法动作 |
| 错误:不支持的动作 | 拒绝协议未支持的动作 |
| 错误:图表数据不齐 | 拒绝时间轴和序列长度不一致的图表 |
切换前若执行过本地预览,会先清除它的当前临时地图、图表和业务结果,保留动作历史供回看;仅选择或编辑 JSONL 不执行新指令。有内容时即可点击“执行本地预览”,无需先点单独校验;每次执行都会重新校验当前全部输入。任何一行错误都会拦截整批,显示具体错误,不执行部分指令;地图尚未就绪时也显示原因。仅空输入或正在执行时禁用按钮,不以调查选择或实时跟随作为本地执行前提。测试不会写入 Server、重启调查或发送 Agent 对话。案例定义位于 investigation-dev-cases.ts。
JSONL 格式
以下每行都是独立对象。第一行只在点击执行后清理本地高亮;第二行预览合成说明;第三行仅为候选数据,不触发高亮、定位或计算。
{"record_type":"presentation","command":{"action":"clear_highlights"}}
{"record_type":"ui_block","evidence_refs":[],"block":{"version":"answer-ui@1","block_id":"dev-note","fallback_text":"本地合成格式示例","spec":{"root":"note","elements":{"note":{"type":"Text","props":{"text":"本地合成格式示例,不代表调查成果。","tone":"warning"},"children":[]}}}}}
{"record_type":"candidate","origin":"synthetic","source_evidence_refs":[],"element_id":"DEMO-PIPE-01","status":"example_only"}
仓库内的可复制数据示例为 unified-presentation.jsonl,覆盖十种 command、一个 phase: final 界面块和带来源的普通数据行;P1 是浏览器测试夹具中的测点,业务项目应使用已核实的实际编号。内置案例从同一个记录生成器输出,并在生成时通过当前校验器。错误案例单独保留,专门验证拒绝行为。
每行必须显式使用 record_type: presentation、record_type: ui_block,或带来源的调查数据类型。裸 command、裸 answer-ui@1 block 和旧 chat 的 name/params 格式均拒绝。展示指令统一接受 locate_features/zoom_to_map/highlight_features/clear_highlights/open_chart/close_chart/set_overlay/clear_overlay/render_scada_analysis/clear_scada_analysis,不能加入项目、运行身份、URL、脚本或任意命令。Dev 的覆盖层样例直接提供合成几何,仅用于本地渲染测试;任务 Agent 的 set_overlay 可只传证据编号,由 Server 提取几何;传入 data 时必须与保存的证据快照一致。Chat 和 Dev 执行已提供并校验的 data。不能把 Dev 格式当成 Server 写入接口。
数据行需要 record_type、origin、source_evidence_refs,其余字段按实际内容保留。origin 接受 system_data、synthetic、derived、human_input,仅说明本地数据来源,不构成 Server 证据认证。显示合成表格不等于运行过定位或完成现场处置。
验证范围
聚焦测试:
pnpm exec vitest run src/features/workbench/utils/investigation-dev-preview.test.ts src/features/workbench/components/map-dev-panel.test.tsx src/features/workbench/hooks/investigation-presentation-follower.test.ts
PLAYWRIGHT_PORT=5194 pnpm exec playwright test tests/browser/investigation-dev-tools.e2e.ts tests/browser/floating-panel-pointer.e2e.ts --workers=1 --reporter=line
浏览器用隔离 API/SSE fixture 验证所选任务到真实 MapLibre/React 展示的消费链、Dev 开启与收起、JSONL 校验和下载、任务切换清理、紧凑窗口及面板外地图输入;不调用付费模型或真实工单、设备接口。真实 Agent 是否发布了正确的事件、报告或 JSONL 文件,仍需按实际项目运行记录核对。
统一展示动作
Chat 使用 present_view({command, reason}),在线通过 SSE 的 tjwater.frontend_action 承载 frontend-action@2,动作字段为 command,不再接收 name/params。浏览器回传 frontend-action-result@2。任务事件和 Dev JSONL 的 command 使用相同结构,并进入同一执行器。Chat、调查和 Dev 预览分别拥有地图源、SCADA 图层及图表状态;清理、切换会话和切换任务不会误清其他入口。Chat 动作按接收顺序执行,切换会话取消正在执行及排队动作;过期动作不会执行。任务仍只记录发布状态,不等待浏览器。查看历史回答不会重放动作。
动作 schema 的维护源是 src/features/agent/presentation/command-schema.ts。修改后在前端仓库运行 node scripts/export-view-command-contract.mjs,同步 Agent 主机/原生工具共用的 TypeScript schema 和 Agent/Server JSON Schema;运行同一命令加 --check 检查一致性。Server 任务入口继续执行证据归属和快照校验。
已有案例与示例迁移
仓库内正向示例统一使用以下格式;测试输入中的旧格式仅用于明确的拒绝用例。
| 内容 | 当前格式 |
|---|---|
| 地图、图表和 SCADA 动作 | {"record_type":"presentation","command":{"action":"动作名",…}} |
| 图表动作 | open_chart,图表数据位于 command.chart,明确提供 chart_id 和 evidence_refs |
| 结构化界面 | {"record_type":"ui_block","block":{"version":"answer-ui@1","block_id":"…","phase":"final",…},"evidence_refs":[]} |
| 调查数据 | 保留 record_type/origin/source_evidence_refs,不把内嵌 action 提升为指令 |
| Chat 调用 | present_view({command, reason}),不再调用旧的独立展示工具 |
本轮迁移只覆盖仓库内的内置案例、夹具和文档示例,未修改历史会话、数据库或外部下载文件。没有增加运行时旧格式转换。
展示动作历史
调查实时展示按所选任务读取 Server 已保存的展示动作,各任务的历史在浏览器中分别保留、切换时按任务展示。对话展示和本地预览展示继续保留当前项目、本次页面会话内收到的动作。清除类动作不纳入历史。展示面板的“切换展示动作”以最新优先倒序排列,“当前(最新)”始终置顶,动作编号保留发生顺序。可选择任一已完成、未完成或取消的动作,也可用上一步/下一步逐步回看;进行中的动作显示状态但不可选择。“回到当前”恢复最新展示。 当前结果与最后一条已完成动作相同时,合并显示为“当前(最新)”,下拉和前后导航不再重复这一项。清理后当前结果与最后快照不同,最后一条仍作为历史结果可选。切换任务、切换案例、关闭图表和清除当前展示都会保留历史;切换项目或刷新页面后清空浏览器缓存,重新选择调查任务可再次读取 Server 保存的事件。不设最近若干条的截断。载入和回看不向 Server 发布事件,不重启调查、审批或现场操作;重复选择同一任务按任务编号和事件序号去重。
本地快照保存图表、界面块、数据、证据摘要、地图几何及镜头。Server 历史保留原发布指令和空间证据快照;只有要素编号的旧定位指令在首次载入时按当前项目读取可访问几何,不声称这些是历史时刻的资产位置。载入后回看使用本地快照,不重复查询。上一轮结果可作为历史查看,不混入本轮当前状态。单条过期或不合法指令显示失败记录,其他有效结果继续载入。历史导航直接渲染快照,不重新查询资产、执行原指令或发送调查请求。关闭图表、显示/隐藏及定位覆盖层、界面块关联要素定位等操作会产生记录;清除临时展示、清除地图展示,以及 clear_highlights/clear_overlay/clear_scada_analysis 指令只更新当前状态,不创建历史条目,已有结果快照仍保留;地图手动拖拽和证据展开属于查看操作,不逐帧记录。记录不是完整底图或外部实时数据的离线副本。
回看期间,新动作继续更新“当前”,面板保留正在查看的历史并提示后续动作数。“回到当前”恢复这些最新结果。历史画面禁止关闭图表、修改覆盖层和发起新的关联要素查询,仍可查看依据、检查表格并定位已有覆盖层。地图与界面使用已有过渡,并尊重减少动画设置。Dev 原始数据检查对应编辑器最近一次执行的输入,不随展示历史切换;历史结果及快照以展示面板为准。
历史接口按 after、through 游标和 limit 分页,返回 task_id/event_cursor/items/next_after;客户端固定首次授权游标,不截断为最近一页。Server 按项目、任务及展示事件类型读取现有事件日志,不需要新增数据表。新接口需与前端一起发布;测试覆盖的是当前源码的服务/仓储/API 单元检查与浏览器模拟 API 联动,未替代真实项目验收。