1032 lines
19 KiB
Markdown
1032 lines
19 KiB
Markdown
# Open Canvas 后端实施清单
|
|
|
|
## 1. 文档目标
|
|
|
|
本文档是 [openCanvas.md](./openCanvas.md) 的后端落地版清单。
|
|
|
|
目标是把 Canvas 模式在当前 DeerFlow 后端中的实施工作拆成可以直接排期和执行的任务,覆盖:
|
|
|
|
- 线程状态扩展
|
|
- `canvas_agent` 设计
|
|
- LangGraph 节点拆分
|
|
- Gateway API 扩展
|
|
- 流式输出契约
|
|
- 模型配置与本地模型支持
|
|
- 结构化 artifact 的持久化
|
|
- 测试与验收顺序
|
|
|
|
本文档默认前端会新增独立的 Canvas 子系统,并通过现有 LangGraph 线程和 Gateway API 与后端通信。
|
|
|
|
---
|
|
|
|
## 2. 实施原则
|
|
|
|
### 2.1 总原则
|
|
|
|
- 不破坏现有 `lead_agent`
|
|
- 不破坏现有 `artifacts: list[str]` 文件产物体系
|
|
- 优先增量扩展,不做推倒重构
|
|
- 先打通状态和协议,再实现复杂 AI 行为
|
|
- 先支持文本/代码双类型,再逐步扩展快捷动作
|
|
|
|
### 2.2 推荐路线
|
|
|
|
推荐采用“新增独立 `canvas_agent`”方案,而不是把所有 Canvas 行为塞进现有 `lead_agent`。
|
|
|
|
推荐原因:
|
|
|
|
- 风险更低
|
|
- 图逻辑更清晰
|
|
- 更容易对齐 open-canvas 的状态结构
|
|
- 不影响现有 DeerFlow 普通聊天与文件产物模式
|
|
|
|
### 2.3 后端目标边界
|
|
|
|
本次后端实施重点是:
|
|
|
|
- 新增 Canvas 专用线程状态字段
|
|
- 新增 Canvas Agent 图
|
|
- 新增前端需要的模型能力元数据
|
|
- 支持结构化 artifact 在线程状态中读写
|
|
|
|
本次不要求:
|
|
|
|
- 完整复刻 open-canvas 的所有 TS 图结构
|
|
- 完整复刻 Supabase 相关逻辑
|
|
- 把所有模型 provider 完全抽象成统一能力中台
|
|
|
|
---
|
|
|
|
## 3. 现有后端基础能力盘点
|
|
|
|
当前 DeerFlow 后端已经具备非常好的基础设施:
|
|
|
|
- LangGraph 线程与流式交互
|
|
- FastAPI Gateway
|
|
- 模型动态配置
|
|
- 本地线程状态管理
|
|
- Sandbox/工具体系
|
|
- 上传与文件 artifact 访问
|
|
- Memory 与标题生成
|
|
|
|
因此 Canvas 模式并不是“从 0 开始做 Agent 平台”,而是“在现有平台上新增一类结构化创作模式”。
|
|
|
|
---
|
|
|
|
## 4. 目标代码落点
|
|
|
|
建议优先关注以下目录:
|
|
|
|
```text
|
|
offline-backend-20260512/backend/
|
|
app/gateway/
|
|
routers/
|
|
deps.py
|
|
app.py
|
|
packages/harness/deerflow/
|
|
agents/
|
|
factory.py
|
|
thread_state.py
|
|
lead_agent/
|
|
middlewares/
|
|
runtime/
|
|
config/
|
|
tools/
|
|
```
|
|
|
|
建议为 Canvas 新增或扩展以下区域:
|
|
|
|
```text
|
|
packages/harness/deerflow/
|
|
agents/
|
|
canvas_agent/
|
|
__init__.py
|
|
agent.py
|
|
prompt.py
|
|
state.py
|
|
nodes/
|
|
route_user_intent.py
|
|
generate_artifact.py
|
|
rewrite_artifact.py
|
|
update_highlighted_text.py
|
|
update_highlighted_code.py
|
|
generate_followup.py
|
|
quick_actions.py
|
|
web_search.py
|
|
```
|
|
|
|
如果不想把节点拆得太细,首版也可以把部分逻辑先收在 `agent.py` 里,但建议至少把 `state.py` 和 `prompt.py` 独立出来。
|
|
|
|
---
|
|
|
|
## 5. 开发阶段总览
|
|
|
|
后端建议分为 11 个阶段:
|
|
|
|
1. 线程状态扩展
|
|
2. 结构化 artifact 协议定义
|
|
3. `canvas_agent` 接入到 Agent 工厂
|
|
4. Canvas 图的最小节点实现
|
|
5. Gateway/线程接口兼容
|
|
6. 流式状态输出适配
|
|
7. 模型能力元数据扩展
|
|
8. 本地模型兼容与配置统一
|
|
9. 快捷动作与局部改写
|
|
10. Web 搜索增强
|
|
11. 测试、回归、验收
|
|
|
|
---
|
|
|
|
## 6. 阶段一:线程状态扩展
|
|
|
|
### 6.1 任务目标
|
|
|
|
让 DeerFlow 的线程状态能原生保存 Canvas 所需的结构化信息。
|
|
|
|
### 6.2 任务清单
|
|
|
|
- 扩展 [thread_state.py](../../offline-backend-20260512/backend/packages/harness/deerflow/agents/thread_state.py)
|
|
- 定义 Canvas 相关 TypedDict 或 dataclass 结构
|
|
- 确保状态字段可序列化
|
|
- 不影响现有 `messages/title/artifacts/todos` 逻辑
|
|
|
|
### 6.3 建议新增字段
|
|
|
|
在现有 `ThreadState` 上新增:
|
|
|
|
- `artifact`
|
|
- `highlighted_text`
|
|
- `highlighted_code`
|
|
- `canvas_mode`
|
|
- `quick_action_id`
|
|
- `web_search_enabled`
|
|
- `web_search_results`
|
|
|
|
### 6.4 建议数据形态
|
|
|
|
可先采用 JSON-safe dict 结构,而不是在状态层引入过重的复杂对象。
|
|
|
|
建议:
|
|
|
|
```python
|
|
class CanvasArtifactText(TypedDict):
|
|
index: int
|
|
type: Literal["text"]
|
|
title: str
|
|
fullMarkdown: str
|
|
|
|
class CanvasArtifactCode(TypedDict):
|
|
index: int
|
|
type: Literal["code"]
|
|
title: str
|
|
language: str
|
|
code: str
|
|
|
|
class CanvasArtifact(TypedDict):
|
|
currentIndex: int
|
|
contents: list[CanvasArtifactText | CanvasArtifactCode]
|
|
```
|
|
|
|
### 6.5 与现有 `artifacts` 的关系
|
|
|
|
必须保留现有:
|
|
|
|
- `artifacts: list[str]`
|
|
|
|
新增:
|
|
|
|
- `artifact: dict | None`
|
|
|
|
含义区分:
|
|
|
|
- `artifacts` 表示文件型产物列表
|
|
- `artifact` 表示 Canvas 当前主文档
|
|
|
|
### 6.6 验收标准
|
|
|
|
- 旧线程无 `artifact` 时不报错
|
|
- 新线程可写入 `artifact`
|
|
- 线程状态能被 FastAPI 和 LangGraph 正确序列化
|
|
|
|
---
|
|
|
|
## 7. 阶段二:结构化 Artifact 协议定义
|
|
|
|
### 7.1 任务目标
|
|
|
|
统一前后端对 Canvas artifact 的字段约定。
|
|
|
|
### 7.2 任务清单
|
|
|
|
- 在后端建立一份明确的 artifact 协议定义
|
|
- 明确字段命名、类型、兼容策略
|
|
- 明确版本管理规则
|
|
|
|
### 7.3 协议要求
|
|
|
|
必须支持:
|
|
|
|
- 文本 artifact
|
|
- 代码 artifact
|
|
- 标题
|
|
- 当前版本索引
|
|
- 历史版本列表
|
|
- 后续支持局部改写
|
|
|
|
### 7.4 版本规则
|
|
|
|
- 每次 AI 整体生成,生成 `contents[0]`
|
|
- 每次 AI 重写,追加一个新版本
|
|
- `currentIndex` 指向当前版本
|
|
- 历史版本默认只保留在线程状态中,不额外落库
|
|
|
|
### 7.5 建议约束
|
|
|
|
- `index` 从 1 开始
|
|
- `currentIndex` 必须落在 `contents` 范围内
|
|
- `type` 只允许 `"text"` 或 `"code"`
|
|
|
|
### 7.6 验收标准
|
|
|
|
- 前后端字段完全一致
|
|
- 状态协议有明确默认值和边界规则
|
|
|
|
---
|
|
|
|
## 8. 阶段三:接入 `canvas_agent`
|
|
|
|
### 8.1 任务目标
|
|
|
|
在现有 Agent 体系中注册一个独立的 Canvas Agent。
|
|
|
|
### 8.2 任务清单
|
|
|
|
- 新建 `packages/harness/deerflow/agents/canvas_agent/`
|
|
- 新建 `agent.py`
|
|
- 新建 `prompt.py`
|
|
- 新建 `state.py`
|
|
- 修改 [factory.py](../../offline-backend-20260512/backend/packages/harness/deerflow/agents/factory.py)
|
|
|
|
### 8.3 注册方式建议
|
|
|
|
建议将 `canvas_agent` 作为一个显式 assistant id 暴露给 LangGraph 运行时。
|
|
|
|
前端调用时:
|
|
|
|
- `assistant_id=canvas_agent`
|
|
|
|
### 8.4 Agent 设计原则
|
|
|
|
- Canvas Agent 不负责 DeerFlow 全部工具生态
|
|
- 首版专注于:
|
|
- 生成文档
|
|
- 重写文档
|
|
- 局部改写
|
|
- 跟进回复
|
|
|
|
### 8.5 工具策略
|
|
|
|
首版建议:
|
|
|
|
- 不强依赖 shell/sandbox
|
|
- 不强依赖 present_files
|
|
- 先把生成与改写链路做好
|
|
|
|
后续可以根据需要接入文件导出能力。
|
|
|
|
### 8.6 验收标准
|
|
|
|
- `canvas_agent` 可被识别
|
|
- 前端能以 assistant id 调用它
|
|
- 不影响 `lead_agent`
|
|
|
|
---
|
|
|
|
## 9. 阶段四:Canvas 状态与图定义
|
|
|
|
### 9.1 任务目标
|
|
|
|
为 Canvas Agent 定义清晰、最小但可扩展的状态结构。
|
|
|
|
### 9.2 任务清单
|
|
|
|
- 新建 `canvas_agent/state.py`
|
|
- 定义图状态
|
|
- 约束与 `ThreadState` 的映射方式
|
|
|
|
### 9.3 建议状态字段
|
|
|
|
- `messages`
|
|
- `_messages` 或等价内部消息
|
|
- `artifact`
|
|
- `highlighted_text`
|
|
- `highlighted_code`
|
|
- `quick_action_id`
|
|
- `web_search_enabled`
|
|
- `web_search_results`
|
|
- `next`
|
|
|
|
### 9.4 状态设计建议
|
|
|
|
优先复用 LangGraph 原生消息 reducer。
|
|
|
|
对结构化字段,尽量采用:
|
|
|
|
- 可整体替换
|
|
- 易序列化
|
|
- 无 Python 特殊对象依赖
|
|
|
|
### 9.5 验收标准
|
|
|
|
- 状态能驱动 Canvas 节点运行
|
|
- 状态可被序列化回线程
|
|
|
|
---
|
|
|
|
## 10. 阶段五:Canvas 图最小节点闭环
|
|
|
|
### 10.1 任务目标
|
|
|
|
先实现最小闭环,不要一开始就追求 open-canvas 全量功能。
|
|
|
|
### 10.2 首版最小节点
|
|
|
|
建议至少实现:
|
|
|
|
- `route_user_intent`
|
|
- `reply_general_input`
|
|
- `generate_artifact`
|
|
- `rewrite_artifact`
|
|
- `generate_followup`
|
|
|
|
### 10.3 节点职责
|
|
|
|
#### `route_user_intent`
|
|
|
|
判断用户当前意图:
|
|
|
|
- 普通聊天
|
|
- 新建 artifact
|
|
- 重写当前 artifact
|
|
|
|
#### `reply_general_input`
|
|
|
|
仅返回普通消息,不更新 artifact。
|
|
|
|
#### `generate_artifact`
|
|
|
|
根据用户需求生成第一版 artifact。
|
|
|
|
#### `rewrite_artifact`
|
|
|
|
根据当前 artifact 和用户请求生成新版本。
|
|
|
|
#### `generate_followup`
|
|
|
|
在 artifact 更新后补一条自然语言消息。
|
|
|
|
### 10.4 输出要求
|
|
|
|
必须至少更新:
|
|
|
|
- `messages`
|
|
- `artifact`
|
|
|
|
### 10.5 验收标准
|
|
|
|
- 无 artifact 时能生成新 artifact
|
|
- 有 artifact 时能整体重写
|
|
- 重写后版本数增加
|
|
|
|
---
|
|
|
|
## 11. 阶段六:Prompt 设计与模型调用封装
|
|
|
|
### 11.1 任务目标
|
|
|
|
把 Canvas 模式的 prompt 和模型调用逻辑集中管理。
|
|
|
|
### 11.2 任务清单
|
|
|
|
- 在 `canvas_agent/prompt.py` 中集中定义 prompt 常量
|
|
- 在 `canvas_agent/agent.py` 或节点工具模块中封装模型调用
|
|
|
|
### 11.3 最少需要的 prompt
|
|
|
|
- 新建 artifact prompt
|
|
- 整体重写 artifact prompt
|
|
- 路由判断 prompt
|
|
- followup prompt
|
|
|
|
### 11.4 设计建议
|
|
|
|
提示词必须显式约束:
|
|
|
|
- 输出完整文档还是局部片段
|
|
- 是否允许修改类型
|
|
- 是否允许修改标题
|
|
- 对文本和代码的输出格式要求
|
|
|
|
### 11.5 模型调用封装建议
|
|
|
|
不要在每个节点里重复拼模型配置。
|
|
|
|
建议提供统一函数:
|
|
|
|
- `get_canvas_model(...)`
|
|
- `invoke_canvas_model(...)`
|
|
|
|
### 11.6 验收标准
|
|
|
|
- prompt 集中管理
|
|
- 节点中模型调用逻辑可复用
|
|
|
|
---
|
|
|
|
## 12. 阶段七:Gateway 线程接口兼容
|
|
|
|
### 12.1 任务目标
|
|
|
|
让前端读取线程状态时能拿到结构化 `artifact`。
|
|
|
|
### 12.2 任务清单
|
|
|
|
- 检查 [threads.py](../../offline-backend-20260512/backend/app/gateway/routers/threads.py)
|
|
- 扩展线程 state 响应的 `values`
|
|
- 确保 `artifact` 字段会被安全返回
|
|
|
|
### 12.3 要求
|
|
|
|
- `GET /api/threads/{id}`
|
|
- 线程历史
|
|
- 状态读取接口
|
|
|
|
都要兼容 `artifact`
|
|
|
|
### 12.4 注意事项
|
|
|
|
- 历史 checkpoint 可能没有 `artifact`
|
|
- 旧线程必须兼容
|
|
- 结构化字段不能被错误裁剪
|
|
|
|
### 12.5 验收标准
|
|
|
|
- 前端取线程时能拿到 `artifact`
|
|
- 刷新页面后 Canvas 内容能恢复
|
|
|
|
---
|
|
|
|
## 13. 阶段八:流式输出适配
|
|
|
|
### 13.1 任务目标
|
|
|
|
让 Canvas 模式的 artifact 能通过 LangGraph 流实时更新。
|
|
|
|
### 13.2 任务清单
|
|
|
|
- 检查运行时序列化逻辑
|
|
- 确保 `artifact` 在流事件中可见
|
|
- 明确前端消费 `values` 还是 `updates`
|
|
|
|
### 13.3 输出建议
|
|
|
|
首版允许采用较简单策略:
|
|
|
|
- 每次节点完成后输出完整 `artifact`
|
|
|
|
不强制首版做精细的 token 级 artifact 局部流。
|
|
|
|
### 13.4 原因
|
|
|
|
完整对象覆盖更新:
|
|
|
|
- 容易实现
|
|
- 容易调试
|
|
- 前后端一致性更好
|
|
|
|
### 13.5 二期方向
|
|
|
|
后续再考虑:
|
|
|
|
- 局部 chunk 更新
|
|
- 文本与代码差异化流式拼接
|
|
|
|
### 13.6 验收标准
|
|
|
|
- 前端发送请求时,artifact 能跟随 run 更新
|
|
- 流结束后状态与线程最终值一致
|
|
|
|
---
|
|
|
|
## 14. 阶段九:模型接口扩展
|
|
|
|
### 14.1 任务目标
|
|
|
|
让前端能拿到适合 Canvas 模式的模型能力信息。
|
|
|
|
### 14.2 任务清单
|
|
|
|
- 扩展 [models.py](../../offline-backend-20260512/backend/app/gateway/routers/models.py)
|
|
- 扩展模型响应结构
|
|
|
|
### 14.3 现有字段之外建议新增
|
|
|
|
- `provider`
|
|
- `supports_vision`
|
|
- `supports_tool_calling`
|
|
- `supports_canvas_generation`
|
|
- `supports_canvas_rewrite`
|
|
- `supports_canvas_code_edit`
|
|
- `supports_streaming_text`
|
|
- `supports_streaming_tool_calls`
|
|
- `is_local`
|
|
- `base_url`
|
|
|
|
### 14.4 注意事项
|
|
|
|
不是所有字段都必须从配置文件显式写出。
|
|
|
|
可以采用:
|
|
|
|
- 配置直出
|
|
- provider 推断
|
|
- 默认值补齐
|
|
|
|
### 14.5 验收标准
|
|
|
|
- 前端模型选择器能获取足够元数据
|
|
- 本地模型和云模型能区分
|
|
|
|
---
|
|
|
|
## 15. 阶段十:本地模型支持与配置统一
|
|
|
|
### 15.1 任务目标
|
|
|
|
支持像 open-canvas 一样自由配置本地模型,但配置真源在 DeerFlow。
|
|
|
|
### 15.2 原则
|
|
|
|
- 以 `config.yaml` 为唯一真源
|
|
- 前端不依赖 open-canvas 的 TS 模型表
|
|
- 后端负责把配置转换成前端可消费的能力描述
|
|
|
|
### 15.3 首批支持范围
|
|
|
|
推荐先支持:
|
|
|
|
- Ollama
|
|
- OpenAI-compatible 本地服务
|
|
|
|
例如:
|
|
|
|
- LM Studio
|
|
- vLLM
|
|
- LocalAI
|
|
- One API/OpenAI 兼容代理
|
|
|
|
### 15.4 配置要求
|
|
|
|
建议模型配置支持以下字段:
|
|
|
|
- `name`
|
|
- `display_name`
|
|
- `use`
|
|
- `model`
|
|
- `api_key`
|
|
- `base_url`
|
|
- `supports_vision`
|
|
- `supports_thinking`
|
|
- `supports_reasoning_effort`
|
|
- `supports_tool_calling`
|
|
- `is_local`
|
|
|
|
### 15.5 Canvas 额外能力字段
|
|
|
|
建议再增加:
|
|
|
|
- `supports_canvas_generation`
|
|
- `supports_canvas_rewrite`
|
|
- `supports_canvas_code_edit`
|
|
|
|
### 15.6 验收标准
|
|
|
|
- 配置本地模型后 `/api/models` 可见
|
|
- `canvas_agent` 可调用本地模型
|
|
- 至少文本生成和整体改写可用
|
|
|
|
---
|
|
|
|
## 16. 阶段十一:整体重写节点完善
|
|
|
|
### 16.1 任务目标
|
|
|
|
让已有 artifact 能被稳定整体重写并产生新版本。
|
|
|
|
### 16.2 任务清单
|
|
|
|
- 实现 `rewrite_artifact`
|
|
- 明确文本与代码两种重写路径
|
|
- 维护标题和类型变更规则
|
|
|
|
### 16.3 规则建议
|
|
|
|
- 默认保持当前类型
|
|
- 用户明确要求时才允许改类型
|
|
- 默认保持标题
|
|
- 用户明确换主题时可更新标题
|
|
|
|
### 16.4 结果写入规则
|
|
|
|
- 新版本追加到 `contents`
|
|
- `currentIndex` 指向新版本
|
|
|
|
### 16.5 验收标准
|
|
|
|
- 文本 artifact 整体重写正常
|
|
- 代码 artifact 整体重写正常
|
|
- 历史版本保留
|
|
|
|
---
|
|
|
|
## 17. 阶段十二:局部改写节点
|
|
|
|
### 17.1 任务目标
|
|
|
|
支持文本和代码的局部选区修改。
|
|
|
|
### 17.2 任务清单
|
|
|
|
- 新增 `update_highlighted_text.py`
|
|
- 新增 `update_highlighted_code.py`
|
|
- 在状态中消费选区信息
|
|
|
|
### 17.3 文本局部改写要求
|
|
|
|
输入:
|
|
|
|
- 当前 `fullMarkdown`
|
|
- 选区起止
|
|
- 选中原文
|
|
- 用户修改指令
|
|
|
|
输出:
|
|
|
|
- 只返回替换片段或返回完整合并后文本
|
|
|
|
### 17.4 首版建议
|
|
|
|
首版优先采用“后端返回完整合并后文本”策略。
|
|
|
|
原因:
|
|
|
|
- 前端逻辑更轻
|
|
- 状态更一致
|
|
|
|
### 17.5 代码局部改写要求
|
|
|
|
输入:
|
|
|
|
- 当前代码全文
|
|
- 选区代码片段
|
|
- 选区边界
|
|
- 用户修改指令
|
|
|
|
输出:
|
|
|
|
- 新的完整代码文本
|
|
|
|
### 17.6 验收标准
|
|
|
|
- 文本局部改写成功
|
|
- 代码局部改写成功
|
|
- 未选中区域不被误改
|
|
|
|
---
|
|
|
|
## 18. 阶段十三:快捷动作节点
|
|
|
|
### 18.1 任务目标
|
|
|
|
支持前端动作栏触发不同的重写行为。
|
|
|
|
### 18.2 任务清单
|
|
|
|
- 新增 `quick_actions.py`
|
|
- 定义动作 id 到 prompt 的映射
|
|
- 在路由节点中识别 `quick_action_id`
|
|
|
|
### 18.3 首版动作建议
|
|
|
|
文本:
|
|
|
|
- `expand`
|
|
- `shorten`
|
|
- `formalize`
|
|
- `casualize`
|
|
|
|
代码:
|
|
|
|
- `add_comments`
|
|
- `add_logs`
|
|
- `fix_bugs`
|
|
|
|
### 18.4 实现建议
|
|
|
|
动作不要散落在各节点里硬编码。
|
|
|
|
建议集中成映射表:
|
|
|
|
- `action_id -> prompt builder`
|
|
|
|
### 18.5 验收标准
|
|
|
|
- 指定动作可触发不同结果
|
|
- 动作执行后生成新版本
|
|
|
|
---
|
|
|
|
## 19. 阶段十四:Web 搜索增强
|
|
|
|
### 19.1 任务目标
|
|
|
|
支持 Canvas 模式在需要时引入搜索结果。
|
|
|
|
### 19.2 任务清单
|
|
|
|
- 新增 `web_search.py`
|
|
- 消费 `web_search_enabled`
|
|
- 将搜索结果写入 `web_search_results`
|
|
|
|
### 19.3 首版策略
|
|
|
|
首版只做:
|
|
|
|
- 打开开关后,生成/重写前先搜索
|
|
- 把结果摘要注入 prompt
|
|
|
|
先不做复杂页面抓取多轮链路。
|
|
|
|
### 19.4 验收标准
|
|
|
|
- 开关打开时能引入搜索结果
|
|
- 结果可回传前端展示
|
|
|
|
---
|
|
|
|
## 20. 阶段十五:线程创建与 metadata 策略
|
|
|
|
### 20.1 任务目标
|
|
|
|
让 Canvas 线程在创建和恢复时保留必要上下文。
|
|
|
|
### 20.2 任务清单
|
|
|
|
- 约定前端创建 Canvas thread 时写入 metadata
|
|
- 后端在 thread search / get 中保留这些 metadata
|
|
|
|
### 20.3 推荐 metadata
|
|
|
|
- `ui_mode: "canvas"`
|
|
- `agent_id: "canvas_agent"`
|
|
- `model_name`
|
|
- `canvas_type` 可选
|
|
|
|
### 20.4 验收标准
|
|
|
|
- Canvas thread 与普通 thread 可区分
|
|
- 恢复线程时前端可据 metadata 恢复 UI
|
|
|
|
---
|
|
|
|
## 21. 阶段十六:Gateway 扩展接口评估
|
|
|
|
### 21.1 任务目标
|
|
|
|
判断是否需要新增 Canvas 专用 REST API。
|
|
|
|
### 21.2 原则
|
|
|
|
能复用现有线程状态与 LangGraph 流,就不要新增太多新接口。
|
|
|
|
### 21.3 可以先不新增的接口
|
|
|
|
- Canvas artifact 专用 CRUD
|
|
- Canvas 快捷动作专用接口
|
|
|
|
这些都可以先通过:
|
|
|
|
- 线程 state
|
|
- runs.stream
|
|
|
|
完成。
|
|
|
|
### 21.4 可能需要新增的接口
|
|
|
|
二期如果需要,可增加:
|
|
|
|
- `GET /api/canvas/models`
|
|
- `POST /api/canvas/export`
|
|
- `POST /api/canvas/convert-to-file`
|
|
|
|
### 21.5 验收标准
|
|
|
|
- 首版尽量少增接口
|
|
- 协议尽量复用现有线程与 run 模型
|
|
|
|
---
|
|
|
|
## 22. 阶段十七:持久化与导出联动
|
|
|
|
### 22.1 任务目标
|
|
|
|
让 Canvas 文档能和现有文件 artifact 体系联动。
|
|
|
|
### 22.2 任务清单
|
|
|
|
- 规划导出接口
|
|
- 规划 artifact 转文件逻辑
|
|
- 规划从 Canvas 生成 outputs 文件
|
|
|
|
### 22.3 推荐能力
|
|
|
|
- 保存为 `.md`
|
|
- 保存为代码文件
|
|
- 将导出文件加入现有 `artifacts: list[str]`
|
|
|
|
### 22.4 首版建议
|
|
|
|
这部分不是最早阶段必须做的。
|
|
|
|
建议等核心 Canvas 生成与重写稳定后再接。
|
|
|
|
### 22.5 验收标准
|
|
|
|
- 导出文件能出现在现有 artifact 文件体系中
|
|
|
|
---
|
|
|
|
## 23. 测试清单
|
|
|
|
### 23.1 单元测试建议
|
|
|
|
优先覆盖:
|
|
|
|
- artifact 协议校验
|
|
- 版本追加逻辑
|
|
- 标题/类型变更规则
|
|
- 文本局部改写拼接逻辑
|
|
- 代码局部改写拼接逻辑
|
|
|
|
### 23.2 集成测试建议
|
|
|
|
应覆盖:
|
|
|
|
- 创建 Canvas thread
|
|
- 首次生成 artifact
|
|
- 整体重写
|
|
- 局部改写
|
|
- 模型切换
|
|
- 本地模型调用
|
|
|
|
### 23.3 回归测试重点
|
|
|
|
重点检查现有功能未被破坏:
|
|
|
|
- 普通 `lead_agent` 对话
|
|
- 文件型 `artifacts`
|
|
- uploads
|
|
- memory
|
|
- scheduled tasks
|
|
|
|
### 23.4 验收标准
|
|
|
|
- Canvas 新功能通过
|
|
- 现有 DeerFlow 核心路径无回归
|
|
|
|
---
|
|
|
|
## 24. 推荐开发顺序
|
|
|
|
强烈建议按以下顺序推进:
|
|
|
|
1. 线程状态扩展
|
|
2. artifact 协议定稿
|
|
3. `canvas_agent` 注册
|
|
4. 最小图闭环
|
|
5. 线程读取与流式返回
|
|
6. 模型接口扩展
|
|
7. 整体生成与整体改写
|
|
8. 局部改写
|
|
9. 快捷动作
|
|
10. 本地模型增强
|
|
11. Web 搜索增强
|
|
12. 导出联动
|
|
|
|
不要一开始就做:
|
|
|
|
- 快捷动作全集
|
|
- 局部 token 级流式 artifact 更新
|
|
- 复杂导出体系
|
|
|
|
---
|
|
|
|
## 25. 多人协作拆分建议
|
|
|
|
### A 组:状态与线程
|
|
|
|
- `thread_state.py`
|
|
- 线程协议
|
|
- Gateway 线程兼容
|
|
|
|
### B 组:Canvas Agent 图
|
|
|
|
- `canvas_agent`
|
|
- prompt
|
|
- route/generate/rewrite/followup
|
|
|
|
### C 组:模型与配置
|
|
|
|
- `/api/models`
|
|
- 本地模型配置
|
|
- provider 兼容
|
|
|
|
### D 组:增强能力
|
|
|
|
- 局部改写
|
|
- 快捷动作
|
|
- Web 搜索
|
|
|
|
---
|
|
|
|
## 26. 首版最小可交付范围
|
|
|
|
后端首版建议只交付这些:
|
|
|
|
- 扩展线程状态支持 `artifact`
|
|
- 新增 `canvas_agent`
|
|
- 支持文本/代码 artifact 首次生成
|
|
- 支持整体重写
|
|
- 支持版本历史
|
|
- 扩展 `/api/models` 返回 Canvas 能力元数据
|
|
- 支持至少一种本地模型接入
|
|
|
|
首版先不强制:
|
|
|
|
- 局部高亮改写
|
|
- 全量快捷动作
|
|
- 搜索增强
|
|
- 导出文件联动
|
|
|
|
---
|
|
|
|
## 27. 总验收标准
|
|
|
|
### 27.1 功能层
|
|
|
|
- 无 artifact 时可生成新文档
|
|
- 有 artifact 时可整体重写
|
|
- 版本历史可保留
|
|
- 前端刷新后可恢复
|
|
|
|
### 27.2 协议层
|
|
|
|
- `artifact` 字段稳定
|
|
- 流式与最终线程状态一致
|
|
- 模型能力字段可用于前端判断
|
|
|
|
### 27.3 兼容层
|
|
|
|
- 不破坏 `lead_agent`
|
|
- 不破坏现有 `artifacts: list[str]`
|
|
- 不破坏现有 Gateway 核心接口
|
|
|
|
---
|
|
|
|
## 28. 下一步建议
|
|
|
|
完成本文档后,建议继续补两份工程文档:
|
|
|
|
### 28.1 Canvas 状态协议文档
|
|
|
|
明确:
|
|
|
|
- `artifact`
|
|
- `highlighted_text`
|
|
- `highlighted_code`
|
|
- `quick_action_id`
|
|
- `web_search_results`
|
|
|
|
的最终 JSON 格式。
|
|
|
|
### 28.2 Canvas Agent 节点接口文档
|
|
|
|
逐节点定义:
|
|
|
|
- 输入字段
|
|
- 输出字段
|
|
- prompt 责任
|
|
- 错误处理
|
|
|
|
这样进入实际编码时会更顺畅。
|