ollama_chat 0.0.24 → 0.0.26

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.contexts/code_comment.rb +25 -0
  3. data/.contexts/full.rb +31 -0
  4. data/.contexts/info.rb +17 -0
  5. data/.contexts/lib.rb +25 -0
  6. data/.contexts/yard.md +94 -0
  7. data/.gitignore +1 -0
  8. data/CHANGES.md +39 -0
  9. data/README.md +10 -1
  10. data/Rakefile +4 -3
  11. data/VERSION +1 -1
  12. data/bin/ollama_chat_send +9 -2
  13. data/lib/ollama_chat/chat.rb +42 -18
  14. data/lib/ollama_chat/clipboard.rb +12 -0
  15. data/lib/ollama_chat/dialog.rb +17 -0
  16. data/lib/ollama_chat/document_cache.rb +28 -10
  17. data/lib/ollama_chat/follow_chat.rb +26 -7
  18. data/lib/ollama_chat/history.rb +55 -7
  19. data/lib/ollama_chat/information.rb +32 -1
  20. data/lib/ollama_chat/kramdown_ansi.rb +15 -1
  21. data/lib/ollama_chat/message_format.rb +16 -0
  22. data/lib/ollama_chat/message_list.rb +52 -5
  23. data/lib/ollama_chat/message_output.rb +12 -0
  24. data/lib/ollama_chat/model_handling.rb +17 -0
  25. data/lib/ollama_chat/ollama_chat_config/default_config.yml +4 -2
  26. data/lib/ollama_chat/ollama_chat_config.rb +19 -0
  27. data/lib/ollama_chat/parsing.rb +13 -0
  28. data/lib/ollama_chat/server_socket.rb +34 -3
  29. data/lib/ollama_chat/source_fetching.rb +25 -2
  30. data/lib/ollama_chat/switches.rb +49 -0
  31. data/lib/ollama_chat/utils/cache_fetcher.rb +15 -0
  32. data/lib/ollama_chat/utils/chooser.rb +16 -0
  33. data/lib/ollama_chat/utils/fetcher.rb +41 -1
  34. data/lib/ollama_chat/utils/file_argument.rb +19 -0
  35. data/lib/ollama_chat/utils.rb +8 -0
  36. data/lib/ollama_chat/version.rb +1 -1
  37. data/lib/ollama_chat/vim.rb +6 -0
  38. data/lib/ollama_chat/web_searching.rb +11 -0
  39. data/lib/ollama_chat.rb +9 -0
  40. data/ollama_chat.gemspec +8 -7
  41. data/spec/ollama_chat/chat_spec.rb +11 -1
  42. data/spec/ollama_chat/kramdown_ansi_spec.rb +45 -0
  43. data/spec/ollama_chat/message_list_spec.rb +70 -9
  44. data/spec/ollama_chat/server_socket_spec.rb +68 -47
  45. data/spec/spec_helper.rb +120 -26
  46. metadata +28 -7
@@ -1,3 +1,22 @@
1
+ # A module that provides functionality for handling file arguments and content
2
+ # retrieval.
3
+ #
4
+ # The FileArgument module offers methods to process either file paths or direct
5
+ # string content, determining whether the input represents a file that should
6
+ # be read or if it's already a string of content to be used directly. It also
7
+ # includes logic to handle default values when no valid input is provided.
8
+ #
9
+ # @example Retrieving file contents or using direct content
10
+ # FileArgument.get_file_argument('path/to/file.txt')
11
+ # # Returns the contents of the file if it exists
12
+ #
13
+ # @example Using a string as content
14
+ # FileArgument.get_file_argument('direct content string')
15
+ # # Returns the string itself
16
+ #
17
+ # @example Providing a default value
18
+ # FileArgument.get_file_argument(nil, default: 'fallback content')
19
+ # # Returns 'fallback content' when no valid input is given
1
20
  module OllamaChat::Utils::FileArgument
2
21
  module_function
3
22
 
@@ -1,3 +1,11 @@
1
+ # A module that provides utility classes and methods for the OllamaChat
2
+ # application.
3
+ #
4
+ # The Utils module serves as a namespace for various helper components that
5
+ # support the core functionality of OllamaChat. It contains implementations for
6
+ # caching, interactive selection, content fetching, and file argument handling
7
+ # that are used throughout the application to provide robust and user-friendly
8
+ # features.
1
9
  module OllamaChat::Utils
2
10
  end
