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_ai or req_llm only 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 – AgentServer handles 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_ai to 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/StopSensor directives.

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