Files
html/api/wevia-nl-autowire.php
2026-04-19 17:35:02 +02:00

180 lines
7.2 KiB
PHP

<?php
/**
* WEVIA NL Auto-Wirer · V126
* Cause racine fix : WEVIA Master ne sait QUE syntax structurée 'master add intent X :: Y :: Z'.
* Ce middleware parse demandes naturelles et auto-génère + auto-execute le wire.
*
* PATTERNS RECOGNIZED :
* "crée moi un intent qui affiche la date" → intent date_intent / triggers "date du jour" / cmd "echo $(date)"
* "ajoute un intent qui liste les dockers" → intent dockers_list / cmd "docker ps"
* "wire un skill qui check ssl" → run_skill ssl-check
* "intègre tool nuclei" → run_skill nuclei
* "crée intent X qui Y" → intent X / cmd Y (extraction directe)
*
* INPUT :
* POST /api/wevia-nl-autowire.php
* { "text": "crée moi un intent qui affiche la date du jour" }
*
* OUTPUT :
* { ok: true, action: "intent_created", intent_name: "date_jour_001",
* wire_command: "master add intent ...", wire_response: {...} }
*/
header('Content-Type: application/json; charset=utf-8');
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$text = trim($input['text'] ?? $_GET['text'] ?? '');
if (!$text) {
echo json_encode(['ok'=>false, 'error'=>'missing text', 'usage'=>'POST {text:"crée un intent qui affiche la date"}']);
exit;
}
// === PATTERN MATCHERS ===
$result = ['ts'=>date('c'), 'source'=>'wevia-nl-autowire', 'input_text'=>$text, 'parsed'=>[]];
// Lowercase for pattern detection
$t = strtolower($text);
// PATTERN 1: "crée/ajoute/wire un intent qui X"
$intent_keywords = ['crée', 'cree', 'créer', 'ajoute', 'ajouter', 'wire', 'créer', 'create'];
$intent_action_present = false;
foreach ($intent_keywords as $kw) {
if (preg_match('/\b' . preg_quote($kw, '/') . '\b/u', $t)) {
$intent_action_present = true;
break;
}
}
$is_intent_request = $intent_action_present && preg_match('/(intent|action|reponse|réponse)/u', $t);
$is_skill_request = $intent_action_present && preg_match('/skill/u', $t);
$is_api_request = $intent_action_present && preg_match('/(api|endpoint)/u', $t);
$is_tool_request = $intent_action_present && preg_match('/(tool|outil) (oss|open source|opensource)/u', $t);
if (!$is_intent_request && !$is_skill_request && !$is_api_request && !$is_tool_request) {
echo json_encode([
'ok' => false,
'error' => 'no_pattern_recognized',
'hint' => 'Use: "crée un intent qui X", "ajoute un skill qui X", "crée un endpoint API X", "intègre tool OSS X"',
'patterns_seen' => [
'intent_action' => $intent_action_present,
'is_intent' => $is_intent_request,
'is_skill' => $is_skill_request,
'is_api' => $is_api_request,
'is_tool' => $is_tool_request,
],
'input' => $text,
], JSON_PRETTY_PRINT);
exit;
}
// === EXTRACT 'qui X' clause (the action description) ===
$action_clause = '';
if (preg_match('/qui\s+(.+?)(?:[\.,;]|$)/u', $text, $m)) {
$action_clause = trim($m[1]);
}
if (!$action_clause) {
// Try "pour X" or "que X"
if (preg_match('/(?:pour|afin de|que)\s+(.+?)(?:[\.,;]|$)/u', $text, $m)) {
$action_clause = trim($m[1]);
}
}
if (!$action_clause) {
// Last resort: take everything after the first verb
$action_clause = $text;
}
$result['parsed']['action_clause'] = $action_clause;
// === MAP DESCRIPTION → SHELL COMMAND ===
function map_to_shell($action) {
$a = strtolower($action);
// Date / heure
if (preg_match('/(date|heure|temps|jour)/u', $a)) {
return ['cmd' => 'date "+%Y-%m-%d %H:%M:%S %Z"', 'category' => 'time'];
}
// Docker containers
if (preg_match('/docker(s)?/u', $a) && preg_match('/(liste|list|actif|running|status)/u', $a)) {
return ['cmd' => 'docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null | head -20', 'category' => 'docker'];
}
// Disk usage
if (preg_match('/(disk|disque|stockage|espace)/u', $a)) {
return ['cmd' => 'df -h / | tail -1', 'category' => 'system'];
}
// Memory
if (preg_match('/(memoire|mémoire|memory|ram)/u', $a)) {
return ['cmd' => 'free -h | head -2', 'category' => 'system'];
}
// Load
if (preg_match('/(load|charge|cpu)/u', $a)) {
return ['cmd' => 'uptime', 'category' => 'system'];
}
// SSL
if (preg_match('/(ssl|cert|certif)/u', $a)) {
return ['cmd' => 'echo SSL CHECK ; certbot certificates 2>/dev/null | grep -E "(Certificate|Expiry)" | head -10', 'category' => 'security'];
}
// DNS
if (preg_match('/(dns|domain|domaine)/u', $a)) {
return ['cmd' => 'dig +short weval-consulting.com', 'category' => 'network'];
}
// Nginx status
if (preg_match('/nginx/u', $a)) {
return ['cmd' => 'systemctl status nginx 2>/dev/null | head -5', 'category' => 'web'];
}
// Git status
if (preg_match('/(git|commit)/u', $a) && preg_match('/(status|etat|état|recent)/u', $a)) {
return ['cmd' => 'cd /var/www/html && git log --oneline -5', 'category' => 'git'];
}
// Pages count
if (preg_match('/(page|html)/u', $a) && preg_match('/(count|nombre|combien)/u', $a)) {
return ['cmd' => 'ls /var/www/html/*.html | wc -l', 'category' => 'inventory'];
}
// Default: echo the action
return ['cmd' => 'echo NEW INTENT for: ' . escapeshellarg($action), 'category' => 'generic'];
}
$shell = map_to_shell($action_clause);
$result['parsed']['shell_cmd'] = $shell['cmd'];
$result['parsed']['category'] = $shell['category'];
// === GENERATE INTENT NAME ===
$slug = preg_replace('/[^a-z0-9]+/', '_', strtolower($action_clause));
$slug = trim($slug, '_');
$slug = substr($slug, 0, 30);
if (!$slug) $slug = 'auto_' . substr(md5($text), 0, 6);
$intent_name = 'nl_' . $slug;
$result['parsed']['intent_name'] = $intent_name;
// === GENERATE TRIGGERS (from action keywords) ===
$keywords = preg_split('/\s+/', $action_clause);
$keywords = array_filter($keywords, fn($k) => strlen($k) > 3 && !in_array(strtolower($k), ['avec','dans','pour','quoi','comme','qu','est','les','des','une','que']));
$keywords = array_slice(array_unique($keywords), 0, 6);
$triggers = implode('|', $keywords);
if (!$triggers) $triggers = $intent_name;
$result['parsed']['triggers'] = $triggers;
// === BUILD master add intent COMMAND ===
$wire_message = 'master add intent ' . $intent_name . ' :: ' . $triggers . ' :: ' . $shell['cmd'];
$result['parsed']['wire_command'] = $wire_message;
// === EXECUTE via wevia-master-api ===
$payload = json_encode(['message' => $wire_message]);
$ch = curl_init('http://127.0.0.1/api/wevia-master-api.php');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 10,
]);
$wire_resp_raw = curl_exec($ch);
curl_close($ch);
$wire_resp = @json_decode($wire_resp_raw, true);
$result['ok'] = true;
$result['action'] = $is_intent_request ? 'intent_created' : ($is_skill_request ? 'skill_request' : ($is_api_request ? 'api_request' : 'tool_request'));
$result['intent_name'] = $wire_resp['intent'] ?? $intent_name;
$result['status'] = $wire_resp['status'] ?? 'UNKNOWN';
$result['wire_response'] = $wire_resp;
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);