feat(clients): adopt model controls, session management, and keyboard history recall on iOS#110831
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 19, 2026, 4:47 AM ET / 08:47 UTC. Summary PR surface: Other +1878. Total +1878 across 54 files. Reproducibility: not applicable. as a bug report; the two review defects are source-reproducible from the current head: external construction loses public visibility, and modified arrow keys enter the new recall handler. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Restore the public session DTO constructors, ignore modified Up/Down keys in the iOS recall handler, and add redacted simulator or device evidence covering the updated chat controls and session flow before merge. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug report; the two review defects are source-reproducible from the current head: external construction loses public visibility, and modified arrow keys enter the new recall handler. Is this the best way to solve the issue? No: adopting the shared iOS surfaces is directionally appropriate, but the patch must preserve the existing exported DTO contract and leave modified arrow-key editing to the native composer path. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 2e8b042f9fba. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +1878. Total +1878 across 54 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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
Review history (9 earlier review cycles; latest 8 shown)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e37cf4e0a4
ℹ️ 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".
| .sheet(isPresented: self.$showsSessions) { | ||
| NavigationStack { | ||
| CommandSessionsScreen( | ||
| usesNativeNavigationChrome: true, | ||
| openChat: { self.showsSessions = false }) | ||
| if let viewModel { | ||
| ChatSessionsSheet(viewModel: viewModel) | ||
| } |
There was a problem hiding this comment.
Keep fixture sessions on the capability-gated screen
When Apple Review or screenshot fixture mode is active, this replacement exposes rename, pin, archive, delete, fork, batch, and group actions even though LocalFixtureChatTransport does not implement those mutation/group methods and therefore falls through to the throwing defaults in apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatTransport.swift:675-723. The previous CommandSessionsScreen explicitly disabled these actions when isLocalChatFixtureEnabled, so fixture users now encounter “not supported” errors; retain that screen or pass equivalent capability gating into the shared sheet.
Useful? React with 👍 / 👎.
| Image(systemName: "slider.horizontal.3") | ||
| } | ||
| } | ||
| .disabled(self.viewModel == nil || !self.gatewayConnected || self.isAttachmentOwnerPinned) |
There was a problem hiding this comment.
Disable advanced session options for local fixtures
In Apple Review or screenshot fixture mode, gatewayConnected is true, so this button is enabled, but AppleReviewDemoChatTransport/LocalFixtureChatTransport do not implement listAgents() and inherit the protocol default returning nil (apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatTransport.swift:671). Consequently the newly exposed sheet can only report “No agents are available” and can never create a session; gate it with !appModel.isLocalChatFixtureEnabled or provide fixture agent support.
Useful? React with 👍 / 👎.
eb3bc75 to
72275cf
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72275cfbce
ℹ️ 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 let name: String | ||
| public let position: Int | ||
|
|
||
| public init(name: String, position: Int) { | ||
| self.name = name | ||
| self.position = position | ||
| } | ||
| } |
There was a problem hiding this comment.
Restore the public session-group initializers
Removing these explicit initializers makes Swift's synthesized memberwise initializers internal, even though OpenClawChatUI is exported as a library product. External/custom OpenClawChatTransport implementations can therefore no longer construct OpenClawChatSessionGroup, OpenClawChatSessionGroupsResponse, or OpenClawChatSessionGroupsMutationResponse after upgrading; the repo tests only continue compiling because they use @testable import. Retain public initializers for all three response types.
Useful? React with 👍 / 👎.
72275cf to
55554fe
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 55554fe9bf
ℹ️ 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".
| usesNativeNavigationChrome: true, | ||
| openChat: { self.showsSessions = false }) | ||
| if let viewModel { | ||
| ChatSessionsSheet(viewModel: viewModel) |
There was a problem hiding this comment.
Unify iOS session-group storage across entry points
When an iOS user manages groups from Chat, this replacement opens the shared sheet backed by gateway sessions.groups.*, while the still-reachable Sessions destination uses CommandSessionsScreen (apps/ios/Sources/RootTabs.swift:414-417) and reads/writes the device-local SessionGroupStore (apps/ios/Sources/Design/CommandCenterTab.swift:986-1013). Consequently renaming or deleting a group in the new sheet leaves a stale group in the other screen, groups created there do not reliably appear here, and existing empty local groups disappear from this entry point; migrate/synchronize the catalog or move all iOS entry points to the same implementation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8269ae3b58
ℹ️ 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".
| if let viewModel { | ||
| ChatModelControlsMenuItems(viewModel: viewModel) |
There was a problem hiding this comment.
Hide unsupported model controls in fixture mode
When Apple Review or screenshot fixture mode is active, this newly exposes thinking, Fast, and verbosity controls even though LocalFixtureChatTransport does not implement the full patchSessionSettings contract. Its inherited default throws when clearing the thinking override and silently ignores Fast/verbosity-only patches (ChatTransport.swift:809-840), so those selections either fail or appear accepted before reverting on refresh. Gate these controls with !appModel.isLocalChatFixtureEnabled or implement fixture settings patches.
Useful? React with 👍 / 👎.
… history recall on iOS
… shared dead-code intersect
…stead of suppressing
c1b9fdb to
41dbaca
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 41dbaca83a
ℹ️ 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".
| .onKeyPress(.upArrow) { | ||
| guard !self.isSlashPopoverPresented else { return .ignored } | ||
| return self.viewModel.recallPreviousInput(caretOnFirstLine: false) | ||
| ? .handled | ||
| : .ignored |
There was a problem hiding this comment.
Preserve modified arrow-key editing during recall
With a hardware keyboard after recall has started, Shift-Up or Option-Up reaches this key-only handler and recallPreviousInput returns true whenever history.isRecalling, so the event is consumed and the composer changes history entries instead of extending the selection or moving the caret. The macOS path explicitly filters modified arrows in ChatComposerKeyRouting.command, with coverage in ChatInputHistoryKeyContextTests; inspect KeyPress.modifiers here and return .ignored for modified arrows as well.
Useful? React with 👍 / 👎.
|
Merged via squash.
|
… history recall on iOS (openclaw#110831) * feat(clients): adopt model controls, session management, and keyboard history recall on iOS * chore(i18n): translate iOS adoption strings and realign locale artifacts * refactor(clients): drop test-only group response inits flagged by the shared dead-code intersect * chore: retrigger ci * chore(i18n): resync inventory after voice-unification main rebase * chore(i18n): resync inventory after main rebase * chore(i18n): resync inventory after main rebase * chore(i18n): realign locale artifacts after main rebase * fix(clients): preserve native chat API and locale copy * fix(ios): retain public session DTO initializers * refactor(clients): delete test-only session DTO inits flagged dead instead of suppressing
What Problem This Solves
The macOS/web chat parity rounds (#110254, #110276, #110339, #110347) landed all capability in shared
OpenClawKit, but iOS still only forwarded transport fields: no model controls, no session groups/batch/inspector, no worktree-aware creation, and no hardware-keyboard input history.Why This Change Was Made
Adopt the shared surfaces on iOS with iOS-idiomatic UX, keeping the shared API additive:
ChatModelControlsMenu.swift, wired from ChatPro's existing action menu): provider-grouped model picker via the sharedChatModelPickerStore(pinned + recents first, default badges), thinking withDefault (inherited), Fast as Default/On/Off (Default patchesfastMode: null; display rideseffectiveFastMode; legacyautonot re-selectable), verbosity as Default/off/on/full (Default patches null).ChatSessionsSheet(groups, select/batch mode, inspector); advanced new-session options (agent, managed worktree, base ref) present in a medium-detent sheet.IOSGatewayChatTransport.swift): exact-route leases for settings, mutations, groups, and new-session; 6-argcreateSessionmappingagentId/worktree/worktreeBaseRef; settings patches forward the fast-mode double-optional including explicit null. Implementing the real overload removes iOS from the fail-closed protocol default.ChatInputHistorystate machine).User Impact
iOS chat users get the same model, Fast, verbosity, and thinking controls as web/macOS, full session organization (groups, batch actions, inspector, worktree sessions from a chosen base ref), and terminal-style input history on hardware keyboards.
Evidence
build-for-testing(generic simulator, Xcode project via xcodegen): green — app and test targets compile.IOSGatewayChatTransportTests: 15/15, including advanced-create encoding, fast-mode set/null, and groups-lease methods/params/decoding.pnpm format:swiftclean;pnpm lint:swift0 violations; all touched files under the 1500-line cap;git diff --checkclean.pnpm native:i18n:checkclean; apple/android i18n vitest gates green.OpenClawTypographyTestsbroad source audit flags pre-existing lines in untouched shared/macOS files; CI'sios-buildjob compiles but does not execute the iOS test bundle, and the new controls use branded typography.