|
|
|
|
@@ -19,6 +19,14 @@ import type {
|
|
|
|
|
SubmitBigFishInputRequest,
|
|
|
|
|
} from '../../../packages/shared/src/contracts/bigFish';
|
|
|
|
|
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
|
|
|
|
|
import type {
|
|
|
|
|
CreateMatch3DSessionRequest,
|
|
|
|
|
ExecuteMatch3DActionRequest,
|
|
|
|
|
Match3DActionResponse,
|
|
|
|
|
Match3DAgentSessionSnapshot,
|
|
|
|
|
Match3DSessionResponse,
|
|
|
|
|
SendMatch3DMessageRequest,
|
|
|
|
|
} from '../../../packages/shared/src/contracts/match3dAgent';
|
|
|
|
|
import type {
|
|
|
|
|
PuzzleAgentActionRequest,
|
|
|
|
|
PuzzleAgentOperationRecord,
|
|
|
|
|
@@ -75,6 +83,7 @@ import {
|
|
|
|
|
readCustomWorldAgentUiState,
|
|
|
|
|
shouldRestoreCustomWorldAgentUiState,
|
|
|
|
|
} from '../../services/customWorldAgentUiState';
|
|
|
|
|
import { match3dCreationClient } from '../../services/match3d-creation';
|
|
|
|
|
import {
|
|
|
|
|
buildBigFishGenerationAnchorEntries,
|
|
|
|
|
buildMiniGameDraftGenerationProgress,
|
|
|
|
|
@@ -652,6 +661,20 @@ const BigFishRuntimeShell = lazy(async () => {
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const Match3DAgentWorkspace = lazy(async () => {
|
|
|
|
|
const module = await import('../match3d-creation/Match3DAgentWorkspace');
|
|
|
|
|
return {
|
|
|
|
|
default: module.Match3DAgentWorkspace,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const Match3DDraftReadyView = lazy(async () => {
|
|
|
|
|
const module = await import('../match3d-creation/Match3DDraftReadyView');
|
|
|
|
|
return {
|
|
|
|
|
default: module.Match3DDraftReadyView,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const CustomWorldCreationHub = lazy(async () => {
|
|
|
|
|
const module = await import('../custom-world-home/CustomWorldCreationHub');
|
|
|
|
|
return {
|
|
|
|
|
@@ -858,6 +881,11 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
resolveRpgCreationErrorMessage(error, fallback),
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const resolveMatch3DErrorMessage = useCallback(
|
|
|
|
|
(error: unknown, fallback: string) =>
|
|
|
|
|
resolveRpgCreationErrorMessage(error, fallback),
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const refreshBigFishShelf = useCallback(async () => {
|
|
|
|
|
setIsBigFishLoadingLibrary(true);
|
|
|
|
|
@@ -1237,6 +1265,44 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const match3dFlow = usePlatformCreationAgentFlowController<
|
|
|
|
|
Match3DAgentSessionSnapshot,
|
|
|
|
|
CreateMatch3DSessionRequest,
|
|
|
|
|
Match3DSessionResponse,
|
|
|
|
|
SendMatch3DMessageRequest,
|
|
|
|
|
ExecuteMatch3DActionRequest,
|
|
|
|
|
Match3DActionResponse
|
|
|
|
|
>({
|
|
|
|
|
client: {
|
|
|
|
|
createSession: match3dCreationClient.createSession,
|
|
|
|
|
getSession: match3dCreationClient.getSession,
|
|
|
|
|
streamMessage: match3dCreationClient.streamMessage,
|
|
|
|
|
executeAction: match3dCreationClient.executeAction,
|
|
|
|
|
selectSession: (response) => response.session,
|
|
|
|
|
},
|
|
|
|
|
createPayload: {},
|
|
|
|
|
workspaceStage: 'match3d-agent-workspace',
|
|
|
|
|
resultStage: 'match3d-result',
|
|
|
|
|
platformStage: 'platform',
|
|
|
|
|
isCompileAction: (payload) => payload.action === 'match3d_compile_draft',
|
|
|
|
|
resolveErrorMessage: resolveMatch3DErrorMessage,
|
|
|
|
|
errorMessages: {
|
|
|
|
|
open: '开启抓大鹅共创工作台失败。',
|
|
|
|
|
restoreMissingSession: '这份抓大鹅草稿缺少会话信息,请重新开始创作。',
|
|
|
|
|
restore: '读取抓大鹅创作草稿失败。',
|
|
|
|
|
submit: '发送抓大鹅共创消息失败。',
|
|
|
|
|
execute: '执行抓大鹅操作失败。',
|
|
|
|
|
},
|
|
|
|
|
enterCreateTab,
|
|
|
|
|
setSelectionStage,
|
|
|
|
|
onSessionOpened: () => {
|
|
|
|
|
setShowCreationTypeModal(false);
|
|
|
|
|
},
|
|
|
|
|
onActionComplete: ({ response, setSession }) => {
|
|
|
|
|
setSession(response.session);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const puzzleFlow = usePlatformCreationAgentFlowController<
|
|
|
|
|
PuzzleAgentSessionSnapshot,
|
|
|
|
|
CreatePuzzleAgentSessionRequest,
|
|
|
|
|
@@ -1356,6 +1422,16 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
const streamingBigFishReplyText = bigFishFlow.streamingReplyText;
|
|
|
|
|
const isStreamingBigFishReply = bigFishFlow.isStreamingReply;
|
|
|
|
|
|
|
|
|
|
const match3dSession = match3dFlow.session;
|
|
|
|
|
const match3dError = match3dFlow.error;
|
|
|
|
|
const setMatch3DSession = match3dFlow.setSession;
|
|
|
|
|
const setMatch3DError = match3dFlow.setError;
|
|
|
|
|
const isMatch3DBusy = match3dFlow.isBusy;
|
|
|
|
|
const streamingMatch3DReplyText = match3dFlow.streamingReplyText;
|
|
|
|
|
const setStreamingMatch3DReplyText = match3dFlow.setStreamingReplyText;
|
|
|
|
|
const isStreamingMatch3DReply = match3dFlow.isStreamingReply;
|
|
|
|
|
const setIsStreamingMatch3DReply = match3dFlow.setIsStreamingReply;
|
|
|
|
|
|
|
|
|
|
const puzzleSession = puzzleFlow.session;
|
|
|
|
|
const puzzleError = puzzleFlow.error;
|
|
|
|
|
const setPuzzleError = puzzleFlow.setError;
|
|
|
|
|
@@ -1379,6 +1455,20 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
await bigFishFlow.openWorkspace();
|
|
|
|
|
}, [bigFishFlow]);
|
|
|
|
|
|
|
|
|
|
const openMatch3DAgentWorkspace = useCallback(async () => {
|
|
|
|
|
setMatch3DSession(null);
|
|
|
|
|
setMatch3DError(null);
|
|
|
|
|
setStreamingMatch3DReplyText('');
|
|
|
|
|
setIsStreamingMatch3DReply(false);
|
|
|
|
|
await match3dFlow.openWorkspace();
|
|
|
|
|
}, [
|
|
|
|
|
match3dFlow,
|
|
|
|
|
setIsStreamingMatch3DReply,
|
|
|
|
|
setMatch3DError,
|
|
|
|
|
setMatch3DSession,
|
|
|
|
|
setStreamingMatch3DReplyText,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const openPuzzleAgentWorkspace = useCallback(async () => {
|
|
|
|
|
setPuzzleRun(null);
|
|
|
|
|
setPuzzleOperation(null);
|
|
|
|
|
@@ -1466,6 +1556,10 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
setBigFishRuntimeReturnStage('platform');
|
|
|
|
|
setBigFishGenerationState(null);
|
|
|
|
|
setBigFishError(null);
|
|
|
|
|
setMatch3DSession(null);
|
|
|
|
|
setMatch3DError(null);
|
|
|
|
|
setStreamingMatch3DReplyText('');
|
|
|
|
|
setIsStreamingMatch3DReply(false);
|
|
|
|
|
setPuzzleOperation(null);
|
|
|
|
|
setPuzzleWorks([]);
|
|
|
|
|
setSelectedPuzzleDetail(null);
|
|
|
|
|
@@ -1500,10 +1594,14 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
resetRpgSessionViewState,
|
|
|
|
|
selectionStage,
|
|
|
|
|
setBigFishError,
|
|
|
|
|
setIsStreamingMatch3DReply,
|
|
|
|
|
setMatch3DError,
|
|
|
|
|
setMatch3DSession,
|
|
|
|
|
setPuzzleError,
|
|
|
|
|
setRpgCustomWorldError,
|
|
|
|
|
setRpgGeneratedCustomWorldProfile,
|
|
|
|
|
setSelectionStage,
|
|
|
|
|
setStreamingMatch3DReplyText,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const handleCreationHubCreateType = useCallback(
|
|
|
|
|
@@ -1523,6 +1621,13 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type === 'match3d') {
|
|
|
|
|
runProtectedAction(() => {
|
|
|
|
|
void openMatch3DAgentWorkspace();
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type === 'puzzle') {
|
|
|
|
|
runProtectedAction(() => {
|
|
|
|
|
void openPuzzleAgentWorkspace();
|
|
|
|
|
@@ -1531,6 +1636,7 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
openBigFishAgentWorkspace,
|
|
|
|
|
openMatch3DAgentWorkspace,
|
|
|
|
|
openPuzzleAgentWorkspace,
|
|
|
|
|
prepareCreationLaunch,
|
|
|
|
|
runProtectedAction,
|
|
|
|
|
@@ -1546,6 +1652,10 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
bigFishFlow.leaveFlow();
|
|
|
|
|
}, [bigFishFlow]);
|
|
|
|
|
|
|
|
|
|
const leaveMatch3DFlow = useCallback(() => {
|
|
|
|
|
match3dFlow.leaveFlow();
|
|
|
|
|
}, [match3dFlow]);
|
|
|
|
|
|
|
|
|
|
const leavePuzzleFlow = useCallback(() => {
|
|
|
|
|
setPuzzleOperation(null);
|
|
|
|
|
setPuzzleRun(null);
|
|
|
|
|
@@ -1556,10 +1666,14 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
|
|
|
|
|
const submitBigFishMessage = bigFishFlow.submitMessage;
|
|
|
|
|
|
|
|
|
|
const submitMatch3DMessage = match3dFlow.submitMessage;
|
|
|
|
|
|
|
|
|
|
const submitPuzzleMessage = puzzleFlow.submitMessage;
|
|
|
|
|
|
|
|
|
|
const executeBigFishAction = bigFishFlow.executeAction;
|
|
|
|
|
|
|
|
|
|
const executeMatch3DAction = match3dFlow.executeAction;
|
|
|
|
|
|
|
|
|
|
const executePuzzleAction = puzzleFlow.executeAction;
|
|
|
|
|
|
|
|
|
|
const retryPuzzleDraftGeneration = useCallback(() => {
|
|
|
|
|
@@ -1602,6 +1716,14 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
}
|
|
|
|
|
}, [bigFishRun, bigFishSession, selectionStage, setSelectionStage]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (selectionStage === 'match3d-result' && !match3dSession?.draft) {
|
|
|
|
|
setSelectionStage(
|
|
|
|
|
match3dSession ? 'match3d-agent-workspace' : 'platform',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}, [match3dSession, selectionStage, setSelectionStage]);
|
|
|
|
|
|
|
|
|
|
const startBigFishRun = useCallback(() => {
|
|
|
|
|
if (!bigFishSession) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -3280,11 +3402,13 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
: (platformBootstrap.platformError ??
|
|
|
|
|
sessionController.agentWorkspaceRestoreError ??
|
|
|
|
|
bigFishError ??
|
|
|
|
|
match3dError ??
|
|
|
|
|
puzzleError)
|
|
|
|
|
}
|
|
|
|
|
onRetry={() => {
|
|
|
|
|
platformBootstrap.setPlatformError(null);
|
|
|
|
|
setBigFishError(null);
|
|
|
|
|
setMatch3DError(null);
|
|
|
|
|
setPuzzleError(null);
|
|
|
|
|
void platformBootstrap.refreshCustomWorldWorks().catch((error) => {
|
|
|
|
|
platformBootstrap.setPlatformError(
|
|
|
|
|
@@ -3297,11 +3421,15 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
void refreshPuzzleShelf();
|
|
|
|
|
}}
|
|
|
|
|
createError={
|
|
|
|
|
sessionController.creationTypeError ?? bigFishError ?? puzzleError
|
|
|
|
|
sessionController.creationTypeError ??
|
|
|
|
|
bigFishError ??
|
|
|
|
|
match3dError ??
|
|
|
|
|
puzzleError
|
|
|
|
|
}
|
|
|
|
|
createBusy={
|
|
|
|
|
sessionController.isCreatingAgentSession ||
|
|
|
|
|
isBigFishBusy ||
|
|
|
|
|
isMatch3DBusy ||
|
|
|
|
|
isPuzzleBusy
|
|
|
|
|
}
|
|
|
|
|
onCreateType={handleCreationHubCreateType}
|
|
|
|
|
@@ -3469,7 +3597,12 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
entry={selectedPublicWorkDetail}
|
|
|
|
|
authorAvatarUrl={selectedPublicWorkAuthor?.avatarUrl ?? null}
|
|
|
|
|
authorDisplayName={selectedPublicWorkAuthor?.displayName ?? null}
|
|
|
|
|
isBusy={isPublicWorkDetailBusy || isPuzzleBusy || isBigFishBusy}
|
|
|
|
|
isBusy={
|
|
|
|
|
isPublicWorkDetailBusy ||
|
|
|
|
|
isPuzzleBusy ||
|
|
|
|
|
isBigFishBusy ||
|
|
|
|
|
isMatch3DBusy
|
|
|
|
|
}
|
|
|
|
|
error={publicWorkDetailError}
|
|
|
|
|
onBack={() => {
|
|
|
|
|
setPublicWorkDetailError(null);
|
|
|
|
|
@@ -3767,6 +3900,58 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
</motion.div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{selectionStage === 'match3d-agent-workspace' && (
|
|
|
|
|
<motion.div
|
|
|
|
|
key="match3d-agent-workspace"
|
|
|
|
|
initial={{ opacity: 0, y: 12 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
|
|
|
|
exit={{ opacity: 0, y: -12 }}
|
|
|
|
|
className="flex h-full min-h-0 flex-col"
|
|
|
|
|
>
|
|
|
|
|
<Suspense
|
|
|
|
|
fallback={<LazyPanelFallback label="正在加载抓大鹅共创工作区..." />}
|
|
|
|
|
>
|
|
|
|
|
<Match3DAgentWorkspace
|
|
|
|
|
session={match3dSession}
|
|
|
|
|
streamingReplyText={streamingMatch3DReplyText}
|
|
|
|
|
isStreamingReply={isStreamingMatch3DReply}
|
|
|
|
|
isBusy={isMatch3DBusy || isStreamingMatch3DReply}
|
|
|
|
|
error={match3dError}
|
|
|
|
|
onBack={leaveMatch3DFlow}
|
|
|
|
|
onSubmitMessage={(payload) => {
|
|
|
|
|
void submitMatch3DMessage(payload);
|
|
|
|
|
}}
|
|
|
|
|
onExecuteAction={(payload) => {
|
|
|
|
|
void executeMatch3DAction(payload);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Suspense>
|
|
|
|
|
</motion.div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{selectionStage === 'match3d-result' && match3dSession?.draft && (
|
|
|
|
|
<motion.div
|
|
|
|
|
key="match3d-result"
|
|
|
|
|
initial={{ opacity: 0, y: 12 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
|
|
|
|
exit={{ opacity: 0, y: -12 }}
|
|
|
|
|
className="flex h-full min-h-0 flex-col"
|
|
|
|
|
>
|
|
|
|
|
<Suspense
|
|
|
|
|
fallback={<LazyPanelFallback label="正在加载抓大鹅结果..." />}
|
|
|
|
|
>
|
|
|
|
|
<Match3DDraftReadyView
|
|
|
|
|
session={match3dSession}
|
|
|
|
|
isBusy={isMatch3DBusy}
|
|
|
|
|
error={match3dError}
|
|
|
|
|
onBack={() => {
|
|
|
|
|
setSelectionStage('match3d-agent-workspace');
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Suspense>
|
|
|
|
|
</motion.div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{selectionStage === 'puzzle-agent-workspace' && (
|
|
|
|
|
<motion.div
|
|
|
|
|
key="puzzle-agent-workspace"
|
|
|
|
|
@@ -4207,15 +4392,20 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
isBusy={
|
|
|
|
|
sessionController.isCreatingAgentSession ||
|
|
|
|
|
isBigFishBusy ||
|
|
|
|
|
isMatch3DBusy ||
|
|
|
|
|
isPuzzleBusy
|
|
|
|
|
}
|
|
|
|
|
error={
|
|
|
|
|
bigFishError ?? puzzleError ?? sessionController.creationTypeError
|
|
|
|
|
bigFishError ??
|
|
|
|
|
match3dError ??
|
|
|
|
|
puzzleError ??
|
|
|
|
|
sessionController.creationTypeError
|
|
|
|
|
}
|
|
|
|
|
onClose={() => {
|
|
|
|
|
if (
|
|
|
|
|
sessionController.isCreatingAgentSession ||
|
|
|
|
|
isBigFishBusy ||
|
|
|
|
|
isMatch3DBusy ||
|
|
|
|
|
isPuzzleBusy
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -4230,6 +4420,11 @@ export function PlatformEntryFlowShellImpl({
|
|
|
|
|
void openBigFishAgentWorkspace();
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onSelectMatch3D={() => {
|
|
|
|
|
runProtectedAction(() => {
|
|
|
|
|
void openMatch3DAgentWorkspace();
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onSelectPuzzle={() => {
|
|
|
|
|
runProtectedAction(() => {
|
|
|
|
|
void openPuzzleAgentWorkspace();
|
|
|
|
|
|