Class: Legion::Extensions::Agentic::Social::Calibration::Helpers::CalibrationStore

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCalibrationStore

Returns a new instance of CalibrationStore.



12
13
14
15
16
17
18
19
20
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 12

def initialize
  @weights = Constants::ADVISORY_TYPES.to_h do |type|
    [type.to_s, Constants::NEUTRAL_SCORE]
  end
  @history = {}
  @last_advisory_meta = nil
  @partner_baselines = { 'avg_latency' => nil, 'avg_length' => nil }
  @dirty = false
end

Instance Attribute Details

#historyObject (readonly)

Returns the value of attribute history.



10
11
12
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 10

def history
  @history
end

#weightsObject (readonly)

Returns the value of attribute weights.



10
11
12
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 10

def weights
  @weights
end

Instance Method Details

#calibration_weightsObject



58
59
60
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 58

def calibration_weights
  @weights.dup
end

#detect_explicit_feedback(content) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 62

def detect_explicit_feedback(content)
  text = content.to_s
  return :positive if text.match?(Constants::POSITIVE_PATTERNS)
  return :negative if text.match?(Constants::NEGATIVE_PATTERNS)

  :neutral
end

#dirty?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 22

def dirty?
  @dirty
end

#evaluate_reaction(observation:) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 39

def evaluate_reaction(observation:)
  return nil unless @last_advisory_meta
  return nil if @last_advisory_meta[:advisory_types].empty?

  elapsed = Time.now.utc - @last_advisory_meta[:timestamp]
  return nil if elapsed > 3600

  reaction_score = compute_reaction_score(observation)
  confidence = compute_confidence(observation)

  deltas = @last_advisory_meta[:advisory_types].map do |type|
    apply_delta(type: type, reaction_score: reaction_score, confidence: confidence)
  end

  @last_advisory_meta = nil
  @dirty = true
  { success: true, deltas: deltas }
end

#from_apollo(store:) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 105

def from_apollo(store:)
  result = store.query(text: 'bond calibration weights', tags: Constants::WEIGHTS_TAGS)
  return false unless result[:success] && result[:results]&.any?

  entry = result[:results].first
  parsed = ::JSON.parse(entry[:content])
  @weights.merge!(parsed['weights']) if parsed['weights']
  @partner_baselines = parsed['baselines'] if parsed['baselines']
  true
rescue StandardError => e
  Legion::Logging.warn("[calibration_store] from_apollo error: #{e.message}")
  false
end

#mark_clean!Object



26
27
28
29
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 26

def mark_clean!
  @dirty = false
  self
end

#record_advisory(advisory_id:, advisory_types:) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 31

def record_advisory(advisory_id:, advisory_types:)
  @last_advisory_meta = {
    advisory_id:    advisory_id,
    advisory_types: Array(advisory_types).map(&:to_s),
    timestamp:      Time.now.utc
  }
end

#to_apollo_entriesObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 83

def to_apollo_entries
  entries = []

  content = Legion::JSON.dump({
                                'weights'    => @weights,
                                'baselines'  => @partner_baselines,
                                'updated_at' => Time.now.utc.iso8601
                              })
  entries << { content: content, tags: Constants::WEIGHTS_TAGS.dup + ['partner'] }

  @history.each do |type, events|
    hist_content = Legion::JSON.dump({
                                       'advisory_type'  => type,
                                       'events'         => events.last(Constants::MAX_HISTORY),
                                       'current_weight' => @weights[type]
                                     })
    entries << { content: hist_content, tags: Constants::HISTORY_TAG_PREFIX + [type] }
  end

  entries
end

#update_baseline(latency:, length:) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb', line 70

def update_baseline(latency:, length:)
  @partner_baselines['avg_latency'] = if @partner_baselines['avg_latency']
                                        (@partner_baselines['avg_latency'] * 0.9) + (latency.to_f * 0.1)
                                      else
                                        latency.to_f
                                      end
  @partner_baselines['avg_length'] = if @partner_baselines['avg_length']
                                       (@partner_baselines['avg_length'] * 0.9) + (length.to_f * 0.1)
                                     else
                                       length.to_f
                                     end
end