14 · 插件系统与进程边界¶
一句话结论: 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. 可复用经验¶
- 深度平台模块与第三方插件应有不同信任模型。
- Manifest 声明只是第一层,Host RPC 每次仍要 capability + scope 检查。
- Worker 隔离不能自动保护同源 UI;浏览器边界必须单独设计。
- 插件数据、job、webhook、log 和 managed resource 都要 namespaced/provenance。
- Provider 插件实现 mechanism,核心保留 lease/operation 等生命周期事实。
- 清楚写出单主机和 filesystem 假设,比模糊宣称“云原生”更安全。
源码入口¶
doc/plugins/PLUGIN_SPEC.mdpackages/plugins/sdk/server/src/services/plugin-manifest-validator.tsserver/src/services/plugin-loader.tsserver/src/services/plugin-worker-manager.tsserver/src/services/plugin-host-services.tsserver/src/services/plugin-capability-validator.tsserver/src/services/plugin-job-coordinator.tsserver/src/services/plugin-tool-dispatcher.tspackages/db/src/schema/plugin_*.tspackages/plugins/examples/plugin-kitchen-sink-example/
插件可能贡献工具,但所有工具还要经过治理。下一章:15 · MCP、工具访问与密钥投影。