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

727 lines
16 KiB
Markdown
Raw Normal View History

# Dashboard Nanobot 模块化重构与远端桥接演进方案
本文档用于指导当前项目的结构性重构,并为后续“支持同机/远端龙虾 + Docker/Native 双运行模式”升级提前抽离边界。
2026-03-26 16:12:46 +00:00
补充约束:本路线图负责说明“为什么拆、先拆什么”;具体“怎么拆、拆到什么边界”为强制执行项,统一以下文为准:
- `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 接入这些边界
因此,这两件事不是对立关系,而是前后依赖关系。