ollama_chat 0.0.127 → 0.0.128
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 +89 -0
- data/README.md +1 -0
- data/lib/ollama_chat/chat.rb +44 -44
- data/lib/ollama_chat/collection_search.rb +2 -0
- data/lib/ollama_chat/commands.rb +22 -32
- data/lib/ollama_chat/conversation.rb +48 -0
- data/lib/ollama_chat/dialog.rb +14 -7
- data/lib/ollama_chat/information.rb +3 -0
- data/lib/ollama_chat/message_list.rb +7 -5
- data/lib/ollama_chat/model_handling.rb +14 -13
- data/lib/ollama_chat/oc.rb +7 -0
- data/lib/ollama_chat/rag_handling.rb +116 -7
- data/lib/ollama_chat/source_fetching.rb +1 -1
- data/lib/ollama_chat/tools/concern.rb +33 -18
- data/lib/ollama_chat/tools/delete_file.rb +2 -2
- data/lib/ollama_chat/tools/directory_structure.rb +2 -2
- data/lib/ollama_chat/tools/execute_grep.rb +3 -5
- data/lib/ollama_chat/tools/file_context.rb +1 -2
- data/lib/ollama_chat/tools/forget.rb +2 -2
- data/lib/ollama_chat/tools/generate_image.rb +4 -6
- data/lib/ollama_chat/tools/get_current_weather.rb +1 -1
- data/lib/ollama_chat/tools/get_cve.rb +2 -2
- data/lib/ollama_chat/tools/get_endoflife.rb +2 -2
- data/lib/ollama_chat/tools/get_rfc.rb +2 -2
- data/lib/ollama_chat/tools/get_url.rb +1 -2
- data/lib/ollama_chat/tools/memorize.rb +1 -1
- data/lib/ollama_chat/tools/move_file.rb +3 -3
- data/lib/ollama_chat/tools/patch_file.rb +7 -2
- data/lib/ollama_chat/tools/read_file.rb +2 -2
- data/lib/ollama_chat/tools/roll_dice.rb +1 -1
- data/lib/ollama_chat/tools/run_tests.rb +3 -5
- data/lib/ollama_chat/tools/search_knowledge.rb +5 -3
- data/lib/ollama_chat/tools/search_web.rb +1 -2
- data/lib/ollama_chat/tools/write_file.rb +2 -2
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +2 -2
- data/spec/ollama_chat/commands_spec.rb +29 -23
- data/spec/ollama_chat/conversation_spec.rb +71 -0
- data/spec/ollama_chat/model_handling_spec.rb +9 -9
- data/spec/ollama_chat/rag_handling_spec.rb +113 -0
- data/spec/ollama_chat/tools/concern_spec.rb +1 -1
- data/spec/ollama_chat/tools/memorize_spec.rb +4 -4
- data/spec/ollama_chat/tools/run_tests_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8c69119a9431fed33aea9fe4f2f23594eea70c570fb5f08b39b88daee8bd31a
|
|
4
|
+
data.tar.gz: efd37e4ba7c7971369bf4bd3f7ea95dd1a031f21f54f8a1b438a516db5b577c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cadf4af1255ea0232708e463b4c48f8b7497a556e4e14766f83c2291da8de7c9f77591da2a1d43678502d41bf414ed2e806ca46ef744d09ca85a33212474891a
|
|
7
|
+
data.tar.gz: 3e286668006435fe9fc00fdafbaa21d1d422ac99b00631838a69b2e334de30a50e3421a5172763827021370d3eb20eacdf16f7ca5f01a60a4baa4634d678b448
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,94 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-07 v0.0.128
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Migrate `/clear` to `/conversation clean` chooser:
|
|
8
|
+
* Removed `clean` method from `chat.rb` and the `/clear` command from
|
|
9
|
+
`commands.rb`.
|
|
10
|
+
* Added `conversation_clean` to `conversation.rb` with an accumulating
|
|
11
|
+
`choose_with_state` chooser (options: `tools`, `images`, `thinking`,
|
|
12
|
+
`messages`, `history`, `links`), a `confirm?` gate, and per-field
|
|
13
|
+
dispatch.
|
|
14
|
+
* Added `what:` keyword argument to `clean_messages` and
|
|
15
|
+
`clean_messages!` in `message_list.rb` supporting `:tools`, `:images`,
|
|
16
|
+
and `:thinking` selection.
|
|
17
|
+
* Updated `/conversation clean` command handler to delegate to
|
|
18
|
+
`conversation_clean`.
|
|
19
|
+
* Add `OLLAMA_EMBEDDING_URL` for dedicated embedding host:
|
|
20
|
+
* Add `OC::OLLAMA::EMBEDDING_URL` const_conf setting (optional,
|
|
21
|
+
`sensitive true`, decoded to `URI`, scheme-checked).
|
|
22
|
+
* Add `connect_embedding_ollama` + public `embedding_ollama` accessor in
|
|
23
|
+
`chat.rb`; fallback to primary chat client when unset.
|
|
24
|
+
* Propagate `ollama:` kwarg through `model_present?`,
|
|
25
|
+
`pull_model_from_remote`, `pull_model_unless_present`, `prepare_model`,
|
|
26
|
+
`use_model` in `model_handling.rb`.
|
|
27
|
+
* Refactor `connect_message` to keyword-arg signature (`base_url:`,
|
|
28
|
+
`prefix:`) + new `connect_message_done` in `dialog.rb`; remove old
|
|
29
|
+
positional-arg version.
|
|
30
|
+
* Remove `ensure connect_message` from `choose_model`.
|
|
31
|
+
* `/reconnect` now calls both `connect_ollama` +
|
|
32
|
+
`connect_embedding_ollama`; `info_rag` shows embedding URL.
|
|
33
|
+
* Fix `source_fetching.rb` Semantic splitter to route chunking
|
|
34
|
+
calls to `embedding_ollama` instead of the primary chat client.
|
|
35
|
+
* Add `url` + `model` to log payloads in `collection_search.rb` and
|
|
36
|
+
`search_knowledge.rb`.
|
|
37
|
+
* Update `README.md` with `OLLAMA_EMBEDDING_URL` entry.
|
|
38
|
+
* Add `/memory dump` and `/memory restore` command:
|
|
39
|
+
* Add `/memory` command in `commands.rb` routing `dump` and `restore`
|
|
40
|
+
subcommands with an optional trailing `.jsonl` path.
|
|
41
|
+
* Add `memory_dump` in `rag_handling.rb` with accumulating multi-select
|
|
42
|
+
chooser (`[ALL]`/`[DONE]`) writing JSONL via `JSONJSONLIO`.
|
|
43
|
+
* Add `memory_restore` in `rag_handling.rb` grouping records by
|
|
44
|
+
`collection` field and re-embedding with original tags and
|
|
45
|
+
`source` association.
|
|
46
|
+
* Extend `create_memory_collection` to accept either a bare persona stem
|
|
47
|
+
or a full `memory-*` collection name via `start_with?` guard.
|
|
48
|
+
* Update `create_memory_collection` YARD prose to reflect dual-input
|
|
49
|
+
behavior.
|
|
50
|
+
* Swap `miyu_pairing` → `personal_assistant` in `forget.rb`,
|
|
51
|
+
`memorize.rb`, and `memorize_spec.rb` to decouple docs from active
|
|
52
|
+
persona.
|
|
53
|
+
|
|
54
|
+
### Refactoring
|
|
55
|
+
|
|
56
|
+
* Refactor all tools to use `tool_config`:
|
|
57
|
+
* Replace 20 `config.tools.functions.<name>` call sites across 14 tool
|
|
58
|
+
files with the `tool_config` accessor from `Tools::Concern`.
|
|
59
|
+
* Remove 12 dead `config = chat.config` locals that existed solely to
|
|
60
|
+
reach the tool's own config.
|
|
61
|
+
* Drop `config` parameter from `eval_template` in `execute_grep.rb`,
|
|
62
|
+
`poll_for_image` in `generate_image.rb`, and `check_path` in
|
|
63
|
+
`run_tests.rb`.
|
|
64
|
+
* Move `tool_config` and `allowed_paths` below `private` in `concern.rb`;
|
|
65
|
+
add YARD documentation to `tool_config`.
|
|
66
|
+
|
|
67
|
+
### Documentation
|
|
68
|
+
|
|
69
|
+
* Document automatic syntax checking in `patch_file` description:
|
|
70
|
+
* Added a `SYNTAX CHECK` note to the `OllamaChat::Tools::PatchFile`
|
|
71
|
+
description, informing users that the tool automatically runs
|
|
72
|
+
language-appropriate checks (e.g. `ruby -wc` for `.rb` files) and
|
|
73
|
+
reports errors in the result message.
|
|
74
|
+
|
|
75
|
+
### Tests
|
|
76
|
+
|
|
77
|
+
* Removed `/clear` describe block from `commands_spec.rb`; replaced
|
|
78
|
+
`/conversation clean` specs with delegation test.
|
|
79
|
+
* Added 6 unit examples for `#conversation_clean` in `conversation_spec.rb`
|
|
80
|
+
covering cancel, deny, field-only, messages+fields, links-only, and
|
|
81
|
+
history-only paths.
|
|
82
|
+
* Fix `model_handling_spec.rb` call sites for new `ollama:` kwarg.
|
|
83
|
+
* Stub `connect_message_done` in `spec_helper.rb`.
|
|
84
|
+
* Add 5 routing specs in `commands_spec.rb` for `/memory` (with-path,
|
|
85
|
+
without-path, spaces-in-path).
|
|
86
|
+
* Add 7 specs in `rag_handling_spec.rb` for `create_memory_collection`,
|
|
87
|
+
`memory_dump`, and `memory_restore`.
|
|
88
|
+
* Update 3 `check_path` mocks in `run_tests_spec.rb` to match the new
|
|
89
|
+
single-argument signature; use `.expose` in `concern_spec.rb` for private
|
|
90
|
+
method access.
|
|
91
|
+
|
|
3
92
|
## 2026-10-06 v0.0.127
|
|
4
93
|
|
|
5
94
|
## Changes
|
data/README.md
CHANGED
|
@@ -61,6 +61,7 @@ The following environment variables can be used to configure behavior:
|
|
|
61
61
|
#### Ollama Core
|
|
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
|
+
- `OLLAMA_EMBEDDING_URL` - Optional base URL for a dedicated Ollama server used exclusively for embedding operations. When set, the embedding model runs on this host while the chat model stays on `OLLAMA_URL`. Falls back to `OLLAMA_URL` when unset.
|
|
64
65
|
- `OLLAMA_SEARXNG_URL` - SearxNG search endpoint URL
|
|
65
66
|
- `OLLAMA_CHAT_TTS_URL` - Base URL for the [audio.cpp](https://github.com/0xshug0/audio.cpp) TTS server (default: `http://localhost:8880`)
|
|
66
67
|
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'tins'
|
|
|
2
2
|
require 'tins/xt/string_version'
|
|
3
3
|
require 'tins/xt/full'
|
|
4
4
|
require 'json'
|
|
5
|
+
require 'set'
|
|
5
6
|
require 'term/ansicolor'
|
|
6
7
|
require 'reline'
|
|
7
8
|
require 'reverse_markdown'
|
|
@@ -116,6 +117,7 @@ class OllamaChat::Chat
|
|
|
116
117
|
setup_session
|
|
117
118
|
setup_state_selectors(config)
|
|
118
119
|
connect_ollama
|
|
120
|
+
connect_embedding_ollama
|
|
119
121
|
@documents = setup_documents
|
|
120
122
|
models::Collection.sync(self)
|
|
121
123
|
@cache = setup_cache
|
|
@@ -321,6 +323,16 @@ class OllamaChat::Chat
|
|
|
321
323
|
voice_handler.new(chat: self, voice: current_voice).speak(text, background:)
|
|
322
324
|
end
|
|
323
325
|
|
|
326
|
+
# Returns the Ollama client to use for embedding operations.
|
|
327
|
+
#
|
|
328
|
+
# Falls back to the primary chat client when no dedicated embedding
|
|
329
|
+
# URL has been configured.
|
|
330
|
+
#
|
|
331
|
+
# @return [Ollama::Client] the embedding or chat Ollama client
|
|
332
|
+
def embedding_ollama
|
|
333
|
+
@embedding_ollama || ollama
|
|
334
|
+
end
|
|
335
|
+
|
|
324
336
|
# Returns a human-readable string representation of the Chat object,
|
|
325
337
|
# including the class name and the base URL.
|
|
326
338
|
#
|
|
@@ -427,47 +439,6 @@ class OllamaChat::Chat
|
|
|
427
439
|
content
|
|
428
440
|
end
|
|
429
441
|
|
|
430
|
-
# The clean method clears various parts of the chat session based on the
|
|
431
|
-
# specified parameter.
|
|
432
|
-
#
|
|
433
|
-
# @param what [ String, nil ] the type of data to clear, defaults to
|
|
434
|
-
# 'messages' if nil
|
|
435
|
-
def clean(what)
|
|
436
|
-
persona_profile = nil
|
|
437
|
-
case what
|
|
438
|
-
when 'messages', nil
|
|
439
|
-
messages.clear
|
|
440
|
-
feedback("Cleared messages.", type: :info)
|
|
441
|
-
when 'links'
|
|
442
|
-
links.clear
|
|
443
|
-
feedback("Cleared links.", type: :info)
|
|
444
|
-
when 'history'
|
|
445
|
-
clear_history
|
|
446
|
-
feedback("Cleared history.", type: :info)
|
|
447
|
-
when 'tags'
|
|
448
|
-
@documents.clear
|
|
449
|
-
feedback("Cleared all tags.", type: :info)
|
|
450
|
-
when 'images'
|
|
451
|
-
messages.clear_images
|
|
452
|
-
feedback("Cleared all images.", type: :info)
|
|
453
|
-
when 'all'
|
|
454
|
-
if confirm?(
|
|
455
|
-
prompt: '🔔 Are you sure to clear messages and collection? (y/n) ',
|
|
456
|
-
yes: /\Ay/i
|
|
457
|
-
)
|
|
458
|
-
then
|
|
459
|
-
messages.clear
|
|
460
|
-
@documents.clear
|
|
461
|
-
links.clear
|
|
462
|
-
clear_history
|
|
463
|
-
feedback("Cleared messages and collection #{bold{collection}}.", type: :info)
|
|
464
|
-
else
|
|
465
|
-
feedback("Denied.", type: :denied)
|
|
466
|
-
end
|
|
467
|
-
end
|
|
468
|
-
persona_profile
|
|
469
|
-
end
|
|
470
|
-
|
|
471
442
|
# The interact_with_user method manages the interactive loop for user input
|
|
472
443
|
# and chat processing.
|
|
473
444
|
# It handles reading user input, processing commands, managing messages, and
|
|
@@ -646,12 +617,13 @@ class OllamaChat::Chat
|
|
|
646
617
|
# @raise [RuntimeError] if the connected Ollama server API version is less
|
|
647
618
|
# than 0.9.0
|
|
648
619
|
def connect_ollama
|
|
620
|
+
connect_message(base_url:)
|
|
649
621
|
@server_version = nil
|
|
650
622
|
@ollama = Ollama::Client.new(
|
|
651
623
|
connect_timeout: config.timeouts.connect_timeout?,
|
|
652
624
|
read_timeout: config.timeouts.read_timeout?,
|
|
653
625
|
write_timeout: config.timeouts.write_timeout?,
|
|
654
|
-
base_url:
|
|
626
|
+
base_url: ,
|
|
655
627
|
debug: ,
|
|
656
628
|
user_agent:
|
|
657
629
|
)
|
|
@@ -659,6 +631,7 @@ class OllamaChat::Chat
|
|
|
659
631
|
raise 'require ollama API version 0.9.0 or higher'
|
|
660
632
|
end
|
|
661
633
|
log(:info, "Connection established", data: { base_url: })
|
|
634
|
+
connect_message_done
|
|
662
635
|
@ollama
|
|
663
636
|
end
|
|
664
637
|
|
|
@@ -673,10 +646,10 @@ class OllamaChat::Chat
|
|
|
673
646
|
if embedding.on?
|
|
674
647
|
@embedding_model = config.embedding.model.name
|
|
675
648
|
@embedding_model_options = Ollama::Options[config.embedding.model.options]
|
|
676
|
-
pull_model_unless_present(@embedding_model)
|
|
649
|
+
pull_model_unless_present(@embedding_model, ollama: embedding_ollama)
|
|
677
650
|
collection = initial_collection
|
|
678
651
|
@documents = Documentrix::Documents.new(
|
|
679
|
-
ollama
|
|
652
|
+
ollama: embedding_ollama,
|
|
680
653
|
model: @embedding_model,
|
|
681
654
|
model_options: config.embedding.model.options,
|
|
682
655
|
embedding_length: config.embedding.model.embedding_length,
|
|
@@ -691,6 +664,33 @@ class OllamaChat::Chat
|
|
|
691
664
|
end
|
|
692
665
|
end
|
|
693
666
|
|
|
667
|
+
# Establishes a dedicated Ollama connection for embedding operations.
|
|
668
|
+
#
|
|
669
|
+
# When OC::OLLAMA::EMBEDDING_URL is configured, creates a separate
|
|
670
|
+
# Ollama::Client targeting that host so the embedding model can run
|
|
671
|
+
# on a different machine (e.g. a GPU box running audio.cpp alongside
|
|
672
|
+
# the embedding model) while the chat model stays on the primary
|
|
673
|
+
# Ollama server.
|
|
674
|
+
#
|
|
675
|
+
# @return [Ollama::Client, nil] the embedding client, or nil when no
|
|
676
|
+
# dedicated embedding URL is configured
|
|
677
|
+
def connect_embedding_ollama
|
|
678
|
+
if base_url = OC::OLLAMA::EMBEDDING_URL?
|
|
679
|
+
connect_message(base_url:, prefix: 'embedding ')
|
|
680
|
+
@embedding_ollama = Ollama::Client.new(
|
|
681
|
+
connect_timeout: config.timeouts.connect_timeout?,
|
|
682
|
+
read_timeout: config.timeouts.read_timeout?,
|
|
683
|
+
write_timeout: config.timeouts.write_timeout?,
|
|
684
|
+
base_url: ,
|
|
685
|
+
debug: ,
|
|
686
|
+
user_agent:
|
|
687
|
+
)
|
|
688
|
+
log(:info, "Embedding connection established", data: { base_url: })
|
|
689
|
+
connect_message_done
|
|
690
|
+
@embedding_ollama
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
|
|
694
694
|
# Adds documents from command line arguments to the document collection.
|
|
695
695
|
#
|
|
696
696
|
# Processes a list of document paths or URLs, handling both local files and
|
|
@@ -31,6 +31,7 @@ module OllamaChat::CollectionSearch
|
|
|
31
31
|
log(
|
|
32
32
|
:info, 'Embedding search request',
|
|
33
33
|
data: {
|
|
34
|
+
url: embedding_ollama.base_url,
|
|
34
35
|
model: config.embedding.model.to_h,
|
|
35
36
|
collection: collection,
|
|
36
37
|
query: effective_query,
|
|
@@ -48,6 +49,7 @@ module OllamaChat::CollectionSearch
|
|
|
48
49
|
log(
|
|
49
50
|
:info, 'Embedding search response',
|
|
50
51
|
data: {
|
|
52
|
+
url: embedding_ollama.base_url,
|
|
51
53
|
collection: collection,
|
|
52
54
|
query: effective_query,
|
|
53
55
|
result_count: records.size,
|
data/lib/ollama_chat/commands.rb
CHANGED
|
@@ -324,24 +324,6 @@ module OllamaChat::Commands
|
|
|
324
324
|
:next
|
|
325
325
|
end
|
|
326
326
|
|
|
327
|
-
command(
|
|
328
|
-
name: :clear,
|
|
329
|
-
regexp: %r(^/clear(?:\s+(messages|images|links|history|tags|all))?$),
|
|
330
|
-
complete: [ 'clear', %w[ messages images links history tags all ] ],
|
|
331
|
-
optional: true,
|
|
332
|
-
help: <<~EOT
|
|
333
|
-
🧹 Clear chat state (messages, images, links,
|
|
334
|
-
history, tags, all)
|
|
335
|
-
EOT
|
|
336
|
-
) do |subcommand|
|
|
337
|
-
if result = clean(subcommand)
|
|
338
|
-
disable_content_parsing
|
|
339
|
-
result
|
|
340
|
-
else
|
|
341
|
-
:next
|
|
342
|
-
end
|
|
343
|
-
end
|
|
344
|
-
|
|
345
327
|
command(
|
|
346
328
|
name: :links,
|
|
347
329
|
regexp: %r(^/links(?:\s+(clear))?$),
|
|
@@ -397,7 +379,7 @@ module OllamaChat::Commands
|
|
|
397
379
|
help: <<~EOT
|
|
398
380
|
💾 Manage conversation content:
|
|
399
381
|
- save/load: Export/import as .json or .jsonl
|
|
400
|
-
- clean:
|
|
382
|
+
- clean: Interactively clean conversation content
|
|
401
383
|
- compact: Summarize old messages, keep recent
|
|
402
384
|
- compact summary: Show last compaction summary
|
|
403
385
|
- summarize: Per-message narrative (-s sentence)
|
|
@@ -416,17 +398,7 @@ module OllamaChat::Commands
|
|
|
416
398
|
load_conversation(path)
|
|
417
399
|
repair_group_uuids
|
|
418
400
|
when 'clean'
|
|
419
|
-
|
|
420
|
-
prompt: '🔔 Clean tool content, images, and thinking from conversation? (y/n) ',
|
|
421
|
-
yes: /\Ay/i
|
|
422
|
-
)
|
|
423
|
-
then
|
|
424
|
-
messages.clean_messages!
|
|
425
|
-
session_sync
|
|
426
|
-
feedback("Conversation cleaned.", type: :info)
|
|
427
|
-
else
|
|
428
|
-
feedback("Denied.", type: :denied)
|
|
429
|
-
end
|
|
401
|
+
conversation_clean
|
|
430
402
|
when 'compact summary'
|
|
431
403
|
show_compaction_summary
|
|
432
404
|
when 'compact'
|
|
@@ -699,6 +671,25 @@ module OllamaChat::Commands
|
|
|
699
671
|
:next
|
|
700
672
|
end
|
|
701
673
|
|
|
674
|
+
command(
|
|
675
|
+
name: :memory,
|
|
676
|
+
regexp: %r{^/memory(?:\s+(dump|restore))(?:\s+([^-].*\.jsonl?))?$},
|
|
677
|
+
complete: [ 'memory', %w[ dump restore ] ],
|
|
678
|
+
options: '[FILENAME]',
|
|
679
|
+
help: <<~EOT
|
|
680
|
+
💾 Manage persona memory (dump/restore)
|
|
681
|
+
optional path must end in .json or .jsonl
|
|
682
|
+
EOT
|
|
683
|
+
) do |subcommand, path|
|
|
684
|
+
case subcommand
|
|
685
|
+
when 'dump'
|
|
686
|
+
memory_dump(path)
|
|
687
|
+
when 'restore'
|
|
688
|
+
memory_restore(path)
|
|
689
|
+
end
|
|
690
|
+
:next
|
|
691
|
+
end
|
|
692
|
+
|
|
702
693
|
category :Persona
|
|
703
694
|
|
|
704
695
|
command(
|
|
@@ -1042,9 +1033,8 @@ module OllamaChat::Commands
|
|
|
1042
1033
|
🔌 Reconnect to Ollama server
|
|
1043
1034
|
EOT
|
|
1044
1035
|
) do
|
|
1045
|
-
feedback green { "Reconnecting to ollama #{base_url.to_s.inspect}…" }, type: :info
|
|
1046
1036
|
connect_ollama
|
|
1047
|
-
|
|
1037
|
+
connect_embedding_ollama
|
|
1048
1038
|
:next
|
|
1049
1039
|
end
|
|
1050
1040
|
|
|
@@ -63,4 +63,52 @@ module OllamaChat::Conversation
|
|
|
63
63
|
"#{filename.to_s.inspect} failed.", type: :warn)
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
|
+
|
|
67
|
+
# Selectively cleans parts of the current conversation.
|
|
68
|
+
#
|
|
69
|
+
# Presents an accumulating chooser of cleanable targets:
|
|
70
|
+
# tool content, images, thinking, messages, history, links.
|
|
71
|
+
# The user picks one or more (or [ALL]), confirms, and the
|
|
72
|
+
# selected items are cleared.
|
|
73
|
+
def conversation_clean
|
|
74
|
+
options = %w[ tools images thinking messages history links ]
|
|
75
|
+
|
|
76
|
+
selected = Set.new
|
|
77
|
+
choose_with_state do
|
|
78
|
+
loop do
|
|
79
|
+
remaining = options - selected.to_a
|
|
80
|
+
entries = (remaining.empty? ? [] : ['[ALL]'] + remaining) + ['[DONE]']
|
|
81
|
+
choice = choose_entry(entries, prompt: 'What to clean from conversation? %s')
|
|
82
|
+
case choice
|
|
83
|
+
when nil, '[DONE]'
|
|
84
|
+
break
|
|
85
|
+
when '[ALL]'
|
|
86
|
+
selected.merge(remaining)
|
|
87
|
+
break
|
|
88
|
+
else
|
|
89
|
+
selected.add(choice)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return feedback('Cancelled, nothing selected.', type: :cancel) if selected.empty?
|
|
95
|
+
|
|
96
|
+
what = selected.map { |s| bold{s} }.to_a
|
|
97
|
+
|
|
98
|
+
unless confirm?(
|
|
99
|
+
prompt: "🔔 Clean #{what * ', '} from conversation? (y/n) ",
|
|
100
|
+
yes: /\Ay/i
|
|
101
|
+
)
|
|
102
|
+
return feedback('Denied.', type: :denied)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
field_options = %w[ tools images thinking ].select { selected.include?(_1) }
|
|
106
|
+
messages.clear if selected.include?('messages')
|
|
107
|
+
messages.clean_messages!(what: field_options.map(&:to_sym)) unless field_options.empty?
|
|
108
|
+
clear_history if selected.include?('history')
|
|
109
|
+
links.clear if selected.include?('links')
|
|
110
|
+
|
|
111
|
+
session_sync
|
|
112
|
+
feedback("Cleaned #{what * ', '} from conversation.", type: :info)
|
|
113
|
+
end
|
|
66
114
|
end
|
data/lib/ollama_chat/dialog.rb
CHANGED
|
@@ -118,14 +118,21 @@ module OllamaChat::Dialog
|
|
|
118
118
|
files
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
#
|
|
121
|
+
# Displays an info-level feedback message indicating that a connection
|
|
122
|
+
# to an Ollama server is being established.
|
|
122
123
|
#
|
|
123
|
-
# @param
|
|
124
|
-
# @param
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
feedback green {
|
|
124
|
+
# @param base_url [URI, String] the target Ollama server URL
|
|
125
|
+
# @param prefix [String] an optional label prepended to "ollama" to
|
|
126
|
+
# distinguish the connection type, e.g. `"embedding "` for a dedicated
|
|
127
|
+
# embedding host (default: `""`)
|
|
128
|
+
def connect_message(base_url:, prefix: '')
|
|
129
|
+
feedback green { "Connecting to #{prefix}ollama #{base_url.to_s.inspect}…" }, type: :info
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Displays a success-level feedback message confirming that a
|
|
133
|
+
# connection was established. Counterpart to {#connect_message}.
|
|
134
|
+
def connect_message_done
|
|
135
|
+
feedback green { "Done." }, type: :success
|
|
129
136
|
end
|
|
130
137
|
|
|
131
138
|
# The change_voice method allows the user to select a voice from a list of
|
|
@@ -191,6 +191,9 @@ module OllamaChat::Information
|
|
|
191
191
|
# @param output [IO] the output stream to write the information to, defaults to STDOUT
|
|
192
192
|
def info_rag(output: STDOUT)
|
|
193
193
|
if embedding.on?
|
|
194
|
+
if base_url = OC::OLLAMA::EMBEDDING_URL?
|
|
195
|
+
output.puts "🔌 Connected to embedding ollama server on: #{base_url.to_s.inspect}"
|
|
196
|
+
end
|
|
194
197
|
output.puts "🗄️ Current RAG model is #{bold{@embedding_model}}"
|
|
195
198
|
if @embedding_model_options.present?
|
|
196
199
|
output.puts " Options: #{JSON.pretty_generate(@embedding_model_options).gsub(/(?<!\A)^/, ' ')}"
|
|
@@ -407,11 +407,13 @@ class OllamaChat::MessageList
|
|
|
407
407
|
# @param messages [Array<OllamaChat::Message>] the list of messages to clean
|
|
408
408
|
# @return [Array<OllamaChat::Message>] a new array containing duplicated
|
|
409
409
|
# messages with stripped content
|
|
410
|
-
def clean_messages(messages: @messages)
|
|
410
|
+
def clean_messages(messages: @messages, what: %i[ tools images ])
|
|
411
|
+
what = Array(what).map(&:to_sym)
|
|
411
412
|
messages.map do |message|
|
|
412
413
|
message = message.dup
|
|
413
|
-
message.content = '' if message.tool?
|
|
414
|
-
message.images = nil
|
|
414
|
+
message.content = '' if what.include?(:tools) && message.tool?
|
|
415
|
+
message.images = nil if what.include?(:images)
|
|
416
|
+
message.thinking = nil if what.include?(:thinking)
|
|
415
417
|
message
|
|
416
418
|
end
|
|
417
419
|
end
|
|
@@ -422,8 +424,8 @@ class OllamaChat::MessageList
|
|
|
422
424
|
# @param messages [Array<OllamaChat::Message>] the messages to clean.
|
|
423
425
|
# Defaults to all current messages.
|
|
424
426
|
# @return [OllamaChat::MessageList] self to allow for method chaining.
|
|
425
|
-
def clean_messages!(messages: @messages)
|
|
426
|
-
@messages = clean_messages(messages:)
|
|
427
|
+
def clean_messages!(messages: @messages, what: %i[ tools images ])
|
|
428
|
+
@messages = clean_messages(messages:, what:)
|
|
427
429
|
self
|
|
428
430
|
end
|
|
429
431
|
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
# model retrieval when necessary.
|
|
9
9
|
#
|
|
10
10
|
# @example Checking if a model is present
|
|
11
|
-
# chat.model_present?('llama3.1')
|
|
11
|
+
# chat.model_present?('llama3.1', ollama:)
|
|
12
12
|
#
|
|
13
13
|
# @example Pulling a model from a remote server
|
|
14
|
-
# chat.pull_model_from_remote('mistral')
|
|
14
|
+
# chat.pull_model_from_remote('mistral', ollama:)
|
|
15
15
|
#
|
|
16
16
|
# @example Ensuring a model is available locally
|
|
17
|
-
# chat.pull_model_unless_present('phi3',
|
|
17
|
+
# chat.pull_model_unless_present('phi3', ollama:)
|
|
18
18
|
module OllamaChat::ModelHandling
|
|
19
19
|
|
|
20
20
|
# A simple data structure representing metadata about a model.
|
|
@@ -411,10 +411,11 @@ module OllamaChat::ModelHandling
|
|
|
411
411
|
# available.
|
|
412
412
|
#
|
|
413
413
|
# @param model [ String ] the name of the Ollama model
|
|
414
|
+
# @param ollama [Ollama::Client] the client to query for model presence
|
|
414
415
|
#
|
|
415
416
|
# @return [ ModelMetadata, NilClass ] if the model is present,
|
|
416
417
|
# nil otherwise
|
|
417
|
-
def model_present?(model)
|
|
418
|
+
def model_present?(model, ollama:)
|
|
418
419
|
ollama.show(model:) do |md|
|
|
419
420
|
return ModelMetadata.new(
|
|
420
421
|
name: model,
|
|
@@ -432,7 +433,8 @@ module OllamaChat::ModelHandling
|
|
|
432
433
|
# remote server if it is not found locally.
|
|
433
434
|
#
|
|
434
435
|
# @param model [ String ] the name of the model to be pulled
|
|
435
|
-
|
|
436
|
+
# @param ollama [Ollama::Client] the client to pull the model from
|
|
437
|
+
def pull_model_from_remote(model, ollama:)
|
|
436
438
|
feedback("Model #{bold{model}} not found locally, attempting to pull it from remote now…", type: :info)
|
|
437
439
|
ollama.pull(model:)
|
|
438
440
|
end
|
|
@@ -444,16 +446,17 @@ module OllamaChat::ModelHandling
|
|
|
444
446
|
# an UnknownModelError indicating the missing model name.
|
|
445
447
|
#
|
|
446
448
|
# @param model [String] the name of the model to ensure is present
|
|
449
|
+
# @param ollama [Ollama::Client] the client to query and pull from
|
|
447
450
|
#
|
|
448
451
|
# @return [ModelMetadata] the metadata for the available model
|
|
449
452
|
# @raise [OllamaChat::UnknownModelError] if the model cannot be found after
|
|
450
453
|
# attempting to pull it from remote
|
|
451
|
-
def pull_model_unless_present(model)
|
|
452
|
-
if model_metadata = model_present?(model)
|
|
454
|
+
def pull_model_unless_present(model, ollama:)
|
|
455
|
+
if model_metadata = model_present?(model, ollama:)
|
|
453
456
|
return model_metadata
|
|
454
457
|
else
|
|
455
|
-
pull_model_from_remote(model)
|
|
456
|
-
if model_metadata = model_present?(model)
|
|
458
|
+
pull_model_from_remote(model, ollama:)
|
|
459
|
+
if model_metadata = model_present?(model, ollama:)
|
|
457
460
|
return model_metadata
|
|
458
461
|
end
|
|
459
462
|
raise OllamaChat::UnknownModelError, "unknown model named #{@model.inspect}"
|
|
@@ -487,7 +490,7 @@ module OllamaChat::ModelHandling
|
|
|
487
490
|
# @return [OllamaChat::ModelHandling::ModelMetadata] the metadata for the
|
|
488
491
|
# prepared model
|
|
489
492
|
def prepare_model(model)
|
|
490
|
-
@model_metadata = pull_model_unless_present(model)
|
|
493
|
+
@model_metadata = pull_model_unless_present(model, ollama:)
|
|
491
494
|
if think? && !@model_metadata.can?('thinking')
|
|
492
495
|
think_mode.selected = 'disabled'
|
|
493
496
|
end
|
|
@@ -584,7 +587,7 @@ module OllamaChat::ModelHandling
|
|
|
584
587
|
@model = choose_model(model, config.model.name)
|
|
585
588
|
end
|
|
586
589
|
|
|
587
|
-
if @model_metadata = model_present?(@model)
|
|
590
|
+
if @model_metadata = model_present?(@model, ollama:)
|
|
588
591
|
session.update(current_model: @model)
|
|
589
592
|
else
|
|
590
593
|
session.update(current_model: nil)
|
|
@@ -655,7 +658,5 @@ module OllamaChat::ModelHandling
|
|
|
655
658
|
else
|
|
656
659
|
cli_model || current_model
|
|
657
660
|
end
|
|
658
|
-
ensure
|
|
659
|
-
connect_message(model, ollama.base_url)
|
|
660
661
|
end
|
|
661
662
|
end
|
data/lib/ollama_chat/oc.rb
CHANGED
|
@@ -112,6 +112,13 @@ module OC
|
|
|
112
112
|
check { value.scheme =~ /\Ahttps?\z/ }
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
EMBEDDING_URL = set do
|
|
116
|
+
description 'Ollama base URL to connect to for embedding'
|
|
117
|
+
sensitive true
|
|
118
|
+
decode { URI.parse(_1) if _1.present? }
|
|
119
|
+
check { value.nil? || value.scheme =~ /\Ahttps?\z/ }
|
|
120
|
+
end
|
|
121
|
+
|
|
115
122
|
SEARXNG_URL = set do
|
|
116
123
|
description 'URL for the SearXNG service for searches'
|
|
117
124
|
default 'http://localhost:8088/search?q=%{query}&language=en&format=json'
|