From 864ce4101a12a8e4ccc835f7f1ee9e6a8bd6fc1f Mon Sep 17 00:00:00 2001 From: HouYunFei <1844025705@qq.com> Date: Thu, 9 Jul 2026 17:16:35 +0800 Subject: [PATCH] feat(agent): implement streamdown for real-time message rendering in chat --- AGENTS.md | 17 ++--------------- CHANGELOG.md | 13 +++++++------ README.md | 2 +- web/package.json | 3 ++- .../components/canvas/canvas-agent-chat-ui.tsx | 9 ++++++++- web/src/main.tsx | 1 + web/src/styles/globals.css | 1 + 7 files changed, 22 insertions(+), 24 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cea4781..b2f51e9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ - 写代码保持最少行数,能简单实现就不要引入复杂抽象。 - 标准格式、协议、解析、压缩、加密、日期等通用能力优先使用成熟稳定的库,不要手写底层实现,除非用户明确要求或项目已有实现必须沿用。 - 不要为了“兼容更多场景”写大量分支,只实现当前明确需要的功能。 -- 项目尚未上线,不需要兼容旧数据;表结构或字段调整时直接按新设计修改,不写旧字段兼容、数据迁移兜底或删除旧表的清理逻辑,除非用户明确要求。 +- 项目尚未上线,不需要兼容旧数据;本地存储结构调整时直接按新设计修改,不写旧字段兼容或数据迁移兜底,除非用户明确要求。 - 每次写完代码,不需要检查语法,不需要执行构建,用户会自己做。 - 不要改无关文件,不要顺手重构。 - 如果工作区已有用户改动,不要回滚,不要覆盖;只在必要范围内追加修改。 @@ -19,22 +19,11 @@ - 补充时写成明确、可执行的规则,避免只写模糊描述。 - 新规则应放到最相关的章节;找不到合适章节时放到“项目注意事项”。 -## 后端规范 - -- 后端使用 Go + Gin + GORM。 -- `handler/` 只处理 HTTP 入参、调用 service、返回 `OK` / `Fail`。 -- `service/` 放业务逻辑、默认值、校验、时间、ID、鉴权等处理。 -- `repository/` 只做数据库访问和 GORM 查询。 -- `model/` 只定义数据结构、枚举和简单模型方法。 -- 列表接口优先沿用 `model.Query`、`Normalize`、分页和标签筛选方式。 -- 业务接口保持 `{ code, data, msg }` 的响应结构。 -- 新增数据表时同步更新 `docs/backend-database.md`。 - ## 前端规范 - 前端使用 Vite、React、React Router、TypeScript、Ant Design、Tailwind、Zustand。 - 编写 Ant Design 相关代码时,参考 https://ant.design/llms-full.txt 理解组件 API、示例和设计规范,并优先结合项目当前 antd 版本与既有写法。 -- API 请求统一放在 `web/src/services/api/`。 +- 外部服务请求统一放在 `web/src/services/api/`,由浏览器前端直连,不假设存在项目后端。 - 全局或跨页面状态优先放在 `web/src/stores/`。 - 已经放在全局 store 或全局 hook 中的状态/动作,组件需要时直接使用对应 store/hook,不要为了“纯组件”层层透传 props;避免一个组件传递过多参数。 - 全局组件、全局常量、全局配置等全局性质的内容不要作为 props 或参数层层传递;哪里需要就在哪里直接从对应全局入口获取。 @@ -76,8 +65,6 @@ - 每次重大改动(新增/调整/删除功能、接口或工具,影响用户可感知行为)完成后,都要在 `CHANGELOG.md` 的 `Unreleased` 追加一条记录,按 `[新增]` / `[调整]` / `[修复]` / `[优化]` 前缀分类,用一句中文归纳;纯内部重构、格式化、无用户可感知影响的小改动可不记。 - 每次 todo 事项完成后,先从 `docs/content/docs/progress/todo.mdx` 移到 `docs/content/docs/progress/pending-test.mdx`,不要直接写进正式功能说明;用户确认测试通过后再更新 `docs/content/docs/overview/features.mdx`。 - 每次任务完成前,都要根据实际变更检查并更新 `docs/content/docs/progress/todo.mdx` 和 `docs/content/docs/progress/pending-test.mdx`;如果功能或待办没有变化,也要确认无需修改。 -- 接口响应规则写到 `docs/content/docs/backend/api-response.mdx`。 -- 数据库结构写到 `docs/content/docs/backend/backend-database.mdx`。 - 文档不要写过期日期;除非用户明确要求记录具体时间。 ## 发版本流程 diff --git a/CHANGELOG.md b/CHANGELOG.md index 53a5898..78aff85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ ## Unreleased -+ [新增] Agent 新增站点级工具:`canvas_list_projects`(画布清单,仅标题/日期/节点数/连线数,配合 `site_navigate` 打开指定画布)、`workbench_image_get_config` / `workbench_image_generate`(生图工作台读取配置、填写提示词并触发生成)、`workbench_video_get_config` / `workbench_video_generate`(视频创作台同理)、`prompts_search`(分页搜索提示词库)、`assets_list` / `assets_add`(查看与新增「我的素材」)。 -+ [新增] Agent 面板全站化:从画布页抽离为全局常驻右侧面板,开/关整体推动顶栏和内容(类似浏览器侧边栏扩展),顶栏和画布工具栏各有一个独立开关按钮。 -+ [新增] Agent 新增 `site_navigate` 工具,Codex 可直接控制网站跳转至首页、画布、生图、视频、提示词库、素材、配置等页面。 -+ [新增] Agent 添加停止对话按钮:对话运行中发送按钮变为红色停止按钮,点击后向后端发送 SIGINT 中断当前 Codex turn。 -+ [调整] Codex 会话改为单一站点级连续线程,不再按画布 ID 分隔,跨页面和跨画布保持同一对话上下文; -+ [调整] 移除仅前端调用 OpenAI responses 接口的在线画布助手死代码,Agent 统一走 MCP + 本地 Codex 链路。 ++ [新增] Agent 对话消息改用 streamdown 流式渲染,提升长回复与 Markdown 内容展示效果。 ++ [新增] Agent 新增画布、工作台、提示词库和素材等站点级工具,支持读取配置、触发生成与新增素材。 ++ [新增] Agent 面板改为全站常驻右侧栏,开关时同步推动顶栏和页面内容,并保留独立入口按钮。 ++ [新增] Agent 新增 `site_navigate` 工具,支持从对话中直接跳转首页、画布、工作台、素材和配置等页面。 ++ [新增] Agent 对话运行中支持一键停止,发送按钮切换为红色停止按钮并中断当前 Codex turn。 ++ [调整] Codex 会话改为站点级连续线程,不再按画布 ID 分隔,跨页面和跨画布保持同一上下文。 ++ [调整] 移除仅前端调用 OpenAI responses 接口的在线画布助手旧逻辑,统一走 MCP + 本地 Codex 链路。 + [新增] 画布节点支持统一维护名称字段,默认显示在节点上方,并可直接双击名称编辑。 + [新增] 画布新增组节点,支持节点拖入/拆出分组、拖拽高亮吸附和移动组时带动子节点。 + [调整] 画布节点顶部工具条改为点击选中节点后显示,避免鼠标经过节点时频繁弹出。 diff --git a/README.md b/README.md index 07e2c50..32c4bf4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ 无限画布是一款面向图片创作的开源工作台。它把画布编排、AI 图片生成、参考图编辑、对话助手、提示词库和素材沉淀放在同一个界面里,适合用来探索视觉方案并连续迭代图片结果。 > [!CAUTION] -> 项目目前处于开发阶段,不保证历史数据兼容。各种数据库结构和存储格式都可能直接调整,欢迎关注后续更新,当前更适合个人/本地部署,不建议直接公网多人共用。 +> 项目目前处于开发阶段,不保证历史数据兼容。各种本地存储格式都可能直接调整,欢迎关注后续更新,当前更适合个人/本地部署,不建议直接公网多人共用。 > > 如果你需要稳定维护自己的分支,建议自行 fork 后独立开发。二次开发与 PR 请保留原作者信息和前端页面标识。 diff --git a/web/package.json b/web/package.json index 4b14758..fbd4357 100644 --- a/web/package.json +++ b/web/package.json @@ -35,6 +35,7 @@ "react-router": "^7.12.0", "react-router-dom": "^7.12.0", "shadcn": "^4.7.0", + "streamdown": "^2.5.0", "tailwind-merge": "^3.6.0", "tailwindcss": "^4", "tw-animate-css": "^1.4.0", @@ -42,11 +43,11 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@vitejs/plugin-react": "^5.2.0", "@types/file-saver": "^2.0.7", "@types/node": "^20", "@types/react": "19.1.12", "@types/react-dom": "19.1.9", + "@vitejs/plugin-react": "^5.2.0", "prettier": "^3.8.3", "typescript": "^5", "vite": "^7.3.0" diff --git a/web/src/components/canvas/canvas-agent-chat-ui.tsx b/web/src/components/canvas/canvas-agent-chat-ui.tsx index 571f824..ddfb271 100644 --- a/web/src/components/canvas/canvas-agent-chat-ui.tsx +++ b/web/src/components/canvas/canvas-agent-chat-ui.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef, useState, type ReactNode } from "react"; import { Button, Tooltip } from "antd"; import { ArrowUp, CheckCircle2, CircleAlert, ImagePlus, LoaderCircle, Square, UserRound, Wrench, X, XCircle } from "lucide-react"; +import { Streamdown } from "streamdown"; import { isPlainEnterKey } from "@/lib/keyboard-event"; import { canvasThemes } from "@/lib/canvas-theme"; @@ -15,6 +16,8 @@ export type CanvasAgentChatMessage = { meta?: string; detail?: unknown; attachments?: CanvasAgentChatAttachment[]; + /** Present while the message is actively streaming; cleared on completion. */ + streamId?: string; }; const WORKING_TEXT = "working..."; @@ -46,7 +49,11 @@ export function AgentChatMessage({ item, theme, user, onRejectTool, onApproveToo