ModelService

Struct ModelService 

Source
pub struct ModelService {
    repo: Arc<dyn ModelRepository>,
}
Expand description

Service for model operations.

This service provides high-level model management by delegating to the injected ModelRepository. It adds no business logic beyond what the repository provides - it’s a thin facade.

Fields§

§repo: Arc<dyn ModelRepository>

Implementations§

Source§

impl ModelService

Source

pub fn new(repo: Arc<dyn ModelRepository>) -> Self

Create a new model service with the given repository.

Source

pub async fn list(&self) -> Result<Vec<Model>, CoreError>

List all models.

Source

pub async fn get(&self, identifier: &str) -> Result<Option<Model>, CoreError>

Get a model by its identifier (id, name, or HF ID).

Source

pub async fn get_by_id(&self, id: i64) -> Result<Option<Model>, CoreError>

Get a model by its database ID.

Source

pub async fn get_by_name(&self, name: &str) -> Result<Option<Model>, CoreError>

Get a model by name.

Source

pub async fn find_by_identifier( &self, identifier: &str, ) -> Result<Model, CoreError>

Find a model by identifier (id, name, or HF ID). Returns error if not found.

Source

pub async fn find_by_name(&self, name: &str) -> Result<Model, CoreError>

Find a model by name. Returns error if not found.

Source

pub async fn add(&self, model: NewModel) -> Result<Model, CoreError>

Add a new model.

Source

pub async fn import_from_file( &self, file_path: &Path, gguf_parser: &dyn GgufParserPort, param_count_override: Option<f64>, ) -> Result<Model, CoreError>

Import a model from a local GGUF file with full metadata extraction.

Validates file, parses GGUF metadata, detects capabilities, and registers with rich metadata. This is the canonical way to add local models.

§Arguments
  • file_path - Absolute path to the GGUF file
  • gguf_parser - Parser implementation for metadata extraction
  • param_count_override - Optional user override for parameter count
§Returns

Returns the registered Model with full metadata, or validation error.

§Design

This method orchestrates:

  1. File validation (existence, extension)
  2. GGUF metadata parsing (architecture, quantization, context)
  3. Capability detection (reasoning, tool-calling from metadata)
  4. Chat template inference (additional capability signals)
  5. Auto-tag generation from detected capabilities
  6. Model persistence with complete NewModel struct
Source

pub async fn update(&self, model: &Model) -> Result<(), CoreError>

Update a model.

Source

pub async fn delete(&self, id: i64) -> Result<(), CoreError>

Delete a model by ID.

Source

pub async fn remove(&self, identifier: &str) -> Result<Model, CoreError>

Remove a model by identifier. Returns the removed model.

Source

pub async fn list_tags(&self) -> Result<Vec<String>, CoreError>

List all unique tags used across all models.

Source

pub async fn add_tag(&self, model_id: i64, tag: String) -> Result<(), CoreError>

Add a tag to a model.

If the tag already exists on the model, this is a no-op.

Source

pub async fn remove_tag( &self, model_id: i64, tag: &str, ) -> Result<(), CoreError>

Remove a tag from a model.

If the tag doesn’t exist on the model, this is a no-op.

Source

pub async fn get_tags(&self, model_id: i64) -> Result<Vec<String>, CoreError>

Get all tags for a specific model.

Source

pub async fn get_by_tag(&self, tag: &str) -> Result<Vec<Model>, CoreError>

Get all models that have a specific tag.

Source

pub async fn get_filter_options(&self) -> Result<ModelFilterOptions, CoreError>

Get filter options aggregated from all models.

Returns distinct quantizations, parameter count range, and context length range for use in the GUI filter popover.

Note: Uses in-memory aggregation for simplicity. This is acceptable for typical model libraries (<100 models). Revisit if libraries grow large.

Source

pub async fn bootstrap_capabilities(&self) -> Result<(), CoreError>

Backfill capabilities for models that don’t have them set.

This runs on startup to handle models with unknown capabilities. Only infers if capabilities are empty (0/unknown).

§INVARIANT

Never overwrite explicitly-set capabilities. Only infer when unknown.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.