Source code for phenotypic.tune._search_space._discovery

"""Discovery catalog: the structured set of tunable parameters in a pipeline.

``pipeline_targets`` re-surfaces ``infer_search_space``'s mining as per-parameter
descriptors (each target ``op_class``-stamped) for the GUI 6c form and the MCP
"what can I tune?" tool — the agent *selects* a target rather than authoring a
key. Imports ``_infer`` (and is NOT imported by ``_space``), so the
``_space -> _targets`` edge stays cycle-free.
"""
from __future__ import annotations

from typing import Any, Literal, Optional

from pydantic import BaseModel, ConfigDict

from ._domains import Categorical, Domain, FloatRange, IntRange
from ._infer import infer_search_space
from ._targets import KnobTarget, Nested, Param, Presence

#: The value-type of a tunable parameter (named ``value_type`` — not ``kind`` —
#: to avoid colliding with the target union's ``kind`` discriminator).
ValueType = Literal["float", "int", "bool", "categorical"]


[docs] class TunableParam(BaseModel): """One tunable parameter a pipeline exposes (a discovery descriptor). Args: target: The structured ``KnobTarget`` to reference it by (``op_class`` always set). op_class: The class of the op at ``target.op``. value_type: The parameter's value type. default: The field's current value on the pipeline. suggested_domain: The inferred domain, or ``None`` if inference excluded it. description: The field's docstring / ``TuneSpec`` text. needs_review: Whether inference flagged the suggested domain for review. """ model_config = ConfigDict(frozen=True) target: KnobTarget op_class: str value_type: ValueType default: Any suggested_domain: Optional[Domain] description: str needs_review: bool
def _value_type(domain: Domain) -> ValueType: if isinstance(domain, FloatRange): return "float" if isinstance(domain, IntRange): return "int" if isinstance(domain, Categorical) and all(isinstance(c, bool) for c in domain.choices): return "bool" return "categorical" def _current_value(target: KnobTarget, ordered_ops: list) -> Any: op = ordered_ops[target.op] if isinstance(target, Param): return getattr(op, target.field, None) if isinstance(target, Presence): return True # an op present in the base pipeline is enabled if isinstance(target, Nested): nested = getattr(op, target.field, None) if isinstance(nested, list) and 0 <= target.index < len(nested) and nested[target.index] is not None: return getattr(nested[target.index], target.leaf, None) return None
[docs] def pipeline_targets(pipeline: Any) -> list[TunableParam]: """The structured catalog of tunable parameters in ``pipeline``. Built on ``infer_search_space`` (each knob's target already ``op_class``- stamped); each knob becomes a ``TunableParam`` carrying the field's current value, inferred domain, value type, description, and review flag. Args: pipeline: A live ``ImagePipeline``. Returns: One ``TunableParam`` per inferred knob, in proposal order. """ proposal = infer_search_space(pipeline) ordered_ops = list(pipeline.get_ops().values()) return [ TunableParam( target=knob.target, op_class=knob.target.op_class or type(ordered_ops[knob.target.op]).__name__, value_type=_value_type(knob.domain), default=_current_value(knob.target, ordered_ops), suggested_domain=knob.domain, description=knob.description, needs_review=knob.needs_review, ) for knob in proposal.knobs ]