Module: Legion::Extensions::Agentic::Affect::Emotion::Helpers::Valence
- Defined in:
- lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb
Constant Summary collapse
- DIMENSIONS =
%i[urgency importance novelty familiarity].freeze
- MAX_MAGNITUDE =
all 4 dimensions at 1.0
Math.sqrt(4.0)
- URGENCY_ATTENTION_WEIGHT =
Attention modulation weights (from spec Section 6.1)
0.4- IMPORTANCE_ATTENTION_WEIGHT =
0.35- NOVELTY_ATTENTION_WEIGHT =
0.25- ATTENTION_MULTIPLIER =
0.3- MOMENTUM_ALPHA =
Momentum
0.3- SOURCE_URGENCY =
Source urgency map (spec Section 3.2)
{ firmware_violation: 1.0, human_direct: 0.9, direct_address: 0.8, mesh_priority: 0.7, scheduled: 0.4, partner_absence: 0.2, ambient: 0.1 }.freeze
- ABSENCE_BASE_IMPORTANCE =
Partner absence importance scaling
0.4- ABSENCE_IMPORTANCE_SCALE =
0.1- ABSENCE_MAX_IMPORTANCE =
0.7- FAMILIARITY_SATURATION =
Familiarity saturation (spec Section 3.5)
100
Class Method Summary collapse
- .absence_importance(consecutive_misses) ⇒ Object
- .aggregate(valences) ⇒ Object
- .clamp(value, min = 0.0, max = 1.0) ⇒ Object
- .compute_arousal(valences) ⇒ Object
- .dominant_dimension(valence) ⇒ Object
- .magnitude(valence) ⇒ Object
- .modulate_salience(base_salience, valence) ⇒ Object
- .new_valence(urgency: 0.0, importance: 0.0, novelty: 0.0, familiarity: 0.0) ⇒ Object
Class Method Details
.absence_importance(consecutive_misses) ⇒ Object
83 84 85 86 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 83 def absence_importance(consecutive_misses) raw = ABSENCE_BASE_IMPORTANCE + (ABSENCE_IMPORTANCE_SCALE * Math.log(consecutive_misses + 1)) clamp(raw, 0.0, ABSENCE_MAX_IMPORTANCE) end |
.aggregate(valences) ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 65 def aggregate(valences) return new_valence if valences.empty? sums = Hash.new(0.0) valences.each do |v| DIMENSIONS.each { |d| sums[d] += v[d] } end n = valences.size.to_f new_valence(**DIMENSIONS.to_h { |d| [d, sums[d] / n] }) end |
.clamp(value, min = 0.0, max = 1.0) ⇒ Object
95 96 97 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 95 def clamp(value, min = 0.0, max = 1.0) value.clamp(min, max) end |
.compute_arousal(valences) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 76 def compute_arousal(valences) return 0.0 if valences.empty? total = valences.sum { |v| magnitude(v) } clamp(total / (valences.size * MAX_MAGNITUDE)) end |
.dominant_dimension(valence) ⇒ Object
61 62 63 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 61 def dominant_dimension(valence) DIMENSIONS.max_by { |d| valence[d] } end |
.magnitude(valence) ⇒ Object
52 53 54 55 56 57 58 59 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 52 def magnitude(valence) Math.sqrt( (valence[:urgency]**2) + (valence[:importance]**2) + (valence[:novelty]**2) + (valence[:familiarity]**2) ) end |
.modulate_salience(base_salience, valence) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 88 def modulate_salience(base_salience, valence) boost = ((valence[:urgency] * URGENCY_ATTENTION_WEIGHT) + (valence[:importance] * IMPORTANCE_ATTENTION_WEIGHT) + (valence[:novelty] * NOVELTY_ATTENTION_WEIGHT)) * ATTENTION_MULTIPLIER clamp(base_salience + boost) end |
.new_valence(urgency: 0.0, importance: 0.0, novelty: 0.0, familiarity: 0.0) ⇒ Object
43 44 45 46 47 48 49 50 |
# File 'lib/legion/extensions/agentic/affect/emotion/helpers/valence.rb', line 43 def new_valence(urgency: 0.0, importance: 0.0, novelty: 0.0, familiarity: 0.0) { urgency: clamp(urgency), importance: clamp(importance), novelty: clamp(novelty), familiarity: clamp(familiarity) } end |