Class: Legion::Extensions::Agentic::Homeostasis::TemporalDiscounting::Helpers::DiscountingEngine
- Inherits:
-
Object
- Object
- Legion::Extensions::Agentic::Homeostasis::TemporalDiscounting::Helpers::DiscountingEngine
- Defined in:
- lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb
Instance Attribute Summary collapse
-
#domain_rates ⇒ Object
readonly
Returns the value of attribute domain_rates.
-
#rewards ⇒ Object
readonly
Returns the value of attribute rewards.
Instance Method Summary collapse
- #compare_rewards(reward_a_id:, reward_b_id:) ⇒ Object
- #create_reward(label:, amount:, delay:, domain: :general, discount_rate: nil) ⇒ Object
- #get_domain_rate(domain) ⇒ Object
- #immediate_vs_delayed(immediate_amount:, delayed_amount:, delay:, domain: :general) ⇒ Object
-
#initialize ⇒ DiscountingEngine
constructor
A new instance of DiscountingEngine.
- #most_valuable(limit: 5) ⇒ Object
- #optimal_delay(reward_id:, min_value: 0.5) ⇒ Object
- #patience_report ⇒ Object
- #prune_expired(min_value: 0.05) ⇒ Object
- #rewards_by_domain(domain:) ⇒ Object
- #set_domain_rate(domain:, rate:) ⇒ Object
- #to_h ⇒ Object
- #worth_waiting_for?(reward_id:, threshold: 0.3) ⇒ Boolean
Constructor Details
#initialize ⇒ DiscountingEngine
Returns a new instance of DiscountingEngine.
12 13 14 15 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 12 def initialize @rewards = {} @domain_rates = {} end |
Instance Attribute Details
#domain_rates ⇒ Object (readonly)
Returns the value of attribute domain_rates.
10 11 12 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 10 def domain_rates @domain_rates end |
#rewards ⇒ Object (readonly)
Returns the value of attribute rewards.
10 11 12 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 10 def rewards @rewards end |
Instance Method Details
#compare_rewards(reward_a_id:, reward_b_id:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 25 def compare_rewards(reward_a_id:, reward_b_id:) a = @rewards.fetch(reward_a_id, nil) b = @rewards.fetch(reward_b_id, nil) return { error: :not_found, missing: missing_ids(reward_a_id, reward_b_id) } if a.nil? || b.nil? delta = (a.subjective_value - b.subjective_value).round(10) preferred = if delta.positive? reward_a_id elsif delta.negative? reward_b_id else :tied end { preferred: preferred, delta: delta.abs, reward_a_value: a.subjective_value, reward_b_value: b.subjective_value } end |
#create_reward(label:, amount:, delay:, domain: :general, discount_rate: nil) ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 17 def create_reward(label:, amount:, delay:, domain: :general, discount_rate: nil) rate = discount_rate || get_domain_rate(domain) reward = Reward.new(label: label, amount: amount, delay: delay, domain: domain, discount_rate: rate) @rewards[reward.id] = reward @rewards.shift while @rewards.size > MAX_REWARDS reward end |
#get_domain_rate(domain) ⇒ Object
59 60 61 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 59 def get_domain_rate(domain) @domain_rates.fetch(domain, DEFAULT_DISCOUNT_RATE) end |
#immediate_vs_delayed(immediate_amount:, delayed_amount:, delay:, domain: :general) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 63 def immediate_vs_delayed(immediate_amount:, delayed_amount:, delay:, domain: :general) k = get_domain_rate(domain) delayed_sv = (delayed_amount / (1.0 + (k * delay.to_f))).round(10) immediate_sv = immediate_amount.to_f.clamp(0.0, 1.0).round(10) preferred = immediate_sv >= delayed_sv ? :immediate : :delayed { preferred: preferred, immediate_value: immediate_sv, delayed_value: delayed_sv, delta: (immediate_sv - delayed_sv).abs.round(10), discount_rate: k } end |
#most_valuable(limit: 5) ⇒ Object
117 118 119 120 121 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 117 def most_valuable(limit: 5) @rewards.values .sort_by { |r| -r.subjective_value } .first(limit) end |
#optimal_delay(reward_id:, min_value: 0.5) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 79 def optimal_delay(reward_id:, min_value: 0.5) reward = @rewards.fetch(reward_id, nil) return { error: :not_found } if reward.nil? k = reward.discount_rate a = reward.amount return { error: :threshold_too_high } if min_value > a max_delay = ((a / min_value) - 1.0) / k { reward_id: reward_id, max_delay: max_delay.round(10), min_value: min_value, amount: a, discount_rate: k } end |
#patience_report ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 97 def patience_report return empty_patience_report if @rewards.empty? values = @rewards.values avg_rate = (values.sum(&:discount_rate) / values.size).round(10) avg_sv = (values.sum(&:subjective_value) / values.size).round(10) distribution = build_impulsivity_distribution(values) { total_rewards: @rewards.size, avg_discount_rate: avg_rate, avg_subjective_value: avg_sv, impulsivity_distribution: distribution } end |
#prune_expired(min_value: 0.05) ⇒ Object
123 124 125 126 127 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 123 def prune_expired(min_value: 0.05) before = @rewards.size @rewards.reject! { |_, r| r.subjective_value < min_value } { pruned: before - @rewards.size, remaining: @rewards.size } end |
#rewards_by_domain(domain:) ⇒ Object
113 114 115 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 113 def rewards_by_domain(domain:) @rewards.values.select { |r| r.domain == domain } end |
#set_domain_rate(domain:, rate:) ⇒ Object
55 56 57 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 55 def set_domain_rate(domain:, rate:) @domain_rates[domain] = rate.clamp(MIN_DISCOUNT_RATE, MAX_DISCOUNT_RATE) end |
#to_h ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 129 def to_h { total_rewards: @rewards.size, domain_rates: @domain_rates, patience: patience_report } end |
#worth_waiting_for?(reward_id:, threshold: 0.3) ⇒ Boolean
47 48 49 50 51 52 53 |
# File 'lib/legion/extensions/agentic/homeostasis/temporal_discounting/helpers/discounting_engine.rb', line 47 def worth_waiting_for?(reward_id:, threshold: 0.3) reward = @rewards.fetch(reward_id, nil) return { error: :not_found } if reward.nil? { reward_id: reward_id, worth_waiting: reward.worth_waiting?(threshold: threshold), subjective_value: reward.subjective_value, threshold: threshold } end |