pub mod config;
pub mod docker;
pub use config::{SandboxConfig, SandboxMode};
pub use docker::DockerSandbox;
use anyhow::{bail, Result};
pub fn resolve_mode(
sandbox_flag: bool,
global_config: &std::collections::HashMap<String, serde_yaml::Value>,
agent_config: &std::collections::HashMap<String, serde_yaml::Value>,
) -> SandboxMode {
if sandbox_flag {
return SandboxMode::FullWorkflow;
}
if let Some(serde_yaml::Value::Mapping(m)) = global_config.get("sandbox") {
if m.get(serde_yaml::Value::String("enabled".into()))
.and_then(|v| v.as_bool())
.unwrap_or(false)
{
return SandboxMode::Devbox;
}
}
if agent_config
.get("sandbox")
.and_then(|v| v.as_bool())
.unwrap_or(false)
{
return SandboxMode::AgentOnly;
}
SandboxMode::Disabled
}
pub async fn require_docker() -> Result<()> {
if !DockerSandbox::is_sandbox_available().await {
bail!(
"Docker Sandbox is not available.\n\
\n\
Requirements:\n\
• Docker Desktop 4.40 or later (https://www.docker.com/products/docker-desktop/)\n\
• Docker daemon must be running\n\
\n\
To disable the sandbox, remove --sandbox flag or set `config.agent.sandbox: false`."
);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
fn make_global_sandbox_enabled() -> HashMap<String, serde_yaml::Value> {
serde_yaml::from_str(
r#"
sandbox:
enabled: true
image: "ubuntu:22.04"
"#,
)
.unwrap()
}
fn make_agent_sandbox_true() -> HashMap<String, serde_yaml::Value> {
serde_yaml::from_str("sandbox: true").unwrap()
}
#[test]
fn cli_flag_wins_over_config() {
let mode = resolve_mode(true, &HashMap::new(), &HashMap::new());
assert_eq!(mode, SandboxMode::FullWorkflow);
}
#[test]
fn global_config_enabled_gives_devbox_mode() {
let global = make_global_sandbox_enabled();
let mode = resolve_mode(false, &global, &HashMap::new());
assert_eq!(mode, SandboxMode::Devbox);
}
#[test]
fn agent_config_sandbox_true_gives_agent_only() {
let agent = make_agent_sandbox_true();
let mode = resolve_mode(false, &HashMap::new(), &agent);
assert_eq!(mode, SandboxMode::AgentOnly);
}
#[test]
fn no_config_gives_disabled() {
let mode = resolve_mode(false, &HashMap::new(), &HashMap::new());
assert_eq!(mode, SandboxMode::Disabled);
}
#[test]
fn cli_flag_overrides_agent_config() {
let agent = make_agent_sandbox_true();
let mode = resolve_mode(true, &HashMap::new(), &agent);
assert_eq!(mode, SandboxMode::FullWorkflow);
}
}