Claude Code sends the system prompt as the top-level `system` field and,
separately, sends skill/plugin listings as `role: "system"` entries inside
`messages` (#1459 made the transformer accept those). `transform()`
unconditionally prepends the top-level field, so once both are present the
OpenAI-compat payload ends up with two `system` messages that are not
adjacent. `coalesceMessages` only merges consecutive same-role messages and
explicitly skips `system`, so it cannot fix this.
Strict OpenAI-compatible backends (LiteLLM among them) reject that shape with:
400 A 'system' message can only appear at index 0 of the messages array.
Add `hoistSystemMessages`, run before `coalesceMessages`, which extracts every
`system` message in encounter order and reinserts a single merged one at
index 0. Content-preserving, no behavior change when at most one system
message is present.
Claude Code's status line and the session log showed 0 tokens for every
streaming response routed through the OpenAI-compatible proxy. The root
cause was that the upstream request did not include
`stream_options: { include_usage: true }`, so the provider (LiteLLM and
other OpenAI-compatible endpoints) never emitted the final SSE chunk
that carries `usage`. The proxy's stream parser was already wired to
forward that chunk into an Anthropic-shaped `message_delta` event but
had nothing to forward.
Set `stream_options.include_usage` whenever the incoming Anthropic
request is streamed. Non-streamed requests are unaffected.
Ref: https://platform.openai.com/docs/api-reference/chat-streaming
(search 'include_usage')
- reject pending tool_result layouts that cannot be translated without reordering user content
- keep interleaved GLMT tool_use blocks open until finalization instead of stopping early
- cover leading/interleaved tool_result regressions and interleaved streaming tool fragments
- enforce strict tool_result ordering and pairing against assistant tool_use ids
- reject tool_result image payloads that cannot map to OpenAI tool messages
- preserve raw tool schemas on the /v1/messages proxy path instead of silently tightening them
- forward Anthropic tool_choice semantics and cover adaptive routing plus upstream payload checks