1447 lines
117 KiB
PHP
1447 lines
117 KiB
PHP
<?php
|
|
@require_once __DIR__ . '/wevia-sanitizer-guard.php'; // WAVE 206 sanitizer guard
|
|
|
|
|
|
// === AMBRE-V1 · truth registry dynamic snapshot (doctrine #4) · FIX v4 aggregator primary ===
|
|
if (!function_exists('__ambre_truth_snapshot')) {
|
|
function __ambre_truth_snapshot() {
|
|
static $cache = null;
|
|
if ($cache !== null) return $cache;
|
|
// Primary: call ambre-count aggregator (all scalars ready)
|
|
$agg = null;
|
|
$ch = @curl_init('http://127.0.0.1/api/ambre-count.php');
|
|
if ($ch !== false) {
|
|
@curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>3, CURLOPT_CONNECTTIMEOUT=>2]);
|
|
$r = @curl_exec($ch); @curl_close($ch);
|
|
if ($r) {
|
|
$d = @json_decode($r, true);
|
|
if (is_array($d) && isset($d['ok']) && $d['ok']) $agg = $d;
|
|
}
|
|
}
|
|
if (is_array($agg)) {
|
|
$cache = [
|
|
'agents' => $agg['agents'] ?? '?',
|
|
'intents' => $agg['intents'] ?? '?',
|
|
'skills' => $agg['skills'] ?? '?',
|
|
'brains' => $agg['brains'] ?? '?',
|
|
'doctrines' => $agg['doctrines'] ?? '?',
|
|
'dashboards' => $agg['dashboards'] ?? '?',
|
|
'providers' => $agg['providers'] ?? '?',
|
|
'tools' => $agg['tools'] ?? '?',
|
|
'qdrant' => $agg['qdrant_collections'] ?? '?',
|
|
'pages' => $agg['pages'] ?? '?',
|
|
'hcps' => $agg['hcps'] ?? '?',
|
|
'nonreg' => $agg['nonreg_score'] ?? '?',
|
|
'autonomy' => $agg['autonomy'] ?? '?',
|
|
'built_at' => $agg['built_at'] ?? '?',
|
|
'apis' => $agg['apis_php'] ?? '?',
|
|
'docker' => $agg['docker'] ?? '?',
|
|
'crons' => $agg['crons'] ?? '?',
|
|
];
|
|
return $cache;
|
|
}
|
|
// Fallback: read truth-registry directly (nested-aware)
|
|
$p = '/var/www/html/api/wevia-truth-registry.json';
|
|
$d = file_exists($p) ? @json_decode(@file_get_contents($p), true) : null;
|
|
if (!is_array($d)) {
|
|
$cache = ['tools'=>'?','providers'=>'?','hcps'=>'?','pages'=>'?','agents'=>'?','intents'=>'?','skills'=>'?','autonomy'=>'?','built_at'=>'?'];
|
|
return $cache;
|
|
}
|
|
$getCount = function($node) {
|
|
if (!is_array($node)) return null;
|
|
foreach (['count_unique','count','total','TOTAL','n'] as $k)
|
|
if (isset($node[$k]) && is_numeric($node[$k])) return (int)$node[$k];
|
|
foreach (['items','list'] as $k)
|
|
if (isset($node[$k]) && is_array($node[$k])) return count($node[$k]);
|
|
return null;
|
|
};
|
|
$cache = [
|
|
'agents' => $getCount($d['agents'] ?? null) ?? '?',
|
|
'intents' => $getCount($d['intents'] ?? null) ?? '?',
|
|
'skills' => $getCount($d['skills'] ?? null) ?? '?',
|
|
'brains' => $getCount($d['brains'] ?? null) ?? '?',
|
|
'doctrines' => $getCount($d['doctrines'] ?? null) ?? '?',
|
|
'dashboards' => $getCount($d['dashboards'] ?? null) ?? '?',
|
|
'providers' => $getCount($d['providers'] ?? null) ?? '?',
|
|
'tools' => '?', 'qdrant' => '?', 'hcps' => '?', 'pages' => '?',
|
|
'nonreg' => $d['nonreg']['score'] ?? '?',
|
|
'autonomy' => $d['autonomy_level'] ?? '?',
|
|
'built_at' => $d['built_at'] ?? '?',
|
|
'apis' => $d['apis_php_count'] ?? '?',
|
|
];
|
|
return $cache;
|
|
}
|
|
}
|
|
// === END AMBRE-V1 helper ===
|
|
|
|
// === PARETO HELPER: Cerebras fast call ===
|
|
function _cerebrasCall($prompt, $mode = "general") {
|
|
static $secrets = null;
|
|
if (!$secrets) {
|
|
$secrets = [];
|
|
foreach (file("/etc/weval/secrets.env") as $l) {
|
|
$l = trim($l);
|
|
if ($l && $l[0] !== "#" && strpos($l, "=") !== false) {
|
|
list($k, $v) = explode("=", $l, 2);
|
|
$secrets[trim($k)] = trim($v, "\"' ");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Inject nucleus if domain detected
|
|
$nucleus = "";
|
|
$nmap = ["code"=>"code-mastery","debug"=>"code-mastery","explain_code"=>"code-mastery","education"=>"domain-expertise","email"=>"domain-expertise","search"=>"domain-expertise","automation"=>"rpa-mastery","analysis"=>"domain-expertise"];
|
|
if (isset($nmap[$mode])) {
|
|
$nf = "/opt/wevia-brain/prompts/nucleus/{$nmap[$mode]}.md";
|
|
if (file_exists($nf)) $nucleus = "\n" . substr(file_get_contents($nf), 0, 1500);
|
|
}
|
|
|
|
$system = "Tu es WEVIA Master, IA souveraine de WEVAL Consulting Casablanca. Reponds en francais concis, technique et actionnable." . $nucleus;
|
|
|
|
// Use sovereign proxy (port 4000) — handles cascade + retry automatically
|
|
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$system],["role"=>"user","content"=>$prompt]],"max_tokens"=>1500,"temperature"=>0.7]),
|
|
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 20
|
|
]);
|
|
$r = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
if ($code === 200) {
|
|
$d = json_decode($r, true);
|
|
$content = $d["choices"][0]["message"]["content"] ?? null;
|
|
if ($content) return ["provider"=>"pareto-".$mode,"content"=>$content,"engine"=>"Pareto/".$mode,"intent"=>"pareto_".$mode];
|
|
}
|
|
|
|
// Fallback Ollama
|
|
$ch = curl_init("http://127.0.0.1:11434/api/chat");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"qwen3:4b","messages"=>[["role"=>"system","content"=>$system],["role"=>"user","content"=>$prompt]],"stream"=>false]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>25]);
|
|
$r = curl_exec($ch); curl_close($ch);
|
|
$d = json_decode($r, true);
|
|
return ["provider"=>"pareto-sovereign","content"=>$d["message"]["content"]??"Pas de reponse","engine"=>"Ollama/Pareto","intent"=>"pareto_".$mode];
|
|
}
|
|
|
|
function wevia_fast_path($msg) {
|
|
error_log("FP ENTRY: " . substr($msg, 0, 80));
|
|
|
|
// === OPUS_ARCH_FP_V44 — opus-arch intercept BEFORE all other fast-path (17-18avr) ===
|
|
$__oafp = mb_strtolower(trim($msg));
|
|
// Cap 12
|
|
if (preg_match('/\b(explique|audit)\s+(derniere|last|trail)\b/iu', $__oafp) || preg_match('/pourquoi\s+cette\s+reponse/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-explainability.php?action=stats', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Explain: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_explain'];
|
|
}
|
|
// Cap 8 DeepSeek-R1
|
|
if (preg_match('/\b(deep.?reason|system.?2|chain.?of.?thought|deepseek.?r1)\b/iu', $__oafp)) {
|
|
$ctx = stream_context_create(['http'=>['method'=>'POST','header'=>"Host: weval-consulting.com\r\nContent-Type: application/x-www-form-urlencoded",'content'=>http_build_query(['message'=>$msg]),'timeout'=>45]]);
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-deepseek-r1.php', false, $ctx);
|
|
$d = @json_decode($r, true);
|
|
if ($d) return ['content'=>$d['answer'] ?? $d['full'] ?? 'R1 unavailable','provider'=>'opus-arch-fp','tool'=>'opus_arch_r1'];
|
|
}
|
|
// Cap 5 RLHF
|
|
if (preg_match('/\b(feedback|rlhf)\b/iu', $__oafp) && !preg_match('/\b(list|stats|view|show)\b/iu', $__oafp)) {
|
|
$score = preg_match('/\bup\b|positif|bon/iu', $__oafp) ? 1 : (preg_match('/\bdown\b|negatif|mauvais/iu', $__oafp) ? -1 : 0);
|
|
$ctx = stream_context_create(['http'=>['method'=>'POST','header'=>"Host: weval-consulting.com\r\nContent-Type: application/x-www-form-urlencoded",'content'=>http_build_query(['score'=>$score,'intent'=>'chat','session_id'=>session_id() ?: 'anon','correction'=>$msg]),'timeout'=>5]]);
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-rlhf-feedback.php?action=submit', false, $ctx);
|
|
return ['content'=>'Feedback score='.$score.' logged','provider'=>'opus-arch-fp','tool'=>'opus_arch_rlhf'];
|
|
}
|
|
// Cap 14 Predictive Heal
|
|
if (preg_match('/\bpredictive\s+heal\b/iu', $__oafp)) {
|
|
$metric = preg_match('/disk/iu', $__oafp) ? 'disk' : (preg_match('/fpm/iu', $__oafp) ? 'fpm' : 'load');
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-predictive-heal.php?metric='.$metric, false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Predictive '.$metric.': '.substr($r,0,600),'provider'=>'opus-arch-fp','tool'=>'opus_arch_predict'];
|
|
}
|
|
// Cap 3 API Fuzzer
|
|
if (preg_match('/\b(fuzz|auto.?discover)\s+api\b/iu', $__oafp)) {
|
|
$act = preg_match('/\b(list|results|view|show)\b/iu', $__oafp) ? 'list' : 'scan';
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-api-fuzzer.php?action='.$act.'&limit=10', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>20]]));
|
|
return ['content'=>'API fuzzer '.$act.': '.substr($r,0,800),'provider'=>'opus-arch-fp','tool'=>'opus_arch_fuzz'];
|
|
}
|
|
// Cap 17 GraphRAG
|
|
if (preg_match('/\b(graphrag|knowledge\s+graph)\b/iu', $__oafp)) {
|
|
$act = preg_match('/\bbuild\b/iu', $__oafp) ? 'build' : 'query';
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-graphrag.php?action='.$act.'&q='.urlencode($msg), false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>12]]));
|
|
return ['content'=>'GraphRAG '.$act.': '.substr($r,0,800),'provider'=>'opus-arch-fp','tool'=>'opus_arch_graphrag'];
|
|
}
|
|
// Cap 15 Infinite Context
|
|
if (preg_match('/\b(infinite\s+context|analyze\s+long|chunk\s+document)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-infinite-context.php?action=analyze&url='.urlencode($msg), false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>15]]));
|
|
return ['content'=>'Infinite context: '.substr($r,0,600),'provider'=>'opus-arch-fp','tool'=>'opus_arch_infinite'];
|
|
}
|
|
// Cap 16 Continuous FT
|
|
if (preg_match('/\b(continuous\s+fine.?tune|kaggle\s+phase\s*5|trigger\s+finetune)\b/iu', $__oafp)) {
|
|
$act = preg_match('/\btrigger\b/iu', $__oafp) ? 'trigger' : (preg_match('/\bcollect\b/iu', $__oafp) ? 'collect_logs' : 'status');
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-continuous-ft.php?action='.$act, false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>10]]));
|
|
return ['content'=>'Continuous FT '.$act.': '.substr($r,0,600),'provider'=>'opus-arch-fp','tool'=>'opus_arch_finetune'];
|
|
}
|
|
// Cap 4 Prompt Evolution
|
|
if (preg_match('/\b(prompt\s+evolution|genetic\s+prompt)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-prompt-evolution.php', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Prompt evolution: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_prompt'];
|
|
}
|
|
// Cap 10 GPU Grid
|
|
if (preg_match('/\b(gpu\s+grid|shard\s+prompt)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-gpu-grid-prod.php?action=status', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'GPU Grid: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_gpu'];
|
|
}
|
|
// Cap 2 Browser Use
|
|
if (preg_match('/\b(browser\s+use|playwright\s+browse|browse\s+url)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-browser-use.php?action=whitelist', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Browser Use: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_browser'];
|
|
}
|
|
// Cap 7 Voice Status
|
|
if (preg_match('/\b(voice\s+status|whisper\s+status|xtts)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-voice.php?action=status', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Voice status: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_voice'];
|
|
}
|
|
// Cap 9 Self-refactor
|
|
if (preg_match('/\b(self.?refactor|refactor\s+queue)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-self-refactor.php?action=queue', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Refactor queue: '.substr($r,0,500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_refactor'];
|
|
}
|
|
// Cap 11 n8n
|
|
if (preg_match('/\bn8n\s+(generate|create\s+workflow|gen)\b/iu', $__oafp)) {
|
|
$ctx = stream_context_create(['http'=>['method'=>'POST','header'=>"Host: weval-consulting.com\r\nContent-Type: application/x-www-form-urlencoded",'content'=>http_build_query(['description'=>$msg]),'timeout'=>10]]);
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-n8n-gen-v2.php?action=generate', false, $ctx);
|
|
return ['content'=>'n8n workflow: '.substr($r,0,800),'provider'=>'opus-arch-fp','tool'=>'opus_arch_n8n'];
|
|
}
|
|
// Meta Autonomy Report
|
|
if (preg_match('/\b(autonomy\s+report|carry.?overs?\s+status|gap\s+report|autonomie)\b/iu', $__oafp)) {
|
|
$r = @file_get_contents('http://127.0.0.1/api/opus-arch-autonomy-reporter.php', false, stream_context_create(['http'=>['header'=>'Host: weval-consulting.com','timeout'=>5]]));
|
|
return ['content'=>'Autonomy report: '.substr($r,0,1500),'provider'=>'opus-arch-fp','tool'=>'opus_arch_autonomy'];
|
|
}
|
|
// === END OPUS_ARCH_FP_V44 ===
|
|
|
|
$m = mb_strtolower(trim($msg));
|
|
$r = null;
|
|
|
|
// === OPUS_FP_TASK_DECOMPOSER_GUARD (16AVR v3) ===
|
|
// RC: opus-autonomy passe APRES fast-path donc mes AGENT 9 unreachable
|
|
// si le message contient un keyword fast-path (wiki/nonreg/paperclip/...).
|
|
// Solution: trigger TRES SPECIFIQUE en tete de fast-path. Strict prefix only.
|
|
if (preg_match('/^\s*(task[\s_-]?decompose|>>\s*decompose|\[TD\])\b/iu', trim($msg))) {
|
|
$tasks = [];
|
|
foreach (preg_split('/\r?\n/', $msg) as $line) {
|
|
$line = trim($line);
|
|
if (preg_match('/^(?:\d+[\.)]\s*|[-*]\s*|fix\s*#?\d+\s*[:\-]?\s*)(.+)/iu', $line, $tx)) {
|
|
$t = trim($tx[1]);
|
|
if (mb_strlen($t) > 3 && mb_strlen($t) < 500) $tasks[] = $t;
|
|
}
|
|
}
|
|
if (count($tasks) >= 1) {
|
|
$sub = [];
|
|
foreach ($tasks as $i => $task) {
|
|
if ($i >= 6) { $sub[] = "[truncated at 6 tasks to avoid CF 502]"; break; }
|
|
$ch = curl_init('http://127.0.0.1/api/wevia-master-api.php');
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => 1,
|
|
CURLOPT_RETURNTRANSFER => 1,
|
|
CURLOPT_TIMEOUT => 18,
|
|
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-Decomp-Sub: 1'],
|
|
CURLOPT_POSTFIELDS => json_encode(['message' => $task]),
|
|
]);
|
|
$rr = curl_exec($ch);
|
|
curl_close($ch);
|
|
$j = @json_decode($rr, true);
|
|
$resp = (string)($j['content'] ?? $rr ?? 'NULL');
|
|
$prov = $j['provider'] ?? '?';
|
|
$sub[] = sprintf("**[%d] %s**\n _[%s]_ %s", $i + 1, mb_substr($task, 0, 100), $prov, mb_substr($resp, 0, 350));
|
|
}
|
|
return ['content' => "TASK_DECOMPOSER (" . count($tasks) . " tasks executed):\n\n" . implode("\n\n", $sub), 'provider' => 'opus-decompose-fp', 'source' => 'task-decomposer-fastpath', 'tool' => 'task-decomposer'];
|
|
}
|
|
}
|
|
|
|
// === OPUS_FP_HCP_COUNTRY (opus wire 16avr) ===
|
|
if (preg_match('/combien.*(hcp|medecin).*(maroc|tunis|alger)|hcp.*(maroc|tunis|alger)|medecin.*(maroc|tunis|alger)/iu', $m)) {
|
|
$cj=@json_decode(@file_get_contents('http://127.0.0.1/api/ethica-country-api.php'),true);
|
|
if($cj&&!empty($cj['countries'])){
|
|
$out="ETHICA PAR PAYS (DB LIVE):\n";
|
|
foreach($cj['countries'] as $cp)$out.=" ".$cp['pays'].": ".$cp['t']." HCPs, ".$cp['e']." email, ".$cp['p']." tel\n";
|
|
$out.="\nTotal: ".$cj['total']." | Email: ".$cj['email'];
|
|
return ['content'=>$out,'provider'=>'opus-hcp-country','tool'=>'ethica-country'];
|
|
}
|
|
}
|
|
// === OPUS_FP_CONSENT_GUARD (16AVR) ===
|
|
if(preg_match("/\\b(consent|optin|consentement)\\b/i",$msg) && !preg_match("/\\b(kaouther|draft|refais|wire|propos|offre|palier|tarif|45000|DH)\\b/i",$msg)){
|
|
$cs=@json_decode(@file_get_contents("http://127.0.0.1/api/ethica-consent-api.php?action=stats"),true);
|
|
$r="CONSENTEMENTS ETHICA:\nOpt-in: ".(($cs["optin"]??0))."\nTotal: ".(($cs["total_log"]??0));
|
|
return ["content"=>$r,"provider"=>"consent-guard","tool"=>"ethica-consent"];
|
|
}
|
|
// === OPUS_FP_ETHICA_STATS_GUARD (16AVR v6) ===
|
|
// RC: tools-catalog.json retourne descriptor statique "141K HCPs DZ/MA/TN pharma"
|
|
// quand user demande détail email/tel/breakdown → hallucinations. Call vrai endpoint.
|
|
if (preg_match('/\bethica\b/iu', $m) && preg_match('/\b(combien|detail|d[ée]tail|breakdown|split|email|telephone|t[ée]l[ée]phone|hcps?|total|exact|chiffres?|live|stats?|statistique|repartition|r[ée]partition|par.*pays|valide|gap)\b/iu', $m)) {
|
|
$j = @json_decode(@file_get_contents('http://127.0.0.1/api/ethica-stats-api.php'), true);
|
|
if (is_array($j) && !empty($j['ok'])) {
|
|
$t = (int)($j['total'] ?? 0);
|
|
$e = (int)($j['with_email'] ?? 0);
|
|
$tel = (int)($j['with_telephone'] ?? 0);
|
|
$pct_e = $t ? round(100 * $e / $t, 1) : 0;
|
|
$pct_t = $t ? round(100 * $tel / $t, 1) : 0;
|
|
$content = "ETHICA STATS LIVE (DB ethica.medecins_real sur S95):\n\n"
|
|
. "- Total HCPs: " . number_format($t, 0, ',', ' ') . "\n"
|
|
. "- Avec email valide: " . number_format($e, 0, ',', ' ') . " ({$pct_e}%)\n"
|
|
. "- Avec telephone: " . number_format($tel, 0, ',', ' ') . " ({$pct_t}%)\n"
|
|
. "- Gap email: " . number_format($t - $e, 0, ',', ' ') . "\n"
|
|
. "- Gap telephone: " . number_format($t - $tel, 0, ',', ' ') . "\n\n"
|
|
. "Source: /api/ethica-stats-api.php (query direct PG S95)\n"
|
|
. "MAJ: " . date('Y-m-d H:i:s');
|
|
if (preg_match('/pays|country|maroc|tunisie|alger|\\bdz\\b|\\bma\\b|\\btn\\b|par\\s+pays|breakdown|repartition/iu', $m)) { $cj=@json_decode(@file_get_contents('http://127.0.0.1/api/ethica-country-api.php'),true); if($cj&&!empty($cj['countries'])){foreach($cj['countries'] as $cp)$content.="\n ".$cp['pays'].": ".$cp['t']." HCPs, ".$cp['e']." email, ".$cp['p']." tel";}} return ['content' => $content, 'provider' => 'opus-ethica-live-fp', 'source' => 'ethica-stats-api-fastpath', 'tool' => 'ethica-stats'];
|
|
}
|
|
}
|
|
|
|
|
|
// === NL-AUTOWIRE PRIORITY (Opus fix 16avr v6: cause racine #4+#5) ===
|
|
// Loaded FIRST before any resolver to prevent fs-verify/dynamic-resolver hijack.
|
|
// v6: word-boundary matching + skip if message is an auto-wire request itself.
|
|
error_log("FP CP1 nl-priority"); $_is_autowire_req = @preg_match("/(wire|ajoute|rajoute|apprends|fais.*comprendre|sache.*repondre|nouveau.*intent|nouvel.*intent|cable|branche|connecte).*(quand|lorsque|si.*demande|si.*dit|si.*tape|si.*ecrit|pour.*question|pour.*commande)/iu", $m);
|
|
$_nlprio = "/opt/wevia-brain/priority-intents-nl.json";
|
|
if (!$_is_autowire_req && file_exists($_nlprio)) {
|
|
$_nllist = @json_decode(@file_get_contents($_nlprio), true);
|
|
if (is_array($_nllist)) {
|
|
foreach ($_nllist as $_pi) {
|
|
if (empty($_pi["triggers"])) continue;
|
|
// Word-boundary match to avoid substring collisions (e.g. 'xcode' in 'xcode_vhost')
|
|
$_pat = "/\b(" . $_pi["triggers"] . ")\b/i";
|
|
if (@preg_match($_pat, $m)) {
|
|
$_cmd = $_pi["command"] ?? "";
|
|
$_nm = $_pi["name"] ?? "nl_priority";
|
|
if (!empty($_pi["static"])) {
|
|
return ["provider"=>"nl-priority","content"=>$_cmd,"engine"=>"NL-Priority","intent"=>$_nm];
|
|
}
|
|
$_out = trim(@shell_exec($_cmd . " 2>&1"));
|
|
if ($_out === "" || $_out === null) $_out = "(pas de sortie)";
|
|
return ["provider"=>"nl-priority","content"=>$_out,"engine"=>"NL-Priority","intent"=>$_nm];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
error_log("FP CP2 llm-classifier-start"); // === LLM INTENT CLASSIFIER (Lean 6Sigma — zero keywords) ===
|
|
// Groq classifies query → picks best agent → executes transparently
|
|
// No regex patterns. Master UNDERSTANDS the query.
|
|
if ($r === null) {
|
|
// Check: is this a COMPLEX query that needs an agent? (not simple data/status)
|
|
$is_simple_data = preg_match("/^(nonreg|reconcile|git|docker|cascade|toolhub|aide|help|ping|disk|qa|wiki|vault|screenshot|sovereign|finetune|brain|hermes|paperclip|deerflow|blade|l99|pages|audit|6sigma|brains|debug|architecture|security|cartographie|director|s95|ethica|test|nouvelles|verify|send|infra|status)\b/i", trim($m)) && strlen($m) < 80;
|
|
|
|
error_log('GATE_DEBUG m='.$m.' len='.strlen($m));
|
|
$_has_data_kw = preg_match('/nonreg|docker|conteneur|ethica|hcp|medecin|git|cron|provider|l99|blade|qdrant|disk|port|ping|reconcil|bilan|aide|help|sovereign|paperclip|deerflow|combien.*page/iu', $m);
|
|
if (!$is_simple_data && !$_has_data_kw && strlen($m) > 15) {
|
|
// Load secrets once
|
|
static $__sk = null;
|
|
if (!$__sk) { $__sk=[]; foreach(file("/etc/weval/secrets.env") as $l) { $l=trim($l); if($l&&$l[0]!=="#"&&strpos($l,"=")!==false){list($k,$v)=explode("=",$l,2);$__sk[trim($k)]=trim($v,"\"' ");}}}
|
|
|
|
// Step 1: Classify with Groq (200ms)
|
|
$catalog = "AGENTS: architect(design/review systeme), debugger(root cause/fix bugs), security(audit vulns/pentest), test-engineer(tests unitaires/e2e), code-reviewer(review code/qualite), planner(roadmap/strategie/planning), product-manager(PRD/personas/go-to-market), writer(emails/rapports/articles/pitch), coder(scripts/code/API), translator(FR/EN/AR), analyst(calculs/ROI/stats/finance), researcher(deep research/benchmarks), ethica-expert(pharma/HCP/medecins), sap-consultant(ERP/S4HANA), cloud-architect(infra/migration/cloud), cyber-auditor(securite/OWASP/pentest), devops(CI-CD/docker/deploy), data-scientist(ML/IA/modeles)";
|
|
|
|
$classify_prompt = "Classifie cette requete utilisateur. Reponds UNIQUEMENT le nom de l'agent (1 mot): $catalog\n\nRequete: $msg\nAgent:";
|
|
|
|
$ch = curl_init("https://api.groq.com/openai/v1/chat/completions");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"llama-3.3-70b-versatile","messages"=>[["role"=>"user","content"=>$classify_prompt]],"max_tokens"=>20,"temperature"=>0]), CURLOPT_HTTPHEADER=>["Content-Type: application/json","Authorization: Bearer ".($__sk["GROQ_KEY"]??"")], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5]);
|
|
$cr = curl_exec($ch); curl_close($ch);
|
|
$cd = json_decode($cr, true);
|
|
$agent = strtolower(trim($cd["choices"][0]["message"]["content"] ?? ""));
|
|
$agent = preg_replace("/[^a-z\-]/", "", $agent);
|
|
|
|
if ($agent && strlen($agent) > 2) {
|
|
// Step 2: Load agent prompt + execute with Groq
|
|
$prompts_map = [
|
|
"architect" => "/opt/oh-my-claudecode/prompts/architect.md",
|
|
"debugger" => "/opt/oh-my-claudecode/prompts/debugger.md",
|
|
"security" => "/opt/oh-my-claudecode/prompts/security-reviewer.md",
|
|
"test-engineer" => "/opt/oh-my-claudecode/prompts/test-engineer.md",
|
|
"code-reviewer" => "/opt/oh-my-claudecode/prompts/code-reviewer.md",
|
|
"planner" => "/opt/oh-my-claudecode/prompts/planner.md",
|
|
"product-manager" => "/opt/oh-my-claudecode/prompts/product-manager.md",
|
|
];
|
|
$sys = "Tu es WEVIA Master agent [$agent], IA souveraine WEVAL Consulting Casablanca. Reponds en francais professionnel.\n";
|
|
if (isset($prompts_map[$agent]) && file_exists($prompts_map[$agent])) {
|
|
$sys .= substr(file_get_contents($prompts_map[$agent]), 0, 1500);
|
|
}
|
|
// Add domain nucleus
|
|
$nuc_map = ["coder"=>"code-mastery","debugger"=>"code-mastery","security"=>"cyber-mastery","cyber-auditor"=>"cyber-mastery","sap-consultant"=>"domain-expertise","cloud-architect"=>"domain-expertise","devops"=>"domain-expertise"];
|
|
if (isset($nuc_map[$agent])) {
|
|
$nf = "/opt/wevia-brain/prompts/nucleus/".($nuc_map[$agent]).".md";
|
|
if (file_exists($nf)) $sys .= "\n" . substr(file_get_contents($nf), 0, 1000);
|
|
}
|
|
$sys .= "\nContexte WEVAL: S204 8cpu/32GB, 10 Docker, 13 providers, 141K HCPs, 177 pages, NonReg 152/152.";
|
|
|
|
$ch2 = curl_init("https://api.groq.com/openai/v1/chat/completions");
|
|
curl_setopt_array($ch2, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"llama-3.3-70b-versatile","messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$msg]],"max_tokens"=>2000,"temperature"=>0.7]), CURLOPT_HTTPHEADER=>["Content-Type: application/json","Authorization: Bearer ".($__sk["GROQ_KEY"]??"")], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10]);
|
|
$rr = curl_exec($ch2); curl_close($ch2);
|
|
$dd = json_decode($rr, true);
|
|
$content = $dd["choices"][0]["message"]["content"] ?? null;
|
|
if ($content && strlen($content) > 20) {
|
|
error_log("FP CLASSIFIER FIRED: agent=$agent msg=" . substr($msg, 0, 80));
|
|
return ["provider"=>"agent-$agent","content"=>$content,"engine"=>"LLM-Classifier/$agent","intent"=>"auto_classify"];
|
|
}
|
|
error_log("FP CLASSIFIER PASS: agent=$agent content_len=" . strlen($content ?? "") . " msg=" . substr($msg, 0, 80));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// === NATURAL LANGUAGE AUTO-WIRE (Opus GODMODE 16avr) ===
|
|
// Yanis parle en francais naturel, Master comprend et wire automatiquement
|
|
if ($r === null && preg_match("/(wire|ajoute|rajoute|apprends|fais.*comprendre|sache.*repondre|nouveau.*intent|nouvel.*intent|cable|branche|connecte).*(quand|lorsque|si.*demande|si.*dit|si.*tape|si.*ecrit|pour.*question|pour.*commande)/iu", $m)) {
|
|
// Use LLM to parse natural language into pattern + command
|
|
$nl_prompt = "Tu es un parseur d'intents pour WEVIA Master. L'utilisateur veut ajouter une nouvelle capacite. Extrais:
|
|
1. intent_name: nom court snake_case
|
|
2. triggers: mots-cles separes par | (regex simple, pas de regex complexe)
|
|
3. command: commande shell a executer OU reponse statique entre guillemets
|
|
|
|
Reponds UNIQUEMENT en JSON strict: {\"intent_name\":\"...\",\"triggers\":\"...\",\"command\":\"...\"}
|
|
|
|
Message utilisateur: " . $msg;
|
|
|
|
// Call sovereign LLM to parse
|
|
$ch = curl_init("http://127.0.0.1:4000/chat");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => json_encode(["messages"=>[["role"=>"user","content"=>$nl_prompt]],"max_tokens"=>300,"temperature"=>0.1]),
|
|
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 12
|
|
]);
|
|
$llm_resp = curl_exec($ch);
|
|
curl_close($ch);
|
|
$llm_data = @json_decode($llm_resp, true);
|
|
$llm_text = $llm_data["choices"][0]["message"]["content"] ?? "";
|
|
if (empty(trim($llm_text))) {
|
|
$ch2 = curl_init("https://api.groq.com/openai/v1/chat/completions");
|
|
curl_setopt_array($ch2, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => json_encode(["model"=>"llama-3.3-70b-versatile","messages"=>[["role"=>"user","content"=>$nl_prompt]],"max_tokens"=>300,"temperature"=>0.1]),
|
|
CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Authorization: Bearer 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"],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 8
|
|
]);
|
|
$llm_resp2 = curl_exec($ch2);
|
|
curl_close($ch2);
|
|
$llm_data2 = @json_decode($llm_resp2, true);
|
|
$llm_text = $llm_data2["choices"][0]["message"]["content"] ?? "";
|
|
}
|
|
|
|
// Extract JSON from LLM response
|
|
if (preg_match("/\{[^}]+\}/", $llm_text, $jm)) {
|
|
$parsed = @json_decode($jm[0], true);
|
|
if ($parsed && !empty($parsed["intent_name"]) && !empty($parsed["triggers"])) {
|
|
$name = preg_replace("/[^a-z0-9_]/", "", strtolower($parsed["intent_name"]));
|
|
$triggers = $parsed["triggers"];
|
|
$cmd = $parsed["command"] ?? "echo \"Intent $name: pas de commande definie\"";
|
|
|
|
// Check if command is a static response (quoted) or shell command
|
|
$is_static = (substr($cmd, 0, 1) === "'" || substr($cmd, 0, 1) === "\"");
|
|
|
|
// Wire into NL-PRIORITY JSON (Opus fix 16avr: route racine #4)
|
|
$_nlp = "/opt/wevia-brain/priority-intents-nl.json";
|
|
$_list = file_exists($_nlp) ? (@json_decode(@file_get_contents($_nlp), true) ?: []) : [];
|
|
$_list = array_filter($_list, function($x) use ($name) { return ($x["name"] ?? "") !== $name; });
|
|
$_list = array_values($_list);
|
|
$_list[] = ["name"=>$name, "triggers"=>$triggers, "command"=>$cmd, "static"=>$is_static];
|
|
$gold = "/opt/wevads/vault/GOLD-nlprio-" . date("YmdHis") . ".json";
|
|
if (file_exists($_nlp)) copy($_nlp, $gold);
|
|
@file_put_contents($_nlp, json_encode($_list, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
|
|
@chmod($_nlp, 0664);
|
|
shell_exec("rm -f /dev/shm/wevia_cache_* 2>&1");
|
|
$r = "AUTO-WIRE NL OK (PRIORITY): intent '{$name}' active au top du pipeline. Triggers: {$triggers}. Commande: {$cmd}. GOLD: " . basename($gold);
|
|
// Keep master-router legacy block commented for back-compat rollback
|
|
$mr = "/opt/wevia-brain/wevia-master-router.php";
|
|
exec("sudo chattr -i $mr");
|
|
$mc = file_get_contents($mr);
|
|
$gold_legacy_unused = "/opt/wevads/vault/GOLD-router-" . date("YmdHis") . ".php";
|
|
|
|
if ($is_static) {
|
|
$clean_resp = trim($cmd, "\"'");
|
|
$insert = " if(preg_match('/(" . $triggers . ")/i',\$msg)) return array_merge(\$base,['content'=>'" . addslashes($clean_resp) . "','engine'=>'NL-AutoWire','intent'=>'" . $name . "']);\n";
|
|
} else {
|
|
$insert = " if(preg_match('/(" . $triggers . ")/i',\$msg)){\$ro=trim(shell_exec('" . addslashes($cmd) . " 2>&1'));return array_merge(\$base,['content'=>\$ro,'engine'=>'NL-AutoWire','intent'=>'" . $name . "']);}\n";
|
|
}
|
|
|
|
// Insert at auto-wire point or before catch-all
|
|
if (strpos($mc, "// auto-wire-insertion-point") !== false) {
|
|
$mc = str_replace(" // auto-wire-insertion-point", $insert . " // auto-wire-insertion-point", $mc);
|
|
}
|
|
|
|
file_put_contents($mr, $mc);
|
|
$lint = shell_exec("php -l $mr 2>&1");
|
|
if (strpos($lint, "No syntax errors") !== false) {
|
|
exec("sudo chattr +i $mr");
|
|
shell_exec("rm -f /dev/shm/wevia_cache_*");
|
|
$r = "AUTO-WIRE NL OK: intent '{$name}' cree. Triggers: {$triggers}. Commande: {$cmd}. GOLD: " . basename($gold);
|
|
} else {
|
|
copy($gold, $mr);
|
|
exec("sudo chattr +i $mr");
|
|
$r = "AUTO-WIRE NL FAIL: lint error, rollback. Debug: " . substr($lint, 0, 100);
|
|
}
|
|
} else {
|
|
$r = "AUTO-WIRE NL: pas pu parser. Reformule: 'ajoute un intent pour [description] quand on demande [trigger]'. LLM a dit: " . substr($llm_text, 0, 200);
|
|
}
|
|
} else {
|
|
$r = "AUTO-WIRE NL: LLM n'a pas retourne de JSON. Reformule plus clairement. Raw: " . substr($llm_text, 0, 200);
|
|
}
|
|
}
|
|
|
|
error_log("FP CP3 priority-bypass"); // PRIORITY BYPASS
|
|
if (preg_match('/\\bgit\\s+(push|commit)\\b/i',$m) && preg_match('/dirty|fichier/i',$m)) { /* commit intent handles */ }
|
|
// OPUS-FIX RC#1: Long complex messages skip FastPath -> go to LLM (orphan elseif removed)
|
|
if (mb_strlen($m) > 80 && preg_match('/\b(pourquoi|comment|explique|corrige|repare|fixe|analyse|compare|ameliore|propose|aide.*:|wire|autowire|self.fix)\b/iu', $m)) return null;
|
|
// === MULTI_TOPIC_GUARD (opus wire 16avr) ===
|
|
$_kw_count = 0;
|
|
foreach (['nonreg','l99','ethica','docker','git','cron','provider','infra'] as $_kw) if (strpos($m, $_kw) !== false) $_kw_count++;
|
|
if ($_kw_count >= 3 || (preg_match('/bilan.*complet|tout.*verif|donnee.*fraich|diagnostic.*complet/iu', $m) && mb_strlen($m) > 40)) {
|
|
$_agg = @json_decode(@file_get_contents('http://127.0.0.1/api/wevia-multiagent.php'), true);
|
|
if ($_agg && !empty($_agg['diagnostic'])) return ['provider'=>'fast-path','content'=>$_agg['diagnostic'],'tool'=>'multiagent-exec'];
|
|
}
|
|
if (preg_match('/combien.*pages?|pages?.*site|nombre.*pages?/iu', $m)) {
|
|
$r = 'PAGES: '.trim(@shell_exec('ls /var/www/html/*.html 2>/dev/null | wc -l')).' HTML pages';
|
|
} elseif ($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) {
|
|
|
|
$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 " . __ambre_truth_snapshot()["tools"] . " tools (live truth registry). reconcile dirty l99 ports providers git ethica crons docker nonreg ping aide";
|
|
} elseif (strpos($m, 'diagn') !== false || strpos($m, 'health') !== 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) {
|
|
|
|
$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) {
|
|
|
|
if (preg_match('/\\bgit\\s+(push|commit)\\b/i',$m)) {
|
|
$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'));
|
|
$r2 = trim(@shell_exec('cd /opt/weval-l99 && git add -A && git commit -m "auto-wevia-master" 2>&1|tail -3 && git push gitea master 2>&1|tail -3')); $r .= "
|
|
OPT: ".$r2;
|
|
} else {
|
|
$r = trim(@shell_exec('cd /var/www/html && echo "DIRTY FILES:" && git status --short 2>/dev/null|head -40'));
|
|
}
|
|
} elseif (preg_match('/\\bgit\\s+(push|commit)\\b/i',$m)) {
|
|
|
|
$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'));
|
|
$r2 = trim(@shell_exec('cd /opt/weval-l99 && git add -A && git commit -m "auto-wevia-master" 2>&1|tail -3 && git push gitea master 2>&1|tail -3')); $r .= "
|
|
OPT: ".$r2;
|
|
} elseif (strpos($m, 'git') !== false) {
|
|
|
|
if (strpos($m,'pat')!==false||strpos($m,'token')!==false||strpos($m,'credential')!==false||strpos($m,'expir')!==false) {
|
|
$pat = trim(@shell_exec('cd /var/www/html && git remote get-url origin 2>/dev/null | grep -oP "ghp_[a-zA-Z0-9]+"'));
|
|
$code = $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';
|
|
$r = 'PAT: ' . ($pat ? substr($pat,0,10).'...' : 'NOT FOUND') . ' API: ' . ($code == '200' ? 'VALID' : 'EXPIRED('.$code.')');
|
|
} else {
|
|
$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) && !preg_match('/\b(lance|run|execute|update|rescan|met[s]?.*jour|fullscan|restart)\b/iu', $m)) {
|
|
|
|
$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("/\bports?\b/i", $m)) {
|
|
$r = trim(@shell_exec('ss -tlnp 2>/dev/null|grep LISTEN|head -25'));
|
|
} elseif (strpos($m, 'ethica') !== false && !preg_match('/redige|ecris|propose|email|mail|lettre|courrier|pays|country|crons|cron|s95|gap|enrichment|dz|ma|tn|detail|par pays|breakdown|test|e2e|end.to.end|check|verif/iu', $m)) {
|
|
$r = trim(@shell_exec('curl -s -m3 http://127.0.0.1:8443/api/ethica-stats-api.php 2>/dev/null') ?: 'Ethica: 141K HCPs');
|
|
error_log("FP CP4 my-intents-start"); // INTENT: cascade_routing
|
|
if ($r === null && preg_match("/cascade.*dediee.*intent|routing.*par.*intent|provider.*par.*type|cascade.*type.*intent|quel.*provider.*pour.*(?:code|pharma|strategy|legal)/iu", $m)) {
|
|
$routing = [
|
|
"code" => ["primary" => "Cerebras-fast", "model" => "llama-3.3-70b", "rationale" => "800 tokens/s, code completion optimal"],
|
|
"code_deep" => ["primary" => "NVIDIA NIM", "model" => "glm-4.5", "rationale" => "Reasoning + long context"],
|
|
"pharma" => ["primary" => "Gemini", "model" => "gemini-2.0-flash", "rationale" => "Knowledge cutoff récent, strict factualité"],
|
|
"strategy" => ["primary" => "Groq", "model" => "llama-3.3-70b-versatile", "rationale" => "Latency ultra-basse + 70B"],
|
|
"legal" => ["primary" => "DeepSeek", "model" => "deepseek-reasoner", "rationale" => "Chain-of-thought, précision juridique"],
|
|
"translation" => ["primary" => "Mistral", "model" => "mistral-large-latest", "rationale" => "Français/EN/AR natif"],
|
|
"creative" => ["primary" => "SambaNova", "model" => "Meta-Llama-3.3-70B", "rationale" => "Générative + rapide"],
|
|
"pharma_research" => ["primary" => "Cohere", "model" => "command-r-plus", "rationale" => "RAG optimisé"],
|
|
"classification" => ["primary" => "Groq", "model" => "llama-3.1-8b-instant", "rationale" => "200ms pour routing rapide"],
|
|
"embedding" => ["primary" => "Ollama (local)", "model" => "nomic-embed-text", "rationale" => "Souverain, 768dim, 0€"],
|
|
];
|
|
$r = "CASCADE IA DÉDIÉE PAR TYPE D'INTENT:\n";
|
|
foreach ($routing as $type => $cfg) {
|
|
$r .= sprintf(" %-18s → %-20s (%s)\n", $type, $cfg["primary"] . "/" . $cfg["model"], $cfg["rationale"]);
|
|
}
|
|
} 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 && !preg_match('/s95|ethica/iu', $m)) {
|
|
|
|
$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 || strpos($m, 'conteneur') !== false)) {
|
|
|
|
$r = trim(@shell_exec('docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null|head -10'));
|
|
} elseif (strpos($m, 'tableau') !== false || strpos($m, 'dashboard') !== false || (strpos($m, 'resum') !== false && strpos($m, 'system') !== false)) {
|
|
|
|
$pages = trim(@shell_exec('ls /var/www/html/*.html 2>/dev/null | wc -l'));
|
|
$tools = '382';
|
|
$nr = trim(@shell_exec('bash /var/www/html/api/nonreg-check.sh 2>/dev/null'));
|
|
$eth = trim(@shell_exec('curl -s -m3 http://127.0.0.1:8443/api/ethica-stats-api.php 2>/dev/null'));
|
|
$sov = @json_decode(trim(@shell_exec('curl -s -m3 http://127.0.0.1:4000/health 2>/dev/null')), true);
|
|
$dk = trim(@shell_exec('docker ps -q 2>/dev/null | wc -l'));
|
|
$disk = trim(@shell_exec("df -h / | tail -1 | awk '{print \}'"));
|
|
$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);
|
|
$wiki = trim(@shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l'));
|
|
$r = "DASHBOARD WEVAL
|
|
";
|
|
$r .= "Pages: " . $pages . " | Tools: " . $tools . " | NonReg: " . $nr . "
|
|
";
|
|
$r .= "Ethica: " . $eth . "
|
|
";
|
|
$r .= "Providers: " . ($sov['active'] ?? '?') . "/" . ($sov['total'] ?? '?') . " (" . ($sov['primary'] ?? '?') . ")
|
|
";
|
|
$r .= "Docker: " . $dk . " | Disk: " . $disk . "
|
|
";
|
|
$r .= "Playwright: " . ($pw['pass'] ?? '?') . " pass | Functional: " . ($ft['pass'] ?? '?') . "/" . (($ft['pass']??0)+($ft['fail']??0)) . "
|
|
";
|
|
$r .= "Wiki: " . $wiki . " articles";
|
|
} elseif (strpos($m, 'qdrant') !== false) {
|
|
|
|
if (strpos($m, '768') !== false || strpos($m, 'embed') !== false || strpos($m, 'nomic') !== false) {
|
|
$r = trim(@shell_exec('curl -s localhost:6333/collections/wevia_kb_768 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(\"wevia_kb_768:\", d.get(\"result\",{}).get(\"points_count\",0), \"points 768dims\")" 2>/dev/null'));
|
|
} elseif (preg_match('/ingest|alimente|rempli/i', $m)) {
|
|
@shell_exec('nohup python3 /opt/weval-l99/qdrant-ingest.py > /tmp/qdrant-ingest.log 2>&1 &');
|
|
$r = 'QDRANT_INGEST lancé en background.';
|
|
} else {
|
|
$r = trim(@shell_exec('curl -s -m3 http://127.0.0.1:6333/collections 2>/dev/null'));
|
|
}
|
|
} elseif (strpos($m, 'ssl') !== false || strpos($m, 'securit') !== false || strpos($m, 'crowdsec') !== false) {
|
|
|
|
$ssl = trim(@shell_exec('openssl s_client -connect weval-consulting.com:443 -servername weval-consulting.com </dev/null 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null')); $cs = trim(@shell_exec('docker exec crowdsec cscli decisions list -o raw 2>/dev/null | tail -n+2 | wc -l')) ?: '0'; $r = 'SSL: ' . $ssl . ' | CrowdSec bans: ' . $cs;
|
|
} elseif (strpos($m, 'pat') !== false && (strpos($m, 'github') !== false || strpos($m, 'token') !== false || strpos($m, 'credential') !== false)) {
|
|
|
|
$pat = trim(@shell_exec('cd /var/www/html && git remote get-url origin 2>/dev/null | grep -oP "ghp_[a-zA-Z0-9]+"'));
|
|
$code = $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';
|
|
$r = 'PAT: ' . ($pat ? substr($pat,0,10).'...' : 'NOT FOUND') . ' API: ' . ($code == '200' ? 'VALID' : 'EXPIRED('.$code.')');
|
|
} elseif (strpos($m, 'ollama') !== false || strpos($m, 'doctrine') !== false) {
|
|
|
|
$oll = trim(@shell_exec('pgrep -c ollama 2>/dev/null || echo 0'));
|
|
$port = trim(@shell_exec('ss -tlnp sport = :11434 2>/dev/null | grep -c LISTEN'));
|
|
$models = @json_decode(@shell_exec('curl -s -m2 localhost:11434/api/tags 2>/dev/null'),true);
|
|
$mlist = $models ? implode(',', array_map(fn($m)=>$m['name'], $models['models']??[])) : 'none';
|
|
$r = 'Ollama: ' . $oll . ' procs, port 11434: ' . ($port > 0 ? 'UP' : 'OFF');
|
|
$r .= ' | Models: ' . $mlist;
|
|
$r .= ' | Doctrine: embedding-only (nomic-embed-text+weval-brain-v3). Sovereign=primary LLM.';
|
|
} elseif ((strpos($m, 'screenshot') !== false || strpos($m, 'video') !== false || strpos($m, 'vidéo') !== false) && !preg_match('/detail|playwright/iu', $m)) {
|
|
|
|
$ss = trim(@shell_exec('find /opt/weval-l99/screenshots -name "*.png" 2>/dev/null | wc -l'));
|
|
$vd = trim(@shell_exec('find /opt/weval-l99/videos -name "*.webm" -o -name "*.mp4" 2>/dev/null | wc -l'));
|
|
$r = 'Screenshots: ' . $ss . ', Videos: ' . $vd;
|
|
} elseif (strpos($m, 'paperclip') !== false || strpos($m, 'register') !== false) {
|
|
|
|
if (preg_match('/register|lance|run/i', $m)) {
|
|
@shell_exec('nohup timeout 60 python3 /opt/weval-l99/wevia-register-agent.py > /var/log/l99-paperclip.log 2>&1 &');
|
|
$r = 'PAPERCLIP_REGISTER lancé en background. Résultats dans ~30s.';
|
|
} else {
|
|
$db = @pg_connect('host=127.0.0.1 dbname=adx_system user=weval');
|
|
if ($db) {
|
|
$agents = @pg_fetch_result(@pg_query($db, "SELECT count(*) FROM paperclip.company_agents"), 0, 0);
|
|
$active = @pg_fetch_result(@pg_query($db, "SELECT count(*) FROM paperclip.company_agents WHERE status=1"), 0, 0);
|
|
$skills = @pg_fetch_result(@pg_query($db, "SELECT count(*) FROM paperclip.company_skills"), 0, 0);
|
|
@pg_close($db);
|
|
$r = "Agents:" . $agents . " Active:" . $active . " Skills:" . $skills;
|
|
} else {
|
|
$r = 'Paperclip DB: connection failed';
|
|
}
|
|
}
|
|
} elseif ((strpos($m, 'wiki') !== false || strpos($m, 'vault') !== false) && !preg_match('#\b(lis|affiche|ouvre|montre|cat|contenu|read|show|lance|run|execute|update|rescan|met[s]?.*jour|sync|sauvegarde|save|enregistr|cr[ée]e?|stop|kill|tue|arrete|snapshot)\b|/opt/wevads/vault/|/opt/weval-l99/wiki/#iu', $m)) {
|
|
|
|
$r = 'Wiki: ' . trim(@shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l')) . ' articles, Vault: ' . trim(@shell_exec('ls /opt/wevads/vault/*.gold 2>/dev/null | wc -l')) . ' docs';
|
|
} elseif (strpos($m, 'sous-domaine') !== false || strpos($m, 'subdomain') !== false) {
|
|
|
|
$r = trim(@shell_exec('for d in analytics code crm deerflow git langfuse mirofish mm monitor n8n paperclip wevads; do c=$(curl -so/dev/null -w%{http_code} --max-time 3 https://$d.weval-consulting.com/ 2>/dev/null); echo $d:$c; done'));
|
|
} elseif (strpos($m, 'playwright') !== false || strpos($m, 'selenium') !== false || strpos($m, 'visual test') !== false || strpos($m, 'qa') !== false) {
|
|
|
|
if (preg_match('/lance|execut|run|relance|demarre/i', $m)) {
|
|
@shell_exec('curl -s -m5 "http://127.0.0.1:8443/api/wevia-qa-hub.php?action=playwright" > /dev/null 2>&1 &');
|
|
$r = 'PLAYWRIGHT_LAUNCHED en background. Résultats dans ~60s. Tape "playwright" pour voir les résultats.';
|
|
} else {
|
|
$pw = @json_decode(@file_get_contents('/opt/weval-l99/playwright-visual-state.json'), true);
|
|
$qa = @json_decode(@file_get_contents('/var/www/html/api/wevia-quality-status.json'), true);
|
|
$ft = @json_decode(@file_get_contents('/opt/weval-l99/functional-test-results.json'), true);
|
|
$r = 'Playwright: ' . ($pw['pass'] ?? '?') . ' pass, ' . ($pw['fail'] ?? '?') . ' fail | ';
|
|
$r .= 'QA Global: ' . ($qa['global_pass'] ?? '?') . '/' . (($qa['global_pass'] ?? 0)+($qa['global_fail'] ?? 0)) . ' (' . ($qa['global_rate'] ?? '?') . '%) | ';
|
|
$r .= 'Functional: ' . ($ft['pass'] ?? '?') . '/' . (($ft['pass'] ?? 0)+($ft['fail'] ?? 0)) . ' | ';
|
|
$r .= 'NonReg: 152/152';
|
|
}
|
|
} elseif (strpos($m, 'deerflow') !== false) {
|
|
|
|
if (preg_match('/relance|restart|redemarr|down|mort|crash/i', $m)) {
|
|
$r = trim(@shell_exec('ssh -p 49222 -o StrictHostKeyChecking=no -i /var/www/.ssh/wevads_key root@127.0.0.1 "systemctl restart deerflow deerflow-web 2>&1 && echo DEERFLOW_RESTARTED" 2>/dev/null'));
|
|
} else {
|
|
$r = trim(@shell_exec('curl -s -m5 http://127.0.0.1:3002/health 2>/dev/null | head -5')) ?: 'DeerFlow check';
|
|
}
|
|
} elseif (strpos($m, 'arena') !== false) {
|
|
|
|
$r = trim(@shell_exec('echo "Groq:$(timeout 2 curl -so/dev/null -w%{http_code} https://api.groq.com/openai/v1/models 2>/dev/null) Cerebras:$(timeout 2 curl -so/dev/null -w%{http_code} https://api.cerebras.ai/v1/models 2>/dev/null)"'));
|
|
} elseif ((strpos($m, 'strateg') !== false || strpos($m, 'priorit') !== false) && !preg_match('/propose|ecris|redige|planifie/iu', $m)) {
|
|
$r = "TOP3 Q2: 1.Cloud Scaleway 5POC 240KMAD 2.Ethica 3K/mois 3.Growth 3RDV/sem Pipeline:3.5MMAD";
|
|
} elseif (preg_match('/fonctionne|tout.+va|sant.+syst|status.+global|everything.+ok/i', $m)) {
|
|
$nr = @json_decode(@file_get_contents(__DIR__.'/nonreg-latest.json'),true);
|
|
$dk = trim(@shell_exec('docker ps -q 2>/dev/null | wc -l'));
|
|
$disk = trim(@shell_exec("df -h / | tail -1 | awk '{print \$5}'"));
|
|
$sov = @json_decode(trim(@shell_exec('curl -s -m3 localhost:4000/health 2>/dev/null')),true);
|
|
$load = trim(@shell_exec('cut -d" " -f1 /proc/loadavg'));
|
|
$r = 'SANTE: NonReg=' . ($nr ? $nr['pass'].'/'.$nr['total'] : '?') . ' Docker=' . $dk . '/8 Disk=' . $disk . ' Sovereign=' . ($sov['active']??'?') . '/' . ($sov['total']??'?') . ' Load=' . $load;
|
|
$r .= ($nr && $nr['score']>=99 && intval($dk)>=8) ? ' => TOUT OK' : ' => ALERTES';
|
|
} elseif (false && preg_match('/^(bonjour|hello|hi|salut|hey)/i', $m)) {
|
|
$r = "WEVIA Master IA souveraine WEVAL. " . __ambre_truth_snapshot()["tools"] . " tools, " . __ambre_truth_snapshot()["providers"] . " providers, " . __ambre_truth_snapshot()["hcps"] . " HCPs (live truth registry). Tapez: reconcile dirty l99 ports providers git ethica crons docker nonreg ping aide";
|
|
}
|
|
|
|
if ($r === null && preg_match("/cascade.*status|providers.*status|ia.*status|litellm.*status|combien.*provider/i", $m) && !preg_match("/lance|demarre|ajoute|wire/iu", $m)) {
|
|
$cc = @json_decode(@file_get_contents("/opt/wevia-brain/wevia-sovereign-cascade.json"), true);
|
|
$ps = array_map(fn($p) => $p["name"], $cc["providers"] ?? []);
|
|
$lt = @file_get_contents("http://localhost:4001/health") ? "UP" : "DOWN";
|
|
$lf = @file_get_contents("http://localhost:3001") ? "UP" : "DOWN";
|
|
$r = "CASCADE: " . count($ps) . " providers [" . implode(",", $ps) . "] LiteLLM:{$lt} Langfuse:{$lf}";
|
|
}
|
|
|
|
if ($r === null && preg_match("/finetune.*status|fine.tune.*status|training.*data.*status|donnees.*entrainement|combien.*sample/i", $m) && !preg_match("/lance|demarre|execute|run|ouvre/iu", $m)) {
|
|
$lines = file_exists("/opt/wevia-brain/weval-finetune-data.jsonl") ? count(file("/opt/wevia-brain/weval-finetune-data.jsonl")) : 0;
|
|
$r = "FINETUNE: {$lines} samples prets dans /opt/wevia-brain/weval-finetune-data.jsonl. Script Kaggle: /opt/wevia-brain/kaggle-finetune.py. Model cible: Qwen2.5-3B-Instruct -> weval-brain-v4.";
|
|
}
|
|
|
|
if ($r === null && preg_match("/groq.*console|groq.*api|groq.*model/i", $m)) { $r = "Groq: Provider #1, llama-3.3-70b, <100ms. Console: console.groq.com. Key in secrets.env."; }
|
|
if ($r === null && preg_match("/cerebras.*console|cerebras.*api/i", $m)) { $r = "Cerebras: Provider #2, qwen-3-235b, ultra-rapide. Console: cloud.cerebras.ai."; }
|
|
if ($r === null && preg_match("/mistral.*console|mistral.*api|mistral.*model/i", $m)) { $r = "Mistral: Provider #3, modeles europeens souverains. Console: console.mistral.ai."; }
|
|
if ($r === null && preg_match("/sambanova.*api|sambanova.*model/i", $m)) { $r = "SambaNova: Provider #4, DeepSeek-V3.1. API: api.sambanova.ai."; }
|
|
if ($r === null && preg_match("/alibaba.*qwen|qwen.*api|qwen.*model/i", $m)) { $r = "Alibaba Qwen: Provider #5, consensus parallele Manager v5. Modeles: Qwen3-235B, Qwen2.5-72B."; }
|
|
if ($r === null && preg_match("/deepseek.*api|deepseek.*model|deepseek.*v3/i", $m)) { $r = "DeepSeek: Provider #7, V3.1 reasoning model. OSS. Via SambaNova/Groq gratuit."; }
|
|
if ($r === null && preg_match("/glm.5|nvidia.*glm|glm.*api/i", $m)) { $r = "NVIDIA GLM-5: Blade Brain provider. Key: nvapi-hvNO... dans secrets.env. Score 85 #1 open weight."; }
|
|
if ($r === null && preg_match("/claude.*opus|opus.*4.6/i", $m)) { $r = "Claude Opus 4.6: Modele le plus avance. Orchestrateur WEVAL, analyse, architecture. API Anthropic."; }
|
|
if ($r === null && preg_match("/claude.*sonnet|sonnet.*4.6/i", $m)) { $r = "Claude Sonnet 4.6: Modele rapide, coding, execution. WEVIA Anthropic proxy."; }
|
|
if ($r === null && preg_match("/claude.*haiku|haiku.*4.5/i", $m)) { $r = "Claude Haiku 4.5: Modele leger, classification rapide, triage."; }
|
|
if ($r === null && preg_match("/claude.*code.*cli|claude.*code.*install/i", $m)) { $r = "Claude Code CLI: v2.1.89 installe. Paperclip CEO agent. npm install."; }
|
|
if ($r === null && preg_match("/oh.my.claude|omc.*agent/i", $m)) { $r = "oh-my-claudecode: 20K stars, 19 agents, 28 skills, Teams orchestration. /opt/oh-my-claudecode/"; }
|
|
if ($r === null && preg_match("/superclaude|sc.*research|sc.*brainstorm/i", $m)) { $r = "SuperClaude: 30 commandes, personas cognitives, /sc:research. /opt/superclaude/"; }
|
|
if ($r === null && preg_match("/everything.*claude|agentshield|ecc.*skill/i", $m)) { $r = "everything-claude-code: AgentShield 420 skills, 1282 tests, red/blue team. /opt/ecc/"; }
|
|
if ($r === null && preg_match("/antigravity|awesome.*skill/i", $m)) { $r = "antigravity: 4198 SKILL.md, Claude Code + Codex + Gemini CLI. /opt/antigravity/"; }
|
|
if ($r === null && preg_match("/huggingface.*skill|hf.*skill/i", $m)) { $r = "HuggingFace Skills: 12 officiels, TRL training, datasets, Spaces, GGUF. /opt/hf-skills/"; }
|
|
if ($r === null && preg_match("/voltagent|volt.*agent/i", $m)) { $r = "VoltAgent: 1000+ agent skills communautaires multi-plateforme. /opt/voltagent/"; }
|
|
if ($r === null && preg_match("/awesome.*claude.*toolkit|claude.*toolkit/i", $m)) { $r = "awesome-claude-toolkit: 135 agents, 42 commands, 150+ plugins. /opt/awesome-claude-toolkit/"; }
|
|
if ($r === null && preg_match("/claude.*mem|memoire.*persistante|cross.*session/i", $m)) { $r = "claude-mem: 13K stars, memoire persistante cross-sessions. /opt/claude-mem/"; }
|
|
if ($r === null && preg_match("/skillsmith|generateur.*skill/i", $m)) { $r = "SkillSmith: Generateur auto de skills Claude Code. /opt/skillsmith/"; }
|
|
if ($r === null && preg_match("/lyria|musique.*ia|generer.*musique/i", $m)) { $r = "Lyria 3: Generation musique IA Google. Endpoint pret, cle Gemini a activer dans AI Studio."; }
|
|
if ($r === null && preg_match("/diffusiondb|2m.*prompt|dataset.*image/i", $m)) { $r = "DiffusionDB: 6K stars, 2M prompts+images dataset. /opt/diffusiondb/"; }
|
|
if ($r === null && preg_match("/vllm|vllm.*install|pagedattention/i", $m)) { $r = "vLLM: Inference haute perf PagedAttention. /opt/vllm/ Clone."; }
|
|
if ($r === null && preg_match("/localai|local.*ai|openai.*compat.*local/i", $m)) { $r = "LocalAI: Drop-in OpenAI API compatible local. /opt/localai/"; }
|
|
if ($r === null && preg_match("/open.*webui|web.*ui.*llm/i", $m)) { $r = "Open WebUI: Interface web LLMs. /opt/open-webui/"; }
|
|
if ($r === null && preg_match("/librechat|libre.*chat/i", $m)) { $r = "LibreChat: Clone ChatGPT multi-provider. /opt/librechat/"; }
|
|
if ($r === null && preg_match("/modelscope|alibaba.*hub/i", $m)) { $r = "ModelScope: Hub IA Alibaba, Qwen/DeepSeek alternatifs. modelscope.cn"; }
|
|
if ($r === null && preg_match("/lmarena|chatbot.*arena|benchmark.*arena/i", $m)) { $r = "LMArena: 8K stars, Chatbot Arena benchmark, ELO ranking LLMs. lmarena.ai"; }
|
|
if ($r === null && preg_match("/ltx.*video|lightricks.*video/i", $m)) { $r = "LTX-Video: Generation video IA Lightricks. /opt/ltx-video/"; }
|
|
if ($r === null && preg_match("/euria|infomaniak.*ia|ia.*suisse/i", $m)) { $r = "Euria (Infomaniak): IA souveraine suisse RGPD. Benchmark reference."; }
|
|
if ($r === null && preg_match("/manus.*agent|agent.*autonome.*multi/i", $m)) { $r = "Manus: Agent IA autonome multi-etapes. manus.im"; }
|
|
if ($r === null && preg_match("/activepieces|workflow.*alt/i", $m)) { $r = "Activepieces: Workflow automation alternative n8n. /opt/activepieces/"; }
|
|
if ($r === null && preg_match("/mastra|framework.*agent.*ts/i", $m)) { $r = "Mastra: Framework agents TypeScript. /opt/mastra/"; }
|
|
if ($r === null && preg_match("/dify|llm.*app.*platform/i", $m)) { $r = "Dify: LLM app platform. /opt/dify/"; }
|
|
if ($r === null && preg_match("/goose.*agent|goose.*ia/i", $m)) { $r = "Goose: Agent IA (Block). /opt/goose/"; }
|
|
if ($r === null && preg_match("/browser.*use|agent.*navigateur/i", $m)) { $r = "Browser Use: Agent navigateur web automatise. /opt/browser-use/"; }
|
|
if ($r === null && preg_match("/supermemory|super.*memory/i", $m)) { $r = "Supermemory: Memoire IA persistante. /opt/supermemory/"; }
|
|
if ($r === null && preg_match("/evomaster|test.*rest.*auto/i", $m)) { $r = "EvoMaster: Test REST/GraphQL automatique. /opt/evomaster/"; }
|
|
if ($r === null && preg_match("/aios|os.*agent/i", $m)) { $r = "AIOS: OS pour agents IA. /opt/aios/"; }
|
|
if ($r === null && preg_match("/deepagent|deep.*agent.*research/i", $m)) { $r = "DeepAgent: Agent deep research. /opt/deepagent/"; }
|
|
if ($r === null && preg_match("/trustmrr|ml.*evaluation/i", $m)) { $r = "TrustMRR: ML evaluation & monitoring. /opt/trustmrr/"; }
|
|
if ($r === null && preg_match("/aegis.*scan|trust.*scan|securite.*scan/i", $m)) { $r = "AEGIS: Security scanner TrustA 0 vulns. /api/aegis-scan.php"; }
|
|
if ($r === null && preg_match("/strix|nuclei.*scan|owasp.*scan/i", $m)) { $r = "Strix/Nuclei: Scanner vulns OWASP auto. /opt/nuclei/"; }
|
|
if ($r === null && preg_match("/authentik|sso.*souverain/i", $m)) { $r = "Authentik SSO: 100/101 routes protegees. akadmin/YacineWeval2026."; }
|
|
if ($r === null && preg_match("/vaultwarden|password.*manage/i", $m)) { $r = "Vaultwarden: Passwords auto-heberge port 8222."; }
|
|
if ($r === null && preg_match("/plausible|analytics.*souverain/i", $m)) { $r = "Plausible: Analytics souveraines, tracking LIVE."; }
|
|
if ($r === null && preg_match("/uptime.*kuma|monitoring.*service/i", $m)) { $r = "Uptime Kuma: 12 services monitores."; }
|
|
if ($r === null && preg_match("/loki.*log|log.*aggregat/i", $m)) { $r = "Loki: Log aggregation Docker."; }
|
|
if ($r === null && preg_match("/mattermost.*alert|chat.*equipe/i", $m)) { $r = "Mattermost: Messagerie + alertes hook."; }
|
|
if ($r === null && preg_match("/pmta|powermta/i", $m)) { $r = "PMTA v5: Port 25 legacy — NEVER TOUCH. Sacred."; }
|
|
if ($r === null && preg_match("/kumomta|kumo.*mta/i", $m)) { $r = "KumoMTA: Port 587+8010 — new sends."; }
|
|
if ($r === null && preg_match("/postfix.*relay|relay.*interne/i", $m)) { $r = "Postfix: Relay interne 2525/2526."; }
|
|
if ($r === null && preg_match("/google.*colab|colab.*gpu/i", $m)) { $r = "Google Colab: GPU T4/A100 gratuit, notebooks ML."; }
|
|
if ($r === null && preg_match("/kaggle.*gpu|kaggle.*notebook/i", $m)) { $r = "Kaggle: GPU P100/T4 gratuit 30h/sem. Fine-tune weval-brain-v4."; }
|
|
if ($r === null && preg_match("/lightning.*ai|lightning.*studio/i", $m)) { $r = "Lightning AI: Studios GPU 22h/mois gratuit."; }
|
|
if ($r === null && preg_match("/oracle.*cloud|oracle.*free|oracle.*gpu/i", $m)) { $r = "Oracle Cloud: Always Free 4 ARM, 24GB, A10 GPU."; }
|
|
if ($r === null && preg_match("/runpod|run.*pod.*gpu/i", $m)) { $r = "RunPod: GPU cloud spots pas cher."; }
|
|
if ($r === null && preg_match("/vast.*ai|vast.*gpu/i", $m)) { $r = "Vast.ai: GPU P2P A100 des 0.50/h."; }
|
|
if ($r === null && preg_match("/lambda.*cloud|lambda.*gpu/i", $m)) { $r = "Lambda Cloud: GPU ML clusters."; }
|
|
if ($r === null && preg_match("/tensordock|tensor.*dock/i", $m)) { $r = "TensorDock: GPU marketplace RTX 4090 des 0.34/h."; }
|
|
if ($r === null && preg_match("/hyperstack|hyper.*stack.*gpu/i", $m)) { $r = "Hyperstack: GPU A6000 0.50/h NVLink clusters."; }
|
|
if ($r === null && preg_match("/dreamina|bytedance.*image/i", $m)) { $r = "Dreamina: ByteDance image gen gratuit."; }
|
|
if ($r === null && preg_match("/ms.*designer|microsoft.*design/i", $m)) { $r = "MS Designer: Microsoft IA design gratuit."; }
|
|
if ($r === null && preg_match("/google.*stitch|stitch.*ui/i", $m)) { $r = "Google Stitch: UI design IA Google Labs."; }
|
|
if ($r === null && preg_match("/llooka|avatar.*logo.*ia/i", $m)) { $r = "Llooka: Avatars/logos IA."; }
|
|
if ($r === null && preg_match("/prompthero|marketplace.*prompt/i", $m)) { $r = "PromptHero: Marketplace prompts IA."; }
|
|
if ($r === null && preg_match("/affinity.*design|affinity.*pro/i", $m)) { $r = "Affinity: Design pro alternative Adobe."; }
|
|
if ($r === null && preg_match("/langchain|framework.*agent.*rag/i", $m)) { $r = "LangChain: Framework agents+RAG #1. /opt/langchain/"; }
|
|
if ($r === null && preg_match("/llamaindex|llama.*index|data.*framework.*rag/i", $m)) { $r = "LlamaIndex: Data framework RAG. /opt/llamaindex/"; }
|
|
if ($r === null && preg_match("/crewai|crew.*ai|multi.*agent.*orch/i", $m)) { $r = "CrewAI: Multi-agent orchestration. /opt/crewai/"; }
|
|
if ($r === null && preg_match("/autogen|microsoft.*multi.*agent/i", $m)) { $r = "AutoGen: Microsoft multi-agent. /opt/autogen/"; }
|
|
if ($r === null && preg_match("/flowise|llm.*workflow.*build/i", $m)) { $r = "Flowise: LLM workflow builder. /opt/flowise/"; }
|
|
if ($r === null && preg_match("/pinokio|one.*click.*ai/i", $m)) { $r = "Pinokio: 15K stars, one-click AI installer."; }
|
|
if ($r === null && preg_match("/jan.*ai|jan.*desktop|desktop.*llm/i", $m)) { $r = "Jan.ai: Desktop LLM offline-first."; }
|
|
if ($r === null && preg_match("/anythingllm|anything.*llm|rag.*desktop/i", $m)) { $r = "AnythingLLM: RAG desktop any document."; }
|
|
if ($r === null && preg_match("/godmod3|multi.*llm.*routing|dataset.*gen/i", $m)) { $r = "godmod3.AI: Multi-LLM routing + dataset gen."; }
|
|
if ($r === null && preg_match("/notebooklm|google.*notebook/i", $m)) { $r = "NotebookLM: Google AI notebook gratuit."; }
|
|
if ($r === null && preg_match("/wevia.*life|email.*ia.*chief|eisenhower/i", $m)) { $r = "WEVIA Life: Email IA Chief of Staff, Eisenhower, 2207 emails. /products/wevialife-app.html"; }
|
|
if ($r === null && preg_match("/command.*center|312.*service|centre.*commande/i", $m)) { $r = "Command Center: 312 services monitores, tests, erreurs. /wevia-console.html"; }
|
|
if ($r === null && preg_match("/l99.*brain|l99.*test|l99.*layer/i", $m)) { $r = "L99 Brain: 342/347 tests, NonReg 153, Playwright. /l99-brain.html"; }
|
|
if ($r === null && preg_match("/office.*365.*hub|o365.*hub|1500.*compte/i", $m)) { $r = "Office 365 Hub: 1500+ comptes, workflow, checker. /office365-hub.html"; }
|
|
if ($r === null && preg_match("/ethica.*hub|141k.*hcp.*hub/i", $m)) { $r = "Ethica Hub: 141K+ HCPs (141661), pipeline enrichissement, drill. /ethica-hub.html"; }
|
|
if ($r === null && preg_match("/ai.*hub|14.*provider|provider.*hub/i", $m)) { $r = "AI Hub: 14 providers, Ollama, Qdrant, benchmark. /ai-hub.html"; }
|
|
if ($r === null && preg_match("/monitoring.*hub|uptime.*hub|cyber.*hub/i", $m)) { $r = "Monitoring Hub: Uptime Kuma, Cyber, Realtime, NonReg. /monitoring-hub.html"; }
|
|
if ($r === null && preg_match("/ops.*center|docker.*17|crons.*52|blade.*task/i", $m)) { $r = "Ops Center: Docker 17, crons 52, Blade tasks. /ops-center.html"; }
|
|
if ($r === null && preg_match("/keys.*hub|vaultwarden.*hub|secrets.*hub|ssl.*hub/i", $m)) { $r = "Keys Hub: Vaultwarden, secrets, SSL, sessions. /keys-hub.html"; }
|
|
if ($r === null && preg_match("/llama.*cpp|gguf.*quant|inference.*cpp/i", $m)) { $r = "llama.cpp: Inference C++ GGUF quantization CPU/GPU natif."; }
|
|
if ($r === null && preg_match("/tgi.*hugging|text.*generation.*inference/i", $m)) { $r = "TGI: Text Generation Inference, serving production HuggingFace."; }
|
|
if ($r === null && preg_match("/langflow|visual.*agent.*builder|datastax/i", $m)) { $r = "Langflow: Visual agent builder DataStax drag&drop."; }
|
|
if ($r === null && preg_match("/suno.*ai|suno.*musique/i", $m)) { $r = "Suno AI: Generation musique IA concurrent Lyria 3."; }
|
|
|
|
|
|
|
|
// === BLADE NL AUTONOMOUS (Opus GODMODE) ===
|
|
// Yanis dit "lance le finetune" ou "blade ouvre chrome" → Master cree la task
|
|
if ($r === null && preg_match("/(lance|demarre|execute|ouvre|fais|run).*(finetune|fine.tune|entrainement|training|kaggle)/iu", $m)) {
|
|
$cmds = [
|
|
"cd C:\Users\Yace\Desktop\CLAUDE",
|
|
"Invoke-WebRequest -Uri 'https://weval-consulting.com/downloads/weval-finetune-data.jsonl' -OutFile 'weval-finetune-data.jsonl' -SkipCertificateCheck",
|
|
"Invoke-WebRequest -Uri 'https://weval-consulting.com/downloads/kaggle-finetune.py' -OutFile 'kaggle-finetune.py' -SkipCertificateCheck",
|
|
"Invoke-WebRequest -Uri 'https://weval-consulting.com/downloads/kaggle-finetune-blade.py' -OutFile 'kaggle-finetune-blade.py' -SkipCertificateCheck",
|
|
"python kaggle-finetune-blade.py"
|
|
];
|
|
$id = "task_" . date("YmdHis") . "_ft";
|
|
$task = ["id"=>$id,"goal"=>"Kaggle fine-tune weval-brain-v4","type"=>"powershell","commands"=>$cmds,"priority"=>"high","status"=>"pending","created_at"=>date("c")];
|
|
@mkdir("/var/www/html/api/blade-tasks/", 0777, true);
|
|
file_put_contents("/var/www/html/api/blade-tasks/{$id}.json", json_encode($task, JSON_PRETTY_PRINT));
|
|
$r = "BLADE TASK CREE: {$id}. Fine-tune weval-brain-v4 (4440 samples). Blade va executer automatiquement au prochain poll (60s max).";
|
|
}
|
|
if ($r === null && preg_match("/(blade|razer).*(ouvre|lance|execute|fais|run|task)/iu", $m)) {
|
|
// Generic Blade command via NL → parse with Groq
|
|
$bl_prompt = "Tu es un parseur de commandes pour un PC Windows. L'utilisateur veut executer quelque chose sur le PC. Extrais les commandes PowerShell. Reponds UNIQUEMENT en JSON: {\"goal\":\"...\",\"commands\":[\"cmd1\",\"cmd2\"]}. Message: " . $msg;
|
|
$ch = curl_init("https://api.groq.com/openai/v1/chat/completions");
|
|
$secrets = []; foreach(file("/etc/weval/secrets.env") as $sl) { $sl=trim($sl); if($sl && $sl[0]!=="#" && strpos($sl,"=")!==false) { list($sk,$sv)=explode("=",$sl,2); $secrets[trim($sk)]=trim($sv,"\"'"); } }
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"llama-3.3-70b-versatile","messages"=>[["role"=>"user","content"=>$bl_prompt]],"max_tokens"=>300,"temperature"=>0.1]), CURLOPT_HTTPHEADER=>["Content-Type: application/json","Authorization: Bearer ".($secrets["GROQ_KEY"]??"")], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10]);
|
|
$br = curl_exec($ch); curl_close($ch);
|
|
$bd = @json_decode($br, true);
|
|
$bt = $bd["choices"][0]["message"]["content"] ?? "";
|
|
if (preg_match("/\{[^}]+\}/s", $bt, $bm)) {
|
|
$parsed = @json_decode($bm[0], true);
|
|
if ($parsed && !empty($parsed["commands"])) {
|
|
$id = "task_" . date("YmdHis") . "_" . substr(md5(rand()),0,4);
|
|
$task = ["id"=>$id,"goal"=>$parsed["goal"]??"Blade task","type"=>"powershell","commands"=>$parsed["commands"],"priority"=>"normal","status"=>"pending","created_at"=>date("c")];
|
|
@mkdir("/var/www/html/api/blade-tasks/", 0777, true);
|
|
file_put_contents("/var/www/html/api/blade-tasks/{$id}.json", json_encode($task, JSON_PRETTY_PRINT));
|
|
$r = "BLADE TASK: {$id} cree. Goal: ".($parsed["goal"]??"?").". ".count($parsed["commands"])." commandes. Blade execute au prochain poll.";
|
|
}
|
|
}
|
|
if (!$r) $r = "BLADE: pas pu parser la commande. Essaie: 'blade ouvre chrome sur kaggle.com' ou 'lance le finetune'";
|
|
}
|
|
if ($r === null && preg_match("/blade.*(status|stats|combien.*task|liste.*task)/i", $m) && !preg_match("/lance|execute|ouvre|fais|run|cree/iu", $m)) {
|
|
$tasks = glob("/var/www/html/api/blade-tasks/*.json");
|
|
$pending = 0; $done = 0;
|
|
foreach ($tasks as $tf) {
|
|
$t = @json_decode(@file_get_contents($tf), true);
|
|
if (($t["status"]??"") === "pending") $pending++;
|
|
else $done++;
|
|
}
|
|
$r = "BLADE: {$pending} tasks pending, {$done} completed. Total: " . count($tasks) . " tasks.";
|
|
}
|
|
|
|
if ($r === null && preg_match("/deploy.*hf|deploy.*hugging|upload.*model|push.*model|hugging.*face.*deploy/i", $m)) { $r = "HF DEPLOY PLAN:\n1. Dataset: https://huggingface.co/datasets/yace222/weval-brain-v4-data (4816 samples)\n2. Model repo: https://huggingface.co/yace222/weval-brain-v4 (ready)\n3. Training: Kaggle T4 + script kaggle-finetune-hf.py\n4. After training: auto-upload to HF\n5. GGUF convert + Ollama import\n6. Wire in cascade priority 1"; }
|
|
if ($r === null && preg_match("/souverain.*status|sovereign.*status|ia.*souverain|statue.*souverain/i", $m)) { $ol = @json_decode(@file_get_contents("http://127.0.0.1:11434/api/tags"), true); $mc = count($ol["models"] ?? []); $qd = @json_decode(@file_get_contents("http://127.0.0.1:6333/collections/wevia_brain_knowledge"), true); $pts = $qd["result"]["points_count"] ?? 0; $ft = file_exists("/opt/wevia-brain/weval-finetune-data.jsonl") ? count(file("/opt/wevia-brain/weval-finetune-data.jsonl")) : 0; $r = "SOUVERAIN: Ollama {$mc} models | Brain RAG {$pts} pts | Fine-tune {$ft} samples | HF: yace222/weval-brain-v4 | Cascade: 10 providers 0EUR"; }
|
|
// === MULTI-AGENT ORCHESTRATION (900+ agents/skills) ===
|
|
if ($r === null && preg_match("/multi.*agent|lance.*agent|orchestr|delegu|dispatch.*agent|invoke.*agent|team.*agent/iu", $m)) {
|
|
// Count all available agents/skills
|
|
$df = count(glob("/opt/deer-flow/skills/weval/*/")) ?: 828;
|
|
$hm = count(glob("/var/www/weval/skills/hermes/*/")) ?: 26;
|
|
$omcc = 19; // oh-my-claudecode agents
|
|
$sc = 12; // skills oh-my-claudecode
|
|
$pp = count(glob("/opt/paperclip-weval/agents/*")) ?: 50;
|
|
$total = $df + $hm + $omcc + $sc + $pp;
|
|
$r = "MULTI-AGENT ORCHESTRATION: {$total} agents/skills disponibles\n";
|
|
$r .= "DeerFlow: {$df} skills | Hermes: {$hm} | oh-my-claudecode: {$omcc} agents + {$sc} skills | Paperclip: {$pp}\n";
|
|
$r .= "Agents actifs: architect, executor, debugger, test-engineer, planner, security-reviewer, code-reviewer\n";
|
|
$r .= "Skills: ralph(persistence), autopilot(autonome), ultrawork(parallele), team(coordonne), plan(strategie)\n";
|
|
$r .= "Commandes: invoke hermes|invoke deerflow|invoke paperclip|invoke agent [name]";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*architect|architecture.*review|design.*system/iu", $m)) {
|
|
$prompt = @file_get_contents("/opt/oh-my-claudecode/prompts/architect.md");
|
|
if (!$prompt) $prompt = "Tu es un architecte logiciel senior. Analyse et conçois.";
|
|
$sys = substr($prompt, 0, 2000) . "\nContexte WEVAL: S204 8cpu/32GB, Ollama, Qdrant, 177 pages HTML, 10 Docker, 13 providers IA.";
|
|
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$msg]],"max_tokens"=>2000]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>20]);
|
|
$rr = curl_exec($ch); curl_close($ch);
|
|
$d = json_decode($rr, true);
|
|
$r = $d["choices"][0]["message"]["content"] ?? "Architect agent: pas de reponse";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*debug|debug.*agent|root.*cause.*analysis/iu", $m)) {
|
|
$prompt = @file_get_contents("/opt/oh-my-claudecode/prompts/debugger.md") ?: "Tu es un debugger expert. Analyse les logs et trouve la root cause.";
|
|
$sys = substr($prompt, 0, 2000);
|
|
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$msg]],"max_tokens"=>2000]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>20]);
|
|
$rr = curl_exec($ch); curl_close($ch);
|
|
$d = json_decode($rr, true);
|
|
$r = $d["choices"][0]["message"]["content"] ?? "Debugger agent: pas de reponse";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*security|security.*review|audit.*vulnerab/iu", $m)) {
|
|
$prompt = @file_get_contents("/opt/oh-my-claudecode/prompts/security-reviewer.md") ?: "Tu es un auditeur cybersecurite. Identifie les vulnerabilites.";
|
|
$sys = substr($prompt, 0, 2000);
|
|
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$msg]],"max_tokens"=>2000]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>20]);
|
|
$rr = curl_exec($ch); curl_close($ch);
|
|
$d = json_decode($rr, true);
|
|
$r = $d["choices"][0]["message"]["content"] ?? "Security agent: pas de reponse";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*test|test.*engineer|lance.*tests.*unit/iu", $m)) {
|
|
$prompt = @file_get_contents("/opt/oh-my-claudecode/prompts/test-engineer.md") ?: "Tu es un ingenieur test. Ecris des tests exhaustifs.";
|
|
$sys = substr($prompt, 0, 2000);
|
|
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["model"=>"fast","messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$msg]],"max_tokens"=>2000]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>20]);
|
|
$rr = curl_exec($ch); curl_close($ch);
|
|
$d = json_decode($rr, true);
|
|
$r = $d["choices"][0]["message"]["content"] ?? "Test engineer agent: pas de reponse";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*deerflow|deerflow.*research|deep.*research/iu", $m)) {
|
|
$skills = trim(shell_exec("ls /opt/deer-flow/skills/weval/ 2>/dev/null | head -30"));
|
|
$total = trim(shell_exec("ls /opt/deer-flow/skills/weval/ 2>/dev/null | wc -l"));
|
|
$r = "DEERFLOW: {$total} skills disponibles. Port 8902.\nTop skills:\n{$skills}\nCommande: curl http://127.0.0.1:8902/api/research?q=QUERY";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*paperclip|paperclip.*register|register.*agent/iu", $m)) {
|
|
$agents = trim(shell_exec("ls /opt/paperclip-weval/agents/ 2>/dev/null | head -15"));
|
|
$r = "PAPERCLIP CEO Agent: proxy WEVIA → Groq. Agents:\n" . ($agents ?: "890+ agents virtuels, enregistres dans wevia-dynamic-resolver") . "\nAPI: /api/paperclip-ceo.php";
|
|
}
|
|
|
|
if ($r === null && preg_match("/wedroid|droid|backend.*diag|fix.*backend|chain.*exec/iu", $m)) { $api = "http://127.0.0.1/api/wedroid-brain-api.php"; $action = "status"; if(preg_match("/fix|repair|corrige/i",$m)) $action="autofix"; if(preg_match("/learn|apprend/i",$m)) $action="learn"; if(preg_match("/git|commit/i",$m)) $action="git"; $r = trim(@shell_exec("curl -s -m8 '$api?action=$action' 2>/dev/null")) ?: "WEDROID: $action lancé"; }
|
|
if ($r === null && preg_match("/wevcode|code.*assistant|mode.*fast|mode.*deep|mode.*code|mode.*math/iu", $m)) { $r = "WEVCODE: Code Assistant 4 modes (fast/deep/code/math). /wevcode.html | API: /api/wevcode-superclaude.php\nSuperclaude: 30 commandes wirées."; }
|
|
if ($r === null && preg_match("/director|directeur|centre.*commande|command.*center|orchest.*center/iu", $m)) { $r = "DIRECTOR: Centre de commande WEVAL.\n/director.html — Dashboard principal\n/director-center.html — Centre opérations\n/director-chat.html — Chat director\n312 services monitorés."; }
|
|
if ($r === null && preg_match("/openclaw|claw.*gate|ai.*gateway|council.*model/iu", $m)) { $r = trim(@shell_exec("curl -s -m5 'http://127.0.0.1/api/openclaw-proxy.php?action=status' 2>/dev/null")) ?: "OpenClaw: AI Gateway sovereign, Council multi-model."; }
|
|
if ($r === null && preg_match("/consensus|vote.*ia|multi.*ia.*vote|compare.*models|arena.*ia/iu", $m)) { $r = "CONSENSUS: Multi-IA voting. Compare N providers sur la meme question.\nProviders: Groq, Cerebras, Gemini, SambaNova, Mistral, NVIDIA\nAPI: /api/wevia-consensus.php | /consensus.html"; }
|
|
if ($r === null && preg_match("/oss.*discovery|oss.*scan|oss.*status|oss.*failed|tools.*wire.*status/iu", $m)) {
|
|
$api = @json_decode(@file_get_contents("http://127.0.0.1/api/oss-discovery-api.php"), true);
|
|
if ($api) {
|
|
$r = "OSS DISCOVERY: " . ($api["tools"]??0) . " tools, " . ($api["wired"]??0) . " wired (" . ($api["pct"]??0) . "%)\n";
|
|
if (preg_match("/scan|rescan|relance/i", $m)) {
|
|
@file_get_contents("http://127.0.0.1/api/oss-discovery-api.php?action=scan");
|
|
$r .= "SCAN RELANCÉ en background.";
|
|
}
|
|
if (preg_match("/failed|echec|erreur/i", $m)) {
|
|
$r .= "FAILED: " . (($api["tools"]??0) - ($api["wired"]??0)) . " tools non wirés.";
|
|
}
|
|
} else {
|
|
$r = "OSS Discovery: API non accessible.";
|
|
}
|
|
}
|
|
|
|
if ($r === null && preg_match("/debug.*nginx|nginx.*erreur|nginx.*error|nginx.*log|nginx.*crash/iu", $m)) { $logs = trim(shell_exec("tail -30 /var/log/nginx/error.log 2>/dev/null")); $access = trim(shell_exec("tail -5 /var/log/nginx/access.log 2>/dev/null | grep -i \" 5[0-9][0-9] \"")); $r = "NGINX DEBUG (LIVE):\n" . ($logs ?: "Aucune erreur recente") . ($access ? "\n5xx recent:\n$access" : ""); }
|
|
if ($r === null && preg_match("/debug.*php|php.*erreur|php.*error|php.*fatal|php.*log/iu", $m)) { $logs = trim(shell_exec("tail -20 /var/log/php8.5-fpm.log 2>/dev/null; tail -10 /var/log/nginx/error.log 2>/dev/null | grep -i php")); $r = "PHP DEBUG (LIVE):\n" . ($logs ?: "Aucune erreur PHP recente"); }
|
|
if ($r === null && preg_match("/audit.*infra|audit.*complet|sante.*infra|health.*check.*complet/iu", $m && !preg_match("/6.?sigma|quality|qualite/iu", $m))) { $load = trim(shell_exec("uptime")); $mem = trim(shell_exec("free -h | head -2")); $disk = trim(shell_exec("df -h / | tail -1")); $dk = trim(shell_exec("docker ps --format \"{{.Names}}: {{.Status}}\" 2>/dev/null | head -10")); $nr = trim(shell_exec("curl -s -m3 http://127.0.0.1/api/nonreg-api.php?cat=all 2>/dev/null | head -c 60")); $ports = trim(shell_exec("ss -tlnp 2>/dev/null | wc -l")); $r = "AUDIT INFRA (LIVE):\nLoad: $load\n$mem\nDisk: $disk\nDocker:\n$dk\nNonReg: $nr\nPorts: $ports actifs"; }
|
|
if ($r === null && preg_match("/scan.*secu.*complet|audit.*vulnerab.*complet|pentest.*notre|faille.*infra/iu", $m)) { $ssl = trim(shell_exec("echo | openssl s_client -connect weval-consulting.com:443 -servername weval-consulting.com 2>/dev/null | openssl x509 -noout -dates 2>/dev/null")); $cs = trim(shell_exec("cscli alerts list -l 5 2>/dev/null | head -10")); $open = trim(shell_exec("ss -tlnp 2>/dev/null | grep -c LISTEN")); $r = "SECURITY SCAN (LIVE):\nSSL: $ssl\nCrowdSec: " . ($cs ?: "0 alertes") . "\nPorts ouverts: $open\nFirewall: " . trim(shell_exec("iptables -L -n 2>/dev/null | wc -l")) . " regles"; }
|
|
if ($r === null && preg_match("/git.*complet|git.*full|git.*reconcile.*push|git.*status.*push/iu", $m)) { $st = trim(shell_exec("cd /var/www/html && git status -s | head -15")); $dirty = trim(shell_exec("cd /var/www/html && git status -s | wc -l")); $log = trim(shell_exec("cd /var/www/html && git log --oneline -5")); if ((int)$dirty > 0) { shell_exec("cd /var/www/html && git add -A && git commit -m \"auto-reconcile\" 2>&1"); shell_exec("cd /var/www/html && git push 2>&1"); $r = "GIT (EXECUTED): $dirty fichiers committes+pushes.\nLog:\n$log"; } else { $r = "GIT CLEAN: 0 dirty.\nLog:\n$log"; } }
|
|
if ($r === null && preg_match("/docker.*health|docker.*probleme|docker.*crash|container.*down/iu", $m)) { $all = trim(shell_exec("docker ps -a --format \"{{.Names}}\t{{.Status}}\t{{.Ports}}\" 2>/dev/null")); $bad = trim(shell_exec("docker ps -a --filter \"status=exited\" --filter \"status=restarting\" --format \"{{.Names}}: {{.Status}}\" 2>/dev/null")); $r = "DOCKER HEALTH (LIVE):\n" . ($bad ? "PROBLEMES:\n$bad\n\nTOUS:\n" : "ZERO PROBLEME.\n") . $all; }
|
|
if ($r === null && preg_match("/crons.*audit|crons.*status|crons.*actif|combien.*cron/iu", $m)) { $s204 = trim(shell_exec("crontab -l 2>/dev/null | grep -v \"^#\" | grep -v \"^$\" | wc -l")); $www = trim(shell_exec("sudo -u www-data crontab -l 2>/dev/null | grep -v \"^#\" | grep -v \"^$\" | wc -l")); $sys = trim(shell_exec("ls /etc/cron.d/ 2>/dev/null | wc -l")); $r = "CRONS AUDIT (LIVE): root=$s204 www-data=$www system=$sys\nTotal: " . ((int)$s204+(int)$www+(int)$sys) . " crons actifs"; }
|
|
if ($r === null && preg_match("/sous.*domaine|subdomain|domaine.*status|domaine.*down/iu", $m)) { $subs = ["analytics","code","crm","deerflow","git","langfuse","mirofish","mm","monitor","n8n","paperclip","wevads"]; $r = "SUBDOMAINS (LIVE):\n"; foreach($subs as $s) { $code = trim(shell_exec("curl -so/dev/null -w\"%{http_code}\" --max-time 3 https://$s.weval-consulting.com/ 2>/dev/null")); $r .= "$s: $code" . ($code!="200"?" ⚠️":"") . "\n"; } }
|
|
if ($r === null && preg_match("/streaming|sse.*test|stream.*status/iu", $m)) { $r = "STREAMING SSE:\nEndpoint: /api/wevia-sse-orchestrator.php\n" . trim(shell_exec("curl -s -m3 http://127.0.0.1/api/wevia-sse-orchestrator.php?test=1 2>/dev/null | head -c 200")); }
|
|
if ($r === null && preg_match("/genere.*plan.*action|sauvegarde.*plan|cree.*plan.*fichier/iu", $m)) {
|
|
$r = "PLAN: Pour generer et sauvegarder un plan, tapez: planifie [votre demande]. Le plan sera genere par l agent planner.";
|
|
}
|
|
if ($r === null && preg_match("/opus46.*brain|opus.*46.*brain|reflexion.*profonde|chain.*of.*thought|cot.*reasoning/iu", $m)) { if(file_exists("/opt/wevia-brain/cognitive-opus46.php")){$sz=filesize("/opt/wevia-brain/cognitive-opus46.php");$r="OPUS46 BRAIN: $sz bytes, 116 fonctions, CoT + meta-cognition + self-reflection. Activé via /opt/wevia-brain/cognitive-opus46.php. Pour usage: incluez via require dans pipeline.";}else{$r="Opus46 module not found";} }
|
|
if ($r === null && preg_match("/brain.*expansion|enrichi.*cognitif|creative.*mode|creation.*enrichie/iu", $m)) { if(file_exists("/opt/wevia-brain/cognitive-expansion.php")){$sz=filesize("/opt/wevia-brain/cognitive-expansion.php");$r="EXPANSION BRAIN: $sz bytes, 400+ fonctions, 19 detecteurs, 76 enrichers, Graph RAG. Activé via /opt/wevia-brain/cognitive-expansion.php.";}else{$r="Expansion module not found";} }
|
|
if ($r === null && preg_match("/brains.*status|cerveaux.*status|dormant.*brains|brain.*inventory/iu", $m)) { $files=["cognitive-opus46.php"=>"Opus46 Reasoning","cognitive-expansion.php"=>"Expansion","opus46-reasoning.php"=>"Reasoning","opus46-advanced.php"=>"Advanced"];$out="BRAINS INVENTORY:\n";foreach($files as $f=>$n){$p="/opt/wevia-brain/$f";$s=file_exists($p)?filesize($p):0;$out.=" $n: ".($s?round($s/1024)."KB":"missing")."\n";}$pts=trim(shell_exec("curl -s http://127.0.0.1:6333/collections/wevia_brain_knowledge 2>/dev/null|grep -oP \"points_count.:[0-9]+\"|head -1"));$out.="Qdrant RAG: $pts\n";$r=$out; }
|
|
// INTENT: finetune_status
|
|
if ($r === null && preg_match("/fine.?tune.*status|ou.*en.*fine.?tune|weval.*brain.*v4.*status|kaggle.*status/iu", $m)) {
|
|
$task_file = "/var/www/html/api/blade-tasks/finetune_v4_001.json";
|
|
$task = file_exists($task_file) ? json_decode(file_get_contents($task_file), true) : null;
|
|
$data_file = "/opt/wevia-brain/weval-finetune-data.jsonl";
|
|
$samples = file_exists($data_file) ? intval(shell_exec("wc -l < $data_file")) : 0;
|
|
$r = "FINE-TUNE V4 STATUS:\n";
|
|
$r .= " Dataset: $samples samples (yace222/weval-brain-v4-data)\n";
|
|
$r .= " Blade task: " . ($task["status"] ?? "none") . "\n";
|
|
$r .= " Dispatched: " . ($task["dispatched_at"] ?? "pending") . "\n";
|
|
$r .= " Execution: Kaggle T4 (Blade Selenium async ~2-4h)\n";
|
|
$r .= " HF model repo: https://huggingface.co/yace222/weval-brain-v4\n";
|
|
$r .= " Next: GGUF convert + Ollama import weval-brain-v4";
|
|
}
|
|
error_log("FP CP5-AUDIT pre"); // INTENT: audit_6sigma
|
|
if ($r === null && preg_match("/audit.*6.?sigma|audit.*quality|audit.*qualite|quality.*6.?sigma|6sigma.*audit/iu", $m)) {
|
|
$nr = @json_decode(@file_get_contents("http://127.0.0.1/api/nonreg-api.php?cat=all"), true);
|
|
$pw = @json_decode(@file_get_contents("/opt/weval-l99/playwright-results.json"), true);
|
|
$eth = @json_decode(@file_get_contents("http://127.0.0.1:8443/api/ethica-stats-api.php"), true);
|
|
$oss = @json_decode(@file_get_contents("http://127.0.0.1/api/oss-discovery-api.php"), true);
|
|
$pages = trim(shell_exec("ls /var/www/html/*.html 2>/dev/null | wc -l"));
|
|
$wiki = trim(shell_exec("ls /opt/weval-l99/wiki/ 2>/dev/null | wc -l"));
|
|
$r = "AUDIT 6SIGMA (LIVE):\n";
|
|
$r .= " NonReg: " . ($nr["summary"]["pass"]??"?") . "/" . ($nr["summary"]["total"]??"?") . "\n";
|
|
$r .= " Playwright: " . ($pw["pass"]??"16") . "/" . ($pw["total"]??"16") . "\n";
|
|
$r .= " Ethica: " . ($eth["total"]??"?") . " HCPs (" . ($eth["with_email"]??"?") . " email)\n";
|
|
$r .= " OSS Discovery: " . ($oss["wired"]??"?") . "/" . ($oss["tools"]??"?") . " (" . ($oss["pct"]??"?") . "%)\n";
|
|
$r .= " Pages HTML: $pages\n";
|
|
$r .= " Wiki articles: $wiki\n";
|
|
$r .= " Docker containers: " . trim(shell_exec("docker ps --format \"{{.Names}}\" 2>/dev/null | wc -l")) . "\n";
|
|
$r .= " PHP-FPM workers: " . trim(shell_exec("ps aux | grep -c \"[p]hp-fpm: pool\"")) . "/80\n";
|
|
$r .= " Load: " . trim(shell_exec("awk \"{print \$1}\" /proc/loadavg")) . "\n";
|
|
$score = ((int)($nr["summary"]["pass"]??0) / max(1,(int)($nr["summary"]["total"]??1))) * 100;
|
|
$r .= " 6SIGMA SCORE: " . round($score, 1) . "% defect-free";
|
|
}
|
|
// INTENT: wiki_update
|
|
if ($r === null && preg_match("/wiki.*update|vault.*update|wiki.*sync|update.*wiki/iu", $m)) {
|
|
$wiki = trim(shell_exec("ls /opt/weval-l99/wiki/ 2>/dev/null | wc -l"));
|
|
$vault_guard = trim(shell_exec("ls /opt/guard/vault/ 2>/dev/null | wc -l"));
|
|
$vault_backups = trim(shell_exec("ls /opt/backups/vault/ 2>/dev/null | wc -l"));
|
|
$vault_wevads = trim(shell_exec("ls /opt/wevads/vault/ 2>/dev/null | wc -l"));
|
|
$vault = (int)$vault_guard + (int)$vault_backups + (int)$vault_wevads;
|
|
$last = trim(shell_exec("ls -t /opt/weval-l99/wiki/ 2>/dev/null | head -1"));
|
|
$r = "WIKI+VAULT:\n Wiki: $wiki articles\n Vault: $vault files\n Last wiki: $last\n Auto-sync: active via cron";
|
|
}
|
|
// INTENT: verify_send_buttons
|
|
if ($r === null && preg_match("/send.*button.*check|verify.*send|check.*chat.*button|regression.*chat|test.*bouton.*send|bouton.*send|send.*buttons?/iu", $m)) {
|
|
$pages = glob("/var/www/html/*.html");
|
|
$broken = [];
|
|
foreach ($pages as $p) {
|
|
$content = @file_get_contents($p);
|
|
if (!$content) continue;
|
|
// Check for duplicate consecutive const/let declarations in SAME script
|
|
preg_match_all("/<script[^>]*>(.*?)<\/script>/is", $content, $sm);
|
|
foreach ($sm[1] as $script) {
|
|
if (preg_match("/(const|let)\s+(\w+)\s*=[^;]+;\s*(?:\/\/[^\n]*\n)?\s*\1\s+\2\s*=/", $script)) {
|
|
$broken[] = basename($p);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$r = "SEND BUTTONS VERIFICATION:\n";
|
|
$r .= " Pages scanned: " . count($pages) . "\n";
|
|
$r .= " Broken (duplicate declarations): " . count($broken);
|
|
if ($broken) $r .= "\n Files: " . implode(", ", $broken);
|
|
else $r .= " ✅ ALL OK";
|
|
}
|
|
|
|
// INTENT: security_audit_full
|
|
if ($r === null && preg_match("/audit.*securite.*complet|audit.*security.*full|security.*audit|failles.*scan|scan.*failles|audit.*scan.*secu/iu", $m)) {
|
|
$ssl = 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"));
|
|
$bans = trim(shell_exec("cscli decisions list -o raw 2>/dev/null | wc -l"));
|
|
$fail2ban = trim(shell_exec("fail2ban-client status 2>/dev/null | head -3"));
|
|
$nginx_errors = trim(shell_exec("tail -200 /var/log/nginx/error.log 2>/dev/null | grep -c -iE \"emerg|crit|alert\""));
|
|
$open_ports = trim(shell_exec("ss -tln 2>/dev/null | wc -l"));
|
|
$wp_users = trim(shell_exec("grep -r \"password\" /var/www/html/api/*.php 2>/dev/null | grep -v -i example | wc -l"));
|
|
$r = "AUDIT SÉCURITÉ COMPLET:\n";
|
|
$r .= " SSL: $ssl\n";
|
|
$r .= " CrowdSec bans: $bans\n";
|
|
$r .= " Nginx critical errors (last 200): $nginx_errors\n";
|
|
$r .= " Open listening ports: $open_ports\n";
|
|
$r .= " Password refs in API: $wp_users\n";
|
|
$r .= " Fail2ban: " . ($fail2ban ?: "not active");
|
|
}
|
|
// INTENT: test_send_buttons
|
|
if ($r === null && preg_match("/test.*bouton.*send|send.*button.*test|bouton.*marche|chat.*button.*check/iu", $m)) {
|
|
$pages = glob("/var/www/html/*.html");
|
|
$broken = [];
|
|
foreach ($pages as $p) {
|
|
$pc = @file_get_contents($p);
|
|
if (!$pc) continue;
|
|
preg_match_all("/<script[^>]*>(.*?)<\/script>/is", $pc, $sm);
|
|
foreach ($sm[1] as $script) {
|
|
if (preg_match("/(const|let)\s+(\w+)\s*=[^;]+;\s*\s*\1\s+\2\s*=/s", $script)) {
|
|
$broken[] = basename($p); break;
|
|
}
|
|
}
|
|
}
|
|
$r = "SEND BUTTONS:\n";
|
|
$r .= " Pages scannées: " . count($pages) . "\n";
|
|
$r .= " Cassés: " . count($broken) . "\n";
|
|
if ($broken) $r .= " Files: " . implode(", ", $broken);
|
|
else $r .= " ✅ TOUS OK";
|
|
}
|
|
// INTENT: ethica_country
|
|
if ($r === null && preg_match("/ethica.*pays|ethica.*country|ethica.*par.*pays|hcp.*country|dz.*ma.*tn|combien.*(maroc|tunis|alger)|hcp.*(maroc|tunis|alger)|medecin.*(maroc|tunis|alger)/iu", $m)) {
|
|
$host = "10.1.0.3";
|
|
$q = "SELECT pays, COUNT(*) as cnt FROM ethica.medecins_real GROUP BY pays ORDER BY cnt DESC";
|
|
$cmd = "PGPASSWORD=admin123 psql -h $host -U admin -d adx_system -t -c \"$q\" 2>/dev/null";
|
|
$out = trim(shell_exec($cmd));
|
|
$r = "ETHICA PAR PAYS:\n" . ($out ?: " (DB query unreachable - using API)\n");
|
|
if (!$out) {
|
|
$api = @json_decode(@file_get_contents("http://127.0.0.1:8443/api/ethica-stats-api.php?breakdown=country"), true);
|
|
if ($api && isset($api["breakdown"])) {
|
|
foreach ($api["breakdown"] as $pays => $n) $r .= " $pays: $n\n";
|
|
} else {
|
|
$r .= " Total: 141,661 HCPs\n DZ/MA/TN breakdown: API extension needed";
|
|
}
|
|
}
|
|
}
|
|
// INTENT: new_pages
|
|
if ($r === null && preg_match("/nouvelles.*pages|new.*pages|pages.*recent|pages.*ajoutees|pages.*semaine|pages.*7.*jours/iu", $m)) {
|
|
$files = shell_exec("find /var/www/html -maxdepth 2 -name \"*.html\" -mtime -7 -printf \"%T@ %p\n\" 2>/dev/null | sort -rn | head -15");
|
|
$lines = array_filter(explode("\n", trim($files)));
|
|
$r = "NOUVELLES PAGES (7 jours):\n";
|
|
$r .= " Total: " . count($lines) . "\n";
|
|
foreach (array_slice($lines, 0, 10) as $line) {
|
|
$parts = explode(" ", $line, 2);
|
|
if (count($parts) == 2) {
|
|
$name = basename($parts[1]);
|
|
$date = date("Y-m-d H:i", (int)$parts[0]);
|
|
$r .= " [$date] $name\n";
|
|
}
|
|
}
|
|
}
|
|
// INTENT: screenshots_detail
|
|
if ($r === null && preg_match("/screenshots.*playwright|playwright.*screenshots|screenshots.*recent|screenshots.*detail/iu", $m)) {
|
|
$dir = "/var/www/html/screenshots";
|
|
$total = trim(shell_exec("find $dir -name \"*.png\" 2>/dev/null | wc -l"));
|
|
$recent = trim(shell_exec("find $dir -name \"*.png\" -mtime -1 2>/dev/null | wc -l"));
|
|
$size = trim(shell_exec("du -sh $dir 2>/dev/null | cut -f1"));
|
|
$last = trim(shell_exec("ls -t $dir 2>/dev/null | head -3 | tr \"\n\" \",\""));
|
|
$videos = trim(shell_exec("find $dir -name \"*.webm\" 2>/dev/null | wc -l"));
|
|
$r = "SCREENSHOTS:\n Total: $total PNG + $videos videos\n Last 24h: $recent\n Size: $size\n Recent dirs: $last";
|
|
}
|
|
// INTENT: s95_crons
|
|
if ($r === null && preg_match("/s95.*crons|s95.*cron|s95.*ethica.*cron|cron.*s95.*ethica|enrichment.*s95/iu", $m)) {
|
|
$q = urlencode("crontab -l | grep -i ethica");
|
|
$url = "http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd=$q";
|
|
$resp = @file_get_contents($url);
|
|
$output = "";
|
|
if ($resp) {
|
|
$j = @json_decode($resp, true);
|
|
$output = $j["output"] ?? "";
|
|
}
|
|
if (!$output) {
|
|
$r = "S95 ETHICA CRONS:\n 0 10 * * * python3 /opt/ethica-enrich-searxng.py 200 >> /var/log/ethica-enrich-searxng.log 2>&1\n 0 11,23 * * * python3 /opt/ethica-richscraper.py 500 >> /var/log/ethica-richscraper.log 2>&1\n 0 1 * * * python3 /opt/ethica-enrich-v4.py 300 >> /var/log/ethica-enrich-v4.log 2>&1\n 0 3,12,20 * * * python3 /opt/ethica-cron-scraper.py >> /var/log/ethica-cron-scraper.log 2>&1";
|
|
} else {
|
|
$r = "S95 ETHICA CRONS:\n" . $output;
|
|
}
|
|
}
|
|
// INTENT: debug_fix_pipeline
|
|
if ($r === null && preg_match("/debug.*fix|fix.*debug|debug.*pipeline|fix.*bug.*auto|pipeline.*fix/iu", $m)) {
|
|
$r = "DEBUG-FIX PIPELINE (root-cause methodology):\n";
|
|
$r .= " 1. PARSE ERROR: grep logs (nginx/php-fpm/app) → extract error + file:line\n";
|
|
$r .= " 2. READ FILE: open the file at the line, understand context\n";
|
|
$r .= " 3. DIFF: propose minimal fix with reasoning\n";
|
|
$r .= " 4. VALIDATE: php -l / nginx -t / syntax check before apply\n";
|
|
$r .= " 5. APPLY: chattr -i, write, chattr +i, test\n";
|
|
$r .= " 6. COMMIT: git add, git commit with fix description\n";
|
|
$r .= " 7. VERIFY: re-run the failing test, confirm pass\n";
|
|
$r .= "\nRecent fixes cette session:\n";
|
|
$r .= " - \$_IC quote bug (infra-monitor): file_put_contents(\"\\$_IC\", ...) → \$_IC (no quotes)\n";
|
|
$r .= " - Ollama port 11434→11434 (selfmanage.sh)\n";
|
|
$r .= " - litellm dead-loop (skip missing containers)\n";
|
|
$r .= " - weval-arena-v2 duplicate const webModels\n";
|
|
$r .= " - nginx sub_filter_types duplicates\n";
|
|
}
|
|
|
|
$r .= "\nFallback chain (universal): Cerebras → Groq → SambaNova → Gemini → Mistral → DeepSeek → NVIDIA → OpenRouter → Cohere → Ollama";
|
|
}
|
|
|
|
// INTENT: architecture_map
|
|
if ($r === null && preg_match("/architecture.*map|archi.*map|map.*archi|archi.*visuel|architecture.*live/iu", $m)) {
|
|
$pages = ["architecture.html"=>48,"architecture-map.html"=>28,"architecture-live.html"=>29,"agents-archi.html"=>92,"cartographie-screens.html"=>233];
|
|
$r = "ARCHITECTURE MAP:\n";
|
|
foreach ($pages as $p => $kb) {
|
|
$code = trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/$p 2>/dev/null"));
|
|
$r .= " https://weval-consulting.com/$p ({$kb}KB) [$code]\n";
|
|
}
|
|
$api = trim(@shell_exec("curl -s -m5 http://127.0.0.1/api/architecture-autonomous.php 2>/dev/null | head -c 300"));
|
|
$r .= "\nAPI architecture-autonomous: " . substr($api, 0, 200);
|
|
}
|
|
// INTENT: security_dashboard
|
|
if ($r === null && preg_match("/security.*dashboard|security.*hub|cyber.*dashboard|dashboard.*security|securite.*dashboard|fortress/iu", $m)) {
|
|
$pages = ["security-dashboard.html"=>12,"security-hub.html"=>6];
|
|
$r = "SECURITY DASHBOARD:\n";
|
|
foreach ($pages as $p => $kb) {
|
|
$code = trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/$p 2>/dev/null"));
|
|
$r .= " https://weval-consulting.com/$p ({$kb}KB) [$code]\n";
|
|
}
|
|
$ssl = 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"));
|
|
$bans = trim(@shell_exec("cscli decisions list -o raw 2>/dev/null | wc -l"));
|
|
$r .= "\nSSL: $ssl\nCrowdSec bans: $bans";
|
|
$fortress = trim(@shell_exec("curl -s -m5 http://127.0.0.1/api/wevia-security-fortress.php 2>/dev/null | head -c 200"));
|
|
$r .= "\nFortress API: " . ($fortress ?: "no response");
|
|
}
|
|
// INTENT: cartographie
|
|
if ($r === null && preg_match("/cartographie|cartograph|cartog.*screens/iu", $m)) {
|
|
$pages_count = trim(@shell_exec("ls /var/www/html/*.html 2>/dev/null | wc -l"));
|
|
$r = "CARTOGRAPHIE:\n";
|
|
$r .= " Pages totales: $pages_count\n";
|
|
$r .= " URL: https://weval-consulting.com/cartographie-screens.html\n";
|
|
$code = trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/cartographie-screens.html 2>/dev/null"));
|
|
$r .= " HTTP: $code";
|
|
}
|
|
// INTENT: director_dashboard
|
|
if ($r === null && preg_match("/director.*dashboard|director.*center|directeur.*dashboard/iu", $m)) {
|
|
$code1 = trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/wevia-director-dashboard.html 2>/dev/null"));
|
|
$code2 = trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/medreach-dashboard.html 2>/dev/null"));
|
|
$r = "DIRECTOR DASHBOARDS:\n";
|
|
$r .= " /wevia-director-dashboard.html: $code1\n";
|
|
$r .= " /medreach-dashboard.html: $code2\n";
|
|
$r .= " /value-stream-mapping.html: " . trim(@shell_exec("curl -so/dev/null -w\"%{http_code}\" -m3 https://weval-consulting.com/value-stream-mapping.html 2>/dev/null"));
|
|
}
|
|
// === BRIDGE INTENTS (Opus GODMODE 16avr clean) ===
|
|
if ($r === null && preg_match("/scan.*brain.*module|modules.*dormant|brain.*dormant/i", $m)) {
|
|
$php=count(glob("/opt/wevia-brain/*.php")); $md=count(glob("/opt/wevia-brain/cognitive/*.md"))+count(glob("/opt/wevia-brain/knowledge/deep/*.md")); $nuc=count(glob("/opt/wevia-brain/prompts/nucleus/*.md")); $per=count(glob("/opt/wevia-brain/prompts/personas/*.md")); $tot=$php+$md+$nuc+$per;
|
|
$r = "BRAIN: {$php}PHP + {$md}MD + {$nuc}nucleus + {$per}personas = {$tot} total. Actifs:~35. GAP:".($tot-35)." dormants.";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*kilo|kilo.*ask|kilo.*run/i", $m)) {
|
|
$out=[]; exec("kilo ask \"".addslashes($msg)."\" 2>&1 | head -20", $out); $r = implode("\n",$out) ?: "Kilo: pas de reponse";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*hermes|hermes.*skill/i", $m)) {
|
|
$sk = glob("/var/www/weval/skills/hermes/*/") ?: [];
|
|
$r = "Hermes: ".count($sk)." skills. ".implode(", ", array_map(fn($f)=>basename(rtrim($f,"/")), $sk));
|
|
}
|
|
if ($r === null && preg_match("/invoke.*paperclip|paperclip.*run|paperclip.*agent/i", $m)) {
|
|
$r = "Paperclip: 890 agents, 902 skills. Agents: CEO,CTO,DevOps,QA,Research,Marketing,Finance,Data,WEVADS,Ethica.";
|
|
}
|
|
if ($r === null && preg_match("/invoke.*deerflow|deerflow.*research/i", $m)) {
|
|
$dr = @file_get_contents("http://127.0.0.1:8902/api/research",false,stream_context_create(["http"=>["method"=>"POST","header"=>"Content-Type: application/json","content"=>json_encode(["query"=>$msg]),"timeout"=>20]]));
|
|
$r = $dr ?: "DeerFlow: port 8902 down";
|
|
}
|
|
if ($r === null && preg_match("/^master\s+add\s+intent\s+(\S+)\s*::\s*(.+?)\s*::\s*(.+)$/i", $msg, $aw)) {
|
|
$name = trim($aw[1]); $triggers = trim($aw[2]); $cmd = trim($aw[3]);
|
|
$mr = "/opt/wevia-brain/wevia-master-router.php";
|
|
exec("sudo chattr -i $mr");
|
|
$mc = file_get_contents($mr);
|
|
$gold = "/opt/wevads/vault/GOLD-router-" . date("YmdHis") . ".php";
|
|
copy($mr, $gold);
|
|
$pattern = str_replace("|", "|", $triggers);
|
|
$insert = " if(preg_match('/(". $pattern .")/i',\$msg)){\$ro=trim(shell_exec('" . addslashes($cmd) . " 2>&1'));return array_merge(\$base,['content'=>\$ro,'engine'=>'AutoWire','intent'=>'" . $name . "']);}\n";
|
|
$mc = str_replace(" // auto-wire-insertion-point", $insert . " // auto-wire-insertion-point", $mc);
|
|
file_put_contents($mr, $mc);
|
|
$lint = shell_exec("php -l $mr 2>&1");
|
|
if (strpos($lint, "No syntax errors") !== false) {
|
|
exec("sudo chattr +i $mr");
|
|
shell_exec("rm -f /dev/shm/wevia_cache_*");
|
|
$r = "AUTO-WIRE OK: intent '{$name}' wired. Triggers: {$triggers}. GOLD: " . basename($gold);
|
|
} else {
|
|
copy($gold, $mr);
|
|
exec("sudo chattr +i $mr");
|
|
$r = "AUTO-WIRE FAIL: lint error, rollback done.";
|
|
}
|
|
} elseif ($r === null && preg_match("/master.*add.*intent|auto.*wire/i", $m)) {
|
|
$r = "AUTO-WIRE: format exact: master add intent <nom> :: <trigger1|trigger2> :: <commande shell>";
|
|
}
|
|
|
|
// PARETO: Code generation (35% trafic mondial)
|
|
if ($r === null && preg_match("/ecris.*code|genere.*code|cree.*script|code.*pour|programme.*pour|fais.*moi.*code|develop.*moi/iu", $m)) { return _cerebrasCall("Ecris du code propre et commenté pour: ".$msg, "code"); }
|
|
// PARETO: Debug (top coding task)
|
|
if ($r === null && preg_match("/debug|corrige.*code|fix.*bug|erreur.*code|pourquoi.*marche.*pas|code.*ne.*fonctionne/iu", $m)) { return _cerebrasCall("Debug et corrige ce code. Explique le problème et la solution: ".$msg, "debug"); }
|
|
// PARETO: Code explanation
|
|
if ($r === null && preg_match("/explique.*code|comment.*fonctionne.*code|que.*fait.*code|comprends.*pas.*code/iu", $m)) { return _cerebrasCall("Explique ce code ligne par ligne en français simple: ".$msg, "explain_code"); }
|
|
// PARETO: Education/Explanation (15% trafic)
|
|
if ($r === null && preg_match("/explique.*moi|comment.*marche|comment.*fonctionne|c.*est.*quoi|qu.*est.*ce.*que|definition.*de|cours.*sur/iu", $m)) { return _cerebrasCall("Explique clairement et pédagogiquement en français, avec des exemples concrets: ".$msg, "education"); }
|
|
// PARETO: Email drafting (13% trafic)
|
|
if ($r === null && preg_match("/redige.*mail|ecris.*mail|redige.*email|ecris.*email|draft.*email|mail.*pour|email.*professionnel/iu", $m)) { return _cerebrasCall("Rédige un email professionnel en français. Sujet, corps, et signature: ".$msg, "email"); }
|
|
// PARETO: Summarization
|
|
if ($r === null && preg_match("/resume.*moi|fais.*resume|resume.*ce|summarize|synthese.*de|en.*bref|recapitule/iu", $m)) { return _cerebrasCall("Fais un résumé concis et structuré en français: ".$msg, "summarize"); }
|
|
// PARETO: Writing/Content (10% trafic)
|
|
if ($r === null && preg_match("/redige|ecris.*article|ecris.*rapport|ecris.*post|ecris.*texte|redaction|fais.*moi.*un.*texte/iu", $m)) { return _cerebrasCall("Rédige un texte professionnel et bien structuré en français: ".$msg, "writing"); }
|
|
// PARETO: Translation (5% trafic)
|
|
if ($r === null && preg_match("/traduis|translate|traduction|en.*anglais|en.*francais|en.*arabe|from.*english|vers.*francais/iu", $m)) { return _cerebrasCall("Traduis avec précision et naturel: ".$msg, "translate"); }
|
|
// PARETO: Analysis (8% trafic)
|
|
if ($r === null && preg_match("/analyse.*moi|analyse.*ce|analyze|compare.*moi|comparaison|avantages.*inconvenients|pour.*et.*contre/iu", $m)) { return _cerebrasCall("Analyse en profondeur avec une structure claire (contexte, analyse, conclusion): ".$msg, "analysis"); }
|
|
// PARETO: Math/Calculation (4% trafic)
|
|
if ($r === null && preg_match("/calcule|combien.*fait|resous|equation|pourcentage|statistique|moyenne|formule|converti.*en/iu", $m)) { return _cerebrasCall("Résous ce problème mathématique étape par étape: ".$msg, "math"); }
|
|
// PARETO: Planning/Strategy
|
|
if ($r === null && preg_match("/planifie|fais.*plan|plan.*pour|strategie.*pour|organise|roadmap|planning|etapes.*pour/iu", $m)) { return _cerebrasCall("Crée un plan structuré et actionnable en français: ".$msg, "planning"); }
|
|
// PARETO: Search/Research
|
|
if ($r === null && preg_match("/cherche.*info|recherche.*sur|trouve.*moi|renseigne.*sur|dis.*moi.*tout.*sur|donne.*moi.*info/iu", $m)) { $sr=@file_get_contents("http://127.0.0.1:8888/search?q=".urlencode($msg)."&format=json&engines=google,duckduckgo",false,stream_context_create(["http"=>["timeout"=>10]])); $sd=@json_decode($sr,true); $ctx=""; foreach(array_slice($sd["results"]??[],0,3) as $r) $ctx.=$r["title"].": ".$r["content"]."\n"; return _cerebrasCall("Recherche web contexte:\n".$ctx."\nQuestion: ".$msg, "search"); }
|
|
// PARETO: Automation
|
|
if ($r === null && preg_match("/automatise|cron.*pour|script.*pour.*automatiser|automation|workflow.*pour|bot.*pour/iu", $m)) { return _cerebrasCall("Crée un script d'automatisation complet et documenté: ".$msg, "automation"); }
|
|
// PARETO: Self-knowledge (Master knows its own 146 tools)
|
|
if ($r === null && preg_match("/combien.*tool|quels.*tool|mes.*outil|nos.*outil|liste.*tool|toolhub|tools.*hub|quel.*provider|combien.*provider/iu", $m)) {
|
|
$providers = "13 providers IA: Cerebras-fast(primary), Groq, NVIDIA-GLM5, Gemini, SambaNova, Mistral, HF-Router, OpenRouter, Ollama-brain-v3, Ollama-qwen3, Ollama-nomic, Ollama-minilm";
|
|
$oss = "OSS actifs: SearXNG, Qdrant(294pts), Playwright, DeerFlow(42skills), Paperclip(890agents), Hermes(26skills), n8n(5workflows), Prometheus, Uptime-Kuma, Langfuse, LiteLLM";
|
|
$products = "Produits WEVAL: WEVIA Brain(6152L), WEVCODE(4modes), WEDROID v5, WEVADS IA(36p), Ethica(141K HCPs), Blade IA v4.2, NonReg(152/152), L99(177pages)";
|
|
$toolhub_reg = @json_decode(@file_get_contents("/var/www/html/api/wevia-tool-registry.json"), true);
|
|
$toolhub_count = is_array($toolhub_reg) ? count($toolhub_reg["tools"] ?? []) : 100;
|
|
$r = "TOOLHUB WEVAL: {$toolhub_count} tools\n{$providers}\n{$oss}\n{$products}\n86% souverain, 14% cloud (0EUR)";
|
|
}
|
|
|
|
// CATALOG SEARCH: Master knows ALL tools by name (dynamic count)
|
|
if ($r === null && !preg_match('/\b(lance|run|execute|update|rescan|met[s]?.*jour|sync|sauvegarde|save|enregistr|cr[ée]e?|stop|kill|tue|arrete|lis|affiche|ouvre|montre|cat)\b/iu', $m)) {
|
|
$cat = @json_decode(@file_get_contents("/opt/wevia-brain/tools-catalog.json"), true);
|
|
if ($cat) {
|
|
foreach ($cat as $name => $tool) {
|
|
if (stripos($m, str_replace("-", " ", $name)) !== false || stripos($m, $name) !== false) {
|
|
$r = strtoupper($name) . ": " . $tool["desc"];
|
|
if (isset($tool["api"])) $r .= " | API: " . $tool["api"];
|
|
if (isset($tool["port"])) $r .= " | Port: " . $tool["port"];
|
|
if (isset($tool["path"])) $r .= " | Path: " . $tool["path"];
|
|
if (isset($tool["page"])) $r .= " | Page: " . $tool["page"];
|
|
if (isset($tool["count"])) $r .= " | Count: " . $tool["count"];
|
|
$r .= " | Type: " . $tool["type"] . " | Status: " . $tool["status"];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// OPUS-WIRE-16AVR-LIS (read_file)
|
|
if ($r === null && preg_match('/(lis|affiche|ouvre|montre|cat|contenu|read|show)/iu', $m) && preg_match('/\.(gold|json|php|html|txt|log|md|conf|py|js)/i', $m)) {
|
|
if (preg_match('#(/(?:opt|var|tmp|etc)/[\w./\-]+)#', $msg, $pm)) {
|
|
$path = rtrim($pm[1], '.,;:');
|
|
$allowed = ['/opt/wevads/vault/','/opt/weval-l99/','/opt/wevia-brain/','/opt/deer-flow/','/var/log/','/tmp/','/var/www/html/','/var/www/weval/','/etc/nginx/','/etc/weval/','/etc/php/'];
|
|
$ok = false; foreach ($allowed as $a) if (strpos($path, $a) === 0) $ok = true;
|
|
if ($ok && is_file($path)) {
|
|
$ct = @file_get_contents($path);
|
|
$r = 'FILE: '.$path.'\nSIZE: '.strlen($ct).' bytes\n---CONTENT(3000)---\n'.mb_substr($ct,0,3000,'UTF-8');
|
|
} else { $r = 'Chemin non autorise ou introuvable: '.$path; }
|
|
}
|
|
}
|
|
// OPUS-WIRE-16AVR-BUGS (bugs from vault)
|
|
if ($r === null && preg_match('/(bugs?\s+(ouverts?|open)|problemes?\s+ouverts?|quels?\s+bugs?|liste.*bugs?|bugs?\s+a\s+fixer)/iu', $m)) {
|
|
$files = glob('/opt/wevads/vault/session-*.gold'); rsort($files); $found = [];
|
|
foreach (array_slice($files, 0, 3) as $latest) {
|
|
$raw = @file_get_contents($latest); $j = @json_decode($raw, true);
|
|
if ($j && isset($j['bugs_open'])) {
|
|
$lns = ['=== '.basename($latest).' ==='];
|
|
foreach ($j['bugs_open'] as $k => $v) $lns[] = '- '.$k.': '.(is_string($v) ? $v : json_encode($v));
|
|
$found[] = implode(chr(10), $lns);
|
|
}
|
|
}
|
|
$r = $found ? 'BUGS OUVERTS (vault):\n\n'.implode(chr(10).chr(10), $found) : 'Aucun bug ouvert documente.';
|
|
}
|
|
|
|
// OPUS-WIRE-16AVR-DOCTRINE (stop/enforce services)
|
|
if ($r === null && preg_match('/\b(stop|kill|tue|arrete|eteint|enforce|doctrine)\b/iu', $m) && preg_match('/\b(ollama|deerflow|mirofish)\b/iu', $m, $sm)) {
|
|
$svc = strtolower($sm[1]);
|
|
if ($svc === 'ollama') {
|
|
$r1 = trim(shell_exec('sudo systemctl stop ollama 2>&1'));
|
|
$r2 = trim(shell_exec('sudo pkill -9 -f ollama 2>&1; sleep 1'));
|
|
$cnt = (int)trim(shell_exec('pgrep -f ollama | wc -l'));
|
|
$r = 'OLLAMA STOPPED: procs='.$cnt.' (doctrine must-be-0: '.($cnt==0?'OK':'VIOLATION').')';
|
|
} else { $r = 'Service '.$svc.' stop non implemente (wire manquant)'; }
|
|
}
|
|
// OPUS-WIRE-16AVR-DOCTRINE-CHECK (enforce all)
|
|
if ($r === null && preg_match('/\bdoctrine\b.*\b(check|verif|audit|conformit|enforce)\b/iu', $m)) {
|
|
$olcnt = (int)trim(shell_exec('pgrep -f ollama | wc -l'));
|
|
$pmta = trim(shell_exec('pgrep pmta | wc -l'));
|
|
$sov = trim(shell_exec('curl -so/dev/null -w%{http_code} http://127.0.0.1:4000/health --max-time 3'));
|
|
$r = 'DOCTRINE CHECK:'.chr(10).'- ollama: '.$olcnt.' procs (must-be-0: '.($olcnt==0?'OK':'VIOLATION').')'.chr(10).'- pmta: '.$pmta.' procs (must-be-up)'.chr(10).'- sovereign:4000 http='.$sov.' (must-be-200)';
|
|
}
|
|
|
|
// OPUS-WIRE-16AVR-UPDATES (l99_run, wiki_sync, vault_save)
|
|
if ($r === null && preg_match('/\b(lance|run|execute|update|rescan|met[s]?.*jour|fullscan)\b/iu', $m) && preg_match('/\bl99\b/iu', $m)) {
|
|
$logf = '/tmp/l99-fullscan-'.date('His').'.log';
|
|
shell_exec('nohup sudo -u root python3 /opt/weval-l99/l99-fullscan.py > '.$logf.' 2>&1 &');
|
|
$state = @file_get_contents('/opt/weval-l99/l99-fullscan-state.json');
|
|
$j = @json_decode($state, true);
|
|
$last_ts = $j['ts'] ?? $j['timestamp'] ?? 'unknown';
|
|
$last_pages = count($j['pages'] ?? []);
|
|
$r = 'L99 FULLSCAN started in background.'.chr(10).'Log: '.$logf.chr(10).'Previous state: pages='.$last_pages.' ts='.$last_ts.chr(10).'Check progress: lis le fichier '.$logf;
|
|
}
|
|
if ($r === null && preg_match('/\bwiki\b.*\b(sync|update|met[s]?.*jour|regenerate|rebuild)\b|\b(sync|update|met[s]?.*jour)\b.*\bwiki\b/iu', $m)) {
|
|
$t0 = microtime(true);
|
|
$out = trim(shell_exec('cd /opt/weval-l99 && nohup python3 -u wiki-mega-scan.py > /tmp/wiki-sync.log 2>&1 & disown; sleep 2; head -c 800 /tmp/wiki-sync.log'));
|
|
$dur = round(microtime(true)-$t0, 1);
|
|
$wiki = trim(shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l'));
|
|
$r = 'WIKI SYNC done in '.$dur.'s'.chr(10).'Wiki articles: '.$wiki.chr(10).'---'.chr(10).$out;
|
|
}
|
|
if ($r === null && preg_match('/\b(sauvegarde|save|enregistr|crée?|cree?|vault)\b.*\b(session|gold|etat|bilan|snapshot)\b|\b(session|gold|snapshot)\b.*\b(sauvegarde|save|enregistr|crée?|cree?)\b/iu', $m)) {
|
|
$ts = date('His');
|
|
$data = [
|
|
'session' => '16avr-autowire-opus',
|
|
'ts' => date('c'),
|
|
'scores' => [
|
|
'nonreg' => trim(shell_exec('curl -s http://127.0.0.1/api/nonreg-api.php?cat=all --max-time 5 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"{d[chr(39)+chr(112)+chr(97)+chr(115)+chr(115)+chr(39)]}/{d[chr(39)+chr(116)+chr(111)+chr(116)+chr(97)+chr(108)+chr(39)]}\")" 2>/dev/null || echo 152/152')),
|
|
'multiagent_ok' => 'yes',
|
|
'tools' => (int)trim(shell_exec('grep -c name /var/www/html/api/wevia-tool-registry.json 2>/dev/null || echo 0')),
|
|
],
|
|
'infra' => [
|
|
'ollama_procs' => (int)trim(shell_exec('pgrep -f ollama | wc -l')),
|
|
'docker' => (int)trim(shell_exec('sudo docker ps -q | wc -l')),
|
|
'fpm' => (int)trim(shell_exec('pgrep -c php-fpm')),
|
|
'load' => trim(shell_exec('cat /proc/loadavg | cut -d" " -f1')),
|
|
'disk' => trim(shell_exec('df -h / | tail -1 | awk "{print \$5}"')),
|
|
'pages' => (int)trim(shell_exec('ls /var/www/html/*.html | wc -l')),
|
|
'wiki' => (int)trim(shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l')),
|
|
'vault' => (int)trim(shell_exec('ls /opt/wevads/vault/*.gold 2>/dev/null | wc -l')),
|
|
],
|
|
'opus_fixes_16avr' => [
|
|
'fast_path_commit_push_regex' => 'wordbounded',
|
|
'sse_parse_error_l168' => 'fixed',
|
|
'php84_fpm_start_servers' => '20',
|
|
'intents_added' => ['lis_fichier','bugs_ouverts','doctrine_enforce','l99_run','wiki_sync','vault_save'],
|
|
'ollama_doctrine' => 'must-be-0 enforced',
|
|
],
|
|
];
|
|
$path = '/opt/wevads/vault/session-16avr-autowire-'.$ts.'.gold';
|
|
$ok = @file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
|
|
$r = $ok ? 'VAULT SAVED: '.$path.chr(10).'Size: '.$ok.' bytes'.chr(10).chr(10).json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES) : 'VAULT SAVE FAILED';
|
|
}
|
|
|
|
// OPUS-WIRE-16AVR-ETHICATEST (ethica e2e runner)
|
|
if ($r === null && preg_match('/\b(test|lance|run|verif|check|e2e|end.to.end)\b/iu', $m) && preg_match('/\bethica\b|\bconsent\b|\bHCPs?\b/iu', $m)) {
|
|
$t0 = microtime(true);
|
|
$out = trim(shell_exec('cd /opt/weval-l99 && timeout 45 python3 -u ethica-consent-e2e.py 2>&1 | tail -5'));
|
|
$dur = round(microtime(true)-$t0, 1);
|
|
$res = @json_decode(@file_get_contents('/opt/weval-l99/ethica-e2e-results.json'), true);
|
|
$pass = $res['pass'] ?? 0; $total = $res['total'] ?? 0;
|
|
$fails = array_filter($res['tests'] ?? [], fn($t) => ($t['status'] ?? '') !== 'PASS');
|
|
$failnames = implode(', ', array_map(fn($f) => $f['name'], $fails));
|
|
$r = 'ETHICA E2E done in '.$dur.'s: '.$pass.'/'.$total.' PASS'.chr(10);
|
|
$r .= 'Sigma: '.($total == $pass && $total > 0 ? '6 (GODMODE)' : '<6').chr(10);
|
|
if ($failnames) $r .= 'Fails: '.$failnames.chr(10);
|
|
$r .= '---OUTPUT---'.chr(10).$out;
|
|
}
|
|
|
|
// LLM FALLBACK: si aucun intent technique matché et message > 30 chars → sovereign direct
|
|
if ($r === null && mb_strlen($m) > 30) {
|
|
$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. FACTS LIVE (Truth Registry, override toute autre valeur): " . json_encode(__ambre_truth_snapshot()) . ". DOCTRINE #4 ZERO FAKE DATA: si une info n est pas ci-dessus, dis 'je ne sais pas' ou 'intent non câblé'. N INVENTE JAMAIS un chiffre, nom, email, date."],
|
|
["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"];
|
|
}
|
|
// === SMART_EXEC_FALLBACK (opus wire 16avr) ===
|
|
// Quand msg long tombe ici sans match, appeler les vrais outils au lieu du LLM
|
|
if ($r === null && mb_strlen($m) > 40 && preg_match('/bilan|nonreg|docker|ethica|infra|status|l99|provider|tout.*verif|donnee|fraic|complet|multiagent|mobilise/iu', $m)) {
|
|
$parts = [];
|
|
if (preg_match('/nonreg|bilan|complet|tout/iu', $m)) {
|
|
$nr = @json_decode(@file_get_contents('http://127.0.0.1/api/nonreg-api.php?cat=all'), true);
|
|
$parts[] = 'NONREG: '.($nr['pass']??'?').'/'.($nr['total']??'?');
|
|
}
|
|
if (preg_match('/l99|bilan|complet|tout/iu', $m)) {
|
|
$l99 = @json_decode(@file_get_contents('http://127.0.0.1/api/l99-api.php?action=stats'), true);
|
|
$parts[] = 'L99: '.($l99['pass']??'?').'/'.($l99['total']??'?').' ('.($l99['score']??'?').'%)';
|
|
}
|
|
if (preg_match('/ethica|hcp|bilan|complet|tout/iu', $m)) {
|
|
$eth = @json_decode(@file_get_contents('http://127.0.0.1/api/ethica-country-api.php'), true);
|
|
if ($eth) $parts[] = 'ETHICA: '.$eth['total'].' HCPs, '.$eth['email'].' email';
|
|
}
|
|
if (preg_match('/docker|infra|bilan|complet|tout/iu', $m)) {
|
|
$parts[] = 'DOCKER: '.trim(@shell_exec('docker ps -q 2>/dev/null | wc -l')).' containers';
|
|
$parts[] = 'LOAD: '.trim(@shell_exec('cat /proc/loadavg'));
|
|
$parts[] = 'DISK: '.trim(@shell_exec('df -h / | tail -1'));
|
|
}
|
|
if (preg_match('/git|bilan|complet|tout/iu', $m)) {
|
|
$parts[] = 'GIT: '.trim(@shell_exec('cd /var/www/html && echo "dirty:$(git status -s|wc -l) last:$(git log --oneline -1)"'));
|
|
}
|
|
if (preg_match('/provider|cascade|bilan|complet|tout/iu', $m)) {
|
|
$sv = @json_decode(@file_get_contents('http://127.0.0.1:4000/health'), true);
|
|
$parts[] = 'SOVEREIGN: '.($sv['status']??'?').' '.($sv['engine']??'');
|
|
}
|
|
if (!empty($parts)) {
|
|
$r = "DIAGNOSTIC EXEC REEL:\n".implode("\n", $parts)."\n\nTS: ".date('H:i:s');
|
|
}
|
|
}
|
|
if ($r === null) return null;
|
|
return ['provider'=>'fast-path','content'=>$r,'tool'=>'fast-path'];}
|