use deepseek_recipe_core::conversation::Conversation;
use crate::response::ProtocolResponse;
use crate::stream::state_machine::ParsingOptions;
pub use options::{ConversionOptions, WebSearchBehavior};
mod options;
#[derive(Debug, Default)]
pub struct InferenceOptions {
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub top_p: Option<f32>,
pub thinking_budget_tokens: Option<u64>,
pub disable_parallel_tool_use: Option<bool>,
}
#[derive(Debug)]
pub struct ConversationRequest {
pub conversation: Conversation,
pub inference_options: InferenceOptions,
pub parsing_options: ParsingOptions,
pub model: Option<String>,
pub stream: bool,
}
impl ConversationRequest {
pub fn new(conversation: Conversation) -> Self {
Self {
conversation,
inference_options: InferenceOptions::default(),
parsing_options: ParsingOptions::default(),
model: None,
stream: false,
}
}
}
pub trait ProtocolRequest: 'static + Send + Sync {
type Response: ProtocolResponse;
fn convert(self, options: ConversionOptions) -> Result<ConversationRequest, ConversionError>;
fn chunk_generator(
request: &ConversationRequest,
id: String,
model: String,
) -> <Self::Response as ProtocolResponse>::ChunkGenerator;
}
#[derive(Debug)]
pub enum ConversionError {
BadRequest { detail: String },
Internal { detail: String },
}
impl ConversionError {
pub fn bad_request(detail: impl Into<String>) -> Self {
ConversionError::BadRequest {
detail: detail.into(),
}
}
pub fn internal(detail: impl Into<String>) -> Self {
ConversionError::Internal {
detail: detail.into(),
}
}
}
impl std::fmt::Display for ConversionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BadRequest { detail } | Self::Internal { detail } => f.write_str(detail),
}
}
}
impl std::error::Error for ConversionError {}