Skip to main content

async_openai/assistants/
runs.rs

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
12#[cfg(not(target_family = "wasm"))]
13use crate::types::assistants::AssistantEventStream;
14
15/// Represents an execution run on a thread.
16///
17/// Related guide: [Assistants](https://platform.openai.com/docs/assistants/overview)
18#[deprecated(
19    note = "Assistants API is deprecated and will be removed in August 2026. Use the Responses API."
20)]
21pub struct Runs<'c, C: Config> {
22    pub thread_id: String,
23    client: &'c Client<C>,
24    pub(crate) request_options: RequestOptions,
25}
26
27impl<'c, C: Config> Runs<'c, C> {
28    pub fn new(client: &'c Client<C>, thread_id: &str) -> Self {
29        Self {
30            client,
31            thread_id: thread_id.into(),
32            request_options: RequestOptions::new(),
33        }
34    }
35
36    ///  [Steps] API group
37    pub fn steps(&self, run_id: &str) -> Steps<'_, C> {
38        Steps::new(self.client, &self.thread_id, run_id)
39    }
40
41    /// Create a run.
42    #[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
43    pub async fn create(&self, request: CreateRunRequest) -> Result<RunObject, OpenAIError> {
44        self.client
45            .post(
46                &format!("/threads/{}/runs", self.thread_id),
47                request,
48                &self.request_options,
49            )
50            .await
51    }
52
53    /// Create a run.
54    ///
55    /// byot: You must ensure "stream: true" in serialized `request`
56    #[cfg(not(target_family = "wasm"))]
57    #[crate::byot(
58        T0 = serde::Serialize,
59        R = serde::de::DeserializeOwned,
60        stream = "true",
61        where_clause = "R: std::marker::Send + 'static + TryFrom<eventsource_stream::Event, Error = OpenAIError>"
62    )]
63    #[allow(unused_mut)]
64    pub async fn create_stream(
65        &self,
66        mut request: CreateRunRequest,
67    ) -> Result<AssistantEventStream, OpenAIError> {
68        #[cfg(not(feature = "byot"))]
69        {
70            if request.stream.is_some() && !request.stream.unwrap() {
71                return Err(OpenAIError::InvalidArgument(
72                    "When stream is false, use Runs::create".into(),
73                ));
74            }
75
76            request.stream = Some(true);
77        }
78
79        self.client
80            .post_stream_mapped_raw_events(
81                &format!("/threads/{}/runs", self.thread_id),
82                request,
83                &self.request_options,
84                TryFrom::try_from,
85            )
86            .await
87    }
88
89    /// Retrieves a run.
90    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
91    pub async fn retrieve(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
92        self.client
93            .get(
94                &format!("/threads/{}/runs/{run_id}", self.thread_id),
95                &self.request_options,
96            )
97            .await
98    }
99
100    /// Modifies a run.
101    #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
102    pub async fn update(
103        &self,
104        run_id: &str,
105        request: ModifyRunRequest,
106    ) -> Result<RunObject, OpenAIError> {
107        self.client
108            .post(
109                &format!("/threads/{}/runs/{run_id}", self.thread_id),
110                request,
111                &self.request_options,
112            )
113            .await
114    }
115
116    /// Returns a list of runs belonging to a thread.
117    #[crate::byot(R = serde::de::DeserializeOwned)]
118    pub async fn list(&self) -> Result<ListRunsResponse, OpenAIError> {
119        self.client
120            .get(
121                &format!("/threads/{}/runs", self.thread_id),
122                &self.request_options,
123            )
124            .await
125    }
126
127    /// When a run has the status: "requires_action" and required_action.type is submit_tool_outputs, this endpoint can be used to submit the outputs from the tool calls once they're all completed. All outputs must be submitted in a single request.
128    #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
129    pub async fn submit_tool_outputs(
130        &self,
131        run_id: &str,
132        request: SubmitToolOutputsRunRequest,
133    ) -> Result<RunObject, OpenAIError> {
134        self.client
135            .post(
136                &format!(
137                    "/threads/{}/runs/{run_id}/submit_tool_outputs",
138                    self.thread_id
139                ),
140                request,
141                &self.request_options,
142            )
143            .await
144    }
145
146    /// byot: You must ensure "stream: true" in serialized `request`
147    #[cfg(not(target_family = "wasm"))]
148    #[crate::byot(
149        T0 = std::fmt::Display,
150        T1 = serde::Serialize,
151        R = serde::de::DeserializeOwned,
152        stream = "true",
153        where_clause = "R: std::marker::Send + 'static + TryFrom<eventsource_stream::Event, Error = OpenAIError>"
154    )]
155    #[allow(unused_mut)]
156    pub async fn submit_tool_outputs_stream(
157        &self,
158        run_id: &str,
159        mut request: SubmitToolOutputsRunRequest,
160    ) -> Result<AssistantEventStream, OpenAIError> {
161        #[cfg(not(feature = "byot"))]
162        {
163            if request.stream.is_some() && !request.stream.unwrap() {
164                return Err(OpenAIError::InvalidArgument(
165                    "When stream is false, use Runs::submit_tool_outputs".into(),
166                ));
167            }
168
169            request.stream = Some(true);
170        }
171
172        self.client
173            .post_stream_mapped_raw_events(
174                &format!(
175                    "/threads/{}/runs/{run_id}/submit_tool_outputs",
176                    self.thread_id
177                ),
178                request,
179                &self.request_options,
180                TryFrom::try_from,
181            )
182            .await
183    }
184
185    /// Cancels a run that is `in_progress`
186    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
187    pub async fn cancel(&self, run_id: &str) -> Result<RunObject, OpenAIError> {
188        self.client
189            .post(
190                &format!("/threads/{}/runs/{run_id}/cancel", self.thread_id),
191                (),
192                &self.request_options,
193            )
194            .await
195    }
196}