@comate/zulu 0.7.1 → 0.7.3

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.
Files changed (155) hide show
  1. package/comate-engine/node_modules/@comate/plugin-shared-internals/dist/index.d.ts +1 -0
  2. package/comate-engine/server.js +3 -3
  3. package/dist/bundle/index.js +2 -2
  4. package/package.json +1 -1
  5. package/comate-engine/node_modules/better-sqlite3/build/Release/better_sqlite3.node +0 -0
  6. package/comate-engine/plugins/aiscan/assets/icon.svg +0 -12
  7. package/comate-engine/plugins/aiscan/dist/index.js +0 -54426
  8. package/comate-engine/plugins/aiscan/package.json +0 -67
  9. package/comate-engine/plugins/appdev/assets/icon.png +0 -0
  10. package/comate-engine/plugins/appdev/dist/help.md +0 -12
  11. package/comate-engine/plugins/appdev/dist/index.d.ts +0 -2
  12. package/comate-engine/plugins/appdev/dist/index.js +0 -194
  13. package/comate-engine/plugins/appdev/dist/providers/err.d.ts +0 -8
  14. package/comate-engine/plugins/appdev/dist/providers/err.js +0 -37
  15. package/comate-engine/plugins/appdev/dist/providers/fallback.d.ts +0 -5
  16. package/comate-engine/plugins/appdev/dist/providers/fallback.js +0 -28
  17. package/comate-engine/plugins/appdev/dist/providers/help.d.ts +0 -8
  18. package/comate-engine/plugins/appdev/dist/providers/help.js +0 -19
  19. package/comate-engine/plugins/appdev/dist/providers/medusa.d.ts +0 -8
  20. package/comate-engine/plugins/appdev/dist/providers/medusa.js +0 -39
  21. package/comate-engine/plugins/appdev/dist/providers/qa.d.ts +0 -8
  22. package/comate-engine/plugins/appdev/dist/providers/qa.js +0 -33
  23. package/comate-engine/plugins/appdev/package.json +0 -67
  24. package/comate-engine/plugins/bfc/assets/bfc-icon.png +0 -0
  25. package/comate-engine/plugins/bfc/dist/config/config.d.ts +0 -4
  26. package/comate-engine/plugins/bfc/dist/config/config.js +0 -4
  27. package/comate-engine/plugins/bfc/dist/help.md +0 -11
  28. package/comate-engine/plugins/bfc/dist/index.d.ts +0 -2
  29. package/comate-engine/plugins/bfc/dist/index.js +0 -452
  30. package/comate-engine/plugins/bfc/dist/providers/bfcInstructMode.d.ts +0 -8
  31. package/comate-engine/plugins/bfc/dist/providers/bfcInstructMode.js +0 -77
  32. package/comate-engine/plugins/bfc/dist/providers/genAbnormalCode.d.ts +0 -8
  33. package/comate-engine/plugins/bfc/dist/providers/genAbnormalCode.js +0 -71
  34. package/comate-engine/plugins/bfc/dist/providers/genBfcCode.d.ts +0 -8
  35. package/comate-engine/plugins/bfc/dist/providers/genBfcCode.js +0 -74
  36. package/comate-engine/plugins/bfc/dist/providers/getBatchCases.d.ts +0 -10
  37. package/comate-engine/plugins/bfc/dist/providers/getBatchCases.js +0 -71
  38. package/comate-engine/plugins/bfc/dist/providers/help.d.ts +0 -8
  39. package/comate-engine/plugins/bfc/dist/providers/help.js +0 -19
  40. package/comate-engine/plugins/bfc/dist/service/generateService.d.ts +0 -14
  41. package/comate-engine/plugins/bfc/dist/service/generateService.js +0 -27
  42. package/comate-engine/plugins/bfc/package.json +0 -85
  43. package/comate-engine/plugins/bpm/assets/bpm.png +0 -0
  44. package/comate-engine/plugins/bpm/dist/index.js +0 -313
  45. package/comate-engine/plugins/bpm/package.json +0 -65
  46. package/comate-engine/plugins/casebuilder/assets/icon.svg +0 -1
  47. package/comate-engine/plugins/casebuilder/dist/help.md +0 -33
  48. package/comate-engine/plugins/casebuilder/dist/index.js +0 -837
  49. package/comate-engine/plugins/casebuilder/package.json +0 -80
  50. package/comate-engine/plugins/centrino/assets/icon.png +0 -0
  51. package/comate-engine/plugins/centrino/dist/help.md +0 -30
  52. package/comate-engine/plugins/centrino/dist/index.js +0 -1046
  53. package/comate-engine/plugins/centrino/package.json +0 -68
  54. package/comate-engine/plugins/cnap/assets/cnap.png +0 -0
  55. package/comate-engine/plugins/cnap/dist/help.md +0 -11
  56. package/comate-engine/plugins/cnap/dist/index.js +0 -171
  57. package/comate-engine/plugins/cnap/package.json +0 -65
  58. package/comate-engine/plugins/demo-timer/assets/icon.svg +0 -2
  59. package/comate-engine/plugins/demo-timer/dist/index.js +0 -463
  60. package/comate-engine/plugins/demo-timer/package.json +0 -73
  61. package/comate-engine/plugins/dev-tools/assets/icon.png +0 -0
  62. package/comate-engine/plugins/dev-tools/dist/help.md +0 -18
  63. package/comate-engine/plugins/dev-tools/dist/index.js +0 -166160
  64. package/comate-engine/plugins/dev-tools/package.json +0 -95
  65. package/comate-engine/plugins/devaux/assets/icon.svg +0 -1
  66. package/comate-engine/plugins/devaux/dist/help.md +0 -41
  67. package/comate-engine/plugins/devaux/dist/index.js +0 -75551
  68. package/comate-engine/plugins/devaux/dist/static/tree-sitter-cpp.wasm +0 -0
  69. package/comate-engine/plugins/devaux/dist/static/tree-sitter-go.wasm +0 -0
  70. package/comate-engine/plugins/devaux/dist/static/tree-sitter.wasm +0 -0
  71. package/comate-engine/plugins/devaux/dist/tree-sitter.wasm +0 -0
  72. package/comate-engine/plugins/devaux/package.json +0 -82
  73. package/comate-engine/plugins/f2c/assets/icon.svg +0 -11
  74. package/comate-engine/plugins/f2c/dist/help.md +0 -13
  75. package/comate-engine/plugins/f2c/dist/index.js +0 -101649
  76. package/comate-engine/plugins/f2c/package.json +0 -56
  77. package/comate-engine/plugins/fcnap/assets/icon.png +0 -0
  78. package/comate-engine/plugins/fcnap/dist/help.md +0 -9
  79. package/comate-engine/plugins/fcnap/dist/index.js +0 -105
  80. package/comate-engine/plugins/fcnap/package.json +0 -50
  81. package/comate-engine/plugins/front-end-skills/assets/icon.svg +0 -1
  82. package/comate-engine/plugins/front-end-skills/dist/help.md +0 -17
  83. package/comate-engine/plugins/front-end-skills/dist/index.js +0 -8172
  84. package/comate-engine/plugins/front-end-skills/package.json +0 -79
  85. package/comate-engine/plugins/gdp/assets/icon.png +0 -0
  86. package/comate-engine/plugins/gdp/dist/help.md +0 -11
  87. package/comate-engine/plugins/gdp/dist/index.js +0 -70806
  88. package/comate-engine/plugins/gdp/package.json +0 -80
  89. package/comate-engine/plugins/git/assets/git.svg +0 -1
  90. package/comate-engine/plugins/git/assets/icon.svg +0 -1
  91. package/comate-engine/plugins/git/dist/help.md +0 -7
  92. package/comate-engine/plugins/git/dist/index.js +0 -32765
  93. package/comate-engine/plugins/git/package.json +0 -91
  94. package/comate-engine/plugins/harmonyos/assets/harmonyos.png +0 -0
  95. package/comate-engine/plugins/harmonyos/dist/index.js +0 -78
  96. package/comate-engine/plugins/harmonyos/package.json +0 -37
  97. package/comate-engine/plugins/iapi/assets/icon.png +0 -0
  98. package/comate-engine/plugins/iapi/dist/help.md +0 -13
  99. package/comate-engine/plugins/iapi/dist/index.js +0 -458
  100. package/comate-engine/plugins/iapi/dist/static/lang/tree-sitter-go.wasm +0 -0
  101. package/comate-engine/plugins/iapi/dist/static/lang/tree-sitter-java.wasm +0 -0
  102. package/comate-engine/plugins/iapi/dist/static/tree-sitter-go.wasm +0 -0
  103. package/comate-engine/plugins/iapi/dist/static/tree-sitter-java.wasm +0 -0
  104. package/comate-engine/plugins/iapi/dist/tree-sitter.wasm +0 -0
  105. package/comate-engine/plugins/iapi/package.json +0 -102
  106. package/comate-engine/plugins/icafe/assets/icafe.svg +0 -1
  107. package/comate-engine/plugins/icafe/dist/help.md +0 -5
  108. package/comate-engine/plugins/icafe/dist/index.js +0 -885
  109. package/comate-engine/plugins/icafe/package.json +0 -74
  110. package/comate-engine/plugins/ievalue/assets/iEValue.svg +0 -10
  111. package/comate-engine/plugins/ievalue/dist/index.js +0 -2920
  112. package/comate-engine/plugins/ievalue/package.json +0 -88
  113. package/comate-engine/plugins/ipipe/assets/iPipePlugin.png +0 -0
  114. package/comate-engine/plugins/ipipe/dist/help.md +0 -15
  115. package/comate-engine/plugins/ipipe/dist/index.js +0 -7268
  116. package/comate-engine/plugins/ipipe/package.json +0 -62
  117. package/comate-engine/plugins/jarvis/assets/icon.svg +0 -1
  118. package/comate-engine/plugins/jarvis/dist/help.md +0 -17
  119. package/comate-engine/plugins/jarvis/dist/index.js +0 -140473
  120. package/comate-engine/plugins/jarvis/package.json +0 -93
  121. package/comate-engine/plugins/mapsearch/assets/mapsearchicon.png +0 -0
  122. package/comate-engine/plugins/mapsearch/dist/help.md +0 -4
  123. package/comate-engine/plugins/mapsearch/dist/index.js +0 -145
  124. package/comate-engine/plugins/mapsearch/package.json +0 -53
  125. package/comate-engine/plugins/paddle/assets/icon.png +0 -0
  126. package/comate-engine/plugins/paddle/assets/paconvert-3.0.1-py3-none-any.whl +0 -0
  127. package/comate-engine/plugins/paddle/dist/help.md +0 -31
  128. package/comate-engine/plugins/paddle/dist/index.js +0 -1011
  129. package/comate-engine/plugins/paddle/package.json +0 -129
  130. package/comate-engine/plugins/robot/assets/Robot.png +0 -0
  131. package/comate-engine/plugins/robot/dist/index.js +0 -476
  132. package/comate-engine/plugins/robot/package.json +0 -91
  133. package/comate-engine/plugins/security/assets/comate.png +0 -0
  134. package/comate-engine/plugins/security/dist/index.js +0 -18434
  135. package/comate-engine/plugins/security/package.json +0 -82
  136. package/comate-engine/plugins/smartapp/assets/icon.png +0 -0
  137. package/comate-engine/plugins/smartapp/dist/help.md +0 -4
  138. package/comate-engine/plugins/smartapp/dist/index.js +0 -113
  139. package/comate-engine/plugins/smartapp/package.json +0 -54
  140. package/comate-engine/plugins/testmate/assets/icon.svg +0 -1
  141. package/comate-engine/plugins/testmate/dist/help.md +0 -62
  142. package/comate-engine/plugins/testmate/dist/index.js +0 -21483
  143. package/comate-engine/plugins/testmate/package.json +0 -85
  144. package/comate-engine/plugins/tor/assets/TorPlugin.png +0 -0
  145. package/comate-engine/plugins/tor/dist/help.md +0 -22
  146. package/comate-engine/plugins/tor/dist/index.js +0 -807
  147. package/comate-engine/plugins/tor/package.json +0 -99
  148. package/comate-engine/plugins/weiyun/assets/icon.png +0 -0
  149. package/comate-engine/plugins/weiyun/dist/help.md +0 -11
  150. package/comate-engine/plugins/weiyun/dist/index.js +0 -100495
  151. package/comate-engine/plugins/weiyun/package.json +0 -55
  152. package/comate-engine/plugins/workcard/assets/favicon.png +0 -0
  153. package/comate-engine/plugins/workcard/dist/help.md +0 -30
  154. package/comate-engine/plugins/workcard/dist/index.js +0 -547
  155. package/comate-engine/plugins/workcard/package.json +0 -102
