Use the dedicated TJWATER_AGENT_URL and Responses stream protocol. Keep running turns active while users steer or queue follow-ups and edit pending delivery. Refresh the model catalog before generation and preserve approval mode selection. Integrate scoped investigation messaging/presentation, geographic place selection, current Agent composer styles and supporting workbench contracts. Validation: 77 focused Vitest checks, 21 browser cases, lint, typecheck and production build. Preserve direct Server/Agent routing and project authentication.
6.0 KiB
本地交互式回答
聊天保留 AI SDK UIMessage、AI Elements 与现有 Agent 后端,新增
@json-render/core / @json-render/react 的本地注册组件。
组件代码随前端构建发布,无 ChatKit iframe、domain key 或 Vercel/OpenAI
托管 UI 请求。模型仍使用 Agent 的既有配置与工具调用能力。
可用内容与交互
Stack、Section、Text、Metric、Table、Chart、Evidence、
MapLocation、FollowUpForm 共九种组件。图表可切换折线、柱状和数据表;
证据可折叠并标注来源;地图定位通过现有控制器执行;表单从空值开始,
由用户主动提交,提交形成普通用户消息。业务证据是否保存以 Agent 实际工具结果为准。
Agent 通过 present_answer 发布完整的局部界面块,可在两块之间继续输出文字。
消息顺序为文字、data-answer_ui、后续文字与最终报告。同一轮内相同
block_id 更新原块;下一轮不会修改上一轮回答。
这是按内容块逐步出现的界面,不是逐 token 编译 JSX 或每个 JSON 属性都立即显示。
结构化消息与普通聊天共用持久化、历史与断线恢复通道。
生成期间展开显示过程;final_answer 到达后,仅展开最后报告的完整文字与
ui_block_ids 明确引用的已发布组件,其余文字、界面与工具轨迹默认折叠在
“查看处理过程”中。报告组件按引用顺序排列,同一组件不会同时作为报告和过程
挂载,避免重复表单。未被报告引用的过程界面只供回看。
已发布交互界面的普通/协作聊天在最终答复完成、且没有待完成工具时停止本轮原生 生成,防止最终报告之后反复自动修改界面。该收尾不标记后台调查任务完成; 后台执行继续等待其原有运行生命周期与 Server 完成/失败接口。
后台调查执行继续走任务报告与任务展示通道,聊天界面块不构成业务完成或浏览器回执。
扩展组件
- 在
src/features/agent/answer-ui/catalog.ts增加严格的 Zod 参数定义、用途描述与必要的数据上限。 - 在
answer-ui-view.tsx注册 React 组件。需要工作台交互时通过 Agent 公共 API 的回调接入,保持依赖方向。 - 从本仓库运行
pnpm export:answer-ui-contract,更新相邻 Agent 仓库的src/chat/answer-ui-catalog.json。组件目录是唯一参数定义源,生成文件需随两边一起交付。 - 如新组件存在跨字段约束,同时更新两端的协议校验并加边界和交互测试。
导出脚本接受可选目标文件:
node scripts/export-answer-ui-contract.mjs /path/to/agent/src/chat/answer-ui-catalog.json
前端沿用 Zod 3,json-render 0.21 两个包通过作用域 override 使用相同 schema 运行时;实际组件渲染和参数校验已有聚焦测试。升级 json-render 时必须保留这组 兼容性测试,不能只根据包版本判断可用。Agent 原生插件仍使用其 Zod 4 工具边界, 执行后再按生成的 JSON Schema 校验组件参数。
校验边界
两端拒绝未知组件、额外属性、任意脚本/事件定义、缺失引用、循环、重复或游离节点。
每块最多 48 节点、深度 12、约 100 KB,图表必须对齐且数值有限;表格每行与列数
一致,表单字段名唯一。组件只消费明确的 props,没有动态代码、网络 URL 或任意动作 DSL。
无法解析的历史内容显示该块的 fallback_text。
验证
pnpm lint
pnpm typecheck
pnpm test src/features/agent/answer-ui src/features/workbench/hooks/agent-session-message-state.test.ts
pnpm test:browser tests/browser/agent-answer-ui.e2e.ts tests/browser/agent-start-page.e2e.ts
pnpm build
Agent 仓库:
bun run check
bun test tests/chat/answer-stream-projection.test.ts tests/chat/answer-ui.test.ts tests/routes/chatStream.test.ts tests/routes/taskCollaboration.test.ts tests/runtime/opencode.test.ts
bun run tests/integration/answer-ui-smoke.ts
原生 smoke 使用独立临时数据库,不发模型推理请求。浏览器用例用明确标注的演练 事件验证组件、更新、历史恢复、键盘展开证据、表单提交和 320/375px 布局,不能当作 真实模型已正确选择组件或现场资料已核验的证明。
前端与 Agent 需一起更新,Agent 进程需重新加载原生插件。无需新增环境变量、 domain key 或数据库迁移。当前开发实例通过现有监听机制重新加载;既有聊天与调查工作进程保留。
真实模型验收(显式启用)
以下浏览器用例直接连接本机 Agent,输入均为明确的演练资料。工作台地图与项目 读取使用测试数据,聊天、模型工具调用、流式 UI、聊天持久化与表单回传使用真实 服务。每次创建独立验收会话,结束后仅删除该会话,不删除既有用户记录。此用例 会发送模型请求,默认浏览器测试不执行它。
TJWATER_ANSWER_UI_REAL_AGENT_URL=http://127.0.0.1:18787 \
TJWATER_ANSWER_UI_REAL_MODEL_LABEL=专家 \
pnpm test:browser tests/browser/agent-answer-ui-real.e2e.ts --workers=1
先在 Agent 仓库启动隔离实例,可指定独立 INTEGRATION_DATA_DIR 保留联调数据。 可省略模型标签来使用默认模型。该用例不是生产 OAuth 登录或真实供水业务核验。
Vite 统一解析 React/React DOM,Playwright 按端口使用独立的依赖缓存,避免同时 运行的开发服务将旧临时目录的 React 预构建写回测试缓存。
消息入口为 POST /api/v1/responses,采用 Responses 文本输入、Response 输出和标准 SSE 生命周期。前端 ResponsesChatTransport 将网络事件转换为已有 UIMessage 渲染数据;审批、凭据续期、地图动作及 answer-ui 走 tjwater.* 扩展事件,不将 AI SDK 的 UIMessage 流作为网络协议。会话、模型及动作回执等接口统一使用 /api/v1 前缀,原 /agent/chat 路径已移除;Agent 服务和现有会话数据保留。