Skip to content

feat(mobile): one sheet for model and thread settings - #5625

Merged
t3dotgg merged 10 commits into
mainfrom
t3code/mobile-model-picker-flows
Aug 8, 2026
Merged

feat(mobile): one sheet for model and thread settings#5625
t3dotgg merged 10 commits into
mainfrom
t3code/mobile-model-picker-flows

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Aug 7, 2026

Copy link
Copy Markdown
Member

Changing the model on mobile meant drilling through nested native context menus: provider submenu, then model, with effort and runtime hiding in a second menu. No search, no overview, and every provider doubled its menu length with a "legacy models" submenu.

Now the composer has one pill that shows the whole thread setup ("Claude Fable 5 · Max · 1M · Auto") and opens a single bottom sheet:

  • Model list grouped by provider with harness logos. Claude and Codex stay expanded; other providers (OpenCode's 438-model OpenRouter catalog...) fold behind their header with a count. Legacy models hide behind a pill and get a badge when shown.
  • Model changes stage until an explicit Save; re-tapping the applied model cancels. While staged, the settings rows edit the staged model's options and Save applies everything in one write.
  • Reasoning, context window, and runtime each live behind a compact disclosure row whose submenu stacks in a small panel over the sheet, so the sheet never changes size. Ultracode/ultrathink pseudo-efforts aren't offered on mobile.
  • Existing threads only list their own harness's models; picking a harness happens on the new-task draft, which shares the same sheet.
  • Plan mode has no toggle here: threads build by default (the /plan command path is unchanged).
Light Staged model Submenu Dark Dark submenu
light staged submenu dark dark submenu

Verified end to end on the iOS Simulator and on-device: model staging and save (with staged option edits carried through), folds, legacy pill, submenu apply, runtime changes, summary pill updates, light and dark.

Built by Claude Fable 5 running in Claude Code.

Note

Consolidate model and thread settings into a single sheet in the mobile composer

  • Replaces separate Model and Options menu pills in NewTaskDraftScreen and ThreadComposer with a single 'Thread settings' toolbar trigger that opens a unified ThreadSettingsSheet modal.
  • The sheet groups models by provider with collapsible sections, hides legacy models by default, and stages model + option changes together until Save is tapped.
  • A new threadSettingsSummaryLabel utility composes a compact summary string (model, options, runtime mode) displayed on the trigger pill.
  • useThreadSettingsSheetPresentation coordinates keyboard dismissal on open and restores editor focus only when the sheet is closed via Save, not on dismiss.
  • resolveDefaultableModelSelection prevents implicit defaults from resolving to legacy models; applyProviderOptionSelection replaces menu-event-string parsing with typed, validated selection updates.

Macroscope summarized a056b34.


Note

Medium Risk
Touches core composer model/runtime selection and draft default resolution; staging and keyboard/focus timing add UX edge cases but changes are localized to mobile thread UI.

Overview
Replaces nested native model/configuration menus in the new-task draft and thread composer with one toolbar pill (summary like Model · Max · Auto) that opens a ThreadSettingsSheet modal.

The sheet adds a scrollable, provider-grouped model list (primary harnesses expanded, large catalogs foldable, legacy behind a toggle), staged model picks applied on Save/Done, and disclosure submenus for provider options and runtime. Open threads only see models from their current harness; new tasks still get all providers. Plan/interaction mode is no longer in the sheet—only reflected in the summary when already in plan mode (/plan unchanged).

Presentation plumbing: useThreadSettingsSheetPresentation dismisses the custom composer keyboard before showing the modal, keeps Android/iOS composer expanded while the sheet is open, and restores focus only after Save, not backdrop dismiss.

Selection defaults: resolveDefaultableModelSelection stops implicit project last-used defaults from landing on legacy models; draft picks stay explicit. setSelectedModelKey can apply model + options in one write when saving a staged change.

Cleanup: Removes buildModelMenuActions and menu-event provider option helpers in favor of direct selection APIs and tests for staging behavior.

Reviewed by Cursor Bugbot for commit a056b34. Bugbot is set up for automated code reviews on this repo. Configure here.

Replaces the two nested native context menus in the composer with a single
trigger pill and one bottom sheet: provider-grouped model list (logos, folds
for non-primary providers, legacy behind a toggle), the selected model's
options, runtime mode, and plan mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8055d93-3818-45f5-b9b2-de6bf7f506e2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 7, 2026
Comment thread apps/mobile/src/features/threads/ThreadSettingsSheet.tsx
Formatting fixes plus a scrollable pinned-settings region so a model with
many option descriptors can't push runtime/plan controls past the sheet's
max height.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 11.4 KiB 11.3 KiB −23 B (−0.2%) 15.1 KiB
Codex Thread snapshot wire 5.5 KiB 5.5 KiB −9 B (−0.2%) 7.3 KiB
Codex Live turn WebSocket wire 5.9 KiB 5.9 KiB −14 B (−0.2%) 7.8 KiB
Codex Live turn WebSocket decoded 49.7 KiB 49.7 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 16 16 0 (0.0%) 21
Claude Total thread wire 11.3 KiB 11.3 KiB −15 B (−0.1%) 15.1 KiB
Claude Thread snapshot wire 5.5 KiB 5.5 KiB −3 B (−0.1%) 7.3 KiB
Claude Live turn WebSocket wire 5.9 KiB 5.8 KiB −12 B (−0.2%) 7.8 KiB
Claude Live turn WebSocket decoded 50.6 KiB 50.6 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 16 16 0 (0.0%) 21

Baseline: 5661c61 · PR result: a056b34 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 94.6 KiB
  • Claude decoded thread snapshot: 95.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Comment thread apps/mobile/src/features/threads/ThreadComposer.tsx Outdated
Comment thread apps/mobile/src/features/threads/ThreadSettingsSheet.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new settings sheet component with substantial new UI logic (~800+ lines), complex keyboard/focus coordination, and staged state management. The scope of new feature code warrants human review. Additionally, there is an unresolved finding about missing error handling for keyboard dismissal that could leave the sheet stuck.

You can customize Macroscope's approvability policy. Learn more.

Legacy models reset to hidden on every open behind a top-right
show/hide pill, and the plan mode toggle is gone: threads build by
default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
Comment thread apps/mobile/src/features/threads/ThreadComposer.tsx
Blur-during-settings-sheet told the parent the composer collapsed while
it still rendered expanded, shrinking the feed inset underneath.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 8, 2026
The sheet is now just the model list with a Save button: reasoning,
context window, and runtime each fold behind a compact disclosure row
that opens an in-sheet submenu. Ultracode/ultrathink pseudo-efforts are
no longer offered on mobile, and existing threads only list their own
harness's models.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@macroscopeapp
macroscopeapp Bot dismissed their stale review August 8, 2026 00:16

Dismissing prior approval to re-evaluate 0c9236e

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 8, 2026
Comment thread apps/mobile/src/features/threads/ThreadSettingsSheet.tsx Outdated
t3dotgg and others added 2 commits August 7, 2026 17:20
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… staging

Submenus open in a small panel on top of the sheet instead of replacing
its content, so the sheet stops resizing while drilling in and out. The
settings rows now stay editable while a model is staged: they show the
staged model's options and Save applies model plus options in one write
(the draft flow previously clobbered a staged model when options followed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/mobile/src/features/threads/ThreadSettingsSheet.tsx
Legacy models never force-show (a selected legacy model is exempted from
the filter individually), the keyboard only returns after the sheet if it
was up beforehand, settings rows render as a stable union across primary
harnesses with unsupported rows disabled instead of vanishing, and a
project's implicit last-used default never resolves to a legacy model
(explicit picks still stick).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
Any dismissal of the thread settings sheet (backdrop, grabber, or a tap
that lands just outside a control like the legacy pill) closed the sheet
and refocused the composer, popping the keyboard unexpectedly. Dismissals
now close quietly; only the explicit Save/Done button brings the keyboard
back. The legacy pill also gets hitSlop so near-misses land on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a056b34. Configure here.

return;
}
setPhase("visible");
});

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.

