fix: enable auto-scroll during assistant response streaming
Fix auto-scroll behavior when AI assistant streams responses in the web UI. Previously, the viewport would remain at the sent message position and users had to manually click a badge to see streaming responses. Fixes #14959 Changes: - Reset chat scroll state before sending message to ensure viewport readiness - Force scroll to bottom after message send to position viewport correctly - Detect streaming start (chatStream: null -> string) and trigger auto-scroll - Ensure smooth scroll-following during entire streaming response Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
eeb140b4f0
commit
04985dab23
@ -1,5 +1,5 @@
|
||||
import { parseAgentSessionKey } from "../../../src/sessions/session-key-utils.js";
|
||||
import { scheduleChatScroll } from "./app-scroll.ts";
|
||||
import { scheduleChatScroll, resetChatScroll } from "./app-scroll.ts";
|
||||
import { setLastActiveSessionKey } from "./app-settings.ts";
|
||||
import { resetToolStream } from "./app-tool-stream.ts";
|
||||
import type { OpenClawApp } from "./app.ts";
|
||||
@ -121,6 +121,8 @@ async function sendChatMessageNow(
|
||||
},
|
||||
) {
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
// Reset scroll state before sending to ensure auto-scroll works for the response
|
||||
resetChatScroll(host as unknown as Parameters<typeof resetChatScroll>[0]);
|
||||
const runId = await sendChatMessage(host as unknown as OpenClawApp, message, opts?.attachments);
|
||||
const ok = Boolean(runId);
|
||||
if (!ok && opts?.previousDraft != null) {
|
||||
@ -141,7 +143,8 @@ async function sendChatMessageNow(
|
||||
if (ok && opts?.restoreAttachments && opts.previousAttachments?.length) {
|
||||
host.chatAttachments = opts.previousAttachments;
|
||||
}
|
||||
scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0]);
|
||||
// Force scroll after sending to ensure viewport is at bottom for incoming stream
|
||||
scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0], true);
|
||||
if (ok && !host.chatRunId) {
|
||||
void flushChatQueue(host);
|
||||
}
|
||||
|
||||
@ -99,9 +99,15 @@ export function handleUpdated(host: LifecycleHost, changed: Map<PropertyKey, unk
|
||||
const forcedByTab = changed.has("tab");
|
||||
const forcedByLoad =
|
||||
changed.has("chatLoading") && changed.get("chatLoading") === true && !host.chatLoading;
|
||||
// Detect streaming start: chatStream changed from null/undefined to a string value
|
||||
const previousStream = changed.get("chatStream") as string | null | undefined;
|
||||
const streamJustStarted =
|
||||
changed.has("chatStream") &&
|
||||
(previousStream === null || previousStream === undefined) &&
|
||||
typeof host.chatStream === "string";
|
||||
scheduleChatScroll(
|
||||
host as unknown as Parameters<typeof scheduleChatScroll>[0],
|
||||
forcedByTab || forcedByLoad || !host.chatHasAutoScrolled,
|
||||
forcedByTab || forcedByLoad || streamJustStarted || !host.chatHasAutoScrolled,
|
||||
);
|
||||
}
|
||||
if (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user