Files
deerflow-code/frontend-web/docs/openCanvas-frontend-checklist.md
T
2026-05-15 10:42:44 +08:00

1374 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
<CanvasThreadProvider>
<CanvasGraphProvider>
<CanvasUIProvider>
<CanvasShell />
</CanvasUIProvider>
</CanvasGraphProvider>
</CanvasThreadProvider>
```
### 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 对应目标文件
- 迁移策略
- 是否可直接借鉴
- 是否需要重写