Module: Legion::Extensions::MindGrowth::Runners::CompetitiveEvolver
- Extended by:
- CompetitiveEvolver
- Included in:
- CompetitiveEvolver
- Defined in:
- lib/legion/extensions/mind_growth/runners/competitive_evolver.rb
Constant Summary collapse
- COMPETITION_STATUSES =
%i[pending active evaluating decided cancelled].freeze
- ACTIVE_STATUSES =
%i[pending active evaluating].freeze
- MIN_TRIAL_ITERATIONS =
10
Instance Method Summary collapse
- #active_competitions ⇒ Object
- #compare_results(competition_id:) ⇒ Object
- #competition_history(limit: 20) ⇒ Object
- #competition_status(competition_id:) ⇒ Object
- #create_competition(gap:, proposal_ids:) ⇒ Object
- #declare_winner(competition_id:) ⇒ Object
- #run_trial(competition_id:, extension:, iterations: MIN_TRIAL_ITERATIONS) ⇒ Object
Instance Method Details
#active_competitions ⇒ Object
111 112 113 114 115 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 111 def active_competitions(**) comps = all_competitions.select { |c| ACTIVE_STATUSES.include?(c[:status]) } { success: true, competitions: comps.map { |c| { id: c[:id], gap: c[:gap], status: c[:status] } }, count: comps.size } end |
#compare_results(competition_id:) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 58 def compare_results(competition_id:, **) competition = get_competition(competition_id) return { success: false, reason: :not_found } unless competition trials = competition[:trials] return { success: true, comparison: [], leader: nil } if trials.empty? ranked = trials.values.sort_by { |t| [-t[:fitness], t[:avg_latency_ms]] } leader = ranked.first comparison = ranked.map.with_index(1) do |trial, rank| { extension_name: trial[:extension_name], fitness: trial[:fitness], error_rate: trial[:error_rate], avg_latency_ms: trial[:avg_latency_ms], rank: rank } end { success: true, comparison: comparison, leader: leader[:extension_name] } end |
#competition_history(limit: 20) ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 117 def competition_history(limit: 20, **) comps = all_competitions.sort_by { |c| c[:created_at] }.reverse.first(limit) entries = comps.map do |c| { id: c[:id], gap: c[:gap], status: c[:status], winner: c[:winner], competitors: c[:proposal_ids].size, trial_count: c[:trials].size } end { success: true, competitions: entries, count: entries.size } end |
#competition_status(competition_id:) ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 102 def competition_status(competition_id:, **) competition = get_competition(competition_id) return { success: false, reason: :not_found } unless competition { success: true, id: competition[:id], gap: competition[:gap], status: competition[:status], competitors: competition[:proposal_ids], trial_count: competition[:trials].size, winner: competition[:winner] } end |
#create_competition(gap:, proposal_ids:) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 14 def create_competition(gap:, proposal_ids:, **) ids = Array(proposal_ids) return { success: false, reason: :insufficient_competitors } if ids.size < 2 competition_id = SecureRandom.uuid competition = { id: competition_id, gap: gap.to_s, proposal_ids: ids, status: :pending, trials: {}, winner: nil, created_at: Time.now.utc, decided_at: nil } store_competition(competition) { success: true, competition_id: competition_id, gap: gap.to_s, competitors: ids.size } end |
#declare_winner(competition_id:) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 81 def declare_winner(competition_id:, **) competition = get_competition(competition_id) return { success: false, reason: :not_found } unless competition return { success: false, reason: :already_decided } if competition[:status] == :decided return { success: false, reason: :no_trials } if competition[:trials].empty? comparison = compare_results(competition_id: competition_id) winner_name = comparison[:leader] losers = competition[:trials].keys.reject { |name| name == winner_name } losers.each do |loser_name| Runners::Evolver.replace_extension(old_name: loser_name, new_proposal_id: "winner:#{winner_name}") end transition_competition(competition_id, :decided) set_winner(competition_id, winner_name) { success: true, winner: winner_name, losers: losers, competition_id: competition_id } end |
#run_trial(competition_id:, extension:, iterations: MIN_TRIAL_ITERATIONS) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/legion/extensions/mind_growth/runners/competitive_evolver.rb', line 34 def run_trial(competition_id:, extension:, iterations: MIN_TRIAL_ITERATIONS, **) competition = get_competition(competition_id) return { success: false, reason: :not_found } unless competition return { success: false, reason: :already_decided } if competition[:status] == :decided transition_competition(competition_id, :active) if competition[:status] == :pending fitness = Helpers::FitnessEvaluator.fitness(extension) name = extension[:name] || extension[:extension_name] trial = { extension_name: name, fitness: fitness, error_rate: extension[:error_rate] || 0.0, avg_latency_ms: extension[:avg_latency_ms] || 0, invocations: extension[:invocation_count] || 0, iterations: iterations, recorded_at: Time.now.utc } record_trial(competition_id, name, trial) { success: true, competition_id: competition_id, trial: trial } end |