anomalyco / anomalyco/opencode

Model swap gets clobbered by model-less prompts (plugin reminders)

Open
#42,893 2 comments 0 reactions 1 assignee View on GitHub

@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

  1. opencode serve → create a session with an agent that has a configured model (e.g. GLM-5.2)
  2. Send a prompt with an explicit model swap (e.g. deepseek-v4-flash)
  3. Send a model-less prompt (e.g. a plugin reminder via promptAsync without model)
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.