openrouter_rs/command.rs
1use futures_util::stream::BoxStream;
2use once_cell::sync::Lazy;
3use tokio::sync::Mutex;
4
5use crate::{
6 api::{api_keys, chat, completion, credits, generation, models},
7 config,
8 error::OpenRouterError,
9};
10
11// Lazy static variables to cache the API key and config
12static DEFAULT_API_KEY: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));
13static PROVISIONING_API_KEY: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));
14static CONFIG: Lazy<Mutex<Option<config::OpenRouterConfig>>> = Lazy::new(|| Mutex::new(None));
15
16async fn get_default_api_key() -> Result<String, OpenRouterError> {
17 let mut api_key = DEFAULT_API_KEY.lock().await;
18 if api_key.is_none() {
19 *api_key = Some(config::api_key::get()?.to_string());
20 }
21 Ok(api_key.clone().unwrap())
22}
23
24async fn get_provisioning_api_key() -> Result<String, OpenRouterError> {
25 let mut api_key = PROVISIONING_API_KEY.lock().await;
26 if api_key.is_none() {
27 *api_key = Some(config::api_key::get()?.to_string());
28 }
29 Ok(api_key.clone().unwrap())
30}
31
32async fn get_config() -> Result<config::OpenRouterConfig, OpenRouterError> {
33 let mut config = CONFIG.lock().await;
34 if config.is_none() {
35 *config = Some(config::load_config()?);
36 }
37 Ok(config.clone().unwrap())
38}
39
40/// Sets the API key for the OpenRouter client.
41///
42/// # Arguments
43///
44/// * `api_key` - The API key to set.
45///
46/// # Returns
47///
48/// * `Result<(), OpenRouterError>` - An empty result indicating success or an error.
49///
50/// # Example
51///
52/// ```
53/// set_api_key("your_api_key").await?;
54/// ```
55pub async fn set_api_key(api_key: &str) -> Result<(), OpenRouterError> {
56 config::api_key::store(api_key)?;
57 let mut cached_api_key = DEFAULT_API_KEY.lock().await;
58 *cached_api_key = Some(api_key.to_string());
59 Ok(())
60}
61
62/// Sends a chat completion request.
63///
64/// # Arguments
65///
66/// * `request` - The chat completion request.
67///
68/// # Returns
69///
70/// * `Result<chat::ChatCompletionResponse, OpenRouterError>` - The response from the chat completion request.
71///
72/// # Example
73///
74/// ```
75/// let request = chat::ChatCompletionRequest::builder()
76/// .model("deepseek/deepseek-chat:free")
77/// .messages(vec![chat::Message::new(chat::Role::User, "What is the meaning of life?")])
78/// .max_tokens(100)
79/// .temperature(0.7)
80/// .build()?;
81/// let response = send_chat_completion(request).await?;
82/// println!("{:?}", response);
83/// ```
84pub async fn send_chat_completion(
85 request: chat::ChatCompletionRequest,
86) -> Result<chat::ChatCompletionResponse, OpenRouterError> {
87 let config = get_config().await?;
88 let api_key = get_default_api_key().await?;
89 chat::send_chat_completion(&config.base_url, &api_key, &request).await
90}
91
92/// Streams chat completion events.
93///
94/// # Arguments
95///
96/// * `request` - The chat completion request.
97///
98/// # Returns
99///
100/// * `Result<BoxStream<'static, Result<chat::ChatCompletionStreamEvent, OpenRouterError>>, OpenRouterError>` - A stream of chat completion events or an error.
101///
102/// # Example
103///
104/// ```
105/// let request = chat::ChatCompletionRequest::builder()
106/// .model("deepseek/deepseek-chat:free")
107/// .messages(vec![chat::Message::new(chat::Role::User, "Tell me a joke.")])
108/// .max_tokens(50)
109/// .temperature(0.5)
110/// .build()?;
111/// let mut stream = stream_chat_completion(request).await?;
112/// while let Some(event) = stream.next().await {
113/// match event {
114/// Ok(event) => println!("{:?}", event),
115/// Err(e) => eprintln!("Error: {:?}", e),
116/// }
117/// }
118/// ```
119pub async fn stream_chat_completion(
120 request: chat::ChatCompletionRequest,
121) -> Result<
122 BoxStream<'static, Result<chat::ChatCompletionStreamEvent, OpenRouterError>>,
123 OpenRouterError,
124> {
125 let config = get_config().await?;
126 let api_key = get_default_api_key().await?;
127 chat::stream_chat_completion(&config.base_url, &api_key, &request).await
128}
129
130/// Sends a completion request.
131///
132/// # Arguments
133///
134/// * `request` - The completion request.
135///
136/// # Returns
137///
138/// * `Result<completion::CompletionResponse, OpenRouterError>` - The response from the completion request.
139///
140/// # Example
141///
142/// ```
143/// let request = completion::CompletionRequest::builder()
144/// .model("deepseek/deepseek-chat:free")
145/// .prompt("Once upon a time")
146/// .max_tokens(100)
147/// .temperature(0.7)
148/// .build()?;
149/// let response = send_completion(request).await?;
150/// println!("{:?}", response);
151/// ```
152pub async fn send_completion(
153 request: completion::CompletionRequest,
154) -> Result<completion::CompletionResponse, OpenRouterError> {
155 let config = get_config().await?;
156 let api_key = get_default_api_key().await?;
157 completion::send_completion_request(&config.base_url, &api_key, &request).await
158}
159
160/// Retrieves the total credits purchased and used for the authenticated user.
161///
162/// # Returns
163///
164/// * `Result<credits::CreditsData, OpenRouterError>` - The response data containing the total credits and usage.
165///
166/// # Example
167///
168/// ```
169/// let credits_data = get_credits().await?;
170/// println!("{:?}", credits_data);
171/// ```
172pub async fn get_credits() -> Result<credits::CreditsData, OpenRouterError> {
173 let config = get_config().await?;
174 let api_key = get_default_api_key().await?;
175 credits::get_credits(&config.base_url, &api_key).await
176}
177
178/// Retrieves metadata about a specific generation request.
179///
180/// # Arguments
181///
182/// * `generation_id` - The ID of the generation request.
183///
184/// # Returns
185///
186/// * `Result<generation::GenerationData, OpenRouterError>` - The metadata of the generation request or an error.
187///
188/// # Example
189///
190/// ```
191/// let generation_data = get_generation("generation_id").await?;
192/// println!("{:?}", generation_data);
193/// ```
194pub async fn get_generation(
195 generation_id: &str,
196) -> Result<generation::GenerationData, OpenRouterError> {
197 let config = get_config().await?;
198 let api_key = get_default_api_key().await?;
199 generation::get_generation(&config.base_url, &api_key, generation_id).await
200}
201
202/// Returns a list of models available through the API.
203///
204/// # Returns
205///
206/// * `Result<Vec<models::Model>, OpenRouterError>` - A list of models or an error.
207///
208/// # Example
209///
210/// ```
211/// let models = list_models().await?;
212/// println!("{:?}", models);
213/// ```
214pub async fn list_models() -> Result<Vec<models::Model>, OpenRouterError> {
215 let config = get_config().await?;
216 let api_key = get_default_api_key().await?;
217 models::list_models(&config.base_url, &api_key).await
218}
219
220/// Returns details about the endpoints for a specific model.
221///
222/// # Arguments
223///
224/// * `author` - The author of the model.
225/// * `slug` - The slug identifier for the model.
226///
227/// # Returns
228///
229/// * `Result<models::EndpointData, OpenRouterError>` - The endpoint data or an error.
230///
231/// # Example
232///
233/// ```
234/// let endpoint_data = list_model_endpoints("author_name", "model_slug").await?;
235/// println!("{:?}", endpoint_data);
236/// ```
237pub async fn list_model_endpoints(
238 author: &str,
239 slug: &str,
240) -> Result<models::EndpointData, OpenRouterError> {
241 let config = get_config().await?;
242 let api_key = get_default_api_key().await?;
243 models::list_model_endpoints(&config.base_url, &api_key, author, slug).await
244}
245
246/// Checks if a specific model is enabled.
247///
248/// # Arguments
249///
250/// * `model_id` - The ID of the model.
251///
252/// # Returns
253///
254/// * `Result<bool, OpenRouterError>` - A boolean indicating whether the model is enabled.
255///
256/// # Example
257///
258/// ```
259/// let is_enabled = is_model_enabled("model_id").await?;
260/// println!("Model enabled: {}", is_enabled);
261/// ```
262pub async fn is_model_enabled(model_id: &str) -> Result<bool, OpenRouterError> {
263 let config = get_config().await?;
264 Ok(config.models.is_enabled(model_id))
265}
266
267/// Retrieves information on the API key associated with the current authentication session.
268///
269/// # Returns
270///
271/// * `Result<api_keys::ApiKeyDetails, OpenRouterError>` - The details of the current API key.
272///
273/// # Example
274///
275/// ```
276/// let api_key_details = get_current_api_key().await?;
277/// println!("{:?}", api_key_details);
278/// ```
279pub async fn get_current_api_key() -> Result<api_keys::ApiKeyDetails, OpenRouterError> {
280 let config = get_config().await?;
281 let api_key = get_default_api_key().await?;
282 api_keys::get_current_api_key(&config.base_url, &api_key).await
283}
284
285/// Returns a list of all API keys associated with the account. Requires a Provisioning API key.
286///
287/// # Arguments
288///
289/// * `offset` - Optional offset for the API keys.
290/// * `include_disabled` - Optional flag to include disabled API keys.
291///
292/// # Returns
293///
294/// * `Result<Vec<api_keys::ApiKey>, OpenRouterError>` - A list of API keys.
295///
296/// # Example
297///
298/// ```
299/// let api_keys = list_api_keys(Some(0.0), Some(true)).await?;
300/// println!("{:?}", api_keys);
301/// ```
302pub async fn list_api_keys(
303 offset: Option<f64>,
304 include_disabled: Option<bool>,
305) -> Result<Vec<api_keys::ApiKey>, OpenRouterError> {
306 let config = get_config().await?;
307 let api_key = get_provisioning_api_key().await?;
308 api_keys::list_api_keys(&config.base_url, &api_key, offset, include_disabled).await
309}
310
311/// Creates a new API key. Requires a Provisioning API key.
312///
313/// # Arguments
314///
315/// * `name` - The display name for the new API key.
316/// * `limit` - Optional credit limit for the new API key.
317///
318/// # Returns
319///
320/// * `Result<api_keys::ApiKey, OpenRouterError>` - The created API key.
321///
322/// # Example
323///
324/// ```
325/// let api_key = create_api_key("New API Key", Some(100.0)).await?;
326/// println!("{:?}", api_key);
327/// ```
328pub async fn create_api_key(
329 name: &str,
330 limit: Option<f64>,
331) -> Result<api_keys::ApiKey, OpenRouterError> {
332 let config = get_config().await?;
333 let api_key = get_provisioning_api_key().await?;
334 api_keys::create_api_key(&config.base_url, &api_key, name, limit).await
335}
336
337/// Returns details about a specific API key. Requires a Provisioning API key.
338///
339/// # Arguments
340///
341/// * `hash` - The hash of the API key to retrieve.
342///
343/// # Returns
344///
345/// * `Result<api_keys::ApiKey, OpenRouterError>` - The details of the specified API key.
346///
347/// # Example
348///
349/// ```
350/// let api_key = get_api_key("api_key_hash").await?;
351/// println!("{:?}", api_key);
352/// ```
353pub async fn get_api_key(hash: &str) -> Result<api_keys::ApiKey, OpenRouterError> {
354 let config = get_config().await?;
355 let api_key = get_provisioning_api_key().await?;
356 api_keys::get_api_key(&config.base_url, &api_key, hash).await
357}
358
359/// Deletes an API key. Requires a Provisioning API key.
360///
361/// # Arguments
362///
363/// * `hash` - The hash of the API key to delete.
364///
365/// # Returns
366///
367/// * `Result<bool, OpenRouterError>` - A boolean indicating whether the deletion was successful.
368///
369/// # Example
370///
371/// ```
372/// let success = delete_api_key("api_key_hash").await?;
373/// println!("Deletion successful: {}", success);
374/// ```
375pub async fn delete_api_key(hash: &str) -> Result<bool, OpenRouterError> {
376 let config = get_config().await?;
377 let api_key = get_provisioning_api_key().await?;
378 api_keys::delete_api_key(&config.base_url, &api_key, hash).await
379}
380
381/// Updates an existing API key. Requires a Provisioning API key.
382///
383/// # Arguments
384///
385/// * `hash` - The hash of the API key to update.
386/// * `name` - Optional new display name for the API key.
387/// * `disabled` - Optional flag to disable the API key.
388/// * `limit` - Optional new credit limit for the API key.
389///
390/// # Returns
391///
392/// * `Result<api_keys::ApiKey, OpenRouterError>` - The updated API key.
393///
394/// # Example
395///
396/// ```
397/// let updated_api_key = update_api_key("api_key_hash", Some("Updated Name".to_string()), Some(false), Some(200.0)).await?;
398/// println!("{:?}", updated_api_key);
399/// ```
400pub async fn update_api_key(
401 hash: &str,
402 name: Option<String>,
403 disabled: Option<bool>,
404 limit: Option<f64>,
405) -> Result<api_keys::ApiKey, OpenRouterError> {
406 let config = get_config().await?;
407 let api_key = get_provisioning_api_key().await?;
408 api_keys::update_api_key(&config.base_url, &api_key, hash, name, disabled, limit).await
409}