4
4
ConfigKey ,
5
5
ExtensionConfiguration ,
6
6
type ConfigurationValueType ,
7
+ PROVIDER_REQUIRED_FIELDS ,
7
8
} from "./types" ;
8
9
import { EXTENSION_NAME } from "../constants" ;
9
10
import { generateCommitMessageSystemPrompt } from "../prompt/prompt" ;
@@ -17,13 +18,15 @@ import {
17
18
generateConfiguration ,
18
19
isConfigValue ,
19
20
} from "./ConfigSchema" ;
21
+ import { getSystemPrompt } from "../ai/utils/generateHelper" ;
20
22
21
23
export class ConfigurationManager {
22
24
private static instance : ConfigurationManager ;
23
25
private configuration : vscode . WorkspaceConfiguration ;
24
26
private configCache : Map < string , any > = new Map ( ) ;
25
27
private readonly disposables : vscode . Disposable [ ] = [ ] ;
26
28
private context ?: vscode . ExtensionContext ;
29
+ private configurationInProgress : boolean = false ;
27
30
28
31
private getUpdatedValue < T > ( key : string ) : T | undefined {
29
32
// 直接从workspace configuration获取最新值
@@ -110,50 +113,75 @@ export class ConfigurationManager {
110
113
public getConfig < K extends ConfigKey > (
111
114
key : K ,
112
115
useCache : boolean = true
113
- ) : ConfigurationValueType [ K ] {
116
+ ) : K extends keyof ConfigurationValueType
117
+ ? ConfigurationValueType [ K ]
118
+ : string {
114
119
console . log ( "获取配置项:" , key , ConfigKeys ) ;
115
120
const configKey = ConfigKeys [ key ] . replace ( "dish-ai-commit." , "" ) ;
116
121
117
122
if ( ! useCache ) {
118
- // 直接从 configuration 获取最新值,确保返回正确的类型
119
- const value =
120
- this . configuration . get < ConfigurationValueType [ K ] > ( configKey ) ;
121
- return value as ConfigurationValueType [ K ] ;
123
+ const value = this . configuration . get < string > ( configKey ) ;
124
+ return value as K extends keyof ConfigurationValueType
125
+ ? ConfigurationValueType [ K ]
126
+ : string ;
122
127
}
123
128
124
129
if ( ! this . configCache . has ( configKey ) ) {
125
- const value =
126
- this . configuration . get < ConfigurationValueType [ K ] > ( configKey ) ;
130
+ const value = this . configuration . get < string > ( configKey ) ;
127
131
this . configCache . set ( configKey , value ) ;
128
132
}
129
- return this . configCache . get ( configKey ) as ConfigurationValueType [ K ] ;
133
+ return this . configCache . get (
134
+ configKey
135
+ ) as K extends keyof ConfigurationValueType
136
+ ? ConfigurationValueType [ K ]
137
+ : string ;
130
138
}
131
139
132
- public getConfiguration ( ) : ExtensionConfiguration {
133
- // 使用generateConfiguration自动生成配置
134
- const config = generateConfiguration ( CONFIG_SCHEMA , ( key : string ) => {
135
- return this . configuration . get < any > ( `${ key } ` ) ;
136
- } ) ;
137
-
138
- // 处理特殊情况:system prompt
139
- const currentScm = SCMFactory . getCurrentSCMType ( ) || "git" ;
140
- if ( ! config . base . systemPrompt ) {
141
- config . base . systemPrompt = generateCommitMessageSystemPrompt (
142
- config . base . language ,
143
- config . features . commitOptions . allowMergeCommits ,
144
- false ,
145
- currentScm ,
146
- config . features . commitOptions . useEmoji
147
- ) ;
140
+ public getConfiguration (
141
+ skipSystemPrompt : boolean = false
142
+ ) : ExtensionConfiguration {
143
+ if ( this . configurationInProgress ) {
144
+ // 如果已经在获取配置过程中,返回基本配置而不包含 systemPrompt
145
+ const config = generateConfiguration ( CONFIG_SCHEMA , ( key : string ) => {
146
+ return this . configuration . get < any > ( `${ key } ` ) ;
147
+ } ) ;
148
+ return config as ExtensionConfiguration ;
148
149
}
149
150
150
- return config as ExtensionConfiguration ;
151
+ try {
152
+ this . configurationInProgress = true ;
153
+
154
+ // 使用generateConfiguration自动生成配置
155
+ const config = generateConfiguration ( CONFIG_SCHEMA , ( key : string ) => {
156
+ return this . configuration . get < any > ( `${ key } ` ) ;
157
+ } ) ;
158
+
159
+ // 只在非跳过模式下且明确需要 systemPrompt 时才生成
160
+ if ( ! skipSystemPrompt && ! config . base . systemPrompt ) {
161
+ const currentScm = SCMFactory . getCurrentSCMType ( ) || "git" ;
162
+ const promptConfig = {
163
+ ...config . base ,
164
+ ...config . features . commitFormat ,
165
+ ...config . features . codeAnalysis ,
166
+ scm : currentScm ,
167
+ diff : "" ,
168
+ additionalContext : "" ,
169
+ model : { } ,
170
+ } ;
171
+
172
+ config . base . systemPrompt = getSystemPrompt ( promptConfig ) ;
173
+ }
174
+
175
+ return config as ExtensionConfiguration ;
176
+ } finally {
177
+ this . configurationInProgress = false ;
178
+ }
151
179
}
152
180
153
- // 修改updateConfig方法签名
181
+ // 修改updateConfig方法签名,使用条件类型处理值的类型
154
182
public async updateConfig < K extends ConfigKey > (
155
183
key : K ,
156
- value : ConfigurationValueType [ K ]
184
+ value : string
157
185
) : Promise < void > {
158
186
await this . configuration . update (
159
187
ConfigKeys [ key ] . replace ( "dish-ai-commit." , "" ) ,
@@ -243,24 +271,23 @@ export class ConfigurationManager {
243
271
*/
244
272
public async validateConfiguration ( ) : Promise < boolean > {
245
273
const config = this . getConfiguration ( ) ;
246
- const provider = config . base . provider . toLowerCase ( ) ;
247
-
248
- switch ( provider ) {
249
- case "openai" :
250
- return this . validateProviderConfig ( "openai" , "apiKey" ) ;
251
- case "ollama" :
252
- return this . validateProviderConfig ( "ollama" , "baseUrl" ) ;
253
- case "zhipuai" :
254
- return this . validateProviderConfig ( "zhipuai" , "apiKey" ) ;
255
- case "dashscope" :
256
- return this . validateProviderConfig ( "dashscope" , "apiKey" ) ;
257
- case "doubao" :
258
- return this . validateProviderConfig ( "doubao" , "apiKey" ) ;
259
- case "vs code provided" :
260
- return Promise . resolve ( true ) ;
261
- default :
262
- return Promise . resolve ( false ) ;
274
+ const provider = ( config . base . provider as string ) . toLowerCase ( ) ;
275
+
276
+ // VS Code 提供的AI不需要验证
277
+ if ( provider === "vs code provided" ) {
278
+ return true ;
263
279
}
280
+
281
+ // 检查是否是支持的提供商
282
+ if ( provider in PROVIDER_REQUIRED_FIELDS ) {
283
+ const requiredField = PROVIDER_REQUIRED_FIELDS [ provider ] ;
284
+ return this . validateProviderConfig (
285
+ provider as keyof ExtensionConfiguration [ "providers" ] ,
286
+ requiredField
287
+ ) ;
288
+ }
289
+
290
+ return false ;
264
291
}
265
292
266
293
/**
@@ -302,12 +329,12 @@ export class ConfigurationManager {
302
329
* 更新 AI 提供商和模型配置
303
330
*/
304
331
public async updateAIConfiguration (
305
- provider : string ,
306
- model : string
332
+ provider : ExtensionConfiguration [ "base" ] [ "provider" ] ,
333
+ model : ExtensionConfiguration [ "base" ] [ "model" ]
307
334
) : Promise < void > {
308
335
await Promise . all ( [
309
- this . updateConfig ( "BASE_PROVIDER" , provider ) ,
310
- this . updateConfig ( "BASE_MODEL" , model ) ,
336
+ this . updateConfig ( "BASE_PROVIDER" as ConfigKey , provider ) ,
337
+ this . updateConfig ( "BASE_MODEL" as ConfigKey , model ) ,
311
338
] ) ;
312
339
}
313
340
}
0 commit comments