gproxy-protocol 3.0.0-alpha.0

GPROXY v3 protocol model: operation taxonomy, wire kinds, and the OperationSpec registry
Documentation
use serde::{Deserialize, Serialize, de};
use serde_json::Value;

use crate::openai::common::Rest;

use super::{AudioTokenUsage, TranscriptionLanguage, TranscriptionLogprob};

/// Speech SSE payload observed by compatible backends. The OpenAI snapshot
/// confirms SSE transport but does not name its events; `type`, `delta`, and
/// `audio` are session-derived aliases and every other field remains opaque.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum SpeechStreamEvent {
    Event(SpeechEvent),
    Raw(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct SpeechEvent {
    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
    pub type_: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub delta: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audio: Option<String>,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum TranscriptionStreamEvent {
    Delta(TranscriptionTextDeltaEvent),
    Done(TranscriptionTextDoneEvent),
    Segment(TranscriptionTextSegmentEvent),
    Unknown(UnknownTranscriptionStreamEvent),
}

impl<'de> Deserialize<'de> for TranscriptionStreamEvent {
    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        let value = Value::deserialize(deserializer)?;
        let known = match value.get("type").and_then(Value::as_str) {
            Some("transcript.text.delta") => serde_json::from_value(value.clone()).map(Self::Delta),
            Some("transcript.text.done") => serde_json::from_value(value.clone()).map(Self::Done),
            Some("transcript.text.segment") => {
                serde_json::from_value(value.clone()).map(Self::Segment)
            }
            _ => serde_json::from_value(value.clone()).map(Self::Unknown),
        };
        known
            .or_else(|_| serde_json::from_value(value).map(Self::Unknown))
            .map_err(de::Error::custom)
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct UnknownTranscriptionStreamEvent {
    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
    pub type_: Option<String>,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct TranscriptionTextDeltaEvent {
    #[serde(rename = "type")]
    pub type_: TranscriptionTextDeltaType,
    pub delta: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub logprobs: Option<Vec<TranscriptionLogprob>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub segment_id: Option<String>,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum TranscriptionTextDeltaType {
    #[serde(rename = "transcript.text.delta")]
    Delta,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct TranscriptionTextDoneEvent {
    #[serde(rename = "type")]
    pub type_: TranscriptionTextDoneType,
    pub text: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub languages: Option<Vec<TranscriptionLanguage>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub logprobs: Option<Vec<TranscriptionLogprob>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub usage: Option<AudioTokenUsage>,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum TranscriptionTextDoneType {
    #[serde(rename = "transcript.text.done")]
    Done,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct TranscriptionTextSegmentEvent {
    #[serde(rename = "type")]
    pub type_: TranscriptionTextSegmentType,
    pub id: String,
    pub end: f64,
    pub speaker: String,
    pub start: f64,
    pub text: String,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum TranscriptionTextSegmentType {
    #[serde(rename = "transcript.text.segment")]
    Segment,
}