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:
98
src/dashboard/routes/memory.py
Normal file
98
src/dashboard/routes/memory.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""Memory (vector store) routes for browsing and searching memories."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Form, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from memory.vector_store import (
|
||||
store_memory,
|
||||
search_memories,
|
||||
get_memory_stats,
|
||||
recall_personal_facts,
|
||||
store_personal_fact,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/memory", tags=["memory"])
|
||||
templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates"))
|
||||
|
||||
|
||||
@router.get("", response_class=HTMLResponse)
|
||||
async def memory_page(
|
||||
request: Request,
|
||||
query: Optional[str] = None,
|
||||
context_type: Optional[str] = None,
|
||||
agent_id: Optional[str] = None,
|
||||
):
|
||||
"""Memory browser and search page."""
|
||||
results = []
|
||||
if query:
|
||||
results = search_memories(
|
||||
query=query,
|
||||
context_type=context_type,
|
||||
agent_id=agent_id,
|
||||
limit=20,
|
||||
)
|
||||
|
||||
stats = get_memory_stats()
|
||||
facts = recall_personal_facts(limit=10)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"memory.html",
|
||||
{
|
||||
"page_title": "Memory Browser",
|
||||
"query": query,
|
||||
"results": results,
|
||||
"stats": stats,
|
||||
"facts": facts,
|
||||
"filter_type": context_type,
|
||||
"filter_agent": agent_id,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.post("/search", response_class=HTMLResponse)
|
||||
async def memory_search(
|
||||
request: Request,
|
||||
query: str = Form(...),
|
||||
context_type: Optional[str] = Form(None),
|
||||
):
|
||||
"""Search memories (form submission)."""
|
||||
results = search_memories(
|
||||
query=query,
|
||||
context_type=context_type,
|
||||
limit=20,
|
||||
)
|
||||
|
||||
# Return partial for HTMX
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"partials/memory_results.html",
|
||||
{
|
||||
"query": query,
|
||||
"results": results,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.post("/fact", response_class=HTMLResponse)
|
||||
async def add_fact(
|
||||
request: Request,
|
||||
fact: str = Form(...),
|
||||
agent_id: Optional[str] = Form(None),
|
||||
):
|
||||
"""Add a personal fact to memory."""
|
||||
store_personal_fact(fact, agent_id=agent_id)
|
||||
|
||||
# Return updated facts list
|
||||
facts = recall_personal_facts(limit=10)
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"partials/memory_facts.html",
|
||||
{
|
||||
"facts": facts,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user