"""Backend protocol. A backend turns an Anthropic-style turn (``messages`` + agent definition) into a stream of :class:`~beaver_gateway.events.stream.MessageStreamEvent` records. The frontend serializes whatever comes out straight to SSE, so backends are the only place where provider quirks are translated. Implementations are plain :class:`typing.Protocol` conformers - no ABC subclassing - to keep them swappable in tests with bare async generators. ``**options`` is the one extension point. Known keys, all optional and ignored by backends that don't keep state: ``conversation_id`` (stable id the backend may pin a live session to), ``session_id`` (backend session to resume when nothing is live), ``capture`` (a :class:`~beaver_gateway.backends.capture.TurnCapture` the backend fills after the stream closes). """ from __future__ import annotations from typing import TYPE_CHECKING, Any, Protocol if TYPE_CHECKING: from collections.abc import AsyncIterator, Iterable from anthropic.types import MessageParam from beaver_gateway.agents.base import BaseAgent from beaver_gateway.events.stream import MessageStreamEvent class Backend(Protocol): """Single-method protocol; ``complete`` returns an async iterator of events.""" def complete( self, *, agent: BaseAgent, messages: Iterable[MessageParam], system: str | None = None, **options: Any, ) -> AsyncIterator[MessageStreamEvent]: """Yield Anthropic stream events for one turn against ``agent``.""" ...