"""Stub file for training directory."""
from typing import Any, Dict, List, Optional, Set, Tuple

# Constants
logger: Any = ...  # From callbacks
logger: Any = ...  # From checkpoint
logger: Any = ...  # From delegated_trainer
logger: Any = ...  # From early_stopping
logger: Any = ...  # From loop_trainer
logger: Any = ...  # From optimizers
logger: Any = ...  # From schedulers
logger: Any = ...  # From trainer

# Functions
# From callbacks
def run_callbacks(callbacks: list[Any], hook: str, *args: Any, **kwargs: Any) -> None:
    """
    Fire a named hook on every callback in the list.
    
        Catches and logs exceptions from individual callbacks so that a
        broken callback does not crash the training loop.
    
        Args:
            callbacks: List of :class:`TrainerCallback` instances.
            hook: Method name to invoke (e.g. ``"on_epoch_end"``).
            *args: Positional arguments forwarded to the hook.
            **kwargs: Keyword arguments forwarded to the hook.
    """
    ...

# From checkpoint
def load_checkpoint(path: str | Any) -> dict[str, Any]:
    """
    Load a checkpoint from disk.
    
        Args:
            path: Path to the ``.pth.tar`` checkpoint file.
            map_location: Device to map tensors to (default ``"cpu"``
                for safe cross-device loading).
    
        Returns:
            The checkpoint state dict.
    
        Raises:
            FileNotFoundError: If *path* does not exist.
    """
    ...

# From checkpoint
def save_checkpoint(state: dict[str, Any], model: Any.Any | Any) -> list[Any]:
    """
    Save a training checkpoint to disk.
    
        Writes ``state`` (typically epoch, state_dict, optimizer, scheduler)
        to *checkpoint_dir/filename*.  When *is_best* is ``True``, also:
    
        * Copies the checkpoint to ``model_best.pth.tar``.
        * Saves the raw model to ``model_best.pt`` (handles
          ``DataParallel`` unwrapping automatically).
    
        Args:
            state: Serialisable dict — must include at minimum ``epoch``
                and ``state_dict``.
            model: The PyTorch model (or ``DataParallel``-wrapped model).
                Used only when *is_best* to create the ``.pt`` snapshot.
            is_best: Whether the current checkpoint is the best so far.
            checkpoint_dir: Directory where files are written.
            filename: Name of the periodic checkpoint file.
    
        Returns:
            List of :class:`Path` objects for every file written.
    """
    ...

# From device
def move_to_device(model: Any, device: Any.Any) -> Any.Any:
    """
    Move a model to *device* and return the device used.
    
        Handles both plain ``nn.Module`` and wrapper objects that store the
        actual model in a ``.model`` attribute (e.g. the ``r2plus1d_Model``
        wrapper from the R2Plus1D BYOM repo).
    
        Args:
            model: A PyTorch ``nn.Module``, or a wrapper with a ``.model``
                attribute pointing to the actual module.
            device: Target device.
    
        Returns:
            The device the model was moved to (same as *device*).
    """
    ...

# From device
def resolve_device(preferred: str = 'cuda') -> Any.Any:
    """
    Select the best available compute device.
    
        Tries the *preferred* backend first, then falls back through the
        priority chain ``cuda → mps → cpu``.
    
        Args:
            preferred: Requested device — one of ``"cuda"``, ``"mps"``,
                or ``"cpu"``.
    
        Returns:
            A :class:`torch.device` for the selected backend.
    
        Example::
    
            device = resolve_device("cuda")
            model = model.to(device)
    """
    ...

