"""Input ingestion layer for evaLLM datasets.

![status](../../../badges/status-evallm-readers.svg)

This package isolates file-reading concerns from metric and orchestration logic.

!!! abstract
    `evallm.readers` is the ingestion boundary. `reader` provides a reusable,
    lazy streaming contract plus concrete file-format readers, while `utils` offers
    optional post-parse helpers for callers that need structured message conversion.

## Design Decisions

:material-source-branch: **Decision**: Use lazy, line-by-line iteration.
:   :material-lightbulb-on-outline: **Motivation**: dataset inputs can be large;
    `BaseReader` parses records on demand instead of loading the full file into memory.

:material-source-branch: **Decision**: Combine iterator and context-manager contracts.
:   :material-lightbulb-on-outline: **Motivation**: consumers can stream naturally with
    `for` while still getting deterministic resource cleanup via `with`.

:material-source-branch: **Decision**: Keep readers format-specific but output-shape-neutral.
:   :material-lightbulb-on-outline: **Motivation**: concrete readers (for example
    `JsonlReader`) produce raw dictionaries; normalization into canonical DTOs is an
    application-layer adapter responsibility.

:material-source-branch: **Decision**: Expose message-conversion helpers outside the core reader abstraction.
:   :material-lightbulb-on-outline: **Motivation**: optional helper utilities should
    not couple the base reading contract to one message representation.
"""

from .reader import BaseReader, JsonlReader
from .utils import InvalidMessageFormatError, messages_from_dicts

__all__ = [
    "BaseReader",
    "InvalidMessageFormatError",
    "JsonlReader",
    "messages_from_dicts",
]
