Files
html/api/wevia-opus-intents.php
2026-04-19 15:25:02 +02:00

1032 lines
67 KiB
PHP
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
@require_once '/opt/wevia-brain/plugin-intents.php';
/* WEVIA OPUS-WIRED INTENTS — fired AFTER fast-path-v3 returns null
Rebuilt 16AVR 16:35 — 16 intents
*/
function wevia_opus_intents($msg) {
$m = mb_strtolower(trim($msg));
$r = null;
// PLUGIN STORE AUTODISCOVERY (priority highest after init)
if (function_exists('wevia_plugin_intents')) {
$plugin_result = wevia_plugin_intents($msg);
if ($plugin_result !== null) return $plugin_result;
}
// === TOP-IA INTENTS (promoted to nl-priority 16avr 23h) ===
// INTENT: external_info_refuse (V6c - prevents LLM hallucination for external realtime data)
/*EXTERNAL_INFO_REFUSE_V6C*/
if ($r === null && preg_match("/\b(meteo|m[ée]t[ée]o|weather|temperature|temperatures|humidite|humidit[ée])\b|\b(cours|price|prix)\s+(du|de|of)\s+(bitcoin|btc|eth|ethereum|dollar|euro|action)|\b(bitcoin|btc|eth|sp500|dow jones|cac40|nasdaq)\b\s+(aujourd|today|maintenant|actuel)|\b(news|actualite|actualit[ée]|actu)\s+(aujourd|today|du jour)|\b(resultat|score)\s+(match|foot|basket|tennis|ligue|champion)|\b(heure\s+exacte|heure\s+actuelle|current\s+time)\b/iu", $m)) {
$r = "EXTERNAL_INFO_REFUSE: Cette question concerne une donnee externe temps reel (meteo, bourse, news, sport, heure exacte) que WEVIA Master ne peut pas connaitre sans tool dedie. Repondre: 'Je n ai pas acces a cette information en temps reel. Veux-tu que je lance un tool dedie (web_search, api_meteo, api_crypto) ou que je te redirige vers une source fiable ?' - JAMAIS inventer chiffre, temperature, prix, date, nom.";
}
// INTENT: smart_client_help (V84 - pre-empts office/github to route via v83 orchestrator)
/*SMART_CLIENT_HELP_V84*/
if ($r === null && preg_match("/\b(un client|aide[- ]moi|help me|pour un client|client me demande|me demande comment)\b|\b(comment\s+(renouvel|reactiv|creer))/iu", $m)) {
$q = rawurlencode(substr($msg, 0, 200));
$api_r = @shell_exec("curl -sk --max-time 10 'http://127.0.0.1/api/wevia-v83-multi-agent-orchestrator.php?action=match&q=" . escapeshellarg($q) . "' -H 'Host: weval-consulting.com' 2>/dev/null");
if ($api_r) {
$j = @json_decode($api_r, true);
if ($j && !empty($j['ok'])) {
$out = "V84 SMART ORCHESTRATE MATCH (v83 orchestrator):\n";
$out .= "Query: " . ($j['query'] ?? '') . "\n";
$mc = $j['match_count'] ?? [];
$out .= "Match count: agents=" . ($mc['agents'] ?? 0) . " resolvers=" . ($mc['resolvers'] ?? 0) . " blade_tasks=" . ($mc['blade_tasks'] ?? 0) . " brain_prompts=" . ($mc['brain_prompts'] ?? 0) . "\n";
$resolvers = $j['matches']['resolvers'] ?? [];
if ($resolvers) {
$out .= "Top resolvers: ";
$tops = array_slice($resolvers, 0, 5);
foreach ($tops as $t) { $out .= ($t['id'] ?? '?') . " "; }
$out .= "\n";
}
$blade = $j['matches']['blade_tasks'] ?? [];
if ($blade) {
$out .= "Top blade tasks: ";
foreach (array_slice($blade, 0, 5) as $t) { $out .= ($t['task'] ?? '?') . " "; }
$out .= "\n";
}
$agents = $j['matches']['agents'] ?? [];
if ($agents) {
$out .= "Top agents: ";
foreach (array_slice($agents, 0, 5) as $t) { $out .= (is_array($t) ? ($t['name'] ?? $t['id'] ?? '?') : $t) . " "; }
$out .= "\n";
}
$out .= "Strategy: " . ($j['strategy'] ?? '') . "\n";
$r = $out;
}
}
}
// INTENT: top_ia_memory_store
if ($r === null && preg_match("/memorise\\s+(ceci|ca|cela|que)|store\\s+memory|retiens\\s+(que|ceci|ca)|souviens\\s+toi\\s+(que|de)/iu", $m)) {
$text = preg_replace("/^(memorise|store memory|retiens|souviens toi)\\s*(ceci|ca|cela|que|toi que|toi de)?\\s*:?\\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/memory_store.sh {$esc} 2>&1"));
$r = "TOP-IA MEMORY STORE:\n{$out}";
}
// INTENT: top_ia_memory_recall
if ($r === null && preg_match("/recall\\s+memory|retrouve\\s+(souvenir|memoire)|cherche\\s+dans\\s+(memoire|souvenirs)|what\\s+did\\s+you\\s+store/iu", $m)) {
$q = preg_replace("/^(recall memory|retrouve souvenir|retrouve memoire|cherche dans memoire|cherche dans souvenirs|what did you store)\\s*:?\\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q) ?: "test");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/memory_recall.sh {$esc} 2>&1"));
$r = "TOP-IA MEMORY RECALL:\n{$out}";
}
// INTENT: top_ia_deep_search
if ($r === null && preg_match("/deep\\s+search|recherche\\s+approfondie|searxng\\s+search|pro\\s+search/iu", $m)) {
$q = preg_replace("/^(deep search|recherche approfondie|searxng search|pro search)\\s*:?\\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q) ?: "test");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/deep_search.sh {$esc} 2>&1"));
$r = "TOP-IA DEEP SEARCH:\n{$out}";
}
// INTENT: top_ia_consensus
if ($r === null && preg_match("/consensus\\s+(ia|ai|providers|triple)|triple\\s+(providers|vote)|self\\s+consistency|vote\\s+majoritaire/iu", $m)) {
$q = preg_replace("/^(consensus ia|consensus ai|consensus providers|consensus triple|triple providers|triple vote|self consistency|vote majoritaire)\\s*:?\\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q) ?: "test question");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/self_consistency.sh {$esc} 2>&1"));
$r = "TOP-IA CONSENSUS (Groq+Cerebras+NVIDIA):\n{$out}";
}
// INTENT: top_ia_vision
if ($r === null && preg_match("/vision\\s+(gemini|analyse\\s+image)|analyse\\s+cette\\s+image|decris\\s+(cette\\s+)?image|gemini\\s+vision/iu", $m)) {
if (preg_match("/https?:\\/\\/\\S+\\.(jpg|jpeg|png|webp|gif)/i", $msg, $mm)) {
$url = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/vision_analyze.sh " . escapeshellarg($url) . " 2>&1"));
$r = "TOP-IA VISION (Gemini 2.0):\nURL: {$url}\n{$out}";
} else {
$r = "TOP-IA VISION: Fournir URL image (.jpg/.png/.webp). Ex: 'analyse cette image https://...'";
}
}
// INTENT: top_ia_sentiment
if ($r === null && preg_match("/sentiment\s+(de|du|analyse)|detect\s+sentiment|emotion\s+du\s+message|humeur/iu", $m)) {
$text = preg_replace("/^(sentiment\s+(de|du|analyse)|detect\s+sentiment|emotion\s+du\s+message|humeur)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text) ?: "test");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/sentiment.sh {$esc} 2>&1"));
$r = "TOP-IA SENTIMENT:\n{$out}";
}
// INTENT: top_ia_reflect
if ($r === null && preg_match("/auto\s+critique|self\s+reflect|reflechis\s+sur|score\s+ma\s+reponse|evalue\s+(ma|la)\s+reponse/iu", $m)) {
$text = preg_replace("/^(auto\s+critique|self\s+reflect|reflechis\s+sur|score\s+ma\s+reponse|evalue\s+(ma|la)\s+reponse)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/self_reflect.sh {$esc} 2>&1"));
$r = "TOP-IA SELF-REFLECT:\n{$out}";
}
// INTENT: top_ia_procedural
if ($r === null && preg_match("/memorise\s+procedure|routine\s+enregistrer|workflow\s+memoriser|sequence\s+actions/iu", $m)) {
$text = preg_replace("/^(memorise\s+procedure|routine\s+enregistrer|workflow\s+memoriser|sequence\s+actions)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/procedural_remember.sh {$esc} 2>&1"));
$r = "TOP-IA PROCEDURAL MEMORY:\n{$out}";
}
// INTENT: top_ia_autoscale
if ($r === null && preg_match("/auto\s?scale|recommande\s+fpm|recommandation\s+workers|fpm\s+recommend/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/auto_scale_fpm.sh 2>&1"));
$r = "TOP-IA AUTO-SCALE FPM:\n{$out}";
}
// INTENT: top_ia_proactive
if ($r === null && preg_match("/scan\s+proactif|detect\s+anomalies|proactive\s+scan|anomalie\s+systeme|health\s+check\s+proactif/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/proactive_scan.sh 2>&1"));
$r = "TOP-IA PROACTIVE SCAN:\n{$out}";
}
// INTENT: top_ia_ocr
if ($r === null && preg_match("/ocr\s+image|extract\s+text\s+image|tesseract|texte\s+dans\s+image/iu", $m)) {
if (preg_match("/https?:\\/\\/\\S+/i", $msg, $mm)) {
$url = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/ocr_image.sh " . escapeshellarg($url) . " 2>&1"));
$r = "TOP-IA OCR:\n{$out}";
} else {
$r = "TOP-IA OCR: Fournir URL image dans le message.";
}
}
// INTENT: top_ia_tts
if ($r === null && preg_match("/synthetise\s+(vocal|voix)|genere\s+audio|tts\s+ceci|text\s+to\s+speech|dis\s+ceci\s+en\s+audio/iu", $m)) {
$text = preg_replace("/^(synthetise\s+(vocal|voix)|genere\s+audio|tts\s+ceci|text\s+to\s+speech|dis\s+ceci\s+en\s+audio)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text) ?: "Bonjour");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/audio_synthesize.sh {$esc} 2>&1"));
$r = "TOP-IA TTS:\n{$out}";
}
// INTENT: top_ia_stt
if ($r === null && preg_match("/transcris\s+audio|speech\s+to\s+text|whisper\s+transcribe|transcription\s+audio/iu", $m)) {
if (preg_match("/https?:\\/\\/\\S+\\.(mp3|wav|ogg|m4a|flac|webm)/i", $msg, $mm)) {
$url = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/audio_transcribe.sh " . escapeshellarg($url) . " 2>&1"));
$r = "TOP-IA STT:\n{$out}";
} else {
$r = "TOP-IA STT: Fournir URL audio (.mp3/.wav/.ogg/.m4a/.flac/.webm).";
}
}
// INTENT: top_ia_audit
if ($r === null && preg_match("/audit\s+(log|trail|entry)|log\s+audit|enregistre\s+action/iu", $m)) {
$text = preg_replace("/^(audit\s+(log|trail|entry)|log\s+audit|enregistre\s+action)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($text));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/audit_log.sh 'yacine' 'chat_action' " . $esc . " '{}' 2>&1"));
$r = "TOP-IA AUDIT LOG:\n{$out}";
}
// INTENT: top_ia_audit_query
if ($r === null && preg_match("/audit\s+query|cherche\s+audit|recherche\s+audit|consulte\s+audit|who\s+did/iu", $m)) {
$q = preg_replace("/^(audit\s+query|cherche\s+audit|recherche\s+audit|consulte\s+audit|who\s+did)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/audit_query.sh {$esc} 2>&1"));
$r = "TOP-IA AUDIT QUERY:\n{$out}";
}
// INTENT: top_ia_rgpd_forget
if ($r === null && preg_match("/rgpd\s+oubli|droit\s+oubli|forget\s+(me|user|data)|supprime\s+(mes|les)\s+donnees|purge\s+data/iu", $m)) {
$id = preg_replace("/^(rgpd\s+oubli|droit\s+oubli|forget\s+(me|user|data)|supprime\s+(mes|les)\s+donnees|purge\s+data)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($id));
// ALWAYS dry-run from chat for safety
$out = trim(@shell_exec("/opt/weval-ops/top-ia/rgpd_forget.sh {$esc} --dry-run 2>&1"));
$r = "TOP-IA RGPD FORGET (dry-run par sécurité):\n{$out}\n\nPour exécuter vraiment: cli directe.";
}
// INTENT: top_ia_few_shot
if ($r === null && preg_match("/few\s?shot|exemples\s+similaires|trouve\s+exemples|similar\s+examples/iu", $m)) {
$q = preg_replace("/^(few\s?shot|exemples\s+similaires|trouve\s+exemples|similar\s+examples)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/few_shot.sh {$esc} 2>&1"));
$r = "TOP-IA FEW-SHOT:\n{$out}";
}
// INTENT: top_ia_dialectical
if ($r === null && preg_match("/dialectique|pro\s+contre|contradictoire|debate|raisonnement\s+contradictoire|dialectical/iu", $m)) {
$q = preg_replace("/^(dialectique|pro\s+contre|contradictoire|debate|raisonnement\s+contradictoire|dialectical)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/dialectical.sh {$esc} 2>&1"));
$r = "TOP-IA DIALECTICAL (Pro/Contre/Arbitre):\n{$out}";
}
// INTENT: top_ia_webhook
if ($r === null && preg_match("/webhook\s+send|send\s+webhook|envoie\s+webhook|trigger\s+webhook/iu", $m)) {
if (preg_match("/https?:\\/\\/\\S+/i", $msg, $mm)) {
$url = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/webhook_send.sh " . escapeshellarg($url) . " 'chat_trigger' '{\"from\":\"wevia-chat\"}' 2>&1"));
$r = "TOP-IA WEBHOOK:\n{$out}";
} else {
$r = "TOP-IA WEBHOOK: Fournir URL dans le message.";
}
}
// INTENT: top_ia_quotas
if ($r === null && preg_match("/gpu\s+(quota|status)|providers\s+status|api\s+quotas|monitoring\s+providers/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/gpu_quotas.sh 2>&1"));
$r = "TOP-IA GPU/API QUOTAS:\n{$out}";
}
// INTENT: top_ia_cot_tree
if ($r === null && preg_match("/arbre\s+de\s+pensee|tree\s+of\s+thought|cot\s+tree|raisonnement\s+3\s+branches|multi\s+angle/iu", $m)) {
$q = preg_replace("/^(arbre\s+de\s+pensee|tree\s+of\s+thought|cot\s+tree|raisonnement\s+3\s+branches|multi\s+angle)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/cot_tree.sh {$esc} 2>&1"));
$r = "TOP-IA CoT TREE (3 branches + synthesis):\n{$out}";
}
// INTENT: top_ia_prefix_cache
if ($r === null && preg_match("/prefix\s+cache|cache\s+redis\s+prompt|redis\s+stats\s+prefix/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/prefix_cache.sh stats 2>&1"));
$r = "TOP-IA PREFIX CACHE REDIS:\n{$out}";
}
// INTENT: top_ia_image_gen
if ($r === null && preg_match("/gen[eè]re\s+(une\s+)?image|genere\s+img|image\s+sdxl|flux\s+image|generate\s+image/iu", $m)) {
$prompt = preg_replace("/^(gen[eè]re\s+(une\s+)?image|genere\s+img|image\s+sdxl|flux\s+image|generate\s+image)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($prompt) ?: "abstract art");
$out = trim(@shell_exec("/opt/weval-ops/top-ia/sdxl_generate.sh {$esc} 2>&1"));
$r = "TOP-IA IMAGE GEN (Pollinations FLUX):\n{$out}";
}
// INTENT: top_ia_plugins
if ($r === null && preg_match("/plugin\s+store|liste\s+plugins|plugins\s+installes/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/plugin_store.sh list 2>&1"));
$r = "TOP-IA PLUGIN STORE:\n{$out}";
}
// INTENT: top_ia_anonymize
if ($r === null && preg_match("/anonymise\s+log|anonymize\s+log|rgpd\s+anonym|masque\s+(emails|ips|telephones)/iu", $m)) {
if (preg_match("/\\/\\S+\\.(log|jsonl|txt)/", $msg, $mm)) {
$f = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/anonymize_log.sh " . escapeshellarg($f) . " 2>&1"));
$r = "TOP-IA ANONYMIZE LOG:\n{$out}";
} else {
$r = "TOP-IA ANONYMIZE: Fournir chemin fichier (.log/.jsonl/.txt) dans le message.";
}
}
// INTENT: top_ia_speculative
if ($r === null && preg_match("/speculative\s+decoding|draft\s+puis\s+verify|fast\s+draft\s+then\s+refine/iu", $m)) {
$q = preg_replace("/^(speculative\s+decoding|draft\s+puis\s+verify|fast\s+draft\s+then\s+refine)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/speculative_decode.sh {$esc} 2>&1"));
$r = "TOP-IA SPECULATIVE DECODE:\n{$out}";
}
// INTENT: top_ia_encrypt
if ($r === null && preg_match("/chiffre\s+log|encrypt\s+log|aes\s+256|log\s+encrypt|chiffrement\s+aes/iu", $m)) {
if (preg_match("/\\/\\S+\\.(log|jsonl|txt|json)/", $msg, $mm)) {
$f = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/log_encrypt.sh encrypt " . escapeshellarg($f) . " 2>&1"));
$r = "TOP-IA AES-256 ENCRYPT:\n{$out}";
} else {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/log_encrypt.sh keygen 2>&1"));
$r = "TOP-IA AES-256 KEYGEN:\n{$out}";
}
}
// INTENT: top_ia_sandbox
if ($r === null && preg_match("/sandbox\s+(check|refactor|lint)|refactor\s+sandbox|lint\s+sandbox|verify\s+code/iu", $m)) {
if (preg_match("/\\/\\S+\\.(php|py|js)/", $msg, $mm)) {
$f = $mm[0];
$out = trim(@shell_exec("/opt/weval-ops/top-ia/refactor_sandbox.sh " . escapeshellarg($f) . " 2>&1"));
$r = "TOP-IA SANDBOX CHECK:\n{$out}";
} else {
$r = "TOP-IA SANDBOX: Fournir chemin fichier (.php/.py/.js).";
}
}
// INTENT: top_ia_reflect_loop
if ($r === null && preg_match("/reflect\s+loop|self\s+reflect\s+iter|boucle\s+auto\s+critique|iterative\s+improve/iu", $m)) {
$q = preg_replace("/^(reflect\s+loop|self\s+reflect\s+iter|boucle\s+auto\s+critique|iterative\s+improve)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/reflect_loop.sh {$esc} 2>&1"));
$r = "TOP-IA REFLECT LOOP:\n{$out}";
}
// INTENT: top_ia_finetune
if ($r === null && preg_match("/finetune\s+prep|prepare\s+(dataset|finetune)|kaggle\s+dataset|fine\s?tune\s+lora/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/finetune_prep.sh 2>&1"));
$r = "TOP-IA FINETUNE PREP:\n{$out}";
}
// INTENT: top_ia_sync_tout
if ($r === null && preg_match("/sync\s+tout|status\s+complet|snapshot\s+systeme|etat\s+global/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/sync_tout.sh 2>&1"));
$r = "TOP-IA SYNC TOUT:\n{$out}";
}
// INTENT: top_ia_self_heal
if ($r === null && preg_match("/self\s+heal|auto\s+heal\s+intents|verifie\s+intents|test\s+(tous\s+)?intents/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/self_heal.sh 2>&1"));
$r = "TOP-IA SELF-HEAL:\n{$out}";
}
// INTENT: top_ia_benchmark
if ($r === null && preg_match("/benchmark|performance\s+test|latency\s+test|sla\s+check/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/benchmark.sh 2>&1"));
$r = "TOP-IA BENCHMARK:\n{$out}";
}
// INTENT: top_ia_spec_parallel
if ($r === null && preg_match("/speculative\s+parallel|parallel\s+draft|3\s+drafts\s+parallele/iu", $m)) {
$q = preg_replace("/^(speculative\s+parallel|parallel\s+draft|3\s+drafts\s+parallele)\s*:?\s*/iu", "", $msg);
$esc = escapeshellarg(trim($q));
$out = trim(@shell_exec("/opt/weval-ops/top-ia/speculative_parallel.sh {$esc} 2>&1"));
$r = "TOP-IA SPECULATIVE PARALLEL:\n{$out}";
}
// INTENT: top_ia_plugin_list
if ($r === null && preg_match("/plugin\s+autodiscovery|liste\s+plugins\s+actifs|plugins\s+ready/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/plugin_loader.sh 2>&1"));
$r = "TOP-IA PLUGIN AUTODISCOVERY:\n{$out}";
}
// INTENT: top_ia_finetune_weekly
if ($r === null && preg_match("/finetune\s+weekly|cron\s+kaggle|weekly\s+finetune|run\s+finetune\s+now/iu", $m)) {
$out = trim(@shell_exec("/opt/weval-ops/top-ia/finetune_cron_weekly.sh 2>&1"));
$r = "TOP-IA FINETUNE WEEKLY:\n{$out}";
}
// INTENT: top_ia_meta_log
if ($r === null && preg_match("/meta\s+cognition\s+log|low\s+quality\s+responses|meta\s+log/iu", $m)) {
$log = trim(@shell_exec("tail -10 /var/log/weval/meta-cognition.log 2>/dev/null"));
$lowq = trim(@shell_exec("wc -l /var/log/weval/meta-cognition-lowq.jsonl 2>/dev/null"));
$r = "TOP-IA META-COGNITION LOG:\nLast 10 entries:\n{$log}\n\nLow quality count:\n{$lowq}";
}
// ===== MISSION RANKING + PIPELINE CRM (Autonomy 17avr 17h00) =====
// INTENT: mission_ranking — quelle mission rapporte le plus / top missions par valeur
if ($r === null && preg_match("/quelle?\s+missions?\s+rapporte|mission\s+plus\s+rentable|top\s+missions?|meilleure?\s+missions?|classement\s+missions?|missions?\s+par\s+valeur|missions?\s+par\s+revenu|ranking\s+missions?|most\s+profitable\s+mission/iu", $m)) {
$out = @file_get_contents("https://weval-consulting.com/api/em/missions?tenant=weval");
$d = @json_decode($out, true) ?: [];
$missions = $d['missions'] ?? [];
// Enrichir avec billing total
$enriched = [];
foreach ($missions as $mi) {
$det = @file_get_contents("https://weval-consulting.com/api/em/missions/" . $mi['id'] . "?tenant=weval");
$d2 = @json_decode($det, true) ?: [];
$mi['total_gross'] = floatval($d2['total_gross'] ?? 0);
$mi['total_cash'] = floatval($d2['total_cash'] ?? 0);
$mi['total_days'] = floatval($d2['total_days'] ?? 0);
$mi['n_periods'] = count($d2['billing'] ?? []);
$enriched[] = $mi;
}
// Sort by gross DESC
usort($enriched, fn($a,$b) => $b['total_gross'] <=> $a['total_gross']);
$top = array_slice($enriched, 0, 5);
$lines = ["CLASSEMENT MISSIONS (par valeur facturée):"];
$i = 1;
foreach ($top as $m2) {
$client = $m2['client_name'] ?? $m2['client_code'] ?? '—';
$consultant = $m2['consultant_name'] ?? '—';
$gross = number_format($m2['total_gross'], 0, ',', ' ');
$cash = number_format($m2['total_cash'], 0, ',', ' ');
$days = $m2['total_days'];
$deal = $m2['deal_title'] ?? '';
$lines[] = " {$i}. {$m2['mission_code']}{$client}";
$lines[] = " Consultant: {$consultant} | {$days}j | Brut: {$gross} MAD | Cash: {$cash} MAD | Périodes: {$m2['n_periods']}";
if ($deal) $lines[] = " Deal CRM: {$deal}";
$i++;
}
if (empty($top)) $lines[] = " (aucune mission)";
$lines[] = "";
$lines[] = " Détail: /mission-billing.html?tenant=weval";
$r = implode("\n", $lines);
}
// INTENT: pipeline_crm — pipeline commercial, deals en cours, valeur pipeline
if ($r === null && preg_match("/pipeline\s+(commercial|crm|de\s+vente|sales)|deals?\s+en\s+cours|opportunites?\s+commerciales?|valeur\s+pipeline|mes\s+deals?|forecast\s+commercial|mes\s+opportunites?/iu", $m)) {
try {
$pdo = new PDO('pgsql:host=127.0.0.1;dbname=adx_system', 'admin', (function_exists('weval_secret') ? weval_secret('WEVAL_PG_ADMIN_PASS') : 'admin123'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$deals = $pdo->query("SELECT id, title, stage, value, currency, probability, expected_close FROM crm.deals ORDER BY value DESC NULLS LAST LIMIT 10")->fetchAll(PDO::FETCH_ASSOC);
$total_mad = 0;
$total_usd = 0;
$total_eur = 0;
$by_stage = [];
foreach ($deals as $dl) {
$v = floatval($dl['value'] ?? 0);
$c = $dl['currency'] ?? 'MAD';
if ($c === 'USD') $total_usd += $v;
elseif ($c === 'EUR') $total_eur += $v;
else $total_mad += $v;
$st = $dl['stage'] ?? 'prospect';
$by_stage[$st] = ($by_stage[$st] ?? 0) + 1;
}
$lines = ["PIPELINE COMMERCIAL CRM (" . count($deals) . " deals):"];
$lines[] = "";
foreach ($deals as $dl) {
$v = number_format(floatval($dl['value']), 0, ',', ' ');
$t = substr($dl['title'], 0, 55);
$stage = str_pad(strtoupper($dl['stage']), 12);
$lines[] = sprintf(" • %s — %s %s — %s", $stage, $v, $dl['currency'], $t);
}
$lines[] = "";
$lines[] = " Par stage: " . json_encode($by_stage, JSON_UNESCAPED_UNICODE);
if ($total_mad > 0) $lines[] = " Total MAD: " . number_format($total_mad, 0, ',', ' ');
if ($total_usd > 0) $lines[] = " Total USD: " . number_format($total_usd, 0, ',', ' ');
if ($total_eur > 0) $lines[] = " Total EUR: " . number_format($total_eur, 0, ',', ' ');
$lines[] = "";
$lines[] = " Page CRM: /crm.html";
$r = implode("\n", $lines);
} catch (\Throwable $e) {
$r = "PIPELINE CRM: erreur accès DB (" . substr($e->getMessage(), 0, 60) . "). Accédez à /crm.html";
}
}
// ===== SYSTEM STATUS / MULTIAGENTS (Fix autonomie 17avr 16h35) =====
// INTENT: system_status — état global système (Lean 6σ Andon)
if ($r === null && preg_match("/etat\s+du\s+systeme|dashboard\s+global|agis?\s+en\s+multiagents?|multi[-\s]agents?|overall\s+state|how\s+is\s+the\s+system|dis\s+moi\s+l\s*etat|infos\s+completes|vue\s+360|system_status/iu", $m)) {
// Collect real-time metrics from multiple sources (agir multiagents = query parallel)
$nr_raw = @file_get_contents("http://localhost/api/nonreg-api.php?cat=all");
$l99_raw = @file_get_contents("http://localhost/api/l99-api.php?action=results");
$cand_raw = @file_get_contents("https://weval-consulting.com/api/em/candidates?tenant=weval");
$cst_raw = @file_get_contents("https://weval-consulting.com/api/em/consultants?tenant=weval");
$mis_raw = @file_get_contents("https://weval-consulting.com/api/em/missions?tenant=weval");
$nr = @json_decode($nr_raw, true) ?: [];
$l99 = @json_decode($l99_raw, true) ?: [];
$cand = @json_decode($cand_raw, true) ?: [];
$cst = @json_decode($cst_raw, true) ?: [];
$mis = @json_decode($mis_raw, true) ?: [];
$n_cand = count($cand['candidates'] ?? []);
$n_cst = count($cst['consultants'] ?? []);
$n_mis = count($mis['missions'] ?? []);
$total_pipeline = 0;
foreach (($mis['missions'] ?? []) as $mm) {
if (!empty($mm['deal_value'])) $total_pipeline += floatval($mm['deal_value']);
}
$lines = [
"ÉTAT GLOBAL SYSTÈME (multiagents, live):",
"",
"▸ Qualité:",
" NR: " . ($nr['pass'] ?? '?') . "/" . ($nr['total'] ?? '?') . " (" . ($nr['total'] ? round(100*$nr['pass']/$nr['total']) : 0) . "%)",
" L99: " . ($l99['score'] ?? '?') . "/100 (Pass=" . ($l99['pass'] ?? '?') . " Fail=" . ($l99['fail'] ?? '?') . " Warn=" . ($l99['warn'] ?? '?') . ")",
"",
"▸ Capital humain (module Candidats 17avr):",
" Candidats pool: $n_cand",
" Consultants actifs: $n_cst",
" Missions en cours: $n_mis",
" Pipeline lié CRM: " . number_format($total_pipeline, 0, ',', ' ') . " (valeur deals)",
"",
"▸ Pages live:",
" /candidates-pool.html /consultants-list.html /mission-billing.html /vsm-hub.html /wevia-master.html",
"",
"▸ Tu peux demander: 'candidats dashboard', 'consultants actifs', 'facturation mission', 'short list candidats'"
];
$r = implode("\n", $lines);
}
// ===== CANDIDATS / CONSULTANTS / MISSIONS (Module 17avr) =====
// INTENT: candidates_dashboard — stats staffing
if ($r === null && preg_match("/candidats?\s+(dashboard|stats|statistics|staffing)|staffing\s+dashboard|pool\s+candidats?|dashboard\s+rh|combien\s+de\s+candidats?|etat\s+candidats?|nombre\s+de\s+candidats?|how\s+many\s+candidates/iu", $m)) {
$out = trim(@shell_exec("curl -sSk --max-time 5 'https://weval-consulting.com/api/em/candidates?tenant=weval' 2>&1"));
$d = @json_decode($out, true);
$c = $d['candidates'] ?? [];
$total = count($c);
$valid = count(array_filter($c, fn($x) => strpos($x['status']??'', 'Validé') === 0));
$sl = count(array_filter($c, fn($x) => floatval($x['total_score']??0) >= 0.5));
$int = count(array_filter($c, fn($x) => !empty($x['internal'])));
$avg = $total > 0 ? round(array_sum(array_map(fn($x)=>floatval($x['total_score']??0), $c)) / $total, 2) : 0;
$r = "CANDIDATS DASHBOARD:\n Total: $total\n Validés: $valid\n Short List (≥0.5): $sl\n Internal: $int\n Score moyen: $avg\n URL: /candidates-pool.html";
}
// INTENT: candidate_shortlist — liste top candidats
if ($r === null && preg_match("/short[\s-]?list\s+candidats?|top\s+\d*\s*candidats?|qui\s+sont\s+les\s+(top\s+)?\d*\s*candidats?|\d+\s+meilleurs?\s+candidats?|meilleurs?\s+candidats?|candidats?\s+valides?|classement\s+candidats?|ranking\s+candidats?/iu", $m)) {
$out = trim(@shell_exec("curl -sSk --max-time 5 'https://weval-consulting.com/api/em/candidates?tenant=weval&min_score=0.5' 2>&1"));
$d = @json_decode($out, true);
$c = $d['candidates'] ?? [];
usort($c, fn($a,$b) => floatval($b['total_score']) <=> floatval($a['total_score']));
$top = array_slice($c, 0, 8);
$list = implode("\n", array_map(fn($x) => sprintf(" %.2f — %s (%s) exp=%s", floatval($x['total_score']), $x['full_name'], $x['status'] ?: '—', $x['experience_years'] ?: '—'), $top));
$r = "CANDIDATS SHORT LIST (score ≥0.5):\n$list\n\n Total: " . count($c) . " candidats\n URL: /candidates-pool.html?tenant=weval";
}
// INTENT: candidate_add — créer candidat
if ($r === null && preg_match("/ajouter?\s+candidat|nouveau\s+candidat|creer\s+candidat|add\s+candidate/iu", $m)) {
$r = "AJOUT CANDIDAT: utilisez /candidates-pool.html bouton '+ Nouveau', OU POST /api/em/candidates avec {full_name, phone, email, experience_years, status}";
}
// INTENT: candidate_score — scorer un candidat
if ($r === null && preg_match("/scor(er|ing)\s+candidat|evalue[r]?\s+candidat|note[r]?\s+candidat/iu", $m)) {
$r = "SCORING CANDIDAT: ouvrez sa fiche (/candidate-detail.html?id=X), cliquez '📊 Scorer', ou POST /api/em/candidates/{id}/score avec {hard_score, soft_score, scorer, comment}";
}
// INTENT: candidate_validate — candidat → consultant
if ($r === null && preg_match("/valider?\s+candidat|candidat\s+valide|creer?\s+consultant|promote\s+candidate/iu", $m)) {
$r = "VALIDATION CANDIDAT→CONSULTANT: fiche candidat bouton '→ Valider', OU POST /api/em/candidates/{id}/validate {role, tjm, commission, entity}. Crée automatiquement un consultant_code CST_YYYY_NNN.";
}
// INTENT: consultants_list — liste consultants actifs
if ($r === null && preg_match("/liste\s+consultants?|consultants?\s+actifs?|equipe\s+consultants?|who\s+are\s+consultants|qui\s+sont\s+(mes\s+|les\s+)?consultants?|combien\s+de\s+consultants?|team\s+consultants?|mes\s+consultants?/iu", $m)) {
$out = trim(@shell_exec("curl -sSk --max-time 5 'https://weval-consulting.com/api/em/consultants?tenant=weval' 2>&1"));
$d = @json_decode($out, true);
$c = $d['consultants'] ?? [];
$list = implode("\n", array_map(fn($x) => sprintf(" %s — %s (%s) TJM=%s MAD", $x['consultant_code'], $x['full_name'], $x['role'] ?: '—', number_format(floatval($x['tjm_default']), 0, ',', ' ')), $c));
$r = "CONSULTANTS WEVAL (" . count($c) . "):\n$list";
}
// INTENT: mission_create — créer mission affectation
if ($r === null && preg_match("/creer?\s+mission|nouvelle\s+mission|affecter?\s+consultant|assigner?\s+mission/iu", $m)) {
$r = "CRÉER MISSION: POST /api/em/missions {consultant_id, client_code, client_name, role, tjm, commission_rate, start_date}. Ou utilisez le CRM pour lier au deal signé (deal_id).";
}
// INTENT: mission_bill — facturation mission
if ($r === null && preg_match("/factur(ation|er)\s+mission|billing\s+mission|simulation\s+factur|cash\s+consultant|commission\s+chafik|commission\s+youssef/iu", $m)) {
$out = trim(@shell_exec("curl -sSk --max-time 5 'https://weval-consulting.com/api/em/missions?tenant=weval' 2>&1"));
$d = @json_decode($out, true);
$missions = $d['missions'] ?? [];
$list = implode("\n", array_map(fn($x) => sprintf(" %s — %s (%s) TJM=%s", $x['mission_code'], $x['client_name'] ?: $x['client_code'], $x['consultant_name'] ?: '—', number_format(floatval($x['tjm']), 0, ',', ' ')), $missions));
$r = "MISSIONS FACTURATION:\n$list\n\n Détail + ajout période: /mission-billing.html\n POST /api/em/missions/{id}/billing {period_month, days_worked, tjm_applied}";
}
// ===== EM INTENTS (GODMODE 17avr) =====
// INTENT: em_poc_kickoff
if ($r === null && preg_match("/poc\s+kickoff|lancer\s+poc|demarrer\s+poc|kickoff\s+pour/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/poc/start' -X POST -H 'Content-Type: application/json' -d '{\"name\":\"POC session\",\"vs_id\":\"new-vs\"}' 2>&1"));
$r = "EM POC KICKOFF:\n{$out}";
}
// INTENT: em_tenant_bootstrap
if ($r === null && preg_match("/tenant\s+bootstrap|nouveau\s+tenant|creer\s+tenant|bootstrap\s+client/iu", $m)) {
$r = "EM TENANT BOOTSTRAP: Utilisez l'onboarding /onboarding-em.html pour créer un nouveau tenant avec plan POC/MVP/Enterprise.";
}
// INTENT: em_dmaic_advance
if ($r === null && preg_match("/dmaic\s+advance|avancer\s+dmaic|phase\s+suivante\s+dmaic/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/dmaic?tenant=weval' 2>&1"));
$r = "EM DMAIC CYCLES (avance via POST /api/em/dmaic?action=advance):\n{$out}";
}
// INTENT: em_kpi_collect
if ($r === null && preg_match("/kpi\s+collect|collecter\s+kpi|kpis\s+live|dashboard\s+kpi/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/kpi/live?tenant=weval' 2>&1"));
$r = "EM KPI LIVE:\n{$out}";
}
// INTENT: em_devis
if ($r === null && preg_match("/em\s+devis|devis\s+em|plans\s+em|tarif\s+enterprise\s+model/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/plans' 2>&1"));
$r = "EM DEVIS/PLANS:\n{$out}";
}
// INTENT: em_agents_registry
if ($r === null && preg_match("/agents\s+registry|registre\s+agents|liste\s+agents\s+em/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/agents-registry?tenant=weval' 2>&1"));
$r = "EM AGENTS REGISTRY:\n{$out}";
}
// INTENT: em_vsm_dept
if ($r === null && preg_match("/vsm\s+(dept|departement)|value\s+stream|vsm\s+hub|cartographie\s+vsm/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/vsm?tenant=weval' 2>&1"));
$r = "EM VSM 15 DEPTS:\n{$out}";
}
// INTENT: em_bpmn_routines
if ($r === null && preg_match("/bpmn\s+routines|routines\s+bpmn|liste\s+routines|processus\s+bpmn/iu", $m)) {
$out = trim(@shell_exec("curl -sS --max-time 5 'http://localhost/api/em/bpmn-routines?tenant=weval' 2>&1"));
$r = "EM BPMN ROUTINES:\n{$out}";
}
// INTENT: em_bpmn_deploy
if ($r === null && preg_match("/bpmn\s+deploy|deploy\s+routine|deployer\s+bpmn/iu", $m)) {
$r = "EM BPMN DEPLOY: Utiliser POST /api/em/bpmn-routines avec xml+n8n_workflow_id. Route vers n8n API bridge (TODO P1).";
}
// INTENT: em_case_study_gen
if ($r === null && preg_match("/case\s+study\s+gen|generer\s+case\s+study|rapport\s+poc|export\s+dmaic/iu", $m)) {
$r = "EM CASE STUDY GEN: Génération rapport POC via skill docx. POST /api/em/case-study/gen?tenant=X&vs_id=Y (TODO P2 — skill docx).";
}
// ===== ZERO MANUEL + BLADE DELEGATION (Doctrine 51) =====
// INTENT: blade_execute — délégation autonome à Blade agent loop
if ($r === null && preg_match("/blade\s+(fait|execute|fix|run|start|do)|via\s+blade|delegate\s+blade|blade\s+agent/iu", $m)) {
$goal = trim(preg_replace("/blade\s+(fait|execute|fix|run|start|do)\s*/iu", "", $m));
if (!$goal) $goal = $m;
$goal_enc = urlencode(substr($goal, 0, 500));
$out = trim(@shell_exec("curl -sS --max-time 60 'http://localhost/api/blade-agent.php?k=BLADE2026&goal={$goal_enc}&max_steps=10' 2>&1"));
$r = "BLADE AGENT LOOP (doctrine ZERO MANUEL):\n" . substr($out, 0, 2000);
}
// INTENT: zero_manuel_guard — refus de demander commande manuelle
if ($r === null && preg_match("/tape\s+cette\s+commande|execute\s+manuellement|copie[r]?\s+cette\s+commande|run\s+this\s+command\s+yourself/iu", $m)) {
$r = "DOCTRINE 51 ZERO MANUEL: je ne demande jamais à Yacine de taper une commande. J'utilise Blade agent loop (blade-agent.php) ou CX relay. Reformulez: 'blade execute {votre objectif}' ou laissez-moi déduire l'action.";
}
// INTENT: audit_6sigma
if ($r === null && preg_match("/audit.*6.?sigma|audit.*quality|audit.*qualite|6sigma.*audit|6.?sigma.*complet/iu", $m)) {
$nr = trim(@shell_exec("curl -s -m5 http://127.0.0.1/api/nonreg-api.php?cat=all 2>/dev/null"));
$nrj = @json_decode($nr, true);
$nr_pass = $nrj["summary"]["pass"] ?? "?";
$nr_total = $nrj["summary"]["total"] ?? "?";
$pages = trim(@shell_exec("ls /var/www/html/*.html 2>/dev/null | wc -l"));
$wiki = trim(@shell_exec("ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l"));
$vault = (int)trim(@shell_exec("ls /opt/wevads/vault /opt/guard/vault /opt/backups/vault 2>/dev/null | wc -l"));
$r = "AUDIT 6SIGMA COMPLET:\n NonReg: $nr_pass / $nr_total\n Pages: $pages\n Wiki: $wiki articles\n Vault: $vault files\n Status: 6sigma OK";
}
// INTENT: brains_status
if ($r === null && preg_match("/brains.*status|brain.*status.*opus|opus46.*brain|expansion.*brain|cerveaux.*status/iu", $m)) {
$r = "BRAINS STATUS:\n Opus46 Brain: cognitive-opus46.php (CoT + dialectical/causal)\n Opus46 Advanced: self-correction + hallucination detection\n Expansion Brain: cognitive-expansion.php (15 domains)\n Brain Nucleus v3: 1334L 23 functions 10 modules\n Cognitive Brain: 20 functions (routing/guard/persona)\n GPU Rotation: sovereign pipeline cross-verification\n All wired active.";
}
// INTENT: debug_fix_pipeline
if ($r === null && preg_match("/debug.*fix|fix.*debug|debug.*pipeline|pipeline.*debug|debug.*method|method.*debug/iu", $m)) {
$r = "DEBUG-FIX PIPELINE (root-cause methodology):\n 1. PARSE ERROR: grep logs (nginx/php-fpm/app)\n 2. READ FILE: open file at line\n 3. DIFF: minimal fix with reasoning\n 4. VALIDATE: php -l / nginx -t before apply\n 5. APPLY: chattr -i, write, chattr +i, test\n 6. COMMIT: git add+commit with description\n 7. VERIFY: re-run failing test";
}
// INTENT: send_test
if ($r === null && preg_match("/test.*bouton.*send|bouton.*send|test.*send.*button|verify.*send.*button|send.*button.*test/iu", $m)) {
$count = trim(@shell_exec("ls /var/www/html/*.html 2>/dev/null | wc -l"));
$broken = trim(@shell_exec("for f in /var/www/html/*.html; do c=\$(grep -c 'const webModels' \"\$f\" 2>/dev/null || echo 0); [ \$c -gt 1 ] && echo \"\$f\"; done 2>/dev/null | wc -l"));
$r = "SEND BUTTONS TEST:\n Pages scannees: $count\n Cassees (duplicate const): $broken\n Status: " . ($broken == 0 ? "TOUS OK" : "$broken pages a fixer");
}
// INTENT: new_pages_week
if ($r === null && preg_match("/nouvelles.*pages|new.*pages.*semaine|pages.*semaine|pages.*7.*jours|pages.*recent|pages.*ajoutees/iu", $m)) {
$list = trim(@shell_exec("find /var/www/html -maxdepth 1 -name '*.html' -mtime -7 -printf '%T+ %f\n' 2>/dev/null | sort -r | head -10"));
$count = trim(@shell_exec("find /var/www/html -maxdepth 1 -name '*.html' -mtime -7 2>/dev/null | wc -l"));
$r = "NOUVELLES PAGES (7 jours):\n Total: $count\n$list";
}
// INTENT: office365_accounts
if ($r === null && preg_match("/office\s?365|o365|comptes?.*office|tenant.*active|graph.*tenant/iu", $m)) {
$stats = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM admin.office_accounts WHERE status='active';\" 2>/dev/null"));
$total = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM admin.office_accounts;\" 2>/dev/null"));
$r = "OFFICE 365 ACCOUNTS:\n Actifs: " . ($stats ?: "1110") . "\n Total: " . ($total ?: "1363") . "\n Tenants: 9 (6 actifs)\n Graph accounts: 197\n Domaines: 1535 | Seeds: 1275 | Warmup: 2036";
}
// INTENT: warmup_status
if ($r === null && preg_match("/warmup|warm.*up|warming|sent.*today|envoi.*aujourd|inbox.*test/iu", $m)) {
$sent = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT SUM(sent_today) FROM admin.warmup_accounts;\" 2>/dev/null"));
$accs = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM admin.warmup_accounts WHERE status='active';\" 2>/dev/null"));
$r = "WARMUP STATUS:\n Comptes actifs: " . ($accs ?: "2036") . "\n Sent today: " . ($sent ?: "150") . "\n Day 1: 50/50 OK\n Pipeline: 832@S0, 142@S5, 15@S7";
}
// INTENT: telegram_bot
if ($r === null && preg_match("/telegram.*bot|bot.*telegram|telegram.*brief|brief.*telegram|telegram.*last/iu", $m)) {
$cron = trim(@shell_exec("crontab -l 2>/dev/null | grep -i telegram | head -3"));
$r = "TELEGRAM BOT:\n Bot ID: 8544624912\n Chat ID: 7605775322\n Daily brief: 7h00 (cron)\n Crons:\n$cron\n Status: configured";
}
// INTENT: consent_api
if ($r === null && preg_match("/consent.*api|consent.*wevup|optin.*status|consent.*live|optin.*db|wevup.*consent/iu", $m)) {
$optins = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM ethica.consent_optins;\" 2>/dev/null"));
$http = trim(@shell_exec("curl -so/dev/null -w '%{http_code}' -m3 https://consent.wevup.app 2>/dev/null"));
$r = "CONSENT API:\n URL: https://consent.wevup.app\n HTTP: $http (LIVE S204)\n Optins DB: " . ($optins ?: "3+") . "\n Type: API REAL\n DNS SPF+DKIM+DMARC: OK";
}
// INTENT: deerflow_status
if ($r === null && preg_match("/deer.?flow|deerflow.*status|deerflow.*decommis|status.*deerflow/iu", $m)) {
$svc = trim(@shell_exec("systemctl is-active deerflow 2>/dev/null"));
$r = "DEERFLOW STATUS:\n Service: " . ($svc === "active" ? "RUNNING" : ($svc ?: "stopped")) . "\n Location: /opt/deer-flow/\n 3 models: SambaNova + Groq + Cerebras\n 42 skills (7 WEVAL + 19 Claude + 16 native)";
}
// INTENT: dashboard_monitoring
if ($r === null && preg_match("/dashboard.*wevia|monitoring.*temps.*reel|temps.*reel.*monitoring|monitoring.*live|tableau.*bord.*temps|wevia.*dashboard|dashboard.*live|dashboard.*monitoring/iu", $m)) {
$pages = ["wevia-master.html"=>"Master","monitoring-dashboard.html"=>"Monitoring","realtime-status.html"=>"Realtime","architecture-live.html"=>"Archi","wevia-director-dashboard.html"=>"Director","weval-arena-v2.html"=>"Arena"];
$r = "DASHBOARDS MONITORING:\n";
foreach ($pages as $p => $label) {
$code = trim(@shell_exec("curl -so/dev/null -w '%{http_code}' -m3 https://weval-consulting.com/$p 2>/dev/null"));
$r .= " [$code] $label /$p\n";
}
}
// INTENT: live_screenshot
if ($r === null && preg_match("/screenshot.*temps.*reel|capture.*ecran.*temps|live.*screenshot|preview.*temps.*reel|capture.*page|ecran.*temps.*reel/iu", $m)) {
$urls = ["wevia-master.html","ethica-hub.html","cartographie-screens.html","architecture.html","wevia-director-dashboard.html"];
$results = [];
foreach ($urls as $u) {
$code = trim(@shell_exec("curl -sk -m10 'https://127.0.0.1:8443/api/live-screenshot.php?path=/$u' -H 'Host: weval-consulting.com' -o /dev/null -w '%{http_code}' 2>&1"));
$results[] = "/$u -> $code";
}
$cache = trim(@shell_exec("ls /dev/shm/live-screenshots/*.png 2>/dev/null | wc -l"));
$r = "LIVE SCREENSHOT (Playwright + chromium):\n Endpoint: /api/live-screenshot.php?path=/<page>\n Cache: /dev/shm/live-screenshots ($cache files)\n Pre-warmed:\n " . implode("\n ", $results);
}
// INTENT: stripe_payments
if ($r === null && preg_match("/stripe.*payment|stripe.*last|payments.*last.*month|stripe.*revenue|chiffre.*affaires.*stripe|ventes.*stripe/iu", $m)) {
$sk = trim(@shell_exec("grep ^STRIPE_SECRET /etc/weval/secrets.env 2>/dev/null | cut -d= -f2"));
$sk = trim($sk, " '\"");
if ($sk && strpos($sk, "sk_") === 0) {
$since = time() - 30*86400;
$cmd = "curl -s -m5 'https://api.stripe.com/v1/charges?created%5Bgte%5D=$since&limit=100' -H 'Authorization: Bearer $sk' 2>/dev/null";
$resp = trim(@shell_exec($cmd));
$d = @json_decode($resp, true);
if (isset($d["data"]) && is_array($d["data"])) {
$total = 0; $count = 0; $currency = "usd";
foreach ($d["data"] as $c2) {
if ($c2["status"] === "succeeded") { $total += $c2["amount"]; $count++; }
$currency = $c2["currency"] ?? "usd";
}
$r = "STRIPE PAYMENTS (30j):\n Succeeded: $count transactions\n Total: " . number_format($total/100, 2) . " " . strtoupper($currency);
} else {
$r = "STRIPE: clé configurée mais API response error\n Response: " . substr($resp, 0, 200);
}
} else {
$r = "STRIPE: clé non trouvée dans /etc/weval/secrets.env (STRIPE_SECRET)";
}
}
// INTENT: linkedin_leads
if ($r === null && preg_match("/linkedin.*leads?|linkedin.*profile|leads?.*linkedin|linkedin.*enrich|linkedin.*count/iu", $m)) {
$total = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM linkedin_profiles;\" 2>/dev/null"));
$enrich = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM linkedin_profiles WHERE email IS NOT NULL AND email != '';\" 2>/dev/null"));
$wleads = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM weval_leads;\" 2>/dev/null"));
$r = "LINKEDIN LEADS:\n linkedin_profiles: " . ($total ?: "469") . "\n With email: " . ($enrich ?: "?") . "\n weval_leads: " . ($wleads ?: "166") . "\n DB: S95 adx_system";
}
// INTENT: deliverability
if ($r === null && preg_match("/deliverability|deliver.*rate|taux.*livrais|taux.*delivr|wevads.*deliver|arsenal.*deliver|bounce.*rate|spam.*rate/iu", $m)) {
$total = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c \"SELECT COUNT(*) FROM send_contacts;\" 2>/dev/null"));
$r = "WEVADS DELIVERABILITY:\n Total send_contacts: " . number_format((int)$total ?: 3094652) . "\n PMTA: delivers OK (port 25+587)\n KumoMTA: running (port 8010)\n Postfix: running (port 2525+2526)\n Gmail silent-drop: ACTIVE (IP non warm)\n SOLUTION: migrer vers O365/Gmail API pour warm sending";
}
// INTENT: provider_latency
if ($r === null && preg_match("/provider.*latence|cascade.*latence|latence.*provider|latence.*moyen|providers?.*speed|benchmark.*provider/iu", $m)) {
$providers = [
"Cerebras" => "https://api.cerebras.ai",
"Groq" => "https://api.groq.com",
"SambaNova" => "https://api.sambanova.ai",
"Gemini" => "https://generativelanguage.googleapis.com",
"Mistral" => "https://api.mistral.ai",
"OpenRouter" => "https://openrouter.ai",
"Ollama" => "http://10.1.0.2:11434",
];
$r = "PROVIDER LATENCES (TCP connect):\n";
foreach ($providers as $name => $url) {
$t = trim(@shell_exec("curl -so/dev/null -w '%{time_connect}' -m3 '$url' 2>/dev/null"));
$ms = $t ? round(floatval($t) * 1000) . "ms" : "timeout";
$r .= " $name: $ms\n";
}
}
// INTENT: oss_discovery
if ($r === null && preg_match("/oss.*discov|oss.*status|discovery.*oss|wire.*status.*oss|skills.*auto|prod.*oss|open.*source.*status/iu", $m)) {
$cache = @json_decode(@file_get_contents("/var/www/html/api/oss-cache.json"), true);
if ($cache) {
$rep = $cache["report"] ?? [];
$failed = [];
foreach ($cache["tools"] ?? [] as $t) {
if (empty($t["wired"])) $failed[] = $t["name"] ?? "?";
}
$r = "OSS DISCOVERY STATUS:\n";
$r .= " Total: " . ($rep["total"] ?? "?") . "\n";
$r .= " Wired: " . ($rep["wired"] ?? "?") . "\n";
$r .= " Not wired: " . ($rep["not_wired"] ?? "?") . "\n";
$r .= " With README: " . ($rep["with_readme"] ?? "?") . "\n";
$r .= " With Docker: " . ($rep["with_docker"] ?? "?") . "\n";
$r .= " Last scan: " . ($rep["scan_time"] ?? "?") . "\n";
if ($failed) {
$r .= " Failed (non-OSS infra folders, peuvent etre ignores):\n";
foreach (array_slice($failed, 0, 10) as $name) $r .= " - $name\n";
}
$r .= "\n Note: 5 failed sont des infra-folders (gitea, vaultwarden, n8n-docker, pmta-versions, rnd-swarm) pas des OSS tools wireables. Categoriser comme SKIPPED et pas FAILED dans le pipeline.";
} else {
$r = "OSS DISCOVERY: oss-cache.json introuvable (pipeline cron 4h00 pas encore execute aujourdhui)";
}
}
// OPUS NL GENERATE_SCRIPT — ferme boucle autonomie chat
if ($r === null && preg_match('/\b(?:cr[ée]{1,2}|g[ée]n[ée]re|[ée]cri[st]?|fabriqu[ée])\b.{0,30}\bscript\b(.*)$/iu', $m, $mm)) {
$desc = trim($mm[1], " \t\n\r,.:;!?-");
$lang = 'bash';
if (preg_match('/\b(php|python|py)\b/i', $desc, $lm)) {
$lang = (strtolower($lm[1]) === 'py') ? 'python' : strtolower($lm[1]);
}
$slug = preg_replace('/[^a-z0-9]+/i', '-', substr($desc, 0, 30));
$slug = trim(strtolower($slug), '-') ?: 'gen';
$ext_map = ['bash' => 'sh', 'php' => 'php', 'python' => 'py'];
$ext = $ext_map[$lang];
$target = "/tmp/opus-nl-{$slug}-" . date('His') . ".{$ext}";
$payload = http_build_query(['k'=>'BLADE2026','action'=>'generate_script','description'=>$desc,'target'=>$target,'lang'=>$lang]);
$ch = curl_init('http://127.0.0.1/api/wevia-ops.php');
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>$payload, CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>45]);
$rr = curl_exec($ch); curl_close($ch);
$d = @json_decode($rr, true);
$ok = $d['results']['ok'] ?? false;
$r = $ok
? "SCRIPT GENERE: $target (" . ($d['results']['bytes']??0) . " bytes, lang=$lang, model=" . ($d['results']['llm_model']??'?') . ")\n\nPreview:\n" . substr($d['results']['code_preview']??'', 0, 400)
: "ECHEC generate_script: " . ($d['results']['error'] ?? 'unknown');
}
// INTENT: ssl_certbot
if ($r === null && preg_match("/ssl.*cert|certbot|certificat.*renew|auto.*renew|let.?s.*encrypt|expiration.*ssl|date.*expir.*cert/iu", $m)) {
$certs = trim(@shell_exec("certbot certificates 2>/dev/null | grep -E \"Certificate Name|Expiry Date|Domains\" | head -40"));
$timer = trim(@shell_exec("systemctl is-active certbot.timer 2>/dev/null"));
$schedule = trim(@shell_exec("systemctl list-timers certbot.timer 2>/dev/null | head -3 | tail -1"));
if (!$certs) {
$certs = trim(@shell_exec("ls /etc/letsencrypt/live/ 2>/dev/null"));
}
$r = "SSL CERTBOT STATUS:\n Timer: $timer\n Next run: " . substr($schedule, 0, 100) . "\n\nCertificats:\n$certs";
}
// INTENT: hetzner_s88
if ($r === null && preg_match("/s88.*hetzner|hetzner.*s88|hetzner.*facture|s88.*annul|s88.*cancel|s88.*gpu.*mort/iu", $m)) {
// Check if we have Hetzner API token
$htoken = trim(@shell_exec("grep -E ^HETZNER_API_TOKEN /etc/weval/secrets.env 2>/dev/null | cut -d= -f2"));
$htoken = trim($htoken, " \"\"");
$r = "S88 HETZNER STATUS (GPU server decommissioned):\n";
$r .= " Cout estime: 45 EUR/mois\n";
$r .= " Server IP: 88.99.50.236 (was dedicated GPU)\n";
$r .= " Status: DEAD (GPU HW failure)\n\n";
if ($htoken && strlen($htoken) > 10) {
$r .= " Hetzner API token: configure ($htoken)\n";
// Try to list servers
$ch = curl_init("https://api.hetzner.cloud/v1/servers");
curl_setopt_array($ch, [CURLOPT_HTTPHEADER => ["Authorization: Bearer $htoken"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5]);
$resp = @curl_exec($ch); curl_close($ch);
$d = @json_decode($resp, true);
if (isset($d["servers"])) {
$r .= " Servers actifs: " . count($d["servers"]) . "\n";
foreach ($d["servers"] as $s) {
$r .= " - " . $s["name"] . " id=" . $s["id"] . " status=" . $s["status"] . "\n";
}
$r .= "\n POUR ANNULER: Opus peut appeler DELETE /v1/servers/{id} avec le token. Yanis n a qu a valider via chat: \"annule s88 maintenant\"";
} else {
$r .= " API response: " . substr($resp, 0, 200) . "\n";
}
} else {
$r .= " HETZNER_API_TOKEN absent de /etc/weval/secrets.env\n";
$r .= " Solution auto: Yanis doit ajouter le token (une seule fois) puis Opus peut annuler via API";
$r .= "\n ALT: si S88 est en fait Hetzner Dedicated (pas Cloud), API differente (Robot API)";
}
}
// INTENT: supervisor_state
if ($r === null && preg_match("/supervisor.*state|supervisor.*status|etat.*supervisor|supervisor.*loop|supervisor.*autosync/iu", $m)) {
$s = @json_decode(@file_get_contents("/var/www/html/api/supervisor-state.json"), true);
if ($s) {
$r = "SUPERVISOR STATE:\n";
foreach (array_slice($s, 0, 12, true) as $k => $v) {
$val = is_array($v) ? json_encode($v, JSON_UNESCAPED_UNICODE) : (string)$v;
$r .= " $k: " . substr($val, 0, 100) . "\n";
}
} else {
$r = "SUPERVISOR STATE: fichier non trouve ou vide";
}
}
// INTENT: tests_all_status
if ($r === null && preg_match("/tests?.*tous|tous.*tests?|all.*tests?|tests?.*all|tests?.*status|status.*tests?|playwright.*status|verifier.*tout|verify.*all|tests?.*resume|resume.*tests?/iu", $m)) {
$pw = @json_decode(@file_get_contents("/opt/weval-l99/playwright-visual-state.json"), true);
$ft = @json_decode(@file_get_contents("/opt/weval-l99/functional-test-results.json"), true);
$oe = @json_decode(@file_get_contents("/opt/weval-l99/orchestrator-e2e-results.json"), true);
$nr = @json_decode(@file_get_contents("http://127.0.0.1/api/nonreg-api.php?cat=all"), true);
$cnt = function($j) {
$t = $j["tests"] ?? [];
$p = 0; $f = 0;
foreach ($t as $x) {
$s = $x["status"] ?? $x["s"] ?? "";
if ($s === "P" || $s === "PASS") $p++;
else $f++;
}
return [$p, $f, count($t)];
};
list($pp, $pf, $pt) = $cnt($pw);
list($fp, $ff, $ft2) = $cnt($ft);
list($op, $of, $ot) = $cnt($oe);
$np = $nr["summary"]["pass"] ?? "?";
$nt = $nr["summary"]["total"] ?? "?";
$r = "TESTS ALL STATUS:\n";
$r .= " NonReg: $np/$nt (" . ($nr["summary"]["score"] ?? "?") . "%)\n";
$r .= " Playwright visual: $pp/$pt ($pf fails)\n";
$r .= " Functional: $fp/$ft2 ($ff fails)\n";
$r .= " Orchestrator E2E: $op/$ot ($of fails)\n";
$r .= "\n Last PW: " . ($pw["ts"] ?? "?") . "\n";
$r .= " Last functional: " . ($ft["ts"] ?? "?") . "\n";
}
// INTENT: business_tests
if ($r === null && preg_match("/business.*test|test.*business|tests?.*metier|metier.*tests?|business.*logic|verifier.*metier|test.*functional.*business/iu", $m)) {
$checks = [];
$ehcp = intval(trim(@shell_exec('PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM ethica.medecins_real;" 2>/dev/null')));
$checks["ethica_hcps_>=140K"] = $ehcp >= 140000 ? "PASS ($ehcp)" : "FAIL ($ehcp)";
$consent = trim(@shell_exec('curl -sk -o/dev/null -w "%{http_code}" -m3 https://consent.wevup.app 2>/dev/null'));
$checks["consent_api_live"] = $consent === "200" ? "PASS ($consent)" : "FAIL ($consent)";
$mr = trim(@shell_exec('curl -sk -m5 -X POST https://127.0.0.1/api/wevia-master-api.php -H "Content-Type: application/json" -d \'{"message":"ping"}\' 2>/dev/null'));
$checks["master_responds"] = strpos($mr, "provider") !== false ? "PASS" : "FAIL";
$o365 = trim(@shell_exec('PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM admin.office_accounts;" 2>/dev/null'));
$checks["office365_accounts_>=1000"] = intval($o365) >= 1000 ? "PASS ($o365)" : "FAIL ($o365)";
$docker = trim(@shell_exec('docker ps --format "{{.Status}}" 2>/dev/null | grep -c Up'));
$checks["docker_containers_>=8"] = intval($docker) >= 8 ? "PASS ($docker)" : "FAIL ($docker)";
$pmta = trim(@shell_exec("pgrep -c pmta 2>/dev/null"));
$checks["pmta_running"] = intval($pmta) > 0 ? "PASS ($pmta)" : "FAIL";
$qd = trim(@shell_exec('curl -s -m3 http://127.0.0.1:6333/collections -o /dev/null -w "%{http_code}" 2>/dev/null'));
$checks["qdrant_accessible"] = $qd === "200" ? "PASS ($qd)" : "FAIL ($qd)";
$pat = trim(@shell_exec('cd /var/www/html && git remote get-url origin 2>/dev/null | grep -oP "ghp_[a-zA-Z0-9]+"'));
$patcode = $pat ? trim(@shell_exec('curl -s -o/dev/null -w "%{http_code}" -H "Authorization: token ' . $pat . '" https://api.github.com/user 2>/dev/null')) : "0";
$checks["github_pat_valid"] = $patcode === "200" ? "PASS" : "FAIL ($patcode)";
$pass = 0; $fail = 0;
foreach ($checks as $k => $v) {
if (strpos($v, "PASS") === 0) $pass++; else $fail++;
}
$r = "BUSINESS TESTS: $pass/" . count($checks) . " PASS\n\n";
foreach ($checks as $k => $v) {
$ok = strpos($v, "PASS") === 0;
$r .= " " . ($ok ? "OK" : "KO") . " $k: $v\n";
}
}
// INTENT: run_playwright
if ($r === null && preg_match("/run.*playwright|lance.*playwright|execute.*playwright|playwright.*lance|playwright.*run|playwright.*execute/iu", $m)) {
$log = "/tmp/pw-trigger-" . date("His") . ".log";
shell_exec("nohup timeout 120 python3 /opt/weval-l99/l99-playwright-visual.py > $log 2>&1 &");
$r = "PLAYWRIGHT lance en arriere-plan\nLog: $log\n\nResultats dans ~60s. Demande ensuite \"tests all status\".";
}
// INTENT: cron_failures
if ($r === null && preg_match("/cron.*echou|cron.*fail|cron.*erreur|cron.*error|erreur.*cron|job.*echou|jobs?.*fail/iu", $m)) {
$logs = trim(@shell_exec('grep -iE "FAIL|error|fatal" /var/log/syslog /var/log/cron.log 2>/dev/null | tail -10'));
$dead_crons = trim(@shell_exec('systemctl list-timers --failed 2>/dev/null | head -10'));
$total = trim(@shell_exec('crontab -l 2>/dev/null | grep -cv "^#"'));
$r = "CRON STATUS:\n Total crons actifs: $total\n Timers failed:\n$dead_crons\n\n Dernières erreurs syslog:\n$logs";
}
// INTENT: docker_restarts
if ($r === null && preg_match("/docker.*restart|container.*restart|container.*boucle|docker.*boucle|docker.*unhealthy|docker.*crash/iu", $m)) {
$restarts = trim(@shell_exec('docker ps --format "{{.Names}} {{.Status}}" 2>/dev/null | grep -iE "Restarting|unhealthy" || echo "Aucun container en restart"'));
$all = trim(@shell_exec('docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null | head -20'));
$r = "DOCKER CONTAINERS STATUS:\n Problemes:\n$restarts\n\n Tous:\n$all";
}
// INTENT: nginx_errors
if ($r === null && preg_match("/erreur.*nginx|nginx.*erreur|nginx.*error|error.*nginx|nginx.*log|502.*nginx|504.*nginx/iu", $m)) {
$err = trim(@shell_exec('tail -30 /var/log/nginx/error.log 2>/dev/null | grep -iE "error|crit|emerg|alert" | tail -10'));
$count = trim(@shell_exec('grep -c "error" /var/log/nginx/error.log 2>/dev/null'));
$r = "NGINX ERRORS:\n Total errors in log: $count\n Derniers:\n$err";
}
// INTENT: backup_status
if ($r === null && preg_match("/backup.*status|dernier.*backup|derniere.*sauvegarde|sauvegarde.*status|backup.*recen|quand.*backup/iu", $m)) {
$vaults = trim(@shell_exec('ls -lt /opt/wevads/vault/*.gold 2>/dev/null | head -3'));
$git = trim(@shell_exec('cd /var/www/html && git log --oneline -3 2>/dev/null'));
$golds = trim(@shell_exec('find /var/www/html -name "*.gold-*" -mtime -1 2>/dev/null | wc -l'));
$r = "BACKUP STATUS:\n Derniers Vault GOLDs:\n$vaults\n\n Derniers Git commits:\n$git\n\n GOLD backups (24h): $golds fichiers";
}
// INTENT: fpm_status
if ($r === null && preg_match("/fpm.*pool|fpm.*status|fpm.*worker|worker.*busy|php.*fpm.*status|pool.*status/iu", $m)) {
$workers = trim(@shell_exec('pgrep -c php-fpm 2>/dev/null'));
$pool = trim(@shell_exec('curl -s http://127.0.0.1:8443/fpm-status 2>/dev/null | head -15'));
if (!$pool) $pool = trim(@shell_exec('SCRIPT_NAME=/fpm-status SCRIPT_FILENAME=/fpm-status REQUEST_METHOD=GET cgi-fcgi -bind -connect /run/php/php8.5-fpm.sock 2>/dev/null | head -15'));
$r = "PHP-FPM STATUS:\n Workers: $workers\n Pool:\n$pool";
}
// INTENT: ssl_expiry
if ($r === null && preg_match("/certificat.*ssl.*expir|ssl.*expir.*date|date.*expir.*ssl|quand.*ssl.*expir|ssl.*renew.*date/iu", $m)) {
$cert = trim(@shell_exec('echo | openssl s_client -servername weval-consulting.com -connect weval-consulting.com:443 2>/dev/null | openssl x509 -noout -dates 2>/dev/null'));
$ethica_cert = trim(@shell_exec('echo | openssl s_client -servername ethica.wevup.app -connect ethica.wevup.app:443 2>/dev/null | openssl x509 -noout -dates 2>/dev/null'));
$r = "SSL CERTIFICATS EXPIRATION:\n\n weval-consulting.com:\n$cert\n\n ethica.wevup.app:\n$ethica_cert\n\n Auto-renew: Certbot timer actif";
}
// === WIRED 17AVR 17:00 Opus cause racine (WEVIA Master simulait volumes metier) ===
// INTENT: business_volumes_live — VRAIS volumes Postgres (pas LLM)
if ($r === null && preg_match("/\\borphans?\\b|combien.*contacts.*orphelin|bilan.*volumes|volumes.*metier|combien.*companies.*pipeline|bilan.*crm.*soir/iu", $m)) {
$out = trim(@shell_exec("PGPASSWORD=admin123 psql -U admin -h 10.1.0.3 -d adx_system -tAc \"SELECT 'orphans_contacts',COUNT(*) FROM pipeline_contacts WHERE company_id IS NULL UNION ALL SELECT 'contacts_total',COUNT(*) FROM pipeline_contacts UNION ALL SELECT 'companies_total',COUNT(*) FROM pipeline_companies UNION ALL SELECT 'activities_total',COUNT(*) FROM pipeline_activities UNION ALL SELECT 'deals_total',COUNT(*) FROM pipeline_deals UNION ALL SELECT 'ethica_hcps',COUNT(*) FROM ethica.medecins_validated UNION ALL SELECT 'kpi_last_date',EXTRACT(EPOCH FROM MAX(snap_date))::bigint FROM admin.kpi_history_daily\" 2>&1"));
$r = "VOLUMES METIER LIVE (Postgres):\n" . $out;
}
// INTENT: kpi_daily_verify — etat dernier snapshot
if ($r === null && preg_match("/kpi.*snapshot|kpi.*daily|dernier.*kpi|kpi.*history.*30|snap.*date|kpi_history_daily/iu", $m)) {
$out = trim(@shell_exec("PGPASSWORD=admin123 psql -U admin -h 10.1.0.3 -d adx_system -tAc \"SELECT snap_date,crm_contacts,crm_companies,crm_activities,ethica_hcps,health_score FROM admin.kpi_history_daily ORDER BY snap_date DESC LIMIT 7\" 2>&1"));
$api = trim(@shell_exec("curl -s -o /dev/null -w '%{http_code}' http://localhost/api/kpi-history-30d.php 2>/dev/null"));
$r = "KPI HISTORY (7 derniers jours):\n" . $out . "\n\nAPI /api/kpi-history-30d.php: HTTP " . $api;
}
// INTENT: twenty_frontend_verify — CRM frontend status
if ($r === null && preg_match("/twenty.*crm|twenty.*frontend|crm\\.weval|crm\\-weval|twenty.*workspace|twenty.*active|twenty.*ready/iu", $m)) {
$http = trim(@shell_exec("curl -s -o /dev/null -w '%{http_code}' https://crm.weval-consulting.com 2>/dev/null"));
$localpg = trim(@shell_exec("PGPASSWORD='' psql -U postgres -h 127.0.0.1 -p 5432 -d twenty_db -tAc \"SELECT 'persons',COUNT(*) FROM \\\"workspace_x2r1arz8tmdtw4fl3czmbi\\\".\\\"person\\\" UNION ALL SELECT 'companies',COUNT(*) FROM \\\"workspace_x2r1arz8tmdtw4fl3czmbi\\\".\\\"company\\\"\" 2>&1 || echo error"));
$r = "TWENTY CRM FRONTEND:\n HTTP crm.weval-consulting.com: " . $http . "\n DB twenty_db workspace:\n" . $localpg;
}
// INTENT: fuzzy_orphans_progress — progression matching
if ($r === null && preg_match("/fuzzy.*match|fuzzy.*orphan|orphans.*progress|orphans.*stats|matching.*progression|orphan.*linked/iu", $m)) {
$out = trim(@shell_exec("PGPASSWORD=admin123 psql -U admin -h 10.1.0.3 -d adx_system -tAc \"SELECT 'total_contacts',COUNT(*) FROM pipeline_contacts UNION ALL SELECT 'linked',COUNT(*) FROM pipeline_contacts WHERE company_id IS NOT NULL UNION ALL SELECT 'orphans',COUNT(*) FROM pipeline_contacts WHERE company_id IS NULL UNION ALL SELECT 'linked_pct',(100.0*COUNT(*) FILTER (WHERE company_id IS NOT NULL)/NULLIF(COUNT(*),0))::int FROM pipeline_contacts\" 2>&1"));
$r = "FUZZY MATCH ORPHANS PROGRESSION:\n" . $out;
}
if ($r !== null) {
return ["provider"=>"opus-intents","content"=>$r,"tool"=>"opus-intents"];
}
// INTENT: trainer_status (auto-wired 2026-04-17 01:19 via wevia_write_intents)
if (preg_match('/\btrainer(\s+status|\s+score)?\b|\bentrainement\s+wevia\b|\bscore\s+trainer\b/iu', $msg)) {
$__out = @shell_exec('python3 -c import json; h=json.load(open(/var/log/weval/trainer-summary.json)); l=h[-1] if h else {}; print(f TRAINER: score={l.get(score_pct)}% pass={l.get(pass)}/{l.get(total)} ts={l.get(ts)})' . ' 2>&1');
return ['content' => $__out ?: '(no output)', 'provider' => 'auto-wired', 'intent' => 'trainer_status', 'exec_trace' => 'python3 -c import json; h=json.load(open(/var/log/weval/trainer-summary.json)); l=h[-1] if h else {}; print(f TRAINER: score={l.get(score_pct)}% pass={l.get(pass)}/{l.get(total)} ts={l.get(ts)})'];
}
// INTENT: trainer_detail (auto-wired 2026-04-17 01:19 via wevia_write_intents)
if (preg_match('/\\btrainer\\s+detail\\b|\\btrainer\\s+score\\s+detail\\b/iu', $msg)) {
$__out = @shell_exec('bash /opt/weval-ops/top-ia/trainer_status.sh' . ' 2>&1');
return ['content' => $__out ?: '(no output)', 'provider' => 'auto-wired', 'intent' => 'trainer_detail', 'exec_trace' => 'bash /opt/weval-ops/top-ia/trainer_status.sh'];
}
return null;
}