ollama_chat 0.0.48 → 0.0.50

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a1e4b299c79b7a7c31c4a9c91b72a65739123ae4cf1d6db7ca0949b8b2965de
4
- data.tar.gz: 2eca8b68cb0484b4664e2bcf12132ea529ab9fad3f3c709d083122e44acfde45
3
+ metadata.gz: 913e3ff0ad4e2b4a7a6d2825f5772f8a4e68dc2931925d096d0989b23e153756
4
+ data.tar.gz: ae44b7d36ebbdc1013bc90841e4dfacd685d99d949a84c201ab0f8cc512dee0b
5
5
  SHA512:
6
- metadata.gz: 42844ce0fc93dceba6b70dec976be9c6bbe1aaef93f937c8c42e9f555f2533beb69b24975c35142dc6b42de15ba5d74a9cb1afff7e5b324e97a6c915f014a0c1
7
- data.tar.gz: c771c974561288203645875f8491f5b7aa9d63c712197fada535614347b067ca22f02c72da71d6d772e034008448551de94b5ffb37ef4ea307ebcb2ed5c1d3f2
6
+ metadata.gz: 7ce3e6e9cebf291d8ffb56fa8960b244f500e6f1e15f65f49a6f1905779032b22559e3b720b8fa22bef2f9992ae634f1aad6a92797a61e080788e9277ca1ee89
7
+ data.tar.gz: 2c7a36c2487c92767345e00a65c3167b5b41339891918421700322fe2722efeda525c6baf447553cd3021fd7a174a10b2d93c32aa555ed274b4eac89dc671a96
data/CHANGES.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-01-03 v0.0.50
4
+
5
+ - Use Redis-based expiring cache implementation with the new
6
+ `OllamaChat::RedisCache` class
7
+ - Replaced `Documentrix::Documents::RedisCache` with `OllamaChat::RedisCache`
8
+ in the `setup_cache` method
9
+ - Updated `GemHadar` development dependency to version **2.16.3**
10
+ - Integrated changelog generation capability into GemHadar configuration
11
+ - Updated Redis image to valkey version **8.1.5** with latest bug fixes and
12
+ improvements
13
+ - Improved file path resolution using `Pathname` for better handling of
14
+ relative paths and home directory shortcuts
15
+ - Enhanced test suite configuration and stubbing for more consistent test
16
+ execution
17
+ - Updated Ruby image tag to stable **4.0**-alpine
18
+ - Added `lib/ollama_chat/redis_cache.rb` to `extra_rdoc_files` and `files`
19
+ lists in gemspec
20
+ - Added `spec/ollama_chat/redis_cache_spec.rb` to `test_files` list in gemspec
21
+ - Removed duplicate entry for `lib/ollama_chat/redis_cache.rb` from `files`
22
+ list
23
+ - Improved test setup for source fetching with explicit configuration file
24
+
25
+ ## 2025-12-24 v0.0.49
26
+
27
+ - Updated `unix_socks` gem dependency from **~> 0.2** to **~> 0.3**
28
+ - Replaced `UnixSocks::Server` with `UnixSocks::DomainSocketServer` in
29
+ `lib/ollama_chat/server_socket.rb`
30
+ - Updated test expectations in `spec/ollama_chat/server_socket_spec.rb` to
31
+ match new class name
32
+ - Bumped `gem_hadar` development dependency from **>= 2.16.0** to **>= 2.16.2**
33
+
3
34
  ## 2025-12-23 v0.0.48
4
35
 
5
36
  - Updated `unix_socks` dependency to version **0.2.3**
data/Rakefile CHANGED
@@ -28,6 +28,10 @@ GemHadar do
28
28
 
29
29
  readme 'README.md'
30
30
 
31
+ changelog do
32
+ filename 'CHANGES.md'
33
+ end
34
+
31
35
  required_ruby_version '>= 3.2'
32
36
 
33
37
  executables << 'ollama_chat' << 'ollama_chat_send'
