| import os
|
| from typing import Optional, Dict
|
| from fastapi import Request
|
|
|
| from langchain_google_genai import ChatGoogleGenerativeAI
|
| from langchain_groq import ChatGroq
|
| from langchain_openrouter import ChatOpenRouter
|
| from langchain_cohere import ChatCohere
|
| from ..utils.api_key_utils import get_api_key_for_provider
|
| from ..core.logger import SingletonLogger
|
|
|
| logger = SingletonLogger().get_logger()
|
|
|
|
|
| class LLMFactory:
|
| @staticmethod
|
| def build_llm(
|
| model_name: str,
|
| api_key: Optional[str] = None,
|
| max_tokens: int = 2048,
|
| temperature: float = 0.7,
|
| reasoning: str = "hidden",
|
| streaming: bool = False,
|
| request: Optional[Request] = None,
|
| ):
|
| """Build and return an LLM instance based on the provided model name and parameters.
|
|
|
| Args:
|
| model_name (str): Model name should be in `provider/model_name` format. Eg. "gemini/gemini-1.5-pro", "groq/qwen/qwen3-32b", "openrouter/nvidia/nemotron-3-nano-30b-a3b:free".
|
| api_key (str, optional): Explicit API key. If not provided, will fetch from request state or environment.
|
| max_tokens (int, optional): Maximum number of tokens to generate. Defaults to 2048.
|
| temperature (float, optional): Sampling temperature for generation. Defaults to 0.7.
|
| reasoning (str, optional): Reasoning format for the model. Defaults to "hidden".
|
| streaming (bool, optional): Whether to enable streaming mode. Defaults to False.
|
| request (Request, optional): FastAPI Request object to fetch decrypted API keys from state.
|
|
|
| Raises:
|
| ValueError: If API key is not found for the provider.
|
| e: If there is an error building the LLM instance.
|
|
|
| Returns:
|
| An instance of the specified LLM.
|
| """
|
| try:
|
| provider, model_name = model_name.split("/", 1)
|
|
|
| if not api_key and request:
|
| api_key = get_api_key_for_provider(request, provider)
|
|
|
| if not api_key:
|
| provider_names = {
|
| "gemini": "Google Gemini",
|
| "cohere": "Cohere",
|
| "groq": "Groq",
|
| "openrouter": "OpenRouter",
|
| }
|
| provider_display = provider_names.get(provider.lower(), provider)
|
| raise ValueError(
|
| f"No API key found for '{provider_display}'. Please add your {provider_display} API key in Settings."
|
| )
|
|
|
| if provider.lower() == "gemini":
|
| llm = ChatGoogleGenerativeAI(
|
| model=model_name,
|
| google_api_key=api_key,
|
| include_thoughts=False,
|
| temperature=temperature,
|
| max_output_tokens=max_tokens,
|
| streaming=streaming,
|
| )
|
| elif provider.lower() == "cohere":
|
| llm = ChatCohere(
|
| model=model_name,
|
| cohere_api_key=api_key,
|
| temperature=temperature,
|
| max_tokens=max_tokens,
|
| streaming=streaming,
|
| )
|
| elif provider.lower() == "groq":
|
| reasoning_format = reasoning if "qwen" in model_name.lower() else None
|
| llm = ChatGroq(
|
| model=model_name,
|
| api_key=api_key,
|
| temperature=temperature,
|
| max_tokens=max_tokens,
|
| reasoning_format=reasoning_format,
|
| streaming=streaming,
|
| )
|
| elif provider.lower() == "openrouter":
|
| llm = ChatOpenRouter(
|
| model=model_name,
|
| api_key=api_key,
|
| temperature=temperature,
|
| max_completion_tokens=max_tokens,
|
| streaming=streaming,
|
| )
|
| else:
|
| raise ValueError(f"Unsupported LLM provider: {provider}")
|
| return llm
|
| except Exception as e:
|
| logger.error(f"Error building LLM: {e}")
|
| raise e
|
|
|