Jido.AI.Reasoning.Helpers
(Jido AI v2.1.0)
View Source
Helper functions for creating StateOps in Jido.AI strategies.
This module provides convenient helpers for common state operation patterns
used across strategies. It wraps Jido.Agent.StateOp constructors with
strategy-specific semantics.
StateOp Types
SetState- Deep merge attributes into stateSetPath- Set value at nested pathDeleteKeys- Remove top-level keysDeletePath- Delete value at nested path
Usage
state_ops = [
Helpers.set_strategy_status(:running),
Helpers.increment_iteration(),
Helpers.append_to_conversation(message)
]
Summary
Functions
Builds normalized context for plugin-routed action execution.
Creates a StateOp to add a pending tool call.
Creates a StateOp to append a message to the conversation.
Creates a StateOp to append to the streaming text.
Applies state operations to a state map.
Creates a StateOp to clear the current LLM call ID.
Creates a StateOp to clear pending tool calls.
Composes multiple state operations into a single list.
Creates a StateOp to delete specific keys from strategy state.
Creates a StateOp to delete temporary keys from strategy state.
Executes a non-strategy Jido.Action instruction using direct strategy semantics.
Executes an instruction if its action is a module implementing run/2.
Creates a StateOp to prepend a message to the conversation.
Creates a StateOp to remove a specific pending tool by ID.
Creates a StateOp to reset the strategy state to initial values.
Creates a StateOp to set the current LLM call ID.
Creates a StateOp to set a specific config field.
Creates a StateOp to set the entire conversation.
Creates a StateOp to set the final answer.
Creates a StateOp to increment the iteration counter.
Creates a StateOp to set the iteration status.
Creates a StateOp to set pending tool calls.
Creates a StateOp to set a specific field in the strategy state.
Creates a StateOp to set the streaming text.
Creates a StateOp to set the termination reason.
Creates a StateOp to set the usage metadata.
Creates a StateOp to update the config field in strategy state.
Creates StateOps to update multiple config fields at once.
Creates a StateOp to update the strategy state.
Creates StateOps to update tools, actions_by_name, and reqllm_tools together.
Types
@type state_op() :: Jido.Agent.StateOp.SetState.t() | Jido.Agent.StateOp.SetPath.t() | Jido.Agent.StateOp.DeleteKeys.t() | Jido.Agent.StateOp.DeletePath.t()
@type strategy_ctx() :: map()
Functions
@spec action_context(Jido.Agent.t(), strategy_ctx()) :: map()
Builds normalized context for plugin-routed action execution.
Guarantees the state, agent, and plugin_state keys are present.
@spec add_pending_tool(map()) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to add a pending tool call.
Examples
iex> tool = %{id: "call_1", name: "search", arguments: %{query: "test"}}
iex> Helpers.add_pending_tool(tool)
%Jido.Agent.StateOp.SetState{attrs: %{pending_tool_calls: [%{id: "call_1", name: "search", arguments: %{query: "test"}}]}}
@spec append_conversation([map()]) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to append a message to the conversation.
Examples
iex> message = %{role: :user, content: "Hello"}
iex> Helpers.append_conversation([message])
%Jido.Agent.StateOp.SetState{attrs: %{conversation: [%{role: :user, content: "Hello"}]}}
@spec append_streaming_text(String.t()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to append to the streaming text.
Examples
iex> Helpers.append_streaming_text(" world")
%Jido.Agent.StateOp.SetPath{path: [:streaming_text], value: " world"}
Applies state operations to a state map.
This is useful for strategies to apply state operations internally before setting the strategy state on the agent.
Examples
iex> ops = [Jido.Agent.StateOp.set_path([:status], :running)]
iex> Helpers.apply_to_state(%{iteration: 1}, ops)
%{iteration: 1, status: :running}
@spec clear_call_id() :: Jido.Agent.StateOp.DeletePath.t()
Creates a StateOp to clear the current LLM call ID.
Examples
iex> Helpers.clear_call_id()
%Jido.Agent.StateOp.DeletePath{path: [:current_llm_call_id]}
@spec clear_pending_tools() :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to clear pending tool calls.
Examples
iex> Helpers.clear_pending_tools()
%Jido.Agent.StateOp.SetState{attrs: %{pending_tool_calls: []}}
Composes multiple state operations into a single list.
This is a convenience function for building state operation lists.
Examples
iex> Helpers.compose([
...> Helpers.set_iteration_status(:running),
...> Helpers.set_iteration(1)
...> ])
[%Jido.Agent.StateOp.SetPath{path: [:status], value: :running}, %Jido.Agent.StateOp.SetPath{path: [:iteration], value: 1}]
@spec delete_keys([atom()]) :: Jido.Agent.StateOp.DeleteKeys.t()
Creates a StateOp to delete specific keys from strategy state.
Examples
iex> Helpers.delete_keys([:temp1, :temp2])
%Jido.Agent.StateOp.DeleteKeys{keys: [:temp1, :temp2]}
@spec delete_temp_keys() :: Jido.Agent.StateOp.DeleteKeys.t()
Creates a StateOp to delete temporary keys from strategy state.
Examples
iex> Helpers.delete_temp_keys()
%Jido.Agent.StateOp.DeleteKeys{keys: [:temp, :cache, :ephemeral]}
@spec execute_action_instruction(Jido.Agent.t(), Jido.Instruction.t(), strategy_ctx()) :: {Jido.Agent.t(), [struct()]}
Executes a non-strategy Jido.Action instruction using direct strategy semantics.
This is used as a fallback path in strategy adapters so plugin-routed action modules can run even when the strategy does not have a dedicated command atom.
@spec maybe_execute_action_instruction( Jido.Agent.t(), Jido.Instruction.t(), strategy_ctx() ) :: {Jido.Agent.t(), [struct()]} | :noop
Executes an instruction if its action is a module implementing run/2.
Returns :noop when the action is not an executable module.
@spec prepend_conversation(map(), [map()]) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to prepend a message to the conversation.
Examples
iex> message = %{role: :user, content: "Hello"}
iex> current_conversation = [%{role: :assistant, content: "Hi"}]
iex> Helpers.prepend_conversation(message, current_conversation)
%Jido.Agent.StateOp.SetState{attrs: %{conversation: [%{role: :user, content: "Hello"}, %{role: :assistant, content: "Hi"}]}}
@spec remove_pending_tool(String.t()) :: Jido.Agent.StateOp.DeletePath.t()
Creates a StateOp to remove a specific pending tool by ID.
Examples
iex> Helpers.remove_pending_tool("call_1")
%Jido.Agent.StateOp.DeletePath{path: [:pending_tool_calls, "call_1"]}Note: This operation is meant for map-based pending_tool_calls. For list-based pending_tool_calls, use filter_pending_tools/1 instead.
@spec reset_strategy_state() :: Jido.Agent.StateOp.ReplaceState.t()
Creates a StateOp to reset the strategy state to initial values.
Examples
iex> result = Helpers.reset_strategy_state()
iex> result.state.status == :idle and result.state.iteration == 0
true
@spec set_call_id(String.t()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set the current LLM call ID.
Examples
iex> Helpers.set_call_id("call_123")
%Jido.Agent.StateOp.SetPath{path: [:current_llm_call_id], value: "call_123"}
@spec set_config_field(atom(), term()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set a specific config field.
Examples
iex> Helpers.set_config_field(:tools, [MyAction])
%Jido.Agent.StateOp.SetPath{path: [:config, :tools], value: [MyAction]}
@spec set_conversation([map()]) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to set the entire conversation.
Examples
iex> messages = [%{role: :user, content: "Hello"}, %{role: :assistant, content: "Hi"}]
iex> Helpers.set_conversation(messages)
%Jido.Agent.StateOp.SetState{attrs: %{conversation: messages}}
@spec set_final_answer(String.t()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set the final answer.
Examples
iex> Helpers.set_final_answer("42")
%Jido.Agent.StateOp.SetPath{path: [:final_answer], value: "42"}
@spec set_iteration(non_neg_integer()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to increment the iteration counter.
Note: This cannot directly read the current value, so it should be used with the current iteration value known from context.
Examples
iex> Helpers.set_iteration(5)
%Jido.Agent.StateOp.SetPath{path: [:iteration], value: 5}
@spec set_iteration_status(atom()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set the iteration status.
Examples
iex> Helpers.set_iteration_status(:awaiting_llm)
%Jido.Agent.StateOp.SetPath{path: [:status], value: :awaiting_llm}
@spec set_pending_tools([map()]) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to set pending tool calls.
Examples
iex> tools = [%{id: "call_1", name: "search", arguments: %{query: "test"}}]
iex> Helpers.set_pending_tools(tools)
%Jido.Agent.StateOp.SetState{attrs: %{pending_tool_calls: tools}}
@spec set_strategy_field(atom(), term()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set a specific field in the strategy state.
Examples
iex> Helpers.set_strategy_field(:status, :running)
%Jido.Agent.StateOp.SetPath{path: [:status], value: :running}
@spec set_streaming_text(String.t()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set the streaming text.
Examples
iex> Helpers.set_streaming_text("Hello")
%Jido.Agent.StateOp.SetPath{path: [:streaming_text], value: "Hello"}
@spec set_termination_reason(atom()) :: Jido.Agent.StateOp.SetPath.t()
Creates a StateOp to set the termination reason.
Examples
iex> Helpers.set_termination_reason(:final_answer)
%Jido.Agent.StateOp.SetPath{path: [:termination_reason], value: :final_answer}
@spec set_usage(map()) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to set the usage metadata.
Examples
iex> usage = %{input_tokens: 10, output_tokens: 20}
iex> Helpers.set_usage(usage)
%Jido.Agent.StateOp.SetState{attrs: %{usage: usage}}
@spec update_config(map()) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to update the config field in strategy state.
Examples
iex> config = %{tools: [], model: "test"}
iex> Helpers.update_config(config)
%Jido.Agent.StateOp.SetState{attrs: %{config: config}}
@spec update_config_fields(map()) :: [Jido.Agent.StateOp.SetPath.t()]
Creates StateOps to update multiple config fields at once.
Examples
iex> ops = Helpers.update_config_fields(%{tools: [], model: "test"})
iex> length(ops)
2
iex> hd(ops).path
[:config, :tools]
@spec update_strategy_state(map()) :: Jido.Agent.StateOp.SetState.t()
Creates a StateOp to update the strategy state.
Performs a deep merge of the given attributes into the strategy state.
Examples
iex> Helpers.update_strategy_state(%{status: :running, iteration: 1})
%Jido.Agent.StateOp.SetState{attrs: %{status: :running, iteration: 1}}
@spec update_tools_config([module()], %{required(String.t()) => module()}, [map()]) :: [ Jido.Agent.StateOp.SetPath.t() ]
Creates StateOps to update tools, actions_by_name, and reqllm_tools together.
This is a common pattern when registering/unregistering tools.
Examples
iex> tools = [SomeAction]
iex> actions_by_name = %{"action" => SomeAction}
iex> reqllm_tools = [%{name: "action"}]
iex> ops = Helpers.update_tools_config(tools, actions_by_name, reqllm_tools)
iex> length(ops)
3
iex> hd(ops).path
[:config, :tools]