Jido.AI.Reasoning.ChainOfThought.Machine
(Jido AI v2.1.0)
View Source
Pure state machine for the Chain-of-Thought (CoT) reasoning pattern.
This module implements state transitions for a CoT agent without any side effects. It uses Fsmx for state machine management and returns directives that describe what external effects should be performed.
Overview
Chain-of-Thought prompting encourages LLMs to break down complex problems into intermediate steps before providing a final answer. This leads to better reasoning on multi-step problems like math, logic, and common sense reasoning.
States
:idle- Initial state, waiting for a prompt:reasoning- Waiting for LLM response with reasoning:completed- Final state, reasoning complete:error- Error state
Usage
The machine is used by the CoT strategy:
machine = Machine.new()
{machine, directives} = Machine.update(machine, {:start, prompt, call_id}, env)All state transitions are pure - side effects are described in directives.
Status Type Boundary
Internal (Machine struct): Status is stored as strings ("idle", "completed")
due to Fsmx library requirements.
External (Strategy state, Snapshots): Status is converted to atoms (:idle,
:completed) via to_map/1 before storage in agent state.
Never compare machine.status directly with atoms - use Machine.to_map/1 first.
Summary
Types
External status (atom) - used in strategy state after to_map/1 conversion
Internal machine status (string) - required by Fsmx library
Functions
Returns the default CoT system prompt.
Extracts reasoning steps and conclusion from LLM response text.
Creates a machine from a map (e.g., from strategy state storage).
Generates a unique call ID for LLM requests.
Creates a new machine in the idle state.
Converts the machine state to a map suitable for strategy state storage.
Updates the machine state based on a message.
Types
@type external_status() :: :idle | :reasoning | :completed | :error
External status (atom) - used in strategy state after to_map/1 conversion
@type internal_status() :: String.t()
Internal machine status (string) - required by Fsmx library
@type step() :: %{number: pos_integer(), content: String.t()}
@type t() :: %Jido.AI.Reasoning.ChainOfThought.Machine{ conclusion: String.t() | nil, current_call_id: String.t() | nil, prompt: String.t() | nil, raw_response: String.t() | nil, result: term(), started_at: integer() | nil, status: internal_status(), steps: [step()], streaming_text: String.t(), termination_reason: termination_reason(), usage: usage() }
@type termination_reason() :: :success | :error | nil
@type usage() :: %{ optional(:input_tokens) => non_neg_integer(), optional(:output_tokens) => non_neg_integer(), optional(:total_tokens) => non_neg_integer() }
Functions
@spec default_system_prompt() :: String.t()
Returns the default CoT system prompt.
Extracts reasoning steps and conclusion from LLM response text.
Supports multiple formats:
- Numbered steps: "Step 1:", "1.", "1)"
- Bullet points: "- ", "* ", "• "
- Conclusion markers: "Conclusion:", "Answer:", "Therefore:", "Final Answer:"
Returns {steps, conclusion} where steps is a list of step maps and
conclusion is the final answer string or nil.
Creates a machine from a map (e.g., from strategy state storage).
@spec generate_call_id() :: String.t()
Generates a unique call ID for LLM requests.
@spec new() :: t()
Creates a new machine in the idle state.
Converts the machine state to a map suitable for strategy state storage.
Updates the machine state based on a message.
Returns the updated machine and a list of directives describing external effects to be performed.
Messages
{:start, prompt, call_id}- Start CoT reasoning{:llm_result, call_id, result}- Handle LLM response{:llm_partial, call_id, delta, chunk_type}- Handle streaming chunk
Directives
{:call_llm_stream, id, context}- Request LLM call with CoT prompt