Class: SwarmSDK::V3::Loop::Executor
- Inherits:
-
Object
- Object
- SwarmSDK::V3::Loop::Executor
- Includes:
- Memory::Adapters::VectorUtils
- Defined in:
- lib/swarm_sdk/v3/loop/executor.rb
Overview
Core loop engine for iterative refinement
Runs a sequence of ask() calls through a provided callable, optionally checking for convergence via embedding similarity between consecutive responses. Emits events for each iteration and the overall loop lifecycle.
The Executor is stateless between runs — all configuration is passed to #run. The ask callable and embedder are injected at construction for testability.
Instance Method Summary collapse
-
#initialize(ask_callable:, embedder:, agent_id:) ⇒ Executor
constructor
Create a new Executor.
-
#run(kickoff:, iterate:, max_iterations:, convergence_threshold:, converge:) ⇒ Result
Execute the iterative loop.
Methods included from Memory::Adapters::VectorUtils
Constructor Details
#initialize(ask_callable:, embedder:, agent_id:) ⇒ Executor
Create a new Executor
38 39 40 41 42 |
# File 'lib/swarm_sdk/v3/loop/executor.rb', line 38 def initialize(ask_callable:, embedder:, agent_id:) @ask_callable = ask_callable @embedder = @agent_id = agent_id end |
Instance Method Details
#run(kickoff:, iterate:, max_iterations:, convergence_threshold:, converge:) ⇒ Result
Execute the iterative loop
Runs the kickoff prompt first, then the iterate prompt for subsequent iterations. If convergence checking is enabled, computes embedding similarity between consecutive responses and stops when it exceeds the threshold.
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 |
# File 'lib/swarm_sdk/v3/loop/executor.rb', line 67 def run(kickoff:, iterate:, max_iterations:, convergence_threshold:, converge:) EventStream.emit( type: "loop_started", agent: @agent_id, max_iterations: max_iterations, convergence_threshold: convergence_threshold, ) iterations = [] converged = false previous_content = nil max_iterations.times do |index| prompt = index.zero? ? kickoff : iterate response = @ask_callable.call(prompt) # Handle interrupted agent (ask() returns nil) break if response.nil? current_content = response.content.to_s input_tokens = response.respond_to?(:input_tokens) ? (response.input_tokens || 0) : 0 output_tokens = response.respond_to?(:output_tokens) ? (response.output_tokens || 0) : 0 delta_score = nil if converge && previous_content && @embedder delta_score = compute_delta(previous_content, current_content) end iteration = Iteration.new( number: index + 1, response: response, prompt: prompt, tokens: { input: input_tokens, output: output_tokens }, delta_score: delta_score, ) iterations << iteration EventStream.emit( type: "loop_iteration_completed", agent: @agent_id, iteration: index + 1, delta_score: delta_score, converged: false, ) if delta_score && delta_score >= convergence_threshold converged = true break end previous_content = current_content end EventStream.emit( type: "loop_completed", agent: @agent_id, iterations: iterations.size, converged: converged, ) Result.new(iterations: iterations, converged: converged) end |