ollama-ruby 0.5.0 → 0.6.0
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/.envrc +1 -0
- data/README.md +4 -1
- data/Rakefile +1 -0
- data/bin/ollama_chat +240 -79
- data/docker-compose.yml +3 -4
- data/lib/ollama/client.rb +2 -2
- data/lib/ollama/documents.rb +6 -2
- data/lib/ollama/utils/cache_fetcher.rb +38 -0
- data/lib/ollama/utils/fetcher.rb +50 -33
- data/lib/ollama/utils/file_argument.rb +3 -1
- data/lib/ollama/version.rb +1 -1
- data/ollama-ruby.gemspec +7 -6
- data/spec/ollama/utils/cache_fetcher_spec.rb +42 -0
- data/spec/ollama/utils/fetcher_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb7858cf04c638fa3369fe7d96d96eed12e5553fd17abe9ed48c1eaf25113ffb
|
4
|
+
data.tar.gz: ccb56d4b85a6e74256feb52ac5642d50850f7b980f9060dbb9fdf933985be746
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36aacde399c0be934425f12669fa6cc55cdfad938ea8157c5195db8c2367243cc6470dff24ec5bf83800079732bfa271450a4779246335c45c2bedbb0e3a6cf
|
7
|
+
data.tar.gz: 56e465f056934210a6cc45677d52518d8adb76e8702561248b6db4cd1e4b129cfd22eedbdcc0c935f69bf85eeb9bc324aef6876f39969942af4529978a277756
|
data/.envrc
CHANGED
data/README.md
CHANGED
@@ -45,7 +45,6 @@ ollama_chat [OPTIONS]
|
|
45
45
|
-D DOCUMENT load document and add to collection (multiple)
|
46
46
|
-M use (empty) MemoryCache for this chat session
|
47
47
|
-E disable embeddings for this chat session
|
48
|
-
-v use voice output
|
49
48
|
-h this help
|
50
49
|
```
|
51
50
|
|
@@ -154,13 +153,17 @@ subject - the young, blue-eyed cat.
|
|
154
153
|
The following commands can be given inside the chat, if prefixed by a `/`:
|
155
154
|
|
156
155
|
```
|
156
|
+
/copy to copy last response to clipboard
|
157
157
|
/paste to paste content
|
158
158
|
/markdown toggle markdown output
|
159
|
+
/stream toggle stream output
|
160
|
+
/voice( change) toggle voice output or change the voice
|
159
161
|
/list [n] list the last n / all conversation exchanges
|
160
162
|
/clear clear the whole conversation
|
161
163
|
/clobber clear the conversation and collection
|
162
164
|
/pop [n] pop the last n exchanges, defaults to 1
|
163
165
|
/model change the model
|
166
|
+
/system change system prompt (clears conversation)
|
164
167
|
/regenerate the last answer message
|
165
168
|
/collection clear [tag]|change clear or show stats of current collection
|
166
169
|
/import source import the source's content
|
data/Rakefile
CHANGED
@@ -41,6 +41,7 @@ GemHadar do
|
|
41
41
|
dependency 'pdf-reader', '~> 2.0'
|
42
42
|
dependency 'logger', '~> 1.0'
|
43
43
|
dependency 'json', '~> 2.0'
|
44
|
+
dependency 'xdg', '~> 7.0'
|
44
45
|
development_dependency 'all_images', '~> 0.4'
|
45
46
|
development_dependency 'rspec', '~> 3.2'
|
46
47
|
development_dependency 'webmock'
|
data/bin/ollama_chat
CHANGED
@@ -17,6 +17,7 @@ require 'nokogiri'
|
|
17
17
|
require 'rss'
|
18
18
|
require 'pdf/reader'
|
19
19
|
require 'csv'
|
20
|
+
require 'xdg'
|
20
21
|
|
21
22
|
class OllamaChatConfig
|
22
23
|
include ComplexConfig
|
@@ -31,7 +32,6 @@ class OllamaChatConfig
|
|
31
32
|
options:
|
32
33
|
num_ctx: 8192
|
33
34
|
prompts:
|
34
|
-
system: <%= ENV.fetch('OLLAMA_CHAT_SYSTEM', 'null') %>
|
35
35
|
embed: "This source was now embedded: %{source}"
|
36
36
|
summarize: |
|
37
37
|
Generate an abstract summary of the content in this document using
|
@@ -42,8 +42,14 @@ class OllamaChatConfig
|
|
42
42
|
Answer the the query %{query} using these sources and summaries:
|
43
43
|
|
44
44
|
%{results}
|
45
|
-
|
45
|
+
system_prompts:
|
46
|
+
default: <%= ENV.fetch('OLLAMA_CHAT_SYSTEM', 'null') %>
|
47
|
+
voice:
|
48
|
+
enabled: false
|
49
|
+
default: Samantha
|
50
|
+
list: <%= `say -v ?`.lines.map { _1[/^(.+?)\s+[a-z]{2}_[a-zA-Z0-9]{2,}/, 1] }.uniq.sort.to_s.force_encoding('ASCII-8BIT') %>
|
46
51
|
markdown: true
|
52
|
+
stream: true
|
47
53
|
embedding:
|
48
54
|
enabled: true
|
49
55
|
model:
|
@@ -57,14 +63,16 @@ class OllamaChatConfig
|
|
57
63
|
splitter:
|
58
64
|
name: RecursiveCharacter
|
59
65
|
chunk_size: 1024
|
60
|
-
cache: Ollama::Documents::
|
66
|
+
cache: Ollama::Documents::RedisBackedMemoryCache
|
61
67
|
redis:
|
62
68
|
documents:
|
63
69
|
url: <%= ENV.fetch('REDIS_URL', 'null') %>
|
64
70
|
expiring:
|
65
71
|
url: <%= ENV.fetch('REDIS_EXPIRING_URL', 'null') %>
|
72
|
+
ex: 86400
|
66
73
|
debug: <%= ENV['OLLAMA_CHAT_DEBUG'].to_i == 1 ? true : false %>
|
67
74
|
ssl_no_verify: []
|
75
|
+
copy: pbcopy
|
68
76
|
EOT
|
69
77
|
|
70
78
|
def initialize(filename = nil)
|
@@ -75,7 +83,7 @@ class OllamaChatConfig
|
|
75
83
|
if @filename == default_path && !retried
|
76
84
|
retried = true
|
77
85
|
mkdir_p File.dirname(default_path)
|
78
|
-
File.secure_write(default_path, DEFAULT_CONFIG)
|
86
|
+
File.secure_write(default_path.to_s, DEFAULT_CONFIG)
|
79
87
|
retry
|
80
88
|
else
|
81
89
|
raise
|
@@ -87,17 +95,11 @@ class OllamaChatConfig
|
|
87
95
|
attr_reader :config
|
88
96
|
|
89
97
|
def default_path
|
90
|
-
|
98
|
+
config_dir_path + 'config.yml'
|
91
99
|
end
|
92
100
|
|
93
101
|
def config_dir_path
|
94
|
-
|
95
|
-
ENV.fetch(
|
96
|
-
'XDG_CONFIG_HOME',
|
97
|
-
File.join(ENV.fetch('HOME'), '.config')
|
98
|
-
),
|
99
|
-
'ollama_chat'
|
100
|
-
)
|
102
|
+
XDG.new.config_home + 'ollama_chat'
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
@@ -158,12 +160,113 @@ class FollowChat
|
|
158
160
|
end
|
159
161
|
end
|
160
162
|
|
163
|
+
module CheckSwitch
|
164
|
+
extend Tins::Concern
|
165
|
+
|
166
|
+
included do
|
167
|
+
alias_method :on?, :value
|
168
|
+
end
|
169
|
+
|
170
|
+
def off?
|
171
|
+
!on?
|
172
|
+
end
|
173
|
+
|
174
|
+
def show
|
175
|
+
puts @msg[value]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class Switch
|
180
|
+
def initialize(name, msg:, config: $config)
|
181
|
+
@value = !!config.send("#{name}?")
|
182
|
+
@msg = msg
|
183
|
+
end
|
184
|
+
|
185
|
+
attr_reader :value
|
186
|
+
|
187
|
+
def set(value, show: false)
|
188
|
+
@value = !!value
|
189
|
+
show && self.show
|
190
|
+
end
|
191
|
+
|
192
|
+
def toggle(show: true)
|
193
|
+
@value = !@value
|
194
|
+
show && self.show
|
195
|
+
end
|
196
|
+
|
197
|
+
include CheckSwitch
|
198
|
+
end
|
199
|
+
|
200
|
+
class CombinedSwitch
|
201
|
+
def initialize(value:, msg:)
|
202
|
+
@value = value
|
203
|
+
@msg = msg
|
204
|
+
end
|
205
|
+
|
206
|
+
def value
|
207
|
+
@value.()
|
208
|
+
end
|
209
|
+
|
210
|
+
include CheckSwitch
|
211
|
+
end
|
212
|
+
|
213
|
+
def setup_switches
|
214
|
+
$markdown = Switch.new(
|
215
|
+
:markdown,
|
216
|
+
msg: {
|
217
|
+
true => "Using #{italic{'ANSI'}} markdown to output content.",
|
218
|
+
false => "Using plaintext for outputting content.",
|
219
|
+
}
|
220
|
+
)
|
221
|
+
|
222
|
+
$stream = Switch.new(
|
223
|
+
:stream,
|
224
|
+
msg: {
|
225
|
+
true => "Streaming enabled.",
|
226
|
+
false => "Streaming disabled.",
|
227
|
+
}
|
228
|
+
)
|
229
|
+
|
230
|
+
$voice = Switch.new(
|
231
|
+
:stream,
|
232
|
+
msg: {
|
233
|
+
true => "Voice output enabled.",
|
234
|
+
false => "Voice output disabled.",
|
235
|
+
},
|
236
|
+
config: $config.voice
|
237
|
+
)
|
238
|
+
|
239
|
+
$embedding_enabled = Switch.new(
|
240
|
+
:embedding_enabled,
|
241
|
+
msg: {
|
242
|
+
true => "Embedding enabled.",
|
243
|
+
false => "Embedding disabled.",
|
244
|
+
}
|
245
|
+
)
|
246
|
+
|
247
|
+
$embedding_paused = Switch.new(
|
248
|
+
:embedding_paused,
|
249
|
+
msg: {
|
250
|
+
true => "Embedding paused.",
|
251
|
+
false => "Embedding resumed.",
|
252
|
+
}
|
253
|
+
)
|
254
|
+
|
255
|
+
$embedding = CombinedSwitch.new(
|
256
|
+
value: -> { $embedding_enabled.on? && $embedding_paused.off? },
|
257
|
+
msg: {
|
258
|
+
true => "Embedding is currently performed.",
|
259
|
+
false => "Embedding is currently not performed.",
|
260
|
+
}
|
261
|
+
)
|
262
|
+
end
|
263
|
+
|
161
264
|
def search_web(query, n = nil)
|
162
265
|
n = n.to_i
|
163
266
|
n < 1 and n = 1
|
164
267
|
query = URI.encode_uri_component(query)
|
165
268
|
url = "https://www.duckduckgo.com/html/?q=#{query}"
|
166
|
-
Ollama::Utils::Fetcher.
|
269
|
+
Ollama::Utils::Fetcher.get(url, debug: $config.debug) do |tmp|
|
167
270
|
result = []
|
168
271
|
doc = Nokogiri::HTML(tmp)
|
169
272
|
doc.css('.results_links').each do |link|
|
@@ -196,7 +299,7 @@ def pull_model_unless_present(model, options, retried = false)
|
|
196
299
|
end
|
197
300
|
}
|
198
301
|
rescue Errors::NotFoundError
|
199
|
-
puts "Model #{bold{model}} not found, attempting to pull it now…"
|
302
|
+
puts "Model #{bold{model}} not found locally, attempting to pull it from remote now…"
|
200
303
|
ollama.pull(name: model)
|
201
304
|
if retried
|
202
305
|
exit 1
|
@@ -205,7 +308,7 @@ rescue Errors::NotFoundError
|
|
205
308
|
retry
|
206
309
|
end
|
207
310
|
rescue Errors::Error => e
|
208
|
-
warn "Caught #{e.class}: #{e} => Exiting."
|
311
|
+
warn "Caught #{e.class} while pulling model: #{e} => Exiting."
|
209
312
|
exit 1
|
210
313
|
end
|
211
314
|
|
@@ -242,7 +345,7 @@ def list_conversation(messages, last = nil)
|
|
242
345
|
when 'system' then 213
|
243
346
|
else 210
|
244
347
|
end
|
245
|
-
content = m.content.full? { $markdown ? Utils::ANSIMarkdown.parse(_1) : _1 }
|
348
|
+
content = m.content.full? { $markdown.on? ? Utils::ANSIMarkdown.parse(_1) : _1 }
|
246
349
|
message_text = message_type(m.images) + " "
|
247
350
|
message_text += bold { color(role_color) { m.role } }
|
248
351
|
message_text += ":\n#{content}"
|
@@ -319,8 +422,6 @@ def parse_source(source_io)
|
|
319
422
|
result << "\n\n"
|
320
423
|
end
|
321
424
|
result
|
322
|
-
when %r(\Atext/)
|
323
|
-
source_io.read
|
324
425
|
when 'application/rss+xml'
|
325
426
|
parse_rss(source_io)
|
326
427
|
when 'application/atom+xml'
|
@@ -330,6 +431,8 @@ def parse_source(source_io)
|
|
330
431
|
when 'application/pdf'
|
331
432
|
reader = PDF::Reader.new(source_io)
|
332
433
|
reader.pages.inject(+'') { |result, page| result << page.text }
|
434
|
+
when %r(\Atext/), nil
|
435
|
+
source_io.read
|
333
436
|
else
|
334
437
|
STDERR.puts "Cannot embed #{source_io&.content_type} document."
|
335
438
|
return
|
@@ -337,7 +440,7 @@ def parse_source(source_io)
|
|
337
440
|
end
|
338
441
|
|
339
442
|
def embed_source(source_io, source)
|
340
|
-
|
443
|
+
$embedding.on? or return parse_source(source_io)
|
341
444
|
puts "Embedding #{italic { source_io&.content_type }} document #{source.to_s.inspect}."
|
342
445
|
text = parse_source(source_io) or return
|
343
446
|
text.downcase!
|
@@ -404,7 +507,12 @@ def fetch_source(source, &block)
|
|
404
507
|
block.(tmp)
|
405
508
|
end
|
406
509
|
when %r(\Ahttps?://\S+)
|
407
|
-
Utils::Fetcher.get(
|
510
|
+
Utils::Fetcher.get(
|
511
|
+
source,
|
512
|
+
cache: $cache,
|
513
|
+
debug: $config.debug,
|
514
|
+
http_options: http_options(source)
|
515
|
+
) do |tmp|
|
408
516
|
block.(tmp)
|
409
517
|
end
|
410
518
|
when %r(\Afile://(?:(?:[.-]|[[:alnum:]])*)(/\S*)|([~.]?/\S*))
|
@@ -417,7 +525,7 @@ def fetch_source(source, &block)
|
|
417
525
|
raise "invalid source"
|
418
526
|
end
|
419
527
|
rescue => e
|
420
|
-
STDERR.puts "Cannot
|
528
|
+
STDERR.puts "Cannot fetch source #{source.to_s.inspect}: #{e}\n#{e.backtrace * ?\n}"
|
421
529
|
end
|
422
530
|
|
423
531
|
def import(source)
|
@@ -445,7 +553,7 @@ def summarize(source, words: nil)
|
|
445
553
|
end
|
446
554
|
|
447
555
|
def embed(source)
|
448
|
-
if
|
556
|
+
if $embedding.on?
|
449
557
|
puts "Now embedding #{source.to_s.inspect}."
|
450
558
|
fetch_source(source) do |source_io|
|
451
559
|
content = parse_source(source_io)
|
@@ -537,62 +645,84 @@ rescue => e
|
|
537
645
|
Ollama::Documents::MemoryCache
|
538
646
|
end
|
539
647
|
|
540
|
-
def
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
def show_markdown
|
546
|
-
if $markdown
|
547
|
-
puts "Using ANSI markdown to output content."
|
548
|
-
else
|
549
|
-
puts "Using plaintext for outputting content."
|
550
|
-
end
|
551
|
-
$markdown
|
552
|
-
end
|
553
|
-
|
554
|
-
def set_embedding(embedding)
|
555
|
-
$embedding_enabled = embedding
|
556
|
-
show_embedding
|
648
|
+
def show_system_prompt
|
649
|
+
puts <<~EOT
|
650
|
+
Configured system prompt is:
|
651
|
+
#{Ollama::Utils::ANSIMarkdown.parse($system.to_s).gsub(/\n+\z/, '').full? || 'n/a'}
|
652
|
+
EOT
|
557
653
|
end
|
558
654
|
|
559
|
-
def
|
560
|
-
|
561
|
-
|
655
|
+
def set_system_prompt(messages, system)
|
656
|
+
$system = system
|
657
|
+
messages.clear
|
658
|
+
messages << Message.new(role: 'system', content: system)
|
562
659
|
end
|
563
660
|
|
564
|
-
def
|
565
|
-
|
661
|
+
def change_system_prompt(messages)
|
662
|
+
prompts = $config.system_prompts.attribute_names.compact
|
663
|
+
chosen = Ollama::Utils::Chooser.choose(prompts)
|
664
|
+
system = if chosen
|
665
|
+
$config.system_prompts.send(chosen)
|
666
|
+
else
|
667
|
+
default
|
668
|
+
end
|
669
|
+
set_system_prompt(messages, system)
|
566
670
|
end
|
567
671
|
|
568
|
-
def
|
569
|
-
|
570
|
-
|
672
|
+
def change_voice
|
673
|
+
chosen = Ollama::Utils::Chooser.choose($config.voice.list)
|
674
|
+
$current_voice = chosen.full? || $config.voice.default
|
571
675
|
end
|
572
676
|
|
573
677
|
def info
|
574
678
|
puts "Current model is #{bold{$model}}."
|
575
679
|
collection_stats
|
576
|
-
|
680
|
+
$embedding.show
|
681
|
+
if $embedding.on?
|
577
682
|
puts "Text splitter is #{bold{$config.embedding.splitter.name}}."
|
578
683
|
end
|
579
|
-
puts "Documents database cache is #{$documents.nil? ? 'n/a' : $documents.cache.class}"
|
580
|
-
|
684
|
+
puts "Documents database cache is #{$documents.nil? ? 'n/a' : bold{$documents.cache.class}}"
|
685
|
+
$markdown.show
|
686
|
+
$stream.show
|
687
|
+
if $voice.on?
|
688
|
+
puts "Using voice #{bold{$current_voice}} to speak."
|
689
|
+
end
|
690
|
+
show_system_prompt
|
581
691
|
end
|
582
692
|
|
583
693
|
def clear_messages(messages)
|
584
694
|
messages.delete_if { _1.role != 'system' }
|
585
695
|
end
|
586
696
|
|
697
|
+
def copy_to_clipboard(messages)
|
698
|
+
if message = messages.last and message.role == 'assistant'
|
699
|
+
copy = `which #{$config.copy}`.chomp
|
700
|
+
if copy.present?
|
701
|
+
IO.popen(copy, 'w') do |clipboard|
|
702
|
+
clipboard.write(message.content)
|
703
|
+
end
|
704
|
+
STDOUT.puts "The last response has been copied to the system clipboard."
|
705
|
+
else
|
706
|
+
STDERR.puts "#{$config.copy.inspect} command not found in system's path!"
|
707
|
+
end
|
708
|
+
else
|
709
|
+
STDERR.puts "No response available to copy to the system clipboard."
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
587
713
|
def display_chat_help
|
588
714
|
puts <<~EOT
|
715
|
+
/copy to copy last response to clipboard
|
589
716
|
/paste to paste content
|
590
717
|
/markdown toggle markdown output
|
718
|
+
/stream toggle stream output
|
719
|
+
/voice( change) toggle voice output or change the voice
|
591
720
|
/list [n] list the last n / all conversation exchanges
|
592
721
|
/clear clear the whole conversation
|
593
722
|
/clobber clear the conversation and collection
|
594
723
|
/pop [n] pop the last n exchanges, defaults to 1
|
595
724
|
/model change the model
|
725
|
+
/system change system prompt (clears conversation)
|
596
726
|
/regenerate the last answer message
|
597
727
|
/collection clear [tag]|change clear or show stats of current collection
|
598
728
|
/import source import the source's content
|
@@ -620,25 +750,31 @@ def usage
|
|
620
750
|
-D DOCUMENT load document and add to embeddings collection (multiple)
|
621
751
|
-M use (empty) MemoryCache for this chat session
|
622
752
|
-E disable embeddings for this chat session
|
623
|
-
-
|
753
|
+
-V display the current version number and quit
|
624
754
|
-h this help
|
625
755
|
|
626
756
|
EOT
|
627
757
|
exit 0
|
628
758
|
end
|
629
759
|
|
760
|
+
def version
|
761
|
+
puts "%s %s" % [ File.basename($0), Ollama::VERSION ]
|
762
|
+
exit 0
|
763
|
+
end
|
764
|
+
|
630
765
|
def ollama
|
631
766
|
$ollama
|
632
767
|
end
|
633
768
|
|
634
|
-
$opts = go 'f:u:m:s:c:C:D:
|
769
|
+
$opts = go 'f:u:m:s:c:C:D:MEVh'
|
635
770
|
|
636
771
|
config = OllamaChatConfig.new($opts[?f])
|
637
772
|
$config = config.config
|
638
773
|
|
639
|
-
|
774
|
+
setup_switches
|
640
775
|
|
641
|
-
|
776
|
+
$opts[?h] and usage
|
777
|
+
$opts[?V] and version
|
642
778
|
|
643
779
|
base_url = $opts[?u] || $config.url
|
644
780
|
$ollama = Client.new(base_url:, debug: $config.debug)
|
@@ -647,14 +783,21 @@ $model = choose_model($opts[?m], $config.model.name)
|
|
647
783
|
options = Options[$config.model.options]
|
648
784
|
model_system = pull_model_unless_present($model, options)
|
649
785
|
messages = []
|
650
|
-
|
786
|
+
$embedding_enabled.set($config.embedding.enabled && !$opts[?E])
|
651
787
|
|
652
|
-
if
|
653
|
-
|
788
|
+
if $opts[?c]
|
789
|
+
messages.concat load_conversation($opts[?c])
|
790
|
+
else
|
791
|
+
default = $config.system_prompts.default? || model_system
|
792
|
+
if $opts[?s] == ??
|
793
|
+
change_system_prompt(messages)
|
794
|
+
else
|
795
|
+
system = Ollama::Utils::FileArgument.get_file_argument($opts[?s], default:)
|
796
|
+
system.present? and set_system_prompt(messages, system)
|
797
|
+
end
|
654
798
|
end
|
655
|
-
$markdown = $config.markdown
|
656
799
|
|
657
|
-
if
|
800
|
+
if $embedding.on?
|
658
801
|
$embedding_model = $config.embedding.model.name
|
659
802
|
embedding_model_options = Options[$config.embedding.model.options]
|
660
803
|
pull_model_unless_present($embedding_model, embedding_model_options)
|
@@ -666,6 +809,7 @@ if embedding_enabled?
|
|
666
809
|
collection:,
|
667
810
|
cache: configure_cache,
|
668
811
|
redis_url: $config.redis.documents.url?,
|
812
|
+
debug: ENV['DEBUG'].to_i == 1,
|
669
813
|
)
|
670
814
|
|
671
815
|
document_list = $opts[?D].to_a
|
@@ -691,24 +835,22 @@ if embedding_enabled?
|
|
691
835
|
end
|
692
836
|
end
|
693
837
|
end
|
694
|
-
collection_stats
|
695
838
|
else
|
696
839
|
$documents = Tins::NULL
|
697
840
|
end
|
698
841
|
|
699
|
-
if $
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
puts <<~EOT
|
706
|
-
Configured system prompt is:
|
707
|
-
#{italic{Ollama::Utils::Width.wrap(system, percentage: 90)}}
|
708
|
-
EOT
|
709
|
-
end
|
842
|
+
if redis_expiring_url = $config.redis.expiring.url?
|
843
|
+
$cache = Ollama::Documents::RedisCache.new(
|
844
|
+
prefix: 'Expiring-',
|
845
|
+
url: redis_expiring_url,
|
846
|
+
ex: $config.redis.expiring.ex,
|
847
|
+
)
|
710
848
|
end
|
711
849
|
|
850
|
+
$current_voice = $config.voice.default
|
851
|
+
|
852
|
+
puts "Configuration read from #{config.filename.inspect} is:", $config
|
853
|
+
info
|
712
854
|
puts "\nType /help to display the chat help."
|
713
855
|
|
714
856
|
images = []
|
@@ -721,8 +863,21 @@ loop do
|
|
721
863
|
when %r(^/paste$)
|
722
864
|
puts bold { "Paste your content and then press C-d!" }
|
723
865
|
content = STDIN.read
|
866
|
+
when %r(^/copy$)
|
867
|
+
copy_to_clipboard(messages)
|
868
|
+
next
|
724
869
|
when %r(^/markdown$)
|
725
|
-
$markdown
|
870
|
+
$markdown.toggle
|
871
|
+
next
|
872
|
+
when %r(^/stream$)
|
873
|
+
$stream.toggle
|
874
|
+
next
|
875
|
+
when %r(^/voice(?:\s+(change))?$)
|
876
|
+
if $1 == 'change'
|
877
|
+
change_voice
|
878
|
+
else
|
879
|
+
$voice.toggle
|
880
|
+
end
|
726
881
|
next
|
727
882
|
when %r(^/list(?:\s+(\d*))?$)
|
728
883
|
last = if $1
|
@@ -755,6 +910,10 @@ loop do
|
|
755
910
|
choose_collection(collection)
|
756
911
|
end
|
757
912
|
next
|
913
|
+
when %r(^/system$)
|
914
|
+
change_system_prompt(messages)
|
915
|
+
info
|
916
|
+
next
|
758
917
|
when %r(/info)
|
759
918
|
info
|
760
919
|
next
|
@@ -789,7 +948,8 @@ loop do
|
|
789
948
|
parse_content = false
|
790
949
|
content = summarize($2, words: $1) or next
|
791
950
|
when %r(^/embedding$)
|
792
|
-
|
951
|
+
$embedding_paused.toggle(show: false)
|
952
|
+
$embedding.show
|
793
953
|
next
|
794
954
|
when %r(^/embed\s+(.+))
|
795
955
|
parse_content = false
|
@@ -828,12 +988,12 @@ loop do
|
|
828
988
|
end
|
829
989
|
|
830
990
|
content, tags = if parse_content
|
831
|
-
parse_content(content, images
|
991
|
+
parse_content(content, images)
|
832
992
|
else
|
833
993
|
[ content, Utils::Tags.new ]
|
834
994
|
end
|
835
995
|
|
836
|
-
if
|
996
|
+
if $embedding.on? && content
|
837
997
|
records = $documents.find_where(
|
838
998
|
content.downcase,
|
839
999
|
tags:,
|
@@ -847,11 +1007,12 @@ loop do
|
|
847
1007
|
end
|
848
1008
|
end
|
849
1009
|
|
850
|
-
messages << Message.new(role: 'user', content:, images:)
|
851
|
-
|
852
|
-
|
1010
|
+
messages << Message.new(role: 'user', content:, images: images.dup)
|
1011
|
+
images.clear
|
1012
|
+
handler = FollowChat.new(messages:, markdown: $markdown.on?, voice: ($current_voice if $voice.on?))
|
1013
|
+
ollama.chat(model: $model, messages:, options:, stream: $stream.on?, &handler)
|
853
1014
|
|
854
|
-
if
|
1015
|
+
if $embedding.on? && !records.empty?
|
855
1016
|
puts "", records.map { |record|
|
856
1017
|
link = if record.source =~ %r(\Ahttps?://)
|
857
1018
|
record.source
|
data/docker-compose.yml
CHANGED
@@ -2,10 +2,9 @@ services:
|
|
2
2
|
redis:
|
3
3
|
image: redis:7.2.5-alpine
|
4
4
|
restart: unless-stopped
|
5
|
-
ports:
|
6
|
-
- "9736:6379"
|
5
|
+
ports: [ "127.0.0.1:9736:6379" ]
|
7
6
|
volumes:
|
8
|
-
|
9
|
-
|
7
|
+
- "redis-data:/data:delegated"
|
8
|
+
- "./config/redis.conf:/etc/redis.conf"
|
10
9
|
volumes:
|
11
10
|
redis-data:
|
data/lib/ollama/client.rb
CHANGED
@@ -19,8 +19,8 @@ class Ollama::Client
|
|
19
19
|
'missing :base_url parameter or OLLAMA_URL environment variable'
|
20
20
|
end
|
21
21
|
base_url.is_a? URI or base_url = URI.parse(base_url)
|
22
|
-
|
23
|
-
|
22
|
+
base_url.is_a?(URI::HTTP) || base_url.is_a?(URI::HTTPS) or
|
23
|
+
raise ArgumentError, "require #{base_url.inspect} to be http/https-URI"
|
24
24
|
@ssl_verify_peer = base_url.query.to_s.split(?&).inject({}) { |h, l|
|
25
25
|
h.merge Hash[*l.split(?=)]
|
26
26
|
}['ssl_verify_peer'] != 'false'
|
data/lib/ollama/documents.rb
CHANGED
@@ -35,12 +35,13 @@ class Ollama::Documents
|
|
35
35
|
alias inspect to_s
|
36
36
|
end
|
37
37
|
|
38
|
-
def initialize(ollama:, model:, model_options: nil, collection: nil, cache: MemoryCache, redis_url: nil)
|
38
|
+
def initialize(ollama:, model:, model_options: nil, collection: nil, cache: MemoryCache, redis_url: nil, debug: false)
|
39
39
|
collection ||= default_collection
|
40
40
|
@ollama, @model, @model_options, @collection =
|
41
41
|
ollama, model, model_options, collection.to_sym
|
42
42
|
@redis_url = redis_url
|
43
|
-
@cache
|
43
|
+
@cache = connect_cache(cache)
|
44
|
+
@debug = debug
|
44
45
|
end
|
45
46
|
|
46
47
|
def default_collection
|
@@ -64,6 +65,9 @@ class Ollama::Documents
|
|
64
65
|
}
|
65
66
|
inputs.reject! { |i| exist?(i) }
|
66
67
|
inputs.empty? and return self
|
68
|
+
if @debug
|
69
|
+
puts Ollama::Utils::ColorizeTexts.new(inputs)
|
70
|
+
end
|
67
71
|
batches = inputs.each_slice(batch_size).
|
68
72
|
with_infobar(
|
69
73
|
label: "Add #{truncate(tags.to_s, percentage: 25)}",
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
class Ollama::Utils::CacheFetcher
|
4
|
+
def initialize(cache)
|
5
|
+
@cache = cache
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(url, &block)
|
9
|
+
block or raise ArgumentError, 'require block argument'
|
10
|
+
body = @cache[key(:body, url)]
|
11
|
+
content_type = @cache[key(:content_type, url)]
|
12
|
+
content_type = MIME::Types[content_type].first
|
13
|
+
if body && content_type
|
14
|
+
io = StringIO.new(body)
|
15
|
+
io.rewind
|
16
|
+
io.extend(Ollama::Utils::Fetcher::ContentType)
|
17
|
+
io.content_type = content_type
|
18
|
+
block.(io)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def put(url, io)
|
23
|
+
io.rewind
|
24
|
+
body = io.read
|
25
|
+
body.empty? and return
|
26
|
+
content_type = io.content_type
|
27
|
+
content_type.nil? and return
|
28
|
+
@cache[key(:body, url)] = body
|
29
|
+
@cache[key(:content_type, url)] = content_type.to_s
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def key(type, url)
|
36
|
+
[ type, Digest::MD5.hexdigest(url) ] * ?-
|
37
|
+
end
|
38
|
+
end
|
data/lib/ollama/utils/fetcher.rb
CHANGED
@@ -3,6 +3,7 @@ require 'tins/unit'
|
|
3
3
|
require 'infobar'
|
4
4
|
require 'mime-types'
|
5
5
|
require 'stringio'
|
6
|
+
require 'ollama/utils/cache_fetcher'
|
6
7
|
|
7
8
|
class Ollama::Utils::Fetcher
|
8
9
|
module ContentType
|
@@ -17,6 +18,54 @@ class Ollama::Utils::Fetcher
|
|
17
18
|
|
18
19
|
class RetryWithoutStreaming < StandardError; end
|
19
20
|
|
21
|
+
def self.get(url, **options, &block)
|
22
|
+
cache = options.delete(:cache) and
|
23
|
+
cache = Ollama::Utils::CacheFetcher.new(cache)
|
24
|
+
if result = cache&.get(url, &block)
|
25
|
+
infobar.puts "Getting #{url.inspect} from cache."
|
26
|
+
return result
|
27
|
+
else
|
28
|
+
new(**options).send(:get, url) do |tmp|
|
29
|
+
result = block.(tmp)
|
30
|
+
if cache && !tmp.is_a?(StringIO)
|
31
|
+
tmp.rewind
|
32
|
+
cache.put(url, tmp)
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.read(filename, &block)
|
40
|
+
if File.exist?(filename)
|
41
|
+
File.open(filename) do |file|
|
42
|
+
file.extend(Ollama::Utils::Fetcher::ContentType)
|
43
|
+
file.content_type = MIME::Types.type_for(filename).first
|
44
|
+
block.(file)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.execute(command, &block)
|
50
|
+
Tempfile.open do |tmp|
|
51
|
+
IO.popen(command) do |command|
|
52
|
+
until command.eof?
|
53
|
+
tmp.write command.read(4096)
|
54
|
+
end
|
55
|
+
tmp.rewind
|
56
|
+
tmp.extend(Ollama::Utils::Fetcher::ContentType)
|
57
|
+
tmp.content_type = MIME::Types['text/plain'].first
|
58
|
+
block.(tmp)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
rescue => e
|
62
|
+
STDERR.puts "Cannot execute #{command.inspect} (#{e})"
|
63
|
+
if @debug && !e.is_a?(RuntimeError)
|
64
|
+
STDERR.puts "#{e.backtrace * ?\n}"
|
65
|
+
end
|
66
|
+
yield ContentType.failed
|
67
|
+
end
|
68
|
+
|
20
69
|
def initialize(debug: false, http_options: {})
|
21
70
|
@debug = debug
|
22
71
|
@started = false
|
@@ -24,9 +73,7 @@ class Ollama::Utils::Fetcher
|
|
24
73
|
@http_options = http_options
|
25
74
|
end
|
26
75
|
|
27
|
-
|
28
|
-
new(**options).get(url, &block)
|
29
|
-
end
|
76
|
+
private
|
30
77
|
|
31
78
|
def excon(url, **options)
|
32
79
|
Excon.new(url, options.merge(@http_options))
|
@@ -105,34 +152,4 @@ class Ollama::Utils::Fetcher
|
|
105
152
|
}
|
106
153
|
'%l ' + progress + ' in %te, ETA %e @%E'
|
107
154
|
end
|
108
|
-
|
109
|
-
def self.read(filename, &block)
|
110
|
-
if File.exist?(filename)
|
111
|
-
File.open(filename) do |file|
|
112
|
-
file.extend(Ollama::Utils::Fetcher::ContentType)
|
113
|
-
file.content_type = MIME::Types.type_for(filename).first
|
114
|
-
block.(file)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.execute(command, &block)
|
120
|
-
Tempfile.open do |tmp|
|
121
|
-
IO.popen(command) do |command|
|
122
|
-
until command.eof?
|
123
|
-
tmp.write command.read(4096)
|
124
|
-
end
|
125
|
-
tmp.rewind
|
126
|
-
tmp.extend(Ollama::Utils::Fetcher::ContentType)
|
127
|
-
tmp.content_type = MIME::Types['text/plain'].first
|
128
|
-
block.(tmp)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
rescue => e
|
132
|
-
STDERR.puts "Cannot execute #{command.inspect} (#{e})"
|
133
|
-
if @debug && !e.is_a?(RuntimeError)
|
134
|
-
STDERR.puts "#{e.backtrace * ?\n}"
|
135
|
-
end
|
136
|
-
yield ContentType.failed
|
137
|
-
end
|
138
155
|
end
|
data/lib/ollama/version.rb
CHANGED
data/ollama-ruby.gemspec
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: ollama-ruby 0.
|
2
|
+
# stub: ollama-ruby 0.6.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "ollama-ruby".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.6.0".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-09-
|
11
|
+
s.date = "2024-09-30"
|
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]
|
15
|
-
s.extra_rdoc_files = ["README.md".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze]
|
16
|
-
s.files = [".envrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_cli".freeze, "bin/ollama_console".freeze, "bin/ollama_update".freeze, "config/redis.conf".freeze, "docker-compose.yml".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze, "ollama-ruby.gemspec".freeze, "spec/assets/embeddings.json".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
|
15
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/cache_fetcher.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze]
|
16
|
+
s.files = [".envrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_cli".freeze, "bin/ollama_console".freeze, "bin/ollama_update".freeze, "config/redis.conf".freeze, "docker-compose.yml".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/cache_fetcher.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze, "ollama-ruby.gemspec".freeze, "spec/assets/embeddings.json".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/cache_fetcher_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
|
17
17
|
s.homepage = "https://github.com/flori/ollama-ruby".freeze
|
18
18
|
s.licenses = ["MIT".freeze]
|
19
19
|
s.rdoc_options = ["--title".freeze, "Ollama-ruby - Interacting with the Ollama API".freeze, "--main".freeze, "README.md".freeze]
|
20
20
|
s.required_ruby_version = Gem::Requirement.new("~> 3.1".freeze)
|
21
21
|
s.rubygems_version = "3.5.18".freeze
|
22
22
|
s.summary = "Interacting with the Ollama API".freeze
|
23
|
-
s.test_files = ["spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
23
|
+
s.test_files = ["spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/cache_fetcher_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
24
24
|
|
25
25
|
s.specification_version = 4
|
26
26
|
|
@@ -47,4 +47,5 @@ Gem::Specification.new do |s|
|
|
47
47
|
s.add_runtime_dependency(%q<pdf-reader>.freeze, ["~> 2.0".freeze])
|
48
48
|
s.add_runtime_dependency(%q<logger>.freeze, ["~> 1.0".freeze])
|
49
49
|
s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0".freeze])
|
50
|
+
s.add_runtime_dependency(%q<xdg>.freeze, ["~> 7.0".freeze])
|
50
51
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Ollama::Utils::CacheFetcher do
|
4
|
+
let :url do
|
5
|
+
'https://www.example.com/hello'
|
6
|
+
end
|
7
|
+
|
8
|
+
let :cache do
|
9
|
+
double('RedisCache')
|
10
|
+
end
|
11
|
+
|
12
|
+
let :fetcher do
|
13
|
+
described_class.new(cache).expose
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can be instantiated' do
|
17
|
+
expect(fetcher).to be_a described_class
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has #get' do
|
21
|
+
expect(cache).to receive(:[]).with('body-69ce405ab83f42dffa9fd22bbd47783f').and_return 'world'
|
22
|
+
expect(cache).to receive(:[]).with('content_type-69ce405ab83f42dffa9fd22bbd47783f').and_return 'text/plain'
|
23
|
+
yielded_io = nil
|
24
|
+
block = -> io { yielded_io = io }
|
25
|
+
fetcher.get(url, &block)
|
26
|
+
expect(yielded_io).to be_a StringIO
|
27
|
+
expect(yielded_io.read).to eq 'world'
|
28
|
+
end
|
29
|
+
|
30
|
+
it '#get needs block' do
|
31
|
+
expect { fetcher.get(url) }.to raise_error(ArgumentError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'has #put' do
|
35
|
+
io = StringIO.new('world')
|
36
|
+
io.extend(Ollama::Utils::Fetcher::ContentType)
|
37
|
+
io.content_type = MIME::Types['text/plain'].first
|
38
|
+
expect(cache).to receive(:[]=).with('body-69ce405ab83f42dffa9fd22bbd47783f', 'world')
|
39
|
+
expect(cache).to receive(:[]=).with('content_type-69ce405ab83f42dffa9fd22bbd47783f', 'text/plain')
|
40
|
+
fetcher.put(url, io)
|
41
|
+
end
|
42
|
+
end
|
@@ -6,7 +6,7 @@ RSpec.describe Ollama::Utils::Fetcher do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
let :fetcher do
|
9
|
-
described_class.new
|
9
|
+
described_class.new.expose
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'can be instantiated' do
|
@@ -36,7 +36,7 @@ RSpec.describe Ollama::Utils::Fetcher do
|
|
36
36
|
it 'can #get without ssl peer verification' do
|
37
37
|
fetcher = described_class.new(
|
38
38
|
http_options: { ssl_verify_peer: false }
|
39
|
-
)
|
39
|
+
).expose
|
40
40
|
stub_request(:get, 'https://www.example.com/hello').
|
41
41
|
with(headers: fetcher.headers).
|
42
42
|
to_return(
|
data/spec/spec_helper.rb
CHANGED
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.
|
4
|
+
version: 0.6.0
|
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-09-
|
11
|
+
date: 2024-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|
@@ -332,6 +332,20 @@ dependencies:
|
|
332
332
|
- - "~>"
|
333
333
|
- !ruby/object:Gem::Version
|
334
334
|
version: '2.0'
|
335
|
+
- !ruby/object:Gem::Dependency
|
336
|
+
name: xdg
|
337
|
+
requirement: !ruby/object:Gem::Requirement
|
338
|
+
requirements:
|
339
|
+
- - "~>"
|
340
|
+
- !ruby/object:Gem::Version
|
341
|
+
version: '7.0'
|
342
|
+
type: :runtime
|
343
|
+
prerelease: false
|
344
|
+
version_requirements: !ruby/object:Gem::Requirement
|
345
|
+
requirements:
|
346
|
+
- - "~>"
|
347
|
+
- !ruby/object:Gem::Version
|
348
|
+
version: '7.0'
|
335
349
|
description: Library that allows interacting with the Ollama API
|
336
350
|
email: flori@ping.de
|
337
351
|
executables:
|
@@ -387,6 +401,7 @@ extra_rdoc_files:
|
|
387
401
|
- lib/ollama/tool/function/parameters.rb
|
388
402
|
- lib/ollama/tool/function/parameters/property.rb
|
389
403
|
- lib/ollama/utils/ansi_markdown.rb
|
404
|
+
- lib/ollama/utils/cache_fetcher.rb
|
390
405
|
- lib/ollama/utils/chooser.rb
|
391
406
|
- lib/ollama/utils/colorize_texts.rb
|
392
407
|
- lib/ollama/utils/fetcher.rb
|
@@ -453,6 +468,7 @@ files:
|
|
453
468
|
- lib/ollama/tool/function/parameters.rb
|
454
469
|
- lib/ollama/tool/function/parameters/property.rb
|
455
470
|
- lib/ollama/utils/ansi_markdown.rb
|
471
|
+
- lib/ollama/utils/cache_fetcher.rb
|
456
472
|
- lib/ollama/utils/chooser.rb
|
457
473
|
- lib/ollama/utils/colorize_texts.rb
|
458
474
|
- lib/ollama/utils/fetcher.rb
|
@@ -499,6 +515,7 @@ files:
|
|
499
515
|
- spec/ollama/options_spec.rb
|
500
516
|
- spec/ollama/tool_spec.rb
|
501
517
|
- spec/ollama/utils/ansi_markdown_spec.rb
|
518
|
+
- spec/ollama/utils/cache_fetcher_spec.rb
|
502
519
|
- spec/ollama/utils/fetcher_spec.rb
|
503
520
|
- spec/ollama/utils/file_argument_spec.rb
|
504
521
|
- spec/ollama/utils/tags_spec.rb
|
@@ -566,6 +583,7 @@ test_files:
|
|
566
583
|
- spec/ollama/options_spec.rb
|
567
584
|
- spec/ollama/tool_spec.rb
|
568
585
|
- spec/ollama/utils/ansi_markdown_spec.rb
|
586
|
+
- spec/ollama/utils/cache_fetcher_spec.rb
|
569
587
|
- spec/ollama/utils/fetcher_spec.rb
|
570
588
|
- spec/ollama/utils/file_argument_spec.rb
|
571
589
|
- spec/ollama/utils/tags_spec.rb
|