1use anyhow::{anyhow, Result};
2use schemars::JsonSchema;
3use serde::Deserialize;
4use serde::Serialize;
5use std::ffi::OsStr;
6use std::path::Path;
7
8use allms::{
9 assistants::OpenAIVectorStore,
10 files::OpenAIFile,
11 llm::{
12 tools::{
13 LLMTools, OpenAICodeInterpreterConfig, OpenAIFileSearchConfig, OpenAIReasoningConfig,
14 OpenAIWebSearchConfig,
15 },
16 OpenAIModels,
17 },
18 Completions,
19};
20
21#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
23struct TranslationResponse {
24 pub spanish: String,
25 pub french: String,
26 pub german: String,
27 pub polish: String,
28}
29
30#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
32struct AINewsArticles {
33 pub articles: Vec<AINewsArticle>,
34}
35
36#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
37struct AINewsArticle {
38 pub title: String,
39 pub url: String,
40 pub description: String,
41}
42
43#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema)]
45pub struct ConcertInfo {
46 dates: Vec<String>,
47 band: String,
48 genre: String,
49 venue: String,
50 city: String,
51 country: String,
52 ticket_price: String,
53}
54
55const BANDS_GENRES: &[(&str, &str)] = &[
56 ("Metallica", "Metal"),
57 ("The Beatles", "Rock"),
58 ("Daft Punk", "Electronic"),
59 ("Miles Davis", "Jazz"),
60 ("Johnny Cash", "Country"),
61];
62
63#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema)]
65pub struct CodeInterpreterResponse {
66 pub problem: String,
67 pub code: String,
68 pub output: String,
69}
70
71#[tokio::main]
72async fn main() -> Result<()> {
73 env_logger::init();
74
75 let instructions =
77 "Translate the following English sentence to all the languages in the response type: Rust is best for working with LLMs";
78
79 let openai_api_key: String = std::env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set");
80
81 let reasoning_tool = LLMTools::OpenAIReasoning(OpenAIReasoningConfig::default());
82
83 let openai_responses = Completions::new(OpenAIModels::Gpt5_4Mini, &openai_api_key, None, None)
84 .version("openai_responses")
85 .add_tool(reasoning_tool);
86
87 match openai_responses
88 .get_answer::<TranslationResponse>(instructions)
89 .await
90 {
91 Ok(response) => println!("Translations:\n{:#?}", response),
92 Err(e) => eprintln!("Error: {:?}", e),
93 }
94
95 let web_search_tool = LLMTools::OpenAIWebSearch(OpenAIWebSearchConfig::new());
97 let openai_responses = Completions::new(OpenAIModels::Gpt5_4Nano, &openai_api_key, None, None)
98 .version("openai_responses")
99 .add_tool(web_search_tool);
100
101 match openai_responses
102 .get_answer::<AINewsArticles>("Find up to 5 most recent news items about Artificial Intelligence, Generative AI, and Large Language Models.
103 For each news item, provide the title, url, and a short description.")
104 .await
105 {
106 Ok(response) => println!("AI news articles:\n{:#?}", response),
107 Err(e) => eprintln!("Error: {:?}", e),
108 }
109
110 let path = Path::new("metallica.pdf");
114 let bytes = std::fs::read(path)?;
115 let file_name = path
116 .file_name()
117 .and_then(OsStr::to_str)
118 .map(|s| s.to_string())
119 .ok_or_else(|| anyhow!("Failed to extract file name"))?;
120 let openai_file = OpenAIFile::new(None, &openai_api_key)
121 .upload(&file_name, bytes)
122 .await?;
123 let openai_vector_store = OpenAIVectorStore::new(None, "Concerts", &openai_api_key)
124 .upload(&[openai_file.id.clone().unwrap_or_default()])
125 .await?;
126
127 let file_search_tool =
129 LLMTools::OpenAIFileSearch(OpenAIFileSearchConfig::new(vec![openai_vector_store
130 .id
131 .clone()
132 .unwrap_or_default()]));
133
134 let openai_responses = Completions::new(OpenAIModels::Gpt5_4Mini, &openai_api_key, None, None)
135 .version("openai_responses")
136 .set_context("bands_genres", &BANDS_GENRES)?
137 .add_tool(file_search_tool);
138
139 match openai_responses
140 .get_answer::<ConcertInfo>("Extract the information requested in the response type from the attached concert information.
141 The response should include the genre of the music the 'band' represents.
142 The mapping of bands to genres was provided in 'bands_genres' list.")
143 .await
144 {
145 Ok(response) => println!("Concert Info:\n{:#?}", response),
146 Err(e) => eprintln!("Error: {:?}", e),
147 }
148
149 openai_file.delete().await?;
151 openai_vector_store.delete().await?;
152
153 let code_interpreter_tool = LLMTools::OpenAICodeInterpreter(OpenAICodeInterpreterConfig::new());
156 let openai_responses = Completions::new(OpenAIModels::Gpt5_4Nano, &openai_api_key, None, None)
157 .version("openai_responses")
158 .set_context("Code Interpreter", &"You are a personal math tutor. When asked a math question, write and run code to answer the question.".to_string())?
159 .add_tool(code_interpreter_tool);
160
161 match openai_responses
162 .get_answer::<CodeInterpreterResponse>(
163 "I need to solve the equation 3x + 11 = 14. Can you help me?",
164 )
165 .await
166 {
167 Ok(response) => println!("Code interpreter response:\n{:#?}", response),
168 Err(e) => eprintln!("Error: {:?}", e),
169 }
170
171 Ok(())
172}