use std::path::PathBuf;
use std::sync::Arc;
use byob_agent::PluginsConfig;
use byob_exec::{Exec, Mode};
use byob_plugins::AgentDef;
use byob_tools::Registry;
pub struct Loaded {
pub prompt: String,
pub agents: Vec<AgentDef>,
pub envs: Option<Arc<dyn byob_tools::EnvControl>>,
pub plugins: PluginsConfig,
}
pub fn load(tools: &mut Registry, linked: Vec<PathBuf>) -> Loaded {
byob_tools::register_builtins(tools);
let paths = byob_store::Paths::resolve();
let mode = Mode::from_env();
let mut exec_prompt = None;
let mut envs: Option<Arc<dyn byob_tools::EnvControl>> = None;
let settings = paths.as_ref().map(|p| byob_store::Settings::load(&p.settings()).value).unwrap_or_default();
match &mode {
Ok(mode) => {
let data = paths.as_ref().ok().map(|p| p.data_dir.clone());
let containers = settings.containers.clone();
let exec = Exec::with_containers(mode.clone(), data, containers.image, containers.runtime.as_deref());
exec_prompt = exec.prompt();
envs = Some(exec.envs.clone());
byob_exec::register(tools, exec);
}
Err(e) => log::warn!("no run_command/run_python: {e}"),
}
let sandbox = match mode {
Ok(Mode::Sandboxed(sb)) => Some(sb),
_ => None,
};
let mut plugins = PluginsConfig { linked, python: byob_plugins::default_python(), sandbox, ..Default::default() };
match &paths {
Ok(paths) => {
plugins.global_roots.push(paths.config_dir.join("plugins"));
plugins.global_roots.extend(settings.plugin_dirs.iter().cloned());
plugins.global_skills = Some(paths.config_dir.join("skills"));
plugins.scratch_root = Some(paths.data_dir.join("chats"));
}
Err(e) => log::warn!("no config folder ({e}); only --plugin folders are loaded"),
}
let mut prompt = byob_tools::artifact::PROMPT.to_owned();
if let Some(p) = exec_prompt {
prompt.push_str("\n\n");
prompt.push_str(&p);
}
let agents = match &paths {
Ok(paths) => {
let (agents, errors) = byob_plugins::load_agents_dir(&paths.config_dir.join("agents"));
for e in errors {
log::warn!("agent {e}");
}
agents
}
Err(_) => Vec::new(),
};
if !agents.is_empty() {
log::info!("{} subagent(s) of your own: {}", agents.len(), agents.iter().map(|a| a.name.as_str()).collect::<Vec<_>>().join(", "));
}
Loaded { prompt: prompt.trim().to_owned(), agents, envs, plugins }
}