Skip to content

The suggest route's detail field is accepted, published, and ignored #463

Description

@JArmandoAnaya

POST /inference/suggest accepts a detail field, validates it, and publishes it in openapi.json. It has no effect. A client sending detail: 0.9 gets the same polygon as one sending detail: 0.01.

Found while inventorying the auto-labeling surfaces for cleanup; not fixed there, because making it work is a real change rather than a removal.

Where the chain breaks

One link, and everything either side of it is correct.

Step Where State
The field is declared and bounded server/models.py:1761float | None, gt=0.0, le=1.0 fine
The route defaults it and passes it on server/routes/inference.py:236detail=DEFAULT_DETAIL if body.detail is None else body.detail fine
suggest() accepts it and never reads it inference/suggestions.py:52 the break
The value that actually reaches polygon_from sam_provider.py:263self._detail always DEFAULT_DETAIL
…set at construction sam_provider.py:128, from a keyword providers._local() never passes always the default

ruff --select ARG reports it directly:

ARG001 Unused function argument: `detail`
  --> src/visionset/inference/suggestions.py:52:5

Why it is not a one-line fix

The adapter's detail is per-provider, and providers are pooled and shared across requests, keyed on (connection.id, connection.updated_at) — that pooling is what makes the embedding cache worth anything. So suggest() cannot set self._detail on the instance it borrowed: two concurrent callers asking with different values would race, and the surviving value would leak into the next click on that connection.

Making the field mean something means carrying it per-request — the same route minimum_confidence already takes through PredictionRequest — and deciding whether it belongs on the port at all, since it is a polygon-simplification setting rather than a model setting and only one of the two adapters produces polygons.

The other honest option is to remove the field. That is a published wire change, so it is a decision rather than a cleanup.

Why it shipped

Nothing tests it. tests/inference/test_masks.py:197 exercises polygon_from(detail=…) directly and proves the simplification responds to the setting; no test asserts that the wire field reaches it. The two halves are each covered and the join between them is not.

Not affected

The default is a good one and every suggestion has been produced with it, so no stored annotation is wrong — the field has simply never been honoured. minimum_confidence and allowed_geometries on the same route both work; this is specific to detail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apivisionset.server — REST API and OpenAPI contractbackendvisionset Python distribution — kernel, server, cli, mcp, formatsbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions