98 lines
4.6 KiB
PHP
98 lines
4.6 KiB
PHP
<?php
|
|
// Intent sovereign_heal - WEVIA self-heal sovereign-api + other services
|
|
// Doctrine 74 compliant: Yacine chat "sovereign heal" → WEVIA restart service via sentinel/systemctl
|
|
// Zero manuel, zero intervention Opus
|
|
|
|
if (!function_exists('wevia_sovereign_heal')) {
|
|
function wevia_sovereign_heal($msg) {
|
|
if (!$msg) return false;
|
|
if (!preg_match('/\b(sovereign\s*heal|heal\s*sovereign|restart\s*sovereign|fix\s*sovereign|sovereign\s*(down|timeout|hang)|self[\s-]?heal|heal\s*services?)\b/i', $msg)) return false;
|
|
|
|
$out = ['intent' => 'sovereign_heal', 'tool' => 'service_self_heal'];
|
|
|
|
// Diagnostic check each critical service
|
|
$checks = [
|
|
'sovereign-api' => ['url' => 'http://127.0.0.1:4000/health', 'systemd' => 'sovereign-api.service'],
|
|
'nginx' => ['cmd_check' => 'systemctl is-active nginx', 'systemd' => 'nginx'],
|
|
'php-fpm' => ['cmd_check' => 'systemctl is-active php8.5-fpm', 'systemd' => 'php8.5-fpm'],
|
|
'deerflow' => ['url' => 'http://127.0.0.1:8001/health', 'systemd' => 'deerflow-gw'],
|
|
'ollama' => ['url' => 'http://127.0.0.1:11434/api/tags', 'systemd' => null],
|
|
];
|
|
|
|
$before = [];
|
|
$after = [];
|
|
$actions = [];
|
|
|
|
foreach ($checks as $name => $cfg) {
|
|
// Check health
|
|
if (isset($cfg['url'])) {
|
|
$ch = curl_init($cfg['url']);
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 4]);
|
|
$r = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
$healthy = ($code == 200 && strlen($r) > 10);
|
|
} else {
|
|
exec($cfg['cmd_check'] . ' 2>/dev/null', $cmd_out, $rc);
|
|
$healthy = ($rc === 0 && !empty($cmd_out) && trim($cmd_out[0]) === 'active');
|
|
}
|
|
|
|
$before[$name] = $healthy ? 'healthy' : 'unhealthy';
|
|
|
|
// If unhealthy and systemd available, restart via sudo systemctl
|
|
if (!$healthy && !empty($cfg['systemd'])) {
|
|
exec("sudo -n systemctl restart " . escapeshellarg($cfg['systemd']) . " 2>&1", $restart_out, $rc_restart);
|
|
$actions[] = [
|
|
'service' => $name,
|
|
'action' => 'systemctl restart ' . $cfg['systemd'],
|
|
'exit_code' => $rc_restart,
|
|
'output' => implode("\n", array_slice($restart_out, 0, 3)),
|
|
];
|
|
|
|
// Wait 3s then re-check
|
|
sleep(3);
|
|
if (isset($cfg['url'])) {
|
|
$ch2 = curl_init($cfg['url']);
|
|
curl_setopt_array($ch2, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5]);
|
|
$r2 = curl_exec($ch2);
|
|
$code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
|
|
curl_close($ch2);
|
|
$after[$name] = ($code2 == 200 && strlen($r2) > 10) ? 'healed' : 'still_unhealthy';
|
|
} else {
|
|
exec($cfg['cmd_check'] . ' 2>/dev/null', $c2o, $rc2);
|
|
$after[$name] = ($rc2 === 0 && trim($c2o[0] ?? '') === 'active') ? 'healed' : 'still_unhealthy';
|
|
}
|
|
} else {
|
|
$after[$name] = $healthy ? 'healthy' : 'no_restart_possible';
|
|
}
|
|
}
|
|
|
|
$healed_count = count(array_filter($after, fn($v) => $v === 'healed'));
|
|
$still_ko = count(array_filter($after, fn($v) => in_array($v, ['still_unhealthy','unhealthy','no_restart_possible'])));
|
|
|
|
$out['before'] = $before;
|
|
$out['after'] = $after;
|
|
$out['actions_performed'] = $actions;
|
|
$out['summary'] = [
|
|
'services_checked' => count($checks),
|
|
'healed_this_run' => $healed_count,
|
|
'still_unhealthy' => $still_ko,
|
|
'overall_status' => $still_ko === 0 ? 'ALL_HEALTHY' : 'PARTIAL_HEAL',
|
|
];
|
|
$out['doctrine'] = 'Doctrine 74 compliant: WEVIA self-heal via systemctl (no Opus intervention, no Yacine manuel)';
|
|
|
|
header("Content-Type: application/json");
|
|
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$_sh_msg = '';
|
|
$_body = @file_get_contents('php://input');
|
|
if ($_body) {
|
|
$_j = @json_decode($_body, true);
|
|
if (is_array($_j) && !empty($_j['message'])) $_sh_msg = $_j['message'];
|
|
}
|
|
if (!$_sh_msg) $_sh_msg = $_POST['message'] ?? $_GET['message'] ?? '';
|
|
if ($_sh_msg) wevia_sovereign_heal($_sh_msg);
|