Skip to main content

use_openai_responses/
use_openai_responses.rs

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// Example 1: Basic translation example using reasoning model
22#[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// Example 2: Web search
31#[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// Example 3: File search
44#[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// Example 4: Code interpreter example
64#[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    // Example 1: Basic translation example using reasoning model
76    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    // Example 2: Web search example
96    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    // Example 3: File search example
111
112    // Read the concert file and upload it to OpenAI
113    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    // Extract concert information using Responses API with file search tool
128    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    // Cleanup
150    openai_file.delete().await?;
151    openai_vector_store.delete().await?;
152
153    // Example 4: Code interpreter example
154
155    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}