Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-llm/src/lexigram/ai/llm/model_manager/base.py: 70%
30 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
1"""Base classes for model management."""
3from __future__ import annotations
5from abc import ABC, abstractmethod
6from typing import Any
8from lexigram.ai.llm.http.client import ResilientHTTPClient
9from lexigram.ai.llm.model_manager.types import ModelLoadResult
10from lexigram.logging import (
11 get_logger,
12)
14logger = get_logger(__name__)
17class AbstractModelManager(ABC):
18 """Abstract base class for LLM model managers."""
20 def __init__(self, base_url: str, name: str = "model-manager"):
21 self.base_url = base_url.rstrip("/")
22 self.name = name
23 self._client: ResilientHTTPClient | None = None
25 async def _get_client(self) -> ResilientHTTPClient:
26 """Get or create HTTP client."""
27 if self._client is None:
28 self._client = ResilientHTTPClient(
29 base_url=self.base_url,
30 timeout=30.0,
31 name=self.name,
32 )
33 return self._client
35 @abstractmethod
36 async def list_models(self) -> list[dict[str, Any]]:
37 """List available models."""
39 @abstractmethod
40 async def load_model(self, model_name: str, **kwargs: Any) -> ModelLoadResult:
41 """Load a model."""
43 @abstractmethod
44 async def unload_model(self, model_name: str) -> bool:
45 """Unload a model."""
47 @abstractmethod
48 async def switch_model(self, model_name: str, **kwargs: Any) -> ModelLoadResult:
49 """Switch to a different model."""
51 @abstractmethod
52 async def get_loaded_models(self) -> list[str]:
53 """Get currently loaded models."""
55 async def close(self) -> None:
56 """Close the manager."""
57 if self._client:
58 await self._client.close()
59 self._client = None