This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/src/swarm/bidder.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

89 lines
2.7 KiB
Python

"""15-second auction system for swarm task assignment.
When a task is posted, agents have 15 seconds to submit bids (in sats).
The lowest bid wins. If no bids arrive, the task remains unassigned.
"""
import asyncio
import logging
from dataclasses import dataclass, field
from typing import Optional
logger = logging.getLogger(__name__)
AUCTION_DURATION_SECONDS = 15
@dataclass
class Bid:
agent_id: str
bid_sats: int
task_id: str
@dataclass
class Auction:
task_id: str
bids: list[Bid] = field(default_factory=list)
closed: bool = False
winner: Optional[Bid] = None
def submit(self, agent_id: str, bid_sats: int) -> bool:
"""Submit a bid. Returns False if the auction is already closed."""
if self.closed:
return False
self.bids.append(Bid(agent_id=agent_id, bid_sats=bid_sats, task_id=self.task_id))
return True
def close(self) -> Optional[Bid]:
"""Close the auction and determine the winner (lowest bid)."""
self.closed = True
if not self.bids:
logger.info("Auction %s: no bids received", self.task_id)
return None
self.winner = min(self.bids, key=lambda b: b.bid_sats)
logger.info(
"Auction %s: winner is %s at %d sats",
self.task_id, self.winner.agent_id, self.winner.bid_sats,
)
return self.winner
class AuctionManager:
"""Manages concurrent auctions for multiple tasks."""
def __init__(self) -> None:
self._auctions: dict[str, Auction] = {}
def open_auction(self, task_id: str) -> Auction:
auction = Auction(task_id=task_id)
self._auctions[task_id] = auction
logger.info("Auction opened for task %s", task_id)
return auction
def get_auction(self, task_id: str) -> Optional[Auction]:
return self._auctions.get(task_id)
def submit_bid(self, task_id: str, agent_id: str, bid_sats: int) -> bool:
auction = self._auctions.get(task_id)
if auction is None:
logger.warning("No auction found for task %s", task_id)
return False
return auction.submit(agent_id, bid_sats)
def close_auction(self, task_id: str) -> Optional[Bid]:
auction = self._auctions.get(task_id)
if auction is None:
return None
return auction.close()
async def run_auction(self, task_id: str) -> Optional[Bid]:
"""Open an auction, wait the bidding period, then close and return winner."""
self.open_auction(task_id)
await asyncio.sleep(AUCTION_DURATION_SECONDS)
return self.close_auction(task_id)
@property
def active_auctions(self) -> list[str]:
return [tid for tid, a in self._auctions.items() if not a.closed]