fix: coalesce system messages into a single leading one at send time - #3
Merged
Conversation
Strict chat templates (Qwen among them) reject any request whose system message is not the single first message - Scaleway-hosted Qwen returns "API error (400): System message must be at the beginning". The extension violated that in three places: the per-turn auto-context note (inserted as a system message before the latest user turn), the agent path's "current active file" note (appended mid-transcript), and the agent transcript opening with two consecutive system messages when workspace orientation exists. ChatMessageNormalizer.CoalesceSystemMessages merges every system message (in order of appearance, blank-line joined) into one system message at index 0, leaving non-system messages and their tool-call metadata untouched. It runs at the request-build point in LLMService, so all chat, streaming, tool, and completion paths across every dialect are covered, and the persisted conversation history is never mutated. Fixes #2 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Fixes #2 — Scaleway-hosted Qwen rejects requests with
API error (400): "System message must be at the beginning."while Llama accepts the same payload. Qwen's chat template requires exactly one system message at position 0; the extension violated that in three places:ChatWindowControlsend): the per-turn auto-context (or no-solution note) was inserted as asystemmessage just before the latest user message — a mid-conversation system message on essentially every request.systemmessage.AgentLoop.NewTranscript): with workspace orientation present, the transcript started with two consecutive system messages — the second, at index 1, is "not at the beginning" for strict templates.Fix
ChatMessageNormalizer.CoalesceSystemMessagesmerges every system message (in order of appearance, joined by a blank line) into a single system message at index 0, leaving non-system messages — including tool-call metadata — untouched. It is applied at the request-build point inLLMService, so one code path covers chat, streaming, native-tool, and completion requests for every dialect. Permissive backends are unaffected; the persisted conversation history is never mutated (normalization is send-time only).This also removes an inconsistency where
TrimMessageHistoryalready hoisted system messages to the front, but only when trimming fired.Testing
New
tests/LocalModelIntegrator.Testsproject (the VSIX project can't be referenced from a plain test project, so the transport-format-free sources are compile-linked): 7 tests covering mid-conversation merge, double-leading-system merge, canonical/no-system passthrough, non-mutation of history, tool-call metadata preservation, and blank-system dropping. All written first and watched fail. VSIX project builds with 0 errors.🤖 Generated with Claude Code