200 lines
6.9 KiB
TypeScript
200 lines
6.9 KiB
TypeScript
import type {
|
|
CreatorIntentReadiness,
|
|
CustomWorldAgentStage,
|
|
CustomWorldAssetCoverageSummary,
|
|
CustomWorldDraftCardSummary,
|
|
CustomWorldPendingClarification,
|
|
EightAnchorContent,
|
|
} from '../../../packages/shared/src/contracts/customWorldAgent.js';
|
|
import {
|
|
buildDraftSummaryFromIntent,
|
|
buildDraftTitleFromIntent,
|
|
type CustomWorldCreatorIntentRecord,
|
|
} from './customWorldAgentIntentExtractionService.js';
|
|
import { CustomWorldAgentQualityGateService } from './customWorldAgentQualityGateService.js';
|
|
import { rebuildRoleAssetCoverage } from './customWorldAgentRoleAssetStateService.js';
|
|
import type { CustomWorldAgentSessionRecord } from './customWorldAgentSessionStore.js';
|
|
import { CustomWorldAgentSuggestedActionService } from './customWorldAgentSuggestedActionService.js';
|
|
import { buildAnchorPackFromEightAnchorContent } from './eightAnchorCompatibilityService.js';
|
|
import { CustomWorldAgentDraftCompiler } from './customWorldAgentDraftCompiler.js';
|
|
|
|
export type CustomWorldAgentDerivedStatePatch = Partial<
|
|
Pick<
|
|
CustomWorldAgentSessionRecord,
|
|
| 'currentTurn'
|
|
| 'anchorContent'
|
|
| 'progressPercent'
|
|
| 'lastAssistantReply'
|
|
| 'stage'
|
|
| 'focusCardId'
|
|
| 'creatorIntent'
|
|
| 'creatorIntentReadiness'
|
|
| 'anchorPack'
|
|
| 'draftProfile'
|
|
| 'pendingClarifications'
|
|
| 'suggestedActions'
|
|
| 'recommendedReplies'
|
|
| 'draftCards'
|
|
| 'qualityFindings'
|
|
| 'assetCoverage'
|
|
>
|
|
>;
|
|
|
|
export class CustomWorldAgentSnapshotBuilder {
|
|
constructor(
|
|
private readonly draftCompiler: CustomWorldAgentDraftCompiler,
|
|
private readonly suggestedActionService: CustomWorldAgentSuggestedActionService,
|
|
private readonly qualityGateService: CustomWorldAgentQualityGateService,
|
|
) {}
|
|
|
|
// 把“草稿改动后需要重算哪些派生字段”统一封装成一个入口,避免每个 action 都重复拼 patch。
|
|
buildRefiningState(params: {
|
|
previousStage: CustomWorldAgentStage;
|
|
draftProfile: Record<string, unknown>;
|
|
draftCards?: CustomWorldDraftCardSummary[];
|
|
assetCoverage?: CustomWorldAssetCoverageSummary;
|
|
nextStage?: Extract<
|
|
CustomWorldAgentStage,
|
|
| 'object_refining'
|
|
| 'visual_refining'
|
|
| 'long_tail_review'
|
|
| 'ready_to_publish'
|
|
>;
|
|
focusCardId?: string | null;
|
|
}): CustomWorldAgentDerivedStatePatch {
|
|
const nextDraftCards =
|
|
params.draftCards ?? this.draftCompiler.compileDraftCards(params.draftProfile);
|
|
const assetCoverage =
|
|
params.assetCoverage ?? rebuildRoleAssetCoverage(params.draftProfile);
|
|
const nextStage =
|
|
params.nextStage ??
|
|
(params.previousStage === 'visual_refining'
|
|
? 'visual_refining'
|
|
: params.previousStage === 'long_tail_review'
|
|
? 'long_tail_review'
|
|
: params.previousStage === 'ready_to_publish'
|
|
? 'ready_to_publish'
|
|
: 'object_refining');
|
|
|
|
return {
|
|
stage: nextStage,
|
|
draftProfile: params.draftProfile,
|
|
draftCards: nextDraftCards,
|
|
assetCoverage,
|
|
qualityFindings: this.qualityGateService.buildQualityFindings({
|
|
draftProfile: params.draftProfile,
|
|
assetCoverage,
|
|
stage: nextStage,
|
|
}),
|
|
focusCardId: params.focusCardId,
|
|
suggestedActions: this.suggestedActionService.buildSuggestedActions({
|
|
stage: nextStage,
|
|
isReady: true,
|
|
draftProfile: params.draftProfile,
|
|
draftCards: nextDraftCards,
|
|
}),
|
|
recommendedReplies: [],
|
|
};
|
|
}
|
|
|
|
buildFoundationDraftState(params: {
|
|
creatorIntent: Record<string, unknown> | null;
|
|
anchorPack: Record<string, unknown> | null;
|
|
draftProfile: Record<string, unknown>;
|
|
assetCoverage?: CustomWorldAssetCoverageSummary;
|
|
}): CustomWorldAgentDerivedStatePatch {
|
|
return {
|
|
...this.buildRefiningState({
|
|
previousStage: 'object_refining',
|
|
nextStage: 'object_refining',
|
|
draftProfile: params.draftProfile,
|
|
assetCoverage: params.assetCoverage,
|
|
}),
|
|
creatorIntent: params.creatorIntent,
|
|
anchorPack: params.anchorPack,
|
|
pendingClarifications: [],
|
|
};
|
|
}
|
|
|
|
buildMessageTurnState(params: {
|
|
latestSession: CustomWorldAgentSessionRecord;
|
|
nextAnchorContent: EightAnchorContent;
|
|
progressPercent: number;
|
|
replyText: string;
|
|
nextCreatorIntent: CustomWorldCreatorIntentRecord;
|
|
creatorIntentReadiness: CreatorIntentReadiness;
|
|
derivedDraftProfile: {
|
|
title: string;
|
|
summary: string;
|
|
};
|
|
derivedPendingClarifications: CustomWorldPendingClarification[];
|
|
derivedStage: CustomWorldAgentStage;
|
|
shouldStayInDraftStage: boolean;
|
|
}): CustomWorldAgentDerivedStatePatch {
|
|
const preservedStage =
|
|
params.latestSession.stage === 'visual_refining'
|
|
? ('visual_refining' as const)
|
|
: ('object_refining' as const);
|
|
const nextDraftProfile = params.shouldStayInDraftStage
|
|
? ((params.latestSession.draftProfile ?? {}) as Record<string, unknown>)
|
|
: params.progressPercent >= 100
|
|
? {
|
|
title: buildDraftTitleFromIntent(params.nextCreatorIntent),
|
|
summary: buildDraftSummaryFromIntent(params.nextCreatorIntent),
|
|
}
|
|
: params.derivedDraftProfile;
|
|
const nextStage = params.shouldStayInDraftStage
|
|
? preservedStage
|
|
: params.derivedStage;
|
|
const assetCoverage = params.shouldStayInDraftStage
|
|
? params.latestSession.assetCoverage
|
|
: rebuildRoleAssetCoverage(nextDraftProfile);
|
|
|
|
return {
|
|
currentTurn: params.latestSession.currentTurn + 1,
|
|
anchorContent: params.nextAnchorContent,
|
|
progressPercent: params.progressPercent,
|
|
lastAssistantReply: params.replyText,
|
|
stage: nextStage,
|
|
focusCardId: params.shouldStayInDraftStage
|
|
? params.latestSession.focusCardId
|
|
: null,
|
|
creatorIntent: params.nextCreatorIntent,
|
|
creatorIntentReadiness: params.creatorIntentReadiness,
|
|
anchorPack: buildAnchorPackFromEightAnchorContent(
|
|
params.nextAnchorContent,
|
|
params.progressPercent,
|
|
),
|
|
draftProfile: nextDraftProfile,
|
|
draftCards: params.shouldStayInDraftStage
|
|
? params.latestSession.draftCards
|
|
: [],
|
|
assetCoverage,
|
|
qualityFindings: this.qualityGateService.buildQualityFindings({
|
|
draftProfile: nextDraftProfile,
|
|
assetCoverage,
|
|
stage: nextStage,
|
|
}),
|
|
pendingClarifications:
|
|
params.progressPercent >= 100 ? [] : params.derivedPendingClarifications,
|
|
suggestedActions: params.shouldStayInDraftStage
|
|
? this.suggestedActionService.buildSuggestedActions({
|
|
stage: preservedStage,
|
|
isReady: true,
|
|
draftProfile: params.latestSession.draftProfile,
|
|
draftCards: params.latestSession.draftCards,
|
|
})
|
|
: params.progressPercent >= 100
|
|
? [
|
|
{
|
|
id: 'draft_foundation',
|
|
type: 'draft_foundation',
|
|
label: '生成游戏设定草稿',
|
|
},
|
|
]
|
|
: [],
|
|
recommendedReplies: [],
|
|
};
|
|
}
|
|
}
|