ollama_chat 0.0.125 → 0.0.127
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 +152 -0
- data/Rakefile +1 -1
- data/lib/ollama_chat/chat.rb +2 -2
- data/lib/ollama_chat/collection_search.rb +14 -2
- data/lib/ollama_chat/commands.rb +33 -23
- data/lib/ollama_chat/compaction.rb +29 -2
- data/lib/ollama_chat/database/models/session.rb +21 -0
- data/lib/ollama_chat/follow_chat.rb +1 -1
- data/lib/ollama_chat/information.rb +6 -20
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +5 -3
- data/lib/ollama_chat/pager.rb +5 -2
- data/lib/ollama_chat/rag_handling.rb +217 -28
- data/lib/ollama_chat/session_management.rb +24 -4
- data/lib/ollama_chat/switches.rb +79 -9
- data/lib/ollama_chat/tool_calling.rb +3 -16
- data/lib/ollama_chat/tools/browse.rb +0 -1
- data/lib/ollama_chat/tools/compute_bmi.rb +1 -2
- data/lib/ollama_chat/tools/concern.rb +26 -0
- data/lib/ollama_chat/tools/copy_to_clipboard.rb +1 -3
- data/lib/ollama_chat/tools/delete_file.rb +4 -3
- data/lib/ollama_chat/tools/directory_structure.rb +0 -1
- data/lib/ollama_chat/tools/eval_ruby.rb +0 -1
- data/lib/ollama_chat/tools/execute_grep.rb +0 -2
- data/lib/ollama_chat/tools/execute_jira_twg.rb +0 -2
- data/lib/ollama_chat/tools/execute_ri.rb +0 -1
- data/lib/ollama_chat/tools/execute_shell.rb +5 -7
- data/lib/ollama_chat/tools/file_context.rb +0 -2
- data/lib/ollama_chat/tools/forget.rb +20 -8
- data/lib/ollama_chat/tools/gem_path_lookup.rb +0 -1
- data/lib/ollama_chat/tools/generate_image.rb +6 -8
- data/lib/ollama_chat/tools/generate_password.rb +0 -2
- data/lib/ollama_chat/tools/get_current_weather.rb +2 -4
- data/lib/ollama_chat/tools/get_cve.rb +0 -2
- data/lib/ollama_chat/tools/get_endoflife.rb +0 -2
- data/lib/ollama_chat/tools/get_ghr.rb +2 -4
- data/lib/ollama_chat/tools/get_jira_issue.rb +0 -2
- data/lib/ollama_chat/tools/get_location.rb +0 -2
- data/lib/ollama_chat/tools/get_rfc.rb +0 -2
- data/lib/ollama_chat/tools/get_time.rb +2 -3
- data/lib/ollama_chat/tools/get_url.rb +0 -2
- data/lib/ollama_chat/tools/lookup_group.rb +0 -2
- data/lib/ollama_chat/tools/memorize.rb +38 -13
- data/lib/ollama_chat/tools/move_file.rb +8 -4
- data/lib/ollama_chat/tools/open_file_in_editor.rb +0 -2
- data/lib/ollama_chat/tools/paste_from_clipboard.rb +1 -4
- data/lib/ollama_chat/tools/paste_into_editor.rb +3 -5
- data/lib/ollama_chat/tools/patch_file.rb +10 -7
- data/lib/ollama_chat/tools/read_file.rb +3 -5
- data/lib/ollama_chat/tools/resolve_tag.rb +1 -2
- data/lib/ollama_chat/tools/roll_dice.rb +0 -2
- data/lib/ollama_chat/tools/run_tests.rb +2 -2
- data/lib/ollama_chat/tools/search_knowledge.rb +19 -17
- data/lib/ollama_chat/tools/search_web.rb +0 -3
- data/lib/ollama_chat/tools/write_file.rb +4 -3
- data/lib/ollama_chat/tools.rb +50 -4
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +4 -4
- data/spec/ollama_chat/commands_spec.rb +41 -7
- data/spec/ollama_chat/rag_handling_spec.rb +191 -18
- data/spec/ollama_chat/session_management_spec.rb +6 -2
- data/spec/ollama_chat/switches_spec.rb +28 -0
- data/spec/ollama_chat/tool_calling_spec.rb +0 -11
- data/spec/ollama_chat/tools/browse_spec.rb +11 -7
- data/spec/ollama_chat/tools/compute_bmi_spec.rb +8 -8
- data/spec/ollama_chat/tools/concern_spec.rb +7 -1
- data/spec/ollama_chat/tools/copy_to_clipboard_spec.rb +8 -8
- data/spec/ollama_chat/tools/delete_file_spec.rb +7 -7
- data/spec/ollama_chat/tools/directory_structure_spec.rb +7 -7
- data/spec/ollama_chat/tools/execute_grep_spec.rb +10 -10
- data/spec/ollama_chat/tools/execute_jira_twg_spec.rb +8 -8
- data/spec/ollama_chat/tools/execute_ri_spec.rb +6 -6
- data/spec/ollama_chat/tools/execute_shell_spec.rb +2 -1
- data/spec/ollama_chat/tools/file_context_spec.rb +4 -4
- data/spec/ollama_chat/tools/forget_spec.rb +25 -15
- data/spec/ollama_chat/tools/gem_path_lookup_spec.rb +5 -5
- data/spec/ollama_chat/tools/generate_image_spec.rb +10 -10
- data/spec/ollama_chat/tools/generate_password_spec.rb +8 -8
- data/spec/ollama_chat/tools/get_current_weather_spec.rb +6 -6
- data/spec/ollama_chat/tools/get_cve_spec.rb +5 -5
- data/spec/ollama_chat/tools/get_endoflife_spec.rb +5 -5
- data/spec/ollama_chat/tools/get_ghr_spec.rb +11 -11
- data/spec/ollama_chat/tools/get_jira_issue_spec.rb +6 -6
- data/spec/ollama_chat/tools/get_location_spec.rb +6 -6
- data/spec/ollama_chat/tools/get_rfc_spec.rb +5 -5
- data/spec/ollama_chat/tools/get_time_spec.rb +4 -4
- data/spec/ollama_chat/tools/get_url_spec.rb +17 -17
- data/spec/ollama_chat/tools/lookup_group_spec.rb +5 -5
- data/spec/ollama_chat/tools/memorize_spec.rb +67 -11
- data/spec/ollama_chat/tools/move_file_spec.rb +8 -8
- data/spec/ollama_chat/tools/open_file_in_editor_spec.rb +6 -6
- data/spec/ollama_chat/tools/paste_from_clipboard_spec.rb +7 -7
- data/spec/ollama_chat/tools/paste_into_editor_spec.rb +6 -6
- data/spec/ollama_chat/tools/patch_file_spec.rb +9 -9
- data/spec/ollama_chat/tools/read_file_spec.rb +12 -12
- data/spec/ollama_chat/tools/resolve_tag_spec.rb +6 -6
- data/spec/ollama_chat/tools/roll_dice_spec.rb +6 -6
- data/spec/ollama_chat/tools/run_tests_spec.rb +13 -13
- data/spec/ollama_chat/tools/search_knowledge_spec.rb +22 -25
- data/spec/ollama_chat/tools/search_web_spec.rb +6 -6
- data/spec/ollama_chat/tools/write_file_spec.rb +15 -15
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a72761f0d0b34c0ba21859589410e914dda692d669a39629e4e6bb8f6e2857ea
|
|
4
|
+
data.tar.gz: 374fa95c62c5510e94c6a7624200a6193a15e9ed842a4b49b5364d43eeecac52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea024b4607101da7037f0234970cb6e655c6d2b1af46fc1eac1b8dc901aebd5ef95a091d079653bfb58e86d381c4bb56173172f9fb0861e9d8a3424667bfdd32
|
|
7
|
+
data.tar.gz: dfbbe6cddbb4aac1f047cb39719ed58e8920e22a42775cb9f18a4d3731d0c53cc7c632733241f58f6cd6c132e5979b0a3117bf38e7e0095417310e839fb7421b
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,157 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-06 v0.0.127
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
* **Switches and Configuration**
|
|
8
|
+
* Added `memory_trigger` switch, registered in `/toggle` (regexp,
|
|
9
|
+
completion list, help string, and fallback feedback).
|
|
10
|
+
* Refactored `Switch` to accept callable values alongside plain values;
|
|
11
|
+
plain values are now wrapped via a new private `adhoc_closure` method
|
|
12
|
+
using a `UNSET` sentinel for read/write disambiguation.
|
|
13
|
+
* Hardened `Switch#initialize` with an arity guard: callable values
|
|
14
|
+
responding to `:arity` must return `-1` (optional single parameter
|
|
15
|
+
defaulting to `UNSET`), otherwise a `TypeError` is raised.
|
|
16
|
+
* Updated `set` methods in `OllamaChat::Switches` to explicitly return
|
|
17
|
+
`nil` for consistent behavior.
|
|
18
|
+
* Added `@raise [TypeError]` tag to `Switch#initialize` and expanded
|
|
19
|
+
`@param value` YARD documentation for `CombinedSwitch`.
|
|
20
|
+
* Added arity guard (`ask_and_send(:arity) <= 0`) to
|
|
21
|
+
`CombinedSwitch#initialize`.
|
|
22
|
+
|
|
23
|
+
* **Session and Model Updates**
|
|
24
|
+
* Added `trigger_enabled?` and `set_trigger_enabled` to the `Session`
|
|
25
|
+
model to encapsulate trigger hash shape.
|
|
26
|
+
* Added YARD documentation for `adhoc_closure` and the `:memory_trigger`
|
|
27
|
+
reader.
|
|
28
|
+
|
|
29
|
+
* **Conversation and Compaction**
|
|
30
|
+
* Added `/conversation compact summary` command.
|
|
31
|
+
* Introduced `show_compaction_summary` in `Compaction` to retrieve the
|
|
32
|
+
most recent summary message via `messages.find_summary` and render its
|
|
33
|
+
content (narrative + `tool_calls` lookup index) through the pager,
|
|
34
|
+
prefixed with a size header and entry count.
|
|
35
|
+
* Registered the new `compact summary` subcommand in the `/conversation`
|
|
36
|
+
regexp alternation, completion list, help text, and dispatch block.
|
|
37
|
+
* Excluded system-injected messages (`runtime_information`,
|
|
38
|
+
`trigger_inject`) from the compaction summary's `tool_calls` block to
|
|
39
|
+
keep the index focused on user-initiated tool calls.
|
|
40
|
+
|
|
41
|
+
* **RAG and Search**
|
|
42
|
+
* Moved `set_documents_collection` above the `private` keyword in
|
|
43
|
+
`rag_handling.rb` to make it callable from outside `RAGHandling`.
|
|
44
|
+
* Updated `choose_collection` to call `set_documents_collection` instead
|
|
45
|
+
of assigning `@documents.collection` directly.
|
|
46
|
+
* Replaced direct `chat.documents.collection` reads/writes in `chat.rb`
|
|
47
|
+
and `search_knowledge.rb` with public accessors `chat.collection` and
|
|
48
|
+
`chat.set_documents_collection`.
|
|
49
|
+
* Consolidated two `chat.log` calls in `search_knowledge.rb` into one,
|
|
50
|
+
adding `rerank:` and `pre_rerank:` to the structured data hash with
|
|
51
|
+
`.compact`.
|
|
52
|
+
* Removed `String#%` interpolation in the old rerank log line and
|
|
53
|
+
eliminated the `collection_name` local variable.
|
|
54
|
+
* Updated `trigger_inject` in `collection_search.rb` to include the
|
|
55
|
+
surviving `records` array (text, similarity, tags) in the log `data:`
|
|
56
|
+
hash instead of only logging the count.
|
|
57
|
+
|
|
58
|
+
* **Shell Execution**
|
|
59
|
+
* Forced pager for all `execute_shell` output by passing `force: true` to
|
|
60
|
+
`use_pager`, ensuring consistent UX with other pager-based tools.
|
|
61
|
+
* Updated test-mode spec examples to include a `stub_success` call with
|
|
62
|
+
sample stdout to exercise the always-active pager path with real
|
|
63
|
+
content.
|
|
64
|
+
|
|
65
|
+
## 2026-10-05 v0.0.126
|
|
66
|
+
|
|
67
|
+
* **Tool Registry Refactor**: Refactored the tool registry to store tool
|
|
68
|
+
classes instead of pre-built instances.
|
|
69
|
+
* `registered_class(name)` now returns the class for `summary_template`
|
|
70
|
+
access.
|
|
71
|
+
* `registered_tool(name, chat:)` instantiates a fresh instance bound to
|
|
72
|
+
the current session.
|
|
73
|
+
* `Concern#initialize(chat)` injects the chat reference; all tools now
|
|
74
|
+
access config via `self.chat` instead of `opts[:chat]`.
|
|
75
|
+
* Helper methods in `execute_shell`, `generate_image`,
|
|
76
|
+
`get_current_weather`, `get_ghr`, and `patch_file` now use `self.chat`
|
|
77
|
+
directly.
|
|
78
|
+
* Migrated all tool specs to use `described_class.new(chat)` and
|
|
79
|
+
`.execute(tool_call)`.
|
|
80
|
+
|
|
81
|
+
* **Path Allowlists**: Moved path allowlists into tool parameter
|
|
82
|
+
descriptions.
|
|
83
|
+
* Added `allowed_paths` to `tools/concern.rb` to return expanded,
|
|
84
|
+
existing paths for the calling tool's `allowed` config.
|
|
85
|
+
* Removed `tool_paths_allowed` from `tool_calling.rb` and its spec.
|
|
86
|
+
* Injected `allowed_paths.map(&:inspect).join(', ')` into the `path`,
|
|
87
|
+
`source`, and `destination` parameter descriptions of `delete_file`,
|
|
88
|
+
`move_file`, `patch_file`, `read_file`, and `write_file`.
|
|
89
|
+
|
|
90
|
+
* **RAG Handling & Runtime Info**: Relocated `collection_descriptions` from
|
|
91
|
+
`information.rb` to `rag_handling.rb`.
|
|
92
|
+
* Removed `collections` key from `static_runtime_information_values` and
|
|
93
|
+
`default_config.yml`.
|
|
94
|
+
* Migrated `static_runtime_information` and `dynamic_runtime_information`
|
|
95
|
+
from `String#%` to `named_placeholders_interpolate`.
|
|
96
|
+
|
|
97
|
+
* **Collection Commands**: Reworked collection clearing into three distinct
|
|
98
|
+
commands.
|
|
99
|
+
* Split monolithic `clear_collection` into `clear_whole_collection`,
|
|
100
|
+
`clear_collection_tags`, and `clear_collection_sources`.
|
|
101
|
+
* `clear_collection_tags` implements a two-level tag-to-source browser.
|
|
102
|
+
* `clear_collection_sources` implements a source-to-tags browser.
|
|
103
|
+
* Added `use_pager(force:)` keyword in `pager.rb` to bypass size checks
|
|
104
|
+
using `Float::INFINITY`.
|
|
105
|
+
* Added `Kramdown::ANSI::Width.wrap(..., percentage: 90)` to pager views
|
|
106
|
+
for terminal-width wrapping.
|
|
107
|
+
* Bumped `documentrix` minimum to **0.8.0** in `Rakefile` and
|
|
108
|
+
`ollama_chat.gemspec` for the new `records(tags:, sources:)` API.
|
|
109
|
+
* Extended `/collection` regexp and completion for `clear sources`.
|
|
110
|
+
|
|
111
|
+
* **Memory Tools**: Enhanced memory management tools.
|
|
112
|
+
* `memorize` now accepts an optional `update` kwarg (ISO timestamp tag)
|
|
113
|
+
to replace an existing memory entry, returning `replaced_timestamp` and
|
|
114
|
+
`replaced_text`.
|
|
115
|
+
* `forget` now returns `forgotten_text` in the JSON response and includes
|
|
116
|
+
an 80-character snippet in the human-readable `message`.
|
|
117
|
+
* Renamed `set_current_collection` to `set_documents_collection` in
|
|
118
|
+
`rag_handling.rb`, `session_management.rb`, and specs.
|
|
119
|
+
* Made `current_collection` public in `RAGHandling`.
|
|
120
|
+
* Enriched `search_knowledge` tool `collection` param with allowed
|
|
121
|
+
collections from `collection_descriptions` and current default.
|
|
122
|
+
|
|
123
|
+
* **Session Management**:
|
|
124
|
+
* Derive memory trigger from persona at session apply by adding a
|
|
125
|
+
`trigger` block to `default_config.yml`.
|
|
126
|
+
* Extracted `create_memory_collection` into `RAGHandling` as the single
|
|
127
|
+
canonical entry point.
|
|
128
|
+
* In `SessionManagement#session_apply`, auto-derive the session trigger
|
|
129
|
+
from `initial_persona_name` and `config.trigger` when no explicit
|
|
130
|
+
trigger is set.
|
|
131
|
+
* Advertise `C-u` random shortcut in the session prompt to clear prefill
|
|
132
|
+
and obtain a random session name.
|
|
133
|
+
|
|
134
|
+
* **Commands & UX**:
|
|
135
|
+
* Added `-r` flag to `/compose` to quote the last assistant reply as an
|
|
136
|
+
`edit_text` pre-fill.
|
|
137
|
+
* Removed the `confirm?` prompt before `compact_with_retry` in
|
|
138
|
+
`/conversation compact`; compaction now runs immediately.
|
|
139
|
+
* Split `/collection clear` into `clear tags` subcommand and bare `clear`
|
|
140
|
+
routing to `clear_whole_collection`.
|
|
141
|
+
|
|
142
|
+
* **Tool Descriptions & Logging**:
|
|
143
|
+
* Made `paste_into_editor` description imperative.
|
|
144
|
+
* Documented bottom-up edit order in `patch_file` to prevent models from
|
|
145
|
+
incorrectly compensating for line shifts.
|
|
146
|
+
* Log full `edits` array in `patch_file` tool info log payload instead of
|
|
147
|
+
just `edits_count`.
|
|
148
|
+
* Strip ANSI codes from `run_tests` captured output using
|
|
149
|
+
`OllamaChat::Utils::StripANSI`.
|
|
150
|
+
|
|
151
|
+
* **Compatibility & Fixes**:
|
|
152
|
+
* Include `persona_name` in the `default` system prompt template in
|
|
153
|
+
`default_config.yml`.
|
|
154
|
+
|
|
3
155
|
## 2026-10-03 v0.0.125
|
|
4
156
|
|
|
5
157
|
### Added
|
data/Rakefile
CHANGED
|
@@ -40,7 +40,7 @@ GemHadar do
|
|
|
40
40
|
|
|
41
41
|
dependency 'excon', '~> 1.0'
|
|
42
42
|
dependency 'ollama-ruby', '~> 1.23'
|
|
43
|
-
dependency 'documentrix', '>= 0.
|
|
43
|
+
dependency 'documentrix', '>= 0.8.0'
|
|
44
44
|
dependency 'unix_socks', '>= 0.4'
|
|
45
45
|
dependency 'rss', '~> 0.3'
|
|
46
46
|
dependency 'term-ansicolor', '~> 1.11'
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -712,7 +712,7 @@ class OllamaChat::Chat
|
|
|
712
712
|
# @note Progress is reported to STDOUT during processing
|
|
713
713
|
def add_documents_from_argv(document_list)
|
|
714
714
|
if document_list.any?(&:empty?)
|
|
715
|
-
feedback("Clearing collection #{bold{
|
|
715
|
+
feedback("Clearing collection #{bold{collection}}.", type: :info)
|
|
716
716
|
documents.clear
|
|
717
717
|
document_list.reject!(&:empty?)
|
|
718
718
|
end
|
|
@@ -724,7 +724,7 @@ class OllamaChat::Chat
|
|
|
724
724
|
File.expand_path(doc)
|
|
725
725
|
end
|
|
726
726
|
end
|
|
727
|
-
feedback("Collection #{bold{
|
|
727
|
+
feedback("Collection #{bold{collection}}: Adding #{document_list.size} documents…", type: :info)
|
|
728
728
|
count = 1
|
|
729
729
|
document_list.each_slice(25) do |docs|
|
|
730
730
|
docs.each do |doc|
|
|
@@ -130,8 +130,20 @@ module OllamaChat::CollectionSearch
|
|
|
130
130
|
records.empty? and return
|
|
131
131
|
pre_rerank = records.size
|
|
132
132
|
records = rerank_records(content, records, prompt_name:)
|
|
133
|
-
log(
|
|
134
|
-
|
|
133
|
+
log(
|
|
134
|
+
:info,
|
|
135
|
+
'Trigger: %d/%d passed rerank for %s' % [ records.size, pre_rerank, collection ],
|
|
136
|
+
data: {
|
|
137
|
+
collection:,
|
|
138
|
+
prompt_name:,
|
|
139
|
+
records: records.map { |r|
|
|
140
|
+
{
|
|
141
|
+
text: r.text,
|
|
142
|
+
similarity: r.similarity&.round(4),
|
|
143
|
+
tags: r.tags_set.to_s(link: false)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
})
|
|
135
147
|
records.empty? and return
|
|
136
148
|
end
|
|
137
149
|
snippets = records.map { |record|
|
data/lib/ollama_chat/commands.rb
CHANGED
|
@@ -161,13 +161,13 @@ module OllamaChat::Commands
|
|
|
161
161
|
|
|
162
162
|
command(
|
|
163
163
|
name: :toggle,
|
|
164
|
-
regexp: %r(^/toggle(?:\s+(markdown|stream|location|runtime_info|voice|think_loud|think_strip|embedding)(?:\s+(-[yn]))?)?$),
|
|
165
|
-
complete: [ 'toggle', %w[ markdown stream location runtime_info voice think_loud think_strip embedding ] ],
|
|
164
|
+
regexp: %r(^/toggle(?:\s+(markdown|stream|location|runtime_info|voice|think_loud|think_strip|embedding|memory_trigger)(?:\s+(-[yn]))?)?$),
|
|
165
|
+
complete: [ 'toggle', %w[ markdown stream location runtime_info voice think_loud think_strip embedding memory_trigger ] ],
|
|
166
166
|
options: '[-y|-n]',
|
|
167
167
|
help: <<~EOT
|
|
168
168
|
🎛️ Toggle feature switches
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
(markdown, stream, location, runtime_info,
|
|
170
|
+
voice, think_loud, think_strip, embedding, memory_trigger)
|
|
171
171
|
Options: -y (on), -n (off)
|
|
172
172
|
EOT
|
|
173
173
|
) do |toggle_name, flag|
|
|
@@ -191,7 +191,7 @@ module OllamaChat::Commands
|
|
|
191
191
|
end
|
|
192
192
|
else
|
|
193
193
|
feedback(
|
|
194
|
-
"Available toggles: markdown|stream|location|runtime_info|voice|think_loud|think_strip|embedding"
|
|
194
|
+
"Available toggles: markdown|stream|location|runtime_info|voice|think_loud|think_strip|embedding|memory_trigger"
|
|
195
195
|
)
|
|
196
196
|
end
|
|
197
197
|
:next
|
|
@@ -391,14 +391,15 @@ module OllamaChat::Commands
|
|
|
391
391
|
|
|
392
392
|
command(
|
|
393
393
|
name: :conversation,
|
|
394
|
-
regexp: %r(^/conversation\s+(clean|compact|save|load|summarize|report)((?:\s+-[sc])*)(?:\s+([^-].*\.jsonl?))?$),
|
|
395
|
-
complete: [ 'conversation', %w[
|
|
394
|
+
regexp: %r(^/conversation\s+(clean|compact summary|compact|save|load|summarize|report)((?:\s+-[sc])*)(?:\s+([^-].*\.jsonl?))?$),
|
|
395
|
+
complete: [ 'conversation', %w[ compact clean report compact\ summary summarize save load ] ],
|
|
396
396
|
options: '[-s|-c] [FILENAME]',
|
|
397
397
|
help: <<~EOT
|
|
398
398
|
💾 Manage conversation content:
|
|
399
399
|
- save/load: Export/import as .json or .jsonl
|
|
400
400
|
- clean: Remove tool content, images, thinking
|
|
401
401
|
- compact: Summarize old messages, keep recent
|
|
402
|
+
- compact summary: Show last compaction summary
|
|
402
403
|
- summarize: Per-message narrative (-s sentence)
|
|
403
404
|
- report: Generate a session report document
|
|
404
405
|
EOT
|
|
@@ -426,16 +427,10 @@ module OllamaChat::Commands
|
|
|
426
427
|
else
|
|
427
428
|
feedback("Denied.", type: :denied)
|
|
428
429
|
end
|
|
430
|
+
when 'compact summary'
|
|
431
|
+
show_compaction_summary
|
|
429
432
|
when 'compact'
|
|
430
|
-
|
|
431
|
-
prompt: '🔔 Compact conversation? Old messages will be summarized. (y/n) ',
|
|
432
|
-
yes: /\Ay/i
|
|
433
|
-
)
|
|
434
|
-
then
|
|
435
|
-
compact_with_retry
|
|
436
|
-
else
|
|
437
|
-
feedback("Denied.", type: :denied)
|
|
438
|
-
end
|
|
433
|
+
compact_with_retry
|
|
439
434
|
when 'summarize'
|
|
440
435
|
opts = go_command('s', opts)
|
|
441
436
|
summarize_conversation(sentence: opts[?s])
|
|
@@ -648,12 +643,12 @@ module OllamaChat::Commands
|
|
|
648
643
|
|
|
649
644
|
command(
|
|
650
645
|
name: :collection,
|
|
651
|
-
regexp: %r(^/collection(?:\s+(change|clear|list|rename|update(?: all)?|new|edit|delete|query))?((?:\s+-[er])*)?$),
|
|
652
|
-
complete: [ 'collection', %w[ change clear list rename update update\ all new edit delete query ] ],
|
|
646
|
+
regexp: %r(^/collection(?:\s+(change|clear(?: (?:tags|sources))?|list|rename|update(?: all)?|new|edit|delete|query))?((?:\s+-[er])*)?$),
|
|
647
|
+
complete: [ 'collection', %w[ change clear\ tags clear\ sources clear list rename update update\ all new edit delete query ] ],
|
|
653
648
|
optional: true,
|
|
654
649
|
help: <<~EOT
|
|
655
650
|
📚 Manage RAG collections:
|
|
656
|
-
|
|
651
|
+
- change/clear/clear tags/clear sources/list/rename
|
|
657
652
|
- update: Re-index modified docs
|
|
658
653
|
- update all: Re-index all collections
|
|
659
654
|
- new: Interactively create a new collection
|
|
@@ -665,7 +660,11 @@ module OllamaChat::Commands
|
|
|
665
660
|
) do |subcommand, opts|
|
|
666
661
|
case subcommand
|
|
667
662
|
when 'clear'
|
|
668
|
-
|
|
663
|
+
clear_whole_collection
|
|
664
|
+
when 'clear tags'
|
|
665
|
+
clear_collection_tags
|
|
666
|
+
when 'clear sources'
|
|
667
|
+
clear_collection_sources
|
|
669
668
|
when 'change'
|
|
670
669
|
choose_collection(collection)
|
|
671
670
|
when 'list'
|
|
@@ -829,12 +828,23 @@ module OllamaChat::Commands
|
|
|
829
828
|
|
|
830
829
|
command(
|
|
831
830
|
name: :compose,
|
|
832
|
-
regexp: %r(^/compose
|
|
831
|
+
regexp: %r(^/compose(\s+-r)?\s*$),
|
|
832
|
+
options: '[-r]',
|
|
833
833
|
help: <<~EOT
|
|
834
834
|
\u270D Compose message in external editor
|
|
835
|
+
Options: -r pre-fill with quoted last assistant reply
|
|
835
836
|
EOT
|
|
836
|
-
) do
|
|
837
|
-
|
|
837
|
+
) do |opts|
|
|
838
|
+
opts = go_command('r', opts)
|
|
839
|
+
prefill = if opts[?r]
|
|
840
|
+
if msg = messages.find_last(content: true) { !_1.tool? && _1.role == 'assistant' }
|
|
841
|
+
msg.content.to_s.lines.map { "> #{_1}" }.join + "\n\n"
|
|
842
|
+
else
|
|
843
|
+
feedback('No assistant message to quote.', type: :warn)
|
|
844
|
+
next :next
|
|
845
|
+
end
|
|
846
|
+
end
|
|
847
|
+
edit_text(prefill).full? or :next
|
|
838
848
|
end
|
|
839
849
|
|
|
840
850
|
command(
|
|
@@ -21,7 +21,7 @@ module OllamaChat::Compaction
|
|
|
21
21
|
# @return [String] a short natural-language description of the call.
|
|
22
22
|
def tool_summary_line(tool_name, result)
|
|
23
23
|
default_summary = "was called."
|
|
24
|
-
klass = OllamaChat::Tools.
|
|
24
|
+
klass = OllamaChat::Tools.registered_class(tool_name)
|
|
25
25
|
klass&.summary_template(result:) || default_summary
|
|
26
26
|
rescue StandardError
|
|
27
27
|
default_summary
|
|
@@ -134,6 +134,33 @@ module OllamaChat::Compaction
|
|
|
134
134
|
false
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
+
# Displays the most recent compaction summary in the pager.
|
|
138
|
+
#
|
|
139
|
+
# Shows the narrative and the tool-call lookup index (the
|
|
140
|
+
# `lookup_group` entries with short UUIDs) carried in the summary
|
|
141
|
+
# message, prefixed with size metadata.
|
|
142
|
+
#
|
|
143
|
+
# @return [nil] always returns nil (command block handles :next).
|
|
144
|
+
def show_compaction_summary
|
|
145
|
+
unless msg = messages.find_summary
|
|
146
|
+
feedback('No compaction summary yet.', type: :info)
|
|
147
|
+
return
|
|
148
|
+
end
|
|
149
|
+
es = OllamaChat::TokenEstimator.estimate(msg.content.to_s)
|
|
150
|
+
use_pager do |output|
|
|
151
|
+
output.puts <<~EOT
|
|
152
|
+
#{bold{'Compaction Summary'}}
|
|
153
|
+
#{'─' * Tins::Terminal.columns}
|
|
154
|
+
|
|
155
|
+
#{kramdown_ansi_parse(msg.content.to_s)}
|
|
156
|
+
|
|
157
|
+
#{'─' * Tins::Terminal.columns}
|
|
158
|
+
Size: 👾#{es.bytes_formatted} 🧩#{es.tokens_formatted}
|
|
159
|
+
Tools: #{msg.tool_calls&.size || 0} lookup_group entries
|
|
160
|
+
EOT
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
137
164
|
private
|
|
138
165
|
|
|
139
166
|
# Serializes non-system messages into a readable block for the prompt.
|
|
@@ -172,7 +199,7 @@ module OllamaChat::Compaction
|
|
|
172
199
|
def build_tool_entries(messages)
|
|
173
200
|
messages.filter_map do |msg|
|
|
174
201
|
next unless tool_name = msg.tool_name.full?
|
|
175
|
-
next if
|
|
202
|
+
next if %w[ runtime_information trigger_inject ].include?(tool_name)
|
|
176
203
|
uuid = msg.group_uuid.to_s[-8..]
|
|
177
204
|
summary = OllamaChat::Compaction.tool_summary_line(
|
|
178
205
|
tool_name, msg.content.to_s
|
|
@@ -65,6 +65,27 @@ class OllamaChat::Database::Models::Session < Sequel::Model(OllamaChat::DB)
|
|
|
65
65
|
messages.to_s.count(?\n)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Returns the `enabled` flag of the first configured trigger entry.
|
|
69
|
+
#
|
|
70
|
+
# @return [Boolean, nil] true when the trigger is active, false when
|
|
71
|
+
# explicitly disabled, nil when no trigger is configured
|
|
72
|
+
def trigger_enabled?
|
|
73
|
+
trigger&.values&.first&.[]('enabled')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Sets the `enabled` flag of the first configured trigger entry and
|
|
77
|
+
# persists the change.
|
|
78
|
+
#
|
|
79
|
+
# No-op when no trigger is configured.
|
|
80
|
+
#
|
|
81
|
+
# @param value [Boolean] the new enabled state
|
|
82
|
+
def set_trigger_enabled(value)
|
|
83
|
+
if hash = trigger&.values&.first
|
|
84
|
+
hash['enabled'] = value
|
|
85
|
+
save
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
68
89
|
# @!attribute [v] id
|
|
69
90
|
# @return [Integer] The primary key for the session.
|
|
70
91
|
#
|
|
@@ -180,7 +180,7 @@ class OllamaChat::FollowChat
|
|
|
180
180
|
feedback(
|
|
181
181
|
("\n%s Execution of tool %s confirmed.\n\n" % [ symbol, bold { name } ])
|
|
182
182
|
)
|
|
183
|
-
result = OllamaChat::Tools.
|
|
183
|
+
result = OllamaChat::Tools.registered_tool(name, chat:).execute(tool_call)
|
|
184
184
|
chat.log(:info, "Tool execution confirmed", data: { tool: name, confirmed: })
|
|
185
185
|
end
|
|
186
186
|
|
|
@@ -327,22 +327,6 @@ module OllamaChat::Information
|
|
|
327
327
|
config.infobar.message.to_h
|
|
328
328
|
end
|
|
329
329
|
|
|
330
|
-
# Retrieves a hash of collection names and their descriptions from the
|
|
331
|
-
# database.
|
|
332
|
-
#
|
|
333
|
-
# This is used to provide context to the AI model about available RAG
|
|
334
|
-
# collections.
|
|
335
|
-
#
|
|
336
|
-
# @return [Hash{String => String}] a hash mapping collection names to their
|
|
337
|
-
# descriptions
|
|
338
|
-
def collection_descriptions
|
|
339
|
-
cols = models::Collection.where(enabled: true)
|
|
340
|
-
.select(:name, :description).order(:name)
|
|
341
|
-
cols.each_with_object({}) do |c, hash|
|
|
342
|
-
hash[c.name] = c.description
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
330
|
# Generates a hash containing static runtime information.
|
|
347
331
|
#
|
|
348
332
|
# This method collects session-level constants including the user,
|
|
@@ -353,11 +337,9 @@ module OllamaChat::Information
|
|
|
353
337
|
def static_runtime_information_values
|
|
354
338
|
{
|
|
355
339
|
client: ,
|
|
356
|
-
collections: JSON.pretty_generate(collection_descriptions),
|
|
357
340
|
current_directory: Pathname.pwd.expand_path.to_path,
|
|
358
341
|
languages: config.languages * ', ',
|
|
359
342
|
location: location.on?.full? { location_description } || 'n/a',
|
|
360
|
-
tool_paths_allowed: JSON.pretty_generate(tool_paths_allowed),
|
|
361
343
|
user: ,
|
|
362
344
|
}
|
|
363
345
|
end
|
|
@@ -369,7 +351,9 @@ module OllamaChat::Information
|
|
|
369
351
|
#
|
|
370
352
|
# @return [String] a formatted static runtime information string.
|
|
371
353
|
def static_runtime_information
|
|
372
|
-
prompt(:static_runtime_info).to_s
|
|
354
|
+
prompt(:static_runtime_info).to_s.named_placeholders_interpolate(
|
|
355
|
+
static_runtime_information_values
|
|
356
|
+
)
|
|
373
357
|
end
|
|
374
358
|
|
|
375
359
|
# Returns a formatted string representing the estimated text length of
|
|
@@ -423,7 +407,9 @@ module OllamaChat::Information
|
|
|
423
407
|
#
|
|
424
408
|
# @return [String] the formatted dynamic runtime information string.
|
|
425
409
|
def dynamic_runtime_information
|
|
426
|
-
prompt(:dynamic_runtime_info).to_s
|
|
410
|
+
prompt(:dynamic_runtime_info).to_s.named_placeholders_interpolate(
|
|
411
|
+
dynamic_runtime_information_values
|
|
412
|
+
)
|
|
427
413
|
end
|
|
428
414
|
|
|
429
415
|
# Injects the current dynamic runtime information (the "heartbeat")
|
|
@@ -56,8 +56,6 @@ prompts:
|
|
|
56
56
|
- Location: %{location}
|
|
57
57
|
- Current directory is "%{current_directory}"
|
|
58
58
|
- Client is %{client}.
|
|
59
|
-
- These tools have access to these allowed paths: %{tool_paths_allowed}
|
|
60
|
-
- Search in these collections with `search_knowledge`: %{collections}
|
|
61
59
|
dynamic_runtime_info: |
|
|
62
60
|
There is usually no reason to mention this information to the user unless
|
|
63
61
|
asked about it.
|
|
@@ -424,7 +422,7 @@ prompts:
|
|
|
424
422
|
To see the full output of any tool call above, use lookup_group
|
|
425
423
|
with the group UUID in parentheses.
|
|
426
424
|
system:
|
|
427
|
-
default: <%= OC::OLLAMA::CHAT::SYSTEM || "%{persona}\n\n%{runtime_info}".inspect %>
|
|
425
|
+
default: <%= OC::OLLAMA::CHAT::SYSTEM || "`persona_name`: %{persona_name}\n\n%{persona}\n\n%{runtime_info}".inspect %>
|
|
428
426
|
persona: |
|
|
429
427
|
`persona_name`: %{persona_name}
|
|
430
428
|
|
|
@@ -497,6 +495,10 @@ document_policy: importing
|
|
|
497
495
|
persona:
|
|
498
496
|
# Basename (without .md) of the default persona file in the personae directory.
|
|
499
497
|
default_name: personal_assistant
|
|
498
|
+
trigger:
|
|
499
|
+
enabled: true
|
|
500
|
+
prompt_name: memory_rerank
|
|
501
|
+
text_count: 3
|
|
500
502
|
parsing:
|
|
501
503
|
directory_structure_max_depth: 1
|
|
502
504
|
think:
|
data/lib/ollama_chat/pager.rb
CHANGED
|
@@ -12,14 +12,17 @@ module OllamaChat::Pager
|
|
|
12
12
|
# If the output would exceed the terminal's line capacity, it pipes the content
|
|
13
13
|
# through an appropriate pager command (like 'less' or 'more').
|
|
14
14
|
#
|
|
15
|
+
# @param force [Boolean] bypass the line-count threshold and always
|
|
16
|
+
# invoke the pager, regardless of output length.
|
|
15
17
|
# @yield A block that yields an IO object to write output to
|
|
16
18
|
# @yieldparam [IO] the IO object to write to
|
|
17
|
-
def use_pager
|
|
19
|
+
def use_pager(force: false)
|
|
18
20
|
command = determine_pager_command
|
|
19
21
|
output_buffer = StringIO.new
|
|
20
22
|
yield output_buffer
|
|
21
23
|
buffer = output_buffer.string
|
|
22
|
-
|
|
24
|
+
lines = force ? Float::INFINITY : buffer.count(?\n)
|
|
25
|
+
Kramdown::ANSI::Pager.pager(command:, lines:) do |output|
|
|
23
26
|
output.puts buffer
|
|
24
27
|
end
|
|
25
28
|
end
|