🧠 fix: Handle Reasoning Chunk Edge Cases (#5800)

* refactor: better reasoning parsing

* style: better model selector mobile styling

* chore: bump vite
This commit is contained in:
Danny Avila 2025-02-11 11:28:18 -05:00 committed by GitHub
parent 404b27d045
commit 4de9619bd9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 1515 additions and 600 deletions

View file

@ -50,11 +50,24 @@ const ContentParts = memo(
[attachments, messageAttachmentsMap, messageId],
);
const hasReasoningParts = useMemo(
() => content?.some((part) => part?.type === ContentTypes.THINK && part.think) ?? false,
[content],
);
const hasReasoningParts = useMemo(() => {
const hasThinkPart = content?.some((part) => part?.type === ContentTypes.THINK) ?? false;
const allThinkPartsHaveContent =
content?.every((part) => {
if (part?.type !== ContentTypes.THINK) {
return true;
}
if (typeof part.think === 'string') {
const cleanedContent = part.think.replace(/<\/?think>/g, '').trim();
return cleanedContent.length > 0;
}
return false;
}) ?? false;
return hasThinkPart && allThinkPartsHaveContent;
}, [content]);
if (!content) {
return null;
}

View file

@ -159,7 +159,9 @@ const MessageContent = ({
return (
<>
{thinkingContent && <Thinking key={`thinking-${messageId}`}>{thinkingContent}</Thinking>}
{thinkingContent.length > 0 && (
<Thinking key={`thinking-${messageId}`}>{thinkingContent}</Thinking>
)}
<DisplayMessage
key={`display-${messageId}`}
showCursor={showRegularCursor}

View file

@ -11,9 +11,16 @@ type ReasoningProps = {
const Reasoning = memo(({ reasoning }: ReasoningProps) => {
const { isExpanded, nextType } = useMessageContext();
const reasoningText = useMemo(() => {
return reasoning.replace(/^<think>\s*/, '').replace(/\s*<\/think>$/, '');
return reasoning
.replace(/^<think>\s*/, '')
.replace(/\s*<\/think>$/, '')
.trim();
}, [reasoning]);
if (!reasoningText) {
return null;
}
return (
<div
className={cn(

View file

@ -40,13 +40,15 @@ export const TemporaryChat = () => {
};
return (
<div className="sticky bottom-0 border-none bg-surface-tertiary px-6 py-4 ">
<div className="flex items-center">
<div className={cn('flex flex-1 items-center gap-2', isActiveConvo && 'opacity-40')}>
<div className="sticky bottom-0 mt-auto w-full border-none bg-surface-tertiary px-6 py-4">
<div className="flex items-center justify-between">
<div className={cn('flex items-center gap-2', isActiveConvo && 'opacity-40')}>
<MessageCircleDashed className="icon-sm" aria-hidden="true" />
<span className="text-sm text-text-primary">{localize('com_ui_temporary_chat')}</span>
<span className="truncate text-sm text-text-primary">
{localize('com_ui_temporary_chat')}
</span>
</div>
<div className="ml-auto flex items-center">
<div className="flex flex-shrink-0 items-center">
<Switch
id="temporary-chat-switch"
checked={isTemporary}

View file

@ -56,7 +56,7 @@ function SelectDropDownPop({
return (
<Root>
<div className={'flex items-center justify-center gap-2 '}>
<div className={'flex items-center justify-center gap-2'}>
<div className={'relative w-full'}>
<Trigger asChild>
<button
@ -64,23 +64,24 @@ function SelectDropDownPop({
className={cn(
'pointer-cursor relative flex flex-col rounded-lg border border-black/10 bg-white py-2 pl-3 pr-10 text-left focus:ring-0 focus:ring-offset-0 dark:border-gray-700 dark:bg-gray-800 sm:text-sm',
'hover:bg-gray-50 radix-state-open:bg-gray-50 dark:hover:bg-gray-700 dark:radix-state-open:bg-gray-700',
'min-w-[200px] max-w-[215px] sm:min-w-full sm:max-w-full',
)}
aria-label={`Select ${title}`}
aria-haspopup="false"
>
{' '}
{showLabel && (
<label className="block text-xs text-gray-700 dark:text-gray-500 ">{title}</label>
<label className="block text-xs text-gray-700 dark:text-gray-500">{title}</label>
)}
<span className="inline-flex w-full ">
<span className="inline-flex w-full">
<span
className={cn(
'flex h-6 items-center gap-1 text-sm text-gray-800 dark:text-white',
'flex h-6 items-center gap-1 text-sm text-text-primary',
!showLabel ? 'text-xs' : '',
'min-w-[75px] font-normal',
)}
>
{typeof value !== 'string' && value ? value.label ?? '' : value ?? ''}
{typeof value !== 'string' && value ? (value.label ?? '') : (value ?? '')}
</span>
</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2">
@ -91,7 +92,7 @@ function SelectDropDownPop({
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4 text-gray-400"
className="h-4 w-4 text-gray-400"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
@ -107,7 +108,7 @@ function SelectDropDownPop({
side="bottom"
align="start"
className={cn(
'mt-2 max-h-[52vh] min-w-full overflow-hidden overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-700 dark:text-white lg:max-h-[52vh]',
'mr-3 mt-2 max-h-[52vh] w-full max-w-[85vw] overflow-hidden overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-700 dark:text-white sm:max-w-full lg:max-h-[52vh]',
hasSearchRender && 'relative',
)}
>