Skip to content

Legion — Elixir-native framework for building runtime AI agents

Legion is Software Mansion Labs’ open-source Elixir framework for building AI agents that live inside an application and get things done by writing code — the agent emits Lua (default) or Elixir, which is evaluated in a sandbox with per-eval time and memory budgets. The only way for generated code to affect the host is through tool functions the developer registered via use Legion.Tool on an existing module. Bundled with a Legion.Sandbox.Lua backend on top of tv-labs/lua (Lua 5.3 VM in pure Elixir, no NIFs), an allowlisted Legion.Sandbox.Elixir backend, an announced Popcorn (AtomVM/WebAssembly) backend that runs generated code in the user’s browser, plus telemetry, persistence via Ecto/Repo, an OpenAI/Anthropic model layer via ReqLLM, and a legion_web LiveView dashboard.

  • Lua-in-pure-Elixir is the default sandbox: agents write Lua evaluated by tv-labs/lua, a Lua 5.3 register-based VM implemented entirely on the BEAM with no NIFs or C dependencies; Lua code has no path to the host BEAM except through the registered tool functions [README, “Legion.Sandbox.Lua (default)”].
  • Tools are ordinary Elixir modules — use Legion.Tool on any module and Legion introspects its source and exposes its public functions to the agent, so there is nothing separate to declare or keep in sync as the app changes [Landing page, “Tools”].
  • Every action runs in a sandbox with timeout and memory budgets; conversations are persisted in the host’s own database via an Ecto Repo the developer supplies; a LiveView dashboard shows live conversations and every line of code an agent writes [Landing page].
  • Auth context is set before the agent starts and can be read from inside tools at runtime — the generated code itself never sees credentials, only the tools do [Landing page, “Auth”].
  • Deployment shapes: one runtime backs a chat interface, an MCP server that lets Claude / Cursor drive it as an external tool, or a background worker that clears a queue, all from the same agent process abstraction (GenServer-shaped, plays with OTP supervision trees and pools) [Landing page, “One runtime, many shapes”].
  • An Elixir sandbox is also available for higher-trust deployments — the agent writes Elixir, defmodule/import/spawn/send/apply and similar dangerous constructs are blocked at the AST level, and module access is allowlisted to stdlib plus the developer’s registered tools; the README explicitly flags this backend as “powerful but the allowlist guards an enormous language surface” and recommends it only for the app’s own LLM-backed agents, not arbitrary third-party generated code [README, “Legion.Sandbox.Elixir”].
  • A third Popcorn backend is announced but not yet shipped — the agent would emit Elixir compiled to AtomVM running in the user’s browser via WebAssembly, so generated code never touches the server [README, “Popcorn (coming soon)”].
  • Datadog integration is available for agent-and-LLM telemetry emitted alongside application telemetry [README, “Datadog integration”].

Legion is structured as one top-level agent process (a supervised GenServer) that owns a conversation, an LLM connection (via ReqLLM — model strings map to OpenAI-compatible / Anthropic / Gemini providers), a registered tool set, and a sandbox backend. On each iteration the LLM produces code targeting the configured sandbox language; the sandbox evaluates that code under time and memory limits; tool calls made from inside the sandbox marshal Lua tables ↔ Elixir maps/lists, Elixir tuples ↔ arrays, atoms ↔ strings, and route through the developer’s registered Legion.Tool modules. The evaluation transcript is persisted through the caller’s Ecto.Repo; telemetry events fire at every level (agent, message, iteration, LLM call, sandbox eval); the legion_web LiveView dashboard subscribes to those events to render live traces.

Legion agents can spawn and message other Legion agents — the intended pattern is delegation between narrowly-scoped agents rather than one monolithic super-agent — and can be exposed as MCP servers so external agents (Claude Desktop, Cursor, another Legion agent) can drive them as tools.

Repository ships with a hello-world quickstart, a chat-window demo, an MCP-server demo, and the LiveView dashboard. No filed benchmarks — this is infrastructure, not a trained model. Landing page (legion.swmansion.com) hosts a live demo where the user can prompt an agent to modify its own page and watch each line of Lua execute. Package appears to be pre-1.0 with active development from Software Mansion (Elixir consultancy; core React Native contributors).

Underlying tv-labs/lua reports “benchmarks competitively” versus Robert Virding’s Luerl (the previous state of the art for embedded Lua on the BEAM); as of lua v1.0.0 it is a full pure-Elixir reimplementation of the Lua 5.3 lexer, parser, and register-based VM rather than a wrapper around Luerl.

Slots into the Tool-Use Agents design space at a point the currently-filed papers have not concretely occupied. The recent MCP-centric trend (Toolathlon-GYM: Large-Scale Long-Horizon Environments for Tool-Use Agents, OpenReward — 330+ RL Environments through one API (General Reasoning announcement), Previewing the Model Hardware Standard) standardizes the protocol between an agent and its tools; Legion standardizes the substrate underneath a single agent — the same “restricted language + registered tools + per-eval budget” split as Cua open-sources Computer History — encrypted local cross-session memory for computer-use agents‘s Computer History pattern (driver-level substrate) and Anthropic’s Model Hardware Standard, but at the language-VM layer inside an existing application. Sibling to DimOS — The Agentive Operating System for Physical Space (v0.0.13) on the “packaged agent runtime” axis (DimOS ports the pattern to embodied hardware via MCP; Legion targets in-app deployment via BEAM).

The “agent writes Lua because it’s the smallest sufficient target for LLM code generation” observation on the ElixirForum thread (Dave Lucia at CodeBeam Berlin) is worth naming — Legion is the second filed artifact after Introducing Waddle: Agents that Control Robots (Waddle) that treats code-as-policy as the primary agent interface rather than tool-call JSON, and the first to bet that the agent’s execution substrate is production-grade BEAM concurrency rather than a container.

  • Tool-Use Agents — Legion is a substrate for the ReAct-over-tools loop this concept tracks; complements Toolathlon-GYM / OpenReward (protocol standardization) with a runtime-standardization pole
  • RL Environment Platforms — Legion shares the “per-action sandbox with time and memory limits” design principle with SETA / Toolathlon-GYM / OpenReward, but as a deployment runtime rather than a training-environment fleet
  • DimOS — The Agentive Operating System for Physical Space (v0.0.13) — sibling on the “packaged runtime for agents that write code against a whitelisted skill/tool surface” axis, applied to embodied hardware instead of BEAM applications
  • Introducing Waddle: Agents that Control Robots — same code-as-policy bet, with the sandbox targeting robot control code rather than in-app tool execution
  • Previewing the Model Hardware Standard — Anthropic’s Model Hardware Standard shares the “explore-then-restrict, deterministic scripts once semantics are pinned” pattern; Legion is the in-app language-VM analog