Skip to main content

novel_openai/assistants/
threads.rs

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