function_call_role/
function_call_role.rs

1use openai_api_rs::v1::api::OpenAIClient;
2use openai_api_rs::v1::chat_completion::chat_completion::ChatCompletionRequest;
3use openai_api_rs::v1::chat_completion::{self};
4use openai_api_rs::v1::common::GPT4_O;
5use openai_api_rs::v1::types;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::{env, vec};
9
10fn get_coin_price(coin: &str) -> f64 {
11    let coin = coin.to_lowercase();
12    match coin.as_str() {
13        "btc" | "bitcoin" => 10000.0,
14        "eth" | "ethereum" => 1000.0,
15        _ => 0.0,
16    }
17}
18
19#[tokio::main]
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21    let api_key = env::var("OPENAI_API_KEY").unwrap().to_string();
22    let mut client = OpenAIClient::builder().with_api_key(api_key).build()?;
23
24    let mut properties = HashMap::new();
25    properties.insert(
26        "coin".to_string(),
27        Box::new(types::JSONSchemaDefine {
28            schema_type: Some(types::JSONSchemaType::String),
29            description: Some("The cryptocurrency to get the price of".to_string()),
30            ..Default::default()
31        }),
32    );
33
34    let req = ChatCompletionRequest::new(
35        GPT4_O.to_string(),
36        vec![chat_completion::ChatCompletionMessage {
37            role: chat_completion::MessageRole::user,
38            content: chat_completion::Content::Text(String::from("What is the price of Ethereum?")),
39            name: None,
40            tool_calls: None,
41            tool_call_id: None,
42        }],
43    )
44    .tools(vec![chat_completion::Tool {
45        r#type: chat_completion::ToolType::Function,
46        function: types::Function {
47            name: String::from("get_coin_price"),
48            description: Some(String::from("Get the price of a cryptocurrency")),
49            parameters: types::FunctionParameters {
50                schema_type: types::JSONSchemaType::Object,
51                properties: Some(properties),
52                required: Some(vec![String::from("coin")]),
53            },
54        },
55    }]);
56
57    let result = client.chat_completion(req).await?;
58
59    match result.choices[0].finish_reason {
60        None => {
61            println!("No finish_reason");
62            println!("{:?}", result.choices[0].message.content);
63        }
64        Some(chat_completion::FinishReason::stop) => {
65            println!("Stop");
66            println!("{:?}", result.choices[0].message.content);
67        }
68        Some(chat_completion::FinishReason::length) => {
69            println!("Length");
70        }
71        Some(chat_completion::FinishReason::tool_calls) => {
72            println!("ToolCalls");
73            #[derive(Deserialize, Serialize)]
74            struct Currency {
75                coin: String,
76            }
77            let tool_calls = result.choices[0].message.tool_calls.as_ref().unwrap();
78            for tool_call in tool_calls {
79                let function_call = &tool_call.function;
80                let arguments = function_call.arguments.clone().unwrap();
81                let c: Currency = serde_json::from_str(&arguments)?;
82                let coin = c.coin;
83                println!("coin: {coin}");
84                let price = get_coin_price(&coin);
85                println!("price: {price}");
86
87                let req = ChatCompletionRequest::new(
88                    GPT4_O.to_string(),
89                    vec![
90                        chat_completion::ChatCompletionMessage {
91                            role: chat_completion::MessageRole::user,
92                            content: chat_completion::Content::Text(String::from(
93                                "What is the price of Ethereum?",
94                            )),
95                            name: None,
96                            tool_calls: None,
97                            tool_call_id: None,
98                        },
99                        chat_completion::ChatCompletionMessage {
100                            role: chat_completion::MessageRole::function,
101                            content: chat_completion::Content::Text({
102                                let price = get_coin_price(&coin);
103                                format!("{{\"price\": {price}}}")
104                            }),
105                            name: Some(String::from("get_coin_price")),
106                            tool_calls: None,
107                            tool_call_id: None,
108                        },
109                    ],
110                );
111
112                let result = client.chat_completion(req).await?;
113                println!("{:?}", result.choices[0].message.content);
114            }
115        }
116        Some(chat_completion::FinishReason::content_filter) => {
117            println!("ContentFilter");
118        }
119        Some(chat_completion::FinishReason::null) => {
120            println!("Null");
121        }
122    }
123    Ok(())
124}
125
126// OPENAI_API_KEY=xxxx cargo run --package openai-api-rs --example function_call_role