# From optimizers
def build_optimizer(model: Any.Any, config: Any) -> Any.Any:
    """
    Construct the optimizer specified in *config*.
    
        For known names (SGD, Adam, AdamW, Adamax, RMSprop) a base kwargs
        dict is built from ``config`` fields (``learning_rate``,
        ``weight_decay``, ``momentum``).  ``config.optimizer_kwargs`` is
        merged on top, so explicit user values always win.
    
        For any other name the class is looked up dynamically from
        ``torch.optim`` and only ``config.optimizer_kwargs`` (plus ``lr``)
        is forwarded.
    
        Args:
            model: The model whose parameters will be optimized.
            config: Training configuration.
            parameter_groups: Custom parameter iterator.  When ``None``
                (the default), ``model.parameters()`` is used.
    
        Returns:
            A configured :class:`torch.optim.Optimizer`.
    
        Raises:
            ValueError: If the optimizer name cannot be resolved.
    """
    ...

# From schedulers
def build_scheduler(optimizer: Any.Any, config: Any) -> Any | None:
    """
    Construct the LR scheduler specified in *config*.
    
        Returns ``None`` when ``config.scheduler`` is unset, giving a
        constant learning rate.
    
        For known names (StepLR, CosineAnnealingLR, ExponentialLR) a base
        kwargs dict is built from ``config`` fields.
        ``config.scheduler_kwargs`` is merged on top, so explicit user
        values always win.
    
        For any other name the class is looked up dynamically from
        ``torch.optim.lr_scheduler`` and only ``config.scheduler_kwargs``
        is forwarded.
    
        Args:
            optimizer: The optimizer whose LR will be scheduled.
            config: Training configuration.
    
        Returns:
            A configured scheduler, or ``None`` for constant LR.
    
        Raises:
            ValueError: If the scheduler name cannot be resolved.
    """
    ...

# From utils
def accuracy(output: Any, target: Any, topk: tuple[int, ...] = (1,)) -> list[float]:
    """
    Compute top-k classification accuracy.
    
        Handles the edge case where *k* exceeds the number of classes by
        clamping to ``output.size(1)`` (from the r2plus1d BYOM repo).
    
        Args:
            output: Model logits with shape ``(N, C)``.
            target: Ground-truth class indices with shape ``(N,)``.
            topk: Tuple of *k* values to compute accuracy for.
    
        Returns:
            List of accuracy values (one per *k*), each in the **[0, 1]**
            range.
    """
    ...

# From utils
def sanitise_metrics(metrics: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """
    Clean metric values for JSON serialisation.
    
        Replaces ``inf`` / ``nan`` with ``0`` and rounds floats to
        *precision* decimal places.  This is the unified version of the
        ``round_metrics`` helper duplicated in the YOLOv10, D-FINE, and
        other BYOM codebases.
    
        Args:
            metrics: Raw epoch-metrics list — each entry is a dict with at
                least a ``metricValue`` key.
            precision: Number of decimal places to round to.
    
        Returns:
            A **new** list with sanitised numeric values (the original is
            not mutated).
    """
    ...

# Classes
# From callbacks
class ActionTrackerCallback:
    # Forward per-epoch metrics and key status updates to the ActionTracker.
    #
    #     Registered by default in ``LoopTrainer`` so that every epoch's
    #     train/val metrics are recorded on the platform without any extra
    #     code in the BYOM project.

    def on_epoch_end(self: Any, trainer: Any, epoch: int, metrics: list[dict[str, Any]]) -> None:
        """
        Log epoch metrics via ``action_tracker.log_epoch_results``.
        """
        ...

    def on_train_begin(self: Any, trainer: Any) -> None:
        """
        Send the ``MDL_TRN_STR`` status to signal loop start.
        """
        ...


# From callbacks
class CheckpointCallback:
    # Save model checkpoints periodically during training.
    #
    #     By default a checkpoint is written after every epoch that improves
    #     the monitored metric.  Set ``save_every_n_epochs`` to checkpoint at
    #     a fixed cadence regardless of metric changes.
    #
    #     Args:
    #         checkpoint_dir: Directory where checkpoint files are written.
    #         monitor: Metric name that determines "best" (matched against
    #             ``metricName`` in epoch-metrics).
    #         mode: ``"min"`` or ``"max"`` — how *monitor* is compared.
    #         save_every_n_epochs: If set, save a checkpoint every *N* epochs
    #             regardless of metric improvement.  ``None`` means save only
    #             when the monitored metric improves.

    def __init__(self: Any, checkpoint_dir: str | Any = 'checkpoints', monitor: str = 'loss', mode: str = 'min', save_every_n_epochs: int | None = None) -> None:
        """
        Initialize checkpoint state.
        
                Args:
                    checkpoint_dir: Target directory for checkpoint files.
                    monitor: ``metricName`` string to track for best-model logic.
                    mode: ``"min"`` (loss-like) or ``"max"`` (accuracy-like).
                    save_every_n_epochs: Fixed checkpoint cadence, or ``None``
                        for best-only saving.
        """
        ...

    def on_epoch_end(self: Any, trainer: Any, epoch: int, metrics: list[dict[str, Any]]) -> None:
        """
        Save a checkpoint if conditions are met.
        """
        ...


# From callbacks
class EarlyStoppingCallback:
    # Stop training when a monitored metric stops improving.
    #
    #     Tracks the value of *monitor* across epochs.  If the metric does
    #     not improve by at least *min_delta* for *patience* consecutive
    #     epochs, :attr:`should_stop` is set to ``True`` and the training
    #     loop should break.
    #
    #     Args:
    #         patience: Number of epochs to wait without improvement.
    #         min_delta: Minimum change to qualify as an improvement.
    #         monitor: Metric name to watch (matched against the
    #             ``metricName`` key in the epoch-metrics list).
    #         mode: ``"min"`` treats lower values as better (e.g. loss),
    #             ``"max"`` treats higher values as better (e.g. accuracy).

    def __init__(self: Any, patience: int = 5, min_delta: float = 0.0, monitor: str = 'loss', mode: str = 'min') -> None:
        """
        Initialize early-stopping state.
        
                Args:
                    patience: Epochs without improvement before stopping.
                    min_delta: Minimum absolute improvement threshold.
                    monitor: ``metricName`` string to track in epoch metrics.
                    mode: ``"min"`` (loss-like) or ``"max"`` (accuracy-like).
        """
        ...

    def on_epoch_end(self: Any, trainer: Any, epoch: int, metrics: list[dict[str, Any]]) -> None:
        """
        Check the monitored metric and update the patience counter.
        """
        ...


# From callbacks
class TrainerCallback:
    # Base callback with no-op defaults for every hook.
    #
    #     Subclass and override only the methods you need.  Any method not
    #     overridden silently does nothing, so new hooks can be added in
    #     future releases without breaking existing callbacks.
    #
    #     Hook firing order inside ``LoopTrainer.train_loop``::
    #
    #         on_train_begin(trainer)
    #         for epoch in range(epochs):
    #             on_epoch_begin(trainer, epoch)
    #             ... train + validate ...
    #             on_epoch_end(trainer, epoch, metrics)
    #         on_train_end(trainer, result)

    def on_epoch_begin(self: Any, trainer: Any, epoch: int) -> None:
        """
        Called at the start of each epoch.
        
                Args:
                    trainer: The active ``Trainer`` instance.
                    epoch: Zero-based epoch index.
        """
        ...

    def on_epoch_end(self: Any, trainer: Any, epoch: int, metrics: list[dict[str, Any]]) -> None:
        """
        Called after training *and* validation for one epoch complete.
        
                Args:
                    trainer: The active ``Trainer`` instance.
                    epoch: Zero-based epoch index.
                    metrics: Epoch metrics in ActionTracker format — a list of
                        dicts each containing ``splitType``, ``metricName``, and
                        ``metricValue``.
        """
        ...

    def on_train_begin(self: Any, trainer: Any) -> None:
        """
        Called once before the first epoch.
        
                Args:
                    trainer: The active ``Trainer`` instance.
        """
        ...

    def on_train_end(self: Any, trainer: Any, result: Any) -> None:
        """
        Called once after the last epoch (or early-stop).
        
                Args:
                    trainer: The active ``Trainer`` instance.
                    result: The :class:`TrainResult` produced by the training loop.
        """
        ...


# From delegated_trainer
class DelegatedTrainer:
    # Trainer for framework-owned training loops.
    #
    #     Unlike :class:`~matrice_models.training.loop_trainer.LoopTrainer`,
    #     which manages the epoch loop itself, ``DelegatedTrainer`` hands
    #     control entirely to the external framework (Ultralytics, D-FINE
    #     solver, etc.).  Subclasses implement:
    #
    #     ========================  =============================================
    #     Hook                      Responsibility
    #     ========================  =============================================
    #     launch_training           Call the framework's train API, return result
    #     get_best_checkpoint_path  Return the path to the best model file
    #     ========================  =============================================
    #
    #     The remaining hooks (``setup_data``, ``setup_model``,
    #     ``get_label_map``, ``run_evaluation``) are inherited from
    #     :class:`Trainer`.
    #
    #     Callback support is intentionally limited — frameworks like
    #     Ultralytics have their **own** callback system.  The
    #     ``on_train_begin`` / ``on_train_end`` hooks still fire, but
    #     per-epoch hooks (``on_epoch_begin``, ``on_epoch_end``) should
    #     be wired through the framework's native callbacks instead.

    def __init__(self: Any, action_id: str | None, model_info: Any, config: Any) -> None:
        """
        Initialise the delegated trainer.
        
                Args:
                    action_id: Platform action ID (``None`` for local runs).
                    model_info: Model identity and capabilities.
                    config: Training hyperparameters.
                    checkpoint_dir: Directory for checkpoint files (note:
                        the framework may write checkpoints to its own
                        location — see :meth:`get_best_checkpoint_path`).
                    callbacks: Optional list of callbacks.
        """
        ...

    def get_best_checkpoint_path(self: Any) -> Any | None:
        """
        Return the path to the framework's best model checkpoint.
        
                Frameworks typically save their own checkpoints in a
                framework-specific location (e.g. Ultralytics writes to
                ``runs/detect/train/weights/best.pt``).  This method tells
                the trainer where to find that file for upload.
        
                Returns:
                    Path to the best checkpoint file, or ``None`` if not
                    available.
        
                Example::
        
                    def get_best_checkpoint_path(self) -> Path:
                        return Path("runs/detect/train/weights/best.pt")
        """
        ...

    def launch_training(self: Any) -> Any:
        """
        Call the framework's training API and return results.
        
                This is where the framework takes full control.  The
                implementation should:
        
                1. Call the framework's train method (e.g. ``model.train()``,
                   ``solver.fit()``).
                2. Collect final metrics from the framework's results.
                3. Build and return a :class:`TrainResult`.
        
                The base trainer handles ActionTracker status updates *around*
                this call — no need to send ``MDL_TRN_STR`` / ``MDL_TRN_CMPL``
                manually.
        
                Returns:
                    A :class:`TrainResult` populated with the training outcome.
        
                Example (Ultralytics)::
        
                    def launch_training(self) -> TrainResult:
                        results = self.model.train(
                            data=self.data_yaml,
                            epochs=self.config.epochs,
                        )
                        return TrainResult(
                            best_metric_name="mAP50",
                            best_metric_value=results.results_dict["metrics/mAP50(B)"],
                            best_epoch=0,
                            epochs_completed=self.config.epochs,
                        )
        """
        ...

    def register_framework_callbacks(self: Any) -> None:
        """
        Register callbacks with the framework's own callback system.
        
                Override this to wire framework-native callbacks for per-epoch
                logging.  Called once before :meth:`launch_training`.
        
                Example (Ultralytics)::
        
                    def register_framework_callbacks(self) -> None:
                        self.model.add_callback("on_fit_epoch_end", self._log_yolo_epoch)
        """
        ...

    def save_model(self: Any) -> None:
        """
        Upload the framework's best checkpoint to the platform.
        
                Uses :meth:`get_best_checkpoint_path` to locate the file.
                Falls back to the base class implementation if no path is
                returned.
        """
        ...

    def train_loop(self: Any) -> None:
        """
        Delegate training to the framework and collect results.
        
                Lifecycle::
        
                    register_framework_callbacks()
                    on_train_begin
                    launch_training()  →  TrainResult
                    on_train_end(result)
        
                Populates ``self._result`` before returning.
        """
        ...


# From early_stopping
class EarlyStopping:
    # Stop training when validation loss stops improving.
    #
    #     Tracks the lowest observed loss.  If the loss does not decrease by
    #     at least *min_delta* for *patience* consecutive calls to
    #     :meth:`update`, the :attr:`stop` flag is set to ``True``.
    #
    #     Example::
    #
    #         es = EarlyStopping(patience=10, min_delta=0.001)
    #         for epoch in range(max_epochs):
    #             loss = train_and_validate(...)
    #             es.update(loss)
    #             if es.stop:
    #                 break
    #
    #     Args:
    #         patience: Number of updates without improvement before stopping.
    #         min_delta: Minimum decrease in loss to count as an improvement.

    def __init__(self: Any, patience: int = 5, min_delta: float = 0.001) -> None:
        """
        Initialize early-stopping state.
        
                Args:
                    patience: Number of updates without improvement before stopping.
                    min_delta: Minimum decrease in loss to count as an improvement.
        """
        ...

    def reset(self: Any) -> None:
        """
        Reset internal state so the instance can be reused.
        """
        ...

    def update(self: Any, val_loss: float) -> None:
        """
        Record a new validation loss and check whether to stop.
        
                Args:
                    val_loss: Current epoch's validation loss.
        """
        ...


# From loop_trainer
class LoopTrainer:
    # Trainer with a standard PyTorch epoch loop.
    #
    #     Subclasses implement four extra hooks beyond the ones inherited from
    #     :class:`Trainer`:
    #
    #     ==================  ======================================================
    #     Hook                Responsibility
    #     ==================  ======================================================
    #     configure_criterion Return the loss function (e.g. ``nn.CrossEntropyLoss``)
    #     configure_optimizer Return the optimiser for ``self.model``
    #     train_one_epoch     Run one training epoch, return a flat metrics dict
    #     validate_one_epoch  Run one validation epoch, return a flat metrics dict
    #     ==================  ======================================================
    #
    #     Optionally override :meth:`configure_scheduler` to add a learning-rate
    #     schedule.
    #
    #     The built-in :meth:`train_loop` then orchestrates:
    #
    #     1. Criterion / optimiser / scheduler creation.
    #     2. ``on_train_begin`` callback.
    #     3. Per-epoch: ``on_epoch_begin`` → train → validate → scheduler step
    #        → format metrics → ``on_epoch_end`` → checkpoint → early-stop check.
    #     4. ``on_train_end`` callback and :class:`TrainResult` population.

    def __init__(self: Any, action_id: str | None, model_info: Any, config: Any) -> None:
        """
        Initialise the loop trainer.
        
                Args:
                    action_id: Platform action ID (``None`` for local runs).
                    model_info: Model identity and capabilities.
                    config: Training hyperparameters.
                    checkpoint_dir: Directory for checkpoint files.
                    callbacks: Optional list of callbacks.  Defaults to
                        ``[ActionTrackerCallback()]``.
                    monitor: Validation metric to track for *best model*
                        selection.  Must match a key returned by
                        :meth:`validate_one_epoch`.
                    monitor_mode: ``"max"`` when higher is better (accuracy)
                        or ``"min"`` when lower is better (loss).
        """
        ...

    def configure_criterion(self: Any) -> Any.Any:
        """
        Return the loss function.
        
                Called once before the epoch loop begins.  The returned module
                is stored as ``self.criterion`` so :meth:`train_one_epoch` and
                :meth:`validate_one_epoch` can access it.
        
                Example::
        
                    def configure_criterion(self) -> nn.Module:
                        return nn.CrossEntropyLoss().to(self.device)
        """
        ...

    def configure_optimizer(self: Any) -> Any.Any:
        """
        Return the optimiser for ``self.model``.
        
                Called once after ``setup_model`` has populated ``self.model``
                and the device has been resolved.  The returned optimiser is
                stored as ``self.optimizer``.
        
                Example::
        
                    def configure_optimizer(self) -> optim.Optimizer:
                        return torch.optim.AdamW(
                            self.model.parameters(),
                            lr=self.config.learning_rate,
                        )
        """
        ...

    def configure_scheduler(self: Any) -> Any | None:
        """
        Return an optional learning-rate scheduler.
        
                Called once after :meth:`configure_optimizer`.  The default
                returns ``None`` (constant LR).  Override to add e.g.
                ``StepLR``, ``CosineAnnealingLR``, etc.
        
                Returns:
                    A scheduler instance, or ``None`` for constant LR.
        
                Example::
        
                    def configure_scheduler(self) -> LRScheduler:
                        return torch.optim.lr_scheduler.StepLR(
                            self.optimizer,
                            step_size=30,
                            gamma=0.1,
                        )
        """
        ...

    def train_loop(self: Any) -> None:
        """
        Execute the standard PyTorch training loop.
        
                Lifecycle::
        
                    configure_criterion → configure_optimizer → configure_scheduler
                    on_train_begin
                    for epoch in range(epochs):
                        on_epoch_begin
                        train_one_epoch  →  validate_one_epoch  →  scheduler.step()
                        format_metrics → on_epoch_end → log_epoch → checkpoint → early_stop?
                    on_train_end(result)
        
                Populates ``self._result`` before returning.
        """
        ...

    def train_one_epoch(self: Any, epoch: int) -> dict[str, float]:
        """
        Run one training epoch and return metrics.
        
                Typical implementations iterate ``self.train_loader``, compute
                the forward/backward pass, and accumulate metrics.
        
                The trainer guarantees that ``self.model``, ``self.criterion``,
                ``self.optimizer``, and ``self.device`` are already set.
        
                Args:
                    epoch: Zero-based epoch index.
        
                Returns:
                    Flat dict of metric values, e.g.
                    ``{"loss": 0.45, "acc@1": 0.82, "acc@5": 0.96}``.
        """
        ...

    def validate_one_epoch(self: Any, epoch: int) -> dict[str, float]:
        """
        Run one validation epoch and return metrics.
        
                Similar to :meth:`train_one_epoch` but in ``torch.no_grad()``
                mode and without gradient updates.
        
                Args:
                    epoch: Zero-based epoch index.
        
                Returns:
                    Flat dict of metric values, e.g.
                    ``{"loss": 0.52, "acc@1": 0.78, "acc@5": 0.94}``.
                    Return an **empty dict** if no validation set exists.
        """
        ...


# From trainer
class TrainResult:
    # Output of a completed training run.
    #
    #     Captures the best metric achieved, the number of epochs that ran,
    #     saved checkpoint paths, and the evaluation payload that was (or will
    #     be) sent to ActionTracker.

    ...

# From trainer
class Trainer:
    # Abstract base for all BYOM training jobs.
    #
    #     Modelled after AWS SageMaker's ``Estimator``: call :meth:`fit` and
    #     the full lifecycle — data loading, model initialisation, training,
    #     checkpointing, evaluation — runs with ActionTracker status updates
    #     at every phase.
    #
    #     Subclass one of the concrete variants instead of this class directly:
    #
    #     * ``LoopTrainer`` — you own the PyTorch for-loop
    #       (classification, R2Plus1D).
    #     * ``DelegatedTrainer`` — the framework owns the loop
    #       (Ultralytics YOLO, D-FINE solver).
    #
    #     Each subclass only implements a handful of hooks; all boilerplate
    #     (ActionTracker wiring, error handling, checkpoint upload) is handled
    #     here.
    #
    #     Example::
    #
    #         class MyTrainer(LoopTrainer):
    #             def setup_data(self) -> None: ...
    #             def setup_model(self) -> None: ...
    #
    #             ...
    #
    #
    #         trainer = MyTrainer(action_id, model_info, config)
    #         result = trainer.fit()

    def __init__(self: Any, action_id: str | None, model_info: Any, config: Any) -> None:
        """
        Initialize the trainer.
        
                Args:
                    action_id: Platform action ID.  Pass ``None`` for local /
                        offline runs (a ``LocalActionTracker`` or no-op stub
                        will be created automatically).
                    model_info: Model identity and capabilities.
                    config: Training hyperparameters.
                    checkpoint_dir: Directory where checkpoints are written.
                    callbacks: Optional list of :class:`TrainerCallback`
                        instances.  When ``None`` the default set
                        (``ActionTrackerCallback``) is registered automatically.
        """
        ...

    def fit(self: Any) -> Any:
        """
        Run the full training lifecycle.
        
                This is the single entry-point, analogous to
                ``sagemaker.estimator.Estimator.fit()``.  The phases are:
        
                1. **Acknowledge** — ``MDL_TRN_ACK``
                2. **Data loading** — ``MDL_TRN_DTL``
                3. **Model init** — ``MDL_TRN_MDL``
                4. **Training loop** — ``MDL_TRN_CMPL``
                5. **Checkpoint upload** — ``MDL_TRN_BMS``
                6. **Evaluation** — ``MDL_TRN_EVL``
        
                Each phase is wrapped in ActionTracker status updates.  On
                failure the tracker receives an ``ERROR`` status and a
                :class:`TrainerError` is raised.
        
                Returns:
                    A :class:`TrainResult` summarising the completed run.
        
                Raises:
                    TrainerError: If any lifecycle phase fails.
        """
        ...

    def get_label_map(self: Any) -> dict[str, str]:
        """
        Return an index-to-label mapping for the ActionTracker.
        
                Returns:
                    Dict mapping **string** class indices to human-readable
                    class names, e.g. ``{"0": "cat", "1": "dog"}``.
        """
        ...

    def get_model_load_strategies(self: Any) -> Any | None:
        """
        Optionally provide shared model-loading strategies.
        
                Returns:
                    ``ModelLoadStrategies`` to enable automatic model-loading in
                    :meth:`_do_setup_model`, or ``None`` to use subclass
                    :meth:`setup_model` behavior.
        """
        ...

    def load_model_with_strategies(self: Any, strategies: Any) -> Any:
        """
        Load model using ActionTracker checkpoint/predefined strategy.
        
                Args:
                    strategies: Strategy callbacks for checkpoint/predefined/scratch branches.
        
                Returns:
                    Loaded model artifact selected from the first available branch.
        """
        ...

    def log_epoch(self: Any, epoch: int, metrics: list[dict[str, Any]]) -> None:
        """
        Forward per-epoch metrics to the ActionTracker.
        
                Called by ``LoopTrainer`` (or your own loop) at the end of each
                epoch.  Override to add side-channels such as TensorBoard or
                Weights & Biases logging.
        
                Args:
                    epoch: Zero-based epoch number.
                    metrics: List of metric dicts, each containing at minimum
                        ``splitType``, ``metricName``, and ``metricValue``.
        """
        ...

    def notify(self: Any, hook: str, *args: Any, **kwargs: Any) -> None:
        """
        Fire a named callback hook on every registered callback.
        
                Exceptions from individual callbacks are logged but do **not**
                interrupt the training loop.
        
                Args:
                    hook: Method name to invoke (e.g. ``"on_epoch_end"``).
                    *args: Positional arguments forwarded to the hook.
                    **kwargs: Keyword arguments forwarded to the hook.
        """
        ...

    def run_evaluation(self: Any) -> list[dict[str, Any]]:
        """
        Run post-training evaluation and return the results payload.
        
                The returned list is forwarded to
                ``action_tracker.save_evaluation_results()``.
        
                Returns:
                    Metric dicts in ActionTracker format::
        
                        [{"splitType": "val", "metricName": "acc@1", "metricValue": 0.95, "category": "all"}, ...]
        """
        ...

    def save_model(self: Any) -> None:
        """
        Save the best model and upload checkpoints to the platform.
        
                The default implementation uploads ``model_best.pth.tar`` and
                ``model_best.pt`` from :attr:`checkpoint_dir`.  If the ``.pt``
                file does not exist but ``self.model`` is set, it is serialised
                with ``torch.save`` first.
        
                Override for frameworks that use a different checkpoint layout
                (e.g. Ultralytics writes to ``runs/detect/train/weights/``).
        """
        ...

    def setup_data(self: Any) -> None:
        """
        Load datasets and create data loaders.
        
                Implementations should store loaders as instance attributes
                (e.g. ``self.train_loader``) so that :meth:`train_loop` and
                :meth:`run_evaluation` can access them.
        """
        ...

    def setup_model(self: Any) -> None:
        """
        Construct or load the model and assign it to ``self.model``.
        
                The compute device is resolved automatically *after* this hook
                returns.  Moving the model to the device is the responsibility
                of the subclass (in this hook or in :meth:`train_loop`), because
                different frameworks handle device placement differently.
        
                For checkpoint/predefined selection flows, subclasses can use
                :meth:`load_model_with_strategies`.
        """
        ...

    def train_loop(self: Any) -> None:
        """
        Execute the main training loop.
        
                ``LoopTrainer`` provides a standard PyTorch epoch-loop.
                ``DelegatedTrainer`` delegates to the framework's own API.
        
                **Contract:** implementations *must* populate ``self._result``
                (a :class:`TrainResult`) before returning.
        """
        ...


# From trainer
class TrainerError(Exception):
    # Raised when a training lifecycle phase fails.
    #
    #     Attributes:
    #         phase: The ActionTracker status code of the failed phase
    #             (e.g. ``"MDL_TRN_DTL"``).

    def __init__(self: Any, phase: str, message: str) -> None:
        """
        Initialize with the failing phase and error message.
        
                Args:
                    phase: ActionTracker status code (e.g. ``MDL_TRN_DTL``).
                    message: Human-readable description of the failure.
        """
        ...


# From utils
class AverageMeter:
    # Running average tracker for a single scalar metric.
    #
    #     Commonly used to track loss and accuracy across mini-batches within
    #     an epoch.
    #
    #     Example::
    #
    #         losses = AverageMeter("Loss")
    #         for inputs, targets in loader:
    #             loss = criterion(model(inputs), targets)
    #             losses.update(loss.item(), n=inputs.size(0))
    #         print(losses)  # Loss 0.3420 (0.4567)
    #         print(losses.avg)  # 0.4567
    #
    #     Args:
    #         name: Human-readable label shown in ``__str__``.
    #         fmt: Format spec for ``val`` and ``avg`` (default ``":f"``).

    def __init__(self: Any, name: str = '', fmt: str = ':f') -> None:
        """
        Initialise the meter.
        
                Args:
                    name: Display name for :meth:`__str__`.
                    fmt: Float format spec (e.g. ``":.4f"``, ``":.2e"``).
        """
        ...

    def reset(self: Any) -> None:
        """
        Zero all accumulators.
        """
        ...

    def update(self: Any, val: float, n: int = 1) -> None:
        """
        Record *n* observations with value *val*.
        
                Args:
                    val: Per-sample (or per-batch-mean) value.
                    n: Number of observations this value represents
                        (typically ``batch_size``).
        """
        ...


from . import callbacks, checkpoint, delegated_trainer, device, early_stopping, loop_trainer, model_loader, optimizers, schedulers, trainer, utils