Skip to content

fix(desktop): reseed new chats from profile defaults, guarded against concurrent picks (supersedes #67207) - #67291

Closed
OutThisLife wants to merge 2 commits into
mainfrom
bb/salvage-67207-newchat-reseed
Closed

fix(desktop): reseed new chats from profile defaults, guarded against concurrent picks (supersedes #67207)#67291
OutThisLife wants to merge 2 commits into
mainfrom
bb/salvage-67207-newchat-reseed

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

Summary

Salvages #67207 (@deniqlab) for #65300 — a fresh Desktop chat should seed from the config.yaml default, not silently reuse the previous chat's sticky composer model. Adds the race guard @teknium1's review asked for.

Behavior

The race guard (teknium1's review)

@deniqlab's version used refreshCurrentModel(true), which bypasses both manual-state guards — so a picker selection made while the reseed's async getGlobalModelInfo() was in flight got overwritten by the resolved default, violating apps/desktop/AGENTS.md's "guard against the past: a stale response must never overwrite newer intent."

Fix: a monotonic manual-pick token (session.ts). selectModel bumps it; the reseed captures it before the await and bails if it moved while pending. So force still overrides a pre-existing manual pick (new chat resets to default), but a newer pick made mid-reseed wins. Added a deferred-result regression test proving the post-start pick survives.

Note on the #65896 relationship

This intentionally drops #65896's cross-chat manual stickiness (a pick no longer bleeds into the next new chat) while keeping its genuinely important part — the stale-guard against incidental refreshes. Net: manual intent wins within a chat and against in-flight reseeds; a brand-new chat honors your configured default.

Test plan

  • vitest run --project ui — 189 files, 1530 pass / 1 skip (incl. new deferred-pick guard test + use-background-sync.test.tsx)
  • npm run typecheck — clean
  • eslint changed files — clean
  • npm run build — success
  • Manual: pick a non-default model, Cmd+N → composer shows the config default; pick a model immediately as a new chat opens → your pick sticks (not overwritten by the reseed).

Fixes #65300

deniqlab and others added 2 commits July 18, 2026 23:24
Addresses teknium1's review of the fresh-draft reseed: refreshCurrentModel(true)
bypassed both manual-state guards, so a picker selection made while the reseed's
async getGlobalModelInfo() was in flight got clobbered by the resolved default —
violating the AGENTS "guard against the past" invariant.

Add a monotonic manual-pick token (session.ts): selectModel bumps it, and the
reseed captures it before the await and bails if it moved while pending. force
still overrides a PRE-EXISTING manual pick (new-chat resets to default), but a
NEWER pick made mid-reseed wins. Adds a deferred-result regression test proving
the post-start pick survives.

Co-authored-by: Denis <276550298+deniqlab@users.noreply.github.com>
@OutThisLife

Copy link
Copy Markdown
Collaborator Author

Closing — after weighing the UX, we're keeping the sticky-last-pick behavior (#65896) instead of resetting new chats to the profile default.

Switching between existing chats is already session-scoped and unaffected; the only thing this changed was the new-chat boundary, and clobbering a deliberate manual pick on Cmd+N is worse for the "I switched models on purpose" workflow than the reset is worth. The actual reported breakage — a removed/stale default (owl-alpha, #58498) lingering and overriding config — is already fixed on main by #65896, which re-syncs default/legacy-derived composer state from config.yaml while leaving explicit picks alone.

The race-guard was only needed because of the force-reseed, so it's moot without it. Thanks @deniqlab for the solid work regardless.

@OutThisLife
OutThisLife deleted the bb/salvage-67207-newchat-reseed branch July 19, 2026 03:35
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 19, 2026
@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hermes Desktop new session ignores config.yaml default and reuses sticky composer model

4 participants