1use crate::{
2 assistants::Steps,
3 config::Config,
4 error::OpenAIError,
5 types::assistants::{
6 CreateRunRequest, ListRunsResponse, ModifyRunRequest, RunObject,
7 SubmitToolOutputsRunRequest,
8 },
9 Client, RequestOptions,
10};
11
12use crate::types::assistants::AssistantEventStream;
13
14#[deprecated(
18 note = "Assistants API is deprecated and will be removed in August 2026. Use the Responses API."
19)]
20pub struct Runs<'c, C: Config> {
21 pub thread_id: String,
22 client: &'c Client<C>,
23 pub(crate) request_options: RequestOptions,
24}
25
26impl<'c, C: Config> Runs<'c, C> {
27 pub fn new(client: &'c Client<C>, thread_id: &str) -> Self {
28 Self {
29 client,
30 thread_id: thread_id.into(),
31 request_options: RequestOptions::new(),
32 }
33 }
34
35 pub fn steps(&self, run_id: &str) -> Steps<'_, C> {
37 Steps::new(self.client, &self.thread_id, run_id)
38 }
39
40 #[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
42 pub async fn create(&self, request: CreateRunRequest) -> Result<RunObject, OpenAIError> {
43 self.client
44 .post(
45 &format!("/threads/{}/runs", self.thread_id),
46 request,
47 &self.request_options,
48 )
49 .await
50 }
51
52 #[crate::byot(
56 T0 = serde::Serialize,
57 R = serde::de::DeserializeOwned,
58 stream = "true",
59 where_clause = "R: crate::traits::MaybeSend + 'static + TryFrom<eventsource_stream::Event, Error = OpenAIError>"
60 )]
61 #[allow(unused_mut)]
62 pub async fn create_stream(
63 &self,
64 mut request: CreateRunRequest,
65 ) -> Result<AssistantEventStream, OpenAIError> {
66 #[cfg(not(feature = "byot"))]
67 {
68 if request.stream.is_some() && !request.stream.unwrap() {
69 return Err(OpenAIError::InvalidArgument(
70 "When stream is false, use Runs::create".into(),
71 ));
72 }
73
74 request.stream = Some(true);
75 }
76
77 self.client
78 .post_stream_mapped_raw_events(
79 &format!("/threads/{}/runs", self.thread_id),
80 request,
81 &self.request_options,
82 TryFrom::try_from,
83 )
84 .await
85 }
86
87 #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
89 pub async fn retrieve(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
90 self.client
91 .get(
92 &format!("/threads/{}/runs/{run_id}", self.thread_id),
93 &self.request_options,
94 )
95 .await
96 }
97
98 #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
100 pub async fn update(
101 &self,
102 run_id: &str,
103 request: ModifyRunRequest,
104 ) -> Result<RunObject, OpenAIError> {
105 self.client
106 .post(
107 &format!("/threads/{}/runs/{run_id}", self.thread_id),
108 request,
109 &self.request_options,
110 )
111 .await
112 }
113
114 #[crate::byot(R = serde::de::DeserializeOwned)]
116 pub async fn list(&self) -> Result<ListRunsResponse, OpenAIError> {
117 self.client
118 .get(
119 &format!("/threads/{}/runs", self.thread_id),
120 &self.request_options,
121 )
122 .await
123 }
124
125 #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
127 pub async fn submit_tool_outputs(
128 &self,
129 run_id: &str,
130 request: SubmitToolOutputsRunRequest,
131 ) -> Result<RunObject, OpenAIError> {
132 self.client
133 .post(
134 &format!(
135 "/threads/{}/runs/{run_id}/submit_tool_outputs",
136 self.thread_id
137 ),
138 request,
139 &self.request_options,
140 )
141 .await
142 }
143
144 #[crate::byot(
146 T0 = std::fmt::Display,
147 T1 = serde::Serialize,
148 R = serde::de::DeserializeOwned,
149 stream = "true",
150 where_clause = "R: crate::traits::MaybeSend + 'static + TryFrom<eventsource_stream::Event, Error = OpenAIError>"
151 )]
152 #[allow(unused_mut)]
153 pub async fn submit_tool_outputs_stream(
154 &self,
155 run_id: &str,
156 mut request: SubmitToolOutputsRunRequest,
157 ) -> Result<AssistantEventStream, OpenAIError> {
158 #[cfg(not(feature = "byot"))]
159 {
160 if request.stream.is_some() && !request.stream.unwrap() {
161 return Err(OpenAIError::InvalidArgument(
162 "When stream is false, use Runs::submit_tool_outputs".into(),
163 ));
164 }
165
166 request.stream = Some(true);
167 }
168
169 self.client
170 .post_stream_mapped_raw_events(
171 &format!(
172 "/threads/{}/runs/{run_id}/submit_tool_outputs",
173 self.thread_id
174 ),
175 request,
176 &self.request_options,
177 TryFrom::try_from,
178 )
179 .await
180 }
181
182 #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
184 pub async fn cancel(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
185 self.client
186 .post(
187 &format!("/threads/{}/runs/{run_id}/cancel", self.thread_id),
188 (),
189 &self.request_options,
190 )
191 .await
192 }
193}