# `ReqLLM.Video`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/video.ex#L1)

Video generation functionality for ReqLLM.

Video generation is asynchronous: `generate_video/3` submits a task and
returns a `ReqLLM.Video.Task` with a `task_id`, `query_video/3` polls the
task status, and `wait_video/3` polls until the task reaches a terminal
state (`:succeeded`, `:failed`, or `:cancelled`).

## Content input

The `content` argument is a keyword list describing the multimodal input:

  * `:prompt` - required text prompt describing the video
  * `:first_frame_image` - URL of the first-frame image (image-to-video)
  * `:last_frame_image` - URL of the last-frame image (image-to-video)
  * `:reference_images` - list of reference image URLs (reference-to-video)
  * `:reference_videos` - list of reference video URLs (reference-to-video)
  * `:reference_audio` - list of reference audio URLs (reference-to-video)

## Examples

    {:ok, task} =
      ReqLLM.Video.generate_video("minimax:MiniMax-H3",
        [prompt: "A boy playing basketball by the sea",
         first_frame_image: "https://example.com/frame.png"],
        duration: 5,
        resolution: "2K"
      )

    {:ok, task} = ReqLLM.Video.wait_video("minimax:MiniMax-H3", task.task_id)

# `file_id`

```elixir
@type file_id() :: String.t() | integer()
```

# `generate_video`

```elixir
@spec generate_video(ReqLLM.model_input(), keyword(), keyword()) ::
  {:ok, ReqLLM.Video.Task.t()} | {:error, term()}
```

Submits a video generation task.

Returns `{:ok, %ReqLLM.Video.Task{}}` with the provider `task_id`, or
`{:error, term()}`. The task runs asynchronously; poll with `query_video/3`
or block until completion with `wait_video/3`.

# `query_video`

```elixir
@spec query_video(ReqLLM.model_input(), String.t(), keyword()) ::
  {:ok, ReqLLM.Video.Task.t()} | {:error, term()}
```

Queries the status of a video generation task by `task_id`.

Returns `{:ok, %ReqLLM.Video.Task{}}` with the current status; `url` is
populated once the task succeeds on V2 providers, `file_id` on V1 providers.

# `retrieve_file`

```elixir
@spec retrieve_file(ReqLLM.model_input(), file_id(), keyword()) ::
  {:ok, ReqLLM.Video.File.t()} | {:error, term()}
```

Resolves a video `file_id` to a time-limited download URL.

V1 providers (e.g. `MiniMax-Hailuo-2.3`) return a `file_id` on task
success instead of a direct URL. Call this with the `file_id` from the
succeeded task to obtain the download URL, which is time-limited and should
be downloaded promptly.

Returns `{:ok, %ReqLLM.Video.File{}}` with the `url` populated.

# `schema`

```elixir
@spec schema() :: NimbleOptions.t()
```

Returns the base video generation options schema.

# `supported_models`

```elixir
@spec supported_models() :: [String.t()]
```

Returns a list of model specs that likely support video generation.

# `upload_file`

```elixir
@spec upload_file(ReqLLM.model_input(), binary(), keyword()) ::
  {:ok, ReqLLM.Video.File.t()} | {:error, term()}
```

Uploads a file to the provider platform for use as video generation input.

Returns `{:ok, %ReqLLM.Video.File{}}` with the `file_id` populated. Use the
returned `file_id` as `mm_file://{file_id}` in the `content` media fields of
`generate_video/3` to reference the uploaded file without exposing a public
URL (important for sensitive data).

Alternatively, pass `{:upload, binary, media_type}` or `{:file, path}` as a
media value in `generate_video/3` content to upload automatically. For V1
models (e.g. `MiniMax-Hailuo-2.3`) the media is inlined as a base64 data URL
instead, since the V1 API does not support `mm_file://` references.

Options: `:purpose` (default `"video_generation_input"`), `:filename`
(defaults to `"input.<ext>"` derived from `:media_type`), `:media_type`
(default `"application/octet-stream"`).

# `validate_model`

```elixir
@spec validate_model(ReqLLM.model_input()) ::
  {:ok, LLMDB.Model.t()} | {:error, term()}
```

Validates that a model supports video generation operations.

# `wait_video`

```elixir
@spec wait_video(ReqLLM.model_input(), String.t(), keyword()) ::
  {:ok, ReqLLM.Video.Task.t()} | {:error, term()}
```

Polls a video generation task until it reaches a terminal state.

Polls every `:poll_interval` milliseconds (default 10s) until the task
succeeds, fails, or is cancelled, or until `:timeout` milliseconds (default
10 minutes) elapse.

This function blocks the calling process for the duration of the wait. For
production use, prefer persisting the `task_id` and polling with
`query_video/3` from a background process.

Transient query errors (network timeouts, connection resets) are retried up
to `:max_transient_retries` times (default 3) before giving up; the task
itself keeps running server-side and can be polled again later.

For V1 providers (e.g. `MiniMax-Hailuo-2.3`) the succeeded task carries a
`file_id` instead of a `url`; resolve it with `retrieve_file/3`.

---

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