1
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-20 21:06:48 +08:00
parent 1c72066bab
commit 75944b1f1f
102 changed files with 9648 additions and 1540 deletions

View File

@@ -17,6 +17,7 @@ import type {
import { badRequest, notFound } from '../errors.js';
import { prepareEventStreamResponse } from '../http.js';
import { CustomWorldAgentAssetBridgeService } from './customWorldAgentAssetBridgeService.js';
import { CustomWorldAgentAutoAssetService } from './customWorldAgentAutoAssetService.js';
import { CustomWorldAgentChangeSummaryService } from './customWorldAgentChangeSummaryService.js';
import {
buildPendingClarifications,
@@ -274,10 +275,12 @@ function buildWelcomeMessage(params: {
function buildFoundationDraftAssistantMessage(params: {
relatedOperationId: string;
draftProfile: unknown;
warnings?: string[];
}) {
const profile = normalizeFoundationDraftProfile(params.draftProfile);
const leadCharacter = profile?.playableNpcs[0];
const leadLandmark = profile?.landmarks[0];
const warnings = (params.warnings ?? []).filter(Boolean);
return {
id: `message-${crypto.randomBytes(8).toString('hex')}`,
@@ -288,6 +291,12 @@ function buildFoundationDraftAssistantMessage(params: {
'',
`当前已经落下来的第一批对象数量是:关键角色 ${profile?.playableNpcs.length ?? 0} 个,关键地点 ${profile?.landmarks.length ?? 0} 个,势力 ${profile?.factions.length ?? 0} 个。`,
`建议你先从“${profile?.name || '世界总卡'}”这张世界总卡看起${leadCharacter ? `,再顺着角色「${leadCharacter.name}」往下细修` : ''}${leadLandmark ? `,地点可以先看「${leadLandmark.name}` : ''}`,
...(warnings.length > 0
? [
'',
`这一轮有 ${warnings.length} 项资产补齐未完成,但不影响世界底稿继续精修。`,
]
: []),
].join('\n'),
createdAt: new Date().toISOString(),
relatedOperationId: params.relatedOperationId,
@@ -332,6 +341,8 @@ export class CustomWorldAgentOrchestrator {
private readonly assetBridgeService: CustomWorldAgentAssetBridgeService;
private readonly autoAssetService: CustomWorldAgentAutoAssetService | null;
private readonly eightAnchorSingleTurnService: EightAnchorSingleTurnService;
constructor(
@@ -339,6 +350,7 @@ export class CustomWorldAgentOrchestrator {
llmClient: UpstreamLlmClient | null = null,
options: {
singleTurnLlmClient?: UpstreamLlmClient | null;
autoAssetService?: CustomWorldAgentAutoAssetService | null;
} = {},
) {
this.foundationDraftService = new CustomWorldAgentFoundationDraftService(
@@ -350,6 +362,8 @@ export class CustomWorldAgentOrchestrator {
);
this.changeSummaryService = new CustomWorldAgentChangeSummaryService();
this.assetBridgeService = new CustomWorldAgentAssetBridgeService();
this.autoAssetService =
options.autoAssetService ?? null;
this.eightAnchorSingleTurnService = new EightAnchorSingleTurnService(
(options.singleTurnLlmClient ?? llmClient) ?? undefined,
);
@@ -844,9 +858,9 @@ export class CustomWorldAgentOrchestrator {
try {
await this.sessionStore.updateOperation(userId, sessionId, operationId, {
status: 'running',
phaseLabel: '生成世界底稿',
phaseDetail: '正在根据已确认设定编译第一版世界结构。',
progress: 38,
phaseLabel: '整理世界骨架',
phaseDetail: '正在校验已确认锚点,并准备第一版世界框架生成链路。',
progress: 12,
});
await sleep(30);
@@ -890,19 +904,44 @@ export class CustomWorldAgentOrchestrator {
},
});
const draftWithAssets = this.autoAssetService
? await this.autoAssetService.populateDraftAssets({
draftProfile,
onProgress: async (progress) => {
await this.sessionStore.updateOperation(
userId,
sessionId,
operationId,
{
status: 'running',
phaseLabel: progress.phaseLabel,
phaseDetail: progress.phaseDetail,
progress: progress.progress,
},
);
},
})
: {
draftProfile,
assetCoverage: rebuildRoleAssetCoverage(draftProfile),
warnings: [],
};
await this.sessionStore.updateOperation(userId, sessionId, operationId, {
phaseLabel: '编译草稿卡',
phaseDetail: '正在把世界底稿整理成可浏览的卡片摘要和详情结构。',
progress: 98,
});
const draftCards = this.draftCompiler.compileDraftCards(draftProfile);
const assetCoverage = rebuildRoleAssetCoverage(draftProfile);
const draftCards = this.draftCompiler.compileDraftCards(
draftWithAssets.draftProfile,
);
const assetCoverage = draftWithAssets.assetCoverage;
const nextStage = 'object_refining' as const;
const nextSuggestedActions = buildSuggestedActions({
stage: nextStage,
isReady: true,
draftProfile,
draftProfile: draftWithAssets.draftProfile,
draftCards,
});
@@ -910,7 +949,8 @@ export class CustomWorldAgentOrchestrator {
stage: nextStage,
creatorIntent,
anchorPack,
draftProfile: draftProfile as unknown as Record<string, unknown>,
draftProfile:
draftWithAssets.draftProfile as unknown as Record<string, unknown>,
draftCards,
assetCoverage,
pendingClarifications: [],
@@ -925,22 +965,34 @@ export class CustomWorldAgentOrchestrator {
sessionId,
buildFoundationDraftAssistantMessage({
relatedOperationId: operationId,
draftProfile,
draftProfile: draftWithAssets.draftProfile,
warnings: draftWithAssets.warnings,
}),
);
await this.sessionStore.updateOperation(userId, sessionId, operationId, {
status: 'completed',
phaseLabel: '世界底稿已生成',
phaseDetail: `第一版世界底稿和 ${draftCards.length} 张草稿卡已经整理完成。`,
phaseDetail:
draftWithAssets.warnings.length > 0
? `第一版世界底稿和 ${draftCards.length} 张草稿卡已经整理完成,另有 ${draftWithAssets.warnings.length} 项资产补齐待后续处理。`
: `第一版世界底稿和 ${draftCards.length} 张草稿卡已经整理完成。`,
progress: 100,
error: null,
});
} catch (error) {
const currentOperation = await this.sessionStore.getOperation(
userId,
sessionId,
operationId,
);
await this.sessionStore.updateOperation(userId, sessionId, operationId, {
status: 'failed',
phaseLabel: '底稿生成失败',
phaseDetail: '这一轮没有成功把设定编成世界底稿。',
phaseLabel:
currentOperation?.phaseLabel?.trim() || '底稿生成失败',
phaseDetail:
currentOperation?.phaseDetail?.trim() ||
'这一轮没有成功把设定编成世界底稿。',
progress: 100,
error:
error instanceof Error ? error.message : 'draft foundation failed',