Jido.AgentServer.DirectiveExec protocol (Jido v2.0.0-rc.0)
View SourceProtocol for executing directives in AgentServer.
Implement this protocol for custom directive types to extend AgentServer with new effect handlers without modifying core code.
Return Values
{:ok, state}- Directive executed successfully, continue processing{:async, ref | nil, state}- Async work started (ref for tracking, nil if fire-and-forget){:stop, reason, state}- Hard stop the agent process (see warning below)
⚠️ WARNING: {:stop, ...} Semantics
{:stop, reason, state} is a hard stop that terminates the AgentServer immediately:
- Pending directives are dropped - Any directives still in the queue will NOT be executed
- Async work is orphaned - In-flight tasks may complete but their signals go nowhere
- Hooks don't run -
on_after_cmd/3and similar callbacks will NOT be invoked - State may be incomplete - External pollers may see partial state or get
:noproc
When to use {:stop, ...}
Reserved for abnormal or framework-level termination only:
- Irrecoverable errors during directive execution
- Framework decisions (e.g.,
on_parent_death: :stop) - Explicit shutdown requests (with reason like
:shutdown)
Do NOT use {:stop, ...} for normal completion
For agents that complete their work (e.g., ReAct finishing a conversation):
- Set
state.statusto:completedor:failedin your agent/strategy - Store results in state (e.g.,
last_answer,final_result) - Let external code poll
AgentServer.state/1and check status - Process stays alive until explicitly stopped or supervised
This matches Elm/Redux semantics where completion is a state concern, not a process lifecycle concern.
Example Implementation
defimpl Jido.AgentServer.DirectiveExec, for: MyApp.Directive.CallLLM do
def exec(%{model: model, prompt: prompt}, _input_signal, state) do
Task.Supervisor.start_child(Jido.TaskSupervisor, fn ->
MyApp.LLM.call(model, prompt)
end)
{:async, nil, state}
end
endFallback for Unknown Directives
Unknown directive types are logged and ignored by default. The fallback
implementation uses @fallback_to_any true.
Summary
Functions
Execute a directive, returning an updated state.
Types
@type t() :: term()
All the types that implement this protocol.
Functions
@spec exec(struct(), Jido.Signal.t(), Jido.AgentServer.State.t()) :: {:ok, Jido.AgentServer.State.t()} | {:async, reference() | nil, Jido.AgentServer.State.t()} | {:stop, term(), Jido.AgentServer.State.t()}
Execute a directive, returning an updated state.
Parameters
directive- The directive struct to executeinput_signal- The signal that triggered this directivestate- The current AgentServer.State
Returns
{:ok, state}- Continue processing with updated state{:async, ref | nil, state}- Async work started{:stop, reason, state}- Stop the agent