When streaming responses with tool calls, the finish_reason was being
overwritten. The upstream sends functionCall in chunk 1, then
finishReason: STOP in chunk 2. The old code would set finish_reason
from every chunk, causing "tool_calls" to be overwritten by "stop".
This broke clients like Claude Code that rely on finish_reason to
detect when tool calls are complete.
Changes:
- Add SawToolCall bool to track tool calls across entire stream
- Add UpstreamFinishReason to cache the finish reason
- Only emit finish_reason on final chunk (has both finishReason + usage)
- Priority: tool_calls > max_tokens > stop
Includes 5 unit tests covering:
- Tool calls not overwritten by subsequent STOP
- Normal text gets "stop"
- MAX_TOKENS without tool calls gets "max_tokens"
- Tool calls take priority over MAX_TOKENS
- Intermediate chunks have no finish_reason
Fixes streaming tool call detection for Claude Code + Gemini models.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced node structure by including `thoughtSignature` for inline data parts in Gemini OpenAI, Gemini CLI, and Antigravity request handlers to improve traceability of thought processes.
Fixed incorrect boundary logic for `message_delta` emission, ensuring proper handling of usage updates and `emitMessageStopIfNeeded` within the response loop.
Remove dead code that was never used:
- toolCallIDToName map: built but never read from
- seenToolCallIDs: declared but never populated, only suppressed with _
Fix three issues in Kiro OpenAI translator that caused "Improperly formed request"
errors when processing LiteLLM-translated requests with tool_use/tool_result:
1. Skip merging tool role messages in MergeAdjacentMessages() to preserve
individual tool_call_id fields
2. Track pendingToolResults and attach to the next user message instead of
only the last message. Create synthetic user message when conversation
ends with tool results.
3. Insert synthetic user message with tool results before assistant messages
to maintain proper alternating user/assistant structure. This fixes the case
where LiteLLM translates Anthropic user messages containing only tool_result
blocks into tool role messages followed by assistant.
Adds unit tests covering all tool result handling scenarios.
Updated Antigravity, Gemini, and Gemini-CLI translators to process `systemResult` of type `string` for system instructions. Ensures properly formatted JSON with dynamic content assignment.
fix(antigravity): validate function arguments before serialization
Ensure `function.arguments` is a valid JSON before setting raw bytes, fallback to setting as parameterized content if invalid.