Skip to content

Commit 3b5fac5

Browse files
committed
Add the ability to configure OpenRouter provider settings
1 parent 4e0c426 commit 3b5fac5

File tree

4 files changed

+102
-3
lines changed

4 files changed

+102
-3
lines changed

docs/configuration.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,15 @@ RubyLLM.configure do |config|
5555
config.ollama_api_base = ENV.fetch('OLLAMA_API_BASE', nil)
5656

5757
# --- Open Router Configuration ---
58-
config.openrouter_referer = 'https://rubyllm.com'
59-
config.openrouter_title = 'RubyLLM'
58+
config.openrouter_referer = 'https://rubyllm.com'
59+
config.openrouter_title = 'RubyLLM'
60+
config.openrouter_provider_order = nil
61+
config.openrouter_provider_allow_fallbacks = true
62+
config.openrouter_provider_require_parameters = false
63+
config.openrouter_provider_data_collection = 'allow'
64+
config.openrouter_provider_ignore = nil
65+
config.openrouter_provider_quantizations = nil
66+
config.openrouter_provider_sort = nil
6067

6168
# --- AWS Bedrock Credentials ---
6269
# Uses standard AWS credential chain (environment, shared config, IAM role)

lib/ruby_llm/configuration.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ class Configuration
2222
:bedrock_secret_key,
2323
:bedrock_region,
2424
:bedrock_session_token,
25+
:ollama_api_base,
26+
# OpenRouter-specific configuration
2527
:openrouter_api_key,
2628
:openrouter_referer,
2729
:openrouter_title,
28-
:ollama_api_base,
30+
:openrouter_provider_order,
31+
:openrouter_provider_allow_fallbacks,
32+
:openrouter_provider_require_parameters,
33+
:openrouter_provider_data_collection,
34+
:openrouter_provider_ignore,
35+
:openrouter_provider_quantizations,
36+
:openrouter_provider_sort,
2937
# Default models
3038
:default_model,
3139
:default_embedding_model,

lib/ruby_llm/providers/openrouter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Providers
55
# OpenRouter API integration.
66
module OpenRouter
77
extend OpenAI
8+
extend OpenRouter::Chat
89
extend OpenRouter::Models
910
extend OpenRouter::Media
1011

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# frozen_string_literal: true
2+
3+
module RubyLLM
4+
module Providers
5+
module OpenRouter
6+
# Chat methods of the OpenRouter API integration
7+
module Chat
8+
def completion_url
9+
'chat/completions'
10+
end
11+
12+
module_function
13+
14+
def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Metrics/MethodLength
15+
{
16+
model: model,
17+
messages: format_messages(messages),
18+
temperature: temperature,
19+
stream: stream,
20+
provider: format_provider_options # @todo Allow for assistant overriding
21+
}.tap do |payload|
22+
if tools.any?
23+
payload[:tools] = tools.map { |_, tool| tool_for(tool) }
24+
payload[:tool_choice] = 'auto'
25+
end
26+
payload[:stream_options] = { include_usage: true } if stream
27+
end
28+
end
29+
30+
def parse_completion_response(response) # rubocop:disable Metrics/MethodLength
31+
data = response.body
32+
return if data.empty?
33+
34+
raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message')
35+
36+
message_data = data.dig('choices', 0, 'message')
37+
return unless message_data
38+
39+
Message.new(
40+
role: :assistant,
41+
content: message_data['content'],
42+
tool_calls: parse_tool_calls(message_data['tool_calls']),
43+
input_tokens: data['usage']['prompt_tokens'],
44+
output_tokens: data['usage']['completion_tokens'],
45+
model_id: data['model']
46+
)
47+
end
48+
49+
def format_messages(messages)
50+
messages.map do |msg|
51+
{
52+
role: format_role(msg.role),
53+
content: self::Media.format_content(msg.content),
54+
tool_calls: format_tool_calls(msg.tool_calls),
55+
tool_call_id: msg.tool_call_id
56+
}.compact
57+
end
58+
end
59+
60+
def format_role(role)
61+
case role
62+
when :system
63+
'developer'
64+
else
65+
role.to_s
66+
end
67+
end
68+
69+
def format_provider_options
70+
{
71+
order: @connection.config.openrouter_provider_order,
72+
allow_fallbacks: @connection.config.openrouter_provider_allow_fallbacks,
73+
require_parameters: @connection.config.openrouter_provider_require_parameters,
74+
data_collection: @connection.config.openrouter_provider_data_collection,
75+
ignore: @connection.config.openrouter_provider_ignore,
76+
quantizations: @connection.config.openrouter_provider_quantizations,
77+
sort: @connection.config.openrouter_provider_sort
78+
}.compact
79+
end
80+
end
81+
end
82+
end
83+
end

0 commit comments

Comments
 (0)