@@ -36,14 +40,10 @@ GemHadar do
36
40
  'static.yml' => {}
37
41
  )
38
42
 
39
- changelog do
40
- filename 'CHANGES.md'
41
- end
42
-
43
43
  dependency 'excon', '~> 1.0'
44
44
  dependency 'ollama-ruby', '~> 1.18'
45
45
  dependency 'documentrix', '>= 0.0.4'
46
- dependency 'unix_socks', '~> 0.2', '>= 0.2.3'
46
+ dependency 'unix_socks', '~> 0.3'
47
47
  dependency 'rss', '~> 0.3'
48
48
  dependency 'term-ansicolor', '~> 1.11'
49
49
  dependency 'redis', '~> 5.0'
data/docker-compose.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  services:
2
2
  redis:
3
3
  container_name: redis
4
- image: valkey/valkey:8.1.3-alpine
4
+ image: valkey/valkey:8.1.5-alpine
5
5
  restart: unless-stopped
6
6
  ports: [ "127.0.0.1:9736:6379" ]
7
7
  volumes:
@@ -749,12 +749,12 @@ class OllamaChat::Chat
749
749
  # The setup_cache method initializes and returns a Redis cache instance with
750
750
  # expiring keys if a Redis URL is configured.
751
751
  #
752
- # @return [ Documentrix::Documents::RedisCache, nil ] the configured Redis
752
+ # @return [ OllamaChat::RedisCache, nil ] the configured Redis
753
753
  # cache instance or nil if no URL is set.
754
754
  def setup_cache
755
755
  if url = config.redis.expiring.url?
756
756
  ex = config.redis.expiring.ex?.to_i
