跳转至

14 · 插件系统与进程边界

ManifestWorker ProcessCapabilitiesJobs / Tools / WebhooksUI Slots

一句话结论: Paperclip 把深度可信的“平台模块”和加法式“插件”分开:插件用 manifest 声明能力,业务逻辑在独立 Worker 进程中通过受控 Host RPC 工作;但当前 UI 扩展仍是同源可信代码,整个系统也仍偏单主机部署。

1. 先区分两类扩展

平台模块

可信、进程内,能深入核心:

  • Adapter;
  • storage provider;
  • secret provider;
  • log/runtime 等基础能力。

它们通常随部署代码发布,拥有较高信任。

Plugin

独立 package + manifest,主要做加法式扩展:

  • Worker actions/jobs/events;
  • tools/webhooks/API routes;
  • UI slots/launchers;
  • managed agents/projects/routines/skills;
  • environment drivers;
  • namespaced data/state。

插件不应直接 import Server 私有 service 并任意修改 DB。

2. Manifest 是插件的能力合约

Manifest 典型字段:

identity
  id / apiVersion / version / display metadata / categories

entrypoints
  worker / ui

governance
  capabilities / config JSON schema

contributions
  jobs / webhooks / tools / apiRoutes
  database / environmentDrivers
  managed agents / projects / routines / skills / localFolders
  UI slots / launchers

安装时先做 schema 与静态验证:ID、版本、entrypoint、capability 与 contribution 一致,不能等 Worker 启动后再猜插件想做什么。

3. 生命周期

stateDiagram-v2
  [*] --> Discovered
  Discovered --> Validated: manifest valid
  Discovered --> Invalid: manifest rejected
  Validated --> Installed
  Installed --> Starting: enabled for instance/company
  Starting --> Running: worker initialized + healthy
  Starting --> Crashed: spawn/init failure
  Running --> Crashed: exit / health failure
  Crashed --> Starting: restart policy
  Running --> Stopped: disable / shutdown
  Stopped --> Starting: re-enable

Plugin registry、loader、lifecycle 和 worker manager 分开:registry 保存状态,loader 解析 package,lifecycle 决定启停,worker manager 管进程与 RPC。

4. Worker 协议

Worker 端可实现:

  • initialize;
  • health;
  • validateConfig;
  • configChanged;
  • onEvent;
  • runJob;
  • handleWebhook;
  • getData;
  • performAction;
  • executeTool。
sequenceDiagram
  participant S as Server Host
  participant W as Plugin Worker
  participant H as Host Services
  participant DB as Plugin Stores

  S->>W: spawn + initialize(manifest, config context)
  W-->>S: ready / health
  S->>W: onEvent / runJob / performAction
  W->>S: host RPC request
  S->>S: capability + company scope check
  S->>H: execute allowed service
  H->>DB: namespaced persistence / core API
  DB-->>H: result
  H-->>W: redacted result

Worker crash 不应让 Server 主进程直接崩溃;manager 记录 health、日志、crash/restart live event,并按策略重启。

5. Capability Gate

Manifest 声明插件需要哪些 host service 能力。每次 Worker RPC 仍由 Host 验证:

  • plugin identity;
  • capability 已声明且获准;
  • company scope;
  • action/resource;
  • payload/schema;
  • secret redaction;
  • rate/size/time limit。

Capability 不是只在安装时勾一次。运行时每个 RPC 都要 fail closed,防止 Worker 调用未声明方法。

6. Plugin Data 分层

插件有多种持久化方式:

存储 用途
plugin config instance/package 配置
company settings 每 Company 开关和设置
plugin state 小型 KV/状态
plugin entities 结构化扩展实体
plugin database namespace 需要迁移的复杂私有数据
jobs/runs 定时/异步执行账本
webhooks endpoint、secret、delivery
logs Worker 与 host 诊断
managed resources 插件声明并维护的 Agent/Project/Routine/Skill

核心通过 plugin ID + company namespace 隔离,避免不同插件 key 冲突。

7. Config 与 Secret Ref

Plugin config 由 manifest JSON Schema 描述,UI 可生成表单,Worker 可进一步 validateConfig。

敏感字段不应直接保存明文,而使用 secret reference:

plugin config: { apiKey: { secretId, versionSelector, ... } }
     ↓
Host 在允许的 action/run 中解析
     ↓
仅把必要值投影给 Worker/外部请求

Secret capability、Company 归属和 config path 都要校验。插件日志/错误由 Host 做敏感信息清理。

8. Event Bus

插件可订阅受支持事件。Core 将业务事件映射到 plugin event bus,再分发给已启用 Worker。

重要边界:

  • 插件只能收到声明/允许的事件;
  • payload 应是稳定、脱敏的公共形状;
  • Worker 慢不能阻塞核心 mutation;
  • delivery 需要记录或可重试语义;
  • 插件自己的事件要 namespaced,防止伪造 core event。

当前 event architecture 仍有单进程/单主机假设,不能直接当分布式 durable queue。

9. Jobs

插件 manifest 可声明 schedule/job handler。Host job coordinator:

  • 建立 job definition/state;
  • 到期 claim;
  • 写 job run;
  • 调用 Worker runJob;
  • 记录 success/failure/retry;
  • shutdown/restart 时对账。

