合并主分支
解决合并冲突
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
generateEditorCharacterAnimation,
|
||||
generateEditorIconSpritesheet,
|
||||
generateEditorImage,
|
||||
generateEditorScene,
|
||||
generateEditorSoundEffect,
|
||||
generateEditorVideo,
|
||||
listEditorProjects,
|
||||
@@ -966,6 +967,60 @@ describe('editorProjectClient', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('generates editor scenes through the structured endpoint without automatic retries', async () => {
|
||||
requestJsonMock.mockResolvedValueOnce({
|
||||
queueState: { jobId: 'scene-job-1', status: 'pending' },
|
||||
});
|
||||
|
||||
await generateEditorScene({
|
||||
sceneContent: '雨夜中的欧洲小镇街道',
|
||||
stylePreset: 'anime',
|
||||
model: 'gemini-3.1-flash-image-preview',
|
||||
aspectRatio: '16:9',
|
||||
imageSize: '1K',
|
||||
referenceImageSrcs: ['editor-resource-reference'],
|
||||
});
|
||||
|
||||
expect(requestJsonMock).toHaveBeenCalledWith(
|
||||
'/api/editor/scenes/generations',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
sceneContent: '雨夜中的欧洲小镇街道',
|
||||
stylePreset: 'anime',
|
||||
model: 'gemini-3.1-flash-image-preview',
|
||||
aspectRatio: '16:9',
|
||||
imageSize: '1K',
|
||||
referenceImageSrcs: ['editor-resource-reference'],
|
||||
}),
|
||||
}),
|
||||
'生成游戏场景失败',
|
||||
expect.objectContaining({
|
||||
timeoutMs: 1_200_000,
|
||||
retry: {
|
||||
maxRetries: 0,
|
||||
retryUnsafeMethods: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects scene reference overflow without sending an HTTP request', async () => {
|
||||
await expect(
|
||||
generateEditorScene({
|
||||
sceneContent: '雨夜中的欧洲小镇街道',
|
||||
stylePreset: 'anime',
|
||||
referenceImageSrcs: Array.from(
|
||||
{ length: 6 },
|
||||
(_, index) =>
|
||||
`/generated-images/editor/scene-reference-${index + 1}.png`,
|
||||
),
|
||||
}),
|
||||
).rejects.toThrow('场景参考图最多允许 5 张');
|
||||
|
||||
expect(requestJsonMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects inline media before submitting editor generation requests', async () => {
|
||||
await expect(
|
||||
generateEditorImage({
|
||||
|
||||
@@ -2,6 +2,7 @@ import type {
|
||||
BackgroundMusicPromptAssistRequest,
|
||||
BackgroundMusicPromptAssistResponse,
|
||||
} from '../../../packages/shared/src/contracts/editorAudio';
|
||||
import type { EditorSceneGenerationRequest } from '../../../packages/shared/src/contracts/editorScene';
|
||||
import type { ExternalGenerationJobStatusRecord } from '../../../packages/shared/src/contracts/externalGeneration';
|
||||
import { requestJson } from '../apiClient';
|
||||
import { EDITOR_GENERATION_REQUEST_RETRY_OPTIONS } from './editorRetryOptions';
|
||||
@@ -12,6 +13,7 @@ const EDITOR_SHOWCASE_RESOURCE_API = '/api/editor/showcase/resources';
|
||||
const EDITOR_SHOWCASE_ASSET_API_BASE = '/api/editor/showcase/assets';
|
||||
const EDITOR_PROJECT_RESOURCE_API_BASE = '/api/editor/project-resources';
|
||||
const EDITOR_IMAGE_GENERATION_API = '/api/editor/images/generations';
|
||||
const EDITOR_SCENE_GENERATION_API = '/api/editor/scenes/generations';
|
||||
const EDITOR_IMAGE_EDIT_API = '/api/editor/images/edits';
|
||||
const EDITOR_BACKGROUND_REMOVAL_API = '/api/editor/images/background-removals';
|
||||
const EDITOR_PIXEL_ART_SNAP_API = '/api/editor/images/pixel-art-snaps';
|
||||
@@ -1036,6 +1038,45 @@ export async function toggleEditorShowcaseAssetLike(
|
||||
return response.showcaseAsset;
|
||||
}
|
||||
|
||||
export type EditorSceneGenerationInput = EditorSceneGenerationRequest;
|
||||
|
||||
export async function generateEditorScene(input: EditorSceneGenerationInput) {
|
||||
assertStableEditorMediaReferences(input.referenceImageSrcs, '场景参考图');
|
||||
assertEditorReferenceLimit(
|
||||
input.referenceImageSrcs,
|
||||
EDITOR_IMAGE_REFERENCE_LIMIT,
|
||||
'场景参考图',
|
||||
);
|
||||
return requestJson<EditorImageGenerationResponse>(
|
||||
EDITOR_SCENE_GENERATION_API,
|
||||
jsonRequest('POST', {
|
||||
sceneContent: input.sceneContent,
|
||||
stylePreset: input.stylePreset,
|
||||
...(input.customStyle ? { customStyle: input.customStyle } : {}),
|
||||
...(input.model ? { model: input.model } : {}),
|
||||
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
|
||||
...(input.imageSize ? { imageSize: input.imageSize } : {}),
|
||||
...(input.referenceImageSrcs?.length
|
||||
? { referenceImageSrcs: input.referenceImageSrcs }
|
||||
: {}),
|
||||
...(input.projectId ? { projectId: input.projectId } : {}),
|
||||
...(input.generationInputs
|
||||
? { generationInputs: input.generationInputs }
|
||||
: {}),
|
||||
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
||||
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
|
||||
...(input.canvasCompletion
|
||||
? { canvasCompletion: input.canvasCompletion }
|
||||
: {}),
|
||||
}),
|
||||
'生成游戏场景失败',
|
||||
{
|
||||
timeoutMs: 1_200_000,
|
||||
retry: EDITOR_GENERATION_REQUEST_RETRY_OPTIONS,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateEditorImage(input: EditorImageGenerationInput) {
|
||||
assertStableEditorMediaReferences(input.referenceImageSrcs, '生成参考图');
|
||||
const referenceLimit =
|
||||
|
||||
Reference in New Issue
Block a user