prototype

This commit is contained in:
kacper 2026-02-28 22:12:04 -05:00
commit 8534b15c20
8 changed files with 3048 additions and 0 deletions

37
wisper.py Normal file
View file

@ -0,0 +1,37 @@
import asyncio
from dataclasses import dataclass, field
from datetime import datetime, timezone
@dataclass(slots=True)
class WisperEvent:
role: str
text: str
timestamp: str = field(
default_factory=lambda: datetime.now(timezone.utc).isoformat(timespec="seconds")
)
def to_dict(self) -> dict[str, str]:
return {"role": self.role, "text": self.text, "timestamp": self.timestamp}
class WisperBus:
def __init__(self) -> None:
self._subscribers: set[asyncio.Queue[WisperEvent]] = set()
self._lock = asyncio.Lock()
async def subscribe(self) -> asyncio.Queue[WisperEvent]:
queue: asyncio.Queue[WisperEvent] = asyncio.Queue()
async with self._lock:
self._subscribers.add(queue)
return queue
async def unsubscribe(self, queue: asyncio.Queue[WisperEvent]) -> None:
async with self._lock:
self._subscribers.discard(queue)
async def publish(self, event: WisperEvent) -> None:
async with self._lock:
subscribers = list(self._subscribers)
for queue in subscribers:
queue.put_nowait(event)