Add delete model endpoint (DELETE /api/delete)

Implement the Ollama DELETE /api/delete endpoint for removing models
from the server.

- Add DeleteRequest type with model field in src/types/delete.rs
- Add OllamaClient::delete() async method in src/lib.rs
- Register delete module in src/types/mod.rs
- Add usage example in examples/delete.rs
This commit is contained in:
2026-02-01 21:14:26 +00:00
parent f15a2c53d6
commit 63c08c484c
4 changed files with 138 additions and 8 deletions

16
examples/delete.rs Normal file
View File

@@ -0,0 +1,16 @@
use std::{env, error::Error};
use ollama_rs::OllamaClient;
use ollama_rs::types::delete::DeleteRequest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
tracing_subscriber::fmt().init();
let _ = dotenvy::dotenv();
let server_address = env::var("OLLAMA_SERVER")?;
let model = env::args().nth(1).expect("usage: delete <model>");
let ollama_client = OllamaClient::new(server_address);
ollama_client.delete(DeleteRequest::new(&model)).await?;
println!("Model '{}' deleted successfully", model);
Ok(())
}

View File

@@ -93,6 +93,7 @@ use crate::{
error::{OllamaError, OllamaResult},
types::{
chat::{ChatRequest, ChatResponse},
delete::DeleteRequest,
generate::{GenerateRequest, GenerateResponse},
ps::PsResponse,
pull::{PullRequest, PullResponse},
@@ -247,6 +248,40 @@ impl OllamaClient {
.await?)
}
/// Deletes a model from the Ollama server.
///
/// Calls `DELETE /api/delete`.
///
/// # Errors
///
/// Returns [`OllamaError::NetworkError`] if the server is unreachable, the model
/// does not exist, or the server returns a non-success status code.
///
/// # Examples
///
/// ```no_run
/// # use ollama_rs::OllamaClient;
/// # use ollama_rs::types::delete::DeleteRequest;
/// # async fn run() -> ollama_rs::error::OllamaResult<()> {
/// let client = OllamaClient::default();
/// let request = DeleteRequest::new("gemma3");
/// client.delete(request).await?;
/// println!("Model deleted successfully");
/// # Ok(())
/// # }
/// ```
pub async fn delete(&self, request: DeleteRequest) -> OllamaResult<()> {
let request_address = format!("{}/api/delete", self.server_address);
info!("Delete model: {}", request.model);
self.client
.delete(request_address)
.json(&request)
.send()
.await?
.error_for_status()?;
Ok(())
}
fn stream_response<R: Serialize, T: DeserializeOwned>(
&self,
endpoint: String,

77
src/types/delete.rs Normal file
View File

@@ -0,0 +1,77 @@
//! Types for the model delete endpoint (`DELETE /api/delete`).
//!
//! Use [`DeleteRequest::new()`] to construct a request and pass it to
//! [`OllamaClient::delete()`](crate::OllamaClient::delete).
//!
//! # Examples
//!
//! ```no_run
//! # use ollama_rs::OllamaClient;
//! # use ollama_rs::types::delete::DeleteRequest;
//! # async fn run() -> ollama_rs::error::OllamaResult<()> {
//! let client = OllamaClient::default();
//! let request = DeleteRequest::new("gemma3");
//! client.delete(request).await?;
//! println!("Model deleted successfully");
//! # Ok(())
//! # }
//! ```
use serde::{Deserialize, Serialize};
/// A request to delete a model from the Ollama server (`DELETE /api/delete`).
///
/// # Examples
///
/// ```
/// use ollama_rs::types::delete::DeleteRequest;
///
/// let request = DeleteRequest::new("gemma3");
/// assert_eq!(request.model, "gemma3");
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct DeleteRequest {
/// The name of the model to delete (e.g., `"gemma3"`, `"llama3:latest"`).
pub model: String,
}
impl DeleteRequest {
/// Creates a new [`DeleteRequest`] for the given model name.
pub fn new<M: Into<String>>(model: M) -> Self {
Self {
model: model.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn new_creates_request() {
let request = DeleteRequest::new("gemma3");
assert_eq!(request.model, "gemma3");
}
#[test]
fn new_accepts_string() {
let request = DeleteRequest::new(String::from("llama3:latest"));
assert_eq!(request.model, "llama3:latest");
}
#[test]
fn request_serializes_correctly() {
let request = DeleteRequest::new("gemma3");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json, json!({"model": "gemma3"}));
}
#[test]
fn request_deserializes_correctly() {
let json = json!({"model": "gemma3"});
let request: DeleteRequest = serde_json::from_value(json).unwrap();
assert_eq!(request.model, "gemma3");
}
}

View File

@@ -2,14 +2,15 @@
//!
//! Each submodule corresponds to an API endpoint:
//!
//! | Module | Endpoint | Description |
//! |--------------|-------------------|------------------------------------------|
//! | [`chat`] | `POST /api/chat` | Multi-turn chat conversations |
//! | [`generate`] | `POST /api/generate` | Single-prompt text generation |
//! | [`pull`] | `POST /api/pull` | Download models from the registry |
//! | [`tags`] | `GET /api/tags` | List available models |
//! | [`ps`] | `GET /api/ps` | List currently loaded/running models |
//! | [`version`] | `GET /api/version` | Query the server version |
//! | Module | Endpoint | Description |
//! |--------------|-----------------------|------------------------------------------|
//! | [`chat`] | `POST /api/chat` | Multi-turn chat conversations |
//! | [`delete`] | `DELETE /api/delete` | Delete a model from the server |
//! | [`generate`] | `POST /api/generate` | Single-prompt text generation |
//! | [`pull`] | `POST /api/pull` | Download models from the registry |
//! | [`tags`] | `GET /api/tags` | List available models |
//! | [`ps`] | `GET /api/ps` | List currently loaded/running models |
//! | [`version`] | `GET /api/version` | Query the server version |
//!
//! The [`common`] module contains types shared across multiple endpoints, such as
//! [`Options`](common::Options) for generation parameters, [`Think`](common::Think)
@@ -17,6 +18,7 @@
pub mod chat;
pub mod common;
pub mod delete;
pub mod generate;
pub mod ps;
pub mod pull;