Base macro for Jido.AI agents with ReAct strategy implied.
Wraps use Jido.Agent with Jido.AI.Reasoning.ReAct.Strategy wired in,
plus standard state fields and helper functions.
Usage
defmodule MyApp.WeatherAgent do
use Jido.AI.Agent,
name: "weather_agent",
description: "Weather Q&A agent",
tools: [MyApp.Actions.Weather, MyApp.Actions.Forecast],
system_prompt: "You are a weather expert..."
endOptions
:name(required) - Agent name:tools(required) - List ofJido.Actionmodules to use as tools:description- Agent description (default: "AI agent #{name}"):tags- Agent tags for discovery/classification (default:[]):system_prompt- Custom system prompt for the LLM:model- Model alias or direct model spec (default: :fast, resolved via Jido.AI.resolve_model/1):max_iterations- Maximum reasoning iterations (default: 10):max_tokens- Maximum tokens per LLM response (default:4096):streaming- Whether to stream LLM responses (default:true):request_policy- Request concurrency policy (default::reject):tool_timeout_ms- Per-attempt tool execution timeout in ms (default: 15_000):tool_max_retries- Number of retries for tool failures (default: 1):tool_retry_backoff_ms- Retry backoff in ms (default: 200):stream_timeout_ms- Stream consumer timeout in ms (default: auto-derived from tool_timeout_ms + 60s). How long to wait for events between coordinator updates. Increase for agents with slow LLM responses or long tool executions.:stream_receive_timeout_msis accepted as a compatibility alias.:effect_policy- Agent-level effect policy (default allow-list):strategy_effect_policy- Optional strategy-level narrowing policy (cannot broaden agent policy):runtime_adapter- Deprecated compatibility flag (delegated ReAct runtime is always enabled):runtime_task_supervisor- Optional Task.Supervisor used by delegated ReAct runtime:observability- Observability options map:req_http_options- Base Req HTTP options passed through to ReqLLM calls:llm_opts- Additional ReqLLM generation options merged into ReAct LLM calls:request_transformer- Module implementing per-turn ReAct request shaping:output- Structured final-output config with an object-shaped Zoi or JSON Schema:tool_context- Context map passed to all tool executions (e.g.,%{actor: user, domain: MyDomain}). Must be literal data only — module aliases, atoms, strings, numbers, lists, and maps are permitted. Function calls, module attributes (@attr), and pinned variables (^var) raiseCompileError. Runtime reserves:state(core Jido-compatible) for tool execution snapshots. User-provided values for that key are overwritten per request.:skills- Additional skills to attach to the agent (TaskSupervisorSkill is auto-included):signal_routes- Additional agent-level signal routes forwarded toJido.Agent. ReAct routes are still provided by the default strategy.
Generated Functions
ask/2,3- Async: sends query, returns{:ok, %Request{}}for later awaitingask_stream/2,3- Async: sends query and returns a request handle plus runtime event streamawait/1,2- Awaits a specific request's completionask_sync/2,3- Sync convenience: sends query and waits for resulton_before_cmd/2- Captures request in state before processingon_after_cmd/3- Updates request result when done
Request Tracking
Each ask/2 call returns a Request struct that can be awaited:
{:ok, request} = MyAgent.ask(pid, "What is 2+2?")
{:ok, result} = MyAgent.await(request, timeout: 30_000)Or use the synchronous convenience wrapper:
{:ok, result} = MyAgent.ask_sync(pid, "What is 2+2?", timeout: 30_000)This pattern follows Elixir's Task.async/await idiom and enables safe
concurrent request handling.
State Fields
The agent state includes:
:model- The LLM model being used:requests- Map of request_id => request state (for concurrent tracking):last_request_id- ID of the most recent request:last_query- The most recent query (backward compat):last_answer- The final answer from the last completed query (backward compat):completed- Boolean indicating if the last query is complete (backward compat)
Task Supervisor
Each agent instance gets its own Task.Supervisor automatically started via the
Jido.AI.Plugins.TaskSupervisor. This supervisor is used for:
- LLM streaming operations
- Tool execution
- Other async operations within the agent's lifecycle
The supervisor is stored in the skill's internal state (agent.state.__task_supervisor_skill__)
and is accessible via Jido.AI.Directive.Helpers.get_task_supervisor/1. It is automatically
cleaned up when the agent terminates.
Example
{:ok, pid} = Jido.AgentServer.start(agent: MyApp.WeatherAgent)
# Async pattern (preferred for concurrent requests)
{:ok, request} = MyApp.WeatherAgent.ask(pid, "What's the weather in Tokyo?")
{:ok, answer} = MyApp.WeatherAgent.await(request)
# Sync pattern (convenience for simple cases)
{:ok, answer} = MyApp.WeatherAgent.ask_sync(pid, "What's the weather in Tokyo?")Per-Request Tool Context
You can pass per-request context that will be merged with the agent's base tool_context:
{:ok, request} = MyApp.WeatherAgent.ask(pid, "Get my preferences",
tool_context: %{actor: current_user, tenant_id: "acme"})ReAct and ToT tool execution contexts include a runtime-managed snapshot at :state
(canonical, core-aligned). This key is reserved and overrides same-named values
from tool_context.
Summary
Functions
Extract tool action modules from skills.