"""Application orchestration layer for evaLLM.

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

This package coordinates dataset access and metric execution while exposing a stable
public API for library and CLI consumers.

!!! abstract
    `evallm.application` is the orchestration layer that turns validated requests into
    executable evaluation flows. `api` exposes ergonomic construction primitives,
    `models` defines canonical contracts, `services` resolves and executes requests,
    `adapters` normalize raw reader output into DTOs, `validation` enforces
    cross-object constraints, and `errors` defines user-facing failure semantics.

## Design Decisions

:material-source-branch: **Decision**: Use immutable DTOs as canonical request/result contracts.
:   :material-lightbulb-on-outline: **Motivation**: `models` uses frozen pydantic DTOs
    to keep boundary data validated, serializable, and mutation-safe across layers.

:material-source-branch: **Decision**: Separate structural validation from runtime/contextual resolution.
:   :material-lightbulb-on-outline: **Motivation**: shape validation happens at DTO
    creation, while checks requiring runtime context (catalog membership, metric
    config validation, reader binding) happen in resolver/services.

:material-source-branch: **Decision**: Resolve requests into two runtime artifacts.
:   :material-lightbulb-on-outline: **Motivation**: `RequestResolver` returns
    `(records_context_manager, composite_metric)`, decoupling data streaming from metric
    composition/execution.

:material-source-branch: **Decision**: Enforce result-key uniqueness before execution.
:   :material-lightbulb-on-outline: **Motivation**: per-record results are merged into a
    single dictionary, so duplicate result keys would overwrite values unless rejected
    early.

:material-source-branch: **Decision**: Keep request construction ergonomic via builder + helpers.
:   :material-lightbulb-on-outline: **Motivation**: `BaseEvaluationBuilder`/
    `JsonlEvaluationBuilder` and helper factories (`metric`, `count_*`, `json_format`)
    provide concise API ergonomics while still yielding canonical DTOs.

:material-source-branch: **Decision**: Depend on abstract contracts where possible.
:   :material-lightbulb-on-outline: **Motivation**: using abstractions like `Catalog`
    improves testability and supports custom registries without changing orchestration
    logic.
"""

from .api import (
    BaseEvaluationBuilder,
    JsonlEvaluationBuilder,
    count_characters,
    count_encodings,
    count_tokens,
    json_format,
    metric,
)
from .models import (
    BaseDatasetSpec,
    DatasetRecord,
    EvaluationRequest,
    EvaluationResult,
    JsonlDatasetSpec,
    MetricSpec,
)
from .services import Evaluator

__all__ = [
    "BaseDatasetSpec",
    "BaseEvaluationBuilder",
    "DatasetRecord",
    "EvaluationRequest",
    "EvaluationResult",
    "Evaluator",
    "JsonlDatasetSpec",
    "JsonlEvaluationBuilder",
    "MetricSpec",
    "count_characters",
    "count_encodings",
    "count_tokens",
    "json_format",
    "metric",
]
