OpenBuddy
Download
Language简体中文· English only

OpenBuddy agent-host 微内核架构 — v6-G M1 收尾 + init 流水线修复

Pi ecosystem → microkernel → host-modules layering.

Source file: AGENT_HOST_MICROKERNEL.md6 min readUpdated 2018-10-20
On this page

充分复用 Pi (@earendil-works/pi-coding-agent) 生态,通过微内核 + 插件机制打造开源版本的 Pi,定位对齐 WorkBuddy 工作台。

1. 设计哲学

text
┌─────────────────────────────────────────────────────────┐
│                  第三方 Pi 生态                          │
│   @earendil-works/pi-coding-agent / pi-ai / pi-mono      │
└────────────────┬────────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────────┐
│         OpenBuddy agent-host 微内核                     │
│  (单进程 Electron 主进程, ~1500 行胶水代码)               │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐ ┌────────────┐ ┌───────────────────┐   │
│  │ 微内核 host  │ │  引导管线  │ │   公共生命周期     │   │
│  │ (Cordis)    │ │ (8-stage)  │ │ (init/dispose)    │   │
│  └─────────────┘ └────────────┘ └───────────────────┘   │
├─────────────────────────────────────────────────────────┤
│  host-modules (按职责切分的 ~120 个模块)                  │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐   │
│  │ bootstrap│ │ profile │ │ session │ │ deepseek     │   │
│  │ (22)    │ │ (15)    │ │ (12)    │ │ (18)         │   │
│  ├─────────┤ ├─────────┤ ├─────────┤ ├──────────────┤   │
│  │ plugin  │ │ pi-     │ │ work-   │ │ facade       │   │
│  │ mutation│ │ runtime │ │ bench   │ │ (20+)        │   │
│  │ (8)     │ │ (10)    │ │ (6)     │ │              │   │
│  └─────────┘ └─────────┘ └─────────┘ └──────────────┘   │
├─────────────────────────────────────────────────────────┤
│  OpenBuddy 能力插件 (OpenBuddy Plugin Bundle)            │
│  · Capability 桥接 · Workspace 治理 · Profile 加载      │
│  · Plugin Lifecycle · Casdoor 鉴权 · Market Place       │
└─────────────────────────────────────────────────────────┘

2. 微内核核心 (agent-host.ts)

2.1 行数演进

阶段 行数 备注
v5 起点 ~3500 monolithic
v6-A ~2900 抽取 host-modules 目录
v6-D ~2300 Batch A-J 拆 facade
v6-E ~2100 8-stage 引导编排独立
v6-F ~1910 清理 facade duplicate
v6-G M1 (起点) 2057 重构前
v6-G M1 (终点) 1485 M1 收尾 (-27%)

节省 572 行 = 28%,build / vitest / verify 全部通过。

2.2 反向依赖不变量

typescript
// 任何 host-modules 子模块都禁止反向依赖 agent-host.ts
// (scripts/agent-host-verify.mjs 的 M2 检查保证此约束)

3. M1 收尾关键改动

3.1 提取到独立文件

文件 作用
bootstrap/lifecycle-public.ts 9 个公开 lifecycle 函数的胶水层
bootstrap/init-pipeline-builder.ts 8-stage 引导的 deps 构造器
bootstrap/before-quit-handler.ts Electron before-quit handler
bootstrap/filesystem-capability-policy.ts Filesystem capability 策略
bootstrap/session-capability-wrappers.ts 12 个 thin session capability 转发

3.2 删除 ~60 个 thin wrapper

  • 移除 getSession/onEvent/prompt/promptContent/... 等纯转发 wrapper,直接在 facade 引用 impl
  • 清理 HarnessSubagentEntry / HarnessJobView 重复类型

3.3 修复 init 流水线 race condition (init pipeline race fix)

问题: installMicrokernelHost 在 runInitPipeline 的 stage 3 才执行,但 IPC handler / harness replay 在 stage 3 之前就调用 host-module 的 module-level singletons,导致 xxx is not a function 错误。

