Files
Genarrative/server-node/src/services/customWorldAgentActionExecutors/updateDraftCardExecutor.ts
2026-04-21 18:27:46 +08:00

112 lines
3.9 KiB
TypeScript

import { updateDraftCardSections } from '../customWorldAgentDraftEditService.js';
import type { CustomWorldAgentActionExecutor } from './types.js';
import type { CustomWorldAgentChangeSummaryService } from '../customWorldAgentChangeSummaryService.js';
import type { CustomWorldAgentDraftCompiler } from '../customWorldAgentDraftCompiler.js';
import type { CustomWorldAgentSnapshotBuilder } from '../customWorldAgentSnapshotBuilder.js';
import type { CustomWorldAgentSessionStore } from '../customWorldAgentSessionStore.js';
import { buildActionResultMessage } from './helpers.js';
import {
buildCheckpointSnapshot,
createOperationUpdater,
getRequiredSession,
} from './executorShared.js';
export function createUpdateDraftCardExecutor(params: {
sessionStore: CustomWorldAgentSessionStore;
draftCompiler: CustomWorldAgentDraftCompiler;
changeSummaryService: CustomWorldAgentChangeSummaryService;
snapshotBuilder: CustomWorldAgentSnapshotBuilder;
}): CustomWorldAgentActionExecutor<'update_draft_card'> {
return async ({ userId, sessionId, operationId, payload }) => {
const updateOperation = createOperationUpdater({
sessionStore: params.sessionStore,
userId,
sessionId,
operationId,
});
try {
await updateOperation({
status: 'running',
phaseLabel: '写回草稿设定',
phaseDetail: '正在把这次编辑内容写回当前世界底稿。',
progress: 34,
});
const latestSession = await getRequiredSession({
sessionStore: params.sessionStore,
userId,
sessionId,
});
const nextDraftProfile = updateDraftCardSections({
draftProfile: (latestSession.draftProfile ?? {}) as Record<
string,
unknown
>,
cardId: payload.cardId,
sections: payload.sections,
});
await updateOperation({
phaseLabel: '重编译草稿卡',
phaseDetail: '正在同步更新草稿摘要和详情内容。',
progress: 72,
});
const nextState = params.snapshotBuilder.buildRefiningState({
previousStage: latestSession.stage,
draftProfile: nextDraftProfile,
focusCardId: payload.cardId,
});
const updatedDetail = params.draftCompiler.getDraftCardDetail(
nextDraftProfile,
payload.cardId,
);
const changedSectionIds = new Set(
payload.sections
.map((section) => section.sectionId.trim())
.filter(Boolean),
);
await params.sessionStore.replaceDerivedState(userId, sessionId, nextState);
await params.sessionStore.appendCheckpoint(userId, sessionId, {
label: `编辑 ${updatedDetail?.title || '草稿卡'}`,
snapshot: buildCheckpointSnapshot(latestSession, nextState),
});
await params.sessionStore.appendMessage(
userId,
sessionId,
buildActionResultMessage({
relatedOperationId: operationId,
text: params.changeSummaryService.buildSummary({
action: 'update_draft_card',
cardId: payload.cardId,
changedLabels:
updatedDetail?.sections
.filter((section) => changedSectionIds.has(section.id))
.map((section) => section.label) ?? [],
draftProfile: nextDraftProfile,
}),
}),
);
await updateOperation({
status: 'completed',
phaseLabel: '草稿设定已保存',
phaseDetail: `${updatedDetail?.title || '当前卡片'}」的设定已经同步更新。`,
progress: 100,
error: null,
});
} catch (error) {
await updateOperation({
status: 'failed',
phaseLabel: '保存失败',
phaseDetail: '这次草稿编辑没有成功写回到底稿。',
progress: 100,
error:
error instanceof Error ? error.message : 'update draft card failed',
});
}
};
}