@@ -1,1011 +0,0 @@
1
- import { SkillProvider, TaskProgressChunkStream, StringChunkStream, TextModel, ElementChunkStream, FallbackProvider } from '@comate/plugin-host';
2
- import fs, { readFileSync } from 'fs';
3
- import { fileURLToPath } from 'node:url';
4
- import path, { dirname } from 'path';
5
- import path$1 from 'node:path';
6
- import assert from 'assert';
7
- import childProcess from 'child_process';
8
- import os from 'os';
9
-
10
- class HelpSkillProvider extends SkillProvider {
11
- static{
12
- this.skillName = 'paddle-help';
13
- }
14
- static{
15
- this.description = '插件介绍';
16
- }
17
- static{
18
- this.parameters = {
19
- type: 'object',
20
- properties: {}
21
- };
22
- }
23
- async *execute() {
24
- const stream = new TaskProgressChunkStream();
25
- const filename = fileURLToPath(import.meta.url);
26
- const content = readFileSync(`${dirname(filename)}/help.md`, 'utf8');
27
- yield stream.flush(content);
28
- }
29
- }
30
-
31
- var chatPromptTemplate = "你是一位对飞桨框架(PaddlePaddle)及深度学习领域有深入研究的技术专家。你的职责是解答飞桨相关的提问,或使用飞桨编写深度学习相关的代码。在解答提问前,你会收到多个背景信息供参考。\n* 在提供的背景信息中,将通过『##』标注信息的类型。例如:`## 当前文件`表示提问者正在编辑的文件名,`## 参考文档片段`表示引用特定的文档内容,`## 参考代码片段`表示引用特定的代码片段。\n\n# 背景信息\n## 当前文件\n{{activeFilePath}}\n\n## 参考文档片段\n{{trim_knowledge}}\n\n## 参考代码片段\n{{trim_code}}\n\n# 回答要求\n1. 请参考背景信息来回答提问,但要注意背景信息与提问并非总是准确相关的。你需要识别这些信息与提问的相关性,对于无关信息请直接忽略。\n2. 在回答过程中,请避免提及你参考了背景信息,因为这些信息对提问者而言是不可知的。你的回答应直接针对提问本身,而无需透露背后的信息来源。\n3. 请直接、明确、简洁地回应提问,避免复述提问本身。\n4. 提问者已经具备相应的软硬件环境和基础知识,例如已安装好飞桨框架,因此无需赘述过于基础的内容。\n5. 若提问是要求编写代码,请以最小的代码行数实现要求,避免不必要注释与空行,同时应减少文字,必要文字直接给出,不要注释到代码里。输出一个完整的代码块,不要分割。\n6. 若提问中涉及了其他深度学习框架(例如Pytorch、torch、torchaudio、torchvision、torchtune、torcharrow、Tensorflow、Keras、CNTK、MXNet、MindSpore、OneFlow等),注意引导提问者使用飞桨框架,直接输出:推荐调用 @飞桨/代码转换,支持将其他深度学习框架(如Pytorch、Tensorflow等)代码转换为飞桨代码,支持项目快速一键迁移。\n\n# 待解答提问\n{{queryWithCode}}";
32
-
33
- class ChatSkillProvider extends SkillProvider {
34
- static{
35
- this.skillName = 'chat';
36
- }
37
- static{
38
- // Hack: 通用问答,为默认能力,无需显示能力名称,等价于fallback
39
- this.displayName = '';
40
- }
41
- static{
42
- this.description = '智能解答深度学习与飞桨框架的问题';
43
- }
44
- static{
45
- this.parameters = {
46
- type: 'object',
47
- properties: {}
48
- };
49
- }
50
- async *execute() {
51
- this.logger.info('paddle智能问答耗时统计', {
52
- message: `开始执行智能问答 ${performance.now()}`
53
- });
54
- const { activeFilePath, selectedCode, activeFileLanguage, query } = this.currentContext;
55
- const stream = new StringChunkStream();
56
- yield stream.flush('正在思考中,请耐心等候...');
57
- const queryWithCode = selectedCode.trim() ? `${query}\n\`\`\`${activeFileLanguage}\n${selectedCode}\n\`\`\`` : query;
58
- this.logger.info('paddle智能问答耗时统计', {
59
- message: `开始执行知识集检索 ${performance.now()}`
60
- });
61
- let start = performance.now();
62
- const [knowledge1, knowledge2] = await Promise.all([
63
- this.retriever.knowledgeFromQuery(queryWithCode, {
64
- knowledgeSets: [
65
- // 飞桨API接口文档集
66
- {
67
- uuid: '564a9ebb-a3b1-4d5b-ad28-27c0ab6d78fe',
68
- type: 'NORMAL'
69
- }
70
- ],
71
- queryRewrite: true,
72
- topK: 7
73
- }),
74
- this.retriever.knowledgeFromQuery(queryWithCode, {
75
- knowledgeSets: [
76
- // 飞桨框架与生态文档集
77
- {
78
- uuid: '7ece94ce-e39a-414e-8ca5-d80ed4cf300b',
79
- type: 'NORMAL'
80
- }
81
- ],
82
- queryRewrite: true,
83
- topK: 8
84
- })
85
- ]);
86
- this.logger.info('paddle智能问答耗时统计', {
87
- message: `知识集检索结束,耗时${performance.now() - start}ms`
88
- });
89
- start = performance.now();
90
- const trim_knowledge = [
91
- ...knowledge1,
92
- ...knowledge2
93
- ];
94
- const trim_code = [
95
- ''
96
- ];
97
- const prompt = this.llm.createPrompt(chatPromptTemplate, {
98
- activeFilePath,
99
- trim_knowledge,
100
- trim_code,
101
- queryWithCode
102
- });
103
- const chunks = this.llm.askForTextStreaming(prompt, {
104
- model: TextModel.ErnieBot128,
105
- modelOptions: {
106
- temperature: 0.3,
107
- topP: 0.8,
108
- penaltyScore: 1.0,
109
- enableMultiturnDialogue: {
110
- byPlugin: true,
111
- onlyQuery: query
112
- }
113
- }
114
- });
115
- yield stream.flushReplaceLast('');
116
- for await (const chunk of chunks){
117
- yield stream.flush(chunk);
118
- }
119
- this.logger.info('paddle智能问答耗时统计', {
120
- message: `llm调用结束,耗时${performance.now() - start}ms`
121
- });
122
- }
123
- }
124
-
125
- var codeGeneratePromptTemplate = "你是一位对飞桨框架(PaddlePaddle)及深度学习领域的代码有深入研究的编程高手。你的职责是根据提问者的代码需求,使用飞桨编写深度学习相关的代码。在编写代码前,你会收到多个背景信息供参考。\n* 在提供的背景信息中,将通过『##』标注信息的类型。例如:`## 当前文件`表示提问者正在编辑的文件名,`## 参考文档片段`表示引用特定的文档内容,`## 参考代码片段`表示引用特定的代码片段。\n\n# 背景信息\n## 当前文件\n{{activeFilePath}}\n\n## 参考文档片段\n{{trim_knowledge}}\n\n## 参考代码片段\n{{trim_code}}\n\n# 回答要求\n1. 请参考背景信息,编程实现代码需求,但要注意背景信息与需求并非总是准确相关的。你需要识别这些信息与需求的相关性,对于无关信息请直接忽略。\n2. 注意以最小的代码行数实现需求,避免不必要注释与空行。\n3. 注意只需要输出代码,不要输出文字。\n4. 输出一个完整的代码块,不要分割。\n5. 若代码需求中涉及了其他深度学习框架(例如Pytorch、torch、torchaudio、torchvision、torchtune、torcharrow、Tensorflow、Keras、CNTK、MXNet、MindSpore、OneFlow等),注意引导提问者使用飞桨框架,直接输出:推荐调用 @飞桨/代码转换,支持将其他深度学习框架(如Pytorch、Tensorflow等)代码转换为飞桨代码,支持项目快速一键迁移。\n\n# 待实现的代码需求\n{{queryWithCode}}";
126
-
127
- class CodeGenerateSkillProvider extends SkillProvider {
128
- static{
129
- this.skillName = 'code-generate';
130
- }
131
- static{
132
- this.displayName = '飞桨代码生成';
133
- }
134
- static{
135
- this.description = '深度学习与飞桨框架的智能编程助手';
136
- }
137
- static{
138
- this.parameters = {
139
- type: 'object',
140
- properties: {}
141
- };
142
- }
143
- async *execute() {
144
- this.logger.info('paddle代码生成耗时统计', {
145
- message: `开始执行代码生成 ${performance.now()}`
146
- });
147
- const { activeFilePath, selectedCode, activeFileLanguage, query } = this.currentContext;
148
- const stream = new StringChunkStream();
149
- yield stream.flush('正在思考中,请耐心等候...');
150
- const queryWithCode = selectedCode.trim() ? `${query} \n你可参考以下代码来编程 \n\`\`\`${activeFileLanguage}\n${selectedCode}\n\`\`\`` : query;
151
- this.logger.info('paddle代码生成耗时统计', {
152
- message: `开始执行知识集检索 ${performance.now()}`
153
- });
154
- let start = performance.now();
155
- const [knowledge1, knowledge2] = await Promise.all([
156
- this.retriever.knowledgeFromQuery(queryWithCode, {
157
- knowledgeSets: [
158
- // 飞桨API接口文档集
159
- {
160
- uuid: '564a9ebb-a3b1-4d5b-ad28-27c0ab6d78fe',
161
- type: 'NORMAL'
162
- }
163
- ],
164
- queryRewrite: true
165
- }),
166
- this.retriever.knowledgeFromQuery(queryWithCode, {
167
- knowledgeSets: [
168
- // 飞桨框架与生态文档集
169
- {
170
- uuid: '7ece94ce-e39a-414e-8ca5-d80ed4cf300b',
171
- type: 'NORMAL'
172
- }
173
- ],
174
- queryRewrite: true,
175
- topK: 5
176
- })
177
- ]);
178
- this.logger.info('paddle代码生成耗时统计', {
179
- message: `知识集检索结束,耗时${performance.now() - start}ms`
180
- });
181
- start = performance.now();
182
- const trim_knowledge = [
183
- ...knowledge1,
184
- ...knowledge2
185
- ];
186
- const trim_code = [
187
- ''
188
- ];
189
- const prompt = this.llm.createPrompt(codeGeneratePromptTemplate, {
190
- activeFilePath,
191
- trim_knowledge,
192
- trim_code,
193
- queryWithCode
194
- });
195
- const chunks = this.llm.askForTextStreaming(prompt, {
196
- model: TextModel.ErnieBot128,
197
- modelOptions: {
198
- temperature: 0.1,
199
- topP: 0.8,
200
- penaltyScore: 1.0,
201
- enableMultiturnDialogue: false
202
- }
203
- });
204
- let start_flush = false;
205
- for await (const chunk of chunks){
206
- if (start_flush) {
207
- yield stream.flush(chunk);
208
- } else {
209
- if (chunk.includes('```')) {
210
- start_flush = true;
211
- yield stream.flushReplaceLast('');
212
- yield stream.flush(chunk);
213
- }
214
- }
215
- }
216
- if (!start_flush) {
217
- yield stream.flushReplaceLast('未生成任何代码,请清晰描述您的代码需求,以便我充分理解。');
218
- }
219
- this.logger.info('paddle代码生成耗时统计', {
220
- message: `llm调用结束,耗时${performance.now() - start}ms`
221
- });
222
- }
223
- }
224
-
225
- function jsx(type, props) {
226
- // 按照React的逻辑,`boolean`、`null`、`undefined`是不会显示出来的
227
- const children = Array.isArray(props.children) ? props.children.filter((v)=>v != null && typeof v !== 'boolean') : props.children;
228
- return {
229
- type,
230
- ...props,
231
- children
232
- };
233
- }
234
-
235
- var codeConvertPromptTemplate = "你是一位对各种深度学习框架(例如飞桨PaddlePaddle、Pytorch、Tensorflow、Keras、CNTK、MXNet、MindSpore、OneFlow等)的代码有深入研究的编程高手。你的职责是将飞桨之外的其他深度学习框架代码转写为飞桨代码。在转写代码前,你会收到多个背景信息和转写示例供参考。\n* 在提供的背景信息中,将通过『##』标注信息的类型。例如:`## 参考文档片段`表示引用特定的文档内容,`## 参考代码片段`表示引用特定的代码片段。\n\n# 背景信息\n## 参考文档片段\n{{trim_knowledge}}\n\n## 参考代码片段\n{{trim_code}}\n\n# 转写示例\n## 输入\n```python\nimport torch\nx = torch.tensor([[4., 5., 6.], [1., 2., 3.], [4., 9., 10.]])\ny = torch.tensor([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])\nresult = torch.matmul(x, y)\n```\n## 输出\n```python\nimport paddle\nx = paddle.to_tensor(data=[[4.0, 5.0, 6.0], [1.0, 2.0, 3.0], [4.0, 9.0, 10.0]])\ny = paddle.to_tensor(data=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]])\nresult = paddle.matmul(x=x, y=y)\n```\n\n# 转写要求\n1. 请参考背景信息与转写示例来转写,但要注意背景信息与待转写代码并非总是准确相关的。你需要识别这些信息的相关性,对于无关信息请直接忽略。\n2. 转写示例以Pytorch代码为例,实际输入可能是任意深度学习框架的代码,无论任何输入,输出都是飞桨的代码\n3. 注意输出只需要转写后的代码,文字解释以代码注释形式给出,不要直接输出任何文字\n4. 若待转写代码中没有其他深度学习框架的代码,则无需转写,直接回复:待转写代码与深度学习无关,无法转写到飞桨。\n\n# 待转写代码\n```{{language}}\n{{in_content}}\n```\n";
236
-
237
- function getLanguageFromFilePath(filePath) {
238
- const extension = filePath.split('.').pop();
239
- switch(extension){
240
- case 'bat':
241
- return 'bat';
242
- case 'c':
243
- return 'c';
244
- case 'cc':
245
- return 'cpp';
246
- case 'cu':
247
- return 'cuda-cpp';
248
- case 'go':
249
- return 'go';
250
- case 'js':
251
- return 'javascript';
252
- case 'ts':
253
- return 'typescript';
254
- case 'py':
255
- return 'python';
256
- case 'sh':
257
- return 'shellscript';
258
- case 'yaml':
259
- return 'yaml';
260
- // 可以继续添加其他语言扩展名的情况
261
- default:
262
- return ''; // 如果不知道扩展名对应的语言,返回空字符串
263
- }
264
- }
265
-
266
- function rmDir(dirPath, logger) {
267
- try {
268
- if (!fs.existsSync(dirPath)) {
269
- return;
270
- }
271
- let entries = fs.readdirSync(dirPath, {
272
- withFileTypes: true
273
- });
274
- if (entries.length === 0) {
275
- // 目录为空,直接删除
276
- fs.rmdirSync(dirPath);
277
- logger.info(`目录 ${dirPath} 删除成功`);
278
- return;
279
- }
280
- for (let entry of entries){
281
- let fullPath = path.join(dirPath, entry.name);
282
- if (entry.isDirectory()) {
283
- rmDir(fullPath, logger);
284
- } else {
285
- fs.unlinkSync(fullPath);
286
- }
287
- }
288
- logger.info(`目录 ${dirPath} 删除成功`);
289
- } catch {
290
- logger.error(`目录 ${dirPath} 删除失败`);
291
- }
292
- fs.rmdirSync(dirPath);
293
- }
294
- function getAllFilesPath(dirPath, logger) {
295
- let fileNames = [];
296
- const files = fs.readdirSync(dirPath);
297
- for (const file of files){
298
- const fullPath = path.join(dirPath, file);
299
- const stats = fs.statSync(fullPath);
300
- if (stats.isDirectory()) {
301
- // 如果是目录,则递归调用
302
- fileNames = fileNames.concat(getAllFilesPath(fullPath));
303
- } else {
304
- // 如果是文件,只添加文件名到列表中
305
- fileNames.push(fullPath);
306
- }
307
- }
308
- return fileNames;
309
- }
310
- function readFiles(filePaths, baseDir, logger) {
311
- return filePaths.map((file)=>{
312
- try {
313
- // 同步读取文件内容
314
- const res = fs.readFileSync(file, 'utf8');
315
- return `\`\`\`\n${res}\`\`\``;
316
- } catch (error) {
317
- logger.error(`Error reading file ${file}: ${error}`);
318
- return ''; // 或者你可以返回一个特定的错误消息或null
319
- }
320
- });
321
- }
322
- function readFile(filePath, logger) {
323
- try {
324
- // 同步读取文件内容
325
- const res = fs.readFileSync(filePath, 'utf8');
326
- return res;
327
- } catch (error) {
328
- logger.error(`Error reading file ${filePath}: ${error}`);
329
- return ''; // 或者你可以返回一个特定的错误消息或null
330
- }
331
- }
332
- function ifOverSize(files, baseDir, logger) {
333
- const limit = 5 * 1024 * 1024; // 5MB in bytes
334
- let totalSize = 0;
335
- for (const file of files){
336
- const filePath = file;
337
- try {
338
- const stats = fs.statSync(filePath);
339
- if (stats.isFile()) {
340
- totalSize += stats.size;
341
- if (totalSize > limit) {
342
- return true;
343
- }
344
- } else {
345
- logger.error(`${filePath} is not a file, skipping.`);
346
- }
347
- } catch (error) {
348
- logger.error(`Error statting file ${filePath}: ${error}`);
349
- }
350
- }
351
- return false;
352
- }
353
-
354
- const TEMP = os.tmpdir();
355
- function exec(command) {
356
- return new Promise((resolve, reject)=>{
357
- childProcess.exec(command, (error, stdout)=>{
358
- if (error) {
359
- reject(error);
360
- return;
361
- }
362
- resolve(stdout);
363
- });
364
- });
365
- }
366
- class CodeConvertSkillProvider extends SkillProvider {
367
- static{
368
- this.skillName = 'code-convert';
369
- }
370
- static{
371
- this.displayName = '飞桨代码转换';
372
- }
373
- static{
374
- this.description = '将其他深度学习框架(例如Pytorch、Tensorflow、Keras等)的代码转换为飞桨的代码';
375
- }
376
- static{
377
- this.parameters = {
378
- type: 'object',
379
- properties: {}
380
- };
381
- }
382
- #cwd;
383
- #pluginDir;
384
- constructor(init){
385
- super(init);
386
- this.#cwd = init.cwd;
387
- this.tempDir = path$1.resolve(TEMP, 'paddle_project');
388
- console.log('temp', TEMP);
389
- const entryFileName = fileURLToPath(import.meta.url);
390
- // 取entryFileName的上两级目录
391
- this.#pluginDir = path$1.resolve(entryFileName, '..', '..');
392
- const paconvertWhl = path$1.join(this.#pluginDir, 'assets', 'paconvert-3.0.1-py3-none-any.whl');
393
- exec('paconvert -h').then((stdout)=>{
394
- this.logger.info(`paconvert已安装,无需再次安装: ${stdout}`);
395
- }).catch(()=>{
396
- exec(`python3 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
397
- this.logger.info(`python3安装paconvert成功: ${stdout}`);
398
- }).catch(()=>{
399
- exec(`python3.9 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
400
- this.logger.info(`python3.9安装paconvert成功: ${stdout}`);
401
- }).catch(()=>{
402
- exec(`python3.10 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
403
- this.logger.info(`python3.10安装paconvert成功: ${stdout}`);
404
- }).catch(()=>{
405
- exec(`python3.11 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
406
- this.logger.info(`python3.11安装paconvert成功: ${stdout}`);
407
- }).catch(()=>{
408
- exec(`python3.12 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
409
- this.logger.info(`python3.12安装paconvert成功: ${stdout}`);
410
- }).catch(()=>{
411
- exec(`python3.13 -m pip install -U ${paconvertWhl}`).then((stdout)=>{
412
- this.logger.info(`python3.13安装paconvert成功: ${stdout}`);
413
- }).catch(()=>{
414
- exec(`python -m pip install -U ${paconvertWhl}`).then((stdout)=>{
415
- this.logger.info(`python安装paconvert成功: ${stdout}`);
416
- }).catch((error)=>{
417
- this.logger.error(`paconvert安装失败: ${error.message}`);
418
- });
419
- });
420
- });
421
- });
422
- });
423
- });
424
- });
425
- });
426
- }
427
- async *handleCommand(commandName, data) {
428
- console.log('commandName', commandName);
429
- console.log('commandNameData', data);
430
- const { files } = data;
431
- const stream = new ElementChunkStream();
432
- if (commandName === 'commitMessage:confirmIssue') {
433
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("p", {
434
- children: /*#__PURE__*/ jsx("ul", {
435
- children: files.map((item)=>/*#__PURE__*/ jsx("li", {
436
- children: /*#__PURE__*/ jsx("file-link", {
437
- showIcon: true,
438
- to: path$1.join('./paddle_project', item.replace(this.tempDir, '')),
439
- line: 2,
440
- children: item.replace(this.tempDir, '')
441
- })
442
- }))
443
- })
444
- }));
445
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
446
- children: `完成转换,已经将所有文件写入目录\`${path$1.join(this.#cwd, 'paddle_project')}\`中,您可点击文件链接查看。\n\n\n`
447
- }));
448
- }
449
- }
450
- /**
451
- * 执行转换任务并返回任务进度块
452
- *
453
- * @returns 异步迭代器,返回 TaskProgressChunk 类型的任务进度块
454
- */ async *execute() {
455
- this.logger.info('paddle代码转换耗时统计', {
456
- message: `开始执行环境适配 ${Date.now()}`
457
- });
458
- const stream = new ElementChunkStream();
459
- const { query, selectedCode, activeFileContent, activeFilePath, activeFileLanguage } = this.currentContext;
460
- let use_paconvert = true;
461
- let in_content = '';
462
- // 绝对路径
463
- let in_dir = '';
464
- // 相对路径
465
- let in_rdir = '';
466
- let language = activeFileLanguage;
467
- const fs = await this.requestWorkspaceFileSystem();
468
- // 优先级1: 用户选择的文件/目录
469
- const selectedKnowledgeList = this.retriever.selectedKnowledgeList();
470
- if (selectedKnowledgeList.length) {
471
- if (selectedKnowledgeList[0].type === 'FILE') {
472
- in_content = selectedKnowledgeList[0].content;
473
- in_dir = path$1.resolve(this.#cwd, selectedKnowledgeList[0].path);
474
- in_rdir = selectedKnowledgeList[0].path;
475
- language = getLanguageFromFilePath(selectedKnowledgeList[0].name);
476
- } else if (selectedKnowledgeList[0].type == 'FOLDER') {
477
- in_content = 'FOLDER';
478
- in_dir = path$1.resolve(this.#cwd, selectedKnowledgeList[0].path);
479
- in_rdir = selectedKnowledgeList[0].path;
480
- } else if (selectedKnowledgeList[0].type === 'CURRENT_FILE') {
481
- in_content = activeFileContent;
482
- in_dir = path$1.resolve(this.#cwd, activeFilePath);
483
- in_rdir = activeFilePath;
484
- } else if (selectedKnowledgeList[0].type === 'REPO') {
485
- in_content = 'FOLDER';
486
- in_dir = path$1.resolve(this.#cwd);
487
- }
488
- }
489
- // 优先级2: query为相对路径
490
- if (!in_content && fs && query.trim().length > 0) {
491
- const queryTrim = query.trim();
492
- try {
493
- const stat = await fs.stat(queryTrim);
494
- if (stat.type === 'file') {
495
- in_content = await fs.readFile(queryTrim, 'utf-8');
496
- in_dir = path$1.resolve(this.#cwd, queryTrim);
497
- in_rdir = queryTrim;
498
- language = getLanguageFromFilePath(queryTrim);
499
- }
500
- if (stat.type === 'directory') {
501
- in_content = 'FOLDER';
502
- in_dir = path$1.resolve(this.#cwd, queryTrim);
503
- in_rdir = queryTrim;
504
- }
505
- } catch (e) {
506
- this.logger.error('解析query中的路径失败: ' + e.message);
507
- }
508
- }
509
- // 优先级3: 选中代码
510
- if (!in_content && selectedCode) {
511
- in_content = selectedCode;
512
- use_paconvert = false;
513
- }
514
- // 优先级4: 当前文件
515
- if (!in_content && activeFilePath) {
516
- in_content = activeFileContent;
517
- in_dir = path$1.resolve(this.#cwd, activeFilePath);
518
- }
519
- // 无任何输入,报错
520
- if (!in_content) {
521
- this.logger.error('未检测到待转换的代码!');
522
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
523
- children: '未检测到待转换的代码,您可通过以下方式指定:\n1. 直接回车则转换当前文件\n2. 使用 # 选择文件或目录\n3. 直接输入相对路径\n4. 框选代码\n\n'
524
- }));
525
- return;
526
- }
527
- if (in_content.includes('tensorflow') || in_content.includes('keras')) {
528
- use_paconvert = false;
529
- }
530
- if (!fs) {
531
- use_paconvert = false;
532
- }
533
- // Python环境检查
534
- if (use_paconvert) {
535
- try {
536
- await exec('python3 --version');
537
- } catch (e) {
538
- try {
539
- await exec('python --version');
540
- } catch (e) {
541
- this.logger.error(`未检测到Python解释器: ${e.message}`);
542
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
543
- children: '未检测到Python解释器,建议安装3.8版本及以上的Python,安装后可支持Pytorch项目整个目录的 **批量/长文本转换**,转换速度更快、准确率更高,一键迁移到飞桨框架。'
544
- }));
545
- use_paconvert = false;
546
- }
547
- }
548
- }
549
- // PaConvert环境检查
550
- if (use_paconvert) {
551
- // 检测是否安装了paconvert
552
- try {
553
- await exec('paconvert -h');
554
- } catch (e) {
555
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
556
- children: '正在配置环境中,请稍等...\n\n'
557
- }));
558
- const paconvertWhl = path$1.join(this.#pluginDir, 'assets', 'paconvert-3.0.1-py3-none-any.whl');
559
- try {
560
- await exec(`python3 -m pip install -U ${paconvertWhl}`);
561
- await exec(`paconvert -h`);
562
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
563
- children: '配置成功,开始转换...\n\n'
564
- }));
565
- } catch (e) {
566
- try {
567
- await exec(`python -m pip install -U ${paconvertWhl}`);
568
- await exec(`paconvert -h`);
569
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
570
- children: '配置成功,开始转换...\n\n'
571
- }));
572
- } catch (e) {
573
- this.logger.error(`paconvert安装失败: ${e.message}`);
574
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
575
- children: '未成功安装飞桨代码转换工具paconvert,安装后可支持Pytorch项目整个目录的 **批量/长文本转换**,转换速度更快、准确率更高,一键迁移到飞桨框架。推荐安装:\n\n'
576
- }));
577
- yield stream.flush(/*#__PURE__*/ jsx("code-block", {
578
- language: "bash",
579
- closed: false,
580
- children: 'pip3 install -U paconvert'
581
- }));
582
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
583
- children: '由于未安装该工具,将使用 **普通转换方式**。\n\n'
584
- }));
585
- use_paconvert = false;
586
- }
587
- }
588
- }
589
- }
590
- if (in_dir) {
591
- if (in_content === 'FOLDER') {
592
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
593
- children: `正在转换整个目录:\`${in_dir}\`,批量转换时间可能较长,请耐心等待...\n\n`
594
- }));
595
- } else {
596
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
597
- children: `正在转换单个文件:\`${in_dir}\`,请稍等...\n\n`
598
- }));
599
- }
600
- } else if (selectedCode) {
601
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
602
- children: '正在转换选中代码...\n\n'
603
- }));
604
- }
605
- // 使用PaConvert转换
606
- if (use_paconvert) {
607
- assert(fs, '文件系统不存在');
608
- const log_file = path$1.resolve(this.#cwd, '.convert.log');
609
- if (in_content === 'FOLDER') {
610
- const out_dir = this.tempDir;
611
- //批量之前删除临时目录里的内容 兼容windows
612
- rmDir(out_dir, this.logger);
613
- //批量之前删除本地的paddle_project
614
- rmDir(path$1.resolve(this.#cwd, 'paddle_project'), this.logger);
615
- try {
616
- // 检查目录合法性
617
- console.log('待转换目录', in_dir);
618
- const in_files = getAllFilesPath(in_dir, this.logger);
619
- console.log('待转换目录中的文件', in_files);
620
- const overSize = ifOverSize(in_files, this.#cwd, this.logger);
621
- if (overSize) {
622
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
623
- children: '选择目录中文件过大,无法进行转换,请减少文件数量,或选择单个文件进行转换。\n\n'
624
- }));
625
- return;
626
- }
627
- // 调用paconvert tool转换
628
- await exec(`paconvert --in_dir ${in_dir} --out_dir ${out_dir} --log_dir ${log_file} --exc_patterns ${out_dir} --log_level WARNING --log_markdown`);
629
- // 展示转换结果
630
- const out_files = getAllFilesPath(this.tempDir, this.logger);
631
- console.log('目录转换文件', out_files);
632
- const out_content = readFiles(out_files, this.#cwd, this.logger);
633
- console.log('目录转换文件内容', out_content);
634
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("p", {
635
- children: [
636
- /*#__PURE__*/ jsx("ul", {
637
- children: out_files.map((item)=>/*#__PURE__*/ jsx("li", {
638
- children: /*#__PURE__*/ jsx("p", {
639
- children: item.replace(this.tempDir, '')
640
- })
641
- }))
642
- }),
643
- /*#__PURE__*/ jsx("flex", {
644
- inline: true,
645
- verticalStartAlign: true,
646
- children: /*#__PURE__*/ jsx("command-button", {
647
- commandName: "commitMessage:confirmIssue",
648
- variant: "text",
649
- action: "acceptDir",
650
- actionData: {
651
- includeHiddenStatsCode: true,
652
- newText: out_content.join('\n'),
653
- from: this.tempDir,
654
- to: path$1.join(this.#cwd, 'paddle_project')
655
- },
656
- propagation: true,
657
- data: {
658
- files: out_files,
659
- from: this.tempDir,
660
- to: path$1.join(this.#cwd, 'paddle_project')
661
- },
662
- tooltipText: "批量采纳",
663
- children: "批量采纳"
664
- })
665
- }),
666
- /*#__PURE__*/ jsx("markdown", {
667
- children: `点击 **批量采纳** 可以将所有文件写入目录\`${path$1.join(this.#cwd, 'paddle_project')}\`中。\n\n\n`
668
- })
669
- ]
670
- }));
671
- } catch (e) {
672
- this.logger.error(`paconvert转换目录${in_dir}失败,失败原因:${e.message}`);
673
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
674
- children: `转换失败,失败原因:\n\`\`\`\n${e.message}\n\`\`\`\n\n您可尝试选择单个文件进行转换。\n\n`
675
- }));
676
- return;
677
- }
678
- } else {
679
- const fileName = path$1.basename(in_dir);
680
- const out_dir = path$1.resolve(this.tempDir, fileName);
681
- try {
682
- // 检查文件合法性
683
- if (in_content.length > 1000000) {
684
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
685
- children: '文本代码长度超过限制,请减少文本代码长度,或框选代码进行转换。\n\n'
686
- }));
687
- return;
688
- }
689
- // 调用paconvert tool转换
690
- await exec(`paconvert --in_dir ${in_dir} --out_dir ${out_dir} --log_dir ${log_file} --log_level WARNING --log_markdown`);
691
- // 展示转换结果
692
- const out_content = readFile(out_dir, this.logger);
693
- console.log('单文件转换结果', out_content);
694
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("code-block", {
695
- language: language,
696
- closed: false,
697
- children: `${out_content}`
698
- }));
699
- exec(`rm -rf ${out_dir}`).then(()=>{
700
- this.logger.info(`转换结果临时保存文件 ${out_dir} 删除成功`);
701
- }).catch(()=>{
702
- this.logger.error(`转换结果临时保存文件 ${out_dir} 删除失败`);
703
- });
704
- } catch (e) {
705
- this.logger.error(`paconvert转换单文件${in_dir}失败,失败原因:${e.message}`);
706
- use_paconvert = false;
707
- if (in_content.length > 200000) {
708
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
709
- children: '待转换的代码长度超过限制,请减少代码量。\n\n'
710
- }));
711
- return;
712
- }
713
- }
714
- }
715
- // 打印转换日志,如果改为使用大模型,则不打印
716
- if (use_paconvert) {
717
- try {
718
- const log_content = await fs.readFile('.convert.log', 'utf8');
719
- yield stream.flush(/*#__PURE__*/ jsx("markdown", {
720
- children: `\n\n${log_content}\n`
721
- }));
722
- exec(`rm -rf ${log_file}`).then(()=>{
723
- this.logger.info(`转换的日志 ${log_file} 删除成功`);
724
- }).catch(()=>{
725
- this.logger.error(`转换的日志 ${log_file} 删除失败`);
726
- });
727
- } catch (e) {
728
- this.logger.error('paconvert转换日志文件读取失败: ', e.message);
729
- }
730
- return;
731
- }
732
- }
733
- // 大模型转换
734
- if (!use_paconvert) {
735
- this.logger.info('paddle代码转换耗时统计', {
736
- message: `paconvert无法转换,使用大模型转换 ${Date.now()}`
737
- });
738
- if (in_content == 'FOLDER') {
739
- // 无法支持,报错
740
- this.logger.error('转换整个目录时,仅能使用paconvert转换,需修复paconvert环境问题');
741
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
742
- children: '**大模型转换方式** 不支持整个目录批量转换,请安装飞桨代码转换工具paconvert以支持 **批量转换**,或者选择单个文件进行转换。\n\n'
743
- }));
744
- yield stream.flush(/*#__PURE__*/ jsx("code-block", {
745
- language: "bash",
746
- closed: false,
747
- children: 'pip3 install -U paconvert'
748
- }));
749
- return;
750
- }
751
- this.logger.info('paddle代码转换耗时统计', {
752
- message: `开始执行知识集检索 ${Date.now()}`
753
- });
754
- let start = Date.now();
755
- const knowledge = await this.retriever.knowledgeFromQuery(in_content, {
756
- knowledgeSets: [
757
- // 飞桨API接口映射文档集
758
- {
759
- uuid: 'a53c6ee5-3bcf-46cd-80b7-103c6d028389',
760
- type: 'NORMAL'
761
- }
762
- ],
763
- queryRewrite: false
764
- });
765
- this.logger.info('paddled代码转换耗时统计', {
766
- message: `知识集检索结束,耗时${Date.now() - start}ms`
767
- });
768
- start = Date.now();
769
- const trim_knowledge = knowledge;
770
- const trim_code = [
771
- ''
772
- ];
773
- const prompt = this.llm.createPrompt(codeConvertPromptTemplate, {
774
- trim_knowledge,
775
- trim_code,
776
- language,
777
- in_content
778
- });
779
- const chunks = this.llm.askForTextStreaming(prompt, {
780
- model: TextModel.ErnieBot128,
781
- modelOptions: {
782
- temperature: 0.1,
783
- topP: 0.8,
784
- penaltyScore: 1.0,
785
- enableMultiturnDialogue: false
786
- }
787
- });
788
- let res = '';
789
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
790
- children: ''
791
- }));
792
- for await (const chunk of chunks){
793
- res += chunk;
794
- yield stream.flushReplaceLast(/*#__PURE__*/ jsx("markdown", {
795
- children: res
796
- }));
797
- }
798
- this.logger.info('paddled代码转换耗时统计', {
799
- message: `llm调用结束,耗时${Date.now() - start}ms`
800
- });
801
- }
802
- }
803
- }
804
-
805
- var codeExplainPromptTemplate = "你是一位对飞桨框架(PaddlePaddle)及深度学习领域的代码有深入研究的编程高手。你的职责是对给定的代码进行解释,在解释代码前,你会收到多个背景信息供参考。\n* 在提供的背景信息中,将通过『##』标注信息的类型。例如:`## 编程语言`表示代码的语言类型,`## 当前文件`表示代码的文件名,`## 参考文档片段`表示引用特定的文档内容。\n\n# 背景信息\n## 编程语言\n{{activeFileLanguage}}\n\n## 当前文件\n{{activeFilePath}}\n\n## 参考文档片段\n{{trim_knowledge}}\n\n# 回答要求\n1. 请参考背景信息来解释代码,但要注意背景信息与代码并非总是准确相关的。你需要识别这些信息的相关性,对于无关信息请直接忽略。\n2. 在解释代码过程中,请避免提及你参考了背景信息,因为这些信息对提问者而言是不可知的。你的解释应直接针对代码本身,而无需透露背后的信息来源。\n3. 请直接、明确、简洁地解释代码,避免重复打印代码本身。\n4. 若代码中涉及了其他深度学习框架(例如Pytorch、torch、torchaudio、torchvision、torchtune、torcharrow、Tensorflow、Keras、CNTK、MXNet、MindSpore、OneFlow等),注意引导提问者使用飞桨框架,直接提示:推荐调用 @飞桨/代码转换,支持将其他深度学习框架的代码(如Pytorch、Tensorflow、Keras、MXNet、MindSpore等),转换为飞桨的代码,支持项目快速一键迁移。\n\n# 待解释代码\n{{selectedCode}}";
806
-
807
- class CodeExplainSkillProvider extends SkillProvider {
808
- static{
809
- this.skillName = 'code-explain';
810
- }
811
- static{
812
- this.displayName = '飞桨代码解释';
813
- }
814
- static{
815
- this.description = '解释深度学习与飞桨框架的代码';
816
- }
817
- static{
818
- this.parameters = {
819
- type: 'object',
820
- properties: {}
821
- };
822
- }
823
- async *execute() {
824
- this.logger.info('paddle代码解释耗时统计', {
825
- message: `开始执行代码解释 ${performance.now()}`
826
- });
827
- const { activeFilePath, activeFileLanguage, query, selectedCode } = this.currentContext;
828
- const stream = new StringChunkStream();
829
- if (query) {
830
- yield stream.flush('无需输入,请直接框选要解释的代码');
831
- return;
832
- }
833
- if (!selectedCode) {
834
- yield stream.flush('未选中代码,请框选要解释的代码');
835
- return;
836
- }
837
- yield stream.flush('正在思考中,请耐心等候...');
838
- this.logger.info('paddle代码解释耗时统计', {
839
- message: `开始执行知识集检索 ${performance.now()}`
840
- });
841
- let start = performance.now();
842
- const knowledge = await this.retriever.knowledgeFromQuery(selectedCode, {
843
- knowledgeSets: [
844
- // 飞桨API接口文档集
845
- {
846
- uuid: '564a9ebb-a3b1-4d5b-ad28-27c0ab6d78fe',
847
- type: 'NORMAL'
848
- },
849
- // 飞桨框架与生态文档集
850
- {
851
- uuid: '7ece94ce-e39a-414e-8ca5-d80ed4cf300b',
852
- type: 'NORMAL'
853
- }
854
- ],
855
- queryRewrite: false
856
- });
857
- this.logger.info('paddle代码解释耗时统计', {
858
- message: `知识集检索结束,耗时${performance.now() - start}ms`
859
- });
860
- start = performance.now();
861
- const trim_knowledge = knowledge;
862
- const prompt = this.llm.createPrompt(codeExplainPromptTemplate, {
863
- activeFileLanguage,
864
- activeFilePath,
865
- trim_knowledge,
866
- selectedCode
867
- });
868
- const chunks = this.llm.askForTextStreaming(prompt, {
869
- model: TextModel.ErnieBot128,
870
- modelOptions: {
871
- temperature: 0.3,
872
- topP: 0.8,
873
- penaltyScore: 1.0,
874
- enableMultiturnDialogue: false
875
- }
876
- });
877
- yield stream.flushReplaceLast('');
878
- for await (const chunk of chunks){
879
- yield stream.flush(chunk);
880
- }
881
- this.logger.info('paddle代码解释耗时统计', {
882
- message: `llm调用结束,耗时${performance.now() - start}ms`
883
- });
884
- }
885
- }
886
-
887
- class CustomFallbackProvider extends FallbackProvider {
888
- static{
889
- this.description = '智能解答深度学习与飞桨框架的问题';
890
- }
891
- async *handleQuery() {
892
- try {
893
- this.logger.info('paddle智能问答耗时统计', {
894
- message: `开始执行智能问答 ${performance.now()}`
895
- });
896
- const { activeFilePath, selectedCode, activeFileLanguage, query } = this.currentContext;
897
- const stream = new StringChunkStream();
898
- yield stream.flush('正在思考中,请耐心等候...');
899
- const queryWithCode = selectedCode.trim() ? `${query}\n\`\`\`${activeFileLanguage}\n${selectedCode}\n\`\`\`` : query;
900
- this.logger.info('paddle智能问答耗时统计', {
901
- message: `开始执行知识集检索 ${performance.now()}`
902
- });
903
- let start = performance.now();
904
- const [knowledge1, knowledge2] = await Promise.all([
905
- this.retriever.knowledgeFromQuery(queryWithCode, {
906
- knowledgeSets: [
907
- // 飞桨API接口文档集
908
- {
909
- uuid: '564a9ebb-a3b1-4d5b-ad28-27c0ab6d78fe',
910
- type: 'NORMAL'
911
- }
912
- ],
913
- queryRewrite: true,
914
- topK: 7
915
- }),
916
- this.retriever.knowledgeFromQuery(queryWithCode, {
917
- knowledgeSets: [
918
- // 飞桨框架与生态文档集
919
- {
920
- uuid: '7ece94ce-e39a-414e-8ca5-d80ed4cf300b',
921
- type: 'NORMAL'
922
- }
923
- ],
924
- queryRewrite: true,
925
- topK: 8
926
- })
927
- ]);
928
- this.logger.info('paddle智能问答耗时统计', {
929
- message: `知识集检索结束,耗时${performance.now() - start}ms`
930
- });
931
- start = performance.now();
932
- const trim_knowledge = [
933
- ...knowledge1,
934
- ...knowledge2
935
- ];
936
- const trim_code = [
937
- ''
938
- ];
939
- const prompt = this.llm.createPrompt(chatPromptTemplate, {
940
- activeFilePath,
941
- trim_knowledge,
942
- trim_code,
943
- queryWithCode
944
- });
945
- const chunks = this.llm.askForTextStreaming(prompt, {
946
- model: TextModel.ErnieBot128,
947
- modelOptions: {
948
- temperature: 0.3,
949
- topP: 0.8,
950
- penaltyScore: 1.0,
951
- enableMultiturnDialogue: {
952
- byPlugin: true,
953
- onlyQuery: query
954
- }
955
- }
956
- });
957
- // ****************** 调试代码,调试时再打开 *************** /
958
- /*
959
- yield stream.flush('\n\n---\n\n');
960
-
961
- yield stream.flush(`\n\n共检索到${trim_knowledge.length}条知识:\n\n`);
962
- yield stream.flush('---\n\n');
963
- const state = {
964
- text_length: 0,
965
- code_length: 0,
966
- };
967
- for (const text of trim_knowledge) {
968
- yield stream.flush(text.split('\n').map(v => '> ' + v).join('\n'));
969
- yield stream.flush('\n\n---\n\n');
970
- state.text_length += text.length;
971
- }
972
- yield stream.flush(`文本总字符长度: ${state.text_length}\n\n`);
973
- yield stream.flush('---\n\n');
974
-
975
- yield stream.flush(`\n\n共检索到${trim_code.length}条代码:\n\n`);
976
- yield stream.flush('---\n\n');
977
- for (const text of trim_code) {
978
- yield stream.flush(text.split('\n').map(v => '> ' + v).join('\n'));
979
- yield stream.flush('\n\n---\n\n');
980
- state.code_length += text.length;
981
- }
982
- yield stream.flush(`代码总字符长度: ${state.code_length}\n\n`);
983
- yield stream.flush('---\n\n');
984
-
985
- yield stream.flush('\n\n以下为 queryWithCode:\n\n');
986
- yield stream.flush(`${queryWithCode}`);
987
- yield stream.flush('\n\n---');
988
- */ // ************************************************************ /
989
- yield stream.flushReplaceLast('');
990
- for await (const chunk of chunks){
991
- yield stream.flush(chunk);
992
- }
993
- this.logger.info('paddle智能问答耗时统计', {
994
- message: `llm调用结束,耗时${performance.now() - start}ms`
995
- });
996
- } catch (ex) {
997
- console.error(ex);
998
- }
999
- }
1000
- }
1001
-
1002
- function setup({ registry }) {
1003
- registry.registerSkillProvider('paddle-help', HelpSkillProvider);
1004
- registry.registerSkillProvider('code-generate', CodeGenerateSkillProvider);
1005
- registry.registerSkillProvider('code-convert', CodeConvertSkillProvider);
1006
- registry.registerSkillProvider('code-explain', CodeExplainSkillProvider);
1007
- registry.registerSkillProvider('chat', ChatSkillProvider);
1008
- registry.registerFallbackProvider('fallback', CustomFallbackProvider, true);
1009
- }
1010
-
1011
- export { setup };