Repository navigation
feat(images): Antigravity image edits accept multiple reference images - #16731
Open
diegosouzapw wants to merge 3 commits into
Open
diegosouzapw wants to merge 3 commits into
diegosouzapw wants to merge 3 commits into
Conversation
Antigravity (Gemini image) edits only ever forwarded the first reference image. Every reference now becomes its own inlineData part: - /v1/images/edits forwards all multipart/JSON references to Antigravity (cap raised from 1 to 14, the Gemini 3 image reference limit). - /v1/images/generations bodies may carry image / images[] / image_url as data URLs, raw base64 or public HTTP(S) URLs; URLs go through the public-only, DNS-pinned fetchUntrustedRemoteImage guard. - An unusable reference fails with a non-retryable 400 before dispatch, so the account is not rotated or cooled down. - When references are attached, the prompt is prefixed with an explicit "use all N attached reference images; do not answer with text only" instruction. - A response with no image (text-only refusal) now returns a 502 carrying the sanitized model text instead of an empty 200. The reference resolution, prompt and response extraction live in providers/geminiInline.ts so imageGeneration.ts shrinks by 4 lines. Co-authored-by: Hai Trinh <haitrinh2605204@gmail.com> Inspired-by: decolua/9router#2769
Contributor
CI Coverage Report
Coverage artifact was not available for this run. |
Collaborator
Author
|
Re-homed to |
…-reference-images Resolve the overlap with #18148 (reject unusable Gemini reference images): keep the base's no-remote-fetch policy for Gemini image models and reapply the multi-reference delta on top of it. HTTP(S) references are rejected with the base's message instead of being fetched; data URLs, raw base64 and multipart uploads keep working as multiple inline parts. The edits route keeps the base's muse-image branch alongside the PR's isGeminiImageEdit reference cap.
This branch has not been deployed
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.
Summary
inlineDatapart instead of only the first one;/v1/images/editsaccepts up to 14 references for Antigravity (was 1)./v1/images/generationsbodies can carryimage/images[]/image_urlreferences as data URLs, raw base64, or public HTTP(S) URLs (fetched through the existing public-only, DNS-pinnedfetchUntrustedRemoteImageguard).Attribution
Thanks to @yheiakadylan for the original implementation.
Changes
open-sse/handlers/imageGeneration/providers/geminiInline.ts— newresolveGeminiReferenceParts(sources:referenceImages→imageBytes→ string refs; capGEMINI_IMAGE_MAX_REFERENCES = 14),buildGeminiImagePrompt(when references are attached, the prompt is prefixed with "Generate an image as the final response. Use all N attached reference image(s) in the result. Do not answer with text only."),buildGeminiImageUserParts,extractGeminiImageResults.geminiInlineImagePartis kept unchanged.open-sse/handlers/imageGeneration.ts(handleGeminiImageGeneration) — uses the helpers; invalid refs →saveImageErrorResult(400, retryable:false); no image in the response →saveImageErrorResult(502)viasanitizeErrorMessage; the log line reports the reference count only (never bytes). File shrinks by 4 lines (frozen file-size cap respected).src/app/api/v1/images/edits/route.ts— Antigravity branch passesreferenceImages: images; its reference cap is 14 with a dedicated error message (Firefly / fal / single-reference messages unchanged).tests/unit/antigravity-image-multi-reference.test.ts— new (9 cases).tests/unit/gemini-antigravity-image-edits.test.ts— the 3 single-reference asserts now expect the reference preamble + prompt (exactassert.equal, same assert count). This is an intended contract change: with one reference attached the prompt is prefixed. Text-to-image without references keeps the prompt untouched (the existingdeepEqualrequest test inimage-generation-handler.test.tsstill passes unchanged).Out of scope (intentionally not ported): playground UI, per-account Antigravity runtime state (already covered by model lockout +
imageCredentialRetryquota-exhausted rotation).Test plan
node --import tsx/esm --test tests/unit/antigravity-image-multi-reference.test.ts→ℹ tests 9 ℹ pass 0 ℹ fail 9(e.g.actual: 1, expected: 3parts).DATA_DIRandenv -u OMNIROUTE_API_KEY:antigravity-image-multi-reference→ℹ tests 9 ℹ pass 9 ℹ fail 0gemini-antigravity-image-edits→ℹ tests 3 ℹ pass 3 ℹ fail 0image-generation-handler→ℹ tests 50 ℹ pass 50 ℹ fail 0image-generation-route→ℹ tests 30 ℹ pass 30 ℹ fail 010197-openrouter-image-edits-route3/3,8510-adobe-firefly-edits-route4/4,image-combo-edits-fallback-125475/5,antigravity-image-credential-retry4/4,image-credential-retry-4294/4,image-generation-size-and-payload-guard9/9,antigravity-image-quota-visibility2/2,codex-images-dedicated-endpoint6/6,guardrail-pipeline-wiring-characterization10/10,hard-session-lease-bypass-inventory3/3,issue-6686-quota-preflight-coverage2/2 — allfail 0.npm run typecheck:core→ exit 0.npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>→ no findings;npx prettier --check <changed files>→ all formatted.npm run check:file-size→[file-size] OK,[test-file-size] OK.GITHUB_BASE_REF=release/v3.8.52 node scripts/check/check-pr-test-policy.mjs→Result: PASS;GITHUB_BASE_REF=release/v3.8.52 npm run check:test-masking→OK — 1 modificado(s) … sem enfraquecimento.live_check (hold-vps)
POST
/v1/images/editstoantigravity/gemini-3.1-flash-imagewith two multipart reference images and confirm the upstream accepts more than one reference and the result uses both; also confirm the 14-reference cap against Google's documented limit.