1
0

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:
Alexander Payne
2026-02-26 08:01:01 -05:00
parent 8d85f95ee5
commit d8d976aa60
41 changed files with 6735 additions and 254 deletions

View File

@@ -5,6 +5,8 @@ The actual backend (mock or LND) is selected via LIGHTNING_BACKEND env var.
For backward compatibility, the PaymentHandler class and payment_handler
singleton are preserved, but they delegate to the lightning backend.
All transactions are logged to the ledger for audit and accounting.
"""
import logging
@@ -13,6 +15,12 @@ from typing import Optional
# Import from the new lightning module
from lightning import get_backend, Invoice
from lightning.base import LightningBackend
from lightning.ledger import (
create_invoice_entry,
mark_settled,
get_balance,
list_transactions,
)
logger = logging.getLogger(__name__)
@@ -42,22 +50,66 @@ class PaymentHandler:
self._backend = backend or get_backend()
logger.info("PaymentHandler initialized — backend: %s", self._backend.name)
def create_invoice(self, amount_sats: int, memo: str = "") -> Invoice:
"""Create a new Lightning invoice."""
def create_invoice(
self,
amount_sats: int,
memo: str = "",
source: str = "payment_handler",
task_id: Optional[str] = None,
agent_id: Optional[str] = None,
) -> Invoice:
"""Create a new Lightning invoice.
Args:
amount_sats: Invoice amount in satoshis
memo: Payment description
source: Component creating the invoice
task_id: Associated task ID
agent_id: Associated agent ID
"""
invoice = self._backend.create_invoice(amount_sats, memo)
logger.info(
"Invoice created: %d sats — %s (hash: %s…)",
amount_sats, memo, invoice.payment_hash[:12],
)
# Log to ledger
create_invoice_entry(
payment_hash=invoice.payment_hash,
amount_sats=amount_sats,
memo=memo,
invoice=invoice.bolt11 if hasattr(invoice, 'bolt11') else None,
source=source,
task_id=task_id,
agent_id=agent_id,
)
return invoice
def check_payment(self, payment_hash: str) -> bool:
"""Check whether an invoice has been paid."""
return self._backend.check_payment(payment_hash)
"""Check whether an invoice has been paid.
If paid, updates the ledger entry.
"""
is_paid = self._backend.check_payment(payment_hash)
if is_paid:
# Update ledger entry
mark_settled(payment_hash)
return is_paid
def settle_invoice(self, payment_hash: str, preimage: str) -> bool:
"""Manually settle an invoice with a preimage (for testing)."""
return self._backend.settle_invoice(payment_hash, preimage)
"""Manually settle an invoice with a preimage (for testing).
Also updates the ledger entry.
"""
result = self._backend.settle_invoice(payment_hash, preimage)
if result:
mark_settled(payment_hash, preimage=preimage)
return result
def get_invoice(self, payment_hash: str) -> Optional[Invoice]:
"""Get invoice details by payment hash."""
@@ -75,6 +127,26 @@ class PaymentHandler:
def backend_name(self) -> str:
"""Get the name of the current backend."""
return self._backend.name
def get_balance(self) -> dict:
"""Get current balance summary from ledger.
Returns:
Dict with incoming, outgoing, pending, and available balances
"""
return get_balance()
def list_transactions(self, limit: int = 100, **filters) -> list:
"""List transactions from ledger.
Args:
limit: Maximum number of transactions
**filters: Optional filters (tx_type, status, task_id, agent_id)
Returns:
List of LedgerEntry objects
"""
return list_transactions(limit=limit, **filters)
# Module-level singleton