feat: add project-aware agent workspace
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
# Agent 交互与报告设计
|
||||
|
||||
本文维护供水前端 Agent 对话、正式调查报告和展开阅读的功能、布局与业务交互。组件基础、配色、材质、排版和无障碍样式统一遵循 [样式设计指南](style-design-guide.md),阶段验证结果见 [实现记录](history/agent-chat-ui-implementation-notes.md)。
|
||||
|
||||
Agent 相关弹窗、面板及菜单统一保持本地 shadcn/ui 设计,具体外观规则由样式设计指南维护。本文规定的历史全屏、展开阅读、审批和主题管理等布局均遵循该规则。
|
||||
|
||||
## Intelligent UI 的目标
|
||||
|
||||
本文中的 Intelligent UI 参考 [ChatGPT Intelligent UI](https://help.openai.com/en/articles/20001598-intelligent-ui-in-chatgpt):回答根据内容选择交互呈现,用户在阅读中探索数据、核查来源并继续提问。Vercel AI Elements 和 shadcn/ui 提供组件与布局参考,功能通过本项目本地组件实现。
|
||||
|
||||
当前落地为“左侧对话 + 主工作区”。聊天回答与正式调查报告共用指标、图表、表格、证据、定位和资料表单。复杂内容由用户点击展开到主工作区;调查状态、结论边界、证据、审批和版本仍由 Server 保存的事实驱动。模型只在注册组件中选择呈现方式。
|
||||
|
||||
## 功能梳理
|
||||
|
||||
以当前组件、回调和消息契约核对功能,再决定它们出现的位置,不继承原有界面分区。
|
||||
|
||||
| 功能组 | 已有能力 | 新布局中的位置 |
|
||||
| --- | --- | --- |
|
||||
| 会话管理 | 新建、历史加载、重命名、删除、折叠和关闭 | 顶部会话栏,历史通过独立窗口按需打开 |
|
||||
| 上下文 | 会话标题、主题选择及管理 | 主题收于助手导航区;会话标题独占下方宽度,最多两行 |
|
||||
| 输入 | 多行文字、引用报告或任务、语音输入、草稿 | 底部统一输入区,空会话使用独立欢迎状态 |
|
||||
| 模型与权限 | 模型选择、审批模式 | 输入组件底栏,保留当前选项反馈 |
|
||||
| 运行控制 | 停止、运行中引导、排队消息、投递方式和未消费消息撤回编辑 | 输入组件顶部的紧凑队列与底栏发送方式 |
|
||||
| 消息阅读 | 流式文字、Markdown、历史恢复、滚动跟随 | 主阅读流,用户消息与助手回复分层 |
|
||||
| 过程与状态 | 执行进度、工具结果、待办、错误、连接状态 | 回复内的过程区域及顶部真实连接状态 |
|
||||
| 人工参与 | 权限审批、问题回答和跳过、补充资料 | 对应回复内保留可操作表单,确认前不执行 |
|
||||
| 分析结果 | 指标、表格、折线和柱状图、证据 | 回复中的交互内容,可搜索、排序、选点、筛选序列及已加载区间 |
|
||||
| 展开阅读 | 聊天回答与正式报告进入主工作区 | 明确点击进入,保留唯一组件实例、筛选、表单草稿和阅读位置 |
|
||||
| 内容追问 | 指标、数据点、表格行、证据 | 带来源的可删除引用;正式报告另带版本和轮次;确认后发送 |
|
||||
| 正式报告 | 当前结论、结论边界、证据、缺口、待办、审批与历史版本 | 固定事实区与可选交互分析模块组合 |
|
||||
| 地图联动 | 定位实际要素、显示定位结果 | 对应内容内的明确按钮 |
|
||||
| 回复工具 | 复制正文及交互摘要、朗读和选段朗读 | 回复底部低强调操作及文字选择入口 |
|
||||
| 任务协作 | 任务引用、报告轮次、协作问答模式 | 输入引用区和回复依据,保留协作语义 |
|
||||
|
||||
普通用户的阅读路径为:确认当前项目,提出问题,阅读回答,核查来源,再按需要定位地图或补充资料。审批和队列在有实际内容时出现,历史与处理过程按需展开。
|
||||
|
||||
运行中的输入区使用一个外框:顶部显示待处理消息,正文最多预览两行,溢出时提供“展开全文”;每条消息只保留正文、简短的处理方式和一个菜单。编辑、处理方式切换、关闭排队统一进入该菜单。底栏在生成期间用“引导 / 排队”替代暂时不能切换的模型选择,生成完成后恢复模型选择。右下角的同一个按钮在运行且输入为空时停止,有内容时发送追加消息,空闲时发送新消息。输入正文默认高 64px,随多行内容自动增高至视口高度的 24%,最多 160px;超出后在输入区内部滚动,清空后恢复 64px;队列单独限制滚动高度,工作台支持的窄屏和短窗口保留可见的输入操作。
|
||||
|
||||
## 1. 交互参考
|
||||
|
||||
[AI Elements](https://elements.ai-sdk.dev/) 基于 shadcn/ui,提供组合式的 AI 应用组件。它将对话容器、消息、输入、过程、来源和工具状态拆成独立组件,适合在同一条消息中呈现文字与交互内容。官方当前提示组件正在迁入 shadcn/ui;本项目维护本地源码,参考交互方式,按需要适配组件。本文不要求整体替换现有依赖。
|
||||
|
||||
| 官方参考 | 采用的设计方式 | 本项目对应内容 |
|
||||
| --- | --- | --- |
|
||||
| [Chatbot 示例](https://elements.ai-sdk.dev/examples/chatbot) | 以消息阅读为主体,输入区独立,辅助操作低强调 | 左侧会话布局、空会话入口和回复操作 |
|
||||
| [Conversation](https://elements.ai-sdk.dev/components/conversation) | 自动跟随消息,离开底部后提供返回入口 | 保留本地滚动管理与“滚动到最新消息” |
|
||||
| [Message](https://elements.ai-sdk.dev/components/message) | 用户与助手分层,正文、流式 Markdown、操作栏组合 | 用户气泡、开放式助手正文、复制和朗读 |
|
||||
| [Prompt Input](https://elements.ai-sdk.dev/components/prompt-input) | 输入、模型、工具和发送组成同一个输入组件 | 统一输入面、权限模式、模型、语音、停止与发送 |
|
||||
| [Reasoning](https://elements.ai-sdk.dev/components/reasoning) | 生成过程可展开,完成后收起 | 已有执行摘要与“查看处理过程” |
|
||||
| [Tool](https://elements.ai-sdk.dev/components/tool) | 工具状态与输入、输出按需展开 | 真实执行进度、审批与用户问题 |
|
||||
| [Sources](https://elements.ai-sdk.dev/components/sources) | 来源单独呈现,详情按需展开 | 来源名称、证据类别、记录时间及资料编号 |
|
||||
| [shadcn/ui Tabs](https://ui.shadcn.com/docs/components/radix/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. 布局
|
||||
|
||||
```text
|
||||
桌面
|
||||
┌───────────────────────┬──────────────────────────────────────┐
|
||||
│ Agent 对话 │ 主工作区 │
|
||||
│ 会话 / 上下文 │ 默认地图 │
|
||||
│ 消息、交互摘要 │ 点击展开 → 报告与分析 │
|
||||
│ 待答问题与权限审批 │ 宽度足够 → 地图对照 / 专注阅读 │
|
||||
│ 队列摘要 / 引用 / 输入│ 宽度不足 → 查看地图 / 返回报告 │
|
||||
└───────────────────────┴──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
主工作区可用宽度至少 960px 时开放地图与报告双列;较窄窗口在地图与报告之间切换。地图实例保留,不重新初始化。手机只显示当前阅读面;展开时保留原抽屉内容实例,收起后恢复。
|
||||
|
||||
2026-10-21 分栏实现更新:采用 [shadcn/ui Resizable](https://ui.shadcn.com/docs/components/radix/resizable),通过本地 [resizable.tsx](../src/shared/ui/resizable.tsx) 封装 `react-resizable-panels` v4。外层直接承载 Agent 和主工作区,替代手写 Pointer Events 拖拽;内层直接承载地图和报告,替代固定的双列 Grid。
|
||||
|
||||
Agent 保留 400px 最小宽度与按窗口计算的最大宽度,上限 640px。收起、临时缩窄窗口及恢复桌面后沿用本次页面内的用户选择。地图与正式报告默认等分,每栏至少 360px;已有分析成果沿用每栏至少 600px 的限制。切换专注阅读后再次分栏,恢复上次调整的比例。手机隐藏分隔线,继续使用抽屉和地图 / 报告切换。尺寸记忆保存在当前页面内,不写入持久化存储。
|
||||
|
||||
两级分栏的容器保持挂载,地图 canvas 跟随实际容器尺寸更新;报告内容继续通过单实例移动保留草稿和阅读位置。手柄使用浅灰细线与可见拖拽标记,键盘焦点使用主题蓝色轮廓;连续调宽不附加布局过渡动画。
|
||||
|
||||
展开操作移动同一个内容实例,避免两份表单、重复提交和草稿分歧;关闭或 Escape 后回到原入口并恢复键盘焦点。阅读位置随文档保留。报告版本改变时切换到该版本自己的内容状态。会话或报告卸载时关闭对应工作区。
|
||||
|
||||
|
||||
```text
|
||||
Agent 面板
|
||||
├─ 会话栏:助手标识 / 连接状态 / 新建与历史 / 折叠或关闭
|
||||
├─ 上下文条:会话标题 / 主题
|
||||
├─ 可滚动消息区
|
||||
│ ├─ 用户问题
|
||||
│ └─ 助手回复
|
||||
│ ├─ 角色和真实生成状态
|
||||
│ ├─ 正文与指标、趋势、表格
|
||||
│ ├─ 证据、地图入口、资料表单
|
||||
│ ├─ 可展开的处理过程
|
||||
│ └─ 复制与朗读
|
||||
└─ 输入区:引用 / 多行输入 / 权限、模型、语音、发送或停止
|
||||
```
|
||||
|
||||
纯指标的双列 `Stack` 合并为紧凑摘要区,容器宽度达到 240px 即可并排;名称、原始数值、单位和来源完整保留,不用省略号截断。指标提问按钮放在名称旁,减少单独操作行。混合内容的双列仍使用 440px 断点。助手正文直接进入消息流,证据按需折叠,补充表单保留独立操作区;表面与间距统一引用样式设计指南。
|
||||
|
||||
图表首先显示标题、视图切换、序列和趋势。范围选择默认收起,展开后可选择起止点及重置;收起只改变展示,不取消已选范围。序列按钮使用低强调色,图例颜色保留数据对应关系;至少一条序列可见。数据点的各序列值分行对齐,保留原始精度。
|
||||
|
||||
正式报告展开后采用连续文档排版,章节之间使用细分隔线。目录跟随阅读区滚动,包含实际存在的结论、分析、调查进展、待办、处置、缺口、脉络、依据、时间线和版本。目录使用导航语义,点击或键盘激活后立即滚动并将焦点交给目标章节;手机目录可横向滚动。接近文档末尾、目标无法滚至顶部时,保留主动选择的章节标记,直到用户再次滚动。该导航只改变阅读位置,不控制任务执行或审批。
|
||||
|
||||
空会话采用“简短引导、首次输入、推荐问题”的顺序,整组在 Agent 面板内横向居中,放在会话栏下方可用区域的中部。居中容器最多 600px,桌面内边距 24px,手机左右内边距 16px;短屏内容超过可用高度时从顶部排列并允许滚动。判断依据是当前会话有无消息,不取决于帐号是否保存其他历史会话。加载历史或已有任务状态、审批、结构化结果时保留正常阅读区,不覆盖为欢迎页。
|
||||
|
||||
输入文字区初始高度 64px,按内容增长至视口允许的高度。首次发送后同一个输入组件回到底部;新建空会话后恢复居中布局。使用 `motion/react` 的位置布局动画处理这两种状态,沿用项目的 180ms 缓动,不缩放输入文字,也不对 Resizable 连续调宽添加动画。系统开启减少动态效果时直接切换位置。表单实例和草稿在布局变化时保留。
|
||||
|
||||
推荐由现有接口生成,排列在首次输入框下方,使用低强调的圆角按钮,窄屏自动换行显示完整问题,实际来源仍可通过 hover 或键盘焦点提示查看。点击发送完整原始问题。加载或生成失败时显示简短状态,也不影响普通输入。材质与边界复用共享样式,输入底栏保留现有操作。
|
||||
|
||||
Agent 形象基于 [Obsidian 原版动画资源](https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/obsidian-2.0.riv),通过本地定制的 `obsidian-water-v1.riv` 使用已确认的 02「冰水蓝」材质并增加离线水纹,以高遮蔽度的浅冰蓝底色和白色高光保留柔和羽化、流动反射与不规则边缘水纹。完整视觉与交互规格见 [Persona 设计](agent-persona-design.md)。默认形象与悬浮入口使用 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 源码](https://github.com/vercel/ai-elements/blob/main/packages/elements/src/persona.tsx);图形制作数据位于运行资源中,可编辑设计文件是 `.rev`,见 [作者的定制说明](https://elements.surge.studio/docs/customization)。已移除之前自行生成球缘曲线、光带和局部高光的实现,也移除改写原版明暗的 CSS 滤镜。配色直接写入 Rive 材质,暗部保持蓝色倾向,高光使用白色。
|
||||
|
||||
离线通过同一 Rive 资源中的 `asleep` 状态呈现“静水待机”:关闭外围三层光圈,保留完整蓝色球体及内部柔光的低速、小幅度流动。在线与离线切换保持同一个动画实例,通过资源内的状态混合衔接,恢复连接后回到在线光圈与节奏。参数和图层说明统一维护在 [Agent 动画资源说明](agent-persona-resource.md)。首次加载、加载失败和系统开启减少动态效果时显示从当前资源渲染的在线或离线静态帧,离线静态帧同样不带外围光圈;兜底形象与按钮功能持续可用。
|
||||
|
||||
鼠标悬停沿用原生 `hover` 动画和光圈尺寸;进入、移动、离开坐标通过共享组件交给 Rive 原生监听,使白色高光跟随鼠标局部移动,避免只开 hover 却使反射固定在中心。移出后恢复常态。球体组件移除 Motion,取消按压缩放、弹簧回弹和明暗变化;触摸按下不触发额外动画。点击、触摸轻点及 Enter / Space 继续展开对话,离线时同样可用。系统开启减少动态效果时显示静态帧,不初始化 Rive。强制颜色模式显示高对比圆形轮廓,保留键盘操作。球体动画与面板布局独立,不对 Resizable 连续调宽增加动画。
|
||||
|
||||
渲染生命周期继续遵守 [Rive 内存问题记录](rive-persona-incident.md):延迟一帧初始化,元素离开视口或页面隐藏时卸载渲染实例,不绑定 View Model;仅缓存不可变的 `.riv` 字节,展开、折叠和不同入口复用一次成功下载。失败下载不永久缓存,后续挂载可重试。动态组件准备完成前保留本地静态帧,原生进入动画在显示切换前完成。静态帧与动画通过 180ms CSS 透明度渐变衔接,结束后才隐藏静态帧,避免首次加载瞬间切换造成的跳动;画布的位置与尺寸始终固定。本轮没有新增依赖,也没有恢复已知存在内存问题的颜色绑定。
|
||||
|
||||
### 离线动画的资源改造
|
||||
|
||||
已解析原版的图形、属性、关键帧和状态机,保存为可读的运行时 JSON,并验证可以逐字节恢复原始 `.riv`。修改后的资源保留 5 个原生状态输入,在原有 20 段动画后增加 3 段离线循环,修正 `asleep` / `wake` 中隐藏和缩小球体的关键帧。修改、再生成及保真验证见 [Agent 动画资源说明](agent-persona-resource.md)。这份 JSON 是运行时数据,不是完整恢复的 `.rev` 编辑器工程。
|
||||
|
||||
### 历史窗口、缓存与后台会话
|
||||
|
||||
“主题”参考 [ChatGPT Projects 的会话组织方式](https://help.openai.com/en/articles/10169521-projects-in-chatgpt),作为会话组织单元,用于归集相关事件和问题;与决定数据权限的业务项目分开。Agent 的主题下拉参考 shadcn [TeamSwitcher 模板](https://github.com/shadcn-ui/ui/blob/main/apps/v4/registry/new-york-v4/blocks/sidebar-07/components/team-switcher.tsx)的起始对齐、触发器宽度与最小菜单宽度,配合本地 `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、标题、内容、状态及来源计算,单纯心跳时间变化不触发推理。生成新推荐时保留上一组问题。
|
||||
|
||||
每个会话持有独立 Chat 实例、生成连接、草稿、引用、阅读位置和审批状态。切换历史或新建对话保留原会话后台生成;后台需要审批或回答时,通过历史入口提示返回处理。模型、项目头和凭据续期绑定原会话。后台浏览器动作返回 `SESSION_NOT_ACTIVE`,提示用户回到会话后重新请求;切换时取消原会话尚在执行的浏览器动作。恢复失败保持可重试的连接异常状态,不将断流视为任务完成。切换业务项目由工作台统一处理,会话、主题及缓存按业务项目隔离。
|
||||
|
||||
## 4. 内容与状态
|
||||
|
||||
`answer-ui@1` 仍由严格参数校验与本地注册组件驱动。已有的 `Stack`、`Section`、`Text`、`Metric`、`Table`、`Chart`、`Evidence`、`MapLocation`、`FollowUpForm` 使用新外观。聊天继续使用现有 Responses 事件;正式报告增加可选 `ui_blocks` 字段,复用相同的内容块协议。实现契约见 [本地交互式回答](agent-answer-ui.md)。
|
||||
|
||||
生成中显示已经到达的文字、内容块和公开执行摘要;最终答复到达后,正文和它明确引用的内容留在主阅读流,其他记录进入处理过程。待回答问题、权限审批和失败状态保持可见,不能因最终文字到达而被隐藏。这里借鉴 Reasoning 的折叠行为,呈现的数据是服务端已发布的过程信息,不额外生成思考文本,也不根据耗时推算完成比例。
|
||||
|
||||
证据类别明确区分查询记录、用户提供、分析推断和演练数据。地图定位的按钮结果以实际回调为准;资料表单提交后只表示发送消息,业务证据是否保存取决于后端实际结果。最终回复不等于后台调查任务完成。
|
||||
|
||||
## 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` 使用聊天通道。实现与生成命令见 [本地交互式回答](agent-answer-ui.md)。
|
||||
Reference in New Issue
Block a user