This commit implements six major features: 1. Event Log System (src/swarm/event_log.py) - SQLite-based audit trail for all swarm events - Task lifecycle tracking (created, assigned, completed, failed) - Agent lifecycle tracking (joined, left, status changes) - Integrated with coordinator for automatic logging - Dashboard page at /swarm/events 2. Lightning Ledger (src/lightning/ledger.py) - Transaction tracking for Lightning Network payments - Balance calculations (incoming, outgoing, net, available) - Integrated with payment_handler for automatic logging - Dashboard page at /lightning/ledger 3. Semantic Memory / Vector Store (src/memory/vector_store.py) - Embedding-based similarity search for Echo agent - Fallback to keyword matching if sentence-transformers unavailable - Personal facts storage and retrieval - Dashboard page at /memory 4. Cascade Router Integration (src/timmy/cascade_adapter.py) - Automatic LLM failover between providers (Ollama → AirLLM → API) - Circuit breaker pattern for failing providers - Metrics tracking per provider (latency, error rates) - Dashboard status page at /router/status 5. Self-Upgrade Approval Queue (src/upgrades/) - State machine for self-modifications: proposed → approved/rejected → applied/failed - Human approval required before applying changes - Git integration for branch management - Dashboard queue at /self-modify/queue 6. Real-Time Activity Feed (src/events/broadcaster.py) - WebSocket-based live activity streaming - Bridges event_log to dashboard clients - Activity panel on /swarm/live Tests: - 101 unit tests passing - 4 new E2E test files for Selenium testing - Run with: SELENIUM_UI=1 pytest tests/functional/ -v --headed Documentation: - 6 ADRs (017-022) documenting architecture decisions - Implementation summary in docs/IMPLEMENTATION_SUMMARY.md - Architecture diagram in docs/architecture-v2.md
6.2 KiB
ADR 022: Real-Time Activity Feed
Status
Proposed
Context
The dashboard currently shows static snapshots of swarm state. Users must refresh to see:
- New tasks being created
- Agents joining/leaving
- Bids being submitted
- Tasks being completed
This creates a poor UX for monitoring the swarm in real-time.
Decision
Implement a WebSocket-based real-time activity feed that streams events from the Event Log to connected dashboard clients.
Architecture
Data Flow
Coordinator Event → Event Log (SQLite)
↓
WebSocket Broadcast
↓
Dashboard Clients (via ws_manager)
Components
-
Event Source (
src/swarm/coordinator.py)- Already emits events via
log_event() - Events are persisted to SQLite
- Already emits events via
-
WebSocket Bridge (
src/ws_manager/handler.py)- Already exists for agent status
- Extend to broadcast events
-
Event Broadcaster (
src/events/broadcaster.py- NEW)class EventBroadcaster: """Bridges event_log → WebSocket.""" async def on_event_logged(self, event: EventLogEntry): """Called when new event is logged.""" await ws_manager.broadcast_event({ "type": event.event_type.value, "source": event.source, "task_id": event.task_id, "agent_id": event.agent_id, "timestamp": event.timestamp, "data": event.data, }) -
Dashboard UI (
/swarm/live- enhanced)- Already exists at
/swarm/live - Add activity feed panel
- Connect to WebSocket
- Show real-time events
- Already exists at
-
Mobile Support
- Same WebSocket for mobile view
- Simplified activity list
Event Types to Broadcast
| Event Type | Display As | Icon |
|---|---|---|
task.created |
"New task: {description}" | 📝 |
task.assigned |
"Task assigned to {agent}" | 👤 |
task.completed |
"Task completed" | ✓ |
agent.joined |
"Agent {name} joined" | 🟢 |
agent.left |
"Agent {name} left" | 🔴 |
bid.submitted |
"Bid: {amount}sats from {agent}" | 💰 |
tool.called |
"Tool: {tool_name}" | 🔧 |
system.error |
"Error: {message}" | ⚠️ |
WebSocket Protocol
// Client connects
{"action": "subscribe", "channel": "events"}
// Server broadcasts
{
"type": "event",
"payload": {
"event_type": "task.assigned",
"source": "coordinator",
"task_id": "task-123",
"agent_id": "agent-456",
"timestamp": "2024-01-15T10:30:00Z",
"data": {"bid_sats": 100}
}
}
UI Design: Activity Feed Panel
┌─────────────────────────────────────────┐
│ LIVE ACTIVITY [🔴] │
├─────────────────────────────────────────┤
│ 📝 New task: Write Python function │
│ 10:30:01 │
│ 💰 Bid: 50sats from forge │
│ 10:30:02 │
│ 👤 Task assigned to forge │
│ 10:30:07 │
│ ✓ Task completed │
│ 10:30:15 │
│ 🟢 Agent Echo joined │
│ 10:31:00 │
│ │
│ [Show All Events] │
└─────────────────────────────────────────┘
Integration with Existing Systems
Existing: Event Log (src/swarm/event_log.py)
- Hook into
log_event()to trigger broadcasts - Use SQLite
AFTER INSERTtrigger or Python callback
Existing: WebSocket Manager (src/ws_manager/handler.py)
- Add
broadcast_event()method - Handle client subscriptions
Existing: Coordinator (src/swarm/coordinator.py)
- Already calls
log_event()for all lifecycle events - No changes needed
Existing: Swarm Live Page (/swarm/live)
- Enhance with activity feed panel
- WebSocket client connection
Technical Design
Option A: Direct Callback (Chosen)
Modify log_event() to call broadcaster directly.
Pros: Simple, immediate delivery Cons: Tight coupling
# In event_log.py
def log_event(...):
# ... store in DB ...
# Broadcast to WebSocket clients
asyncio.create_task(_broadcast_event(event))
Option B: SQLite Trigger + Poll
Use SQLite trigger to mark new events, poll from broadcaster.
Pros: Decoupled, survives restarts Cons: Latency from polling
Option C: Event Bus
Use existing src/events/bus.py to publish/subscribe.
Pros: Decoupled, flexible Cons: Additional complexity
Decision: Option A for simplicity, with Option C as future refactoring.
Performance Considerations
- Rate Limiting: Max 10 events/second to clients
- Buffering: If client disconnected, buffer last 100 events
- Filtering: Clients can filter by event type
- Deduplication: WebSocket manager handles client dedup
Security
- Only authenticated dashboard users receive events
- Sanitize event data (no secrets in logs)
- Rate limit connections per IP
Consequences
Positive
- Real-time visibility into swarm activity
- Better UX for monitoring
- Uses existing infrastructure (Event Log, WebSocket)
Negative
- Increased server load from WebSocket connections
- Event data must be carefully sanitized
- More complex client-side state management
Mitigations
- Event throttling
- Connection limits
- Graceful degradation to polling
Implementation Plan
- Create EventBroadcaster - Bridge event_log → ws_manager
- Extend ws_manager - Add
broadcast_event()method - Modify event_log.py - Hook in broadcaster
- Enhance /swarm/live - Add activity feed panel with WebSocket
- Create EventFeed component - Reusable HTMX + WebSocket widget
- Write tests - E2E tests for real-time updates
Dependencies
- Existing
src/swarm/event_log.py - Existing
src/ws_manager/handler.py - Existing
/swarm/livepage - HTMX WebSocket extension (already loaded)