Module: RubyOpenrouter::Http

Defined in:
lib/ruby_openrouter/http.rb

Class Method Summary collapse

Class Method Details

.connection(config) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruby_openrouter/http.rb', line 9

def self.connection(config)
  Faraday.new(url: config.base_url.chomp("/") + "/") do |conn|
    conn.request  :retry, max: 2, interval: 0.5, retry_statuses: [429, 500, 502, 503]
    conn.request  :json
    conn.response :json
    conn.headers["Authorization"]  = "Bearer #{config.api_key}"
    conn.headers["Content-Type"]   = "application/json"
    conn.headers["HTTP-Referer"]   = config.site_url  if config.site_url
    conn.headers["X-Title"]        = config.site_name if config.site_name
    conn.options.timeout = config.timeout
    conn.adapter Faraday.default_adapter
  end
end

.get(path, config:) ⇒ Object



29
30
31
32
33
# File 'lib/ruby_openrouter/http.rb', line 29

def self.get(path, config:)
  resp = connection(config).get(relative(path))
  handle_error(resp)
  resp.body
end

.post(path, body:, config:) ⇒ Object



23
24
25
26
27
# File 'lib/ruby_openrouter/http.rb', line 23

def self.post(path, body:, config:)
  resp = connection(config).post(relative(path), body)
  handle_error(resp)
  resp.body
end

.stream(path, body:, config:, &block) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ruby_openrouter/http.rb', line 40

def self.stream(path, body:, config:, &block)
  uri = URI.join(config.base_url + "/", path.sub(%r{^/}, ""))
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl     = uri.scheme == "https"
  http.read_timeout = config.timeout

  request = Net::HTTP::Post.new(uri.request_uri)
  request["Authorization"] = "Bearer #{config.api_key}"
  request["Content-Type"]  = "application/json"
  request["HTTP-Referer"]  = config.site_url  if config.site_url
  request["X-Title"]       = config.site_name if config.site_name
  request.body = JSON.generate(body)

  buffer = ""
  http.request(request) do |response|
    raise_for_status(response.code.to_i, nil)
    response.read_body do |raw_chunk|
      buffer += raw_chunk
      while (line_end = buffer.index("\n"))
        line   = buffer.slice!(0..line_end).strip
        buffer = buffer.lstrip
        next unless line.start_with?("data: ")

        payload = line.delete_prefix("data: ")
        next if payload == "[DONE]"

        chunk = JSON.parse(payload) rescue next
        text  = chunk.dig("choices", 0, "delta", "content")
        block.call(text) if text && !text.empty?
      end
    end
  end
end