Class: Legion::Extensions::Agentic::Affect::Resilience::Helpers::AdversityTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAdversityTracker

Returns a new instance of AdversityTracker.



12
13
14
15
16
17
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 12

def initialize
  @active_adversities = []
  @resolved_adversities = []
  @consecutive_recoveries = 0
  @adversity_counter = 0
end

Instance Attribute Details

#active_adversitiesObject (readonly)

Returns the value of attribute active_adversities.



10
11
12
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 10

def active_adversities
  @active_adversities
end

#consecutive_recoveriesObject (readonly)

Returns the value of attribute consecutive_recoveries.



10
11
12
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 10

def consecutive_recoveries
  @consecutive_recoveries
end

#resolved_adversitiesObject (readonly)

Returns the value of attribute resolved_adversities.



10
11
12
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 10

def resolved_adversities
  @resolved_adversities
end

Instance Method Details

#active_by_typeObject



68
69
70
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 68

def active_by_type
  @active_adversities.group_by { |a| a[:type] }.transform_values(&:size)
end

#average_recovery_speedObject



80
81
82
83
84
85
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 80

def average_recovery_speed
  return 0.0 if @resolved_adversities.empty?

  ratios = @resolved_adversities.map { |a| a[:ticks_elapsed].to_f / [a[:expected_ticks], 1].max }
  ratios.sum / ratios.size.to_f
end

#recovery_rateObject



72
73
74
75
76
77
78
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 72

def recovery_rate
  total = @resolved_adversities.size
  return 0.0 if total.zero?

  on_time = @resolved_adversities.count { |a| a[:ticks_elapsed] <= a[:expected_ticks] }
  on_time.to_f / total
end

#register(type:, severity:, context: {}) ⇒ 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
43
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 19

def register(type:, severity:, context: {})
  return nil unless Constants::ADVERSITY_TYPES.include?(type)
  return nil unless Constants::SEVERITY_LEVELS.key?(severity)

  @adversity_counter += 1
  severity_config = Constants::SEVERITY_LEVELS[severity]

  adversity = {
    id:              @adversity_counter,
    type:            type,
    severity:        severity,
    impact:          severity_config[:impact],
    expected_ticks:  severity_config[:recovery_ticks],
    phase:           :absorbing,
    health_at_onset: 1.0,
    current_health:  1.0 - severity_config[:impact],
    ticks_elapsed:   0,
    context:         context,
    registered_at:   Time.now.utc
  }

  @active_adversities << adversity
  trim_active
  adversity
end

#tick_recoveryObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 45

def tick_recovery
  @active_adversities.each do |adv|
    adv[:ticks_elapsed] += 1
    advance_phase(adv)
    recover_health(adv)
  end

  newly_resolved = @active_adversities.select { |a| a[:current_health] >= Constants::RECOVERY_THRESHOLD }
  newly_resolved.each { |a| resolve(a) }

  {
    active_count:   @active_adversities.size,
    resolved_count: newly_resolved.size,
    worst_health:   worst_health
  }
end

#total_adversitiesObject



87
88
89
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 87

def total_adversities
  @active_adversities.size + @resolved_adversities.size
end

#worst_healthObject



62
63
64
65
66
# File 'lib/legion/extensions/agentic/affect/resilience/helpers/adversity_tracker.rb', line 62

def worst_health
  return 1.0 if @active_adversities.empty?

  @active_adversities.map { |a| a[:current_health] }.min
end