跳转到内容

构建你的第一个插件

本教程引导你编写一个最小 Bub 插件,用 echo 响应覆写 model 阶段,将其安装到活动环境,并确认框架已识别。

该插件无需模型凭据,可同时作为冒烟测试和真实插件的起点模板。

你需要准备:

  • 已在 uv 管理的环境中 安装 Bub
  • 在 workspace 之外有一个空闲目录用于 scaffold 插件包

创建包结构:

mkdir bub-echo-plugin
cd bub-echo-plugin
mkdir -p src/bub_echo_plugin
touch src/bub_echo_plugin/__init__.py

创建 pyproject.toml[project.entry-points."bub"] 段是让插件可被发现的关键:

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "bub-echo-plugin"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bub>=0.1"]

[project.entry-points."bub"]
echo = "bub_echo_plugin.plugin:echo_plugin"

[tool.hatch.build.targets.wheel]
packages = ["src/bub_echo_plugin"]

创建 src/bub_echo_plugin/plugin.py。插件是任何方法被 @hookimpl 装饰的对象:

from __future__ import annotations

from bub import hookimpl


class EchoPlugin:
    @hookimpl
    def build_prompt(self, message, session_id, state):
        if hasattr(message, "content"):
            return str(message.content)
        if isinstance(message, dict):
            return str(message.get("content", ""))
        return str(message)

    @hookimpl
    def run_model(self, prompt, session_id, state):
        text = prompt if isinstance(prompt, str) else str(prompt)
        return f"[echo:{session_id}] {text}"


echo_plugin = EchoPlugin()

build_promptfirstresult hook —— 第一个非 None 的返回值胜出。run_model 同样是 firstresult,所以本实现完全覆写了内置 agent。

从插件目录把插件包及其依赖同步到该插件项目的 .venv

uv sync

uv sync 默认以 editable 方式安装当前插件包。下面的 uv run bub ... 命令会在同一个包含插件 entry point 的环境中运行 Bub。

如果你想把插件安装到已有 Bub checkout 的虚拟环境中,请先激活目标虚拟环境,再运行 uv pip install -e .

请求 Bub 输出 hook 报告:

uv run bub hooks

你应当在 build_promptrun_model hook 项下看到 echobuiltin 并列。

接着运行一次单次 turn:

uv run bub run "hello from plugin tutorial"

outbound 消息应当包含:

[echo:cli:local] hello from plugin tutorial

如果响应来自真实模型,说明插件未加载——请在插件项目中重跑 uv sync,或确认插件已安装到运行 bub 的虚拟环境中,然后重新检查 bub hooks