Keep investigation graphs stable during updates, defer expensive chart rendering, and prevent stale results when switching tasks. Adopt reference annotations and consolidate frontend documentation.
38 KiB
Agent 交互与报告设计
本文维护供水前端 Agent 对话、正式调查报告和展开阅读的功能、布局与业务交互。组件基础、配色、材质、排版和无障碍样式统一遵循 样式设计指南,阶段验证结果见 实现记录。
Agent 相关弹窗、面板及菜单统一保持本地 shadcn/ui 设计,具体外观规则由样式设计指南维护。本文规定的历史全屏、展开阅读、审批和主题管理等布局均遵循该规则。
Intelligent UI 的目标
本文中的 Intelligent UI 参考 ChatGPT Intelligent UI:回答根据内容选择交互呈现,用户在阅读中探索数据、核查来源并继续提问。Vercel AI Elements 和 shadcn/ui 提供组件与布局参考,功能通过本项目本地组件实现。
当前落地为“左侧对话 + 主工作区”。聊天回答与正式调查报告共用指标、图表、表格、证据、定位和资料表单。复杂内容由用户点击展开到主工作区;调查状态、结论边界、证据、审批和版本仍由 Server 保存的事实驱动。模型只在注册组件中选择呈现方式。
功能梳理
以当前组件、回调和消息契约核对功能,再决定它们出现的位置,不继承原有界面分区。
| 功能组 | 已有能力 | 新布局中的位置 |
|---|---|---|
| 会话管理 | 新建、历史加载、重命名、删除、折叠和关闭 | 顶部会话栏,历史通过独立窗口按需打开 |
| 上下文 | 会话标题、主题选择及管理 | 主题收于助手导航区;会话标题独占下方宽度,最多两行 |
| 输入 | 多行文字、引用报告或任务、语音输入、草稿 | 底部统一输入区,空会话使用独立欢迎状态 |
| 模型与权限 | 模型选择、审批模式 | 输入组件底栏,保留当前选项反馈 |
| 运行控制 | 停止、运行中引导、排队消息、投递方式和未消费消息撤回编辑 | 输入组件顶部的紧凑队列与底栏发送方式 |
| 消息阅读 | 流式文字、Markdown、历史恢复、滚动跟随 | 主阅读流,用户消息与助手回复分层 |
| 过程与状态 | 执行进度、工具结果、待办、错误、连接状态 | 回复内的过程区域及顶部真实连接状态 |
| 人工参与 | 权限审批、问题回答和跳过、补充资料 | 对应回复内保留可操作表单,确认前不执行 |
| 分析结果 | 指标、表格、折线和柱状图、证据 | 回复中的交互内容,可搜索、排序、选点、筛选序列及已加载区间 |
| 展开阅读 | 聊天回答与正式报告进入主工作区 | 明确点击进入,保留唯一组件实例、筛选、表单草稿和阅读位置 |
| 数据浏览 | 指标、数据点、表格、证据 | 展示与本地查看;不提供行勾选、分析篮或组件追问 |
| 正式报告 | 当前结论、结论边界、证据、缺口、待办、审批与历史版本 | 固定事实区与可选交互分析模块组合 |
| 地图联动 | 定位实际要素、显示定位结果 | 对应内容内的明确按钮 |
| 回复工具 | 复制正文及交互摘要、朗读和选段朗读 | 回复底部低强调操作及文字选择入口 |
| 任务协作 | 任务引用、报告轮次、协作问答模式 | 输入引用区和回复依据,保留协作语义 |
普通用户的阅读路径为:确认当前项目,提出问题,阅读回答,核查来源,再按需要定位地图或补充资料。审批和队列在有实际内容时出现,历史与处理过程按需展开。
任务协作以对应任务名称作为初始标题,随后由 Agent 根据任务名称与对话内容生成具体标题;生成失败或仅返回通用名称时保留现有标题。“任务协作”仅作为历史列表中的类型标记。旧的通用标题随历史分页和详情读取逐步补齐,保留手动重命名及原有顺序;标题更新不重载消息或打断当前对话。
运行中的输入区使用一个外框:顶部显示待处理消息,正文最多预览两行,溢出时提供“展开全文”;每条消息只保留正文、简短的处理方式和一个菜单。编辑、处理方式切换、关闭排队统一进入该菜单。底栏在生成期间用“引导 / 排队”替代暂时不能切换的模型选择,生成完成后恢复模型选择。右下角的同一个按钮在运行且输入为空时停止,有内容时发送追加消息,空闲时发送新消息。输入正文默认高 64px,随多行内容自动增高至视口高度的 24%,最多 160px;超出后在输入区内部滚动,清空后恢复 64px;队列单独限制滚动高度,工作台支持的窄屏和短窗口保留可见的输入操作。
1. 交互参考
AI Elements 基于 shadcn/ui,提供组合式的 AI 应用组件。它将对话容器、消息、输入、过程、来源和工具状态拆成独立组件,适合在同一条消息中呈现文字与交互内容。官方当前提示组件正在迁入 shadcn/ui;本项目维护本地源码,参考交互方式,按需要适配组件。本文不要求整体替换现有依赖。
| 官方参考 | 采用的设计方式 | 本项目对应内容 |
|---|---|---|
| Chatbot 示例 | 以消息阅读为主体,输入区独立,辅助操作低强调 | 左侧会话布局、空会话入口和回复操作 |
| Conversation | 自动跟随消息,离开底部后提供返回入口 | 保留本地滚动管理与“滚动到最新消息” |
| Message | 用户与助手分层,正文、流式 Markdown、操作栏组合 | 用户气泡、开放式助手正文、复制和朗读 |
| Prompt Input | 输入、模型、工具和发送组成同一个输入组件 | 统一输入面、权限模式、模型、语音、停止与发送 |
| Reasoning | 生成过程可展开,完成后收起 | 已有执行摘要与“查看处理过程” |
| Tool | 工具状态与输入、输出按需展开 | 真实执行进度、审批与用户问题 |
| Sources | 来源单独呈现,详情按需展开 | 来源名称、证据类别、记录时间及资料编号 |
| shadcn/ui Tabs | 同一内容的视图用键盘可操作的页签切换 | 图表折线、柱状、原始数据切换 |
用户消息与助手回复分层组织,图表、证据与资料输入按内容用途组合。交互内容表达已有数据和可执行动作,不用虚构指标或装饰性进度制造智能感。
2. 组件规则
| 区域 | 组件组合 | 展示与行为 |
|---|---|---|
| 消息列表 | AI Elements Conversation、Message、MessageContent |
用户右对齐,助手使用完整阅读宽度 |
| 助手标识 | 共享 AgentPersona、shadcn Badge |
角色、真实回复状态及交互内容标记 |
| 回复操作 | AI Elements MessageActions、MessageAction |
复制正文与结构化摘要,保留朗读能力 |
| 指标 | shadcn Card、CardContent |
名称、值、单位、来源;同组指标使用紧凑对照条,提问入口采用有名称的图标按钮 |
| 图表 | Card、Tabs、Collapsible、现有图表渲染器 |
折线、柱状、数据三种视图;范围筛选按需展开,收起时仍显示已选范围 |
| 表格 | 本地 shadcn/ui Table 组件组合 |
列头、标题、数值、键盘可达的滚动容器 |
| 证据 | Collapsible、Button、Badge |
收起时可读来源与类别,展开显示完整摘要和编号 |
| 地图定位 | Button、位置图标 |
由用户点击触发,显示依据和实际定位结果 |
| 补充资料 | Input、Textarea、DateTimeField、Button |
从空值开始,明确必填和提交状态 |
| 历史对话 | Dialog、Input、会话列表 |
跨主题标题及正文搜索、时间分组、游标分页与会话操作 |
| 模型与主题 | DropdownMenu |
模型选择、主题归类与管理;数据权限跟随当前业务项目 |
| 报告目录 | nav、Button |
展开阅读时固定于阅读区顶部,仅显示实际章节;支持键盘跳转和滚动位置提示 |
| 工作区分栏 | ResizablePanelGroup、ResizablePanel、ResizableHandle |
Agent 与主工作区、地图与报告均可拖拽;分隔线可通过 Tab 聚焦,方向键及 Home / End 调整宽度 |
尺寸、圆角和交互状态按样式设计指南选用共享变体。尚未接入的附件、网页搜索和回答重试不展示可点击占位按钮。
3. 布局
桌面
┌───────────────────────┬──────────────────────────────────────┐
│ Agent 对话 │ 主工作区 │
│ 会话 / 上下文 │ 默认地图 │
│ 消息、交互摘要 │ 点击展开 → 报告与分析 │
│ 待答问题与权限审批 │ 宽度足够 → 地图对照 / 专注阅读 │
│ 队列摘要 / 引用 / 输入│ 宽度不足 → 查看地图 / 返回报告 │
└───────────────────────┴──────────────────────────────────────┘
主工作区可用宽度至少 960px 时开放地图与报告双列;较窄窗口在地图与报告之间切换。地图实例保留,不重新初始化。手机只显示当前阅读面;展开时保留原抽屉内容实例,收起后恢复。
2026-10-21 分栏实现更新:采用 shadcn/ui Resizable,通过本地 resizable.tsx 封装 react-resizable-panels v4。外层直接承载 Agent 和主工作区,替代手写 Pointer Events 拖拽;内层直接承载地图和报告,替代固定的双列 Grid。
Agent 保留 400px 最小宽度与按窗口计算的最大宽度,上限 640px。收起、临时缩窄窗口及恢复桌面后沿用本次页面内的用户选择。地图与正式报告默认等分,每栏至少 360px;已有分析成果沿用每栏至少 600px 的限制。切换专注阅读后再次分栏,恢复上次调整的比例。手机隐藏分隔线,继续使用抽屉和地图 / 报告切换。尺寸记忆保存在当前页面内,不写入持久化存储。
两级分栏的容器保持挂载,地图 canvas 跟随实际容器尺寸更新;报告内容继续通过单实例移动保留草稿和阅读位置。手柄使用浅灰细线与可见拖拽标记,键盘焦点使用主题蓝色轮廓;连续调宽不附加布局过渡动画。
展开操作移动同一个内容实例,避免两份表单、重复提交和草稿分歧;关闭或 Escape 后回到原入口并恢复键盘焦点。阅读位置随文档保留。报告版本改变时切换到该版本自己的内容状态。会话或报告卸载时关闭对应工作区。
Agent 面板
├─ 会话栏:助手标识 / 连接状态 / 新建与历史 / 折叠或关闭
├─ 上下文条:会话标题 / 主题
├─ 可滚动消息区
│ ├─ 用户问题
│ └─ 助手回复
│ ├─ 角色和真实生成状态
│ ├─ 正文与指标、趋势、表格
│ ├─ 证据、地图入口、资料表单
│ ├─ 可展开的处理过程
│ └─ 复制与朗读
└─ 输入区:引用 / 多行输入 / 权限、模型、语音、发送或停止
纯指标的双列 Stack 合并为紧凑摘要区,容器宽度达到 240px 即可并排;名称、原始数值、单位和来源完整保留,不用省略号截断。指标仅展示名称、数值、单位和来源。混合内容的双列仍使用 440px 断点。助手正文直接进入消息流,证据按需折叠,补充表单保留独立操作区;表面与间距统一引用样式设计指南。
图表首先显示标题、视图切换、序列和趋势。范围选择默认收起,展开后可选择起止点及重置;收起只改变展示,不取消已选范围。序列按钮使用低强调色,图例颜色保留数据对应关系;至少一条序列可见。数据点的各序列值分行对齐,保留原始精度。
图表通过“放大查看”打开独立浮窗,标题栏的“最大化窗口”按钮铺满可用视口,保留还原与关闭入口。内容宽度达到640px时,主图占据剩余空间,序列与摘要放在右侧;较窄窗口将资料放在主图下方独立滚动。展开、最大化与还原共享视图、序列显隐及表格筛选状态,调整窗口尺寸沿用同一图表实例。时间轴集中标注UTC+8,采样详情保留完整日期与偏移。工作台在独立层叠上下文内排列业务面板,浮窗与后续打开的菜单、对话框通过Portal显示。
正式报告展开后采用连续文档排版,章节之间使用细分隔线。目录跟随阅读区滚动,包含实际存在的结论、分析、调查进展、待办、处置、缺口、脉络、依据、时间线和版本。目录使用导航语义,点击或键盘激活后立即滚动并将焦点交给目标章节;手机目录可横向滚动。接近文档末尾、目标无法滚至顶部时,保留主动选择的章节标记,直到用户再次滚动。该导航只改变阅读位置,不控制任务执行或审批。
空会话采用“简短引导、首次输入、推荐问题”的顺序,整组在 Agent 面板内横向居中,放在会话栏下方可用区域的中部。居中容器最多 600px,桌面内边距 24px,手机左右内边距 16px;短屏内容超过可用高度时从顶部排列并允许滚动。判断依据是当前会话有无消息,不取决于帐号是否保存其他历史会话。加载历史、引用任务或已有工具权限审批、结构化结果时保留正常阅读区,不覆盖为欢迎页。
输入文字区初始高度 64px,按内容增长至视口允许的高度。首次发送后同一个输入组件回到底部;新建空会话后恢复居中布局。使用 motion/react 的位置布局动画处理这两种状态,沿用项目的 180ms 缓动,不缩放输入文字,也不对 Resizable 连续调宽添加动画。系统开启减少动态效果时直接切换位置。表单实例和草稿在布局变化时保留。
推荐由现有接口生成,排列在首次输入框下方,使用低强调的圆角按钮,窄屏自动换行显示完整问题,实际来源仍可通过 hover 或键盘焦点提示查看。点击发送完整原始问题。加载或生成失败时显示简短状态,也不影响普通输入。材质与边界复用共享样式,输入底栏保留现有操作。
Agent 形象基于 Obsidian 原版动画资源,通过本地定制的 obsidian-water-v1.riv 使用已确认的 02「冰水蓝」材质并增加离线水纹,以高遮蔽度的浅冰蓝底色和白色高光保留柔和羽化、流动反射与不规则边缘水纹。完整视觉与交互规格见 Persona 设计。默认形象与悬浮入口使用 64 × 64px,画布填满点击范围;入口距地图左侧、顶部导航下沿均为 12px,由同一层内边距控制。桌面及手机面板标题栏中的形象也使用 64px,手机地图入口使用 40px。三处通过同一个 AgentPersona 组件显示,保留原版资源自身的羽化留白。悬浮形象不附加状态文案、状态点、箭头、卡片或按钮底圈。完整业务状态继续通过按钮无障碍名称与原生悬停提示提供,点击或 Enter / Space 展开对话。
标题区分为导航与标题两层。导航行高 80px:左侧为 64px persona,其右侧首行并列助手名称与连接状态,状态位于名称右侧;下方间隔 6px 放置主题下拉,使用文件夹图标与名称,不再另列“主题”标签。连接状态保留共享状态点和文字,主题按钮使用本地 Button 的 outline / sm 变体,高 32px,使用文件夹和 Lucide 上下切换箭头。右侧集中放置新建、历史及折叠或关闭按钮,命中范围均为 40px。导航与会话标题之间只保留一条本地 Separator,使用 1px、bg-border/40 的低对比度分界线。默认空白会话不渲染“新对话”占位标题,也不保留空标题行。有实际会话时,标题区四周留白 12px,只显示当前会话标题,独占宽度、最多两行,不再增加下边框。长主题名在导航剩余空间内收缩,完整名称通过提示与可访问描述保留;320px 手机宽度下不挤压三个操作按钮。
在线动画由 Rive WebGL2 播放原资源的 default 状态机。沿用原生 thinking、listening、speaking 和 hover 控制项,状态过渡及水纹细节由资源自身完成。原版公开组件可见 AI Elements Persona 源码;图形制作数据位于运行资源中,可编辑设计文件是 .rev,见 作者的定制说明。已移除之前自行生成球缘曲线、光带和局部高光的实现,也移除改写原版明暗的 CSS 滤镜。配色直接写入 Rive 材质,暗部保持蓝色倾向,高光使用白色。
离线通过同一 Rive 资源中的 asleep 状态呈现“静水待机”:关闭外围三层光圈,保留完整蓝色球体及内部柔光的低速、小幅度流动。在线与离线切换保持同一个动画实例,通过资源内的状态混合衔接,恢复连接后回到在线光圈与节奏。参数和图层说明统一维护在 Agent 动画资源说明。首次加载、加载失败和系统开启减少动态效果时显示从当前资源渲染的在线或离线静态帧,离线静态帧同样不带外围光圈;兜底形象与按钮功能持续可用。
鼠标悬停沿用原生 hover 动画和光圈尺寸;进入、移动、离开坐标通过共享组件交给 Rive 原生监听,使白色高光跟随鼠标局部移动,避免只开 hover 却使反射固定在中心。移出后恢复常态。球体组件移除 Motion,取消按压缩放、弹簧回弹和明暗变化;触摸按下不触发额外动画。点击、触摸轻点及 Enter / Space 继续展开对话,离线时同样可用。系统开启减少动态效果时显示静态帧,不初始化 Rive。强制颜色模式显示高对比圆形轮廓,保留键盘操作。球体动画与面板布局独立,不对 Resizable 连续调宽增加动画。
渲染生命周期继续遵守 Rive 内存问题记录:延迟一帧初始化,元素离开视口或页面隐藏时卸载渲染实例,不绑定 View Model;仅缓存不可变的 .riv 字节,展开、折叠和不同入口复用一次成功下载。失败下载不永久缓存,后续挂载可重试。动态组件准备完成前保留本地静态帧,原生进入动画在显示切换前完成。静态帧与动画通过 180ms CSS 透明度渐变衔接,结束后才隐藏静态帧,避免首次加载瞬间切换造成的跳动;画布的位置与尺寸始终固定。本轮没有新增依赖,也没有恢复已知存在内存问题的颜色绑定。
Persona 资源与生命周期
Persona 的视觉、尺寸、离线状态、悬停、缓存和再生成统一维护在 Persona 设计。聊天面板与悬浮入口复用同一资源和指针通路,保留静态降级、减少动态效果和可见性卸载。
历史 Rive 内存问题的触发条件与修复依据见 排查记录;不根据历史记录重建已经替换的悬停通路或 View Model 绑定。
历史窗口、缓存与后台会话
“主题”参考 ChatGPT Projects 的会话组织方式,作为会话组织单元,用于归集相关事件和问题;与决定数据权限的业务项目分开。Agent 的主题下拉参考 shadcn TeamSwitcher 模板的起始对齐、触发器宽度与最小菜单宽度,配合本地 DropdownMenuRadioGroup 表示主题单选。菜单标注“切换主题”,主题列表独立滚动,新建与管理操作保留在底部;支持未分类、主题选择、新建和管理;原无处理逻辑的“新建项目”入口移除。Agent 默认访问当前工作台业务项目的数据,移除聊天面板中的“个人/项目数据”切换入口及前端个人会话分支。数据访问权限由项目身份和服务端授权决定,后续按角色限制可访问范围,主题选择不改变数据权限;业务项目切换仍从工作台入口进入。选择主题开启该主题的新对话,当前会话草稿和后台生成继续保留;新建对话沿用当前主题。主题名可修改,删除主题时会话保留为未分类;历史行操作可将已有会话移入其他主题或移出为未分类。主题列表内存缓存 5 分钟,登录和业务项目隔离,并发复用。旧会话默认未分类,不移动现有业务数据。本轮主题用于组织记录,不自动合并其他会话上下文、共享指令或附件。
主题新建、重命名、管理与删除确认使用标准 DialogHeader、DialogDescription、Input 和 DialogFooter。表单显示名称标签、80 字符限制、错误与取消/提交按钮;管理页使用可滚动的平面列表,每行保留重命名与删除入口,底部提供新建与完成。重命名和删除进入有明确标题的独立步骤,删除前确认会话保留规则。打开表单聚焦名称输入,打开管理页聚焦新建入口;失败保留输入,关闭后恢复主题按钮焦点。主题增删改先完成共享列表读取,再更新服务端与缓存,防止旧列表请求晚返回覆盖刚创建或修改的主题。
历史按钮打开独立模态窗口,桌面最大宽度 760px、高度不超过视口的 80%;小于 640px 时使用全屏窗口,保留安全区和独立滚动。窗口包含当前业务项目、标题及正文搜索、主题筛选、时间分组、会话状态和关闭入口。标题最多两行,重命名和删除进入每行操作菜单,删除需明确确认。选择会话成功后关闭窗口,失败时保留当前聊天与列表并显示错误。关闭、Escape 及取消操作恢复触发按钮焦点;模态期间底层地图和通知不覆盖窗口。
会话列表每页 30 条,标题及可见消息正文搜索在服务端覆盖当前用户及当前业务项目下的全部主题及未分类记录,结果显示所属主题和正文命中摘要,输入防抖 250ms,按更新时间及 ID 排序;时间按浏览器本地时区分为今天、昨天、近 7 天和更早。窗口浏览期间保持条目顺序,运行状态原位更新;有新的排序结果时由用户点击更新。关闭窗口保留已加载页和搜索缓存。历史统一包含普通对话和手动任务协作,不展示后台执行会话。主题筛选独立于搜索词,默认“全部主题”,不随当前对话主题隐式收窄。
正文首次读取最近 40 条,向上滚动或点击“加载更早消息”继续读取。插入旧页保持当前可见消息的位置。用户向上阅读后停止自动跟随,点击返回最新消息恢复跟随。恢复流也使用最近消息页,客户端按稳定消息 ID 合并旧页和实时尾部,断线区间缺口通过分页补齐。服务端仍保留完整历史,续聊只发送本轮输入;UI 分页不截断原生会话和保存记录。当前磁盘存储仍整份读取 JSON,分页主要减少网络传输和浏览器渲染。
缓存属于当前登录生命周期,按业务项目隔离并跨工作台重挂载复用;退出登录后释放。历史列表和已读正文缓存 60 秒,授权项目列表 5 分钟,推荐问题 10 分钟,推荐生成失败缓存 30 秒。有效期内打开窗口和面板不重复请求。过期刷新保留已有内容,并发消费者共用请求,单个消费者关闭不取消共享请求。主动刷新及真实数据变更按需更新缓存,项目进入操作仍核验访问上下文。
推荐依据使用独立的近期会话页,历史搜索和翻页不改变输入。缓存摘要按活动 ID、标题、内容、状态及来源计算,单纯心跳时间变化不触发推理。生成新推荐时保留上一组问题。
推荐失败后,面板保持打开时在错误缓存到期后重试,同一轮最多请求三次;服务从离线恢复时立即重试失败项,也提供“重试推荐”入口。成功缓存继续复用,重试不改变输入草稿,模型目录尚未加载时不发送空模型请求。
Agent 面板、历史和主题窗口及正文阅读窗口共用选区复制处理,仅移除浏览器附加的末尾段落换行。正文内部段落、代码缩进、表格制表符与用户输入的有效换行保留;输入框沿用原生复制。
每个会话持有独立 Chat 实例、生成连接、草稿、引用、阅读位置和审批状态。切换历史或新建对话保留原会话后台生成;后台需要审批或回答时,通过历史入口提示返回处理。模型、项目头和凭据续期绑定原会话。后台浏览器动作返回 SESSION_NOT_ACTIVE,提示用户回到会话后重新请求;切换时取消原会话尚在执行的浏览器动作。切换业务项目由工作台统一处理,会话、主题及缓存按业务项目隔离。
头部在线状态由 Agent 公共 /health 的就绪结果独立决定,单次业务失败、提问等待、主动停止和新建对话不直接改为离线或在线。在线时每 15 秒探测,失败后按 1、2、4、8、15 秒退避,单次超时 5 秒;浏览器恢复联网、窗口聚焦或页面重新可见时立即重检。服务恢复后刷新初始化信息和当前会话的提问、输入队列,保留草稿与阅读位置。
已知会话的 Responses 流意外断开后,改用该会话的只读订阅恢复;订阅中断同样按 1 至 15 秒退避重连,合并权威消息尾部并保留已加载历史。重连不重发问题、不重启模型、不重做工具操作,也不将断流视为任务完成。权限失效、会话不存在、主动停止和所属工作台销毁时终止重连;切换到其他对话仍由原会话持有后台恢复连接。
4. 内容与状态
任务驱动的回答表达
按 Intelligent UI 的声明式组件路线增强当前对话:Agent 使用既有 Harness 与 present_answer 决定文字、指标、趋势、对照表、证据及补充表单的组合,前端负责本地交互和视觉层次。简单回答保留文字;说明和判断边界使用本地 shadcn/ui Alert 的图标、标题与正文组合,静态历史内容使用 note 语义,避免恢复会话时反复播报警告。
包含两类及以上可导航组件,且含表格、图表、补充表单或达到长内容标准时,回答上方出现“浏览回答”菜单,按实际组件显示类别和数量。选中项目在当前内容实例内滚动并交接键盘焦点;Escape 关闭菜单后回到触发按钮。导览沿用 DropdownMenu、Button、Badge,不切换页面、不重建图表或表单。只有一种可导航组件或内容较短时不增加导览。导航入口与内容类别摘要在窄屏保持紧凑,长标签自然换行。
图表保留折线、柱状和数据页签;范围筛选收进标题右侧的控件,所选非完整区间仍明确显示。数据点详情按需展开,点击图上数据点自动展开对应读数;键盘用户通过“查看数据点”及选择器完成同等操作。收起详情保留所选点。当前界面交互均只影响已加载数据;新查询与仿真仍走原业务工具。
消息标题区明确助手身份和真实生成状态。指标保留原始精度、单位与来源;证据继续区分事实和推断;资料表单通过 CardHeader、CardContent 划分说明和输入,提交是明确的主操作,失败保留填写内容。颜色、字体与表面沿用样式设计指南,交互状态不冒充业务状态。
本次无需新增 UI 协议、环境变量或数据库迁移。自由代码沙箱、跨会话保存控件状态和参数驱动的新数据查询属于后续能力;当前表单、筛选与选择在聊天和展开工作区之间移动时保留,历史恢复仍从已保存的回答结构重新建立控件。
后续的状态保存、压力历史探索与沙箱接入条件见 可持续分析工作区设计。该部分是未实现的提案,不能作为当前功能清单。
answer-ui@1 仍由严格参数校验与本地注册组件驱动。已有的 Stack、Section、Text、Metric、Table、Chart、Evidence、MapLocation、FollowUpForm 使用新外观。聊天继续使用现有 Responses 事件;正式报告增加可选 ui_blocks 字段,复用相同的内容块协议。实现契约见 本地交互式回答。
处理过程统一位于回复正文下方。生成中,文字与回答内容块在前,公开执行摘要、标记为过程的内容块和待办在后;最终答复到达或回复流结束后,过程收起为底部“查看处理过程”,入口位于语音播放左侧,没有 final_answer 标记的历史回复也遵循同一布局。最终答复明确引用的回答内容块留在主阅读流,其他记录进入处理过程。待回答问题、权限审批和失败状态在正文下方保持可见,不能因回复结束而被隐藏。这里借鉴 Reasoning 的折叠行为,呈现的数据是服务端已发布的过程信息,不额外生成思考文本,也不根据耗时推算完成比例。
最终答复到达后,正文、回复状态与语音/复制操作在同一次交接中切换,网络流的后续收尾不再改变这条回复的展示阶段。输入框仍根据真实执行状态接受引导或排队消息。过程复用生成时的容器和步骤实例,保留工具详情的展开状态;无论用户是否向上滚动或查看过工具详情,交接后默认收起过程并优先让结果正文可读;用户可通过“查看处理过程”重新展开。历史回放直接显示保存的结果,不重新播放交接。
补充问题打断后继续执行时,依据提问记录的 message_id 和补充回答的 delivery.native_message_id 将前后过程归到续接答复下方;连续补充时沿同一关联链顺序归组。没有正文的旧过程消息不再单独占位,原有正文和用户补充回答仍保留。尚未出现续接答复、历史分页缺少关联消息、仍有待回答问题或审批、关联之间出现新用户请求时,保留原位置。该归组仅影响展示,不改原始记录或消息标识。
生成中、补充后续接和历史恢复共用一个处理过程容器,边框、背景和内边距保持一致;各段执行记录合并为一份列表,不再嵌套另一张“执行进度”卡片。步骤显示身份包含来源消息,避免前后轮次的同名步骤互相覆盖;生成时统一控制整个过程的最近三项与展开全部,完成后由底部入口统一折叠。
已提交的回答以原生用户消息 ID 保存纯净文本和 data-interaction_reply 快照,首屏即可还原同一张“已回答”卡片并归组前后过程,不等待独立提问接口。该接口返回较新修订后更新投递状态和重试操作。旧历史由 Agent 按所属会话中已保存的投递 ID 补齐相同表示,不通过文本前缀猜测对应关系,也不改写历史文件。给模型的“用户提交的提问回复”协议前缀只用于推理输入。
提问等待和续接失败不禁用消息发送。生成中或存在未解决的提问/续接时,输入区提供“引导当前任务”和“排队处理”;消息通过既有 Responses 输入接口进入原生收件箱。没有宿主执行轮次时只保存输入,不自行启动模型,也不把消息当作提问表单的答案。读取续接状态时,服务端可以依据已消费的原生回答和已完成的原生输出恢复丢失的确认;仅有部分文字或原生状态不可用时保留未确认状态。若输入在入队前被明确告知当前轮次已结束,客户端刷新状态后作为新一轮发送;其他错误不自动重发。
证据类别明确区分查询记录、用户提供、分析推断和演练数据。地图定位的按钮结果以实际回调为准;资料表单提交后只表示发送消息,业务证据是否保存取决于后端实际结果。最终回复不等于后台调查任务完成。
5. 实现边界
保留 Vite 和 React SPA。通用 AI 展示组件位于 src/shared/ai-elements/,基础组件位于 src/shared/ui/;消息业务组合位于 src/features/agent/components/,结构化回答位于 src/features/agent/answer-ui/。
不引入 Next.js 路由、服务端组件或第二套聊天接口。地图控制器、会话存储和审批流程沿用已有实现。报告内容扩展同时进入 Agent 校验、Server 校验、现有报告 JSON 存储和 OpenAPI。组件按需加入本地源码,避免批量覆盖已定制的共享组件。AI Elements 负责展示组合,现有 Responses transport 负责消息传输,两者的职责分开。
6. 响应式与业务验收
桌面验证 1280px 及以上窗口,并检查面板宽度 400px、640px 的真实布局;手机验证 320px、375px。手机 Agent 默认打开全高抽屉,输入区进入正常布局,阅读内容不藏在悬浮输入框下面;抽屉仍可手动调低查看地图。混合内容在手机上使用单列,短指标按容器宽度保留双列。输入、发送、模型菜单、证据展开和滚动返回均需可操作。
本轮聚焦验收包括图表页签与方向键、证据键盘展开、历史恢复、表单提交、复制回复、流式结束和面板缩放。检查文字与背景对比度、减少动态效果和强制颜色模式。运行 lint、类型检查、相关单测、聚焦浏览器测试;依赖变化额外运行构建。浏览器演练数据必须标明来源,截图不代表真实业务核验。
当前文档描述本轮目标与实现约定,实际通过的检查和预览截图以交付记录为准。
7. 交互规则与范围
数据组件按展示与本地浏览组织:短内容不附加目录;单个证据或补充表单不叠加分组标题与固定提示;来源已在证据卡中显示时,报告外层只列出其余依据。调查脉络节点保留详情、缩放和地图定位,不提供节点追问按钮。
| 内容 | 本轮实现 | 数据与操作边界 |
|---|---|---|
| 指标 | 值、单位、来源 | 不补造变化率、单位或精度 |
| 表格 | 搜索、三态排序 | 只处理当前数据;不提供勾选与引用操作 |
| 图表 | 折线 / 柱状 / 数据,序列显隐,加载区间,点击或键盘选点 | 最少保留一条序列;区间不触发查询或重算 |
| 证据 | 来源、类别、时间、编号,展开与类别筛选 | 正式报告使用已保存证据覆盖生成的摘要、来源和类别 |
| 地图 | 显式定位,地图对照或切换 | 使用真实定位结果与失败反馈 |
| 表单 | 空白初始值、必填校验、提交中禁用、失败保留 | 聊天表单主动发送;报告表单先带入对话,确认后发送 |
| 任务与报告对话 | 输入区引用卡片、详情、移除 | 保留专用任务、报告和补充表单入口;通用数据组件不产生引用 |
| 历史内容 | 固定报告事实可读,不支持的块显示摘要 | 降级不执行未知组件或事件 |
本轮未包含参数重算、新数据查询控件、附件上传、导出、报告版本差异比较。后续扩展时需要独立定义参数校验、数据来源和执行反馈;不能把本地筛选当作重新分析。后台任务完成、业务审批和证据写入继续以各自服务端状态为准。
8. 正式报告契约
InvestigationReport.ui_blocks 可省略;每项包含 block: AnswerUiBlock 和 evidence_refs: string[]。最多 8 块,总 UTF-8 JSON 不超过 400000 字节;单块完整序列化结果不超过 100000 个 JavaScript UTF-16 代码单元,最多 48 节点、深度 12。每块绑定至少一条报告证据,Evidence 节点只能引用该块的依据。Server 发布时再检查这些证据确属当前任务。
固定报告字段不变:阶段、结果、结论、边界、数据缺口、证据和建议仍独立校验。新字段通过原有报告 JSON 保存,跟随 revision 与 execution_generation 读取;请求幂等沿用原有机制。旧报告缺省为空,不因缺省字段而产生虚假的报告更新通知。无需数据库表或环境变量迁移。
组件参数唯一来源为前端 catalog.ts,导出到 Agent 与 Server;跨字段约束在三端分别验证。Agent publish_task_report 使用正式报告通道,聊天 present_answer 使用聊天通道。实现与生成命令见 本地交互式回答。
任务业务审核统一从 header 的“状态和提醒”进入对应任务详情,由关联的负责节点或动作卡承接人工审核。会话只保留任务引用、讨论和消息,不注入固定的任务状态、人工事实或业务审核表单;调查详情继续负责草稿编辑、批准、拒绝及执行回执。工具执行权限审批和用户问题仍按会话交互协议处理。
调查报告与自由对话的分工
后台调查的固定问答放在右侧调查报告的“补充回答”中,支持选项、自定义文字、提交状态和历史回答。任务通知打开该报告;提交直接保存到原任务并接续调查,无需创建或发送左侧聊天消息。数据缺口旁的“回答当前调查问题”定位到报告内待答表单。
左侧 Agent 保留自由讨论、追问和进一步分析。“Agent 协作”和“讨论此缺口”是明确的讨论入口;固定任务回答不经过这些入口转发。