fix(opencode): classify OpenRouter's typeless 502 overflow chunk as ContextOverflowError
Description
Fixes USE-2673.
When the model's context fills up behind OpenRouter, OpenRouter does not fail the HTTP request. It relays the upstream overflow as a mid-stream chunk with no type field:
{ "code": 502, "message": "Your input exceeds the context window of this model. Please adjust your input and try again.", "metadata": { "error_type": "provider_unavailable" } }
parseStreamError gated everything on body.type === "error", so this chunk returned undefined, fromError fell through to UnknownError with the JSON stringified into message, and the processor treated the turn as a generic failure. Users saw "Something went wrong" with a Retry button that re-sent the same oversized prompt: prod shows ten identical failures in three minutes for one session.
The overflow text patterns in @opencode-ai/llm already match this message, but only ran on the APICallError branch. This PR checks the message text (at error.message or top-level message) against those patterns before the type gate, and folds the existing context_length_exceeded case into the same check so overflow is classified in one place.
Now the chunk becomes ContextOverflowError, which the processor already handles: it flags needsCompaction, compacts once, and replays the prompt (converging per #41) instead of surfacing an opaque error.
Shipping this to the fleet needs a fork release tag and an OPENCODE_VERSION bump in apps/daytona-snapshot/Dockerfile in andytown.
Testing
TODO
🤖 Generated with Claude Code
Summary by cubic
Fixes OpenRouter's typeless 502 overflow chunks showing up as a generic "Something went wrong" error. These chunks now classify as ContextOverflowError, so the existing compaction and prompt-replay path runs instead of a Retry that re-sends the oversized prompt.
parseStreamErrorno longer requiresbody.type === "error"to match overflow message text; thecontext_length_exceededcode check is folded into the same pre-gate match.- Adds a regression test for the typeless chunk shape.
- Shipping needs a fork release tag and an
OPENCODE_VERSIONbump inapps/daytona-snapshot/Dockerfile.