@git-ai/cli 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -305
- package/package.json +1 -1
- package/src/actions/CommitAction.mjs +3 -4
- package/src/actions/ModelAction.mjs +2 -43
- package/src/const.mjs +0 -6
- package/src/index.mjs +2 -10
- package/src/services/AIService.mjs +3 -5
- package/src/utils/OpenAI.mjs +2 -12
package/README.md
CHANGED
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
[](https://github.com/code-ba/git-ai/actions)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
基于 AI 的 Git 提交消息生成器,自动分析代码变更并生成规范的 commit message。
|
|
9
9
|
|
|
10
10
|
## ✨ 特性
|
|
11
11
|
|
|
12
|
-
- 🤖 **AI 自动生成提交消息**
|
|
13
|
-
- 🔄
|
|
14
|
-
- 🛡️ **冲突检测**
|
|
15
|
-
- 🔍 **AI 诊断**
|
|
16
|
-
- ⚙️ **灵活配置**
|
|
17
|
-
- 🎯 **符合规范**
|
|
18
|
-
- 🚀 **开箱即用** - 支持免费 API,无需配置即可使用
|
|
12
|
+
- 🤖 **AI 自动生成提交消息**
|
|
13
|
+
- 🔄 **完整 Git 工作流** (add/commit/fetch/merge/push)
|
|
14
|
+
- 🛡️ **冲突检测** (Git 冲突 + 代码冲突标记)
|
|
15
|
+
- 🔍 **AI 诊断** (commit 失败时自动分析)
|
|
16
|
+
- ⚙️ **灵活配置** (支持多 API/模型/密钥)
|
|
17
|
+
- 🎯 **符合规范** (feat/fix/docs 等格式)
|
|
19
18
|
|
|
20
19
|
## 📦 安装
|
|
21
20
|
|
|
@@ -25,347 +24,98 @@ npm install -g @git-ai/cli
|
|
|
25
24
|
|
|
26
25
|
## 🚀 快速开始
|
|
27
26
|
|
|
28
|
-
### 1.
|
|
29
|
-
|
|
30
|
-
无需配置,直接使用:
|
|
27
|
+
### 1. 配置 API
|
|
31
28
|
|
|
32
29
|
```bash
|
|
33
|
-
git ai
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
工具会自动:
|
|
37
|
-
|
|
38
|
-
- 检查 Git 环境
|
|
39
|
-
- 执行 `git add .`
|
|
40
|
-
- 分析代码变更
|
|
41
|
-
- 使用 AI 生成提交消息
|
|
42
|
-
- 执行 `git commit`
|
|
43
|
-
- 执行 `git fetch` 和 `git merge`(如有需要)
|
|
44
|
-
- 执行 `git push`
|
|
45
|
-
|
|
46
|
-
**运行示例:**
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
$ git ai
|
|
50
|
-
git-ai verb @git-ai/cli@1.0.0
|
|
51
|
-
git-ai verb 按 Ctrl+C 退出...
|
|
52
|
-
git-ai success AI 生成的内容:
|
|
53
|
-
docs(John): 更新文档和代码格式规范
|
|
54
|
-
|
|
55
|
-
- 添加了 select-model 命令的环境变量配置说明
|
|
56
|
-
- 统一了代码中的引号使用为双引号
|
|
57
|
-
- 修复了 package.json 中缺少的 access 字段
|
|
58
|
-
- 规范化了代码缩进和格式
|
|
59
|
-
git-ai info 本次模型消耗统计:总数 17050 tokens、输入 16977 tokens、输出 73 tokens
|
|
60
|
-
git-ai success git commit 提交成功...
|
|
61
|
-
git-ai info 获取 git 远程仓库地址
|
|
62
|
-
git-ai success 获取 git 远程仓库地址成功
|
|
63
|
-
git-ai info 获取远程仓库最新状态,执行 git fetch...
|
|
64
|
-
git-ai success 远程分支 origin 的最新更改状态获取成功
|
|
65
|
-
git-ai info 正在检测是否需要拉取...
|
|
66
|
-
git-ai success 本地代码是最新,无需合并
|
|
67
|
-
git-ai info 正在推送本地分支与远程分支的差异...
|
|
68
|
-
git-ai success 本地分支与远程分支的差异已推送。
|
|
69
|
-
git-ai verb 日志地址: C:\Users\用户名\.config\git-ai\cli\logs\2025-11\log-2025-11-22_10-56-59.txt
|
|
70
|
-
git-ai verb 本次执行指令耗时: 14.481 秒,程序退出...
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 2. 配置自定义 API(可选)
|
|
74
|
-
|
|
75
|
-
如果你有自己的 OpenAI compatible API,可以配置:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
# 设置 API Base URL
|
|
79
30
|
git ai set-baseURL https://api.siliconflow.cn/v1
|
|
80
|
-
|
|
81
|
-
# 设置 API Key
|
|
82
31
|
git ai set-key your-api-key
|
|
83
|
-
|
|
84
|
-
# 设置模型(支持多个,用逗号分隔)
|
|
85
|
-
git ai set-model gpt-4,claude-3
|
|
86
|
-
|
|
87
|
-
# 或者从模型列表中选择(需要配置 OPENAI_MODEL_LIST_URL 环境变量)
|
|
88
|
-
git ai select-model
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**注意:** 使用 `select-model` 命令前,需要先设置 `OPENAI_MODEL_LIST_URL` 环境变量指向模型列表配置文件(详见下方命令说明)。
|
|
92
|
-
|
|
93
|
-
### 3. 设置最大 Token 数
|
|
94
|
-
|
|
95
|
-
如果代码变更较大,可以调整最大 token 数:
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
git ai set-max-token 128000
|
|
32
|
+
git ai set-model Qwen/Qwen2.5-Coder-7B-Instruct
|
|
99
33
|
```
|
|
100
34
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
### 主命令
|
|
35
|
+
### 2. 生成提交
|
|
104
36
|
|
|
105
37
|
```bash
|
|
106
|
-
git ai
|
|
38
|
+
git ai
|
|
107
39
|
```
|
|
108
40
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
**选项:**
|
|
41
|
+
工具会自动执行:`git add` → AI 生成消息 → `git commit` → `git fetch` → `git merge` → `git push`
|
|
112
42
|
|
|
113
|
-
|
|
114
|
-
- `-e, --allow-empty` - 等同于 `git commit --allow-empty -m <message>`,允许空提交
|
|
115
|
-
- `-n, --no-verify` - 等同于 `git commit --no-verify -m <message>`,跳过 Git hooks
|
|
116
|
-
- `-s, --skip` - 跳过 `git add` 命令,只提交已暂存的更改
|
|
43
|
+
## 📖 常用命令
|
|
117
44
|
|
|
118
|
-
|
|
45
|
+
| 命令 | 说明 |
|
|
46
|
+
| ---------------------------- | ----------------- |
|
|
47
|
+
| `git ai` | 生成并提交 |
|
|
48
|
+
| `git ai -e, --allowEmpty` | 允许空提交 |
|
|
49
|
+
| `git ai -n, --noVerify` | 跳过 Git hooks |
|
|
50
|
+
| `git ai -s, --skip` | 跳过 git add |
|
|
51
|
+
| `git ai set-baseURL <url>` | 设置 API 地址 |
|
|
52
|
+
| `git ai set-key <key>` | 设置 API 密钥 |
|
|
53
|
+
| `git ai set-model <model>` | 设置模型 |
|
|
54
|
+
| `git ai set-max-token <num>` | 设置最大 token 数 |
|
|
119
55
|
|
|
120
|
-
|
|
56
|
+
## ⚙️ 配置说明
|
|
121
57
|
|
|
122
|
-
|
|
58
|
+
### 多 API/模型支持
|
|
123
59
|
|
|
124
60
|
```bash
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
支持多个 URL,用英文逗号分隔:
|
|
61
|
+
# 多个地址(随机选择)
|
|
62
|
+
git ai set-baseURL https://api1.com/v1,https://api2.com/v1
|
|
129
63
|
|
|
130
|
-
|
|
131
|
-
git ai set-baseURL https://api1.example.com/v1,https://api2.example.com/v1
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
#### `set-key [key]`
|
|
135
|
-
|
|
136
|
-
设置 OpenAI compatible API Key。
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
git ai set-key sk-xxxxxxxxxxxxx
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
支持多个 Key,用英文逗号分隔:
|
|
143
|
-
|
|
144
|
-
```bash
|
|
64
|
+
# 多个密钥(随机选择)
|
|
145
65
|
git ai set-key key1,key2,key3
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
#### `set-model [model]`
|
|
149
66
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
git ai set-model gpt-4
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
支持多个模型,用英文逗号分隔:
|
|
157
|
-
|
|
158
|
-
```bash
|
|
67
|
+
# 多个模型(随机选择)
|
|
159
68
|
git ai set-model gpt-4,claude-3,gemini-pro
|
|
160
69
|
```
|
|
161
70
|
|
|
162
|
-
如果不提供参数,会交互式选择模型:
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
git ai set-model
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
#### `select-model`
|
|
169
|
-
|
|
170
|
-
从模型列表中交互式选择模型。使用此命令前需要配置环境变量 `OPENAI_MODEL_LIST_URL`。
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
git ai select-model
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**环境变量配置:**
|
|
177
|
-
|
|
178
|
-
`OPENAI_MODEL_LIST_URL` 用于指定模型列表的来源,支持 HTTP(S) URL 或本地文件路径。
|
|
179
|
-
|
|
180
|
-
**设置环境变量:**
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
# Linux/macOS
|
|
184
|
-
export OPENAI_MODEL_LIST_URL="https://raw.githubusercontent.com/xx025/carrot/main/model_list.json"
|
|
185
|
-
|
|
186
|
-
# Windows (PowerShell)
|
|
187
|
-
$env:OPENAI_MODEL_LIST_URL="https://raw.githubusercontent.com/xx025/carrot/main/model_list.json"
|
|
188
|
-
|
|
189
|
-
# Windows (CMD)
|
|
190
|
-
set OPENAI_MODEL_LIST_URL=https://raw.githubusercontent.com/xx025/carrot/main/model_list.json
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**支持的格式:**
|
|
194
|
-
|
|
195
|
-
- **HTTP(S) URL**: `https://example.com/model_list.json`
|
|
196
|
-
- **本地文件路径(Linux/macOS)**: `/path/to/your/local/model_list.json`
|
|
197
|
-
- **本地文件路径(Windows)**: `C:\Path\To\Your\Local\model_list.json`
|
|
198
|
-
|
|
199
|
-
**JSON 配置格式:**
|
|
200
|
-
|
|
201
|
-
模型 id、baseURL、key 配置多个会随机取,必填(id、baseURL)、非必填(keys)
|
|
202
|
-
|
|
203
|
-
```json
|
|
204
|
-
{
|
|
205
|
-
"data": [
|
|
206
|
-
{
|
|
207
|
-
"id": "modelId1,modelId2,modelId3",
|
|
208
|
-
"baseURL": "baseURL1,baseURL2,baseURL3",
|
|
209
|
-
"keys": "key1,key2,key3"
|
|
210
|
-
}
|
|
211
|
-
]
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**示例:**
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
# 设置环境变量后执行
|
|
219
|
-
export OPENAI_MODEL_LIST_URL="https://raw.githubusercontent.com/xx025/carrot/main/model_list.json"
|
|
220
|
-
git ai select-model
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
#### `set-max-token <maxToken>`
|
|
224
|
-
|
|
225
|
-
设置最大 token 数,默认 128000(128k)。
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
git ai set-max-token 128000
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
当代码变更超过最大 token 数时,工具会使用 `git diff --stat` 来获取文件统计信息。
|
|
232
|
-
|
|
233
71
|
## 🔧 工作流程
|
|
234
72
|
|
|
235
|
-
执行 `git ai` 时,工具会按以下流程执行:
|
|
236
|
-
|
|
237
73
|
```
|
|
238
|
-
检查环境 →
|
|
239
|
-
↓
|
|
240
|
-
git add → 获取 diff → AI 生成 commit message
|
|
241
|
-
↓
|
|
242
|
-
git commit → git fetch → git merge → 检查冲突 → git push
|
|
74
|
+
检查环境 → git add → AI 生成消息 → git commit → git fetch → git merge → git push
|
|
243
75
|
```
|
|
244
76
|
|
|
245
77
|
## 📝 提交消息格式
|
|
246
78
|
|
|
247
|
-
工具生成的提交消息符合常见的 commit message 规范:
|
|
248
|
-
|
|
249
79
|
```
|
|
250
80
|
<type>(<username>): <description>
|
|
251
81
|
|
|
252
|
-
[
|
|
82
|
+
[详细说明]
|
|
253
83
|
```
|
|
254
84
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
- `feat` - 新功能
|
|
258
|
-
- `fix` - 修复 bug
|
|
259
|
-
- `docs` - 文档变更
|
|
260
|
-
- `style` - 代码格式变更(不影响代码运行)
|
|
261
|
-
- `refactor` - 重构代码
|
|
262
|
-
- `perf` - 性能优化
|
|
263
|
-
- `test` - 测试相关
|
|
264
|
-
- `build` - 构建系统或外部依赖变更
|
|
265
|
-
- `ci` - CI 配置文件和脚本变更
|
|
266
|
-
- `chore` - 其他变更(不修改 src 或 test 文件)
|
|
267
|
-
- `revert` - 回滚提交
|
|
268
|
-
|
|
269
|
-
**示例:**
|
|
270
|
-
|
|
271
|
-
```
|
|
272
|
-
feat(John): 添加用户登录功能
|
|
273
|
-
|
|
274
|
-
- 实现用户名密码登录
|
|
275
|
-
- 添加 JWT token 验证
|
|
276
|
-
- 完善错误处理机制
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
## 🛠️ 高级功能
|
|
280
|
-
|
|
281
|
-
### 冲突检测
|
|
282
|
-
|
|
283
|
-
工具会自动检测:
|
|
284
|
-
|
|
285
|
-
1. **Git 冲突** - 检测未解决的合并冲突(UU、AA、DD 状态)
|
|
286
|
-
2. **代码冲突标记** - 检测代码中的冲突标记(`<<<<<<<`、`=======`、`>>>>>>>`)
|
|
287
|
-
|
|
288
|
-
如果检测到冲突,工具会提示你手动解决。
|
|
289
|
-
|
|
290
|
-
### AI 诊断
|
|
291
|
-
|
|
292
|
-
当 `git commit` 失败时,工具会:
|
|
293
|
-
|
|
294
|
-
1. 自动收集错误信息、git status 和 hook 输出
|
|
295
|
-
2. 使用 AI 分析失败原因
|
|
296
|
-
3. 提供诊断结果和修复建议
|
|
297
|
-
|
|
298
|
-
### 子目录支持
|
|
299
|
-
|
|
300
|
-
如果在 Git 仓库的子目录中运行,工具会:
|
|
301
|
-
|
|
302
|
-
- 只处理当前目录下的文件
|
|
303
|
-
- 显示警告提示当前操作范围
|
|
304
|
-
|
|
305
|
-
## ⚙️ 配置存储
|
|
306
|
-
|
|
307
|
-
配置信息存储在本地,使用 `configstore` 管理。配置文件位置:
|
|
308
|
-
|
|
309
|
-
- **Linux/macOS**: `~/.config/configstore/git-ai/cli.json`
|
|
310
|
-
- **Windows**: `%APPDATA%\configstore\@git-ai\cli.json`
|
|
85
|
+
**类型**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
|
|
311
86
|
|
|
312
|
-
|
|
87
|
+
**示例**:
|
|
313
88
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
89
|
+
```sh
|
|
90
|
+
$ git ai
|
|
91
|
+
git-ai verb @git-ai/cli@1.0.0
|
|
92
|
+
git-ai verb 按 Ctrl+C 退出...
|
|
93
|
+
git-ai success AI 生成的内容:
|
|
94
|
+
docs(John): 更新文档和代码格式规范
|
|
317
95
|
|
|
318
|
-
|
|
319
|
-
|
|
96
|
+
- 添加了 select-model 命令的环境变量配置说明
|
|
97
|
+
- 统一了代码中的引号使用为双引号
|
|
98
|
+
- 修复了 package.json 中缺少的 access 字段
|
|
99
|
+
- 规范化了代码缩进和格式
|
|
100
|
+
git-ai info 本次模型消耗统计:总数 17050 tokens、输入 16977 tokens、输出 73 tokens
|
|
101
|
+
git-ai success git commit 提交成功...
|
|
102
|
+
git-ai info 获取 git 远程仓库地址
|
|
103
|
+
git-ai success 获取 git 远程仓库地址成功
|
|
104
|
+
git-ai info 获取远程仓库最新状态,执行 git fetch...
|
|
105
|
+
git-ai success 远程分支 origin 的最新更改状态获取成功
|
|
106
|
+
git-ai info 正在检测是否需要拉取...
|
|
107
|
+
git-ai success 本地代码是最新,无需合并
|
|
108
|
+
git-ai info 正在推送本地分支与远程分支的差异...
|
|
109
|
+
git-ai success 本地分支与远程分支的差异已推送。
|
|
110
|
+
git-ai verb 日志地址: C:\Users\用户名\.config\git-ai\cli\logs\2025-11\log-2025-11-22_10-56-59.txt
|
|
111
|
+
git-ai verb 本次执行指令耗时: 14.481 秒,程序退出...
|
|
320
112
|
```
|
|
321
113
|
|
|
322
|
-
### 问题:更新内容超过模型支持的最大 token 数
|
|
323
|
-
|
|
324
|
-
**解决方案:**
|
|
325
|
-
|
|
326
|
-
1. 减少要提交的文件数量
|
|
327
|
-
2. 增加最大 token 数:`git ai set-max-token <更大的值>`
|
|
328
|
-
|
|
329
|
-
### 问题:AI 生成的内容不符合规则
|
|
330
|
-
|
|
331
|
-
**解决方案:**
|
|
332
|
-
|
|
333
|
-
重新运行 `git ai`,AI 会重新生成提交消息。
|
|
334
|
-
|
|
335
|
-
### 问题:网络错误或 API 调用失败
|
|
336
|
-
|
|
337
|
-
**解决方案:**
|
|
338
|
-
|
|
339
|
-
1. 检查网络连接
|
|
340
|
-
2. 验证 API Base URL 和 Key 是否正确
|
|
341
|
-
3. 检查 API 服务是否可用
|
|
342
|
-
|
|
343
114
|
## 📋 系统要求
|
|
344
115
|
|
|
345
116
|
- Node.js >= 12.20.0
|
|
346
117
|
- Git >= 2.0.0
|
|
347
118
|
|
|
348
|
-
## 🤝 贡献
|
|
349
|
-
|
|
350
|
-
欢迎提交 Issue 和 Pull Request!
|
|
351
|
-
|
|
352
119
|
## 📄 许可证
|
|
353
120
|
|
|
354
121
|
MIT License
|
|
355
|
-
|
|
356
|
-
## 👤 作者
|
|
357
|
-
|
|
358
|
-
**Baran**
|
|
359
|
-
|
|
360
|
-
- GitHub: [@code-ba](https://github.com/code-ba)
|
|
361
|
-
- Email: info@cxvh.com
|
|
362
|
-
|
|
363
|
-
## 🔗 相关链接
|
|
364
|
-
|
|
365
|
-
- [GitHub Repository](https://github.com/code-ba/git-ai)
|
|
366
|
-
- [Issue Tracker](https://github.com/code-ba/git-ai/issues)
|
|
367
|
-
- [NPM Package](https://www.npmjs.com/package/@git-ai/cli)
|
|
368
|
-
|
|
369
|
-
---
|
|
370
|
-
|
|
371
|
-
**注意:** 首次使用建议先使用 `--dry-run` 选项测试,确保一切正常后再正式提交。
|
package/package.json
CHANGED
|
@@ -17,10 +17,9 @@ import { collectError, collectWarning } from '../utils/Log.mjs';
|
|
|
17
17
|
* 负责处理 git commit 的完整流程
|
|
18
18
|
*/
|
|
19
19
|
class CommitAction extends BaseAction {
|
|
20
|
-
constructor({
|
|
21
|
-
super({
|
|
20
|
+
constructor({ allowEmpty, noVerify, skip }) {
|
|
21
|
+
super({ allowEmpty, noVerify, skip });
|
|
22
22
|
|
|
23
|
-
this.dryRun = dryRun;
|
|
24
23
|
this.allowEmpty = allowEmpty;
|
|
25
24
|
this.noVerify = noVerify;
|
|
26
25
|
this.skip = skip;
|
|
@@ -377,7 +376,7 @@ class CommitAction extends BaseAction {
|
|
|
377
376
|
* Git merge
|
|
378
377
|
*/
|
|
379
378
|
gitMerge() {
|
|
380
|
-
Logger.info('
|
|
379
|
+
Logger.info('正在检测是否需要合并...');
|
|
381
380
|
try {
|
|
382
381
|
const aheadCount = this.gitService.getAheadCount(this.remoteName, this.currentBranch);
|
|
383
382
|
if (aheadCount > 0) {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getModelList } from '../utils/OpenAI.mjs';
|
|
2
2
|
import { config } from '../utils/Storage.mjs';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import { BIN } from '../const.mjs';
|
|
5
5
|
import Logger from '../utils/Logger.mjs';
|
|
6
6
|
import Spinner from '../utils/Spinner.mjs';
|
|
7
7
|
import BaseAction from './BaseAction.mjs';
|
|
8
|
-
import { formatMessage } from '../utils/MessageUtils.mjs';
|
|
9
8
|
class SetModelAction extends BaseAction {
|
|
10
9
|
constructor(modelId) {
|
|
11
10
|
super(modelId);
|
|
@@ -58,46 +57,6 @@ class SetModelAction extends BaseAction {
|
|
|
58
57
|
throw error && error.message ? error.message : error;
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
|
-
// 验证模型是否可用
|
|
62
|
-
async validateModel() {
|
|
63
|
-
const spinner = new Spinner('正在验证模型是否可用...');
|
|
64
|
-
spinner.start();
|
|
65
|
-
|
|
66
|
-
const startTimestamp = Date.now();
|
|
67
|
-
const configModel = config.get('model') ? config.get('model').split(',') : [];
|
|
68
|
-
if (!this.baseURL || !configModel.length) return;
|
|
69
|
-
const total = configModel.length;
|
|
70
|
-
const errTotal = [];
|
|
71
|
-
while (configModel.length) {
|
|
72
|
-
const model = configModel.shift();
|
|
73
|
-
try {
|
|
74
|
-
const result = await chat({
|
|
75
|
-
model: model,
|
|
76
|
-
messages: [
|
|
77
|
-
{
|
|
78
|
-
role: 'user',
|
|
79
|
-
content: '1+1=?',
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
});
|
|
83
|
-
formatMessage(result);
|
|
84
|
-
} catch {
|
|
85
|
-
errTotal.push(model);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
spinner.stop();
|
|
89
|
-
if (total - errTotal.length > 0) {
|
|
90
|
-
Logger.success(`模型验证通过 ${total - errTotal.length} 个`);
|
|
91
|
-
}
|
|
92
|
-
if (errTotal.length) {
|
|
93
|
-
Logger.error(`模型验证失败 ${errTotal.length} 个,分别是:\n${errTotal.join('\n - ')}`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const endTimestamp = Date.now();
|
|
97
|
-
const duration = endTimestamp - startTimestamp;
|
|
98
|
-
|
|
99
|
-
Logger.success(`本次检查模型用时: ${(duration / 1000).toFixed(3)} 秒`);
|
|
100
|
-
}
|
|
101
60
|
async execute() {
|
|
102
61
|
config.set('model', this.modelId);
|
|
103
62
|
if (!this.modelId && this.defaultModel) {
|
|
@@ -112,7 +71,7 @@ class SetModelAction extends BaseAction {
|
|
|
112
71
|
if (this.modelId) {
|
|
113
72
|
Logger.success(`已设置模型: \n - ${this.modelId.split(`,`).join('\n - ')}`);
|
|
114
73
|
}
|
|
115
|
-
await this.validateModel();
|
|
74
|
+
// await this.validateModel();
|
|
116
75
|
}
|
|
117
76
|
}
|
|
118
77
|
|
package/src/const.mjs
CHANGED
|
@@ -11,15 +11,9 @@ export const DESCRIPTION = pkg.description;
|
|
|
11
11
|
export const VERSION = pkg.version;
|
|
12
12
|
export const AUTHOR = pkg.author;
|
|
13
13
|
export const LOWEST_NODE_VERSION = pkg.engines.node;
|
|
14
|
-
export const OPENAI_BASE_URL = ''; //"https://api.siliconflow.cn/v1"
|
|
15
|
-
export const OPENAI_API_KEYS_URL = ''; //"https://cloud.siliconflow.cn/me/account/ak"
|
|
16
|
-
export const OPENAI_MODELS_URL = ''; //"https://cloud.siliconflow.cn/me/models"
|
|
17
|
-
export const OPENAI_MODEL_DEFAULT = ''; // "Qwen/Qwen2.5-Coder-7B-Instruct"
|
|
18
14
|
export const OPENAI_TIMEOUT = 60 * 1000 * 3;
|
|
19
15
|
export const OPENAI_MAX_TOKEN_DEFAULT = 128000;
|
|
20
16
|
export const OPENAI_MODEL_LIST_URL = process.env.OPENAI_MODEL_LIST_URL;
|
|
21
|
-
export const OPENAI_FREE_BASE_URL = 'https://open.bigmodel.cn/api/paas/v4';
|
|
22
|
-
export const OPENAI_FREE_MODEL_ID = 'glm-4-flash-250414,glm-4.5-flash';
|
|
23
17
|
export const OPENAI_COMMIT_MESSAGE_TYPES = [
|
|
24
18
|
'feat',
|
|
25
19
|
'fix',
|
package/src/index.mjs
CHANGED
|
@@ -5,7 +5,6 @@ import TokenAction from './actions/TokenAction.mjs';
|
|
|
5
5
|
import BaseUrlAction from './actions/BaseUrlAction.mjs';
|
|
6
6
|
import MaxTokenAction from './actions/MaxTokenAction.mjs';
|
|
7
7
|
import { exitProcess } from './utils/Utils.mjs';
|
|
8
|
-
import SelectModelAction from './actions/SelectModelAction.mjs';
|
|
9
8
|
import { BIN, VERSION, DESCRIPTION, NAME, OPENAI_MAX_TOKEN_DEFAULT, asciiArt } from './const.mjs';
|
|
10
9
|
import Logger from './utils/Logger.mjs';
|
|
11
10
|
import chalk from 'chalk';
|
|
@@ -15,8 +14,6 @@ function registerCommand() {
|
|
|
15
14
|
const program = new Command();
|
|
16
15
|
program
|
|
17
16
|
.name(BIN)
|
|
18
|
-
// .description(`${asciiArt}`)
|
|
19
|
-
// .description(`${asciiArt}\n${DESCRIPTION}`)
|
|
20
17
|
.version(VERSION)
|
|
21
18
|
.helpOption(
|
|
22
19
|
'-h',
|
|
@@ -49,13 +46,8 @@ function registerCommand() {
|
|
|
49
46
|
)
|
|
50
47
|
.action(MaxTokenAction);
|
|
51
48
|
program
|
|
52
|
-
.
|
|
53
|
-
.
|
|
54
|
-
.action(SelectModelAction);
|
|
55
|
-
program
|
|
56
|
-
.option('-d, --dry-run', `等同于 ${chalk.cyan('`git commit --dry-run -m <message>`')}`)
|
|
57
|
-
.option('-e, --allow-empty', `等同于 ${chalk.cyan('`git commit --allow-empty -m <message>`')}`)
|
|
58
|
-
.option('-n, --no-verify', `等同于 ${chalk.cyan('`git commit --no-verify -m <message>`')}`)
|
|
49
|
+
.option('-e, --allowEmpty', `等同于 ${chalk.cyan('`git commit --allow-empty -m <message>`')}`)
|
|
50
|
+
.option('-n, --noVerify', `等同于 ${chalk.cyan('`git commit --no-verify -m <message>`')}`)
|
|
59
51
|
.option(
|
|
60
52
|
'-s, --skip',
|
|
61
53
|
`跳过 ${chalk.cyan('`git add`')} 命令, 只提交已暂存的更改,如:${chalk.cyan(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chat
|
|
1
|
+
import { chat } from '../utils/OpenAI.mjs';
|
|
2
2
|
import { generateSystemMessage, formatCompletions } from '../utils/MessageUtils.mjs';
|
|
3
3
|
import { config } from '../utils/Storage.mjs';
|
|
4
4
|
import chalk from 'chalk';
|
|
@@ -22,8 +22,7 @@ export class AIService {
|
|
|
22
22
|
* 生成提交消息
|
|
23
23
|
*/
|
|
24
24
|
async generateCommitMessage(diffString) {
|
|
25
|
-
const
|
|
26
|
-
const result = await request({
|
|
25
|
+
const result = await chat({
|
|
27
26
|
messages: [
|
|
28
27
|
{
|
|
29
28
|
role: 'system',
|
|
@@ -54,7 +53,6 @@ export class AIService {
|
|
|
54
53
|
*/
|
|
55
54
|
async analyzeCommitFailure({ errorMessage = '', gitStatus = '', hookLogs = '' } = {}) {
|
|
56
55
|
this.usageMessage = '';
|
|
57
|
-
const request = this.checkConfig() ? chat : freeChat;
|
|
58
56
|
const contextParts = [];
|
|
59
57
|
if (errorMessage) {
|
|
60
58
|
contextParts.push(`Git 命令报错:\n${errorMessage}`);
|
|
@@ -69,7 +67,7 @@ export class AIService {
|
|
|
69
67
|
? contextParts.join('\n\n')
|
|
70
68
|
: '未提供额外日志,只知道 git commit 失败。';
|
|
71
69
|
|
|
72
|
-
const result = await
|
|
70
|
+
const result = await chat({
|
|
73
71
|
messages: [
|
|
74
72
|
{
|
|
75
73
|
role: 'system',
|
package/src/utils/OpenAI.mjs
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { config } from './Storage.mjs';
|
|
3
|
-
import { OPENAI_TIMEOUT
|
|
4
|
-
import {
|
|
3
|
+
import { OPENAI_TIMEOUT } from '../const.mjs';
|
|
4
|
+
import { getOpenAiConfig } from './Utils.mjs';
|
|
5
5
|
|
|
6
6
|
export const headers = {
|
|
7
7
|
Accept: 'application/json',
|
|
8
8
|
'Content-Type': 'application/json',
|
|
9
9
|
};
|
|
10
|
-
export const getFreeModelInfo = async () => {
|
|
11
|
-
return axios.get(
|
|
12
|
-
`https://api2.immersivetranslate.com/big-model/get-token?deviceId=${getDeviceId()}`
|
|
13
|
-
);
|
|
14
|
-
};
|
|
15
10
|
export const getModelList = (options) => {
|
|
16
11
|
const conf = {};
|
|
17
12
|
const baseURL = config.get('baseURL').split(',')[0];
|
|
@@ -57,8 +52,3 @@ export const chat = (data, baseURL, apiKey) => {
|
|
|
57
52
|
},
|
|
58
53
|
});
|
|
59
54
|
};
|
|
60
|
-
export const freeChat = async (data) => {
|
|
61
|
-
const config = await getFreeModelInfo();
|
|
62
|
-
data.model = getRandomItem(OPENAI_FREE_MODEL_ID);
|
|
63
|
-
return chat(data, OPENAI_FREE_BASE_URL, config.data.apiToken);
|
|
64
|
-
};
|