use agent_client_protocol::schema::ProtocolVersion;
use agent_client_protocol::schema::v1::{
ContentBlock, InitializeRequest, NewSessionRequest, PromptRequest, RequestPermissionOutcome,
RequestPermissionRequest, RequestPermissionResponse, SelectedPermissionOutcome,
SessionNotification, TextContent,
};
use agent_client_protocol::{AcpAgent, Agent, ConnectionTo};
use clap::Parser;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Parser)]
#[command(name = "yolo-one-shot-client")]
#[command(about = "A simple ACP client for one-shot prompts", long_about = None)]
struct Cli {
#[arg(short, long)]
command: String,
prompt: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
eprintln!("🚀 Spawning agent: {}", cli.command);
let agent = AcpAgent::from_str(&cli.command)?;
agent_client_protocol::Client
.builder()
.on_receive_notification(
async move |notification: SessionNotification, _cx| {
println!("{:?}", notification.update);
Ok(())
},
agent_client_protocol::on_receive_notification!(),
)
.on_receive_request(
async move |request: RequestPermissionRequest, responder, _connection| {
eprintln!("✅ Auto-approving permission request: {request:?}");
let option_id = request.options.first().map(|opt| opt.option_id.clone());
if let Some(id) = option_id {
responder.respond(RequestPermissionResponse::new(
RequestPermissionOutcome::Selected(SelectedPermissionOutcome::new(id)),
))
} else {
eprintln!("⚠️ No options provided in permission request, cancelling");
responder.respond(RequestPermissionResponse::new(
RequestPermissionOutcome::Cancelled,
))
}
},
agent_client_protocol::on_receive_request!(),
)
.connect_with(agent, |connection: ConnectionTo<Agent>| async move {
eprintln!("🤝 Initializing agent...");
let init_response = connection
.send_request(InitializeRequest::new(ProtocolVersion::V1))
.block_task()
.await?;
eprintln!("✓ Agent initialized: {:?}", init_response.agent_info);
eprintln!("📝 Creating new session...");
let new_session_response = connection
.send_request(NewSessionRequest::new(
std::env::current_dir().unwrap_or_else(|_| PathBuf::from("/")),
))
.block_task()
.await?;
let session_id = new_session_response.session_id;
eprintln!("✓ Session created");
eprintln!("💬 Sending prompt: \"{}\"", cli.prompt);
let prompt_response = connection
.send_request(PromptRequest::new(
session_id.clone(),
vec![ContentBlock::Text(TextContent::new(cli.prompt.clone()))],
))
.block_task()
.await?;
eprintln!("✅ Agent completed!");
eprintln!("Stop reason: {:?}", prompt_response.stop_reason);
Ok(())
})
.await?;
Ok(())
}