Skip to main content

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 (numeric database id, then exact name).

Thin wrapper over ModelRepository::get_by_identifier, which owns the lookup-key policy so this service and the ModelCatalogPort adapter cannot disagree about what a given string resolves to.

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 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 validates and parses the GGUF file, then delegates naming, capability detection, and tag generation to build_new_model — the construction path shared with the HuggingFace download path — before persisting the result.

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. System tags (see crate::domain::is_system_tag) are protected and cannot be removed through this API — use Self::remove_tag_force for admin/debug paths that intentionally need to drop them.

Source

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

Force-remove a tag from a model, including system tags.

Bypasses the system-tag protection enforced by Self::remove_tag. Intended for admin/debug paths (e.g. the gglib model retag --full rebuild) where the caller intentionally needs to drop a format:* tag before re-detecting capabilities.

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.

Source

pub async fn retag_model( &self, model_id: i64, gguf_parser: &dyn GgufParserPort, full: bool, ) -> Result<Option<RetagDiff>, CoreError>

Re-derive auto-tags for a single model from its persisted GGUF metadata.

full = false (default) is additive: any newly-detected tag that isn’t already present is appended; nothing is ever removed. This is the safe path for backfilling format:* tags on models imported before format-tag detection landed.

full = true performs a full rebuild: every previously auto-generated tag (the predefined capability tag namespace plus every existing format:* tag) is dropped and the freshly-detected set is added in its place. User-curated tags outside that namespace are preserved.

Returns None when the tag set is unchanged (no write occurred) and Some(diff) when the model was updated, carrying the full added/removed delta.

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Same for T

Source§

type Output = T

Should always be Self
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.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more