Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ SUPABASE_KEY=your_service_role_key
# These apply to all agent nodes unless overridden below.
GROQ_API_KEY=your_groq_api_key
OPENROUTER_API_KEY=your_openrouter_api_key
LLM_PROVIDER=groq # "groq" or "openrouter"
LLM_MODEL=llama-3.3-70b-versatile
GEMINI_API_KEY=your_gemini_api_key
LLM_PROVIDER=gemini # "groq", "openrouter", or "gemini"
LLM_MODEL=gemini-2.5-pro

# Per-node LLM Overrides (optional)
# Uncomment to override a specific agent's provider/model.
Expand Down
13 changes: 8 additions & 5 deletions backend/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ class Settings(BaseSettings):
# LLM Provider Configuration — Global Defaults
groq_api_key: str = ""
openrouter_api_key: str = ""
llm_provider: Literal["groq", "openrouter"] = "groq"
gemini_api_key: str = ""
llm_provider: Literal["groq", "openrouter", "gemini"] = "groq"
llm_model: str = "llama-3.3-70b-versatile"

# Per-node LLM overrides (None = use global defaults above)
planner_llm_provider: Optional[Literal["groq", "openrouter"]] = None
planner_llm_provider: Optional[Literal["groq", "openrouter", "gemini"]] = None
planner_llm_model: Optional[str] = None
scripter_llm_provider: Optional[Literal["groq", "openrouter"]] = None
scripter_llm_provider: Optional[Literal["groq", "openrouter", "gemini"]] = None
scripter_llm_model: Optional[str] = None
coder_llm_provider: Optional[Literal["groq", "openrouter"]] = None
coder_llm_provider: Optional[Literal["groq", "openrouter", "gemini"]] = None
coder_llm_model: Optional[str] = None
reflector_llm_provider: Optional[Literal["groq", "openrouter"]] = None
reflector_llm_provider: Optional[Literal["groq", "openrouter", "gemini"]] = None
reflector_llm_model: Optional[str] = None

# Storage Configuration
Expand All @@ -59,6 +60,8 @@ def is_llm_configured(self) -> bool:
"""Check if at least one LLM provider is configured."""
if self.llm_provider == "groq":
return bool(self.groq_api_key)
if self.llm_provider == "gemini":
return bool(self.gemini_api_key)
return bool(self.openrouter_api_key)


Expand Down
25 changes: 24 additions & 1 deletion backend/app/services/llm_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,14 @@ def create_llm(role: AgentRole, temperature: float = 0.7) -> BaseChatModel:
return _create_openrouter_llm(
model, temperature, settings.openrouter_api_key
)
elif provider == "gemini":
return _create_gemini_llm(
model, temperature, settings.gemini_api_key
)
else:
raise ValueError(
f"Unsupported LLM provider '{provider}' for role '{role}'. "
f"Supported: groq, openrouter"
f"Supported: groq, openrouter, gemini"
)


Expand Down Expand Up @@ -105,3 +109,22 @@ def _create_openrouter_llm(
temperature=temperature,
api_key=api_key,
)


def _create_gemini_llm(
model: str, temperature: float, api_key: str
) -> BaseChatModel:
"""Create a ChatGoogleGenerativeAI instance."""
if not api_key:
raise ValueError(
"GEMINI_API_KEY is required when using the 'gemini' "
"provider. Set it in your .env file."
)

from langchain_google_genai import ChatGoogleGenerativeAI

return ChatGoogleGenerativeAI(
model=model,
temperature=temperature,
google_api_key=api_key,
)
1 change: 1 addition & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ httpx>=0.26.0
# Testing
pytest>=7.4.0
pytest-asyncio>=0.21.0
langchain-google-genai>=1.0.0
Loading