ollama_chat 0.0.83 → 0.0.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +46 -0
- data/README.md +4 -2
- data/Rakefile +1 -1
- data/lib/ollama_chat/chat.rb +18 -40
- data/lib/ollama_chat/config_handling.rb +3 -3
- data/lib/ollama_chat/conversation.rb +6 -3
- data/lib/ollama_chat/dialog.rb +50 -5
- data/lib/ollama_chat/follow_chat.rb +35 -14
- data/lib/ollama_chat/input_content.rb +9 -0
- data/lib/ollama_chat/message_output.rb +2 -2
- data/lib/ollama_chat/model_handling.rb +1 -1
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +2 -0
- data/lib/ollama_chat/personae_management.rb +3 -3
- data/lib/ollama_chat/server_socket.rb +1 -1
- data/lib/ollama_chat/switches.rb +1 -1
- data/lib/ollama_chat/tools/browse.rb +11 -4
- data/lib/ollama_chat/tools/concern.rb +1 -0
- data/lib/ollama_chat/tools/copy_to_clipboard.rb +2 -2
- data/lib/ollama_chat/tools/open_file_in_editor.rb +7 -6
- data/lib/ollama_chat/tools/paste_from_clipboard.rb +3 -2
- data/lib/ollama_chat/tools/paste_into_editor.rb +1 -1
- data/lib/ollama_chat/tools/patch_file.rb +5 -3
- data/lib/ollama_chat/tools/resolve_tag.rb +8 -3
- data/lib/ollama_chat/tools/retrieve_document_snippets.rb +118 -0
- data/lib/ollama_chat/tools/search_web.rb +10 -3
- data/lib/ollama_chat/tools/write_file.rb +10 -3
- data/lib/ollama_chat/tools.rb +1 -0
- data/lib/ollama_chat/utils/value_formatter.rb +10 -0
- data/lib/ollama_chat/utils.rb +3 -2
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +6 -6
- data/spec/ollama_chat/chat_spec.rb +12 -4
- data/spec/ollama_chat/tools/browse_spec.rb +9 -3
- data/spec/ollama_chat/tools/open_file_in_editor_spec.rb +2 -0
- data/spec/ollama_chat/tools/paste_from_clipboard_spec.rb +3 -2
- data/spec/ollama_chat/tools/resolve_tag_spec.rb +1 -1
- data/spec/ollama_chat/tools/retrieve_document_snippets_spec.rb +66 -0
- data/spec/ollama_chat/tools/search_web_spec.rb +10 -6
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a9e61c3d789441bb11ee79fe2ec63f219cc8d938845a7dc6fe9c8f6d012d5bb
|
|
4
|
+
data.tar.gz: f453e609568a6df073fbaf865860fa1c919419b728c309ae0e19e97dc09d6b52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 24fadb41107daee4f625bb3d80743c8323624da545e6386b07ef25da5be3974afa2b0759a8db86d44eea04c9b156b92400e6a348d6bd9aae3dd71791939533bd
|
|
7
|
+
data.tar.gz: 7c43765e2da1f09781b6a8b0af70ea562cdec22fbdb4c92ab7f4eca033fdd3b9f79a55cbe3d7c3e91684c771a29cca95c76f26c44b7871cf9e142c3d0ca12179
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-03-29 v0.0.85
|
|
4
|
+
|
|
5
|
+
- Added `list` and `rename` subcommands to the `/collection` command, allowing
|
|
6
|
+
users to display available collections and rename them via the
|
|
7
|
+
`rename_collection` method in `lib/ollama_chat/dialog.rb`.
|
|
8
|
+
- Enhanced the `/collection` command to be optional; running `/collection`
|
|
9
|
+
without arguments now displays collection statistics by invoking the
|
|
10
|
+
`collection_stats` method.
|
|
11
|
+
- Updated `README.md` to reflect new command options and adjusted help text for
|
|
12
|
+
the `/collection` command.
|
|
13
|
+
- Modified tests in `spec/ollama_chat/chat_spec.rb` to accommodate new command
|
|
14
|
+
options and collection handling.
|
|
15
|
+
- Adjusted `regexp` and `complete` configurations in `lib/ollama_chat/chat.rb`
|
|
16
|
+
for the `/collection` command.
|
|
17
|
+
- Updated the `documentrix` dependency from **0.0.4** to **0.1.0**.
|
|
18
|
+
- Introduced progress feedback in `lib/ollama_chat/input_content.rb` within the
|
|
19
|
+
`provide_file_set_content` method, displaying `count/total` for batch
|
|
20
|
+
processing or just `count` for interactive mode.
|
|
21
|
+
- Optimized persona loading logic to skip setting a default persona if the
|
|
22
|
+
conversation already contains messages, while retaining fallbacks from
|
|
23
|
+
command-line options for new conversations.
|
|
24
|
+
- Fixed the warning condition in `OllamaChat::FollowChat` by correcting the
|
|
25
|
+
success check in `lib/ollama_chat/follow_chat.rb`.
|
|
26
|
+
|
|
27
|
+
## 2026-03-26 v0.0.84
|
|
28
|
+
|
|
29
|
+
- Added `OllamaChat::Utils::ValueFormatter` with helper `format_bytes` in
|
|
30
|
+
`lib/ollama_chat/utils/value_formatter.rb`.
|
|
31
|
+
- Added `require 'ollama_chat/utils/value_formatter'` where needed.
|
|
32
|
+
- Updated `write_file`, `patch_file`, `paste_from_clipboard` to use
|
|
33
|
+
`format_bytes` for byte‑size messages.
|
|
34
|
+
- Implemented new tool `RetrieveDocumentSnippets` in
|
|
35
|
+
`lib/ollama_chat/tools/retrieve_document_snippets.rb` and its spec
|
|
36
|
+
`spec/ollama_chat/tools/retrieve_document_snippets_spec.rb`.
|
|
37
|
+
- Updated `default_config.yml` to enable `retrieve_document_snippets` by
|
|
38
|
+
default.
|
|
39
|
+
- Rewrote tool payloads to include a `message` key for `browse`, `search_web`,
|
|
40
|
+
`paste_from_clipboard`, `resolve_tag`, and others.
|
|
41
|
+
- `browse` now returns `"Opened \"<url>\" in browser."` or a failure message.
|
|
42
|
+
- Refactored `confirm?` in `lib/ollama_chat/dialog.rb` to accept keyword `yes:`
|
|
43
|
+
for a confirmation regex and display a coloured emoji matching the response
|
|
44
|
+
or timeout/default.
|
|
45
|
+
- Updated all calls to `confirm?` to use `yes: /y/i` syntax.
|
|
46
|
+
- Updated `lib/ollama_chat/message_output.rb` to add `yes:` keyword to
|
|
47
|
+
`confirm?` calls and refine the emoji shown when a file already exists.
|
|
48
|
+
|
|
3
49
|
## 2026-03-24 v0.0.83
|
|
4
50
|
|
|
5
51
|
- Added timeout support to `Dialog#confirm?`: introduced optional `timeout:`
|
data/README.md
CHANGED
|
@@ -209,8 +209,10 @@ The following commands can be given inside the chat, if prefixed by a `/`:
|
|
|
209
209
|
├──────────────────┼────────────────────┼──────────────────┼──────────────────────────────────────────────────────────┤
|
|
210
210
|
│ /load │ │ path │ load conversation messages │
|
|
211
211
|
├──────────────────┼────────────────────┼──────────────────┼──────────────────────────────────────────────────────────┤
|
|
212
|
-
│ /collection │ change
|
|
213
|
-
│ │ clear
|
|
212
|
+
│ /collection │ change │ │ display, clear (current), change, list, or rename │
|
|
213
|
+
│ │ clear │ │ collection │
|
|
214
|
+
│ │ list │ │ │
|
|
215
|
+
│ │ rename │ │ │
|
|
214
216
|
├──────────────────┼────────────────────┼──────────────────┼──────────────────────────────────────────────────────────┤
|
|
215
217
|
│ /persona │ add │ │ manage and load/play personae for roleplay │
|
|
216
218
|
│ │ delete │ │ │
|
data/Rakefile
CHANGED
|
@@ -42,7 +42,7 @@ GemHadar do
|
|
|
42
42
|
|
|
43
43
|
dependency 'excon', '~> 1.0'
|
|
44
44
|
dependency 'ollama-ruby', '~> 1.21'
|
|
45
|
-
dependency 'documentrix', '>= 0.0
|
|
45
|
+
dependency 'documentrix', '>= 0.1.0'
|
|
46
46
|
dependency 'unix_socks', '~> 0.3'
|
|
47
47
|
dependency 'rss', '~> 0.3'
|
|
48
48
|
dependency 'term-ansicolor', '~> 1.11'
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -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.
|
|
@@ -478,11 +479,12 @@ class OllamaChat::Chat
|
|
|
478
479
|
|
|
479
480
|
command(
|
|
480
481
|
name: :collection,
|
|
481
|
-
regexp: %r(^/collection(?:\s+(clear|change))?$),
|
|
482
|
-
complete: [ 'collection', %w[ clear change ] ],
|
|
483
|
-
|
|
482
|
+
regexp: %r(^/collection(?:\s+(clear|change|list|rename))?$),
|
|
483
|
+
complete: [ 'collection', %w[ clear change list rename ] ],
|
|
484
|
+
optional: true,
|
|
485
|
+
help: 'display, clear (current), change, list, or rename collection'
|
|
484
486
|
) do |subcommand|
|
|
485
|
-
case subcommand
|
|
487
|
+
case subcommand
|
|
486
488
|
when 'clear'
|
|
487
489
|
loop do
|
|
488
490
|
tags = @documents.tags.add('[EXIT]').add('[ALL]')
|
|
@@ -492,7 +494,7 @@ class OllamaChat::Chat
|
|
|
492
494
|
STDOUT.puts "Exiting chooser."
|
|
493
495
|
break
|
|
494
496
|
when '[ALL]'
|
|
495
|
-
if confirm?(prompt: '🔔 Are you sure? (y/n) '
|
|
497
|
+
if confirm?(prompt: '🔔 Are you sure? (y/n) ', yes: /y/i)
|
|
496
498
|
@documents.clear
|
|
497
499
|
STDOUT.puts "Cleared collection #{bold{@documents.collection}}."
|
|
498
500
|
break
|
|
@@ -508,6 +510,14 @@ class OllamaChat::Chat
|
|
|
508
510
|
end
|
|
509
511
|
when 'change'
|
|
510
512
|
choose_collection(@documents.collection)
|
|
513
|
+
when 'list'
|
|
514
|
+
current_collection = @documents.collection
|
|
515
|
+
puts @documents.collections.
|
|
516
|
+
map { |c| current_collection == c ? bold { c } : c }
|
|
517
|
+
when 'rename'
|
|
518
|
+
rename_collection(@documents.collection)
|
|
519
|
+
when nil
|
|
520
|
+
collection_stats
|
|
511
521
|
end
|
|
512
522
|
:next
|
|
513
523
|
end
|
|
@@ -537,7 +547,7 @@ class OllamaChat::Chat
|
|
|
537
547
|
end
|
|
538
548
|
when 'edit'
|
|
539
549
|
if result = edit_persona and
|
|
540
|
-
confirm?(prompt: '🔔 Load new persona profile? (y/n) '
|
|
550
|
+
confirm?(prompt: '🔔 Load new persona profile? (y/n) ', yes: /y/i)
|
|
541
551
|
then
|
|
542
552
|
result
|
|
543
553
|
else
|
|
@@ -868,7 +878,7 @@ class OllamaChat::Chat
|
|
|
868
878
|
STDOUT.puts "Exiting chooser."
|
|
869
879
|
break
|
|
870
880
|
when '[ALL]'
|
|
871
|
-
if confirm?(prompt: '🔔 Are you sure? (y/n) '
|
|
881
|
+
if confirm?(prompt: '🔔 Are you sure? (y/n) ', yes: /y/i)
|
|
872
882
|
links.clear
|
|
873
883
|
STDOUT.puts "Cleared all links in list."
|
|
874
884
|
break
|
|
@@ -916,7 +926,7 @@ class OllamaChat::Chat
|
|
|
916
926
|
@documents.clear
|
|
917
927
|
STDOUT.puts "Cleared all tags."
|
|
918
928
|
when 'all'
|
|
919
|
-
if confirm?(prompt: '🔔 Are you sure to clear messages and collection? (y/n) '
|
|
929
|
+
if confirm?(prompt: '🔔 Are you sure to clear messages and collection? (y/n) ', yes: /y/i)
|
|
920
930
|
messages.clear
|
|
921
931
|
@documents.clear
|
|
922
932
|
links.clear
|
|
@@ -1000,27 +1010,6 @@ class OllamaChat::Chat
|
|
|
1000
1010
|
[ content, Documentrix::Utils::Tags.new(valid_tag: /\A#*([\w\]\[]+)/) ]
|
|
1001
1011
|
end
|
|
1002
1012
|
|
|
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
1013
|
runtime_info.on? && content and
|
|
1025
1014
|
content << ?\n << {
|
|
1026
1015
|
ollama_chat_runtime_information: runtime_information
|
|
@@ -1056,17 +1045,6 @@ class OllamaChat::Chat
|
|
|
1056
1045
|
raise
|
|
1057
1046
|
end
|
|
1058
1047
|
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
1048
|
|
|
1071
1049
|
case type
|
|
1072
1050
|
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) '
|
|
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) "
|
|
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) "
|
|
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?(
|
|
31
|
-
|
|
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
|
data/lib/ollama_chat/dialog.rb
CHANGED
|
@@ -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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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
|
|
@@ -111,6 +135,27 @@ module OllamaChat::Dialog
|
|
|
111
135
|
info
|
|
112
136
|
end
|
|
113
137
|
|
|
138
|
+
# Rename an existing collection to a new, user‑supplied name.
|
|
139
|
+
#
|
|
140
|
+
# This helper prompts the user to provide a new name for the collection
|
|
141
|
+
# identified by <code>current_collection</code>. It then renames the current
|
|
142
|
+
# collection to have the new_name and switches to it.
|
|
143
|
+
#
|
|
144
|
+
# @param current_collection [Symbol] the current collection name
|
|
145
|
+
def rename_collection(current_collection)
|
|
146
|
+
prompt = 'Rename collection %s to: ' % current_collection
|
|
147
|
+
if new_collection = ask?(prompt:).full?(:to_sym)
|
|
148
|
+
begin
|
|
149
|
+
@documents.rename_collection(new_collection)
|
|
150
|
+
STDOUT.puts "Renamed current collection #{current_collection} to #{new_collection}."
|
|
151
|
+
rescue
|
|
152
|
+
STDERR.puts "Renaming to #{new_collection} failed, it already exists."
|
|
153
|
+
end
|
|
154
|
+
else
|
|
155
|
+
STDOUT.puts "Renaming cancelled."
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
114
159
|
# The change_system_prompt method allows the user to select or enter a new
|
|
115
160
|
# system prompt for the chat session.
|
|
116
161
|
# It provides an interactive chooser when multiple prompts match the given
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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') == false
|
|
189
|
+
rescue
|
|
190
|
+
false
|
|
191
|
+
end
|
|
192
|
+
|
|
179
193
|
tools_used[name] = {
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
189
|
-
|
|
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
|
|
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.
|
|
@@ -161,7 +161,16 @@ module OllamaChat::InputContent
|
|
|
161
161
|
# @yield [filename] the block that processes each filename
|
|
162
162
|
# @return [String] the concatenated result of the block applied to each file
|
|
163
163
|
def provide_file_set_content(patterns, all: false, &block)
|
|
164
|
+
total = 0
|
|
165
|
+
all and file_set_each(patterns, all:) { total += 1 }
|
|
166
|
+
count = 0
|
|
164
167
|
file_set_each(patterns, all:).each_with_object('') do |filename, result|
|
|
168
|
+
count += 1
|
|
169
|
+
if all
|
|
170
|
+
STDOUT.puts "Handling File (#{bold{count}}/#{bold{total}}):"
|
|
171
|
+
else
|
|
172
|
+
STDOUT.puts "Handling File (#{bold{count}}):"
|
|
173
|
+
end
|
|
165
174
|
result << ("%s:\n\n%s\n\n" % [ filename, block.(filename) ])
|
|
166
175
|
end.full?
|
|
167
176
|
end
|
|
@@ -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
|
|
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) "
|
|
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
|
-
|
|
98
|
+
format_bytes(model.size)
|
|
99
99
|
}
|
|
100
100
|
SearchUI::Wrapper.new(model.name, display: "#{model.name} #{formatted_size}")
|
|
101
101
|
end
|
|
@@ -40,7 +40,7 @@ module OllamaChat::PersonaeManagement
|
|
|
40
40
|
# playing the persona file if it exists.
|
|
41
41
|
def setup_persona_from_opts
|
|
42
42
|
@default_persona and return
|
|
43
|
-
@
|
|
43
|
+
@messages.size > 0 and return
|
|
44
44
|
if persona = @opts[?p].full? { Pathname.new(_1) }
|
|
45
45
|
if persona.extname == '.md'
|
|
46
46
|
pathname = persona
|
|
@@ -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) "
|
|
176
|
+
if confirm?(prompt: "🔔 Are you sure? (y/n) ", yes: /y/i)
|
|
177
177
|
FileUtils.mv pathname, backup_pathname
|
|
178
|
-
STDOUT.puts "
|
|
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) '
|
|
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
|
data/lib/ollama_chat/switches.rb
CHANGED
|
@@ -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
|
|
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
|
|
30
|
-
the system’s web/browser app. Use when you want to hand off
|
|
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:
|
|
71
|
+
message: ,
|
|
65
72
|
url: ,
|
|
66
73
|
}.to_json
|
|
67
74
|
rescue => e
|
|
@@ -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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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:
|
|
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:
|
|
49
|
-
message:
|
|
49
|
+
success: true,
|
|
50
|
+
message: ,
|
|
50
51
|
content:
|
|
51
52
|
}.to_json
|
|
52
53
|
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
|
-
|
|
73
|
-
|
|
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: ,
|