# `ALLM.ImageRequest`
[🔗](https://github.com/cykod/ALLM/blob/v0.3.0/lib/allm/image_request.ex#L1)

A request for image generation, editing, or variation. See spec §35.2.2.

Layer A — pure serializable data. Three operations:

- `:generate` — text-to-image; requires `:prompt`, `:input_images == []`.
- `:edit` — modify one or two input images optionally with a `:mask`;
  requires `:prompt` and `length(:input_images) in 1..2`.
- `:variation` — generate variants of one input image; requires
  `length(:input_images) == 1` and `:prompt in [nil, ""]`.

Operation-arity rules are enforced by `ALLM.Validate.image_request/1`
(Phase 13.3); construction via `new/1` does not validate.

## Sizes and qualities

`:size` accepts `{w, h}` (positive integers), a binary like `"1024x1024"`,
the atom `:auto`, or `nil`. JSON encodes the tuple as a 2-element array
`[w, h]`; decode reconstructs the tuple from a 2-element list of positive
integers, treats `"auto"` as `:auto`, and otherwise passes binaries
through verbatim.

`:quality` is the closed atom set `[:low, :standard, :high, :hd, :auto]`
with a `String.t()` open arm — providers extend the set (`:hd` is
dall-e-3-only; `:high` is gpt-image-1-only). The decoder restores known
atoms; unknown binaries pass through verbatim.

`:operation`, `:response_format`, `:style`, and `:background` are closed
atom enums; an unknown value at decode time raises `ArgumentError` and
surfaces as `{:_unknown, :atom_decode_failed}` per the serializer's rescue
contract.

# `operation`

```elixir
@type operation() :: :generate | :edit | :variation
```

# `quality`

```elixir
@type quality() :: :low | :standard | :high | :hd | :auto | String.t()
```

# `response_format`

```elixir
@type response_format() :: :binary | :base64 | :url
```

# `size`

```elixir
@type size() :: {pos_integer(), pos_integer()} | String.t() | :auto
```

# `t`

```elixir
@type t() :: %ALLM.ImageRequest{
  background: :transparent | :opaque | nil,
  input_images: [ALLM.Image.t()],
  mask: ALLM.Image.t() | nil,
  metadata: map(),
  model: String.t() | nil,
  n: pos_integer(),
  operation: operation(),
  options: map(),
  prompt: String.t() | nil,
  quality: quality() | nil,
  response_format: response_format(),
  size: size() | nil,
  style: :natural | :vivid | nil
}
```

# `new`

```elixir
@spec new(keyword()) :: t()
```

Build an `%ImageRequest{}` from keyword opts.

Unknown keys raise `KeyError` via `struct!/2` (matches `ALLM.Request.new/2`
precedent). No validation — call `ALLM.Validate.image_request/1` to check
operation-arity and field rules.

## Examples

    iex> req = ALLM.ImageRequest.new(prompt: "a kestrel", size: {1024, 1024}, n: 2)
    iex> req.operation
    :generate
    iex> req.size
    {1024, 1024}
    iex> req.n
    2

---

*Consult [api-reference.md](api-reference.md) for complete listing*
