Module: Legion::Extensions::Agentic::Memory::Trace::Helpers::Decay

Defined in:
lib/legion/extensions/agentic/memory/trace/helpers/decay.rb

Class Method Summary collapse

Class Method Details

.compute_decay(peak_strength:, base_decay_rate:, ticks_since_access:, emotional_intensity: 0.0) ⇒ Object

Power-law decay formula from spec: new_strength = peak_strength * (ticks_since_access + 1)^(-base_decay_rate / (1 + emotional_intensity * E_WEIGHT))



14
15
16
17
18
19
20
21
22
# File 'lib/legion/extensions/agentic/memory/trace/helpers/decay.rb', line 14

def compute_decay(peak_strength:, base_decay_rate:, ticks_since_access:, emotional_intensity: 0.0, **)
  return peak_strength if base_decay_rate.zero?
  return 0.0 if peak_strength.zero?

  e_weight = Helpers::Trace::E_WEIGHT
  effective_rate = base_decay_rate / (1.0 + (emotional_intensity * e_weight))
  new_strength = peak_strength * ((ticks_since_access + 1).to_f**(-effective_rate))
  new_strength.clamp(0.0, 1.0)
end

.compute_reinforcement(current_strength:, imprint_active: false) ⇒ Object

Reinforcement formula from spec: new_strength = min(1.0, current_strength + R_AMOUNT * IMPRINT_MULTIPLIER_if_applicable)



26
27
28
29
30
31
# File 'lib/legion/extensions/agentic/memory/trace/helpers/decay.rb', line 26

def compute_reinforcement(current_strength:, imprint_active: false, **)
  r_amount = Helpers::Trace::R_AMOUNT
  multiplier = imprint_active ? Helpers::Trace::IMPRINT_MULTIPLIER : 1.0
  new_strength = current_strength + (r_amount * multiplier)
  new_strength.clamp(0.0, 1.0)
end

.compute_retrieval_score(trace:, query_time: nil, associated: false) ⇒ Object

Composite retrieval score from spec: score = strength * recency_factor * emotional_weight * (1 + association_bonus)



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/legion/extensions/agentic/memory/trace/helpers/decay.rb', line 35

def compute_retrieval_score(trace:, query_time: nil, associated: false, **)
  query_time ||= Time.now.utc
  seconds_since = [query_time - ensure_time(trace[:last_reinforced]), 0].max
  half_life = Helpers::Trace::RETRIEVAL_RECENCY_HALF.to_f

  recency_factor = 2.0**(-seconds_since / half_life)
  emotional_weight = 1.0 + trace[:emotional_intensity]
  assoc_bonus = associated ? (1.0 + Helpers::Trace::ASSOCIATION_BONUS) : 1.0

  trace[:strength] * recency_factor * emotional_weight * assoc_bonus
end

.compute_storage_tier(trace:, now: nil) ⇒ Object

Determine storage tier based on last access time



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/legion/extensions/agentic/memory/trace/helpers/decay.rb', line 48

def compute_storage_tier(trace:, now: nil, **)
  now ||= Time.now.utc
  seconds_since = now - ensure_time(trace[:last_reinforced])

  if trace[:strength] <= Helpers::Trace::PRUNE_THRESHOLD
    :erased
  elsif seconds_since <= Helpers::Trace::HOT_TIER_WINDOW
    :hot
  elsif seconds_since <= Helpers::Trace::WARM_TIER_WINDOW
    :warm
  else
    :cold
  end
end

.ensure_time(value) ⇒ Object



63
64
65
66
67
68
# File 'lib/legion/extensions/agentic/memory/trace/helpers/decay.rb', line 63

def ensure_time(value)
  return value if value.is_a?(Time)
  return Time.parse(value) if value.is_a?(String)

  Time.now.utc
end