chatbot / llm /generate.py
anris05's picture
bot
8a2dcce
Raw
History Blame Contribute Delete
1.77 kB
"""
Provider factory.
This is the ONLY module the rest of the application should import to talk
to an LLM. It picks the concrete provider based on config.LLM_PROVIDER and
exposes a single generate(prompt) function. Swapping providers is a
config change only.
"""
import config
from logs.logger import get_logger
logger = get_logger(__name__)
_PROVIDER_SINGLETON = None
def _build_provider():
provider_name = config.LLM_PROVIDER.lower()
if provider_name == "local":
from llm.local_provider import LocalMistralProvider
return LocalMistralProvider()
if provider_name == "groq":
from llm.groq_provider import GroqProvider
return GroqProvider()
if provider_name == "openai":
from llm.openai_provider import OpenAIProvider
return OpenAIProvider()
raise ValueError(
f"Unknown LLM_PROVIDER={provider_name!r} in config.py. "
"Expected one of: 'local', 'groq', 'openai'."
)
def get_provider():
"""Module-level singleton so the local model (if used) loads only once."""
global _PROVIDER_SINGLETON
if _PROVIDER_SINGLETON is None:
_PROVIDER_SINGLETON = _build_provider()
logger.info("LLM provider initialized: %s", _PROVIDER_SINGLETON.name())
return _PROVIDER_SINGLETON
def generate(prompt: str, stream: bool = False):
"""
The single entrypoint the rest of the app (Flask routes, agents,
evaluation) should call. Never import a provider class directly outside
of this module.
"""
provider = get_provider()
return provider.generate(prompt, stream=stream)
def reset_provider():
"""Mainly for tests: force re-reading config.LLM_PROVIDER on next call."""
global _PROVIDER_SINGLETON
_PROVIDER_SINGLETON = None