use mixtape_core::{
Agent, AgentEvent, BedrockProvider, InferenceProfile, NoOpConversationManager, NovaMicro,
};
use std::io::Write;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Mixtape Streaming Example\n");
println!("Watch the response stream in real-time!\n");
println!("{}", "=".repeat(60));
let char_count = Arc::new(AtomicUsize::new(0));
let char_count_clone = Arc::clone(&char_count);
let provider = BedrockProvider::new(NovaMicro)
.await?
.with_inference_profile(InferenceProfile::US);
let agent = Agent::builder()
.provider(provider)
.with_conversation_manager(NoOpConversationManager::new())
.build()
.await?;
agent.add_hook(move |event: &AgentEvent| {
if let AgentEvent::ModelCallStreaming { delta, .. } = event {
print!("{}", delta);
let _ = std::io::stdout().flush();
char_count_clone.fetch_add(delta.len(), Ordering::Relaxed);
}
});
let question = "Tell me a short story about a robot learning to code in Rust.";
println!("\n> {}\n", question);
print!("Assistant: ");
std::io::stdout().flush()?;
let response = agent.run(question).await?;
let total_chars = char_count.load(Ordering::Relaxed);
println!("\n\n{}", "=".repeat(60));
println!("Execution Stats:");
println!(
" Streamed {} characters in {:.2}s ({:.0} chars/sec)",
total_chars,
response.duration.as_secs_f64(),
total_chars as f64 / response.duration.as_secs_f64()
);
println!(" Model calls: {}", response.model_calls);
let usage = agent.get_context_usage();
println!(
" Context: {} messages, ~{} tokens",
usage.total_messages, usage.context_tokens
);
Ok(())
}