ollama_chat 0.0.105 → 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 +44 -0
- data/lib/ollama_chat/chat.rb +2 -1
- data/lib/ollama_chat/commands.rb +18 -12
- data/lib/ollama_chat/database/models/prompt.rb +1 -1
- data/lib/ollama_chat/input_content.rb +1 -1
- data/lib/ollama_chat/model_handling.rb +33 -5
- data/lib/ollama_chat/prompt_management.rb +84 -38
- data/lib/ollama_chat/rag_handling.rb +6 -5
- data/lib/ollama_chat/version.rb +1 -1
- data/ollama_chat.gemspec +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 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,49 @@
|
|
|
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
|
+
|
|
3
47
|
## 2026-08-04 v0.0.105
|
|
4
48
|
|
|
5
49
|
### New Features
|
data/lib/ollama_chat/chat.rb
CHANGED
|
@@ -535,7 +535,8 @@ class OllamaChat::Chat
|
|
|
535
535
|
store_messages_in_session
|
|
536
536
|
rescue Ollama::Errors::BadRequestError
|
|
537
537
|
if (think? || tools_support.on?) && !retried
|
|
538
|
-
|
|
538
|
+
msg = "Error in think mode/with tool support, switch both off and retry."
|
|
539
|
+
log(:warn, msg, warn: true)
|
|
539
540
|
sleep 1
|
|
540
541
|
think_mode.selected = 'disabled'
|
|
541
542
|
tools_support.set false
|
data/lib/ollama_chat/commands.rb
CHANGED
|
@@ -139,13 +139,14 @@ module OllamaChat::Commands
|
|
|
139
139
|
|
|
140
140
|
command(
|
|
141
141
|
name: :model,
|
|
142
|
-
regexp: %r(^/model(?:\s+(change|options(?: copy)?|options from session|options to session))?((?:\s+(?:-m))*)$),
|
|
143
|
-
complete: [ 'model', %w[ change options options\ copy 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
148
|
- options copy: Copy profile from another model
|
|
149
|
+
- options delete: Delete a saved profile
|
|
149
150
|
- options from session: Save live → Saved
|
|
150
151
|
- options to session: Apply Saved → Live
|
|
151
152
|
-m interactively choose a model
|
|
@@ -170,6 +171,8 @@ module OllamaChat::Commands
|
|
|
170
171
|
edit_model_options(model, profile:)
|
|
171
172
|
when 'options copy'
|
|
172
173
|
copy_model_options_profile(model)
|
|
174
|
+
when 'options delete'
|
|
175
|
+
delete_model_options_profile(model)
|
|
173
176
|
when 'options from session'
|
|
174
177
|
profile = choose_profile_for_model(model) || 'default'
|
|
175
178
|
copy_model_options_from_session(model, profile:)
|
|
@@ -460,14 +463,14 @@ module OllamaChat::Commands
|
|
|
460
463
|
|
|
461
464
|
command(
|
|
462
465
|
name: :prompt,
|
|
463
|
-
regexp: %r(^/prompt(?:\s+(edit|info|add|delete|list|duplicate|import|export|reset|-e))?(\s+(?:-[ef]|-c\s+(?:\w+|\?)))?(?:\s+([^-].*))?$),
|
|
464
|
-
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 ] ],
|
|
465
468
|
optional: true,
|
|
466
469
|
options: '[-c CONTEXT|-e|-f]',
|
|
467
470
|
help: <<~EOT,
|
|
468
471
|
📝 Manage prompt templates:
|
|
469
472
|
Subcommands: edit, info, add, delete, list,
|
|
470
|
-
duplicate, import, export, reset.
|
|
473
|
+
duplicate, import, export, reset, rename.
|
|
471
474
|
Options: -c [context]
|
|
472
475
|
(? for interactive in /prompt),
|
|
473
476
|
-e (edit next)
|
|
@@ -499,6 +502,8 @@ module OllamaChat::Commands
|
|
|
499
502
|
list_prompts(context:)
|
|
500
503
|
when 'duplicate'
|
|
501
504
|
duplicate_prompt(context:)
|
|
505
|
+
when 'rename'
|
|
506
|
+
rename_prompt(context:)
|
|
502
507
|
when 'import'
|
|
503
508
|
import_prompt(filename, context:)
|
|
504
509
|
when 'export'
|
|
@@ -565,12 +570,13 @@ module OllamaChat::Commands
|
|
|
565
570
|
|
|
566
571
|
command(
|
|
567
572
|
name: :conversation,
|
|
568
|
-
regexp: %r(^/conversation\s+(clean|save|load)(\s+-c)?(?:\s+([^-]
|
|
573
|
+
regexp: %r(^/conversation\s+(clean|save|load)(\s+-c)?(?:\s+([^-].*\.jsonl?))?$),
|
|
569
574
|
complete: [ 'conversation', %w[ save load clean ] ],
|
|
570
|
-
options: '[-c]',
|
|
575
|
+
options: '[-c] [FILENAME]',
|
|
571
576
|
help: <<~EOT
|
|
572
577
|
💾 Save/Load conversation state
|
|
573
578
|
(-c to clean before saving)
|
|
579
|
+
FILENAME ends with .json or .jsonl
|
|
574
580
|
Or clean inplace (removes tool content, images, and thinking)
|
|
575
581
|
EOT
|
|
576
582
|
) do |subcommand,opts,path|
|
|
@@ -826,7 +832,7 @@ module OllamaChat::Commands
|
|
|
826
832
|
if opts[?p]
|
|
827
833
|
words = opts.fetch(?w, 100)
|
|
828
834
|
all = opts.fetch(?a, false)
|
|
829
|
-
|
|
835
|
+
patterns = extract_patterns(arg)
|
|
830
836
|
next provide_file_set_content(patterns, all:, skip_blank: true) { summarize(_1, words:) } || :next
|
|
831
837
|
elsif arg
|
|
832
838
|
words = opts.fetch(?w, 100)
|
|
@@ -840,7 +846,7 @@ module OllamaChat::Commands
|
|
|
840
846
|
opts = go_command('pa', opts)
|
|
841
847
|
if opts[?p]
|
|
842
848
|
all = opts.fetch(?a, false)
|
|
843
|
-
patterns = arg
|
|
849
|
+
patterns = extract_patterns(arg).full? || [ '**/*' ]
|
|
844
850
|
next context_spook(patterns, all:) || :next
|
|
845
851
|
elsif arg
|
|
846
852
|
next context_spook(Array(arg.to_s), all: true) || :next
|
|
@@ -862,7 +868,7 @@ module OllamaChat::Commands
|
|
|
862
868
|
tags = opts[?t].full?(:split, ?,)
|
|
863
869
|
if opts[?p]
|
|
864
870
|
all = opts.fetch(?a, false)
|
|
865
|
-
|
|
871
|
+
patterns = extract_patterns(arg)
|
|
866
872
|
next provide_file_set_content(patterns, all:, skip_blank: true) { embed(_1, tags:) } || :next
|
|
867
873
|
elsif arg
|
|
868
874
|
next embed(arg, tags:) || :next
|
|
@@ -875,7 +881,7 @@ module OllamaChat::Commands
|
|
|
875
881
|
opts = go_command('pae', opts)
|
|
876
882
|
if opts[?p]
|
|
877
883
|
all = opts.fetch(?a, false)
|
|
878
|
-
|
|
884
|
+
patterns = extract_patterns(arg)
|
|
879
885
|
read = -> pathname {
|
|
880
886
|
STDOUT.puts "Reading #{pathname.to_s.inspect}."
|
|
881
887
|
pathname.read
|
|
@@ -895,7 +901,7 @@ module OllamaChat::Commands
|
|
|
895
901
|
opts = go_command('pae', opts)
|
|
896
902
|
if opts[?p]
|
|
897
903
|
all = opts.fetch(?a, false)
|
|
898
|
-
|
|
904
|
+
patterns = extract_patterns(arg)
|
|
899
905
|
next provide_file_set_content(patterns, all:, skip_blank: true) { import(_1) } || :next
|
|
900
906
|
elsif arg
|
|
901
907
|
source = arg
|
|
@@ -52,7 +52,7 @@ class OllamaChat::Database::Models::Prompt < Sequel::Model(OllamaChat::DB)
|
|
|
52
52
|
# database when the underlying prompt is removed.
|
|
53
53
|
def after_destroy
|
|
54
54
|
super
|
|
55
|
-
|
|
55
|
+
OllamaChat::Database::Models::Favourite.where(context:, name:).destroy
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Seeds the prompt table from the provided chat configuration.
|
|
@@ -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:).
|
|
@@ -156,7 +156,8 @@ module OllamaChat::ModelHandling
|
|
|
156
156
|
model_name ||= @model
|
|
157
157
|
model_options = get_session_model_options
|
|
158
158
|
store_model_options(model_name, model_options, profile:)
|
|
159
|
-
STDOUT.puts "Model options #{italic{profile}} for #{bold{model_name}}
|
|
159
|
+
STDOUT.puts "Model options #{italic{profile}} for #{bold{model_name}} "\
|
|
160
|
+
"were copied from session model options."
|
|
160
161
|
end
|
|
161
162
|
|
|
162
163
|
# Resets the session's model options to match the stored defaults for the
|
|
@@ -169,7 +170,8 @@ module OllamaChat::ModelHandling
|
|
|
169
170
|
model_name ||= @model
|
|
170
171
|
stored_model_options = get_stored_model_options(model_name, profile:)
|
|
171
172
|
session.update(model_options: stored_model_options)
|
|
172
|
-
STDOUT.puts "Model options #{italic{profile}} of #{bold{model_name}}
|
|
173
|
+
STDOUT.puts "Model options #{italic{profile}} of #{bold{model_name}} "\
|
|
174
|
+
"were copied to session model options."
|
|
173
175
|
end
|
|
174
176
|
|
|
175
177
|
# Interactively copies model options from a source model/profile to the
|
|
@@ -181,7 +183,7 @@ module OllamaChat::ModelHandling
|
|
|
181
183
|
src_model = choose_model('', model)
|
|
182
184
|
src_profile = choose_profile_for_model(src_model) || 'default'
|
|
183
185
|
dst_model = model
|
|
184
|
-
dst_profile = choose_profile_for_model(dst_model, allow_new: true
|
|
186
|
+
dst_profile = choose_profile_for_model(dst_model, allow_new: true, suggest: src_profile)
|
|
185
187
|
|
|
186
188
|
src_opts = get_stored_model_options(src_model, profile: src_profile).full? or return
|
|
187
189
|
|
|
@@ -200,7 +202,31 @@ module OllamaChat::ModelHandling
|
|
|
200
202
|
end
|
|
201
203
|
|
|
202
204
|
store_model_options(dst_model, src_opts, profile: dst_profile)
|
|
203
|
-
STDOUT.puts "✅ Copied options from #{italic{src_model}}/#{italic{src_profile}}
|
|
205
|
+
STDOUT.puts "✅ Copied options from #{italic{src_model}}/#{italic{src_profile}} "\
|
|
206
|
+
"to #{bold{dst_model}}/#{italic{dst_profile}}."
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Interactively deletes a stored model options profile.
|
|
210
|
+
#
|
|
211
|
+
# If the deleted profile is the default one, it is replaced with an empty
|
|
212
|
+
# options hash `{}` to ensure the model always has a valid default profile.
|
|
213
|
+
#
|
|
214
|
+
# @param model [String] the model whose profile should be deleted
|
|
215
|
+
def delete_model_options_profile(model)
|
|
216
|
+
profile = choose_profile_for_model(model) or return
|
|
217
|
+
|
|
218
|
+
if confirm?(prompt: "🔔 Really delete profile #{bold{profile}} for #{bold{model}}? (y/n) ", yes: /\Ay/i)
|
|
219
|
+
if profile == 'default'
|
|
220
|
+
store_model_options(model, {}, profile:)
|
|
221
|
+
STDOUT.puts "Default profile #{italic{profile}} for #{bold{model}} has been reset to empty options."
|
|
222
|
+
else
|
|
223
|
+
models::ModelOptions.where(model_name: model, profile:).destroy
|
|
224
|
+
STDOUT.puts "Profile #{italic{profile}} for #{bold{model}} deleted."
|
|
225
|
+
end
|
|
226
|
+
log(:info, "Model options profile deleted", data: { model:, profile: })
|
|
227
|
+
else
|
|
228
|
+
STDOUT.puts "Cancelled."
|
|
229
|
+
end
|
|
204
230
|
end
|
|
205
231
|
|
|
206
232
|
# Presents an interactive list of stored configuration profiles for the
|
|
@@ -212,12 +238,14 @@ module OllamaChat::ModelHandling
|
|
|
212
238
|
#
|
|
213
239
|
# @param model_name [String] the name of the model whose profiles are to be listed
|
|
214
240
|
# @return [String, nil] the selected profile name, or `nil` if none was chosen
|
|
215
|
-
def choose_profile_for_model(model_name, allow_new: false)
|
|
241
|
+
def choose_profile_for_model(model_name, allow_new: false, suggest: nil)
|
|
216
242
|
profiles = models::ModelOptions.where(model_name:).order(:profile).map(&:profile)
|
|
217
243
|
|
|
218
244
|
if allow_new
|
|
245
|
+
profiles.unshift(suggest) if suggest && !profiles.member?(suggest)
|
|
219
246
|
profiles = [ '[EXIT]', '[NEW]' ] + profiles
|
|
220
247
|
else
|
|
248
|
+
profiles.unshift(suggest) if suggest && !profiles.member?(suggest)
|
|
221
249
|
profiles.size < 2 and return profiles.first
|
|
222
250
|
profiles = [ '[EXIT]' ] + profiles
|
|
223
251
|
end
|
|
@@ -88,11 +88,11 @@ module OllamaChat::PromptManagement
|
|
|
88
88
|
# Interactively prompts the user for a name and content (optionally loading
|
|
89
89
|
# from a file) to create a new prompt template.
|
|
90
90
|
#
|
|
91
|
-
# @return [
|
|
91
|
+
# @return [self, nil] self if the prompt was added, nil if the process was
|
|
92
92
|
# cancelled
|
|
93
93
|
def add_new_prompt(context: nil)
|
|
94
94
|
context ||= 'prompt'
|
|
95
|
-
switch_history(:
|
|
95
|
+
switch_history(:prompt) do
|
|
96
96
|
name = determine_valid_new_name_for_prompt('to add', context:) or return
|
|
97
97
|
|
|
98
98
|
sources = %w[ [CLIPBOARD] [FILES] [EMPTY/MANUAL] ]
|
|
@@ -115,7 +115,7 @@ module OllamaChat::PromptManagement
|
|
|
115
115
|
prompt_content = edit_text(content)
|
|
116
116
|
store_prompt(name, prompt_content, context:)
|
|
117
117
|
log(:info, "Prompt added", data: { name:, context: })
|
|
118
|
-
|
|
118
|
+
self
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
@@ -165,31 +165,75 @@ module OllamaChat::PromptManagement
|
|
|
165
165
|
# cancelled the operation or no prompt was selected.
|
|
166
166
|
def duplicate_prompt(context: nil)
|
|
167
167
|
context ||= 'prompt'
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
name = nil
|
|
173
|
-
loop do
|
|
174
|
-
name = ask?(
|
|
175
|
-
prompt: "❓ Enter new prompt name to duplicate as, C-c ⇒ cancel: "
|
|
168
|
+
switch_history(:prompt) do
|
|
169
|
+
selected_prompt = choose_prompt(context:, prompt: 'Which prompt shall be the basis for a new one? %s') or return
|
|
170
|
+
STDOUT.puts kramdown_ansi_parse(
|
|
171
|
+
selected_prompt.to_s + "\n---"
|
|
176
172
|
)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
name = nil
|
|
174
|
+
loop do
|
|
175
|
+
name = ask?(
|
|
176
|
+
prompt: "❓ Enter new prompt name to duplicate as, C-c ⇒ cancel: "
|
|
177
|
+
)
|
|
178
|
+
if name.nil?
|
|
179
|
+
STDOUT.puts "Cancelled."
|
|
180
|
+
return nil
|
|
181
|
+
end
|
|
182
|
+
if prompt(name, context:)
|
|
183
|
+
STDOUT.puts "Prompt named #{bold{name}} already exists."
|
|
184
|
+
else
|
|
185
|
+
break
|
|
186
|
+
end
|
|
180
187
|
end
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
188
|
+
duplicated_prompt = selected_prompt.duplicate
|
|
189
|
+
duplicated_prompt.name = name
|
|
190
|
+
duplicated_prompt.metadata['default'] = false
|
|
191
|
+
duplicated_prompt.save
|
|
192
|
+
log(:info, "Prompt duplicated", data: { name:, old_name: selected_prompt.name, context: })
|
|
193
|
+
self
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Interactively selects an existing prompt and renames it.
|
|
198
|
+
#
|
|
199
|
+
# @return [self, nil] the current context on success, or nil if the user
|
|
200
|
+
# cancelled the operation or no prompt was selected.
|
|
201
|
+
def rename_prompt(context: nil)
|
|
202
|
+
context ||= 'prompt'
|
|
203
|
+
switch_history(:prompt) do
|
|
204
|
+
selected_prompt = choose_prompt(
|
|
205
|
+
prompt: 'Which prompt would you like to rename? %s',
|
|
206
|
+
context:
|
|
207
|
+
) or return
|
|
208
|
+
|
|
209
|
+
STDOUT.puts kramdown_ansi_parse(
|
|
210
|
+
selected_prompt.to_s + "\n---"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
name = nil
|
|
214
|
+
loop do
|
|
215
|
+
name = ask?(
|
|
216
|
+
prompt: "❓ Enter new prompt name, C-c ⇒ cancel: "
|
|
217
|
+
)
|
|
218
|
+
if name.nil?
|
|
219
|
+
STDOUT.puts "Cancelled."
|
|
220
|
+
return nil
|
|
221
|
+
end
|
|
222
|
+
if name == selected_prompt.name
|
|
223
|
+
STDOUT.puts "That is the current name."
|
|
224
|
+
elsif prompt(name, context:)
|
|
225
|
+
STDOUT.puts "Prompt named #{bold{name}} already exists."
|
|
226
|
+
else
|
|
227
|
+
break
|
|
228
|
+
end
|
|
185
229
|
end
|
|
230
|
+
|
|
231
|
+
old_name = selected_prompt.name
|
|
232
|
+
selected_prompt.name = name
|
|
233
|
+
selected_prompt.save
|
|
234
|
+
log(:info, "Prompt renamed", data: { old_name:, new_name: name, context: })
|
|
235
|
+
self
|
|
186
236
|
end
|
|
187
|
-
duplicated_prompt = selected_prompt.duplicate
|
|
188
|
-
duplicated_prompt.name = name
|
|
189
|
-
duplicated_prompt.metadata['default'] = false
|
|
190
|
-
duplicated_prompt.save
|
|
191
|
-
log(:info, "Prompt duplicated", data: { name:, old_name: selected_prompt.name, context: })
|
|
192
|
-
self
|
|
193
237
|
end
|
|
194
238
|
|
|
195
239
|
# Interactively imports a prompt from a file.
|
|
@@ -366,21 +410,23 @@ module OllamaChat::PromptManagement
|
|
|
366
410
|
# the operation was cancelled.
|
|
367
411
|
def determine_valid_new_name_for_prompt(action, context: nil)
|
|
368
412
|
context ||= 'prompt'
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
413
|
+
switch_history(:prompt) do
|
|
414
|
+
prompt_name = nil
|
|
415
|
+
loop do
|
|
416
|
+
prompt_name = ask?(
|
|
417
|
+
prompt: "❓ Enter new prompt name #{action}, C-c ⇒ cancel: "
|
|
418
|
+
)
|
|
419
|
+
if prompt_name.nil?
|
|
420
|
+
STDOUT.puts "Cancelled."
|
|
421
|
+
return nil
|
|
422
|
+
end
|
|
423
|
+
if prompt(prompt_name, context:)
|
|
424
|
+
STDOUT.puts "Prompt named #{bold{prompt_name}} already exists."
|
|
425
|
+
else
|
|
426
|
+
break
|
|
427
|
+
end
|
|
382
428
|
end
|
|
429
|
+
prompt_name
|
|
383
430
|
end
|
|
384
|
-
prompt_name
|
|
385
431
|
end
|
|
386
432
|
end
|
|
@@ -219,15 +219,16 @@ module OllamaChat::RAGHandling
|
|
|
219
219
|
end
|
|
220
220
|
end
|
|
221
221
|
|
|
222
|
-
# Extracts and normalizes file patterns from a
|
|
222
|
+
# Extracts and normalizes file patterns from a shell-style string.
|
|
223
223
|
#
|
|
224
|
-
# Splits the input string
|
|
225
|
-
#
|
|
224
|
+
# Splits the input string using shell semantics, correctly handling
|
|
225
|
+
# spaces enclosed in single/double quotes or escaped with backslashes.
|
|
226
|
+
# Each resulting pattern is expanded to an absolute path.
|
|
226
227
|
#
|
|
227
|
-
# @param patterns_str [String, nil] the
|
|
228
|
+
# @param patterns_str [String, nil] the shell-style glob patterns
|
|
228
229
|
# @return [Array<String>] an array of expanded absolute path patterns
|
|
229
230
|
def extract_patterns(patterns_str)
|
|
230
|
-
patterns =
|
|
231
|
+
patterns = Shellwords.split(patterns_str.to_s)
|
|
231
232
|
patterns.map { File.expand_path(_1) }
|
|
232
233
|
end
|
|
233
234
|
|
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.106 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.106".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]
|