Conflict in request_adapter.py with #2001, which adds continuation_video and
materializes it through _materialize_video. This branch replaced that helper
with materialize_clip, so continuation_video now goes through materialize_clip
as well, with the same "continuation" upload name. As a result it gets the same
policy as the other video fields: media_roots, the private-URL check, the size
cap, and base64 data:video/... URLs.
- docs/design/server_contracts/openai.md: continuation_video is listed in the
video row of the media-source table.
- docs/inference/fasth3_omniref.md: continuation_video may be a data:video URL.
- test_openai_serving_engine.py: an inline continuation video is decoded,
tracked and removed, and a data:audio one is refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`POST /v1/videos` decoded `data:image/...` references but refused
`data:` video references and passed every `audio_url` to the pipeline
unchanged, so clients without a public URL could not send a reference
video or audio file (SGLang Diffusion accepts all three).
- `video_reference` / `video_path` / `video_url` accept
`data:video/...;base64,` and `audio_reference` accepts
`data:audio/...;base64,`. Each decoded file is capped by
`server.media_reference_max_bytes` (checked from the payload length
before decoding), written under `output_dir/uploads`, kept in field
order, and deleted when the job ends.
- Invalid base64, a non-base64 data URL, or a media type that does not
match the field returns HTTP 400. Percent escapes and line-wrapped
payloads decode, as in SGLang.
- Audio references are now materialized like video references: http(s)
URLs go through the media policy download (public addresses, byte
cap) and local paths must sit under `server.media_roots`. Before, the
raw string reached PyAV, which opened any local file or URL.
- `docs/design/server_contracts/openai.md` lists the accepted forms per
field.
Fixes#2018
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>