| """ |
| llm_factory.py — Creates LangChain ChatOpenAI instances pointing at OpenRouter. |
| All LLMs in this project are built through this single factory so config |
| stays in one place. |
| """ |
| from langchain_openai import ChatOpenAI |
|
|
| from app.config import settings |
|
|
|
|
| def make_llm( |
| model: str, |
| temperature: float | None = None, |
| max_tokens: int | None = None, |
| ) -> ChatOpenAI: |
| """ |
| Return a LangChain ChatOpenAI client configured for OpenRouter. |
| |
| Args: |
| model: OpenRouter model string e.g. "arcee-ai/trinity-large-preview:free" |
| temperature: Override; defaults to settings.PANEL_TEMPERATURE |
| max_tokens: Override; defaults to settings.PANEL_MAX_TOKENS |
| """ |
| if not settings.OPENROUTER_API_KEY: |
| raise ValueError( |
| "OPENROUTER_API_KEY is not set. " |
| "Add it to your .env file or HF Space Secrets." |
| ) |
|
|
| return ChatOpenAI( |
| model=model, |
| openai_api_key=settings.OPENROUTER_API_KEY, |
| openai_api_base=settings.BASE_URL, |
| temperature=temperature if temperature is not None else settings.PANEL_TEMPERATURE, |
| max_tokens=max_tokens if max_tokens is not None else settings.PANEL_MAX_TOKENS, |
| default_headers={ |
| "HTTP-Referer": "https://codedebug.local", |
| "X-Title": "CodeDebug Multi-LLM Assistant", |
| }, |
| ) |
|
|
|
|
| def make_panel_llm(model: str, temperature: float | None = None) -> ChatOpenAI: |
| """Panel LLM with panel token budget.""" |
| return make_llm(model, temperature=temperature, max_tokens=settings.PANEL_MAX_TOKENS) |
|
|
|
|
| def make_judge_llm() -> ChatOpenAI: |
| """Judge LLM with larger token budget and near-zero temperature.""" |
| return make_llm( |
| settings.JUDGE_MODEL, |
| temperature=settings.JUDGE_TEMPERATURE, |
| max_tokens=settings.JUDGE_MAX_TOKENS, |
| ) |
|
|