portkey_sdk/service/
messages.rs

1use std::future::Future;
2
3use crate::model::{
4    CreateMessageRequest, ListMessageFilesResponse, ListMessagesResponse, Message, MessageFile,
5    ModifyMessageRequest, PaginationParams,
6};
7use crate::{PortkeyClient, Result};
8
9/// Service for managing messages in threads.
10///
11/// # Example
12///
13/// ```no_run
14/// use portkey_sdk::{PortkeyConfig, PortkeyClient, Result};
15/// use portkey_sdk::service::MessagesService;
16/// use portkey_sdk::model::CreateMessageRequest;
17///
18/// # async fn example() -> Result<()> {
19/// let config = PortkeyConfig::builder()
20///     .with_api_key("your-api-key")
21///     .build()?;
22/// let client = PortkeyClient::new(config)?;
23///
24///     let message = client.create_message(
25///         "thread_abc123",
26///         CreateMessageRequest {
27///             role: "user".to_string(),
28///             content: "Hello!".to_string(),
29///             ..Default::default()
30///         }
31///     ).await?;
32///
33///     println!("Created message: {}", message.id);
34///     Ok(())
35/// # }
36/// ```
37pub trait MessagesService {
38    /// Create a message.
39    fn create_message(
40        &self,
41        thread_id: &str,
42        request: CreateMessageRequest,
43    ) -> impl Future<Output = Result<Message>>;
44
45    /// Retrieve a message.
46    fn retrieve_message(
47        &self,
48        thread_id: &str,
49        message_id: &str,
50    ) -> impl Future<Output = Result<Message>>;
51
52    /// Modifies a message.
53    fn modify_message(
54        &self,
55        thread_id: &str,
56        message_id: &str,
57        request: ModifyMessageRequest,
58    ) -> impl Future<Output = Result<Message>>;
59
60    /// Returns a list of messages for a given thread.
61    fn list_messages(
62        &self,
63        thread_id: &str,
64        params: PaginationParams,
65    ) -> impl Future<Output = Result<ListMessagesResponse>>;
66
67    /// Retrieves a message file.
68    fn retrieve_message_file(
69        &self,
70        thread_id: &str,
71        message_id: &str,
72        file_id: &str,
73    ) -> impl Future<Output = Result<MessageFile>>;
74
75    /// Returns a list of message files.
76    fn list_message_files(
77        &self,
78        thread_id: &str,
79        message_id: &str,
80        params: PaginationParams,
81    ) -> impl Future<Output = Result<ListMessageFilesResponse>>;
82}
83
84impl MessagesService for PortkeyClient {
85    async fn create_message(
86        &self,
87        thread_id: &str,
88        request: CreateMessageRequest,
89    ) -> Result<Message> {
90        #[cfg(feature = "tracing")]
91        tracing::debug!(
92            target: crate::TRACING_TARGET_SERVICE,
93            thread_id = %thread_id,
94            "Creating message"
95        );
96
97        let response = self
98            .send_json(
99                reqwest::Method::POST,
100                &format!("/threads/{}/messages", thread_id),
101                &request,
102            )
103            .await?;
104        let response = response.error_for_status()?;
105        let message: Message = response.json().await?;
106
107        #[cfg(feature = "tracing")]
108        tracing::debug!(
109            target: crate::TRACING_TARGET_SERVICE,
110            "Message created successfully"
111        );
112
113        Ok(message)
114    }
115
116    async fn retrieve_message(&self, thread_id: &str, message_id: &str) -> Result<Message> {
117        #[cfg(feature = "tracing")]
118        tracing::debug!(
119            target: crate::TRACING_TARGET_SERVICE,
120            thread_id = %thread_id,
121            message_id = %message_id,
122            "Retrieving message"
123        );
124
125        let response = self
126            .send(
127                reqwest::Method::GET,
128                &format!("/threads/{}/messages/{}", thread_id, message_id),
129            )
130            .await?;
131        let response = response.error_for_status()?;
132        let message: Message = response.json().await?;
133
134        #[cfg(feature = "tracing")]
135        tracing::debug!(
136            target: crate::TRACING_TARGET_SERVICE,
137            "Message retrieved successfully"
138        );
139
140        Ok(message)
141    }
142
143    async fn modify_message(
144        &self,
145        thread_id: &str,
146        message_id: &str,
147        request: ModifyMessageRequest,
148    ) -> Result<Message> {
149        #[cfg(feature = "tracing")]
150        tracing::debug!(
151            target: crate::TRACING_TARGET_SERVICE,
152            thread_id = %thread_id,
153            message_id = %message_id,
154            "Modifying message"
155        );
156
157        let response = self
158            .send_json(
159                reqwest::Method::POST,
160                &format!("/threads/{}/messages/{}", thread_id, message_id),
161                &request,
162            )
163            .await?;
164        let response = response.error_for_status()?;
165        let message: Message = response.json().await?;
166
167        #[cfg(feature = "tracing")]
168        tracing::debug!(
169            target: crate::TRACING_TARGET_SERVICE,
170            "Message modified successfully"
171        );
172
173        Ok(message)
174    }
175
176    async fn list_messages(
177        &self,
178        thread_id: &str,
179        params: PaginationParams<'_>,
180    ) -> Result<ListMessagesResponse> {
181        #[cfg(feature = "tracing")]
182        tracing::debug!(
183            target: crate::TRACING_TARGET_SERVICE,
184            thread_id = %thread_id,
185            "Listing messages"
186        );
187
188        let query_params = params.to_query_params();
189        let query_params_refs: Vec<(&str, &str)> =
190            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
191
192        let response = self
193            .send_with_params(
194                reqwest::Method::GET,
195                &format!("/threads/{}/messages", thread_id),
196                &query_params_refs,
197            )
198            .await?;
199        let response = response.error_for_status()?;
200        let messages: ListMessagesResponse = response.json().await?;
201
202        #[cfg(feature = "tracing")]
203        tracing::debug!(
204            target: crate::TRACING_TARGET_SERVICE,
205            "Messages retrieved successfully"
206        );
207
208        Ok(messages)
209    }
210
211    async fn retrieve_message_file(
212        &self,
213        thread_id: &str,
214        message_id: &str,
215        file_id: &str,
216    ) -> Result<MessageFile> {
217        #[cfg(feature = "tracing")]
218        tracing::debug!(
219            target: crate::TRACING_TARGET_SERVICE,
220            thread_id = %thread_id,
221            message_id = %message_id,
222            file_id = %file_id,
223            "Retrieving message file"
224        );
225
226        let response = self
227            .send(
228                reqwest::Method::GET,
229                &format!(
230                    "/threads/{}/messages/{}/files/{}",
231                    thread_id, message_id, file_id
232                ),
233            )
234            .await?;
235        let response = response.error_for_status()?;
236        let file: MessageFile = response.json().await?;
237
238        #[cfg(feature = "tracing")]
239        tracing::debug!(
240            target: crate::TRACING_TARGET_SERVICE,
241            "Message file retrieved successfully"
242        );
243
244        Ok(file)
245    }
246
247    async fn list_message_files(
248        &self,
249        thread_id: &str,
250        message_id: &str,
251        params: PaginationParams<'_>,
252    ) -> Result<ListMessageFilesResponse> {
253        #[cfg(feature = "tracing")]
254        tracing::debug!(
255            target: crate::TRACING_TARGET_SERVICE,
256            thread_id = %thread_id,
257            message_id = %message_id,
258            "Listing message files"
259        );
260
261        let query_params = params.to_query_params();
262        let query_params_refs: Vec<(&str, &str)> =
263            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
264
265        let response = self
266            .send_with_params(
267                reqwest::Method::GET,
268                &format!("/threads/{}/messages/{}/files", thread_id, message_id),
269                &query_params_refs,
270            )
271            .await?;
272        let response = response.error_for_status()?;
273        let files: ListMessageFilesResponse = response.json().await?;
274
275        #[cfg(feature = "tracing")]
276        tracing::debug!(
277            target: crate::TRACING_TARGET_SERVICE,
278            "Message files retrieved successfully"
279        );
280
281        Ok(files)
282    }
283}