Plugin job 与 Agent Heartbeat 不同:前者执行插件 Worker 逻辑,后者执行 Agent runtime。插件可以通过受控 action 创建/唤醒 Agent 工作,但不应偷用 job 绕开治理。

10. Webhooks

Plugin webhook contribution 通常包含:

  • namespaced route;
  • method/schema;
  • signature/secret policy;
  • delivery metadata;
  • Worker handler;
  • timeout/response contract。

外部 payload 是不可信输入。Host 需要在进入 Worker 前做大小限制、签名验证、scope 和日志 redaction;Worker 输出也不能直接成为任意 HTTP header/path。

11. Plugin Tools

插件可注册 namespaced tool,再由 tool dispatcher 暴露给受允许 Agent。调用链仍要:

Agent tool intent
→ tool catalog/profile/policy
→ plugin tool registry
→ Worker executeTool
→ result guard/redaction/audit

“插件声明了 tool”不等于所有 Agent 自动可见,更不等于 destructive call 自动允许。

12. Plugin API Routes

当前插件 API route 是 JSON-only、namespaced、受 scope 的扩展面。Host 负责:

  • 固定 path 前缀;
  • method 与 payload size;
  • actor/company context;
  • capability;
  • JSON serialization;
  • timeout/error mapping。

这避免 Worker 直接拿到原始 Express req/res 并绕过中间件。

13. Environment Driver

Sandbox provider 插件(例如多种云 sandbox)可贡献 environment driver:

  • capability/probe;
  • acquire/release;
  • exec/file sync;
  • provider lease reference;
  • cleanup/reconciliation。

核心仍持有 environment/workspace/lease 账本,插件只实现 provider-specific mechanism。这让 Heartbeat 不必知道每家 sandbox SDK。

14. Managed Resources

插件可以声明它管理的 Agent、Project、Routine、Skill。核心保存 provenance 与 drift 状态:

  • desired definition;
  • actual resource;
  • plugin/version;
  • last reconcile;
  • drift/health;
  • disable/uninstall behavior。

如果用户手工修改 managed resource,系统不能静默覆盖;要依据管理策略提示 drift、reconcile 或释放管理权。

15. UI 扩展

Manifest 可贡献 dashboard、settings、entity detail 等 UI slot 或 launcher。Server 提供静态资源和 contribution manifest,UI 动态加载。

当前 UI 不是安全 sandbox

插件规格明确:当前 UI 扩展作为 same-origin trusted JavaScript 运行。Worker capability gate 只能约束 Worker 的 Host RPC,不能阻止 UI bundle 直接调用用户浏览器可访问的普通 HTTP API。因此只应安装可信 UI 插件。

未来若要运行不可信 UI,需要 iframe/origin isolation、CSP、message contract 等真正的浏览器边界。

16. 本地开发与打包现实

插件开发支持 local folder、watch/reload、SDK link 和 create-plugin 脚手架。当前运行假设包括:

  • host 有可写 filesystem; -可启动 Node Worker;
  • 某些安装流程需要 npm/network;
  • package/entrypoint 可本地解析。

这些假设与纯 serverless、只读镜像或多副本平台不完全兼容。

17. 当前单主机边界

插件 Worker manager、dev watcher、local folders、jobs 和进程 health 主要由一个持久 Server 主机管理。横向扩展需要额外解决:

  • Worker ownership/leader election;
  • shared job claim;
  • plugin event delivery;
  • package/artifact distribution;
  • UI/static asset consistency;
  • provider lease reconciliation。

规格清楚把当前版本定位在 single-host/persistent deployment,而不是假装已分布式。

18. Kitchen Sink Example 的价值

示例插件不是只输出 Hello World,而是覆盖 config、state、entity、job、webhook、tool、API、UI slot、managed resource 等大量 contribution。它同时是:

  • SDK 用法样例;
  • manifest validator fixture;
  • plugin lifecycle smoke test;
  • 打包/加载契约测试。

扩展系统需要这种“全表面样例”,否则每个 feature 只在生产插件中被偶然覆盖。

19. 可复用经验

  1. 深度平台模块与第三方插件应有不同信任模型。
  2. Manifest 声明只是第一层,Host RPC 每次仍要 capability + scope 检查。
  3. Worker 隔离不能自动保护同源 UI;浏览器边界必须单独设计。
  4. 插件数据、job、webhook、log 和 managed resource 都要 namespaced/provenance。
  5. Provider 插件实现 mechanism,核心保留 lease/operation 等生命周期事实。
  6. 清楚写出单主机和 filesystem 假设,比模糊宣称“云原生”更安全。

源码入口

  • doc/plugins/PLUGIN_SPEC.md
  • packages/plugins/sdk/
  • server/src/services/plugin-manifest-validator.ts
  • server/src/services/plugin-loader.ts
  • server/src/services/plugin-worker-manager.ts
  • server/src/services/plugin-host-services.ts
  • server/src/services/plugin-capability-validator.ts
  • server/src/services/plugin-job-coordinator.ts
  • server/src/services/plugin-tool-dispatcher.ts
  • packages/db/src/schema/plugin_*.ts
  • packages/plugins/examples/plugin-kitchen-sink-example/

插件可能贡献工具,但所有工具还要经过治理。下一章:15 · MCP、工具访问与密钥投影。