ollama_chat 0.0.136 → 0.0.138
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 +98 -0
- data/Rakefile +2 -2
- data/lib/ollama_chat/chat.rb +1 -1
- data/lib/ollama_chat/conversation.rb +1 -1
- data/lib/ollama_chat/database/models/collection.rb +2 -1
- data/lib/ollama_chat/dialog.rb +1 -1
- data/lib/ollama_chat/http_handling.rb +1 -1
- data/lib/ollama_chat/information.rb +3 -2
- data/lib/ollama_chat/links_set.rb +1 -0
- data/lib/ollama_chat/model_handling.rb +15 -7
- data/lib/ollama_chat/oc.rb +1 -1
- data/lib/ollama_chat/rag_handling.rb +39 -16
- data/lib/ollama_chat/system_prompt_management.rb +3 -3
- data/lib/ollama_chat/tools/browse.rb +4 -4
- data/lib/ollama_chat/tools/concern.rb +1 -0
- data/lib/ollama_chat/tools/execute_grep.rb +3 -3
- data/lib/ollama_chat/tools/generate_image.rb +2 -2
- data/lib/ollama_chat/utils/analyze_directory.rb +19 -19
- data/lib/ollama_chat/utils/fetcher.rb +2 -1
- data/lib/ollama_chat/utils/redact.rb +32 -0
- data/lib/ollama_chat/utils.rb +1 -0
- data/lib/ollama_chat/version.rb +1 -1
- data/lib/ollama_chat/web_searching.rb +1 -1
- data/ollama_chat.gemspec +8 -8
- data/spec/ollama_chat/information_spec.rb +23 -0
- data/spec/ollama_chat/parsing_spec.rb +5 -4
- data/spec/ollama_chat/rag_handling_spec.rb +120 -3
- data/spec/ollama_chat/tools/list_directory_spec.rb +10 -3
- data/spec/ollama_chat/utils/analyze_directory_spec.rb +33 -21
- data/spec/ollama_chat/web_searching_spec.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 170c9e2778ed0d581bda082eebc43d07a6c6e6a6cd99a0d1e0d3634a5281ca9f
|
|
4
|
+
data.tar.gz: e57e2eb4d990f10617e1574ae1f70d22741dd814cf945575cc2cb7fb882dd4be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5e6781664a38632da9d7a4f11900864b86b9e0049fcb66d6084777d0f8b4a85e762a57217c23817c77f0fb365592d5d659e3eab874aa270fa97b52a3e727c45
|
|
7
|
+
data.tar.gz: 6aa806be34d04830f4788dd452d6e8a078e848767978d6bf49d6fef39f3dbd92b3f61fd4dc203c9914491c1ab2d8fa432ff75bc3543bf385dffcda2333acbd83
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,103 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-28 v0.0.138
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Added `OllamaChat::Utils::Redact` module with `redact_password` to mask
|
|
8
|
+
credentials in URLs for user-facing display.
|
|
9
|
+
- `memory_restore` now deduplicates entries by checking existing tags before
|
|
10
|
+
adding records, reporting the number of skipped duplicates.
|
|
11
|
+
- `OllamaChat::Utils::AnalyzeDirectory` now returns a `Hash` with `:height` and
|
|
12
|
+
`:entries` keys instead of a bare `Array`. Entry hashes no longer include
|
|
13
|
+
`:type` or `:name`; directories are identified by a trailing `/` in `:path`.
|
|
14
|
+
|
|
15
|
+
### Fixes
|
|
16
|
+
|
|
17
|
+
- `use_model` now raises `OllamaChat::UnknownModelError` if the previous model
|
|
18
|
+
is missing or blank after a cancelled pull, preventing stale metadata from
|
|
19
|
+
being returned.
|
|
20
|
+
- Fixed `update_collection` to use `Set` for the `seen` variable, resolving a
|
|
21
|
+
latent `NoMethodError` when upstream yields a `Set`.
|
|
22
|
+
- Corrected the error message in `pull_model_unless_present` to reference the
|
|
23
|
+
`model` parameter instead of the potentially stale `@model` instance
|
|
24
|
+
variable.
|
|
25
|
+
|
|
26
|
+
### Improvements
|
|
27
|
+
|
|
28
|
+
- Applied password redaction to all user-visible URL displays, including
|
|
29
|
+
`Chat#inspect`, `Dialog#connect_message`, `Information#info_rag`,
|
|
30
|
+
`Information#print_welcome`, `Tools::Browse#execute`,
|
|
31
|
+
`Tools::GenerateImage#execute`, and `Fetcher.get`.
|
|
32
|
+
- Standardized `Set` insertion to use the `<<` idiom across `conversation.rb`,
|
|
33
|
+
`http_handling.rb`, `rag_handling.rb`, `generate_image.rb`, and
|
|
34
|
+
`web_searching.rb`.
|
|
35
|
+
- Added `<<` alias to `LinksSet` to support the standard `Set` insertion idiom.
|
|
36
|
+
- `AnalyzeDirectory` now omits the `:children` key from directory entries when
|
|
37
|
+
the array is empty, both during build and pruning.
|
|
38
|
+
|
|
39
|
+
### Build & CI
|
|
40
|
+
|
|
41
|
+
- Added `lib/ollama_chat/utils/redact.rb` to the gemspec file list.
|
|
42
|
+
|
|
43
|
+
### Testing
|
|
44
|
+
|
|
45
|
+
- Updated `analyze_directory_spec.rb`, `parsing_spec.rb`, and
|
|
46
|
+
`list_directory_spec.rb` to assert the new `AnalyzeDirectory` return
|
|
47
|
+
structure.
|
|
48
|
+
- Added specs for `redact_password` covering URI/String inputs, passthrough for
|
|
49
|
+
URLs without passwords, and non-mutation of the original object.
|
|
50
|
+
- Added specs for `memory_restore` deduplication logic, covering partial and
|
|
51
|
+
full skip scenarios.
|
|
52
|
+
- Updated `web_searching_spec.rb` to expect `<<` instead of `add` for link
|
|
53
|
+
insertion.
|
|
54
|
+
|
|
55
|
+
### Documentation
|
|
56
|
+
|
|
57
|
+
- Updated `execute_grep` tool description to explicitly state that the regex
|
|
58
|
+
runs against file contents.
|
|
59
|
+
- Updated YARD documentation for `AnalyzeDirectory` to reflect the new return
|
|
60
|
+
value structure.
|
|
61
|
+
|
|
62
|
+
## 2026-10-23 v0.0.137
|
|
63
|
+
|
|
64
|
+
### Fixes
|
|
65
|
+
|
|
66
|
+
- Fixed a double-scheme bug in `OC::URL` default generation by delegating to
|
|
67
|
+
`Ollama.base_url`, ensuring correct handling of `HOST` values that already
|
|
68
|
+
include `http://` or `https://`.
|
|
69
|
+
- Prevented deletion of the `default` collection in `delete_collection`,
|
|
70
|
+
returning a warning feedback instead.
|
|
71
|
+
- Reset `session.current_collection` to `'default'` when the active collection
|
|
72
|
+
is deleted.
|
|
73
|
+
|
|
74
|
+
### Improvements
|
|
75
|
+
|
|
76
|
+
- Ensured the `default` collection row always exists in the database by
|
|
77
|
+
unioning it with `chat.documents.collections` during `Collection.sync`.
|
|
78
|
+
- Removed four vestigial `refresh_system_prompt` calls from
|
|
79
|
+
`create_collection`, `edit_collection`, `rename_collection`, and
|
|
80
|
+
`delete_collection`, as collection data no longer interpolates into the
|
|
81
|
+
system prompt.
|
|
82
|
+
|
|
83
|
+
### Build & CI
|
|
84
|
+
|
|
85
|
+
- Updated `ollama-ruby` dependency from **1.25** to **1.26**.
|
|
86
|
+
- Updated `kramdown-ansi` dependency from **~> 0.6** to **~> 0.7**.
|
|
87
|
+
- Updated `gem_hadar` development dependency from **2.20.1** to **2.21.0**.
|
|
88
|
+
|
|
89
|
+
### Testing
|
|
90
|
+
|
|
91
|
+
- Added specs for `delete_collection` to verify refusal to delete the `default`
|
|
92
|
+
collection, resetting `current_collection` when the active collection is
|
|
93
|
+
deleted, and leaving `current_collection` unchanged for non-active
|
|
94
|
+
collections.
|
|
95
|
+
|
|
96
|
+
### Documentation
|
|
97
|
+
|
|
98
|
+
- Updated YARD documentation for `refresh_system_prompt` to accurately reflect
|
|
99
|
+
the placeholders used (`persona`, `persona_name`, `runtime_info`).
|
|
100
|
+
|
|
3
101
|
## 2026-10-21 v0.0.136
|
|
4
102
|
|
|
5
103
|
### Features
|
data/Rakefile
CHANGED
|
@@ -39,7 +39,7 @@ GemHadar do
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
dependency 'excon', '~> 1.0'
|
|
42
|
-
dependency 'ollama-ruby', '~> 1.
|
|
42
|
+
dependency 'ollama-ruby', '~> 1.26'
|
|
43
43
|
dependency 'documentrix', '>= 0.8.0'
|
|
44
44
|
dependency 'unix_socks', '>= 0.4'
|
|
45
45
|
dependency 'rss', '~> 0.3'
|
|
@@ -47,7 +47,7 @@ GemHadar do
|
|
|
47
47
|
dependency 'redis', '~> 5.0'
|
|
48
48
|
dependency 'mime-types', '~> 3.0'
|
|
49
49
|
dependency 'reverse_markdown', '~> 3.0'
|
|
50
|
-
dependency 'kramdown-ansi', '~> 0.
|
|
50
|
+
dependency 'kramdown-ansi', '~> 0.7'
|
|
51
51
|
dependency 'complex_config', '~> 0.22', '>= 0.22.2'
|
|
52
52
|
dependency 'tins', '~> 1.61'
|
|
53
53
|
dependency 'search_ui', '>= 0.2'
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -51,7 +51,8 @@ class OllamaChat::Database::Models::Collection < Sequel::Model(OllamaChat::DB)
|
|
|
51
51
|
#
|
|
52
52
|
# @param chat [OllamaChat::Chat] the chat instance providing the configuration
|
|
53
53
|
def self.sync(chat)
|
|
54
|
-
chat.documents.collections.
|
|
54
|
+
all_collections = (%w[ default ] + chat.documents.collections).to_set
|
|
55
|
+
all_collections.each do |name|
|
|
55
56
|
where(name: name.to_s).first and next
|
|
56
57
|
create(
|
|
57
58
|
name: name.to_s,
|
data/lib/ollama_chat/dialog.rb
CHANGED
|
@@ -142,7 +142,7 @@ module OllamaChat::Dialog
|
|
|
142
142
|
# distinguish the connection type, e.g. `"embedding "` for a dedicated
|
|
143
143
|
# embedding host (default: `""`)
|
|
144
144
|
def connect_message(base_url:, prefix: '')
|
|
145
|
-
feedback green { "Connecting to #{prefix}ollama #{base_url.
|
|
145
|
+
feedback green { "Connecting to #{prefix}ollama #{redact_password(base_url).inspect}…" }, type: :info
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
# Displays a success-level feedback message confirming that a
|
|
@@ -61,7 +61,7 @@ module OllamaChat::HTTPHandling
|
|
|
61
61
|
# @yield [IO] yields a temporary file handle for the caller to consume.
|
|
62
62
|
# @return [Object] the result of the block or the fetcher.
|
|
63
63
|
def get_url(url, headers: nil, cache: nil, remember: true, &block)
|
|
64
|
-
remember and links
|
|
64
|
+
remember and links << url.to_s
|
|
65
65
|
headers = config.request_headers?.to_h | headers
|
|
66
66
|
OllamaChat::Utils::Fetcher.get(
|
|
67
67
|
url,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# chat.usage
|
|
17
17
|
module OllamaChat::Information
|
|
18
18
|
extend Tins::Concern
|
|
19
|
+
include OllamaChat::Utils::Redact
|
|
19
20
|
|
|
20
21
|
included do
|
|
21
22
|
include UserAgent
|
|
@@ -190,7 +191,7 @@ module OllamaChat::Information
|
|
|
190
191
|
def info_rag(output: STDOUT)
|
|
191
192
|
if embedding.on?
|
|
192
193
|
if base_url = OC::OLLAMA::EMBEDDING_URL?
|
|
193
|
-
output.puts "🔌 Connected to embedding ollama server on: #{base_url
|
|
194
|
+
output.puts "🔌 Connected to embedding ollama server on: #{redact_password(base_url)}"
|
|
194
195
|
end
|
|
195
196
|
output.puts "🗄️ Current RAG model is #{bold{@embedding_model}}"
|
|
196
197
|
if @embedding_model_options.present?
|
|
@@ -220,7 +221,7 @@ module OllamaChat::Information
|
|
|
220
221
|
def print_welcome(output: STDOUT)
|
|
221
222
|
feedback(<<~EOT, output:)
|
|
222
223
|
💎 Running ollama_chat version: #{bold{OllamaChat::VERSION}}
|
|
223
|
-
🔌 Connected to ollama server version: #{bold{server_version}} on: #{bold{server_url}}
|
|
224
|
+
🔌 Connected to ollama server version: #{bold{server_version}} on: #{bold{redact_password(server_url)}}
|
|
224
225
|
EOT
|
|
225
226
|
end
|
|
226
227
|
|
|
@@ -465,7 +465,7 @@ module OllamaChat::ModelHandling
|
|
|
465
465
|
if model_metadata = model_present?(model, ollama:)
|
|
466
466
|
return model_metadata
|
|
467
467
|
end
|
|
468
|
-
raise OllamaChat::UnknownModelError, "unknown model named #{
|
|
468
|
+
raise OllamaChat::UnknownModelError, "unknown model named #{model.inspect}"
|
|
469
469
|
end
|
|
470
470
|
end
|
|
471
471
|
|
|
@@ -587,17 +587,25 @@ module OllamaChat::ModelHandling
|
|
|
587
587
|
old_model = @model
|
|
588
588
|
|
|
589
589
|
if model.blank?
|
|
590
|
-
|
|
590
|
+
new_model = choose_model('', old_model)
|
|
591
591
|
else
|
|
592
|
-
|
|
592
|
+
new_model = choose_model(model, config.model.name)
|
|
593
593
|
end
|
|
594
594
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
595
|
+
unless model_metadata = model_present?(new_model, ollama:)
|
|
596
|
+
feedback("Model #{bold{new_model}} not found locally.", type: :warn)
|
|
597
|
+
unless confirm?(prompt: "Pull it from remote? (y/n) ", yes: /\Ay/i)
|
|
598
|
+
feedback("Cancelled.", type: :cancel)
|
|
599
|
+
old_model.full? && model_present?(old_model, ollama:) or
|
|
600
|
+
raise OllamaChat::UnknownModelError, "no usable model after cancel"
|
|
601
|
+
return @model_metadata
|
|
602
|
+
end
|
|
603
|
+
model_metadata = pull_model_unless_present(new_model, ollama:)
|
|
599
604
|
end
|
|
600
605
|
|
|
606
|
+
@model, @model_metadata = new_model, model_metadata
|
|
607
|
+
session.update(current_model: @model)
|
|
608
|
+
|
|
601
609
|
if old_model != @model
|
|
602
610
|
reconfigure_model_options(profile:, keep_options:)
|
|
603
611
|
if @model_metadata&.can?('thinking')
|
data/lib/ollama_chat/oc.rb
CHANGED
|
@@ -114,7 +114,7 @@ module OC
|
|
|
114
114
|
|
|
115
115
|
URL = set do
|
|
116
116
|
description 'Ollama base URL to connect to'
|
|
117
|
-
default {
|
|
117
|
+
default { host = OC::OLLAMA::HOST? and Ollama.base_url(host).to_s }
|
|
118
118
|
sensitive true
|
|
119
119
|
decode { URI.parse(_1) if _1.present? }
|
|
120
120
|
check { value.scheme =~ /\Ahttps?\z/ }
|
|
@@ -122,7 +122,7 @@ module OllamaChat::RAGHandling
|
|
|
122
122
|
selected.merge(remaining)
|
|
123
123
|
break
|
|
124
124
|
else
|
|
125
|
-
selected
|
|
125
|
+
selected << choice
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
end
|
|
@@ -202,7 +202,7 @@ module OllamaChat::RAGHandling
|
|
|
202
202
|
selected.merge(remaining)
|
|
203
203
|
break
|
|
204
204
|
else
|
|
205
|
-
selected
|
|
205
|
+
selected << choice
|
|
206
206
|
end
|
|
207
207
|
end
|
|
208
208
|
end
|
|
@@ -213,14 +213,25 @@ module OllamaChat::RAGHandling
|
|
|
213
213
|
|
|
214
214
|
feedback("Restoring #{selected.size} collection(s): #{selected.join(', ')}")
|
|
215
215
|
|
|
216
|
-
total
|
|
216
|
+
total = 0
|
|
217
|
+
skipped = 0
|
|
217
218
|
collections.slice(*selected).sort.each do |col, group|
|
|
218
219
|
create_memory_collection(col)
|
|
219
220
|
switch_collection(col) do
|
|
221
|
+
existing_tags = Set.new
|
|
222
|
+
@documents.each_record do |r|
|
|
223
|
+
r.tags.each { |t| existing_tags << t.to_s(link: false) }
|
|
224
|
+
end
|
|
225
|
+
|
|
220
226
|
group.each do |entry|
|
|
227
|
+
tags = Array(entry['tags'])
|
|
228
|
+
if tags.any? { |t| existing_tags.include?(t) }
|
|
229
|
+
skipped += 1
|
|
230
|
+
next
|
|
231
|
+
end
|
|
221
232
|
@documents.add(
|
|
222
233
|
[entry['text']],
|
|
223
|
-
tags
|
|
234
|
+
tags:,
|
|
224
235
|
batch_size: 1,
|
|
225
236
|
source: entry['source']
|
|
226
237
|
)
|
|
@@ -230,9 +241,10 @@ module OllamaChat::RAGHandling
|
|
|
230
241
|
end
|
|
231
242
|
|
|
232
243
|
log(:info, 'Memory restored',
|
|
233
|
-
data: { file: filename.to_s, collections: selected, records: total })
|
|
244
|
+
data: { file: filename.to_s, collections: selected, records: total, skipped: })
|
|
234
245
|
feedback(
|
|
235
|
-
"Restored #{total} record(s) across #{selected.size} collection(s) from #{filename.to_s.inspect}."
|
|
246
|
+
"Restored #{total} record(s) across #{selected.size} collection(s) from #{filename.to_s.inspect}." +
|
|
247
|
+
(skipped.zero? ? '' : " (#{skipped} duplicate(s) skipped)."),
|
|
236
248
|
type: :success
|
|
237
249
|
)
|
|
238
250
|
end
|
|
@@ -374,7 +386,7 @@ module OllamaChat::RAGHandling
|
|
|
374
386
|
source_tags = Hash.new { |h, k| h[k] = Set.new }
|
|
375
387
|
@documents.records.each do |record|
|
|
376
388
|
source = record.source.full? or next
|
|
377
|
-
sources
|
|
389
|
+
sources << source
|
|
378
390
|
source_tags[source].merge(record.tags)
|
|
379
391
|
end
|
|
380
392
|
display_map = {}
|
|
@@ -480,7 +492,6 @@ module OllamaChat::RAGHandling
|
|
|
480
492
|
col&.update(name: new_collection.to_s)
|
|
481
493
|
log(:info, "Collection renamed", data: { old_name: current_collection, new_name: new_collection })
|
|
482
494
|
feedback("Renamed current collection #{current_collection} to #{new_collection}.", type: :info)
|
|
483
|
-
refresh_system_prompt
|
|
484
495
|
rescue Sequel::UniqueConstraintViolation
|
|
485
496
|
feedback("Renaming to #{new_collection} failed, it already exists in database.", type: :warn)
|
|
486
497
|
rescue => e
|
|
@@ -600,12 +611,12 @@ module OllamaChat::RAGHandling
|
|
|
600
611
|
end
|
|
601
612
|
|
|
602
613
|
sources = {}
|
|
603
|
-
seen
|
|
614
|
+
seen = Set.new
|
|
604
615
|
@documents.each_record do |record|
|
|
605
616
|
source = @documents.normalize_source(record.source) or next
|
|
606
617
|
if matched_sources.nil? || matched_sources.member?(source)
|
|
607
|
-
seen.
|
|
608
|
-
seen
|
|
618
|
+
seen.member?(source) and next
|
|
619
|
+
seen << source
|
|
609
620
|
unless @documents.source_modified?(source)
|
|
610
621
|
infobar.puts "Source #{source.to_s.inspect} is unmodified. => Skipping."
|
|
611
622
|
next
|
|
@@ -616,8 +627,8 @@ module OllamaChat::RAGHandling
|
|
|
616
627
|
end
|
|
617
628
|
|
|
618
629
|
if patterns = col.patterns.full?
|
|
619
|
-
new_sources = all_file_set(patterns).map(&:to_s).reject { seen.
|
|
620
|
-
new_sources.each { seen
|
|
630
|
+
new_sources = all_file_set(patterns).map(&:to_s).reject { seen.member?(_1) }.to_set
|
|
631
|
+
new_sources.each { seen << _1 }
|
|
621
632
|
new_sources.each { sources[_1] = [] }
|
|
622
633
|
end
|
|
623
634
|
|
|
@@ -678,7 +689,6 @@ module OllamaChat::RAGHandling
|
|
|
678
689
|
end
|
|
679
690
|
feedback("Created collection '#{name}'.", type: :success)
|
|
680
691
|
log(:info, "Collection created", data: { name:, description:, patterns: })
|
|
681
|
-
refresh_system_prompt
|
|
682
692
|
rescue Sequel::UniqueConstraintViolation
|
|
683
693
|
feedback("Collection #{name.inspect} already exists.", type: :warn)
|
|
684
694
|
rescue Sequel::Error => e
|
|
@@ -737,7 +747,6 @@ module OllamaChat::RAGHandling
|
|
|
737
747
|
end
|
|
738
748
|
feedback("Updated collection '#{col.name}'.", type: :success)
|
|
739
749
|
log(:info, "Collection updated", data: { name: col.name, enabled: col.enabled })
|
|
740
|
-
refresh_system_prompt
|
|
741
750
|
rescue Sequel::Error => e
|
|
742
751
|
feedback("Database error: #{e.message}", type: :warn)
|
|
743
752
|
end
|
|
@@ -761,17 +770,31 @@ module OllamaChat::RAGHandling
|
|
|
761
770
|
next
|
|
762
771
|
end
|
|
763
772
|
|
|
773
|
+
if target_name.to_s == 'default'
|
|
774
|
+
feedback(
|
|
775
|
+
"Cannot delete #{target_name.inspect}: it is the default collection. " \
|
|
776
|
+
'Switch to another collection first.',
|
|
777
|
+
type: :warn
|
|
778
|
+
)
|
|
779
|
+
next
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
destroyed = false
|
|
764
783
|
if confirm?(prompt: "⚠️ Are you sure you want to permanently delete #{target_name.inspect}? (y/n) ", yes: /\Ay/i)
|
|
765
784
|
begin
|
|
766
785
|
col.chat = self
|
|
767
786
|
col.destroy
|
|
787
|
+
destroyed = true
|
|
768
788
|
feedback("Deleted collection #{target_name.inspect}.", type: :success)
|
|
769
789
|
log(:info, "Collection deleted", data: { name: target_name })
|
|
770
|
-
refresh_system_prompt
|
|
771
790
|
rescue Sequel::Error => e
|
|
772
791
|
feedback("Database error: #{e.message}", type: :warn)
|
|
773
792
|
rescue => e
|
|
774
793
|
feedback("Error removing from Documentrix: #{e.message}", type: :warn)
|
|
794
|
+
ensure
|
|
795
|
+
if destroyed && session.current_collection == target_name
|
|
796
|
+
session.update(current_collection: 'default')
|
|
797
|
+
end
|
|
775
798
|
end
|
|
776
799
|
else
|
|
777
800
|
feedback("Deletion denied.", type: :denied)
|
|
@@ -42,11 +42,11 @@ module OllamaChat::SystemPromptManagement
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Re-interpolates the current system prompt with fresh dynamic values
|
|
45
|
-
# (persona content,
|
|
45
|
+
# (persona content, persona name, runtime info).
|
|
46
46
|
#
|
|
47
47
|
# Call this after any operation that mutates the sources baked into
|
|
48
|
-
# the system prompt, such as
|
|
49
|
-
#
|
|
48
|
+
# the system prompt, such as switching personas or toggling runtime
|
|
49
|
+
# info.
|
|
50
50
|
#
|
|
51
51
|
# Safe to call when no system prompt is set; returns immediately.
|
|
52
52
|
def refresh_system_prompt
|
|
@@ -60,10 +60,10 @@ class OllamaChat::Tools::Browse
|
|
|
60
60
|
result = browse_url(url)
|
|
61
61
|
|
|
62
62
|
message = if result.success?
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
"Opened #{redact_password(url).inspect} in browser."
|
|
64
|
+
else
|
|
65
|
+
"Could not open #{redact_password(url).inspect} in browser."
|
|
66
|
+
end
|
|
67
67
|
|
|
68
68
|
{
|
|
69
69
|
success: result.success?,
|
|
@@ -21,9 +21,9 @@ class OllamaChat::Tools::ExecuteGrep
|
|
|
21
21
|
function: Tool::Function.new(
|
|
22
22
|
name:,
|
|
23
23
|
description: <<~EOT,
|
|
24
|
-
Pattern searcher – Runs a regex against all files at path,
|
|
25
|
-
case‑insensitive, returning matches (up to max_results).
|
|
26
|
-
quick codebase queries or finding config values.
|
|
24
|
+
Pattern searcher – Runs a regex against all files' contents at path,
|
|
25
|
+
optionally case‑insensitive, returning matches (up to max_results).
|
|
26
|
+
Useful for quick codebase queries or finding config values.
|
|
27
27
|
EOT
|
|
28
28
|
parameters: Tool::Function::Parameters.new(
|
|
29
29
|
type: 'object',
|
|
@@ -92,10 +92,10 @@ class OllamaChat::Tools::GenerateImage
|
|
|
92
92
|
filename:, subfolder: '', type: 'output', rand:
|
|
93
93
|
)
|
|
94
94
|
|
|
95
|
-
chat.links
|
|
95
|
+
chat.links << view_url.to_s
|
|
96
96
|
|
|
97
97
|
message = "Image successfully generated! The user can view it here,"\
|
|
98
|
-
" give this URL to the user: #{view_url}"
|
|
98
|
+
" give this URL to the user: #{redact_password(view_url)}"
|
|
99
99
|
{
|
|
100
100
|
status: 'success',
|
|
101
101
|
message: ,
|
|
@@ -44,13 +44,13 @@ module OllamaChat::Utils::AnalyzeDirectory
|
|
|
44
44
|
# directories are included in the tree. Defaults to `false`, which
|
|
45
45
|
# skips any entry whose base name starts with a dot.
|
|
46
46
|
#
|
|
47
|
-
# @return [
|
|
48
|
-
# * `:
|
|
49
|
-
# * `:
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
47
|
+
# @return [Hash] A hash with two keys:
|
|
48
|
+
# * `:height` – The maximum depth found in the entire tree.
|
|
49
|
+
# * `:entries` – Array of entry hashes. Each hash contains:
|
|
50
|
+
# * `:path` – Absolute path (directories end with `/`)
|
|
51
|
+
# * `:depth` – Depth relative to the root (root = 0)
|
|
52
|
+
# * `:children` – Array of child entry hashes (directories only,
|
|
53
|
+
# omitted when empty)
|
|
54
54
|
#
|
|
55
55
|
# @raise [StandardError] Any exception raised during traversal is
|
|
56
56
|
# rescued and returned as a hash with `:error` and `:message`
|
|
@@ -72,15 +72,16 @@ module OllamaChat::Utils::AnalyzeDirectory
|
|
|
72
72
|
height = e[:depth] if e[:depth] > height
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
structure_each_entry(entries) { |e| e[:height] = height }
|
|
76
|
-
|
|
77
75
|
if max_depth && max_depth <= height
|
|
78
76
|
structure_each_entry(entries) do |e|
|
|
79
|
-
|
|
77
|
+
if children = e[:children].full?
|
|
78
|
+
children.reject! { |c| c[:depth] >= max_depth }
|
|
79
|
+
e.delete(:children) if children.empty?
|
|
80
|
+
end
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
entries
|
|
84
|
+
{ height:, entries: }
|
|
84
85
|
rescue => e
|
|
85
86
|
{ error: e.class, message: e.message }
|
|
86
87
|
end
|
|
@@ -116,19 +117,18 @@ module OllamaChat::Utils::AnalyzeDirectory
|
|
|
116
117
|
next if exclude.any? { |e| child.basename.fnmatch?(e.to_s, File::FNM_PATHNAME) }
|
|
117
118
|
|
|
118
119
|
if child.directory?
|
|
120
|
+
children = recurse_generate_structure(
|
|
121
|
+
child, exclude:, suffix:, depth: depth + 1, include_hidden:
|
|
122
|
+
).full?
|
|
119
123
|
entries << {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
depth:
|
|
125
|
-
}
|
|
124
|
+
path: child.expand_path.to_s << ?/,
|
|
125
|
+
depth: ,
|
|
126
|
+
children: ,
|
|
127
|
+
}.compact
|
|
126
128
|
elsif child.file?
|
|
127
129
|
# Skip unless suffix matches
|
|
128
130
|
next if extname.present? && child.extname != extname
|
|
129
131
|
entries << {
|
|
130
|
-
type: 'file',
|
|
131
|
-
name: child.basename.to_s,
|
|
132
132
|
path: child.expand_path.to_s,
|
|
133
133
|
depth:
|
|
134
134
|
}
|
|
@@ -19,6 +19,7 @@ require 'ollama_chat/utils/cache_fetcher'
|
|
|
19
19
|
# # Process the fetched content
|
|
20
20
|
# end
|
|
21
21
|
class OllamaChat::Utils::Fetcher
|
|
22
|
+
include OllamaChat::Utils::Redact
|
|
22
23
|
# A module that extends IO objects with content type metadata and expiration
|
|
23
24
|
# tracking.
|
|
24
25
|
#
|
|
@@ -154,7 +155,7 @@ class OllamaChat::Utils::Fetcher
|
|
|
154
155
|
def self.get(url, headers: {}, **options, &block)
|
|
155
156
|
cache = options.delete(:cache) and
|
|
156
157
|
cache = OllamaChat::Utils::CacheFetcher.new(cache)
|
|
157
|
-
cache and infobar.puts "Getting #{url.
|
|
158
|
+
cache and infobar.puts "Getting #{OllamaChat::Utils::Redact.redact_password(url).inspect} via cache…"
|
|
158
159
|
if result = cache&.get(url, &block)
|
|
159
160
|
content_type = result&.content_type || 'unknown'
|
|
160
161
|
infobar.puts "…hit, found #{content_type} content in cache."
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
# Redacts credentials from URLs for safe, user-facing display.
|
|
4
|
+
#
|
|
5
|
+
# Whenever a URL that may carry a password (e.g.
|
|
6
|
+
# `http://user:secret@host`) is about to be printed to the terminal or
|
|
7
|
+
# echoed back to the model, run it through {#redact_password} so the
|
|
8
|
+
# secret is masked as `***`.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# OllamaChat::Utils::Redact.redact_password('http://u:secret@example.com')
|
|
12
|
+
# # => "http://u:***@example.com"
|
|
13
|
+
#
|
|
14
|
+
# The module can also be +include+d to gain {#redact_password} as a
|
|
15
|
+
# private helper on the host class.
|
|
16
|
+
module OllamaChat::Utils::Redact
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
# Returns the URL as a string with its password component replaced by
|
|
20
|
+
# `***`. Accepts a +URI+ or a plain +String+ (parsed on the fly). The
|
|
21
|
+
# original object is never mutated: a duplicate is redacted and the
|
|
22
|
+
# result returned as a string. URLs without a password are returned
|
|
23
|
+
# unchanged.
|
|
24
|
+
#
|
|
25
|
+
# @param url [URI, String] the URL whose password should be hidden
|
|
26
|
+
# @return [String] the URL with its password redacted
|
|
27
|
+
def redact_password(url)
|
|
28
|
+
uri = url.is_a?(String) ? URI.parse(url) : url.dup
|
|
29
|
+
uri.password = '***' if uri.password
|
|
30
|
+
uri.to_s
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/ollama_chat/utils.rb
CHANGED
data/lib/ollama_chat/version.rb
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# by hand; it is rewritten on every `rake version` invocation.
|
|
6
6
|
module OllamaChat
|
|
7
7
|
# The current version of the OllamaChat gem as a String.
|
|
8
|
-
VERSION = '0.0.
|
|
8
|
+
VERSION = '0.0.138'
|
|
9
9
|
VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
|
|
10
10
|
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
|
11
11
|
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
|
@@ -31,7 +31,7 @@ module OllamaChat::WebSearching
|
|
|
31
31
|
log(:info, "Web search performed", data: {
|
|
32
32
|
search_engine: engine, query:, results: results.size
|
|
33
33
|
})
|
|
34
|
-
results.each { |url| links
|
|
34
|
+
results.each { |url| links << url }
|
|
35
35
|
end
|
|
36
36
|
else
|
|
37
37
|
feedback("Search engine #{bold{engine}} not implemented!", type: :warn)
|