use super::{NoAdapter, NoLauncher, NoSleeper};
use crate::prompt::clock::SystemClock;
use crate::prompt::tool::{ExecError, ToolCall, ToolExecutor, ToolOutcome};
use crate::template::RealGit;
use serde_json::Value;
use std::cell::RefCell;
use std::sync::atomic::AtomicBool;
use tempfile::TempDir;
pub(super) struct Scripted {
pub(super) log: RefCell<Vec<(String, String, Value)>>,
pub(super) fail: &'static [&'static str],
pub(super) kill: &'static [&'static str],
pub(super) fault: &'static [&'static str],
}
impl Scripted {
pub(super) fn new() -> Self {
Self {
log: RefCell::new(Vec::new()),
fail: &[],
kill: &[],
fault: &[],
}
}
}
impl ToolExecutor for Scripted {
fn execute(
&self,
invocation: ToolCall<'_>,
_step_dir: &std::path::Path,
_stop: &AtomicBool,
_bound: Option<crate::config::ToolOutputBound>,
) -> Result<ToolOutcome, ExecError> {
self.log.borrow_mut().push((
invocation.id.to_string(),
invocation.name.to_string(),
invocation.input.clone(),
));
if self.kill.contains(&invocation.name) {
return Err(ExecError::KilledBySignal {
name: invocation.name.to_string(),
signal: 15,
});
}
if self.fault.contains(&invocation.name) {
return Err(ExecError::Spawn {
name: invocation.name.to_string(),
source: std::io::Error::other("no such binary"),
});
}
Ok(ToolOutcome {
content: format!("ran {}", invocation.name).into_bytes(),
is_error: self.fail.contains(&invocation.name),
})
}
}
pub(super) struct Fixture {
pub(super) git: RealGit,
clock: SystemClock,
id_gen: crate::prompt::NanoIdGen,
cfg: TempDir,
}
impl Fixture {
pub(super) fn new() -> Self {
Self {
git: RealGit::new(),
clock: SystemClock,
id_gen: crate::prompt::NanoIdGen,
cfg: TempDir::new().unwrap(),
}
}
pub(super) fn deps<'a>(
&'a self,
exec: &'a dyn ToolExecutor,
stop: &'a AtomicBool,
) -> crate::prompt::Deps<'a> {
crate::prompt::Deps {
adapter: &NoAdapter,
sleeper: &NoSleeper,
git: &self.git,
clock: &self.clock,
id_gen: &self.id_gen,
tool_executor: exec,
config_root: self.cfg.path(),
data_root: self.cfg.path(),
adapter_target: None,
stop,
launcher: &NoLauncher,
rng: crate::workspace::agent_name::mint::test_rng(),
}
}
}