打包插件
把想要复用或分享的应用行为放进插件。Python 包在 bub 入口点组中声明目标,Bub 导入这个目标,并注册其中的 hook 实现。你也可以在自己的服务中复用现有插件,继续使用宿主自己的调用入口。
完整的入门例子见编写第一个插件。这篇指南说明打包自己的插件时,需要选择哪些形式。
可移植的 Agent Plugins 使用另一种格式,包括 plugin.json、skills 和 MCP servers。Agent Plugins 集成通过一个 Python 插件加载这些包。
插件需要安装 Bub中说明的应用依赖。本指南使用 bub[app]>=0.6.0 作为包依赖。更新已有插件时,参见升级到 0.6.0。
[project.entry-points."bub"]
myplugin = "bub_myplugin.plugin"
键 myplugin 是诊断信息中的插件名称,值是要导入的 Python 对象。
选择一种目标形式:
| 目标 | 注册方式 | 适用情况 |
|---|---|---|
bub_myplugin.plugin |
注册模块 | hooks 是模块级函数 |
bub_myplugin.plugin:plugin |
注册实例 | hooks 需要共享对象状态 |
bub_myplugin.plugin:MyPlugin |
将 BubFramework 传给类或工厂,注册返回值 |
hooks 需要访问 framework |
模块形式在模块顶层定义 hooks:
from bub import hookimpl
@hookimpl
def build_prompt(message, session_id, state):
return "Describe this workspace."
实例形式在目标模块中创建对象:
from bub import hookimpl
class MyPlugin:
@hookimpl
def build_prompt(self, message, session_id, state):
return "Describe this workspace."
plugin = MyPlugin()
所有可调用目标都会收到 framework,类也一样。构造函数或工厂需要接收这个参数:
from bub import BubFramework, hookimpl
class MyPlugin:
def __init__(self, framework: BubFramework) -> None:
self.framework = framework
@hookimpl
def build_prompt(self, message, session_id, state):
return f"Describe the workspace at {self.framework.workspace}."
这些例子会替换提示词。请在改变应用行为中选择真正适合任务的 hook。
导入时注册工具
Section titled “导入时注册工具”如果包内定义了 @tool 函数,在入口点模块中导入工具模块,确保 agent 创建前已完成注册:
from . import tools # noqa: F401
应用创建 BubAgent 时会获取已注册工具的快照。添加应用工具会说明注册、延迟加载和代码模式。
安装到应用环境
Section titled “安装到应用环境”可编辑安装允许你直接修改 Python 源码,无需重新构建包。安装目标必须是运行 Bub 的同一个环境。
使用 uv 项目时,在插件目录运行:
uv sync
uv run bub hooks
如果安装到已有且已激活的应用环境,使用 uv pip install -e .,然后在该环境中运行 bub hooks。
bub hooks 可以确认注册结果。实际运行一次 hook 要处理的任务,再检查优先级和返回值。Bub 先注册内置 hooks,再注册入口点插件。同等优先级通常按注册顺序的逆序调用;tryfirst 和 trylast 会影响顺序。调用规则说明了哪个实现先运行。
如果插件没有出现,检查入口点组名、当前环境,以及启动日志中的导入错误。修改包元数据后,需要重新安装包。
发布前,构建 wheel 并安装到独立环境,确认入口点能加载,并用一个实际任务检查 hook。如果要同时发布 skills 或多个插件,参见打包 Bub 应用。