Class: AgentRuntime::FSM
- Inherits:
-
Object
- Object
- AgentRuntime::FSM
- Defined in:
- lib/agent_runtime/fsm.rb
Overview
Formal Finite State Machine for agentic workflows.
Implements the canonical agentic workflow FSM 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)
Valid state transitions:
-
INTAKE → PLAN
-
PLAN → DECIDE | HALT
-
DECIDE → EXECUTE | FINALIZE | HALT
-
EXECUTE → OBSERVE | FINALIZE | HALT
-
OBSERVE → LOOP_CHECK
-
LOOP_CHECK → EXECUTE | FINALIZE | HALT
-
FINALIZE → (terminal)
-
HALT → (terminal)
Constant Summary collapse
- STATES =
State constants mapping state names to integer values.
{ INTAKE: 0, PLAN: 1, DECIDE: 2, EXECUTE: 3, OBSERVE: 4, LOOP_CHECK: 5, FINALIZE: 6, HALT: 7 }.freeze
- TERMINAL_STATES =
Terminal states that cannot transition to other states.
[STATES[:FINALIZE], STATES[:HALT]].freeze
- VALID_TRANSITIONS =
Valid state transitions based on FSM specification.
Maps each state to an array of valid next states.
{ STATES[:INTAKE] => [STATES[:PLAN]], STATES[:PLAN] => [STATES[:DECIDE], STATES[:HALT]], STATES[:DECIDE] => [STATES[:EXECUTE], STATES[:FINALIZE], STATES[:HALT]], STATES[:EXECUTE] => [STATES[:OBSERVE], STATES[:FINALIZE], STATES[:HALT]], STATES[:OBSERVE] => [STATES[:LOOP_CHECK]], STATES[:LOOP_CHECK] => [STATES[:EXECUTE], STATES[:FINALIZE], STATES[:HALT]], STATES[:FINALIZE] => [], STATES[:HALT] => [] }.freeze
Instance Attribute Summary collapse
-
#history ⇒ Object
readonly
Returns the value of attribute history.
-
#iteration_count ⇒ Integer
readonly
Current iteration count.
-
#state ⇒ Integer
readonly
Current state value.
Instance Method Summary collapse
-
#decide? ⇒ Boolean
Check if current state is DECIDE.
-
#execute? ⇒ Boolean
Check if current state is EXECUTE.
-
#finalize? ⇒ Boolean
Check if current state is FINALIZE.
-
#halt? ⇒ Boolean
Check if current state is HALT.
-
#increment_iteration ⇒ void
Increment the iteration count.
-
#initialize(max_iterations: 50) ⇒ FSM
constructor
Initialize a new FSM instance.
-
#intake? ⇒ Boolean
Check if current state is INTAKE.
-
#loop_check? ⇒ Boolean
Check if current state is LOOP_CHECK.
-
#observe? ⇒ Boolean
Check if current state is OBSERVE.
-
#plan? ⇒ Boolean
Check if current state is PLAN.
-
#reset ⇒ void
Reset the FSM to initial state.
-
#state_name ⇒ Symbol, String
Get the name of the current state.
-
#state_name_for(state_value) ⇒ Symbol, String
Get the name for a state value.
-
#terminal? ⇒ Boolean
Check if current state is terminal (FINALIZE or HALT).
-
#transition_to(new_state, reason: nil) ⇒ void
Transition to a new state.
-
#validate_transition(from, to) ⇒ void
Validate a state transition.
Constructor Details
Instance Attribute Details
#history ⇒ Object (readonly)
Returns the value of attribute history.
84 |
# File 'lib/agent_runtime/fsm.rb', line 84 attr_reader :state, :iteration_count, :history |
#iteration_count ⇒ Integer (readonly)
84 |
# File 'lib/agent_runtime/fsm.rb', line 84 attr_reader :state, :iteration_count, :history |
#state ⇒ Integer (readonly)
84 85 86 |
# File 'lib/agent_runtime/fsm.rb', line 84 def state @state end |
Instance Method Details
#decide? ⇒ Boolean
Check if current state is DECIDE.
103 104 105 |
# File 'lib/agent_runtime/fsm.rb', line 103 def decide? @state == STATES[:DECIDE] end |
#execute? ⇒ Boolean
Check if current state is EXECUTE.
110 111 112 |
# File 'lib/agent_runtime/fsm.rb', line 110 def execute? @state == STATES[:EXECUTE] end |
#finalize? ⇒ Boolean
Check if current state is FINALIZE.
131 132 133 |
# File 'lib/agent_runtime/fsm.rb', line 131 def finalize? @state == STATES[:FINALIZE] end |
#halt? ⇒ Boolean
Check if current state is HALT.
138 139 140 |
# File 'lib/agent_runtime/fsm.rb', line 138 def halt? @state == STATES[:HALT] end |
#increment_iteration ⇒ void
This method returns an undefined value.
Increment the iteration count.
170 171 172 173 |
# File 'lib/agent_runtime/fsm.rb', line 170 def increment_iteration @iteration_count += 1 raise MaxIterationsExceeded, "Max iterations (#{@max_iterations}) exceeded" if @iteration_count > @max_iterations end |
#intake? ⇒ Boolean
Check if current state is INTAKE.
89 90 91 |
# File 'lib/agent_runtime/fsm.rb', line 89 def intake? @state == STATES[:INTAKE] end |
#loop_check? ⇒ Boolean
Check if current state is LOOP_CHECK.
124 125 126 |
# File 'lib/agent_runtime/fsm.rb', line 124 def loop_check? @state == STATES[:LOOP_CHECK] end |
#observe? ⇒ Boolean
Check if current state is OBSERVE.
117 118 119 |
# File 'lib/agent_runtime/fsm.rb', line 117 def observe? @state == STATES[:OBSERVE] end |
#plan? ⇒ Boolean
Check if current state is PLAN.
96 97 98 |
# File 'lib/agent_runtime/fsm.rb', line 96 def plan? @state == STATES[:PLAN] end |
#reset ⇒ void
This method returns an undefined value.
Reset the FSM to initial state.
Resets state to INTAKE, clears iteration count and history.
180 181 182 183 184 |
# File 'lib/agent_runtime/fsm.rb', line 180 def reset @state = STATES[:INTAKE] @iteration_count = 0 @history = [] end |
#state_name ⇒ Symbol, String
Get the name of the current state.
189 190 191 |
# File 'lib/agent_runtime/fsm.rb', line 189 def state_name STATES.key(@state) || "UNKNOWN" end |
#state_name_for(state_value) ⇒ Symbol, String
Get the name for a state value.
209 210 211 |
# File 'lib/agent_runtime/fsm.rb', line 209 def state_name_for(state_value) STATES.key(state_value) || "UNKNOWN" end |
#terminal? ⇒ Boolean
Check if current state is terminal (FINALIZE or HALT).
145 146 147 |
# File 'lib/agent_runtime/fsm.rb', line 145 def terminal? TERMINAL_STATES.include?(@state) end |
#transition_to(new_state, reason: nil) ⇒ void
This method returns an undefined value.
Transition to a new state.
Validates the transition and records it in history.
160 161 162 163 164 |
# File 'lib/agent_runtime/fsm.rb', line 160 def transition_to(new_state, reason: nil) validate_transition(@state, new_state) @history << { from: @state, to: new_state, reason: reason, iteration: @iteration_count } @state = new_state end |
#validate_transition(from, to) ⇒ void
This method returns an undefined value.
Validate a state transition.
199 200 201 202 203 |
# File 'lib/agent_runtime/fsm.rb', line 199 def validate_transition(from, to) return if VALID_TRANSITIONS[from]&.include?(to) raise ExecutionError, "Invalid transition from #{state_name_for(from)} to #{state_name_for(to)}" end |