fix: session history not loading + new session showing stale messages

Bug 1 - Session opens with empty messages:
- loadChatHistory effect was re-running on every currentSessionId change,
  racing with openSessionById and overwriting loaded messages
- Removed currentSessionId from effect dependencies (only runs on mount/postId)
- Added recovery: if session has 0 messages but has post_id, try fetching
  from the post-based conversation endpoint as fallback

Bug 2 - Start New Session shows old messages:
- startNewConversation now sets isHydratingSessionRef=true before changing
  session state, preventing the persistence effect from saving stale data
- Fully resets: messages, plan, agentMode, keyword suggestions, providerInfo
- loadPostSessions called AFTER state reset to avoid stale renders

Also fixed:
- Legacy fallback now only fires when no session was resolved at all
  (prevents loading old post_meta data over session data)
This commit is contained in:
Dwindi Ramadhana
2026-06-06 05:14:34 +07:00
parent b4ea9025b1
commit 23a34b3035

View File

@@ -1136,6 +1136,11 @@
React.useEffect(() => {
const loadChatHistory = async () => {
// Skip if we already have a session loaded (e.g., from openSessionById)
if (messages.length > 0 || isHydratingSessionRef.current) {
return;
}
try {
const headers = {
'X-WP-Nonce': wpAgenticWriter.nonce,
@@ -1148,7 +1153,7 @@
if (sessions.length > 0) {
if (sessions.length > 0) {
let selected = sessions[0];
const preferred = currentSessionId || (() => {
const preferred = (() => {
try {
return window.localStorage.getItem(`wpawSessionId_${postId}`) || '';
} catch (error) {
@@ -1185,8 +1190,8 @@
}
}
// Legacy endpoint fallback.
if (postId && historyMessages.length === 0) {
// Legacy endpoint fallback - only if no session found at all.
if (postId && historyMessages.length === 0 && !resolvedSessionId) {
const legacy = await fetch(`${wpAgenticWriter.apiUrl}/chat-history/${postId}`, {
method: 'GET',
headers,
@@ -1216,7 +1221,9 @@
}
};
loadChatHistory();
}, [postId, currentSessionId, sanitizeMessagesForStorage, hydrateSessionStateFromMessages]);
// Only run on mount / postId change — NOT on currentSessionId change
// Session switches are handled by openSessionById directly
}, [postId]);
const loadPostSessions = async () => {
const headers = {
@@ -1316,9 +1323,24 @@
setCurrentSessionId(sessionId);
const sessionMessages = Array.isArray(data?.messages) ? data.messages : [];
// If session has no messages but has a post_id, it may have been improperly persisted
if (sessionMessages.length === 0) {
wpawLog.warn('Session loaded with 0 messages:', sessionId);
// If session has no messages, try fetching from the conversations/post endpoint
// as a recovery mechanism (messages may be stored under post relationship)
if (sessionMessages.length === 0 && data?.post_id && Number(data.post_id) > 0) {
wpawLog.warn('Session has 0 messages, attempting post-based recovery:', sessionId);
try {
const postSessionRes = await fetch(`${wpAgenticWriter.apiUrl}/conversation/${data.post_id}`, {
method: 'GET',
headers,
});
if (postSessionRes.ok) {
const postSessionData = await postSessionRes.json();
if (Array.isArray(postSessionData?.messages) && postSessionData.messages.length > 0) {
sessionMessages.push(...postSessionData.messages);
}
}
} catch (e) {
// Non-fatal recovery attempt
}
}
lastPersistedMessagesRef.current = JSON.stringify(sanitizeMessagesForStorage(sessionMessages));
@@ -5627,13 +5649,27 @@
throw new Error('Failed to create a new conversation');
}
const data = await response.json();
// Fully reset state for clean slate
isHydratingSessionRef.current = true;
if (data?.session_id) {
setCurrentSessionId(data.session_id);
}
await loadPostSessions();
lastPersistedMessagesRef.current = JSON.stringify([]);
setMessages([]);
currentPlanRef.current = null;
setAgentMode('chat');
setShowWelcome(false);
setFocusKeywordSuggestions([]);
setSelectedFocusKeyword('');
setProviderInfo(null);
await loadPostSessions();
setTimeout(() => {
isHydratingSessionRef.current = false;
// Focus input
if (inputRef.current) {
inputRef.current.focus();
}
}, 50);
} catch (error) {
setMessages(prev => [...prev, {
role: 'system',