1use crate::session::SessionConfig;
2use crate::types::{AudioInputFrame, AudioOutputFrame, ControlEvent, ExternalContextEvent};
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use thiserror::Error;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9pub struct BackendCapabilities {
10 pub supports_full_duplex: bool,
11 pub supports_control_stream: bool,
12 pub supports_context_injection: bool,
13 pub supports_pause_resume: bool,
14 pub supports_style_conditioning: bool,
15 pub supports_word_timestamps: bool,
16}
17
18impl Default for BackendCapabilities {
19 fn default() -> Self {
20 Self {
21 supports_full_duplex: true,
22 supports_control_stream: true,
23 supports_context_injection: false,
24 supports_pause_resume: true,
25 supports_style_conditioning: false,
26 supports_word_timestamps: false,
27 }
28 }
29}
30
31#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
32pub struct BackendStep {
33 pub output_audio: Vec<AudioOutputFrame>,
34 pub control_events: Vec<ControlEvent>,
35 pub transcript: Option<String>,
36 pub finished: bool,
37 pub debug_payload: Option<Value>,
38}
39
40#[derive(Debug, Error)]
41pub enum BackendError {
42 #[error("backend session start failed: {0}")]
43 Start(String),
44 #[error("backend step failed: {0}")]
45 Step(String),
46 #[error("backend context injection failed: {0}")]
47 Inject(String),
48 #[error("backend end session failed: {0}")]
49 End(String),
50}
51
52#[async_trait]
53pub trait SpeechToSpeechBackend: Send + Sync {
54 type Session: Send + Sync;
55
56 fn capabilities(&self) -> BackendCapabilities;
57
58 async fn start_session(&self, config: SessionConfig) -> Result<Self::Session, BackendError>;
59
60 async fn step(
61 &self,
62 session: &mut Self::Session,
63 input: AudioInputFrame,
64 ) -> Result<BackendStep, BackendError>;
65
66 async fn inject_event(
67 &self,
68 session: &mut Self::Session,
69 event: ExternalContextEvent,
70 ) -> Result<(), BackendError>;
71
72 async fn end_session(&self, session: Self::Session) -> Result<(), BackendError>;
73}