1use serde::Serialize;
2
3use crate::{
4 config::Config,
5 error::OpenAIError,
6 steps::Steps,
7 types::{
8 AssistantEventStream, AssistantStreamEvent, CreateRunRequest, ListRunsResponse,
9 ModifyRunRequest, RunObject, SubmitToolOutputsRunRequest,
10 },
11 Client,
12};
13
14pub struct Runs<'c, C: Config> {
18 pub thread_id: String,
19 client: &'c Client<C>,
20}
21
22impl<'c, C: Config> Runs<'c, C> {
23 pub fn new(client: &'c Client<C>, thread_id: &str) -> Self {
24 Self {
25 client,
26 thread_id: thread_id.into(),
27 }
28 }
29
30 pub fn steps(&self, run_id: &str) -> Steps<C> {
32 Steps::new(self.client, &self.thread_id, run_id)
33 }
34
35 pub async fn create(&self, request: CreateRunRequest) -> Result<RunObject, OpenAIError> {
37 self.client
38 .post(&format!("/threads/{}/runs", self.thread_id), request)
39 .await
40 }
41
42 pub async fn create_stream(
44 &self,
45 mut request: CreateRunRequest,
46 ) -> Result<AssistantEventStream, OpenAIError> {
47 if request.stream.is_some() && !request.stream.unwrap() {
48 return Err(OpenAIError::InvalidArgument(
49 "When stream is false, use Runs::create".into(),
50 ));
51 }
52
53 request.stream = Some(true);
54
55 Ok(self
56 .client
57 .post_stream_mapped_raw_events(
58 &format!("/threads/{}/runs", self.thread_id),
59 request,
60 AssistantStreamEvent::try_from,
61 )
62 .await)
63 }
64
65 pub async fn retrieve(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
67 self.client
68 .get(&format!("/threads/{}/runs/{run_id}", self.thread_id))
69 .await
70 }
71
72 pub async fn update(
74 &self,
75 run_id: &str,
76 request: ModifyRunRequest,
77 ) -> Result<RunObject, OpenAIError> {
78 self.client
79 .post(
80 &format!("/threads/{}/runs/{run_id}", self.thread_id),
81 request,
82 )
83 .await
84 }
85
86 pub async fn list<Q>(&self, query: &Q) -> Result<ListRunsResponse, OpenAIError>
88 where
89 Q: Serialize + ?Sized,
90 {
91 self.client
92 .get_with_query(&format!("/threads/{}/runs", self.thread_id), query)
93 .await
94 }
95
96 pub async fn submit_tool_outputs(
98 &self,
99 run_id: &str,
100 request: SubmitToolOutputsRunRequest,
101 ) -> Result<RunObject, OpenAIError> {
102 self.client
103 .post(
104 &format!(
105 "/threads/{}/runs/{run_id}/submit_tool_outputs",
106 self.thread_id
107 ),
108 request,
109 )
110 .await
111 }
112
113 pub async fn submit_tool_outputs_stream(
114 &self,
115 run_id: &str,
116 mut request: SubmitToolOutputsRunRequest,
117 ) -> Result<AssistantEventStream, OpenAIError> {
118 if request.stream.is_some() && !request.stream.unwrap() {
119 return Err(OpenAIError::InvalidArgument(
120 "When stream is false, use Runs::submit_tool_outputs".into(),
121 ));
122 }
123
124 request.stream = Some(true);
125
126 Ok(self
127 .client
128 .post_stream_mapped_raw_events(
129 &format!(
130 "/threads/{}/runs/{run_id}/submit_tool_outputs",
131 self.thread_id
132 ),
133 request,
134 AssistantStreamEvent::try_from,
135 )
136 .await)
137 }
138
139 pub async fn cancel(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
141 self.client
142 .post(
143 &format!("/threads/{}/runs/{run_id}/cancel", self.thread_id),
144 (),
145 )
146 .await
147 }
148}