Class: AgentRuntime::Agent

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

Overview

Simple agent implementation with step-by-step execution and multi-step loops.

This class provides a straightforward agent implementation that executes planning, validation, and execution steps in a loop until termination. Use this for simpler workflows where you don’t need the full FSM structure.

Examples:

Single step execution

agent = AgentRuntime::Agent.new(planner: planner, policy: policy, executor: executor, state: state)
result = agent.step(input: "What is 2+2?")

Multi-step agentic workflow

agent = AgentRuntime::Agent.new(planner: planner, policy: policy, executor: executor, state: state)
result = agent.run(initial_input: "Find the weather and send an email")

Instance Method Summary collapse

Constructor Details

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

Initialize a new Agent instance.



26
27
28
29
30
31
32
33
# File 'lib/agent_runtime/agent.rb', line 26

def initialize(planner:, policy:, executor:, state:, audit_log: nil, max_iterations: 50)
  @planner = planner
  @policy = policy
  @executor = executor
  @state = state
  @audit_log = audit_log
  @max_iterations = max_iterations
end

Instance Method Details

#run(initial_input:, input_builder: nil) ⇒ Hash

Agentic workflow loop (runs until termination).

Use this for multi-step workflows where the agent decides when to stop. The loop continues until:

  • The decision action is “finish”

  • The result contains ‘done: true`

  • Maximum iterations are exceeded

Examples:

result = agent.run(initial_input: "Find weather and send email")
# => { done: true, iterations: 3, ... }

With custom input builder

builder = ->(result, iteration) { "Iteration #{iteration}: #{result.inspect}" }
result = agent.run(initial_input: "Start", input_builder: builder)

Raises:



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/agent_runtime/agent.rb', line 92

def run(initial_input:, input_builder: nil)
  iteration = 0
  current_input = initial_input
  final_result = nil

  loop do
    iteration += 1

    raise MaxIterationsExceeded, "Max iterations (#{@max_iterations}) exceeded" if iteration > @max_iterations

    decision = @planner.plan(
      input: current_input,
      state: @state.snapshot
    )

    @policy.validate!(decision, state: @state)

    result = @executor.execute(decision, state: @state)

    @state.apply!(result)

    @audit_log&.record(
      input: current_input,
      decision: decision,
      result: result
    )

    # Always set final_result before checking termination
    final_result = result

    break if terminated?(decision, result)

    current_input = input_builder ? input_builder.call(result, iteration) : build_next_input(result, iteration)
  end

  final_result || { done: true, iterations: iteration }
end

#step(input:) ⇒ Hash

Single step execution (non-agentic).

Use this for one-shot decisions or when you control the loop externally. This method performs a single planning, validation, execution, and state update cycle.

Examples:

result = agent.step(input: "Calculate 5 * 10")
# => { result: 50 }

Raises:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/agent_runtime/agent.rb', line 48

def step(input:)
  decision = @planner.plan(
    input: input,
    state: @state.snapshot
  )

  @policy.validate!(decision, state: @state)

  result = @executor.execute(decision, state: @state)

  @state.apply!(result)

  @audit_log&.record(
    input: input,
    decision: decision,
    result: result
  )

  result
end