Hex.pm Hex Docs CI License Coverage Status

Pure functional agents and OTP runtime for building autonomous multi-agent workflows in Elixir.

The name "Jido" (自動) comes from the Japanese word meaning "automatic" or "automated", where 自 (ji) means "self" and 動 (dō) means "movement".

Learn more about Jido at agentjido.xyz.

Overview

With Jido, your agents are immutable data structures with a single command function:

defmodule MyAgent do
  use Jido.Agent,
    name: "my_agent",
    description: "My custom agent",
    schema: [
      count: [type: :integer, default: 0]
    ]
  end
end

{agent, directives} = MyAgent.cmd(agent, action)

State changes are pure data transformations; side effects are described as directives and executed by an OTP runtime. You get deterministic agent logic, testability without processes, and a clear path to running those agents in production.

The Jido Ecosystem

Jido is the core package of the Jido ecosystem. The ecosystem is built around the core Jido Agent behavior and offer several opt-in packages to extend the core behavior.

PackageDescription
req_llmHTTP client for LLM APIs
jido_actionComposable, validated actions with AI tool integration
jido_signalCloudEvents-based message envelope and supporting utilities for routing and pub/sub messaging
jidoCore agent framework with state management, directives, and runtime
jido_aiAI/LLM integration for agents
jido_coderAI coding agent with file operations, git integration, and test execution

For demos and examples of what you can build with the Jido Ecosystem, see https://agentjido.xyz.

Why Jido?

OTP primitives are excellent. You can build agent systems with raw GenServer. But when building multiple cooperating agents, you'll reinvent:

Raw OTPJido Formalizes
Ad-hoc message shapes per GenServerSignals as standard envelope
Business logic mixed in callbacksActions as reusable command pattern
Implicit effects scattered in codeDirectives as typed effect descriptions
Custom child tracking per serverBuilt-in parent/child hierarchy
Process exit = completionState-based completion semantics

Jido isn't "better GenServer" - it's a formalized agent pattern built on GenServer.

Key Features

Immutable Agent Architecture

  • Pure functional agent design inspired by Elm/Redux
  • cmd/2 as the core operation: actions in, updated agent + directives out
  • Schema-validated state with NimbleOptions or Zoi

Directive-Based Effects

  • Actions transform state; directives describe external effects
  • Built-in directives: Emit, Spawn, SpawnAgent, StopChild, Schedule, Stop
  • Protocol-based extensibility for custom directives

OTP Runtime Integration

  • GenServer-based AgentServer for production deployment
  • Parent-child agent hierarchies with lifecycle management
  • Signal routing with configurable strategies
  • Instance-scoped supervision for multi-tenant deployments

Composable Skills

  • Reusable behavior modules that extend agents
  • State isolation per skill with automatic schema merging
  • Lifecycle hooks for initialization and signal handling

Execution Strategies

  • Direct execution for simple workflows
  • FSM (Finite State Machine) strategy for state-driven workflows
  • Extensible strategy protocol for custom execution patterns

Multi-Agent Orchestration

  • Multi-agent workflows with configurable strategies
  • Plan-based orchestration for complex workflows
  • Extensible strategy protocol for custom execution patterns

Installation

The fastest way to get started is with Igniter:

mix igniter.install jido

This automatically:

  • Adds Jido to your dependencies
  • Creates configuration in config/config.exs
  • Adds Jido.Bus.InMemory to your supervision tree

Generate an example agent to get started:

mix igniter.install jido --example

Manual Installation

Add jido to your list of dependencies in mix.exs:

def deps do
  [
    {:jido, "~> 2.0"}
  ]
end

Then define a Jido instance module and add it to your supervision tree:

# In lib/my_app/jido.ex
defmodule MyApp.Jido do
  use Jido, otp_app: :my_app
end
# In config/config.exs
config :my_app, MyApp.Jido,
  max_tasks: 1000,
  agent_pools: []
# In your application.ex
children = [
  MyApp.Jido
]

Supervisor.start_link(children, strategy: :one_for_one)

Quick Start

1. Define an Agent

defmodule MyApp.CounterAgent do
  use Jido.Agent,
    name: "counter",
    description: "A simple counter agent",
    schema: [
      count: [type: :integer, default: 0]
    ]
end

2. Define an Action

defmodule MyApp.Actions.Increment do
  use Jido.Action,
    name: "increment",
    description: "Increments the counter by a given amount",
    schema: [
      amount: [type: :integer, default: 1]
    ]

  def run(params, context) do
    current = context.state[:count] || 0
    {:ok, %{count: current + params.amount}}
  end
end

3. Execute Commands

# Create an agent
agent = MyApp.CounterAgent.new()

# Execute an action - returns updated agent + directives
{agent, directives} = MyApp.CounterAgent.cmd(agent, {MyApp.Actions.Increment, %{amount: 5}})

# Check the state
agent.state.count
# => 5

4. Run with AgentServer

# Start the agent server
{:ok, pid} = MyApp.Jido.start_agent(MyApp.CounterAgent, id: "counter-1")

# Send signals to the running agent (synchronous)
{:ok, agent} = Jido.AgentServer.call(pid, Jido.Signal.new!("increment", %{amount: 10}, source: "/user"))

# Look up the agent by ID
pid = MyApp.Jido.whereis("counter-1")

# List all running agents
agents = MyApp.Jido.list_agents()

Core Concepts

The cmd/2 Contract

The fundamental operation in Jido:

{agent, directives} = MyAgent.cmd(agent, action)

Key invariants:

  • The returned agent is always complete - no "apply directives" step needed
  • directives describe external effects only - they never modify agent state
  • cmd/2 is a pure function - same inputs always produce same outputs

Actions vs Directives vs State Operations

ActionsDirectivesState Operations
Transform state, may perform side effectsDescribe external effectsDescribe internal state changes
Executed by cmd/2, update agent.stateBare structs emitted by agentsApplied by strategy layer
Can call APIs, read files, query databasesRuntime (AgentServer) interprets themNever leave the strategy

State Operations (Jido.Agent.StateOp)

State operations are internal state transitions handled by the strategy layer during cmd/2. Unlike directives, they never reach the runtime.

StateOpPurpose
SetStateDeep merge attributes into state
ReplaceStateReplace state wholesale
DeleteKeysRemove top-level keys
SetPathSet value at nested path
DeletePathDelete value at nested path

Directive Types

DirectivePurpose
EmitDispatch a signal via configured adapters
ErrorSignal an error from cmd/2
SpawnSpawn a generic BEAM child process
SpawnAgentSpawn a child Jido agent with hierarchy tracking
StopChildGracefully stop a tracked child agent
ScheduleSchedule a delayed message
StopStop the agent process

Documentation

Start here:

Guides:

Advanced:

API Reference: hexdocs.pm/jido

Development

Prerequisites

  • Elixir 1.17+
  • Erlang/OTP 26+

Running Tests

mix test

Quality Checks

mix quality  # Runs formatter, dialyzer, and credo

Contributing

We welcome contributions! Please see our Contributing Guide for details on:

  • Setting up your development environment
  • Running tests and quality checks
  • Submitting pull requests
  • Code style guidelines

License

Copyright 2024-2025 Mike Hostetler

Licensed under the Apache License, Version 2.0. See LICENSE for details.