Class: OllamaChat::MessageList
- Inherits:
-
Object
- Object
- OllamaChat::MessageList
- Includes:
- MessageFormat, Pager, Utils::ValueFormatter, Term::ANSIColor
- Defined in:
- lib/ollama_chat/message_list.rb
Overview
A collection class for managing chat messages with support for system prompts, paged output, and conversation history.
This class provides functionality for storing, retrieving, and displaying chat messages in a structured manner. It handles system prompts separately from regular user and assistant messages, supports pagination for displaying conversations, and offers methods for manipulating message history including clearing, loading, saving, and dropping exchanges. The class integrates with Kramdown::ANSI for formatted output.
Instance Attribute Summary collapse
-
#messages ⇒ Object
readonly
The messages attribute reader returns the messages set for this object, initializing it lazily if needed.
-
#system ⇒ Object
readonly
The system attribute reader returns the system prompt for the chat session.
-
#system_name ⇒ Object
readonly
The system_name attribute reader returns the name of the current system prompt.
Instance Method Summary collapse
-
#<<(message) ⇒ OllamaChat::MessageList
The << operator appends a message to the list of messages and returns self.
-
#clean_messages(messages: @messages) ⇒ Array<OllamaChat::Message>
Returns a new list of messages with the content replaced by their stripped versions.
-
#clear(all: false) ⇒ OllamaChat::MessageList
The clear method removes all non-system messages from the message list.
-
#clear_images ⇒ OllamaChat::MessageList
Removes all images from all messages in the current list.
-
#drop(n) ⇒ Integer
Removes the last ‘n` conversation exchanges from the message list.
-
#each_message(role: %w[ user assistant ],, tool: false) {|message| ... } ⇒ Enumerator?
Iterates over messages in the conversation, yielding those matching the specified roles.
-
#find_last(content: false) {|Message| ... } ⇒ OllamaChat::Message?
Find the last message that satisfies the supplied block.
-
#initialize(chat) ⇒ MessageList
constructor
The initialize method sets up the message list for an OllamaChat session.
-
#last ⇒ OllamaChat::Message
Returns the last message from the conversation.
-
#list_conversation(last = nil) ⇒ OllamaChat::MessageList
Displays the most recent messages from the conversation history.
-
#load_conversation(filename) ⇒ OllamaChat::MessageList
The load_conversation method loads a conversation from a file and populates the message list.
-
#read_conversation_jsonl(input) ⇒ OllamaChat::MessageList
Loads conversation messages from a JSONL (JSON Lines) input stream.
-
#save_conversation(filename, messages: @messages) ⇒ OllamaChat::MessageList
The save_conversation method saves the current conversation to a file.
-
#set_system_prompt(system_name) ⇒ OllamaChat::MessageList
Sets the system prompt for the chat session.
-
#show_last(n = nil, pager: true) ⇒ OllamaChat::MessageList?
Displays the most recent messages that were not authored by the user.
-
#show_system_prompt ⇒ self, NilClass
The show_system_prompt method displays the system prompt configured for the chat session.
-
#size ⇒ Integer
Returns the number of messages stored in the message list.
-
#to_ary ⇒ Array
The to_ary method converts the message list into an array of OllamaChat::Message objects.
-
#write_conversation_jsonl(output, messages: @messages) ⇒ OllamaChat::MessageList
Writes each message in the conversation to the output as a JSON line.
Methods included from Utils::ValueFormatter
Methods included from Pager
Methods included from MessageFormat
#chat, #display_sender, #message_type, #role_color, #role_template, #sender_name_displayed, #talk_annotate, #think_annotate
Constructor Details
#initialize(chat) ⇒ MessageList
The initialize method sets up the message list for an OllamaChat session.
40 41 42 43 |
# File 'lib/ollama_chat/message_list.rb', line 40 def initialize(chat) @chat = chat @messages = [] end |
Instance Attribute Details
#messages ⇒ Object (readonly)
The messages attribute reader returns the messages set for this object, initializing it lazily if needed.
The messages set is memoized, meaning it will only be created once per object instance and subsequent calls will return the same OllamaChat::MessageList instance.
64 65 66 |
# File 'lib/ollama_chat/message_list.rb', line 64 def @messages end |
#system ⇒ Object (readonly)
The system attribute reader returns the system prompt for the chat session.
48 49 50 |
# File 'lib/ollama_chat/message_list.rb', line 48 def system @system end |
#system_name ⇒ Object (readonly)
The system_name attribute reader returns the name of the current system prompt.
53 54 55 |
# File 'lib/ollama_chat/message_list.rb', line 53 def system_name @system_name end |
Instance Method Details
#<<(message) ⇒ OllamaChat::MessageList
The << operator appends a message to the list of messages and returns self.
90 91 92 93 |
# File 'lib/ollama_chat/message_list.rb', line 90 def <<() @messages << sync end |
#clean_messages(messages: @messages) ⇒ Array<OllamaChat::Message>
Returns a new list of messages with the content replaced by their stripped versions. This is used to create a “clean” version of the conversation for saving or displaying without mutating the original message objects.
198 199 200 201 202 203 204 205 |
# File 'lib/ollama_chat/message_list.rb', line 198 def (messages: @messages) .map do || = .dup .content = '' if .tool? .images = nil end end |
#clear(all: false) ⇒ OllamaChat::MessageList
The clear method removes all non-system messages from the message list.
76 77 78 79 80 81 82 83 |
# File 'lib/ollama_chat/message_list.rb', line 76 def clear(all: false) if all @messages.clear else @messages.delete_if { _1.role != 'system' } end sync end |
#clear_images ⇒ OllamaChat::MessageList
Removes all images from all messages in the current list.
440 441 442 443 444 445 |
# File 'lib/ollama_chat/message_list.rb', line 440 def clear_images @messages.each do || .images = nil end sync end |
#drop(n) ⇒ Integer
This method automatically synchronizes the message list with the session store.
Removes the last ‘n` conversation exchanges from the message list.
An exchange is typically defined as a pair of user and assistant messages. This method iterates backwards through the history and removes messages until the requested number of exchanges have been dropped. It will stop if it encounters a system message.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/ollama_chat/message_list.rb', line 305 def drop(n) n = n.to_i.clamp(1, Float::INFINITY) i = 0 m = 0 @messages.reverse_each.each_cons(2) do |, before| .role == 'system' and break if .role == 'assistant' i += 1 elsif .role == 'user' i += 1 next if before.role == 'user' m += 1 end m >= n and break end i.times { @messages.pop } STDOUT.puts "Dropped the last #{m} exchanges." m ensure sync end |
#each_message(role: %w[ user assistant ],, tool: false) {|message| ... } ⇒ Enumerator?
Iterates over messages in the conversation, yielding those matching the specified roles.
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/ollama_chat/message_list.rb', line 148 def (role: %w[ user assistant ], tool: false, &block) block or return enum_for(__method__, role:, tool:) @messages.each do || role.include?(.role) or next !tool && .tool? and next yield end nil end |
#find_last(content: false) {|Message| ... } ⇒ OllamaChat::Message?
The method iterates in reverse order (‘reverse_each`) so that the *most recent* matching message is returned. It also respects the `content` flag to skip empty messages, which is handy when the chat history contains empty messages e. g. when tool calling.
Find the last message that satisfies the supplied block.
129 130 131 132 133 134 |
# File 'lib/ollama_chat/message_list.rb', line 129 def find_last(content: false, &block) @messages.reverse_each.find { |m| content and !m.content.present? and next block.(m) } end |
#last ⇒ OllamaChat::Message
Returns the last message from the conversation.
99 100 101 |
# File 'lib/ollama_chat/message_list.rb', line 99 def last @messages.last end |
#list_conversation(last = nil) ⇒ OllamaChat::MessageList
Displays the most recent messages from the conversation history.
This method prints a specified number of trailing messages to the console using the pager for better readability. Tool messages are automatically excluded from the output. If no count is provided, the entire conversation is displayed.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/ollama_chat/message_list.rb', line 218 def list_conversation(last = nil) = @messages.reject(&:tool?) last = (last || .size).clamp(0, .size) = [-last..-1].to_ary use_pager do |output| = (messages:) = .( output: STDERR, label: 'Message', total: .size, message: @chat., ) .each do || output.puts () + end end self end |
#load_conversation(filename) ⇒ OllamaChat::MessageList
The load_conversation method loads a conversation from a file and populates the message list.
165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/ollama_chat/message_list.rb', line 165 def load_conversation(filename) filename = Pathname.new(filename). unless filename.exist? STDERR.puts "File #{filename.to_s.inspect} doesn't exist. Choose another filename." return end @messages = OllamaChat::Utils::JSONJSONLIO.new(filename).read( jsonl_transform: method(:parse_message_from_json), json_transform: method(:construct_message_from_hash) ).to_a sync end |
#read_conversation_jsonl(input) ⇒ OllamaChat::MessageList
Loads conversation messages from a JSONL (JSON Lines) input stream. Each line in the input is expected to be a valid JSON representation of a message. The method parses each line and adds the resulting message to the current conversation.
429 430 431 432 433 434 435 |
# File 'lib/ollama_chat/message_list.rb', line 429 def read_conversation_jsonl(input) @messages = OllamaChat::Utils::JSONJSONLIO.new('as.jsonl').read_io( input:, jsonl_transform: method(:parse_message_from_json) ).to_a self end |
#save_conversation(filename, messages: @messages) ⇒ OllamaChat::MessageList
The save_conversation method saves the current conversation to a file.
185 186 187 188 |
# File 'lib/ollama_chat/message_list.rb', line 185 def save_conversation(filename, messages: @messages) OllamaChat::Utils::JSONJSONLIO.new(filename).write(collection: ) self end |
#set_system_prompt(system_name) ⇒ OllamaChat::MessageList
This method:
-
Removes all existing system prompts from the message list
-
Adds the new system prompt to the beginning of the message list if provided
-
Handles edge cases such as clearing prompts when ‘system` is `nil` or `false`
Sets the system prompt for the chat session.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/ollama_chat/message_list.rb', line 341 def set_system_prompt(system_name) @system_name = system_name if system_name == 'model_default' system = @chat.model_default_system_prompt.to_s else system = @chat.system_prompt(system_name).to_s end @messages.reject! { |msg| msg.role == 'system' } templates_values = { persona: @chat.default_persona_profile, runtime_info: @chat.static_runtime_information, } if new_system_prompt = system.full? { _1.to_s % templates_values } @system = new_system_prompt @messages.unshift( OllamaChat::Message.new(role: 'system', content: self.system) ) else @system = nil end sync end |
#show_last(n = nil, pager: true) ⇒ OllamaChat::MessageList?
Displays the most recent messages that were not authored by the user.
This is particularly useful for quickly reviewing the assistant’s last responses without having to scroll through the user’s own input. Output is routed through the pager.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/ollama_chat/message_list.rb', line 249 def show_last(n = nil, pager: true) n ||= 1 = @messages.reject { || .role == 'user' } n = n.clamp(0...size) n <= 0 and return = (last.content if last&.role == 'user') outputter = -> output do = [-n..-1].to_a = .( output: STDERR, label: 'Message', total: .size, message: @chat., ) .each do || output.puts () + end ensure if = Kramdown::ANSI::Width.truncate( .inspect, length: Tins::Terminal.columns * 0.9 ) msg = <<~EOT ⚠️ Last message is actually #{bold{'user message'}}, see: #{} You might want to drop it. EOT output.puts msg end end if pager use_pager(&outputter) else outputter.(STDOUT) end self end |
#show_system_prompt ⇒ self, NilClass
The show_system_prompt method displays the system prompt configured for the chat session.
It retrieves the system prompt from the @system instance variable, parses it using Kramdown::ANSI, and removes any trailing newlines. If the resulting string is empty, the method returns immediately.
Otherwise, it prints a formatted message to the console, including the configured system prompt and its length in characters.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/ollama_chat/message_list.rb', line 375 def show_system_prompt current_system = system.to_s size_bytes = current_system.size size = format_bytes(size_bytes) tokens = OllamaChat::Utils::TokenEstimator.estimate(size_bytes) tokens_size = format_tokens(tokens) system_prompt = @chat.kramdown_ansi_parse(current_system). gsub(/\n+\z/, '').full? if system_prompt.blank? if current_system.present? system_prompt = current_system else return end end use_pager do |output| output.puts <<~EOT Configured system prompt is: #{system_prompt} System prompt name: #{bold{system_name}} System prompt length: 👾#{size} 🧩#{tokens_size} EOT end self end |
#size ⇒ Integer
Returns the number of messages stored in the message list.
69 70 71 |
# File 'lib/ollama_chat/message_list.rb', line 69 def size @messages.size end |
#to_ary ⇒ Array
The to_ary method converts the message list into an array of OllamaChat::Message objects.
407 408 409 |
# File 'lib/ollama_chat/message_list.rb', line 407 def to_ary @messages.dup end |
#write_conversation_jsonl(output, messages: @messages) ⇒ OllamaChat::MessageList
Writes each message in the conversation to the output as a JSON line.
417 418 419 420 |
# File 'lib/ollama_chat/message_list.rb', line 417 def write_conversation_jsonl(output, messages: @messages) OllamaChat::Utils::JSONJSONLIO.new('as.jsonl').write_io(output:, collection: ) self end |