boxcars 0.6.8 → 0.6.9
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/Gemfile.lock +50 -46
- data/lib/boxcars/engine/anthropic.rb +1 -1
- data/lib/boxcars/engine/cohere.rb +1 -1
- data/lib/boxcars/engine/gemini_ai.rb +43 -85
- data/lib/boxcars/engine/groq.rb +1 -3
- data/lib/boxcars/engine/openai.rb +1 -1
- data/lib/boxcars/engine/perplexityai.rb +1 -1
- data/lib/boxcars/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a058c8e9111ba8c7b3e29d25c6f9226f87c862c4b10b26c3c05f8a69dbe7659c
|
4
|
+
data.tar.gz: 718546be88153f0f26ba932811e30fa9f8c3a467ac029a76c88d554912640b29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baf4a36fbb72e064f110576f73945d276794b7f235935d9dc0797460ac3a641439ff29e7e650c93d468e9a70a0f148d0fabde6724cc82b7c3cd05df2020974cd
|
7
|
+
data.tar.gz: 85e40690235ed5e13daa9a326cfef6dae29cd882a18716913a264026fed46cde355ea50c01703aac26da5b77ac3aefc22eaa7eb2583b12485840b32d45f1c94b
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
boxcars (0.6.
|
4
|
+
boxcars (0.6.9)
|
5
5
|
anthropic (~> 0.1)
|
6
6
|
google_search_results (~> 2.2)
|
7
7
|
gpt4all (~> 0.0.4)
|
@@ -13,13 +13,13 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
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)
|
16
|
+
activemodel (7.2.2.1)
|
17
|
+
activesupport (= 7.2.2.1)
|
18
|
+
activerecord (7.2.2.1)
|
19
|
+
activemodel (= 7.2.2.1)
|
20
|
+
activesupport (= 7.2.2.1)
|
21
21
|
timeout (>= 0.4.0)
|
22
|
-
activesupport (7.2.2)
|
22
|
+
activesupport (7.2.2.1)
|
23
23
|
base64
|
24
24
|
benchmark (>= 0.3)
|
25
25
|
bigdecimal
|
@@ -50,41 +50,43 @@ GEM
|
|
50
50
|
protocol-http1 (~> 0.19.0)
|
51
51
|
protocol-http2 (~> 0.16.0)
|
52
52
|
traces (>= 0.10.0)
|
53
|
-
async-http-faraday (0.
|
53
|
+
async-http-faraday (0.19.0)
|
54
54
|
async-http (~> 0.42)
|
55
55
|
faraday
|
56
56
|
async-io (1.43.2)
|
57
57
|
async
|
58
|
-
async-pool (0.
|
58
|
+
async-pool (0.10.2)
|
59
59
|
async (>= 1.25)
|
60
|
+
traces
|
60
61
|
base64 (0.2.0)
|
61
62
|
benchmark (0.4.0)
|
62
63
|
bigdecimal (3.1.8)
|
63
64
|
concurrent-ruby (1.3.4)
|
64
65
|
connection_pool (2.4.1)
|
65
|
-
console (1.
|
66
|
+
console (1.29.2)
|
66
67
|
fiber-annotation
|
67
68
|
fiber-local (~> 1.1)
|
68
69
|
json
|
69
70
|
crack (1.0.0)
|
70
71
|
bigdecimal
|
71
72
|
rexml
|
72
|
-
|
73
|
+
date (3.4.1)
|
74
|
+
debug (1.10.0)
|
73
75
|
irb (~> 1.10)
|
74
76
|
reline (>= 0.3.8)
|
75
77
|
diff-lcs (1.5.1)
|
76
78
|
domain_name (0.6.20240107)
|
77
|
-
dotenv (3.1.
|
79
|
+
dotenv (3.1.7)
|
78
80
|
drb (2.2.1)
|
79
81
|
event_stream_parser (1.0.0)
|
80
|
-
faraday (2.12.
|
82
|
+
faraday (2.12.2)
|
81
83
|
faraday-net_http (>= 2.0, < 3.5)
|
82
84
|
json
|
83
85
|
logger
|
84
86
|
faraday-http-cache (2.5.1)
|
85
87
|
faraday (>= 0.8)
|
86
|
-
faraday-multipart (1.0
|
87
|
-
multipart-post (~> 2)
|
88
|
+
faraday-multipart (1.1.0)
|
89
|
+
multipart-post (~> 2.0)
|
88
90
|
faraday-net_http (3.4.0)
|
89
91
|
net-http (>= 0.5.0)
|
90
92
|
faraday-retry (2.2.1)
|
@@ -92,7 +94,7 @@ GEM
|
|
92
94
|
fiber-annotation (0.2.0)
|
93
95
|
fiber-local (1.1.0)
|
94
96
|
fiber-storage
|
95
|
-
fiber-storage (0.
|
97
|
+
fiber-storage (1.0.0)
|
96
98
|
github_changelog_generator (1.16.4)
|
97
99
|
activesupport
|
98
100
|
async (>= 1.25.0)
|
@@ -107,33 +109,34 @@ GEM
|
|
107
109
|
faraday (~> 2.7)
|
108
110
|
os (~> 1.1)
|
109
111
|
tty-progressbar (~> 0.18.2)
|
110
|
-
hashdiff (1.1.
|
112
|
+
hashdiff (1.1.2)
|
111
113
|
hnswlib (0.9.0)
|
112
114
|
http-accept (1.7.0)
|
113
|
-
http-cookie (1.0.
|
115
|
+
http-cookie (1.0.8)
|
114
116
|
domain_name (~> 0.5)
|
115
117
|
i18n (1.14.6)
|
116
118
|
concurrent-ruby (~> 1.0)
|
117
|
-
io-console (0.
|
118
|
-
irb (1.14.
|
119
|
+
io-console (0.8.0)
|
120
|
+
irb (1.14.3)
|
119
121
|
rdoc (>= 4.0.0)
|
120
122
|
reline (>= 0.4.2)
|
121
|
-
json (2.9.
|
123
|
+
json (2.9.1)
|
122
124
|
language_server-protocol (3.17.0.3)
|
123
|
-
logger (1.6.
|
124
|
-
mime-types (3.
|
125
|
+
logger (1.6.4)
|
126
|
+
mime-types (3.6.0)
|
127
|
+
logger
|
125
128
|
mime-types-data (~> 3.2015)
|
126
|
-
mime-types-data (3.2024.
|
129
|
+
mime-types-data (3.2024.1203)
|
127
130
|
minitest (5.25.4)
|
128
131
|
multi_json (1.15.0)
|
129
132
|
multipart-post (2.4.1)
|
130
133
|
net-http (0.6.0)
|
131
134
|
uri
|
132
135
|
netrc (0.11.0)
|
133
|
-
nio4r (2.7.
|
134
|
-
nokogiri (1.
|
136
|
+
nio4r (2.7.4)
|
137
|
+
nokogiri (1.17.2-arm64-darwin)
|
135
138
|
racc (~> 1.4)
|
136
|
-
nokogiri (1.
|
139
|
+
nokogiri (1.17.2-x86_64-linux)
|
137
140
|
racc (~> 1.4)
|
138
141
|
octokit (4.25.1)
|
139
142
|
faraday (>= 1, < 3)
|
@@ -145,44 +148,45 @@ GEM
|
|
145
148
|
racc
|
146
149
|
pg (1.5.9)
|
147
150
|
pgvector (0.2.2)
|
148
|
-
protocol-hpack (1.
|
151
|
+
protocol-hpack (1.5.1)
|
149
152
|
protocol-http (0.26.8)
|
150
153
|
protocol-http1 (0.19.1)
|
151
154
|
protocol-http (~> 0.22)
|
152
155
|
protocol-http2 (0.16.0)
|
153
156
|
protocol-hpack (~> 1.4)
|
154
157
|
protocol-http (~> 0.18)
|
155
|
-
psych (5.
|
158
|
+
psych (5.2.2)
|
159
|
+
date
|
156
160
|
stringio
|
157
161
|
public_suffix (6.0.1)
|
158
162
|
racc (1.8.1)
|
159
163
|
rainbow (3.1.1)
|
160
164
|
rake (13.2.1)
|
161
|
-
rdoc (6.
|
165
|
+
rdoc (6.10.0)
|
162
166
|
psych (>= 4.0.0)
|
163
167
|
regexp_parser (2.9.3)
|
164
|
-
reline (0.
|
168
|
+
reline (0.6.0)
|
165
169
|
io-console (~> 0.5)
|
166
170
|
rest-client (2.1.0)
|
167
171
|
http-accept (>= 1.7.0, < 2.0)
|
168
172
|
http-cookie (>= 1.0.2, < 2.0)
|
169
173
|
mime-types (>= 1.16, < 4.0)
|
170
174
|
netrc (~> 0.8)
|
171
|
-
rexml (3.
|
175
|
+
rexml (3.4.0)
|
172
176
|
rspec (3.13.0)
|
173
177
|
rspec-core (~> 3.13.0)
|
174
178
|
rspec-expectations (~> 3.13.0)
|
175
179
|
rspec-mocks (~> 3.13.0)
|
176
|
-
rspec-core (3.13.
|
180
|
+
rspec-core (3.13.2)
|
177
181
|
rspec-support (~> 3.13.0)
|
178
|
-
rspec-expectations (3.13.
|
182
|
+
rspec-expectations (3.13.3)
|
179
183
|
diff-lcs (>= 1.2.0, < 2.0)
|
180
184
|
rspec-support (~> 3.13.0)
|
181
|
-
rspec-mocks (3.13.
|
185
|
+
rspec-mocks (3.13.2)
|
182
186
|
diff-lcs (>= 1.2.0, < 2.0)
|
183
187
|
rspec-support (~> 3.13.0)
|
184
|
-
rspec-support (3.13.
|
185
|
-
rubocop (1.69.
|
188
|
+
rspec-support (3.13.2)
|
189
|
+
rubocop (1.69.2)
|
186
190
|
json (~> 2.3)
|
187
191
|
language_server-protocol (>= 3.17.0)
|
188
192
|
parallel (~> 1.10)
|
@@ -192,11 +196,11 @@ GEM
|
|
192
196
|
rubocop-ast (>= 1.36.2, < 2.0)
|
193
197
|
ruby-progressbar (~> 1.7)
|
194
198
|
unicode-display_width (>= 2.4.0, < 4.0)
|
195
|
-
rubocop-ast (1.
|
199
|
+
rubocop-ast (1.37.0)
|
196
200
|
parser (>= 3.3.1.0)
|
197
201
|
rubocop-rake (0.6.0)
|
198
202
|
rubocop (~> 1.0)
|
199
|
-
rubocop-rspec (3.
|
203
|
+
rubocop-rspec (3.3.0)
|
200
204
|
rubocop (~> 1.61)
|
201
205
|
ruby-openai (7.3.1)
|
202
206
|
event_stream_parser (>= 0.3.0, < 2.0.0)
|
@@ -206,16 +210,16 @@ GEM
|
|
206
210
|
sawyer (0.9.2)
|
207
211
|
addressable (>= 2.3.5)
|
208
212
|
faraday (>= 0.17.3, < 3)
|
209
|
-
securerandom (0.4.
|
210
|
-
sqlite3 (2.
|
211
|
-
sqlite3 (2.
|
212
|
-
stringio (3.1.
|
213
|
+
securerandom (0.4.1)
|
214
|
+
sqlite3 (2.4.1-arm64-darwin)
|
215
|
+
sqlite3 (2.4.1-x86_64-linux-gnu)
|
216
|
+
stringio (3.1.2)
|
213
217
|
strings-ansi (0.2.0)
|
214
|
-
timeout (0.4.
|
218
|
+
timeout (0.4.3)
|
215
219
|
timers (4.3.5)
|
216
|
-
traces (0.
|
220
|
+
traces (0.14.1)
|
217
221
|
tty-cursor (0.7.1)
|
218
|
-
tty-progressbar (0.18.
|
222
|
+
tty-progressbar (0.18.3)
|
219
223
|
strings-ansi (~> 0.2)
|
220
224
|
tty-cursor (~> 0.7)
|
221
225
|
tty-screen (~> 0.8)
|
@@ -1,73 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Boxcars
|
3
|
+
# Boxcars is a framework for running a series of tools to get an answer to a question.
|
4
4
|
module Boxcars
|
5
|
-
# A engine that uses
|
5
|
+
# A engine that uses GeminiAI's API.
|
6
6
|
class GeminiAi < Engine
|
7
|
-
attr_reader :prompts, :
|
7
|
+
attr_reader :prompts, :llm_parmas, :model_kwargs, :batch_size
|
8
8
|
|
9
9
|
# The default parameters to use when asking the engine.
|
10
10
|
DEFAULT_PARAMS = {
|
11
|
-
model: "gemini-1.5-flash-latest"
|
11
|
+
model: "gemini-1.5-flash-latest",
|
12
|
+
temperature: 0.1
|
12
13
|
}.freeze
|
13
14
|
|
14
15
|
# the default name of the engine
|
15
|
-
DEFAULT_NAME = "
|
16
|
+
DEFAULT_NAME = "GeminiAI engine"
|
16
17
|
# the default description of the engine
|
17
|
-
DEFAULT_DESCRIPTION = "useful for when you need to use
|
18
|
+
DEFAULT_DESCRIPTION = "useful for when you need to use AI to answer questions. " \
|
18
19
|
"You should ask targeted questions"
|
19
20
|
|
20
|
-
# A engine is
|
21
|
-
# @param name [String] The name of the engine. Defaults to "
|
21
|
+
# A engine is a container for a single tool to run.
|
22
|
+
# @param name [String] The name of the engine. Defaults to "GeminiAI engine".
|
22
23
|
# @param description [String] A description of the engine. Defaults to:
|
23
24
|
# useful for when you need to use AI to answer questions. You should ask targeted questions".
|
24
25
|
# @param prompts [Array<String>] The prompts to use when asking the engine. Defaults to [].
|
25
|
-
|
26
|
-
|
26
|
+
# @param batch_size [Integer] The number of prompts to send to the engine at once. Defaults to 20.
|
27
|
+
def initialize(name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, prompts: [], batch_size: 20, **kwargs)
|
28
|
+
@llm_parmas = DEFAULT_PARAMS.merge(kwargs)
|
27
29
|
@prompts = prompts
|
28
|
-
@batch_size =
|
30
|
+
@batch_size = batch_size
|
29
31
|
super(description: description, name: name)
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
# Get the OpenAI API client
|
35
|
+
# @param gemini_api_key [String] The access token to use when asking the engine.
|
36
|
+
# Defaults to Boxcars.configuration.gemini_api_key
|
37
|
+
# @return [OpenAI::Client] The OpenAI API gem client.
|
38
|
+
def self.open_ai_client(gemini_api_key: nil)
|
39
|
+
access_token = Boxcars.configuration.gemini_api_key(gemini_api_key: gemini_api_key)
|
40
|
+
::OpenAI::Client.new(access_token: access_token, uri_base: "https://generativelanguage.googleapis.com/v1beta/openai/")
|
34
41
|
end
|
35
42
|
|
36
|
-
def
|
37
|
-
|
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)
|
43
|
+
def conversation_model?(_model)
|
44
|
+
true
|
54
45
|
end
|
55
46
|
|
56
47
|
# Get an answer from the engine.
|
57
48
|
# @param prompt [String] The prompt to use when asking the engine.
|
58
|
-
# @param gemini_api_key [String]
|
49
|
+
# @param gemini_api_key [String] The access token to use when asking the engine.
|
59
50
|
# Defaults to Boxcars.configuration.gemini_api_key.
|
60
51
|
# @param kwargs [Hash] Additional parameters to pass to the engine if wanted.
|
61
|
-
def client(prompt:, inputs: {}, **kwargs)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
52
|
+
def client(prompt:, inputs: {}, gemini_api_key: nil, **kwargs)
|
53
|
+
clnt = GeminiAi.open_ai_client(gemini_api_key: gemini_api_key)
|
54
|
+
params = llm_parmas.merge(kwargs)
|
55
|
+
prompt = prompt.first if prompt.is_a?(Array)
|
56
|
+
params = prompt.as_messages(inputs).merge(params)
|
57
|
+
if Boxcars.configuration.log_prompts
|
58
|
+
Boxcars.debug(params[:messages].last(2).map { |p| ">>>>>> Role: #{p[:role]} <<<<<<\n#{p[:content]}" }.join("\n"), :cyan)
|
59
|
+
end
|
60
|
+
clnt.chat(parameters: params)
|
61
|
+
rescue => e
|
62
|
+
Boxcars.error(e, :red)
|
63
|
+
raise
|
71
64
|
end
|
72
65
|
|
73
66
|
# get an answer from the engine for a question.
|
@@ -76,13 +69,10 @@ module Boxcars
|
|
76
69
|
def run(question, **kwargs)
|
77
70
|
prompt = Prompt.new(template: question)
|
78
71
|
response = client(prompt: prompt, **kwargs)
|
79
|
-
|
80
72
|
raise Error, "GeminiAI: No response from API" unless response
|
81
|
-
raise Error, "GeminiAI: #{response[:error]}" if response[:error]
|
82
73
|
|
83
|
-
|
84
|
-
|
85
|
-
answer
|
74
|
+
check_response(response)
|
75
|
+
response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
|
86
76
|
end
|
87
77
|
|
88
78
|
# Get the default parameters for the engine.
|
@@ -95,13 +85,13 @@ module Boxcars
|
|
95
85
|
# @param must_haves [Array<String>] The keys that must be in the response. Defaults to %w[choices].
|
96
86
|
# @raise [KeyError] if there is an issue with the access token.
|
97
87
|
# @raise [ValueError] if the response is not valid.
|
98
|
-
def check_response(response, must_haves: %w[
|
99
|
-
if response['error']
|
88
|
+
def check_response(response, must_haves: %w[choices])
|
89
|
+
if response['error'].is_a?(Hash)
|
100
90
|
code = response.dig('error', 'code')
|
101
91
|
msg = response.dig('error', 'message') || 'unknown error'
|
102
|
-
raise KeyError, "
|
92
|
+
raise KeyError, "GEMINI_API_TOKEN not valid" if code == 'invalid_api_key'
|
103
93
|
|
104
|
-
raise ValueError, "
|
94
|
+
raise ValueError, "GeminiAI error: #{msg}"
|
105
95
|
end
|
106
96
|
|
107
97
|
must_haves.each do |key|
|
@@ -111,13 +101,7 @@ module Boxcars
|
|
111
101
|
|
112
102
|
# the engine type
|
113
103
|
def engine_type
|
114
|
-
"
|
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
|
104
|
+
"gemini_ai"
|
121
105
|
end
|
122
106
|
|
123
107
|
# Calculate the maximum number of tokens possible to generate for a prompt.
|
@@ -127,34 +111,8 @@ module Boxcars
|
|
127
111
|
num_tokens = get_num_tokens(prompt_text)
|
128
112
|
|
129
113
|
# get max context size for model by name
|
130
|
-
max_size =
|
114
|
+
max_size = 8096
|
131
115
|
max_size - num_tokens
|
132
116
|
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
117
|
end
|
160
118
|
end
|
data/lib/boxcars/engine/groq.rb
CHANGED
@@ -73,9 +73,7 @@ module Boxcars
|
|
73
73
|
raise Error, "Groq: No response from API" unless response
|
74
74
|
|
75
75
|
check_response(response)
|
76
|
-
|
77
|
-
puts answer
|
78
|
-
answer
|
76
|
+
response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
|
79
77
|
end
|
80
78
|
|
81
79
|
# Get the default parameters for the engine.
|
@@ -92,7 +92,7 @@ module Boxcars
|
|
92
92
|
raise Error, "OpenAI: #{response['error']}" if response["error"]
|
93
93
|
|
94
94
|
answer = response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
|
95
|
-
|
95
|
+
Boxcars.debug("Answer: #{answer}", :cyan)
|
96
96
|
answer
|
97
97
|
end
|
98
98
|
|
@@ -78,7 +78,7 @@ module Boxcars
|
|
78
78
|
raise Error, "PerplexityAI: #{response['error']}" if response["error"]
|
79
79
|
|
80
80
|
answer = response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
|
81
|
-
|
81
|
+
Boxcars.debug("Answer: #{answer}", :cyan)
|
82
82
|
answer
|
83
83
|
end
|
84
84
|
|
data/lib/boxcars/version.rb
CHANGED
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.
|
4
|
+
version: 0.6.9
|
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-
|
12
|
+
date: 2024-12-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: anthropic
|