Skip to main content

async_openai/assistants/
threads.rs

1use crate::{
2    config::Config,
3    error::OpenAIError,
4    types::assistants::{
5        CreateThreadAndRunRequest, CreateThreadRequest, DeleteThreadResponse, ModifyThreadRequest,
6        RunObject, ThreadObject,
7    },
8    Client, Messages, RequestOptions, Runs,
9};
10
11use crate::types::assistants::AssistantEventStream;
12
13/// Create threads that assistants can interact with.
14///
15/// Related guide: [Assistants](https://platform.openai.com/docs/assistants/overview)
16#[deprecated(
17    note = "Assistants API is deprecated and will be removed in August 2026. Use the Responses API."
18)]
19pub struct Threads<'c, C: Config> {
20    client: &'c Client<C>,
21    pub(crate) request_options: RequestOptions,
22}
23
24impl<'c, C: Config> Threads<'c, C> {
25    pub fn new(client: &'c Client<C>) -> Self {
26        Self {
27            client,
28            request_options: RequestOptions::new(),
29        }
30    }
31
32    /// Call [Messages] group API to manage message in `thread_id` thread.
33    pub fn messages(&self, thread_id: &str) -> Messages<'_, C> {
34        Messages::new(self.client, thread_id)
35    }
36
37    /// Call [Runs] group API to manage runs in `thread_id` thread.
38    pub fn runs(&self, thread_id: &str) -> Runs<'_, C> {
39        Runs::new(self.client, thread_id)
40    }
41
42    /// Create a thread and run it in one request.
43    #[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
44    pub async fn create_and_run(
45        &self,
46        request: CreateThreadAndRunRequest,
47    ) -> Result<RunObject, OpenAIError> {
48        self.client
49            .post("/threads/runs", request, &self.request_options)
50            .await
51    }
52
53    /// Create a thread and run it in one request (streaming).
54    ///
55    /// byot: You must ensure "stream: true" in serialized `request`
56    #[crate::byot(
57        T0 = serde::Serialize,
58        R = serde::de::DeserializeOwned,
59        stream = "true",
60        where_clause = "R: crate::traits::MaybeSend + 'static + TryFrom<eventsource_stream::Event, Error = OpenAIError>"
61    )]
62    #[allow(unused_mut)]
63    pub async fn create_and_run_stream(
64        &self,
65        mut request: CreateThreadAndRunRequest,
66    ) -> Result<AssistantEventStream, OpenAIError> {
67        #[cfg(not(feature = "byot"))]
68        {
69            if request.stream.is_some() && !request.stream.unwrap() {
70                return Err(OpenAIError::InvalidArgument(
71                    "When stream is false, use Threads::create_and_run".into(),
72                ));
73            }
74
75            request.stream = Some(true);
76        }
77        self.client
78            .post_stream_mapped_raw_events(
79                "/threads/runs",
80                request,
81                &self.request_options,
82                TryFrom::try_from,
83            )
84            .await
85    }
86
87    /// Create a thread.
88    #[crate::byot(T0 = serde::Serialize, R = serde::de::DeserializeOwned)]
89    pub async fn create(&self, request: CreateThreadRequest) -> Result<ThreadObject, OpenAIError> {
90        self.client
91            .post("/threads", request, &self.request_options)
92            .await
93    }
94
95    /// Retrieves a thread.
96    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
97    pub async fn retrieve(&self, thread_id: &str) -> Result<ThreadObject, OpenAIError> {
98        self.client
99            .get(&format!("/threads/{thread_id}"), &self.request_options)
100            .await
101    }
102
103    /// Modifies a thread.
104    #[crate::byot(T0 = std::fmt::Display, T1 = serde::Serialize, R = serde::de::DeserializeOwned)]
105    pub async fn update(
106        &self,
107        thread_id: &str,
108        request: ModifyThreadRequest,
109    ) -> Result<ThreadObject, OpenAIError> {
110        self.client
111            .post(
112                &format!("/threads/{thread_id}"),
113                request,
114                &self.request_options,
115            )
116            .await
117    }
118
119    /// Delete a thread.
120    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
121    pub async fn delete(&self, thread_id: &str) -> Result<DeleteThreadResponse, OpenAIError> {
122        self.client
123            .delete(&format!("/threads/{thread_id}"), &self.request_options)
124            .await
125    }
126}