Module: OllamaChat::SystemPromptManagement

Included in:
Chat
Defined in:
lib/ollama_chat/system_prompt_management.rb

Overview

Provides advanced system prompt management capabilities for the OllamaChat session.

This module encapsulates the logic for initializing, changing, and loading system prompts, allowing for dynamic and interactive configuration within the chat lifecycle.

Instance Method Summary collapse

Instance Method Details

#add_new_system_promptBoolean?

Interactively prompts the user for a name and content to create a new system prompt. Optionally sets the new prompt as the current one.

Returns:

  • (Boolean, nil)

    true if the prompt was added and set as current, false if added but not set, or nil if the process was cancelled



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/ollama_chat/system_prompt_management.rb', line 151

def add_new_system_prompt
  switch_history(:add_system_prompt) do
    system_prompt_name = determine_valid_new_name_for_system_prompt('to add') or return
    patterns = ask?(
      prompt: "❓ Enter file patterns to load file, C-u ⇒ new, C-c ⇒ cancel: ",
      prefill: '**/*.{txt,md}'
    )
    patterns.nil? and return
    content = nil
    patterns.present? and content = load_prompt_from_file(patterns)
    system_prompt = edit_text(content)
    store_system_prompt(system_prompt_name, system_prompt).to_s
    ask_to_set_current_system_prompt(system_prompt_name)
  end
end

#all_system_promptsArray<SearchUI::Wrapper>

Retrieves all stored system prompts, decorated with a heart if they are marked as favourites.

Returns:

  • (Array<SearchUI::Wrapper>)

    the list of system prompts for display in a chooser



13
14
15
16
17
18
# File 'lib/ollama_chat/system_prompt_management.rb', line 13

def all_system_prompts
  favs = all_favourited('system_prompt')
  each_system_prompt.sort_by(&:name).map do |p|
    system_prompt_with_favourite(p.name, favs[p.name])
  end
end

#change_system_prompt(default) ⇒ Object?

The change_system_prompt method allows the user to select or enter a new system prompt for the chat session. It provides an interactive chooser when multiple prompts match the given selector, and sets the selected prompt as the current system prompt for the messages.

The user can choose from all stored system prompts, the model’s default, or exit the chooser. If the selection is cancelled or returns nil, the provided default is used.

Parameters:

  • default (String)

    the system prompt name to use as a fallback

Returns:

  • (Object, nil)

    the result of setting the current system prompt, or nil if the operation was explicitly exited.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ollama_chat/system_prompt_management.rb', line 85

def change_system_prompt(default)
  prompts = all_system_prompts
  prompts.unshift('[MODEL DEFAULT]').unshift('[EXIT]')
  chosen = choose_entry(
    prompts,
    prompt: 'Which governing law shall we enact?'
  )
  system_prompt_name =
    case chosen
    when '[EXIT]'
      STDOUT.puts "Exiting chooser."
      return
    when '[MODEL DEFAULT]'
      'model_default'
    when nil
      default
    when SearchUI::Wrapper
      chosen.value.to_s
    else
      default
    end
  set_current_system_prompt(system_prompt_name)
end

#choose_and_delete_system_promptself?

Interactively selects an existing system prompt and deletes it after confirmation.

Returns:

  • (self, nil)

    the current context on success, or nil if cancelled



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/ollama_chat/system_prompt_management.rb', line 185

def choose_and_delete_system_prompt
  system_prompt = choose_system_prompt(prompt: 'Which old rule is now obsolete? ') or return
  STDOUT.puts kramdown_ansi_parse(
    system_prompt.to_s + "\n---"
  )
  confirm?(
    prompt: "🔔 Really delete the system prompt #{bold{system_prompt.name}}? (y/n) ",
    yes: /\Ay/i
  ) or return
  system_prompt.destroy
  self
end

#choose_and_edit_system_promptself?

Interactively selects an existing system prompt and allows the user to edit its content.

Returns:

  • (self, nil)

    the current context on success, or nil if cancelled



171
172
173
174
175
176
177
178
179
# File 'lib/ollama_chat/system_prompt_management.rb', line 171

