init with react+axum+spacetimedb
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-26 18:06:23 +08:00
commit cbc27bad4a
20199 changed files with 883714 additions and 0 deletions

View File

@@ -0,0 +1,827 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type {
CustomWorldAgentActionRequest,
CustomWorldAgentOperationRecord,
CustomWorldAgentSessionSnapshot,
SendCustomWorldAgentMessageRequest,
} from '../../../packages/shared/src/contracts/customWorldAgent';
import {
buildAgentDraftFoundationAnchorEntries,
buildAgentDraftFoundationGenerationProgress,
buildAgentDraftFoundationSettingText,
isDraftFoundationOperation,
isDraftFoundationOperationRunning,
} from '../../services/customWorldAgentGenerationProgress';
import {
readCustomWorldAgentUiState,
writeCustomWorldAgentUiState,
} from '../../services/customWorldAgentUiState';
import {
createRpgCreationSession,
executeRpgCreationAction,
getRpgCreationSession,
streamRpgCreationMessage,
} from '../../services/rpg-creation';
import { rpgCreationPreviewAdapter } from '../../services/rpg-creation/rpgCreationPreviewAdapter';
import type { CustomWorldProfile } from '../../types';
import {
buildOptimisticAgentMessage,
createFailedAgentOperation,
normalizeAgentBackedProfile,
resolveRpgCreationErrorMessage,
} from './rpgEntryShared';
import type {
CustomWorldGenerationViewSource,
CustomWorldResultViewSource,
SelectionStage,
} from './rpgEntryTypes';
type UseRpgCreationSessionControllerParams = {
userId: string | null | undefined;
openLoginModal?: ((postLoginAction?: (() => void) | null) => void) | undefined;
selectionStage: SelectionStage;
setSelectionStage: (stage: SelectionStage) => void;
enterCreateTab?: (() => void) | undefined;
onSessionOpened?: (() => void) | undefined;
};
type PendingAgentUserMessage = {
sessionId: string;
message: CustomWorldAgentSessionSnapshot['messages'][number];
};
const AGENT_DRAFT_RESULT_AUTO_OPEN_MAX_ATTEMPTS = 12;
const AGENT_DRAFT_RESULT_AUTO_OPEN_RETRY_MS = 900;
export function useRpgCreationSessionController(
params: UseRpgCreationSessionControllerParams,
) {
const {
userId,
openLoginModal,
selectionStage,
setSelectionStage,
enterCreateTab,
onSessionOpened,
} = params;
const initialAgentUiStateRef = useRef(readCustomWorldAgentUiState());
const isInitialAgentUiStateOwnedByCurrentUser =
!initialAgentUiStateRef.current.ownerUserId ||
initialAgentUiStateRef.current.ownerUserId === userId;
const isHydratingInitialAgentWorkspaceRef = useRef(
Boolean(
initialAgentUiStateRef.current.activeSessionId &&
isInitialAgentUiStateOwnedByCurrentUser,
),
);
const hasAppliedInitialAgentWorkspaceRef = useRef(false);
const hasRequestedInitialAgentWorkspaceAuthRef = useRef(false);
const isAgentDraftResultAutoOpenSuppressedRef = useRef(false);
const currentAgentSessionIdRef = useRef<string | null>(null);
const activeAgentReplyAbortControllerRef = useRef<AbortController | null>(
null,
);
const latestAgentSessionSyncRequestIdRef = useRef(0);
const [isCreatingAgentSession, setIsCreatingAgentSession] = useState(false);
const [activeAgentSessionId, setActiveAgentSessionId] = useState<
string | null
>(() =>
isInitialAgentUiStateOwnedByCurrentUser
? (initialAgentUiStateRef.current.activeSessionId ?? null)
: null,
);
const [activeAgentOperationId, setActiveAgentOperationId] = useState<
string | null
>(() =>
isInitialAgentUiStateOwnedByCurrentUser
? (initialAgentUiStateRef.current.activeOperationId ?? null)
: null,
);
const [agentSession, setAgentSession] =
useState<CustomWorldAgentSessionSnapshot | null>(null);
const [agentOperation, setAgentOperation] =
useState<CustomWorldAgentOperationRecord | null>(null);
const [streamingAgentReplyText, setStreamingAgentReplyText] = useState('');
const [isStreamingAgentReply, setIsStreamingAgentReply] = useState(false);
const [pendingAgentUserMessage, setPendingAgentUserMessage] =
useState<PendingAgentUserMessage | null>(null);
const [isLoadingAgentSession, setIsLoadingAgentSession] = useState(false);
const [creationTypeError, setCreationTypeError] = useState<string | null>(null);
const [agentWorkspaceRestoreError, setAgentWorkspaceRestoreError] =
useState<string | null>(null);
const [generatedCustomWorldProfile, setGeneratedCustomWorldProfile] =
useState<CustomWorldProfile | null>(null);
const [customWorldError, setCustomWorldError] = useState<string | null>(null);
const [customWorldGenerationViewSource, setCustomWorldGenerationViewSource] =
useState<CustomWorldGenerationViewSource>(null);
const [customWorldResultViewSource, setCustomWorldResultViewSource] =
useState<CustomWorldResultViewSource>(null);
const [agentDraftGenerationStartedAt, setAgentDraftGenerationStartedAt] =
useState<number | null>(null);
const pendingAgentUserMessageRef = useRef<PendingAgentUserMessage | null>(null);
useEffect(() => {
currentAgentSessionIdRef.current = agentSession?.sessionId ?? null;
}, [agentSession]);
useEffect(() => {
pendingAgentUserMessageRef.current = pendingAgentUserMessage;
}, [pendingAgentUserMessage]);
const invalidateAgentSessionSyncRequests = useCallback(() => {
latestAgentSessionSyncRequestIdRef.current += 1;
}, []);
const abortActiveAgentReplyStream = useCallback(() => {
activeAgentReplyAbortControllerRef.current?.abort();
activeAgentReplyAbortControllerRef.current = null;
}, []);
const mergePendingAgentUserMessageIntoSession = useCallback(
(
session: CustomWorldAgentSessionSnapshot | null,
pending: PendingAgentUserMessage | null = pendingAgentUserMessageRef.current,
) => {
if (!session || !pending || pending.sessionId !== session.sessionId) {
return session;
}
const hasServerEchoedPendingMessage = session.messages.some(
(message) => message.id === pending.message.id,
);
if (hasServerEchoedPendingMessage) {
return session;
}
return {
...session,
messages: [...session.messages, pending.message],
updatedAt: pending.message.createdAt,
};
},
[],
);
const persistAgentUiState = useCallback(
(
nextSessionId: string | null,
nextOperationId: string | null,
nextGenerationSource: CustomWorldGenerationViewSource = null,
) => {
setActiveAgentSessionId(nextSessionId);
setActiveAgentOperationId(nextOperationId);
writeCustomWorldAgentUiState({
activeSessionId: nextSessionId,
activeOperationId: nextOperationId,
customWorldGenerationSource: nextGenerationSource,
// 工作区 session 是按 userId 持久化的,恢复指针必须绑定当前登录用户,
// 避免切换账号或复用旧 URL 时反复请求不属于当前用户的 session 产生 404。
ownerUserId: nextSessionId ? userId : null,
});
},
[userId],
);
const syncAgentSessionSnapshot = useCallback(async (sessionId: string) => {
const requestId = latestAgentSessionSyncRequestIdRef.current + 1;
latestAgentSessionSyncRequestIdRef.current = requestId;
const nextSession = await getRpgCreationSession(sessionId);
const mergedSession = mergePendingAgentUserMessageIntoSession(nextSession);
if (latestAgentSessionSyncRequestIdRef.current === requestId) {
setAgentSession(mergedSession);
const currentPendingAgentUserMessage = pendingAgentUserMessageRef.current;
const hasServerEchoedPendingMessage =
currentPendingAgentUserMessage?.sessionId === nextSession.sessionId &&
nextSession.messages.some(
(message) => message.id === currentPendingAgentUserMessage.message.id,
);
if (hasServerEchoedPendingMessage) {
setPendingAgentUserMessage(null);
}
}
return mergedSession;
}, [mergePendingAgentUserMessageIntoSession]);
useEffect(() => {
const initialAgentSessionId = initialAgentUiStateRef.current.activeSessionId;
if (!initialAgentSessionId || hasAppliedInitialAgentWorkspaceRef.current) {
return;
}
enterCreateTab?.();
if (!userId) {
if (!hasRequestedInitialAgentWorkspaceAuthRef.current) {
hasRequestedInitialAgentWorkspaceAuthRef.current = true;
openLoginModal?.(() => {
if (
initialAgentUiStateRef.current.activeOperationId &&
initialAgentUiStateRef.current.customWorldGenerationSource ===
'agent-draft-foundation'
) {
setCustomWorldGenerationViewSource('agent-draft-foundation');
setSelectionStage('custom-world-generating');
return;
}
setSelectionStage('agent-workspace');
});
}
return;
}
if (
initialAgentUiStateRef.current.ownerUserId &&
initialAgentUiStateRef.current.ownerUserId !== userId
) {
hasAppliedInitialAgentWorkspaceRef.current = true;
isHydratingInitialAgentWorkspaceRef.current = false;
persistAgentUiState(null, null);
return;
}
hasAppliedInitialAgentWorkspaceRef.current = true;
if (
initialAgentUiStateRef.current.activeOperationId &&
initialAgentUiStateRef.current.customWorldGenerationSource ===
'agent-draft-foundation'
) {
setCustomWorldGenerationViewSource('agent-draft-foundation');
setCustomWorldResultViewSource(null);
setSelectionStage('custom-world-generating');
return;
}
setSelectionStage('agent-workspace');
}, [enterCreateTab, openLoginModal, persistAgentUiState, setSelectionStage, userId]);
useEffect(() => {
if (
selectionStage !== 'agent-workspace' &&
selectionStage !== 'custom-world-generating'
) {
abortActiveAgentReplyStream();
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
}
}, [abortActiveAgentReplyStream, selectionStage]);
useEffect(() => {
return () => {
abortActiveAgentReplyStream();
};
}, [abortActiveAgentReplyStream]);
useEffect(() => {
if (!activeAgentSessionId) {
abortActiveAgentReplyStream();
invalidateAgentSessionSyncRequests();
setAgentSession(null);
setAgentOperation(null);
setIsLoadingAgentSession(false);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
setPendingAgentUserMessage(null);
setAgentWorkspaceRestoreError(null);
isHydratingInitialAgentWorkspaceRef.current = false;
return;
}
if (!userId) {
abortActiveAgentReplyStream();
invalidateAgentSessionSyncRequests();
setAgentSession(null);
setAgentOperation(null);
setIsLoadingAgentSession(false);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
setPendingAgentUserMessage(null);
setAgentWorkspaceRestoreError(null);
return;
}
let cancelled = false;
const isInitialWorkspaceRestore =
isHydratingInitialAgentWorkspaceRef.current &&
activeAgentSessionId === initialAgentUiStateRef.current.activeSessionId;
if (currentAgentSessionIdRef.current !== activeAgentSessionId) {
abortActiveAgentReplyStream();
setAgentSession(null);
setAgentOperation(null);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
setPendingAgentUserMessage(null);
}
setIsLoadingAgentSession(true);
void syncAgentSessionSnapshot(activeAgentSessionId)
.then(() => {
if (!cancelled) {
setCreationTypeError(null);
setAgentWorkspaceRestoreError(null);
isHydratingInitialAgentWorkspaceRef.current = false;
}
})
.catch((error) => {
if (cancelled) {
return;
}
// 登录后自动恢复的是“上一次残留的工作区指针”,
// 这里失败时应优先静默清理,避免把旧恢复错误冒充成当前登录已失效。
if (isInitialWorkspaceRestore) {
setAgentWorkspaceRestoreError(null);
} else {
setAgentWorkspaceRestoreError(
resolveRpgCreationErrorMessage(error, '读取 Agent 共创工作区失败。'),
);
}
setAgentSession(null);
setAgentOperation(null);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
isHydratingInitialAgentWorkspaceRef.current = false;
persistAgentUiState(null, null);
enterCreateTab?.();
setSelectionStage('platform');
})
.finally(() => {
if (!cancelled) {
setIsLoadingAgentSession(false);
}
});
return () => {
cancelled = true;
};
}, [
activeAgentSessionId,
abortActiveAgentReplyStream,
enterCreateTab,
invalidateAgentSessionSyncRequests,
persistAgentUiState,
setSelectionStage,
syncAgentSessionSnapshot,
userId,
]);
useEffect(() => {
if (
!isDraftFoundationOperationRunning(agentOperation) ||
agentDraftGenerationStartedAt
) {
return;
}
setAgentDraftGenerationStartedAt(Date.now());
}, [agentDraftGenerationStartedAt, agentOperation]);
useEffect(() => {
if (
selectionStage !== 'custom-world-generating' ||
customWorldGenerationViewSource !== 'agent-draft-foundation' ||
!isDraftFoundationOperation(agentOperation) ||
agentOperation.status !== 'completed'
) {
return;
}
let cancelled = false;
void (async () => {
for (
let attempt = 1;
attempt <= AGENT_DRAFT_RESULT_AUTO_OPEN_MAX_ATTEMPTS;
attempt += 1
) {
await new Promise((resolve) => {
window.setTimeout(
resolve,
AGENT_DRAFT_RESULT_AUTO_OPEN_RETRY_MS,
);
});
if (cancelled) {
return;
}
const latestSession = activeAgentSessionId
? await syncAgentSessionSnapshot(activeAgentSessionId).catch(
() => null,
)
: agentSession;
if (cancelled) {
return;
}
const draftResultProfile =
rpgCreationPreviewAdapter.buildPreviewFromSession(
latestSession ?? agentSession,
);
if (!draftResultProfile) {
continue;
}
setGeneratedCustomWorldProfile(
normalizeAgentBackedProfile(draftResultProfile),
);
setAgentDraftGenerationStartedAt(null);
setCustomWorldGenerationViewSource(null);
setCustomWorldResultViewSource('agent-draft');
setSelectionStage('custom-world-result');
return;
}
if (!cancelled) {
setAgentDraftGenerationStartedAt(null);
}
})();
return () => {
cancelled = true;
};
}, [
activeAgentSessionId,
agentOperation,
agentSession,
customWorldGenerationViewSource,
selectionStage,
setSelectionStage,
syncAgentSessionSnapshot,
]);
const agentDraftSettingPreview = useMemo(
() => buildAgentDraftFoundationSettingText(agentSession),
[agentSession],
);
const agentDraftAnchorPreviewEntries = useMemo(
() => buildAgentDraftFoundationAnchorEntries(agentSession),
[agentSession],
);
const agentDraftResultProfile = useMemo(
() => rpgCreationPreviewAdapter.buildPreviewFromSession(agentSession),
[agentSession],
);
const shouldAutoOpenAgentDraftResult = useMemo(
() =>
Boolean(
agentDraftResultProfile &&
agentSession &&
(agentSession.stage === 'object_refining' ||
agentSession.stage === 'visual_refining' ||
agentSession.stage === 'long_tail_review' ||
agentSession.stage === 'ready_to_publish' ||
agentSession.stage === 'published') &&
agentSession.draftCards.length > 0,
),
[agentDraftResultProfile, agentSession],
);
const agentDraftGenerationProgress = useMemo(
() =>
buildAgentDraftFoundationGenerationProgress(
agentOperation,
agentDraftGenerationStartedAt,
),
[agentDraftGenerationStartedAt, agentOperation],
);
const isAgentDraftGenerationView =
customWorldGenerationViewSource === 'agent-draft-foundation';
const isAgentDraftResultView = customWorldResultViewSource === 'agent-draft';
const isActiveGenerationRunning =
isDraftFoundationOperationRunning(agentOperation);
const activeGenerationError =
isDraftFoundationOperation(agentOperation) &&
agentOperation.status === 'failed'
? agentOperation.error || agentOperation.phaseDetail
: null;
useEffect(() => {
if (!shouldAutoOpenAgentDraftResult || !agentDraftResultProfile) {
return;
}
if (isAgentDraftResultAutoOpenSuppressedRef.current) {
return;
}
if (selectionStage === 'agent-workspace') {
setGeneratedCustomWorldProfile(agentDraftResultProfile);
setCustomWorldResultViewSource('agent-draft');
isAgentDraftResultAutoOpenSuppressedRef.current = false;
setSelectionStage('custom-world-result');
return;
}
if (
selectionStage === 'custom-world-result' &&
!generatedCustomWorldProfile
) {
setGeneratedCustomWorldProfile(agentDraftResultProfile);
setCustomWorldResultViewSource('agent-draft');
isAgentDraftResultAutoOpenSuppressedRef.current = false;
}
}, [
agentDraftResultProfile,
generatedCustomWorldProfile,
selectionStage,
setSelectionStage,
shouldAutoOpenAgentDraftResult,
]);
const openRpgAgentWorkspace = useCallback(
async (seedText = '') => {
if (isCreatingAgentSession) {
return;
}
setIsCreatingAgentSession(true);
setCreationTypeError(null);
isAgentDraftResultAutoOpenSuppressedRef.current = false;
invalidateAgentSessionSyncRequests();
setAgentSession(null);
setAgentOperation(null);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
setPendingAgentUserMessage(null);
setGeneratedCustomWorldProfile(null);
setCustomWorldError(null);
setAgentDraftGenerationStartedAt(null);
setCustomWorldGenerationViewSource(null);
setCustomWorldResultViewSource(null);
try {
const { session } = await createRpgCreationSession(
seedText ? { seedText } : {},
);
isHydratingInitialAgentWorkspaceRef.current = false;
setAgentSession(session);
setAgentOperation(null);
setGeneratedCustomWorldProfile(null);
setCustomWorldError(null);
setAgentDraftGenerationStartedAt(null);
setCustomWorldGenerationViewSource(null);
setCustomWorldResultViewSource(null);
enterCreateTab?.();
onSessionOpened?.();
persistAgentUiState(session.sessionId, null);
setSelectionStage('agent-workspace');
} catch (error) {
setCreationTypeError(
resolveRpgCreationErrorMessage(error, '开启共创工作台失败。'),
);
} finally {
setIsCreatingAgentSession(false);
}
},
[
enterCreateTab,
invalidateAgentSessionSyncRequests,
isCreatingAgentSession,
onSessionOpened,
persistAgentUiState,
setSelectionStage,
],
);
const submitAgentMessage = useCallback(
async (payload: SendCustomWorldAgentMessageRequest) => {
if (!activeAgentSessionId || isStreamingAgentReply) {
return;
}
const optimisticUserMessage = buildOptimisticAgentMessage({
id: payload.clientMessageId,
role: 'user',
kind: 'chat',
text: payload.text.trim(),
});
const pendingMessagePayload: PendingAgentUserMessage = {
sessionId: activeAgentSessionId,
message: optimisticUserMessage,
};
setAgentOperation(null);
persistAgentUiState(activeAgentSessionId, null);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(true);
setPendingAgentUserMessage(pendingMessagePayload);
const replyAbortController = new AbortController();
activeAgentReplyAbortControllerRef.current = replyAbortController;
setAgentSession((current) =>
mergePendingAgentUserMessageIntoSession(current, pendingMessagePayload),
);
try {
const nextSession = await streamRpgCreationMessage(
activeAgentSessionId,
payload,
{
onUpdate: (text) => {
if (replyAbortController.signal.aborted) {
return;
}
setStreamingAgentReplyText(text);
},
signal: replyAbortController.signal,
},
);
if (replyAbortController.signal.aborted) {
return;
}
const mergedNextSession = mergePendingAgentUserMessageIntoSession(
nextSession,
pendingMessagePayload,
);
setAgentSession(mergedNextSession);
setAgentOperation(null);
setStreamingAgentReplyText('');
const hasServerEchoedPendingMessage = nextSession.messages.some(
(message) => message.id === optimisticUserMessage.id,
);
setPendingAgentUserMessage(
hasServerEchoedPendingMessage ? null : pendingMessagePayload,
);
} catch (error) {
if (replyAbortController.signal.aborted) {
return;
}
const errorMessage = resolveRpgCreationErrorMessage(
error,
'发送共创消息失败。',
);
const warningMessage = buildOptimisticAgentMessage({
id: `message-error-${Date.now()}`,
role: 'assistant',
kind: 'warning',
text: errorMessage,
});
setAgentSession((current) =>
{
const mergedCurrentSession = mergePendingAgentUserMessageIntoSession(
current,
pendingMessagePayload,
);
return mergedCurrentSession
? {
...mergedCurrentSession,
messages: [...mergedCurrentSession.messages, warningMessage],
updatedAt: warningMessage.createdAt,
}
: current;
},
);
setPendingAgentUserMessage(null);
setStreamingAgentReplyText('');
persistAgentUiState(activeAgentSessionId, null);
} finally {
if (activeAgentReplyAbortControllerRef.current === replyAbortController) {
activeAgentReplyAbortControllerRef.current = null;
}
if (!replyAbortController.signal.aborted) {
setIsStreamingAgentReply(false);
}
}
},
[
activeAgentSessionId,
isStreamingAgentReply,
mergePendingAgentUserMessageIntoSession,
persistAgentUiState,
],
);
const executeAgentAction = useCallback(
async (payload: CustomWorldAgentActionRequest) => {
if (!activeAgentSessionId) {
return;
}
const isDraftFoundationAction = payload.action === 'draft_foundation';
if (isDraftFoundationAction) {
isAgentDraftResultAutoOpenSuppressedRef.current = false;
setGeneratedCustomWorldProfile(null);
setCustomWorldError(null);
setCustomWorldGenerationViewSource('agent-draft-foundation');
setCustomWorldResultViewSource(null);
setAgentDraftGenerationStartedAt(Date.now());
setSelectionStage('custom-world-generating');
}
try {
const { operation } = await executeRpgCreationAction(
activeAgentSessionId,
payload,
);
setAgentOperation(operation);
persistAgentUiState(
activeAgentSessionId,
operation.operationId,
isDraftFoundationAction ? 'agent-draft-foundation' : null,
);
} catch (error) {
const errorMessage = resolveRpgCreationErrorMessage(
error,
'执行共创操作失败。',
);
setAgentOperation(
createFailedAgentOperation({
type:
payload.action === 'draft_foundation'
? 'draft_foundation'
: payload.action,
phaseLabel: '执行操作失败',
error: errorMessage,
}),
);
persistAgentUiState(
activeAgentSessionId,
null,
isDraftFoundationAction ? 'agent-draft-foundation' : null,
);
}
},
[activeAgentSessionId, persistAgentUiState, setSelectionStage],
);
const setNormalizedGeneratedCustomWorldProfile = useCallback(
(profile: CustomWorldProfile | null) => {
setGeneratedCustomWorldProfile(
profile ? normalizeAgentBackedProfile(profile) : null,
);
},
[],
);
const resetSessionViewState = useCallback(() => {
setAgentOperation(null);
setStreamingAgentReplyText('');
setIsStreamingAgentReply(false);
setPendingAgentUserMessage(null);
setAgentDraftGenerationStartedAt(null);
setCustomWorldGenerationViewSource(null);
setCustomWorldResultViewSource(null);
}, []);
const suppressAgentDraftResultAutoOpen = useCallback(() => {
isAgentDraftResultAutoOpenSuppressedRef.current = true;
}, []);
const releaseAgentDraftResultAutoOpenSuppression = useCallback(() => {
isAgentDraftResultAutoOpenSuppressedRef.current = false;
}, []);
return {
initialAgentSessionId: initialAgentUiStateRef.current.activeSessionId ?? null,
isCreatingAgentSession,
activeAgentSessionId,
activeAgentOperationId,
agentSession,
setAgentSession,
agentOperation,
setAgentOperation,
resetSessionViewState,
streamingAgentReplyText,
isStreamingAgentReply,
isLoadingAgentSession,
creationTypeError,
setCreationTypeError,
agentWorkspaceRestoreError,
customWorldError,
setCustomWorldError,
generatedCustomWorldProfile,
setGeneratedCustomWorldProfile: setNormalizedGeneratedCustomWorldProfile,
rawSetGeneratedCustomWorldProfile: setGeneratedCustomWorldProfile,
customWorldGenerationViewSource,
setCustomWorldGenerationViewSource,
customWorldResultViewSource,
setCustomWorldResultViewSource,
agentDraftGenerationStartedAt,
setAgentDraftGenerationStartedAt,
agentDraftSettingPreview,
agentDraftAnchorPreviewEntries,
agentDraftResultProfile,
agentDraftGenerationProgress,
isAgentDraftGenerationView,
isAgentDraftResultView,
isActiveGenerationRunning,
activeGenerationError,
isAgentDraftResultAutoOpenSuppressedRef,
suppressAgentDraftResultAutoOpen,
releaseAgentDraftResultAutoOpenSuppression,
persistAgentUiState,
syncAgentSessionSnapshot,
openRpgAgentWorkspace,
submitAgentMessage,
executeAgentAction,
};
}