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-jsonand 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
autoas a resolver - give Tuzi GPT compatibility a real adapter boundary
- preserve the current official GPT adapter and schema split
- preserve
openai-compatible-basicas 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.editabstraction 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
- no full
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-compatibleis accepted as an alias and normalized totuzi-gpt-image. -
Decision:
autois a resolver, not a wire protocol.autostays stored on profiles. Runtime resolution maps it to a concrete internal mode based on profile metadata and selected model. -
Decision:
requestSchemais the adapter dispatch boundary.metadata.image.resolvedImageApiCompatibilityis 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 ImageTuzi GPT 兼容
Profiles that still store
autooropenai-compatible-basicshould 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-imageso the common path is explicit rather than hidden behindauto. -
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
imageApiCompatibilityoverride instead of resetting the field toauto. -
Decision: Only migrate missing defaults, not explicit
auto.Historical profiles that explicitly store
automay reflect deliberate operator intent. We should migrate missing compatibility fields and managed-profile defaults toopenai-gpt-image, but avoid silently rewriting explicitautoon custom profiles.
Internal Compatibility Model
Stored Values
autoopenai-gpt-imagetuzi-gpt-imageopenai-compatible-basic
Accepted Legacy Alias
tuzi-compatible-> normalize totuzi-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/editsmultipart 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 valuesauto | low | medium | highsize: official GPT size valueresolution: 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 expectationsresolution: compatibility concept used to derive the legacy quality tier when needed- outbound
quality: legacy compatibility value such as1k | 2k | 4k - official GPT
qualityremains 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 ImageTuzi GPT 兼容
Support behavior:
- new profiles default to
OpenAI GPT Image - built-in managed profiles default to
OpenAI GPT Imagewhen they have no stored override - profiles with no explicit stored compatibility from older data are upgraded to
OpenAI GPT Image - profiles that already store
autoremain onauto - the settings UI can show a resolved summary for
auto, for example “自动判断,当前解析为 OpenAI GPT Image” openai-compatible-basicremains supported for migration, diagnostics, and rollback, but does not need to be a prominent everyday choice
Migration
- Preserve explicit stored
autovalues on custom profiles. - Do not reinterpret existing
autoon official OpenAI profiles as basic fallback. - Normalize legacy
tuzi-compatiblevalues totuzi-gpt-image. - Keep
openai-compatible-basicvalid for existing profiles and rollback scenarios. - Default newly created profiles to
openai-gpt-image. - Default managed profiles to
openai-gpt-imagewhen 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-imageresolver 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
autoif missing-vs-explicit state is not distinguished carefully autocould 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