use serde::{Deserialize, Serialize};
mod utils;
use plainllm::client::tool_registry::FunctionTool;
use plainllm::client::ToolRegistry;
use plainllm::client::{self, extract_answer};
pub async fn get_weather(location: &str) -> String {
let url = format!("https://wttr.in/{}?format=3", location);
let response = reqwest::get(&url).await;
if response.is_err() {
return format!("Failed to get weather: HTTP {:#?}", response.unwrap_err());
}
let res = response.unwrap();
if res.status().is_success() {
let weather_data = res.text().await.expect("No text");
weather_data
} else {
format!("Failed to get weather: HTTP {}", res.status()).into()
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
utils::init_logger();
let args = utils::get_client_args();
#[derive(Serialize, Deserialize, Clone, Debug, schemars::JsonSchema)]
struct GetWeatherParams {
location: String,
}
let mut registry = ToolRegistry::new();
let add_tool = FunctionTool::from_type::<GetWeatherParams>(
"get_weather",
"Gets the current weather for a location",
);
registry.register_with_callbacks(
add_tool,
async |params: GetWeatherParams| -> String { get_weather(¶ms.location).await },
Some(|p: &GetWeatherParams| println!("Calling tool get_weather with {:?}", p)),
Some(|_p: &GetWeatherParams, res: &String| {
println!("Received response from tool call: {}", res)
}),
);
let messages = vec![
client::Message::new(
"system",
r#"You are an helpful assistant with access to some tools."#,
),
client::Message::new("user", "What is the current weather in Vilassar de Mar?"),
];
println!("User:");
println!(
"{}\n",
messages
.get(1)
.unwrap()
.content
.as_ref()
.expect("No content")
);
println!("Generating response...\n");
let (response, new_messages) = client::PlainLLM::call_llm_with_tools(
&args.client,
&args.model,
messages.clone(),
®istry,
None,
None,
)
.await?;
println!("Final Answer:\n{}", extract_answer(response));
println!("{:#?}", new_messages);
Ok(())
}