Skip to main content

vona_core/
backend.rs

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}