fix: persist agent scene generation pending state
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-24 14:29:55 +08:00
parent ae93dfcfda
commit d73f6d6a29

View File

@ -527,9 +527,76 @@ function getReplacementCardStatusMeta(status: ReplacementCardStatus) {
}
interface LocalGenerationPendingState {
chatId: string;
modeType: AgentGenerationResultModeType;
expectedCount: number;
userTurnCountAtStart: number;
timestamp: number;
}
const AGENT_PENDING_GENERATION_STORAGE_KEY = "ai-chatbot-agent-pending-generations";
const AGENT_PENDING_GENERATION_EXPIRY_MS = 30 * 60 * 1000;
function getStoredAgentPendingGenerations(): LocalGenerationPendingState[] {
if (typeof window === "undefined") {
return [];
}
try {
const raw = window.localStorage.getItem(AGENT_PENDING_GENERATION_STORAGE_KEY);
if (!raw) {
return [];
}
const now = Date.now();
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) {
return [];
}
return parsed.filter((item) => {
if (!item || typeof item !== "object") {
return false;
}
const record = item as Record<string, unknown>;
const chatId = String(record.chatId || "").trim();
const modeType = String(record.modeType || "").trim();
const expectedCount = Number(record.expectedCount);
const userTurnCountAtStart = Number(record.userTurnCountAtStart);
const timestamp = Number(record.timestamp);
return (
Boolean(chatId) &&
(modeType === "scene_generation" ||
modeType === "detail_replacement" ||
modeType === "sku_replacement") &&
Number.isFinite(expectedCount) &&
expectedCount > 0 &&
Number.isFinite(userTurnCountAtStart) &&
Number.isFinite(timestamp) &&
now - timestamp < AGENT_PENDING_GENERATION_EXPIRY_MS
);
}) as LocalGenerationPendingState[];
} catch {
return [];
}
}
function saveStoredAgentPendingGenerations(items: LocalGenerationPendingState[]) {
if (typeof window === "undefined") {
return;
}
try {
window.localStorage.setItem(
AGENT_PENDING_GENERATION_STORAGE_KEY,
JSON.stringify(items)
);
} catch (error) {
console.warn(
"[AgentGenerationWorkspaceDarkV2] Failed to persist pending generation state:",
error
);
}
}
function AnimatedGenerationPlaceholderCard(params: {
@ -693,6 +760,27 @@ export function AgentGenerationWorkspaceDarkV2({
const [pendingGeneration, setPendingGeneration] =
useState<LocalGenerationPendingState | null>(null);
useEffect(() => {
const restored = getStoredAgentPendingGenerations().find(
(item) => item.chatId === chatId
);
if (!restored) {
return;
}
setPendingGeneration((current) => current || restored);
}, [chatId]);
useEffect(() => {
const allItems = getStoredAgentPendingGenerations().filter(
(item) => item.chatId !== chatId
);
if (pendingGeneration) {
allItems.push(pendingGeneration);
}
saveStoredAgentPendingGenerations(allItems);
}, [chatId, pendingGeneration]);
const { data: historyData } = useSWR<{ messages: ChatMessage[] }>(
rawChatId ? `/api/messages?chatId=${rawChatId}` : null,
fetcher,
@ -1613,6 +1701,10 @@ export function AgentGenerationWorkspaceDarkV2({
return;
}
if (pendingGeneration.modeType === "scene_generation") {
return;
}
if (!hasAssistantFailureAfterLastUser) {
return;
}
@ -1911,6 +2003,7 @@ export function AgentGenerationWorkspaceDarkV2({
setActiveResultModeType(currentResultModeType);
setSelectedResultUrl(null);
setPendingGeneration({
chatId,
modeType: currentResultModeType,
expectedCount:
currentResultModeType === "scene_generation"
@ -1919,6 +2012,7 @@ export function AgentGenerationWorkspaceDarkV2({
? detailReplacementReferenceCards.length
: skuReplacementReferenceCards.length,
userTurnCountAtStart: userMessageCount,
timestamp: Date.now(),
});
try {
sendMessage({ role: "user", parts });