Portable Rust Plugin
Create one portable Rust Plugin and ship a verified Bundle.
Use this path for an ordinary installable Agent Tool. The Rust scaffold keeps business behavior in one source file and lets the SDK derive its Capability descriptor, Wasm lowering, Process entrypoint, and package metadata.
1. Create the project
# Portable Wasm plus a trusted native Process from the same source
lenso plugin new example.echo
# Wasm only
lenso plugin new example.echo --runtime wasm
# Trusted Process only
lenso plugin new example.echo --runtime process
The default multi-output project is useful when portability and native process compatibility both matter. Process Plugins have normal local process authority; they are not sandboxes.
example.echo/
├── Cargo.toml
├── Cargo.lock
└── src/
├── lib.rs # business behavior
└── main.rs # generated Process entrypoint for multi/process projects
The scaffold is intentionally narrow: it creates an Agent Tool Provider. It is not a general generator for arbitrary Capability providers, stateful Plugins, Web UI, or Bun projects.
2. Implement behavior
The initial scaffold uses the public macros rather than hand-written Adapter protocol code:
use lenso_agent_tool_sdk::prelude::*;
use schemars::JsonSchema;
#[derive(Debug, serde::Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
struct Arguments {
text: String,
}
#[lenso::plugin]
#[derive(Clone, Copy, Debug, Default)]
struct Plugin;
#[lenso_agent_tool_sdk::tool_provider]
impl Plugin {
#[tool(name = "example.echo", description = "Echo text.")]
fn execute(arguments: Arguments) -> Result<ExecuteResponse, ExecuteError> {
Ok(ExecuteResponse {
content: arguments.text,
content_type: ContentType::Text,
metadata_json: "{}".try_into().unwrap(),
})
}
}
The Arguments type becomes the Tool’s JSON Schema. Expected bad input returns
ExecuteError; a panic or broken runtime boundary remains a Runtime Failure.
3. Run the development loop
lenso plugin check
lenso plugin dev --implementation auto --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 builds every declared implementation and checks descriptor agreement.
dev crosses a real Adapter boundary; it does not call the Rust function as a
test shortcut. --watch rebuilds and reruns the same request after changes.
Use --implementation wasm, process, or all when you need to compare the
declared outputs explicitly.
4. Package the Release
lenso plugin pack
pack builds release artifacts, requires every implementation to expose the
same Contract, writes one immutable .lenso-plugin archive under dist/, and
reopens the published bytes through the installation verifier.
Add the resulting Bundle through Add Plugins to an App. For another Capability role, define its contract first and use the Linked Rust Plugin path or a supported typed SDK.
For independent providers of the same Capability, stateful construction, and cleanup, continue with named dependencies and the complete document-sync example.