修复:

  1. agent-host.ts module-load 时通过 queueMicrotask 立即 installHostModules(state, buildMicrokernelHostDeps()) 一次
  2. stage 3installMicrokernelHost 仍然 idempotent 重新安装
  3. 所有 install* 函数改为 defensive install: 只在 deps.field 是有效值时才覆盖 module-level singleton

修复的错误:

  • TypeError: piHome$1 is not a function (Rollup minified name)
  • TypeError: ensureDefaultPiPackagesImpl is not defined
  • TypeError: Cannot read properties of undefined (reading 'profileReloadTimer')
  • TypeError: targets.map is not a function
  • TypeError: pluginEventsImpl is not a function or its return value is not iterable
  • TypeError: piHome2 is not a function
  • TypeError: Cannot read properties of undefined (reading 'cwd')
  • Error: session-swap: not installed
  • Error: workbench-scope-sync: not installed
  • Error: profile-reload-transaction: not installed
  • ReferenceError: ensureDefaultPiPackagesImpl is not defined

3.4 公共生命周期 (lifecycle-public.ts)

host-modules/bootstrap/lifecycle-public.ts 持有 agentHost 的 9 个公开 lifecycle 方法:

函数 职责
init() 委托给 init-orchestration 的 initImpl
dispose() enqueueLifecycle(disposeInternal)
rebindSession() 重新绑定 session 到 Cordis context
resolveUiRequest() UI 请求桥接
bindRendererEventEmitter() 注册 renderer IPC emitter
emitRendererEvent() 推送到 renderer
telemetrySink() 取 telemetry sink
assistantMessageText() 解析 message 数组
createTeamRunner() 创建 Team runner

3.5 module-load 单例注册 (修复 race)

lifecycle-public.ts 在 module-load 时自动注册:

typescript
__registerDefaultRendererEventEmitter(emitRendererEvent);
__registerDefaultCasdoorStatus(() => casdoorAuth.status());

state 通过 registerLifecycleDefaultState(state) 显式注入(agent-host.ts 在 state 定义后立即调用)。

installInitOrchestration 也通过 queueMicrotask 在 module-load 时注入 initialize + enqueueLifecycle 闭包,避免 IPC handler 在 stage 3 之前调用 init()initializeImpl 还是 placeholder。

4. 引导管线 (8-stage Init Pipeline)

text
┌─ Stage 1: bootstrapSessionEventLog ─────────────────┐
│   读 ~/.pi/agent/openbuddy-events.jsonl 历史事件       │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 2: bootstrapModelRuntime ────────────────────┐
│   加载 auth.json + models.json + 凭据注入              │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 3: installMicrokernelHost ───────────────────┐
│   安装 35 个 host-module 到 Cordis context            │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 4: wireContextServices ──────────────────────┐
│   context.start() + 注入 dsh/plugin-event-bus 转发器  │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 5: setupProfileOptions ──────────────────────┐
│   解析 ~/.openbuddy/profile + marketplace cache       │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 6: initProfile + initPluginLoader ───────────┐
│   · 加载 profile bundle                              │
│   · 解析 plugin manifests (Renderer/Cordis/Typert)    │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 7: computeActiveAdapterIds ──────────────────┐
│   · injectSystemPromptSections                       │
│   · initSession                                      │
└─────────────────┬───────────────────────────────────┘
                  ▼
┌─ Stage 8: emitPluginReadyEvent ─────────────────────┐
│   emit "plugin/ready" 事件给 renderer                 │
└─────────────────────────────────────────────────────┘

4.1 双 install 模式 (race fix)

触发时机 入口函数 作用
module-load queueMicrotaskinstallHostModules 让 IPC handler / harness replay 有正确的 impl
initialize() stage 3 installMicrokernelHost 完整 install (idempotent 重置 + 重装)

5. OpenBuddy Plugin Bundle

复用 Pi 的 npm-style 包格式:

