function_call_role/
function_call_role.rs1use 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