gproxy-protocol 4.1.10

GPROXY v4 connection modelling, operation declarations, vendor wire types and pairwise conversion
Documentation
use crate::{
    transform::{Report, TransformError, TransformErrorKind},
    wire::DeclaredFields,
};

#[derive(Debug, Clone, Copy)]
pub struct StreamLimits {
    pub max_bytes: usize,
}

impl Default for StreamLimits {
    fn default() -> Self {
        Self {
            max_bytes: 16 * 1024 * 1024,
        }
    }
}

pub struct StreamEnd<T> {
    pub chunks: Vec<T>,
    pub identities: crate::transform::identity::IdentityFlow,
    pub report: Report,
}

pub(super) fn invalid(message: &'static str) -> TransformError {
    TransformError::invalid_result("chat_responses.stream", message)
}

pub(super) fn unsupported(field: &'static str, message: &'static str) -> TransformError {
    TransformError::unsupported(field, message)
}

pub(super) fn limit() -> TransformError {
    TransformError::new(
        TransformErrorKind::Limit,
        "chat_responses.stream",
        "stream limit exceeded",
    )
}

pub(super) struct Budget {
    limits: StreamLimits,

    input_bytes: usize,

    output_bytes: usize,
}

impl Budget {
    pub(super) fn new(limits: StreamLimits) -> Self {
        Self {
            limits,

            input_bytes: 0,

            output_bytes: 0,
        }
    }

    pub(super) fn input<T: serde::Serialize>(&mut self, value: &T) -> Result<(), TransformError> {
        self.input_bytes = self
            .input_bytes
            .checked_add(measure(
                value,
                self.limits.max_bytes.saturating_sub(self.input_bytes),
            )?)
            .ok_or_else(limit)?;
        Ok(())
    }

    pub(super) fn output<T: serde::Serialize>(&mut self, value: &T) -> Result<(), TransformError> {
        self.output_bytes = self
            .output_bytes
            .checked_add(measure(
                value,
                self.limits.max_bytes.saturating_sub(self.output_bytes),
            )?)
            .ok_or_else(limit)?;
        Ok(())
    }
}

pub(super) fn measure<T: serde::Serialize>(
    value: &T,
    remaining: usize,
) -> Result<usize, TransformError> {
    crate::codec::encode_json(
        value,
        crate::codec::CodecLimits {
            max_value_bytes: remaining as u64,
            max_body_bytes: remaining as u64,
            max_buffer_bytes: remaining as u64,
            max_line_bytes: remaining as u64,
            max_part_bytes: remaining as u64,
            max_parts: usize::MAX,
        },
    )
    .map(|v| v.len())
    .map_err(|e| {
        if e.kind() == crate::codec::CodecErrorKind::Limit {
            limit()
        } else {
            invalid("invalid declared stream value")
        }
    })
}

pub(super) fn declared<T: DeclaredFields>(value: T) -> T {
    value.into_declared()
}

pub(super) fn stream_logs(
    logs: &[crate::wire::openai::responses::input::OutputLogprob],
) -> Vec<crate::wire::openai::responses::stream::StreamLogprob> {
    use crate::wire::openai::responses::stream as s;
    logs.iter()
        .map(|v| s::StreamLogprob {
            token: v.token.clone(),
            logprob: v.logprob.clone(),
            top_logprobs: Some(
                v.top_logprobs
                    .iter()
                    .map(|t| s::StreamTopLogprob {
                        token: Some(t.token.clone()),
                        logprob: Some(t.logprob.clone()),
                        rest: Default::default(),
                    })
                    .collect(),
            ),
            rest: Default::default(),
        })
        .collect()
}