1"""Abstract base class for LLM providers.

2

3 This module provides the base interface that all LLM provider implementations

4 must follow, ensuring consistent API across different providers.

5"""

6

7 from __future__ import annotations

8

9 import logging

10 from abc import ABC, abstractmethod

11 from typing import TYPE_CHECKING, Any

12

13 if TYPE_CHECKING:

14 from collections.abc import AsyncGenerator

15

16 from session_buddy.llm.models import LLMMessage, LLMResponse

17

18

19 class LLMProvider(ABC):

20 """Abstract base class for LLM providers."""

21

22 def __init__(self, config: dict[str, Any]) -> None:

23 self.config = config

24 self.name = self.__class__.__name__.replace("Provider", "").lower()

25 self.logger = logging.getLogger(f"llm_providers.{self.name}")

26

27 @abstractmethod

28 async def generate(

29 self,

30 messages: list[LLMMessage],

31 model: str | None = None,

32 temperature: float = 0.7,

33 max_tokens: int | None = None,

34 **kwargs: Any,

35 ) -> LLMResponse:

36 """Generate a response from the LLM."""

37

38 @abstractmethod

39 async def stream_generate( # type: ignore[override]

40 self,

41 messages: list[LLMMessage],

42 model: str | None = None,

43 temperature: float = 0.7,

44 max_tokens: int | None = None,

45 **kwargs: Any,

46 ) -> AsyncGenerator[str]:

47 """Generate a streaming response from the LLM."""

48

49 @abstractmethod

50 async def is_available(self) -> bool:

51 """Check if the provider is available and properly configured."""

52

53 @abstractmethod

54 def get_models(self) -> list[str]:

55 """Get list of available models for this provider."""