agentjido/jido
🤖 Autonomous agent framework for Elixir. Built for distributed, autonomous behavior and dynamic workflows.
Jido – An autonomous‑agent framework for Elixir
What it is – Jido is a library that lets you build autonomous agents as ordinary Elixir/OTP components. An agent is an immutable data structure that implements a single cmd/2 function: you feed it an action, it returns a new agent state plus a list of directives that describe side‑effects the runtime should perform (e.g., emit a signal, spawn a child process, schedule a future task). The core package provides the agent model, a GenServer‑based AgentServer runtime, and a set of built‑in directives; AI/LLM integration is optional via companion packages.
Key concepts
| Concept | Role |
|---|---|
| Agent | Immutable struct with schema‑validated state; defines cmd/2. |
| Action | Pure or effectful function that receives validated params and the current context, returns state updates (and optionally directives). |
| Signal | CloudEvents‑style envelope used to route external events into agents. |
| Directive | Typed description of an effect the runtime owns (emit, spawn, schedule, stop, etc.). |
| Strategy | Execution policy (Direct, FSM, or custom) that decides how cmd/2 is run. |
| Plugin | Reusable capability module that can add state, actions, and directives to an agent. |
Why use Jido?
- OTP‑native – built on GenServer and supervision trees, so you get fault‑tolerance and hot‑code upgrades for free.
- Immutable, Elm‑style state – makes reasoning and testing straightforward.
- Explicit effect boundary – actions change state; directives describe side‑effects, keeping business logic pure.
- Multi‑agent orchestration – hierarchical parent/child agents, signal routing, and durable pods for grouping agents.
- AI‑optional – core works without any LLM; add
jido_aiorreq_llmonly when you need it.
Core features (as listed in the README)
- Immutable agent architecture with schema validation via NimbleOptions/Zoi.
- Directive‑based effects (Emit, Spawn, SpawnAgent, StopChild, StartSensor, Schedule, Stop, …) and a protocol for custom directives.
- OTP runtime integration –
AgentServerhandles supervision, parent‑child hierarchies, and signal routing. - Composable plugins that merge their own schema into the agent and provide lifecycle hooks.
- Multiple execution strategies – direct execution, finite‑state‑machine (FSM) workflows, and extensible custom strategies.
- Multi‑agent orchestration – named topologies, nested pods, partition‑safe tenancy, and durable groups.
- Built‑in scheduling & cron support.
- Extensive documentation (quick‑start, guides, API reference) and a Discord community.
Typical use cases
- Workflow engines where each step is an action and the overall process is modelled as an agent.
- Coordinated micro‑services that need reliable stateful orchestration (e.g., order processing, IoT device management).
- LLM‑augmented bots – add
jido_aito let an agent call an LLM for reasoning while keeping the core loop pure. - Multi‑tenant SaaS back‑ends – use pods and partitions to isolate tenant workloads while sharing the same BEAM node.
- Sensor/edge‑device orchestration – start/stop sensor runtimes via
StartSensor/StopSensordirectives.
Installation & quick start
# Add to mix.exs
{:jido, "~> 2.0"}
Then create a Jido instance module and put it in your supervision tree:
defmodule MyApp.Jido do
use Jido, otp_app: :my_app
end
# application.ex
children = [MyApp.Jido]
Supervisor.start_link(children, strategy: :one_for_one)
Define an agent and an action:
defmodule MyApp.CounterAgent do
use Jido.Agent,
name: "counter",
schema: [count: [type: :integer, default: 0]],
signal_routes: [{"increment", MyApp.Actions.Increment}]
end
defmodule MyApp.Actions.Increment do
use Jido.Action,
name: "increment",
schema: [amount: [type: :integer, default: 1]]
def run(params, ctx) do
current = ctx.state[:count] || 0
{:ok, %{count: current + params.amount}}
end
end
Run it:
agent = MyApp.CounterAgent.new()
{agent, dirs} = MyApp.CounterAgent.cmd(agent, {MyApp.Actions.Increment, %{amount: 5}})
# agent.state.count => 5
Or start it under the runtime:
{:ok, pid} = MyApp.Jido.start_agent(MyApp.CounterAgent, id: "c1")
Jido.AgentServer.call(pid, Jido.Signal.new!("increment", %{amount: 10}, source: "/user"))
Ecosystem packages
| Package | What it adds |
|---|---|
req_llm |
Thin HTTP client for LLM APIs |
jido_action |
Helper macros for composable actions, validation, and AI‑tool integration |
jido_signal |
CloudEvents envelope + utilities for pub/sub routing |
jido (core) |
Agent framework, directives, runtime |
jido_ai |
Optional LLM/AI integration for agents |
Maturity & community
- Version: 2.x (stable on Hex.pm).
- CI: GitHub Actions badge shows continuous integration.
- Docs: Full API reference on hexdocs.pm and extensive guides in the repo.
- Support: Discord community, website with demos, and a workbench repository for visual experimentation.
- License: Apache‑2.0 (permissive, commercial‑friendly).
TL;DR
Jido gives Elixir developers a formal, OTP‑native way to write autonomous agents. State is immutable, side‑effects are described by directives, and the runtime handles supervision, signal routing, and multi‑agent orchestration. AI is an optional add‑on, making Jido suitable for pure workflow engines as well as LLM‑augmented bots.
Related
- Project
- Project
- Project
- Project
- Project