mirror of https://github.com/buster-so/buster.git
chat updates
This commit is contained in:
parent
9c0838209e
commit
0ad6eb3a00
|
@ -12,6 +12,7 @@ export interface BusterChat {
|
|||
created_by_id: string;
|
||||
created_by_name: string;
|
||||
created_by_avatar: string | null;
|
||||
feedback: 'negative' | null;
|
||||
// pinned_message_id: string | null; MAYBE WE NEED THIS?
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ import {
|
|||
getChat_server,
|
||||
updateChat,
|
||||
deleteChat,
|
||||
getListLogs
|
||||
getListLogs,
|
||||
duplicateChat
|
||||
} from './requests';
|
||||
import type { IBusterChat, IBusterChatMessage } from '@/api/asset_interfaces/chat';
|
||||
import { queryKeys } from '@/api/query_keys';
|
||||
|
@ -115,10 +116,22 @@ export const prefetchGetChat = async (
|
|||
};
|
||||
|
||||
export const useUpdateChat = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: updateChat,
|
||||
onMutate: () => {
|
||||
onMutate: (data) => {
|
||||
//this is actually handled in @useChatUpdate file
|
||||
|
||||
//except for the chat title and feedback
|
||||
if (data.title || data.feedback !== undefined) {
|
||||
const options = queryKeys.chatsGetChat(data.id);
|
||||
queryClient.setQueryData(options.queryKey, (old) => {
|
||||
return {
|
||||
...old!,
|
||||
...data
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -158,3 +171,9 @@ export const useGetChatMessage = <TData = IBusterChatMessage>(
|
|||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
export const useDuplicateChat = () => {
|
||||
return useMutation({
|
||||
mutationFn: duplicateChat
|
||||
});
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ import { mainApi } from '../instances';
|
|||
import { serverFetch } from '../../createServerInstance';
|
||||
import type { BusterChatListItem, BusterChat } from '@/api/asset_interfaces/chat';
|
||||
import type {
|
||||
DuplicateChatParams,
|
||||
GetChatListParams,
|
||||
GetChatParams,
|
||||
UpdateChatParams
|
||||
|
@ -55,3 +56,13 @@ export const updateChat = async ({ id, ...data }: UpdateChatParams): Promise<Bus
|
|||
export const deleteChat = async (ids: string[]): Promise<void> => {
|
||||
return mainApi.delete(`${CHATS_BASE}`, { data: { ids } }).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const duplicateChat = async ({
|
||||
id,
|
||||
message_id,
|
||||
share_with_same_people
|
||||
}: DuplicateChatParams): Promise<BusterChat> => {
|
||||
return mainApi
|
||||
.post(`${CHATS_BASE}/duplicate`, { id, message_id, share_with_same_people })
|
||||
.then((res) => res.data);
|
||||
};
|
||||
|
|
|
@ -37,8 +37,6 @@ export type UpdateMetricParams = {
|
|||
chart_config?: BusterChartConfigProps;
|
||||
/** Flag to save the current draft state */
|
||||
save_draft?: boolean;
|
||||
/** Feedback status for the metric */
|
||||
feedback?: 'negative';
|
||||
/** Admin only: verification status update */
|
||||
status?: VerificationStatus;
|
||||
/** file in yaml format to update */
|
||||
|
|
|
@ -3,6 +3,7 @@ import { QueryClient } from '@tanstack/react-query';
|
|||
import { useMemoizedFn, useDebounceFn } from '@/hooks';
|
||||
import {
|
||||
deleteMetrics,
|
||||
duplicateMetric,
|
||||
getMetric,
|
||||
getMetric_server,
|
||||
getMetricData,
|
||||
|
@ -382,3 +383,9 @@ export const useRemoveMetricFromDashboard = () => {
|
|||
mutationFn: removeMetricFromDashboard
|
||||
});
|
||||
};
|
||||
|
||||
export const useDuplicateMetric = () => {
|
||||
return useMutation({
|
||||
mutationFn: duplicateMetric
|
||||
});
|
||||
};
|
||||
|
|
|
@ -51,6 +51,8 @@ export interface UpdateChatParams {
|
|||
title?: string;
|
||||
/** Optional flag to set the chat's favorite status */
|
||||
is_favorited?: boolean;
|
||||
/** Optional feedback to set for the chat */
|
||||
feedback?: 'negative' | null;
|
||||
}
|
||||
|
||||
export interface ChatsSearchParams {
|
||||
|
@ -63,6 +65,13 @@ export interface DuplicateChatParams {
|
|||
id: string;
|
||||
/** The message ID to start the duplication from */
|
||||
message_id: string;
|
||||
/** The target chat ID to duplicate content to */
|
||||
chat_id: string;
|
||||
/** Whether to share the duplicated chat with the same people as the source chat */
|
||||
share_with_same_people: boolean;
|
||||
}
|
||||
|
||||
export interface DuplicateChatResponse {
|
||||
/** The unique identifier of the duplicated chat */
|
||||
id: string;
|
||||
/** The title of the duplicated chat */
|
||||
title: string;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { ChatInput } from './ChatInput';
|
|||
const autoClass = 'mx-auto max-w-[600px] w-full';
|
||||
|
||||
export const ChatContent: React.FC<{}> = React.memo(({}) => {
|
||||
const chatId = useChatIndividualContextSelector((state) => state.chatId);
|
||||
const chatMessageIds = useChatIndividualContextSelector((state) => state.chatMessageIds);
|
||||
|
||||
return (
|
||||
|
@ -16,7 +17,7 @@ export const ChatContent: React.FC<{}> = React.memo(({}) => {
|
|||
<div className="pb-8">
|
||||
{chatMessageIds?.map((messageId) => (
|
||||
<div key={messageId} className={autoClass}>
|
||||
<ChatMessageBlock key={messageId} messageId={messageId} />
|
||||
<ChatMessageBlock key={messageId} messageId={messageId} chatId={chatId || ''} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,8 @@ import { useGetChatMessage } from '@/api/buster_rest/chats';
|
|||
|
||||
export const ChatMessageBlock: React.FC<{
|
||||
messageId: string;
|
||||
}> = React.memo(({ messageId }) => {
|
||||
chatId: string;
|
||||
}> = React.memo(({ messageId, chatId }) => {
|
||||
const requestMessage = useGetChatMessage(messageId, (message) => message?.request_message);
|
||||
const isCompletedStream = useGetChatMessage(messageId, (x) => x?.isCompletedStream);
|
||||
|
||||
|
@ -14,7 +15,11 @@ export const ChatMessageBlock: React.FC<{
|
|||
return (
|
||||
<div className={'flex flex-col space-y-3.5 py-2 pr-3 pl-4'} id={messageId}>
|
||||
<ChatUserMessage requestMessage={requestMessage} />
|
||||
<ChatResponseMessages isCompletedStream={isCompletedStream!} messageId={messageId} />
|
||||
<ChatResponseMessages
|
||||
isCompletedStream={isCompletedStream!}
|
||||
messageId={messageId}
|
||||
chatId={chatId}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import React from 'react';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import { AppTooltip } from '@/components/ui/tooltip';
|
||||
import { Copy, ThumbsDown } from '@/components/ui/icons';
|
||||
import { ThumbsDown as ThumbsDownFilled } from '@/components/ui/icons/NucleoIconFilled';
|
||||
import { useDuplicateChat, useGetChat, useUpdateChat } from '@/api/buster_rest/chats';
|
||||
|
||||
export const ChatMessageOptions: React.FC<{
|
||||
messageId: string;
|
||||
chatId: string;
|
||||
}> = React.memo(({ messageId, chatId }) => {
|
||||
const { mutateAsync: duplicateChat, isPending: isCopying } = useDuplicateChat();
|
||||
const { mutateAsync: updateChat } = useUpdateChat();
|
||||
const { data: feedback } = useGetChat({ id: chatId }, (data) => data.feedback);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1">
|
||||
<AppTooltip title="Duplicate message">
|
||||
<Button
|
||||
variant="ghost"
|
||||
prefix={<Copy />}
|
||||
loading={isCopying}
|
||||
onClick={() =>
|
||||
duplicateChat({
|
||||
id: chatId,
|
||||
message_id: messageId,
|
||||
share_with_same_people: false
|
||||
})
|
||||
}
|
||||
/>
|
||||
</AppTooltip>
|
||||
<AppTooltip title="Report message">
|
||||
<Button
|
||||
variant="ghost"
|
||||
prefix={feedback === 'negative' ? <ThumbsDownFilled /> : <ThumbsDown />}
|
||||
onClick={() =>
|
||||
updateChat({
|
||||
id: chatId,
|
||||
feedback: feedback === 'negative' ? null : 'negative'
|
||||
})
|
||||
}
|
||||
/>
|
||||
</AppTooltip>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
ChatMessageOptions.displayName = 'ChatMessageOptions';
|
|
@ -3,14 +3,16 @@ import { MessageContainer } from '../MessageContainer';
|
|||
import { ChatResponseMessageSelector } from './ChatResponseMessageSelector';
|
||||
import { ChatResponseReasoning } from './ChatResponseReasoning';
|
||||
import { useGetChatMessage } from '@/api/buster_rest/chats';
|
||||
import { ChatMessageOptions } from '../ChatMessageOptions';
|
||||
|
||||
interface ChatResponseMessagesProps {
|
||||
isCompletedStream: boolean;
|
||||
messageId: string;
|
||||
chatId: string;
|
||||
}
|
||||
|
||||
export const ChatResponseMessages: React.FC<ChatResponseMessagesProps> = React.memo(
|
||||
({ isCompletedStream, messageId }) => {
|
||||
({ chatId, isCompletedStream, messageId }) => {
|
||||
const responseMessageIds = useGetChatMessage(messageId, (x) => x?.response_message_ids || [])!;
|
||||
const lastReasoningMessageId = useGetChatMessage(
|
||||
messageId,
|
||||
|
@ -36,6 +38,8 @@ export const ChatResponseMessages: React.FC<ChatResponseMessagesProps> = React.m
|
|||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{isCompletedStream && <ChatMessageOptions messageId={messageId} chatId={chatId} />}
|
||||
</MessageContainer>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue