import { expect, test } from 'vitest'; import type { CustomWorldAgentOperationRecord, CustomWorldAgentSessionSnapshot, } from '../../packages/shared/src/contracts/customWorldAgent'; import { buildAgentDraftFoundationGenerationProgress, buildAgentDraftFoundationSettingText, isDraftFoundationOperationRunning, } from './customWorldAgentGenerationProgress'; const baseOperation: CustomWorldAgentOperationRecord = { operationId: 'operation-1', type: 'draft_foundation', status: 'running', phaseLabel: '生成世界底稿', phaseDetail: '正在根据已确认锚点编译第一版世界结构。', progress: 38, error: null, }; const baseSession: CustomWorldAgentSessionSnapshot = { sessionId: 'session-1', stage: 'foundation_review', focusCardId: null, creatorIntent: { sourceMode: 'card', worldHook: '海雾、旧灯塔和失控航路交织的边缘群岛', themeKeywords: ['海雾', '灯塔', '旧航路'], toneDirectives: ['压抑', '悬疑'], playerPremise: '玩家刚回到群岛,准备调查父亲沉船的真相。', openingSituation: '首夜就有陌生船只在禁航区点灯。', coreConflicts: ['航运公会与守灯会争夺航路控制权'], keyFactions: [], keyCharacters: [], keyLandmarks: [], iconicElements: ['会移动的海雾'], forbiddenDirectives: [], rawSettingText: '', }, creatorIntentReadiness: { isReady: true, completedKeys: [], missingKeys: [], }, anchorPack: null, lockState: null, draftProfile: null, messages: [ { id: 'message-1', role: 'user', kind: 'chat', text: '我想做一个被海雾吞没的旧航路世界。', createdAt: '2026-04-14T10:00:00.000Z', relatedOperationId: null, }, ], draftCards: [], pendingClarifications: [], suggestedActions: [], recommendedReplies: [], qualityFindings: [], assetCoverage: { roleAssets: [], sceneAssets: [], allRoleAssetsReady: false, allSceneAssetsReady: false, }, updatedAt: '2026-04-14T10:00:00.000Z', }; test('maps running draft_foundation operation to legacy generation progress', () => { const progress = buildAgentDraftFoundationGenerationProgress( baseOperation, 1_000, 5_000, ); expect(progress).not.toBeNull(); expect(progress?.phaseId).toBe('foundation'); expect(progress?.batchLabel).toBe('生成世界底稿'); expect(progress?.overallProgress).toBe(38); expect(progress?.elapsedMs).toBe(4_000); expect(progress?.estimatedRemainingMs).toBeGreaterThan(0); expect(progress?.steps.map((step) => step.status)).toEqual([ 'completed', 'active', 'pending', 'pending', ]); expect(isDraftFoundationOperationRunning(baseOperation)).toBe(true); }); test('marks all legacy progress steps complete when draft foundation finishes', () => { const progress = buildAgentDraftFoundationGenerationProgress( { ...baseOperation, status: 'completed', phaseLabel: '世界底稿已生成', phaseDetail: '第一版世界底稿和 6 张草稿卡已经整理完成。', progress: 100, }, 1_000, 5_000, ); expect(progress?.phaseId).toBe('workspace'); expect(progress?.estimatedRemainingMs).toBe(0); expect(progress?.steps.every((step) => step.status === 'completed')).toBe( true, ); }); test('builds readable draft setting text from creator intent first', () => { const settingText = buildAgentDraftFoundationSettingText(baseSession); expect(settingText).toContain('世界核心命题'); expect(settingText).toContain('玩家身份'); expect(settingText).toContain('标志性要素'); }); test('falls back to latest user message when creator intent is unavailable', () => { const settingText = buildAgentDraftFoundationSettingText({ ...baseSession, creatorIntent: null, }); expect(settingText).toBe('我想做一个被海雾吞没的旧航路世界。'); });