portkey_sdk/service/
fine_tuning.rs

1use std::future::Future;
2
3use crate::model::{
4    CreateFineTuningJobRequest, FineTuningJob, ListFineTuningJobCheckpointsResponse,
5    ListFineTuningJobEventsResponse, ListFineTuningJobsResponse, PaginationParams,
6};
7use crate::{PortkeyClient, Result};
8
9/// Service for managing fine-tuning jobs.
10///
11/// # Example
12///
13/// ```no_run
14/// use portkey_sdk::{PortkeyConfig, PortkeyClient, Result};
15/// use portkey_sdk::service::FineTuningService;
16/// use portkey_sdk::model::CreateFineTuningJobRequest;
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 job = client.create_fine_tuning_job(
25///     CreateFineTuningJobRequest {
26///         model: "gpt-3.5-turbo".to_string(),
27///         training_file: "file-abc123".to_string(),
28///         ..Default::default()
29///     }
30/// ).await?;
31///
32/// println!("Created fine-tuning job: {}", job.id);
33/// # Ok(())
34/// # }
35/// ```
36pub trait FineTuningService {
37    /// Creates a fine-tuning job which begins the process of creating a new model from a given dataset.
38    ///
39    /// # Example
40    ///
41    /// ```no_run
42    /// # use portkey_sdk::{PortkeyConfig, PortkeyClient, Result};
43    /// # use portkey_sdk::service::FineTuningService;
44    /// # use portkey_sdk::model::CreateFineTuningJobRequest;
45    /// # async fn example(client: PortkeyClient) -> Result<()> {
46    /// let job = client.create_fine_tuning_job(
47    ///     CreateFineTuningJobRequest {
48    ///         model: "gpt-3.5-turbo".to_string(),
49    ///         training_file: "file-abc123".to_string(),
50    ///         suffix: Some("my-custom-model".to_string()),
51    ///         ..Default::default()
52    ///     }
53    /// ).await?;
54    /// # Ok(())
55    /// # }
56    /// ```
57    fn create_fine_tuning_job(
58        &self,
59        request: CreateFineTuningJobRequest,
60    ) -> impl Future<Output = Result<FineTuningJob>>;
61
62    /// List your organization's fine-tuning jobs.
63    ///
64    /// # Arguments
65    ///
66    /// * `after` - Identifier for the last job from the previous pagination request.
67    /// * `limit` - Number of fine-tuning jobs to retrieve (default: 20).
68    ///
69    /// # Example
70    ///
71    /// ```no_run
72    /// # use portkey_sdk::service::FineTuningService;
73    /// # use portkey_sdk::model::PaginationParams;
74    /// # async fn example(client: &impl FineTuningService) -> portkey_sdk::Result<()> {
75    /// let params = PaginationParams { limit: Some(10), order: None, after: None, before: None };
76    /// let jobs = client.list_fine_tuning_jobs(params).await?;
77    /// for job in jobs.data {
78    ///     println!("Job {}: {}", job.id, job.status);
79    /// }
80    /// # Ok(())
81    /// # }
82    /// ```
83    fn list_fine_tuning_jobs(
84        &self,
85        params: PaginationParams,
86    ) -> impl Future<Output = Result<ListFineTuningJobsResponse>>;
87
88    /// Get info about a fine-tuning job.
89    ///
90    /// # Arguments
91    ///
92    /// * `fine_tuning_job_id` - The ID of the fine-tuning job.
93    ///
94    /// # Example
95    ///
96    /// ```no_run
97    /// # use portkey_sdk::{PortkeyClient, Result};
98    /// # use portkey_sdk::service::FineTuningService;
99    /// # async fn example(client: PortkeyClient) -> Result<()> {
100    /// let job = client.retrieve_fine_tuning_job("ftjob-abc123").await?;
101    /// println!("Status: {}", job.status);
102    /// # Ok(())
103    /// # }
104    /// ```
105    fn retrieve_fine_tuning_job(
106        &self,
107        fine_tuning_job_id: &str,
108    ) -> impl Future<Output = Result<FineTuningJob>>;
109
110    /// Immediately cancel a fine-tuning job.
111    ///
112    /// # Arguments
113    ///
114    /// * `fine_tuning_job_id` - The ID of the fine-tuning job to cancel.
115    ///
116    /// # Example
117    ///
118    /// ```no_run
119    /// # use portkey_sdk::{PortkeyClient, Result};
120    /// # use portkey_sdk::service::FineTuningService;
121    /// # async fn example(client: PortkeyClient) -> Result<()> {
122    /// let job = client.cancel_fine_tuning_job("ftjob-abc123").await?;
123    /// println!("Cancelled job: {}", job.id);
124    /// # Ok(())
125    /// # }
126    /// ```
127    fn cancel_fine_tuning_job(
128        &self,
129        fine_tuning_job_id: &str,
130    ) -> impl Future<Output = Result<FineTuningJob>>;
131
132    /// Get status updates for a fine-tuning job.
133    ///
134    /// # Arguments
135    ///
136    /// * `fine_tuning_job_id` - The ID of the fine-tuning job to get events for.
137    /// * `after` - Identifier for the last event from the previous pagination request.
138    /// * `limit` - Number of events to retrieve (default: 20).
139    ///
140    /// # Example
141    ///
142    /// ```no_run
143    /// # use portkey_sdk::service::FineTuningService;
144    /// # use portkey_sdk::model::PaginationParams;
145    /// # async fn example(client: &impl FineTuningService) -> portkey_sdk::Result<()> {
146    /// let params = PaginationParams { limit: Some(10), order: None, after: None, before: None };
147    /// let events = client.list_fine_tuning_job_events("ftjob-abc123", params).await?;
148    /// for event in events.data {
149    ///     println!("[{}] {}", event.level, event.message);
150    /// }
151    /// # Ok(())
152    /// # }
153    /// ```
154    fn list_fine_tuning_job_events(
155        &self,
156        fine_tuning_job_id: &str,
157        params: PaginationParams,
158    ) -> impl Future<Output = Result<ListFineTuningJobEventsResponse>>;
159
160    /// List checkpoints for a fine-tuning job.
161    ///
162    /// # Arguments
163    ///
164    /// * `fine_tuning_job_id` - The ID of the fine-tuning job to get checkpoints for.
165    /// * `after` - Identifier for the last checkpoint from the previous pagination request.
166    /// * `limit` - Number of checkpoints to retrieve (default: 10).
167    ///
168    /// # Example
169    ///
170    /// ```no_run
171    /// # use portkey_sdk::service::FineTuningService;
172    /// # use portkey_sdk::model::PaginationParams;
173    /// # async fn example(client: &impl FineTuningService) -> portkey_sdk::Result<()> {
174    /// let params = PaginationParams { limit: Some(5), order: None, after: None, before: None };
175    /// let checkpoints = client.list_fine_tuning_job_checkpoints("ftjob-abc123", params).await?;
176    /// for checkpoint in checkpoints.data {
177    ///     println!("Checkpoint at step {}", checkpoint.step_number);
178    /// }
179    /// # Ok(())
180    /// # }
181    /// ```
182    fn list_fine_tuning_job_checkpoints(
183        &self,
184        fine_tuning_job_id: &str,
185        params: PaginationParams,
186    ) -> impl Future<Output = Result<ListFineTuningJobCheckpointsResponse>>;
187}
188
189impl FineTuningService for PortkeyClient {
190    async fn create_fine_tuning_job(
191        &self,
192        request: CreateFineTuningJobRequest,
193    ) -> Result<FineTuningJob> {
194        #[cfg(feature = "tracing")]
195        tracing::debug!(
196            target: crate::TRACING_TARGET_SERVICE,
197            "Creating fine-tuning job"
198        );
199
200        let response = self
201            .send_json(reqwest::Method::POST, "/fine_tuning/jobs", &request)
202            .await?;
203        let response = response.error_for_status()?;
204        let job: FineTuningJob = response.json().await?;
205
206        #[cfg(feature = "tracing")]
207        tracing::debug!(
208            target: crate::TRACING_TARGET_SERVICE,
209            "Fine-tuning job created successfully"
210        );
211
212        Ok(job)
213    }
214
215    async fn list_fine_tuning_jobs(
216        &self,
217        params: PaginationParams<'_>,
218    ) -> Result<ListFineTuningJobsResponse> {
219        #[cfg(feature = "tracing")]
220        tracing::debug!(
221            target: crate::TRACING_TARGET_SERVICE,
222            "Listing fine-tuning jobs"
223        );
224
225        let query_params = params.to_query_params();
226        let query_params_refs: Vec<(&str, &str)> =
227            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
228
229        let response = self
230            .send_with_params(
231                reqwest::Method::GET,
232                "/fine_tuning/jobs",
233                &query_params_refs,
234            )
235            .await?;
236        let response = response.error_for_status()?;
237        let jobs: ListFineTuningJobsResponse = response.json().await?;
238
239        #[cfg(feature = "tracing")]
240        tracing::debug!(
241            target: crate::TRACING_TARGET_SERVICE,
242            "Fine-tuning jobs retrieved successfully"
243        );
244
245        Ok(jobs)
246    }
247
248    async fn retrieve_fine_tuning_job(&self, fine_tuning_job_id: &str) -> Result<FineTuningJob> {
249        #[cfg(feature = "tracing")]
250        tracing::debug!(
251            target: crate::TRACING_TARGET_SERVICE,
252            job_id = %fine_tuning_job_id,
253            "Retrieving fine-tuning job"
254        );
255
256        let response = self
257            .send(
258                reqwest::Method::GET,
259                &format!("/fine_tuning/jobs/{}", fine_tuning_job_id),
260            )
261            .await?;
262        let response = response.error_for_status()?;
263        let job: FineTuningJob = response.json().await?;
264
265        #[cfg(feature = "tracing")]
266        tracing::debug!(
267            target: crate::TRACING_TARGET_SERVICE,
268            "Fine-tuning job retrieved successfully"
269        );
270
271        Ok(job)
272    }
273
274    async fn cancel_fine_tuning_job(&self, fine_tuning_job_id: &str) -> Result<FineTuningJob> {
275        #[cfg(feature = "tracing")]
276        tracing::debug!(
277            target: crate::TRACING_TARGET_SERVICE,
278            job_id = %fine_tuning_job_id,
279            "Cancelling fine-tuning job"
280        );
281
282        let response = self
283            .send_json(
284                reqwest::Method::POST,
285                &format!("/fine_tuning/jobs/{}/cancel", fine_tuning_job_id),
286                &serde_json::json!({}),
287            )
288            .await?;
289        let response = response.error_for_status()?;
290        let job: FineTuningJob = response.json().await?;
291
292        #[cfg(feature = "tracing")]
293        tracing::debug!(
294            target: crate::TRACING_TARGET_SERVICE,
295            "Fine-tuning job cancelled successfully"
296        );
297
298        Ok(job)
299    }
300
301    async fn list_fine_tuning_job_events(
302        &self,
303        fine_tuning_job_id: &str,
304        params: PaginationParams<'_>,
305    ) -> Result<ListFineTuningJobEventsResponse> {
306        #[cfg(feature = "tracing")]
307        tracing::debug!(
308            target: crate::TRACING_TARGET_SERVICE,
309            job_id = %fine_tuning_job_id,
310            "Listing fine-tuning job events"
311        );
312
313        let query_params = params.to_query_params();
314        let query_params_refs: Vec<(&str, &str)> =
315            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
316
317        let response = self
318            .send_with_params(
319                reqwest::Method::GET,
320                &format!("/fine_tuning/jobs/{}/events", fine_tuning_job_id),
321                &query_params_refs,
322            )
323            .await?;
324        let response = response.error_for_status()?;
325        let events: ListFineTuningJobEventsResponse = response.json().await?;
326
327        #[cfg(feature = "tracing")]
328        tracing::debug!(
329            target: crate::TRACING_TARGET_SERVICE,
330            "Fine-tuning job events retrieved successfully"
331        );
332
333        Ok(events)
334    }
335
336    async fn list_fine_tuning_job_checkpoints(
337        &self,
338        fine_tuning_job_id: &str,
339        params: PaginationParams<'_>,
340    ) -> Result<ListFineTuningJobCheckpointsResponse> {
341        #[cfg(feature = "tracing")]
342        tracing::debug!(
343            target: crate::TRACING_TARGET_SERVICE,
344            job_id = %fine_tuning_job_id,
345            "Listing fine-tuning job checkpoints"
346        );
347
348        let query_params = params.to_query_params();
349        let query_params_refs: Vec<(&str, &str)> =
350            query_params.iter().map(|(k, v)| (*k, v.as_str())).collect();
351
352        let response = self
353            .send_with_params(
354                reqwest::Method::GET,
355                &format!("/fine_tuning/jobs/{}/checkpoints", fine_tuning_job_id),
356                &query_params_refs,
357            )
358            .await?;
359        let response = response.error_for_status()?;
360        let checkpoints: ListFineTuningJobCheckpointsResponse = response.json().await?;
361
362        #[cfg(feature = "tracing")]
363        tracing::debug!(
364            target: crate::TRACING_TARGET_SERVICE,
365            "Fine-tuning job checkpoints retrieved successfully"
366        );
367
368        Ok(checkpoints)
369    }
370}