🚀 Auto-deploy: BotVPS atualizado em 02/05/2026 15:37:40
This commit is contained in:
104
core_tools.py
104
core_tools.py
@@ -393,6 +393,93 @@ class WorkspaceTools:
|
||||
cmd = 'docker exec coolify-db psql -U coolify -d coolify -c "SELECT application_name, status, created_at FROM application_deployment_queues ORDER BY created_at DESC LIMIT 5;"'
|
||||
return run_bash(cmd)
|
||||
|
||||
# ============================================================
|
||||
# BROWSER CLOUD TOOLS
|
||||
# ============================================================
|
||||
|
||||
BROWSER_CLOUD_URL = "http://localhost:8088"
|
||||
_current_session_id = None
|
||||
|
||||
class BrowserCloudTools:
|
||||
@staticmethod
|
||||
def _req(method: str, path: str, data: dict = None):
|
||||
import urllib.request, json
|
||||
url = f"{BROWSER_CLOUD_URL}{path}"
|
||||
body = json.dumps(data).encode() if data else None
|
||||
req = urllib.request.Request(url, data=body, method=method,
|
||||
headers={"Content-Type": "application/json"})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
return json.loads(r.read())
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
@staticmethod
|
||||
def _session():
|
||||
global _current_session_id
|
||||
if _current_session_id:
|
||||
return _current_session_id
|
||||
r = BrowserCloudTools._req("POST", "/session", {"headless": True})
|
||||
if "session_id" in r:
|
||||
_current_session_id = r["session_id"]
|
||||
return _current_session_id
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def navigate(url: str) -> str:
|
||||
sid = BrowserCloudTools._session()
|
||||
if not sid:
|
||||
return "Erro: não foi possível criar sessão no browser cloud"
|
||||
r = BrowserCloudTools._req("POST", f"/session/{sid}/navigate",
|
||||
{"url": url, "wait_until": "load"})
|
||||
if "error" in r:
|
||||
return f"Erro: {r['error']}"
|
||||
return f"OK — {r.get('title', '')} ({url})"
|
||||
|
||||
@staticmethod
|
||||
def screenshot(url_or_current: str = "current") -> str:
|
||||
sid = BrowserCloudTools._session()
|
||||
if not sid:
|
||||
return "Erro: sem sessão"
|
||||
# If URL provided, navigate first
|
||||
if url_or_current != "current" and url_or_current.startswith("http"):
|
||||
nav = BrowserCloudTools.navigate(url_or_current)
|
||||
if nav.startswith("Erro"):
|
||||
return nav
|
||||
r = BrowserCloudTools._req("GET", f"/session/{sid}/screenshot")
|
||||
if "error" in r:
|
||||
return f"Erro: {r['error']}"
|
||||
b64 = r.get("data", "")
|
||||
size = len(b64) * 3 // 4 # base64 → bytes approx
|
||||
return f"Screenshot OK — {r.get('format')} {size // 1024}KB (base64)"
|
||||
|
||||
@staticmethod
|
||||
def click(selector: str) -> str:
|
||||
sid = BrowserCloudTools._session()
|
||||
if not sid:
|
||||
return "Erro: sem sessão"
|
||||
r = BrowserCloudTools._req("POST", f"/session/{sid}/click",
|
||||
{"selector": selector})
|
||||
if "error" in r:
|
||||
return f"Erro: {r['error']}"
|
||||
return "OK — clicado"
|
||||
|
||||
@staticmethod
|
||||
def fill(input_str: str) -> str:
|
||||
# Formato: selector|value|submit(optional)
|
||||
parts = input_str.split("|")
|
||||
selector = parts[0]
|
||||
value = parts[1] if len(parts) > 1 else ""
|
||||
submit = len(parts) > 2 and parts[2].lower() == "true"
|
||||
sid = BrowserCloudTools._session()
|
||||
if not sid:
|
||||
return "Erro: sem sessão"
|
||||
r = BrowserCloudTools._req("POST", f"/session/{sid}/fill",
|
||||
{"selector": selector, "value": value, "submit": submit})
|
||||
if "error" in r:
|
||||
return f"Erro: {r['error']}"
|
||||
return "OK — preenchido" + (" e submetido" if submit else "")
|
||||
|
||||
# ============================================================
|
||||
# HERMES ORCHESTRATOR
|
||||
# ============================================================
|
||||
@@ -532,6 +619,23 @@ AVAILABLE_TOOLS = {
|
||||
"description": "Delega tarefas muito complexas para o Operador Master (Hermes Agent)",
|
||||
"func": delegate_to_hermes
|
||||
},
|
||||
# Browser Cloud
|
||||
"browser_navigate": {
|
||||
"description": "Navega URL no browser cloud (HEADLESS). Uso: URL completa",
|
||||
"func": BrowserCloudTools.navigate
|
||||
},
|
||||
"browser_screenshot": {
|
||||
"description": "Tira screenshot do browser cloud (PNG base64). Uso: URL ou 'current'",
|
||||
"func": BrowserCloudTools.screenshot
|
||||
},
|
||||
"browser_click": {
|
||||
"description": "Clica em elemento CSS no browser cloud. Uso: seletor CSS",
|
||||
"func": BrowserCloudTools.click
|
||||
},
|
||||
"browser_fill": {
|
||||
"description": "Preenche input e opcionalmente submete. Uso: seletor|valor|submeter(true/false)",
|
||||
"func": BrowserCloudTools.fill
|
||||
},
|
||||
# Legado (aliases)
|
||||
"get_docker_stats": {
|
||||
"description": "CPU/RAM por container (legacy)",
|
||||
|
||||
Reference in New Issue
Block a user