"""Side channel for what a backend learned during one turn. Frontends pass ``capture=TurnCapture()`` through ``Backend.complete``'s ``**options``. Backends that keep state per conversation (the Claude SDK adapter) fill it in after the stream closes; backends that don't (anthropic, raycast) drop the kwarg and the frontend falls back to a text-only history. """ from __future__ import annotations from dataclasses import dataclass, field from typing import Any __all__ = ["TurnCapture", "TurnUsage"] @dataclass(frozen=True, slots=True) class TurnUsage: input_tokens: int = 0 output_tokens: int = 0 cache_read_tokens: int = 0 cache_creation_tokens: int = 0 cost_usd: float | None = None duration_ms: int | None = None num_turns: int | None = None @dataclass class TurnCapture: synthesized_messages: list[dict[str, Any]] = field(default_factory=list) """The assistant/tool_result cycle of the turn as Anthropic messages.""" session_id: str | None = None """Backend session that ran the turn; persist and pass back as ``session_id``.""" usage: TurnUsage | None = None interrupted: bool = False """The turn was cut by ``interrupt()`` (urgent inject), not by an error."""