Comparing version 1.0.0 to 1.1.0
@@ -1,31 +0,2 @@ | ||
/// <reference types="node" /> | ||
import { Answer, AnswerRequest, Classification, ClassificationRequest, Completion, CompletionRequest, ContentLabel, Engine, EngineId, File, FilePurpose, FineTune, FineTuneEvent, FineTuneRequest, JsonLines, SearchDocument, SearchRequest } from './types'; | ||
import { Readable } from 'stream'; | ||
export * from './types'; | ||
export declare class OpenAI { | ||
private readonly url; | ||
private readonly headers; | ||
constructor(apiKey: string, organizationId?: string, version?: string); | ||
getEngines(): Promise<Engine[]>; | ||
getEngine(engine: EngineId): Promise<Engine>; | ||
complete(engine: EngineId, options: CompletionRequest): Promise<Completion>; | ||
completeFromModel(fineTunedModel: string, options: CompletionRequest): Promise<Completion>; | ||
completeAndStream(engine: EngineId, options: CompletionRequest): Promise<Readable>; | ||
completeFromModelAndStream(fineTunedModel: string, options: CompletionRequest): Promise<Readable>; | ||
contentFilter(content: string, user?: string): Promise<ContentLabel>; | ||
search(engine: EngineId, options: SearchRequest): Promise<SearchDocument[]>; | ||
classify(options: ClassificationRequest): Promise<Classification>; | ||
answer(options: AnswerRequest): Promise<Answer>; | ||
getFiles(): Promise<File[]>; | ||
uploadFile(file: string, jsonlines: JsonLines, purpose: FilePurpose): Promise<File>; | ||
getFile(fileId: string): Promise<File>; | ||
deleteFile(fileId: string): Promise<void>; | ||
finetune(options: FineTuneRequest): Promise<FineTune>; | ||
getFinetunes(): Promise<FineTune[]>; | ||
getFinetune(finetuneId: string): Promise<FineTune>; | ||
cancelFinetune(finetuneId: string): Promise<FineTune>; | ||
getFinetuneEvents(finetuneId: string): Promise<FineTuneEvent[]>; | ||
private requestRaw; | ||
private request; | ||
private eventStreamTransformer; | ||
} | ||
export * from './lib.js'; | ||
export * from './types.js'; |
@@ -1,193 +0,2 @@ | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "tslib", "stream", "form-data", "node-fetch", "./types"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OpenAI = void 0; | ||
const tslib_1 = require("tslib"); | ||
const stream_1 = require("stream"); | ||
const form_data_1 = (0, tslib_1.__importDefault)(require("form-data")); | ||
const node_fetch_1 = (0, tslib_1.__importDefault)(require("node-fetch")); | ||
const baseUrl = 'https://api.openai.com'; | ||
const defaultVersion = 'v1'; | ||
(0, tslib_1.__exportStar)(require("./types"), exports); | ||
class OpenAI { | ||
url; | ||
headers; | ||
constructor(apiKey, organizationId, version = defaultVersion) { | ||
this.headers = { | ||
'authorization': `Bearer ${apiKey}`, | ||
'content-type': 'application/json', | ||
}; | ||
if (organizationId) { | ||
this.headers['openai-organization'] = organizationId; | ||
} | ||
this.url = `${baseUrl}/${version}`; | ||
} | ||
getEngines() { | ||
return this.request('/engines', 'GET').then((r) => r.data); | ||
} | ||
getEngine(engine) { | ||
return this.request(`/engines/${engine}`, 'GET'); | ||
} | ||
complete(engine, options) { | ||
return this.request(`/engines/${engine}/completions`, 'POST', options); | ||
} | ||
completeFromModel(fineTunedModel, options) { | ||
return this.request(`/completions`, 'POST', { ...options, model: fineTunedModel }); | ||
} | ||
async completeAndStream(engine, options) { | ||
const request = await this.requestRaw(`/engines/${engine}/completions`, 'POST', { ...options, stream: true }); | ||
return request.body.pipe(this.eventStreamTransformer()); | ||
} | ||
async completeFromModelAndStream(fineTunedModel, options) { | ||
const request = await this.requestRaw(`/completions`, 'POST', { | ||
...options, | ||
model: fineTunedModel, | ||
stream: true, | ||
}); | ||
return request.body.pipe(this.eventStreamTransformer()); | ||
} | ||
async contentFilter(content, user) { | ||
const completion = await this.complete('content-filter-alpha-c4', { | ||
prompt: `<|endoftext|>${content}\n--\nLabel:`, | ||
temperature: 0, | ||
max_tokens: 1, | ||
top_p: 1, | ||
frequency_penalty: 0, | ||
presence_penalty: 0, | ||
logprobs: 10, | ||
user, | ||
}); | ||
let label = Number(completion.choices[0].text); | ||
if (label === 2) { | ||
const logprobs = completion.choices[0].logprobs?.top_logprobs[0]; | ||
if (logprobs && logprobs['2'] < -0.355) { | ||
if (logprobs['0'] && logprobs['1']) { | ||
label = logprobs['0'] >= logprobs['1'] ? 0 : 1; | ||
} | ||
else if (logprobs['0']) { | ||
label = 0; | ||
} | ||
else if (logprobs['1']) { | ||
label = 1; | ||
} | ||
} | ||
} | ||
if (![0, 1, 2].includes(label)) { | ||
label = 2; | ||
} | ||
return label; | ||
} | ||
search(engine, options) { | ||
return this.request(`/engines/${engine}/search`, 'POST', options).then((r) => r.data); | ||
} | ||
classify(options) { | ||
return this.request('/classifications', 'POST', options); | ||
} | ||
answer(options) { | ||
return this.request('/answers', 'POST', options); | ||
} | ||
getFiles() { | ||
return this.request('/files', 'GET').then((r) => r.data); | ||
} | ||
uploadFile(file, jsonlines, purpose) { | ||
const data = new form_data_1.default(); | ||
let fileJsonlines; | ||
if (Array.isArray(jsonlines)) { | ||
if (typeof jsonlines[0] === 'object') { | ||
jsonlines = jsonlines.map((j) => JSON.stringify(j)); | ||
} | ||
fileJsonlines = jsonlines.join('\n'); | ||
} | ||
else { | ||
fileJsonlines = jsonlines; | ||
} | ||
data.append('file', fileJsonlines, file); | ||
data.append('purpose', purpose); | ||
return this.request('/files', 'POST', data); | ||
} | ||
getFile(fileId) { | ||
return this.request(`/files/${fileId}`, 'GET'); | ||
} | ||
deleteFile(fileId) { | ||
return this.request(`/files/${fileId}`, 'DELETE'); | ||
} | ||
finetune(options) { | ||
return this.request(`/fine-tunes`, 'POST', options); | ||
} | ||
getFinetunes() { | ||
return this.request('/fine-tunes', 'GET').then((r) => r.data); | ||
} | ||
getFinetune(finetuneId) { | ||
return this.request(`/fine-tunes/${finetuneId}`, 'GET'); | ||
} | ||
cancelFinetune(finetuneId) { | ||
return this.request(`/fine-tunes/${finetuneId}/cancel`, 'POST'); | ||
} | ||
getFinetuneEvents(finetuneId) { | ||
return this.request(`/fine-tunes/${finetuneId}/events`, 'GET').then((r) => r.data); | ||
} | ||
async requestRaw(path, method, body) { | ||
let headers = { ...this.headers }; | ||
if (body instanceof form_data_1.default) { | ||
delete headers['content-type']; | ||
headers = body.getHeaders(headers); | ||
} | ||
else if (!['string', 'undefined'].includes(typeof body)) { | ||
body = JSON.stringify(body); | ||
} | ||
const response = await (0, node_fetch_1.default)(this.url + path, { | ||
headers, | ||
method, | ||
body: body, | ||
}); | ||
if (!response.ok) { | ||
let errorBody; | ||
try { | ||
const { error: { message }, } = await response.json(); | ||
errorBody = message; | ||
} | ||
catch { | ||
try { | ||
errorBody = await response.text(); | ||
} | ||
catch { | ||
errorBody = 'Failed to get body as text'; | ||
} | ||
} | ||
throw new Error(`OpenAI did not return ok: ${response.status} ~ Error body: ${errorBody}`); | ||
} | ||
return response; | ||
} | ||
async request(path, method, body) { | ||
const response = await this.requestRaw(path, method, body); | ||
return response.json(); | ||
} | ||
eventStreamTransformer() { | ||
const dataHeader = Buffer.from('data: '); | ||
return new stream_1.Transform({ | ||
transform: function (chunk, _, callback) { | ||
if (chunk.length >= dataHeader.length && | ||
dataHeader.compare(chunk, undefined, dataHeader.length) === 0) { | ||
if (this.prevChunk) { | ||
const completion = JSON.parse(this.prevChunk.toString()); | ||
this.push(completion.choices[0].text); | ||
this.prevChunk = undefined; | ||
} | ||
chunk = chunk.slice(dataHeader.length); | ||
} | ||
this.prevChunk = this.prevChunk ? Buffer.concat([this.prevChunk, chunk]) : chunk; | ||
callback(); | ||
}, | ||
}); | ||
} | ||
} | ||
exports.OpenAI = OpenAI; | ||
}); | ||
export * from './lib.js'; | ||
export * from './types.js'; |
@@ -16,2 +16,3 @@ export declare type EngineId = 'davinci' | 'curie' | 'babbage' | 'ada' | string; | ||
data: T[]; | ||
model?: string; | ||
} | ||
@@ -52,2 +53,7 @@ export interface CompletionRequest { | ||
} | ||
export declare enum ContentLabel { | ||
Safe = 0, | ||
Sensitive = 1, | ||
Unsafe = 2 | ||
} | ||
export interface SearchRequest { | ||
@@ -173,6 +179,9 @@ query: string; | ||
} | ||
export declare const enum ContentLabel { | ||
Safe = 0, | ||
Sensitive = 1, | ||
Unsafe = 2 | ||
export interface EmbeddingRequest { | ||
input: string | string[]; | ||
} | ||
export interface Embedding { | ||
object: 'embedding'; | ||
embedding: number[]; | ||
index: number; | ||
} |
@@ -1,12 +0,6 @@ | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
}); | ||
export var ContentLabel; | ||
(function (ContentLabel) { | ||
ContentLabel[ContentLabel["Safe"] = 0] = "Safe"; | ||
ContentLabel[ContentLabel["Sensitive"] = 1] = "Sensitive"; | ||
ContentLabel[ContentLabel["Unsafe"] = 2] = "Unsafe"; | ||
})(ContentLabel || (ContentLabel = {})); |
{ | ||
"name": "openai", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Tiny OpenAI API wrapper", | ||
"type": "module", | ||
"main": "dist/index.js", | ||
@@ -29,18 +30,16 @@ "scripts": { | ||
"devDependencies": { | ||
"@types/node": "16.10.5", | ||
"@types/node-fetch": "2.5.12", | ||
"@typescript-eslint/eslint-plugin": "5.0.0", | ||
"@typescript-eslint/parser": "5.0.0", | ||
"eslint": "8.0.0", | ||
"@types/node": "16.11.11", | ||
"@typescript-eslint/eslint-plugin": "5.5.0", | ||
"@typescript-eslint/parser": "5.5.0", | ||
"eslint": "8.3.0", | ||
"eslint-config-prettier": "8.3.0", | ||
"eslint-plugin-prettier": "4.0.0", | ||
"eslint-plugin-sort-imports-es6-autofix": "0.6.0", | ||
"prettier": "2.4.1", | ||
"typescript": "4.4.4" | ||
"prettier": "2.5.0", | ||
"typescript": "4.5.2" | ||
}, | ||
"dependencies": { | ||
"form-data": "4.0.0", | ||
"node-fetch": "2.6.5", | ||
"tslib": "2.3.1" | ||
"node-fetch": "3.1.0" | ||
} | ||
} |
@@ -0,1 +1,5 @@ | ||
[![Build Status](https://github.com/ceifa/openai/actions/workflows/publish.yml/badge.svg)](https://github.com/ceifa/openai/actions/workflows/publish.yml) | ||
[![npm](https://img.shields.io/npm/v/openai.svg)](https://npmjs.com/package/openai) | ||
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) | ||
# OpenAI | ||
@@ -72,4 +76,2 @@ | ||
```js | ||
// Very experimental! Don't use on production!!! | ||
// This API may change at any time | ||
const stream = await openai.completeAndStream('curie', { // or completeFromModelAndStream | ||
@@ -76,0 +78,0 @@ prompt: 'Q: Hello\nA:', |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2
9
9
205
Yes
19641
405
2
+ Addeddata-uri-to-buffer@4.0.1(transitive)
+ Addedfetch-blob@3.2.0(transitive)
+ Addedformdata-polyfill@4.0.10(transitive)
+ Addednode-domexception@1.0.0(transitive)
+ Addednode-fetch@3.1.0(transitive)
+ Addedweb-streams-polyfill@3.3.3(transitive)
- Removedtslib@2.3.1
- Removednode-fetch@2.6.5(transitive)
- Removedtr46@0.0.3(transitive)
- Removedtslib@2.3.1(transitive)
- Removedwebidl-conversions@3.0.1(transitive)
- Removedwhatwg-url@5.0.0(transitive)
Updatednode-fetch@3.1.0