setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (Exception $e) { echo json_encode(['success' => false, 'error' => 'DB Error']); exit; } // Config $config = []; try { $stmt = $pdo->query("SELECT config_key, config_value FROM admin.commonia_config"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $config[$row['config_key']] = $row['config_value']; } catch (Exception $e) {} // Input - supporter JSON et FormData $contentType = $_SERVER['CONTENT_TYPE'] ?? ''; if (strpos($contentType, 'application/json') !== false) { $input = json_decode(file_get_contents('php://input'), true) ?: []; } else { $input = $_POST; } $message = trim($input['message'] ?? ''); $provider = $input['provider'] ?? $config['default_provider'] ?? 'cerebras'; if (empty($message)) { echo json_encode(['success' => false, 'error' => 'Message vide']); exit; } $startTime = microtime(true); $msgLower = mb_strtolower($message); $artifacts = []; $aiResponse = ''; $autoGenerated = false; $kbUsed = false; $kbContext = ''; // ===== KNOWLEDGE BASE ===== // Ne pas utiliser KB pour ollama_mini (trop lent) if (true) { try { $kbStmt = $pdo->query("SELECT content, title FROM admin.commonia_knowledge ORDER BY created_at DESC LIMIT 10"); $kbDocs = $kbStmt->fetchAll(PDO::FETCH_ASSOC); if (!empty($kbDocs)) { $kbContext = "\n\n[KNOWLEDGE BASE WEVAL]:\n"; foreach ($kbDocs as $doc) { $kbContext .= "- " . ($doc['title'] ?? 'Doc') . ": " . substr($doc['content'], 0, 500) . "\n"; } $kbUsed = true; } } catch (Exception $e) { // KB pas disponible, continuer sans } } // ===== DETECTION GENERATION DOCUMENTS ===== if ($toolsAvailable && class_exists('IATools')) { // PDF / Document / Architecture / Schema - AVEC KB COMPLÈTE (Articles + QA) if (preg_match('/(pdf|pd|schema|schéma|architecture|architec|document|doc|rapport)/iu', $msgLower) && preg_match('/(génère|genere|générer|generer|créer|creer|créé|cree|fais|faire|veux|veu|veut|envoi|envoie|donne|détail|detail)/iu', $msgLower)) { // 1. Récupérer le contexte KB COMPLET (Articles + QA) $kbContext = ''; try { // Articles pertinents $searchTerms = preg_split('/\s+/', $message); $searchPattern = '%' . implode('%', $searchTerms) . '%'; $stmtArticles = $pdo->prepare(" SELECT title, description, content, category FROM admin.commonia_articles WHERE title ILIKE ? OR description ILIKE ? OR content ILIKE ? OR category ILIKE ? LIMIT 5 "); $stmtArticles->execute([$searchPattern, $searchPattern, $searchPattern, $searchPattern]); $articles = $stmtArticles->fetchAll(PDO::FETCH_ASSOC); if (!empty($articles)) { $kbContext .= "\n=== ARTICLES KB ===\n"; foreach ($articles as $art) { $kbContext .= "📄 {$art['title']} [{$art['category']}]\n"; $kbContext .= substr($art['content'] ?? $art['description'] ?? '', 0, 800) . "\n\n"; } } // QA pertinents $stmtQA = $pdo->prepare(" SELECT question, answer, category FROM admin.commonia_knowledge WHERE question ILIKE ? OR answer ILIKE ? OR category ILIKE ? LIMIT 10 "); $stmtQA->execute([$searchPattern, $searchPattern, $searchPattern]); $qas = $stmtQA->fetchAll(PDO::FETCH_ASSOC); if (!empty($qas)) { $kbContext .= "\n=== QA KB ===\n"; foreach ($qas as $qa) { $kbContext .= "❓ {$qa['question']}\n✅ " . substr($qa['answer'], 0, 500) . "\n\n"; } } $kbUsed = !empty($articles) || !empty($qas); } catch (Exception $e) { $kbContext = ''; } // 2. Demander à l'IA de RÉFLÉCHIR puis GÉNÉRER avec KB $brain = new HamidBrain(); $contentPrompt = "Tu dois créer un document HTML professionnel et TRÈS DÉTAILLÉ sur: '$message' === PROCESSUS DE RÉFLEXION === Avant de générer, réfléchis: 1. ANALYSE: Que demande exactement l'utilisateur? 2. CONTEXTE: Utilise les informations de la Knowledge Base ci-dessous 3. STRUCTURE: Quelles sections sont nécessaires? 4. CONTENU: Minimum 5000 mots, au moins 15 pages, données concrètes $kbContext === DONNÉES WEVAL À INCLURE === - Serveur: 89.167.40.150 (Hetzner Cloud, Ubuntu 24.04, 16GB RAM) - WEVAL: port 5821, FMGAPP: port 5822, BCGAPP: port 5823 - Base: PostgreSQL (adx_system, adx_clients) - Email: PowerMTA, Office 365 automation - IA: WEVAL MIND avec 11 providers (Cerebras, Groq, DeepSeek, etc.) === FORMAT HTML REQUIS === - Structure:

,

,

pour titres - Tableaux:
/ pour données - Listes:
  • pour énumérations - Sections: Introduction, Architecture, Composants, Configuration, Sécurité, Conclusion - CSS inline pour style professionnel Retourne UNIQUEMENT le HTML (pas de markdown, pas de ```)."; $aiResult = $brain->callWithFallback($contentPrompt, $kbContext, $provider); if ($aiResult['success'] && !empty($aiResult['response'])) { $richContent = $aiResult['response']; $richContent = preg_replace('/^```html?\s*/i', '', $richContent); $richContent = preg_replace('/```\s*$/', '', $richContent); } else { $richContent = method_exists('IATools', 'getArchitectureContent') ? IATools::getArchitectureContent() : '

    Architecture WEVAL

    Système email marketing

    '; } // 3. Générer le PDF $result = IATools::generate_pdf($richContent, 'Architecture_WEVAL_' . date('Ymd_His')); if ($result['success']) { $result['type'] = 'pdf'; $result['title'] = 'Architecture WEVAL'; $artifacts[] = $result; $aiResponse = "✅ Voici votre document PDF.\n\n📄 **Fichier:** [{$result['file']}]({$result['url']})"; $autoGenerated = true; } } // POWERPOINT elseif (preg_match('/(ppt|powerpoint|présentation|presentation|diapo)/iu', $msgLower) && preg_match('/(génère|genere|créer|creer|fais|faire|veux|envoi|donne)/iu', $msgLower)) { $result = IATools::generate_pptx(null, 'Presentation_WEVAL_' . date('Ymd_His')); if ($result['success']) { $result['type'] = 'presentation'; $result['title'] = 'Présentation WEVAL'; $artifacts[] = $result; $aiResponse = "✅ Voici votre présentation PowerPoint.\n\n📊 **Fichier:** [{$result['file']}]({$result['url']})"; $autoGenerated = true; } } // EXCEL elseif (preg_match('/(excel|xlsx|tableur|feuille.*calcul)/iu', $msgLower) && preg_match('/(génère|genere|créer|creer|fais|faire|veux|envoi|donne)/iu', $msgLower)) { $result = IATools::generate_xlsx(null, 'Rapport_WEVAL_' . date('Ymd_His')); if ($result['success']) { $result['type'] = 'spreadsheet'; $result['title'] = 'Rapport Excel'; $artifacts[] = $result; $aiResponse = "✅ Voici votre fichier Excel.\n\n📈 **Fichier:** [{$result['file']}]({$result['url']})"; $autoGenerated = true; } } // WORD elseif (preg_match('/(word|docx|doc\b)/iu', $msgLower) && preg_match('/(génère|genere|créer|creer|fais|faire|veux|envoi|donne)/iu', $msgLower)) { $result = IATools::generate_docx('', 'Document_WEVAL_' . date('Ymd_His')); if ($result['success']) { $result['type'] = 'document'; $result['title'] = 'Document Word'; $artifacts[] = $result; $aiResponse = "✅ Voici votre document Word.\n\n📝 **Fichier:** [{$result['file']}]({$result['url']})"; $autoGenerated = true; } } // QR CODE elseif (preg_match('/(qr|qrcode)/iu', $msgLower)) { $url = 'https://wevads.com'; if (preg_match('/https?:\/\/[^\s]+/', $message, $m)) $url = $m[0]; $result = IATools::generate_qrcode($url); if ($result['success']) { $result['type'] = 'image'; $result['title'] = 'QR Code'; $artifacts[] = $result; $aiResponse = "✅ QR Code généré pour: $url\n\n🔲 **Fichier:** [{$result['file']}]({$result['url']})"; $autoGenerated = true; } } } // ===== APPEL IA ===== if (!$autoGenerated) { if (class_exists('HamidBrain')) { try { $brain = new HamidBrain(); // Ajouter le contexte KB au message $fullMessage = $message; if ($kbUsed && !empty($kbContext)) { $fullMessage = $message . $kbContext; } $response = $brain->callProvider($provider, $fullMessage, ''); if ($response['success']) { $aiResponse = $response['response']; } else { echo json_encode([ 'success' => false, 'error' => $response['error'] ?? 'Erreur provider', 'provider' => strtoupper($provider) ]); exit; } } catch (Exception $e) { echo json_encode([ 'success' => false, 'error' => $e->getMessage(), 'provider' => strtoupper($provider) ]); exit; } } else { $aiResponse = "⚠️ Cerveau IA non chargé. Vérifiez /commonia/commonia-brain.php"; } } // === PARSING THINKING === $thinking = null; if (preg_match("/(.*?)<\/thinking>/s", $aiResponse, $thinkMatch)) { $thinking = trim($thinkMatch[1]); $aiResponse = trim(preg_replace("/.*?<\/thinking>/s", "", $aiResponse)); } // === FIN PARSING === $duration = round((microtime(true) - $startTime) * 1000); echo json_encode([ 'success' => true, 'response' => trim($aiResponse), 'thinking' => $thinking, 'provider' => strtoupper($provider), 'duration_ms' => $duration, 'kb_used' => $kbUsed, 'artifacts' => $artifacts, 'tools_used' => $autoGenerated ]);