3
11
 
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.24'
3
+ VERSION = '0.0.26'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -1,6 +1,12 @@
1
1
  require 'tempfile'
2
2
  require 'pathname'
3
3
 
4
+ # A class that provides functionality for inserting text into Vim buffers via
5
+ # remote communication.
6
+ #
7
+ # @example
8
+ # vim = OllamaChat::Vim.new("MY_SERVER")
9
+ # vim.insert("Hello, Vim!")
4
10
  class OllamaChat::Vim
5
11
  # Initializes a new Vim server connection
6
12
  #
@@ -1,3 +1,14 @@
1
+ # A module that provides web search functionality for OllamaChat.
2
+ #
3
+ # The WebSearching module encapsulates the logic for performing web searches
4
+ # using configured search engines. It handles query construction, location
5
+ # information integration, and delegates to engine-specific implementations for
6
+ # retrieving search results. The module supports multiple search engines
7
+ # including SearxNG and DuckDuckGo, making it flexible for different deployment
8
+ # scenarios and privacy preferences.
9
+ #
10
+ # @example Performing a web search
11
+ # chat.search_web('ruby programming tutorials', 5)
1
12
  module OllamaChat::WebSearching
2
13
  # The search_web method performs a web search using the configured search
3
14
  # engine.
data/lib/ollama_chat.rb CHANGED
@@ -1,3 +1,12 @@
1
+ # The main module namespace for the OllamaChat application.
2
+ #
3
+ # This module serves as the root namespace for all components of the OllamaChat
4
+ # Ruby gem, providing access to core classes, utilities, and configuration
5
+ # management for interacting with Ollama language models through a terminal
6
+ # interface.
7
+ #
8
+ # @example Accessing the main module
9
+ # OllamaChat::VERSION # => "0.0.25"
1
10
  module OllamaChat
2
11
  end
3
12
 
data/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.24 ruby lib
2
+ # stub: ollama_chat 0.0.26 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.24".freeze
6
+ s.version = "0.0.26".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]
@@ -13,26 +13,27 @@ Gem::Specification.new do |s|
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_chat".freeze, "ollama_chat_send".freeze]
15
15
  s.extra_rdoc_files = ["README.md".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "lib/ollama_chat/vim.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze]
16
- s.files = [".all_images.yml".freeze, ".envrc".freeze, ".gitignore".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_send".freeze, "config/searxng/settings.yml".freeze, "docker-compose.yml".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "lib/ollama_chat/vim.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze, "ollama_chat.gemspec".freeze, "redis/redis.conf".freeze, "spec/assets/api_show.json".freeze, "spec/assets/api_tags.json".freeze, "spec/assets/api_version.json".freeze, "spec/assets/conversation.json".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.html".freeze, "spec/assets/example.pdf".freeze, "spec/assets/example.ps".freeze, "spec/assets/example.rb".freeze, "spec/assets/example.rss".freeze, "spec/assets/example.xml".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/assets/searxng.json".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
16
+ s.files = [".all_images.yml".freeze, ".contexts/code_comment.rb".freeze, ".contexts/full.rb".freeze, ".contexts/info.rb".freeze, ".contexts/lib.rb".freeze, ".contexts/yard.md".freeze, ".envrc".freeze, ".gitignore".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_send".freeze, "config/searxng/settings.yml".freeze, "docker-compose.yml".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "lib/ollama_chat/vim.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze, "ollama_chat.gemspec".freeze, "redis/redis.conf".freeze, "spec/assets/api_show.json".freeze, "spec/assets/api_tags.json".freeze, "spec/assets/api_version.json".freeze, "spec/assets/conversation.json".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.html".freeze, "spec/assets/example.pdf".freeze, "spec/assets/example.ps".freeze, "spec/assets/example.rb".freeze, "spec/assets/example.rss".freeze, "spec/assets/example.xml".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/assets/searxng.json".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
17
17
  s.homepage = "https://github.com/flori/ollama_chat".freeze
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "OllamaChat - A command-line interface (CLI) for interacting with an Ollama AI model.".freeze, "--main".freeze, "README.md".freeze]
20
20
  s.required_ruby_version = Gem::Requirement.new("~> 3.1".freeze)
21
21
  s.rubygems_version = "3.6.9".freeze
22
22
  s.summary = "A command-line interface (CLI) for interacting with an Ollama AI model.".freeze
23
- s.test_files = ["spec/assets/example.rb".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze]
23
+ s.test_files = ["spec/assets/example.rb".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze]
24
24
 
25
25
  s.specification_version = 4
26
26
 
27
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.0".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.1".freeze])
28
28
  s.add_development_dependency(%q<all_images>.freeze, ["~> 0.6".freeze])
