prepare("INSERT INTO admin.hamid_memory (session_id, user_id, memory_type, key, value, confidence, source) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW(), access_count = admin.hamid_memory.access_count + 1"); $stmt->execute([ $input['session_id'] ?? '', $input['user_id'] ?? 'default', $input['type'] ?? 'fact', $input['key'] ?? '', $input['value'] ?? '', $input['confidence'] ?? 1.0, $input['source'] ?? 'conversation' ]); echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); break; case 'recall': // Rappeler des mémoires pertinentes $query = $input['query'] ?? ''; $limit = $input['limit'] ?? 10; $type = $input['type'] ?? null; $sql = "SELECT * FROM admin.hamid_memory WHERE 1=1"; $params = []; if ($type) { $sql .= " AND memory_type = ?"; $params[] = $type; } if ($query) { $sql .= " AND (key ILIKE ? OR value ILIKE ?)"; $params[] = "%$query%"; $params[] = "%$query%"; } $sql .= " ORDER BY confidence DESC, access_count DESC, updated_at DESC LIMIT ?"; $params[] = $limit; $stmt = $pdo->prepare($sql); $stmt->execute($params); $memories = $stmt->fetchAll(PDO::FETCH_ASSOC); // Mettre à jour access_count foreach ($memories as $m) { $pdo->exec("UPDATE admin.hamid_memory SET access_count = access_count + 1, last_accessed = NOW() WHERE id = " . $m['id']); } echo json_encode(['memories' => $memories, 'count' => count($memories)]); break; case 'learn': // Apprentissage automatique $stmt = $pdo->prepare("INSERT INTO admin.hamid_learning (topic, question, answer, learned_from) VALUES (?, ?, ?, ?)"); $stmt->execute([ $input['topic'] ?? 'general', $input['question'] ?? '', $input['answer'] ?? '', $input['session_id'] ?? '' ]); echo json_encode(['success' => true, 'learned' => true]); break; case 'extract_entities': // Extraire entités d'un texte $text = $input['text'] ?? ''; $entities = extractEntities($text); foreach ($entities as $e) { $stmt = $pdo->prepare("INSERT INTO admin.hamid_entities (entity_type, entity_name, properties) VALUES (?, ?, ?::jsonb) ON CONFLICT DO NOTHING"); $stmt->execute([$e['type'], $e['name'], json_encode($e['properties'] ?? [])]); } echo json_encode(['entities' => $entities]); break; case 'get_context': // Obtenir contexte complet pour une session $sessionId = $input['session_id'] ?? ''; $userId = $input['user_id'] ?? 'default'; // Mémoires récentes $stmt = $pdo->prepare("SELECT * FROM admin.hamid_memory WHERE (session_id = ? OR user_id = ?) ORDER BY updated_at DESC LIMIT 20"); $stmt->execute([$sessionId, $userId]); $memories = $stmt->fetchAll(PDO::FETCH_ASSOC); // Apprentissages pertinents $stmt = $pdo->prepare("SELECT * FROM admin.hamid_learning ORDER BY times_used DESC, created_at DESC LIMIT 10"); $stmt->execute(); $learnings = $stmt->fetchAll(PDO::FETCH_ASSOC); // Entités récentes $stmt = $pdo->prepare("SELECT * FROM admin.hamid_entities ORDER BY last_seen DESC LIMIT 20"); $stmt->execute(); $entities = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode([ 'memories' => $memories, 'learnings' => $learnings, 'entities' => $entities ]); break; case 'stats': $stats = []; $stmt = $pdo->query("SELECT COUNT(*) as total, memory_type FROM admin.hamid_memory GROUP BY memory_type"); $stats['memories'] = $stmt->fetchAll(PDO::FETCH_ASSOC); $stmt = $pdo->query("SELECT COUNT(*) as total FROM admin.hamid_learning"); $stats['learnings'] = $stmt->fetch(PDO::FETCH_ASSOC)['total']; $stmt = $pdo->query("SELECT COUNT(*) as total FROM admin.hamid_entities"); $stats['entities'] = $stmt->fetch(PDO::FETCH_ASSOC)['total']; echo json_encode($stats); break; default: echo json_encode(['error' => 'Action inconnue']); } function extractEntities($text) { $entities = []; // Détecter IPs if (preg_match_all('/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/', $text, $matches)) { foreach ($matches[0] as $ip) { $entities[] = ['type' => 'server', 'name' => $ip, 'properties' => ['ip' => $ip]]; } } // Détecter domaines if (preg_match_all('/\b[a-zA-Z0-9-]+\.[a-zA-Z]{2,}\b/', $text, $matches)) { foreach ($matches[0] as $domain) { if (!filter_var($domain, FILTER_VALIDATE_IP)) { $entities[] = ['type' => 'domain', 'name' => $domain]; } } } // Détecter technologies connues $techs = ['PostgreSQL', 'PowerMTA', 'Apache', 'Nginx', 'PHP', 'Java', 'Python', 'WEVAL', 'FMGAPP', 'BCGAPP', 'Redis', 'Docker', 'Kubernetes']; foreach ($techs as $tech) { if (stripos($text, $tech) !== false) { $entities[] = ['type' => 'technology', 'name' => $tech]; } } return $entities; }