Skip to content

feat: harden LLM API fault tolerance against 429 and overload - #1530

Merged
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/llm-retry-fault-tolerance
Jul 10, 2026
Merged

feat: harden LLM API fault tolerance against 429 and overload#1530
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/llm-retry-fault-tolerance

Conversation

@sailist

@sailist sailist commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — see Problem.

Problem

In long-running eval runs, a kimi-code run could die mid-rollout when the provider returned a 429 / overload / stream interruption, surfacing as an unfinished turn ("API error occurred at step N") and triggering far more container-level retries than a peer harness against the same model and backend. The OpenAI path (a) did not retry several transient errors, (b) used a small backoff budget that gave up long before an overloaded engine recovered, and (c) ignored the server Retry-After, whereas that peer harness absorbs these in place.

What changed

  • Retry more transient errors: 408/409/429/5xx/529 are now retried; an embedded upstream status_code=429 in OpenAI Responses stream error text is treated as a rate limit; and any unclassified provider error is retried as a last-resort fallback instead of failing the run on the first error.
  • Honor Retry-After and align the backoff with the reference CLI: the OpenAI and Anthropic providers parse the response Retry-After header into the error and the retry loop prefers it over its own delay; the app backoff is now 500ms base / 32s cap / factor 2 / up to 25% jitter, so high-attempt configs ride out multi-minute overload.
  • Surface retries in stream-json: -p --output-format stream-json now emits a turn.step.retrying meta line so consumers can observe retries.

Request timeout is unchanged (the OpenAI SDK default of 600s already matches the reference CLI's default). Deterministic 4xx (auth, not-found, bad-request) are intentionally still not retried.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

sailist added 2 commits July 10, 2026 12:35
- retry more transient errors: 408/409/429/5xx/529, an embedded upstream
  status_code=429 in OpenAI Responses stream errors, and unclassified
  provider errors as a last-resort fallback
- honor server Retry-After (parsed into APIStatusError.retryAfterMs by the
  OpenAI and Anthropic providers); chatWithRetry prefers it over its backoff
- align app-level backoff with claude-code (500ms base, 32s cap, factor 2,
  up to 25% jitter) so high-attempt configs ride out multi-minute overload
- emit a turn.step.retrying meta line in -p --output-format stream-json
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5205322

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 10, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@5205322
npx https://pkg.pr.new/@moonshot-ai/kimi-code@5205322

commit: 5205322

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ef159dc99

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// (400/401/403/404/422) and the recovery-owned context-overflow /
// request-too-large subclasses keep their dedicated handling instead of
// burning retries first.
return error instanceof ChatProviderError;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid retrying all base ChatProviderError failures

Because ChatProviderError is also used for deterministic preflight/serialization failures (for example missing API keys in requireProviderApiKey and unrecognized OpenAI Responses stream errors in errorFromOpenAIResponsesEvent), this fallback now makes non-transient 4xx/config errors retryable. With a high max_retries_per_step, the new 32s-capped backoff can delay surfacing bad auth or bad-request failures for minutes, contrary to the intended deterministic-4xx behavior; use a distinct transient wrapper or status-gate the gateway fallback instead of retrying every base provider error.

Useful? React with 👍 / 👎.

// Mirrors claude-code's retryable statuses: 408 (request timeout), 409
// (lock/conflict timeout), 429 (rate limit), 5xx (server errors) and 529
// (provider overloaded — the "engine is currently overloaded" case).
return [408, 409, 429, 500, 502, 503, 504, 529].includes(error.statusCode);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Retry the whole 5xx status range

The new behavior is documented here as retrying 5xx, but the predicate still enumerates only 500/502/503/504 plus 529. Providers and gateways commonly use other server-side 5xx statuses such as 520, 522, or 524; those still become APIStatusError instances and will fail immediately instead of entering the retry path this change is adding.

Useful? React with 👍 / 👎.

@sailist
sailist merged commit 9f66ec4 into MoonshotAI:main Jul 10, 2026
11 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant