返回课程首页

附录 E

Extensions 速查

注册、事件、工具、Provider、生命周期与错误语义。

源码基线:Pi v0.82.0 · commit 518855d

1. 一句话定义

Extension 是运行在 Pi 进程中的本地代码,通过注册与事件机制改变 Agent Runtime。

2. 生命周期

discover path
→ import module
→ execute factory
→ collect registration
→ bind core/session/UI
→ session_start
→ events/tools
→ session_shutdown
→ cleanup

Factory 失败后 Extension Object 不进入列表,但此前对共享 Runtime 的部分副作用不保证回滚。

3. Factory

export default function (pi: ExtensionAPI) {
  pi.registerTool(/* ... */);
  pi.on("tool_call", /* ... */);
}

Factory 只做注册。长期 Timer/Watcher/Socket/EventBus Listener 应延迟到 session_start 或首次 使用,避免 Factory 失败后没有 Shutdown Handler 可清理。

4. 可注册能力

  • Event Handler;
  • Tool;
  • Command;
  • Flag;
  • Provider;
  • UI/Host 交互;
  • Dynamic Resource Path;
  • EventBus Channel。

精确 API 以 core/extensions/types.ts 为准。

5. 常用事件

类别 事件示例
输入/Run inputbefore_agent_startcontext
Tool tool_calltool_result
Session session_startsession_shutdown、切换/分支事件
资源 resources_discover
模型 Model/Thinking 相关 Extension Event
完成 agent_settled

Extension Runner Event 不等于公共 AgentSessionEvent。

6. 错误语义

Handler Throw 后
普通观察/转换 报 Error,通常继续
project_trust 记录 Error,继续寻找 Decision
tool_call Tool 失败且不执行
tool_result 报 Error,保留已有 Result 并继续
EventBus Listener Catch 后 Console;Emit 不 Await

安全脱敏不能靠 tool_result Throw 实现 Fail Closed。

7. Tool 拦截

raw args
→ validate/prepare
→ tool_call handlers
→ approval/final policy
→ execute
→ tool_result handlers
→ model

审批绑定 Canonical Args;最终 Backend 再检查。所有副作用入口(Write/Edit/Bash/自定义工具) 必须统一覆盖。

8. Provider 三种形态

  • 完整 Provider
  • Name + Legacy ProviderConfig
  • createProvider()

三者 Model 类型、刷新返回值和 ModelsStore 责任不同。动态刷新必须尊重 allowNetwork=false

unregisterProvider(id) 按共享 Registry ID 删除,没有扩展所有权隔离。

9. Dynamic Resources

resources_discover 当前贡献:

  • Skill Paths;
  • Prompt Paths;
  • Theme Paths。

不能发明任意 Core Resource Type。业务知识库由 Extension 自管,再通过 Tool/Context 暴露。

10. EventBus

Extension 侧 pi.events

  • on()
  • emit()

Host/Internal Controller 才有 clear()。Bus 无持久化、Ack、Replay、Backpressure,异步 Listener 不会被 emit() Await。

11. 状态选择

状态 保存
Instance Cache Factory Closure
Branch Tool State ToolResult Details
Branch 非模型状态 Custom Entry
Account/跨 Session External Store

Module-level Singleton 可能跨多个 Extension Instance/Session 共享。

12. Reload 与 Replacement

  • session_shutdown 中幂等清理;
  • pi/ctx 视为失效;
  • EventBus Subscription 调用 Unsubscribe;
  • Reload Generation 防止旧异步回调产生副作用;
  • 新 Session 重新绑定 UI/Command/Error/Shutdown。

v0.82.0 Reload 对旧 Runner/Context 的统一失效保护有实现边界,宿主要用 Generation 与测试 补强。

13. 冲突

  • Tool/Flag:前者胜并产生诊断;
  • Command:保留并可获得序号;
  • Handler:全部执行;
  • EventBus:无自动 Namespace;
  • Extension Tool 可覆盖 Built-in;
  • SDK Custom Tool 可继续覆盖 Extension。

生产启动门禁应检查意外冲突。

14. 安全

Extension 有当前进程完整权限,可直接访问 Filesystem/Process/Network。Tool Broker 只能约束 经过 Tool 链的动作;约束 Extension 本身需要整进程 OS Sandbox/Container。

15. 测试清单

  • Factory 成功/失败;
  • Handler 顺序/Throw;
  • Tool Block/Transform/Result Patch;
  • Timeout/Abort;
  • Reload Cleanup;
  • New/Resume/Fork;
  • EventBus Unsubscribe;
  • 多 Session;
  • 冲突;
  • Provider 离线刷新;
  • Pi/Node 版本矩阵。

源码入口:extensions/loader.tsrunner.tstypes.tsevent-bus.ts