feat(media): image edits + input_type + Solana quality on blockrun-llm 1.7.0 (0.7.0)#18
Merged
Merged
Conversation
VickyXAI
force-pushed
the
fix/media-parameter-parity
branch
from
July 15, 2026 20:36
5397d61 to
5f5a1b4
Compare
The image and video params this branch forwarded — quality, reference_videos, reference_audios, input_type — exist in no blockrun-llm release, including 1.6.1. The SDK clients have closed signatures, and ImageClient.generate/edit explicitly raise TypeError on unknown kwargs, so each of these is a runtime failure on the first real call, on Base and Solana alike. No floor bump fixes it: the parameters aren't in any published version, and the companion SDK PR the branch description refers to was never opened. The media tests fake the SDK clients with **kwargs signatures, which swallow any kwarg the adapter invents — that's why 96 green media tests reported a surface that cannot work. Keep the part that does work: image edits (JSON + multipart, multi-image, mask) call ImageClient.edit / SolanaLLMClient.image_edit, both of which are real — edit has existed since 0.6.0, image_edit ships in the 1.6.1 solana floor. Add tests/test_sdk_param_contract.py, which binds the adapter's forwarded params against the installed SDK's real signatures. It fails on each of the four removed params, so the fakes can't hide this class of bug again.
BlockRunAI/blockrun-llm#24 shipped the two params this branch originally tried to forward, so they can now go back — pointing at a real SDK surface rather than a gap. input_type (/v1/videos/generations, both chains): declared seed mode, cross checked by the gateway against the seed fields and rejected 400-unbilled on disagreement. quality (/v1/images/{generations,edits}): Solana only. The Base gateway has no quality field and strips unknown keys, so routing it there would silently drop it and the caller would never learn their latency knob did nothing. The adapter refuses on the Base branch and _media_endpoint turns that into a 400 naming the constraint — verified end-to-end through the real proxy, not a 500. Floors go to blockrun-llm>=1.7.0, base and [solana]. The base floor moves this time, unlike the Solana-only re-signing bump reverted earlier in this branch: input_type is genuinely a Base concern, and VideoClient.generate has a closed signature, so an older core raises TypeError the first time anyone sends it. reference_videos/reference_audios stay out. Both gateways gate them behind R2V_ENABLED — unset on blockrun-sol, "false" on blockrun-web — so every call 503s until that flips. The contract test now also pins the Base-rejects-quality asymmetry, so a future SDK adding quality to ImageClient fails here loudly instead of leaving the adapter's Base guard silently stale. Verified against the real SDK 1.7.0 with only HTTP stubbed: input_type reaches the video body, quality reaches /v1/images/generations and image2image.
added 2 commits
July 15, 2026 20:20
Multipart clients routinely emit every optional field, blank ones included, and a JSON caller templating "" means the same thing. Both reached the Solana-only guard as a set value, so a Base request that never knowingly sent quality answered 400 with a message about a parameter the caller did not use. Blank now means absent on both the JSON and multipart paths. A real value on Base still gets the clean 400 — the guard is unchanged, only what counts as "supplied" is.
From review of #18: The contract test was vacuous for the Base image surface — the exact failure it exists to prevent. _accepted() returns None for **kwargs signatures, and ImageClient.generate/edit both have **kwargs (they validate at runtime for a friendlier error), so every `if accepted is not None:` body never ran. The test whose docstring promised to fail loudly if a future SDK taught Base about quality would have stayed green through precisely the likely evolution: a named quality param added *alongside* **kwargs. Base image params are now probed by calling, with the transport stubbed, so a contract test can never reach a gateway or settle funds. Verified by mutation: adding `quality` to ImageClient.generate while keeping **kwargs now fails. Closed signatures still use inspection; the file says why the two differ. Also fixed, both reachable: - A `prompt` sent as a multipart file part was billed as a Python repr. UploadFile is truthy, so the required check passed and str() sent "UploadFile(filename='p.txt', ...)" upstream as the prompt — a paid call on garbage, returning 200. Reproduced, then guarded: prompt must be non-blank text on both image routes. - Non-string image/mask on the JSON path went to the gateway to be rejected; refused locally now, matching the isinstance guards model/size/quality had. Multipart uploads are capped (BLOCKRUN_MAX_IMAGE_BYTES, 12MB → 413; BLOCKRUN_MAX_IMAGE_PARTS, 16 → 400). Starlette spools big bodies to disk to keep RAM clear; building a data URI reads them back and inflates ~1.33x, so an unbounded POST was buffered and encoded before the gateway could say no. The part cap is a resource guard only — per-model caps stay the gateway's call. And test_base_image_generation_omits_none_values now observes what it claims: its fake defaulted size=None, so it read the same whether the adapter omitted size or passed it. It captures **kwargs now, which sees only what was sent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebased onto main and reworked after a gateway audit. Adds OpenAI-compatible image editing, plus the two media params that are real as of blockrun-llm 1.7.0.
What changed from the original revision
This branch originally forwarded four params —
quality,reference_videos,reference_audios,input_type— that existed in no blockrun-llm release, including 1.6.1. The SDK clients have closed signatures, andImageClient.generate/editexplicitly raise on unknown kwargs, so each was aTypeErroron the first real call, on both chains. The 96 green media tests fake the SDK with**kwargssignatures, which swallowed every invented param.Checking each against the gateway split them three ways:
input_typequalityopenai/gpt-image-*)reference_videos/reference_audiosR2V_ENABLED="false"→ 503R2V_ENABLEDunset → 503BlockRunAI/blockrun-llm#24 shipped
input_typeand Solanaquality(released as 1.7.0), so those are back — now pointing at a real SDK surface.Contents
POST /v1/images/edits(alias/v1/images/image2image): JSON data URIs or multipartimage/image[], multiple source images,mask. This was always sound:ImageClient.edithas existed since 0.6.0 andSolanaLLMClient.image_editships in the solana floor. Addspython-multipartto theproxyextra.input_typeon/v1/videos/generations, both chains. The gateway infers the seed mode and returns 400 without charging on disagreement — so a droppedimage_urlbecomes an error instead of a text-to-video clip you still pay for.qualityon the image endpoints — Solana only. On Base the adapter returns a 400 naming the constraint rather than letting the value be silently dropped (or surfacing a 500TypeError).blockrun-llm>=1.7.0, base and[solana]. The base floor moves this time — unlike the Solana-only re-signing bump this branch first proposed (reverted),input_typeis a genuine Base concern.Not included
Reference-to-video. Both gateways gate
reference_videos/reference_audiosbehindR2V_ENABLED, currently off, so every call 503s. Shipping it would repeat the original mistake one layer down.Verification
tests/test_sdk_param_contract.pybinds every forwarded param against the installed SDK's real signatures — the check that would have caught the original bug, since the fakes cannot. It also pins the Base-rejects-qualityasymmetry so a future SDK change fails loudly instead of leaving the adapter's guard stale.quality→ 400 confirmed by driving the real FastAPI proxy, not asserted from a mock.input_typereaches the video body;qualityreaches/v1/images/generationsand/v1/images/image2image.