ollama_chat 0.0.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 +7 -0
- data/.all_images.yml +17 -0
- data/.gitignore +9 -0
- data/Gemfile +5 -0
- data/README.md +159 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/bin/ollama_chat +5 -0
- data/lib/ollama_chat/chat.rb +398 -0
- data/lib/ollama_chat/clipboard.rb +23 -0
- data/lib/ollama_chat/dialog.rb +94 -0
- data/lib/ollama_chat/document_cache.rb +16 -0
- data/lib/ollama_chat/follow_chat.rb +60 -0
- data/lib/ollama_chat/information.rb +113 -0
- data/lib/ollama_chat/message_list.rb +216 -0
- data/lib/ollama_chat/message_type.rb +5 -0
- data/lib/ollama_chat/model_handling.rb +29 -0
- data/lib/ollama_chat/ollama_chat_config.rb +103 -0
- data/lib/ollama_chat/parsing.rb +159 -0
- data/lib/ollama_chat/source_fetching.rb +173 -0
- data/lib/ollama_chat/switches.rb +119 -0
- data/lib/ollama_chat/utils/cache_fetcher.rb +38 -0
- data/lib/ollama_chat/utils/chooser.rb +53 -0
- data/lib/ollama_chat/utils/fetcher.rb +175 -0
- data/lib/ollama_chat/utils/file_argument.rb +34 -0
- data/lib/ollama_chat/utils.rb +7 -0
- data/lib/ollama_chat/version.rb +8 -0
- data/lib/ollama_chat.rb +20 -0
- data/ollama_chat.gemspec +50 -0
- data/spec/assets/api_show.json +63 -0
- data/spec/assets/api_tags.json +21 -0
- data/spec/assets/conversation.json +14 -0
- data/spec/assets/duckduckgo.html +757 -0
- data/spec/assets/example.atom +26 -0
- data/spec/assets/example.csv +5 -0
- data/spec/assets/example.html +10 -0
- data/spec/assets/example.pdf +139 -0
- data/spec/assets/example.ps +4 -0
- data/spec/assets/example.rb +1 -0
- data/spec/assets/example.rss +25 -0
- data/spec/assets/example.xml +7 -0
- data/spec/assets/kitten.jpg +0 -0
- data/spec/assets/prompt.txt +1 -0
- data/spec/ollama_chat/chat_spec.rb +105 -0
- data/spec/ollama_chat/clipboard_spec.rb +29 -0
- data/spec/ollama_chat/follow_chat_spec.rb +46 -0
- data/spec/ollama_chat/information_spec.rb +50 -0
- data/spec/ollama_chat/message_list_spec.rb +132 -0
- data/spec/ollama_chat/model_handling_spec.rb +35 -0
- data/spec/ollama_chat/parsing_spec.rb +240 -0
- data/spec/ollama_chat/source_fetching_spec.rb +54 -0
- data/spec/ollama_chat/switches_spec.rb +167 -0
- data/spec/ollama_chat/utils/cache_fetcher_spec.rb +43 -0
- data/spec/ollama_chat/utils/fetcher_spec.rb +137 -0
- data/spec/ollama_chat/utils/file_argument_spec.rb +17 -0
- data/spec/spec_helper.rb +46 -0
- data/tmp/.keep +0 -0
- metadata +476 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<title>Example Feed</title>
|
4
|
+
<link rel="self" type="application/atom+xml" href="https://example.com/feed.atom"/>
|
5
|
+
<id>urn:uuid:12345678-1234-1234-1234-123456789012</id>
|
6
|
+
<updated>2024-01-01T12:00:00Z</updated>
|
7
|
+
|
8
|
+
<!-- Entry 1 -->
|
9
|
+
<entry>
|
10
|
+
<title>New Study Shows Benefits of Meditation</title>
|
11
|
+
<link rel="alternate" type="text/html" href="https://example.com/article/meditation-benefits"/>
|
12
|
+
<id>urn:uuid:23456789-2345-2345-2345-234567890123</id>
|
13
|
+
<updated>2024-01-01T12:00:00Z</updated>
|
14
|
+
<summary>A new study has found that regular meditation can have numerous physical and mental health benefits.</summary>
|
15
|
+
</entry>
|
16
|
+
|
17
|
+
<!-- Entry 2 -->
|
18
|
+
<entry>
|
19
|
+
<title>Local Business Opens New Location</title>
|
20
|
+
<link rel="alternate" type="text/html" href="https://example.com/article/local-business-new-location"/>
|
21
|
+
<id>urn:uuid:34567890-3456-3456-3456-345678901234</id>
|
22
|
+
<updated>2024-01-02T10:00:00Z</updated>
|
23
|
+
<summary>A local business has opened a new location in the area.</summary>
|
24
|
+
</entry>
|
25
|
+
|
26
|
+
</feed>
|
@@ -0,0 +1,139 @@
|
|
1
|
+
%PDF-1.3
|
2
|
+
%����
|
3
|
+
2 0 obj
|
4
|
+
<<
|
5
|
+
/Length 75
|
6
|
+
>>
|
7
|
+
stream
|
8
|
+
BT
|
9
|
+
/TT2 1 Tf
|
10
|
+
36 0 0 36 72 684 Tm
|
11
|
+
0 g
|
12
|
+
/GS1 gs
|
13
|
+
0 Tc
|
14
|
+
0 Tw
|
15
|
+
(Hello World!)Tj
|
16
|
+
ET
|
17
|
+
endstream
|
18
|
+
endobj
|
19
|
+
3 0 obj
|
20
|
+
<<
|
21
|
+
/ProcSet [/PDF /Text ]
|
22
|
+
/Font <<
|
23
|
+
/TT2 4 0 R
|
24
|
+
>>
|
25
|
+
/ExtGState <<
|
26
|
+
/GS1 5 0 R
|
27
|
+
>>
|
28
|
+
>>
|
29
|
+
endobj
|
30
|
+
5 0 obj
|
31
|
+
<<
|
32
|
+
/Type /ExtGState
|
33
|
+
/SA false
|
34
|
+
/SM 0.02
|
35
|
+
/OP false
|
36
|
+
/op false
|
37
|
+
/OPM 1
|
38
|
+
/BG2 /Default
|
39
|
+
/UCR2 /Default
|
40
|
+
/HT /Default
|
41
|
+
/TR2 /Default
|
42
|
+
>>
|
43
|
+
endobj
|
44
|
+
7 0 obj
|
45
|
+
<<
|
46
|
+
/Type /FontDescriptor
|
47
|
+
/Ascent 750
|
48
|
+
/CapHeight 676
|
49
|
+
/Descent -250
|
50
|
+
/Flags 262178
|
51
|
+
/FontBBox [-168 -218 1000 935]
|
52
|
+
/FontName /Times-Bold
|
53
|
+
/ItalicAngle 0
|
54
|
+
/StemV 133
|
55
|
+
/XHeight 461
|
56
|
+
/StemH 139
|
57
|
+
>>
|
58
|
+
endobj
|
59
|
+
4 0 obj
|
60
|
+
<<
|
61
|
+
/Type /Font
|
62
|
+
/Subtype /TrueType
|
63
|
+
/FirstChar 32
|
64
|
+
/LastChar 114
|
65
|
+
/Widths [250 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
66
|
+
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
67
|
+
0 0 0 0 0 0 0 0 778 0 0 0 0 0 0 0
|
68
|
+
0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0
|
69
|
+
0 0 0 0 556 444 0 0 0 0 0 0 278 0 0 500
|
70
|
+
0 0 444 ]
|
71
|
+
/Encoding /WinAnsiEncoding
|
72
|
+
/BaseFont /Times-Bold
|
73
|
+
/FontDescriptor 7 0 R
|
74
|
+
>>
|
75
|
+
endobj
|
76
|
+
1 0 obj
|
77
|
+
<<
|
78
|
+
/Type /Page
|
79
|
+
/Parent 6 0 R
|
80
|
+
/Resources 3 0 R
|
81
|
+
/Contents 2 0 R
|
82
|
+
>>
|
83
|
+
endobj
|
84
|
+
8 0 obj
|
85
|
+
<<
|
86
|
+
/S /D
|
87
|
+
>>
|
88
|
+
endobj
|
89
|
+
9 0 obj
|
90
|
+
<<
|
91
|
+
/Nums [0 8 0 R ]
|
92
|
+
>>
|
93
|
+
endobj
|
94
|
+
6 0 obj
|
95
|
+
<<
|
96
|
+
/Type /Pages
|
97
|
+
/Kids [1 0 R]
|
98
|
+
/Count 1
|
99
|
+
/MediaBox [0 0 612 792]
|
100
|
+
>>
|
101
|
+
endobj
|
102
|
+
10 0 obj
|
103
|
+
<<
|
104
|
+
/CreationDate (D:20250120235539+01'00')
|
105
|
+
/ModDate (D:20250120235539+01'00')
|
106
|
+
/Producer (Apple pstopdf)
|
107
|
+
>>
|
108
|
+
endobj
|
109
|
+
11 0 obj
|
110
|
+
<<
|
111
|
+
/Type /Catalog
|
112
|
+
/Pages 6 0 R
|
113
|
+
/PageLabels 9 0 R
|
114
|
+
>>
|
115
|
+
endobj
|
116
|
+
xref
|
117
|
+
0 12
|
118
|
+
0000000000 65535 f
|
119
|
+
0000000929 00000 n
|
120
|
+
0000000016 00000 n
|
121
|
+
0000000141 00000 n
|
122
|
+
0000000577 00000 n
|
123
|
+
0000000236 00000 n
|
124
|
+
0000001074 00000 n
|
125
|
+
0000000376 00000 n
|
126
|
+
0000001009 00000 n
|
127
|
+
0000001036 00000 n
|
128
|
+
0000001155 00000 n
|
129
|
+
0000001278 00000 n
|
130
|
+
trailer
|
131
|
+
<<
|
132
|
+
/Size 12
|
133
|
+
/Root 11 0 R
|
134
|
+
/Info 10 0 R
|
135
|
+
/ID [<d30f9b19200969dad7c3656d50e43d11><d30f9b19200969dad7c3656d50e43d11>]
|
136
|
+
>>
|
137
|
+
startxref
|
138
|
+
1346
|
139
|
+
%%EOF
|
@@ -0,0 +1 @@
|
|
1
|
+
puts "Hello World!"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<rss version="2.0">
|
3
|
+
<channel>
|
4
|
+
<title>Example News Feed</title>
|
5
|
+
<link>https://example.com</link>
|
6
|
+
<description>A sample news feed.</description>
|
7
|
+
|
8
|
+
<!-- Item 1 -->
|
9
|
+
<item>
|
10
|
+
<title>New Study Shows Benefits of Meditation</title>
|
11
|
+
<link>https://example.com/article/meditation-benefits</link>
|
12
|
+
<pubDate>Mon, 01 Jan 2024 12:00:00 GMT</pubDate>
|
13
|
+
<description>A new study has found that regular meditation can have numerous physical and mental health benefits.</description>
|
14
|
+
</item>
|
15
|
+
|
16
|
+
<!-- Item 2 -->
|
17
|
+
<item>
|
18
|
+
<title>Local Business Opens New Location</title>
|
19
|
+
<link>https://example.com/article/local-business-new-location</link>
|
20
|
+
<pubDate>Tue, 02 Jan 2024 10:00:00 GMT</pubDate>
|
21
|
+
<description>A local business has opened a new location in the area.</description>
|
22
|
+
</item>
|
23
|
+
|
24
|
+
</channel>
|
25
|
+
</rss>
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
You are a test prompt just used for testing.
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::Chat do
|
4
|
+
let :argv do
|
5
|
+
[]
|
6
|
+
end
|
7
|
+
|
8
|
+
let :chat do
|
9
|
+
OllamaChat::Chat.new argv: argv
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
stub_request(:get, %r(/api/tags\z)).
|
14
|
+
to_return(status: 200, body: asset_json('api_tags.json'))
|
15
|
+
stub_request(:post, %r(/api/show\z)).
|
16
|
+
to_return(status: 200, body: asset_json('api_show.json'))
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can be instantiated' do
|
20
|
+
expect(chat).to be_a described_class
|
21
|
+
end
|
22
|
+
|
23
|
+
describe OllamaChat::DocumentCache do
|
24
|
+
context 'with MemoryCache' do
|
25
|
+
let :argv do
|
26
|
+
%w[ -M ]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'can use MemoryCache' do
|
30
|
+
expect(chat.documents.cache).to be_a Documentrix::Documents::MemoryCache
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'falls back to MemoryCache' do
|
35
|
+
it 'falls back to MemoryCache' do
|
36
|
+
expect_any_instance_of(OllamaChat::Chat).to\
|
37
|
+
receive(:document_cache_class).and_raise(NameError)
|
38
|
+
expect(chat.documents.cache).to be_a Documentrix::Documents::MemoryCache
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Documentrix::Documents do
|
44
|
+
context 'with documents' do
|
45
|
+
let :argv do
|
46
|
+
%w[ -D ] << asset('example.html')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'Adds documents passed to app via -D option' do
|
50
|
+
expect_any_instance_of(OllamaChat::Chat).to receive(:add_documents_from_argv).
|
51
|
+
with(kind_of(Documentrix::Documents), [ asset('example.html') ])
|
52
|
+
chat
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe OllamaChat::Information do
|
58
|
+
it 'has progname' do
|
59
|
+
expect(chat.progname).to eq 'ollama_chat'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'has user_agent' do
|
63
|
+
expect(chat.user_agent).to match %r(\Aollama_chat/\d+\.\d+\.\d+\z)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'can display collection_stats' do
|
67
|
+
chat
|
68
|
+
expect(STDOUT).to receive(:puts).with(
|
69
|
+
"Current Collection\n Name: \e[1mdefault\e[0m\n #Embeddings: 0\n #Tags: 0\n Tags: \n"
|
70
|
+
)
|
71
|
+
expect(chat.collection_stats).to be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'can display info' do
|
75
|
+
chat
|
76
|
+
expect(STDOUT).to receive(:puts).
|
77
|
+
with(
|
78
|
+
/
|
79
|
+
Current\ model|
|
80
|
+
Options|
|
81
|
+
Embedding|
|
82
|
+
Text\ splitter|
|
83
|
+
Documents\ database\ cache|
|
84
|
+
output\ content|
|
85
|
+
Streaming|
|
86
|
+
Location|
|
87
|
+
Document\ policy
|
88
|
+
/x
|
89
|
+
).at_least(1)
|
90
|
+
expect(chat.info).to be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'can display usage' do
|
94
|
+
chat
|
95
|
+
expect(STDOUT).to receive(:puts).with(/\AUsage: ollama_chat/)
|
96
|
+
expect(chat.usage).to eq 0
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'can display version' do
|
100
|
+
chat
|
101
|
+
expect(STDOUT).to receive(:puts).with(/\Aollama_chat \d+\.\d+\.\d+\z/)
|
102
|
+
expect(chat.version).to eq 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::Clipboard do
|
4
|
+
let :chat do
|
5
|
+
OllamaChat::Chat.new
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_request(:get, %r(/api/tags\z)).
|
10
|
+
to_return(status: 200, body: asset_json('api_tags.json'))
|
11
|
+
stub_request(:post, %r(/api/show\z)).
|
12
|
+
to_return(status: 200, body: asset_json('api_show.json'))
|
13
|
+
chat
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can copy to clipboard' do
|
17
|
+
expect(STDERR).to receive(:puts).with(/No response available to copy to the system clipboard/)
|
18
|
+
expect(chat.copy_to_clipboard).to be_nil
|
19
|
+
chat.instance_variable_get(:@messages).load_conversation(asset('conversation.json'))
|
20
|
+
expect(STDOUT).to receive(:puts).with(/The last response has been copied to the system clipboard/)
|
21
|
+
expect(chat.copy_to_clipboard).to be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can paste from input' do
|
25
|
+
expect(STDOUT).to receive(:puts).with(/Paste your content/)
|
26
|
+
expect(STDIN).to receive(:read).and_return 'test input'
|
27
|
+
expect(chat.paste_from_input).to eq 'test input'
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::FollowChat do
|
4
|
+
let :messages do
|
5
|
+
[
|
6
|
+
Ollama::Message.new(role: 'user', content: 'hello', images: []),
|
7
|
+
]
|
8
|
+
end
|
9
|
+
|
10
|
+
let :follow_chat do
|
11
|
+
described_class.new(messages:, output:)
|
12
|
+
end
|
13
|
+
|
14
|
+
let :output do
|
15
|
+
double('output', :sync= => true)
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow(OllamaChat::Chat).to receive(:config).and_return(double(debug: false))
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'has .call' do
|
23
|
+
expect(follow_chat).to receive(:call).with(:foo)
|
24
|
+
follow_chat.call(:foo)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can follow without markdown' do
|
28
|
+
message = Ollama::Message.new(role: 'assistant', content: 'world')
|
29
|
+
response = double(message:, done: false)
|
30
|
+
expect(output).to receive(:puts).with(/assistant/)
|
31
|
+
expect(output).to receive(:print).with(/world/)
|
32
|
+
follow_chat.call(response)
|
33
|
+
response = double(
|
34
|
+
message: nil,
|
35
|
+
done: true,
|
36
|
+
total_duration: 777.77,
|
37
|
+
eval_duration: 666.66,
|
38
|
+
eval_count: 23,
|
39
|
+
prompt_eval_duration: 42.0,
|
40
|
+
prompt_eval_count: 7,
|
41
|
+
load_duration: 33.45,
|
42
|
+
)
|
43
|
+
expect(output).to receive(:puts).with("", /eval_duration/)
|
44
|
+
follow_chat.call(response)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::Information do
|
4
|
+
let :chat do
|
5
|
+
OllamaChat::Chat.new
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_request(:get, %r(/api/tags\z)).
|
10
|
+
to_return(status: 200, body: asset_json('api_tags.json'))
|
11
|
+
stub_request(:post, %r(/api/show\z)).
|
12
|
+
to_return(status: 200, body: asset_json('api_show.json'))
|
13
|
+
chat
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ::OllamaChat::Information::UserAgent do
|
17
|
+
it 'has progname' do
|
18
|
+
expect(chat.progname).to eq 'ollama_chat'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has user_agent' do
|
22
|
+
expect(chat.user_agent).to match %r(\Aollama_chat/\d+\.\d+\.\d+\z)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can show collection_stats' do
|
27
|
+
expect(STDOUT).to receive(:puts).with(/Current Collection/)
|
28
|
+
expect(chat.collection_stats).to be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can show info' do
|
32
|
+
expect(STDOUT).to receive(:puts).with(/Current model is/)
|
33
|
+
expect(STDOUT).to receive(:puts).at_least(1)
|
34
|
+
expect(chat.info).to be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can show display_chat_help' do
|
38
|
+
expect(STDOUT).to receive(:puts).with(%r(/info.*show information))
|
39
|
+
expect(chat.display_chat_help).to be_nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can show usage' do
|
43
|
+
expect(STDOUT).to receive(:puts).with(/Usage: ollama_chat/)
|
44
|
+
expect(chat.usage).to eq 0
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can show version' do
|
48
|
+
expect(chat.version).to eq 0
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::MessageList do
|
4
|
+
let :config do
|
5
|
+
double(
|
6
|
+
location: double(
|
7
|
+
enabled: false,
|
8
|
+
name: 'Berlin',
|
9
|
+
decimal_degrees: [ 52.514127, 13.475211 ],
|
10
|
+
units: 'SI (International System of Units)'
|
11
|
+
),
|
12
|
+
prompts: double(
|
13
|
+
location: 'You are at %{location_name} (%{location_decimal_degrees}), on %{localtime}, preferring %{units}'
|
14
|
+
)
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
let :chat do
|
19
|
+
double('Chat', config:)
|
20
|
+
end
|
21
|
+
|
22
|
+
let :list do
|
23
|
+
described_class.new(chat).tap do |list|
|
24
|
+
list << Ollama::Message.new(role: 'system', content: 'hello')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can clear non system messages' do
|
29
|
+
expect(list.size).to eq 1
|
30
|
+
list.clear
|
31
|
+
expect(list.size).to eq 1
|
32
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
33
|
+
expect(list.size).to eq 2
|
34
|
+
list.clear
|
35
|
+
expect(list.size).to eq 1
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can be added to' do
|
39
|
+
expect(list.size).to eq 1
|
40
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
41
|
+
expect(list.size).to eq 2
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has a last message' do
|
45
|
+
expect(list.last).to be_a Ollama::Message
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'can load conversations if existing' do
|
49
|
+
expect(list.messages.first.role).to eq 'system'
|
50
|
+
expect(list.load_conversation(asset('conversation-nixda.json'))).to be_nil
|
51
|
+
expect {
|
52
|
+
list.load_conversation(asset('conversation.json'))
|
53
|
+
}.to change { list.messages.size }.from(1).to(3)
|
54
|
+
expect(list.messages.map(&:role)).to eq %w[ system user assistant ]
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can save conversations' do
|
58
|
+
expect(list.save_conversation('tmp/test-conversation.json')).to eq list
|
59
|
+
expect(list.save_conversation('tmp/test-conversation.json')).to be_nil
|
60
|
+
ensure
|
61
|
+
FileUtils.rm_f 'tmp/test-conversation.json'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'can list conversations' do
|
65
|
+
expect(chat).to receive(:markdown).
|
66
|
+
and_return(double(on?: true)).at_least(:once)
|
67
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
68
|
+
expect(STDOUT).to receive(:puts).
|
69
|
+
with("📨 \e[1m\e[38;5;213msystem\e[0m\e[0m:\nhello\n")
|
70
|
+
expect(STDOUT).to receive(:puts).
|
71
|
+
with("📨 \e[1m\e[38;5;172muser\e[0m\e[0m:\nworld\n")
|
72
|
+
list.list_conversation
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'can show_system_prompt' do
|
76
|
+
expect(list).to receive(:system).and_return 'test **prompt**'
|
77
|
+
expect(Kramdown::ANSI).to receive(:parse).with('test **prompt**').
|
78
|
+
and_call_original
|
79
|
+
expect(list.show_system_prompt).to eq list
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'can set_system_prompt' do
|
83
|
+
expect {
|
84
|
+
expect(list.set_system_prompt('test prompt')).to eq list
|
85
|
+
}.to change { list.system }.from(nil).to('test prompt')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'can drop n conversations exhanges' do
|
89
|
+
expect(list.size).to eq 1
|
90
|
+
expect(list.drop(1)).to eq 0
|
91
|
+
expect(list.size).to eq 1
|
92
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
93
|
+
expect(list.size).to eq 2
|
94
|
+
expect(list.drop(1)).to eq 0
|
95
|
+
list << Ollama::Message.new(role: 'assistant', content: 'hi')
|
96
|
+
expect(list.size).to eq 3
|
97
|
+
expect(list.drop(1)).to eq 1
|
98
|
+
expect(list.size).to eq 1
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'can determine location for system prompt' do
|
102
|
+
expect(chat).to receive(:location).and_return(double(on?: true))
|
103
|
+
expect(list.send(:at_location)).to match(
|
104
|
+
%r(You are at Berlin \(52.514127, 13.475211\), on))
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'can be converted int an Ollama::Message array' do
|
108
|
+
expect(chat).to receive(:location).and_return(double(on?: false))
|
109
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
110
|
+
expect(list.to_ary.map(&:as_json)).to eq [
|
111
|
+
Ollama::Message.new(role: 'system', content: 'hello').as_json,
|
112
|
+
Ollama::Message.new(role: 'user', content: 'world').as_json,
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'can be converted int an Ollama::Message array with location' do
|
117
|
+
expect(chat).to receive(:location).and_return(double(on?: true))
|
118
|
+
list << Ollama::Message.new(role: 'user', content: 'world')
|
119
|
+
first = list.to_ary.first
|
120
|
+
expect(first.role).to eq 'system'
|
121
|
+
expect(first.content).to match(
|
122
|
+
%r(You are at Berlin \(52.514127, 13.475211\), on))
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'can display messages with images' do
|
126
|
+
expect(list.message_type([])).to eq ?📨
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'can display messages without images' do
|
130
|
+
expect(list.message_type(%w[ image ])).to eq ?📸
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe OllamaChat::ModelHandling do
|
4
|
+
let :chat do
|
5
|
+
OllamaChat::Chat.new
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_request(:get, %r(/api/tags\z)).
|
10
|
+
to_return(status: 200, body: asset_json('api_tags.json'))
|
11
|
+
stub_request(:post, %r(/api/show\z)).
|
12
|
+
to_return(status: 200, body: asset_json('api_show.json'))
|
13
|
+
chat
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can check if model_present?' do
|
17
|
+
expect(chat.ollama).to receive(:show).and_raise Ollama::Errors::NotFoundError
|
18
|
+
expect(chat.model_present?('nixda')).to eq false
|
19
|
+
expect(chat.ollama).to receive(:show).and_return 'llama3.1'
|
20
|
+
expect(chat.model_present?('llama3.1')).to be_truthy
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can pull_model_from_remote' do
|
24
|
+
stub_request(:post, %r(/api/pull\z)).
|
25
|
+
to_return(status: 200, body: asset_json('api_show.json'))
|
26
|
+
expect(chat.pull_model_from_remote('llama3.1'))
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'can pull_model_unless_present' do
|
30
|
+
expect(chat).to receive(:model_present?).with('llama3.1').and_return false
|
31
|
+
expect(chat).to receive(:model_present?).with('llama3.1').and_return true
|
32
|
+
expect(chat).to receive(:pull_model_from_remote).with('llama3.1')
|
33
|
+
expect(chat.pull_model_unless_present('llama3.1', {}))
|
34
|
+
end
|
35
|
+
end
|