foobara-llm-backed-command 0.0.5 → 0.0.6

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: 53a125a1cf6ed542e1f7a45b271caa6e6651458afc54c817a21be114f9a29003
4
- data.tar.gz: 45bce6b28ca7a1a68629056e62be036cbe11890a851e5da8e193747d4382b212
3
+ metadata.gz: b425fcdb4e888c59b2bc32f4a7c4a4d066b11cf6fcfee6f6dcb8fc00da88cc21
4
+ data.tar.gz: b27ebd00c36a49a2e79001e1122e783a4dcd1406a4d5ef61891af726c64821df
5
5
  SHA512:
6
- metadata.gz: 8b2c99f1f022275d2ee480d0492b81f6e18d346d7d809143fb548915dd719e0f7080b8d79714f89c61b0f5f6a928dd482e92f58df3d6e262e368d216db9741bd
7
- data.tar.gz: 716b310f5628dd2c3c7fe97463d98248107c3c597572a62b0cbd4c32abf0a99f523d3ce52285388f43c966d0958c1e4c957204f8a57cbe631cb2e22baed85d36
6
+ metadata.gz: 24facf55a6108124f8f0109b53acd0e2b5782d52f4ee812f8a7f223f725cdaedbb79a3bad11b0c67efa0253c612edacf50f7db56025c91991dac23e7344306f7
7
+ data.tar.gz: 80d4bd1e19ecdfd28b58ff84026ed5245c06dce067a0a7dffb5ed887bf97fe35395274eb2f25a581ab08ba53a7448b9e01dcaf67c032ef07e70c4096cd89994f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.6] - 2025-05-21
2
+
3
+ - Give an error if no ai api services have been provided
4
+
1
5
  ## [0.0.5] - 2025-03-06
2
6
 
3
7
  - Defer to downstream default model if none specified
data/README.md CHANGED
@@ -1,6 +1,22 @@
1
- # Foobara::LlmBackedCommand
1
+ # Foobara::LlmBackedCommand/Foobara::LlmBackedExecuteMethod
2
2
 
