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