use anyhow::Result;
use std::sync::Arc;
use crate::providers::Provider;
use super::ai::{AiExecutor, AiExecutorConfig};
use super::condition::ConditionExecutor;
use super::node_executor::NodeExecutor;
use super::tool::ToolExecutor;
use super::validate::{ValidateExecutor, ValidateExecutorConfig};
pub struct ExecutorFactory {
pub provider: Option<Arc<dyn Provider>>,
pub tool_names: Vec<String>,
}
impl ExecutorFactory {
pub fn new() -> Self {
Self {
provider: None,
tool_names: Vec::new(),
}
}
pub fn with_provider(mut self, provider: Arc<dyn Provider>) -> Self {
self.provider = Some(provider);
self
}
pub fn with_tool_names(mut self, names: Vec<String>) -> Self {
self.tool_names = names;
self
}
pub fn create_ai_executor(&self) -> Result<Arc<dyn NodeExecutor>> {
let provider = self.provider.clone()
.ok_or_else(|| anyhow::anyhow!("Provider not configured for AI executor"))?;
Ok(Arc::new(AiExecutor::new(provider)))
}
pub fn create_ai_executor_with_config(&self, config: AiExecutorConfig) -> Result<Arc<dyn NodeExecutor>> {
let provider = self.provider.clone()
.ok_or_else(|| anyhow::anyhow!("Provider not configured for AI executor"))?;
Ok(Arc::new(AiExecutor::with_config(provider, config)))
}
pub fn create_tool_executor(&self) -> Arc<dyn NodeExecutor> {
let tools = if let Some(provider) = &self.provider {
crate::tools::all_tools_with_provider(
std::sync::Arc::new(Vec::new()),
provider.clone()
)
} else {
crate::tools::all_tools()
};
Arc::new(ToolExecutor::new(tools))
}
pub fn create_condition_executor(&self) -> Arc<dyn NodeExecutor> {
Arc::new(ConditionExecutor::new())
}
pub fn create_validate_executor(&self) -> Arc<dyn NodeExecutor> {
Arc::new(ValidateExecutor::new())
}
pub fn create_validate_executor_with_ai(&self, config: ValidateExecutorConfig) -> Result<Arc<dyn NodeExecutor>> {
let provider = self.provider.clone()
.ok_or_else(|| anyhow::anyhow!("Provider not configured for AI validation"))?;
Ok(Arc::new(ValidateExecutor::with_ai(provider, config)))
}
pub fn create_executor_for_task(&self, task_type: &str) -> Result<Arc<dyn NodeExecutor>> {
match task_type {
"ai" | "claude" | "gpt" => self.create_ai_executor(),
"tool" | "bash" | "read" | "write" | "edit" => Ok(self.create_tool_executor()),
"condition" | "branch" => Ok(self.create_condition_executor()),
"validate" | "check" => Ok(self.create_validate_executor()),
_ => Err(anyhow::anyhow!("Unknown task type: {}", task_type)),
}
}
}
impl Default for ExecutorFactory {
fn default() -> Self {
Self::new()
}
}