portkey_sdk/service/
assistants.rs

1use std::future::Future;
2
3use crate::model::{
4    Assistant, AssistantFile, CreateAssistantFileRequest, CreateAssistantRequest,
5    DeleteAssistantFileResponse, DeleteAssistantResponse, ListAssistantFilesResponse,
6    ListAssistantsResponse, ModifyAssistantRequest, PaginationParams,
7};
8use crate::{PortkeyClient, Result};
9
10/// Service for managing assistants.
11///
12/// # Example
13///
14/// ```no_run
15/// use portkey_sdk::{PortkeyConfig, PortkeyClient, Result};
16/// use portkey_sdk::service::AssistantsService;
17/// use portkey_sdk::model::CreateAssistantRequest;
18///
19/// # async fn example() -> Result<()> {
20/// let config = PortkeyConfig::builder()
21///     .with_api_key("your-api-key")
22///     .build()?;
23/// let client = PortkeyClient::new(config)?;
24///
25///     let assistant = client.create_assistant(
26///         CreateAssistantRequest {
27///             model: "gpt-4".to_string(),
28///             name: Some("Math Tutor".to_string()),
29///             instructions: Some("You are a helpful math tutor.".to_string()),
30///             ..Default::default()
31///         }
32///     ).await?;
33///
34///     println!("Created assistant: {}", assistant.id);
35///     Ok(())
36/// # }
37/// ```
38pub trait AssistantsService {
39    /// Create an assistant with a model and instructions.
40    fn create_assistant(
41        &self,
42        request: CreateAssistantRequest,
43    ) -> impl Future<Output = Result<Assistant>>;
44
45    /// Retrieves an assistant.
46    fn retrieve_assistant(&self, assistant_id: &str) -> impl Future<Output = Result<Assistant>>;
47
48    /// Modifies an assistant.
49    fn modify_assistant(
50        &self,
51        assistant_id: &str,
52        request: ModifyAssistantRequest,
53    ) -> impl Future<Output = Result<Assistant>>;
54
55    /// Delete an assistant.
56    fn delete_assistant(
57        &self,
58        assistant_id: &str,
59    ) -> impl Future<Output = Result<DeleteAssistantResponse>>;
60
61    /// Returns a list of assistants.
62    fn list_assistants(
63        &self,
64        params: PaginationParams,
65    ) -> impl Future<Output = Result<ListAssistantsResponse>>;
66
67    /// Create an assistant file by attaching a File to an assistant.
68    fn create_assistant_file(
69        &self,
70        assistant_id: &str,
71        request: CreateAssistantFileRequest,
72    ) -> impl Future<Output = Result<AssistantFile>>;
73
74    /// Retrieves an AssistantFile.
75    fn retrieve_assistant_file(
76        &self,
77        assistant_id: &str,
78        file_id: &str,
79    ) -> impl Future<Output = Result<AssistantFile>>;
80
81    /// Delete an assistant file.
82    fn delete_assistant_file(
83        &self,
84        assistant_id: &str,
85        file_id: &str,
86    ) -> impl Future<Output = Result<DeleteAssistantFileResponse>>;
87
88    /// Returns a list of assistant files.
89    fn list_assistant_files(
90        &self,
91        assistant_id: &str,
92        params: PaginationParams,
93    ) -> impl Future<Output = Result<ListAssistantFilesResponse>>;
94}
95
96impl AssistantsService for PortkeyClient {
97    async fn create_assistant(&self, request: CreateAssistantRequest) -> Result<Assistant> {
98        #[cfg(feature = "tracing")]
99        tracing::debug!(
100            target: crate::TRACING_TARGET_SERVICE,
101            "Creating assistant"
102        );
103
104        let response = self
105            .send_json(reqwest::Method::POST, "/assistants", &request)
106            .await?;
107        let response = response.error_for_status()?;
108        let assistant: Assistant = response.json().await?;
109
110        #[cfg(feature = "tracing")]
111        tracing::debug!(
112            target: crate::TRACING_TARGET_SERVICE,
113            "Assistant created successfully"
114        );
115
116        Ok(assistant)
117    }
118
119    async fn retrieve_assistant(&self, assistant_id: &str) -> Result<Assistant> {
120        #[cfg(feature = "tracing")]
121        tracing::debug!(
122            target: crate::TRACING_TARGET_SERVICE,
123            assistant_id = %assistant_id,
124            "Retrieving assistant"
125        );
126
127        let response = self
128            .send(
129                reqwest::Method::GET,
130                &format!("/assistants/{}", assistant_id),
131            )
132            .await?;
133        let response = response.error_for_status()?;
134        let assistant: Assistant = response.json().await?;
135
136        #[cfg(feature = "tracing")]
137        tracing::debug!(
138            target: crate::TRACING_TARGET_SERVICE,
139            "Assistant retrieved successfully"
140        );
141
142        Ok(assistant)
143    }
144
145    async fn modify_assistant(
146        &self,
147        assistant_id: &str,
148        request: ModifyAssistantRequest,
149    ) -> Result<Assistant> {
150        #[cfg(feature = "tracing")]
151        tracing::debug!(
152            target: crate::TRACING_TARGET_SERVICE,
153            assistant_id = %assistant_id,
154            "Modifying assistant"
155        );
156
157        let response = self
158            .send_json(
159                reqwest::Method::POST,
160                &format!("/assistants/{}", assistant_id),
161                &request,
162            )
163            .await?;
164        let response = response.error_for_status()?;
165        let assistant: Assistant = response.json().await?;
166
167        #[cfg(feature = "tracing")]
168        tracing::debug!(
169            target: crate::TRACING_TARGET_SERVICE,
170            "Assistant modified successfully"
171        );
172
173        Ok(assistant)
174    }
175
176    async fn delete_assistant(&self, assistant_id: &str) -> Result<DeleteAssistantResponse> {
177        #[cfg(feature = "tracing")]
178        tracing::debug!(
179            target: crate::TRACING_TARGET_SERVICE,
180            assistant_id = %assistant_id,
181            "Deleting assistant"
182        );
183
184        let response = self
185            .send(
186                reqwest::Method::DELETE,
187                &format!("/assistants/{}", assistant_id),
188            )
189            .await?;
190        let response = response.error_for_status()?;
191        let delete_response: DeleteAssistantResponse = response.json().await?;
192
193        #[cfg(feature = "tracing")]
194        tracing::debug!(
195            target: crate::TRACING_TARGET_SERVICE,
196            "Assistant deleted successfully"
197        );
198
199        Ok(delete_response)
200    }
201
202    async fn list_assistants(
203        &self,
204        params: PaginationParams<'_>,
205    ) -> Result<ListAssistantsResponse> {
206        #[cfg(feature = "tracing")]
207        tracing::debug!(
208            target: crate::TRACING_TARGET_SERVICE,
209            "Listing assistants"
210        );
211
212        let query_params = params.to_query_params();
213        let query_params_refs: Vec<(&str, &str)> =
214            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
215
216        let response = self
217            .send_with_params(reqwest::Method::GET, "/assistants", &query_params_refs)
218            .await?;
219        let response = response.error_for_status()?;
220        let assistants: ListAssistantsResponse = response.json().await?;
221
222        #[cfg(feature = "tracing")]
223        tracing::debug!(
224            target: crate::TRACING_TARGET_SERVICE,
225            "Assistants retrieved successfully"
226        );
227
228        Ok(assistants)
229    }
230
231    async fn create_assistant_file(
232        &self,
233        assistant_id: &str,
234        request: CreateAssistantFileRequest,
235    ) -> Result<AssistantFile> {
236        #[cfg(feature = "tracing")]
237        tracing::debug!(
238            target: crate::TRACING_TARGET_SERVICE,
239            assistant_id = %assistant_id,
240            "Creating assistant file"
241        );
242
243        let response = self
244            .send_json(
245                reqwest::Method::POST,
246                &format!("/assistants/{}/files", assistant_id),
247                &request,
248            )
249            .await?;
250        let response = response.error_for_status()?;
251        let file: AssistantFile = response.json().await?;
252
253        #[cfg(feature = "tracing")]
254        tracing::debug!(
255            target: crate::TRACING_TARGET_SERVICE,
256            "Assistant file created successfully"
257        );
258
259        Ok(file)
260    }
261
262    async fn retrieve_assistant_file(
263        &self,
264        assistant_id: &str,
265        file_id: &str,
266    ) -> Result<AssistantFile> {
267        #[cfg(feature = "tracing")]
268        tracing::debug!(
269            target: crate::TRACING_TARGET_SERVICE,
270            assistant_id = %assistant_id,
271            file_id = %file_id,
272            "Retrieving assistant file"
273        );
274
275        let response = self
276            .send(
277                reqwest::Method::GET,
278                &format!("/assistants/{}/files/{}", assistant_id, file_id),
279            )
280            .await?;
281        let response = response.error_for_status()?;
282        let file: AssistantFile = response.json().await?;
283
284        #[cfg(feature = "tracing")]
285        tracing::debug!(
286            target: crate::TRACING_TARGET_SERVICE,
287            "Assistant file retrieved successfully"
288        );
289
290        Ok(file)
291    }
292
293    async fn delete_assistant_file(
294        &self,
295        assistant_id: &str,
296        file_id: &str,
297    ) -> Result<DeleteAssistantFileResponse> {
298        #[cfg(feature = "tracing")]
299        tracing::debug!(
300            target: crate::TRACING_TARGET_SERVICE,
301            assistant_id = %assistant_id,
302            file_id = %file_id,
303            "Deleting assistant file"
304        );
305
306        let response = self
307            .send(
308                reqwest::Method::DELETE,
309                &format!("/assistants/{}/files/{}", assistant_id, file_id),
310            )
311            .await?;
312        let response = response.error_for_status()?;
313        let delete_response: DeleteAssistantFileResponse = response.json().await?;
314
315        #[cfg(feature = "tracing")]
316        tracing::debug!(
317            target: crate::TRACING_TARGET_SERVICE,
318            "Assistant file deleted successfully"
319        );
320
321        Ok(delete_response)
322    }
323
324    async fn list_assistant_files(
325        &self,
326        assistant_id: &str,
327        params: PaginationParams<'_>,
328    ) -> Result<ListAssistantFilesResponse> {
329        #[cfg(feature = "tracing")]
330        tracing::debug!(
331            target: crate::TRACING_TARGET_SERVICE,
332            assistant_id = %assistant_id,
333            "Listing assistant files"
334        );
335
336        let query_params = params.to_query_params();
337        let query_params_refs: Vec<(&str, &str)> =
338            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
339
340        let response = self
341            .send_with_params(
342                reqwest::Method::GET,
343                &format!("/assistants/{}/files", assistant_id),
344                &query_params_refs,
345            )
346            .await?;
347        let response = response.error_for_status()?;
348        let files: ListAssistantFilesResponse = response.json().await?;
349
350        #[cfg(feature = "tracing")]
351        tracing::debug!(
352            target: crate::TRACING_TARGET_SERVICE,
353            "Assistant files retrieved successfully"
354        );
355
356        Ok(files)
357    }
358}