fix(models): restore sticky new-thread selections#9164

merged1
main
GitHub fork: t3code/fix-sticky-model-defaults
openedSep 2, 2026byMmaria
View on GitHubTwo-way sync enabledPR last imported 20d ago

New projects were saving an automatically resolved model as a project override, so stale project records beat the app-wide last selection and missing options became catalog defaults such as Sol/Low.

Following the persistence issue identified in #8913, project creation now stays unconfigured: new threads reuse the last provider, model, and options unless the user explicitly sets a per-project override. Migration 44 clears old create-time seeds only when no later project-default write exists, and web and mobile send only options selected in T3, so real project overrides survive while the bad upgrade state disappears.

How it works

T3 still remembers the last provider, model, and options across projects. A project setting wins only when the user explicitly sets one. New projects no longer save an inferred override, and migration 44 removes old create-time seeds without touching later explicit settings. The clients also dispatch only options the user selected, so a displayed catalog default does not become saved state.

Before and after

Same browser, project, and database in both shots: select High, start a thread, then open another new thread.

Before

The base commit reopened the next thread on Low because the project's inferred default overrode the remembered selection.

Before: a new thread reset GPT-5.6-Sol to Low

After

After migration 44 and the sticky-selection fix, the next thread stays on High.

After: a new thread keeps GPT-5.6-Sol on High

Verified with 158 focused tests, targeted lint and formatting, and typechecks for contracts, shared, server, web, and mobile. Built with gpt-5.6-sol through the Codex harness in T3 Code.

Closes #8829.


Note

Medium Risk Touches orchestration event semantics, a data migration on existing SQLite stores, and what model/options are sent to providers—behavior changes for new threads and legacy project records, though explicit overrides are preserved.

Overview Fixes sticky model selection by stopping automatic project defaults from overriding the app-wide “last used” model and by not persisting catalog option defaults as if the user chose them.

Project defaults are now explicit only: project.create always records defaultModelSelection: null (older clients may still send the field; the server ignores it). Web command-palette and CLI project add, plus auto-bootstrap startup, no longer attach a resolved model to new projects; welcome bootstrap still seeds the first thread via getAutoBootstrapThreadModelSelection. Migration 044 clears projection and project.created payloads for create-time seeds when no later project.meta-updated set a default, while keeping user-configured project defaults.

Provider model options use buildExplicitProviderOptionSelectionsFromDescriptors on web, mobile, and shared code: UI can show descriptor defaults, but dispatch and stored selections include only options the user picked. User docs describe remembered selection vs project override and explicit options.

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

Note

Fix sticky model selections by dispatching only explicit options and clearing inferred project defaults

  • Adds buildExplicitProviderOptionSelectionsFromDescriptors in model.ts to return only explicitly selected option IDs, replacing descriptor-default materialization across mobile, web, and server dispatch paths
  • Server project.create decider now always writes null for the default model selection in project.created events; the command field is retained for compatibility but ignored
  • Migration 044 in 044_ClearAutomaticProjectModelDefaults.ts clears inferred create-time model defaults from project projections and rewrites matching project.created event payloads to null, preserving streams with a later explicit metadata update
  • Auto-bootstrap welcome-thread creation no longer attaches a model default to the project; the welcome thread receives the canonical selection directly
  • Behavioral Change: ProjectCreateCommand default model field is now ignored by the server; clients must use project metadata updates to set explicit defaults. Existing projects with inferred defaults from create-time will have those defaults cleared by migration 044

Macroscope summarized 649672a.

Added 1 commit

  • fix(models): restore sticky new-thread selections649672a
Synced from GitHub

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes how new threads inherit models and provider options across web, mobile, CLI, and startup flows, while also migrating persisted project defaults and historical events. The cross-platform behavior change and data transition warrant human review.

You can add or adjust custom eligibility rules. Learn more.