ollama_chat 0.0.20 → 0.0.21

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.
@@ -6,28 +6,56 @@ module OllamaChat::Switches
6
6
  alias_method :on?, :value
7
7
  end
8
8
 
9
+ # The off? method returns true if the switch is in the off state, false
10
+ # otherwise.
11
+ #
12
+ # @return [ TrueClass, FalseClass ] indicating whether the switch is off
9
13
  def off?
10
14
  !on?
11
15
  end
12
16
 
17
+ # The show method outputs the current value of the message to standard
18
+ # output.
19
+ #
20
+ # @return [ void ]
13
21
  def show
14
22
  STDOUT.puts @msg[value]
15
23
  end
16
24
  end
17
25
 
18
26
  class Switch
19
- def initialize(name, msg:, config:)
20
- @value = [ false, true ].include?(config) ? config : !!config.send("#{name}?")
27
+ # The initialize method sets up the switch with a default value and
28
+ # message.
29
+ #
30
+ # @param msg [ Hash ] a hash containing true and false messages
31
+ # @param value [ Object ] the default state of the switch
32
+ #
33
+ # @return [ void ]
34
+ def initialize(msg:, value:)
35
+ @value = !!value
21
36
  @msg = msg
22
37
  end
23
38
 
39
+ # The value reader returns the current value of the attribute.
24
40
  attr_reader :value
25
41
 
42
+ # The set method assigns a boolean value to the instance variable @value
43
+ # and optionally displays it.
44
+ #
45
+ # @param value [ Object ] the value to be converted to a boolean and
46
+ # assigned
47
+ # @param show [ TrueClass, FalseClass ] determines whether to display the
48
+ # value after setting
26
49
  def set(value, show: false)
27
50
  @value = !!value
28
51
  show && self.show
29
52
  end
30
53
 
54
+ # The toggle method switches the current value of the instance variable and
55
+ # optionally displays it.
56
+ #
57
+ # @param show [ TrueClass, FalseClass ] determines whether to show the
58
+ # value after toggling
31
59
  def toggle(show: true)
32
60
  @value = !@value
33
61
  show && self.show
@@ -37,11 +65,17 @@ module OllamaChat::Switches
37
65
  end
38
66
 
39
67
  class CombinedSwitch
68
+ # The initialize method sets up the switch with a value and message.
69
+ #
70
+ # @param value [ Object ] the value to be stored
71
+ # @param msg [ Hash ] the message hash containing true and false keys
40
72
  def initialize(value:, msg:)
41
73
  @value = value
42
74
  @msg = msg
43
75
  end
44
76
 
77
+ # The value method returns the result of calling the stored proc with no
78
+ # arguments.
45
79
  def value
46
80
  @value.()
47
81
  end
@@ -49,26 +83,61 @@ module OllamaChat::Switches
49
83
  include CheckSwitch
50
84
  end
51
85
 
86
+ # The think method returns the current state of the stream switch.
87
+ #
88
+ # @return [ OllamaChat::Switches::Switch ] the stream switch instance
52
89
  attr_reader :stream
53
90
 
91
+ # The think method returns the current state of the thinking switch.
92
+ #
93
+ # @return [ OllamaChat::Switches::Switch ] the thinking switch instance
54
94
  attr_reader :think
55
95
 
96
+ # The markdown attribute reader returns the markdown switch object.
97
+ # The voice reader returns the voice switch instance.
98
+ #
99
+ # @return [ OllamaChat::Switches::Switch ] the markdown switch instance
56
100
  attr_reader :markdown
57
101
 
102
+ # The voice reader returns the voice switch instance.
103
+ #
104
+ # @return [ OllamaChat::Switches::Switch ] the voice switch instance
58
105
  attr_reader :voice
59
106
 
107
+ # The embedding attribute reader returns the embedding switch object.
108
+ #
109
+ # @return [ OllamaChat::Switches::CombinedSwitch ] the embedding switch
110
+ # instance
60
111
  attr_reader :embedding
61
112
 
113
+ # The embedding_enabled reader returns the embedding enabled switch instance.
114
+ #
115
+ # @return [ OllamaChat::Switches::Switch ] the embedding enabled switch
116
+ # instance
62
117
  attr_reader :embedding_enabled
63
118
 
