Module: PWN::AI::HttpRetry

Defined in:
lib/pwn/ai/http_retry.rb

Overview

Shared REST timeout / 429 / ReadTimeout policy for every AI provider. Default wall clock per attempt is 180s with up to 5 attempts (≈900s total). Short quiet sidecar hops stay single-shot.

Constant Summary collapse

DEFAULT_TIMEOUT_S =
180
DEFAULT_MAX_ATTEMPTS =
5

Class Method Summary collapse

Class Method Details

.authorsObject



58
59
60
# File 'lib/pwn/ai/http_retry.rb', line 58

public_class_method def self.authors
  "AUTHOR(S):\n  0day Inc. <support@0dayinc.com>\n"
end

.helpObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/pwn/ai/http_retry.rb', line 62

public_class_method def self.help
  puts <<~USAGE
    USAGE:
      PWN::AI::HttpRetry.timeout_s(timeout: nil)         # => 180
      PWN::AI::HttpRetry.max_attempts(quiet: false)      # => 5
      PWN::AI::HttpRetry.report_event(
        label: 'grok',
        error: e,
        http_method: :post,
        rest_call: 'chat/completions'
      )
      #{self}.authors
  USAGE
end

.max_attempts(opts = {}) ⇒ Object



19
20
21
22
23
24
25
26
27
28
# File 'lib/pwn/ai/http_retry.rb', line 19

public_class_method def self.max_attempts(opts = {})
  return 1 unless opts.is_a?(Hash)

  n = opts[:max_attempts].to_i
  return n if n.positive?
  return 1 if opts[:quiet]
  return 1 if opts[:timeout].to_i.positive? && opts[:timeout].to_i < DEFAULT_TIMEOUT_S

  DEFAULT_MAX_ATTEMPTS
end

.report_event(opts = {}) ⇒ Object

Tees provider REST events into the open pwn-ai DEBUG RN log and STDERR.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/pwn/ai/http_retry.rb', line 40

public_class_method def self.report_event(opts = {})
  return unless opts.is_a?(Hash)

  label = opts[:label].to_s
  label = 'ai' if label.empty?
  err = opts[:error]
  extra = opts[:extra].to_s
  meth = opts[:http_method].to_s.upcase
  call = opts[:rest_call].to_s
  klass = err ? err.class : 'Error'
  msg = err ? err.message : extra
  line = "[pwn-ai/#{label}] #{klass}: #{msg} (#{meth} #{call} #{extra})".strip
  which = opts[:which_self] || self
  PWN::Plugins::Log.progress(msg: line, which_self: which, cap: 0) if defined?(PWN::Plugins::Log) && PWN::Plugins::Log.debug_enabled?
  warn line unless opts[:quiet]
  line
end

.retry_after_s(opts = {}) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/pwn/ai/http_retry.rb', line 30

public_class_method def self.retry_after_s(opts = {})
  retry_count = [opts[:retry_count].to_i, 1].max
  retry_after = 0
  resp = opts[:response]
  retry_after = resp.headers[:retry_after].to_i if resp.respond_to?(:headers) && resp.headers
  retry_after = (0.5 * retry_count) if retry_after.to_f <= 0
  retry_after
end

.timeout_s(opts = {}) ⇒ Object



12
13
14
15
16
17
# File 'lib/pwn/ai/http_retry.rb', line 12

public_class_method def self.timeout_s(opts = {})
  return DEFAULT_TIMEOUT_S unless opts.is_a?(Hash)

  t = opts[:timeout].to_i
  t.positive? ? t : DEFAULT_TIMEOUT_S
end