Jido.Agent.Directive
(Jido v2.2.0)
View Source
Typed directive structs for Jido.Agent.
A directive is a pure description of an external effect for the runtime
(e.g. Jido.AgentServer) to execute. Agents and strategies never
interpret or execute directives; they only emit them.
Signal Integration
The Emit directive integrates with Jido.Signal and Jido.Signal.Dispatch:
%Emit{}- Dispatch a signal via configured adapters (pid, pubsub, bus, http, etc.)
Design
Directives are bare structs - no tuple wrappers. This enables:
- Clean pattern matching on struct type
- Protocol-based dispatch for extensibility
- External packages can define custom directives
Core Directives
%Emit{}- Dispatch a signal viaJido.Signal.Dispatch%Error{}- Signal an error (wrapsJido.Error.t())%Spawn{}- Spawn a generic BEAM child process (fire-and-forget, no tracking)%SpawnAgent{}- Spawn a child Jido agent with full hierarchy tracking%AdoptChild{}- Attach an orphaned or unattached child to the current parent%StopChild{}- Request a tracked child agent to stop gracefully%Schedule{}- Schedule a delayed message%RunInstruction{}- Execute an instruction at runtime and route result tocmd/2%Stop{}- Stop the agent process (self)
Usage
alias Jido.Agent.Directive
# Emit a signal (runtime will dispatch via configured adapters)
%Directive.Emit{signal: my_signal}
%Directive.Emit{signal: my_signal, dispatch: {:pubsub, topic: "events"}}
%Directive.Emit{signal: my_signal, dispatch: {:pid, target: pid}}
# Schedule for later
%Directive.Schedule{delay_ms: 5000, message: :timeout}
# Execute instruction at runtime
%Directive.RunInstruction{instruction: instruction, result_action: :fsm_instruction_result}Extensibility
External packages can define their own directive structs:
defmodule MyApp.Directive.CallLLM do
defstruct [:model, :prompt, :tag]
endThe runtime dispatches on struct type, so no changes to core are needed.
Summary
Types
Built-in core directives.
Restart policy for spawned AgentServer children.
Any external directive struct (core or extension).
Functions
Creates an AdoptChild directive for explicitly attaching a child to the current parent.
Creates a Cron directive for recurring scheduled execution.
Creates a CronCancel directive to stop a recurring job.
Creates an Emit directive.
Creates an Emit directive targeting the agent's parent.
Creates an Emit directive targeting a specific process by PID.
Creates an Error directive.
Creates a RunInstruction directive.
Creates a Schedule directive.
Creates a Spawn directive.
Creates a SpawnAgent directive for spawning child agents with hierarchy tracking.
Creates a Stop directive.
Creates a StopChild directive to gracefully stop a tracked child agent.
Types
@type core() :: Jido.Agent.Directive.Emit.t() | Jido.Agent.Directive.Error.t() | Jido.Agent.Directive.Spawn.t() | Jido.Agent.Directive.SpawnAgent.t() | Jido.Agent.Directive.AdoptChild.t() | Jido.Agent.Directive.StopChild.t() | Jido.Agent.Directive.Schedule.t() | Jido.Agent.Directive.RunInstruction.t() | Jido.Agent.Directive.Stop.t() | Jido.Agent.Directive.Cron.t() | Jido.Agent.Directive.CronCancel.t()
Built-in core directives.
@type restart_policy() :: :permanent | :temporary | :transient
Restart policy for spawned AgentServer children.
@type t() :: struct()
Any external directive struct (core or extension).
This is intentionally struct() so external packages can define
their own directive structs without modifying this type.
Functions
@spec adopt_child(pid() | String.t(), term(), keyword()) :: Jido.Agent.Directive.AdoptChild.t()
Creates an AdoptChild directive for explicitly attaching a child to the current parent.
Options
:meta- Metadata to write into the adopted child's new parent reference (map)
Examples
Directive.adopt_child(child_pid, :worker_1)
Directive.adopt_child("child-agent-id", :worker_1, meta: %{restored: true})
@spec cron(term(), term(), keyword()) :: Jido.Agent.Directive.Cron.t()
Creates a Cron directive for recurring scheduled execution.
Options
:job_id- Logical id for the job (for upsert/cancel):timezone- Timezone identifier
Examples
Directive.cron("* * * * *", tick_signal)
Directive.cron("@daily", cleanup_signal, job_id: :daily_cleanup)
Directive.cron("0 9 * * MON", weekly_signal, job_id: :monday_9am, timezone: "America/New_York")
@spec cron_cancel(term()) :: Jido.Agent.Directive.CronCancel.t()
Creates a CronCancel directive to stop a recurring job.
Examples
Directive.cron_cancel(:heartbeat)
Directive.cron_cancel(:daily_cleanup)
@spec emit(term(), term()) :: Jido.Agent.Directive.Emit.t()
Creates an Emit directive.
If dispatch is omitted, runtime will use AgentServer default_dispatch.
When no default is configured, runtime falls back to emitting to the current
agent process (self()).
Examples
Directive.emit(signal)
Directive.emit(signal, {:pubsub, topic: "events"})
@spec emit_to_parent(struct(), term(), Keyword.t()) :: Jido.Agent.Directive.Emit.t() | nil
Creates an Emit directive targeting the agent's parent.
The agent's state must have a __parent__ field containing a ParentRef struct.
This field is automatically populated when an agent is spawned via the
SpawnAgent directive or explicitly reattached via AdoptChild.
Returns nil if the agent has no current parent. Orphaned agents clear
__parent__ during the orphan transition, so emit_to_parent/3 becomes
unavailable until the child is explicitly adopted again. Former parent
provenance remains available via agent.state.__orphaned_from__, but that
field is intentionally not used for routing. Use List.wrap/1 to safely
handle the result when building directive lists.
Options
Same as emit_to_pid/3.
Examples
# In a child agent's action:
defmodule WorkDoneAction do
use Jido.Action, name: "work.done", schema: []
def run(_params, context) do
reply = Signal.new!("worker.result", %{answer: 42}, source: "/worker")
directive = Directive.emit_to_parent(context.agent, reply)
{:ok, %{}, List.wrap(directive)}
end
end
# With sync delivery
Directive.emit_to_parent(agent, signal, delivery_mode: :sync)
@spec emit_to_pid(term(), pid(), Keyword.t()) :: Jido.Agent.Directive.Emit.t()
Creates an Emit directive targeting a specific process by PID.
This is a convenience for sending signals directly to another agent or process.
Options
All options are passed to the :pid dispatch adapter:
:delivery_mode-:async(default) or:sync:timeout- Timeout for sync delivery (default: 5000)
Examples
Directive.emit_to_pid(signal, some_pid)
Directive.emit_to_pid(signal, worker_pid, delivery_mode: :sync)
@spec error(term(), atom() | nil) :: Jido.Agent.Directive.Error.t()
Creates an Error directive.
Examples
Directive.error(Jido.Error.validation_error("Invalid input"))
Directive.error(error, :normalize)
@spec run_instruction( Jido.Instruction.t(), keyword() ) :: Jido.Agent.Directive.RunInstruction.t()
Creates a RunInstruction directive.
Options
:result_action- Internal action atom/module to receive execution results (default::instruction_result):meta- Optional metadata echoed in result payload (map)
Examples
Directive.run_instruction(instruction)
Directive.run_instruction(instruction, result_action: :fsm_instruction_result)
@spec schedule(non_neg_integer(), term()) :: Jido.Agent.Directive.Schedule.t()
Creates a Schedule directive.
Examples
Directive.schedule(5000, :timeout)
Directive.schedule(1000, {:check, ref})
@spec spawn(term(), term()) :: Jido.Agent.Directive.Spawn.t()
Creates a Spawn directive.
Examples
Directive.spawn({MyWorker, arg: value})
Directive.spawn(child_spec, :worker_1)
@spec spawn_agent(term(), term(), keyword()) :: Jido.Agent.Directive.SpawnAgent.t()
Creates a SpawnAgent directive for spawning child agents with hierarchy tracking.
Options
:opts- Additional options for the child AgentServer (map)- Supports child startup options like
:id,:initial_state, and:on_parent_death - Does not support InstanceManager lifecycle/persistence options like
:storage,:idle_timeout,:lifecycle_mod,:pool,:pool_key, or:restored_from_storage
- Supports child startup options like
:meta- Metadata to pass to the child via parent reference (map):restart- Child restart policy under supervision (default::transient)
Examples
Directive.spawn_agent(MyWorkerAgent, :worker_1)
Directive.spawn_agent(MyWorkerAgent, :processor, opts: %{initial_state: %{batch_size: 100}})
Directive.spawn_agent(MyWorkerAgent, :handler, meta: %{assigned_topic: "events"})
Directive.spawn_agent(MyWorkerAgent, :durable, restart: :permanent)
@spec stop(term()) :: Jido.Agent.Directive.Stop.t()
Creates a Stop directive.
Examples
Directive.stop()
Directive.stop(:shutdown)
@spec stop_child(term(), term()) :: Jido.Agent.Directive.StopChild.t()
Creates a StopChild directive to gracefully stop a tracked child agent.
Examples
Directive.stop_child(:worker_1)
Directive.stop_child(:processor, :shutdown)