Filter preserved user messages to be text only. (#5391)

This commit is contained in:
David Katz
2025-10-27 15:21:23 -04:00
committed by GitHub
parent f0cffdb4ac
commit c021e00893
+48 -14
View File
@@ -42,21 +42,55 @@ pub async fn compact_messages(
let messages = conversation.messages(); let messages = conversation.messages();
// Check if the most recent message is a user message let has_text_only = |msg: &Message| {
let (messages_to_compact, preserved_user_message) = if let Some(last_message) = messages.last() let has_text = msg
{ .content
if matches!(last_message.role, rmcp::model::Role::User) { .iter()
// Remove the last user message before compaction .any(|c| matches!(c, MessageContent::Text(_)));
(&messages[..messages.len() - 1], Some(last_message.clone())) 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 { } else if preserve_last_user_message {
// Last message is not a user message, but we want to preserve the most recent user message // 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 and copy it (don't remove from history) // Find the most recent user message with text content only and extract its text
let most_recent_user_message = messages let preserved_text = messages
.iter() .iter()
.rev() .rev()
.find(|msg| matches!(msg.role, rmcp::model::Role::User)) .find(|msg| matches!(msg.role, rmcp::model::Role::User) && has_text_only(msg))
.cloned(); .and_then(extract_text);
(messages.as_slice(), most_recent_user_message) (messages.as_slice(), preserved_text)
} else { } else {
(messages.as_slice(), None) (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); final_token_counts.push(assistant_message_tokens);
// Add back the preserved user message if it exists // Add back the preserved user message if it exists
if let Some(user_message) = preserved_user_message { if let Some(user_text) = preserved_user_text {
final_messages.push(user_message); final_messages.push(Message::user().with_text(&user_text));
} }
Ok(( Ok((