Class: SavvyOpenrouter::ResponsesRetryPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/savvy_openrouter/responses_retry_policy.rb

Overview

Retries for Resources::Responses#create (zero output tokens / selected HTTP errors).

Constant Summary collapse

DEFAULT_ON =
{
  "zero_output_tokens" => true,
  "rate_limit" => true,
  "bad_gateway" => true,
  "internal_server_error" => true,
  "service_unavailable" => true
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(raw) ⇒ ResponsesRetryPolicy

Returns a new instance of ResponsesRetryPolicy.



14
15
16
17
18
19
20
21
22
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 14

def initialize(raw)
  @raw =
    case raw
    when false, nil then {}
    when Hash then Configuration.stringify_keys_static(raw)
    else
      raise ArgumentError, "responses_retries must be a Hash or false"
    end
end

Instance Method Details

#enabled?Boolean

Returns:

  • (Boolean)


30
31
32
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 30

def enabled?
  max_attempts > 1
end

#max_attemptsObject



24
25
26
27
28
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 24

def max_attempts
  n = @raw["max_attempts"]
  i = Integer(n, exception: false)
  i&.positive? ? i : 1
end

#retry_http_error?(error) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 34

def retry_http_error?(error)
  return false unless enabled?
  return false unless error.is_a?(SavvyOpenrouter::ApiError)

  code = error.status_code
  return false unless code

  flag =
    case code
    when 429 then "rate_limit"
    when 502 then "bad_gateway"
    when 500, 501 then "internal_server_error"
    when 503 then "service_unavailable"
    end
  flag ? on?(flag) : false
end

#retry_response?(response) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
55
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 51

def retry_response?(response)
  return false unless enabled?

  on?("zero_output_tokens") && responses_zero_output_retry?(response)
end

#wait_after_attempt(attempt_number) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/savvy_openrouter/responses_retry_policy.rb', line 57

def wait_after_attempt(attempt_number)
  base = integer_opt(@raw["base_delay_ms"], 400)
  max_d = integer_opt(@raw["max_delay_ms"], 10_000)
  exponential = @raw["exponential_backoff"] != false
  jitter_ratio = float_opt(@raw["jitter_ratio"], 0.15)

  delay_ms =
    if exponential
      base * (2**(attempt_number - 1))
    else
      base
    end
  delay_ms = [delay_ms, max_d].min
  jitter = jitter_ratio.clamp(0.0, 1.0) * delay_ms * rand
  sleep((delay_ms + jitter) / 1000.0)
end