Skip to Content
How-To GuidesRustAdding a New Agent to a Rust Golem Component

Adding a New Agent to a Rust Golem Component

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

  1. Create the agent module — add a new file src/<agent_name>.rs
  2. Define the agent trait — annotate with #[agent_definition]
  3. Implement the agent — annotate with #[agent_implementation]
  4. Re-export from lib.rs — add mod <agent_name>; and pub use <agent_name>::*;
  5. Build — run golem build to 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 type E must derive Schema like 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 Schema derive (plus IntoValue and FromValueAndType, which Schema implies)
  • 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. Use async methods and .await instead of blocking on futures
Last updated on