boxcars 0.6.5 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 164d55b95e134a691b4525f778a83f6d06cdaa1948028b87371cb6cb8a16fd43
4
- data.tar.gz: 2707ac063bbc1127d75398be8770812ae258447ba021c0b9527cd3fbf113ff02
3
+ metadata.gz: de08261a25297ffb293928ed0f041c23bd40c509becb59a2c959c1a9e29eba15
4
+ data.tar.gz: a9896ba99310815803c7ce4143d959a37f0e2c740675fcc57a87ecb74e1e6f5f
5
5
  SHA512:
6
- metadata.gz: 8b0d7909ef7c049d7c393b646abd072c01dd4b295a7af909bbe2f85fe48b8425c946f956440548fa3902182c636d3e57e81279332d331a9d7c4df4181cd4e4d5
7
- data.tar.gz: ed1c903fb5575ae563ccab8adb0e80cfed9c00e529a5850fc7b89acaf165eecaf42e69cdd548cdec3622855645b5bf88591b3d6a6cb1af47bfbe97d5d6d16ad9
6
+ metadata.gz: a400bcd9c05ee4d81b67340b0edb9612b94406b02c93db6deaf29604a812469798d23256aa180bc76464025a7c26730395e3f3bd2d5d0235210acae0c60bbdbe
7
+ data.tar.gz: 1001cc39c183ae93aa9e8e30fc85679b1bc3ad8a1dc77888a9150ac8ad134d5b595fc94fdf4c68d6e7843bc0be6b1d5690b60263516445e4d6b4fc243b264b93
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.6.5](https://github.com/BoxcarsAI/boxcars/tree/v0.6.5) (2024-10-04)
4
+
5
+ [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.4...v0.6.5)
6
+
7
+ **Closed issues:**
8
+
9
+ - Consider methods to prevent hallucinations and incorrect answers [\#89](https://github.com/BoxcarsAI/boxcars/issues/89)
10
+ - Fix: change SQL Boxcar to use the name of the database in the prompt [\#14](https://github.com/BoxcarsAI/boxcars/issues/14)
11
+
12
+ **Merged pull requests:**
13
+
14
+ - Update ruby [\#217](https://github.com/BoxcarsAI/boxcars/pull/217) ([francis](https://github.com/francis))
15
+ - \[infra\] Bump rubocop-rspec from 3.0.4 to 3.1.0 [\#216](https://github.com/BoxcarsAI/boxcars/pull/216) ([dependabot[bot]](https://github.com/apps/dependabot))
16
+ - \[infra\] Bump pg from 1.5.7 to 1.5.8 [\#214](https://github.com/BoxcarsAI/boxcars/pull/214) ([dependabot[bot]](https://github.com/apps/dependabot))
17
+ - \[infra\] Bump dotenv from 3.1.2 to 3.1.4 [\#213](https://github.com/BoxcarsAI/boxcars/pull/213) ([dependabot[bot]](https://github.com/apps/dependabot))
18
+ - \[infra\] Bump rubocop from 1.65.1 to 1.66.1 [\#212](https://github.com/BoxcarsAI/boxcars/pull/212) ([dependabot[bot]](https://github.com/apps/dependabot))
19
+ - \[infra\] Bump activesupport from 7.1.3.4 to 7.1.4 [\#211](https://github.com/BoxcarsAI/boxcars/pull/211) ([dependabot[bot]](https://github.com/apps/dependabot))
20
+ - \[infra\] Bump activerecord from 7.1.3.4 to 7.1.4 [\#210](https://github.com/BoxcarsAI/boxcars/pull/210) ([dependabot[bot]](https://github.com/apps/dependabot))
21
+ - \[infra\] Bump rexml from 3.3.4 to 3.3.6 [\#209](https://github.com/BoxcarsAI/boxcars/pull/209) ([dependabot[bot]](https://github.com/apps/dependabot))
22
+ - \[infra\] Bump vcr from 6.3.0 to 6.3.1 [\#208](https://github.com/BoxcarsAI/boxcars/pull/208) ([dependabot[bot]](https://github.com/apps/dependabot))
23
+ - \[infra\] Bump vcr from 6.2.0 to 6.3.0 [\#207](https://github.com/BoxcarsAI/boxcars/pull/207) ([dependabot[bot]](https://github.com/apps/dependabot))
24
+ - \[infra\] Bump rubocop-rspec from 3.0.3 to 3.0.4 [\#205](https://github.com/BoxcarsAI/boxcars/pull/205) ([dependabot[bot]](https://github.com/apps/dependabot))
25
+ - \[infra\] Bump rubocop from 1.65.0 to 1.65.1 [\#204](https://github.com/BoxcarsAI/boxcars/pull/204) ([dependabot[bot]](https://github.com/apps/dependabot))
26
+ - \[infra\] Bump nokogiri from 1.16.6 to 1.16.7 [\#202](https://github.com/BoxcarsAI/boxcars/pull/202) ([dependabot[bot]](https://github.com/apps/dependabot))
27
+ - \[infra\] Bump pg from 1.5.6 to 1.5.7 [\#201](https://github.com/BoxcarsAI/boxcars/pull/201) ([dependabot[bot]](https://github.com/apps/dependabot))
28
+
3
29
  ## [v0.6.4](https://github.com/BoxcarsAI/boxcars/tree/v0.6.4) (2024-07-27)
4
30
 
5
31
  [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.3...v0.6.4)
data/Gemfile CHANGED
@@ -11,7 +11,7 @@ gem "dotenv", "~> 3.1"
11
11
 
12
12
  gem "rake", "~> 13.2"
13
13
 
14
- gem "sqlite3", "~> 1.7"
14
+ gem "sqlite3", "~> 2.0"
15
15
 
16
16
  gem "async", "~>1.32.1"
17
17
 
@@ -32,9 +32,9 @@ gem "pgvector", "~> 0.2.2"
32
32
 
33
33
  group :development, :test do
34
34
  gem "rspec", "~> 3.13"
35
- gem "rubocop", "~> 1.66"
35
+ gem "rubocop", "~> 1.67"
36
36
  gem "vcr", "~> 6.3.1"
37
- gem "webmock", "~> 3.23.1"
37
+ gem "webmock", "~> 3.24.0"
38
38
  gem "rubocop-rake", "~> 0.6.0"
39
- gem "rubocop-rspec", "~> 3.1"
39
+ gem "rubocop-rspec", "~> 3.2"
40
40
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boxcars (0.6.5)
4
+ boxcars (0.6.7)
5
5
  anthropic (~> 0.1)
6
6
  google_search_results (~> 2.2)
7
7
  gpt4all (~> 0.0.4)
@@ -13,25 +13,27 @@ PATH
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
- activemodel (7.1.4)
17
- activesupport (= 7.1.4)
18
- activerecord (7.1.4)
19
- activemodel (= 7.1.4)
20
- activesupport (= 7.1.4)
16
+ activemodel (7.2.2)
17
+ activesupport (= 7.2.2)
18
+ activerecord (7.2.2)
19
+ activemodel (= 7.2.2)
20
+ activesupport (= 7.2.2)
21
21
  timeout (>= 0.4.0)
22
- activesupport (7.1.4)
22
+ activesupport (7.2.2)
23
23
  base64
24
+ benchmark (>= 0.3)
24
25
  bigdecimal
25
- concurrent-ruby (~> 1.0, >= 1.0.2)
26
+ concurrent-ruby (~> 1.0, >= 1.3.1)
26
27
  connection_pool (>= 2.2.5)
27
28
  drb
28
29
  i18n (>= 1.6, < 2)
30
+ logger (>= 1.4.2)
29
31
  minitest (>= 5.1)
30
- mutex_m
31
- tzinfo (~> 2.0)
32
+ securerandom (>= 0.3)
33
+ tzinfo (~> 2.0, >= 2.0.5)
32
34
  addressable (2.8.7)
33
35
  public_suffix (>= 2.0.2, < 7.0)
34
- anthropic (0.3.0)
36
+ anthropic (0.3.2)
35
37
  event_stream_parser (>= 0.3.0, < 2.0.0)
36
38
  faraday (>= 1)
37
39
  faraday-multipart (>= 1)
@@ -56,6 +58,7 @@ GEM
56
58
  async-pool (0.7.0)
57
59
  async (>= 1.25)
58
60
  base64 (0.2.0)
61
+ benchmark (0.4.0)
59
62
  bigdecimal (3.1.8)
60
63
  concurrent-ruby (1.3.4)
61
64
  connection_pool (2.4.1)
@@ -74,14 +77,15 @@ GEM
74
77
  dotenv (3.1.4)
75
78
  drb (2.2.1)
76
79
  event_stream_parser (1.0.0)
77
- faraday (2.10.0)
78
- faraday-net_http (>= 2.0, < 3.2)
80
+ faraday (2.12.0)
81
+ faraday-net_http (>= 2.0, < 3.4)
82
+ json
79
83
  logger
80
84
  faraday-http-cache (2.5.1)
81
85
  faraday (>= 0.8)
82
86
  faraday-multipart (1.0.4)
83
87
  multipart-post (~> 2)
84
- faraday-net_http (3.1.1)
88
+ faraday-net_http (3.3.0)
85
89
  net-http
86
90
  faraday-retry (2.2.1)
87
91
  faraday (~> 2.0)
@@ -103,44 +107,43 @@ GEM
103
107
  faraday (~> 2.7)
104
108
  os (~> 1.1)
105
109
  tty-progressbar (~> 0.18.2)
106
- hashdiff (1.1.0)
110
+ hashdiff (1.1.1)
107
111
  hnswlib (0.9.0)
108
112
  http-accept (1.7.0)
109
113
  http-cookie (1.0.6)
110
114
  domain_name (~> 0.5)
111
- i18n (1.14.5)
115
+ i18n (1.14.6)
112
116
  concurrent-ruby (~> 1.0)
113
117
  io-console (0.7.2)
114
118
  irb (1.14.0)
115
119
  rdoc (>= 4.0.0)
116
120
  reline (>= 0.4.2)
117
- json (2.7.2)
121
+ json (2.9.0)
118
122
  language_server-protocol (3.17.0.3)
119
- logger (1.6.0)
123
+ logger (1.6.2)
120
124
  mime-types (3.5.2)
121
125
  mime-types-data (~> 3.2015)
122
126
  mime-types-data (3.2024.0702)
123
- minitest (5.25.1)
127
+ minitest (5.25.4)
124
128
  multi_json (1.15.0)
125
129
  multipart-post (2.4.1)
126
- mutex_m (0.2.0)
127
130
  net-http (0.4.1)
128
131
  uri
129
132
  netrc (0.11.0)
130
133
  nio4r (2.7.3)
131
- nokogiri (1.16.7-arm64-darwin)
134
+ nokogiri (1.16.8-arm64-darwin)
132
135
  racc (~> 1.4)
133
- nokogiri (1.16.7-x86_64-linux)
136
+ nokogiri (1.16.8-x86_64-linux)
134
137
  racc (~> 1.4)
135
138
  octokit (4.25.1)
136
139
  faraday (>= 1, < 3)
137
140
  sawyer (~> 0.9)
138
141
  os (1.1.4)
139
142
  parallel (1.26.3)
140
- parser (3.3.5.0)
143
+ parser (3.3.6.0)
141
144
  ast (~> 2.4.1)
142
145
  racc
143
- pg (1.5.8)
146
+ pg (1.5.9)
144
147
  pgvector (0.2.2)
145
148
  protocol-hpack (1.4.3)
146
149
  protocol-http (0.26.8)
@@ -151,13 +154,13 @@ GEM
151
154
  protocol-http (~> 0.18)
152
155
  psych (5.1.2)
153
156
  stringio
154
- public_suffix (6.0.0)
157
+ public_suffix (6.0.1)
155
158
  racc (1.8.1)
156
159
  rainbow (3.1.1)
157
160
  rake (13.2.1)
158
161
  rdoc (6.7.0)
159
162
  psych (>= 4.0.0)
160
- regexp_parser (2.9.2)
163
+ regexp_parser (2.9.3)
161
164
  reline (0.5.9)
162
165
  io-console (~> 0.5)
163
166
  rest-client (2.1.0)
@@ -165,7 +168,7 @@ GEM
165
168
  http-cookie (>= 1.0.2, < 2.0)
166
169
  mime-types (>= 1.16, < 4.0)
167
170
  netrc (~> 0.8)
168
- rexml (3.3.8)
171
+ rexml (3.3.9)
169
172
  rspec (3.13.0)
170
173
  rspec-core (~> 3.13.0)
171
174
  rspec-expectations (~> 3.13.0)
@@ -179,23 +182,23 @@ GEM
179
182
  diff-lcs (>= 1.2.0, < 2.0)
180
183
  rspec-support (~> 3.13.0)
181
184
  rspec-support (3.13.1)
182
- rubocop (1.66.1)
185
+ rubocop (1.69.1)
183
186
  json (~> 2.3)
184
187
  language_server-protocol (>= 3.17.0)
185
188
  parallel (~> 1.10)
186
189
  parser (>= 3.3.0.2)
187
190
  rainbow (>= 2.2.2, < 4.0)
188
- regexp_parser (>= 2.4, < 3.0)
189
- rubocop-ast (>= 1.32.2, < 2.0)
191
+ regexp_parser (>= 2.9.3, < 3.0)
192
+ rubocop-ast (>= 1.36.2, < 2.0)
190
193
  ruby-progressbar (~> 1.7)
191
- unicode-display_width (>= 2.4.0, < 3.0)
192
- rubocop-ast (1.32.3)
194
+ unicode-display_width (>= 2.4.0, < 4.0)
195
+ rubocop-ast (1.36.2)
193
196
  parser (>= 3.3.1.0)
194
197
  rubocop-rake (0.6.0)
195
198
  rubocop (~> 1.0)
196
- rubocop-rspec (3.1.0)
199
+ rubocop-rspec (3.2.0)
197
200
  rubocop (~> 1.61)
198
- ruby-openai (7.1.0)
201
+ ruby-openai (7.3.1)
199
202
  event_stream_parser (>= 0.3.0, < 2.0.0)
200
203
  faraday (>= 1)
201
204
  faraday-multipart (>= 1)
@@ -203,11 +206,12 @@ GEM
203
206
  sawyer (0.9.2)
204
207
  addressable (>= 2.3.5)
205
208
  faraday (>= 0.17.3, < 3)
206
- sqlite3 (1.7.3-arm64-darwin)
207
- sqlite3 (1.7.3-x86_64-linux)
209
+ securerandom (0.4.0)
210
+ sqlite3 (2.0.4-arm64-darwin)
211
+ sqlite3 (2.0.4-x86_64-linux-gnu)
208
212
  stringio (3.1.1)
209
213
  strings-ansi (0.2.0)
210
- timeout (0.4.1)
214
+ timeout (0.4.2)
211
215
  timers (4.3.5)
212
216
  traces (0.11.1)
213
217
  tty-cursor (0.7.1)
@@ -220,10 +224,10 @@ GEM
220
224
  tzinfo (2.0.6)
221
225
  concurrent-ruby (~> 1.0)
222
226
  unicode-display_width (2.6.0)
223
- uri (0.13.0)
227
+ uri (0.13.1)
224
228
  vcr (6.3.1)
225
229
  base64
226
- webmock (3.23.1)
230
+ webmock (3.24.0)
227
231
  addressable (>= 2.8.0)
228
232
  crack (>= 0.3.2)
229
233
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -249,12 +253,12 @@ DEPENDENCIES
249
253
  rake (~> 13.2)
250
254
  rest-client (~> 2.1)
251
255
  rspec (~> 3.13)
252
- rubocop (~> 1.66)
256
+ rubocop (~> 1.67)
253
257
  rubocop-rake (~> 0.6.0)
254
- rubocop-rspec (~> 3.1)
255
- sqlite3 (~> 1.7)
258
+ rubocop-rspec (~> 3.2)
259
+ sqlite3 (~> 2.0)
256
260
  vcr (~> 6.3.1)
257
- webmock (~> 3.23.1)
261
+ webmock (~> 3.24.0)
258
262
 
259
263
  BUNDLED WITH
260
264
  2.4.16
@@ -45,6 +45,7 @@ module Boxcars
45
45
  # @param anthropic_api_key [String] Optional api key to use when asking the engine.
46
46
  # Defaults to Boxcars.configuration.anthropic_api_key.
47
47
  # @param kwargs [Hash] Additional parameters to pass to the engine if wanted.
48
+ # rubocop:disable Metrics/PerceivedComplexity
48
49
  def client(prompt:, inputs: {}, **kwargs)
49
50
  model_params = llm_params.merge(kwargs)
50
51
  api_key = Boxcars.configuration.anthropic_api_key(**kwargs)
@@ -54,6 +55,9 @@ module Boxcars
54
55
  if conversation_model?(model_params[:model])
55
56
  params = convert_to_anthropic(prompt.as_messages(inputs).merge(model_params))
56
57
  if Boxcars.configuration.log_prompts
58
+ if params[:messages].length < 2 && params[:system].present?
59
+ Boxcars.debug(">>>>>> Role: system <<<<<<\n#{params[:system]}")
60
+ end
57
61
  Boxcars.debug(params[:messages].last(2).map { |p| ">>>>>> Role: #{p[:role]} <<<<<<\n#{p[:content]}" }.join("\n"), :cyan)
58
62
  end
59
63
  response = aclient.messages(parameters: params)
@@ -68,6 +72,7 @@ module Boxcars
68
72
  aclient.complete(parameters: params)
69
73
  end
70
74
  end
75
+ # rubocop:enable Metrics/PerceivedComplexity
71
76
 
72
77
  # get an answer from the engine for a question.
73
78
  # @param question [String] The question to ask the engine.
@@ -50,9 +50,6 @@ module Boxcars
50
50
 
51
51
  # Make the API call
52
52
  response = connection.post { |req| req.body = params.to_json }
53
-
54
- # response_data = JSON.parse(response.body, symbolize_names: true)
55
- # response_data[:text]
56
53
  JSON.parse(response.body, symbolize_names: true)
57
54
  end
58
55
 
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Boxcars - a framework for running a series of tools to get an answer to a question.
4
+ module Boxcars
5
+ # A engine that uses Gemini's API.
6
+ class GeminiAi < Engine
7
+ attr_reader :prompts, :llm_params, :model_kwargs, :batch_size
8
+
9
+ # The default parameters to use when asking the engine.
10
+ DEFAULT_PARAMS = {
11
+ model: "gemini-1.5-flash-latest"
12
+ }.freeze
13
+
14
+ # the default name of the engine
15
+ DEFAULT_NAME = "Google Gemini AI engine"
16
+ # the default description of the engine
17
+ DEFAULT_DESCRIPTION = "useful for when you need to use Google Gemini AI to answer questions. " \
18
+ "You should ask targeted questions"
19
+
20
+ # A engine is the driver for a single tool to run.
21
+ # @param name [String] The name of the engine. Defaults to "OpenAI engine".
22
+ # @param description [String] A description of the engine. Defaults to:
23
+ # useful for when you need to use AI to answer questions. You should ask targeted questions".
24
+ # @param prompts [Array<String>] The prompts to use when asking the engine. Defaults to [].
25
+ def initialize(name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, prompts: [], **kwargs)
26
+ @llm_params = DEFAULT_PARAMS.merge(kwargs)
27
+ @prompts = prompts
28
+ @batch_size = 20
29
+ super(description: description, name: name)
30
+ end
31
+
32
+ def conversation_model?(_model)
33
+ true
34
+ end
35
+
36
+ def chat(params, gemini_api_key)
37
+ raise Boxcars::ConfigurationError('Google AI API key not set') if gemini_api_key.blank?
38
+
39
+ model_string = params.delete(:model_string)
40
+ raise Boxcars::ConfigurationError('Google AI API key not set') if model_string.blank?
41
+
42
+ # Define the API endpoint and parameters
43
+ api_endpoint = "https://generativelanguage.googleapis.com/v1beta/models/#{model_string}:generateContent?key=#{gemini_api_key}"
44
+
45
+ connection = Faraday.new(api_endpoint) do |faraday|
46
+ faraday.request :url_encoded
47
+ faraday.headers['Content-Type'] = 'application/json'
48
+ end
49
+
50
+ # Make the API call
51
+ response = connection.post { |req| req.body = params.to_json }
52
+
53
+ JSON.parse(response.body, symbolize_names: true)
54
+ end
55
+
56
+ # Get an answer from the engine.
57
+ # @param prompt [String] The prompt to use when asking the engine.
58
+ # @param gemini_api_key [String] Optional api key to use when asking the engine.
59
+ # Defaults to Boxcars.configuration.gemini_api_key.
60
+ # @param kwargs [Hash] Additional parameters to pass to the engine if wanted.
61
+ def client(prompt:, inputs: {}, **kwargs)
62
+ api_key = Boxcars.configuration.gemini_api_key(**kwargs)
63
+ option_params = llm_params.merge(kwargs)
64
+ model_string = option_params.delete(:model) || DEFAULT_PARAMS[:model]
65
+ convo = prompt.as_messages(inputs: inputs)
66
+ # Convert conversation to Google Gemini format
67
+ params = to_google_gemini_format(convo[:messages], option_params)
68
+ params[:model_string] = model_string
69
+ Boxcars.debug("Prompt after formatting:#{params[:message]}", :cyan) if Boxcars.configuration.log_prompts
70
+ chat(params, api_key)
71
+ end
72
+
73
+ # get an answer from the engine for a question.
74
+ # @param question [String] The question to ask the engine.
75
+ # @param kwargs [Hash] Additional parameters to pass to the engine if wanted.
76
+ def run(question, **kwargs)
77
+ prompt = Prompt.new(template: question)
78
+ response = client(prompt: prompt, **kwargs)
79
+
80
+ raise Error, "GeminiAI: No response from API" unless response
81
+ raise Error, "GeminiAI: #{response[:error]}" if response[:error]
82
+
83
+ answer = response[:candidates].first[:content][:parts].first[:text]
84
+ Boxcars.debug(response, :yellow)
85
+ answer
86
+ end
87
+
88
+ # Get the default parameters for the engine.
89
+ def default_params
90
+ llm_params
91
+ end
92
+
93
+ # make sure we got a valid response
94
+ # @param response [Hash] The response to check.
95
+ # @param must_haves [Array<String>] The keys that must be in the response. Defaults to %w[choices].
96
+ # @raise [KeyError] if there is an issue with the access token.
97
+ # @raise [ValueError] if the response is not valid.
98
+ def check_response(response, must_haves: %w[completion])
99
+ if response['error']
100
+ code = response.dig('error', 'code')
101
+ msg = response.dig('error', 'message') || 'unknown error'
102
+ raise KeyError, "ANTHOPIC_API_KEY not valid" if code == 'invalid_api_key'
103
+
104
+ raise ValueError, "Gemini error: #{msg}"
105
+ end
106
+
107
+ must_haves.each do |key|
108
+ raise ValueError, "Expecting key #{key} in response" unless response.key?(key)
109
+ end
110
+ end
111
+
112
+ # the engine type
113
+ def engine_type
114
+ "claude"
115
+ end
116
+
117
+ # lookup the context size for a model by name
118
+ # @param modelname [String] The name of the model to lookup.
119
+ def modelname_to_contextsize(_modelname)
120
+ 100000
121
+ end
122
+
123
+ # Calculate the maximum number of tokens possible to generate for a prompt.
124
+ # @param prompt_text [String] The prompt text to use.
125
+ # @return [Integer] the number of tokens possible to generate.
126
+ def max_tokens_for_prompt(prompt_text)
127
+ num_tokens = get_num_tokens(prompt_text)
128
+
129
+ # get max context size for model by name
130
+ max_size = modelname_to_contextsize(model_name)
131
+ max_size - num_tokens
132
+ end
133
+
134
+ def to_google_gemini_format(convo, option_params)
135
+ instructions = convo.shift.last if convo.first && convo.first[:role] == :system
136
+ system_instructions = instructions || "You are a helpful assistant."
137
+
138
+ # Convert conversation history to the format expected by Google
139
+ contents = convo.map { |message| { text: message[:content] } }
140
+
141
+ generation_config = {}
142
+ if option_params.length.positive?
143
+ generation_config.merge!(option_params)
144
+ generation_config[:stopSequences] = [generation_config.delete(:stop)] if generation_config[:stop].present?
145
+ end
146
+
147
+ rv = {
148
+ system_instruction: { parts: { text: system_instructions } }, # System instructions or context
149
+ contents: { parts: contents } # The chat messages
150
+ }
151
+
152
+ rv[:generationConfig] = generation_config if generation_config.length.positive?
153
+ rv
154
+ end
155
+
156
+ def default_prefixes
157
+ { system: "SYSTEM: ", user: "USER: ", assistant: "CHATBOT: ", history: :history }
158
+ end
159
+ end
160
+ end
@@ -79,3 +79,4 @@ require "boxcars/engine/ollama"
79
79
  require "boxcars/engine/openai"
80
80
  require "boxcars/engine/perplexityai"
81
81
  require "boxcars/engine/gpt4all_eng"
82
+ require "boxcars/engine/gemini_ai"
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Boxcars
4
4
  # The current version of the gem.
5
- VERSION = "0.6.5"
5
+ VERSION = "0.6.7"
6
6
  end
@@ -54,7 +54,9 @@ module Boxcars
54
54
  end
55
55
 
56
56
  def xtext(path)
57
+ # rubocop:disable Style/SafeNavigationChainLength
57
58
  rv = xpath(path)&.text&.gsub(/[[:space:]]+/, " ")&.strip
59
+ # rubocop:enable Style/SafeNavigationChainLength
58
60
  return nil if rv.empty?
59
61
 
60
62
  rv
data/lib/boxcars.rb CHANGED
@@ -62,6 +62,11 @@ module Boxcars
62
62
  key_lookup(:groq_api_key, kwargs)
63
63
  end
64
64
 
65
+ # @return [String] The Google AI API key either from arg or env.
66
+ def gemini_api_key(**kwargs)
67
+ key_lookup(:gemini_api_key, kwargs)
68
+ end
69
+
65
70
  private
66
71
 
67
72
  def check_key(key, val)
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.6.5
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francis Sullivan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-10-04 00:00:00.000000000 Z
12
+ date: 2024-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anthropic
@@ -159,6 +159,7 @@ files:
159
159
  - lib/boxcars/engine/anthropic.rb
160
160
  - lib/boxcars/engine/cohere.rb
161
161
  - lib/boxcars/engine/engine_result.rb
162
+ - lib/boxcars/engine/gemini_ai.rb
162
163
  - lib/boxcars/engine/gpt4all_eng.rb
163
164
  - lib/boxcars/engine/groq.rb
164
165
  - lib/boxcars/engine/ollama.rb
@@ -219,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
220
  - !ruby/object:Gem::Version
220
221
  version: '0'
221
222
  requirements: []
222
- rubygems_version: 3.5.20
223
+ rubygems_version: 3.5.23
223
224
  signing_key:
224
225
  specification_version: 4
225
226
  summary: Boxcars is a gem that enables you to create new systems with AI composability.