ollama-ruby 0.9.0 → 0.9.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: d0b3ea2bd67e3f4fa2ca4da88a25cb869fc81e35578f1e7fd97ba43e84fc2278
4
- data.tar.gz: 626c534bd2fd0580ab0520e8b70587489edbc963e179be0f800ee63235690b33
3
+ metadata.gz: 3976b4254bbedc3655a6a737000903217eff8b4b941971eb6ae4fda630ba40c3
4
+ data.tar.gz: 29187dded0f2748e8e684648ab374d027aaff18a6f85ede48df78dc34b705645
5
5
  SHA512:
6
- metadata.gz: 149986d8144b1bc2c20771e245ead20f6e6bc07b46dbe26f8f355e0bc61eca146cc085a920dcbe3e3e08de65632693a35b6995c9dffef288aa929dd6b034de16
7
- data.tar.gz: 4214aa2911db561635011b8ea200074d15c74b93bf7abb3c8e77af9c40ac5d8994e908e2ade8e5f288c2919678e03ea5d84d07684a63ba1f8039de52b6091a86
6
+ metadata.gz: 69ad552c73c297d23db6a65681008c79329de3d4a02a07f28b027a94820f9505488870e4bce6b43c1ae6a6fb64c6107ce4cc3d28b307f07573987464e6eaed84
7
+ data.tar.gz: 79dd0a71d48726900ed7df4508f2031191f00f15b3713cc562aa29112c4942e72836c5d487c8883b173dc760d8e815461b66e3c4b0fbdccd1226e6019af2419a
data/CHANGES.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changes
2
2
 
3
+ ## 2024-10-19 v0.9.1
4
+
5
+ * Fixing string interpolation in `import_source` method:
6
+ + Changed result to use `#{}` instead of `%{}` for string interpolation
7
+ * Move `pull_model_unless_present` method:
8
+ + Moved the method before other methods
9
+ * Moved Switch classes and `setup_switches` method into Switches module:
10
+ + Moved the classes and method into a new module
11
+ * Utils::Fetcher: Normalize URL in fetcher utility:
12
+ + Added `normalize_url` method to class Ollama::Utils::Fetcher
13
+ + Normalizes URL by decoding URI components, removing anchors, and escaping special characters
14
+ + `excon` method now calls `normalize_url` on the provided URL
15
+ + Added specs for `normalize_url` in `fetcher_spec.rb`
16
+ * Remove Ollama top level Namespace b/c we include it from `ollama_chat`:
17
+ + Removed the top-level namespace
18
+
3
19
  ## 2024-10-18 v0.9.0
4
20
 
5
21
  * Add document policy chooser and modify embedding/importing/summarizing
data/bin/ollama_chat CHANGED
@@ -108,7 +108,7 @@ class OllamaChatConfig
108
108
  end
109
109
 
110
110
  class FollowChat
111
- include Ollama::Handlers::Concern
111
+ include Handlers::Concern
112
112
  include Term::ANSIColor
113
113
 
114
114
  def initialize(messages:, markdown: false, voice: nil, output: $stdout)
@@ -164,114 +164,142 @@ class FollowChat
164
164
  end
165
165
  end
166
166
 
167
- module CheckSwitch
168
- extend Tins::Concern
167
+ module Switches
168
+ module CheckSwitch
169
+ extend Tins::Concern
169
170
 
170
- included do
171
- alias_method :on?, :value
172
- end
171
+ included do
172
+ alias_method :on?, :value
173
+ end
173
174
 
174
- def off?
175
- !on?
176
- end
175
+ def off?
176
+ !on?
177
+ end
177
178
 
178
- def show
179
- puts @msg[value]
179
+ def show
180
+ puts @msg[value]
181
+ end
180
182
  end
181
- end
182
183
 
183
- class Switch
184
- def initialize(name, msg:, config: $config)
185
- @value = [ false, true ].include?(config) ? config : !!config.send("#{name}?")
186
- @msg = msg
187
- end
184
+ class Switch
185
+ def initialize(name, msg:, config: $config)
186
+ @value = [ false, true ].include?(config) ? config : !!config.send("#{name}?")
187
+ @msg = msg
188
+ end
188
189
 
