refactor: use custom OpenAI "fetch" (#106)

This commit is contained in:
hiroki osame
2023-03-01 19:56:56 -05:00
committed by GitHub
parent f68ba4a3ec
commit f8fb0e246a
2 changed files with 53 additions and 5 deletions

View File

@@ -60,6 +60,8 @@
]
},
"release": {
"branches": ["main"]
"branches": [
"main"
]
}
}

View File

@@ -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<CreateCompletionResponse>((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) {