Class: OllamaChat::MessageList
- Inherits:
-
Object
- Object
- OllamaChat::MessageList
- Includes:
- MessageFormat, Pager, 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.
Instance Method Summary collapse
-
#<<(message) ⇒ OllamaChat::MessageList
The << operator appends a message to the list of messages and returns self.
-
#clear ⇒ OllamaChat::MessageList
The clear method removes all non-system messages from the message list.
-
#config ⇒ Object
private
The config method provides access to the chat configuration object.
-
#drop(n) ⇒ Integer
Removes the last
nexchanges from the message list. -
#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 ⇒ Ollama::Message
Returns the last message from the conversation.
-
#list_conversation(last = nil) ⇒ OllamaChat::MessageList
The list_conversation method displays the last n messages from the conversation.
-
#load_conversation(filename) ⇒ OllamaChat::MessageList
The load_conversation method loads a conversation from a file and populates the message list.
-
#message_text_for(message) ⇒ String
private
The message_text_for method generates formatted text representation of a message including its role, content, thinking annotations, and associated images.
-
#save_conversation(filename) ⇒ OllamaChat::MessageList
The save_conversation method saves the current conversation to a file.
-
#second_last ⇒ Ollama::Message
The second_last method returns the second-to-last message from the conversation if there are more than one non-system messages.
-
#set_system_prompt(system) ⇒ OllamaChat::MessageList
Sets the system prompt for the chat session.
-
#show_last(n = nil) ⇒ OllamaChat::MessageList
The show_last method displays the text of the last message if it is not from 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 Ollama::Message objects.
Methods included from Pager
#determine_pager_command, #use_pager
Methods included from MessageFormat
#message_type, #talk_annotate, #think_annotate
Constructor Details
#initialize(chat) ⇒ MessageList
The initialize method sets up the message list for an OllamaChat session.
39 40 41 42 |
# File 'lib/ollama_chat/message_list.rb', line 39 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.
58 59 60 |
# File 'lib/ollama_chat/message_list.rb', line 58 def @messages end |
#system ⇒ Object (readonly)
The system attribute reader returns the system prompt for the chat session.
47 48 49 |
# File 'lib/ollama_chat/message_list.rb', line 47 def system @system end |
Instance Method Details
#<<(message) ⇒ OllamaChat::MessageList
The << operator appends a message to the list of messages and returns self.
80 81 82 83 |
# File 'lib/ollama_chat/message_list.rb', line 80 def <<() @messages << self end |
#clear ⇒ OllamaChat::MessageList
The clear method removes all non-system messages from the message list.
70 71 72 73 |
# File 'lib/ollama_chat/message_list.rb', line 70 def clear @messages.delete_if { _1.role != 'system' } self end |
#config ⇒ Object (private)
The config method provides access to the chat configuration object.
300 301 302 |
# File 'lib/ollama_chat/message_list.rb', line 300 def config @chat.config end |
#drop(n) ⇒ Integer
-
System messages are preserved and not considered part of an exchange.
-
If only one incomplete exchange (a single user message) exists, it will be dropped first before removing complete exchanges.
Removes the last n exchanges from the message list. An exchange consists of a user and an assistant message. If only a single user message is present at the end, it will be removed first before proceeding with complete exchanges.
213 214 215 216 217 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 213 def drop(n) n = n.to_i.clamp(1, Float::INFINITY) = @messages.reject { _1.role == 'system' } if &.last&.role == 'user' @messages.pop n -= 1 end if n == 0 STDOUT.puts "Dropped the last exchange." return 1 end if .empty? STDOUT.puts "No more exchanges can be dropped." return 0 end m = 0 while @messages.size > 1 && n > 0 @messages.pop(2) m += 1 n -= 1 end STDOUT.puts "Dropped the last #{m} exchanges." m 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.
119 120 121 122 123 124 |
# File 'lib/ollama_chat/message_list.rb', line 119 def find_last(content: false, &block) @messages.reverse_each.find { |m| content and !m.content.present? and next block.(m) } end |
#last ⇒ Ollama::Message
Returns the last message from the conversation.
89 90 91 |
# File 'lib/ollama_chat/message_list.rb', line 89 def last @messages.last end |
#list_conversation(last = nil) ⇒ OllamaChat::MessageList
The list_conversation method displays the last n messages from the conversation.
173 174 175 176 177 178 179 180 181 |
# File 'lib/ollama_chat/message_list.rb', line 173 def list_conversation(last = nil) last = (last || @messages.size).clamp(0, @messages.size) use_pager do |output| @messages[-last..-1].to_a.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.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/ollama_chat/message_list.rb', line 142 def load_conversation(filename) unless File.exist?(filename) STDERR.puts "File #{filename.to_s.inspect} doesn't exist. Choose another filename." return end @messages = File.open(filename, 'r') do |output| JSON(output.read).map { Ollama::Message.from_hash(_1 | { 'content' => nil }) } end self end |
#message_text_for(message) ⇒ String (private)
The message_text_for method generates formatted text representation of a message including its role, content, thinking annotations, and associated images. It applies color coding to different message roles and uses markdown parsing when enabled. The method also handles special formatting for thinking annotations and image references within the message.
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/ollama_chat/message_list.rb', line 314 def () role_color = case .role when 'user' then 172 when 'assistant' then 111 when 'system' then 213 else 210 end thinking = if @chat.think_loud? think_annotate do .thinking.full? { @chat.markdown.on? ? @chat.kramdown_ansi_parse(_1) : _1 } end end content = .content.full? { @chat.markdown.on? ? @chat.kramdown_ansi_parse(_1) : _1 } = (.images) + " " += bold { color(role_color) { .role } } if thinking += [ ?:, thinking, talk_annotate { content } ].compact. map { _1.chomp } * ?\n else += ":\n#{content}" end .images.full? { |images| += "\nImages: " + italic { images.map(&:path) * ', ' } } end |
#save_conversation(filename) ⇒ OllamaChat::MessageList
The save_conversation method saves the current conversation to a file.
161 162 163 164 165 166 |
# File 'lib/ollama_chat/message_list.rb', line 161 def save_conversation(filename) File.open(filename, ?w) do |output| output.puts JSON(@messages) end self end |
#second_last ⇒ Ollama::Message
The second_last method returns the second-to-last message from the conversation if there are more than one non-system messages.
130 131 132 133 134 |
# File 'lib/ollama_chat/message_list.rb', line 130 def second_last if @messages.reject { _1.role == 'system' }.size > 1 @messages[-2] end end |
#set_system_prompt(system) ⇒ 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
systemisnilorfalse
Sets the system prompt for the chat session.
250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/ollama_chat/message_list.rb', line 250 def set_system_prompt(system) @messages.reject! { |msg| msg.role == 'system' } if new_system_prompt = system.full?(:to_s) @system = new_system_prompt @messages.unshift( Ollama::Message.new(role: 'system', content: self.system) ) else @system = nil end self end |
#show_last(n = nil) ⇒ OllamaChat::MessageList
The show_last method displays the text of the last message if it is not from the user. It uses a pager for output and returns the instance itself.
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/ollama_chat/message_list.rb', line 187 def show_last(n = nil) n ||= 1 = @messages.reject { || .role == 'user' } n = n.clamp(0...size) n <= 0 and return use_pager do |output| [-n..-1].to_a.each do || output.puts () end 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.
274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/ollama_chat/message_list.rb', line 274 def show_system_prompt system_prompt = @chat.kramdown_ansi_parse(system.to_s).gsub(/\n+\z/, '').full? system_prompt or return STDOUT.puts <<~EOT Configured system prompt is: #{system_prompt} System prompt length: #{bold{system_prompt.size}} characters. EOT self end |
#size ⇒ Integer
Returns the number of messages stored in the message list.
63 64 65 |
# File 'lib/ollama_chat/message_list.rb', line 63 def size @messages.size end |
#to_ary ⇒ Array
The to_ary method converts the message list into an array of Ollama::Message objects.
291 292 293 |
# File 'lib/ollama_chat/message_list.rb', line 291 def to_ary @messages.dup end |