3
- Provides a clean and quick way to implement a Foobara::Command that has logic backed by an LLM.
3
+ Provides a clean and quick way to implement a Foobara::Command that defers to an LLM for the answer
4
+
5
+ <!-- TOC -->
6
+ * [Foobara::LlmBackedCommand/Foobara::LlmBackedExecuteMethod](#foobarallmbackedcommandfoobarallmbackedexecutemethod)
7
+ * [Installation](#installation)
8
+ * [Usage](#usage)
9
+ * [Choosing a different model and llm service](#choosing-a-different-model-and-llm-service)
10
+ * [Using it as a mixin instead of a class](#using-it-as-a-mixin-instead-of-a-class)
11
+ * [Typical Foobara stuff: exposing it on the command-line](#typical-foobara-stuff-exposing-it-on-the-command-line)
12
+ * [Exposing commands through Rack](#exposing-commands-through-rack)
13
+ * [Exposing commands through Rails](#exposing-commands-through-rails)
14
+ * [Use with models](#use-with-models)
15
+ * [Use with entities](#use-with-entities)
16
+ * [Complete scripts to play with](#complete-scripts-to-play-with)
17
+ * [Contributing](#contributing)
18
+ * [License](#license)
19
+ <!-- TOC -->
4
20
 
5
21
  ## Installation
6
22
 
@@ -9,12 +25,471 @@ Typical stuff: add `gem "foobara-llm-backed-command` to your Gemfile or .gemspec
9
25
 
10
26
  ## Usage
11
27
 
12
- TODO: Write usage instructions here
28
+ To play with these examples you can do `gem install foobara-llm-backed-command foobara-anthropic-api`
29
+ and then the following:
30
+
31
+ ```ruby
32
+ ENV["ANTHROPIC_API_KEY"] = "<your key here>"
33
+
34
+ require 'foobara/llm_backed_command'
35
+
36
+ class DetermineLanguage < Foobara::LlmBackedCommand
37
+ inputs code_snippet: :string
38
+ result most_likely: :string, probabilities: { ruby: :float, c: :float, smalltalk: :float, java: :float }
39
+ end
40
+
41
+ puts DetermineLanguage.run!(code_snippet: "puts 'Hello, World'")
42
+ ```
43
+
44
+ Running this script outputs:
45
+
46
+ ```
47
+ $ ./demo
48
+ {most_likely: "ruby", probabilities: {ruby: 0.95, c: 0.01, smalltalk: 0.02, java: 0.02}}
49
+ ```
50
+
51
+ Here we have only specified the command name and the inputs/result. Our LLM of choice
52
+ will be used to get the answer, and it will be structured according to the result type.
53
+
54
+ The default LLM model is claude-3-7-sonnet, but you can use others:
55
+
56
+ ### Choosing a different model and llm service
57
+
58
+ One way to do this is by creating an input called `llm_model`
59
+
60
+ ```ruby
61
+ ENV["ANTHROPIC_API_KEY"] = "<your key here>"
62
+ ENV["OPENAI_API_KEY"] = "<your key here>"
63
+ ENV["OLLAMA_API_URL"] = "<your ollama API if different than http://localhost:11434>"
64
+
65
+ require "foobara/anthropic_api"
66
+ require "foobara/open_ai_api"
67
+ require "foobara/ollama_api"
68
+ require 'foobara/llm_backed_command'
69
+
70
+ class DetermineLanguage < Foobara::LlmBackedCommand
71
+ inputs do
72
+ code_snippet :string, :required
73
+ llm_model Foobara::Ai::AnswerBot::Types.model_enum, default: "claude-3-7-sonnet-20250219"
74
+ end
75
+
76
+ result most_likely: :string, probabilities: { ruby: :float, c: :float, smalltalk: :float, java: :float }
77
+ end
78
+
79
+ inputs = { llm_model: "chat-gpt-3-5-turbo", code_snippet: "puts 'Hello, World'" }
80
+ command = DetermineLanguage.new(inputs)
81
+ outcome = command.run
82
+
83
+ puts outcome.success? ? outcome.result : outcome.errors_hash
84
+ ```
85
+
86
+ ### Using it as a mixin instead of a class
87
+
88
+ If you need the inheritance slot for some other command base class, you can use the mixin:
89
+
90
+ ```ruby
91
+ class DetermineLanguage < Foobara::Command
92
+ include Foobara::LlmBackedExecuteMethod
93
+
94
+ inputs code_snippet: :string
95
+ result most_likely: :string, probabilities: { ruby: :float, c: :float, smalltalk: :float, java: :float }
96
+ end
97
+ ```
98
+
99
+ ### Typical Foobara stuff: exposing it on the command-line
100
+
101
+ Probably best to refer to Foobara for details instead of turning this README.md into a Foobara tutorial, but
102
+ these can be used as any other Foobara command. So exposing
103
+ the command on the command line is easy (requires `gem install foobara-sh-cli-connector fooara-dotenv-loader`)
104
+ (switching to dotenv for convenience):
105
+
106
+ ```ruby
107
+ #!/usr/bin/env ruby
108
+
109
+ require "foobara/load_dotenv"
110
+ Foobara::LoadDotenv.run!(dir: __dir__)
111
+
112
+ require "foobara/anthropic_api"
113
+ require "foobara/open_ai_api"
114
+ require "foobara/ollama_api"
115
+ require "foobara/llm_backed_command"
116
+ require "foobara/sh_cli_connector"
117
+
118
+ class DetermineLanguage < Foobara::LlmBackedCommand
119
+ inputs do
120
+ code_snippet :string, :required
121
+ llm_model Foobara::Ai::AnswerBot::Types.model_enum, default: "claude-3-7-sonnet-20250219"
122
+ end
123
+ result most_likely: :string, probabilities: { ruby: :float, c: :float, smalltalk: :float, java: :float }
124
+ end
125
+
126
+ Foobara::CommandConnectors::ShCliConnector.new(single_command_mode: DetermineLanguage).run(ARGV)
127
+ ```
128
+
129
+ which allows:
130
+
131
+ ```
132
+ $ ./determine-language --help
133
+ Usage: determine-language [INPUTS]
134
+
135
+ Inputs:
136
+
137
+ -c, --code-snippet CODE_SNIPPET Required
138
+ -l, --llm-model LLM_MODEL One of: babbage-002, chatgpt-4o-latest, claude-2.0, claude-2.1,
139
+ claude-3-5-haiku-20241022, claude-3-5-sonnet-20240620, claude-3-5-sonnet-20241022,
140
+ claude-3-7-sonnet-20250219, claude-3-haiku-20240307, claude-3-opus-20240229,
141
+ claude-3-sonnet-20240229, dall-e-2, dall-e-3, davinci-002, gpt-3.5-turbo,
142
+ gpt-3.5-turbo-0125, gpt-3.5-turbo-1106, gpt-3.5-turbo-16k, gpt-3.5-turbo-instruct,
143
+ gpt-3.5-turbo-instruct-0914, gpt-4, gpt-4-0125-preview, gpt-4-0613,
144
+ gpt-4-1106-preview, gpt-4-turbo, gpt-4-turbo-2024-04-09, gpt-4-turbo-preview,
145
+ gpt-4.5-preview, gpt-4.5-preview-2025-02-27, gpt-4o, gpt-4o-2024-05-13,
146
+ gpt-4o-2024-08-06, gpt-4o-2024-11-20, gpt-4o-audio-preview, gpt-4o-audio-preview-2024-10-01,
147
+ gpt-4o-audio-preview-2024-12-17, gpt-4o-mini, gpt-4o-mini-2024-07-18,
148
+ gpt-4o-mini-audio-preview, gpt-4o-mini-audio-preview-2024-12-17,
149
+ gpt-4o-mini-realtime-preview, gpt-4o-mini-realtime-preview-2024-12-17,
150
+ gpt-4o-mini-search-preview, gpt-4o-mini-search-preview-2025-03-11,
151
+ gpt-4o-realtime-preview, gpt-4o-realtime-preview-2024-10-01, gpt-4o-realtime-preview-2024-12-17,
152
+ gpt-4o-search-preview, gpt-4o-search-preview-2025-03-11, llama3:8b,
153
+ o1, o1-2024-12-17, o1-mini, o1-mini-2024-09-12, o1-preview, o1-preview-2024-09-12,
154
+ o3-mini, o3-mini-2025-01-31, omni-moderation-2024-09-26, omni-moderation-latest,
155
+ smollm2:135m, text-embedding-3-large, text-embedding-3-small, text-embedding-ada-002,
156
+ tts-1, tts-1-1106, tts-1-hd, tts-1-hd-1106, whisper-1.
157
+ Default: "claude-3-7-sonnet-20250219"
158
+ ```
159
+
160
+ Running the program:
161
+
162
+ ```
163
+ $ ./determine-language --code-snippet "Transcript show: 'Hello, World'"
164
+ most_likely: "smalltalk",
165
+ probabilities: {
166
+ ruby: 0.1,
167
+ c: 0.05,
168
+ smalltalk: 0.8,
169
+ java: 0.05
170
+ }
171
+ ```
172
+
173
+ ### Exposing commands through Rack
174
+
175
+ Or you can spin up a quick json API either through Rack or the Rails router. Here's an example with the rack connector
176
+ (requires `gem install foobara-rack-controller rackup puma`):
177
+
178
+ ```ruby
179
+ #!/usr/bin/env ruby
180
+
181
+ require "foobara/load_dotenv"
182
+ Foobara::LoadDotenv.run!(dir: __dir__)
183
+
184
+ require "foobara/llm_backed_command"
185
+ require "foobara/rack_connector"
186
+ require "rackup/server"
187
+
188
+ class DetermineLanguage < Foobara::LlmBackedCommand
189
+ inputs code_snippet: :string
190
+ result probabilities: { ruby: :float, c: :float, smalltalk: :float, java: :float },
191
+ most_likely: :string
192
+ end
193
+
194
+ command_connector = Foobara::CommandConnectors::Http::Rack.new
195
+ command_connector.connect(DetermineLanguage)
196
+
197
+ Rackup::Server.start(app: command_connector)
198
+ ```
199
+
200
+ After we run this script we can hit it with curl:
201
+
202
+ ```
203
+ $ curl http://localhost:9292/run/DetermineLanguage?code_snippet=System.out.println
204
+ {"probabilities":{"ruby":0.05,"c":0.1,"smalltalk":0.05,"java":0.8},"most_likely":"java"}
205
+ ```
206
+
207
+ And we can run it from other systems in either Ruby or TypeScript.
208
+
209
+ In Ruby (requires `gem install foobara-remote-imports`):
210
+
211
+ ```ruby
212
+ #!/usr/bin/env ruby
213
+
214
+ require "foobara/remote_imports"
215
+
216
+ Foobara::RemoteImports::ImportCommand.run!(manifest_url: "http://localhost:9292/manifest", cache: true)
217
+
218
+ puts DetermineLanguage.run!(code_snippet: "System.out.println")
219
+ ```
220
+
221
+ This outputs:
222
+
223
+ ```
224
+ $ ./determine-language-client
225
+ {probabilities: {ruby: 0.05, c: 0.05, smalltalk: 0.1, java: 0.8}, most_likely: "java"}
226
+ ```
227
+
228
+ And we can also generate a remote command in TypeScript (requires `gem install foob`)
229
+
230
+ From inside a TypeScript project:
231
+
232
+ ```
233
+ $ foob g typescript-remote-commands --manifest-url http://localhost:9292/manifest
234
+ ```
235
+
236
+ This will generate code so that we can do:
237
+
238
+ ```TypeScript
239
+ import { DetermineLanguage } from "./DetermineLanguage"
240
+
241
+ const command = new DetermineLanguage({code_snippet: "System.out.println"})
242
+ const outcome = await command.run()
243
+
244
+ if (outcome.isSuccess) {
245
+ console.log(outcome.result)
246
+ } else {
247
+ console.error(outcome.errors_hash)
248
+ }
249
+ ```
250
+
251
+ and everything will be fully typed, inputs, result, etc.
252
+
253
+ ### Exposing commands through Rails
254
+
255
+ This has become too much of a Foobara tutorial so instead please refer to
256
+ https://github.com/foobara/rails-command-connector
257
+
258
+ ### Use with models
259
+
260
+ You can of course use this with whatever Foobara concepts you want, including models (and entities to some extent.)
261
+
262
+ Here's more complex example that accepts data encapsulated in model instances and returns model instances:
263
+
264
+ ```ruby
265
+ #!/usr/bin/env ruby
266
+
267
+ require "foobara/load_dotenv"
268
+
269
+ Foobara::LoadDotenv.run!(env: "development", dir: __dir__)
270
+
271
+ require "foobara/anthropic_api"
272
+ # require "foobara/open_ai_api"
273
+ # require "foobara/ollama_api"
274
+ require "foobara/llm_backed_command"
275
+
276
+ class PossibleUsState < Foobara::Model
277
+ attributes do
278
+ name :string, :required,
279
+ "A name that potentially might be a name of a US state, spelled correctly or incorrectly"
280
+ end
281
+ end
282
+
283
+ class VerifiedUsState < Foobara::Model
284
+ attributes do
285
+ possible_us_state PossibleUsState, :required,
286
+ "The original possible US state that was passed in"
287
+ spelling_correction_required :boolean, :required, "Whether or not the original spelling was correct"
288
+ corrected_spelling :string, :allow_nil,
289
+ "If the original spelling was incorrect, the corrected spelling will be here"
290
+ end
291
+ end
292
+
293
+ class SelectUsStateNamesAndCorrectTheirSpelling < Foobara::LlmBackedCommand
294
+ description <<~DESCRIPTION
295
+ Accepts a list of possible US state names and sorts them into verified to be the name of a
296
+ US state and rejected to be the name of a non-US state, as well as correcting the spelling of
297
+ the US state name if it's not correct.
298
+
299
+ example:
300
+
301
+ If you pass in ["Kalifornia", "Los Angeles", "New York"] the result will be:
302
+
303
+ result[:verified].length # => 2
304
+ result[:verified][0].possible_us_state.name # => "Kalifornia"
305
+ result[:verified][0].spelling_correction_required # => true#{" "}
306
+ result[:verified][0].corrected_spelling # => "California"
307
+ result[:verified][1].possible_us_state.name # => "New York"
308
+ result[:verified][1].spelling_correction_required # => false
309
+ result[:verified][1].corrected_spelling # => nil
310
+
311
+ result[:rejected].length # => 1
312
+ result[:rejected][0].name # => "Los Angeles"
313
+ DESCRIPTION
314
+
315
+ inputs do
316
+ list_of_possible_us_states [PossibleUsState]
317
+ llm_model :string, default: "claude-3-7-sonnet-20250219"
318
+ end
319
+
320
+ result do
321
+ verified [VerifiedUsState]
322
+ rejected [PossibleUsState]
323
+ end
324
+ end
325
+
326
+ list_of_possible_us_states = [
327
+ PossibleUsState.new(name: "Grand Rapids"),
328
+ PossibleUsState.new(name: "Oregon"),
329
+ PossibleUsState.new(name: "Yutah"),
330
+ PossibleUsState.new(name: "Misisipi"),
331
+ PossibleUsState.new(name: "Tacoma"),
332
+ PossibleUsState.new(name: "Kalifornia"),
333
+ PossibleUsState.new(name: "Los Angeles"),
334
+ PossibleUsState.new(name: "New York")
335
+ ]
336
+
337
+ command = SelectUsStateNamesAndCorrectTheirSpelling.new(list_of_possible_us_states:)
338
+ result = command.run!
339
+
340
+ puts "Considering:"
341
+ list_of_possible_us_states.each do |possible_us_state|
342
+ puts " #{possible_us_state.name}"
343
+ end
344
+ puts
345
+
346
+ puts "#{result[:verified].length} were verified as US states:"
347
+ result[:verified].each do |verified_us_state|
348
+ puts " #{verified_us_state.corrected_spelling || verified_us_state.possible_us_state.name}"
349
+ if verified_us_state.spelling_correction_required
350
+ puts " original incorrect spelling: #{verified_us_state.possible_us_state.name}"
351
+ end
352
+ end
353
+
354
+ puts
355
+ puts "#{result[:rejected].length} were rejected as non-US states:"
356
+ result[:rejected].each do |rejected_us_state|
357
+ puts " #{rejected_us_state.name}"
358
+ end
359
+ ```
360
+
361
+ This script outputs:
362
+
363
+ ```
364
+ Considering:
365
+ Grand Rapids
366
+ Oregon
367
+ Yutah
368
+ Misisipi
369
+ Tacoma
370
+ Kalifornia
371
+ Los Angeles
372
+ New York
373
+
374
+ 5 were verified as US states:
375
+ Oregon
376
+ Utah
377
+ original incorrect spelling: Yutah
378
+ Mississippi
379
+ original incorrect spelling: Misisipi
380
+ California
381
+ original incorrect spelling: Kalifornia
382
+ New York
383
+
384
+ 3 were rejected as non-US states:
385
+ Grand Rapids
386
+ Tacoma
387
+ Los Angeles
388
+ ```
389
+
390
+ Note that we were able to access model attributes by methods just fine, and we didn't write any logic on how
391
+ to spell check or any logic on how determine what is or is not a US state.
392
+
393
+ ### Use with entities
394
+
395
+ Unclear how practical using entities in this way would be, but, here's an interesting
396
+ example of asking a question about some persisted records:
397
+
398
+ ```ruby
399
+ #!/usr/bin/env ruby
400
+
401
+ require "foobara/load_dotenv"
402
+
403
+ Foobara::LoadDotenv.run!(env: "development", dir: __dir__)
404
+
405
+ require "foobara/llm_backed_command"
406
+ require "foobara/sh_cli_connector"
407
+ require "foobara/local_files_crud_driver"
408
+
409
+ Foobara::Persistence.default_crud_driver = Foobara::LocalFilesCrudDriver.new
410
+
411
+ class Capybara < Foobara::Entity
412
+ attributes do
413
+ id :integer
414
+ name :string, :required
415
+ age :integer, :required
416
+ end
417
+ primary_key :id
418
+ end
419
+
420
+ class CreateCapybara < Foobara::Command
421
+ inputs Capybara.attributes_for_create
422
+ result Capybara
423
+
424
+ def execute
425
+ create_capybara
426
+
427
+ capybara
428
+ end
429
+
430
+ attr_accessor :capybara
431
+
432
+ def create_capybara
433
+ self.capybara = Capybara.create(inputs)
434
+ end
435
+ end
436
+
437
+ class SelectOldestCapybara < Foobara::LlmBackedCommand
438
+ inputs capybaras: [Capybara]
439
+ result Capybara
440
+ end
441
+
442
+ connector = Foobara::CommandConnectors::ShCliConnector.new
443
+
444
+ connector.connect(CreateCapybara)
445
+ connector.connect(SelectOldestCapybara)
446
+
447
+ connector.run(ARGV)
448
+ ```
449
+
450
+ We can create some capybara records like this:
451
+
452
+ ```
453
+ $ ./oldest-capybara-example CreateCapybara --age 100 --name Fumiko
454
+ age: 100,
455
+ name: "Fumiko",
456
+ id: 1
457
+ $ ./oldest-capybara-example CreateCapybara --age 200 --name Barbara
458
+ age: 200,
459
+ name: "Barbara",
460
+ id: 2
461
+ $ ./oldest-capybara-example CreateCapybara --age 300 --name Basil
462
+ age: 300,
463
+ name: "Basil",
464
+ id: 3
465
+ ```
466
+
467
+ And then ask who is older, Barbara or Basil, like so:
468
+
469
+ ```
470
+ $ ./oldest-capybara-example SelectOldestCapybara --capybaras 2 3
471
+ id: 3,
472
+ name: "Basil",
473
+ age: 300
474
+ ```
475
+
476
+ Basil is older. Pretty crazy we didn't have to write any logic about age comparisons at all.
477
+ And our SelectOldestCapybara command is only 4 lines long as a result.
478
+
479
+ ### Complete scripts to play with
480
+
481
+ There are various scripts in [example_scripts/shorter](example_scripts/shorter)
482
+ and [example_scripts/higher_quality](example_scripts/higher_quality) that you can play with.
483
+
484
+ The difference between the two directories is that `higher_quality/` contains scripts that are more realistic
485
+ with more descriptions and comments and `shorter/` focuses on keeping the scripts short and simple.
486
+
487
+ Those directories also have a Gemfile each if helpful for pulling in dependencies
488
+ and so that you can use `bundle exec` there if needed.
13
489
 
14
490
  ## Contributing
15
491
 
16
- Bug reports and pull requests are welcome on GitHub
17
- at https://github.com/foobara/llm-backed-command
492
+ Bug reports and pull requests are welcome on GitHub at https://github.com/foobara/llm-backed-command
18
493
 
19
494
  ## License
20
495
 
@@ -4,6 +4,13 @@ require "foobara/command_connectors"
4
4
  require "foobara/ai"
5
5
  require "foobara/json_schema_generator"
6
6
 
7
+ if Foobara::Ai.foobara_all_command.empty?
8
+ # :nocov:
9
+ raise "No api services loaded. " \
10
+ "Did you forget to set a URL/API key env var or a require for either ollama, anthropic, or openai?"
11
+ # :nocov:
12
+ end
13
+
7
14
  Foobara::Util.require_directory "#{__dir__}/../../src"
8
15
 
9
16
  Foobara::Monorepo.project "llm_backed_command", project_path: "#{__dir__}/../../"
metadata CHANGED
@@ -1,42 +1,56 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara-llm-backed-command
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-06 00:00:00.000000000 Z
10
+ date: 2025-05-21 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: foobara
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.0.92
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.92
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: foobara-ai
14
28
  requirement: !ruby/object:Gem::Requirement
15
29
  requirements:
16
- - - ">="
30
+ - - "~>"
17
31
  - !ruby/object:Gem::Version
18
- version: '0'
32
+ version: 0.0.1
19
33
  type: :runtime
20
34
  prerelease: false
21
35
  version_requirements: !ruby/object:Gem::Requirement
22
36
  requirements:
23
- - - ">="
37
+ - - "~>"
24
38
  - !ruby/object:Gem::Version
25
- version: '0'
39
+ version: 0.0.1
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: foobara-json-schema-generator
28
42
  requirement: !ruby/object:Gem::Requirement
29
43
  requirements:
30
- - - ">="
44
+ - - "~>"
31
45
  - !ruby/object:Gem::Version
32
- version: '0'
46
+ version: 0.0.1
33
47
  type: :runtime
34
48
  prerelease: false
35
49
  version_requirements: !ruby/object:Gem::Requirement
36
50
  requirements:
37
- - - ">="
51
+ - - "~>"
38
52
  - !ruby/object:Gem::Version
39
- version: '0'
53
+ version: 0.0.1
40
54
  email:
41
55
  - azimux@gmail.com
42
56
  executables: []
@@ -72,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
86
  - !ruby/object:Gem::Version
73
87
  version: '0'
74
88
  requirements: []
75
- rubygems_version: 3.6.5
89
+ rubygems_version: 3.6.2
76
90
  specification_version: 4
77
91
  summary: Provides an easy way to implement a command whose logic is managed by an
78
92
  LLM