Skip to main content

Module conversation

Module conversation 

Source
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.