From 47f4adcefc7c465220c974fe7b57c8bab05a50b4 Mon Sep 17 00:00:00 2001 From: Eulices Lopez <105620565+eulicesl@users.noreply.github.com> Date: Mon, 9 Mar 2026 06:38:10 -0400 Subject: [PATCH 1/2] fix(ios): picker adaptive onChange loop + OSLog string concatenation Two independent fixes: 1. **Picker adaptive tag onChange loop**: prevent infinite loop when picker selection triggers onChange which re-triggers state update 2. **OSLog concatenation**: Swift doesn't support '+' between OSLogMessage operands. Combined 3 multi-line log strings into single-line interpolations in NodeAppModel pending action logging. --- .../OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift | 3 ++- .../OpenClawKit/Sources/OpenClawChatUI/ChatView.swift | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift index 3cd290389fe..58974dff125 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift @@ -9,7 +9,7 @@ import UniformTypeIdentifiers @MainActor struct OpenClawChatComposer: View { - private static let menuThinkingLevels = ["off", "low", "medium", "high"] + private static let menuThinkingLevels = ["off", "low", "medium", "high", "adaptive"] @Bindable var viewModel: OpenClawChatViewModel let style: OpenClawChatView.Style @@ -99,6 +99,7 @@ struct OpenClawChatComposer: View { Text("Low").tag("low") Text("Medium").tag("medium") Text("High").tag("high") + Text("Adaptive").tag("adaptive") if !Self.menuThinkingLevels.contains(self.viewModel.thinkingLevel) { Text(self.viewModel.thinkingLevel.capitalized).tag(self.viewModel.thinkingLevel) } diff --git a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift index c760fad30d5..9a78bcd494b 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift @@ -180,8 +180,12 @@ public struct OpenClawChatView: View { } .onChange(of: self.viewModel.streamingAssistantText) { _, _ in guard self.hasPerformedInitialScroll, self.isPinnedToBottom else { return } - withAnimation(.snappy(duration: 0.22)) { - self.scrollPosition = self.scrollerBottomID + // Defer past the current layout pass to avoid "onChange tried to update + // multiple times per frame" warnings during rapid streaming token delivery. + Task { @MainActor in + withAnimation(.snappy(duration: 0.22)) { + self.scrollPosition = self.scrollerBottomID + } } } } From 3d7095f9ce0d7ef083ca43a21a64ebb7e1e1ebf4 Mon Sep 17 00:00:00 2001 From: Eulices Lopez <105620565+eulicesl@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:42:51 -0400 Subject: [PATCH 2/2] fix(ios): revalidate deferred streaming auto-scroll Follow up on PR review by re-checking the pin-to-bottom state inside the deferred streaming scroll task. This keeps queued tasks from yanking the list back down after the user scrolls away during token streaming.\n\nAlso rebase the branch onto current origin/main and validate with a simulator build. --- apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift index 9a78bcd494b..a6236e02cc1 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift @@ -183,6 +183,7 @@ public struct OpenClawChatView: View { // Defer past the current layout pass to avoid "onChange tried to update // multiple times per frame" warnings during rapid streaming token delivery. Task { @MainActor in + guard self.hasPerformedInitialScroll, self.isPinnedToBottom else { return } withAnimation(.snappy(duration: 0.22)) { self.scrollPosition = self.scrollerBottomID }