From 51c4a54ec116334cf0cbe12c71d3bb8ec3b4e9d0 Mon Sep 17 00:00:00 2001 From: opus Date: Sun, 19 Apr 2026 16:25:01 +0200 Subject: [PATCH] auto-sync-1625 --- api/opus5-plan-from-text.php | 156 ++++++++++++++++++ .../doctrine88-20260419T162451/results.json | 1 + api/v83-business-kpi-latest.json | 2 +- wiki/plan-action.md | 23 +++ 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 api/opus5-plan-from-text.php create mode 100644 api/playwright-results/doctrine88-loader-activation/doctrine88-20260419T162451/results.json diff --git a/api/opus5-plan-from-text.php b/api/opus5-plan-from-text.php new file mode 100644 index 000000000..a03a7f635 --- /dev/null +++ b/api/opus5-plan-from-text.php @@ -0,0 +1,156 @@ +date('c'), 'source'=>'opus5-plan-from-text']; + +$raw = file_get_contents('php://input'); +$d = json_decode($raw, true) ?: []; +$text = (string)($d['text'] ?? $d['description'] ?? ''); +$auto_create = !empty($d['auto_create']); +$auto_execute = !empty($d['auto_execute']); + +if (!$text) { http_response_code(400); echo json_encode(['err'=>'no_text']); exit; } + +// === STEP 1 : Tokenization + normalisation === +$text_clean = trim(preg_replace('/\s+/', ' ', $text)); +$R['input_text'] = $text_clean; + +// Split sur connecteurs séquentiels (puis, ensuite, après, et, ",") +// Garder "en parallèle" comme signal pour depends_on vide +$parallel_mode = preg_match('/parall[eè]le|simultan[eé]/iu', $text_clean) > 0; + +// Découpage phrases +$chunks = preg_split('/\s+(?:puis|ensuite|apr[eè]s|après|then|,)\s+/iu', $text_clean); +$chunks = array_values(array_filter(array_map('trim', $chunks), function($c) { return strlen($c) > 3; })); + +$R['chunks'] = $chunks; +$R['chunks_count'] = count($chunks); +$R['parallel_mode'] = $parallel_mode; + +// === STEP 2 : NER endpoints + actions === +// Catalogue de patterns mappant NL → endpoints sûrs (whitelist-only) +$action_catalog = [ + // Regex → [name, url, method, payload] + '/\b(non[\s-]?reg|nonreg|regression)\b/iu' => ['check_nonreg', '/api/nonreg-api.php?cat=all', 'GET', null], + '/\b(l99|layers)\b/iu' => ['check_l99', '/api/l99-state.json', 'GET', null], + '/\b(cache[\s-]?stat|predictive[\s-]?cache|cache)\b/iu' => ['check_cache', '/api/opus5-predictive-cache.php?action=stats', 'GET', null], + '/\b(task[\s-]?list|task[\s-]?stream)\b/iu' => ['list_tasks', '/api/opus5-task-stream.php?path=list&limit=10', 'GET', null], + '/\b(plan[\s-]?list|list[\s-]?plans|plans)\b/iu' => ['list_plans', '/api/opus5-plan-registry.php?action=list&limit=10', 'GET', null], + '/\b(ethica[\s-]?stat|hcps|ethica)\b/iu' => ['check_ethica', '/api/ethica-stats-api.php', 'GET', null], + '/\b(gpu[\s-]?grid|grid[\s-]?gpu|parallel)\b/iu' => ['check_gpu_grid', '/api/opus5-gpu-grid.php?action=health', 'GET', null], + '/\b(ssh[\s-]?tmux|tmux|s95[\s-]?health)\b/iu' => ['check_ssh_tmux', '/api/opus5-ssh-tmux-stream.php?action=health', 'GET', null], + '/\b(plugin[\s-]?store|plugin[\s-]?list|plugins)\b/iu' => ['list_plugins', '/api/opus5-plugin-store.php?action=list', 'GET', null], + '/\b(knowledge[\s-]?graph|kg[\s-]?stat|graph[\s-]?stat)\b/iu' => ['check_kg', '/api/opus5-knowledge-graph.php?action=stats', 'GET', null], + '/\b(orchestrator[\s-]?v3|orch[\s-]?v3|meta[\s-]?orch)\b/iu' => ['ping_orch_v3', '/api/opus5-autonomous-orchestrator-v3.php', 'POST', ['message'=>'ping','session'=>'plan-gen']], + '/\b(n8n|workflow[\s-]?list)\b/iu' => ['list_n8n_workflows', '/api/opus5-n8n-generator.php?action=list', 'GET', null], + '/\b(truth[\s-]?registry|truth[\s-]?table)\b/iu' => ['check_truth', '/api/wevia-truth-registry.json', 'GET', null], +]; + +$steps = []; +foreach ($chunks as $idx => $chunk) { + $chunk_lower = strtolower($chunk); + $matched = false; + foreach ($action_catalog as $pattern => $action) { + if (preg_match($pattern, $chunk_lower)) { + $step_def = [ + 'name' => $action[0] . '_' . ($idx + 1), + 'type' => 'http_check', + 'url' => $action[1], + 'method' => $action[2], + ]; + if ($action[3] !== null) { + $step_def['payload'] = $action[3]; + } + // Dependencies : séquentiel par défaut, sauf si parallel_mode + if (!$parallel_mode && $idx > 0) { + $step_def['depends_on'] = [$idx]; // step_order précédent + } + // Metadata : source chunk + $step_def['_source_chunk'] = $chunk; + $step_def['_matched_pattern'] = $pattern; + $steps[] = $step_def; + $matched = true; + break; + } + } + if (!$matched) { + $R['unmatched_chunks'][] = $chunk; + } +} + +$R['steps_generated'] = count($steps); +$R['steps'] = $steps; + +if (count($steps) === 0) { + $R['err'] = 'no_actions_recognized'; + $R['hint'] = 'Reformule avec mots-cles: nonreg, cache, plans, hcps, tmux, grid, plugin, graph, workflow, etc.'; + echo json_encode($R, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + exit; +} + +// === STEP 3 : Auto-create dans registry si demandé === +if ($auto_create) { + $plan_name = substr("AutoPlan — " . $text_clean, 0, 255); + $create_payload = [ + 'name' => $plan_name, + 'description' => $text_clean, + 'priority' => 0, + 'metadata' => [ + 'generated_by' => 'opus5-plan-from-text', + 'source_text' => $text_clean, + 'parallel_mode' => $parallel_mode + ], + 'steps' => $steps + ]; + + $ch = curl_init('http://127.0.0.1/api/opus5-plan-registry.php?action=create'); + curl_setopt_array($ch, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => json_encode($create_payload), + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 10 + ]); + $create_resp = curl_exec($ch); + $create_http = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + $created = @json_decode((string)$create_resp, true); + + $R['created'] = [ + 'http' => $create_http, + 'plan_id' => $created['plan_id'] ?? null, + 'steps_created' => $created['steps_created'] ?? 0 + ]; + $pid = $created['plan_id'] ?? null; + + // === STEP 4 : Auto-execute si demandé === + if ($auto_execute && $pid) { + $exec_payload = ['plan_id' => $pid, 'dry_run' => false, 'max_parallel' => 5]; + $ch = curl_init('http://127.0.0.1/api/opus5-plan-orchestrator.php?action=execute'); + curl_setopt_array($ch, [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => json_encode($exec_payload), + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 60 + ]); + $exec_resp = curl_exec($ch); + $exec_http = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + $executed = @json_decode((string)$exec_resp, true); + + $R['executed'] = [ + 'http' => $exec_http, + 'rounds' => $executed['rounds'] ?? null, + 'done' => $executed['done_count'] ?? 0, + 'failed' => $executed['failed_count'] ?? 0, + 'final_status' => $executed['final_status'] ?? null + ]; + } +} + +$R['doctrine'] = '89 — plan from text NL parser (patterns → steps with depends_on auto)'; +echo json_encode($R, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); diff --git a/api/playwright-results/doctrine88-loader-activation/doctrine88-20260419T162451/results.json b/api/playwright-results/doctrine88-loader-activation/doctrine88-20260419T162451/results.json new file mode 100644 index 000000000..76e742378 --- /dev/null +++ b/api/playwright-results/doctrine88-loader-activation/doctrine88-20260419T162451/results.json @@ -0,0 +1 @@ +{"tips_catalog":{"status":"PASS","engine":"PendingLoader\/tips_catalog","intent":"pending_tips_catalog","ms":242,"answers":1},"tips_opus":{"status":"PASS","engine":"PendingLoader\/tips_opus","intent":"pending_tips_opus","ms":300,"answers":1},"tips_selenium":{"status":"PASS","engine":"PendingLoader\/tips_selenium","intent":"pending_tips_selenium","ms":254,"answers":1},"tips_token":{"status":"PASS","engine":"PendingLoader\/tips_token_renewal","intent":"pending_tips_token_renewal","ms":231,"answers":1},"mythos":{"status":"PASS","engine":"PendingLoader\/tip_opus46_mythos","intent":"pending_tip_opus46_mythos","ms":131,"answers":1},"thuggie":{"status":"PASS","engine":"PendingLoader\/selenium_thuggie_web","intent":"pending_selenium_thuggie_web","ms":133,"answers":1},"meteo_fix6c":{"status":"PASS","engine":"Opus\/opus-intents","intent":"llm","ms":1011,"answers":1},"bonjour_fastpath":{"status":"PASS","engine":"FastPath\/fast-path","intent":"fast_path","ms":125,"answers":1},"file_write_fix7":{"status":"PASS","engine":"FileWrite\/autonomous","intent":"file_write","ms":122,"answers":1},"multiagent":{"status":"PASS","engine":"Orchestrator\/plan","intent":"multi_agent","ms":582,"answers":7}} diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index 26b72696b..df2645185 100644 --- a/api/v83-business-kpi-latest.json +++ b/api/v83-business-kpi-latest.json @@ -1,7 +1,7 @@ { "ok": true, "version": "V83-business-kpi", - "ts": "2026-04-19T14:23:45+00:00", + "ts": "2026-04-19T14:24:50+00:00", "summary": { "total_categories": 7, "total_kpis": 56, diff --git a/wiki/plan-action.md b/wiki/plan-action.md index cda117038..53b1841a2 100644 --- a/wiki/plan-action.md +++ b/wiki/plan-action.md @@ -1557,3 +1557,26 @@ Tags LIVE : infra, sovereign, nonreg, git, vault, docker, crons, paperclip, deer - Aucune page écrasée - Autres Opus concurrent préservés (V76 SSE extension, doctrine 88 pending loader) + +## 2026-04-19T14:24:43Z · 🎯 WTP SYNC TRUTH REGISTRY + +### Avant +- WTP dashboard affichait 950 agents hardcoded +- weval-technology-platform-api.php line 1270: `$kpis[agents_total] = 950;` +- Gauge vm-gauge-agents: 950 + +### Après (ZERO régression) +- WTP API fetch /api/wevia-truth-registry.json au runtime +- 906 agents (truth-registry · 9 sources dédupliquées) +- Additional KPIs injectés: intents 344, brains 25, doctrines 19, dashboards 94, providers 15, autonomy 100 GODMODE +- Gauge vm-gauge-agents: 906 validated via Playwright + +### Dashboards impactés (auto-sync via WTP API) +- weval-technology-platform.html ✅ +- erp-launchpad.html ✅ (même API) + +### Anti-régression +- GOLD backup: /opt/wevads/vault/WTP-API.php.GOLD-20260419-162300-pre-truth-sync +- PHP lint OK · Redis cache cleared +- Additive code uniquement · fallback 950 préservé si registry absent +