Skip to content

Commit 61cd8e1

Browse files
committedAug 5, 2023
v4.0.0-beta.8
1 parent 347a227 commit 61cd8e1

40 files changed

+752
-699
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules
22
yarn-error.log
33
codegen.log
44
dist
5+
/deno
56
/*.tgz

‎.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
CHANGELOG.md
22
/ecosystem-tests
33
/node_modules
4+
/deno

‎README.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,15 @@ await openai.models.list({
230230
})
231231
```
232232

233-
## Status
233+
## Semantic Versioning
234234

235-
This package is in beta. Its internals and interfaces are not stable
236-
and subject to change without a major semver bump;
237-
please reach out if you rely on any undocumented behavior.
235+
This package generally attempts to follow [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
236+
237+
1. Changes that only affect static types, without breaking runtime behavior.
238+
2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
239+
3. Changes that we do not expect to impact the vast majority of users in practice.
240+
241+
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
238242

239243
We are keen for your feedback; please open an [issue](https://www.github.com/openai/openai-node/issues) with questions, bugs, or suggestions.
240244

‎build

+15-15
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@ set -exuo pipefail
33

44
node scripts/check-version.cjs
55

6-
yarn tsc
7-
86
# Build into dist and will publish the package from there,
97
# so that src/resources/foo.ts becomes <package root>/resources/foo.js
108
# This way importing from `"openai/resources/foo"` works
119
# even with `"moduleResolution": "node"`
1210

13-
rm -rf dist
14-
mkdir dist
11+
rm -rf dist; mkdir dist
1512
# Copy src to dist/src and build from dist/src into dist, so that
1613
# the source map for index.js.map will refer to ./src/index.ts etc
1714
cp -rp src README.md dist
@@ -23,10 +20,10 @@ done
2320
node scripts/make-dist-package-json.cjs > dist/package.json
2421

2522
# build to .js/.mjs/.d.ts files
26-
tsc-multi
23+
npm exec tsc-multi
2724
# copy over handwritten .js/.mjs/.d.ts files
2825
cp src/_shims/*.{d.ts,js,mjs} dist/_shims
29-
tsc-alias -p tsconfig.build.json
26+
npm exec tsc-alias -- -p tsconfig.build.json
3027
# we need to add exports = module.exports = OpenAI Node to index.js;
3128
# No way to get that from index.ts because it would cause compile errors
3229
# when building .mjs
@@ -37,19 +34,22 @@ node scripts/fix-index-exports.cjs
3734
# the same export default statement)
3835
cp dist/index.d.ts dist/index.d.mts
3936

37+
SED=(sed -i)
38+
if [[ "$OSTYPE" == "darwin"* ]]; then SED=(sed -i ''); fi
39+
4040
# strip out lib="dom" and types="node" references; these are needed at build time,
4141
# but would pollute the user's TS environment
4242
REFERENCE_SUBS='s/^ *\/\/\/ *<reference *lib="dom".*//g;s/^ *\/\/\/ *<reference *types="node".*//g'
43-
if [[ "$OSTYPE" == "darwin"* ]]; then
44-
find dist -type f -exec sed -i '' "${REFERENCE_SUBS}" {} +
45-
else
46-
find dist -type f -exec sed -i "${REFERENCE_SUBS}" {} +
47-
fi
43+
find dist -type f -exec "${SED[@]}" "${REFERENCE_SUBS}" {} +
4844

49-
yarn prettier --loglevel=warn --write .
45+
npm exec prettier -- --loglevel=warn --write .
5046

5147
# make sure that nothing crashes when we require the output CJS or
5248
# import the output ESM
53-
cd dist
54-
node -e 'require("openai")'
55-
node -e 'import("openai")' --input-type=module
49+
(cd dist && node -e 'require("openai")')
50+
(cd dist && node -e 'import("openai")' --input-type=module)
51+
52+
if command -v deno &> /dev/null && [ -e ./build-deno ]
53+
then
54+
./build-deno
55+
fi

‎ecosystem-tests/ts-browser-webpack/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const model = 'whisper-1';
9393

9494
const params = new URLSearchParams(location.search);
9595

