use super::config::Seat;
use std::path::Path;
use std::process::ExitCode;
#[derive(Clone, Copy, Debug, clap::Subcommand)]
pub enum AgentCommand {
Run,
#[command(hide = true)]
Tools,
}
#[must_use]
pub fn run(path: &Path, command: AgentCommand) -> ExitCode {
let result = Seat::load(path).and_then(|seat| match command {
AgentCommand::Tools => tools(&seat),
AgentCommand::Run => {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?;
let outcome = runtime.block_on(super::host::serve(&seat))?;
for error in outcome.errors {
eprintln!("liminal agent: {error}");
}
Ok(outcome.status)
}
});
match result {
Ok(status) => u8::try_from(status).map_or_else(
|_| {
eprintln!("liminal agent: harness exit status is outside the process exit range");
ExitCode::from(1)
},
ExitCode::from,
),
Err(error) => {
eprintln!("liminal agent: {error}");
ExitCode::from(1)
}
}
}
fn tools(seat: &Seat) -> anyhow::Result<i32> {
let live = crate::Live::new(&seat.ticket).map_err(anyhow::Error::msg)?;
let mut server = crate::Server::new(live, seat.ticket.limits.frame_bytes);
let stdin = std::io::stdin();
server.serve(&mut stdin.lock(), &mut std::io::stdout())?;
Ok(0)
}