Jido.Instruction (Jido v1.1.0-rc)
View SourceInstructions in Jido represent discrete units of work that can be planned, validated, and executed by agents. Think of them as "work orders" that tell agents exactly what needs to be done and how to do it.
Core Concepts
An Instruction wraps an Action module with everything it needs to execute:
- The Action to perform (required)
- Parameters for the action
- Execution context
- Runtime options
Structure
Each Instruction contains:
%Instruction{
id: "inst_abc123", # Unique identifier
action: MyApp.Actions.DoTask, # The action module to execute
params: %{value: 42}, # Parameters for the action
context: %{user_id: "123"}, # Execution context
opts: [retry: true], # Runtime options
}
Creating Instructions
Instructions support multiple creation formats for convenience:
1. Full Struct (Most Explicit)
%Instruction{
action: MyApp.Actions.ProcessOrder,
params: %{order_id: "123"},
context: %{tenant_id: "456"}
}
2. Action Module Only (Simplest)
MyApp.Actions.ProcessOrder
3. Action With Parameters (Common)
{MyApp.Actions.ProcessOrder, %{order_id: "123"}}
4. Factory Function
Instruction.new!(%{
action: MyApp.Actions.ProcessOrder,
params: %{order_id: "123"},
context: %{tenant_id: "456"}
})
Working with Instructions
Normalization
Convert various input formats to standard instruction structs:
# Normalize a single instruction
{:ok, [instruction]} = Instruction.normalize(MyApp.Actions.ProcessOrder)
# Normalize with context
{:ok, instructions} = Instruction.normalize(
[
MyApp.Actions.ValidateOrder,
{MyApp.Actions.ProcessOrder, %{priority: "high"}}
],
%{tenant_id: "123"} # Shared context
)
Validation
Ensure instructions use allowed actions:
allowed_actions = [
MyApp.Actions.ValidateOrder,
MyApp.Actions.ProcessOrder
]
:ok = Instruction.validate_allowed_actions(instructions, allowed_actions)
Common Patterns
1. Workflow Definition
instructions = [
MyApp.Actions.ValidateInput,
{MyApp.Actions.ProcessData, %{format: "json"}},
MyApp.Actions.SaveResults
]
2. Conditional Execution
instructions = [
MyApp.Actions.ValidateOrder,
{MyApp.Actions.CheckInventory, %{strict: true}},
# Add fulfillment only if in stock
if has_stock? do
{MyApp.Actions.FulfillOrder, %{warehouse: "main"}}
end
]
|> Enum.reject(&is_nil/1)
3. Context Sharing
# All instructions share common context
{:ok, instructions} = Instruction.normalize(
[ValidateUser, ProcessOrder, NotifyUser],
%{
request_id: "req_123",
tenant_id: "tenant_456",
}
)
See Also
Jido.Action
- Action behavior and implementationJido.Runner
- Instruction executionJido.Agent
- Agent-based execution
Summary
Functions
Creates a new Instruction struct from a map or keyword list of attributes.
Creates a new Instruction struct from a map or keyword list of attributes. Returns the struct directly or raises an error.
Normalizes instruction shorthand input into instruction structs. Accepts a variety of input formats and returns a list of normalized instruction structs.
Same as normalize/3
but raises on error.
Validates that all instructions use allowed actions.
Types
@type action_module() :: module()
@type action_params() :: map()
@type action_tuple() :: {action_module(), action_params()}
@type instruction() :: action_module() | action_tuple() | t()
@type instruction_list() :: [instruction()]
Functions
Creates a new Instruction struct from a map or keyword list of attributes.
Parameters
attrs
- Map or keyword list containing instruction attributes::action
- Action module (required):params
- Map of parameters (optional, default: %{}):context
- Context map (optional, default: %{}):opts
- Keyword list of options (optional, default: []):id
- String identifier (optional, defaults to UUID)
Returns
{:ok, %Instruction{}}
- Successfully created instruction{:error, :missing_action}
- If action is not provided{:error, :invalid_action}
- If action is not a module
Examples
iex> Instruction.new(%{action: MyAction, params: %{value: 1}})
{:ok, %Instruction{action: MyAction, params: %{value: 1}}}
iex> Instruction.new(action: MyAction)
{:ok, %Instruction{action: MyAction}}
iex> Instruction.new(%{params: %{value: 1}})
{:error, :missing_action}
Creates a new Instruction struct from a map or keyword list of attributes. Returns the struct directly or raises an error.
Parameters
attrs
- Map or keyword list containing instruction attributes::action
- Action module (required):params
- Map of parameters (optional, default: %{}):context
- Context map (optional, default: %{}):opts
- Keyword list of options (optional, default: [])
Returns
%Instruction{}
- Successfully created instruction
Raises
Jido.Error
- If action is missing or invalid
Examples
iex> Instruction.new!(%{action: MyAction, params: %{value: 1}})
%Instruction{action: MyAction, params: %{value: 1}}
iex> Instruction.new!(action: MyAction)
%Instruction{action: MyAction}
iex> Instruction.new!(%{params: %{value: 1}})
** (Jido.Error) missing action
@spec normalize(instruction() | instruction_list(), map(), keyword()) :: {:ok, [t()]} | {:error, term()}
@spec normalize(instruction() | instruction_list(), map(), keyword()) :: [t()]
Normalizes instruction shorthand input into instruction structs. Accepts a variety of input formats and returns a list of normalized instruction structs.
Parameters
input
- One of:- Single instruction struct (%Instruction{})
- List of instruction structs
- Single action module (MyApp.Actions.ProcessOrder)
- Action tuple with params ({MyApp.Actions.ProcessOrder, %{order_id: "123"}})
- Action tuple with empty params ({MyApp.Actions.ProcessOrder, %{}})
- Action tuple with context ({MyApp.Actions.ProcessOrder, %{}, %{tenant_id: "123"}})
- Action tuple with opts ({MyApp.Actions.ProcessOrder, %{}, %{}, [retry: true]})
- List of any combination of the above formats
context
- Optional context map to merge into all instructions (default: %{})opts
- Optional keyword list of options (default: [])
Returns
{:ok, [%Instruction{}]}
- List of normalized instruction structs{:error, term()}
- If normalization fails
Examples
iex> Instruction.normalize(MyApp.Actions.ProcessOrder)
{:ok, [%Instruction{action: MyApp.Actions.ProcessOrder}]}
iex> Instruction.normalize({MyApp.Actions.ProcessOrder, %{order_id: "123"}})
{:ok, [%Instruction{action: MyApp.Actions.ProcessOrder, params: %{order_id: "123"}}]}
iex> Instruction.normalize([
...> MyApp.Actions.ValidateOrder,
...> {MyApp.Actions.ProcessOrder, %{priority: "high"}},
...> {MyApp.Actions.NotifyUser, %{}, %{user_id: "123"}}
...> ])
{:ok, [%Instruction{...}, %Instruction{...}, %Instruction{...}]}
Same as normalize/3
but raises on error.
Parameters
instruction
- Instruction to normalizecontext
- Optional context map to mergeopts
- Optional options to merge
Returns
[t()]
- List of normalized instructions
Raises
Jido.Error
- If instruction cannot be normalized
Examples
iex> Instruction.normalize!({MyAction, %{value: 42}})
[%Instruction{action: MyAction, params: %{value: 42}}]
iex> Instruction.normalize!(MyAction)
[%Instruction{action: MyAction, params: %{}}]
Validates that all instructions use allowed actions.
Parameters
instructions
- List of instruction structsallowed_actions
- List of allowed action modules
Returns
:ok
- All actions are allowed{:error, term()}
- If any action is not allowed
Examples
iex> instructions = [%Instruction{action: MyAction}, %Instruction{action: OtherAction}]
iex> Instruction.validate_allowed_actions(instructions, [MyAction])
{:error, "Actions not allowed: OtherAction"}
iex> instructions = [%Instruction{action: MyAction}]
iex> Instruction.validate_allowed_actions(instructions, [MyAction])
:ok