Files
dora-image-view/AGENTS.md
T
cristhianandClaude Opus 5 22bd1e9e89
validate / dataflow (pull_request) Failing after 59m9s
validate / test (pull_request) Successful in 59m8s
add an in-repo synthetic source so the example needs no network
The example dataflow pulled opencv-video-capture and pyarrow-sender from
dora-hub, needed a webcam, and left `bbox` unwired because every bbox source
is a detector. examples/source.py emits an animated frame, the box around the
square in it, and a caption, so the dataflow exercises all three inputs with
nothing outside this checkout.

SOURCE_FRAMES bounds the run, which lets CI run the dataflow headless rather
than only validate it. Drops the dora-zed and dora-yolo wirings from the
README and trims AGENTS.md to what the code and README do not already say.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WLVZCFFcCH1EpTXGfS9aD
2026-09-14 16:09:01 -05:00

42 lines
4.6 KiB
Markdown

# AGENTS.md
This file provides guidance to AI coding assistants when working with code in this repository.
## What this is
A dora-rs Python node that displays a video stream with overlays: it keeps a current frame, bbox set and text string, and every `image` event redraws all three into an OpenCV window. It is a display sink — it produces no outputs. [README.md](README.md) documents the inputs, the encodings and the environment variables; this file covers only what the code and the README do not say.
Everything the example dataflow needs is in this checkout. Do not reintroduce a dependency on another repository — the example must keep running with no camera, no detector and no network.
**It is Python on purpose.** The node was first written in Rust against the `opencv` crate; that crate generates its bindings from the OpenCV headers installed on the build machine, so it needs `libopencv-dev` and `libclang-dev` on every machine and every architecture and does not cross-compile. Every dependency here ships prebuilt wheels for linux-x86_64, linux-aarch64 and macos-arm64, so `uv sync` is the whole install. Do not reintroduce a dependency that has to be compiled from source.
## Commands
```bash
uv sync --group dev # deps plus pytest and ruff
uv run pytest && uv run ruff check . # no camera/dataflow/display needed
dora run dataflow.yml --uv # the example, in a window
CI=true SOURCE_FRAMES=30 dora run dataflow.yml --uv # the same, headless
```
`dora build --uv` / `dora run --uv` rewrites each manifest's `build: pip install .` to `uv pip install .` and gives the node its own managed venv under `.dora/python-envs/<node-id>/`, so what it imports at runtime is what was installed at build time.
## Architecture
- **`dora_plot/main.py`** — Argument parsing and the dora event loop, nothing else. The env var wins over the CLI flag for `PLOT_WIDTH`/`PLOT_HEIGHT`, matching the upstream node. `Node(args.name)` rather than `Node()` so the node also runs standalone as a dynamic node.
- **`dora_plot/decode.py`** — `to_bgr()`: every supported encoding to a writable BGR array. Two behaviours are deliberate, not bugs: `bgr8` **copies** (the payload may be a read-only view on shared memory, and the frame is annotated in place), and `yuv420` converts with `COLOR_YUV420p2RGB` rather than `...2BGR` — the upstream node converts to RGB and then displays it as BGR, and that channel swap is part of the behaviour callers already see.
- **`dora_plot/plot.py`** — `Plot` (the overlay state and the window) and `Bboxes`. `headless` (from `CI=true`) skips only the window: every input is still decoded, which is what makes the node safe in a pipeline test.
- **`dora_plot/bbox.py`** — Parses the `bbox` struct into xyxy corners. `xywh` is centre-based (x, y are the box centre). `_flat()` unwraps the single-element list that `pa.array([{...}])` produces around each field, and reads a field stored flat as-is.
- **`examples/source.py`** — The synthetic source node: an animated frame, the box around the square in it, and a caption. It exists so the example dataflow exercises all three inputs without a camera or a detector, and so CI can run the dataflow rather than only validate it. `SOURCE_FRAMES` bounds the run, which is what lets CI wait for a clean exit instead of killing it on a timeout.
- **`dora-node.yml`** — Node manifest (`apiVersion: 1`). `dora validate` injects these types into any dataflow that reaches the node by `path:`; a `git:`-sourced node does **not** pick it up, which is why the example builds from the checkout. `image` and `text` carry type URNs naming the element type because each payload is a raw buffer described by its metadata, not an Arrow struct. `bbox` is deliberately **untyped**: senders disagree on whether its numeric fields are 32- or 64-bit, and the node reads either.
- **`dataflow.yml`** — The example and the CI gate, with `strict_types: true`. `source` carries `output_types:` because it has no manifest of its own; `bbox` is annotated on neither side, matching the manifest.
- **`.gitea/workflows/validate.yml`** — CI: validates and runs the dataflow headless, and runs the unit tests. Needs no camera and no display.
## A caveat on typed optional inputs
`dora validate --strict` injects a contract type for *every* typed manifest input and then warns `input_types key "..." not found in inputs list` for any the dataflow does not wire. So a typed optional input forces the example dataflow to wire it. If a typed input is added to the manifest, either wire it in `dataflow.yml` or leave it untyped.
## Rules
- Do not mention AI tools in commit messages or documentation.