Skip to content

Commit 18e78d8

Browse files
authored
Merge pull request #8 from RonasIT/PRD-2007-edit-ai-message-logic
PRD-2007: Edit AI message logic
2 parents 13cdec9 + 786963e commit 18e78d8

4 files changed

Lines changed: 118 additions & 3 deletions

File tree

libs/mobile/chat/features/use-edit-message/src/use-edit-message.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import { FormValues } from '@open-webui-react-native/mobile/shared/utils/form';
44
import {
55
chatApi,
66
ChatResponse,
7-
prepareUpdateMessageInChatPayload,
87
prepareCompleteChatPayload,
98
prepareUpdateMessageToSendPayload,
9+
prepareEditAssistantMessagePayload,
10+
prepareCopyEditedMessagePayload,
11+
prepareUpdateMessageInChatPayload,
12+
History,
1013
} from '@open-webui-react-native/shared/data-access/api';
14+
import { Role } from '@open-webui-react-native/shared/data-access/common';
1115
import { socketService } from '@open-webui-react-native/shared/data-access/websocket';
1216

1317
interface UseEditMessageProps {
@@ -32,6 +36,12 @@ export const useEditMessage = ({ chat, modelId }: UseEditMessageProps): typeof r
3236
const { mutateAsync: updateChat, isPending: isChatUpdating } = chatApi.useUpdate();
3337
const { mutate: completeChat } = chatApi.useCompleteChat();
3438

39+
const isAssistantMessage = (chatHistory: History, messageId: string): boolean => {
40+
const editedMessage = chatHistory.messages[messageId];
41+
42+
return editedMessage.role === Role.ASSISTANT;
43+
};
44+
3545
const startEditing = (messageId: string, content: string): void => {
3646
setEditingMessageId(messageId);
3747
reset({ editMessageInputValue: content });
@@ -47,7 +57,11 @@ export const useEditMessage = ({ chat, modelId }: UseEditMessageProps): typeof r
4757
return;
4858
}
4959

50-
const preparedChat = prepareUpdateMessageInChatPayload(chat, editingMessageId, message);
60+
const chatHistory = chat.chat.history;
61+
62+
const preparedChat: ChatResponse = isAssistantMessage(chatHistory, editingMessageId)
63+
? prepareCopyEditedMessagePayload(chat, editingMessageId, message)
64+
: prepareUpdateMessageInChatPayload(chat, editingMessageId, message);
5165

5266
await updateChat(preparedChat);
5367
cancelEditing();
@@ -60,10 +74,14 @@ export const useEditMessage = ({ chat, modelId }: UseEditMessageProps): typeof r
6074
const chatHistory = chat.chat.history;
6175
const editedMessage = chatHistory.messages[editingMessageId];
6276

63-
const preparedChat = prepareUpdateMessageToSendPayload(chat, message, modelId, editedMessage.parentId);
77+
const preparedChat: ChatResponse = isAssistantMessage(chatHistory, editingMessageId)
78+
? prepareEditAssistantMessagePayload(chat, editingMessageId, message)
79+
: prepareUpdateMessageToSendPayload(chat, message, modelId, editedMessage.parentId);
6480

6581
await updateChat(preparedChat, {
6682
onSuccess: (data) => {
83+
if (editedMessage.role === Role.ASSISTANT) return;
84+
6785
const completePayload = prepareCompleteChatPayload({
6886
chatId: data.id,
6987
messageId: data.chat!.history.currentId,

libs/shared/data-access/api/src/lib/chats/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ export * from './create-messages-list';
1616
export * from './patch-chat-with-selected-messages';
1717
export * from './prepare-update-message-in-chat-payload';
1818
export * from './prepare-update-message-to-send-payload';
19+
export * from './prepare-edit-assistant-message-payload';
20+
export * from './prepare-copy-edited-message-payload';
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import uuid from 'react-native-uuid';
2+
import { Role } from '@open-webui-react-native/shared/data-access/common';
3+
import { ChatResponse, History, Message } from '../models';
4+
import { createMessagesList } from './create-messages-list';
5+
6+
export function prepareCopyEditedMessagePayload(
7+
oldData: ChatResponse,
8+
messageId: string,
9+
newContent: string,
10+
): ChatResponse {
11+
const history = oldData.chat.history;
12+
const messagesMap = { ...history.messages };
13+
14+
const original = messagesMap[messageId];
15+
if (!original || original.role !== Role.ASSISTANT) return oldData;
16+
17+
const newAssistantMessageId = uuid.v4();
18+
19+
const parentId = original.parentId ?? original.id;
20+
21+
const newAssistantMessage: Message = {
22+
...original,
23+
id: newAssistantMessageId,
24+
parentId,
25+
childrenIds: [],
26+
content: newContent,
27+
done: true,
28+
};
29+
30+
if (parentId && messagesMap[parentId]) {
31+
const parent = messagesMap[parentId];
32+
messagesMap[parentId] = {
33+
...parent,
34+
childrenIds: [...(parent.childrenIds ?? []), newAssistantMessageId],
35+
};
36+
}
37+
38+
messagesMap[newAssistantMessageId] = newAssistantMessage;
39+
40+
const updatedHistory: History = {
41+
...history,
42+
currentId: newAssistantMessageId,
43+
messages: messagesMap,
44+
lastAssistantMessage: newAssistantMessage,
45+
};
46+
47+
return {
48+
...oldData,
49+
chat: {
50+
...oldData.chat,
51+
history: updatedHistory,
52+
messages: createMessagesList(updatedHistory, newAssistantMessageId),
53+
},
54+
};
55+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Role } from '@open-webui-react-native/shared/data-access/common';
2+
import { ChatResponse } from '../models';
3+
4+
export function prepareEditAssistantMessagePayload(
5+
oldData: ChatResponse,
6+
messageId: string,
7+
newContent: string,
8+
): ChatResponse {
9+
const history = oldData.chat.history;
10+
const messagesMap = { ...history.messages };
11+
12+
const target = messagesMap[messageId];
13+
if (!target || target.role !== Role.ASSISTANT) return oldData;
14+
15+
const updatedMessage = {
16+
...target,
17+
content: newContent,
18+
done: true,
19+
};
20+
21+
messagesMap[messageId] = updatedMessage;
22+
23+
const updatedMessagesList = oldData.chat.messages.map((m) => (m.id === messageId ? updatedMessage : m));
24+
25+
const lastAssistantMessage =
26+
history.lastAssistantMessage?.id === messageId ? updatedMessage : history.lastAssistantMessage;
27+
28+
return {
29+
...oldData,
30+
chat: {
31+
...oldData.chat,
32+
history: {
33+
...history,
34+
messages: messagesMap,
35+
lastAssistantMessage,
36+
},
37+
messages: updatedMessagesList,
38+
},
39+
};
40+
}

0 commit comments

Comments
 (0)