diff --git a/package.json b/package.json index 8eb9366..84ea90b 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,8 @@ ] }, "release": { - "branches": ["main"] + "branches": [ + "main" + ] } } diff --git a/src/utils/openai.ts b/src/utils/openai.ts index cf31c1e..c3d6e68 100644 --- a/src/utils/openai.ts +++ b/src/utils/openai.ts @@ -1,4 +1,51 @@ -import { Configuration, OpenAIApi } from 'openai'; +import https from 'https'; +import type { CreateCompletionRequest, CreateCompletionResponse } from 'openai'; + +const createCompletion = ( + apiKey: string, + json: CreateCompletionRequest, +) => new Promise((resolve, reject) => { + const postContent = JSON.stringify(json); + const request = https.request( + { + port: 443, + hostname: 'api.openai.com', + path: '/v1/completions', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': postContent.length, + Authorization: `Bearer ${apiKey}`, + }, + timeout: 10_000, // 10s + }, + (response) => { + if ( + !response.statusCode + || response.statusCode < 200 + || response.statusCode > 299 + ) { + return reject(new Error(`HTTP status code ${response.statusCode}`)); + } + + const body: Buffer[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + resolve( + JSON.parse(Buffer.concat(body).toString()), + ); + }); + }, + ); + request.on('error', reject); + request.on('timeout', () => { + request.destroy(); + reject(new Error('Request timed out')); + }); + + request.write(postContent); + request.end(); +}); const sanitizeMessage = (message: string) => message.trim().replace(/[\n\r]/g, '').replace(/(\w)\.$/, '$1'); @@ -18,9 +65,8 @@ export const generateCommitMessage = async ( throw new Error('The diff is too large for the OpenAI API. Try reducing the number of staged changes, or write your own commit message.'); } - const openai = new OpenAIApi(new Configuration({ apiKey })); try { - const completion = await openai.createCompletion({ + const completion = await createCompletion(apiKey, { model: 'text-davinci-003', prompt, temperature: 0.7, @@ -33,7 +79,7 @@ export const generateCommitMessage = async ( }); return deduplicateMessages( - completion.data.choices + completion.choices .map(choice => sanitizeMessage(choice.text!)), ); } catch (error) {