anomalyco / anomalyco/opencode
Model swap gets clobbered by model-less prompts (plugin reminders)
@neriousy is already working on this.
Since Aug 16, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Bug
When a user swaps the model in an opencode serve / mobile session (e.g. to deepseek-v4-flash), the swap is lost on the next model-less prompt — typically a plugin completion-reminder (e.g. oh-my-openagent's promptAsync without a --model flag). The session row reverts to the agent's configured model.
The TUI is unaffected because it always sends model: input.draft.model explicitly on every prompt.
Root cause
In packages/opencode/src/session/prompt.ts, createUserMessage resolves the model as:
input.model ?? ag.model ?? currentModel(sessionID)
When input.model is absent, ag.model (the agent's configured model) wins over the session's persisted model (the user's swap). Then setAgentModel overwrites the session row to the resolved model, permanently clobbering the swap.
This was introduced by #26765 ("Persist session model switches outside event flag"), which intentionally made ag.model outrank currentModel so an agent's configured model applies when no explicit model is given. The design is correct for the turn's model — but setAgentModel should not overwrite the session row when the model was resolved from the agent fallback rather than an explicit user choice.
Repro
opencode serve→ create a session with an agent that has a configured model (e.g. GLM-5.2)- Send a prompt with an explicit model swap (e.g.
deepseek-v4-flash) - Send a model-less prompt (e.g. a plugin reminder via
promptAsyncwithoutmodel) - Query the session row — it reverts to the agent's model (GLM-5.2), losing the swap
Fix
Guard the setAgentModel write: skip it when the prompt carried no explicit model AND the session already has a stored model that differs from the agent's resolved model. Fresh sessions (no stored model) and explicit-model prompts still persist normally.
The model resolution precedence (input.model ?? ag.model ?? currentModel) is unchanged — model-less prompts still use the agent's model for the turn (existing design, tested by "applies agent variant only when using agent model"). Only the row persistence is guarded.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.