Class: RobotLab::To::Orchestrator

Inherits:
Object
  • Object
show all
Defined in:
lib/robot_lab/to/orchestrator.rb

Overview

Main autonomous loop.

Creates a new robot per iteration, reads the iteration result from SubmitResultTool, then commits, rolls back, or queues repair depending on the outcome.

Human-in-the-loop is asynchronous: when the robot raises a decision it must not make alone, it is written to a decision file (see DecisionManager). A blocking decision either pauses the loop (decision_mode: wait) or stops the run for a later --resume (decision_mode: exit).

Constant Summary collapse

SIGNAL_STOP =
"graceful_stop"
SUBMIT_NUDGE =

Sent to a robot that ended its turn without calling submit_result (the "thinks but doesn't act" degenerate case).

<<~MSG
  You ended your turn without calling submit_result. You MUST call it now:
  report success: true with a one-sentence summary (and key_changes if you
  modified files), or success: false with what blocked you. Do not do any
  further work first -- just submit the result of what you have done.
MSG

Instance Method Summary collapse

Constructor Details

#initialize(objective, config, resume_run_id: nil) ⇒ Orchestrator

Returns a new instance of Orchestrator.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/robot_lab/to/orchestrator.rb', line 29

def initialize(objective, config, resume_run_id: nil)
  @objective              = objective
  @config                 = config
  @resume_run_id          = resume_run_id
  @stop_requested         = false
  @abort_reason           = nil
  @pending_commit_failure = nil
  @logger                 = JsonlLogger.new  # buffers pre-open events
  @run                    = nil
  @git                    = nil
  @runner_thread          = nil
  @evaluator              = nil
  @robot                  = nil
  @submit_tool            = nil
  @decisions              = nil
  @decision_tool          = nil
  @injected_decisions     = []
  @accounted_in           = 0
  @accounted_out          = 0
end

Instance Method Details

#runObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/robot_lab/to/orchestrator.rb', line 50

def run
  @resume_run_id ? setup_resume : setup_run
  install_signal_handlers
  unless @resume_run_id
    @logger.log("orchestrator:start", run_id: @run.run_id, objective: @objective,
                                      branch: @run.branch, model: @config.model)
    progress "run #{@run.run_id} → branch #{@run.branch}"
  end
  main_loop
rescue AbortError => e
  @abort_reason = e.reason
  @logger.log("orchestrator:abort", reason: @abort_reason)
rescue PermanentError => e
  @abort_reason = "permanent error: #{e.message}"
  @git&.reset_hard unless @pending_commit_failure
  @logger.log("orchestrator:abort", reason: @abort_reason, permanent: true)
rescue => e
  @abort_reason = "fatal: #{e.message}"
  @git&.reset_hard unless @pending_commit_failure
  @logger.log("orchestrator:fatal", error: e.class.to_s, message: e.message)
ensure
  finalize_run
end