Coverage for src / lilbee / model_info.py: 100%
54 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
1"""Public API for reading model architecture metadata from GGUF files."""
3from __future__ import annotations
5import logging
6from dataclasses import dataclass
8from lilbee.config import cfg
10log = logging.getLogger(__name__)
13@dataclass
14class ModelArchInfo:
15 """Architecture metadata for installed models."""
17 chat_arch: str = "unknown"
18 embed_arch: str = "unknown"
19 vision_projector: str = "unknown"
20 active_handler: str = "not loaded"
23def get_model_architecture() -> ModelArchInfo:
24 """Return architecture metadata for the currently configured models.
25 Reads GGUF headers for chat, embedding, and (optionally) vision models.
26 Falls back gracefully if llama-cpp-python is not installed or models
27 are not available.
28 """
29 info = ModelArchInfo()
30 try:
31 import lilbee.providers.llama_cpp_provider # noqa: F401
33 info = _read_chat_arch(info)
34 info = _read_embed_arch(info)
35 info = _read_vision_arch(info)
36 except ImportError:
37 pass
38 return info
41def _read_chat_arch(info: ModelArchInfo) -> ModelArchInfo:
42 """Read chat model architecture from GGUF metadata."""
43 try:
44 from lilbee.providers.llama_cpp_provider import read_gguf_metadata, resolve_model_path
46 path = resolve_model_path(cfg.chat_model)
47 meta = read_gguf_metadata(path)
48 if meta:
49 info.chat_arch = meta.get("architecture", "unknown")
50 info.active_handler = "llama-cpp"
51 except Exception:
52 log.debug("Failed to read chat model architecture", exc_info=True)
53 return info
56def _read_embed_arch(info: ModelArchInfo) -> ModelArchInfo:
57 """Read embedding model architecture from GGUF metadata."""
58 try:
59 from lilbee.providers.llama_cpp_provider import read_gguf_metadata, resolve_model_path
61 path = resolve_model_path(cfg.embedding_model)
62 meta = read_gguf_metadata(path)
63 if meta:
64 info.embed_arch = meta.get("architecture", "unknown")
65 except Exception:
66 log.debug("Failed to read embedding model architecture", exc_info=True)
67 return info
70def _read_vision_arch(info: ModelArchInfo) -> ModelArchInfo:
71 """Read vision projector type from GGUF metadata for ``cfg.vision_model``.
73 Reads the vision model name from the global ``cfg`` singleton (same
74 pattern as :func:`_read_chat_arch` / :func:`_read_embed_arch`) rather
75 than taking it as a parameter. The chat model is never inspected for
76 vision capability here: role separation is explicit. Returns the
77 input unchanged when no vision model is configured.
78 """
79 if not cfg.vision_model:
80 return info
81 try:
82 from lilbee.providers.llama_cpp_provider import (
83 find_mmproj_for_model,
84 read_mmproj_projector_type,
85 resolve_model_path,
86 )
88 path = resolve_model_path(cfg.vision_model)
89 mmproj = find_mmproj_for_model(path)
90 proj_type = read_mmproj_projector_type(mmproj)
91 info.vision_projector = proj_type or "unknown"
92 except Exception:
93 log.debug("Failed to read vision projector type", exc_info=True)
94 return info