fix(llm): remove package retry policy (#35003)

This commit is contained in:
Aiden Cline 2026-07-02 15:51:12 -05:00 committed by GitHub
commit 460cdc5aec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 77 additions and 244 deletions

View file

@ -1,4 +1,4 @@
import { Cause, Context, Effect, Layer, Random } from "effect"
import { Cause, Context, Effect, Layer } from "effect"
import {
FetchHttpClient,
Headers,
@ -33,9 +33,6 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/LLM/RequestExecutor") {}
const BODY_LIMIT = 16_384
const MAX_RETRIES = 2
const BASE_DELAY_MS = 500
const MAX_DELAY_MS = 10_000
const REDACTED = "<redacted>"
// One source of truth for what counts as a sensitive name across headers,
@ -88,7 +85,7 @@ const requestId = (headers: Record<string, string>) => {
)
}
const retryableStatus = (status: number) => status === 429 || status === 503 || status === 504 || status === 529
const providerInternalStatus = (status: number) => status === 429 || status === 503 || status === 504 || status === 529
const retryAfterMs = (headers: Record<string, string>) => {
const millis = Number(headers["retry-after-ms"])
@ -263,7 +260,7 @@ const statusReason = (input: {
http: input.http,
})
}
if (input.status >= 500 || retryableStatus(input.status)) {
if (input.status >= 500 || providerInternalStatus(input.status)) {
return new ProviderInternalReason({
message: input.message,
status: input.status,
@ -342,27 +339,6 @@ const toHttpError = (redactedNames: ReadonlyArray<string | RegExp>) => (error: u
})
}
const retryDelay = (error: LLMError, attempt: number) => {
if (error.retryAfterMs !== undefined) return Effect.succeed(Math.min(error.retryAfterMs, MAX_DELAY_MS))
return Random.nextBetween(
Math.min(BASE_DELAY_MS * 2 ** attempt * 0.8, MAX_DELAY_MS),
Math.min(BASE_DELAY_MS * 2 ** attempt * 1.2, MAX_DELAY_MS),
).pipe(Effect.map((delay) => Math.round(delay)))
}
const retryStatusFailures = <A, R>(
effect: Effect.Effect<A, LLMError, R>,
retries = MAX_RETRIES,
attempt = 0,
): Effect.Effect<A, LLMError, R> =>
Effect.catchTag(effect, "LLM.Error", (error): Effect.Effect<A, LLMError, R> => {
if (!error.retryable || retries <= 0) return Effect.fail(error)
return retryDelay(error, attempt).pipe(
Effect.flatMap((delay) => Effect.sleep(delay)),
Effect.flatMap(() => retryStatusFailures(effect, retries - 1, attempt + 1)),
)
})
export const layer: Layer.Layer<Service, never, HttpClient.HttpClient> = Layer.effect(
Service,
Effect.gen(function* () {
@ -375,7 +351,7 @@ export const layer: Layer.Layer<Service, never, HttpClient.HttpClient> = Layer.e
.pipe(Effect.mapError(toHttpError(redactedNames)), Effect.flatMap(statusError(request, redactedNames)))
})
return Service.of({
execute: (request) => retryStatusFailures(executeOnce(request)),
execute: executeOnce,
})
}),
)