| """ |
| LLM provider interface. |
| |
| The rest of the application (router, chat endpoints, evaluation) must |
| NEVER call a specific model directly. Everything goes through |
| generate(prompt) on whatever provider is configured via |
| config.LLM_PROVIDER. Switching from local Mistral to Groq or OpenAI later |
| should require changing config only — no changes to callers. |
| """ |
|
|
| from abc import ABC, abstractmethod |
|
|
|
|
| class LLMProvider(ABC): |
| """Base interface every provider (local, groq, openai, ...) must implement.""" |
|
|
| @abstractmethod |
| def generate(self, prompt: str, stream: bool = False): |
| """ |
| Args: |
| prompt: the fully-constructed prompt string (see llm/prompts.py). |
| stream: if True, returns a generator yielding text chunks as |
| they're produced, instead of a single string. Providers |
| that can't stream should fall back to yielding the full |
| response once. |
| |
| Returns: |
| str if stream=False, otherwise a generator[str]. |
| """ |
| raise NotImplementedError |
|
|
| def name(self) -> str: |
| return self.__class__.__name__ |
|
|