use mixtape_core::{Agent, ClaudeHaiku4_5, SimpleConversationManager, Tool, ToolError, ToolResult};
use schemars::JsonSchema;
use serde::Deserialize;
use std::time::Duration;
#[derive(Debug, Deserialize, JsonSchema)]
struct SlowInput {
name: String,
duration_ms: u64,
}
struct SlowTool;
impl Tool for SlowTool {
type Input = SlowInput;
fn name(&self) -> &str {
"slow_task"
}
fn description(&self) -> &str {
"Simulate a slow task by sleeping for a specified duration"
}
async fn execute(&self, input: Self::Input) -> Result<ToolResult, ToolError> {
println!(
"[{}] Starting (expected: {}ms)",
input.name, input.duration_ms
);
let start = std::time::Instant::now();
tokio::time::sleep(Duration::from_millis(input.duration_ms)).await;
let actual = start.elapsed().as_millis();
println!("[{}] Completed (actual: {}ms)", input.name, actual);
Ok(format!(
"Task '{}' completed (expected: {}ms, actual: {}ms)",
input.name, input.duration_ms, actual
)
.into())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Parallel Tool Execution Demo (Anthropic) ===\n");
println!("Watch the timestamps to see parallel execution!\n");
let agent = Agent::builder()
.anthropic_from_env(ClaudeHaiku4_5)
.with_system_prompt("You are a helpful assistant that can run slow tasks in parallel.")
.with_conversation_manager(SimpleConversationManager::new(10)) .with_max_concurrent_tools(12)
.add_trusted_tool(SlowTool)
.build()
.await?;
let response = agent
.run(
"Please run 5 slow tasks in parallel with these durations: \
Task A (1000ms), Task B (2000ms), Task C (3000ms), Task D (5000ms), Task E (5000ms). \
If sequential: 16000ms total. If parallel: ~5000ms (longest task).",
)
.await?;
println!("\n=== Agent Response ===\n{}", response.text);
println!("\n=== Execution Stats ===");
println!(" Total duration: {:.2}s", response.duration.as_secs_f64());
println!(" Model calls: {}", response.model_calls);
println!(" Tool calls: {}", response.tool_calls.len());
for tc in &response.tool_calls {
println!(
" - {} ({:.2}s) {}",
tc.name,
tc.duration.as_secs_f64(),
if tc.success { "✓" } else { "✗" }
);
}
if let Some(usage) = &response.token_usage {
println!(
" Tokens: {} input, {} output, {} total",
usage.input_tokens,
usage.output_tokens,
usage.total()
);
}
let usage = agent.get_context_usage();
println!("\n=== Context Stats ===");
println!(" Messages in history: {}", usage.total_messages);
println!(" Messages in context: {}", usage.context_messages);
println!(" (SimpleConversationManager keeps last 10, truncating older messages)");
let expected_sequential = 16.0;
let actual = response.duration.as_secs_f64();
if actual < expected_sequential * 0.6 {
println!(
"\n Parallel execution saved ~{:.1}s vs sequential!",
expected_sequential - actual
);
}
Ok(())
}