fix: normalize stale session models after provider switch — v0.50.99 (#751)

## Summary

Rebased-on-behalf of @likawa3b (originally PR #748 — stale base).

Sessions can outlive provider changes. When an old session still points to a model from a previous provider (e.g. `gemini-3.1-pro-preview` after switching the agent to OpenAI Codex), starting a chat hits the wrong backend and fails silently.

This PR adds a lightweight normalization pass:
- `_normalize_provider_id()` maps common prefixes to canonical provider IDs
- `_resolve_compatible_session_model()` checks the session model's provider against `active_provider` and returns the default model if they differ
- `_normalize_session_model_in_place()` is called at GET `/api/session` — corrects and persists stale models once
- Chat start also normalizes via `_resolve_compatible_session_model()` and returns `effective_model` in the response
- `messages.js` applies `effective_model` back to the UI/localStorage/dropdown if set

Closes #748

## Tests

1498 passed (2 pre-existing ordering failures unrelated to this PR; 5 new tests added in `test_provider_mismatch.py`).

**Original author:** @likawa3b
This commit is contained in:
nesquena-hermes
2026-04-19 23:22:26 -07:00
committed by GitHub
parent c68420d9aa
commit 7f16a41a31
4 changed files with 197 additions and 2 deletions

View File

@@ -71,6 +71,12 @@ async function send(){
model:S.session.model||$('modelSelect').value,workspace:S.session.workspace,
attachments:uploaded.length?uploaded:undefined
})});
if(startData.effective_model && S.session){
S.session.model=startData.effective_model;
localStorage.setItem('hermes-webui-model', startData.effective_model);
if($('modelSelect')) _applyModelToDropdown(startData.effective_model, $('modelSelect'));
if(typeof syncTopbar==='function') syncTopbar();
}
streamId=startData.stream_id;
S.activeStreamId = streamId;
markInflight(activeSid, streamId);