Skip to content

Commit 347a227

Browse files
committedJul 29, 2023
v4.0.0-beta.7
1 parent 96e5b7f commit 347a227

File tree

20 files changed

+353
-203
lines changed

20 files changed

+353
-203
lines changed
 

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import OpenAI from 'openai';
5050
const openai = new OpenAI();
5151

5252
async function main() {
53-
const completion = await openai.chat.completions.create({
53+
const stream = await openai.chat.completions.create({
5454
model: 'gpt-4',
5555
messages: [{ role: 'user', content: 'Say this is a test' }],
5656
stream: true,

‎api.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Types:
1717

1818
- <code><a href="./src/resources/chat/completions.ts">ChatCompletion</a></code>
1919
- <code><a href="./src/resources/chat/completions.ts">ChatCompletionChunk</a></code>
20+
- <code><a href="./src/resources/chat/completions.ts">CreateChatCompletionRequestMessage</a></code>
2021

2122
Methods:
2223

‎ecosystem-tests/cli.ts

+100-19
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ function parseArgs() {
125125
default: false,
126126
description: 'Push projects to live servers',
127127
},
128+
jobs: {
129+
type: 'number',
130+
default: 1,
131+
description: 'number of parallel jobs to run',
132+
},
133+
parallel: {
134+
type: 'boolean',
135+
default: false,
136+
description: 'run all projects in parallel (jobs = # projects)',
137+
},
128138
})
129139
.help().argv;
130140
}
@@ -157,26 +167,97 @@ async function main() {
157167

158168
const failed: typeof projectNames = [];
159169

160-
for (const project of projectsToRun) {
161-
const fn = projects[project];
162-
163-
await withChdir(path.join(rootDir, 'ecosystem-tests', project), async () => {
164-
console.error('\n');
165-
console.error(banner(project));
166-
console.error('\n');
167-
168-
try {
169-
await fn();
170-
console.error(`✅ - Successfully ran ${project}`);
171-
} catch (err) {
172-
if (err && (err as any).shortMessage) {
173-
console.error((err as any).shortMessage);
174-
} else {
175-
console.error(err);
176-
}
177-
failed.push(project);
170+
let { jobs } = args;
171+
if (args.parallel) jobs = projectsToRun.length;
172+
if (jobs > 1) {
173+
const queue = [...projectsToRun];
174+
const runningProjects = new Set();
175+
176+
const cursorLeft = '\x1B[G';
177+
const eraseLine = '\x1B[2K';
178+
179+
let progressDisplayed = false;
180+
function clearProgress() {
181+
if (progressDisplayed) {
182+
process.stderr.write(cursorLeft + eraseLine);
183+
progressDisplayed = false;
178184
}
179-
});
185+
}
186+
const spinner = ['|', '/', '-', '\\'];
187+
188+
function showProgress() {
189+
clearProgress();
190+
progressDisplayed = true;
191+
const spin = spinner[Math.floor(Date.now() / 500) % spinner.length];
192+
process.stderr.write(
193+
`${spin} Running ${[...runningProjects].join(', ')}`.substring(0, process.stdout.columns - 3) + '...',
194+
);
195+
}
196+
197+
const progressInterval = setInterval(showProgress, process.stdout.isTTY ? 500 : 5000);
198+
showProgress();
199+
200+
await Promise.all(
201+
[...Array(jobs).keys()].map(async () => {
202+
while (queue.length) {
203+
const project = queue.shift();
204+
if (!project) break;
205+
let stdout, stderr;
206+
try {
207+
runningProjects.add(project);
208+
const result = await execa(
209+
'yarn',
210+
[
211+
'tsn',
212+
__filename,
213+
project,
214+
'--skip-pack',
215+
...(args.live ? ['--live'] : []),
216+
...(args.verbose ? ['--verbose'] : []),
217+
...(args.deploy ? ['--deploy'] : []),
218+
...(args.fromNpm ? ['--from-npm'] : []),
219+
],
220+
{ stdio: 'pipe', encoding: 'utf8', maxBuffer: 100 * 1024 * 1024 },
221+
);
222+
({ stdout, stderr } = result);
223+
} catch (error) {
224+
({ stdout, stderr } = error as any);
225+
failed.push(project);
226+
} finally {
227+
runningProjects.delete(project);
228+
}
229+
230+
if (stdout) process.stdout.write(stdout);
231+
if (stderr) process.stderr.write(stderr);
232+
}
233+
}),
234+
);
235+
236+
clearInterval(progressInterval);
237+
clearProgress();
238+
} else {
239+
for (const project of projectsToRun) {
240+
const fn = projects[project];
241+
242+
await withChdir(path.join(rootDir, 'ecosystem-tests', project), async () => {
243+
console.error('\n');
244+
console.error(banner(project));
245+
console.error('\n');
246+
247+
try {
248+
await fn();
249+
console.error(`✅ - Successfully ran ${project}`);
250+
} catch (err) {
251+
if (err && (err as any).shortMessage) {
252+
console.error('❌', (err as any).shortMessage);
253+
} else {
254+
console.error('❌', err);
255+
}
256+
failed.push(project);
257+
}
258+
console.error('\n');
259+
});
260+
}
180261
}
181262

182263
if (failed.length) {
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import OpenAI from 'openai';
2-
import { uploadWebApiTestCases } from './uploadWebApiTestCases.js';
3-
import { distance } from 'fastest-levenshtein'
1+
import { distance } from 'fastest-levenshtein';
42

53
/**
64
* Welcome to Cloudflare Workers! This is your first worker.
@@ -35,54 +33,68 @@ type Test = { description: string; handler: () => Promise<void> };
3533

3634
export default {
3735
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
38-
const client = new OpenAI({ apiKey: env.OPENAI_API_KEY });
36+
try {
37+
console.error('importing openai');
38+
const { default: OpenAI } = await import('openai');
39+
console.error('importing test cases');
40+
const { uploadWebApiTestCases } = await import('./uploadWebApiTestCases.js');
41+
console.error('creating client');
42+
const client = new OpenAI({ apiKey: env.OPENAI_API_KEY });
43+
console.error('created client');
3944

40-
const tests: Test[] = [];
41-
function it(description: string, handler: () => Promise<void>) {
42-
tests.push({ description, handler });
43-
}
44-
function expectEqual(a: any, b: any) {
45-
if (!Object.is(a, b)) {
46-
throw new Error(`expected values to be equal: ${JSON.stringify({ a, b })}`);
45+
const tests: Test[] = [];
46+
function it(description: string, handler: () => Promise<void>) {
47+
tests.push({ description, handler });
4748
}
48-
}
49-
function expectSimilar(received: string, expected: string, maxDistance: number) {
50-
const receivedDistance = distance(received, expected);
51-
if (receivedDistance < maxDistance) {
52-
return;
49+
function expectEqual(a: any, b: any) {
50+
if (!Object.is(a, b)) {
51+
throw new Error(`expected values to be equal: ${JSON.stringify({ a, b })}`);
52+
}
5353
}
54+
function expectSimilar(received: string, expected: string, maxDistance: number) {
55+
const receivedDistance = distance(received, expected);
56+
if (receivedDistance < maxDistance) {
57+
return;
58+
}
5459

55-
const message = [
56-
`Received: ${JSON.stringify(received)}`,
57-
`Expected: ${JSON.stringify(expected)}`,
58-
`Max distance: ${maxDistance}`,
59-
`Received distance: ${receivedDistance}`,
60-
].join('\n');
60+
const message = [
61+
`Received: ${JSON.stringify(received)}`,
62+
`Expected: ${JSON.stringify(expected)}`,
63+
`Max distance: ${maxDistance}`,
64+
`Received distance: ${receivedDistance}`,
65+
].join('\n');
6166

62-
throw new Error(message);
63-
}
67+
throw new Error(message);
68+
}
6469

65-
uploadWebApiTestCases({
66-
client: client as any,
67-
it,
68-
expectEqual,
69-
expectSimilar,
70-
});
70+
uploadWebApiTestCases({
71+
client: client as any,
72+
it,
73+
expectEqual,
74+
expectSimilar,
75+
});
7176

72-
let allPassed = true;
73-
const results = [];
77+
let allPassed = true;
78+
const results = [];
7479

75-
for (const { description, handler } of tests) {
76-
let result;
77-
try {
78-
result = await handler();
79-
} catch (error) {
80-
allPassed = false;
81-
result = error instanceof Error ? error.stack : String(error);
80+
for (const { description, handler } of tests) {
81+
console.error('running', description);
82+
let result;
83+
try {
84+
result = await handler();
85+
console.error('passed ', description);
86+
} catch (error) {
87+
console.error('failed ', description, error);
88+
allPassed = false;
89+
result = error instanceof Error ? error.stack : String(error);
90+
}
91+
results.push(`${description}\n\n${String(result)}`);
8292
}
83-
results.push(`${description}\n\n${String(result)}`);
84-
}
8593

86-
return new Response(allPassed ? 'Passed!' : results.join('\n\n'));
94+
return new Response(allPassed ? 'Passed!' : results.join('\n\n'));
95+
} catch (error) {
96+
console.error(error instanceof Error ? error.stack : String(error));
97+
return new Response(error instanceof Error ? error.stack : String(error), { status: 500 });
98+
}
8799
},
88100
};
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import fetch from 'node-fetch';
22

3-
it('works', async () => {
4-
expect(await (await fetch('http://localhost:8787')).text()).toEqual('Passed!');
5-
}, 30000);
3+
it(
4+
'works',
5+
async () => {
6+
expect(await (await fetch('http://localhost:8787')).text()).toEqual('Passed!');
7+
},
8+
3 * 60000
9+
);

‎ecosystem-tests/deno/main_test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assertEquals, AssertionError } from 'https://deno.land/std@0.192.0/testing/asserts.ts';
22
import OpenAI, { toFile } from 'npm:openai@3.3.0';
3-
import { distance } from 'https://deno.land/x/fastest_levenshtein/mod.ts'
3+
import { distance } from 'https://deno.land/x/fastest_levenshtein/mod.ts';
44

55
const url = 'https://audio-samples.github.io/samples/mp3/blizzard_biased/sample-1.mp3';
66
const filename = 'sample-1.mp3';

‎ecosystem-tests/node-ts-cjs-dom/jest.config.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ module.exports = {
55
testMatch: ['<rootDir>/tests/*.ts'],
66
watchPathIgnorePatterns: ['<rootDir>/node_modules/'],
77
verbose: false,
8-
testTimeout: 15000,
8+
testTimeout: 60000,
99
};

‎ecosystem-tests/node-ts-cjs/jest.config.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ module.exports = {
55
testMatch: ['<rootDir>/tests/*.ts'],
66
watchPathIgnorePatterns: ['<rootDir>/node_modules/'],
77
verbose: false,
8-
testTimeout: 15000,
8+
testTimeout: 60000,
99
};

‎ecosystem-tests/node-ts-esm-dom/jest.config.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ module.exports = {
1919
testMatch: ['<rootDir>/tests/*.ts'],
2020
watchPathIgnorePatterns: ['<rootDir>/node_modules/'],
2121
verbose: false,
22-
testTimeout: 15000,
22+
testTimeout: 60000,
2323
};

‎ecosystem-tests/node-ts-esm/jest.config.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ module.exports = {
1919
testMatch: ['<rootDir>/tests/*.ts'],
2020
watchPathIgnorePatterns: ['<rootDir>/node_modules/'],
2121
verbose: false,
22-
testTimeout: 15000,
22+
testTimeout: 60000,
2323
};

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function describe(description: string, handler: () => void) {
5555
}
5656
}
5757

58-
function it(description: string, run: () => any, timeout = 15000) {
58+
function it(description: string, run: () => any, timeout = 60000) {
5959
tests.push({ path: [...testPath, description], run, timeout });
6060
}
6161

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

+52-17
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,74 @@
1-
import puppeteer from 'puppeteer'
1+
import puppeteer from 'puppeteer';
22

33
(async () => {
4-
const browser = await puppeteer.launch();
4+
const browser = await puppeteer.launch({
5+
args: ['--no-sandbox'],
6+
});
7+
let page;
58
try {
6-
const page = await browser.newPage();
9+
page = await browser.newPage();
10+
function debugEvent(subj: string) {
11+
return subj.padEnd('requestfailed'.length);
12+
}
13+
page
14+
.on('console', (message) =>
15+
console.error(
16+
`${debugEvent('console')} ${message
17+
.type()
18+
.substr(0, 'warning'.length)
19+
.toUpperCase()
20+
.padEnd('warning'.length)} ${message.text()}`,
21+
),
22+
)
23+
.on('pageerror', ({ message }) => console.error(`${debugEvent('pageerror')} ${message}`))
24+
.on('response', (response) =>
25+
console.error(`${debugEvent('response')} ${response.status()} ${response.url()}`),
26+
)
27+
.on('requestfailed', (request) =>
28+
console.error(`${debugEvent('requestfailed')} ${request.failure()?.errorText} ${request.url()}`),
29+
);
730

8-
const apiKey = process.env.OPENAI_API_KEY
31+
const apiKey = process.env.OPENAI_API_KEY;
932

10-
if (!apiKey) throw new Error('missing process.env.OPENAI_API_KEY')
33+
if (!apiKey) throw new Error('missing process.env.OPENAI_API_KEY');
1134

1235
// Navigate the page to a URL
1336
await page.goto(`http://localhost:8080/index.html?apiKey=${apiKey}`);
1437

15-
await page.waitForSelector('#running', { timeout: 15000 })
38+
await page.waitForSelector('#running', { timeout: 15000 });
1639

17-
let start = Date.now()
18-
while (await page.$('#running') != null && Date.now() - start < 60000) {
19-
await new Promise(r => setTimeout(r, 1000))
40+
let start = Date.now();
41+
while ((await page.$('#running')) != null && Date.now() - start < 3 * 60000) {
42+
await new Promise((r) => setTimeout(r, 1000));
2043
}
2144

22-
let results
23-
const resultsEl = await page.$('#results')
45+
let results;
46+
const resultsEl = await page.$('#results');
2447
if (resultsEl) {
25-
const text = await page.evaluate(el => el.textContent, resultsEl)
26-
results = text ? JSON.parse(text) : undefined
48+
const text = await page.evaluate((el) => el.textContent, resultsEl);
49+
results = text ? JSON.parse(text) : undefined;
2750
}
2851

2952
if (!Array.isArray(results)) {
30-
throw new Error(`failed to get test results from page`)
53+
throw new Error(`failed to get test results from page`);
3154
}
32-
const failed = results.filter(r => !r.passed)
55+
const failed = results.filter((r) => !r.passed);
3356
if (failed.length) {
34-
throw new Error(`${failed.length} of ${results.length} tests failed: ${JSON.stringify(failed, null, 2)}`)
57+
throw new Error(
58+
`${failed.length} of ${results.length} tests failed: ${JSON.stringify(failed, null, 2)}`,
59+
);
60+
}
61+
console.log(`${results.length} tests passed!`);
62+
} catch (error) {
63+
if (page) {
64+
try {
65+
const html = await page.evaluate(() => document.body.innerHTML);
66+
console.error(`\n====================\nBODY HTML\n====================\n\n${html}\n\n`);
67+
} catch (error) {
68+
console.error(`failed to get body HTML for debugging`, error);
69+
}
3570
}
36-
console.log(`${results.length} tests passed!`)
71+
throw error;
3772
} finally {
3873
await browser.close();
3974
}

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openai",
3-
"version": "4.0.0-beta.6",
3+
"version": "4.0.0-beta.7",
44
"description": "Client library for the OpenAI API",
55
"author": "OpenAI <support@openai.com>",
66
"types": "dist/index.d.ts",

‎src/core.ts

+38
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ export abstract class APIClient {
208208

209209
this.debug('request', url, options, req.headers);
210210

211+
if (options.signal?.aborted) {
212+
throw new APIUserAbortError();
213+
}
214+
211215
const controller = new AbortController();
212216
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
213217

@@ -760,6 +764,19 @@ export const ensurePresent = <T>(value: T | null | undefined): T => {
760764
return value;
761765
};
762766

767+
/**
768+
* Read an environment variable.
769+
*
770+
* Will return an empty string if the environment variable doesn't exist or cannot be accessed.
771+
*/
772+
export const readEnv = (env: string): string | undefined => {
773+
if (typeof process === 'undefined') {
774+
return undefined;
775+
}
776+
777+
return process.env[env] ?? undefined;
778+
};
779+
763780
export const coerceInteger = (value: unknown): number => {
764781
if (typeof value === 'number') return Math.round(value);
765782
if (typeof value === 'string') return parseInt(value, 10);
@@ -780,6 +797,27 @@ export const coerceBoolean = (value: unknown): boolean => {
780797
return Boolean(value);
781798
};
782799

800+
export const maybeCoerceInteger = (value: unknown): number | undefined => {
801+
if (value === undefined) {
802+
return undefined;
803+
}
804+
return coerceInteger(value);
805+
};
806+
807+
export const maybeCoerceFloat = (value: unknown): number | undefined => {
808+
if (value === undefined) {
809+
return undefined;
810+
}
811+
return coerceFloat(value);
812+
};
813+
814+
export const maybeCoerceBoolean = (value: unknown): boolean | undefined => {
815+
if (value === undefined) {
816+
return undefined;
817+
}
818+
return coerceBoolean(value);
819+
};
820+
783821
// https://stackoverflow.com/a/34491287
784822
export function isEmptyObj(obj: Object | null | undefined): boolean {
785823
if (!obj) return true;

‎src/error.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,27 @@ export class APIError extends Error {
1717
message: string | undefined,
1818
headers: Headers | undefined,
1919
) {
20-
super(message || (error as any)?.message || 'Unknown error occurred.');
20+
super(APIError.makeMessage(error, message));
2121
this.status = status;
2222
this.headers = headers;
2323

2424
const data = error as Record<string, any>;
2525
this.error = data;
2626
this.code = data?.['code'];
27-
this.message = data?.['message'];
2827
this.param = data?.['param'];
2928
this.type = data?.['type'];
3029
}
3130

31+
private static makeMessage(error: any, message: string | undefined) {
32+
return (
33+
error?.message ?
34+
typeof error.message === 'string' ? error.message
35+
: JSON.stringify(error.message)
36+
: error ? JSON.stringify(error)
37+
: message || 'Unknown error occurred'
38+
);
39+
}
40+
3241
static generate(
3342
status: number | undefined,
3443
errorResponse: Object | undefined,

‎src/index.ts

+21-10
Original file line numberDiff line numberDiff line change
@@ -66,36 +66,46 @@ export interface ClientOptions {
6666
* param to `undefined` in request options.
6767
*/
6868
defaultQuery?: Core.DefaultQuery;
69+
70+
organization?: string | null;
6971
}
7072

7173
/** Instantiate the API Client. */
7274
export class OpenAI extends Core.APIClient {
7375
apiKey: string;
76+
organization?: string | null;
7477

7578
private _options: ClientOptions;
7679

77-
constructor(opts?: ClientOptions) {
78-
const options: ClientOptions = {
79-
apiKey: typeof process === 'undefined' ? '' : process.env['OPENAI_API_KEY'] || '',
80-
baseURL: 'https://api.openai.com/v1',
81-
...opts,
82-
};
83-
84-
if (!options.apiKey && options.apiKey !== null) {
80+
constructor({
81+
apiKey = Core.readEnv('OPENAI_API_KEY'),
82+
organization = Core.readEnv('OPENAI_ORG_ID') ?? null,
83+
...opts
84+
}: ClientOptions = {}) {
85+
if (apiKey === undefined) {
8586
throw new Error(
86-
"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' }).",
87+
'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: undefined }).',
8788
);
8889
}
8990

91+
const options: ClientOptions = {
92+
apiKey,
93+
organization,
94+
baseURL: `https://api.openai.com/v1`,
95+
...opts,
96+
};
97+
9098
super({
9199
baseURL: options.baseURL!,
92100
timeout: options.timeout ?? 600000,
93101
httpAgent: options.httpAgent,
94102
maxRetries: options.maxRetries,
95103
fetch: options.fetch,
96104
});
97-
this.apiKey = options.apiKey;
98105
this._options = options;
106+
107+
this.apiKey = apiKey;
108+
this.organization = organization;
99109
}
100110

101111
completions: API.Completions = new API.Completions(this);
@@ -116,6 +126,7 @@ export class OpenAI extends Core.APIClient {
116126
protected override defaultHeaders(): Core.Headers {
117127
return {
118128
...super.defaultHeaders(),
129+
'OpenAI-Organization': this.organization,
119130
...this._options.defaultHeaders,
120131
};
121132
}

‎src/resources/chat/chat.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ export namespace Chat {
1212
export import Completions = API.Completions;
1313
export import ChatCompletion = API.ChatCompletion;
1414
export import ChatCompletionChunk = API.ChatCompletionChunk;
15+
export import CreateChatCompletionRequestMessage = API.CreateChatCompletionRequestMessage;
1516
export import CompletionCreateParams = API.CompletionCreateParams;
1617
}

‎src/resources/chat/completions.ts

+52-100
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,55 @@ export namespace ChatCompletionChunk {
161161
}
162162
}
163163

164+
export interface CreateChatCompletionRequestMessage {
165+
/**
166+
* The contents of the message. `content` is required for all messages, and may be
167+
* null for assistant messages with function calls.
168+
*/
169+
content: string | null;
170+
171+
/**
172+
* The role of the messages author. One of `system`, `user`, `assistant`, or
173+
* `function`.
174+
*/
175+
role: 'system' | 'user' | 'assistant' | 'function';
176+
177+
/**
178+
* The name and arguments of a function that should be called, as generated by the
179+
* model.
180+
*/
181+
function_call?: CreateChatCompletionRequestMessage.FunctionCall;
182+
183+
/**
184+
* The name of the author of this message. `name` is required if role is
185+
* `function`, and it should be the name of the function whose response is in the
186+
* `content`. May contain a-z, A-Z, 0-9, and underscores, with a maximum length of
187+
* 64 characters.
188+
*/
189+
name?: string;
190+
}
191+
192+
export namespace CreateChatCompletionRequestMessage {
193+
/**
194+
* The name and arguments of a function that should be called, as generated by the
195+
* model.
196+
*/
197+
export interface FunctionCall {
198+
/**
199+
* The arguments to call the function with, as generated by the model in JSON
200+
* format. Note that the model does not always generate valid JSON, and may
201+
* hallucinate parameters not defined by your function schema. Validate the
202+
* arguments in your code before calling your function.
203+
*/
204+
arguments: string;
205+
206+
/**
207+
* The name of the function to call.
208+
*/
209+
name: string;
210+
}
211+
}
212+
164213
export type CompletionCreateParams =
165214
| CompletionCreateParams.CreateChatCompletionRequestNonStreaming
166215
| CompletionCreateParams.CreateChatCompletionRequestStreaming;
@@ -171,7 +220,7 @@ export namespace CompletionCreateParams {
171220
* A list of messages comprising the conversation so far.
172221
* [Example Python code](https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb).
173222
*/
174-
messages: Array<CompletionCreateParams.CreateChatCompletionRequestNonStreaming.Message>;
223+
messages: Array<CreateChatCompletionRequestMessage>;
175224

176225
/**
177226
* ID of the model to use. See the
@@ -296,55 +345,6 @@ export namespace CompletionCreateParams {
296345
}
297346

298347
export namespace CreateChatCompletionRequestNonStreaming {
299-
export interface Message {
300-
/**
301-
* The contents of the message. `content` is required for all messages, and may be
302-
* null for assistant messages with function calls.
303-
*/
304-
content: string | null;
305-
306-
/**
307-
* The role of the messages author. One of `system`, `user`, `assistant`, or
308-
* `function`.
309-
*/
310-
role: 'system' | 'user' | 'assistant' | 'function';
311-
312-
/**
313-
* The name and arguments of a function that should be called, as generated by the
314-
* model.
315-
*/
316-
function_call?: Message.FunctionCall;
317-
318-
/**
319-
* The name of the author of this message. `name` is required if role is
320-
* `function`, and it should be the name of the function whose response is in the
321-
* `content`. May contain a-z, A-Z, 0-9, and underscores, with a maximum length of
322-
* 64 characters.
323-
*/
324-
name?: string;
325-
}
326-
327-
export namespace Message {
328-
/**
329-
* The name and arguments of a function that should be called, as generated by the
330-
* model.
331-
*/
332-
export interface FunctionCall {
333-
/**
334-
* The arguments to call the function with, as generated by the model in JSON
335-
* format. Note that the model does not always generate valid JSON, and may
336-
* hallucinate parameters not defined by your function schema. Validate the
337-
* arguments in your code before calling your function.
338-
*/
339-
arguments: string;
340-
341-
/**
342-
* The name of the function to call.
343-
*/
344-
name: string;
345-
}
346-
}
347-
348348
export interface FunctionCallOption {
349349
/**
350350
* The name of the function to call.
@@ -383,7 +383,7 @@ export namespace CompletionCreateParams {
383383
* A list of messages comprising the conversation so far.
384384
* [Example Python code](https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb).
385385
*/
386-
messages: Array<CompletionCreateParams.CreateChatCompletionRequestStreaming.Message>;
386+
messages: Array<CreateChatCompletionRequestMessage>;
387387

388388
/**
389389
* ID of the model to use. See the
@@ -508,55 +508,6 @@ export namespace CompletionCreateParams {
508508
}
509509

510510
export namespace CreateChatCompletionRequestStreaming {
511-
export interface Message {
512-
/**
513-
* The contents of the message. `content` is required for all messages, and may be
514-
* null for assistant messages with function calls.
515-
*/
516-
content: string | null;
517-
518-
/**
519-
* The role of the messages author. One of `system`, `user`, `assistant`, or
520-
* `function`.
521-
*/
522-
role: 'system' | 'user' | 'assistant' | 'function';
523-
524-
/**
525-
* The name and arguments of a function that should be called, as generated by the
526-
* model.
527-
*/
528-
function_call?: Message.FunctionCall;
529-
530-
/**
531-
* The name of the author of this message. `name` is required if role is
532-
* `function`, and it should be the name of the function whose response is in the
533-
* `content`. May contain a-z, A-Z, 0-9, and underscores, with a maximum length of
534-
* 64 characters.
535-
*/
536-
name?: string;
537-
}
538-
539-
export namespace Message {
540-
/**
541-
* The name and arguments of a function that should be called, as generated by the
542-
* model.
543-
*/
544-
export interface FunctionCall {
545-
/**
546-
* The arguments to call the function with, as generated by the model in JSON
547-
* format. Note that the model does not always generate valid JSON, and may
548-
* hallucinate parameters not defined by your function schema. Validate the
549-
* arguments in your code before calling your function.
550-
*/
551-
arguments: string;
552-
553-
/**
554-
* The name of the function to call.
555-
*/
556-
name: string;
557-
}
558-
}
559-
560511
export interface FunctionCallOption {
561512
/**
562513
* The name of the function to call.
@@ -594,5 +545,6 @@ export namespace CompletionCreateParams {
594545
export namespace Completions {
595546
export import ChatCompletion = API.ChatCompletion;
596547
export import ChatCompletionChunk = API.ChatCompletionChunk;
548+
export import CreateChatCompletionRequestMessage = API.CreateChatCompletionRequestMessage;
597549
export import CompletionCreateParams = API.CompletionCreateParams;
598550
}

‎src/resources/chat/index.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
// File generated from our OpenAPI spec by Stainless.
22

33
export { Chat } from './chat';
4-
export { ChatCompletion, ChatCompletionChunk, CompletionCreateParams, Completions } from './completions';
4+
export {
5+
ChatCompletion,
6+
ChatCompletionChunk,
7+
CreateChatCompletionRequestMessage,
8+
CompletionCreateParams,
9+
Completions,
10+
} from './completions';

‎src/version.ts

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

0 commit comments

Comments
 (0)
Please sign in to comment.