Ask OpenAI whether the supplied image depicts *artwork* — either a digital artwork (e.g. digital painting, illustration) or a professional digitization of physical artwork (a flat reproduction / scan). Photographs of artwork in situ (framed on a wall, inside a gallery, held by a person) are **not** treated as artwork by this predicate.
Value
A list with:
- `is_artwork`
Logical. `TRUE` if the image depicts artwork.
- `confidence`
Numeric in `[0, 1]`. Model self-reported confidence.
- `reason`
Character. One-sentence explanation.
- `model`
Character. Model that produced the answer.
- `usage`
List. Token usage from the Responses API.
Details
This function enforces a **thumbnail-input contract**: `img_path` must point to a file of at most `max_bytes` bytes (default 2 MB). It does **not** resize the image itself — callers are expected to pre-resize (e.g., to ~1000x1000 px) during ingestion. This keeps every call fast and deterministic: no libpng decode of large masters, no re-encoding, ~20 ms of local work before the API call.
The model, reasoning effort, and request shape are hardcoded. The `ART_OPENAI_MODEL` env var is deliberately **not** consulted.
Efficiency choices:
`gpt-5.4-nano` — smallest current GPT-5 tier with vision support.
`reasoning = list(effort = "none")` — skip chain-of-thought entirely.
`detail = "low"` — Responses API encodes the image as a single 85-token tile, independent of upload resolution.
Raw-byte read + magic-byte mime detection — no image library call.
Strict JSON schema with three small fields keeps output short.
Supported image formats: PNG, JPEG, WebP, GIF.
Examples
if (FALSE) { # \dontrun{
res <- is_artwork("path/to/thumbnail.jpg")
if (res$is_artwork && res$confidence > 0.8) {
message("Looks like artwork: ", res$reason)
}
} # }
