feat: use new gpt-3.5-turbo model (#123)
Co-authored-by: Hiroki Osame <hiroki.osame@gmail.com>
This commit is contained in:
@@ -49,6 +49,10 @@ export default async (
|
|||||||
);
|
);
|
||||||
s.stop('Changes analyzed');
|
s.stop('Changes analyzed');
|
||||||
|
|
||||||
|
if (messages.length === 0) {
|
||||||
|
throw new KnownError('No commit messages were generated. Try again.');
|
||||||
|
}
|
||||||
|
|
||||||
let message: string;
|
let message: string;
|
||||||
if (messages.length === 1) {
|
if (messages.length === 1) {
|
||||||
[message] = messages;
|
[message] = messages;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import https from 'https';
|
import https from 'https';
|
||||||
import type { ClientRequest, IncomingMessage } from 'http';
|
import type { ClientRequest, IncomingMessage } from 'http';
|
||||||
import type { CreateCompletionRequest, CreateCompletionResponse } from 'openai';
|
import type { CreateChatCompletionRequest, CreateChatCompletionResponse } from 'openai';
|
||||||
import { encoding_for_model as encodingForModel } from '@dqbd/tiktoken';
|
import { encoding_for_model as encodingForModel } from '@dqbd/tiktoken';
|
||||||
import { KnownError } from './error.js';
|
import { KnownError } from './error.js';
|
||||||
|
|
||||||
@@ -50,13 +50,13 @@ const httpsPost = async (
|
|||||||
request.end();
|
request.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
const createCompletion = async (
|
const createChatCompletion = async (
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
json: CreateCompletionRequest,
|
json: CreateChatCompletionRequest,
|
||||||
) => {
|
) => {
|
||||||
const { response, data } = await httpsPost(
|
const { response, data } = await httpsPost(
|
||||||
'api.openai.com',
|
'api.openai.com',
|
||||||
'/v1/completions',
|
'/v1/chat/completions',
|
||||||
{
|
{
|
||||||
Authorization: `Bearer ${apiKey}`,
|
Authorization: `Bearer ${apiKey}`,
|
||||||
},
|
},
|
||||||
@@ -81,7 +81,7 @@ const createCompletion = async (
|
|||||||
throw new KnownError(errorMessage);
|
throw new KnownError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(data) as CreateCompletionResponse;
|
return JSON.parse(data) as CreateChatCompletionResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeMessage = (message: string) => message.trim().replace(/[\n\r]/g, '').replace(/(\w)\.$/, '$1');
|
const sanitizeMessage = (message: string) => message.trim().replace(/[\n\r]/g, '').replace(/(\w)\.$/, '$1');
|
||||||
@@ -90,8 +90,9 @@ const deduplicateMessages = (array: string[]) => Array.from(new Set(array));
|
|||||||
|
|
||||||
const getPrompt = (locale: string, diff: string) => `Write an insightful but concise Git commit message in a complete sentence in present tense for the following diff without prefacing it with anything, the response must be in the language ${locale}:\n${diff}`;
|
const getPrompt = (locale: string, diff: string) => `Write an insightful but concise Git commit message in a complete sentence in present tense for the following diff without prefacing it with anything, the response must be in the language ${locale}:\n${diff}`;
|
||||||
|
|
||||||
const model = 'text-davinci-003';
|
const model = 'gpt-3.5-turbo';
|
||||||
const encoder = encodingForModel(model);
|
// TODO: update for the new gpt-3.5 model
|
||||||
|
const encoder = encodingForModel('text-davinci-003');
|
||||||
|
|
||||||
export const generateCommitMessage = async (
|
export const generateCommitMessage = async (
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
@@ -110,9 +111,12 @@ export const generateCommitMessage = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const completion = await createCompletion(apiKey, {
|
const completion = await createChatCompletion(apiKey, {
|
||||||
model,
|
model,
|
||||||
prompt,
|
messages: [{
|
||||||
|
role: 'user',
|
||||||
|
content: prompt,
|
||||||
|
}],
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
top_p: 1,
|
top_p: 1,
|
||||||
frequency_penalty: 0,
|
frequency_penalty: 0,
|
||||||
@@ -124,7 +128,8 @@ export const generateCommitMessage = async (
|
|||||||
|
|
||||||
return deduplicateMessages(
|
return deduplicateMessages(
|
||||||
completion.choices
|
completion.choices
|
||||||
.map(choice => sanitizeMessage(choice.text!)),
|
.filter(choice => choice.message?.content)
|
||||||
|
.map(choice => sanitizeMessage(choice.message!.content)),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorAsAny = error as any;
|
const errorAsAny = error as any;
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ import { createFixture } from 'fs-fixture';
|
|||||||
import { createAicommits, createGit } from '../utils.js';
|
import { createAicommits, createGit } from '../utils.js';
|
||||||
|
|
||||||
const { OPENAI_KEY } = process.env;
|
const { OPENAI_KEY } = process.env;
|
||||||
if (!OPENAI_KEY) {
|
|
||||||
throw new Error('process.env.OPENAI_KEY is necessary to run these tests');
|
|
||||||
}
|
|
||||||
|
|
||||||
export default testSuite(({ describe }) => {
|
export default testSuite(({ describe }) => {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
@@ -14,6 +11,11 @@ export default testSuite(({ describe }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!OPENAI_KEY) {
|
||||||
|
console.warn('⚠️ process.env.OPENAI_KEY is necessary to run these tests. Skipping...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
describe('CLI', async ({ test }) => {
|
describe('CLI', async ({ test }) => {
|
||||||
const data: Record<string, string> = {
|
const data: Record<string, string> = {
|
||||||
firstName: 'Hiroki',
|
firstName: 'Hiroki',
|
||||||
@@ -94,10 +96,8 @@ export default testSuite(({ describe }) => {
|
|||||||
if (stdout.match('└')) {
|
if (stdout.match('└')) {
|
||||||
const countChoices = stdout.match(/ {2}[●○]/g)?.length ?? 0;
|
const countChoices = stdout.match(/ {2}[●○]/g)?.length ?? 0;
|
||||||
|
|
||||||
// 2 choices or less should be generated
|
// 2 choices should be generated
|
||||||
// pretty common for it to return 2 results that are the same
|
expect(countChoices).toBe(2);
|
||||||
// which gets de-duplicated
|
|
||||||
expect(countChoices <= 2).toBe(true);
|
|
||||||
|
|
||||||
committing.stdin!.write('\r');
|
committing.stdin!.write('\r');
|
||||||
committing.stdin!.end();
|
committing.stdin!.end();
|
||||||
|
|||||||
Reference in New Issue
Block a user