"""Short-lived per-process conversation memory.

Long-term memory lives in the vector store (semantic recall) and in the
audit trail (interaction history). This module is the volatile in-flight
buffer the agent runner reads while drafting a response.
"""

from __future__ import annotations

from collections import deque
from dataclasses import dataclass, field
from typing import Any


@dataclass
class MemoryEntry:
    role: str
    content: str
    metadata: dict[str, Any] = field(default_factory=dict)


class ConversationMemory:
    """Bounded FIFO buffer keyed by conversation id."""

    def __init__(self, max_entries: int = 50) -> None:
        if max_entries < 1:
            raise ValueError("max_entries must be >= 1")
        self._max = max_entries
        self._buf: dict[str, deque[MemoryEntry]] = {}

    def append(self, conversation_id: str, entry: MemoryEntry) -> None:
        buf = self._buf.setdefault(conversation_id, deque(maxlen=self._max))
        buf.append(entry)

    def history(self, conversation_id: str) -> list[MemoryEntry]:
        return list(self._buf.get(conversation_id, ()))

    def clear(self, conversation_id: str | None = None) -> None:
        if conversation_id is None:
            self._buf.clear()
        else:
            self._buf.pop(conversation_id, None)


_DEFAULT = ConversationMemory()


def default_memory() -> ConversationMemory:
    return _DEFAULT
