mirror of https://github.com/buster-so/buster.git
reasoning message update
This commit is contained in:
parent
0db64cd4a4
commit
ee997a6c98
|
@ -35,7 +35,7 @@ const AvatarFallback = React.forwardRef<
|
||||||
<AvatarPrimitive.Fallback
|
<AvatarPrimitive.Fallback
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'bg-gray-light/60 text-background flex h-full w-full items-center justify-center rounded-full text-base',
|
'bg-gray-light/60 text-background flex h-full w-full items-center justify-center rounded-full text-xs',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
@ -45,7 +45,7 @@ StreamingMessage_File.displayName = 'StreamingMessage_File';
|
||||||
const StreamHeader: React.FC<{ file_name: string; version_number: number }> = React.memo(
|
const StreamHeader: React.FC<{ file_name: string; version_number: number }> = React.memo(
|
||||||
({ file_name, version_number }) => {
|
({ file_name, version_number }) => {
|
||||||
return (
|
return (
|
||||||
<div className="file-header bg-item-hover border-border flex h-8 w-full items-center space-x-1.5 overflow-hidden border-b px-2.5">
|
<div className="file-header bg-item-select border-border flex h-8 w-full items-center space-x-1.5 overflow-hidden border-b px-2.5">
|
||||||
<Text truncate>{file_name}</Text>
|
<Text truncate>{file_name}</Text>
|
||||||
<VersionPill version_number={version_number} />
|
<VersionPill version_number={version_number} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -182,7 +182,6 @@ export const useChatStreamMessage = () => {
|
||||||
draft[chat_id]?.messages?.[message_id]?.response_messages?.[responseMessageId];
|
draft[chat_id]?.messages?.[message_id]?.response_messages?.[responseMessageId];
|
||||||
if (!responseMessage) return;
|
if (!responseMessage) return;
|
||||||
const messageText = responseMessage as BusterChatMessageReasoning_text;
|
const messageText = responseMessage as BusterChatMessageReasoning_text;
|
||||||
|
|
||||||
Object.assign(messageText, {
|
Object.assign(messageText, {
|
||||||
...existingResponseMessageText,
|
...existingResponseMessageText,
|
||||||
...response_message,
|
...response_message,
|
||||||
|
|
|
@ -20,13 +20,19 @@ export const ChatResponseMessages: React.FC<ChatResponseMessagesProps> = React.m
|
||||||
messageId,
|
messageId,
|
||||||
(x) => x?.reasoning_message_ids?.[x.reasoning_message_ids.length - 1]
|
(x) => x?.reasoning_message_ids?.[x.reasoning_message_ids.length - 1]
|
||||||
);
|
);
|
||||||
|
const finalReasoningMessage = useMessageIndividual(
|
||||||
const lastMessageIndex = responseMessageIds.length - 1;
|
messageId,
|
||||||
const showDefaultMessage = responseMessageIds.length === 0;
|
(x) => x?.final_reasoning_message
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MessageContainer className="flex w-full flex-col overflow-hidden">
|
<MessageContainer className="flex w-full flex-col space-y-3 overflow-hidden">
|
||||||
{showDefaultMessage && <DefaultFirstMessage />}
|
<ChatResponseReasoning
|
||||||
|
reasoningMessageId={lastReasoningMessageId}
|
||||||
|
finalReasoningMessage={finalReasoningMessage}
|
||||||
|
isCompletedStream={isCompletedStream}
|
||||||
|
messageId={messageId}
|
||||||
|
/>
|
||||||
|
|
||||||
{responseMessageIds.map((responseMessageId, index) => (
|
{responseMessageIds.map((responseMessageId, index) => (
|
||||||
<React.Fragment key={responseMessageId}>
|
<React.Fragment key={responseMessageId}>
|
||||||
|
@ -35,14 +41,6 @@ export const ChatResponseMessages: React.FC<ChatResponseMessagesProps> = React.m
|
||||||
messageId={messageId}
|
messageId={messageId}
|
||||||
isCompletedStream={isCompletedStream}
|
isCompletedStream={isCompletedStream}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{index === lastMessageIndex && lastReasoningMessageId && (
|
|
||||||
<ChatResponseReasoning
|
|
||||||
reasoningMessageId={lastReasoningMessageId}
|
|
||||||
isCompletedStream={isCompletedStream}
|
|
||||||
messageId={messageId}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
</MessageContainer>
|
</MessageContainer>
|
||||||
|
@ -51,11 +49,3 @@ export const ChatResponseMessages: React.FC<ChatResponseMessagesProps> = React.m
|
||||||
);
|
);
|
||||||
|
|
||||||
ChatResponseMessages.displayName = 'ChatResponseMessages';
|
ChatResponseMessages.displayName = 'ChatResponseMessages';
|
||||||
|
|
||||||
const DefaultFirstMessage: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ShimmerText text="Thinking..." />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
@ -3,11 +3,9 @@ import { ShimmerText } from '@/components/ui/typography/ShimmerText';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { AnimatePresence } from 'framer-motion';
|
import { AnimatePresence } from 'framer-motion';
|
||||||
import { Stars } from '@/components/ui/icons';
|
|
||||||
import { Text } from '@/components/ui/typography';
|
import { Text } from '@/components/ui/typography';
|
||||||
import { useChatLayoutContextSelector } from '../../../ChatLayoutContext';
|
import { useChatLayoutContextSelector } from '../../../ChatLayoutContext';
|
||||||
import { useMessageIndividual } from '@/context/Chats';
|
import { useMessageIndividual } from '@/context/Chats';
|
||||||
import { cn } from '@/lib/classMerge';
|
|
||||||
|
|
||||||
const animations = {
|
const animations = {
|
||||||
initial: { opacity: 0 },
|
initial: { opacity: 0 },
|
||||||
|
@ -16,21 +14,23 @@ const animations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChatResponseReasoning: React.FC<{
|
export const ChatResponseReasoning: React.FC<{
|
||||||
reasoningMessageId: string;
|
reasoningMessageId: string | undefined;
|
||||||
|
finalReasoningMessage: string | undefined | null;
|
||||||
isCompletedStream: boolean;
|
isCompletedStream: boolean;
|
||||||
messageId: string;
|
messageId: string;
|
||||||
}> = React.memo(({ reasoningMessageId, isCompletedStream, messageId }) => {
|
}> = React.memo(({ reasoningMessageId, isCompletedStream, messageId }) => {
|
||||||
const lastMessageTitle = useMessageIndividual(
|
const lastMessageTitle = useMessageIndividual(
|
||||||
messageId,
|
messageId,
|
||||||
(x) => x?.reasoning_messages?.[reasoningMessageId]?.title
|
(x) => x?.reasoning_messages?.[reasoningMessageId ?? '']?.title
|
||||||
);
|
);
|
||||||
const finalReasoningMessage = useMessageIndividual(messageId, (x) => x?.final_reasoning_message);
|
const finalReasoningMessage = useMessageIndividual(messageId, (x) => x?.final_reasoning_message);
|
||||||
const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile);
|
const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile);
|
||||||
const selectedFileType = useChatLayoutContextSelector((x) => x.selectedFileType);
|
const selectedFileType = useChatLayoutContextSelector((x) => x.selectedFileType);
|
||||||
const isReasonginFileSelected = selectedFileType === 'reasoning';
|
const isReasonginFileSelected = selectedFileType === 'reasoning' && isCompletedStream;
|
||||||
|
|
||||||
const text: string = useMemo(() => {
|
const text: string = useMemo(() => {
|
||||||
if (finalReasoningMessage) return finalReasoningMessage;
|
if (finalReasoningMessage) return finalReasoningMessage;
|
||||||
|
if (lastMessageTitle) return lastMessageTitle;
|
||||||
return lastMessageTitle || 'Thinking...';
|
return lastMessageTitle || 'Thinking...';
|
||||||
}, [lastMessageTitle, finalReasoningMessage]);
|
}, [lastMessageTitle, finalReasoningMessage]);
|
||||||
|
|
||||||
|
@ -41,56 +41,19 @@ export const ChatResponseReasoning: React.FC<{
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(isReasonginFileSelected, isCompletedStream);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence initial={!isCompletedStream} mode="wait">
|
<AnimatePresence initial={!isCompletedStream} mode="wait">
|
||||||
<motion.div {...animations} key={text} className="mb-3.5 w-fit" onClick={onClickReasoning}>
|
<motion.div {...animations} key={text} className="mb-3.5 w-fit" onClick={onClickReasoning}>
|
||||||
<ShimmerTextWithIcon
|
{isReasonginFileSelected ? (
|
||||||
text={text ?? ''}
|
<Text className="cursor-pointer hover:underline">{text}</Text>
|
||||||
isCompletedStream={isCompletedStream}
|
) : (
|
||||||
isSelected={isReasonginFileSelected}
|
<ShimmerText text={text ?? ''} />
|
||||||
/>
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ChatResponseReasoning.displayName = 'ChatThoughts';
|
ChatResponseReasoning.displayName = 'ChatThoughts';
|
||||||
|
|
||||||
const ShimmerTextWithIcon = React.memo(
|
|
||||||
({
|
|
||||||
text,
|
|
||||||
isCompletedStream,
|
|
||||||
isSelected
|
|
||||||
}: {
|
|
||||||
text: string;
|
|
||||||
isCompletedStream: boolean;
|
|
||||||
isSelected: boolean;
|
|
||||||
}) => {
|
|
||||||
if (isCompletedStream) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'text-icon-color hover:text-foreground',
|
|
||||||
'cursor-pointer',
|
|
||||||
'flex w-fit items-center gap-1',
|
|
||||||
isSelected && 'text-foreground'
|
|
||||||
)}>
|
|
||||||
<div>
|
|
||||||
<Stars />
|
|
||||||
</div>
|
|
||||||
<Text variant="inherit">{text}</Text>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'text-icon-color flex cursor-pointer items-center gap-1'}>
|
|
||||||
<div className={'text-icon-color'}>
|
|
||||||
<Stars />
|
|
||||||
</div>
|
|
||||||
<ShimmerText text={text} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
ShimmerTextWithIcon.displayName = 'ShimmerTextWithIcon';
|
|
||||||
|
|
Loading…
Reference in New Issue