Skip to content

Commit

Permalink
Merge pull request #369 from openai/release-please--branches--master-…
Browse files Browse the repository at this point in the history
…-changes--next--components--openai

release: 4.12.2
  • Loading branch information
athyuttamre authored Oct 16, 2023
2 parents 6484039 + 09e10b3 commit 72e4495
Show file tree
Hide file tree
Showing 35 changed files with 321 additions and 127 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "4.12.1"
".": "4.12.2"
}
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

## 4.12.2 (2023-10-16)

Full Changelog: [v4.12.1...v4.12.2](https://github.com/openai/openai-node/compare/v4.12.1...v4.12.2)

### Bug Fixes

* **client:** correctly handle errors during streaming ([#377](https://github.com/openai/openai-node/issues/377)) ([09233b1](https://github.com/openai/openai-node/commit/09233b1ccc80ee900be19050f438cc8aa9dbb513))
* **client:** correctly handle errors during streaming ([#379](https://github.com/openai/openai-node/issues/379)) ([9ced580](https://github.com/openai/openai-node/commit/9ced5804777a5857d6775a49ddf30ed9cc016fab))
* improve status code in error messages ([#381](https://github.com/openai/openai-node/issues/381)) ([68dfb17](https://github.com/openai/openai-node/commit/68dfb17cce300ade8d29afc854d616833b3283ca))


### Chores

* add case insensitive get header function ([#373](https://github.com/openai/openai-node/issues/373)) ([b088998](https://github.com/openai/openai-node/commit/b088998ae610de54bb8700eefd6b664eb9a2fcc3))
* **internal:** add debug logs for stream responses ([#380](https://github.com/openai/openai-node/issues/380)) ([689db0b](https://github.com/openai/openai-node/commit/689db0b8058527ae5c3af5e457c962d8a6635297))
* show deprecation notice on re-export ([#368](https://github.com/openai/openai-node/issues/368)) ([b176703](https://github.com/openai/openai-node/commit/b176703102998f0e9d8ca2ed93ccd495fd10a6ee))
* update comment ([#376](https://github.com/openai/openai-node/issues/376)) ([a06c685](https://github.com/openai/openai-node/commit/a06c6850bfdd756dc8f07dd1f70218be610faa30))
* update comment ([#378](https://github.com/openai/openai-node/issues/378)) ([b04031d](https://github.com/openai/openai-node/commit/b04031d19210a66f82c7d233a50f7bc427a1bf92))


### Refactors

* **streaming:** change Stream constructor signature ([#370](https://github.com/openai/openai-node/issues/370)) ([71984ed](https://github.com/openai/openai-node/commit/71984edc3141ba99ffa1327bab6a182b4452209f))
* **test:** refactor authentication tests ([#371](https://github.com/openai/openai-node/issues/371)) ([e0d459f](https://github.com/openai/openai-node/commit/e0d459f958451a99e15a11a0e5ea6471abbe1ac1))

## 4.12.1 (2023-10-11)

Full Changelog: [v4.12.0...v4.12.1](https://github.com/openai/openai-node/compare/v4.12.0...v4.12.1)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The full API of this library can be found in [api.md file](https://github.com/op
import OpenAI from 'openai';

const openai = new OpenAI({
apiKey: 'my api key', // defaults to process.env["OPENAI_API_KEY"]
apiKey: 'My API Key', // defaults to process.env["OPENAI_API_KEY"]
});

async function main() {
Expand Down Expand Up @@ -73,7 +73,7 @@ This library includes TypeScript definitions for all request params and response
import OpenAI from 'openai';

const openai = new OpenAI({
apiKey: 'my api key', // defaults to process.env["OPENAI_API_KEY"]
apiKey: 'My API Key', // defaults to process.env["OPENAI_API_KEY"]
});

async function main() {
Expand Down Expand Up @@ -297,7 +297,7 @@ await openai.models.list({

## Semantic Versioning

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:
This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:

1. Changes that only affect static types, without breaking runtime behavior.
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)_.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openai",
"version": "4.12.1",
"version": "4.12.2",
"description": "Client library for the OpenAI API",
"author": "OpenAI <[email protected]>",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -93,7 +93,8 @@
"digest-fetch": "^1.3.0",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
"node-fetch": "^2.6.7",
"web-streams-polyfill": "^3.2.1"
},
"devDependencies": {
"@types/jest": "^29.4.0",
Expand Down
2 changes: 1 addition & 1 deletion release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"include-v-in-tag": true,
"include-component-in-tag": false,
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"bump-patch-for-minor-pre-major": false,
"pull-request-header": "Automated Release PR",
"pull-request-title-pattern": "release: ${version}",
"changelog-sections": [
Expand Down
4 changes: 3 additions & 1 deletion src/_shims/auto/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,6 @@ export declare class FsReadStream extends Readable {

// @ts-ignore
type _ReadableStream<R = any> = unknown extends ReadableStream<R> ? never : ReadableStream<R>;
export { type _ReadableStream as ReadableStream };
// @ts-ignore
declare const _ReadableStream: unknown extends typeof ReadableStream ? never : typeof ReadableStream;
export { _ReadableStream as ReadableStream };
2 changes: 2 additions & 0 deletions src/_shims/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export type Readable = SelectType<manual.Readable, auto.Readable>;
export type FsReadStream = SelectType<manual.FsReadStream, auto.FsReadStream>;
// @ts-ignore
export type ReadableStream = SelectType<manual.ReadableStream, auto.ReadableStream>;
// @ts-ignore
export const ReadableStream: SelectType<typeof manual.ReadableStream, typeof auto.ReadableStream>;

export function getMultipartRequestOptions<T extends {} = Record<string, unknown>>(
form: FormData,
Expand Down
2 changes: 2 additions & 0 deletions src/_shims/node-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Readable } from 'node:stream';
import { type RequestOptions } from '../core';
import { MultipartBody } from './MultipartBody';
import { type Shims } from './registry';
import { ReadableStream } from 'web-streams-polyfill';

type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;

Expand Down Expand Up @@ -71,6 +72,7 @@ export function getRuntime(): Shims {
FormData: fd.FormData,
Blob: fd.Blob,
File: fd.File,
ReadableStream,
getMultipartRequestOptions,
getDefaultAgent: (url: string): Agent => (url.startsWith('https') ? defaultHttpsAgent : defaultHttpAgent),
fileFromPath,
Expand Down
2 changes: 1 addition & 1 deletion src/_shims/node-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as fd from 'formdata-node';
export { type Agent } from 'node:http';
export { type Readable } from 'node:stream';
export { type ReadStream as FsReadStream } from 'node:fs';
export { type ReadableStream } from 'web-streams-polyfill';
export { ReadableStream } from 'web-streams-polyfill';

export const fetch: typeof nf.default;

Expand Down
3 changes: 3 additions & 0 deletions src/_shims/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface Shims {
FormData: any;
Blob: any;
File: any;
ReadableStream: any;
getMultipartRequestOptions: <T extends {} = Record<string, unknown>>(
form: Shims['FormData'],
opts: RequestOptions<T>,
Expand All @@ -32,6 +33,7 @@ export let Headers: Shims['Headers'] | undefined = undefined;
export let FormData: Shims['FormData'] | undefined = undefined;
export let Blob: Shims['Blob'] | undefined = undefined;
export let File: Shims['File'] | undefined = undefined;
export let ReadableStream: Shims['ReadableStream'] | undefined = undefined;
export let getMultipartRequestOptions: Shims['getMultipartRequestOptions'] | undefined = undefined;
export let getDefaultAgent: Shims['getDefaultAgent'] | undefined = undefined;
export let fileFromPath: Shims['fileFromPath'] | undefined = undefined;
Expand All @@ -55,6 +57,7 @@ export function setShims(shims: Shims, options: { auto: boolean } = { auto: fals
FormData = shims.FormData;
Blob = shims.Blob;
File = shims.File;
ReadableStream = shims.ReadableStream;
getMultipartRequestOptions = shims.getMultipartRequestOptions;
getDefaultAgent = shims.getDefaultAgent;
fileFromPath = shims.fileFromPath;
Expand Down
12 changes: 12 additions & 0 deletions src/_shims/web-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ export function getRuntime({ manuallyImported }: { manuallyImported?: boolean }
}
}
),
ReadableStream:
// @ts-ignore
typeof ReadableStream !== 'undefined' ? ReadableStream : (
class ReadableStream {
// @ts-ignore
constructor() {
throw new Error(
`streaming isn't supported in this environment yet as 'ReadableStream' is undefined. ${recommendation}`,
);
}
}
),
getMultipartRequestOptions: async <T extends {} = Record<string, unknown>>(
// @ts-ignore
form: FormData,
Expand Down
3 changes: 2 additions & 1 deletion src/_shims/web-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@ export declare class FsReadStream extends Readable {
}

type _ReadableStream<R = any> = ReadableStream<R>;
export { type _ReadableStream as ReadableStream };
declare const _ReadableStream: typeof ReadableStream;
export { _ReadableStream as ReadableStream };
39 changes: 29 additions & 10 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ type APIResponseProps = {
async function defaultParseResponse<T>(props: APIResponseProps): Promise<T> {
const { response } = props;
if (props.options.stream) {
debug('response', response.status, response.url, response.headers, response.body);

// Note: there is an invariant here that isn't represented in the type system
// that if you set `stream: true` the response type must also be `Stream<T>`
return new Stream(response, props.controller) as any;
return Stream.fromSSEResponse(response, props.controller) as any;
}

const contentType = response.headers.get('content-type');
Expand Down Expand Up @@ -1059,16 +1061,33 @@ export const isHeadersProtocol = (headers: any): headers is HeadersProtocol => {
return typeof headers?.get === 'function';
};

export const getHeader = (headers: HeadersLike, key: string): string | null | undefined => {
const lowerKey = key.toLowerCase();
if (isHeadersProtocol(headers)) return headers.get(key) || headers.get(lowerKey);
const value = headers[key] || headers[lowerKey];
if (Array.isArray(value)) {
if (value.length <= 1) return value[0];
console.warn(`Received ${value.length} entries for the ${key} header, using the first entry.`);
return value[0];
export const getRequiredHeader = (headers: HeadersLike, header: string): string => {
const lowerCasedHeader = header.toLowerCase();
if (isHeadersProtocol(headers)) {
// to deal with the case where the header looks like Stainless-Event-Id
const intercapsHeader =
header[0]?.toUpperCase() +
header.substring(1).replace(/([^\w])(\w)/g, (_m, g1, g2) => g1 + g2.toUpperCase());
for (const key of [header, lowerCasedHeader, header.toUpperCase(), intercapsHeader]) {
const value = headers.get(key);
if (value) {
return value;
}
}
}
return value;

for (const [key, value] of Object.entries(headers)) {
if (key.toLowerCase() === lowerCasedHeader) {
if (Array.isArray(value)) {
if (value.length <= 1) return value[0];
console.warn(`Received ${value.length} entries for the ${header} header, using the first entry.`);
return value[0];
}
return value;
}
}

throw new Error(`Could not find ${header} header`);
};

/**
Expand Down
20 changes: 15 additions & 5 deletions src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class APIError extends OpenAIError {
message: string | undefined,
headers: Headers | undefined,
) {
super(`${status} ${APIError.makeMessage(error, message)}`);
super(`${APIError.makeMessage(status, error, message)}`);
this.status = status;
this.headers = headers;

Expand All @@ -30,14 +30,24 @@ export class APIError extends OpenAIError {
this.type = data?.['type'];
}

private static makeMessage(error: any, message: string | undefined) {
return (
private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
const msg =
error?.message ?
typeof error.message === 'string' ? error.message
: JSON.stringify(error.message)
: error ? JSON.stringify(error)
: message || 'status code (no body)'
);
: message;

if (status && msg) {
return `${status} ${msg}`;
}
if (status) {
return `${status} status code (no body)`;
}
if (msg) {
return msg;
}
return '(no status code or body)';
}

static generate(
Expand Down
17 changes: 10 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import * as API from 'openai/resources/index';

export interface ClientOptions {
/**
* Defaults to process.env["OPENAI_API_KEY"].
* Defaults to process.env['OPENAI_API_KEY'].
*/
apiKey?: string;

/**
* Defaults to process.env['OPENAI_ORG_ID'].
*/
organization?: string | null;

/**
* Override the default base URL for the API, e.g., "https://api.example.com/v2/"
*/
Expand Down Expand Up @@ -72,21 +77,20 @@ export interface ClientOptions {
* Only set this option to `true` if you understand the risks and have appropriate mitigations in place.
*/
dangerouslyAllowBrowser?: boolean;

organization?: string | null;
}

/** API Client for interfacing with the OpenAI API. */
export class OpenAI extends Core.APIClient {
apiKey: string;
organization?: string | null;
organization: string | null;

private _options: ClientOptions;

/**
* API Client for interfacing with the OpenAI API.
*
* @param {string} [opts.apiKey=process.env['OPENAI_API_KEY']] - The API Key to send to the API.
* @param {string} [opts.apiKey==process.env['OPENAI_API_KEY'] ?? undefined]
* @param {string | null} [opts.organization==process.env['OPENAI_ORG_ID'] ?? null]
* @param {string} [opts.baseURL] - Override the default base URL for the API.
* @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
* @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
Expand All @@ -95,7 +99,6 @@ export class OpenAI extends Core.APIClient {
* @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API.
* @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API.
* @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
* @param {string | null} [opts.organization]
*/
constructor({
apiKey = Core.readEnv('OPENAI_API_KEY'),
Expand All @@ -104,7 +107,7 @@ export class OpenAI extends Core.APIClient {
}: ClientOptions = {}) {
if (apiKey === undefined) {
throw new Errors.OpenAIError(
"The OPENAI_API_KEY environment variable is missing or empty; either provide it, or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'my apiKey' }).",
"The OPENAI_API_KEY environment variable is missing or empty; either provide it, or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'My API Key' }).",
);
}

Expand Down
3 changes: 3 additions & 0 deletions src/resources/chat/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export namespace Chat {
export import ChatCompletionMessage = CompletionsAPI.ChatCompletionMessage;
export import ChatCompletionMessageParam = CompletionsAPI.ChatCompletionMessageParam;
export import ChatCompletionRole = CompletionsAPI.ChatCompletionRole;
/**
* @deprecated ChatCompletionMessageParam should be used instead
*/
export import CreateChatCompletionRequestMessage = CompletionsAPI.CreateChatCompletionRequestMessage;
export import ChatCompletionCreateParams = CompletionsAPI.ChatCompletionCreateParams;
export import CompletionCreateParams = CompletionsAPI.CompletionCreateParams;
Expand Down
3 changes: 3 additions & 0 deletions src/resources/chat/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ export namespace Completions {
export import ChatCompletionMessage = ChatCompletionsAPI.ChatCompletionMessage;
export import ChatCompletionMessageParam = ChatCompletionsAPI.ChatCompletionMessageParam;
export import ChatCompletionRole = ChatCompletionsAPI.ChatCompletionRole;
/**
* @deprecated ChatCompletionMessageParam should be used instead
*/
export import CreateChatCompletionRequestMessage = ChatCompletionsAPI.CreateChatCompletionRequestMessage;
export import ChatCompletionCreateParams = ChatCompletionsAPI.ChatCompletionCreateParams;
export import CompletionCreateParams = ChatCompletionsAPI.CompletionCreateParams;
Expand Down
2 changes: 1 addition & 1 deletion src/shims/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ declare module '../_shims/manual-types' {
// @ts-ignore
export type FsReadStream = types.FsReadStream;
// @ts-ignore
export type ReadableStream = types.ReadableStream;
export import ReadableStream = types.ReadableStream;
}
}
2 changes: 1 addition & 1 deletion src/shims/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ declare module '../_shims/manual-types' {
// @ts-ignore
export type FsReadStream = types.FsReadStream;
// @ts-ignore
export type ReadableStream = types.ReadableStream;
export import ReadableStream = types.ReadableStream;
}
}
Loading

0 comments on commit 72e4495

Please sign in to comment.