1
This commit is contained in:
@@ -1,19 +1,37 @@
|
||||
import type { CustomWorldSceneImageRequest, CustomWorldSceneImageResult } from '../aiTypes';
|
||||
import {
|
||||
generateCustomWorldCoverImage,
|
||||
uploadCustomWorldCoverImage,
|
||||
} from '../customWorldCoverAssetService';
|
||||
import { requestJson } from '../apiClient';
|
||||
import { ASSET_API_PATHS } from '../../editor/shared/editorApiClient';
|
||||
import type {
|
||||
CustomWorldLandmark,
|
||||
CustomWorldNpc,
|
||||
CustomWorldPlayableNpc,
|
||||
CustomWorldProfile,
|
||||
} from '../../types';
|
||||
import type {
|
||||
CustomWorldSceneImageRequest,
|
||||
CustomWorldSceneImageResult,
|
||||
} from '../aiTypes';
|
||||
import { requestJson } from '../apiClient';
|
||||
import {
|
||||
generateCustomWorldCoverImage,
|
||||
uploadCustomWorldCoverImage,
|
||||
} from '../customWorldCoverAssetService';
|
||||
import { requestRpgCreationPostJson } from './rpgCreationRequestHelpers';
|
||||
|
||||
const RPG_CREATION_ASSET_API_BASE = '/api/custom-world';
|
||||
|
||||
export type RpgCreationHistoryAssetKind = 'character_visual' | 'scene_image';
|
||||
|
||||
export type RpgCreationHistoryAsset = {
|
||||
assetObjectId: string;
|
||||
assetKind: RpgCreationHistoryAssetKind;
|
||||
imageSrc: string;
|
||||
ownerUserId?: string | null;
|
||||
ownerLabel: string;
|
||||
profileId?: string | null;
|
||||
entityId?: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export async function generateRpgWorldSceneImage(
|
||||
payload: CustomWorldSceneImageRequest,
|
||||
) {
|
||||
@@ -28,6 +46,24 @@ export async function generateRpgWorldSceneImage(
|
||||
);
|
||||
}
|
||||
|
||||
export async function listRpgCreationHistoryAssets(payload: {
|
||||
kind: RpgCreationHistoryAssetKind;
|
||||
limit?: number;
|
||||
}) {
|
||||
const params = new URLSearchParams({ kind: payload.kind });
|
||||
if (payload.limit) {
|
||||
params.set('limit', String(payload.limit));
|
||||
}
|
||||
|
||||
const response = await requestJson<{ assets: RpgCreationHistoryAsset[] }>(
|
||||
`${ASSET_API_PATHS.assetHistory}?${params.toString()}`,
|
||||
{ method: 'GET' },
|
||||
'读取历史素材失败',
|
||||
);
|
||||
|
||||
return response.assets;
|
||||
}
|
||||
|
||||
export async function generateRpgWorldSceneNpc(payload: {
|
||||
profile: CustomWorldProfile;
|
||||
landmarkId: string;
|
||||
@@ -101,6 +137,7 @@ export async function generateRpgWorldLandmark(payload: {
|
||||
* 保留封面资产服务的既有边界,不把逻辑重新塞回 `aiService.ts`。
|
||||
*/
|
||||
export const rpgCreationAssetClient = {
|
||||
listHistoryAssets: listRpgCreationHistoryAssets,
|
||||
generateSceneImage: generateRpgWorldSceneImage,
|
||||
generateSceneNpc: generateRpgWorldSceneNpc,
|
||||
generatePlayableNpc: generateRpgWorldPlayableNpc,
|
||||
|
||||
@@ -202,12 +202,13 @@ test('buildRpgCreationPreviewFromResultPreview normalizes server preview envelop
|
||||
expect(profile?.settingText).toBe('被海雾吞没的旧航路群岛');
|
||||
});
|
||||
|
||||
test('buildRpgCreationPreviewFromSession prefers server result preview', () => {
|
||||
test('buildRpgCreationPreviewFromSession prefers agent draft profile', () => {
|
||||
const profile = buildRpgCreationPreviewFromSession(sessionWithPreview);
|
||||
|
||||
expect(profile?.name).toBe('服务端结果预览');
|
||||
expect(profile?.summary).toBe('结果页应该优先消费 session.resultPreview。');
|
||||
expect(profile?.id).toBe('preview-profile-1');
|
||||
expect(profile?.name).toBe('只作为 fallback 的本地草稿名');
|
||||
expect(profile?.summary).toBe('fallback');
|
||||
expect(profile?.id).toBe('draft-profile-1');
|
||||
expect(profile?.playableNpcs[0]?.id).toBe('draft-playable-1');
|
||||
});
|
||||
|
||||
test('buildRpgCreationPreviewFromSession does not require resultPreview', () => {
|
||||
|
||||
@@ -15,14 +15,14 @@ export function buildCustomWorldProfileFromAgentSession(
|
||||
session: CustomWorldAgentSessionSnapshot | null | undefined,
|
||||
): CustomWorldProfile | null {
|
||||
return (
|
||||
buildCustomWorldProfileFromResultPreview(session?.resultPreview) ??
|
||||
normalizeCustomWorldProfileRecord(session?.draftProfile ?? null)
|
||||
normalizeCustomWorldProfileRecord(session?.draftProfile ?? null) ??
|
||||
buildCustomWorldProfileFromResultPreview(session?.resultPreview)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 这是工作包 A 提供的新命名兼容层。
|
||||
* 主入口保持命名稳定,优先消费服务端 resultPreview,缺失时回退到 draftProfile。
|
||||
* 主入口保持命名稳定,优先消费 Agent 草稿真相源,缺失时才回退到 resultPreview。
|
||||
*/
|
||||
export const rpgCreationPreviewAdapter = {
|
||||
buildPreviewFromSession: buildCustomWorldProfileFromAgentSession,
|
||||
|
||||
Reference in New Issue
Block a user