| Crates.io | distri |
| lib.rs | distri |
| version | 0.3.2 |
| created_at | 2025-12-22 15:52:17.444999+00 |
| updated_at | 2026-01-23 20:38:22.197324+00 |
| description | Rust client for the Distri A2A agent platform |
| homepage | https://distri.dev |
| repository | https://github.com/distrihub/distri |
| max_upload_size | |
| id | 1999904 |
| size | 254,206 |
Rust client for the Distri A2A agent platform. Use it to invoke agents, stream responses over SSE, and handle tool calls, connect MCPs and much more. Check out https://distri.dev/ for further information.
[dependencies]
distri = "0.2.4"
use distri::Distri;
use distri_types::Message;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Uses DISTRI_BASE_URL and DISTRI_API_KEY if set.
let client = Distri::from_env();
let messages = vec![Message::user("Write a short haiku about Rust.".into(), None)];
let replies = client.invoke("my-agent", &messages).await?;
for reply in replies {
if let Some(text) = reply.as_text() {
println!("{text}");
}
}
Ok(())
}
use distri::Distri;
use distri_types::Message;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Distri::new();
let messages = vec![Message::user("Stream the response.".into(), None)];
client
.invoke_stream("my-agent", &messages, |item| async move {
if let Some(message) = item.message {
if let Some(text) = message.as_text() {
println!("{text}");
}
}
})
.await?;
Ok(())
}
use distri::{AgentStreamClient, Distri, DistriConfig, ExternalToolRegistry};
use distri_types::{AgentEvent, ToolCall, ToolResponse};
use serde_json::json;
let registry = ExternalToolRegistry::new();
registry.register("my-agent", "echo", |call: ToolCall, _event: AgentEvent| async move {
Ok(ToolResponse::direct(
call.tool_call_id,
call.tool_name,
json!({ "echo": call.input }),
))
});
let stream = AgentStreamClient::from_config(DistriConfig::default()).with_tool_registry(registry);
let client = Distri::new().with_stream_client(stream);
Distri::from_env() and DistriConfig::from_env() read:
DISTRI_BASE_URL (defaults to https://api.distri.dev)DISTRI_API_KEY (optional)You can also create a ~/.distri/config file:
base_url = "https://api.distri.dev"
api_key = "your-api-key"
The Distri client provides a comprehensive session store API for managing thread-scoped key-value storage. Session values can be used to store state, share data between agent iterations, and attach additional content to user messages.
use distri::Distri;
use serde_json::json;
let client = Distri::from_env();
let session_id = "thread-123";
// Set a session value
client.set_session_value(
session_id,
"user_preference",
json!({ "theme": "dark", "language": "en" }),
None, // Optional expiry ISO timestamp
).await?;
// Get a single session value
let value = client.get_session_value(session_id, "user_preference").await?;
println!("User preference: {:?}", value);
// Get all session values as a HashMap
let all_values = client.get_session_values(session_id).await?;
for (key, value) in all_values {
println!("{}: {:?}", key, value);
}
// Delete a specific key
client.delete_session_value(session_id, "user_preference").await?;
// Clear all values in a session
client.clear_session(session_id).await?;
For granular control, use the prefixed user parts API. Any session value with the __user_part_ prefix is automatically included in user messages:
use distri::Distri;
use distri_types::Part;
let client = Distri::from_env();
let session_id = "thread-123";
// Set a named user part (automatically prefixed with __user_part_)
client.set_user_part(
session_id,
"observation", // Name for this part
Part::Text("The user clicked the submit button".to_string()),
).await?;
// Set a text user part (convenience method)
client.set_user_part_text(
session_id,
"screenshot_description",
"Screenshot shows the login form with validation errors",
).await?;
// Set an image user part (with automatic gzip compression)
client.set_user_part_image(
session_id,
"screenshot",
distri_types::FileType::Bytes {
bytes: base64_image_string,
mime_type: "image/png".to_string(),
name: Some("screenshot.png".to_string()),
},
).await?;
// Delete a specific user part
client.delete_user_part(session_id, "observation").await?;
// Clear all user parts
client.clear_user_parts(session_id).await?;
Session values can optionally have an expiry time:
use chrono::Utc;
let expiry = Utc::now() + chrono::Duration::hours(24);
client.set_session_value(
session_id,
"temporary_data",
json!({ "data": "value" }),
Some(&expiry.to_rfc3339()),
).await?;
distri-types for message, tool, and config typesdistri-a2a for the A2A protocol primitivesdistri-filesystem for tool implementationsMIT