189
- attr_reader :value
190
+ attr_reader :value
190
191
 
191
- def set(value, show: false)
192
- @value = !!value
193
- show && self.show
194
- end
192
+ def set(value, show: false)
193
+ @value = !!value
194
+ show && self.show
195
+ end
196
+
197
+ def toggle(show: true)
198
+ @value = !@value
199
+ show && self.show
200
+ end
195
201
 
196
- def toggle(show: true)
197
- @value = !@value
198
- show && self.show
202
+ include CheckSwitch
199
203
  end
200
204
 
201
- include CheckSwitch
202
- end
205
+ class CombinedSwitch
206
+ def initialize(value:, msg:)
207
+ @value = value
208
+ @msg = msg
209
+ end
203
210
 
204
- class CombinedSwitch
205
- def initialize(value:, msg:)
206
- @value = value
207
- @msg = msg
208
- end
211
+ def value
212
+ @value.()
213
+ end
209
214
 
210
- def value
211
- @value.()
215
+ include CheckSwitch
212
216
  end
213
217
 
214
- include CheckSwitch
215
- end
218
+ def setup_switches
219
+ $markdown = Switch.new(
220
+ :markdown,
221
+ msg: {
222
+ true => "Using #{italic{'ANSI'}} markdown to output content.",
223
+ false => "Using plaintext for outputting content.",
224
+ }
225
+ )
216
226
 
217
- def setup_switches
218
- $markdown = Switch.new(
219
- :markdown,
220
- msg: {
221
- true => "Using #{italic{'ANSI'}} markdown to output content.",
222
- false => "Using plaintext for outputting content.",
223
- }
224
- )
227
+ $stream = Switch.new(
228
+ :stream,
229
+ msg: {
230
+ true => "Streaming enabled.",
231
+ false => "Streaming disabled.",
232
+ }
233
+ )
225
234
 
226
- $stream = Switch.new(
227
- :stream,
228
- msg: {
229
- true => "Streaming enabled.",
230
- false => "Streaming disabled.",
231
- }
232
- )
235
+ $voice = Switch.new(
236
+ :stream,
237
+ msg: {
238
+ true => "Voice output enabled.",
239
+ false => "Voice output disabled.",
240
+ },
241
+ config: $config.voice
242
+ )
233
243
 
234
- $voice = Switch.new(
235
- :stream,
236
- msg: {
237
- true => "Voice output enabled.",
238
- false => "Voice output disabled.",
239
- },
240
- config: $config.voice
241
- )
244
+ $embedding_enabled = Switch.new(
245
+ :embedding_enabled,
246
+ msg: {
247
+ true => "Embedding enabled.",
248
+ false => "Embedding disabled.",
249
+ }
250
+ )
242
251
 
243
- $embedding_enabled = Switch.new(
244
- :embedding_enabled,
245
- msg: {
246
- true => "Embedding enabled.",
247
- false => "Embedding disabled.",
248
- }
249
- )
252
+ $embedding_paused = Switch.new(
253
+ :embedding_paused,
254
+ msg: {
255
+ true => "Embedding paused.",
256
+ false => "Embedding resumed.",
257
+ }
258
+ )
250
259
 
251
- $embedding_paused = Switch.new(
252
- :embedding_paused,
253
- msg: {
254
- true => "Embedding paused.",
255
- false => "Embedding resumed.",
256
- }
257
- )
260
+ $embedding = CombinedSwitch.new(
261
+ value: -> { $embedding_enabled.on? && $embedding_paused.off? },
262
+ msg: {
263
+ true => "Embedding is currently performed.",
264
+ false => "Embedding is currently not performed.",
265
+ }
266
+ )
258
267
 