96-
const client = new OpenAI({ apiKey: params.get('apiKey') ?? undefined });
96+
const client = new OpenAI({ apiKey: params.get('apiKey') ?? undefined, dangerouslyAllowBrowser: true });
9797

9898
async function typeTests() {
9999
// @ts-expect-error this should error if the `Uploadable` type was resolved correctly

‎examples/azure.ts

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env yarn tsn -T
1+
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI from 'openai';
44

‎examples/demo.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env yarn tsn -T
1+
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI from 'openai';
44

‎examples/errors.ts

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env yarn tsn -T
1+
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI, { NotFoundError } from 'openai';
44

‎examples/fine-tunes.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env yarn tsn -T
1+
#!/usr/bin/env -S npm run tsn -T
22

33
/**
44
* Fine-tuning allows you to train models on your own data.

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openai",
3-
"version": "4.0.0-beta.7",
3+
"version": "4.0.0-beta.8",
44
"description": "Client library for the OpenAI API",
55
"author": "OpenAI <support@openai.com>",
66
"types": "dist/index.d.ts",
@@ -91,6 +91,7 @@
9191
"jest": "^29.4.0",
9292
"prettier": "rattrayalex/prettier#postfix-ternaries",
9393
"ts-jest": "^29.1.0",
94+
"ts-morph": "^19.0.0",
9495
"ts-node": "^10.5.0",
9596
"tsc-alias": "^1.8.6",
9697
"tsc-multi": "^1.1.0",

‎src/_shims/ReadableStream.d.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3+
*/
4+
5+
/**
6+
* >>> Confused? <<<
7+
*
8+
* If you're getting errors from these types, try adding "lib": ["DOM"]
9+
* to your tsconfig.json, or otherwise configure the appropriate builtin
10+
* `ReadableStream` type for your environment.
11+
*/
12+
13+
// @ts-ignore
14+
type _ReadableStream<R = any> = unknown extends ReadableStream ? never : ReadableStream<R>;
15+
declare const _ReadableStream: {
16+
prototype: _ReadableStream;
17+
new (
18+
underlyingSource: _UnderlyingByteSource,
19+
strategy?: { highWaterMark?: number },
20+
): _ReadableStream<Uint8Array>;
21+
new <R = any>(
22+
underlyingSource: _UnderlyingDefaultSource<R>,
23+
strategy?: _QueuingStrategy<R>,
24+
): _ReadableStream<R>;
25+
new <R = any>(underlyingSource?: _UnderlyingSource<R>, strategy?: _QueuingStrategy<R>): _ReadableStream<R>;
26+
};
27+
28+
// @ts-ignore
29+
type _UnderlyingSource<R = any> = unknown extends UnderlyingSource ? never : UnderlyingSource<R>;
30+
// @ts-ignore
31+
type _UnderlyingByteSource = unknown extends UnderlyingByteSource ? never : UnderlyingByteSource;
32+
type _UnderlyingDefaultSource<R = any> =
33+
// @ts-ignore
34+
unknown extends UnderlyingDefaultSource ? never : UnderlyingDefaultSource<R>;
35+
// @ts-ignore
36+
type _QueuingStrategy<R = any> = unknown extends QueuingStrategy ? never : QueuingStrategy<R>;
37+
38+
export { _ReadableStream as ReadableStream };

‎src/_shims/ReadableStream.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3+
*/
4+
5+
exports.ReadableStream = ReadableStream;

‎src/_shims/ReadableStream.mjs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3+
*/
4+
5+
const _ReadableStream = ReadableStream;
6+
7+
export { _ReadableStream as ReadableStream };

‎src/_shims/ReadableStream.node.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3+
*/
4+
import { ReadableStream } from 'web-streams-polyfill';
5+
6+
export { ReadableStream };

‎src/_shims/fetch.deno.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const _fetch = fetch;
2+
const _Request = Request;
3+
type _RequestInfo = RequestInfo;
4+
type _RequestInit = RequestInit;
5+
const _Response = Response;
6+
type _ResponseInit = ResponseInit;
7+
type _BodyInit = BodyInit;
8+
const _Headers = Headers;
9+
type _HeadersInit = HeadersInit;
10+
11+
export const isPolyfilled = false;
12+
13+
export {
14+
_fetch as fetch,
15+
_Request as Request,
16+
type _RequestInfo as RequestInfo,
17+
type _RequestInit as RequestInit,
18+
_Response as Response,
19+
type _ResponseInit as ResponseInit,
20+
type _BodyInit as BodyInit,
21+
_Headers as Headers,
22+
type _HeadersInit as HeadersInit,
23+
};

‎src/_shims/formdata.deno.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type _BlobPropertyBag = BlobPropertyBag;
2+
type _FilePropertyBag = FilePropertyBag;
3+
4+
const _FormData = FormData;
5+
const _File = File;
6+
const _Blob = Blob;
7+
8+
export const isPolyfilled = false;
9+
10+
export {
11+
_FormData as FormData,
12+
_File as File,
13+
_Blob as Blob,
14+
type _BlobPropertyBag as BlobPropertyBag,
15+
type _FilePropertyBag as FilePropertyBag,
16+
};

‎src/core.ts

+74-9
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,13 @@ type PlatformName =
635635
| 'Android'
636636
| `Other:${string}`
637637
| 'Unknown';
638+
type Browser = 'ie' | 'edge' | 'chrome' | 'firefox' | 'safari';
638639
type PlatformProperties = {
639640
'X-Stainless-Lang': 'js';
640641
'X-Stainless-Package-Version': string;
641642
'X-Stainless-OS': PlatformName;
642643
'X-Stainless-Arch': Arch;
643-
'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | 'unknown';
644+
'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | `browser:${Browser}` | 'unknown';
644645
'X-Stainless-Runtime-Version': string;
645646
};
646647
const getPlatformProperties = (): PlatformProperties => {
@@ -675,7 +676,20 @@ const getPlatformProperties = (): PlatformProperties => {
675676
'X-Stainless-Runtime-Version': process.version,
676677
};
677678
}
678-
// TODO add support for Cloudflare workers, browsers, etc.
679+
680+
const browserInfo = getBrowserInfo();
681+
if (browserInfo) {
682+
return {
683+
'X-Stainless-Lang': 'js',
684+
'X-Stainless-Package-Version': VERSION,
685+
'X-Stainless-OS': 'Unknown',
686+
'X-Stainless-Arch': 'unknown',
687+
'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
688+
'X-Stainless-Runtime-Version': browserInfo.version,
689+
};
690+
}
691+
692+
// TODO add support for Cloudflare workers, etc.
679693
return {
680694
'X-Stainless-Lang': 'js',
681695
'X-Stainless-Package-Version': VERSION,
@@ -686,6 +700,44 @@ const getPlatformProperties = (): PlatformProperties => {
686700
};
687701
};
688702

703+
type BrowserInfo = {
704+
browser: Browser;
705+
version: string;
706+
};
707+
708+
declare const navigator: { userAgent: string } | undefined;
709+
710+
// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
711+
function getBrowserInfo(): BrowserInfo | null {
712+
if (!navigator || typeof navigator === 'undefined') {
713+
return null;
714+
}
715+
716+
// NOTE: The order matters here!
717+
const browserPatterns = [
718+
{ key: 'edge' as const, pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
719+
{ key: 'ie' as const, pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
720+
{ key: 'ie' as const, pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
721+
{ key: 'chrome' as const, pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
722+
{ key: 'firefox' as const, pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
723+
{ key: 'safari' as const, pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
724+
];
725+
726+
// Find the FIRST matching browser
727+
for (const { key, pattern } of browserPatterns) {
728+
const match = pattern.exec(navigator.userAgent);
729+
if (match) {
730+
const major = match[1] || 0;
731+
const minor = match[2] || 0;
732+
const patch = match[3] || 0;
733+
734+
return { browser: key, version: `${major}.${minor}.${patch}` };
735+
}
736+
}
737+
738+
return null;
739+
}
740+
689741
const normalizeArch = (arch: string): Arch => {
690742
// Node docs:
691743
// - https://nodejs.org/api/process.html#processarch
@@ -744,8 +796,8 @@ const isAbsoluteURL = (url: string): boolean => {
744796

745797
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
746798

747-
const validatePositiveInteger = (name: string, n: number) => {
748-
if (!Number.isInteger(n)) {
799+
const validatePositiveInteger = (name: string, n: unknown): number => {
800+
if (typeof n !== 'number' || !Number.isInteger(n)) {
749801
throw new Error(`${name} must be an integer`);
750802
}
751803
if (n < 0) {
@@ -767,14 +819,16 @@ export const ensurePresent = <T>(value: T | null | undefined): T => {
767819
/**
768820
* Read an environment variable.
769821
*
770-
* Will return an empty string if the environment variable doesn't exist or cannot be accessed.
822+
* Will return undefined if the environment variable doesn't exist or cannot be accessed.
771823
*/
772824
export const readEnv = (env: string): string | undefined => {
773-
if (typeof process === 'undefined') {
774-
return undefined;
825+
if (typeof process !== 'undefined') {
826+
return process.env?.[env] ?? undefined;
775827
}
776-
777-
return process.env[env] ?? undefined;
828+
if (typeof Deno !== 'undefined') {
829+
return Deno.env?.get?.(env);
830+
}
831+
return undefined;
778832
};
779833

780834
export const coerceInteger = (value: unknown): number => {
@@ -841,6 +895,17 @@ const uuid4 = () => {
841895
});
842896
};
843897

898+
export const isRunningInBrowser = () => {
899+
return (
900+
// @ts-ignore
901+
typeof window !== 'undefined' &&
902+
// @ts-ignore
903+
typeof window.document !== 'undefined' &&
904+
// @ts-ignore
905+
typeof navigator !== 'undefined'
906+
);
907+
};
908+
844909
export interface HeadersProtocol {
845910
get: (header: string) => string | null | undefined;
846911
}

‎src/index.ts

+16
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ export interface ClientOptions {
6767
*/
6868
defaultQuery?: Core.DefaultQuery;
6969

70+
/**
71+
* By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
72+
* Only set this option to `true` if you understand the risks and have appropriate mitigations in place.
73+
*/
74+
dangerouslyAllowBrowser?: boolean;
75+
7076
organization?: string | null;
7177
}
7278

@@ -95,6 +101,12 @@ export class OpenAI extends Core.APIClient {
95101
...opts,
96102
};
97103

104+
if (!options.dangerouslyAllowBrowser && Core.isRunningInBrowser()) {
105+
throw new Error(
106+
"It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers. \nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n",
107+
);
108+
}
109+
98110
super({
99111
baseURL: options.baseURL!,
100112
timeout: options.timeout ?? 600000,
@@ -181,6 +193,8 @@ export namespace OpenAI {
181193
export import Completion = API.Completion;
182194
export import CompletionChoice = API.CompletionChoice;
183195
export import CompletionCreateParams = API.CompletionCreateParams;
196+
export import CompletionCreateParamsNonStreaming = API.CompletionCreateParamsNonStreaming;
197+
export import CompletionCreateParamsStreaming = API.CompletionCreateParamsStreaming;
184198

185199
export import Chat = API.Chat;
186200

@@ -225,6 +239,8 @@ export namespace OpenAI {
225239
export import FineTunesPage = API.FineTunesPage;
226240
export import FineTuneCreateParams = API.FineTuneCreateParams;
227241
export import FineTuneListEventsParams = API.FineTuneListEventsParams;
242+
export import FineTuneListEventsParamsNonStreaming = API.FineTuneListEventsParamsNonStreaming;
243+
export import FineTuneListEventsParamsStreaming = API.FineTuneListEventsParamsStreaming;
228244
}
229245

230246
export default OpenAI;

‎src/resources/audio/audio.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { APIResource } from 'openai/resource';
44
import { Transcriptions } from './transcriptions';
55
import { Translations } from './translations';
6-
import * as API from './';
6+
import * as API from './index';
77

88
export class Audio extends APIResource {
99
transcriptions: Transcriptions = new Transcriptions(this.client);

‎src/resources/audio/transcriptions.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66
import { type Uploadable, multipartFormRequestOptions } from 'openai/core';
77

88
export class Transcriptions extends APIResource {

‎src/resources/audio/translations.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66
import { type Uploadable, multipartFormRequestOptions } from 'openai/core';
77

88
export class Translations extends APIResource {

‎src/resources/chat/chat.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { APIResource } from 'openai/resource';
44
import { Completions } from './completions';
5-
import * as API from './';
5+
import * as API from './index';
66

77
export class Chat extends APIResource {
88
completions: Completions = new Completions(this.client);
@@ -14,4 +14,6 @@ export namespace Chat {
1414
export import ChatCompletionChunk = API.ChatCompletionChunk;
1515
export import CreateChatCompletionRequestMessage = API.CreateChatCompletionRequestMessage;
1616
export import CompletionCreateParams = API.CompletionCreateParams;
17+
export import CompletionCreateParamsNonStreaming = API.CompletionCreateParamsNonStreaming;
18+
export import CompletionCreateParamsStreaming = API.CompletionCreateParamsStreaming;
1719
}

‎src/resources/chat/completions.ts

+163-302
Large diffs are not rendered by default.

‎src/resources/chat/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ export {
66
ChatCompletionChunk,
77
CreateChatCompletionRequestMessage,
88
CompletionCreateParams,
9+
CompletionCreateParamsNonStreaming,
10+
CompletionCreateParamsStreaming,
911
Completions,
1012
} from './completions';

‎src/resources/completions.ts

+188-314
Large diffs are not rendered by default.

‎src/resources/edits.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66

77
export class Edits extends APIResource {
88
/**

‎src/resources/embeddings.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66

77
export class Embeddings extends APIResource {
88
/**

‎src/resources/files.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66
import { type Uploadable, multipartFormRequestOptions } from 'openai/core';
77
import { Page } from 'openai/pagination';
88

‎src/resources/fine-tunes.ts

+49-30
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
55
import * as Files from 'openai/resources/files';
6-
import * as API from './';
6+
import * as API from './index';
77
import { Page } from 'openai/pagination';
88
import { Stream } from 'openai/streaming';
99

@@ -48,14 +48,19 @@ export class FineTunes extends APIResource {
4848
*/
4949
listEvents(
5050
fineTuneId: string,
51-
query?: FineTuneListEventsParams.ListEventsRequestNonStreaming,
51+
query?: FineTuneListEventsParamsNonStreaming,
5252
options?: Core.RequestOptions,
5353
): Promise<Core.APIResponse<FineTuneEventsListResponse>>;
5454
listEvents(
5555
fineTuneId: string,
56-
query: FineTuneListEventsParams.ListEventsRequestStreaming,
56+
query: FineTuneListEventsParamsStreaming,
5757
options?: Core.RequestOptions,
5858
): Promise<Core.APIResponse<Stream<FineTuneEvent>>>;
59+
listEvents(
60+
fineTuneId: string,
61+
query?: FineTuneListEventsParams,
62+
options?: Core.RequestOptions,
63+
): Promise<Core.APIResponse<FineTuneEventsListResponse | Stream<FineTuneEvent>>>;
5964
listEvents(
6065
fineTuneId: string,
6166
query?: FineTuneListEventsParams | undefined,
@@ -266,36 +271,48 @@ export interface FineTuneCreateParams {
266271
validation_file?: string | null;
267272
}
268273

269-
export type FineTuneListEventsParams =
270-
| FineTuneListEventsParams.ListEventsRequestNonStreaming
271-
| FineTuneListEventsParams.ListEventsRequestStreaming;
274+
export interface FineTuneListEventsParams {
275+
/**
276+
* Whether to stream events for the fine-tune job. If set to true, events will be
277+
* sent as data-only
278+
* [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
279+
* as they become available. The stream will terminate with a `data: [DONE]`
280+
* message when the job is finished (succeeded, cancelled, or failed).
281+
*
282+
* If set to false, only events generated so far will be returned.
283+
*/
284+
stream?: boolean;
285+
}
272286

273287
export namespace FineTuneListEventsParams {
274-
export interface ListEventsRequestNonStreaming {
275-
/**
276-
* Whether to stream events for the fine-tune job. If set to true, events will be
277-
* sent as data-only
278-
* [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
279-
* as they become available. The stream will terminate with a `data: [DONE]`
280-
* message when the job is finished (succeeded, cancelled, or failed).
281-
*
282-
* If set to false, only events generated so far will be returned.
283-
*/
284-
stream?: false;
285-
}
288+
export type FineTuneListEventsParamsNonStreaming = API.FineTuneListEventsParamsNonStreaming;
289+
export type FineTuneListEventsParamsStreaming = API.FineTuneListEventsParamsStreaming;
290+
}
286291

287-
export interface ListEventsRequestStreaming {
288-
/**
289-
* Whether to stream events for the fine-tune job. If set to true, events will be
290-
* sent as data-only
291-
* [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
292-
* as they become available. The stream will terminate with a `data: [DONE]`
293-
* message when the job is finished (succeeded, cancelled, or failed).
294-
*
295-
* If set to false, only events generated so far will be returned.
296-
*/
297-
stream: true;
298-
}
292+
export interface FineTuneListEventsParamsNonStreaming extends FineTuneListEventsParams {
293+
/**
294+
* Whether to stream events for the fine-tune job. If set to true, events will be
295+
* sent as data-only
296+
* [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
297+
* as they become available. The stream will terminate with a `data: [DONE]`
298+
* message when the job is finished (succeeded, cancelled, or failed).
299+
*
300+
* If set to false, only events generated so far will be returned.
301+
*/
302+
stream?: false;
303+
}
304+
305+
export interface FineTuneListEventsParamsStreaming extends FineTuneListEventsParams {
306+
/**
307+
* Whether to stream events for the fine-tune job. If set to true, events will be
308+
* sent as data-only
309+
* [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
310+
* as they become available. The stream will terminate with a `data: [DONE]`
311+
* message when the job is finished (succeeded, cancelled, or failed).
312+
*
313+
* If set to false, only events generated so far will be returned.
314+
*/
315+
stream: true;
299316
}
300317

301318
export namespace FineTunes {
@@ -305,4 +322,6 @@ export namespace FineTunes {
305322
export type FineTunesPage = _FineTunesPage;
306323
export import FineTuneCreateParams = API.FineTuneCreateParams;
307324
export import FineTuneListEventsParams = API.FineTuneListEventsParams;
325+
export import FineTuneListEventsParamsNonStreaming = API.FineTuneListEventsParamsNonStreaming;
326+
export import FineTuneListEventsParamsStreaming = API.FineTuneListEventsParamsStreaming;
308327
}

‎src/resources/images.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66
import { type Uploadable, multipartFormRequestOptions } from 'openai/core';
77

88
export class Images extends APIResource {

‎src/resources/index.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
export { Audio } from './audio/audio';
44
export { Chat } from './chat/chat';
5-
export { Completion, CompletionChoice, CompletionCreateParams, Completions } from './completions';
5+
export {
6+
Completion,
7+
CompletionChoice,
8+
CompletionCreateParams,
9+
CompletionCreateParamsNonStreaming,
10+
CompletionCreateParamsStreaming,
11+
Completions,
12+
} from './completions';
613
export { Edit, EditCreateParams, Edits } from './edits';
714
export { Embedding, EmbeddingCreateParams, Embeddings } from './embeddings';
815
export { FileContent, FileDeleted, FileObject, FileCreateParams, FileObjectsPage, Files } from './files';
@@ -12,6 +19,8 @@ export {
1219
FineTuneEventsListResponse,
1320
FineTuneCreateParams,
1421
FineTuneListEventsParams,
22+
FineTuneListEventsParamsNonStreaming,
23+
FineTuneListEventsParamsStreaming,
1524
FineTunesPage,
1625
FineTunes,
1726
} from './fine-tunes';

‎src/resources/models.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66
import { Page } from 'openai/pagination';
77

88
export class Models extends APIResource {

‎src/resources/moderations.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import * as Core from 'openai/core';
44
import { APIResource } from 'openai/resource';
5-
import * as API from './';
5+
import * as API from './index';
66

77
export class Moderations extends APIResource {
88
/**

‎src/streaming.ts

+33
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Response } from 'openai/_shims/fetch';
2+
import { ReadableStream } from 'openai/_shims/ReadableStream';
23

34
import { APIResponse, Headers, createResponseHeaders } from './core';
45

@@ -78,6 +79,38 @@ export class Stream<Item> implements AsyncIterable<Item>, APIResponse<Stream<Ite
7879
if (!done) this.controller.abort();
7980
}
8081
}
82+
83+
toReadableStream(): ReadableStream {
84+
const self = this;
85+
let iter: AsyncIterator<Item>;
86+
const encoder = new TextEncoder();
87+
88+
return new ReadableStream({
89+
async start() {
90+
iter = self[Symbol.asyncIterator]();
91+
},
92+
async pull(ctrl) {
93+
try {
94+
const { value, done } = await iter.next();
95+
if (done) return ctrl.close();
96+
97+
const str =
98+
typeof value === 'string' ? value : (
99+
// Add a newline after JSON to make it easier to parse newline-separated JSON on the frontend.
100+
JSON.stringify(value) + '\n'
101+
);
102+
const bytes = encoder.encode(str);
103+
104+
ctrl.enqueue(bytes);
105+
} catch (err) {
106+
ctrl.error(err);
107+
}
108+
},
109+
async cancel() {
110+
await iter.return?.();
111+
},
112+
});
113+
}
81114
}
82115

83116
class SSEDecoder {

‎src/uploads.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { type RequestOptions } from './core';
22
import { type Readable } from 'openai/_shims/node-readable';
33
import { type BodyInit } from 'openai/_shims/fetch';
4-
import { FormData, File, type FilePropertyBag } from 'openai/_shims/formdata';
4+
import { FormData, File, type Blob, type FilePropertyBag } from 'openai/_shims/formdata';
55
import { getMultipartRequestOptions } from 'openai/_shims/getMultipartRequestOptions';
66
import { fileFromPath } from 'openai/_shims/fileFromPath';
77
import { type FsReadStream, isFsReadStream } from 'openai/_shims/node-readable';
88

99
export { fileFromPath };
1010

11-
export type BlobPart = string | ArrayBuffer | ArrayBufferView | BlobLike | Uint8Array | DataView;
11+
type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | Uint8Array | DataView;
12+
export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | Uint8Array | DataView;
1213

1314
/**
1415
* Typically, this is a native "File" class.
@@ -84,11 +85,11 @@ export const isUploadable = (value: any): value is Uploadable => {
8485
return isFileLike(value) || isResponseLike(value) || isFsReadStream(value);
8586
};
8687

87-
export type ToFileInput = Uploadable | Exclude<BlobPart, string> | AsyncIterable<BlobPart>;
88+
export type ToFileInput = Uploadable | Exclude<BlobLikePart, string> | AsyncIterable<BlobLikePart>;
8889

8990
/**
9091
* Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
91-
* @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobPart}, or {@link AsyncIterable} of {@link BlobPart}s
92+
* @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
9293
* @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
9394
* @param {Object=} options additional properties
9495
* @param {string=} options.type the MIME type of the content
@@ -231,10 +232,10 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis
231232

232233
// TODO: make nested formats configurable
233234
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
234-
form.append(key, value);
235+
form.append(key, String(value));
235236
} else if (isUploadable(value)) {
236237
const file = await toFile(value);
237-
form.append(key, file);
238+
form.append(key, file as File);
238239
} else if (Array.isArray(value)) {
239240
await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry)));
240241
} else if (typeof value === 'object') {

‎src/version.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const VERSION = '4.0.0-beta.7';
1+
export const VERSION = '4.0.0-beta.8';

‎tsconfig.build.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"extends": "./tsconfig.json",
33
"include": ["dist/src"],
4-
"exclude": [],
4+
"exclude": ["dist/src/_shims/*.deno.ts"],
55
"compilerOptions": {
66
"rootDir": "./dist/src",
77
"paths": {

‎tsconfig.deno.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["deno"],
4+
"exclude": [],
5+
"compilerOptions": {
6+
"rootDir": "./deno",
7+
"lib": ["es2020", "DOM"],
8+
"paths": {
9+
"openai/_shims/*": ["deno/_shims/*"],
10+
"openai": ["deno/index.ts"],
11+
"openai/*": ["deno/*"],
12+
"digest-fetch": ["./typings/digest-fetch"]
13+
},
14+
"noEmit": true,
15+
"declaration": true,
16+
"declarationMap": true,
17+
"outDir": "deno",
18+
"pretty": true,
19+
"sourceMap": true
20+
}
21+
}

‎tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"include": ["src", "tests", "examples"],
3+
"exclude": ["src/_shims/*.deno.ts"],
34
"compilerOptions": {
45
"target": "es2019",
56
"lib": ["es2020"],

‎yarn.lock

+47
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,16 @@
720720
dependencies:
721721
"@sinonjs/commons" "^3.0.0"
722722

723+
"@ts-morph/common@~0.20.0":
724+
version "0.20.0"
725+
resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af"
726+
integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q==
727+
dependencies:
728+
fast-glob "^3.2.12"
729+
minimatch "^7.4.3"
730+
mkdirp "^2.1.6"
731+
path-browserify "^1.0.1"
732+
723733
"@tsconfig/node10@^1.0.7":
724734
version "1.0.8"
725735
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
@@ -1218,6 +1228,13 @@ brace-expansion@^1.1.7:
12181228
balanced-match "^1.0.0"
12191229
concat-map "0.0.1"
12201230

1231+
brace-expansion@^2.0.1:
1232+
version "2.0.1"
1233+
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
1234+
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
1235+
dependencies:
1236+
balanced-match "^1.0.0"
1237+
12211238
braces@^3.0.2, braces@~3.0.2:
12221239
version "3.0.2"
12231240
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@@ -1393,6 +1410,11 @@ co@^4.6.0:
13931410
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
13941411
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
13951412

1413+
code-block-writer@^12.0.0:
1414+
version "12.0.0"
1415+
resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770"
1416+
integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==
1417+
13961418
collapse-white-space@1.0.6, collapse-white-space@^1.0.2:
13971419
version "1.0.6"
13981420
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287"
@@ -2962,11 +2984,23 @@ minimatch@^3.0.4, minimatch@^3.1.2:
29622984
dependencies:
29632985
brace-expansion "^1.1.7"
29642986

2987+
minimatch@^7.4.3:
2988+
version "7.4.6"
2989+
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb"
2990+
integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==
2991+
dependencies:
2992+
brace-expansion "^2.0.1"
2993+
29652994
minimist@1.2.6, minimist@^1.2.0, minimist@^1.2.6:
29662995
version "1.2.6"
29672996
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
29682997
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
29692998

2999+
mkdirp@^2.1.6:
3000+
version "2.1.6"
3001+
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
3002+
integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
3003+
29703004
ms@2.1.2:
29713005
version "2.1.2"
29723006
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@@ -3142,6 +3176,11 @@ parse-srcset@ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee:
31423176
version "1.0.2"
31433177
resolved "https://codeload.github.com/ikatyang/parse-srcset/tar.gz/54eb9c1cb21db5c62b4d0e275d7249516df6f0ee"
31443178

3179+
path-browserify@^1.0.1:
3180+
version "1.0.1"
3181+
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
3182+
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
3183+
31453184
path-exists@^4.0.0:
31463185
version "4.0.0"
31473186
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
@@ -3783,6 +3822,14 @@ ts-jest@^29.1.0:
37833822
semver "7.x"
37843823
yargs-parser "^21.0.1"
37853824

3825+
ts-morph@^19.0.0:
3826+
version "19.0.0"
3827+
resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169"
3828+
integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ==
3829+
dependencies:
3830+
"@ts-morph/common" "~0.20.0"
3831+
code-block-writer "^12.0.0"
3832+
37863833
ts-node@^10.5.0:
37873834
version "10.7.0"
37883835
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5"

0 commit comments

Comments
 (0)
Please sign in to comment.