ollama-ruby 0.11.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +44 -1
- data/README.md +3 -2
- data/Rakefile +3 -1
- data/bin/ollama_chat +79 -29
- data/lib/ollama/client.rb +5 -5
- data/lib/ollama/documents/cache/common.rb +5 -1
- data/lib/ollama/documents/cache/memory_cache.rb +1 -1
- data/lib/ollama/documents/cache/records.rb +87 -0
- data/lib/ollama/documents/cache/redis_backed_memory_cache.rb +2 -1
- data/lib/ollama/documents/cache/redis_cache.rb +3 -10
- data/lib/ollama/documents/cache/sqlite_cache.rb +215 -0
- data/lib/ollama/documents/splitters/semantic.rb +1 -0
- data/lib/ollama/documents.rb +35 -62
- data/lib/ollama/utils/chooser.rb +15 -1
- data/lib/ollama/utils/tags.rb +2 -1
- data/lib/ollama/version.rb +1 -1
- data/ollama-ruby.gemspec +9 -7
- data/spec/ollama/documents/{memory_cache_spec.rb → cache/memory_cache_spec.rb} +37 -3
- data/spec/ollama/documents/{redis_backed_memory_cache_spec.rb → cache/redis_backed_memory_cache_spec.rb} +19 -7
- data/spec/ollama/documents/{redis_cache_spec.rb → cache/redis_cache_spec.rb} +34 -19
- data/spec/ollama/documents/cache/sqlite_cache_spec.rb +141 -0
- data/spec/ollama/utils/tags_spec.rb +7 -2
- metadata +50 -10
@@ -1,33 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Ollama::Documents::RedisCache do
|
4
|
+
let :prefix do
|
5
|
+
'test-'
|
6
|
+
end
|
7
|
+
|
8
|
+
let :cache do
|
9
|
+
described_class.new prefix:, url: 'something'
|
10
|
+
end
|
11
|
+
|
4
12
|
it 'can be instantiated' do
|
5
|
-
cache = described_class.new prefix: 'test-', url: 'something'
|
6
13
|
expect(cache).to be_a described_class
|
7
14
|
end
|
8
15
|
|
9
16
|
it 'defaults to nil object_class' do
|
10
|
-
cache = described_class.new prefix: 'test-', url: 'something'
|
11
17
|
expect(cache.object_class).to be_nil
|
12
18
|
end
|
13
19
|
|
14
20
|
it 'can be configured with object_class' do
|
15
21
|
object_class = Class.new(JSON::GenericObject)
|
16
|
-
cache = described_class.new(prefix
|
22
|
+
cache = described_class.new(prefix:, url: 'something', object_class:)
|
17
23
|
expect(cache.object_class).to eq object_class
|
18
24
|
end
|
19
25
|
|
20
26
|
it 'raises ArgumentError if url is missing' do
|
21
27
|
expect {
|
22
|
-
described_class.new prefix
|
28
|
+
described_class.new prefix:, url: nil
|
23
29
|
}.to raise_error ArgumentError
|
24
30
|
end
|
25
31
|
|
26
32
|
context 'test redis interactions' do
|
27
|
-
let :cache do
|
28
|
-
described_class.new prefix: 'test-', url: 'something'
|
29
|
-
end
|
30
|
-
|
31
33
|
let :redis do
|
32
34
|
double('Redis')
|
33
35
|
end
|
@@ -42,43 +44,56 @@ RSpec.describe Ollama::Documents::RedisCache do
|
|
42
44
|
|
43
45
|
it 'can get a key' do
|
44
46
|
key = 'foo'
|
45
|
-
expect(redis).to receive(:get).with(
|
47
|
+
expect(redis).to receive(:get).with(prefix + key).and_return '"some_json"'
|
46
48
|
expect(cache[key]).to eq 'some_json'
|
47
49
|
end
|
48
50
|
|
49
51
|
it 'can set a value for a key' do
|
50
52
|
key, value = 'foo', { test: true }
|
51
|
-
expect(redis).to receive(:set).with(
|
53
|
+
expect(redis).to receive(:set).with(prefix + key, JSON(value), ex: nil)
|
52
54
|
cache[key] = value
|
53
55
|
end
|
54
56
|
|
55
57
|
it 'can set a value for a key with ttl' do
|
56
|
-
cache = described_class.new prefix
|
58
|
+
cache = described_class.new prefix:, url: 'something', ex: 3_600
|
57
59
|
key, value = 'foo', { test: true }
|
58
|
-
expect(redis).to receive(:set).with(
|
60
|
+
expect(redis).to receive(:set).with(prefix + key, JSON(value), ex: 3_600)
|
59
61
|
cache[key] = value
|
60
|
-
expect(redis).to receive(:ttl).with(
|
62
|
+
expect(redis).to receive(:ttl).with(prefix + key).and_return 3_600
|
61
63
|
expect(cache.ttl(key)).to eq 3_600
|
62
64
|
end
|
63
65
|
|
64
66
|
it 'can determine if key exists' do
|
65
67
|
key = 'foo'
|
66
|
-
expect(redis).to receive(:exists?).with(
|
68
|
+
expect(redis).to receive(:exists?).with(prefix + key).and_return(false, true)
|
67
69
|
expect(cache.key?('foo')).to eq false
|
68
70
|
expect(cache.key?('foo')).to eq true
|
69
71
|
end
|
70
72
|
|
71
73
|
it 'can delete' do
|
72
74
|
key = 'foo'
|
73
|
-
expect(redis).to receive(:del).with(
|
75
|
+
expect(redis).to receive(:del).with(prefix + key)
|
74
76
|
cache.delete(key)
|
75
77
|
end
|
76
78
|
|
79
|
+
it 'can iterate over keys, values' do
|
80
|
+
key, value = 'foo', { 'test' => true }
|
81
|
+
expect(redis).to receive(:set).with(prefix + key, JSON(value), ex: nil)
|
82
|
+
cache[key] = value
|
83
|
+
expect(redis).to receive(:scan_each).with(match: "#{prefix}*").
|
84
|
+
and_yield("#{prefix}foo")
|
85
|
+
expect(redis).to receive(:get).with(prefix + key).and_return(JSON(test: true))
|
86
|
+
cache.each do |k, v|
|
87
|
+
expect(k).to eq prefix + key
|
88
|
+
expect(v).to eq value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
77
92
|
it 'returns size' do
|
78
|
-
|
79
|
-
and_yield(
|
80
|
-
and_yield(
|
81
|
-
and_yield(
|
93
|
+
expect(redis).to receive(:scan_each).with(match: "#{prefix}*").
|
94
|
+
and_yield("#{prefix}foo").
|
95
|
+
and_yield("#{prefix}bar").
|
96
|
+
and_yield("#{prefix}baz")
|
82
97
|
expect(cache.size).to eq 3
|
83
98
|
end
|
84
99
|
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Ollama::Documents::SQLiteCache do
|
4
|
+
let :prefix do
|
5
|
+
'test-'
|
6
|
+
end
|
7
|
+
|
8
|
+
let :test_value do
|
9
|
+
{
|
10
|
+
key: 'test',
|
11
|
+
text: 'test text',
|
12
|
+
norm: 0.5,
|
13
|
+
source: 'for-test.txt',
|
14
|
+
tags: %w[ test ],
|
15
|
+
embedding: [ 0.5 ] * 1_024,
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
let :cache do
|
20
|
+
described_class.new prefix:
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can be instantiated' do
|
24
|
+
expect(cache).to be_a described_class
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'defaults to :memory: mode' do
|
28
|
+
expect(cache.filename).to eq ':memory:'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can be switchted to file mode' do
|
32
|
+
expect(SQLite3::Database).to receive(:new).with('foo.sqlite').
|
33
|
+
and_return(double.as_null_object)
|
34
|
+
cache = described_class.new prefix:, filename: 'foo.sqlite'
|
35
|
+
expect(cache.filename).to eq 'foo.sqlite'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can get/set a key' do
|
39
|
+
key, value = 'foo', test_value
|
40
|
+
queried_value = nil
|
41
|
+
expect {
|
42
|
+
cache[key] = value
|
43
|
+
}.to change {
|
44
|
+
queried_value = cache[key]
|
45
|
+
}.from(nil).to(Ollama::Documents::Record[value])
|
46
|
+
expect(queried_value.embedding).to eq [ 0.5 ] * 1_024
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can determine if key exists' do
|
50
|
+
key, value = 'foo', test_value
|
51
|
+
expect {
|
52
|
+
cache[key] = value
|
53
|
+
}.to change {
|
54
|
+
cache.key?(key)
|
55
|
+
}.from(false).to(true)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'can set key with different prefixes' do
|
59
|
+
key, value = 'foo', test_value
|
60
|
+
expect {
|
61
|
+
cache[key] = value
|
62
|
+
}.to change {
|
63
|
+
cache.size
|
64
|
+
}.from(0).to(1)
|
65
|
+
cache2 = cache.dup
|
66
|
+
cache2.prefix = 'test2-'
|
67
|
+
expect {
|
68
|
+
cache2[key] = value
|
69
|
+
}.to change {
|
70
|
+
cache2.size
|
71
|
+
}.from(0).to(1)
|
72
|
+
expect(cache.size).to eq 1
|
73
|
+
s = 0
|
74
|
+
cache.full_each { s += 1 }
|
75
|
+
expect(s).to eq 2
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'can delete' do
|
79
|
+
key, value = 'foo', test_value
|
80
|
+
expect(cache.delete(key)).to be_falsy
|
81
|
+
cache[key] = value
|
82
|
+
expect {
|
83
|
+
expect(cache.delete(key)).to be_truthy
|
84
|
+
}.to change {
|
85
|
+
cache.key?(key)
|
86
|
+
}.from(true).to(false)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns size' do
|
90
|
+
key, value = 'foo', test_value
|
91
|
+
expect {
|
92
|
+
cache[key] = value
|
93
|
+
}.to change {
|
94
|
+
cache.size
|
95
|
+
}.from(0).to(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'can convert_to_vector' do
|
99
|
+
vector = [ 23.0, 666.0 ]
|
100
|
+
expect(cache.convert_to_vector(vector)).to eq vector
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'can clear' do
|
104
|
+
key, value = 'foo', { embedding: [ 0.5 ] * 1_024 }
|
105
|
+
cache[key] = value
|
106
|
+
expect {
|
107
|
+
expect(cache.clear).to eq cache
|
108
|
+
}.to change {
|
109
|
+
cache.size
|
110
|
+
}.from(1).to(0)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'can clear for tags' do
|
114
|
+
key, value = 'foo', { tags: %w[ foo ], embedding: [ 0.5 ] * 1_024 }
|
115
|
+
cache[key] = value
|
116
|
+
key, value = 'bar', { embedding: [ 0.5 ] * 1_024 }
|
117
|
+
cache[key] = value
|
118
|
+
expect {
|
119
|
+
expect(cache.clear_for_tags(%w[ #foo ])).to eq cache
|
120
|
+
}.to change {
|
121
|
+
cache.size
|
122
|
+
}.from(2).to(1)
|
123
|
+
expect(cache).not_to be_key 'foo'
|
124
|
+
expect(cache).to be_key 'bar'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'can return tags' do
|
128
|
+
key, value = 'foo', { tags: %w[ foo ], embedding: [ 0.5 ] * 1_024 }
|
129
|
+
cache[key] = value
|
130
|
+
key, value = 'bar', { tags: %w[ bar baz ], embedding: [ 0.5 ] * 1_024 }
|
131
|
+
cache[key] = value
|
132
|
+
tags = cache.tags
|
133
|
+
expect(tags).to be_a Ollama::Utils::Tags
|
134
|
+
expect(tags.to_a).to eq %w[ bar baz foo ]
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'can iterate over keys under a prefix' do
|
138
|
+
cache['foo'] = test_value
|
139
|
+
expect(cache.to_a).to eq [ [ 'test-foo', Ollama::Documents::Record[test_value] ] ]
|
140
|
+
end
|
141
|
+
end
|
@@ -10,6 +10,11 @@ RSpec.describe Ollama::Utils::Tags do
|
|
10
10
|
expect(tags.to_a).to eq %w[ bar foo ]
|
11
11
|
end
|
12
12
|
|
13
|
+
it 'can contain unique tags with leading # characters and is sorted' do
|
14
|
+
tags = described_class.new(%w[ #bar ##foo ])
|
15
|
+
expect(tags.to_a).to eq %w[ bar foo ]
|
16
|
+
end
|
17
|
+
|
13
18
|
it 'tags can be added to it' do
|
14
19
|
tags = described_class.new([ 'foo' ])
|
15
20
|
tags.add 'bar'
|
@@ -27,13 +32,13 @@ RSpec.describe Ollama::Utils::Tags do
|
|
27
32
|
expect { tags.clear }.to change { tags.size }.from(2).to(0)
|
28
33
|
end
|
29
34
|
|
30
|
-
it 'tags can be
|
35
|
+
it 'tags can be empty' do
|
31
36
|
tags = described_class.new([ 'foo' ])
|
32
37
|
expect { tags.clear }.to change { tags.empty? }.from(false).to(true)
|
33
38
|
end
|
34
39
|
|
35
40
|
it 'can be output nicely' do
|
36
|
-
expect(described_class.new(%w[ foo bar ]).to_s).to eq '#bar #foo'
|
41
|
+
expect(described_class.new(%w[ #foo bar ]).to_s).to eq '#bar #foo'
|
37
42
|
end
|
38
43
|
|
39
44
|
it 'can be output nicely with links to source' do
|
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.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.6'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
40
|
+
version: '0.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -358,6 +358,40 @@ dependencies:
|
|
358
358
|
- - "~>"
|
359
359
|
- !ruby/object:Gem::Version
|
360
360
|
version: '0.0'
|
361
|
+
- !ruby/object:Gem::Dependency
|
362
|
+
name: sqlite-vec
|
363
|
+
requirement: !ruby/object:Gem::Requirement
|
364
|
+
requirements:
|
365
|
+
- - "~>"
|
366
|
+
- !ruby/object:Gem::Version
|
367
|
+
version: '0.0'
|
368
|
+
type: :runtime
|
369
|
+
prerelease: false
|
370
|
+
version_requirements: !ruby/object:Gem::Requirement
|
371
|
+
requirements:
|
372
|
+
- - "~>"
|
373
|
+
- !ruby/object:Gem::Version
|
374
|
+
version: '0.0'
|
375
|
+
- !ruby/object:Gem::Dependency
|
376
|
+
name: sqlite3
|
377
|
+
requirement: !ruby/object:Gem::Requirement
|
378
|
+
requirements:
|
379
|
+
- - "~>"
|
380
|
+
- !ruby/object:Gem::Version
|
381
|
+
version: '2.0'
|
382
|
+
- - ">="
|
383
|
+
- !ruby/object:Gem::Version
|
384
|
+
version: 2.0.1
|
385
|
+
type: :runtime
|
386
|
+
prerelease: false
|
387
|
+
version_requirements: !ruby/object:Gem::Requirement
|
388
|
+
requirements:
|
389
|
+
- - "~>"
|
390
|
+
- !ruby/object:Gem::Version
|
391
|
+
version: '2.0'
|
392
|
+
- - ">="
|
393
|
+
- !ruby/object:Gem::Version
|
394
|
+
version: 2.0.1
|
361
395
|
description: Library that allows interacting with the Ollama API
|
362
396
|
email: flori@ping.de
|
363
397
|
executables:
|
@@ -387,8 +421,10 @@ extra_rdoc_files:
|
|
387
421
|
- lib/ollama/documents.rb
|
388
422
|
- lib/ollama/documents/cache/common.rb
|
389
423
|
- lib/ollama/documents/cache/memory_cache.rb
|
424
|
+
- lib/ollama/documents/cache/records.rb
|
390
425
|
- lib/ollama/documents/cache/redis_backed_memory_cache.rb
|
391
426
|
- lib/ollama/documents/cache/redis_cache.rb
|
427
|
+
- lib/ollama/documents/cache/sqlite_cache.rb
|
392
428
|
- lib/ollama/documents/splitters/character.rb
|
393
429
|
- lib/ollama/documents/splitters/semantic.rb
|
394
430
|
- lib/ollama/dto.rb
|
@@ -452,8 +488,10 @@ files:
|
|
452
488
|
- lib/ollama/documents.rb
|
453
489
|
- lib/ollama/documents/cache/common.rb
|
454
490
|
- lib/ollama/documents/cache/memory_cache.rb
|
491
|
+
- lib/ollama/documents/cache/records.rb
|
455
492
|
- lib/ollama/documents/cache/redis_backed_memory_cache.rb
|
456
493
|
- lib/ollama/documents/cache/redis_cache.rb
|
494
|
+
- lib/ollama/documents/cache/sqlite_cache.rb
|
457
495
|
- lib/ollama/documents/splitters/character.rb
|
458
496
|
- lib/ollama/documents/splitters/semantic.rb
|
459
497
|
- lib/ollama/dto.rb
|
@@ -503,9 +541,10 @@ files:
|
|
503
541
|
- spec/ollama/commands/push_spec.rb
|
504
542
|
- spec/ollama/commands/show_spec.rb
|
505
543
|
- spec/ollama/commands/tags_spec.rb
|
506
|
-
- spec/ollama/documents/memory_cache_spec.rb
|
507
|
-
- spec/ollama/documents/redis_backed_memory_cache_spec.rb
|
508
|
-
- spec/ollama/documents/redis_cache_spec.rb
|
544
|
+
- spec/ollama/documents/cache/memory_cache_spec.rb
|
545
|
+
- spec/ollama/documents/cache/redis_backed_memory_cache_spec.rb
|
546
|
+
- spec/ollama/documents/cache/redis_cache_spec.rb
|
547
|
+
- spec/ollama/documents/cache/sqlite_cache_spec.rb
|
509
548
|
- spec/ollama/documents/splitters/character_spec.rb
|
510
549
|
- spec/ollama/documents/splitters/semantic_spec.rb
|
511
550
|
- spec/ollama/documents_spec.rb
|
@@ -571,9 +610,10 @@ test_files:
|
|
571
610
|
- spec/ollama/commands/push_spec.rb
|
572
611
|
- spec/ollama/commands/show_spec.rb
|
573
612
|
- spec/ollama/commands/tags_spec.rb
|
574
|
-
- spec/ollama/documents/memory_cache_spec.rb
|
575
|
-
- spec/ollama/documents/redis_backed_memory_cache_spec.rb
|
576
|
-
- spec/ollama/documents/redis_cache_spec.rb
|
613
|
+
- spec/ollama/documents/cache/memory_cache_spec.rb
|
614
|
+
- spec/ollama/documents/cache/redis_backed_memory_cache_spec.rb
|
615
|
+
- spec/ollama/documents/cache/redis_cache_spec.rb
|
616
|
+
- spec/ollama/documents/cache/sqlite_cache_spec.rb
|
577
617
|
- spec/ollama/documents/splitters/character_spec.rb
|
578
618
|
- spec/ollama/documents/splitters/semantic_spec.rb
|
579
619
|
- spec/ollama/documents_spec.rb
|