function_call_role/
function_call_role.rs

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