mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-07-10 00:14:16 +00:00
## Problem
OpenAI-chat providers lost explicit empty reasoning state and could
replay invalid tool-call history when unrelated messages appeared before
matching tool results.
## Changes
| Before | After |
| --- | --- |
| Empty `reasoning_content` and empty thinking blocks were treated as
absent. | Empty reasoning is preserved as explicit replay state. |
| OpenAI-chat conversion only deferred post-tool assistant text. |
OpenAI-chat conversion buffers later transcript messages until required
tool results are emitted. |
| Responses prior tool calls and outputs were emitted one item per
message. | Responses prior tool calls and outputs are grouped into valid
Anthropic tool-use/result messages. |
| Empty streamed `reasoning_content` produced no thinking block. | Empty
streamed `reasoning_content` starts thinking state without visible delta
text. |
<!-- greptile_comment -->
<details open><summary><h3>Greptile Summary</h3></summary>
This PR fixes OpenAI chat reasoning replay and tool-history ordering.
The main changes are:
- Preserves explicit empty `reasoning_content` and empty thinking
blocks.
- Reworks OpenAI chat conversion around a ledger that waits for required
tool results before replaying buffered transcript messages.
- Groups prior Responses tool calls and outputs into valid Anthropic
tool-use and tool-result messages.
- Starts streamed thinking state when empty `reasoning_content` is
received.
- Adds focused tests for nested tool turns, out-of-order results,
multi-tool replay, and empty reasoning.
</details>
<h3>Confidence Score: 5/5</h3>
Safe to merge with low risk.
No blocking issues were found in the changed conversion paths. The
updated ledger covers the prior invalid replay cases and the tests
include nested, out-of-order, multi-tool, and empty reasoning scenarios.
The required patch version and lockfile updates are present.
No files require special attention.
<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>
**What T-Rex did**
- Ran the focused OpenAI conversion regression suite with Pytest,
capturing the command, working directory, pass count, exit code, and
elapsed time.
- Encountered an external timeout during the initial Pytest run at 98%
progress, then re-ran the same focused suite to completion for
definitive proof.
- Validated code quality with Ruff by executing the lint command and
obtaining a successful output.
<a
href="https://app.greptile.com/trex/runs/13503694/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>
<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>
<details open><summary><h3>Important Files Changed</h3></summary>
| Filename | Overview |
|----------|----------|
| core/anthropic/conversion.py | Replaces single pending-tool state with
a ledger that buffers transcript segments until required OpenAI chat
tool results can be emitted in valid order. |
| core/openai_responses/input.py | Groups consecutive prior Responses
tool calls/results into Anthropic tool-use/result turns and preserves
explicit empty reasoning. |
| core/openai_responses/reasoning.py | Updates reasoning extraction and
combination helpers so empty strings remain explicit replay state
without adding spurious separators. |
| providers/deepseek/compat.py | Treats empty top-level or block-level
thinking as replayable when detecting DeepSeek tool-history
compatibility. |
| providers/transports/openai_chat/stream.py | Starts an Anthropic
thinking block for empty streamed `reasoning_content` while only
emitting deltas for non-empty text. |
| tests/providers/test_converter.py | Adds OpenAI chat conversion
coverage for buffered tool history, nested pending tool turns, and
explicit empty reasoning. |
| tests/core/openai_responses/test_conversion.py | Adds Responses
conversion tests for grouped prior tool calls/results and empty
reasoning attachment. |
| pyproject.toml | Bumps the package patch version for the production
conversion fixes. |
| uv.lock | Keeps the lockfile package version in sync with
`pyproject.toml`. |
</details>
<details open><summary><h3>Sequence Diagram</h3></summary>
<a href="#gh-light-mode-only">
```mermaid
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant A as Anthropic transcript
participant L as OpenAI chat ledger
participant O as OpenAI chat history
A->>L: Assistant tool_use segment
L->>O: Emit assistant tool_calls
A->>L: Later plain user/assistant messages
L-->>L: Buffer until required tool_result ids arrive
A->>L: User tool_result blocks
L->>O: Emit matching role: tool results in tool_call order
L->>O: Emit deferred assistant post-tool content
L->>O: Drain buffered plain transcript messages
```
</a>
<a href="#gh-dark-mode-only">
```mermaid
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant A as Anthropic transcript
participant L as OpenAI chat ledger
participant O as OpenAI chat history
A->>L: Assistant tool_use segment
L->>O: Emit assistant tool_calls
A->>L: Later plain user/assistant messages
L-->>L: Buffer until required tool_result ids arrive
A->>L: User tool_result blocks
L->>O: Emit matching role: tool results in tool_call order
L->>O: Emit deferred assistant post-tool content
L->>O: Drain buffered plain transcript messages
```
</a>
</details>
<sub>Reviews (3): Last reviewed commit: ["Refactor OpenAI chat tool
history
replay"](
|
||
|---|---|---|
| .. | ||
| anthropic | ||
| openai_responses | ||
| __init__.py | ||
| rate_limit.py | ||
| trace.py | ||