plainllm 1.2.0

A plain & simple LLM client
Documentation
use serde::{Deserialize, Serialize};

mod utils;
use plainllm::client::tool_registry::FunctionTool;
use plainllm::client::ToolRegistry;
use plainllm::client::{self, extract_answer};

/// Fetches the current weather for a given location using the wttr.in API
pub async fn get_weather(location: &str) -> String {
    // Format the URL with the encoded location parameter
    // Using format=3 to get a simple one-line output
    let url = format!("https://wttr.in/{}?format=3", location);

    // Send the request and get the response
    let response = reqwest::get(&url).await;

    if response.is_err() {
        return format!("Failed to get weather: HTTP {:#?}", response.unwrap_err());
    }

    let res = response.unwrap();

    // Check if the request was successful
    if res.status().is_success() {
        // Get the response body as text
        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();

    //// Setting up availabe tools

    // Define parameter struct for add_numbers
    #[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(&params.location).await },
        Some(|p: &GetWeatherParams| println!("Calling tool get_weather with {:?}", p)),
        Some(|_p: &GetWeatherParams, res: &String| {
            println!("Received response from tool call: {}", res)
        }),
    );

    //// Using tools with call_llm_with_tools
    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(),
        &registry,
        None,
        None,
    )
    .await?;

    println!("Final Answer:\n{}", extract_answer(response));

    println!("{:#?}", new_messages);

    Ok(())
}