fix(tui): use role=user for model switch marker to avoid HTTP 400 on strict providers (#48338) - #54210
Merged
Merged
Conversation
…strict providers (#48338) _append_model_switch_marker() appended the post-/model-switch context marker to session history as {"role": "system"}. The cached system prompt is prepended to the API message list (conversation_loop.py), so this marker became a SECOND system message mid-array after prior user/assistant turns. Strict OpenAI-compatible providers (vLLM, Qwen) reject any system message that is not at the beginning of the array, returning HTTP 400 and killing the conversation on the next turn. Flip the marker to role="user" (history entry + both session-DB persist sites), matching the existing personality-overlay marker which already uses role="user". repair_message_sequence() then coalesces it with adjacent user turns as needed. Co-authored-by: liuhao1024 <sunsky.lau@gmail.com> Co-authored-by: Lucas Nicolas <lucas.nicolas@proton.me>
Contributor
🔎 Lint report:
|
This was referenced Jun 28, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A mid-session
/modelswitch no longer kills the conversation with HTTP 400 on strict OpenAI-compatible providers (vLLM, Qwen)._append_model_switch_marker()appended the post-switch context marker to session history as{"role": "system"}. The cached system prompt is prepended to the API message list (agent/conversation_loop.py), so this marker became a second system message mid-array, after prior user/assistant turns. Strict providers reject any system message that is not at the beginning of the array → HTTP 400 on the next turn.Changes
tui_gateway/server.py: marker history entry + both session-DB persist sites now userole="user"instead ofrole="system". Matches the existing personality-overlay marker (server.py), which already appends its[System: …]text underrole="user".tests/tui_gateway/test_model_switch_marker_role.py: new regression coverage — marker role, content preservation, empty provider, lock path, version bump, no-op guards, and the mid-conversation shape from the report.tests/test_tui_gateway_server.py: updated the existing switch test's role assertions.Validation
system(mid-array)userrepair_message_sequence()coalesces the user-role marker with adjacent user turns as needed, so alternation stays valid.Credit
Same one-line fix was independently submitted by @liuhao1024 (#48346, earliest), @lucas-nicolas-viseo (#48355, reporter), and @Elshayib (#48361). Cleanest minimal version (#48346) salvaged here; explanatory comment from #48355 folded in. Both credited via
Co-authored-by. #48361 additionally bundled unrelated custom-provider catalog changes, left out of this fix.Infographic