Class: Legion::Extensions::Agentic::Inference::FreeEnergy::Helpers::FreeEnergyEngine

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb

Constant Summary

Constants included from Constants

Constants::DEFAULT_PRECISION, Constants::FREE_ENERGY_THRESHOLD, Constants::INFERENCE_MODES, Constants::LEARNING_RATE, Constants::MAX_ACTIONS, Constants::MAX_BELIEFS, Constants::MAX_HISTORY, Constants::PRECISION_CEILING, Constants::PRECISION_DECAY, Constants::PRECISION_FLOOR, Constants::PRECISION_UPDATE_RATE, Constants::STALE_THRESHOLD, Constants::SURPRISE_LABELS

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFreeEnergyEngine

Returns a new instance of FreeEnergyEngine.



14
15
16
17
18
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 14

def initialize
  @beliefs      = {}
  @belief_count = 0
  @history      = []
end

Instance Attribute Details

#beliefsObject (readonly)

Returns the value of attribute beliefs.



12
13
14
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 12

def beliefs
  @beliefs
end

#historyObject (readonly)

Returns the value of attribute history.



12
13
14
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 12

def history
  @history
end

Instance Method Details

#add_belief(content:, domain: :general, prediction: {}, precision: DEFAULT_PRECISION) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 20

def add_belief(content:, domain: :general, prediction: {}, precision: DEFAULT_PRECISION)
  return nil if @beliefs.size >= MAX_BELIEFS

  @belief_count += 1
  belief = Belief.new(
    id:         :"belief_#{@belief_count}",
    content:    content,
    domain:     domain,
    prediction: prediction,
    precision:  precision
  )
  @beliefs[belief.id] = belief
  record_event(:add_belief, belief_id: belief.id)
  belief
end

#decay_staleObject



116
117
118
119
120
121
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 116

def decay_stale
  now = Time.now.utc
  @beliefs.each_value do |belief|
    belief.decay_precision if belief.stale?(now: now)
  end
end

#domain_beliefs(domain:) ⇒ Object



91
92
93
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 91

def domain_beliefs(domain:)
  @beliefs.values.select { |b| b.domain == domain }
end

#domain_free_energy(domain:) ⇒ Object



95
96
97
98
99
100
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 95

def domain_free_energy(domain:)
  relevant = domain_beliefs(domain: domain)
  return 0.0 if relevant.empty?

  relevant.sum(&:free_energy) / relevant.size.to_f
end

#high_surprise_beliefsObject



87
88
89
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 87

def high_surprise_beliefs
  @beliefs.values.select(&:surprising?).map(&:to_h)
end

#minimize(belief_id:, mode: :perceptual) ⇒ Object



69
70
71
72
73
74
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 69

def minimize(belief_id:, mode: :perceptual)
  case mode
  when :perceptual then minimize_perceptual(belief_id: belief_id)
  when :active     then minimize_active(belief_id: belief_id)
  end
end

#minimize_active(belief_id:) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 55

def minimize_active(belief_id:)
  belief = @beliefs[belief_id]
  return nil unless belief

  action = {
    type:      :active_inference,
    belief_id: belief_id,
    target:    belief.prediction,
    urgency:   belief.free_energy
  }
  record_event(:minimize_active, belief_id: belief_id, action: action)
  action
end

#minimize_perceptual(belief_id:) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 45

def minimize_perceptual(belief_id:)
  belief = @beliefs[belief_id]
  return nil unless belief
  return nil unless belief.last_observation

  belief.revise_prediction(observation: belief.last_observation)
  record_event(:minimize_perceptual, belief_id: belief_id)
  belief
end

#most_precise(limit: 5) ⇒ Object



109
110
111
112
113
114
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 109

def most_precise(limit: 5)
  @beliefs.values
          .sort_by { |b| -b.precision }
          .first(limit)
          .map(&:to_h)
end

#most_surprising(limit: 5) ⇒ Object



102
103
104
105
106
107
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 102

def most_surprising(limit: 5)
  @beliefs.values
          .sort_by { |b| -b.free_energy }
          .first(limit)
          .map(&:to_h)
end

#observe(belief_id:, observation:) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 36

def observe(belief_id:, observation:)
  belief = @beliefs[belief_id]
  return nil unless belief

  belief.observe(observation: observation)
  record_event(:observe, belief_id: belief_id, error: belief.prediction_error)
  belief
end

#remove_belief(belief_id:) ⇒ Object



123
124
125
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 123

def remove_belief(belief_id:)
  @beliefs.delete(belief_id)
end

#surprise_levelObject



82
83
84
85
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 82

def surprise_level
  fe = total_free_energy
  SURPRISE_LABELS.find { |range, _| range.cover?(fe) }&.last || :trivial
end

#to_hObject



127
128
129
130
131
132
133
134
135
136
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 127

def to_h
  {
    belief_count:        @beliefs.size,
    total_free_energy:   total_free_energy.round(4),
    surprise_level:      surprise_level,
    high_surprise_count: @beliefs.values.count(&:surprising?),
    mean_precision:      mean_precision.round(4),
    history_size:        @history.size
  }
end

#total_free_energyObject



76
77
78
79
80
# File 'lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb', line 76

def total_free_energy
  return 0.0 if @beliefs.empty?

  @beliefs.values.sum(&:free_energy) / @beliefs.size.to_f
end