Class: Zuno::Providers::OpenRouter

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

Constant Summary collapse

CHAT_COMPLETIONS_URL =
"https://openrouter.ai/api/v1/chat/completions".freeze
EMBEDDINGS_URL =
"https://openrouter.ai/api/v1/embeddings".freeze
DEFAULT_TIMEOUT =
120_000

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, app_url: nil, title: nil, timeout: DEFAULT_TIMEOUT) ⇒ OpenRouter

Returns a new instance of OpenRouter.

Raises:



1506
1507
1508
1509
1510
1511
1512
1513
# File 'lib/zuno.rb', line 1506

def initialize(api_key: nil, app_url: nil, title: nil, timeout: DEFAULT_TIMEOUT)
  @api_key = api_key
  raise ProviderError, "OpenRouter API key not configured" if @api_key.nil? || @api_key.to_s.empty?

  @app_url = app_url || "http://localhost"
  @title = title || "zuno-ruby"
  @timeout = timeout
end

Instance Method Details

#chat(payload) ⇒ Object



1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
# File 'lib/zuno.rb', line 1523

def chat(payload)
  response = Typhoeus.post(
    CHAT_COMPLETIONS_URL,
    headers: headers,
    body: JSON.generate(payload),
    timeout: @timeout
  )

  validate_response!(response)
  parsed = JSON.parse(response.body)
  raise ProviderError, "OpenRouter returned invalid JSON" unless parsed.is_a?(Hash)

  parsed
rescue JSON::ParserError => e
  raise ProviderError, "Failed to parse OpenRouter response: #{e.message}"
end

#embed(payload) ⇒ Object



1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
# File 'lib/zuno.rb', line 1540

def embed(payload)
  response = Typhoeus.post(
    EMBEDDINGS_URL,
    headers: headers,
    body: JSON.generate(payload),
    timeout: @timeout
  )

  validate_response!(response)
  parsed = JSON.parse(response.body)
  raise ProviderError, "OpenRouter returned invalid JSON" unless parsed.is_a?(Hash)

  parsed
rescue JSON::ParserError => e
  raise ProviderError, "Failed to parse OpenRouter response: #{e.message}"
end

#model(model_id) ⇒ Object



1515
1516
1517
1518
1519
1520
1521
# File 'lib/zuno.rb', line 1515

def model(model_id)
  ModelDescriptor.new(
    id: model_id,
    provider: :openrouter,
    provider_options: provider_options
  )
end

#stream(payload) ⇒ Object

Raises:

  • (ArgumentError)


1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
# File 'lib/zuno.rb', line 1557

def stream(payload)
  raise ArgumentError, "stream requires a block callback" unless block_given?

  request = Typhoeus::Request.new(
    CHAT_COMPLETIONS_URL,
    method: :post,
    headers: headers,
    body: JSON.generate(payload),
    timeout: @timeout
  )

  parser = SseParser.new { |data| yield(data) }
  request.on_body do |chunk|
    parser.push(chunk)
    nil
  end

  request.run
  validate_response!(request.response)
  parser.flush
end