Skip to content

Commit 9ffe290

Browse files
authored
fix(chat): decode native thinking metadata
Decode gateway-provided thinking metadata for native iOS/macOS chat picker options, preserving extended and legacy thinking levels without leaking default-model options across sessions.\n\nVerification:\n- swift test --package-path apps/shared/OpenClawKit --filter ChatViewModelTests --no-parallel\n- swift test --package-path apps/macos --filter WebChatSwiftUISmokeTests --no-parallel\n- pnpm lint:swift\n- pnpm check:changed\n\nFollow-up maintainer fix for #40878 review feedback.
1 parent 62ccd8b commit 9ffe290

6 files changed

Lines changed: 525 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ Docs: https://docs.openclaw.ai
140140

141141
### Fixes
142142

143+
- Native chat: decode gateway-provided thinking metadata for the iOS/macOS picker so provider-specific levels such as `adaptive`, `xhigh`, and `max` appear without leaking unsupported default-model options. Thanks @BunsDev.
143144
- Agents/tools: fail `exec host=node` before `system.run` when the selected node is known to be disconnected, with an actionable reconnect message instead of a raw node invoke failure. Thanks @BunsDev.
144145
- Agents/models: accept legacy `anthropic-cli/*` model refs as Claude CLI runtime refs instead of failing model resolution with `Unknown model`. Thanks @BunsDev.
145146
- Agents/tools: keep restrictive-profile tool-section warnings scoped to the configured sections whose tools are still missing from `alsoAllow`, so already re-allowed filesystem tools do not make exec-only fixes look broader than they are. Thanks @BunsDev.

apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ struct MacGatewayChatTransport: OpenClawChatTransport {
6363
let mainSessionKey = await GatewayConnection.shared.cachedMainSessionKey()
6464
let defaults = decoded.defaults.map {
6565
OpenClawChatSessionsDefaults(
66+
modelProvider: $0.modelProvider,
6667
model: $0.model,
6768
contextTokens: $0.contextTokens,
69+
thinkingLevels: $0.thinkingLevels,
70+
thinkingOptions: $0.thinkingOptions,
71+
thinkingDefault: $0.thinkingDefault,
6872
mainSessionKey: mainSessionKey)
6973
} ?? OpenClawChatSessionsDefaults(
7074
model: nil,

apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import UniformTypeIdentifiers
99

1010
@MainActor
1111
struct OpenClawChatComposer: View {
12-
private static let menuThinkingLevels = ["off", "low", "medium", "high"]
13-
1412
@Bindable var viewModel: OpenClawChatViewModel
1513
let style: OpenClawChatView.Style
1614
let showsSessionSwitcher: Bool
@@ -95,12 +93,8 @@ struct OpenClawChatComposer: View {
9593
get: { self.viewModel.thinkingLevel },
9694
set: { next in self.viewModel.selectThinkingLevel(next) }))
9795
{
98-
Text("Off").tag("off")
99-
Text("Low").tag("low")
100-
Text("Medium").tag("medium")
101-
Text("High").tag("high")
102-
if !Self.menuThinkingLevels.contains(self.viewModel.thinkingLevel) {
103-
Text(self.viewModel.thinkingLevel.capitalized).tag(self.viewModel.thinkingLevel)
96+
ForEach(self.viewModel.thinkingLevelOptions) { option in
97+
Text(option.label).tag(option.id)
10498
}
10599
}
106100
.labelsHidden()

apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatSessions.swift

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import Foundation
22

3+
public struct OpenClawChatThinkingLevelOption: Codable, Identifiable, Sendable, Hashable {
4+
public let id: String
5+
public let label: String
6+
7+
public init(id: String, label: String) {
8+
self.id = id
9+
self.label = label
10+
}
11+
}
12+
313
public struct OpenClawChatModelChoice: Identifiable, Codable, Sendable, Hashable {
414
public var id: String {
515
self.selectionID
@@ -34,13 +44,29 @@ public struct OpenClawChatModelChoice: Identifiable, Codable, Sendable, Hashable
3444
}
3545

3646
public struct OpenClawChatSessionsDefaults: Codable, Sendable {
47+
public let modelProvider: String?
3748
public let model: String?
3849
public let contextTokens: Int?
50+
public let thinkingLevels: [OpenClawChatThinkingLevelOption]?
51+
public let thinkingOptions: [String]?
52+
public let thinkingDefault: String?
3953
public let mainSessionKey: String?
4054

41-
public init(model: String?, contextTokens: Int?, mainSessionKey: String? = nil) {
55+
public init(
56+
modelProvider: String? = nil,
57+
model: String?,
58+
contextTokens: Int?,
59+
thinkingLevels: [OpenClawChatThinkingLevelOption]? = nil,
60+
thinkingOptions: [String]? = nil,
61+
thinkingDefault: String? = nil,
62+
mainSessionKey: String? = nil)
63+
{
64+
self.modelProvider = modelProvider
4265
self.model = model
4366
self.contextTokens = contextTokens
67+
self.thinkingLevels = thinkingLevels
68+
self.thinkingOptions = thinkingOptions
69+
self.thinkingDefault = thinkingDefault
4470
self.mainSessionKey = mainSessionKey
4571
}
4672
}
@@ -72,6 +98,57 @@ public struct OpenClawChatSessionEntry: Codable, Identifiable, Sendable, Hashabl
7298
public let modelProvider: String?
7399
public let model: String?
74100
public let contextTokens: Int?
101+
public let thinkingLevels: [OpenClawChatThinkingLevelOption]?
102+
public let thinkingOptions: [String]?
103+
public let thinkingDefault: String?
104+
105+
public init(
106+
key: String,
107+
kind: String?,
108+
displayName: String?,
109+
surface: String?,
110+
subject: String?,
111+
room: String?,
112+
space: String?,
113+
updatedAt: Double?,
114+
sessionId: String?,
115+
systemSent: Bool?,
116+
abortedLastRun: Bool?,
117+
thinkingLevel: String?,
118+
verboseLevel: String?,
119+
inputTokens: Int?,
120+
outputTokens: Int?,
121+
totalTokens: Int?,
122+
modelProvider: String?,
123+
model: String?,
124+
contextTokens: Int?,
125+
thinkingLevels: [OpenClawChatThinkingLevelOption]? = nil,
126+
thinkingOptions: [String]? = nil,
127+
thinkingDefault: String? = nil)
128+
{
129+
self.key = key
130+
self.kind = kind
131+
self.displayName = displayName
132+
self.surface = surface
133+
self.subject = subject
134+
self.room = room
135+
self.space = space
136+
self.updatedAt = updatedAt
137+
self.sessionId = sessionId
138+
self.systemSent = systemSent
139+
self.abortedLastRun = abortedLastRun
140+
self.thinkingLevel = thinkingLevel
141+
self.verboseLevel = verboseLevel
142+
self.inputTokens = inputTokens
143+
self.outputTokens = outputTokens
144+
self.totalTokens = totalTokens
145+
self.modelProvider = modelProvider
146+
self.model = model
147+
self.contextTokens = contextTokens
148+
self.thinkingLevels = thinkingLevels
149+
self.thinkingOptions = thinkingOptions
150+
self.thinkingDefault = thinkingDefault
151+
}
75152
}
76153

77154
public struct OpenClawChatSessionsListResponse: Codable, Sendable {

0 commit comments

Comments
 (0)