757
- Documentrix::Documents::RedisCache.new(
757
+ OllamaChat::RedisCache.new(
758
758
  prefix: 'Expiring-',
759
759
  url:,
760
760
  ex:
@@ -78,10 +78,11 @@ module OllamaChat::MessageOutput
78
78
  # @return [ TrueClass ] returns true if the file was successfully written
79
79
  # @return [ nil ] returns nil if the user chose not to overwrite or if an error occurred
80
80
  def attempt_to_write_file(filename, message)
81
- if !File.exist?(filename) ||
82
- ask?(prompt: "File #{filename.inspect} already exists, overwrite? (y/n) ") =~ /\Ay/i
81
+ path = Pathname.new(filename.to_s).expand_path
82
+ if !path.exist? ||
83
+ ask?(prompt: "File #{path.to_s.inspect} already exists, overwrite? (y/n) ") =~ /\Ay/i
83
84
  then
84
- File.open(filename, ?w) do |output|
85
+ File.open(path, ?w) do |output|
85
86
  output.write(message.content)
86
87
  end
87
88
  else
@@ -0,0 +1,158 @@
1
+ require 'redis'
2
+
3
+ # A Redis-based cache implementation for OllamaChat
4
+ #
5
+ # This class provides a wrapper around Redis that offers a simple key-value
6
+ # caching interface with support for expiration times and namespace isolation.
7
+ # It's designed to be used as a cache backend for various components in the
8
+ # OllamaChat application.
9
+ #
10
+ # @example Basic usage
11
+ # cache = OllamaChat::RedisCache.new(prefix: 'myapp-', url: 'redis://localhost:6379')
12
+ # cache['key'] = 'value'
13
+ # value = cache['key']
14
+ # cache.delete('key')
15
+ #
16
+ # @example With expiration
17
+ # cache = OllamaChat::RedisCache.new(prefix: 'expiring-', url: 'redis://localhost:6379', ex: 3600)
18
+ # cache['key'] = 'value' # Automatically expires in 1 hour
19
+ #
20
+ # @example Iteration
21
+ # cache.each do |key, value|
22
+ # puts "#{key}: #{value}"
23
+ # end
24
+ #
25
+ # @example Cache management
26
+ # cache.clear # Remove all entries with this prefix
27
+ # size = cache.size # Get number of entries
28
+ module OllamaChat
29
+ class RedisCache
30
+ include Enumerable
31
+
32
+ # Initializes a new RedisCache instance
33
+ #
34
+ # @param prefix [String] The prefix to use for all keys in this cache
35
+ # @param url [String, nil] The Redis connection URL (defaults to ENV['REDIS_URL'])
36
+ # @param ex [Integer, nil] Default expiration time in seconds
37
+ #
38
+ # @raise [ArgumentError] If no Redis URL is provided
39
+ def initialize(prefix:, url: ENV['REDIS_URL'], ex: nil)
40
+ @prefix = prefix
41
+ @url = url
42
+ @ex = ex
43
+ raise ArgumentError, 'require redis url' unless @url
44
+ end
45
+
46
+ # Returns the Redis connection instance
47
+ #
48
+ # This method lazily initializes the Redis connection to avoid
49
+ # establishing connections until they're actually needed.
50
+ #
51
+ # @return [Redis] The Redis client instance
52
+ def redis
53
+ @redis ||= Redis.new(url: @url)
54
+ end
55
+
56
+ # Retrieves a value from the cache by key
57
+ #
58
+ # @param key [String] The cache key to retrieve
59
+ # @return [String, nil] The cached value or nil if not found
60
+ def [](key)
61
+ value = redis.get(pre(key))
62
+ value
63
+ end
64
+
65
+ # Stores a value in the cache with the given key
66
+ #
67
+ # @param key [String] The cache key
68
+ # @param value [String] The value to cache
69
+ # @return [String] The cached value
70
+ def []=(key, value)
71
+ set(key, value)
72
+ end
73
+
74
+ # Stores a value in the cache with optional expiration
75
+ #
76
+ # @param key [String] The cache key
77
+ # @param value [String] The value to cache
78
+ # @param ex [Integer, nil] Expiration time in seconds (overrides default)
79
+ # @return [String] The cached value
80
+ def set(key, value, ex: nil)
81
+ ex ||= @ex
82
+ if !ex.nil? && ex < 1
83
+ redis.del(pre(key))
84
+ else
85
+ redis.set(pre(key), value, ex:)
86
+ end
87
+ value
88
+ end
89
+
90
+ # Gets the time-to-live for a key
91
+ #
92
+ # @param key [String] The cache key
93
+ # @return [Integer] The remaining time-to-live in seconds, or -1 if not found
94
+ def ttl(key)
95
+ redis.ttl(pre(key))
96
+ end
97
+
98
+ # Checks if a key exists in the cache
99
+ #
100
+ # @param key [String] The cache key to check
101
+ # @return [Boolean] true if the key exists, false otherwise
102
+ def key?(key)
103
+ !!redis.exists?(pre(key))
104
+ end
105
+
106
+ # Deletes a key from the cache
107
+ #
108
+ # @param key [String] The cache key to delete
109
+ # @return [Boolean] true if the key was deleted, false if it didn't exist
110
+ def delete(key)
111
+ redis.del(pre(key)) == 1
112
+ end
113
+
114
+ # Gets the number of entries in the cache
115
+ #
116
+ # @return [Integer] The number of entries
117
+ def size
118
+ s = 0
119
+ redis.scan_each(match: "#{@prefix}*") { |key| s += 1 }
120
+ s
121
+ end
122
+
123
+ # Clears all entries from the cache with this prefix
124
+ #
125
+ # @return [OllamaChat::RedisCache] Returns self for chaining
126
+ def clear
127
+ redis.scan_each(match: "#{@prefix}*") { |key| redis.del(key) }
128
+ self
129
+ end
130
+
131
+ # Iterates over all entries in the cache
132
+ #
133
+ # @yield [key, value] Yields each key-value pair
134
+ # @return [OllamaChat::RedisCache] Returns self for chaining
135
+ def each(&block)
136
+ redis.scan_each(match: "#{@prefix}*") { |key| block.(key, self[unpre(key)]) }
137
+ self
138
+ end
139
+
140
+ private
141
+
142
+ # Prepends the prefix to a key
143
+ #
144
+ # @param key [String] The key to prefix
145
+ # @return [String] The prefixed key
146
+ def pre(key)
147
+ [ @prefix, key ].join
148
+ end
149
+
150
+ # Removes the prefix from a key
151
+ #
152
+ # @param key [String] The prefixed key
153
+ # @return [String] The key without prefix
154
+ def unpre(key)
155
+ key.sub(/\A#@prefix/, '')
156
+ end
157
+ end
158
+ end
@@ -58,7 +58,7 @@ module OllamaChat::ServerSocket
58
58
  # The create_socket_server method constructs and returns a Unix domain
59
59
  # socket server instance for communication with the Ollama Chat client.
60
60
  #
61
- # This method initializes a UnixSocks::Server object configured to listen
61
+ # This method initializes a UnixSocks::DomainSocketServer object configured to listen
62
62
  # for incoming messages on a named socket file. It supports specifying a
63
63
  # custom runtime directory for the socket, which is useful for isolating
64
64
  # multiple instances or environments. If no runtime directory is provided
@@ -70,19 +70,19 @@ module OllamaChat::ServerSocket
70
70
  # @param runtime_dir [ String ] pathname to runtime_dir of socket file
71
71
  # @param working_dir [ String ] pathname to working_dir used for deriving socket file
72
72
  #
73
- # @return [UnixSocks::Server] a configured Unix domain socket server
73
+ # @return [UnixSocks::DomainSocketServer] a configured Unix domain socket server
74
74
  # instance ready to receive messages
75
75
  def create_socket_server(config:, runtime_dir: nil, working_dir: nil)
76
76
  working_dir ||= Dir.pwd
77
77
  if runtime_dir
78
- return UnixSocks::Server.new(socket_name: 'ollama_chat.sock', runtime_dir:)
78
+ return UnixSocks::DomainSocketServer.new(socket_name: 'ollama_chat.sock', runtime_dir:)
79
79
  end
80
80
  if config.working_dir_dependent_socket
81
81
  path = File.expand_path(working_dir)
82
82
  digest = Digest::MD5.hexdigest(path)
83
- UnixSocks::Server.new(socket_name: "ollama_chat-#{digest}.sock")
83
+ UnixSocks::DomainSocketServer.new(socket_name: "ollama_chat-#{digest}.sock")
84
84
  else
85
- UnixSocks::Server.new(socket_name: 'ollama_chat.sock')
85
+ UnixSocks::DomainSocketServer.new(socket_name: 'ollama_chat.sock')
86
86
  end
87
87
  end
88
88
  end
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.48'
3
+ VERSION = '0.0.50'
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:
data/lib/ollama_chat.rb CHANGED
@@ -15,6 +15,7 @@ require 'documentrix'
15
15
  require 'unix_socks'
16
16
  require 'ollama_chat/version'
17
17
  require 'ollama_chat/utils'
18
+ require 'ollama_chat/redis_cache'
18
19
  require 'ollama_chat/message_format'
19
20
  require 'ollama_chat/ollama_chat_config'
20
21
  require 'ollama_chat/follow_chat'
data/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.48 ruby lib
2
+ # stub: ollama_chat 0.0.50 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.48".freeze
6
+ s.version = "0.0.50".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]
@@ -12,19 +12,19 @@ Gem::Specification.new do |s|
12
12
  s.description = "The app provides a command-line interface (CLI) to an Ollama AI model,\nallowing users to engage in text-based conversations and generate\nhuman-like responses. Users can import data from local files or web pages,\nwhich are then processed through three different modes: fully importing the\ncontent into the conversation context, summarizing the information for\nconcise reference, or storing it in an embedding vector database for later\nretrieval based on the conversation.\n".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_chat".freeze, "ollama_chat_send".freeze]
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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.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/think_control.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 = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.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/think_control.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/example_with_quote.html".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]
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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.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/redis_cache.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/think_control.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 = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.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/redis_cache.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/think_control.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/example_with_quote.html".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/redis_cache_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.2".freeze)
21
21
  s.rubygems_version = "4.0.2".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/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]
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/redis_cache_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.16.0".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.16.3".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])
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
35
35
  s.add_runtime_dependency(%q<excon>.freeze, ["~> 1.0".freeze])