259
- $embedding = CombinedSwitch.new(
260
- value: -> { $embedding_enabled.on? && $embedding_paused.off? },
261
- msg: {
262
- true => "Embedding is currently performed.",
263
- false => "Embedding is currently not performed.",
264
- }
265
- )
268
+ $location = Switch.new(
269
+ :location,
270
+ msg: {
271
+ true => "Location and localtime enabled.",
272
+ false => "Location and localtime disabled.",
273
+ },
274
+ config: $config.location.enabled
275
+ )
276
+ end
277
+ end
278
+ include Switches
266
279
 
267
- $location = Switch.new(
268
- :location,
269
- msg: {
270
- true => "Location and localtime enabled.",
271
- false => "Location and localtime disabled.",
272
- },
273
- config: $config.location.enabled
274
- )
280
+ def pull_model_unless_present(model, options, retried = false)
281
+ ollama.show(name: model) { |response|
282
+ puts "Model #{bold{model}} with architecture "\
283
+ "#{response.model_info['general.architecture']} found."
284
+ if system = response.system
285
+ puts "Configured model system prompt is:\n#{italic { system }}"
286
+ return system
287
+ else
288
+ return
289
+ end
290
+ }
291
+ rescue Errors::NotFoundError
292
+ puts "Model #{bold{model}} not found locally, attempting to pull it from remote now…"
293
+ ollama.pull(name: model)
294
+ if retried
295
+ exit 1
296
+ else
297
+ retried = true
298
+ retry
299
+ end
300
+ rescue Errors::Error => e
301
+ warn "Caught #{e.class} while pulling model: #{e} => Exiting."
302
+ exit 1
275
303
  end
276
304
 
277
305
  def search_web(query, n = nil)
@@ -282,7 +310,7 @@ def search_web(query, n = nil)
282
310
  n < 1 and n = 1
283
311
  query = URI.encode_uri_component(query)
284
312
  url = "https://www.duckduckgo.com/html/?q=#{query}"
285
- Ollama::Utils::Fetcher.get(url, debug: $config.debug) do |tmp|
313
+ Utils::Fetcher.get(url, debug: $config.debug) do |tmp|
286
314
  result = []
287
315
  doc = Nokogiri::HTML(tmp)
288
316
  doc.css('.results_links').each do |link|
@@ -303,38 +331,13 @@ def search_web(query, n = nil)
303
331
  end
304
332
  end
305
333
 
306
- def pull_model_unless_present(model, options, retried = false)
307
- ollama.show(name: model) { |response|
308
- puts "Model #{bold{model}} with architecture "\
309
- "#{response.model_info['general.architecture']} found."
310
- if system = response.system
311
- puts "Configured model system prompt is:\n#{italic { system }}"
312
- return system
313
- else
314
- return
315
- end
316
- }
317
- rescue Errors::NotFoundError
318
- puts "Model #{bold{model}} not found locally, attempting to pull it from remote now…"
319
- ollama.pull(name: model)
320
- if retried
321
- exit 1
322
- else
323
- retried = true
324
- retry
325
- end
326
- rescue Errors::Error => e
327
- warn "Caught #{e.class} while pulling model: #{e} => Exiting."
328
- exit 1
329
- end
330
-
331
334
  def load_conversation(filename)
332
335
  unless File.exist?(filename)
333
336
  puts "File #{filename} doesn't exist. Choose another filename."
334
337
  return
335
338
  end
336
339
  File.open(filename, 'r') do |output|
337
- return JSON(output.read).map { Ollama::Message.from_hash(_1) }
340
+ return JSON(output.read).map { Message.from_hash(_1) }
338
341
  end
339
342
  end
340
343
 
@@ -504,7 +507,7 @@ def fetch_source(source, &block)
504
507
  source,
505
508
  cache: $cache,
506
509
  debug: $config.debug,
507
- http_options: http_options(source)
510
+ http_options: http_options(Utils::Fetcher.normalize_url(source))
508
511
  ) do |tmp|
509
512
  block.(tmp)
510
513
  end
@@ -518,7 +521,7 @@ def fetch_source(source, &block)
518
521
  raise "invalid source"
519
522
  end
520
523
  rescue => e
