ollama_chat 0.0.108 → 0.0.109

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +54 -0
  3. data/lib/ollama_chat/clipboard.rb +11 -0
  4. data/lib/ollama_chat/commands.rb +27 -8
  5. data/lib/ollama_chat/kramdown_ansi.rb +1 -1
  6. data/lib/ollama_chat/model_handling.rb +116 -0
  7. data/lib/ollama_chat/prompt_handling.rb +9 -9
  8. data/lib/ollama_chat/prompt_management.rb +1 -1
  9. data/lib/ollama_chat/session_management.rb +16 -2
  10. data/lib/ollama_chat/version.rb +1 -1
  11. data/ollama_chat.gemspec +4 -4
  12. data/spec/ollama_chat/commands_spec.rb +24 -0
  13. data/spec/ollama_chat/config_handling_spec.rb +150 -0
  14. data/spec/ollama_chat/conversation_spec.rb +107 -0
  15. data/spec/ollama_chat/favourites_management_spec.rb +143 -0
  16. data/spec/ollama_chat/information_spec.rb +36 -2
  17. data/spec/ollama_chat/model_handling_spec.rb +139 -0
  18. data/spec/ollama_chat/prompt_handling_spec.rb +183 -0
  19. data/spec/ollama_chat/prompt_management_spec.rb +464 -0
  20. data/spec/ollama_chat/rag_handling_spec.rb +498 -0
  21. data/spec/ollama_chat/session_management_spec.rb +4 -4
  22. data/spec/ollama_chat/system_prompt_management_spec.rb +200 -0
  23. data/spec/ollama_chat/think_control_spec.rb +2 -2
  24. data/spec/ollama_chat/tools/execute_ri_spec.rb +2 -2
  25. data/spec/ollama_chat/tools/generate_image_spec.rb +6 -6
  26. data/spec/ollama_chat/tools/get_url_spec.rb +3 -3
  27. data/spec/ollama_chat/tools/move_file_spec.rb +1 -1
  28. data/spec/ollama_chat/tools/patch_file_spec.rb +3 -3
  29. data/spec/ollama_chat/tools/run_tests_spec.rb +3 -3
  30. data/spec/ollama_chat/tools/search_knowledge_spec.rb +5 -5
  31. data/spec/ollama_chat/utils/path_completer_spec.rb +1 -1
  32. data/spec/ollama_chat/utils/png_metadata_extractor_spec.rb +3 -3
  33. data/spec/ollama_chat/web_searching_spec.rb +99 -21
  34. metadata +15 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 857b8cf92f68e5856238c1758cfebe463535ded52de3e4dc591cd83b501ccd63
4
- data.tar.gz: fc90ce1e2145207dc49dfeb6512804dec0e0e3933c943ec0050221b5867bccd1
3
+ metadata.gz: e6c85b95f4c5051b6b0f257dd8f63ee2a3997146c527fd8af251458fee641039
4
+ data.tar.gz: 45a66e25a1a92d8cbd86253a991ad28eeb48d1a8ca68c1f8bbb8df90bbbba37f
5
5
  SHA512:
6
- metadata.gz: 173caf67db6f004400f1f5199e07fcd16acd36c44a531a7d8b5618e5c2fb03f994aa63d03c5e4140d2d443022afd7fccc29d6c17d63f76e2d7085f41b9dd97e9
7
- data.tar.gz: 5addb13b768f52b9ef3f5e3bd532aa632a37e5b5bf7b3c69c64be2d063b0f74ddc41640dd9e19a87d27e570c581e24f5456cf7b3a4d7c1351eba85e6d152e10b
6
+ metadata.gz: a401173a7deb626af01ad8c9adf358259a6ffd7ea292644bb1a5a4553df2f70e9c74bb4ff0807d04914a7aa47e8140e81e0bd46745e33900962d8559950ea914
7
+ data.tar.gz: 6b04fcce611684e73bbe54cdadb01859fc4219f57960604a64c3037b414e56a02c7389a5bfef2341d0a2aa2a44d8a723761469f9c677ec8784c2c9d9e8b6fae0
data/CHANGES.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-08-18 v0.0.109
4
+
5
+ ### Added
6
+
7
+ * Support for exporting and importing model options via the `/model` command:
8
+ * New `export_model_options` method in `model_handling.rb` to export
9
+ stored model profiles to a JSON file.
10
+ * New `import_model_options` method in `model_handling.rb` to import
11
+ profiles from a JSON file, featuring selective model picking, diff
12
+ display, and override confirmation.
13
+ * Extended `/model` command with `options export` and `options import`
14
+ subcommands.
15
+ * `-p` pattern flag for `/model options import` to narrow file search, with a
16
+ fallback to `**/*.json`.
17
+ * `-i` flag for `/paste` command to read input from stdin:
18
+ * New `paste_from_stdin` method in `clipboard.rb`.
19
+ * Updated `/paste` command regex and parsing to support both `-e` and
20
+ `-i` flags.
21
+ * `options` metadata to command definitions for `/copy`, `/paste`, `/toggle`,
22
+ and `/model`.
23
+ * Comprehensive test coverage for previously untested or under-tested
24
+ modules:
25
+ * `spec/ollama_chat/conversation_spec.rb` (9 examples).
26
+ * `spec/ollama_chat/favourites_management_spec.rb` (15 examples).
27
+ * `spec/ollama_chat/rag_handling_spec.rb` covering
28
+ `OllamaChat::RAGHandling`.
29
+ * `spec/ollama_chat/prompt_handling_spec.rb` (19 examples).
30
+ * `spec/ollama_chat/prompt_management_spec.rb` (47 examples).
31
+ * `spec/ollama_chat/system_prompt_management_spec.rb` (20 examples).
32
+ * `spec/ollama_chat/config_handling_spec.rb` (15 examples).
33
+ * `spec/ollama_chat/web_searching_spec.rb` (8 examples).
34
+ * `spec/ollama_chat/information_spec.rb` (5 examples).
35
+
36
+ ### Changed
37
+
38
+ * Refactored session management to extract and reuse
39
+ `set_previous_session_on_change` as a shared private method in
40
+ `lib/ollama_chat/session_management.rb`.
41
+ * `set_new_session`, `duplicate_session`, and `change_session` now
42
+ delegate to this method for consistent `@previous_session_id` handling.
43
+ * Migrated test stubs from `allow` to `expect` across multiple spec files to
44
+ eliminate false-green tests where stubs were never invoked.
45
+ * Normalized `context` and `name` arguments in `prompt_handling.rb` to handle
46
+ `Symbol` inputs safely in SQL queries.
47
+ * Updated `s.files` and `s.test_files` in `ollama_chat.gemspec` to include
48
+ new configuration, asset, and test files.
49
+
50
+ ### Fixed
51
+
52
+ * Infinite retry loop in `kramdown_ansi.rb` by using `retried ||= false` to
53
+ persist the guard across `retry` calls.
54
+ * Incorrect YARD `@return` documentation for `#info_prompt` in
55
+ `prompt_management.rb`.
56
+
3
57
  ## 2026-08-15 v0.0.108
