feat(cloudbot-social): DOCTRINE 143 feed vivant SSE streaming reel + inter-agent conversations via /api/cloudbot-social-feed.php et /api/cloudbot-interagent.php - agents se parlent vraiment (log PG) - badge LIVE anime - zero ecrasement reconcilie v2 autre Claude
This commit is contained in:
@@ -194,6 +194,11 @@ main{max-width:1500px;margin:0 auto;padding:0 24px 40px;display:grid;grid-templa
|
||||
|
||||
/* Badge categories */
|
||||
.cat-emoji{font-size:14px;line-height:1}
|
||||
|
||||
/* DOCTRINE 143 SSE badge */
|
||||
#sse-live-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:9px;font-weight:700;letter-spacing:.5px;color:#fff;background:#64748b;vertical-align:middle;margin-left:8px}
|
||||
@keyframes flash{0%{opacity:1}50%{opacity:.3}100%{opacity:1}}
|
||||
#sse-health-pulse{font-size:10px;color:var(--a2);font-weight:600}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -689,6 +694,160 @@ document.addEventListener("keydown",function(e){
|
||||
if(e.key==="/"&&document.activeElement.tagName!=="INPUT"){ e.preventDefault(); document.getElementById("q").focus(); }
|
||||
if(e.key==="Escape"&&document.getElementById("chat-modal").classList.contains("on")){ closeModal(); }
|
||||
});
|
||||
|
||||
// ============ DOCTRINE 143 LIVE SSE STREAMING v1 (additif) ============
|
||||
var __SSE_ES = null;
|
||||
var __SSE_CONN = false;
|
||||
var __SSE_EVENTS = [];
|
||||
|
||||
function connectSSELive(){
|
||||
if(__SSE_ES && __SSE_CONN)return;
|
||||
try{
|
||||
__SSE_ES = new EventSource("/api/cloudbot-social-feed.php");
|
||||
|
||||
__SSE_ES.addEventListener("hello", function(e){
|
||||
__SSE_CONN = true;
|
||||
try{
|
||||
var d = JSON.parse(e.data);
|
||||
console.log("[SSE Cloudbot] Connected", d);
|
||||
var badge = document.getElementById("sse-live-badge");
|
||||
if(badge){ badge.textContent = "LIVE"; badge.style.background = "#10b981"; badge.style.animation = "pulse 1.5s infinite"; }
|
||||
}catch(ex){}
|
||||
});
|
||||
|
||||
__SSE_ES.addEventListener("router_match", function(e){
|
||||
try{
|
||||
var d = JSON.parse(e.data);
|
||||
pushSSEEvent({type:"router", msg:d.msg, ts:d.ts, pattern:d.pattern, agent:d.agent||"Router"});
|
||||
}catch(ex){}
|
||||
});
|
||||
|
||||
__SSE_ES.addEventListener("agent_msg", function(e){
|
||||
try{
|
||||
var d = JSON.parse(e.data);
|
||||
pushSSEEvent({type:"conversation", role:d.role, msg:d.content, ts:d.ts, session:d.session, source:d.source, agent:d.agent});
|
||||
}catch(ex){}
|
||||
});
|
||||
|
||||
__SSE_ES.addEventListener("ecosystem_health", function(e){
|
||||
try{
|
||||
var d = JSON.parse(e.data);
|
||||
var h = document.getElementById("sse-health-pulse");
|
||||
if(h){ h.textContent = (d.agents_up||"-") + "/" + (d.agents_total||"-") + " agents"; h.style.animation = "flash 0.5s"; setTimeout(function(){h.style.animation=""},500);}
|
||||
}catch(ex){}
|
||||
});
|
||||
|
||||
__SSE_ES.addEventListener("ping", function(e){ /* keep alive */ });
|
||||
|
||||
__SSE_ES.addEventListener("bye", function(e){
|
||||
__SSE_CONN = false;
|
||||
if(__SSE_ES){ __SSE_ES.close(); __SSE_ES = null; }
|
||||
setTimeout(connectSSELive, 2000); // auto reconnect
|
||||
});
|
||||
|
||||
__SSE_ES.onerror = function(){
|
||||
__SSE_CONN = false;
|
||||
var badge = document.getElementById("sse-live-badge");
|
||||
if(badge){ badge.textContent = "RECONNECT..."; badge.style.background = "#f59e0b"; }
|
||||
setTimeout(function(){
|
||||
if(__SSE_ES){ __SSE_ES.close(); __SSE_ES = null; }
|
||||
connectSSELive();
|
||||
}, 3000);
|
||||
};
|
||||
}catch(e){ console.warn("SSE init failed:", e); }
|
||||
}
|
||||
|
||||
function pushSSEEvent(ev){
|
||||
__SSE_EVENTS.unshift(ev);
|
||||
if(__SSE_EVENTS.length > 50) __SSE_EVENTS = __SSE_EVENTS.slice(0, 50);
|
||||
renderSSEFeed();
|
||||
}
|
||||
|
||||
function renderSSEFeed(){
|
||||
var feed = document.getElementById("live-feed");
|
||||
if(!feed)return;
|
||||
if(!__SSE_EVENTS.length){ return; }
|
||||
var html = __SSE_EVENTS.slice(0, 12).map(function(ev){
|
||||
var ago = timeAgo(ev.ts);
|
||||
var icon = ev.type === "conversation" ? (ev.role === "user" ? "👤" : "🤖") : (ev.type === "router" ? "🎯" : "⚡");
|
||||
var color = ev.type === "conversation" ? "#06d6ba" : (ev.type === "router" ? "#8b5cf6" : "#3b82f6");
|
||||
var label = ev.agent || (ev.role === "user" ? "User" : "WEVIA");
|
||||
var msg = (ev.msg||"").substring(0, 120);
|
||||
var meta = ev.session ? "session " + ev.session : (ev.source ? "src:"+ev.source : (ev.pattern||"live"));
|
||||
return '<div class="live-item" style="border-left-color:'+color+'">'+
|
||||
'<div class="live-item-head">'+
|
||||
'<div class="live-item-msg">'+icon+' <strong style="color:'+color+'">'+escapeHtml(label)+':</strong> '+escapeHtml(msg)+'</div>'+
|
||||
'</div>'+
|
||||
'<div class="live-item-meta">🕐 '+ago+' · <span style="font-family:monospace;opacity:.7">'+escapeHtml(meta)+'</span></div>'+
|
||||
'</div>';
|
||||
}).join("");
|
||||
feed.innerHTML = html;
|
||||
}
|
||||
|
||||
// Start SSE on page load
|
||||
setTimeout(connectSSELive, 1000);
|
||||
// ============ END SSE additif ============
|
||||
|
||||
|
||||
function startCollab(){
|
||||
// DOCTRINE 143 - Real inter-agent conversation via /api/cloudbot-interagent.php
|
||||
var n1 = prompt("Nom agent 1 (ex: WEVIA, Ethica, WEVCODE, Blade, WEDROID, Manager, WEVAL MIND) :");
|
||||
if(!n1) return;
|
||||
var n2 = prompt("Nom agent 2 (different du premier) :");
|
||||
if(!n2) return;
|
||||
var topic = prompt("Topic de collaboration (question/sujet a discuter) :");
|
||||
if(!topic) return;
|
||||
var turns = prompt("Nombre de tours (2-4 recommande, max 6) :", "3");
|
||||
turns = Math.min(6, Math.max(1, parseInt(turns)||3));
|
||||
openInterAgentModal(n1, n2, topic, turns);
|
||||
}
|
||||
|
||||
function openInterAgentModal(agent1, agent2, topic, turns){
|
||||
var modal = document.getElementById("chat-modal");
|
||||
document.getElementById("m-title").textContent = "🤝 "+agent1+" ↔ "+agent2;
|
||||
document.getElementById("m-avatar").textContent = "🤝";
|
||||
document.getElementById("m-avatar").style.background = "linear-gradient(135deg,#ec4899,#8b5cf6,#06d6ba)";
|
||||
var chat = document.getElementById("m-chat");
|
||||
chat.innerHTML = '<div class="msg sys">🤝 <strong>Conversation inter-agents en cours</strong> · '+agent1+' ↔ '+agent2+' · Topic: '+escapeHtml(topic)+' · '+turns+' tours</div>';
|
||||
chat.innerHTML += '<div class="msg sys">⏳ Initialisation... (peut prendre 30-60 sec selon les APIs agents)</div>';
|
||||
modal.classList.add("on");
|
||||
document.getElementById("m-input").placeholder = "Conversation auto - attendez les reponses...";
|
||||
document.getElementById("m-input").disabled = true;
|
||||
document.getElementById("m-send").disabled = true;
|
||||
|
||||
fetch("/api/cloudbot-interagent.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({agent1: agent1, agent2: agent2, topic: topic, turns: turns})
|
||||
}).then(function(r){ return r.json(); }).then(function(data){
|
||||
chat.innerHTML = '<div class="msg sys">🤝 <strong>'+agent1+' ↔ '+agent2+'</strong> · Topic: '+escapeHtml(topic)+' · '+(data.turns_completed||0)+' tours</div>';
|
||||
if(!data.dialogue || !data.dialogue.length){
|
||||
chat.innerHTML += '<div class="msg sys" style="color:#ef4444">⚠️ Aucun dialogue (agent non trouve ou erreur API)</div>';
|
||||
if(data.error) chat.innerHTML += '<div class="msg sys">ERR: '+escapeHtml(data.error)+'</div>';
|
||||
document.getElementById("m-input").disabled = false;
|
||||
document.getElementById("m-send").disabled = false;
|
||||
return;
|
||||
}
|
||||
data.dialogue.forEach(function(t){
|
||||
// Question de from -> to
|
||||
chat.innerHTML += '<div class="msg u" style="max-width:85%"><div style="font-size:11px;font-weight:700;opacity:.9;margin-bottom:4px">🎯 '+escapeHtml(t.from)+' → '+escapeHtml(t.to)+' (tour '+t.turn+')</div>'+escapeHtml(t.message)+'</div>';
|
||||
// Reponse
|
||||
chat.innerHTML += '<div class="msg a"><div style="font-size:11px;font-weight:700;color:#06d6ba;margin-bottom:4px">🤖 '+escapeHtml(t.to)+' repond :</div>'+escapeHtml(t.response)+'<div class="msg-meta">via '+escapeHtml(t.provider)+' · '+t.latency_ms+'ms</div></div>';
|
||||
});
|
||||
chat.innerHTML += '<div class="msg sys">✅ Conversation terminee · '+(data.logged_to_db?"📝 loggee en PG (visible dans SSE feed)":"")+' · Session: '+(data.session_id||"").substring(0,30)+'</div>';
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
document.getElementById("m-input").disabled = false;
|
||||
document.getElementById("m-send").disabled = false;
|
||||
addActivity("🤝 Inter-Agent: "+agent1+" ↔ "+agent2+" sur "+topic.substring(0,30));
|
||||
CONV_COUNT += data.dialogue.length;
|
||||
var kc = document.getElementById("k-conv");
|
||||
if(kc) kc.textContent = CONV_COUNT;
|
||||
}).catch(function(e){
|
||||
chat.innerHTML += '<div class="msg sys" style="color:#ef4444">⚠️ '+escapeHtml(e.message)+'</div>';
|
||||
document.getElementById("m-input").disabled = false;
|
||||
document.getElementById("m-send").disabled = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user