Initial project structure

Scaffold all modules, route stubs, data models, and config.
No logic implemented yet — all core methods raise NotImplementedError.
Establishes the full directory layout matching the architecture in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaroslav Benes
2026-04-08 14:48:48 +02:00
commit 083cbb1fa7
32 changed files with 1507 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
"""
Session store — in-memory registry of all active sessions.
Keyed by session token. Also holds the associated SessionLoop and MessageQueue per session.
"""
import logging
import secrets
from dataclasses import dataclass, field
from typing import Optional
from fellowship.core.session import Session
from fellowship.core.loop import SessionLoop
from fellowship.core.queue import MessageQueue
logger = logging.getLogger(__name__)
@dataclass
class SessionEntry:
session: Session
loop: SessionLoop
queue: MessageQueue
class SessionStore:
def __init__(self) -> None:
self._sessions: dict[str, SessionEntry] = {}
def create(self, session: Session, loop: SessionLoop, queue: MessageQueue) -> str:
"""Register a new session. Returns the session token."""
self._sessions[session.token] = SessionEntry(session, loop, queue)
return session.token
def get(self, token: str) -> Optional[SessionEntry]:
"""Return the SessionEntry for the given token, or None if not found."""
return self._sessions.get(token)
def remove(self, token: str) -> None:
"""Remove a session from the store."""
self._sessions.pop(token, None)
def generate_token(self) -> str:
"""Generate a cryptographically random session token."""
return secrets.token_urlsafe(32)
def all_tokens(self) -> list[str]:
return list(self._sessions.keys())
# Global singleton — imported by routes and other modules
session_store = SessionStore()