use crate::openai::{
endpoint::{endpoint_filter, request_endpoint, Endpoint, EndpointVariant},
types::{common::Error, edit::EditResponse, model::Model},
};
use log::{debug, warn};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
#[serde_as]
#[derive(Serialize, Deserialize, Debug)]
pub struct Edit {
pub model: Model,
#[serde(skip_serializing_if = "Option::is_none")]
pub input: Option<String>,
pub instruction: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub n: Option<u32>,
}
impl Default for Edit {
fn default() -> Self {
Self {
model: Model::TEXT_DAVINCI_EDIT_001,
input: Some(String::from("")),
instruction: String::new(),
temperature: None,
top_p: None,
n: None,
}
}
}
impl Edit {
pub fn model(self, model: Model) -> Self {
Self { model, ..self }
}
pub fn input(self, content: &str) -> Self {
Self {
input: Some(content.into()),
..self
}
}
pub fn instruction(self, content: &str) -> Self {
Self {
instruction: content.into(),
..self
}
}
pub fn temperature(self, temperature: f32) -> Self {
Self {
temperature: Some(temperature),
..self
}
}
pub fn top_p(self, top_p: f32) -> Self {
Self {
top_p: Some(top_p),
..self
}
}
pub fn n(self, n: u32) -> Self {
Self { n: Some(n), ..self }
}
pub async fn edit(self) -> Result<EditResponse, Box<dyn std::error::Error>> {
if !endpoint_filter(&self.model, &Endpoint::Edit_v1) {
return Err("Model not compatible with this endpoint".into());
}
let mut edit_response: Option<EditResponse> = None;
request_endpoint(&self, &Endpoint::Edit_v1, EndpointVariant::None, |res| {
if let Ok(text) = res {
if let Ok(response_data) = serde_json::from_str::<EditResponse>(&text) {
debug!(target: "openai", "Response parsed, edit response deserialized.");
edit_response = Some(response_data);
} else {
if let Ok(response_error) = serde_json::from_str::<Error>(&text) {
warn!(target: "openai",
"OpenAI error code {}: `{:?}`",
response_error.error.code.unwrap_or(0),
text
);
} else {
warn!(target: "openai", "Edit response not deserializable.");
}
}
}
})
.await?;
if let Some(response_data) = edit_response {
Ok(response_data)
} else {
Err("No response or error parsing response".into())
}
}
}