diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..a464b26b8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + lint: + name: lint + runs-on: ubuntu-latest + if: github.repository == 'openai/openai-node' + + steps: + - uses: actions/checkout@v3 + + - name: Set up Node + uses: actions/setup-node@v3 + with: + node-version: '16' + + - name: Install dependencies + run: | + yarn install + + - name: Check types + run: | + yarn build diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4750060f4..898c7258c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.13.0" + ".": "4.14.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index a84c16a20..46e2b5e87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 4.14.0 (2023-10-25) + +Full Changelog: [v4.13.0...v4.14.0](https://github.com/openai/openai-node/compare/v4.13.0...v4.14.0) + +### Features + +* **client:** adjust retry behavior to be exponential backoff ([#400](https://github.com/openai/openai-node/issues/400)) ([2bc14ce](https://github.com/openai/openai-node/commit/2bc14ce300ef020bc045199fe3d76dd352d78ef9)) + + +### Chores + +* **docs:** update deno version ([#399](https://github.com/openai/openai-node/issues/399)) ([cdee077](https://github.com/openai/openai-node/commit/cdee0770690d4b66b357d970827e9ba1597ffb89)) + ## 4.13.0 (2023-10-22) Full Changelog: [v4.12.4...v4.13.0](https://github.com/openai/openai-node/compare/v4.12.4...v4.13.0) diff --git a/README.md b/README.md index dbc3c698b..c54a8df75 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,14 @@ yarn add openai You can import in Deno via: + + ```ts -import OpenAI from 'https://raw.githubusercontent.com/openai/openai-node/v4.12.4-deno/mod.ts'; +import OpenAI from 'https://raw.githubusercontent.com/openai/openai-node/v4.13.0-deno/mod.ts'; ``` + + ## Usage The full API of this library can be found in [api.md file](https://github.com/openai/openai-node/blob/master/api.md). The code below shows how to get started using the chat completions API. diff --git a/package.json b/package.json index 64da4e85d..c4e9f1f8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.13.0", + "version": "4.14.0", "description": "Client library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/core.ts b/src/core.ts index 75cb120c6..4cf238457 100644 --- a/src/core.ts +++ b/src/core.ts @@ -27,8 +27,6 @@ export { type Uploadable, } from './uploads'; -const MAX_RETRIES = 2; - export type Fetch = (url: RequestInfo, init?: RequestInit) => Promise; type PromiseOrValue = T | Promise; @@ -162,7 +160,7 @@ export abstract class APIClient { constructor({ baseURL, - maxRetries, + maxRetries = 2, timeout = 600000, // 10 minutes httpAgent, fetch: overridenFetch, @@ -174,7 +172,7 @@ export abstract class APIClient { fetch: Fetch | undefined; }) { this.baseURL = baseURL; - this.maxRetries = validatePositiveInteger('maxRetries', maxRetries ?? MAX_RETRIES); + this.maxRetries = validatePositiveInteger('maxRetries', maxRetries); this.timeout = validatePositiveInteger('timeout', timeout); this.httpAgent = httpAgent; @@ -513,8 +511,6 @@ export abstract class APIClient { retriesRemaining: number, responseHeaders?: Headers | undefined, ): Promise { - retriesRemaining -= 1; - // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After let timeoutMillis: number | undefined; const retryAfterHeader = responseHeaders?.['retry-after']; @@ -540,22 +536,22 @@ export abstract class APIClient { } await sleep(timeoutMillis); - return this.makeRequest(options, retriesRemaining); + return this.makeRequest(options, retriesRemaining - 1); } private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number { const initialRetryDelay = 0.5; - const maxRetryDelay = 2; + const maxRetryDelay = 8.0; const numRetries = maxRetries - retriesRemaining; // Apply exponential backoff, but not more than the max. - const sleepSeconds = Math.min(initialRetryDelay * Math.pow(numRetries - 1, 2), maxRetryDelay); + const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay); - // Apply some jitter, plus-or-minus half a second. - const jitter = Math.random() - 0.5; + // Apply some jitter, take up to at most 25 percent of the retry time. + const jitter = 1 - Math.random() * 0.25; - return (sleepSeconds + jitter) * 1000; + return sleepSeconds * jitter * 1000; } private getUserAgent(): string { diff --git a/src/version.ts b/src/version.ts index aa60823c4..ddc4bbe90 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.13.0'; // x-release-please-version +export const VERSION = '4.14.0'; // x-release-please-version diff --git a/tests/index.test.ts b/tests/index.test.ts index 192d26c6c..f54ea5cfc 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -135,8 +135,8 @@ describe('instantiate client', () => { }); test('maxRetries option is correctly set', () => { - const client = new OpenAI({ maxRetries: 1, apiKey: 'My API Key' }); - expect(client.maxRetries).toEqual(1); + const client = new OpenAI({ maxRetries: 4, apiKey: 'My API Key' }); + expect(client.maxRetries).toEqual(4); // default const client2 = new OpenAI({ apiKey: 'My API Key' });