🚀 Auto-deploy: BotVPS atualizado em 29/04/2026 10:42:36
This commit is contained in:
@@ -231,7 +231,7 @@ async def get_available_models(provider: str = None) -> List[Dict]:
|
||||
# ASYNC LLM CALL FUNCTIONS
|
||||
# ============================================================
|
||||
|
||||
async def call_llm(provider: str, model: str, prompt: str, system_prompt: str = None, **kwargs) -> str:
|
||||
async def call_llm(provider: str, model: str, prompt: str, system_prompt: str = None, **kwargs) -> dict:
|
||||
"""Suporte universal async para chamadas de LLM com monitoramento de tráfego."""
|
||||
# Monitoramento de Rate Limit
|
||||
alert_msg = track_request()
|
||||
@@ -239,19 +239,24 @@ async def call_llm(provider: str, model: str, prompt: str, system_prompt: str =
|
||||
asyncio.create_task(send_telegram_alert(alert_msg))
|
||||
|
||||
if provider == "gemini":
|
||||
return await _call_gemini_async(model, prompt, system_prompt)
|
||||
res = await _call_gemini_async(model, prompt, system_prompt)
|
||||
elif provider == "openai":
|
||||
return await _call_openai_async(model, prompt, system_prompt)
|
||||
res = await _call_openai_async(model, prompt, system_prompt)
|
||||
elif provider == "anthropic":
|
||||
return await _call_anthropic_async(model, prompt, system_prompt)
|
||||
res = await _call_anthropic_async(model, prompt, system_prompt)
|
||||
elif provider == "ollama":
|
||||
return await _call_ollama_async(model, prompt, system_prompt)
|
||||
res = await _call_ollama_async(model, prompt, system_prompt)
|
||||
elif provider == "openrouter":
|
||||
return await _call_openrouter_async(model, prompt, system_prompt)
|
||||
res = await _call_openrouter_async(model, prompt, system_prompt)
|
||||
else:
|
||||
return f"Erro: Provider '{provider}' não suportado."
|
||||
return {"content": f"Erro: Provider '{provider}' não suportado.", "usage": {}}
|
||||
|
||||
# Garante que o retorno seja um dicionário (compatibilidade com shims antigos se houver)
|
||||
if isinstance(res, str):
|
||||
return {"content": res, "usage": {}, "model": model}
|
||||
return res
|
||||
|
||||
async def _call_openrouter_async(model: str, prompt: str, system_prompt: str = None) -> str:
|
||||
async def _call_openrouter_async(model: str, prompt: str, system_prompt: str = None) -> dict:
|
||||
"""Chama API do OpenRouter (OpenAI Compatible) via httpx (async)."""
|
||||
api_key = get_api_key("openrouter")
|
||||
url = "https://openrouter.ai/api/v1/chat/completions"
|
||||
@@ -279,17 +284,21 @@ async def _call_openrouter_async(model: str, prompt: str, system_prompt: str = N
|
||||
if res.status_code == 200:
|
||||
data = res.json()
|
||||
if "choices" in data and len(data["choices"]) > 0:
|
||||
return data["choices"][0]["message"]["content"]
|
||||
return f"Erro OpenRouter (Resposta sem 'choices'): {json.dumps(data)}"
|
||||
return {
|
||||
"content": data["choices"][0]["message"]["content"],
|
||||
"usage": data.get("usage", {}),
|
||||
"model": data.get("model", model)
|
||||
}
|
||||
return {"content": f"Erro OpenRouter (Resposta sem 'choices'): {json.dumps(data)}", "usage": {}}
|
||||
|
||||
# Se não for 200, tenta extrair erro detalhado
|
||||
try:
|
||||
error_data = res.json()
|
||||
return f"Erro OpenRouter {res.status_code}: {json.dumps(error_data)}"
|
||||
return {"content": f"Erro OpenRouter {res.status_code}: {json.dumps(error_data)}", "usage": {}}
|
||||
except:
|
||||
return f"Erro OpenRouter: {res.status_code} - {res.text}"
|
||||
return {"content": f"Erro OpenRouter: {res.status_code} - {res.text}", "usage": {}}
|
||||
except Exception as e:
|
||||
return f"Erro OpenRouter: {str(e)}"
|
||||
return {"content": f"Erro OpenRouter: {str(e)}", "usage": {}}
|
||||
|
||||
async def _call_gemini_async(model: str, prompt: str, system_prompt: str = None) -> str:
|
||||
"""Chama API do Google Gemini via httpx (async)."""
|
||||
@@ -438,22 +447,25 @@ def get_executor_llm() -> tuple:
|
||||
async def call_planner_async(prompt: str, system_prompt: str = None) -> str:
|
||||
provider, model = get_planner_llm()
|
||||
try:
|
||||
response = await call_llm(provider, model, prompt, system_prompt)
|
||||
response_dict = await call_llm(provider, model, prompt, system_prompt)
|
||||
content = response_dict["content"]
|
||||
# Se a resposta indicar um erro de API, disparamos o fallback
|
||||
if response.startswith("Erro OpenRouter"):
|
||||
raise Exception(response)
|
||||
return response
|
||||
if content.startswith("Erro OpenRouter"):
|
||||
raise Exception(content)
|
||||
return content
|
||||
except Exception as e:
|
||||
# Lógica de FALLBACK: Se o Qwen falhar, tenta o Ling-2.6-flash
|
||||
if provider == "openrouter" and model == "qwen/qwen-2.5-72b-instruct":
|
||||
backup_model = "inclusionai/ling-2.6-flash:free"
|
||||
print(f"⚠️ [FALLBACK] Falha no Qwen ({str(e)}). Tentando {backup_model}...")
|
||||
return await call_llm("openrouter", backup_model, prompt, system_prompt)
|
||||
res = await call_llm("openrouter", backup_model, prompt, system_prompt)
|
||||
return res["content"]
|
||||
return f"Erro Crítico no Planner: {str(e)}"
|
||||
|
||||
async def call_executor_async(prompt: str, system_prompt: str = None) -> str:
|
||||
provider, model = get_executor_llm()
|
||||
return await call_llm(provider, model, prompt, system_prompt)
|
||||
res = await call_llm(provider, model, prompt, system_prompt)
|
||||
return res["content"]
|
||||
|
||||
# --- BACKWARD COMPATIBILITY SHIMS (SYNC WRAPPERS) ---
|
||||
def call_planner(prompt: str, system_prompt: str = None) -> str:
|
||||
|
||||
Reference in New Issue
Block a user