1use std::future::Future;
2
3use crate::model::{
4 CreateRunRequest, ListRunStepsResponse, ListRunsResponse, ModifyRunRequest, PaginationParams,
5 Run, RunStep, SubmitToolOutputsRequest,
6};
7use crate::{PortkeyClient, Result};
8
9pub trait RunsService {
37 fn create_run(
39 &self,
40 thread_id: &str,
41 request: CreateRunRequest,
42 ) -> impl Future<Output = Result<Run>>;
43
44 fn retrieve_run(&self, thread_id: &str, run_id: &str) -> impl Future<Output = Result<Run>>;
46
47 fn modify_run(
49 &self,
50 thread_id: &str,
51 run_id: &str,
52 request: ModifyRunRequest,
53 ) -> impl Future<Output = Result<Run>>;
54
55 fn list_runs(
57 &self,
58 thread_id: &str,
59 params: PaginationParams,
60 ) -> impl Future<Output = Result<ListRunsResponse>>;
61
62 fn submit_tool_outputs(
65 &self,
66 thread_id: &str,
67 run_id: &str,
68 request: SubmitToolOutputsRequest,
69 ) -> impl Future<Output = Result<Run>>;
70
71 fn cancel_run(&self, thread_id: &str, run_id: &str) -> impl Future<Output = Result<Run>>;
73
74 fn create_thread_and_run(&self, request: CreateRunRequest)
76 -> impl Future<Output = Result<Run>>;
77
78 fn retrieve_run_step(
80 &self,
81 thread_id: &str,
82 run_id: &str,
83 step_id: &str,
84 ) -> impl Future<Output = Result<RunStep>>;
85
86 fn list_run_steps(
88 &self,
89 thread_id: &str,
90 run_id: &str,
91 params: PaginationParams,
92 ) -> impl Future<Output = Result<ListRunStepsResponse>>;
93}
94
95impl RunsService for PortkeyClient {
96 async fn create_run(&self, thread_id: &str, request: CreateRunRequest) -> Result<Run> {
97 #[cfg(feature = "tracing")]
98 tracing::debug!(
99 target: crate::TRACING_TARGET_SERVICE,
100 thread_id = %thread_id,
101 "Creating run"
102 );
103
104 let response = self
105 .send_json(
106 reqwest::Method::POST,
107 &format!("/threads/{}/runs", thread_id),
108 &request,
109 )
110 .await?;
111 let response = response.error_for_status()?;
112 let run: Run = response.json().await?;
113
114 #[cfg(feature = "tracing")]
115 tracing::debug!(
116 target: crate::TRACING_TARGET_SERVICE,
117 "Run created successfully"
118 );
119
120 Ok(run)
121 }
122
123 async fn retrieve_run(&self, thread_id: &str, run_id: &str) -> Result<Run> {
124 #[cfg(feature = "tracing")]
125 tracing::debug!(
126 target: crate::TRACING_TARGET_SERVICE,
127 thread_id = %thread_id,
128 run_id = %run_id,
129 "Retrieving run"
130 );
131
132 let response = self
133 .send(
134 reqwest::Method::GET,
135 &format!("/threads/{}/runs/{}", thread_id, run_id),
136 )
137 .await?;
138 let response = response.error_for_status()?;
139 let run: Run = response.json().await?;
140
141 #[cfg(feature = "tracing")]
142 tracing::debug!(
143 target: crate::TRACING_TARGET_SERVICE,
144 "Run retrieved successfully"
145 );
146
147 Ok(run)
148 }
149
150 async fn modify_run(
151 &self,
152 thread_id: &str,
153 run_id: &str,
154 request: ModifyRunRequest,
155 ) -> Result<Run> {
156 #[cfg(feature = "tracing")]
157 tracing::debug!(
158 target: crate::TRACING_TARGET_SERVICE,
159 thread_id = %thread_id,
160 run_id = %run_id,
161 "Modifying run"
162 );
163
164 let response = self
165 .send_json(
166 reqwest::Method::POST,
167 &format!("/threads/{}/runs/{}", thread_id, run_id),
168 &request,
169 )
170 .await?;
171 let response = response.error_for_status()?;
172 let run: Run = response.json().await?;
173
174 #[cfg(feature = "tracing")]
175 tracing::debug!(
176 target: crate::TRACING_TARGET_SERVICE,
177 "Run modified successfully"
178 );
179
180 Ok(run)
181 }
182
183 async fn list_runs(
184 &self,
185 thread_id: &str,
186 params: PaginationParams<'_>,
187 ) -> Result<ListRunsResponse> {
188 #[cfg(feature = "tracing")]
189 tracing::debug!(
190 target: crate::TRACING_TARGET_SERVICE,
191 thread_id = %thread_id,
192 "Listing runs"
193 );
194
195 let query_params = params.to_query_params();
196 let query_params_refs: Vec<(&str, &str)> =
197 query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
198
199 let response = self
200 .send_with_params(
201 reqwest::Method::GET,
202 &format!("/threads/{}/runs", thread_id),
203 &query_params_refs,
204 )
205 .await?;
206 let response = response.error_for_status()?;
207 let runs: ListRunsResponse = response.json().await?;
208
209 #[cfg(feature = "tracing")]
210 tracing::debug!(
211 target: crate::TRACING_TARGET_SERVICE,
212 "Runs retrieved successfully"
213 );
214
215 Ok(runs)
216 }
217
218 async fn submit_tool_outputs(
219 &self,
220 thread_id: &str,
221 run_id: &str,
222 request: SubmitToolOutputsRequest,
223 ) -> Result<Run> {
224 #[cfg(feature = "tracing")]
225 tracing::debug!(
226 target: crate::TRACING_TARGET_SERVICE,
227 thread_id = %thread_id,
228 run_id = %run_id,
229 "Submitting tool outputs"
230 );
231
232 let response = self
233 .send_json(
234 reqwest::Method::POST,
235 &format!("/threads/{}/runs/{}/submit_tool_outputs", thread_id, run_id),
236 &request,
237 )
238 .await?;
239 let response = response.error_for_status()?;
240 let run: Run = response.json().await?;
241
242 #[cfg(feature = "tracing")]
243 tracing::debug!(
244 target: crate::TRACING_TARGET_SERVICE,
245 "Tool outputs submitted successfully"
246 );
247
248 Ok(run)
249 }
250
251 async fn cancel_run(&self, thread_id: &str, run_id: &str) -> Result<Run> {
252 #[cfg(feature = "tracing")]
253 tracing::debug!(
254 target: crate::TRACING_TARGET_SERVICE,
255 thread_id = %thread_id,
256 run_id = %run_id,
257 "Cancelling run"
258 );
259
260 let response = self
261 .send_json(
262 reqwest::Method::POST,
263 &format!("/threads/{}/runs/{}/cancel", thread_id, run_id),
264 &serde_json::json!({}),
265 )
266 .await?;
267 let response = response.error_for_status()?;
268 let run: Run = response.json().await?;
269
270 #[cfg(feature = "tracing")]
271 tracing::debug!(
272 target: crate::TRACING_TARGET_SERVICE,
273 "Run cancelled successfully"
274 );
275
276 Ok(run)
277 }
278
279 async fn create_thread_and_run(&self, request: CreateRunRequest) -> Result<Run> {
280 #[cfg(feature = "tracing")]
281 tracing::debug!(
282 target: crate::TRACING_TARGET_SERVICE,
283 "Creating thread and run"
284 );
285
286 let response = self
287 .send_json(reqwest::Method::POST, "/threads/runs", &request)
288 .await?;
289 let response = response.error_for_status()?;
290 let run: Run = response.json().await?;
291
292 #[cfg(feature = "tracing")]
293 tracing::debug!(
294 target: crate::TRACING_TARGET_SERVICE,
295 "Thread and run created successfully"
296 );
297
298 Ok(run)
299 }
300
301 async fn retrieve_run_step(
302 &self,
303 thread_id: &str,
304 run_id: &str,
305 step_id: &str,
306 ) -> Result<RunStep> {
307 #[cfg(feature = "tracing")]
308 tracing::debug!(
309 target: crate::TRACING_TARGET_SERVICE,
310 thread_id = %thread_id,
311 run_id = %run_id,
312 step_id = %step_id,
313 "Retrieving run step"
314 );
315
316 let response = self
317 .send(
318 reqwest::Method::GET,
319 &format!("/threads/{}/runs/{}/steps/{}", thread_id, run_id, step_id),
320 )
321 .await?;
322 let response = response.error_for_status()?;
323 let step: RunStep = response.json().await?;
324
325 #[cfg(feature = "tracing")]
326 tracing::debug!(
327 target: crate::TRACING_TARGET_SERVICE,
328 "Run step retrieved successfully"
329 );
330
331 Ok(step)
332 }
333
334 async fn list_run_steps(
335 &self,
336 thread_id: &str,
337 run_id: &str,
338 params: PaginationParams<'_>,
339 ) -> Result<ListRunStepsResponse> {
340 #[cfg(feature = "tracing")]
341 tracing::debug!(
342 target: crate::TRACING_TARGET_SERVICE,
343 thread_id = %thread_id,
344 run_id = %run_id,
345 "Listing run steps"
346 );
347
348 let query_params = params.to_query_params();
349 let query_params_refs: Vec<(&str, &str)> =
350 query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
351
352 let response = self
353 .send_with_params(
354 reqwest::Method::GET,
355 &format!("/threads/{}/runs/{}/steps", thread_id, run_id),
356 &query_params_refs,
357 )
358 .await?;
359 let response = response.error_for_status()?;
360 let steps: ListRunStepsResponse = response.json().await?;
361
362 #[cfg(feature = "tracing")]
363 tracing::debug!(
364 target: crate::TRACING_TARGET_SERVICE,
365 "Run steps retrieved successfully"
366 );
367
368 Ok(steps)
369 }
370}