Refactor to tags and ps

This commit is contained in:
2025-12-28 20:35:04 +00:00
parent 7251ac07bd
commit d7cb16a6d8
6 changed files with 25 additions and 36 deletions

View File

@@ -8,8 +8,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
let _ = dotenvy::dotenv(); let _ = dotenvy::dotenv();
let server_address = env::var("OLLAMA_SERVER")?; let server_address = env::var("OLLAMA_SERVER")?;
let ollama_client = OllamaClient::new(server_address); let ollama_client = OllamaClient::new(server_address);
let models = ollama_client.list_runnning_models().await?; let result = ollama_client.ps().await?;
for model in models { for model in result.models {
println!("{:?}", model); println!("{:?}", model);
} }
Ok(()) Ok(())

View File

@@ -8,8 +8,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
let _ = dotenvy::dotenv(); let _ = dotenvy::dotenv();
let server_address = env::var("OLLAMA_SERVER")?; let server_address = env::var("OLLAMA_SERVER")?;
let ollama_client = OllamaClient::new(server_address); let ollama_client = OllamaClient::new(server_address);
let models = ollama_client.tags().await?; let response = ollama_client.tags().await?;
for model in models { for model in response.models {
println!("{:?}", model); println!("{:?}", model);
} }
Ok(()) Ok(())

View File

@@ -1,7 +1,6 @@
use async_stream::stream; use async_stream::stream;
use futures_util::{Stream, StreamExt}; use futures_util::{Stream, StreamExt};
use serde::{Serialize, de::DeserializeOwned}; use serde::{Serialize, de::DeserializeOwned};
use serde_json::Value;
use tokio_util::{ use tokio_util::{
codec::{FramedRead, LinesCodec}, codec::{FramedRead, LinesCodec},
io::StreamReader, io::StreamReader,
@@ -13,9 +12,9 @@ use crate::{
types::{ types::{
chat::{ChatRequest, ChatResponse}, chat::{ChatRequest, ChatResponse},
generate::{GenerateRequest, GenerateResponse}, generate::{GenerateRequest, GenerateResponse},
ps::RunningModel, ps::PsResponse,
pull::{PullRequest, PullResponse}, pull::{PullRequest, PullResponse},
tags::Model, tags::TagsResponse,
version::VersionResponse, version::VersionResponse,
}, },
}; };
@@ -34,6 +33,7 @@ impl OllamaClient {
} }
} }
/// Retrieve the version of the Ollama
pub async fn version(&self) -> OllamaResult<VersionResponse> { pub async fn version(&self) -> OllamaResult<VersionResponse> {
let request_address = format!("{}/api/version", self.server_address); let request_address = format!("{}/api/version", self.server_address);
Ok(reqwest::get(request_address) Ok(reqwest::get(request_address)
@@ -44,47 +44,25 @@ impl OllamaClient {
} }
/// Fetch a list of models and their details /// Fetch a list of models and their details
pub async fn tags(&self) -> OllamaResult<Vec<Model>> { pub async fn tags(&self) -> OllamaResult<TagsResponse> {
let request_address = format!("{}/api/tags", self.server_address); let request_address = format!("{}/api/tags", self.server_address);
info!("List models: {}", request_address); info!("List models: {}", request_address);
let mut response: Value = reqwest::get(request_address) Ok(reqwest::get(request_address)
.await? .await?
.error_for_status()? .error_for_status()?
.json() .json()
.await?; .await?)
let Some(response) = response.as_object_mut() else {
return Ok(vec![]);
};
let Some(models) = response.remove("models") else {
return Ok(vec![]);
};
let models = serde_json::from_value(models)?;
Ok(models)
} }
/// Retrieve a list of models that are currently running /// Retrieve a list of models that are currently running
pub async fn list_runnning_models(&self) -> OllamaResult<Vec<RunningModel>> { pub async fn ps(&self) -> OllamaResult<PsResponse> {
let request_address = format!("{}/api/ps", self.server_address); let request_address = format!("{}/api/ps", self.server_address);
info!("List models: {}", request_address); info!("List models: {}", request_address);
let mut response: Value = reqwest::get(request_address) Ok(reqwest::get(request_address)
.await? .await?
.error_for_status()? .error_for_status()?
.json() .json()
.await?; .await?)
let Some(response) = response.as_object_mut() else {
return Ok(vec![]);
};
let Some(models) = response.remove("models") else {
return Ok(vec![]);
};
let models = serde_json::from_value(models)?;
Ok(models)
} }
async fn stream_response<R: Serialize, T: DeserializeOwned>( async fn stream_response<R: Serialize, T: DeserializeOwned>(
@@ -140,6 +118,7 @@ impl OllamaClient {
self.stream_response(request_address, request).await self.stream_response(request_address, request).await
} }
/// Pull a model
pub async fn pull( pub async fn pull(
&self, &self,
request: PullRequest, request: PullRequest,

View File

@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
pub struct ModelDetails { pub struct ModelDetails {
pub format: String, pub format: String,
pub family: String, pub family: String,
pub families: Vec<String>, pub families: Option<Vec<String>>,
pub parameter_size: String, pub parameter_size: String,
pub quantization_level: String, pub quantization_level: String,
} }

View File

@@ -2,6 +2,11 @@ use serde::{Deserialize, Serialize};
use crate::types::common::ModelDetails; use crate::types::common::ModelDetails;
#[derive(Debug, Serialize, Deserialize)]
pub struct PsResponse {
pub models: Vec<RunningModel>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct RunningModel { pub struct RunningModel {
pub name: String, pub name: String,

View File

@@ -2,6 +2,11 @@ use serde::{Deserialize, Serialize};
use crate::types::common::ModelDetails; use crate::types::common::ModelDetails;
#[derive(Debug, Serialize, Deserialize)]
pub struct TagsResponse {
pub models: Vec<Model>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Model { pub struct Model {
pub name: String, pub name: String,