mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-07-04 12:41:15 +08:00
Merge remote-tracking branch 'origin/main' into feat/add-hermes-provider
# Conflicts: # src/components/mcp/constants.ts
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { memo, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { memo, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo';
|
||||
@@ -30,7 +30,6 @@ type MessageComponentProps = {
|
||||
onFileOpen?: (filePath: string, diffInfo?: unknown) => void;
|
||||
onShowSettings?: () => void;
|
||||
onGrantToolPermission?: (suggestion: ClaudePermissionSuggestion) => PermissionGrantResult | null | undefined;
|
||||
autoExpandTools?: boolean;
|
||||
showRawParameters?: boolean;
|
||||
showThinking?: boolean;
|
||||
selectedProject?: Project | null;
|
||||
@@ -45,7 +44,7 @@ type InteractiveOption = {
|
||||
|
||||
const COPY_HIDDEN_TOOL_NAMES = new Set(['Bash', 'Edit', 'Write', 'ApplyPatch']);
|
||||
|
||||
const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, autoExpandTools, showRawParameters, showThinking, selectedProject, provider }: MessageComponentProps) => {
|
||||
const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, showRawParameters, showThinking, selectedProject, provider }: MessageComponentProps) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const isGrouped = prevMessage && prevMessage.type === message.type &&
|
||||
((prevMessage.type === 'assistant') ||
|
||||
@@ -53,7 +52,6 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
(prevMessage.type === 'tool') ||
|
||||
(prevMessage.type === 'error'));
|
||||
const messageRef = useRef<HTMLDivElement | null>(null);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const userCopyContent = String(message.content || '');
|
||||
const formattedMessageContent = useMemo(
|
||||
() => formatUsageLimitText(String(message.content || '')),
|
||||
@@ -72,32 +70,6 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
!message.isThinking;
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const node = messageRef.current;
|
||||
if (!autoExpandTools || !node || !message.isToolUse) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && !isExpanded) {
|
||||
setIsExpanded(true);
|
||||
const details = node.querySelectorAll<HTMLDetailsElement>('details');
|
||||
details.forEach((detail) => {
|
||||
detail.open = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
);
|
||||
|
||||
observer.observe(node);
|
||||
|
||||
return () => {
|
||||
observer.unobserve(node);
|
||||
};
|
||||
}, [autoExpandTools, isExpanded, message.isToolUse]);
|
||||
|
||||
const formattedTime = useMemo(() => new Date(message.timestamp).toLocaleTimeString(), [message.timestamp]);
|
||||
const shouldHideThinkingMessage = Boolean(message.isThinking && !showThinking);
|
||||
|
||||
@@ -115,7 +87,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
/* User message bubble on the right */
|
||||
<div className="flex w-full items-end space-x-0 sm:w-auto sm:max-w-[85%] sm:space-x-3 md:max-w-md lg:max-w-lg xl:max-w-xl">
|
||||
<div className="group flex-1 rounded-2xl rounded-br-md bg-blue-600 px-3 py-2 text-white shadow-sm sm:flex-initial sm:px-4">
|
||||
<div dir="auto" className="whitespace-pre-wrap break-words text-sm">
|
||||
<div dir="auto" className="whitespace-pre-wrap break-words font-serif text-sm">
|
||||
{message.content}
|
||||
</div>
|
||||
{message.images && message.images.length > 0 && (
|
||||
@@ -166,7 +138,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
🔧
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full p-1 text-sm text-white">
|
||||
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full p-1 text-sm text-foreground">
|
||||
<SessionProviderLogo provider={provider} className="h-full w-full" />
|
||||
</div>
|
||||
)}
|
||||
@@ -196,7 +168,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
<>
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-col">
|
||||
<Markdown className="prose prose-sm max-w-none dark:prose-invert">
|
||||
<Markdown className="prose prose-sm max-w-none font-serif dark:prose-invert">
|
||||
{String(message.displayText || '')}
|
||||
</Markdown>
|
||||
</div>
|
||||
@@ -212,7 +184,6 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
onFileOpen={onFileOpen}
|
||||
createDiff={createDiff}
|
||||
selectedProject={selectedProject}
|
||||
autoExpandTools={autoExpandTools}
|
||||
showRawParameters={showRawParameters}
|
||||
rawToolInput={typeof message.toolInput === 'string' ? message.toolInput : undefined}
|
||||
isSubagentContainer={message.isSubagentContainer}
|
||||
@@ -235,7 +206,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
<span className="text-xs font-medium text-red-700 dark:text-red-300">{t('messageTypes.error')}</span>
|
||||
</div>
|
||||
<div className="relative text-sm text-red-900 dark:text-red-100">
|
||||
<Markdown className="prose prose-sm prose-red max-w-none dark:prose-invert">
|
||||
<Markdown className="prose prose-sm prose-red max-w-none font-serif dark:prose-invert">
|
||||
{String(message.toolResult.content || '')}
|
||||
</Markdown>
|
||||
</div>
|
||||
@@ -252,7 +223,6 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
onFileOpen={onFileOpen}
|
||||
createDiff={createDiff}
|
||||
selectedProject={selectedProject}
|
||||
autoExpandTools={autoExpandTools}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
@@ -344,7 +314,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
<Reasoning defaultOpen={false}>
|
||||
<ReasoningTrigger />
|
||||
<ReasoningContent>
|
||||
<Markdown className="prose prose-sm prose-gray max-w-none dark:prose-invert">
|
||||
<Markdown className="prose prose-sm prose-gray max-w-none font-serif dark:prose-invert">
|
||||
{message.content}
|
||||
</Markdown>
|
||||
<div className="mt-3 flex items-center text-[11px]">
|
||||
@@ -379,15 +349,15 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
|
||||
return (
|
||||
<div className="my-2">
|
||||
<div className="mb-2 flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<div className="mb-2 flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span className="font-medium">{t('json.response')}</span>
|
||||
</div>
|
||||
<div className="overflow-hidden rounded-lg border border-gray-600/30 bg-gray-800 dark:border-gray-700 dark:bg-gray-900">
|
||||
<div className="overflow-hidden rounded-lg border border-border bg-muted">
|
||||
<pre className="overflow-x-auto p-4">
|
||||
<code className="block whitespace-pre font-mono text-sm text-gray-100 dark:text-gray-200">
|
||||
<code className="block whitespace-pre font-mono text-sm text-foreground">
|
||||
{formatted}
|
||||
</code>
|
||||
</pre>
|
||||
@@ -401,7 +371,7 @@ const MessageComponent = memo(({ message, prevMessage, createDiff, onFileOpen, a
|
||||
|
||||
// Normal rendering for non-JSON content
|
||||
return message.type === 'assistant' ? (
|
||||
<Markdown className="prose prose-sm prose-gray max-w-none dark:prose-invert">
|
||||
<Markdown className="prose prose-sm prose-gray max-w-none font-serif dark:prose-invert">
|
||||
{content}
|
||||
</Markdown>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user