ollama_chat 0.0.77 → 0.0.79
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 +73 -0
- data/README.md +1 -9
- data/Rakefile +2 -2
- data/lib/ollama_chat/chat.rb +9 -20
- data/lib/ollama_chat/clipboard.rb +0 -1
- data/lib/ollama_chat/dialog.rb +3 -1
- data/lib/ollama_chat/document_cache.rb +1 -1
- data/lib/ollama_chat/follow_chat.rb +40 -19
- data/lib/ollama_chat/history.rb +10 -23
- data/lib/ollama_chat/information.rb +44 -1
- data/lib/ollama_chat/input_content.rb +1 -1
- data/lib/ollama_chat/logging.rb +29 -0
- data/lib/ollama_chat/model_handling.rb +3 -7
- data/lib/ollama_chat/oc.rb +22 -4
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +15 -6
- data/lib/ollama_chat/personae_management.rb +13 -2
- data/lib/ollama_chat/tools/directory_structure.rb +2 -2
- data/lib/ollama_chat/tools/execute_grep.rb +30 -4
- data/lib/ollama_chat/tools/paste_into_editor.rb +2 -2
- data/lib/ollama_chat/tools/patch_file.rb +119 -0
- data/lib/ollama_chat/tools/run_tests.rb +15 -9
- data/lib/ollama_chat/tools.rb +1 -0
- data/lib/ollama_chat/utils/chooser.rb +7 -3
- data/lib/ollama_chat/utils/tag_resolver.rb +1 -1
- data/lib/ollama_chat/version.rb +1 -1
- data/lib/ollama_chat/web_searching.rb +5 -7
- data/lib/ollama_chat.rb +1 -0
- data/ollama_chat.gemspec +7 -7
- data/spec/ollama_chat/chat_spec.rb +8 -13
- data/spec/ollama_chat/clipboard_spec.rb +0 -2
- data/spec/ollama_chat/follow_chat_spec.rb +0 -2
- data/spec/ollama_chat/information_spec.rb +0 -2
- data/spec/ollama_chat/input_content_spec.rb +0 -2
- data/spec/ollama_chat/kramdown_ansi_spec.rb +0 -2
- data/spec/ollama_chat/message_editing_spec.rb +0 -2
- data/spec/ollama_chat/message_list_spec.rb +0 -2
- data/spec/ollama_chat/message_output_spec.rb +0 -2
- data/spec/ollama_chat/model_handling_spec.rb +0 -2
- data/spec/ollama_chat/parsing_spec.rb +0 -3
- data/spec/ollama_chat/redis_cache_spec.rb +0 -2
- data/spec/ollama_chat/server_socket_spec.rb +0 -2
- data/spec/ollama_chat/source_fetching_spec.rb +0 -2
- data/spec/ollama_chat/state_selectors_spec.rb +0 -2
- data/spec/ollama_chat/switches_spec.rb +0 -2
- data/spec/ollama_chat/think_control_spec.rb +0 -2
- data/spec/ollama_chat/tools/browse_spec.rb +0 -2
- data/spec/ollama_chat/tools/copy_to_clipboard_spec.rb +0 -2
- data/spec/ollama_chat/tools/directory_structure_spec.rb +0 -2
- data/spec/ollama_chat/tools/execute_grep_spec.rb +28 -10
- data/spec/ollama_chat/tools/execute_ri_spec.rb +0 -2
- data/spec/ollama_chat/tools/file_context_spec.rb +0 -2
- data/spec/ollama_chat/tools/gem_path_lookup_spec.rb +0 -2
- data/spec/ollama_chat/tools/generate_password_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_current_weather_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_cve_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_endoflife_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_jira_issue_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_location_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_rfc_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_time_spec.rb +0 -2
- data/spec/ollama_chat/tools/get_url_spec.rb +0 -2
- data/spec/ollama_chat/tools/open_file_in_editor_spec.rb +0 -2
- data/spec/ollama_chat/tools/paste_from_clipboard_spec.rb +0 -2
- data/spec/ollama_chat/tools/paste_into_editor_spec.rb +0 -2
- data/spec/ollama_chat/tools/patch_file_spec.rb +155 -0
- data/spec/ollama_chat/tools/read_file_spec.rb +0 -2
- data/spec/ollama_chat/tools/resolve_tag_spec.rb +0 -2
- data/spec/ollama_chat/tools/run_tests_spec.rb +24 -9
- data/spec/ollama_chat/tools/search_web_spec.rb +0 -2
- data/spec/ollama_chat/tools/write_file_spec.rb +0 -2
- data/spec/ollama_chat/utils/analyze_directory_spec.rb +0 -4
- data/spec/ollama_chat/utils/cache_fetcher_spec.rb +0 -2
- data/spec/ollama_chat/utils/fetcher_spec.rb +0 -2
- data/spec/ollama_chat/utils/file_argument_spec.rb +0 -2
- data/spec/ollama_chat/vim_spec.rb +0 -2
- data/spec/ollama_chat/web_searching_spec.rb +0 -2
- data/spec/spec_helper.rb +7 -0
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 982588e8a14a4bb35aebd365a9dea99fb7c7b474f4d1293436fa97d1258eec79
|
|
4
|
+
data.tar.gz: 0a0410940246c4d9d260256e02373f002aeadba778a2097aefc97f190dc17e68
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f15c28d9980519078af9b27d5706edfa91df2c4c13ac235377dd97623c62a40c9b8014c06373f093ef473e5c9553e20a949fa4488afb7be06b94ebd006c2eb1c
|
|
7
|
+
data.tar.gz: 8bc4b5bd4880ab46ea227379ff4786681a7f7bef67d81df35628f5aea238c250f0842de5408fdb94056828c792080ce0ee0793a3a74e13d8a78c6d504b005f9d
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-03-13 v0.0.79
|
|
4
|
+
|
|
5
|
+
- Added `tmp/*` to Rakefile ignore list for cleaner builds.
|
|
6
|
+
- Updated gemspec: changed `s.rubygems_version` to **3.6.9**.
|
|
7
|
+
- Added `logging.rb` to `extra_rdoc_files` and `files` in gemspec.
|
|
8
|
+
- Adjusted gemspec file list to reflect new structure.
|
|
9
|
+
- Removed `Runtime Directory` (`-d`) explanation from `README.md`.
|
|
10
|
+
- Updated URL in `README.md`.
|
|
11
|
+
- Added explicit check that `args.path.full?` is true before calling
|
|
12
|
+
`assert_valid_path`, raising `ArgumentError` with message `'require path to
|
|
13
|
+
file to be patched'`.
|
|
14
|
+
- Updated path assignment to first validate presence, then assert validity
|
|
15
|
+
against `config.tools.functions.patch_file.allowed?`.
|
|
16
|
+
- Updated `OllamaChat::Tools::ExecuteGrep` to accept new options `before`,
|
|
17
|
+
`after`, and `context`.
|
|
18
|
+
- Added helper method `normalize_number` for optional integer arguments.
|
|
19
|
+
- Adjusted command template in `default_config.yml` to include `-B`, `-A`, and
|
|
20
|
+
`-C` flags based on provided values.
|
|
21
|
+
- Refactored logging: replaced `logger.error` / `logger.warn` calls with
|
|
22
|
+
`log(:error, …)` or `log(:warn, …)` across multiple files.
|
|
23
|
+
- Added optional `warn: true` flag to new helper so that critical errors also
|
|
24
|
+
trigger a user‑visible warning output while still being written to the log
|
|
25
|
+
file.
|
|
26
|
+
- Implemented `OllamaChat::Logging#log(severity, msg, warn:)` in `logging.rb`;
|
|
27
|
+
it formats exceptions with backtraces and forwards messages to the underlying
|
|
28
|
+
Ruby `Logger`.
|
|
29
|
+
- Updated `spec_helper.rb` by adding a global `config.before` hook that sets
|
|
30
|
+
temporary paths for `OC::OLLAMA::CHAT::HISTORY` and `LOGFILE` so all specs
|
|
31
|
+
run against isolated files.
|
|
32
|
+
- Added `tmp/*` to `.gitignore`.
|
|
33
|
+
- Created new module `OllamaChat::Logging` that lazily builds a Logger writing
|
|
34
|
+
to the file defined by `OC::OLLAMA::CHAT::LOGFILE` in XDG STATE.
|
|
35
|
+
- Required this logging module in `lib/ollama_chat.rb` and included it in
|
|
36
|
+
`class OllamaChat::Chat` so every chat instance has access to `logger`.
|
|
37
|
+
- Logged connection messages via `@chat.logger.info` before printing the
|
|
38
|
+
“Connecting …” line in `OllamaChat::Dialog#connect_message`.
|
|
39
|
+
- Centralized tool‑call error handling: log unconfigured, unregistered or
|
|
40
|
+
disabled tools with `@chat.logger.error`, and record each executed function
|
|
41
|
+
payload using `JSON.pretty_generate`.
|
|
42
|
+
- Introduced an explicit vs implicit confirmation flow (`:explicit`,
|
|
43
|
+
`:implicite`, `:denied`) in `OllamaChat::FollowChat#follow_chat` and log the
|
|
44
|
+
outcome accordingly.
|
|
45
|
+
- Switched chat history storage from XDG CACHE to XDG STATE by updating
|
|
46
|
+
`OC::OLLAMA::CHAT::HISTORY` path, adjusting file operations in
|
|
47
|
+
`lib/ollama_chat/history.rb`, and adding a new config entry for `LOGFILE`
|
|
48
|
+
under state home in `oc.rb`.
|
|
49
|
+
- Enhanced PatchFile tool: updated documentation to specify `unified diff
|
|
50
|
+
format` and `JSON response`.
|
|
51
|
+
- Added private method `digest` that returns `MD5` of a file path.
|
|
52
|
+
- Modified `apply_patch` to compute old digest, run patch command, compare
|
|
53
|
+
digests, set `success` flag accordingly.
|
|
54
|
+
- Improved error handling: now includes `success`, clearer messages, empty
|
|
55
|
+
result on failure.
|
|
56
|
+
|
|
57
|
+
## 2026-03-11 v0.0.78
|
|
58
|
+
|
|
59
|
+
- Added new `patch_file` tool for applying unified diff patches to files with
|
|
60
|
+
safety checks, including specs and integration into the tool system.
|
|
61
|
+
- Updated `DirectoryStructure` tool description to clarify that `max_depth`
|
|
62
|
+
limits the tree height for better LLM understanding.
|
|
63
|
+
- Bumped `search_ui` gem dependency from **0.0** to **0.1**, refactored model
|
|
64
|
+
handling using `SearchUI::Wrapper.new` and updated chooser logic for safer
|
|
65
|
+
method dispatch.
|
|
66
|
+
- Enhanced `run_tests` tool with a path validation whitelist in
|
|
67
|
+
`default_config.yml`, introducing `OllamaChat::Utils::PathValidator` and
|
|
68
|
+
updating `check_path` method to validate against the allowed list.
|
|
69
|
+
- Simplified runtime information handling by adding new helper methods:
|
|
70
|
+
`runtime_information_values`, `runtime_information`, and updated `chat.rb` to
|
|
71
|
+
use these for displaying structured runtime data.
|
|
72
|
+
- Added default persona name display using the `default_persona_name` helper,
|
|
73
|
+
updating information output and refactoring `reload_default_persona` guard
|
|
74
|
+
logic.
|
|
75
|
+
|
|
3
76
|
## 2026-03-09 v0.0.77
|
|
4
77
|
|
|
5
78
|
- Add runtime Git and time placeholders: added `git_current_branch` and
|
data/README.md
CHANGED
|
@@ -252,14 +252,6 @@ The `ollama_chat_send` command now supports additional parameters to enhance fun
|
|
|
252
252
|
$ echo "Hello world" | ollama_chat_send -d /tmp/my_working_dir -r
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
- **Runtime Directory (`-d`)**: Specifies the directory where the Unix socket
|
|
256
|
-
file of `ollama_chat` was created, if you want to send to a specific
|
|
257
|
-
`ollama_chat`.
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
$ echo "Hello world" | ollama_chat_send -d /tmp/my_runtime_dir -r
|
|
261
|
-
```
|
|
262
|
-
|
|
263
255
|
- **Help (`-h` or `--help`)**: Displays usage information and available options.
|
|
264
256
|
|
|
265
257
|
```bash
|
|
@@ -273,7 +265,7 @@ These parameters provide greater flexibility in how you interact with
|
|
|
273
265
|
|
|
274
266
|
The homepage of this app is located at
|
|
275
267
|
|
|
276
|
-
* https://github.com/flori/
|
|
268
|
+
* https://github.com/flori/ollama_chat
|
|
277
269
|
|
|
278
270
|
## Author
|
|
279
271
|
|
data/Rakefile
CHANGED
|
@@ -22,7 +22,7 @@ GemHadar do
|
|
|
22
22
|
test_dir 'spec'
|
|
23
23
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
|
|
24
24
|
'.yardoc', 'doc', 'tags', 'corpus', 'coverage', '/config/searxng/*',
|
|
25
|
-
'.starscope.db', 'cscope.out', 'errors.lst'
|
|
25
|
+
'.starscope.db', 'cscope.out', 'errors.lst', 'tmp/*'
|
|
26
26
|
package_ignore '.all_images.yml', '.tool-versions', '.gitignore', 'VERSION',
|
|
27
27
|
'.rspec', '.github', '.contexts', '.envrc', '.yardopts'
|
|
28
28
|
|
|
@@ -52,7 +52,7 @@ GemHadar do
|
|
|
52
52
|
dependency 'kramdown-ansi', '~> 0.3'
|
|
53
53
|
dependency 'complex_config', '~> 0.22', '>= 0.22.2'
|
|
54
54
|
dependency 'tins', '~> 1.52'
|
|
55
|
-
dependency 'search_ui', '~> 0.
|
|
55
|
+
dependency 'search_ui', '~> 0.1'
|
|
56
56
|
dependency 'amatch', '~> 0.4'
|
|
57
57
|
dependency 'pdf-reader', '~> 2.0'
|
|
58
58
|
dependency 'bigdecimal', '~> 3.1'
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -33,6 +33,7 @@ require 'context_spook'
|
|
|
33
33
|
class OllamaChat::Chat
|
|
34
34
|
include Tins::GO
|
|
35
35
|
include Term::ANSIColor
|
|
36
|
+
include OllamaChat::Logging
|
|
36
37
|
include OllamaChat::DocumentCache
|
|
37
38
|
include OllamaChat::Switches
|
|
38
39
|
include OllamaChat::StateSelectors
|
|
@@ -193,7 +194,7 @@ class OllamaChat::Chat
|
|
|
193
194
|
end
|
|
194
195
|
|
|
195
196
|
# The disable_content_parsing method turns off content parsing by setting
|
|
196
|
-
#
|
|
197
|
+
# `@parse_content` to false.
|
|
197
198
|
#
|
|
198
199
|
# This prevents automatic parsing of user input content during chat
|
|
199
200
|
# processing.
|
|
@@ -264,7 +265,8 @@ class OllamaChat::Chat
|
|
|
264
265
|
begin
|
|
265
266
|
use_model
|
|
266
267
|
rescue OllamaChatError::UnknownModelError => e
|
|
267
|
-
|
|
268
|
+
msg = "Caught #{e.class}: #{e}"
|
|
269
|
+
log(:error, msg, warn: true)
|
|
268
270
|
end
|
|
269
271
|
:next
|
|
270
272
|
when %r(^/system(?:\s+(show))?$)
|
|
@@ -707,23 +709,7 @@ class OllamaChat::Chat
|
|
|
707
709
|
end
|
|
708
710
|
end
|
|
709
711
|
|
|
710
|
-
if runtime_info.on? && content
|
|
711
|
-
runtime_info_values = {
|
|
712
|
-
languages: config.languages * ', ',
|
|
713
|
-
location: location.on? ? location_description.inspect : 'n/a',
|
|
714
|
-
git_current_branch: `git rev-parse --abbrev-ref HEAD 2>/dev/null`.chomp.full? || 'n/a',
|
|
715
|
-
git_remote_origin: `git remote get-url origin 2>/dev/null`.chomp.full? || 'n/a',
|
|
716
|
-
client: ,
|
|
717
|
-
current_directory: Pathname.pwd.expand_path.to_path.inspect,
|
|
718
|
-
terminal_rows: Tins::Terminal.rows,
|
|
719
|
-
terminal_cols: Tins::Terminal.cols,
|
|
720
|
-
time: Time.now.iso8601,
|
|
721
|
-
voice: voice.on? ? 'enabled' : 'disabled',
|
|
722
|
-
markdown: markdown.on? ? 'enabled' : 'disabled',
|
|
723
|
-
tool_paths_allowed: JSON(tool_paths_allowed),
|
|
724
|
-
}
|
|
725
|
-
content << config.prompts.runtime_info % runtime_info_values
|
|
726
|
-
end
|
|
712
|
+
content << runtime_information if runtime_info.on? && content
|
|
727
713
|
|
|
728
714
|
messages << Ollama::Message.new(role: 'user', content:, images: @images.dup)
|
|
729
715
|
@images.clear
|
|
@@ -777,7 +763,8 @@ class OllamaChat::Chat
|
|
|
777
763
|
server_socket_message&.disconnect
|
|
778
764
|
end
|
|
779
765
|
rescue Ollama::Errors::TimeoutError
|
|
780
|
-
|
|
766
|
+
msg = "Currently lost connection to ollama server and cannot send command."
|
|
767
|
+
log(:warn, msg, warn: true)
|
|
781
768
|
rescue Interrupt
|
|
782
769
|
STDOUT.puts "Type /quit to quit."
|
|
783
770
|
ensure
|
|
@@ -785,6 +772,7 @@ class OllamaChat::Chat
|
|
|
785
772
|
end
|
|
786
773
|
0
|
|
787
774
|
rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
|
|
775
|
+
log(:error, e)
|
|
788
776
|
fix_config(e)
|
|
789
777
|
ensure
|
|
790
778
|
save_history
|
|
@@ -821,6 +809,7 @@ class OllamaChat::Chat
|
|
|
821
809
|
if server_version.version < '0.9.0'.version
|
|
822
810
|
raise 'require ollama API version 0.9.0 or higher'
|
|
823
811
|
end
|
|
812
|
+
log(:info, "Connection to #{base_url} established.")
|
|
824
813
|
@ollama
|
|
825
814
|
end
|
|
826
815
|
|
|
@@ -98,7 +98,6 @@ module OllamaChat::Clipboard
|
|
|
98
98
|
# handles any OllamaChat::OllamaChatError exceptions by printing the error
|
|
99
99
|
# message to standard error and does not re-raise the exception.
|
|
100
100
|
def copy_to_clipboard
|
|
101
|
-
|
|
102
101
|
perform_copy_to_clipboard
|
|
103
102
|
STDOUT.puts "The last response has been successfully copied to the system clipboard."
|
|
104
103
|
true
|
data/lib/ollama_chat/dialog.rb
CHANGED
|
@@ -30,7 +30,9 @@ module OllamaChat::Dialog
|
|
|
30
30
|
# @param model [String] the model name to connect to
|
|
31
31
|
# @param base_url [String] the base URL of the connection
|
|
32
32
|
def connect_message(model, base_url)
|
|
33
|
-
|
|
33
|
+
msg = "Connecting to #{model}@#{base_url} now…"
|
|
34
|
+
log(:info, msg)
|
|
35
|
+
STDOUT.puts green { msg }
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
# The choose_collection method presents a menu to select or create a document
|
|
@@ -43,7 +43,7 @@ module OllamaChat::DocumentCache
|
|
|
43
43
|
document_cache_class
|
|
44
44
|
end
|
|
45
45
|
rescue => e
|
|
46
|
-
|
|
46
|
+
log(:error, "Caught #{e.class}: #{e} => Falling back to MemoryCache.")
|
|
47
47
|
Documentrix::Documents::MemoryCache
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -99,43 +99,46 @@ class OllamaChat::FollowChat
|
|
|
99
99
|
response.message.tool_calls.each do |tool_call|
|
|
100
100
|
name = tool_call.function.name
|
|
101
101
|
unless @chat.tool_configured?(name)
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
msg = "Error: Unconfigured tool named %s ignored => Skip.\n" % name
|
|
103
|
+
@chat.tool_call_results[name] = msg
|
|
104
|
+
@chat.log(:error, msg)
|
|
104
105
|
next
|
|
105
106
|
end
|
|
106
107
|
unless @chat.tool_registered?(name)
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
msg = "Error: Unregistered tool named %s ignored => Skip.\n" % name
|
|
109
|
+
@chat.tool_call_results[name] = msg
|
|
110
|
+
@chat.log(:error, msg)
|
|
109
111
|
next
|
|
110
112
|
end
|
|
111
113
|
unless @chat.tool_enabled?(name)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
msg = "Error: Disabled tool named %s ignored => Skip.\n" % name
|
|
115
|
+
@chat.tool_call_results[name] = msg
|
|
116
|
+
@chat.log(:error, msg)
|
|
114
117
|
next
|
|
115
118
|
end
|
|
116
119
|
STDOUT.puts
|
|
117
|
-
confirmed =
|
|
118
|
-
|
|
120
|
+
confirmed = :implicit
|
|
121
|
+
function = JSON.pretty_generate(tool_call.function)
|
|
122
|
+
@chat.log(:info, function)
|
|
119
123
|
if @chat.tool_function(name).require_confirmation?
|
|
120
124
|
prompt = "I want to execute tool %s\n%s\nConfirm? (y/n) " % [
|
|
121
125
|
bold { name },
|
|
122
|
-
italic {
|
|
126
|
+
italic { function },
|
|
123
127
|
]
|
|
124
|
-
|
|
128
|
+
if @chat.ask?(prompt:) =~ /\Ay/i
|
|
129
|
+
confirmed = :explicit
|
|
130
|
+
else
|
|
131
|
+
confirmed = :denied
|
|
132
|
+
end
|
|
125
133
|
else
|
|
126
134
|
STDOUT.puts "Executing tool %s\n%s" % [
|
|
127
135
|
bold { name },
|
|
128
|
-
italic {
|
|
136
|
+
italic { function },
|
|
129
137
|
]
|
|
130
138
|
end
|
|
131
139
|
result = nil
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"\n%s Execution of tool %s confirmed.\n\n", ?✅, bold { name }
|
|
135
|
-
)
|
|
136
|
-
result = OllamaChat::Tools.registered[name].
|
|
137
|
-
execute(tool_call, chat: @chat, config: @chat.config)
|
|
138
|
-
else
|
|
140
|
+
case confirmed
|
|
141
|
+
when :denied
|
|
139
142
|
result = JSON(
|
|
140
143
|
message: 'User denied confirmation!',
|
|
141
144
|
resolve: 'You **MUST** ask the user for instructions on how to proceed!!!',
|
|
@@ -143,7 +146,25 @@ class OllamaChat::FollowChat
|
|
|
143
146
|
STDOUT.printf(
|
|
144
147
|
"\n%s Execution of tool %s denied by user.\n", ?🚫, bold { name }
|
|
145
148
|
)
|
|
146
|
-
|
|
149
|
+
@chat.log(:warn,"Execution of tool %s was denied by user!" % name)
|
|
150
|
+
else
|
|
151
|
+
symbol = confirmed == :implicit ? '☑️ ' : '✅'
|
|
152
|
+
STDOUT.printf(
|
|
153
|
+
"\n%s Execution of tool %s confirmed.\n\n", symbol, bold { name }
|
|
154
|
+
)
|
|
155
|
+
result = OllamaChat::Tools.registered[name].
|
|
156
|
+
execute(tool_call, chat: @chat, config: @chat.config)
|
|
157
|
+
if confirmed == :explicit
|
|
158
|
+
@chat.log(:info, "Execution of tool %s was explicitly confirmed." % name)
|
|
159
|
+
else
|
|
160
|
+
@chat.log(:info, "Execution of tool %s was implicitly confirmed." % name)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
begin
|
|
164
|
+
data = JSON.parse(result)
|
|
165
|
+
@chat.log(:info, JSON.pretty_generate(data))
|
|
166
|
+
rescue
|
|
167
|
+
@chat.log(:info, result)
|
|
147
168
|
end
|
|
148
169
|
@chat.tool_call_results[name] = result
|
|
149
170
|
end
|
data/lib/ollama_chat/history.rb
CHANGED
|
@@ -17,20 +17,6 @@
|
|
|
17
17
|
module OllamaChat::History
|
|
18
18
|
private
|
|
19
19
|
|
|
20
|
-
# The chat_history_filename method constructs and returns the full file path
|
|
21
|
-
# for the chat history file.
|
|
22
|
-
#
|
|
23
|
-
# This method takes the configured chat history filename from the
|
|
24
|
-
# configuration and expands it to an absolute path using File.expand_path.
|
|
25
|
-
# This ensures that the returned path is fully qualified and can be used
|
|
26
|
-
# reliably for reading from or writing to the chat history file.
|
|
27
|
-
#
|
|
28
|
-
# @return [String] the absolute file path to the chat history file as
|
|
29
|
-
# specified in the configuration
|
|
30
|
-
def chat_history_filename
|
|
31
|
-
File.expand_path(OC::OLLAMA::CHAT::HISTORY)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
20
|
# The init_chat_history method initializes the chat session by loading
|
|
35
21
|
# previously saved command history from a file.
|
|
36
22
|
#
|
|
@@ -40,15 +26,15 @@ module OllamaChat::History
|
|
|
40
26
|
# loading process are caught and logged as warnings, but do not interrupt the
|
|
41
27
|
# execution flow.
|
|
42
28
|
def init_chat_history
|
|
43
|
-
if
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
end
|
|
29
|
+
if OC::OLLAMA::CHAT::HISTORY.exist?
|
|
30
|
+
history = OC::OLLAMA::CHAT::HISTORY.read
|
|
31
|
+
history_data = JSON.load(history)
|
|
32
|
+
Readline::HISTORY.clear
|
|
33
|
+
Readline::HISTORY.push(*history_data)
|
|
49
34
|
end
|
|
50
35
|
rescue => e
|
|
51
|
-
|
|
36
|
+
msg = "Caught #{e.class} while loading #{OC::OLLAMA::CHAT::HISTORY.inspect}: #{e}"
|
|
37
|
+
log(:error, msg, warn: true)
|
|
52
38
|
end
|
|
53
39
|
|
|
54
40
|
# The save_history method persists the current command history to a file.
|
|
@@ -57,9 +43,10 @@ module OllamaChat::History
|
|
|
57
43
|
# writes it to the chat history filename. It handles potential errors during
|
|
58
44
|
# the write operation by catching exceptions and issuing a warning message.
|
|
59
45
|
def save_history
|
|
60
|
-
File.secure_write(
|
|
46
|
+
File.secure_write(OC::OLLAMA::CHAT::HISTORY, JSON.dump(Readline::HISTORY))
|
|
61
47
|
rescue => e
|
|
62
|
-
|
|
48
|
+
msg = "Caught #{e.class} while saving #{OC::OLLAMA::CHAT::HISTORY.inspect}: #{e}"
|
|
49
|
+
log(:error, msg, warn: true)
|
|
63
50
|
end
|
|
64
51
|
|
|
65
52
|
# The clear_history method clears the Readline history array and ensures that
|
|
@@ -112,13 +112,20 @@ module OllamaChat::Information
|
|
|
112
112
|
think_mode.show
|
|
113
113
|
think_loud.show
|
|
114
114
|
location.show
|
|
115
|
-
runtime_info.show
|
|
116
115
|
voice.show
|
|
117
116
|
@voice.on? and @voices.show
|
|
117
|
+
if runtime_info.on?
|
|
118
|
+
STDOUT.puts "Runtime Information:"
|
|
119
|
+
STDOUT.puts runtime_information_values.transform_keys(&:to_s).to_yaml.
|
|
120
|
+
sub(/\A---\s*\n/, '').gsub(/^/, ' ')
|
|
121
|
+
else
|
|
122
|
+
runtime_info.show
|
|
123
|
+
end
|
|
118
124
|
tools_support.show
|
|
119
125
|
STDOUT.puts "Documents database cache is #{@documents.nil? ? 'n/a' : bold{@documents.cache.class}}"
|
|
120
126
|
STDOUT.puts "Document policy for references in user text: #{bold{document_policy}}"
|
|
121
127
|
STDOUT.puts "Currently selected search engine is #{bold(search_engine)}."
|
|
128
|
+
name = default_persona_name and STDOUT.puts "Default persona: #{bold{name}}"
|
|
122
129
|
STDOUT.puts "Conversation length: #{bold(@messages.size.to_s)} message(s)."
|
|
123
130
|
nil
|
|
124
131
|
end
|
|
@@ -231,4 +238,40 @@ module OllamaChat::Information
|
|
|
231
238
|
def server_url
|
|
232
239
|
@server_url ||= ollama.base_url
|
|
233
240
|
end
|
|
241
|
+
|
|
242
|
+
# The runtime_information_values method compiles a set of key runtime details
|
|
243
|
+
# such as languages, location description, default persona name, current git
|
|
244
|
+
# branch and remote origin, client agent string, current directory, terminal
|
|
245
|
+
# dimensions, timestamp, voice and markdown status, and allowed tool paths.
|
|
246
|
+
#
|
|
247
|
+
# @return [Hash] a hash containing runtime information values.
|
|
248
|
+
def runtime_information_values
|
|
249
|
+
{
|
|
250
|
+
languages: config.languages * ', ',
|
|
251
|
+
time: Time.now.iso8601,
|
|
252
|
+
location: location.on?.full? { location_description } || 'n/a',
|
|
253
|
+
default_persona: default_persona_name.full? || 'n/a',
|
|
254
|
+
git_current_branch: `git rev-parse --abbrev-ref HEAD 2>/dev/null`.chomp.full? || 'n/a',
|
|
255
|
+
git_remote_origin: `git remote get-url origin 2>/dev/null`.chomp.full? || 'n/a',
|
|
256
|
+
client: ,
|
|
257
|
+
current_directory: Pathname.pwd.expand_path.to_path,
|
|
258
|
+
terminal_rows: Tins::Terminal.rows,
|
|
259
|
+
terminal_cols: Tins::Terminal.cols,
|
|
260
|
+
voice: voice.on? ? 'enabled' : 'disabled',
|
|
261
|
+
markdown: markdown.on? ? 'enabled' : 'disabled',
|
|
262
|
+
tool_paths_allowed: JSON.pretty_generate(tool_paths_allowed),
|
|
263
|
+
}
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# The runtime_information method generates a formatted string containing
|
|
267
|
+
# various runtime values such as languages, location description, git branch
|
|
268
|
+
# and origin, client agent, current directory, terminal size, time, voice and
|
|
269
|
+
# markdown status, and allowed tool paths.
|
|
270
|
+
# It returns the result of interpolating these values into the configured
|
|
271
|
+
# runtime_info prompt template.
|
|
272
|
+
#
|
|
273
|
+
# @return [String] the formatted runtime information string.
|
|
274
|
+
def runtime_information
|
|
275
|
+
config.prompts.runtime_info % runtime_information_values
|
|
276
|
+
end
|
|
234
277
|
end
|
|
@@ -37,7 +37,7 @@ module OllamaChat::InputContent
|
|
|
37
37
|
# searches for files matching the given pattern, excludes already chosen
|
|
38
38
|
# files, and presents them in an interactive chooser menu.
|
|
39
39
|
#
|
|
40
|
-
# @param
|
|
40
|
+
# @param patterns [ Array<String> ] the glob patterns to search for files
|
|
41
41
|
# @param chosen [ Set ] a set of already chosen filenames to exclude from
|
|
42
42
|
# selection
|
|
43
43
|
#
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Provides a simple logging facility for the OllamaChat application. It offers
|
|
2
|
+
# methods to access a logger, determine the current log level, and write
|
|
3
|
+
# messages at various severity levels, including debug.
|
|
4
|
+
module OllamaChat::Logging
|
|
5
|
+
# The logger method returns the current Logger instance used by OllamaChat.
|
|
6
|
+
# If no Logger exists, it creates one pointing to the configured log file.
|
|
7
|
+
#
|
|
8
|
+
# @return [Logger] the active Logger instance
|
|
9
|
+
def logger
|
|
10
|
+
@logger and return @logger
|
|
11
|
+
OC::OLLAMA::CHAT::LOGFILE.dirname.mkpath
|
|
12
|
+
@logger = Logger.new(OC::OLLAMA::CHAT::LOGFILE)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# The log method records a message or exception at the specified severity
|
|
16
|
+
# level using the logger and optionally triggers a warning output
|
|
17
|
+
#
|
|
18
|
+
# @param severity [ Symbol ] the logging level to use
|
|
19
|
+
# @param msg [ String, Exception ] the message or exception to be logged
|
|
20
|
+
# @param warn [ TrueClass, FalseClass ] whether to also trigger a warning output
|
|
21
|
+
def log(severity, msg, warn: false)
|
|
22
|
+
if msg.is_a?(Exception)
|
|
23
|
+
msg = "Caught #{msg.class}: #{msg}\n#{Array(msg&.backtrace).join(?\n)}"
|
|
24
|
+
end
|
|
25
|
+
logger.send(severity, msg)
|
|
26
|
+
warn and self.warn(msg)
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -94,14 +94,10 @@ module OllamaChat::ModelHandling
|
|
|
94
94
|
# @return [ Object ] a result object with an overridden to_s method
|
|
95
95
|
# that combines the model name and formatted size
|
|
96
96
|
private def model_with_size(model)
|
|
97
|
-
result = model.name
|
|
98
97
|
formatted_size = Term::ANSIColor.bold {
|
|
99
98
|
Tins::Unit.format(model.size, unit: ?B, prefix: 1024, format: '%.1f %U')
|
|
100
99
|
}
|
|
101
|
-
|
|
102
|
-
define_method(:to_s) { "%s %s" % [ model.name, formatted_size ] }
|
|
103
|
-
end
|
|
104
|
-
result
|
|
100
|
+
SearchUI::Wrapper.new(model.name, display: "#{model.name} #{formatted_size}")
|
|
105
101
|
end
|
|
106
102
|
|
|
107
103
|
# The use_model method selects and sets the model to be used for the chat
|
|
@@ -151,12 +147,12 @@ module OllamaChat::ModelHandling
|
|
|
151
147
|
Regexp.new($1)
|
|
152
148
|
end
|
|
153
149
|
models = ollama.tags.models.sort_by(&:name).map { |m| model_with_size(m) }
|
|
154
|
-
selector and models = models.
|
|
150
|
+
selector and models = models.select { _1.value =~ selector }
|
|
155
151
|
model =
|
|
156
152
|
if models.size == 1
|
|
157
153
|
models.first
|
|
158
154
|
elsif cli_model == ''
|
|
159
|
-
OllamaChat::Utils::Chooser.choose(models) || current_model
|
|
155
|
+
OllamaChat::Utils::Chooser.choose(models)&.value || current_model
|
|
160
156
|
else
|
|
161
157
|
cli_model || current_model
|
|
162
158
|
end
|
data/lib/ollama_chat/oc.rb
CHANGED
|
@@ -17,17 +17,23 @@ module OC
|
|
|
17
17
|
prefix ''
|
|
18
18
|
|
|
19
19
|
XDG_CONFIG_HOME = set do
|
|
20
|
-
description 'XDG Configuration directory path'
|
|
20
|
+
description 'XDG Configuration home directory path'
|
|
21
21
|
default { '~/.config' }
|
|
22
22
|
decode { Pathname.new(_1).join('ollama_chat').expand_path }
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
XDG_CACHE_HOME = set do
|
|
26
|
-
description 'XDG Cache directory path'
|
|
26
|
+
description 'XDG Cache home directory path'
|
|
27
27
|
default { '~/.cache' }
|
|
28
28
|
decode { Pathname.new(_1).join('ollama_chat').expand_path }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
XDG_STATE_HOME = set do
|
|
32
|
+
description 'XDG State home directory path'
|
|
33
|
+
default { '~/.local' }
|
|
34
|
+
decode { Pathname.new(_1).join('state', 'ollama_chat').expand_path }
|
|
35
|
+
end
|
|
36
|
+
|
|
31
37
|
PAGER = set do
|
|
32
38
|
description 'Pager command to use in case terminal lines are exceeded by output'
|
|
33
39
|
|
|
@@ -133,14 +139,19 @@ module OC
|
|
|
133
139
|
|
|
134
140
|
HISTORY = set do
|
|
135
141
|
description 'File to save the chat history in'
|
|
136
|
-
default
|
|
142
|
+
default XDG_STATE_HOME + 'history.json'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
LOGFILE = set do
|
|
146
|
+
description 'File to output log messages to'
|
|
147
|
+
default XDG_STATE_HOME + 'chat.log'
|
|
137
148
|
end
|
|
138
149
|
|
|
139
150
|
module TOOLS
|
|
140
151
|
description 'Tool specific configuration settings'
|
|
141
152
|
|
|
142
153
|
# Run Tests tool configuration
|
|
143
|
-
|
|
154
|
+
TEST_RUNNER = set do
|
|
144
155
|
description 'Configured test runner for run_tests tool function'
|
|
145
156
|
default 'rspec'
|
|
146
157
|
required true
|
|
@@ -162,6 +173,13 @@ module OC
|
|
|
162
173
|
decode { Pathname.new(_1).expand_path }
|
|
163
174
|
end
|
|
164
175
|
|
|
176
|
+
PATCH_TOOL = set do
|
|
177
|
+
description 'Patch tool to use'
|
|
178
|
+
|
|
179
|
+
default { `which patch`.full?(:chomp) }
|
|
180
|
+
check { value.blank? || File.exist?(value) }
|
|
181
|
+
end
|
|
182
|
+
|
|
165
183
|
module JIRA
|
|
166
184
|
description 'Jira tool configuration'
|
|
167
185
|
|
|
@@ -11,7 +11,7 @@ timeouts:
|
|
|
11
11
|
languages:
|
|
12
12
|
- en-US
|
|
13
13
|
location:
|
|
14
|
-
enabled:
|
|
14
|
+
enabled: true
|
|
15
15
|
name: Berlin
|
|
16
16
|
decimal_degrees: [ 52.514127, 13.475211 ]
|
|
17
17
|
units: SI (International System of Units) # or USCS (United States Customary System)
|
|
@@ -44,10 +44,10 @@ prompts:
|
|
|
44
44
|
There is usually no reason to mention this information to the user unless
|
|
45
45
|
asked about it.
|
|
46
46
|
|
|
47
|
-
- Languages the user prefers: %{languages}
|
|
48
|
-
- Current time is %{time}
|
|
49
|
-
- Location
|
|
50
|
-
- Current directory is %{current_directory}
|
|
47
|
+
- Languages the user prefers: %{languages}
|
|
48
|
+
- Current time is %{time}
|
|
49
|
+
- Location: %{location}
|
|
50
|
+
- Current directory is "%{current_directory}"
|
|
51
51
|
- **Git**:
|
|
52
52
|
- Current branch is %{git_current_branch}
|
|
53
53
|
- Current remote origin is %{git_remote_origin}
|
|
@@ -185,7 +185,7 @@ tools:
|
|
|
185
185
|
execute_grep:
|
|
186
186
|
default: true
|
|
187
187
|
cmd: |
|
|
188
|
-
grep #{'-i' if ignore_case} -m #{max_results} -r #{pattern} #{path}
|
|
188
|
+
grep #{'-i' if ignore_case} -m #{max_results} -r #{before.full? { "-B %u " % it }}#{after.full? { "-A %u " % it }}#{context.full? { "-C %u " % it }}#{pattern} #{path}
|
|
189
189
|
browse:
|
|
190
190
|
default: true
|
|
191
191
|
write_file:
|
|
@@ -218,6 +218,10 @@ tools:
|
|
|
218
218
|
run_tests:
|
|
219
219
|
require_confirmation: true
|
|
220
220
|
default: true
|
|
221
|
+
allowed:
|
|
222
|
+
- "./spec"
|
|
223
|
+
- "./test"
|
|
224
|
+
- "./tests"
|
|
221
225
|
get_jira_issue:
|
|
222
226
|
default: false
|
|
223
227
|
get_rfc:
|
|
@@ -236,3 +240,8 @@ tools:
|
|
|
236
240
|
default: true
|
|
237
241
|
resolve_tag:
|
|
238
242
|
default: true
|
|
243
|
+
patch_file:
|
|
244
|
+
default: true
|
|
245
|
+
require_confirmation: true
|
|
246
|
+
allowed:
|
|
247
|
+
- './tmp'
|
|
@@ -55,11 +55,22 @@ module OllamaChat::PersonaeManagement
|
|
|
55
55
|
@default_persona ||= :none
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
# The default_persona_name method returns the name of the currently set
|
|
59
|
+
# default persona by extracting its basename and removing the file extension,
|
|
60
|
+
# unless no persona is set.
|
|
61
|
+
#
|
|
62
|
+
# @return [ String ] the default persona name or nil if none.
|
|
63
|
+
def default_persona_name
|
|
64
|
+
if @default_persona.present? && @default_persona != :none
|
|
65
|
+
@default_persona.basename.sub_ext('').to_s
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
58
69
|
# Reloads the default persona file if one is set and not :none, prompting the
|
|
59
70
|
# user for confirmation before playing the persona file.
|
|
60
71
|
def reload_default_persona
|
|
61
|
-
|
|
62
|
-
prompt = "Reload default persona #{
|
|
72
|
+
name = default_persona_name or return
|
|
73
|
+
prompt = "Reload default persona #{name}? (y/n) "
|
|
63
74
|
if ask?(prompt:) =~ /\Ay/i
|
|
64
75
|
play_persona_file @default_persona
|
|
65
76
|
end
|