kowalski_core/model/
mod.rs1use crate::error::KowalskiError;
2use reqwest::Client;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Serialize, Deserialize)]
6pub struct ModelInfo {
7 pub name: String,
8 pub size: u64,
9 pub digest: String,
10 pub modified_at: String,
11}
12
13#[derive(Debug, Serialize, Deserialize)]
14pub struct ModelsResponse {
15 pub models: Vec<ModelInfo>,
16}
17
18#[derive(Debug, Serialize, Deserialize)]
19pub struct PullResponse {
20 pub status: String,
21 pub digest: Option<String>,
22 pub total: Option<u64>,
23 pub completed: Option<u64>,
24}
25
26pub struct ModelManager {
28 client: Client,
29 base_url: String,
30}
31
32impl ModelManager {
33 pub fn new(base_url: String) -> Result<Self, KowalskiError> {
35 let client = reqwest::ClientBuilder::new()
36 .pool_max_idle_per_host(0)
37 .build()
38 .map_err(KowalskiError::Request)?;
39
40 Ok(Self { client, base_url })
41 }
42
43 pub async fn list_models(&self) -> Result<ModelsResponse, KowalskiError> {
45 let response = self
46 .client
47 .get(format!("{}/api/tags", self.base_url))
48 .send()
49 .await?;
50
51 if !response.status().is_success() {
52 let error_text = response.text().await?;
53 return Err(KowalskiError::Server(error_text));
54 }
55
56 let models_response: ModelsResponse = response.json().await?;
57 Ok(models_response)
58 }
59
60 pub async fn model_exists(&self, model_name: &str) -> Result<bool, KowalskiError> {
62 let models = self.list_models().await?;
63 Ok(models.models.iter().any(|m| m.name == model_name))
64 }
65
66 pub async fn pull_model(&self, model_name: &str) -> Result<PullResponse, KowalskiError> {
68 let response = self
69 .client
70 .post(format!("{}/api/pull", self.base_url))
71 .json(&serde_json::json!({
72 "name": model_name
73 }))
74 .send()
75 .await?;
76
77 if !response.status().is_success() {
78 let error_text = response.text().await?;
79 return Err(KowalskiError::Server(error_text));
80 }
81
82 let pull_response: PullResponse = response.json().await?;
83 Ok(pull_response)
84 }
85}