Capability authoring
Define Request, Stream, and Event contracts and generate each language projection in its owning package.
A Capability is the contract between a consumer and a provider. Author it once; each Rust or Bun distribution generates only the projection it owns.
The first lenso plugin new scaffold consumes the existing Agent Tool Provider
Capability. Defining a new cross-Plugin role remains an explicit contract-owner
workflow: author the Descriptor and schemas, generate each owned projection,
and publish them from the Capability package.
Create a request Capability
This descriptor declares one greet Operation:
{
"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"
}]
}
The three referenced files are ordinary JSON Schema. Keep expected business failures in the Domain Error schema rather than returning strings from runtime exceptions:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string",
"enum": ["empty_name"]
}
Install the generator and write the projection owned by this package. For a native Rust Capability package:
cargo install lenso-contract-codegen --locked
lenso-contract-codegen generate \
contract/greeting/capability.json \
--rust \
contract/greeting/src/generated.rs
For a custom Bun Capability package, use --typescript and keep only the
TypeScript output. Official Lenso Bun projections are published by
@lenso/bun from locked snapshots of their owner repositories.
bun add @lenso/bun
CI should reject generated drift and incompatible revisions:
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
Choose the interaction shape
| Shape | Descriptor value | Use it for | Current semantics |
|---|---|---|---|
| Request | "request" |
commands and queries with one terminal result | bounded queue, concurrency, deadline, cancellation |
| Stream | "stream" |
bidirectional conversations | bounded messages, independent half-close, explicit terminal result |
| Event | "event" |
volatile fan-out | per-subscriber bounded admission and partial outcomes; no persistence or redelivery |
For Stream and Event, only the interaction value changes. The generator emits
the matching Provider/Client types for the selected language.
Configure capacity in Composition
Capacity is App policy, not part of the portable Descriptor. The Plugin-owned contract supplies safe defaults; the resolved App Plan records Request admission, operation overrides, and Event mailbox bounds for the exact Generation.
event_capacity matters only for Event Operations. A full queue rejects
admission; it does not silently become a durable Outbox.
Keep package-owned projections current
Run lenso-contract-codegen check in each package that distributes a generated
projection. App authoring consumes the resulting Plugin Descriptor and Bundle;
it does not use a second lenso.json contract registry.
See the complete, maintained fixtures for Request, Stream, and Event.