chat update

This commit is contained in:
Nate Kelley 2025-02-10 20:15:32 -07:00
parent 7a349da981
commit 644d7f89d8
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
20 changed files with 77 additions and 62 deletions

View File

@ -5,9 +5,5 @@ export default function Page({
}: {
params: { chatId: string; messageId: string };
}) {
return (
<>
<ReasoningController chatId={chatId} messageId={messageId} />
</>
);
return <ReasoningController chatId={chatId} messageId={messageId} />;
}

View File

@ -1,5 +1,5 @@
import { createStyles } from 'antd-style';
import { Text } from '@/components';
import { Text } from '@/components/text';
import React from 'react';
export const VersionPill: React.FC<{ version_number: number }> = React.memo(

View File

@ -1,5 +1,5 @@
'use client';
import React, { useMemo } from 'react';
import React from 'react';
import { useChatIndividualContextSelector } from '../../_layouts/ChatLayout/ChatContext';
import { ReasoningMessageContainer } from './ReasoningMessageContainer';
import { useBusterChatContextSelector } from '@/context/Chats';

View File

@ -1,6 +1,7 @@
import type { FileType } from '@/api/asset_interfaces';
import { createChatAssetRoute } from '@appLayouts/ChatLayout/ChatLayoutContext/helpers';
import { AppMaterialIcons, AppTooltip } from '@/components';
import { AppTooltip } from '@/components/tooltip';
import { AppMaterialIcons } from '@/components/icons';
import { Button } from 'antd';
import React from 'react';
import { useChatLayoutContextSelector } from '@/app/app/_layouts/ChatLayout';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Text } from '@/components';
import { VersionPill } from '@/app/app/_components/Text/VersionPill';
import { Text } from '@/components/text';
import { VersionPill } from '@appComponents/Text/VersionPill';
export const ReasoningFileTitle = React.memo(
({ file_name, version_number }: { file_name: string; version_number: number }) => {

View File

@ -13,14 +13,11 @@ const autoSize = { minRows: 3, maxRows: 16 };
export const ChatInput: React.FC<{}> = React.memo(({}) => {
const { styles, cx } = useStyles();
const isNewChat = useChatIndividualContextSelector((x) => x.isNewChat);
const isFollowUpChat = useChatIndividualContextSelector((x) => x.isFollowUpChat);
const inputRef = useRef<TextAreaRef>(null);
const loading = useChatIndividualContextSelector((x) => x.isLoading);
const [inputValue, setInputValue] = useState('');
const [isFocused, setIsFocused] = React.useState(false);
const loading = isNewChat || isFollowUpChat;
const [isFocused, setIsFocused] = useState(false);
const disableSendButton = useMemo(() => {
return !inputHasText(inputValue);

View File

@ -7,6 +7,7 @@ import {
import type { SelectedFile } from '../interfaces';
import { useSubscribeIndividualChat } from './useSubscribeIndividualChat';
import { useAutoChangeLayout } from './useAutoChangeLayout';
import { useBusterChatContextSelector } from '@/context/Chats';
export const useChatIndividualContext = ({
chatId,
@ -25,6 +26,7 @@ export const useChatIndividualContext = ({
chatId,
defaultSelectedFile
});
const hasChat = !!chatId && !!chat;
const chatTitle = chat?.title;
const chatMessageIds = chat?.messages ?? [];
@ -34,10 +36,11 @@ export const useChatIndividualContext = ({
//MESSAGES
const currentMessageId = chatMessageIds[chatMessageIds.length - 1];
const isNewChat = chat?.isNewChat ?? false;
const isFollowUpChat = chat?.isFollowupMessage ?? false;
const isLoading = useBusterChatContextSelector(
(x) => x.chatsMessages[currentMessageId]?.isCompletedStream
);
useAutoChangeLayout({ lastMessageId: currentMessageId, onSetSelectedFile, chat });
useAutoChangeLayout({ lastMessageId: currentMessageId, onSetSelectedFile });
return {
hasChat,
@ -48,8 +51,7 @@ export const useChatIndividualContext = ({
selectedFileType,
chatMessageIds,
chatId,
isNewChat,
isFollowUpChat
isLoading
};
};

View File

@ -1,24 +1,20 @@
import { IBusterChat, useBusterChatContextSelector } from '@/context/Chats';
import { SelectedFile } from '../interfaces';
import { useBusterChatContextSelector } from '@/context/Chats';
import type { SelectedFile } from '../interfaces';
import { usePrevious } from 'ahooks';
import { useEffect } from 'react';
export const useAutoChangeLayout = ({
lastMessageId,
chat,
onSetSelectedFile
}: {
lastMessageId: string;
chat: IBusterChat | undefined;
onSetSelectedFile: (file: SelectedFile) => void;
}) => {
const message = useBusterChatContextSelector((x) => x.chatsMessages[lastMessageId]);
const reasoningMessagesLength = message?.reasoning?.length;
const previousReasoningMessagesLength = usePrevious(reasoningMessagesLength);
const isCompletedStream = message?.isCompletedStream;
const isFollowupMessage = chat?.isFollowupMessage;
const isNewChat = chat?.isNewChat;
const isLoading = isNewChat || isFollowupMessage || !isCompletedStream;
const isLoading = !isCompletedStream;
const hasReasoning = !!reasoningMessagesLength;
const previousIsEmpty = previousReasoningMessagesLength === 0;

View File

@ -74,8 +74,6 @@ export const useFileFallback = ({
const fallbackToFileChat = ({ id }: { id: string }): IBusterChat => {
return {
id,
isNewChat: false,
isFollowupMessage: false,
messages: [fallbackMessageId(id)],
title: '',
is_favorited: false,

View File

@ -5,7 +5,7 @@ import {
useContextSelector
} from '@fluentui/react-context-selector';
import type { BusterChat } from '@/api/asset_interfaces';
import { IBusterChat, IBusterChatMessage } from '../interfaces';
import type { IBusterChat, IBusterChatMessage } from '../interfaces';
import { useChatSubscriptions } from './useChatSubscriptions';
import { useChatAssosciations } from './useChatAssosciations';
import { useChatSelectors } from './useChatSelectors';

View File

@ -1 +1 @@
export * from './chatUpgrader';
export * from './useFileFallback';

View File

@ -61,8 +61,6 @@ export const useFileFallback = ({
const fallbackToFileChat = ({ id }: { id: string }): IBusterChat => {
return {
id,
isNewChat: true,
isFollowupMessage: false,
messages: [fallbackMessageId(id)],
title: '',
is_favorited: false,

View File

@ -1,5 +1,5 @@
import { MutableRefObject, useCallback } from 'react';
import { IBusterChat, IBusterChatMessage } from '../interfaces';
import { type MutableRefObject, useCallback } from 'react';
import type { IBusterChat, IBusterChatMessage } from '../interfaces';
import { useMemoizedFn } from 'ahooks';
export const useChatSelectors = ({

View File

@ -2,8 +2,8 @@ import { MutableRefObject } from 'react';
import { useBusterWebSocket } from '../../BusterWebSocket';
import { useMemoizedFn } from 'ahooks';
import type { BusterChat } from '@/api/asset_interfaces';
import { IBusterChat, IBusterChatMessage } from '../interfaces';
import { chatMessageUpgrader, chatUpgrader } from './helpers';
import type { IBusterChat, IBusterChatMessage } from '../interfaces';
import { updateChatToIChat } from '@/utils/chat';
import { MOCK_CHAT } from './MOCK_CHAT';
export const useChatSubscriptions = ({
@ -18,17 +18,17 @@ export const useChatSubscriptions = ({
const busterSocket = useBusterWebSocket();
const _onGetChat = useMemoizedFn((chat: BusterChat): IBusterChat => {
const upgradedChat = chatUpgrader(chat);
const upgradedChatMessages = chatMessageUpgrader(chat.messages);
chatsRef.current[chat.id] = upgradedChat;
const { iChat, iChatMessages } = updateChatToIChat(chat);
chatsRef.current[chat.id] = iChat;
chatsMessagesRef.current = {
...chatsMessagesRef.current,
...upgradedChatMessages
...iChatMessages
};
startTransition(() => {
//just used to trigger UI update
});
return upgradedChat;
return iChat;
});
const unsubscribeFromChat = useMemoizedFn(({ chatId }: { chatId: string }) => {

View File

@ -1,7 +1,7 @@
import { useBusterWebSocket } from '@/context/BusterWebSocket';
import { useMemoizedFn } from 'ahooks';
import { MutableRefObject } from 'react';
import { IBusterChat, IBusterChatMessage } from '../interfaces';
import { type MutableRefObject } from 'react';
import type { IBusterChat, IBusterChatMessage } from '../interfaces';
export const useChatUpdate = ({
chatsRef,
@ -15,13 +15,25 @@ export const useChatUpdate = ({
const busterSocket = useBusterWebSocket();
const onUpdateChat = useMemoizedFn(
async (newChatConfig: Partial<IBusterChat> & { id: string }) => {
async (newChatConfig: Partial<IBusterChat> & { id: string }, saveToServer: boolean = false) => {
chatsRef.current[newChatConfig.id] = {
...chatsRef.current[newChatConfig.id],
...newChatConfig
};
startTransition(() => {
//just used to trigger UI update
if (saveToServer) {
const { title, is_favorited, id } = chatsRef.current[newChatConfig.id];
busterSocket.emit({
route: '/chats/update',
payload: {
id,
title,
is_favorited
}
});
}
});
}
);
@ -38,8 +50,21 @@ export const useChatUpdate = ({
}
);
const onBulkSetChatMessages = useMemoizedFn(
(newMessagesConfig: Record<string, IBusterChatMessage>) => {
chatsMessagesRef.current = {
...chatsMessagesRef.current,
...newMessagesConfig
};
startTransition(() => {
//just used to trigger UI update
});
}
);
return {
onUpdateChat,
onUpdateChatMessage
onUpdateChatMessage,
onBulkSetChatMessages
};
};

View File

@ -5,7 +5,7 @@ import {
useContextSelector
} from '@fluentui/react-context-selector';
import { useMemoizedFn } from 'ahooks';
import type { BusterDatasetListItem, BusterSearchResult, FileType } from '@/api/asset_interfaces';
import type { BusterSearchResult, FileType } from '@/api/asset_interfaces';
import { useBusterWebSocket } from '@/context/BusterWebSocket';
import { useChatUpdateMessage } from './useChatUpdateMessage';

View File

@ -7,6 +7,7 @@ import {
ChatEvent_GeneratingResponseMessage,
ChatEvent_GeneratingTitle
} from '@/api/buster_socket/chats';
import { updateChatToIChat } from '@/utils/chat';
export const useChatUpdateMessage = () => {
const busterSocket = useBusterWebSocket();
@ -14,6 +15,7 @@ export const useChatUpdateMessage = () => {
const getChatMemoized = useBusterChatContextSelector((x) => x.getChatMemoized);
const onUpdateChatMessage = useBusterChatContextSelector((x) => x.onUpdateChatMessage);
const getChatMessageMemoized = useBusterChatContextSelector((x) => x.getChatMessageMemoized);
const onBulkSetChatMessages = useBusterChatContextSelector((x) => x.onBulkSetChatMessages);
const _generatingTitleCallback = useMemoizedFn((d: ChatEvent_GeneratingTitle) => {
const { chat_id, title, title_chunk } = d;
@ -57,10 +59,9 @@ export const useChatUpdateMessage = () => {
);
const completeChatCallback = useMemoizedFn((d: BusterChat) => {
onUpdateChatMessage({
...d,
isCompletedStream: true
});
const { iChat, iChatMessages } = updateChatToIChat(d);
onBulkSetChatMessages(iChatMessages);
onUpdateChat(iChat);
});
const stopChatCallback = useMemoizedFn((chatId: string) => {

View File

@ -1,8 +1,6 @@
import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
export interface IBusterChat extends Omit<BusterChat, 'messages'> {
isNewChat: boolean;
isFollowupMessage: boolean;
messages: string[];
}

View File

@ -1,20 +1,14 @@
import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
import type { IBusterChat, IBusterChatMessage } from '../../interfaces';
import type { IBusterChat, IBusterChatMessage } from '@/context/Chats/interfaces';
export const chatUpgrader = (
chat: BusterChat,
options?: { isNewChat?: boolean; isFollowupMessage?: boolean }
): IBusterChat => {
const { isNewChat = false, isFollowupMessage = false } = options || {};
const chatUpgrader = (chat: BusterChat): IBusterChat => {
return {
...chat,
isNewChat,
isFollowupMessage,
messages: chat.messages.map((message) => message.id)
};
};
export const chatMessageUpgrader = (
const chatMessageUpgrader = (
message: BusterChatMessage[],
options?: { isCompletedStream: boolean; messageId: string }
): Record<string, IBusterChatMessage> => {
@ -40,3 +34,12 @@ export const chatMessageUpgrader = (
{} as Record<string, IBusterChatMessage>
);
};
export const updateChatToIChat = (chat: BusterChat) => {
const iChat = chatUpgrader(chat);
const iChatMessages = chatMessageUpgrader(chat.messages);
return {
iChat,
iChatMessages
};
};