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

@@ -1595,10 +1595,23 @@ function parseDraftGenerationStartedAtMs(value: string | null | undefined) {
function createMiniGameDraftGenerationStateFromStartedAt(
kind: MiniGameDraftGenerationKind,
startedAtMs: number,
metadata?: MiniGameDraftGenerationState['metadata'],
): MiniGameDraftGenerationState {
return {
...createMiniGameDraftGenerationState(kind),
startedAtMs,
...(metadata ? { metadata } : {}),
};
}
function createPuzzleDraftGenerationStateFromPayload(
payload: CreatePuzzleAgentSessionRequest | null | undefined,
): MiniGameDraftGenerationState {
return {
...createMiniGameDraftGenerationState('puzzle'),
metadata: {
puzzleAiRedraw: payload?.aiRedraw ?? true,
},
};
}
@@ -4499,7 +4512,9 @@ export function PlatformEntryFlowShellImpl({
markPendingDraftGenerating('puzzle', session.sessionId);
selectionStageRef.current = 'puzzle-generating';
setSelectionStage('puzzle-generating');
const nextGenerationState = createMiniGameDraftGenerationState('puzzle');
const nextGenerationState = createPuzzleDraftGenerationStateFromPayload(
formPayload ?? buildPuzzleFormPayloadFromSession(session),
);
setPuzzleGenerationState(nextGenerationState);
setPuzzleBackgroundCompileTasks((current) => ({
...current,
@@ -4515,14 +4530,14 @@ export function PlatformEntryFlowShellImpl({
if (payload.action !== 'compile_puzzle_draft') {
return;
}
const generationState =
puzzleBackgroundCompileTasks[session.sessionId]?.generationState ??
puzzleGenerationState ??
createMiniGameDraftGenerationState('puzzle');
const formPayload =
buildPuzzleFormPayloadFromAction(payload) ??
puzzleBackgroundCompileTasks[session.sessionId]?.payload ??
buildPuzzleFormPayloadFromSession(session);
const generationState =
puzzleBackgroundCompileTasks[session.sessionId]?.generationState ??
puzzleGenerationState ??
createPuzzleDraftGenerationStateFromPayload(formPayload);
const recovered = await recoverCompletedPuzzleDraftGeneration({
sessionId: session.sessionId,
payload: formPayload,
@@ -5017,7 +5032,7 @@ export function PlatformEntryFlowShellImpl({
return;
}
const generationState = createMiniGameDraftGenerationState('puzzle');
const generationState = createPuzzleDraftGenerationStateFromPayload(payload);
setPuzzleBackgroundCompileTasks((current) => ({
...current,
[nextSession.sessionId]: {
@@ -7497,7 +7512,10 @@ export function PlatformEntryFlowShellImpl({
);
const startPuzzleTestRunFromDraft = useCallback(
async (draft: PuzzleResultDraft) => {
async (
draft: PuzzleResultDraft,
options: { levelId?: string | null } = {},
) => {
if (isPuzzleBusy) {
return false;
}
@@ -7526,7 +7544,7 @@ export function PlatformEntryFlowShellImpl({
coverAssetId: draft.coverAssetId,
levels: draft.levels ?? [],
});
const run = startLocalPuzzleRun(item);
const run = startLocalPuzzleRun(item, options.levelId ?? null);
setSelectedPuzzleDetail(item);
setPuzzleRun(run);
setPuzzleRuntimeAuthMode('default');
@@ -9286,6 +9304,11 @@ export function PlatformEntryFlowShellImpl({
createMiniGameDraftGenerationStateFromStartedAt(
'puzzle',
parseDraftGenerationStartedAtMs(item.updatedAt),
{
puzzleAiRedraw:
buildPuzzleFormPayloadFromSession(latestSession).aiRedraw ??
true,
},
),
);
enterCreateTab();