现在位置: 首页 > Pi Agent > 正文

Pi Agent 扩展入门

Extensions(扩展)是 Pi Agent 最强大的定制方式——你可以用 TypeScript 编写自定义工具、命令和事件监听器。


什么是 Extension

Extension 是一个 TypeScript 模块,它可以:

  • 注册自定义工具——AI 可以调用的新功能
  • 注册自定义命令——用户通过 /命令名 调用
  • 监听生命周期事件——在 AI 工作的各个阶段插入逻辑
  • 注册键盘快捷键
  • 展示自定义 UI——在终端中渲染交互界面

第一个 Extension:Hello World

实例

// 文件路径:~/.pi/agent/extensions/my-extension.ts
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";

export default function (pi: ExtensionAPI) {
  // 在会话启动时触发
  pi.on("session_start", async (_event, ctx) => {
    ctx.ui.notify("我的扩展已加载!", "info");
  });

  // 拦截危险命令
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName === "bash"
        && event.input.command?.includes("rm -rf")) {
      const ok = await ctx.ui.confirm("危险操作!", "确认执行 rm -rf?");
      if (!ok) return { block: true, reason: "用户阻止" };
    }
  });

  // 注册一个自定义工具
  pi.registerTool({
    name: "greet",
    label: "打招呼",
    description: "向指定的人打招呼",
    parameters: Type.Object({
      name: Type.String({ description: "要打招呼的人名" }),
    }),
    async execute(toolCallId, params) {
      return {
        content: [{ type: "text", text: `你好,${params.name}!` }],
        details: {},
      };
    },
  });

  // 注册一个自定义命令
  pi.registerCommand("hello", {
    description: "向世界问好",
    handler: async (args, ctx) => {
      ctx.ui.notify(`你好 ${args || "世界"}!`, "info");
    },
  });
}

测试你的扩展:

$ pi -e ~/.pi/agent/extensions/my-extension.ts

扩展的加载位置

位置作用范围说明
~/.pi/agent/extensions/*.ts全局对所有项目生效,自动发现
~/.pi/agent/extensions/*/index.ts全局子目录中有 index.ts 的扩展
.pi/extensions/*.ts项目仅当前项目,需项目信任
.pi/extensions/*/index.ts项目项目子目录扩展

也可以通过 settings.json 或 CLI 参数加载扩展:

# 从路径加载(临时)
$ pi -e ./my-extension.ts

# 在 settings.json 中配置

实例

{
  "extensions": [
    "/path/to/local/extension.ts",
    "/path/to/local/extension/dir"
  ]
}

Extension 文件结构

单文件扩展

最简单的形式,适合小型扩展:

~/.pi/agent/extensions/
└── my-extension.ts

目录扩展(含 index.ts)

适合多文件扩展:

~/.pi/agent/extensions/
└── my-extension/
    ├── index.ts        # 入口文件(导出默认函数)
    ├── tools.ts        # 辅助模块
    └── utils.ts        # 工具函数

带依赖的扩展

适合需要 npm 包的大型扩展:

~/.pi/agent/extensions/
└── my-extension/
    ├── package.json    # 声明依赖和入口
    ├── node_modules/   # npm install 后生成
    └── src/
        └── index.ts

扩展以你的系统权限运行,可以执行任意代码。只安装来自可信来源的扩展


扩展的加载机制

扩展通过 jiti 加载,TypeScript 代码无需编译即可直接运行。

如果你的工厂函数返回 Promise,Pi Agent 会在继续启动流程之前等待它完成——这意味着你可以在扩展初始化时做异步操作,比如获取远程配置。


可用 Import 包

包名用途
@earendil-works/pi-coding-agent扩展类型(ExtensionAPI、ExtensionContext 和各种事件类型)
typebox工具参数的 Schema 定义
@earendil-works/pi-aiAI 工具(如 StringEnum,用于 Google 兼容的枚举)
@earendil-works/pi-tuiTUI 组件,用于自定义渲染

这些是 Pi Agent 的内置依赖,应该列为 peerDependencies 而不是打包到你的扩展中。

其他 npm 包也可以使用——在扩展目录中添加 package.json 并运行 npm install 即可。


开发提示

  • 将扩展放在 ~/.pi/agent/extensions/ 目录中,支持 /reload 热重载
  • 使用 pi -e ./path.ts 仅在快速测试时使用
  • 不要在扩展工厂函数中启动后台资源(进程、socket、文件监听器、定时器等),这些应该在 session_start 事件中启动
  • 在 session_shutdown 事件中清理会话级资源