1
This commit is contained in:
199
server-node/src/services/customWorldAgentSnapshotBuilder.ts
Normal file
199
server-node/src/services/customWorldAgentSnapshotBuilder.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
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: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user