# Golem Add Agent Moonbit

> Adding a new MoonBit agent to a Golem component. Use when the user asks to create, add, or define a new agent type in a MoonBit Golem project.

- Skill: `golemcloud/golem-add-agent-moonbit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add golemcloud/golem-add-agent-moonbit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/golemcloud/golem-add-agent-moonbit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: golemcloud (https://skillmd.com/u/golemcloud)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/golemcloud/golem-add-agent-moonbit

---


# Adding a New Agent to a MoonBit Golem Component

## Overview

An **agent** is a durable, stateful unit of computation in Golem. Each agent type is defined as a struct annotated with `#derive.agent` and has a constructor `fn AgentName::new(...)` plus public methods `pub fn AgentName::method(self: Self)`.

## Steps

1. **Create the agent file** — add a new file `src/<agent_name>.mbt`
2. **Define the agent struct** — annotate with `#derive.agent`
3. **Add constructor** — `fn AgentName::new(param: Type) -> AgentName`
4. **Add methods** — `pub fn AgentName::method(self: Self) -> ReturnType`
5. **Build** — run `golem build` to verify

## Agent Definition

```moonbit
#derive.agent
struct MyAgent {
  name: String
  mut count: UInt
}

fn MyAgent::new(name: String) -> MyAgent {
  { name, count: 0 }
}

pub fn MyAgent::get_count(self: Self) -> UInt {
  self.count
}

pub fn MyAgent::increment(self: Self) -> UInt {
  self.count = self.count + 1
  self.count
}
```

## Custom Types

All parameter and return types must have schema support. For custom structs and enums, annotate with `#derive.golem_schema`:

```moonbit
#derive.golem_schema
struct MyData {
  field1: String
  field2: UInt
}

#derive.golem_schema
enum Status {
  Active
  Inactive(String)
}
```

## Returning Failures

Agent methods should distinguish between **domain errors** (expected failure outcomes) and **uncaught errors**:

- **Uncaught errors** (uncaught `raise`, aborts, runtime panics) 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]`. Custom error types need `#derive.golem_schema`.

```moonbit
#derive.golem_schema
pub(all) enum WithdrawError {
  InsufficientFunds(UInt64)
  AccountClosed
}

#derive.agent
struct Wallet {
  owner : String
  mut balance : UInt64
  mut closed : Bool
}

fn Wallet::new(owner : String) -> Wallet {
  { owner, balance: 0, closed: false }
}

pub fn Wallet::withdraw(self : Self, amount : UInt64) -> Result[UInt64, WithdrawError] {
  if self.closed {
    Err(AccountClosed)
  } else if amount > self.balance {
    Err(InsufficientFunds(self.balance))
  } else {
    self.balance = self.balance - amount
    Ok(self.balance)
  }
}
```

Returning `Err(...)` completes the invocation successfully — the caller receives the error as a value. Letting an exception propagate out of the method (e.g. an unhandled `raise`, or `abort(...)`) will instead trigger a retry and eventually fail the whole agent.

## Key Constraints

- 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
- Method names use `snake_case`
- **Never edit generated files** — `golem_reexports.mbt`, `golem_agents.mbt`, and `golem_derive.mbt` are auto-generated by `golem build`
- Only `pub fn` methods are exposed as agent methods — private functions are not exported

