| Crates.io | runtara-agent-macro |
| lib.rs | runtara-agent-macro |
| version | 1.4.1 |
| created_at | 2025-12-17 14:05:32.467876+00 |
| updated_at | 2026-01-10 20:11:27.778456+00 |
| description | Proc macros for runtara agent definitions |
| homepage | |
| repository | https://github.com/runtara/runtara |
| max_upload_size | |
| id | 1990296 |
| size | 55,822 |
Procedural macros for defining custom agents in Runtara workflows. Use #[agent] and #[capability] to create reusable workflow components.
This crate provides macros to define agents and their capabilities:
#[agent]: Define an agent module with metadata#[capability]: Define individual capabilities (operations) within an agentAgents are automatically registered at compile time and can be used in workflow definitions.
Add to your Cargo.toml:
[dependencies]
runtara-agent-macro = "1.0"
runtara-dsl = "1.0" # For type definitions
use runtara_agent_macro::agent;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct GreetInput {
pub name: String,
}
#[derive(Serialize, Deserialize)]
pub struct GreetOutput {
pub message: String,
}
#[agent(id = "greeter", category = "demo")]
pub mod greeter {
use super::*;
#[capability(id = "greet", description = "Generate a greeting message")]
pub async fn greet(input: GreetInput) -> Result<GreetOutput, Box<dyn std::error::Error>> {
Ok(GreetOutput {
message: format!("Hello, {}!", input.name),
})
}
}
use runtara_agent_macro::agent;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct CreateOrderInput {
pub product_id: String,
pub quantity: u32,
}
#[derive(Serialize, Deserialize)]
pub struct CreateOrderOutput {
pub order_id: String,
pub total: f64,
}
#[derive(Serialize, Deserialize)]
pub struct GetOrderInput {
pub order_id: String,
}
#[derive(Serialize, Deserialize)]
pub struct GetOrderOutput {
pub order_id: String,
pub status: String,
pub items: Vec<String>,
}
#[agent(id = "my-erp", category = "integration", description = "ERP system integration")]
pub mod my_erp {
use super::*;
#[capability(id = "create-order", description = "Create a new order in the ERP system")]
pub async fn create_order(input: CreateOrderInput) -> Result<CreateOrderOutput, Box<dyn std::error::Error>> {
// Your ERP integration logic
let order_id = format!("ORD-{}", uuid::Uuid::new_v4());
let total = calculate_total(&input.product_id, input.quantity).await?;
Ok(CreateOrderOutput { order_id, total })
}
#[capability(id = "get-order", description = "Retrieve order details from the ERP system")]
pub async fn get_order(input: GetOrderInput) -> Result<GetOrderOutput, Box<dyn std::error::Error>> {
// Fetch order from ERP
let order = fetch_order_from_erp(&input.order_id).await?;
Ok(GetOrderOutput {
order_id: order.id,
status: order.status,
items: order.items,
})
}
}
Agents can receive connection configuration for external services:
use runtara_agent_macro::agent;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct FetchDataInput {
pub endpoint: String,
#[serde(default)]
pub connection: Option<serde_json::Value>, // Connection config injected by runtime
}
#[derive(Serialize, Deserialize)]
pub struct FetchDataOutput {
pub data: serde_json::Value,
}
#[agent(id = "custom-api", category = "integration")]
pub mod custom_api {
use super::*;
#[capability(id = "fetch", description = "Fetch data from API")]
pub async fn fetch(input: FetchDataInput) -> Result<FetchDataOutput, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let mut request = client.get(&input.endpoint);
// Apply connection configuration (API key, Bearer token, etc.)
if let Some(conn) = &input.connection {
if let Some(api_key) = conn.get("api_key").and_then(|v| v.as_str()) {
request = request.header("X-API-Key", api_key);
}
if let Some(bearer) = conn.get("bearer_token").and_then(|v| v.as_str()) {
request = request.header("Authorization", format!("Bearer {}", bearer));
}
}
let response = request.send().await?;
let data = response.json().await?;
Ok(FetchDataOutput { data })
}
}
#[agent] Attributes| Attribute | Required | Description |
|---|---|---|
id |
Yes | Unique identifier for the agent |
category |
Yes | Agent category (e.g., "integration", "transform", "io") |
description |
No | Human-readable description |
#[capability] Attributes| Attribute | Required | Description |
|---|---|---|
id |
Yes | Unique identifier for the capability |
description |
Yes | Human-readable description |
For capabilities to work with the workflow system:
Serialize + DeserializeSerialize + Deserializeasync and return Result<Output, Error>The macros generate:
Once defined, agents can be used in JSON workflow definitions:
{
"steps": {
"create": {
"stepType": "Agent",
"id": "create",
"agentId": "my-erp",
"capabilityId": "create-order",
"inputMapping": {
"product_id": { "valueType": "reference", "value": "data.product" },
"quantity": { "valueType": "immediate", "value": 5 }
}
}
}
}
runtara-dsl - DSL type definitionsruntara-agents - Built-in agent implementationsruntara-workflows - Compile workflows with custom agentsThis project is licensed under AGPL-3.0-or-later.