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}