29
29
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
30
30
  s.add_development_dependency(%q<kramdown>.freeze, ["~> 2.0".freeze])
31
31
  s.add_development_dependency(%q<webmock>.freeze, [">= 0".freeze])
32
32
  s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
33
33
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
34
+ s.add_development_dependency(%q<context_spook>.freeze, [">= 0".freeze])
34
35
  s.add_runtime_dependency(%q<excon>.freeze, ["~> 1.0".freeze])
35
- s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 1.2".freeze])
36
+ s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 1.6".freeze])
36
37
  s.add_runtime_dependency(%q<documentrix>.freeze, ["~> 0.0".freeze, ">= 0.0.2".freeze])
37
38
  s.add_runtime_dependency(%q<unix_socks>.freeze, [">= 0.0.1".freeze])
38
39
  s.add_runtime_dependency(%q<rss>.freeze, ["~> 0.3".freeze])
@@ -43,7 +44,7 @@ Gem::Specification.new do |s|
43
44
  s.add_runtime_dependency(%q<xdg>.freeze, [">= 0".freeze])
44
45
  s.add_runtime_dependency(%q<kramdown-ansi>.freeze, ["~> 0.1".freeze])
45
46
  s.add_runtime_dependency(%q<complex_config>.freeze, ["~> 0.22".freeze, ">= 0.22.2".freeze])
46
- s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.34".freeze])
47
+ s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.41".freeze])
47
48
  s.add_runtime_dependency(%q<search_ui>.freeze, ["~> 0.0".freeze])
48
49
  s.add_runtime_dependency(%q<amatch>.freeze, ["~> 0.4.1".freeze])
49
50
  s.add_runtime_dependency(%q<pdf-reader>.freeze, ["~> 2.0".freeze])
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe OllamaChat::Chat do
3
+ describe OllamaChat::Chat, protect_env: true do
4
4
  let :argv do
5
5
  %w[ -C test ]
6
6
  end
@@ -77,6 +77,16 @@ describe OllamaChat::Chat do
77
77
  expect(chat.handle_input("/clobber")).to eq :next
78
78
  end
79
79
 
80
+ it 'returns :next when input is "/last"' do
81
+ expect(chat.messages).to receive(:show_last)
82
+ expect(chat.handle_input("/last")).to eq :next
83
+ end
84
+
85
+ it 'returns :next when input is "/last\s+(\d+)"' do
86
+ expect(chat.messages).to receive(:show_last).with(2)
87
+ expect(chat.handle_input("/last 2")).to eq :next
88
+ end
89
+
80
90
  it 'returns :next when input is "/drop(?:\s+(\d*))?"' do
81
91
  expect(chat.messages).to receive(:drop).with(?2)
82
92
  expect(chat.messages).to receive(:show_last)
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::KramdownANSI do
4
+ let :chat do
5
+ double('Chat').extend(described_class)
6
+ end
7
+
8
+ describe '#configure_kramdown_ansi_styles', protect_env: true do
9
+ it 'can be configured via env var' do
10
+ ENV['KRAMDOWN_ANSI_OLLAMA_CHAT_STYLES'] = '{}'
11
+ ENV.delete('KRAMDOWN_ANSI_STYLES')
12
+
13
+ styles = { bold: '1' }
14
+ expect(Kramdown::ANSI::Styles).to receive(:from_env_var).
15
+ with('KRAMDOWN_ANSI_OLLAMA_CHAT_STYLES').
16
+ and_return(double(ansi_styles: styles))
17
+
18
+ expect(chat.configure_kramdown_ansi_styles).to eq(styles)
19
+ end
20
+
21
+ it 'has a default configuration' do
22
+ ENV.delete('KRAMDOWN_ANSI_OLLAMA_CHAT_STYLES')
23
+ ENV.delete('KRAMDOWN_ANSI_STYLES')
24
+
25
+ expect(chat.configure_kramdown_ansi_styles).to be_a(Hash)
26
+ end
27
+ end
28
+
29
+ describe '#kramdown_ansi_parse' do
30
+ it 'can parse markdown' do
31
+ content = "# Header\n\nParagraph text"
32
+ result = chat.kramdown_ansi_parse(content)
33
+
34
+ expect(result).to be_a(String)
35
+ end
36
+
37
+ it 'handles empty string correctly' do
38
+ expect(chat.kramdown_ansi_parse('')).to eq ''
39
+ end
40
+
41
+ it 'handles nil correctly' do
42
+ expect(chat.kramdown_ansi_parse(nil)).to eq ''
43
+ end
44
+ end
45
+ end
@@ -39,7 +39,7 @@ describe OllamaChat::MessageList do
39
39
  expect(list.size).to eq 1
