openai 1.0.0-next.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -200
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/lib.d.ts +31 -30
- package/dist/lib.js +179 -176
- package/dist/types.d.ts +186 -175
- package/dist/types.js +6 -6
- package/package.json +13 -10
- package/postinstall.js +1 -0
package/README.md
CHANGED
|
@@ -1,204 +1,7 @@
|
|
|
1
|
-
[](https://github.com/ceifa/openai/actions/workflows/publish.yml)
|
|
2
|
-
[](https://npmjs.com/package/openai)
|
|
3
|
-
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
|
|
5
1
|
# OpenAI
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
**This is an unofficial library and has no affiliations with OpenAI**
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
### Via npm
|
|
14
|
-
|
|
15
|
-
```sh
|
|
16
|
-
npm install openai
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### Via yarn
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
yarn add openai
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Usage
|
|
26
|
-
|
|
27
|
-
### Initialize OpenAI
|
|
28
|
-
|
|
29
|
-
```js
|
|
30
|
-
import { OpenAI } from 'openai';
|
|
31
|
-
// or the commonJS way:
|
|
32
|
-
const { OpenAI } = require('openai');
|
|
33
|
-
|
|
34
|
-
// new OpenAI(apikey: string, organization?: string, version?: string)
|
|
35
|
-
const openai = new OpenAI(process.env.API_KEY, 'my-organization');
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Engine
|
|
39
|
-
|
|
40
|
-
Get all engines:
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
const engines = await openai.getEngines();
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Get specific engine:
|
|
47
|
-
|
|
48
|
-
```js
|
|
49
|
-
const engine = await openai.getEngine('curie');
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Completion
|
|
53
|
-
|
|
54
|
-
Make a completion:
|
|
55
|
-
|
|
56
|
-
```js
|
|
57
|
-
const completion = await openai.complete('curie', {
|
|
58
|
-
prompt: 'Q: Hello\nA:',
|
|
59
|
-
user: 'user-123'
|
|
60
|
-
});
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The options argument(2nd) properties follow the exactly same names as shown on official docs.
|
|
64
|
-
|
|
65
|
-
Make a completion from a fine-tuned model:
|
|
66
|
-
|
|
67
|
-
```js
|
|
68
|
-
const completion = await openai.completeFromModel('FINE_TUNED_MODEL', {
|
|
69
|
-
prompt: 'Q: Hello\nA:'
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Make a completion and stream the response:
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
const stream = await openai.completeAndStream('curie', { // or completeFromModelAndStream
|
|
77
|
-
prompt: 'Q: Hello\nA:',
|
|
78
|
-
user: 'user-123'
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
stream.pipe(response)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Make a content filter:
|
|
85
|
-
|
|
86
|
-
```js
|
|
87
|
-
const isSafe = (await openai.contentFilter('hi I am cool')) === 0;
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Search
|
|
91
|
-
|
|
92
|
-
Make a search:
|
|
93
|
-
|
|
94
|
-
```js
|
|
95
|
-
const search = await openai.search('curie', {
|
|
96
|
-
query: 'the president',
|
|
97
|
-
documents: [
|
|
98
|
-
'whitehouse',
|
|
99
|
-
'school',
|
|
100
|
-
'hospital'
|
|
101
|
-
]
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
The options argument(2nd) properties follow the exactly same names as shown on official docs.
|
|
106
|
-
|
|
107
|
-
### Classification
|
|
108
|
-
|
|
109
|
-
Classify a document:
|
|
110
|
-
|
|
111
|
-
```js
|
|
112
|
-
const classification = await openai.classify({
|
|
113
|
-
examples: [
|
|
114
|
-
['A happy moment', 'Positive'],
|
|
115
|
-
['I am sad.', 'Negative'],
|
|
116
|
-
['I am feeling awesome', 'Positive']
|
|
117
|
-
],
|
|
118
|
-
labels: ['Positive', 'Negative', 'Neutral'],
|
|
119
|
-
query: 'It is a raining day :(',
|
|
120
|
-
search_model: 'ada',
|
|
121
|
-
model: 'curie'
|
|
122
|
-
});
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
The argument properties follow the exactly same names as shown on official docs.
|
|
126
|
-
|
|
127
|
-
### Answer
|
|
128
|
-
|
|
129
|
-
Answer a question:
|
|
130
|
-
|
|
131
|
-
```js
|
|
132
|
-
const answer = await openai.answer({
|
|
133
|
-
documents: ['Puppy A is happy.', 'Puppy B is sad.'],
|
|
134
|
-
question: 'which puppy is happy?',
|
|
135
|
-
search_model: 'ada',
|
|
136
|
-
model: 'curie',
|
|
137
|
-
examples_context: 'In 2017, U.S. life expectancy was 78.6 years.',
|
|
138
|
-
examples: [['What is human life expectancy in the United States?','78 years.']],
|
|
139
|
-
});
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
The argument properties follow the exactly same names as shown on official docs.
|
|
143
|
-
|
|
144
|
-
### File
|
|
145
|
-
|
|
146
|
-
Get all files:
|
|
147
|
-
|
|
148
|
-
```js
|
|
149
|
-
const files = await openai.getFiles();
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Upload a single file:
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
const result = await openai.uploadFile('filename.json', await fs.readFileSync('somefile.json'), 'fine-tune');
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Get a single file by id:
|
|
159
|
-
|
|
160
|
-
```js
|
|
161
|
-
const file = await openai.getFile('file-29u89djwq');
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Delete a single file by id:
|
|
165
|
-
|
|
166
|
-
```js
|
|
167
|
-
await openai.deleteFile('file-29u89djwq');
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Fine-tuning
|
|
171
|
-
|
|
172
|
-
Fine-tune from a file:
|
|
173
|
-
|
|
174
|
-
```js
|
|
175
|
-
const result = await openai.finetune({
|
|
176
|
-
training_file: 'file-29u89djwq'
|
|
177
|
-
});
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
The argument properties follow the exactly same names as shown on official docs.
|
|
181
|
-
|
|
182
|
-
Get all fine-tunes:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
const finetunes = await openai.getFinetunes();
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Get a specific fine-tune:
|
|
189
|
-
|
|
190
|
-
```js
|
|
191
|
-
const finetune = await openai.getFinetune('ftjob-AF1WoRqd3aJ');
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Cancel a fine-tune:
|
|
195
|
-
|
|
196
|
-
```js
|
|
197
|
-
await openai.cancelFinetune('ftjob-AF1WoRqd3aJ');
|
|
198
|
-
```
|
|
3
|
+
> tl;dr: Please consider using [GPT-X](https://www.npmjs.com/package/gpt-x) instead
|
|
199
4
|
|
|
200
|
-
|
|
5
|
+
This package will be replaced soon by an official one from OpenAI. If you still want to use the unofficial version package, just switch to the new one called [GPT-X](https://www.npmjs.com/package/gpt-x), it will remain the same API for compatibility reasons.
|
|
201
6
|
|
|
202
|
-
|
|
203
|
-
const events = await openai.getFinetuneEvents('ftjob-AF1WoRqd3aJ');
|
|
204
|
-
```
|
|
7
|
+
Enter in our community about Natural language generation to share and learn about OpenAI, prompt engineering and other providers: https://discord.gg/8ZwcSt9XkD
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './lib.js';
|
|
2
|
-
export * from './types.js';
|
|
1
|
+
export * from './lib.js';
|
|
2
|
+
export * from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './lib.js';
|
|
2
|
-
export * from './types.js';
|
|
1
|
+
export * from './lib.js';
|
|
2
|
+
export * from './types.js';
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Answer, AnswerRequest, Classification, ClassificationRequest, Completion, CompletionRequest, ContentLabel, Engine, EngineId, File, FilePurpose, FineTune, FineTuneEvent, FineTuneRequest, JsonLines, SearchDocument, SearchRequest } from './types.js';
|
|
3
|
-
import { Readable } from 'stream';
|
|
4
|
-
export declare class OpenAI {
|
|
5
|
-
private readonly url;
|
|
6
|
-
private readonly headers;
|
|
7
|
-
constructor(apiKey: string, organizationId?: string, version?: string);
|
|
8
|
-
getEngines(): Promise<Engine[]>;
|
|
9
|
-
getEngine(engine: EngineId): Promise<Engine>;
|
|
10
|
-
complete(engine: EngineId, options: CompletionRequest): Promise<Completion>;
|
|
11
|
-
completeFromModel(fineTunedModel: string, options: CompletionRequest): Promise<Completion>;
|
|
12
|
-
completeAndStream(engine: EngineId, options: CompletionRequest): Promise<Readable>;
|
|
13
|
-
completeFromModelAndStream(fineTunedModel: string, options: CompletionRequest): Promise<Readable>;
|
|
14
|
-
contentFilter(content: string, user?: string): Promise<ContentLabel>;
|
|
15
|
-
search(engine: EngineId, options: SearchRequest): Promise<SearchDocument[]>;
|
|
16
|
-
classify(options: ClassificationRequest): Promise<Classification>;
|
|
17
|
-
answer(options: AnswerRequest): Promise<Answer>;
|
|
18
|
-
getFiles(): Promise<File[]>;
|
|
19
|
-
uploadFile(file: string, jsonlines: JsonLines, purpose: FilePurpose): Promise<File>;
|
|
20
|
-
getFile(fileId: string): Promise<File>;
|
|
21
|
-
deleteFile(fileId: string): Promise<void>;
|
|
22
|
-
finetune(options: FineTuneRequest): Promise<FineTune>;
|
|
23
|
-
getFinetunes(): Promise<FineTune[]>;
|
|
24
|
-
getFinetune(finetuneId: string): Promise<FineTune>;
|
|
25
|
-
cancelFinetune(finetuneId: string): Promise<FineTune>;
|
|
26
|
-
getFinetuneEvents(finetuneId: string): Promise<FineTuneEvent[]>;
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
private
|
|
30
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Answer, AnswerRequest, Classification, ClassificationRequest, Completion, CompletionRequest, ContentLabel, Embedding, EmbeddingRequest, Engine, EngineId, File, FilePurpose, FineTune, FineTuneEvent, FineTuneRequest, JsonLines, List, SearchDocument, SearchRequest } from './types.js';
|
|
3
|
+
import { Readable } from 'stream';
|
|
4
|
+
export declare class OpenAI {
|
|
5
|
+
private readonly url;
|
|
6
|
+
private readonly headers;
|
|
7
|
+
constructor(apiKey: string, organizationId?: string, version?: string);
|
|
8
|
+
getEngines(): Promise<Engine[]>;
|
|
9
|
+
getEngine(engine: EngineId): Promise<Engine>;
|
|
10
|
+
complete(engine: EngineId, options: CompletionRequest): Promise<Completion>;
|
|
11
|
+
completeFromModel(fineTunedModel: string, options: CompletionRequest): Promise<Completion>;
|
|
12
|
+
completeAndStream(engine: EngineId, options: CompletionRequest): Promise<Readable>;
|
|
13
|
+
completeFromModelAndStream(fineTunedModel: string, options: CompletionRequest): Promise<Readable>;
|
|
14
|
+
contentFilter(content: string, user?: string): Promise<ContentLabel>;
|
|
15
|
+
search(engine: EngineId, options: SearchRequest): Promise<SearchDocument[]>;
|
|
16
|
+
classify(options: ClassificationRequest): Promise<Classification>;
|
|
17
|
+
answer(options: AnswerRequest): Promise<Answer>;
|
|
18
|
+
getFiles(): Promise<File[]>;
|
|
19
|
+
uploadFile(file: string, jsonlines: JsonLines, purpose: FilePurpose): Promise<File>;
|
|
20
|
+
getFile(fileId: string): Promise<File>;
|
|
21
|
+
deleteFile(fileId: string): Promise<void>;
|
|
22
|
+
finetune(options: FineTuneRequest): Promise<FineTune>;
|
|
23
|
+
getFinetunes(): Promise<FineTune[]>;
|
|
24
|
+
getFinetune(finetuneId: string): Promise<FineTune>;
|
|
25
|
+
cancelFinetune(finetuneId: string): Promise<FineTune>;
|
|
26
|
+
getFinetuneEvents(finetuneId: string): Promise<FineTuneEvent[]>;
|
|
27
|
+
createEmbedding(engine: EngineId, options: EmbeddingRequest): Promise<List<Embedding>>;
|
|
28
|
+
private requestRaw;
|
|
29
|
+
private request;
|
|
30
|
+
private eventStreamTransformer;
|
|
31
|
+
}
|
package/dist/lib.js
CHANGED
|
@@ -1,176 +1,179 @@
|
|
|
1
|
-
import { ContentLabel, } from './types.js';
|
|
2
|
-
import { Transform } from 'stream';
|
|
3
|
-
import FormData from 'form-data';
|
|
4
|
-
import fetch from 'node-fetch';
|
|
5
|
-
const baseUrl = 'https://api.openai.com';
|
|
6
|
-
const defaultVersion = 'v1';
|
|
7
|
-
export class OpenAI {
|
|
8
|
-
constructor(apiKey, organizationId, version = defaultVersion) {
|
|
9
|
-
this.headers = {
|
|
10
|
-
'authorization': `Bearer ${apiKey}`,
|
|
11
|
-
'content-type': 'application/json',
|
|
12
|
-
};
|
|
13
|
-
if (organizationId) {
|
|
14
|
-
this.headers['openai-organization'] = organizationId;
|
|
15
|
-
}
|
|
16
|
-
this.url = `${baseUrl}/${version}`;
|
|
17
|
-
}
|
|
18
|
-
getEngines() {
|
|
19
|
-
return this.request('/engines', 'GET').then((r) => r.data);
|
|
20
|
-
}
|
|
21
|
-
getEngine(engine) {
|
|
22
|
-
return this.request(`/engines/${engine}`, 'GET');
|
|
23
|
-
}
|
|
24
|
-
complete(engine, options) {
|
|
25
|
-
return this.request(`/engines/${engine}/completions`, 'POST', options);
|
|
26
|
-
}
|
|
27
|
-
completeFromModel(fineTunedModel, options) {
|
|
28
|
-
return this.request(`/completions`, 'POST', { ...options, model: fineTunedModel });
|
|
29
|
-
}
|
|
30
|
-
async completeAndStream(engine, options) {
|
|
31
|
-
const request = await this.requestRaw(`/engines/${engine}/completions`, 'POST', { ...options, stream: true });
|
|
32
|
-
return request.body.pipe(this.eventStreamTransformer());
|
|
33
|
-
}
|
|
34
|
-
async completeFromModelAndStream(fineTunedModel, options) {
|
|
35
|
-
const request = await this.requestRaw(`/completions`, 'POST', {
|
|
36
|
-
...options,
|
|
37
|
-
model: fineTunedModel,
|
|
38
|
-
stream: true,
|
|
39
|
-
});
|
|
40
|
-
return request.body.pipe(this.eventStreamTransformer());
|
|
41
|
-
}
|
|
42
|
-
async contentFilter(content, user) {
|
|
43
|
-
const completion = await this.complete('content-filter-alpha-c4', {
|
|
44
|
-
prompt: `<|endoftext|>${content}\n--\nLabel:`,
|
|
45
|
-
temperature: 0,
|
|
46
|
-
max_tokens: 1,
|
|
47
|
-
top_p: 1,
|
|
48
|
-
frequency_penalty: 0,
|
|
49
|
-
presence_penalty: 0,
|
|
50
|
-
logprobs: 10,
|
|
51
|
-
user,
|
|
52
|
-
});
|
|
53
|
-
let label = Number(completion.choices[0].text);
|
|
54
|
-
if (label === ContentLabel.Unsafe) {
|
|
55
|
-
const logprobs = completion.choices[0].logprobs?.top_logprobs[0];
|
|
56
|
-
if (logprobs && logprobs['2'] < -0.355) {
|
|
57
|
-
if (logprobs['0'] && logprobs['1']) {
|
|
58
|
-
label = logprobs['0'] >= logprobs['1'] ? ContentLabel.Safe : ContentLabel.Sensitive;
|
|
59
|
-
}
|
|
60
|
-
else if (logprobs['0']) {
|
|
61
|
-
label = ContentLabel.Safe;
|
|
62
|
-
}
|
|
63
|
-
else if (logprobs['1']) {
|
|
64
|
-
label = ContentLabel.Sensitive;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (![0, 1, 2].includes(label)) {
|
|
69
|
-
label = ContentLabel.Unsafe;
|
|
70
|
-
}
|
|
71
|
-
return label;
|
|
72
|
-
}
|
|
73
|
-
search(engine, options) {
|
|
74
|
-
return this.request(`/engines/${engine}/search`, 'POST', options).then((r) => r.data);
|
|
75
|
-
}
|
|
76
|
-
classify(options) {
|
|
77
|
-
return this.request('/classifications', 'POST', options);
|
|
78
|
-
}
|
|
79
|
-
answer(options) {
|
|
80
|
-
return this.request('/answers', 'POST', options);
|
|
81
|
-
}
|
|
82
|
-
getFiles() {
|
|
83
|
-
return this.request('/files', 'GET').then((r) => r.data);
|
|
84
|
-
}
|
|
85
|
-
uploadFile(file, jsonlines, purpose) {
|
|
86
|
-
const data = new FormData();
|
|
87
|
-
let fileJsonlines;
|
|
88
|
-
if (Array.isArray(jsonlines)) {
|
|
89
|
-
if (typeof jsonlines[0] === 'object') {
|
|
90
|
-
jsonlines = jsonlines.map((j) => JSON.stringify(j));
|
|
91
|
-
}
|
|
92
|
-
fileJsonlines = jsonlines.join('\n');
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
fileJsonlines = jsonlines;
|
|
96
|
-
}
|
|
97
|
-
data.append('file', fileJsonlines, file);
|
|
98
|
-
data.append('purpose', purpose);
|
|
99
|
-
return this.request('/files', 'POST', data);
|
|
100
|
-
}
|
|
101
|
-
getFile(fileId) {
|
|
102
|
-
return this.request(`/files/${fileId}`, 'GET');
|
|
103
|
-
}
|
|
104
|
-
deleteFile(fileId) {
|
|
105
|
-
return this.request(`/files/${fileId}`, 'DELETE');
|
|
106
|
-
}
|
|
107
|
-
finetune(options) {
|
|
108
|
-
return this.request(`/fine-tunes`, 'POST', options);
|
|
109
|
-
}
|
|
110
|
-
getFinetunes() {
|
|
111
|
-
return this.request('/fine-tunes', 'GET').then((r) => r.data);
|
|
112
|
-
}
|
|
113
|
-
getFinetune(finetuneId) {
|
|
114
|
-
return this.request(`/fine-tunes/${finetuneId}`, 'GET');
|
|
115
|
-
}
|
|
116
|
-
cancelFinetune(finetuneId) {
|
|
117
|
-
return this.request(`/fine-tunes/${finetuneId}/cancel`, 'POST');
|
|
118
|
-
}
|
|
119
|
-
getFinetuneEvents(finetuneId) {
|
|
120
|
-
return this.request(`/fine-tunes/${finetuneId}/events`, 'GET').then((r) => r.data);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
errorBody =
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
1
|
+
import { ContentLabel, } from './types.js';
|
|
2
|
+
import { Transform } from 'stream';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import fetch from 'node-fetch';
|
|
5
|
+
const baseUrl = 'https://api.openai.com';
|
|
6
|
+
const defaultVersion = 'v1';
|
|
7
|
+
export class OpenAI {
|
|
8
|
+
constructor(apiKey, organizationId, version = defaultVersion) {
|
|
9
|
+
this.headers = {
|
|
10
|
+
'authorization': `Bearer ${apiKey}`,
|
|
11
|
+
'content-type': 'application/json',
|
|
12
|
+
};
|
|
13
|
+
if (organizationId) {
|
|
14
|
+
this.headers['openai-organization'] = organizationId;
|
|
15
|
+
}
|
|
16
|
+
this.url = `${baseUrl}/${version}`;
|
|
17
|
+
}
|
|
18
|
+
getEngines() {
|
|
19
|
+
return this.request('/engines', 'GET').then((r) => r.data);
|
|
20
|
+
}
|
|
21
|
+
getEngine(engine) {
|
|
22
|
+
return this.request(`/engines/${engine}`, 'GET');
|
|
23
|
+
}
|
|
24
|
+
complete(engine, options) {
|
|
25
|
+
return this.request(`/engines/${engine}/completions`, 'POST', options);
|
|
26
|
+
}
|
|
27
|
+
completeFromModel(fineTunedModel, options) {
|
|
28
|
+
return this.request(`/completions`, 'POST', { ...options, model: fineTunedModel });
|
|
29
|
+
}
|
|
30
|
+
async completeAndStream(engine, options) {
|
|
31
|
+
const request = await this.requestRaw(`/engines/${engine}/completions`, 'POST', { ...options, stream: true });
|
|
32
|
+
return request.body.pipe(this.eventStreamTransformer());
|
|
33
|
+
}
|
|
34
|
+
async completeFromModelAndStream(fineTunedModel, options) {
|
|
35
|
+
const request = await this.requestRaw(`/completions`, 'POST', {
|
|
36
|
+
...options,
|
|
37
|
+
model: fineTunedModel,
|
|
38
|
+
stream: true,
|
|
39
|
+
});
|
|
40
|
+
return request.body.pipe(this.eventStreamTransformer());
|
|
41
|
+
}
|
|
42
|
+
async contentFilter(content, user) {
|
|
43
|
+
const completion = await this.complete('content-filter-alpha-c4', {
|
|
44
|
+
prompt: `<|endoftext|>${content}\n--\nLabel:`,
|
|
45
|
+
temperature: 0,
|
|
46
|
+
max_tokens: 1,
|
|
47
|
+
top_p: 1,
|
|
48
|
+
frequency_penalty: 0,
|
|
49
|
+
presence_penalty: 0,
|
|
50
|
+
logprobs: 10,
|
|
51
|
+
user,
|
|
52
|
+
});
|
|
53
|
+
let label = Number(completion.choices[0].text);
|
|
54
|
+
if (label === ContentLabel.Unsafe) {
|
|
55
|
+
const logprobs = completion.choices[0].logprobs?.top_logprobs[0];
|
|
56
|
+
if (logprobs && logprobs['2'] < -0.355) {
|
|
57
|
+
if (logprobs['0'] && logprobs['1']) {
|
|
58
|
+
label = logprobs['0'] >= logprobs['1'] ? ContentLabel.Safe : ContentLabel.Sensitive;
|
|
59
|
+
}
|
|
60
|
+
else if (logprobs['0']) {
|
|
61
|
+
label = ContentLabel.Safe;
|
|
62
|
+
}
|
|
63
|
+
else if (logprobs['1']) {
|
|
64
|
+
label = ContentLabel.Sensitive;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (![0, 1, 2].includes(label)) {
|
|
69
|
+
label = ContentLabel.Unsafe;
|
|
70
|
+
}
|
|
71
|
+
return label;
|
|
72
|
+
}
|
|
73
|
+
search(engine, options) {
|
|
74
|
+
return this.request(`/engines/${engine}/search`, 'POST', options).then((r) => r.data);
|
|
75
|
+
}
|
|
76
|
+
classify(options) {
|
|
77
|
+
return this.request('/classifications', 'POST', options);
|
|
78
|
+
}
|
|
79
|
+
answer(options) {
|
|
80
|
+
return this.request('/answers', 'POST', options);
|
|
81
|
+
}
|
|
82
|
+
getFiles() {
|
|
83
|
+
return this.request('/files', 'GET').then((r) => r.data);
|
|
84
|
+
}
|
|
85
|
+
uploadFile(file, jsonlines, purpose) {
|
|
86
|
+
const data = new FormData();
|
|
87
|
+
let fileJsonlines;
|
|
88
|
+
if (Array.isArray(jsonlines)) {
|
|
89
|
+
if (typeof jsonlines[0] === 'object') {
|
|
90
|
+
jsonlines = jsonlines.map((j) => JSON.stringify(j));
|
|
91
|
+
}
|
|
92
|
+
fileJsonlines = jsonlines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
fileJsonlines = jsonlines;
|
|
96
|
+
}
|
|
97
|
+
data.append('file', fileJsonlines, file);
|
|
98
|
+
data.append('purpose', purpose);
|
|
99
|
+
return this.request('/files', 'POST', data);
|
|
100
|
+
}
|
|
101
|
+
getFile(fileId) {
|
|
102
|
+
return this.request(`/files/${fileId}`, 'GET');
|
|
103
|
+
}
|
|
104
|
+
deleteFile(fileId) {
|
|
105
|
+
return this.request(`/files/${fileId}`, 'DELETE');
|
|
106
|
+
}
|
|
107
|
+
finetune(options) {
|
|
108
|
+
return this.request(`/fine-tunes`, 'POST', options);
|
|
109
|
+
}
|
|
110
|
+
getFinetunes() {
|
|
111
|
+
return this.request('/fine-tunes', 'GET').then((r) => r.data);
|
|
112
|
+
}
|
|
113
|
+
getFinetune(finetuneId) {
|
|
114
|
+
return this.request(`/fine-tunes/${finetuneId}`, 'GET');
|
|
115
|
+
}
|
|
116
|
+
cancelFinetune(finetuneId) {
|
|
117
|
+
return this.request(`/fine-tunes/${finetuneId}/cancel`, 'POST');
|
|
118
|
+
}
|
|
119
|
+
getFinetuneEvents(finetuneId) {
|
|
120
|
+
return this.request(`/fine-tunes/${finetuneId}/events`, 'GET').then((r) => r.data);
|
|
121
|
+
}
|
|
122
|
+
createEmbedding(engine, options) {
|
|
123
|
+
return this.request(`/engines/${engine}/embeddings`, 'POST', options);
|
|
124
|
+
}
|
|
125
|
+
async requestRaw(path, method, body) {
|
|
126
|
+
let headers = { ...this.headers };
|
|
127
|
+
if (body instanceof FormData) {
|
|
128
|
+
delete headers['content-type'];
|
|
129
|
+
headers = body.getHeaders(headers);
|
|
130
|
+
}
|
|
131
|
+
else if (!['string', 'undefined'].includes(typeof body)) {
|
|
132
|
+
body = JSON.stringify(body);
|
|
133
|
+
}
|
|
134
|
+
const response = await fetch(this.url + path, {
|
|
135
|
+
headers,
|
|
136
|
+
method,
|
|
137
|
+
body: body,
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
let errorBody;
|
|
141
|
+
try {
|
|
142
|
+
const { error: { message }, } = (await response.json());
|
|
143
|
+
errorBody = message;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
try {
|
|
147
|
+
errorBody = await response.text();
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
errorBody = 'Failed to get body as text';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
throw new Error(`OpenAI did not return ok: ${response.status} ~ Error body: ${errorBody}`);
|
|
154
|
+
}
|
|
155
|
+
return response;
|
|
156
|
+
}
|
|
157
|
+
async request(path, method, body) {
|
|
158
|
+
const response = await this.requestRaw(path, method, body);
|
|
159
|
+
return response.json();
|
|
160
|
+
}
|
|
161
|
+
eventStreamTransformer() {
|
|
162
|
+
const dataHeader = Buffer.from('data: ');
|
|
163
|
+
return new Transform({
|
|
164
|
+
transform: function (chunk, _, callback) {
|
|
165
|
+
if (chunk.length >= dataHeader.length &&
|
|
166
|
+
dataHeader.compare(chunk, undefined, dataHeader.length) === 0) {
|
|
167
|
+
if (this.prevChunk) {
|
|
168
|
+
const completion = JSON.parse(this.prevChunk.toString());
|
|
169
|
+
this.push(completion.choices[0].text);
|
|
170
|
+
this.prevChunk = undefined;
|
|
171
|
+
}
|
|
172
|
+
chunk = chunk.slice(dataHeader.length);
|
|
173
|
+
}
|
|
174
|
+
this.prevChunk = this.prevChunk ? Buffer.concat([this.prevChunk, chunk]) : chunk;
|
|
175
|
+
callback();
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,175 +1,186 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
export interface
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
export interface
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
object: 'fine-tune';
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
1
|
+
declare type LiteralUnion<T extends U, U = string> = T | (U & {});
|
|
2
|
+
export declare type EngineId = LiteralUnion<'davinci' | 'curie' | 'babbage' | 'ada'>;
|
|
3
|
+
export interface Engine {
|
|
4
|
+
id: EngineId;
|
|
5
|
+
object: 'engine';
|
|
6
|
+
created?: Date;
|
|
7
|
+
max_replicas?: number;
|
|
8
|
+
owner: string;
|
|
9
|
+
permissions: unknown;
|
|
10
|
+
ready: boolean;
|
|
11
|
+
ready_replicas: unknown;
|
|
12
|
+
replicas: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface List<T> {
|
|
15
|
+
object: 'list';
|
|
16
|
+
data: T[];
|
|
17
|
+
model?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CompletionRequest {
|
|
20
|
+
prompt?: string | string[];
|
|
21
|
+
max_tokens?: number;
|
|
22
|
+
temperature?: number;
|
|
23
|
+
top_p?: number;
|
|
24
|
+
n?: number;
|
|
25
|
+
logprobs?: number;
|
|
26
|
+
echo?: boolean;
|
|
27
|
+
stop?: string | string[];
|
|
28
|
+
presence_penalty?: number;
|
|
29
|
+
frequency_penalty?: number;
|
|
30
|
+
best_of?: number;
|
|
31
|
+
logit_bias?: Record<string, number>;
|
|
32
|
+
user?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface LogProbs {
|
|
35
|
+
tokens: string[];
|
|
36
|
+
token_logprobs: number[];
|
|
37
|
+
top_logprobs: Array<Record<string, number>>;
|
|
38
|
+
text_offset: number[];
|
|
39
|
+
}
|
|
40
|
+
export interface Choice {
|
|
41
|
+
text: string;
|
|
42
|
+
index: number;
|
|
43
|
+
logprobs: LogProbs | null;
|
|
44
|
+
finish_reason: string | null;
|
|
45
|
+
}
|
|
46
|
+
export interface Completion {
|
|
47
|
+
id: string;
|
|
48
|
+
object: 'text_completion';
|
|
49
|
+
created: number;
|
|
50
|
+
model: string;
|
|
51
|
+
choices: Choice[];
|
|
52
|
+
}
|
|
53
|
+
export declare enum ContentLabel {
|
|
54
|
+
Safe = 0,
|
|
55
|
+
Sensitive = 1,
|
|
56
|
+
Unsafe = 2
|
|
57
|
+
}
|
|
58
|
+
export interface SearchRequest {
|
|
59
|
+
query: string;
|
|
60
|
+
documents?: string[];
|
|
61
|
+
file?: string;
|
|
62
|
+
max_rerank?: number;
|
|
63
|
+
return_metadata?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface SearchDocument {
|
|
66
|
+
document: number;
|
|
67
|
+
object: 'search_result';
|
|
68
|
+
score: number;
|
|
69
|
+
}
|
|
70
|
+
export interface ClassificationRequest {
|
|
71
|
+
model: string;
|
|
72
|
+
query: string;
|
|
73
|
+
examples?: string[];
|
|
74
|
+
file?: string;
|
|
75
|
+
labels?: string[] | null;
|
|
76
|
+
search_model?: string;
|
|
77
|
+
temperature?: number;
|
|
78
|
+
logprobs?: number;
|
|
79
|
+
max_examples?: number;
|
|
80
|
+
logit_bias?: Record<string, number>;
|
|
81
|
+
return_prompt?: boolean;
|
|
82
|
+
return_metadata?: boolean;
|
|
83
|
+
expand?: string[];
|
|
84
|
+
}
|
|
85
|
+
export interface ClassificationExample {
|
|
86
|
+
document: number;
|
|
87
|
+
label: string;
|
|
88
|
+
text: string;
|
|
89
|
+
}
|
|
90
|
+
export interface Classification {
|
|
91
|
+
completion: string;
|
|
92
|
+
label: string;
|
|
93
|
+
model: string;
|
|
94
|
+
object: 'classification';
|
|
95
|
+
search_model: string;
|
|
96
|
+
selected_examples: ClassificationExample[];
|
|
97
|
+
}
|
|
98
|
+
export interface AnswerRequest {
|
|
99
|
+
model: string;
|
|
100
|
+
question: string;
|
|
101
|
+
examples: Array<[string, string]>;
|
|
102
|
+
examples_context: string;
|
|
103
|
+
documents?: string[];
|
|
104
|
+
file?: string;
|
|
105
|
+
search_model?: string;
|
|
106
|
+
max_rerank?: number;
|
|
107
|
+
temperature?: number;
|
|
108
|
+
logprobs?: number;
|
|
109
|
+
max_tokens?: number;
|
|
110
|
+
stop?: string | string[];
|
|
111
|
+
n?: number;
|
|
112
|
+
logit_bias?: Record<string, number>;
|
|
113
|
+
return_metadata?: boolean;
|
|
114
|
+
return_prompt?: boolean;
|
|
115
|
+
expand?: string[];
|
|
116
|
+
}
|
|
117
|
+
export interface AnswerDocument {
|
|
118
|
+
document: number;
|
|
119
|
+
text: string;
|
|
120
|
+
}
|
|
121
|
+
export interface Answer {
|
|
122
|
+
answers: string[];
|
|
123
|
+
completion: string | Completion;
|
|
124
|
+
model: string;
|
|
125
|
+
object: 'answer';
|
|
126
|
+
search_model: string;
|
|
127
|
+
prompt: string;
|
|
128
|
+
selected_documents: AnswerDocument[];
|
|
129
|
+
}
|
|
130
|
+
export declare type FilePurpose = 'search' | 'answers' | 'classifications' | 'fine-tune';
|
|
131
|
+
export declare type JsonLines = string | string[] | unknown[];
|
|
132
|
+
export interface File {
|
|
133
|
+
id: string;
|
|
134
|
+
object: string;
|
|
135
|
+
bytes: number;
|
|
136
|
+
created_at: number;
|
|
137
|
+
filename: string;
|
|
138
|
+
purpose: FilePurpose;
|
|
139
|
+
}
|
|
140
|
+
export interface Hyperparams {
|
|
141
|
+
n_epochs?: number;
|
|
142
|
+
batch_size?: number;
|
|
143
|
+
learning_rate_multiplier?: number;
|
|
144
|
+
use_packing?: boolean;
|
|
145
|
+
prompt_loss_weight?: number;
|
|
146
|
+
}
|
|
147
|
+
export interface FineTuneRequest extends Hyperparams {
|
|
148
|
+
training_file: string;
|
|
149
|
+
validation_file?: string;
|
|
150
|
+
model?: string;
|
|
151
|
+
compute_classification_metrics?: boolean;
|
|
152
|
+
classification_n_classes?: number;
|
|
153
|
+
classification_positive_class?: string;
|
|
154
|
+
classification_betas?: number[];
|
|
155
|
+
}
|
|
156
|
+
export interface FineTuneEvent {
|
|
157
|
+
object: 'fine-tune-event';
|
|
158
|
+
created_at: number;
|
|
159
|
+
level: string;
|
|
160
|
+
message: string;
|
|
161
|
+
}
|
|
162
|
+
export interface FineTune {
|
|
163
|
+
id: string;
|
|
164
|
+
object: 'fine-tune';
|
|
165
|
+
model: string;
|
|
166
|
+
created_at: number;
|
|
167
|
+
events: FineTuneEvent[];
|
|
168
|
+
fine_tuned_model: string;
|
|
169
|
+
hyperparams: Hyperparams;
|
|
170
|
+
organization_id: string;
|
|
171
|
+
result_files: File[];
|
|
172
|
+
status: string;
|
|
173
|
+
validation_files: File[];
|
|
174
|
+
training_files: File[];
|
|
175
|
+
updated_at: number;
|
|
176
|
+
user_id: string;
|
|
177
|
+
}
|
|
178
|
+
export interface EmbeddingRequest {
|
|
179
|
+
input: string | string[];
|
|
180
|
+
}
|
|
181
|
+
export interface Embedding {
|
|
182
|
+
object: 'embedding';
|
|
183
|
+
embedding: number[];
|
|
184
|
+
index: number;
|
|
185
|
+
}
|
|
186
|
+
export {};
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export var ContentLabel;
|
|
2
|
-
(function (ContentLabel) {
|
|
3
|
-
ContentLabel[ContentLabel["Safe"] = 0] = "Safe";
|
|
4
|
-
ContentLabel[ContentLabel["Sensitive"] = 1] = "Sensitive";
|
|
5
|
-
ContentLabel[ContentLabel["Unsafe"] = 2] = "Unsafe";
|
|
6
|
-
})(ContentLabel || (ContentLabel = {}));
|
|
1
|
+
export var ContentLabel;
|
|
2
|
+
(function (ContentLabel) {
|
|
3
|
+
ContentLabel[ContentLabel["Safe"] = 0] = "Safe";
|
|
4
|
+
ContentLabel[ContentLabel["Sensitive"] = 1] = "Sensitive";
|
|
5
|
+
ContentLabel[ContentLabel["Unsafe"] = 2] = "Unsafe";
|
|
6
|
+
})(ContentLabel || (ContentLabel = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Tiny OpenAI API wrapper",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"build": "tsc -d",
|
|
10
10
|
"clean": "rm -rf dist",
|
|
11
11
|
"lint": "eslint . --fix --cache && prettier --write src",
|
|
12
|
-
"lint:nofix": "eslint . && prettier --check src"
|
|
12
|
+
"lint:nofix": "eslint . && prettier --check src",
|
|
13
|
+
"postinstall": "node ./postinstall.js"
|
|
13
14
|
},
|
|
14
15
|
"repository": {
|
|
15
16
|
"type": "git",
|
|
@@ -20,25 +21,27 @@
|
|
|
20
21
|
"keywords": [
|
|
21
22
|
"gpt-3",
|
|
22
23
|
"gpt",
|
|
23
|
-
"ai"
|
|
24
|
+
"ai",
|
|
25
|
+
"openai"
|
|
24
26
|
],
|
|
25
27
|
"bugs": {
|
|
26
28
|
"url": "https://github.com/ceifa/openai/issues"
|
|
27
29
|
},
|
|
28
30
|
"homepage": "https://github.com/ceifa/openai#readme",
|
|
29
31
|
"devDependencies": {
|
|
30
|
-
"@types/node": "16.
|
|
31
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
32
|
-
"@typescript-eslint/parser": "5.
|
|
33
|
-
"eslint": "8.0
|
|
32
|
+
"@types/node": "16.11.11",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "5.5.0",
|
|
34
|
+
"@typescript-eslint/parser": "5.5.0",
|
|
35
|
+
"eslint": "8.3.0",
|
|
34
36
|
"eslint-config-prettier": "8.3.0",
|
|
35
37
|
"eslint-plugin-prettier": "4.0.0",
|
|
36
38
|
"eslint-plugin-sort-imports-es6-autofix": "0.6.0",
|
|
37
|
-
"prettier": "2.
|
|
38
|
-
"typescript": "4.
|
|
39
|
+
"prettier": "2.5.0",
|
|
40
|
+
"typescript": "4.5.2"
|
|
39
41
|
},
|
|
40
42
|
"dependencies": {
|
|
41
43
|
"form-data": "4.0.0",
|
|
42
|
-
"node-fetch": "3.
|
|
44
|
+
"node-fetch": "3.1.0",
|
|
45
|
+
"openai": "^1.1.2"
|
|
43
46
|
}
|
|
44
47
|
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log(`\u001b[0m\u001b[96mEnter in our community about Natural language generation to share and learn about OpenAI, prompt engineering and other providers: \u001b[94mhttps://discord.gg/8ZwcSt9XkD\u001b[0m\u001b[22m\u001b[39m`);
|