use goose_provider_types::conversation::message::{ActionRequiredData, Message, MessageContent};
use rmcp::model::Role;
pub fn format_message_for_compacting(msg: &Message) -> String {
let content_parts: Vec<String> = msg
.content
.iter()
.filter_map(|content| match content {
MessageContent::Text(text) => Some(text.text.clone()),
MessageContent::Image(img) => Some(format!("[image: {}]", img.mime_type)),
MessageContent::Document(doc) => Some(match &doc.name {
Some(name) => format!("[document: {} ({})]", name, doc.mime_type),
None => format!("[document: {}]", doc.mime_type),
}),
MessageContent::ToolRequest(req) => {
if let Ok(call) = &req.tool_call {
Some(format!(
"tool_request({}): {}",
call.name,
serde_json::to_string(&call.arguments)
.unwrap_or_else(|_| "<<invalid json>>".to_string())
))
} else {
Some("tool_request: [error]".to_string())
}
}
MessageContent::ToolResponse(res) => {
if let Ok(result) = &res.tool_result {
let text_items: Vec<String> = result
.content
.iter()
.filter_map(|content| {
content.as_text().map(|text_str| text_str.text.clone())
})
.collect();
if !text_items.is_empty() {
Some(format!("tool_response: {}", text_items.join("\n")))
} else {
Some("tool_response: [non-text content]".to_string())
}
} else {
Some("tool_response: [error]".to_string())
}
}
MessageContent::ToolConfirmationRequest(req) => {
Some(format!("tool_confirmation_request: {}", req.tool_name))
}
MessageContent::ActionRequired(action) => match &action.data {
ActionRequiredData::ToolConfirmation { tool_name, .. } => {
Some(format!("action_required(tool_confirmation): {}", tool_name))
}
ActionRequiredData::Elicitation { message, .. } => {
Some(format!("action_required(elicitation): {}", message))
}
ActionRequiredData::ElicitationResponse { id, .. } => {
Some(format!("action_required(elicitation_response): {}", id))
}
ActionRequiredData::ToolConfirmationResponse { id, .. } => Some(format!(
"action_required(tool_confirmation_response): {}",
id
)),
},
MessageContent::Thinking(_) => None,
MessageContent::RedactedThinking(_) => None,
MessageContent::SystemNotification(notification) => {
Some(format!("system_notification: {}", notification.msg))
}
MessageContent::Error(error) => Some(format!("error: {}", error.message)),
})
.collect();
let role_str = match msg.role {
Role::User => "user",
Role::Assistant => "assistant",
};
if content_parts.is_empty() {
format!("[{}]: <empty message>", role_str)
} else {
format!("[{}]: {}", role_str, content_parts.join("\n"))
}
}