You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature Request: Retain current model and agent selection when switching sessions #4930
Feature Request: Retain current model and agent selection when switching sessions
Problem Description
When switching between sessions using Ctrl+X l, the session loads with whatever model and agent we were currently using. This forces users to manually reselect their preferred model and agent every time they switch sessions, which disrupts workflow continuity.
Current Behavior
User has Session A open with Model X and Agent Y
User switches to Session B using Ctrl+X l
Session B loads with whatever model and agent it was last using (e.g., Model Z and Agent W)
User must manually change model and agent back to their preferred selection
Desired Behavior
User has Session A open with Model X and Agent Y
User switches to Session B using Ctrl+X l
Session B loads but retains the session's last model and agent selection (Model X and Agent Y)
User can continue working without manual reconfiguration
Rationale
Users choose the best model and agent for a specific task. Each session serves a specific task, so the current model and agent selection should follow the user as they switch between sessions, rather than being locked to whatever a session was previously configured with.
Implementation Suggestion
Add a setting or default behavior where the current model and agent selection persists across session switches, rather than being tied to the global opencode CLI.
Additional Context
This is different from issue #4344 (model selection not sticking between agent alternation) - this is specifically about session switching via Ctrl+X l retaining the current user's model and agent preferences.
I’d like to take this. Sessions in opencode don’t currently persist model/agent;
they’re tracked as global TUI state.
I see two approaches:
A: Derive model/agent from the session’s last user message (good for existing data, but undefined for empty/new sessions).
B: Add defaultModel / defaultAgent to Session.Info and have the TUI (and other clients) respect those as the per-session defaults.
What approach is best? I'm leaning toward B, it fits the "sessions serve specific tasks" rationale better.
Would love to contribute once there is a clear direction!
Both aporoaches would be functionally equivalent.
B feels cleaner to me, but I'm not very familiar with the codebase. Both of them could serve a getSessionAgent and getSessionProvider API to expose these things also for other use cases.
Arguably, a "default" for a session is kinda meaningless, right? Like, it's always what you last used - so the term "current" may just aswell be used to not confuse it with global defaults?
@JosXa Good point, "currentModel"/"currentAgent" is much clearer than "default" since it's always what you last used.
@rekram1-node Noticed you labeled this as a good first issue. If the Option B approach sounds good, I'll proceed with extending Session.Info, updating on changes, exposing getters, and reading on switch.
Does this plan cover everything, or am I missing something?
+1 I found this issue because I was just surprised when resuming a past session didn't restore the agent I was using in that session.
I agree with the rationale at top that sessions represent a user's task, and the user already made a meaningful choice of model and agent for that task. Currently, it's jarring when I run opencode -s <session> and see my old task with the wrong agent and/or model — usually what happens is I send my first message, and only then notice that the agent/model aren't what I expected, and then I have to undo and switch agent/model and then submit it again.
Making agent/model sticky to the session seems like the least surprising UX to me.
Reacted by Joscha Götzer, Phong Do, Ayush Walekar, kaanmertkoc and bhargav-nexie
@ShpetimA Right, I created the session and then sent the API request prompt specifying agent, sorry for confusion. I was unable to fix it in the PR, so I rather closed it.
Hi! I'd like to take a crack at this. My approach: add an effect in local.tsx that watches for session route changes and restores the model/agent from the last user message. This follows Option A discussed above - no schema changes needed since user messages already store model and agent. Let me know if this sounds good before I open a PR.
Hi! I'd like to take a crack at this. My approach: add an effect in local.tsx that watches for session route changes and restores the model/agent from the last user message. This follows Option A discussed above - no schema changes needed since user messages already store model and agent. Let me know if this sounds good before I open a PR.
@ShpetimA already had a PR open, check if you can review and improve upon it first please :)
where lastModel walks back through the session's user messages to find the last used model.
However, I want to add some technical context that might help refine the approach before you open a PR.
Current TUI architecture
The TUI already maintains global model/agent selection in local.tsx:
local.agent.current() — returns the currently selected agent (stored in agentStore.current)
local.model.current() — returns the currently selected model (stored per-agent in modelStore.model[a.name])
When the user sends a message from the TUI, the prompt component explicitly passes local.model.current() to the server (line 672, 776-777 in prompt/index.tsx). So the server always receives the user's explicit choice.
The actual gap
The issue isn't that the server ignores the user's selection — it's that when you navigate to a different session, the TUI doesn't restore the model/agent that were used in that session's last message.
Your "global state" approach (Option A) would work for the TUI, but has a limitation: it wouldn't help for opencode attach or API-created sessions, as @snaselj noted. The server is headless — it has no concept of a "user's current global selection".
Why Option B (per-session) is more robust
Looking at the feedback from @jdanbrown and the implementation @ShpetimA attempted, the consensus leans toward making model/agent sticky to the session itself:
"Making agent/model sticky to the session seems like the least surprising UX"
This means:
When navigating to a session, the TUI reads lastModel(sessionID) and lastAgent(sessionID) and sets them as the current selection
This works for TUI, attach, and API because it derives from session data, not ephemeral TUI state
Concrete implementation suggestion
Instead of adding global state, add an effect in routes/session/index.tsx that reacts to route.sessionID changes:
// When navigating to a session, restore its last used model/agentcreateEffect(on(()=>route.sessionID,(sessionID)=>{// Derive last model from session messagesconstlastMsg=sync.data.message[sessionID]?.findLast(m=>m.info.role==="user"&&m.info.model)if(lastMsg?.info.model){local.model.set(lastMsg.info.model)}// Derive last agent from session messages if(lastMsg?.info.agent){local.agent.set(lastMsg.info.agent)}}))
This is a minimal TUI-only change that leverages existing data structures. The server side is already correct — lastModel() and user message storage handle the persistence.
Caveat
As @ShpetimA discovered, there's edge cases with empty sessions (no user messages yet) and custom agents. You'd need to handle:
Session with no messages → keep current global selection (don't override)
Model/agent no longer valid (provider removed) → fallback gracefully
Would love to hear thoughts from @rekram1-node on whether this direction aligns with the team's view.
Opened PR #24508 with a minimal approach: a KV toggle that controls whether model/agent get restored from the session's last message when you switch. Default is on (current behavior), so nothing changes unless you opt out via the command palette. This keeps it backward-compatible while giving users who want sticky selection a way to get it.
Activity
github-actions commentedon Dec 1, 2025
This issue might be a duplicate of existing issues. Please check:
Feel free to ignore if none of these address your specific case.
rekram1-node commentedon Dec 2, 2025
Yeah that makes sense
phongndo commentedon Dec 3, 2025
I’d like to take this. Sessions in opencode don’t currently persist model/agent;
they’re tracked as global TUI state.
I see two approaches:
What approach is best? I'm leaning toward B, it fits the "sessions serve specific tasks" rationale better.
Would love to contribute once there is a clear direction!
JosXa commentedon Dec 3, 2025
Thanks @ph8n! 😊
Both aporoaches would be functionally equivalent.
B feels cleaner to me, but I'm not very familiar with the codebase. Both of them could serve a
getSessionAgentandgetSessionProviderAPI to expose these things also for other use cases.Arguably, a "default" for a session is kinda meaningless, right? Like, it's always what you last used - so the term "current" may just aswell be used to not confuse it with global defaults?
phongndo commentedon Dec 4, 2025
@JosXa Good point, "currentModel"/"currentAgent" is much clearer than "default" since it's always what you last used.
@rekram1-node Noticed you labeled this as a good first issue. If the Option B approach sounds good, I'll proceed with extending Session.Info, updating on changes, exposing getters, and reading on switch.
Does this plan cover everything, or am I missing something?
rekram1-node commentedon Dec 4, 2025
Hm I think I'm realizing i may have misunderstood op
So is the expectation that whenever you switch sessions it switches to whatever model was last used in that session?
Hmmm
phongndo commentedon Dec 4, 2025
@JosXa can you clarify the wanted behavior?
JosXa commentedon Dec 4, 2025
Yes, exactly.
I wanna be able to work on sessions in parallel, not have to reconfigure models and the agent every.single.time I switch between them.
Not a fan?
rekram1-node commentedon Dec 4, 2025
The more i think about it I actually do think i like it? initially i didnt but lemme ask
ry2009 commentedon Dec 9, 2025
@JosXa check out this PR and lmk what you think it should be solved lmk if any errors pop up or any additional requests: #5264
jdanbrown commentedon Dec 9, 2025
+1 I found this issue because I was just surprised when resuming a past session didn't restore the agent I was using in that session.
I agree with the rationale at top that sessions represent a user's task, and the user already made a meaningful choice of model and agent for that task. Currently, it's jarring when I run
opencode -s <session>and see my old task with the wrong agent and/or model — usually what happens is I send my first message, and only then notice that the agent/model aren't what I expected, and then I have toundoand switch agent/model and then submit it again.Making agent/model sticky to the session seems like the least surprising UX to me.
5 remaining items
snaselj commentedon Dec 29, 2025
@ShpetimA Right, I created the session and then sent the API request prompt specifying agent, sorry for confusion. I was unable to fix it in the PR, so I rather closed it.
jamiehicks154 commentedon Jan 16, 2026
Hi! I'd like to take a crack at this. My approach: add an effect in local.tsx that watches for session route changes and restores the model/agent from the last user message. This follows Option A discussed above - no schema changes needed since user messages already store model and agent. Let me know if this sounds good before I open a PR.
JosXa commentedon Jan 16, 2026
@ShpetimA already had a PR open, check if you can review and improve upon it first please :)
jamiehicks154 commentedon Jan 16, 2026
@JosXa sorry that was my bad and missed that a PR was already open
deadcoder0904 commentedon Feb 21, 2026
#12582
This PR got merged but it still switches agents, at least custom agents in my case.
I have a custom agent called architect under
.opencode/agents/architect.mdwhich is what I set in the cycle through command:And when I click new session it automatically switches. Did the merged PR get released in desktop? Because I don't see it actually fixed.
ShpetimA commentedon Feb 22, 2026
I'm closing the pr I had for this since it's old now, if there is interest by the team in future I can open it again
fix(tui): retain model and agent selection when switching sessions
Jah-yee commentedon Apr 4, 2026
Good day! I'd like to help implement this feature.
Analysis
Currently in
packages/opencode/src/session/prompt.ts, model selection is resolved via:When switching sessions via
Ctrl+X l, the session loads with its stored model/agent rather than the current active selection.Proposed Solution
This could be implemented by:
I'd like to submit a PR for this. Could you confirm this approach works for your design?
alfredocristofano commentedon Apr 26, 2026
@Jah-yee Your analysis of
session/prompt.tsis accurate. The model resolution chain is indeed:where
lastModelwalks back through the session's user messages to find the last used model.However, I want to add some technical context that might help refine the approach before you open a PR.
Current TUI architecture
The TUI already maintains global model/agent selection in
local.tsx:local.agent.current()— returns the currently selected agent (stored inagentStore.current)local.model.current()— returns the currently selected model (stored per-agent inmodelStore.model[a.name])When the user sends a message from the TUI, the prompt component explicitly passes
local.model.current()to the server (line 672, 776-777 inprompt/index.tsx). So the server always receives the user's explicit choice.The actual gap
The issue isn't that the server ignores the user's selection — it's that when you navigate to a different session, the TUI doesn't restore the model/agent that were used in that session's last message.
Your "global state" approach (Option A) would work for the TUI, but has a limitation: it wouldn't help for
opencode attachor API-created sessions, as @snaselj noted. The server is headless — it has no concept of a "user's current global selection".Why Option B (per-session) is more robust
Looking at the feedback from @jdanbrown and the implementation @ShpetimA attempted, the consensus leans toward making model/agent sticky to the session itself:
This means:
lastModel(sessionID)andlastAgent(sessionID)and sets them as the current selectionattach, and API because it derives from session data, not ephemeral TUI stateConcrete implementation suggestion
Instead of adding global state, add an effect in
routes/session/index.tsxthat reacts toroute.sessionIDchanges:This is a minimal TUI-only change that leverages existing data structures. The server side is already correct —
lastModel()and user message storage handle the persistence.Caveat
As @ShpetimA discovered, there's edge cases with empty sessions (no user messages yet) and custom agents. You'd need to handle:
Would love to hear thoughts from @rekram1-node on whether this direction aligns with the team's view.
alfredocristofano commentedon Apr 26, 2026
Opened PR #24508 with a minimal approach: a KV toggle that controls whether model/agent get restored from the session's last message when you switch. Default is on (current behavior), so nothing changes unless you opt out via the command palette. This keeps it backward-compatible while giving users who want sticky selection a way to get it.
github-actions commentedon Jul 3, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.