use sage_core::agent::UnifiedExecutor;
use sage_core::agent::{ExecutionMode, ExecutionOptions};
use sage_core::error::SageResult;
use sage_core::mcp::{clear_active_mcp_registry, set_active_mcp_registry};
use sage_core::output::{OutputMode, UiEventOutput};
use sage_core::ui::traits::UiContext;
use std::sync::Arc;
pub async fn create_executor(
ui_context: Option<UiContext>,
config_file: &str,
working_dir: Option<std::path::PathBuf>,
max_steps: Option<u32>,
) -> SageResult<UnifiedExecutor> {
let config = if std::path::Path::new(config_file).exists() {
sage_core::config::load_config_from_file(config_file)?
} else {
sage_core::config::load_config()?
};
let resolved_working_dir = working_dir
.or_else(|| config.working_directory.clone())
.unwrap_or_else(|| {
std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."))
});
let mut options = ExecutionOptions::default()
.with_mode(ExecutionMode::interactive())
.with_working_directory(&resolved_working_dir);
if let Some(steps) = max_steps {
options = options.with_step_limit(steps);
}
let mut executor = UnifiedExecutor::with_options(config.clone(), options)?;
if let Some(ctx) = ui_context {
executor.set_ui_context(ctx.clone());
executor.set_output_strategy(Arc::new(UiEventOutput::new(ctx)));
} else {
executor.set_output_mode(OutputMode::Rnk);
}
let mut all_tools = sage_tools::get_default_tools_with_context(
resolved_working_dir.clone(),
executor.skill_registry(),
);
if config.mcp.enabled {
match crate::commands::unified::build_mcp_registry_from_config(&config).await {
Ok(mcp_registry) => {
let mcp_registry = Arc::new(mcp_registry);
set_active_mcp_registry(Arc::clone(&mcp_registry));
let mcp_tools = mcp_registry.as_tools().await;
if !mcp_tools.is_empty() {
all_tools.extend(mcp_tools);
}
}
Err(e) => {
clear_active_mcp_registry();
tracing::error!("Failed to build MCP registry: {}", e);
}
}
} else {
clear_active_mcp_registry();
}
executor.register_tools(all_tools);
if let Err(e) = executor.init_subagent_support() {
tracing::warn!("Failed to initialize subagent support: {}", e);
}
let jsonl_storage = sage_core::session::JsonlSessionStorage::default_path()?;
executor.set_jsonl_storage(std::sync::Arc::new(jsonl_storage));
if let Err(e) = executor.enable_session_recording().await {
tracing::warn!("Failed to enable session recording: {}", e);
}
Ok(executor)
}