portkey_sdk/service/
chat.rs

1use std::future::Future;
2
3#[cfg(feature = "tracing")]
4use crate::TRACING_TARGET_SERVICE;
5use crate::model::{ChatCompletionRequest, ChatCompletionResponse};
6use crate::{PortkeyClient, Result};
7
8/// Trait for chat completion operations.
9///
10/// Provides methods for creating chat completions using the Portkey API.
11/// This trait is implemented on the [`PortkeyClient`](crate::client::PortkeyClient).
12pub trait ChatService {
13    /// Creates a chat completion.
14    ///
15    /// Sends a chat completion request to the configured LLM provider through Portkey's gateway.
16    /// The request follows the OpenAI-compatible chat completions format and can be routed to
17    /// any supported provider based on your Portkey configuration.
18    ///
19    /// # Arguments
20    ///
21    /// * `request` - The chat completion request with model, messages, and optional parameters
22    ///
23    /// # Returns
24    ///
25    /// Returns the chat completion response with the model's generated message(s).
26    ///
27    /// # Authentication Options
28    ///
29    /// The client must be configured with one of the following authentication methods:
30    ///
31    /// 1. **Virtual Key**: API key + Virtual key (managed provider credentials)
32    /// 2. **Provider Auth**: API key + Provider name + Authorization header
33    /// 3. **Config**: API key + Config ID (for complex routing/fallback configurations)
34    /// 4. **Custom Host**: API key + Provider name + Authorization + Custom host URL
35    ///
36    /// # Example
37    ///
38    /// ```no_run
39    /// # use portkey_sdk::{PortkeyClient, PortkeyConfig, Result};
40    /// # use portkey_sdk::builder::AuthMethod;
41    /// # use portkey_sdk::model::{ChatCompletionRequest, ChatCompletionRequestMessage, ChatCompletionUserMessageContent};
42    /// # use portkey_sdk::service::ChatService;
43    /// # async fn example() -> Result<()> {
44    /// let config = PortkeyConfig::builder()
45    ///     .with_api_key("your-portkey-api-key")
46    ///     .with_auth_method(AuthMethod::virtual_key("your-virtual-key"))
47    ///     .build()?;
48    /// let client = PortkeyClient::new(config)?;
49    ///
50    /// let request = ChatCompletionRequest {
51    ///     model: "gpt-4o".to_string(),
52    ///     messages: vec![
53    ///         ChatCompletionRequestMessage::System {
54    ///             content: "You are a helpful assistant.".to_string(),
55    ///             name: None,
56    ///         },
57    ///         ChatCompletionRequestMessage::User {
58    ///             content: ChatCompletionUserMessageContent::Text("Hello!".to_string()),
59    ///             name: None,
60    ///         },
61    ///     ],
62    ///     temperature: Some(0.7),
63    ///     max_tokens: Some(100),
64    ///     frequency_penalty: None,
65    ///     logit_bias: None,
66    ///     logprobs: None,
67    ///     top_logprobs: None,
68    ///     n: None,
69    ///     presence_penalty: None,
70    ///     response_format: None,
71    ///     seed: None,
72    ///     stop: None,
73    ///     stream: None,
74    ///     stream_options: None,
75    ///     thinking: None,
76    ///     top_p: None,
77    ///     tools: None,
78    ///     tool_choice: None,
79    ///     parallel_tool_calls: None,
80    ///     user: None,
81    /// };
82    ///
83    /// let response = client.create_chat_completion(request).await?;
84    /// println!("Response: {:?}", response.choices[0].message.content);
85    /// # Ok(())
86    /// # }
87    /// ```
88    fn create_chat_completion(
89        &self,
90        request: ChatCompletionRequest,
91    ) -> impl Future<Output = Result<ChatCompletionResponse>>;
92}
93
94impl ChatService for PortkeyClient {
95    async fn create_chat_completion(
96        &self,
97        request: ChatCompletionRequest,
98    ) -> Result<ChatCompletionResponse> {
99        #[cfg(feature = "tracing")]
100        tracing::debug!(
101            target: TRACING_TARGET_SERVICE,
102            model = %request.model,
103            messages_count = request.messages.len(),
104            "Creating chat completion"
105        );
106
107        let response = self
108            .send_json(reqwest::Method::POST, "/chat/completions", &request)
109            .await?;
110        let response = response.error_for_status()?;
111        let chat_response: ChatCompletionResponse = response.json().await?;
112
113        #[cfg(feature = "tracing")]
114        tracing::debug!(
115            target: TRACING_TARGET_SERVICE,
116            id = %chat_response.id,
117            choices_count = chat_response.choices.len(),
118            "Chat completion created successfully"
119        );
120
121        Ok(chat_response)
122    }
123}