Skip to content

feat(clients): provider-grouped model picker with fast, verbosity, and inherited-thinking controls#110339

Merged
steipete merged 8 commits into
mainfrom
claude/macos-chat-model-controls
Jul 18, 2026
Merged

feat(clients): provider-grouped model picker with fast, verbosity, and inherited-thinking controls#110339
steipete merged 8 commits into
mainfrom
claude/macos-chat-model-controls

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

The native macOS chat's model picker is a flat list with no provider context, and it exposes none of the web chat's per-session model controls: Fast mode, verbosity, or an explicit "inherit default" thinking choice. Round 3a of the macOS/web parity effort (follow-up to #109712, #109995, #110019).

Why This Change Was Made

Continue converging the native macOS chat on web-chat capability using shared OpenClawKit code so iOS benefits from the same surfaces later.

  • Provider-grouped model picker: pinned + recent entries stay first, remaining models group by provider with the default provider ordered first; provider branding and default-model badges (ChatModelPickerStore.swift, ChatComposer.swift, ChatWindowShell.swift).
  • Fast mode toggle, verbosity control (off/on/full), and an explicit Default (inherited) thinking option with optimistic patches, per-target serialization, and target-aware rollback (ChatViewModel+ModelControls.swift, ChatViewModel+Thinking.swift).
  • Transport encodes the canonical sessions.patch fields: thinkingLevel (null = reset), fastMode (true/false/"auto"/null), verboseLevel ("off"/"on"/"full"/null) — verified against packages/gateway-protocol/src/schema/sessions.ts and src/gateway/sessions-patch.ts.
  • Docs: docs/platforms/mac/webchat.md; i18n catalogs regenerated and translated.

User Impact

macOS chat users can pick models grouped by provider and adjust Fast mode, verbosity, and thinking inheritance per session from the composer, matching the web chat. Shared implementation keeps iOS ready to adopt the same controls.

Evidence

  • Shared OpenClawKit full suite: 906/906 (81 suites); focused view-model suite 221/221; picker suite 10/10.
  • macOS release build green; relevant macOS transport/UI tests 17/17; post-rebase verification: OpenClawChatUI build + release build + 309 shared tests green.
  • pnpm format:swift clean, pnpm lint:swift 0 violations, pnpm native:i18n:check changed=false, apple/android i18n vitest gates green.
  • Schema proof for patch fields: packages/gateway-protocol/src/schema/sessions.ts:373, src/gateway/sessions-patch.ts:452, src/gateway/sessions-patch.test.ts:501.
  • Autoreview (branch mode): no accepted/actionable findings remaining.

Review-driven hardening (post-spec)

  • Fast and verbosity controls gained a Default (inherited) selection that patches explicit null, matching web's clear-override contract (ui/src/pages/chat/chat-session.ts switchChatFastMode); legacy "auto" overrides display via effective state and are not re-selectable, mirroring web.
  • Thinking-success snapshots now merge fast/verbosity last-success state so a sparse thinking patch can no longer erase them before a stale sessions.list restore.
  • Inherited verbosity persists: clearing the override removes openclaw.webchat.verboseLevel via the additive onVerbosePreferenceChanged callback (macOS consumer coordinated).
  • Final validation: 957 Swift tests green (48 XCTest + 909 Swift Testing), macOS release build green, branch autoreview clean ("patch is correct", zero findings).

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: android App: android app: ios App: ios app: macos App: macos size: XL maintainer Maintainer-authored PR labels Jul 18, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3cf0dea40c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


/// `models.list` currently has no fast-support capability field. Keep the
/// control available and let the gateway validate the session patch.
public var selectedModelSupportsFastMode: Bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Hide fast mode where the provider cannot honor it

For any selected model whose provider has no fast-mode runtime mapping (for example Google/Gemini or local providers), this always renders the Fast control and lets the user persist a fastMode override. I checked the web control and it explicitly limits the toggle to providers with wire support (ui/src/lib/chat/model-select-state.ts:70-74), while sessions.patch only validates the value shape and stores it without provider capability checks (src/gateway/sessions-patch.ts:452-462). This makes the native picker advertise a setting that can be a no-op for unsupported providers, so please gate it from the model/provider metadata or add a real gateway capability/validation before showing it.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added the P2 Normal backlog priority with limited blast radius. label Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 18, 2026, 12:47 AM ET / 04:47 UTC.

Summary
The branch adds provider-grouped native model selection plus per-session Fast, verbosity, and inherited-thinking controls across shared Swift chat UI, macOS transport, localization, tests, and macOS documentation.

PR surface: Docs 0, Other +4188. Total +4188 across 44 files.

Reproducibility: yes. from source: select a model whose provider has no Fast runtime mapping, then open the native control; the changed capability predicate always returns true and exposes a setting the gateway can store without provider validation.

Review metrics: 1 noteworthy metric.

  • Persisted session-control surfaces: 3 controls changed; 1 local preference added. Fast, verbosity, and inherited-thinking changes use optimistic session patches, while verbosity also persists a macOS UserDefaults preference, so upgrade and stale-state behavior need direct proof.

Stored data model
Persistent data-model change detected: serialized state: apps/macos/Tests/OpenClawIPCTests/WebChatSwiftUISmokeTests.swift. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Gate Fast mode to providers that can honor it and add focused supported/unsupported-provider coverage.
  • Attach redacted native screenshots or a short recording showing provider grouping, Fast behavior, inherited thinking, and verbosity reset; updating the PR body should trigger a fresh review, or a maintainer can comment @clawsweeper re-review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR reports tests and builds but provides no inspectable after-fix native recording, screenshots, logs, or live output; add redacted evidence for provider grouping and supported/unsupported Fast plus inherited-reset behavior before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging as written lets macOS users select and persist a Fast override for unsupported providers, producing a visible setting that may be a no-op because the gateway accepts the field without provider-capability enforcement.
  • [P1] The PR updates optimistic per-session settings and persisted verbosity preference; native interaction proof should cover an override, inherited reset, unsupported-provider selection, and a reopen/refresh cycle before merge.

Maintainer options:

  1. Gate Fast mode by capability (recommended)
    Reuse the web-supported provider rule or expose a gateway-backed capability so unsupported models cannot show or persist the Fast control.
  2. Accept the all-provider control
    Land the current behavior only if maintainers intentionally want Fast overrides to be writable for providers that may ignore them.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Gate the native Fast control to providers that can honor it, add focused coverage for supported and unsupported provider selection, and preserve inherited session state.

Next step before merge

  • [P1] The protected maintainer label and required contributor-owned real behavior proof keep this PR on a human review path; no automated repair should be queued.

Security
Cleared: The reviewed diff is native UI, transport serialization, localization, tests, and documentation; it introduces no concrete dependency, workflow, permission, secret, or supply-chain concern.

Review findings

  • [P2] Gate Fast mode to supported providers — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatViewModel+ModelControls.swift:27-28
Review details

Best possible solution:

Use the existing web Fast-support rule through a shared capability contract or a native-equivalent provider gate, then attach redacted native evidence showing provider grouping plus supported and unsupported Fast, inherited thinking, and verbosity-reset behavior.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: select a model whose provider has no Fast runtime mapping, then open the native control; the changed capability predicate always returns true and exposes a setting the gateway can store without provider validation.

Is this the best way to solve the issue?

No: provider grouping and inherited controls are a reasonable parity direction, but the unconditional Fast predicate is not the best implementation because web already limits Fast to supported providers.

Full review comments:

  • [P2] Gate Fast mode to supported providers — apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatViewModel+ModelControls.swift:27-28
    selectedModelSupportsFastMode always returns true, so models whose providers have no Fast runtime mapping still show a control that writes a fastMode override. Web chat already limits this surface to supported providers, while the gateway accepts the field shape without enforcing provider support; reuse that rule or expose an explicit capability before showing the toggle.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.96

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 4e0cc187a21c.

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: This is a bounded native-client feature with a concrete user-visible behavior defect rather than an urgent runtime outage.
  • merge-risk: 🚨 compatibility: Fast is displayed for providers without runtime support, creating a conflicting or no-op control relative to existing web behavior.
  • merge-risk: 🚨 session-state: The change modifies optimistic per-session patching, inherited-reset semantics, and persisted verbosity preference state.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR reports tests and builds but provides no inspectable after-fix native recording, screenshots, logs, or live output; add redacted evidence for provider grouping and supported/unsupported Fast plus inherited-reset behavior before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Docs 0, Other +4188. Total +4188 across 44 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 1 2 2 0
Config 0 0 0 0
Generated 0 0 0 0
Other 43 4931 743 +4188
Total 44 4933 745 +4188

What I checked:

Likely related people:

  • steipete: Authored the current PR and the prior merged native macOS chat-parity series that this PR explicitly follows, including the broad shared-chat integration. (role: recent area contributor; confidence: high; commits: bf754b8a344a, 4f93f516479c; files: apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatViewModel+ModelControls.swift, apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatComposer.swift, apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (3 earlier review cycles)
  • reviewed 2026-07-18T02:52:59.232Z sha 3cf0dea :: needs real behavior proof before merge. :: [P2] Gate Fast mode to providers that support it
  • reviewed 2026-07-18T03:39:48.195Z sha feedbff :: needs real behavior proof before merge. :: [P2] Gate Fast mode to providers that can honor it
  • reviewed 2026-07-18T04:04:49.701Z sha 4f93f51 :: needs real behavior proof before merge. :: [P2] Gate Fast mode to supported providers | [P2] Preserve inherited thinking through model-only patches

@steipete
steipete force-pushed the claude/macos-chat-model-controls branch from 3cf0dea to ea61ff3 Compare July 18, 2026 03:15

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea61ff3f3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +176 to +180
let acceptedOverride = next == nil ? nil : (result?.fastMode ?? next)
let acceptedEffective = result?.effectiveFastMode
?? result?.fastMode
?? acceptedOverride
?? baselineEffectiveFastMode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't reuse stale effective fast state on default clear

When the user changes Fast from an explicit override back to Default (inherited), the live sessions.patch response does not include a resolved effectiveFastMode for this fast-only patch (the gateway response only adds resolved model/thinking metadata in src/gateway/server-methods/sessions-mutations.ts:297-307, and the stored entry has no effective field). In that scenario these fallbacks all become nil until baselineEffectiveFastMode, so an explicit On→Default clear keeps rendering Fast even when the inherited/default config is off (or Off→Default keeps rendering Standard when the inherited default is fast) until a later session-list refresh happens to correct it. Please force/reuse an authoritative session-list projection for clears instead of writing the previous effective state back as accepted.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: feedbff828

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


public var thinkingOverrideIsInherited: Bool {
if self.hasAppliedLiveSessions {
return self.currentSessionEntry()?.thinkingLevel == nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep inherited thinking after model-only patches

When a session is inheriting its thinking level and the user changes only the model, the gateway returns resolved.thinkingLevel as the effective default for the new model (src/gateway/server-methods/sessions-mutations.ts:297-307), and the model-selection path writes that patchResult.thinkingLevel back into the local session row (apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatViewModel.swift:1616-1624). This new inherited check then treats the row as an explicit override because it only tests for nil, so the picker flips from Default (inherited) to <level> (override) even though no thinking override was persisted; preserve override-vs-effective state instead of deriving inheritance from the merged resolved value.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 18, 2026
@steipete
steipete merged commit 8ae1581 into main Jul 18, 2026
118 of 122 checks passed
@steipete
steipete deleted the claude/macos-chat-model-controls branch July 18, 2026 06:01
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 18, 2026
…d inherited-thinking controls (openclaw#110339)

* feat(clients): provider-grouped model picker with fast, verbosity, and inherited-thinking controls

* chore(i18n): translate model-control strings and regenerate platform catalogs

* feat(clients): inherited-default restore for fast mode and verbosity controls

* fix(clients): preserve control state in thinking snapshots and persist inherited verbosity

* chore(i18n): resync native inventory after rebase onto message-reader main

* chore(i18n): realign locale artifacts after rebase onto message-reader main

* refactor(clients): drop superseded fast-mode accessors and picker convenience flagged by periphery

* chore(i18n): resync inventory line refs after dead-code removal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: android App: android app: ios App: ios app: macos App: macos docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant