mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
Filter preserved user messages to be text only. (#5391)
This commit is contained in:
@@ -42,21 +42,55 @@ pub async fn compact_messages(
|
||||
|
||||
let messages = conversation.messages();
|
||||
|
||||
// Check if the most recent message is a user message
|
||||
let (messages_to_compact, preserved_user_message) = if let Some(last_message) = messages.last()
|
||||
{
|
||||
if matches!(last_message.role, rmcp::model::Role::User) {
|
||||
// Remove the last user message before compaction
|
||||
(&messages[..messages.len() - 1], Some(last_message.clone()))
|
||||
let has_text_only = |msg: &Message| {
|
||||
let has_text = msg
|
||||
.content
|
||||
.iter()
|
||||
.any(|c| matches!(c, MessageContent::Text(_)));
|
||||
let has_tool_content = msg.content.iter().any(|c| {
|
||||
matches!(
|
||||
c,
|
||||
MessageContent::ToolRequest(_) | MessageContent::ToolResponse(_)
|
||||
)
|
||||
});
|
||||
has_text && !has_tool_content
|
||||
};
|
||||
|
||||
// Helper function to extract text content from a message
|
||||
let extract_text = |msg: &Message| -> Option<String> {
|
||||
let text_parts: Vec<String> = msg
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| {
|
||||
if let MessageContent::Text(text) = c {
|
||||
Some(text.text.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if text_parts.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(text_parts.join("\n"))
|
||||
}
|
||||
};
|
||||
|
||||
// Check if the most recent message is a user message with text content only
|
||||
let (messages_to_compact, preserved_user_text) = if let Some(last_message) = messages.last() {
|
||||
if matches!(last_message.role, rmcp::model::Role::User) && has_text_only(last_message) {
|
||||
// Remove the last user message before compaction and preserve its text
|
||||
(&messages[..messages.len() - 1], extract_text(last_message))
|
||||
} else if preserve_last_user_message {
|
||||
// Last message is not a user message, but we want to preserve the most recent user message
|
||||
// Find the most recent user message and copy it (don't remove from history)
|
||||
let most_recent_user_message = messages
|
||||
// Last message is not a user message with text only, but we want to preserve the most recent user message with text only
|
||||
// Find the most recent user message with text content only and extract its text
|
||||
let preserved_text = messages
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|msg| matches!(msg.role, rmcp::model::Role::User))
|
||||
.cloned();
|
||||
(messages.as_slice(), most_recent_user_message)
|
||||
.find(|msg| matches!(msg.role, rmcp::model::Role::User) && has_text_only(msg))
|
||||
.and_then(extract_text);
|
||||
(messages.as_slice(), preserved_text)
|
||||
} else {
|
||||
(messages.as_slice(), None)
|
||||
}
|
||||
@@ -117,8 +151,8 @@ Just continue the conversation naturally based on the summarized context"
|
||||
final_token_counts.push(assistant_message_tokens);
|
||||
|
||||
// Add back the preserved user message if it exists
|
||||
if let Some(user_message) = preserved_user_message {
|
||||
final_messages.push(user_message);
|
||||
if let Some(user_text) = preserved_user_text {
|
||||
final_messages.push(Message::user().with_text(&user_text));
|
||||
}
|
||||
|
||||
Ok((
|
||||
|
||||
Reference in New Issue
Block a user