diff --git a/web/claw/app/components/ChatPanel.vue b/web/claw/app/components/ChatPanel.vue
index d982097..6728624 100644
--- a/web/claw/app/components/ChatPanel.vue
+++ b/web/claw/app/components/ChatPanel.vue
@@ -50,8 +50,20 @@ function onScroll(): void {
pinned.value = el.scrollHeight - el.scrollTop - el.clientHeight < 48
}
+// Thinking grows inside the trailing entry without changing the
+// entries length, so its total length joins the watch to keep the
+// stream pinned at the bottom.
+function liveThinkingLength(): number {
+ return (
+ props.live?.entries.reduce(
+ (count, entry) => (entry.kind === 'thinking' ? count + entry.text.length : count),
+ 0,
+ ) ?? 0
+ )
+}
+
watch(
- () => [props.items.length, props.live?.reply.length, props.live?.thinking.length, props.live?.entries.length],
+ () => [props.items.length, props.live?.reply.length, liveThinkingLength(), props.live?.entries.length],
async () => {
if (!pinned.value) return
await nextTick()
@@ -224,10 +236,6 @@ function streamTone(status: StreamStatus): 'ok' | 'warn' | 'error' {
{{ item.turn.thinking }}
- {{ live.thinking }}
-