boxcars 0.5.1 → 0.6.1

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: 03363b9d82506ac0c784569089c21c605fd76cc0f11fbfdbb05744e1bc330ddd
4
- data.tar.gz: 6fb219328727d9603bd86358a28e3f715e861db57ff74e49c98d94801b960651
3
+ metadata.gz: 71b72b7d30bda72b5dd0b3150773a233eac72e15ab3efa66d7643d5278770793
4
+ data.tar.gz: '080addca8e8c89f982db5ae91d9f12e67db15fb37f58d4787857b209848c1006'
5
5
  SHA512:
6
- metadata.gz: 56c9344b6e8c9fbf07323add0e4b3ee245ff6663331a5fd6db917152f7c2aadb428565988c6d63fdb25f5bf2fac2870f47bcf2e8d8fcd9f22239571ea7ee635e
7
- data.tar.gz: 99f92d94254d6df4260b975642e3d58af6093f024917e3d0e082c8cefd15f94aed879bdc713536f492cb1942d6ffbf52c97b598bb0afa5b26d643c93f3fea132
6
+ metadata.gz: 330aa8094b7069084a7e06c7d656b30bd1935f1e12cfefded4788f23d92c62dbbbb92458328e37b95cbf5e446afd73b9170916329f409490e532ae329ac20a79
7
+ data.tar.gz: 1730d2356b2ddae5e19ee6d0ec0b4b6150eb9a9efb2305863b8e946ccd0184124a3ab22ef6fa37c4cfdacebed7a8fbf520f2d18243f9d05de7f547764d3625ef
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.5.1](https://github.com/BoxcarsAI/boxcars/tree/v0.5.1) (2024-06-14)
4
+
5
+ [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.4.10...v0.5.1)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Fix `Boxcars::SecurityError` error when we have newline [\#192](https://github.com/BoxcarsAI/boxcars/pull/192) ([moustafasallam](https://github.com/moustafasallam))
10
+ - \[infra\] Bump rubocop from 1.64.0 to 1.64.1 [\#190](https://github.com/BoxcarsAI/boxcars/pull/190) ([dependabot[bot]](https://github.com/apps/dependabot))
11
+ - \[infra\] Bump rubocop-rspec from 2.29.1 to 2.30.0 [\#188](https://github.com/BoxcarsAI/boxcars/pull/188) ([dependabot[bot]](https://github.com/apps/dependabot))
12
+ - \[infra\] Bump webmock from 3.23.0 to 3.23.1 [\#186](https://github.com/BoxcarsAI/boxcars/pull/186) ([dependabot[bot]](https://github.com/apps/dependabot))
13
+ - \[infra\] Bump rubocop from 1.60.2 to 1.64.0 [\#183](https://github.com/BoxcarsAI/boxcars/pull/183) ([dependabot[bot]](https://github.com/apps/dependabot))
14
+ - \[infra\] Bump rexml from 3.2.6 to 3.2.8 [\#182](https://github.com/BoxcarsAI/boxcars/pull/182) ([dependabot[bot]](https://github.com/apps/dependabot))
15
+ - \[infra\] Bump nokogiri from 1.16.2 to 1.16.5 [\#181](https://github.com/BoxcarsAI/boxcars/pull/181) ([dependabot[bot]](https://github.com/apps/dependabot))
16
+ - \[infra\] Bump anthropic from 0.1.0 to 0.2.0 [\#180](https://github.com/BoxcarsAI/boxcars/pull/180) ([dependabot[bot]](https://github.com/apps/dependabot))
17
+ - \[infra\] Bump debug from 1.9.1 to 1.9.2 [\#179](https://github.com/BoxcarsAI/boxcars/pull/179) ([dependabot[bot]](https://github.com/apps/dependabot))
18
+ - \[infra\] Bump dotenv from 3.1.0 to 3.1.2 [\#177](https://github.com/BoxcarsAI/boxcars/pull/177) ([dependabot[bot]](https://github.com/apps/dependabot))
19
+ - \[infra\] Bump async from 1.31.0 to 1.32.1 [\#175](https://github.com/BoxcarsAI/boxcars/pull/175) ([dependabot[bot]](https://github.com/apps/dependabot))
20
+ - \[infra\] Update ruby-openai requirement from \>= 4.2, \< 7.0 to \>= 4.2, \< 8.0 [\#174](https://github.com/BoxcarsAI/boxcars/pull/174) ([dependabot[bot]](https://github.com/apps/dependabot))
21
+ - \[infra\] Bump rake from 13.1.0 to 13.2.1 [\#168](https://github.com/BoxcarsAI/boxcars/pull/168) ([dependabot[bot]](https://github.com/apps/dependabot))
22
+
3
23
  ## [v0.4.10](https://github.com/BoxcarsAI/boxcars/tree/v0.4.10) (2024-04-19)
4
24
 
5
25
  [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.4.9...v0.4.10)
@@ -205,7 +225,7 @@
205
225
 
206
226
  - Chore/refactored vector stores [\#92](https://github.com/BoxcarsAI/boxcars/pull/92) ([jaigouk](https://github.com/jaigouk))
207
227
  - Fix the issue of calling the wrong method in vector\_answer.rb. [\#91](https://github.com/BoxcarsAI/boxcars/pull/91) ([xleotranx](https://github.com/xleotranx))
208
- - issue\_83 Fix readme 404 [\#87](https://github.com/BoxcarsAI/boxcars/pull/87) ([beouk](https://github.com/beouk))
228
+ - issue\_83 Fix readme 404 [\#87](https://github.com/BoxcarsAI/boxcars/pull/87) ([ntabernacle](https://github.com/ntabernacle))
209
229
 
210
230
  ## [v0.2.13](https://github.com/BoxcarsAI/boxcars/tree/v0.2.13) (2023-05-24)
211
231
 
data/Gemfile CHANGED
@@ -36,5 +36,5 @@ group :development, :test do
36
36
  gem "vcr", "~> 6.2.0"
37
37
  gem "webmock", "~> 3.23.1"
38
38
  gem "rubocop-rake", "~> 0.6.0"
39
- gem "rubocop-rspec", "~> 2.30"
39
+ gem "rubocop-rspec", "~> 3.0"
40
40
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boxcars (0.5.1)
4
+ boxcars (0.6.1)
5
5
  anthropic (~> 0.1)
6
6
  google_search_results (~> 2.2)
7
7
  gpt4all (~> 0.0.4)
@@ -13,19 +13,26 @@ PATH
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
- activemodel (7.0.7.1)
17
- activesupport (= 7.0.7.1)
18
- activerecord (7.0.7.1)
19
- activemodel (= 7.0.7.1)
20
- activesupport (= 7.0.7.1)
21
- activesupport (7.0.7.1)
16
+ activemodel (7.1.3.4)
17
+ activesupport (= 7.1.3.4)
18
+ activerecord (7.1.3.4)
19
+ activemodel (= 7.1.3.4)
20
+ activesupport (= 7.1.3.4)
21
+ timeout (>= 0.4.0)
22
+ activesupport (7.1.3.4)
23
+ base64
24
+ bigdecimal
22
25
  concurrent-ruby (~> 1.0, >= 1.0.2)
26
+ connection_pool (>= 2.2.5)
27
+ drb
23
28
  i18n (>= 1.6, < 2)
24
29
  minitest (>= 5.1)
30
+ mutex_m
25
31
  tzinfo (~> 2.0)
26
- addressable (2.8.6)
27
- public_suffix (>= 2.0.2, < 6.0)
28
- anthropic (0.2.0)
32
+ addressable (2.8.7)
33
+ public_suffix (>= 2.0.2, < 7.0)
34
+ anthropic (0.3.0)
35
+ event_stream_parser (>= 0.3.0, < 2.0.0)
29
36
  faraday (>= 1)
30
37
  faraday-multipart (>= 1)
31
38
  ast (2.4.2)
@@ -33,26 +40,28 @@ GEM
33
40
  console (~> 1.10)
34
41
  nio4r (~> 2.3)
35
42
  timers (~> 4.1)
36
- async-http (0.61.0)
43
+ async-http (0.64.2)
37
44
  async (>= 1.25)
38
45
  async-io (>= 1.28)
39
46
  async-pool (>= 0.2)
40
- protocol-http (~> 0.25.0)
41
- protocol-http1 (~> 0.16.0)
42
- protocol-http2 (~> 0.15.0)
47
+ protocol-http (~> 0.26.0)
48
+ protocol-http1 (~> 0.19.0)
49
+ protocol-http2 (~> 0.16.0)
43
50
  traces (>= 0.10.0)
44
- async-http-faraday (0.12.0)
51
+ async-http-faraday (0.14.0)
45
52
  async-http (~> 0.42)
46
53
  faraday
47
- async-io (1.35.0)
54
+ async-io (1.43.2)
48
55
  async
49
- async-pool (0.4.0)
56
+ async-pool (0.7.0)
50
57
  async (>= 1.25)
58
+ base64 (0.2.0)
51
59
  bigdecimal (3.1.8)
52
- concurrent-ruby (1.2.2)
53
- console (1.24.0)
60
+ concurrent-ruby (1.3.3)
61
+ connection_pool (2.4.1)
62
+ console (1.27.0)
54
63
  fiber-annotation
55
- fiber-local
64
+ fiber-local (~> 1.1)
56
65
  json
57
66
  crack (1.0.0)
58
67
  bigdecimal
@@ -61,13 +70,14 @@ GEM
61
70
  irb (~> 1.10)
62
71
  reline (>= 0.3.8)
63
72
  diff-lcs (1.5.1)
64
- domain_name (0.5.20190701)
65
- unf (>= 0.0.5, < 1.0.0)
73
+ domain_name (0.6.20240107)
66
74
  dotenv (3.1.2)
75
+ drb (2.2.1)
67
76
  event_stream_parser (1.0.0)
68
- faraday (2.9.0)
77
+ faraday (2.10.0)
69
78
  faraday-net_http (>= 2.0, < 3.2)
70
- faraday-http-cache (2.5.0)
79
+ logger
80
+ faraday-http-cache (2.5.1)
71
81
  faraday (>= 0.8)
72
82
  faraday-multipart (1.0.4)
73
83
  multipart-post (~> 2)
@@ -76,7 +86,9 @@ GEM
76
86
  faraday-retry (2.2.1)
77
87
  faraday (~> 2.0)
78
88
  fiber-annotation (0.2.0)
79
- fiber-local (1.0.0)
89
+ fiber-local (1.1.0)
90
+ fiber-storage
91
+ fiber-storage (0.1.2)
80
92
  github_changelog_generator (1.16.4)
81
93
  activesupport
82
94
  async (>= 1.25.0)
@@ -94,105 +106,98 @@ GEM
94
106
  hashdiff (1.1.0)
95
107
  hnswlib (0.9.0)
96
108
  http-accept (1.7.0)
97
- http-cookie (1.0.5)
109
+ http-cookie (1.0.6)
98
110
  domain_name (~> 0.5)
99
- i18n (1.14.1)
111
+ i18n (1.14.5)
100
112
  concurrent-ruby (~> 1.0)
101
113
  io-console (0.7.2)
102
- irb (1.13.1)
114
+ irb (1.14.0)
103
115
  rdoc (>= 4.0.0)
104
116
  reline (>= 0.4.2)
105
117
  json (2.7.2)
106
118
  language_server-protocol (3.17.0.3)
107
- mime-types (3.4.1)
119
+ logger (1.6.0)
120
+ mime-types (3.5.2)
108
121
  mime-types-data (~> 3.2015)
109
- mime-types-data (3.2023.0218.1)
110
- minitest (5.20.0)
122
+ mime-types-data (3.2024.0702)
123
+ minitest (5.24.1)
111
124
  multi_json (1.15.0)
112
125
  multipart-post (2.4.1)
126
+ mutex_m (0.2.0)
113
127
  net-http (0.4.1)
114
128
  uri
115
129
  netrc (0.11.0)
116
- nio4r (2.7.1)
117
- nokogiri (1.16.5-arm64-darwin)
130
+ nio4r (2.7.3)
131
+ nokogiri (1.16.6-arm64-darwin)
118
132
  racc (~> 1.4)
119
- nokogiri (1.16.5-x86_64-linux)
133
+ nokogiri (1.16.6-x86_64-linux)
120
134
  racc (~> 1.4)
121
135
  octokit (4.25.1)
122
136
  faraday (>= 1, < 3)
123
137
  sawyer (~> 0.9)
124
138
  os (1.1.4)
125
- parallel (1.24.0)
126
- parser (3.3.2.0)
139
+ parallel (1.25.1)
140
+ parser (3.3.4.0)
127
141
  ast (~> 2.4.1)
128
142
  racc
129
143
  pg (1.5.6)
130
144
  pgvector (0.2.2)
131
- protocol-hpack (1.4.2)
132
- protocol-http (0.25.0)
133
- protocol-http1 (0.16.0)
145
+ protocol-hpack (1.4.3)
146
+ protocol-http (0.26.8)
147
+ protocol-http1 (0.19.1)
134
148
  protocol-http (~> 0.22)
135
- protocol-http2 (0.15.1)
149
+ protocol-http2 (0.16.0)
136
150
  protocol-hpack (~> 1.4)
137
151
  protocol-http (~> 0.18)
138
152
  psych (5.1.2)
139
153
  stringio
140
- public_suffix (5.0.5)
154
+ public_suffix (6.0.0)
141
155
  racc (1.8.0)
142
156
  rainbow (3.1.1)
143
157
  rake (13.2.1)
144
- rdoc (6.6.3.1)
158
+ rdoc (6.7.0)
145
159
  psych (>= 4.0.0)
146
160
  regexp_parser (2.9.2)
147
- reline (0.5.6)
161
+ reline (0.5.9)
148
162
  io-console (~> 0.5)
149
163
  rest-client (2.1.0)
150
164
  http-accept (>= 1.7.0, < 2.0)
151
165
  http-cookie (>= 1.0.2, < 2.0)
152
166
  mime-types (>= 1.16, < 4.0)
153
167
  netrc (~> 0.8)
154
- rexml (3.2.8)
155
- strscan (>= 3.0.9)
168
+ rexml (3.3.2)
169
+ strscan
156
170
  rspec (3.13.0)
157
171
  rspec-core (~> 3.13.0)
158
172
  rspec-expectations (~> 3.13.0)
159
173
  rspec-mocks (~> 3.13.0)
160
174
  rspec-core (3.13.0)
161
175
  rspec-support (~> 3.13.0)
162
- rspec-expectations (3.13.0)
176
+ rspec-expectations (3.13.1)
163
177
  diff-lcs (>= 1.2.0, < 2.0)
164
178
  rspec-support (~> 3.13.0)
165
- rspec-mocks (3.13.0)
179
+ rspec-mocks (3.13.1)
166
180
  diff-lcs (>= 1.2.0, < 2.0)
167
181
  rspec-support (~> 3.13.0)
168
182
  rspec-support (3.13.1)
169
- rubocop (1.64.1)
183
+ rubocop (1.65.0)
170
184
  json (~> 2.3)
171
185
  language_server-protocol (>= 3.17.0)
172
186
  parallel (~> 1.10)
173
187
  parser (>= 3.3.0.2)
174
188
  rainbow (>= 2.2.2, < 4.0)
175
- regexp_parser (>= 1.8, < 3.0)
189
+ regexp_parser (>= 2.4, < 3.0)
176
190
  rexml (>= 3.2.5, < 4.0)
177
191
  rubocop-ast (>= 1.31.1, < 2.0)
178
192
  ruby-progressbar (~> 1.7)
179
193
  unicode-display_width (>= 2.4.0, < 3.0)
180
194
  rubocop-ast (1.31.3)
181
195
  parser (>= 3.3.1.0)
182
- rubocop-capybara (2.20.0)
183
- rubocop (~> 1.41)
184
- rubocop-factory_bot (2.25.1)
185
- rubocop (~> 1.41)
186
196
  rubocop-rake (0.6.0)
187
197
  rubocop (~> 1.0)
188
- rubocop-rspec (2.30.0)
189
- rubocop (~> 1.40)
190
- rubocop-capybara (~> 2.17)
191
- rubocop-factory_bot (~> 2.22)
192
- rubocop-rspec_rails (~> 2.28)
193
- rubocop-rspec_rails (2.28.3)
194
- rubocop (~> 1.40)
195
- ruby-openai (7.0.1)
198
+ rubocop-rspec (3.0.3)
199
+ rubocop (~> 1.61)
200
+ ruby-openai (7.1.0)
196
201
  event_stream_parser (>= 0.3.0, < 2.0.0)
197
202
  faraday (>= 1)
198
203
  faraday-multipart (>= 1)
@@ -200,11 +205,12 @@ GEM
200
205
  sawyer (0.9.2)
201
206
  addressable (>= 2.3.5)
202
207
  faraday (>= 0.17.3, < 3)
203
- sqlite3 (1.7.2-arm64-darwin)
204
- sqlite3 (1.7.2-x86_64-linux)
205
- stringio (3.1.0)
208
+ sqlite3 (1.7.3-arm64-darwin)
209
+ sqlite3 (1.7.3-x86_64-linux)
210
+ stringio (3.1.1)
206
211
  strings-ansi (0.2.0)
207
212
  strscan (3.1.0)
213
+ timeout (0.4.1)
208
214
  timers (4.3.5)
209
215
  traces (0.11.1)
210
216
  tty-cursor (0.7.1)
@@ -213,12 +219,9 @@ GEM
213
219
  tty-cursor (~> 0.7)
214
220
  tty-screen (~> 0.8)
215
221
  unicode-display_width (>= 1.6, < 3.0)
216
- tty-screen (0.8.1)
222
+ tty-screen (0.8.2)
217
223
  tzinfo (2.0.6)
218
224
  concurrent-ruby (~> 1.0)
219
- unf (0.1.4)
220
- unf_ext
221
- unf_ext (0.0.8.2)
222
225
  unicode-display_width (2.5.0)
223
226
  uri (0.13.0)
224
227
  vcr (6.2.0)
@@ -249,7 +252,7 @@ DEPENDENCIES
249
252
  rspec (~> 3.13)
250
253
  rubocop (~> 1.64)
251
254
  rubocop-rake (~> 0.6.0)
252
- rubocop-rspec (~> 2.30)
255
+ rubocop-rspec (~> 3.0)
253
256
  sqlite3 (~> 1.7)
254
257
  vcr (~> 6.2.0)
255
258
  webmock (~> 3.23.1)
@@ -48,7 +48,8 @@ module Boxcars
48
48
  "use the following format and we’ll take care of the rest:\n",
49
49
  "${{Question with hard calculation.}}\n",
50
50
  "reply only with the following format:\n",
51
- "```ruby\n${{only Ruby code that prints the answer}}\n```\n",
51
+ "```ruby\n${{only Ruby code that prints the answer. " \
52
+ "If you use puts, make sure to wrap the expression in paranthesis}}\n```\n",
52
53
  "```output\n${{Output of your code}}\n```\n\n",
53
54
  "Otherwise, you should use this simpler format:\n",
54
55
  "${{Question without hard calculation}}\n",
@@ -5,23 +5,27 @@ module Boxcars
5
5
  # For Boxcars that use an engine to do their work.
6
6
  class JSONEngineBoxcar < EngineBoxcar
7
7
  # A JSON Engine Boxcar is a container for a single tool to run.
8
- attr_accessor :wanted_data, :data_description
8
+ attr_accessor :wanted_data, :data_description, :important
9
9
 
10
10
  # @param prompt [Boxcars::Prompt] The prompt to use for this boxcar with sane defaults.
11
11
  # @param wanted_data [String] The data to extract from.
12
12
  # @param data_description [String] The description of the data.
13
+ # @param important [String] Any important instructions you want to give the LLM.
13
14
  # @param kwargs [Hash] Additional arguments
14
- def initialize(prompt: nil, wanted_data: nil, data_description: nil, **kwargs)
15
+ def initialize(prompt: nil, wanted_data: nil, data_description: nil, important: nil, **kwargs)
15
16
  @wanted_data = wanted_data || "summarize the pertinent facts from the input data"
16
17
  @data_description = data_description || "the input data"
18
+ @important = important
17
19
  the_prompt = prompt || default_prompt
20
+ the_prompt.append("\n\nImportant: #{important}\n") if important.present?
18
21
  kwargs[:description] ||= "JSON Engine Boxcar"
19
22
  super(prompt: the_prompt, **kwargs)
20
23
  end
21
24
 
22
25
  def default_prompt
23
26
  stock_prompt = <<~SYSPR
24
- I will provide you with %<data_description>s, and your job is to extract information as described below.
27
+ I will provide you with %<data_description>s.
28
+ Your job is to extract information as described below.
25
29
 
26
30
  Your Output must be valid JSON with no lead in or post answer text in the output format below:
27
31
 
@@ -165,7 +165,8 @@ module Boxcars
165
165
  begin
166
166
  output = call(inputs: inputs)
167
167
  rescue StandardError => e
168
- Boxcars.error "Error in #{name} boxcar#call: #{e}\nbt:#{caller[0..5].join("\n ")}", :red
168
+ Boxcars.error "Error in #{name} boxcar#call: #{e}\nbt:#{e.backtrace[0..5].join("\n ")}", :red
169
+ Boxcars.error("Response Body: #{e.response[:body]}", :red) if e.respond_to?(:response)
169
170
  raise e
170
171
  end
171
172
  validate_outputs(outputs: output.keys)
@@ -20,7 +20,6 @@ module Boxcars
20
20
  raise ArgumentError, "Conversation item must be a array" unless ln.is_a?(Array)
21
21
  raise ArgumentError, "Conversation item must have 2 items, role and text" unless ln.size == 2
22
22
  raise ArgumentError, "Conversation item must have a role #{ln} in (#{PEOPLE})" unless PEOPLE.include? ln[0]
23
- raise ArgumentError, "Conversation value must be a string" unless ln[1].is_a?(String)
24
23
  end
25
24
  end
26
25
 
@@ -112,6 +111,24 @@ module Boxcars
112
111
  raise KeyError, "Prompt format error: #{first_line}"
113
112
  end
114
113
 
114
+ def process_content(content, inputs)
115
+ # If content is a string, treat it as text
116
+ if content.is_a?(String)
117
+ [{ type: "text", text: cformat(content, inputs) }]
118
+ # If content is an array, assume it's already in the new format
119
+ elsif content.is_a?(Array)
120
+ content.map do |item|
121
+ if item[:type] == "text"
122
+ { type: "text", text: cformat(item[:text], inputs) }
123
+ else
124
+ item # Pass through non-text items (like images) without modification
125
+ end
126
+ end
127
+ else
128
+ raise ArgumentError, "Invalid content type: #{content.class}"
129
+ end
130
+ end
131
+
115
132
  # special format that replaces lone percent signs with double percent signs
116
133
  def cformat(*args)
117
134
  args[0] = args[0].dup.gsub(/%(?!<)/, '%%') if args.length > 1
@@ -9,9 +9,9 @@ module Boxcars
9
9
 
10
10
  # The default parameters to use when asking the engine.
11
11
  DEFAULT_PARAMS = {
12
- model: "claude-2",
13
- max_tokens_to_sample: 8096,
14
- temperature: 0.2
12
+ model: "claude-3-5-sonnet-20240620",
13
+ max_tokens: 4096,
14
+ temperature: 0.1
15
15
  }.freeze
16
16
 
17
17
  # the default name of the engine
@@ -32,8 +32,8 @@ module Boxcars
32
32
  super(description: description, name: name)
33
33
  end
34
34
 
35
- def conversation_model?(_model)
36
- false
35
+ def conversation_model?(model)
36
+ @conversation_model ||= (extract_model_version(model) > 3.49)
37
37
  end
38
38
 
39
39
  def anthropic_client(anthropic_api_key: nil)
@@ -46,13 +46,27 @@ module Boxcars
46
46
  # Defaults to Boxcars.configuration.anthropic_api_key.
47
47
  # @param kwargs [Hash] Additional parameters to pass to the engine if wanted.
48
48
  def client(prompt:, inputs: {}, **kwargs)
49
+ model_params = llm_params.merge(kwargs)
49
50
  api_key = Boxcars.configuration.anthropic_api_key(**kwargs)
50
51
  aclient = anthropic_client(anthropic_api_key: api_key)
51
- params = prompt.as_prompt(inputs: inputs, prefixes: default_prefixes, show_roles: true).merge(llm_params.merge(kwargs))
52
- params[:prompt] = "\n\n#{params[:prompt]}" unless params[:prompt].start_with?("\n\n")
53
- params[:stop_sequences] = params.delete(:stop) if params.key?(:stop)
54
- Boxcars.debug("Prompt after formatting:#{params[:prompt]}", :cyan) if Boxcars.configuration.log_prompts
55
- aclient.complete(parameters: params)
52
+ prompt = prompt.first if prompt.is_a?(Array)
53
+
54
+ if conversation_model?(model_params[:model])
55
+ params = convert_to_anthropic(prompt.as_messages(inputs).merge(model_params))
56
+ if Boxcars.configuration.log_prompts
57
+ Boxcars.debug(params[:messages].last(2).map { |p| ">>>>>> Role: #{p[:role]} <<<<<<\n#{p[:content]}" }.join("\n"), :cyan)
58
+ end
59
+ response = aclient.messages(parameters: params)
60
+ response['completion'] = response.dig('content', 0, 'text')
61
+ response.delete('content')
62
+ response
63
+ else
64
+ params = prompt.as_prompt(inputs: inputs, prefixes: default_prefixes, show_roles: true).merge(model_params)
65
+ params[:prompt] = "\n\n#{params[:prompt]}" unless params[:prompt].start_with?("\n\n")
66
+ params[:stop_sequences] = params.delete(:stop) if params.key?(:stop)
67
+ Boxcars.debug("Prompt after formatting:#{params[:prompt]}", :cyan) if Boxcars.configuration.log_prompts
68
+ aclient.complete(parameters: params)
69
+ end
56
70
  end
57
71
 
58
72
  # get an answer from the engine for a question.
@@ -165,6 +179,46 @@ module Boxcars
165
179
  max_size - num_tokens
166
180
  end
167
181
 
182
+ def extract_model_version(model_string)
183
+ # Use a regular expression to find the version number
184
+ match = model_string.match(/claude-(\d+)(?:-(\d+))?/)
185
+
186
+ raise ArgumentError, "No version number found in model string: #{model_string}" unless match
187
+
188
+ major = match[1].to_i
189
+ minor = match[2].to_i
190
+
191
+ # Combine major and minor versions
192
+ major + (minor.to_f / 10)
193
+ end
194
+
195
+ # convert generic parameters to Anthopic specific ones
196
+ def convert_to_anthropic(params)
197
+ params[:stop_sequences] = params.delete(:stop) if params.key?(:stop)
198
+ params[:system] = params[:messages].shift[:content] if params.dig(:messages, 0, :role) == :system
199
+ params[:messages].pop if params[:messages].last[:content].blank?
200
+ combine_assistant(params)
201
+ end
202
+
203
+ def combine_assistant(params)
204
+ params[:messages] = combine_assistant_entries(params[:messages])
205
+ params[:messages].last[:content].rstrip! if params[:messages].last[:role] == :assistant
206
+ params
207
+ end
208
+
209
+ # if we have multiple assistant entries in a row, we need to combine them
210
+ def combine_assistant_entries(hashes)
211
+ combined_hashes = []
212
+ hashes.each do |hash|
213
+ if combined_hashes.empty? || combined_hashes.last[:role] != :assistant || hash[:role] != :assistant
214
+ combined_hashes << hash
215
+ else
216
+ combined_hashes.last[:content].concat("\n", hash[:content].rstrip)
217
+ end
218
+ end
219
+ combined_hashes
220
+ end
221
+
168
222
  def default_prefixes
169
223
  { system: "Human: ", user: "Human: ", assistant: "Assistant: ", history: :history }
170
224
  end
@@ -9,7 +9,7 @@ module Boxcars
9
9
 
10
10
  # The default parameters to use when asking the engine.
11
11
  DEFAULT_PARAMS = {
12
- model: "gpt-4-turbo-preview",
12
+ model: "gpt-4o-mini",
13
13
  temperature: 0.1,
14
14
  max_tokens: 4096
15
15
  }.freeze
@@ -29,7 +29,7 @@ module Boxcars
29
29
  # @param inputs [Hash] The inputs to use for the prompt.
30
30
  # @return [Hash] The formatted prompt { prompt: "..."}
31
31
  def as_messages(inputs)
32
- { messages: [{ role: :assistant, content: format(inputs) }] }
32
+ { messages: [{ role: :user, content: format(inputs) }] }
33
33
  end
34
34
 
35
35
  # tack on the ongoing conversation if present to the prompt
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Boxcars
4
4
  # The current version of the gem.
5
- VERSION = "0.5.1"
5
+ VERSION = "0.6.1"
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.5.1
4
+ version: 0.6.1
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-06-14 00:00:00.000000000 Z
12
+ date: 2024-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anthropic