use async_trait::async_trait;
use serde_json::Value;
use crate::mcp::core::{error::WorkflowError, nodes::Node, task::TaskContext};
#[derive(Debug, Clone)]
pub struct AnalyzeKnowledgeNode;
#[async_trait]
impl Node for AnalyzeKnowledgeNode {
async fn execute(&self, input: Value, _context: &TaskContext) -> Result<Value, WorkflowError> {
let notion_results = input.get("notion_search_results");
let helpscout_results = input.get("helpscout_search_results");
let slack_results = input.get("slack_search_results");
let mut total_results = 0;
let mut high_relevance_count = 0;
let mut all_sources = Vec::new();
if let Some(notion) = notion_results {
if let Some(count) = notion.get("results_found").and_then(|v| v.as_u64()) {
total_results += count;
}
if let Some(pages) = notion.get("pages").and_then(|v| v.as_array()) {
for page in pages {
if let Some(relevance) = page.get("relevance").and_then(|v| v.as_u64()) {
if relevance >= 80 {
high_relevance_count += 1;
}
}
}
}
all_sources.push("notion");
}
if let Some(helpscout) = helpscout_results {
if let Some(count) = helpscout.get("results_found").and_then(|v| v.as_u64()) {
total_results += count;
}
for result_type in ["articles", "conversations"] {
if let Some(items) = helpscout.get(result_type).and_then(|v| v.as_array()) {
for item in items {
if let Some(relevance) = item.get("relevance").and_then(|v| v.as_u64()) {
if relevance >= 80 {
high_relevance_count += 1;
}
}
}
}
}
all_sources.push("helpscout");
}
if let Some(slack) = slack_results {
if let Some(count) = slack.get("results_found").and_then(|v| v.as_u64()) {
total_results += count;
}
if let Some(messages) = slack.get("messages").and_then(|v| v.as_array()) {
for message in messages {
if let Some(relevance) = message.get("relevance").and_then(|v| v.as_u64()) {
if relevance >= 80 {
high_relevance_count += 1;
}
}
}
}
all_sources.push("slack");
}
let sufficient_info = total_results >= 2 && high_relevance_count >= 1;
let analysis_message = if !sufficient_info {
"Insufficient information found to provide a comprehensive answer".to_string()
} else {
format!(
"Found {} results with {} high-relevance matches",
total_results, high_relevance_count
)
};
Ok(serde_json::json!({
"total_results_found": total_results,
"high_relevance_count": high_relevance_count,
"sufficient_information": sufficient_info,
"sources_searched": all_sources,
"analysis_completed": true,
"analysis_message": analysis_message,
"event_data": input.get("event_data").cloned().unwrap_or(input.clone())
}))
}
fn name(&self) -> &str {
"AnalyzeKnowledgeNode"
}
}