diff --git a/apps/ai-game-creator-shell/src/App.tsx b/apps/ai-game-creator-shell/src/App.tsx index 5bf3330e9..9523363ac 100644 --- a/apps/ai-game-creator-shell/src/App.tsx +++ b/apps/ai-game-creator-shell/src/App.tsx @@ -605,16 +605,13 @@ function isPersistableDirectCodexConversationMessage(message: ChatMessage) { return /^[a-z0-9][a-z0-9-]{5,159}$/iu.test(turnId); } -function claimInitialSupervisorMessageForPage( - projectPath: string, - messageKey = '', -) { +function claimInitialSupervisorMessageForPage(projectPath: string, scope = '') { let claimedProjectPaths = initialSupervisorMessageClaimsByPage.get(window); if (!claimedProjectPaths) { claimedProjectPaths = new Set(); initialSupervisorMessageClaimsByPage.set(window, claimedProjectPaths); } - const claimKey = `${projectPath}\u0000${messageKey}`; + const claimKey = `${projectPath}\u0000${scope}`; if (claimedProjectPaths.has(claimKey)) { return false; } @@ -687,6 +684,7 @@ type AppProps = { activeVersionId?: ProjectSupervisorComponentProps['activeVersionId']; supervisorChatOnly?: boolean; initialSupervisorMessage?: string; + initialSupervisorMessageClaimScope?: string; initialCreationType?: HomeCreationType | null; initialAttachments?: LauncherImportedAttachment[]; playRequest?: ProjectSupervisorComponentProps['playRequest']; @@ -737,6 +735,7 @@ export function App({ activeVersionId = null, supervisorChatOnly = false, initialSupervisorMessage = '', + initialSupervisorMessageClaimScope = '', initialCreationType = null, initialAttachments = [], playRequest = null, @@ -874,6 +873,7 @@ export function App({ const initialSupervisorMessageLatchRef = useRef({ projectPath: initialProjectPath, prompt: initialSupervisorMessage.trim(), + claimScope: initialSupervisorMessageClaimScope, creationType: initialCreationType, attachments: toDirectCodexTurnAttachments(initialAttachments), }); @@ -7505,7 +7505,7 @@ export function App({ } if ( chatAgentBusy || - !claimInitialSupervisorMessageForPage(latch.projectPath, latch.prompt) + !claimInitialSupervisorMessageForPage(latch.projectPath, latch.claimScope) ) { return; } diff --git a/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx b/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx index 8b64a4505..c40dca2e4 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx +++ b/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx @@ -36,7 +36,10 @@ import type { WorkspaceLauncherShellProps } from './model'; import { NonEmptyProjectDialog, ProjectsPage } from './ProjectCreation'; import { useAccountWallet } from './useAccountWallet'; import { useDeveloperAgentPanel } from './useDeveloperAgentPanel'; -import { useHomeProjectCreation } from './useHomeProjectCreation'; +import { + DESIGN_ARTIFACTS_BUILD_PROMPT, + useHomeProjectCreation, +} from './useHomeProjectCreation'; import { useRecentProjects } from './useRecentProjects'; export function WorkspaceLauncherShell({ @@ -113,7 +116,7 @@ export function WorkspaceLauncherShell({ const agentRuntimeMode: 'design' | 'game' = planningStartMode ? 'design' : 'game'; - const suppressInitialGameTurn = switchedToGameRuntime; + const omitOriginalPlanningTurnInputs = switchedToGameRuntime; const activeProjectContextRef = useRef(currentProjectContext); const manifestMergeRef = useRef(null); activeProjectContextRef.current = currentProjectContext; @@ -495,9 +498,6 @@ export function WorkspaceLauncherShell({ }); } - const approvedDesignBuildPrompt = - '查看当前项目 design_artifacts/ 目录及其子目录下的文档,理解其游戏设计,并按照这些文档将游戏实现出来。'; - const currentHelpTitle = launcherView === 'guide' ? '使用指南' @@ -665,23 +665,26 @@ export function WorkspaceLauncherShell({ initialProjectKind={currentProjectContext.projectKind} initialSupervisorMessage={ switchedToGameRuntime - ? approvedDesignBuildPrompt - : !suppressInitialGameTurn + ? DESIGN_ARTIFACTS_BUILD_PROMPT + : !omitOriginalPlanningTurnInputs ? currentProjectContext.initialPrompt : '' } initialCreationType={ switchedToGameRuntime ? 'game' - : !suppressInitialGameTurn + : !omitOriginalPlanningTurnInputs ? currentProjectContext.creationType : null } initialAttachments={ - !suppressInitialGameTurn + !omitOriginalPlanningTurnInputs ? currentProjectContext.attachments : [] } + initialSupervisorMessageClaimScope={ + switchedToGameRuntime ? 'approved-design-build' : '' + } activeVersionId={activeVersionId} orchestrationMode="single-supervisor" projectSupervisorOnly diff --git a/apps/ai-game-creator-shell/src/features/app-shell/model.ts b/apps/ai-game-creator-shell/src/features/app-shell/model.ts index 5c54a5055..90ace801c 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/model.ts +++ b/apps/ai-game-creator-shell/src/features/app-shell/model.ts @@ -35,6 +35,7 @@ export type ProjectSupervisorComponentProps = { initialProjectManifest?: GameCreationAppManifest; initialProjectKind?: 'web' | 'godot' | 'cocos'; initialSupervisorMessage?: string; + initialSupervisorMessageClaimScope?: string; initialCreationType?: HomeCreationType | null; initialAttachments?: LauncherImportedAttachment[]; orchestrationMode?: 'single-supervisor' | 'professional-dag'; diff --git a/apps/ai-game-creator-shell/src/features/app-shell/useHomeProjectCreation.ts b/apps/ai-game-creator-shell/src/features/app-shell/useHomeProjectCreation.ts index 56201d7d3..27059edca 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/useHomeProjectCreation.ts +++ b/apps/ai-game-creator-shell/src/features/app-shell/useHomeProjectCreation.ts @@ -66,7 +66,7 @@ type UseHomeProjectCreationOptions = { rememberRecentWorkspace: (projectPath: string) => void; }; -const APPROVED_GDD_BUILD_PROMPT = [ +export const APPROVED_GDD_BUILD_PROMPT = [ '请按照附件中的已批准 GDD 开始建造这款游戏。', '', '这份 GDD 已覆盖游戏定位与一句话概念、类型与美术方向、游戏支柱、核心循环、目标用户、平台与输入事实、MVP 系统、暂不纳入范围、创作者提示和原型验证项。', @@ -74,6 +74,9 @@ const APPROVED_GDD_BUILD_PROMPT = [ '请先阅读并理解附件中的 fast_gdd.md,以它作为本次建造的主要依据,优先实现其中 MVP 范围内的可运行游戏原型。', ].join('\n'); +export const DESIGN_ARTIFACTS_BUILD_PROMPT = + '查看当前项目 design_artifacts/ 目录及其子目录下的文档,理解其游戏设计,并按照这些文档将游戏实现出来。'; + function createTextAttachmentFile(content: string) { const file = new File([content], 'fast_gdd.md', { type: 'text/markdown',