ollama-ruby 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +28 -0
- data/README.md +2 -0
- data/Rakefile +4 -1
- data/bin/ollama_chat +63 -42
- data/lib/ollama/documents/cache/common.rb +17 -0
- data/lib/ollama/documents/{memory_cache.rb → cache/memory_cache.rb} +8 -10
- data/lib/ollama/documents/cache/redis_backed_memory_cache.rb +44 -0
- data/lib/ollama/documents/{redis_cache.rb → cache/redis_cache.rb} +9 -8
- data/lib/ollama/documents.rb +19 -16
- data/lib/ollama/utils/colorize_texts.rb +21 -1
- data/lib/ollama/utils/fetcher.rb +8 -6
- data/lib/ollama/utils/file_argument.rb +18 -0
- data/lib/ollama/utils/tags.rb +1 -0
- data/lib/ollama/version.rb +1 -1
- data/ollama-ruby.gemspec +8 -6
- data/spec/ollama/documents/memory_cache_spec.rb +16 -16
- data/spec/ollama/documents/redis_backed_memory_cache_spec.rb +95 -0
- data/spec/ollama/documents/redis_cache_spec.rb +15 -15
- data/spec/ollama/utils/fetcher_spec.rb +2 -1
- metadata +40 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29863f68627a05541de5eab810850b0509db94c1d91b2e9a5a9be9bd387e8aea
|
4
|
+
data.tar.gz: 07f3558153a0a724c08e27a86482e0951070348bf25641d2a9feed113e3e7046
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11c405277b59c6acc75c24220942dd883bb7aec99d97d19bc9baf8d61aa4e5dc59af905631dc37641b91babdd9e5ab7305720a8720451db7b4bb6ca067833913
|
7
|
+
data.tar.gz: 129f49e2d4b5cb65b7999f666f33798511b8a34b1be84bbc7bd4433872cd7c323812cd4dd3e8d2ae325cb013cfb6403db8181c8cbe641139469e5ea9821cc71d
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
## 2024-09-21 v0.4.0
|
4
|
+
|
5
|
+
### Change Log for **1.2.3**
|
6
|
+
|
7
|
+
#### New Features
|
8
|
+
|
9
|
+
* Added `-E` option to disable embeddings for this chat session.
|
10
|
+
* Added `-M` option to load document embeddings into (empty) MemoryCache for this chat session.
|
11
|
+
* Added CSV parsing support to `ollama_chat`.
|
12
|
+
* Improved error handling in `Ollama::Utils::Fetcher` methods.
|
13
|
+
|
14
|
+
#### Bug Fixes
|
15
|
+
|
16
|
+
* Handle case in `ollama_chat` where responses don't provide counts, display 0
|
17
|
+
rates instead.
|
18
|
+
|
19
|
+
#### Refactoring and Improvements
|
20
|
+
|
21
|
+
* Updated eval count and rate display in FollowChat class.
|
22
|
+
* Refactor system prompt display and chunk listing in chat output.
|
23
|
+
* Refactor cache implementation to use Ollama::Documents::Cache::Common module.
|
24
|
+
* Improved system prompt formatting in `ollama_chat` script.
|
25
|
+
* Renamed `tags` method to `tags_set` in `Ollama::Documents::Record` class.
|
26
|
+
|
27
|
+
#### Documentation
|
28
|
+
|
29
|
+
* Added comments to ColorizeTexts utility class.
|
30
|
+
|
3
31
|
## 2024-09-15 v0.3.2
|
4
32
|
|
5
33
|
* Add color support to chooser module:
|
data/README.md
CHANGED
@@ -43,6 +43,8 @@ ollama_chat [OPTIONS]
|
|
43
43
|
-c CHAT a saved chat conversation to load
|
44
44
|
-C COLLECTION name of the collection used in this conversation
|
45
45
|
-D DOCUMENT load document and add to collection (multiple)
|
46
|
+
-M use (empty) MemoryCache for this chat session
|
47
|
+
-E disable embeddings for this chat session
|
46
48
|
-v use voice output
|
47
49
|
-h this help
|
48
50
|
```
|
data/Rakefile
CHANGED
@@ -13,7 +13,8 @@ GemHadar do
|
|
13
13
|
description 'Library that allows interacting with the Ollama API'
|
14
14
|
test_dir 'spec'
|
15
15
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
|
16
|
-
'.yardoc', 'tags', 'errors.lst', 'cscope.out', 'coverage', 'tmp',
|
16
|
+
'.yardoc', 'doc', 'tags', 'errors.lst', 'cscope.out', 'coverage', 'tmp',
|
17
|
+
'corpus'
|
17
18
|
package_ignore '.all_images.yml', '.tool-versions', '.gitignore', 'VERSION',
|
18
19
|
'.rspec', *Dir.glob('.github/**/*', File::FNM_DOTMATCH)
|
19
20
|
readme 'README.md'
|
@@ -41,6 +42,8 @@ GemHadar do
|
|
41
42
|
development_dependency 'all_images', '~> 0.4'
|
42
43
|
development_dependency 'rspec', '~> 3.2'
|
43
44
|
development_dependency 'webmock'
|
45
|
+
development_dependency 'debug'
|
46
|
+
development_dependency 'simplecov'
|
44
47
|
|
45
48
|
licenses << 'MIT'
|
46
49
|
|
data/bin/ollama_chat
CHANGED
@@ -14,6 +14,7 @@ require 'uri'
|
|
14
14
|
require 'nokogiri'
|
15
15
|
require 'rss'
|
16
16
|
require 'pdf/reader'
|
17
|
+
require 'csv'
|
17
18
|
|
18
19
|
class OllamaChatConfig
|
19
20
|
include ComplexConfig
|
@@ -47,7 +48,7 @@ class OllamaChatConfig
|
|
47
48
|
splitter:
|
48
49
|
name: RecursiveCharacter
|
49
50
|
chunk_size: 1024
|
50
|
-
cache: Ollama::Documents::
|
51
|
+
cache: Ollama::Documents::Cache::RedisBackedMemoryCache
|
51
52
|
redis:
|
52
53
|
url: <%= ENV.fetch('REDIS_URL', 'null') %>
|
53
54
|
debug: <%= ENV['OLLAMA_CHAT_DEBUG'].to_i == 1 ? true : false %>
|
@@ -130,11 +131,11 @@ class FollowChat
|
|
130
131
|
prompt_eval_duration = response.prompt_eval_duration / 1e9
|
131
132
|
stats_text = {
|
132
133
|
eval_duration: Tins::Duration.new(eval_duration),
|
133
|
-
eval_count: response.eval_count,
|
134
|
-
eval_rate: bold { "%.2f c/s" % (response.eval_count / eval_duration) } + color(111),
|
134
|
+
eval_count: response.eval_count.to_i,
|
135
|
+
eval_rate: bold { "%.2f c/s" % (response.eval_count.to_i / eval_duration) } + color(111),
|
135
136
|
prompt_eval_duration: Tins::Duration.new(prompt_eval_duration),
|
136
|
-
prompt_eval_count: response.prompt_eval_count,
|
137
|
-
prompt_eval_rate: bold { "%.2f c/s" % (response.prompt_eval_count / prompt_eval_duration) } + color(111),
|
137
|
+
prompt_eval_count: response.prompt_eval_count.to_i,
|
138
|
+
prompt_eval_rate: bold { "%.2f c/s" % (response.prompt_eval_count.to_i / prompt_eval_duration) } + color(111),
|
138
139
|
total_duration: Tins::Duration.new(response.total_duration / 1e9),
|
139
140
|
load_duration: Tins::Duration.new(response.load_duration / 1e9),
|
140
141
|
}.map { _1 * '=' } * ' '
|
@@ -149,7 +150,7 @@ def search_web(query, n = nil)
|
|
149
150
|
n < 1 and n = 1
|
150
151
|
query = URI.encode_uri_component(query)
|
151
152
|
url = "https://www.duckduckgo.com/html/?q=#{query}"
|
152
|
-
Ollama::Utils::Fetcher.new.get(url) do |tmp|
|
153
|
+
Ollama::Utils::Fetcher.new(debug: $config.debug).get(url) do |tmp|
|
153
154
|
result = []
|
154
155
|
doc = Nokogiri::HTML(tmp)
|
155
156
|
doc.css('.results_links').each do |link|
|
@@ -302,6 +303,16 @@ def parse_source(source_io)
|
|
302
303
|
end
|
303
304
|
source_io.rewind
|
304
305
|
source_io.read
|
306
|
+
when 'text/csv'
|
307
|
+
result = +''
|
308
|
+
CSV.table(File.new(source_io), col_sep: ?,).each do |row|
|
309
|
+
next if row.fields.select(&:present?).size == 0
|
310
|
+
result << row.map { |pair|
|
311
|
+
pair.compact.map { _1.to_s.strip } * ': ' if pair.last.present?
|
312
|
+
}.select(&:present?).map { _1.prepend(' ') } * ?\n
|
313
|
+
result << "\n\n"
|
314
|
+
end
|
315
|
+
result
|
305
316
|
when %r(\Atext/)
|
306
317
|
source_io.read
|
307
318
|
when 'application/rss+xml'
|
@@ -312,11 +323,7 @@ def parse_source(source_io)
|
|
312
323
|
source_io.read
|
313
324
|
when 'application/pdf'
|
314
325
|
reader = PDF::Reader.new(source_io)
|
315
|
-
result
|
316
|
-
reader.pages.each do |page|
|
317
|
-
result << page.text
|
318
|
-
end
|
319
|
-
result
|
326
|
+
reader.pages.inject(+'') { |result, page| result << page.text }
|
320
327
|
else
|
321
328
|
STDERR.puts "Cannot import #{source_io&.content_type} document."
|
322
329
|
return
|
@@ -324,10 +331,7 @@ def parse_source(source_io)
|
|
324
331
|
end
|
325
332
|
|
326
333
|
def import_document(source_io, source)
|
327
|
-
|
328
|
-
STDOUT.puts "Embedding disabled, I won't import any documents, try: /summarize"
|
329
|
-
return
|
330
|
-
end
|
334
|
+
embedding_enabled? or return parse_source(source_io)
|
331
335
|
puts "Importing #{italic { source_io&.content_type }} document #{source.to_s.inspect}."
|
332
336
|
text = parse_source(source_io) or return
|
333
337
|
text.downcase!
|
@@ -364,7 +368,7 @@ end
|
|
364
368
|
def fetch_source(source, &block)
|
365
369
|
case source
|
366
370
|
when %r(\Ahttps?://\S+)
|
367
|
-
Utils::Fetcher.get(source) do |tmp|
|
371
|
+
Utils::Fetcher.get(source, debug: $config.debug) do |tmp|
|
368
372
|
block.(tmp)
|
369
373
|
end
|
370
374
|
when %r(\Afile://(?:(?:[.-]|[[:alnum:]])*)(/\S*)|([~.]?/\S*))
|
@@ -384,7 +388,8 @@ def summarize(source)
|
|
384
388
|
puts "Now summarizing #{source.to_s.inspect}."
|
385
389
|
source_content =
|
386
390
|
fetch_source(source) do |source_io|
|
387
|
-
content = parse_source(source_io)
|
391
|
+
content = parse_source(source_io)
|
392
|
+
content.present? or return
|
388
393
|
source_io.rewind
|
389
394
|
import_document(source_io, source)
|
390
395
|
content
|
@@ -433,7 +438,7 @@ ensure
|
|
433
438
|
end
|
434
439
|
|
435
440
|
def choose_collection(default_collection)
|
436
|
-
collections = [ default_collection ] + $documents.collections
|
441
|
+
collections = [ default_collection ] + $documents.collections.map(&:to_s)
|
437
442
|
collections = collections.uniq.sort
|
438
443
|
$documents.collection = collection =
|
439
444
|
Ollama::Utils::Chooser.choose(collections) || default_collection
|
@@ -452,7 +457,11 @@ def collection_stats
|
|
452
457
|
end
|
453
458
|
|
454
459
|
def configure_cache
|
455
|
-
|
460
|
+
if $opts[?M]
|
461
|
+
Ollama::Documents::MemoryCache
|
462
|
+
else
|
463
|
+
Object.const_get($config.cache)
|
464
|
+
end
|
456
465
|
rescue => e
|
457
466
|
STDERR.puts "Caught #{e.class}: #{e} => Falling back to MemoryCache."
|
458
467
|
Ollama::Documents::MemoryCache
|
@@ -468,6 +477,14 @@ def set_markdown(value)
|
|
468
477
|
end
|
469
478
|
end
|
470
479
|
|
480
|
+
def clear_messages(messages)
|
481
|
+
messages.delete_if { _1.role != 'system' }
|
482
|
+
end
|
483
|
+
|
484
|
+
def embedding_enabled?
|
485
|
+
$config.embedding.enabled && !$opts[?E]
|
486
|
+
end
|
487
|
+
|
471
488
|
def display_chat_help
|
472
489
|
puts <<~end
|
473
490
|
/paste to paste content
|
@@ -498,7 +515,9 @@ def usage
|
|
498
515
|
-s SYSTEM the system prompt to use as a file, OLLAMA_CHAT_SYSTEM
|
499
516
|
-c CHAT a saved chat conversation to load
|
500
517
|
-C COLLECTION name of the collection used in this conversation
|
501
|
-
-D DOCUMENT load document and add to collection (multiple)
|
518
|
+
-D DOCUMENT load document and add to embeddings collection (multiple)
|
519
|
+
-M use (empty) MemoryCache for this chat session
|
520
|
+
-E disable embeddings for this chat session
|
502
521
|
-v use voice output
|
503
522
|
-h this help
|
504
523
|
|
@@ -510,28 +529,28 @@ def ollama
|
|
510
529
|
$ollama
|
511
530
|
end
|
512
531
|
|
513
|
-
opts = go 'f:u:m:s:c:C:D:
|
532
|
+
$opts = go 'f:u:m:s:c:C:D:MEvh'
|
514
533
|
|
515
|
-
config = OllamaChatConfig.new(opts[?f])
|
534
|
+
config = OllamaChatConfig.new($opts[?f])
|
516
535
|
$config = config.config
|
517
536
|
|
518
|
-
opts[?h] and usage
|
537
|
+
$opts[?h] and usage
|
519
538
|
|
520
539
|
puts "Configuration read from #{config.filename.inspect} is:", $config
|
521
540
|
|
522
|
-
base_url = opts[?u] || $config.url
|
541
|
+
base_url = $opts[?u] || $config.url
|
523
542
|
$ollama = Client.new(base_url:, debug: $config.debug)
|
524
543
|
|
525
|
-
model = choose_model(opts[?m], $config.model.name)
|
544
|
+
model = choose_model($opts[?m], $config.model.name)
|
526
545
|
options = Options[$config.model.options]
|
527
546
|
model_system = pull_model_unless_present(model, options)
|
528
547
|
messages = []
|
529
548
|
|
530
|
-
if
|
549
|
+
if embedding_enabled?
|
531
550
|
embedding_model = $config.embedding.model.name
|
532
551
|
embedding_model_options = Options[$config.embedding.model.options]
|
533
552
|
pull_model_unless_present(embedding_model, embedding_model_options)
|
534
|
-
collection = opts[?C] || $config.embedding.collection
|
553
|
+
collection = $opts[?C] || $config.embedding.collection
|
535
554
|
$documents = Documents.new(
|
536
555
|
ollama:,
|
537
556
|
model: $config.embedding.model.name,
|
@@ -541,7 +560,7 @@ if $config.embedding.enabled
|
|
541
560
|
redis_url: $config.redis.url?,
|
542
561
|
)
|
543
562
|
|
544
|
-
document_list = opts[?D].to_a
|
563
|
+
document_list = $opts[?D].to_a
|
545
564
|
if document_list.any?(&:empty?)
|
546
565
|
puts "Clearing collection #{bold{collection}}."
|
547
566
|
$documents.clear
|
@@ -569,18 +588,21 @@ else
|
|
569
588
|
$documents = Documents.new(ollama:, model:)
|
570
589
|
end
|
571
590
|
|
572
|
-
if voice = ($config.voice if opts[?v])
|
591
|
+
if voice = ($config.voice if $opts[?v])
|
573
592
|
puts "Using voice #{bold{voice}} to speak."
|
574
593
|
end
|
575
594
|
markdown = set_markdown($config.markdown)
|
576
595
|
|
577
|
-
if opts[?c]
|
578
|
-
messages.concat load_conversation(opts[?c])
|
596
|
+
if $opts[?c]
|
597
|
+
messages.concat load_conversation($opts[?c])
|
579
598
|
else
|
580
599
|
if system = Ollama::Utils::FileArgument.
|
581
|
-
get_file_argument(opts[?s], default: $config.prompts.system? || model_system)
|
600
|
+
get_file_argument($opts[?s], default: $config.prompts.system? || model_system)
|
582
601
|
messages << Message.new(role: 'system', content: system)
|
583
|
-
puts
|
602
|
+
puts <<~end
|
603
|
+
Configured system prompt is:
|
604
|
+
#{italic{Ollama::Utils::Width.wrap(system, percentage: 90)}}
|
605
|
+
end
|
584
606
|
end
|
585
607
|
end
|
586
608
|
|
@@ -606,11 +628,11 @@ loop do
|
|
606
628
|
list_conversation(messages, markdown)
|
607
629
|
next
|
608
630
|
when %r(^/clear$)
|
609
|
-
messages
|
631
|
+
clear_messages(messages)
|
610
632
|
puts "Cleared messages."
|
611
633
|
next
|
612
634
|
when %r(^/clobber$)
|
613
|
-
messages
|
635
|
+
clear_messages(messages)
|
614
636
|
$documents.clear
|
615
637
|
puts "Cleared messages and collection."
|
616
638
|
next
|
@@ -697,7 +719,7 @@ loop do
|
|
697
719
|
[ content, Utils::Tags.new ]
|
698
720
|
end
|
699
721
|
|
700
|
-
if
|
722
|
+
if embedding_enabled? && content
|
701
723
|
records = $documents.find_where(
|
702
724
|
content.downcase,
|
703
725
|
tags:,
|
@@ -705,10 +727,9 @@ loop do
|
|
705
727
|
text_size: $config.embedding.found_texts_size?,
|
706
728
|
text_count: $config.embedding.found_texts_count?,
|
707
729
|
)
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
"#{found_texts.join("\n\n---\n\n")}"
|
730
|
+
unless records.empty?
|
731
|
+
content += "\nConsider these chunks for your answer:\n\n"\
|
732
|
+
"#{records.map { [ _1.text, _1.tags_set ] * ?\n }.join("\n\n---\n\n")}"
|
712
733
|
end
|
713
734
|
end
|
714
735
|
|
@@ -716,8 +737,8 @@ loop do
|
|
716
737
|
handler = FollowChat.new(messages:, markdown:, voice:)
|
717
738
|
ollama.chat(model:, messages:, options:, stream: true, &handler)
|
718
739
|
|
719
|
-
if records
|
720
|
-
puts records.map { |record|
|
740
|
+
if embedding_enabled? && !records.empty?
|
741
|
+
puts "", records.map { |record|
|
721
742
|
link = if record.source =~ %r(\Ahttps?://)
|
722
743
|
record.source
|
723
744
|
else
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ollama::Documents::Cache::Common
|
2
|
+
attr_writer :prefix
|
3
|
+
|
4
|
+
def collections(prefix)
|
5
|
+
unique = Set.new
|
6
|
+
full_each { |key, _| unique << key[/\A#{prefix}(.*)-/, 1] }
|
7
|
+
unique.map(&:to_sym)
|
8
|
+
end
|
9
|
+
|
10
|
+
def pre(key)
|
11
|
+
[ @prefix, key ].join
|
12
|
+
end
|
13
|
+
|
14
|
+
def unpre(key)
|
15
|
+
key.sub(/\A#@prefix/, '')
|
16
|
+
end
|
17
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
require 'ollama/documents/cache/common'
|
2
|
+
|
1
3
|
class Ollama::Documents::MemoryCache
|
4
|
+
include Ollama::Documents::Cache::Common
|
5
|
+
|
2
6
|
def initialize(prefix:)
|
3
7
|
@prefix = prefix
|
4
8
|
@data = {}
|
5
9
|
end
|
6
10
|
|
7
|
-
attr_writer :prefix
|
8
|
-
|
9
11
|
def [](key)
|
10
12
|
@data[pre(key)]
|
11
13
|
end
|
@@ -23,11 +25,11 @@ class Ollama::Documents::MemoryCache
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def size
|
26
|
-
|
28
|
+
count
|
27
29
|
end
|
28
30
|
|
29
31
|
def clear
|
30
|
-
@data.
|
32
|
+
@data.delete_if { |key, _| key.start_with?(@prefix) }
|
31
33
|
self
|
32
34
|
end
|
33
35
|
|
@@ -36,11 +38,7 @@ class Ollama::Documents::MemoryCache
|
|
36
38
|
end
|
37
39
|
include Enumerable
|
38
40
|
|
39
|
-
def
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def unpre(key)
|
44
|
-
key.sub(/\A#@prefix/, '')
|
41
|
+
def full_each(&block)
|
42
|
+
@data.each(&block)
|
45
43
|
end
|
46
44
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'redis'
|
2
|
+
|
3
|
+
class Ollama::Documents
|
4
|
+
class RedisBackedMemoryCache < MemoryCache
|
5
|
+
def initialize(prefix:, url: ENV['REDIS_URL'])
|
6
|
+
super(prefix:)
|
7
|
+
url or raise ArgumentError, 'require redis url'
|
8
|
+
@prefix, @url = prefix, url
|
9
|
+
@redis_cache = Ollama::Documents::RedisCache.new(prefix:, url:)
|
10
|
+
@redis_cache.full_each do |key, value|
|
11
|
+
@data[key] = value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def redis
|
16
|
+
@redis_cache.redis
|
17
|
+
end
|
18
|
+
|
19
|
+
def []=(key, value)
|
20
|
+
super
|
21
|
+
redis.set(pre(key), JSON(value))
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(key)
|
25
|
+
result = redis.del(pre(key))
|
26
|
+
super
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear
|
31
|
+
redis.scan_each(match: "#@prefix*") { |key| redis.del(key) }
|
32
|
+
super
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def pre(key)
|
37
|
+
[ @prefix, key ].join
|
38
|
+
end
|
39
|
+
|
40
|
+
def unpre(key)
|
41
|
+
key.sub(/\A#@prefix/, '')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
require 'ollama/documents/cache/common'
|
1
2
|
require 'redis'
|
2
3
|
|
3
4
|
class Ollama::Documents::RedisCache
|
5
|
+
include Ollama::Documents::Cache::Common
|
6
|
+
|
4
7
|
def initialize(prefix:, url: ENV['REDIS_URL'])
|
5
8
|
url or raise ArgumentError, 'require redis url'
|
6
9
|
@prefix, @url = prefix, url
|
7
10
|
end
|
8
11
|
|
9
|
-
attr_writer :prefix
|
10
|
-
|
11
12
|
def redis
|
12
13
|
@redis ||= Redis.new(url: @url)
|
13
14
|
end
|
@@ -48,11 +49,11 @@ class Ollama::Documents::RedisCache
|
|
48
49
|
end
|
49
50
|
include Enumerable
|
50
51
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
def full_each(&block)
|
53
|
+
redis.scan_each do |key|
|
54
|
+
value = redis.get(key) or next
|
55
|
+
value = JSON(value, object_class: Ollama::Documents::Record)
|
56
|
+
block.(key, value)
|
57
|
+
end
|
57
58
|
end
|
58
59
|
end
|
data/lib/ollama/documents.rb
CHANGED
@@ -3,8 +3,11 @@ require 'digest'
|
|
3
3
|
|
4
4
|
class Ollama::Documents
|
5
5
|
end
|
6
|
-
|
7
|
-
|
6
|
+
class Ollama::Documents::Cache
|
7
|
+
end
|
8
|
+
require 'ollama/documents/cache/memory_cache'
|
9
|
+
require 'ollama/documents/cache/redis_cache'
|
10
|
+
require 'ollama/documents/cache/redis_backed_memory_cache'
|
8
11
|
module Ollama::Documents::Splitters
|
9
12
|
end
|
10
13
|
require 'ollama/documents/splitters/character'
|
@@ -16,11 +19,15 @@ class Ollama::Documents
|
|
16
19
|
|
17
20
|
class Record < JSON::GenericObject
|
18
21
|
def to_s
|
19
|
-
my_tags =
|
22
|
+
my_tags = tags_set
|
20
23
|
my_tags.empty? or my_tags = " #{my_tags}"
|
21
24
|
"#<#{self.class} #{text.inspect}#{my_tags} #{similarity || 'n/a'}>"
|
22
25
|
end
|
23
26
|
|
27
|
+
def tags_set
|
28
|
+
Ollama::Utils::Tags.new(tags)
|
29
|
+
end
|
30
|
+
|
24
31
|
def ==(other)
|
25
32
|
text == other.text
|
26
33
|
end
|
@@ -28,15 +35,19 @@ class Ollama::Documents
|
|
28
35
|
alias inspect to_s
|
29
36
|
end
|
30
37
|
|
31
|
-
def initialize(ollama:, model:, model_options: nil, collection:
|
32
|
-
@ollama, @model, @model_options, @collection = ollama, model, model_options, collection
|
38
|
+
def initialize(ollama:, model:, model_options: nil, collection: default_collection, cache: MemoryCache, redis_url: nil)
|
39
|
+
@ollama, @model, @model_options, @collection = ollama, model, model_options, collection.to_sym
|
33
40
|
@cache, @redis_url = connect_cache(cache), redis_url
|
34
41
|
end
|
35
42
|
|
43
|
+
def default_collection
|
44
|
+
:default
|
45
|
+
end
|
46
|
+
|
36
47
|
attr_reader :ollama, :model, :collection
|
37
48
|
|
38
49
|
def collection=(new_collection)
|
39
|
-
@collection
|
50
|
+
@collection = new_collection.to_sym
|
40
51
|
@cache.prefix = prefix
|
41
52
|
end
|
42
53
|
|
@@ -137,15 +148,7 @@ class Ollama::Documents
|
|
137
148
|
end
|
138
149
|
|
139
150
|
def collections
|
140
|
-
|
141
|
-
when MemoryCache
|
142
|
-
[ @collection ]
|
143
|
-
when RedisCache
|
144
|
-
prefix = '%s-' % self.class
|
145
|
-
Documents::RedisCache.new(prefix:, url: @redis_url).map { _1[/#{prefix}(.*)-/, 1] }.uniq
|
146
|
-
else
|
147
|
-
[]
|
148
|
-
end
|
151
|
+
([ default_collection ] + @cache.collections('%s-' % self.class)).uniq
|
149
152
|
end
|
150
153
|
|
151
154
|
def tags
|
@@ -156,7 +159,7 @@ class Ollama::Documents
|
|
156
159
|
|
157
160
|
def connect_cache(cache_class)
|
158
161
|
cache = nil
|
159
|
-
if cache_class
|
162
|
+
if cache_class.instance_method(:redis)
|
160
163
|
begin
|
161
164
|
cache = cache_class.new(prefix:)
|
162
165
|
cache.size
|
@@ -3,11 +3,20 @@ class Ollama::Utils::ColorizeTexts
|
|
3
3
|
include Term::ANSIColor
|
4
4
|
include Ollama::Utils::Width
|
5
5
|
|
6
|
+
# Initializes a new instance of Ollama::Utils::ColorizeTexts
|
7
|
+
#
|
8
|
+
# @param [Array<String>] texts the array of strings to be displayed with colors
|
9
|
+
#
|
10
|
+
# @return [Ollama::Utils::ColorizeTexts] an instance of Ollama::Utils::ColorizeTexts
|
6
11
|
def initialize(*texts)
|
7
|
-
texts
|
12
|
+
texts = texts.map(&:to_a)
|
8
13
|
@texts = Array(texts.flatten)
|
9
14
|
end
|
10
15
|
|
16
|
+
# Returns a string representation of the object, including all texts content,
|
17
|
+
# colored differently and their sizes.
|
18
|
+
#
|
19
|
+
# @return [String] The formatted string.
|
11
20
|
def to_s
|
12
21
|
result = +''
|
13
22
|
@texts.each_with_index do |t, i|
|
@@ -22,6 +31,14 @@ class Ollama::Utils::ColorizeTexts
|
|
22
31
|
|
23
32
|
private
|
24
33
|
|
34
|
+
# Returns the nearest RGB color to the given ANSI color
|
35
|
+
#
|
36
|
+
# @param [color] color The ANSI color attribute
|
37
|
+
#
|
38
|
+
# @return [Array<RGBTriple>] An array containing two RGB colors, one for black and
|
39
|
+
# one for white text, where the first is the closest match to the input color
|
40
|
+
# when printed on a black background, and the second is the closest match
|
41
|
+
# when printed on a white background.
|
25
42
|
def text_color(color)
|
26
43
|
color = Term::ANSIColor::Attribute[color]
|
27
44
|
[
|
@@ -30,6 +47,9 @@ class Ollama::Utils::ColorizeTexts
|
|
30
47
|
].max_by { |t| t.distance_to(color) }
|
31
48
|
end
|
32
49
|
|
50
|
+
# Returns an array of colors for each step in the gradient
|
51
|
+
#
|
52
|
+
# @return [Array<Array<Integer>>] An array of RGB color arrays
|
33
53
|
def colors
|
34
54
|
@colors ||= (0..255).map { |i|
|
35
55
|
[
|
data/lib/ollama/utils/fetcher.rb
CHANGED
@@ -2,6 +2,7 @@ require 'tempfile'
|
|
2
2
|
require 'tins/unit'
|
3
3
|
require 'infobar'
|
4
4
|
require 'mime-types'
|
5
|
+
require 'stringio'
|
5
6
|
|
6
7
|
class Ollama::Utils::Fetcher
|
7
8
|
module ContentType
|
@@ -10,13 +11,14 @@ class Ollama::Utils::Fetcher
|
|
10
11
|
|
11
12
|
class RetryWithoutStreaming < StandardError; end
|
12
13
|
|
13
|
-
def initialize
|
14
|
+
def initialize(debug: false)
|
15
|
+
@debug = debug
|
14
16
|
@started = false
|
15
17
|
@streaming = true
|
16
18
|
end
|
17
19
|
|
18
|
-
def self.get(url, &block)
|
19
|
-
new.get(url, &block)
|
20
|
+
def self.get(url, **options, &block)
|
21
|
+
new(**options).get(url, &block)
|
20
22
|
end
|
21
23
|
|
22
24
|
def get(url, &block)
|
@@ -46,11 +48,11 @@ class Ollama::Utils::Fetcher
|
|
46
48
|
@streaming = false
|
47
49
|
retry
|
48
50
|
rescue => e
|
49
|
-
STDERR.puts "Cannot get #{url.to_s.inspect} (#{e}): #{response&.status_line}"
|
50
|
-
|
51
|
+
STDERR.puts "Cannot get #{url.to_s.inspect} (#{e}): #{response&.status_line || 'n/a'}"
|
52
|
+
if @debug && !e.is_a?(RuntimeError)
|
51
53
|
STDERR.puts "#{e.backtrace * ?\n}"
|
52
54
|
end
|
53
|
-
yield
|
55
|
+
yield StringIO.new.extend(ContentType)
|
54
56
|
end
|
55
57
|
|
56
58
|
def headers
|
@@ -1,6 +1,24 @@
|
|
1
1
|
module Ollama::Utils::FileArgument
|
2
2
|
module_function
|
3
3
|
|
4
|
+
# Returns the contents of a file or string, or a default value if neither is provided.
|
5
|
+
#
|
6
|
+
# @param [String] path_or_content The path to a file or a string containing
|
7
|
+
# the content.
|
8
|
+
#
|
9
|
+
# @param [String] default The default value to return if no valid input is
|
10
|
+
# given. Defaults to nil.
|
11
|
+
#
|
12
|
+
# @return [String] The contents of the file, the string, or the default value.
|
13
|
+
#
|
14
|
+
# @example Get the contents of a file
|
15
|
+
# get_file_argument('path/to/file')
|
16
|
+
#
|
17
|
+
# @example Use a string as content
|
18
|
+
# get_file_argument('string content')
|
19
|
+
#
|
20
|
+
# @example Return a default value if no valid input is given
|
21
|
+
# get_file_argument(nil, default: 'default content')
|
4
22
|
def get_file_argument(path_or_content, default: nil)
|
5
23
|
if path_or_content.present? && path_or_content.size < 2 ** 15 &&
|
6
24
|
File.basename(path_or_content).size < 2 ** 8 &&
|
data/lib/ollama/utils/tags.rb
CHANGED
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.4.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.4.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-21"
|
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/memory_cache.rb".freeze, "lib/ollama/documents/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/memory_cache.rb".freeze, "lib/ollama/documents/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_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/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]
|
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_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/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
|
|
@@ -28,6 +28,8 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_development_dependency(%q<all_images>.freeze, ["~> 0.4".freeze])
|
29
29
|
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
|
30
30
|
s.add_development_dependency(%q<webmock>.freeze, [">= 0".freeze])
|
31
|
+
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
32
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
|
31
33
|
s.add_runtime_dependency(%q<excon>.freeze, ["~> 0.111".freeze])
|
32
34
|
s.add_runtime_dependency(%q<infobar>.freeze, ["~> 0.8".freeze])
|
33
35
|
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
|
@@ -1,63 +1,63 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Ollama::Documents::MemoryCache do
|
4
|
-
let :
|
4
|
+
let :cache do
|
5
5
|
described_class.new prefix: 'test-'
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'can be instantiated' do
|
9
|
-
expect(
|
9
|
+
expect(cache).to be_a described_class
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'can get/set a key' do
|
13
13
|
key, value = 'foo', { test: true }
|
14
14
|
expect {
|
15
|
-
|
15
|
+
cache[key] = value
|
16
16
|
}.to change {
|
17
|
-
|
17
|
+
cache[key]
|
18
18
|
}.from(nil).to(value)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'can determine if key exists' do
|
22
22
|
key, value = 'foo', { test: true }
|
23
23
|
expect {
|
24
|
-
|
24
|
+
cache[key] = value
|
25
25
|
}.to change {
|
26
|
-
|
26
|
+
cache.key?(key)
|
27
27
|
}.from(false).to(true)
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'can delete' do
|
31
31
|
key, value = 'foo', { test: true }
|
32
|
-
|
32
|
+
cache[key] = value
|
33
33
|
expect {
|
34
|
-
|
34
|
+
cache.delete(key)
|
35
35
|
}.to change {
|
36
|
-
|
36
|
+
cache.key?(key)
|
37
37
|
}.from(true).to(false)
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'returns size' do
|
41
41
|
key, value = 'foo', { test: true }
|
42
42
|
expect {
|
43
|
-
|
43
|
+
cache[key] = value
|
44
44
|
}.to change {
|
45
|
-
|
45
|
+
cache.size
|
46
46
|
}.from(0).to(1)
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'can clear' do
|
50
50
|
key, value = 'foo', { test: true }
|
51
|
-
|
51
|
+
cache[key] = value
|
52
52
|
expect {
|
53
|
-
expect(
|
53
|
+
expect(cache.clear).to eq cache
|
54
54
|
}.to change {
|
55
|
-
|
55
|
+
cache.size
|
56
56
|
}.from(1).to(0)
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'can iterate over keys under a prefix' do
|
60
|
-
|
61
|
-
expect(
|
60
|
+
cache['foo'] = 'bar'
|
61
|
+
expect(cache.to_a).to eq [ %w[ test-foo bar ] ]
|
62
62
|
end
|
63
63
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Ollama::Documents::RedisBackedMemoryCache do
|
4
|
+
it 'raises ArgumentError if url is missing' do
|
5
|
+
expect {
|
6
|
+
described_class.new prefix: 'test-', url: nil
|
7
|
+
}.to raise_error ArgumentError
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'test redis interactions' do
|
11
|
+
let :cache do
|
12
|
+
described_class.new prefix: 'test-', url: 'something'
|
13
|
+
end
|
14
|
+
|
15
|
+
let :data do
|
16
|
+
cache.instance_eval { @data }
|
17
|
+
end
|
18
|
+
|
19
|
+
let :redis_cache do
|
20
|
+
cache.instance_eval { @redis_cache }
|
21
|
+
end
|
22
|
+
|
23
|
+
let :redis do
|
24
|
+
double('Redis')
|
25
|
+
end
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow_any_instance_of(Ollama::Documents::RedisCache).to\
|
29
|
+
receive(:redis).and_return(redis)
|
30
|
+
allow(redis).to receive(:scan_each)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'can be instantiated and initialized' do
|
34
|
+
cache = described_class.new prefix: 'test-', url: 'something'
|
35
|
+
expect(cache).to be_a described_class
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has Redis client' do
|
39
|
+
expect(cache.redis).to eq redis
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can get a key' do
|
43
|
+
key = 'foo'
|
44
|
+
expect(data).to receive(:[]).with('test-' + key).and_return 666
|
45
|
+
expect(cache[key]).to eq 666
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'can set a value for a key' do
|
49
|
+
key, value = 'foo', { test: true }
|
50
|
+
expect(data).to receive(:[]=).with('test-' + key, { test: true }).and_call_original
|
51
|
+
expect(redis).to receive(:set).with('test-' + key, JSON(value))
|
52
|
+
cache[key] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can determine if key exists' do
|
56
|
+
key = 'foo'
|
57
|
+
expect(data).to receive(:key?).with('test-' + key).and_return(false, true)
|
58
|
+
expect(cache.key?('foo')).to eq false
|
59
|
+
expect(cache.key?('foo')).to eq true
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'can delete' do
|
63
|
+
key = 'foo'
|
64
|
+
expect(data).to receive(:delete).with('test-' + key)
|
65
|
+
expect(redis).to receive(:del).with('test-' + key)
|
66
|
+
cache.delete(key)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns size' do
|
70
|
+
allow(cache).to receive(:count).and_return 3
|
71
|
+
expect(cache.size).to eq 3
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'can clear' do
|
75
|
+
expect(redis).to receive(:scan_each).with(match: 'test-*').and_yield(
|
76
|
+
'test-foo'
|
77
|
+
)
|
78
|
+
expect(redis).to receive(:del).with('test-foo')
|
79
|
+
expect(cache.clear).to eq cache
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'can iterate over keys under a prefix' do
|
83
|
+
data['test-foo'] = 'bar'
|
84
|
+
expect(cache.to_a).to eq [ %w[ test-foo bar ] ]
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'can compute prefix with pre' do
|
88
|
+
expect(cache.pre('foo')).to eq 'test-foo'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'can remove prefix with unpre' do
|
92
|
+
expect(cache.unpre('test-foo')).to eq 'foo'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Ollama::Documents::RedisCache do
|
4
4
|
it 'can be instantiated' do
|
5
|
-
|
6
|
-
expect(
|
5
|
+
cache = described_class.new prefix: 'test-', url: 'something'
|
6
|
+
expect(cache).to be_a described_class
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'raises ArgumentError if url is missing' do
|
@@ -13,7 +13,7 @@ RSpec.describe Ollama::Documents::RedisCache do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
context 'test redis interactions' do
|
16
|
-
let :
|
16
|
+
let :cache do
|
17
17
|
described_class.new prefix: 'test-', url: 'something'
|
18
18
|
end
|
19
19
|
|
@@ -26,32 +26,32 @@ RSpec.describe Ollama::Documents::RedisCache do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'has Redis client' do
|
29
|
-
expect(
|
29
|
+
expect(cache.redis).to eq redis
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'can get a key' do
|
33
33
|
key = 'foo'
|
34
|
-
expect(redis).to receive(:get).with('test-' + key).and_return
|
35
|
-
|
34
|
+
expect(redis).to receive(:get).with('test-' + key).and_return '"some_json"'
|
35
|
+
expect(cache[key]).to eq 'some_json'
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'can set a value for a key' do
|
39
39
|
key, value = 'foo', { test: true }
|
40
40
|
expect(redis).to receive(:set).with('test-' + key, JSON(value))
|
41
|
-
|
41
|
+
cache[key] = value
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'can determine if key exists' do
|
45
45
|
key = 'foo'
|
46
46
|
expect(redis).to receive(:exists?).with('test-' + key).and_return(false, true)
|
47
|
-
expect(
|
48
|
-
expect(
|
47
|
+
expect(cache.key?('foo')).to eq false
|
48
|
+
expect(cache.key?('foo')).to eq true
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'can delete' do
|
52
52
|
key = 'foo'
|
53
53
|
expect(redis).to receive(:del).with('test-' + key)
|
54
|
-
|
54
|
+
cache.delete(key)
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'returns size' do
|
@@ -59,7 +59,7 @@ RSpec.describe Ollama::Documents::RedisCache do
|
|
59
59
|
and_yield('test-foo').
|
60
60
|
and_yield('test-bar').
|
61
61
|
and_yield('test-baz')
|
62
|
-
expect(
|
62
|
+
expect(cache.size).to eq 3
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'can clear' do
|
@@ -67,20 +67,20 @@ RSpec.describe Ollama::Documents::RedisCache do
|
|
67
67
|
'test-foo'
|
68
68
|
)
|
69
69
|
expect(redis).to receive(:del).with('test-foo')
|
70
|
-
expect(
|
70
|
+
expect(cache.clear).to eq cache
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'can iterate over keys under a prefix' do
|
74
74
|
expect(redis).to receive(:scan_each).with(match: 'test-*')
|
75
|
-
|
75
|
+
cache.to_a
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'can compute prefix with pre' do
|
79
|
-
expect(
|
79
|
+
expect(cache.pre('foo')).to eq 'test-foo'
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'can remove prefix with unpre' do
|
83
|
-
expect(
|
83
|
+
expect(cache.unpre('test-foo')).to eq 'foo'
|
84
84
|
end
|
85
85
|
end
|
86
86
|
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.
|
4
|
+
version: 0.4.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-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: debug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: excon
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -303,8 +331,10 @@ extra_rdoc_files:
|
|
303
331
|
- lib/ollama/commands/show.rb
|
304
332
|
- lib/ollama/commands/tags.rb
|
305
333
|
- lib/ollama/documents.rb
|
306
|
-
- lib/ollama/documents/
|
307
|
-
- lib/ollama/documents/
|
334
|
+
- lib/ollama/documents/cache/common.rb
|
335
|
+
- lib/ollama/documents/cache/memory_cache.rb
|
336
|
+
- lib/ollama/documents/cache/redis_backed_memory_cache.rb
|
337
|
+
- lib/ollama/documents/cache/redis_cache.rb
|
308
338
|
- lib/ollama/documents/splitters/character.rb
|
309
339
|
- lib/ollama/documents/splitters/semantic.rb
|
310
340
|
- lib/ollama/dto.rb
|
@@ -367,8 +397,10 @@ files:
|
|
367
397
|
- lib/ollama/commands/show.rb
|
368
398
|
- lib/ollama/commands/tags.rb
|
369
399
|
- lib/ollama/documents.rb
|
370
|
-
- lib/ollama/documents/
|
371
|
-
- lib/ollama/documents/
|
400
|
+
- lib/ollama/documents/cache/common.rb
|
401
|
+
- lib/ollama/documents/cache/memory_cache.rb
|
402
|
+
- lib/ollama/documents/cache/redis_backed_memory_cache.rb
|
403
|
+
- lib/ollama/documents/cache/redis_cache.rb
|
372
404
|
- lib/ollama/documents/splitters/character.rb
|
373
405
|
- lib/ollama/documents/splitters/semantic.rb
|
374
406
|
- lib/ollama/dto.rb
|
@@ -420,6 +452,7 @@ files:
|
|
420
452
|
- spec/ollama/commands/show_spec.rb
|
421
453
|
- spec/ollama/commands/tags_spec.rb
|
422
454
|
- spec/ollama/documents/memory_cache_spec.rb
|
455
|
+
- spec/ollama/documents/redis_backed_memory_cache_spec.rb
|
423
456
|
- spec/ollama/documents/redis_cache_spec.rb
|
424
457
|
- spec/ollama/documents/splitters/character_spec.rb
|
425
458
|
- spec/ollama/documents/splitters/semantic_spec.rb
|
@@ -486,6 +519,7 @@ test_files:
|
|
486
519
|
- spec/ollama/commands/show_spec.rb
|
487
520
|
- spec/ollama/commands/tags_spec.rb
|
488
521
|
- spec/ollama/documents/memory_cache_spec.rb
|
522
|
+
- spec/ollama/documents/redis_backed_memory_cache_spec.rb
|
489
523
|
- spec/ollama/documents/redis_cache_spec.rb
|
490
524
|
- spec/ollama/documents/splitters/character_spec.rb
|
491
525
|
- spec/ollama/documents/splitters/semantic_spec.rb
|