ModelArena / core /memory.py
vedanshmathur7's picture
Sync from GitHub via hub-sync
af8b301 verified
Raw History Blame Contribute Delete
2.71 kB
"""
Short-term conversational memory manager.
Maintains a rolling buffer of the last N exchanges for both assistants.
"""
from __future__ import annotations
import time
from dataclasses import dataclass, field
from typing import List, Literal, Optional
Role = Literal["user", "assistant", "system"]
@dataclass
class Message:
role: Role
content: str
timestamp: float = field(default_factory=time.time)
def to_dict(self) -> dict:
return {"role": self.role, "content": self.content}
class ConversationMemory:
"""
Rolling buffer memory that keeps the last `max_exchanges` user/assistant pairs.
A system prompt is always prepended when building the message list.
"""
def __init__(self, max_exchanges: int = 8, system_prompt: Optional[str] = None):
self.max_exchanges = max_exchanges
self.system_prompt: Optional[str] = system_prompt
self._history: List[Message] = []
# ------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------
def add_user_message(self, content: str) -> None:
self._history.append(Message(role="user", content=content))
self._trim()
def add_assistant_message(self, content: str) -> None:
self._history.append(Message(role="assistant", content=content))
self._trim()
def get_messages(self) -> List[dict]:
"""Return the full message list ready for an LLM API call."""
messages: List[dict] = []
if self.system_prompt:
messages.append({"role": "system", "content": self.system_prompt})
messages.extend(msg.to_dict() for msg in self._history)
return messages
def clear(self) -> None:
self._history.clear()
def set_system_prompt(self, prompt: str) -> None:
self.system_prompt = prompt
@property
def history(self) -> List[Message]:
return list(self._history)
@property
def turn_count(self) -> int:
return sum(1 for m in self._history if m.role == "user")
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _trim(self) -> None:
"""Keep only the last max_exchanges * 2 messages (user + assistant pairs)."""
max_messages = self.max_exchanges * 2
if len(self._history) > max_messages:
self._history = self._history[-max_messages:]
def __repr__(self) -> str:
return (
f"ConversationMemory(turns={self.turn_count}, "
f"max_exchanges={self.max_exchanges})"
)