Commit ·
37bc9aa
1
Parent(s): abd9bdb
Add openai_compatible provider branch for freellmapi gateway
Browse filesChatOpenAI(base_url, api_key) path with no client-side rate limiter (gateway handles failover + limits). Set LLM_PROVIDER=openai_compatible + the OPENAI_COMPATIBLE_* vars to use it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .env.example +8 -3
- gaia_agent/config.py +6 -1
- gaia_agent/llm.py +16 -1
- pyproject.toml +1 -0
- requirements.txt +1 -0
.env.example
CHANGED
|
@@ -4,15 +4,20 @@ TAVILY_API_KEY=
|
|
| 4 |
# Required when LLM_PROVIDER=gemini (default). Free key: aistudio.google.com
|
| 5 |
GOOGLE_API_KEY=
|
| 6 |
|
| 7 |
-
# --- LLM provider for text/reasoning + judge nodes
|
| 8 |
-
#
|
| 9 |
-
# GOOGLE_API_KEY must come from a project WITHOUT billing (else free tier = 0).
|
| 10 |
LLM_PROVIDER=gemini
|
| 11 |
GEMINI_TEXT_MODEL=gemini-2.5-flash
|
| 12 |
GROQ_TEXT_MODEL=llama-3.1-8b-instant
|
| 13 |
# Global pace across all text-LLM calls (req/sec). 0.15 = ~9/min (<10 RPM free).
|
|
|
|
| 14 |
RATE_LIMIT_RPS=0.15
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
# --- Optional: LangSmith tracing (nice for debugging the graph) ---
|
| 17 |
# Set TRACING=true and provide the API key to stream runs to smith.langchain.com.
|
| 18 |
# LangChain/LangGraph pick these up automatically; no code change needed.
|
|
|
|
| 4 |
# Required when LLM_PROVIDER=gemini (default). Free key: aistudio.google.com
|
| 5 |
GOOGLE_API_KEY=
|
| 6 |
|
| 7 |
+
# --- LLM provider for text/reasoning + judge nodes ---
|
| 8 |
+
# "openai_compatible" (freellmapi gateway, best for rate limits), "gemini", "groq".
|
|
|
|
| 9 |
LLM_PROVIDER=gemini
|
| 10 |
GEMINI_TEXT_MODEL=gemini-2.5-flash
|
| 11 |
GROQ_TEXT_MODEL=llama-3.1-8b-instant
|
| 12 |
# Global pace across all text-LLM calls (req/sec). 0.15 = ~9/min (<10 RPM free).
|
| 13 |
+
# Ignored when LLM_PROVIDER=openai_compatible (gateway manages its own limits).
|
| 14 |
RATE_LIMIT_RPS=0.15
|
| 15 |
|
| 16 |
+
# --- freellmapi gateway (set LLM_PROVIDER=openai_compatible to use) ---
|
| 17 |
+
OPENAI_COMPATIBLE_BASE_URL=
|
| 18 |
+
OPENAI_COMPATIBLE_API_KEY=
|
| 19 |
+
OPENAI_COMPATIBLE_MODEL=auto
|
| 20 |
+
|
| 21 |
# --- Optional: LangSmith tracing (nice for debugging the graph) ---
|
| 22 |
# Set TRACING=true and provide the API key to stream runs to smith.langchain.com.
|
| 23 |
# LangChain/LangGraph pick these up automatically; no code change needed.
|
gaia_agent/config.py
CHANGED
|
@@ -24,13 +24,18 @@ class Settings(BaseSettings):
|
|
| 24 |
google_api_key: str = ""
|
| 25 |
|
| 26 |
# --- LLM provider for the text/reasoning + judge nodes ---
|
| 27 |
-
# "
|
| 28 |
# Vision + Whisper always use Groq.
|
| 29 |
llm_provider: str = "gemini"
|
| 30 |
|
| 31 |
# --- Models (override via env) ---
|
| 32 |
gemini_text_model: str = "gemini-2.5-flash"
|
| 33 |
groq_text_model: str = "llama-3.1-8b-instant"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
groq_vision_model: str = "meta-llama/llama-4-scout-17b-16e-instruct"
|
| 35 |
groq_whisper_model: str = "whisper-large-v3"
|
| 36 |
|
|
|
|
| 24 |
google_api_key: str = ""
|
| 25 |
|
| 26 |
# --- LLM provider for the text/reasoning + judge nodes ---
|
| 27 |
+
# "openai_compatible" (freellmapi gateway, recommended), "gemini", or "groq".
|
| 28 |
# Vision + Whisper always use Groq.
|
| 29 |
llm_provider: str = "gemini"
|
| 30 |
|
| 31 |
# --- Models (override via env) ---
|
| 32 |
gemini_text_model: str = "gemini-2.5-flash"
|
| 33 |
groq_text_model: str = "llama-3.1-8b-instant"
|
| 34 |
+
|
| 35 |
+
# --- OpenAI-compatible gateway (freellmapi) ---
|
| 36 |
+
openai_compatible_base_url: str = "" # e.g. https://my-gateway.example.com/v1
|
| 37 |
+
openai_compatible_api_key: str = ""
|
| 38 |
+
openai_compatible_model: str = "auto"
|
| 39 |
groq_vision_model: str = "meta-llama/llama-4-scout-17b-16e-instruct"
|
| 40 |
groq_whisper_model: str = "whisper-large-v3"
|
| 41 |
|
gaia_agent/llm.py
CHANGED
|
@@ -31,7 +31,22 @@ def get_text_llm(temperature: float = 0.0):
|
|
| 31 |
s = get_settings()
|
| 32 |
limiter = _rate_limiter()
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
from langchain_groq import ChatGroq
|
| 36 |
|
| 37 |
return ChatGroq(
|
|
|
|
| 31 |
s = get_settings()
|
| 32 |
limiter = _rate_limiter()
|
| 33 |
|
| 34 |
+
provider = s.llm_provider.lower()
|
| 35 |
+
|
| 36 |
+
if provider == "openai_compatible":
|
| 37 |
+
# freellmapi gateway: it does its own multi-provider failover + rate
|
| 38 |
+
# tracking, so no client-side rate limiter is applied here.
|
| 39 |
+
from langchain_openai import ChatOpenAI
|
| 40 |
+
|
| 41 |
+
return ChatOpenAI(
|
| 42 |
+
model=s.openai_compatible_model,
|
| 43 |
+
base_url=s.openai_compatible_base_url,
|
| 44 |
+
api_key=s.openai_compatible_api_key,
|
| 45 |
+
temperature=temperature,
|
| 46 |
+
max_retries=3,
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
if provider == "groq":
|
| 50 |
from langchain_groq import ChatGroq
|
| 51 |
|
| 52 |
return ChatGroq(
|
pyproject.toml
CHANGED
|
@@ -15,6 +15,7 @@ dependencies = [
|
|
| 15 |
"langchain-core>=0.3.0",
|
| 16 |
"langchain-groq>=0.2.0",
|
| 17 |
"langchain-google-genai>=2.0.0",
|
|
|
|
| 18 |
"langchain-tavily>=0.1.0",
|
| 19 |
"langchain-community>=0.3.0",
|
| 20 |
"wikipedia>=1.4.0",
|
|
|
|
| 15 |
"langchain-core>=0.3.0",
|
| 16 |
"langchain-groq>=0.2.0",
|
| 17 |
"langchain-google-genai>=2.0.0",
|
| 18 |
+
"langchain-openai>=0.2.0",
|
| 19 |
"langchain-tavily>=0.1.0",
|
| 20 |
"langchain-community>=0.3.0",
|
| 21 |
"wikipedia>=1.4.0",
|
requirements.txt
CHANGED
|
@@ -9,6 +9,7 @@ langchain>=0.3.0
|
|
| 9 |
langchain-core>=0.3.0
|
| 10 |
langchain-groq>=0.2.0
|
| 11 |
langchain-google-genai>=2.0.0
|
|
|
|
| 12 |
langchain-tavily>=0.1.0
|
| 13 |
langchain-community>=0.3.0
|
| 14 |
wikipedia
|
|
|
|
| 9 |
langchain-core>=0.3.0
|
| 10 |
langchain-groq>=0.2.0
|
| 11 |
langchain-google-genai>=2.0.0
|
| 12 |
+
langchain-openai>=0.2.0
|
| 13 |
langchain-tavily>=0.1.0
|
| 14 |
langchain-community>=0.3.0
|
| 15 |
wikipedia
|