use anyhow::Result;
use crate::generator::context::GeneratorContext;
use crate::generator::research::agents::architecture_researcher::ArchitectureResearcher;
use crate::generator::research::agents::boundary_analyzer::BoundaryAnalyzer;
use crate::generator::research::agents::database_overview_analyzer::DatabaseOverviewAnalyzer;
use crate::generator::research::agents::domain_modules_detector::DomainModulesDetector;
use crate::generator::research::agents::key_modules_insight::KeyModulesInsight;
use crate::generator::research::agents::system_context_researcher::SystemContextResearcher;
use crate::generator::research::agents::workflow_researcher::WorkflowResearcher;
use crate::generator::step_forward_agent::StepForwardAgent;
use crate::generator::preprocess::memory::{MemoryScope, ScopedKeys};
use crate::types::code::CodePurpose;
use crate::types::{CodeAndDirectoryInsights, DirectoryPurpose};
#[derive(Default)]
pub struct ResearchOrchestrator;
impl ResearchOrchestrator {
pub async fn execute_research_pipeline(&self, context: &GeneratorContext) -> Result<()> {
println!("🚀 Starting Litho Studies Research investigation pipeline...");
self.execute_agent(&SystemContextResearcher, context)
.await?;
self.execute_agent(&DomainModulesDetector, context)
.await?;
self.execute_agent(&ArchitectureResearcher, context)
.await?;
self.execute_agent(&WorkflowResearcher, context)
.await?;
self.execute_agent(&KeyModulesInsight, context)
.await?;
self.execute_agent(&BoundaryAnalyzer::default(), context)
.await?;
if self.has_database_files(context).await {
self.execute_agent(&DatabaseOverviewAnalyzer::default(), context)
.await?;
}
println!("✓ Litho Studies Research pipeline execution completed");
Ok(())
}
async fn has_database_files(&self, context: &GeneratorContext) -> bool {
if let Some(insights) = context
.get_from_memory::<CodeAndDirectoryInsights>(MemoryScope::PREPROCESS, ScopedKeys::CODE_INSIGHTS)
.await
{
insights.directory_insights.iter().any(|dossier| {
dossier.purpose == DirectoryPurpose::Database
|| dossier.name.to_lowercase().contains("database")
|| dossier.name.to_lowercase().contains("db")
}) || insights.directory_insights.iter().flat_map(|d| d.file_insights.iter()).any(|fi| {
fi.code_purpose == CodePurpose::Database
|| fi.file_path.to_string_lossy().ends_with(".sql")
|| fi.file_path.to_string_lossy().ends_with(".sqlproj")
})
} else {
false
}
}
async fn execute_agent<T>(
&self,
agent: &T,
context: &GeneratorContext,
) -> Result<()>
where
T: StepForwardAgent + Send + Sync,
{
let agent_name = if let Some(agent_enum) = agent.agent_type_enum() {
agent_enum.display_name(&context.config.target_language)
} else {
agent.agent_type()
};
println!("🤖 Executing {} agent analysis...", agent_name);
agent.execute(context).await?;
println!("✓ {} analysis completed", agent_name);
Ok(())
}
}