Switch to VectorEngine gpt-image-2 and edits

Replace uses of the legacy `gpt-image-2-all` model with `gpt-image-2` and standardize image workflows: no-reference generation uses POST /v1/images/generations, any-reference flows use POST /v1/images/edits with multipart `image` parts. Update SKILLs, generation scripts, decision logs, and docs to reflect the contract change and edits-vs-generations guidance. Apply corresponding changes across backend (api-server match3d/puzzle modules, openai image adapter, mappers, telemetry, spacetime client/module), frontend components and services (Match3D, Puzzle, CreativeImageInputPanel, runtime shells), and add new spritesheet/parser files and tests. Also add media/logo.png. These changes align repository code and documentation with the VectorEngine image API contract and update generation/upload handling (green-screen -> alpha processing, spritesheet handling, and related tests).
This commit is contained in:
2026-05-22 03:06:41 +08:00
parent 321e1ea33a
commit ae014ac881
90 changed files with 7078 additions and 3389 deletions

View File

@@ -38,6 +38,7 @@ export type CreativeImageInputPanelProps = {
mainImageMode?: 'edit' | 'preview';
canRemoveMainImage?: boolean;
canToggleAiRedraw?: boolean;
canUploadPromptReferences?: boolean;
uploadedImageSrc: string;
uploadedImageAlt: string;
uploadedImageRefreshKey?: string | number | null;
@@ -79,6 +80,7 @@ export function CreativeImageInputPanel({
mainImageMode = 'edit',
canRemoveMainImage = true,
canToggleAiRedraw = true,
canUploadPromptReferences,
uploadedImageSrc,
uploadedImageAlt,
uploadedImageRefreshKey = null,
@@ -114,6 +116,8 @@ export function CreativeImageInputPanel({
const [isRemoveImageConfirmOpen, setIsRemoveImageConfirmOpen] =
useState(false);
const showPrompt = mainImageMode === 'preview' || !uploadedImageSrc || aiRedraw;
const shouldShowPromptReferences =
canUploadPromptReferences ?? !uploadedImageSrc;
const promptReferenceUploadDisabled =
disabled || promptReferenceImages.length >= promptReferenceLimit;
const canEditMainImage = mainImageMode === 'edit';
@@ -157,7 +161,7 @@ export function CreativeImageInputPanel({
{labels.imageField}
</div>
<div className="creative-image-input-panel__image-frame puzzle-image-card-frame flex min-h-0 flex-1 items-center justify-center">
<div className="creative-image-input-panel__image-card puzzle-image-upload-card relative aspect-square h-full max-h-full max-w-full overflow-hidden rounded-[1.25rem] border border-[var(--platform-subpanel-border)] bg-white/90 shadow-[0_12px_28px_rgba(15,23,42,0.08)] transition lg:h-auto lg:w-full">
<div className="creative-image-input-panel__image-card puzzle-image-upload-card relative aspect-square h-full min-h-[14rem] max-h-full max-w-full overflow-hidden rounded-[1.25rem] border border-[var(--platform-subpanel-border)] bg-white/90 shadow-[0_12px_28px_rgba(15,23,42,0.08)] transition sm:min-h-[18rem] lg:h-auto lg:w-full">
{canEditMainImage ? (
<>
<input
@@ -292,7 +296,7 @@ export function CreativeImageInputPanel({
aria-label={promptAriaLabel ?? promptLabel}
/>
{imageModelPicker}
{!uploadedImageSrc && onPromptReferenceFilesSelect ? (
{shouldShowPromptReferences && onPromptReferenceFilesSelect ? (
<label
className={`absolute bottom-3 right-3 z-10 inline-flex h-8 w-8 items-center justify-center rounded-full border border-[var(--platform-subpanel-border)] bg-white/96 text-[var(--platform-text-strong)] shadow-sm transition hover:bg-[var(--platform-subpanel-fill)] hover:text-[var(--platform-accent)] ${
promptReferenceUploadDisabled
@@ -321,7 +325,7 @@ export function CreativeImageInputPanel({
</label>
) : null}
</div>
{!uploadedImageSrc && promptReferenceImages.length > 0 ? (
{shouldShowPromptReferences && promptReferenceImages.length > 0 ? (
<div className="mt-2 flex flex-wrap gap-2">
{promptReferenceImages.map((reference) => (
<div