use serde::Deserialize;
use deepseek_recipe_core::multimodal::ImageDetail;
#[derive(Debug, Deserialize)]
pub struct ChatCompletionRequest {
pub messages: Vec<ChatCompletionRequestMessage>,
pub model: String,
pub frequency_penalty: Option<f32>,
pub max_tokens: Option<u32>,
pub n: Option<u8>,
pub presence_penalty: Option<f32>,
pub seed: Option<u64>,
pub stop: Option<ChatCompletionStopSequences>,
pub stream: Option<bool>,
pub stream_options: Option<ChatCompletionStreamOptions>,
pub temperature: Option<f32>,
pub top_p: Option<f32>,
pub response_format: Option<ChatCompletionResponseFormat>,
pub tools: Option<Vec<ChatCompletionTool>>,
pub tool_choice: Option<ChatCompletionToolChoiceOption>,
pub reasoning_effort: Option<ChatCompletionReasoningEffort>,
pub thinking: Option<ChatCompletionThinking>,
pub parallel_tool_calls: Option<bool>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "role", rename_all = "snake_case")]
pub enum ChatCompletionRequestMessage {
System {
content: ChatCompletionRequestContent,
},
User {
content: ChatCompletionRequestContent,
},
Assistant {
content: Option<ChatCompletionRequestContent>,
reasoning_content: Option<String>,
tool_calls: Option<Vec<ChatCompletionRequestToolCall>>,
},
Tool {
content: ChatCompletionRequestContent,
tool_call_id: String,
},
LatestReminder {
content: String,
},
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionRequestToolCall {
pub id: String,
pub function: ChatCompletionRequestFunctionCall,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionRequestFunctionCall {
pub name: String,
pub arguments: String,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum ChatCompletionRequestContent {
String(String),
List(Vec<ChatCompletionRequestContentBlock>),
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionImageUrl {
pub url: String,
#[serde(default)]
pub detail: Option<ImageDetail>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ChatCompletionRequestContentBlock {
Text {
text: String,
},
ImageUrl {
image_url: ChatCompletionImageUrl,
},
File {
file_id: Option<String>,
file_data: Option<String>,
filename: Option<String>,
},
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub enum ChatCompletionStopSequences {
Array(Vec<String>),
String(String),
}
impl From<ChatCompletionStopSequences> for Vec<String> {
fn from(value: ChatCompletionStopSequences) -> Self {
match value {
ChatCompletionStopSequences::Array(values) => values,
ChatCompletionStopSequences::String(value) => vec![value],
}
}
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionStreamOptions {
pub include_usage: Option<bool>,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ChatCompletionResponseFormat {
JsonObject,
JsonSchema,
Regex {
regex: String,
},
Text,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionTool {
pub r#type: ChatCompletionToolType,
pub function: ChatCompletionFunctionDefinition,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionToolType {
Function,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionFunctionDefinition {
pub name: String,
pub description: Option<String>,
pub parameters: Option<serde_json::Value>,
pub strict: Option<bool>,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum ChatCompletionToolChoiceOption {
Mode(ChatCompletionToolChoiceMode),
Named(ChatCompletionNamedToolChoice),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionToolChoiceMode {
None,
Auto,
Required,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionNamedToolChoice {
pub r#type: ChatCompletionToolType,
pub function: ChatCompletionToolChoiceFunction,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionToolChoiceFunction {
pub name: String,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionThinking {
#[serde(rename = "type")]
pub kind: ChatCompletionThinkingType,
pub budget_tokens: Option<u64>,
}
#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionThinkingType {
#[serde(alias = "adaptive")]
Enabled,
Disabled,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionReasoningEffort {
None,
Minimal,
Low,
Medium,
High,
Xhigh,
Max,
}