Keerthisujana's picture
Initial deploy of AI ResearchPilot
6a5d1ee
Raw
History Blame Contribute Delete
2.23 kB
"""
llm.py
-------
Shared local-LLM wrapper used by the Planner, Reasoning, and Final-Answer
agents for text generation.
Primary path: google/flan-t5-base, a real open-source instruction-tuned
Hugging Face model (~250M params) that runs on free Hugging Face Space CPU
hardware in a few seconds per call. No paid API key required.
Fallback path: if the model cannot be downloaded (offline sandbox, first
run before the HF cache is warm, etc.) agents fall back to their own
deterministic, template/extractive logic instead of calling this class.
Every agent module documents its specific fallback. This wrapper simply
reports whether a real generative model is available so callers can decide.
"""
from __future__ import annotations
import logging
import os
from typing import List, Optional
logger = logging.getLogger(__name__)
GEN_MODEL_NAME = os.environ.get("RESEARCHPILOT_GEN_MODEL", "google/flan-t5-base")
class LocalLLM:
def __init__(self, model_name: str = GEN_MODEL_NAME):
self.model_name = model_name
self._pipe = None
self.available = False
try:
from transformers import pipeline
self._pipe = pipeline("text2text-generation", model=model_name, device=-1)
self.available = True
logger.info("Loaded real generation model: %s", model_name)
except Exception as exc: # noqa: BLE001
logger.warning(
"Could not load generation model %s (%s). "
"Agents will use their deterministic fallback logic instead.",
model_name,
exc,
)
def generate(self, prompt: str, max_new_tokens: int = 200) -> Optional[str]:
if not self.available:
return None
try:
out = self._pipe(prompt, max_new_tokens=max_new_tokens, do_sample=False)
return out[0]["generated_text"].strip()
except Exception as exc: # noqa: BLE001
logger.warning("Generation call failed (%s); falling back.", exc)
return None
_SINGLETON: Optional[LocalLLM] = None
def get_llm() -> LocalLLM:
global _SINGLETON
if _SINGLETON is None:
_SINGLETON = LocalLLM()
return _SINGLETON