# Open Canvas 前端实施清单 ## 1. 文档目标 本文档是 [openCanvas.md](./openCanvas.md) 的前端落地版清单。 目标是把 Canvas 模式拆成可以直接开发的前端任务,覆盖: - 路由接入 - 目录结构 - 页面布局 - 状态管理 - 组件拆分 - 接口适配 - 流式更新 - 版本管理 - 局部改写 - 模型选择 - 验收标准 本文档默认后端会配合新增结构化 `artifact` 字段与 `canvas_agent`。 --- ## 2. 实施原则 ### 2.1 总原则 - 不破坏现有 `workspace` 聊天页面 - 尽量复用现有基础设施 - 先做骨架,再接数据,再接智能行为 - 每一步都能跑、能看、能验收 ### 2.2 可复用的现有能力 当前项目前端已有以下基础设施,可尽量复用: - `react-router-dom` 路由体系 - `WorkspaceLayout` 工作区布局 - `@langchain/langgraph-sdk` 客户端 - `useThreadStream` 的流式线程模式 - 模型列表接口 `/api/models` - 现有认证头注入机制 - `sonner` 提示 - `react-resizable-panels` 双栏/拖拽布局 - `CodeMirror` 代码编辑器 ### 2.3 新增能力的边界 Canvas 模式前端是一个“新子系统”,但不建议做成完全独立的第二套应用。 建议方式: - 复用现有壳层和 API 客户端 - 新建 `src/open-canvas` 目录承载新功能 - 将 Canvas 模式接到现有 Page 层路由里 --- ## 3. 目标目录结构 建议新增如下目录: ```text frontend-web/src/open-canvas/ api/ client.ts models.ts threads.ts runs.ts components/ layout/ CanvasShell.tsx CanvasHeader.tsx CanvasResizableLayout.tsx chat/ CanvasChatPanel.tsx CanvasMessageList.tsx CanvasInputBox.tsx CanvasWelcome.tsx artifact/ CanvasArtifactPanel.tsx CanvasArtifactRenderer.tsx CanvasArtifactHeader.tsx CanvasArtifactVersionNav.tsx CanvasEmptyState.tsx TextArtifactRenderer.tsx CodeArtifactRenderer.tsx selectors/ CanvasModelSelector.tsx CanvasModeSelector.tsx quick-actions/ QuickActionBar.tsx QuickActionButton.tsx web-search/ CanvasWebSearchPanel.tsx contexts/ CanvasThreadContext.tsx CanvasGraphContext.tsx CanvasUIContext.tsx hooks/ useCanvasThread.ts useCanvasStream.ts useCanvasArtifact.ts useCanvasSelection.ts useCanvasQuickActions.ts pages/ CanvasHomePage.tsx CanvasThreadPage.tsx routes/ OpenCanvasRoutes.tsx types/ artifact.ts thread.ts model.ts selection.ts quick-action.ts utils/ artifact.ts selection.ts thread.ts stream.ts quick-actions.ts constants/ index.ts ``` --- ## 4. 开发阶段总览 前端建议分为 10 个实施阶段: 1. 路由与目录骨架 2. Canvas 页面布局 3. 类型与状态协议 4. API 适配层 5. 线程和流式状态接入 6. Artifact 渲染与版本管理 7. 快速开始与空状态 8. 局部选区改写交互 9. 快捷动作系统 10. 模型选择与增强能力接入 建议每个阶段完成后都做一次可视化验收。 --- ## 5. 阶段一:路由与目录骨架 ### 5.1 任务目标 把 Canvas 模式先挂到系统里,确保页面可进入。 ### 5.2 任务清单 - 新建 `src/open-canvas/` 目录 - 新建 `src/open-canvas/routes/OpenCanvasRoutes.tsx` - 新建 `src/open-canvas/pages/CanvasHomePage.tsx` - 新建 `src/open-canvas/pages/CanvasThreadPage.tsx` - 修改 [PageRoutes.tsx](../src/pages/PageRoutes.tsx) ### 5.3 路由建议 建议新增: - `/page/canvas` - `/page/canvas/:thread_id` 建议在 `PageLayout` 内部新增: - `path="canvas/*"` 子路由建议: - `index -> CanvasHomePage` - `:thread_id -> CanvasThreadPage` - `new -> 跳转到 CanvasHomePage 或创建临时线程态` ### 5.4 页面行为要求 `CanvasHomePage`: - 展示 Canvas 欢迎页 - 展示快速开始入口 - 可进入新建文本或代码模式 `CanvasThreadPage`: - 只负责线程级页面装配 - 挂载所有 Canvas 上下文提供器 - 渲染主布局组件 ### 5.5 验收标准 - 访问 `/page/canvas` 正常 - 访问 `/page/canvas/xxx` 正常 - 不影响 `/page/workspace/*` - 页面为独立功能入口 --- ## 6. 阶段二:Canvas 页面布局 ### 6.1 任务目标 先搭出稳定的“左聊天右画布”骨架。 ### 6.2 任务清单 - 新建 `layout/CanvasShell.tsx` - 新建 `layout/CanvasHeader.tsx` - 新建 `layout/CanvasResizableLayout.tsx` - 新建 `chat/CanvasChatPanel.tsx` - 新建 `artifact/CanvasArtifactPanel.tsx` - 新建 `artifact/CanvasEmptyState.tsx` ### 6.3 布局要求 推荐布局: - 顶部:Canvas 标题栏 - 左侧:聊天面板 - 右侧:artifact 面板 - 可选右抽屉:Web 搜索结果 ### 6.4 建议复用 可以优先复用: - `react-resizable-panels` - 现有按钮、分隔线、Tabs、Tooltip 等 UI 组件 ### 6.5 初始状态要求 无 thread 或 thread 中无 artifact 时: - 右侧显示空状态 - 左侧显示欢迎语和快速开始 ### 6.6 验收标准 - 双栏布局稳定 - 可拖拽调整宽度 - 空状态显示正常 - 适配桌面优先,移动端先做降级布局 --- ## 7. 阶段三:类型与状态协议 ### 7.1 任务目标 先把前端需要消费和管理的数据类型定下来。 ### 7.2 任务清单 - 新建 `types/artifact.ts` - 新建 `types/thread.ts` - 新建 `types/model.ts` - 新建 `types/selection.ts` - 新建 `types/quick-action.ts` ### 7.3 必要类型 #### artifact.ts - `CanvasArtifact` - `CanvasArtifactText` - `CanvasArtifactCode` - `CanvasArtifactContent` #### selection.ts - `CanvasTextSelection` - `CanvasCodeSelection` - `CanvasSelectionState` #### thread.ts - `CanvasThreadValues` - `CanvasThreadMetadata` - `CanvasThread` ### 7.4 建议结构 ```ts export type CanvasArtifact = { currentIndex: number; contents: CanvasArtifactContent[]; }; export type CanvasArtifactText = { index: number; type: "text"; title: string; fullMarkdown: string; }; export type CanvasArtifactCode = { index: number; type: "code"; title: string; language: string; code: string; }; ``` ### 7.5 线程值类型建议 ```ts export type CanvasThreadValues = { title?: string; messages?: Message[]; artifact?: CanvasArtifact; web_search_results?: unknown[]; todos?: unknown[]; }; ``` ### 7.6 验收标准 - 所有 Canvas 组件只依赖 `open-canvas/types` - 不把类型散落到页面或组件内部 - 前后端协议字段统一命名 --- ## 8. 阶段四:前端 Context 设计 ### 8.1 任务目标 把 Canvas 的状态拆成职责清晰的三层上下文。 ### 8.2 任务清单 - 新建 `CanvasThreadContext.tsx` - 新建 `CanvasGraphContext.tsx` - 新建 `CanvasUIContext.tsx` ### 8.3 职责划分 #### CanvasThreadContext 负责: - 当前 thread id - thread 基础信息 - thread 创建/切换 - 模型名称 - 模型配置 #### CanvasGraphContext 负责: - messages - artifact - runId - streaming 状态 - error 状态 - 发送消息 - 停止生成 - 切换版本 - 更新 artifact 内容 #### CanvasUIContext 负责: - 面板折叠状态 - 是否正在编辑 - 当前选区 - Web 搜索面板开关 - 快捷动作面板开关 ### 8.4 验收标准 - 页面组件不直接持有大量跨层 useState - 聊天状态和 UI 状态分离 - 线程切换时可安全重置状态 --- ## 9. 阶段五:API 适配层 ### 9.1 任务目标 为 Canvas 模式建立专用的前端 API 包装层。 ### 9.2 任务清单 - 新建 `api/client.ts` - 新建 `api/models.ts` - 新建 `api/threads.ts` - 新建 `api/runs.ts` ### 9.3 设计要求 不要让页面组件直接到处调用现有 `getAPIClient()` 或裸 `fetch`。 建议统一在 `src/open-canvas/api/` 中封装。 ### 9.4 需要封装的能力 #### models.ts - `loadCanvasModels()` - 对现有 `/api/models` 结果做标准化 #### threads.ts - `createCanvasThread()` - `getCanvasThread(threadId)` - `updateCanvasThreadMetadata(threadId, metadata)` - `updateCanvasThreadState(threadId, values)` #### runs.ts - `streamCanvasRun(...)` - `stopCanvasRun(...)` ### 9.5 与现有 API 的关系 底层可以复用: - `src/core/api/api-client.ts` - `src/core/api/fetch-client.ts` 但上层调用应走 Canvas 专用 API。 ### 9.6 验收标准 - 页面层不直接拼接 URL - Canvas API 调用集中管理 - 后续改协议时只动一层 --- ## 10. 阶段六:线程与流式状态接入 ### 10.1 任务目标 让 Canvas 页面能像现有 ChatPage 一样收发消息并接流。 ### 10.2 任务清单 - 新建 `hooks/useCanvasThread.ts` - 新建 `hooks/useCanvasStream.ts` - 新建 `utils/stream.ts` ### 10.3 设计建议 可以参考现有: - [ChatPage.tsx](../src/pages/ChatPage.tsx) - [threads/hooks.ts](../src/core/threads/hooks.ts) 但不要直接把现有 `ChatPage` 复制一份。 ### 10.4 `useCanvasThread` 负责 - 当前 thread id 管理 - 新建/切换 thread - 从 URL 参数恢复 thread ### 10.5 `useCanvasStream` 负责 - 发送消息 - 停止生成 - 处理流式事件 - 更新 `messages` - 更新 `artifact` - 更新 `runId` ### 10.6 流式更新要求 首版可以假设后端在 `values` 或 `updates` 中返回: - `messages` - `artifact` 前端需要: - 新消息追加 - artifact 覆盖或增量更新 - 流结束后保持最终状态 ### 10.7 验收标准 - 能发消息 - 能收到消息 - 能实时更新 artifact - 停止按钮可用 --- ## 11. 阶段七:Artifact 渲染器 ### 11.1 任务目标 实现文本/代码两类 artifact 的基础渲染与切换。 ### 11.2 任务清单 - 新建 `artifact/CanvasArtifactRenderer.tsx` - 新建 `artifact/CanvasArtifactHeader.tsx` - 新建 `artifact/CanvasArtifactVersionNav.tsx` - 新建 `artifact/TextArtifactRenderer.tsx` - 新建 `artifact/CodeArtifactRenderer.tsx` ### 11.3 组件职责 #### CanvasArtifactRenderer - 判断当前 artifact 是否存在 - 判断当前内容是文本还是代码 - 分发到具体渲染器 #### CanvasArtifactHeader - 显示标题 - 显示保存状态 - 显示版本导航 #### CanvasArtifactVersionNav - 上一个版本 - 下一个版本 - 当前版本号 #### TextArtifactRenderer - 渲染 markdown 内容 - 支持编辑模式 - 支持文本选区 #### CodeArtifactRenderer - 使用 CodeMirror - 支持语言模式切换 - 支持代码选区 ### 11.4 首版策略 文本首版建议: - 编辑态用 textarea 或现有 markdown 编辑器 - 展示态用现有 markdown renderer 代码首版建议: - 直接复用现有 CodeMirror 基础能力 ### 11.5 验收标准 - 文本 artifact 可看可编辑 - 代码 artifact 可看可编辑 - 版本切换正确 - 标题与当前版本一致 --- ## 12. 阶段八:快速开始与空状态 ### 12.1 任务目标 让用户在没有任何 artifact 时也能顺畅开始。 ### 12.2 任务清单 - 新建 `chat/CanvasWelcome.tsx` - 在 `CanvasHomePage` 中增加快速开始面板 - 在 `CanvasThreadPage` 空状态时提供快速开始 ### 12.3 快速开始项建议 - 空白文本 - 空白代码 - React 组件模板 - HTML 页面模板 - Python 脚本模板 ### 12.4 行为要求 点击后: - 创建本地前端 artifact 草稿 - 必要时自动创建 thread - 自动进入编辑态 ### 12.5 验收标准 - 不发消息也能先建立 artifact - 新建文本/代码入口可用 - 初始编辑体验完整 --- ## 13. 阶段九:Artifact 版本管理 ### 13.1 任务目标 让每次 AI 生成或修改都成为一个新版本。 ### 13.2 任务清单 - 新建 `hooks/useCanvasArtifact.ts` - 新建 `utils/artifact.ts` ### 13.3 必要能力 - 获取当前版本内容 - 切换版本 - 更新当前版本内容 - 追加新版本 - 判断 artifact 是否为空 ### 13.4 推荐工具函数 - `getCurrentArtifactContent(artifact)` - `setCurrentArtifactIndex(artifact, index)` - `appendArtifactVersion(artifact, content)` - `replaceCurrentArtifactContent(artifact, content)` - `isTextArtifact(content)` - `isCodeArtifact(content)` ### 13.5 注意事项 - 前端切版本不能直接修改原对象引用 - 每次更新要创建新对象,避免渲染异常 ### 13.6 验收标准 - AI 更新后版本数增加 - 手动切换历史版本稳定 - 当前版本高亮正确 --- ## 14. 阶段十:局部选区交互 ### 14.1 任务目标 实现局部改写所需的前端选区采集与展示。 ### 14.2 任务清单 - 新建 `hooks/useCanvasSelection.ts` - 新建 `utils/selection.ts` ### 14.3 文本选区需求 - 获取选中起止位置 - 获取选中文本 - 在 UI 上显示“已选中某段内容” - 支持清除选区 ### 14.4 代码选区需求 - 获取 CodeMirror 选区 - 保存选中代码内容 - 保存 start/end 或行列信息 ### 14.5 交互建议 可以在选区出现后展示浮层或工具条: - 改写 - 精简 - 扩写 - 解释 首版先只保留: - “对所选内容进行修改” 的统一入口 ### 14.6 验收标准 - 文本选区可读 - 代码选区可读 - 选区状态可清空 - 切换版本或 thread 时选区自动重置 --- ## 15. 阶段十一:聊天面板适配 ### 15.1 任务目标 实现 Canvas 模式专用聊天面板,不直接塞回现有 ChatBox。 ### 15.2 任务清单 - 新建 `chat/CanvasMessageList.tsx` - 新建 `chat/CanvasInputBox.tsx` - 新建 `chat/CanvasChatPanel.tsx` ### 15.3 设计建议 可以参考现有 ChatPage 的结构,但建议把 Canvas 模式聊天区做成更轻量版本。 ### 15.4 必要功能 - 展示消息列表 - 展示生成中状态 - 提交输入 - 停止生成 - 显示模型选择器 - 显示 Web 搜索开关 ### 15.5 可以复用 - 现有消息渲染组件中的部分能力 - 现有 InputBox 的一部分交互逻辑 ### 15.6 不建议直接复用 - 当前工作区的文件 artifact 面板耦合 - 当前以文件产物为中心的 ChatBox 结构 ### 15.7 验收标准 - Canvas 聊天区独立可用 - 能与 artifact 面板联动 - 布局不受现有文件 artifact 影响 --- ## 16. 阶段十二:模型选择器 ### 16.1 任务目标 让 Canvas 模式可以使用 DeerFlow 的动态模型列表。 ### 16.2 任务清单 - 新建 `selectors/CanvasModelSelector.tsx` - 在 `api/models.ts` 中做标准化 ### 16.3 UI 要求 - 显示模型名 - 显示是否本地模型 - 显示是否支持视觉/推理/Canvas ### 16.4 状态要求 - 当前 thread 记录 `model_name` - 必要时记录 `model_config` - 切换 thread 时能恢复模型 ### 16.5 首版能力 首版可以只做: - 下拉选择模型 - 将模型信息写入 thread metadata 或 run configurable ### 16.6 验收标准 - 模型列表正确展示 - 切换模型后发消息使用新模型 - 本地模型与云模型能在 UI 中区分 --- ## 17. 阶段十三:快捷动作栏 ### 17.1 任务目标 实现 artifact 上方或下方的快捷动作入口。 ### 17.2 任务清单 - 新建 `quick-actions/QuickActionBar.tsx` - 新建 `quick-actions/QuickActionButton.tsx` - 新建 `hooks/useCanvasQuickActions.ts` - 新建 `utils/quick-actions.ts` ### 17.3 首版动作建议 文本类: - 扩写 - 精简 - 改正式 - 改口语 代码类: - 加注释 - 加日志 - 修 bug ### 17.4 行为要求 点击动作后: - 写入 `quick_action_id` - 触发一次 Canvas run - 生成新的 artifact 版本 ### 17.5 验收标准 - 动作栏根据 artifact 类型动态变化 - 动作点击后有效果 - 新版本正确生成 --- ## 18. 阶段十四:Web 搜索面板 ### 18.1 任务目标 为后续搜索增强预留 UI 和交互位置。 ### 18.2 任务清单 - 新建 `web-search/CanvasWebSearchPanel.tsx` - 在 `CanvasUIContext` 中增加开关状态 ### 18.3 首版要求 - 只做抽屉面板 - 可展示结构化搜索结果列表 - 可开关显示 ### 18.4 二期能力 - 支持点击来源预览 - 支持从结果插入上下文 ### 18.5 验收标准 - 面板开关正常 - 搜索结果区域可承载数据 --- ## 19. 阶段十五:页面装配 ### 19.1 任务目标 将所有子模块整合到页面中。 ### 19.2 任务清单 `CanvasHomePage.tsx`: - 欢迎页 - 快速开始 - 最近 Canvas 线程入口 `CanvasThreadPage.tsx`: - 解析 route params - 挂载 `CanvasThreadContext` - 挂载 `CanvasGraphContext` - 挂载 `CanvasUIContext` - 渲染 `CanvasShell` ### 19.3 结构建议 ```tsx ``` ### 19.4 验收标准 - 页面层只负责装配,不承载复杂业务逻辑 - 子组件依赖上下文而不是层层 props drilling --- ## 20. 推荐逐文件实施顺序 建议按这个顺序建文件: 1. `routes/OpenCanvasRoutes.tsx` 2. `pages/CanvasHomePage.tsx` 3. `pages/CanvasThreadPage.tsx` 4. `types/*` 5. `contexts/CanvasThreadContext.tsx` 6. `contexts/CanvasUIContext.tsx` 7. `contexts/CanvasGraphContext.tsx` 8. `layout/CanvasShell.tsx` 9. `layout/CanvasResizableLayout.tsx` 10. `artifact/CanvasEmptyState.tsx` 11. `artifact/CanvasArtifactRenderer.tsx` 12. `artifact/TextArtifactRenderer.tsx` 13. `artifact/CodeArtifactRenderer.tsx` 14. `chat/CanvasChatPanel.tsx` 15. `chat/CanvasInputBox.tsx` 16. `api/*` 17. `hooks/useCanvasStream.ts` 18. `hooks/useCanvasSelection.ts` 19. `quick-actions/*` 20. `web-search/*` --- ## 21. 开发任务拆分建议 如果多人协作,建议这样拆: ### A 组:页面与路由 - 路由接入 - 页面骨架 - 主布局 ### B 组:artifact 视图 - artifact 类型 - 渲染器 - 版本导航 - 代码/文本编辑器 ### C 组:聊天与流式 - thread 管理 - stream 接入 - 消息面板 - 模型切换 ### D 组:增强交互 - 选区 - 快捷动作 - 搜索面板 --- ## 22. 每阶段验收清单 ### 22.1 阶段一到三 - 路由正常 - 空页面正常 - 类型编译通过 - 目录结构清晰 ### 22.2 阶段四到六 - thread 可创建/读取 - 消息可发送 - artifact 可展示 - 流式结果可更新 ### 22.3 阶段七到九 - 文本/代码 artifact 渲染正确 - 版本导航正确 - 快速开始可用 - 模型选择可用 ### 22.4 阶段十到十四 - 局部选区可采集 - 快捷动作可触发 - 搜索面板可显示 - 各功能互不冲突 --- ## 23. 风险点与规避方式 ### 23.1 不要直接复制现有 ChatPage 原因: - 现有页面与文件 artifact 耦合较重 - Canvas 需要结构化 artifact 而不是文件列表 ### 23.2 不要把所有状态都放一个 Context 原因: - 更新频率高 - 容易导致全树重渲染 ### 23.3 不要先做复杂富文本 原因: - 选区映射复杂 - 首版容易卡在编辑器实现而不是业务链路 建议先以: - `fullMarkdown` - `textarea/markdown renderer` 作为最小闭环。 ### 23.4 不要前端硬编码模型表 原因: - 后端才是真源 - 后期本地模型和自定义 provider 会频繁变化 --- ## 24. 首版最小可交付范围 前端首版建议只交付这些: - `canvas/*` 路由 - Canvas 双栏布局 - 文本/代码 artifact 渲染 - 模型选择器 - 流式聊天 - artifact 版本切换 - 快速开始 首版先不强制包含: - 复杂文本局部高亮浮层 - 复杂快捷动作配置中心 - 高级 Web 搜索结果联动 --- ## 25. 下一步建议 完成本文档后,建议继续产出两份更细的执行文件: ### 25.1 前端文件创建顺序清单 按天或按 PR 颗粒度,列出: - 每一批次新建哪些文件 - 每一批次修改哪些已有文件 ### 25.2 前端组件接口文档 列出关键组件 props: - `CanvasShell` - `CanvasChatPanel` - `CanvasArtifactRenderer` - `CanvasModelSelector` 这样正式开工时会更顺畅。 --- ## 26. 参考源码映射 前端实施清单建议补充对 `langchain-ai/open-canvas` 源码的“映射式参考”,但不建议把源码大段粘贴进本文档。 推荐做法是: - 记录参考文件路径 - 说明它解决了什么问题 - 说明在 DeerFlow 前端里应该落到哪个模块 - 只摘能力点,不摘整段实现 这样做的原因: - 文档更清晰 - 不会把 Next.js 运行时细节误当成可直接迁移代码 - 后续维护更轻 ### 26.1 推荐参考文件总览 以下文件最值得作为前端实现参考: - `apps/web/src/contexts/GraphContext.tsx` - `apps/web/src/components/canvas/canvas.tsx` - `apps/web/src/components/artifacts/ArtifactRenderer.tsx` - `apps/web/src/components/artifacts/TextRenderer.tsx` - `apps/web/src/components/artifacts/CodeRenderer.tsx` - `apps/web/src/contexts/ThreadProvider.tsx` - `apps/web/src/contexts/AssistantContext.tsx` - `apps/web/src/hooks/useRuns.tsx` - `apps/web/src/types.ts` - `packages/shared/src/types.ts` - `packages/shared/src/models.ts` - `packages/shared/src/utils/artifacts.ts` ### 26.2 逐文件映射建议 #### `apps/web/src/contexts/GraphContext.tsx` 参考价值: - 这是 open-canvas 前端最核心的状态管理文件之一 - 管理消息、artifact、流式状态、保存状态、版本切换、局部更新 - 处理流中 artifact 更新和 thread 切换 DeerFlow 对应落点: - `src/open-canvas/contexts/CanvasGraphContext.tsx` - `src/open-canvas/hooks/useCanvasStream.ts` - `src/open-canvas/utils/stream.ts` - `src/open-canvas/utils/artifact.ts` 重点借鉴内容: - artifact 如何作为线程主状态存在 - 流式过程中如何同步 messages 与 artifact - 切换 thread 时如何恢复状态 - 如何维护“当前版本”和“已保存状态” 不建议直接照搬的部分: - 与 Next.js、`nuqs`、open-canvas 内部 hook 耦合的代码 - 与其后端返回格式强绑定的处理逻辑 #### `apps/web/src/components/canvas/canvas.tsx` 参考价值: - Open Canvas 的主页面装配组件 - 管理左聊天右画布布局 - 定义快速开始逻辑 - 管理 chat collapsed、artifact 初始创建 DeerFlow 对应落点: - `src/open-canvas/components/layout/CanvasShell.tsx` - `src/open-canvas/components/layout/CanvasResizableLayout.tsx` - `src/open-canvas/pages/CanvasThreadPage.tsx` 重点借鉴内容: - 快速开始时如何创建文本或代码 artifact - 左右双栏如何组织 - 页面级状态和上下文边界怎么划分 不建议直接照搬的部分: - Next 路由参数逻辑 - 与 open-canvas ThreadProvider 强耦合的状态恢复代码 #### `apps/web/src/components/artifacts/ArtifactRenderer.tsx` 参考价值: - 负责 artifact 总渲染分发 - 根据当前版本内容选择文本或代码渲染器 - 负责版本导航和选区交互挂钩 DeerFlow 对应落点: - `src/open-canvas/components/artifact/CanvasArtifactRenderer.tsx` - `src/open-canvas/components/artifact/CanvasArtifactHeader.tsx` - `src/open-canvas/components/artifact/CanvasArtifactVersionNav.tsx` 重点借鉴内容: - 当前 artifact 的统一入口组件结构 - 版本导航和正文渲染如何组合 - 文本/代码视图如何统一被包装 #### `apps/web/src/components/artifacts/TextRenderer.tsx` 参考价值: - 负责文本 artifact 的渲染与编辑 - 处理 markdown 内容、更新、局部交互 DeerFlow 对应落点: - `src/open-canvas/components/artifact/TextArtifactRenderer.tsx` - `src/open-canvas/hooks/useCanvasSelection.ts` 重点借鉴内容: - 文本 artifact 的编辑态与展示态切换 - 当前版本内容如何回写到状态 - 局部选区的挂接点 实现上的取舍建议: - DeerFlow 首版不要追求和 open-canvas 一样复杂的富文本块级编辑 - 建议先用 `fullMarkdown` + markdown renderer + 简单编辑态完成闭环 #### `apps/web/src/components/artifacts/CodeRenderer.tsx` 参考价值: - 负责代码 artifact 的渲染与编辑 - 与 CodeMirror 集成 - 管理代码内容更新 DeerFlow 对应落点: - `src/open-canvas/components/artifact/CodeArtifactRenderer.tsx` 重点借鉴内容: - 代码 artifact 如何绑定语言 - 代码编辑结果如何同步回 artifact 状态 - 局部代码选区的接入位置 #### `apps/web/src/contexts/ThreadProvider.tsx` 参考价值: - 负责 thread 与模型相关状态 - 管理 thread 切换和 thread 级配置 DeerFlow 对应落点: - `src/open-canvas/contexts/CanvasThreadContext.tsx` - `src/open-canvas/hooks/useCanvasThread.ts` 重点借鉴内容: - 当前 thread id 的管理方式 - thread metadata 与 model state 的关系 - 页面恢复 thread 时的上下文同步 #### `apps/web/src/contexts/AssistantContext.tsx` 参考价值: - 管理 assistant 选择 - 管理与 assistant 相关的 thread 行为 DeerFlow 对应落点: - DeerFlow 首版可以弱化这部分 - 如果首版只有 `canvas_agent` 一个固定 assistant,可只保留最小 assistant 绑定能力 重点借鉴内容: - thread 与 assistant 的耦合方式 #### `apps/web/src/hooks/useRuns.tsx` 参考价值: - 管理 run 相关行为 DeerFlow 对应落点: - `src/open-canvas/api/runs.ts` - `src/open-canvas/hooks/useCanvasStream.ts` 重点借鉴内容: - run 行为与页面状态的解耦方式 #### `apps/web/src/types.ts` 参考价值: - 保存了一部分 artifact 和消息类型定义 DeerFlow 对应落点: - `src/open-canvas/types/artifact.ts` - `src/open-canvas/types/thread.ts` 重点借鉴内容: - artifact 的前端表达方式 注意: - 更建议以 `packages/shared/src/types.ts` 为主参考,而不是这个文件 - 因为 `src/types.ts` 里同时包含了部分历史兼容结构 #### `packages/shared/src/types.ts` 参考价值: - 这是 open-canvas 中最重要的共享类型来源之一 - 定义了 `ArtifactV3`、代码/文本内容、选择区和其他共享结构 DeerFlow 对应落点: - `src/open-canvas/types/artifact.ts` - `src/open-canvas/types/selection.ts` - 可作为前后端协议设计的主要参考 重点借鉴内容: - `ArtifactV3` 结构 - 文本/代码 artifact 类型边界 - 与版本管理有关的字段组织方式 建议: - DeerFlow 可以参考其字段设计 - 但不要机械复制所有字段,保留适合当前项目的最小集 #### `packages/shared/src/models.ts` 参考价值: - 展示了 open-canvas 如何组织前端模型列表和模型能力 DeerFlow 对应落点: - `src/open-canvas/types/model.ts` - `src/open-canvas/api/models.ts` - `src/open-canvas/components/selectors/CanvasModelSelector.tsx` 重点借鉴内容: - 模型展示结构 - provider 概念 - 各模型能力标签的前端呈现思路 注意: - 不应作为 DeerFlow 的模型配置真源 - DeerFlow 必须以自己后端 `/api/models` 为真源 #### `packages/shared/src/utils/artifacts.ts` 参考价值: - 里面有 artifact 类型判断和内容获取工具 DeerFlow 对应落点: - `src/open-canvas/utils/artifact.ts` 重点借鉴内容: - 获取当前版本内容 - 判断当前 artifact 是文本还是代码 - 为渲染器和快捷动作提供统一入口 ### 26.3 可以直接参考但不要直接迁移的部分 以下内容可以借鉴思路,但不建议直接搬代码: - Next.js 路由和页面结构 - `src/app/api/*` 目录中的 API Route - Supabase SSR 和服务端 session 相关代码 - `next/navigation` 相关逻辑 - `middleware.ts` 原因: - DeerFlow 前端是 `React 19 + Vite + react-router-dom` - 这些代码依赖 Next.js 运行时 ### 26.4 建议的使用方式 开发时推荐这样使用参考源码: 1. 先按本文档实现 DeerFlow 自己的模块边界 2. 遇到某个具体功能点时,再去查对应 open-canvas 文件 3. 提炼实现思路,重写到 DeerFlow 的目录结构中 4. 不要复制包含 Next.js 运行时依赖的代码 ### 26.5 推荐补充动作 如果后面要正式进入实现阶段,建议再单独新增一份源码映射文档,例如: - `frontend-web/docs/openCanvas-source-map.md` 里面可以更细地记录: - open-canvas 文件路径 - DeerFlow 对应目标文件 - 迁移策略 - 是否可直接借鉴 - 是否需要重写