1use reqwest::Method;
6
7use crate::client::Client;
8use crate::error::OpenAIError;
9use crate::pagination::List;
10use crate::request::RequestOptions;
11use crate::streaming::EventStream;
12use crate::types::responses::{CreateResponseRequest, Response, ResponseIncludable, ResponseItem, ResponseStreamEvent};
13
14#[derive(Debug, Clone, Default)]
16pub struct RetrieveParams {
17 pub include: Option<Vec<ResponseIncludable>>,
18 pub include_obfuscation: Option<bool>,
19}
20
21impl RetrieveParams {
22 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn include(mut self, include: Vec<ResponseIncludable>) -> Self {
27 self.include = Some(include);
28 self
29 }
30
31 pub fn include_obfuscation(mut self, include_obfuscation: bool) -> Self {
32 self.include_obfuscation = Some(include_obfuscation);
33 self
34 }
35
36 fn to_query(&self) -> Vec<(String, String)> {
37 let mut query = Vec::new();
38 if let Some(include) = &self.include {
39 for item in include {
40 query.push(("include[]".into(), item.as_str().to_string()));
41 }
42 }
43 if let Some(include_obfuscation) = self.include_obfuscation {
44 query.push(("include_obfuscation".into(), include_obfuscation.to_string()));
45 }
46 query
47 }
48}
49
50#[derive(Debug, Clone, Default)]
52pub struct InputItemsListParams {
53 pub after: Option<String>,
54 pub before: Option<String>,
55 pub limit: Option<u32>,
56 pub order: Option<String>,
57 pub include: Option<Vec<ResponseIncludable>>,
58}
59
60impl InputItemsListParams {
61 pub fn new() -> Self {
62 Self::default()
63 }
64
65 pub fn after(mut self, after: impl Into<String>) -> Self {
66 self.after = Some(after.into());
67 self
68 }
69
70 pub fn limit(mut self, limit: u32) -> Self {
71 self.limit = Some(limit);
72 self
73 }
74
75 pub fn order(mut self, order: impl Into<String>) -> Self {
77 self.order = Some(order.into());
78 self
79 }
80
81 pub fn include(mut self, include: Vec<ResponseIncludable>) -> Self {
82 self.include = Some(include);
83 self
84 }
85
86 fn to_query(&self) -> Vec<(String, String)> {
87 let mut query = crate::pagination::cursor_query(
88 self.after.as_deref(),
89 self.before.as_deref(),
90 self.limit,
91 self.order.as_deref(),
92 );
93 if let Some(include) = &self.include {
94 for item in include {
95 query.push(("include[]".into(), item.as_str().to_string()));
96 }
97 }
98 query
99 }
100}
101
102#[derive(Debug, Clone)]
104pub struct Responses {
105 client: Client,
106}
107
108impl Responses {
109 pub(crate) fn new(client: Client) -> Self {
110 Self { client }
111 }
112
113 pub async fn create(&self, mut request: CreateResponseRequest) -> Result<Response, OpenAIError> {
115 request.stream = None;
116 let body = serde_json::to_value(&request)?;
117 self.client
118 .execute(Method::POST, "/responses", RequestOptions::json(body))
119 .await
120 }
121
122 pub async fn create_stream(
124 &self,
125 mut request: CreateResponseRequest,
126 ) -> Result<EventStream<ResponseStreamEvent>, OpenAIError> {
127 request.stream = Some(true);
128 let body = serde_json::to_value(&request)?;
129 let response = self
130 .client
131 .execute_raw(Method::POST, "/responses", RequestOptions::json(body))
132 .await?;
133 Ok(EventStream::new(response))
134 }
135
136 pub async fn retrieve(
138 &self,
139 response_id: &str,
140 params: Option<RetrieveParams>,
141 ) -> Result<Response, OpenAIError> {
142 let query = params.map(|p| p.to_query()).unwrap_or_default();
143 self.client
144 .execute(
145 Method::GET,
146 &format!("/responses/{response_id}"),
147 RequestOptions::query(query),
148 )
149 .await
150 }
151
152 pub async fn retrieve_stream(
155 &self,
156 response_id: &str,
157 starting_after: Option<u64>,
158 ) -> Result<EventStream<ResponseStreamEvent>, OpenAIError> {
159 let mut query = vec![("stream".to_string(), "true".to_string())];
160 if let Some(starting_after) = starting_after {
161 query.push(("starting_after".to_string(), starting_after.to_string()));
162 }
163 let response = self
164 .client
165 .execute_raw(
166 Method::GET,
167 &format!("/responses/{response_id}"),
168 RequestOptions::query(query),
169 )
170 .await?;
171 Ok(EventStream::new(response))
172 }
173
174 pub async fn delete(&self, response_id: &str) -> Result<(), OpenAIError> {
176 self.client
177 .execute_no_content(
178 Method::DELETE,
179 &format!("/responses/{response_id}"),
180 RequestOptions::default(),
181 )
182 .await
183 }
184
185 pub async fn cancel(&self, response_id: &str) -> Result<Response, OpenAIError> {
187 self.client
188 .execute(
189 Method::POST,
190 &format!("/responses/{response_id}/cancel"),
191 RequestOptions::default(),
192 )
193 .await
194 }
195
196 pub fn input_items(&self, response_id: impl Into<String>) -> ResponseInputItems {
198 ResponseInputItems {
199 client: self.client.clone(),
200 response_id: response_id.into(),
201 }
202 }
203}
204
205#[derive(Debug, Clone)]
208pub struct ResponseInputItems {
209 client: Client,
210 response_id: String,
211}
212
213impl ResponseInputItems {
214 pub async fn list(
216 &self,
217 params: Option<InputItemsListParams>,
218 ) -> Result<List<ResponseItem>, OpenAIError> {
219 let query = params.map(|p| p.to_query()).unwrap_or_default();
220 self.client
221 .execute(
222 Method::GET,
223 &format!("/responses/{}/input_items", self.response_id),
224 RequestOptions::query(query),
225 )
226 .await
227 }
228
229 pub async fn list_all(
231 &self,
232 params: Option<InputItemsListParams>,
233 ) -> Result<Vec<ResponseItem>, OpenAIError> {
234 let query = params.map(|p| p.to_query()).unwrap_or_default();
235 self.client
236 .paginate_all(
237 &format!("/responses/{}/input_items", self.response_id),
238 query,
239 )
240 .await
241 }
242}