opendev_http/adapters/
groq.rs1use serde_json::{Value, json};
10
11const DEFAULT_API_URL: &str = "https://api.groq.com/openai/v1/chat/completions";
12
13#[derive(Debug, Clone, Default)]
15pub struct RateLimitInfo {
16 pub limit_requests: Option<u64>,
18 pub limit_tokens: Option<u64>,
20 pub remaining_requests: Option<u64>,
22 pub remaining_tokens: Option<u64>,
24 pub reset_requests: Option<String>,
26 pub reset_tokens: Option<String>,
28}
29
30impl RateLimitInfo {
31 pub fn from_headers(headers: &[(String, String)]) -> Self {
41 let mut info = Self::default();
42 for (key, value) in headers {
43 match key.as_str() {
44 "x-ratelimit-limit-requests" => {
45 info.limit_requests = value.parse().ok();
46 }
47 "x-ratelimit-limit-tokens" => {
48 info.limit_tokens = value.parse().ok();
49 }
50 "x-ratelimit-remaining-requests" => {
51 info.remaining_requests = value.parse().ok();
52 }
53 "x-ratelimit-remaining-tokens" => {
54 info.remaining_tokens = value.parse().ok();
55 }
56 "x-ratelimit-reset-requests" => {
57 info.reset_requests = Some(value.clone());
58 }
59 "x-ratelimit-reset-tokens" => {
60 info.reset_tokens = Some(value.clone());
61 }
62 _ => {}
63 }
64 }
65 info
66 }
67
68 pub fn to_json(&self) -> Value {
70 let mut obj = json!({});
71 if let Some(v) = self.limit_requests {
72 obj["limit_requests"] = json!(v);
73 }
74 if let Some(v) = self.limit_tokens {
75 obj["limit_tokens"] = json!(v);
76 }
77 if let Some(v) = self.remaining_requests {
78 obj["remaining_requests"] = json!(v);
79 }
80 if let Some(v) = self.remaining_tokens {
81 obj["remaining_tokens"] = json!(v);
82 }
83 if let Some(ref v) = self.reset_requests {
84 obj["reset_requests"] = json!(v);
85 }
86 if let Some(ref v) = self.reset_tokens {
87 obj["reset_tokens"] = json!(v);
88 }
89 obj
90 }
91}
92
93#[derive(Debug, Clone)]
98pub struct GroqAdapter {
99 api_url: String,
100}
101
102impl GroqAdapter {
103 pub fn new() -> Self {
105 Self {
106 api_url: DEFAULT_API_URL.to_string(),
107 }
108 }
109
110 pub fn with_url(url: impl Into<String>) -> Self {
112 Self {
113 api_url: url.into(),
114 }
115 }
116
117 fn clean_request(payload: &mut Value) {
121 if let Some(obj) = payload.as_object_mut() {
122 obj.remove("logprobs");
123 obj.remove("top_logprobs");
124 obj.remove("n");
125 }
126 }
127}
128
129impl Default for GroqAdapter {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135#[async_trait::async_trait]
136impl super::base::ProviderAdapter for GroqAdapter {
137 fn provider_name(&self) -> &str {
138 "groq"
139 }
140
141 fn convert_request(&self, mut payload: Value) -> Value {
142 Self::clean_request(&mut payload);
143 payload
145 .as_object_mut()
146 .map(|obj| obj.remove("_reasoning_effort"));
147 payload
148 }
149
150 fn convert_response(&self, response: Value) -> Value {
151 response
153 }
154
155 fn api_url(&self) -> &str {
156 &self.api_url
157 }
158}
159
160#[cfg(test)]
161#[path = "groq_tests.rs"]
162mod tests;