1 Commits
Author SHA1 Message Date
viettranx a565ad8402 fix: preserve FinishReason on truncated tool calls + ParseError propagation (#605)
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
2026-03-31 14:33:33 +07:00