-> String variant
@@ -60,26 +71,44 @@ macro_rules! impl_from {
}
// From String "family" to Prompt
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(&str, Prompt);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(String, Prompt);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(&String, Prompt);
// From String "family" to StopConfiguration
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(&str, StopConfiguration);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(String, StopConfiguration);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from!(&String, StopConfiguration);
// From String "family" to ModerationInput
+#[cfg(feature = "moderation-types")]
impl_from!(&str, ModerationInput);
+#[cfg(feature = "moderation-types")]
impl_from!(String, ModerationInput);
+#[cfg(feature = "moderation-types")]
impl_from!(&String, ModerationInput);
// From String "family" to EmbeddingInput
+#[cfg(feature = "embedding-types")]
impl_from!(&str, EmbeddingInput);
+#[cfg(feature = "embedding-types")]
impl_from!(String, EmbeddingInput);
+#[cfg(feature = "embedding-types")]
impl_from!(&String, EmbeddingInput);
/// for `impl_default!(Enum)`, implements `Default` for `Enum` as `Enum::String("")` where `Enum` has `String` variant
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "completion-types",
+ feature = "embedding-types",
+ feature = "moderation-types"
+))]
macro_rules! impl_default {
($for_typ:ty) => {
impl Default for $for_typ {
@@ -90,18 +119,13 @@ macro_rules! impl_default {
};
}
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_default!(Prompt);
+#[cfg(feature = "moderation-types")]
impl_default!(ModerationInput);
+#[cfg(feature = "embedding-types")]
impl_default!(EmbeddingInput);
-impl Default for InputSource {
- fn default() -> Self {
- InputSource::Path {
- path: PathBuf::new(),
- }
- }
-}
-
/// for `impl_input!(Struct)` where
/// ```text
/// Struct {
@@ -110,10 +134,15 @@ impl Default for InputSource {
/// ```
/// implements methods `from_bytes` and `from_vec_u8`,
/// and `From` for `P: AsRef`
+#[cfg(any(
+ feature = "audio-types",
+ feature = "file-types",
+ feature = "image-types"
+))]
macro_rules! impl_input {
($for_typ:ty) => {
impl $for_typ {
- pub fn from_bytes(filename: String, bytes: Bytes) -> Self {
+ pub fn from_bytes(filename: String, bytes: bytes::Bytes) -> Self {
Self {
source: InputSource::Bytes { filename, bytes },
}
@@ -126,7 +155,7 @@ macro_rules! impl_input {
}
}
- impl> From for $for_typ {
+ impl> From for $for_typ {
fn from(path: P) -> Self {
let path_buf = path.as_ref().to_path_buf();
Self {
@@ -137,10 +166,18 @@ macro_rules! impl_input {
};
}
+#[cfg(feature = "audio-types")]
impl_input!(AudioInput);
+#[cfg(feature = "file-types")]
impl_input!(FileInput);
+#[cfg(feature = "image-types")]
impl_input!(ImageInput);
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "completion-types",
+ feature = "embedding-types"
+))]
macro_rules! impl_from_for_integer_array {
($from_typ:ty, $to_typ:ty) => {
impl From<[$from_typ; N]> for $to_typ {
@@ -169,9 +206,16 @@ macro_rules! impl_from_for_integer_array {
};
}
+#[cfg(feature = "embedding-types")]
impl_from_for_integer_array!(u32, EmbeddingInput);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from_for_integer_array!(u32, Prompt);
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "completion-types",
+ feature = "embedding-types"
+))]
macro_rules! impl_from_for_array_of_integer_array {
($from_typ:ty, $to_typ:ty) => {
impl From>> for $to_typ {
@@ -266,5 +310,7 @@ macro_rules! impl_from_for_array_of_integer_array {
};
}
+#[cfg(feature = "embedding-types")]
impl_from_for_array_of_integer_array!(u32, EmbeddingInput);
+#[cfg(any(feature = "chat-completion-types", feature = "completion-types"))]
impl_from_for_array_of_integer_array!(u32, Prompt);
diff --git a/async-openai/src/types/input_source.rs b/async-openai/src/types/input_source.rs
new file mode 100644
index 00000000..87cfda67
--- /dev/null
+++ b/async-openai/src/types/input_source.rs
@@ -0,0 +1,22 @@
+#[derive(Debug, Clone, PartialEq)]
+pub enum InputSource {
+ Path {
+ path: std::path::PathBuf,
+ },
+ Bytes {
+ filename: String,
+ bytes: bytes::Bytes,
+ },
+ VecU8 {
+ filename: String,
+ vec: Vec,
+ },
+}
+
+impl Default for InputSource {
+ fn default() -> Self {
+ InputSource::Path {
+ path: std::path::PathBuf::new(),
+ }
+ }
+}
diff --git a/async-openai/src/types/common.rs b/async-openai/src/types/metadata.rs
similarity index 61%
rename from async-openai/src/types/common.rs
rename to async-openai/src/types/metadata.rs
index b8170673..63169da4 100644
--- a/async-openai/src/types/common.rs
+++ b/async-openai/src/types/metadata.rs
@@ -1,22 +1,10 @@
-use std::path::PathBuf;
-
-use bytes::Bytes;
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Clone, PartialEq)]
-pub enum InputSource {
- Path { path: PathBuf },
- Bytes { filename: String, bytes: Bytes },
- VecU8 { filename: String, vec: Vec },
-}
-
/// Set of 16 key-value pairs that can be attached to an object.
/// This can be useful for storing additional information about the
/// object in a structured format, and querying for objects via API
/// or the dashboard. Keys are strings with a maximum length of 64
/// characters. Values are strings with a maximum length of 512
/// characters.
-#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
+#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Default)]
#[serde(transparent)]
pub struct Metadata(serde_json::Value);
diff --git a/async-openai/src/types/mod.rs b/async-openai/src/types/mod.rs
index 3309d519..b30d670a 100644
--- a/async-openai/src/types/mod.rs
+++ b/async-openai/src/types/mod.rs
@@ -1,44 +1,142 @@
//! Types used in OpenAI API requests and responses.
//! These types are created from component schemas in the [OpenAPI spec](https://github.com/openai/openai-openapi)
+#[cfg(feature = "administration-types")]
pub mod admin;
+#[cfg(feature = "assistant-types")]
pub mod assistants;
+#[cfg(feature = "audio-types")]
pub mod audio;
+#[cfg(feature = "batch-types")]
pub mod batches;
+#[cfg(feature = "chat-completion-types")]
pub mod chat;
+#[cfg(feature = "chatkit-types")]
pub mod chatkit;
-mod common;
+#[cfg(feature = "completion-types")]
pub mod completions;
+#[cfg(feature = "container-types")]
pub mod containers;
+#[cfg(feature = "embedding-types")]
pub mod embeddings;
+#[cfg(feature = "eval-types")]
pub mod evals;
+#[cfg(feature = "file-types")]
pub mod files;
+#[cfg(feature = "finetuning-types")]
pub mod finetuning;
+#[cfg(feature = "grader-types")]
pub mod graders;
+#[cfg(feature = "image-types")]
pub mod images;
+#[cfg(any(
+ feature = "audio-types",
+ feature = "file-types",
+ feature = "upload-types",
+ feature = "image-types",
+ feature = "video-types",
+ feature = "container-types",
+ feature = "chat-completion-types",
+ feature = "realtime-types"
+))]
+mod input_source;
+#[cfg(any(feature = "response-types", feature = "realtime-types"))]
pub mod mcp;
+#[cfg(any(
+ feature = "response-types",
+ feature = "audio-types",
+ feature = "video-types",
+ feature = "image-types",
+ feature = "batch-types",
+ feature = "file-types",
+ feature = "upload-types",
+ feature = "vectorstore-types",
+ feature = "container-types",
+ feature = "chat-completion-types",
+ feature = "realtime-types"
+))]
+mod metadata;
+#[cfg(feature = "model-types")]
pub mod models;
+#[cfg(feature = "moderation-types")]
pub mod moderations;
-#[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
-#[cfg(feature = "realtime")]
+#[cfg_attr(docsrs, doc(cfg(feature = "realtime-types")))]
+#[cfg(feature = "realtime-types")]
pub mod realtime;
+#[cfg(feature = "response-types")]
pub mod responses;
+#[cfg(any(
+ feature = "response-types",
+ feature = "video-types",
+ feature = "vectorstore-types",
+ feature = "chat-completion-types",
+ feature = "assistant-types",
+ feature = "batch-types",
+ feature = "audio-types",
+ feature = "realtime-types",
+ feature = "image-types"
+))]
mod shared;
+#[cfg(feature = "upload-types")]
pub mod uploads;
+#[cfg(feature = "vectorstore-types")]
pub mod vectorstores;
+#[cfg(feature = "video-types")]
pub mod videos;
-#[cfg_attr(docsrs, doc(cfg(feature = "webhook")))]
-#[cfg(feature = "webhook")]
+#[cfg_attr(docsrs, doc(cfg(feature = "webhook-types")))]
+#[cfg(feature = "webhook-types")]
pub mod webhooks;
-pub use common::*;
+#[cfg(any(
+ feature = "audio-types",
+ feature = "file-types",
+ feature = "upload-types",
+ feature = "image-types",
+ feature = "video-types",
+ feature = "container-types",
+ feature = "chat-completion-types",
+ feature = "realtime-types"
+))]
+pub use input_source::*;
-mod impls;
-use derive_builder::UninitializedFieldError;
+#[cfg(any(
+ feature = "audio-types",
+ feature = "batch-types",
+ feature = "file-types",
+ feature = "upload-types",
+ feature = "image-types",
+ feature = "video-types",
+ feature = "vectorstore-types",
+ feature = "container-types",
+ feature = "response-types",
+ feature = "chat-completion-types",
+ feature = "realtime-types"
+))]
+pub use metadata::*;
-use crate::error::OpenAIError;
+#[cfg(any(
+ feature = "audio-types",
+ feature = "file-types",
+ feature = "image-types",
+ feature = "chat-completion-types",
+ feature = "completion-types",
+ feature = "embedding-types",
+ feature = "moderation-types"
+))]
+mod impls;
-impl From for OpenAIError {
- fn from(value: UninitializedFieldError) -> Self {
- OpenAIError::InvalidArgument(value.to_string())
+#[cfg(any(
+ feature = "response-types",
+ feature = "audio-types",
+ feature = "file-types",
+ feature = "image-types",
+ feature = "chat-completion-types",
+ feature = "completion-types",
+ feature = "embedding-types",
+ feature = "moderation-types",
+ feature = "administration-types",
+))]
+impl From for crate::error::OpenAIError {
+ fn from(value: derive_builder::UninitializedFieldError) -> Self {
+ crate::error::OpenAIError::InvalidArgument(value.to_string())
}
}
diff --git a/async-openai/src/types/realtime/client_event.rs b/async-openai/src/types/realtime/client_event.rs
index b9089f7b..2a0e4276 100644
--- a/async-openai/src/types/realtime/client_event.rs
+++ b/async-openai/src/types/realtime/client_event.rs
@@ -1,7 +1,5 @@
use serde::{Deserialize, Serialize};
-use tokio_tungstenite::tungstenite::Message;
-use crate::traits::EventType;
use crate::types::realtime::{RealtimeConversationItem, RealtimeResponseCreateParams, Session};
#[derive(Debug, Serialize, Deserialize, Clone)]
@@ -239,22 +237,6 @@ impl From<&RealtimeClientEvent> for String {
}
}
-impl From for Message {
- fn from(value: RealtimeClientEvent) -> Self {
- Message::Text(String::from(&value).into())
- }
-}
-
-macro_rules! message_from_event {
- ($from_typ:ty, $evt_typ:ty) => {
- impl From<$from_typ> for Message {
- fn from(value: $from_typ) -> Self {
- Self::from(<$evt_typ>::from(value))
- }
- }
- };
-}
-
macro_rules! event_from {
($from_typ:ty, $evt_typ:ty, $variant:ident) => {
impl From<$from_typ> for $evt_typ {
@@ -321,58 +303,87 @@ event_from!(
OutputAudioBufferClear
);
+impl From for RealtimeClientEventConversationItemCreate {
+ fn from(value: RealtimeConversationItem) -> Self {
+ Self {
+ event_id: None,
+ previous_item_id: None,
+ item: value,
+ }
+ }
+}
+
+#[cfg(feature = "_api")]
+impl From for tokio_tungstenite::tungstenite::Message {
+ fn from(value: RealtimeClientEvent) -> Self {
+ tokio_tungstenite::tungstenite::Message::Text(String::from(&value).into())
+ }
+}
+
+#[cfg(feature = "_api")]
+macro_rules! message_from_event {
+ ($from_typ:ty, $evt_typ:ty) => {
+ impl From<$from_typ> for tokio_tungstenite::tungstenite::Message {
+ fn from(value: $from_typ) -> Self {
+ Self::from(<$evt_typ>::from(value))
+ }
+ }
+ };
+}
+
+#[cfg(feature = "_api")]
message_from_event!(RealtimeClientEventSessionUpdate, RealtimeClientEvent);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventInputAudioBufferAppend,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventInputAudioBufferCommit,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventInputAudioBufferClear,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventConversationItemCreate,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventConversationItemTruncate,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventConversationItemDelete,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventConversationItemRetrieve,
RealtimeClientEvent
);
+#[cfg(feature = "_api")]
message_from_event!(RealtimeClientEventResponseCreate, RealtimeClientEvent);
+#[cfg(feature = "_api")]
message_from_event!(RealtimeClientEventResponseCancel, RealtimeClientEvent);
+#[cfg(feature = "_api")]
message_from_event!(
RealtimeClientEventOutputAudioBufferClear,
RealtimeClientEvent
);
-impl From for RealtimeClientEventConversationItemCreate {
- fn from(value: RealtimeConversationItem) -> Self {
- Self {
- event_id: None,
- previous_item_id: None,
- item: value,
- }
- }
-}
-
// Implement EventType trait for all event types in this file
-
+#[cfg(feature = "_api")]
macro_rules! impl_event_type {
($($ty:ty => $event_type:expr),* $(,)?) => {
$(
- impl EventType for $ty {
+ impl crate::traits::EventType for $ty {
fn event_type(&self) -> &'static str {
$event_type
}
@@ -381,6 +392,7 @@ macro_rules! impl_event_type {
};
}
+#[cfg(feature = "_api")]
impl_event_type! {
RealtimeClientEventSessionUpdate => "session.update",
RealtimeClientEventInputAudioBufferAppend => "input_audio_buffer.append",
@@ -395,7 +407,8 @@ impl_event_type! {
RealtimeClientEventOutputAudioBufferClear => "output_audio_buffer.clear",
}
-impl EventType for RealtimeClientEvent {
+#[cfg(feature = "_api")]
+impl crate::traits::EventType for RealtimeClientEvent {
fn event_type(&self) -> &'static str {
match self {
RealtimeClientEvent::SessionUpdate(e) => e.event_type(),
diff --git a/async-openai/src/types/realtime/mod.rs b/async-openai/src/types/realtime/mod.rs
index 0f9c3e18..1def8978 100644
--- a/async-openai/src/types/realtime/mod.rs
+++ b/async-openai/src/types/realtime/mod.rs
@@ -2,6 +2,7 @@ mod api;
mod client_event;
mod conversation_item;
mod error;
+#[cfg(feature = "_api")]
mod form;
mod response;
mod server_event;
diff --git a/async-openai/src/types/realtime/server_event.rs b/async-openai/src/types/realtime/server_event.rs
index 1c6c3fab..3df1a4df 100644
--- a/async-openai/src/types/realtime/server_event.rs
+++ b/async-openai/src/types/realtime/server_event.rs
@@ -1,6 +1,5 @@
use serde::{Deserialize, Serialize};
-use crate::traits::EventType;
use crate::types::realtime::{LogProbProperties, TranscriptionUsage};
use super::{
@@ -807,11 +806,11 @@ pub enum RealtimeServerEvent {
}
// Implement EventType trait for all event types in this file
-
+#[cfg(feature = "_api")]
macro_rules! impl_event_type {
($($ty:ty => $event_type:expr),* $(,)?) => {
$(
- impl EventType for $ty {
+ impl crate::traits::EventType for $ty {
fn event_type(&self) -> &'static str {
$event_type
}
@@ -820,6 +819,7 @@ macro_rules! impl_event_type {
};
}
+#[cfg(feature = "_api")]
impl_event_type! {
RealtimeServerEventError => "error",
RealtimeServerEventSessionCreated => "session.created",
@@ -866,7 +866,8 @@ impl_event_type! {
RealtimeServerEventRateLimitsUpdated => "rate_limits.updated",
}
-impl EventType for RealtimeServerEvent {
+#[cfg(feature = "_api")]
+impl crate::traits::EventType for RealtimeServerEvent {
fn event_type(&self) -> &'static str {
match self {
RealtimeServerEvent::Error(e) => e.event_type(),
diff --git a/async-openai/src/types/realtime/session.rs b/async-openai/src/types/realtime/session.rs
index 21c3e33e..039970bb 100644
--- a/async-openai/src/types/realtime/session.rs
+++ b/async-openai/src/types/realtime/session.rs
@@ -301,9 +301,12 @@ pub struct TokenLimits {
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "type")]
pub enum Session {
+ // Boxed as per clippy suggestion:
+ // https://rust-lang.github.io/rust -clippy/rust-1.91.0/index.html#large_enum_variant
+ // the largest variant contains at least 600 bytes, the second-largest variant contains at least 144 bytes
/// The type of session to create. Always `realtime` for the Realtime API.
#[serde(rename = "realtime")]
- RealtimeSession(RealtimeSession),
+ RealtimeSession(Box),
/// The type of session to create. Always `transcription` for transcription sessions.
#[serde(rename = "transcription")]
RealtimeTranscriptionSession(RealtimeTranscriptionSession),
diff --git a/async-openai/src/types/responses/conversation.rs b/async-openai/src/types/responses/conversation.rs
index 94d23545..bd87c435 100644
--- a/async-openai/src/types/responses/conversation.rs
+++ b/async-openai/src/types/responses/conversation.rs
@@ -13,7 +13,7 @@ use crate::{
},
};
-use crate::types::common::Metadata;
+use crate::types::Metadata;
/// Represents a conversation object.
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
diff --git a/async-openai/src/types/responses/stream.rs b/async-openai/src/types/responses/stream.rs
index 6e58dff2..86bfc261 100644
--- a/async-openai/src/types/responses/stream.rs
+++ b/async-openai/src/types/responses/stream.rs
@@ -1,15 +1,6 @@
-use futures::Stream;
use serde::{Deserialize, Serialize};
-use std::pin::Pin;
-use crate::{
- error::OpenAIError,
- types::responses::{OutputContent, OutputItem, Response, ResponseLogProb, SummaryPart},
-};
-
-/// Stream of response events
-pub type ResponseStream =
- Pin> + Send>>;
+use crate::types::responses::{OutputContent, OutputItem, Response, ResponseLogProb, SummaryPart};
/// Event types for streaming responses from the Responses API
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
@@ -544,14 +535,18 @@ pub struct ResponseErrorEvent {
pub param: Option,
}
-use crate::traits::EventType;
+/// Stream of response events
+#[cfg(feature = "_api")]
+pub type ResponseStream = std::pin::Pin<
+ Box> + Send>,
+>;
// Implement EventType trait for all event types in this file
-
+#[cfg(feature = "_api")]
macro_rules! impl_event_type {
($($ty:ty => $event_type:expr),* $(,)?) => {
$(
- impl EventType for $ty {
+ impl crate::traits::EventType for $ty {
fn event_type(&self) -> &'static str {
$event_type
}
@@ -561,6 +556,7 @@ macro_rules! impl_event_type {
}
// Apply macro for each event struct type in this file.
+#[cfg(feature = "_api")]
impl_event_type! {
ResponseCreatedEvent => "response.created",
ResponseInProgressEvent => "response.in_progress",
@@ -613,7 +609,8 @@ impl_event_type! {
ResponseErrorEvent => "error",
}
-impl EventType for ResponseStreamEvent {
+#[cfg(feature = "_api")]
+impl crate::traits::EventType for ResponseStreamEvent {
fn event_type(&self) -> &'static str {
match self {
ResponseStreamEvent::ResponseCreated(event) => event.event_type(),
diff --git a/async-openai/src/types/shared/image_input.rs b/async-openai/src/types/shared/image_input.rs
index 7a3e358b..48a96600 100644
--- a/async-openai/src/types/shared/image_input.rs
+++ b/async-openai/src/types/shared/image_input.rs
@@ -1,6 +1,6 @@
use crate::types::InputSource;
-#[derive(Debug, Default, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Default)]
pub struct ImageInput {
pub source: InputSource,
}
diff --git a/async-openai/src/types/shared/mod.rs b/async-openai/src/types/shared/mod.rs
index 7847a550..76359d8c 100644
--- a/async-openai/src/types/shared/mod.rs
+++ b/async-openai/src/types/shared/mod.rs
@@ -1,36 +1,93 @@
//! Shared types - these types are use by multiple type modules
//! and not exported directly, instead they are re-exported
//! by the modules that use them.
+
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
mod completion_tokens_details;
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
mod custom_grammar_format_param;
+#[cfg(any(feature = "response-types", feature = "vectorstore-types"))]
mod filter;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
mod function_call;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
mod function_name;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
mod function_object;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "assistant-types"
+))]
mod image_detail;
+#[cfg(any(feature = "image-types", feature = "video-types"))]
mod image_input;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
mod image_url;
+#[cfg(any(feature = "audio-types", feature = "realtime-types"))]
mod log_prob_properties;
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
mod prompt_tokens_details;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "grader-types"
+))]
mod reasoning_effort;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "assistant-types"
+))]
mod response_format;
+#[cfg(any(feature = "response-types", feature = "batch-types"))]
mod response_usage;
+#[cfg(any(feature = "assistant-types", feature = "vectorstore-types"))]
mod static_chunking_strategy;
+#[cfg(any(feature = "audio-types", feature = "realtime-types"))]
mod transcription_usage;
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
pub use completion_tokens_details::*;
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
pub use custom_grammar_format_param::*;
+#[cfg(any(feature = "response-types", feature = "vectorstore-types"))]
pub use filter::*;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
pub use function_call::*;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
pub use function_name::*;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
pub use function_object::*;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "assistant-types"
+))]
pub use image_detail::*;
+#[cfg(any(feature = "image-types", feature = "video-types"))]
pub use image_input::*;
+#[cfg(any(feature = "chat-completion-types", feature = "assistant-types"))]
pub use image_url::*;
+#[cfg(any(feature = "audio-types", feature = "realtime-types"))]
pub use log_prob_properties::*;
+#[cfg(any(feature = "chat-completion-types", feature = "response-types"))]
pub use prompt_tokens_details::*;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "grader-types"
+))]
pub use reasoning_effort::*;
+#[cfg(any(
+ feature = "chat-completion-types",
+ feature = "response-types",
+ feature = "assistant-types"
+))]
pub use response_format::*;
+#[cfg(any(feature = "response-types", feature = "batch-types"))]
pub use response_usage::*;
+#[cfg(any(feature = "assistant-types", feature = "vectorstore-types"))]
pub use static_chunking_strategy::*;
+#[cfg(any(feature = "audio-types", feature = "realtime-types"))]
pub use transcription_usage::*;
diff --git a/async-openai/src/types/uploads/mod.rs b/async-openai/src/types/uploads/mod.rs
index 879d91d8..c2a8fbe7 100644
--- a/async-openai/src/types/uploads/mod.rs
+++ b/async-openai/src/types/uploads/mod.rs
@@ -1,3 +1,4 @@
+#[cfg(feature = "_api")]
mod form;
mod upload;
diff --git a/async-openai/src/types/videos/mod.rs b/async-openai/src/types/videos/mod.rs
index 9d3c3821..d8eef6cc 100644
--- a/async-openai/src/types/videos/mod.rs
+++ b/async-openai/src/types/videos/mod.rs
@@ -1,4 +1,5 @@
mod api;
+#[cfg(feature = "_api")]
mod form;
mod impls;
mod video;
diff --git a/async-openai/src/types/webhooks/mod.rs b/async-openai/src/types/webhooks/mod.rs
index 73f94904..43b5ee06 100644
--- a/async-openai/src/types/webhooks/mod.rs
+++ b/async-openai/src/types/webhooks/mod.rs
@@ -1,3 +1,3 @@
-mod webhooks;
+mod webhooks_;
-pub use webhooks::*;
+pub use webhooks_::*;
diff --git a/async-openai/src/types/webhooks/webhooks.rs b/async-openai/src/types/webhooks/webhooks_.rs
similarity index 78%
rename from async-openai/src/types/webhooks/webhooks.rs
rename to async-openai/src/types/webhooks/webhooks_.rs
index 15548c18..51aff984 100644
--- a/async-openai/src/types/webhooks/webhooks.rs
+++ b/async-openai/src/types/webhooks/webhooks_.rs
@@ -1,7 +1,5 @@
use serde::{Deserialize, Serialize};
-use crate::traits::{EventId, EventType};
-
/// Sent when a batch API request has been cancelled.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookBatchCancelled {
@@ -77,56 +75,6 @@ pub struct WebhookBatchData {
pub id: String,
}
-// EventType and EventId implementations for batch events
-
-impl EventType for WebhookBatchCancelled {
- fn event_type(&self) -> &'static str {
- "batch.cancelled"
- }
-}
-
-impl EventId for WebhookBatchCancelled {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookBatchCompleted {
- fn event_type(&self) -> &'static str {
- "batch.completed"
- }
-}
-
-impl EventId for WebhookBatchCompleted {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookBatchExpired {
- fn event_type(&self) -> &'static str {
- "batch.expired"
- }
-}
-
-impl EventId for WebhookBatchExpired {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookBatchFailed {
- fn event_type(&self) -> &'static str {
- "batch.failed"
- }
-}
-
-impl EventId for WebhookBatchFailed {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
/// Sent when an eval run has been canceled.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookEvalRunCanceled {
@@ -185,44 +133,6 @@ pub struct WebhookEvalRunData {
pub id: String,
}
-// EventType and EventId implementations for eval run events
-
-impl EventType for WebhookEvalRunCanceled {
- fn event_type(&self) -> &'static str {
- "eval.run.canceled"
- }
-}
-
-impl EventId for WebhookEvalRunCanceled {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookEvalRunFailed {
- fn event_type(&self) -> &'static str {
- "eval.run.failed"
- }
-}
-
-impl EventId for WebhookEvalRunFailed {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookEvalRunSucceeded {
- fn event_type(&self) -> &'static str {
- "eval.run.succeeded"
- }
-}
-
-impl EventId for WebhookEvalRunSucceeded {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
/// Sent when a fine-tuning job has been cancelled.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookFineTuningJobCancelled {
@@ -283,42 +193,6 @@ pub struct WebhookFineTuningJobData {
// EventType and EventId implementations for fine-tuning job events
-impl EventType for WebhookFineTuningJobCancelled {
- fn event_type(&self) -> &'static str {
- "fine_tuning.job.cancelled"
- }
-}
-
-impl EventId for WebhookFineTuningJobCancelled {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookFineTuningJobFailed {
- fn event_type(&self) -> &'static str {
- "fine_tuning.job.failed"
- }
-}
-
-impl EventId for WebhookFineTuningJobFailed {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookFineTuningJobSucceeded {
- fn event_type(&self) -> &'static str {
- "fine_tuning.job.succeeded"
- }
-}
-
-impl EventId for WebhookFineTuningJobSucceeded {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
/// Sent when Realtime API receives an incoming SIP call.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookRealtimeCallIncoming {
@@ -356,20 +230,6 @@ pub struct SipHeader {
pub value: String,
}
-// EventType and EventId implementations for realtime call events
-
-impl EventType for WebhookRealtimeCallIncoming {
- fn event_type(&self) -> &'static str {
- "realtime.call.incoming"
- }
-}
-
-impl EventId for WebhookRealtimeCallIncoming {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
/// Sent when a background response has been cancelled.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookResponseCancelled {
@@ -447,54 +307,6 @@ pub struct WebhookResponseData {
// EventType and EventId implementations for response events
-impl EventType for WebhookResponseCancelled {
- fn event_type(&self) -> &'static str {
- "response.cancelled"
- }
-}
-
-impl EventId for WebhookResponseCancelled {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookResponseCompleted {
- fn event_type(&self) -> &'static str {
- "response.completed"
- }
-}
-
-impl EventId for WebhookResponseCompleted {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookResponseFailed {
- fn event_type(&self) -> &'static str {
- "response.failed"
- }
-}
-
-impl EventId for WebhookResponseFailed {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
-impl EventType for WebhookResponseIncomplete {
- fn event_type(&self) -> &'static str {
- "response.incomplete"
- }
-}
-
-impl EventId for WebhookResponseIncomplete {
- fn event_id(&self) -> &str {
- &self.id
- }
-}
-
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum WebhookEvent {
@@ -544,9 +356,75 @@ pub enum WebhookEvent {
ResponseIncomplete(WebhookResponseIncomplete),
}
-// Trait implementations for WebhookEvent enum
+// Implement EventType trait for all event types in this file
+#[cfg(feature = "_api")]
+macro_rules! impl_event_type {
+ ($($ty:ty => $event_type:expr),* $(,)?) => {
+ $(
+ impl crate::traits::EventType for $ty {
+ fn event_type(&self) -> &'static str {
+ $event_type
+ }
+ }
+ )*
+ };
+}
+
+#[cfg(feature = "_api")]
+macro_rules! impl_event_id {
+ ($($ty:ty),* $(,)?) => {
+ $(
+ impl crate::traits::EventId for $ty {
+ fn event_id(&self) -> &str {
+ &self.id
+ }
+ }
+ )*
+ };
+}
+// Use the macro to implement EventType for all webhook event structs
+#[cfg(feature = "_api")]
+impl_event_type! {
+ WebhookBatchCancelled => "batch.cancelled",
+ WebhookBatchCompleted => "batch.completed",
+ WebhookBatchExpired => "batch.expired",
+ WebhookBatchFailed => "batch.failed",
+ WebhookEvalRunCanceled => "eval.run.canceled",
+ WebhookEvalRunFailed => "eval.run.failed",
+ WebhookEvalRunSucceeded => "eval.run.succeeded",
+ WebhookFineTuningJobCancelled => "fine_tuning.job.cancelled",
+ WebhookFineTuningJobFailed => "fine_tuning.job.failed",
+ WebhookFineTuningJobSucceeded => "fine_tuning.job.succeeded",
+ WebhookRealtimeCallIncoming => "realtime.call.incoming",
+ WebhookResponseCancelled => "response.cancelled",
+ WebhookResponseCompleted => "response.completed",
+ WebhookResponseFailed => "response.failed",
+ WebhookResponseIncomplete => "response.incomplete",
+}
+
+// Use the macro to implement EventId for all webhook event structs
+#[cfg(feature = "_api")]
+impl_event_id! {
+ WebhookBatchCancelled,
+ WebhookBatchCompleted,
+ WebhookBatchExpired,
+ WebhookBatchFailed,
+ WebhookEvalRunCanceled,
+ WebhookEvalRunFailed,
+ WebhookEvalRunSucceeded,
+ WebhookFineTuningJobCancelled,
+ WebhookFineTuningJobFailed,
+ WebhookFineTuningJobSucceeded,
+ WebhookRealtimeCallIncoming,
+ WebhookResponseCancelled,
+ WebhookResponseCompleted,
+ WebhookResponseFailed,
+ WebhookResponseIncomplete,
+}
-impl EventType for WebhookEvent {
+// Trait implementations for WebhookEvent enum
+#[cfg(feature = "_api")]
+impl crate::traits::EventType for WebhookEvent {
fn event_type(&self) -> &'static str {
match self {
WebhookEvent::BatchCancelled(e) => e.event_type(),
@@ -568,7 +446,8 @@ impl EventType for WebhookEvent {
}
}
-impl EventId for WebhookEvent {
+#[cfg(feature = "_api")]
+impl crate::traits::EventId for WebhookEvent {
fn event_id(&self) -> &str {
match self {
WebhookEvent::BatchCancelled(e) => e.event_id(),
diff --git a/async-openai/src/util.rs b/async-openai/src/util.rs
index eab55caf..56db1ee6 100644
--- a/async-openai/src/util.rs
+++ b/async-openai/src/util.rs
@@ -1,5 +1,3 @@
-use std::path::Path;
-
use reqwest::Body;
use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};
@@ -57,8 +55,9 @@ pub(crate) async fn create_file_part(
Ok(file_part)
}
-pub(crate) fn create_all_dir>(dir: P) -> Result<(), OpenAIError> {
- let exists = match Path::try_exists(dir.as_ref()) {
+#[cfg(any(feature = "image", feature = "audio"))]
+pub(crate) fn create_all_dir>(dir: P) -> Result<(), OpenAIError> {
+ let exists = match std::path::Path::try_exists(dir.as_ref()) {
Ok(exists) => exists,
Err(e) => return Err(OpenAIError::FileSaveError(e.to_string())),
};
diff --git a/examples/assistants-code-interpreter/Cargo.toml b/examples/assistants-code-interpreter/Cargo.toml
index c53112ae..4b6d2980 100644
--- a/examples/assistants-code-interpreter/Cargo.toml
+++ b/examples/assistants-code-interpreter/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["assistant", "file"] }
tokio = { version = "1.43.0", features = ["full"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"]}
diff --git a/examples/assistants-file-search/Cargo.toml b/examples/assistants-file-search/Cargo.toml
index 7c94c891..47104d74 100644
--- a/examples/assistants-file-search/Cargo.toml
+++ b/examples/assistants-file-search/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["assistant", "file", "vectorstore"] }
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/assistants-func-call-stream/Cargo.toml b/examples/assistants-func-call-stream/Cargo.toml
index 9767e2b0..dbc3e1da 100644
--- a/examples/assistants-func-call-stream/Cargo.toml
+++ b/examples/assistants-func-call-stream/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["assistant"] }
tokio = { version = "1.43.0", features = ["full"] }
serde_json = "1.0.135"
futures = "0.3.31"
diff --git a/examples/assistants/Cargo.toml b/examples/assistants/Cargo.toml
index d7595fd4..339268df 100644
--- a/examples/assistants/Cargo.toml
+++ b/examples/assistants/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["assistant"]}
tokio = { version = "1.43.0", features = ["full"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"]}
diff --git a/examples/audio-speech-stream/Cargo.toml b/examples/audio-speech-stream/Cargo.toml
index 7b644292..53603c6a 100644
--- a/examples/audio-speech-stream/Cargo.toml
+++ b/examples/audio-speech-stream/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["audio"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
base64 = "0.22.1"
diff --git a/examples/audio-speech/Cargo.toml b/examples/audio-speech/Cargo.toml
index 32c19367..7f38c2e6 100644
--- a/examples/audio-speech/Cargo.toml
+++ b/examples/audio-speech/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["audio"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/audio-transcribe/Cargo.toml b/examples/audio-transcribe/Cargo.toml
index 73dd52ae..5090fd6a 100644
--- a/examples/audio-transcribe/Cargo.toml
+++ b/examples/audio-transcribe/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["audio"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
diff --git a/examples/audio-translate/Cargo.toml b/examples/audio-translate/Cargo.toml
index ba64e89a..d98bf28e 100644
--- a/examples/audio-translate/Cargo.toml
+++ b/examples/audio-translate/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["audio"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/azure-openai-service/Cargo.toml b/examples/azure-openai-service/Cargo.toml
index ec8f0b41..06d24c94 100644
--- a/examples/azure-openai-service/Cargo.toml
+++ b/examples/azure-openai-service/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion", "embedding"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
diff --git a/examples/bring-your-own-type/Cargo.toml b/examples/bring-your-own-type/Cargo.toml
index e99a7454..1c29fbd9 100644
--- a/examples/bring-your-own-type/Cargo.toml
+++ b/examples/bring-your-own-type/Cargo.toml
@@ -6,7 +6,7 @@ rust-version.workspace = true
publish = false
[dependencies]
-async-openai = {path = "../../async-openai", features = ["byot"]}
+async-openai = {path = "../../async-openai", features = ["byot", "chat-completion"]}
tokio = { version = "1.43.0", features = ["full"] }
serde_json = "1"
futures-core = "0.3"
diff --git a/examples/chat-store/Cargo.toml b/examples/chat-store/Cargo.toml
index 0bf77f5f..f28d3d0c 100644
--- a/examples/chat-store/Cargo.toml
+++ b/examples/chat-store/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/chat-stream/Cargo.toml b/examples/chat-stream/Cargo.toml
index 85b4cf43..e33b8323 100644
--- a/examples/chat-stream/Cargo.toml
+++ b/examples/chat-stream/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
diff --git a/examples/chat/Cargo.toml b/examples/chat/Cargo.toml
index b7251e36..9cf9994b 100644
--- a/examples/chat/Cargo.toml
+++ b/examples/chat/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/chatkit/Cargo.toml b/examples/chatkit/Cargo.toml
index 7ff906d9..3d9bfadb 100644
--- a/examples/chatkit/Cargo.toml
+++ b/examples/chatkit/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chatkit"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/completions-stream/Cargo.toml b/examples/completions-stream/Cargo.toml
index fd6d5e59..8bed6947 100644
--- a/examples/completions-stream/Cargo.toml
+++ b/examples/completions-stream/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["completions"]}
futures = "0.3.30"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/completions-web-search/Cargo.toml b/examples/completions-web-search/Cargo.toml
index f58d4f8b..637845e8 100644
--- a/examples/completions-web-search/Cargo.toml
+++ b/examples/completions-web-search/Cargo.toml
@@ -6,5 +6,5 @@ publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/completions/Cargo.toml b/examples/completions/Cargo.toml
index 0574060f..61dfe196 100644
--- a/examples/completions/Cargo.toml
+++ b/examples/completions/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["completions"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/containers/Cargo.toml b/examples/containers/Cargo.toml
index 40736578..103b6daf 100644
--- a/examples/containers/Cargo.toml
+++ b/examples/containers/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["container"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/conversations/Cargo.toml b/examples/conversations/Cargo.toml
index 36a4799e..3a2616fc 100644
--- a/examples/conversations/Cargo.toml
+++ b/examples/conversations/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["responses"] }
tokio = { version = "1.41.1", features = ["full"] }
serde_json = "1"
diff --git a/examples/create-image-variation/Cargo.toml b/examples/create-image-variation/Cargo.toml
index 12de47cb..4a932bab 100644
--- a/examples/create-image-variation/Cargo.toml
+++ b/examples/create-image-variation/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/embeddings/Cargo.toml b/examples/embeddings/Cargo.toml
index 49855f24..9809ddcc 100644
--- a/examples/embeddings/Cargo.toml
+++ b/examples/embeddings/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["embedding"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/gemini-openai-compatibility/Cargo.toml b/examples/gemini-openai-compatibility/Cargo.toml
index f75bbda2..698d0fed 100644
--- a/examples/gemini-openai-compatibility/Cargo.toml
+++ b/examples/gemini-openai-compatibility/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai", features = ["byot"]}
+async-openai = {path = "../../async-openai", features = ["byot", "chat-completion", "image", "embedding", "model"]}
tokio = { version = "1.43.0", features = ["full"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"]}
dotenv = "0.15.0"
diff --git a/examples/image-edit-stream/Cargo.toml b/examples/image-edit-stream/Cargo.toml
index 14b9d759..40e3d8bd 100644
--- a/examples/image-edit-stream/Cargo.toml
+++ b/examples/image-edit-stream/Cargo.toml
@@ -6,7 +6,7 @@ publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
base64 = "0.22.1"
diff --git a/examples/image-edit/Cargo.toml b/examples/image-edit/Cargo.toml
index 24eb2f63..dda7e43b 100644
--- a/examples/image-edit/Cargo.toml
+++ b/examples/image-edit/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/image-gen-stream/Cargo.toml b/examples/image-gen-stream/Cargo.toml
index 907e9882..3f61be42 100644
--- a/examples/image-gen-stream/Cargo.toml
+++ b/examples/image-gen-stream/Cargo.toml
@@ -6,7 +6,7 @@ publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
futures = "0.3.31"
base64 = "0.22.1"
diff --git a/examples/image-generate-b64-json/Cargo.toml b/examples/image-generate-b64-json/Cargo.toml
index 87a2b045..c0e7812b 100644
--- a/examples/image-generate-b64-json/Cargo.toml
+++ b/examples/image-generate-b64-json/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/image-generate/Cargo.toml b/examples/image-generate/Cargo.toml
index 71b5cbe0..42580b1a 100644
--- a/examples/image-generate/Cargo.toml
+++ b/examples/image-generate/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["image"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/in-memory-file/Cargo.toml b/examples/in-memory-file/Cargo.toml
index 1d5c4458..cc2dfbfb 100644
--- a/examples/in-memory-file/Cargo.toml
+++ b/examples/in-memory-file/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["audio"]}
tokio = { version = "1.43.0", features = ["full"] }
bytes = "1.9.0"
diff --git a/examples/models/Cargo.toml b/examples/models/Cargo.toml
index bc38c36f..e8873b53 100644
--- a/examples/models/Cargo.toml
+++ b/examples/models/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["model"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/moderations/Cargo.toml b/examples/moderations/Cargo.toml
index 12cf62eb..919b3d56 100644
--- a/examples/moderations/Cargo.toml
+++ b/examples/moderations/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["moderation"] }
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/ollama-chat/Cargo.toml b/examples/ollama-chat/Cargo.toml
index cbdd7cc2..bc121558 100644
--- a/examples/ollama-chat/Cargo.toml
+++ b/examples/ollama-chat/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/responses-function-call/Cargo.toml b/examples/responses-function-call/Cargo.toml
index fae73d83..eb61b286 100644
--- a/examples/responses-function-call/Cargo.toml
+++ b/examples/responses-function-call/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["responses"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
serde = { version = "1.0.219", features = ["derive"] }
diff --git a/examples/responses-images-and-vision/Cargo.toml b/examples/responses-images-and-vision/Cargo.toml
index 6258b396..74cf62b8 100644
--- a/examples/responses-images-and-vision/Cargo.toml
+++ b/examples/responses-images-and-vision/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["responses"] }
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
base64 = "0.22.1"
diff --git a/examples/responses-retrieve-stream/Cargo.toml b/examples/responses-retrieve-stream/Cargo.toml
index 8f57a2a8..53275a32 100644
--- a/examples/responses-retrieve-stream/Cargo.toml
+++ b/examples/responses-retrieve-stream/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["responses"] }
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
serde_json = "1.0"
diff --git a/examples/responses-stream/Cargo.toml b/examples/responses-stream/Cargo.toml
index 5a276ba0..feaa5fc6 100644
--- a/examples/responses-stream/Cargo.toml
+++ b/examples/responses-stream/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["responses"] }
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
serde_json = "1.0"
diff --git a/examples/responses-structured-outputs/Cargo.toml b/examples/responses-structured-outputs/Cargo.toml
index 869d3436..1bb475de 100644
--- a/examples/responses-structured-outputs/Cargo.toml
+++ b/examples/responses-structured-outputs/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["responses"] }
serde_json = "1.0"
tokio = { version = "1", features = ["full"] }
clap = { version = "4", features = ["derive"] }
diff --git a/examples/responses/Cargo.toml b/examples/responses/Cargo.toml
index 5de7c1e4..39d5ace2 100644
--- a/examples/responses/Cargo.toml
+++ b/examples/responses/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["responses"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/structured-outputs-schemars/Cargo.toml b/examples/structured-outputs-schemars/Cargo.toml
index 029298c1..75c93280 100644
--- a/examples/structured-outputs-schemars/Cargo.toml
+++ b/examples/structured-outputs-schemars/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
serde_json = "1.0.127"
tokio = { version = "1.39.3", features = ["full"] }
schemars = "0.8.21"
diff --git a/examples/structured-outputs/Cargo.toml b/examples/structured-outputs/Cargo.toml
index 0005568b..6e268e57 100644
--- a/examples/structured-outputs/Cargo.toml
+++ b/examples/structured-outputs/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/tool-call-stream/Cargo.toml b/examples/tool-call-stream/Cargo.toml
index 6d68ba36..9ab536c9 100644
--- a/examples/tool-call-stream/Cargo.toml
+++ b/examples/tool-call-stream/Cargo.toml
@@ -7,7 +7,7 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
rand = "0.8.5"
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/tool-call/Cargo.toml b/examples/tool-call/Cargo.toml
index e6a2dc63..967e47c7 100644
--- a/examples/tool-call/Cargo.toml
+++ b/examples/tool-call/Cargo.toml
@@ -7,7 +7,7 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["chat-completion"]}
rand = "0.8.5"
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/usage/Cargo.toml b/examples/usage/Cargo.toml
index 669ef3c2..3553dbd8 100644
--- a/examples/usage/Cargo.toml
+++ b/examples/usage/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["administration"]}
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/vector-store-retrieval/Cargo.toml b/examples/vector-store-retrieval/Cargo.toml
index a4b8bb22..9a11003d 100644
--- a/examples/vector-store-retrieval/Cargo.toml
+++ b/examples/vector-store-retrieval/Cargo.toml
@@ -5,5 +5,5 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["vectorstore", "file"] }
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/video/Cargo.toml b/examples/video/Cargo.toml
index 601bd03d..5514380f 100644
--- a/examples/video/Cargo.toml
+++ b/examples/video/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = {path = "../../async-openai"}
+async-openai = {path = "../../async-openai", features = ["video"]}
tokio = { version = "1.43.0", features = ["full"] }
bytes = "1.9.0"
diff --git a/examples/vision-chat/Cargo.toml b/examples/vision-chat/Cargo.toml
index 11a7cde5..b2ac34b7 100644
--- a/examples/vision-chat/Cargo.toml
+++ b/examples/vision-chat/Cargo.toml
@@ -7,6 +7,6 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-async-openai = { path = "../../async-openai" }
+async-openai = { path = "../../async-openai", features = ["chat-completion"] }
serde_json = "1.0.135"
tokio = { version = "1.43.0", features = ["full"] }
diff --git a/examples/webhooks/Cargo.toml b/examples/webhooks/Cargo.toml
index fb004089..f2f4a49a 100644
--- a/examples/webhooks/Cargo.toml
+++ b/examples/webhooks/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
publish = false
[dependencies]
-async-openai = { path = "../../async-openai", features = ["webhook"] }
+async-openai = { path = "../../async-openai", features = ["webhook", "responses"] }
tokio = { version = "1.42.0", features = ["full"] }
axum = "0.7.9"
tracing = "0.1.41"