diff --git a/web-app/src/containers/ChatInput.tsx b/web-app/src/containers/ChatInput.tsx
index 01a33260d..ec7fefcf9 100644
--- a/web-app/src/containers/ChatInput.tsx
+++ b/web-app/src/containers/ChatInput.tsx
@@ -49,6 +49,7 @@ const ChatInput = ({
const { prompt, setPrompt } = usePrompt()
const { t } = useTranslation()
const { spellCheckChatInput } = useGeneralSetting()
+ const { tokenSpeed } = useAppState()
const maxRows = 10
const { selectedModel } = useModelProvider()
@@ -226,7 +227,7 @@ const ChatInput = ({
{showSpeedToken && (
- 42 tokens/sec
+ {Math.round(tokenSpeed?.tokenSpeed ?? 0)} tokens/sec
)}
diff --git a/web-app/src/containers/ThreadContent.tsx b/web-app/src/containers/ThreadContent.tsx
index e9f0602c1..82f7d8d7b 100644
--- a/web-app/src/containers/ThreadContent.tsx
+++ b/web-app/src/containers/ThreadContent.tsx
@@ -14,6 +14,18 @@ import { useMessages } from '@/hooks/useMessages'
import ThinkingBlock from '@/containers/ThinkingBlock'
import ToolCallBlock from '@/containers/ToolCallBlock'
import { useChat } from '@/hooks/useChat'
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from '@/components/ui/dialog'
+import { Button } from '@/components/ui/button'
+import { Textarea } from '@/components/ui/textarea'
+import { toast } from 'sonner'
const CopyButton = ({ text }: { text: string }) => {
const [copied, setCopied] = useState(false)
@@ -49,6 +61,8 @@ const CopyButton = ({ text }: { text: string }) => {
// Use memo to prevent unnecessary re-renders, but allow re-renders when props change
export const ThreadContent = memo(
(item: ThreadMessage & { isLastMessage?: boolean; index?: number }) => {
+ const [message, setMessage] = useState(item.content?.[0]?.text?.value || '')
+
// Use useMemo to stabilize the components prop
const linkComponents = useMemo(
() => ({
@@ -94,6 +108,20 @@ export const ThreadContent = memo(
sendMessage(lastMessage.content?.[0]?.text?.value || '')
}, [deleteMessage, getMessages, item, sendMessage])
+ const editMessage = useCallback(
+ (messageId: string) => {
+ const threadMessages = getMessages(item.thread_id)
+ const index = threadMessages.findIndex((msg) => msg.id === messageId)
+ if (index === -1) return
+ // Delete all messages after the edited message
+ for (let i = threadMessages.length - 1; i >= index; i--) {
+ deleteMessage(threadMessages[i].thread_id, threadMessages[i].id)
+ }
+ sendMessage(message)
+ },
+ [deleteMessage, getMessages, item.thread_id, message, sendMessage]
+ )
+
const isToolCalls =
item.metadata &&
'tool_calls' in item.metadata &&
@@ -110,17 +138,63 @@ export const ThreadContent = memo(
-
+