40
40
  list.clear
41
41
  expect(list.size).to eq 1
42
- list << Ollama::Message.new(role: 'user', content: 'world')
42
+ list << Ollama::Message.new(role: 'user', content: 'world')
43
43
  expect(list.size).to eq 2
44
44
  list.clear
45
45
  expect(list.size).to eq 1
@@ -47,7 +47,7 @@ describe OllamaChat::MessageList do
47
47
 
48
48
  it 'can be added to' do
49
49
  expect(list.size).to eq 1
50
- list << Ollama::Message.new(role: 'user', content: 'world')
50
+ list << Ollama::Message.new(role: 'user', content: 'world')
51
51
  expect(list.size).to eq 2
52
52
  end
53
53
 
@@ -71,6 +71,67 @@ describe OllamaChat::MessageList do
71
71
  FileUtils.rm_f 'tmp/test-conversation.json'
72
72
  end
73
73
 
74
+ describe "#last" do
75
+ it "returns the last message when there are multiple messages" do
76
+ list = described_class.new(chat)
77
+ list << Ollama::Message.new(role: 'system', content: 'hello')
78
+ list << Ollama::Message.new(role: 'user', content: 'First message')
79
+ list << Ollama::Message.new(role: 'assistant', content: 'Second message')
80
+
81
+ expect(list.last.content).to eq('Second message')
82
+ end
83
+
84
+ it "returns the last message when there is only one message" do
85
+ list = described_class.new(chat)
86
+ list << Ollama::Message.new(role: 'system', content: 'hello')
87
+
88
+ expect(list.last.content).to eq('hello')
89
+ end
90
+
91
+ it "returns nil when there are no messages" do
92
+ list = described_class.new(chat)
93
+
94
+ expect(list.last).to be_nil
95
+ end
96
+ end
97
+
98
+ describe '#show_last' do
99
+ it 'shows nothing when there are no messages' do
100
+ empty_list = described_class.new(chat)
101
+ expect { empty_list.show_last }.not_to raise_error
102
+ expect(empty_list.show_last).to be nil
103
+ end
104
+
105
+ it 'shows nothing when the last message is by the assistant' do
106
+ list = described_class.new(chat)
107
+ allow(chat).to receive(:think).and_return(double(on?: false))
108
+ allow(chat).to receive(:markdown).and_return(double(on?: false))
109
+ list << Ollama::Message.new(role: 'assistant', content: 'hello')
110
+ expect(STDOUT).to receive(:puts).
111
+ with("📨 \e[1m\e[38;5;111massistant\e[0m\e[0m:\nhello\n")
112
+ expect(list.show_last).to be_a described_class
113
+ end
114
+
115
+ it 'shows nothing when the last message is by the user' do
116
+ list = described_class.new(chat)
117
+ list << Ollama::Message.new(role: 'user', content: 'world')
118
+ expect { list.show_last }.not_to raise_error
119
+ expect(list.show_last).to be nil
120
+ end
121
+
122
+ it "shows last N messages when N is larger than available messages" do
123
+ allow(chat).to receive(:think).and_return(double(on?: false))
124
+ allow(chat).to receive(:markdown).and_return(double(on?: false))
125
+ list = described_class.new(chat)
126
+ list << Ollama::Message.new(role: 'system', content: 'hello')
127
+ list << Ollama::Message.new(role: 'user', content: 'First message')
128
+ list << Ollama::Message.new(role: 'assistant', content: 'Second message')
129
+
130
+ expect(STDOUT).to receive(:puts).with(/Second message/)
131
+ expect(list.show_last(23)).to eq(list)
132
+ end
133
+ end
134
+
74
135
  context 'without pager' do
75
136
  before do
76
137
  expect(list).to receive(:determine_pager_command).and_return nil
@@ -91,7 +152,7 @@ describe OllamaChat::MessageList do
91
152
  and_return(double(on?: true)).at_least(:once)
92
153
  expect(chat).to receive(:think).
