feat: implement api/show endpoint
This commit is contained in:
@@ -162,6 +162,7 @@ When the model decides to call a tool, the response `message.tool_calls` field w
|
||||
| `chat(request)` | Chat conversation (streaming) |
|
||||
| `pull(request)` | Pull/download a model (streaming) |
|
||||
| `delete(request)` | Delete a model from the server |
|
||||
| `show_model(request)` | Show information about a model |
|
||||
| `embed(request)` | Generate vector embeddings |
|
||||
|
||||
**`OllamaClient::builder(server_address)`** -- `.connection_timeout(Duration)`, `.build()`
|
||||
@@ -185,6 +186,8 @@ let client = OllamaClient::builder("http://localhost:11434")
|
||||
|
||||
**`EmbedRequest::builder(model)`** -- `.input()`, `.inputs()`, `.truncate()`, `.dimensions()`, `.keep_alive()`, `.options()`
|
||||
|
||||
**`ShowModelRequest::new(model)`** -- `.verbose()`
|
||||
|
||||
### Generation Options
|
||||
|
||||
Configure sampling parameters via `Options::builder()`:
|
||||
@@ -212,6 +215,7 @@ The `examples/` directory contains runnable programs:
|
||||
| `tool_call` | Function calling / tool use |
|
||||
| `pull` | Download a model |
|
||||
| `delete` | Delete a model |
|
||||
| `show_model` | Show model information |
|
||||
| `embed` | Generate text embeddings |
|
||||
| `tags` | List available models |
|
||||
| `ps` | List running models |
|
||||
|
||||
22
examples/show_model.rs
Normal file
22
examples/show_model.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use ollama_rs::OllamaClient;
|
||||
use ollama_rs::types::show::ShowModelRequest;
|
||||
use std::error::Error;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let client = OllamaClient::default();
|
||||
let model = "qwen3:8b";
|
||||
|
||||
println!("Requesting info for model: {}", model);
|
||||
let request = ShowModelRequest::new(model.to_string());
|
||||
let response = client.show_model(request).await?;
|
||||
|
||||
println!("Model Info:");
|
||||
println!(" License: {}", response.license.as_deref().unwrap_or("N/A").lines().next().unwrap_or("")); // First line only
|
||||
println!(" Modelfile: {} bytes", response.modelfile.as_ref().map(|s| s.len()).unwrap_or(0));
|
||||
println!(" Parameters: {}", response.parameters.as_ref().map(|s| s.len()).unwrap_or(0));
|
||||
println!(" Template: {:?}", response.template.is_some());
|
||||
println!(" Details: {:?}", response.details);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
38
src/lib.rs
38
src/lib.rs
@@ -98,6 +98,7 @@ use crate::{
|
||||
generate::{GenerateRequest, GenerateResponse},
|
||||
ps::PsResponse,
|
||||
pull::{PullRequest, PullResponse},
|
||||
show::{ShowModelRequest, ShowModelResponse},
|
||||
tags::TagsResponse,
|
||||
version::VersionResponse,
|
||||
},
|
||||
@@ -456,6 +457,43 @@ impl OllamaClient {
|
||||
let request_address = format!("{}/api/pull", self.server_address);
|
||||
self.stream_response(request_address, request)
|
||||
}
|
||||
|
||||
/// Shows information about a model.
|
||||
///
|
||||
/// Calls `POST /api/show`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns [`OllamaError::NetworkError`] if the server is unreachable or returns
|
||||
/// a non-success status code.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use ollama_rs::OllamaClient;
|
||||
/// # use ollama_rs::types::show::ShowModelRequest;
|
||||
/// # async fn run() -> ollama_rs::error::OllamaResult<()> {
|
||||
/// let client = OllamaClient::default();
|
||||
/// let request = ShowModelRequest::new("llama3".to_string());
|
||||
///
|
||||
/// let response = client.show_model(request).await?;
|
||||
/// println!("Model info: {:?}", response);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub async fn show_model(&self, request: ShowModelRequest) -> OllamaResult<ShowModelResponse> {
|
||||
let request_address = format!("{}/api/show", self.server_address);
|
||||
info!("Show model: {}", request.name);
|
||||
Ok(self
|
||||
.client
|
||||
.post(request_address)
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.json()
|
||||
.await?)
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for constructing an [`OllamaClient`] with custom configuration.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Detailed metadata about a model, returned by the tags and ps endpoints.
|
||||
/// Detailed metadata about a model, returned by the tags, ps, and show endpoints.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ModelDetails {
|
||||
/// The model file format (e.g., `"gguf"`).
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
//! | [`embed`] | `POST /api/embed` | Generate vector embeddings |
|
||||
//! | [`generate`] | `POST /api/generate` | Single-prompt text generation |
|
||||
//! | [`pull`] | `POST /api/pull` | Download models from the registry |
|
||||
//! | [`show`] | `POST /api/show` | Show model details |
|
||||
//! | [`tags`] | `GET /api/tags` | List available models |
|
||||
//! | [`ps`] | `GET /api/ps` | List currently loaded/running models |
|
||||
//! | [`version`] | `GET /api/version` | Query the server version |
|
||||
@@ -24,5 +25,6 @@ pub mod embed;
|
||||
pub mod generate;
|
||||
pub mod ps;
|
||||
pub mod pull;
|
||||
pub mod show;
|
||||
pub mod tags;
|
||||
pub mod version;
|
||||
|
||||
101
src/types/show.rs
Normal file
101
src/types/show.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
//! Types for the show model information endpoint (`POST /api/show`).
|
||||
//!
|
||||
//! Use [`ShowModelRequest`] to construct a request and pass it to
|
||||
//! [`OllamaClient::show_model`](crate::OllamaClient::show_model).
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::common::ModelDetails;
|
||||
|
||||
/// A request to the show model endpoint (`POST /api/show`).
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ShowModelRequest {
|
||||
/// The name of the model to retrieve information for.
|
||||
pub name: String,
|
||||
/// Whether to return full model details (e.g. system prompt, template).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub verbose: Option<bool>,
|
||||
}
|
||||
|
||||
impl ShowModelRequest {
|
||||
/// Creates a new request for the given model name.
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
verbose: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables verbose output, returning full model details.
|
||||
pub fn verbose(mut self) -> Self {
|
||||
self.verbose = Some(true);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A response from the show model endpoint.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ShowModelResponse {
|
||||
/// The license of the model.
|
||||
pub license: Option<String>,
|
||||
/// The modelfile content.
|
||||
pub modelfile: Option<String>,
|
||||
/// The model parameters (e.g., stop tokens, temperature defaults).
|
||||
pub parameters: Option<String>,
|
||||
/// The prompt template.
|
||||
pub template: Option<String>,
|
||||
/// The system prompt.
|
||||
pub system: Option<String>,
|
||||
/// Detailed model metadata.
|
||||
pub details: Option<ModelDetails>,
|
||||
/// Additional model information.
|
||||
pub model_info: Option<serde_json::Map<String, serde_json::Value>>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn request_new_serialized() {
|
||||
let request = ShowModelRequest::new("llama3".to_string());
|
||||
let json = serde_json::to_value(&request).unwrap();
|
||||
assert_eq!(json, json!({"name": "llama3"}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn request_verbose_serialized() {
|
||||
let request = ShowModelRequest::new("llama3".to_string()).verbose();
|
||||
let json = serde_json::to_value(&request).unwrap();
|
||||
assert_eq!(json, json!({"name": "llama3", "verbose": true}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_deserialization() {
|
||||
let json = json!({
|
||||
"license": "MIT",
|
||||
"modelfile": "FROM llama3",
|
||||
"parameters": "temperature 0.7",
|
||||
"template": "Please answer:",
|
||||
"system": "You are helpful",
|
||||
"details": {
|
||||
"format": "gguf",
|
||||
"family": "llama",
|
||||
"families": ["llama"],
|
||||
"parameter_size": "8B",
|
||||
"quantization_level": "Q4_0"
|
||||
}
|
||||
});
|
||||
let response: ShowModelResponse = serde_json::from_value(json).unwrap();
|
||||
assert_eq!(response.license, Some("MIT".to_string()));
|
||||
assert_eq!(response.modelfile, Some("FROM llama3".to_string()));
|
||||
assert_eq!(response.parameters, Some("temperature 0.7".to_string()));
|
||||
assert_eq!(response.template, Some("Please answer:".to_string()));
|
||||
assert_eq!(response.system, Some("You are helpful".to_string()));
|
||||
|
||||
let details = response.details.unwrap();
|
||||
assert_eq!(details.format, "gguf");
|
||||
assert_eq!(details.family, "llama");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user