forked from Rockachopa/Timmy-time-dashboard
feat: complete Event Log, Ledger, Memory, Cascade Router, Upgrade Queue, Activity Feed
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
This commit is contained in:
103
src/dashboard/templates/events.html
Normal file
103
src/dashboard/templates/events.html
Normal file
@@ -0,0 +1,103 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Event Log - Timmy Time{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="mc-panel">
|
||||
<div class="mc-panel-header">
|
||||
<h1 class="page-title">Event Log</h1>
|
||||
<p class="mc-text-secondary">System audit trail and activity history</p>
|
||||
</div>
|
||||
|
||||
<!-- Summary Stats -->
|
||||
<div class="mc-stats-row">
|
||||
{% for event_type, count in summary.items() %}
|
||||
<div class="mc-stat-card">
|
||||
<div class="mc-stat-value">{{ count }}</div>
|
||||
<div class="mc-stat-label">{{ event_type }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if not summary %}
|
||||
<div class="mc-stat-card">
|
||||
<div class="mc-stat-value">-</div>
|
||||
<div class="mc-stat-label">No events (last hour)</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Filters -->
|
||||
<div class="mc-filters">
|
||||
<form method="get" action="/swarm/events" class="mc-filter-form">
|
||||
<select name="event_type" class="mc-select" onchange="this.form.submit()">
|
||||
<option value="">All Event Types</option>
|
||||
{% for et in event_types %}
|
||||
<option value="{{ et }}" {% if filter_type == et %}selected{% endif %}>{{ et }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
{% if filter_task %}
|
||||
<input type="hidden" name="task_id" value="{{ filter_task }}">
|
||||
<span class="mc-filter-tag">Task: {{ filter_task[:8] }}... <a href="/swarm/events">✕</a></span>
|
||||
{% endif %}
|
||||
|
||||
{% if filter_agent %}
|
||||
<input type="hidden" name="agent_id" value="{{ filter_agent }}">
|
||||
<span class="mc-filter-tag">Agent: {{ filter_agent[:8] }}... <a href="/swarm/events">✕</a></span>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Events Table -->
|
||||
<div class="mc-table-container">
|
||||
{% if events %}
|
||||
<table class="mc-table events-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Type</th>
|
||||
<th>Source</th>
|
||||
<th>Task</th>
|
||||
<th>Agent</th>
|
||||
<th>Data</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for event in events %}
|
||||
<tr class="event-row" data-type="{{ event.event_type.value }}">
|
||||
<td class="event-time">{{ event.timestamp[11:19] }}</td>
|
||||
<td>
|
||||
<span class="mc-badge mc-badge-{{ event.event_type.value.split('.')[0] }}">
|
||||
{{ event.event_type.value }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ event.source }}</td>
|
||||
<td>
|
||||
{% if event.task_id %}
|
||||
<a href="/swarm/events?task_id={{ event.task_id }}">{{ event.task_id[:8] }}...</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if event.agent_id %}
|
||||
<a href="/swarm/events?agent_id={{ event.agent_id }}">{{ event.agent_id[:8] }}...</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="event-data">
|
||||
{% if event.data %}
|
||||
<code>{{ event.data[:60] }}{% if event.data|length > 60 %}...{% endif %}</code>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="mc-empty-state">
|
||||
<p>No events found.</p>
|
||||
{% if filter_type or filter_task or filter_agent %}
|
||||
<p><a href="/swarm/events" class="mc-link">Clear filters</a></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user