Files
html/api/wevia-sovereign-heal-intent.php
2026-04-17 18:25:01 +02:00

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);