[ 'name' => 'MiroFish Swarm Intelligence', 'system' => "Tu es l'agent MiroFish, moteur d'intelligence en essaim. Tu utilises la simulation multi-agents pour faire des prédictions. API MiroFish: http://127.0.0.1:5001 - GET /health: statut du service - GET /api/report/list: liste des rapports - POST /api/report/generate: generer un rapport (body: {topic, language}) - POST /api/report/chat: discuter avec un rapport (body: {message, report_id}) - GET /api/report//progress: progression Bridge: http://127.0.0.1/api/mirofish-bridge.php?action=ceo (donnees CEO) Reponds en JSON: {\"action\":\"api\",\"url\":\"http://127.0.0.1:5001/api/report/list\"} pour appeler l'API MiroFish {\"action\":\"generate\",\"topic\":\"...\"} pour lancer une simulation {\"action\":\"done\",\"summary\":\"...\",\"data\":{}} quand tu as termine", 'tools' => ['api_call', 'exec_local'], 'max_steps' => 6, ], 'devops' => [ 'name' => 'WEVIA DevOps Agent', 'system' => "Tu es un agent DevOps autonome pour WEVAL Consulting. Tu surveilles l'infrastructure: - S204 (204.168.152.13): PRIMARY, Ollama, Qdrant, 22 Docker, nginx, PostgreSQL - S95 (95.216.167.89): WEVADS, Arsenal:5890, iResponse:5821, PMTA, PostgreSQL - S151 (151.80.235.110): OVH tracking, Ollama, nginx Tu peux exécuter des commandes shell pour diagnostiquer. Réponds en JSON: {\"action\":\"exec\",\"cmd\":\"df -h /\"} pour exécuter une commande {\"action\":\"analyze\",\"findings\":\"...\"} pour donner ton analyse {\"action\":\"done\",\"summary\":\"...\",\"status\":\"ok|warning|critical\"} quand tu as terminé", 'tools' => ['exec_local'], 'max_steps' => 8, ], 'ethica' => [ 'name' => 'WEVIA Ethica Agent', 'system' => "Tu es un agent Ethica spécialisé dans la gestion des HCP (Healthcare Professionals) pour le Maroc, Tunisie, Algérie. DB: PostgreSQL schema ethica dans adx_system sur S95. Table: medecins_real (135K+ HCPs). Scrapers: DabaDoc, Google Maps, RichScraper, ethica-enrich-v4.py. Tu peux exécuter des requêtes SQL et des scripts. Réponds en JSON: {\"action\":\"sql\",\"query\":\"SELECT COUNT(*) FROM ethica.medecins_real\"} pour une requête SQL {\"action\":\"exec\",\"cmd\":\"...\"} pour un script {\"action\":\"done\",\"summary\":\"...\",\"data\":{}} quand tu as terminé", 'tools' => ['sql_s95', 'exec_s95'], 'max_steps' => 6, ], 'security' => [ 'name' => 'WEVIA Security Agent', 'system' => "Tu es un agent de sécurité pour WEVAL Consulting. Tu audites: - 5 comptes O365 compromis: rodolftripp, sfgb518, phyleciaamato, kamrynnbonilla, jolineweatherly - PMTA/MTA status sur S95 - Spamhaus blacklist check - SSL certificates expiry - Firewall ports ouverts Réponds en JSON: {\"action\":\"exec\",\"cmd\":\"...\"} pour vérifier {\"action\":\"done\",\"summary\":\"...\",\"alerts\":[]} quand tu as terminé", 'tools' => ['exec_local', 'exec_s95'], 'max_steps' => 8, ], 'monitor' => [ 'name' => 'WEVIA Monitor Agent', 'system' => "Tu es un agent de monitoring. Tu vérifies: - Disk usage (<85%) - Docker containers (tous UP?) - Ollama (port 11435 répond?) - Qdrant (collections saines?) - L99 tests (derniers résultats?) - Crons (tous actifs?) Réponds en JSON: {\"action\":\"exec\",\"cmd\":\"...\"} pour vérifier {\"action\":\"done\",\"summary\":\"...\",\"metrics\":{}} quand tu as terminé", 'tools' => ['exec_local'], 'max_steps' => 6, ], ]; // ═══════════════════════════════════════════════════════════════ // TOOL EXECUTORS // ═══════════════════════════════════════════════════════════════ function agent_exec_local($cmd, $timeout = 10) { // $cmd = escapeshellcmd($cmd); // Removed: corrupts pipes and flags $result = shell_exec("timeout $timeout bash -c " . escapeshellarg($cmd) . " 2>&1"); $output = $result ? mb_substr($result, 0, 3000) : ""; return ['output' => $output, 'exit_code' => 0]; } function agent_exec_s95($cmd, $timeout = 15) { $escaped = str_replace("'", "'\\''", $cmd); $sshCmd = "ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p49222 root@10.1.0.3 '$escaped'"; $output = []; $return = 0; exec("timeout $timeout $sshCmd 2>&1", $output, $return); return ['output' => implode("\n", array_slice($output, 0, 50)), 'exit_code' => $return]; } function agent_sql_s95($query, $timeout = 10) { $escaped = str_replace("'", "'\\''", $query); $cmd = "ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p49222 root@10.1.0.3 'PGPASSWORD=admin123 psql -U admin -d adx_system -t -A -c \"$escaped\"'"; $output = []; $return = 0; exec("timeout $timeout $cmd 2>&1", $output, $return); return ['output' => implode("\n", array_slice($output, 0, 30)), 'exit_code' => $return]; } // ═══════════════════════════════════════════════════════════════ // AGENT LOOP ENGINE // ═══════════════════════════════════════════════════════════════ function agent_run($agentId, $goal, $maxSteps = null) { global $AGENTS; if (!isset($AGENTS[$agentId])) return ['error' => "Unknown agent: $agentId"]; $agent = $AGENTS[$agentId]; $maxSteps = $maxSteps ?? $agent['max_steps'] ?? AGENT_MAX_STEPS; $systemPrompt = $agent['system']; $history = []; $steps = []; $startTime = microtime(true); // Initial message: the goal $history[] = ['role' => 'user', 'content' => "OBJECTIF: $goal\n\nCommence par analyser ce qui est nécessaire, puis exécute étape par étape. Réponds UNIQUEMENT en JSON valide."]; for ($step = 1; $step <= $maxSteps; $step++) { // Call Master Router with RAG $result = mr_route( end($history)['content'], $systemPrompt, array_slice($history, 0, -1), ['max_tier' => 2, 'force_tier' => 1] // Skip Ollama (too slow on CPU), go Cerebras direct ); $response = $result['content'] ?? ''; $history[] = ['role' => 'assistant', 'content' => $response]; // Parse JSON action from response $action = null; if (preg_match('/\{[^{}]*"action"\s*:\s*"[^"]+"/s', $response, $matches)) { $jsonStr = $matches[0]; // Try to find the complete JSON object $braceCount = 0; $jsonComplete = ''; for ($i = strpos($response, $jsonStr); $i < strlen($response); $i++) { $char = $response[$i]; if ($char === '{') $braceCount++; if ($char === '}') $braceCount--; $jsonComplete .= $char; if ($braceCount === 0) break; } $action = json_decode($jsonComplete, true); } $stepData = [ 'step' => $step, 'model' => $result['model'] ?? 'unknown', 'provider' => $result['provider'] ?? 'unknown', 'latency_ms' => $result['latency_ms'] ?? 0, 'action' => $action, ]; if (!$action) { $stepData['raw_response'] = mb_substr($response, 0, 500); $stepData['error'] = 'no_json_action'; $steps[] = $stepData; // Add context for retry $history[] = ['role' => 'user', 'content' => "ERREUR: Ta réponse n'est pas en JSON valide. Réponds UNIQUEMENT avec un objet JSON contenant \"action\"."]; continue; } // Execute action switch ($action['action'] ?? '') { case 'exec': $cmd = $action['cmd'] ?? ''; if (empty($cmd)) { $stepData['result'] = 'empty command'; break; } // Determine if local or S95 if (in_array('exec_s95', $agent['tools']) && ( strpos($cmd, 'S95') !== false || strpos($cmd, 's95') !== false || strpos($cmd, '10.1.0.3') !== false || strpos($cmd, 'ethica') !== false || strpos($cmd, 'pmta') !== false )) { $execResult = agent_exec_s95($cmd); } else { $execResult = agent_exec_local($cmd); } $stepData['result'] = $execResult; $history[] = ['role' => 'user', 'content' => "RÉSULTAT COMMANDE:\n```\n{$execResult['output']}\n```\nExit code: {$execResult['exit_code']}\n\nAnalyse ce résultat et continue. Réponds en JSON."]; break; case 'sql': $query = $action['query'] ?? ''; if (empty($query)) { $stepData['result'] = 'empty query'; break; } $sqlResult = agent_sql_s95($query); $stepData['result'] = $sqlResult; $history[] = ['role' => 'user', 'content' => "RÉSULTAT SQL:\n```\n{$sqlResult['output']}\n```\n\nAnalyse et continue. Réponds en JSON."]; break; case 'analyze': $stepData['findings'] = $action['findings'] ?? ''; $history[] = ['role' => 'user', 'content' => "OK, analyse notée. Continue avec la prochaine vérification ou termine avec {\"action\":\"done\"}. Réponds en JSON."]; break; case 'done': $stepData['summary'] = $action['summary'] ?? ''; $stepData['status'] = $action['status'] ?? 'unknown'; $steps[] = $stepData; $totalTime = round((microtime(true) - $startTime) * 1000); $totalCost = array_sum(array_column($steps, 'cost')); $report = [ 'agent' => $agent['name'], 'goal' => $goal, 'steps_count' => count($steps), 'total_time_ms' => $totalTime, 'total_cost' => $totalCost, 'summary' => $action['summary'] ?? '', 'status' => $action['status'] ?? 'unknown', 'data' => $action['data'] ?? $action['metrics'] ?? $action['alerts'] ?? null, 'steps' => $steps, ]; // Log $logFile = AGENT_LOG_DIR . "/$agentId-" . date('Y-m-d-His') . ".json"; @file_put_contents($logFile, json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); return $report; default: $stepData['error'] = "Unknown action: " . ($action['action'] ?? 'null'); $history[] = ['role' => 'user', 'content' => "Action inconnue. Utilise: exec, sql, analyze, ou done. Réponds en JSON."]; } $steps[] = $stepData; } // Max steps reached return [ 'agent' => $agent['name'], 'goal' => $goal, 'steps_count' => count($steps), 'total_time_ms' => round((microtime(true) - $startTime) * 1000), 'status' => 'max_steps_reached', 'steps' => $steps, ]; } // ═══════════════════════════════════════════════════════════════ // API HANDLER // ═══════════════════════════════════════════════════════════════ // List agents if (isset($_GET['list'])) { global $AGENTS; $list = []; foreach ($AGENTS as $id => $a) { $list[$id] = ['name' => $a['name'], 'tools' => $a['tools'], 'max_steps' => $a['max_steps']]; } echo json_encode($list, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } $agentId = $_GET['agent'] ?? $_POST['agent'] ?? ''; $goal = $_GET['goal'] ?? $_POST['goal'] ?? ''; if (empty($agentId) || empty($goal)) { echo json_encode([ 'error' => 'Usage: ?agent=devops|ethica|security|monitor&goal=your+task', 'agents' => array_keys($AGENTS), ]); exit; } // Run agent $report = agent_run($agentId, $goal); echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);