diff --git a/packages/ui/src/components/chat/multi-task-chat.tsx b/packages/ui/src/components/chat/multi-task-chat.tsx index 42f83cf..20e2798 100644 --- a/packages/ui/src/components/chat/multi-task-chat.tsx +++ b/packages/ui/src/components/chat/multi-task-chat.tsx @@ -107,7 +107,7 @@ export default function MultiTaskChat(props: MultiTaskChatProps) { }; // Filter messages based on selected task - use store's session messages for the task session - const filteredMessageIds = () => { + const filteredMessageIds = createMemo(() => { const task = selectedTask(); if (!task) return []; // Show no messages in Pipeline view @@ -119,7 +119,7 @@ export default function MultiTaskChat(props: MultiTaskChatProps) { // Fallback to task.messageIds for backward compatibility return task.messageIds || []; - }; + }); // Note: Auto-scroll is handled in two places: // 1. After sending a message (in handleSendMessage) @@ -229,13 +229,23 @@ export default function MultiTaskChat(props: MultiTaskChatProps) { return () => clearInterval(interval); }); - // Auto-scroll when new messages arrive + // Auto-scroll when new messages arrive (throttled to count changes only) + let lastScrolledCount = 0; createEffect(() => { const ids = filteredMessageIds(); + const count = ids.length; const thinking = isAgentThinking(); - // Scroll when message count changes or when thinking starts (unless user is scrolling) - if ((ids.length > 0 || thinking) && !userScrolling()) { + // Only scroll when message COUNT changes, not on every store update + // This prevents the effect from firing on every streaming chunk + if (count !== lastScrolledCount && count > 0 && !userScrolling()) { + lastScrolledCount = count; + requestAnimationFrame(() => { + setTimeout(scrollToBottom, 50); + }); + } + // Also scroll when thinking first starts + if (thinking && count > 0 && !userScrolling()) { requestAnimationFrame(() => { setTimeout(scrollToBottom, 50); }); diff --git a/packages/ui/src/components/message-block-list.tsx b/packages/ui/src/components/message-block-list.tsx index 68d4f6e..3db083c 100644 --- a/packages/ui/src/components/message-block-list.tsx +++ b/packages/ui/src/components/message-block-list.tsx @@ -1,10 +1,7 @@ -import { Index, type Accessor, createEffect } from "solid-js" +import { Index, type Accessor } from "solid-js" import VirtualItem from "./virtual-item" import MessageBlock from "./message-block" import type { InstanceMessageStore } from "../stores/message-v2/instance-store" -import { getLogger } from "../lib/logger" - -const log = getLogger("multix-chat") export function getMessageAnchorId(messageId: string) { return `message-anchor-${messageId}` @@ -31,14 +28,6 @@ interface MessageBlockListProps { } export default function MessageBlockList(props: MessageBlockListProps) { - createEffect(() => { - const ids = props.messageIds(); - log.info("[MessageBlockList] messageIds changed", { - count: ids.length, - ids: ids.slice(-3) // Log last 3 for context - }); - }); - return ( <>