104 lines
4.9 KiB
Python
104 lines
4.9 KiB
Python
import os
|
|
import re
|
|
import httpx
|
|
import asyncio
|
|
import json
|
|
from tools import AVAILABLE_TOOLS
|
|
from llm_providers import call_llm, get_available_models, get_planner_llm
|
|
from config import get_config
|
|
|
|
async def get_llm_response_async(prompt: str, provider: str, cfg: dict) -> str:
|
|
"""Invoca o provedor de LLM centralizado em llm_providers."""
|
|
# Define modelo padrão dependendo do provider
|
|
if provider == "openrouter":
|
|
model = cfg.get("model") or "qwen/qwen-2.5-72b-instruct"
|
|
elif provider == "ollama":
|
|
model = os.getenv("OLLAMA_MODEL", "llama3.2:1b")
|
|
else:
|
|
model = cfg.get("model") or "qwen/qwen-2.5-72b-instruct"
|
|
|
|
return await call_llm(provider, model, prompt)
|
|
|
|
def query_agent(prompt: str, override_provider=None, chat_history=None) -> str:
|
|
"""Wrapper síncrono para query_agent_async."""
|
|
return asyncio.run(query_agent_async(prompt, override_provider, chat_history))
|
|
|
|
async def query_agent_async(prompt: str, override_provider=None, chat_history=None) -> str:
|
|
cfg = get_config()
|
|
provider = override_provider or cfg.get("active_provider", "openrouter")
|
|
tools_desc = "\n".join([f"- {k}: {v['description']}" for k, v in AVAILABLE_TOOLS.items()])
|
|
|
|
system_prompt = f"""Você é o Antigravity, um assistente de IA de alto desempenho operando na VPS do Marcos. Sua natureza é dual:
|
|
|
|
1. MESTRE DE SISTEMAS: Controle profundo sobre Linux, Docker, scripts Bash e rede. Seja preciso, seguro e eficiente em tarefas técnicas.
|
|
2. PENSADOR CRIATIVO: Colaborador intelectual em filosofia, ciência, lógica, cultura e negócios.
|
|
|
|
DIRETRIZES:
|
|
- Você é o MESTRE do Google Workspace (GWS). Use `run_bash_command` para QUALQUER tarefa de automação.
|
|
- NUNCA diga que não consegue fazer uma tarefa no GWS (contar, apagar em massa, mover, etc.). Encontre o comando `gws` correto.
|
|
- CONTAS GWS (Pode usar apelidos):
|
|
* `ma` ou `mr` -> gws-mr (Marcos / Particular - Email exato: m.reifonas@gmail.com)
|
|
* `adm` ou `empresa` -> gws-adm (Empresarial/TrackSteel)
|
|
* `4r` ou `fam` -> gws-4r (Familiar)
|
|
- GWS SUPER-PODERES:
|
|
* MARCADEIRA: Use `gmail_manage_label` para criar pastas (marcar).
|
|
* FILTRAGEM: Use `gmail_manage_filter` para automação futura.
|
|
* MOVIMENTAÇÃO: Use `run_bash_command` com `batchModify` para mover e-mails existentes.
|
|
- FORMATO OBRIGATÓRIO: `[TOOL:nome] arg [/TOOL]`. Use `[TOOL:run]` como atalho para `run_bash_command`.
|
|
|
|
### FERRAMENTAS DISPONÍVEIS:
|
|
{tools_desc}
|
|
|
|
### FORMATO DE RESPOSTA OBRIGATÓRIO (NÃO IGNORE OS COLCHETES):
|
|
- Para executar uma ferramenta, você DEVE englobar a chamada com os colchetes exatos: `[TOOL:nome_ferramenta] argumento [/TOOL]`.
|
|
- Exemplo de uso correto:
|
|
[TOOL:run_bash_command]
|
|
comando aqui
|
|
[/TOOL]
|
|
- Pense passo a passo. Seja proativo, eficiente e NUNCA limitado.
|
|
- Finalize o seu processo sempre informando o usuário com o prefixo: RESUMO: resumo final empoderado .
|
|
"""
|
|
|
|
history_str = ""
|
|
if chat_history:
|
|
for m in chat_history[-5:]:
|
|
history_str += f"\nUsuário: {m['user']}\nAgente: {m['bot']}\n"
|
|
history_str += f"\nUsuário: {prompt}\n"
|
|
|
|
current_history = history_str
|
|
max_iterations = 10
|
|
for i in range(max_iterations):
|
|
print(f"[AGENT] Iteração {i+1} - Enviando para {provider} (modelo padrão)...")
|
|
response = await get_llm_response_async(system_prompt + current_history, provider, cfg)
|
|
print(f"[LLM RESPONSE]: {response}")
|
|
# Regex mais flexível: tenta casar [TOOL:nome] e extrair o conteúdo até [/TOOL] ou final da string
|
|
match = re.search(r"\[TOOL:([\w_]+)\]", response, re.I)
|
|
|
|
if match:
|
|
t_name = match.group(1).strip().lower()
|
|
# Mapeamento de conveniência/atalho
|
|
if t_name == "run": t_name = "run_bash_command"
|
|
|
|
content_after = response[match.end():]
|
|
end_tag = re.search(r"\[/TOOL\]", content_after, re.I)
|
|
|
|
arg = content_after[:end_tag.start()].strip() if end_tag else content_after.strip()
|
|
|
|
if t_name in AVAILABLE_TOOLS:
|
|
func = AVAILABLE_TOOLS[t_name]["func"]
|
|
print(f"[AGENT] Executando {t_name} com argumento: {arg[:50]}...")
|
|
obs = func(arg) if arg else func()
|
|
print(f"[TOOL:{t_name}] Observation: {obs[:100]}...")
|
|
|
|
if len(str(obs)) > 3000:
|
|
obs = str(obs)[:3000] + "... [TRUNCATED]"
|
|
current_history += f"\nAgente: {response}\nSISTEMA ({t_name}): {obs}\n"
|
|
else:
|
|
print(f"[AGENT] Erro: Ferramenta '{t_name}' não encontrada.")
|
|
current_history += f"\nAgente: {response}\nSISTEMA: Erro: Ferramenta '{t_name}' inexistente no sistema.\n"
|
|
else:
|
|
# Se não há ferramenta, terminou o pensamento.
|
|
return response
|
|
|
|
return f"Limite de pensamento ({max_iterations} iterações) atingido.\nÚltima resposta: {response if 'response' in locals() else 'Nenhuma'}"
|