mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-29 14:02:19 +00:00
feat: replace optimistic message removal with error response handling
- Updated error handling in `threadSlice` to add agent responses instead of removing user messages. - Simplified Redux actions by consolidating error handling logic for failed message transmissions. - Ensured conversation flow consistency by providing fallback error messages to users.
This commit is contained in:
+17
-49
@@ -44,7 +44,6 @@ import {
|
||||
setLastViewed,
|
||||
setPanelWidth,
|
||||
setSelectedThread,
|
||||
updateMessagesForThread,
|
||||
} from '../store/threadSlice';
|
||||
import type { ThreadMessage } from '../types/thread';
|
||||
|
||||
@@ -344,31 +343,19 @@ const Conversations = () => {
|
||||
},
|
||||
onError: event => {
|
||||
if (event.thread_id !== selectedThreadIdRef.current) return;
|
||||
if (event.error_type !== 'cancelled') {
|
||||
setSendError(event.message);
|
||||
}
|
||||
setIsSending(false);
|
||||
setActiveToolCall(null);
|
||||
dispatch(setActiveThread(null));
|
||||
|
||||
// Remove the optimistic user message on error
|
||||
dispatch((innerDispatch, getState) => {
|
||||
const state = getState() as {
|
||||
thread: { messagesByThreadId: Record<string, ThreadMessage[]> };
|
||||
};
|
||||
const persistedMessages = state.thread.messagesByThreadId[event.thread_id] || [];
|
||||
const lastUserIdx = [...persistedMessages]
|
||||
.reverse()
|
||||
.findIndex(m => m.sender === 'user');
|
||||
if (lastUserIdx !== -1) {
|
||||
const actualIdx = persistedMessages.length - 1 - lastUserIdx;
|
||||
const updated = persistedMessages.filter((_, i) => i !== actualIdx);
|
||||
innerDispatch(updateMessagesForThread({ threadId: event.thread_id, messages: updated }));
|
||||
if (event.thread_id === selectedThreadIdRef.current) {
|
||||
innerDispatch(setSelectedThread(event.thread_id));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (event.error_type !== 'cancelled') {
|
||||
dispatch(
|
||||
addInferenceResponse({
|
||||
content: 'Something went wrong — please try again.',
|
||||
threadId: event.thread_id,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
dispatch(setActiveThread(null));
|
||||
}
|
||||
},
|
||||
}).then(fn => {
|
||||
if (mounted) cleanup = fn;
|
||||
@@ -633,32 +620,13 @@ const Conversations = () => {
|
||||
|
||||
// Pass the original sending thread ID to ensure response goes to correct thread
|
||||
dispatch(addInferenceResponse({ content: finalContent, threadId: sendingThreadId }));
|
||||
} catch (err) {
|
||||
// Remove the user message from persistent storage on error
|
||||
// We'll use a thunk-like approach to access current state
|
||||
dispatch((innerDispatch, getState) => {
|
||||
const state = getState() as {
|
||||
thread: { messagesByThreadId: Record<string, ThreadMessage[]> };
|
||||
};
|
||||
const persistedMessages = state.thread.messagesByThreadId[sendingThreadId] || [];
|
||||
const currentMessages = persistedMessages.filter(m => m.id !== userMessage.id);
|
||||
innerDispatch(
|
||||
updateMessagesForThread({ threadId: sendingThreadId, messages: currentMessages })
|
||||
);
|
||||
|
||||
// Also remove from current view if this is the selected thread
|
||||
if (sendingThreadId === selectedThreadId) {
|
||||
innerDispatch(setSelectedThread(sendingThreadId));
|
||||
}
|
||||
});
|
||||
|
||||
const msg =
|
||||
err && typeof err === 'object' && 'error' in err
|
||||
? String((err as { error: unknown }).error)
|
||||
: 'Failed to get response';
|
||||
setSendError(msg);
|
||||
// Clear active thread on error
|
||||
dispatch(setActiveThread(null));
|
||||
} catch {
|
||||
dispatch(
|
||||
addInferenceResponse({
|
||||
content: 'Something went wrong — please try again.',
|
||||
threadId: sendingThreadId,
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
clearTimeout(safetyTimeout);
|
||||
setIsSending(false);
|
||||
|
||||
@@ -114,11 +114,13 @@ export const sendMessage = createAsyncThunk(
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
// Remove optimistic user message on failure
|
||||
const state = (getState() as { thread: ThreadState }).thread;
|
||||
const messages = state.messagesByThreadId[threadId] || [];
|
||||
const filteredMessages = messages.filter(m => m.id !== userMessage.id);
|
||||
dispatch(updateMessagesForThread({ threadId, messages: filteredMessages }));
|
||||
// Add an error message as an agent response so the conversation flow continues
|
||||
dispatch(
|
||||
addInferenceResponse({
|
||||
content: 'Something went wrong — please try again.',
|
||||
threadId,
|
||||
})
|
||||
);
|
||||
|
||||
const msg =
|
||||
error && typeof error === 'object' && 'error' in error
|
||||
|
||||
Reference in New Issue
Block a user