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
plugin: a model switch from a CLI plugin is not reflected in the TUI #57771
A CLI plugin cannot change the model. client.session.switchModel() changes the session on the server, but the TUI keeps its own selection: the composer does not change and the next prompt sends the old model back, undoing it.
Environment
opencode version: 2.1.2
OS: Darwin 27.0.0 (arm64)
Terminal: ghostty (xterm-256color)
Shell: /bin/zsh
Install/channel: latest
Active plugins: local TUI plugins; the one below reproduces it
Reproduction
Open a continued session (opencode -c) with a local CLI plugin that calls context.client.session.switchModel({ sessionID, model }).
Call it from the plugin before the first prompt, or right after switching agent.
The server records the change (session model + a model-switched message); the composer stays on the old model.
Expected Behavior
The TUI shows the model the session now uses — or a plugin has a documented way to change it.
Actual Behavior
The TUI keeps a model selection per (session, agent) in its own memory and prefers it over the session's model; the next prompt sends that selection, so the switch is reverted. The plugin API has ui.model.current() and variant.list()/set() only — no setter. The native picker writes that selection through an internal model.set, unreachable from a plugin.
Additional Context
Workaround: write the model into model.json's favorite[] and dispatch model.cycle_favorite, then restore the list. It works only because that command ends on the first favourite, and it relies on undocumented behaviour.
Ask: expose a model setter to CLI plugins (e.g. ui.model.set({ providerID, modelID }, { recent? })), or make the client adopt a model change made through the API.
Thanks for the detailed write-up and the workaround. You're asking for a supported way for a plugin to change the model the TUI uses: either a setter in the plugin API such as ui.model.set({ providerID, modelID }, { recent }), or the TUI picking up a model change made through session.switchModel().
What you describe matches how the TUI works today. Each tab keeps its own model choice per session and agent, and that choice wins over the session's saved model. When a model change event arrives, the TUI only uses it to confirm a switch the TUI started itself, so a switch made by a plugin or another API client gets overwritten by the next prompt. The plugin API gives ui.model only current() and variant.list()/set(), so I don't think a plugin can do this cleanly yet. Your favourites-cycling trick looks like the only option for now.
I've passed the suggested API addition on to the maintainers, and they will consider it. Related issues:
Activity
opencode-agent commentedon Oct 21, 2026
Thanks for the detailed write-up and the workaround. You're asking for a supported way for a plugin to change the model the TUI uses: either a setter in the plugin API such as
ui.model.set({ providerID, modelID }, { recent }), or the TUI picking up a model change made throughsession.switchModel().What you describe matches how the TUI works today. Each tab keeps its own model choice per session and agent, and that choice wins over the session's saved model. When a model change event arrives, the TUI only uses it to confirm a switch the TUI started itself, so a switch made by a plugin or another API client gets overwritten by the next prompt. The plugin API gives
ui.modelonlycurrent()andvariant.list()/set(), so I don't think a plugin can do this cleanly yet. Your favourites-cycling trick looks like the only option for now.I've passed the suggested API addition on to the maintainers, and they will consider it. Related issues:
session.get()doesn't return the session's model