"""``PolyfillResult`` — the shape returned by the context-management dispatcher.

Threaded from the dispatcher through ``async_anthropic_messages_handler`` into
the adapter so it can prepend the ``compaction`` block to the response and
attach ``iterations`` to ``usage``.
"""

from dataclasses import dataclass, field
from typing import Any, Final

from litellm.types.llms.anthropic import (
    AppliedEdit,
    CompactionBlock,
    UsageIteration,
)

from .constants import COMPACT_EDIT_TYPE


@dataclass
class PolyfillResult:
    messages: list[dict[str, Any]]
    system: str | list[dict[str, Any]] | None
    applied_edits: list[AppliedEdit] = field(default_factory=list)
    compaction_block: CompactionBlock | None = None
    iterations_usage: list[UsageIteration] | None = None

    def applied_edits_for_response(self) -> list[AppliedEdit] | None:
        """``applied_edits`` to attach on the client-visible response.

        ``compact_20260112`` is included when a new compaction block was
        synthesized (success), when the edit carries an ``error`` field
        (``summary_model_not_configured``, ``summary_call_failed``,
        ``summary_extraction_failed``), or when the edit carries
        ``warnings`` (e.g. ``unsupported_trigger_type_X_using_input_tokens``,
        ``pause_after_compaction_ignored``) — operators and clients need to
        see why compaction was requested but not applied as expected.
        Slice-only / under-threshold paths that produced no edit at all
        (no block, no error, no warnings) are omitted. Other edit types are
        included when the editor returned an ``AppliedEdit``.
        """
        visible: Final[list[AppliedEdit]] = []
        for edit in self.applied_edits:
            if edit.get("type") == COMPACT_EDIT_TYPE:
                if self.compaction_block is not None or edit.get("error") or edit.get("warnings"):
                    visible.append(edit)
            else:
                visible.append(edit)
        return visible or None
