ollama_chat 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.all_images.yml +17 -0
  3. data/.gitignore +9 -0
  4. data/Gemfile +5 -0
  5. data/README.md +159 -0
  6. data/Rakefile +58 -0
  7. data/VERSION +1 -0
  8. data/bin/ollama_chat +5 -0
  9. data/lib/ollama_chat/chat.rb +398 -0
  10. data/lib/ollama_chat/clipboard.rb +23 -0
  11. data/lib/ollama_chat/dialog.rb +94 -0
  12. data/lib/ollama_chat/document_cache.rb +16 -0
  13. data/lib/ollama_chat/follow_chat.rb +60 -0
  14. data/lib/ollama_chat/information.rb +113 -0
  15. data/lib/ollama_chat/message_list.rb +216 -0
  16. data/lib/ollama_chat/message_type.rb +5 -0
  17. data/lib/ollama_chat/model_handling.rb +29 -0
  18. data/lib/ollama_chat/ollama_chat_config.rb +103 -0
  19. data/lib/ollama_chat/parsing.rb +159 -0
  20. data/lib/ollama_chat/source_fetching.rb +173 -0
  21. data/lib/ollama_chat/switches.rb +119 -0
  22. data/lib/ollama_chat/utils/cache_fetcher.rb +38 -0
  23. data/lib/ollama_chat/utils/chooser.rb +53 -0
  24. data/lib/ollama_chat/utils/fetcher.rb +175 -0
  25. data/lib/ollama_chat/utils/file_argument.rb +34 -0
  26. data/lib/ollama_chat/utils.rb +7 -0
  27. data/lib/ollama_chat/version.rb +8 -0
  28. data/lib/ollama_chat.rb +20 -0
  29. data/ollama_chat.gemspec +50 -0
  30. data/spec/assets/api_show.json +63 -0
  31. data/spec/assets/api_tags.json +21 -0
  32. data/spec/assets/conversation.json +14 -0
  33. data/spec/assets/duckduckgo.html +757 -0
  34. data/spec/assets/example.atom +26 -0
  35. data/spec/assets/example.csv +5 -0
  36. data/spec/assets/example.html +10 -0
  37. data/spec/assets/example.pdf +139 -0
  38. data/spec/assets/example.ps +4 -0
  39. data/spec/assets/example.rb +1 -0
  40. data/spec/assets/example.rss +25 -0
  41. data/spec/assets/example.xml +7 -0
  42. data/spec/assets/kitten.jpg +0 -0
  43. data/spec/assets/prompt.txt +1 -0
  44. data/spec/ollama_chat/chat_spec.rb +105 -0
  45. data/spec/ollama_chat/clipboard_spec.rb +29 -0
  46. data/spec/ollama_chat/follow_chat_spec.rb +46 -0
  47. data/spec/ollama_chat/information_spec.rb +50 -0
  48. data/spec/ollama_chat/message_list_spec.rb +132 -0
  49. data/spec/ollama_chat/model_handling_spec.rb +35 -0
  50. data/spec/ollama_chat/parsing_spec.rb +240 -0
  51. data/spec/ollama_chat/source_fetching_spec.rb +54 -0
  52. data/spec/ollama_chat/switches_spec.rb +167 -0
  53. data/spec/ollama_chat/utils/cache_fetcher_spec.rb +43 -0
  54. data/spec/ollama_chat/utils/fetcher_spec.rb +137 -0
  55. data/spec/ollama_chat/utils/file_argument_spec.rb +17 -0
  56. data/spec/spec_helper.rb +46 -0
  57. data/tmp/.keep +0 -0
  58. 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,5 @@
1
+ Name,Age,Occupation
2
+ John Doe,32,Software Engineer
3
+ Jane Smith,28,Marketing Manager
4
+ Bob Johnson,45,Retired
5
+ Alice Brown,25,Student
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <body>
4
+
5
+ <h1>My First Heading</h1>
6
+
7
+ <p>My first paragraph.</p>
8
+
9
+ </body>
10
+ </html>
@@ -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,4 @@
1
+ %!PS
2
+ /Times-Bold findfont 36 scalefont setfont
3
+ 72 684 moveto (Hello World!) show
4
+ showpage
@@ -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>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <note>
3
+ <to>Tove</to>
4
+ <from>Jani</from>
5
+ <heading>Reminder</heading>
6
+ <body>Don't forget me this weekend!</body>
7
+ </note>
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