Skip to content

Commit ac08f99

Browse files
authored
feat: 增加最大令牌数配置项 (#2)
为配置结构增加了 `max_tokens` 字段,允许用户自定义生成 commit message 时的最大令牌数。 Signed-off-by: jinlong <fslongjin@vip.qq.com>
1 parent c5f13f2 commit ac08f99

3 files changed

Lines changed: 86 additions & 11 deletions

File tree

src/config.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use serde::{Deserialize, Serialize};
22
use std::{fmt::Display, fs};
33

4-
use crate::constants::{DEFAULT_OPENAI_API_BASE, DEFAULT_OPENAI_MODEL};
4+
use crate::constants::{DEFAULT_MAX_TOKENS, DEFAULT_OPENAI_API_BASE, DEFAULT_OPENAI_MODEL};
55

66
#[derive(Debug, Serialize, Deserialize)]
77
pub struct Config {
88
pub api_base: Option<String>,
99
pub api_key: String,
1010
pub model: Option<String>,
11+
/// The maximum number of tokens to generate in the commit message.
12+
pub max_tokens: Option<u32>,
1113
/// Whether to use conventional commit message format.
1214
pub conventional: bool,
1315
pub language: CommitLanguage,
@@ -78,6 +80,7 @@ impl Default for Config {
7880
api_base: Some(DEFAULT_OPENAI_API_BASE.into()),
7981
api_key: "".to_owned(),
8082
model: Some(DEFAULT_OPENAI_MODEL.into()),
83+
max_tokens: Some(DEFAULT_MAX_TOKENS),
8184
conventional: true,
8285
language: CommitLanguage::default(),
8386
verbosity: Verbosity::default(),

src/constants.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,56 @@ pub const DEFAULT_PROMPT_TEMPLATE: &str = r#"
77
88
作为代码版本控制专家,请分析以下变更并生成commit message。
99
10-
要求:
10+
# 要求:
11+
- **使用约定式提交规范?: {{conventional_commit}}**
12+
- **只输出最终message**
1113
- 使用{{language}}编写
1214
- 详细程度:{{verbosity_level}}
13-
- 只输出最终message
14-
- 使用约定式提交规范? {{conventional_commit}}
15+
16+
# 什么是约定式提交规范?
17+
18+
约定式提交 1.0.0
19+
概述
20+
约定式提交规范是一种基于提交信息的轻量级约定。 它提供了一组简单规则来创建清晰的提交历史; 这更有利于编写自动化工具。 通过在提交信息中描述功能、修复和破坏性变更, 使这种惯例与 SemVer 相互对应。
21+
22+
提交说明的结构如下所示:
23+
24+
原文:
25+
26+
<type>[optional scope]: <description>
27+
28+
[optional body]
29+
30+
[optional footer(s)]
31+
译文:
32+
33+
<类型>[可选 范围]: <描述>
34+
35+
[可选 正文]
36+
37+
[可选 脚注]
38+
提交说明包含了下面的结构化元素,以向类库使用者表明其意图:
39+
40+
fix: 类型 为 fix 的提交表示在代码库中修复了一个 bug(这和语义化版本中的 PATCH 相对应)。
41+
feat: 类型 为 feat 的提交表示在代码库中新增了一个功能(这和语义化版本中的 MINOR 相对应)。
42+
BREAKING CHANGE: 在脚注中包含 BREAKING CHANGE: 或 <类型>(范围) 后面有一个 ! 的提交,表示引入了破坏性 API 变更(这和语义化版本中的 MAJOR 相对应)。 破坏性变更可以是任意 类型 提交的一部分。
43+
除 fix: 和 feat: 之外,也可以使用其它提交 类型 ,例如 @commitlint/config-conventional(基于 Angular 约定)中推荐的 build:、chore:、 ci:、docs:、style:、refactor:、perf:、test:,等等。
44+
build: 用于修改项目构建系统,例如修改依赖库、外部接口或者升级 Node 版本等;
45+
chore: 用于对非业务性代码进行修改,例如修改构建流程或者工具配置等;
46+
ci: 用于修改持续集成流程,例如修改 Travis、Jenkins 等工作流配置;
47+
docs: 用于修改文档,例如修改 README 文件、API 文档等;
48+
style: 用于修改代码的样式,例如调整缩进、空格、空行等;
49+
refactor: 用于重构代码,例如修改代码结构、变量名、函数名等但不修改功能逻辑;
50+
perf: 用于优化性能,例如提升代码的性能、减少内存占用等;
51+
test: 用于修改测试用例,例如添加、删除、修改代码的测试用例等。
52+
脚注中除了 BREAKING CHANGE: <description> ,其它条目应该采用类似 git trailer format 这样的惯例。
53+
其它提交类型在约定式提交规范中并没有强制限制,并且在语义化版本中没有隐式影响(除非它们包含 BREAKING CHANGE)。 可以为提交类型添加一个围在圆括号内的范围,以为其提供额外的上下文信息。例如 feat(parser): adds ability to parse arrays.。
1554
1655
# 输出格式案例
1756
1857
message内容要使用<aicommit>标签包裹,例如:
1958
<aicommit>
59+
(这里是commit标题)
2060
2161
(这里是commit message内容)
2262
@@ -27,7 +67,6 @@ message内容要使用<aicommit>标签包裹,例如:
2767
{{diff}}
2868
"#;
2969

30-
3170
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
3271
pub enum PromptTemplateReplaceLabel {
3372
Language,
@@ -49,4 +88,6 @@ impl PromptTemplateReplaceLabel {
4988

5089
lazy_static! {
5190
pub static ref STOP_WORDS: Vec<String> = vec![String::from("</aicommit>")];
52-
}
91+
}
92+
93+
pub const DEFAULT_MAX_TOKENS: u32 = 2048;

src/generate.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
21
use openai_api_rust::chat::*;
32
use openai_api_rust::*;
43
use std::process::Command;
54

65
use crate::cli;
76
use crate::config::{self, Config};
8-
use crate::constants::{DEFAULT_OPENAI_MODEL, DEFAULT_PROMPT_TEMPLATE, STOP_WORDS};
7+
use crate::constants::{
8+
DEFAULT_MAX_TOKENS, DEFAULT_OPENAI_MODEL, DEFAULT_PROMPT_TEMPLATE, STOP_WORDS,
9+
};
910
use crate::template_engine::{render_template, TemplateContext};
1011

1112
async fn generate_commit_message(diff: &str, config: &config::Config) -> anyhow::Result<String> {
@@ -48,7 +49,7 @@ async fn generate_commit_message(diff: &str, config: &config::Config) -> anyhow:
4849
n: None,
4950
stream: Some(false),
5051
stop: Some(STOP_WORDS.to_owned()),
51-
max_tokens: Some(2048),
52+
max_tokens: Some(DEFAULT_MAX_TOKENS as i32),
5253
presence_penalty: None,
5354
frequency_penalty: None,
5455
logit_bias: None,
@@ -67,16 +68,46 @@ async fn generate_commit_message(diff: &str, config: &config::Config) -> anyhow:
6768
Ok(commit_message)
6869
}
6970

71+
fn delete_thinking_contents(orig: &str) -> String {
72+
let start_tag = "<think>";
73+
let end_tag = "</think>";
74+
75+
let start_idx = orig.find(start_tag).unwrap_or(orig.len());
76+
let end_idx = orig.find(end_tag).unwrap_or_else(|| 0);
77+
let s = if start_idx < end_idx {
78+
let mut result = orig[..start_idx].to_string();
79+
result.push_str(&orig[end_idx..]);
80+
log::debug!(
81+
"Delete thinking contents, start_idx: {}, end_idx: {}: {:?} => {:?}",
82+
start_idx,
83+
end_idx,
84+
orig,
85+
result
86+
);
87+
result
88+
} else {
89+
orig.to_string()
90+
};
91+
s
92+
}
93+
7094
fn extract_commit_message(response: &str) -> anyhow::Result<String> {
7195
let start_tag = "<aicommit>";
7296
let end_tag = "</aicommit>";
7397

98+
let response = delete_thinking_contents(response);
99+
74100
let start_idx = response
75101
.find(start_tag)
76102
.ok_or(anyhow::anyhow!("Start tag <aicommit> not found"))?
77103
+ start_tag.len();
78-
let end_idx = response
79-
.find(end_tag).unwrap_or_else(|| response.len());
104+
let end_idx = response.find(end_tag).unwrap_or_else(|| response.len());
105+
106+
if start_idx >= end_idx {
107+
return Err(anyhow::anyhow!(
108+
"End tag </aicommit> not found or misplaced"
109+
));
110+
}
80111

81112
let commit_message = response[start_idx..end_idx].trim().to_string();
82113
Ok(commit_message)

0 commit comments

Comments
 (0)