use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ReasoningEffort {
Low,
Medium,
High,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenAIConfig {
pub api_key: String,
pub model: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub project_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub base_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option<ReasoningEffort>,
}
impl Default for OpenAIConfig {
fn default() -> Self {
Self {
api_key: String::new(),
model: "gpt-4o-mini".to_string(),
organization_id: None,
project_id: None,
base_url: None,
reasoning_effort: None,
}
}
}
impl OpenAIConfig {
pub fn new(api_key: impl Into<String>, model: impl Into<String>) -> Self {
Self { api_key: api_key.into(), model: model.into(), ..Default::default() }
}
pub fn compatible(
api_key: impl Into<String>,
base_url: impl Into<String>,
model: impl Into<String>,
) -> Self {
Self {
api_key: api_key.into(),
model: model.into(),
base_url: Some(base_url.into()),
..Default::default()
}
}
pub fn with_organization(mut self, org_id: impl Into<String>) -> Self {
self.organization_id = Some(org_id.into());
self
}
pub fn with_project(mut self, project_id: impl Into<String>) -> Self {
self.project_id = Some(project_id.into());
self
}
pub fn with_reasoning_effort(mut self, effort: ReasoningEffort) -> Self {
self.reasoning_effort = Some(effort);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AzureConfig {
pub api_key: String,
pub api_base: String,
pub api_version: String,
pub deployment_id: String,
}
impl AzureConfig {
pub fn new(
api_key: impl Into<String>,
api_base: impl Into<String>,
api_version: impl Into<String>,
deployment_id: impl Into<String>,
) -> Self {
Self {
api_key: api_key.into(),
api_base: api_base.into(),
api_version: api_version.into(),
deployment_id: deployment_id.into(),
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum ResponsesTransport {
#[default]
Http,
WebSocket,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ServiceTier {
Auto,
Priority,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PromptCacheRetention {
InMemory,
#[serde(rename = "24h")]
TwentyFourHours,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ReasoningSummary {
Auto,
Concise,
Detailed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenAIResponsesConfig {
pub api_key: String,
pub model: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub project_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub base_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option<ReasoningEffort>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_summary: Option<ReasoningSummary>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transport: Option<ResponsesTransport>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_tier: Option<ServiceTier>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_cache_retention: Option<PromptCacheRetention>,
#[serde(skip_serializing_if = "Option::is_none")]
pub open_responses_mode: Option<bool>,
}
impl OpenAIResponsesConfig {
pub fn new(api_key: impl Into<String>, model: impl Into<String>) -> Self {
Self {
api_key: api_key.into(),
model: model.into(),
organization_id: None,
project_id: None,
base_url: None,
reasoning_effort: None,
reasoning_summary: None,
transport: None,
service_tier: None,
prompt_cache_retention: None,
open_responses_mode: None,
}
}
#[must_use]
pub fn with_organization(mut self, org_id: impl Into<String>) -> Self {
self.organization_id = Some(org_id.into());
self
}
#[must_use]
pub fn with_project(mut self, project_id: impl Into<String>) -> Self {
self.project_id = Some(project_id.into());
self
}
#[must_use]
pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
self.base_url = Some(base_url.into());
self
}
#[must_use]
pub fn with_reasoning_effort(mut self, effort: ReasoningEffort) -> Self {
self.reasoning_effort = Some(effort);
self
}
#[must_use]
pub fn with_reasoning_summary(mut self, summary: ReasoningSummary) -> Self {
self.reasoning_summary = Some(summary);
self
}
#[must_use]
pub fn with_transport(mut self, transport: ResponsesTransport) -> Self {
self.transport = Some(transport);
self
}
#[must_use]
pub fn with_service_tier(mut self, tier: ServiceTier) -> Self {
self.service_tier = Some(tier);
self
}
#[must_use]
pub fn with_prompt_cache_retention(mut self, retention: PromptCacheRetention) -> Self {
self.prompt_cache_retention = Some(retention);
self
}
#[must_use]
pub fn with_open_responses_mode(mut self, enabled: bool) -> Self {
self.open_responses_mode = Some(enabled);
self
}
}