use claude_api::Client;
use claude_api::conversation::Conversation;
use claude_api::derive::Tool;
use claude_api::messages::{ContentBlock, KnownBlock};
use claude_api::tool_dispatch::{RunOptions, ToolError, ToolRegistry};
use claude_api::types::ModelId;
use schemars::JsonSchema;
use serde::Deserialize;
use serde_json::{Value, json};
#[derive(Deserialize, JsonSchema, Tool)]
struct GetWeather {
city: String,
}
impl GetWeather {
#[allow(clippy::unused_async)]
async fn run(self) -> Result<Value, ToolError> {
Ok(json!({"temp_f": 72, "city": self.city, "summary": "clear"}))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("ANTHROPIC_API_KEY")
.map_err(|_| "ANTHROPIC_API_KEY must be set in the environment")?;
let client = Client::new(api_key);
let mut registry = ToolRegistry::new();
registry.register_tool(GetWeather::tool());
let mut convo = Conversation::new(ModelId::SONNET_4_6, 1024);
convo.push_user("What's the weather in San Francisco?");
let final_msg = client
.run(
&mut convo,
®istry,
RunOptions::default().max_iterations(8),
)
.await?;
for block in &final_msg.content {
if let ContentBlock::Known(KnownBlock::Text { text, .. }) = block {
println!("{text}");
}
}
Ok(())
}