4
58
 
5
59
  ### Added
@@ -143,4 +143,15 @@ module OllamaChat::Clipboard
143
143
  log(:error, e, data: { method: __method__ })
144
144
  STDERR.puts e.message
145
145
  end
146
+
147
+ # Read the full text from STDIN and return it.
148
+ #
149
+ # @param edit [Boolean] If true, the text is passed through
150
+ # {#edit_text} before being returned.
151
+ # @return [String] The raw (or edited) content read from STDIN.
152
+ def paste_from_stdin(edit: false)
153
+ text = STDIN.read
154
+ edit and text = edit_text(text)
155
+ text
156
+ end
146
157
  end
@@ -27,6 +27,7 @@ module OllamaChat::Commands
27
27
  command(
28
28
  name: :copy,
29
29
  regexp: %r(^/copy(\s+-e)?\s*$),
30
+ options: '[-e]',
30
31
  help: <<~EOT
31
32
  📋 Copy the last response to the clipboard.
32
33
  Options: -e to edit before copying.
@@ -39,15 +40,22 @@ module OllamaChat::Commands
39
40
 
40
41
  command(
41
42
  name: :paste,
42
- regexp: %r(^/paste(\s+-e)?\s*$),
43
+ regexp: %r(^/paste(\s+-[ie])*\s*$),
44
+ options: '[-e|-i]',
43
45
  help: <<~EOT
44
- 📋 Paste content from the clipboard.
45
- Options: -e to edit after pasting.
46
+ 📋 Paste content from the clipboard or stdin.
47
+ Options:
48
+ -e Edit after pasting.
49
+ -i Read from stdin instead of clipboard.
46
50
  EOT
47
51
  ) do |opts|
48
52
  disable_content_parsing
49
- opts = go_command('e', opts)
50
- paste_from_clipboard(edit: opts[?e])
53
+ opts = go_command('ie', opts)
54
+ if opts[?i]
55
+ paste_from_stdin(edit: opts[?e])
56
+ else
57
+ paste_from_clipboard(edit: opts[?e])
58
+ end
51
59
  end
52
60
 
53
61
  ## Settings
@@ -88,6 +96,7 @@ module OllamaChat::Commands
88
96
  name: :toggle,
89
97
  regexp: %r(^/toggle(?:\s+(markdown|stream|location|runtime_info|voice|think_loud|think_strip|embedding)(?:\s+(-[yn]))?)?$),
90
98
  complete: [ 'toggle', %w[ markdown stream location runtime_info voice think_loud think_strip embedding ] ],
99
+ options: '[-y|-n]',
91
100
  help: <<~EOT
92
101
  🎛️ Toggle feature switches
93
102
  (markdown, stream, location, runtime_info,
@@ -139,17 +148,21 @@ module OllamaChat::Commands
139
148
 
140
149
  command(
141
150
  name: :model,
142
- regexp: %r(^/model(?:\s+(change|options(?: copy| delete)?|options from session|options to session))?((?:\s+(?:-m))*)$),
143
- complete: [ 'model', %w[ change options options\ copy options\ delete options\ from\ session options\ to\ session ] ],
151
+ regexp: %r(^/model(?:\s+(change|options(?: copy| delete| export| import)?|options from session|options to session))?((?:\s+(?:-m|-p\s+[\S]+))*)$),
152
+ complete: [ 'model', %w[ change options options\ copy options\ delete options\ export options\ import options\ from\ session options\ to\ session ] ],
153
+ options: '[-m|-p pattern]',
144
154
  help: <<~EOT
145
155
  🤖 Manage AI models & profiles:
146
156
  - change: Switch active model
147
157
  - options: Edit saved profile config
148
158
  - options copy: Copy profile from another model
149
159
  - options delete: Delete a saved profile
160
+ - options export: Export ALL model profiles to JSON
161
+ - options import: Selectively import profiles from JSON
150
162
  - options from session: Save live → Saved
151
163
  - options to session: Apply Saved → Live
152
164
  -m interactively choose a model
165
+ -p PATTERN narrow file search for import
153
166
  EOT
154
167
  ) do |subcommand, opts|
155
168
  if subcommand == 'change'
@@ -163,7 +176,7 @@ module OllamaChat::Commands
163
176
  end
164
177
  next :next
165
178
  end
166
- opts = go_command('m', opts)
179
+ opts = go_command('mp:', opts)
167
180
  model = opts[?m] ? choose_model('', @model) : @model
168
181
  case subcommand
169
182
  when 'options'
@@ -179,6 +192,12 @@ module OllamaChat::Commands
179
192
  when 'options to session'
180
193
  profile = choose_profile_for_model(model) || 'default'
181
194
  copy_model_options_to_session(model, profile:)
195
+ when 'options export'
196
+ export_model_options
197
+ when 'options import'
198
+ pattern = opts[?p] || '**/*.json'
199
+ filename = choose_filename(pattern) or next :next
200
+ import_model_options(filename)
182
201
  end
183
202
  :next
184
203
  end
@@ -39,7 +39,7 @@ module OllamaChat::KramdownANSI
39
39
  # @return [ String ] the content formatted with ANSI escape sequences
40
40
  # according to the configured styles
41
41
  def kramdown_ansi_parse(content)
42
- retried = false
42
+ retried ||= false
43
43
  content.nil? and return ''
44
44
  Kramdown::ANSI.parse(content, ansi_styles: @kramdown_ansi_styles)
45
45
  rescue Encoding::UndefinedConversionError
@@ -268,6 +268,122 @@ module OllamaChat::ModelHandling
268
268
  end
269
269
  end
270
270
 
271
+ # Exports all stored model options for every model to a JSON file.
272
+ #
273
+ # The resulting JSON structure is:
274
+ # [
275
+ # { "model_name": "…", "profiles": [ { "profile": "…", "options": {…} } ] },
276
+ # …
277
+ # ]
278
+ #
279
+ # @return [Pathname, nil] the path of the written file, or nil if cancelled
280
+ def export_model_options
281
+ model_names = models::ModelOptions.distinct.map(&:model_name).sort
282
+ unless model_names.any?
283
+ STDERR.puts "❌ No model options stored yet!"
284
+ return
285
+ end
286
+
287
+ payload = model_names.map do |name|
288
+ { model_name: name,
289
+ profiles: models::ModelOptions.where(model_name: name)
290
+ .order(:profile).map { |m|
291
+ { profile: m.profile, options: m.options.to_h }
292
+ } }
293
+ end
294
+
295
+ filename = determine_valid_output_filename('to export model options to') or return
296
+ filename.write(JSON.pretty_generate(payload))
297
+ total = model_names.sum { |n|
298
+ models::ModelOptions.where(model_name: n).count
299
+ }
300
+ log(:info, "Model options exported",
301
+ data: { models: model_names, dest: filename.to_s })
302
+ STDOUT.puts "✅ #{model_names.size} model(s), #{total} profile(s) "\
303
+ "exported to #{filename.to_path.inspect}."
304
+ filename
305
+ end
306
+
307
+ # Imports model options from a JSON file into the database.
308
+ #
309
+ # The JSON file must be an array of entries:
310
+ # [ { "model_name": "…", "profiles": [ … ] }, … ]
311
+ #
312
+ # If multiple models are present, the user selects which to import.
313
+ # For each profile, if an existing record has different options, both
314
+ # are displayed side-by-side and the user decides per-profile.
315
+ #
316
+ # @param filename [String, Pathname] the path to the JSON file to import
317
+ # @return [Boolean, nil] true on success, nil if cancelled
318
+ def import_model_options(filename)
319
+ filename = Pathname.new(filename)
320
+ data = JSON.parse(filename.read)
321
+ unless data.is_a?(Array) && data.all? { |d| d['model_name'] }
322
+ STDERR.puts "❌ Invalid format: expected array of { 'model_name', 'profiles' }!"
323
+ return
324
+ end
325
+
326
+ # Let user pick models if more than one
327
+ if data.size > 1
328
+ options = (['[ALL]'] + data.map { |d| d['model_name'] } + ['[EXIT]'])
329
+ chosen = choose_entry(options, prompt: 'Which model(s) to import? %s')
330
+ case chosen
331
+ when '[EXIT]', nil
332
+ STDOUT.puts "Cancelled."
333
+ return
334
+ when '[ALL]'
335
+ selected = data
336
+ else
337
+ selected = data.select { |d| d['model_name'] == chosen }
338
+ end
339
+ else
340
+ selected = data
341
+ end
342
+
343
+ imported = 0
344
+ selected.each do |entry|
345
+ model_name = entry['model_name']
346
+ profiles = Array(entry['profiles'])
347
+ STDOUT.puts "\n📦 #{bold{model_name}} (#{profiles.size} profile(s))"
348
+
349
+ profiles.each do |profile_data|
350
+ profile = profile_data['profile'] || 'default'
351
+ options = profile_data['options'] || {}
352
+
353
+ existing = stored_model_options_exist?(model_name, profile:)
354
+ if existing
355
+ current = existing.options.to_h.symbolize_keys_recursive
356
+ incoming = options.to_h.symbolize_keys_recursive
357
+ if current == incoming
358
+ STDOUT.puts " • #{italic{profile}}: identical, skipping."
359
+ next
360
+ end
361
+ STDOUT.puts " • #{italic{profile}}: differs!"
362
+ STDOUT.puts " 📤 Current:"
363
+ STDOUT.puts " " + JSON.pretty_generate(current).sub(/^/m, ' ')
364
+ STDOUT.puts " 📥 Incoming:"
365
+ STDOUT.puts " " + JSON.pretty_generate(incoming).sub(/^/m, ' ')
366
+ unless confirm?(prompt: " ⚠️ Overwrite? (y/n) ", yes: /\Ay/i)
367
+ STDOUT.puts " Skipped."
368
+ next
369
+ end
370
+ end
371
+
372
+ store_model_options(model_name, options, profile:)
373
+ imported += 1
374
+ STDOUT.puts " • #{italic{profile}}: ✅"
375
+ end
376
+ end
377
+
378
+ log(:info, "Model options imported",
379
+ data: { models: selected.map { |e| e['model_name'] },
380
+ imported:, source: filename.to_s })
381
+ STDOUT.puts "\n✅ Imported #{imported} profile(s) "\
382
+ "from #{filename.to_path.inspect}."
383
+ true
384
+ end
385
+
386
+
271
387
  # The model_present? method checks if the specified Ollama model is
272
388
  # available.
273
389
  #
@@ -10,7 +10,7 @@ module OllamaChat::PromptHandling
10
10
  # @return [OllamaChat::Database::Models::Prompt, nil] the prompt model
11
11
  # instance or nil if not found
12
12
  def prompt(name, context: nil)
13
- context ||= 'prompt'
13
+ context = (context || 'prompt').to_s
14
14
  models::Prompt.where(context:, name: name.to_s).first
15
15
  end
16
16
 
@@ -19,7 +19,7 @@ module OllamaChat::PromptHandling
19
19
  # @yield [prompt] yields each prompt model instance
20
20
  # @return [Enumerator] an enumerator if no block is given
21
21
  def each_prompt(context: nil, default: nil, &block)
22
- context ||= 'prompt'
22
+ context = (context || 'prompt').to_s
23
23
  block or return enum_for(__method__, context:, default:)
24
24
  prompts = models::Prompt.where(context:)
25
25
  case default
@@ -39,7 +39,7 @@ module OllamaChat::PromptHandling
39
39
  # @param name [String, Symbol] the name of the prompt to delete
40
40
  # @return [Boolean] true if deleted, false otherwise
41
41
  def delete_prompt(name, context: nil)
42
- context ||= 'prompt'
42
+ context = (context || 'prompt').to_s
43
43
  if found = prompt(name, context:) and !found.metadata['default']
44
44
  found.destroy
45
45
  return true
@@ -54,25 +54,25 @@ module OllamaChat::PromptHandling
54
54
  # @return [OllamaChat::Database::Models::Prompt] the saved prompt model
55
55
  # instance
56
56
  def store_prompt(name, content, context: nil)
57
- context ||= 'prompt'
57
+ context = (context || 'prompt').to_s
58
58
  write_prompt(name, content, context:)
59
59
  end
60
60
 
61
61
  # Creates or updates a prompt in the specified context.
62
62
  #
63
- # @param context [String] the context (e.g., 'prompt' or 'system')
64
- # @param name [String] the name of the prompt
63
+ # @param context [String, Symbol] the context (e.g., 'prompt' or 'system')
64
+ # @param name [String, Symbol] the name of the prompt
65
65
  # @param content [String] the content of the prompt
66
66
  # @return [OllamaChat::Database::Models::Prompt] the created or updated
67
67
  # prompt model instance
68
68
  def write_prompt(name, content, context: nil)
69
- context ||= 'prompt'
69
+ context = (context || 'prompt').to_s
70
70
  obj = nil
71
- if found = models::Prompt.where(context:, name:).first
71
+ if found = models::Prompt.where(context:, name: name.to_s).first
72
72
  found.metadata['content'] = content
73
73
  obj = found
74
74
  else
75
- obj = models::Prompt.create(name:, context:)
75
+ obj = models::Prompt.create(name: name.to_s, context:)
76
76
  obj.metadata = { default: false, content: }.stringify_keys_recursive
77
77
  end
78
78
  obj.tap(&:save)
@@ -67,7 +67,7 @@ module OllamaChat::PromptManagement
67
67
 
68
68
  # Displays detailed information about a selected prompt template.
69
69
  #
70
- # @return [self, nil] the current context on success, or nil if cancelled
70
+ # @return [self] the current context
71
71
  def info_prompt(context: nil)
72
72
  context ||= 'prompt'
73
73
  if selected_prompt = choose_prompt(context:, prompt: 'Which blueprint would you like to inspect? %s')
@@ -179,8 +179,9 @@ module OllamaChat::SessionManagement
179
179
  determine_valid_new_name_for_session('to create')
180
180
  end
181
181
  session_close
182
- @previous_session_id = @session.id
182
+ previous_session_id = @session.id
183
183
  @session = new_session
184
+ set_previous_session_on_change(previous_session_id)
184
185
  session.lock? or raise OllamaChat::OllamaChatError,
185
186
  "Could not lock session #{session.id} #{session.errors.full?(:inspect)}"
186
187
  if name.full?
@@ -212,6 +213,7 @@ module OllamaChat::SessionManagement
212
213
  old_session = session
213
214
  old_session.unlock
214
215
  @session = session.duplicate
216
+ set_previous_session_on_change(old_session.id)
215
217
  session.update(name:)
216
218
  session.lock? or raise OllamaChat::OllamaChatError,
217
219
  "Could not lock session #{session.id} #{session.errors.full?(:inspect)}"
@@ -467,10 +469,22 @@ module OllamaChat::SessionManagement
467
469
  end
468
470
  end
469
471
  ensure
472
+ set_previous_session_on_change(previous_session_id)
473
+ session.update(working_directory: Dir.pwd)
474
+ end
475
+
476
+ # Records the previous session ID after a session transition.
477
+ #
478
+ # Stores the ID in `@previous_session_id` so that `#previous_session`
479
+ # can later retrieve it, unless the ID refers to the currently active
480
+ # session (i.e., the user re-selected the same session).
481
+ #
482
+ # @param previous_session_id [Integer, nil] the ID of the session
483
+ # that was active before the transition; `nil` if no transition occurred
484
+ def set_previous_session_on_change(previous_session_id)
470
485
  if previous_session_id && previous_session_id != session.id
471
486
  @previous_session_id = previous_session_id
472
487
  end
473
- session.update(working_directory: Dir.pwd)
474
488
  end
475
489
 
476
490
  # Finds or selects a session based on a name, ID, or pattern.
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.108'
3
+ VERSION = '0.0.109'
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/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.108 ruby lib
2
+ # stub: ollama_chat 0.0.109 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.108".freeze
6
+ s.version = "0.0.109".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,14 +13,14 @@ Gem::Specification.new do |s|
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_chat".freeze, "ollama_chat_send".freeze, "ollama_chat_log".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/command_concern.rb".freeze, "lib/ollama_chat/commands.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/database.rb".freeze, "lib/ollama_chat/database/duplicatable.rb".freeze, "lib/ollama_chat/database/migrations.rb".freeze, "lib/ollama_chat/database/migrations/001_initial_schema.rb".freeze, "lib/ollama_chat/database/migrations/002_add_links_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/003_add_history_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/004_add_profile_to_model_options.rb".freeze, "lib/ollama_chat/database/migrations/005_add_context_format_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/006_rename_system_prompt_context_to_system.rb".freeze, "lib/ollama_chat/database/migrations/007_add_collections_table.rb".freeze, "lib/ollama_chat/database/migrations/008_drop_think_mode_constraint.rb".freeze, "lib/ollama_chat/database/models/collection.rb".freeze, "lib/ollama_chat/database/models/favourite.rb".freeze, "lib/ollama_chat/database/models/model_options.rb".freeze, "lib/ollama_chat/database/models/prompt.rb".freeze, "lib/ollama_chat/database/models/session.rb".freeze, "lib/ollama_chat/database/session_locking.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/favourites_management.rb".freeze, "lib/ollama_chat/file_editing.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/http_handling.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/links_set.rb".freeze, "lib/ollama_chat/location_handling.rb".freeze, "lib/ollama_chat/logging.rb".freeze, "lib/ollama_chat/message.rb".freeze, "lib/ollama_chat/message_editing.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/oc.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/pager.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/personae_management.rb".freeze, "lib/ollama_chat/prompt_handling.rb".freeze, "lib/ollama_chat/prompt_management.rb".freeze, "lib/ollama_chat/rag_handling.rb".freeze, "lib/ollama_chat/redis_cache.rb".freeze, "lib/ollama_chat/say.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/session_management.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/system_prompt_management.rb".freeze, "lib/ollama_chat/think_control.rb".freeze, "lib/ollama_chat/token_estimator.rb".freeze, "lib/ollama_chat/token_estimator/crude.rb".freeze, "lib/ollama_chat/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/browse.rb".freeze, "lib/ollama_chat/tools/compute_bmi.rb".freeze, "lib/ollama_chat/tools/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/delete_file.rb".freeze, "lib/ollama_chat/tools/directory_structure.rb".freeze, "lib/ollama_chat/tools/eval_ruby.rb".freeze, "lib/ollama_chat/tools/execute_grep.rb".freeze, "lib/ollama_chat/tools/execute_ri.rb".freeze, "lib/ollama_chat/tools/file_context.rb".freeze, "lib/ollama_chat/tools/gem_path_lookup.rb".freeze, "lib/ollama_chat/tools/generate_image.rb".freeze, "lib/ollama_chat/tools/generate_password.rb".freeze, "lib/ollama_chat/tools/get_current_weather.rb".freeze, "lib/ollama_chat/tools/get_cve.rb".freeze, "lib/ollama_chat/tools/get_endoflife.rb".freeze, "lib/ollama_chat/tools/get_ghr.rb".freeze, "lib/ollama_chat/tools/get_jira_issue.rb".freeze, "lib/ollama_chat/tools/get_location.rb".freeze, "lib/ollama_chat/tools/get_rfc.rb".freeze, "lib/ollama_chat/tools/get_time.rb".freeze, "lib/ollama_chat/tools/get_url.rb".freeze, "lib/ollama_chat/tools/move_file.rb".freeze, "lib/ollama_chat/tools/open_file_in_editor.rb".freeze, "lib/ollama_chat/tools/paste_from_clipboard.rb".freeze, "lib/ollama_chat/tools/paste_into_editor.rb".freeze, "lib/ollama_chat/tools/patch_file.rb".freeze, "lib/ollama_chat/tools/read_file.rb".freeze, "lib/ollama_chat/tools/resolve_tag.rb".freeze, "lib/ollama_chat/tools/roll_dice.rb".freeze, "lib/ollama_chat/tools/run_tests.rb".freeze, "lib/ollama_chat/tools/search_knowledge.rb".freeze, "lib/ollama_chat/tools/search_web.rb".freeze, "lib/ollama_chat/tools/write_file.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/analyze_directory.rb".freeze, "lib/ollama_chat/utils/backup.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/json_jsonl_io.rb".freeze, "lib/ollama_chat/utils/log_viewer.rb".freeze, "lib/ollama_chat/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/png_metadata_extractor.rb".freeze, "lib/ollama_chat/utils/tag_resolver.rb".freeze, "lib/ollama_chat/utils/utf8_converter.rb".freeze, "lib/ollama_chat/utils/value_formatter.rb".freeze, "lib/ollama_chat/uuid_v7.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, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_log".freeze, "bin/ollama_chat_send".freeze, "config/searxng/settings.yml".freeze, "config/sherlock.md".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/command_concern.rb".freeze, "lib/ollama_chat/commands.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/database.rb".freeze, "lib/ollama_chat/database/duplicatable.rb".freeze, "lib/ollama_chat/database/migrations.rb".freeze, "lib/ollama_chat/database/migrations/001_initial_schema.rb".freeze, "lib/ollama_chat/database/migrations/002_add_links_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/003_add_history_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/004_add_profile_to_model_options.rb".freeze, "lib/ollama_chat/database/migrations/005_add_context_format_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/006_rename_system_prompt_context_to_system.rb".freeze, "lib/ollama_chat/database/migrations/007_add_collections_table.rb".freeze, "lib/ollama_chat/database/migrations/008_drop_think_mode_constraint.rb".freeze, "lib/ollama_chat/database/models/collection.rb".freeze, "lib/ollama_chat/database/models/favourite.rb".freeze, "lib/ollama_chat/database/models/model_options.rb".freeze, "lib/ollama_chat/database/models/prompt.rb".freeze, "lib/ollama_chat/database/models/session.rb".freeze, "lib/ollama_chat/database/session_locking.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/favourites_management.rb".freeze, "lib/ollama_chat/file_editing.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/http_handling.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/links_set.rb".freeze, "lib/ollama_chat/location_handling.rb".freeze, "lib/ollama_chat/logging.rb".freeze, "lib/ollama_chat/message.rb".freeze, "lib/ollama_chat/message_editing.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/oc.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/pager.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/personae_management.rb".freeze, "lib/ollama_chat/prompt_handling.rb".freeze, "lib/ollama_chat/prompt_management.rb".freeze, "lib/ollama_chat/rag_handling.rb".freeze, "lib/ollama_chat/redis_cache.rb".freeze, "lib/ollama_chat/say.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/session_management.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/system_prompt_management.rb".freeze, "lib/ollama_chat/think_control.rb".freeze, "lib/ollama_chat/token_estimator.rb".freeze, "lib/ollama_chat/token_estimator/crude.rb".freeze, "lib/ollama_chat/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/browse.rb".freeze, "lib/ollama_chat/tools/compute_bmi.rb".freeze, "lib/ollama_chat/tools/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/delete_file.rb".freeze, "lib/ollama_chat/tools/directory_structure.rb".freeze, "lib/ollama_chat/tools/eval_ruby.rb".freeze, "lib/ollama_chat/tools/execute_grep.rb".freeze, "lib/ollama_chat/tools/execute_ri.rb".freeze, "lib/ollama_chat/tools/file_context.rb".freeze, "lib/ollama_chat/tools/gem_path_lookup.rb".freeze, "lib/ollama_chat/tools/generate_image.rb".freeze, "lib/ollama_chat/tools/generate_password.rb".freeze, "lib/ollama_chat/tools/get_current_weather.rb".freeze, "lib/ollama_chat/tools/get_cve.rb".freeze, "lib/ollama_chat/tools/get_endoflife.rb".freeze, "lib/ollama_chat/tools/get_ghr.rb".freeze, "lib/ollama_chat/tools/get_jira_issue.rb".freeze, "lib/ollama_chat/tools/get_location.rb".freeze, "lib/ollama_chat/tools/get_rfc.rb".freeze, "lib/ollama_chat/tools/get_time.rb".freeze, "lib/ollama_chat/tools/get_url.rb".freeze, "lib/ollama_chat/tools/move_file.rb".freeze, "lib/ollama_chat/tools/open_file_in_editor.rb".freeze, "lib/ollama_chat/tools/paste_from_clipboard.rb".freeze, "lib/ollama_chat/tools/paste_into_editor.rb".freeze, "lib/ollama_chat/tools/patch_file.rb".freeze, "lib/ollama_chat/tools/read_file.rb".freeze, "lib/ollama_chat/tools/resolve_tag.rb".freeze, "lib/ollama_chat/tools/roll_dice.rb".freeze, "lib/ollama_chat/tools/run_tests.rb".freeze, "lib/ollama_chat/tools/search_knowledge.rb".freeze, "lib/ollama_chat/tools/search_web.rb".freeze, "lib/ollama_chat/tools/write_file.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/analyze_directory.rb".freeze, "lib/ollama_chat/utils/backup.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/json_jsonl_io.rb".freeze, "lib/ollama_chat/utils/log_viewer.rb".freeze, "lib/ollama_chat/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/png_metadata_extractor.rb".freeze, "lib/ollama_chat/utils/tag_resolver.rb".freeze, "lib/ollama_chat/utils/utf8_converter.rb".freeze, "lib/ollama_chat/utils/value_formatter.rb".freeze, "lib/ollama_chat/uuid_v7.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/conversation.jsonl".freeze, "spec/assets/deep/deeper/empty.txt".freeze, "spec/assets/deep/deeper/not-empty.txt".freeze, "spec/assets/deep/empty.txt".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.epub".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/fluffy.png".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/miyu.png".freeze, "spec/assets/pirateweather.json".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/commands_spec.rb".freeze, "spec/ollama_chat/database/models/favourite_spec.rb".freeze, "spec/ollama_chat/file_editing_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/history_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_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/session_management_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_spec.rb".freeze, "spec/ollama_chat/token_estimator_spec.rb".freeze, "spec/ollama_chat/tool_calling_spec.rb".freeze, "spec/ollama_chat/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/compute_bmi_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/delete_file_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/execute_grep_spec.rb".freeze, "spec/ollama_chat/tools/execute_ri_spec.rb".freeze, "spec/ollama_chat/tools/file_context_spec.rb".freeze, "spec/ollama_chat/tools/gem_path_lookup_spec.rb".freeze, "spec/ollama_chat/tools/generate_image_spec.rb".freeze, "spec/ollama_chat/tools/generate_password_spec.rb".freeze, "spec/ollama_chat/tools/get_current_weather_spec.rb".freeze, "spec/ollama_chat/tools/get_cve_spec.rb".freeze, "spec/ollama_chat/tools/get_endoflife_spec.rb".freeze, "spec/ollama_chat/tools/get_ghr_spec.rb".freeze, "spec/ollama_chat/tools/get_jira_issue_spec.rb".freeze, "spec/ollama_chat/tools/get_location_spec.rb".freeze, "spec/ollama_chat/tools/get_rfc_spec.rb".freeze, "spec/ollama_chat/tools/get_time_spec.rb".freeze, "spec/ollama_chat/tools/get_url_spec.rb".freeze, "spec/ollama_chat/tools/move_file_spec.rb".freeze, "spec/ollama_chat/tools/open_file_in_editor_spec.rb".freeze, "spec/ollama_chat/tools/paste_from_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/paste_into_editor_spec.rb".freeze, "spec/ollama_chat/tools/patch_file_spec.rb".freeze, "spec/ollama_chat/tools/read_file_spec.rb".freeze, "spec/ollama_chat/tools/resolve_tag_spec.rb".freeze, "spec/ollama_chat/tools/roll_dice_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_spec.rb".freeze, "spec/ollama_chat/tools/search_knowledge_spec.rb".freeze, "spec/ollama_chat/tools/search_web_spec.rb".freeze, "spec/ollama_chat/tools/write_file_spec.rb".freeze, "spec/ollama_chat/utils/analyze_directory_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/log_viewer_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_spec.rb".freeze, "spec/ollama_chat/utils/png_metadata_extractor_spec.rb".freeze, "spec/ollama_chat/vim_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
16
+ s.files = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_log".freeze, "bin/ollama_chat_send".freeze, "config/searxng/settings.yml".freeze, "config/sherlock.md".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/command_concern.rb".freeze, "lib/ollama_chat/commands.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/database.rb".freeze, "lib/ollama_chat/database/duplicatable.rb".freeze, "lib/ollama_chat/database/migrations.rb".freeze, "lib/ollama_chat/database/migrations/001_initial_schema.rb".freeze, "lib/ollama_chat/database/migrations/002_add_links_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/003_add_history_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/004_add_profile_to_model_options.rb".freeze, "lib/ollama_chat/database/migrations/005_add_context_format_to_sessions.rb".freeze, "lib/ollama_chat/database/migrations/006_rename_system_prompt_context_to_system.rb".freeze, "lib/ollama_chat/database/migrations/007_add_collections_table.rb".freeze, "lib/ollama_chat/database/migrations/008_drop_think_mode_constraint.rb".freeze, "lib/ollama_chat/database/models/collection.rb".freeze, "lib/ollama_chat/database/models/favourite.rb".freeze, "lib/ollama_chat/database/models/model_options.rb".freeze, "lib/ollama_chat/database/models/prompt.rb".freeze, "lib/ollama_chat/database/models/session.rb".freeze, "lib/ollama_chat/database/session_locking.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/favourites_management.rb".freeze, "lib/ollama_chat/file_editing.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/http_handling.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/links_set.rb".freeze, "lib/ollama_chat/location_handling.rb".freeze, "lib/ollama_chat/logging.rb".freeze, "lib/ollama_chat/message.rb".freeze, "lib/ollama_chat/message_editing.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/oc.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/pager.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/personae_management.rb".freeze, "lib/ollama_chat/prompt_handling.rb".freeze, "lib/ollama_chat/prompt_management.rb".freeze, "lib/ollama_chat/rag_handling.rb".freeze, "lib/ollama_chat/redis_cache.rb".freeze, "lib/ollama_chat/say.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/session_management.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/system_prompt_management.rb".freeze, "lib/ollama_chat/think_control.rb".freeze, "lib/ollama_chat/token_estimator.rb".freeze, "lib/ollama_chat/token_estimator/crude.rb".freeze, "lib/ollama_chat/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/browse.rb".freeze, "lib/ollama_chat/tools/compute_bmi.rb".freeze, "lib/ollama_chat/tools/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/delete_file.rb".freeze, "lib/ollama_chat/tools/directory_structure.rb".freeze, "lib/ollama_chat/tools/eval_ruby.rb".freeze, "lib/ollama_chat/tools/execute_grep.rb".freeze, "lib/ollama_chat/tools/execute_ri.rb".freeze, "lib/ollama_chat/tools/file_context.rb".freeze, "lib/ollama_chat/tools/gem_path_lookup.rb".freeze, "lib/ollama_chat/tools/generate_image.rb".freeze, "lib/ollama_chat/tools/generate_password.rb".freeze, "lib/ollama_chat/tools/get_current_weather.rb".freeze, "lib/ollama_chat/tools/get_cve.rb".freeze, "lib/ollama_chat/tools/get_endoflife.rb".freeze, "lib/ollama_chat/tools/get_ghr.rb".freeze, "lib/ollama_chat/tools/get_jira_issue.rb".freeze, "lib/ollama_chat/tools/get_location.rb".freeze, "lib/ollama_chat/tools/get_rfc.rb".freeze, "lib/ollama_chat/tools/get_time.rb".freeze, "lib/ollama_chat/tools/get_url.rb".freeze, "lib/ollama_chat/tools/move_file.rb".freeze, "lib/ollama_chat/tools/open_file_in_editor.rb".freeze, "lib/ollama_chat/tools/paste_from_clipboard.rb".freeze, "lib/ollama_chat/tools/paste_into_editor.rb".freeze, "lib/ollama_chat/tools/patch_file.rb".freeze, "lib/ollama_chat/tools/read_file.rb".freeze, "lib/ollama_chat/tools/resolve_tag.rb".freeze, "lib/ollama_chat/tools/roll_dice.rb".freeze, "lib/ollama_chat/tools/run_tests.rb".freeze, "lib/ollama_chat/tools/search_knowledge.rb".freeze, "lib/ollama_chat/tools/search_web.rb".freeze, "lib/ollama_chat/tools/write_file.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/analyze_directory.rb".freeze, "lib/ollama_chat/utils/backup.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/json_jsonl_io.rb".freeze, "lib/ollama_chat/utils/log_viewer.rb".freeze, "lib/ollama_chat/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/png_metadata_extractor.rb".freeze, "lib/ollama_chat/utils/tag_resolver.rb".freeze, "lib/ollama_chat/utils/utf8_converter.rb".freeze, "lib/ollama_chat/utils/value_formatter.rb".freeze, "lib/ollama_chat/uuid_v7.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/conversation.jsonl".freeze, "spec/assets/deep/deeper/empty.txt".freeze, "spec/assets/deep/deeper/not-empty.txt".freeze, "spec/assets/deep/empty.txt".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.epub".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/fluffy.png".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/miyu.png".freeze, "spec/assets/pirateweather.json".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/commands_spec.rb".freeze, "spec/ollama_chat/config_handling_spec.rb".freeze, "spec/ollama_chat/conversation_spec.rb".freeze, "spec/ollama_chat/database/models/favourite_spec.rb".freeze, "spec/ollama_chat/favourites_management_spec.rb".freeze, "spec/ollama_chat/file_editing_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/history_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_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/prompt_handling_spec.rb".freeze, "spec/ollama_chat/prompt_management_spec.rb".freeze, "spec/ollama_chat/rag_handling_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/session_management_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/system_prompt_management_spec.rb".freeze, "spec/ollama_chat/think_control_spec.rb".freeze, "spec/ollama_chat/token_estimator_spec.rb".freeze, "spec/ollama_chat/tool_calling_spec.rb".freeze, "spec/ollama_chat/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/compute_bmi_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/delete_file_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/execute_grep_spec.rb".freeze, "spec/ollama_chat/tools/execute_ri_spec.rb".freeze, "spec/ollama_chat/tools/file_context_spec.rb".freeze, "spec/ollama_chat/tools/gem_path_lookup_spec.rb".freeze, "spec/ollama_chat/tools/generate_image_spec.rb".freeze, "spec/ollama_chat/tools/generate_password_spec.rb".freeze, "spec/ollama_chat/tools/get_current_weather_spec.rb".freeze, "spec/ollama_chat/tools/get_cve_spec.rb".freeze, "spec/ollama_chat/tools/get_endoflife_spec.rb".freeze, "spec/ollama_chat/tools/get_ghr_spec.rb".freeze, "spec/ollama_chat/tools/get_jira_issue_spec.rb".freeze, "spec/ollama_chat/tools/get_location_spec.rb".freeze, "spec/ollama_chat/tools/get_rfc_spec.rb".freeze, "spec/ollama_chat/tools/get_time_spec.rb".freeze, "spec/ollama_chat/tools/get_url_spec.rb".freeze, "spec/ollama_chat/tools/move_file_spec.rb".freeze, "spec/ollama_chat/tools/open_file_in_editor_spec.rb".freeze, "spec/ollama_chat/tools/paste_from_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/paste_into_editor_spec.rb".freeze, "spec/ollama_chat/tools/patch_file_spec.rb".freeze, "spec/ollama_chat/tools/read_file_spec.rb".freeze, "spec/ollama_chat/tools/resolve_tag_spec.rb".freeze, "spec/ollama_chat/tools/roll_dice_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_spec.rb".freeze, "spec/ollama_chat/tools/search_knowledge_spec.rb".freeze, "spec/ollama_chat/tools/search_web_spec.rb".freeze, "spec/ollama_chat/tools/write_file_spec.rb".freeze, "spec/ollama_chat/utils/analyze_directory_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/log_viewer_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_spec.rb".freeze, "spec/ollama_chat/utils/png_metadata_extractor_spec.rb".freeze, "spec/ollama_chat/vim_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.17".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/commands_spec.rb".freeze, "spec/ollama_chat/database/models/favourite_spec.rb".freeze, "spec/ollama_chat/file_editing_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/history_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_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/session_management_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_spec.rb".freeze, "spec/ollama_chat/token_estimator_spec.rb".freeze, "spec/ollama_chat/tool_calling_spec.rb".freeze, "spec/ollama_chat/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/compute_bmi_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/delete_file_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/execute_grep_spec.rb".freeze, "spec/ollama_chat/tools/execute_ri_spec.rb".freeze, "spec/ollama_chat/tools/file_context_spec.rb".freeze, "spec/ollama_chat/tools/gem_path_lookup_spec.rb".freeze, "spec/ollama_chat/tools/generate_image_spec.rb".freeze, "spec/ollama_chat/tools/generate_password_spec.rb".freeze, "spec/ollama_chat/tools/get_current_weather_spec.rb".freeze, "spec/ollama_chat/tools/get_cve_spec.rb".freeze, "spec/ollama_chat/tools/get_endoflife_spec.rb".freeze, "spec/ollama_chat/tools/get_ghr_spec.rb".freeze, "spec/ollama_chat/tools/get_jira_issue_spec.rb".freeze, "spec/ollama_chat/tools/get_location_spec.rb".freeze, "spec/ollama_chat/tools/get_rfc_spec.rb".freeze, "spec/ollama_chat/tools/get_time_spec.rb".freeze, "spec/ollama_chat/tools/get_url_spec.rb".freeze, "spec/ollama_chat/tools/move_file_spec.rb".freeze, "spec/ollama_chat/tools/open_file_in_editor_spec.rb".freeze, "spec/ollama_chat/tools/paste_from_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/paste_into_editor_spec.rb".freeze, "spec/ollama_chat/tools/patch_file_spec.rb".freeze, "spec/ollama_chat/tools/read_file_spec.rb".freeze, "spec/ollama_chat/tools/resolve_tag_spec.rb".freeze, "spec/ollama_chat/tools/roll_dice_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_spec.rb".freeze, "spec/ollama_chat/tools/search_knowledge_spec.rb".freeze, "spec/ollama_chat/tools/search_web_spec.rb".freeze, "spec/ollama_chat/tools/write_file_spec.rb".freeze, "spec/ollama_chat/utils/analyze_directory_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/log_viewer_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_spec.rb".freeze, "spec/ollama_chat/utils/png_metadata_extractor_spec.rb".freeze, "spec/ollama_chat/vim_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/commands_spec.rb".freeze, "spec/ollama_chat/config_handling_spec.rb".freeze, "spec/ollama_chat/conversation_spec.rb".freeze, "spec/ollama_chat/database/models/favourite_spec.rb".freeze, "spec/ollama_chat/favourites_management_spec.rb".freeze, "spec/ollama_chat/file_editing_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/history_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_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/prompt_handling_spec.rb".freeze, "spec/ollama_chat/prompt_management_spec.rb".freeze, "spec/ollama_chat/rag_handling_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/session_management_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/system_prompt_management_spec.rb".freeze, "spec/ollama_chat/think_control_spec.rb".freeze, "spec/ollama_chat/token_estimator_spec.rb".freeze, "spec/ollama_chat/tool_calling_spec.rb".freeze, "spec/ollama_chat/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/compute_bmi_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/delete_file_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/execute_grep_spec.rb".freeze, "spec/ollama_chat/tools/execute_ri_spec.rb".freeze, "spec/ollama_chat/tools/file_context_spec.rb".freeze, "spec/ollama_chat/tools/gem_path_lookup_spec.rb".freeze, "spec/ollama_chat/tools/generate_image_spec.rb".freeze, "spec/ollama_chat/tools/generate_password_spec.rb".freeze, "spec/ollama_chat/tools/get_current_weather_spec.rb".freeze, "spec/ollama_chat/tools/get_cve_spec.rb".freeze, "spec/ollama_chat/tools/get_endoflife_spec.rb".freeze, "spec/ollama_chat/tools/get_ghr_spec.rb".freeze, "spec/ollama_chat/tools/get_jira_issue_spec.rb".freeze, "spec/ollama_chat/tools/get_location_spec.rb".freeze, "spec/ollama_chat/tools/get_rfc_spec.rb".freeze, "spec/ollama_chat/tools/get_time_spec.rb".freeze, "spec/ollama_chat/tools/get_url_spec.rb".freeze, "spec/ollama_chat/tools/move_file_spec.rb".freeze, "spec/ollama_chat/tools/open_file_in_editor_spec.rb".freeze, "spec/ollama_chat/tools/paste_from_clipboard_spec.rb".freeze, "spec/ollama_chat/tools/paste_into_editor_spec.rb".freeze, "spec/ollama_chat/tools/patch_file_spec.rb".freeze, "spec/ollama_chat/tools/read_file_spec.rb".freeze, "spec/ollama_chat/tools/resolve_tag_spec.rb".freeze, "spec/ollama_chat/tools/roll_dice_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_spec.rb".freeze, "spec/ollama_chat/tools/search_knowledge_spec.rb".freeze, "spec/ollama_chat/tools/search_web_spec.rb".freeze, "spec/ollama_chat/tools/write_file_spec.rb".freeze, "spec/ollama_chat/utils/analyze_directory_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/log_viewer_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_spec.rb".freeze, "spec/ollama_chat/utils/png_metadata_extractor_spec.rb".freeze, "spec/ollama_chat/vim_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
 
@@ -244,6 +244,30 @@ describe OllamaChat::Commands, protect_env: true do
244
244
  expect(chat).to receive(:copy_model_options_profile).with('codellama')
245
245
  expect(chat.handle_input("/model options copy -m")).to eq :next
246
246
  end
247
+
248
+ it 'returns :next when input is "/model options export"' do
249
+ expect(chat).to receive(:export_model_options)
250
+ expect(chat.handle_input("/model options export")).to eq :next
251
+ end
252
+
253
+ it 'returns :next when input is "/model options import"' do
254
+ filename = Pathname.new('tmp/test.json')
255
+ expect(chat).to receive(:choose_filename).with('**/*.json').and_return filename
256
+ expect(chat).to receive(:import_model_options).with(filename)
257
+ expect(chat.handle_input("/model options import")).to eq :next
258
+ end
259
+
260
+ it 'returns :next when input is "/model options import" with cancel' do
261
+ expect(chat).to receive(:choose_filename).with('**/*.json').and_return nil
262
+ expect(chat.handle_input("/model options import")).to eq :next
263
+ end
264
+
265
+ it 'returns :next when input is "/model options import -p /foo/**/*.json"' do
266
+ filename = Pathname.new('/foo/bar.json')
267
+ expect(chat).to receive(:choose_filename).with('/foo/**/*.json').and_return filename
268
+ expect(chat).to receive(:import_model_options).with(filename)
269
+ expect(chat.handle_input("/model options import -p /foo/**/*.json")).to eq :next
270
+ end
247
271
  end
248
272
 
249
273
  describe '/session model options change' do