use anyhow::Result;
use crate::generator::research::memory::MemoryScope;
use crate::generator::research::types::{AgentType, DomainModulesReport};
use crate::generator::{
context::GeneratorContext,
step_forward_agent::{
AgentDataConfig, DataSource, FormatterConfig, LLMCallMode, PromptTemplate, StepForwardAgent,
},
};
#[derive(Default)]
pub struct DomainModulesDetector;
impl StepForwardAgent for DomainModulesDetector {
type Output = DomainModulesReport;
fn agent_type(&self) -> String {
AgentType::DomainModulesDetector.to_string()
}
fn agent_type_enum(&self) -> Option<AgentType> {
Some(AgentType::DomainModulesDetector)
}
fn memory_scope_key(&self) -> String {
MemoryScope::STUDIES_RESEARCH.to_string()
}
fn data_config(&self) -> AgentDataConfig {
AgentDataConfig {
required_sources: vec![
DataSource::ResearchResult(AgentType::SystemContextResearcher.to_string()),
DataSource::DEPENDENCY_ANALYSIS,
DataSource::CODE_INSIGHTS,
],
optional_sources: vec![DataSource::PROJECT_STRUCTURE],
}
}
fn prompt_template(&self) -> PromptTemplate {
PromptTemplate {
system_prompt: r#"You are a professional software architecture analyst, specializing in identifying domain architecture and modules in projects based on the provided information and research materials"#
.to_string(),
opening_instruction: "Based on the following research materials, conduct a high-level architecture analysis:".to_string(),
closing_instruction: r#"
## Analysis Requirements:
- Use a top-down analysis approach, domains first then modules
- Domain division should reflect functional value, not technical implementation
- Maintain a reasonable level of abstraction, avoid excessive detail
- Focus on core business logic and key dependency relationships"#
.to_string(),
llm_call_mode: LLMCallMode::Extract,
formatter_config: FormatterConfig {
only_directories_when_files_more_than: Some(500),
..FormatterConfig::default()
},
}
}
fn post_process(
&self,
result: &DomainModulesReport,
_context: &GeneratorContext,
) -> Result<()> {
println!("✅ Domain architecture analysis completed:");
println!(" - Identified domain modules: {}", result.domain_modules.len());
let total_sub_modules: usize = result
.domain_modules
.iter()
.map(|d| d.sub_modules.len())
.sum();
println!(" - Total sub-modules: {}", total_sub_modules);
println!(" - Domain relations: {}", result.domain_relations.len());
println!(" - Business flows: {}", result.business_flows.len());
println!(" - Confidence score: {:.1}/10", result.confidence_score);
Ok(())
}
}