fix: don't insert relocated system text before tool_result blocks - #257
fix: don't insert relocated system text before tool_result blocks#257darknessest wants to merge 1 commit into
Conversation
Anthropic requires tool_result blocks to be the leading content of the message that follows a tool_use. Unshifting the relocated system prompt text in front of them makes the API reject the request with "tool_use ids were found without tool_result blocks immediately after". Compaction requests are the common victim: their first user message is the tool_result carrier for a leading assistant tool_use turn.
|
Independent repro, same root cause. opencode 1.18.11 auto-compaction anchored its tail on an assistant (ids can be OpenAI-style when earlier turns in the session ran on a non-Anthropic model — the transform is id-agnostic, so it reproduces either way.) Confirmed the failure loops on every compaction retry until the tail boundary shifts. Applied this branch locally (merged onto 2.1.5), transforms suite passes 43/43 incl. the new regression test, and compaction works again. Would be good to get this out of draft. |
|
@griffinmartin LGTM, confirming this fixes a real failure One small nit, optional chaining on the block lookup :213 |
While chasing recurring 400s from Anthropic during opencode's session compaction, I traced it back to the system-prompt relocation in
transformBody.What happens: when the request's first user message carries
tool_resultblocks (which is the norm for compaction requests — their history often starts with an assistanttool_useturn), the relocated system text getsunshifted in front of the results. Anthropic wants tool_results to be the leading blocks of the message that follows atool_use, so it rejects the whole request:Regular chat requests never hit this (their first user message is plain text), which makes it look like a mysterious compaction-only failure. It also keeps re-failing on every auto-compaction retry until the tail boundary happens to shift, so sessions get stuck in an error loop near the context limit.
Repro/verification: captured a failing compaction request from a live session, replayed it against the API — 400 with the exact error above. Moved the injected text block after the tool_results, replayed again — 200. That one-block reorder is this patch.
Fix: insert the relocated text after any leading
tool_resultblocks instead of always at index 0. Added a regression test.Marking as draft since I only exercised the compaction path against the real API — happy to adjust if you'd rather relocate into a different message entirely.