use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::error::AiMuxError;
use crate::shared::{
AbortSignal, SharedHeaders, SharedProviderMetadata, SharedProviderOptions, Warning,
};
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub enum AudioData {
Base64(String),
Binary(Vec<u8>),
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct SpeechCallOptions {
pub text: String,
pub voice: Option<String>,
pub output_format: Option<String>,
pub instructions: Option<String>,
pub speed: Option<f64>,
pub language: Option<String>,
pub provider_options: Option<SharedProviderOptions>,
#[serde(skip)]
#[ts(skip)]
pub abort_signal: Option<AbortSignal>,
pub headers: Option<SharedHeaders>,
}
impl SpeechCallOptions {
pub fn new(text: impl Into<String>) -> Self {
Self {
text: text.into(),
voice: None,
output_format: None,
instructions: None,
speed: None,
language: None,
provider_options: None,
abort_signal: None,
headers: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct SpeechResult {
pub audio: AudioData,
pub warnings: Vec<Warning>,
pub request: Option<SpeechRequest>,
pub response: SpeechResponse,
pub provider_metadata: Option<SharedProviderMetadata>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct SpeechRequest {
pub body: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct SpeechResponse {
pub timestamp: Option<String>,
pub model_id: Option<String>,
pub headers: Option<SharedHeaders>,
pub body: Option<serde_json::Value>,
}
#[async_trait]
pub trait SpeechModel: Send + Sync {
fn specification_version(&self) -> &'static str {
"v4"
}
fn provider(&self) -> &str;
fn model_id(&self) -> &str;
async fn do_generate(&self, options: &SpeechCallOptions) -> Result<SpeechResult, AiMuxError>;
}