How to Use GPT-Image2 for Reference-Photo Editing with Prompt Chaining

GPT-Image2 implements reference-photo editing through a two-step prompt-chaining workflow where the first prompt extracts a description of the unchanged reference region, and the second prompt applies user edits while preserving that region, using APIMart's asynchronous generation API.

The freestylefly/awesome-gpt-image-2 repository demonstrates an elegant, stateless architecture for GPT-Image2 reference-photo editing with prompt chaining, combining a React front-end with serverless API endpoints to orchestrate multi-stage image generation without requiring a backend database. This approach leverages Case 541—documented in data/cases.json and docs/gallery-part-2.md—to preserve specific portions of a reference image while transforming others.

Understanding the Prompt-Chaining Architecture

The workflow relies on APIMart's /v1/images/generations endpoint and maintains state purely in the browser. The core client logic resides in src/apimartClient.js, which exports submitPlatformGeneration for initiating jobs and fetchPlatformTask (wrapped in pollApimartTask) for retrieving results.

Key design characteristics:

  • Stateless server: The API endpoints do not persist generation data; the server only forwards requests to APIMart and returns task IDs
  • Client-side persistence: Pending task IDs are stored in browser localStorage using the constants APIMART_PENDING_STORAGE_KEY and GENERATED_TESTS_STORAGE_KEY defined in src/apimartClient.js
  • Asynchronous polling: After submitting a prompt, the front-end polls /api/generation/status until the task reaches a terminal state (succeeded or failed)

Implementing the Two-Step Workflow

Step 1: Extracting the Reference Description

The first prompt asks the model to analyze the reference image and generate a concise description of the region that must remain unchanged. The UI component in src/main.jsx collects the reference image URL and sends a POST request to /api/generate-image, implemented in api/generate-image.js.

// src/main.jsx - Initiating reference extraction
async function startReferenceExtraction(refImageUrl, userPrompt) {
  const body = {
    caseId: 541,  // Reference-photo editing case identifier
    prompt: `Analyse the reference image ${refImageUrl} and return a short description of the unchanged portion.`,
    language: 'en'
  };
  
  const res = await fetch('/api/generate-image', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  });
  
  const { taskId } = await res.json();
  return taskId;
}

The api/generate-image.js handler forwards this payload via submitPlatformGeneration in src/apimartClient.js, which returns a taskId representing the asynchronous job.

Step 2: Chaining the Edit Instruction

Once the first task completes, the client extracts the generated description and appends the user’s edit instruction. This prompt chaining occurs entirely client-side before submitting the second generation request.

// Chaining the reference description with the edit instruction
async function applyEdit(referenceDesc, userEdit) {
  const editPrompt = `${referenceDesc}. Now ${userEdit}.`;
  
  const body = {
    caseId: 541,
    prompt: editPrompt,
    language: 'en'
  };
  
  const res = await fetch('/api/generate-image', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  });
  
  const { taskId } = await res.json();
  return taskId;
}

This concatenated prompt ensures the model preserves the reference region while applying the transformation to the target area.

Step 3: Polling for Generation Status

Both generation steps require polling /api/generation/status (implemented in api/generation/status.js) via the fetchPlatformTask function. The endpoint queries APIMart for the current task state every few seconds until completion.

// Polling implementation for asynchronous tasks
async function pollTask(taskId) {
  while (true) {
    const r = await fetch(`/api/generation/status?taskId=${taskId}&language=en`);
    const data = await r.json();
    
    if (data.status === 'succeeded') return data;
    if (data.status === 'failed') throw new Error('Generation failed');
    
    await new Promise(res => setTimeout(res, 2000));  // 2-second interval
  }
}

Complete End-to-End Implementation

The following function orchestrates the full workflow, from reference extraction through final image display, utilizing the stateless task management system:

// Complete reference-photo editing workflow
async function editReferencePhoto(refImageUrl, userEdit) {
  // Step 1: Extract description of the unchanged portion
  const firstTaskId = await startReferenceExtraction(refImageUrl, userEdit);
  const firstResult = await pollTask(firstTaskId);
  const referenceDesc = firstResult.output?.description ?? '';

  // Step 2: Generate edited image using chained prompt
  const secondTaskId = await applyEdit(referenceDesc, userEdit);
  const finalResult = await pollTask(secondTaskId);

  // Step 3: Display the final result
  document.getElementById('result').src = finalResult.output?.imageUrl;
}

When finalResult.output.imageUrl is returned, the React component replaces the placeholder with the edited image, maintaining the integrity of the original reference portion as specified in Case 541.

Key Source Files and Functions

Understanding these files is essential for customizing or debugging the GPT-Image2 reference-photo editing workflow:

  • src/main.jsx — React entry point that gathers user input, displays results, and coordinates the prompt-chaining sequence
  • src/apimartClient.js — Core client library exporting submitPlatformGeneration for image requests and pollApimartTask for status monitoring; manages localStorage persistence
  • api/generate-image.js — Server-side handler that forwards prompts to APIMart's /v1/images/generations endpoint and returns the initial taskId
  • api/generation/status.js — Server-side endpoint that invokes fetchPlatformTask to retrieve current generation status from APIMart
  • data/cases.json — Structured metadata for all use cases, including Case 541 configuration parameters for reference-photo editing
  • docs/gallery-part-2.md — Documentation describing the reference-photo editing capabilities and gallery examples

Summary

  • GPT-Image2 achieves reference-photo editing through a two-step prompt-chaining methodology that first analyzes and describes the preservation region, then applies edits while maintaining that description in context.
  • The architecture is stateless on the server side, with task persistence handled via browser localStorage using keys defined in src/apimartClient.js.
  • Case 541 provides the specific implementation pattern for preserving portions of reference images while transforming others.
  • The workflow relies on asynchronous polling via /api/generation/status to retrieve final images from APIMart's generation service.
  • All orchestration occurs in src/main.jsx and supporting API routes, requiring no dedicated database infrastructure.

Frequently Asked Questions

What is Case 541 in the GPT-Image2 repository?

Case 541 is the specific reference-photo editing implementation documented in data/cases.json and docs/gallery-part-2.md. It defines the parameters for workflows where users upload a reference image and specify which portions to preserve while editing others, serving as the canonical example for prompt-chaining-based preservation.

How does the stateless architecture track pending generations?

Since the server does not maintain a database, pending task IDs are stored in browser localStorage using the constants APIMART_PENDING_STORAGE_KEY and GENERATED_TESTS_STORAGE_KEY defined in src/apimartClient.js. This allows the React front-end to resume polling for results even if the user refreshes the page.

Why is prompt chaining necessary instead of a single prompt?

Prompt chaining is required because the model needs to first analyze and encode the visual characteristics of the reference region before receiving the edit instruction. Attempting both operations in a single generation would reduce accuracy; separating them ensures the preservation description is explicitly available in the context window when the transformation is applied.

Which APIMart endpoint handles the actual image generation?

The submitPlatformGeneration function in src/apimartClient.js forwards all requests to the APIMart /v1/images/generations endpoint. This endpoint accepts the JSON payload containing the chained prompt and returns a taskId for asynchronous processing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →