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 WEVALSystè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
]);
|
|---|