Class: Legion::Extensions::Agentic::Integration::Zeitgeist::Helpers::ZeitgeistEngine

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb

Constant Summary

Constants included from Constants

Constants::CONVERGENCE_LABELS, Constants::CONVERGENCE_THRESHOLD, Constants::DEFAULT_INTENSITY, Constants::DIVERGENCE_THRESHOLD, Constants::MAX_SIGNALS, Constants::MOMENTUM_LABELS, Constants::MOMENTUM_THRESHOLD, Constants::MOOD_LABELS, Constants::SIGNAL_DOMAINS, Constants::WINDOW_SIZE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Constants

label_for

Constructor Details

#initializeZeitgeistEngine

Returns a new instance of ZeitgeistEngine.



14
15
16
17
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 14

def initialize
  @signals      = []
  @trend_window = TrendWindow.new
end

Instance Attribute Details

#signalsObject (readonly)

Returns the value of attribute signals.



12
13
14
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 12

def signals
  @signals
end

#trend_windowObject (readonly)

Returns the value of attribute trend_window.



12
13
14
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 12

def trend_window
  @trend_window
end

Instance Method Details

#cognitive_convergenceObject



53
54
55
56
57
58
59
60
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 53

def cognitive_convergence
  return 1.0 if @signals.empty?

  subsystems = @signals.map(&:source_subsystem).uniq
  return 1.0 if subsystems.size <= 1

  compute_alignment(subsystems)
end

#collective_moodObject



43
44
45
46
47
48
49
50
51
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 43

def collective_mood
  return 0.0 if @signals.empty?

  weighted_sum = @signals.sum { |s| s.valence * s.intensity }
  total = @signals.sum(&:intensity)
  return 0.0 if total.zero?

  (weighted_sum / total).clamp(-1.0, 1.0).round(10)
end

#divergence_alert?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 82

def divergence_alert?
  cognitive_convergence < DIVERGENCE_THRESHOLD
end

#dominant_themes(limit: 5) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 33

def dominant_themes(limit: 5)
  return [] if @signals.empty?

  weights = Hash.new(0.0)
  @signals.each { |s| weights[s.domain] += s.intensity }
  weights.sort_by { |_d, w| -w }.first(limit).map do |domain, weight|
    { domain: domain, weight: weight.round(10) }
  end
end

#falling_domains(window_size: WINDOW_SIZE / 2) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 72

def falling_domains(window_size: WINDOW_SIZE / 2)
  return [] if @signals.size < window_size

  recent  = @signals.last(window_size)
  earlier = @signals.last(window_size * 2).first(window_size)

  deltas = domain_intensity_deltas(recent, earlier)
  deltas.select { |d| d[:delta] < 0.0 }.sort_by { |d| d[:delta] }
end

#ingest(source_subsystem:, domain:, intensity: DEFAULT_INTENSITY, valence: 0.0, timestamp: nil) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 19

def ingest(source_subsystem:, domain:, intensity: DEFAULT_INTENSITY, valence: 0.0, timestamp: nil)
  signal = CognitiveSignal.new(
    source_subsystem: source_subsystem,
    domain:           domain,
    intensity:        intensity,
    valence:          valence,
    timestamp:        timestamp
  )
  @signals << signal
  @signals.shift while @signals.size > MAX_SIGNALS
  @trend_window.add(signal)
  signal
end

#rising_domains(window_size: WINDOW_SIZE / 2) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 62

def rising_domains(window_size: WINDOW_SIZE / 2)
  return [] if @signals.size < window_size

  recent  = @signals.last(window_size)
  earlier = @signals.last(window_size * 2).first(window_size)

  deltas = domain_intensity_deltas(recent, earlier)
  deltas.select { |d| d[:delta] > 0.0 }.sort_by { |d| -d[:delta] }
end

#zeitgeist_reportObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/legion/extensions/agentic/integration/zeitgeist/helpers/zeitgeist_engine.rb', line 86

def zeitgeist_report
  mood_value = collective_mood
  conv_value = cognitive_convergence
  mom_value  = @trend_window.momentum

  {
    signal_count:      @signals.size,
    dominant_themes:   dominant_themes,
    collective_mood:   mood_value,
    mood_label:        Constants.label_for(MOOD_LABELS, normalize_mood(mood_value)),
    convergence:       conv_value,
    convergence_label: Constants.label_for(CONVERGENCE_LABELS, conv_value),
    momentum:          mom_value,
    momentum_label:    Constants.label_for(MOMENTUM_LABELS, mom_value),
    rising_domains:    rising_domains,
    falling_domains:   falling_domains,
    divergence_alert:  divergence_alert?,
    trend_window:      @trend_window.to_h
  }
end