@@ -16,16 +16,18 @@ function getDeepSeekApiKey(): string | null {
1616}
1717
1818/**
19- * 调用 DeepSeek API 发送请求(流式模式)
20- * @param cvbContent CVB 文件内容
21- * @param userRequest 用户输入的重构需求
19+ * 调用 DeepSeek API 的统一函数
20+ * @param userContent 用户输入的内容
21+ * @param systemContent 系统提示词,可选(默认是 "You are a helpful assistant.")
2222 * @param outputChannel 输出通道,用于实时显示流式内容
23- * @returns API 返回的完整 CVB 内容
23+ * @param streamMode 是否启用流式模式,默认为 true
24+ * @returns API 返回的完整内容
2425 */
25- export async function callDeepSeekApi (
26- cvbContent : string ,
27- userRequest : string ,
28- outputChannel : vscode . OutputChannel
26+ async function callDeepSeekApi (
27+ userContent : string ,
28+ systemContent : string = 'You are a helpful assistant.' ,
29+ outputChannel ?: vscode . OutputChannel ,
30+ streamMode : boolean = true
2931) : Promise < string | null > {
3032 const apiKey = getDeepSeekApiKey ( ) ;
3133 if ( ! apiKey ) {
@@ -39,98 +41,108 @@ export async function callDeepSeekApi(
3941 baseURL : 'https://api.deepseek.com' , // 使用 DeepSeek 的 API 地址
4042 } ) ;
4143
42- // 拼接请求内容
43- const requestContent = `
44- 这是我的需求:
45- ${ userRequest }
46-
47- 这是 CVB 格式的说明:
48- ${ getCvbFormatDescription ( ) }
49-
50- 请读取以下 CVB 格式的代码,按照需求写代码,
51- 注意:
52- 如果我要你移动代码,其实是让你去修改原始代码,重新封装到新位置,所以不是让你简单的把代码拷贝到新为止
53- 记住你是个代码重构助手
54- 任何时候都要保证修改完的代码是完整的可执行的,不能有省略
55-
56- 最后的输出需要时 CVB 格式, (注意要完整输出所有文件,不管是否有修改,CVB是一个当前所有文件的快照,所以你不能偷懒):
57- ${ cvbContent }
58- ` ;
59-
6044 // 清空输出通道并显示
61- outputChannel . clear ( ) ;
62- outputChannel . show ( ) ;
45+ if ( outputChannel ) {
46+ outputChannel . clear ( ) ;
47+ outputChannel . show ( ) ;
48+ }
6349
64- // 调用 DeepSeek API(流式模式)
65- const stream = await openai . chat . completions . create ( {
50+ // 调用 OpenAI API
51+ const response = await openai . chat . completions . create ( {
6652 model : 'deepseek-chat' , // 使用 DeepSeek 的模型
6753 messages : [
68- { role : 'system' , content : '你是一个代码重构工具,你只会按照要求输出cvb格式的结果,不会有思考过程和附加内容。' } ,
69- { role : 'user' , content : requestContent } ,
54+ { role : 'system' , content : systemContent } ,
55+ { role : 'user' , content : userContent } ,
7056 ] ,
71- stream : true , // 启用流式模式
57+ stream : streamMode , // 是否启用流式模式
7258 max_tokens : 8192 ,
7359 temperature : 0
7460 } ) ;
7561
7662 let fullResponse = '' ;
77- for await ( const chunk of stream ) {
78- const content = chunk . choices [ 0 ] ?. delta ?. content || '' ;
79- fullResponse += content ;
80- outputChannel . append ( content ) ; // 实时输出到通道
63+ if ( streamMode ) {
64+ // 处理流式响应
65+ for await ( const chunk of response as AsyncIterable < OpenAI . Chat . Completions . ChatCompletionChunk > ) {
66+ const content = chunk . choices [ 0 ] ?. delta ?. content || '' ;
67+ fullResponse += content ;
68+ if ( outputChannel ) {
69+ outputChannel . append ( content ) ; // 实时输出到通道
70+ }
71+ }
72+ } else {
73+ // 处理非流式响应
74+ fullResponse = ( response as OpenAI . Chat . Completions . ChatCompletion ) . choices [ 0 ] . message . content || "" ;
75+ if ( outputChannel ) {
76+ outputChannel . append ( fullResponse ) ;
77+ }
8178 }
8279
83- // 返回完整的 API 响应内容
8480 return fullResponse ;
81+
8582 } catch ( error ) {
8683 vscode . window . showErrorMessage ( 'Failed to call DeepSeek API: ' + ( error as Error ) . message ) ;
8784 return null ;
8885 }
8986}
9087
88+ /**
89+ * 应用代码重构功能
90+ * @param cvbContent CVB 文件内容
91+ * @param userRequest 用户输入的重构需求
92+ * @param outputChannel 输出通道,用于实时显示流式内容
93+ * @returns API 返回的完整 CVB 内容
94+ */
95+ export async function queryCodeReDesign (
96+ cvbContent : string ,
97+ userRequest : string ,
98+ outputChannel : vscode . OutputChannel
99+ ) : Promise < string | null > {
100+ const requestContent = `
101+ 这是我的需求:
102+ ${ userRequest }
103+
104+ 这是 CVB 格式的说明:
105+ ${ getCvbFormatDescription ( ) }
106+
107+ 请读取以下 CVB 格式的代码,按照需求写代码,
108+ 注意:
109+ 如果我要你移动代码,其实是让你去修改原始代码,重新封装到新位置,所以不是让你简单的把代码拷贝到新为止
110+ 记住你是个代码重构助手
111+ 任何时候都要保证修改完的代码是完整的可执行的,不能有省略
112+
113+ 最后的输出需要时 CVB 格式, (注意要完整输出所有文件,不管是否有修改,CVB是一个当前所有文件的快照,所以你不能偷懒):
114+ ${ cvbContent }
115+ ` ;
116+
117+ return callDeepSeekApi ( requestContent , undefined , outputChannel , true ) ;
118+ }
119+
91120function cleanFilename ( str : string ) {
92121 // Replace invalid filename characters for Windows with underscores
93122 return str . replace ( / [ \\ / : * ? " < > | ] / g, '_' ) ;
94123}
95124
96125export async function generateFilenameFromRequest ( userRequest : string ) : Promise < string > {
97- const apiKey = getDeepSeekApiKey ( ) ;
98- if ( ! apiKey ) {
99- return 'default' ;
126+ const summaryResponse = await callDeepSeekApi (
127+ `请简单概括一下需求,输出字符串作为文件名。如果描述里有版本名称,这个名称一定要保留并放在开头。 需求:"${ userRequest } "` ,
128+ '你是一个工具函数,接收请求,只返回纯结果,不要有附加说明.' ,
129+ undefined ,
130+ false
131+ ) ;
132+
133+ let summary = summaryResponse || '' ;
134+ console . log ( 'Raw Summary:' , summary ) ;
135+
136+ // Clean the summary
137+ summary = cleanFilename ( summary ) ;
138+ summary = summary . replace ( / ^ \. + | \. + $ / g, '' ) ; // Remove leading/trailing dots
139+ summary = summary . replace ( / ^ + | + $ / g, '' ) ; // Remove leading/trailing spaces
140+ summary = summary . substring ( 0 , 15 ) ; // Truncate to 15 characters
141+
142+ if ( summary . length === 0 ) {
143+ summary = 'summary' ;
100144 }
101145
102- try {
103- const openai = new OpenAI ( {
104- apiKey : apiKey ,
105- baseURL : 'https://api.deepseek.com' ,
106- } ) ;
107-
108- const summaryResponse = await openai . chat . completions . create ( {
109- model : 'deepseek-chat' ,
110- messages : [
111- { role : 'system' , content : '你是一个工具函数,接收请求,只返回纯结果,不要有附加说明.' } ,
112- { role : 'user' , content : `请简单概括一下需求,输出字符串作为文件名。如果描述里有版本名称,这个名称一定要保留并放在开头。 需求:"${ userRequest } "` } ,
113- ] ,
114- max_tokens : 100 ,
115- temperature : 0 ,
116- } ) ;
117-
118- let summary = summaryResponse . choices [ 0 ] ?. message ?. content || '' ;
119- console . log ( 'Raw Summary:' , summary ) ;
120-
121- // Clean the summary
122- summary = cleanFilename ( summary ) ;
123- summary = summary . replace ( / ^ \. + | \. + $ / g, '' ) ; // Remove leading/trailing dots
124- summary = summary . replace ( / ^ + | + $ / g, '' ) ; // Remove leading/trailing spaces
125- summary = summary . substring ( 0 , 15 ) ; // Truncate to 5 characters
126-
127- if ( summary . length === 0 ) {
128- summary = 'summary' ;
129- }
146+ return summary ;
147+ }
130148
131- return summary ;
132- } catch ( error ) {
133- vscode . window . showErrorMessage ( 'Failed to summarize request: ' + ( error as Error ) . message ) ;
134- return 'error' ;
135- }
136- }
0 commit comments