Class: Legion::Extensions::Agentic::Learning::PreferenceLearning::Helpers::PreferenceEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb

Instance Method Summary collapse

Constructor Details

#initializePreferenceEngine

Returns a new instance of PreferenceEngine.



10
11
12
13
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 10

def initialize
  @options      = {} # id => Option
  @comparisons  = 0
end

Instance Method Details

#bottom_preferences(domain: nil, limit: 5) ⇒ Object



63
64
65
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 63

def bottom_preferences(domain: nil, limit: 5)
  filtered(domain).sort_by(&:preference_score).first(limit).map(&:to_h)
end

#decay_allObject



90
91
92
93
94
95
96
97
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 90

def decay_all
  @options.each_value do |option|
    delta = (option.preference_score - Constants::DEFAULT_PREFERENCE) * Constants::DECAY_RATE
    option.preference_score = (option.preference_score - delta)
                              .clamp(Constants::PREFERENCE_FLOOR, Constants::PREFERENCE_CEILING)
  end
  @options.size
end

#most_compared(limit: 10) ⇒ Object



83
84
85
86
87
88
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 83

def most_compared(limit: 10)
  @options.values
          .sort_by { |o| -o.times_seen }
          .first(limit)
          .map(&:to_h)
end

#predict_preference(option_a_id:, option_b_id:) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 41

def predict_preference(option_a_id:, option_b_id:)
  a = @options[option_a_id]
  b = @options[option_b_id]
  return { error: 'option not found' } unless a && b

  diff       = (a.preference_score - b.preference_score).abs
  confidence = diff.clamp(0.0, 1.0)
  preferred  = a.preference_score >= b.preference_score ? a : b

  {
    preferred_id:    preferred.id,
    preferred_label: preferred.label,
    confidence:      confidence,
    score_a:         a.preference_score,
    score_b:         b.preference_score
  }
end

#preference_stabilityObject



74
75
76
77
78
79
80
81
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 74

def preference_stability
  scores = @options.values.map(&:preference_score)
  return 0.0 if scores.size < 2

  mean = scores.sum / scores.size.to_f
  variance = scores.sum { |s| (s - mean)**2 } / scores.size.to_f
  Math.sqrt(variance)
end

#preferences_by_domain(domain:) ⇒ Object



67
68
69
70
71
72
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 67

def preferences_by_domain(domain:)
  @options.values
          .select { |o| o.domain == domain }
          .sort_by { |o| -o.preference_score }
          .map(&:to_h)
end

#record_comparison(winner_id:, loser_id:) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 23

def record_comparison(winner_id:, loser_id:)
  winner = @options[winner_id]
  loser  = @options[loser_id]
  return { error: 'option not found' } unless winner && loser

  @comparisons += 1
  winner.win!
  loser.lose!

  {
    winner_id:    winner_id,
    loser_id:     loser_id,
    comparisons:  @comparisons,
    winner_score: winner.preference_score,
    loser_score:  loser.preference_score
  }
end

#register_option(label:, domain: :general) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 15

def register_option(label:, domain: :general)
  return { error: 'max options reached' } if @options.size >= Constants::MAX_OPTIONS

  option = Option.new(label: label, domain: domain)
  @options[option.id] = option
  option.to_h
end

#to_hObject



99
100
101
102
103
104
105
106
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 99

def to_h
  {
    total_options: @options.size,
    comparisons:   @comparisons,
    stability:     preference_stability,
    options:       @options.values.map(&:to_h)
  }
end

#top_preferences(domain: nil, limit: 5) ⇒ Object



59
60
61
# File 'lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb', line 59

def top_preferences(domain: nil, limit: 5)
  filtered(domain).sort_by { |o| -o.preference_score }.first(limit).map(&:to_h)
end