mirror of https://github.com/buster-so/buster.git
Merge pull request #562 from buster-so/devin/BUS-1447-1752896644
feat(BUS-1447): Add hook to track new message insertions from external sources
This commit is contained in:
commit
d141cc5987
|
@ -4,7 +4,7 @@ import { useShape, useShapeStream } from '../instances';
|
||||||
import { useChatUpdate } from '@/context/Chats/useChatUpdate';
|
import { useChatUpdate } from '@/context/Chats/useChatUpdate';
|
||||||
import { updateMessageShapeToIChatMessage } from './helpers';
|
import { updateMessageShapeToIChatMessage } from './helpers';
|
||||||
import { useMemoizedFn } from '@/hooks';
|
import { useMemoizedFn } from '@/hooks';
|
||||||
import { prefetchGetChatsList, useGetChatMemoized } from '@/api/buster_rest/chats';
|
import { useGetChatMemoized, useGetChatMessageMemoized } from '@/api/buster_rest/chats';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
import type { ChatMessageResponseMessage_File } from '@buster/server-shared/chats';
|
import type { ChatMessageResponseMessage_File } from '@buster/server-shared/chats';
|
||||||
import type { BusterChatMessage } from '../../asset_interfaces/chat';
|
import type { BusterChatMessage } from '../../asset_interfaces/chat';
|
||||||
|
@ -12,6 +12,7 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { dashboardQueryKeys } from '../../query_keys/dashboard';
|
import { dashboardQueryKeys } from '../../query_keys/dashboard';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
import { metricsQueryKeys } from '../../query_keys/metric';
|
import { metricsQueryKeys } from '../../query_keys/metric';
|
||||||
|
import { chatQueryKeys } from '../../query_keys/chat';
|
||||||
|
|
||||||
export const useGetMessage = ({ chatId, messageId }: { chatId: string; messageId: string }) => {
|
export const useGetMessage = ({ chatId, messageId }: { chatId: string; messageId: string }) => {
|
||||||
const shape = useMemo(() => messageShape({ chatId, messageId }), [chatId, messageId]);
|
const shape = useMemo(() => messageShape({ chatId, messageId }), [chatId, messageId]);
|
||||||
|
@ -24,6 +25,7 @@ export const useGetMessages = ({ chatId }: { chatId: string }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateOperations: Array<'insert' | 'update' | 'delete'> = ['update'];
|
const updateOperations: Array<'insert' | 'update' | 'delete'> = ['update'];
|
||||||
|
const insertOperations: Array<'insert' | 'update' | 'delete'> = ['insert'];
|
||||||
|
|
||||||
export const useTrackAndUpdateMessageChanges = (
|
export const useTrackAndUpdateMessageChanges = (
|
||||||
{
|
{
|
||||||
|
@ -40,6 +42,7 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
const { onUpdateChatMessage, onUpdateChat } = useChatUpdate();
|
const { onUpdateChatMessage, onUpdateChat } = useChatUpdate();
|
||||||
const checkIfWeHaveAFollowupDashboard = useCheckIfWeHaveAFollowupDashboard(messageId);
|
const checkIfWeHaveAFollowupDashboard = useCheckIfWeHaveAFollowupDashboard(messageId);
|
||||||
const getChatMemoized = useGetChatMemoized();
|
const getChatMemoized = useGetChatMemoized();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const subscribe = !!chatId && !!messageId && messageId !== 'undefined';
|
const subscribe = !!chatId && !!messageId && messageId !== 'undefined';
|
||||||
|
|
||||||
|
@ -63,6 +66,7 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
if (currentMessageIds.length !== allMessageIds.length) {
|
if (currentMessageIds.length !== allMessageIds.length) {
|
||||||
onUpdateChat({
|
onUpdateChat({
|
||||||
...chat,
|
...chat,
|
||||||
|
id: chatId,
|
||||||
message_ids: allMessageIds
|
message_ids: allMessageIds
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -75,16 +79,20 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
(reasoningMessage as ChatMessageResponseMessage_File)?.file_type === 'dashboard'
|
(reasoningMessage as ChatMessageResponseMessage_File)?.file_type === 'dashboard'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (hasFiles) {
|
|
||||||
prefetchGetChatsList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isEmpty(iChatMessage.response_message_ids)) {
|
if (!isEmpty(iChatMessage.response_message_ids)) {
|
||||||
checkIfWeHaveAFollowupDashboard(iChatMessage);
|
checkIfWeHaveAFollowupDashboard(iChatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iChatMessage.is_completed) {
|
if (iChatMessage.is_completed) {
|
||||||
prefetchGetChatsList();
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: chatQueryKeys.chatsGetList().queryKey
|
||||||
|
});
|
||||||
|
if (hasFiles) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: metricsQueryKeys.metricsGetList().queryKey
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback?.(iChatMessage);
|
callback?.(iChatMessage);
|
||||||
|
@ -128,3 +136,46 @@ const useCheckIfWeHaveAFollowupDashboard = (messageId: string) => {
|
||||||
|
|
||||||
return useMemoizedFn(method);
|
return useMemoizedFn(method);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useTrackAndUpdateNewMessages = ({ chatId }: { chatId: string | undefined }) => {
|
||||||
|
const { onUpdateChat } = useChatUpdate();
|
||||||
|
const getChatMemoized = useGetChatMemoized();
|
||||||
|
const getChatMessageMemoized = useGetChatMessageMemoized();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const subscribe = !!chatId;
|
||||||
|
|
||||||
|
const shape = useMemo(() => messagesShape({ chatId: chatId || '', columns: ['id'] }), [chatId]);
|
||||||
|
|
||||||
|
return useShapeStream(
|
||||||
|
shape,
|
||||||
|
insertOperations,
|
||||||
|
useMemoizedFn((message) => {
|
||||||
|
if (message && message.value && chatId) {
|
||||||
|
const messageId = message.value.id;
|
||||||
|
const chat = getChatMemoized(chatId);
|
||||||
|
|
||||||
|
if (chat && messageId) {
|
||||||
|
const currentMessageIds = chat.message_ids;
|
||||||
|
const allMessageIds = uniq([...currentMessageIds, messageId]);
|
||||||
|
|
||||||
|
if (currentMessageIds.length !== allMessageIds.length) {
|
||||||
|
onUpdateChat({
|
||||||
|
...chat,
|
||||||
|
id: chatId,
|
||||||
|
message_ids: allMessageIds
|
||||||
|
});
|
||||||
|
|
||||||
|
const messageIsStored = getChatMessageMemoized(messageId);
|
||||||
|
if (!messageIsStored) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: chatQueryKeys.chatsGetChat(chatId).queryKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
subscribe
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ export type BusterChatMessageShape = {
|
||||||
is_completed: boolean;
|
is_completed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: (keyof BusterChatMessageShape)[] = [
|
const MESSAGE_DEFAULT_COLUMNS: (keyof BusterChatMessageShape)[] = [
|
||||||
'id',
|
'id',
|
||||||
'response_messages',
|
'response_messages',
|
||||||
'reasoning',
|
'reasoning',
|
||||||
|
@ -36,18 +36,24 @@ export const messageShape = ({
|
||||||
params: {
|
params: {
|
||||||
table: 'messages',
|
table: 'messages',
|
||||||
where: `chat_id='${chatId}' AND id='${messageId}'`,
|
where: `chat_id='${chatId}' AND id='${messageId}'`,
|
||||||
columns,
|
columns: MESSAGE_DEFAULT_COLUMNS,
|
||||||
replica: 'default'
|
replica: 'default'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const messagesShape = ({
|
export const messagesShape = ({
|
||||||
chatId
|
chatId,
|
||||||
|
columns = MESSAGE_DEFAULT_COLUMNS
|
||||||
}: {
|
}: {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
|
columns?: (keyof BusterChatMessageShape)[];
|
||||||
}): ElectricShapeOptions<BusterChatMessageShape> => {
|
}): ElectricShapeOptions<BusterChatMessageShape> => {
|
||||||
return {
|
return {
|
||||||
params: { table: 'messages', where: `chat_id='${chatId}'`, columns }
|
params: {
|
||||||
|
table: 'messages',
|
||||||
|
where: `chat_id='${chatId}'`,
|
||||||
|
columns: columns || MESSAGE_DEFAULT_COLUMNS
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,7 +152,7 @@ export const useStartChatFromAsset = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prefetchGetChat = async (
|
export const prefetchGetChatServer = async (
|
||||||
params: Parameters<typeof getChat>[0],
|
params: Parameters<typeof getChat>[0],
|
||||||
queryClientProp?: QueryClient
|
queryClientProp?: QueryClient
|
||||||
) => {
|
) => {
|
||||||
|
@ -170,6 +170,20 @@ export const prefetchGetChat = async (
|
||||||
return queryClient;
|
return queryClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const prefetchGetChat = async (
|
||||||
|
params: Parameters<typeof getChat>[0],
|
||||||
|
queryClientProp?: QueryClient
|
||||||
|
) => {
|
||||||
|
const queryClient = queryClientProp || new QueryClient();
|
||||||
|
|
||||||
|
await queryClient.prefetchQuery({
|
||||||
|
...chatQueryKeys.chatsGetChat(params.id),
|
||||||
|
queryFn: () => getChat(params)
|
||||||
|
});
|
||||||
|
|
||||||
|
return queryClient;
|
||||||
|
};
|
||||||
|
|
||||||
export const useUpdateChat = (params?: { updateToServer?: boolean }) => {
|
export const useUpdateChat = (params?: { updateToServer?: boolean }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { updateToServer = true } = params || {};
|
const { updateToServer = true } = params || {};
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { updateChatToIChat } from '@/lib/chat';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { prefetchGetMetricDataClient } from '@/api/buster_rest/metrics';
|
import { prefetchGetMetricDataClient } from '@/api/buster_rest/metrics';
|
||||||
import { queryKeys } from '@/api/query_keys';
|
import { queryKeys } from '@/api/query_keys';
|
||||||
import { useTrackAndUpdateMessageChanges } from '@/api/buster-electric/messages';
|
import { useTrackAndUpdateMessageChanges, useTrackAndUpdateNewMessages } from '@/api/buster-electric/messages';
|
||||||
import { useTrackAndUpdateChatChanges } from '@/api/buster-electric/chats';
|
import { useTrackAndUpdateChatChanges } from '@/api/buster-electric/chats';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useGetChatMessageMemoized } from '@/api/buster_rest/chats';
|
import { useGetChatMessageMemoized } from '@/api/buster_rest/chats';
|
||||||
|
@ -90,6 +90,7 @@ export const useChatStreaming = ({
|
||||||
|
|
||||||
//HOOKS FOR TRACKING CHAT AND MESSAGE CHANGES
|
//HOOKS FOR TRACKING CHAT AND MESSAGE CHANGES
|
||||||
useTrackAndUpdateChatChanges({ chatId, isStreamingMessage });
|
useTrackAndUpdateChatChanges({ chatId, isStreamingMessage });
|
||||||
|
useTrackAndUpdateNewMessages({ chatId });
|
||||||
useTrackAndUpdateMessageChanges({ chatId, messageId, isStreamingMessage }, (c) => {
|
useTrackAndUpdateMessageChanges({ chatId, messageId, isStreamingMessage }, (c) => {
|
||||||
const {
|
const {
|
||||||
reasoning_messages,
|
reasoning_messages,
|
||||||
|
|
Loading…
Reference in New Issue