mod agent;
pub mod commands;
use agent::OctomindAgent;
use anyhow::Result;
use futures::future::LocalBoxFuture;
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
use crate::config::Config;
pub async fn run(config: Config, role: String) -> Result<()> {
let write_init_error = |msg: String| {
if let Ok(logs_dir) = crate::directories::get_logs_dir() {
let log_file = logs_dir.join("acp-init-errors.log");
if let Ok(mut file) = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&log_file)
{
use std::io::Write;
let _ = writeln!(file, "{msg}");
}
}
};
let log_level = config.log_level.as_str();
if let Err(e) = crate::logging::tracing_setup::init_tracing(
crate::logging::tracing_setup::LoggingMode::Acp,
log_level,
) {
write_init_error(format!("Failed to initialize tracing: {e}"));
}
if let Err(e) = crate::logging::AcpErrorSink::initialize() {
write_init_error(format!("Failed to initialize ACP error sink: {e}"));
}
let local = tokio::task::LocalSet::new();
local
.run_until(async move {
let agent = std::rc::Rc::new(OctomindAgent::new(config, role));
let stdin = tokio::io::stdin().compat();
let stdout = tokio::io::stdout().compat_write();
let (conn, io_task) = agent_client_protocol::AgentSideConnection::new(
std::rc::Rc::clone(&agent),
stdout,
stdin,
|fut: LocalBoxFuture<'static, ()>| {
tokio::task::spawn_local(fut);
},
);
let conn = std::rc::Rc::new(conn);
agent.set_connection(std::rc::Rc::clone(&conn));
if let Err(e) = io_task.await {
crate::log_debug!("ACP: I/O loop ended: {}", e);
}
Ok(())
})
.await
}