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>
95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
"""
|
|
Session API routes. Route handlers are thin — they validate input and delegate to core/.
|
|
All routes are mounted under /v1 in main.py.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, HTTPException, WebSocket, WebSocketDisconnect
|
|
from fastapi.responses import StreamingResponse
|
|
|
|
from fellowship.api.models.session import (
|
|
CreateSessionRequest,
|
|
CreateSessionResponse,
|
|
SessionStatusResponse,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(tags=["sessions"])
|
|
|
|
|
|
@router.post(
|
|
"/session/create",
|
|
response_model=CreateSessionResponse,
|
|
summary="Initialize a new session",
|
|
description="Create a new Fellowship session with the given bots and options. Returns a session token.",
|
|
)
|
|
async def create_session(body: CreateSessionRequest) -> CreateSessionResponse:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.get(
|
|
"/session/{token}",
|
|
response_model=SessionStatusResponse,
|
|
summary="Get session status",
|
|
description="Returns current state, turn count, and connected member counts for a session.",
|
|
)
|
|
async def get_session(token: str) -> SessionStatusResponse:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.delete(
|
|
"/session/{token}",
|
|
summary="End a session",
|
|
description="Terminates the session loop and disconnects all members.",
|
|
)
|
|
async def end_session(token: str) -> dict[str, str]:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.post(
|
|
"/session/{token}/pause",
|
|
summary="Pause a session",
|
|
description="Halts the session loop. Members remain connected and receive a session_paused event.",
|
|
)
|
|
async def pause_session(token: str) -> dict[str, str]:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.post(
|
|
"/session/{token}/resume",
|
|
summary="Resume a paused session",
|
|
description="Restarts the session loop. Members receive a session_resumed event.",
|
|
)
|
|
async def resume_session(token: str) -> dict[str, str]:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.get(
|
|
"/session/{token}/history",
|
|
summary="Get full conversation history",
|
|
description="Returns the complete ordered message log for the session.",
|
|
)
|
|
async def get_history(token: str) -> dict:
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.websocket("/session/{token}/connect")
|
|
async def websocket_connect(websocket: WebSocket, token: str, role: str = "observer") -> None:
|
|
"""
|
|
WebSocket connection for talkers (role=talker) and observers (role=observer).
|
|
On connect: sends a history event with the full conversation, then streams live events.
|
|
Talkers may send user_message and ping frames.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
|
|
@router.get(
|
|
"/session/{token}/stream",
|
|
summary="SSE observe-only stream",
|
|
description="Server-Sent Events stream for observers. Sends history replay then live events.",
|
|
)
|
|
async def sse_stream(token: str) -> StreamingResponse:
|
|
raise NotImplementedError
|