文件历史

2 次代码提交

作者 SHA1 备注 提交日期
Ali Khokhar 36bb282558 Recover Claude sessions from provider context overflow (#1215)
## Problem
NVIDIA NIM can report context exhaustion as a 400 `BadRequestError`
saying its derived `max_tokens` is negative. FCC treated that as a
generic invalid request, so Claude Code could not recognize the smaller
upstream context window, compact the conversation, and replay the
interrupted turn. LM Studio also encoded Claude's recovery phrase inside
provider code instead of reporting a protocol-neutral failure. Fixes
#1198.

## Changes
- Add one protocol-neutral `context_window_exceeded` execution failure
with a non-retryable 400 contract.
- Narrowly classify only NVIDIA NIM's negative derived-`max_tokens`
signature while preserving the complete redacted provider diagnostic and
request ID.
- Let the Anthropic serializer alone add Claude's `prompt is too long`
compaction trigger; OpenAI Responses keeps a standard invalid-request
envelope.
- Migrate LM Studio's existing context preflight to the same neutral
semantic and document the ownership boundary.
- Add provider, protocol, API, trace, near-miss, and real Claude
compaction/replay coverage; bump FCC to 4.11.4.

| Before | After |
| --- | --- |
| Context overflow appeared as an ordinary provider 400 and ended the
Claude turn. | Claude receives a typed 400 with its recognized
compaction trigger, compacts once, and replays the interrupted turn
without an FCC or SDK retry loop. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR adds protocol-neutral recovery from provider context-window
exhaustion. The main changes are:

- Classify NVIDIA NIM negative derived-`max_tokens` errors as
context-window failures.
- Move Claude's compaction trigger into the Anthropic serializer.
- Migrate LM Studio context preflight to the neutral failure type.
- Preserve the standard OpenAI Responses invalid-request envelope.
- Add provider, protocol, API, trace, and recovery tests.
- Bump the package version to 4.11.4.
</details>

<h3>Confidence Score: 5/5</h3>

This looks safe to merge.

- No blocking issues found in the changed code.
- The new failure kind is covered by both protocol mappings.
- Provider classification remains narrow and non-retryable.
- The protocol-specific compaction phrase stays at the Anthropic
boundary.

<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 narrow pytest command from /home/user/repo without live
provider credentials or services, and observed a clean test run with all
tests passing.

<a
href="https://app.greptile.com/trex/runs/15073403/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 |
|----------|----------|
| src/free_claude_code/providers/nvidia_nim/client.py | Adds narrow
context-window classification for nested and top-level NVIDIA NIM error
bodies. |
| src/free_claude_code/providers/lmstudio/client.py | Migrates
context-budget preflight failures to the canonical context-window
failure. |
| src/free_claude_code/core/anthropic/errors.py | Adds Anthropic mapping
and injects Claude's compaction phrase at the wire boundary. |
| src/free_claude_code/core/openai_responses/errors.py | Maps context
exhaustion to the standard OpenAI invalid-request error. |
| src/free_claude_code/providers/failure_policy.py | Adds the canonical
non-retryable status-400 context-window failure factory. |
| src/free_claude_code/core/failures.py | Adds the protocol-neutral
context-window failure category. |

</details>

<details open><summary><h3>Flowchart</h3></summary>

<a href="#gh-light-mode-only">

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Provider detects context exhaustion] --> B[Context-window ExecutionFailure]
B --> C{Protocol adapter}
C -->|Anthropic Messages| D[400 invalid_request_error]
D --> E[Add prompt is too long trigger]
E --> F[Claude compacts and replays]
C -->|OpenAI Responses| G[400 invalid_request_error]
G --> H[Keep neutral provider message]
```

</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"}}}%%
flowchart TD
A[Provider detects context exhaustion] --> B[Context-window ExecutionFailure]
B --> C{Protocol adapter}
C -->|Anthropic Messages| D[400 invalid_request_error]
D --> E[Add prompt is too long trigger]
E --> F[Claude compacts and replays]
C -->|OpenAI Responses| G[400 invalid_request_error]
G --> H[Keep neutral provider message]
```

