boxcars 0.6.9 → 0.7.1

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: a058c8e9111ba8c7b3e29d25c6f9226f87c862c4b10b26c3c05f8a69dbe7659c
4
- data.tar.gz: 718546be88153f0f26ba932811e30fa9f8c3a467ac029a76c88d554912640b29
3
+ metadata.gz: f737b8f862a6054265b74b7705a9779d301ceba197737c5b85aed4fc96733867
4
+ data.tar.gz: ffb896560aab128f2bcf685082755ce6400174d38b7d8b5294feea51808d0e17
5
5
  SHA512:
6
- metadata.gz: baf4a36fbb72e064f110576f73945d276794b7f235935d9dc0797460ac3a641439ff29e7e650c93d468e9a70a0f148d0fabde6724cc82b7c3cd05df2020974cd
7
- data.tar.gz: 85e40690235ed5e13daa9a326cfef6dae29cd882a18716913a264026fed46cde355ea50c01703aac26da5b77ac3aefc22eaa7eb2583b12485840b32d45f1c94b
6
+ metadata.gz: 2f9afcd76b2efda7fc9f35f2ae02882256a03f935d8a94a10149daa10ad8180c5d91db34e11296310074a1ec9d5d4863a10e74ddc41b19cd9d250d2da64bdff2
7
+ data.tar.gz: 17860c296d8cb4a167e4e4bc58835b3bb9da867bb65e38b89cc08d884f88bf09707bc64b4a36195848d7ee995592c4f32ede29752744a7dee4135dd90338285f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.6.9](https://github.com/BoxcarsAI/boxcars/tree/v0.6.9) (2024-12-19)
4
+
5
+ [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.8...v0.6.9)
6
+
7
+ ## [v0.6.8](https://github.com/BoxcarsAI/boxcars/tree/v0.6.8) (2024-12-07)
8
+
9
+ [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.7...v0.6.8)
10
+
3
11
  ## [v0.6.7](https://github.com/BoxcarsAI/boxcars/tree/v0.6.7) (2024-12-04)
4
12
 
5
13
  [Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.6...v0.6.7)
data/Gemfile.lock CHANGED
@@ -1,14 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boxcars (0.6.9)
5
- anthropic (~> 0.1)
4
+ boxcars (0.7.1)
5
+ anthropic (~> 0.3)
6
6
  google_search_results (~> 2.2)
7
- gpt4all (~> 0.0.4)
8
- hnswlib (~> 0.8)
9
- nokogiri (~> 1.16)
7
+ gpt4all (~> 0.0.5)
8
+ hnswlib (~> 0.9)
9
+ intelligence (>= 0.8)
10
+ nokogiri (~> 1.18)
10
11
  pgvector (~> 0.2)
11
- ruby-openai (>= 7.1, < 8.0)
12
+ ruby-openai (>= 7.3)
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
@@ -60,9 +61,9 @@ GEM
60
61
  traces
61
62
  base64 (0.2.0)
62
63
  benchmark (0.4.0)
63
- bigdecimal (3.1.8)
64
- concurrent-ruby (1.3.4)
65
- connection_pool (2.4.1)
64
+ bigdecimal (3.1.9)
65
+ concurrent-ruby (1.3.5)
66
+ connection_pool (2.5.0)
66
67
  console (1.29.2)
67
68
  fiber-annotation
68
69
  fiber-local (~> 1.1)
@@ -78,6 +79,7 @@ GEM
78
79
  domain_name (0.6.20240107)
79
80
  dotenv (3.1.7)
80
81
  drb (2.2.1)
82
+ dynamicschema (1.0.0.beta04)
81
83
  event_stream_parser (1.0.0)
82
84
  faraday (2.12.2)
83
85
  faraday-net_http (>= 2.0, < 3.5)
@@ -116,17 +118,23 @@ GEM
116
118
  domain_name (~> 0.5)
117
119
  i18n (1.14.6)
118
120
  concurrent-ruby (~> 1.0)
121
+ intelligence (0.8.0)
122
+ dynamicschema (~> 1.0.0.beta03)
123
+ faraday (~> 2.7)
124
+ json-repair (~> 0.2)
125
+ mime-types (~> 3.6)
119
126
  io-console (0.8.0)
120
127
  irb (1.14.3)
121
128
  rdoc (>= 4.0.0)
122
129
  reline (>= 0.4.2)
123
130
  json (2.9.1)
131
+ json-repair (0.2.0)
124
132
  language_server-protocol (3.17.0.3)
125
- logger (1.6.4)
133
+ logger (1.6.5)
126
134
  mime-types (3.6.0)
127
135
  logger
128
136
  mime-types-data (~> 3.2015)
129
- mime-types-data (3.2024.1203)
137
+ mime-types-data (3.2025.0107)
130
138
  minitest (5.25.4)
131
139
  multi_json (1.15.0)
132
140
  multipart-post (2.4.1)
@@ -134,16 +142,28 @@ GEM
134
142
  uri
135
143
  netrc (0.11.0)
136
144
  nio4r (2.7.4)
137
- nokogiri (1.17.2-arm64-darwin)
145
+ nokogiri (1.18.1-aarch64-linux-gnu)
146
+ racc (~> 1.4)
147
+ nokogiri (1.18.1-aarch64-linux-musl)
148
+ racc (~> 1.4)
149
+ nokogiri (1.18.1-arm-linux-gnu)
150
+ racc (~> 1.4)
151
+ nokogiri (1.18.1-arm-linux-musl)
152
+ racc (~> 1.4)
153
+ nokogiri (1.18.1-arm64-darwin)
154
+ racc (~> 1.4)
155
+ nokogiri (1.18.1-x86_64-darwin)
156
+ racc (~> 1.4)
157
+ nokogiri (1.18.1-x86_64-linux-gnu)
138
158
  racc (~> 1.4)
139
- nokogiri (1.17.2-x86_64-linux)
159
+ nokogiri (1.18.1-x86_64-linux-musl)
140
160
  racc (~> 1.4)
141
161
  octokit (4.25.1)
142
162
  faraday (>= 1, < 3)
143
163
  sawyer (~> 0.9)
144
164
  os (1.1.4)
145
165
  parallel (1.26.3)
146
- parser (3.3.6.0)
166
+ parser (3.3.7.0)
147
167
  ast (~> 2.4.1)
148
168
  racc
149
169
  pg (1.5.9)
@@ -155,16 +175,16 @@ GEM
155
175
  protocol-http2 (0.16.0)
156
176
  protocol-hpack (~> 1.4)
157
177
  protocol-http (~> 0.18)
158
- psych (5.2.2)
178
+ psych (5.2.3)
159
179
  date
160
180
  stringio
161
181
  public_suffix (6.0.1)
162
182
  racc (1.8.1)
163
183
  rainbow (3.1.1)
164
184
  rake (13.2.1)
165
- rdoc (6.10.0)
185
+ rdoc (6.11.0)
166
186
  psych (>= 4.0.0)
167
- regexp_parser (2.9.3)
187
+ regexp_parser (2.10.0)
168
188
  reline (0.6.0)
169
189
  io-console (~> 0.5)
170
190
  rest-client (2.1.0)
@@ -186,7 +206,7 @@ GEM
186
206
  diff-lcs (>= 1.2.0, < 2.0)
187
207
  rspec-support (~> 3.13.0)
188
208
  rspec-support (3.13.2)
189
- rubocop (1.69.2)
209
+ rubocop (1.70.0)
190
210
  json (~> 2.3)
191
211
  language_server-protocol (>= 3.17.0)
192
212
  parallel (~> 1.10)
@@ -211,8 +231,14 @@ GEM
211
231
  addressable (>= 2.3.5)
212
232
  faraday (>= 0.17.3, < 3)
213
233
  securerandom (0.4.1)
214
- sqlite3 (2.4.1-arm64-darwin)
215
- sqlite3 (2.4.1-x86_64-linux-gnu)
234
+ sqlite3 (2.5.0-aarch64-linux-gnu)
235
+ sqlite3 (2.5.0-aarch64-linux-musl)
236
+ sqlite3 (2.5.0-arm-linux-gnu)
237
+ sqlite3 (2.5.0-arm-linux-musl)
238
+ sqlite3 (2.5.0-arm64-darwin)
239
+ sqlite3 (2.5.0-x86_64-darwin)
240
+ sqlite3 (2.5.0-x86_64-linux-gnu)
241
+ sqlite3 (2.5.0-x86_64-linux-musl)
216
242
  stringio (3.1.2)
217
243
  strings-ansi (0.2.0)
218
244
  timeout (0.4.3)
@@ -237,10 +263,14 @@ GEM
237
263
  hashdiff (>= 0.4.0, < 2.0.0)
238
264
 
239
265
  PLATFORMS
240
- arm64-darwin-22
241
- arm64-darwin-23
242
- arm64-darwin-24
243
- x86_64-linux
266
+ aarch64-linux-gnu
267
+ aarch64-linux-musl
268
+ arm-linux-gnu
269
+ arm-linux-musl
270
+ arm64-darwin
271
+ x86_64-darwin
272
+ x86_64-linux-gnu
273
+ x86_64-linux-musl
244
274
 
245
275
  DEPENDENCIES
246
276
  activerecord (~> 7.1)
@@ -265,4 +295,4 @@ DEPENDENCIES
265
295
  webmock (~> 3.24.0)
266
296
 
267
297
  BUNDLED WITH
268
- 2.4.16
298
+ 2.5.23
data/boxcars.gemspec CHANGED
@@ -31,13 +31,14 @@ Gem::Specification.new do |spec|
31
31
  spec.require_paths = ["lib"]
32
32
 
33
33
  # runtime dependencies
34
- spec.add_dependency "anthropic", "~> 0.1"
34
+ spec.add_dependency "anthropic", "~> 0.3"
35
35
  spec.add_dependency "google_search_results", "~> 2.2"
36
- spec.add_dependency "gpt4all", "~> 0.0.4"
37
- spec.add_dependency "hnswlib", "~> 0.8"
38
- spec.add_dependency "nokogiri", "~> 1.16"
36
+ spec.add_dependency "gpt4all", "~> 0.0.5"
37
+ spec.add_dependency "hnswlib", "~> 0.9"
38
+ spec.add_dependency "intelligence", ">= 0.8"
39
+ spec.add_dependency "nokogiri", "~> 1.18"
39
40
  spec.add_dependency "pgvector", "~> 0.2"
40
- spec.add_dependency "ruby-openai", ">= 7.1", "< 8.0"
41
+ spec.add_dependency "ruby-openai", ">= 7.3"
41
42
 
42
43
  # For more information and examples about making a new gem, checkout our
43
44
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -95,6 +95,20 @@ module Boxcars
95
95
  raise KeyError, "Prompt format error: #{first_line}"
96
96
  end
97
97
 
98
+ def as_intelligence_conversation(inputs = nil)
99
+ conversation = Intelligence::Conversation.new
100
+ no_history.each do |ln|
101
+ message = Intelligence::Message.new(ln[0])
102
+ message << Intelligence::MessageContent::Text.new(text: cformat(ln.last, inputs))
103
+ conversation.messages << message
104
+ end
105
+ conversation
106
+ rescue ::KeyError => e
107
+ first_line = e.message.to_s.split("\n").first
108
+ Boxcars.error "Missing prompt input key: #{first_line}"
109
+ raise KeyError, "Prompt format error: #{first_line}"
110
+ end
111
+
98
112
  # compute the prompt parameters with input substitutions
99
113
  # @param inputs [Hash] The inputs to use for the prompt.
100
114
  # @return [Hash] The formatted prompt { prompt: "..."}
@@ -51,5 +51,12 @@ module Boxcars
51
51
  def default_prefixes
52
52
  conversation.default_prefixes
53
53
  end
54
+
55
+ # Convert the prompt to an Intelligence::Conversation
56
+ # @param inputs [Hash] The inputs to use for the prompt
57
+ # @return [Intelligence::Conversation] The converted conversation
58
+ def as_intelligence_conversation(inputs: nil)
59
+ conversation.to_intelligence_conversation(inputs: inputs)
60
+ end
54
61
  end
55
62
  end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "intelligence"
4
+ module Boxcars
5
+ # A engine that uses Cerebras's API
6
+ class Cerebras < Engine
7
+ attr_reader :prompts, :cerebras_params, :model_kwargs, :batch_size
8
+
9
+ # The default parameters to use when asking the engine
10
+ DEFAULT_PARAMS = {
11
+ model: "llama-3.3-70b",
12
+ temperature: 0.1
13
+ }.freeze
14
+
15
+ # the default name of the engine
16
+ DEFAULT_NAME = "Cerebras engine"
17
+ # the default description of the engine
18
+ DEFAULT_DESCRIPTION = "useful for when you need to use Cerebras to process complex content. " \
19
+ "Supports text, images, and other content types"
20
+
21
+ def initialize(name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, prompts: [], batch_size: 20, **kwargs)
22
+ @cerebras_params = DEFAULT_PARAMS.merge(kwargs)
23
+ @prompts = prompts
24
+ @batch_size = batch_size
25
+ super(description: description, name: name)
26
+ end
27
+
28
+ # Get the Cerebras API client
29
+ def self.adapter(params:, api_key: nil)
30
+ api_key = Boxcars.configuration.cerebras_api_key(**params) if api_key.nil?
31
+ raise ArgumentError, "Cerebras API key not configured" unless api_key
32
+
33
+ Intelligence::Adapter[:cerebras].new(
34
+ { key: api_key, chat_options: params }
35
+ )
36
+ end
37
+
38
+ # Process different content types
39
+ def process_content(content)
40
+ case content
41
+ when String
42
+ { type: "text", text: content }
43
+ when Hash
44
+ validate_content(content)
45
+ when Array
46
+ content.map { |c| process_content(c) }
47
+ else
48
+ raise ArgumentError, "Unsupported content type: #{content.class}"
49
+ end
50
+ end
51
+
52
+ # Validate content structure
53
+ def validate_content(content)
54
+ raise ArgumentError, "Content must have type and text fields" unless content[:type] && content[:text]
55
+
56
+ content
57
+ end
58
+
59
+ # Get an answer from the engine
60
+ def client(prompt:, inputs: {}, api_key: nil, **kwargs)
61
+ params = cerebras_params.merge(kwargs)
62
+ adapter = Cerebras.adapter(api_key: api_key, params: params)
63
+ raise Error, "OpenAI: No response from API" unless adapter
64
+
65
+ convo = prompt.as_intelligence_conversation(inputs: inputs)
66
+
67
+ # Add content processing
68
+ Boxcars.debug("Sending to Cerebras:\n#{convo}", :cyan) if Boxcars.configuration.log_prompts
69
+
70
+ # Make API call
71
+ request = Intelligence::ChatRequest.new(adapter: adapter)
72
+ response = request.chat(convo)
73
+ check_response(response)
74
+ rescue StandardError => e
75
+ Boxcars.error("Cerebras Error: #{e.message}", :red)
76
+ raise
77
+ end
78
+
79
+ # Run the engine with a question
80
+ def run(question, **kwargs)
81
+ prompt = Prompt.new(template: question)
82
+ response = client(prompt: prompt, **kwargs)
83
+ extract_answer(response)
84
+ end
85
+
86
+ private
87
+
88
+ def extract_answer(response)
89
+ # Handle different response formats
90
+ if response["choices"]
91
+ response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
92
+ else
93
+ response["output"] || response.to_s
94
+ end
95
+ end
96
+
97
+ def check_response(response)
98
+ return response.result.text if response.success?
99
+
100
+ raise KeyError, "CEREBRAS_API_KEY not valid" if response&.reason_phrase == "Unauthorized"
101
+
102
+ raise ValueError, "Cerebras error: #{response&.reason_phrase&.present? ? response.reason_phrase : response}"
103
+ end
104
+
105
+ def conversation_model?(_model)
106
+ true
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Boxcars
4
+ class Intelligence
5
+ # Client for interacting with the Intelligence API
6
+ class Client
7
+ BASE_URL = "https://api.intelligence.com/v1"
8
+ DEFAULT_TIMEOUT = 120
9
+
10
+ def initialize(api_key:)
11
+ @api_key = api_key
12
+ @connection = Faraday.new(
13
+ url: BASE_URL,
14
+ headers: {
15
+ "Content-Type" => "application/json",
16
+ "Authorization" => "Bearer #{@api_key}"
17
+ },
18
+ request: {
19
+ timeout: DEFAULT_TIMEOUT
20
+ }
21
+ )
22
+ end
23
+
24
+ # Generate a response from the Intelligence API
25
+ def generate(parameters:)
26
+ response = @connection.post("/generate") do |req|
27
+ req.body = parameters.to_json
28
+ end
29
+
30
+ handle_response(response)
31
+ end
32
+
33
+ # Stream a response from the Intelligence API
34
+ def stream(parameters:, &block)
35
+ @connection.post("/generate") do |req|
36
+ req.options.on_data = block
37
+ req.headers["Accept"] = "text/event-stream"
38
+ req.body = parameters.to_json
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def handle_response(response)
45
+ case response.status
46
+ when 200
47
+ JSON.parse(response.body)
48
+ when 401
49
+ raise KeyError, "Invalid API key"
50
+ when 429
51
+ raise ValueError, "Rate limit exceeded"
52
+ when 400..499
53
+ raise ArgumentError, "Bad request: #{response.body}"
54
+ when 500..599
55
+ raise Error, "Intelligence API server error"
56
+ else
57
+ raise Error, "Unexpected response: #{response.status}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Boxcars
4
+ # A engine that uses Intelligence's API
5
+ class Intelligence < Engine
6
+ attr_reader :prompts, :intelligence_params, :model_kwargs, :batch_size
7
+
8
+ # The default parameters to use when asking the engine
9
+ DEFAULT_PARAMS = {
10
+ model: "intelligence-1.0",
11
+ temperature: 0.1
12
+ }.freeze
13
+
14
+ # the default name of the engine
15
+ DEFAULT_NAME = "Intelligence engine"
16
+ # the default description of the engine
17
+ DEFAULT_DESCRIPTION = "useful for when you need to use Intelligence to process complex content. " \
18
+ "Supports text, images, and other content types"
19
+
20
+ def initialize(name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, prompts: [], batch_size: 20, **kwargs)
21
+ begin
22
+ require 'intelligence'
23
+ rescue LoadError => _e
24
+ raise LoadError,
25
+ "The intelligence gem is required. Please add 'gem \"intelligence\"' to your Gemfile and run bundle install"
26
+ end
27
+
28
+ @intelligence_params = DEFAULT_PARAMS.merge(kwargs)
29
+ @prompts = prompts
30
+ @batch_size = batch_size
31
+ super(description: description, name: name)
32
+ end
33
+
34
+ # Get the Intelligence API client
35
+ def self.intelligence_client(api_key: nil)
36
+ api_key ||= Boxcars.configuration.intelligence_api_key
37
+ raise ArgumentError, "Intelligence API key not configured" unless api_key
38
+
39
+ Client.new(api_key: api_key)
40
+ end
41
+
42
+ # Stream responses from the Intelligence API
43
+ def stream(prompt:, inputs: {}, api_key: nil, &block)
44
+ client = Intelligence.intelligence_client(api_key: api_key)
45
+ params = intelligence_params.merge(stream: true)
46
+
47
+ processed_prompt = if conversation_model?(params[:model])
48
+ prompt.as_messages(inputs)
49
+ else
50
+ { prompt: prompt.as_prompt(inputs: inputs) }
51
+ end
52
+
53
+ processed_prompt[:content] = process_content(processed_prompt[:content]) if processed_prompt[:content]
54
+
55
+ client.stream(parameters: params.merge(processed_prompt), &block)
56
+ end
57
+
58
+ # Process different content types
59
+ def process_content(content)
60
+ case content
61
+ when String
62
+ { type: "text", text: content }
63
+ when Hash
64
+ validate_content(content)
65
+ when Array
66
+ content.map { |c| process_content(c) }
67
+ else
68
+ raise ArgumentError, "Unsupported content type: #{content.class}"
69
+ end
70
+ end
71
+
72
+ # Validate content structure
73
+ def validate_content(content)
74
+ raise ArgumentError, "Content must have type and text fields" unless content[:type] && content[:text]
75
+
76
+ content
77
+ end
78
+
79
+ # Get an answer from the engine
80
+ def client(prompt:, inputs: {}, api_key: nil, **kwargs)
81
+ client = Intelligence.intelligence_client(api_key: api_key)
82
+ params = intelligence_params.merge(kwargs)
83
+
84
+ processed_prompt = if conversation_model?(params[:model])
85
+ prompt.as_messages(inputs)
86
+ else
87
+ { prompt: prompt.as_prompt(inputs: inputs) }
88
+ end
89
+
90
+ # Add content processing
91
+ processed_prompt[:content] = process_content(processed_prompt[:content]) if processed_prompt[:content]
92
+
93
+ Boxcars.debug("Sending to Intelligence:\n#{processed_prompt}", :cyan) if Boxcars.configuration.log_prompts
94
+
95
+ # Make API call
96
+ response = client.generate(parameters: params.merge(processed_prompt))
97
+ check_response(response)
98
+ response
99
+ rescue StandardError => e
100
+ Boxcars.error("Intelligence Error: #{e.message}", :red)
101
+ raise
102
+ end
103
+
104
+ # Run the engine with a question
105
+ def run(question, **kwargs)
106
+ prompt = Prompt.new(template: question)
107
+ response = client(prompt: prompt, **kwargs)
108
+ extract_answer(response)
109
+ end
110
+
111
+ private
112
+
113
+ def extract_answer(response)
114
+ # Handle different response formats
115
+ if response["choices"]
116
+ response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
117
+ else
118
+ response["output"] || response.to_s
119
+ end
120
+ end
121
+
122
+ def check_response(response)
123
+ if response["error"]
124
+ code = response.dig("error", "code")
125
+ msg = response.dig("error", "message") || "unknown error"
126
+ raise KeyError, "INTELLIGENCE_API_KEY not valid" if code == "invalid_api_key"
127
+
128
+ raise ValueError, "Intelligence error: #{msg}"
129
+ end
130
+
131
+ # Validate response structure
132
+ return if response["choices"] || response["output"]
133
+
134
+ raise Error, "Invalid response format from Intelligence API"
135
+ end
136
+
137
+ def conversation_model?(_model)
138
+ true
139
+ end
140
+ end
141
+ end
@@ -80,3 +80,4 @@ require "boxcars/engine/openai"
80
80
  require "boxcars/engine/perplexityai"
81
81
  require "boxcars/engine/gpt4all_eng"
82
82
  require "boxcars/engine/gemini_ai"
83
+ require "boxcars/engine/cerebras"
@@ -44,6 +44,18 @@ module Boxcars
44
44
  def default_prefixes
45
45
  end
46
46
 
47
+ # Convert the prompt to an Intelligence::Conversation
48
+ # @param inputs [Hash] The inputs to use for the prompt
49
+ # @return [Intelligence::Conversation] The converted conversation
50
+ def as_intelligence_conversation(inputs: nil)
51
+ conversation = Intelligence::Conversation.new
52
+ user_msg = Intelligence::Message.new(:user)
53
+ user_msg << Intelligence::MessageContent::Text.new(text: format(inputs))
54
+ conversation.messages << user_msg
55
+
56
+ conversation
57
+ end
58
+
47
59
  private
48
60
 
49
61
  # format the prompt with the input variables
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Boxcars
4
4
  # The current version of the gem.
5
- VERSION = "0.6.9"
5
+ VERSION = "0.7.1"
6
6
  end
data/lib/boxcars.rb CHANGED
@@ -27,7 +27,7 @@ module Boxcars
27
27
 
28
28
  # Configuration contains gem settings
29
29
  class Configuration
30
- attr_writer :openai_access_token, :serpapi_api_key, :groq_api_key
30
+ attr_writer :openai_access_token, :serpapi_api_key, :groq_api_key, :cerebras_api_key
31
31
  attr_accessor :organization_id, :logger, :log_prompts, :log_generated, :default_train, :default_engine
32
32
 
33
33
  def initialize
@@ -62,6 +62,11 @@ module Boxcars
62
62
  key_lookup(:groq_api_key, kwargs)
63
63
  end
64
64
 
65
+ # @return [String] The Cerebras API key either from arg or env.
66
+ def cerebras_api_key(**kwargs)
67
+ key_lookup(:cerebras_api_key, kwargs)
68
+ end
69
+
65
70
  # @return [String] The Google AI API key either from arg or env.
66
71
  def gemini_api_key(**kwargs)
67
72
  key_lookup(:gemini_api_key, kwargs)
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.9
4
+ version: 0.7.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-12-19 00:00:00.000000000 Z
12
+ date: 2025-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anthropic
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '0.1'
20
+ version: '0.3'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '0.1'
27
+ version: '0.3'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: google_search_results
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -45,26 +45,40 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 0.0.4
48
+ version: 0.0.5
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 0.0.4
55
+ version: 0.0.5
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: hnswlib
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '0.8'
62
+ version: '0.9'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.9'
70
+ - !ruby/object:Gem::Dependency
71
+ name: intelligence
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0.8'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
68
82
  - !ruby/object:Gem::Version
69
83
  version: '0.8'
70
84
  - !ruby/object:Gem::Dependency
@@ -73,14 +87,14 @@ dependencies:
73
87
  requirements:
74
88
  - - "~>"
75
89
  - !ruby/object:Gem::Version
76
- version: '1.16'
90
+ version: '1.18'
77
91
  type: :runtime
78
92
  prerelease: false
79
93
  version_requirements: !ruby/object:Gem::Requirement
80
94
  requirements:
81
95
  - - "~>"
82
96
  - !ruby/object:Gem::Version
83
- version: '1.16'
97
+ version: '1.18'
84
98
  - !ruby/object:Gem::Dependency
85
99
  name: pgvector
86
100
  requirement: !ruby/object:Gem::Requirement
@@ -101,20 +115,14 @@ dependencies:
101
115
  requirements:
102
116
  - - ">="
103
117
  - !ruby/object:Gem::Version
104
- version: '7.1'
105
- - - "<"
106
- - !ruby/object:Gem::Version
107
- version: '8.0'
118
+ version: '7.3'
108
119
  type: :runtime
109
120
  prerelease: false
110
121
  version_requirements: !ruby/object:Gem::Requirement
111
122
  requirements:
112
123
  - - ">="
113
124
  - !ruby/object:Gem::Version
114
- version: '7.1'
115
- - - "<"
116
- - !ruby/object:Gem::Version
117
- version: '8.0'
125
+ version: '7.3'
118
126
  description: You simply set an OpenAI key, give a number of Boxcars to a Train, and
119
127
  magic ensues when you run it.
120
128
  email:
@@ -157,11 +165,14 @@ files:
157
165
  - lib/boxcars/conversation_prompt.rb
158
166
  - lib/boxcars/engine.rb
159
167
  - lib/boxcars/engine/anthropic.rb
168
+ - lib/boxcars/engine/cerebras.rb
160
169
  - lib/boxcars/engine/cohere.rb
161
170
  - lib/boxcars/engine/engine_result.rb
162
171
  - lib/boxcars/engine/gemini_ai.rb
163
172
  - lib/boxcars/engine/gpt4all_eng.rb
164
173
  - lib/boxcars/engine/groq.rb
174
+ - lib/boxcars/engine/intelligence.rb
175
+ - lib/boxcars/engine/intelligence/client.rb
165
176
  - lib/boxcars/engine/ollama.rb
166
177
  - lib/boxcars/engine/openai.rb
167
178
  - lib/boxcars/engine/perplexityai.rb