Bun Plugin
使用受支持的 Bun SDK 与 CLI 路径构建强类型 Request Plugin。
Bun 是可信子进程 Execution Class,不是 Sandbox。Plugin 业务代码实现生成的
Capability Provider 类型;@lenso/bun 与生成的 Entrypoint 持有启动、JSON-RPC、
取消与关闭。
1. 创建项目
lenso plugin new example.echo --runtime bun
cd example.echo
创建过程会先暂存完整目录、安装精确 bun.lock 并执行 TypeScript 检查,成功后才
发布项目。只有离线脚手架才使用 --no-install。
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 投影与开发调用:
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. 检查与开发
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. 打包并安装
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,进程边界见
lenso-bun-adapter。
使用生成的 Capability 编写有状态 Plugin
上面的 providers/bind*Provider 形式仍是兼容入口。新代码优先通过生成的
Capability 值、provides 和 create 表达 Provider 与生命周期。
以下结构示例假设项目已从自己的 Contract 生成 Conversation 和 Store,
并定义了对应的 chat/get 操作:
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。 继续阅读命名依赖、完整同步示例 或构建 TypeScript Host。Host 的构建 Profile 有独立限制。