119
+ # The embedding_paused method returns the current state of the embedding pause flag.
120
+ #
121
+ # @return [ OllamaChat::Switches::Switch ] the embedding pause flag switch instance
64
122
  attr_reader :embedding_paused
65
123
 
124
+ # The location method returns the current location setting.
125
+ #
126
+ # @return [ OllamaChat::Switches::Switch ] the location setting object
66
127
  attr_reader :location
67
128
 
129
+ # The setup_switches method initializes various switches for configuring the
130
+ # application's behavior.
131
+ #
132
+ # This method creates and configures multiple switch objects that control
133
+ # different aspects of the application, such as streaming, thinking, markdown
134
+ # output, voice output, embedding, and location settings.
135
+ #
136
+ # @param config [ ComplexConfig::Settings ] the configuration object
137
+ # containing settings for the switches
68
138
  def setup_switches(config)
69
139
  @stream = Switch.new(
70
- :stream,
71
- config:,
140
+ value: config.stream,
72
141
  msg: {
73
142
  true => "Streaming enabled.",
74
143
  false => "Streaming disabled.",
@@ -76,8 +145,7 @@ module OllamaChat::Switches
76
145
  )
77
146
 
78
147
  @think = Switch.new(
79
- :think,
80
- config:,
148
+ value: config.think,
81
149
  msg: {
82
150
  true => "Thinking enabled.",
83
151
  false => "Thinking disabled.",
@@ -85,8 +153,7 @@ module OllamaChat::Switches
85
153
  )
86
154
 
87
155
  @markdown = Switch.new(
88
- :markdown,
89
- config:,
156
+ value: config.markdown,
90
157
  msg: {
91
158
  true => "Using #{italic{'ANSI'}} markdown to output content.",
92
159
  false => "Using plaintext for outputting content.",
@@ -94,8 +161,7 @@ module OllamaChat::Switches
94
161
  )
95
162
 
96
163
  @voice = Switch.new(
97
- :stream,
98
- config: config.voice,
164
+ value: config.voice.enabled,
99
165
  msg: {
100
166
  true => "Voice output enabled.",
101
167
  false => "Voice output disabled.",
@@ -103,8 +169,7 @@ module OllamaChat::Switches
103
169
  )
104
170
 
105
171
  @embedding_enabled = Switch.new(
106
- :embedding_enabled,
107
- config:,
172
+ value: config.embedding.enabled,
108
173
  msg: {
109
174
  true => "Embedding enabled.",
110
175
  false => "Embedding disabled.",
@@ -112,8 +177,7 @@ module OllamaChat::Switches
112
177
  )
113
178
 
114
179
  @embedding_paused = Switch.new(
115
- :embedding_paused,
116
- config:,
180
+ value: config.embedding.paused,
117
181
  msg: {
118
182
  true => "Embedding paused.",
119
183
  false => "Embedding resumed.",
@@ -129,8 +193,7 @@ module OllamaChat::Switches
129
193
  )
130
194
 
131
195
  @location = Switch.new(
132
- :location,
133
- config: config.location.enabled,
196
+ value: config.location.enabled,
134
197
  msg: {
135
198
  true => "Location and localtime enabled.",
136
199
  false => "Location and localtime disabled.",
@@ -1,10 +1,24 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  class OllamaChat::Utils::CacheFetcher
4
+ # The initialize method sets up the cache instance variable for the object.
5
+ #
6
+ # @param cache [ Object ] the cache object to be stored
7
+ #
8
+ # @return [ void ]
4
9
  def initialize(cache)
5
10
  @cache = cache
6
11
  end
7
12
 
13
+ # The get method retrieves cached content by key and yields it as an IO object.
14
+ # It first checks if the body and content type are present in the cache.
15
+ # If both are found, it creates a StringIO object from the body,
16
+ # extends it with HeaderExtension, sets the content type,
17
+ # and then yields the IO object to the provided block.
18
+ #
19
+ # @param url [ String ] the URL used as a key for caching
20
+ #
21
+ # @yield [ io ] yields the cached IO object if found
8
22
  def get(url, &block)
9
23
  block or raise ArgumentError, 'require block argument'
10
24
  body = @cache[key(:body, url)]
@@ -19,6 +33,13 @@ class OllamaChat::Utils::CacheFetcher
19
33
  end
20
34
  end
21
35
 
36
+ # The put method stores the body and content type of an IO object in the
37
+ # cache using a URL-based key.
38
+ #
39
+ # @param url [ String ] the URL used to generate the cache key
40
+ # @param io [ StringIO, Tempfile ] the IO object containing the body and content type
41
+ #
42
+ # @return [ CacheFetcher ] returns itself to allow for method chaining
22
43
  def put(url, io)
23
44
  io.rewind
24
45
  body = io.read
@@ -32,6 +53,15 @@ class OllamaChat::Utils::CacheFetcher
32
53
 
33
54
  private
34
55
 
56
+ # The key method generates a unique identifier by combining a type prefix
57
+ # with a URL digest.
58
+ # It returns a string that consists of the type, a hyphen, and the MD5 hash
59
+ # of the URL.
60
+ #
61
+ # @param type [ String ] the type prefix for categorizing the key
62
+ # @param url [ String ] the URL to be hashed
63
+ #
64
+ # @return [ String ] a hyphen-separated string of the type and URL's MD5 digest
35
65
  def key(type, url)
36
66
  [ type, Digest::MD5.hexdigest(url) ] * ?-
37
67
  end
@@ -7,10 +7,22 @@ require 'ollama_chat/utils/cache_fetcher'
7
7
 
8
8
  class OllamaChat::Utils::Fetcher
9
9
  module HeaderExtension
10
+ # The content_type method accesses the content type attribute of the object.
11
+ #
12
+ # @return [ String ] the content type of the object.
10
13
  attr_accessor :content_type
11
14
 
15
+ # The ex accessor is used to get or set the expiry value in seconds.
12
16
  attr_accessor :ex
13
17
 
18
+ # The failed method creates a StringIO object with a text/plain content type.
19
+ #
20
+ # This method is used to generate a failed response object that can be used
21
+ # when an operation does not succeed. It initializes a new StringIO object
22
+ # and extends it with the current class, setting its content type to
23
+ # text/plain.
24
+ #
25
+ # @return [ StringIO ] a StringIO object with text/plain content type
14
26
  def self.failed
15
27
  object = StringIO.new.extend(self)
16
28
  object.content_type = MIME::Types['text/plain'].first
@@ -20,6 +32,22 @@ class OllamaChat::Utils::Fetcher
20
32
 
21
33
  class RetryWithoutStreaming < StandardError; end
22
34
 
35
+ # The get method retrieves content from a URL, using caching when available.
36
+ # It processes the URL with optional headers and additional options,
37
+ # then yields a temporary file containing the retrieved content.
38
+ # If caching is enabled and content is found in the cache,
39
+ # it returns the cached result instead of fetching again.
40
+ # The method handles both cached and fresh fetches,
41
+ # ensuring that cache is updated when new content is retrieved.
42
+ #
43
+ # @param url [ String ] the URL to fetch content from
44
+ # @param headers [ Hash ] optional headers to include in the request
45
+ # @param options [ Hash ] additional options for the fetch operation
46
+ #
47
+ # @yield [ tmp ]
48
+ #
49
+ # @return [ Object ] the result of the block execution
50
+ # @return [ nil ] if no block is given or if the fetch fails
23
51
  def self.get(url, headers: {}, **options, &block)
24
52
  cache = options.delete(:cache) and
25
53
  cache = OllamaChat::Utils::CacheFetcher.new(cache)
@@ -38,6 +66,9 @@ class OllamaChat::Utils::Fetcher
38
66
  end
39
67
  end
40
68
 
69
+ # The normalize_url method processes a URL by converting it to a string,
70
+ # decoding any URI components, removing anchors, and then escaping the URL to
71
+ # ensure it is properly formatted.
41
72
  def self.normalize_url(url)
42
73
  url = url.to_s
43
74
  url = URI.decode_uri_component(url)
@@ -45,6 +76,17 @@ class OllamaChat::Utils::Fetcher
45
76
  URI::Parser.new.escape(url).to_s
46
77
  end
47
78
 
79
+ # The read method opens a file and extends it with header extension metadata.
80
+ # It then yields the file to the provided block for processing.
81
+ # If the file does not exist, it outputs an error message to standard error.
82
+ #
83
+ # @param filename [ String ] the path to the file to be read
84
+ #
85
+ # @yield [ file ] yields the opened file with header extension
86
+ #
87
+ # @return [ nil ] returns nil if the file does not exist
88
+ # @return [ Object ] returns the result of the block execution if the file
89
+ # exists
48
90
  def self.read(filename, &block)
49
91
  if File.exist?(filename)
50
92
  File.open(filename) do |file|
@@ -57,6 +99,16 @@ class OllamaChat::Utils::Fetcher
57
99
  end
58
100
  end
59
101
 
102
+ # The execute method runs a shell command and processes its output.
103
+ #
104
+ # It captures the command's standard output and error streams,
105
+ # writes them to a temporary file, and yields the file to the caller.
106
+ # If an exception occurs during execution, it reports the error
107
+ # and yields a failed temporary file instead.
108
+ #
109
+ # @param command [ String ] the shell command to execute
110
+ #
111
+ # @yield [ tmpfile ]
60
112
  def self.execute(command, &block)
61
113
  Tempfile.open do |tmp|
62
114
  unless command =~ /2>&1/
@@ -80,6 +132,11 @@ class OllamaChat::Utils::Fetcher
80
132
  yield HeaderExtension.failed
81
133
  end
82
134
 
135
+ # The initialize method sets up the fetcher instance with debugging and HTTP
136
+ # configuration options.
137
+ #
138
+ # @param debug [ TrueClass, FalseClass ] enables or disables debug output
139
+ # @param http_options [ Hash ] additional options to pass to the HTTP client
83
140
  def initialize(debug: false, http_options: {})
84
141
  @debug = debug
85
142
  @started = false
@@ -89,11 +146,34 @@ class OllamaChat::Utils::Fetcher
89
146
 
90
147
  private
91
148
 
149
+ # The excon method creates a new Excon client instance configured with the
150
+ # specified URL and options.
151
+ #
152
+ # @param url [ String ] the URL to be used for the Excon client
153
+ # @param options [ Hash ] additional options to be merged with http_options
154
+ #
155
+ # @return [ Excon ] a new Excon client instance
156
+ #
157
+ # @see #normalize_url
158
+ # @see #http_options
92
159
  def excon(url, **options)
93
160
  url = self.class.normalize_url(url)
94
161
  Excon.new(url, options.merge(@http_options))
95
162
  end
96
163
 
164
+ # Makes an HTTP GET request to the specified URL with optional headers and
165
+ # processing block.
166
+ #
167
+ # This method handles both streaming and non-streaming HTTP requests, using
168
+ # Excon for the actual HTTP communication. The response body is written to a
169
+ # temporary file which is then decorated with additional behavior before
170
+ # being passed to the provided block.
171
+ #
172
+ # @param url [String] The URL to make the GET request to
173
+ # @param headers [Hash] Optional headers to include in the request (keys will
174
+ # be converted to strings)
175
+ # @yield [Tempfile] The temporary file containing the response body, after
176
+ # decoration
97
177
  def get(url, headers: {}, &block)
98
178
  headers |= self.headers
99
179
  headers = headers.transform_keys(&:to_s)
@@ -130,18 +210,41 @@ class OllamaChat::Utils::Fetcher
130
210
  yield HeaderExtension.failed
131
211
  end
132
212
 
213
+ # The headers method returns a hash containing the default HTTP headers
214
+ # that should be used for requests, including a User-Agent header
215
+ # configured with the application's user agent string.
216
+ #
217
+ # @return [ Hash ] a hash mapping header names to their values
218
+ # @note The returned hash includes the 'User-Agent' header
219
+ # set to OllamaChat::Chat.user_agent.
133
220
  def headers
134
221
  {
135
222
  'User-Agent' => OllamaChat::Chat.user_agent,
136
223
  }
137
224
  end
138
225
 
226
+ # The middlewares method returns the combined array of default Excon
227
+ # middlewares and the RedirectFollower middleware, ensuring there are no
228
+ # duplicates.
229
+ #
230
+ # @return [ Array ] an array of middleware classes including RedirectFollower
231
+ # deduplicated from the default Excon middlewares.
139
232
  def middlewares
140
233
  (Excon.defaults[:middlewares] + [ Excon::Middleware::RedirectFollower ]).uniq
141
234
  end
142
235
 
143
236
  private
144
237
 
238
+ # Decorates a temporary IO object with header information from an HTTP
239
+ # response.
240
+ #
241
+ # This method extends the given temporary IO object with HeaderExtension
242
+ # module and populates it with content type and cache expiration information
243
+ # extracted from the provided response headers.
244
+ #
245
+ # @param tmp [IO] The temporary IO object to decorate (typically a file handle)
246
+ # @param response [Object] HTTP response object containing headers
247
+ # @option response [Hash] :headers HTTP headers hash
145
248
  def decorate_io(tmp, response)
146
249
  tmp.rewind
147
250
  tmp.extend(HeaderExtension)
@@ -156,6 +259,13 @@ class OllamaChat::Utils::Fetcher
156
259
  end
157
260
  end
158
261
 
262
+ # The callback method creates a proc that handles chunked data processing by
263
+ # updating progress information and writing chunks to a temporary file.
264
+ #
265
+ # @param tmp [ Tempfile ] the temporary file to which data chunks are written
266
+ #
267
+ # @return [ Proc ] a proc that accepts chunk, remaining_bytes, and total_bytes
268
+ # parameters for processing streamed data
159
269
  def callback(tmp)
160
270
  -> chunk, remaining_bytes, total_bytes do
161
271
  total = total_bytes or next
@@ -171,6 +281,13 @@ class OllamaChat::Utils::Fetcher
171
281
  end
172
282
  end
173
283
 
284
+ # The message method formats progress information by combining current and
285
+ # total values with unit formatting, along with timing details.
286
+ #
287
+ # @param current [ Integer ] the current progress value
288
+ # @param total [ Integer ] the total progress value
289
+ #
290
+ # @return [ String ] a formatted progress string including units and timing information
174
291
  def message(current, total)
175
292
  progress = '%s/%s' % [ current, total ].map {
176
293
  Tins::Unit.format(_1, format: '%.2f %U')
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.20'
3
+ VERSION = '0.0.21'
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:
@@ -0,0 +1,53 @@
1
+ require 'tempfile'
2
+ require 'pathname'
3
+
4
+ class OllamaChat::Vim
5
+ # Initializes a new Vim server connection
6
+ #
7
+ # Creates a new OllamaChat::Vim instance for interacting with a specific Vim
8
+ # server. If no server name is provided, it defaults to using the current
9
+ # working directory as the server identifier.
10
+ #
11
+ # @param server_name [String, nil] The name of the Vim server to connect to.
12
+ # If nil or empty, defaults to the current working directory path in
13
+ # uppercase
14
+ def initialize(server_name)
15
+ server_name.full? or server_name = default_server_name
16
+ @server_name = server_name
17
+ end
18
+
19
+ # The default server name is derived from the current working directory It
20
+ # converts the absolute path to uppercase for consistent identification This
21
+ # approach ensures each working directory gets a unique server identifier The
22
+ # server name format makes it easy to distinguish different Vim sessions
23
+ def default_server_name
24
+ Pathname.pwd.to_s.upcase
25
+ end
26
+
27
+ # Inserts text at the current cursor position in Vim
28
+ #
29
+ # This method writes the provided text to a temporary file and uses Vim's
30
+ # remote-send functionality to insert it at the current cursor position.
31
+ # The text is automatically indented to match the current column position.
32
+ #
33
+ # @param text [String] The text to be inserted into the Vim buffer
34
+ def insert(text)
35
+ spaces = (col - 1).clamp(0..)
36
+ text = text.gsub(/^/, ' ' * spaces)
37
+ Tempfile.open do |tmp|
38
+ tmp.write(text)
39
+ tmp.flush
40
+ system %{vim --servername "#@server_name" --remote-send "<ESC>:r #{tmp.path}<CR>"}
41
+ end
42
+ end
43
+
44
+ # Returns the current column position of the cursor in the Vim server
45
+ #
46
+ # This method queries the specified Vim server for the current cursor position
47
+ # using Vim's remote expression feature. It executes a Vim command that returns
48
+ # the result of `col('.')`, which represents the current column number (1-indexed)
49
+ # of the cursor position.
50
+ def col
51
+ `vim --servername "#@server_name" --remote-expr "col('.')"`.chomp.to_i
52
+ end
53
+ end
@@ -1,4 +1,16 @@
1
1
  module OllamaChat::WebSearching
2
+ # The search_web method performs a web search using the configured search
3
+ # engine.
4
+ # It appends location information to the query if available and limits the
5
+ # number of results.
6
+ # The method delegates to engine-specific search methods based on the
7
+ # configured search engine.
8
+ #
9
+ # @param query [ String ] the search query string
10
+ # @param n [ Integer ] the maximum number of results to return
11
+ #
12
+ # @return [ Array<String>, nil ] an array of URLs from the search results or
13
+ # nil if the search engine is not implemented
2
14
  def search_web(query, n = nil)
3
15
  l = @messages.at_location.full? and query += " #{l}"
4
16
  n = n.to_i.clamp(1..)
@@ -14,10 +26,22 @@ module OllamaChat::WebSearching
14
26
 
15
27
  private
16
28
 
29
+ # The search_engine method returns the currently configured web search engine
30
+ # to be used for online searches.
31
+ #
32
+ # @return [ String ] the name of the web search engine
33
+ # @see OllamaChat::Config::WebSearch#use
17
34
  def search_engine
18
35
  config.web_search.use
19
36
  end
20
37
 
38
+ # The search_web_with_searxng method performs a web search using the SearxNG
39
+ # engine and returns the URLs of the first n search results.
40
+ #
41
+ # @param query [ String ] the search query string
42
+ # @param n [ Integer ] the number of search results to return
43
+ #
44
+ # @return [ Array<String> ] an array of URLs from the search results
21
45
  def search_web_with_searxng(query, n)
22
46
  url = config.web_search.engines.searxng.url % { query: }
23
47
  OllamaChat::Utils::Fetcher.get(
@@ -30,6 +54,15 @@ module OllamaChat::WebSearching
30
54
  end
31
55
  end
32
56
 
57
+ # The search_web_with_duckduckgo method performs a web search using the
58
+ # DuckDuckGo search engine and extracts URLs from the search results.
59
+ #
60
+ # @param query [ String ] the search query string to be used
61
+ # @param n [ Integer ] the maximum number of URLs to extract from the search
62
+ # results
63
+ #
64
+ # @return [ Array<String> ] an array of URL strings extracted from the search
65
+ # results
33
66
  def search_web_with_duckduckgo(query, n)
34
67
  url = config.web_search.engines.duckduckgo.url % { query: }
35
68
  OllamaChat::Utils::Fetcher.get(
@@ -47,7 +80,8 @@ module OllamaChat::WebSearching
47
80
  url = URI.decode_uri_component(url)
48
81
  url = URI.parse(url)
49
82
  url.host =~ /duckduckgo\.com/ and next
50
- links.add(url.to_s)
83
+ url = url.to_s
84
+ links.add(url)
51
85
  result << url
52
86
  n -= 1
53
87
  else
data/lib/ollama_chat.rb CHANGED
@@ -19,6 +19,7 @@ require 'ollama_chat/dialog'
19
19
  require 'ollama_chat/information'
20
20
  require 'ollama_chat/message_output'
21
21
  require 'ollama_chat/clipboard'
22
+ require 'ollama_chat/vim'
22
23
  require 'ollama_chat/document_cache'
23
24
  require 'ollama_chat/history'
24
25
  require 'ollama_chat/server_socket'
data/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.20 ruby lib
2
+ # stub: ollama_chat 0.0.21 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.20".freeze
6
+ s.version = "0.0.21".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,8 +12,8 @@ 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/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/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/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/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/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/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/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/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/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/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]
@@ -16,6 +16,23 @@
16
16
  "parameter_size": "8.0B",
17
17
  "quantization_level": "Q4_K_M"
18
18
  }
19
+ },
20
+ {
21
+ "name": "qwen3-coder:latest",
22
+ "model": "qwen3-coder:latest",
23
+ "modified_at": "2025-08-08T00:10:43.7235626Z",
24
+ "size": 18556701140,
25
+ "digest": "ad67f85ca2502e92936ef793bf29a312e1912ecd1e2c09c9c2963adf1debde78",
26
+ "details": {
27
+ "parent_model": "",
28
+ "format": "gguf",
29
+ "family": "qwen3moe",
30
+ "families": [
31
+ "qwen3moe"
32
+ ],
33
+ "parameter_size": "30.5B",
34
+ "quantization_level": "Q4_K_M"
35
+ }
19
36
  }
20
37
  ]
21
38
  }