dashboard-nanobot/design/refactor-modularization-roa...

727 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Dashboard Nanobot 模块化重构与远端桥接演进方案
本文档用于指导当前项目的结构性重构,并为后续“支持同机/远端龙虾 + Docker/Native 双运行模式”升级提前抽离边界。
补充约束:本路线图负责说明“为什么拆、先拆什么”;具体“怎么拆、拆到什么边界”为强制执行项,统一以下文为准:
- `design/code-structure-standards.md`
目标不是一次性大改所有代码,而是先把未来 2 个核心问题理顺:
- 当前前端/后端过于集中,后续功能迭代成本越来越高
- 执行层默认绑定“本机 Docker + 本机文件系统”,无法自然扩展到远端与 Native 模式
## 1. 结论先行
### 1.1 前端必须拆,但优先做“页面内模块化”,不是重写 UI
当前前端最大的问题不是样式,而是页面级组件承担了太多职责:
- 页面状态
- API 调用
- 业务编排
- 视图渲染
- 弹窗
- 文件预览
- 表单保存
- WebSocket/轮询
因此,前端应优先按“页面 -> 业务区块 -> 通用能力”三层拆分。
### 1.2 后端必须拆代码结构,但不建议现在把中央 backend 再拆成多个部署服务
当前 `backend/main.py` 已经承担:
- API 路由
- Bot 生命周期
- Workspace 文件操作
- Runtime 状态判断
- 日志/监控
- Provider 测试
- 平台默认值拼装
这会让未来远端执行支持非常困难。
建议:
- 现在:先把 `backend` 按领域和 provider 分层拆开,保持 **一个 central backend 服务**
- 后续:新增一个 **独立部署的桥接服务 `dashboard-edge`**
也就是说:
- 中央控制面 backend保留继续作为统一 API、数据库、权限、审计入口
- 执行桥接层:新增独立服务,不再内嵌在 central backend 中
### 1.3 为了支持远端龙虾,必须引入桥接服务,但不需要修改 nanobot 核心
推荐结构:
- `dashboard-backend`
- 控制平面
- 统一前端 API
- DB / 权限 / 审计 / 聚合视图
- `dashboard-edge`
- 执行平面
- 部署在本机或远端节点
- 管理该节点上的 Docker / Native Bot
- 与 nanobot 的 `dashboard.py` channel 通信
这是未来最稳的演进方向。
### 1.4 `dashboard-edge` 应作为执行节点的标准组件
长期目标不是“只有远端机器需要 edge”而是
- 任何实际运行 Bot 的节点,都部署一个 `dashboard-edge`
- 同机部署场景下central backend 与 edge 可以位于同一台机器
- 远端部署场景下,在远端 Bot 所在机器部署 edge
也就是说:
- `dashboard-backend` 负责控制平面
- `dashboard-edge` 负责执行平面
- 一个节点一个 edge不是一个 Bot 一个 edge
这样本机与远端最终会走同一条执行链路,避免长期维护两套调用路径。
### 1.5 `dashboard-edge` 的长期职责不应只绑定 nanobot
当前第一阶段仍以 nanobot 为主,因为现有接入基础已经存在:
- workspace 生成
- `dashboard.py` channel
- 运行态日志解析
但从架构角度,`dashboard-edge` 应定位为“Bot Core Adapter Host”
- edge 负责对接不同 Bot 核心
- 每类核心通过 adapter/executor 做本地适配
- 对上统一输出 dashboard 可理解的生命周期、命令、工作区、日志与状态协议
因此,未来可以扩展出:
- `NanobotCoreAdapter`
- `LobsterCoreAdapter`
- 其它兼容 Bot Core Adapter
控制面不需要理解不同核心的内部细节,只需要依赖统一 provider 契约。
## 2. 当前项目的主要结构问题
### 2.1 Frontend 问题
- `frontend/src/modules/dashboard/BotDashboardModule.tsx` 体量过大,已经承担多个页面级职责
- `BotWizardModule.tsx` 同时负责创建流程、provider 测试、五个 MD 文件编辑
- `PlatformDashboardPage.tsx` 混合平台设置、资源视图、Bot 管理视图
- 页面内部状态与 API 编排严重耦合,局部重构成本很高
- 公共能力分散:
- Markdown 编辑器
- workspace markdown 渲染
- timezone 选项
- page size 缓存
- bot 访问工具
### 2.2 Backend 问题
- `backend/main.py` 是单体入口,所有领域逻辑都堆在同一文件
- 运行时逻辑默认直接依赖本机资源:
- Docker
- 本地工作区
- 本地 dashboard channel
- 路由层和业务层耦合严重
- 未来引入 remote/native 时,如果继续在 `main.py` 里堆条件分支,会快速失控
### 2.3 未来升级的真正分界线
本质上项目需要明确区分:
- 控制平面
- 执行平面
- nanobot 接入层
目前这三者是混在一起的。
## 3. 目标架构
### 3.1 总体分层
推荐把系统拆成 4 层:
1. `frontend`
- 页面、组件、交互、状态编排
2. `dashboard-backend`
- 统一 API、鉴权、DB、Provider 路由、审计
3. `dashboard-edge`
- 本机或远端节点执行代理
4. `nanobot + dashboard.py`
- Bot 本体,不修改核心
### 3.2 控制平面 vs 执行平面
#### 控制平面
职责:
- 统一 UI
- 统一 API
- 节点注册与节点状态
- Bot 元数据存储
- 权限与访问控制
- 操作审计
- 运行状态聚合
#### 执行平面
职责:
- 启停 Bot
- 管理 Docker / Host 进程
- 读写本机工作区
- 注入 dashboard channel 配置
- 与 Bot 的本地 dashboard channel 通信
- 收集运行日志与事件
补充原则:
- 执行平面的核心宿主是 `dashboard-edge`
- edge 内部可以再通过 core adapter 对不同 Bot 核心做协议适配
- central backend 不直接理解某个具体核心的启动脚本、端口、日志细节
### 3.3 支持矩阵
最终要支持 4 种执行模式:
- Local + Docker
- Local + Native
- Remote + Docker
- Remote + Native
这 4 种模式在控制面前端和 API 层应该尽量表现一致,只在 Provider/Executor 层分流。
## 4. Backend 是否需要拆分
### 4.1 代码结构上:必须拆
必须从当前单文件/弱分层状态拆成:
- API 路由层
- 领域服务层
- Provider 层
- 基础设施层
否则未来远端支持几乎只能靠 `if local else remote` 的条件分支硬堆。
### 4.2 部署形态上:中央 backend 不建议继续拆成多个控制面服务
不建议现在把 central backend 再拆成:
- bot-api
- workspace-api
- monitor-api
原因:
- 当前规模还不值得引入多控制面服务复杂度
- 主要痛点不是“服务数量不足”,而是“执行逻辑没抽象”
- 真正需要新增的,是独立的执行代理服务 `dashboard-edge`
### 4.3 最终建议
- 保留一个 central backend
- 新增一个 edge service
- central backend 内部彻底模块化
## 5. Backend 目标目录建议
建议逐步演进为:
```text
backend/
app/
main.py
dependencies.py
lifespan.py
api/
bots.py
workspace.py
monitor.py
images.py
platform.py
topics.py
nodes.py
domain/
bots/
service.py
runtime_service.py
workspace_service.py
schemas.py
platform/
service.py
topics/
service.py
nodes/
service.py
providers/
runtime/
base.py
local.py
remote.py
workspace/
base.py
local.py
remote.py
provision/
base.py
local.py
remote.py
infra/
docker/
manager.py
workspace/
files.py
nanobot/
config_manager.py
dashboard_channel_client.py
persistence/
database.py
repositories/
settings/
config.py
models/
schemas/
services/
```
### 5.1 关键原则
- `api/` 只做 HTTP 协议转换,不做业务编排
- `domain/` 承担业务规则
- `providers/` 负责本机/远端、多运行模式适配
- `infra/` 负责 Docker、文件系统、dashboard channel、数据库等底层细节
## 6. Edge 服务目标目录建议
新增独立目录:
```text
edge/
main.py
api/
bots.py
workspace.py
monitor.py
health.py
executors/
base.py
docker_executor.py
native_executor.py
adapters/
dashboard_channel.py
log_parser.py
workspace/
service.py
runtime/
service.py
settings.py
```
### 6.1 Edge 的职责边界
只做“本节点执行代理”,不做:
- 全局权限模型
- 多节点聚合
- 平台配置中心
- 中央数据库业务
并且建议把“核心适配”显式纳入 edge 边界:
- edge 内部管理 `CoreAdapter`
- 负责把不同核心的运行方式转换成统一执行接口
- central backend 不直接依赖某个核心的私有实现
## 7. Frontend 目标结构建议
前端建议按“页面/区块/共享能力”拆,而不是继续让超大页面组件承担一切。
推荐结构:
```text
frontend/src/
app/
routes/
providers/
pages/
dashboard/
onboarding/
platform/
image-factory/
widgets/
bot-list/
bot-chat/
workspace-panel/
bot-settings/
topic-feed/
platform-overview/
features/
bot-control/
bot-editor/
workspace-preview/
skill-install/
mcp-config/
topic-config/
cron-config/
entities/
bot/
workspace/
topic/
platform/
node/
shared/
api/
ui/
hooks/
lib/
markdown/
i18n/
```
### 7.1 优先拆分的页面
#### `BotDashboardModule`
优先拆成:
- `BotHeader`
- `BotControlBar`
- `BotConversationPanel`
- `BotWorkspacePanel`
- `BotRuntimePanel`
- `BotSettingsModals`
- `WorkspacePreviewModal`
- `BotSkillSection`
- `TopicFeedSection`
并把状态和副作用抽入 hooks
- `useBotRuntime`
- `useWorkspaceBrowser`
- `useBotEditor`
- `useBotConversation`
- `useBotMonitorStream`
#### `BotWizardModule`
优先拆成:
- `WizardBaseStep`
- `WizardModelStep`
- `WizardAgentFilesStep`
- `WizardSummaryStep`
- `useBotWizardForm`
- `useProviderTest`
#### `PlatformDashboardPage`
优先拆成:
- `PlatformOverviewPanel`
- `PlatformBotsPanel`
- `PlatformSettingsPanel`
- `PlatformUsagePanel`
## 8. Provider 抽象建议
### 8.1 RuntimeProvider
统一接口:
- `start_bot`
- `stop_bot`
- `restart_bot`
- `send_command`
- `get_status`
- `get_recent_logs`
- `stream_monitor`
- `get_resource_snapshot`
### 8.2 WorkspaceProvider
统一接口:
- `list_tree`
- `read_file`
- `write_markdown`
- `upload_files`
- `download_file`
### 8.3 ProvisionProvider
统一接口:
- `create_bot`
- `delete_bot`
- `upgrade_bot`
- `sync_config`
### 8.4 实现矩阵
- `LocalDockerRuntimeProvider`
- `LocalNativeRuntimeProvider`
- `RemoteDockerRuntimeProvider`
- `RemoteNativeRuntimeProvider`
但对上层 API 来说,尽量只感知:
- `LocalRuntimeProvider`
- `RemoteRuntimeProvider`
具体 Docker / Native 再由 provider 内部选择 executor。
## 9. 数据模型建议
当前 `BotInstance` 不足以表达远端执行目标,需要新增节点维度。
### 9.1 建议新增 Node 实体
建议字段:
- `id`
- `name`
- `endpoint`
- `auth_type`
- `auth_secret_ref`
- `enabled`
- `status`
- `capabilities_json`
- `last_heartbeat_at`
### 9.2 BotInstance 建议新增字段
- `node_id`
- `runtime_kind`
- `docker`
- `native`
- `location_kind`
- `local`
- `remote`
或者简化为:
- `node_id`
- `runtime_kind`
其中:
- `node_id = local` 表示同服务器
- 其它 `node_id` 表示远端节点
### 9.3 迁移策略
现有数据默认迁移为:
- `node_id = local`
- `runtime_kind = docker`
保证老实例零感知升级。
## 10. 与 nanobot 的关系
原则保持不变:
- 不修改 nanobot 核心
- 继续复用 `dashboard.py`
- 由 dashboard 侧负责桥接与配置注入
具体职责:
- central backend 不直接操作 nanobot
- edge 负责:
- 生成/更新 `.nanobot/config.json`
- 确保 `channels.dashboard` 注入正确
- 调用 dashboard channel
## 11. 分阶段实施路线
### Phase 1前端拆大文件不改 API
目标:
- 仅拆页面组件、hooks、services
- API 不变
- 行为不变
优先级:
- `BotDashboardModule`
- `BotWizardModule`
- `PlatformDashboardPage`
### Phase 2后端拆主文件不改功能
目标:
-`backend/main.py` 中拆出:
- bot lifecycle 路由
- workspace 路由
- bot service
- workspace service
- runtime service
- 行为保持不变
### Phase 3引入 Provider 抽象,保留本机 Docker
目标:
- 在不改变当前功能的前提下,把执行逻辑走 provider
- 当前 provider 先只实现 local docker
这是最关键的“抽骨架”阶段。
### Phase 4补 Local Native 模式
目标:
- 支持同机宿主机直装
- 通过 `NativeExecutor` 管理进程/端口/workspace
### Phase 5新增 `dashboard-edge`
目标:
- 远端节点部署 edge 服务
- central backend 引入 remote provider
- 不改前端 API只增加节点/运行模式字段
### Phase 6前端补节点视图
目标:
- 节点管理页
- Bot 运行位置与运行模式选择
- 节点资源与健康状态展示
### Phase 7本机执行路径统一切到 edge
目标:
- 逐步让同机 Docker / Native 也通过本机 edge 执行
- central backend 不再保留长期的“本机直连执行层”
- 最终形成“所有执行节点统一经由 edge”的稳定结构
## 12. 本轮重构建议的落地顺序
如果从今天开始进入真正改造,建议按下面顺序推进:
1. 先拆前端大页面
2. 再拆 backend main.py
3. 然后引入 provider interface
4. 再实现 local native
5. 最后接入 remote edge
原因:
- 页面和 `main.py` 的可维护性问题已经是当前痛点
- provider 抽象是远端能力的必要前提
- native 支持可以提前验证抽象是否合理
- remote edge 是最后一公里,不应该在结构没理顺前硬接
## 13. 建议的下一步动作
下一步不要直接开始“远端龙虾支持”的业务开发,而应先做一轮基础重构:
### 13.1 前端第一刀
`BotDashboardModule` 开始,拆成:
- workspace
- conversation
- runtime
- settings modal
- skills/topic
### 13.2 后端第一刀
`backend/main.py` 中先抽 3 个领域:
- bots lifecycle
- workspace
- bot runtime snapshot / config sync
### 13.3 provider 第一版
先定义接口,不着急做 remote
- `RuntimeProvider`
- `WorkspaceProvider`
- `ProvisionProvider`
并用当前本机逻辑实现 `Local*Provider`
---
本方案的核心思想只有一句话:
**中央 backend 保持控制平面,新增 edge 作为执行平面;先做代码结构分层,再做远端与 native 支持。**
## 14. 为什么不是一开始就直接拆成 backend + edge
这个问题的关键不在于“是否值得上 edge”而在于“当前代码是否已经具备承接 edge 的稳定边界”。
答案是:**方向上应该从一开始就以 backend + edge 为目标,但工程实施上不应该在现有单体逻辑不拆的情况下直接硬接 edge。**
原因如下。
### 14.1 当前 central backend 还没有稳定的 provider 边界
如果现在直接上 edge但 central backend 仍然保持现状,那么会出现:
- 本机逻辑继续直连 Docker / 文件系统
- 远端逻辑走 edge
- API 路由层同时理解本机细节和远端细节
结果会形成两套执行路径:
- local direct
- remote edge
这会让后续统一 Native、统一工作区、统一日志协议变得更贵。
### 14.2 先拆结构不是绕路,而是在降低总成本
先做结构重构的价值是:
- 把当前隐式耦合改成显式边界
- 先定义 provider / executor / adapter 契约
- 为 edge 预留稳定接入点
这样后续接 edge 是“接到标准接口上”,不是“插进一团已有业务里”。
### 14.3 如果现在直接硬上 edge代价反而更大
直接开做 edge 的风险:
- central backend 仍然需要保留大量本机直连逻辑
- 远端功能会复制一套相似业务编排
- 前端状态和 API 语义可能被迫提前扭曲
- 最后仍然要回头拆 `main.py` 和超大页面组件
也就是说,不是“现在拆结构,后面代价更大”,而是:
- **如果现在不先拆结构,后面引入 edge 的总代价更大**
### 14.4 推荐理解方式
正确顺序不是:
- 先重构
- 再考虑 edge
而是:
- 先以 edge 为最终目标设计边界
- 再做最小必要的结构重构
- 然后把 edge 接入这些边界
因此,这两件事不是对立关系,而是前后依赖关系。