Coverage for src / lilbee / catalog / models.py: 100%
57 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-15 20:55 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-15 20:55 +0000
1"""Catalog dataclasses and pydantic types: leaf module, no sibling imports."""
3from dataclasses import dataclass
5from pydantic import BaseModel
7from lilbee.catalog.types import ModelTask
10class HfGgufMeta(BaseModel):
11 """GGUF metadata returned by the HF API when expand=gguf is requested.
13 ModelInfo.gguf is typed as ``dict | None`` upstream, so we validate it ourselves.
14 """
16 total: int = 0
17 architecture: str = ""
18 context_length: int = 0
21@dataclass
22class DownloadProgress:
23 """Human-readable snapshot of download progress.
25 ``percent`` is a float (0.0 to 100.0) so the ProgressBar renders smooth
26 fractional movement during multi-GB downloads. Call sites that need
27 an integer for display format it themselves.
28 """
30 percent: float
31 detail: str
32 is_cache_hit: bool
35@dataclass(frozen=True)
36class CatalogModel:
37 """One catalog entry, keyed by HuggingFace repo. ``gguf_filename`` may be a glob."""
39 hf_repo: str
40 gguf_filename: str
41 size_gb: float
42 min_ram_gb: float
43 description: str
44 featured: bool
45 downloads: int
46 task: ModelTask
47 recommended: bool = False
49 @property
50 def ref(self) -> str:
51 """Browse-time ref (the HF repo); concrete filename is resolved at install."""
52 return self.hf_repo
54 @property
55 def display_name(self) -> str:
56 """Human-readable label derived from the HuggingFace repo id."""
57 # Local import keeps models.py a leaf (no sibling imports at module top).
58 from lilbee.catalog.formatting import clean_display_name
60 return clean_display_name(self.hf_repo)
63@dataclass(frozen=True)
64class CatalogResult:
65 """Paginated catalog result."""
67 total: int
68 limit: int
69 offset: int
70 models: list[CatalogModel]
71 has_more: bool = False
74@dataclass(frozen=True)
75class HfPage:
76 """One page of HuggingFace API results."""
78 models: list[CatalogModel]
79 has_more: bool
82@dataclass(frozen=True)
83class ModelVariant:
84 """One quantization within a model family. ``filename`` may be a glob."""
86 hf_repo: str
87 filename: str
88 param_count: str
89 quant: str
90 size_mb: int
91 recommended: bool
92 mmproj_filename: str = ""
95@dataclass(frozen=True)
96class ModelFamily:
97 """A group of related model variants (e.g. Qwen3 in multiple sizes)."""
99 slug: str # family slug for building refs: "qwen3"
100 name: str # display name: "Qwen3"
101 task: ModelTask
102 description: str
103 variants: tuple[ModelVariant, ...]