boxcars 0.8.2 → 0.8.3
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 +8 -0
- data/Gemfile.lock +8 -8
- data/lib/boxcars/engine/gemini_ai.rb +6 -2
- data/lib/boxcars/engine/groq.rb +6 -2
- data/lib/boxcars/engine/openai.rb +2 -0
- data/lib/boxcars/engine.rb +33 -6
- data/lib/boxcars/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: 93e000d3596a656454fb5c76becff8c5d5b4bbb33fe75f91598aceb0526c8d48
|
4
|
+
data.tar.gz: 87d3db350a3faa94cb367fbd600749ed584f0868cd8298469b7bef6c9434e93e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3028c6cbaec10e84597c3a68e2f8f6c88b336b4be50144b04349662afa647d9c266d00debc14c0370bda0bb2150472cf69e347def8fcdc5d3682fc6c2d19512
|
7
|
+
data.tar.gz: 98a10191a8cd96cf85d91f9d5f1f38f07fa29fc7521f55bfd67c500a21fb23b3ef7d4ba7a16df1cc1d35f2a7486fe9ba18f11ab922e288895533ed2197766601
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.8.2](https://github.com/BoxcarsAI/boxcars/tree/v0.8.2) (2025-06-04)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.8.1...v0.8.2)
|
6
|
+
|
7
|
+
## [v0.8.1](https://github.com/BoxcarsAI/boxcars/tree/v0.8.1) (2025-06-03)
|
8
|
+
|
9
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.8.0...v0.8.1)
|
10
|
+
|
3
11
|
## [v0.8.0](https://github.com/BoxcarsAI/boxcars/tree/v0.8.0) (2025-06-03)
|
4
12
|
|
5
13
|
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.7...v0.8.0)
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
boxcars (0.8.
|
4
|
+
boxcars (0.8.3)
|
5
5
|
faraday-retry (~> 2.0)
|
6
6
|
google_search_results (~> 2.2)
|
7
7
|
gpt4all (~> 0.0.5)
|
@@ -56,10 +56,10 @@ GEM
|
|
56
56
|
async (>= 1.25)
|
57
57
|
base64 (0.3.0)
|
58
58
|
benchmark (0.4.1)
|
59
|
-
bigdecimal (3.2.
|
59
|
+
bigdecimal (3.2.2)
|
60
60
|
concurrent-ruby (1.3.5)
|
61
61
|
connection_pool (2.5.3)
|
62
|
-
console (1.
|
62
|
+
console (1.31.0)
|
63
63
|
fiber-annotation
|
64
64
|
fiber-local (~> 1.1)
|
65
65
|
json
|
@@ -74,7 +74,7 @@ GEM
|
|
74
74
|
domain_name (0.6.20240107)
|
75
75
|
dotenv (3.1.8)
|
76
76
|
drb (2.2.3)
|
77
|
-
dynamicschema (1.0.0
|
77
|
+
dynamicschema (1.0.0)
|
78
78
|
erb (5.0.1)
|
79
79
|
event_stream_parser (1.0.0)
|
80
80
|
faraday (2.13.1)
|
@@ -132,7 +132,7 @@ GEM
|
|
132
132
|
mime-types (3.7.0)
|
133
133
|
logger
|
134
134
|
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
135
|
-
mime-types-data (3.2025.
|
135
|
+
mime-types-data (3.2025.0603)
|
136
136
|
minitest (5.25.5)
|
137
137
|
multi_json (1.15.0)
|
138
138
|
multipart-post (2.4.1)
|
@@ -211,7 +211,7 @@ GEM
|
|
211
211
|
diff-lcs (>= 1.2.0, < 2.0)
|
212
212
|
rspec-support (~> 3.13.0)
|
213
213
|
rspec-support (3.13.4)
|
214
|
-
rubocop (1.
|
214
|
+
rubocop (1.76.1)
|
215
215
|
json (~> 2.3)
|
216
216
|
language_server-protocol (~> 3.17.0.2)
|
217
217
|
lint_roller (~> 1.1.0)
|
@@ -219,10 +219,10 @@ GEM
|
|
219
219
|
parser (>= 3.3.0.2)
|
220
220
|
rainbow (>= 2.2.2, < 4.0)
|
221
221
|
regexp_parser (>= 2.9.3, < 3.0)
|
222
|
-
rubocop-ast (>= 1.
|
222
|
+
rubocop-ast (>= 1.45.0, < 2.0)
|
223
223
|
ruby-progressbar (~> 1.7)
|
224
224
|
unicode-display_width (>= 2.4.0, < 4.0)
|
225
|
-
rubocop-ast (1.
|
225
|
+
rubocop-ast (1.45.1)
|
226
226
|
parser (>= 3.3.7.2)
|
227
227
|
prism (~> 1.4)
|
228
228
|
rubocop-rake (0.6.0)
|
@@ -79,12 +79,16 @@ module Boxcars
|
|
79
79
|
)
|
80
80
|
end
|
81
81
|
|
82
|
-
|
82
|
+
# If there's an error, raise it to maintain backward compatibility with existing tests
|
83
|
+
raise response_data[:error] if response_data[:error]
|
84
|
+
|
85
|
+
response_data
|
83
86
|
end
|
84
87
|
|
85
88
|
def run(question, **)
|
86
89
|
prompt = Prompt.new(template: question)
|
87
|
-
|
90
|
+
response_data = client(prompt:, inputs: {}, **)
|
91
|
+
answer = _gemini_handle_call_outcome(response_data:)
|
88
92
|
Boxcars.debug("Answer: #{answer}", :cyan)
|
89
93
|
answer
|
90
94
|
end
|
data/lib/boxcars/engine/groq.rb
CHANGED
@@ -71,12 +71,16 @@ module Boxcars
|
|
71
71
|
)
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
# If there's an error, raise it to maintain backward compatibility with existing tests
|
75
|
+
raise response_data[:error] if response_data[:error]
|
76
|
+
|
77
|
+
response_data
|
75
78
|
end
|
76
79
|
|
77
80
|
def run(question, **)
|
78
81
|
prompt = Prompt.new(template: question)
|
79
|
-
|
82
|
+
response_data = client(prompt:, inputs: {}, **)
|
83
|
+
answer = _groq_handle_call_outcome(response_data:)
|
80
84
|
Boxcars.debug("Answer: #{answer}", :cyan)
|
81
85
|
answer
|
82
86
|
end
|
@@ -128,6 +128,7 @@ module Boxcars
|
|
128
128
|
# Called by Engine#generate to check the response from the client.
|
129
129
|
# @param response [Hash] The parsed JSON response from the OpenAI API.
|
130
130
|
# @raise [Boxcars::Error] if the response contains an error.
|
131
|
+
# rubocop:disable Naming/PredicateMethod
|
131
132
|
def check_response(response)
|
132
133
|
if response.is_a?(Hash) && response["error"]
|
133
134
|
err_details = response["error"]
|
@@ -136,6 +137,7 @@ module Boxcars
|
|
136
137
|
end
|
137
138
|
true
|
138
139
|
end
|
140
|
+
# rubocop:enable Naming/PredicateMethod
|
139
141
|
|
140
142
|
def run(question, **)
|
141
143
|
prompt = Prompt.new(template: question)
|
data/lib/boxcars/engine.rb
CHANGED
@@ -57,12 +57,39 @@ module Boxcars
|
|
57
57
|
# Includes prompt, completion, and total tokens used.
|
58
58
|
inkeys = %w[completion_tokens prompt_tokens total_tokens].freeze
|
59
59
|
prompts.each_slice(batch_size) do |sub_prompts|
|
60
|
-
sub_prompts.each do |
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
sub_prompts.each do |sprompt, inputs|
|
61
|
+
client_response = client(prompt: sprompt, inputs:, **params)
|
62
|
+
|
63
|
+
# Handle different response formats:
|
64
|
+
# - New format: response_data hash with :parsed_json key (Groq, Gemini)
|
65
|
+
# - Legacy format: direct API response hash (OpenAI, others)
|
66
|
+
api_response_hash = if client_response.is_a?(Hash) && client_response.key?(:parsed_json)
|
67
|
+
client_response[:parsed_json]
|
68
|
+
else
|
69
|
+
client_response
|
70
|
+
end
|
71
|
+
|
72
|
+
# Ensure we have a hash to work with
|
73
|
+
unless api_response_hash.is_a?(Hash)
|
74
|
+
raise TypeError, "Expected Hash from client method, got #{api_response_hash.class}: #{api_response_hash.inspect}"
|
75
|
+
end
|
76
|
+
|
77
|
+
check_response(api_response_hash)
|
78
|
+
|
79
|
+
current_choices = api_response_hash["choices"]
|
80
|
+
if current_choices.is_a?(Array)
|
81
|
+
choices.concat(current_choices)
|
82
|
+
else
|
83
|
+
Boxcars.logger&.warn "No 'choices' found in API response: #{api_response_hash.inspect}"
|
84
|
+
end
|
85
|
+
|
86
|
+
api_usage = api_response_hash["usage"]
|
87
|
+
if api_usage.is_a?(Hash)
|
88
|
+
usage_keys = inkeys & api_usage.keys
|
89
|
+
usage_keys.each { |key| token_usage[key] = token_usage[key].to_i + api_usage[key] }
|
90
|
+
else
|
91
|
+
Boxcars.logger&.warn "No 'usage' data found in API response: #{api_response_hash.inspect}"
|
92
|
+
end
|
66
93
|
end
|
67
94
|
end
|
68
95
|
|
data/lib/boxcars/version.rb
CHANGED