Phase 6: Real-Time Agent Coordination Demo
See active agents and their work across multiple sessions in real-time
Waiting for agent activity...
// Connect to WebSocket for broadcast events
const ws = new WebSocket('ws://localhost:8000/ws/broadcasts');
ws.onopen = () => {
console.log('✅ Connected to broadcast stream');
updateStatus('Connected to real-time updates', true);
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
// Listen for presence updates
if (msg.type === 'presence_update') {
const { agent_id, presence } = msg;
updateAgentCard(agent_id, presence);
updateStatistics();
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
updateStatus('Connection error', false);
};
ws.onclose = () => {
console.log('WebSocket closed, attempting reconnect...');
setTimeout(() => connectWebSocket(), 3000);
};
from dataclasses import dataclass
from datetime import datetime
@dataclass
class AgentPresence:
agent_id: str # e.g., 'claude-1', 'gemini-2'
status: str # 'active' | 'idle' | 'offline'
current_feature_id: str # e.g., 'feat-123' or None
last_tool_name: str # e.g., 'Bash', 'Read', 'Write'
last_activity: datetime # When last event occurred
total_tools_executed: int # Cumulative counter per session
total_cost_tokens: int # Total token spend
session_id: str # Current session identifier
# WebSocket broadcast format
{
"type": "presence_update",
"event_type": "presence_update",
"agent_id": "claude-1",
"presence": {
"agent_id": "claude-1",
"status": "active",
"current_feature_id": "feat-aa1f17eb",
"last_tool_name": "Bash",
"last_activity": "2025-01-14T14:50:30Z",
"total_tools_executed": 42,
"total_cost_tokens": 150000,
"session_id": "sess-abc123"
},
"timestamp": "2025-01-14T14:50:30Z"
}
// Real-Time Presence Updates (Primary)
WS /ws/broadcasts
Broadcast channel for all sessions
Sends: presence_update events with agent status
Latency: <100ms from event to delivery
Connect once, receive all agent updates
// Manual Presence Check (Optional)
GET /api/presence
Get current presence of all agents
Response: { agents: [AgentPresence, ...], timestamp }
Use if WebSocket not available
// Presence Manager (Backend)
PresenceManager.update_presence(agent_id, event, websocket_manager)
Called on each tool execution
Updates status, activity time, metrics
Broadcasts to all connected clients if websocket_manager provided
Latency: <500ms from activity to presence update - Tool execution completes - PresenceManager updates state (<1ms) - WebSocket broadcasts to all clients (<50ms) - Browser renders UI update (<50ms) - Total: ~100ms typical case Throughput: 1000+ presence updates per second - Each agent can emit multiple events per second - All updates broadcast to all connected dashboards - Batching not needed for presence (low volume) Memory: <100MB for 1000 connected clients - Per-connection: ~100KB overhead - Presence data cached in-memory - SQLite for persistence across restarts Connections: 10 clients max per session (configurable) - Prevents runaway memory usage - Enforced at WebSocket.connect()
POST /api/broadcast/features/{id}/status also triggers presence update when feature changes
/api/status to start HtmlGraph server (if not already running)python3 -c "from htmlgraph import SDK; sdk = SDK('demo'); from htmlgraph.api.presence import PresenceManager, AgentPresence; from datetime import datetime; pm = PresenceManager(); pm.update_presence('claude-1', 'tool_execute', None); print('✅ Presence updated')"