Skip to content

Commit 6f71621

Browse files
committed
feat(ios): hide thinking-level control for models without reasoning support
1 parent 3442a8e commit 6f71621

11 files changed

Lines changed: 670 additions & 60 deletions

File tree

apps/.i18n/native-source.json

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21155,191 +21155,191 @@
2115521155
},
2115621156
{
2115721157
"kind": "ui-call",
21158-
"line": 195,
21158+
"line": 197,
2115921159
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2116021160
"source": "Thinking",
2116121161
"surface": "apple",
2116221162
"id": "native.apple.510c6dfa05924ae2"
2116321163
},
2116421164
{
2116521165
"kind": "ui-call",
21166-
"line": 216,
21166+
"line": 218,
2116721167
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2116821168
"source": "Model",
2116921169
"surface": "apple",
2117021170
"id": "native.apple.0fce9d743a640218"
2117121171
},
2117221172
{
2117321173
"kind": "ui-call",
21174-
"line": 233,
21174+
"line": 235,
2117521175
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2117621176
"source": "Pinned",
2117721177
"surface": "apple",
2117821178
"id": "native.apple.745b004e0b5b6b80"
2117921179
},
2118021180
{
2118121181
"kind": "ui-call",
21182-
"line": 241,
21182+
"line": 243,
2118321183
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2118421184
"source": "Recent",
2118521185
"surface": "apple",
2118621186
"id": "native.apple.69381a0a462ccd84"
2118721187
},
2118821188
{
2118921189
"kind": "ui-call",
21190-
"line": 249,
21190+
"line": 251,
2119121191
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2119221192
"source": "Models",
2119321193
"surface": "apple",
2119421194
"id": "native.apple.aa321cf4820426ef"
2119521195
},
2119621196
{
2119721197
"kind": "conditional-branch",
21198-
"line": 278,
21198+
"line": 280,
2119921199
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2120021200
"source": "Pin model",
2120121201
"surface": "apple",
2120221202
"id": "native.apple.75550b03f06d6abc"
2120321203
},
2120421204
{
2120521205
"kind": "conditional-branch",
21206-
"line": 278,
21206+
"line": 280,
2120721207
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2120821208
"source": "Unpin model",
2120921209
"surface": "apple",
2121021210
"id": "native.apple.af4df27bdbacb5de"
2121121211
},
2121221212
{
2121321213
"kind": "ui-call",
21214-
"line": 282,
21214+
"line": 284,
2121521215
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2121621216
"source": "Session",
2121721217
"surface": "apple",
2121821218
"id": "native.apple.5dfc0700d8dff8de"
2121921219
},
2122021220
{
2122121221
"kind": "ui-modifier",
21222-
"line": 346,
21222+
"line": 348,
2122321223
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2122421224
"source": "Add Image",
2122521225
"surface": "apple",
2122621226
"id": "native.apple.284b2b94c272591d"
2122721227
},
2122821228
{
2122921229
"kind": "ui-modifier",
21230-
"line": 347,
21230+
"line": 349,
2123121231
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2123221232
"source": "Attachments",
2123321233
"surface": "apple",
2123421234
"id": "native.apple.1963dfa3285cb715"
2123521235
},
2123621236
{
2123721237
"kind": "conditional-branch",
21238-
"line": 517,
21238+
"line": 519,
2123921239
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2124021240
"source": "Talk",
2124121241
"surface": "apple",
2124221242
"id": "native.apple.ee2c0d22f5861159"
2124321243
},
2124421244
{
2124521245
"kind": "conditional-branch",
21246-
"line": 563,
21246+
"line": 565,
2124721247
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2124821248
"source": "Start realtime chat",
2124921249
"surface": "apple",
2125021250
"id": "native.apple.5d5041aefe6dfddd"
2125121251
},
2125221252
{
2125321253
"kind": "conditional-branch",
21254-
"line": 563,
21254+
"line": 565,
2125521255
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2125621256
"source": "Stop realtime chat",
2125721257
"surface": "apple",
2125821258
"id": "native.apple.21a7d3a3386a2218"
2125921259
},
2126021260
{
2126121261
"kind": "conditional-branch",
21262-
"line": 596,
21262+
"line": 598,
2126321263
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2126421264
"source": "Start",
2126521265
"surface": "apple",
2126621266
"id": "native.apple.88c2de261ddae511"
2126721267
},
2126821268
{
2126921269
"kind": "conditional-branch",
21270-
"line": 596,
21270+
"line": 598,
2127121271
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2127221272
"source": "Stop",
2127321273
"surface": "apple",
2127421274
"id": "native.apple.72e5aa4446eaca9e"
2127521275
},
2127621276
{
2127721277
"kind": "ui-call",
21278-
"line": 706,
21278+
"line": 708,
2127921279
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2128021280
"source": "Loading commands",
2128121281
"surface": "apple",
2128221282
"id": "native.apple.9d4bdedcbf74d86c"
2128321283
},
2128421284
{
2128521285
"kind": "ui-call",
21286-
"line": 715,
21286+
"line": 717,
2128721287
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2128821288
"source": "Commands unavailable",
2128921289
"surface": "apple",
2129021290
"id": "native.apple.fdd34aa94629c962"
2129121291
},
2129221292
{
2129321293
"kind": "ui-call",
21294-
"line": 724,
21294+
"line": 726,
2129521295
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2129621296
"source": "Retry",
2129721297
"surface": "apple",
2129821298
"id": "native.apple.a1953e3e9be8b8d5"
2129921299
},
2130021300
{
2130121301
"kind": "ui-call",
21302-
"line": 733,
21302+
"line": 735,
2130321303
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2130421304
"source": "No matching commands",
2130521305
"surface": "apple",
2130621306
"id": "native.apple.0f942ca442f88936"
2130721307
},
2130821308
{
2130921309
"kind": "ui-modifier",
21310-
"line": 865,
21310+
"line": 867,
2131121311
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2131221312
"source": "Stop response",
2131321313
"surface": "apple",
2131421314
"id": "native.apple.afd8a2b9e3bf6d60"
2131521315
},
2131621316
{
2131721317
"kind": "ui-modifier",
21318-
"line": 890,
21318+
"line": 892,
2131921319
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2132021320
"source": "Send message",
2132121321
"surface": "apple",
2132221322
"id": "native.apple.d30969d467c66537"
2132321323
},
2132421324
{
2132521325
"kind": "ui-modifier",
21326-
"line": 905,
21326+
"line": 907,
2132721327
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2132821328
"source": "Refresh",
2132921329
"surface": "apple",
2133021330
"id": "native.apple.f4473f79bb87b2fd"
2133121331
},
2133221332
{
2133321333
"kind": "conditional-branch",
21334-
"line": 1013,
21334+
"line": 1015,
2133521335
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2133621336
"source": "Connecting...",
2133721337
"surface": "apple",
2133821338
"id": "native.apple.6c984c0e3ed3a69e"
2133921339
},
2134021340
{
2134121341
"kind": "conditional-branch",
21342-
"line": 1013,
21342+
"line": 1015,
2134321343
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift",
2134421344
"source": "Gateway connected",
2134521345
"surface": "apple",

apps/ios/Sources/Chat/IOSGatewayChatTransport.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct IOSGatewayChatTransport: OpenClawChatTransport {
8080
var name: String
8181
var provider: String
8282
var contextWindow: Int?
83+
var reasoning: Bool?
8384
}
8485
}
8586

