openrouter_rs/api/
models.rs

1use serde::{Deserialize, Serialize};
2use surf::http::headers::AUTHORIZATION;
3use urlencoding::encode;
4
5use crate::{error::OpenRouterError, types::ApiResponse, utils::handle_error};
6
7#[derive(Serialize, Deserialize, Debug)]
8pub struct Model {
9    pub id: String,
10    pub name: String,
11    pub created: f64,
12    pub description: String,
13    pub context_length: f64,
14    pub architecture: Architecture,
15    pub top_provider: TopProvider,
16    pub pricing: Pricing,
17    pub per_request_limits: Option<std::collections::HashMap<String, String>>,
18}
19
20#[derive(Serialize, Deserialize, Debug)]
21pub struct Architecture {
22    pub modality: String,
23    pub tokenizer: String,
24    pub instruct_type: Option<String>,
25}
26
27#[derive(Serialize, Deserialize, Debug)]
28pub struct TopProvider {
29    pub context_length: Option<f64>,
30    pub max_completion_tokens: Option<f64>,
31    pub is_moderated: bool,
32}
33
34#[derive(Serialize, Deserialize, Debug)]
35pub struct Pricing {
36    pub prompt: String,
37    pub completion: String,
38    pub image: String,
39    pub request: String,
40    pub input_cache_read: String,
41    pub input_cache_write: String,
42    pub web_search: String,
43    pub internal_reasoning: String,
44}
45
46#[derive(Serialize, Deserialize, Debug)]
47pub struct Endpoint {
48    pub name: String,
49    pub context_length: f64,
50    pub pricing: EndpointPricing,
51    pub provider_name: String,
52    pub supported_parameters: Vec<String>,
53    pub quantization: Option<String>,
54    pub max_completion_tokens: Option<f64>,
55    pub max_prompt_tokens: Option<f64>,
56    pub status: Option<serde_json::Value>,
57}
58
59#[derive(Serialize, Deserialize, Debug)]
60pub struct EndpointPricing {
61    pub request: String,
62    pub image: String,
63    pub prompt: String,
64    pub completion: String,
65}
66
67#[derive(Serialize, Deserialize, Debug)]
68pub struct EndpointData {
69    pub id: String,
70    pub name: String,
71    pub created: f64,
72    pub description: String,
73    pub architecture: EndpointArchitecture,
74    pub endpoints: Vec<Endpoint>,
75}
76
77#[derive(Serialize, Deserialize, Debug)]
78pub struct EndpointArchitecture {
79    pub tokenizer: Option<String>,
80    pub instruct_type: Option<String>,
81    pub modality: Option<String>,
82}
83
84/// Returns a list of models available through the API
85///
86/// # Arguments
87///
88/// * `base_url` - The base URL of the OpenRouter API.
89/// * `api_key` - The API key for authentication.
90///
91/// # Returns
92///
93/// * `Result<Vec<Model>, OpenRouterError>` - A list of models or an error.
94pub async fn list_models(base_url: &str, api_key: &str) -> Result<Vec<Model>, OpenRouterError> {
95    let url = format!("{}/models", base_url);
96
97    let mut response = surf::get(url)
98        .header(AUTHORIZATION, format!("Bearer {}", api_key))
99        .await?;
100
101    if response.status().is_success() {
102        let model_list_response: ApiResponse<_> = response.body_json().await?;
103        Ok(model_list_response.data)
104    } else {
105        handle_error(response).await?;
106        unreachable!()
107    }
108}
109
110/// Returns details about the endpoints for a specific model
111///
112/// # Arguments
113///
114/// * `base_url` - The base URL of the OpenRouter API.
115/// * `api_key` - The API key for authentication.
116/// * `author` - The author of the model.
117/// * `slug` - The slug identifier for the model.
118///
119/// # Returns
120///
121/// * `Result<EndpointData, OpenRouterError>` - The endpoint data or an error.
122pub async fn list_model_endpoints(
123    base_url: &str,
124    api_key: &str,
125    author: &str,
126    slug: &str,
127) -> Result<EndpointData, OpenRouterError> {
128    let encoded_author = encode(&author);
129    let encoded_slug = encode(&slug);
130    let url = format!(
131        "{}/models/{}/{}/endpoints",
132        base_url, encoded_author, encoded_slug
133    );
134    println!("URL: {}", url);
135
136    let mut response = surf::get(&url)
137        .header(AUTHORIZATION, format!("Bearer {}", api_key))
138        .await?;
139
140    if response.status().is_success() {
141        let endpoint_list_response: ApiResponse<_> = response.body_json().await?;
142        Ok(endpoint_list_response.data)
143    } else {
144        handle_error(response).await?;
145        unreachable!()
146    }
147}