pub mod http;
pub mod terminal;
use anyhow::Result;
use async_trait::async_trait;
#[async_trait]
pub trait AgentIO: Send + Sync {
async fn show_status(&self, msg: &str) -> Result<()>;
async fn show_tool_call(&self, tool_name: &str, args_preview: &str) -> Result<()>;
async fn show_tool_result(&self, preview: &str, is_error: bool) -> Result<()>;
async fn write_error(&self, msg: &str) -> Result<()>;
async fn confirm_destructive(&self, tool_name: &str, args_preview: &str) -> Result<bool>;
}
#[allow(dead_code)]
pub struct NullIO;
#[async_trait]
impl AgentIO for NullIO {
async fn show_status(&self, _msg: &str) -> Result<()> {
Ok(())
}
async fn show_tool_call(&self, _tool_name: &str, _args_preview: &str) -> Result<()> {
Ok(())
}
async fn show_tool_result(&self, _preview: &str, _is_error: bool) -> Result<()> {
Ok(())
}
async fn write_error(&self, _msg: &str) -> Result<()> {
Ok(())
}
async fn confirm_destructive(&self, _tool_name: &str, _args_preview: &str) -> Result<bool> {
Ok(false)
}
}
pub struct AutoApproveIO;
#[async_trait]
impl AgentIO for AutoApproveIO {
async fn show_status(&self, msg: &str) -> Result<()> {
terminal::TerminalIO { no_markdown: false }
.show_status(msg)
.await
}
async fn show_tool_call(&self, tool_name: &str, args_preview: &str) -> Result<()> {
terminal::TerminalIO { no_markdown: false }
.show_tool_call(tool_name, args_preview)
.await
}
async fn show_tool_result(&self, preview: &str, is_error: bool) -> Result<()> {
terminal::TerminalIO { no_markdown: false }
.show_tool_result(preview, is_error)
.await
}
async fn write_error(&self, msg: &str) -> Result<()> {
terminal::TerminalIO { no_markdown: false }
.write_error(msg)
.await
}
async fn confirm_destructive(&self, _tool_name: &str, _args_preview: &str) -> Result<bool> {
Ok(true)
}
}
pub struct JsonIO;
#[async_trait]
impl AgentIO for JsonIO {
async fn show_status(&self, msg: &str) -> Result<()> {
let j = serde_json::json!({ "event": "status", "msg": msg });
println!("{}", j);
Ok(())
}
async fn show_tool_call(&self, tool_name: &str, args_preview: &str) -> Result<()> {
let j = serde_json::json!({ "event": "tool_call", "tool": tool_name, "args": args_preview });
println!("{}", j);
Ok(())
}
async fn show_tool_result(&self, preview: &str, is_error: bool) -> Result<()> {
let j = serde_json::json!({ "event": "tool_result", "preview": preview, "is_error": is_error });
println!("{}", j);
Ok(())
}
async fn write_error(&self, msg: &str) -> Result<()> {
let j = serde_json::json!({ "event": "error", "msg": msg });
println!("{}", j);
Ok(())
}
async fn confirm_destructive(&self, _tool_name: &str, _args_preview: &str) -> Result<bool> {
Ok(true)
}
}