Jido.AI

Hex.pmHex DocsCILicenseCoverage Status

Build tool-using Elixir agents with explicit reasoning strategies and production-ready request orchestration.

Hex | HexDocs | Jido Ecosystem | Discord

jido_ai is the AI runtime layer for Jido. You define tools and agents as Elixir modules, then run synchronous or asynchronous requests with built-in model routing, retries, and observability.

defmodule MyApp.Actions.AddNumbers do
  use Jido.Action,
    name: "add_numbers",
    schema: Zoi.object(%{a: Zoi.integer(), b: Zoi.integer()}),
    description: "Add two numbers."

  @impl true
  def run(%{a: a, b: b}, _context), do: {:ok, %{sum: a + b}}
end

defmodule MyApp.MathAgent do
  use Jido.AI.Agent,
    name: "math_agent",
    model: :fast,
    tools: [MyApp.Actions.AddNumbers],
    system_prompt: "Solve accurately. Use tools for arithmetic."
end

{:ok, pid} = Jido.AgentServer.start(agent: MyApp.MathAgent)
{:ok, answer} = MyApp.MathAgent.ask_sync(pid, "What is 19 + 23?")

Where This Package Fits

jido_ai is a core package in the Jido ecosystem:

Use jido_ai when you need long-lived agents, tool-calling loops, or explicit reasoning strategies. You can also use it without a running agent process via Jido.AI.generate_text/2, Jido.AI.ask/2, or Jido.Exec.run/3 with any action module. For cross-package tutorials (for example jido + jido_ai + app packages), see agentjido.xyz.

Installation

Igniter Installation (Recommended)

The fastest way to get started is with Igniter:

mix igniter.install jido_ai

This automatically:

Manual Installation

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

def deps do
  [
    {:jido, "~> 2.0"},
    {:jido_ai, "~> 2.0.0-rc.0"}
  ]
end
mix deps.get

Configure model aliases and at least one provider credential:

# config/config.exs
config :jido_ai,
  model_aliases: %{
    fast: "provider:fast-model",
    capable: "provider:capable-model"
  }

config :req_llm,
  anthropic_api_key: System.get_env("ANTHROPIC_API_KEY"),
  openai_api_key: System.get_env("OPENAI_API_KEY")

Quick Start

  1. Define one Jido.Action tool.
  2. Define one Jido.AI.Agent with that tool.
  3. Start the agent and call ask_sync/3 or ask/3 + await/2.
defmodule MyApp.Actions.Multiply do
  use Jido.Action,
    name: "multiply",
    schema: Zoi.object(%{a: Zoi.integer(), b: Zoi.integer()})

  @impl true
  def run(%{a: a, b: b}, _context), do: {:ok, %{product: a * b}}
end

defmodule MyApp.Agent do
  use Jido.AI.Agent,
    name: "my_agent",
    model: :fast,
    tools: [MyApp.Actions.Multiply]
end

{:ok, pid} = Jido.AgentServer.start(agent: MyApp.Agent)

# Sync convenience path
{:ok, result} = MyApp.Agent.ask_sync(pid, "What is 15 * 23?")

# Async path with explicit request handle
{:ok, request} = MyApp.Agent.ask(pid, "What is 144 * 12?")
{:ok, result2} = MyApp.Agent.await(request, timeout: 15_000)

Request-Scoped ReAct Controls

ask/3 and ask_sync/3 can narrow or override the active tool registry for a single run:

{:ok, result} =
  MyApp.Agent.ask_sync(pid, "Multiply 15 by 23",
    allowed_tools: ["multiply"],
    tool_context: %{tenant_id: "acme"},
    llm_opts: [reasoning_effort: :medium]
  )

For retrieval or classification flows, prefer having tools write StateOp.SetState updates and let a request_transformer read context[:state] to constrain the next turn. That keeps tool exposure, runtime state, and output schemas aligned without scraping message history. See Standalone ReAct Runtime for the pattern.

Need one-shot text generation without an agent process?

{:ok, text} = Jido.AI.ask("Summarize Phoenix PubSub in one paragraph.", model: :fast)

Choose Your Integration Surface

If you need Use Why
Tool-using agent loops Jido.AI.Agent ReAct strategy with request tracking and tool orchestration
Fixed reasoning strategy Jido.AI.CoDAgent, Jido.AI.CoTAgent, Jido.AI.AoTAgent, Jido.AI.ToTAgent, Jido.AI.GoTAgent, Jido.AI.TRMAgent, Jido.AI.AdaptiveAgent Strategy-specific control over reasoning behavior
AI inside existing workflows/jobs Jido.AI.Actions.* Run via Jido.Exec.run/3 without defining an agent module
Streaming + checkpoint/resume Jido.AI.Reasoning.ReAct Standalone ReAct runtime with event streams and checkpoint tokens
Thin model facade helpers Jido.AI.generate_text/2, generate_object/3, stream_text/2, ask/2 Fast path for direct LLM calls with alias/default support

Strategy Quick Pick

Full tradeoff matrix: Strategy Selection Playbook

Common First-Run Errors

Unknown model alias: :my_model

{:error, :not_a_tool} when registering or calling tools

Documentation

Documentation Map

Start here:

Strategy guides:

Integration and runtime guides:

Upgrading:

Deep reference:

Runnable Examples

The runnable demos now live in the top-level examples/ folder and are loaded on demand, so they stay out of the core jido_ai compile path.

mix run examples/scripts/demo/actions_llm_runtime_demo.exs
mix run examples/scripts/demo/actions_tool_calling_runtime_demo.exs
mix run examples/scripts/demo/actions_reasoning_runtime_demo.exs
mix run examples/scripts/demo/weather_multi_turn_context_demo.exs

Additional examples:

Why Jido.AI

Contributing

See CONTRIBUTING.md.

License

Apache-2.0. See LICENSE.md.