@@ -224,7 +225,8 @@ struct IOSGatewayChatTransport: OpenClawChatTransport {
224225
modelID: model.id,
225226
name: name.isEmpty ? model.id : model.name,
226227
provider: model.provider,
227-
contextWindow: model.contextWindow)
228+
contextWindow: model.contextWindow,
229+
reasoning: model.reasoning)
228230
}
229231
}
230232

apps/ios/Tests/IOSGatewayChatTransportTests.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,27 @@ struct IOSGatewayChatTransportTests {
111111
#expect(params["model"] is NSNull)
112112
}
113113

114-
@Test func `models list response decodes choices and falls back blank names`() throws {
114+
@Test func `models list response decodes choices reasoning and blank names`() throws {
115115
let data = Data(
116-
#"{"models":[{"id":"claude-opus-4","name":"Claude Opus 4","provider":"anthropic","contextWindow":200000,"reasoning":true},{"id":"gpt-5","name":" ","provider":"openai","extra":"ignored"}]}"#.utf8)
116+
#"""
117+
{"models":[
118+
{"id":"claude-opus-4","name":"Claude Opus 4","provider":"anthropic","contextWindow":200000,"reasoning":true},
119+
{"id":"gpt-5","name":" ","provider":"openai","extra":"ignored"}
120+
]}
121+
"""#.utf8)
117122
let choices = try IOSGatewayChatTransport.decodeModelChoices(data)
118123

119124
#expect(choices.count == 2)
120125
#expect(choices[0].modelID == "claude-opus-4")
121126
#expect(choices[0].name == "Claude Opus 4")
122127
#expect(choices[0].provider == "anthropic")
123128
#expect(choices[0].contextWindow == 200_000)
129+
#expect(choices[0].reasoning == true)
124130
#expect(choices[1].modelID == "gpt-5")
125131
#expect(choices[1].name == "gpt-5")
126132
#expect(choices[1].provider == "openai")
127133
#expect(choices[1].contextWindow == nil)
134+
#expect(choices[1].reasoning == nil)
128135
}
129136

130137
@Test func `commands list params request text scope with args`() throws {

apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ struct MacGatewayChatTransport: OpenClawChatTransport {
232232
modelID: model.id,
233233
name: model.name,
234234
provider: model.provider,
235-
contextWindow: model.contextwindow)
235+
contextWindow: model.contextwindow,
236+
reasoning: model.reasoning)
236237
}
237238
}
238239

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ struct OpenClawChatComposer: View {
170170
HStack(spacing: 5) {
171171
if self.showsSessionSwitcher {
172172
self.sessionPicker
173-
self.thinkingPicker
173+
if self.viewModel.showsThinkingPicker {
174+
self.thinkingPicker
175+
}
174176
}
175177
if self.viewModel.showsModelPicker {
176178
self.modelPicker

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@ public struct OpenClawChatModelChoice: Identifiable, Codable, Sendable, Hashable
1919
public let name: String
2020
public let provider: String
2121
public let contextWindow: Int?
22+
public let reasoning: Bool?
2223

23-
public init(modelID: String, name: String, provider: String, contextWindow: Int?) {
24+
public init(
25+
modelID: String,
26+
name: String,
27+
provider: String,
28+
contextWindow: Int?,
29+
reasoning: Bool? = nil)
30+
{
2431
self.modelID = modelID
2532
self.name = name
2633
self.provider = provider
2734
self.contextWindow = contextWindow
35+
self.reasoning = reasoning
2836
}
2937

3038
/// Provider-qualified model ref used for picker identity and selection tags.

apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatViewModel+Outbox.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ extension OpenClawChatViewModel {
6969
id: UUID().uuidString,
7070
sessionKey: session.key,
7171
text: text,
72-
thinking: self.thinkingLevel,
72+
thinking: self.effectiveThinkingLevelForSend,
7373
createdAt: Date().timeIntervalSince1970,
7474
status: .queued,
7575
retryCount: 0,
@@ -311,9 +311,11 @@ extension OpenClawChatViewModel {
311311
let response = try await self.transport.sendMessage(
312312
sessionKey: next.sessionKey,
313313
message: next.text,
314-
// Thinking level captured at enqueue time, never the
315-
// visible session's current setting.
316-
thinking: next.thinking,
314+
// Preserve the queued level when supported, but never send
315+
// an explicit unsupported level after the gate changes.
316+
thinking: self.effectiveThinkingLevelForSend(
317+
next.thinking,
318+
sessionKey: next.sessionKey),
317319
idempotencyKey: next.id,
318320
attachments: [])
319321
if response.status == "error" || response.status == "timeout" {

0 commit comments

Comments
 (0)