Skip to content

Commit 12ac012

Browse files
Fix exponential backoff for provider: {anthropic,openai}
Exponential backoff was broken for anthropic. The reason is that ParseError() returned a plain Error with no .response property. withExponentialBackoff() only triggers the backoff logic when when error.response?.status == 429. Without that property, it immediately rethrows the error. With this fix, it correctly backs off on an HTTP 429 error. `provider: openai` bypasses BaseLLM.fetch() and uses the openai SDK. Fix the tests so that they pass again. Some APIs have a per minute rate-limt, so increase the max retries in both codepaths to 8 so that it it retries up to 127.5s until it fails.
1 parent cb27309 commit 12ac012

3 files changed

Lines changed: 9 additions & 6 deletions

File tree

core/llm/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,11 @@ export abstract class BaseLLM implements ILLM {
460460
);
461461
}
462462
}
463-
return new Error(
463+
const error = new Error(
464464
`HTTP ${resp.status} ${resp.statusText} from ${resp.url}\n\n${text}`,
465-
);
465+
) as any;
466+
error.response = resp;
467+
return error;
466468
}
467469

468470
fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response> {
@@ -543,7 +545,7 @@ export abstract class BaseLLM implements ILLM {
543545
};
544546
return withExponentialBackoff<Response>(
545547
() => customFetch(url, init) as any,
546-
5,
548+
8,
547549
0.5,
548550
);
549551
}

core/util/withExponentialBackoff.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
RETRY_AFTER_HEADER,
77
} from "./withExponentialBackoff";
88

9-
describe.skip("withExponentialBackoff", () => {
9+
describe("withExponentialBackoff", () => {
1010
it("should return result when apiCall succeeds on first attempt", async () => {
1111
// Arrange
1212
const apiCall = jest.fn().mockResolvedValue("Success");
@@ -112,7 +112,7 @@ describe.skip("withExponentialBackoff", () => {
112112
// Act & Assert
113113
await expect(
114114
withExponentialBackoff(apiCall, maxTries, initialDelaySeconds),
115-
).rejects.toThrow("Failed to make API call after max tries");
115+
).rejects.toThrow(`Failed to make API call after ${maxTries} retries`);
116116

117117
expect(apiCall).toHaveBeenCalledTimes(maxTries);
118118
});
@@ -135,7 +135,7 @@ describe.skip("withExponentialBackoff", () => {
135135

136136
await expect(
137137
withExponentialBackoff(apiCall, maxTries, initialDelaySeconds),
138-
).rejects.toThrow("Failed to make API call after max tries");
138+
).rejects.toThrow(`Failed to make API call after ${maxTries} retries`);
139139

140140
expect(apiCall).toHaveBeenCalledTimes(0);
141141
});

packages/openai-adapters/src/apis/OpenAI.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export class OpenAIApi implements BaseLlmApi {
4646
baseURL: this.apiBase,
4747
fetch: customFetch(config.requestOptions),
4848
timeout: config?.requestOptions?.timeout || undefined,
49+
maxRetries: 8,
4950
});
5051
}
5152
modifyChatBody<T extends ChatCompletionCreateParams>(body: T): T {

0 commit comments

Comments
 (0)