Files
html/api/wevia-master-api.php
opus 1968996243
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
auto-commit via WEVIA vault_git intent 2026-04-20T02:28:09+00:00
2026-04-20 04:28:10 +02:00

994 lines
56 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$_RAW=file_get_contents("php://input");$_JIN=json_decode($_RAW,true);$_mam=$_JIN["message"]??"";
@include __DIR__ . '/wevia-opus-arch-early.php'; // V41 before Resolver
// === OPUS4-AUTOWIRE-EARLY-v2 (17avr 02h20) ===
// Priority handler : master add/list intent bypass tout le pipeline (fast-path greedy cause racine)
// Zero regression : return silencieux si syntaxe pas matchee
if (!empty($_mam)) {
$__opus4_m = mb_strtolower(trim($_mam));
if (preg_match('/^\s*master\s+add\s+intent\s+([a-z0-9_]+)\s*::\s*(.+?)\s*::\s*(.+)$/i', $__opus4_m, $__m)) {
$__name = trim($__m[1]); $__trg = trim($__m[2]); $__cmd = trim($__m[3]);
$__pd = '/var/www/html/api/wired-pending'; @mkdir($__pd, 0755, true);
$__stub = "$__pd/intent-opus4-$__name.php";
$__ok = false; foreach (['/var/www/html/','/var/www/weval/','/opt/wevia-brain/','/opt/wevads/vault/','echo ','curl ','php8.4 ','git '] as $__p) { if (strpos($__cmd,$__p)!==false) { $__ok=true; break; } }
$__payload = ['name'=>$__name,'triggers'=>array_map('trim',explode('|',$__trg)),'cmd'=>$__cmd,'status'=>$__ok?'PENDING_APPROVAL':'PENDING_SECURITY_REVIEW','created_at'=>date('c'),'source'=>'opus4-autowire-early-v2'];
@file_put_contents($__stub, "<?php\nreturn " . var_export($__payload,true) . ";\n");
@file_put_contents('/var/log/weval/opus4-autowire.log', date('c')." EARLY_WIRED name=$__name\n", FILE_APPEND);
$__qf = '/var/www/html/api/wave-wiring-queue.json'; $__q = @json_decode(@file_get_contents($__qf), true) ?: []; $__q[] = $__payload; @file_put_contents($__qf, json_encode($__q, JSON_PRETTY_PRINT));
header('Content-Type: application/json');
echo json_encode(['response'=>"Intent '$__name' wired (status={$__payload['status']}). Stub: $__stub", 'executed'=>true, 'provider'=>'opus4-autowire-early', 'intent'=>$__name, 'status'=>$__payload['status'], 'triggers'=>$__payload['triggers']]);
exit;
}
if (preg_match('/^\s*master\s+(list|show)\s+intents?\s*$/i', $__opus4_m)) {
$__stubs = @glob('/var/www/html/api/wired-pending/intent-opus4-*.php') ?: [];
$__sum = []; foreach ($__stubs as $__s) { ob_start(); $__info = @include $__s; @ob_end_clean(); if (is_array($__info)) $__sum[] = ['name'=>$__info['name']??'?','status'=>$__info['status']??'?','triggers'=>$__info['triggers']??[]]; }
header('Content-Type: application/json');
echo json_encode(['response'=>'Wired intents: '.count($__stubs)."\n".json_encode($__sum, JSON_PRETTY_PRINT), 'executed'=>true, 'provider'=>'opus4-autowire-early-list', 'count'=>count($__stubs)]);
exit;
}
}
// === OPUS4-AUTOWIRE-EARLY-v2 END ===
// === OPUS5-STUB-DISPATCHER-v1 (17avr) ===
// Route messages to opus4-wired stubs BEFORE fast-path/dynamic-resolver capture.
// This unlocks WEVIA autonomy: user types a stub trigger, the cmd executes immediately.
if (isset($_mam) && $_mam) {
$__sd_msg = mb_strtolower(trim($_mam));
$__sd_stubs = @glob('/var/www/html/api/wired-pending/intent-opus4-*.php') ?: [];
foreach ($__sd_stubs as $__sd_s) {
ob_start(); $__sd_info = @include $__sd_s; @ob_end_clean();
if (!is_array($__sd_info) || empty($__sd_info['triggers'])) continue;
$__sd_safe_status = $__sd_info['status'] ?? '';
if (!in_array($__sd_safe_status, ['EXECUTED', 'PENDING_APPROVAL'])) continue;
foreach ($__sd_info['triggers'] as $__sd_trg) {
$__sd_trg = trim($__sd_trg);
if ($__sd_trg === '') continue;
$__sd_trg_lc = mb_strtolower($__sd_trg);
// ROOT-CAUSE-FIX 19avr v96: word boundary for short triggers (doctrine #13)
if (mb_strlen($__sd_trg_lc) <= 4) {
$__sd_match = (bool) preg_match('/\b' . preg_quote($__sd_trg_lc, '/') . '\b/ui', $__sd_msg);
} else {
$__sd_match = (stripos($__sd_msg, $__sd_trg_lc) !== false);
}
if ($__sd_match) {
$__sd_cmd = $__sd_info['cmd'] ?? '';
$__sd_safe = false;
foreach (['/var/www/html/', 'echo ', 'curl ', 'php8.4 ', 'grep ', 'psql ', 'cat /var/log/'] as $__sd_p) {
if (stripos($__sd_cmd, $__sd_p) === 0 || stripos($__sd_cmd, " $__sd_p") !== false) { $__sd_safe = true; break; }
}
if (!$__sd_safe) continue;
$__sd_out = @shell_exec('timeout 15 ' . $__sd_cmd . ' 2>&1');
// ROOT-CAUSE-FIX-19avr: skip if output empty (doctrine #13, let cascade handle)
if (trim((string)$__sd_out) === '') continue;
header('Content-Type: application/json');
echo json_encode([
'response' => "Intent '{$__sd_info['name']}' executed (trigger: $__sd_trg)\n" . trim((string)$__sd_out),
'executed' => true,
'provider' => 'opus5-stub-dispatcher',
'intent' => $__sd_info['name'],
'trigger_matched' => $__sd_trg,
'output' => trim((string)$__sd_out)
]);
@file_put_contents('/tmp/opus5-dispatcher.log', date('c') . " MATCH intent={$__sd_info['name']} trg=$__sd_trg\n", FILE_APPEND);
exit;
}
}
}
}
// === OPUS5-STUB-DISPATCHER-v1 END ===
// === OPUS_ROOT_CAUSE_GUARDS_EARLY_17AVR ===
if (!empty($_mam)) {
$__opus_m = $_mam;
if (preg_match('/\bexecute\s+SELECT|\bexec.*?sql|SELECT\s+.+?\s+FROM\s+[a-zA-Z._]+/i', $__opus_m)) {
if (preg_match('/(SELECT\s+[\s\S]+?)(?:;|$)/i', $__opus_m, $__qm)) {
$__q = trim($__qm[1]);
if (preg_match('/\b(DROP|DELETE|UPDATE|INSERT|TRUNCATE|GRANT|REVOKE|ALTER)\b/i', $__q)) {
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'SQL GUARD: mutations bloquees','tool'=>'sql_guard']); exit;
}
$__out = @shell_exec('PGPASSWORD=admin123 timeout 10 psql -h 10.1.0.3 -U admin -d adx_system -c ' . escapeshellarg(str_replace("'", "''", $__q)) . ' 2>&1');
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'SQL EXEC REAL (S95 admin):' . PHP_EOL . substr($__out ?? 'DB_UNREACHABLE', 0, 2500),'tool'=>'sql_exec_real','source'=>'early-guard-primary']); exit;
}
}
if (preg_match('/\b(?:commit|git\s+add)\s+(?:le\s+)?(?:fichier|file)?\s*([a-zA-Z0-9._\/\-]+\.(?:php|html|js|css|json|md|py|sh))/iu', $__opus_m, $__gm)) {
$__file = $__gm[1];
$__full = '/var/www/html/' . ltrim($__file, '/');
if (!is_file($__full)) {
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'GIT: file not found: ' . $__full,'tool'=>'git_commit_real']); exit;
}
@shell_exec('sudo chattr -i ' . escapeshellarg($__full) . ' 2>&1');
$__out = @shell_exec('cd /var/www/html && git add ' . escapeshellarg($__file) . ' 2>&1 && git commit -m "[wevia-auto] commit $__file" 2>&1 | tail -5');
@shell_exec('sudo chattr +i ' . escapeshellarg($__full) . ' 2>&1');
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'GIT COMMIT REAL for ' . $__file . ':' . PHP_EOL . trim($__out ?? ''),'tool'=>'git_commit_real','source'=>'early-guard-primary']); exit;
}
if (preg_match('/\b(?:pourquoi|why)[\s\S]*?(?:CRM|pipeline|send_contacts|send.contacts.merge)[\s\S]*?(?:vide|empty|que\s+\d+|seulement|stopp[eé]|arrêt[eé]|halt)|crm[\s\S]*?diagnostic|pipeline[\s\S]*?root.*?cause|send_contacts_merge[\s\S]*?(?:stopp|arrêt|pourquoi|why)|crm\s+staleness|doctrine\s*55/iu', $__opus_m)) {
$__p = [];
$__p[] = '=== CRM ROOT CAUSE DIAGNOSTIC (S95) ===';
$__q1 = 'SELECT stage,count(*) c FROM admin.pipeline_deals GROUP BY stage ORDER BY c DESC';
$__p[] = 'DEALS PAR STAGE:' . PHP_EOL . trim(@shell_exec('PGPASSWORD=admin123 timeout 10 psql -h 10.1.0.3 -U admin -d adx_system -t -c ' . escapeshellarg($__q1) . ' 2>&1') ?? 'N/A');
$__q2 = "SELECT 'deals' t,count(*) c FROM admin.pipeline_deals UNION ALL SELECT 'companies',count(*) FROM admin.pipeline_companies UNION ALL SELECT 'contacts',count(*) FROM admin.pipeline_contacts UNION ALL SELECT 'leads',count(*) FROM admin.weval_leads UNION ALL SELECT 'activities',count(*) FROM admin.pipeline_activities";
$__p[] = 'VOLUMES TABLES:' . PHP_EOL . trim(@shell_exec('PGPASSWORD=admin123 timeout 10 psql -h 10.1.0.3 -U admin -d adx_system -t -c ' . escapeshellarg($__q2) . ' 2>&1') ?? 'N/A');
$__p[] = 'HYPOTHESES ROOT CAUSE: 1) Import stoppe 2) Purge 3) Sync Twenty CRM casse 4) Schema change. ACTIONS: relancer import + kaizen 5Why';
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>implode(PHP_EOL . PHP_EOL, $__p),'tool'=>'crm_diagnostic_real','source'=>'early-guard-primary']); exit;
}
if (preg_match('/\btu\s+as\s+halluc|auto.?wire.*fix|fix.*hallucination|bloque.*llm.?fallback/iu', $__opus_m)) {
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'AUTO-WIRE ACK: Opus-early-guards actifs. SQL->psql exec reel, git->exec reel, CRM->query reelle. Doctrine 7 OK. Marker: OPUS_ROOT_CAUSE_GUARDS_EARLY_17AVR','tool'=>'auto_wire_ack','source'=>'early-guard-primary']); exit;
}
if (preg_match('/\bsovereign\s+(?:timeout|down|pourquoi|diagnostic|fix)/iu', $__opus_m)) {
$__h = @shell_exec('curl -sk --max-time 3 http://127.0.0.1:4000/health 2>&1 | head -c 300');
$__p2 = @shell_exec('ss -tln 2>/dev/null | grep -E ":4000|:11434|:8010" | head -5');
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>'SOVEREIGN DIAGNOSTIC:' . PHP_EOL . 'health :4000: ' . trim($__h ?? 'no resp') . PHP_EOL . 'ports:' . PHP_EOL . trim($__p2 ?? 'N/A') . PHP_EOL . PHP_EOL . 'FIX: sudo systemctl restart sovereign','tool'=>'sovereign_diagnostic','source'=>'early-guard-primary']); exit;
}
}
// OPUS_MEMORY_GUARD_17AVR
// GUARD 6: Memory recall/store (priorité EARLY avant ram_free)
if (preg_match('/\b(?:memory|memoire)\s+(?:recall|store|rappel|storage|retrieve)|recall\s+memory|memorise(?:\s+ceci)?\s+/iu', $__opus_m)) {
if (preg_match('/(?:recall|rappel|retrieve)/i', $__opus_m)) {
$__q = preg_replace('/\b(?:memory|memoire|recall|rappel|retrieve)\b/i', '', $__opus_m);
$__q = trim(preg_replace('/\s+/', ' ', $__q));
$__out = @shell_exec('timeout 10 bash /opt/weval-ops/top-ia/memory_recall.sh ' . escapeshellarg($__q) . ' 2>&1');
} else {
$__out = @shell_exec('timeout 10 bash /opt/weval-ops/top-ia/memory_store.sh ' . escapeshellarg($__opus_m) . ' 2>&1');
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>"MEMORY OP (Qdrant):" . PHP_EOL . trim($__out ?? 'N/A'),'tool'=>'memory_op_real','source'=>'early-guard-primary']);
exit;
}
// GUARD 7: Self heal infra explicit
if (preg_match('/\bself\s+heal\s+infra|heal\s+infrastructure|verifie\s+infra\s+sante/iu', $__opus_m)) {
$__out = @shell_exec('timeout 20 sudo bash /opt/weval-ops/top-ia/self_heal_infra.sh 2>&1');
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>"SELF_HEAL_INFRA:" . PHP_EOL . trim($__out ?? 'N/A'),'tool'=>'self_heal_infra_real','source'=>'early-guard-primary']);
exit;
}
// GUARD 8: Dormant capabilities list
if (preg_match('/\b(?:dormant|dormants)\s+(?:capabilit|tools|scripts|oss|clones)|liste\s+dormant|archive\s+dormant/iu', $__opus_m)) {
$__arch = '/opt/wevia-brain/DORMANT-CAPABILITIES-ARCHIVE.json';
$__data = @file_get_contents($__arch);
$__j = @json_decode($__data, true);
$__summary = [];
$__summary[] = "=== DORMANT CAPABILITIES ARCHIVE ===";
$__summary[] = "Date archive: " . ($__j['date'] ?? '?');
$__summary[] = "Reason: " . ($__j['reason'] ?? '?');
foreach (($__j['categories'] ?? []) as $__cat => $__info) {
$__summary[] = "- $__cat: " . ($__info['count'] ?? '?') . " files (" . ($__info['status'] ?? '?') . ")";
}
// Also OSS dormants
$__oss = @file_get_contents('http://localhost/api/dormant-scan.php');
$__oj = @json_decode($__oss, true);
if ($__oj) {
$__summary[] = "\nOSS clones: " . ($__oj['oss_total'] ?? '?') . " total, " . ($__oj['oss_dormant'] ?? '?') . " dormants";
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>implode(PHP_EOL, $__summary),'tool'=>'dormant_capabilities_list','source'=>'early-guard-primary']);
exit;
}
// OPUS_DBINFRA_GUARDS_17AVR
// GUARD 11: DB stats live (674 tables breakdown)
if (preg_match('/\b(?:db\s+stats|database\s+stats|combien\s+tables|stats\s+postgres|volume\s+database|size\s+database|postgres\s+stats|db\s+volume)\b/iu', $__opus_m)) {
$__out = @file_get_contents("http://127.0.0.1/api/db-stats-live.php");
$__d = @json_decode($__out, true);
if ($__d && isset($__d['summary'])) {
$__s = $__d['summary'];
$__msg = "DB STATS LIVE (PostgreSQL):\n";
$__msg .= " Tables total: " . $__s['total_tables'] . " (active: " . $__s['active_tables'] . ", empty: " . $__s['empty_tables'] . ")\n";
$__msg .= " Rows total: " . number_format($__s['total_rows'], 0, '.', ',') . "\n";
foreach (($__s['schemas'] ?? []) as $__sn => $__sc) {
$__msg .= " Schema " . $__sn . ": " . $__sc['tables'] . " tables, " . number_format($__sc['rows'], 0, '.', ',') . " rows\n";
}
$__msg .= "\nTop 5 tables:\n";
foreach (array_slice($__d['top_tables'] ?? [], 0, 5) as $__t) {
$__msg .= " " . $__t['table'] . ": " . number_format($__t['rows'], 0, '.', ',') . "\n";
}
} else {
$__msg = "DB STATS: query failed or empty";
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'db_stats_live','source'=>'early-guard-primary']);
exit;
}
// GUARD 12: Infra live
if (preg_match('/\b(?:infra\s+live|infra\s+status|infra\s+dashboard|system\s+stats|load\s+avg|disque\s+plein|memoire\s+ram|docker\s+status)\b/iu', $__opus_m)) {
$__out = @file_get_contents("http://127.0.0.1/api/infra-live.php");
$__d = @json_decode($__out, true);
if ($__d && isset($__d['system'])) {
$__sys = $__d['system'];
$__msg = "INFRA LIVE S204:\n";
$__msg .= " Load: " . $__sys['load1'] . " / " . $__sys['load5'] . " / " . $__sys['load15'] . "\n";
$__msg .= " Memory: " . $__sys['mem_pct'] . "% (" . round($__sys['mem_used_kb']/1024/1024, 1) . "G / " . round($__sys['mem_total_kb']/1024/1024, 1) . "G)\n";
$__msg .= " Disk /: " . $__sys['disk_pct'] . "\n";
$__msg .= " FPM processes: " . $__sys['fpm_processes'] . "\n";
$__msg .= " Uptime: " . round($__sys['uptime_s']/3600, 1) . "h\n";
$__msg .= " Docker: " . ($__d['docker']['count'] ?? 0) . " containers\n";
$__active = 0;
foreach (($__d['services'] ?? []) as $__svc => $__st) {
if ($__st === 'active') $__active++;
}
$__msg .= " Services active: $__active/" . count($__d['services'] ?? []) . "\n";
} else {
$__msg = "INFRA: query failed";
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'infra_live','source'=>'early-guard-primary']);
exit;
}
// GUARD 13: Dashboard hub redirect
if (preg_match('/\b(?:dashboard\s+hub|dashboards\s+hub|all\s+dashboards|tous\s+dashboards|liste\s+dashboards)\b/iu', $__opus_m)) {
$__msg = "DASHBOARDS HUB:\n";
$__msg .= "Navigation: https://weval-consulting.com/dashboards-hub.html\n\n";
$__msg .= "Business:\n";
$__msg .= " /ethica-dashboard-live.html (146K HCPs pharma)\n";
$__msg .= " /office-365-dashboard-live.html (6403 accounts)\n";
$__msg .= " /crm-dashboard-live.html (Twenty + legacy 256K)\n";
$__msg .= "\nTechnique:\n";
$__msg .= " /database-dashboard-live.html (674 tables, 12M rows)\n";
$__msg .= " /infra-dashboard-live.html (load/mem/disk/docker)\n";
$__msg .= " /dormant-dashboard.html (158 capabilities)\n";
$__msg .= " /wevia-orchestrator.html (intents/tools/skills)\n";
$__msg .= "\nArchi:\n";
$__msg .= " /agents-archi.html (61 agents 3D)\n";
$__msg .= " /director-center.html (C-level)\n";
$__msg .= " /cartographie-screens.html (196 HTML map)\n";
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'dashboards_hub','source'=>'early-guard-primary']);
exit;
}
// GUARD 14: Kaizen CRM show
if (preg_match('/\b(?:kaizen\s+crm|5\s*why\s+crm|decision\s+twenty|crm\s+consolidation|twenty\s+vs\s+legacy)\b/iu', $__opus_m)) {
$__kz = @file_get_contents('/var/www/html/api/wiki/kaizen-crm-17avr.md');
$__brief = $__kz ? substr($__kz, 0, 2500) : 'Kaizen doc not found';
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>"KAIZEN CRM 5Why + DECISION:\nURL: https://weval-consulting.com/wiki/kaizen-crm-17avr.md\n\n" . $__brief,'tool'=>'kaizen_crm_show','source'=>'early-guard-primary']);
exit;
}
// GUARD 15: Bridge status (pipeline_activities)
if (preg_match('/\b(?:bridge\s+status|pipeline\s+activities|crm\s+bridge)\b/iu', $__opus_m)) {
$__state = @file_get_contents('/opt/weval-ops/crm-bridge-state.json');
$__count = trim(@shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c \"SELECT count(*) FROM admin.pipeline_activities\" 2>&1"));
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>"CRM BRIDGE STATUS:\n pipeline_activities: " . $__count . " rows\n state: " . ($__state ?? 'N/A'),'tool'=>'bridge_status','source'=>'early-guard-primary']);
exit;
}
// GUARD 16: B2B/B2C segmentation show
if (preg_match('/\b(?:segmentation|b2b|b2c|classification|industr[iy]|activite|classif)\s*(?:contacts|leads|crm|dashboard|live)?|separe\s+b2b|classer\s+(?:par|selon)\s+activit/iu', $__opus_m)) {
$__out = @file_get_contents('http://127.0.0.1/api/contacts-segmentation-live.php');
$__d = @json_decode($__out, true);
if ($__d) {
$__msg = "CONTACTS SEGMENTATION LIVE:\n";
$__p = $__d['progress'] ?? [];
$__msg .= " leads: " . number_format($__p['leads_classified'] ?? 0, 0, '.', ',') . " / " . number_format($__p['leads_total'] ?? 0, 0, '.', ',') . " (" . ($__p['leads_pct'] ?? 0) . "%)\n";
$__msg .= " send_contacts: " . number_format($__p['send_contacts_classified'] ?? 0, 0, '.', ',') . " / " . number_format($__p['send_contacts_total'] ?? 0, 0, '.', ',') . " (" . ($__p['send_contacts_pct'] ?? 0) . "%)\n";
$__msg .= "\nIndustries B2B Top 10:\n";
$__i = 0;
foreach (($__d['industries_b2b_all_sources'] ?? $__d['industries_b2b'] ?? [] ?? []) as $__ind => $__cnt) {
$__msg .= " " . $__ind . ": " . number_format($__cnt, 0, '.', ',') . "\n";
if (++$__i >= 10) break;
}
$__msg .= "\nDashboard: https://weval-consulting.com/contacts-segmentation-dashboard.html";
} else {
$__msg = "Segmentation query failed";
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'segmentation_b2b_b2c','source'=>'early-guard-primary']);
exit;
}
// GUARD 17: Visual Management dashboard (doctrine 65)
if (preg_match('/\b(?:visual\s*management|vm\s*dashboard|kpi\s*wall|tableau\s*de\s*bord|lean\s*6\s*sigma|health\s*score|kpi\s*live|andon\s+(?:alerts?|live|show)|vm\s+live)\b/iu', $__opus_m)) {
$__v = @file_get_contents('http://127.0.0.1/api/visual-management-live.php');
$__d = @json_decode($__v, true);
if ($__d) {
$__b = $__d['business'] ?? [];
$__f = $__d['flux'] ?? [];
$__q = $__d['quality'] ?? [];
$__msg = "VISUAL MANAGEMENT LIVE (doctrine 65):\n";
$__msg .= " Health: " . ($__d['health_score'] ?? 0) . "/100 (" . ($__d['health_status'] ?? '?') . ")\n";
$__msg .= " Andons: " . ($__d['andons_count'] ?? 0) . "\n\n";
$__msg .= "BUSINESS:\n";
$__msg .= " CRM Deals: " . number_format($__b['crm_deals'] ?? 0) . " (" . number_format(($__b['crm_deals_amount_eur'] ?? 0)/1000) . "k EUR)\n";
$__msg .= " Companies: " . number_format($__b['crm_companies'] ?? 0) . "\n";
$__msg .= " Contacts B2B: " . number_format($__b['crm_contacts_b2b'] ?? 0) . "\n";
$__msg .= " Activities: " . number_format($__b['crm_activities'] ?? 0) . "\n";
$__msg .= " Ethica HCPs: " . number_format($__b['ethica_hcps'] ?? 0) . "\n\n";
$__msg .= "FLUX:\n";
$__msg .= " send_contacts 30j: " . number_format($__f['send_contacts_last_30d'] ?? 0) . "\n";
$__msg .= " graph_send 7j: " . number_format($__f['graph_send_last_7d'] ?? 0) . "\n";
$__msg .= " weval_leads 7j: " . number_format($__f['weval_leads_last_7d'] ?? 0) . "\n\n";
$__msg .= "QUALITY: NonReg " . ($__q['nonreg_score'] ?? 0) . "% | L99 " . ($__q['l99_score'] ?? 0) . "%\n\n";
if (!empty($__d['andons'])) {
$__msg .= "ALERTES:\n";
foreach ($__d['andons'] as $__a) {
$__msg .= " [" . $__a['severity'] . "] " . $__a['kpi'] . ": " . $__a['message'] . "\n";
}
}
$__msg .= "\nDashboard: https://weval-consulting.com/visual-management.html";
} else {
$__msg = "Visual Management query failed";
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'visual_management_show','source'=>'early-guard-primary']);
exit;
}
// GUARD 18: Andon History (doctrine 55 + 65 monitoring)
if (preg_match('/\b(?:andon\s+history|historique\s+andon|alertes\s+historique|flux\s+monitor|andon\s+log)\b/iu', $__opus_m)) {
$__hist = @shell_exec("PGPASSWORD=admin123 timeout 10 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F '|' -c \"SELECT ts::text, severity, kpi, LEFT(message,80), CASE WHEN resolved_at IS NULL THEN 'ACTIVE' ELSE 'RESOLVED' END FROM admin.andon_history ORDER BY ts DESC LIMIT 15\" 2>&1");
$__msg = "ANDON HISTORY (15 derniers):\n\n";
foreach (array_filter(array_map('trim', explode(chr(10), $__hist ?? ''))) as $__l) {
$__p = explode('|', $__l);
if (count($__p) >= 5) {
$__msg .= " [" . $__p[4] . "] " . $__p[1] . " " . $__p[2] . ": " . $__p[3] . " (" . substr($__p[0],0,16) . ")\n";
}
}
$__msg .= "\nCron: */15min · Table: admin.andon_history · Doctrine 55+65";
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>$__msg,'tool'=>'andon_history','source'=>'early-guard-primary']);
exit;
}
// END OPUS_DBINFRA_GUARDS_17AVR
// === END OPUS_ROOT_CAUSE_GUARDS_EARLY_17AVR ===
// V26-SURGICAL normalizer prehook (Opus 17avr 17h50) — fix "combien j'ai de leads" → route correct
@require_once __DIR__ . "/wevia-nl-normalizer-prehook.php";
// === OPUS_BUSINESS_COUNT_GUARD_17AVR (natural language → SQL real) ===
if (!empty($_mam)) {
$__bm = $_mam;
// Map entités → table
$__entity_map = [
'deals?' => 'admin.pipeline_deals',
'contacts?' => 'admin.pipeline_contacts',
'compan(?:y|ies)' => 'admin.pipeline_companies',
'activit[eé]s?' => 'admin.pipeline_activities',
'enrichissements?|enrichments?' => 'admin.pipeline_enrichments',
'leads?' => 'admin.weval_leads',
'hcps?|m[eé]decins?' => 'ethica.medecins_real',
'optins?|consents?' => 'ethica.consent_optins',
'campaigns?|campagnes?' => 'ethica.campaigns',
'send_contacts?' => 'admin.send_contacts',
'crm_contacts?' => 'admin.crm_contacts',
'office_accounts?' => 'admin.office_accounts',
'crm_leads?' => 'admin.crm_leads',
'ads_accounts?' => 'admin.ads_accounts',
'affiliate_conversions?' => 'admin.affiliate_conversions',
'aqualink_clicks?' => 'admin.aqualink_clicks',
];
if (preg_match('/\b(?:combien|nombre|count|total)\s+(?:de\s+|d\'|of\s+)?([a-z_\xC0-\xFF]+)/iu', $__bm, $__cm)) {
$__raw = mb_strtolower(trim($__cm[1]));
$__table = null;
foreach ($__entity_map as $__pat => $__tbl) {
if (preg_match('/^' . $__pat . '$/i', $__raw) || preg_match('/\b' . $__pat . '\b/i', $__raw)) {
$__table = $__tbl; break;
}
}
// Also allow inline table reference "admin.pipeline_deals" etc.
if (!$__table && preg_match('/\b((?:admin|ethica|weval|public)\.[a-z_]+)\b/i', $__bm, $__tm)) {
$__table = $__tm[1];
}
if ($__table) {
// Detect filters (status, date range, country)
$__where = [];
if (preg_match('/\b(actif|active|open)\b/i', $__bm)) $__where[] = "(status='active' OR status='open' OR status='actif')";
if (preg_match('/\b(converted|converti)\b/i', $__bm)) $__where[] = "converted=true";
if (preg_match('/\bnon.?convert[ei]/i', $__bm)) $__where[] = "(converted IS NULL OR converted=false)";
if (preg_match('/\b(?:30|trente)\s*(?:derniers?|dernier)\s*jours?|last\s+30\s*days?/i', $__bm)) $__where[] = "created_at >= CURRENT_DATE - INTERVAL '30 days'";
if (preg_match('/\b(?:7|sept)\s*(?:derniers?|dernier)\s*jours?|last\s+7\s*days?|derni[eè]re?\s+semaine/i', $__bm)) $__where[] = "created_at >= CURRENT_DATE - INTERVAL '7 days'";
if (preg_match('/\bDZ|alg[ée]rie\b/i', $__bm)) $__where[] = "pays='DZ'";
if (preg_match('/\bMA|maroc\b/i', $__bm)) $__where[] = "pays='MA'";
if (preg_match('/\bTN|tunisie\b/i', $__bm)) $__where[] = "pays='TN'";
// Comparison "30j vs 30j avant"
if (preg_match('/\b(?:30j|30\s+jours?|derniers?\s+30|last\s+30)[\s\S]*?(?:vs|versus|contre|avant|compar[eé])/i', $__bm)) {
$__q = "SELECT 'last_30d' periode, count(*) c FROM {$__table} WHERE created_at >= CURRENT_DATE - INTERVAL '30 days' UNION ALL SELECT 'prev_30d', count(*) FROM {$__table} WHERE created_at >= CURRENT_DATE - INTERVAL '60 days' AND created_at < CURRENT_DATE - INTERVAL '30 days'";
} else {
$__wc = empty($__where) ? "" : " WHERE " . implode(' AND ', $__where);
$__q = "SELECT count(*) c FROM {$__table}{$__wc}";
}
$__cmd = 'PGPASSWORD=admin123 timeout 10 psql -h 10.1.0.3 -U admin -d adx_system -c ' . escapeshellarg($__q) . ' 2>&1';
$__out = @shell_exec($__cmd);
header('Content-Type: application/json');
echo json_encode([
'provider' => 'opus-early-guard',
'content' => "COUNT BUSINESS REAL (S95):\nTable: $__table\nQuery: $__q\n\nResult:\n" . trim($__out ?? 'DB_ERR'),
'tool' => 'count_business_real',
'source' => 'early-guard-primary',
'table' => $__table,
]);
exit;
}
}
// Crons CRM / system crons diagnostic
if (preg_match('/\b(?:crons?|cron\s+job|import)[\s\S]*?(?:CRM|crm|import|stopp[eé]|cass[eé]|fail|broken)|import[s]?\s+(?:stopp|cass|fail|broken)/iu', $__bm)) {
$__c = [];
$__c[] = "=== CRONS DIAGNOSTIC ===";
$__c[] = "S204 crontab www-data:\n" . trim(@shell_exec('crontab -u www-data -l 2>&1 | head -30') ?? 'N/A');
$__c[] = "S204 crontab root:\n" . trim(@shell_exec('sudo crontab -u root -l 2>&1 | head -30') ?? 'N/A');
// Import-related crons
$__c[] = "Import/CRM crons grep:\n" . trim(@shell_exec('(sudo crontab -u root -l; crontab -u www-data -l) 2>&1 | grep -iE "crm|import|pipeline|deal|lead" | head -15') ?? 'N/A');
// Latest import log
$__logs = @shell_exec('ls -t /var/log/weval/*crm* /var/log/weval/*import* /var/log/weval/*pipeline* 2>/dev/null | head -3');
$__c[] = "Latest import logs files:\n" . trim($__logs ?? 'aucun log /var/log/weval/');
if ($__logs) {
$__first = trim(explode("\n", $__logs)[0]);
if (is_file($__first)) $__c[] = "Tail $__first:\n" . trim(@shell_exec("tail -15 " . escapeshellarg($__first)) ?? '');
}
header('Content-Type: application/json');
echo json_encode(['provider'=>'opus-early-guard','content'=>implode("\n\n", $__c),'tool'=>'crons_diagnostic_real','source'=>'early-guard-primary']);
exit;
}
}
// === END OPUS_BUSINESS_COUNT_GUARD_17AVR ===
// === V77 PARALLEL MAX-AGENTS (19avr Opus - zero ecrasement) ===
// Intercept max agents / tous les agents / parallelise BEFORE standard SSE.
// V77 fires ~37 agents in parallel ~256ms vs standard sequential 3.4s.
if (!empty($_mam)) {
$_v77_low = mb_strtolower($_mam);
$_v77_triggers = ['max agents','max d agents','tous les agents','tous agents','agents maximum','maximum agents','full parallele','parallel max','max parallele','parallelise','100 agents','v77'];
foreach ($_v77_triggers as $_t) {
if (stripos($_v77_low, $_t) !== false) {
header('X-Accel-Buffering: no');
$msg = $_mam;
include __DIR__ . '/wevia-v77-parallel-executor.php';
exit;
}
}
}
// === V77 PARALLEL MAX-AGENTS END ===
// === V78 CAPABILITY DISPATCHER (19avr Opus) ===
// Intercept dispatcher / selective agents / focus agents BEFORE standard SSE.
// V78 selects relevant agents by keyword matching, fires parallel.
if (!empty($_mam)) {
$_v78_low = mb_strtolower($_mam);
$_v78_triggers = ['dispatcher','selective agents','focus agents','smart agents','agents selectif','agents pertinents','capability dispatcher','agents sur mesure'];
foreach ($_v78_triggers as $_t) {
if (stripos($_v78_low, $_t) !== false) {
header('X-Accel-Buffering: no');
$msg = $_mam;
include __DIR__ . '/wevia-v78-capability-dispatcher.php';
exit;
}
}
}
// === V78 CAPABILITY DISPATCHER END ===
// OPUS WIRE: Content-generation guard — bypass multiagent for content requests
$_is_content_req = preg_match('/(?:r[eé]dige|[eé]cris|pr[eé]pare|g[eé]n[eè]re|compose|cr[eé]e|fais)[\s\-].*(?:post|linkedin|article|contenu|texte|email|marketing|communic|blog|newsletter|carousel|pitch)/iu', $_mam)
|| preg_match('/(?:post|article|contenu|texte)[\s\-].*(?:linkedin|marketing|r[eé]seau|social)/iu', $_mam)
|| preg_match('/(?:plan|calendrier|strat[eé]gie)[\s\-]+(?:de\s+)?(?:contenu|[eé]ditorial|publication|linkedin|marketing)/iu', $_mam);
// V27-SURGICAL 20avr Opus (doctrine #73 Type B + #54): exclude structured intents from content-guard
if ($_is_content_req && preg_match('/(kaizen|muda|andon|5s|pdca|gemba|poka[\s-]?yoke|a3|ticket|reminder|todo|stub|intent|dashboard|autonomy|honest|orphans|plans?\s+list|plan\s+status|kpi\s+feeder|health\s+check|capabilities|ethica\s+count|paperclip|git\s+(full|status|commit))/iu', $_mam)) {
$_is_content_req = false; // structured intent has priority over content-gen
}
if (!$_is_content_req) { // Only multiagent SSE if NOT a content request
if(preg_match("/multi[\s\-]?agents?|plusieurs[\s\-]?agents?|\d+\s*agents?[\s\-]+(en[\s\-]+)?parall[eè]le|agents?[\s\-]+en[\s\-]+parall[eè]le|agir[\s\-]+en[\s\-]+(multi[\s\-]?)?agents?/iu",$_mam)){$_GET["msg"]=$_mam;header("X-Accel-Buffering: no");include __DIR__."/wevia-sse-orchestrator.php";exit;}}
// OPUS WIRE: Content enrichment — inject real platform data for content-generation requests
if ($_is_content_req ?? false) {
$_platform_data = "DONNÉES PLATEFORME RÉELLES WEVAL (à utiliser dans le contenu):\n"
. "- 153/153 tests NonReg (zéro régression)\n"
. "- 930 agents en production\n"
. "- 382 outils dans le resolver dynamique\n"
. "- 131 639 HCPs Ethica (109K email, 131K tel)\n"
. "- 12/13 providers IA souverains, 0€\n"
. "- 19 containers Docker\n"
. "- -40% délais de pilotage\n"
. "- 1,2M€ de gaspillage identifié\n"
. "- ROI en 4 mois\n"
. "- POC gratuit 2 semaines\n"
. "- 15 dépôts enterprise\n";
$_mam = $_platform_data . "\n\nDEMANDE UTILISATEUR: " . $_mam;
// CONTENT_ENRICHMENT_WIRE marker
// OPUS_CONTENT_DIRECT_LLM_FIX — bypass opus-intents + fast-path for content requests
// Direct to sovereign LLM with enriched $_mam
$__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 Master, IA souveraine de WEVAL Consulting Casablanca. Tu es un expert en rédaction de contenu professionnel, marketing digital et LinkedIn. Tu rédiges du contenu premium en français impeccable : orthographe parfaite, accents corrects, ton de dirigeant. Tu utilises les données réelles de la plateforme WEVAL fournies ci-dessous pour enrichir tes textes. Sois concret, percutant, orienté storytelling terrain. Maximum 1200 caractères par post sauf indication contraire."],
["role" => "user", "content" => $_mam]
],
"max_tokens" => 2000,
"stream" => false
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 25
]);
$__cr = curl_exec($__ch); curl_close($__ch);
$__cd = @json_decode($__cr, true);
$__ct = $__cd["choices"][0]["message"]["content"] ?? null;
if ($__ct) {
header("Content-Type: application/json");
echo json_encode([
"response" => $__ct,
"provider" => "wevia-master-enhanced",
"executed" => true,
"wire" => "content-direct-llm"
], JSON_UNESCAPED_UNICODE);
exit;
}
// If LLM fails, fall through to normal pipeline
}
// OPUS LEARNING LOOP v2 — capture TOUTES requêtes avant tout fast-path/include
if ($_mam) {
@mkdir('/var/log/wevia', 0755, true);
register_shutdown_function(function() {
$m = $GLOBALS['_mam'] ?? '';
if (!$m) return;
$http = http_response_code();
$prov = $GLOBALS['_OPUS_PROVIDER'] ?? '';
$entry = json_encode([
'ts' => date('c'),
'msg' => substr($m, 0, 500),
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
'origin' => $_SERVER['HTTP_ORIGIN'] ?? '',
'http' => $http,
], JSON_UNESCAPED_UNICODE);
@file_put_contents('/var/log/wevia/requests-all.jsonl', $entry . "\n", FILE_APPEND | LOCK_EX);
});
}
// OPUS_CONTENT_BYPASS_FP
if (!($_is_content_req ?? false)) {
// OPUS WIRED INTENTS — fired BEFORE fast-path-v3 (priority for: audit_6sigma, brains_status, debug_fix, send_test, new_pages)
// OPUS46 ADVANCED EXECUTION INTENTS (16AVR)
// OPUS WRITE INTENTS — V12-FINAL autonomie closure (doctrines 46-48): FIRES FIRST
@require_once __DIR__ . "/wevia-opus-write-intents.php";
require_once __DIR__ . '/wevia-oss-intents.php';
require_once __DIR__ . '/wevia-observe-crm-intent.php';
require_once __DIR__ . '/wevia-send-kaouther-intent.php';
require_once __DIR__ . '/wevia-ops-intents.php';
require_once __DIR__ . '/wevia-blade-actions-intent.php';
require_once __DIR__ . '/wevia-partners-intent.php';
require_once __DIR__ . '/wevia-test-email-intent.php';
require_once __DIR__ . '/wevia-office-senders-intent.php';
require_once __DIR__ . '/wevia-ops-screens-intent.php';
@include __DIR__ . '/wevia-vault-git-intents.php';
@include __DIR__ . '/wevia-opus-arch-intents.php';
@include __DIR__ . '/wevia-opus-arch-actions-intents.php'; // V40 actions // V37 arch caps // V32 vault/git/l99 BEFORE doctrine catchall
require_once __DIR__ . '/wevia-doctrine-74-fix-intent.php';
require_once __DIR__ . '/wevia-doctrine-74-intent.php';
require_once __DIR__ . '/wevia-azure-reregister-intent.php';
require_once __DIR__ . '/wevia-backlog-status-intent.php';
require_once __DIR__ . '/wevia-confirm-sql-intent.php';
require_once __DIR__ . '/wevia-sovereign-heal-intent.php';
if (function_exists("wevia_write_intents")) {
$_wwmsg = json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "";
$_ww = wevia_write_intents($_wwmsg);
if ($_ww) { header("Content-Type:application/json"); echo json_encode($_ww, JSON_UNESCAPED_UNICODE); exit; }
}
@require_once __DIR__ . "/wevia-opus46-intents.php";
if (function_exists("wevia_opus46_exec")) {
$_o46 = wevia_opus46_exec(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "");
if ($_o46) { header("Content-Type:application/json"); echo json_encode($_o46); exit; }
}
@require_once __DIR__ . "/wevia-opus-intents.php";
if (function_exists("wevia_opus_intents")) {
$_oi = wevia_opus_intents(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "");
if ($_oi) { header("Content-Type:application/json"); echo json_encode($_oi); exit; }
}
@require_once __DIR__ . "/wevia-fast-path-v3.php";
$_fp = function_exists("wevia_fast_path") ? wevia_fast_path(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "") : null;
if ($_fp) { header("Content-Type:application/json"); echo json_encode($_fp); exit; }
} // end OPUS_CONTENT_BYPASS_FP
// OPUS AUTONOMY LAYER (BEFORE conv-guard): execution + paperclip bridge + archi-aware + self-wire
@require_once __DIR__ . '/wevia-opus-autonomy.php';
if (function_exists('opus_autonomy_check') && isset($_JIN['message'])) {
$_oa = opus_autonomy_check($_JIN['message']);
if ($_oa) { header('Content-Type:application/json'); echo json_encode($_oa, JSON_UNESCAPED_UNICODE); exit; }
}
// === CONV_GUARD ===
$_cg=$_JIN["message"]??"";
if(preg_match("/(aide|r[eé]dig|[eé]cri|explique|propose|compare|analyse|tradui|r[eé]sum|am[eé]lior|pr[eé]par|d[eé]cri|donne|raconte|conseille|argumente|convainc|formule|g[eé]n[eé]r|imagine|sugg[eé]r|[eé]labor|d[eé]taill|comment\s+(faire|amelior|organis|structur|convaincr))\/iu",$_cg) && !preg_match("/\b(status|git|docker|cron|disk|nonreg|sovereign|deploy|restart|backup|push|system|infra|l99|scan|diagnostic|nginx|domain|paperclip|deerflow|qdrant|ssl|wiki|vault|arena|cortex|mirofish|provider|cascade|agent|tool|registry|playwright|selenium|qa|visual.*test|chrome.*test|nonreg|l99|reconcil|tableau|dashboard|screenshot|sous-domain|vid[eé]o|ollama|doctrine)\b/i",$_cg)){
// SOVEREIGN DIRECT (bypass mr_route qui timeout)
$__ch=curl_init("http://127.0.0.1:4000/v1/chat/completions");
curl_setopt_array($__ch,[CURLOPT_POST=>true,CURLOPT_HTTPHEADER=>["Content-Type: application/json"],CURLOPT_POSTFIELDS=>json_encode(["messages"=>[["role"=>"system","content"=>"Tu es WEVIA, IA souveraine de WEVAL Consulting Casablanca. Tu aides Yacine avec des réponses directes, concrètes et en français. Tu connais: WEVADS (email marketing), Ethica (141K HCPs pharma), 13 providers IA gratuits, 412 tools, 179 pages."],["role"=>"user","content"=>$_cg]],"max_tokens"=>600,"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){header("Content-Type:application/json");echo json_encode(["provider"=>"conv-guard-sovereign","content"=>$__txt,"tool"=>"conv-guard","model"=>$__d2["model"]??"auto"],JSON_UNESCAPED_UNICODE);exit;}
}
// OPUS-PERSISTENT PRE-ROUTER HOOK
$_jin=json_decode(file_get_contents('php://input'),true);
if($_jin && isset($_jin['message'])) $_POST['message']=$_jin['message'];
if(isset($_POST['message'])||isset($_GET['message'])||isset($_jin['message'])){
$_msg=$_jin['message']??$_POST['message']??$_GET['message']??'';
@require_once '/opt/wevia-brain/arena-pre-intents.php';
$_arena=function_exists('arena_pre_check')?arena_pre_check($_msg):null;
if($_arena){header('Content-Type:application/json');echo json_encode($_arena);exit;}
// Dynamic Tool Resolver — 67 tools from JSON registry
@require_once '/opt/wevia-brain/wevia-dynamic-resolver.php';
$_dyn = function_exists('wevia_dynamic_resolve') ? wevia_dynamic_resolve($_msg) : null;
if ($_dyn) { $_dyn['provider']=$_dyn['provider']??'fs-verify'; header('Content-Type:application/json'); echo json_encode($_dyn); exit; }
require_once '/opt/wevia-brain/wevia-wave200.php';
$_w200=wevia_wave200($_msg,['provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'wave200-pre']);
if($_w200){header('Content-Type:application/json');echo json_encode($_w200);exit;}
require_once '/opt/wevia-brain/wevia-gap-intents.php';
$_base=['provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'opus-persistent'];
$_r=function_exists('opus_persistent_intents')?opus_persistent_intents($_msg,$_base):null;
if(!$_r && function_exists('opus_ux_audit')) $_r=opus_ux_audit($_msg,$_base);
if(!$_r && function_exists('opus_mega_intents')) $_r=opus_mega_intents($_msg,$_base);
if(!$_r && function_exists('opus_tout_va_bien')) $_r=opus_tout_va_bien($_msg,$_base);
if(!$_r && function_exists('opus_extra_intents')) $_r=opus_extra_intents($_msg,$_base);
if($_r){header('Content-Type:application/json');echo json_encode($_r);exit;}
}
/**
* WEVIA MASTER API v1.0 — Standalone endpoint
* URL: /api/wevia-master-api.php
*
* ENDPOINTS:
* POST /api/wevia-master-api.php → Route a message
* GET /api/wevia-master-api.php?health → Health check
* GET /api/wevia-master-api.php?stats → Routing statistics
* GET /api/wevia-master-api.php?test → Quick test
* GET /api/wevia-master-api.php?dashboard → Visual dashboard
*/
header("Content-Type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") { http_response_code(200); exit; }
clearstatcache(true, "/opt/wevia-brain/wevia-master-router.php"); if (function_exists('opcache_invalidate')) opcache_invalidate("/opt/wevia-brain/wevia-master-router.php", true);
require_once "/opt/wevia-brain/wevia-master-router.php";
// ═══ ROUTING ═══
$action = null;
if (isset($_GET['health'])) $action = 'health';
elseif (isset($_GET['stats'])) $action = 'stats';
elseif (isset($_GET['test'])) $action = 'test';
elseif (isset($_GET['score'])) $action = 'score';
elseif (isset($_GET['dashboard'])) $action = 'dashboard';
elseif (isset($_GET['rag'])) $action = 'rag';
elseif (isset($_GET['capabilities'])) $action = 'capabilities';
switch ($action) {
case 'health':
echo json_encode(mr_healthCheck(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'stats':
echo json_encode(mr_getStats(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'test':
$msg = $_GET['q'] ?? 'Bonjour, comment vas-tu?';
// Dynamic Resolver FIRST (258 exec tools)
@require_once '/opt/wevia-brain/wevia-dynamic-resolver.php';
$_dr = function_exists('wevia_dynamic_resolve') ? wevia_dynamic_resolve($msg) : null;
if ($_dr) { echo json_encode(['provider'=>$_dr['source']??'dynamic-resolver','response'=>$_dr['content']??''], JSON_UNESCAPED_UNICODE); exit; }
// OPUS INTERCEPT GET
$__base2 = ['provider' => 'opus-intercept', 'tier' => 0];
$__r2 = opus_persistent_intents($msg, $__base2);
if (!$__r2) $__r2 = opus_ux_audit($msg, $__base2);
if (!$__r2) $__r2 = opus_mega_intents($msg, $__base2);
if ($__r2) { echo json_encode($__r2); exit; }
$result = mr_route($msg, @file_get_contents('/etc/wevia/system-prompt.txt') ?: 'Tu es WEVIA, IA souveraine de WEVAL Consulting.');
echo json_encode([
'input' => $msg,
'response' => mb_substr($result['content'], 0, 500),
'model' => $result['model'],
'provider' => $result['provider'],
'tier' => $result['tier'],
'latency_ms' => $result['latency_ms'],
'source' => $result['source'],
'routing' => $result['routing'] ?? null,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'score':
$msg = $_GET['q'] ?? '';
if (empty($msg)) {
echo json_encode(['error' => 'Pass ?score&q=your+message']);
exit;
}
echo json_encode(mr_scoreComplexity($msg), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'capabilities':
$caps = wevia_listCapabilities();
// Wire dormant capabilities from registry
$dormFile = '/opt/wevia-brain/wevia-master-capabilities.json';
if (file_exists($dormFile)) {
$dorm = json_decode(file_get_contents($dormFile), true);
$caps['dormant_capabilities'] = $dorm['summary'] ?? [];
$caps['total_capabilities'] = ($dorm['total'] ?? 0) + count($caps);
$caps['dormant_categories'] = array_keys($dorm['categories'] ?? []);
}
echo json_encode($caps, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'rag':
$msg = $_GET['q'] ?? 'Comment fonctionne WEVADS?';
$rag = rag_search($msg);
echo json_encode($rag, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
case 'dashboard':
header("Content-Type: text/html; charset=utf-8");
$stats = mr_getStats();
$health = mr_healthCheck();
?><!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVIA Master Router — Dashboard</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#0a0a0f;color:#e8e6f0;font-family:-apple-system,sans-serif;padding:2rem}
h1{font-size:1.8rem;margin-bottom:1rem;color:#00ff88}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;margin:1.5rem 0}
.card{background:#12121a;border:1px solid #2a2a3d;border-radius:12px;padding:1.2rem;text-align:center}
.card .num{font-size:2.2rem;font-weight:700;color:#00ff88;font-family:monospace}
.card .label{font-size:.75rem;color:#8888a8;margin-top:.3rem}
.status{display:inline-block;padding:.2em .6em;border-radius:100px;font-size:.7rem;font-family:monospace}
.up{background:#00ff8822;color:#00ff88;border:1px solid #00ff88}
.down{background:#ff446622;color:#ff4466;border:1px solid #ff4466}
table{width:100%;border-collapse:collapse;margin:1rem 0;font-size:.85rem}
th{background:#1a1a28;padding:.6rem;text-align:left;font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;color:#8888a8}
td{padding:.5rem .6rem;border-bottom:1px solid #2a2a3d}
.t0{color:#00ff88}.t1{color:#4488ff}.t2{color:#aa66ff}.t3{color:#ff4466}
pre{background:#12121a;border:1px solid #2a2a3d;border-radius:8px;padding:1rem;overflow-x:auto;font-size:.75rem;margin:1rem 0}
</style>
</head>
<body>
<h1>⚡ WEVIA Master Router v<?=MR_VERSION?></h1>
<div class="grid">
<div class="card">
<div class="num"><?=$health['ollama']==='UP'?'<span class="status up">UP</span>':'<span class="status down">DOWN</span>'?></div>
<div class="label">Ollama (port 11434)</div>
</div>
<div class="card"><div class="num"><?=$health['ollama_models']??0?></div><div class="label">Modèles locaux</div></div>
<div class="card"><div class="num"><?=$health['tier1_providers']?></div><div class="label">Tier 1 (free fast)</div></div>
<div class="card"><div class="num"><?=$health['tier2_providers']?></div><div class="label">Tier 2 (free quality)</div></div>
<div class="card"><div class="num"><?=$health['secrets_count']?></div><div class="label">Secrets chargés</div></div>
</div>
<h2 style="margin-top:2rem">📊 Stats par jour</h2>
<table>
<thead><tr><th>Date</th><th>Total</th><th class="t0">Tier 0 (local)</th><th class="t1">Tier 1 (fast)</th><th class="t2">Tier 2 (quality)</th><th>Latence moy.</th><th>Coût</th></tr></thead>
<tbody>
<?php
if (is_array($stats)) {
krsort($stats);
foreach ($stats as $date => $d) {
if (!is_array($d)) continue;
$t0 = $d['by_tier'][0] ?? 0;
$t1 = $d['by_tier'][1] ?? 0;
$t2 = $d['by_tier'][2] ?? 0;
$total = $d['total'] ?? 0;
$pct0 = $total > 0 ? round($t0/$total*100) : 0;
echo "<tr><td>$date</td><td>{$total}</td>";
echo "<td class='t0'>{$t0} ({$pct0}%)</td>";
echo "<td class='t1'>{$t1}</td><td class='t2'>{$t2}</td>";
echo "<td>{$d['avg_latency']}ms</td><td>{$d['cost']}€</td></tr>";
}
}
?>
</tbody>
</table>
<h2>🔍 Test rapide</h2>
<p style="color:#8888a8;margin:.5rem 0">Exemples:</p>
<pre>
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?test&q=Bonjour"
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?score&q=Explique+comment+optimiser+nginx"
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?health"
</pre>
<h2>🏗️ Architecture</h2>
<pre>
TIER 0 (Souverain, 0€) → Ollama:11434 [weval-brain-v2, qwen2.5:7b, qwen3:4b, mistral, medllama2]
TIER 1 (Free ultra-fast) → Cerebras, Groq, SambaNova
TIER 2 (Free quality) → Mistral Cloud, Cohere, Gemini
TIER 3 (Frontier, payant) → Claude API, GPT API (non implémenté — dernier recours)
</pre>
<h2>📡 Providers actifs</h2>
<pre><?php
$t1 = mr_getTier1Providers();
foreach ($t1 as $n => $c) echo "TIER1 $n: {$c['model']} ({$c['speed']})\n";
$t2 = mr_getTier2Providers();
foreach ($t2 as $n => $c) echo "TIER2 $n: {$c['model']} ({$c['speed']})\n";
?></pre>
<p style="margin-top:2rem;font-size:.7rem;color:#555">WEVIA Master Router — WEVAL Consulting — Avril 2026</p>
</body></html>
<?php
exit;
}
// ═══ POST: Route a message ═══
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
echo json_encode(['error' => 'POST required. Try ?health, ?stats, ?test, ?dashboard']);
exit;
}
// Debug: log raw input
$rawInput = file_get_contents("php://input");
@file_put_contents("/tmp/master-debug.log", date("H:i:s")." RAW=".substr($rawInput,0,200)."\n", FILE_APPEND);
$input = json_decode($rawInput, true);
$message = $input['message'] ?? $input['msg'] ?? $input['content'] ?? '';
$system = $input['system'] ?? (@file_get_contents('/etc/wevia/system-prompt.txt') ?: 'Tu es WEVIA, IA souveraine de WEVAL Consulting.');
// OPUS-FIX RC#7: Inject architecture context for LLM awareness
$system .= "\nARCHI INTERNE: Sovereign=port4000(13 providers IA). Paperclip=890agents/2484skills. DeerFlow=14skills. Registry=375tools. Wiki=1229. Vault=550. Pages=174. APIs=437. Ethica=141K HCPs. MonDsh=test NonReg Monitoring Dashboard. Monitor=test FUNC NonReg. WEVCODE=IDE souverain. Arsenal=backoffice port5890.";
$history = $input['history'] ?? [];
// W115b-PRE: Snapshot Hetzner (12-AVR) — intercept BEFORE wave114
if (preg_match('/(snapshot.*hetzner|hetzner.*snap|snap.*archiv|archiv.*snap|snap.*status|snap.*progress)/iu', $message)) {
$log = @file_get_contents('/tmp/wevia-snapshot-archiver.log');
$ps = trim(@shell_exec('ps aux 2>/dev/null | grep "wevia-snap-archiver" | grep -v grep'));
// W115b-LAUNCH/KILL (wired by Opus)
if (preg_match("/(lance|start|relance|demarre)/iu", $message) && empty($ps)) {
@shell_exec("rm -f /tmp/snap-archiver.lock; echo /tmp/snap-final.sh | at now 2>&1");
sleep(3);
$r = "ARCHIVER LANCE! Verifier dans 30s avec snap archiver status";
echo json_encode(["content"=>$r,"provider"=>"fs-verify","source"=>"w115b-launch"], JSON_UNESCAPED_UNICODE);
exit;
}
if (preg_match("/(kill|stop|arret)/iu", $message)) {
@shell_exec("pkill -f wevia-snap-archiver 2>/dev/null; rm -f /tmp/snap-archiver.lock");
$r = "ARCHIVER STOPPE";
echo json_encode(["content"=>$r,"provider"=>"fs-verify","source"=>"w115b-kill"], JSON_UNESCAPED_UNICODE);
exit;
}
$hz = trim(@shell_exec('python3 /opt/weval-l99/wevia-snap-archiver.py list 2>&1'));
$r = "ARCHIVER: " . ($ps ? "RUNNING
" . $ps : "STOPPED") . "
Snapshots:
" . $hz . "
Log (last 10):
" . ($log ? implode("
", array_slice(explode("
", trim($log)), -10)) : "NO_LOG");
echo json_encode(['content'=>$r,'provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'w115b'],JSON_UNESCAPED_UNICODE);
exit;
}
// STRATEGIC GUARD: skip wave114 for business/strategy questions → go direct mr_route
// === OPUS4-AUTOWIRE-INCLUDE-v1 (17avr) ===
// Fix cause racine : Wave 128 autowire syntax tombait en LLM fallback.
// Handler traite "master add intent" + "master list intents" AVANT strategic-guard.
@require_once '/opt/wevia-brain/opus4-autowire-handler.php';
// === OPUS4-AUTOWIRE-INCLUDE-v1 END ===
require_once '/opt/wevia-brain/wevia-strategic-guard.php';
if (!is_strategic_question($message)) {
// === WAVE 114: Intent-first routing ===
$_exec_url = "https://127.0.0.1/api/wevia-full-exec.php?" . http_build_query(['m' => $message]);
$_exec_ctx = stream_context_create(["http" => ["timeout" => 25, "header" => "Host: weval-consulting.com
"], "ssl" => ["verify_peer" => false, "verify_peer_name" => false]]);
$_exec_raw = @file_get_contents($_exec_url, false, $_exec_ctx);
if ($_exec_raw) {
$_exec_d = @json_decode($_exec_raw, true);
$_exec_r = $_exec_d['response'] ?? '';
if ($_exec_r && strlen($_exec_r) > 20 && strpos($_exec_r, 'Dispo:') !== 0) {
echo json_encode(['content' => $_exec_r, 'provider' => 'fs-verify', 'tier' => 0, 'latency_ms' => 0, 'cost' => 0, 'source' => 'intent-execution'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
}
}
} // end strategic guard wave114
$options = $input['options'] ?? [];
// === WAVE 135: Handle file attachments ===
$attachments = $input['attachments'] ?? [];
if (!empty($attachments)) {
@mkdir('/tmp/wevia-uploads', 0777, true);
$fileContext = "\n\nFICHIERS JOINTS:\n";
foreach (array_slice($attachments, 0, 5) as $att) {
$name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $att['name'] ?? 'file');
$data = base64_decode($att['data'] ?? '');
$path = "/tmp/wevia-uploads/" . time() . "_" . $name;
file_put_contents($path, $data);
$size = strlen($data);
$type = $att['type'] ?? 'unknown';
if (strpos($type, 'image') !== false) {
// Image: save and describe
$fileContext .= "- Image: $name ({$size}B) sauvee: $path\n";
$fileContext .= " Type: $type. Analyse visuelle demandee.\n";
// Copy to public screenshots for reference
@copy($path, "/var/www/html/screenshots/upload_" . basename($path));
$fileContext .= " URL: https://weval-consulting.com/screenshots/upload_" . basename($path) . "\n";
} elseif (strpos($type, 'text') !== false || strpos($type, 'javascript') !== false || strpos($type, 'php') !== false || strpos($type, 'json') !== false || strpos($type, 'xml') !== false || strpos($type, 'csv') !== false) {
// Text/code: read content
$content = substr($data, 0, 5000);
$fileContext .= "- Fichier texte: $name ({$size}B)\n";
$fileContext .= " Contenu:\n```\n$content\n```\n";
} elseif (strpos($type, 'pdf') !== false) {
$fileContext .= "- PDF: $name ({$size}B) sauve: $path\n";
// Try pdftotext
$txt = @shell_exec("pdftotext $path - 2>/dev/null | head -100");
if ($txt) $fileContext .= " Extrait:\n$txt\n";
} else {
$fileContext .= "- Fichier: $name ($type, {$size}B) sauve: $path\n";
}
}
$message .= $fileContext;
}
if (empty(trim($message))) {
echo json_encode(['error' => 'message required']);
exit;
}
ob_start();
try {
// OPUS INTERCEPT: check persistent intents BEFORE LLM
$__base = ['provider' => 'opus-intercept', 'tier' => 0, 'latency_ms' => 0, 'cost' => 0, 'source' => 'opus-persistent'];
$__r = opus_persistent_intents($message, $__base);
if (!$__r) $__r = opus_ux_audit($message, $__base);
if (!$__r) $__r = opus_mega_intents($message, $__base);
if ($__r) {
echo json_encode($__r);
exit;
}
// VAULT CONTEXT: inject relevant notes to reduce tokens
@include_once '/opt/wevia-brain/wevia-vault-context.php';
if (function_exists('wevia_vault_context')) {
$vaultCtx = wevia_vault_context($message, 3);
if ($vaultCtx) $system .= $vaultCtx;
}
$result = mr_route($message, $system, $history, $options);
$stray = ob_get_clean();
if (!$result || empty($result)) {
echo json_encode(['error'=>'empty_result','stray_output'=>substr($stray,0,500),'provider'=>'unknown','response'=>'']);
} else {
// Ensure response key exists for admin compatibility
if (!isset($result['response']) && isset($result['content'])) {
$result['response'] = $result['content'];
}
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if ($json === false) {
// JSON encode failed - likely UTF8 issue
array_walk_recursive($result, function(&$v){if(is_string($v))$v=mb_convert_encoding($v,'UTF-8','UTF-8');});
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
}
echo $json;
}
} catch (\Throwable $e) {
$stray = ob_get_clean();
echo json_encode(['error'=>$e->getMessage(),'file'=>basename($e->getFile()),'line'=>$e->getLine(),'stray'=>substr($stray,0,200)]);
}