diff --git a/ax/core/runner.py b/ax/core/runner.py index 39d71ed99f8..89f2bdbed86 100644 --- a/ax/core/runner.py +++ b/ax/core/runner.py @@ -10,7 +10,8 @@ from abc import ABC, abstractmethod from collections.abc import Iterable -from typing import Any, Self, TYPE_CHECKING +from dataclasses import dataclass +from typing import Any, ClassVar, Self, TYPE_CHECKING from ax.utils.common.base import Base from ax.utils.common.serialization import SerializationMixin @@ -21,9 +22,27 @@ from ax import core # noqa F401 +class RunnerConfig: + @dataclass(frozen=True) + class SearchSpaceUpdateArguments: + """Base arguments for search space updates. Override in RunnerConfig + subclasses to add runner-specific fields.""" + + pass + + @dataclass(frozen=True) + class RunnerUpdateArguments: + """Base arguments for general runner updates. Override in RunnerConfig + subclasses to add runner-specific fields.""" + + pass + + class Runner(Base, SerializationMixin, ABC): """Abstract base class for custom runner classes""" + config_type: ClassVar[type[RunnerConfig]] = RunnerConfig + @property def staging_required(self) -> bool: """Whether the trial goes to staged or running state once deployed.""" diff --git a/ax/utils/common/sentinel.py b/ax/utils/common/sentinel.py new file mode 100644 index 00000000000..2b8a7ca3f39 --- /dev/null +++ b/ax/utils/common/sentinel.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# pyre-strict + + +class Unset: + """Sentinel type for distinguishing "not provided" from an explicit ``None``. + + Use the module-level ``UNSET`` instance as the default value for + optional fields where ``None`` is a valid, meaningful value and a + separate "not set" state is needed. + """ + + def __repr__(self) -> str: + return "UNSET" + + +UNSET: Unset = Unset()