ollama_chat 0.0.104 → 0.0.106
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 +87 -0
- data/README.md +0 -5
- data/lib/ollama_chat/chat.rb +5 -15
- data/lib/ollama_chat/commands.rb +74 -28
- data/lib/ollama_chat/database/migrations/007_add_collections_table.rb +12 -0
- data/lib/ollama_chat/database/models/collection.rb +81 -0
- data/lib/ollama_chat/database/models/session.rb +6 -0
- data/lib/ollama_chat/information.rb +18 -6
- data/lib/ollama_chat/input_content.rb +1 -1
- data/lib/ollama_chat/model_handling.rb +90 -15
- data/lib/ollama_chat/prompt_management.rb +105 -38
- data/lib/ollama_chat/rag_handling.rb +218 -39
- data/lib/ollama_chat/session_management.rb +16 -9
- data/lib/ollama_chat/tools/patch_file.rb +8 -4
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +4 -4
- data/spec/ollama_chat/chat_spec.rb +3 -43
- data/spec/ollama_chat/commands_spec.rb +15 -8
- data/spec/ollama_chat/session_management_spec.rb +0 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c735b80b131af33178cdbc883a31d6c0693371736cfc91366bcd0d9f42bf2ffb
|
|
4
|
+
data.tar.gz: 18a1019995611afe96a0fad541aad75324834ce9ac1828392b956988f7c916ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db82070f04d57c6679e0ec52474d26b1240b9cea164170258e34916a66097b3c6d3fac51e78a428372377fa956dc7732964387062f1c56d0f04906920e6a3e4e
|
|
7
|
+
data.tar.gz: d049ed9ba805b0d2ff670ecc7c3427f5644373fab6a8bf877b0260edadabb777354d5d118fc40534801ea023a6f52b8467b705cfa126eb70115c9b420a1710ec
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,92 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-08-06 v0.0.106
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- New `/model options delete` subcommand to allow removing saved profiles.
|
|
8
|
+
- Implementation of `delete_model_options_profile` in `model_handling.rb`.
|
|
9
|
+
- New `/prompt rename` subcommand for prompt templates.
|
|
10
|
+
- Implementation of `rename_prompt` method in `prompt_management.rb`.
|
|
11
|
+
- Support for shell-style quoting for file pattern arguments using
|
|
12
|
+
`Shellwords.split`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Tightened validation for the `/conversation` command to restrict filenames to
|
|
17
|
+
`.json` or `.jsonl` extensions.
|
|
18
|
+
- Updated `options` string documentation to include the optional `FILENAME`
|
|
19
|
+
argument and added format hints to `save` and `load` subcommands.
|
|
20
|
+
- Added a `suggest` parameter to `choose_profile_for_model` to allow specific
|
|
21
|
+
profiles to be inserted at the top of selection lists.
|
|
22
|
+
- Updated `copy_model_options_profile` to use the source profile as the
|
|
23
|
+
suggested destination.
|
|
24
|
+
- Refactored error logging in `OllamaChat::Chat` to use a standardized `log`
|
|
25
|
+
method with `:warn` level instead of direct `STDOUT.puts`.
|
|
26
|
+
- Centralized pattern parsing logic by replacing `arg.scan(/(\S+)/).flatten`
|
|
27
|
+
with `extract_patterns` in `commands.rb`.
|
|
28
|
+
- Updated context generation in `input_content.rb` to dynamically call
|
|
29
|
+
`to_json` or `to_toon` based on the selected format.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Resolved a scope limitation in `Prompt#after_destroy` by replacing
|
|
34
|
+
`models::Favourite` with `OllamaChat::Database::Models::Favourite`.
|
|
35
|
+
- Ensured the `default` profile remains valid by resetting it to an empty
|
|
36
|
+
options `{}` instead of deleting it during model option removal.
|
|
37
|
+
|
|
38
|
+
### Refactored
|
|
39
|
+
|
|
40
|
+
- Improved readability in `model_handling.rb` by wrapping long `STDOUT.puts`
|
|
41
|
+
strings.
|
|
42
|
+
- Wrapped prompt operations in `switch_history(:prompt)` for improved
|
|
43
|
+
consistency.
|
|
44
|
+
- Updated YARD documentation for `extract_patterns` to reflect new shell
|
|
45
|
+
semantics.
|
|
46
|
+
|
|
47
|
+
## 2026-08-04 v0.0.105
|
|
48
|
+
|
|
49
|
+
### New Features
|
|
50
|
+
|
|
51
|
+
- **Collection Management**: Introduced the
|
|
52
|
+
`OllamaChat::Database::Models::Collection` model and a corresponding `Sequel`
|
|
53
|
+
migration for persistent storage. Added interactive CLI commands under
|
|
54
|
+
`/collection` including `new`, `edit`, `delete`, and `update all`.
|
|
55
|
+
- **Model Profile Copying**: Added an `options copy` subcommand to allow users
|
|
56
|
+
to interactively copy configuration profiles between models, including
|
|
57
|
+
implementation of `copy_model_options_profile`.
|
|
58
|
+
- **Interactive Prompt Contexts**: Implemented `choose_prompt_context` in
|
|
59
|
+
`prompt_management.rb`, allowing the `/prompt` command to dynamically query
|
|
60
|
+
and select contexts via a new `-c ?` flag.
|
|
61
|
+
|
|
62
|
+
### Enhancements
|
|
63
|
+
|
|
64
|
+
- **Model Options Matching**: Improved profile matching by replacing default
|
|
65
|
+
overwrite prompts with comprehensive checks against all saved `ModelOptions`
|
|
66
|
+
profiles using `ask_and_send(:symbolize_keys_recursive)`. Added pager display
|
|
67
|
+
for available profiles via `use_pager` and the ability to switch profiles via
|
|
68
|
+
`choose_profile_for_model`.
|
|
69
|
+
- **Collection Synchronization**: Enhanced `list_collections` with descriptions
|
|
70
|
+
and paging, and implemented a `Collection.sync` method to backfill database
|
|
71
|
+
records during startup.
|
|
72
|
+
- **Command Refactoring**: Renamed `show_session` to `info_session` within the
|
|
73
|
+
`Commands` module for increased verbosity when no subcommand is provided.
|
|
74
|
+
|
|
75
|
+
### Bug Fixes & Maintenance
|
|
76
|
+
|
|
77
|
+
- **Documentation**:
|
|
78
|
+
- Clarified that the `checksum` for the `patch_file` tool must be an 8 hex
|
|
79
|
+
digit long CRC32.
|
|
80
|
+
- Added YARD `@!attribute` documentation for `links` and `history` in the
|
|
81
|
+
`Session` model.
|
|
82
|
+
- **Code Cleanup**:
|
|
83
|
+
- Replaced `.exists?` and `.first` dataset checks with `.present?` in
|
|
84
|
+
`model_handling.rb` and `session_management.rb`.
|
|
85
|
+
- Removed deprecated CLI flags `-c`, `-C`, `-D`, `-M`, and `-E` in favor of
|
|
86
|
+
interactive management.
|
|
87
|
+
- Added an `after_destroy` hook to the `Collection` model to purge
|
|
88
|
+
corresponding `Documentrix` vector data.
|
|
89
|
+
|
|
3
90
|
## 2026-07-31 v0.0.104
|
|
4
91
|
|
|
5
92
|
### Changed
|
data/README.md
CHANGED
|
@@ -83,11 +83,6 @@ Usage: ollama_chat [OPTIONS]
|
|
|
83
83
|
-n create a new session
|
|
84
84
|
-u URL the ollama base url, OLLAMA_URL
|
|
85
85
|
-m MODEL the ollama model to chat with, OLLAMA_CHAT_MODEL, ?selector
|
|
86
|
-
-c CHAT a saved chat conversation to load
|
|
87
|
-
-C COLLECTION name of the collection used in this conversation
|
|
88
|
-
-D DOCUMENT load document and add to embeddings collection (multiple)
|
|
89
|
-
-M use (empty) MemoryCache for this chat session
|
|
90
|
-
-E disable embeddings for this chat session
|
|
91
86
|
-S open a socket to receive input from ollama_chat_send
|
|
92
87
|
-V display the current version number and quit
|
|
93
88
|
-h this help
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -101,7 +101,7 @@ class OllamaChat::Chat
|
|
|
101
101
|
# @raise [RuntimeError] If the Ollama API version is less than 0.9.0, indicating
|
|
102
102
|
# incompatibility with required API features
|
|
103
103
|
def initialize(argv: ARGV.dup)
|
|
104
|
-
@opts = go 'f:u:m:
|
|
104
|
+
@opts = go 'f:u:m:l:nSVh', argv
|
|
105
105
|
@opts[?h] and exit usage
|
|
106
106
|
@opts[?V] and exit version
|
|
107
107
|
@ollama_chat_config = OllamaChat::OllamaChatConfig.new(@opts[?f])
|
|
@@ -112,14 +112,8 @@ class OllamaChat::Chat
|
|
|
112
112
|
setup_switches
|
|
113
113
|
setup_state_selectors(config)
|
|
114
114
|
connect_ollama
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
else
|
|
118
|
-
messages.read_conversation_jsonl(session.messages.to_s)
|
|
119
|
-
end
|
|
120
|
-
repair_group_uuids
|
|
121
|
-
embedding_enabled.set(config.embedding.enabled && !@opts[?E])
|
|
122
|
-
@documents = setup_documents
|
|
115
|
+
@documents = setup_documents
|
|
116
|
+
models::Collection.sync(self)
|
|
123
117
|
@cache = setup_cache
|
|
124
118
|
@images = []
|
|
125
119
|
@kramdown_ansi_styles = configure_kramdown_ansi_styles
|
|
@@ -221,7 +215,6 @@ class OllamaChat::Chat
|
|
|
221
215
|
# @return [ Symbol ] the collection name symbol
|
|
222
216
|
def initial_collection
|
|
223
217
|
(
|
|
224
|
-
@opts[?C] ||
|
|
225
218
|
session&.current_collection.full? ||
|
|
226
219
|
config.embedding.collection.full? ||
|
|
227
220
|
:default
|
|
@@ -542,7 +535,8 @@ class OllamaChat::Chat
|
|
|
542
535
|
store_messages_in_session
|
|
543
536
|
rescue Ollama::Errors::BadRequestError
|
|
544
537
|
if (think? || tools_support.on?) && !retried
|
|
545
|
-
|
|
538
|
+
msg = "Error in think mode/with tool support, switch both off and retry."
|
|
539
|
+
log(:warn, msg, warn: true)
|
|
546
540
|
sleep 1
|
|
547
541
|
think_mode.selected = 'disabled'
|
|
548
542
|
tools_support.set false
|
|
@@ -639,10 +633,6 @@ class OllamaChat::Chat
|
|
|
639
633
|
redis_url: config.redis.documents.url?,
|
|
640
634
|
debug:
|
|
641
635
|
)
|
|
642
|
-
|
|
643
|
-
document_list = @opts[?D].to_a
|
|
644
|
-
add_documents_from_argv(document_list)
|
|
645
|
-
@documents
|
|
646
636
|
else
|
|
647
637
|
NULL
|
|
648
638
|
end
|
data/lib/ollama_chat/commands.rb
CHANGED
|
@@ -139,12 +139,14 @@ module OllamaChat::Commands
|
|
|
139
139
|
|
|
140
140
|
command(
|
|
141
141
|
name: :model,
|
|
142
|
-
regexp: %r(^/model(?:\s+(change|options|options from session|options to session))?((?:\s+(?:-m))*)$),
|
|
143
|
-
complete: [ 'model', %w[ change options options\ from\ session options\ to\ session ] ],
|
|
142
|
+
regexp: %r(^/model(?:\s+(change|options(?: copy| delete)?|options from session|options to session))?((?:\s+(?:-m))*)$),
|
|
143
|
+
complete: [ 'model', %w[ change options options\ copy options\ delete options\ from\ session options\ to\ session ] ],
|
|
144
144
|
help: <<~EOT
|
|
145
145
|
🤖 Manage AI models & profiles:
|
|
146
146
|
- change: Switch active model
|
|
147
147
|
- options: Edit saved profile config
|
|
148
|
+
- options copy: Copy profile from another model
|
|
149
|
+
- options delete: Delete a saved profile
|
|
148
150
|
- options from session: Save live → Saved
|
|
149
151
|
- options to session: Apply Saved → Live
|
|
150
152
|
-m interactively choose a model
|
|
@@ -167,6 +169,10 @@ module OllamaChat::Commands
|
|
|
167
169
|
when 'options'
|
|
168
170
|
profile = choose_profile_for_model(model, allow_new: true) or next :next
|
|
169
171
|
edit_model_options(model, profile:)
|
|
172
|
+
when 'options copy'
|
|
173
|
+
copy_model_options_profile(model)
|
|
174
|
+
when 'options delete'
|
|
175
|
+
delete_model_options_profile(model)
|
|
170
176
|
when 'options from session'
|
|
171
177
|
profile = choose_profile_for_model(model) || 'default'
|
|
172
178
|
copy_model_options_from_session(model, profile:)
|
|
@@ -276,7 +282,7 @@ module OllamaChat::Commands
|
|
|
276
282
|
) do |subcommand, opts, name|
|
|
277
283
|
case subcommand
|
|
278
284
|
when nil
|
|
279
|
-
|
|
285
|
+
info_session
|
|
280
286
|
when 'list'
|
|
281
287
|
list_sessions
|
|
282
288
|
when 'new'
|
|
@@ -457,50 +463,71 @@ module OllamaChat::Commands
|
|
|
457
463
|
|
|
458
464
|
command(
|
|
459
465
|
name: :prompt,
|
|
460
|
-
regexp: %r(^/prompt(?:\s+(edit|info|add|delete|list|duplicate|import|export|reset|-e))?(\s+(?:-[ef]|-c\s
|
|
461
|
-
complete: [ 'prompt', %w[ edit info add delete list duplicate import export reset ] ],
|
|
466
|
+
regexp: %r(^/prompt(?:\s+(edit|info|add|delete|list|duplicate|import|export|reset|rename|-e))?(\s+(?:-[ef]|-c\s+(?:\w+|\?)))?(?:\s+([^-].*))?$),
|
|
467
|
+
complete: [ 'prompt', %w[ edit info add delete list duplicate import export reset rename ] ],
|
|
462
468
|
optional: true,
|
|
463
469
|
options: '[-c CONTEXT|-e|-f]',
|
|
464
470
|
help: <<~EOT,
|
|
465
471
|
📝 Manage prompt templates:
|
|
466
472
|
Subcommands: edit, info, add, delete, list,
|
|
467
|
-
duplicate, import, export, reset.
|
|
468
|
-
Options: -c [context]
|
|
473
|
+
duplicate, import, export, reset, rename.
|
|
474
|
+
Options: -c [context]
|
|
475
|
+
(? for interactive in /prompt),
|
|
476
|
+
-e (edit next)
|
|
469
477
|
EOT
|
|
470
478
|
) do |subcommand, opts, filename|
|
|
471
479
|
opts = go_command('fc:', opts)
|
|
480
|
+
context = if subcommand.nil? || subcommand == '-e'
|
|
481
|
+
if opts[?c] == ??
|
|
482
|
+
choose_prompt_context
|
|
483
|
+
else
|
|
484
|
+
opts[?c] || 'prompt'
|
|
485
|
+
end
|
|
486
|
+
else
|
|
487
|
+
opts[?c] || choose_prompt_context
|
|
488
|
+
end
|
|
489
|
+
unless context
|
|
490
|
+
STDOUT.puts 'Cancelled.'
|
|
491
|
+
next :next
|
|
492
|
+
end
|
|
493
|
+
|
|
472
494
|
case subcommand
|
|
473
495
|
when 'add'
|
|
474
|
-
add_new_prompt(context:
|
|
496
|
+
add_new_prompt(context:)
|
|
475
497
|
when 'delete'
|
|
476
|
-
choose_and_delete_prompt(context
|
|
498
|
+
choose_and_delete_prompt(context:, force: opts[?f])
|
|
477
499
|
when 'edit'
|
|
478
|
-
choose_and_edit_prompt(context:
|
|
500
|
+
choose_and_edit_prompt(context:)
|
|
479
501
|
when 'list'
|
|
480
|
-
list_prompts(context:
|
|
502
|
+
list_prompts(context:)
|
|
481
503
|
when 'duplicate'
|
|
482
|
-
duplicate_prompt(context:
|
|
504
|
+
duplicate_prompt(context:)
|
|
505
|
+
when 'rename'
|
|
506
|
+
rename_prompt(context:)
|
|
483
507
|
when 'import'
|
|
484
|
-
import_prompt(filename, context:
|
|
508
|
+
import_prompt(filename, context:)
|
|
485
509
|
when 'export'
|
|
486
|
-
export_prompt(context:
|
|
510
|
+
export_prompt(context:)
|
|
487
511
|
when 'info'
|
|
488
|
-
info_prompt(context:
|
|
512
|
+
info_prompt(context:)
|
|
489
513
|
when 'reset'
|
|
490
514
|
if prompt = choose_prompt(
|
|
491
515
|
default: true,
|
|
492
|
-
context
|
|
516
|
+
context:,
|
|
493
517
|
prompt: 'Which prompt needs to be restored to its origin? %s'
|
|
494
518
|
)
|
|
495
519
|
then
|
|
496
|
-
if reset_prompt_to_default(prompt.name, context:
|
|
520
|
+
if reset_prompt_to_default(prompt.name, context:)
|
|
497
521
|
STDOUT.puts "Reset prompt #{bold{prompt.name}} to default."
|
|
498
522
|
else
|
|
499
523
|
STDOUT.puts "No default value found for prompt #{bold{prompt.name}}."
|
|
500
524
|
end
|
|
501
525
|
end
|
|
502
526
|
when nil, '-e'
|
|
503
|
-
if prompt = choose_prompt(
|
|
527
|
+
if prompt = choose_prompt(
|
|
528
|
+
prompt: 'Which template shall guide the next response? %s',
|
|
529
|
+
context:
|
|
530
|
+
).full?(&:to_s)
|
|
504
531
|
if subcommand
|
|
505
532
|
prompt = edit_text(prompt)
|
|
506
533
|
next prompt
|
|
@@ -543,12 +570,13 @@ module OllamaChat::Commands
|
|
|
543
570
|
|
|
544
571
|
command(
|
|
545
572
|
name: :conversation,
|
|
546
|
-
regexp: %r(^/conversation\s+(clean|save|load)(\s+-c)?(?:\s+([^-]
|
|
573
|
+
regexp: %r(^/conversation\s+(clean|save|load)(\s+-c)?(?:\s+([^-].*\.jsonl?))?$),
|
|
547
574
|
complete: [ 'conversation', %w[ save load clean ] ],
|
|
548
|
-
options: '[-c]',
|
|
575
|
+
options: '[-c] [FILENAME]',
|
|
549
576
|
help: <<~EOT
|
|
550
577
|
💾 Save/Load conversation state
|
|
551
578
|
(-c to clean before saving)
|
|
579
|
+
FILENAME ends with .json or .jsonl
|
|
552
580
|
Or clean inplace (removes tool content, images, and thinking)
|
|
553
581
|
EOT
|
|
554
582
|
) do |subcommand,opts,path|
|
|
@@ -582,13 +610,17 @@ module OllamaChat::Commands
|
|
|
582
610
|
|
|
583
611
|
command(
|
|
584
612
|
name: :collection,
|
|
585
|
-
regexp: %r(^/collection(?:\s+(change|clear|list|rename|update))?$),
|
|
586
|
-
complete: [ 'collection', %w[ change clear list rename update ] ],
|
|
613
|
+
regexp: %r(^/collection(?:\s+(change|clear|list|rename|update(?: all)?|new|edit|delete))?$),
|
|
614
|
+
complete: [ 'collection', %w[ change clear list rename update update\ all new edit delete ] ],
|
|
587
615
|
optional: true,
|
|
588
616
|
help: <<~EOT
|
|
589
617
|
📚 Manage RAG collections:
|
|
590
618
|
- change/clear/list/rename
|
|
591
619
|
- update: Re-index modified docs
|
|
620
|
+
- update all: Re-index all collections
|
|
621
|
+
- new: Interactively create a new collection
|
|
622
|
+
- edit: Interactively update an existing collection
|
|
623
|
+
- delete: Permanently remove a collection
|
|
592
624
|
- (no subcommand): Show stats
|
|
593
625
|
EOT
|
|
594
626
|
) do |subcommand|
|
|
@@ -601,11 +633,25 @@ module OllamaChat::Commands
|
|
|
601
633
|
list_collections
|
|
602
634
|
when 'rename'
|
|
603
635
|
rename_collection(collection)
|
|
636
|
+
when 'update all'
|
|
637
|
+
results = ''
|
|
638
|
+
all_collections.pluck(:name).each do |collection|
|
|
639
|
+
STDOUT.puts "📝 Updating collection #{collection.inspect}… "
|
|
640
|
+
results << update_collection(collection) << ?\n
|
|
641
|
+
STDOUT.puts "✅ Done."
|
|
642
|
+
end
|
|
643
|
+
results.full? and next results
|
|
604
644
|
when 'update'
|
|
605
|
-
if results = update_collection
|
|
645
|
+
if results = update_collection(collection)
|
|
606
646
|
disable_content_parsing
|
|
607
647
|
next results
|
|
608
648
|
end
|
|
649
|
+
when 'new'
|
|
650
|
+
create_collection
|
|
651
|
+
when 'edit'
|
|
652
|
+
edit_collection
|
|
653
|
+
when 'delete'
|
|
654
|
+
delete_collection
|
|
609
655
|
when nil
|
|
610
656
|
collection_stats
|
|
611
657
|
end
|
|
@@ -786,7 +832,7 @@ module OllamaChat::Commands
|
|
|
786
832
|
if opts[?p]
|
|
787
833
|
words = opts.fetch(?w, 100)
|
|
788
834
|
all = opts.fetch(?a, false)
|
|
789
|
-
|
|
835
|
+
patterns = extract_patterns(arg)
|
|
790
836
|
next provide_file_set_content(patterns, all:, skip_blank: true) { summarize(_1, words:) } || :next
|
|
791
837
|
elsif arg
|
|
792
838
|
words = opts.fetch(?w, 100)
|
|
@@ -800,7 +846,7 @@ module OllamaChat::Commands
|
|
|
800
846
|
opts = go_command('pa', opts)
|
|
801
847
|
if opts[?p]
|
|
802
848
|
all = opts.fetch(?a, false)
|
|
803
|
-
patterns = arg
|
|
849
|
+
patterns = extract_patterns(arg).full? || [ '**/*' ]
|
|
804
850
|
next context_spook(patterns, all:) || :next
|
|
805
851
|
elsif arg
|
|
806
852
|
next context_spook(Array(arg.to_s), all: true) || :next
|
|
@@ -822,7 +868,7 @@ module OllamaChat::Commands
|
|
|
822
868
|
tags = opts[?t].full?(:split, ?,)
|
|
823
869
|
if opts[?p]
|
|
824
870
|
all = opts.fetch(?a, false)
|
|
825
|
-
|
|
871
|
+
patterns = extract_patterns(arg)
|
|
826
872
|
next provide_file_set_content(patterns, all:, skip_blank: true) { embed(_1, tags:) } || :next
|
|
827
873
|
elsif arg
|
|
828
874
|
next embed(arg, tags:) || :next
|
|
@@ -835,7 +881,7 @@ module OllamaChat::Commands
|
|
|
835
881
|
opts = go_command('pae', opts)
|
|
836
882
|
if opts[?p]
|
|
837
883
|
all = opts.fetch(?a, false)
|
|
838
|
-
|
|
884
|
+
patterns = extract_patterns(arg)
|
|
839
885
|
read = -> pathname {
|
|
840
886
|
STDOUT.puts "Reading #{pathname.to_s.inspect}."
|
|
841
887
|
pathname.read
|
|
@@ -855,7 +901,7 @@ module OllamaChat::Commands
|
|
|
855
901
|
opts = go_command('pae', opts)
|
|
856
902
|
if opts[?p]
|
|
857
903
|
all = opts.fetch(?a, false)
|
|
858
|
-
|
|
904
|
+
patterns = extract_patterns(arg)
|
|
859
905
|
next provide_file_set_content(patterns, all:, skip_blank: true) { import(_1) } || :next
|
|
860
906
|
elsif arg
|
|
861
907
|
source = arg
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Sequel.migration do
|
|
2
|
+
change do
|
|
3
|
+
create_table :collections do
|
|
4
|
+
primary_key :id
|
|
5
|
+
String :name, null: false, unique: true
|
|
6
|
+
Text :description, null: false
|
|
7
|
+
Text :patterns # JSON-encoded array of globs
|
|
8
|
+
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP, null: false
|
|
9
|
+
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP, null: false
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Represents a document collection stored in the database, allowing for
|
|
2
|
+
# dynamic management of documentrix collections.
|
|
3
|
+
#
|
|
4
|
+
# This model stores collections with a name, description, and patterns
|
|
5
|
+
# for automatic file discovery and synchronization.
|
|
6
|
+
class OllamaChat::Database::Models::Collection < Sequel::Model(OllamaChat::DB)
|
|
7
|
+
include OllamaChat::Database::Duplicatable
|
|
8
|
+
|
|
9
|
+
plugin :timestamps, update_on_create: true
|
|
10
|
+
plugin :serialization, :json, :patterns
|
|
11
|
+
plugin :validation_helpers
|
|
12
|
+
|
|
13
|
+
# Validates the collection.
|
|
14
|
+
#
|
|
15
|
+
# Ensures that the `name` is present and unique.
|
|
16
|
+
def validate
|
|
17
|
+
super
|
|
18
|
+
validates_presence :name
|
|
19
|
+
validates_unique :name
|
|
20
|
+
validates_presence :description
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sets the chat instance associated with this collection.
|
|
24
|
+
#
|
|
25
|
+
# This allows the collection to interact with the chat's document
|
|
26
|
+
# store during lifecycle events, such as cleanup upon destruction.
|
|
27
|
+
#
|
|
28
|
+
# @param chat [OllamaChat::Chat] the chat instance
|
|
29
|
+
attr_writer :chat
|
|
30
|
+
|
|
31
|
+
# Hook to clean up the corresponding Documentrix collection when
|
|
32
|
+
# the database record is destroyed.
|
|
33
|
+
#
|
|
34
|
+
# This ensures that we don't leave orphaned vector data in the
|
|
35
|
+
# Documentrix engine when the underlying collection record is removed.
|
|
36
|
+
def after_destroy
|
|
37
|
+
super
|
|
38
|
+
@chat or return
|
|
39
|
+
@chat.switch_collection(name) do
|
|
40
|
+
@chat.documents.clear
|
|
41
|
+
end
|
|
42
|
+
true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Synchronizes the database records with the Documentrix collections.
|
|
46
|
+
#
|
|
47
|
+
# This method iterates through the configured collections in the chat's
|
|
48
|
+
# document store and ensures that every collection has a corresponding
|
|
49
|
+
# record in the database. If a collection exists in Documentrix but not
|
|
50
|
+
# in the database, a new record is created with a default description.
|
|
51
|
+
#
|
|
52
|
+
# @param chat [OllamaChat::Chat] the chat instance providing the configuration
|
|
53
|
+
def self.sync(chat)
|
|
54
|
+
chat.documents.collections.each do |name|
|
|
55
|
+
where(name: name.to_s).first and next
|
|
56
|
+
create(
|
|
57
|
+
name: name.to_s,
|
|
58
|
+
description: "TODO: Describe collection #{name}",
|
|
59
|
+
patterns: []
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @!attribute [v] id
|
|
65
|
+
# @return [Integer] The primary key for the collection entry.
|
|
66
|
+
#
|
|
67
|
+
# @!attribute [v] name
|
|
68
|
+
# @return [String] The name of the collection (matches documentrix name).
|
|
69
|
+
#
|
|
70
|
+
# @!attribute [v] description
|
|
71
|
+
# @return [String, nil] A description of the collection.
|
|
72
|
+
#
|
|
73
|
+
# @!attribute [v] patterns
|
|
74
|
+
# @return [Array, nil] An array of glob patterns for file discovery.
|
|
75
|
+
#
|
|
76
|
+
# @!attribute [v] created_at
|
|
77
|
+
# @return [Time, nil] The timestamp when the collection was created.
|
|
78
|
+
#
|
|
79
|
+
# @!attribute [v] updated_at
|
|
80
|
+
# @return [Time, nil] The timestamp of the last update to the collection.
|
|
81
|
+
end
|
|
@@ -137,6 +137,12 @@ class OllamaChat::Database::Models::Session < Sequel::Model(OllamaChat::DB)
|
|
|
137
137
|
# @!attribute [v] messages
|
|
138
138
|
# @return [String] The full conversation history, stored in JSONL format.
|
|
139
139
|
#
|
|
140
|
+
# @!attribute [v] links
|
|
141
|
+
# @return [String] A text field storing links associated with the session.
|
|
142
|
+
#
|
|
143
|
+
# @!attribute [v] history
|
|
144
|
+
# @return [String] A text field storing the history for the session.
|
|
145
|
+
#
|
|
140
146
|
# @!attribute [v] created_at
|
|
141
147
|
# @return [Time, nil] The timestamp when the session was created.
|
|
142
148
|
#
|
|
@@ -72,6 +72,7 @@ module OllamaChat::Information
|
|
|
72
72
|
#
|
|
73
73
|
# @param output [IO] the output stream to write the message to
|
|
74
74
|
def collection_stats(output: STDOUT)
|
|
75
|
+
col = database_collection?(collection)
|
|
75
76
|
length = (Tins::Terminal.cols - 10).clamp(0..)
|
|
76
77
|
wrapped_tags = Kramdown::ANSI::Width.
|
|
77
78
|
wrap(@documents.tags.to_a.join(', '), length:).
|
|
@@ -79,6 +80,7 @@ module OllamaChat::Information
|
|
|
79
80
|
output.puts <<~EOT
|
|
80
81
|
Current Collection
|
|
81
82
|
Name: #{bold{collection}}
|
|
83
|
+
Patterns: #{italic{col&.patterns&.join(' ')}}
|
|
82
84
|
#Embeddings: #{@documents.size}
|
|
83
85
|
#Tags: #{@documents.tags.size}
|
|
84
86
|
Tags:
|
|
@@ -235,11 +237,6 @@ module OllamaChat::Information
|
|
|
235
237
|
-n create a new session
|
|
236
238
|
-u URL the ollama base url, OLLAMA_URL
|
|
237
239
|
-m MODEL the ollama chat model, OLLAMA_CHAT_MODEL, ?selector
|
|
238
|
-
-c CHAT a saved chat conversation to load
|
|
239
|
-
-C COLLECTION name of the collection used in this conversation
|
|
240
|
-
-D DOCUMENT load document and add to embeddings collection (multiple)
|
|
241
|
-
-M use (empty) MemoryCache for this chat session
|
|
242
|
-
-E disable embeddings for this chat session
|
|
243
240
|
-S open a socket to receive input from ollama_chat_send
|
|
244
241
|
-V display the current version number and quit
|
|
245
242
|
-h this help
|
|
@@ -297,6 +294,21 @@ module OllamaChat::Information
|
|
|
297
294
|
config.infobar.message.to_h
|
|
298
295
|
end
|
|
299
296
|
|
|
297
|
+
# Retrieves a hash of collection names and their descriptions from the
|
|
298
|
+
# database.
|
|
299
|
+
#
|
|
300
|
+
# This is used to provide context to the AI model about available RAG
|
|
301
|
+
# collections.
|
|
302
|
+
#
|
|
303
|
+
# @return [Hash{String => String}] a hash mapping collection names to their
|
|
304
|
+
# descriptions
|
|
305
|
+
def collection_descriptions
|
|
306
|
+
cols = models::Collection.select(:name, :description).order(:name)
|
|
307
|
+
cols.each_with_object({}) do |c, hash|
|
|
308
|
+
hash[c.name] = c.description
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
300
312
|
# Generates a hash containing static runtime information.
|
|
301
313
|
#
|
|
302
314
|
# This method collects session-level constants including the user,
|
|
@@ -307,7 +319,7 @@ module OllamaChat::Information
|
|
|
307
319
|
def static_runtime_information_values
|
|
308
320
|
{
|
|
309
321
|
client: ,
|
|
310
|
-
collections: JSON.pretty_generate(
|
|
322
|
+
collections: JSON.pretty_generate(collection_descriptions),
|
|
311
323
|
current_directory: Pathname.pwd.expand_path.to_path,
|
|
312
324
|
languages: config.languages * ', ',
|
|
313
325
|
location: location.on?.full? { location_description } || 'n/a',
|
|
@@ -102,7 +102,7 @@ module OllamaChat::InputContent
|
|
|
102
102
|
file filename.to_path
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
|
-
end.
|
|
105
|
+
end.send("to_#{format.downcase}")
|
|
106
106
|
else
|
|
107
107
|
if context_filename = choose_filename('.contexts/*.rb')
|
|
108
108
|
ContextSpook.generate_context(context_filename, verbose: true, format:).
|