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:1761 — float | None, gt=0.0, le=1.0 |
fine |
| The route defaults it and passes it on |
server/routes/inference.py:236 — detail=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:263 — self._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.
POST /inference/suggestaccepts adetailfield, validates it, and publishes it inopenapi.json. It has no effect. A client sendingdetail: 0.9gets the same polygon as one sendingdetail: 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.
server/models.py:1761—float | None,gt=0.0,le=1.0server/routes/inference.py:236—detail=DEFAULT_DETAIL if body.detail is None else body.detailsuggest()accepts it and never reads itinference/suggestions.py:52polygon_fromsam_provider.py:263—self._detailDEFAULT_DETAILsam_provider.py:128, from a keywordproviders._local()never passesruff --select ARGreports it directly:Why it is not a one-line fix
The adapter's
detailis 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. Sosuggest()cannot setself._detailon 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_confidencealready takes throughPredictionRequest— 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:197exercisespolygon_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_confidenceandallowed_geometrieson the same route both work; this is specific todetail.