use crate::{anthropic_request_json, ApiResponseOrError, Credentials};
use derive_builder::Builder;
use reqwest::Method;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct Model {
pub id: String,
pub display_name: String,
pub created_at: String,
#[serde(rename = "type")]
pub model_type: String,
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct ModelList {
pub data: Vec<Model>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "ModelListBuilder")]
#[builder(setter(strip_option, into))]
pub struct ModelListRequest {
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub before_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub after_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "ModelBuilder")]
#[builder(setter(strip_option, into))]
pub struct ModelRequest {
pub model_id: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
impl ModelList {
pub fn builder() -> ModelListBuilder {
ModelListBuilder::create_empty()
}
pub async fn create(request: ModelListRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let mut query_params = Vec::new();
if let Some(before_id) = &request.before_id {
query_params.push(("before_id", before_id.clone()));
}
if let Some(after_id) = &request.after_id {
query_params.push(("after_id", after_id.clone()));
}
if let Some(limit) = request.limit {
query_params.push(("limit", limit.to_string()));
}
anthropic_request_json(
Method::GET,
"models",
|r| r.query(&query_params),
credentials_opt,
)
.await
}
}
impl Model {
pub fn builder(model_id: impl Into<String>) -> ModelBuilder {
ModelBuilder::create_empty().model_id(model_id)
}
pub async fn create(request: ModelRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("models/{}", request.model_id);
anthropic_request_json(Method::GET, &route, |r| r, credentials_opt).await
}
}
impl ModelListBuilder {
pub async fn create(self) -> ApiResponseOrError<ModelList> {
let request = self.build().unwrap();
ModelList::create(request).await
}
}
impl ModelBuilder {
pub async fn create(self) -> ApiResponseOrError<Model> {
let request = self.build().unwrap();
Model::create(request).await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Credentials;
#[tokio::test]
async fn test_list_models() {
let credentials = Credentials::from_env();
let models = ModelList::builder()
.credentials(credentials)
.create()
.await
.unwrap();
assert!(!models.data.is_empty());
}
#[tokio::test]
async fn test_get_model() {
let credentials = Credentials::from_env();
let models = ModelList::builder()
.credentials(credentials.clone())
.create()
.await
.unwrap();
let model_id = &models.data[0].id;
let model = Model::builder(model_id)
.credentials(credentials)
.create()
.await
.unwrap();
assert_eq!(model.id, *model_id);
}
}