Conversation
A model-less prompt (no input.model — e.g. plugin completion-reminders via promptAsync) resolves from the agent fallback (ag.model) for the turn. The existing design (PR anomalyco#26765) intentionally uses the agent's model when no explicit model is given. However, setAgentModel then overwrites the session row to the resolved model, permanently destroying a model the user explicitly stored via a prior swap. The TUI is unaffected (always sends draft.model explicitly), but opencode serve / mobile clients lose the swap on the next plugin reminder. 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.
|
This seems to fix the original model-clobber case, but I found a related state-update edge case: the guard can also suppress an explicit agent change because Consider this sequence:
The PR correctly prevents fallback model However, because
rather than:
In this case the two fields need different treatment: preserve the stored model, but still persist the explicitly selected agent. I think a regression covering this transition would be useful:
That would preserve the model-swap fix without leaving the persisted agent stale. |
|
|
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:
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. |
Issue for this PR
Closes #42893
Type of change
What does this PR do?
A model-less prompt (no
input.model— e.g. plugin completion-reminders viapromptAsync) resolves from the agent fallback (ag.model) for the turn. The existing design (PR #26765) intentionally uses the agent's model when no explicit model is given — this is correct for the turn's model and is preserved.However,
setAgentModelthen overwrites the session row to the resolved model, permanently destroying a model the user explicitly stored via a prior swap. The TUI is unaffected (always sendsdraft.modelexplicitly), butopencode serve/ mobile clients lose the swap on the next plugin reminder.The fix: guard the
setAgentModelwrite increateUserMessage— skip it when:input.model == null), ANDstoredModelDiffers)Fresh sessions (no stored model) still persist the agent's model on the first model-less prompt (
hasNoStoredModelguard), and explicit-model prompts always persist normally. The model-resolution precedence is unchanged — model-less prompts still use the agent's model for the turn.How did you verify your code works?
"model-less prompt does not clobber user's stored model swap"— creates a session, swaps tokimi-k2.5-free, sends a model-less prompt with an agent carryingtest/test-model, asserts the turn usestest-model(design preserved) but the session row stayskimi-k2.5-free(the fix). Verified RED→GREEN."model-less first prompt on fresh session persists agent model to row"— confirms thehasNoStoredModelguard firessetAgentModelon a fresh session so the row is initialized."applies agent variant only when using agent model"(the test that pins the agent-model design from Persist session model switches outside event flag #26765) still passes — model-less prompts still use the agent's model for the turn.test/session/prompt.test.ts.Checklist