ollama_chat 0.0.128 → 0.0.130
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 +79 -0
- data/README.md +7 -7
- data/Rakefile +1 -1
- data/lib/ollama_chat/commands.rb +10 -1
- data/lib/ollama_chat/dialog.rb +24 -8
- data/lib/ollama_chat/oc.rb +3 -3
- data/lib/ollama_chat/ollama_chat_config/default_config.yml +5 -9
- data/lib/ollama_chat/rag_handling.rb +19 -11
- data/lib/ollama_chat/source_fetching.rb +2 -2
- data/lib/ollama_chat/tools/execute_shell.rb +1 -1
- data/lib/ollama_chat/tools/get_url.rb +13 -6
- data/lib/ollama_chat/tools/{directory_structure.rb → list_directory.rb} +2 -2
- data/lib/ollama_chat/tools/{gem_path_lookup.rb → lookup_gem_path.rb} +2 -2
- data/lib/ollama_chat/tools/patch_file.rb +7 -5
- data/lib/ollama_chat/tools/read_file.rb +4 -4
- data/lib/ollama_chat/tools.rb +2 -3
- data/lib/ollama_chat/version.rb +1 -1
- data/lib/ollama_chat/web_searching.rb +2 -2
- data/ollama_chat.gemspec +6 -6
- data/spec/ollama_chat/rag_handling_spec.rb +10 -10
- data/spec/ollama_chat/tools/get_url_spec.rb +22 -4
- data/spec/ollama_chat/tools/{directory_structure_spec.rb → list_directory_spec.rb} +6 -6
- data/spec/ollama_chat/tools/{gem_path_lookup_spec.rb → lookup_gem_path_spec.rb} +4 -4
- data/spec/ollama_chat/tools/patch_file_spec.rb +12 -4
- data/spec/ollama_chat/tools/read_file_spec.rb +58 -22
- data/spec/ollama_chat/web_searching_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -0
- metadata +15 -13
- data/lib/ollama_chat/tools/file_context.rb +0 -90
- data/spec/ollama_chat/tools/file_context_spec.rb +0 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01d91ba996f30f84990c3d3eb60d0e65cc46b3eb0c593bd55eab6cc580e935e1
|
|
4
|
+
data.tar.gz: 28563308f748187b5cf15dcad886a775dcb6d2abd3c4466ab66854a10dec63fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edb330105098a15cb10bb0edaaca0131c1f339568c5639d2bc75b02adfaf1a4e0b94176e663e45784e9fb0d978732c854a680b937d135205bcb88c943c02c8b0
|
|
7
|
+
data.tar.gz: 2dff67556aab12d5ad4a9a72239ffa34982804cfa311970a42bf35af33ad1e848baf94f82d74e9e65f21724019963b016c05823fa7e1ec40e01f7b511c1824fd
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,84 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-08 v0.0.130
|
|
4
|
+
|
|
5
|
+
* Replace `ask?` with `confirm?` in `rag_handling.rb` for the `[v]iew` /
|
|
6
|
+
`[c]lear` prompts in `#clear_collection_tags` and
|
|
7
|
+
`#clear_collection_sources` to bypass `Reline` and keep command history
|
|
8
|
+
clean.
|
|
9
|
+
* Add `use_pager(force: true)` in the `#clear_collection_sources` view branch
|
|
10
|
+
to fix display.
|
|
11
|
+
* Rewrite `confirm?` YARD documentation in `dialog.rb` to clarify the
|
|
12
|
+
two-branch return contract (`yes: nil` → raw char, `yes:` matcher → matched
|
|
13
|
+
char or `nil`) and history-pollution rationale.
|
|
14
|
+
* Swap 7 `ask?` → `confirm?` stubs in `rag_handling_spec.rb`.
|
|
15
|
+
* Add `line_numbers: true` to the `read_file` tool block in
|
|
16
|
+
`default_config.yml`.
|
|
17
|
+
* Update `read_file.rb` to fall back to `tool_config.line_numbers?` when the
|
|
18
|
+
model omits the argument and interpolate the live default into the tool
|
|
19
|
+
description.
|
|
20
|
+
* Fix typo in description: `linenumbers` → `line numbers`.
|
|
21
|
+
* Update specs to extract `let :tool`, adjust `nil`-arg expectations for the
|
|
22
|
+
`1: ` prefix, checksum, and `line_count`, and add a new spec asserting raw
|
|
23
|
+
content when `tool_config.line_numbers` is stubbed to `false`.
|
|
24
|
+
|
|
25
|
+
## 2026-10-08 v0.0.129
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
* **`get_url`**: Added support for the `file` scheme and updated the tool
|
|
30
|
+
description to display live allowed schemes.
|
|
31
|
+
* **`get_url`**: Implemented extraction of character card metadata from PNG
|
|
32
|
+
images when `sub_type` is `'png'`.
|
|
33
|
+
* **`patch_file`**: Enabled deletion of line ranges by passing `text: null`.
|
|
34
|
+
Omitting the key now raises an error, while an explicit `nil` value deletes
|
|
35
|
+
the range.
|
|
36
|
+
* **`update_collection`**: Prunes stale sources from the vector store when
|
|
37
|
+
collection patterns are shrunk, ensuring pattern edits propagate cleanly.
|
|
38
|
+
* **`/input`**: Clarified help text to distinguish between smart import
|
|
39
|
+
(content-type detection, HTML→MD, audio→ASR) and raw file reading.
|
|
40
|
+
* **`/conversation clean`**: Expanded help text to list cleanable categories
|
|
41
|
+
(`tools`, `images`, `thinking`, `messages`, `history`, `links`).
|
|
42
|
+
|
|
43
|
+
### Fixes
|
|
44
|
+
|
|
45
|
+
* **`execute_grep`**: Replaced `it` with `_1` in the grep command template to
|
|
46
|
+
fix a Ruby **3.3** deprecation warning regarding the implicit block
|
|
47
|
+
parameter in **3.4**.
|
|
48
|
+
* **`less`/`more` fallback**: Split the combined fallback logic so that
|
|
49
|
+
`less` receives the `-r` flag for raw control characters, while `more`
|
|
50
|
+
remains bare, fixing compatibility with GNU `more` on Debian trixie.
|
|
51
|
+
* **`get_url`**: Fixed `URI.parse` errors for URLs containing spaces by
|
|
52
|
+
encoding them as `%20`.
|
|
53
|
+
* **Web searching prompts**: Corrected swapped prompt references to ensure
|
|
54
|
+
`prompt(:web_summarize)` is used for the 'summarizing' policy and
|
|
55
|
+
`prompt(:web_import)` for the import mode.
|
|
56
|
+
* **`source_fetching`**: Moved the `prompt(:embed)` call earlier to ensure it
|
|
57
|
+
is available for both concurrent and non-concurrent execution paths.
|
|
58
|
+
|
|
59
|
+
### Refactoring
|
|
60
|
+
|
|
61
|
+
* **Tools**: Renamed `directory_structure` to `list_directory` (class
|
|
62
|
+
`DirectoryStructure` → `ListDirectory`).
|
|
63
|
+
* **Tools**: Renamed `gem_path_lookup` to `lookup_gem_path` (class
|
|
64
|
+
`GemPathLookup` → `LookupGemPath`) for verb-first naming consistency.
|
|
65
|
+
* **Tools**: Removed the `file_context` tool, as bulk file context is now
|
|
66
|
+
handled by `/input context` (ContextSpook).
|
|
67
|
+
* **`get_url`**: Reformatted description text for improved readability.
|
|
68
|
+
|
|
69
|
+
### Dependencies
|
|
70
|
+
|
|
71
|
+
* Bumped the minimum version of the `tins` dependency to **1.60.1**.
|
|
72
|
+
|
|
73
|
+
### Testing
|
|
74
|
+
|
|
75
|
+
* Stubbed `Tins::Terminal.columns` and `Tins::Terminal.lines` in
|
|
76
|
+
`spec/spec_helper.rb`.
|
|
77
|
+
* Added specs for PNG character card extraction and updated image spec
|
|
78
|
+
doubles to include `sub_type: 'jpeg'`.
|
|
79
|
+
* Split `patch_file` specs to distinguish between omitted keys (raises) and
|
|
80
|
+
explicit `nil` (deletes).
|
|
81
|
+
|
|
3
82
|
## 2026-10-07 v0.0.128
|
|
4
83
|
|
|
5
84
|
### Features
|
data/README.md
CHANGED
|
@@ -524,18 +524,18 @@ context, manipulate files, and retrieve external information.
|
|
|
524
524
|
|
|
525
525
|
| Category | Tools | Description |
|
|
526
526
|
| :--- | :--- | :--- |
|
|
527
|
-
| **Filesystem** | `read_file`, `write_file`, `patch_file`, `delete_file`, `move_file`, `
|
|
528
|
-
| **Ruby/Dev** | `resolve_tag`, `execute_ri`, `
|
|
527
|
+
| **Filesystem** | `read_file`, `write_file`, `patch_file`, `delete_file`, `move_file`, `list_directory`, `execute_grep`, `execute_shell` | Read, write, and search files within allowed directories; run shell commands as a last resort. |
|
|
528
|
+
| **Ruby/Dev** | `resolve_tag`, `execute_ri`, `lookup_gem_path`, `run_tests`, `eval_ruby` | Introspect Ruby code, check documentation, and run test suites. |
|
|
529
529
|
| **Web/External** | `search_web`, `get_url`, `browse`, `get_rfc`, `get_cve`, `get_endoflife`, `get_ghr`, `get_jira_issue`, `execute_jira_twg` | Access the internet, fetch specific URLs, and look up technical standards; run Jira CLI queries via `twg`. |
|
|
530
530
|
| **System/Util** | `get_time`, `get_location`, `get_current_weather`, `generate_password`, `compute_bmi`, `roll_dice` | General utility functions for time, location, and simple calculations. |
|
|
531
531
|
| **Editor/Clip** | `copy_to_clipboard`, `paste_from_clipboard`, `paste_into_editor`, `open_file_in_editor` | Bridge the gap between the chat and the system clipboard or editor. |
|
|
532
|
-
| **Knowledge** | `search_knowledge`, `
|
|
532
|
+
| **Knowledge** | `search_knowledge`, `lookup_group` | Semantic search for specific snippets, or retrieving prior message groups by UUID. |
|
|
533
533
|
| **Multimodal** | `generate_image` | Generate images via a local ComfyUI server. |
|
|
534
534
|
|
|
535
|
-
***Note on Knowledge Tools**: Use `search_knowledge` for
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
535
|
+
***Note on Knowledge Tools**: Use `search_knowledge` for low-token
|
|
536
|
+
semantic discovery. For comprehensive project context, use the
|
|
537
|
+
`/input context` command instead of loading files into the tool
|
|
538
|
+
call context window.*
|
|
539
539
|
|
|
540
540
|
## External Dependencies
|
|
541
541
|
|
data/Rakefile
CHANGED
|
@@ -49,7 +49,7 @@ GemHadar do
|
|
|
49
49
|
dependency 'reverse_markdown', '~> 3.0'
|
|
50
50
|
dependency 'kramdown-ansi', '~> 0.5'
|
|
51
51
|
dependency 'complex_config', '~> 0.22', '>= 0.22.2'
|
|
52
|
-
dependency 'tins', '~> 1.60'
|
|
52
|
+
dependency 'tins', '~> 1.60', '>= 1.60.1'
|
|
53
53
|
dependency 'search_ui', '>= 0.2'
|
|
54
54
|
dependency 'amatch', '~> 0.4'
|
|
55
55
|
dependency 'pdf-reader', '~> 2.0'
|
data/lib/ollama_chat/commands.rb
CHANGED
|
@@ -380,6 +380,12 @@ module OllamaChat::Commands
|
|
|
380
380
|
💾 Manage conversation content:
|
|
381
381
|
- save/load: Export/import as .json or .jsonl
|
|
382
382
|
- clean: Interactively clean conversation content
|
|
383
|
+
- tools: tool call content
|
|
384
|
+
- images: added images
|
|
385
|
+
- thinking: reasoning content
|
|
386
|
+
- messages: all messages ⇒ tools, images, thinking
|
|
387
|
+
- history: command history
|
|
388
|
+
- links: remembered URLs
|
|
383
389
|
- compact: Summarize old messages, keep recent
|
|
384
390
|
- compact summary: Show last compaction summary
|
|
385
391
|
- summarize: Per-message narrative (-s sentence)
|
|
@@ -867,7 +873,10 @@ module OllamaChat::Commands
|
|
|
867
873
|
EOT
|
|
868
874
|
help: <<~EOT
|
|
869
875
|
📥 Import content (read, summarize, embed, context)
|
|
870
|
-
|
|
876
|
+
Subcommands: path, context, embedding, summary
|
|
877
|
+
(no subcommand) → smart import (HTML→MD, audio→ASR,
|
|
878
|
+
image→context, PNG char cards)
|
|
879
|
+
path → raw file read (no parsing)
|
|
871
880
|
Options: -p (pattern), -w [words], -a (all),
|
|
872
881
|
-c [collection], -t [tags], -e (edit),
|
|
873
882
|
-m (monochrome), -i (summary instruction),
|
data/lib/ollama_chat/dialog.rb
CHANGED
|
@@ -29,21 +29,37 @@ module OllamaChat::Dialog
|
|
|
29
29
|
prefill and Reline.pre_input_hook = old_pre_input_hook
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
# The confirm? method displays a prompt and reads a single
|
|
33
|
-
# from the user in raw mode,
|
|
34
|
-
#
|
|
32
|
+
# The confirm? method displays a prompt and reads a **single keypress**
|
|
33
|
+
# from the user in raw mode (no Enter required), returning that character.
|
|
34
|
+
# Unlike {#ask?}, it does not go through Reline, so it never pollutes the
|
|
35
|
+
# command history — making it the right tool for confirmation gates *and*
|
|
36
|
+
# terse single-key selections such as `[v]iew` / `[c]lear` menus.
|
|
37
|
+
#
|
|
38
|
+
# The returned value depends on whether a positive-response matcher (`yes`)
|
|
39
|
+
# is supplied:
|
|
40
|
+
#
|
|
41
|
+
# - `yes: nil` (default) — the raw keypress is returned verbatim so the
|
|
42
|
+
# caller can dispatch on it (e.g. `case key; when /\Av/i; ...`); on
|
|
43
|
+
# timeout the `default` value is returned, and on interrupt (Ctrl-C)
|
|
44
|
+
# `nil` is returned.
|
|
45
|
+
# - `yes: <Regexp/Object>` — the keypress is returned only when it
|
|
46
|
+
# satisfies `yes === keypress` (e.g. `yes: /\Ay/i`); any other keypress,
|
|
47
|
+
# or an interrupt, yields `nil`.
|
|
35
48
|
#
|
|
36
49
|
# @param prompt [String] the prompt to display to the user
|
|
37
50
|
# @param timeout [Integer, nil] optional timeout in seconds; if nil, the
|
|
38
|
-
# method blocks until input, if 0
|
|
39
|
-
# value.
|
|
51
|
+
# method blocks until input, if 0 it immediately returns the `default`
|
|
52
|
+
# value without waiting.
|
|
40
53
|
# @param default [Object, nil] value returned when the timeout expires
|
|
41
54
|
# (defaults to `nil`)
|
|
42
|
-
# @param yes [Object, nil]
|
|
55
|
+
# @param yes [Object, nil] matcher (`#===`) that defines a positive
|
|
56
|
+
# response; when `nil` the raw keypress is returned for the caller to
|
|
57
|
+
# interpret (default: `nil`)
|
|
43
58
|
# @param output [IO] the IO object to write the prompt and the answer to
|
|
44
59
|
#
|
|
45
|
-
# @return [Object] the
|
|
46
|
-
#
|
|
60
|
+
# @return [Object, nil] see the dispatch rules above: the keypress (or
|
|
61
|
+
# `default` on timeout / `nil` on interrupt) when `yes:` is nil, otherwise
|
|
62
|
+
# the keypress only if it matches `yes`, else `nil`.
|
|
47
63
|
def confirm?(prompt:, timeout: nil, default: nil, yes: nil, output: STDOUT)
|
|
48
64
|
return default if timeout&.zero?
|
|
49
65
|
if prompt.include?('%s')
|
data/lib/ollama_chat/oc.rb
CHANGED
|
@@ -41,10 +41,10 @@ module OC
|
|
|
41
41
|
description 'Pager command to use in case terminal lines are exceeded by output'
|
|
42
42
|
|
|
43
43
|
default do
|
|
44
|
-
if fallback_pager = `which 2>/dev/null less`.full?(:chomp)
|
|
45
|
-
`which 2>/dev/null more`.full?(:chomp)
|
|
46
|
-
then
|
|
44
|
+
if fallback_pager = `which 2>/dev/null less`.full?(:chomp)
|
|
47
45
|
fallback_pager << ' -r'
|
|
46
|
+
elsif fallback_pager = `which 2>/dev/null more`.full?(:chomp)
|
|
47
|
+
fallback_pager
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
end
|
|
@@ -584,13 +584,7 @@ tools:
|
|
|
584
584
|
get_location:
|
|
585
585
|
result_display_timeout: 3
|
|
586
586
|
default: true
|
|
587
|
-
|
|
588
|
-
default: false
|
|
589
|
-
require_confirmation: false
|
|
590
|
-
result_display_timeout: 3
|
|
591
|
-
allowed:
|
|
592
|
-
- './spec'
|
|
593
|
-
directory_structure:
|
|
587
|
+
list_directory:
|
|
594
588
|
default: true
|
|
595
589
|
require_confirmation: false
|
|
596
590
|
result_display_timeout: 3
|
|
@@ -601,7 +595,7 @@ tools:
|
|
|
601
595
|
default: true
|
|
602
596
|
result_display_timeout: 3
|
|
603
597
|
cmd: |
|
|
604
|
-
grep #{'-i' if ignore_case} -m #{max_results} -r #{before.full? { "-B %u " %
|
|
598
|
+
grep #{'-i' if ignore_case} -m #{max_results} -r #{before.full? { "-B %u " % _1 }}#{after.full? { "-A %u " % _1 }}#{context.full? { "-C %u " % _1 }}#{pattern} #{path}
|
|
605
599
|
execute_shell:
|
|
606
600
|
default: false
|
|
607
601
|
require_confirmation: false # Preflight confirm is skipped, but in-tool it's mandatory.
|
|
@@ -629,6 +623,7 @@ tools:
|
|
|
629
623
|
default: true
|
|
630
624
|
require_confirmation: false
|
|
631
625
|
result_display_timeout: 3
|
|
626
|
+
line_numbers: true
|
|
632
627
|
allowed:
|
|
633
628
|
- './tmp'
|
|
634
629
|
- './lib'
|
|
@@ -645,7 +640,8 @@ tools:
|
|
|
645
640
|
schemes:
|
|
646
641
|
- http
|
|
647
642
|
- https
|
|
648
|
-
|
|
643
|
+
- file
|
|
644
|
+
lookup_gem_path:
|
|
649
645
|
result_display_timeout: 3
|
|
650
646
|
default: true
|
|
651
647
|
lookup_group:
|
|
@@ -248,7 +248,7 @@ module OllamaChat::RAGHandling
|
|
|
248
248
|
label = source ? "#{source} #{snippet}" : snippet
|
|
249
249
|
feedback(label, type: :info)
|
|
250
250
|
view_tag_records(tag, [record])
|
|
251
|
-
|
|
251
|
+
confirm?(prompt: " [c]lear / other to go back: ") =~ /\Ac/i or next
|
|
252
252
|
clear_tag_records(tag, source)
|
|
253
253
|
else
|
|
254
254
|
group_lines = []
|
|
@@ -270,7 +270,7 @@ module OllamaChat::RAGHandling
|
|
|
270
270
|
)
|
|
271
271
|
next if chosen.nil? || chosen == '[back]'
|
|
272
272
|
src, recs = group_map[chosen]
|
|
273
|
-
action =
|
|
273
|
+
action = confirm?(prompt: " [v]iew / [c]lear / other to go back: ")
|
|
274
274
|
case action
|
|
275
275
|
when /\Av/i
|
|
276
276
|
view_tag_records(tag, recs)
|
|
@@ -350,11 +350,11 @@ module OllamaChat::RAGHandling
|
|
|
350
350
|
break
|
|
351
351
|
else
|
|
352
352
|
source = display_map[chosen]
|
|
353
|
-
action =
|
|
353
|
+
action = confirm?(prompt: " [v]iew / [c]lear / other to go back: ")
|
|
354
354
|
case action
|
|
355
355
|
when /\Av/i
|
|
356
356
|
records = @documents.records(sources: [ source ])
|
|
357
|
-
use_pager do |output|
|
|
357
|
+
use_pager(force: true) do |output|
|
|
358
358
|
output.puts "#{bold{source}} (#{records.size} records)"
|
|
359
359
|
output.puts
|
|
360
360
|
records.each do |record|
|
|
@@ -547,22 +547,30 @@ module OllamaChat::RAGHandling
|
|
|
547
547
|
feedback("Collection #{collection.inspect} not found in database.", type: :warn)
|
|
548
548
|
return ''
|
|
549
549
|
end
|
|
550
|
+
|
|
551
|
+
matched_sources = nil
|
|
552
|
+
if patterns = col.patterns.full?
|
|
553
|
+
matched_sources = all_file_set(patterns).map(&:to_s).to_set
|
|
554
|
+
end
|
|
555
|
+
|
|
550
556
|
sources = {}
|
|
551
557
|
seen = {}
|
|
552
558
|
@documents.each_record do |record|
|
|
553
559
|
source = @documents.normalize_source(record.source) or next
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
560
|
+
if matched_sources.nil? || matched_sources.member?(source)
|
|
561
|
+
seen.key?(source) and next
|
|
562
|
+
seen[source] = true
|
|
563
|
+
unless @documents.source_modified?(source)
|
|
564
|
+
infobar.puts "Source #{source.to_s.inspect} is unmodified. => Skipping."
|
|
565
|
+
next
|
|
566
|
+
end
|
|
567
|
+
sources[source] = record.tags_set
|
|
559
568
|
end
|
|
560
|
-
sources[source] = record.tags_set
|
|
561
569
|
@documents.source_remove(source)
|
|
562
570
|
end
|
|
563
571
|
|
|
564
572
|
if patterns = col.patterns.full?
|
|
565
|
-
new_sources = all_file_set(patterns).map(&:to_s).reject { seen.key?(_1) }
|
|
573
|
+
new_sources = all_file_set(patterns).map(&:to_s).reject { seen.key?(_1) }.to_set
|
|
566
574
|
new_sources.each { seen[_1] = true }
|
|
567
575
|
new_sources.each { sources[_1] = [] }
|
|
568
576
|
end
|
|
@@ -288,12 +288,12 @@ module OllamaChat::SourceFetching
|
|
|
288
288
|
# to the tags array to apply to that source
|
|
289
289
|
# @return [Array<String>] results from each successful embed call
|
|
290
290
|
def bulk_embed_sources(sources_tags)
|
|
291
|
-
|
|
291
|
+
prompt = prompt(:embed)
|
|
292
|
+
return sources_tags.map { |s, tags| embed(s, prompt:, tags:) }.compact if
|
|
292
293
|
sources_tags.size <= 1 or config.embedding.concurrency <= 1
|
|
293
294
|
|
|
294
295
|
results = []
|
|
295
296
|
mutex = Mutex.new
|
|
296
|
-
prompt = prompt(:embed)
|
|
297
297
|
Tins::Limited.new(config.embedding.concurrency, name: 'embed').process do |l|
|
|
298
298
|
sources_tags.each do |s, tags|
|
|
299
299
|
l.execute do
|
|
@@ -38,7 +38,7 @@ class OllamaChat::Tools::ExecuteShell
|
|
|
38
38
|
then a mandatory y/n/i confirm prompt gates execution.
|
|
39
39
|
Last resort: use ONLY when no dedicated tool covers
|
|
40
40
|
the task (e.g. `git commit`, `bundle install`, `make`).
|
|
41
|
-
Prefer `execute_grep`, `
|
|
41
|
+
Prefer `execute_grep`, `list_directory`, `read_file`,
|
|
42
42
|
`patch_file` over shell equivalents. Only invoke when
|
|
43
43
|
the user explicitly requests it or you have proposed
|
|
44
44
|
the command to the user beforehand. Runs in the current
|
|
@@ -22,9 +22,10 @@ class OllamaChat::Tools::GetURL
|
|
|
22
22
|
function: Tool::Function.new(
|
|
23
23
|
name:,
|
|
24
24
|
description: <<~EOT,
|
|
25
|
-
Web fetcher – Downloads any web resource (HTML, Markdown, plain text,
|
|
26
|
-
at url and makes its contents available to the model. Good
|
|
27
|
-
documentation snippets or viewing generated images.
|
|
25
|
+
Web fetcher – Downloads any web resource (HTML, Markdown, plain text,
|
|
26
|
+
or images) at url and makes its contents available to the model. Good
|
|
27
|
+
for pulling documentation snippets or viewing generated images.
|
|
28
|
+
Allowed schemes: #{Array(tool_config.schemes?).map(&:to_s).join(', ')}
|
|
28
29
|
EOT
|
|
29
30
|
parameters: Tool::Function::Parameters.new(
|
|
30
31
|
type: 'object',
|
|
@@ -46,8 +47,10 @@ class OllamaChat::Tools::GetURL
|
|
|
46
47
|
typically transform the source content into a text-based
|
|
47
48
|
representation
|
|
48
49
|
(e.g., HTML to Markdown, PDF to text) before processing.
|
|
49
|
-
- 'ignoring': Returns the raw content without any
|
|
50
|
-
|
|
50
|
+
- 'ignoring': Returns the raw content without any
|
|
51
|
+
transformation (best for raw text, logs, or code).
|
|
52
|
+
- 'importing': Processes content (e.g., HTML to Markdown) and
|
|
53
|
+
adds it to the chat context.
|
|
51
54
|
- 'embedding': Processes the content for vector storage.
|
|
52
55
|
- 'summarizing': Returns a condensed summary of the content.
|
|
53
56
|
EOT
|
|
@@ -104,7 +107,7 @@ class OllamaChat::Tools::GetURL
|
|
|
104
107
|
|
|
105
108
|
allowed_schemes = Array(tool_config.schemes?).map(&:to_s)
|
|
106
109
|
|
|
107
|
-
url = URI.parse(args.url.to_s)
|
|
110
|
+
url = URI.parse(args.url.to_s.gsub(' ', '%20'))
|
|
108
111
|
unless allowed_schemes.include?(url.scheme)
|
|
109
112
|
raise OllamaChat::ToolFunctionArgumentError,
|
|
110
113
|
"scheme #{url.scheme.inspect} not allowed "\
|
|
@@ -120,6 +123,10 @@ class OllamaChat::Tools::GetURL
|
|
|
120
123
|
case source_io&.content_type&.media_type
|
|
121
124
|
when 'image'
|
|
122
125
|
chat.add_image(chat.images, source_io, source)
|
|
126
|
+
if source_io&.content_type&.sub_type == 'png'
|
|
127
|
+
source_io.rewind
|
|
128
|
+
content = chat.parse_png(source_io).full?(:join, ?\n)
|
|
129
|
+
end
|
|
123
130
|
when 'text', 'application', nil
|
|
124
131
|
case document_policy
|
|
125
132
|
when 'ignoring'
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
#
|
|
7
7
|
# The tool supports traversing directories and returns a structured
|
|
8
8
|
# representation of the file system hierarchy.
|
|
9
|
-
class OllamaChat::Tools::
|
|
9
|
+
class OllamaChat::Tools::ListDirectory
|
|
10
10
|
include OllamaChat::Tools::Concern
|
|
11
11
|
include OllamaChat::Utils::AnalyzeDirectory
|
|
12
12
|
|
|
13
13
|
# @return [String] the registered name for this tool
|
|
14
|
-
def self.register_name = '
|
|
14
|
+
def self.register_name = 'list_directory'
|
|
15
15
|
|
|
16
16
|
# Creates and returns a tool definition for retrieving directory structure.
|
|
17
17
|
#
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
# This tool allows the chat client to find the installation paths of gems
|
|
4
4
|
# on the system. It integrates with the Ollama tool calling system to
|
|
5
5
|
# provide gem path information to the language model.
|
|
6
|
-
class OllamaChat::Tools::
|
|
6
|
+
class OllamaChat::Tools::LookupGemPath
|
|
7
7
|
include OllamaChat::Tools::Concern
|
|
8
8
|
|
|
9
9
|
# @return [String] the registered name for this tool
|
|
10
|
-
def self.register_name = '
|
|
10
|
+
def self.register_name = 'lookup_gem_path'
|
|
11
11
|
|
|
12
12
|
# Creates and returns a tool definition for gem path lookup.
|
|
13
13
|
#
|
|
@@ -71,7 +71,8 @@ class OllamaChat::Tools::PatchFile
|
|
|
71
71
|
type: 'array',
|
|
72
72
|
description: <<~EOT,
|
|
73
73
|
A list of edits. Each edit must contain start_line, end_line,
|
|
74
|
-
and text.
|
|
74
|
+
and text. Set `text` to null to delete the line range
|
|
75
|
+
without replacement.
|
|
75
76
|
EOT
|
|
76
77
|
items: Tool::Function::Parameters::Property.new(
|
|
77
78
|
type: 'object',
|
|
@@ -86,7 +87,8 @@ class OllamaChat::Tools::PatchFile
|
|
|
86
87
|
type: 'integer', description: '1-indexed end line'
|
|
87
88
|
),
|
|
88
89
|
text: Tool::Function::Parameters::Property.new(
|
|
89
|
-
type: 'string',
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'The replacement text. Set to null to delete the range.'
|
|
90
92
|
),
|
|
91
93
|
},
|
|
92
94
|
)
|
|
@@ -234,7 +236,7 @@ class OllamaChat::Tools::PatchFile
|
|
|
234
236
|
s_idx = edit[:start_line] - 1
|
|
235
237
|
e_idx = edit[:end_line] - 1
|
|
236
238
|
|
|
237
|
-
lines[s_idx..e_idx] = [edit[:text]]
|
|
239
|
+
lines[s_idx..e_idx] = edit[:text].nil? ? [] : [edit[:text]]
|
|
238
240
|
end
|
|
239
241
|
|
|
240
242
|
lines * ?\n
|
|
@@ -251,8 +253,8 @@ class OllamaChat::Tools::PatchFile
|
|
|
251
253
|
e[:start_line] or raise OllamaChat::ToolFunctionArgumentError,
|
|
252
254
|
"Edit ##{i + 1} is missing a start_line"
|
|
253
255
|
e[:end_line] ||= e[:start_line]
|
|
254
|
-
e
|
|
255
|
-
"Edit ##{i + 1} is missing
|
|
256
|
+
e.key?(:text) or raise OllamaChat::ToolFunctionArgumentError,
|
|
257
|
+
"Edit ##{i + 1} is missing the text key; set it to null to delete"
|
|
256
258
|
if e[:start_line] < 1 || e[:end_line] > 1 && e[:end_line] > file_size || e[:start_line] > e[:end_line]
|
|
257
259
|
raise OllamaChat::ToolFunctionArgumentError,
|
|
258
260
|
"Invalid range for edit ##{i + 1}: lines #{e[:start_line]}-#{e[:end_line]} (File size: #{file_size})"
|
|
@@ -28,7 +28,7 @@ class OllamaChat::Tools::ReadFile
|
|
|
28
28
|
File reader – Returns raw text from path if it’s within allowed
|
|
29
29
|
directories. No side effects; useful for inspecting config or source
|
|
30
30
|
files. You can optionally specify a line range to read. You can also
|
|
31
|
-
enable prefixing with
|
|
31
|
+
enable prefixing with line numbers; this is highly recommended (and
|
|
32
32
|
practically mandatory) before calling `open_file_in_editor` to ensure
|
|
33
33
|
the line range is precise.
|
|
34
34
|
EOT
|
|
@@ -53,8 +53,8 @@ class OllamaChat::Tools::ReadFile
|
|
|
53
53
|
line_numbers: Tool::Function::Parameters::Property.new(
|
|
54
54
|
type: 'boolean',
|
|
55
55
|
description: <<~EOT
|
|
56
|
-
Whether to prefix each line with its line number,
|
|
57
|
-
|
|
56
|
+
Whether to prefix each line with its line number, e.g.
|
|
57
|
+
"666: The line content…" (default: #{!!tool_config.line_numbers?})
|
|
58
58
|
EOT
|
|
59
59
|
)
|
|
60
60
|
},
|
|
@@ -77,12 +77,12 @@ class OllamaChat::Tools::ReadFile
|
|
|
77
77
|
# @return [String] an error message as a JSON string if the operation fails
|
|
78
78
|
# @raise [JSON::ParserError] if the result cannot be serialized to JSON
|
|
79
79
|
def execute(tool_call, **opts)
|
|
80
|
-
|
|
81
80
|
args = tool_call.function.arguments
|
|
82
81
|
|
|
83
82
|
start_line = args.start_line.full?
|
|
84
83
|
end_line = args.end_line.full?
|
|
85
84
|
line_numbers = args.line_numbers
|
|
85
|
+
line_numbers.nil? and line_numbers = !!tool_config.line_numbers?
|
|
86
86
|
|
|
87
87
|
path = assert_valid_path(args.path, tool_config.allowed?, check: :file)
|
|
88
88
|
full_content = path.read
|
data/lib/ollama_chat/tools.rb
CHANGED
|
@@ -90,15 +90,14 @@ require 'ollama_chat/tools/browse'
|
|
|
90
90
|
require 'ollama_chat/tools/compute_bmi'
|
|
91
91
|
require 'ollama_chat/tools/copy_to_clipboard'
|
|
92
92
|
require 'ollama_chat/tools/delete_file'
|
|
93
|
-
require 'ollama_chat/tools/directory_structure'
|
|
94
93
|
require 'ollama_chat/tools/eval_ruby'
|
|
95
94
|
require 'ollama_chat/tools/execute_grep'
|
|
96
95
|
require 'ollama_chat/tools/execute_ri'
|
|
97
96
|
require 'ollama_chat/tools/execute_shell'
|
|
98
97
|
require 'ollama_chat/tools/execute_jira_twg'
|
|
99
|
-
require 'ollama_chat/tools/file_context'
|
|
100
98
|
require 'ollama_chat/tools/forget'
|
|
101
|
-
require 'ollama_chat/tools/
|
|
99
|
+
require 'ollama_chat/tools/list_directory'
|
|
100
|
+
require 'ollama_chat/tools/lookup_gem_path'
|
|
102
101
|
require 'ollama_chat/tools/generate_image'
|
|
103
102
|
require 'ollama_chat/tools/generate_password'
|
|
104
103
|
require 'ollama_chat/tools/get_current_weather'
|
data/lib/ollama_chat/version.rb
CHANGED
|
@@ -78,7 +78,7 @@ module OllamaChat::WebSearching
|
|
|
78
78
|
end
|
|
79
79
|
prompt.named_placeholders_interpolate({query:})
|
|
80
80
|
elsif document_policy.selected == 'summarizing'
|
|
81
|
-
prompt = prompt(:
|
|
81
|
+
prompt = prompt(:web_summarize).to_s
|
|
82
82
|
results = urls.each_with_object('') do |url, content|
|
|
83
83
|
summarize(url).full? do |c|
|
|
84
84
|
content << c.ask_and_send_or_self(:read)
|
|
@@ -86,7 +86,7 @@ module OllamaChat::WebSearching
|
|
|
86
86
|
end
|
|
87
87
|
prompt.named_placeholders_interpolate({query:, results:})
|
|
88
88
|
else
|
|
89
|
-
prompt = prompt(:
|
|
89
|
+
prompt = prompt(:web_import).to_s
|
|
90
90
|
results = urls.each_with_object('') do |url, content|
|
|
91
91
|
import(url).full? do |c|
|
|
92
92
|
content << c.ask_and_send_or_self(:read)
|