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();
|
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((
|
||||||
|
|||||||
Reference in New Issue
Block a user