Spaces:
Sleeping
Sleeping
File size: 6,644 Bytes
c46013c bb78940 c46013c bb78940 c46013c bb78940 c46013c bb78940 c46013c bb78940 b9f1124 bb78940 b9f1124 b144b5f b9f1124 b144b5f bb78940 c46013c b9f1124 bb78940 c46013c b9f1124 bb78940 b9f1124 bb78940 b9f1124 f7c8bab db446f6 bb78940 db446f6 bb78940 b9f1124 c46013c bb78940 c46013c bb78940 b9f1124 bf76179 b9f1124 bf76179 bb78940 b9f1124 bb78940 b9f1124 bb78940 b9f1124 bb78940 b9f1124 c46013c bb78940 c46013c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | # core/llm_client.py
import asyncio
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
from agents.registry import PROVIDERS, AGENT_REGISTRY
class LLMClient:
def __init__(self):
self.semaphore = asyncio.Semaphore(6) # mΓ‘ximo 6 llamadas simultΓ‘neas
async def call(self, agent_key: str, messages: list, temperature: float = 0.7):
agent = AGENT_REGISTRY.get(agent_key)
if not agent:
raise ValueError(f"Agente {agent_key} no encontrado")
provider = PROVIDERS[agent["provider"]]
system_prompt = agent["role"]
full_messages = [{"role": "system", "content": system_prompt}] + messages
if provider["type"] == "gemini":
# ββ Soporte para Google Gemini βββββββββββββββββββββββββββββββββββββββ
try:
import google.generativeai as genai
genai.configure(api_key=provider["key"])
model_name = agent["models"][0]
print(f"Intentando Gemini con modelo: {model_name}")
try:
model = genai.GenerativeModel(model_name)
except Exception as e:
print(f"Modelo {model_name} fallΓ³: {str(e)}")
model_name = "gemini-2.5-flash" # fallback seguro
print(f"Usando fallback: {model_name}")
model = genai.GenerativeModel(model_name)
# Convertir formato OpenAI β Gemini
gemini_messages = []
for msg in full_messages:
role = "user" if msg["role"] in ("system", "user") else "model"
gemini_messages.append({
"role": role,
"parts": [{"text": msg["content"]}]
})
response = await asyncio.to_thread(
model.generate_content,
gemini_messages,
generation_config={"temperature": temperature, "max_output_tokens": 4096}
)
print(f"Gemini respondiΓ³ exitosamente con {model_name}")
return response.text
except ImportError:
raise ImportError("Instala google-generativeai: pip install google-generativeai")
except Exception as e:
print(f"Error completo en Gemini ({model_name}): {str(e)}")
if hasattr(e, 'response'):
print(f"Status: {e.response.status_code}")
print(f"Body: {e.response.text[:500]}")
raise
elif provider["type"] == "openai_compat":
# ββ Soporte para OpenRouter, Groq, etc. βββββββββββββββββββββββββββββββ
@retry(
stop=stop_after_attempt(6), # un intento mΓ‘s
wait=wait_exponential(multiplier=2, min=5, max=120), # espera progresiva: 5s β 10s β 20s β 40s β 80s β 120s
retry=retry_if_exception_type((httpx.HTTPStatusError, httpx.TimeoutException)),
before_sleep=lambda retry_state: print(f"Reintento {retry_state.attempt_number} despuΓ©s de {retry_state.outcome.exception()}")
)
async def try_provider(base_url, model, api_key, headers):
async with self.semaphore:
payload = {
"model": model,
"messages": full_messages,
"temperature": temperature,
"max_tokens": 4096,
"top_p": 0.92
}
print(f"Intentando {provider['name']} con modelo {model}")
async with httpx.AsyncClient(timeout=120) as client: # timeout mΓ‘s largo
url = f"{base_url}/chat/completions" # β Β‘esto es lo que falta!
print(f"URL completa: {url}")
resp = await client.post(
url,
headers={"Authorization": f"Bearer {api_key}", **headers},
json=payload
)
try:
resp.raise_for_status()
except httpx.HTTPStatusError as exc:
print(f"HTTP Error {resp.status_code} con {model}")
print(f"Response body: {resp.text[:500]}")
raise exc
content = resp.json()["choices"][0]["message"]["content"]
print(f"Γxito con {model}")
return content
last_err = None
for model in agent.get("models", []):
try:
return await try_provider(
provider["base_url"],
model,
provider["key"],
provider.get("headers", {})
)
except Exception as e:
print(f"Error completo con {model}: {str(e)}")
if hasattr(e, 'response') and e.response is not None:
print(f" β Status: {e.response.status_code}")
print(f" β Body: {e.response.text[:500]}")
print(f" β Headers: {dict(e.response.headers)}")
last_err = e
# Fallback a OpenRouter
if agent["provider"] != "openrouter" and PROVIDERS["openrouter"]["key"]:
or_p = PROVIDERS["openrouter"]
print("Probando fallback a OpenRouter...")
for model in or_p["models"][:3]: # solo los primeros 3 para no saturar
try:
return await try_provider(
or_p["base_url"],
model,
or_p["key"],
or_p.get("headers", {})
)
except Exception as e:
print(f"Fallback fallΓ³ con {model}: {str(e)}")
last_err = e
error_msg = f"Todos los proveedores fallaron. Γltimo error: {last_err}"
print(error_msg)
raise Exception(error_msg)
else:
raise ValueError(f"Tipo de proveedor desconocido: {provider['type']}")
# Instancia global
llm = LLMClient() |