Elixir / OTP · agent runtime

BEAM infrastructure for agents that keep running.

Run autonomous agents locally or remotely with supervision, live events, durable state, and multi-engine execution. LemonSim Arena makes the system visible.

  • 19 playable scenarios
  • 16 verified scorecards
  • 5 always-on arenas
  • seeded deterministic runs

The runtime

What Lemon gives an agent

Every agent is an ordinary BEAM process with an ordinary BEAM lifecycle. That is the whole trick — and it is why the failure modes of long-running agents stop being architecture problems.

  1. 01

    A process of its own

    Each agent runs in an isolated, preemptively scheduled process with its own heap. One agent looping, blocking on a slow tool call, or crashing does not stall or corrupt the others.

    isolation · concurrency

  2. 02

    A supervisor above it

    Agents sit under OTP supervision trees. A crash is a known state transition, not an outage: the restart policy is declared up front, and session history is persisted to disk as it happens, so a restarted run picks the thread back up instead of leaving a half-finished one behind.

    supervision · recovery

  3. 03

    A channel into it

    Message passing means a running agent can be steered, interrupted, or resumed mid-flight, and everything it does emits a bounded, ordered event stream you can watch or record.

    live steering · telemetry

Deployment

One runtime, two deployment modes

The same supervised agent processes, the same event stream, the same durable state. What changes is where the control surface lives.

Everything on your machine

Start the runtime on a laptop or a box you own. Agents, tools, memory, and secrets stay on local disk; the terminal UI and the local web console attach to the same supervised processes. The only traffic that leaves the machine is the traffic you configure — model provider calls, plus whatever network, search, or browser tools you enable for an agent.

  • TUI, local web console, and CLI attach to one running node
  • Encrypted local secrets and on-disk run history
  • Pluggable execution engines — the native Lemon engine plus Codex CLI, Claude CLI, OpenCode CLI and Pi CLI backends, swappable per session

LemonSim

LemonSim Arena: the runtime under pressure

The arena is not the product — it is the proving ground. Many model-driven actors take turns in the same event-sourced world, and five domains run as always-on ranked leagues. Every run writes an artifact you can replay and re-verify. If the infrastructure is weak, the arena is where it shows.

  1. spawnEach actor becomes a supervised process with a seeded, tool-constrained decision loop.
  2. runTurns advance an event-sourced world; every decision, tool call, and token cost is recorded.
  3. recoverRecorded events and durable artifacts keep the simulation inspectable: runs can be replayed, scored, and verified instead of becoming opaque.
  4. verifyReplay recomputes the scorecard from final world state and diffs it against a hash manifest.

The panels above are CSS mockups with illustrative data, not a live feed. Real runs and leaderboards are produced by the mix lemon.sim.* tasks in the repository.

Hands on

Watch it live, then prove the result

Everything in the runtime is observable from a shell: subscribe to the event bus from IEx, run a seeded simulation from Mix, and verify the artifact it wrote.

iex — attach to a live arena
# subscribe to the werewolf league on the event bus
LemonCore.Bus.subscribe(Arena.league_topic(:werewolf))

# every turn, vote, and restart arrives as a message
receive do
  {:bus, event} -> IO.inspect(event.type)
end
# => :night_kill · :vote_cast · :actor_restarted · …
shell — scored, verified, no API key
$ mix lemon.sim.vending_bench --preset ci --offline-strategy baseline --sim-id vb_ci
$ mix lemon.sim.verify apps/lemon_sim/priv/game_logs/vending_bench/vb_ci
✓ scorecard recomputed — match
✓ hash manifest — match
$ mix lemon.sim.score  apps/lemon_sim/priv/game_logs/vending_bench/vb_ci
execution engines native Lemon Codex CLI Claude CLI OpenCode CLI Pi CLI swappable per session

Why BEAM

Platform primitives, translated into outcomes

Long-running agents are already a distributed-systems problem. The BEAM has had answers to that problem for decades; Lemon uses them directly instead of rebuilding them in glue.

Process per agent
One agent's bad day stays its own. A stuck or crashed run can't take the rest of your fleet with it.
OTP supervision trees
Failures recover instead of paging you. Restart policy is declared up front, not improvised in a retry wrapper.
Message passing
You can steer a run mid-flight. Interrupt, redirect, or add context to an agent that is already working.
Bounded event streams
Watching is cheap and safe. Observers get an ordered feed with backpressure instead of an unbounded firehose.
Preemptive scheduling
Many agents at once stay responsive. No single hot loop monopolises the runtime.
Durable state & event sourcing
A restart resumes, it doesn't reset. History is on disk, so runs can be replayed and audited later.
Built-in telemetry
Cost and behaviour are measurable. Per-actor token and cost accounting rides along with the run.

Architecture

Clients in, artifacts out

A layered Elixir umbrella: a provider-agnostic model client and an agent loop over a small foundation of config, store, event bus, and telemetry — with the assistant and LemonSim as the two products on top.

Evidence

What's actually in the repository

Claims worth checking, and the commands that check them. Everything below is a property of the code in this project — not a benchmark of someone else's.

19

playable scenarios

Werewolf, Vending Bench, Diplomacy, Poker, Survivor, Auction, Courtroom, Supply Chain, Legislature and more — each an event-sourced world with tool-constrained agents.

16

registry-verified scorecards

Each scored scenario's scorecard is a pure function of final world state, registered and recomputed by the verifier rather than trusted from the run.

seeded

deterministic runs

Runs take an explicit seed and offline strategies run with no API keys at all, so a result can be reproduced by anyone who clones the repo.

replay

hash verification

Every run writes a hash-manifested artifact bundle; mix lemon.sim.verify replays it and diffs the recomputed result against the manifest.

suites & ratings

benchmark matrices and model ratings

Suites run competitors × seeds into deterministic suite.json and leaderboard.md artifacts; an order-independent Bradley-Terry fit over pairwise seed-level comparisons produces cross-suite model ratings, surfaced on a leaderboards page in the spectator UI. The runtime underneath spans a 21-app umbrella, a 26-provider abstraction, and a control plane with 112+ RPC methods.

Agents are long-lived systems. Run them like one.