Coverage for src / lilbee / catalog / models.py: 100%

59 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-06-28 01:01 +0000

1"""Catalog dataclasses and pydantic types: leaf module, no sibling imports.""" 

2 

3from dataclasses import dataclass 

4 

5from pydantic import BaseModel 

6 

7from lilbee.catalog.types import ModelCompat, ModelTask 

8 

9 

10class HfGgufMeta(BaseModel): 

11 """GGUF metadata returned by the HF API when expand=gguf is requested. 

12 

13 ModelInfo.gguf is typed as ``dict | None`` upstream, so we validate it ourselves. 

14 """ 

15 

16 total: int = 0 

17 architecture: str = "" 

18 context_length: int = 0 

19 

20 

21@dataclass 

22class DownloadProgress: 

23 """Human-readable snapshot of download progress. 

24 

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 """ 

29 

30 percent: float 

31 detail: str 

32 is_cache_hit: bool 

33 

34 

35@dataclass(frozen=True) 

36class CatalogModel: 

37 """One catalog entry, keyed by HuggingFace repo. ``gguf_filename`` may be a glob.""" 

38 

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 

48 architecture: str = "" 

49 compat: ModelCompat = ModelCompat.UNKNOWN 

50 

51 @property 

52 def ref(self) -> str: 

53 """Browse-time ref (the HF repo); concrete filename is resolved at install.""" 

54 return self.hf_repo 

55 

56 @property 

57 def display_name(self) -> str: 

58 """Human-readable label derived from the HuggingFace repo id.""" 

59 # Local import keeps models.py a leaf (no sibling imports at module top). 

60 from lilbee.catalog.formatting import clean_display_name 

61 

62 return clean_display_name(self.hf_repo) 

63 

64 

65@dataclass(frozen=True) 

66class CatalogResult: 

67 """Paginated catalog result.""" 

68 

69 total: int 

70 limit: int 

71 offset: int 

72 models: list[CatalogModel] 

73 has_more: bool = False 

74 

75 

76@dataclass(frozen=True) 

77class HfPage: 

78 """One page of HuggingFace API results.""" 

79 

80 models: list[CatalogModel] 

81 has_more: bool 

82 

83 

84@dataclass(frozen=True) 

85class ModelVariant: 

86 """One quantization within a model family. ``filename`` may be a glob.""" 

87 

88 hf_repo: str 

89 filename: str 

90 param_count: str 

91 quant: str 

92 size_mb: int 

93 recommended: bool 

94 mmproj_filename: str = "" 

95 

96 

97@dataclass(frozen=True) 

98class ModelFamily: 

99 """A group of related model variants (e.g. Qwen3 in multiple sizes).""" 

100 

101 slug: str # family slug for building refs: "qwen3" 

102 name: str # display name: "Qwen3" 

103 task: ModelTask 

104 description: str 

105 variants: tuple[ModelVariant, ...]