portkey_sdk/service/prompts.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::{
8 PromptCompletionRequest, PromptCompletionResponse, PromptRenderRequest, PromptRenderResponse,
9};
10
11/// Service trait for executing prompt templates.
12///
13/// This trait provides methods for executing saved prompt templates on Portkey,
14/// allowing you to substitute variables and override hyperparameters.
15///
16/// # Example
17///
18/// ```rust,no_run
19/// use portkey_sdk::{PortkeyConfig, Result};
20/// use portkey_sdk::service::PromptsService;
21/// use portkey_sdk::builder::AuthMethod;
22/// use portkey_sdk::model::PromptCompletionRequest;
23/// use std::collections::HashMap;
24///
25/// #[tokio::main]
26/// async fn main() -> Result<()> {
27/// let client = PortkeyConfig::builder()
28/// .with_api_key("your-portkey-api-key")
29/// .with_auth_method(AuthMethod::virtual_key("your-virtual-key"))
30/// .build_client()?;
31///
32/// let mut variables = HashMap::new();
33/// variables.insert("user_input".to_string(), serde_json::json!("Hello world"));
34///
35/// let request = PromptCompletionRequest {
36/// variables,
37/// stream: Some(false),
38/// max_tokens: Some(250),
39/// presence_penalty: Some(0.2),
40/// temperature: None,
41/// frequency_penalty: None,
42/// top_p: None,
43/// stop: None,
44/// n: None,
45/// logprobs: None,
46/// echo: None,
47/// best_of: None,
48/// logit_bias: None,
49/// user: None,
50/// };
51///
52/// let response = client.execute_prompt("your-prompt-id", request).await?;
53/// println!("Completion: {:?}", response.body);
54///
55/// Ok(())
56/// }
57/// ```
58pub trait PromptsService {
59 /// Executes a saved prompt template with the given variables and parameters.
60 ///
61 /// # Arguments
62 ///
63 /// * `prompt_id` - The unique identifier of the prompt template
64 /// * `request` - The completion request with variables and hyperparameters
65 ///
66 /// # Returns
67 ///
68 /// Returns a `PromptCompletionResponse` containing the completion result.
69 ///
70 /// # Errors
71 ///
72 /// Returns an error if the API request fails or the response cannot be parsed.
73 fn execute_prompt(
74 &self,
75 prompt_id: &str,
76 request: PromptCompletionRequest,
77 ) -> impl Future<Output = Result<PromptCompletionResponse>>;
78
79 /// Renders a prompt template with variables and hyperparameters without executing it.
80 ///
81 /// This method substitutes variables in the prompt template and applies hyperparameters,
82 /// returning the fully rendered configuration that would be sent to the LLM provider.
83 ///
84 /// # Arguments
85 ///
86 /// * `prompt_id` - The unique identifier of the prompt template
87 /// * `request` - The render request with variables and optional hyperparameters
88 ///
89 /// # Returns
90 ///
91 /// Returns a `PromptRenderResponse` containing the rendered prompt configuration.
92 ///
93 /// # Errors
94 ///
95 /// Returns an error if the API request fails or the response cannot be parsed.
96 fn render_prompt(
97 &self,
98 prompt_id: &str,
99 request: PromptRenderRequest,
100 ) -> impl Future<Output = Result<PromptRenderResponse>>;
101}
102
103impl PromptsService for PortkeyClient {
104 async fn execute_prompt(
105 &self,
106 prompt_id: &str,
107 request: PromptCompletionRequest,
108 ) -> Result<PromptCompletionResponse> {
109 #[cfg(feature = "tracing")]
110 tracing::debug!(
111 target: TRACING_TARGET_SERVICE,
112 prompt_id = %prompt_id,
113 stream = ?request.stream,
114 max_tokens = ?request.max_tokens,
115 "Executing prompt template"
116 );
117
118 let path = format!("/prompts/{}/completions", prompt_id);
119 let response = self
120 .send_json(reqwest::Method::POST, &path, &request)
121 .await?;
122 let response = response.error_for_status()?;
123 let completion_response: PromptCompletionResponse = response.json().await?;
124
125 Ok(completion_response)
126 }
127
128 async fn render_prompt(
129 &self,
130 prompt_id: &str,
131 request: PromptRenderRequest,
132 ) -> Result<PromptRenderResponse> {
133 #[cfg(feature = "tracing")]
134 tracing::debug!(
135 target: TRACING_TARGET_SERVICE,
136 prompt_id = %prompt_id,
137 max_tokens = ?request.max_tokens,
138 "Rendering prompt template"
139 );
140
141 let path = format!("/prompts/{}/render", prompt_id);
142 let response = self
143 .send_json(reqwest::Method::POST, &path, &request)
144 .await?;
145 let response = response.error_for_status()?;
146 let render_response: PromptRenderResponse = response.json().await?;
147
148 Ok(render_response)
149 }
150}