521
- STDERR.puts "Cannot fetch source #{source.to_s.inspect}: #{e}\n#{e.backtrace * ?\n}"
524
+ STDERR.puts "Cannot fetch source #{source.to_s.inspect}: #{e.class} #{e}\n#{e.backtrace * ?\n}"
522
525
  end
523
526
 
524
527
  def add_image(images, source_io, source)
@@ -530,7 +533,8 @@ end
530
533
  def import_source(source_io, source)
531
534
  source = source.to_s
532
535
  puts "Importing #{italic { source_io&.content_type }} document #{source.inspect} now."
533
- "Imported #{source.inspect}:\n%s\n\n" % parse_source(source_io)
536
+ source_content = parse_source(source_io)
537
+ "Imported #{source.inspect}:\n#{source_content}\n\n"
534
538
  end
535
539
 
536
540
  def import(source)
@@ -572,17 +576,17 @@ def embed_source(source_io, source, count: nil)
572
576
  inputs = nil
573
577
  case splitter_config.name
574
578
  when 'Character'
575
- splitter = Ollama::Documents::Splitters::Character.new(
579
+ splitter = Documents::Splitters::Character.new(
576
580
  chunk_size: splitter_config.chunk_size,
577
581
  )
578
582
  inputs = splitter.split(text)
579
583
  when 'RecursiveCharacter'
580
- splitter = Ollama::Documents::Splitters::RecursiveCharacter.new(
584
+ splitter = Documents::Splitters::RecursiveCharacter.new(
581
585
  chunk_size: splitter_config.chunk_size,
582
586
  )
583
587
  inputs = splitter.split(text)
584
588
  when 'Semantic'
585
- splitter = Ollama::Documents::Splitters::Semantic.new(
589
+ splitter = Documents::Splitters::Semantic.new(
586
590
  ollama:, model: $config.embedding.model.name,
587
591
  chunk_size: splitter_config.chunk_size,
588
592
  )
@@ -597,7 +601,7 @@ def embed_source(source_io, source, count: nil)
597
601
  inputs or return
598
602
  source = source.to_s
599
603
  if source.start_with?(?!)
600
- source = Ollama::Utils::Width.truncate(
604
+ source = Utils::Width.truncate(
601
605
  source[1..-1].gsub(/\W+/, ?_),
602
606
  length: 10
603
607
  )
@@ -662,7 +666,7 @@ end
662
666
  def choose_model(cli_model, current_model)
663
667
  models = ollama.tags.models.map(&:name).sort
664
668
  model = if cli_model == ''
665
- Ollama::Utils::Chooser.choose(models) || current_model
669
+ Utils::Chooser.choose(models) || current_model
666
670
  else
667
671
  cli_model || current_model
668
672
  end
@@ -679,7 +683,7 @@ def choose_collection(current_collection)
679
683
  collections = [ current_collection ] + $documents.collections
680
684
  collections = collections.compact.map(&:to_s).uniq.sort
681
685
  collections.unshift('[EXIT]').unshift('[NEW]')
682
- collection = Ollama::Utils::Chooser.choose(collections) || current_collection
686
+ collection = Utils::Chooser.choose(collections) || current_collection
683
687
  case collection
684
688
  when '[NEW]'
685
689
  $documents.collection = ask?(prompt: "Enter name of the new collection: ")
@@ -703,7 +707,7 @@ def choose_document_policy
703
707
  policies.first
704
708
  end
705
709
  policies.unshift('[EXIT]')
706
- policy = Ollama::Utils::Chooser.choose(policies)
710
+ policy = Utils::Chooser.choose(policies)
707
711
  case policy
708
712
  when nil, '[EXIT]'
709
713
  puts "Exiting chooser."
@@ -733,19 +737,19 @@ end
733
737
 
734
738
  def configure_cache
735
739
  if $opts[?M]
736
- Ollama::Documents::MemoryCache
740
+ Documents::MemoryCache
737
741
  else
738
742
  Object.const_get($config.cache)
739
743
  end
740
744
  rescue => e
741
745
  STDERR.puts "Caught #{e.class}: #{e} => Falling back to MemoryCache."
742
- Ollama::Documents::MemoryCache
746
+ Documents::MemoryCache
743
747
  end
744
748
 
745
749
  def show_system_prompt
746
750
  puts <<~EOT
747
751
  Configured system prompt is:
748
- #{Ollama::Utils::ANSIMarkdown.parse($system.to_s).gsub(/\n+\z/, '').full? || 'n/a'}
752
+ #{Utils::ANSIMarkdown.parse($system.to_s).gsub(/\n+\z/, '').full? || 'n/a'}
749
753
  EOT
750
754
  end
751
755
 
@@ -769,7 +773,7 @@ end
769
773
 
770
774
  def change_system_prompt(messages, default)
771
775
  prompts = $config.system_prompts.attribute_names.compact
772
- chosen = Ollama::Utils::Chooser.choose(prompts)
776
+ chosen = Utils::Chooser.choose(prompts)
773
777
  system = if chosen
774
778
  $config.system_prompts.send(chosen)
775
779
  else
@@ -779,7 +783,7 @@ def change_system_prompt(messages, default)
779
783
  end
780
784
 
781
785
  def change_voice
782
- chosen = Ollama::Utils::Chooser.choose($config.voice.list)
786
+ chosen = Utils::Chooser.choose($config.voice.list)
783
787
  $current_voice = chosen.full? || $config.voice.default
784
788
  end
785
789
 
@@ -872,7 +876,7 @@ def usage
872
876
  end
873
877
 
874
878
  def version
875
- puts "%s %s" % [ File.basename($0), Ollama::VERSION ]
879
+ puts "%s %s" % [ File.basename($0), VERSION ]
876
880
  exit 0
877
881
  end
878
882
 
@@ -907,7 +911,7 @@ else
907
911
  if $opts[?s] == ??
908
912
  change_system_prompt(messages, default)
909
913
  else
910
- system = Ollama::Utils::FileArgument.get_file_argument($opts[?s], default:)
914
+ system = Utils::FileArgument.get_file_argument($opts[?s], default:)
911
915
  system.present? and set_system_prompt(messages, system)
912
916
  end
913
917
  end
@@ -957,7 +961,7 @@ else
957
961
  end
958
962
 
959
963
  if redis_expiring_url = $config.redis.expiring.url?
960
- $cache = Ollama::Documents::RedisCache.new(
964
+ $cache = Documents::RedisCache.new(
961
965
  prefix: 'Expiring-',
962
966
  url: redis_expiring_url,
963
967
  ex: $config.redis.expiring.ex,
@@ -1051,7 +1055,7 @@ loop do
1051
1055
  when 'clear'
1052
1056
  loop do
1053
1057
  tags = $documents.tags.add('[EXIT]').add('[ALL]')
1054
- tag = Ollama::Utils::Chooser.choose(tags, prompt: 'Clear? %s')
1058
+ tag = Utils::Chooser.choose(tags, prompt: 'Clear? %s')
1055
1059
  case tag
1056
1060
  when nil, '[EXIT]'
1057
1061
  puts "Exiting chooser."
@@ -38,6 +38,13 @@ class Ollama::Utils::Fetcher
38
38
  end
39
39
  end
40
40
 
41
+ def self.normalize_url(url)
42
+ url = url.to_s
43
+ url = URI.decode_uri_component(url)
44
+ url = url.sub(/#.*/, '')
45
+ URI::Parser.new.escape(url).to_s
46
+ end
47
+
41
48
  def self.read(filename, &block)
42
49
  if File.exist?(filename)
43
50
  File.open(filename) do |file|
@@ -80,6 +87,7 @@ class Ollama::Utils::Fetcher
80
87
  private
81
88
 
82
89
  def excon(url, **options)
90
+ url = self.class.normalize_url(url)
83
91
  Excon.new(url, options.merge(@http_options))
84
92
  end
85
93
 
@@ -1,6 +1,6 @@
1
1
  module Ollama
2
2
  # Ollama version
3
- VERSION = '0.9.0'
3
+ VERSION = '0.9.1'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/ollama-ruby.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama-ruby 0.9.0 ruby lib
2
+ # stub: ollama-ruby 0.9.1 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama-ruby".freeze
6
- s.version = "0.9.0".freeze
6
+ s.version = "0.9.1".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2024-10-18"
11
+ s.date = "2024-10-19"
12
12
  s.description = "Library that allows interacting with the Ollama API".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_console".freeze, "ollama_chat".freeze, "ollama_update".freeze, "ollama_cli".freeze]
@@ -19,7 +19,7 @@ RSpec.describe Ollama::Utils::Fetcher do
19
19
  end
20
20
 
21
21
  it 'can #get with streaming' do
22
- stub_request(:get, 'https://www.example.com/hello').
22
+ stub_request(:get, url).
23
23
  with(headers: fetcher.headers).
24
24
  to_return(
25
25
  status: 200,
@@ -37,7 +37,7 @@ RSpec.describe Ollama::Utils::Fetcher do
37
37
  fetcher = described_class.new(
38
38
  http_options: { ssl_verify_peer: false }
39
39
  ).expose
40
- stub_request(:get, 'https://www.example.com/hello').
40
+ stub_request(:get, url).
41
41
  with(headers: fetcher.headers).
42
42
  to_return(
43
43
  status: 200,
@@ -45,7 +45,7 @@ RSpec.describe Ollama::Utils::Fetcher do
45
45
  headers: { 'Content-Type' => 'text/plain' },
46
46
  )
47
47
  expect(Excon).to receive(:new).with(
48
- 'https://www.example.com/hello',
48
+ url,
49
49
  hash_including(ssl_verify_peer: false)
50
50
  ).and_call_original
51
51
  fetcher.get(url) do |tmp|
@@ -56,7 +56,7 @@ RSpec.describe Ollama::Utils::Fetcher do
56
56
  end
57
57
 
58
58
  it 'can #get and fallback from streaming' do
59
- stub_request(:get, 'https://www.example.com/hello').
59
+ stub_request(:get, url).
60
60
  with(headers: fetcher.headers).
61
61
  to_return(
62
62
  { status: 501 },
@@ -74,9 +74,10 @@ RSpec.describe Ollama::Utils::Fetcher do
74
74
  end
75
75
 
76
76
  it 'can #get and finally fail' do
77
- stub_request(:get, 'https://www.example.com/hello').
77
+ stub_request(:get, url).
78
78
  with(headers: fetcher.headers).
79
79
  to_return(status: 500)
80
+ expect(STDERR).to receive(:puts).with(/cannot.*get.*#{url}/i)
80
81
  fetcher.get(url) do |tmp|
81
82
  expect(tmp).to be_a StringIO
82
83
  expect(tmp.read).to eq ''
@@ -106,10 +107,31 @@ RSpec.describe Ollama::Utils::Fetcher do
106
107
 
107
108
  it 'can .execute and fail' do
108
109
  expect(IO).to receive(:popen).and_raise StandardError
110
+ expect(STDERR).to receive(:puts).with(/cannot.*execute.*foobar/i)
109
111
  described_class.execute('foobar') do |file|
110
112
  expect(file).to be_a StringIO
111
113
  expect(file.read).to be_empty
112
114
  expect(file.content_type).to eq 'text/plain'
113
115
  end
114
116
  end
117
+
118
+ describe '.normalize_url' do
119
+ it 'can handle umlauts' do
120
+ expect(described_class.normalize_url('https://foo.de/bär')).to eq(
121
+ 'https://foo.de/b%C3%A4r'
122
+ )
123
+ end
124
+
125
+ it 'can handle escaped umlauts' do
126
+ expect(described_class.normalize_url('https://foo.de/b%C3%A4r')).to eq(
127
+ 'https://foo.de/b%C3%A4r'
128
+ )
129
+ end
130
+
131
+ it 'can remove #anchors' do
132
+ expect(described_class.normalize_url('https://foo.de#bar')).to eq(
133
+ 'https://foo.de'
134
+ )
135
+ end
136
+ end
115
137
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ollama-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-18 00:00:00.000000000 Z
11
+ date: 2024-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar