Files

9.7 KiB

Context

The repository now has three distinct realities for GPT Image requests:

  • official OpenAI GPT Image requests already route cleanly through dedicated schemas and the gpt-image-adapter
  • Tuzi GPT compatibility is still encoded as openai.image.basic-json and ultimately handled by the generic default image adapter
  • generic OpenAI-compatible gateways also use the same basic adapter path

That means resolvedImageApiCompatibility is richer than the actual dispatch boundary. The metadata can say tuzi-compatible, but the adapter selection still collapses it into the same generic route as every other basic gateway. This makes the current system work, but it keeps provider-specific GPT behavior in the wrong module.

Goals / Non-Goals

  • Goals:
    • keep compatibility decisions profile-scoped
    • keep auto as a resolver
    • give Tuzi GPT compatibility a real adapter boundary
    • preserve the current official GPT adapter and schema split
    • preserve openai-compatible-basic as the generic fallback
    • separate official GPT quality semantics from legacy basic resolution semantics
    • keep the UI simpler than the internal routing model
  • Non-Goals:
    • no full image.generate / image.edit abstraction yet
    • no new task type
    • no forced removal of existing fallback behavior during rollout
    • no commitment that Tuzi edit uses the same transport shape as official GPT edit

Decisions

  • Decision: Keep image contract selection on ProviderProfile.

    The compatibility difference is caused by the selected profile and API key, not by the model ID alone. The contract selector therefore remains a profile-level field.

  • Decision: Refine the internal compatibility enum.

    type ImageApiCompatibility =
      | 'auto'
      | 'openai-gpt-image'
      | 'tuzi-gpt-image'
      | 'openai-compatible-basic';
    

    Legacy value tuzi-compatible is accepted as an alias and normalized to tuzi-gpt-image.

  • Decision: auto is a resolver, not a wire protocol.

    auto stays stored on profiles. Runtime resolution maps it to a concrete internal mode based on profile metadata and selected model.

  • Decision: requestSchema is the adapter dispatch boundary.

    metadata.image.resolvedImageApiCompatibility is observability context. It is not enough on its own. Real ownership changes only when routing emits a distinct request schema that resolves to a distinct adapter.

  • Decision: Introduce a dedicated Tuzi GPT adapter.

    Tuzi GPT compatibility should no longer be implemented as GPT-specific special cases inside default-adapters.ts. The generic default/basic adapter remains the fallback for broad OpenAI-compatible gateways.

  • Decision: Keep the main settings UI simpler than the internal state model.

    The UI should primarily steer users toward explicit override choices for:

    • OpenAI GPT Image
    • Tuzi GPT 兼容

    Profiles that still store auto or openai-compatible-basic should remain supported, but those modes are treated as internal or migration-oriented rather than first-class marketing options.

  • Decision: Default profile creation to explicit official GPT mode.

    New provider profiles should start with imageApiCompatibility = openai-gpt-image so the common path is explicit rather than hidden behind auto.

  • Decision: Managed profile rebuilds must preserve stored overrides.

    Built-in managed profiles such as the legacy default and Tuzi presets may be reconstructed by settings compatibility helpers. Their rebuild path must preserve any stored imageApiCompatibility override instead of resetting the field to auto.

  • Decision: Only migrate missing defaults, not explicit auto.

    Historical profiles that explicitly store auto may reflect deliberate operator intent. We should migrate missing compatibility fields and managed-profile defaults to openai-gpt-image, but avoid silently rewriting explicit auto on custom profiles.

Internal Compatibility Model

Stored Values

  • auto
  • openai-gpt-image
  • tuzi-gpt-image
  • openai-compatible-basic

Accepted Legacy Alias

  • tuzi-compatible -> normalize to tuzi-gpt-image

Auto Resolution Rules

auto resolves only for GPT Image models. Non-GPT image models continue using their existing model-specific routing rules.

Profile / model condition Resolved mode
api.openai.com + GPT Image model openai-gpt-image
api.tu-zi.com + GPT Image model tuzi-gpt-image
other profile + GPT Image model openai-compatible-basic

Manual non-auto values always win.

Request Schema Mapping

The routing layer should produce a schema that matches the resolved compatibility mode.

Resolved mode Operation Request schema Adapter
openai-gpt-image generation openai.image.gpt-generation-json gpt-image-adapter
openai-gpt-image edit openai.image.gpt-edit-form gpt-image-adapter
tuzi-gpt-image generation tuzi.image.gpt-generation-json tuzi-gpt-image-adapter
tuzi-gpt-image edit (phase 2) dedicated Tuzi edit schema tuzi-gpt-image-adapter
openai-compatible-basic generation / compatibility fallback openai.image.basic-json default/basic adapter

The key architectural change is that tuzi-gpt-image stops being metadata-only and becomes a real dispatch target.

Adapter Responsibilities

gpt-image-adapter

  • own official GPT Image generation and edit
  • own official size and quality semantics
  • own official /images/edits multipart transport
  • remain selected only by the official GPT request schemas

tuzi-gpt-image-adapter

  • own Tuzi GPT-specific request serialization
  • translate project-level image parameters into the Tuzi GPT contract
  • own the current resolution -> legacy quality(1k|2k|4k) folding behavior
  • keep official GPT-only fields internal unless Tuzi later exposes matching support
  • become the future home for Tuzi edit transport once phase 2 begins

default/basic image adapter

  • remain the generic fallback for openai-compatible-basic
  • keep serving non-GPT OpenAI-compatible image providers
  • stop owning GPT-specific Tuzi translation rules after migration

Contract Semantics

Official GPT Image Contract

  • quality: official values auto | low | medium | high
  • size: official GPT size value
  • resolution: internal convenience only; it may help the UI choose a concrete size, but it is not the outbound official quality field
  • edit transport: multipart/form-data for /images/edits

Tuzi GPT Contract

  • size: outbound value stays compatible with Tuzi expectations
  • resolution: compatibility concept used to derive the legacy quality tier when needed
  • outbound quality: legacy compatibility value such as 1k | 2k | 4k
  • official GPT quality remains an internal setting unless and until Tuzi explicitly supports the same meaning
  • phase 2 decides the final Tuzi edit transport contract independently from official multipart semantics

Generic OpenAI-Compatible Basic Contract

  • remains a compatibility fallback
  • does not become the primary home for GPT-specific translation logic

UI Model

Primary user-facing override options:

  • OpenAI GPT Image
  • Tuzi GPT 兼容

Support behavior:

  • new profiles default to OpenAI GPT Image
  • built-in managed profiles default to OpenAI GPT Image when they have no stored override
  • profiles with no explicit stored compatibility from older data are upgraded to OpenAI GPT Image
  • profiles that already store auto remain on auto
  • the settings UI can show a resolved summary for auto, for example “自动判断,当前解析为 OpenAI GPT Image”
  • openai-compatible-basic remains supported for migration, diagnostics, and rollback, but does not need to be a prominent everyday choice

Migration

  • Preserve explicit stored auto values on custom profiles.
  • Do not reinterpret existing auto on official OpenAI profiles as basic fallback.
  • Normalize legacy tuzi-compatible values to tuzi-gpt-image.
  • Keep openai-compatible-basic valid for existing profiles and rollback scenarios.
  • Default newly created profiles to openai-gpt-image.
  • Default managed profiles to openai-gpt-image when they do not already store a compatibility override.
  • Upgrade profiles that are missing the compatibility field to openai-gpt-image.
  • When copying or exporting profiles, preserve the stored compatibility mode exactly.
  • Managed profile rebuild helpers must preserve explicit stored compatibility values rather than resetting them to auto.

Rollout Phases

Phase 1

  • add enum and alias normalization
  • add tuzi-gpt-image resolver branch
  • add tuzi.image.gpt-generation-json
  • add tuzi-gpt-image-adapter
  • move Tuzi GPT generation translation logic out of default-adapters.ts
  • keep official GPT generation/edit unchanged

Phase 2

  • define Tuzi edit request schema and transport
  • route Tuzi GPT image-edit requests through tuzi-gpt-image-adapter
  • extend planner, persistence, and tests for the dedicated Tuzi edit path

Observability

Diagnostics should expose:

  • stored imageApiCompatibility
  • resolved compatibility mode
  • requestSchema
  • adapter ID
  • submit path
  • whether the request used generation or edit semantics

API keys and authorization headers must never be logged.

Risks

  • aggressive alias migration could accidentally rewrite user intent
  • default migration could accidentally rewrite explicit auto if missing-vs-explicit state is not distinguished carefully
  • auto could still mis-resolve for unusual custom gateways
  • moving GPT translation out of the default adapter could regress current Tuzi behavior if request parity tests are weak
  • UI simplification could hide recovery options unless diagnostics remain visible
  • phase 2 could be delayed, leaving generation cleanly separated while Tuzi edit still relies on fallback behavior