ollama_chat 0.0.117 → 0.0.119
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 +97 -0
- data/README.md +33 -0
- data/Rakefile +1 -1
- data/lib/ollama_chat/commands.rb +2 -1
- data/lib/ollama_chat/compaction.rb +1 -1
- data/lib/ollama_chat/database/models/app_state.rb +5 -4
- data/lib/ollama_chat/input_content.rb +1 -1
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +46 -8
- data/lib/ollama_chat/personae_management.rb +12 -6
- data/lib/ollama_chat/prompt_management.rb +9 -3
- data/lib/ollama_chat/rag_handling.rb +9 -12
- data/lib/ollama_chat/session_management.rb +29 -13
- data/lib/ollama_chat/source_fetching.rb +34 -6
- data/lib/ollama_chat/tools/get_url.rb +15 -1
- data/lib/ollama_chat/utils/chooser.rb +1 -1
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +3 -3
- data/spec/ollama_chat/commands_spec.rb +5 -5
- data/spec/ollama_chat/compaction_spec.rb +1 -21
- data/spec/ollama_chat/input_content_spec.rb +10 -0
- data/spec/ollama_chat/session_management_spec.rb +2 -0
- data/spec/ollama_chat/tools/get_url_spec.rb +29 -14
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7b876b681130c1ff2ec672460bb04aa85ed095e9358dbdaa62d744f82d68720
|
|
4
|
+
data.tar.gz: 3f85175d15231880d45e8f192f9f9af47c861cb8f1475d2fe653309ca173ab1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9cf60761b6ce28cb22873b30808d3398ffcefc9e9991fcf781621b4db8a8fed5fd6cca21de046d8bf2851dd60a7529cfa162125ca4ee567e32c09042f4dc4e81
|
|
7
|
+
data.tar.gz: a2f1e6210141a8f00c4b9428453c49e4e1673e51521f788dcec694cd2c2c9963542bd491618ec8d1a4bb3ad5788588ca3d2c7f51ed3b67b977eaac1b4a59115a
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-09-14 v0.0.119
|
|
4
|
+
|
|
5
|
+
* **Word-boundary fuzzy matching in chooser**
|
|
6
|
+
* Pass `/\b/` as the word-boundary argument to `matcher.similar` in
|
|
7
|
+
`chooser.rb` to filter out partial-word hits, improving ranked results
|
|
8
|
+
for model names containing `/`, `-`, `:`, and `.` separators.
|
|
9
|
+
|
|
10
|
+
* **Parallel embedding via bounded thread pool**
|
|
11
|
+
* Add `concurrency: 3` under `embedding:` in `default_config.yml`.
|
|
12
|
+
* Add `bulk_embed_sources` to `source_fetching.rb` using a
|
|
13
|
+
`Tins::Limited` bounded thread pool with a `Mutex`-guarded results
|
|
14
|
+
array.
|
|
15
|
+
* Change `embed` to accept a `prompt:` kwarg (defaults to
|
|
16
|
+
`prompt(:embed)`) so worker threads share a single resolved template
|
|
17
|
+
instead of each hitting Sequel/SQLite.
|
|
18
|
+
* Replace `STDOUT.puts` with `infobar.puts` in `embed_source` to prevent
|
|
19
|
+
raw output from clobbering the progress bar in concurrent workers.
|
|
20
|
+
* Rewrite the `-p` pattern path in `commands.rb` embedding to build a
|
|
21
|
+
`{source => tags}` Hash and call `bulk_embed_sources`.
|
|
22
|
+
* Rewrite `update_collection` in `rag_handling.rb` to collect both
|
|
23
|
+
modified and new sources into a single Hash and issue one
|
|
24
|
+
`bulk_embed_sources` call instead of a sequential `embed` loop.
|
|
25
|
+
* Update `commands_spec.rb` to stub `bulk_embed_sources` returning an
|
|
26
|
+
array.
|
|
27
|
+
|
|
28
|
+
* **Speed up embedding generation**
|
|
29
|
+
* Implement batch processing in the ollama server.
|
|
30
|
+
|
|
31
|
+
* **Dependency updates**
|
|
32
|
+
* Update `documentrix` minimum version to **0.7.0** in `Rakefile` and
|
|
33
|
+
`ollama_chat.gemspec` to support improved embedding speed.
|
|
34
|
+
|
|
35
|
+
* **Improve session switching and duplication robustness**
|
|
36
|
+
* In `duplicate_session`, replaced defensive `session.lock?` check with a
|
|
37
|
+
direct `session.lock` call, since a freshly duplicated session is never
|
|
38
|
+
yet locked.
|
|
39
|
+
* In `change_session`, added `except_id: session.id` to `choose_session`
|
|
40
|
+
to prevent re-selecting the current session from the chooser.
|
|
41
|
+
* Track `previous_session` as a full object instead of just an ID,
|
|
42
|
+
enabling restoration on lock failure.
|
|
43
|
+
* On lock failure, restore `@session` to the previous session, re-acquire
|
|
44
|
+
its lock, and reset `name` to `??` so the next iteration opens the
|
|
45
|
+
interactive picker instead of retrying the same locked session.
|
|
46
|
+
* Log `previous_session_id` correctly in the "Session changed" info
|
|
47
|
+
message.
|
|
48
|
+
|
|
49
|
+
* **Formatting fix**
|
|
50
|
+
* Add space before `\`.
|
|
51
|
+
|
|
52
|
+
* **Fix `context_spook` returning `nil` instead of context**
|
|
53
|
+
* Reordered `STDOUT.puts` and `ctx.send("to_#{format.downcase}")` in
|
|
54
|
+
`context_spook` so the serialized context is the last expression in the
|
|
55
|
+
`if count > 0` branch, preventing `STDOUT.puts` from clobbering the
|
|
56
|
+
implicit return value.
|
|
57
|
+
* Added a regression spec in `input_content_spec.rb` that exercises the
|
|
58
|
+
`count > 0` path with a real file and `all: true`, asserting the return
|
|
59
|
+
value is a non-blank `String` containing the ingested file path.
|
|
60
|
+
|
|
61
|
+
## 2026-09-05 v0.0.118
|
|
62
|
+
|
|
63
|
+
* Documented the upgrade workflow in the README, adding an "Upgrading"
|
|
64
|
+
section that covers the post-`gem update` flow: `/config diff` with
|
|
65
|
+
`:diffget`, reload, and `/prompt sync` for per-prompt drift resolution.
|
|
66
|
+
* Clarified that the local `config.yml` is a partial override requiring no
|
|
67
|
+
migration script.
|
|
68
|
+
* Improved the prompt drift nagging message in `app_state.rb#seed` by
|
|
69
|
+
replacing the previous prompt with a two-part message featuring a bold
|
|
70
|
+
`Tip:` line suggesting `/prompt sync` and a "Seen these changes?"
|
|
71
|
+
confirmation.
|
|
72
|
+
* Replaced literal `⚠️` emoji with `\u26A0\uFE0F` escapes for consistent
|
|
73
|
+
rendering and introduced `Term::ANSIColor` locally for the bold tip prefix.
|
|
74
|
+
* Added a `session.standup` template to `default_config.yml` defining a
|
|
75
|
+
six-section end-of-day document.
|
|
76
|
+
* Moved the compaction system prompt from `prompts.compaction.system` to
|
|
77
|
+
`prompts.system.compaction` and updated `compaction.rb` to call
|
|
78
|
+
`prompt(:compaction, context: 'system')`.
|
|
79
|
+
* Added `prompts.system.report`, a genre-neutral writer system prompt, and
|
|
80
|
+
updated `session_management.rb#report_session` to pass `system:` and
|
|
81
|
+
`think: true` to `generate` for report generation.
|
|
82
|
+
* Simplified `compaction_spec.rb` to resolve templates from
|
|
83
|
+
`chat.config.prompts.system.compaction` and added a `prompt(:report,
|
|
84
|
+
context: 'system')` expectation to `session_management_spec.rb`.
|
|
85
|
+
* Fixed the `get_url` summarizing policy by wrapping it in `Infobar.busy` and
|
|
86
|
+
`chat.generate` to ensure the LLM produces the summary.
|
|
87
|
+
* Added a `words` (integer) parameter to the `get_url` tool schema, forwarded
|
|
88
|
+
to `summarize_source` to control summary length.
|
|
89
|
+
* Changed `STDOUT.puts` to `infobar.puts` in `summarize_source` to prevent
|
|
90
|
+
garbling spinner output.
|
|
91
|
+
* Updated `get_url_spec.rb` to include `words: nil` in argument doubles,
|
|
92
|
+
reworked the summarizing test to expect `chat.generate`, and added a
|
|
93
|
+
`words: 50` forwarding test.
|
|
94
|
+
* Added `Infobar.busy` spinners with descriptive labels to LLM `generate`
|
|
95
|
+
calls in `personae_management.rb`, `prompt_management.rb`, and
|
|
96
|
+
`session_management.rb`.
|
|
97
|
+
* Modified `prompt_management.rb` to only call `edit_text(suggestions)` if
|
|
98
|
+
`suggestions.present?`.
|
|
99
|
+
|
|
3
100
|
## 2026-09-03 v0.0.117
|
|
4
101
|
|
|
5
102
|
* Fixed `/favourite` subcommand completion rendering by replacing separate
|
data/README.md
CHANGED
|
@@ -19,6 +19,39 @@ gem install ollama_chat
|
|
|
19
19
|
|
|
20
20
|
in your terminal.
|
|
21
21
|
|
|
22
|
+
## Upgrading
|
|
23
|
+
|
|
24
|
+
After `gem update ollama_chat`, the next launch will either
|
|
25
|
+
start cleanly or prompt you to fix the config:
|
|
26
|
+
|
|
27
|
+
1. **Open the config diff.** Run `/config diff`, or wait for
|
|
28
|
+
the automatic `fix_config` prompt if the new version
|
|
29
|
+
introduced required keys. Either way, your `$DIFF_TOOL`
|
|
30
|
+
(default: `vimdiff`) opens with your local `config.yml`
|
|
31
|
+
on one side and the shipped `default_config.yml` on the
|
|
32
|
+
other.
|
|
33
|
+
2. **Pull in the changes.** In vimdiff, use `:diffget` to
|
|
34
|
+
copy new or updated keys from the default into your local
|
|
35
|
+
file. Ignore keys you've intentionally overridden.
|
|
36
|
+
3. **Reload.** Close the diff tool and answer `y` to the
|
|
37
|
+
"restart?" prompt.
|
|
38
|
+
4. **Prompt drift.** If the new version changed any shipped
|
|
39
|
+
prompts, a fingerprint notice lists modified, added, and
|
|
40
|
+
removed prompts. To reconcile your stored prompts with
|
|
41
|
+
the new defaults, run `/prompt sync`. It diffs each
|
|
42
|
+
prompt against the shipped version and lets you decide
|
|
43
|
+
per prompt: adopt the new default, keep your local edit,
|
|
44
|
+
or review the change. After syncing, the fingerprint is
|
|
45
|
+
updated and the nagging stops.
|
|
46
|
+
|
|
47
|
+
If you simply want to dismiss the notice without
|
|
48
|
+
syncing, answer `y` to the boot prompt. The fingerprint
|
|
49
|
+
is stored and you won't be asked again.
|
|
50
|
+
|
|
51
|
+
Your local config is a partial override. Keys you don't
|
|
52
|
+
have fall through to the shipped defaults. No migration
|
|
53
|
+
script needed.
|
|
54
|
+
|
|
22
55
|
## Configuration
|
|
23
56
|
|
|
24
57
|
### Environment Variables
|
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.7.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/commands.rb
CHANGED
|
@@ -883,7 +883,8 @@ module OllamaChat::Commands
|
|
|
883
883
|
if opts[?p]
|
|
884
884
|
all = opts.fetch(?a, false)
|
|
885
885
|
patterns = extract_patterns(arg)
|
|
886
|
-
|
|
886
|
+
sources = file_set_each(patterns, all:).map(&:to_s).to_h { [_1, tags] }
|
|
887
|
+
next bulk_embed_sources(sources) || :next
|
|
887
888
|
elsif arg
|
|
888
889
|
next embed(arg, tags:) || :next
|
|
889
890
|
else
|
|
@@ -191,7 +191,7 @@ module OllamaChat::Compaction
|
|
|
191
191
|
prompt = prompt(:summarize, context: 'compaction').to_s % {
|
|
192
192
|
previous:, groups:
|
|
193
193
|
}
|
|
194
|
-
system = prompt(:
|
|
194
|
+
system = prompt(:compaction, context: 'system').to_s
|
|
195
195
|
|
|
196
196
|
es = OllamaChat::TokenEstimator.estimate(prompt)
|
|
197
197
|
log(:info, "Compaction: sending prompt " \
|
|
@@ -73,19 +73,20 @@ class OllamaChat::Database::Models::AppState < Sequel::Model(OllamaChat::DB)
|
|
|
73
73
|
removed = old.keys - hashes.keys
|
|
74
74
|
changed = hashes.select { |k, v| old[k] && old[k] != v }.keys
|
|
75
75
|
|
|
76
|
-
STDERR.puts "
|
|
76
|
+
STDERR.puts "\u26A0\uFE0F Shipped prompts changed since last boot:"
|
|
77
77
|
changed.each { |k| STDERR.puts " ~ #{k} (modified)" }
|
|
78
78
|
added.each { |k| STDERR.puts " + #{k} (new)" }
|
|
79
79
|
removed.each { |k| STDERR.puts " - #{k} (removed)" }
|
|
80
80
|
elsif !OllamaChat.test_mode?
|
|
81
|
-
STDERR.puts
|
|
81
|
+
STDERR.puts "\u26A0\uFE0F First run — storing prompt fingerprints."
|
|
82
82
|
store_fingerprint(fingerprint, hashes)
|
|
83
83
|
return true
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
c = Term::ANSIColor
|
|
86
87
|
prompt = <<~EOT.chomp << ' '
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
#{c.bold{'Tip'}}: /prompt sync adopts shipped defaults into local config.
|
|
89
|
+
Seen these changes? (y = stop nagging, n = ask again next boot) %s
|
|
89
90
|
EOT
|
|
90
91
|
if OllamaChat.test_mode? || chat.confirm?(prompt:, yes: /\Ay/i, timeout: 5)
|
|
91
92
|
store_fingerprint(fingerprint, hashes)
|
|
@@ -106,8 +106,8 @@ module OllamaChat::InputContent
|
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
if count > 0
|
|
109
|
-
ctx.send("to_#{format.downcase}")
|
|
110
109
|
STDOUT.puts "✅ Ingesting context now."
|
|
110
|
+
ctx.send("to_#{format.downcase}")
|
|
111
111
|
else
|
|
112
112
|
STDERR.puts "❌ No files in context. ⇨ Cancelled."
|
|
113
113
|
end
|
|
@@ -190,12 +190,40 @@ prompts:
|
|
|
190
190
|
|
|
191
191
|
Write a narrative retelling of the roleplay session
|
|
192
192
|
above. Your story MUST:
|
|
193
|
+
|
|
193
194
|
- Capture the emotional arc and key plot beats.
|
|
194
195
|
- Stay in the established setting and character voices.
|
|
195
196
|
- Use vivid, evocative prose; show, don't tell.
|
|
196
197
|
- Highlight turning points, revelations, and character
|
|
197
198
|
growth.
|
|
198
199
|
- Read it like a short story chapter, not a log.
|
|
200
|
+
standup: |
|
|
201
|
+
%{content}
|
|
202
|
+
|
|
203
|
+
Write a document for an end-of-session snapshot. It captures what was
|
|
204
|
+
accomplished, which decisions were made and why, and what happens next —
|
|
205
|
+
the same alignment a Scrum standup provides, but written down so no
|
|
206
|
+
context is lost between sessions.
|
|
207
|
+
|
|
208
|
+
Your document MUST contain these exact sections:
|
|
209
|
+
|
|
210
|
+
1. ## Progress Log — bulleted list of completed tasks with relative file
|
|
211
|
+
paths. 2. ## External References — all URLs, API docs, or GitHub links
|
|
212
|
+
discussed during the session. 3. ## Current Mental Model — current focus,
|
|
213
|
+
existing blockers, and the immediate next step. 4. ## Technical Decision
|
|
214
|
+
Log — rationale for chosen implementations vs. rejected alternatives
|
|
215
|
+
(table). 5. ## Pending Roadmap — Critical → Important → Future Polish. 6.
|
|
216
|
+
## Quick-Start Pointers — 2–3 files or links the next session must read
|
|
217
|
+
#first.
|
|
218
|
+
|
|
219
|
+
Constraints:
|
|
220
|
+
- Use relative Markdown paths for file references.
|
|
221
|
+
- Document *why* decisions were made, not just *what*.
|
|
222
|
+
- Do not restate what the conversation records verbatim.
|
|
223
|
+
- Professional, precise, technical tone.
|
|
224
|
+
|
|
225
|
+
Output only the standup document. No preamble, no
|
|
226
|
+
postamble, no meta-commentary.
|
|
199
227
|
suggest:
|
|
200
228
|
coding: |
|
|
201
229
|
## Context
|
|
@@ -366,12 +394,6 @@ prompts:
|
|
|
366
394
|
Output only the 9 suggestions as plain text, each separated by one empty line.
|
|
367
395
|
No other text.
|
|
368
396
|
compaction:
|
|
369
|
-
system: |
|
|
370
|
-
You are a context summarizer for a chat application.
|
|
371
|
-
Your sole task is to produce a concise, factual narrative
|
|
372
|
-
summary of the conversation provided. Be precise, omit
|
|
373
|
-
speculation, and follow the formatting instructions in the
|
|
374
|
-
user prompt exactly. Output only the summary text.
|
|
375
397
|
summarize: |
|
|
376
398
|
previous_summary:
|
|
377
399
|
%{previous}
|
|
@@ -408,6 +430,20 @@ prompts:
|
|
|
408
430
|
|
|
409
431
|
%{runtime_info}
|
|
410
432
|
assistant: You are a helpful assistant.
|
|
433
|
+
compaction: |
|
|
434
|
+
You are a context summarizer for a chat application.
|
|
435
|
+
Your sole task is to produce a concise, factual narrative
|
|
436
|
+
summary of the conversation provided. Be precise, omit
|
|
437
|
+
speculation, and follow the formatting instructions in the
|
|
438
|
+
user prompt exactly. Output only the summary text.
|
|
439
|
+
report: |
|
|
440
|
+
You are a writer. The user prompt below
|
|
441
|
+
specifies the document to produce: its
|
|
442
|
+
structure, tone, and constraints. Follow
|
|
443
|
+
it exactly. Output only the final document
|
|
444
|
+
— no preamble, no postamble, no commentary,
|
|
445
|
+
no reference to yourself or the act of
|
|
446
|
+
writing.
|
|
411
447
|
voice:
|
|
412
448
|
handler: OllamaChat::Say
|
|
413
449
|
enabled: false
|
|
@@ -442,10 +478,12 @@ embedding:
|
|
|
442
478
|
name: snowflake-arctic-embed:137m
|
|
443
479
|
embedding_length: 768
|
|
444
480
|
context_length: 2048
|
|
445
|
-
options:
|
|
481
|
+
options:
|
|
482
|
+
num_batch: 2048
|
|
446
483
|
# Retrieval prompt template:
|
|
447
484
|
prompt: 'Represent this sentence for searching relevant passages: %s'
|
|
448
|
-
batch_size:
|
|
485
|
+
batch_size: 500
|
|
486
|
+
concurrency: 3
|
|
449
487
|
database_filename: null # ':memory:'
|
|
450
488
|
collection: <%= OC::OLLAMA::CHAT::COLLECTION %>
|
|
451
489
|
found_texts_size: 16384
|
|
@@ -597,12 +597,18 @@ module OllamaChat::PersonaeManagement
|
|
|
597
597
|
# @param persona_name [String] the name of the character to replace {{char}} with
|
|
598
598
|
# @return [String] the resulting structured Markdown persona profile
|
|
599
599
|
def convert_json_character_to_markdown(character, persona_name)
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
600
|
+
Infobar.busy(
|
|
601
|
+
label: 'Converting character…',
|
|
602
|
+
frames: :braille7,
|
|
603
|
+
output: STDOUT,
|
|
604
|
+
) do
|
|
605
|
+
generate(
|
|
606
|
+
prompt: prompt(:persona_architect).to_s % {
|
|
607
|
+
character:,
|
|
608
|
+
persona_template: prompt(:persona).to_s
|
|
609
|
+
}
|
|
610
|
+
).gsub(/{{user}}/i, '%{user}').gsub(/{{char}}/i, persona_name)
|
|
611
|
+
end
|
|
606
612
|
end
|
|
607
613
|
|
|
608
614
|
# Interactively exports a persona profile to a specified file.
|
|
@@ -346,10 +346,16 @@ module OllamaChat::PromptManagement
|
|
|
346
346
|
full_prompt = template % { history:, instruction: }
|
|
347
347
|
|
|
348
348
|
# Execute a silent chat oneshot call (doesn't add to history)
|
|
349
|
-
suggestions =
|
|
349
|
+
suggestions = Infobar.busy(
|
|
350
|
+
label: 'Creating suggestions…',
|
|
351
|
+
frames: :braille7,
|
|
352
|
+
output: STDOUT,
|
|
353
|
+
) do
|
|
354
|
+
generate(prompt: full_prompt)
|
|
355
|
+
end
|
|
350
356
|
|
|
351
357
|
# Pass the AI's suggestions through the editor for final refinement
|
|
352
|
-
edit_text(suggestions)
|
|
358
|
+
edit_text(suggestions) if suggestions.present?
|
|
353
359
|
end
|
|
354
360
|
|
|
355
361
|
# Lists all prompt templates in the database, indicating which are defaults
|
|
@@ -426,7 +432,7 @@ module OllamaChat::PromptManagement
|
|
|
426
432
|
end
|
|
427
433
|
|
|
428
434
|
if orphans.any?
|
|
429
|
-
STDOUT.puts "\n#{orphans.count} orphaned prompt(s) "\
|
|
435
|
+
STDOUT.puts "\n#{orphans.count} orphaned prompt(s) " \
|
|
430
436
|
"(no longer in default config):\n"
|
|
431
437
|
orphans.each { |p| STDOUT.puts " • #{bold{p.name}} in #{italic{p.context}}" }
|
|
432
438
|
STDOUT.puts
|
|
@@ -184,12 +184,13 @@ module OllamaChat::RAGHandling
|
|
|
184
184
|
#
|
|
185
185
|
# @return [String] a newline-separated string of embedding result messages.
|
|
186
186
|
def update_collection(collection)
|
|
187
|
+
results = []
|
|
187
188
|
switch_collection(collection) do
|
|
188
189
|
unless col = database_collection?(collection)
|
|
189
190
|
STDERR.puts "❌ Collection #{collection.inspect} not found in database."
|
|
190
|
-
return
|
|
191
|
+
return ''
|
|
191
192
|
end
|
|
192
|
-
|
|
193
|
+
sources = {}
|
|
193
194
|
seen = {}
|
|
194
195
|
@documents.each_record do |record|
|
|
195
196
|
source = @documents.normalize_source(record.source) or next
|
|
@@ -199,24 +200,20 @@ module OllamaChat::RAGHandling
|
|
|
199
200
|
infobar.puts "Source #{source.to_s.inspect} is unmodified. => Skipping."
|
|
200
201
|
next
|
|
201
202
|
end
|
|
202
|
-
|
|
203
|
+
sources[source] = record.tags_set
|
|
203
204
|
@documents.source_remove(source)
|
|
204
|
-
r = embed(source, tags:) or next
|
|
205
|
-
results << r
|
|
206
205
|
end
|
|
207
206
|
|
|
208
207
|
if patterns = col.patterns.full?
|
|
209
|
-
all_file_set(patterns).
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
r = embed(file.to_s, tags: []) or next
|
|
213
|
-
results << r
|
|
214
|
-
end
|
|
208
|
+
new_sources = all_file_set(patterns).map(&:to_s).reject { seen.key?(_1) }
|
|
209
|
+
new_sources.each { seen[_1] = true }
|
|
210
|
+
new_sources.each { sources[_1] = [] }
|
|
215
211
|
end
|
|
216
212
|
|
|
213
|
+
results.concat(bulk_embed_sources(sources))
|
|
217
214
|
log(:info, "Collection updated", data: { collection:, sources_updated: results.size })
|
|
218
|
-
results * "\n"
|
|
219
215
|
end
|
|
216
|
+
results * ?\n
|
|
220
217
|
end
|
|
221
218
|
|
|
222
219
|
# Extracts and normalizes file patterns from a shell-style string.
|
|
@@ -219,8 +219,7 @@ module OllamaChat::SessionManagement
|
|
|
219
219
|
@session = session.duplicate
|
|
220
220
|
set_previous_session_on_change(old_session.id)
|
|
221
221
|
session.update(name:)
|
|
222
|
-
session.lock
|
|
223
|
-
"Could not lock session #{session.id} #{session.errors.full?(:inspect)}"
|
|
222
|
+
session.lock
|
|
224
223
|
confirm?(
|
|
225
224
|
prompt: "🔔 Clear messages of duplicated session? (y/n) ",
|
|
226
225
|
yes: /\Ay/i
|
|
@@ -444,7 +443,15 @@ module OllamaChat::SessionManagement
|
|
|
444
443
|
end
|
|
445
444
|
template or return
|
|
446
445
|
|
|
447
|
-
|
|
446
|
+
system = prompt(:report, context: 'system').to_s
|
|
447
|
+
|
|
448
|
+
Infobar.busy(
|
|
449
|
+
label: 'Generating session report…',
|
|
450
|
+
frames: :braille7,
|
|
451
|
+
output: STDOUT,
|
|
452
|
+
) do
|
|
453
|
+
generate(system:, prompt: template.to_s % { content: }, think: true)
|
|
454
|
+
end
|
|
448
455
|
end
|
|
449
456
|
|
|
450
457
|
# Generates a report and displays or saves the result.
|
|
@@ -485,11 +492,17 @@ module OllamaChat::SessionManagement
|
|
|
485
492
|
c << "%s: %s\n\n" % [ sender_name, message.content ]
|
|
486
493
|
end
|
|
487
494
|
prompt = prompt(:session_title).to_s % { length:, content: }
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
495
|
+
Infobar.busy(
|
|
496
|
+
label: 'Naming session…',
|
|
497
|
+
frames: :braille7,
|
|
498
|
+
output: STDOUT,
|
|
499
|
+
) do
|
|
500
|
+
generate(prompt:).full? do |name|
|
|
501
|
+
name = name.
|
|
502
|
+
gsub(/(\A(\s|[^A-Za-z])+|(\s|[^A-Za-z])+\z)/m, '').
|
|
503
|
+
gsub(/\s+/, ' ')
|
|
504
|
+
Kramdown::ANSI::Width.truncate(name, length:)
|
|
505
|
+
end
|
|
493
506
|
end
|
|
494
507
|
end
|
|
495
508
|
|
|
@@ -523,9 +536,9 @@ module OllamaChat::SessionManagement
|
|
|
523
536
|
# @param name [String] the name or ID of the session to switch to
|
|
524
537
|
def change_session(name)
|
|
525
538
|
name.full? or name = ??
|
|
526
|
-
|
|
539
|
+
previous_session = nil
|
|
527
540
|
loop do
|
|
528
|
-
if chosen_session = choose_session(name, allow_new: true)
|
|
541
|
+
if chosen_session = choose_session(name, except_id: session.id, allow_new: true)
|
|
529
542
|
if chosen_session.nil? || chosen_session == session
|
|
530
543
|
confirm?(
|
|
531
544
|
prompt: "\n⏎ Same session chosen, Press any key to continue (%s). ",
|
|
@@ -534,7 +547,7 @@ module OllamaChat::SessionManagement
|
|
|
534
547
|
break
|
|
535
548
|
end
|
|
536
549
|
session_close
|
|
537
|
-
|
|
550
|
+
previous_session = session
|
|
538
551
|
@session = chosen_session
|
|
539
552
|
if session.lock?
|
|
540
553
|
messages.read_conversation_jsonl(session.messages.to_s)
|
|
@@ -549,10 +562,13 @@ module OllamaChat::SessionManagement
|
|
|
549
562
|
set_default_persona_name(session.default_persona_name.full? || :none)
|
|
550
563
|
set_current_system_prompt(session.current_system_prompt.full? || 'default')
|
|
551
564
|
session_apply
|
|
552
|
-
log(:info, "Session changed", data: { session_id: session.id, name: session.name, previous_session_id: })
|
|
565
|
+
log(:info, "Session changed", data: { session_id: session.id, name: session.name, previous_session_id: previous_session&.id })
|
|
553
566
|
info_session
|
|
554
567
|
break
|
|
555
568
|
else
|
|
569
|
+
@session = previous_session
|
|
570
|
+
@session.lock
|
|
571
|
+
name = ??
|
|
556
572
|
confirm?(
|
|
557
573
|
prompt: "\n⏎ Session locked: could not switch, Press any key to continue (%s). ",
|
|
558
574
|
timeout: 3
|
|
@@ -565,7 +581,7 @@ module OllamaChat::SessionManagement
|
|
|
565
581
|
end
|
|
566
582
|
end
|
|
567
583
|
ensure
|
|
568
|
-
set_previous_session_on_change(
|
|
584
|
+
set_previous_session_on_change(previous_session&.id)
|
|
569
585
|
session_sync
|
|
570
586
|
end
|
|
571
587
|
|
|
@@ -144,7 +144,7 @@ module OllamaChat::SourceFetching
|
|
|
144
144
|
# @param words [Integer, nil] The target number of words for the summary (defaults to 100)
|
|
145
145
|
# @return [String, nil] The formatted summary message or nil if content is empty or cannot be processed
|
|
146
146
|
def summarize_source(source_io, source, words: nil)
|
|
147
|
-
|
|
147
|
+
infobar.puts "Summarizing #{italic { source_io&.content_type }} document #{source.to_s.inspect} now."
|
|
148
148
|
log(:info, "Source summarized", data: { source: source.to_s, content_type: source_io&.content_type, words: })
|
|
149
149
|
words = words.to_i
|
|
150
150
|
words < 1 and words = 100
|
|
@@ -185,7 +185,7 @@ module OllamaChat::SourceFetching
|
|
|
185
185
|
def embed_source(source_io, source, tags: [], count: nil)
|
|
186
186
|
@embedding.on? or return parse_source(source_io)
|
|
187
187
|
unless @documents.source_modified?(source)
|
|
188
|
-
|
|
188
|
+
infobar.puts "Source #{source.to_s.inspect} already up-to-date. => Skipping."
|
|
189
189
|
log(:info, "Source up-to-date", data: { source: source.to_s })
|
|
190
190
|
return
|
|
191
191
|
end
|
|
@@ -225,9 +225,9 @@ module OllamaChat::SourceFetching
|
|
|
225
225
|
chunks: inputs.size
|
|
226
226
|
})
|
|
227
227
|
if count
|
|
228
|
-
|
|
228
|
+
infobar.puts '%u. %s' % [ count, m ]
|
|
229
229
|
else
|
|
230
|
-
|
|
230
|
+
infobar.puts m
|
|
231
231
|
end
|
|
232
232
|
source = source.to_s
|
|
233
233
|
command = false
|
|
@@ -253,10 +253,14 @@ module OllamaChat::SourceFetching
|
|
|
253
253
|
#
|
|
254
254
|
# @param source [String] The source identifier which can be a command, URL,
|
|
255
255
|
# or file path
|
|
256
|
+
# @param tags [Array<String>] Tags to apply to the embedded source
|
|
257
|
+
# @param prompt [#to_s] The prompt template to format the result with
|
|
258
|
+
# (defaults to `prompt(:embed)`)
|
|
256
259
|
#
|
|
257
260
|
# @return [String, nil] The formatted embedding result or summary message, or
|
|
258
261
|
# nil if the operation fails
|
|
259
|
-
def embed(source, tags: [])
|
|
262
|
+
def embed(source, tags: [], prompt: prompt(:embed))
|
|
263
|
+
prompt = prompt.to_s
|
|
260
264
|
@embedding.on? or return
|
|
261
265
|
fetch_source(source) do |source_io|
|
|
262
266
|
content = parse_source(source_io)
|
|
@@ -264,7 +268,31 @@ module OllamaChat::SourceFetching
|
|
|
264
268
|
source_io.rewind
|
|
265
269
|
embed_source(source_io, source, tags:) or return
|
|
266
270
|
end
|
|
267
|
-
prompt
|
|
271
|
+
prompt.to_s % { source:, collection: }
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Embeds multiple sources concurrently using a bounded thread pool.
|
|
275
|
+
#
|
|
276
|
+
# @param sources_tags [Hash{String => Array}] mapping of source identifier
|
|
277
|
+
# to the tags array to apply to that source
|
|
278
|
+
# @return [Array<String>] results from each successful embed call
|
|
279
|
+
def bulk_embed_sources(sources_tags)
|
|
280
|
+
return sources_tags.map { |s, tags| embed(s, tags:) }.compact if
|
|
281
|
+
sources_tags.size <= 1 or config.embedding.concurrency <= 1
|
|
282
|
+
|
|
283
|
+
results = []
|
|
284
|
+
mutex = Mutex.new
|
|
285
|
+
prompt = prompt(:embed)
|
|
286
|
+
Tins::Limited.new(config.embedding.concurrency, name: 'embed').process do |l|
|
|
287
|
+
sources_tags.each do |s, tags|
|
|
288
|
+
l.execute do
|
|
289
|
+
r = embed(s, prompt:, tags:)
|
|
290
|
+
mutex.synchronize { results << r } if r
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
l.stop
|
|
294
|
+
end
|
|
295
|
+
results
|
|
268
296
|
end
|
|
269
297
|
|
|
270
298
|
private
|
|
@@ -52,6 +52,13 @@ class OllamaChat::Tools::GetURL
|
|
|
52
52
|
- 'summarizing': Returns a condensed summary of the content.
|
|
53
53
|
EOT
|
|
54
54
|
),
|
|
55
|
+
words: Tool::Function::Parameters::Property.new(
|
|
56
|
+
type: 'integer',
|
|
57
|
+
description: <<~EOT,
|
|
58
|
+
Target word count for the summary (only applies when
|
|
59
|
+
document_policy is 'summarizing'). Defaults to 100.
|
|
60
|
+
EOT
|
|
61
|
+
),
|
|
55
62
|
},
|
|
56
63
|
required: %w[url]
|
|
57
64
|
)
|
|
@@ -75,6 +82,7 @@ class OllamaChat::Tools::GetURL
|
|
|
75
82
|
args = tool_call.function.arguments
|
|
76
83
|
url = args.url.to_s
|
|
77
84
|
document_policy = args.document_policy.full? || 'ignoring'
|
|
85
|
+
words = args.words.to_i
|
|
78
86
|
|
|
79
87
|
allowed_schemes = Array(config.tools.functions.get_url.schemes?).map(&:to_s)
|
|
80
88
|
|
|
@@ -99,7 +107,13 @@ class OllamaChat::Tools::GetURL
|
|
|
99
107
|
when 'embedding'
|
|
100
108
|
content = chat.embed_source(source_io, source)
|
|
101
109
|
when 'summarizing'
|
|
102
|
-
content =
|
|
110
|
+
content = Infobar.busy(
|
|
111
|
+
label: 'Summarizing…',
|
|
112
|
+
frames: :braille7,
|
|
113
|
+
output: STDOUT,
|
|
114
|
+
) do
|
|
115
|
+
chat.generate(prompt: chat.summarize_source(source_io, source, words:))
|
|
116
|
+
end
|
|
103
117
|
else
|
|
104
118
|
message = "Invalid document policy #{document_policy.inspect} used."
|
|
105
119
|
end
|
|
@@ -51,7 +51,7 @@ module OllamaChat::Utils::Chooser
|
|
|
51
51
|
matches = entries.map { |n|
|
|
52
52
|
[
|
|
53
53
|
n,
|
|
54
|
-
-matcher.similar(n.ask_and_send_or_self(:value).to_s.downcase)
|
|
54
|
+
-matcher.similar(n.ask_and_send_or_self(:value).to_s.downcase, /\b/)
|
|
55
55
|
]
|
|
56
56
|
}.select { |_, s| s < 0 }.sort_by(&:last).map(&:first)
|
|
57
57
|
matches.empty? and matches = entries
|
data/lib/ollama_chat/version.rb
CHANGED
data/ollama_chat.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: ollama_chat 0.0.
|
|
2
|
+
# stub: ollama_chat 0.0.119 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "ollama_chat".freeze
|
|
6
|
-
s.version = "0.0.
|
|
6
|
+
s.version = "0.0.119".freeze
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
|
|
|
35
35
|
s.add_development_dependency(%q<utils>.freeze, [">= 0".freeze])
|
|
36
36
|
s.add_runtime_dependency(%q<excon>.freeze, ["~> 1.0".freeze])
|
|
37
37
|
s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 1.23".freeze])
|
|
38
|
-
s.add_runtime_dependency(%q<documentrix>.freeze, [">= 0.
|
|
38
|
+
s.add_runtime_dependency(%q<documentrix>.freeze, [">= 0.7.0".freeze])
|
|
39
39
|
s.add_runtime_dependency(%q<unix_socks>.freeze, [">= 0.4".freeze])
|
|
40
40
|
s.add_runtime_dependency(%q<rss>.freeze, ["~> 0.3".freeze])
|
|
41
41
|
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
|
|
@@ -411,11 +411,11 @@ describe OllamaChat::Commands, protect_env: true do
|
|
|
411
411
|
end
|
|
412
412
|
|
|
413
413
|
it 'returns "success" when input is "/input embedding -p (.+)"' do
|
|
414
|
-
expect(chat).to receive(:
|
|
415
|
-
with(
|
|
416
|
-
and_return 'success'
|
|
417
|
-
expect(chat.handle_input("/input embedding -a -p #{asset('*.rb')}"))
|
|
418
|
-
to
|
|
414
|
+
expect(chat).to receive(:bulk_embed_sources).
|
|
415
|
+
with(anything).
|
|
416
|
+
and_return [ 'success' ]
|
|
417
|
+
expect(chat.handle_input("/input embedding -a -p #{asset('*.rb')}"))
|
|
418
|
+
.to eq [ 'success' ]
|
|
419
419
|
end
|
|
420
420
|
|
|
421
421
|
it 'returns :next when input is "/input embedding"' do
|
|
@@ -9,31 +9,11 @@ describe OllamaChat::Compaction do
|
|
|
9
9
|
|
|
10
10
|
connect_to_ollama_server
|
|
11
11
|
|
|
12
|
-
let :summarize_template do
|
|
13
|
-
chat.config.prompts.compaction.summarize
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
let :system_template do
|
|
17
|
-
chat.config.prompts.compaction
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
let :assemble_template do
|
|
21
|
-
chat.config.prompts.compaction.assemble
|
|
13
|
+
chat.config.prompts.system.compaction
|
|
22
14
|
end
|
|
23
15
|
|
|
24
16
|
before do
|
|
25
|
-
allow(chat).to receive(:prompt)
|
|
26
|
-
.with(:summarize, context: 'compaction')
|
|
27
|
-
.and_return(summarize_template)
|
|
28
|
-
|
|
29
|
-
allow(chat).to receive(:prompt)
|
|
30
|
-
.with(:system, context: 'compaction')
|
|
31
|
-
.and_return(system_template)
|
|
32
|
-
|
|
33
|
-
allow(chat).to receive(:prompt)
|
|
34
|
-
.with(:assemble, context: 'compaction')
|
|
35
|
-
.and_return(assemble_template)
|
|
36
|
-
|
|
37
17
|
allow(chat).to receive(:log)
|
|
38
18
|
end
|
|
39
19
|
|
|
@@ -97,5 +97,15 @@ describe OllamaChat::InputContent do
|
|
|
97
97
|
and_return(nil)
|
|
98
98
|
expect(chat.context_spook(nil)).to be_nil
|
|
99
99
|
end
|
|
100
|
+
|
|
101
|
+
it 'returns the serialized context instead of nil' do
|
|
102
|
+
patterns = ['spec/assets/example.rb']
|
|
103
|
+
expect(STDOUT).to receive(:puts).with(/Ingesting context now/)
|
|
104
|
+
result = chat.context_spook(patterns, all: true)
|
|
105
|
+
expect(result).to be_a(String)
|
|
106
|
+
json = JSON.parse(result)
|
|
107
|
+
expected = Pathname.new('spec/assets/example.rb').expand_path.to_path
|
|
108
|
+
expect(json['files'].keys).to include(expected)
|
|
109
|
+
end
|
|
100
110
|
end
|
|
101
111
|
end
|
|
@@ -366,6 +366,8 @@ describe OllamaChat::SessionManagement do
|
|
|
366
366
|
expect(chat).to receive(:sender_name_displayed).and_return('User')
|
|
367
367
|
expect(chat).to receive(:prompt).with('coding_brief', context: 'session')
|
|
368
368
|
.and_return(double(to_s: '%{content}'))
|
|
369
|
+
expect(chat).to receive(:prompt).with(:report, context: 'system')
|
|
370
|
+
.and_return(double(to_s: '%{content}'))
|
|
369
371
|
expect(chat).to receive(:generate).and_return('Brief')
|
|
370
372
|
expect(chat.report_session(name: 'coding_brief')).to eq('Brief')
|
|
371
373
|
end
|
|
@@ -26,7 +26,8 @@ describe OllamaChat::Tools::GetURL do
|
|
|
26
26
|
name: 'get_url',
|
|
27
27
|
arguments: double(
|
|
28
28
|
url: 'https://www.example.com/foo',
|
|
29
|
-
document_policy: nil
|
|
29
|
+
document_policy: nil,
|
|
30
|
+
words: nil
|
|
30
31
|
)
|
|
31
32
|
)
|
|
32
33
|
)
|
|
@@ -55,7 +56,8 @@ describe OllamaChat::Tools::GetURL do
|
|
|
55
56
|
name: 'get_url',
|
|
56
57
|
arguments: double(
|
|
57
58
|
url:,
|
|
58
|
-
document_policy: nil
|
|
59
|
+
document_policy: nil,
|
|
60
|
+
words: nil
|
|
59
61
|
)
|
|
60
62
|
)
|
|
61
63
|
)
|
|
@@ -81,10 +83,11 @@ describe OllamaChat::Tools::GetURL do
|
|
|
81
83
|
'ToolCall',
|
|
82
84
|
function: double(
|
|
83
85
|
name: 'get_url',
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
arguments: double(
|
|
87
|
+
url: 'https://www.example.com/foo',
|
|
88
|
+
document_policy: nil,
|
|
89
|
+
words: nil,
|
|
90
|
+
)
|
|
88
91
|
)
|
|
89
92
|
)
|
|
90
93
|
|
|
@@ -111,7 +114,7 @@ describe OllamaChat::Tools::GetURL do
|
|
|
111
114
|
end
|
|
112
115
|
|
|
113
116
|
it 'handles the "ignoring" policy' do
|
|
114
|
-
args = double(url:, document_policy: 'ignoring')
|
|
117
|
+
args = double(url:, document_policy: 'ignoring', words: nil)
|
|
115
118
|
tool_call = double(function: double(arguments: args))
|
|
116
119
|
|
|
117
120
|
result = described_class.new.execute(tool_call, chat:)
|
|
@@ -120,7 +123,7 @@ describe OllamaChat::Tools::GetURL do
|
|
|
120
123
|
end
|
|
121
124
|
|
|
122
125
|
it 'handles the "importing" policy' do
|
|
123
|
-
args = double(url:, document_policy: 'importing')
|
|
126
|
+
args = double(url:, document_policy: 'importing', words: nil)
|
|
124
127
|
tool_call = double(function: double(arguments: args))
|
|
125
128
|
expect(chat).to receive(:import_source).with(source_io, URI.parse(url)).and_return('imported content')
|
|
126
129
|
|
|
@@ -130,7 +133,7 @@ describe OllamaChat::Tools::GetURL do
|
|
|
130
133
|
end
|
|
131
134
|
|
|
132
135
|
it 'handles the "embedding" policy' do
|
|
133
|
-
args = double(url:, document_policy: 'embedding')
|
|
136
|
+
args = double(url:, document_policy: 'embedding', words: nil)
|
|
134
137
|
tool_call = double(function: double(arguments: args))
|
|
135
138
|
expect(chat).to receive(:embed_source).with(source_io, URI.parse(url)).and_return('embedded content')
|
|
136
139
|
|
|
@@ -140,17 +143,29 @@ describe OllamaChat::Tools::GetURL do
|
|
|
140
143
|
end
|
|
141
144
|
|
|
142
145
|
it 'handles the "summarizing" policy' do
|
|
143
|
-
args = double(url:, document_policy: 'summarizing')
|
|
146
|
+
args = double(url:, document_policy: 'summarizing', words: nil)
|
|
144
147
|
tool_call = double(function: double(arguments: args))
|
|
145
|
-
expect(chat).to receive(:summarize_source).with(source_io, URI.parse(url)).and_return('
|
|
148
|
+
expect(chat).to receive(:summarize_source).with(source_io, URI.parse(url), words: 0).and_return('summarize prompt')
|
|
149
|
+
expect(chat).to receive(:generate).with(prompt: 'summarize prompt').and_return('summarized content')
|
|
146
150
|
|
|
147
151
|
result = described_class.new.execute(tool_call, chat:)
|
|
148
152
|
json = json_object(result)
|
|
149
153
|
expect(json.content).to eq('summarized content')
|
|
150
154
|
end
|
|
151
155
|
|
|
156
|
+
it 'handles the "summarizing" policy with custom words' do
|
|
157
|
+
args = double(url:, document_policy: 'summarizing', words: 50)
|
|
158
|
+
tool_call = double(function: double(arguments: args))
|
|
159
|
+
expect(chat).to receive(:summarize_source).with(source_io, URI.parse(url), words: 50).and_return('summarize prompt 50')
|
|
160
|
+
expect(chat).to receive(:generate).with(prompt: 'summarize prompt 50').and_return('short summary')
|
|
161
|
+
|
|
162
|
+
result = described_class.new.execute(tool_call, chat:)
|
|
163
|
+
json = json_object(result)
|
|
164
|
+
expect(json.content).to eq('short summary')
|
|
165
|
+
end
|
|
166
|
+
|
|
152
167
|
it 'handles an invalid policy' do
|
|
153
|
-
args = double(url:, document_policy: 'chaos_mode')
|
|
168
|
+
args = double(url:, document_policy: 'chaos_mode', words: nil)
|
|
154
169
|
tool_call = double(function: double(arguments: args))
|
|
155
170
|
|
|
156
171
|
result = described_class.new.execute(tool_call, chat:)
|
|
@@ -167,7 +182,7 @@ describe OllamaChat::Tools::GetURL do
|
|
|
167
182
|
expect(chat).to receive(:fetch_source).and_yield(source_io)
|
|
168
183
|
expect(chat).to receive(:add_image).with(chat.images, source_io, URI.parse(url))
|
|
169
184
|
|
|
170
|
-
args = double(url:, document_policy: 'ignoring')
|
|
185
|
+
args = double(url:, document_policy: 'ignoring', words: nil)
|
|
171
186
|
tool_call = double(function: double(arguments: args))
|
|
172
187
|
|
|
173
188
|
result = described_class.new.execute(tool_call, chat:)
|
|
@@ -179,7 +194,7 @@ describe OllamaChat::Tools::GetURL do
|
|
|
179
194
|
source_io = double('SourceIO', content_type: double(media_type: 'video'))
|
|
180
195
|
expect(chat).to receive(:fetch_source).and_yield(source_io)
|
|
181
196
|
|
|
182
|
-
args = double(url:, document_policy: 'ignoring')
|
|
197
|
+
args = double(url:, document_policy: 'ignoring', words: nil)
|
|
183
198
|
tool_call = double(function: double(arguments: args))
|
|
184
199
|
|
|
185
200
|
result = described_class.new.execute(tool_call, chat:)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ollama_chat
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.119
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -169,14 +169,14 @@ dependencies:
|
|
|
169
169
|
requirements:
|
|
170
170
|
- - ">="
|
|
171
171
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: 0.
|
|
172
|
+
version: 0.7.0
|
|
173
173
|
type: :runtime
|
|
174
174
|
prerelease: false
|
|
175
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
176
176
|
requirements:
|
|
177
177
|
- - ">="
|
|
178
178
|
- !ruby/object:Gem::Version
|
|
179
|
-
version: 0.
|
|
179
|
+
version: 0.7.0
|
|
180
180
|
- !ruby/object:Gem::Dependency
|
|
181
181
|
name: unix_socks
|
|
182
182
|
requirement: !ruby/object:Gem::Requirement
|