36
36
  s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 1.18".freeze])
37
37
  s.add_runtime_dependency(%q<documentrix>.freeze, [">= 0.0.4".freeze])
38
- s.add_runtime_dependency(%q<unix_socks>.freeze, ["~> 0.2".freeze, ">= 0.2.3".freeze])
38
+ s.add_runtime_dependency(%q<unix_socks>.freeze, ["~> 0.3".freeze])
39
39
  s.add_runtime_dependency(%q<rss>.freeze, ["~> 0.3".freeze])
40
40
  s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
41
41
  s.add_runtime_dependency(%q<redis>.freeze, ["~> 5.0".freeze])
@@ -1,8 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::Chat, protect_env: true do
4
+ use_default_config = -> a {
5
+ a << '-f' << 'lib/ollama_chat/ollama_chat_config/default_config.yml'
6
+ }
7
+
4
8
  let :argv do
5
- %w[ -C test ]
9
+ use_default_config.(%w[ -C test ])
6
10
  end
7
11
 
8
12
  before do
@@ -94,7 +98,7 @@ describe OllamaChat::Chat, protect_env: true do
94
98
  end
95
99
 
96
100
  it 'returns :next when input is "/model"' do
97
- expect(chat).to receive(:choose_model).with('', 'llama3.1')
101
+ expect(chat).to receive(:choose_model).and_return 'llama3.1'
98
102
  expect(chat.handle_input("/model")).to eq :next
