Skip to content

Commit

Permalink
feat(cz-git,cli): use gpt-3.5-turbo openai model (#96)
Browse files Browse the repository at this point in the history
- update requestion prompt
- AI default maxSubjectLength update `65`
- update http error handler and msg
  • Loading branch information
Zhengqbbb authored Mar 2, 2023
1 parent 354481f commit 5018654
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 21 deletions.
1 change: 0 additions & 1 deletion .commitlintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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}`,
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
}
Expand Down
64 changes: 64 additions & 0 deletions docs/.vitepress/theme/components/Badge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script setup lang="ts">
defineProps<{
text?: string
type?: 'info' | 'tip' | 'warning' | 'danger'
}>()
</script>

<template>
<span class="Badge" :class="type ?? 'tip'">
<slot>{{ text }}</slot>
</span>
</template>

<style scoped>
.Badge {
display: inline-block;
margin-left: 2px;
border: 1px solid transparent;
border-radius: 10px;
padding: 0 8px;
line-height: 18px;
font-size: 12px;
font-weight: 600;
transform: translateY(-2px);
}
h1 .Badge,
h2 .Badge,
h3 .Badge,
h4 .Badge,
h5 .Badge,
h6 .Badge {
vertical-align: top;
}
h2 .Badge {
border-radius: 11px;
line-height: 20px;
}
.Badge.info {
border-color: var(--vp-custom-block-info-border);
color: var(--vp-custom-block-info-text);
background-color: var(--vp-custom-block-info-bg);
}
.Badge.tip {
border-color: var(--vp-custom-block-tip-border);
color: var(--vp-custom-block-tip-text);
background-color: var(--vp-custom-block-tip-bg);
}
.Badge.warning {
border-color: var(--vp-custom-block-warning-border);
color: var(--vp-custom-block-warning-text);
background-color: var(--vp-custom-block-warning-bg);
}
.Badge.danger {
border-color: var(--vp-custom-block-danger-border);
color: var(--vp-custom-block-danger-text);
background-color: var(--vp-custom-block-danger-bg);
}
</style>
2 changes: 2 additions & 0 deletions docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions docs/recipes/openai.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# OpenAI
# OpenAI <Badge type="info" text="GPT 3.5 Turbo Model" />

Let the AI generate your **git commit message** subject <sup>(short description)</sup>

Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion docs/zh/config/show.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sitemap:

## themeColorCode

- **描述** : set prompt inquirer theme color
- **描述** : 设置终端交互部件的主题色
- **类型** : `string`
- **默认** : `""` (⇒ cyan 青色)

Expand Down
4 changes: 2 additions & 2 deletions docs/zh/recipes/openai.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# OpenAI
# OpenAI <Badge type="info" text="GPT 3.5 Turbo 模型" />

让 AI 生成你的 git commit 提交信息简短描述

Expand Down Expand Up @@ -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) 并修改了部分代码
7 changes: 5 additions & 2 deletions packages/@cz-git/plugin-inquirer/src/shared/utils/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand Down
32 changes: 19 additions & 13 deletions packages/cz-git/src/generator/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' },
Expand Down Expand Up @@ -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,
Expand All @@ -223,32 +223,38 @@ 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}`,
},
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: */

0 comments on commit 5018654

Please sign in to comment.