true, 'ts' => date('c'), 'streams' => ['router-activity', 'social-signals', 'wevia-conversations', 'ecosystem-health'], 'interval_s' => $poll ]); while (time() - $start < $max_duration) { // 1. ROUTER ACTIVITY (intents matches live) - source: /tmp/v103-router.log $log = '/tmp/v103-router.log'; if (file_exists($log)) { $lines = @file($log, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; $recent = array_slice($lines, -10); foreach ($recent as $line) { if (preg_match('/^(\S+)\s+MATCH\s+pattern=(\S+)\s+msg=(.*)$/', $line, $m)) { if ($m[1] > $last_activity_ts) { send_event('router_match', [ 'ts' => $m[1], 'pattern' => substr($m[2], 0, 60), 'msg' => substr($m[3], 0, 180), 'agent' => 'V103-Router', 'type' => 'intent_routing' ]); $last_activity_ts = $m[1]; } } } } // 2. WEVIA MESSAGES (real conversations) - public.messages try { $pdo = new PDO( "pgsql:host=10.1.0.3;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_TIMEOUT => 3] ); $stmt = $pdo->prepare("SELECT m.id, m.role, m.content, m.created_at, c.session_id, c.source FROM public.messages m LEFT JOIN public.conversations c ON c.id = m.conversation_id WHERE m.id > :last ORDER BY m.id ASC LIMIT 5"); $stmt->execute([':last' => $last_msg_id]); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { send_event('agent_msg', [ 'id' => (int)$row['id'], 'ts' => $row['created_at'], 'role' => $row['role'], 'content' => mb_substr($row['content'] ?? '', 0, 200), 'session' => substr($row['session_id'] ?? '', 0, 20), 'source' => $row['source'] ?? 'unknown', 'agent' => $row['role'] === 'assistant' ? 'WEVIA' : 'User', 'type' => 'conversation' ]); $last_msg_id = (int)$row['id']; } } catch (Exception $e) { // silent fail - DB peut etre down temporairement } // 3. ECOSYSTEM HEALTH ping (agents status live) static $last_health_tick = 0; if (time() - $last_health_tick > 15) { $ctx = stream_context_create(['http' => ['timeout' => 2]]); $h = @file_get_contents('http://127.0.0.1/api/ecosystem-health.php', false, $ctx); if ($h) { $j = @json_decode($h, true); if ($j) { send_event('ecosystem_health', [ 'ts' => date('c'), 'agents_up' => $j['agents_up'] ?? null, 'agents_total' => $j['agents_total'] ?? null, 'score' => $j['score'] ?? $j['health_score'] ?? null, 'type' => 'health_tick' ]); } } $last_health_tick = time(); } // 4. Heartbeat send_event('ping', ['ts' => date('c'), 'uptime_s' => time() - $start]); sleep($poll); } send_event('bye', ['ts' => date('c'), 'reason' => 'max_duration']);