fix: resolve Claude 4.6 assistant prefill compatibility issues#16883
fix: resolve Claude 4.6 assistant prefill compatibility issues#16883hsuanguo wants to merge 1 commit intoanomalyco:devfrom
Conversation
This commit addresses two root causes of the 'This model does not support assistant message prefill' error that occurs with Claude Opus 4.6 and Sonnet 4.6 models: 1. Max steps message role (prompt.ts:670) - Changed from assistant to user role for MAX_STEPS instruction - Claude 4.6 rejects conversations ending with assistant messages - User role maintains instruction delivery while ensuring compatibility 2. Agentic loop exit condition (prompt.ts:322) - Replaced timestamp-based ID comparison with explicit parentID check - Previous: lastUser.id < lastAssistant.id (vulnerable to clock skew) - Fixed: lastAssistant.parentID === lastUser.id (clock-skew resistant) - Prevents extra assistant messages when client/server clocks differ Fixes anomalyco#13768
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
|
The following comment was made by an LLM, it may be inaccurate: I found related PRs that are relevant to the current PR: Related PRs:
|
|
This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window. Feel free to open a new pull request that follows our guidelines. |
Summary
Fixes #13768 - Resolves the "This model does not support assistant message prefill" error that occurs with Claude Opus 4.6 and Sonnet 4.6 models across all providers (Anthropic, GitHub Copilot, OpenRouter, etc.).
This PR addresses two distinct root causes with targeted, surgical fixes:
1. Max Steps Message Role (
prompt.ts:670)Problem: When the maximum step limit is reached, opencode appends an assistant message containing
MAX_STEPSinstructions. Claude 4.6 rejects any conversation ending with an assistant message.Fix: Changed the role from
assistanttouserfor the MAX_STEPS instruction.2. Agentic Loop Exit Condition (
prompt.ts:322)Problem: The loop exit condition used timestamp-based ID comparison (
lastUser.id < lastAssistant.id) to determine if the assistant had responded to the user. When client clocks run ahead of server clocks, this comparison fails, causing the loop to create an extra assistant message that becomes the final message in the array.Fix: Replaced ID comparison with explicit parent-child relationship check (
lastAssistant.parentID === lastUser.id).parentIDfield that tracks which user message an assistant is responding toChanges
packages/opencode/src/session/prompt.ts(2 lines changed)Testing
Context
Previous PR #14772 attempted to fix this with a safety net approach (
stripTrailingAssistant()) but was correctly identified as hiding the real bugs rather than fixing them. This PR implements proper root-cause fixes instead.Credit to @nguquen for identifying the clock-skew issue in this comment.