重构:统一编辑器工作流中的 "icon-spec" 处理
- 将所有相关工作流从 "ui-spec" 迁移至 "icon-spec"。 - 优化 `playSetting` 和 `artStyle` 的输入处理逻辑。 - 更新编辑器提示词、提交模型及测试用例以适配 "icon-spec"。 - 在 UI 及后端调用中集成 `EDITOR_ICON_SPEC_PROMPT_MAX_LENGTH` 及相关校验。 - 新增 "icon-spec" 生成与微调的专用 API 路径。 - 移除旧版 "ui-spec" 相关定义及提示词构建器。
This commit is contained in:
@@ -8,6 +8,12 @@ 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_ICON_SPEC_GENERATION_API = '/api/editor/icon-specs/generations';
|
||||
const EDITOR_ICON_SPEC_REFINE_GAME_PLAY_API =
|
||||
'/api/editor/llm/icon-specs/refine-game-play';
|
||||
const EDITOR_ICON_SPEC_REFINE_ART_STYLE_API =
|
||||
'/api/editor/llm/icon-specs/refine-art-style';
|
||||
export const EDITOR_ICON_SPEC_PROMPT_MAX_LENGTH = 200;
|
||||
const EDITOR_IMAGE_EDIT_API = '/api/editor/images/edits';
|
||||
const EDITOR_BACKGROUND_REMOVAL_API = '/api/editor/images/background-removals';
|
||||
const EDITOR_ICON_SPRITESHEET_GENERATION_API =
|
||||
@@ -41,7 +47,18 @@ function assertStableEditorMediaReferences(
|
||||
values: readonly string[] | undefined,
|
||||
fieldLabel: string,
|
||||
) {
|
||||
values?.forEach((value) => assertStableEditorMediaReference(value, fieldLabel));
|
||||
values?.forEach((value) =>
|
||||
assertStableEditorMediaReference(value, fieldLabel),
|
||||
);
|
||||
}
|
||||
|
||||
function requireEditorIconSpecPromptLength(value: string, fieldLabel: string) {
|
||||
if (Array.from(value).length > EDITOR_ICON_SPEC_PROMPT_MAX_LENGTH) {
|
||||
throw new Error(
|
||||
`${fieldLabel}不能超过 ${EDITOR_ICON_SPEC_PROMPT_MAX_LENGTH} 个字符`,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function assertStableEditorVideoReferences(input: EditorVideoGenerationInput) {
|
||||
@@ -86,9 +103,7 @@ export type EditorAssetGenerationInputs = {
|
||||
};
|
||||
|
||||
export type EditorProjectResourceSourceType =
|
||||
| 'uploaded'
|
||||
| 'generated'
|
||||
| 'mock_generated';
|
||||
'uploaded' | 'generated' | 'mock_generated';
|
||||
|
||||
export type EditorProjectResourceSnapshot = {
|
||||
resourceId: string;
|
||||
@@ -190,11 +205,7 @@ export type EditorImageGenerationInput = {
|
||||
prompt: string;
|
||||
size?: string;
|
||||
kind?:
|
||||
| 'spec'
|
||||
| 'character'
|
||||
| 'quick-edit'
|
||||
| 'ui-design'
|
||||
| 'publication-material';
|
||||
'spec' | 'character' | 'quick-edit' | 'ui-design' | 'publication-material';
|
||||
model?: string;
|
||||
screenColor?: string;
|
||||
segModel?: string;
|
||||
@@ -211,6 +222,18 @@ export type EditorImageGenerationInput = {
|
||||
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
||||
};
|
||||
|
||||
export type EditorIconSpecGenerationInput = {
|
||||
playSetting: string;
|
||||
artStyle: string;
|
||||
referenceImageSrcs?: string[];
|
||||
projectId?: string | null;
|
||||
generationInputs?: EditorAssetGenerationInputs | null;
|
||||
assetFolderId?: string | null;
|
||||
assetLabel?: string | null;
|
||||
sourceResourceId?: string | null;
|
||||
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
||||
};
|
||||
|
||||
export type EditorCanvasGenerationCompletionInput = {
|
||||
dialogId?: string;
|
||||
title: string;
|
||||
@@ -358,12 +381,7 @@ export type EditorIconSpritesheetSliceResult = {
|
||||
export type EditorCharacterAnimationResolution = '480p' | '720p';
|
||||
|
||||
export type EditorCharacterAnimationRatio =
|
||||
| 'same'
|
||||
| '1:1'
|
||||
| '4:3'
|
||||
| '16:9'
|
||||
| '9:16'
|
||||
| '3:4';
|
||||
'same' | '1:1' | '4:3' | '16:9' | '9:16' | '3:4';
|
||||
|
||||
export type EditorCharacterAnimationFrameCount = 32 | 40 | 48;
|
||||
|
||||
@@ -424,12 +442,7 @@ export type EditorVideoModel =
|
||||
export type EditorVideoResolution = '480p' | '720p' | '1080p';
|
||||
export type EditorVideoSoundMode = 'on' | 'off';
|
||||
export type EditorVideoAspectRatio =
|
||||
| '16:9'
|
||||
| '9:16'
|
||||
| '1:1'
|
||||
| '4:3'
|
||||
| '3:4'
|
||||
| '21:9';
|
||||
'16:9' | '9:16' | '1:1' | '4:3' | '3:4' | '21:9';
|
||||
|
||||
export type EditorVideoGenerationInput = {
|
||||
prompt: string;
|
||||
@@ -948,14 +961,75 @@ export async function generateEditorImage(input: EditorImageGenerationInput) {
|
||||
);
|
||||
}
|
||||
|
||||
export async function refineEditorIconSpecPlaySetting(playSetting: string) {
|
||||
const validPlaySetting = requireEditorIconSpecPromptLength(
|
||||
playSetting,
|
||||
'玩法设定',
|
||||
);
|
||||
const response = await requestJson<{ playSetting: string }>(
|
||||
EDITOR_ICON_SPEC_REFINE_GAME_PLAY_API,
|
||||
jsonRequest('POST', { playSetting: validPlaySetting }),
|
||||
'优化玩法设定失败',
|
||||
);
|
||||
return requireEditorIconSpecPromptLength(response.playSetting, '玩法设定');
|
||||
}
|
||||
|
||||
export async function refineEditorIconSpecArtStyle(artStyle: string) {
|
||||
const validArtStyle = requireEditorIconSpecPromptLength(artStyle, '美术风格');
|
||||
const response = await requestJson<{ artStyle: string }>(
|
||||
EDITOR_ICON_SPEC_REFINE_ART_STYLE_API,
|
||||
jsonRequest('POST', { artStyle: validArtStyle }),
|
||||
'优化美术风格失败',
|
||||
);
|
||||
return requireEditorIconSpecPromptLength(response.artStyle, '美术风格');
|
||||
}
|
||||
|
||||
export async function generateEditorIconSpec(
|
||||
input: EditorIconSpecGenerationInput,
|
||||
) {
|
||||
const playSetting = requireEditorIconSpecPromptLength(
|
||||
input.playSetting,
|
||||
'玩法设定',
|
||||
);
|
||||
const artStyle = requireEditorIconSpecPromptLength(
|
||||
input.artStyle,
|
||||
'美术风格',
|
||||
);
|
||||
assertStableEditorMediaReferences(input.referenceImageSrcs, '图标规范参考图');
|
||||
return requestJson<EditorImageGenerationResponse>(
|
||||
EDITOR_ICON_SPEC_GENERATION_API,
|
||||
jsonRequest('POST', {
|
||||
playSetting,
|
||||
artStyle,
|
||||
...(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.sourceResourceId
|
||||
? { sourceResourceId: input.sourceResourceId }
|
||||
: {}),
|
||||
...(input.canvasCompletion
|
||||
? { canvasCompletion: input.canvasCompletion }
|
||||
: {}),
|
||||
}),
|
||||
'生成图标规范失败',
|
||||
{
|
||||
timeoutMs: 1_200_000,
|
||||
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateEditorIconSpritesheet(
|
||||
input: EditorIconSpritesheetGenerationInput,
|
||||
) {
|
||||
assertStableEditorMediaReference(input.referenceImageSrc, '图标素材规范');
|
||||
assertStableEditorMediaReferences(
|
||||
input.referenceImageSrcs,
|
||||
'图标素材参考图',
|
||||
);
|
||||
assertStableEditorMediaReferences(input.referenceImageSrcs, '图标素材参考图');
|
||||
return requestJson<EditorIconSpritesheetGenerationResponse>(
|
||||
EDITOR_ICON_SPRITESHEET_GENERATION_API,
|
||||
jsonRequest('POST', {
|
||||
|
||||
Reference in New Issue
Block a user