use crate::models::structured::JsonSchemaConfig;
use crate::models::tool::Tool;
use crate::types::chat::Message;
use serde::Serialize;
use serde_json::Value;
#[derive(Debug, Clone, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ResponseFormatConfig {
#[serde(rename = "type")]
pub format_type: String,
#[serde(rename = "json_schema")]
pub json_schema: JsonSchemaConfig,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestPayload<T: Serialize> {
pub model: String,
pub messages: Vec<Message>,
#[serde(skip_serializing_if = "Option::is_none")]
pub response_format: Option<ResponseFormatConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<Tool>>,
#[serde(flatten)]
pub extra_params: T,
}
pub struct RequestBuilder<T: Serialize> {
model: String,
messages: Vec<Message>,
extra_params: T,
structured_output: Option<ResponseFormatConfig>,
tools: Option<Vec<Tool>>,
pub validate_structured: bool,
pub fallback_on_failure: bool,
}
impl<T: Serialize> RequestBuilder<T> {
pub fn new(model: impl Into<String>, messages: Vec<Message>, extra_params: T) -> Self {
Self {
model: model.into(),
messages,
extra_params,
structured_output: None,
tools: None,
validate_structured: true,
fallback_on_failure: false,
}
}
#[must_use]
pub fn with_structured_output(
mut self,
config: JsonSchemaConfig,
validate: bool,
fallback: bool,
) -> Self {
self.structured_output = Some(ResponseFormatConfig {
format_type: "json_schema".to_string(),
json_schema: config,
});
self.validate_structured = validate;
self.fallback_on_failure = fallback;
self
}
#[must_use]
pub fn with_tools(mut self, tools: Vec<Tool>) -> Self {
self.tools = Some(tools);
self
}
#[must_use]
pub fn build(self) -> RequestPayload<T> {
RequestPayload {
model: self.model,
messages: self.messages,
response_format: self.structured_output,
tools: self.tools,
extra_params: self.extra_params,
}
}
}
impl RequestBuilder<Value> {
#[must_use = "returns the updated builder that should be used for constructing the request"]
pub fn with_provider_preferences(
mut self,
preferences: crate::models::provider_preferences::ProviderPreferences,
) -> Result<Self, crate::error::Error> {
preferences.validate()?;
let provider_value =
serde_json::to_value(preferences).map_err(crate::error::Error::SerializationError)?;
if let Value::Object(ref mut map) = self.extra_params {
map.insert("provider".to_string(), provider_value);
}
Ok(self)
}
}