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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 842e02d2d8d43ea2a989c5a0b5708022443cf532d7616ab4319a063705f808fa
4
- data.tar.gz: 0c3349ae1dc50be9984bd440c520a74f2f972151338f1ff23aca5bc47d56837c
3
+ metadata.gz: 93e000d3596a656454fb5c76becff8c5d5b4bbb33fe75f91598aceb0526c8d48
4
+ data.tar.gz: 87d3db350a3faa94cb367fbd600749ed584f0868cd8298469b7bef6c9434e93e
5
5
  SHA512:
6
- metadata.gz: 68c3560e8e67c59f711c6433ba5950b48e5ecc0d955b039280399c81baf26361bb659eae89660f2180064b8a2ec7cf799bf0950b42cb5bc8c28b224fa6eb6c53
7
- data.tar.gz: 9f2538a7659b6ab4f236f23fbecb0a594f0ad0778e82b4fc634a2179e355fb40fb5f9ec54f6b9df6cda558a93ca5d2522c950ed8fe454d800cea1db16f5b72ba
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.2)
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.1)
59
+ bigdecimal (3.2.2)
60
60
  concurrent-ruby (1.3.5)
61
61
  connection_pool (2.5.3)
62
- console (1.30.2)
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.beta04)
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.0527)
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.75.8)
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.44.0, < 2.0)
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.44.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
- _gemini_handle_call_outcome(response_data:)
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
- answer = client(prompt:, inputs: {}, **)
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
@@ -71,12 +71,16 @@ module Boxcars
71
71
  )
72
72
  end
73
73
 
74
- _groq_handle_call_outcome(response_data:)
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
- answer = client(prompt:, inputs: {}, **)
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)
@@ -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 |sprompts, inputs|
61
- response = client(prompt: sprompts, inputs:, **params)
62
- check_response(response)
63
- choices.concat(response["choices"])
64
- usage_keys = inkeys & response["usage"].keys
65
- usage_keys.each { |key| token_usage[key] = token_usage[key].to_i + response["usage"][key] }
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
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Boxcars
4
4
  # The current version of the gem.
5
- VERSION = "0.8.2"
5
+ VERSION = "0.8.3"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boxcars
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francis Sullivan