From 5018654621990c5811e49e67bd4fc710ec56703e Mon Sep 17 00:00:00 2001 From: "Q.Ben Zheng" <40693636+Zhengqbbb@users.noreply.github.com> Date: Thu, 2 Mar 2023 16:06:05 +0800 Subject: [PATCH] feat(cz-git,cli): use `gpt-3.5-turbo` openai model (#96) - update requestion prompt - AI default maxSubjectLength update `65` - update http error handler and msg --- .commitlintrc.cjs | 1 - docs/.vitepress/components.d.ts | 1 + docs/.vitepress/theme/components/Badge.vue | 64 +++++++++++++++++++ docs/.vitepress/theme/index.ts | 2 + docs/recipes/openai.md | 4 +- docs/zh/config/show.md | 2 +- docs/zh/recipes/openai.md | 4 +- .../plugin-inquirer/src/shared/utils/style.ts | 7 +- packages/cz-git/src/generator/message.ts | 32 ++++++---- 9 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 docs/.vitepress/theme/components/Badge.vue diff --git a/.commitlintrc.cjs b/.commitlintrc.cjs index 391845a66..66470eed2 100644 --- a/.commitlintrc.cjs +++ b/.commitlintrc.cjs @@ -42,7 +42,6 @@ module.exports = { { value: 'link', name: 'link: Work in processing to ISSUES' }, { value: 'closed', name: 'closed: ISSUES has been processed' }, ], - aiNumber: 5, aiDiffIgnore: [ 'pnpm-lock.yaml', 'docs/public' ], customIssuePrefixAlign: !issue ? 'top' : 'bottom', defaultIssues: !issue ? '' : `#${issue}`, diff --git a/docs/.vitepress/components.d.ts b/docs/.vitepress/components.d.ts index 2e5a023bd..4f9ee791a 100644 --- a/docs/.vitepress/components.d.ts +++ b/docs/.vitepress/components.d.ts @@ -7,6 +7,7 @@ export {} declare module '@vue/runtime-core' { export interface GlobalComponents { + Badge: typeof import('./theme/components/Badge.vue')['default'] CodeGroupItem: typeof import('./theme/components/CodeGroupItem.vue')['default'] HomePage: typeof import('./theme/components/HomePage.vue')['default'] } diff --git a/docs/.vitepress/theme/components/Badge.vue b/docs/.vitepress/theme/components/Badge.vue new file mode 100644 index 000000000..bbb5d3f36 --- /dev/null +++ b/docs/.vitepress/theme/components/Badge.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 6db762f7c..60f140c31 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -6,6 +6,7 @@ import './style/main.css' import './style/vars.css' import 'uno.css' import { createMediumZoomProvider } from './components/composables' +import Badge from './components/Badge.vue' import HomePage from './components/HomePage.vue' import CodeGroupItem from './components/CodeGroupItem.vue' import { CodeGroup } from './components/CodeGroup' @@ -21,6 +22,7 @@ export default { }) }, enhanceApp({ app, router }: EnhanceAppContext) { + app.component('Badge', Badge) app.component('CodeGroup', CodeGroup) app.component('CodeGroupItem', CodeGroupItem) createMediumZoomProvider(app, router) diff --git a/docs/recipes/openai.md b/docs/recipes/openai.md index 63d4bdd82..4d600d0b9 100644 --- a/docs/recipes/openai.md +++ b/docs/recipes/openai.md @@ -1,4 +1,4 @@ -# OpenAI +# OpenAI Let the AI generate your **git commit message** subject (short description) @@ -107,5 +107,5 @@ npx czg ai -N=5 ## How it works -- Run git diff to obtain difference code information, combine prompt task, send them to **OpenAI GPT-3 API**, Return the subjects information generated by AI. +- Run git diff to obtain difference code information, combine prompt task, send them to **OpenAI GPT 3.5 Turbo API**, Return the subjects information generated by AI. - 💡 Inspired by [aicommits](https://github.com/Nutlope/aicommits) and modified part of the code diff --git a/docs/zh/config/show.md b/docs/zh/config/show.md index f9a4c107a..ea9d2aaa5 100644 --- a/docs/zh/config/show.md +++ b/docs/zh/config/show.md @@ -24,7 +24,7 @@ sitemap: ## themeColorCode -- **描述** : set prompt inquirer theme color +- **描述** : 设置终端交互部件的主题色 - **类型** : `string` - **默认** : `""` (⇒ cyan 青色) diff --git a/docs/zh/recipes/openai.md b/docs/zh/recipes/openai.md index 9136847da..fc061d70b 100644 --- a/docs/zh/recipes/openai.md +++ b/docs/zh/recipes/openai.md @@ -1,4 +1,4 @@ -# OpenAI +# OpenAI 让 AI 生成你的 git commit 提交信息简短描述 @@ -117,5 +117,5 @@ module.exports = { ## 如何实现 -- 运行 git diff 命令获取文件的差异,并结合描述信息,发送请求给 **OpenAI GPT-3 API**,来获取 AI 生成的简短描述 +- 运行 git diff 命令获取文件的差异,并结合描述信息,发送请求给 **OpenAI GPT 3.5 Turbo API**,来获取 AI 生成的简短描述 - 💡 灵感来源 [aicommits](https://github.com/Nutlope/aicommits) 并修改了部分代码 diff --git a/packages/@cz-git/plugin-inquirer/src/shared/utils/style.ts b/packages/@cz-git/plugin-inquirer/src/shared/utils/style.ts index fabee3b94..13ee18225 100644 --- a/packages/@cz-git/plugin-inquirer/src/shared/utils/style.ts +++ b/packages/@cz-git/plugin-inquirer/src/shared/utils/style.ts @@ -14,10 +14,13 @@ export const isColorizenSupport = (colorSupoort = true) => { return ( colorSupoort && !('NO_COLOR' in process.env) - && (process.platform === 'win32' + && ( + process.platform === 'win32' || (tty.isatty(1) && process.env.TERM !== 'dumb') - || 'CI' in process.env) + || 'CI' in process.env + ) ) + || (!process.env.VITEST && 'FORCE_COLOR' in process.env) } export const replaceClose = ( diff --git a/packages/cz-git/src/generator/message.ts b/packages/cz-git/src/generator/message.ts index e52489c96..9a490311f 100644 --- a/packages/cz-git/src/generator/message.ts +++ b/packages/cz-git/src/generator/message.ts @@ -178,7 +178,7 @@ export async function generateAISubjects( // TODO: Accounting for GPT-3's input req of 4k tokens (approx 8k chars) const diffIgnore = options.aiDiffIgnore?.map(i => `:(exclude)${i}`) || [] const diffOpts = process.env.CZ_ALL_CHANGE_MODE === '1' - ? ['.'] + ? ['HEAD'] : ['--cached', '.'] const diff = spawnSync('git', ['diff', ...diffOpts, ...diffIgnore], { encoding: 'utf8' }, @@ -209,8 +209,8 @@ export async function generateAISubjects( async function fetchOpenAIMessage(options: CommitizenGitOptions, prompt: string) { const payload = { - model: 'text-davinci-003', - prompt, + model: 'gpt-3.5-turbo', + messages: [{ role: 'user', content: prompt }], temperature: 0.7, top_p: 1, frequency_penalty: 0, @@ -223,7 +223,8 @@ async function fetchOpenAIMessage(options: CommitizenGitOptions, prompt: string) log('err', `NO Found OpenAI Token, Please use setup command ${style.cyan('`npx -y czg --openai-token="sk-XXXX"`')}`) throw new Error('See guide page: https://cz-git.qbb.sh/recipes/openai#setup-openai-token') } - const response = await fetch('https://api.openai.com/v1/completions', { + // https://platform.openai.com/docs/api-reference/chat/create + const response = await fetch('https://api.openai.com/v1/chat/completions', { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${options.openAIToken}`, @@ -231,24 +232,29 @@ async function fetchOpenAIMessage(options: CommitizenGitOptions, prompt: string) method: 'POST', body: JSON.stringify(payload), }) - if (response.status !== 200) { + if ( + !response.status + || response.status < 200 + || response.status > 299 + ) { const errorJson: any = await response.json() - log('err', 'Fetch OpenAI API message failed') + let errorMsg = `Fetch OpenAI API message failed, The response HTTP Code: ${response.status}` + if (response.status === 500) + errorMsg += '; Check the API status: https://status.openai.com' + log('err', errorMsg) throw new Error(errorJson?.error?.message) } const json: any = await response.json() - return json.choices.map((r: any) => parseAISubject(options, r.text)) + return json.choices.map((r: any) => parseAISubject(options, r?.message?.content)) } function generateSubjectDefaultPrompt( - { type, defaultScope, maxSubjectLength, upperCaseSubject, diff }: GenerateAIPromptType, + { maxSubjectLength, diff }: GenerateAIPromptType, ) { - const scopeText = defaultScope ? `The commit message scope is "${defaultScope}."` : '' - const startCaseText = upperCaseSubject ? 'start with a capital letter' : 'start with a lowercase letter' - if (maxSubjectLength === Infinity) - maxSubjectLength = 75 + if (!maxSubjectLength || maxSubjectLength === Infinity || maxSubjectLength > 90) + maxSubjectLength = 65 - return `I want you to write a git commit message and follow Conventional Commits, It is currently known that the type of The commit message is "${type}",${scopeText} And I will input you a git diff output, your job is to give me conventional commit subject that is short description mean do not preface the commit with type and scope. Without adding any preface the commit with anything! Using present tense, return a complete sentence, don't repeat yourself. Allow program abbreviations. The result must be control in ${maxSubjectLength} words! And ${startCaseText} ! Now enter part of the git diff code for you: \`\`\`diff\n${diff}\n\`\`\`` + return `Write an insightful and concise Git commit message in the present tense for the following Git diff code, without any prefixes, and no longer than ${maxSubjectLength} characters.: \n\`\`\`diff\n${diff}\n\`\`\`` } /** EndSection: */