use reqwest::Method;
use crate::client::Client;
use crate::error::OpenAIError;
use crate::pagination::List;
use crate::request::RequestOptions;
use crate::streaming::EventStream;
use crate::types::responses::{CreateResponseRequest, Response, ResponseIncludable, ResponseItem, ResponseStreamEvent};
#[derive(Debug, Clone, Default)]
pub struct RetrieveParams {
pub include: Option<Vec<ResponseIncludable>>,
pub include_obfuscation: Option<bool>,
}
impl RetrieveParams {
pub fn new() -> Self {
Self::default()
}
pub fn include(mut self, include: Vec<ResponseIncludable>) -> Self {
self.include = Some(include);
self
}
pub fn include_obfuscation(mut self, include_obfuscation: bool) -> Self {
self.include_obfuscation = Some(include_obfuscation);
self
}
fn to_query(&self) -> Vec<(String, String)> {
let mut query = Vec::new();
if let Some(include) = &self.include {
for item in include {
query.push(("include[]".into(), item.as_str().to_string()));
}
}
if let Some(include_obfuscation) = self.include_obfuscation {
query.push(("include_obfuscation".into(), include_obfuscation.to_string()));
}
query
}
}
#[derive(Debug, Clone, Default)]
pub struct InputItemsListParams {
pub after: Option<String>,
pub before: Option<String>,
pub limit: Option<u32>,
pub order: Option<String>,
pub include: Option<Vec<ResponseIncludable>>,
}
impl InputItemsListParams {
pub fn new() -> Self {
Self::default()
}
pub fn after(mut self, after: impl Into<String>) -> Self {
self.after = Some(after.into());
self
}
pub fn limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
pub fn order(mut self, order: impl Into<String>) -> Self {
self.order = Some(order.into());
self
}
pub fn include(mut self, include: Vec<ResponseIncludable>) -> Self {
self.include = Some(include);
self
}
fn to_query(&self) -> Vec<(String, String)> {
let mut query = crate::pagination::cursor_query(
self.after.as_deref(),
self.before.as_deref(),
self.limit,
self.order.as_deref(),
);
if let Some(include) = &self.include {
for item in include {
query.push(("include[]".into(), item.as_str().to_string()));
}
}
query
}
}
#[derive(Debug, Clone)]
pub struct Responses {
client: Client,
}
impl Responses {
pub(crate) fn new(client: Client) -> Self {
Self { client }
}
pub async fn create(&self, mut request: CreateResponseRequest) -> Result<Response, OpenAIError> {
request.stream = None;
let body = serde_json::to_value(&request)?;
self.client
.execute(Method::POST, "/responses", RequestOptions::json(body))
.await
}
pub async fn create_stream(
&self,
mut request: CreateResponseRequest,
) -> Result<EventStream<ResponseStreamEvent>, OpenAIError> {
request.stream = Some(true);
let body = serde_json::to_value(&request)?;
let response = self
.client
.execute_raw(Method::POST, "/responses", RequestOptions::json(body))
.await?;
Ok(EventStream::new(response))
}
pub async fn retrieve(
&self,
response_id: &str,
params: Option<RetrieveParams>,
) -> Result<Response, OpenAIError> {
let query = params.map(|p| p.to_query()).unwrap_or_default();
self.client
.execute(
Method::GET,
&format!("/responses/{response_id}"),
RequestOptions::query(query),
)
.await
}
pub async fn retrieve_stream(
&self,
response_id: &str,
starting_after: Option<u64>,
) -> Result<EventStream<ResponseStreamEvent>, OpenAIError> {
let mut query = vec![("stream".to_string(), "true".to_string())];
if let Some(starting_after) = starting_after {
query.push(("starting_after".to_string(), starting_after.to_string()));
}
let response = self
.client
.execute_raw(
Method::GET,
&format!("/responses/{response_id}"),
RequestOptions::query(query),
)
.await?;
Ok(EventStream::new(response))
}
pub async fn delete(&self, response_id: &str) -> Result<(), OpenAIError> {
self.client
.execute_no_content(
Method::DELETE,
&format!("/responses/{response_id}"),
RequestOptions::default(),
)
.await
}
pub async fn cancel(&self, response_id: &str) -> Result<Response, OpenAIError> {
self.client
.execute(
Method::POST,
&format!("/responses/{response_id}/cancel"),
RequestOptions::default(),
)
.await
}
pub fn input_items(&self, response_id: impl Into<String>) -> ResponseInputItems {
ResponseInputItems {
client: self.client.clone(),
response_id: response_id.into(),
}
}
}
#[derive(Debug, Clone)]
pub struct ResponseInputItems {
client: Client,
response_id: String,
}
impl ResponseInputItems {
pub async fn list(
&self,
params: Option<InputItemsListParams>,
) -> Result<List<ResponseItem>, OpenAIError> {
let query = params.map(|p| p.to_query()).unwrap_or_default();
self.client
.execute(
Method::GET,
&format!("/responses/{}/input_items", self.response_id),
RequestOptions::query(query),
)
.await
}
pub async fn list_all(
&self,
params: Option<InputItemsListParams>,
) -> Result<Vec<ResponseItem>, OpenAIError> {
let query = params.map(|p| p.to_query()).unwrap_or_default();
self.client
.paginate_all(
&format!("/responses/{}/input_items", self.response_id),
query,
)
.await
}
}