fix(llm): developer message after assistant turn opens a user message - #114
Merged
Conversation
The Claude mapper merged developer-role content into the previous message regardless of its role. After a truncated agent turn the previous message is the partial assistant text, so the truncation feedback was glued into the assistant message: the model was credited with text it never produced, and the request ended on an assistant turn, which the API treats as prefill and models from Sonnet 4.6 on reject with "This model does not support assistant message prefill" (reproduced live: an agent flow died mid-import on claude-sonnet-5, and a minimal trailing-assistant request returns the same 400). Developer content now merges only into a preceding plain user message; after an assistant message (or a tool_result) it opens a new user message, so recovery guidance reaches the model on the user turn. Claude-Session: https://claude.ai/code/session_01GGANLtqTDCWHbSYmycvjpV
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.
Defect
claude/mapper.luamergeddeveloper-role content into the previous message regardless of that message's role. Two consequences:<developer-instruction>...) was appended into the partial assistant message, attributing text to the model it never produced.This model does not support assistant message prefill. The conversation must end with a user message.Observed in production
A
kb_importeragent dataflow onclaude-sonnet-5died mid-import, twice, at the first truncated turn (the agent node's truncation recovery stores the partial action and a developer feedback observation —dataflow/src/node/agent/node.luatruncation branch — which the mapper then merged into the assistant message). Minimal reproduction against the API returns the same 400 (req_011CegoQokuK2cP4bx7pw8FP). On pre-4.6 models the pattern was accidentally functional because the API accepted the prefill.Fix
Developer content merges only into a preceding plain user message. After an assistant message — or a tool_result — it opens a new user message, so recovery guidance reaches the model on the user turn and the request never ends on an assistant message.
Tests
expected "user", got "assistant"), pinning: developer-after-assistant opens a user message, the assistant message stays byte-identical to what the model produced, and the mapped conversation never ends on an assistant turn.claude-sonnet-5throughgenerate_handler(400 on master, passes with the fix).https://claude.ai/code/session_01GGANLtqTDCWHbSYmycvjpV