Skip to content

Suggest prompts outside the asset are refused, not passed through #520

Description

@JArmandoAnaya

POST /inference/suggest accepts prompt points at any coordinate whatsoever. Nothing on the path examines them: SuggestPoint declares x and y as bare floats with no constraint, the route projects them straight into the domain's PointPrompt, and the orchestration hands that to the provider without ever comparing a coordinate to the asset it belongs to. A click a thousand pixels off the right-hand edge of a 640×480 image is therefore a well-formed request, and the model is asked a question about a place that does not exist.

The behaviour was measured rather than inferred, during the editor work that shipped the client-side half of this (#514, "Editor polish: asset-bounded suggest clicks, confidence only in preview, selected-only labels"). A press at (900, 700) on a 640×480 asset sent positive: [{"x": 900, "y": 700}], the editor painted a prompt dot in the margin around the picture, and whatever the model returned was drawn as a suggestion.

#514 closed the browser's half: the editor now hit-tests every armed-suggest click against the asset's rendered rectangle in canvas space before it becomes a prompt, so a press on the stage surround records nothing and sends nothing. That fix cannot reach any other caller. The route is public, and a script, a notebook, or a future tool composing a prompt from coordinates it computed rather than from a pointer event will still be answered.

What "answered" means here is the part worth stating plainly: there is no correct response to a prompt point that is not on the asset, so whatever comes back is noise wearing the shape of a suggestion. A segmenter handed an out-of-frame point does not fail — it returns a mask, with a confidence attached, and that confidence is about a question nobody asked.

What this needs

The check belongs on the server, applied to every point in the request, positive and negative alike. One bad point refuses the whole request rather than being dropped, because a prompt with a point removed is a different question from the one the caller sent, and silently answering the different one is the same class of mistake as answering the out-of-frame one.

Edge semantics have to agree with the client half, since disagreement would produce a coordinate the editor allows and the server refuses. The predicate #514 added treats the frame as inclusive at both ends — the last row of pixels is part of the asset — and the server's rule follows it.

The refusal is a 422 carrying the standard error body, with the offending coordinate and the asset's bounds in the message, so a caller reading prose rather than rendering a canvas knows what it sent and what would have been acceptable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions