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

16 KiB
Raw Permalink Blame History

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 目标目录建议

建议逐步演进为:

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 服务目标目录建议

新增独立目录:

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 目标结构建议

前端建议按“页面/区块/共享能力”拆,而不是继续让超大页面组件承担一切。

推荐结构:

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 接入这些边界

因此,这两件事不是对立关系,而是前后依赖关系。