ferrin_spec/
speech_model.rs1use std::future::Future;
4
5use bytes::Bytes;
6use serde::Deserialize;
7use serde::Serialize;
8use tokio_util::sync::CancellationToken;
9
10use crate::error::ProviderError;
11use crate::language_model::RequestMetadata;
12use crate::language_model::ResponseMetadata;
13use crate::shared::Headers;
14use crate::shared::MediaType;
15use crate::shared::ModelId;
16use crate::shared::ProviderId;
17use crate::shared::ProviderMetadata;
18use crate::shared::ProviderOptions;
19use crate::shared::Warning;
20use crate::shared::base64_bytes;
21
22pub trait SpeechModel: Send + Sync + 'static {
24 fn provider(&self) -> &ProviderId;
26
27 fn model_id(&self) -> &ModelId;
29
30 fn do_generate(
32 &self,
33 options: SpeechOptions,
34 ) -> impl Future<Output = Result<SpeechResult, ProviderError>> + Send;
35}
36
37#[derive(Debug, Clone, Default)]
39pub struct SpeechOptions {
40 pub text: String,
42 pub voice: Option<String>,
44 pub output_format: Option<String>,
46 pub instructions: Option<String>,
48 pub speed: Option<f64>,
50 pub language: Option<String>,
52 pub provider_options: ProviderOptions,
54 pub headers: Headers,
56 pub cancellation: CancellationToken,
58}
59
60impl SpeechOptions {
61 #[must_use]
63 pub fn new(text: impl Into<String>) -> Self {
64 Self {
65 text: text.into(),
66 ..Self::default()
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
73pub struct SpeechResult {
74 #[serde(with = "base64_bytes")]
76 pub audio: Bytes,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub media_type: Option<MediaType>,
80 #[serde(default)]
82 pub warnings: Vec<Warning>,
83 #[serde(default)]
85 pub request: RequestMetadata,
86 #[serde(default)]
88 pub response: ResponseMetadata,
89 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub provider_metadata: Option<ProviderMetadata>,
92}