portkey_sdk/service/responses.rs
1use std::future::Future;
2
3#[cfg(feature = "tracing")]
4use crate::TRACING_TARGET_SERVICE;
5use crate::client::PortkeyClient;
6use crate::error::Result;
7use crate::model::{CreateResponseRequest, ListInputItemsParams, ListInputItemsResponse, Response};
8
9/// Service trait for managing responses in Portkey.
10///
11/// This trait provides methods for creating, retrieving, listing, and deleting
12/// responses, as well as managing input items associated with responses.
13///
14/// # Example
15///
16/// ```rust,no_run
17/// use portkey_sdk::{PortkeyConfig, Result};
18/// use portkey_sdk::service::ResponsesService;
19/// use portkey_sdk::builder::AuthMethod;
20/// use portkey_sdk::model::CreateResponseRequest;
21///
22/// #[tokio::main]
23/// async fn main() -> Result<()> {
24/// let client = PortkeyConfig::builder()
25/// .with_api_key("your-portkey-api-key")
26/// .with_auth_method(AuthMethod::virtual_key("your-virtual-key"))
27/// .build_client()?;
28///
29/// // Create a new response
30/// let request = CreateResponseRequest {
31/// trace_id: Some("trace-123".to_string()),
32/// model: Some("gpt-4".to_string()),
33/// provider: Some("openai".to_string()),
34/// status: Some("success".to_string()),
35/// total_tokens: Some(150),
36/// prompt_tokens: Some(100),
37/// completion_tokens: Some(50),
38/// latency_ms: Some(1500),
39/// cost: Some(0.003),
40/// metadata: None,
41/// request: None,
42/// response: None,
43/// };
44///
45/// let response = client.create_response(request).await?;
46/// println!("Created response: {}", response.id);
47///
48/// // Get the response
49/// let fetched = client.get_response(&response.id).await?;
50/// println!("Fetched response: {:?}", fetched);
51///
52/// // List input items for the response
53/// let params = portkey_sdk::model::ListInputItemsParams {
54/// limit: Some(50),
55/// offset: Some(0),
56/// };
57/// let input_items = client.list_input_items(&response.id, params).await?;
58/// println!("Found {} input items", input_items.data.len());
59///
60/// // Delete the response
61/// client.delete_response(&response.id).await?;
62/// println!("Deleted response");
63///
64/// Ok(())
65/// }
66/// ```
67pub trait ResponsesService {
68 /// Creates a new response.
69 ///
70 /// # Arguments
71 ///
72 /// * `request` - The response data to create
73 ///
74 /// # Returns
75 ///
76 /// Returns the created `Response` object with its assigned ID and metadata.
77 ///
78 /// # Errors
79 ///
80 /// Returns an error if the API request fails or the response cannot be parsed.
81 fn create_response(
82 &self,
83 request: CreateResponseRequest,
84 ) -> impl Future<Output = Result<Response>>;
85
86 /// Retrieves a specific response by ID.
87 ///
88 /// # Arguments
89 ///
90 /// * `response_id` - The unique identifier of the response to retrieve
91 ///
92 /// # Returns
93 ///
94 /// Returns the `Response` object if found.
95 ///
96 /// # Errors
97 ///
98 /// Returns an error if the response is not found or the API request fails.
99 fn get_response(&self, response_id: &str) -> impl Future<Output = Result<Response>>;
100
101 /// Deletes a response.
102 ///
103 /// # Arguments
104 ///
105 /// * `response_id` - The unique identifier of the response to delete
106 ///
107 /// # Returns
108 ///
109 /// Returns `Ok(())` if the response was successfully deleted.
110 ///
111 /// # Errors
112 ///
113 /// Returns an error if the response is not found or the deletion fails.
114 fn delete_response(&self, response_id: &str) -> impl Future<Output = Result<()>>;
115
116 /// Lists input items for a specific response.
117 ///
118 /// # Arguments
119 ///
120 /// * `response_id` - The unique identifier of the response
121 /// * `params` - Pagination parameters (limit and offset)
122 ///
123 /// # Returns
124 ///
125 /// Returns a `ListInputItemsResponse` containing the input items and pagination info.
126 ///
127 /// # Errors
128 ///
129 /// Returns an error if the response is not found or the API request fails.
130 fn list_input_items(
131 &self,
132 response_id: &str,
133 params: ListInputItemsParams,
134 ) -> impl Future<Output = Result<ListInputItemsResponse>>;
135}
136
137impl ResponsesService for PortkeyClient {
138 async fn create_response(&self, request: CreateResponseRequest) -> Result<Response> {
139 #[cfg(feature = "tracing")]
140 tracing::debug!(
141 target: TRACING_TARGET_SERVICE,
142 trace_id = ?request.trace_id,
143 model = ?request.model,
144 "Creating response"
145 );
146
147 let response = self
148 .send_json(reqwest::Method::POST, "/responses", &request)
149 .await?;
150 let response = response.error_for_status()?;
151 let response_data: Response = response.json().await?;
152
153 Ok(response_data)
154 }
155
156 async fn get_response(&self, response_id: &str) -> Result<Response> {
157 #[cfg(feature = "tracing")]
158 tracing::debug!(
159 target: TRACING_TARGET_SERVICE,
160 response_id = %response_id,
161 "Getting response"
162 );
163
164 let path = format!("/responses/{}", response_id);
165 let response = self.send(reqwest::Method::GET, &path).await?;
166 let response = response.error_for_status()?;
167 let response_data: Response = response.json().await?;
168
169 Ok(response_data)
170 }
171
172 async fn delete_response(&self, response_id: &str) -> Result<()> {
173 #[cfg(feature = "tracing")]
174 tracing::debug!(
175 target: TRACING_TARGET_SERVICE,
176 response_id = %response_id,
177 "Deleting response"
178 );
179
180 let path = format!("/responses/{}", response_id);
181 let response = self.send(reqwest::Method::DELETE, &path).await?;
182 response.error_for_status()?;
183
184 Ok(())
185 }
186
187 async fn list_input_items(
188 &self,
189 response_id: &str,
190 params: ListInputItemsParams,
191 ) -> Result<ListInputItemsResponse> {
192 #[cfg(feature = "tracing")]
193 tracing::debug!(
194 target: TRACING_TARGET_SERVICE,
195 response_id = %response_id,
196 limit = ?params.limit,
197 offset = ?params.offset,
198 "Listing input items"
199 );
200
201 let path = format!("/responses/{}/input_items", response_id);
202 let mut request = self.request_builder(reqwest::Method::GET, &path)?;
203
204 // Add query parameters if specified
205 if let Some(limit) = params.limit {
206 request = request.query(&[("limit", limit.to_string())]);
207 }
208 if let Some(offset) = params.offset {
209 request = request.query(&[("offset", offset.to_string())]);
210 }
211
212 let response = request.send().await?;
213 let response = response.error_for_status()?;
214 let input_items: ListInputItemsResponse = response.json().await?;
215
216 Ok(input_items)
217 }
218}