99
103
  end
100
104
 
@@ -226,7 +230,7 @@ describe OllamaChat::Chat, protect_env: true do
226
230
  connect_to_ollama_server(instantiate: false)
227
231
 
228
232
  let :argv do
229
- %w[ -C test -c ] << asset('conversation.json')
233
+ use_default_config.(%w[ -C test -c ] << asset('conversation.json'))
230
234
  end
231
235
 
232
236
  it 'dispays the last exchange of the converstation' do
@@ -243,7 +247,7 @@ describe OllamaChat::Chat, protect_env: true do
243
247
  context 'with MemoryCache' do
244
248
 
245
249
  let :argv do
246
- %w[ -M ]
250
+ use_default_config.(%w[ -M ])
247
251
  end
248
252
 
249
253
  it 'can use MemoryCache' do
@@ -265,7 +269,7 @@ describe OllamaChat::Chat, protect_env: true do
265
269
  connect_to_ollama_server(instantiate: false)
266
270
 
267
271
  let :argv do
268
- %w[ -C test -D ] << asset('example.html')
272
+ use_default_config.(%w[ -C test -D ] << asset('example.html'))
269
273
  end
270
274
 
271
275
  it 'Adds documents passed to app via -D option' do
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::RedisCache do
4
+ let :prefix do
5
+ 'test-'
6
+ end
7
+
8
+ let :cache do
9
+ described_class.new(prefix:, url: 'something').expose
10
+ end
11
+
12
+ it 'can be instantiated' do
13
+ expect(cache).to be_a described_class
14
+ end
15
+
16
+ it 'raises ArgumentError if url is missing' do
17
+ expect {
18
+ described_class.new prefix:, url: nil
19
+ }.to raise_error ArgumentError
20
+ end
21
+
22
+ context 'test redis interactions' do
23
+ let :redis do
24
+ double('Redis')
25
+ end
26
+
27
+ before do
28
+ allow_any_instance_of(described_class).to receive(:redis).and_return(redis)
29
+ end
30
+
31
+ it 'has Redis client' do
32
+ expect(cache.redis).to eq redis
33
+ end
34
+
35
+ it 'can get a key' do
36
+ key = 'foo'
37
+ expect(redis).to receive(:get).with(prefix + key).and_return 'some_value'
38
+ expect(cache[key]).to eq 'some_value'
39
+ end
40
+
41
+ it 'can set a value for a key' do
42
+ key, value = 'foo', 'some_value'
43
+ expect(redis).to receive(:set).with(prefix + key, value, ex: nil)
44
+ cache[key] = value
45
+ end
46
+
47
+ it 'can set a value for a key with ttl' do
48
+ cache = described_class.new prefix:, url: 'something', ex: 3_600
49
+ key, value = 'foo', 'some_value'
50
+ expect(redis).to receive(:set).with(prefix + key, value, ex: 3_600)
51
+ cache[key] = value
52
+ expect(redis).to receive(:ttl).with(prefix + key).and_return 3_600
53
+ expect(cache.ttl(key)).to eq 3_600
54
+ end
55
+
56
+ it 'can determine if key exists' do
57
+ key = 'foo'
58
+ expect(redis).to receive(:exists?).with(prefix + key).and_return(false, true)
59
+ expect(cache.key?('foo')).to eq false
60
+ expect(cache.key?('foo')).to eq true
61
+ end
62
+
63
+ it 'can delete' do
64
+ key = 'foo'
65
+ expect(redis).to receive(:del).with(prefix + key).and_return 1
66
+ expect(cache.delete(key)).to eq true
67
+ expect(redis).to receive(:del).with(prefix + key).and_return 0
68
+ expect(cache.delete(key)).to eq false
69
+ end
70
+
71
+ it 'can iterate over keys, values' do
72
+ key, value = 'foo', 'some_value'
73
+ expect(redis).to receive(:set).with(prefix + key, value, ex: nil)
74
+ cache[key] = value
75
+ expect(redis).to receive(:scan_each).with(match: "#{prefix}*").
76
+ and_yield("#{prefix}foo")
77
+ expect(redis).to receive(:get).with(prefix + key).and_return('some_value')
78
+ cache.each do |k, v|
79
+ expect(k).to eq prefix + key
80
+ expect(v).to eq value
81
+ end
82
+ end
83
+
84
+ it 'returns size' do
85
+ expect(redis).to receive(:scan_each).with(match: "#{prefix}*").
86
+ and_yield("#{prefix}foo").
87
+ and_yield("#{prefix}bar").
88
+ and_yield("#{prefix}baz")
89
+ expect(cache.size).to eq 3
90
+ end
91
+
92
+ it 'can clear' do
93
+ expect(redis).to receive(:scan_each).with(match: 'test-*').and_yield(
94
+ 'test-foo'
95
+ )
96
+ expect(redis).to receive(:del).with('test-foo')
97
+ expect(cache.clear).to eq cache
98
+ end
99
+
100
+ it 'can iterate over keys under a prefix' do
101
+ expect(redis).to receive(:scan_each).with(match: 'test-*')
102
+ cache.to_a
103
+ end
104
+
105
+ it 'can compute prefix with pre' do
106
+ expect(cache.pre('foo')).to eq 'test-foo'
107
+ end
108
+
109
+ it 'can remove prefix with unpre' do
110
+ expect(cache.unpre('test-foo')).to eq 'foo'
111
+ end
112
+ end
113
+ end
114
+
@@ -131,7 +131,7 @@ describe OllamaChat::ServerSocket do
131
131
  context 'with working dir dependent socket' do
