OpenBuddy agent-host 微内核架构 — v6-G M1 收尾 + init 流水线修复
Pi ecosystem → microkernel → host-modules layering.
AGENT_HOST_MICROKERNEL.md6 min readUpdated 2018-10-20On this page
- 1. 设计哲学
- 2. 微内核核心 (agent-host.ts)
- 2.1 行数演进
- 2.2 反向依赖不变量
- 3. M1 收尾关键改动
- 3.1 提取到独立文件
- 3.2 删除 ~60 个 thin wrapper
- 3.3 修复 init 流水线 race condition (init pipeline race fix)
- 3.4 公共生命周期 (lifecycle-public.ts)
- 3.5 module-load 单例注册 (修复 race)
- 4. 引导管线 (8-stage Init Pipeline)
- 4.1 双 install 模式 (race fix)
- 5. OpenBuddy Plugin Bundle
- 6. IPC 表面
- 7. 与 WorkBuddy 的差距分析
- 8. 微内核验证 (scripts/agent-host-verify.mjs)
- 9. 测试矩阵
- 10. 后续优化方向
充分复用 Pi (@earendil-works/pi-coding-agent) 生态,通过微内核 + 插件机制打造开源版本的 Pi,定位对齐 WorkBuddy 工作台。
1. 设计哲学
┌─────────────────────────────────────────────────────────┐
│ 第三方 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 反向依赖不变量
// 任何 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 错误。
修复:
agent-host.tsmodule-load 时通过queueMicrotask立即installHostModules(state, buildMicrokernelHostDeps())一次stage 3的installMicrokernelHost仍然 idempotent 重新安装- 所有
install*函数改为 defensive install: 只在deps.field是有效值时才覆盖 module-level singleton
修复的错误:
TypeError: piHome$1 is not a function(Rollup minified name)TypeError: ensureDefaultPiPackagesImpl is not definedTypeError: Cannot read properties of undefined (reading 'profileReloadTimer')TypeError: targets.map is not a functionTypeError: pluginEventsImpl is not a function or its return value is not iterableTypeError: piHome2 is not a functionTypeError: Cannot read properties of undefined (reading 'cwd')Error: session-swap: not installedError: workbench-scope-sync: not installedError: profile-reload-transaction: not installedReferenceError: 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 时自动注册:
__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)
┌─ 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 | queueMicrotask → installHostModules |
让 IPC handler / harness replay 有正确的 impl |
initialize() stage 3 |
installMicrokernelHost |
完整 install (idempotent 重置 + 重装) |
5. OpenBuddy Plugin Bundle
复用 Pi 的 npm-style 包格式:
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.* 调用:
┌─ 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. 后续优化方向
- M5: facade/ 中 16 个未 wire 的文件清理(删除 dead code 或调整 verify 阈值)
- M6: 把
init-pipeline.ts进一步拆分为runStage{1..8}.ts,每个 stage 独立可测 - M7: 把
host-modules/_state-shape.ts的AgentHostState进一步切片(reducer pattern) - M8: 把
pi-runtime-coordinator.ts+pi-session-runtime.ts合并为PiRuntime单类 - M9: 把 IPC handler 注册从
electron/main/ipc/agent.ts拆为分 domain registry - M10: 修复 chat-flow-echo 测试的 DeepSeek credentials 环境依赖