> For the complete documentation index, see [llms.txt](https://docs.eyepop.ai/developer-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eyepop.ai/developer-documentation/platform/pop/pop-components.md).

# Components

Every Pop component type and the attributes it accepts

The component types a [Pop](/developer-documentation/platform/pop.md) can contain, and every attribute each one accepts. For how components chain together, see [Forwarding](/developer-documentation/platform/pop/pop-forwarding.md).

### Component types

| `type`             | Purpose                                                              | Runs inference |
| ------------------ | -------------------------------------------------------------------- | -------------- |
| `inference`        | Run an ability or model and emit predictions.                        | yes            |
| `tracking`         | Assign stable `trackId`s to detections across video frames.          | yes            |
| `forward`          | Route media and predictions onward without analyzing them.           | no             |
| `contour_finder`   | Turn segmentation masks into contours.                               | no             |
| `component_finder` | Split segmentation masks into sub-objects with connected components. | no             |

### Attributes every component shares

| Attribute | Type    | Description                                                                                                                                                                                                                                                                                                                                                                                               |
| --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`    | string  | One of the types above. Required. An unrecognized value is rejected.                                                                                                                                                                                                                                                                                                                                      |
| `id`      | integer | Stable identifier for this component. Assigned automatically from `1` upward when omitted. Must be unique within the Pop — a collision is rejected with `id N is not unique`.                                                                                                                                                                                                                             |
| `forward` | object  | Where this component's output goes next. See [Forwarding](/developer-documentation/platform/pop/pop-forwarding.md).                                                                                                                                                                                                                                                                                       |
| `toWorld` | boolean | Enrich this component's point-based predictions with world coordinates, back-projected through the Pop's [`depthMap`](/developer-documentation/platform/pop/pop-object.md). Only `inference` and `tracking` honour it; asking for it on any other type is rejected when the Pop is compiled. See [World Coordinates](/developer-documentation/platform/depth-and-world-coordinates/world-coordinates.md). |

Every component type can forward, including the ones that run no inference. That is what lets a Pop tee one stage into several, or chain a finder into further analysis.

### `inference`

Runs one ability or model over the media it receives and attaches structured predictions to the result.

An inference component must name exactly one ability. `ability` and `abilityUuid` are the current spellings; `model` and `modelUuid` are the older ones, still accepted and marked deprecated in the Python SDK. Naming none is rejected, and naming both an alias and a uuid is rejected.

| Attribute                 | Type    | Description                                                                                                                                                                                                                                                  | SDK                                |
| ------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- |
| `ability`                 | string  | Ability alias with a tag, e.g. `eyepop.person:latest`. See [Models](/developer-documentation/platform/models.md).                                                                                                                                            | both                               |
| `abilityUuid`             | string  | Ability by uuid, for a custom trained model.                                                                                                                                                                                                                 | both                               |
| `model`                   | string  | Deprecated spelling of `ability`.                                                                                                                                                                                                                            | both                               |
| `modelUuid`               | string  | Deprecated spelling of `abilityUuid`.                                                                                                                                                                                                                        | both                               |
| `inferenceTypes`          | list    | Narrows what the ability is run for. Resolved from the ability when omitted, so most Pops leave it unset. Values: `image_classification`, `object_detection`, `key_points`, `ocr`, `mesh`, `feature_vector`, `semantic_segmentation`, `segmentation`, `raw`. | `raw` is missing from the Node SDK |
| `categoryName`            | string  | Tags every prediction from this component with a category name, so results from several components stay distinguishable.                                                                                                                                     | both                               |
| `confidenceThreshold`     | float   | Drops predictions below this confidence, overriding the ability's default.                                                                                                                                                                                   | both                               |
| `objectAreaThreshold`     | float   | Drops detections smaller than this fraction of the frame.                                                                                                                                                                                                    | missing from the Node SDK          |
| `topK`                    | integer | Keeps only the highest-scoring *N* predictions.                                                                                                                                                                                                              | both                               |
| `topKClasses`             | integer | Keeps only the highest-scoring *N* classes per prediction.                                                                                                                                                                                                   | both                               |
| `multiClass`              | boolean | Allows one detection to carry several class labels.                                                                                                                                                                                                          | **neither SDK** — wire only        |
| `targetFps`               | string  | Samples video at this rate for this component, as a fraction of integers, e.g. `"3/2"`. Independent of the source's own [`fps`](/developer-documentation/platform/sources-and-options/options/frame-rate.md).                                                | both                               |
| `videoChunkLengthSeconds` | float   | For abilities that reason over a span of video, the length of each chunk.                                                                                                                                                                                    | both                               |
| `videoChunkOverlap`       | float   | How much consecutive chunks overlap.                                                                                                                                                                                                                         | both                               |
| `hidden`                  | boolean | Keeps this component's predictions out of the response while still feeding downstream components. See [Hiding intermediate stages](#hiding-intermediate-stages).                                                                                             | both                               |
| `params`                  | object  | Parameters passed through to abilities that accept them — prompts for a vision-language ability, for instance.                                                                                                                                               | both                               |

#### Prompting an ability

Abilities backed by a vision-language model take their instruction through `params`:

```json
{
    "type": "inference",
    "ability": "eyepop.localize-objects:latest",
    "params": { "prompts": [{ "prompt": "forklift" }] }
}
```

#### Hiding intermediate stages

Real pipelines often need a stage the caller never asked to see — a face detector that exists only to feed expression analysis. Setting `hidden` on it keeps its predictions out of the response, and what that means depends on what the component produces:

| The component produces                | `hidden` does                                                                                                                     |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| object detections                     | Predictions are withheld from the response but still forwarded downstream, and downstream results attach to the enclosing object. |
| segmentation or semantic segmentation | Masks are merged into the object that fed the component rather than returned separately.                                          |
| anything else                         | Predictions are dropped from the response entirely.                                                                               |

### `tracking`

Re-identifies objects across video frames so the same object carries the same `trackId` from frame to frame. Place it on a forward from the detector whose objects you want tracked.

Tracking is trajectory-based by default. Naming a re-identification ability adds appearance similarity — `eyepop.person.reid:latest` is the usual choice for people.

| Attribute                           | Type    | Description                                                                                                |
| ----------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `reidModel`                         | string  | Re-identification ability by alias. Omit for trajectory-only tracking.                                     |
| `reidModelUuid`                     | string  | Re-identification ability by uuid. Mutually exclusive with `reidModel`.                                    |
| `maxAgeSeconds`                     | float   | How long an unmatched trace is kept before it is retired. Does not cap the length of a matched trace.      |
| `iouThreshold`                      | float   | Minimum overlap for a detection to join a trace that similarity did not already match.                     |
| `simThreshold`                      | float   | Minimum appearance similarity for a detection to join a trace.                                             |
| `agnostic`                          | boolean | Matches across class labels instead of tracking each class separately.                                     |
| `motionModel`                       | string  | `random_walk`, `constant_velocity`, or `constant_acceleration`. Match it to how the objects actually move. |
| `downweightLowConfidenceDetections` | boolean | Lets weak detections extend a trace without pulling it as hard as a confident one.                         |

The Kalman filter's noise terms are exposed for tuning when the defaults track poorly — `processNoisePosition`, `processNoiseVelocity`, `processNoiseAcceleration`, `processNoiseScale`, `processNoiseAspectRatio`, `measurementNoiseCx`, `measurementNoiseCy`, `measurementNoiseArea`, and `measurementNoiseAspectRatio`. Raising a process-noise term tells the tracker to trust its motion prediction less; raising a measurement-noise term tells it to trust the detector less.

When a tracked object's class label flickers between frames, class hysteresis holds the label steady: `classHysteresis` turns it on, `classHysteresisHighThreshold` and `classHysteresisLowThreshold` set the confidences to switch at, `classHysteresisMinHoldFrames` sets how long a label must hold before it can change again, and `classHysteresisAllowedClasses` restricts which labels participate. `classBeta` and `classGamma` weight how class agreement contributes to matching.

### `contour_finder`

Converts segmentation masks into contours.

| Attribute       | Type   | Description                                                                                                                                                                                              |
| --------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contourType`   | string | The shape to fit. Optional — defaults to `polygon`. One of `polygon`, `all_pixels`, `convex_hull`, `hough_circles`, `circle`, `triangle`, or `rectangle`.                                                |
| `areaThreshold` | float  | Discards contours covering less than this fraction of the source's total pixels — `0.01` drops anything under 1% of the source. Applies to `polygon` and `all_pixels` only; the fitted shapes ignore it. |

Contours always come back as polygons, even for `circle` and `rectangle`. `all_pixels` and `polygon` can contain cut-outs; the fitted shapes cannot.

### `component_finder`

Splits one segmentation mask into separate sub-objects using connected components — the way to turn a single "cell colony" mask into a count of individual cells.

| Attribute             | Type    | Description                                                                              |
| --------------------- | ------- | ---------------------------------------------------------------------------------------- |
| `componentClassLabel` | string  | Class label applied to each sub-object found. Defaults to the source object's own label. |
| `erode`               | float   | Shrinks the mask before splitting. `0.0`–`1.0`, default `0.0` (off).                     |
| `dilate`              | float   | Grows the mask before splitting. `0.0`–`1.0`, default `0.0` (off).                       |
| `keepSource`          | boolean | Keeps the original mask in the result alongside the sub-objects.                         |

#### How `erode` and `dilate` reshape the mask

Both are classic morphological operations applied to the mask **before** components are counted, so they change how many sub-objects you get.

* **`erode`** peels pixels off the mask's edges. Thin bridges between blobs that are really separate objects break, and each blob shrinks. This is what turns one mask of touching cells into a count of individual cells.
* **`dilate`** adds pixels around the mask's edges. Nearby fragments merge, and gaps and pinholes close. This is what stops one speckled object from being counted as many.

Two details decide what a value actually does:

**The value is a fraction of the mask's own size, not the frame's.** Each kernel axis is `round(factor × mask_extent ÷ 2)` pixels, so `0.1` on a mask 200 pixels wide gives a kernel 10 pixels across. Because it scales with the mask, the same factor behaves consistently on objects of different sizes. The kernel is elliptical, so the effect is even in all directions rather than boxy.

A factor small enough to round either axis below one pixel is treated as a no-op rather than a smaller kernel — both axes decide that together, so a sub-pixel request never applies to one axis only because the mask happens to be tall and narrow.

**Order is fixed: `erode` runs first, then `dilate`.** Setting both is therefore a morphological *opening*: erosion severs the thin connections and drops specks, then dilation restores the surviving blobs to roughly their original size. That is usually what you want for counting — separation without shrinking everything you kept. Setting them expecting dilation to undo the erosion will not work; the pixels erosion removed are gone before dilation runs.

Start with `erode` alone when objects are merged, `dilate` alone when one object is fragmenting into several, and both when you need separation without losing size.

### `forward`

Carries media and predictions onward without analyzing them. Every other component type inherits forwarding, so a dedicated `forward` component is only needed to tee one stage into several branches, or as a Pop's single pass-through component.

It has no attributes of its own beyond [the shared ones](#attributes-every-component-shares).

### Next steps

* [Forwarding](/developer-documentation/platform/pop/pop-forwarding.md) — chaining these components, and what each one receives
* [Examples](/developer-documentation/platform/pop/pop-examples.md) — worked pipelines end to end
* [Models](/developer-documentation/platform/models.md) — the pretrained and custom models to name in an inference component
