Class: Aidp::Harness::UsageLimit

Inherits:
Object
  • Object
show all
Defined in:
lib/aidp/harness/usage_limit.rb

Overview

Immutable value object representing usage limit configuration Encapsulates limit settings for a provider with tier-based limits

Constant Summary collapse

VALID_PERIODS =
%w[daily weekly monthly].freeze
VALID_TIERS =
%w[mini standard thinking advanced pro max].freeze
DEFAULT_PERIOD =
"monthly"
DEFAULT_RESET_DAY =
1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(enabled: true, period: DEFAULT_PERIOD, reset_day: DEFAULT_RESET_DAY, tier_limits: {}, max_tokens: nil, max_cost: nil) ⇒ UsageLimit

Returns a new instance of UsageLimit.



32
33
34
35
36
37
38
39
40
41
# File 'lib/aidp/harness/usage_limit.rb', line 32

def initialize(enabled: true, period: DEFAULT_PERIOD, reset_day: DEFAULT_RESET_DAY,
  tier_limits: {}, max_tokens: nil, max_cost: nil)
  @enabled = enabled
  @period = validate_period(period)
  @reset_day = validate_reset_day(reset_day)
  @tier_limits = freeze_tier_limits(tier_limits)
  @max_tokens = max_tokens&.to_i
  @max_cost = max_cost&.to_f
  freeze
end

Instance Attribute Details

#enabledObject (readonly)

Returns the value of attribute enabled.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def enabled
  @enabled
end

#max_costObject (readonly)

Returns the value of attribute max_cost.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def max_cost
  @max_cost
end

#max_tokensObject (readonly)

Returns the value of attribute max_tokens.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def max_tokens
  @max_tokens
end

#periodObject (readonly)

Returns the value of attribute period.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def period
  @period
end

#reset_dayObject (readonly)

Returns the value of attribute reset_day.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def reset_day
  @reset_day
end

#tier_limitsObject (readonly)

Returns the value of attribute tier_limits.



13
14
15
# File 'lib/aidp/harness/usage_limit.rb', line 13

def tier_limits
  @tier_limits
end

Class Method Details

.from_config(config) ⇒ UsageLimit

Create a new UsageLimit from configuration hash

Parameters:

  • config (Hash)

    Configuration hash with usage limit settings

Returns:



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/aidp/harness/usage_limit.rb', line 19

def self.from_config(config)
  return new(enabled: false) unless config.is_a?(Hash)

  new(
    enabled: config[:enabled] == true,
    period: normalize_period(config[:period]),
    reset_day: config[:reset_day] || DEFAULT_RESET_DAY,
    tier_limits: parse_tier_limits(config[:tier_limits]),
    max_tokens: config[:max_tokens],
    max_cost: config[:max_cost]
  )
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Value equality



107
108
109
110
111
112
113
114
115
116
# File 'lib/aidp/harness/usage_limit.rb', line 107

def ==(other)
  return false unless other.is_a?(UsageLimit)

  enabled == other.enabled &&
    period == other.period &&
    reset_day == other.reset_day &&
    tier_limits == other.tier_limits &&
    max_tokens == other.max_tokens &&
    max_cost == other.max_cost
end

#enabled?Boolean

Check if limits are enabled and configured

Returns:

  • (Boolean)


44
45
46
# File 'lib/aidp/harness/usage_limit.rb', line 44

def enabled?
  @enabled
end

#exceeds_limit?(current_tokens:, current_cost:, tier: "standard") ⇒ Hash

Check if usage would exceed limits

Parameters:

  • current_tokens (Integer)

    Current token count

  • current_cost (Float)

    Current cost

  • tier (String) (defaults to: "standard")

    The tier to check against

Returns:

  • (Hash)

    Result with :exceeded boolean and :reason



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/aidp/harness/usage_limit.rb', line 84

def exceeds_limit?(current_tokens:, current_cost:, tier: "standard")
  return {exceeded: false, reason: nil} unless enabled?

  limits = limits_for_tier(tier)

  if limits[:max_tokens] && current_tokens >= limits[:max_tokens]
    return {
      exceeded: true,
      reason: "Token limit exceeded: #{current_tokens}/#{limits[:max_tokens]}"
    }
  end

  if limits[:max_cost] && current_cost >= limits[:max_cost]
    return {
      exceeded: true,
      reason: "Cost limit exceeded: $#{format("%.2f", current_cost)}/$#{format("%.2f", limits[:max_cost])}"
    }
  end

  {exceeded: false, reason: nil}
end

#hashObject



120
121
122
# File 'lib/aidp/harness/usage_limit.rb', line 120

def hash
  [enabled, period, reset_day, tier_limits, max_tokens, max_cost].hash
end

#limits_for_tier(tier) ⇒ Hash

Get limits for a specific tier

Parameters:

  • tier (String, Symbol)

    The tier name (mini, standard, advanced, etc.)

Returns:

  • (Hash)

    Tier-specific limits or global limits



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/aidp/harness/usage_limit.rb', line 52

def limits_for_tier(tier)
  tier_key = tier.to_s.downcase

  # Map thinking tier names to usage limit tiers
  tier_key = case tier_key
  when "thinking", "pro", "max" then "advanced"
  when "standard" then "standard"
  else tier_key
  end

  tier_config = @tier_limits[tier_key] || @tier_limits[tier_key.to_sym]

  if tier_config
    {
      max_tokens: tier_config[:max_tokens],
      max_cost: tier_config[:max_cost]
    }
  else
    # Fall back to global limits
    {
      max_tokens: @max_tokens,
      max_cost: @max_cost
    }
  end
end

#to_hObject

Convert to configuration hash



125
126
127
128
129
130
131
132
133
134
# File 'lib/aidp/harness/usage_limit.rb', line 125

def to_h
  {
    enabled: @enabled,
    period: @period,
    reset_day: @reset_day,
    tier_limits: @tier_limits.transform_values(&:to_h),
    max_tokens: @max_tokens,
    max_cost: @max_cost
  }.compact
end