@commitsage/mcp-server 1.0.0 → 1.1.0
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 +87 -101
- package/dist/models/errors.d.ts +0 -12
- package/dist/models/errors.d.ts.map +1 -1
- package/dist/models/errors.js +0 -24
- package/dist/models/errors.js.map +1 -1
- package/dist/models/types.d.ts +0 -19
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js.map +1 -1
- package/dist/server/mcpServer.d.ts.map +1 -1
- package/dist/server/mcpServer.js +3 -79
- package/dist/server/mcpServer.js.map +1 -1
- package/dist/server/tools.d.ts +1 -49
- package/dist/server/tools.d.ts.map +1 -1
- package/dist/server/tools.js +22 -178
- package/dist/server/tools.js.map +1 -1
- package/dist/services/baseAIService.d.ts +15 -26
- package/dist/services/baseAIService.d.ts.map +1 -1
- package/dist/services/baseAIService.js +53 -62
- package/dist/services/baseAIService.js.map +1 -1
- package/dist/services/codestralService.d.ts.map +1 -1
- package/dist/services/codestralService.js +11 -35
- package/dist/services/codestralService.js.map +1 -1
- package/dist/services/geminiService.d.ts +2 -6
- package/dist/services/geminiService.d.ts.map +1 -1
- package/dist/services/geminiService.js +61 -84
- package/dist/services/geminiService.js.map +1 -1
- package/dist/services/ollamaService.d.ts +1 -2
- package/dist/services/ollamaService.d.ts.map +1 -1
- package/dist/services/ollamaService.js +16 -35
- package/dist/services/ollamaService.js.map +1 -1
- package/dist/services/openaiService.d.ts +0 -1
- package/dist/services/openaiService.d.ts.map +1 -1
- package/dist/services/openaiService.js +12 -33
- package/dist/services/openaiService.js.map +1 -1
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +3 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/httpUtils.d.ts +1 -2
- package/dist/utils/httpUtils.d.ts.map +1 -1
- package/dist/utils/httpUtils.js +7 -8
- package/dist/utils/httpUtils.js.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
- package/dist/adapters/sse.d.ts +0 -26
- package/dist/adapters/sse.d.ts.map +0 -1
- package/dist/adapters/sse.js +0 -45
- package/dist/adapters/sse.js.map +0 -1
- package/dist/auth/jwt.d.ts +0 -70
- package/dist/auth/jwt.d.ts.map +0 -1
- package/dist/auth/jwt.js +0 -171
- package/dist/auth/jwt.js.map +0 -1
- package/dist/auth/oauth.d.ts +0 -71
- package/dist/auth/oauth.d.ts.map +0 -1
- package/dist/auth/oauth.js +0 -213
- package/dist/auth/oauth.js.map +0 -1
package/dist/server/tools.js
CHANGED
|
@@ -1,147 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tools definitions for CommitSage
|
|
3
3
|
*/
|
|
4
|
-
import { z } from
|
|
5
|
-
import { AIService } from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { ConfigService } from '../utils/config.js';
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { AIService } from "../services/aiService.js";
|
|
6
|
+
import { Logger } from "../utils/logger.js";
|
|
7
|
+
import { ConfigService } from "../utils/config.js";
|
|
9
8
|
// Tool schemas
|
|
10
9
|
export const GenerateCommitMessageSchema = z.object({
|
|
11
|
-
repoPath: z
|
|
12
|
-
provider: z
|
|
13
|
-
.enum(['gemini', 'openai', 'codestral', 'ollama'])
|
|
14
|
-
.optional()
|
|
15
|
-
.describe('AI provider to use (defaults to configured provider)'),
|
|
16
|
-
format: z
|
|
17
|
-
.enum([
|
|
18
|
-
'conventional',
|
|
19
|
-
'angular',
|
|
20
|
-
'karma',
|
|
21
|
-
'semantic',
|
|
22
|
-
'emoji',
|
|
23
|
-
'emojiKarma',
|
|
24
|
-
'google',
|
|
25
|
-
'atom',
|
|
26
|
-
])
|
|
27
|
-
.optional()
|
|
28
|
-
.describe('Commit message format'),
|
|
29
|
-
language: z
|
|
30
|
-
.enum(['english', 'russian', 'chinese', 'japanese', 'spanish'])
|
|
31
|
-
.optional()
|
|
32
|
-
.describe('Language for commit message'),
|
|
33
|
-
onlyStaged: z
|
|
34
|
-
.boolean()
|
|
35
|
-
.optional()
|
|
36
|
-
.describe('Only analyze staged changes (default: false)'),
|
|
37
|
-
customInstructions: z
|
|
10
|
+
repoPath: z
|
|
38
11
|
.string()
|
|
39
|
-
.
|
|
40
|
-
.describe('Custom instructions for commit message generation'),
|
|
41
|
-
});
|
|
42
|
-
export const AnalyzeChangesSchema = z.object({
|
|
43
|
-
repoPath: z.string().describe('Path to the git repository'),
|
|
44
|
-
onlyStaged: z
|
|
45
|
-
.boolean()
|
|
46
|
-
.optional()
|
|
47
|
-
.describe('Only analyze staged changes (default: false)'),
|
|
12
|
+
.describe("Absolute path to the git repository (e.g. /home/user/project or C:\\Users\\user\\project)"),
|
|
48
13
|
});
|
|
49
|
-
export const ListCommitFormatsSchema = z.object({});
|
|
50
14
|
export const ValidateApiKeySchema = z.object({
|
|
51
15
|
provider: z
|
|
52
|
-
.enum([
|
|
53
|
-
.describe(
|
|
54
|
-
apiKey: z.string().optional().describe('API key to validate (optional, uses env if not provided)'),
|
|
16
|
+
.enum(["gemini", "openai", "codestral", "ollama"])
|
|
17
|
+
.describe("Provider to validate"),
|
|
55
18
|
});
|
|
56
19
|
// Tool handlers
|
|
57
20
|
export async function handleGenerateCommitMessage(args) {
|
|
58
21
|
try {
|
|
59
22
|
Logger.log(`Generating commit message for: ${args.repoPath}`);
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
if (args.format) {
|
|
63
|
-
process.env.DEFAULT_COMMIT_FORMAT = args.format;
|
|
64
|
-
}
|
|
65
|
-
if (args.language) {
|
|
66
|
-
process.env.DEFAULT_COMMIT_LANGUAGE = args.language;
|
|
67
|
-
}
|
|
68
|
-
if (args.customInstructions) {
|
|
69
|
-
process.env.USE_CUSTOM_INSTRUCTIONS = 'true';
|
|
70
|
-
process.env.CUSTOM_INSTRUCTIONS = args.customInstructions;
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
const result = await AIService.generateCommitMessageForRepo(args.repoPath, args.onlyStaged || false, args.provider);
|
|
74
|
-
return {
|
|
75
|
-
content: [
|
|
76
|
-
{
|
|
77
|
-
type: 'text',
|
|
78
|
-
text: JSON.stringify({
|
|
79
|
-
success: true,
|
|
80
|
-
message: result.message,
|
|
81
|
-
model: result.model,
|
|
82
|
-
provider: args.provider || ConfigService.getProvider(),
|
|
83
|
-
}, null, 2),
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
finally {
|
|
89
|
-
// Restore original env
|
|
90
|
-
process.env = originalEnv;
|
|
91
|
-
ConfigService.initialize();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
Logger.error('Error generating commit message:', error);
|
|
96
|
-
return {
|
|
97
|
-
content: [
|
|
98
|
-
{
|
|
99
|
-
type: 'text',
|
|
100
|
-
text: JSON.stringify({
|
|
101
|
-
success: false,
|
|
102
|
-
error: error instanceof Error ? error.message : String(error),
|
|
103
|
-
}, null, 2),
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
isError: true,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
export async function handleAnalyzeChanges(args) {
|
|
111
|
-
try {
|
|
112
|
-
Logger.log(`Analyzing changes for: ${args.repoPath}`);
|
|
113
|
-
await GitService.validateRepository(args.repoPath);
|
|
114
|
-
const hasStagedChanges = await GitService.hasChanges(args.repoPath, 'staged');
|
|
115
|
-
const hasUnstagedChanges = await GitService.hasChanges(args.repoPath, 'unstaged');
|
|
116
|
-
const hasUntrackedFiles = await GitService.hasChanges(args.repoPath, 'untracked');
|
|
117
|
-
const diff = await GitService.getDiff(args.repoPath, args.onlyStaged || false);
|
|
118
|
-
const changedFiles = await GitService.getChangedFiles(args.repoPath, args.onlyStaged || false);
|
|
23
|
+
const onlyStaged = ConfigService.getOnlyStaged();
|
|
24
|
+
const result = await AIService.generateCommitMessageForRepo(args.repoPath, onlyStaged);
|
|
119
25
|
return {
|
|
120
26
|
content: [
|
|
121
27
|
{
|
|
122
|
-
type:
|
|
28
|
+
type: "text",
|
|
123
29
|
text: JSON.stringify({
|
|
124
30
|
success: true,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
hasUntrackedFiles,
|
|
129
|
-
changedFilesCount: changedFiles.length,
|
|
130
|
-
changedFiles,
|
|
131
|
-
diffLength: diff.length,
|
|
132
|
-
diffPreview: diff.substring(0, 500),
|
|
133
|
-
},
|
|
31
|
+
message: result.message,
|
|
32
|
+
model: result.model,
|
|
33
|
+
provider: ConfigService.getProvider(),
|
|
134
34
|
}, null, 2),
|
|
135
35
|
},
|
|
136
36
|
],
|
|
137
37
|
};
|
|
138
38
|
}
|
|
139
39
|
catch (error) {
|
|
140
|
-
Logger.error(
|
|
40
|
+
Logger.error("Error generating commit message:", error);
|
|
141
41
|
return {
|
|
142
42
|
content: [
|
|
143
43
|
{
|
|
144
|
-
type:
|
|
44
|
+
type: "text",
|
|
145
45
|
text: JSON.stringify({
|
|
146
46
|
success: false,
|
|
147
47
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -152,75 +52,19 @@ export async function handleAnalyzeChanges(args) {
|
|
|
152
52
|
};
|
|
153
53
|
}
|
|
154
54
|
}
|
|
155
|
-
export async function handleListCommitFormats(_args) {
|
|
156
|
-
const formats = [
|
|
157
|
-
{
|
|
158
|
-
name: 'conventional',
|
|
159
|
-
description: 'Conventional Commits format: type(scope): description',
|
|
160
|
-
example: 'feat(auth): add OAuth2 authentication',
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: 'angular',
|
|
164
|
-
description: 'Angular commit format with type, scope, and summary',
|
|
165
|
-
example: 'build(deps): update dependency versions',
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
name: 'karma',
|
|
169
|
-
description: 'Karma format: type(scope): message',
|
|
170
|
-
example: 'fix(parser): handle edge case in tokenizer',
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
name: 'semantic',
|
|
174
|
-
description: 'Semantic format: type: message',
|
|
175
|
-
example: 'refactor: simplify user authentication flow',
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
name: 'emoji',
|
|
179
|
-
description: 'Emoji-based commit messages',
|
|
180
|
-
example: ':sparkles: Add dark mode support',
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'emojiKarma',
|
|
184
|
-
description: 'Combination of emoji and Karma format',
|
|
185
|
-
example: ':bug: fix(ui): correct button alignment',
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
name: 'google',
|
|
189
|
-
description: 'Google commit format with capitalized type',
|
|
190
|
-
example: 'Feature: Add user profile page',
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
name: 'atom',
|
|
194
|
-
description: 'Atom editor commit format',
|
|
195
|
-
example: 'feat(editor): add syntax highlighting',
|
|
196
|
-
},
|
|
197
|
-
];
|
|
198
|
-
return {
|
|
199
|
-
content: [
|
|
200
|
-
{
|
|
201
|
-
type: 'text',
|
|
202
|
-
text: JSON.stringify({
|
|
203
|
-
success: true,
|
|
204
|
-
formats,
|
|
205
|
-
currentFormat: ConfigService.getCommitFormat(),
|
|
206
|
-
}, null, 2),
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
55
|
export async function handleValidateApiKey(args) {
|
|
212
56
|
try {
|
|
213
57
|
const provider = args.provider;
|
|
214
58
|
// Ollama doesn't require API key
|
|
215
|
-
if (provider ===
|
|
59
|
+
if (provider === "ollama") {
|
|
216
60
|
return {
|
|
217
61
|
content: [
|
|
218
62
|
{
|
|
219
|
-
type:
|
|
63
|
+
type: "text",
|
|
220
64
|
text: JSON.stringify({
|
|
221
65
|
success: true,
|
|
222
66
|
valid: true,
|
|
223
|
-
message:
|
|
67
|
+
message: "Ollama does not require an API key",
|
|
224
68
|
}),
|
|
225
69
|
},
|
|
226
70
|
],
|
|
@@ -231,7 +75,7 @@ export async function handleValidateApiKey(args) {
|
|
|
231
75
|
return {
|
|
232
76
|
content: [
|
|
233
77
|
{
|
|
234
|
-
type:
|
|
78
|
+
type: "text",
|
|
235
79
|
text: JSON.stringify({
|
|
236
80
|
success: false,
|
|
237
81
|
valid: false,
|
|
@@ -244,7 +88,7 @@ export async function handleValidateApiKey(args) {
|
|
|
244
88
|
return {
|
|
245
89
|
content: [
|
|
246
90
|
{
|
|
247
|
-
type:
|
|
91
|
+
type: "text",
|
|
248
92
|
text: JSON.stringify({
|
|
249
93
|
success: true,
|
|
250
94
|
valid: true,
|
|
@@ -258,7 +102,7 @@ export async function handleValidateApiKey(args) {
|
|
|
258
102
|
return {
|
|
259
103
|
content: [
|
|
260
104
|
{
|
|
261
|
-
type:
|
|
105
|
+
type: "text",
|
|
262
106
|
text: JSON.stringify({
|
|
263
107
|
success: false,
|
|
264
108
|
error: error instanceof Error ? error.message : String(error),
|
package/dist/server/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,eAAe;AACf,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CACP,2FAA2F,CAC5F;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;SACjD,QAAQ,CAAC,sBAAsB,CAAC;CACpC,CAAC,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,IAAiD;IAEjD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,kCAAkC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE9D,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,4BAA4B,CACzD,IAAI,CAAC,QAAQ,EACb,UAAU,CACX,CAAC;QAEF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,IAAI;wBACb,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,QAAQ,EAAE,aAAa,CAAC,WAAW,EAAE;qBACtC,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA0C;IAE1C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE/B,iCAAiC;QACjC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,OAAO,EAAE,IAAI;4BACb,KAAK,EAAE,IAAI;4BACX,OAAO,EAAE,oCAAoC;yBAC9C,CAAC;qBACH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEjD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,KAAK;4BACZ,OAAO,EAAE,wBAAwB,QAAQ,EAAE;yBAC5C,CAAC;qBACH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE,IAAI;wBACX,OAAO,EAAE,qBAAqB,QAAQ,EAAE;qBACzC,CAAC;iBACH;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,CAAC;iBACH;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,46 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base AI service utilities
|
|
3
|
-
* Adapted from VSCode extension
|
|
4
3
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { ApiErrorResult } from "../utils/retryUtils.js";
|
|
5
|
+
import { CommitMessage, ProgressReporter } from "../models/types.js";
|
|
6
|
+
export interface ProviderRequestConfig {
|
|
7
|
+
url: string;
|
|
8
|
+
payload: unknown;
|
|
9
|
+
headers: Record<string, string>;
|
|
10
|
+
model: string;
|
|
11
|
+
providerName: string;
|
|
12
|
+
}
|
|
7
13
|
export declare class BaseAIService {
|
|
8
|
-
/**
|
|
9
|
-
* Clean commit message
|
|
10
|
-
*/
|
|
11
|
-
static cleanCommitMessage(message: string): string;
|
|
12
14
|
/**
|
|
13
15
|
* Validate commit message is not empty
|
|
14
16
|
*/
|
|
15
17
|
static validateCommitMessage(message: string): string;
|
|
16
|
-
static createRequestHeaders: typeof HttpUtils.createRequestHeaders;
|
|
17
|
-
static createRequestConfig: typeof HttpUtils.createRequestConfig;
|
|
18
|
-
static updateProgressForAttempt: typeof RetryUtils.updateProgressForAttempt;
|
|
19
|
-
static calculateRetryDelay: typeof RetryUtils.calculateRetryDelay;
|
|
20
|
-
static delay: typeof RetryUtils.delay;
|
|
21
|
-
static handleGenerationError: typeof RetryUtils.handleGenerationError;
|
|
22
18
|
/**
|
|
23
19
|
* Extract and validate commit message from response
|
|
24
20
|
*/
|
|
25
21
|
static extractAndValidateMessage(content: string | undefined | null, serviceName: string): string;
|
|
26
22
|
/**
|
|
27
|
-
*
|
|
23
|
+
* Shared generation method with retry logic for all providers.
|
|
24
|
+
* Handles: request, response extraction, 401 → ApiKeyInvalidError, retry.
|
|
28
25
|
*/
|
|
29
|
-
static
|
|
26
|
+
static generateWithRetry<TResponse>(config: ProviderRequestConfig, extractMessage: (data: TResponse) => string, errorHandler: (error: Error) => ApiErrorResult, progress: ProgressReporter, attempt: number, generateFn: (prompt: string, progress: ProgressReporter, attempt: number) => Promise<CommitMessage>, prompt: string): Promise<CommitMessage>;
|
|
30
27
|
/**
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
static handleGeminiError(error: Error): ApiErrorResult;
|
|
34
|
-
/**
|
|
35
|
-
* OpenAI-specific error handling
|
|
36
|
-
*/
|
|
37
|
-
static handleOpenAIError(error: Error): ApiErrorResult;
|
|
38
|
-
/**
|
|
39
|
-
* Codestral-specific error handling
|
|
28
|
+
* Universal HTTP error handler for all AI services
|
|
40
29
|
*/
|
|
41
|
-
static
|
|
30
|
+
static handleHttpError(error: Error, serviceName: string): ApiErrorResult;
|
|
42
31
|
/**
|
|
43
|
-
* Ollama-specific error handling
|
|
32
|
+
* Ollama-specific error handling (has extra cases for 404 and connection)
|
|
44
33
|
*/
|
|
45
34
|
static handleOllamaError(error: Error): ApiErrorResult;
|
|
46
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseAIService.d.ts","sourceRoot":"","sources":["../../src/services/baseAIService.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"baseAIService.d.ts","sourceRoot":"","sources":["../../src/services/baseAIService.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAWrE,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAQrD;;OAEG;IACH,MAAM,CAAC,yBAAyB,CAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAClC,WAAW,EAAE,MAAM,GAClB,MAAM;IAOT;;;OAGG;WACU,iBAAiB,CAAC,SAAS,EACtC,MAAM,EAAE,qBAAqB,EAC7B,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,EAC3C,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,cAAc,EAC9C,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,aAAa,CAAC,EAC3B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC;IAwCzB;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc;IAgEzE;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc;CAyBvD"}
|
|
@@ -1,42 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base AI service utilities
|
|
3
|
-
* Adapted from VSCode extension
|
|
4
3
|
*/
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
4
|
+
import axios from "axios";
|
|
5
|
+
import { Logger } from "../utils/logger.js";
|
|
6
|
+
import { HttpUtils } from "../utils/httpUtils.js";
|
|
7
|
+
import { RetryUtils } from "../utils/retryUtils.js";
|
|
8
|
+
import { ApiKeyInvalidError } from "../models/errors.js";
|
|
7
9
|
const errorMessages = {
|
|
8
|
-
authenticationError:
|
|
9
|
-
paymentRequired:
|
|
10
|
-
rateLimitExceeded:
|
|
11
|
-
invalidRequest:
|
|
12
|
-
serverError:
|
|
13
|
-
apiError:
|
|
10
|
+
authenticationError: "Authentication failed. Please check your API key.",
|
|
11
|
+
paymentRequired: "Payment required. Please check your account billing.",
|
|
12
|
+
rateLimitExceeded: "Rate limit exceeded. Please try again later.",
|
|
13
|
+
invalidRequest: "Invalid request. Please check your parameters.",
|
|
14
|
+
serverError: "Server error. Please try again later.",
|
|
15
|
+
apiError: "API error (status {0})",
|
|
14
16
|
};
|
|
15
17
|
export class BaseAIService {
|
|
16
|
-
/**
|
|
17
|
-
* Clean commit message
|
|
18
|
-
*/
|
|
19
|
-
static cleanCommitMessage(message) {
|
|
20
|
-
return message.trim();
|
|
21
|
-
}
|
|
22
18
|
/**
|
|
23
19
|
* Validate commit message is not empty
|
|
24
20
|
*/
|
|
25
21
|
static validateCommitMessage(message) {
|
|
26
|
-
const cleanMessage =
|
|
27
|
-
if (!cleanMessage
|
|
28
|
-
throw new Error(
|
|
22
|
+
const cleanMessage = message.trim();
|
|
23
|
+
if (!cleanMessage) {
|
|
24
|
+
throw new Error("Generated commit message is empty.");
|
|
29
25
|
}
|
|
30
26
|
return cleanMessage;
|
|
31
27
|
}
|
|
32
|
-
// Delegate HTTP operations to HttpUtils
|
|
33
|
-
static createRequestHeaders = HttpUtils.createRequestHeaders;
|
|
34
|
-
static createRequestConfig = HttpUtils.createRequestConfig;
|
|
35
|
-
// Delegate retry operations to RetryUtils
|
|
36
|
-
static updateProgressForAttempt = RetryUtils.updateProgressForAttempt;
|
|
37
|
-
static calculateRetryDelay = RetryUtils.calculateRetryDelay;
|
|
38
|
-
static delay = RetryUtils.delay;
|
|
39
|
-
static handleGenerationError = RetryUtils.handleGenerationError;
|
|
40
28
|
/**
|
|
41
29
|
* Extract and validate commit message from response
|
|
42
30
|
*/
|
|
@@ -46,6 +34,32 @@ export class BaseAIService {
|
|
|
46
34
|
}
|
|
47
35
|
return this.validateCommitMessage(content);
|
|
48
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Shared generation method with retry logic for all providers.
|
|
39
|
+
* Handles: request, response extraction, 401 → ApiKeyInvalidError, retry.
|
|
40
|
+
*/
|
|
41
|
+
static async generateWithRetry(config, extractMessage, errorHandler, progress, attempt, generateFn, prompt) {
|
|
42
|
+
try {
|
|
43
|
+
Logger.log(`Attempt ${attempt}: Sending request to ${config.providerName}`);
|
|
44
|
+
await RetryUtils.updateProgressForAttempt(progress, attempt);
|
|
45
|
+
const requestConfig = HttpUtils.createRequestConfig(config.headers);
|
|
46
|
+
const response = await axios.post(config.url, config.payload, requestConfig);
|
|
47
|
+
progress.report({
|
|
48
|
+
message: "Processing generated message...",
|
|
49
|
+
increment: 90,
|
|
50
|
+
});
|
|
51
|
+
const message = extractMessage(response.data);
|
|
52
|
+
Logger.log(`Commit message generated using ${config.model} model`);
|
|
53
|
+
return { message, model: config.model };
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const axiosError = error;
|
|
57
|
+
if (axiosError.response?.status === 401) {
|
|
58
|
+
throw new ApiKeyInvalidError(config.providerName);
|
|
59
|
+
}
|
|
60
|
+
return RetryUtils.handleGenerationError(error, prompt, progress, attempt, generateFn, errorHandler);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
49
63
|
/**
|
|
50
64
|
* Universal HTTP error handler for all AI services
|
|
51
65
|
*/
|
|
@@ -84,68 +98,45 @@ export class BaseAIService {
|
|
|
84
98
|
default:
|
|
85
99
|
const responseData = JSON.stringify(axiosError.response.data);
|
|
86
100
|
return {
|
|
87
|
-
errorMessage: `${errorMessages.apiError.replace(
|
|
101
|
+
errorMessage: `${errorMessages.apiError.replace("{0}", String(status))}: ${errorMessage || responseData}`,
|
|
88
102
|
shouldRetry: status >= 500,
|
|
89
103
|
};
|
|
90
104
|
}
|
|
91
105
|
}
|
|
92
106
|
// Network errors
|
|
93
|
-
if (axiosError.code ===
|
|
94
|
-
axiosError.code ===
|
|
95
|
-
axiosError.message?.includes(
|
|
96
|
-
axiosError.message?.includes(
|
|
107
|
+
if (axiosError.code === "ECONNREFUSED" ||
|
|
108
|
+
axiosError.code === "ETIMEDOUT" ||
|
|
109
|
+
axiosError.message?.includes("ECONNREFUSED") ||
|
|
110
|
+
axiosError.message?.includes("ETIMEDOUT")) {
|
|
97
111
|
return {
|
|
98
112
|
errorMessage: `Could not connect to ${serviceName}. Please check your internet connection.`,
|
|
99
113
|
shouldRetry: true,
|
|
100
114
|
};
|
|
101
115
|
}
|
|
102
116
|
return {
|
|
103
|
-
errorMessage: axiosError.message ||
|
|
117
|
+
errorMessage: axiosError.message || "Unknown error",
|
|
104
118
|
shouldRetry: false,
|
|
105
119
|
};
|
|
106
120
|
}
|
|
107
121
|
/**
|
|
108
|
-
*
|
|
109
|
-
*/
|
|
110
|
-
static handleGeminiError(error) {
|
|
111
|
-
return this.handleHttpError(error, 'Gemini API');
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* OpenAI-specific error handling
|
|
115
|
-
*/
|
|
116
|
-
static handleOpenAIError(error) {
|
|
117
|
-
return this.handleHttpError(error, 'OpenAI API');
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Codestral-specific error handling
|
|
121
|
-
*/
|
|
122
|
-
static handleCodestralError(error) {
|
|
123
|
-
const result = this.handleHttpError(error, 'Codestral API');
|
|
124
|
-
if (error.response?.status === 401) {
|
|
125
|
-
result.errorMessage =
|
|
126
|
-
'Invalid API key. Please check your Codestral API key.';
|
|
127
|
-
}
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Ollama-specific error handling
|
|
122
|
+
* Ollama-specific error handling (has extra cases for 404 and connection)
|
|
132
123
|
*/
|
|
133
124
|
static handleOllamaError(error) {
|
|
134
125
|
const axiosError = error;
|
|
135
126
|
if (axiosError.response?.status === 404) {
|
|
136
127
|
return {
|
|
137
|
-
errorMessage:
|
|
128
|
+
errorMessage: "Model not found. Please check if Ollama is running and the model is installed.",
|
|
138
129
|
shouldRetry: false,
|
|
139
130
|
};
|
|
140
131
|
}
|
|
141
|
-
const result = this.handleHttpError(error,
|
|
142
|
-
if (result.shouldRetry &&
|
|
132
|
+
const result = this.handleHttpError(error, "Ollama");
|
|
133
|
+
if (result.shouldRetry && axiosError.response?.status === 500) {
|
|
143
134
|
result.errorMessage =
|
|
144
|
-
|
|
135
|
+
"Server error. Please check if Ollama is running properly.";
|
|
145
136
|
}
|
|
146
|
-
if (result.shouldRetry && !
|
|
137
|
+
if (result.shouldRetry && !axiosError.response) {
|
|
147
138
|
result.errorMessage =
|
|
148
|
-
|
|
139
|
+
"Could not connect to Ollama. Please make sure Ollama is running.";
|
|
149
140
|
}
|
|
150
141
|
return result;
|
|
151
142
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseAIService.js","sourceRoot":"","sources":["../../src/services/baseAIService.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"baseAIService.js","sourceRoot":"","sources":["../../src/services/baseAIService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codestralService.d.ts","sourceRoot":"","sources":["../../src/services/codestralService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codestralService.d.ts","sourceRoot":"","sources":["../../src/services/codestralService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAarE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CACuB;WAExC,qBAAqB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,aAAa,CAAC;IAwBzB,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAIpC"}
|
|
@@ -1,45 +1,21 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import { Logger } from "../utils/logger.js";
|
|
3
1
|
import { ConfigService } from "../utils/config.js";
|
|
4
|
-
import { ApiKeyInvalidError } from "../models/errors.js";
|
|
5
2
|
import { BaseAIService } from "./baseAIService.js";
|
|
6
3
|
import { HttpUtils } from "../utils/httpUtils.js";
|
|
7
|
-
import { RetryUtils } from "../utils/retryUtils.js";
|
|
8
|
-
// AI сервис для работы с Mistral Codestral API
|
|
9
|
-
// Реализует интерфейс IAIService со статическими методами
|
|
10
4
|
export class CodestralService {
|
|
11
5
|
static apiUrl = "https://codestral.mistral.ai/v1/chat/completions";
|
|
12
6
|
static async generateCommitMessage(prompt, progress, attempt = 1) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
const apiKey = ConfigService.getApiKey("codestral");
|
|
8
|
+
const model = ConfigService.getCodestralModel();
|
|
9
|
+
return BaseAIService.generateWithRetry({
|
|
10
|
+
url: this.apiUrl,
|
|
11
|
+
payload: {
|
|
12
|
+
model,
|
|
18
13
|
messages: [{ role: "user", content: prompt }],
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const response = await axios.post(this.apiUrl, payload, requestConfig);
|
|
25
|
-
void Logger.log("Codestral API response received successfully");
|
|
26
|
-
progress.report({
|
|
27
|
-
message: "Processing generated message...",
|
|
28
|
-
increment: 90,
|
|
29
|
-
});
|
|
30
|
-
const commitMessage = this.extractCommitMessage(response.data);
|
|
31
|
-
void Logger.log(`Commit message generated using ${model} model`);
|
|
32
|
-
return { message: commitMessage, model };
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
// Обработка специальных случаев для Codestral
|
|
36
|
-
const axiosError = error;
|
|
37
|
-
if (axiosError.response?.status === 401) {
|
|
38
|
-
throw new ApiKeyInvalidError("Codestral");
|
|
39
|
-
}
|
|
40
|
-
// Используем retry utils для retry логики
|
|
41
|
-
return RetryUtils.handleGenerationError(error, prompt, progress, attempt, this.generateCommitMessage.bind(this), BaseAIService.handleCodestralError.bind(BaseAIService));
|
|
42
|
-
}
|
|
14
|
+
},
|
|
15
|
+
headers: HttpUtils.createRequestHeaders(apiKey),
|
|
16
|
+
model,
|
|
17
|
+
providerName: "Codestral",
|
|
18
|
+
}, (data) => this.extractCommitMessage(data), (error) => BaseAIService.handleHttpError(error, "Codestral API"), progress, attempt, this.generateCommitMessage.bind(this), prompt);
|
|
43
19
|
}
|
|
44
20
|
static extractCommitMessage(response) {
|
|
45
21
|
const content = response.choices?.[0]?.message?.content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codestralService.js","sourceRoot":"","sources":["../../src/services/codestralService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codestralService.js","sourceRoot":"","sources":["../../src/services/codestralService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAUlD,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAU,MAAM,GAC5B,kDAAkD,CAAC;IAErD,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAChC,MAAc,EACd,QAA0B,EAC1B,UAAkB,CAAC;QAEnB,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,aAAa,CAAC,iBAAiB,EAAE,CAAC;QAEhD,OAAO,aAAa,CAAC,iBAAiB,CACpC;YACE,GAAG,EAAE,IAAI,CAAC,MAAM;YAChB,OAAO,EAAE;gBACP,KAAK;gBACL,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C;YACD,OAAO,EAAE,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC;YAC/C,KAAK;YACL,YAAY,EAAE,WAAW;SAC1B,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EACzC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC,KAAK,EAAE,eAAe,CAAC,EAChE,QAAQ,EACR,OAAO,EACP,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EACrC,MAAM,CACP,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,QAA2B;QAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;QACxD,OAAO,aAAa,CAAC,yBAAyB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACvE,CAAC"}
|