$data['agents']['count_unique'] ?? $data['agents_count'] ?? null, 'tools' => $data['tools_count'] ?? null, 'providers' => $data['providers_count'] ?? null, 'hcps' => $data['ethica_hcps_total'] ?? null, 'pages' => $data['pages_count'] ?? null, 'intents' => $data['intents']['count'] ?? $data['intents_count'] ?? null, 'skills' => $data['skills']['TOTAL'] ?? $data['skills_total'] ?? null, 'autonomy' => $data['autonomy_level'] ?? null, 'nonreg' => $data['nonreg_score'] ?? null, 'built_at' => $data['built_at'] ?? $data['last_update'] ?? null, ]; return $cached; } function wevia_fast_path($msg) { $m = mb_strtolower(trim($msg)); $r = null; // PRIORITY BYPASS if (preg_match('/reconcil|bilan|dirty|l99|saas|tout.*verif|ethica.*pays|ethica.*valid|ethica.*enrich|ethica.*campag|ethica.*maroc|ethica.*tunisie|ethica.*alger|medecins.*maroc|medecins.*tunisie|medecins.*alger|specialite|gap.*detail|ethica.*count|ethica.*countries|ethica.*repartition|hcp.*count/i', $m)) return null; // === WAVE-267 Route vers master-api pour intents puissants (additif pur) === // intents_pool, orchestrate_parallele, auto-wire NL → master-api.php (qui sait faire) if (preg_match('/^intents.?pool$|^pool.?intents$|combien.*capacit|nombre.*intent|liste.*intent|quelles.*capacit/i', $m) || preg_match('/^orchestrate.*(en.*parallele|parallele.*:|:)/i', $m) || preg_match('/^cable un intent |^wire.*intent|cree un intent pour|nouveau.*intent.*pour/i', $m) || preg_match('/^quelle.*heure|^donne.*heure|^date serveur/i', $m) || preg_match('/^multiagent|^multi.?agent.*(parallele|verifier|check)|^mobilise.*agent/i', $m)) { $ch = curl_init('http://127.0.0.1/api/wevia-master-api.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['message' => $msg])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 15); $resp = curl_exec($ch); curl_close($ch); if ($resp) { $j = @json_decode($resp, true); if (is_array($j) && isset($j['content'])) { return ['tool' => ($j['tool'] ?? 'master-api'), 'content' => $j['content'], 'provider' => ($j['provider'] ?? 'master-api')]; } } return null; } // === END WAVE-267 === if (preg_match('/reconcil|bilan|dirty|l99|saas|tout.*verif|ethica.*pays|ethica.*valid|ethica.*enrich|ethica.*campag|ethica.*maroc|ethica.*tunisie|ethica.*alger|medecins.*maroc|medecins.*tunisie|medecins.*alger|specialite|gap.*detail|ethica.*count|ethica.*countries|ethica.*repartition|hcp.*count/i', $m)) return null; if ($m === 'ping' || strpos($m, 'ping') === 0) { $r = trim(@shell_exec('echo S95:$(timeout 1 ping -c1 -W1 10.1.0.3 2>/dev/null | grep -oP "time=\K[0-9.]+") Groq:$(curl -so/dev/null -w%{http_code} -m2 https://api.groq.com 2>/dev/null)')); } elseif (strpos($m, 'nonreg') !== false && strpos($m, 'lance') === false && strpos($m, 'run') === false) { $d = @json_decode(@file_get_contents(__DIR__.'/nonreg-latest.json'),true); $r = $d ? 'NONREG: '.$d['pass'].'/'.$d['total'].' ('.$d['score'].'%)' : 'NONREG: run check'; } elseif ($m === 'aide' || $m === 'help') { $r = "WEVIA MASTER 421 tools. reconcile dirty l99 ports providers git ethica crons docker nonreg ping aide"; } elseif (strpos($m, 'sovereign') !== false && strpos($m, 'health') !== false) { $r = trim(@shell_exec('curl -s --max-time 5 http://127.0.0.1:4000/health')); } elseif (strpos($m, 'diagn') !== false || (strpos($m, 'health') !== false && strpos($m, 'sovereign') === false)) { $r = trim(@shell_exec('echo "LOAD: $(cat /proc/loadavg)" && echo "RAM: $(free -m | grep Mem)" && echo "DISK: $(df -h / | tail -1)" && echo "FPM: $(pgrep -c php-fpm) workers"')); } elseif (strpos($m, 'disk') !== false || strpos($m, 'espace') !== false) { $r = trim(@shell_exec('df -h / | tail -1')); } elseif (strpos($m, 'reconcil') !== false || strpos($m, 'bilan') !== false || strpos($m, 'multiagent') !== false || strpos($m, 'mobilise') !== false || (strpos($m, 'diagno') !== false && strpos($m, 'complet') !== false) || (strpos($m, 'tout') !== false && strpos($m, 'verif') !== false)) { $cmds = []; $cmds[] = 'echo "=GIT=" && cd /var/www/html && echo "Dirty:$(git status -s|wc -l)" && git status -s 2>/dev/null|head -15'; $cmds[] = 'echo "=PORTS=" && ss -tlnp 2>/dev/null|grep -oP ":\K[0-9]+"|sort -un|tr "\n" " "'; $cmds[] = 'echo "" && echo "=SOVEREIGN=" && curl -s -m3 localhost:4000/health 2>/dev/null|head -c 80'; $cmds[] = 'echo "" && echo "=NONREG=" && php8.4 /var/www/html/api/nonreg-quick.php 2>/dev/null|tail -1'; $cmds[] = 'echo "=L99=" && echo "Pages:$(ls /var/www/html/*.html|wc -l) Wiki:$(ls /opt/weval-l99/wiki/*.json 2>/dev/null|wc -l)"'; $cmds[] = 'echo "=CRONS=" && echo "Active:$(crontab -l 2>/dev/null|grep -cv ^#)"'; $r = trim(@shell_exec(implode(' && ', $cmds))); } elseif (strpos($m, 'dirty') !== false || strpos($m, 'fichiers modif') !== false) { $r = trim(@shell_exec('cd /var/www/html && echo "DIRTY FILES:" && git status --short 2>/dev/null|head -40')); } elseif (strpos($m, 'git push') !== false || strpos($m, 'commit') !== false || strpos($m, 'pousse') !== false) { $r = trim(@shell_exec('cd /var/www/html && git add -A && git commit -m "auto-wevia-master" 2>&1|tail -3 && git push 2>&1|tail -3')); } elseif (strpos($m, 'git') !== false) { $r = trim(@shell_exec('cd /var/www/html && echo "DIRTY:$(git status -s|wc -l)" && git log --oneline -3 2>/dev/null')); } elseif (strpos($m, 'l99') !== false || strpos($m, 'saas') !== false) { $r = trim(@shell_exec('echo "Pages:$(ls /var/www/html/*.html|wc -l) Wiki:$(ls /opt/weval-l99/wiki/*.json 2>/dev/null|wc -l)" && echo "Last wiki:" && ls -lt /opt/weval-l99/wiki/*.json 2>/dev/null|head -3')); } elseif (preg_match('/\bport\b/', $m)) { $r = trim(@shell_exec('ss -tlnp 2>/dev/null|grep LISTEN|head -25')); } elseif ((strpos($m, 'ethica') !== false || preg_match('/hcp|medecin|combien.*(maroc|tunis|alger)/i', $m))) { $r = trim(@shell_exec('curl -s -m5 http://127.0.0.1/api/ethica-country-api.php 2>/dev/null') ?: 'Ethica: 146K HCPs'); } elseif (strpos($m, 'provider') !== false || strpos($m, 'cascade') !== false) { $r = trim(@shell_exec('curl -s -m3 localhost:4000/health 2>/dev/null') ?: 'Sovereign: check'); } elseif (strpos($m, 'cron') !== false) { $r = trim(@shell_exec('echo "Active:$(crontab -l 2>/dev/null|grep -cv "^#")" && crontab -l 2>/dev/null|grep -v "^#"|head -10')); } elseif (strpos($m, 'docker') !== false) { $r = trim(@shell_exec('docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null|head -10')); } elseif (strpos($m, 'toolhub') !== false || (strpos($m, 'tool') !== false && strpos($m, 'count') !== false)) { $reg = @json_decode(@file_get_contents('/var/www/html/api/wevia-tool-registry.json'), true); $r = "TOOLS: " . count($reg['tools'] ?? []) . " wired in registry"; } elseif (strpos($m, 'kpi') !== false && strpos($m, 'refresh') !== false) { $r = trim(@shell_exec('curl -s http://127.0.0.1/api/em-live-kpi.php --max-time 12 > /var/www/html/api/em-kpi-cache.json 2>/dev/null && echo KPI_CACHE_REFRESHED')); } elseif (strpos($m, 's95') !== false && (strpos($m, 'clean') !== false || strpos($m, 'disk') !== false)) { $r = trim(@shell_exec('ssh -p 49222 -i /var/www/.ssh/wevads_key -o StrictHostKeyChecking=no -o ConnectTimeout=3 root@10.1.0.3 "journalctl --vacuum-size=500M 2>/dev/null; find /var/log -name *.gz -delete 2>/dev/null; find /tmp -mtime +1 -delete 2>/dev/null; df -h / | awk NR==2" 2>/dev/null')); } elseif (strpos($m, 'contrat') !== false || strpos($m, 'contract') !== false || strpos($m, 'nda') !== false) { $r = trim(@shell_exec('curl -s http://127.0.0.1/api/contract-api.php?action=stats --max-time 3 2>/dev/null')); } elseif (strpos($m, 'factur') !== false || strpos($m, 'invoice') !== false) { $r = trim(@shell_exec('curl -s http://127.0.0.1/api/invoice-api.php?action=stats --max-time 3 2>/dev/null')); } elseif (strpos($m, 'devis') !== false || strpos($m, 'quote') !== false) { $r = trim(@shell_exec('curl -s http://127.0.0.1/api/quote-api.php?action=stats --max-time 3 2>/dev/null')); } elseif (strpos($m, 'social') !== false || strpos($m, 'linkedin') !== false) { $r = trim(@shell_exec('curl -s http://127.0.0.1/api/social-media-api.php --max-time 3 2>/dev/null | head -c 500')); } elseif (strpos($m, 'deerflow') !== false || strpos($m, 'deer') !== false) { $r = trim(@shell_exec('curl -s -o /dev/null -w "DeerFlow:%{http_code}" http://127.0.0.1:3002/ --max-time 2 2>/dev/null && curl -s -o /dev/null -w " API:%{http_code}" http://127.0.0.1:8001/health --max-time 2 2>/dev/null && echo " Qdrant:$(curl -s -o /dev/null -w %{http_code} http://127.0.0.1:6333/collections --max-time 2 2>/dev/null)"')); } elseif (strpos($m, 'arena') !== false) { $r = trim(@shell_exec('php -r \'$h=@json_decode(@file_get_contents("http://127.0.0.1:4000/health"),true);if($h&&$h["status"]==="ok"){foreach($h["providers"]??[] as $p)echo "$p:UP\n";echo "Active:".$h["active"]."/".$h["total"]."\nPrimary:".($h["primary"]??"auto");}else echo "Sovereign:DOWN";\'')); } elseif (strpos($m, 'strateg') !== false || strpos($m, 'priorit') !== false) { $r = "TOP3 Q2: 1.Cloud Scaleway 5POC 240KMAD 2.Ethica 3K/mois 3.Growth 3RDV/sem Pipeline:3.5MMAD"; } elseif (preg_match('/^(bonjour|hello|hi|salut|hey)/i', $m)) { $r = "WEVIA Master IA souveraine WEVAL. 421 tools, 13 providers, 146K HCPs. Tapez: reconcile dirty l99 ports providers git ethica crons docker nonreg ping aide"; } // === AMBRE-V1 · EXTENDED TRIGGERS (additif pur, fin 100% autonomie) === elseif (strpos($m, 'truth registry') !== false || preg_match('/source.*verit|read.*truth|truth.*source|registry.*stat/i', $m)) { $raw = @file_get_contents('https://weval-consulting.com/api/opus-arch-generic.php?tool=read_truth_registry'); $d = @json_decode($raw, true); $inner = is_array($d) ? @json_decode($d['output'] ?? '', true) : null; if (is_array($inner) && !empty($inner['headlines'])) { $lines = []; foreach ($inner['headlines'] as $k=>$v) $lines[] = "$k: $v"; $r = "TRUTH REGISTRY (live, honest) · " . implode(' · ', $lines); } else { $r = "TRUTH REGISTRY: callable via /api/opus-arch-generic.php?tool=read_truth_registry (honest, zero hallucination)"; } } elseif (preg_match('/scan.*(file|fichier)|etat.*(fichier|wepredict|wtp|hub|page)|file.*info|wepredict.*state|wtp.*state/i', $m)) { // WAVE 203: honest path extraction — enrichment of existing logic $path = null; // P1: explicit absolute path in the message if (preg_match('#(/var/www/[A-Za-z0-9_./\-]+\.(html|php|json|js|md|txt))#', $m, $pm)) { $path = $pm[1]; } // P2: filename-only mention (e.g. "wevia.html", "scan_file director-chat.html") elseif (preg_match('/\b([a-zA-Z0-9][a-zA-Z0-9_\-]{1,63}\.(html|php|json))\b/i', $m, $pm)) { $fn = $pm[1]; foreach (['/var/www/html/', '/var/www/html/api/', '/var/www/html/wevia-ia/', '/var/www/weval/', '/var/www/weval/wevia-ia/'] as $dir) { if (file_exists($dir . $fn)) { $path = $dir . $fn; break; } } if (!$path) $path = '/var/www/html/' . $fn; // honest fallback (will 404 via scan_file) } // P3: preserved existing alias keywords if ($path === null) { $path = '/var/www/html/wepredict.html'; if (preg_match('/all.ia.hub|hub\.html/i', $m)) $path = '/var/www/html/all-ia-hub.html'; elseif (preg_match('/wtp|technology.platform/i', $m)) $path = '/var/www/html/weval-technology-platform.html'; elseif (preg_match('/orchestrator/i', $m)) $path = '/var/www/html/wevia-orchestrator.html'; elseif (preg_match('/master/i', $m)) $path = '/var/www/html/wevia-master.html'; } $raw = @file_get_contents("https://weval-consulting.com/api/opus-arch-generic.php?tool=scan_file&path=" . urlencode($path)); $d = @json_decode($raw, true); $inner = is_array($d) ? @json_decode($d['output'] ?? '', true) : null; if (is_array($inner) && $inner['ok']) { $r = "SCAN " . basename($inner['path']) . " · " . $inner['size_kb'] . "KB · v=" . $inner['version'] . " · mtime=" . $inner['mtime'] . " · md5=" . substr($inner['md5'], 0, 8); } else { $r = "SCAN FILE: path=$path · intent non câblé ou fichier introuvable · zéro hallucination"; } } // === END AMBRE-V1 EXTENDED TRIGGERS === // LLM FALLBACK: si aucun intent technique matché et message > 30 chars → sovereign direct if ($r === null && mb_strlen($m) > 30) { // === AMBRE-V1 · dynamic truth snapshot for LLM grounding (doctrine #4) === $tr = __ambre_truth_snapshot(); $live_facts = ''; if (!empty($tr)) { $live_facts = "\n\nFACTS LIVE (Truth Registry · source unique · override toute autre valeur):"; if ($tr['agents'] !== null) $live_facts .= "\n- Agents uniques: " . $tr['agents']; if ($tr['tools'] !== null) $live_facts .= "\n- Tools: " . $tr['tools']; if ($tr['providers'] !== null) $live_facts .= "\n- Providers IA: " . $tr['providers']; if ($tr['hcps'] !== null) $live_facts .= "\n- HCPs pharma Ethica: " . $tr['hcps']; if ($tr['pages'] !== null) $live_facts .= "\n- Pages plateforme: " . $tr['pages']; if ($tr['intents'] !== null) $live_facts .= "\n- Intents: " . $tr['intents']; if ($tr['skills'] !== null) $live_facts .= "\n- Skills: " . $tr['skills']; if ($tr['autonomy'] !== null) $live_facts .= "\n- Autonomy: " . $tr['autonomy']; if ($tr['built_at'] !== null) $live_facts .= "\n- Registry built at: " . $tr['built_at']; } $anti_hall = "\n\nDOCTRINE #4 ZERO FAKE DATA : si une information n'est pas dans FACTS LIVE ci-dessus, dis 'je ne sais pas' ou 'intent non câblé'. N'INVENTE JAMAIS un chiffre, un nom, un email, une date. Reste concis et honnête."; $ch = curl_init("http://127.0.0.1:4000/v1/chat/completions"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode([ "messages" => [ ["role"=>"system","content"=>"Tu es WEVIA, IA souveraine de WEVAL Consulting Casablanca. Tu aides Yacine avec des réponses directes, concrètes et en français. Tu connais: WEVADS (email marketing), Ethica (146K HCPs pharma), 13 providers IA gratuits, 421 tools, 223 pages." . $live_facts . $anti_hall], ["role"=>"user","content"=>$msg] ], "max_tokens" => 500, "stream" => false ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15 ]); $r2 = curl_exec($ch); curl_close($ch); $d2 = @json_decode($r2, true); $txt = $d2["choices"][0]["message"]["content"] ?? null; if ($txt) return ["provider"=>"sovereign-direct","content"=>$txt,"tool"=>"llm-fallback","model"=>$d2["model"]??"auto"]; } if ($r === null) return null; return ['provider'=>'fast-path','content'=>$r,'tool'=>'fast-path']; }