class Conversation
Represents a conversation with the Ollama API, managing messages, tool calls, and summarization.
Nested
Definitions
def initialize(client, model: MODEL, messages: [], **options)
Initializes a new conversation.
Signature
-
parameter
client
Client
The Ollama client instance.
-
parameter
model
String
The model to use for the conversation.
-
parameter
messages
Array(Hash)
The initial messages for the conversation.
-
parameter
options
Hash
Additional options for the conversation.
Implementation
def initialize(client, model: MODEL, messages: [], **options)
@client = client
@model = model
@messages = messages
@options = options
@toolbox = Toolbox.new
@last_response = nil
end
attr :toolbox
Signature
-
attribute
Toolbox
The toolbox for this conversation.
attr :messages
Signature
-
attribute
Array(Hash)
The messages in the conversation.
def size
Signature
-
returns
Integer
The number of messages in the conversation.
Implementation
def size
@messages.size
end
def token_count
Signature
-
returns
Integer
The token count of the last response, or 0 if none.
Implementation
def token_count
@last_response&.token_count || 0
end
def call(prompt, &block)
Sends a prompt to the conversation and processes the response, including tool calls.
Signature
-
parameter
prompt
String | Hash
The prompt to send (as a string or message hash).
-
returns
Chat
The final chat response.
Implementation
def call(prompt, &block)
if prompt.is_a?(String)
@messages << {
role: "user",
content: prompt
}
else
@messages << prompt
end
while true
@last_response = @client.chat(@messages, model: @model, tools: @toolbox.explain, options: @options, &block)
if error = @last_response.error
raise ChatError, error
end
@messages << @last_response.message
tool_calls = @last_response.tool_calls
if tool_calls.nil? || tool_calls.empty?
return @last_response
end
tool_calls.each do |tool_call|
@messages << @toolbox.call(tool_call)
end
end
end
def summarize!(retain = -1, role: "user")
Summarizes the conversation and truncates messages to reduce context usage.
Signature
-
parameter
retain
Integer
The number of messages to retain after summarization.
-
parameter
role
String
The role to use for the summarization message.
-
returns
void
Implementation
def summarize!(retain = -1, role: "user")
current_size = @messages.size
# In principle, this could generate several messages:
message = {
role: role,
content: SUMMARIZE_MESSAGE,
}
self.call(message)
# The number of messages generated by the summarization:
delta = @messages.size - current_size
# After much experimentation, I found that leaving the SUMMARIZE_MESSAGE in the message stream caused extreme confusion, so we set retain to -1 to remove it by default.
retain += delta
if retain < @messages.size
truncated = @messages.size - retain
# We need to truncate the messages:
@messages = @messages.last(retain)
@messages.unshift({
role: "system",
content: "#{truncated} previous messages that have been removed and summarized to reduce context usage. Continue the conversation naturally as if the previous messages were still present.",
})
end
end