use std::path::Path;
use std::sync::mpsc;
use std::time::Duration;
use termesh_agent::service::{AgentEvent, AgentRequest, AgentService, ClientCapabilities};
use termesh_agent::AcpAgent;
fn command() -> Option<Vec<String>> {
let raw = std::env::var("TERMESH_TEST_AGENT").ok()?;
let argv: Vec<String> = raw.split_whitespace().map(str::to_string).collect();
if argv.is_empty() {
return None;
}
Some(argv)
}
#[test]
#[ignore = "needs a real ACP agent; set TERMESH_TEST_AGENT"]
fn a_real_agent_completes_the_handshake_and_opens_a_session() {
let Some(argv) = command() else {
panic!("set TERMESH_TEST_AGENT, e.g. TERMESH_TEST_AGENT=\"opencode acp\"");
};
let cwd = std::env::temp_dir();
let (tx, events) = mpsc::channel();
let mut agent =
AcpAgent::spawn(&argv, Path::new(&cwd), ClientCapabilities::default(), move |e| {
let _ = tx.send(e);
})
.expect("the agent should spawn");
agent.send(AgentRequest::NewSession { cwd });
let deadline = Duration::from_secs(30);
loop {
match events.recv_timeout(deadline) {
Ok(AgentEvent::SessionStarted { session }) => {
println!("session started: {session}");
return;
}
Ok(AgentEvent::Failed { message, .. }) => {
println!("agent declined: {message}");
assert!(
!message.contains("exited"),
"the agent died rather than answering: {message}"
);
return;
}
Ok(other) => println!("(ignoring {other:?})"),
Err(e) => panic!("no answer from the agent within {deadline:?}: {e}"),
}
}
}