We write your reusable computer vision tools. π
# Agent Guidelines for `supervision`
Behave like a senior contributor: precise, efficient, maintainable. When this file and [CONTRIBUTING.md](.github/CONTRIBUTING.md) conflict, **CONTRIBUTING.md wins**.
______________________________________________________________________
## 1. Before You Code
- Read the task thoroughly; group clarifications into one ask.
- Outline a plan before making changes.
- Check whether the feature already exists under a different name.
- Confirm alignment with `src/supervision/` architecture.
______________________________________________________________________
## 2. Repository Architecture
**Package root**: `src/supervision/` β all library code. **Tests**: `tests/` β mirrors `src/supervision/`. **Public API**: `src/supervision/__init__.py`.
```
src/supervision/
βββ detection/
β βββ core.py β Detections dataclass; all model connectors as classmethods
β βββ compact_mask.py β compact mask representation
β βββ vlm.py β VLM connectors (Florence-2, Gemini, Qwen, PaliGemma)
β βββ utils/ β pure NumPy helpers: boxes, converters, iou_and_nms, masks, polygons
β βββ line_zone.py β LineZone
β βββ tools/ β InferenceSlicer, PolygonZone, CSVSink, JSONSink, DetectionsSmoother
βββ annotators/core.py β BoxAnnotator, MaskAnnotator, LabelAnnotator, β¦ each: .annotate(scene, detections)
βββ key_points/ β KeyPoints, EdgeAnnotator, VertexAnnotator (use this, NOT keypoint/ β see Β§4)
βββ tracker/ β DEPRECATED
βββ dataset/core.py β DetectionDataset / ClassificationDataset (YOLO / COCO / Pascal VOC)
βββ geometry/core.py β Point, Rect, Vector, Position
βββ metrics/ β mAP, confusion matrix (requires --extra metrics)
βββ utils/internal.py β warn_deprecated, deprecated_parameter, internal helpers
βββ config.py β string constants; always import from here, never use literals
```
### Key design patterns
- **`Detections` is the lingua franca** β every connector, tracker, and annotator speaks `Detections`. New connector = `@classmethod from_<framework>(cls, result) -> Detections`.
- **Annotators are composable** β receive `scene` (BGR `np.ndarray`) + `detections`, return annotated copy.
- **`data` dict extensibility** β per-detection metadata in `detections.data` as `np.ndarray` aligned with `xyxy`. Keys are constants from `config.py`.
- **Vectorized throughout** β NumPy arrays, no Python loops in hot paths. Never write `for det in detections`.
- **Lazy-import heavy deps** β `torch`, `transformers`, `ultralytics` must be imported inside the function that needs them, never at module top level.
______________________________________________________________________
## 3. Agent-Critical Rules
These supplement [CONTRIBUTING.md](.github/CONTRIBUTING.md) β covering gaps or agent-specific failure modes.
**Doc headings**: `###` max in docstrings and docs. `####` renders identically to bold in mkdocs β use `**bold**` instead.
**Type hints**: required on all new code. mypy is enforced by pre-commit (`.pre-commit-config.yaml`).
**Function docstrings**: every new or modified function, including private helpers and tests, must have a succinct docstring explaining its purpose. Put function-level why/what/how context inside the function docstring, not in a comment before the function. Public APIs still require the full Google-style structure described below.
**Readable argument lists**: do not put multi-branch conditional expressions inside function or constructor arguments. If an argument needs more than a simple `a if condition else b`, assign it to a named local variable before the call.
**Inline comments**: write code so the intent is clear from names, small helpers, and straightforward control flow. For non-trivial logic inside a function that still needs context, add concise inline comments explaining why the code exists, what invariant it protects, and how the tricky part works. Do not put comments before functions; use the function docstring instead. Do not comment obvious assignments, mechanical plumbing, lint-only changes, typing-only changes, or pure docs edits.
**Doctest determinism** β output must be reproducible across platforms:
- Use `# doctest: +ELLIPSIS` for floats that vary by platform.
- Seed any RNG before calling it.
- Never assert `dict` or `set` iteration order.
- No network or filesystem access outside `supervision/assets/`.
**β Test structure** β agents frequently fail here; read [CONTRIBUTING.md Β§Tests](.github/CONTRIBUTING.md#-tests) carefully: AAA structure, class grouping, parametrize with `pytest.param(..., id="slug")`, one-line docstring per test.
For branching, commit, code style, and API design conventions see [CONTRIBUTING.md](.github/CONTRIBUTING.md).
______________________________________________________________________
## 4. Deprecated Module Aliases
`supervision.keypoint` deprecated since `0.27.0`, removed in `0.31.0`. Always import from `supervision.key_points`, not `supervision.keypoint`.
______________________________________________________________________
## 5. Deprecating APIs
**Minimum window**: deprecated APIs must remain for at least **3 minor releases** before removal. Example: deprecated in `0.29.0` β removed in `0.32.0`.
- Module-level: `supervision.utils.internal.warn_deprecated` in the deprecated module's own `__init__.py`
- Parameter renamed (oldβnew): `supervision.utils.internal.deprecated_parameter` decorator
- Public function, method, or class: `@deprecated` from `pydeprecate`
Always name the version introduced and the removal version:
```python
warn_deprecated("'foo' deprecated in `0.29.0`, removed in `0.32.0`. Use 'bar'.")
```
______________________________________________________________________
## 6. Implementing Features
- Minimal implementation; type hints and Google docstrings with usage examples.
- Tests covering new functionality and edge cases (see [CONTRIBUTING.md Β§Tests](.github/CONTRIBUTING.md#-tests)).
- Update docstrings and mkdocs entries as needed.
- Update [docs/changelog.md](docs/changelog.md) for every functional change or bug fix, including user-visible behavior changes. Skip changelog entries for lint-only, type-only, formatting-only, and pure documentation-only changes.
**Extending `Detections`**: store metadata in `detections.data` as `np.ndarray` aligned with `xyxy`; define the key as a constant in `config.py` (e.g. `CLASS_NAME_DATA_FIELD`, `ORIENTED_BOX_COORDINATES`).
**New model connector** (`detection/core.py`):
```python
@classmethod
def from_myframework(cls, result) -> "Detections":
import myframework # noqa: F401 β lazy import
xyxy = ... # (N, 4)
return cls(
xyxy=xyxy,
confidence=...,
class_id=...,
data={CLASS_NAME_DATA_FIELD: np.array([...])},
)
```
VLM connectors go in `detection/vlm.py`, not `core.py`.
______________________________________________________________________
## 7. Bugs & Refactoring
**Bugs**: reproduce β write failing test β minimal fix β verify no regressions.
**Refactoring**: preserve behavior and API; reduce duplication; avoid sweeping changes unless requested; apply Β§5 deprecation when removing public API.
______________________________________________________________________
## 8. Before You Commit
```bash
uv run pytest --cov=supervision
uv run pre-commit run --all-files
```
Capture a baseline before changes to avoid introducing new failures:
```bash
STASH_BEFORE=$(git rev-parse refs/stash 2>/dev/null)
git stash push --include-untracked
uv run pytest -q 2>&1 | tee /tmp/baseline.txt
[ "$(git rev-parse refs/stash 2>/dev/null)" != "$STASH_BEFORE" ] && git stash pop
uv run pytest -q 2>&1 | tee /tmp/after.txt
diff /tmp/baseline.txt /tmp/after.txt
```
Any test passing in baseline but failing after = blocker.