ollama_chat 0.0.122 → 0.0.124
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 +162 -0
- data/README.md +65 -9
- data/Rakefile +1 -2
- data/lib/ollama_chat/asr.rb +5 -5
- data/lib/ollama_chat/chat.rb +16 -14
- data/lib/ollama_chat/clipboard.rb +4 -4
- data/lib/ollama_chat/collection_search.rb +66 -0
- data/lib/ollama_chat/commands.rb +85 -59
- data/lib/ollama_chat/compaction.rb +32 -15
- data/lib/ollama_chat/config_handling.rb +13 -7
- data/lib/ollama_chat/conversation.rb +9 -5
- data/lib/ollama_chat/database/models/app_state.rb +7 -5
- data/lib/ollama_chat/database/models/session.rb +4 -2
- data/lib/ollama_chat/database/session_locking.rb +1 -1
- data/lib/ollama_chat/dialog.rb +8 -8
- data/lib/ollama_chat/favourites_management.rb +4 -4
- data/lib/ollama_chat/feedback.rb +41 -0
- data/lib/ollama_chat/file_editing.rb +5 -4
- data/lib/ollama_chat/follow_chat.rb +33 -28
- data/lib/ollama_chat/information.rb +31 -12
- data/lib/ollama_chat/input_content.rb +5 -5
- data/lib/ollama_chat/kramdown_ansi.rb +22 -11
- data/lib/ollama_chat/message_editing.rb +3 -3
- data/lib/ollama_chat/message_list.rb +69 -13
- data/lib/ollama_chat/message_output.rb +7 -7
- data/lib/ollama_chat/model_handling.rb +71 -45
- data/lib/ollama_chat/oc.rb +3 -1
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +8 -0
- data/lib/ollama_chat/parsing.rb +7 -7
- data/lib/ollama_chat/personae_management.rb +45 -27
- data/lib/ollama_chat/prompt_management.rb +54 -50
- data/lib/ollama_chat/rag_handling.rb +87 -25
- data/lib/ollama_chat/redis_cache.rb +1 -1
- data/lib/ollama_chat/server_socket.rb +1 -1
- data/lib/ollama_chat/session_management.rb +90 -86
- data/lib/ollama_chat/source_fetching.rb +7 -5
- data/lib/ollama_chat/speaker.rb +15 -1
- data/lib/ollama_chat/state_selectors.rb +3 -2
- data/lib/ollama_chat/switches.rb +1 -3
- data/lib/ollama_chat/system_prompt_management.rb +14 -2
- data/lib/ollama_chat/tool_calling.rb +5 -5
- data/lib/ollama_chat/tools/compute_bmi.rb +2 -2
- data/lib/ollama_chat/tools/concern.rb +1 -0
- data/lib/ollama_chat/tools/directory_structure.rb +6 -6
- data/lib/ollama_chat/tools/execute_grep.rb +4 -0
- data/lib/ollama_chat/tools/execute_shell.rb +1 -1
- data/lib/ollama_chat/tools/forget.rb +113 -0
- data/lib/ollama_chat/tools/memorize.rb +116 -0
- data/lib/ollama_chat/tools/roll_dice.rb +1 -1
- data/lib/ollama_chat/tools/run_tests.rb +1 -1
- data/lib/ollama_chat/tools/search_knowledge.rb +3 -59
- data/lib/ollama_chat/tools.rb +2 -0
- data/lib/ollama_chat/tts.rb +1 -1
- data/lib/ollama_chat/utils/audio_player.rb +1 -0
- data/lib/ollama_chat/version.rb +1 -1
- data/lib/ollama_chat/vim.rb +4 -2
- data/lib/ollama_chat/web_searching.rb +5 -5
- data/lib/ollama_chat.rb +2 -0
- data/ollama_chat.gemspec +6 -7
- data/spec/ollama_chat/asr_spec.rb +7 -7
- data/spec/ollama_chat/chat_spec.rb +2 -2
- data/spec/ollama_chat/clipboard_spec.rb +3 -3
- data/spec/ollama_chat/commands_spec.rb +26 -19
- data/spec/ollama_chat/compaction_spec.rb +21 -15
- data/spec/ollama_chat/config_handling_spec.rb +9 -12
- data/spec/ollama_chat/conversation_spec.rb +17 -18
- data/spec/ollama_chat/favourites_management_spec.rb +6 -6
- data/spec/ollama_chat/file_editing_spec.rb +3 -3
- data/spec/ollama_chat/follow_chat_spec.rb +3 -1
- data/spec/ollama_chat/http_handling_spec.rb +10 -10
- data/spec/ollama_chat/information_spec.rb +4 -4
- data/spec/ollama_chat/input_content_spec.rb +1 -1
- data/spec/ollama_chat/kramdown_ansi_spec.rb +60 -0
- data/spec/ollama_chat/message_editing_spec.rb +5 -5
- data/spec/ollama_chat/message_list_spec.rb +76 -2
- data/spec/ollama_chat/message_output_spec.rb +7 -7
- data/spec/ollama_chat/prompt_management_spec.rb +12 -14
- data/spec/ollama_chat/rag_handling_spec.rb +31 -32
- data/spec/ollama_chat/session_management_spec.rb +32 -18
- data/spec/ollama_chat/source_fetching_spec.rb +2 -2
- data/spec/ollama_chat/speaker_spec.rb +92 -0
- data/spec/ollama_chat/state_selectors_spec.rb +1 -1
- data/spec/ollama_chat/system_prompt_management_spec.rb +4 -4
- data/spec/ollama_chat/think_control_spec.rb +2 -2
- data/spec/ollama_chat/tool_calling_spec.rb +4 -4
- data/spec/ollama_chat/tools/execute_shell_spec.rb +7 -7
- data/spec/ollama_chat/tools/forget_spec.rb +144 -0
- data/spec/ollama_chat/tools/memorize_spec.rb +204 -0
- data/spec/ollama_chat/tools/search_knowledge_spec.rb +8 -8
- data/spec/ollama_chat/tts_spec.rb +15 -21
- data/spec/ollama_chat/utils/audio_player_spec.rb +5 -3
- data/spec/ollama_chat/web_searching_spec.rb +2 -2
- metadata +17 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d2664dce7c6742ff5c950e64330b84325bcbb573467edde9aceddc3fa209641
|
|
4
|
+
data.tar.gz: 87baa515acb398c9da1b7cf6c7fce173d946e4bd4d79ad0f1eb9dfbd2526235a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a091addc87c893f700f405147386dc8fe8fcc5c3134ad12bb1ffda570ec8a0f64ac4acbaeaed70116a6c61d0765e14e2f085fa8d2c0b98496fb0881a56fdb0f8
|
|
7
|
+
data.tar.gz: 6d078a9c69b50719dda02e9c81a32d51929627ab6e50c7cae023630543e717dd2c1a86166495f339875178108e0ded60f9f451ebbec1275f16f06771c9b1b215
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,167 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-02 v0.0.124
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
* `OllamaChat::Feedback` module to replace raw `STDOUT.puts` and
|
|
8
|
+
`STDERR.puts` calls with typed, testable system notifications.
|
|
9
|
+
* Supports types: `:success`, `:cancel`, `:denied`, `:warn`, `:info`,
|
|
10
|
+
`:alarm`.
|
|
11
|
+
* Integrates with `use_pager` and handles newline formatting via
|
|
12
|
+
`output.print`.
|
|
13
|
+
* `memorize` tool to embed timestamped entries into per-persona
|
|
14
|
+
`memory-<persona_name>` Documentrix collections.
|
|
15
|
+
* `forget` tool to clear a single memory record by its ISO-8601 timestamp
|
|
16
|
+
tag.
|
|
17
|
+
* `/collection query` subcommand to debug collections, supporting optional
|
|
18
|
+
`-e` (edit) and `-r` (rerank) flags.
|
|
19
|
+
* `/config env` subcommand to display the Ollama Chat environment variable
|
|
20
|
+
tree using `OC.view`.
|
|
21
|
+
* `/last -v` flag to voice previous assistant messages via
|
|
22
|
+
`MessageList#speak_last`.
|
|
23
|
+
* `OllamaChat::CollectionSearch` module extracted from `SearchKnowledge`
|
|
24
|
+
tool, providing `find_document_records` and `rerank_records` methods mixed
|
|
25
|
+
into `Chat`.
|
|
26
|
+
* `refresh_system_prompt` method in `SystemPromptManagement` to
|
|
27
|
+
re-interpolate the active system prompt with fresh `persona` and
|
|
28
|
+
`runtime_info` values after collection mutations.
|
|
29
|
+
* Voice announcement in the compaction report, including
|
|
30
|
+
`context_filled_before`, `context_filled_after`, and `duration` in
|
|
31
|
+
`Compaction::Result`.
|
|
32
|
+
* `Speaker#wait_for_speaker` method to join the speaker thread and block
|
|
33
|
+
until completion.
|
|
34
|
+
* `spec/ollama_chat/speaker_spec.rb` with tests for `OllamaChat::Speaker`.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
* Replaced `str % {…}` with `named_placeholders_interpolate({…})` for
|
|
39
|
+
DB-prompt call sites to handle unknown placeholders gracefully.
|
|
40
|
+
* Updated `directory_structure` tool description from "Tree viewer" to "File
|
|
41
|
+
locator" and added guidance to prefer it over shell `find` or `ls -R`.
|
|
42
|
+
* Routed prompt change feedback through the `chat` instance in `app_state.rb`
|
|
43
|
+
to ensure messages target the active chat session.
|
|
44
|
+
* Switched spec stubs from `allow` to `expect` in `http_handling_spec.rb`,
|
|
45
|
+
`message_list_spec.rb`, `execute_shell_spec.rb`, `tts_spec.rb`,
|
|
46
|
+
`compaction_spec.rb`, `audio_player_spec.rb`, and `asr_spec.rb` to enforce
|
|
47
|
+
required calls.
|
|
48
|
+
* Bumped `const_conf` dependency from `~> **0.3**` to `~> **0.9**`.
|
|
49
|
+
* Updated `rerank_records` to accept an optional `prompt_name:` keyword
|
|
50
|
+
argument.
|
|
51
|
+
* Improved new session name generation by extracting
|
|
52
|
+
`new_random_session_name` into `SessionManagement` and handling `nil`
|
|
53
|
+
cancellation in `determine_valid_new_name_for_session`.
|
|
54
|
+
* Allowed naming new sessions via `choose_session` by threading an optional
|
|
55
|
+
`name:` keyword through `new_session` and `Session.with_defaults`.
|
|
56
|
+
* Logged stored memory text in the `memorize` tool by adding `text:` to the
|
|
57
|
+
`chat.log` data hash.
|
|
58
|
+
* Extracted context usage helpers `context_usage_colored` and
|
|
59
|
+
`context_percentage` to eliminate duplicated format logic.
|
|
60
|
+
* Updated `output_eval_stats` in `follow_chat.rb` to print colored context
|
|
61
|
+
usage.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
* Fixed indentation bug in `model_handling.rb` import/export by changing
|
|
66
|
+
`sub` to `gsub`.
|
|
67
|
+
* Guarded source link rendering in `search_knowledge` against `nil` or empty
|
|
68
|
+
`source` values.
|
|
69
|
+
* Suppressed `report_on_exception` on `AudioPlayer` background thread.
|
|
70
|
+
|
|
71
|
+
## 2026-09-25 v0.0.123
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
* README section 5 documenting `/conversation compact`: token-aware
|
|
76
|
+
keep-recent budget, safe & retryable behavior, visible before/after
|
|
77
|
+
metrics, and iterative re-compaction.
|
|
78
|
+
* Three-step context escalation ladder in the README: `/conversation
|
|
79
|
+
compact` first, then `/conversation report` + `/clear` + `/input path`
|
|
80
|
+
as the preferred second step, and `/conversation clean` as the emergency
|
|
81
|
+
exit.
|
|
82
|
+
* `execute_shell` tool to the Filesystem row in the README, noted as running
|
|
83
|
+
shell commands as a last resort.
|
|
84
|
+
* `execute_jira_twg` tool to the Web/External row in the README for running
|
|
85
|
+
Jira CLI queries via `twg`.
|
|
86
|
+
* `lookup_group` tool to the Knowledge row in the README for retrieving prior
|
|
87
|
+
conversation groups by UUID.
|
|
88
|
+
* Speech Services (ASR) section documenting `OLLAMA_CHAT_ASR_URL`,
|
|
89
|
+
`OLLAMA_CHAT_ASR_CONVERT_COMMAND`, and `OLLAMA_CHAT_ASR_MODEL`.
|
|
90
|
+
* Audio Playback section documenting `OLLAMA_CHAT_AUDIO_PLAYER_CONFIG`.
|
|
91
|
+
* Invidious (YouTube Proxy) section documenting `OLLAMA_CHAT_INVIDIOUS_URL`,
|
|
92
|
+
`OLLAMA_CHAT_INVIDIOUS_COMPANION_KEY`, and
|
|
93
|
+
`OLLAMA_CHAT_INVIDIOUS_CAPTION_LANGUAGES`.
|
|
94
|
+
* `markdown:` keyword argument (default `true`) to
|
|
95
|
+
`kramdown_markdown_remove`; when `false`, skips the `kramdown_ansi_parse`
|
|
96
|
+
step while still removing emoji, ANSI, and box-drawing characters.
|
|
97
|
+
* Explanatory comment block to `eval_template` in
|
|
98
|
+
`lib/ollama_chat/tools/execute_grep.rb` clarifying that the `cmd` config
|
|
99
|
+
value is a Ruby string template whose `#{...}` interpolations are resolved
|
|
100
|
+
against the method's local parameters via `eval`.
|
|
101
|
+
* `cleaned` string prefix in `save_conversation` so the `STDOUT`/`STDERR`
|
|
102
|
+
confirmation messages read "Saved cleaned conversation to…" when `clean:
|
|
103
|
+
true` is passed.
|
|
104
|
+
* "Cancelled." message when the user skips saving in conversation report and
|
|
105
|
+
summarize flows.
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
* Renamed `report_session` to `generate_conversation_report` to clarify it
|
|
110
|
+
only builds the report text.
|
|
111
|
+
* Reworked `report_conversation` to always display in the pager first, then
|
|
112
|
+
optionally save to a file; removed the `save:` keyword argument.
|
|
113
|
+
* Reworked `summarize_conversation` in `session_management.rb` to always
|
|
114
|
+
render via `use_pager` first, then optionally save via `ask_for_filename?`
|
|
115
|
+
and `should_overwrite?`.
|
|
116
|
+
* Removed the `save:` keyword argument from `summarize_conversation` and the
|
|
117
|
+
`-f` flag from the `/conversation` command dispatch in `commands.rb`.
|
|
118
|
+
* Tightened the `/conversation` regex from `(?:[sf]|c)` to `[sc]` and updated
|
|
119
|
+
the `options:` help text to drop `-f save`.
|
|
120
|
+
* Changed "Nothing to summarize!" and "Nothing to report!" output from
|
|
121
|
+
`STDERR` to `STDOUT`.
|
|
122
|
+
* `kramdown_markdown_remove` now strips `\p{Extended_Pictographic}` emoji
|
|
123
|
+
before any further processing, preventing TTS engines from vocalizing them.
|
|
124
|
+
* `kramdown_markdown_remove` in `lib/ollama_chat/kramdown_ansi.rb` now strips
|
|
125
|
+
Unicode box-drawing characters (`U+2500`..`U+257F`) that kramdown renders
|
|
126
|
+
as table borders, preventing TTS engines from stammering on them.
|
|
127
|
+
* Collapses resulting multi-space runs and strips leading/trailing whitespace
|
|
128
|
+
in `kramdown_markdown_remove`.
|
|
129
|
+
* Moved the `kramdown_markdown_remove` call from `flush_buffer` into
|
|
130
|
+
`enqueue_tts` in `lib/ollama_chat/tts.rb` so all enqueue paths are covered,
|
|
131
|
+
passing `markdown: @chat.markdown.on?`.
|
|
132
|
+
* `multipart_form_data` in `lib/ollama_chat/asr.rb` now returns a hash
|
|
133
|
+
containing only `headers:`, `expects:`, and `body:`, which are the actual
|
|
134
|
+
Excon request options, instead of merging `rest` (`model:`, `language:`)
|
|
135
|
+
into the returned options hash.
|
|
136
|
+
* Updated YARD documentation to reflect the new parameter and emoji stripping
|
|
137
|
+
behavior.
|
|
138
|
+
* Updated `spec/ollama_chat/asr_spec.rb` expectations from
|
|
139
|
+
`hash_including(model: ...)` / `hash_including(language: ...)` to
|
|
140
|
+
`hash_including(body: kind_of(String))` to match the new option shape.
|
|
141
|
+
* Updated `commands_spec.rb` to remove the obsolete `/conversation summarize
|
|
142
|
+
-f` and `/conversation report -f` specs and drop `save:` from expectations.
|
|
143
|
+
* Updated `session_management_spec.rb` for the new show-then-save flow,
|
|
144
|
+
`STDOUT` stream, and `Cancelled.` expectation.
|
|
145
|
+
* Updated the corresponding expectation in `conversation_spec.rb` to match
|
|
146
|
+
the new message text.
|
|
147
|
+
* Renamed former section 5 "Session Reports" to section 6 "Conversation
|
|
148
|
+
Reports" to match the actual command name.
|
|
149
|
+
* Updated Conversation Archiving section from `/session summarize` to
|
|
150
|
+
`/conversation summarize`, removed obsolete `-f` flag reference, and
|
|
151
|
+
described the show-then-save flow.
|
|
152
|
+
|
|
153
|
+
### Fixed
|
|
154
|
+
* Fixed `TTS_URL` to `OLLAMA_CHAT_TTS_URL` to match the actual env var name
|
|
155
|
+
in `oc.rb`.
|
|
156
|
+
* Wrapped `@prefix` with `Regexp.quote()` in `RedisCache#unpre` to ensure the
|
|
157
|
+
prefix is always matched as a literal string.
|
|
158
|
+
* Fixed typos in height validation error message.
|
|
159
|
+
|
|
160
|
+
### Removed
|
|
161
|
+
* `context_spook` from development dependencies in `Rakefile` and
|
|
162
|
+
`ollama_chat.gemspec`.
|
|
163
|
+
* The `-f` flag from the `/report` command in `commands.rb`.
|
|
164
|
+
|
|
3
165
|
## 2026-09-25 v0.0.122
|
|
4
166
|
|
|
5
167
|
## Features
|
data/README.md
CHANGED
|
@@ -62,7 +62,7 @@ The following environment variables can be used to configure behavior:
|
|
|
62
62
|
- `OLLAMA_URL` - Base URL for Ollama server (default: `http://localhost:11434`)
|
|
63
63
|
- `OLLAMA_HOST` - Base hostname for Ollama server (default: `localhost:11434`)
|
|
64
64
|
- `OLLAMA_SEARXNG_URL` - SearxNG search endpoint URL
|
|
65
|
-
- `
|
|
65
|
+
- `OLLAMA_CHAT_TTS_URL` - Base URL for the [audio.cpp](https://github.com/0xshug0/audio.cpp) TTS server (default: `http://localhost:8880`)
|
|
66
66
|
|
|
67
67
|
#### Chat Settings
|
|
68
68
|
- `OLLAMA_CHAT_MODEL` - Default model to use (e.g., `llama3.1`)
|
|
@@ -75,6 +75,19 @@ The following environment variables can be used to configure behavior:
|
|
|
75
75
|
- `OLLAMA_CHAT_LOG_DATABASE` - Database log file path (default: `$XDG_STATE_HOME/database.log`)
|
|
76
76
|
- `OLLAMA_CHAT_LOG_TAIL_LINES` - Max lines to retain in log files (default: `10000`)
|
|
77
77
|
|
|
78
|
+
#### Speech Services (ASR)
|
|
79
|
+
- `OLLAMA_CHAT_ASR_URL` - Base URL for the ASR (Speech-to-Text) service (default: `http://localhost:8880`)
|
|
80
|
+
- `OLLAMA_CHAT_ASR_CONVERT_COMMAND` - Shell command template to convert video to 16 kHz mono PCM WAV; use `%{input}` / `%{output}` as placeholders (default: `ffmpeg -y -i %{input} -vn -acodec pcm_s16le -ar 16000 -ac 1 %{output}`)
|
|
81
|
+
- `OLLAMA_CHAT_ASR_MODEL` - ASR model identifier (default: `qwen3-asr-1.7b`)
|
|
82
|
+
|
|
83
|
+
#### Audio Playback
|
|
84
|
+
- `OLLAMA_CHAT_AUDIO_PLAYER_CONFIG` - JSON object with `command`, `frequency`, `bits`, `pause` keys controlling the ffplay-based TTS audio player
|
|
85
|
+
|
|
86
|
+
#### Invidious (YouTube Proxy)
|
|
87
|
+
- `OLLAMA_CHAT_INVIDIOUS_URL` - Base URL for an Invidious instance
|
|
88
|
+
- `OLLAMA_CHAT_INVIDIOUS_COMPANION_KEY` - Bearer token for the Invidious companion player API (required when `URL` is set)
|
|
89
|
+
- `OLLAMA_CHAT_INVIDIOUS_CAPTION_LANGUAGES` - JSON array of language-code regexes for caption selection priority (default: `["\\Aen\\z","\\Aen-","\\Ade\\z","\\Ade-"]`)
|
|
90
|
+
|
|
78
91
|
#### Tool Configuration
|
|
79
92
|
- `OLLAMA_CHAT_TOOLS_TEST_RUNNER` - Configured test runner for `run_tests` (default: `rspec`)
|
|
80
93
|
- `OLLAMA_CHAT_TOOLS_CTAGS_TOOL` - Path to the ctags tool
|
|
@@ -243,14 +256,57 @@ switch. The profile system allows you to manage "Live" vs "Saved" settings:
|
|
|
243
256
|
"bake" those live settings into a permanent profile using `options from
|
|
244
257
|
session`.
|
|
245
258
|
|
|
246
|
-
#### 4. Conversation Archiving (`/
|
|
259
|
+
#### 4. Conversation Archiving (`/conversation summarize`)
|
|
247
260
|
|
|
248
261
|
Turn your long-form brainstorming sessions into structured documents. The
|
|
249
|
-
`/
|
|
250
|
-
summary.
|
|
262
|
+
`/conversation summarize` command distills an entire conversation into a
|
|
263
|
+
concise summary, displayed in the pager first, then optionally saved.
|
|
251
264
|
* **Quick View**: Use `-s` for a one-sentence executive summary.
|
|
252
|
-
* **Archiving**:
|
|
253
|
-
Markdown file, creating an automatic journal
|
|
265
|
+
* **Archiving**: After the summary is displayed, you are prompted for a
|
|
266
|
+
filename to save it as a Markdown file, creating an automatic journal
|
|
267
|
+
of your project's evolution.
|
|
268
|
+
|
|
269
|
+
#### 5. Context Compaction (`/conversation compact`)
|
|
270
|
+
|
|
271
|
+
Long sessions inevitably fill up the model's context window. The
|
|
272
|
+
`/conversation compact` command summarizes older messages into a single
|
|
273
|
+
compact summary while preserving recent exchanges, freeing up space for
|
|
274
|
+
continued work.
|
|
275
|
+
|
|
276
|
+
* **Token-aware**: The keep-recent budget is derived from the active
|
|
277
|
+
model's context length, so it adapts automatically.
|
|
278
|
+
* **Safe & retryable**: If the LLM summarization fails, the message list
|
|
279
|
+
is left untouched and you can simply retry.
|
|
280
|
+
* **Visible metrics**: After compaction, a report shows summarized
|
|
281
|
+
message count, summary size, and context usage before/after.
|
|
282
|
+
* **Iterative**: Repeated compactions merge into the existing summary
|
|
283
|
+
rather than stacking multiple summary messages.
|
|
284
|
+
|
|
285
|
+
Run it whenever context usage climbs into the red zone (visible in the
|
|
286
|
+
runtime info gauge) — the model stays sharp and the conversation keeps
|
|
287
|
+
flowing.
|
|
288
|
+
|
|
289
|
+
If compaction alone isn't enough, a practical escalation ladder:
|
|
290
|
+
|
|
291
|
+
1. **`/conversation compact`** — summarize old messages, keep recent tail.
|
|
292
|
+
Try this first; it's the least destructive.
|
|
293
|
+
2. **`/conversation report`** → **`/clear`** → **`/input path
|
|
294
|
+
standup.md`** — generate a standup-style report, save it, clear
|
|
295
|
+
the messages, then feed the report back as context. Do this
|
|
296
|
+
before `clean`, because `clean` strips the tool output and
|
|
297
|
+
thinking that make a good report.
|
|
298
|
+
3. **`/conversation clean`** — strips tool results, images, and
|
|
299
|
+
thinking content from all messages. More radical, but the
|
|
300
|
+
conversation structure and text remain intact. The emergency
|
|
301
|
+
exit: if context is so stuffed that even a report can't fit,
|
|
302
|
+
`clean` carves out enough room for anything to work again.
|
|
303
|
+
|
|
304
|
+
#### 6. Conversation Reports (`/conversation report`)
|
|
305
|
+
|
|
306
|
+
Generate a structured report from your conversation using configurable
|
|
307
|
+
prompt templates. The report is displayed in the pager first, then
|
|
308
|
+
optionally saved to a file. Particularly useful for daily standup summaries
|
|
309
|
+
— run it at the end of the day and save the output for your team sync.
|
|
254
310
|
|
|
255
311
|
### Using a Persona
|
|
256
312
|
|
|
@@ -467,12 +523,12 @@ context, manipulate files, and retrieve external information.
|
|
|
467
523
|
|
|
468
524
|
| Category | Tools | Description |
|
|
469
525
|
| :--- | :--- | :--- |
|
|
470
|
-
| **Filesystem** | `read_file`, `write_file`, `patch_file`, `delete_file`, `move_file`, `directory_structure`, `execute_grep` | Read, write, and search files within allowed directories. |
|
|
526
|
+
| **Filesystem** | `read_file`, `write_file`, `patch_file`, `delete_file`, `move_file`, `directory_structure`, `execute_grep`, `execute_shell` | Read, write, and search files within allowed directories; run shell commands as a last resort. |
|
|
471
527
|
| **Ruby/Dev** | `resolve_tag`, `execute_ri`, `gem_path_lookup`, `run_tests`, `eval_ruby` | Introspect Ruby code, check documentation, and run test suites. |
|
|
472
|
-
| **Web/External** | `search_web`, `get_url`, `browse`, `get_rfc`, `get_cve`, `get_endoflife`, `get_ghr`, `get_jira_issue` | Access the internet, fetch specific URLs, and look up technical standards
|
|
528
|
+
| **Web/External** | `search_web`, `get_url`, `browse`, `get_rfc`, `get_cve`, `get_endoflife`, `get_ghr`, `get_jira_issue`, `execute_jira_twg` | Access the internet, fetch specific URLs, and look up technical standards; run Jira CLI queries via `twg`. |
|
|
473
529
|
| **System/Util** | `get_time`, `get_location`, `get_current_weather`, `generate_password`, `compute_bmi`, `roll_dice` | General utility functions for time, location, and simple calculations. |
|
|
474
530
|
| **Editor/Clip** | `copy_to_clipboard`, `paste_from_clipboard`, `paste_into_editor`, `open_file_in_editor` | Bridge the gap between the chat and the system clipboard or editor. |
|
|
475
|
-
| **Knowledge** | `search_knowledge`, `file_context` | Semantic search for specific snippets
|
|
531
|
+
| **Knowledge** | `search_knowledge`, `file_context`, `lookup_group` | Semantic search for specific snippets, broad retrieval of structured project context, or retrieving prior message groups by UUID. |
|
|
476
532
|
| **Multimodal** | `generate_image` | Generate images via a local ComfyUI server. |
|
|
477
533
|
|
|
478
534
|
***Note on Knowledge Tools**: Use `search_knowledge` for precise,
|
data/Rakefile
CHANGED
|
@@ -55,7 +55,7 @@ GemHadar do
|
|
|
55
55
|
dependency 'pdf-reader', '~> 2.0'
|
|
56
56
|
dependency 'bigdecimal', '~> 3.1'
|
|
57
57
|
dependency 'csv', '~> 3.0'
|
|
58
|
-
dependency 'const_conf', '~> 0.
|
|
58
|
+
dependency 'const_conf', '~> 0.9'
|
|
59
59
|
dependency 'context_spook', '~> 1.6'
|
|
60
60
|
dependency 'infobar', '>= 0.13.1'
|
|
61
61
|
dependency 'rubyzip', '~> 3.0'
|
|
@@ -68,7 +68,6 @@ GemHadar do
|
|
|
68
68
|
development_dependency 'webmock'
|
|
69
69
|
development_dependency 'debug'
|
|
70
70
|
development_dependency 'simplecov'
|
|
71
|
-
development_dependency 'context_spook'
|
|
72
71
|
development_dependency 'utils'
|
|
73
72
|
|
|
74
73
|
licenses << 'MIT'
|
data/lib/ollama_chat/asr.rb
CHANGED
|
@@ -38,11 +38,11 @@ module OllamaChat
|
|
|
38
38
|
executable = Shellwords.split(cmd).first
|
|
39
39
|
result = system(cmd, out: File::NULL, err: File::NULL)
|
|
40
40
|
if result.nil?
|
|
41
|
-
|
|
41
|
+
chat.feedback("ASR: #{executable} not found in PATH.", type: :warn)
|
|
42
42
|
return
|
|
43
43
|
end
|
|
44
44
|
unless File.size(wav.path) > 0
|
|
45
|
-
|
|
45
|
+
chat.feedback("ASR: #{executable} produced no output.", type: :warn)
|
|
46
46
|
return
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -61,7 +61,7 @@ module OllamaChat
|
|
|
61
61
|
result = JSON.parse(response.body) rescue nil
|
|
62
62
|
end
|
|
63
63
|
chat.log(:error, e, data: { status:, result: })
|
|
64
|
-
|
|
64
|
+
chat.feedback("ASR transcription failed: #{e.message}", type: :warn)
|
|
65
65
|
nil
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -99,10 +99,10 @@ module OllamaChat
|
|
|
99
99
|
body << Excon::CR_NL
|
|
100
100
|
body << "--#{boundary}--" << Excon::CR_NL
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
{
|
|
103
103
|
headers: { 'Content-Type' => %{multipart/form-data; boundary="#{boundary}"} },
|
|
104
104
|
expects: 200,
|
|
105
|
-
body
|
|
105
|
+
body: ,
|
|
106
106
|
}
|
|
107
107
|
end
|
|
108
108
|
end
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -34,6 +34,7 @@ require 'zlib'
|
|
|
34
34
|
class OllamaChat::Chat
|
|
35
35
|
include Tins::GO
|
|
36
36
|
include Term::ANSIColor
|
|
37
|
+
include OllamaChat::Feedback
|
|
37
38
|
include OllamaChat::TokenEstimator
|
|
38
39
|
include OllamaChat::HTTPHandling
|
|
39
40
|
include OllamaChat::Commands
|
|
@@ -64,6 +65,7 @@ class OllamaChat::Chat
|
|
|
64
65
|
include OllamaChat::ConfigHandling
|
|
65
66
|
include OllamaChat::PersonaeManagement
|
|
66
67
|
include OllamaChat::SessionManagement
|
|
68
|
+
include OllamaChat::CollectionSearch
|
|
67
69
|
include OllamaChat::RAGHandling
|
|
68
70
|
include OllamaChat::FavouritesManagement
|
|
69
71
|
include OllamaChat::PromptHandling
|
|
@@ -195,7 +197,7 @@ class OllamaChat::Chat
|
|
|
195
197
|
abort "Failed to use to model: #{e}"
|
|
196
198
|
end
|
|
197
199
|
|
|
198
|
-
|
|
200
|
+
feedback ?\n
|
|
199
201
|
|
|
200
202
|
setup_persona_from_session
|
|
201
203
|
setup_system_prompt
|
|
@@ -203,7 +205,7 @@ class OllamaChat::Chat
|
|
|
203
205
|
print_welcome
|
|
204
206
|
info_session
|
|
205
207
|
|
|
206
|
-
|
|
208
|
+
feedback("\nType /help to display the chat help.")
|
|
207
209
|
|
|
208
210
|
interact_with_user
|
|
209
211
|
end
|
|
@@ -434,19 +436,19 @@ class OllamaChat::Chat
|
|
|
434
436
|
case what
|
|
435
437
|
when 'messages', nil
|
|
436
438
|
messages.clear
|
|
437
|
-
|
|
439
|
+
feedback("Cleared messages.", type: :info)
|
|
438
440
|
when 'links'
|
|
439
441
|
links.clear
|
|
440
|
-
|
|
442
|
+
feedback("Cleared links.", type: :info)
|
|
441
443
|
when 'history'
|
|
442
444
|
clear_history
|
|
443
|
-
|
|
445
|
+
feedback("Cleared history.", type: :info)
|
|
444
446
|
when 'tags'
|
|
445
447
|
@documents.clear
|
|
446
|
-
|
|
448
|
+
feedback("Cleared all tags.", type: :info)
|
|
447
449
|
when 'images'
|
|
448
450
|
messages.clear_images
|
|
449
|
-
|
|
451
|
+
feedback("Cleared all images.", type: :info)
|
|
450
452
|
when 'all'
|
|
451
453
|
if confirm?(
|
|
452
454
|
prompt: '🔔 Are you sure to clear messages and collection? (y/n) ',
|
|
@@ -457,9 +459,9 @@ class OllamaChat::Chat
|
|
|
457
459
|
@documents.clear
|
|
458
460
|
links.clear
|
|
459
461
|
clear_history
|
|
460
|
-
|
|
462
|
+
feedback("Cleared messages and collection #{bold{collection}}.", type: :info)
|
|
461
463
|
else
|
|
462
|
-
|
|
464
|
+
feedback("Denied.", type: :denied)
|
|
463
465
|
end
|
|
464
466
|
end
|
|
465
467
|
persona_profile
|
|
@@ -517,7 +519,7 @@ class OllamaChat::Chat
|
|
|
517
519
|
type = message.type.full?(:to_sym) || :socket_input
|
|
518
520
|
content = message.content
|
|
519
521
|
@parse_content = message.parse
|
|
520
|
-
|
|
522
|
+
feedback color(112) { "Received a server socket message. Processing now…" }, type: :info
|
|
521
523
|
else
|
|
522
524
|
raise
|
|
523
525
|
end
|
|
@@ -619,13 +621,13 @@ class OllamaChat::Chat
|
|
|
619
621
|
msg = "Currently lost connection to ollama server and cannot send command."
|
|
620
622
|
log(:warn, msg, warn: true)
|
|
621
623
|
rescue Interrupt
|
|
622
|
-
|
|
624
|
+
feedback("Type /quit to quit.")
|
|
623
625
|
ensure
|
|
624
626
|
self.server_socket_message = nil
|
|
625
627
|
end
|
|
626
628
|
0
|
|
627
629
|
rescue OllamaChat::OllamaChatQuitError
|
|
628
|
-
|
|
630
|
+
feedback("Goodbye.")
|
|
629
631
|
rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
|
|
630
632
|
log(:error, e)
|
|
631
633
|
fix_config(e)
|
|
@@ -718,7 +720,7 @@ class OllamaChat::Chat
|
|
|
718
720
|
# @note Progress is reported to STDOUT during processing
|
|
719
721
|
def add_documents_from_argv(document_list)
|
|
720
722
|
if document_list.any?(&:empty?)
|
|
721
|
-
|
|
723
|
+
feedback("Clearing collection #{bold{documents.collection}}.", type: :info)
|
|
722
724
|
documents.clear
|
|
723
725
|
document_list.reject!(&:empty?)
|
|
724
726
|
end
|
|
@@ -730,7 +732,7 @@ class OllamaChat::Chat
|
|
|
730
732
|
File.expand_path(doc)
|
|
731
733
|
end
|
|
732
734
|
end
|
|
733
|
-
|
|
735
|
+
feedback("Collection #{bold{documents.collection}}: Adding #{document_list.size} documents…", type: :info)
|
|
734
736
|
count = 1
|
|
735
737
|
document_list.each_slice(25) do |docs|
|
|
736
738
|
docs.each do |doc|
|
|
@@ -116,11 +116,11 @@ module OllamaChat::Clipboard
|
|
|
116
116
|
text = last_message_content(content: false)
|
|
117
117
|
perform_copy_to_clipboard(text:, edit:)
|
|
118
118
|
log(:info, "Copied to clipboard", data: { bytes: format_bytes(text.bytesize) }) if text
|
|
119
|
-
|
|
119
|
+
feedback("The last response has been successfully copied to the system clipboard.", type: :info)
|
|
120
120
|
true
|
|
121
121
|
rescue OllamaChat::OllamaChatError => e
|
|
122
122
|
log(:error, e, data: { method: __method__ })
|
|
123
|
-
|
|
123
|
+
feedback(e.message, type: :warn)
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
# Pastes content from the system clipboard into the chat.
|
|
@@ -137,11 +137,11 @@ module OllamaChat::Clipboard
|
|
|
137
137
|
def paste_from_clipboard(edit: false)
|
|
138
138
|
result = perform_paste_from_clipboard(edit:)
|
|
139
139
|
log(:info, "Pasted from clipboard", data: { bytes: format_bytes(result.bytesize) }) if result
|
|
140
|
-
|
|
140
|
+
feedback("The clipboard content has been successfully copied to the chat.", type: :info)
|
|
141
141
|
result
|
|
142
142
|
rescue OllamaChat::OllamaChatError => e
|
|
143
143
|
log(:error, e, data: { method: __method__ })
|
|
144
|
-
|
|
144
|
+
feedback(e.message, type: :warn)
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
# Read the full text from STDIN and return it.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Shared collection search primitives for document retrieval and LLM
|
|
2
|
+
# reranking.
|
|
3
|
+
#
|
|
4
|
+
# Extracted from {OllamaChat::Tools::SearchKnowledge} so that the
|
|
5
|
+
# `/collection query` command and the trigger mechanism can reuse
|
|
6
|
+
# the same search + rerank pipeline without duplicating logic.
|
|
7
|
+
module OllamaChat::CollectionSearch
|
|
8
|
+
include Kramdown::ANSI::Width
|
|
9
|
+
|
|
10
|
+
# Searches the active document collection for records matching
|
|
11
|
+
# the given query.
|
|
12
|
+
#
|
|
13
|
+
# @param query [String] the search query
|
|
14
|
+
# @param tags [Array<String>, nil] tag filter
|
|
15
|
+
# @param text_size [Integer, nil] max snippet size
|
|
16
|
+
# @param text_count [Integer, nil] max number of snippets
|
|
17
|
+
# @param min_similarity [Float, nil] minimum similarity threshold
|
|
18
|
+
#
|
|
19
|
+
# @return [Array<Documentrix::Utils::TagResult>] matching records
|
|
20
|
+
def find_document_records(
|
|
21
|
+
query,
|
|
22
|
+
tags: nil, text_size: nil, text_count: nil, min_similarity: nil
|
|
23
|
+
)
|
|
24
|
+
tags = Documentrix::Utils::Tags.new(
|
|
25
|
+
tags, valid_tag: /\A#*([-\w.\]\[]+)/
|
|
26
|
+
)
|
|
27
|
+
@documents.find_where(
|
|
28
|
+
query.first(config.embedding.model.context_length),
|
|
29
|
+
tags:,
|
|
30
|
+
prompt: config.embedding.model.prompt?,
|
|
31
|
+
text_size:,
|
|
32
|
+
text_count:,
|
|
33
|
+
min_similarity:
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Reranks a set of records using the LLM with the `rerank` prompt.
|
|
38
|
+
#
|
|
39
|
+
# @param query [String] the original search query
|
|
40
|
+
# @param records [Array<Documentrix::Utils::TagResult>] candidate records
|
|
41
|
+
# @param prompt_name [String, nil] the prompt template to use for
|
|
42
|
+
# reranking; defaults to `'rerank'`
|
|
43
|
+
# @return [Array<Documentrix::Utils::TagResult>] filtered records
|
|
44
|
+
def rerank_records(query, records, prompt_name: nil)
|
|
45
|
+
candidates = records.each_with_index.map { |r, i|
|
|
46
|
+
"[#{i}] #{truncate(r.text.strip, length: 300)}"
|
|
47
|
+
}.join("\n")
|
|
48
|
+
|
|
49
|
+
prompt_name ||= 'rerank'
|
|
50
|
+
rerank_prompt = prompt(prompt_name) or
|
|
51
|
+
raise 'missing prompt %s' % prompt_name.inspect
|
|
52
|
+
rerank_prompt = rerank_prompt.to_s
|
|
53
|
+
.named_placeholders_interpolate({ query:, candidates: })
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
if response = generate(prompt: rerank_prompt).full?
|
|
57
|
+
indices = response.scan(/\d+/).map(&:to_i)
|
|
58
|
+
.select { |i| (0...records.size).include?(i) }
|
|
59
|
+
records = records.values_at(*indices) if indices.any?
|
|
60
|
+
end
|
|
61
|
+
rescue => e
|
|
62
|
+
log(:error, e, data: { context: 'rerank' })
|
|
63
|
+
end
|
|
64
|
+
records
|
|
65
|
+
end
|
|
66
|
+
end
|