use open_agent::{
AgentOptions, Client, ContentBlock, estimate_tokens, is_approaching_limit, truncate_messages,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", "=".repeat(70));
println!("CONTEXT MANAGEMENT EXAMPLES");
println!("{}", "=".repeat(70));
println!();
pattern_1_stateless().await?;
pattern_2_manual_truncation().await?;
pattern_3_token_monitoring().await?;
Ok(())
}
async fn pattern_1_stateless() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Pattern 1: Stateless Agents ===");
println!("Best for: Single-task agents with no context needed");
println!();
let options = AgentOptions::builder()
.model("qwen3:8b")
.base_url("http://localhost:11434/v1")
.system_prompt("You are a helpful assistant")
.build()?;
let tasks = vec!["Explain Rust", "Explain Python", "Explain JavaScript"];
for task in tasks {
let mut client = Client::new(options.clone())?;
client.send(task).await?;
let mut response = String::new();
while let Some(block) = client.receive().await? {
if let ContentBlock::Text(text) = block {
response.push_str(&text.text);
}
}
println!("Task: {}", task);
println!("Response length: {} chars", response.len());
println!("History size: {} messages", client.history().len());
println!("Estimated tokens: {}", estimate_tokens(client.history()));
println!();
}
println!("{}", "-".repeat(70));
println!();
Ok(())
}
async fn pattern_2_manual_truncation() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Pattern 2: Manual Truncation ===");
println!("Best for: Multi-turn conversations with task boundaries");
println!();
let options = AgentOptions::builder()
.model("qwen3:8b")
.base_url("http://localhost:11434/v1")
.system_prompt("You are a helpful coding assistant")
.max_turns(10)
.build()?;
let mut client = Client::new(options)?;
println!("Task 1: Adding messages to history...");
client
.send("Analyze this: def add(a, b): return a + b")
.await?;
while client.receive().await?.is_some() {
}
println!("After task 1: {} messages", client.history().len());
println!("\nTask 2: Adding more messages...");
client.send("Write unit tests for the add function").await?;
while client.receive().await?.is_some() {
}
println!("After task 2: {} messages", client.history().len());
println!("\nTruncating history (keeping last 3 messages)...");
let truncated = truncate_messages(client.history(), 3, true);
*client.history_mut() = truncated;
println!("After truncation: {} messages", client.history().len());
println!();
println!("{}", "-".repeat(70));
println!();
Ok(())
}
async fn pattern_3_token_monitoring() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Pattern 3: Token Budget Monitoring ===");
println!("Best for: Long-running conversations with token limits");
println!();
let options = AgentOptions::builder()
.model("qwen3:8b")
.base_url("http://localhost:11434/v1")
.system_prompt("You are a helpful assistant")
.build()?;
let mut client = Client::new(options)?;
let interactions = [
"What is Rust?",
"Explain ownership",
"What are lifetimes?",
"How do traits work?",
"Explain async/await",
];
let token_limit = 1000; let margin = 0.8;
for (i, prompt) in interactions.iter().enumerate() {
println!("Interaction {}: {}", i + 1, prompt);
let current_tokens = estimate_tokens(client.history());
println!(" Current tokens: {}", current_tokens);
if is_approaching_limit(client.history(), token_limit, margin) {
println!(" ⚠️ Approaching token limit! Truncating...");
let truncated = truncate_messages(client.history(), 3, true);
*client.history_mut() = truncated;
println!(
" After truncation: {} tokens",
estimate_tokens(client.history())
);
}
client.send(prompt).await?;
println!();
}
println!("Final history size: {} messages", client.history().len());
println!("Final token count: {}", estimate_tokens(client.history()));
println!();
println!("{}", "-".repeat(70));
println!();
Ok(())
}