def choose_and_edit_system_prompt
  system_prompt = choose_system_prompt(
    prompt: 'Which system directive needs rewriting? '
  ) or return
  system_prompt.['content'] = edit_text(system_prompt.['content'].to_s)
  system_prompt.save
  ask_to_set_current_system_prompt(system_prompt.name)
  self
end

#choose_system_prompt(prompt: 'Select a system prompt: ') ⇒ Object?

Presents an interactive menu to select a stored system prompt.

Parameters:

  • prompt (String) (defaults to: 'Select a system prompt: ')

    the prompt message to display when asking for input (default: ‘Select a system prompt: ’)

Returns:

  • (Object, nil)

    the selected system prompt object, or nil if cancelled



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/ollama_chat/system_prompt_management.rb', line 115

def choose_system_prompt(prompt: 'Select a system prompt: ')
  prompts = all_system_prompts
  prompts.unshift('[EXIT]')
  case chosen = choose_entry(prompts, prompt:)
  when '[EXIT]', nil
    STDOUT.puts "Exiting chooser."
    return
  when SearchUI::Wrapper
    system_prompt(chosen.value)
  end
end

#current_system_promptString?

Retrieves the content of the system prompt currently active in the chat session.

Returns:

  • (String, nil)

    the content of the current system prompt, or nil if no system prompt is set.



49
50
51
# File 'lib/ollama_chat/system_prompt_management.rb', line 49

def current_system_prompt
  messages.system
end

#current_system_prompt_nameString?

Returns the name of the system prompt currently active in the chat session.

Returns:

  • (String, nil)

    the name of the current system prompt, or nil if no system prompt is set.



40
41
42
# File 'lib/ollama_chat/system_prompt_management.rb', line 40

def current_system_prompt_name
  messages.system_name
end

#duplicate_system_promptself?

Duplicates an existing system prompt.

This method initiates an interactive workflow:

  1. Prompts the user to select a system prompt to clone.

  2. Displays the content of the selected prompt for verification.

  3. Requests a new name for the duplicate, validating that it does not already exist in the database.

  4. Creates and saves the new prompt record using the Database::Duplicatable mixin.

Returns:

  • (self, nil)

    the current context on success, or nil if the user cancelled the operation or no system prompt was selected.



228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/ollama_chat/system_prompt_management.rb', line 228

def duplicate_system_prompt
  system_prompt = choose_system_prompt(prompt: 'Which core logic shall be cloned? ') or return
  STDOUT.puts kramdown_ansi_parse(
    system_prompt.to_s + "\n---"
  )
  system_prompt_name = determine_valid_new_name_for_system_prompt('to ducplicate as') or return
  duplicated_prompt = system_prompt.duplicate
  duplicated_prompt.name = system_prompt_name
  duplicated_prompt.['default'] = false
  duplicated_prompt.save
  self
end

#export_system_promptself?

Interactively exports a system prompt to a specified file.

