View Source Jido.Agent.Directive (Jido v1.0.0)
Provides a type-safe way to modify agent state through discrete, validated directives.
## Overview
Directives are immutable instructions that can be applied to an agent to modify its state in predefined ways. Each directive type is implemented as a separate struct with its own validation rules, helping ensure type safety and consistent state transitions.
## Available Directives
EnqueueDirective- Adds a new instruction to the agent's pending queue- Requires an action atom
- Supports optional params and context maps
- Example:
%EnqueueDirective{action: :move, params: %{location: :kitchen}}
RegisterActionDirective- Registers a new action module with the agent- Requires a valid module atom
- Example:
%RegisterActionDirective{action_module: MyApp.Actions.Move}
DeregisterActionDirective- Removes an action module from the agent- Requires a valid module atom
- Example:
%DeregisterActionDirective{action_module: MyApp.Actions.Move}
## Usage
Directives are typically created by action handlers and applied through the apply_directives/3
function. The function processes directives in order and ensures atomicity - if any directive
fails, the entire operation is rolled back.
# Single directive
directive = %EnqueueDirective{action: :move, params: %{location: :kitchen}}
result = %Result{directives: [directive]}
{:ok, updated_agent} = Directive.apply_directives(agent, result)
# Multiple directives
directives = [
%RegisterActionDirective{action_module: MyApp.Actions.Move},
%EnqueueDirective{action: :move, params: %{location: :kitchen}}
]
result = %Result{directives: directives}
{:ok, updated_agent} = Directive.apply_directives(agent, result)## Validation
Each directive type has its own validation rules:
EnqueueDirectiverequires a non-nil atom for the actionRegisterActionDirectiverequires a valid module atomDeregisterActionDirectiverequires a valid module atom
Failed validation results in an error tuple being returned and processing being halted.
## Error Handling
The module uses tagged tuples for error handling:
{:ok, updated_agent}- Successful application of directives{:error, reason}- Failed validation or application
Common error reasons include:
:invalid_action- The action specified in anEnqueueDirectiveis invalid:invalid_action_module- The module specified in aRegister/DeregisterDirectiveis invalid
Summary
Functions
Applies a single directive to an agent. Pattern matches on directive type to execute the appropriate transformation.
Applies a list of directives to an agent, maintaining ordering and atomicity. Returns either the updated agent or an error if any directive application fails.
Checks if a value is a valid directive struct or ok-tupled directive.
Types
@type directive_result() :: {:ok, Jido.Agent.t()} | {:error, term()}
Functions
@spec apply_directive(Jido.Agent.t(), t(), keyword()) :: directive_result()
Applies a single directive to an agent. Pattern matches on directive type to execute the appropriate transformation.
Parameters
- agent: The agent struct to apply the directive to
- directive: The directive struct to apply
- opts: Optional keyword list of options (default: [])
Returns
{:ok, updated_agent}- Directive was successfully applied{:error, reason}- Failed to apply directive with reason
Directive Types
EnqueueDirective
Adds a new instruction to the agent's pending queue.
RegisterActionDirective
Registers a new action module with the agent.
DeregisterActionDirective
Removes an action module from the agent.
Applies a list of directives to an agent, maintaining ordering and atomicity. Returns either the updated agent or an error if any directive application fails.
Parameters
- agent: The agent struct to apply directives to
- result: A Result struct containing the list of directives to apply
- opts: Optional keyword list of options (default: [])
Returns
{:ok, updated_agent}- All directives were successfully applied{:error, reason}- A directive failed to apply, with reason for failure
Examples
result = %Result{directives: [
%EnqueueDirective{action: :my_action, params: %{key: "value"}},
%RegisterActionDirective{action_module: MyAction}
]}
{:ok, updated_agent} = Directive.apply_directives(agent, result)Behavior
- Applies directives in order, stopping on first error
- Maintains atomicity - all directives succeed or none are applied
- Logs debug info about directive application
Checks if a value is a valid directive struct or ok-tupled directive.
A valid directive is either:
- A struct of type EnqueueDirective, RegisterActionDirective, or DeregisterActionDirective
- An ok-tuple containing one of the above directive structs
Parameters
- value: Any value to check
Returns
trueif the value is a valid directivefalseotherwise
Examples
iex> is_directive?(%EnqueueDirective{action: :test})
true
iex> is_directive?({:ok, %RegisterActionDirective{action_module: MyModule}})
true
iex> is_directive?(:not_a_directive)
false