diff --git a/orchestrator.py b/orchestrator.py index 436aa2d..f11af93 100644 --- a/orchestrator.py +++ b/orchestrator.py @@ -5,6 +5,7 @@ import json import re +import os from typing import Dict, List, Optional from llm_providers import ( call_planner, call_executor, get_planner_llm, get_executor_llm, @@ -20,24 +21,22 @@ from credential_manager import sync_credentials, get_services_status PLANNER_SYSTEM_PROMPT = """Você é o PLANNER AGENT do BotVPS. Seu trabalho é decompor tarefas em passos executáveis CORRETOS. -### CAMINHO DO REPOSITÓRIO: -O repositório BotVPS está em: /data/applications/bw1erd9ww5121i1fsh420bcj -O repositório Git está em: /data/repositories/0/5/5adtracksteel/AdmTrackSteel +### REPOSITORIOS CONHECIDOS: +- BotVPS: /data/applications/bw1erd9ww5121i1fsh420bcj +- TrackSteel: /data/repositories/0/5/5adtracksteel/AdmTrackSteel + +{CONTEXT_INFO} ### REGRAS CRÍTICAS DE COMANDOS: 1. USE SEMPRE "docker compose" (COM ESPAÇO), NUNCA "docker-compose" (COM HÍFEN) 2. Para git, use o caminho ABSOLUTO completo do repositório 3. Para docker compose, use "cd /caminho && docker compose up -d" +4. Se não souber o caminho, use: find /data/repositories -name '*.git' -type d ### EXEMPLOS DE COMANDOS CORRETOS: -✅ CORRETO: cd /data/applications/bw1erd9ww5121i1fsh420bcj && git pull origin master -❌ ERRADO: git -C /BotVPS pull - -✅ CORRETO: cd /data/applications/bw1erd9ww5121i1fsh420bcj && docker compose up -d --build -❌ ERRADO: docker-compose up -d - -✅ CORRETO: cd /data/applications/bw1erd9ww5121i1fsh420bcj && docker compose down -❌ ERRADO: docker-compose down +✅ CORRETO: cd /repo/path && git pull origin master +✅ CORRETO: cd /repo/path && docker compose up -d --build +✅ CORRETO: docker restart nome-do-container ### NÍVEIS DE PERIGO: - SAFE: listar, ver status, ler logs @@ -104,6 +103,78 @@ def _format_tools_for_prompt() -> str: lines.append(f"- {name}: {info['desc']} [{info['danger']}]") return "\n".join(lines) +def detect_git_repo_path(task: str) -> str: + """ + Detecta automaticamente o caminho do repositório Git baseado na tarefa. + Retorna o caminho do repositório mais provável. + """ + from tools_v2 import run_bash + + # Normaliza o texto da tarefa + task_lower = task.lower() + + # Lista de repositórios conhecidos no host + known_repos = [ + "/data/repositories/0/5/5adtracksteel/AdmTrackSteel", + "/data/repositories/0/5/5adtracksteel/BotVPS", + "/data/applications/bw1erd9ww5121i1fsh420bcj", + "/data/coolify", + "/root", + "/app" + ] + + # Tenta detectar pelo nome mencionado na tarefa + if "tracksteel" in task_lower or "tracksteel" in task_lower: + return "/data/repositories/0/5/5adtracksteel/AdmTrackSteel" + if "botvps" in task_lower or "bot vps" in task_lower: + return "/data/applications/bw1erd9ww5121i1fsh420bcj" + if "coolify" in task_lower: + return "/data/coolify" + + # Tenta encontrar repositório git válido + for repo_path in known_repos: + result = run_bash(f"test -d {repo_path}/.git && echo 'FOUND:{repo_path}' || true") + if result.get("success") and "FOUND:" in result.get("output", ""): + return result["output"].split("FOUND:")[1].strip() + + # Procura em /data/repositories por repositórios git + result = run_bash("find /data/repositories -name '*.git' -type d 2>/dev/null | head -10") + if result.get("success") and result.get("output"): + # Retorna o primeiro repositório encontrado + first_repo = result["output"].split("\n")[0].replace("/.git", "") + return first_repo + + # Fallback: retorna /app se existir + if os.path.exists("/app/.git"): + return "/app" + + return "/" + +def detect_app_in_docker(task: str) -> str: + """ + Detecta qual container/app o usuário quer interagir baseado na tarefa. + """ + from tools_v2 import run_bash + + task_lower = task.lower() + + # Lista containers e tenta match + result = run_bash("docker ps --format '{{.Names}}' 2>/dev/null") + if result.get("success"): + containers = result["output"].lower() + + if "tracksteel" in task_lower: + if "tracksteel" in containers: + return "tracksteel" + if "botvps" in task_lower or "antigravity" in task_lower: + if "vps" in containers: + return "vps-ai-agent" + if "coolify" in task_lower: + if "coolify" in containers: + return "coolify" + + return "" + def _parse_json_response(text: str) -> Optional[Dict]: """Extrai JSON da resposta do LLM.""" # Tenta encontrar JSON no texto @@ -152,7 +223,22 @@ def plan_task(task: str) -> Dict: provider, model = get_planner_llm() print(f"[PLANNER] Using: {provider}/{model}") + # Detecta automaticamente informações do contexto + detected_repo = detect_git_repo_path(task) + detected_app = detect_app_in_docker(task) + + print(f"[CONTEXT] Repo: {detected_repo}, App: {detected_app}") + + # Contexto adicional para o planner + context_info = f""" +### CONTEXTO DETECTADO: +- Repositório mais provável: {detected_repo} +- Aplicação mais provável: {detected_app} +- Para descobrir o repositório correto, use: find /data/repositories -name '*.git' -type d 2>/dev/null +""" + system_prompt = PLANNER_SYSTEM_PROMPT.replace("{TOOLS_LIST}", _format_tools_for_prompt()) + system_prompt = system_prompt.replace("{CONTEXT_INFO}", context_info) response = call_planner(task, system_prompt) print(f"[RESPONSE] Planner response:\n{response[:500]}...")