pub use bindings::Bindings;
use names::{
APPLY_PATCH, BASH, CD, DISPATCH, LOAD_SKILL, MESSAGE, READ_FILE, REMEMBER, SEARCH_HISTORY,
};
pub use names::{NAMES, pool};
pub(crate) use names::{PYTHON, READ_TOOL_OUTPUT};
use std::io::{Read, Write};
use thiserror::Error;
pub mod apply_patch;
pub mod bash;
pub(crate) mod bindings;
pub mod cd;
pub(crate) mod child;
pub mod compaction;
pub mod dispatch;
mod harness;
pub mod load_skill;
pub mod message;
mod names;
pub mod python;
pub mod read_file;
pub mod read_tool_output;
pub mod remember;
pub mod search_history;
#[derive(Debug, Error)]
pub enum Error {
#[error("unknown built-in tool: {0:?}; available: {available}", available = pool())]
Unknown(String),
#[error(transparent)]
ReadFile(#[from] read_file::Error),
#[error(transparent)]
ApplyPatch(#[from] apply_patch::Error),
#[error(transparent)]
Bash(#[from] bash::Error),
#[error(transparent)]
Dispatch(#[from] dispatch::Error),
#[error(transparent)]
Message(#[from] message::Error),
#[error(transparent)]
Cd(#[from] cd::Error),
#[error(transparent)]
LoadSkill(#[from] load_skill::Error),
#[error(transparent)]
ReadToolOutput(#[from] read_tool_output::Error),
#[error(transparent)]
Remember(#[from] remember::Error),
#[error(transparent)]
SearchHistory(#[from] search_history::Error),
#[error(transparent)]
Python(#[from] python::Error),
#[error(transparent)]
Compaction(#[from] compaction::Error),
}
#[rustfmt::skip]
pub fn run<R: Read, W: Write, E: Write>(
name: &str,
bindings: &Bindings<'_>,
stdin: &mut R,
stdout: &mut W,
stderr: &mut E,
) -> Result<i32, Error> {
if name == PYTHON {
return python::run(stdin, stdout, stderr, bindings, &dispatch::ProcessEnv)
.map_err(Error::Python);
}
let target = bindings.driver_target.to_path_buf();
let spawner = dispatch::SubprocessSpawner::with_exe(target.clone());
let sender = message::SubprocessSender::with_exe(target);
run_with(name, stdin, stdout, stderr, &dispatch::ProcessEnv, &spawner, &sender)
}
pub fn run_with<R: Read, W: Write, E: Write>(
name: &str,
stdin: &mut R,
stdout: &mut W,
stderr: &mut E,
env: &dyn dispatch::EnvLookup,
spawner: &dyn dispatch::Spawner,
sender: &dyn message::Sender,
) -> Result<i32, Error> {
if name == READ_FILE {
return read_file::run(stdin, stdout, stderr)
.map(|()| 0)
.map_err(Error::ReadFile);
}
if name == APPLY_PATCH {
return apply_patch::run(stdin, stdout)
.map(|()| 0)
.map_err(Error::ApplyPatch);
}
if name == BASH {
return bash::run(stdin, stdout, stderr).map_err(Error::Bash);
}
if name == DISPATCH {
return dispatch::run(stdin, stdout, env, spawner)
.map(|()| 0)
.map_err(Error::Dispatch);
}
if name == MESSAGE {
return message::run(stdin, stdout, env, sender)
.map(|()| 0)
.map_err(Error::Message);
}
if name == CD {
return cd::run(stdin, stdout, env).map(|()| 0).map_err(Error::Cd);
}
if name == LOAD_SKILL {
return load_skill::run(stdin, stdout, env)
.map(|()| 0)
.map_err(Error::LoadSkill);
}
if name == READ_TOOL_OUTPUT {
return read_tool_output::run(stdin, stdout, stderr, env)
.map(|()| 0)
.map_err(Error::ReadToolOutput);
}
if name == REMEMBER {
return remember::run(stdin, stdout, env)
.map(|()| 0)
.map_err(Error::Remember);
}
if name == SEARCH_HISTORY {
return search_history::run(stdin, stdout, env)
.map(|()| 0)
.map_err(Error::SearchHistory);
}
if name == crate::prompt::compactor::tools::WRITE_SUMMARY {
return compaction::run_write_summary(stdin, stdout, env)
.map(|()| 0)
.map_err(Error::Compaction);
}
if name == crate::prompt::compactor::tools::MARK_FOR_DELETION {
return compaction::run_mark_for_deletion(stdin, stdout, env)
.map(|()| 0)
.map_err(Error::Compaction);
}
Err(Error::Unknown(name.to_string()))
}
#[cfg(test)]
mod tests;