93
154
  and_return(double(on?: false)).at_least(:once)
94
- list << Ollama::Message.new(role: 'user', content: 'world')
155
+ list << Ollama::Message.new(role: 'user', content: 'world')
95
156
  expect(STDOUT).to receive(:puts).
96
157
  with(
97
158
  "📨 \e[1m\e[38;5;213msystem\e[0m\e[0m:\nhello\n" \
@@ -132,7 +193,7 @@ describe OllamaChat::MessageList do
132
193
  and_return(double(on?: true)).at_least(:once)
133
194
  expect(chat).to receive(:think).
134
195
  and_return(double(on?: false)).at_least(:once)
135
- list << Ollama::Message.new(role: 'user', content: 'world')
196
+ list << Ollama::Message.new(role: 'user', content: 'world')
136
197
  list.list_conversation
137
198
  end
138
199
  end
@@ -169,9 +230,9 @@ describe OllamaChat::MessageList do
169
230
  expect(list.size).to eq 1
170
231
  expect(list.drop(1)).to eq 0
171
232
  expect(list.size).to eq 1
172
- list << Ollama::Message.new(role: 'user', content: 'world')
233
+ list << Ollama::Message.new(role: 'user', content: 'world')
173
234
  expect(list.size).to eq 2
174
- list << Ollama::Message.new(role: 'assistant', content: 'hi')
235
+ list << Ollama::Message.new(role: 'assistant', content: 'hi')
175
236
  expect(list.size).to eq 3
176
237
  expect(list.drop(1)).to eq 1
177
238
  expect(list.size).to eq 1
@@ -201,7 +262,7 @@ describe OllamaChat::MessageList do
201
262
 
202
263
  it 'can be converted int an Ollama::Message array' do
203
264
  expect(chat).to receive(:location).and_return(double(on?: false))
204
- list << Ollama::Message.new(role: 'user', content: 'world')
265
+ list << Ollama::Message.new(role: 'user', content: 'world')
205
266
  expect(list.to_ary.map(&:as_json)).to eq [
206
267
  Ollama::Message.new(role: 'system', content: 'hello').as_json,
207
268
  Ollama::Message.new(role: 'user', content: 'world').as_json,
@@ -210,7 +271,7 @@ describe OllamaChat::MessageList do
210
271
 
211
272
  it 'can be converted int an Ollama::Message array with location' do
212
273
  expect(chat).to receive(:location).and_return(double(on?: true))
213
- list << Ollama::Message.new(role: 'user', content: 'world')
274
+ list << Ollama::Message.new(role: 'user', content: 'world')
214
275
  first = list.to_ary.first
215
276
  expect(first.role).to eq 'system'
216
277
  expect(first.content).to match(
@@ -220,7 +281,7 @@ describe OllamaChat::MessageList do
220
281
  it 'can be converted int an Ollama::Message array with location without a system prompt' do
221
282
  expect(chat).to receive(:location).and_return(double(on?: true))
222
283
  list = described_class.new(chat).tap do |list|
223
- list << Ollama::Message.new(role: 'user', content: 'hello')
284
+ list << Ollama::Message.new(role: 'user', content: 'hello')
224
285
  list << Ollama::Message.new(role: 'assistant', content: 'world')
225
286
  end
226
287
  first = list.to_ary.first
@@ -9,75 +9,96 @@ describe OllamaChat::ServerSocket do
9
9
  let(:config) { double('Config') }
10
10
  let(:server) { double('Server') }
11
11
 
12
- before do
13
- expect(OllamaChat::ServerSocket).to receive(:create_socket_server).with(config: config).and_return(server)
14
- end
12
+ context 'without runtime_dir' do
15
13
 
16
- context 'with default parameters' do
17
- it 'uses correct defaults' do
18
- message = { content: 'test', type: :socket_input, parse: false }
14
+ before do
15
+ expect(OllamaChat::ServerSocket).to receive(:create_socket_server).
16
+ with(config: config, runtime_dir: nil).and_return(server)
17
+ end
19
18
 
20
- expect(server).to receive(:transmit).with(message).and_return(nil)
19
+ context 'with default parameters' do
20
+ it 'uses correct defaults' do
21
+ message = { content: 'test', type: :socket_input, parse: false }
21
22
 
22
- result = OllamaChat::ServerSocket.send_to_server_socket('test', config: config)
23
+ expect(server).to receive(:transmit).with(message).and_return(nil)
23
24
 
24
- expect(result).to be_nil
25
+ result = OllamaChat::ServerSocket.send_to_server_socket('test', config: config)
26
+
27
+ expect(result).to be_nil
28
+ end
25
29
  end
26
- end
27
30
 
28
- context 'with :socket_input type and parse: true' do
29
- it 'sends message with parse flag and returns nil' do
30
- message = { content: 'test', type: :socket_input, parse: true }
31
+ context 'with :socket_input type and parse: true' do
32
+ it 'sends message with parse flag and returns nil' do
33
+ message = { content: 'test', type: :socket_input, parse: true }
31
34
 
32
- expect(server).to receive(:transmit).with(message).and_return(nil)
35
+ expect(server).to receive(:transmit).with(message).and_return(nil)
33
36
 
34
- result = OllamaChat::ServerSocket.send_to_server_socket(
35
- 'test',
36
- config: config,
37
- type: :socket_input,
38
- parse: true
39
- )
37
+ result = OllamaChat::ServerSocket.send_to_server_socket(
38
+ 'test',
39
+ config: config,
40
+ type: :socket_input,
41
+ parse: true
42
+ )
40
43
 
41
- expect(result).to be_nil
44
+ expect(result).to be_nil
45
+ end
42
46
  end
43
- end
44
47
 
45
- context 'with :socket_input_with_response type and parse: false' do
46
- it 'sends message and returns response with parse flag' do
47
- message = { content: 'test', type: :socket_input_with_response, parse: false }
48
- response = double('Response')
48
+ context 'with :socket_input_with_response type and parse: false' do
49
+ it 'sends message and returns response with parse flag' do
50
+ message = { content: 'test', type: :socket_input_with_response, parse: false }
51
+ response = double('Response')
49
52
 
50
- expect(server).to receive(:transmit_with_response).with(message).and_return(response)
53
+ expect(server).to receive(:transmit_with_response).with(message).and_return(response)
51
54
 
52
- result = OllamaChat::ServerSocket.send_to_server_socket(
53
- 'test',
54
- config: config,
55
- type: :socket_input_with_response,
56
- parse: false
57
- )
55
+ result = OllamaChat::ServerSocket.send_to_server_socket(
56
+ 'test',
57
+ config: config,
58
+ type: :socket_input_with_response,
59
+ parse: false
60
+ )
58
61
 
59
- expect(result).to eq(response)
62
+ expect(result).to eq(response)
63
+ end
60
64
  end
61
- end
62
65
 
63
- context 'with :socket_input_with_response type and parse: true' do
64
- it 'sends message and returns response with parse flag' do
65
- message = { content: 'test', type: :socket_input_with_response, parse: true }
66
- response = double('Response')
66
+ context 'with :socket_input_with_response type and parse: true' do
67
+ it 'sends message and returns response with parse flag' do
68
+ message = { content: 'test', type: :socket_input_with_response, parse: true }
69
+ response = double('Response')
67
70
 
68
- expect(server).to receive(:transmit_with_response).with(message).and_return(response)
71
+ expect(server).to receive(:transmit_with_response).with(message).and_return(response)
69
72
 
70
- result = OllamaChat::ServerSocket.send_to_server_socket(
71
- 'test',
72
- config: config,
73
- type: :socket_input_with_response,
74
- parse: true
75
- )
73
+ result = OllamaChat::ServerSocket.send_to_server_socket(
74
+ 'test',
75
+ config: config,
76
+ type: :socket_input_with_response,
77
+ parse: true
78
+ )
76
79
 
77
- expect(result).to eq(response)
80
+ expect(result).to eq(response)
81
+ end
78
82
  end
79
83
  end
80
84
 
85
+ context 'with runtime_dir parameter' do
86
+ before do
87
+ expect(OllamaChat::ServerSocket).to receive(:create_socket_server).
88
+ with(config: config, runtime_dir: '/foo/bar').and_return(server)
89
+ end
90
+
91
+ it 'uses correct defaults' do
92
+ message = { content: 'test', type: :socket_input, parse: false }
93
+
94
+ expect(server).to receive(:transmit).with(message).and_return(nil)
95
+
96
+
97
+ result = OllamaChat::ServerSocket.send_to_server_socket('test', config: config, runtime_dir: '/foo/bar')
98
+
99
+ expect(result).to be_nil
100
+ end
101
+ end
81
102
  end
82
103
 
83
104
  describe '#create_socket_server' do