#!/usr/bin/env python3 """V103 - Add natural language multi-agent router BEFORE stub dispatcher Doctrine #14 ADDITIF PUR """ path = "/var/www/html/api/wevia-master-api.php" with open(path, "rb") as f: raw = f.read() if b"V103-NATURAL-MULTI-AGENT-ROUTER" in raw: print("ALREADY") exit(0) # Insertion point: BEFORE OPUS5-STUB-DISPATCHER marker = b'// === OPUS5-STUB-DISPATCHER-v1 (17avr) ===\n' if marker not in raw: print("MARKER NOT FOUND") exit(1) addition = b'''// === V103-NATURAL-MULTI-AGENT-ROUTER (20avr) === // Doctrine #14 ADDITIF: Natural language detection of multi-agent intent // MUST run BEFORE stub dispatcher to prevent stubs from catching multi-agent phrases // Triggers: orchestrate, status all, all status, parallel, simultan, bilan complet, // rapport multi-agent, tous les agents, full scan, exhaustif, cartograph, // multi.?agent, "agis en multi", "donne moi un bilan complet" if (isset($_mam) && $_mam) { $__v103_msg = mb_strtolower(trim($_mam)); // Natural language patterns - ALL trigger multi-agent SSE $__v103_patterns = [ // English/Franglais '/\\borchestrate\\b/i', '/\\b(status\\s+all|all\\s+status|full\\s+scan|all\\s+agents)\\b/i', '/\\b(parallel|simultan)/i', // French naturel '/\\b(bilan\\s+complet|rapport\\s+(multi|complet|exhaustif)|orchestre|orchestrate)\\b/i', '/\\b(tous\\s+les\\s+agents|toutes\\s+les\\s+(metriques|capacites)|cartograph)\\b/i', '/\\b(exhaustif|reconcile|6sigma|six\\s*sigma|tout\\s+finir)\\b/i', '/\\b(agir|agis|fais)\\s+(en\\s+)?(multi|plusieurs)/i', '/\\b(en\\s+)?multi[\\s\\-]?agents?\\b/i', // "donne moi un point complet", "fais le tour de", etc. '/\\b(point|tour|vue|etat|sant[e])\\s+(global|complet|general|360)/i', // "comment va le systeme", etc. '/\\b(comment|que)\\s+(vont?|va|tourne)\\s+(les|le)\\s+(systeme|infra|services)/i', ]; foreach ($__v103_patterns as $__v103_p) { if (preg_match($__v103_p, $__v103_msg)) { // Match! Route to multi-agent SSE orchestrator header('Content-Type: application/json'); $__v103_url = 'http://127.0.0.1/api/wevia-multiagent-sse.php?msg=' . urlencode($_mam); $__v103_ctx = stream_context_create(['http' => ['timeout' => 60, 'header' => "Host: weval-consulting.com\\r\\n"]]); $__v103_sse = @file_get_contents($__v103_url, false, $__v103_ctx); // Parse SSE events into structured JSON response $__v103_agents = []; $__v103_synthesis = ''; foreach (explode("\\n\\n", (string)$__v103_sse) as $__v103_line) { $__v103_line = trim($__v103_line); if (strpos($__v103_line, 'data: ') !== 0) continue; $__v103_d = @json_decode(substr($__v103_line, 6), true); if (!is_array($__v103_d)) continue; if (($__v103_d['type'] ?? '') === 'agent') { $__v103_agents[$__v103_d['id']] = $__v103_d['result']; } if (($__v103_d['type'] ?? '') === 'synthesis') { $__v103_synthesis = $__v103_d['content'] ?? ''; } } $__v103_resp = "Multi-agent orchestration executed (" . count($__v103_agents) . " agents)\\n\\n"; foreach ($__v103_agents as $__v103_id => $__v103_r) { $__v103_resp .= "[$__v103_id] " . substr((string)$__v103_r, 0, 200) . "\\n"; } if ($__v103_synthesis) $__v103_resp .= "\\n=== SYNTHESIS ===\\n" . $__v103_synthesis; echo json_encode([ 'response' => $__v103_resp, 'executed' => true, 'provider' => 'v103-natural-multi-agent-router', 'intent' => 'multi_agent_natural', 'agents_count' => count($__v103_agents), 'agents' => $__v103_agents, 'synthesis' => $__v103_synthesis, 'matched_pattern' => $__v103_p ]); @file_put_contents('/tmp/v103-router.log', date('c') . " MATCH pattern=$__v103_p msg=" . substr($_mam, 0, 80) . "\\n", FILE_APPEND); exit; } } } // === V103-NATURAL-MULTI-AGENT-ROUTER END === ''' raw = raw.replace(marker, addition + marker, 1) with open(path, "wb") as f: f.write(raw) print(f"PATCHED size={len(raw)}")