Jido.AI.ToTAgent (Jido AI v2.2.0)

Copy Markdown View Source

Base macro for Tree-of-Thoughts-powered agents.

Wraps use Jido.Agent with Jido.AI.Reasoning.TreeOfThoughts.Strategy wired in, plus standard state fields and helper functions.

Usage

defmodule MyApp.PuzzleSolver do
  use Jido.AI.ToTAgent,
    name: "puzzle_solver",
    description: "Solves complex puzzles using tree exploration",
    branching_factor: 4,
    max_depth: 5,
    traversal_strategy: :best_first
end

Options

  • :name (required) - Agent name
  • :description - Agent description (default: "ToT agent #{name}")
  • :model - Model alias or direct model spec (default: :fast, resolved via Jido.AI.resolve_model/1)
  • :branching_factor, :max_depth, :traversal_strategy - Core tree exploration knobs
  • :top_k, :min_depth, :max_nodes, :max_duration_ms, :beam_width - Search budget and shaping knobs
  • :early_success_threshold, :convergence_window, :min_score_improvement, :max_parse_retries - Deterministic stopping/parser controls
  • :tools, :tool_context, :tool_timeout_ms, :tool_max_retries, :tool_retry_backoff_ms, :max_tool_round_trips - Tool orchestration controls
  • :effect_policy, :strategy_effect_policy - Effect policy controls (strategy may only narrow)
  • :generation_prompt - Custom prompt for thought generation
  • :evaluation_prompt - Custom prompt for thought evaluation
  • :skills - Additional skills to attach to the agent (TaskSupervisorSkill is auto-included)

Generated Functions

  • explore/2,3 - Async: sends prompt, returns {:ok, %Request{}} for later awaiting
  • await/1,2 - Awaits a specific request's completion
  • explore_sync/2,3 - Sync convenience: sends prompt and waits for result
  • on_before_cmd/2 - Captures request in state before processing
  • on_after_cmd/3 - Updates request result when done
  • best_answer/1, top_candidates/2, result_summary/1 - Structured result helpers

Request Tracking

Each explore/2 call returns a Request struct that can be awaited:

{:ok, request} = MyAgent.explore(pid, "Solve the 8-puzzle")
{:ok, result} = MyAgent.await(request, timeout: 30_000)

Or use the synchronous convenience wrapper:

{:ok, result} = MyAgent.explore_sync(pid, "Solve the 8-puzzle")

State Fields

The agent state includes:

  • :model - The LLM model being used
  • :requests - Map of request_id => request state (for concurrent tracking)
  • :last_request_id - ID of the most recent request
  • :last_prompt - The most recent prompt (backward compat)
  • :last_result - The final result from the last completed exploration (backward compat)
  • :completed - Boolean indicating if the last exploration is complete (backward compat)

Structured Result Contract

explore_sync/3 (and awaited async requests) resolve to a structured map:

  • best - best-ranked candidate
  • candidates - ranked candidate list
  • termination - reason/status/depth/node-count/duration metadata
  • tree - search topology metadata
  • usage - LLM usage metadata
  • diagnostics - parser/tool-round/convergence diagnostics

Task Supervisor

Each agent instance gets its own Task.Supervisor automatically started via the Jido.AI.Plugins.TaskSupervisor. This supervisor is used for:

  • LLM streaming operations
  • Other async operations within the agent's lifecycle

Example

{:ok, pid} = Jido.AgentServer.start(agent: MyApp.PuzzleSolver)

# Async pattern (preferred for concurrent requests)
{:ok, request} = MyApp.PuzzleSolver.explore(pid, "Solve the 8-puzzle: [2,8,3,1,6,4,7,_,5]")
{:ok, result} = MyApp.PuzzleSolver.await(request)

# Sync pattern (convenience for simple cases)
{:ok, result} = MyApp.PuzzleSolver.explore_sync(pid, "Solve the 8-puzzle: [2,8,3,1,6,4,7,_,5]")

Traversal Strategies

  • :bfs - Breadth-first search: explores all nodes at current depth before going deeper
  • :dfs - Depth-first search: explores deeply before backtracking
  • :best_first - Explores highest-scored nodes first (default)