1
This commit is contained in:
@@ -421,6 +421,162 @@ test('phase4 sync_result_profile keeps existing foundation structure while updat
|
||||
);
|
||||
});
|
||||
|
||||
test('phase4 sync_result_profile also writes latest role and scene assets back into draft profile', async () => {
|
||||
const runtimeRepository = createRuntimeRepositoryStub();
|
||||
const sessionStore = new CustomWorldAgentSessionStore(runtimeRepository);
|
||||
const orchestrator = new CustomWorldAgentOrchestrator(sessionStore, null, {
|
||||
singleTurnLlmClient: createTestCustomWorldAgentSingleTurnLlmClient(),
|
||||
});
|
||||
const userId = 'user-phase4-sync-result-profile-assets';
|
||||
const session = await createObjectRefiningSession(orchestrator, userId);
|
||||
const baselineProfile = normalizeFoundationDraftProfile(session.draftProfile)!;
|
||||
const playableRole = baselineProfile.playableNpcs[0]!;
|
||||
const storyRole = baselineProfile.storyNpcs[0]!;
|
||||
const landmark = baselineProfile.landmarks[0]!;
|
||||
|
||||
const response = await orchestrator.executeAction(userId, session.sessionId, {
|
||||
action: 'sync_result_profile',
|
||||
profile: {
|
||||
id: `agent-draft-${session.sessionId}`,
|
||||
settingText: '被海雾吞没的旧航路群岛',
|
||||
name: '潮雾列岛·结果页精修版',
|
||||
subtitle: '旧灯塔与失控航路',
|
||||
summary: '结果页已经把最新图与动作一起确认。 ',
|
||||
tone: '压抑、潮湿、悬疑',
|
||||
playerGoal: '查清沉船夜与假航灯的真正操盘者。',
|
||||
templateWorldType: 'WUXIA',
|
||||
majorFactions: ['守灯会', '航运公会'],
|
||||
coreConflicts: ['守灯会与航运公会争夺旧航路控制权'],
|
||||
attributeSchema: {
|
||||
id: 'schema:test',
|
||||
worldId: 'CUSTOM',
|
||||
schemaVersion: 1,
|
||||
schemaName: '测试',
|
||||
generatedFrom: {
|
||||
worldType: 'CUSTOM',
|
||||
worldName: '潮雾列岛·结果页精修版',
|
||||
settingSummary: '测试',
|
||||
tone: '测试',
|
||||
conflictCore: '测试',
|
||||
},
|
||||
slots: [],
|
||||
},
|
||||
playableNpcs: [
|
||||
{
|
||||
id: playableRole.id,
|
||||
name: playableRole.name,
|
||||
title: '结果页角色',
|
||||
role: '关键同行者',
|
||||
description: '结果页确认的最新角色资产。',
|
||||
backstory: '测试',
|
||||
personality: '冷静',
|
||||
motivation: '验证资产回写',
|
||||
combatStyle: '观察',
|
||||
initialAffinity: 12,
|
||||
relationshipHooks: [],
|
||||
tags: [],
|
||||
imageSrc: '/generated/playable/latest-master.png',
|
||||
generatedVisualAssetId: 'visual-playable-latest',
|
||||
generatedAnimationSetId: 'anim-playable-latest',
|
||||
animationMap: {
|
||||
idle: {
|
||||
spriteSheetPath: '/generated/playable/idle.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
storyNpcs: [
|
||||
{
|
||||
id: storyRole.id,
|
||||
name: storyRole.name,
|
||||
title: '结果页场景角色',
|
||||
role: '场景关键角色',
|
||||
description: '结果页确认的最新场景角色资产。',
|
||||
backstory: '测试',
|
||||
personality: '克制',
|
||||
motivation: '验证资产回写',
|
||||
combatStyle: '观察',
|
||||
initialAffinity: 6,
|
||||
relationshipHooks: [],
|
||||
tags: [],
|
||||
imageSrc: '/generated/story/latest-master.png',
|
||||
generatedVisualAssetId: 'visual-story-latest',
|
||||
},
|
||||
],
|
||||
items: [],
|
||||
landmarks: [
|
||||
{
|
||||
id: landmark.id,
|
||||
name: landmark.name,
|
||||
description: '结果页确认的最新地点图。',
|
||||
dangerLevel: '中',
|
||||
sceneNpcIds: [],
|
||||
connections: [],
|
||||
imageSrc: '/generated/landmark/latest-scene.png',
|
||||
},
|
||||
],
|
||||
sceneChapterBlueprints: [
|
||||
{
|
||||
id: 'scene-chapter-1',
|
||||
sceneId: landmark.id,
|
||||
title: '灯塔初章',
|
||||
summary: '结果页确认最新分幕图。',
|
||||
linkedThreadIds: [],
|
||||
linkedLandmarkIds: [landmark.id],
|
||||
acts: [
|
||||
{
|
||||
id: `${landmark.id}-act-1`,
|
||||
sceneId: landmark.id,
|
||||
title: '第一幕',
|
||||
summary: '第一幕',
|
||||
stageCoverage: ['opening'],
|
||||
backgroundImageSrc: '/generated/scene/act-1-latest.png',
|
||||
backgroundAssetId: 'scene-asset-latest',
|
||||
encounterNpcIds: [],
|
||||
primaryNpcId: '',
|
||||
linkedThreadIds: [],
|
||||
advanceRule: 'after_primary_contact',
|
||||
actGoal: '验证分幕图回写',
|
||||
transitionHook: '进入下一幕',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
generationMode: 'full',
|
||||
generationStatus: 'complete',
|
||||
},
|
||||
});
|
||||
const operation = await waitForOperation(
|
||||
orchestrator,
|
||||
userId,
|
||||
session.sessionId,
|
||||
response.operation.operationId,
|
||||
);
|
||||
const snapshot = await orchestrator.getSessionSnapshot(userId, session.sessionId);
|
||||
const profile = normalizeFoundationDraftProfile(snapshot?.draftProfile)!;
|
||||
const syncedPlayable = profile.playableNpcs.find(
|
||||
(entry) => entry.id === playableRole.id,
|
||||
);
|
||||
const syncedStory = profile.storyNpcs.find((entry) => entry.id === storyRole.id);
|
||||
const syncedLandmark = profile.landmarks.find((entry) => entry.id === landmark.id);
|
||||
const syncedSceneAct = profile.sceneChapters[0]?.acts[0];
|
||||
|
||||
assert.equal(operation?.status, 'completed');
|
||||
assert.equal(syncedPlayable?.imageSrc, '/generated/playable/latest-master.png');
|
||||
assert.equal(syncedPlayable?.generatedVisualAssetId, 'visual-playable-latest');
|
||||
assert.equal(syncedPlayable?.generatedAnimationSetId, 'anim-playable-latest');
|
||||
assert.deepEqual(syncedPlayable?.animationMap, {
|
||||
idle: {
|
||||
spriteSheetPath: '/generated/playable/idle.png',
|
||||
},
|
||||
});
|
||||
assert.equal(syncedStory?.imageSrc, '/generated/story/latest-master.png');
|
||||
assert.equal(syncedStory?.generatedVisualAssetId, 'visual-story-latest');
|
||||
assert.equal(syncedLandmark?.imageSrc, '/generated/landmark/latest-scene.png');
|
||||
assert.equal(syncedSceneAct?.backgroundImageSrc, '/generated/scene/act-1-latest.png');
|
||||
assert.equal(syncedSceneAct?.backgroundAssetId, 'scene-asset-latest');
|
||||
});
|
||||
|
||||
test('phase4 generate_characters appends story npcs and updates work summary counts', async () => {
|
||||
const runtimeRepository = createRuntimeRepositoryStub();
|
||||
const sessionStore = new CustomWorldAgentSessionStore(runtimeRepository);
|
||||
|
||||
Reference in New Issue
Block a user