open_ai_rust 0.2.12

Open AI SDK for Rust. To my knowledge, the only fully comprehensive and up-to-date Open AI crate built in and for Rust. Provides both low-level control with high level ergonomics for doing cool things (the whole reason we use Rust in the first place). Is maintained and has been used and tested in products used in production.
Documentation

// WARNING:
// KEEP IN MIND TESTS SOMETIMES CAN RANDOMLY FAIL EVEN THOUGH SAME SEED AND 0 TEMP
// IF A TEST USING THE FUNCTION CALL DOES FAIL TRY RUNNING IT AGAIN BEFORE DEBUGGING
#[cfg(test)]
mod tests {
    use open_ai_rust::{logoi::{input::{payload::builder::PayLoadBuilder, tool::{EnumValues, FunctionCall, FunctionParameter, FunctionType}}, message::{ChatMessage, ChatMessageRole}, models::OpenAiModel}, requests::open_ai_msg, set_key};

    #[tokio::test]
    async fn can_do_function_call_simple() {
        dotenv::dotenv().ok();
        set_key(std::env::var("OPENAI_SK").unwrap()); // Set the OpenAI API key from the environment variable

        let system_msg = ChatMessage {
            role: ChatMessageRole::System,
            content: "You are part of a test in a Rust program. Follow the user's request to complete the function/tool call.".to_string(),
            name: None
        };

        let user_msg = ChatMessage {
            role: ChatMessageRole::User,
            content: "Turn on light!".to_string(),
            name: None
        };

        let functions = vec![
            FunctionCall {
                name: "change_light".to_string(),
                description: Some("Change the light in the room.".to_string()),
                parameters: vec![
                    FunctionParameter {
                        name: "turn_on_light".to_string(),
                        _type: FunctionType::Boolean,
                        description: Some("True turns on the light and false turns it off".to_string()),
                    }
                ],
            }
        ];

        let payload = PayLoadBuilder::new(OpenAiModel::GPT4o)
            .messages(vec![system_msg, user_msg])
            .tools(functions)
            .seed(0)
            .build();

        let response = open_ai_msg(payload).await.unwrap();
        let tool_calls = response.get_tool_calls();
        assert_eq!(tool_calls.len(), 1);
        let tool_call = &tool_calls[0];
        assert_eq!(tool_call.name, "change_light");
        let arguments = tool_call.arguments.as_object().unwrap();
        assert_eq!(arguments.get("turn_on_light").unwrap().as_bool().unwrap(), true);
    }

    #[tokio::test]
    async fn can_do_weather_function_call_including_enums_and_strings_multiple_calls_and_params() {
        dotenv::dotenv().ok();
        set_key(std::env::var("OPENAI_SK").unwrap()); // Set the OpenAI API key from the environment variable

        let system_msg = ChatMessage {
            role: ChatMessageRole::System,
            content: "You are a weather bot. Use the provided functions to answer questions. If calling both functions make sure to do them in order of rain probability first.".to_string(),
            name: None
        };

        let user_msg = ChatMessage {
            role: ChatMessageRole::User,
            content: "What's the weather in San Francisco today and the likelihood it'll rain?".to_string(),
            name: None
        };

        let functions = vec![
            FunctionCall {
                name: "get_current_temperature".to_string(),
                description: Some("Get the current temperature for a specific location".to_string()),
                parameters: vec![
                    FunctionParameter {
                        name: "location".to_string(),
                        _type: FunctionType::String,
                        description: Some("The city and state, e.g., San Francisco, CA".to_string()),
                    },
                    FunctionParameter {
                        name: "unit".to_string(),
                        _type: FunctionType::Enum(EnumValues::String(vec!["Fahrenheight".to_string(), "Celcius".to_string()])),
                        description: Some("The temperature unit to use. Infer this from the user's location.".to_string()),
                    }
                ],
            },
            FunctionCall {
                name: "get_rain_probability".to_string(),
                description: Some("Get the probability of rain for a specific location".to_string()),
                parameters: vec![
                    FunctionParameter {
                        name: "location".to_string(),
                        _type: FunctionType::String,
                        description: Some("The city and state, e.g., San Francisco, CA".to_string()),
                    }
                ],
            }
        ];

        let payload = PayLoadBuilder::new(OpenAiModel::GPT4o)
            .messages(vec![system_msg, user_msg])
            .tools(functions)
            .temperature(0.0)
            .seed(0)
            .build();

        let response = open_ai_msg(payload).await.unwrap();
        let tool_calls = response.get_tool_calls();
        assert_eq!(tool_calls.len(), 2);

        // Check the first tool call
        let tool_call_1 = &tool_calls[0];
        assert_eq!(tool_call_1.name, "get_rain_probability");
        let arguments_1 = tool_call_1.arguments.as_object().unwrap();
        assert_eq!(arguments_1.get("location").unwrap().as_str().unwrap(), "San Francisco, CA");

        // Check the second tool call
        let tool_call_2 = &tool_calls[1];
        assert_eq!(tool_call_2.name, "get_current_temperature");
        let arguments_2 = tool_call_2.arguments.as_object().unwrap();
        assert_eq!(arguments_2.get("location").unwrap().as_str().unwrap(), "San Francisco, CA");
        assert_eq!(arguments_2.get("unit").unwrap().as_str().unwrap(), "Fahrenheight");
    }
}