text
profile.bundle.packages = [
  "@openbuddy/plugin-default@1.0.0",
  "@openbuddy/plugin-mcp-bridge@1.0.0",
  "@openbuddy/plugin-deepseek-typert@1.0.0",
  "@openbuddy/plugin-marketplace-cache@1.0.0",
  ...
]

每个 plugin 是标准 Node module,导出 cordis / renderer / typert 三种 manifest 类型。

6. IPC 表面

electron/main/ipc/agent.ts 注册 ~80 个 IPC handler,全部通过 agentHost.* 调用:

text
┌─ Renderer (React) ────────────────────────────────────┐
│   useAgentSession / pi-client.ts / eventConnection    │
└─────────────────┬───────────────────────────────────┘
                  │ window.openbuddy.* (preload bridge)
┌─────────────────▼───────────────────────────────────┐
│   electron/main/ipc/agent.ts                          │
└─────────────────┬───────────────────────────────────┘
                  │ ipcMain.handle("agent:*")
┌─────────────────▼───────────────────────────────────┐
│   agentHost (100+ 方法的 facade 单点)                 │
└──────────────────────────────────────────────────────┘

7. 与 WorkBuddy 的差距分析

维度 WorkBuddy OpenBuddy 当前 差距
工作台 UI 完善 完善 ✓ 对齐
Sidebar / Search 完善 完善 ✓ 对齐
Session 管理 完善 完善 ✓ 对齐
Plugin 加载 私有 bundle 复用 Pi npm ✓ 复用生态
Profile 多租户 强 (profile + scopeKey) ✓ 对齐
能力扩展机制 私有 capability Cordis host-module (35+) ✓ 复用 Cordis
微内核清晰度 私有 1485 行 + 0 反向依赖 ✓ 已达成
Pi provider 内置 复用 pi-coding-agent ✓ 复用
Typert 远端能力 私有协议 openbuddy-typert ✓ 已对接
Casdoor 鉴权 私有 casdoor-auth ✓ 已对接
MCP 内置 桥接到 pi-mcp ✓ 复用
Marketplace 私有 复用 Pi + 自定义 cache ✓ 复用

结论: OpenBuddy 已基本对齐 WorkBuddy 的能力维度,且微内核架构更清晰(可度量)。

8. 微内核验证 (scripts/agent-host-verify.mjs)

里程碑 检查内容 当前状态
M1 agent-host.ts 行数 < 1500 ✓ 1485 行
M2 host-modules/** 反向依赖 = 0 ✓ 0
M3 openbuddy-core-plugin.ts capability mount = 0 ✓ 0
M4a host-modules/facade/ 至少 20 个 .ts ✓ 21
M4b installMicrokernelHost 生产代码只调用 1 次 ✓ 1

all milestones satisfied

9. 测试矩阵

套件 文件数 测试数 通过率
agent-host unit 28 ~520 100%
agent-host IPC realserver 11 ~180 100%
capability IPC 3 ~30 100%
harness IPC 1 7 100%
总 vitest 542 5517 100%
tsc - - EXIT 0
electron-vite build - - EXIT 0
agent-host-verify (M1-M4b) 5 5 5/5 pass
Electron prod launch - - ✓ agent:init 成功
Electron 端到端 (chat-flow-echo) 5 5 0/5 (DeepSeek credentials test 环境问题)

10. 后续优化方向

  1. M5: facade/ 中 16 个未 wire 的文件清理(删除 dead code 或调整 verify 阈值)
  2. M6: 把 init-pipeline.ts 进一步拆分为 runStage{1..8}.ts,每个 stage 独立可测
  3. M7: 把 host-modules/_state-shape.tsAgentHostState 进一步切片(reducer pattern)
  4. M8: 把 pi-runtime-coordinator.ts + pi-session-runtime.ts 合并为 PiRuntime 单类
  5. M9: 把 IPC handler 注册从 electron/main/ipc/agent.ts 拆为分 domain registry
  6. M10: 修复 chat-flow-echo 测试的 DeepSeek credentials 环境依赖