Class: Ralph::Iteration
- Inherits:
-
Object
- Object
- Ralph::Iteration
- Includes:
- Helpers
- Defined in:
- lib/ralph/iteration.rb
Defined Under Namespace
Classes: Result
Instance Attribute Summary collapse
-
#iteration_start ⇒ Object
readonly
Returns the value of attribute iteration_start.
-
#struggle_indicators ⇒ Object
readonly
Returns the value of attribute struggle_indicators.
Instance Method Summary collapse
- #context_at_start ⇒ Object
-
#handle_iteration_error(error, iteration_start) ⇒ Object
———- Warnings and error detection ———-.
-
#initialize(loop_context) ⇒ Iteration
constructor
A new instance of Iteration.
- #run ⇒ Object
-
#struggling? ⇒ Boolean
Returns true when the agent appears to be stuck.
Methods included from Helpers
#check_completion, #escape_regex, #format_duration, #format_duration_long, #format_tool_summary, #now_ms, #strip_ansi, #which
Constructor Details
#initialize(loop_context) ⇒ Iteration
Returns a new instance of Iteration.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/ralph/iteration.rb', line 42 def initialize(loop_context) @loop = loop_context @config = @loop.config @agent = @loop.agent @state = @loop.state @struggle_indicators = @loop.struggle_indicators # Streaming configuration @compact_tools = !@config.verbose_tools @tool_summary_interval_ms = 3000 @heartbeat_interval_ms = 10_000 @stream_tool_counts = Hash.new(0) @mutex = Mutex.new @timing = { last_printed_at: now_ms, last_activity_at: now_ms } @last_tool_summary_at = 0 @iteration_start = now_ms end |
Instance Attribute Details
#iteration_start ⇒ Object (readonly)
Returns the value of attribute iteration_start.
40 41 42 |
# File 'lib/ralph/iteration.rb', line 40 def iteration_start @iteration_start end |
#struggle_indicators ⇒ Object (readonly)
Returns the value of attribute struggle_indicators.
40 41 42 |
# File 'lib/ralph/iteration.rb', line 40 def struggle_indicators @struggle_indicators end |
Instance Method Details
#context_at_start ⇒ Object
62 |
# File 'lib/ralph/iteration.rb', line 62 def context_at_start = @_context_at_start ||= @loop.context |
#handle_iteration_error(error, iteration_start) ⇒ Object
———- Warnings and error detection ———-
147 148 |
# File 'lib/ralph/iteration.rb', line 147 def handle_iteration_error(error, iteration_start) end |
#run ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/ralph/iteration.rb', line 64 def run snapshot_before = Git::FileSnapshot.capture if @config.stream_output heartbeat = Threads::Heartbeat.new(iteration_start, @heartbeat_interval_ms, @timing, @mutex) end @agent.execute( @loop.prompt.build_iteration(@state, @agent), on_line: method(:handle_line), model: @config.model, stream_output: @config.stream_output, disable_plugins: @config.disable_plugins, allow_all_permissions: @config., ).then do |agent_result| heartbeat&.stop if @config.stream_output @mutex.synchronize { maybe_print_tool_summary(force: true) } end unless @config.stream_output if agent_result warn agent_result.stderr_text unless agent_result.stderr_text.empty? puts agent_result.stdout_text end end snapshot_after = Git::FileSnapshot.capture combined_output = agent_result.combined_output completion_detected = check_completion(combined_output, @config.completion_promise) fatal_error = @agent.detect_fatal_error(combined_output) status = ( if fatal_error :fatal elsif agent_result.exit_code != 0 :failed elsif completion_detected :completed else :continuing end ) Result.new( status: status, agent_result: agent_result, duration_ms: now_ms - iteration_start, files_modified: snapshot_before.modified_since(snapshot_after), completion_detected: completion_detected, errors: @agent.extract_errors(combined_output) ).tap do |result| update_struggle_indicators(result) end end rescue StandardError => error if @config.current_pid begin Process.kill('TERM', @config.current_pid) rescue StandardError # process may have exited end @config.current_pid = nil end Output::Iteration::Error.call(@loop, error) sleep 2 Result.new( status: :error, agent_result: nil, duration_ms: now_ms - (iteration_start || now_ms), # this is so fucking wrong files_modified: [], completion_detected: false, errors: [error.] ) end |
#struggling? ⇒ Boolean
Returns true when the agent appears to be stuck. Should only be called after iteration > 2 for meaningful results.
152 153 154 155 |
# File 'lib/ralph/iteration.rb', line 152 def struggling? @struggle_indicators[:no_progress_iterations] >= 3 || @struggle_indicators[:short_iterations] >= 3 end |