Spaces:
Running
Running
Upload 22 files
Browse files- modules/api.py +20 -4
- modules/config.py +8 -2
- modules/local_llm.py +2 -1
- modules/web_search.py +18 -4
modules/api.py
CHANGED
|
@@ -202,11 +202,17 @@ class LLMManager:
|
|
| 202 |
# 2. Google Gemini
|
| 203 |
if genai:
|
| 204 |
try:
|
| 205 |
-
#
|
| 206 |
gemini_key = getattr(config, "GEMINI_API_KEY", None)
|
| 207 |
-
model_name = getattr(config, "GEMINI_MODEL", "gemini-
|
| 208 |
|
| 209 |
if gemini_key:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
if GEMINI_USING_NEW_API:
|
| 211 |
self.gemini_client = genai.Client(api_key=gemini_key)
|
| 212 |
logger.info(f"Google Gemini (Novo) ativo: {model_name}")
|
|
@@ -214,6 +220,8 @@ class LLMManager:
|
|
| 214 |
genai.configure(api_key=gemini_key)
|
| 215 |
self.gemini_model = genai.GenerativeModel(model_name)
|
| 216 |
logger.info(f"Google Gemini (Legado) ativo: {model_name}")
|
|
|
|
|
|
|
| 217 |
except Exception as e:
|
| 218 |
logger.error(f"Erro ao configurar Gemini: {e}")
|
| 219 |
self.gemini_model = None
|
|
@@ -444,8 +452,12 @@ class LLMManager:
|
|
| 444 |
content = turn.get("content", "")
|
| 445 |
messages.append({"role": role, "content": content})
|
| 446 |
messages.append({"role": "user", "content": user_prompt})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
resp = self.groq_client.chat.completions.create(
|
| 448 |
-
model=
|
| 449 |
messages=messages,
|
| 450 |
temperature=0.7,
|
| 451 |
max_tokens=1000
|
|
@@ -515,8 +527,12 @@ class LLMManager:
|
|
| 515 |
content = turn.get("content", "")
|
| 516 |
messages.append({"role": role, "content": content})
|
| 517 |
messages.append({"role": "user", "content": user_prompt})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 518 |
resp = self.together_client.chat.completions.create(
|
| 519 |
-
model=
|
| 520 |
messages=messages,
|
| 521 |
temperature=0.7,
|
| 522 |
max_tokens=1000
|
|
|
|
| 202 |
# 2. Google Gemini
|
| 203 |
if genai:
|
| 204 |
try:
|
| 205 |
+
# Prioriza a chave do config que já limpamos
|
| 206 |
gemini_key = getattr(config, "GEMINI_API_KEY", None)
|
| 207 |
+
model_name = getattr(config, "GEMINI_MODEL", "gemini-2.0-flash")
|
| 208 |
|
| 209 |
if gemini_key:
|
| 210 |
+
# Resolve conflito de variáveis de ambiente do SDK
|
| 211 |
+
# O SDK do Google prioriza GOOGLE_API_KEY. Se queremos usar a GEMINI_API_KEY do config,
|
| 212 |
+
# limpamos a do ambiente para garantir consistência.
|
| 213 |
+
if os.getenv("GOOGLE_API_KEY") != gemini_key:
|
| 214 |
+
os.environ["GOOGLE_API_KEY"] = gemini_key
|
| 215 |
+
|
| 216 |
if GEMINI_USING_NEW_API:
|
| 217 |
self.gemini_client = genai.Client(api_key=gemini_key)
|
| 218 |
logger.info(f"Google Gemini (Novo) ativo: {model_name}")
|
|
|
|
| 220 |
genai.configure(api_key=gemini_key)
|
| 221 |
self.gemini_model = genai.GenerativeModel(model_name)
|
| 222 |
logger.info(f"Google Gemini (Legado) ativo: {model_name}")
|
| 223 |
+
else:
|
| 224 |
+
logger.warning("Gemini não configurado: Chave ausente")
|
| 225 |
except Exception as e:
|
| 226 |
logger.error(f"Erro ao configurar Gemini: {e}")
|
| 227 |
self.gemini_model = None
|
|
|
|
| 452 |
content = turn.get("content", "")
|
| 453 |
messages.append({"role": role, "content": content})
|
| 454 |
messages.append({"role": "user", "content": user_prompt})
|
| 455 |
+
|
| 456 |
+
# Usar modelo do config
|
| 457 |
+
model_name = getattr(config, 'GROQ_MODEL', 'llama-3.3-70b-versatile')
|
| 458 |
+
|
| 459 |
resp = self.groq_client.chat.completions.create(
|
| 460 |
+
model=model_name,
|
| 461 |
messages=messages,
|
| 462 |
temperature=0.7,
|
| 463 |
max_tokens=1000
|
|
|
|
| 527 |
content = turn.get("content", "")
|
| 528 |
messages.append({"role": role, "content": content})
|
| 529 |
messages.append({"role": "user", "content": user_prompt})
|
| 530 |
+
|
| 531 |
+
# Usar modelo do config
|
| 532 |
+
model_name = getattr(config, 'TOGETHER_MODEL', 'meta-llama/Llama-3.3-70B-Instruct-Turbo')
|
| 533 |
+
|
| 534 |
resp = self.together_client.chat.completions.create(
|
| 535 |
+
model=model_name,
|
| 536 |
messages=messages,
|
| 537 |
temperature=0.7,
|
| 538 |
max_tokens=1000
|
modules/config.py
CHANGED
|
@@ -103,12 +103,18 @@ logger = setup_logger()
|
|
| 103 |
def _get_key(name: str) -> str:
|
| 104 |
val = os.getenv(name, "").strip()
|
| 105 |
if len(val) >= 2:
|
|
|
|
| 106 |
if (val.startswith('"') and val.endswith('"')) or (val.startswith("'") and val.endswith("'")):
|
| 107 |
-
|
| 108 |
return val
|
| 109 |
|
| 110 |
-
|
|
|
|
| 111 |
GEMINI_API_KEY: str = _get_key("GEMINI_API_KEY")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
GROQ_API_KEY: str = _get_key("GROQ_API_KEY")
|
| 113 |
GROK_API_KEY: str = _get_key("GROK_API_KEY")
|
| 114 |
COHERE_API_KEY: str = _get_key("COHERE_API_KEY")
|
|
|
|
| 103 |
def _get_key(name: str) -> str:
|
| 104 |
val = os.getenv(name, "").strip()
|
| 105 |
if len(val) >= 2:
|
| 106 |
+
# Remove aspas se existirem (comum em setups de env)
|
| 107 |
if (val.startswith('"') and val.endswith('"')) or (val.startswith("'") and val.endswith("'")):
|
| 108 |
+
val = val[1:-1]
|
| 109 |
return val
|
| 110 |
|
| 111 |
+
# Prioridade Gemini: Se GEMINI_API_KEY existir, ela manda.
|
| 112 |
+
# Se não, tenta GOOGLE_API_KEY.
|
| 113 |
GEMINI_API_KEY: str = _get_key("GEMINI_API_KEY")
|
| 114 |
+
if not GEMINI_API_KEY:
|
| 115 |
+
GEMINI_API_KEY = _get_key("GOOGLE_API_KEY")
|
| 116 |
+
|
| 117 |
+
MISTRAL_API_KEY: str = _get_key("MISTRAL_API_KEY")
|
| 118 |
GROQ_API_KEY: str = _get_key("GROQ_API_KEY")
|
| 119 |
GROK_API_KEY: str = _get_key("GROK_API_KEY")
|
| 120 |
COHERE_API_KEY: str = _get_key("COHERE_API_KEY")
|
modules/local_llm.py
CHANGED
|
@@ -262,7 +262,8 @@ class LocalLLMFallback:
|
|
| 262 |
|
| 263 |
model_route = self._model_path or "mistralai/Mistral-7B-Instruct-v0.3"
|
| 264 |
max_new = max_tokens or self._max_tokens
|
| 265 |
-
|
|
|
|
| 266 |
|
| 267 |
headers = {"Authorization": f"Bearer {hf_token}", "Content-Type": "application/json"}
|
| 268 |
|
|
|
|
| 262 |
|
| 263 |
model_route = self._model_path or "mistralai/Mistral-7B-Instruct-v0.3"
|
| 264 |
max_new = max_tokens or self._max_tokens
|
| 265 |
+
# Upgrade: Usando o novo endpoint do roteador da HF para evitar Erro 410 (Gone)
|
| 266 |
+
api_url = f"https://router.huggingface.co/hf-inference/models/{model_route}/v1/chat/completions"
|
| 267 |
|
| 268 |
headers = {"Authorization": f"Bearer {hf_token}", "Content-Type": "application/json"}
|
| 269 |
|
modules/web_search.py
CHANGED
|
@@ -342,10 +342,24 @@ class WebSearch:
|
|
| 342 |
return True
|
| 343 |
|
| 344 |
# 4. Contexto do histórico (se usuário estava pedindo info antes)
|
| 345 |
-
if historico:
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
|
| 350 |
return False
|
| 351 |
|
|
|
|
| 342 |
return True
|
| 343 |
|
| 344 |
# 4. Contexto do histórico (se usuário estava pedindo info antes)
|
| 345 |
+
if historico and isinstance(historico, list):
|
| 346 |
+
try:
|
| 347 |
+
# Conversão ultra-segura: ignora None, extrai de tupla/dict ou converte str
|
| 348 |
+
historico_limpo = []
|
| 349 |
+
for h in historico[-5:]:
|
| 350 |
+
if h is None: continue
|
| 351 |
+
if isinstance(h, tuple) and len(h) > 0:
|
| 352 |
+
historico_limpo.append(str(h[0]))
|
| 353 |
+
elif isinstance(h, dict):
|
| 354 |
+
historico_limpo.append(str(h.get('content', h.get('mensagem', ''))))
|
| 355 |
+
else:
|
| 356 |
+
historico_limpo.append(str(h))
|
| 357 |
+
|
| 358 |
+
ultima_5 = " ".join(historico_limpo).lower()
|
| 359 |
+
if any(t in ultima_5 for t in ["pesquisa", "busca", "notícia", "aconteceu", "saber sobre"]):
|
| 360 |
+
return True
|
| 361 |
+
except Exception as e:
|
| 362 |
+
logger.warning(f"Erro ao processar histórico na busca: {e}")
|
| 363 |
|
| 364 |
return False
|
| 365 |
|