Adapts Jido Actions into ReqLLM.Tool structs for LLM consumption.
This module bridges Jido domain concepts (actions with schemas) to ReqLLM's tool representation.
Design
- Schema-focused: Tools use a noop callback; Jido owns execution via
Directive.ToolExec - Adapter pattern: Converts
Jido.Actionbehaviour →ReqLLM.Toolstruct - Single source of truth: All action→tool conversion goes through this module
Usage
# Convert action modules to ReqLLM tools
tools = Jido.AI.ToolAdapter.from_actions([
MyApp.Actions.Calculator,
MyApp.Actions.Search
])
# With options
tools = Jido.AI.ToolAdapter.from_actions(actions,
prefix: "myapp_",
filter: fn mod -> mod.category() == :search end
)
# Use in LLM call
ReqLLM.stream_text(model, messages, tools: tools)
Summary
Functions
Converts a single Jido.Action module into a ReqLLM.Tool struct.
Converts a list of Jido.Action modules into ReqLLM.Tool structs.
Looks up an action module by tool name from a list of action modules.
Normalizes tool input into an action lookup map (%{name => module}).
Validates that all modules in the list implement the Jido.Action behaviour.
Functions
@spec from_action( module(), keyword() ) :: ReqLLM.Tool.t()
Converts a single Jido.Action module into a ReqLLM.Tool struct.
Arguments
action_module- A module implementing theJido.Actionbehaviouropts- Optional keyword list of options
Options
:prefix- String prefix to add to the tool name (e.g.,"myapp_"):strict- Whether to enable strict mode on the tool. When not set, auto-detects based on the action'sstrict?/0callback (defaults tofalse).
Returns
A ReqLLM.Tool struct
Example
tool = Jido.AI.ToolAdapter.from_action(MyApp.Actions.Calculator, prefix: "v2_")
# => %ReqLLM.Tool{name: "v2_calculator", ...}
@spec from_actions( [module()], keyword() ) :: [ReqLLM.Tool.t()]
Converts a list of Jido.Action modules into ReqLLM.Tool structs.
The returned tools use a noop callback—they're purely for describing available
actions to the LLM. Actual execution happens via Jido.AI.Directive.ToolExec.
Arguments
action_modules- List of modules implementing theJido.Actionbehaviouropts- Optional keyword list of options
Options
:prefix- String prefix to add to all tool names (e.g.,"myapp_"):filter- Function(module -> boolean)to filter which actions to include:strict- Whether to enable strict mode on the tools. When not set, auto-detects based on each action'sstrict?/0callback (defaults tofalse).
Returns
A list of ReqLLM.Tool structs
Examples
# Basic usage
tools = Jido.AI.ToolAdapter.from_actions([MyApp.Actions.Add, MyApp.Actions.Search])
# With prefix
tools = Jido.AI.ToolAdapter.from_actions(actions, prefix: "calc_")
# Tool names become "calc_add", "calc_search", etc.
# With filter
tools = Jido.AI.ToolAdapter.from_actions(actions,
filter: fn mod -> mod.category() == :math end
)
Looks up an action module by tool name from a list of action modules.
Useful for finding which action module corresponds to a tool name returned by an LLM.
Arguments
tool_name- The name of the tool to look upaction_modules- List of action modules to search
Returns
{:ok, module}- If found{:error, :not_found}- If no action module has that tool name
Example
{:ok, module} = ToolAdapter.lookup_action("calculator", [Calculator, Search])
# => {:ok, Calculator}
{:error, :not_found} = ToolAdapter.lookup_action("unknown", [Calculator])
# => {:error, :not_found}
Normalizes tool input into an action lookup map (%{name => module}).
Accepts any of the common tool container shapes used by actions/skills:
nil->%{}%{"tool_name" => MyAction}-> unchanged%{tool_name: MyAction}->%{"tool_name" => MyAction}when values are modules[MyAction, OtherAction]->%{"my_action" => MyAction, "other_action" => OtherAction}MyAction->%{"my_action" => MyAction}
Validates that all modules in the list implement the Jido.Action behaviour.
Returns :ok if all modules are valid, or {:error, {:invalid_action, module, reason}}
for the first invalid module found.
Example
:ok = ToolAdapter.validate_actions([Calculator, Search])
{:error, {:invalid_action, BadModule, :missing_name}} = ToolAdapter.validate_actions([BadModule])