</a>
</details>

<sub>Reviews (1): Last reviewed commit: ["Normalize provider context
overflow for
..."](https://github.com/alishahryar1/free-claude-code/commit/29c89a4c1011d986284e9d163855174d1d433293)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=45603631)</sub>

<!-- /greptile_comment -->
2026-07-20 04:23:28 -07:00
Ali Khokhar e22a38b2c2 Canonicalize provider failure and retry ownership (#1046)
## Problem

Provider SDK classification, retry policy, canonical failures, and
downstream wire errors shared exception types across layers. That
blurred ownership and let cleanup or provisional Responses tool failures
mask the real provider diagnostic.

## Changes

| Before | After |
| --- | --- |
| Provider failures carried Anthropic wire types and core code
classified OpenAI/httpx errors. | Protocol-neutral `ExecutionFailure`
values cross layers, providers classify SDK errors, and protocol
packages map wire types. |
| Provider adapters could author terminal wire events. | The HTTP commit
boundary selects non-2xx JSON or a protocol terminal event with one
ingress request ID. |
| Retry policy and diagnostic handling were spread across core and
provider modules. | Providers own the unchanged retry budgets while
neutral core utilities own bounded credential redaction. |
| Stream cleanup could replace an already-mapped provider failure. |
Cleanup records safe metadata and preserves the canonical failure,
status, and diagnostic. |
| An incomplete Responses tool could preempt a later provider failure. |
Tool-finalization errors remain provisional so canonical provider
failures take precedence. |
| Readiness failures reused provider exception types. |
Application-owned errors represent deterministic validation and
availability phases without terminal retry headers. |
| Legacy exception and recovery owners remained importable. | Obsolete
modules are deleted without shims, architecture rules enforce the
boundaries, and package version is 3.4.21. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR canonicalizes provider failure handling across the API boundary.
The main changes are:

- Adds protocol-neutral execution failure values and safe diagnostics.
- Moves SDK and HTTP failure classification into provider-owned policy.
- Lets Messages and Responses choose their own wire error payloads.
- Preserves canonical failures across stream cleanup and committed
stream failures.
- Makes incomplete Responses tool errors provisional until finalization.
</details>

<h3>Confidence Score: 5/5</h3>

This looks safe to merge.

No blocking issues found in the changed code.

No files need 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 API failure contract suite and related tests
(tests/api/test\_execution\_failure\_contract.py,
tests/core/test\_failure\_protocol\_mapping.py,
tests/providers/test\_execution\_failure\_boundary.py,
tests/providers/test\_failure\_policy.py); 48 passed in 3.36s.
- Ran the streaming boundaries tests including response streams, stream
recovery, and streaming errors; 70 passed in 5.36s.
- Ran the OpenAI responses tests; 20 passed in 4.42s.

<a
href="https://app.greptile.com/trex/runs/14071383/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 |
|----------|----------|
| src/free_claude_code/providers/transports/http.py | Adds cleanup-safe
stream closing that preserves established outcomes. |
| src/free_claude_code/core/openai_responses/stream.py | Preserves
canonical execution failures when committed Responses streams fail. |
| src/free_claude_code/core/openai_responses/streaming/assembler.py |
Keeps malformed tool-call errors provisional so later provider failures
can win. |
| src/free_claude_code/core/failures.py | Defines neutral failure kinds
and exception-group lookup for execution failures. |

</details>

<sub>Reviews (2): Last reviewed commit: ["Preserve canonical outcomes in
grouped
a..."](https://github.com/alishahryar1/free-claude-code/commit/f57f21241dbe582985627ed4fb40734b2c656809)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=43468297)</sub>

<!-- /greptile_comment -->
2026-07-10 21:33:50 -07:00