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 agents: Vec<AgentDef>,
pub envs: Option<Arc<dyn byob_tools::EnvControl>>,
pub plugins: PluginsConfig,
}
pub fn load(tools: &mut Registry, artifact_types: &byob_tools::ArtifactTypes, linked: Vec<PathBuf>) -> Loaded {
byob_tools::register_builtins_with(tools, artifact_types);
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 natives = byob_agent::Natives::builtin().prompt("exec", move |_| exec_prompt.clone().unwrap_or_default());
#[cfg(feature = "native-sheets")]
let natives = natives.backend(byob_sheets::ID, byob_sheets::factory());
let mut plugins = PluginsConfig {
linked,
python: byob_plugins::default_python(),
sandbox,
bundled: byob_agent::natives::bundled_plugins(),
natives,
..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"));
plugins.python_root = Some(paths.data_dir.join("plugin-python"));
plugins.bundled_cache = Some(paths.data_dir.join("bundled-plugins"));
}
Err(e) => log::warn!("no config folder ({e}); only --plugin folders are loaded"),
}
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 { agents, envs, plugins }
}