Sheet stuck after dismiss failure

High Severity

open only moves to visible inside KeyboardController.dismiss().then, with no rejection path. Elsewhere in mobile (ThreadDetailScreen) dismiss failures are handled with .catch. If dismiss rejects here, phase stays opening, isActiveRef stays true, the modal never appears, and later open calls no-op, so thread settings stay unavailable and the composer can remain expanded until remount.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a056b34. Configure here.

@t3dotgg
t3dotgg merged commit 30164cb into main Aug 8, 2026
17 checks passed
@t3dotgg
t3dotgg deleted the t3code/mobile-model-picker-flows branch August 8, 2026 10:51
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Aug 8, 2026
## What's Changed
* fix(desktop): zoom shortcuts no longer die when the preview browser has focus by @t3dotgg in pingdotgg/t3code#5691
* feat(mobile): one sheet for model and thread settings by @t3dotgg in pingdotgg/t3code#5625
* feat(usage): usage page reading provider transcripts across environments by @t3dotgg in pingdotgg/t3code#5684


**Full Changelog**: pingdotgg/t3code@v0.0.33-nightly.20260808.1031...v0.0.33-nightly.20260808.1033

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.33-nightly.20260808.1033
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Aug 8, 2026
…224)

* fix(desktop): zoom shortcuts no longer die when the preview browser has focus (pingdotgg#5691)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* feat(mobile): one sheet for model and thread settings (pingdotgg#5625)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* feat(usage): usage page reading provider transcripts across environments (pingdotgg#5684)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(desktop): zoom shortcuts no longer die when the preview browser has focus (pingdotgg#5691)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* feat(mobile): one sheet for model and thread settings (pingdotgg#5625)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* feat(usage): usage page reading provider transcripts across environments (pingdotgg#5684)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com>
omegent-app Bot added a commit to patroza/t3code that referenced this pull request Aug 8, 2026
Adopts the three upstream commits after #381: a cross-environment usage page
reading provider transcripts (pingdotgg#5684), its chart fix (pingdotgg#5697), and one mobile
sheet for model and thread settings (pingdotgg#5625).

Resolutions:

- server.ts / ws.ts / client-runtime state: upstream's UsageService and its
  usageSummary atom family are additive next to the fork's diagnostics services
  (HostResourceProbe, ProcessResourceMonitor, TraceDiagnostics, BackgroundPolicy)
  and hostResourceSnapshot family — unioned.
- ThreadComposer: pingdotgg#5625 folds the model picker and provider options into a
  single settings sheet, replacing the fork's ControlPillMenu. The sheet is
  adopted, and the fork's usage signal rides on it: the trigger keeps
  ProviderUsageIcon with the live marker rather than upstream's plain
  ProviderIcon, so quota state stays visible at a glance. The fork-only
  collapsed-composer pill (upstream has none) now opens the same sheet instead
  of the retired menu.

Adversarial review caught that retiring the model menu also orphaned the fork's
numeric usage note: the marker survived on the trigger icon but the quota
percentage the menu rows carried had no home. It now hangs off the trigger
label, so both halves of the fork's usage signal survive the consolidation.
The plain ProviderIcon import went with upstream's replaced icon.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
radroid added a commit to radroid/t3code that referenced this pull request Aug 8, 2026
apps/mobile/src/features/threads/composerSendLabel.ts is a logic mirror
and was not on the mirrors table. It does not merely duplicate upstream
logic -- it replaced four upstream lines in ThreadComposer.tsx with a
call, which is the more dangerous shape: a future upstream edit to those
three conditions lands nowhere, because the lines that held them are
gone. Nothing conflicts and nothing fails.

Re-verified against the follow-up merge-base. pingdotgg#5625 rewrote
ThreadComposer.tsx end to end (-124/+57) and left the ternary's
conditions alone, so the helper is still byte-equivalent to what it
replaced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant