ollama_chat 0.0.83 β†’ 0.0.84

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +22 -0
  3. data/lib/ollama_chat/chat.rb +5 -36
  4. data/lib/ollama_chat/config_handling.rb +3 -3
  5. data/lib/ollama_chat/conversation.rb +6 -3
  6. data/lib/ollama_chat/dialog.rb +29 -5
  7. data/lib/ollama_chat/follow_chat.rb +35 -14
  8. data/lib/ollama_chat/message_output.rb +2 -2
  9. data/lib/ollama_chat/model_handling.rb +1 -1
  10. data/lib/ollama_chat/ollama_chat_config/default_config.yml +2 -0
  11. data/lib/ollama_chat/personae_management.rb +2 -2
  12. data/lib/ollama_chat/server_socket.rb +1 -1
  13. data/lib/ollama_chat/switches.rb +1 -1
  14. data/lib/ollama_chat/tools/browse.rb +11 -4
  15. data/lib/ollama_chat/tools/concern.rb +1 -0
  16. data/lib/ollama_chat/tools/copy_to_clipboard.rb +2 -2
  17. data/lib/ollama_chat/tools/open_file_in_editor.rb +7 -6
  18. data/lib/ollama_chat/tools/paste_from_clipboard.rb +3 -2
  19. data/lib/ollama_chat/tools/paste_into_editor.rb +1 -1
  20. data/lib/ollama_chat/tools/patch_file.rb +5 -3
  21. data/lib/ollama_chat/tools/resolve_tag.rb +8 -3
  22. data/lib/ollama_chat/tools/retrieve_document_snippets.rb +118 -0
  23. data/lib/ollama_chat/tools/search_web.rb +10 -3
  24. data/lib/ollama_chat/tools/write_file.rb +10 -3
  25. data/lib/ollama_chat/tools.rb +1 -0
  26. data/lib/ollama_chat/utils/value_formatter.rb +10 -0
  27. data/lib/ollama_chat/utils.rb +3 -2
  28. data/lib/ollama_chat/version.rb +1 -1
  29. data/ollama_chat.gemspec +5 -5
  30. data/spec/ollama_chat/tools/browse_spec.rb +9 -3
  31. data/spec/ollama_chat/tools/open_file_in_editor_spec.rb +2 -0
  32. data/spec/ollama_chat/tools/paste_from_clipboard_spec.rb +3 -2
  33. data/spec/ollama_chat/tools/resolve_tag_spec.rb +1 -1
  34. data/spec/ollama_chat/tools/retrieve_document_snippets_spec.rb +66 -0
  35. data/spec/ollama_chat/tools/search_web_spec.rb +10 -6
  36. metadata +7 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8947d6cdb437ce85afb32cb689bad1b16de54c2afb35da9f0eac7b1f1fff19df
4
- data.tar.gz: 3a03448c69d3f8883e11d5de11e9f44c455a4a8e95e2d93593d945dc99a0be63
3
+ metadata.gz: f2439d1523f092997e86300083d46a0db7efcc3e2e6d4253c828ae83ae417043
4
+ data.tar.gz: 3e946c28dc28d5b6eacd948437dbede5f7160cdad4dca205d2b9fc7f57a0f5fe
5
5
  SHA512:
6
- metadata.gz: 02e28130adb2881c44ea053035b5b39eb43025bf0e761063e6442a031b8b8acd88fe588850438ff0ae3c9fcf039ca4cff32bcb5abae4bcca4a349852a217580b
7
- data.tar.gz: 1055061e111fff2384020505b467b60ab30facc7fbf5733856061adc6834401a5414ba28a6716452b5b5fe2bb8ec5a77d54fc81d2e3ed065f0b9568847ce326c
6
+ metadata.gz: 8e06a5f8362fe5760eb063eb810041449d1faeec408e40c6d806621814f148818e06e1799452c0357add7d723c512c52bc04aab768166bf8c73e8fa923ebc6d1
7
+ data.tar.gz: 6194047eb8d4f3ef45b62df2d307e7f498e29b08566ea2061a73813ef1753a5554e41427f212b7381bd093b50806529ac2da255f02f35d0667dc62892984424f
data/CHANGES.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-03-26 v0.0.84
4
+
5
+ - Added `OllamaChat::Utils::ValueFormatter` with helper `format_bytes` in
6
+ `lib/ollama_chat/utils/value_formatter.rb`.
7
+ - Added `require 'ollama_chat/utils/value_formatter'` where needed.
8
+ - Updated `write_file`, `patch_file`, `paste_from_clipboard` to use
9
+ `format_bytes` for byte‑size messages.
10
+ - Implemented new tool `RetrieveDocumentSnippets` in
11
+ `lib/ollama_chat/tools/retrieve_document_snippets.rb` and its spec
12
+ `spec/ollama_chat/tools/retrieve_document_snippets_spec.rb`.
13
+ - Updated `default_config.yml` to enable `retrieve_document_snippets` by
14
+ default.
15
+ - Rewrote tool payloads to include a `message` key for `browse`, `search_web`,
16
+ `paste_from_clipboard`, `resolve_tag`, and others.
17
+ - `browse` now returns `"Opened \"<url>\" in browser."` or a failure message.
18
+ - Refactored `confirm?` in `lib/ollama_chat/dialog.rb` to accept keyword `yes:`
19
+ for a confirmation regex and display a coloured emoji matching the response
20
+ or timeout/default.
21
+ - Updated all calls to `confirm?` to use `yes: /y/i` syntax.
22
+ - Updated `lib/ollama_chat/message_output.rb` to add `yes:` keyword to
23
+ `confirm?` calls and refine the emoji shown when a file already exists.
24
+
3
25
  ## 2026-03-24 v0.0.83
4
26
 
5
27
  - Added timeout support to `Dialog#confirm?`: introduced optional `timeout:`
@@ -61,6 +61,7 @@ class OllamaChat::Chat
61
61
  include OllamaChat::ToolCalling
62
62
  include OllamaChat::ConfigHandling
63
63
  include OllamaChat::PersonaeManagement
64
+ include OllamaChat::Utils::ValueFormatter
64
65
 
65
66
  # Initializes a new OllamaChat::Chat instance with the given command-line
66
67
  # arguments.
@@ -492,7 +493,7 @@ class OllamaChat::Chat
492
493
  STDOUT.puts "Exiting chooser."
493
494
  break
494
495
  when '[ALL]'
495
- if confirm?(prompt: 'πŸ”” Are you sure? (y/n) ') =~ /y/i
496
+ if confirm?(prompt: 'πŸ”” Are you sure? (y/n) ', yes: /y/i)
496
497
  @documents.clear
497
498
  STDOUT.puts "Cleared collection #{bold{@documents.collection}}."
498
499
  break
@@ -537,7 +538,7 @@ class OllamaChat::Chat
537
538
  end
538
539
  when 'edit'
539
540
  if result = edit_persona and
540
- confirm?(prompt: 'πŸ”” Load new persona profile? (y/n) ') =~ /y/i
541
+ confirm?(prompt: 'πŸ”” Load new persona profile? (y/n) ', yes: /y/i)
541
542
  then
542
543
  result
543
544
  else
@@ -868,7 +869,7 @@ class OllamaChat::Chat
868
869
  STDOUT.puts "Exiting chooser."
869
870
  break
870
871
  when '[ALL]'
871
- if confirm?(prompt: 'πŸ”” Are you sure? (y/n) ') =~ /y/i
872
+ if confirm?(prompt: 'πŸ”” Are you sure? (y/n) ', yes: /y/i)
872
873
  links.clear
873
874
  STDOUT.puts "Cleared all links in list."
874
875
  break
@@ -916,7 +917,7 @@ class OllamaChat::Chat
916
917
  @documents.clear
917
918
  STDOUT.puts "Cleared all tags."
918
919
  when 'all'
919
- if confirm?(prompt: 'πŸ”” Are you sure to clear messages and collection? (y/n) ') =~ /y/i
920
+ if confirm?(prompt: 'πŸ”” Are you sure to clear messages and collection? (y/n) ', yes: /y/i)
920
921
  messages.clear
921
922
  @documents.clear
922
923
  links.clear
@@ -1000,27 +1001,6 @@ class OllamaChat::Chat
1000
1001
  [ content, Documentrix::Utils::Tags.new(valid_tag: /\A#*([\w\]\[]+)/) ]
1001
1002
  end
1002
1003
 
1003
- if embedding.on? && content
1004
- records = @documents.find_where(
1005
- content.downcase.first(config.embedding.model.context_length),
1006
- tags:,
1007
- prompt: config.embedding.model.prompt?,
1008
- text_size: config.embedding.found_texts_size?,
1009
- text_count: config.embedding.found_texts_count?,
1010
- )
1011
- unless records.empty?
1012
- content << ?\n << JSON(
1013
- prompt: "Consider these snippets generated from retrieval when formulating your response!",
1014
- ollama_chat_retrieval_snippets: records.map { |r|
1015
- {
1016
- text: r.text,
1017
- tags: r.tags_set.map { |t| { name: t.to_s(link: false), source: t.source }.compact }
1018
- }
1019
- },
1020
- )
1021
- end
1022
- end
1023
-
1024
1004
  runtime_info.on? && content and
1025
1005
  content << ?\n << {
1026
1006
  ollama_chat_runtime_information: runtime_information
@@ -1056,17 +1036,6 @@ class OllamaChat::Chat
1056
1036
  raise
1057
1037
  end
1058
1038
  end
1059
- if embedding.on? && !records.empty?
1060
- STDOUT.puts "", records.map { |record|
1061
- link = if record.source =~ %r(\Ahttps?://)
1062
- record.source
1063
- else
1064
- 'file://%s' % File.expand_path(record.source)
1065
- end
1066
- [ link, ?# + record.tags.first ]
1067
- }.uniq.map { |l, t| hyperlink(l, t) }.join(' ')
1068
- debug and jj messages.to_ary
1069
- end
1070
1039
 
1071
1040
  case type
1072
1041
  when :socket_input
@@ -58,7 +58,7 @@ module OllamaChat::ConfigHandling
58
58
  unless diff_tool = OC::DIFF_TOOL?
59
59
  exit 1
60
60
  end
61
- if confirm?(prompt: 'πŸ”” Do you want to fix the config? (y/n) ') =~ /y/i
61
+ if confirm?(prompt: 'πŸ”” Do you want to fix the config? (y/n) ', yes: /y/i)
62
62
  system Shellwords.join([
63
63
  diff_tool,
64
64
  @ollama_chat_config.filename,
@@ -84,7 +84,7 @@ module OllamaChat::ConfigHandling
84
84
  # `ollama_chat` if desired.
85
85
  def edit_config
86
86
  if result = edit_file(@ollama_chat_config.filename)
87
- if confirm?(prompt: "πŸ”” Do you want to restart #{progname}? (y/n) ") =~ /y/i
87
+ if confirm?(prompt: "πŸ”” Do you want to restart #{progname}? (y/n) ", yes: /y/i)
88
88
  save_conversation(OC::XDG_CACHE_HOME + 'backup.json')
89
89
  save_history
90
90
  exec($0, *ARGV)
@@ -101,7 +101,7 @@ module OllamaChat::ConfigHandling
101
101
  # @example Restarting the app after confirmation
102
102
  # config.reload_config # => restarts if user answers "y"
103
103
  def reload_config
104
- if confirm?(prompt: "πŸ”” Do you want to restart #{progname}? (y/n) ") =~ /y/i
104
+ if confirm?(prompt: "πŸ”” Do you want to restart #{progname}? (y/n) ", yes: /y/i)
105
105
  save_conversation(OC::XDG_CACHE_HOME + 'backup.json')
106
106
  save_history
107
107
  exec($0, *ARGV)
@@ -26,9 +26,12 @@ module OllamaChat::Conversation
26
26
  # @example Save conversation with explicit filename
27
27
  # chat.save_conversation('conversations/2023-10-15_my_session.json')
28
28
  def save_conversation(filename)
29
- File.exist?(filename) &&
30
- confirm?(prompt: "πŸ”” File #{filename.to_s.inspect} already exists, overwrite? (y/n) ") !~ /y/i and
31
- return
29
+ if File.exist?(filename)
30
+ confirm?(
31
+ prompt: "πŸ”” File #{filename.to_s.inspect} already exists, overwrite? (y/n) ",
32
+ yes: /y/i
33
+ ) or return
34
+ end
32
35
  if messages.save_conversation(filename)
33
36
  STDOUT.puts "Saved conversation to #{filename.to_s.inspect}."
34
37
  else
@@ -36,22 +36,46 @@ module OllamaChat::Dialog
36
36
  #
37
37
  # @return [Object] the character entered by the user, or the `default` value
38
38
  # if a timeout occurs
39
- def confirm?(prompt:, timeout: nil, default: nil)
39
+ def confirm?(prompt:, timeout: nil, default: nil, yes: nil)
40
40
  return default if timeout&.zero?
41
41
  if prompt.include?('%s')
42
42
  prompt = prompt % (timeout ? ('timeout in %us' % timeout) : 'no timeout')
43
43
  end
44
44
  print prompt
45
45
  system 'stty raw'
46
+ keypress = nil
46
47
  c = if timeout
47
- ready = IO.select([ STDIN ], nil, nil, timeout)
48
- ready ? STDIN.getc : nil
48
+ keypress = !!IO.select([ STDIN ], nil, nil, timeout)
49
+ keypress ? STDIN.getc : nil
49
50
  else
51
+ keypress = true
50
52
  STDIN.getc
51
53
  end
52
54
  system 'stty cooked'
53
- puts
54
- c || default
55
+ answer = c || default
56
+ case
57
+ when yes.nil?
58
+ if keypress
59
+ puts "⌨️ #{answer}"
60
+ else
61
+ puts "βŒ›οΈ #{answer}"
62
+ end
63
+ answer
64
+ when answer =~ yes
65
+ if keypress
66
+ puts "βœ… #{answer}"
67
+ else
68
+ puts "β˜‘οΈ #{answer}"
69
+ end
70
+ answer
71
+ else
72
+ if keypress
73
+ puts "🚫 #{answer}"
74
+ else
75
+ puts "βŒ›οΈ #{answer}"
76
+ end
77
+ nil
78
+ end
55
79
  end
56
80
 
57
81
  private
@@ -11,6 +11,7 @@ class OllamaChat::FollowChat
11
11
  include Ollama::Handlers::Concern
12
12
  include Term::ANSIColor
13
13
  include OllamaChat::MessageFormat
14
+ include OllamaChat::Utils::ValueFormatter
14
15
 
15
16
  # Initializes a new instance of OllamaChat::FollowChat.
16
17
  #
@@ -131,9 +132,10 @@ class OllamaChat::FollowChat
131
132
  if @chat.tool_function(name).require_confirmation?
132
133
  prompt = "πŸ”” I want to execute tool %s\n%s\nConfirm? (y/n) " % [
133
134
  bold { name },
134
- italic { function },
135
+ italic { function },
135
136
  ]
136
- if @chat.confirm?(prompt:) =~ /y/i
137
+ prompt.gsub!('%', '%%')
138
+ if @chat.confirm?(prompt:, yes: /y/i)
137
139
  confirmed = :explicit
138
140
  else
139
141
  confirmed = :denied
@@ -153,7 +155,7 @@ class OllamaChat::FollowChat
153
155
  resolve: 'You **MUST** ask the user for instructions on how to proceed!!!',
154
156
  )
155
157
  STDOUT.printf(
156
- "\n%s Execution of tool %s denied by user.\n", ?🚫, bold { name }
158
+ "\n%s Execution of tool %s denied by user.\n\n", ?🚫, bold { name }
157
159
  )
158
160
  @chat.log(:warn,"Execution of tool %s was denied by user!" % name)
159
161
  else
@@ -169,24 +171,43 @@ class OllamaChat::FollowChat
169
171
  @chat.log(:info, "Execution of tool %s was implicitly confirmed." % name)
170
172
  end
171
173
  end
172
- begin
173
- data = JSON.parse(result)
174
- @chat.log(:info, JSON.pretty_generate(data))
175
- rescue
176
- @chat.log(:info, result)
177
- end
174
+
178
175
  @chat.tool_call_results[name] = result
176
+
177
+ data = nil
178
+ message = begin
179
+ data = JSON.parse(result)
180
+ @chat.log(:info, JSON.pretty_generate(data))
181
+ data['message']
182
+ rescue
183
+ @chat.log(:info, result)
184
+ nil
185
+ end
186
+ warn =
187
+ begin
188
+ !!data.ask_and_send(:[], 'error') || data.ask_and_send(:[], 'success')
189
+ rescue
190
+ false
191
+ end
192
+
179
193
  tools_used[name] = {
180
- 'size' => Tins::Unit.format(result.to_s.size, unit: ?B, prefix: 1024, format: '%.1f %U'),
181
- 'duration' => Tins::Duration.new(Time.now - start).to_s,
194
+ message:,
195
+ warn: ,
196
+ size: format_bytes(result.to_s.size),
197
+ duration: Tins::Duration.new(Time.now - start).to_s,
182
198
  }
183
199
  end
184
200
 
185
201
  if tools_used.full?
186
202
  infobar.reset
187
203
  tools_used.each do |name, info|
188
- puts "πŸ”§ Tool functions #{name} returned result:",
189
- info.to_yaml.sub(/\A---\s*\n/, '').gsub(/^/, ' '), ""
204
+ feedback_message = if info[:message]
205
+ "\n%s %s\n\n" % [ info[:warn] ? '⚠️' : 'πŸ’‘', info[:message] ]
206
+ end
207
+ puts <<~EOT.strip, ""
208
+ πŸ”§ Tool functions #{name} returned result (#{info[:size]} in #{info[:duration]}).
209
+ #{feedback_message}
210
+ EOT
190
211
  timeout = @chat.tool_function(name).result_display_timeout?
191
212
  @chat.confirm?(prompt: '⏎ Press any key to continue (%s). ', timeout:)
192
213
  end
@@ -304,7 +325,7 @@ class OllamaChat::FollowChat
304
325
  #
305
326
  # This method delegates to the messages object's show_last method, which
306
327
  # displays the most recent non-user message in the conversation history.
307
- # It is typically used to provide feedback to the user about the last
328
+ # It is typically used to provide message to the user about the last
308
329
  # response from the assistant.
309
330
  # @return [ nil, String ] the pager command or nil if no paging was
310
331
  # performed.
@@ -3,7 +3,7 @@
3
3
  # This module encapsulates methods for piping assistant responses to command
4
4
  # standard input and writing assistant responses to files. It handles the
5
5
  # mechanics of sending output to external processes or saving content to disk
6
- # while providing appropriate error handling and user feedback.
6
+ # while providing appropriate error handling and user message.
7
7
  #
8
8
  # @example Piping a response to a command
9
9
  # chat.pipe('cat > output.txt')
@@ -83,7 +83,7 @@ module OllamaChat::MessageOutput
83
83
  def attempt_to_write_file(filename, message)
84
84
  path = Pathname.new(filename.to_s).expand_path
85
85
  if !path.exist? ||
86
- confirm?(prompt: "πŸ”” File #{path.to_s.inspect} already exists, overwrite? (y/n) ") =~ /y/i
86
+ confirm?(prompt: "πŸ”” File #{path.to_s.inspect} already exists, overwrite? (y/n) ", yes: /y/i)
87
87
  then
88
88
  File.open(path, ?w) do |output|
89
89
  output.write(message.content)
@@ -95,7 +95,7 @@ module OllamaChat::ModelHandling
95
95
  # that combines the model name and formatted size
96
96
  private def model_with_size(model)
97
97
  formatted_size = Term::ANSIColor.bold {
98
- Tins::Unit.format(model.size, unit: ?B, prefix: 1024, format: '%.1f %U')
98
+ format_bytes(model.size)
99
99
  }
100
100
  SearchUI::Wrapper.new(model.name, display: "#{model.name} #{formatted_size}")
101
101
  end
@@ -264,3 +264,5 @@ tools:
264
264
  require_confirmation: true
265
265
  allowed:
266
266
  - './tmp'
267
+ retrieve_document_snippets:
268
+ default: true
@@ -173,9 +173,9 @@ module OllamaChat::PersonaeManagement
173
173
  STDOUT.puts "Deleting '#{bold{persona.sub_ext('')}}'..."
174
174
  STDOUT.puts "Backup will be saved to: #{backup_pathname}"
175
175
 
176
- if confirm?(prompt: "πŸ”” Are you sure? (y/n) ") =~ /y/i
176
+ if confirm?(prompt: "πŸ”” Are you sure? (y/n) ", yes: /y/i)
177
177
  FileUtils.mv pathname, backup_pathname
178
- STDOUT.puts "βœ… Persona #{bold{persona.sub_ext('')}} deleted successfully"
178
+ STDOUT.puts "Persona #{bold{persona.sub_ext('')}} deleted successfully"
179
179
  {
180
180
  success: true,
181
181
  persona: persona.sub_ext(''),
@@ -117,7 +117,7 @@ module OllamaChat::ServerSocket
117
117
  running using the same directory or that a previous process left a stale
118
118
  socket file.
119
119
  EOT
120
- if confirm?(prompt: 'πŸ”” Do you want to remove the existing socket file and continue? (y/n) ') =~ /y/i
120
+ if confirm?(prompt: 'πŸ”” Do you want to remove the existing socket file and continue? (y/n) ', yes: /y/i)
121
121
  FileUtils.rm_f socket_path
122
122
  retry
123
123
  else
@@ -51,7 +51,7 @@ module OllamaChat::Switches
51
51
  #
52
52
  # The Switch class provides a simple way to manage boolean configuration
53
53
  # options with methods to toggle, set, and query the current state. It
54
- # includes messaging capabilities to provide feedback when the state changes.
54
+ # includes messaging capabilities to provide message when the state changes.
55
55
  #
56
56
  # @example Creating and using a switch
57
57
  # switch = Switch.new(value: false, msg: { true => 'Enabled', false => 'Disabled' })
@@ -26,9 +26,9 @@ class OllamaChat::Tools::Browse
26
26
  function: Tool::Function.new(
27
27
  name:,
28
28
  description: <<~EOT,
29
- Launch external viewer – Opens an HTTP/HTTPS link (or local file) in
30
- the system’s web/browser app. Use when you want to hand off a page
31
- for human inspection; no return value is expected.
29
+ Launch external viewer – Opens an HTTP/HTTPS link (or local file
30
+ path) in the system’s web/browser app. Use when you want to hand off
31
+ a page for human inspection; no return value is expected.
32
32
  EOT
33
33
  parameters: Tool::Function::Parameters.new(
34
34
  type: 'object',
@@ -58,10 +58,17 @@ class OllamaChat::Tools::Browse
58
58
  def execute(tool_call, **opts)
59
59
  url = tool_call.function.arguments.url
60
60
  result = browse_url(url)
61
+
62
+ message = if result.success?
63
+ "Opened #{url.to_s.inspect} in browser."
64
+ else
65
+ "Could not open #{url.to_s.inspect} in browser."
66
+ end
67
+
61
68
  {
62
69
  success: result.success?,
63
70
  exitstatus: result.exitstatus,
64
- message: 'opening URL/file',
71
+ message: ,
65
72
  url: ,
66
73
  }.to_json
67
74
  rescue => e
@@ -6,6 +6,7 @@
6
6
  # functionality to integrate tools into the chat system's tool registry.
7
7
  module OllamaChat::Tools::Concern
8
8
  extend Tins::Concern
9
+ include OllamaChat::Utils::ValueFormatter
9
10
 
10
11
  included do
11
12
  include Ollama
@@ -56,8 +56,8 @@ class OllamaChat::Tools::CopyToClipboard
56
56
  "The provided text has been successfully copied to the system clipboard."
57
57
  end
58
58
  {
59
- success: true,
60
- message:,
59
+ success: true,
60
+ message: ,
61
61
  }.to_json
62
62
  rescue => e
63
63
  {
@@ -73,15 +73,16 @@ class OllamaChat::Tools::OpenFileInEditor
73
73
  end
74
74
 
75
75
  chat.vim.open_file(file_path, start_line, end_line)
76
- if end_line
77
- result_msg = "Opened #{file_path} and selected range #{start_line}-#{end_line}"
78
- else
79
- result_msg = "Opened #{file_path} at line #{start_line}"
80
- end
76
+ message =
77
+ if end_line
78
+ "Opened #{file_path.to_s.inspect} and selected range #{start_line}-#{end_line}"
79
+ else
80
+ "Opened #{file_path.to_s.inspect} at line #{start_line}"
81
+ end
81
82
 
82
83
  {
83
84
  success: true,
84
- message: result_msg,
85
+ message: ,
85
86
  path: file_path,
86
87
  start_line: start_line,
87
88
  end_line: end_line,
@@ -43,10 +43,11 @@ class OllamaChat::Tools::PasteFromClipboard
43
43
 
44
44
  # Use the chat instance's clipboard paste functionality
45
45
  content = chat.perform_paste_from_clipboard
46
+ message = "Pasted #{format_bytes(content.to_s.size)} of content."
46
47
 
47
48
  {
48
- success: true,
49
- message: "Content pasted from clipboard",
49
+ success: true,
50
+ message: ,
50
51
  content:
51
52
  }.to_json
52
53
  rescue => e
@@ -53,7 +53,7 @@ class OllamaChat::Tools::PasteIntoEditor
53
53
  end
54
54
 
55
55
  {
56
- success: true,
56
+ success: true,
57
57
  message: ,
58
58
  }.to_json
59
59
  rescue => e
@@ -68,9 +68,11 @@ class OllamaChat::Tools::PatchFile
68
68
  path = assert_valid_path(path, config.tools.functions.patch_file.allowed?, check_file: true)
69
69
 
70
70
  result = apply_patch(path, diff_content)
71
- message = result[:success] ?
72
- "Successfully applied patch to #{path.to_s.inspect}." :
73
- "Failed to apply patch to file #{path.to_s.inspect}."
71
+ message = if result[:success]
72
+ "Successfully applied patch to #{path.to_s.inspect}."
73
+ else
74
+ "Failed to apply patch to file #{path.to_s.inspect}."
75
+ end
74
76
  (result | {
75
77
  path: path.to_s,
76
78
  message: ,
@@ -67,11 +67,16 @@ class OllamaChat::Tools::ResolveTag
67
67
  results = OllamaChat::Utils::TagResolver.new(tags).
68
68
  resolve(symbol:, kind:, directory:)
69
69
 
70
+ message = "Found %{results_count} results of symbol \"%{symbol}\"." % {
71
+ results_count: results.size, symbol:
72
+ }
73
+
70
74
  {
71
- symbol:,
72
- kind:,
75
+ message: ,
76
+ symbol: ,
77
+ kind: ,
73
78
  directory:,
74
- results:
79
+ results: ,
75
80
  }.to_json
76
81
  rescue => e
77
82
  { error: e.class.to_s, message: e.message }.to_json
@@ -0,0 +1,118 @@
1
+ # Collect snippets relevant to the supplied query.
2
+ #
3
+ # This tool searches the local document collection for text that matches the
4
+ # supplied query. It is used by the chat backend to provide an
5
+ # "in‑context" snippet set that the model can reference when answering user
6
+ # questions. The tool performs three steps:
7
+ #
8
+ # 1. **Validate** the request – the model must be running with embeddings
9
+ # enabled and the query cannot be empty.
10
+ # 2. **Search** – it uses `chat.documents.find_where` to locate snippets that
11
+ # contain the query string (trimmed to the embedding model’s context length)
12
+ # and collect tags from the snippet text.
13
+ # 3. **Return** – a JSON string containing a friendly prompt header and an
14
+ # array of `{text, tags}` objects. Each tag includes `name` and the
15
+ # originating `source`.
16
+ #
17
+ # @note The tool is deliberately read‑only; it never mutates the chat or
18
+ # the underlying document store.
19
+ class OllamaChat::Tools::RetrieveDocumentSnippets
20
+ include OllamaChat::Tools::Concern
21
+
22
+ # @return [String] the registered name for this tool
23
+ def self.register_name = 'retrieve_document_snippets'
24
+
25
+ # Function‑definition that the chat system exposes to the model.
26
+ # It follows the same pattern as other tools in the project.
27
+ #
28
+ # @return [Ollama::Tool] the tool definition usable by the Ollama
29
+ # server
30
+ def tool
31
+ Tool.new(
32
+ type: 'function',
33
+ function: Tool::Function.new(
34
+ name:,
35
+ description: <<~EOT,
36
+ Return document snippets from the current collection of documents
37
+ that match the supplied query. The result is a JSON string containing
38
+ a prompt header and an array of {text, tags} objects.
39
+ EOT
40
+ parameters: Tool::Function::Parameters.new(
41
+ type: 'object',
42
+ properties: {
43
+ query: Tool::Function::Parameters::Property.new(
44
+ type: 'string',
45
+ description: 'The query or text to search for in the document collection.'
46
+ )
47
+ },
48
+ required: ['query']
49
+ )
50
+ )
51
+ )
52
+ end
53
+
54
+ # Called when the model invokes the tool.
55
+ #
56
+ # @param tool_call [OllamaChat::Tool::Call] the tool call object
57
+ # @param opts [Hash] additional options, usually containing the chat
58
+ # @return [String] JSON string with the resulting snippets, or an error
59
+ # @raise [OllamaChat::OllamaChatError] if embeddings are disabled or query
60
+ # is empty
61
+ def execute(tool_call, **opts)
62
+ chat = opts[:chat]
63
+
64
+ chat.embedding.on? or raise OllamaChat::OllamaChatError, 'Embedding disabled'
65
+
66
+ query = tool_call.function.arguments.query.to_s
67
+
68
+ query.blank? and raise OllamaChat::OllamaChatError, 'Empty query'
69
+
70
+
71
+ records = find_document_records(chat, query)
72
+
73
+ message = records.map { |record|
74
+ link = if record.source =~ %r(\Ahttps?://)
75
+ record.source
76
+ else
77
+ 'file://%s' % File.expand_path(record.source)
78
+ end
79
+ [ link, ?# + record.tags.first ]
80
+ }.uniq.map { |l, t| chat.hyperlink(l, t) }.join(' ')
81
+
82
+ {
83
+ prompt: 'Consider these snippets generated from retrieval when formulating your response!',
84
+ ollama_chat_retrieval_snippets: records.map do |record|
85
+ {
86
+ text: record.text,
87
+ tags: record.tags_set.map { |t| { name: t.to_s(link: false), source: t.source }.compact }
88
+ }
89
+ end,
90
+ message:,
91
+ }.to_json
92
+ rescue => e
93
+ { error: e.class.name, message: e.message }.to_json
94
+ end
95
+
96
+ private
97
+
98
+ # The find_document_records method searches for document records matching the
99
+ # given query string.
100
+ #
101
+ # @param query [String] the search query string
102
+ #
103
+ # @return [Array<Documentrix::Utils::TagResult>] an array of found document
104
+ # records
105
+ def find_document_records(chat, query)
106
+ tags = Documentrix::Utils::Tags.new(valid_tag: /\A#*([\w\]\[]+)/)
107
+
108
+ chat.documents.find_where(
109
+ query.downcase.first(chat.config.embedding.model.context_length),
110
+ tags:,
111
+ prompt: chat.config.embedding.model.prompt?,
112
+ text_size: chat.config.embedding.found_texts_size?,
113
+ text_count: chat.config.embedding.found_texts_count?
114
+ )
115
+ end
116
+
117
+ self
118
+ end.register
@@ -62,12 +62,19 @@ class OllamaChat::Tools::SearchWeb
62
62
  config = chat.config
63
63
  args = tool_call.function.arguments
64
64
 
65
- query = args.query
65
+ query = args.query
66
66
  max_results = config.tools.functions.search_web?.max_results? || 10
67
67
  num_results = (args.num_results || 5).clamp(..max_results)
68
+ results = chat.search_web(query, num_results)
69
+
70
+ message = "Searched the web with query %{query} "\
71
+ "which returned %{results_count} results." % {
72
+ query: query.inspect, results_count: results.size
73
+ }
74
+
68
75
  {
69
- query: ,
70
- url: chat.search_web(query, num_results)
76
+ message:,
77
+ results:,
71
78
  }.to_json
72
79
  rescue => e
73
80
  {
@@ -84,10 +84,17 @@ class OllamaChat::Tools::WriteFile
84
84
  raise ArgumentError, 'Invalid mode %s' % args.mode.inspect
85
85
  end
86
86
 
87
+ bytes_written = format_bytes(bytes_written)
88
+ path = target_path.to_s.inspect
89
+
90
+ message = <<~EOT % { bytes_written:, path: }
91
+ Wrote %{bytes_written} to file %{path}.
92
+ EOT
93
+
87
94
  {
88
- success: true,
89
- path: target_path.to_s,
90
- bytes_written: ,
95
+ success: true,
96
+ path: ,
97
+ message:,
91
98
  }.to_json
92
99
  rescue => e
93
100
  {
@@ -62,6 +62,7 @@ require 'ollama_chat/tools/paste_into_editor'
62
62
  require 'ollama_chat/tools/patch_file'
63
63
  require 'ollama_chat/tools/read_file'
64
64
  require 'ollama_chat/tools/resolve_tag'
65
+ require 'ollama_chat/tools/retrieve_document_snippets'
65
66
  require 'ollama_chat/tools/run_tests'
66
67
  require 'ollama_chat/tools/search_web'
67
68
  require 'ollama_chat/tools/write_file'
@@ -0,0 +1,10 @@
1
+ # Module to format values for user consumption.
2
+ module OllamaChat::Utils::ValueFormatter
3
+ # Formats a byte value into a human‑readable string with units
4
+ #
5
+ # @param bytes [Integer] the number of bytes to format
6
+ # @return [String] the formatted byte string
7
+ def format_bytes(bytes)
8
+ Tins::Unit.format(bytes, unit: ?B, prefix: 1024, format: '%.1f %U')
9
+ end
10
+ end
@@ -9,11 +9,12 @@
9
9
  module OllamaChat::Utils
10
10
  end
11
11
 
12
+ require 'ollama_chat/utils/analyze_directory'
12
13
  require 'ollama_chat/utils/cache_fetcher'
13
14
  require 'ollama_chat/utils/chooser'
14
15
  require 'ollama_chat/utils/fetcher'
15
16
  require 'ollama_chat/utils/file_argument'
16
- require 'ollama_chat/utils/analyze_directory'
17
+ require 'ollama_chat/utils/path_completer'
17
18
  require 'ollama_chat/utils/path_validator'
18
19
  require 'ollama_chat/utils/tag_resolver'
19
- require 'ollama_chat/utils/path_completer'
20
+ require 'ollama_chat/utils/value_formatter'
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.83'
3
+ VERSION = '0.0.84'
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.83 ruby lib
2
+ # stub: ollama_chat 0.0.84 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.83".freeze
6
+ s.version = "0.0.84".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,15 +12,15 @@ 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/command_concern.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.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/location_handling.rb".freeze, "lib/ollama_chat/logging.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.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/think_control.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/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/directory_structure.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_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_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/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/run_tests.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/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/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/tag_resolver.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/command_concern.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.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/location_handling.rb".freeze, "lib/ollama_chat/logging.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.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/think_control.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/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/directory_structure.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_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_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/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/run_tests.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/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/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/tag_resolver.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/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.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/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/follow_chat_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/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/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_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_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_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/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/run_tests_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/file_argument_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_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]
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/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.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/location_handling.rb".freeze, "lib/ollama_chat/logging.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.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/think_control.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/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/directory_structure.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_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_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/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/retrieve_document_snippets.rb".freeze, "lib/ollama_chat/tools/run_tests.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/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/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/tag_resolver.rb".freeze, "lib/ollama_chat/utils/value_formatter.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/command_concern.rb".freeze, "lib/ollama_chat/config_handling.rb".freeze, "lib/ollama_chat/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.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/location_handling.rb".freeze, "lib/ollama_chat/logging.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.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/think_control.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/concern.rb".freeze, "lib/ollama_chat/tools/copy_to_clipboard.rb".freeze, "lib/ollama_chat/tools/directory_structure.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_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_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/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/retrieve_document_snippets.rb".freeze, "lib/ollama_chat/tools/run_tests.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/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/utils/path_completer.rb".freeze, "lib/ollama_chat/utils/path_validator.rb".freeze, "lib/ollama_chat/utils/tag_resolver.rb".freeze, "lib/ollama_chat/utils/value_formatter.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/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.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/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/follow_chat_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/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/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_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_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_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/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/retrieve_document_snippets_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_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/file_argument_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_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.8".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/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/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/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_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_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_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/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/run_tests_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/file_argument_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_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/follow_chat_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/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/tools/browse_spec.rb".freeze, "spec/ollama_chat/tools/copy_to_clipboard_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_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_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/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/retrieve_document_snippets_spec.rb".freeze, "spec/ollama_chat/tools/run_tests_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/file_argument_spec.rb".freeze, "spec/ollama_chat/utils/path_completer_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
 
@@ -40,7 +40,9 @@ describe OllamaChat::Tools::Browse do
40
40
  expect(json.error).to be_nil # No excception was raised
41
41
  expect(json.success).to be true
42
42
  expect(json.exitstatus).to eq 0
43
- expect(json.message).to eq 'opening URL/file'
43
+ expect(json.message).to eq(
44
+ "Opened \"https://www.example.com\" in browser."
45
+ )
44
46
  expect(json.url).to eq 'https://www.example.com'
45
47
  end
46
48
 
@@ -66,7 +68,9 @@ describe OllamaChat::Tools::Browse do
66
68
  expect(json.error).to be_nil # No excception was raised
67
69
  expect(json.success).to be false
68
70
  expect(json.exitstatus).to eq 1
69
- expect(json.message).to eq 'opening URL/file'
71
+ expect(json.message).to eq(
72
+ "Could not open \"https://nonexistent-domain-12345.com\" in browser."
73
+ )
70
74
  end
71
75
 
72
76
  it 'can handle execution exceptions gracefully' do
@@ -118,7 +122,9 @@ describe OllamaChat::Tools::Browse do
118
122
  json = json_object(result)
119
123
  expect(json.success).to be true
120
124
  expect(json.exitstatus).to eq 0
121
- expect(json.message).to eq 'opening URL/file'
125
+ expect(json.message).to eq(
126
+ "Opened \"https://www.example.com\" in browser."
127
+ )
122
128
  expect(json.url).to eq 'https://www.example.com'
123
129
  end
124
130
  end
@@ -31,6 +31,7 @@ describe OllamaChat::Tools::OpenFileInEditor do
31
31
  json = json_object(result)
32
32
  expect(json.path).to eq asset('example.rb')
33
33
  expect(json.start_line).to eq 42
34
+ expect(json.message).to match(%r(spec/assets/example.rb" at line 42))
34
35
  end
35
36
 
36
37
  it 'can be executed successfully with valid path, start_line, end_line' do
@@ -52,6 +53,7 @@ describe OllamaChat::Tools::OpenFileInEditor do
52
53
  expect(json.path).to eq asset('example.rb')
53
54
  expect(json.start_line).to eq 23
54
55
  expect(json.end_line).to eq 42
56
+ expect(json.message).to match(%r(spec/assets/example.rb" and selected range 23-42))
55
57
  end
56
58
 
57
59
  it 'can handle invalid path gracefully' do
@@ -27,7 +27,8 @@ describe OllamaChat::Tools::PasteFromClipboard do
27
27
  )
28
28
 
29
29
  # Test that perform_paste_from_clipboard is called
30
- expect(chat).to receive(:perform_paste_from_clipboard)
30
+ expect(chat).to receive(:perform_paste_from_clipboard).
31
+ and_return 'Hello World'
31
32
 
32
33
  result = described_class.new.execute(tool_call, chat: chat)
33
34
 
@@ -36,7 +37,7 @@ describe OllamaChat::Tools::PasteFromClipboard do
36
37
  json = json_object(result)
37
38
  expect(json.error).to be_nil # No exception was raised
38
39
  expect(json.success).to be true
39
- expect(json.message).to eq 'Content pasted from clipboard'
40
+ expect(json.message).to eq "Pasted 11.0 B of content."
40
41
  end
41
42
 
42
43
  it 'can handle execution errors gracefully' do
@@ -51,7 +51,7 @@ describe OllamaChat::Tools::ResolveTag do
51
51
  "linenumber" => 49}
52
52
  ]
53
53
  expect(OllamaChat::Utils::TagResolver).to receive(:new).
54
- and_return(double(resolve: double(resolve: result_array)))
54
+ and_return(double(resolve: double(size: 2, resolve: result_array)))
55
55
 
56
56
  result = described_class.new.execute(tool_call)
57
57
 
@@ -0,0 +1,66 @@
1
+ describe OllamaChat::Tools::RetrieveDocumentSnippets do
2
+ let :chat do
3
+ OllamaChat::Chat.new(argv: chat_default_config)
4
+ end
5
+
6
+ connect_to_ollama_server
7
+
8
+ it 'has the expected name' do
9
+ expect(described_class.new.name).to eq 'retrieve_document_snippets'
10
+ end
11
+
12
+ it 'provides a Tool instance' do
13
+ expect(described_class.new.tool).to be_a(Ollama::Tool)
14
+ end
15
+
16
+ it 'works with a valid query' do
17
+ tool_call = double(
18
+ 'ToolCall',
19
+ function: double(
20
+ name: 'retrieve_document_snippets',
21
+ arguments: double(
22
+ query: 'Ruby array',
23
+ # other attributes are irrelevant for this tool
24
+ )
25
+ )
26
+ )
27
+
28
+ tool = described_class.new
29
+ expect(tool).to receive(:find_document_records).with(
30
+ kind_of(OllamaChat::Chat), kind_of(String)
31
+ ).and_return(
32
+ [ double('Record', text: 'quux', source: 'foo', tags: %w[ bar ], tags_set: []) ]
33
+ )
34
+
35
+ result = tool.execute(tool_call, chat:)
36
+
37
+ # Should return a JSON string
38
+ expect(result).to be_a(String)
39
+ json = json_object(result)
40
+ expect(json.prompt).to eq(
41
+ "Consider these snippets generated from retrieval when formulating your response!"
42
+ )
43
+ expect(json.ollama_chat_retrieval_snippets.size).to eq 1
44
+ end
45
+
46
+ it 'returns an error when query is empty' do
47
+ tool_call = double(
48
+ 'ToolCall',
49
+ function: double(
50
+ name: 'retrieve_document_snippets',
51
+ arguments: double(
52
+ query: '',
53
+ )
54
+ )
55
+ )
56
+
57
+ result = described_class.new.execute(tool_call, chat:)
58
+ json = json_object(result)
59
+ expect(json.error).to eq('OllamaChat::OllamaChatError')
60
+ expect(json.message).to eq('Empty query')
61
+ end
62
+
63
+ it 'can be converted to hash' do
64
+ expect(described_class.new.to_hash).to be_a(Hash)
65
+ end
66
+ end
@@ -40,9 +40,11 @@ describe OllamaChat::Tools::SearchWeb do
40
40
  # Should return valid JSON
41
41
  expect(result).to be_a(String)
42
42
  json = json_object(result)
43
- expect(json.query).to eq 'Ruby programming'
44
- expect(json.url).to be_a(Array)
45
- expect(json.url.length).to be >= 1
43
+ expect(json.message).to eq(
44
+ "Searched the web with query \"Ruby programming\" which returned 2 results."
45
+ )
46
+ expect(json.results).to be_a(Array)
47
+ expect(json.results.length).to be >= 1
46
48
  end
47
49
 
48
50
  it 'can be executed successfully with a query and custom num_results' do
@@ -67,9 +69,11 @@ describe OllamaChat::Tools::SearchWeb do
67
69
  # Should return valid JSON
68
70
  expect(result).to be_a(String)
69
71
  json = json_object(result)
70
- expect(json.query).to eq 'Ruby programming'
71
- expect(json.url).to be_a(Array)
72
- expect(json.url.length).to eq 1
72
+ expect(json.message).to eq(
73
+ "Searched the web with query \"Ruby programming\" which returned 1 results."
74
+ )
75
+ expect(json.results).to be_a(Array)
76
+ expect(json.results.length).to eq 1
73
77
  end
74
78
 
75
79
  it 'can handle execution errors gracefully' do
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.83
4
+ version: 0.0.84
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -508,6 +508,7 @@ extra_rdoc_files:
508
508
  - lib/ollama_chat/tools/patch_file.rb
509
509
  - lib/ollama_chat/tools/read_file.rb
510
510
  - lib/ollama_chat/tools/resolve_tag.rb
511
+ - lib/ollama_chat/tools/retrieve_document_snippets.rb
511
512
  - lib/ollama_chat/tools/run_tests.rb
512
513
  - lib/ollama_chat/tools/search_web.rb
513
514
  - lib/ollama_chat/tools/write_file.rb
@@ -520,6 +521,7 @@ extra_rdoc_files:
520
521
  - lib/ollama_chat/utils/path_completer.rb
521
522
  - lib/ollama_chat/utils/path_validator.rb
522
523
  - lib/ollama_chat/utils/tag_resolver.rb
524
+ - lib/ollama_chat/utils/value_formatter.rb
523
525
  - lib/ollama_chat/version.rb
524
526
  - lib/ollama_chat/vim.rb
525
527
  - lib/ollama_chat/web_searching.rb
@@ -592,6 +594,7 @@ files:
592
594
  - lib/ollama_chat/tools/patch_file.rb
593
595
  - lib/ollama_chat/tools/read_file.rb
594
596
  - lib/ollama_chat/tools/resolve_tag.rb
597
+ - lib/ollama_chat/tools/retrieve_document_snippets.rb
595
598
  - lib/ollama_chat/tools/run_tests.rb
596
599
  - lib/ollama_chat/tools/search_web.rb
597
600
  - lib/ollama_chat/tools/write_file.rb
@@ -604,6 +607,7 @@ files:
604
607
  - lib/ollama_chat/utils/path_completer.rb
605
608
  - lib/ollama_chat/utils/path_validator.rb
606
609
  - lib/ollama_chat/utils/tag_resolver.rb
610
+ - lib/ollama_chat/utils/value_formatter.rb
607
611
  - lib/ollama_chat/version.rb
608
612
  - lib/ollama_chat/vim.rb
609
613
  - lib/ollama_chat/web_searching.rb
@@ -669,6 +673,7 @@ files:
669
673
  - spec/ollama_chat/tools/patch_file_spec.rb
670
674
  - spec/ollama_chat/tools/read_file_spec.rb
671
675
  - spec/ollama_chat/tools/resolve_tag_spec.rb
676
+ - spec/ollama_chat/tools/retrieve_document_snippets_spec.rb
672
677
  - spec/ollama_chat/tools/run_tests_spec.rb
673
678
  - spec/ollama_chat/tools/search_web_spec.rb
674
679
  - spec/ollama_chat/tools/write_file_spec.rb
@@ -747,6 +752,7 @@ test_files:
747
752
  - spec/ollama_chat/tools/patch_file_spec.rb
748
753
  - spec/ollama_chat/tools/read_file_spec.rb
749
754
  - spec/ollama_chat/tools/resolve_tag_spec.rb
755
+ - spec/ollama_chat/tools/retrieve_document_snippets_spec.rb
750
756
  - spec/ollama_chat/tools/run_tests_spec.rb
751
757
  - spec/ollama_chat/tools/search_web_spec.rb
752
758
  - spec/ollama_chat/tools/write_file_spec.rb