---
title: Bun Plugin
description: 使用受支持的 Bun SDK 与 CLI 路径构建强类型 Request Plugin。
---

Bun 是可信子进程 Execution Class，不是 Sandbox。Plugin 业务代码实现生成的
Capability Provider 类型；`@lenso/bun` 与生成的 Entrypoint 持有启动、JSON-RPC、
取消与关闭。

## 1. 创建项目

```sh
lenso plugin new example.echo --runtime bun
cd example.echo
```

创建过程会先暂存完整目录、安装精确 `bun.lock` 并执行 TypeScript 检查，成功后才
发布项目。只有离线脚手架才使用 `--no-install`。

```text
example.echo/
├── package.json
├── bun.lock
├── tsconfig.json
└── src/
    ├── plugin.ts
    ├── lenso.bun.generated.ts
    ├── lenso.describe.generated.ts
    └── lenso.invoke.generated.ts
```

只编辑 `src/plugin.ts`。初始脚手架实现生成的
`lenso.agent.tool-provider@2` Provider，并暴露一个 Tool。预期业务结果返回生成的
Domain Error；抛出的异常仍是 Runtime Failure。

## 2. 实现 Provider

authoring 文件只导出一个 Plugin definition。生成文件负责 Bun server、Descriptor
投影与开发调用：

```ts title="src/plugin.ts"
import { definePlugin } from "@lenso/bun";
import {
  bindToolProviderProvider,
  type ToolProviderProvider,
} from "@lenso/bun/capabilities/agent-tool-provider";

const tool: ToolProviderProvider = {
  async catalog() {
    return { ok: true, value: { tools: [{
      name: "company.uppercase",
      description: "Convert text to uppercase.",
      input_schema_json: JSON.stringify({
        type: "object",
        additionalProperties: false,
        properties: { text: { type: "string", maxLength: 4096 } },
        required: ["text"],
      }),
    }] } };
  },
  async execute(_context, request) {
    if (request.name !== "company.uppercase") {
      return { ok: false, error: { kind: "domain", error: "not_found" } };
    }
    let input: unknown;
    try {
      input = JSON.parse(request.arguments_json);
    } catch {
      return { ok: false, error: { kind: "domain", error: "invalid_arguments" } };
    }
    if (typeof input !== "object" || input === null || !("text" in input)
      || typeof input.text !== "string") {
      return { ok: false, error: { kind: "domain", error: "invalid_arguments" } };
    }
    return { ok: true, value: {
      content: input.text.toUpperCase(),
      content_type: "text",
      metadata_json: "{}",
    } };
  },
};

export default definePlugin({ providers: [bindToolProviderProvider(tool)] });
```

输入校验与预期业务拒绝应保留在生成的 Domain Error union 中。只有实现损坏或
运行时条件才应抛出异常。

## 3. 检查与开发

```sh
lenso plugin check
lenso plugin dev \
  --operation execute \
  --request-json '{"name":"example.echo","arguments_json":"{\"text\":\"hello\"}"}'
lenso plugin dev --watch \
  --operation execute \
  --request-json '{"name":"example.echo","arguments_json":"{\"text\":\"hello\"}"}'
```

`check` 会类型检查、构建 Bun 实现、派生可移植 Descriptor、生成标准 Bundle 并
验证其 Closure。`dev` 直接调用同一份 Provider，作者无需实现测试 Wire。Watch
Mode 在一次构建失败后仍保持运行。

## 4. 打包并安装

```sh
lenso plugin pack
lenso plugins add dist/example.echo-0.1.0.lenso-plugin --root "$HOME/.lenso/agent"
```

Archive 选择 `lenso.bun-process@1`。兼容的产品 Host 必须链接 Bun Adapter，并为
每个 Provided Capability 注册生成的 Rust Codec；Agent Host 已包含这条集成。
运行 Host 的机器必须能找到 `bun`。

当前 Bun Authoring V2 支持 Request、双向 Stream、Event Provider，以及这三种交互的
生成式出站依赖客户端。`@lenso/bun 0.5.1` 和 `@lenso/bun-plugin 0.4.1` 是已记录的
发布版本；文档中的早期“仅 Request”限制不再适用于这组 SDK。

类型化 SDK 见 [`@lenso/bun`](https://www.npmjs.com/package/@lenso/bun)，进程边界见
[`lenso-bun-adapter`](https://github.com/LioRael/lenso-bun-adapter)。


## 使用生成的 Capability 编写有状态 Plugin

上面的 `providers`/`bind*Provider` 形式仍是兼容入口。新代码优先通过生成的
Capability 值、`provides` 和 `create` 表达 Provider 与生命周期。
以下结构示例假设项目已从自己的 Contract 生成 `Conversation` 和 `Store`，
并定义了对应的 `chat`/`get` 操作：

```ts
import { definePlugin } from "@lenso/bun";
import { Conversation } from "./generated/conversation.ts";
import { Store } from "./generated/store.ts";

export default definePlugin({
  provides: [Conversation],
  dependencies: { store: Store.required() },
  async create({ dependencies }) {
    return {
      async *chat(_context, request) {
        const greeting = await dependencies.store.get(request.room);
        yield { text: greeting ?? "Hello" };
      },
    };
  },
});
```


依赖字段名默认成为稳定 requirement ID；`required()`、`optional()` 和 `many()`
适用于所有三种交互。`create` 按 Instance 构造，`stop` 在托管关闭中最多执行一次。
无 Provider、只消费依赖或持有生命周期工作的 Plugin 也有效。

服务端输出 Stream 可返回 async generator；双向消息、独立 half-close 或终结业务
错误使用生成的 `StreamSession`。Event handler 可返回 `void` 或 `Promise<void>`，
发布等待处理完成，Promise 拒绝映射为 Runtime Failure。出站客户端只调用 Plan 选择的
Provider，并保留取消、消息顺序及有界准入语义。

具体生成接口见 [Bun SDK](https://github.com/LioRael/lenso-bun-adapter/blob/main/packages/lenso-bun-plugin/README.md)。
继续阅读[命名依赖](/docs/zh/core/named-dependencies)、[完整同步示例](/docs/zh/core/document-sync)
或[构建 TypeScript Host](/docs/zh/core/typescript-host)。Host 的构建 Profile 有独立限制。
