fix: keep agent chat history anchored when resizing the input box (#17834)

This commit is contained in:
euvre
2026-08-05 22:51:22 -07:00
committed by GitHub
parent 8bc34219f5
commit 0054657c7c

View File

@@ -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<HTMLDivElement>(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<FileUploadProps['onUpload']> =
useCallback(
async (files, options) => {
@@ -129,20 +150,22 @@ function AgentChatBox() {
<div ref={scrollRef} />
</div>
{isTaskMode || (
<NextMessageInput
value={value}
sendLoading={sendLoading}
disabled={isWaiting}
sendDisabled={sendLoading || isWaiting}
isUploading={loading || isWaiting}
resize="vertical"
onPressEnter={handlePressEnter}
onInputChange={handleInputChange}
stopOutputMessage={stopOutputMessage}
onUpload={handleUploadFile}
removeFile={removeFile}
conversationId=""
/>
<div ref={inputWrapperRef}>
<NextMessageInput
value={value}
sendLoading={sendLoading}
disabled={isWaiting}
sendDisabled={sendLoading || isWaiting}
isUploading={loading || isWaiting}
resize="vertical"
onPressEnter={handlePressEnter}
onInputChange={handleInputChange}
stopOutputMessage={stopOutputMessage}
onUpload={handleUploadFile}
removeFile={removeFile}
conversationId=""
/>
</div>
)}
</section>
{visible && (