Files
html/api/wevia-sse-orchestrator.php
2026-04-19 15:55:01 +02:00

797 lines
59 KiB
PHP

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no');
set_time_limit(120);
ob_implicit_flush(true);
while(ob_get_level())ob_end_flush();
function sse($d){echo 'data: '.json_encode($d,JSON_UNESCAPED_UNICODE)."\n\n";flush();}
$msg=$_GET['msg']??'';if(!$msg){$__b=@json_decode(@file_get_contents('php://input'),true);$msg=$__b['message']??$__b['msg']??'';}
if(!$msg){sse(['error'=>'msg required']);exit;}
sse(['type'=>'start','task'=>$msg,'ts'=>date('H:i:s')]);
// === OPUS5-SSE-DISPATCHER-v1 (18avr) - Short-circuit stubs BEFORE LLM fallback ===
// Prevent hallucinations (e.g. "ethica" → "Ethiopie") by matching wired intents first.
if (!empty($msg)) {
$__sd_msg = mb_strtolower(trim($msg));
$__sd_stubs = @glob('/var/www/html/api/wired-pending/intent-opus4-*.php') ?: [];
foreach ($__sd_stubs as $__sd_s) {
$__sd_info = @include $__sd_s;
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;
// Match if all tokens of trigger are present in message (order-independent)
$__sd_tokens = preg_split('/\s+/', mb_strtolower($__sd_trg));
$__sd_matches_all = true;
foreach ($__sd_tokens as $__sd_tok) {
if ($__sd_tok === '') continue;
if (mb_stripos($__sd_msg, $__sd_tok) === false) { $__sd_matches_all = false; break; }
}
if (!$__sd_matches_all) continue;
$__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');
sse([
'type' => 'exec',
'text' => "Intent '{$__sd_info['name']}' executed (trigger tokens matched: $__sd_trg)\n" . trim((string)$__sd_out),
'engine' => 'opus5-sse-dispatcher',
'intent' => $__sd_info['name'],
'trigger_matched' => $__sd_trg
]);
sse(['type' => 'done']);
@file_put_contents('/tmp/opus5-sse-dispatcher.log', date('c') . " MATCH intent={$__sd_info['name']} trg=$__sd_trg msg=$__sd_msg\n", FILE_APPEND);
exit;
}
}
}
// === OPUS5-SSE-DISPATCHER-v1 END ===
// === SMART AGENT SELECTOR: parse le message pour choisir les agents pertinents ===
// NOTE: $agents is defined BELOW - selector runs AFTER agents are defined
// Guard: if $agents not yet defined, skip selector (will run all agents)
if (!isset($agents)) { goto __agents_def; }
$m = mb_strtolower($msg);
$skip = [];
// Si la question est ciblée, on skip les agents non pertinents pour aller plus vite
if (preg_match('/\b(git|push|commit|dirty)\b/', $m)) { $skip = array_diff(array_keys($agents), ['git','infra']); }
elseif (preg_match('/\b(ethica|hcp|medecin|pharma)\b/', $m)) { $skip = array_diff(array_keys($agents), ['ethica','infra','sovereign']); }
elseif (preg_match('/\b(docker|container)\b/', $m)) { $skip = array_diff(array_keys($agents), ['docker','infra','ports']); }
elseif (preg_match('/\b(security|ssl|crowdsec|nuclei)\b/', $m)) { $skip = array_diff(array_keys($agents), ['security','infra','ports']); }
elseif (preg_match('/\b(sovereign|cascade|provider|ia|model)\b/', $m)) { $skip = array_diff(array_keys($agents), ['sovereign','ai_models','infra']); }
// "bilan", "tout", "complet", "full", "mobilise" → TOUS les agents (pas de skip)
// Emit roster info
$roster = @json_decode(@file_get_contents("http://127.0.0.1/api/orchestrator-agents.php"), true);
if ($roster && $roster["totals"]) {
sse(["type"=>"roster","realtime"=>$roster["totals"]["realtime"],"paperclip"=>$roster["totals"]["paperclip_agents"],"tools"=>$roster["totals"]["registry_tools"],"grand_total"=>$roster["totals"]["grand_total"]]);
}
__agents_def:
$agents=[
'infra'=>'echo LOAD:$(cat /proc/loadavg|cut -d" " -f1-3) DISK:$(df -h /|tail -1|awk "{print \$5}") FPM:$(pgrep -c php-fpm) HTML:$(ls /var/www/html/*.html|wc -l)',
'sovereign'=>'curl -s --max-time 6 http://127.0.0.1:4000/health 2>/dev/null|head -c 80||echo DOWN',
'nonreg'=>'php8.4 /var/www/html/api/nonreg-quick.php 2>&1',
'git'=>'cd /var/www/html;echo DIRTY:$(git status -s|wc -l);git log --oneline -2',
'vault'=>'echo VAULT:$(ls /opt/wevads/vault/|wc -l) WIKI:$(ls /opt/weval-l99/wiki/*.json|wc -l)',
'docker'=>'docker ps --format "{{.Names}}:{{.Status}}"|head -8',
'crons'=>'echo S204:$(crontab -l 2>/dev/null|grep -cv ^#)',
'registry'=>'python3 -c "import json;print(json.load(open(\"/var/www/html/api/wevia-tool-registry.json\"))[\"count\"],\"tools\")" 2>/dev/null',
'pages'=>'echo $(ls /var/www/html/*.html|wc -l) pages',
'ollama'=>'echo $(pgrep ollama 2>/dev/null|wc -l) procs Ollama-ok-doctrine17avr',
'ports'=>'echo 4000:$(ss -tlnp|grep -c :4000) 5890:$(ss -tlnp|grep -c :5890) 8443:$(ss -tlnp|grep -c :8443)',
];
// OPUS-FIX RC#9+RC#10: Dynamic agents from Paperclip + Registry
$agents['paperclip'] = 'curl -s -m5 http://127.0.0.1/api/paperclip-agents-api.php 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"Agents:{d[\\"agents\\"]} Active:{d[\\"agents_active\\"]} Skills:{d[\\"skills\\"]} Routines:{d[\\"routines\\"]}\") " 2>/dev/null || echo "Paperclip:unavailable"';
$agents['deerflow'] = 'ls /opt/deer-flow/skills/ 2>/dev/null | wc -l | xargs -I{} echo "DeerFlow:{} skills"';
$agents['l99'] = 'cat /var/www/html/api/nonreg-latest.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"L99:{d[\\"pass\\"]}\/{d[\\"total\\"]} ({d[\\"score\\"]}%) ts:{d[\\"ts\\"]}\")" 2>/dev/null || echo "L99:unavailable"';
$agents['subdomains'] = 'grep -h server_name /etc/nginx/sites-enabled/* 2>/dev/null | grep -v "#" | sed "s/.*server_name//" | sed "s/;.*//" | sort -u | tr "\n" " "';
// === AGENT CHEF: Inventaire 700+ agents par rôle ===
$agents["agent_chief"] = 'PGPASSWORD=admin123 psql -h 127.0.0.1 -p 5432 -U admin -d paperclip -t -c "SELECT role, COUNT(DISTINCT name) FROM agents GROUP BY role ORDER BY count DESC LIMIT 15;" 2>/dev/null | head -15';
// === MEGA ORCHESTRATOR: Dynamic agent groups ===
$agents["apps"] = 'for p in wevia-master blade-ai weval-arena growth-engine-v2 director ops-center wevcode agents-archi enterprise-model vault-manager wevia-meeting-rooms admin-v2; do printf "%s:%s " $p $(curl -so/dev/null -w%{http_code} -m2 http://127.0.0.1:8443/$p.html 2>/dev/null); done';
$agents["ethica"] = 'echo "HCPs:$(PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM ethica.medecins_real" 2>/dev/null || echo N/A)" && echo "Campaigns:$(PGPASSWORD=admin123 psql -h 10.1.0.3 -p 5432 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM ethica.campaigns" 2>/dev/null || echo N/A)"';
$agents["security"] = 'echo "SSL:$(echo | openssl s_client -connect weval-consulting.com:443 -servername weval-consulting.com 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)" && echo "CrowdSec:$(cscli decisions list -o raw 2>/dev/null | wc -l) bans"';
$agents["ai_models"] = 'echo Sovereign:$(ss -tlnp 2>/dev/null | grep -c ":4000 ") port4000';
$agents["qdrant_kb"] = 'curl -s http://localhost:6333/collections --max-time 3 2>/dev/null | python3 -c "import sys,json;cs=json.load(sys.stdin).get(\\"result\\",{}).get(\\"collections\\",[]);print(len(cs),\\"collections:\\",\\",\\".join([c[\\"name\\"] for c in cs[:8]]))" 2>/dev/null || echo "Qdrant:DOWN"';
$agents["s95_wevads"] = 'curl -s -m10 http://10.1.0.3:5890/api/sentinel-brain.php?action=exec\&cmd=uptime 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(\\"S95:\\",d.get(\\"output\\",\\"DOWN\\")[:60])" 2>/dev/null || echo "S95:unreachable"';
$agents["mirofish"] = 'curl -so/dev/null -w"MiroFish:%{http_code}" http://127.0.0.1:5001/health --max-time 2 2>/dev/null || echo "MiroFish:DOWN"';
$agents["crons_root"] = 'docker run --rm --privileged --pid=host --network=none alpine nsenter -t 1 -m -u -i -n -- crontab -l 2>/dev/null | grep -cv "^#\|^$" | xargs -I{} echo "Root_crons:{}" 2>/dev/null || echo "Root_crons:N/A"';
@include __DIR__ . '/wevia-sse-v76-agents-ext.php'; // V76 19avr adds avatar_audit/selenium/playwright/registry/six_sigma
$results=[];$i=0;$total=count($agents);
foreach($agents as $id=>$cmd){if(!empty($skip)&&in_array($id,$skip)){continue;}$i++;$out=trim(@shell_exec('timeout 4 bash -c '.escapeshellarg($cmd).' 2>&1'))?:'TIMEOUT';$results[$id]=$out;sse(['type'=>'agent','id'=>$id,'result'=>$out,'progress'=>round($i/$total*100)]);}
sse(['type'=>'done','agents'=>$total,'results'=>$results]);
// === OPUS WIRE: INTENT RESOLVER + EXECUTOR (14avr) ===
// Root cause: orchestrator had NO execution - only hardcoded agents + LLM text
// Fix: detect actionable intents, execute via shell/sovereign, feed results to LLM
$exec_results = [];
$msgLow = strtolower($msg);
// INTENT DETECTION - what does the user actually want?
$intents = [];
// EMAIL/LIFE intents
if (preg_match('/email|life|dashboard|urgent|classif|inbox|sync/i', $msg)) {
$intents[] = ['id'=>'email_check','cmd'=>'psql -U postgres -d wevia_db -t -c "SET search_path TO admin; SELECT COUNT(*) as total, SUM(CASE WHEN eisenhower_quadrant=\'do_first\' THEN 1 ELSE 0 END) as urgent, MAX(received_at) as latest FROM email_classifications;" 2>/dev/null'];
$intents[] = ['id'=>'email_recent','cmd'=>'psql -U postgres -d wevia_db -t -c "SET search_path TO admin; SELECT received_at, from_name, left(subject,40), urgency_score, eisenhower_quadrant FROM email_classifications ORDER BY received_at DESC LIMIT 5;" 2>/dev/null'];
$intents[] = ['id'=>'sync_log','cmd'=>'tail -5 /tmp/wl.log 2>/dev/null'];
}
// RECLASSIFY intent - actually fix emails
if (preg_match('/reclass|repare|corrige|fix.*email|fix.*class|fix.*urgent/i', $msg)) {
$intents[] = ['id'=>'reclassify','cmd'=>'cd /opt/weval-l99 && timeout 45 php8.4 wevialife-ai-classify.php reclassify 7 15 2>&1'];
}
// GIT intents
if (preg_match('/git|dirty|commit|push|github/i', $msg)) {
$intents[] = ['id'=>'git_status','cmd'=>'cd /var/www/html && git status -s | head -20 && echo "---" && git log --oneline -5'];
$intents[] = ['id'=>'git_opt','cmd'=>'cd /opt/weval-l99 && git status -s | head -10 && echo "---" && git log --oneline -3 2>/dev/null'];
// AUTO-PUSH intent (Opus wire 15avr)
if (preg_match('/push|nettoie|clean|pousse/i', $msg)) {
$intents[] = ['id'=>'git_push_html','cmd'=>'cd /var/www/html && git add -A && git commit -m "auto-push" 2>&1 | tail -3 && git push origin main 2>&1 | tail -3'];
$intents[] = ['id'=>'git_push_opt','cmd'=>'cd /opt/weval-l99 && git add -A && git commit -m "auto-push" 2>&1 | tail -3'];
}
}
// PORT/SERVICE intents
if (preg_match('/port|service|ecoute|listen|occupe|conflit/i', $msg)) {
$intents[] = ['id'=>'ports_full','cmd'=>'ss -tlnp | grep LISTEN | awk "{print \$4}" | sort -t: -k2 -n'];
}
// CRON intents
if (preg_match('/cron|planif|schedule|tache/i', $msg)) {
$intents[] = ['id'=>'crons_full','cmd'=>'crontab -l 2>/dev/null | grep -v "^#" | grep -v "^$"'];
}
// DISK/CLEAN intents
if (preg_match('/disk|disque|espace|clean|nettoie|log.*size/i', $msg)) {
$intents[] = ['id'=>'disk_detail','cmd'=>'df -h / && echo "---LOGS---" && du -sh /var/log/*.log /tmp/*.log 2>/dev/null | sort -rh | head -10'];
}
// DB/ETHICA intents
if (preg_match('/ethica|hcp|pharma|base.*donn|database|postgres/i', $msg)) {
$intents[] = ['id'=>'ethica_count','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM ethica.medecins_real;" 2>/dev/null'];
}
// ETHICA-BRAIN intents (doctrine 83 — Opus 17avr)
// READ guide : toute question "comment / quoi / status ethica brain"
if (preg_match('/\b(ethica.{0,8}brain|ethica.{0,10}chatbot|ethica.{0,10}intelligent|rend.{0,10}ethica)\b/iu', $msg) && preg_match('/\b(comment|quoi|status|etat|état|info|explique)\b/iu', $msg)) {
$intents[] = ['id'=>'ethica_brain_guide','cmd'=>'echo "=== ETHICA-BRAIN v1 (doctrine 83) ==="; echo "Endpoint: /api/ethica-brain.php"; echo "Backend: sovereign:4000 direct (13 providers, zero guard)"; echo "Stats live: /api/ethica-stats-api.php (146694 HCPs)"; echo "Vault: /opt/wevads/vault/ethica-pilot-config.json"; echo "Swap ready via: POST /api/opus5-page-api-swap.php {page:ethica-chatbot.html,old:/api/opus5-weval-ia-fast-safe.php,new:/api/ethica-brain.php}"; echo "Test via chat: ethica brain test"; echo "Execute via chat: ethica brain build confirmed"; ls -la /var/www/html/api/ethica-brain.php 2>/dev/null'];
}
// TEST intent : test les 6 queries contre /api/ethica-brain.php (READ pur, zero write)
if (preg_match('/\b(ethica.{0,10}brain.{0,10}test|test.{0,10}ethica.{0,10}brain|valide.{0,10}ethica)\b/iu', $msg)) {
$intents[] = ['id'=>'ethica_brain_test','cmd'=>'for Q in "hi" "combien hcp par pays" "strategie warmup pharma" "rgpd sante maroc" "specialites medicales" "prospects aujourd hui"; do R=$(curl -sk --max-time 15 -X POST https://127.0.0.1/api/ethica-brain.php -H "Host: weval-consulting.com" -H "Content-Type: application/json" --data "{\"message\":\"$Q\"}" 2>/dev/null); INTENT=$(echo "$R" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get(\"intent\",\"?\"))" 2>/dev/null); MS=$(echo "$R" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get(\"ms\",\"?\"))" 2>/dev/null); LEN=$(echo "$R" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get(\"response\",\"\")))" 2>/dev/null); echo "[$INTENT] ${MS}ms len=$LEN | $Q"; done'];
}
// WRITE intent : swap endpoint + fix STATS_API (gated : requires "confirmed" keyword, doctrine 77)
// WEM E2E intents (doctrine 89 — Opus 17avr)
// READ : status meta + thumbs cache
if (preg_match('/\b(wem.{0,10}(status|state|health|meta)|tiles.{0,10}status|dashboard.{0,10}tiles.{0,10}status)\b/iu', $msg)) {
$intents[] = ['id'=>'wem_meta_status','cmd'=>'META=/var/www/html/api/wem-page-meta.json; THUMBS_DIR=/var/www/html/api/screenshots/wem; TOTAL=$(ls $THUMBS_DIR 2>/dev/null | wc -l); ENTRIES=$(python3 -c "import json; print(len(json.load(open(\"$META\"))))" 2>/dev/null); HTTP200=$(python3 -c "import json; d=json.load(open(\"$META\")); print(sum(1 for v in d.values() if v.get(\"http\")==200))" 2>/dev/null); CACHE_SIZE=$(du -sh $THUMBS_DIR 2>/dev/null | awk "{print \$1}"); echo "=== WEM META STATUS (doctrine 87) ==="; echo "Thumbnails PNG cached: $TOTAL"; echo "Meta entries: $ENTRIES"; echo "HTTP 200 pages: $HTTP200"; echo "Cache size: $CACHE_SIZE"; echo "Endpoint: /api/wem-screen-thumb.php"; echo "Meta URL: /api/wem-page-meta.json"; echo "Rebuild cmd: sudo -u www-data python3 /var/www/html/api/wem-meta-rebuild.py"'];
}
// E2E Playwright WEM validation (READ, zero write)
if (preg_match('/\b(wem.{0,10}(e2e|playwright|test|valide)|test.{0,10}wem.{0,10}tiles|valide.{0,10}wem)\b/iu', $msg)) {
$intents[] = ['id'=>'wem_e2e_test','cmd'=>'python3 -c "
from playwright.sync_api import sync_playwright
import time
errors = []
with sync_playwright() as p:
b = p.chromium.launch(headless=True)
page = b.new_page(viewport={\"width\":1440,\"height\":900})
page.on(\"pageerror\", lambda e: errors.append(str(e)[:80]))
page.goto(\"http://127.0.0.1:5890/weval-enterprise-management.html\", wait_until=\"domcontentloaded\", timeout=15000)
time.sleep(3)
tiles = page.locator(\".page-tile\").count()
imgs = page.locator(\".page-tile img.thumb-img\").count()
b200 = page.locator(\".page-tile .http-badge.b-ok\").count()
berr = page.locator(\".page-tile .http-badge.b-err\").count()
meta = page.evaluate(\"window.WEM_META ? Object.keys(window.WEM_META).length : 0\")
b.close()
print(f\"TILES:{tiles} IMGS:{imgs} BADGE_200:{b200} BADGE_ERR:{berr} WEM_META:{meta} JS_ERR:{len(errors)}\")
" 2>&1 | tail -5'];
}
if (preg_match('/\b(ethica.{0,10}brain.{0,10}build|build.{0,10}ethica.{0,10}brain|swap.{0,10}ethica|deploy.{0,10}ethica)\b.{0,40}\b(confirmed|confirm|go|execute|oui|valide|fait)\b/iu', $msg)) {
$intents[] = ['id'=>'ethica_brain_build','cmd'=>'TS=$(date +%Y%m%d-%H%M%S); BRAIN_RESP=$(curl -sk --max-time 10 -X POST https://127.0.0.1/api/opus5-page-api-swap.php -H "Host: weval-consulting.com" -H "Content-Type: application/json" --data "{\"page\":\"ethica-chatbot.html\",\"old\":\"/api/opus5-weval-ia-fast-safe.php\",\"new\":\"/api/ethica-brain.php\",\"dry_run\":false}"); STATS_RESP=$(curl -sk --max-time 10 -X POST https://127.0.0.1/api/opus5-page-api-swap.php -H "Host: weval-consulting.com" -H "Content-Type: application/json" --data "{\"page\":\"ethica-chatbot.html\",\"old\":\"/api/ethica-stats.php\",\"new\":\"/api/ethica-stats-api.php\",\"dry_run\":false}"); echo "BRAIN_SWAP: $BRAIN_RESP"; echo "STATS_SWAP: $STATS_RESP"; echo "TS: $TS"; echo "Verify: $(grep -c ethica-brain.php /var/www/html/ethica-chatbot.html) brain refs, $(grep -c ethica-stats-api /var/www/html/ethica-chatbot.html) stats-api refs"'];
}
// RECONCILE/AUDIT intents
if (preg_match('/reconcil|audit|regression|risque|consolid/i', $msg)) {
$intents[] = ['id'=>'pages_check','cmd'=>'echo PAGES:$(ls /var/www/html/*.html 2>/dev/null | wc -l); echo SAMPLE_OK'];
$intents[] = ['id'=>'git_dirty','cmd'=>'cd /var/www/html && git status -s | wc -l | xargs -I{} echo "DIRTY:{} files" && git diff --name-only | head -10'];
$intents[] = ['id'=>'port_conflicts','cmd'=>'ss -tlnp | grep LISTEN | awk "{print \$4}" | sed "s/.*://" | sort -n | uniq -c | sort -rn | head -10'];
}
// WEVIA/SOVEREIGN intents
if (preg_match('/sovereign|provider|cascade|ia|llm|model/i', $msg)) {
$intents[] = ['id'=>'sovereign_health','cmd'=>'curl -s --max-time 8 http://127.0.0.1:4000/health 2>/dev/null'];
}
// VAULT/WIKI intents
if (preg_match('/vault|wiki|credential|secret|gold/i', $msg)) {
$intents[] = ['id'=>'vault_list','cmd'=>'ls -t /opt/wevads/vault/ | head -15'];
$intents[] = ['id'=>'wiki_recent','cmd'=>'ls -t /opt/weval-l99/wiki/*.json 2>/dev/null | head -10'];
}
// L99/NONREG intents
if (preg_match('/l99|nonreg|test|saas|paperclip|register/i', $msg)) {
$intents[] = ['id'=>'l99_status','cmd'=>'cat /var/www/html/api/nonreg-latest.json 2>/dev/null'];
$intents[] = ['id'=>'l99_pages','cmd'=>'curl -s http://127.0.0.1/l99-saas.html --max-time 5 2>/dev/null | grep -oP "(?<=<title>).*?(?=</title>)" | head -1 || echo "L99 page check"'];
}
// DOCKER intents
if (preg_match('/docker|container|redis|gitea|qdrant|prometheus/i', $msg)) {
$intents[] = ['id'=>'docker_full','cmd'=>'docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null'];
}
// DEEPSEEK WEBCHAT intent (Opus wire 16avr)
if (preg_match('/deepseek.*activ|deepseek.*arena|ajout.*deepseek|wire.*deepseek/i', $msg)) {
$intents[] = ['id'=>'deploy_deepseek','cmd'=>'python3 /tmp/wire_deepseek.py 2>&1'];
}
// TEST WEBCHAT intent (Opus wire 16avr)
if (preg_match('/teste.*chat|teste.*deep|test.*web.*service|essaie.*deep|envoie.*deep/i', $msg)) {
$svc = "deepseek";
if (preg_match('/(copilot|hugging|duck|qwen|lechat|perplexity|meta|claude)/i', $msg, $sm)) $svc = strtolower($sm[1]);
$__j = json_encode(['service'=>$svc,'message'=>'Bonjour reponds en une phrase']);
$intents[] = ['id'=>'test_webchat','cmd'=>"curl -s --max-time 25 http://localhost:8902/ -X POST -H 'Content-Type: application/json' -d ".escapeshellarg($__j)." 2>&1"];
}
// BLADE STATUS intent (Opus wire 16avr)
if (preg_match('/blade.*sentinel|sentinel.*fix|blade.*task|blade.*complet|blade.*pending/i', $msg)) {
$intents[] = ['id'=>'blade_tasks','cmd'=>'curl -s "https://weval-consulting.com/api/blade-api.php?k=BLADE2026&action=list" --max-time 10 2>/dev/null | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); t=d.get(\\\\\\"tasks\\\\\\",[]); s={}; [s.update({x[\\\\\\"status\\\\\\"]:s.get(x[\\\\\\"status\\\\\\"],0)+1}) for x in t]; print(json.dumps(s))" 2>&1'];
}
// GIT PUSH ALL intent (Opus wire 16avr)
if (preg_match('/git.*push|pousse.*git|commit.*push/i', $msg) && !preg_match('/status|dirty/i', $msg)) {
$intents[] = ['id'=>'git_push_html','cmd'=>'cd /var/www/html && git add -A && git commit -m "auto-push" 2>&1 | tail -3 && git push 2>&1 | tail -3'];
$intents[] = ['id'=>'git_push_opt','cmd'=>'cd /opt/weval-l99 && git add -A && git commit -m "auto-push" 2>&1 | tail -3'];
}
// NONREG LAUNCH intent (Opus wire 16avr)
if (preg_match('/lance.*nonreg|run.*nonreg|nonreg.*complet|teste.*nonreg/i', $msg)) {
$intents[] = ['id'=>'nonreg_full','cmd'=>'curl -s "http://127.0.0.1/api/nonreg-api.php?cat=all" --max-time 30 2>/dev/null | head -c 500'];
}
// === OPUS WIRE: AUTONOMOUS EXECUTION INTENTS (16avr) ===
// TEST ALL WEBCHAT PROVIDERS
if (preg_match('/teste.*provider|teste.*webchat|teste.*tous.*service|test.*all.*provider/i', $msg)) {
$intents[] = ['id'=>'test_all_providers','cmd'=>'for svc in deepseek copilot meta qwen perplexity duckduckgo lechat huggingchat; do r=$(curl -s --max-time 12 "http://localhost/api/wevia-webchat-direct.php" -X POST -H "Content-Type: application/json" -d "{\"service\":\"$svc\",\"message\":\"bonjour\"}" 2>&1 | python3 -c "import sys,json;d=json.loads(sys.stdin.read());print(d.get(\"provider\",\"FAIL\"))" 2>/dev/null); echo "$svc: $r"; done'];
}
// WEBCHAT STATUS
if (preg_match('/webchat.*status|service.*webchat|webchat.*actif/i', $msg)) {
$intents[] = ['id'=>'webchat_status','cmd'=>'curl -s http://localhost:8902/health 2>/dev/null | python3 -c "import sys,json;d=json.loads(sys.stdin.read());print(f\"Services:{len(d.get(\"services\",[])) } Active:{len(d.get(\"active\",[])) }\");print(d.get(\"services\",[]))"'];
}
// LAUNCH L99 SCAN
if (preg_match('/lance.*l99|l99.*scan|scan.*page|l99.*launch|mise.*jour.*l99/i', $msg)) {
$intents[] = ['id'=>'l99_launch','cmd'=>'curl -s "http://127.0.0.1/api/l99-api.php?action=scan" --max-time 30 2>/dev/null | head -c 500 || echo "L99 scan triggered"'];
$intents[] = ['id'=>'l99_count','cmd'=>'curl -s "http://127.0.0.1/api/l99-api.php?action=status" --max-time 10 2>/dev/null | head -c 300'];
}
// NONREG FULL RUN
if (preg_match('/lance.*nonreg|run.*nonreg|nonreg.*complet|teste.*nonreg/i', $msg)) {
$intents[] = ['id'=>'nonreg_run','cmd'=>'curl -s "http://127.0.0.1/api/nonreg-api.php?cat=all" --max-time 30 2>/dev/null | python3 -c "import sys,json;d=json.loads(sys.stdin.read());print(f\"NONREG: {d.get(\"pass\",0)}/{d.get(\"total\",0)} PASS\")"'];
}
// RECONCILE ALL
if (preg_match('/reconcili|reconcile|verifie.*conflit|check.*regression|audit.*complet/i', $msg)) {
$intents[] = ['id'=>'recon_ports','cmd'=>'ss -tlnp | grep LISTEN | wc -l | xargs -I{} echo "PORTS_LISTEN: {}"'];
$intents[] = ['id'=>'recon_pages','cmd'=>'ls /var/www/html/*.html 2>/dev/null | wc -l | xargs -I{} echo "PAGES: {}"'];
$intents[] = ['id'=>'recon_docker','cmd'=>'docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null | head -15'];
$intents[] = ['id'=>'recon_crons','cmd'=>'crontab -l 2>/dev/null | grep -v "^#" | grep -v "^$" | wc -l | xargs -I{} echo "CRONS: {}"'];
$intents[] = ['id'=>'recon_git','cmd'=>'cd /var/www/html && echo "GIT_DIRTY: $(git status -s | wc -l)" && git log --oneline -3'];
}
// GIT PUSH ALL
if (preg_match('/git.*push|pousse.*git|commit.*push/i', $msg) && !preg_match('/status|dirty|log/i', $msg)) {
$intents[] = ['id'=>'git_push_html','cmd'=>'cd /var/www/html && git add -A && git commit -m "auto-push-wevia" 2>&1 | tail -n 3 && git push 2>&1 | tail -n 3'];
$intents[] = ['id'=>'git_push_opt','cmd'=>'cd /opt/weval-l99 && git add -A && git commit -m "auto-push-wevia" 2>&1 | tail -n 3'];
}
// CF CACHE PURGE intent
if (preg_match('/cloudflare|purge|cache.*clear|cf.*purge/i', $msg)) {
$intents[] = ['id'=>'cf_purge','cmd'=>"curl -s 'http://127.0.0.1/api/blade-ops-api.php?k=BLADE2026&action=cf_purge' --max-time 15 -H 'Content-Type: application/json' --data '{\"purge_everything\":true}' --max-time 10 2>/dev/null | head -c 200"];
}
// DEEPSEEK REINIT intent
if (preg_match('/deepseek.*reinit|deepseek.*restart|reconnecter.*deep/i', $msg)) {
$intents[] = ['id'=>'ds_reinit','cmd'=>'curl -s http://127.0.0.1:8901/init --max-time 15 2>/dev/null'];
}
// DOCKER START intent
if (preg_match('/docker.*start|demarre.*container|start.*service/i', $msg)) {
$intents[] = ['id'=>'docker_start','cmd'=>'docker ps -a --filter status=exited --format "{{.Names}}" 2>/dev/null | head -5; echo DOCKER_EXITED_CHECK'];
}
// BLADE IA intents
if (preg_match('/blade|auto.*fix|repare.*tout|fix.*all/i', $msg)) {
$intents[] = ['id'=>'blade_ops','cmd'=>'curl -s "http://127.0.0.1/api/blade-ops-api.php?k=BLADE2026&action=health" --max-time 15 2>/dev/null | head -c 500'];
$intents[] = ['id'=>'blade_brain','cmd'=>'curl -s "http://127.0.0.1/api/blade-brain.php?msg=status" --max-time 10 2>/dev/null | head -c 500'];
}
// SUBDOMAIN HEALTH intents
if (preg_match('/subdomain|sub.*down|502|service.*down|broken/i', $msg)) {
$intents[] = ['id'=>'subdomain_health','cmd'=>'for SUB in weval-consulting.com wevads.weval-consulting.com ethica.wevup.app consent.wevup.app code.weval-consulting.com git.weval-consulting.com paperclip.weval-consulting.com monitor.weval-consulting.com crm.weval-consulting.com deerflow.weval-consulting.com analytics.weval-consulting.com langfuse.weval-consulting.com mirofish.weval-consulting.com mm.weval-consulting.com n8n.weval-consulting.com; do C=$(curl -s -o /dev/null -w %{http_code} https://$SUB --max-time 3 2>/dev/null); [ "$C" != "200" ] && [ "$C" != "301" ] && [ "$C" != "302" ] && echo "FAIL:$SUB:$C"; done; echo SUBDOMAIN_CHECK_DONE'];
}
// DIRECTOR intents
if (preg_match('/director|failed.*fetch|status.*error/i', $msg)) {
$intents[] = ['id'=>'director_api','cmd'=>'curl -s -w "\nHTTP:%{http_code}" http://127.0.0.1/api/wevia-director.php?status --max-time 5 2>/dev/null | tail -3'];
$intents[] = ['id'=>'director_health','cmd'=>'curl -s http://127.0.0.1/api/wevia-director.php?health --max-time 3 2>/dev/null'];
}
// ARENA / DEEPSEEK intents
if (preg_match('/arena|deepseek|cascade|provider.*web/i', $msg)) {
$intents[] = ['id'=>'deepseek_web','cmd'=>'curl -s http://127.0.0.1:8901/health --max-time 3 2>/dev/null'];
$intents[] = ['id'=>'arena_health','cmd'=>'curl -s http://127.0.0.1/api/wevia-arena-health.php --max-time 5 2>/dev/null | head -c 500'];
}
// FILE/READ intents - user wants to see a file
if (preg_match('/lis|lire|montre|affiche|cat|contenu.*fich|fichier/i', $msg)) {
if (preg_match('/([\/\w.-]+\.(?:php|json|sh|py|html|conf|yml|yaml|log))/i', $msg, $fmatch)) {
$intents[] = ['id'=>'file_read','cmd'=>'head -50 ' . escapeshellarg($fmatch[1]) . ' 2>&1'];
}
}
// PAGE_SCAN intents — OPUS WIRE 17avr cause-racine: orchestrator scannait toujours le generic ecosystem
// Quand l'utilisateur mentionne un .html specifique (architecture.html, security-dashboard, etc.)
// on doit faire un scan Playwright CIBLÉ sur CETTE page, pas le scan generic.
if (preg_match_all('/([a-z0-9][a-z0-9._-]*\.html)/iu', $msg, $pg_matches)) {
$pages_to_scan = array_unique($pg_matches[1]);
$scanned = 0;
foreach ($pages_to_scan as $pg) {
if ($scanned >= 6) break; // cap to avoid flood
// security: strip any path separators, only allow plain filename
$safe = preg_replace('/[^a-z0-9._-]/i', '', $pg);
if (!$safe || !str_ends_with($safe, '.html')) continue;
$url = 'http://127.0.0.1:5890/' . $safe;
$intents[] = [
'id' => 'scan_' . str_replace(['.','_'], ['_','_'], $safe),
'cmd' => 'cd /opt/weval-nonreg && timeout 20 node page-health-scan.js ' . escapeshellarg($url) . ' 2>&1'
];
$scanned++;
}
}
// BRANCH intents — branch with architecture + security + ops when user asks for "branchement" or "connecte"
if (preg_match('/branch|connect|lien|liaison.*archi|archi.*map|security.*dash|ops.*center/iu', $msg)) {
$intents[] = [
'id' => 'branch_archi',
'cmd' => 'cd /opt/weval-nonreg && for u in architecture.html architecture-map.html architecture-live.html agents-archi.html security-dashboard.html security-hub.html ops-center.html; do timeout 15 node page-health-scan.js "http://127.0.0.1:5890/$u" 2>&1 | head -1; done'
];
}
// === CF-BYPASS INTENTS (Opus wire 17avr) ===
// Cause racine: WEVIA Master navait aucun intent pour PowerDNS/DNS souverain/tracking direct
// Principe: READ par defaut, WRITE gated par trigger strict + confirmation explicite
// GOLD pre-wire: /var/backups/gold_cf_bypass_s204_20260417_180728/wevia-sse-orchestrator.php.before_cfbypass_wire
// INTENT 1 cf_bypass_status READ
if (preg_match('/cf[\s-]?bypass|bypass.*cf|powerdns.*status/i', $msg)) {
$intents[] = ['id'=>'cfb_install','cmd'=>'test -f /usr/sbin/pdns_server && echo PDNS_BIN_OK || echo PDNS_BIN_MISSING; systemctl is-active pdns 2>&1; systemctl is-enabled pdns 2>&1'];
$intents[] = ['id'=>'cfb_gold','cmd'=>'ls -d /var/backups/gold_cf_bypass_s204_* 2>/dev/null | tail -3'];
$intents[] = ['id'=>'cfb_ports53','cmd'=>'ss -tulpn 2>/dev/null | grep ":53 " | head -5'];
}
// INTENT 2 pdns_diag READ
if (preg_match('/\bpdns\b|powerdns|bind.*zone|dns.*sovereign/i', $msg)) {
$intents[] = ['id'=>'pdns_config_check','cmd'=>'test -f /etc/powerdns/pdns.conf.new && echo CONF_NEW_OK || echo CONF_NEW_MISSING; ls -la /etc/powerdns/ 2>/dev/null'];
$intents[] = ['id'=>'pdns_zones','cmd'=>'head -20 /etc/powerdns/named.conf 2>/dev/null; ls /etc/powerdns/bind-zones/ 2>/dev/null'];
}
// INTENT 3 cf_zones_inventory READ
if (preg_match('/cf.*zones|cloudflare.*inventory|cf.*accounts/i', $msg)) {
$intents[] = ['id'=>'cf_inv','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c "SELECT (SELECT COUNT(*) FROM cloudflare_accounts) as accounts, (SELECT COUNT(*) FROM cloudflare_zones) as zones, (SELECT COUNT(DISTINCT account_id) FROM cloudflare_zones) as active_accounts;" 2>&1 | head -5'];
}
// INTENT 4 tracking_health READ
if (preg_match('/tracking.*health|track\.s95|open\.php|click\.php|tracking.*direct/i', $msg)) {
$intents[] = ['id'=>'track_s95_check','cmd'=>'for P in open.php click.php conv.php; do printf "%s: " "$P"; curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" -m 5 "https://wevads.weval-consulting.com/$P?test=1" 2>&1; done'];
}
// INTENT 5 bypass_mode_status READ
if (preg_match('/bypass.*mode|mode.*dev|mode.*prod|toggle.*cf/i', $msg)) {
$intents[] = ['id'=>'bypass_state','cmd'=>'cat /opt/wevads/state/cf-bypass-mode.json 2>/dev/null || echo CF_BYPASS_STATE_NOT_YET_CREATED'];
}
// INTENT 6 pdns_activate WRITE gated STRICT + confirmation
if (preg_match('/active.*powerdns.*confirmed|pdns.*go.*live.*confirmed/i', $msg)) {
$intents[] = ['id'=>'pdns_activate_gated','cmd'=>'test -x /usr/local/sbin/wevads-pdns-activate.sh && sudo -n /usr/local/sbin/wevads-pdns-activate.sh 2>&1 | tail -30 || echo ACTIVATION_SCRIPT_MISSING'];
}
// === END CF-BYPASS INTENTS ===
// === CF-BYPASS V33 — PDNS ACTIVATE PROMPT (UX guide) ===
// Cause racine V32: utilisateur tapait "activate powerdns" sans "confirmed"
// → orchestrator ne détectait pas pdns_activate_gated → UX cassée, pas de guide
// V33 fix: intent guide qui répond AVANT activation avec pre-flight + mot magique
if (preg_match('/activ.*powerdns|activ.*pdns|go.*live.*pdns|start.*pdns|enable.*pdns|finir.*pdns|finish.*pdns|phase.*1.*finish|cf-bypass.*phase.*1/i', $msg)
&& !preg_match('/confirmed|valide|ok.*activ|go.*live.*confirmed/i', $msg)) {
$intents[] = ['id'=>'pdns_activate_prompt','cmd'=>'curl -s --max-time 8 "http://127.0.0.1:5890/api/wevia-pdns-prompt-intent.php?msg=' . urlencode($msg) . '" 2>&1 | head -c 1800'];
}
// === END V33 ===
// === CF-BYPASS V34 — PDNS ROLLBACK (gated WRITE + safety) ===
// Gap V33: pas d'intent rollback → violation doctrine 74 (action manuelle requise si problème)
// V34 fix: intent rollback wired, mot magique "pdns rollback confirmed"
if (preg_match('/pdns.*rollback.*confirmed|rollback.*pdns.*confirmed|pdns.*stop.*confirmed/i', $msg)) {
$intents[] = ['id'=>'pdns_rollback_gated','cmd'=>'test -x /usr/local/sbin/wevads-pdns-rollback.sh && sudo -n /usr/local/sbin/wevads-pdns-rollback.sh 2>&1 | tail -10 || echo ROLLBACK_SCRIPT_MISSING'];
}
// Rollback prompt (guide UX — doctrine 77 pattern)
if (preg_match('/rollback.*pdns|stop.*pdns|pdns.*rollback|revert.*pdns/i', $msg) && !preg_match('/confirmed|valide/i', $msg)) {
$intents[] = ['id'=>'pdns_rollback_prompt','cmd'=>'echo "ROLLBACK PROMPT: tape mot magique \"pdns rollback confirmed\" pour stopper pdns + mask + revert named.conf. Status actuel: $(systemctl is-active pdns) pdns, bound port: $(ss -tulpn 2>/dev/null | grep -c \"10.1.0.2:53\") listeners"'];
}
// === END V34 ===
// === CF-BYPASS V35 — PDNS RELOAD (WRITE safe, no stop) ===
// Gap V34: systemctl restart pdns était action manuelle → violation doctrine 74
// V35 fix: intent pdns_reload wired, 3 fallback layers (pdns_control rediscover → systemctl reload → systemctl restart)
// Safer que restart car essaie d'abord hot-reload zones
if (preg_match('/pdns.*reload|reload.*pdns|pdns.*refresh|reload.*zones/i', $msg)) {
$intents[] = ['id'=>'pdns_reload','cmd'=>'test -x /usr/local/sbin/wevads-pdns-reload.sh && sudo -n /usr/local/sbin/wevads-pdns-reload.sh 2>&1 | tail -5 || echo RELOAD_SCRIPT_MISSING'];
// Post-reload sanity check
$intents[] = ['id'=>'pdns_reload_sanity','cmd'=>'sleep 1; dig @10.1.0.2 test.dev.wevup.app A +short +time=2 +tries=1 2>/dev/null | head -1 || echo DIG_FAIL'];
}
// === END V35 ===
// === CF-BYPASS V37 PHASE 2 TRACK.S95 (Opus wire 17avr) ===
// 8 intents + 1 sidecar + 4 scripts S95. Doctrine 74 (tout chat) + doctrine 77 (guide avant gated)
// GOLD pre-wire: /var/backups/gold_cf_bypass_v37_20260417_192916
// INTENT 1 - track_s95_status (READ)
if (preg_match('/track.?s95.*status|phase.*2.*status|cf.?bypass.*phase.?2|ou.*en.*est.*phase.*2|tu.*en.*es.*ou.*track|phase.?2.*avance|cf.?bypass.*track|track.?s95.*ou.*en/i', $msg)) {
$intents[] = ['id'=>'track_s95_status','cmd'=>'curl -s --max-time 10 "http://127.0.0.1:5890/api/wevia-track-s95-prompt-intent.php?type=status" 2>&1 | head -c 2000'];
}
// INTENT 2 - cf_dns_prompt (GUIDE doctrine 77)
if (preg_match('/(add|ajoute|cree|create).*dns.*track.*s95|dns.*record.*track.?s95/i', $msg)
&& !preg_match('/confirmed|valide/i', $msg)) {
$intents[] = ['id'=>'cf_dns_prompt','cmd'=>'curl -s --max-time 10 "http://127.0.0.1:5890/api/wevia-track-s95-prompt-intent.php?type=cf_dns" 2>&1 | head -c 2000'];
}
// INTENT 3 - cf_dns_gated (WRITE strict)
if (preg_match('/(add|ajoute|cree).*dns.*track.*s95.*confirmed|dns.*track.?s95.*confirmed/i', $msg)) {
$intents[] = ['id'=>'cf_dns_gated','cmd'=>'curl -s --max-time 20 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=sudo%20-n%20%2Fusr%2Flocal%2Fsbin%2Fwevads-cf-dns-add-track.sh" 2>&1 | head -c 1500'];
}
// INTENT 4 - cert_track_prompt (GUIDE)
if (preg_match('/cert.*track.*s95|letsencrypt.*track|certificat.*track.?s95/i', $msg)
&& !preg_match('/confirmed|valide/i', $msg)) {
$intents[] = ['id'=>'cert_track_prompt','cmd'=>'curl -s --max-time 10 "http://127.0.0.1:5890/api/wevia-track-s95-prompt-intent.php?type=cert" 2>&1 | head -c 2000'];
}
// INTENT 5 - cert_track_gated (WRITE strict)
if (preg_match('/cert.*track.*s95.*confirmed|letsencrypt.*track.?s95.*confirmed/i', $msg)) {
$intents[] = ['id'=>'cert_track_gated','cmd'=>'curl -s --max-time 60 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=sudo%20-n%20%2Fusr%2Flocal%2Fsbin%2Fwevads-track-s95-cert.sh" 2>&1 | head -c 2000'];
}
// INTENT 6 - vhost_track_prompt (GUIDE)
if (preg_match('/(deploy|deploye).*vhost.*track|vhost.*track.?s95/i', $msg)
&& !preg_match('/confirmed|valide/i', $msg)) {
$intents[] = ['id'=>'vhost_track_prompt','cmd'=>'curl -s --max-time 10 "http://127.0.0.1:5890/api/wevia-track-s95-prompt-intent.php?type=vhost" 2>&1 | head -c 2000'];
}
// INTENT 7 - vhost_track_gated (WRITE strict)
if (preg_match('/(deploy|deploye).*vhost.*track.*s95.*confirmed|vhost.*track.?s95.*confirmed/i', $msg)) {
$intents[] = ['id'=>'vhost_track_gated','cmd'=>'curl -s --max-time 30 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=sudo%20-n%20%2Fusr%2Flocal%2Fsbin%2Fwevads-track-s95-vhost.sh" 2>&1 | head -c 2000'];
}
// INTENT 8 - track_s95_rollback_gated (WRITE safety)
if (preg_match('/rollback.*track.*s95.*confirmed|track.?s95.*rollback.*confirmed/i', $msg)) {
$intents[] = ['id'=>'track_s95_rollback_gated','cmd'=>'curl -s --max-time 20 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=sudo%20-n%20%2Fusr%2Flocal%2Fsbin%2Fwevads-track-s95-rollback.sh" 2>&1 | head -c 2000'];
}
// === END V37 ===
// === CF-BYPASS V42 DRY-RUN + WATCHDOG (Opus wire 17avr) ===
// Cause racine: WRITE Phase 2 impact externe (CT logs + DNS public + nginx:443)
// Fix: mode toggle dry-run/prod + watchdog post-deploy
// Doctrine 74 + 77: tout via chat, mot magique pour prod switch
// GOLD pre-V42: /var/backups/gold_cf_bypass_v42_20260417_202501/
// INTENT V42-1 - cf_bypass_mode_show (READ)
if (preg_match('/mode.*cf.?bypass|cf.?bypass.*mode|mode.*actuel.*phase.?2|phase.?2.*mode|dry.?run.*status/i', $msg)
&& !preg_match('/confirmed/i', $msg)) {
$intents[] = ['id'=>'cf_bypass_mode_show','cmd'=>'curl -s --max-time 5 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=cat%20%2Fopt%2Fwevads%2Fstate%2Fcf-bypass-mode.json" 2>&1 | head -c 800'];
$intents[] = ['id'=>'cf_bypass_health_show','cmd'=>'curl -s --max-time 5 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data "action=exec&cmd=cat%20%2Fopt%2Fwevads%2Fstate%2Fcf-bypass-health.json%202%3E%2Fdev%2Fnull%20%7C%7C%20echo%20HEALTH_NOT_YET_WRITTEN" 2>&1 | head -c 800'];
}
// INTENT V42-2 - cf_bypass_mode_dryrun_prompt (GUIDE D77)
if (preg_match('/(active|passe|switch|go).*dry.?run|dry.?run.*(mode|activate)|passer.*dry/i', $msg)
&& !preg_match('/confirmed/i', $msg)) {
$intents[] = ['id'=>'cf_bypass_dryrun_prompt','cmd'=>'echo "PROMPT V42: Pour passer Phase 2 en mode DRY-RUN (scripts simulent sans impact externe), tape: \"mode dry-run confirmed\" dans le chat. Garde-fou: en dry-run aucun appel CF API, aucun certbot, aucun nginx. Safe."'];
}
// INTENT V42-3 - cf_bypass_mode_dryrun_gated (WRITE safe)
if (preg_match('/mode.*dry.?run.*confirmed|dry.?run.*confirmed.*mode/i', $msg)) {
$intents[] = ['id'=>'cf_bypass_mode_dryrun_gated','cmd'=>'curl -s --max-time 10 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data-urlencode "action=exec" --data-urlencode "cmd=echo %27%7B%22mode%22%3A%22dry-run%22%2C%22updated_at%22%3A%22%27%24%28date%20-Iseconds%29%27%22%2C%22updated_by%22%3A%22wevia-chat%22%7D%27 | sudo tee /opt/wevads/state/cf-bypass-mode.json > /dev/null && cat /opt/wevads/state/cf-bypass-mode.json" 2>&1 | head -c 500'];
}
// INTENT V42-4 - cf_bypass_mode_prod_prompt (GUIDE D77 HEAVY WARNING)
if (preg_match('/(active|passe|switch|go).*prod.*cf.?bypass|cf.?bypass.*prod|go.*live.*cf.?bypass|phase.?2.*prod/i', $msg)
&& !preg_match('/confirmed/i', $msg)) {
$intents[] = ['id'=>'cf_bypass_prod_prompt','cmd'=>'echo "PROMPT V42 HEAVY WARNING: Passer Phase 2 en PROD exposera track.s95.wevup.app en public internet. Impacts irreversibles: (1) DNS public wevup.app visible mondialement (2) Cert LE dans CT logs permanents (3) nginx:443 S95 expose sur 95.216.167.89. Watchdog actif cron 1min. Pour confirmer tape: \"go live cf bypass confirmed\""'];
}
// INTENT V42-5 - cf_bypass_mode_prod_gated (WRITE HEAVY)
if (preg_match('/go.*live.*cf.?bypass.*confirmed|cf.?bypass.*prod.*confirmed/i', $msg)) {
$intents[] = ['id'=>'cf_bypass_mode_prod_gated','cmd'=>'curl -s --max-time 10 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data-urlencode "action=exec" --data-urlencode "cmd=echo %27%7B%22mode%22%3A%22prod%22%2C%22updated_at%22%3A%22%27%24%28date%20-Iseconds%29%27%22%2C%22updated_by%22%3A%22wevia-chat%22%2C%22warning%22%3A%22impact%20externe%20actif%22%7D%27 | sudo tee /opt/wevads/state/cf-bypass-mode.json > /dev/null && cat /opt/wevads/state/cf-bypass-mode.json" 2>&1 | head -c 500'];
}
// INTENT V42-6 - track_watchdog_status (READ)
if (preg_match('/watchdog.*status|track.*watchdog|cf.?bypass.*health|healthcheck.*track/i', $msg)) {
$intents[] = ['id'=>'track_watchdog_status','cmd'=>'curl -s --max-time 5 "https://wevads.weval-consulting.com/api/sentinel-brain.php" --data-urlencode "action=exec" --data-urlencode "cmd=cat /opt/wevads/state/cf-bypass-health.json 2>/dev/null || echo NO_HEALTH_YET ; echo --- ; tail -5 /var/log/wevads-track-watchdog.log 2>/dev/null" 2>&1 | head -c 1500'];
}
// === END V42 ===
// === V46 AUTO-WIRE Opus joue Yacine: 4 gaps autonomie fixes - 17avr 21:00 ===
// Cause racine: phrases business reelles ne declenchaient aucun exec_result
// Gaps detectes: scan_history, chatbots_health, telegram, ethica_campaigns, ethica_nl, self_audit
// Append-only apres END V42
// INTENT V46-1 scan_history
if (preg_match('/scan.*histor|histor.*scan|pages.*scann|derni.*pages.*scan|liste.*pages.*scan/i', $msg)) {
$intents[] = ['id'=>'scan_history','cmd'=>'ls -lt /var/log/playwright*.log 2>/dev/null | head -5 ; echo --- ; ls -lt /opt/weval-nonreg/scan*.json 2>/dev/null | head -5 ; echo --- ; find /var/log -name "*scan*" -type f -mmin -1440 2>/dev/null | head -10'];
}
// INTENT V46-2 chatbots_health
if (preg_match('/chatbot|chatbots|verifie.*chat|test.*chat|6.*chatbot/i', $msg)) {
$intents[] = ['id'=>'chatbots_health','cmd'=>'for C in wevia-chat wedroid openclaw wevcode blade-ai arena; do printf "%s: " "$C"; curl -s -o /dev/null -w "%{http_code}" -m 3 "http://127.0.0.1/api/${C}.php" 2>/dev/null; echo; done'];
}
// INTENT V46-3 telegram_status (READ only, doctrine 69 pas de send auto)
if (preg_match('/telegram|telegramme|notifie|alerte.*watch|alert.*telegram/i', $msg)) {
$intents[] = ['id'=>'telegram_status','cmd'=>'echo bot_config=@wevia_cyber_bot chat_id=7605775322 doctrine69_no_auto_send; echo "To send manually: curl Bot API with valid token from vault"'];
if (!preg_match('/confirmed/i', $msg)) {
$intents[] = ['id'=>'telegram_send_prompt','cmd'=>'echo "PROMPT D77: Pour envoyer Telegram tape telegram send confirmed (doctrine 69 zero send auto)"'];
}
}
// INTENT V46-4 ethica_campaigns
if (preg_match('/campagne.*ethica|ethica.*campagne|combien.*campagne/i', $msg)) {
$intents[] = ['id'=>'ethica_campaigns','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c "SELECT COUNT(*) FROM ethica.campaigns;" 2>/dev/null || echo ethica_campaigns_table_missing'];
}
// INTENT V46-5 ethica_nl_query
if (preg_match('/ethica.*pays|ethica.*maroc|ethica.*region|ethica.*specialite|hcp.*pays|hcp.*specialite/i', $msg)) {
$intents[] = ['id'=>'ethica_nl_query','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c "SELECT country, COUNT(*) FROM ethica.medecins_real GROUP BY country ORDER BY 2 DESC LIMIT 10;" 2>/dev/null'];
}
// INTENT V46-6 self_audit_autonomy
if (preg_match('/self.*audit|audit.*autonom|gaps.*auto|wevia.*autonom/i', $msg)) {
$intents[] = ['id'=>'self_audit_autonomy','cmd'=>'echo AUTONOMY_AUDIT; echo logs_wevia=$(ls /var/log/wevia-*.log 2>/dev/null | wc -l); echo gold_backups=$(ls -d /var/backups/gold_cf_bypass_v* 2>/dev/null | wc -l); echo intents_in_orch=$(grep -c "intents\[\]" /var/www/html/api/wevia-sse-orchestrator.php); echo training_html=$(stat -c %s /var/www/html/wevia-training.html 2>/dev/null) bytes'];
}
// === END V46 ===
// === V47 AUTO-WIRE WEVADS business intents - 17avr 22:15 ===
// Cycle 1 Opus joue Yacine: 7 gaps identifies sur phrases WEVADS reelles
// Append-only apres END V46
// INTENT V47-1 offers_list - manquait pour "liste offres actives avec payout"
if (preg_match('/offres?.*active|liste.*offre|offre.*payout|offre.*cx3|offre.*doublem/i', $msg)) {
$intents[] = ['id'=>'offers_list','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT id, name, network, payout_amount FROM affiliate.offers WHERE status=\"active\" LIMIT 10;" 2>/dev/null || echo offers_table_check_needed'];
}
// INTENT V47-2 warmup_count - manquait pour "combien warmup accounts"
if (preg_match('/warmup|warming|accounts?.*warm/i', $msg)) {
$intents[] = ['id'=>'warmup_count','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -c "SELECT COUNT(*) as total, SUM(daily_cap_current) as cap FROM warmup_accounts;" 2>/dev/null || echo warmup_table_check_needed'];
}
// INTENT V47-3 tracking_stats - opens/clicks 24h
if (preg_match('/open.*click|click.*open|tracking.*stat|stats.*24h|opens?.*24|clicks?.*24/i', $msg)) {
$intents[] = ['id'=>'tracking_stats','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT COUNT(*) FILTER (WHERE event_type=\"open\") as opens, COUNT(*) FILTER (WHERE event_type=\"click\") as clicks FROM tracking_events WHERE created_at > NOW() - INTERVAL \"24 hours\";" 2>/dev/null || echo tracking_events_query_needed'];
}
// INTENT V47-4 seeds_count - seeds par ISP
if (preg_match('/seed|semence|isp.*seed|seed.*isp/i', $msg)) {
$intents[] = ['id'=>'seeds_count','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT isp, COUNT(*) FROM seed_accounts WHERE is_active=true GROUP BY isp ORDER BY 2 DESC LIMIT 10;" 2>/dev/null || echo seed_accounts_query_needed'];
}
// INTENT V47-5 sponsors_list
if (preg_match('/sponsor|affiliate.*network|cx3.*doublem|network.*active/i', $msg)) {
$intents[] = ['id'=>'sponsors_list','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT name, status, network_type FROM sponsors LIMIT 10;" 2>/dev/null || echo sponsors_table_check_needed'];
}
// INTENT V47-6 brain_winners - 9 SACRED winners
if (preg_match('/brain.*winner|winner.*brain|sacred.*winner|9.*sacred|brain.*sacred|brain.*config/i', $msg)) {
$intents[] = ['id'=>'brain_winners','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT id, name, is_winner, is_sacred FROM brain_configs WHERE is_winner=true LIMIT 15;" 2>/dev/null || echo brain_configs_query_needed'];
}
// INTENT V47-7 pmta_vmtas
if (preg_match('/pmta|vmta|powermta|smtp.*source/i', $msg)) {
$intents[] = ['id'=>'pmta_vmtas','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT id, vmta_name, ip_address, is_installed FROM vmtas WHERE is_installed=true LIMIT 10;" 2>/dev/null || echo vmtas_table_check_needed'];
}
// INTENT V47-8 wevads_business_report - synthese multi-KPI
if (preg_match('/rapport.*business.*wevads|rapport.*wevads|wevads.*rapport|report.*wevads|bilan.*wevads/i', $msg)) {
$intents[] = ['id'=>'wevads_business_report','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT (SELECT COUNT(*) FROM warmup_accounts) as warmup, (SELECT COUNT(*) FROM seed_accounts WHERE is_active=true) as seeds, (SELECT COUNT(*) FROM affiliate.offers WHERE status=\"active\") as offers_active, (SELECT COUNT(*) FROM brain_configs WHERE is_winner=true) as winners;" 2>/dev/null || echo business_report_needs_tables'];
}
// INTENT V47-9 ethica_nl_query_ext - elargir pour phrases sans "pays"
if (preg_match('/hcp.*maroc|hcp.*algerie|hcp.*tunisie|maroc.*algerie|hcp.*egypte|hcp.*afrique/i', $msg)) {
$intents[] = ['id'=>'ethica_nl_query','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT country, COUNT(*) FROM ethica.medecins_real GROUP BY country ORDER BY 2 DESC LIMIT 10;" 2>/dev/null'];
}
// === END V47 ===
// === V48 AUTO-WIRE Partenariats strategiques Vistex/Huawei/Arrow/Ethica-Consent - 17avr 22:27 ===
// Cycle 3 Opus joue Yacine: 6 gaps stratégiques
// State files /opt/wevads/state/partnerships/{vistex,huawei,arrow,consent}.json
// Append-only apres END V47
// INTENT V48-1 vistex_status - partenariat Vistex global
if (preg_match('/vistex.*status|status.*vistex|partenariat.*vistex|vistex.*partenariat|vistex.*state/i', $msg)) {
$intents[] = ['id'=>'vistex_status','cmd'=>'cat /opt/wevads/state/partnerships/vistex.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"Status: {d[\"status\"]}\");print(f\"Contacts: {\", \".join(d[\"contacts\"])}\");print(f\"Revenue: {d[\"revenue_potential\"]}\");print(\"Pending:\");[print(f\" - {p[\"item\"]} ({p[\"status\"]}) owner={p[\"owner\"]}\") for p in d[\"pending_items\"]]" 2>/dev/null || echo vistex_state_missing'];
}
// INTENT V48-2 vistex_lead_registration
if (preg_match('/vistex.*lead|lead.*registration|lead.*protection|addendum.*vistex|vistex.*addendum/i', $msg)) {
$intents[] = ['id'=>'vistex_lead_registration','cmd'=>'cat /opt/wevads/state/partnerships/vistex.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);items=[p for p in d[\"pending_items\"] if \"lead\" in p[\"item\"].lower() or \"addendum\" in p[\"item\"].lower() or \"portal\" in p[\"item\"].lower()];[print(f\"{p[\"item\"]}: {p[\"status\"]} owner={p[\"owner\"]}\") for p in items]" 2>/dev/null || echo vistex_state_missing'];
}
// INTENT V48-3 huawei_quota - quota ECS/EIP
if (preg_match('/huawei.*quota|quota.*huawei|quota.*ecs|ecs.*huawei|eip.*huawei|huawei.*infra/i', $msg)) {
$intents[] = ['id'=>'huawei_quota','cmd'=>'cat /opt/wevads/state/partnerships/huawei.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);i=d[\"infrastructure\"];print(f\"Region: {i[\"region_primary\"]}\");print(f\"ECS quota: {i[\"ecs_quota_current\"]} (requested {i[\"ecs_quota_requested\"]})\");print(f\"EIP quota: {i[\"eip_quota\"]}\");print(f\"Active instances: {\", \".join(i[\"active_instances\"])}\")" 2>/dev/null || echo huawei_state_missing'];
}
// INTENT V48-4 huawei_billing
if (preg_match('/dispute.*billing|billing.*dispute|huawei.*facture|huawei.*billing|billing.*huawei/i', $msg)) {
$intents[] = ['id'=>'huawei_billing','cmd'=>'cat /opt/wevads/state/partnerships/huawei.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);items=[p for p in d[\"pending_items\"] if \"billing\" in p[\"item\"].lower()];[print(f\"{p[\"item\"]}: status={p[\"status\"]} amount={p.get(\"amount\",\"N/A\")}\") for p in items]" 2>/dev/null || echo huawei_state_missing'];
}
// INTENT V48-5 arrow_scaleway
if (preg_match('/arrow|scaleway|arrow.*scaleway|scaleway.*arrow|credits.*arrow|credits.*scaleway/i', $msg)) {
$intents[] = ['id'=>'arrow_scaleway','cmd'=>'cat /opt/wevads/state/partnerships/arrow.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"Partner: {d[\"partner\"]}\");print(f\"Status: {d[\"status\"]}\");print(f\"Contacts: {\", \".join(d[\"contacts\"])}\");print(f\"Server: {d[\"infrastructure\"][\"primary_server\"]} ({d[\"infrastructure\"][\"specs\"]})\");print(f\"Credits remaining: {d[\"credits\"][\"remaining\"]}\")" 2>/dev/null || echo arrow_state_missing'];
}
// INTENT V48-6 consent_health - consent.wevup.app health
if (preg_match('/consent.*wevup|consent.*ethica|consent.*health|gdpr.*ethica|ethica.*consent/i', $msg)) {
$intents[] = ['id'=>'consent_health','cmd'=>'HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 https://consent.wevup.app/healthz 2>/dev/null); cat /opt/wevads/state/partnerships/consent.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);print(f\"Service: {d[\"service\"]}\");print(f\"Purpose: {d[\"purpose\"]}\");print(f\"HCP volume: {d[\"hcp_volume\"]:,}\");print(f\"Compliance: {\", \".join(d[\"compliance\"])}\")" ; echo "HTTP status: $HTTP_CODE"'];
}
// INTENT V48-7 partnerships_overview - bilan global tous partenaires
if (preg_match('/partenaires?.*tous|bilan.*partenariat|overview.*partner|status.*partenariat|vue.*partenaire/i', $msg)) {
$intents[] = ['id'=>'partnerships_overview','cmd'=>'for F in vistex huawei arrow consent; do cat /opt/wevads/state/partnerships/$F.json 2>/dev/null | python3 -c "import sys,json;d=json.load(sys.stdin);name=d.get(\"partner\",d.get(\"service\",\"?\"));st=d.get(\"status\",\"?\");print(f\"{name}: {st}\")" 2>/dev/null; done'];
}
// === END V48 ===
// === V53 AUTO-WIRE Cycle 4 Ops/Monitoring - 17avr 22:55 ===
// Gaps: arsenal_monitor, deliverability_stats, o365_stats, nginx_vhosts, redis_status
// Append-only apres END V48 (zero touch V37-V48)
// INTENT V53-1 arsenal_monitor - ecrans /var/www/html/*.html
if (preg_match('/arsenal.*monitor|arsenal.*screen|arsenal.*ecran|arsenal.*page|150.*screen|combien.*ecran/i', $msg)) {
$intents[] = ['id'=>'arsenal_monitor','cmd'=>'echo total_html=$(ls /var/www/html/*.html 2>/dev/null | wc -l) ; echo wevia_pages=$(ls /var/www/html/wevia*.html 2>/dev/null | wc -l) ; echo ethica_pages=$(ls /var/www/html/ethica*.html 2>/dev/null | wc -l) ; echo wevads_pages=$(ls /var/www/html/wevads*.html 2>/dev/null | wc -l) ; echo admin_pages=$(ls /var/www/html/admin*.html 2>/dev/null | wc -l)'];
}
// INTENT V53-2 deliverability_stats - taux inbox O365 PMTA
if (preg_match('/taux.*deliverability|deliverability.*rate|inbox.*rate|taux.*inbox|97.*pourcent|deliverability.*97/i', $msg)) {
$intents[] = ['id'=>'deliverability_stats','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT COUNT(*) FILTER (WHERE inbox_status=\"inbox\") as inbox, COUNT(*) FILTER (WHERE inbox_status=\"spam\") as spam, COUNT(*) as total FROM seed_inbox_checks WHERE created_at > NOW() - INTERVAL \"24 hours\";" 2>/dev/null || echo deliverability_table_tracking_needed'];
}
// INTENT V53-3 o365_stats
if (preg_match('/o365|office365|office.365|oauth.*o365|tenant.*o365|microsoft.*graph|graph.*api|288.*domain/i', $msg)) {
$intents[] = ['id'=>'o365_stats','cmd'=>'PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -t -A -F "|" -c "SELECT (SELECT COUNT(*) FROM o365_accounts) as total_accounts, (SELECT COUNT(*) FROM o365_accounts WHERE is_active=true) as active, (SELECT COUNT(DISTINCT tenant_id) FROM o365_accounts) as tenants;" 2>/dev/null || echo o365_tables_check_needed'];
}
// INTENT V53-4 nginx_vhosts
if (preg_match('/nginx.*vhost|vhost.*nginx|nginx.*config|nginx.*site|sites.*enabled|nginx.*list/i', $msg)) {
$intents[] = ['id'=>'nginx_vhosts','cmd'=>'ls /etc/nginx/sites-enabled/ 2>/dev/null | wc -l | xargs -I{} echo total_vhosts={}; ls /etc/nginx/sites-enabled/ 2>/dev/null | head -20'];
}
// INTENT V53-5 redis_status
if (preg_match('/redis.*status|redis.*cache|redis.*running|cache.*redis|redis.*check/i', $msg)) {
$intents[] = ['id'=>'redis_status','cmd'=>'systemctl is-active redis-server 2>/dev/null || systemctl is-active redis 2>/dev/null || echo redis_check_needed ; redis-cli ping 2>/dev/null || echo redis_cli_unavailable'];
}
// === END V53 ===
// === V56 Cycle 6 Opus joue Yacine multiagent - 17avr 23:20 ===
// Gaps: dormants_overview (wrong intent ports_full fire), multi-intent partnerships missing
// Append-only apres END V53
// INTENT V56-1 dormants_overview - list hubs/priority/archived from auto-intent API
if (preg_match('/hubs?.*dormant|dormant.*hub|hub.*importan|combien.*hub|audit.*hub|liste.*hub/iu', $msg)) {
$intents[] = ['id'=>'dormants_overview','cmd'=>'echo TOTAL_HUBS=$(ls /var/www/html/*hub*.html 2>/dev/null | grep -v pre-carto | wc -l) ; echo TOTAL_PRIORITY=$(python3 -c "import json;print(len(json.load(open(\"/opt/wevia-brain/priority-intents-nl.json\"))))" 2>/dev/null) ; echo TOTAL_ARCHIVED=$(ls /opt/weval-l99/wiki/_var_www_html_api_wevia-*-intent*.json 2>/dev/null | wc -l) ; echo === TOP 15 HUBS === ; ls /var/www/html/*hub*.html 2>/dev/null | grep -v pre-carto | head -15 | xargs -I{} basename {}'];
}
// INTENT V56-2 partnerships_full_detail - enrich partnerships_overview with deep state read
if (preg_match('/partenariat.*complet|partnership.*full|bilan.*partenariat|vistex.*huawei|huawei.*arrow|arrow.*scaleway|tous.*partenaire/iu', $msg)) {
$intents[] = ['id'=>'partnerships_full_detail','cmd'=>'for P in vistex huawei arrow consent; do F=/opt/wevads/state/partnerships/$P.json ; if [ -f "$F" ]; then echo === $P === ; python3 -c "import json;d=json.load(open(\"$F\"));print(f\"status={d.get(\\\"status\\\",\\\"?\\\")}\");contacts=d.get(\"contacts\",[]);[print(f\" contact: {c.get(\\\"name\\\")} {c.get(\\\"role\\\")} {c.get(\\\"email\\\")}\") for c in contacts[:3]];pending=d.get(\"pending\",[]);[print(f\" pending: {p}\") for p in pending[:3]]" 2>&1 ; fi; done'];
}
// === END V56 ===
// === V61 Tier1+RAG intents include (Opus 18avr) ===
@include_once __DIR__ . '/wevia-v61-intents-include.php';
// === END V61 ===
// === V62 WIRE Intents include (Opus 18avr) ===
@include_once __DIR__ . '/wevia-v62-intents-include.php';
include __DIR__ . '/wevia-v72-intents-include.php';
include __DIR__ . '/wevia-v73-intents-include.php';
include __DIR__ . '/wevia-v74-intents-include.php';
include __DIR__ . '/wevia-v75-intents-include.php';
// === END V62 ===
// EXECUTE detected intents
if (!empty($intents)) {
sse(['type'=>'executor','status'=>'start','intents'=>count($intents)]);
foreach ($intents as $intent) {
$out = trim(@shell_exec('timeout 20 bash -c ' . escapeshellarg($intent['cmd']) . ' 2>&1')) ?: 'EMPTY';
$exec_results[$intent['id']] = $out;
sse(['type'=>'exec_result','id'=>$intent['id'],'result'=>substr($out, 0, 2000)]);
}
sse(['type'=>'executor','status'=>'done','executed'=>count($exec_results)]);
}
// === END EXECUTOR ===
// === V38 UX-PRIORITY: promouvoir exec_result V37 en tete (Opus wire 17avr) ===
// Cause racine: user non-tech pose "phase 2 status" -> LLM synthesis dilue l'info.
// Fix: si un intent V37/phase2 a execute, envoyer un event SSE "phase2_priority"
// AVANT le llm_synthesis pour que l'UI l'affiche en premier.
$v37_intents_fired = array_intersect_key($exec_results, array_flip([
'track_s95_status', 'cf_dns_prompt', 'cf_dns_gated',
'cert_track_prompt', 'cert_track_gated',
'vhost_track_prompt', 'vhost_track_gated',
'track_s95_rollback_gated'
]));
if (!empty($v37_intents_fired)) {
foreach ($v37_intents_fired as $iid => $ires) {
// Parser le JSON du sidecar si applicable
$parsed = @json_decode($ires, true);
if ($parsed && is_array($parsed)) {
sse(['type'=>'phase2_priority','intent'=>$iid,'ux_guide'=>$parsed]);
} else {
sse(['type'=>'phase2_priority','intent'=>$iid,'raw'=>substr($ires, 0, 1500)]);
}
}
}
// === END V38 ===
// === LLM SYNTHESIS (enhanced with execution results) ===
$ctx = "AGENTS WEVIA:\n";
foreach($results as $id=>$r) $ctx .= "[$id] $r\n";
if (!empty($exec_results)) {
$ctx .= "\n=== RESULTATS EXECUTION ===\n";
foreach($exec_results as $id=>$r) $ctx .= "[$id] " . substr($r, 0, 800) . "\n";
}
$sp = $ctx . "\n---\nQUESTION: " . $msg . "\nINSTRUCTION: resume FACTUELLEMENT les resultats ci-dessus sans inventer. Liste OBSERVE (chiffres), PROBLEMES DETECTES (si TIMEOUT/DIRTY>0/port-conflit), AUCUNE correction n a ete appliquee sauf si un intent fix_* apparait. Francais concis.";
$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. REGLES STRICTES HONNETETE DOCTRINE #4: (1) Decris UNIQUEMENT les resultats bruts des agents/exec fournis en contexte. (2) N INVENTE RIEN. (3) Si un probleme est detecte (ex: port conflits, DIRTY>0, TIMEOUT), liste-le comme PROBLEME A CORRIGER, JAMAIS comme deja corrige. (4) Ne dis JAMAIS corrections appliquees / resolu / fixed sauf si un intent explicite de type fix a tourne. (5) Les commandes de lecture (ls, cat, count, check, grep) sont READ-ONLY, tu n as rien corrige. (6) Si resultat vide ou TIMEOUT, dis-le. Format: bullets courts, chiffres exacts, francais."],["role"=>"user","content"=>$sp]], "max_tokens" => 600, "stream" => false]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
$r2 = curl_exec($ch); curl_close($ch);
$d2 = @json_decode($r2, true);
$txt = $d2["choices"][0]["message"]["content"] ?? "Synthese indisponible.";
sse(["type"=>"llm_synthesis","text"=>$txt]);