use oxide_agent::client::{HttpOllamaClient, OllamaClient};
use oxide_agent::tools::{ToolBuilder, ToolRegistry};
use oxide_agent::types::{ChatRequest, Message, Role};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = HttpOllamaClient::new("http://localhost:11434");
let mut registry = ToolRegistry::new();
let weather_def = ToolBuilder::new("get_weather", "Get the current weather for a city")
.string_param("city", "The city name", true)
.string_param(
"unit",
"Temperature unit: 'celsius' or 'fahrenheit'",
false,
)
.build();
registry.register(weather_def, |args| async move {
let city = args["city"].as_str().unwrap_or("unknown").to_string();
let unit = args["unit"].as_str().unwrap_or("celsius");
Ok(serde_json::json!({
"city": city,
"temperature": 22,
"unit": unit,
"condition": "sunny"
}))
});
let calc_def = ToolBuilder::new("calculate", "Evaluate a basic arithmetic expression")
.number_param("a", "Left operand", true)
.number_param("b", "Right operand", true)
.string_param("op", "Operator: add, sub, mul, div", true)
.build();
registry.register(calc_def, |args| async move {
let a = args["a"].as_f64().unwrap_or(0.0);
let b = args["b"].as_f64().unwrap_or(0.0);
let result = match args["op"].as_str().unwrap_or("add") {
"sub" => a - b,
"mul" => a * b,
"div" if b != 0.0 => a / b,
_ => a + b,
};
Ok(serde_json::json!({ "result": result }))
});
let mut messages = vec![Message {
role: Role::User,
content: "What's the weather in Berlin and what is 42 times 7?".into(),
tool_calls: None,
}];
let req = ChatRequest {
model: "llama3".into(),
messages: messages.clone(),
tools: Some(registry.definitions()),
stream: false,
};
let resp = client.chat(req).await?;
messages.push(resp.message.clone());
if let Some(calls) = &resp.message.tool_calls {
for call in calls {
println!("Model called tool: {}", call.function.name);
let result = registry
.dispatch(&call.function.name, call.function.arguments.clone())
.await?;
println!("Tool result: {result}");
messages.push(Message {
role: Role::Tool,
content: result.to_string(),
tool_calls: None,
});
}
let follow_up = ChatRequest {
model: "llama3".into(),
messages: messages.clone(),
tools: Some(registry.definitions()),
stream: false,
};
let final_resp = client.chat(follow_up).await?;
println!("\nFinal answer: {}", final_resp.message.content);
} else {
println!("Direct answer: {}", resp.message.content);
}
Ok(())
}