Files
Timmy-time-dashboard/src/swarm/tasks.py
Alexspayne f9b84c1e2f feat: Mission Control v2 — swarm, L402, voice, marketplace, React dashboard
Major expansion of the Timmy Time Dashboard:

Backend modules:
- Swarm subsystem: registry, manager, bidder, coordinator, agent_runner, swarm_node, tasks, comms
- L402/Lightning: payment_handler, l402_proxy with HMAC macaroons
- Voice NLU: regex-based intent detection (chat, status, swarm, task, help, voice)
- Notifications: push notifier for swarm events
- Shortcuts: Siri Shortcuts iOS integration endpoints
- WebSocket: live dashboard event manager
- Inter-agent: agent-to-agent messaging layer

Dashboard routes:
- /swarm/* — swarm management and agent registry
- /marketplace — agent catalog with sat pricing
- /voice/* — voice command processing
- /mobile — mobile status endpoint
- /swarm/live — WebSocket live feed

React web dashboard (dashboard-web/):
- Sovereign Terminal design — dark theme with Bitcoin orange accents
- Three-column layout: status sidebar, workspace tabs, context panel
- Chat, Swarm, Tasks, Marketplace tab views
- JetBrains Mono typography, terminal aesthetic
- Framer Motion animations throughout

Tests: 228 passing (expanded from 93)
Includes Kimi's additional templates and QA work.
2026-02-21 12:57:38 -05:00

142 lines
4.0 KiB
Python

"""Swarm task dataclasses and CRUD operations.
Tasks are the unit of work in the swarm system. A coordinator posts a task,
agents bid on it, and the winning agent executes it. All persistence goes
through SQLite so the system survives restarts.
"""
import sqlite3
import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from pathlib import Path
from typing import Optional
DB_PATH = Path("data/swarm.db")
class TaskStatus(str, Enum):
PENDING = "pending"
BIDDING = "bidding"
ASSIGNED = "assigned"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
@dataclass
class Task:
id: str = field(default_factory=lambda: str(uuid.uuid4()))
description: str = ""
status: TaskStatus = TaskStatus.PENDING
assigned_agent: Optional[str] = None
result: Optional[str] = None
created_at: str = field(
default_factory=lambda: datetime.now(timezone.utc).isoformat()
)
completed_at: Optional[str] = None
def _get_conn() -> sqlite3.Connection:
DB_PATH.parent.mkdir(parents=True, exist_ok=True)
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
conn.execute(
"""
CREATE TABLE IF NOT EXISTS tasks (
id TEXT PRIMARY KEY,
description TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
assigned_agent TEXT,
result TEXT,
created_at TEXT NOT NULL,
completed_at TEXT
)
"""
)
conn.commit()
return conn
def create_task(description: str) -> Task:
task = Task(description=description)
conn = _get_conn()
conn.execute(
"INSERT INTO tasks (id, description, status, created_at) VALUES (?, ?, ?, ?)",
(task.id, task.description, task.status.value, task.created_at),
)
conn.commit()
conn.close()
return task
def get_task(task_id: str) -> Optional[Task]:
conn = _get_conn()
row = conn.execute("SELECT * FROM tasks WHERE id = ?", (task_id,)).fetchone()
conn.close()
if row is None:
return None
return Task(
id=row["id"],
description=row["description"],
status=TaskStatus(row["status"]),
assigned_agent=row["assigned_agent"],
result=row["result"],
created_at=row["created_at"],
completed_at=row["completed_at"],
)
def list_tasks(status: Optional[TaskStatus] = None) -> list[Task]:
conn = _get_conn()
if status:
rows = conn.execute(
"SELECT * FROM tasks WHERE status = ? ORDER BY created_at DESC",
(status.value,),
).fetchall()
else:
rows = conn.execute(
"SELECT * FROM tasks ORDER BY created_at DESC"
).fetchall()
conn.close()
return [
Task(
id=r["id"],
description=r["description"],
status=TaskStatus(r["status"]),
assigned_agent=r["assigned_agent"],
result=r["result"],
created_at=r["created_at"],
completed_at=r["completed_at"],
)
for r in rows
]
def update_task(task_id: str, **kwargs) -> Optional[Task]:
conn = _get_conn()
allowed = {"status", "assigned_agent", "result", "completed_at"}
updates = {k: v for k, v in kwargs.items() if k in allowed}
if not updates:
conn.close()
return get_task(task_id)
# Convert enums to their value
if "status" in updates and isinstance(updates["status"], TaskStatus):
updates["status"] = updates["status"].value
set_clause = ", ".join(f"{k} = ?" for k in updates)
values = list(updates.values()) + [task_id]
conn.execute(f"UPDATE tasks SET {set_clause} WHERE id = ?", values)
conn.commit()
conn.close()
return get_task(task_id)
def delete_task(task_id: str) -> bool:
conn = _get_conn()
cursor = conn.execute("DELETE FROM tasks WHERE id = ?", (task_id,))
conn.commit()
deleted = cursor.rowcount > 0
conn.close()
return deleted