Expand description
Host-side bookkeeping wrapper around DuplexSession.
Conversation keeps a rolling history of TurnResults,
cumulative cost, and an optional BudgetTracker hard stop on top
of an underlying DuplexSession. The duplex session itself
remains the transport; this wrapper only adds accounting that
DuplexSession::send does not provide on its own.
For the equivalent shape on top of transient --resume subprocess
turns, see Session. Conversation
is the duplex-flavoured peer.
§When to use
Reach for Conversation when you already want a
DuplexSession (long-running host, mid-turn interrupts, broadcast
subscribers) AND want to answer questions like:
- How much have I spent on this conversation so far?
- What’s the full history of turns and their costs?
- Stop accepting new turns once I hit $5.
If you do not need bookkeeping, use DuplexSession directly. If
you want accounting on short-lived per-turn subprocess calls, use
Session instead.
§Example
use claude_wrapper::Claude;
use claude_wrapper::conversation::Conversation;
use claude_wrapper::duplex::{DuplexOptions, DuplexSession};
let claude = Claude::builder().build()?;
let session = DuplexSession::spawn(
&claude,
DuplexOptions::default().model("haiku"),
).await?;
let mut conv = Conversation::new(session);
let _first = conv.send("hello").await?;
let _second = conv.send("and again").await?;
println!("turns: {}", conv.total_turns());
println!("cost: ${:.4}", conv.total_cost_usd());
conv.close().await?;§Budget tracking
Attach a BudgetTracker (the same type Session
uses) to enforce a cumulative USD ceiling. The pre-turn check runs
before delegating to DuplexSession::send; once the ceiling is
hit, Conversation::send returns
Error::BudgetExceeded
without touching the underlying session.
use claude_wrapper::{BudgetTracker, Claude};
use claude_wrapper::conversation::Conversation;
use claude_wrapper::duplex::{DuplexOptions, DuplexSession};
let budget = BudgetTracker::builder().max_usd(5.00).build();
let claude = Claude::builder().build()?;
let session = DuplexSession::spawn(&claude, DuplexOptions::default()).await?;
let mut conv = Conversation::new(session).with_budget(budget.clone());
let _ = conv.send("hello").await?;
println!("spent: ${:.4}", budget.total_usd());§Beyond bookkeeping
Conversation::send is the only entry point that updates
history. For DuplexSession::subscribe,
DuplexSession::interrupt, and
DuplexSession::respond_to_permission, use Conversation::session
to reach the inner handle. Those calls bypass the wrapper’s
accounting on purpose: an interrupt still produces a TurnResult
that the in-flight Conversation::send records cleanly when the
truncated turn lands.
Structs§
- Conversation
- Host-side bookkeeping over a
DuplexSession.