gproxy-protocol 3.0.0-alpha.0

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

use crate::openai::common::*;

use super::{
    ChatAudioParam, ChatAudioRef, ChatFileRef, ChatWebSearchOptions, CustomToolCall, ImageUrl,
    InputAudio, PredictionContent, StreamOptions,
};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct ChatCompletionRequest {
    pub messages: Vec<ChatCompletionMessageParam>,
    pub model: OpenAiModelId,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audio: Option<ChatAudioParam>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub frequency_penalty: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub function_call: Option<LegacyFunctionCallChoice>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub functions: Option<Vec<LegacyFunctionDefinition>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub logit_bias: Option<LogitBias>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub logprobs: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_completion_tokens: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_tokens: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub modalities: Option<Vec<TextOrAudioModality>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub moderation: Option<ModerationConfig>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub n: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub parallel_tool_calls: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prediction: Option<PredictionContent>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub presence_penalty: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prompt_cache_key: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prompt_cache_options: Option<PromptCacheOptions>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prompt_cache_retention: Option<PromptCacheRetention>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reasoning_effort: Option<ReasoningEffort>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub response_format: Option<ChatResponseFormat>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub safety_identifier: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub seed: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub service_tier: Option<ServiceTier>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stop: Option<StringOrList>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub store: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stream: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stream_options: Option<StreamOptions>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub temperature: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tool_choice: Option<ChatToolChoice>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tools: Option<Vec<ChatTool>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub top_logprobs: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub top_p: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub verbosity: Option<Verbosity>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub web_search_options: Option<ChatWebSearchOptions>,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatCompletionMessageParam {
    Developer(ChatDeveloperMessageParam),
    System(ChatSystemMessageParam),
    User(ChatUserMessageParam),
    Assistant(ChatAssistantMessageParam),
    Tool(ChatToolMessageParam),
    Function(ChatFunctionMessageParam),
    Unknown(Value),
}

macro_rules! text_message {
    ($name:ident, $role:ident) => {
        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
        pub struct $name {
            pub role: $role,
            pub content: ChatTextContent,
            #[serde(skip_serializing_if = "Option::is_none")]
            pub name: Option<String>,
            #[serde(default, flatten)]
            pub rest: Rest,
        }
    };
}

text_message!(ChatDeveloperMessageParam, ChatDeveloperRole);
text_message!(ChatSystemMessageParam, ChatSystemRole);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct ChatUserMessageParam {
    pub role: ChatUserRole,
    pub content: ChatContent,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: 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 ChatAssistantMessageParam {
    pub role: ChatAssistantRole,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub content: Option<ChatAssistantContent>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audio: Option<ChatAudioRef>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub function_call: Option<FunctionCall>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reasoning_content: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub refusal: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tool_calls: Option<Vec<ChatToolCall>>,
    #[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 ChatToolMessageParam {
    pub role: ChatToolRole,
    pub content: ChatTextContent,
    pub tool_call_id: 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 ChatFunctionMessageParam {
    pub role: ChatFunctionRole,
    pub content: Option<String>,
    pub name: String,
    #[serde(default, flatten)]
    pub rest: Rest,
}

macro_rules! role {
    ($name:ident, $variant:ident, $wire:literal) => {
        #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
        #[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
        pub enum $name {
            #[serde(rename = $wire)]
            $variant,
        }
    };
}

role!(ChatDeveloperRole, Developer, "developer");
role!(ChatSystemRole, System, "system");
role!(ChatUserRole, User, "user");
role!(ChatAssistantRole, Assistant, "assistant");
role!(ChatToolRole, Tool, "tool");
role!(ChatFunctionRole, Function, "function");

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatTextContent {
    Text(String),
    Parts(Vec<ChatTextContentPart>),
    Unknown(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatTextContentPart {
    Text(ChatTextPart),
    Unknown(Value),
}

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

role!(ChatTextPartType, Text, "text");

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatAssistantContent {
    Text(String),
    Parts(Vec<ChatAssistantContentPart>),
    Unknown(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatAssistantContentPart {
    Text(ChatTextPart),
    Refusal(ChatRefusalPart),
    Unknown(Value),
}

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

role!(ChatRefusalPartType, Refusal, "refusal");

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatContent {
    Text(String),
    Parts(Vec<ChatContentPart>),
    Unknown(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatContentPart {
    Text(ChatTextPart),
    ImageUrl(ChatImageUrlPart),
    InputAudio(ChatInputAudioPart),
    File(ChatFilePart),
    Unknown(Value),
}

macro_rules! input_part {
    ($name:ident, $type_name:ident, $variant:ident, $wire:literal, $field:ident, $ty:ty) => {
        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
        pub struct $name {
            #[serde(rename = "type")]
            pub type_: $type_name,
            pub $field: $ty,
            #[serde(skip_serializing_if = "Option::is_none")]
            pub prompt_cache_breakpoint: Option<PromptCacheBreakpoint>,
            #[serde(default, flatten)]
            pub rest: Rest,
        }
        role!($type_name, $variant, $wire);
    };
}

input_part!(
    ChatImageUrlPart,
    ChatImageUrlPartType,
    ImageUrl,
    "image_url",
    image_url,
    ImageUrl
);
input_part!(
    ChatInputAudioPart,
    ChatInputAudioPartType,
    InputAudio,
    "input_audio",
    input_audio,
    InputAudio
);
input_part!(
    ChatFilePart,
    ChatFilePartType,
    File,
    "file",
    file,
    ChatFileRef
);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatTool {
    Function(ChatFunctionTool),
    Custom(ChatCustomTool),
    Unknown(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct ChatFunctionTool {
    #[serde(rename = "type")]
    pub type_: FunctionToolChoiceType,
    pub function: FunctionDefinition,
    #[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 ChatCustomTool {
    #[serde(rename = "type")]
    pub type_: CustomToolChoiceType,
    pub custom: CustomToolDefinition,
    #[serde(default, flatten)]
    pub rest: Rest,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub enum ChatToolCall {
    Function(ChatFunctionToolCall),
    Custom(ChatCustomToolCall),
    Unknown(Value),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
pub struct ChatFunctionToolCall {
    pub id: String,
    #[serde(rename = "type")]
    pub type_: FunctionToolChoiceType,
    pub function: FunctionCall,
    #[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 ChatCustomToolCall {
    pub id: String,
    #[serde(rename = "type")]
    pub type_: CustomToolChoiceType,
    pub custom: CustomToolCall,
    #[serde(default, flatten)]
    pub rest: Rest,
}