132
132
  it 'can be created with configured runtime_dir' do
133
133
  config = double('Config', working_dir_dependent_socket: true)
134
- expect(UnixSocks::Server).to receive(:new).with(
134
+ expect(UnixSocks::DomainSocketServer).to receive(:new).with(
135
135
  socket_name: /\Aollama_chat-\h{32}.sock\z/,
136
136
  ).and_return :unix_socks_server
137
137
 
@@ -143,7 +143,7 @@ describe OllamaChat::ServerSocket do
143
143
  context 'with default runtime_dir and name' do
144
144
  it 'can be created with default runtime_dir' do
145
145
  config = double('Config', working_dir_dependent_socket: false)
146
- expect(UnixSocks::Server).to receive(:new).with(
146
+ expect(UnixSocks::DomainSocketServer).to receive(:new).with(
147
147
  socket_name: 'ollama_chat.sock'
148
148
  ).and_return :unix_socks_server
149
149
 
@@ -2,7 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::SourceFetching do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new(
6
+ argv: %w[ -f lib/ollama_chat/ollama_chat_config/default_config.yml ]
7
+ )
6
8
  end
7
9
 
8
10
  connect_to_ollama_server
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ollama_chat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.48
4
+ version: 0.0.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 2.16.0
18
+ version: 2.16.3
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 2.16.0
25
+ version: 2.16.3
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: all_images
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -169,20 +169,14 @@ dependencies:
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '0.2'
173
- - - ">="
174
- - !ruby/object:Gem::Version
175
- version: 0.2.3
172
+ version: '0.3'
176
173
  type: :runtime
177
174
  prerelease: false
178
175
  version_requirements: !ruby/object:Gem::Requirement
179
176
  requirements:
180
177
  - - "~>"
181
178
  - !ruby/object:Gem::Version
182
- version: '0.2'
183
- - - ">="
184
- - !ruby/object:Gem::Version
185
- version: 0.2.3
179
+ version: '0.3'
186
180
  - !ruby/object:Gem::Dependency
187
181
  name: rss
188
182
  requirement: !ruby/object:Gem::Requirement
@@ -417,6 +411,7 @@ extra_rdoc_files:
417
411
  - lib/ollama_chat/model_handling.rb
418
412
  - lib/ollama_chat/ollama_chat_config.rb
419
413
  - lib/ollama_chat/parsing.rb
414
+ - lib/ollama_chat/redis_cache.rb
420
415
  - lib/ollama_chat/server_socket.rb
421
416
  - lib/ollama_chat/source_fetching.rb
422
417
  - lib/ollama_chat/switches.rb
@@ -457,6 +452,7 @@ files:
457
452
  - lib/ollama_chat/ollama_chat_config.rb
458
453
  - lib/ollama_chat/ollama_chat_config/default_config.yml
459
454
  - lib/ollama_chat/parsing.rb
455
+ - lib/ollama_chat/redis_cache.rb
460
456
  - lib/ollama_chat/server_socket.rb
461
457
  - lib/ollama_chat/source_fetching.rb
462
458
  - lib/ollama_chat/switches.rb
@@ -497,6 +493,7 @@ files:
497
493
  - spec/ollama_chat/message_output_spec.rb
498
494
  - spec/ollama_chat/model_handling_spec.rb
499
495
  - spec/ollama_chat/parsing_spec.rb
496
+ - spec/ollama_chat/redis_cache_spec.rb
500
497
  - spec/ollama_chat/server_socket_spec.rb
501
498
  - spec/ollama_chat/source_fetching_spec.rb
502
499
  - spec/ollama_chat/switches_spec.rb
@@ -542,6 +539,7 @@ test_files:
542
539
  - spec/ollama_chat/message_output_spec.rb
543
540
  - spec/ollama_chat/model_handling_spec.rb
544
541
  - spec/ollama_chat/parsing_spec.rb
542
+ - spec/ollama_chat/redis_cache_spec.rb
545
543
  - spec/ollama_chat/server_socket_spec.rb
546
544
  - spec/ollama_chat/source_fetching_spec.rb
547
545
  - spec/ollama_chat/switches_spec.rb