Skip to content

fix(tui): keep session model stable when recents sync - #52533

Closed
opencode-agent[bot] wants to merge 1 commit into
devfrom
model-selection-isolation
Closed

opencode-agent[bot] wants to merge 1 commit into
devfrom
model-selection-isolation

Conversation

@opencode-agent

@opencode-agent opencode-agent Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

What changed

  • An open session without a durable model used the live recents list as its fallback. Another TUI instance selecting a model reordered recents and changed that session’s active model.
  • Capture the fallback per session and agent in the local TUI. Explicit drafts and durable same-session selections still take priority, while newly opened sessions can use newly synced recents. Shared recents, favorites, and variant preferences continue syncing.

Validation

  • Regression: an external preference repository updates recents, favorites, and variant; the open session keeps its model and variant, a newly opened session sees the latest recent, and a durable selection for the original session still takes effect.
  • bun test test/context/local-selection.test.tsx (packages/tui)
  • bun typecheck (packages/tui)
  • Focused oxlint on changed files

Requested by: @rekram1-node (Aiden via Slack)

@cleardevice

Copy link
Copy Markdown

Found a case this doesn't cover (reported in #54375). The fallback is captured per agent the first time that agent is resolved in a session, so an agent that hasn't been selected in the session yet (for example after the TUI restarts) still picks up a model chosen meanwhile in another tab or client:

  1. Session A: the last prompt was sent with plan on model X; build has no model and there is no global model in config.
  2. In another tab, pick model Y.
  3. Back in A, switch to build: it runs on Y, though nothing was picked in A.
Test: expects X, gets Y on dev 7b3d4ce both with and without this change (ported onto dev)
test("an agent first shown after another tab picks a model keeps the session fallback", async () => {
  await using setup = await renderLocal({
    models: [model("first"), model("second")],
    agents: [agent("build"), agent("plan")],
    preferences: { recent: [{ providerID: "provider", modelID: "first" }] },
    sessions: [
      session("ses_a", { providerID: "provider", id: "first" }, "plan"),
      session("ses_b", { providerID: "provider", id: "first" }, "build"),
    ],
  })
  await Promise.all([setup.data.session.sync("ses_a"), setup.data.session.sync("ses_b")])
  setup.route.navigate({ type: "session", sessionID: "ses_a" })
  setup.route.navigate({ type: "session", sessionID: "ses_b" })
  setup.local.model.set({ providerID: "provider", modelID: "second" }, { recent: true })
  setup.route.navigate({ type: "session", sessionID: "ses_a" })
  setup.local.agent.set("build")
  expect(setup.local.model.current()?.modelID).toBe("first")
})

Capturing the fallback for all agents when the session is first resolved would make the test pass, but it would still snapshot the shared recents at that moment rather than use the session's own model. Which model build should get here is the open question in #54375 and #43179, so leaving it out of scope is fine; just flagging the gap.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants