docs(codebase): generate codebase map

This commit is contained in:
肖应宇 2026-04-07 11:37:10 +08:00
parent 6b900ccb60
commit 6411b3d7a0
7 changed files with 1042 additions and 0 deletions

View File

@ -0,0 +1,141 @@
# 架构分析
**Analysis Date:** 2026-04-07
## 模式概览
**Overall:** 分层单体 + 前后端分离 + 运行时内核Harness与应用壳层App拆分
**Key Characteristics:**
- 后端采用 `Harness(Core)``Gateway/Channels(App)` 分层,依赖方向固定为 `app.* -> deerflow.*`,反向依赖禁止(见 `backend/docs/HARNESS_APP_SPLIT.md`
- 前端采用 Next.js App Router页面层(`src/app`)与领域能力层(`src/core`)分离UI 组件集中在 `src/components`
- 运行时通过单例对象管理(`RunManager`、`StreamBridge`、`checkpointer`、`store`),由网关生命周期统一初始化(`backend/app/gateway/deps.py`
**结论:**
当前架构边界清晰后续规划应优先沿“Gateway 负责协议与路由、Harness 负责运行时与智能体能力、Frontend core 负责数据访问”的既有分层扩展,避免跨层直接调用。
## 分层设计
**前端展示与路由层Next App Router:**
- Purpose: 负责页面路由、布局装配、页面级 Provider 注入
- Location: `frontend/src/app`
- Contains: `layout.tsx`、`page.tsx`、`workspace/*`、`api/*` Route Handler
- Depends on: `frontend/src/components`、`frontend/src/core`、`frontend/src/server`
- Used by: 浏览器请求与 Next.js 运行时
**前端领域能力层Core:**
- Purpose: 负责 API 客户端、流式会话、线程管理、上传、设置与 i18n 逻辑
- Location: `frontend/src/core`
- Contains: `core/threads/hooks.ts`、`core/api/api-client.ts`、`core/*/api.ts|hooks.ts`
- Depends on: `@langchain/langgraph-sdk`、`@tanstack/react-query`、后端 API
- Used by: `frontend/src/components/workspace/*` 与页面组件
**后端 API 网关层App Gateway:**
- Purpose: 负责 HTTP 协议适配、路由聚合、SSE 输出、线程与运行生命周期接口
- Location: `backend/app/gateway`
- Contains: `app.py`、`deps.py`、`services.py`、`routers/*.py`
- Depends on: `deerflow.runtime`、`deerflow.config`、`deerflow.agents`
- Used by: 前端、第三方客户端、IM 渠道服务
**后端 IM 渠道层App Channels:**
- Purpose: 负责飞书/Slack/Telegram 等外部消息通道接入与消息转发
- Location: `backend/app/channels`
- Contains: `service.py`、`manager.py`、`feishu.py`、`slack.py`、`telegram.py`
- Depends on: `deerflow` 核心能力与 Gateway 配置
- Used by: 网关生命周期在启动阶段触发(`backend/app/gateway/app.py`
**后端运行时内核层Harness:**
- Purpose: 负责 Agent 构建、Middleware 编排、工具系统、运行时状态与流桥接
- Location: `backend/packages/harness/deerflow`
- Contains: `agents/`、`runtime/`、`tools/`、`sandbox/`、`skills/`、`models/`、`config/`
- Depends on: LangChain/LangGraph 与基础设施依赖
- Used by: `backend/app/gateway/*` 与潜在 SDK/CLI 调用
## 关键数据/控制流
**Flow 1: Web 会话流式对话(主链路)**
1. 前端聊天页通过 `useThreadStream` 发起 `runs.stream``frontend/src/core/threads/hooks.ts`
2. LangGraph SDK 客户端调用网关流式接口(`frontend/src/core/api/api-client.ts` -> `/api/langgraph`
3. Gateway 路由进入 `thread_runs.py``runs.py`,委派 `start_run``backend/app/gateway/routers/thread_runs.py`, `backend/app/gateway/services.py`
4. `start_run` 创建 RunRecord 并启动后台任务,运行 `make_lead_agent` 构建的 Agent 图(`backend/packages/harness/deerflow/agents/lead_agent/agent.py`
5. 运行时事件通过 `MemoryStreamBridge` 发布,`sse_consumer` 序列化为 SSE 推送到前端(`backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
6. 前端 `useStream` 消费增量状态,刷新消息、标题、子任务与线程列表缓存(`frontend/src/core/threads/hooks.ts`
**Flow 2: 线程生命周期与状态持久化**
1. 前端线程列表调用 `threads.search`,线程详情页读取/更新状态(`frontend/src/core/threads/hooks.ts`
2. Gateway `threads.py` 通过 `store` + `checkpointer` 读写线程元数据与 checkpoint
3. run 完成后,服务层将 checkpoint 中的标题回写线程 store`_sync_thread_title_after_run``backend/app/gateway/services.py`
**Flow 3: 前端 API 代理转发(非 LangGraph SDK 路径)**
1. 前端 Route Handler 接收 `/api/memory/*` 请求(`frontend/src/app/api/memory/[...path]/route.ts`
2. 直接代理至 `NEXT_PUBLIC_BACKEND_BASE_URL` 对应网关地址
3. Gateway 处理并返回,前端透明透传响应头与响应体
**State Management:**
- 前端 UI 状态React State + Context例如 `ArtifactsProvider`、`SubtasksProvider`
- 前端服务端状态React Query线程列表、突变后失效重取
- 后端运行状态:`RunManager` 内存注册表(运行中任务)
- 后端持久状态LangGraph checkpointer + store线程状态、checkpoint、元数据
## 关键抽象
**Run 生命周期抽象RunManager + RunRecord:**
- Purpose: 统一 run 的创建、冲突策略、取消、状态迁移
- Examples: `backend/packages/harness/deerflow/runtime/runs/manager.py`
- Pattern: 内存注册表 + asyncio 锁保护并发一致性
**流桥接抽象StreamBridge:**
- Purpose: 将后台执行事件转换为可订阅的事件流
- Examples: `backend/packages/harness/deerflow/runtime/stream_bridge/base.py`, `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
- Pattern: 每 run 一条队列 + END/HEARTBEAT 哨兵事件
**Agent 组装抽象make_lead_agent / create_deerflow_agent:**
- Purpose: 基于配置与上下文动态装配模型、工具与 middleware 链
- Examples: `backend/packages/harness/deerflow/agents/lead_agent/agent.py`, `backend/packages/harness/deerflow/agents/factory.py`
- Pattern: “配置驱动 + 有序中间件管线 + 条件启用能力”
**前端会话编排抽象useThreadStream:**
- Purpose: 屏蔽流式协议细节,提供统一发送消息/停止运行/状态更新能力
- Examples: `frontend/src/core/threads/hooks.ts`
- Pattern: Hook 封装 SDK + optimistic UI + query cache 同步
## 关键入口
**Gateway 入口:**
- Location: `backend/app/gateway/app.py`
- Triggers: `uvicorn app.gateway.app:app`(见 `backend/Makefile`
- Responsibilities: 应用启动、router 装配、生命周期内 runtime 单例初始化
**Gateway 运行时依赖入口:**
- Location: `backend/app/gateway/deps.py`
- Triggers: FastAPI lifespan 调用 `langgraph_runtime`
- Responsibilities: 创建/销毁 `stream_bridge`、`checkpointer`、`store`、`run_manager`
**前端根入口:**
- Location: `frontend/src/app/layout.tsx`
- Triggers: Next.js App Router 根布局渲染
- Responsibilities: 注入主题与 i18n Provider
**前端工作台入口:**
- Location: `frontend/src/app/workspace/layout.tsx`, `frontend/src/app/workspace/chats/[thread_id]/page.tsx`
- Triggers: 访问 `/workspace/*`
- Responsibilities: QueryClient 注入、侧边栏控制、聊天线程交互
## 错误处理策略
**Strategy:** 分层兜底 + 协议一致化
**Patterns:**
- 路由层用 HTTP 状态码表达失败,依赖层缺失返回 503`backend/app/gateway/deps.py`
- 流式执行失败统一在服务层记录并通过 SSE/最终状态输出(`backend/app/gateway/services.py`
- 前端流式错误统一 toast 呈现并清理 optimistic 状态(`frontend/src/core/threads/hooks.ts`
## 跨切面关注点
**Logging:** 后端在网关入口统一配置 logging模块内按 `logger` 输出(`backend/app/gateway/app.py`
**Validation:** 请求模型使用 Pydantic运行配置做字段规整`normalize_stream_modes`、`build_run_config`
**Authentication:** 前端通过 `better-auth` 路由处理认证(`frontend/src/app/api/auth/[...all]/route.ts`, `frontend/src/server/better-auth/*`);网关核心 API 当前以部署侧网关/Nginx 控制为主
---
*Architecture analysis: 2026-04-07*

View File

@ -0,0 +1,141 @@
# Codebase Concerns
**Analysis Date:** 2026-04-07
## 简短结论
当前代码库后端能力完整、测试数量较多但在“生产安全基线”和“运行时一致性”上存在高优先级缺口API 鉴权缺失、回滚语义未闭环、流式事件链路缺少可恢复能力。前端主要问题是关键模块体量偏大与测试覆盖不均衡,短期会拖慢迭代速度,中期会放大回归风险。
## 优先级建议(面向规划)
- P0立即补齐网关鉴权与访问控制补全 rollback 真回滚语义。
- P1近期修复消息角色归一化错误完善 SSE 可恢复性与丢事件观测。
- P2排期拆分超大前端组件、收敛 demo 静态资源体积、减少“声明支持但未实现”的 API 选项。
## Tech Debt
**运行时回滚语义未实现(高优先级):**
- Issue: 取消 run 时支持 `action=rollback`,但实际未执行 checkpoint 回滚,仅记录日志并 `pass`
- Files: `backend/packages/harness/deerflow/runtime/runs/worker.py`
- Impact: 前端/调用方会认为“已回滚”,但线程状态可能仍保留部分中间写入,导致状态一致性问题。
- Fix approach: 在 `rollback` 分支接入 checkpointer 的真实回退 API`pre_run_checkpoint_id` 恢复),并补充回滚前后状态断言测试(成功、失败、并发取消三类)。
**后端代码布局存在“空 src + 实际实现在 packages”认知负债中优先级:**
- Issue: 业务实现集中在 `backend/packages/harness/deerflow/`,而 `backend/src/` 仅有缓存产物目录结构,容易误导新贡献者。
- Files: `backend/packages/harness/deerflow/`, `backend/src/`
- Impact: 新代码落点不稳定、审查成本上升、重构时容易出现重复实现。
- Fix approach: 在贡献文档和目录说明中明确“单一真实源码根”;清理或显式标注 `backend/src/` 的用途,避免“影子目录”持续存在。
**前端关键组件体量过大(中优先级):**
- Issue: 交互核心组件单文件体量偏大,状态/视图/副作用耦合。
- Files: `frontend/src/components/ai-elements/prompt-input.tsx`, `frontend/src/components/workspace/input-box.tsx`, `frontend/src/components/workspace/artifacts/artifact-file-detail.tsx`
- Impact: 修改单一功能易触发连带回归,评审与测试成本高。
- Fix approach: 以“状态管理、上传/附件、动作菜单、发送流程”拆分子模块;每次拆分同步补充组件级测试。
## Known Bugs
**消息角色被错误归一化为 HumanMessage高优先级:**
- Symptoms: 非 `user/human` 的消息(如 system/ai/tool在输入归一化中被降级为 `HumanMessage`
- Files: `backend/app/gateway/services.py`
- Trigger: `normalize_input()` 处理 `messages` 列表时遇到非用户角色。
- Workaround: 调用端仅传用户消息;系统消息改走其他配置通道。
**artifact 文本判定后仍可能触发 UTF-8 解码异常(中优先级):**
- Symptoms: 文件被判定为“文本”后直接 `read_text(encoding="utf-8")`,遇到非 UTF-8 内容可能返回 500。
- Files: `backend/app/gateway/routers/artifacts.py`
- Trigger: `is_text_file_by_content()` 返回 true但实际编码非 UTF-8。
- Workaround: 使用 `download=true` 强制下载,避免 inline 文本解码路径。
**API 声明支持 `enqueue` 但运行时不支持(中优先级):**
- Symptoms: 请求模型允许 `multitask_strategy="enqueue"`,但运行时抛 `UnsupportedStrategyError`501
- Files: `backend/app/gateway/routers/thread_runs.py`, `backend/packages/harness/deerflow/runtime/runs/manager.py`
- Trigger: 客户端按 schema 传入 `enqueue`
- Workaround: 客户端仅使用 `reject|interrupt|rollback`
## Security Considerations
**网关缺少统一鉴权/鉴别层(高优先级):**
- Risk: 线程、上传、技能、memory、run 控制等接口可被未授权调用(取决于外围网络暴露)。
- Files: `backend/app/gateway/app.py`, `backend/app/gateway/routers/*.py`
- Current mitigation: 注释说明依赖外层 nginx代码内无显式 `Depends` 鉴权依赖。
- Recommendations: 在网关层增加统一认证中间件JWT/API Key/Session 任一),并对高风险写操作路由做细粒度授权。
**本地 host bash 仅“尽力防护”,非强隔离(中高优先级):**
- Risk: 启用 `allow_host_bash` 后,命令路径校验强调 best-effort且对 bash 写入限制不等同于读写工具限制。
- Files: `backend/packages/harness/deerflow/sandbox/tools.py`
- Current mitigation: 绝对路径校验、路径遍历检查、file:// 阻断、虚拟路径替换。
- Recommendations: 将 host bash 默认硬禁用;在生产配置强制容器沙箱;增加审计日志与策略开关(按工具/命令白名单)。
## Performance Bottlenecks
**流式桥接队列容量有限且存在丢事件(中优先级):**
- Problem: 单 run 队列默认上限 256发布超时会丢事件且仅日志告警。
- Files: `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
- Cause: 内存队列 + 固定容量 + 没有持久化重放。
- Improvement path: 引入可重放后端Redis/持久队列)或增大可配置容量;将 dropped_count 暴露为指标并设置告警阈值。
**前端仓库包含较大 demo 资产,影响构建/分发体积(中优先级):**
- Problem: `frontend/public/demo/` 包含较多图片/视频与线程快照。
- Files: `frontend/public/demo/threads/**`
- Cause: demo 内容直接入仓并随静态资源参与交付。
- Improvement path: 将大型 demo 资产迁移到对象存储/CDN 或按环境开关构建;保留最小样例集。
## Fragile Areas
**Run 生命周期与 SSE 消费链路耦合(中高优先级):**
- Files: `backend/app/gateway/services.py`, `backend/app/gateway/routers/thread_runs.py`, `backend/packages/harness/deerflow/runtime/runs/manager.py`, `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
- Why fragile: 断线策略、取消语义、状态迁移、队列清理分散在多处,边界行为(断线+取消+重连)容易退化。
- Safe modification: 先补“状态机契约测试”再改逻辑;对 `cancel/rollback/interrupt` 统一建表驱动测试。
- Test coverage: 后端测试较多,但“断线重连 + 事件重放 + 回滚一致性”端到端场景仍有缺口。
**前端输入与工件详情模块变更风险高(中优先级):**
- Files: `frontend/src/components/workspace/input-box.tsx`, `frontend/src/components/ai-elements/prompt-input.tsx`, `frontend/src/components/workspace/artifacts/artifact-file-detail.tsx`
- Why fragile: 单文件承担过多职责,状态路径复杂。
- Safe modification: 采用“先抽 hooks/子组件,后迁移调用点”的两阶段改造;每步保留行为快照测试。
- Test coverage: `frontend/src/` 下单元测试文件较少(仅少量),复杂交互主要依赖 E2E。
## Scaling Limits
**Run/Stream 元数据以内存为中心,重启后状态不连续(中高优先级):**
- Current capacity: 单进程内存字典 + 队列run 记录会延迟清理stream 事件不支持回放。
- Limit: 进程重启或横向扩容后,`Last-Event-ID` 无法恢复历史事件;跨实例一致性弱。
- Files: `backend/packages/harness/deerflow/runtime/runs/manager.py`, `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
- Scaling path: 引入跨实例共享存储(持久 run registry + 可回放事件流),并将 `last_event_id` 变为可用恢复机制。
## Dependencies at Risk
**前端依赖面较宽,升级波动风险上升(中优先级):**
- Risk: UI/渲染/动画/编辑器与 AI SDK 依赖较多,任一主版本变化可能触发连锁适配。
- Impact: 构建稳定性与行为一致性风险上升。
- Files: `frontend/package.json`
- Migration plan: 建立“核心依赖分层升级策略”渲染内核、AI SDK、UI 库分批升级)与最小回归清单。
## Missing Critical Features
**后端 API 层缺少内建访问控制能力(高优先级):**
- Problem: 关键写操作接口缺少统一认证与授权依赖。
- Blocks: 无法安全对公网或多租户环境直接暴露网关。
- Files: `backend/app/gateway/app.py`, `backend/app/gateway/routers/*.py`
**SSE 可恢复协议未形成闭环(中高优先级):**
- Problem: 桥接层注明接受 `last_event_id` 但忽略重放。
- Blocks: 客户端断线恢复体验与长任务稳定性。
- Files: `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
## Test Coverage Gaps
**前端复杂交互缺少充分单元/组件测试(中优先级):**
- What's not tested: 输入框状态机、附件生命周期、artifact 详情多分支渲染的细粒度行为。
- Files: `frontend/src/components/workspace/input-box.tsx`, `frontend/src/components/ai-elements/prompt-input.tsx`, `frontend/src/components/workspace/artifacts/artifact-file-detail.tsx`
- Risk: 小改动引发 UI 行为回归且难快速定位。
- Priority: High
**安全基线测试缺少“未认证访问”负向用例(高优先级):**
- What's not tested: 未携带认证凭据访问关键 API 的拒绝路径(当前实现层面未内建)。
- Files: `backend/app/gateway/routers/*.py`, `backend/tests/`
- Risk: 安全能力依赖部署外部组件,环境漂移即暴露风险。
- Priority: High
---
*Concerns audit: 2026-04-07*

View File

@ -0,0 +1,112 @@
# Coding Conventions
**Analysis Date:** 2026-04-07
## Naming Patterns
**Files:**
- Python 使用 `snake_case.py`,按领域分层放置,例如 `backend/packages/harness/deerflow/config/app_config.py`、`backend/packages/harness/deerflow/agents/lead_agent/agent.py`。
- Backend 测试文件统一 `test_*.py`,位于 `backend/tests/`,例如 `backend/tests/test_client.py`、`backend/tests/test_stream_bridge.py`。
- Frontend 页面与组件文件使用 `kebab-case.tsx` 或目录约定命名,例如 `frontend/src/app/workspace/page.tsx`、`frontend/src/components/workspace/workspace-container.tsx`。
- Frontend E2E 测试使用 `*.spec.ts`,位于 `frontend/tests/e2e/`;轻量模块测试使用 `*.test.ts``*.test.mjs`,例如 `frontend/src/core/api/stream-mode.test.ts`
**Functions:**
- Python 函数与内部 helper 统一 `snake_case`,例如 `_make_e2e_config``backend/tests/test_client_e2e.py`)、`get_available_tools``backend/packages/harness/deerflow/tools/tools.py`)。
- TypeScript/JavaScript 函数统一 `camelCase`,例如 `copyToClipboard``frontend/src/lib/utils.ts`)、`skipIfMissingThread``frontend/tests/e2e/support/chat-helpers.ts`)。
**Variables:**
- Python 常量使用全大写下划线,如 `BUILTIN_TOOLS``backend/packages/harness/deerflow/tools/tools.py`)。
- TS 常量通常 `camelCase`,跨测试配置使用全大写语义常量,如 `THREAD_FOR_WELCOME``frontend/tests/e2e/support/chat-helpers.ts`)。
**Types:**
- Python 使用类型注解(`list[str]`、`dict[str, Any]`)与 `pydantic` 模型,见 `backend/packages/harness/deerflow/config/app_config.py`
- Frontend 使用 TypeScript 严格模式,并偏向显式返回类型(例如 `Promise<void>` in `frontend/src/lib/utils.ts`)。
## Code Style
**Formatting:**
- Backend 使用 `ruff format`;规则来源 `backend/ruff.toml``quote-style = "double"``indent-style = "space"``line-length = 240`)。
- Frontend 使用 `prettier` + `prettier-plugin-tailwindcss`,配置在 `frontend/prettier.config.js`CI 中执行 `pnpm format`check 模式)。
**Linting:**
- Backend 通过 `ruff check .`,启用 `E/F/I/UP``backend/ruff.toml`)。
- Frontend 通过 `eslint` flat config`frontend/eslint.config.js`),叠加 `next/core-web-vitals``typescript-eslint` type-checked 规则。
- Frontend 强制导入顺序(`import/order`)与分组换行,内部别名 `@/**` 归类为 internal。
## Import Organization
**Order:**
1. 标准库/内建模块(如 `import os`、`import path from "path"`)。
2. 第三方依赖(如 `from pydantic import BaseModel`、`import { expect, test } from "@playwright/test"`)。
3. 项目内部模块(如 `from deerflow...`、`from "@/env"`)。
**Path Aliases:**
- Frontend 启用 `@/* -> ./src/*``frontend/tsconfig.json`);新增代码应优先使用该别名替代跨层级相对路径。
- Backend 无类似别名约定;使用包内绝对导入 `deerflow.*`(见 `backend/packages/harness/deerflow/client.py`)。
## Error Handling
**Patterns:**
- Backend 在参数/配置非法时直接抛出 `ValueError` / `FileNotFoundError`,示例见 `backend/packages/harness/deerflow/config/app_config.py``backend/packages/harness/deerflow/client.py`
- Backend 在可降级场景使用 `try/except` + `logger.warning/error`,不中断主流程(例如 MCP/ACP 工具加载,`backend/packages/harness/deerflow/tools/tools.py`)。
- Frontend 偏向显式 guard + return例如 `frontend/src/app/workspace/page.tsx` 的条件重定向)。
## Logging
**Framework:** `logging`Python + `console`Frontend 局部)
**Patterns:**
- Backend 统一模块级 `logger = logging.getLogger(__name__)`记录关键分支、fallback、装载结果`backend/packages/harness/deerflow/tools/tools.py`)。
- Frontend 存在业务调试日志(`console.log` / `console.warn`)用于 iframe 与失败分支,见 `frontend/src/lib/utils.ts`、`frontend/src/core/uploads/prompt-input-files.test.mjs`(通过 mock 断言 warning
## Comments
**When to Comment:**
- Backend 在复杂中间件顺序、循环依赖绕过、测试分层原则等高认知负担位置写块注释,示例:
- `backend/packages/harness/deerflow/agents/lead_agent/agent.py`middleware 顺序约束)
- `backend/tests/conftest.py`(循环导入链与 mock 注入原因)
- `backend/tests/test_client_e2e.py`(测试金字塔与运行边界)
**JSDoc/TSDoc:**
- Frontend 在共享工具函数处使用 JSDoc 解释行为与边界(`frontend/src/lib/utils.ts`)。
- Backend 在公共类/函数上常见 docstring测试文件顶部也有职责说明。
## Function Design
**Size:** 无硬性行数限制;允许长函数,但通过“局部 helper + 注释分段”提高可读性(见 `backend/packages/harness/deerflow/client.py`)。
**Parameters:**
- 偏向显式关键字参数与默认值Python 常见 `*` 强制关键字调用(`DeerFlowClient.__init__`)。
- 测试 helper 参数常封装为对象/字典,减少调用点重复(`frontend/tests/e2e/support/chat-helpers.ts`)。
**Return Values:**
- Python 公开接口通常返回结构化对象或强类型(如 `StreamEvent` dataclass in `backend/packages/harness/deerflow/client.py`)。
- Frontend helper 对异常场景返回 `null/undefined` 并由调用方判定(`frontend/src/core/uploads/prompt-input-files.test.mjs` 覆盖该行为)。
## Module Design
**Exports:**
- Python 模块多为显式函数/类导出,避免通配导入;测试按模块行为组织断言。
- Frontend 使用 `export function` / `export const` 的命名导出为主(`frontend/src/lib/utils.ts`)。
**Barrel Files:**
- 后端包存在少量 `__init__.py` 聚合导出(如 `backend/packages/harness/deerflow/models/__init__.py`)。
- Frontend 未形成统一 barrel 规范;新增公共模块应优先“就近导出 + 明确 import 路径”,避免深层 barrel 隐式耦合。
## CI / 质量门禁约定
- CI 工作流定义于 `.github/workflows/lint-check.yml`、`.github/workflows/backend-unit-tests.yml`。
- 合入前最低门禁:
- Backend: `make lint`ruff check + format --check
- Frontend: `pnpm format`、`pnpm lint`、`pnpm typecheck`、`pnpm build`
- Backend 单测:`make test`pytest
- Frontend E2E 未纳入默认 CI 工作流;仅定义本地命令 `pnpm test:e2e``frontend/package.json`)。
## 简短结论
- 本仓库已形成“双栈分治”质量约定Backend 以 `ruff + pytest` 为核心Frontend 以 `eslint + prettier + typecheck + build` 为核心,并在 CI 中执行。
- 后续新增代码应严格沿用现有命名、导入分组与异常处理风格;新增测试优先补齐 Frontend 单元测试执行入口与 E2E 的 CI 接入,避免“有测试文件但无持续校验”。
---
*Convention analysis: 2026-04-07*

View File

@ -0,0 +1,168 @@
# 外部集成审计Tech Focus
**分析日期:** 2026-04-07
## APIs 与外部服务
**LLM Provider通过配置动态切换**
- OpenAI / Anthropic / Gemini / DeepSeek / MiniMax / OpenRouter示例在 `config.example.yaml``models`
- SDK/适配层:`langchain_openai`、`langchain_anthropic`、`langchain_google_genai`、`langchain_deepseek``backend/packages/harness/pyproject.toml`
- 认证:`config.yaml` 中模型字段支持 `$ENV_VAR` 注入(`backend/packages/harness/deerflow/config/app_config.py`
**MCPModel Context Protocol服务**
- 支持 `stdio` / `sse` / `http` 三种传输(`backend/packages/harness/deerflow/mcp/client.py`
- 管理接口:`GET/PUT /api/mcp/config``backend/app/gateway/routers/mcp.py`
- 配置文件:`extensions_config.json``backend/packages/harness/deerflow/config/extensions_config.py`
- OAuthHTTP/SSE MCP 可启用 token 自动刷新(`backend/packages/harness/deerflow/mcp/oauth.py`
**Web 搜索与抓取:**
- DuckDuckGo`ddgs`,免 key`backend/packages/harness/deerflow/community/ddg_search/tools.py`
- Jina Reader`https://r.jina.ai/`(可选 `JINA_API_KEY``backend/packages/harness/deerflow/community/jina_ai/jina_client.py`
- Tavily可配置 api_key`backend/packages/harness/deerflow/community/tavily/tools.py`
- Firecrawl可配置 api_key`backend/packages/harness/deerflow/community/firecrawl/tools.py`
- InfoQuest`INFOQUEST_API_KEY``backend/packages/harness/deerflow/community/infoquest/infoquest_client.py`
**IM 渠道:**
- Feishu/Lark、Slack、Telegram、WeCom`backend/app/channels/*.py`
- Feishu`app_id`/`app_secret`
- Slack`bot_token`/`app_token`
- Telegram`bot_token`
- WeCom`bot_id`/`bot_secret`
**前端到后端接口:**
- 前端直接调用网关 REST`/api/models`、`/api/memory`、`/api/skills`、`/api/mcp/config`、`/api/threads/*/uploads``frontend/src/core/*/api.ts`
- 前端通过 `@langchain/langgraph-sdk` 调用 LangGraph API`frontend/src/core/api/api-client.ts`
**结论:**
- 集成模式以“配置驱动 + 适配层解耦”为主;新增三方服务优先走 `config.yaml` / `extensions_config.json`,避免硬编码。
## 数据存储
**会话状态与持久化:**
- Checkpointer 支持:`memory` / `sqlite` / `postgres``backend/packages/harness/deerflow/config/checkpointer_config.py`
- 默认示例为 SQLite`config.example.yaml` 的 `checkpointer` 段)
- 同步 Store 与 checkpointer 类型保持一致(`backend/packages/harness/deerflow/runtime/store/provider.py`
**文件与工件存储:**
- 上传与工件基于本地文件系统路径(`backend/app/gateway/routers/uploads.py`、`backend/app/gateway/routers/artifacts.py`、`backend/packages/harness/deerflow/uploads/manager.py`
**缓存:**
- 未检测到 Redis/Memcached 等独立缓存服务;主要使用进程内缓存/单例(如配置缓存与客户端缓存,见 `backend/packages/harness/deerflow/config/*.py`、`frontend/src/core/api/api-client.ts`
**结论:**
- 当前默认可单机落地SQLite + 本地文件);若进入多实例部署,应优先切换 Postgres checkpointer/store 并外置文件存储策略。
## 身份认证与权限
**前端身份认证:**
- `better-auth``frontend/src/server/better-auth/config.ts`、`frontend/src/app/api/auth/[...all]/route.ts`
- 当前配置启用 `emailAndPassword`GitHub 相关变量为可选(`frontend/src/env.js`
**MCP 授权:**
- MCP HTTP/SSE OAuth 支持 `client_credentials``refresh_token``backend/packages/harness/deerflow/mcp/oauth.py`
- 可针对每个 MCP server 配置 headers/env/oauth`backend/packages/harness/deerflow/config/extensions_config.py`
**结论:**
- 认证面分为“前端会话认证”和“后端集成凭证认证”两条线;规划时应分离处理,避免混用同一密钥域。
## 观测与可观测性
**Tracing**
- LangSmith`LANGSMITH_*` / `LANGCHAIN_*`)与 Langfuse`LANGFUSE_*`)双支持(`backend/packages/harness/deerflow/config/tracing_config.py`
- 回调挂载在模型创建阶段(`backend/packages/harness/deerflow/tracing/factory.py`、`backend/packages/harness/deerflow/models/factory.py`
**日志:**
- Gateway 使用 Python logging支持 `LOG_LEVEL``backend/app/gateway/app.py`
**结论:**
- Tracing 已具备按环境开关能力,建议在 staging 强制开启至少一个 provider减少线上问题追踪成本。
## CI/CD 与部署集成
**CI**
- GitHub Actions
- 后端单测(`.github/workflows/backend-unit-tests.yml`
- 前后端 lint/type/build`.github/workflows/lint-check.yml`
**部署:**
- 一体化入口:`make dev` / `make up`(根 `Makefile`
- Nginx 统一反代前端 + LangGraph + Gateway`backend/README.md`、`docker/nginx/nginx.local.conf`、`docker/nginx/nginx.conf`
- Docker 编排文件存在:`docker/docker-compose.yaml`、`docker/docker-compose-dev.yaml`
**结论:**
- 已形成本地开发与容器部署双通道;下一步提升点是把 e2ePlaywright纳入 CI 的默认门禁。
## 环境变量(关键清单)
**前端(`frontend/src/env.js`**
- `BETTER_AUTH_SECRET`
- `BETTER_AUTH_GITHUB_CLIENT_ID`
- `BETTER_AUTH_GITHUB_CLIENT_SECRET`
- `GITHUB_OAUTH_TOKEN`
- `NEXT_PUBLIC_BACKEND_BASE_URL`
- `NEXT_PUBLIC_LANGGRAPH_BASE_URL`
- `NEXT_PUBLIC_STATIC_WEBSITE_ONLY`
- `SKIP_ENV_VALIDATION`
**后端网关(`backend/app/gateway/config.py`、`backend/app/gateway/app.py`**
- `GATEWAY_HOST`
- `GATEWAY_PORT`
- `CORS_ORIGINS`
- `SKILL_CONTENT_API_URL`
- `LOG_LEVEL`
**后端主配置解析(`backend/packages/harness/deerflow/config/app_config.py`**
- `DEER_FLOW_CONFIG_PATH`
- `DEER_FLOW_EXTENSIONS_CONFIG_PATH`
- 以及 `config.yaml` / `extensions_config.json` 中所有 `$VAR` 占位符
**Tracing`backend/packages/harness/deerflow/config/tracing_config.py`**
- `LANGSMITH_TRACING` / `LANGCHAIN_TRACING_V2` / `LANGCHAIN_TRACING`
- `LANGSMITH_API_KEY` / `LANGCHAIN_API_KEY`
- `LANGSMITH_PROJECT` / `LANGCHAIN_PROJECT`
- `LANGSMITH_ENDPOINT` / `LANGCHAIN_ENDPOINT`
- `LANGFUSE_TRACING`
- `LANGFUSE_PUBLIC_KEY`
- `LANGFUSE_SECRET_KEY`
- `LANGFUSE_BASE_URL`
**Channels`config.example.yaml`、`backend/app/channels/service.py`**
- `FEISHU_APP_ID`、`FEISHU_APP_SECRET`
- `SLACK_BOT_TOKEN`、`SLACK_APP_TOKEN`
- `TELEGRAM_BOT_TOKEN`
- `WECOM_BOT_ID`、`WECOM_BOT_SECRET`
- `DEER_FLOW_CHANNELS_LANGGRAPH_URL`
- `DEER_FLOW_CHANNELS_GATEWAY_URL`
**社区工具与凭证:**
- `JINA_API_KEY``backend/packages/harness/deerflow/community/jina_ai/jina_client.py`
- `INFOQUEST_API_KEY``backend/packages/harness/deerflow/community/infoquest/infoquest_client.py`
- Claude/Codex 凭证相关变量(`backend/packages/harness/deerflow/models/credential_loader.py`
**结论:**
- 环境变量来源分散于前端 env schema、后端配置加载器和工具客户端后续应维护一份单独的“env contract”用于部署校验。
## Webhook 与回调
**Incoming**
- 未检测到典型公网 webhook 接收实现IM 渠道主要是 WebSocket/轮询主动连接(`backend/app/channels/*.py`
**Outgoing**
- MCP OAuth token endpoint按 server 配置动态请求,`backend/packages/harness/deerflow/mcp/oauth.py`
- 远端技能内容拉取接口(`SKILL_CONTENT_API_URL``backend/app/gateway/config.py`
- 第三方搜索/抓取 APIJina、InfoQuest、Tavily、Firecrawl
**结论:**
- 当前外部交互以“主动调用”为主,公网暴露面较小;若新增 webhook应同步补充签名校验与重放保护。
## 总结(规划导向)
- DeerFlow 当前集成体系已经具备“多模型 + 多工具 + 多渠道 + 可选追踪”的完整闭环,且关键接入点均配置化。
- 后续规划优先级建议:
1. 统一环境变量契约与部署校验(降低配置错误率)
2. 多实例场景的持久化与文件存储升级Postgres + 外置对象存储)
3. 外部集成回归套件MCP OAuth、IM 渠道、搜索工具)持续化到 CI
---
*集成审计完成于 2026-04-07基于 `backend`、`frontend`、`config.example.yaml`、CI 工作流与网关/工具实现静态审计)*

130
.planning/codebase/STACK.md Normal file
View File

@ -0,0 +1,130 @@
# 技术栈Tech Focus
**分析日期:** 2026-04-07
## 语言
**主语言:**
- Python 3.12+后端网关、Agent Runtime、MCP/工具系统(`backend/pyproject.toml`、`backend/.python-version`、`backend/langgraph.json`、`backend/packages/harness/pyproject.toml`
- TypeScriptES2022前端 App Router、API 代理、状态管理与 UI 组件(`frontend/package.json`、`frontend/tsconfig.json`
**次要语言:**
- JavaScriptESMNext.js/工具链配置(`frontend/next.config.js`、`frontend/eslint.config.js`、`frontend/prettier.config.js`
- YAML运行时模型与工具编排配置`config.example.yaml`、`config.yaml`
**结论:**
- 代码库是 Python + TypeScript 双栈,后端偏 AI runtime 编排,前端偏 Next.js 应用层版本锚点明确Python 3.12、Node 22
## 运行时
**后端运行时:**
- Python 3.12`backend/.python-version`、`backend/langgraph.json`
- FastAPI + Uvicorn`backend/pyproject.toml`、`backend/Makefile`
- LangGraph Server`backend/Makefile` 的 `uv run langgraph dev`
**前端运行时:**
- Node.js 22+`frontend/README.md`CI 也固定 Node 22`.github/workflows/lint-check.yml`
- Next.js 16 + React 19`frontend/package.json`
**结论:**
- 运行时依赖在文档与 CI 双重约束,团队应以 Python 3.12 + Node 22 作为本地/CI 基线。
## 依赖与包管理
**后端:**
- 包管理器:`uv``Makefile`、`backend/Makefile`
- 工作区:`backend` 主工程 + `backend/packages/harness``backend/pyproject.toml` 的 `[tool.uv.workspace]`
- 锁文件:`backend/uv.lock`(存在)
**前端:**
- 包管理器:`pnpm@10.26.2``frontend/package.json`
- 锁文件:`frontend/pnpm-lock.yaml`(存在)
**结论:**
- 后端与前端均已锁版本;规划阶段应坚持 `uv sync` + `pnpm install --frozen-lockfile`,避免跨环境漂移。
## 核心框架
**后端核心:**
- `langgraph` / `langgraph-api`Agent 图运行与 API 能力(`backend/packages/harness/pyproject.toml`
- `langchain` 生态:模型适配、工具接口、回调(`backend/packages/harness/pyproject.toml`、`backend/packages/harness/deerflow/models/factory.py`
- `fastapi` + `sse-starlette`:网关 REST 与流式接口(`backend/pyproject.toml`、`backend/app/gateway/routers/runs.py`
**前端核心:**
- `next` 16App Router+ `react` 19`frontend/package.json`
- `@tanstack/react-query`:前端数据获取与缓存(`frontend/src/core/*/hooks.ts`
- `@langchain/langgraph-sdk`:前端直连 LangGraph API`frontend/src/core/api/api-client.ts`
**结论:**
- 架构重心是 LangGraph runtime + FastAPI gateway + Next.js UI 三段式,新增能力应优先挂靠这三层边界。
## 构建与开发工具
**后端:**
- 启动:`uv run langgraph dev`、`uv run uvicorn ...``backend/Makefile`
- 测试:`pytest``backend/pyproject.toml`、`backend/Makefile`
- 质量:`ruff``backend/ruff.toml`
**前端:**
- 开发:`next dev --turbo``frontend/package.json`
- 构建:`next build``frontend/package.json`
- 质量:`eslint` + `typescript-eslint` + `prettier``frontend/eslint.config.js`、`frontend/prettier.config.js`
- E2E`playwright``frontend/playwright.config.ts`
**CI**
- GitHub Actions后端单测、前后端 lint/type/build`.github/workflows/backend-unit-tests.yml`、`.github/workflows/lint-check.yml`
**结论:**
- 工具链完整,且 CI 已覆盖“格式/Lint/类型/构建/后端单测”;后续 phase 应直接复用现有流水线,不建议新建并行脚本体系。
## 关键依赖(对规划最有影响)
**AI 与模型:**
- `langchain-openai`、`langchain-anthropic`、`langchain-google-genai`、`langchain-deepseek``backend/packages/harness/pyproject.toml`
- `langgraph-sdk`(前后端均使用,`backend/pyproject.toml`、`frontend/package.json`
**集成与工具:**
- `langchain-mcp-adapters`MCP 多服务接入,`backend/packages/harness/pyproject.toml`
- `slack-sdk`、`python-telegram-bot`、`lark-oapi`、`wecom-aibot-python-sdk``backend/pyproject.toml`、`backend/app/channels/*.py`
- `tavily-python`、`firecrawl-py`、`ddgs`、`duckdb``backend/packages/harness/pyproject.toml`
**前端平台能力:**
- `better-auth`(鉴权,`frontend/src/server/better-auth/config.ts`
- `@t3-oss/env-nextjs` + `zod`(环境变量校验,`frontend/src/env.js`
**结论:**
- 依赖风险主要在第三方模型/搜索/IM SDK 的 API 兼容性;规划中应为这些“边缘适配层”预留回归验证。
## 配置体系
**应用配置:**
- 主配置:`config.yaml`(示例:`config.example.yaml`),支持 `$ENV_VAR` 解析(`backend/packages/harness/deerflow/config/app_config.py`
- 扩展配置:`extensions_config.json`MCP servers + skills 状态,`backend/packages/harness/deerflow/config/extensions_config.py`
**前端配置:**
- 运行时环境校验:`frontend/src/env.js`
- 前端 API 基址解析:`frontend/src/core/config/index.ts`
**敏感配置文件存在性(仅记录存在,不读取值):**
- 根目录 `.env`
- 前端 `frontend/.env`、`frontend/.env.example`
**结论:**
- 配置源分层清晰(主业务配置 + 扩展配置 + 前端 env新功能应优先扩展现有配置模型不要散落新增私有配置文件。
## 平台与部署要求
**开发:**
- `make install` 安装前后端依赖(`Makefile`
- `make dev` 一键启动LangGraph + Gateway + Frontend + Nginx`Makefile``backend/README.md`
**生产/容器:**
- 前端 `next.config.js` 使用 `output: "standalone"``frontend/next.config.js`
- 支持 Docker 部署脚本与编排目录(`docker/docker-compose.yaml`、`docker/docker-compose-dev.yaml`、`scripts/deploy.sh`、`scripts/docker.sh`
**结论:**
- 默认目标是容器化/反向代理下的整套部署;后续规划应把“网关端口与反代路径一致性”作为上线前强校验项。
---
*栈分析完成于 2026-04-07基于 `backend`、`frontend`、根目录构建脚本与配置文件的静态审计)*

View File

@ -0,0 +1,144 @@
# 代码库结构
**Analysis Date:** 2026-04-07
## 目录布局
```text
deerflow2/
├── backend/ # Python 后端Gateway + Harness workspace
│ ├── app/ # 应用壳层HTTP Gateway、IM channels
│ ├── packages/harness/deerflow/ # 运行时内核agent/runtime/tools/sandbox
│ ├── tests/ # 后端测试
│ └── pyproject.toml # 后端 workspace 定义
├── frontend/ # Next.js 前端App Router
│ ├── src/app/ # 页面与路由入口
│ ├── src/components/ # UI 与业务组件
│ ├── src/core/ # 领域能力层API/hooks/types
│ ├── src/server/ # 服务端能力auth
│ └── tests/ # 前端 E2E 测试
├── docker/ # 部署与网关编排
├── docs/ # 项目文档
├── scripts/ # 开发与部署脚本
└── skills/ # 技能资源public skills
```
## 目录职责
**`backend/app`:**
- Purpose: 面向产品的 API/协议层,不承载核心 agent 组装逻辑
- Contains: `gateway/app.py`、`gateway/routers/*.py`、`channels/*.py`
- Key files: `backend/app/gateway/app.py`, `backend/app/gateway/services.py`, `backend/app/channels/service.py`
**`backend/packages/harness/deerflow`:**
- Purpose: 可复用内核层,封装智能体运行时与能力模块
- Contains: `agents/`, `runtime/`, `tools/`, `sandbox/`, `skills/`, `models/`, `config/`
- Key files: `backend/packages/harness/deerflow/agents/lead_agent/agent.py`, `backend/packages/harness/deerflow/runtime/runs/manager.py`, `backend/packages/harness/deerflow/runtime/stream_bridge/memory.py`
**`frontend/src/app`:**
- Purpose: Next.js 路由与页面入口,组合 UI 与 core 能力
- Contains: 根布局、workspace 页面、docs 页面、API route handlers
- Key files: `frontend/src/app/layout.tsx`, `frontend/src/app/workspace/layout.tsx`, `frontend/src/app/workspace/chats/[thread_id]/page.tsx`
**`frontend/src/components`:**
- Purpose: 可复用 UI 组件与工作台业务组件
- Contains: `ui/*`, `workspace/*`, `landing/*`, `ai-elements/*`
- Key files: `frontend/src/components/workspace/workspace-container.tsx`, `frontend/src/components/workspace/chats/use-thread-chat.ts`
**`frontend/src/core`:**
- Purpose: 前端领域逻辑层统一管理数据访问、hook 与类型
- Contains: `threads/`, `api/`, `memory/`, `models/`, `skills/`, `uploads/`, `settings/`
- Key files: `frontend/src/core/threads/hooks.ts`, `frontend/src/core/api/api-client.ts`, `frontend/src/core/config/index.ts`
## 关键文件位置
**Entry Points:**
- `backend/app/gateway/app.py`: FastAPI 入口与路由总装
- `frontend/src/app/layout.tsx`: 前端根布局入口
- `frontend/src/app/page.tsx`: Landing 页面入口
- `frontend/src/app/workspace/page.tsx`: 工作台入口重定向
**Configuration:**
- `backend/pyproject.toml`: Python 依赖与 workspace
- `frontend/package.json`: 前端依赖与脚本
- `frontend/tsconfig.json`: TS 编译策略与 `@/*` 别名
- `frontend/next.config.js`: Next 构建输出与运行参数
- `config.yaml`: 运行配置主文件(存在,勿在规划文档中记录敏感值)
**Core Logic:**
- `backend/app/gateway/services.py`: run 生命周期业务逻辑与 SSE 格式化
- `backend/app/gateway/routers/thread_runs.py`: 线程 run 协议接口
- `backend/packages/harness/deerflow/agents/lead_agent/agent.py`: 主 Agent 构建逻辑
- `backend/packages/harness/deerflow/runtime/runs/manager.py`: run 状态机与并发控制
- `frontend/src/core/threads/hooks.ts`: 流式会话、线程列表、突变逻辑
- `frontend/src/core/api/api-client.ts`: LangGraph SDK 客户端封装
**Testing:**
- `backend/tests/*.py`: 后端单元/集成测试
- `frontend/tests/e2e/*`: 前端端到端测试Playwright
- `frontend/src/core/**/*.{test.ts,test.mjs}`: 前端核心逻辑单测
## 命名约定
**Files:**
- 前端组件文件:`kebab-case.tsx`(示例:`workspace-container.tsx`
- 前端 Hook 文件:`use-*.ts` 或 `hooks.ts`(示例:`use-thread-chat.ts`, `threads/hooks.ts`
- 后端 Python 文件:`snake_case.py`(示例:`thread_runs.py`, `memory_middleware.py`
- 路由文件:按资源名命名(示例:`routers/threads.py`, `routers/models.py`
**Directories:**
- 前端按职责分层:`app`(路由)/`components`(视图)/`core`(领域)
- 后端按边界分层:`app`(应用层)/`packages/harness/deerflow`(内核层)
## 新增代码放置规则(可执行)
**新增后端 API 端点:**
- 路由定义: `backend/app/gateway/routers/{resource}.py`
- 复用业务逻辑: 优先放 `backend/app/gateway/services.py` 或同级 `{resource}_service.py`
- 依赖获取: 统一通过 `backend/app/gateway/deps.py`
**新增 Agent/运行时能力:**
- Agent 相关: `backend/packages/harness/deerflow/agents/*`
- 运行时状态/流: `backend/packages/harness/deerflow/runtime/*`
- 工具能力: `backend/packages/harness/deerflow/tools/*``community/*`
- 规则: 不在 `backend/app/*` 写核心算法/agent 编排逻辑
**新增前端业务功能:**
- 页面入口: `frontend/src/app/{route}/page.tsx`
- 业务组件: `frontend/src/components/workspace/*`(工作台)或对应域目录
- 数据访问与副作用: `frontend/src/core/{domain}/api.ts|hooks.ts|types.ts`
- 规则: 页面层只做组合,不直接实现复杂 API 调用细节
**新增 Next API 代理:**
- 放置于 `frontend/src/app/api/{resource}/route.ts``[...path]/route.ts`
- 代理逻辑复用现有 `proxyRequest` 模式(参考 `frontend/src/app/api/memory/[...path]/route.ts`
**新增测试:**
- 后端: `backend/tests/test_{feature}.py`
- 前端 core 单测: 与实现文件同目录 `*.test.ts|*.test.mjs`
- 前端 E2E: `frontend/tests/e2e/{feature}.spec.ts`
## 特殊目录说明
**`backend/src`:**
- Purpose: 旧路径兼容目录(当前主要为 `__pycache__`
- Generated: Yes当前内容以缓存文件为主
- Committed: Yes目录存在于仓库
- Guidance: 新代码不要放在 `backend/src`,统一落到 `backend/packages/harness/deerflow``backend/app`
**`frontend/.next` 与 `frontend/node_modules`:**
- Purpose: 构建产物与依赖缓存
- Generated: Yes
- Committed: No应视为构建输出
**`.planning/codebase`:**
- Purpose: 供后续规划/执行代理读取的代码库认知文档
- Generated: Yes由 map 阶段生成)
- Committed: Yes作为流程资产
**结论:**
该仓库最重要的结构约束是“后端 Harness 与 App 分层 + 前端 app/components/core 三段分层”。后续新增功能应优先沿既有目录职责扩展,避免把核心逻辑散落到路由层或页面层。
---
*Structure analysis: 2026-04-07*

View File

@ -0,0 +1,206 @@
# Testing Patterns
**Analysis Date:** 2026-04-07
## Test Framework
**Runner:**
- Backend: `pytest` (>=8.0.0, 定义于 `backend/pyproject.toml`)
- Frontend E2E: `@playwright/test` (定义于 `frontend/package.json`)
- Frontend 轻量单测: Node 内置 `node:test` + `node:assert/strict`(示例见 `frontend/src/core/api/stream-mode.test.ts`
- Config: `frontend/playwright.config.ts`E2EBackend 未检测到独立 `pytest.ini`/`tox.ini`
**Assertion Library:**
- Backend: `pytest` 原生断言
- Frontend E2E: Playwright `expect`
- Frontend 轻量单测: `node:assert/strict`
**Run Commands:**
```bash
cd backend && make test # 运行后端测试pytest tests/ -v
cd backend && make lint # 后端静态检查ruff check + format --check
cd frontend && pnpm test:e2e # 运行 Playwright E2E
cd frontend && pnpm test:e2e:ui # Playwright UI 模式
cd frontend && pnpm lint && pnpm typecheck # 前端质量门禁
```
## Test File Organization
**Location:**
- Backend 测试集中在 `backend/tests/`,按模块与能力拆分(如 `test_client.py`、`test_stream_bridge.py`)。
- Frontend E2E 在 `frontend/tests/e2e/`,辅助函数在 `frontend/tests/e2e/support/`
- Frontend 轻量模块测试与实现同目录共置(如 `frontend/src/core/uploads/*.test.mjs`)。
**Naming:**
- Python: `test_*.py`
- Playwright: `*.spec.ts`
- Node 内置测试: `*.test.ts` / `*.test.mjs`
**Structure:**
```text
backend/tests/test_*.py
frontend/tests/e2e/*.spec.ts
frontend/tests/e2e/support/*.ts
frontend/src/**/**.test.ts
frontend/src/**/**.test.mjs
```
## Test Structure
**Suite Organization:**
```python
# backend/tests/test_stream_bridge.py
@pytest.fixture
def bridge() -> MemoryStreamBridge:
return MemoryStreamBridge(queue_maxsize=256)
@pytest.mark.anyio
async def test_publish_subscribe(bridge: MemoryStreamBridge):
...
```
```typescript
// frontend/tests/e2e/input-and-compose.spec.ts
test.describe("聊天工作台 / 输入区与发送", () => {
test("DF-INPUT-001 ...", async ({ page }, testInfo) => {
...
});
});
```
**Patterns:**
- Setup pattern:
- Backend 使用 `conftest.py` 全局 fixture 与 import/mock 预处理(`backend/tests/conftest.py`)。
- E2E 使用 `chat-helpers.ts` 封装 URL 构建、页面打开、发送消息、线程前置校验。
- Teardown pattern:
- Backend 通过 `tmp_path` + `monkeypatch` 隔离文件系统与全局单例(`backend/tests/test_client_e2e.py`)。
- Frontend Node 测试手动还原 `globalThis.fetch`/`console.warn`。
- Assertion pattern:
- Backend 侧重行为与事件序列断言(含异常、边界、并发)。
- E2E 使用 `expect.poll` 与语义选择器(`getByTestId`、`getByRole`)减少时序抖动。
## Mocking
**Framework:** `unittest.mock` + `pytest.monkeypatch`Backend函数级覆写全局对象Frontend Node tests
**Patterns:**
```python
# backend/tests/test_model_factory.py
def _patch_factory(monkeypatch, app_config, model_class=FakeChatModel):
monkeypatch.setattr(factory_module, "get_app_config", lambda: app_config)
monkeypatch.setattr(factory_module, "resolve_class", lambda path, base: model_class)
```
```typescript
// frontend/src/core/uploads/prompt-input-files.test.mjs
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => { throw new Error("network down"); };
...
globalThis.fetch = originalFetch;
```
**What to Mock:**
- 外部依赖与昂贵路径LLM、网络请求、全局单例、文件系统路径。
- 与测试目标无关的中间件/副作用(如标题生成、内存队列)应在测试中关闭。
**What NOT to Mock:**
- 核心业务状态流与事件序列(例如 `MemoryStreamBridge` 的 publish/subscribe/end 行为)。
- E2E 页面路由与关键 UI 交互链路(应尽量走真实页面流程)。
## Fixtures and Factories
**Test Data:**
```python
# backend/tests/test_client.py
@pytest.fixture
def mock_app_config():
model = MagicMock()
model.name = "test-model"
...
return config
```
```typescript
// frontend/tests/e2e/support/chat-helpers.ts
export function newChatEntry(threadId: string) { ... }
export async function openChat(page: Page, url: string, options?: { expectInput?: boolean }) { ... }
```
**Location:**
- Backend 全局 fixture: `backend/tests/conftest.py`
- Backend 模块级 fixture/factory: 各 `backend/tests/test_*.py`
- Frontend E2E fixture/helper: `frontend/tests/e2e/support/chat-helpers.ts`
## Coverage
**Requirements:** 未检测到覆盖率阈值与强制 coverage 工具(无 `coverage.py`/`c8`/`nyc` 配置CI 未执行 coverage 报告)。
**View Coverage:**
```bash
Not applicable仓库未提供标准覆盖率命令
```
## Test Types
**Unit Tests:**
- Backend: 大量纯单测,重度使用 mock 与 monkeypatch覆盖配置解析、middleware、tools、runtime 细节。
- Frontend: 少量模块单测,采用 Node 内置测试框架,主要覆盖上传与 stream mode 边界。
**Integration Tests:**
- Backend: `test_client_e2e.py` 定位为“中层集成”,走真实模块链路并通过环境控制是否触发真实 LLM。
- Backend: 存在 `*_live.py` 用于更高成本的真实依赖验证(如 `backend/tests/test_client_live.py`、`backend/tests/test_create_deerflow_agent_live.py`)。
**E2E Tests:**
- Frontend: Playwright 场景化用例覆盖路由、输入、历史、artifact 面板等用户路径(`frontend/tests/e2e/*.spec.ts`)。
- 执行依赖线程相关环境变量(`FRONTEND_E2E_THREAD_ID` 等),缺失时通过 `testInfo.skip` 跳过。
## Common Patterns
**Async Testing:**
```python
@pytest.mark.anyio
async def test_heartbeat(bridge: MemoryStreamBridge):
await asyncio.wait_for(consumer(), timeout=2.0)
```
```typescript
await expect
.poll(async () => await page.locator(".is-user, .is-assistant").count(), { timeout: 30_000 })
.toBeGreaterThan(0);
```
**Error Testing:**
```python
with pytest.raises(ValueError, match="Invalid agent name"):
DeerFlowClient(agent_name="invalid name with spaces!")
```
```typescript
globalThis.fetch = async () => new Response("missing", { status: 404, statusText: "Not Found" });
const converted = await promptInputFilePartToFile(...);
assert.equal(converted, null);
```
## 分层执行与覆盖风险(可执行建议)
- 当前可稳定落地的分层执行顺序:
1. `cd backend && make lint && make test`
2. `cd frontend && pnpm format && pnpm lint && pnpm typecheck && pnpm build`
3. `cd frontend && pnpm test:e2e`(在具备线程测试数据的环境)
- 关键风险:
- Frontend 单元测试未接入统一脚本与 CI`package.json` 无 `test` 脚本CI 未跑 `test:e2e`)。
- 覆盖率无门槛,变更后“测试数量增长”不等于“关键路径被覆盖”。
- E2E 对外部线程数据依赖较强,易出现“跳过即通过”。
- 建议后续规划优先级:
1. 为 Frontend 增加统一单测命令并纳入 CI。
2. 在 CI 增加最小 E2E smoke可用固定 seed 数据或 mock 后端)。
3. 引入覆盖率报告(先观测,再设阈值)。
## 简短结论
- 仓库已具备较完整 Backend 测试金字塔与前端场景化 E2E 基础,但“前端自动化测试接入 CI 不完整、覆盖率无硬约束”是当前质量收敛的主要短板。
- 后续规划应优先补齐前端测试执行入口和 CI 集成,再推进覆盖率治理,才能让测试从“存在”转为“持续有效”。
---
*Testing analysis: 2026-04-07*