---
title: 编写 Capability
description: 定义 Request、Stream 与 Event 契约，并在各自负责的 Package 中生成语言投影。
---

Capability 是 Consumer 与 Provider 之间的契约。只定义一次；Rust 与 Bun
各自在分发该语言的 Package 中生成自己的投影。

首个 `lenso plugin new` 脚手架使用已有 Agent Tool Provider Capability。新的跨
Plugin 角色仍是显式 Contract-owner Workflow：编写 Descriptor 与 Schema，生成各
Package 自己持有的投影，再由 Capability Package 发布。

## 创建 Request Capability

下面的 Descriptor 定义了一个 `greet` Operation：

```json title="contract/greeting/capability.json"
{
  "id": "example.greeting@1",
  "version": "1.0.0",
  "portable": true,
  "cross_lane_transfer": true,
  "operations": [{
    "name": "greet",
    "interaction": "request",
    "request_schema": "schemas/greet-request.schema.json",
    "response_schema": "schemas/greet-response.schema.json",
    "domain_error_schema": "schemas/greet-error.schema.json"
  }]
}
```

引用的三个文件都是普通 JSON Schema。可预期的业务失败应进入 Domain
Error Schema，不要把运行时异常字符串当作业务结果：

```json title="contract/greeting/schemas/greet-error.schema.json"
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "string",
  "enum": ["empty_name"]
}
```

安装生成器，并只生成当前 Package 负责的投影。原生 Rust Capability Package：

```sh
cargo install lenso-contract-codegen --locked
lenso-contract-codegen generate \
  contract/greeting/capability.json \
  --rust \
  contract/greeting/src/generated.rs
```

自定义 Bun Capability Package 使用 `--typescript`，并且只保留 TypeScript
输出。Lenso 官方 Bun 投影由 `@lenso/bun` 从所有者仓库的锁定快照发布。

```sh
bun add @lenso/bun
```

CI 应拒绝生成物漂移和不兼容变更：

```sh
lenso-contract-codegen check \
  contract/greeting/capability.json \
  --rust \
  contract/greeting/src/generated.rs

lenso-contract-codegen lint old/capability.json contract/greeting/capability.json
```

## 选择交互形态

| 形态 | Descriptor 值 | 适用场景 | 当前语义 |
| --- | --- | --- | --- |
| Request | `"request"` | 只有一个最终结果的命令或查询 | 有界队列、并发上限、Deadline、取消 |
| Stream | `"stream"` | 双向会话 | 有界消息、两侧独立 half-close、显式最终结果 |
| Event | `"event"` | 易失性 fan-out | 每个订阅者独立有界准入和部分结果；不保证持久化或重投 |

Stream 与 Event 只需改变 `interaction`。生成器会输出所选语言对应的
Provider / Client 类型。

## 在 Composition 中设置容量

容量是 App 策略，不属于可移植 Descriptor。Plugin-owned Contract 提供安全默认；
Resolved App Plan 为精确 Generation 记录 Request Admission、Operation Override 与
Event Mailbox 上限。

`event_capacity` 只作用于 Event Operation。队列满时会拒绝准入，不会悄悄
变成带持久化和重投的 Outbox。

## 保持 Package-owned 投影最新

每个分发生成投影的 Package 都应运行 `lenso-contract-codegen check`。App Authoring
消费最终 Plugin Descriptor 与 Bundle，不再维护第二份 `lenso.json` Contract Registry。

可直接参考持续维护的完整 fixture：
[Request](https://github.com/LioRael/lenso-cli/tree/main/crates/lenso-authoring/tests/fixtures/contracts/greeting)、
[Stream](https://github.com/LioRael/lenso-protocols/tree/main/crates/lenso-contract-codegen/tests/fixtures/stream)
和 [Event](https://github.com/LioRael/lenso-protocols/tree/main/crates/lenso-contract-codegen/tests/fixtures/event)。
