diff --git a/src/lib/components/MessageList.svelte b/src/lib/components/MessageList.svelte index 336f845..4835edf 100644 --- a/src/lib/components/MessageList.svelte +++ b/src/lib/components/MessageList.svelte @@ -105,6 +105,11 @@ $messages.length, $isProcessing, last?.content?.length ?? 0, + last?.parts?.length ?? 0, + // Letzten Part tracken — bei Streaming waechst dessen content + (last?.parts && last.parts.length > 0) + ? last.parts[last.parts.length - 1]?.content?.length ?? 0 + : 0, last?.toolCalls?.length ?? 0, last?.toolCalls?.map((t) => t.status).join(',') ?? '', ]; @@ -120,14 +125,12 @@ const last = $messages[$messages.length - 1]; const role = last?.role ?? null; if (role && role !== lastRole) { - if (role === 'user') { - // Beim Senden: wieder ans Ende kleben — und sofort scrollen, - // nicht auf den naechsten Stream-Token warten. Force=true geht - // am userScrolledUp-Guard vorbei. Ein rAF, damit das DOM die - // neue Message schon gerendert hat. - userScrolledUp = false; - requestAnimationFrame(() => scrollToBottom(true)); - } + // Beim Rollenwechsel (user→assistant oder assistant→user): + // Immer wieder ans Ende kleben. Ohne das bleibt userScrolledUp=true + // wenn checkScroll zwischen User-Send und Assistant-Antwort feuert, + // und der Auto-Scroll fuer die gesamte Antwort ist tot. + userScrolledUp = false; + requestAnimationFrame(() => scrollToBottom(true)); lastRole = role; } });