openai_tools/lib.rs
1//! # OpenAI Tools for Rust
2//!
3//! A comprehensive Rust library for interacting with OpenAI's APIs, providing easy-to-use
4//! interfaces for chat completions, responses, and various AI-powered functionalities.
5//! This crate offers both high-level convenience methods and low-level control for
6//! advanced use cases.
7//!
8//! ## Features
9//!
10//! ### Core APIs
11//! - **Chat Completions API**: Chat with streaming, function calling, and structured output
12//! - **Responses API**: Assistant-style interactions with multi-modal input
13//! - **Conversations API**: Long-running conversation state management
14//! - **Embedding API**: Text to vector embeddings for semantic search
15//! - **Realtime API**: WebSocket-based real-time audio/text streaming
16//!
17//! ### Content & Media APIs
18//! - **Images API**: DALL-E image generation, editing, and variations
19//! - **Audio API**: Text-to-speech, transcription, and translation
20//! - **Moderations API**: Content policy violation detection
21//!
22//! ### Management APIs
23//! - **Models API**: List and retrieve available models
24//! - **Files API**: Upload and manage files for fine-tuning/batch
25//! - **Batch API**: Async bulk processing with 50% cost savings
26//! - **Fine-tuning API**: Custom model training
27//!
28//! ## Quick Start
29//!
30//! Add this to your `Cargo.toml`:
31//!
32//! ```toml
33//! [dependencies]
34//! openai-tools = "1.0"
35//! tokio = { version = "1.0", features = ["full"] }
36//! serde = { version = "1.0", features = ["derive"] }
37//! ```
38//!
39//! Set up your API key:
40//!
41//! ```bash
42//! export OPENAI_API_KEY="your-api-key-here"
43//! ```
44//!
45//! ## Basic Chat Completion
46//!
47//! ```rust,no_run
48//! use openai_tools::chat::request::ChatCompletion;
49//! use openai_tools::common::message::Message;
50//! use openai_tools::common::role::Role;
51//! use openai_tools::common::models::ChatModel;
52//!
53//! #[tokio::main]
54//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
55//! let mut chat = ChatCompletion::new();
56//! let messages = vec![
57//! Message::from_string(Role::User, "Hello! How are you?")
58//! ];
59//!
60//! let response = chat
61//! .model(ChatModel::Gpt4oMini) // Type-safe model selection
62//! .messages(messages)
63//! .temperature(0.7)
64//! .chat()
65//! .await?;
66//!
67//! println!("AI: {}", response.choices[0].message.content.as_ref().unwrap().text.as_ref().unwrap());
68//! Ok(())
69//! }
70//! ```
71//!
72//! ## Structured Output with JSON Schema
73//!
74//! ```rust,no_run
75//! use openai_tools::chat::request::ChatCompletion;
76//! use openai_tools::common::{message::Message, role::Role, structured_output::Schema, models::ChatModel};
77//! use serde::{Deserialize, Serialize};
78//!
79//! #[derive(Debug, Serialize, Deserialize)]
80//! struct PersonInfo {
81//! name: String,
82//! age: u32,
83//! occupation: String,
84//! }
85//!
86//! #[tokio::main]
87//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
88//! let mut chat = ChatCompletion::new();
89//!
90//! // Create JSON schema
91//! let mut schema = Schema::chat_json_schema("person_info");
92//! schema.add_property("name", "string", "Person's full name");
93//! schema.add_property("age", "number", "Person's age");
94//! schema.add_property("occupation", "string", "Person's job");
95//!
96//! let messages = vec![
97//! Message::from_string(Role::User,
98//! "Extract info: John Smith, 30, Software Engineer")
99//! ];
100//!
101//! let response = chat
102//! .model(ChatModel::Gpt4oMini)
103//! .messages(messages)
104//! .json_schema(schema)
105//! .chat()
106//! .await?;
107//!
108//! let person: PersonInfo = serde_json::from_str(
109//! response.choices[0].message.content.as_ref().unwrap().text.as_ref().unwrap()
110//! )?;
111//!
112//! println!("Extracted: {} ({}), {}", person.name, person.age, person.occupation);
113//! Ok(())
114//! }
115//! ```
116//!
117//! ## Function Calling with Tools
118//!
119//! ```rust,no_run
120//! use openai_tools::chat::request::ChatCompletion;
121//! use openai_tools::common::{message::Message, role::Role, tool::Tool, parameters::ParameterProperty, models::ChatModel};
122//!
123//! #[tokio::main]
124//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
125//! let mut chat = ChatCompletion::new();
126//!
127//! // Define a weather tool
128//! let weather_tool = Tool::function(
129//! "get_weather",
130//! "Get current weather for a location",
131//! vec![
132//! ("location", ParameterProperty::from_string("City name")),
133//! ("unit", ParameterProperty::from_string("Temperature unit (celsius/fahrenheit)")),
134//! ],
135//! false,
136//! );
137//!
138//! let messages = vec![
139//! Message::from_string(Role::User, "What's the weather in Tokyo?")
140//! ];
141//!
142//! let response = chat
143//! .model(ChatModel::Gpt4oMini)
144//! .messages(messages)
145//! .tools(vec![weather_tool])
146//! .chat()
147//! .await?;
148//!
149//! // Handle tool calls
150//! if let Some(tool_calls) = &response.choices[0].message.tool_calls {
151//! for call in tool_calls {
152//! println!("Tool: {}", call.function.name);
153//! if let Ok(args) = call.function.arguments_as_map() {
154//! println!("Args: {:?}", args);
155//! }
156//! // Execute the function and continue conversation...
157//! }
158//! }
159//! Ok(())
160//! }
161//! ```
162//!
163//! ## Multi-modal Input (Text + Image)
164//!
165//! Both Chat Completions API and Responses API support multi-modal messages.
166//! The same `Content` and `Message` types work with both APIs - serialization
167//! format differences are handled automatically.
168//!
169//! ### Chat Completions API
170//!
171//! ```rust,no_run
172//! use openai_tools::chat::request::ChatCompletion;
173//! use openai_tools::common::{message::{Message, Content}, role::Role, models::ChatModel};
174//!
175//! #[tokio::main]
176//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
177//! let mut chat = ChatCompletion::new();
178//!
179//! let message = Message::from_message_array(
180//! Role::User,
181//! vec![
182//! Content::from_text("What do you see in this image?"),
183//! Content::from_image_url("https://example.com/image.jpg"),
184//! ],
185//! );
186//!
187//! let response = chat
188//! .model(ChatModel::Gpt4oMini)
189//! .messages(vec![message])
190//! .chat()
191//! .await?;
192//!
193//! println!("AI: {}", response.choices[0].message.content.as_ref().unwrap().text.as_ref().unwrap());
194//! Ok(())
195//! }
196//! ```
197//!
198//! ### Responses API
199//!
200//! ```rust,no_run
201//! use openai_tools::responses::request::Responses;
202//! use openai_tools::common::{message::{Message, Content}, role::Role, models::ChatModel};
203//!
204//! #[tokio::main]
205//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
206//! let mut responses = Responses::new();
207//!
208//! responses
209//! .model(ChatModel::Gpt4oMini)
210//! .instructions("You are an image analysis assistant.");
211//!
212//! let message = Message::from_message_array(
213//! Role::User,
214//! vec![
215//! Content::from_text("What do you see in this image?"),
216//! Content::from_image_file("path/to/image.jpg"),
217//! ],
218//! );
219//!
220//! responses.messages(vec![message]);
221//!
222//! let response = responses.complete().await?;
223//! let text = response.output_text().unwrap();
224//! println!("Response: {}", text);
225//! Ok(())
226//! }
227//! ```
228//!
229//! ## Choosing the Right API
230//!
231//! | Use Case | Recommended API | Module |
232//! |----------|-----------------|--------|
233//! | Simple Q&A, chatbot | Chat Completions | [`chat`] |
234//! | Multi-turn assistant with state | Responses + Conversations | [`responses`], [`conversations`] |
235//! | Real-time voice interaction | Realtime | [`realtime`] |
236//! | Semantic search, similarity | Embeddings | [`embedding`] |
237//! | Image generation (DALL-E) | Images | [`images`] |
238//! | Speech-to-text, TTS | Audio | [`audio`] |
239//! | Content moderation | Moderations | [`moderations`] |
240//! | Bulk processing (50% off) | Batch | [`batch`] |
241//! | Custom model training | Fine-tuning | [`fine_tuning`] |
242//!
243//! ## Module Structure
244//!
245//! ### Core APIs
246//!
247//! - [`chat`] - Chat Completions API (`/v1/chat/completions`)
248//! - [`chat::request`] - `ChatCompletion` builder
249//! - [`chat::response`] - Response types
250//!
251//! - [`responses`] - Responses API (`/v1/responses`)
252//! - [`responses::request`] - `Responses` builder with CRUD operations
253//! - [`responses::response`] - Response types
254//!
255//! - [`conversations`] - Conversations API (`/v1/conversations`)
256//! - [`conversations::request`] - `Conversations` client
257//! - [`conversations::response`] - Conversation and item types
258//!
259//! - [`embedding`] - Embeddings API (`/v1/embeddings`)
260//! - [`embedding::request`] - `Embedding` builder
261//! - [`embedding::response`] - Vector response types
262//!
263//! - [`realtime`] - Realtime API (WebSocket)
264//! - [`RealtimeClient`](realtime::RealtimeClient) and
265//! [`RealtimeSession`](realtime::RealtimeSession)
266//! - [`realtime::events`] - Client/server event types
267//!
268//! ### Content & Media APIs
269//!
270//! - [`images`] - Images API (`/v1/images`)
271//! - Generate, edit, create variations with the GPT Image models
272//!
273//! - [`videos`] - Videos API (`/v1/videos`)
274//! - Generate, poll, download and remix Sora video clips
275//!
276//! - [`audio`] - Audio API (`/v1/audio`)
277//! - Text-to-speech, transcription, translation
278//!
279//! - [`moderations`] - Moderations API (`/v1/moderations`)
280//! - Content policy violation detection
281//!
282//! ### Management APIs
283//!
284//! - [`models`] - Models API (`/v1/models`)
285//! - List and retrieve available models
286//!
287//! - [`files`] - Files API (`/v1/files`)
288//! - Upload/download files for fine-tuning and batch
289//!
290//! - [`batch`] - Batch API (`/v1/batches`)
291//! - Async bulk processing with 50% cost savings
292//!
293//! - [`fine_tuning`] - Fine-tuning API (`/v1/fine_tuning/jobs`)
294//! - Custom model training and management
295//!
296//! ### Shared Utilities
297//!
298//! - [`common`] - Shared types across all APIs
299//! - [`common::models`] - Type-safe model enums (`ChatModel`, `EmbeddingModel`, etc.)
300//! - [`common::message`] - Message and content structures
301//! - [`common::role`] - User roles (User, Assistant, System, Tool)
302//! - [`common::tool`] - Function calling definitions
303//! - [`common::auth`] - Authentication (OpenAI, Azure, custom)
304//! - [`common::errors`] - Error types
305//! - [`common::structured_output`] - JSON schema utilities
306//!
307//! ## Error Handling
308//!
309//! All operations return `Result<T, OpenAIToolError>`:
310//!
311//! ```rust,no_run
312//! use openai_tools::common::errors::OpenAIToolError;
313//! # use openai_tools::chat::request::ChatCompletion;
314//!
315//! # #[tokio::main]
316//! # async fn main() {
317//! # let mut chat = ChatCompletion::new();
318//! match chat.chat().await {
319//! Ok(response) => {
320//! println!("Success: {:?}", response.choices[0].message.content);
321//! },
322//! // Network/HTTP errors (connection failed, timeout, etc.)
323//! Err(OpenAIToolError::RequestError(e)) => {
324//! eprintln!("Network error: {}", e);
325//! },
326//! // JSON parsing errors (unexpected response format)
327//! Err(OpenAIToolError::SerdeJsonError(e)) => {
328//! eprintln!("JSON parse error: {}", e);
329//! },
330//! // WebSocket errors (Realtime API)
331//! Err(OpenAIToolError::WebSocketError(msg)) => {
332//! eprintln!("WebSocket error: {}", msg);
333//! },
334//! // Realtime API specific errors
335//! Err(OpenAIToolError::RealtimeError { code, message }) => {
336//! eprintln!("Realtime error [{}]: {}", code, message);
337//! },
338//! // Other errors
339//! Err(e) => eprintln!("Error: {}", e),
340//! }
341//! # }
342//! ```
343//!
344//! For API errors (rate limits, invalid requests), check the HTTP response status
345//! in `RequestError`.
346//!
347//! ## Provider Configuration
348//!
349//! This library supports multiple providers: OpenAI, Azure OpenAI, and OpenAI-compatible APIs.
350//!
351//! ### OpenAI (Default)
352//!
353//! ```bash
354//! export OPENAI_API_KEY="sk-..."
355//! ```
356//!
357//! ```rust,no_run
358//! use openai_tools::chat::request::ChatCompletion;
359//!
360//! let chat = ChatCompletion::new(); // Uses OPENAI_API_KEY
361//! ```
362//!
363//! ### Azure OpenAI
364//!
365//! ```bash
366//! export AZURE_OPENAI_API_KEY="..."
367//! export AZURE_OPENAI_BASE_URL="https://my-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-08-01-preview"
368//! ```
369//!
370//! ```rust,no_run
371//! use openai_tools::chat::request::ChatCompletion;
372//!
373//! // From environment variables
374//! let chat = ChatCompletion::azure().unwrap();
375//!
376//! // Or with explicit URL
377//! let chat = ChatCompletion::with_url(
378//! "https://my-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-08-01-preview",
379//! "api-key"
380//! );
381//! ```
382//!
383//! ### OpenAI-Compatible APIs (Ollama, vLLM, LocalAI)
384//!
385//! ```rust,no_run
386//! use openai_tools::chat::request::ChatCompletion;
387//!
388//! let chat = ChatCompletion::with_url("http://localhost:11434/v1", "ollama");
389//! ```
390//!
391//! ### Auto-Detect Provider
392//!
393//! ```rust,no_run
394//! use openai_tools::chat::request::ChatCompletion;
395//!
396//! // Uses Azure if AZURE_OPENAI_API_KEY is set, otherwise OpenAI
397//! let chat = ChatCompletion::detect_provider().unwrap();
398//! ```
399//!
400//! ## Type-Safe Model Selection
401//!
402//! All APIs use enum-based model selection for compile-time validation:
403//!
404//! ```rust,no_run
405//! use openai_tools::common::models::{ChatModel, EmbeddingModel, RealtimeModel, FineTuningModel};
406//! use openai_tools::chat::request::ChatCompletion;
407//! use openai_tools::embedding::request::Embedding;
408//!
409//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
410//! // Chat/Responses API
411//! let mut chat = ChatCompletion::new();
412//! chat.model(ChatModel::Gpt4oMini); // Cost-effective
413//! chat.model(ChatModel::Gpt4o); // Most capable
414//! chat.model(ChatModel::O3Mini); // Reasoning model
415//!
416//! // Embedding API
417//! let mut embedding = Embedding::new()?;
418//! embedding.model(EmbeddingModel::TextEmbedding3Small);
419//!
420//! // Custom/fine-tuned models
421//! chat.model(ChatModel::custom("ft:gpt-4o-mini:my-org::abc123"));
422//! # Ok(())
423//! # }
424//! ```
425//!
426
427pub mod audio;
428pub mod batch;
429pub mod chat;
430pub mod common;
431pub mod conversations;
432pub mod embedding;
433pub mod files;
434pub mod fine_tuning;
435pub mod images;
436pub mod models;
437pub mod moderations;
438pub mod realtime;
439pub mod responses;
440pub mod videos;