open_router_enhanced 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/lib/open_router/client.rb +4 -0
- data/lib/open_router/model_registry.rb +12 -24
- data/lib/open_router/responses_response.rb +10 -10
- data/lib/open_router/responses_tool_call.rb +4 -5
- data/lib/open_router/tool_call_base.rb +1 -0
- data/lib/open_router/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d14a6a35444f5f2321779b457bcd3e72bbb6f549faed1271f845a094195a7cc7
|
|
4
|
+
data.tar.gz: 5633d120125f115e56cf00a4da5e6be0d2a16934180fd2c6f9b4088342ea2615
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5abeac77e6a1e81c3151df75b3450841912b74e3326f745eea5000be8f784822df73daaec90e92e928a1745df79a4eb335b1be922cd01c587a8b73c0b3cb391b
|
|
7
|
+
data.tar.gz: b6e344ffd954a89ebe79f7cf42a308f95e6e93569863e0a06ecb4b28d97d16ff6e656284312bb0dd80ad8943c3018f529794e03aa541624aa8f5b040dd1ca4cf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.2.1] - 2025-12-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Memoized `output_id` in `ResponsesToolResult` to ensure consistent IDs across multiple calls
|
|
7
|
+
- Memoized `message_output` and `reasoning_output` finders in `ResponsesResponse` for performance
|
|
8
|
+
|
|
3
9
|
## [1.2.0] - 2025-12-24
|
|
4
10
|
|
|
5
11
|
### Added
|
data/Gemfile.lock
CHANGED
data/lib/open_router/client.rb
CHANGED
|
@@ -9,6 +9,7 @@ require "pry"
|
|
|
9
9
|
module OpenRouter
|
|
10
10
|
class ServerError < StandardError; end
|
|
11
11
|
|
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
|
12
13
|
class Client
|
|
13
14
|
include OpenRouter::HTTP
|
|
14
15
|
|
|
@@ -103,8 +104,10 @@ module OpenRouter
|
|
|
103
104
|
# @param extras [Hash] Optional hash of model-specific parameters to send to the OpenRouter API
|
|
104
105
|
# @param stream [Proc, nil] Optional callable object for streaming
|
|
105
106
|
# @return [Response] The completion response wrapped in a Response object.
|
|
107
|
+
# rubocop:disable Metrics/ParameterLists
|
|
106
108
|
def complete(messages, model: "openrouter/auto", providers: [], transforms: [], plugins: [], tools: [], tool_choice: nil,
|
|
107
109
|
response_format: nil, force_structured_output: nil, prediction: nil, extras: {}, stream: nil)
|
|
110
|
+
# rubocop:enable Metrics/ParameterLists
|
|
108
111
|
parameters = prepare_base_parameters(messages, model, providers, transforms, plugins, prediction, stream, extras)
|
|
109
112
|
forced_extraction = configure_tools_and_structured_outputs!(parameters, model, tools, tool_choice,
|
|
110
113
|
response_format, force_structured_output)
|
|
@@ -666,4 +669,5 @@ module OpenRouter
|
|
|
666
669
|
INSTRUCTION
|
|
667
670
|
end
|
|
668
671
|
end
|
|
672
|
+
# rubocop:enable Metrics/ClassLength
|
|
669
673
|
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
-
require "
|
|
5
|
-
require "uri"
|
|
4
|
+
require "faraday"
|
|
6
5
|
require "tmpdir"
|
|
7
6
|
require "fileutils"
|
|
8
|
-
require "openssl"
|
|
9
7
|
|
|
10
8
|
module OpenRouter
|
|
11
9
|
class ModelRegistryError < Error; end
|
|
@@ -18,30 +16,20 @@ module OpenRouter
|
|
|
18
16
|
MAX_CACHE_SIZE_MB = 50 # Maximum cache size in megabytes
|
|
19
17
|
|
|
20
18
|
class << self
|
|
21
|
-
# Fetch models from OpenRouter API
|
|
19
|
+
# Fetch models from OpenRouter API using Faraday for consistent SSL handling
|
|
22
20
|
def fetch_models_from_api
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
http.use_ssl = true
|
|
28
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
29
|
-
http.read_timeout = OpenRouter.configuration.model_registry_timeout
|
|
30
|
-
http.open_timeout = OpenRouter.configuration.model_registry_timeout
|
|
31
|
-
|
|
32
|
-
request = Net::HTTP::Get.new(uri)
|
|
33
|
-
response = http.request(request)
|
|
34
|
-
|
|
35
|
-
unless response.code == "200"
|
|
36
|
-
raise ModelRegistryError,
|
|
37
|
-
"Failed to fetch models from OpenRouter API: #{response.message}"
|
|
21
|
+
conn = Faraday.new(url: API_BASE) do |f|
|
|
22
|
+
f.options[:timeout] = OpenRouter.configuration.model_registry_timeout
|
|
23
|
+
f.options[:open_timeout] = OpenRouter.configuration.model_registry_timeout
|
|
24
|
+
f.response :raise_error
|
|
38
25
|
end
|
|
39
26
|
|
|
27
|
+
response = conn.get("models")
|
|
40
28
|
JSON.parse(response.body)
|
|
29
|
+
rescue Faraday::Error => e
|
|
30
|
+
raise ModelRegistryError, "Failed to fetch models from OpenRouter API: #{e.message}"
|
|
41
31
|
rescue JSON::ParserError => e
|
|
42
32
|
raise ModelRegistryError, "Failed to parse OpenRouter API response: #{e.message}"
|
|
43
|
-
rescue StandardError => e
|
|
44
|
-
raise ModelRegistryError, "Network error fetching models: #{e.message}"
|
|
45
33
|
end
|
|
46
34
|
|
|
47
35
|
# Ensure cache directory exists and set up cleanup
|
|
@@ -367,9 +355,9 @@ module OpenRouter
|
|
|
367
355
|
total_size = Dir.glob(File.join(CACHE_DIR, "**/*"))
|
|
368
356
|
.select { |f| File.file?(f) }
|
|
369
357
|
.sum do |f|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
358
|
+
File.size(f)
|
|
359
|
+
rescue StandardError
|
|
360
|
+
0
|
|
373
361
|
end
|
|
374
362
|
total_size / (1024.0 * 1024.0)
|
|
375
363
|
end
|
|
@@ -48,9 +48,10 @@ module OpenRouter
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
# Check if reasoning was included in the response
|
|
51
|
-
def
|
|
51
|
+
def reasoning?
|
|
52
52
|
!reasoning_output.nil?
|
|
53
53
|
end
|
|
54
|
+
alias has_reasoning? reasoning?
|
|
54
55
|
|
|
55
56
|
# Get tool/function calls from the response as ResponsesToolCall objects
|
|
56
57
|
#
|
|
@@ -68,9 +69,10 @@ module OpenRouter
|
|
|
68
69
|
output.select { |o| o["type"] == "function_call" }
|
|
69
70
|
end
|
|
70
71
|
|
|
71
|
-
def
|
|
72
|
+
def tool_calls?
|
|
72
73
|
tool_calls.any?
|
|
73
74
|
end
|
|
75
|
+
alias has_tool_calls? tool_calls?
|
|
74
76
|
|
|
75
77
|
# Execute all tool calls and return results
|
|
76
78
|
#
|
|
@@ -137,9 +139,7 @@ module OpenRouter
|
|
|
137
139
|
end
|
|
138
140
|
|
|
139
141
|
# Add assistant message if present
|
|
140
|
-
if message_output
|
|
141
|
-
input_items << message_output
|
|
142
|
-
end
|
|
142
|
+
input_items << message_output if message_output
|
|
143
143
|
|
|
144
144
|
# Add follow-up user message if provided
|
|
145
145
|
if follow_up_message
|
|
@@ -155,15 +155,15 @@ module OpenRouter
|
|
|
155
155
|
|
|
156
156
|
# Token counts
|
|
157
157
|
def input_tokens
|
|
158
|
-
usage
|
|
158
|
+
usage["input_tokens"] || 0
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def output_tokens
|
|
162
|
-
usage
|
|
162
|
+
usage["output_tokens"] || 0
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
def total_tokens
|
|
166
|
-
usage
|
|
166
|
+
usage["total_tokens"] || 0
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
def reasoning_tokens
|
|
@@ -182,11 +182,11 @@ module OpenRouter
|
|
|
182
182
|
private
|
|
183
183
|
|
|
184
184
|
def message_output
|
|
185
|
-
output.find { |o| o["type"] == "message" }
|
|
185
|
+
@message_output ||= output.find { |o| o["type"] == "message" }
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
def reasoning_output
|
|
189
|
-
output.find { |o| o["type"] == "reasoning" }
|
|
189
|
+
@reasoning_output ||= output.find { |o| o["type"] == "reasoning" }
|
|
190
190
|
end
|
|
191
191
|
end
|
|
192
192
|
end
|
|
@@ -18,9 +18,7 @@ module OpenRouter
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Get the function name
|
|
21
|
-
|
|
22
|
-
@name
|
|
23
|
-
end
|
|
21
|
+
attr_reader :name
|
|
24
22
|
|
|
25
23
|
# Alias for consistency with ToolCall
|
|
26
24
|
def function_name
|
|
@@ -56,12 +54,13 @@ module OpenRouter
|
|
|
56
54
|
class ResponsesToolResult
|
|
57
55
|
include ToolResultBase
|
|
58
56
|
|
|
59
|
-
attr_reader :tool_call, :result, :error
|
|
57
|
+
attr_reader :tool_call, :result, :error, :output_id
|
|
60
58
|
|
|
61
59
|
def initialize(tool_call, result = nil, error = nil)
|
|
62
60
|
@tool_call = tool_call
|
|
63
61
|
@result = result
|
|
64
62
|
@error = error
|
|
63
|
+
@output_id = "fc_output_#{SecureRandom.hex(8)}"
|
|
65
64
|
end
|
|
66
65
|
|
|
67
66
|
# Convert to function_call_output format for conversation continuation
|
|
@@ -78,7 +77,7 @@ module OpenRouter
|
|
|
78
77
|
|
|
79
78
|
{
|
|
80
79
|
"type" => "function_call_output",
|
|
81
|
-
"id" =>
|
|
80
|
+
"id" => @output_id,
|
|
82
81
|
"call_id" => @tool_call.call_id,
|
|
83
82
|
"output" => output_content
|
|
84
83
|
}
|
data/lib/open_router/version.rb
CHANGED