use std::time::Instant;
use chrono::Local;
use super::{
ActivityItem, ChatMessage, ChatView, InlineContent, McpCallData, McpCallStatus, McpRetryInfo,
McpStatus, MessageRole,
};
use crate::runtime::chat_workflow::Role as WorkflowRole;
impl ChatView {
pub fn add_mcp_call(&mut self, tool: &str, server: &str, params: &str) {
let data = McpCallData::new(tool, server).with_params(params);
self.inline_content.push(InlineContent::McpCall(data));
self.activity_items.push(ActivityItem::hot(
format!("mcp-{}", self.inline_content.len()),
"invoke",
));
if let Some(server_info) = self
.session_context
.mcp_servers
.iter_mut()
.find(|s| s.name == server)
{
server_info.status = McpStatus::Hot;
server_info.last_call = Some(Instant::now());
}
self.auto_scroll_to_bottom();
}
pub fn complete_mcp_call(&mut self, result: &str) {
if let Some(InlineContent::McpCall(data)) = self.inline_content.last_mut() {
data.result = Some(result.to_string());
data.status = McpCallStatus::Success;
}
self.transition_activity_to_warm("invoke");
self.auto_scroll_to_bottom();
}
pub fn fail_mcp_call(&mut self, error: &str) {
if let Some(InlineContent::McpCall(data)) = self.inline_content.last_mut() {
self.last_failed_mcp = Some(McpRetryInfo {
tool: data.tool.clone(),
server: data.server.clone(),
params: serde_json::from_str(&data.params).unwrap_or(serde_json::Value::Null),
});
data.error = Some(error.to_string());
data.status = McpCallStatus::Failed;
}
self.auto_scroll_to_bottom();
}
pub fn add_tool_message(&mut self, content: String) {
let id = self.next_message_id();
self.messages.push(ChatMessage {
id,
role: MessageRole::Tool,
content: content.clone(),
timestamp: Local::now(),
created_at: Instant::now(),
execution: None,
thinking: None,
});
self.maybe_sync_dag();
let _ = self
.workflow
.add_message_with_mentions(&content, WorkflowRole::Tool);
}
}