Skip to content

feat: image editing capability (I2I + inpainting) on openai_compat - #15

Open
amosgeek wants to merge 3 commits into
mofa-org:mainfrom
amosgeek:feat/image-edit
Open

amosgeek wants to merge 3 commits into
mofa-org:mainfrom
amosgeek:feat/image-edit

Conversation

@amosgeek

Copy link
Copy Markdown

What

Adds an image_edit capability so callers can regenerate an input image — either whole (I2I) or restricted to a painted region (inpainting) — over any OpenAI-compatible /images/edits endpoint (gpt-image-1 style).

  • Capability::ImageEdit (image_edit, aliases image-edit/inpaint/inpainting)
  • InferenceRequest.input_mask: data: URL / local path / http(s) URL for a mask PNG, transparent (alpha 0) areas mark where to regenerate — the OpenAI convention, passed through to the provider untouched. None = whole-image I2I.
  • Input images ride on messages[0].images (the same slot VLM uses); every entry becomes its own multipart image part (gpt-image-1 multi-reference consistency — first is the edited base, the rest are anchors).
  • References resolve via a shared fetch_image_ref: base64 data-URL decode, local file read, or http(s) download with content-type.
  • invoke_image_edit posts multipart (model, prompt, n, image ×refs, optional mask, optional size), then reuses the same b64/url artifact resolution as image_gen (extracted into image_bytes_from_response).
  • config.example.toml documents the setup.

Testing

5 new tests in openai_compat against a live local axum mock (multipart wire assertions — image/mask/size parts, reference bytes inline, b64 artifact written to disk), maskless whole-image edit, missing-input-image rejection, parse_data_url unit cases, and one-part-per-reference. Full workspace suite green.

Stacked on #12 (provider config API) — only the last two commits are new here.

🤖 Generated with Claude Code

amosgeek and others added 3 commits August 26, 2026 12:52
Add Capability::ImageEdit and InferenceRequest.input_mask. The backend
posts multipart to the OpenAI-compatible /images/edits endpoint: the
input image is resolved from messages[0].images[0] (data: URL, local
path, or http(s) download) and passed through with the mask untouched —
a PNG whose fully transparent areas mark where to regenerate (the
OpenAI convention). No mask = whole-image I2I edit.

Co-Authored-By: Claude <noreply@anthropic.com>
…stency)

gpt-image-1 style: every messages[0].images entry rides as its own
multipart image part — first is the edited base, the rest are
consistency anchors.

Co-Authored-By: Claude <noreply@anthropic.com>
The tests were introduced with the capability but leaned on the dev-dep
from the stacked branch; make it explicit so this branch stands alone.

Co-Authored-By: Claude <noreply@anthropic.com>
@amosgeek

Copy link
Copy Markdown
Author

Rebased onto current main — the branch now carries only the two image-edit commits (plus an explicit axum dev-dependency for the mock-server tests), no longer stacked on #12. Workspace tests green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant