119 lines
4.3 KiB
PHP
119 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* Cloudbot Social SSE Live Feed - WAVE-278 / Doctrine 143
|
|
* Stream reel des conversations agents + activity + social signals
|
|
* Zero hardcode - tout depuis sources de verite live
|
|
*/
|
|
header('Content-Type: text/event-stream');
|
|
header('Cache-Control: no-cache, no-transform');
|
|
header('X-Accel-Buffering: no');
|
|
header('Connection: keep-alive');
|
|
header('Access-Control-Allow-Origin: *');
|
|
@ini_set('output_buffering', 'off');
|
|
@ini_set('zlib.output_compression', 0);
|
|
while (@ob_end_flush()) {}
|
|
|
|
set_time_limit(180);
|
|
$start = time();
|
|
$max_duration = 120; // 2 min max par session SSE
|
|
$poll = 3; // poll interval
|
|
$last_activity_ts = '';
|
|
$last_msg_id = 0;
|
|
$last_social_ts = '';
|
|
|
|
function send_event($type, $data) {
|
|
echo "event: $type\n";
|
|
echo "data: " . json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n\n";
|
|
@ob_flush();
|
|
@flush();
|
|
}
|
|
|
|
// Initial hello
|
|
send_event('hello', [
|
|
'ok' => 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']);
|