diff --git a/web/src/pages/agent/chat/box.tsx b/web/src/pages/agent/chat/box.tsx index 96326b0b02..2d0ad3c8fb 100644 --- a/web/src/pages/agent/chat/box.tsx +++ b/web/src/pages/agent/chat/box.tsx @@ -14,7 +14,7 @@ import { } from '@/hooks/use-agent-request'; import { useFetchUserInfo } from '@/hooks/use-user-setting-request'; import { buildMessageUuidWithRole } from '@/utils/chat'; -import { memo, useCallback, useContext, useEffect } from 'react'; +import { memo, useCallback, useContext, useEffect, useRef } from 'react'; import { AgentChatContext } from '../context'; import DebugContent from '../debug-content'; import { useAwaitComponentData } from '../hooks/use-chat-logic'; @@ -64,6 +64,27 @@ function AgentChatBox() { const isTaskMode = useIsTaskMode(); + const inputWrapperRef = useRef(null); + + // Keep the message list anchored to its bottom edge while the input box + // changes height (drag-to-resize or autosize), so history shifts up/down + // together with the input instead of being covered by it. + useEffect(() => { + const wrapper = inputWrapperRef.current; + const container = messageContainerRef.current; + if (!wrapper || !container) return; + let previousHeight = wrapper.clientHeight; + const observer = new ResizeObserver(() => { + const delta = wrapper.clientHeight - previousHeight; + previousHeight = wrapper.clientHeight; + if (delta !== 0) { + container.scrollTop += delta; + } + }); + observer.observe(wrapper); + return () => observer.disconnect(); + }, [messageContainerRef]); + const handleUploadFile: NonNullable = useCallback( async (files, options) => { @@ -129,20 +150,22 @@ function AgentChatBox() {
{isTaskMode || ( - +
+ +
)} {visible && (