Add a Module or Pipe
A module or pipe is the executable runtime unit selected by metric_configs[*].pipe_name. This is the right layer for a new metric, judge behavior, or other callable block that the pipeline should execute directly.
Add the Class and Register It
Pipe implementations live under src/autopipeline/components/modules/.
Minimal pattern:
from . import BasePipe, PIPE_REGISTRY
@PIPE_REGISTRY.register("my-pipe")
class MyPipe(BasePipe):
def __init__(self, **kwargs):
super().__init__(**kwargs)
...
def __call__(self, ...):
...
After adding the file, import it in src/autopipeline/components/modules/__init__.py. Without that import, the registry will never see the new pipe.
Decide the Runtime Contract Up Front
The correct __call__ signature depends on the target pipeline family.
Typical call patterns are:
object-centricref_image,edited_image,coords,mask_mode,metric, plusruntime_paramshuman-centriccropped human images, masks, face boxes,metric, and region-dependent runtime parametersvlm-as-a-judgethe normalized input dictionary rather than image pairs plus coords
Do not design the pipe in isolation. Start from the pipeline call site you intend to support.
Expose Constructor Defaults
If the pipe has reusable init-time parameters, add them to:
configs/pipelines/modules_init/pipes_default.yaml
Then consume them from pipeline YAML:
metric_configs:
my_metric:
pipe_name: my-pipe
default_config: ${pipes_default.my-pipe}
init_config:
scope: edit_area
runtime_params:
threshold: 0.2
ConfigEngine merges default_config and init_config before the class is instantiated, so the constructor receives only the final merged init_config.
Keep metric and pipe_name Separate in Your Design
One pipe can serve several metrics.
That is already a core framework pattern:
- the YAML key under
metric_configsbecomes the runtimemetricargument pipe_nameselects the class
This is why one pipe can branch internally on several metric names without forcing you to duplicate the implementation class.
Be Careful with Shared Pipe Instances
Inside a pipeline runtime, pipes are cached by:
pipe_name- merged
init_config
If two metrics reference the same pipe with the same init config, they will share one instance.
That means a pipe should generally avoid storing mutable per-metric runtime state on self. Treat runtime_params and the metric argument as the per-call surface instead.
Human-Centric and Parser-Grounder Caveats
Two areas need extra care:
- human-centric metrics may be skipped unless they are consistent with the measurement rubric and region routing used by
human_centric.py parser-grounderis not just another metric pipe; it is loaded explicitly as a pre-step by the current region-aware pipeline families
If your new pipe depends on new region semantics, you may need both a new pipe and a small pipeline change.
Validation Checklist
- import the new file from
modules/__init__.py - confirm the registry key resolves
- add one minimal entry to
pipes_default.yamlif the pipe needs init args - add one minimal
metric_configsentry to a real pipeline YAML - run one sample through the target pipeline family
- confirm the emitted score shape and
Nonebehavior are intentional