Fix SSE route dependency and align architecture docs

This commit is contained in:
ash66
2026-05-18 16:32:42 +08:00
parent 86b9ac806a
commit 3f69cad404
149 changed files with 4786 additions and 5957 deletions

View File

@@ -0,0 +1,5 @@
"""Initialize the app.infrastructure.session package."""
# Keep package boundaries explicit so backend imports stay predictable.
__all__ = []

View File

@@ -0,0 +1,95 @@
"""Implement infrastructure support for in memory conversation store."""
from __future__ import annotations
import time
import uuid
from app.domain.conversation import ConversationMessage, ConversationSession, ConversationStore
# Keep adapter behavior explicit so integration details remain easy to audit.
class InMemoryConversationStore(ConversationStore):
"""Provide the In Memory Conversation Store store implementation."""
def __init__(self, *, max_sessions: int = 100, timeout_minutes: int = 30) -> None:
"""Initialize the In Memory Conversation Store instance."""
self.max_sessions = max_sessions
self.timeout_seconds = timeout_minutes * 60
self.sessions: dict[str, ConversationSession] = {}
def _now(self) -> int:
"""Handle now for this module for the In Memory Conversation Store instance."""
return int(time.time())
def _cleanup_expired(self) -> None:
"""Handle cleanup expired for this module for the In Memory Conversation Store instance."""
now = self._now()
expired = [
session_id
for session_id, session in self.sessions.items()
if (now - session.updated_at) > self.timeout_seconds
]
for session_id in expired:
self.sessions.pop(session_id, None)
def create_session(self, metadata: dict | None = None) -> ConversationSession:
"""Create session for the In Memory Conversation Store instance."""
self._cleanup_expired()
if len(self.sessions) >= self.max_sessions:
oldest = min(self.sessions.values(), key=lambda item: item.updated_at)
self.sessions.pop(oldest.session_id, None)
session_id = str(uuid.uuid4())[:8]
session = ConversationSession(
session_id=session_id,
created_at=self._now(),
updated_at=self._now(),
metadata=metadata or {},
)
self.sessions[session_id] = session
return session
def get_session(self, session_id: str) -> ConversationSession | None:
"""Return session for the In Memory Conversation Store instance."""
self._cleanup_expired()
return self.sessions.get(session_id)
def save_message(
self,
session_id: str,
*,
role: str,
content: str,
sources: list[dict] | None = None,
) -> ConversationSession | None:
"""Save message for the In Memory Conversation Store instance."""
session = self.get_session(session_id)
if not session:
return None
session.messages.append(
ConversationMessage(
role=role,
content=content,
timestamp=self._now(),
sources=sources or [],
)
)
session.updated_at = self._now()
return session
def delete_session(self, session_id: str) -> bool:
"""Delete session for the In Memory Conversation Store instance."""
return self.sessions.pop(session_id, None) is not None
def list_sessions(self) -> list[dict]:
"""List sessions for the In Memory Conversation Store instance."""
self._cleanup_expired()
return [
{
"session_id": session.session_id,
"message_count": len(session.messages),
"created_at": session.created_at,
"updated_at": session.updated_at,
}
for session in self.sessions.values()
]