Adding a New Agent to a Rust Golem Component
SkillAI & modelsAdding a new Rust agent to a Golem component. Use when the user asks to create, add, or define a new agent type, implement an agent trait, or add agent methods in a Rust Golem project.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Adding a New Agent to a Rust Golem Component skill
What this skill tells your AI
The instructions your AI receives, as published by golemcloud/golem in golem-skills/skills/rust/golem-add-agent-rust/SKILL.md and read by ahel’s review.
Overview
An agent is a durable, stateful unit of computation in Golem. Each agent type is defined as a trait annotated with #[agent_definition] and implemented on a struct annotated with #[agent_implementation].
Steps
- Create the agent module — add a new file
src/<agent_name>.rs - Define the agent trait — annotate with
#[agent_definition] - Implement the agent — annotate with
#[agent_implementation] - Re-export from
lib.rs— addmod <agent_name>;andpub use <agent_name>::*; - Build — run
golem buildto verify
Agent Definition
use golem_rust::{agent_definition, agent_implementation};
#[agent_definition]
pub trait MyAgent {
// Constructor parameters form the agent's identity.
// Two agents with the same parameters are the same agent.
fn new(name: String) -> Self;
// Agent methods — can be sync or async
fn get_count(&self) -> u32;
fn increment(&mut self) -> u32;
async fn fetch_data(&self, url: String) -> String;
}
struct MyAgentImpl {
name: String,
count: u32,
}
#[agent_implementation]
impl MyAgent for MyAgentImpl {
fn new(name: String) -> Self {
Self { name, count: 0 }
}
fn get_count(&self) -> u32 {
self.count
}
fn increment(&mut self) -> u32 {
self.count += 1;
self.count
}
async fn fetch_data(&self, url: String) -> String {
// Use wstd::http for HTTP requests
todo!()
}
}
Custom Types
All parameter and return types must implement the Schema trait. For custom types, derive it along with IntoValue and FromValueAndType:
use golem_rust::Schema;
use serde::{Serialize, Deserialize};
#[derive(Clone, Schema, Serialize, Deserialize)]
pub struct MyData {
pub field1: String,
pub field2: u32,
}
Returning Failures
Agent methods should distinguish between domain errors (expected failure outcomes) and uncaught errors:
- Uncaught errors (panics, unwrapped
Err, etc.) are not returned to the caller as a failed invocation. Golem treats them as crashes: the invocation is retried according to the agent's retry policy, and if the retries are exhausted the agent itself becomes failed. - Domain errors that the caller should observe as a normal failure result must be expressed in the method's return type using
Result<T, E>. The error typeEmust deriveSchemalike any other custom type.
use golem_rust::{agent_definition, agent_implementation, Schema};
use serde::{Serialize, Deserialize};
#[derive(Clone, Debug, Schema, Serialize, Deserialize)]
pub enum WithdrawError {
InsufficientFunds { available: u64 },
AccountClosed,
}
#[agent_definition]
pub trait Wallet {
fn new(owner: String) -> Self;
fn withdraw(&mut self, amount: u64) -> Result<u64, WithdrawError>;
}
struct WalletImpl {
owner: String,
balance: u64,
closed: bool,
}
#[agent_implementation]
impl Wallet for WalletImpl {
fn new(owner: String) -> Self {
Self { owner, balance: 0, closed: false }
}
fn withdraw(&mut self, amount: u64) -> Result<u64, WithdrawError> {
if self.closed {
return Err(WithdrawError::AccountClosed);
}
if amount > self.balance {
return Err(WithdrawError::InsufficientFunds { available: self.balance });
}
self.balance -= amount;
Ok(self.balance)
}
}
Returning Err(WithdrawError::...) completes the invocation successfully — the caller receives the error as a value. Panicking with unwrap(), expect(), panic!(), or returning from ? on an unrelated error type will instead trigger a retry and eventually fail the whole agent.
Key Constraints
- All agent method parameters are passed by value (no references)
- All custom types need
Schemaderive (plusIntoValueandFromValueAndType, whichSchemaimplies) - Constructor parameters form the agent identity — two agents with the same parameters are the same agent
- Agents are created implicitly on first invocation — no separate creation step
- Invocations are processed sequentially in a single thread — no concurrency within a single agent
- Never use
block_on— all agent methods run in an async context. Useasyncmethods and.awaitinstead of blocking on futures
Signals
- GitHub stars
- 2k
- Forks
- 212
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
golem-add-agent-rust- Source
- github.com/golemcloud/golem