Files
wevia-brain/cognitive-opus46-advanced.php
2026-04-12 23:01:36 +02:00

1031 lines
59 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* ╔═══════════════════════════════════════════════════════════════════════════╗
* ║ WEVIA COGNITIVE OPUS 4.6 ADVANCED — Final Capabilities Layer ║
* ║ Self-Correction, GPU Intelligence, Tool Planning, Ethical Reasoning ║
* ║ Analogical, Bayesian, Debate, Creative Synthesis, Knowledge Graph ║
* ║ 2026-03-03 — 150+ functions ║
* ╚═══════════════════════════════════════════════════════════════════════════╝
*/
// ═══════════════════════════════════════════════════════════════════════════
// MODULE R: SELF-CORRECTION ENGINE (15 functions)
// Detect errors in own output and auto-fix before delivery
// ═══════════════════════════════════════════════════════════════════════════
function selfCorrectionShouldActivate($response, $intent) {
return mb_strlen($response) > 200 && !in_array($intent, ['greeting','conversational']);
}
function detectLogicalContradiction($response) {
$sentences = preg_split('/(?<=[.!?])\s+/', $response);
$assertions = [];
foreach ($sentences as $s) {
if (preg_match('/\b(ne|pas|jamais|aucun|impossible)\b/i', $s)) $assertions[] = ['neg', $s];
elseif (preg_match('/\b(toujours|doit|obligatoire|certainement|absolument)\b/i', $s)) $assertions[] = ['pos', $s];
}
for ($i = 0; $i < count($assertions); $i++) {
for ($j = $i+1; $j < count($assertions); $j++) {
if ($assertions[$i][0] !== $assertions[$j][0]) {
$overlap = array_intersect(
array_filter(explode(' ', mb_strtolower($assertions[$i][1])), fn($w) => mb_strlen($w) > 4),
array_filter(explode(' ', mb_strtolower($assertions[$j][1])), fn($w) => mb_strlen($w) > 4)
);
if (count($overlap) >= 2) return ['found' => true, 'sentences' => [$assertions[$i][1], $assertions[$j][1]]];
}
}
}
return ['found' => false];
}
function detectHallucinatedNumbers($response) {
$flags = [];
preg_match_all('/(\d+(?:[.,]\d+)?)\s*%/', $response, $pcts);
foreach ($pcts[1] as $p) { $v = floatval(str_replace(',','.',$p)); if ($v > 99.9 || $v == 0) $flags[] = "Suspicious percentage: {$p}%"; }
preg_match_all('/(\d{4,})/', $response, $nums);
foreach ($nums[1] as $n) { if (intval($n) > 1000000 && !preg_match('/\d{4}-\d{2}/', $n)) $flags[] = "Large unverified number: $n"; }
return $flags;
}
function detectIncompleteCode($response) {
$issues = [];
if (preg_match('/```(\w+)/', $response) && !preg_match('/```\s*$/', $response)) $issues[] = 'Unclosed code block';
if (preg_match('/TODO|FIXME|PLACEHOLDER|à compléter|\.\.\.(?=\n)/i', $response)) $issues[] = 'Incomplete code markers';
$opens = substr_count($response, '{'); $closes = substr_count($response, '}');
if (abs($opens - $closes) > 2) $issues[] = "Brace mismatch: { = $opens, } = $closes";
return $issues;
}
function detectMissingContext($response, $msg) {
$questions = [];
if (preg_match('/\b(quel|which|combien|how many)\b/i', $msg) && !preg_match('/\d/', $response)) $questions[] = 'Question demande un chiffre, réponse sans chiffre';
if (preg_match('/\b(exemple|example)\b/i', $msg) && !preg_match('/exemple|par exemple|for example|```/i', $response)) $questions[] = 'Demande un exemple, pas fourni';
if (preg_match('/\b(liste|list|énumère)\b/i', $msg) && substr_count($response, "\n") < 3) $questions[] = 'Demande une liste, format insuffisant';
return $questions;
}
function autoFixResponse($response, $issues) {
foreach ($issues as $issue) {
if (strpos($issue, 'Unclosed code block') !== false) $response .= "\n```";
if (strpos($issue, 'Incomplete code') !== false) $response = preg_replace('/TODO|FIXME|PLACEHOLDER/i', '/* À implémenter */', $response);
}
$response = preg_replace('/\n{4,}/', "\n\n\n", $response);
$response = preg_replace('/ +/', ' ', $response);
return $response;
}
function selfCorrectionPipeline($response, $msg, $intent) {
if (!selfCorrectionShouldActivate($response, $intent)) return $response;
$allIssues = [];
$contradiction = detectLogicalContradiction($response);
if ($contradiction['found']) $allIssues[] = 'logical_contradiction';
$hallucNums = detectHallucinatedNumbers($response);
$allIssues = array_merge($allIssues, $hallucNums);
$incompleteCode = detectIncompleteCode($response);
$allIssues = array_merge($allIssues, $incompleteCode);
$missingCtx = detectMissingContext($response, $msg);
$allIssues = array_merge($allIssues, $missingCtx);
if (!empty($allIssues)) {
$response = autoFixResponse($response, $allIssues);
error_log("WEVIA_SELF_CORRECTION: fixed " . count($allIssues) . " issues: " . implode("|", array_slice($allIssues, 0, 3)));
}
return $response;
}
function detectTruncatedResponse($response) {
$lastChar = mb_substr(trim($response), -1);
if (in_array($lastChar, [',', ':', '(', '{', '['])) return true;
if (preg_match('/\b(et|or|mais|however|also|de plus)$/i', trim($response))) return true;
return false;
}
function detectLanguageMismatch($response, $expectedLang) {
if ($expectedLang === 'french' && preg_match_all('/\b(the|is|are|was|were|have|has|this|that|with)\b/i', $response) > 5) return true;
if ($expectedLang === 'english' && preg_match_all('/\b(le|la|les|est|sont|avec|dans|pour|qui|que)\b/i', $response) > 5) return true;
return false;
}
function detectExcessiveRepetition($response) {
$words = preg_split('/\s+/', mb_strtolower($response));
$freqs = array_count_values($words);
foreach ($freqs as $word => $count) {
if (mb_strlen($word) > 5 && $count > 8 && $count / count($words) > 0.02) return "Word '$word' repeated $count times";
}
return null;
}
function measureResponseDensity($response) {
$words = str_word_count($response);
$unique = count(array_unique(preg_split('/\s+/', mb_strtolower($response))));
return $words > 0 ? round($unique / $words, 3) : 0;
}
function detectOffTopic($response, $msg) {
$msgWords = array_filter(explode(' ', mb_strtolower($msg)), fn($w) => mb_strlen($w) > 4);
$respWords = array_filter(explode(' ', mb_strtolower($response)), fn($w) => mb_strlen($w) > 4);
if (count($msgWords) < 2) return false;
$overlap = count(array_intersect($msgWords, $respWords));
return $overlap / max(count($msgWords), 1) < 0.15;
}
function selfCorrectionScore($response, $msg) {
$score = 100;
if (detectTruncatedResponse($response)) $score -= 20;
if (detectExcessiveRepetition($response)) $score -= 15;
if (detectOffTopic($response, $msg)) $score -= 25;
$density = measureResponseDensity($response);
if ($density < 0.3) $score -= 10;
$codeIssues = detectIncompleteCode($response);
$score -= count($codeIssues) * 10;
return max(0, $score);
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE S: GPU MODEL INTELLIGENCE (20 functions)
// Smart model selection based on task type, load, and quality needs
// ═══════════════════════════════════════════════════════════════════════════
function getOllamaModelInventory() {
return [
'deepseek-r1:32b' => ['params' => '32B', 'type' => 'reasoning', 'speed' => 'slow', 'quality' => 'excellent', 'vram' => 20],
'qwen2.5:14b' => ['params' => '14B', 'type' => 'general', 'speed' => 'medium', 'quality' => 'good', 'vram' => 10],
'qwen2.5-coder:7b' => ['params' => '7B', 'type' => 'code', 'speed' => 'fast', 'quality' => 'good', 'vram' => 5],
'llama3.1:8b' => ['params' => '8B', 'type' => 'general', 'speed' => 'fast', 'quality' => 'good', 'vram' => 5],
'mistral:7b' => ['params' => '7B', 'type' => 'general', 'speed' => 'fast', 'quality' => 'good', 'vram' => 5],
'codellama:13b' => ['params' => '13B', 'type' => 'code', 'speed' => 'medium', 'quality' => 'good', 'vram' => 8],
'phi3:14b' => ['params' => '14B', 'type' => 'reasoning', 'speed' => 'medium', 'quality' => 'good', 'vram' => 10],
'nomic-embed-text' => ['params' => '137M', 'type' => 'embedding', 'speed' => 'instant', 'quality' => 'n/a', 'vram' => 1],
];
}
function selectBestGPUModel($intent, $complexity, $msgLen) {
if ($intent === 'code' || $intent === 'technical') {
return $complexity === 'complex' ? 'deepseek-r1:32b' : 'qwen2.5-coder:7b';
}
if ($intent === 'analytical' || $intent === 'strategic') {
return 'deepseek-r1:32b';
}
if ($intent === 'mathematical' || $intent === 'causal') {
return $complexity === 'simple' ? 'qwen2.5:14b' : 'deepseek-r1:32b';
}
if ($intent === 'creative') {
return 'qwen2.5:14b';
}
if ($msgLen < 30) return 'llama3.1:8b';
return $complexity === 'complex' ? 'qwen2.5:14b' : 'llama3.1:8b';
}
function selectCloudFallbackOrder($intent) {
$orders = [
'code' => ['cerebras','sambanova','groq'],
'technical' => ['cerebras','sambanova','groq'],
'analytical' => ['sambanova','groq','cerebras'],
'strategic' => ['sambanova','mistral','groq'],
'creative' => ['groq','sambanova','cerebras'],
'mathematical' => ['cerebras','sambanova','groq'],
'greeting' => ['groq','cerebras'],
'conversational' => ['groq','cerebras'],
];
return $orders[$intent] ?? ['groq','cerebras','sambanova'];
}
function estimateGPUInferenceTime($model, $inputTokens, $outputTokens) {
$speeds = ['deepseek-r1:32b' => 8, 'qwen2.5:14b' => 25, 'qwen2.5-coder:7b' => 40, 'llama3.1:8b' => 45, 'mistral:7b' => 45, 'codellama:13b' => 20, 'phi3:14b' => 25];
$tps = $speeds[$model] ?? 20;
return round(($inputTokens / 1000 * 0.5) + ($outputTokens / $tps), 1);
}
function shouldUseGPULocal($intent, $complexity, $maxLatency = 15) {
$model = selectBestGPUModel($intent, $complexity, 50);
$estTime = estimateGPUInferenceTime($model, 2000, 1000);
return $estTime <= $maxLatency;
}
function advBuildGPURotation($intent, $complexity) {
$primary = selectBestGPUModel($intent, $complexity, 50);
$cloud = selectCloudFallbackOrder($intent);
return array_merge(['ollama:'.$primary], $cloud);
}
function getModelCapabilities($model) {
$caps = [
'deepseek-r1:32b' => ['reasoning','code','analysis','math','planning','multilingual'],
'qwen2.5:14b' => ['general','code','analysis','multilingual','creative'],
'qwen2.5-coder:7b' => ['code','debugging','refactoring','documentation'],
'llama3.1:8b' => ['general','conversation','creative','summarization'],
'mistral:7b' => ['general','conversation','creative','french'],
'codellama:13b' => ['code','debugging','explanation','documentation'],
'phi3:14b' => ['reasoning','math','analysis','code'],
];
return $caps[$model] ?? ['general'];
}
function checkGPUHealth() {
$ch = @curl_init('http://127.0.0.1:11434/api/tags');
if (!$ch) return ['healthy' => false, 'reason' => 'curl_init failed'];
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 3]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 200) return ['healthy' => false, 'reason' => "HTTP $code"];
$data = json_decode($resp, true);
$models = count($data['models'] ?? []);
return ['healthy' => true, 'models' => $models];
}
function getGPULoadEstimate() {
$load = @file_get_contents('/proc/loadavg');
if (!$load) return ['load' => 0, 'status' => 'unknown'];
$parts = explode(' ', $load);
$avg1 = floatval($parts[0]);
$status = $avg1 < 4 ? 'light' : ($avg1 < 8 ? 'moderate' : 'heavy');
return ['load' => $avg1, 'status' => $status];
}
function shouldOffloadToCloud($gpuLoad) {
return $gpuLoad['status'] === 'heavy';
}
function selectModelForEmbedding() {
return 'nomic-embed-text';
}
function selectModelForSummarization($length) {
return $length > 5000 ? 'qwen2.5:14b' : 'llama3.1:8b';
}
function selectModelForTranslation($sourceLang, $targetLang) {
if (in_array('arabic', [$sourceLang, $targetLang])) return 'qwen2.5:14b';
return 'mistral:7b';
}
function selectModelForCodeReview() {
return 'deepseek-r1:32b';
}
function selectModelForDiagram() {
return 'qwen2.5-coder:7b';
}
function buildModelPromptPrefix($model) {
$prefixes = [
'deepseek-r1:32b' => "Tu es un expert en raisonnement profond. Analyse étape par étape.",
'qwen2.5-coder:7b' => "Tu es un développeur senior. Code complet, documenté, testable.",
'llama3.1:8b' => "Tu es un assistant professionnel WEVAL. Réponse claire et concise.",
'qwen2.5:14b' => "Tu es un consultant expert. Analyse structurée et recommandations actionnables.",
];
return $prefixes[$model] ?? "";
}
function advLogModelSelection($model, $intent, $complexity, $reason) {
error_log("WEVIA_GPU_SELECT: model=$model intent=$intent complexity=$complexity reason=$reason");
}
function getModelTokenLimits($model) {
$limits = ['deepseek-r1:32b' => 32768, 'qwen2.5:14b' => 32768, 'qwen2.5-coder:7b' => 16384, 'llama3.1:8b' => 8192, 'mistral:7b' => 8192, 'codellama:13b' => 16384, 'phi3:14b' => 16384];
return $limits[$model] ?? 8192;
}
function calculateTokenBudget($model, $systemLen, $messageLen) {
$maxCtx = getModelTokenLimits($model);
$inputTokens = intval(($systemLen + $messageLen) / 3.5);
$remaining = $maxCtx - $inputTokens;
return max(500, min($remaining, 4000));
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE T: TOOL USE PLANNING (15 functions)
// Decide what tools/resources to use for each query
// ═══════════════════════════════════════════════════════════════════════════
function planToolUsage($msg, $intent) {
$tools = [];
if (function_exists('detectCodeInMessage') && detectCodeInMessage($msg)) $tools[] = 'code_execution';
if (function_exists('detectURLInMessage') && detectURLInMessage($msg)) $tools[] = 'web_scraper';
if (function_exists('detectVisualization') && detectVisualization($msg)) $tools[] = 'mermaid_diagram';
if (function_exists('detectFileReference') && detectFileReference($msg)) $tools[] = 'file_handler';
if (preg_match('/\b(image|photo|dessin|illustration|logo|bannière|visuel)\b/i', $msg)) $tools[] = 'image_generation';
if (preg_match('/\b(cherche|search|google|web|internet|actualité|news)\b/i', $msg)) $tools[] = 'web_search';
if (preg_match('/\b(pdf|document|rapport|présentation|pptx|docx|xlsx)\b/i', $msg)) $tools[] = 'document_gen';
if (preg_match('/\b(email|mail|campagne|newsletter|smtp|envoi)\b/i', $msg)) $tools[] = 'email_tools';
if (preg_match('/\b(base de données|sql|requête|table|postgresql|pg)\b/i', $msg)) $tools[] = 'database_query';
if (preg_match('/\b(serveur|server|ssh|systemctl|nginx|apache)\b/i', $msg)) $tools[] = 'server_admin';
return $tools;
}
function shouldUseKB($msg, $intent) {
if (preg_match('/\b(WEVAL|wevia|wevads|notre|nos|consulting|service|offre)\b/i', $msg)) return true;
if (in_array($intent, ['technical','operational','strategic'])) return true;
if (function_exists('detectSAPContext') && detectSAPContext($msg)) return true;
if (function_exists('detectEmailTechContext') && detectEmailTechContext($msg)) return true;
return mb_strlen($msg) > 50;
}
function shouldUseDarkModules($msg) {
if (preg_match('/\b(scan|audit|sécurité|vulnerability|SSL|certificat|DNS|whois)\b/i', $msg)) return 'dark-scout';
if (preg_match('/\b(scrape|extract|url|site web|page web|contenu de)\b/i', $msg)) return 'dark-scraper';
if (preg_match('/\b(compare.*IA|AI.*compare|meilleur.*modèle|benchmark.*LLM)\b/i', $msg)) return 'ia-discovery';
if (preg_match('/\b(linkedin|profil|entreprise|société)\b/i', $msg)) return 'wevia-linkedin';
if (preg_match('/\b(youtube|vidéo|tutoriel|watch)\b/i', $msg)) return 'wevia-youtube';
return null;
}
function shouldUseImageGen($msg) {
return (bool)preg_match('/\b(génère|crée|dessine|fais).*\b(image|photo|illustration|logo|bannière|affiche|infographie)\b/i', $msg);
}
function shouldUseMermaid($msg) {
return (bool)preg_match('/\b(diagramme|schéma|flowchart|sequence|graph|architecture|flux|processus|workflow|organigramme|UML)\b/i', $msg);
}
function shouldUseExec($msg) {
return (bool)preg_match('/\b(exécute|execute|lance|run|test|vérifie|check|installe|install)\b.*\b(script|commande|command|code|programme)\b/i', $msg);
}
function estimateToolLatency($tools) {
$latencies = ['code_execution' => 5, 'web_scraper' => 8, 'mermaid_diagram' => 3, 'file_handler' => 2, 'image_generation' => 20, 'web_search' => 5, 'document_gen' => 10, 'email_tools' => 3, 'database_query' => 2, 'server_admin' => 5, 'dark-scout' => 10, 'dark-scraper' => 15, 'ia-discovery' => 10];
$total = 0;
foreach ($tools as $t) $total += $latencies[$t] ?? 3;
return $total;
}
function prioritizeTools($tools, $maxLatency = 30) {
$critical = ['code_execution','database_query','server_admin'];
$nice = ['image_generation','web_search','mermaid_diagram'];
$prioritized = [];
foreach ($tools as $t) { if (in_array($t, $critical)) $prioritized[] = $t; }
foreach ($tools as $t) { if (!in_array($t, $critical)) $prioritized[] = $t; }
$budget = $maxLatency;
$selected = [];
foreach ($prioritized as $t) {
$cost = estimateToolLatency([$t]);
if ($budget >= $cost) { $selected[] = $t; $budget -= $cost; }
}
return $selected;
}
function buildToolChain($msg, $intent) {
$tools = planToolUsage($msg, $intent);
if (shouldUseKB($msg, $intent)) array_unshift($tools, 'knowledge_base');
$dark = shouldUseDarkModules($msg);
if ($dark) $tools[] = $dark;
return prioritizeTools(array_unique($tools));
}
function shouldStreamResponse($msg, $intent, $tools) {
if (in_array('image_generation', $tools)) return false;
if ($intent === 'greeting') return false;
return mb_strlen($msg) > 50;
}
function getToolDescription($tool) {
$descs = [
'knowledge_base' => 'Base de connaissances WEVAL (2490+ entrées)',
'code_execution' => 'Exécution de code sécurisée',
'web_scraper' => 'Extraction de contenu web',
'mermaid_diagram' => 'Génération de diagrammes Mermaid',
'image_generation' => 'Création d\'images via Stable Diffusion',
'web_search' => 'Recherche web en temps réel',
'dark-scout' => 'Analyse sécurité/DNS/SSL de domaines',
'dark-scraper' => 'Extraction intelligente de pages web',
'ia-discovery' => 'Comparaison et benchmark de modèles IA',
];
return $descs[$tool] ?? $tool;
}
function logToolPlan($tools, $msg) {
error_log("WEVIA_TOOL_PLAN: tools=" . implode(",", $tools) . " msg_len=" . mb_strlen($msg));
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE U: ETHICAL REASONING ENGINE (15 functions)
// Detect bias, assess harm, ensure responsible output
// ═══════════════════════════════════════════════════════════════════════════
function detectBiasRisk($msg) {
if (preg_match('/\b(tous les|all|chaque|every)\s+(hommes|femmes|arabes|africains|européens|musulmans|chrétiens|juifs|blancs|noirs)\b/i', $msg)) return 'generalization_bias';
if (preg_match('/\b(meilleur|supérieur|inférieur|pire)\s+(race|religion|genre|sexe|pays|culture)\b/i', $msg)) return 'comparative_bias';
return null;
}
function detectHarmfulIntent($msg) {
if (preg_match('/\b(pirater|hacker|crack|exploit|malware|virus|ddos|phishing)\b/i', $msg) && !preg_match('/\b(protéger|défendre|sécuriser|audit|test|formation)\b/i', $msg)) return 'potential_malicious';
if (preg_match('/\b(arme|weapon|bombe|explosif|drogue|drug)\b/i', $msg) && !preg_match('/\b(politique|loi|prévention|article|documentaire)\b/i', $msg)) return 'potential_harmful';
return null;
}
function detectPrivacyRisk($response) {
if (preg_match('/\b\d{3}[-.\s]?\d{2}[-.\s]?\d{4}\b/', $response)) return 'ssn_pattern';
if (preg_match('/\b[A-Z]{2}\d{2}[\s]?[\dA-Z]{4}[\s]?[\dA-Z]{4}[\s]?[\dA-Z]{4}[\s]?[\dA-Z]{4}[\s]?[\dA-Z]{0,4}\b/', $response)) return 'iban_pattern';
if (preg_match('/\b(?:\d{4}[-\s]?){3}\d{4}\b/', $response)) return 'credit_card_pattern';
return null;
}
function assessResponseSafety($response) {
$score = 100;
$issues = [];
$privacy = detectPrivacyRisk($response);
if ($privacy) { $score -= 30; $issues[] = $privacy; }
if (function_exists('validateNoLeakedInternals')) { $leak = validateNoLeakedInternals($response); if ($leak) { $score -= 40; $issues[] = $leak; } }
if (preg_match('/\b(password|mot de passe|mdp|pwd)\s*[:=]\s*\S+/i', $response)) { $score -= 50; $issues[] = 'password_leak'; }
return ['score' => max(0, $score), 'issues' => $issues];
}
function addEthicalGuardrail($sys, $msg) {
$bias = detectBiasRisk($msg);
$harm = detectHarmfulIntent($msg);
if ($bias) $sys .= "\n[GUARD: Évite les généralisations. Nuance ta réponse avec des données factuelles.]";
if ($harm === 'potential_malicious') $sys .= "\n[GUARD: Oriente vers la défense et la sécurisation, pas l'attaque.]";
return $sys;
}
function detectMisinformationRisk($response) {
$flags = [];
if (preg_match('/\b(prouvé scientifiquement|études montrent|100% garanti|sans aucun doute)\b/i', $response) && !preg_match('/\bsource|référence|étude de|publi/i', $response)) $flags[] = 'unsourced_strong_claim';
if (preg_match('/\b(remède miracle|guérit tout|secret que.*cache)\b/i', $response)) $flags[] = 'misinformation_pattern';
return $flags;
}
function ensureBalancedPerspective($response, $intent) {
if ($intent === 'analytical' || $intent === 'strategic') {
if (!preg_match('/\b(cependant|toutefois|néanmoins|en revanche|inconvénient|risque|limitation)\b/i', $response)) return 'missing_counterpoint';
}
return null;
}
function sanitizePersonalData($response) {
$response = preg_replace('/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/', '[EMAIL]', $response);
$response = preg_replace('/\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/', '[PHONE]', $response);
return $response;
}
function detectRegulatoryContext($msg) {
if (preg_match('/\b(RGPD|GDPR|CNIL|CNDP|loi 09-08|protection des données)\b/i', $msg)) return 'data_protection';
if (preg_match('/\b(PCI.?DSS|carte de crédit|paiement|payment)\b/i', $msg)) return 'payment_security';
if (preg_match('/\b(HIPAA|santé|médical|patient)\b/i', $msg)) return 'health_data';
if (preg_match('/\b(SOX|Sarbanes|audit financier|contrôle interne)\b/i', $msg)) return 'financial_compliance';
return null;
}
function injectRegulatoryContext($sys, $regulation) {
$injections = [
'data_protection' => "\n## RGPD/CNDP: Minimisation, consentement, droit d'accès/rectification/effacement. PIA si risque élevé.",
'payment_security' => "\n## PCI-DSS: Ne jamais stocker CVV. Tokenisation. Chiffrement AES-256. Logs d'accès.",
'health_data' => "\n## Données de santé: Hébergement certifié HDS. Chiffrement. Accès restreint. Consentement explicite.",
'financial_compliance' => "\n## SOX: Séparation des tâches. Piste d'audit. Contrôles IT. Documentation des processus.",
];
return $sys . ($injections[$regulation] ?? "");
}
function ethicalReasoningPipeline($sys, $msg, $response, $intent) {
$sys = addEthicalGuardrail($sys, $msg);
$reg = detectRegulatoryContext($msg);
if ($reg) $sys = injectRegulatoryContext($sys, $reg);
$safety = assessResponseSafety($response);
if ($safety['score'] < 60) {
$response = sanitizePersonalData($response);
if (function_exists('sanitizeForPublic')) $response = sanitizeForPublic($response);
}
return ['sys' => $sys, 'response' => $response, 'safety_score' => $safety['score']];
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE V: ANALOGICAL REASONING (12 functions)
// Transfer knowledge between domains
// ═══════════════════════════════════════════════════════════════════════════
function findAnalogy($concept, $sourceDomain, $targetDomain) {
$analogyMap = [
'database' => ['body' => 'mémoire/cerveau', 'city' => 'bibliothèque', 'computer' => 'disque dur'],
'api' => ['body' => 'système nerveux', 'city' => 'routes/autoroutes', 'restaurant' => 'serveur/menu'],
'cache' => ['body' => 'mémoire court-terme', 'city' => 'raccourcis', 'kitchen' => 'plan de travail'],
'encryption' => ['body' => 'ADN', 'city' => 'coffre-fort', 'language' => 'code secret'],
'load_balancer' => ['body' => 'cœur/circulation', 'city' => 'rond-point', 'restaurant' => 'hôtesse d\'accueil'],
'microservice' => ['body' => 'organes spécialisés', 'city' => 'quartiers spécialisés', 'army' => 'unités tactiques'],
'container' => ['body' => 'cellule', 'city' => 'appartement', 'shipping' => 'conteneur standardisé'],
'firewall' => ['body' => 'système immunitaire', 'city' => 'douane', 'castle' => 'remparts'],
'backup' => ['body' => 'jumeau', 'city' => 'plan d\'évacuation', 'finance' => 'assurance'],
'pipeline' => ['body' => 'chaîne alimentaire', 'factory' => 'chaîne de montage', 'river' => 'cascade'],
];
return $analogyMap[$concept][$targetDomain] ?? null;
}
function suggestAnalogy($msg) {
$concepts = ['database','api','cache','encryption','load_balancer','microservice','container','firewall','backup','pipeline'];
foreach ($concepts as $c) {
if (preg_match('/\b' . str_replace('_', '.', $c) . '\b/i', $msg)) {
$domains = ['body','city','restaurant','kitchen'];
$analogies = [];
foreach ($domains as $d) { $a = findAnalogy($c, 'tech', $d); if ($a) $analogies[$d] = $a; }
return ['concept' => $c, 'analogies' => $analogies];
}
}
return null;
}
function buildAnalogyPrompt($concept, $targetDomain) {
$analogy = findAnalogy($concept, 'tech', $targetDomain);
return $analogy ? "\n💡 Analogie: Un $concept est comme $analogy (dans le domaine du $targetDomain)." : "";
}
function detectExpertiseGap($msg, $history) {
if (function_exists('detectExpertiseLevel')) {
$level = detectExpertiseLevel($msg);
if ($level === 'beginner') return true;
}
return (bool)preg_match('/\b(c.est quoi|explain|vulgarise|simplifie|pour un débutant|en termes simples)\b/i', $msg);
}
function buildBridgeExplanation($techConcept) {
$bridges = [
'kubernetes' => "Imagine un chef d'orchestre qui dirige des musiciens (containers). Chaque musicien joue sa partition, et le chef s'assure que la symphonie sonne bien.",
'docker' => "C'est comme une valise standardisée: peu importe l'aéroport (serveur), ta valise (container) fonctionne partout.",
'microservice' => "Au lieu d'un seul super-héros, c'est une équipe de spécialistes. Chacun fait UNE chose parfaitement.",
'CI/CD' => "C'est la différence entre livrer un colis à la main vs avoir un tapis roulant automatique de l'usine au client.",
'API' => "C'est le menu du restaurant: tu choisis ce que tu veux (requête), le serveur (API) te l'apporte.",
'DNS' => "C'est l'annuaire téléphonique d'Internet: tu cherches un nom, il te donne le numéro.",
'SSL' => "C'est l'enveloppe cachetée de ta lettre: même si quelqu'un intercepte, il ne peut pas lire.",
'webhook' => "Au lieu d'appeler toutes les 5 minutes pour demander 'c'est prêt?', on te rappelle quand c'est prêt.",
];
return $bridges[$techConcept] ?? null;
}
function detectNeedForAnalogy($msg, $intent) {
return detectExpertiseGap($msg, []) && in_array($intent, ['technical','operational','analytical']);
}
function injectAnalogyIfNeeded($sys, $msg, $intent) {
if (!detectNeedForAnalogy($msg, $intent)) return $sys;
$analogy = suggestAnalogy($msg);
if ($analogy) {
$best = reset($analogy['analogies']);
$sys .= "\n[ANALOGIE: Utilise cette analogie pour expliquer: {$analogy['concept']}$best]";
}
return $sys;
}
function transferPatternBetweenDomains($pattern, $source, $target) {
$transfers = [
'retry_with_backoff' => ['code' => 'try/catch avec délai exponentiel', 'business' => 'relancer un client avec espacement croissant', 'health' => 'doses progressives d\'un traitement'],
'circuit_breaker' => ['code' => 'couper l\'appel si trop d\'erreurs', 'business' => 'stopper un partenariat qui échoue', 'health' => 'arrêter un traitement qui nuit'],
'cache_invalidation' => ['code' => 'rafraîchir le cache', 'business' => 'mettre à jour le catalogue', 'health' => 'revoir un diagnostic périmé'],
];
return $transfers[$pattern][$target] ?? null;
}
function buildCrossReferencePrompt($msg) {
$refs = [];
if (preg_match('/\b(comme|similar|pareil|équivalent|analogue)\b/i', $msg)) $refs[] = "Cherche des parallèles dans d'autres domaines.";
if (preg_match('/\b(pattern|modèle|méthode|approche)\b/i', $msg)) $refs[] = "Ce pattern existe peut-être dans d'autres contextes.";
return implode(" ", $refs);
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE W: DEBATE & ARGUMENTATION ENGINE (12 functions)
// Steel-man arguments, counter-arguments, structured reasoning
// ═══════════════════════════════════════════════════════════════════════════
function detectDebateContext($msg) {
return (bool)preg_match('/\b(pour ou contre|avantage.*inconvénient|argument|débat|controverse|opinion|avis|position|point de vue|dilemme)\b/i', $msg);
}
function buildSteelManArgument($position) {
return "## Meilleur argument POUR: $position\n[Présente la version la plus forte et charitable de cette position]\n\n## Meilleur argument CONTRE:\n[Présente la critique la plus forte et honnête]\n\n## Synthèse nuancée:\n[Position équilibrée avec conditions et contexte]";
}
function identifyLogicalFallacies($text) {
$fallacies = [];
if (preg_match('/\b(tout le monde|everyone|everybody)\s+(sait|pense|dit)\b/i', $text)) $fallacies[] = ['name' => 'Argumentum ad populum', 'desc' => 'Appel à la majorité'];
if (preg_match('/\b(si.*alors.*si.*alors.*donc)\b/i', $text)) $fallacies[] = ['name' => 'Pente glissante', 'desc' => 'Enchaînement causal non justifié'];
if (preg_match('/\b(ou bien.*ou bien)\b/i', $text) && !preg_match('/\b(aussi|également|en plus)\b/i', $text)) $fallacies[] = ['name' => 'Faux dilemme', 'desc' => 'Choix binaire artificiel'];
if (preg_match('/\b(a dit|selon|d\'après)\b.*\b(donc|par conséquent|c\'est vrai)\b/i', $text)) $fallacies[] = ['name' => 'Argument d\'autorité', 'desc' => 'La source ne garantit pas la véracité'];
return $fallacies;
}
function buildCounterArgument($claim) {
return "**Contre-argument à \"$claim\":**\n1. Prémisse contestable: [identifier l'hypothèse faible]\n2. Contre-exemple: [cas qui invalide la généralisation]\n3. Conséquence ignorée: [effet secondaire non mentionné]\n4. Alternative: [autre explication ou solution]";
}
function assessArgumentStrength($argument) {
$score = 5;
if (preg_match('/\b(données|étude|statistique|chiffre|mesure)\b/i', $argument)) $score += 2;
if (preg_match('/\b(exemple|cas concret|en pratique)\b/i', $argument)) $score += 1;
if (preg_match('/\b(mais|cependant|toutefois|limitation)\b/i', $argument)) $score += 1;
if (preg_match('/\b(toujours|jamais|impossible|garanti)\b/i', $argument)) $score -= 2;
if (preg_match('/\b(je pense|je crois|il me semble)\b/i', $argument)) $score -= 1;
return min(10, max(1, $score));
}
function structureDebate($topic) {
return "## DÉBAT: $topic\n\n### Thèse (POUR)\n**Argument 1:** [le plus fort]\n**Argument 2:** [données/evidence]\n**Argument 3:** [conséquences positives]\n\n### Antithèse (CONTRE)\n**Argument 1:** [le plus fort]\n**Argument 2:** [contre-exemples]\n**Argument 3:** [risques/effets pervers]\n\n### Synthèse\n**Position nuancée:** [conditions, contexte, compromis]";
}
function detectCognitivebiasInResponse($response) {
$biases = [];
if (preg_match('/\bévident|obviously|bien sûr\b/i', $response)) $biases[] = 'anchoring';
if (preg_match('/\bnous avons toujours|tradition|habitude\b/i', $response)) $biases[] = 'status_quo';
if (preg_match('/\brécemment|dernièrement|cette semaine\b/i', $response) && preg_match('/\bdonc|par conséquent\b/i', $response)) $biases[] = 'recency_bias';
return $biases;
}
function injectDebateMode($sys, $msg) {
if (!detectDebateContext($msg)) return $sys;
return $sys . "\n## MODE DÉBAT\nPrésente systématiquement: 1) Le meilleur argument POUR 2) Le meilleur argument CONTRE 3) Les données factuelles 4) Une synthèse nuancée. Évite les biais cognitifs.";
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE X: CREATIVE SYNTHESIS (12 functions)
// Combine disparate ideas into novel solutions
// ═══════════════════════════════════════════════════════════════════════════
function detectCreativeSynthesisNeed($msg) {
return (bool)preg_match('/\b(innov|créati|original|nouveau|idée|brainstorm|concept|invente|imagine|et si|what if)\b/i', $msg);
}
function generateCrossPollinationPrompt($domain1, $domain2) {
return "Combine les principes de $domain1 et $domain2 pour créer une solution innovante:\n- Qu'est-ce que $domain1 fait bien que $domain2 ignore ?\n- Quel pattern de $domain2 pourrait révolutionner $domain1 ?\n- Quelle fusion créerait le plus de valeur ?";
}
function applySCAMPER($concept) {
return "## SCAMPER — $concept\n**S**ubstituer: Que remplacer ?\n**C**ombiner: Avec quoi fusionner ?\n**A**dapter: Que modifier/ajuster ?\n**M**odifier: Que magnifier/minimiser ?\n**P**enser autrement: Autre usage ?\n**É**liminer: Que supprimer ?\n**R**éorganiser: Inverser le processus ?";
}
function applyRandomStimulus($topic) {
$stimuli = ['nature', 'musique', 'sport', 'cuisine', 'architecture', 'jeu', 'voyage', 'art', 'science-fiction', 'enfance'];
$chosen = $stimuli[array_rand($stimuli)];
return "## STIMULUS ALÉATOIRE\nConcepte: $topic\nStimulus: $chosen\n→ Et si $topic fonctionnait comme dans le monde de $chosen ?";
}
function buildBisociationMatrix($conceptA, $conceptB) {
return "## BISOCIATION: $conceptA × $conceptB\nPrincipes de $conceptA: [lister 3]\nPrincipes de $conceptB: [lister 3]\nCroisements:\n- A1 × B1 → ?\n- A1 × B2 → ?\n- A2 × B1 → ?\n- A2 × B3 → ?\nIdée la plus prometteuse: [développer]";
}
function applyReverseBrainstorm($goal) {
return "## BRAINSTORM INVERSÉ\nObjectif: $goal\n\n**Comment ÉCHOUER à coup sûr ?**\n1. [Anti-solution 1]\n2. [Anti-solution 2]\n3. [Anti-solution 3]\n\n**Inverser chaque anti-solution:**\n1. → [Solution positive]\n2. → [Solution positive]\n3. → [Solution positive]";
}
function detectDomainForCreative($msg) {
if (preg_match('/\b(site|web|app|interface|UX|design)\b/i', $msg)) return 'digital';
if (preg_match('/\b(business|entreprise|marché|client|vente)\b/i', $msg)) return 'business';
if (preg_match('/\b(produit|service|offre|solution)\b/i', $msg)) return 'product';
if (preg_match('/\b(marketing|comm|brand|marque|campagne)\b/i', $msg)) return 'marketing';
return 'general';
}
function generateCreativeConstraints($domain) {
$constraints = [
'digital' => ['Budget zéro', 'Mobile-only', 'Offline-first', '1 page max', 'Zero-click'],
'business' => ['Sans employé', 'En 24h', 'Budget 100€', 'Sans bureau', 'Sans tech'],
'product' => ['Un seul bouton', 'Gratuit', 'En papier', 'Pour enfants', 'Invisible'],
'marketing' => ['Sans pub', 'Un seul mot', 'Sans internet', 'En 6 secondes', 'Bouche-à-oreille'],
];
$c = $constraints[$domain] ?? ['Sans budget', 'En 1 heure', 'Seul'];
return "Contraintes créatives: " . implode(" | ", array_rand(array_flip($c), min(3, count($c))));
}
function advInjectCreativeMode($sys, $msg) {
if (!detectCreativeSynthesisNeed($msg)) return $sys;
$domain = detectDomainForCreative($msg);
return $sys . "\n## MODE CRÉATIF\nPense latéralement. 3 idées minimum dont 1 provocante. Cross-pollination entre domaines. Utilise SCAMPER ou brainstorm inversé si pertinent. Domaine: $domain.";
}
function buildIdeationPrompt($topic, $numIdeas = 5) {
return "Génère $numIdeas idées pour '$topic':\n- 1 idée conservatrice (safe bet)\n- 1 idée ambitieuse (moonshot)\n- 1 idée provocante (challenge le statu quo)\n- 1 idée combinatoire (fusionne 2 domaines)\n- 1 idée inverse (fait le contraire de l'évident)";
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE Y: KNOWLEDGE GRAPH REASONING (12 functions)
// Entity relationships, inference chains
// ═══════════════════════════════════════════════════════════════════════════
function extractEntitiesFromMessage($msg) {
$entities = [];
if (preg_match_all('/\b[A-Z][a-zA-Z]+(?:\s+[A-Z][a-zA-Z]+)*\b/', $msg, $m)) $entities['proper_nouns'] = array_unique($m[0]);
if (preg_match_all('/\b(?:S\d{2,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/', $msg, $m)) $entities['servers'] = $m[0];
if (preg_match_all('/\b[\w\-]+\.(?:php|py|js|ts|sh|sql|json|yaml|md|html|css)\b/i', $msg, $m)) $entities['files'] = $m[0];
if (preg_match_all('/\b(?:PostgreSQL|MySQL|Redis|nginx|Apache|Docker|Kubernetes|Ollama|PMTA)\b/i', $msg, $m)) $entities['technologies'] = array_unique($m[0]);
if (preg_match_all('/\b(?:WEVAL|WEVIA|WEVADS|Arsenal|Sentinel|Brain)\b/i', $msg, $m)) $entities['systems'] = array_unique($m[0]);
return $entities;
}
function buildRelationships($entities) {
$rels = [];
if (!empty($entities['servers']) && !empty($entities['technologies'])) {
foreach ($entities['servers'] as $s) {
foreach ($entities['technologies'] as $t) { $rels[] = "$s → runs → $t"; }
}
}
if (!empty($entities['files']) && !empty($entities['systems'])) {
foreach ($entities['files'] as $f) {
foreach ($entities['systems'] as $s) { $rels[] = "$f → belongs_to → $s"; }
}
}
return $rels;
}
function getWEVALKnowledgeGraph() {
return [
'S88' => ['role' => 'AI Primary', 'runs' => ['Ollama','nginx','PHP-FPM','PostgreSQL'], 'hosts' => ['weval-consulting.com','WEVIA']],
'S89' => ['role' => 'Email Engine', 'runs' => ['PMTA','Apache','PostgreSQL','Redis'], 'hosts' => ['WEVADS','Arsenal','Sentinel']],
'S151' => ['role' => 'Tracking + DR', 'runs' => ['nginx','PHP'], 'hosts' => ['tracking','backup']],
'WEVIA' => ['type' => 'AI System', 'components' => ['chatbot','widget','think-api','dark-modules','KB']],
'WEVADS' => ['type' => 'Email Platform', 'components' => ['ADX','Arsenal','Brain','PMTA']],
];
}
function inferFromGraph($entity, $question) {
$graph = getWEVALKnowledgeGraph();
if (isset($graph[$entity])) return $graph[$entity];
foreach ($graph as $k => $v) {
if (isset($v['components']) && in_array($entity, $v['components'])) return ['parent' => $k, 'details' => $v];
if (isset($v['runs']) && in_array($entity, $v['runs'])) return ['server' => $k, 'role' => $v['role']];
}
return null;
}
function buildContextFromEntities($entities) {
$context = [];
foreach ($entities as $type => $items) {
foreach ($items as $item) {
$info = inferFromGraph($item, '');
if ($info) $context[] = "$item: " . json_encode($info, JSON_UNESCAPED_UNICODE);
}
}
return implode("\n", array_slice($context, 0, 5));
}
function detectEntityAmbiguity($entity) {
$ambiguous = ['Brain' => ['WEVADS Brain Engine','cognitive-brain.php'], 'Arsenal' => ['WEVADS Arsenal admin','Arsenal dashboard'], 'API' => ['chatbot API','Sentinel API','WEVADS API']];
return $ambiguous[$entity] ?? null;
}
function resolveEntityAmbiguity($entity, $msg) {
$options = detectEntityAmbiguity($entity);
if (!$options) return $entity;
if (preg_match('/\b(wevads|email|envoi|campagne)\b/i', $msg)) return $options[0];
if (preg_match('/\b(wevia|chatbot|cognitive|IA)\b/i', $msg)) return $options[1] ?? $options[0];
return $options[0];
}
function buildMermaidFromEntities($entities, $relationships) {
$mermaid = "graph TB\n";
foreach ($entities as $type => $items) {
foreach ($items as $item) {
$safe = preg_replace('/[^a-zA-Z0-9]/', '_', $item);
$mermaid .= " {$safe}[\"$item\"]\n";
}
}
foreach ($relationships as $rel) {
if (preg_match('/(.+) → (.+) → (.+)/', $rel, $m)) {
$from = preg_replace('/[^a-zA-Z0-9]/', '_', trim($m[1]));
$to = preg_replace('/[^a-zA-Z0-9]/', '_', trim($m[3]));
$label = trim($m[2]);
$mermaid .= " {$from} -->|{$label}| {$to}\n";
}
}
return $mermaid;
}
function enrichWithKnowledgeGraph($sys, $msg) {
$entities = extractEntitiesFromMessage($msg);
if (empty($entities)) return $sys;
$context = buildContextFromEntities($entities);
if ($context) $sys .= "\n## ENTITÉS DÉTECTÉES\n" . mb_substr($context, 0, 500);
return $sys;
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE Z: BAYESIAN REASONING (10 functions)
// Update beliefs based on evidence
// ═══════════════════════════════════════════════════════════════════════════
function bayesianUpdate($prior, $likelihood, $evidence) {
if ($evidence <= 0) return $prior;
return ($likelihood * $prior) / $evidence;
}
function estimatePriorProbability($hypothesis, $context) {
$priors = [
'server_down' => 0.05, 'config_error' => 0.3, 'code_bug' => 0.4, 'network_issue' => 0.15, 'resource_exhaustion' => 0.1,
'permission_error' => 0.2, 'dependency_issue' => 0.15, 'version_mismatch' => 0.1, 'data_corruption' => 0.05,
];
return $priors[$hypothesis] ?? 0.2;
}
function rankHypotheses($symptoms, $hypotheses) {
$ranked = [];
foreach ($hypotheses as $h) {
$score = estimatePriorProbability($h, '');
foreach ($symptoms as $s) {
if ($h === 'config_error' && preg_match('/\b(403|permission|denied|config|conf)\b/i', $s)) $score *= 2;
if ($h === 'code_bug' && preg_match('/\b(error|exception|fatal|null|undefined)\b/i', $s)) $score *= 2;
if ($h === 'network_issue' && preg_match('/\b(timeout|connection|refused|unreachable)\b/i', $s)) $score *= 2;
if ($h === 'resource_exhaustion' && preg_match('/\b(memory|disk|cpu|full|oom)\b/i', $s)) $score *= 2;
}
$ranked[$h] = min(0.95, $score);
}
arsort($ranked);
return $ranked;
}
function buildDiagnosticTree($symptom) {
return "## ARBRE DIAGNOSTIQUE: $symptom\nHypothèses (probabilité a priori):\n" .
"H1: Erreur de configuration (30%)\n→ Vérifier: logs, config files, permissions\n" .
"H2: Bug dans le code (40%)\n→ Vérifier: stack trace, derniers commits, tests\n" .
"H3: Problème réseau (15%)\n→ Vérifier: ping, ports, firewall, DNS\n" .
"H4: Ressources épuisées (10%)\n→ Vérifier: CPU, RAM, disk, file descriptors\n" .
"H5: Serveur HS (5%)\n→ Vérifier: SSH, systemctl, health check\n" .
"\nRègle: Tester l'hypothèse la plus probable d'abord.";
}
function updateAfterEvidence($hypotheses, $evidence, $result) {
foreach ($hypotheses as $h => &$prob) {
if ($result === 'confirmed' && $h === $evidence) $prob = min(0.95, $prob * 3);
elseif ($result === 'eliminated' && $h === $evidence) $prob = max(0.01, $prob * 0.1);
}
$total = array_sum($hypotheses);
if ($total > 0) foreach ($hypotheses as &$p) $p = round($p / $total, 3);
return $hypotheses;
}
function buildEvidenceCollectionPlan($hypotheses) {
$plan = [];
foreach ($hypotheses as $h => $prob) {
$tests = [];
if ($h === 'config_error') $tests = ['Vérifier nginx -t', 'php -l', 'diff avec backup'];
elseif ($h === 'code_bug') $tests = ['tail error.log', 'git diff HEAD~1', 'phpunit'];
elseif ($h === 'network_issue') $tests = ['ping', 'ss -tlnp', 'curl -v localhost'];
elseif ($h === 'resource_exhaustion') $tests = ['df -h', 'free -m', 'top -bn1'];
$plan[] = ['hypothesis' => $h, 'probability' => $prob, 'tests' => $tests];
}
usort($plan, fn($a, $b) => $b['probability'] <=> $a['probability']);
return $plan;
}
function injectBayesianDiagnostic($sys, $msg) {
if (!function_exists('detectDiagnostic') || !detectDiagnostic($msg)) return $sys;
$symptoms = preg_split('/[.!?]+/', $msg);
$hypotheses = rankHypotheses($symptoms, ['config_error','code_bug','network_issue','resource_exhaustion','server_down','permission_error']);
$top3 = array_slice($hypotheses, 0, 3, true);
$diag = "\n## DIAGNOSTIC BAYÉSIEN";
foreach ($top3 as $h => $p) $diag .= "\n- $h: " . round($p * 100) . "%";
$diag .= "\nCommence par l'hypothèse la plus probable.";
return $sys . $diag;
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE AA: MULTI-MODAL REASONING (10 functions)
// Handle different input/output types
// ═══════════════════════════════════════════════════════════════════════════
function detectModalityRequest($msg) {
$modalities = [];
if (preg_match('/\b(image|photo|screenshot|capture|visuel|graphique)\b/i', $msg)) $modalities[] = 'image';
if (preg_match('/\b(diagramme|schéma|flowchart|mermaid|UML|architecture)\b/i', $msg)) $modalities[] = 'diagram';
if (preg_match('/\b(code|script|programme|fonction|classe|API)\b/i', $msg)) $modalities[] = 'code';
if (preg_match('/\b(tableau|table|excel|csv|données|stats)\b/i', $msg)) $modalities[] = 'data';
if (preg_match('/\b(document|PDF|rapport|présentation|PPTX|DOCX)\b/i', $msg)) $modalities[] = 'document';
if (preg_match('/\b(audio|voix|podcast|transcription)\b/i', $msg)) $modalities[] = 'audio';
if (empty($modalities)) $modalities[] = 'text';
return $modalities;
}
function selectOutputModality($modalities, $intent) {
if (in_array('diagram', $modalities)) return 'mermaid';
if (in_array('image', $modalities)) return 'image_gen';
if (in_array('code', $modalities)) return 'code_block';
if (in_array('data', $modalities)) return 'table';
if (in_array('document', $modalities)) return 'document';
if ($intent === 'analytical') return 'structured_text';
return 'prose';
}
function buildMultiModalResponse($modalities, $content) {
$response = [];
foreach ($modalities as $m) {
switch ($m) {
case 'code': $response[] = "```\n{$content['code']}\n```"; break;
case 'diagram': $response[] = "```mermaid\n{$content['diagram']}\n```"; break;
case 'data': $response[] = $content['table'] ?? ''; break;
default: $response[] = $content['text'] ?? '';
}
}
return implode("\n\n", array_filter($response));
}
function shouldGenerateImage($msg) {
return (bool)preg_match('/\b(génère|crée|dessine|fais|make|create|draw|generate)\b.*\b(image|photo|illustration|logo|bannière|visuel|infographie)\b/i', $msg);
}
function shouldGenerateDiagram($msg) {
return (bool)preg_match('/\b(diagramme|schéma|flowchart|architecture|flux|processus|workflow|UML|ERD|sequence)\b/i', $msg);
}
function suggestOutputEnrichments($response, $intent) {
$suggestions = [];
if ($intent === 'technical' && !preg_match('/```/', $response)) $suggestions[] = 'Un bloc de code aiderait';
if ($intent === 'analytical' && !preg_match('/\|.*\|.*\|/', $response)) $suggestions[] = 'Un tableau comparatif serait plus clair';
if (preg_match('/\b(processus|étape|workflow|flux)\b/i', $response) && !preg_match('/mermaid/i', $response)) $suggestions[] = 'Un diagramme Mermaid illustrerait le processus';
return $suggestions;
}
function detectInputModality($msg) {
if (preg_match('/\b(image|photo|screenshot)\b/i', $msg) && preg_match('/\b(analyse|décris|qu.est-ce|identify)\b/i', $msg)) return 'image_analysis';
if (preg_match('/\b(fichier|file|pdf|doc|excel)\b/i', $msg)) return 'file_input';
if (preg_match('/\b(url|lien|site|page)\b/i', $msg)) return 'url_input';
return 'text_input';
}
function estimateResponseModality($msg, $intent) {
$modalities = detectModalityRequest($msg);
return [
'input' => detectInputModality($msg),
'output' => selectOutputModality($modalities, $intent),
'enrichments' => $modalities,
];
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE AB: CONVERSATION FLOW INTELLIGENCE (15 functions)
// Manage multi-turn conversations, context, follow-ups
// ═══════════════════════════════════════════════════════════════════════════
function detectConversationIntent($msg, $history) {
if (function_exists('detectFollowUp') && detectFollowUp($msg)) return 'follow_up';
if (function_exists('detectClarification') && detectClarification($msg)) return 'clarification';
if (function_exists('detectGreeting') && detectGreeting($msg)) return 'greeting';
if (function_exists('detectFarewell') && detectFarewell($msg)) return 'farewell';
if (function_exists('detectGratitude') && detectGratitude($msg)) return 'gratitude';
if (function_exists('detectFrustration') && detectFrustration($msg)) return 'frustration';
if (function_exists('detectCompliment') && detectCompliment($msg)) return 'compliment';
return 'new_topic';
}
function buildConversationState($history) {
$state = ['turns' => count($history), 'topics' => [], 'mood' => 'neutral', 'resolved' => false];
foreach ($history as $h) {
$c = $h['content'] ?? '';
if ($h['role'] === 'user' && mb_strlen($c) > 10) {
$state['topics'][] = mb_substr($c, 0, 50);
if (function_exists('detectSentiment')) {
$s = detectSentiment($c);
if ($s !== 'neutral') $state['mood'] = $s;
}
}
}
if (function_exists('detectGratitude') && !empty($history)) {
$lastMsg = end($history)['content'] ?? '';
if (detectGratitude($lastMsg)) $state['resolved'] = true;
}
return $state;
}
function suggestConversationAction($state, $intent) {
if ($intent === 'frustration') return 'acknowledge_and_solve';
if ($intent === 'clarification') return 'refine_previous';
if ($intent === 'follow_up') return 'continue_topic';
if ($intent === 'gratitude') return 'close_gracefully';
if ($intent === 'farewell') return 'farewell_response';
if ($state['turns'] > 10) return 'summarize_and_focus';
return 'respond_normally';
}
function buildFollowUpPrompt($history) {
if (count($history) < 2) return "";
$lastAssistant = '';
for ($i = count($history) - 1; $i >= 0; $i--) {
if ($history[$i]['role'] === 'assistant') { $lastAssistant = $history[$i]['content'] ?? ''; break; }
}
if (!$lastAssistant) return "";
return "\n[CONTEXTE PRÉCÉDENT: " . mb_substr($lastAssistant, 0, 200) . "...]";
}
function detectTopicShift($history, $msg) {
if (count($history) < 2) return false;
$lastTopic = '';
for ($i = count($history) - 1; $i >= 0; $i--) {
if ($history[$i]['role'] === 'user') { $lastTopic = $history[$i]['content'] ?? ''; break; }
}
if (!$lastTopic) return false;
$prevWords = array_filter(explode(' ', mb_strtolower($lastTopic)), fn($w) => mb_strlen($w) > 4);
$currWords = array_filter(explode(' ', mb_strtolower($msg)), fn($w) => mb_strlen($w) > 4);
$overlap = count(array_intersect($prevWords, $currWords));
return $overlap < 2 && mb_strlen($msg) > 20;
}
function buildTopicTransition($oldTopic, $newTopic) {
return "[TRANSITION: Le sujet change de '$oldTopic' vers '$newTopic'. Réinitialiser le contexte.]";
}
function calculateConversationDepth($history) {
$turns = count($history);
$avgLen = 0;
$codePresent = false;
foreach ($history as $h) {
$c = $h['content'] ?? '';
$avgLen += mb_strlen($c);
if (preg_match('/```/', $c)) $codePresent = true;
}
$avgLen = $turns > 0 ? $avgLen / $turns : 0;
if ($turns < 3) return 'shallow';
if ($turns < 8 && $avgLen < 200) return 'moderate';
return 'deep';
}
function shouldSummarize($history) {
return count($history) > 12;
}
function advBuildConversationSummary($history) {
$topics = []; $decisions = [];
foreach ($history as $h) {
$c = $h['content'] ?? '';
if ($h['role'] === 'user' && mb_strlen($c) > 20) $topics[] = mb_substr($c, 0, 60);
if (preg_match('/\b(décidé|choisi|validé|approuvé|confirmé|OK|go)\b/i', $c)) $decisions[] = mb_substr($c, 0, 60);
}
return ['topics' => array_slice($topics, 0, 5), 'decisions' => $decisions, 'turns' => count($history)];
}
function enrichWithConversationFlow($sys, $msg, $history) {
$convIntent = detectConversationIntent($msg, $history);
$state = buildConversationState($history);
$action = suggestConversationAction($state, $convIntent);
if ($convIntent === 'follow_up') $sys .= buildFollowUpPrompt($history);
if ($convIntent === 'frustration') $sys .= "\n[FRUSTRATION DÉTECTÉE: Sois empathique, propose une solution concrète immédiate.]";
if ($action === 'summarize_and_focus') $sys .= "\n[CONVERSATION LONGUE: Résume les points clés avant de répondre.]";
return $sys;
}
// ═══════════════════════════════════════════════════════════════════════════
// MODULE MASTER: opus46AdvancedPipeline — Orchestrate all advanced modules
// ═══════════════════════════════════════════════════════════════════════════
function opus46AdvancedEnrich($sys, $msg, $intent, $history = []) {
if (mb_strlen(trim($msg)) < 10 || $intent === 'greeting') return $sys;
$budget = 1200;
// Self-correction prep
if (function_exists('selfCorrectionShouldActivate')) {
// Wired in post-processing, not enrichment
}
// Ethical guardrails (always active)
if (function_exists('addEthicalGuardrail')) {
$sys = addEthicalGuardrail($sys, $msg);
$reg = detectRegulatoryContext($msg);
if ($reg && $budget > 200) { $sys = injectRegulatoryContext($sys, $reg); $budget -= 200; }
}
// Bayesian diagnostic for troubleshooting
if (function_exists('detectDiagnostic') && detectDiagnostic($msg) && $budget > 300) {
$sys = injectBayesianDiagnostic($sys, $msg);
$budget -= 300;
}
// Analogies for beginners
if (function_exists('injectAnalogyIfNeeded') && $budget > 200) {
$sys = injectAnalogyIfNeeded($sys, $msg, $intent);
$budget -= 100;
}
// Debate mode for controversial topics
if (function_exists('injectDebateMode') && $budget > 200) {
$sys = injectDebateMode($sys, $msg);
}
// Creative mode
if (function_exists('injectCreativeMode') && $budget > 200) {
$sys = injectCreativeMode($sys, $msg);
}
// Knowledge graph enrichment
if (function_exists('enrichWithKnowledgeGraph') && $budget > 300) {
$sys = enrichWithKnowledgeGraph($sys, $msg);
}
// Conversation flow
if (function_exists('enrichWithConversationFlow') && !empty($history) && $budget > 200) {
$sys = enrichWithConversationFlow($sys, $msg, $history);
}
return $sys;
}
function opus46AdvancedPostProcess($response, $msg, $intent) {
// Self-correction pipeline
if (function_exists('selfCorrectionPipeline')) {
$response = selfCorrectionPipeline($response, $msg, $intent);
}
// Ethical safety check
if (function_exists('assessResponseSafety')) {
$safety = assessResponseSafety($response);
if ($safety['score'] < 60 && function_exists('sanitizeForPublic')) {
$response = sanitizeForPublic($response);
}
}
// Quality score logging
if (function_exists('selfCorrectionScore')) {
$score = selfCorrectionScore($response, $msg);
if ($score < 70) error_log("WEVIA_OPUS46_QUALITY: score=$score for intent=$intent");
}
return $response;
}