The process follows these steps:

  1. Prompts the user to select a system prompt via ‘choose_system_prompt`.

  2. Displays the system prompt’s current content to the terminal.

  3. Prompts for a destination filename via

`determine_valid_output_filename`.
  1. Writes the system prompt content to the chosen file.

Returns:

  • (self, nil)

    returns self if the export was successful, or nil if the process was cancelled during system prompt selection or filename entry.



283
284
285
286
287
288
289
290
291
292
# File 'lib/ollama_chat/system_prompt_management.rb', line 283

def export_system_prompt
  prompt = choose_system_prompt(prompt: 'Which system prompt are you archiving to disk? ') or return
  STDOUT.puts kramdown_ansi_parse(
    prompt.to_s + "\n---"
  )
  filename = determine_valid_output_filename('to write to') or return
  filename.write(prompt.to_s)
  STDOUT.puts "Prompt #{prompt.name.inspect} was exported as #{filename.to_path.inspect}?"
  self
end

#import_system_prompt(filename) ⇒ self?

Imports a system prompt from a file.

This method prompts the user for a name for the imported prompt, reads the content from the specified file, stores it, and then asks whether to set it as the current system prompt.

Parameters:

  • filename (String, Pathname)

    the path to the file containing the system prompt

Returns:

  • (self, nil)

    self or nil if cancelled



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/ollama_chat/system_prompt_management.rb', line 250

def import_system_prompt(filename)
  if filename
    if File.exist?(filename)
      filename = Pathname.new(filename)
    else
      filename = choose_filename(filename)
    end
  else
    filename = choose_filename('**/*.md')
  end
  unless filename
    STDOUT.puts "Cancelled."
    return
  end
  system_prompt_name = determine_valid_new_name_for_system_prompt('to import') or return
  system_prompt = filename.read
  store_system_prompt(system_prompt_name, system_prompt)
  ask_to_set_current_system_prompt(system_prompt_name)
  STDOUT.puts "Imported system prompt as #{system_prompt_name.inspect}."
  self
end

#info_system_promptself?

Displays detailed information about a selected system prompt.

Returns:

  • (self, nil)

    the current context on success, or nil if cancelled



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/ollama_chat/system_prompt_management.rb', line 130

def info_system_prompt
  if system_prompt = choose_system_prompt(prompt: 'Which system law would you like to review? ')
    use_pager do |output|
      output.puts kramdown_ansi_parse(<<~EOT)
        # System Prompt #{system_prompt.name}
        ---

        #{system_prompt.to_s}

        ---
      EOT
    end
  end
  self
end

#list_system_promptsArray

Lists all stored system prompts in a formatted view, displaying their default status and a truncated preview of their content.

Returns:

  • (Array)

    an array of the results of the printing operations



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/ollama_chat/system_prompt_management.rb', line 202

def list_system_prompts
  favs = all_favourited('system_prompt')
  each_system_prompt.sort_by(&:name).map do |prompt|
    default = prompt.['default'] ? '' : ''
    start   = '%s %s' % [ default, bold { prompt.name } ]
    start   = prefix_favourite(start, favs[prompt.name])
    content = prompt.to_s.inspect[1..-2]
    content = Kramdown::ANSI::Width.truncate(
      content, length: 0.9 * (Tins::Terminal.columns - start.size)
    )
    STDOUT.print start
    STDOUT.puts ' %s' % italic { content }
  end
end

#model_default_system_promptString?

Retrieves the default system prompt associated with the current model.

Returns:

  • (String, nil)

    the default system prompt from the model metadata, or nil if the metadata is not available.



24
25
26
# File 'lib/ollama_chat/system_prompt_management.rb', line 24

def model_default_system_prompt
  @model_metadata&.system
end

#reset_system_prompt_to_default(name) ⇒ Boolean?

Resets a system prompt’s content to the default value defined in the configuration.

Parameters:

  • name (String, Symbol)

    the name of the system prompt to reset

Returns:

  • (Boolean, nil)

    true if the system prompt was reset, false if no default was found



299
300
301
302
303
304
# File 'lib/ollama_chat/system_prompt_management.rb', line 299

def reset_system_prompt_to_default(name)
  if content = config.system_prompts[name.to_s]
    store_system_prompt(name, content)
    true
  end
end

#set_current_system_prompt(system_prompt_name) ⇒ Object

Sets the current system prompt for the chat session.

Parameters:

  • system_prompt_name (String)

    the system prompt to set



31
32
33
34
# File 'lib/ollama_chat/system_prompt_management.rb', line 31

def set_current_system_prompt(system_prompt_name)
  messages.set_system_prompt(system_prompt_name)
  session.update(current_system_prompt: system_prompt_name)
end

#setup_system_promptObject

Sets up the system prompt for the chat session.

This method determines whether to use a default system prompt or a custom one specified via command-line options. If a custom system prompt is provided with a regexp selector (starting with ?), it invokes the change_system_prompt method to handle the selection. Otherwise, it retrieves the system prompt from a file or uses the default value, then sets it in the message history.



61
62
63
64
65
66
67
68
69
70
# File 'lib/ollama_chat/system_prompt_management.rb', line 61

def setup_system_prompt
  system_prompt_name = session.current_system_prompt.full? ||
    ('default' if system_prompt(:default)) ||
    'model_default'
  if system_prompt_name.full?
    set_current_system_prompt(system_prompt_name)
  else
    change_system_prompt(system_prompt_name)
  end
end