Class: AgentRuntime::AgentFSM

Inherits:
Object
  • Object
show all
Defined in:
lib/agent_runtime/agent_fsm.rb

Overview

Agentic workflow implementation using formal FSM.

Maps directly to the canonical agentic workflow specification with 8 states:

  • INTAKE: Normalize input, initialize state

  • PLAN: Single-shot planning using /generate

  • DECIDE: Make bounded decision (continue vs stop)

  • EXECUTE: LLM proposes next actions using /chat (looping state)

  • OBSERVE: Execute tools, inject real-world results

  • LOOP_CHECK: Control continuation

  • FINALIZE: Produce terminal output (terminal state)

  • HALT: Abort safely (terminal state)

This implementation provides a complete agentic workflow with explicit state transitions, tool execution, and audit logging.

Examples:

Basic usage

agent_fsm = AgentFSM.new(
  planner: planner,
  policy: policy,
  executor: executor,
  state: state,
  tool_registry: tools
)
result = agent_fsm.run(initial_input: "Analyze this data")

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(planner:, policy:, executor:, state:, tool_registry:, audit_log: nil, max_iterations: 50) ⇒ AgentFSM

Initialize a new AgentFSM instance.

Parameters:

  • planner (Planner)

    The planner for generating plans and chat responses

  • policy (Policy)

    The policy validator for decisions

  • executor (Executor)

    The executor for tool calls (currently unused, tools called directly)

  • state (State)

    The state manager for agent state

  • tool_registry (ToolRegistry)

    The registry containing available tools

  • audit_log (AuditLog, nil) (defaults to: nil)

    Optional audit logger for recording decisions

  • max_iterations (Integer) (defaults to: 50)

    Maximum number of iterations before raising an error (default: 50)



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/agent_runtime/agent_fsm.rb', line 44

def initialize(planner:, policy:, executor:, state:, tool_registry:, audit_log: nil, max_iterations: 50)
  @planner = planner
  @policy = policy
  @executor = executor
  @state = state
  @tool_registry = tool_registry
  @audit_log = audit_log
  @fsm = FSM.new(max_iterations: max_iterations)
  @messages = []
  @plan = nil
  @decision = nil
end

Instance Attribute Details

#decisionObject (readonly)

Returns the value of attribute decision.



115
# File 'lib/agent_runtime/agent_fsm.rb', line 115

attr_reader :fsm, :messages, :plan, :decision

#fsmFSM (readonly)

Returns The finite state machine instance.

Returns:

  • (FSM)

    The finite state machine instance



115
116
117
# File 'lib/agent_runtime/agent_fsm.rb', line 115

def fsm
  @fsm
end

#messagesArray<Hash> (readonly)

Returns Array of message hashes with :role and :content.

Returns:

  • (Array<Hash>)

    Array of message hashes with :role and :content



115
# File 'lib/agent_runtime/agent_fsm.rb', line 115

attr_reader :fsm, :messages, :plan, :decision

#planHash? (readonly)

Returns The plan hash with :goal, :required_capabilities, :initial_steps.

Returns:

  • (Hash, nil)

    The plan hash with :goal, :required_capabilities, :initial_steps



115
# File 'lib/agent_runtime/agent_fsm.rb', line 115

attr_reader :fsm, :messages, :plan, :decision

Instance Method Details

#run(initial_input:) ⇒ Hash

Run the complete agentic workflow from INTAKE to FINALIZE/HALT.

Executes the full FSM workflow, transitioning through all states until reaching a terminal state (FINALIZE or HALT). The workflow handles planning, decision-making, tool execution, and observation in a structured loop.

Examples:

result = agent_fsm.run(initial_input: "Find weather and send email")
# => { done: true, iterations: 3, state: {...}, fsm_history: [...] }

Parameters:

  • initial_input (String)

    The initial input to start the workflow

Returns:

  • (Hash)

    Final result hash containing:

    • done: Boolean indicating completion status

    • iterations: Number of iterations executed

    • state: Final state snapshot

    • fsm_history: Array of state transition history

    • final_message: Optional final message content (if FINALIZE)

    • error: Error reason (if HALT)

Raises:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/agent_runtime/agent_fsm.rb', line 77

def run(initial_input:)
  @fsm.reset
  @messages = []
  @plan = nil
  @decision = nil

  loop do
    case @fsm.state_name
    when :INTAKE
      handle_intake(initial_input)
    when :PLAN
      handle_plan
    when :DECIDE
      handle_decide
    when :EXECUTE
      handle_execute
    when :OBSERVE
      handle_observe
    when :LOOP_CHECK
      handle_loop_check
    when :FINALIZE
      return handle_finalize
    when :HALT
      return handle_halt
    end

    break if @fsm.terminal?
  end
end