Class: Legion::Extensions::Agentic::Attention::Synesthesia::Helpers::SynesthesiaEngine

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb

Constant Summary

Constants included from Constants

Constants::DEFAULT_STRENGTH, Constants::INTENSITY_LABELS, Constants::MAX_EVENTS, Constants::MAX_MAPPINGS, Constants::MODALITIES, Constants::RICHNESS_LABELS, Constants::STRENGTH_BOOST, Constants::STRENGTH_DECAY, Constants::STRENGTH_LABELS, Constants::TRIGGER_THRESHOLD

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Constants

label_for

Constructor Details

#initializeSynesthesiaEngine

Returns a new instance of SynesthesiaEngine.



14
15
16
17
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 14

def initialize
  @mappings = {}
  @events   = []
end

Instance Attribute Details

#eventsObject (readonly)

Returns the value of attribute events.



12
13
14
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 12

def events
  @events
end

#mappingsObject (readonly)

Returns the value of attribute mappings.



12
13
14
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 12

def mappings
  @mappings
end

Instance Method Details

#cross_modal_richnessObject



63
64
65
66
67
68
69
70
71
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 63

def cross_modal_richness(**)
  return 0.0 if @mappings.empty?

  pairs = active_mapping_pairs
  total_possible = (MODALITIES.size * (MODALITIES.size - 1)).to_f
  return 0.0 if total_possible.zero?

  (pairs.size.to_f / total_possible).clamp(0.0, 1.0).round(10)
end

#decay_mappings!Object



55
56
57
58
59
60
61
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 55

def decay_mappings!(**)
  @mappings.each_value(&:decay!)
  removed = prune_weak_mappings!

  Legion::Logging.debug("[cognitive_synesthesia] decay_mappings! removed=#{removed} remaining=#{@mappings.size}") # rubocop:disable Legion/HelperMigration/DirectLogging
  { success: true, mappings_removed: removed, mappings_remaining: @mappings.size }
end

#dominant_modality_pairs(limit: 5) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 73

def dominant_modality_pairs(limit: 5, **)
  pair_counts = Hash.new(0)
  @mappings.each_value do |m|
    next unless m.active?

    pair_counts["#{m.source_modality}->#{m.target_modality}"] += m.activation_count
  end

  sorted = pair_counts.sort_by { |_, count| -count }.first(limit)
  sorted.map { |pair, count| { pair: pair, activation_count: count } }
end

#event_history(limit: 20) ⇒ Object



85
86
87
88
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 85

def event_history(limit: 20, **)
  recent = @events.last(limit)
  { success: true, events: recent.map(&:to_h), count: recent.size }
end

#modality_coverageObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 90

def modality_coverage(**)
  covered = Set.new
  @mappings.each_value do |m|
    next unless m.active?

    covered << m.source_modality
    covered << m.target_modality
  end
  {
    covered_modalities: covered.to_a.sort,
    coverage_count:     covered.size,
    total_modalities:   MODALITIES.size
  }
end

#register_mapping(source_modality:, target_modality:, trigger_pattern:, response_pattern:, strength: DEFAULT_STRENGTH) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 19

def register_mapping(source_modality:, target_modality:, trigger_pattern:,
                     response_pattern:, strength: DEFAULT_STRENGTH, **)
  return invalid_modality_error(:source_modality) unless MODALITIES.include?(source_modality)
  return invalid_modality_error(:target_modality) unless MODALITIES.include?(target_modality)

  mapping = SensoryMapping.new(
    source_modality:  source_modality,
    target_modality:  target_modality,
    trigger_pattern:  trigger_pattern,
    response_pattern: response_pattern,
    strength:         strength
  )

  @mappings[mapping.id] = mapping
  prune_mappings! if @mappings.size > MAX_MAPPINGS

  # rubocop:disable Legion/HelperMigration/DirectLogging
  Legion::Logging.debug("[cognitive_synesthesia] mapping registered id=#{mapping.id[0..7]} " \
                        "#{source_modality}->#{target_modality} strength=#{strength.round(2)}")
  # rubocop:enable Legion/HelperMigration/DirectLogging

  { success: true, mapping_id: mapping.id, source_modality: source_modality,
    target_modality: target_modality }
end

#synesthesia_reportObject



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 105

def synesthesia_report(**)
  richness = cross_modal_richness
  {
    mapping_count:           @mappings.size,
    active_mapping_count:    @mappings.values.count(&:active?),
    event_count:             @events.size,
    cross_modal_richness:    richness,
    richness_label:          Constants.label_for(RICHNESS_LABELS, richness),
    dominant_modality_pairs: dominant_modality_pairs,
    modality_coverage:       modality_coverage
  }
end

#trigger(source_modality:, input:) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb', line 44

def trigger(source_modality:, input:, **)
  active = active_mappings_for(source_modality)
  return { success: true, events: [], triggered_count: 0 } if active.empty?

  triggered_events = active.map do |mapping|
    fire_event(mapping, input)
  end

  { success: true, events: triggered_events.map(&:to_h), triggered_count: triggered_events.size }
end