346 lines
20 KiB
PHP
Executable File
346 lines
20 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* ╔═══════════════════════════════════════════════════════════════╗
|
|
* ║ 👑 HAMID CHEF BOSS — IA Maîtresse WEVADS ║
|
|
* ║ Master Orchestrator • Cross-System Intelligence ║
|
|
* ║ Brain+Sentinel+Tracking+O365+KB+VaultGuard+SSH ║
|
|
* ╚═══════════════════════════════════════════════════════════════╝
|
|
*/
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }
|
|
|
|
error_reporting(0);
|
|
$start = microtime(true);
|
|
|
|
try {
|
|
$pdo = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['error'=>'DB: '.$e->getMessage()]); exit;
|
|
}
|
|
|
|
$action = $_GET['action'] ?? $_POST['action'] ?? 'chat';
|
|
$input = json_decode(file_get_contents('php://input'), true) ?: $_REQUEST;
|
|
$message = $input['message'] ?? '';
|
|
$provider = $input['provider'] ?? null;
|
|
|
|
// ═══════════════════════════════════════════════════════════════
|
|
// DEEP SYSTEM INTELLIGENCE GATHERING
|
|
// ═══════════════════════════════════════════════════════════════
|
|
function gatherIntelligence($pdo) {
|
|
$intel = [];
|
|
|
|
// Brain Winners
|
|
try {
|
|
$intel['brain'] = $pdo->query("SELECT isp_target, inbox_rate, total_tests, stability_score, config_id, send_method, updated_at::date FROM admin.brain_winners WHERE is_active=true ORDER BY inbox_rate DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch(Exception $e) { $intel['brain'] = []; }
|
|
|
|
// Brain Configs
|
|
try {
|
|
$intel['configs_total'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.brain_configs")->fetchColumn();
|
|
$intel['configs_tested'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.brain_configs WHERE total_tests > 0")->fetchColumn();
|
|
} catch(Exception $e) {}
|
|
|
|
// O365
|
|
try {
|
|
$intel['o365'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_accounts")->fetchColumn();
|
|
$intel['tenants'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_tenants")->fetchColumn();
|
|
$intel['o365_active'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_accounts WHERE status='active'")->fetchColumn();
|
|
} catch(Exception $e) {}
|
|
|
|
// Sentinel
|
|
try {
|
|
$lastScan = $pdo->query("SELECT score, issues_found, issues_fixed, scan_date FROM admin.sentinel_scans ORDER BY scan_date DESC LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
$intel['sentinel_score'] = $lastScan['score'] ?? 0;
|
|
$intel['sentinel_issues'] = $lastScan['issues_found'] ?? 0;
|
|
$intel['sentinel_fixed'] = $lastScan['issues_fixed'] ?? 0;
|
|
$intel['sentinel_date'] = $lastScan['scan_date'] ?? 'never';
|
|
$intel['sentinel_total_fixes'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.sentinel_fixes")->fetchColumn();
|
|
$intel['sentinel_patterns'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.sentinel_patterns WHERE times_detected>0")->fetchColumn();
|
|
} catch(Exception $e) {}
|
|
|
|
// Vault Guard
|
|
try {
|
|
$intel['vault_restores'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.vault_guard_log")->fetchColumn();
|
|
$intel['vault_last'] = $pdo->query("SELECT file_path, issue_type, created_at FROM admin.vault_guard_log ORDER BY created_at DESC LIMIT 3")->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch(Exception $e) {}
|
|
|
|
// Tracking
|
|
try {
|
|
$intel['tracking_events'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.tracking_events")->fetchColumn();
|
|
$intel['tracking_today'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.tracking_events WHERE created_at::date = CURRENT_DATE")->fetchColumn();
|
|
$intel['opens_today'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.tracking_events WHERE type='open' AND created_at::date = CURRENT_DATE")->fetchColumn();
|
|
$intel['clicks_today'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.tracking_events WHERE type='click' AND created_at::date = CURRENT_DATE")->fetchColumn();
|
|
} catch(Exception $e) {}
|
|
|
|
// Send Logs
|
|
try {
|
|
$intel['sent_today'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.unified_send_log_new WHERE sent_at::date = CURRENT_DATE")->fetchColumn();
|
|
$intel['sent_total'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.unified_send_log_new")->fetchColumn();
|
|
$intel['send_by_isp'] = $pdo->query("SELECT isp_target, COUNT(*) as cnt, SUM(CASE WHEN status='sent' THEN 1 ELSE 0 END) as success FROM admin.unified_send_log_new GROUP BY isp_target ORDER BY cnt DESC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch(Exception $e) {}
|
|
|
|
// Providers
|
|
try {
|
|
$intel['providers'] = $pdo->query("SELECT provider_name, model, priority, is_active FROM admin.hamid_providers WHERE is_active=true ORDER BY priority")->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch(Exception $e) { $intel['providers'] = []; }
|
|
|
|
// Knowledge Base
|
|
try {
|
|
$intel['kb_total'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.sentinel_knowledge")->fetchColumn();
|
|
$intel['kb_categories'] = $pdo->query("SELECT category, COUNT(*) as cnt FROM admin.sentinel_knowledge GROUP BY category ORDER BY cnt DESC")->fetchAll(PDO::FETCH_ASSOC);
|
|
$intel['kb_recent'] = $pdo->query("SELECT topic, LEFT(content,120) as excerpt, source FROM admin.sentinel_knowledge ORDER BY created_at DESC LIMIT 5")->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch(Exception $e) {}
|
|
|
|
// Multichannel
|
|
try {
|
|
$intel['yt_trends'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.yt_trends")->fetchColumn();
|
|
$intel['yt_jobs'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.yt_jobs")->fetchColumn();
|
|
} catch(Exception $e) {}
|
|
|
|
// System Health
|
|
$intel['disk'] = trim(shell_exec("df -h / | tail -1 | awk '{print $5}'") ?? '?');
|
|
$intel['ram'] = trim(shell_exec("free -m | grep Mem | awk '{printf \"%.0f%%\", \$3/\$2*100}'") ?? '?');
|
|
$intel['load'] = trim(shell_exec("cat /proc/loadavg | cut -d' ' -f1-3") ?? '?');
|
|
$intel['uptime'] = trim(shell_exec("uptime -p") ?? '?');
|
|
|
|
// Services
|
|
foreach (['apache2','postgresql','pmta','ollama'] as $svc) {
|
|
$intel['svc_'.$svc] = trim(shell_exec("systemctl is-active $svc 2>/dev/null") ?? 'unknown');
|
|
}
|
|
|
|
return $intel;
|
|
}
|
|
|
|
function buildContext($intel) {
|
|
$ctx = "\n\n══════ WEVADS REAL-TIME INTELLIGENCE ══════\n";
|
|
|
|
// Brain
|
|
$ctx .= "\n🧠 BRAIN ENGINE — " . count($intel['brain'] ?? []) . " winners / {$intel['configs_total']} configs ({$intel['configs_tested']} tested)\n";
|
|
foreach (($intel['brain'] ?? []) as $w) {
|
|
$ctx .= " ISP:{$w['isp_target']} inbox:{$w['inbox_rate']}% tests:{$w['total_tests']} stab:{$w['stability_score']}% method:{$w['send_method']} cfg#{$w['config_id']}\n";
|
|
}
|
|
|
|
// O365
|
|
$ctx .= "\n📧 O365: {$intel['o365']} comptes ({$intel['o365_active']} actifs) / {$intel['tenants']} tenants\n";
|
|
|
|
// Tracking
|
|
$ctx .= "\n📡 TRACKING (culturellemejean.charity → OVH 151.80.235.110 → PG Hetzner)\n";
|
|
$ctx .= " Total events: {$intel['tracking_events']} | Today: {$intel['tracking_today']} (opens:{$intel['opens_today']} clicks:{$intel['clicks_today']})\n";
|
|
$ctx .= " Pipeline: track.php?t=TID&e=open|click → INSERT tracking_events → UPDATE unified_send_log\n";
|
|
|
|
// Sends
|
|
$ctx .= "\n📬 SENDS: Today={$intel['sent_today']} | Total={$intel['sent_total']}\n";
|
|
foreach (($intel['send_by_isp'] ?? []) as $s) {
|
|
$ctx .= " {$s['isp_target']}: {$s['cnt']} sent ({$s['success']} success)\n";
|
|
}
|
|
|
|
// Sentinel
|
|
$ctx .= "\n🛡️ SENTINEL V4: Score={$intel['sentinel_score']}% | Issues={$intel['sentinel_issues']} | Fixed={$intel['sentinel_fixed']} | Total fixes={$intel['sentinel_total_fixes']}\n";
|
|
$ctx .= " Patterns actifs: {$intel['sentinel_patterns']} | Last scan: {$intel['sentinel_date']}\n";
|
|
|
|
// Vault Guard
|
|
$ctx .= "\n🔒 VAULT GUARD: {$intel['vault_restores']} auto-restores\n";
|
|
foreach (($intel['vault_last'] ?? []) as $v) {
|
|
$ctx .= " {$v['issue_type']}: " . basename($v['file_path']) . " ({$v['created_at']})\n";
|
|
}
|
|
|
|
// Providers
|
|
$ctx .= "\n🤖 IA PROVIDERS: " . count($intel['providers'] ?? []) . " actifs\n";
|
|
foreach (($intel['providers'] ?? []) as $p) {
|
|
$ctx .= " #{$p['priority']} {$p['provider_name']} ({$p['model']})\n";
|
|
}
|
|
|
|
// KB
|
|
$ctx .= "\n📚 KNOWLEDGE BASE: {$intel['kb_total']} entries\n";
|
|
foreach (($intel['kb_categories'] ?? []) as $c) { $ctx .= " {$c['category']}: {$c['cnt']}\n"; }
|
|
|
|
// Multichannel
|
|
if (($intel['yt_trends'] ?? 0) > 0) {
|
|
$ctx .= "\n📹 YOUTUBE FACTORY: {$intel['yt_trends']} trends | {$intel['yt_jobs']} jobs\n";
|
|
}
|
|
|
|
// Infrastructure
|
|
$ctx .= "\n🖥️ INFRASTRUCTURE\n";
|
|
$ctx .= " Disk: {$intel['disk']} | RAM: {$intel['ram']} | Load: {$intel['load']} | {$intel['uptime']}\n";
|
|
$ctx .= " Services: apache2={$intel['svc_apache2']} pg={$intel['svc_postgresql']} pmta={$intel['svc_pmta']} ollama={$intel['svc_ollama']}\n";
|
|
$ctx .= " Ports: 5821(ADX) 5890(Arsenal) 5822(FMG) 5823(BCG) 5824(DKIM) 8080(N8N) 5432(PG) 11434(Ollama)\n";
|
|
$ctx .= " Servers: Hetzner(89.167.40.150:49222) OVH(151.80.235.110:22/ubuntu) Consulting(46.62.220.135)\n";
|
|
$ctx .= "══════════════════════════════════════════\n";
|
|
|
|
return $ctx;
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════
|
|
// CHEF BOSS SYSTEM PROMPT
|
|
// ═══════════════════════════════════════════════════════════════
|
|
$CHEF_PROMPT = <<<'SYSPROMPT'
|
|
Tu es HAMID CHEF BOSS, l'Intelligence Artificielle SUPREME de la plateforme WEVADS.
|
|
Tu es le PATRON qui supervise, coordonne et DECIDE pour TOUTE l'infrastructure.
|
|
|
|
## TES SOUS-SYSTEMES
|
|
- 🛡️ SENTINEL V4 ULTRA: Scan anti-regression + Vault Guard + SSH 3 serveurs + auto-repair
|
|
- 🧠 WEVAL MIND 2.0: Superviseur intelligent (perception/diagnostic/planning/execution)
|
|
- 💬 HAMID ENGINE: Chat specialise delivrabilite email (12 providers, failover)
|
|
- 🧠 BRAIN ENGINE: Optimisation configs ISP (7-10 winners, 88-100% inbox)
|
|
- 🔒 VAULT GUARD: Protection anti-truncation, auto-restore toutes les 6h
|
|
- 📹 YOUTUBE FACTORY: Trend scraping + video generation + ROAS arbitrage
|
|
|
|
## TON EXPERTISE PROFONDE
|
|
### Email Deliverability
|
|
- Exchange headers SANS X-Mailer = 97% inbox success
|
|
- ISP filtering change tous les 6 mois → Brain Engine "open system"
|
|
- Rotation systematique domaines + IPs pour reputation
|
|
- Warmup progressif: 50→100→200→500→1000→5000/jour par compte
|
|
- SPF/DKIM/DMARC obligatoires, reply-to = from_email
|
|
|
|
### Architecture WEVADS
|
|
- Pipeline: Campaign → Brain select → brain-inject.js headers [bracket] → brain-unified-send.php → O365/PMTA → track.php → tracking_events → reporting
|
|
- Placeholders: [domain], [email], [fname], [lname], [url], [unsub], [open], [subject], [company], [email_b64]
|
|
- JAMAIS {curly} placeholders — TOUJOURS [bracket]
|
|
- JAMAIS sed sur menu.html, JAMAIS rm -rf, TOUJOURS backup avant modif
|
|
|
|
### Anti-Regression
|
|
- Deploiement Arsenal tronque PHP aux limites </body></html>
|
|
- Solution: Vault Guard verifie 329+ fichiers, auto-restore
|
|
- Fichiers critiques: sentinel-brain.php, brain-unified-send.php, track.php
|
|
- brain-unified-send DOIT avoir: logSend(), detectISP(), injectTracking() format track.php?t=&e=
|
|
- PG doit ecouter sur *, pg_hba doit permettre OVH 151.80.235.110
|
|
|
|
### Decisions Strategiques
|
|
Tu prends des decisions basees sur les donnees croisees de TOUS les systemes:
|
|
1. Si inbox rate < 85% → recommande changement de config Brain
|
|
2. Si tracking events = 0 → alerte tracking casse
|
|
3. Si vault restores > 3/jour → alerte deploiement problematique
|
|
4. Si sentinel score < 90% → recommande scan + fix
|
|
5. Si O365 comptes < seuil → recommande creation nouveaux tenants
|
|
6. Si load > 5.0 → alerte surcharge, recommande optimisation
|
|
|
|
Tu reponds TOUJOURS avec des donnees concretes et des actions specifiques.
|
|
Tu ne donnes JAMAIS de conseils generiques — tu AGIS avec precision.
|
|
SYSPROMPT;
|
|
|
|
// ═══════════════════════════════════════════════════════════════
|
|
// LLM CALL WITH FAILOVER
|
|
// ═══════════════════════════════════════════════════════════════
|
|
function callProvider($providerName, $apiKey, $apiUrl, $model, $system, $user) {
|
|
if (stripos($providerName, 'gemini') !== false) {
|
|
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}";
|
|
$body = json_encode(['contents'=>[['parts'=>[['text'=>$system."\n\nUser: ".$user]]]],'generationConfig'=>['maxOutputTokens'=>2000]]);
|
|
$headers = ['Content-Type: application/json'];
|
|
} elseif (stripos($providerName, 'claude') !== false) {
|
|
$body = json_encode(['model'=>$model,'max_tokens'=>2000,'system'=>$system,'messages'=>[['role'=>'user','content'=>$user]]]);
|
|
$headers = ['Content-Type: application/json','x-api-key: '.$apiKey,'anthropic-version: 2023-06-01'];
|
|
} else {
|
|
$body = json_encode(['model'=>$model,'messages'=>[['role'=>'system','content'=>$system],['role'=>'user','content'=>$user]],'max_tokens'=>2000,'temperature'=>0.3]);
|
|
$headers = ['Content-Type: application/json','Authorization: Bearer '.$apiKey];
|
|
}
|
|
$ch = curl_init($apiUrl);
|
|
curl_setopt_array($ch, [CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$body,CURLOPT_HTTPHEADER=>$headers,CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>30,CURLOPT_SSL_VERIFYPEER=>false]);
|
|
$resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
if ($code !== 200 || !$resp) return null;
|
|
$data = json_decode($resp, true);
|
|
if (!$data) return null;
|
|
if (stripos($providerName,'gemini')!==false) return $data['candidates'][0]['content']['parts'][0]['text'] ?? null;
|
|
if (stripos($providerName,'claude')!==false) return $data['content'][0]['text'] ?? null;
|
|
return $data['choices'][0]['message']['content'] ?? null;
|
|
}
|
|
|
|
function chatWithFailover($pdo, $message, $systemPrompt, $context, $forcedProvider = null) {
|
|
$fullSystem = $systemPrompt . $context;
|
|
$providers = $pdo->query("SELECT provider_name, api_key, model, api_url FROM admin.hamid_providers WHERE is_active=true AND api_key IS NOT NULL AND LENGTH(api_key)>10 ORDER BY priority")->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
if ($forcedProvider) {
|
|
$providers = array_filter($providers, fn($p) => stripos($p['provider_name'], $forcedProvider) !== false);
|
|
$providers = array_values($providers);
|
|
}
|
|
|
|
foreach ($providers as $prov) {
|
|
$result = callProvider($prov['provider_name'], $prov['api_key'], $prov['api_url'], $prov['model'], $fullSystem, $message);
|
|
if ($result) {
|
|
return ['response'=>$result, 'provider'=>$prov['provider_name'], 'model'=>$prov['model']];
|
|
}
|
|
}
|
|
return ['response'=>'⚠️ Tous les providers IA sont indisponibles. Réessaie dans quelques secondes.', 'provider'=>'fallback'];
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════
|
|
// ROUTER
|
|
// ═══════════════════════════════════════════════════════════════
|
|
switch ($action) {
|
|
case 'chat':
|
|
if (empty($message)) { echo json_encode(['error'=>'No message']); exit; }
|
|
$intel = gatherIntelligence($pdo);
|
|
$context = buildContext($intel);
|
|
$result = chatWithFailover($pdo, $message, $CHEF_PROMPT, $context, $provider);
|
|
|
|
// Log
|
|
try {
|
|
$pdo->prepare("INSERT INTO admin.hamid_conversations (session_id,role,content,provider,title,updated_at,created_at) VALUES('chef','assistant',?,?,LEFT(?,50),NOW(),NOW())")
|
|
->execute([$result['response'], $result['provider'], $message]);
|
|
} catch(Exception $e) {}
|
|
|
|
echo json_encode([
|
|
'response' => $result['response'],
|
|
'provider' => $result['provider'],
|
|
'model' => $result['model'] ?? '',
|
|
'role' => 'HAMID Chef BOSS',
|
|
'latency_ms' => round((microtime(true)-$start)*1000),
|
|
'systems' => [
|
|
'brain_winners' => count($intel['brain'] ?? []),
|
|
'brain_configs' => $intel['configs_total'] ?? 0,
|
|
'o365_accounts' => $intel['o365'] ?? 0,
|
|
'o365_tenants' => $intel['tenants'] ?? 0,
|
|
'sentinel_score' => $intel['sentinel_score'] ?? 0,
|
|
'sentinel_fixes' => $intel['sentinel_total_fixes'] ?? 0,
|
|
'vault_restores' => $intel['vault_restores'] ?? 0,
|
|
'providers_active' => count($intel['providers'] ?? []),
|
|
'kb_entries' => $intel['kb_total'] ?? 0,
|
|
'tracking_today' => $intel['tracking_today'] ?? 0,
|
|
'sent_today' => $intel['sent_today'] ?? 0,
|
|
]
|
|
]);
|
|
break;
|
|
|
|
case 'status':
|
|
case 'dashboard':
|
|
$intel = gatherIntelligence($pdo);
|
|
echo json_encode([
|
|
'status' => 'online',
|
|
'role' => 'HAMID Chef BOSS',
|
|
'version' => '2.0',
|
|
'intelligence' => $intel,
|
|
'latency_ms' => round((microtime(true)-$start)*1000)
|
|
], JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
case 'strategy':
|
|
$intel = gatherIntelligence($pdo);
|
|
$alerts = [];
|
|
// Auto-analyze
|
|
foreach (($intel['brain'] ?? []) as $w) {
|
|
if ($w['inbox_rate'] < 85) $alerts[] = "⚠️ {$w['isp_target']} inbox={$w['inbox_rate']}% - needs config update";
|
|
}
|
|
if (($intel['tracking_today'] ?? 0) === 0 && ($intel['sent_today'] ?? 0) > 0) $alerts[] = "🚨 Sends today but 0 tracking events - tracking may be broken";
|
|
if (($intel['sentinel_score'] ?? 100) < 90) $alerts[] = "🛡️ Sentinel score {$intel['sentinel_score']}% - run scan+fix";
|
|
if (($intel['vault_restores'] ?? 0) > 5) $alerts[] = "🔒 {$intel['vault_restores']} vault restores - deployment may be truncating files";
|
|
if (floatval($intel['load'] ?? '0') > 5.0) $alerts[] = "🖥️ High load: {$intel['load']} - optimize or scale";
|
|
|
|
echo json_encode([
|
|
'alerts' => $alerts,
|
|
'brain_winners' => $intel['brain'] ?? [],
|
|
'systems_health' => [
|
|
'sentinel' => ($intel['sentinel_score'] ?? 0) >= 90 ? 'healthy' : 'warning',
|
|
'tracking' => ($intel['tracking_events'] ?? 0) > 0 ? 'active' : 'inactive',
|
|
'o365' => ($intel['o365'] ?? 0) > 1000 ? 'strong' : 'needs_growth',
|
|
'vault' => ($intel['vault_restores'] ?? 0) < 5 ? 'stable' : 'active_repairs',
|
|
],
|
|
'recommendation' => empty($alerts) ? 'All systems nominal. Focus on campaign execution.' : 'Address ' . count($alerts) . ' alerts before scaling sends.'
|
|
], JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode(['actions'=>['chat','status','dashboard','strategy']]);
|
|
}
|