use std::io::Write;
use claude_wrapper::Claude;
use claude_wrapper::duplex::{DuplexOptions, DuplexSession, InboundEvent};
use tokio::io::{AsyncBufReadExt, BufReader};
#[tokio::main]
async fn main() -> claude_wrapper::Result<()> {
let claude = Claude::builder().build()?;
let session = DuplexSession::spawn(&claude, DuplexOptions::default().model("haiku")).await?;
let mut rx = session.subscribe();
let printer = tokio::spawn(async move {
while let Ok(event) = rx.recv().await {
let tag = match event {
InboundEvent::SystemInit { ref session_id } => {
eprintln!("[init] session_id={session_id}");
continue;
}
InboundEvent::Assistant(_) => "[assistant]",
InboundEvent::StreamEvent(_) => "[stream]",
InboundEvent::User(_) => "[user]",
InboundEvent::Other(_) => "[other]",
};
eprintln!("{tag}");
}
});
let stdin = tokio::io::stdin();
let mut lines = BufReader::new(stdin).lines();
println!("DuplexSession chat (empty line to exit)");
print!("> ");
std::io::stdout().flush().ok();
while let Some(line) = lines.next_line().await.ok().flatten() {
if line.trim().is_empty() {
break;
}
let turn = session.send(line).await?;
if let Some(text) = turn.result_text() {
println!("\n{text}\n");
}
if let Some(cost) = turn.total_cost_usd() {
eprintln!("(turn cost: ${cost:.4})");
}
print!("> ");
std::io::stdout().flush().ok();
}
println!("\nclosing session...");
session.close().await?;
let _ = printer.await;
Ok(())
}