openai_tools/embedding/mod.rs
1//! # Embedding Module
2//!
3//! This module provides functionality for interacting with the OpenAI Embeddings API.
4//! It allows you to convert text into numerical vector representations (embeddings)
5//! that capture semantic meaning, enabling various NLP tasks such as semantic search,
6//! clustering, and similarity comparison.
7//!
8//! ## Key Features
9//!
10//! - **Text Embedding Generation**: Convert single or multiple texts into vector embeddings
11//! - **Multiple Input Formats**: Support for single text strings or arrays of texts
12//! - **Flexible Encoding**: Support for both `float` and `base64` encoding formats
13//! - **Various Model Support**: Compatible with OpenAI's embedding models (e.g., `text-embedding-3-small`, `text-embedding-3-large`)
14//! - **Multi-dimensional Output**: Support for 1D, 2D, and 3D embedding vectors
15//!
16//! ## Quick Start
17//!
18//! ```rust,no_run
19//! use openai_tools::embedding::request::Embedding;
20//! use openai_tools::common::models::EmbeddingModel;
21//!
22//! #[tokio::main]
23//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
24//! // Initialize the embedding client
25//! let mut embedding = Embedding::new()?;
26//!
27//! // Configure the model and input text
28//! embedding
29//! .model(EmbeddingModel::TextEmbedding3Small)
30//! .input_text("Hello, world!");
31//!
32//! // Generate embedding
33//! let response = embedding.embed().await?;
34//!
35//! // Access the embedding vector
36//! let vector = response.data[0].embedding.as_1d().unwrap();
37//! println!("Embedding dimension: {}", vector.len());
38//! Ok(())
39//! }
40//! ```
41//!
42//! ## Usage Examples
43//!
44//! ### Single Text Embedding
45//!
46//! ```rust,no_run
47//! use openai_tools::embedding::request::Embedding;
48//! use openai_tools::common::models::EmbeddingModel;
49//!
50//! #[tokio::main]
51//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
52//! let mut embedding = Embedding::new()?;
53//!
54//! embedding
55//! .model(EmbeddingModel::TextEmbedding3Small)
56//! .input_text("The quick brown fox jumps over the lazy dog.");
57//!
58//! let response = embedding.embed().await?;
59//!
60//! // The response contains embedding data
61//! assert_eq!(response.object, "list");
62//! assert_eq!(response.data.len(), 1);
63//!
64//! let vector = response.data[0].embedding.as_1d().unwrap();
65//! println!("Generated embedding with {} dimensions", vector.len());
66//! Ok(())
67//! }
68//! ```
69//!
70//! ### Batch Text Embedding
71//!
72//! ```rust,no_run
73//! use openai_tools::embedding::request::Embedding;
74//! use openai_tools::common::models::EmbeddingModel;
75//!
76//! #[tokio::main]
77//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
78//! let mut embedding = Embedding::new()?;
79//!
80//! // Embed multiple texts at once
81//! let texts = vec![
82//! "Hello, world!",
83//! "こんにちは,世界!",
84//! "Bonjour le monde!",
85//! ];
86//!
87//! embedding
88//! .model(EmbeddingModel::TextEmbedding3Small)
89//! .input_text_array(texts);
90//!
91//! let response = embedding.embed().await?;
92//!
93//! // Each input text gets its own embedding
94//! for (i, data) in response.data.iter().enumerate() {
95//! let vector = data.embedding.as_1d().unwrap();
96//! println!("Text {}: {} dimensions", i, vector.len());
97//! }
98//! Ok(())
99//! }
100//! ```
101//!
102//! ### Using Different Encoding Formats
103//!
104//! ```rust,no_run
105//! use openai_tools::embedding::request::Embedding;
106//! use openai_tools::common::models::EmbeddingModel;
107//!
108//! #[tokio::main]
109//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
110//! let mut embedding = Embedding::new()?;
111//!
112//! embedding
113//! .model(EmbeddingModel::TextEmbedding3Small)
114//! .input_text("Sample text for embedding")
115//! .encoding_format("float"); // or "base64"
116//!
117//! let response = embedding.embed().await?;
118//! println!("Model used: {}", response.model);
119//! println!("Token usage: {:?}", response.usage);
120//! Ok(())
121//! }
122//! ```
123//!
124//! ## Supported Models
125//!
126//! | Model | Dimensions | Description |
127//! |-------|------------|-------------|
128//! | `text-embedding-3-small` | 1536 | Efficient model for most use cases |
129//! | `text-embedding-3-large` | 3072 | Higher quality embeddings for demanding tasks |
130//! | `text-embedding-ada-002` | 1536 | Legacy model (still supported) |
131//!
132//! ## Response Structure
133//!
134//! The embedding response contains:
135//! - `object`: Always "list" for embedding responses
136//! - `data`: Array of embedding objects, each containing:
137//! - `object`: Type identifier ("embedding")
138//! - `embedding`: The vector representation (1D, 2D, or 3D)
139//! - `index`: Position in the input array
140//! - `model`: The model used for embedding
141//! - `usage`: Token usage information
142
143pub mod request;
144pub mod response;
145
146#[cfg(test)]
147mod tests {
148 use crate::common::models::EmbeddingModel;
149 use crate::embedding::request::Embedding;
150
151 #[test]
152 fn test_embedding_builder_model() {
153 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
154 embedding.model(EmbeddingModel::TextEmbedding3Small);
155 // Model is set internally, we can verify by serialization
156 }
157
158 #[test]
159 fn test_embedding_builder_input_text() {
160 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
161 embedding.input_text("Hello, world!");
162 // Input is set internally
163 }
164
165 #[test]
166 fn test_embedding_builder_input_text_array() {
167 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
168 let texts = vec!["Text 1", "Text 2", "Text 3"];
169 embedding.input_text_array(texts);
170 // Input array is set internally
171 }
172
173 #[test]
174 fn test_embedding_builder_encoding_format_float() {
175 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
176 embedding.encoding_format("float");
177 // Encoding format is set internally
178 }
179
180 #[test]
181 fn test_embedding_builder_encoding_format_base64() {
182 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
183 embedding.encoding_format("base64");
184 // Encoding format is set internally
185 }
186
187 #[test]
188 #[should_panic(expected = "encoding_format must be either 'float' or 'base64'")]
189 fn test_embedding_builder_encoding_format_invalid() {
190 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
191 embedding.encoding_format("invalid"); // Should panic
192 }
193
194 #[test]
195 fn test_embedding_builder_chain() {
196 let mut embedding = Embedding::new().expect("Embedding initialization should succeed");
197 embedding.model(EmbeddingModel::TextEmbedding3Small).input_text("Hello!").encoding_format("float");
198 // Method chaining works
199 }
200}