Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
Fix definitif issues gemini: - Clé Gemini source correct identifiée: /etc/weval/secrets.env (AIzaSyCMbYKyTldlCjg2eSCtwNONX9mMomhmIM4) - Clé vault credentials.php (AIzaSyBt...) était expiree - SYNC vers bonne clé - GOLD backup credentials.php.phase22-gemini-sync créé Nouveau handler rolling-hub-enrich.sh: - 7 hubs Yacine: paperclip-dashboard deerflow-hub ai-hub wevia-multiagent-dashboard brain-council wevia-meeting agents-hub - Strategy: Gemini primary + Cerebras qwen 235B fallback - Output JSON avec suggestions UX doctrine 60 (entrance staggered, hover glow, etc.) Intent wevia_rolling_hub_enrich_7hubs wired: - Triggers spécifiques pour éviter collision paperclip/deerflow - Test live OK avec brain-council via Cerebras BUG gemini_ux_design_agent identifié: lit GEMINI_API_KEY au lieu de GEMINI_KEY. BUG gemini_hub_enrich OK (lit bonne source) mais collision trigger. Solution: nouvel intent wevia_rolling_hub_enrich_7hubs plus spécifique. Alternative live: WEVIA prompt complet Yacine route via multi_agent_natural (50 agents) + synthesis.
305 lines
12 KiB
PHP
305 lines
12 KiB
PHP
<?php
|
|
// WEVIA autowire trigger endpoint - doctrine 147 + 148 (presets)
|
|
// Whitelist + generic preset dispatcher
|
|
header('Content-Type: application/json');
|
|
|
|
$whitelist = [
|
|
'wire-mr-paperclip' => '/opt/wevia-brain/scripts/wire-mr-paperclip.sh',
|
|
'wire-wtp-live-ops' => '/opt/wevia-brain/scripts/wire-wtp-live-ops.sh',
|
|
'wevia-playwright-test' => '/opt/wevia-brain/scripts/wevia-playwright-test.sh',
|
|
];
|
|
|
|
// Presets dir (doctrine 148)
|
|
$presets_dir = '/opt/wevia-brain/presets';
|
|
$preset_runner = '/opt/wevia-brain/scripts/apply-preset.sh';
|
|
|
|
$action = $_GET['action'] ?? $_POST['action'] ?? '';
|
|
$action = preg_replace('/[^a-z0-9\-]/i','',$action);
|
|
|
|
// LIST available (for introspection)
|
|
if ($action === 'list') {
|
|
$presets_available = [];
|
|
if (is_dir($presets_dir)) {
|
|
foreach (glob("$presets_dir/*.json") as $p) {
|
|
$presets_available[] = basename($p, '.json');
|
|
}
|
|
}
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'whitelist_actions' => array_keys($whitelist),
|
|
'presets_available' => $presets_available,
|
|
'presets_dir' => $presets_dir,
|
|
], JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
// APPLY PRESET (doctrine 148)
|
|
if ($action === 'apply-preset') {
|
|
$preset = $_GET['preset'] ?? $_POST['preset'] ?? '';
|
|
$preset = preg_replace('/[^a-z0-9\-]/i','',$preset);
|
|
if (!$preset) {
|
|
echo json_encode(['ok' => false, 'err' => 'preset_required']);
|
|
exit;
|
|
}
|
|
$preset_file = "$presets_dir/$preset.json";
|
|
if (!is_file($preset_file)) {
|
|
$available = array_map(fn($p) => basename($p, '.json'), glob("$presets_dir/*.json"));
|
|
echo json_encode(['ok' => false, 'err' => 'preset_not_found', 'preset' => $preset, 'available' => $available]);
|
|
exit;
|
|
}
|
|
$log_id = bin2hex(random_bytes(6));
|
|
$start = microtime(true);
|
|
$cmd = "timeout 30 sudo bash $preset_runner " . escapeshellarg($preset) . " 2>&1";
|
|
$output = @shell_exec($cmd);
|
|
$duration_ms = round((microtime(true) - $start) * 1000);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
// Parfois output contient des lignes debug puis JSON final
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
@file_put_contents('/tmp/wevia-autowire-trigger.log',
|
|
date('c') . " apply-preset=$preset log_id=$log_id duration={$duration_ms}ms ok=" . ($parsed['ok'] ?? '?') . "
|
|
", FILE_APPEND);
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'action' => 'apply-preset',
|
|
'preset' => $preset,
|
|
'log_id' => $log_id,
|
|
'duration_ms' => $duration_ms,
|
|
'raw_output' => trim((string)$output),
|
|
'result' => $parsed,
|
|
], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// ROLLBACK (doctrine 153)
|
|
if ($action === 'rollback') {
|
|
$marker = $_GET['marker'] ?? $_POST['marker'] ?? '';
|
|
$target = $_GET['target'] ?? $_POST['target'] ?? '';
|
|
$marker = preg_replace('/[^a-zA-Z0-9\-_]/','', $marker);
|
|
if ($target && !str_starts_with($target, '/var/www/html/')) {
|
|
echo json_encode(['ok'=>false,'err'=>'target_outside_whitelist']); exit;
|
|
}
|
|
if (!$marker && !$target) {
|
|
echo json_encode(['ok'=>false,'err'=>'marker_or_target_required']); exit;
|
|
}
|
|
$env = [];
|
|
if ($marker) $env[] = 'MARKER=' . escapeshellarg($marker);
|
|
if ($target) $env[] = 'TARGET=' . escapeshellarg($target);
|
|
$cmd = 'timeout 30 sudo env ' . implode(' ', $env) . ' bash /opt/wevia-brain/scripts/wevia-rollback.sh 2>&1';
|
|
$output = @shell_exec($cmd);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
echo json_encode(['ok'=>true,'action'=>'rollback','marker'=>$marker,'target'=>$target,'raw_output'=>trim((string)$output),'result'=>$parsed], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// LIST GOLD backups (doctrine 153)
|
|
if ($action === 'list-gold') {
|
|
$golds = [];
|
|
foreach (glob('/var/www/html/*.html.GOLD-*') as $g) {
|
|
$basename = basename($g);
|
|
if (preg_match('/^(.+?)\.html\.GOLD-([0-9\-]+)-pre-(.+)$/', $basename, $m)) {
|
|
$golds[] = [
|
|
'file' => $basename,
|
|
'page' => $m[1] . '.html',
|
|
'timestamp' => $m[2],
|
|
'marker_slug' => $m[3],
|
|
'size_bytes' => filesize($g),
|
|
];
|
|
}
|
|
}
|
|
usort($golds, fn($a,$b) => strcmp($b['timestamp'], $a['timestamp']));
|
|
echo json_encode(['ok'=>true,'count'=>count($golds),'golds'=>$golds], JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
// SCHEDULE (doctrine 156)
|
|
if ($action === 'schedule-list') {
|
|
$output = @shell_exec('SCHEDULE_ACTION=list bash /opt/wevia-brain/scripts/schedule-preset.sh 2>&1');
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
echo json_encode(['ok'=>true,'action'=>'schedule-list','result'=>$parsed,'raw'=>$output], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
if ($action === 'schedule-install') {
|
|
$preset = $_GET['preset'] ?? $_POST['preset'] ?? '';
|
|
$preset = preg_replace('/[^a-zA-Z0-9\-_]/','', $preset);
|
|
if (!$preset) { echo json_encode(['ok'=>false,'err'=>'preset required']); exit; }
|
|
$output = @shell_exec('SCHEDULE_ACTION=install PRESET=' . escapeshellarg($preset) . ' bash /opt/wevia-brain/scripts/schedule-preset.sh 2>&1');
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
echo json_encode(['ok'=>true,'action'=>'schedule-install','preset'=>$preset,'result'=>$parsed], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
if ($action === 'schedule-remove') {
|
|
$preset = $_GET['preset'] ?? $_POST['preset'] ?? '';
|
|
$preset = preg_replace('/[^a-zA-Z0-9\-_]/','', $preset);
|
|
if (!$preset) { echo json_encode(['ok'=>false,'err'=>'preset required']); exit; }
|
|
$output = @shell_exec('SCHEDULE_ACTION=remove PRESET=' . escapeshellarg($preset) . ' bash /opt/wevia-brain/scripts/schedule-preset.sh 2>&1');
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
echo json_encode(['ok'=>true,'action'=>'schedule-remove','preset'=>$preset,'result'=>$parsed], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// VERIFY-PATCHES (doctrine 159)
|
|
if ($action === 'verify-patches') {
|
|
$output = @shell_exec('timeout 30 bash /opt/wevia-brain/scripts/wevia-verify-patches.sh 2>&1');
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
echo json_encode(['ok'=>true,'action'=>'verify-patches','result'=>$parsed], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// CYBER PROBE (doctrine 160)
|
|
if ($action === 'cyber-probe') {
|
|
// Lance en background pour eviter timeout
|
|
@shell_exec('nohup bash /opt/wevia-brain/scripts/wevia-cyber-probe.sh > /tmp/cyber-probe.log 2>&1 &');
|
|
echo json_encode(['ok'=>true,'action'=>'cyber-probe','status'=>'started_background','hint'=>'check /proofs/wevia-cyber-probe-* in ~3 min','log'=>'/tmp/cyber-probe.log']);
|
|
exit;
|
|
}
|
|
if ($action === 'cyber-probe-latest') {
|
|
$dirs = glob('/var/www/html/proofs/wevia-cyber-probe-*');
|
|
usort($dirs, fn($a,$b) => filemtime($b)-filemtime($a));
|
|
if (!$dirs) { echo json_encode(['ok'=>false,'err'=>'no runs']); exit; }
|
|
$latest = $dirs[0];
|
|
$summary_path = $latest . '/probe-summary.json';
|
|
if (!file_exists($summary_path)) {
|
|
echo json_encode(['ok'=>true,'status'=>'in_progress','dir'=>basename($latest),'index'=>basename($latest).'/index.html']);
|
|
exit;
|
|
}
|
|
$s = json_decode(file_get_contents($summary_path), true);
|
|
echo json_encode(['ok'=>true,'status'=>'done','summary'=>$s,'index'=>'https://weval-consulting.com/proofs/'.basename($latest).'/index.html']);
|
|
exit;
|
|
}
|
|
|
|
// CHROME LAUNCH in Xvfb (doctrine 161)
|
|
if ($action === 'chrome-launch') {
|
|
$profile = $_GET['profile'] ?? $_POST['profile'] ?? '';
|
|
$profile = preg_replace('/[^a-zA-Z0-9_\-]/','', $profile);
|
|
if (!$profile) { echo json_encode(['ok'=>false,'err'=>'profile required']); exit; }
|
|
$output = @shell_exec('bash /opt/wevia-brain/scripts/chrome-profile-launch.sh ' . escapeshellarg($profile) . ' 2>&1');
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
echo json_encode(['ok'=>true,'action'=>'chrome-launch','profile'=>$profile,'result'=>$parsed,'raw'=>trim((string)$output)], JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
// SEND-PROMPT web-IA (doctrine 163) - async
|
|
if ($action === 'send-prompt') {
|
|
$provider = $_GET['provider'] ?? $_POST['provider'] ?? '';
|
|
$prompt = $_GET['prompt'] ?? $_POST['prompt'] ?? '';
|
|
$provider = preg_replace('/[^a-zA-Z0-9_\-]/','', $provider);
|
|
if (!$provider || !$prompt) {
|
|
echo json_encode(['ok'=>false,'err'=>'provider and prompt required']);
|
|
exit;
|
|
}
|
|
$run_id = date('Ymd-His');
|
|
$cmd = sprintf(
|
|
'nohup sudo -u www-data python3 /opt/wevia-brain/selenium/send-prompt.py %s %s > /tmp/wevia-prompt-%s.log 2>&1 &',
|
|
escapeshellarg($provider),
|
|
escapeshellarg($prompt),
|
|
$run_id
|
|
);
|
|
@shell_exec($cmd);
|
|
echo json_encode([
|
|
'ok'=>true,
|
|
'action'=>'send-prompt',
|
|
'provider'=>$provider,
|
|
'prompt_len'=>strlen($prompt),
|
|
'status'=>'started_background',
|
|
'run_id'=>$run_id,
|
|
'hint'=>'check /api/wevia-autowire-trigger.php?action=send-prompt-latest&provider=' . $provider
|
|
]);
|
|
exit;
|
|
}
|
|
if ($action === 'send-prompt-latest') {
|
|
$provider = $_GET['provider'] ?? '';
|
|
$provider = preg_replace('/[^a-zA-Z0-9_\-]/','', $provider);
|
|
$pattern = $provider
|
|
? '/var/www/html/proofs/wevia-prompt-' . $provider . '-*'
|
|
: '/var/www/html/proofs/wevia-prompt-*';
|
|
$dirs = glob($pattern);
|
|
usort($dirs, fn($a,$b) => filemtime($b)-filemtime($a));
|
|
if (!$dirs) { echo json_encode(['ok'=>false,'err'=>'no runs']); exit; }
|
|
$latest = $dirs[0];
|
|
$res_path = $latest . '/result.json';
|
|
if (!file_exists($res_path)) {
|
|
echo json_encode(['ok'=>true,'status'=>'in_progress','dir'=>basename($latest)]);
|
|
exit;
|
|
}
|
|
$r = json_decode(file_get_contents($res_path), true);
|
|
echo json_encode(['ok'=>true,'status'=>'done','result'=>$r]);
|
|
exit;
|
|
}
|
|
|
|
// UX AUDIT Playwright (doctrine 167)
|
|
if ($action === 'ux-audit') {
|
|
@shell_exec('cd /opt/weval-nonreg && nohup node playwright-ux-audit.js > /tmp/ux-audit.log 2>&1 &');
|
|
echo json_encode(['ok'=>true,'action'=>'ux-audit','status'=>'started_background','hint'=>'check /proofs/wevia-ux-audit-* in ~90s']);
|
|
exit;
|
|
}
|
|
if ($action === 'ux-audit-latest') {
|
|
$dirs = glob('/var/www/html/proofs/wevia-ux-audit-*');
|
|
usort($dirs, fn($a,$b) => filemtime($b)-filemtime($a));
|
|
if (!$dirs) { echo json_encode(['ok'=>false,'err'=>'no runs']); exit; }
|
|
$latest = $dirs[0];
|
|
$sum = $latest . '/summary.json';
|
|
if (!file_exists($sum)) { echo json_encode(['ok'=>true,'status'=>'in_progress','dir'=>basename($latest)]); exit; }
|
|
$d = json_decode(file_get_contents($sum), true);
|
|
echo json_encode(['ok'=>true,'status'=>'done','summary'=>$d,'index'=>'https://weval-consulting.com/proofs/'.basename($latest).'/index.html']);
|
|
exit;
|
|
}
|
|
|
|
// Classic whitelist action
|
|
if (!$action || !isset($whitelist[$action])) {
|
|
echo json_encode([
|
|
'ok' => false,
|
|
'err' => 'unknown_action',
|
|
'available_actions' => array_keys($whitelist),
|
|
'presets_endpoint' => '?action=list',
|
|
'hint' => 'GET ?action=<action> OR ?action=apply-preset&preset=<preset>'
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$script = $whitelist[$action];
|
|
if (!is_file($script) || !is_executable($script)) {
|
|
echo json_encode(['ok'=>false,'err'=>'script_not_executable','path'=>$script]);
|
|
exit;
|
|
}
|
|
|
|
$log_id = bin2hex(random_bytes(6));
|
|
$start = microtime(true);
|
|
$output = @shell_exec("timeout 150 sudo bash $script 2>&1");
|
|
$duration_ms = round((microtime(true) - $start) * 1000);
|
|
$parsed = json_decode(trim((string)$output), true);
|
|
if (!is_array($parsed)) {
|
|
$lines = explode("
|
|
", trim((string)$output));
|
|
foreach (array_reverse($lines) as $l) {
|
|
$p = json_decode(trim($l), true);
|
|
if (is_array($p)) { $parsed = $p; break; }
|
|
}
|
|
}
|
|
@file_put_contents('/tmp/wevia-autowire-trigger.log',
|
|
date('c') . " action=$action log_id=$log_id duration={$duration_ms}ms ok=" . ($parsed['ok'] ?? '?') . "
|
|
", FILE_APPEND);
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'action' => $action,
|
|
'script' => $script,
|
|
'log_id' => $log_id,
|
|
'duration_ms' => $duration_ms,
|
|
'raw_output' => trim((string)$output),
|
|
'result' => $parsed,
|
|
], JSON_UNESCAPED_SLASHES);
|