Three layered bugs caused OpenAI-compatible providers to silently
produce empty tool call arguments when max_tokens was hit mid-JSON:
1. FinishReason override: all providers unconditionally overwrote
"length" → "tool_calls" when tool calls existed, preventing the
agent loop's truncation guard from firing.
2. Silent parse failure: JSON unmarshal errors were logged but args
stayed as empty map with no signal to the caller.
3. No fallback for unreliable providers: some proxies don't emit
finish_reason:"length" at all, leaving no detection path.
Fixes:
- Add ParseError field to ToolCall struct for explicit error signal
- Guard FinishReason override with `!= "length"` in OpenAI, Codex
- Set ParseError in all provider parsers (OpenAI, Anthropic, Codex)
- Add hasParseErrors() fallback guard in agent loop for EC-5 scenario
- Cap consecutive truncation retries (maxTruncationRetries=3) to
prevent burning all iterations when max_tokens is persistently low
Closes#605