@opensumi/ide-ai-native 2.26.9-rc-1695091570.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.
Files changed (196) hide show
  1. package/LICENSE +21 -0
  2. package/lib/browser/ai-chat.contribution.d.ts +26 -0
  3. package/lib/browser/ai-chat.contribution.d.ts.map +1 -0
  4. package/lib/browser/ai-chat.contribution.js +227 -0
  5. package/lib/browser/ai-chat.contribution.js.map +1 -0
  6. package/lib/browser/ai-chat.module.less +174 -0
  7. package/lib/browser/ai-chat.service.d.ts +30 -0
  8. package/lib/browser/ai-chat.service.d.ts.map +1 -0
  9. package/lib/browser/ai-chat.service.js +134 -0
  10. package/lib/browser/ai-chat.service.js.map +1 -0
  11. package/lib/browser/ai-chat.view.d.ts +4 -0
  12. package/lib/browser/ai-chat.view.d.ts.map +1 -0
  13. package/lib/browser/ai-chat.view.js +305 -0
  14. package/lib/browser/ai-chat.view.js.map +1 -0
  15. package/lib/browser/ai-editor.contribution.d.ts +24 -0
  16. package/lib/browser/ai-editor.contribution.d.ts.map +1 -0
  17. package/lib/browser/ai-editor.contribution.js +419 -0
  18. package/lib/browser/ai-editor.contribution.js.map +1 -0
  19. package/lib/browser/ai-project/generate.service.d.ts +31 -0
  20. package/lib/browser/ai-project/generate.service.d.ts.map +1 -0
  21. package/lib/browser/ai-project/generate.service.js +453 -0
  22. package/lib/browser/ai-project/generate.service.js.map +1 -0
  23. package/lib/browser/ai-sumi/sumi.service.d.ts +11 -0
  24. package/lib/browser/ai-sumi/sumi.service.d.ts.map +1 -0
  25. package/lib/browser/ai-sumi/sumi.service.js +64 -0
  26. package/lib/browser/ai-sumi/sumi.service.js.map +1 -0
  27. package/lib/browser/code-widget/ai-code-document.provider.d.ts +10 -0
  28. package/lib/browser/code-widget/ai-code-document.provider.d.ts.map +1 -0
  29. package/lib/browser/code-widget/ai-code-document.provider.js +26 -0
  30. package/lib/browser/code-widget/ai-code-document.provider.js.map +1 -0
  31. package/lib/browser/code-widget/ai-code-widget.d.ts +20 -0
  32. package/lib/browser/code-widget/ai-code-widget.d.ts.map +1 -0
  33. package/lib/browser/code-widget/ai-code-widget.js +164 -0
  34. package/lib/browser/code-widget/ai-code-widget.js.map +1 -0
  35. package/lib/browser/components/AIImprove.d.ts +9 -0
  36. package/lib/browser/components/AIImprove.d.ts.map +1 -0
  37. package/lib/browser/components/AIImprove.js +34 -0
  38. package/lib/browser/components/AIImprove.js.map +1 -0
  39. package/lib/browser/components/AIInput.d.ts +5 -0
  40. package/lib/browser/components/AIInput.d.ts.map +1 -0
  41. package/lib/browser/components/AIInput.js +21 -0
  42. package/lib/browser/components/AIInput.js.map +1 -0
  43. package/lib/browser/components/ChatEditor.d.ts +5 -0
  44. package/lib/browser/components/ChatEditor.d.ts.map +1 -0
  45. package/lib/browser/components/ChatEditor.js +85 -0
  46. package/lib/browser/components/ChatEditor.js.map +1 -0
  47. package/lib/browser/components/ChatInput.d.ts +6 -0
  48. package/lib/browser/components/ChatInput.d.ts.map +1 -0
  49. package/lib/browser/components/ChatInput.js +127 -0
  50. package/lib/browser/components/ChatInput.js.map +1 -0
  51. package/lib/browser/components/ChatMoreActions.d.ts +5 -0
  52. package/lib/browser/components/ChatMoreActions.d.ts.map +1 -0
  53. package/lib/browser/components/ChatMoreActions.js +26 -0
  54. package/lib/browser/components/ChatMoreActions.js.map +1 -0
  55. package/lib/browser/components/Thinking.d.ts +3 -0
  56. package/lib/browser/components/Thinking.d.ts.map +1 -0
  57. package/lib/browser/components/Thinking.js +19 -0
  58. package/lib/browser/components/Thinking.js.map +1 -0
  59. package/lib/browser/components/components.module.less +259 -0
  60. package/lib/browser/components/lineVertical.d.ts +4 -0
  61. package/lib/browser/components/lineVertical.d.ts.map +1 -0
  62. package/lib/browser/components/lineVertical.js +22 -0
  63. package/lib/browser/components/lineVertical.js.map +1 -0
  64. package/lib/browser/content-widget/ai-content-widget.d.ts +38 -0
  65. package/lib/browser/content-widget/ai-content-widget.d.ts.map +1 -0
  66. package/lib/browser/content-widget/ai-content-widget.js +97 -0
  67. package/lib/browser/content-widget/ai-content-widget.js.map +1 -0
  68. package/lib/browser/content-widget/ai-inline-chat-panel.d.ts +6 -0
  69. package/lib/browser/content-widget/ai-inline-chat-panel.d.ts.map +1 -0
  70. package/lib/browser/content-widget/ai-inline-chat-panel.js +108 -0
  71. package/lib/browser/content-widget/ai-inline-chat-panel.js.map +1 -0
  72. package/lib/browser/content-widget/ai-inline-chat.module.less +74 -0
  73. package/lib/browser/content-widget/ai-inline-chat.service.d.ts +23 -0
  74. package/lib/browser/content-widget/ai-inline-chat.service.d.ts.map +1 -0
  75. package/lib/browser/content-widget/ai-inline-chat.service.js +47 -0
  76. package/lib/browser/content-widget/ai-inline-chat.service.js.map +1 -0
  77. package/lib/browser/diff-widget/ai-diff-document.provider.d.ts +10 -0
  78. package/lib/browser/diff-widget/ai-diff-document.provider.d.ts.map +1 -0
  79. package/lib/browser/diff-widget/ai-diff-document.provider.js +26 -0
  80. package/lib/browser/diff-widget/ai-diff-document.provider.js.map +1 -0
  81. package/lib/browser/diff-widget/ai-diff-widget.d.ts +20 -0
  82. package/lib/browser/diff-widget/ai-diff-widget.d.ts.map +1 -0
  83. package/lib/browser/diff-widget/ai-diff-widget.js +158 -0
  84. package/lib/browser/diff-widget/ai-diff-widget.js.map +1 -0
  85. package/lib/browser/index.d.ts +12 -0
  86. package/lib/browser/index.d.ts.map +1 -0
  87. package/lib/browser/index.js +84 -0
  88. package/lib/browser/index.js.map +1 -0
  89. package/lib/browser/inline-completions/constants.d.ts +62 -0
  90. package/lib/browser/inline-completions/constants.d.ts.map +1 -0
  91. package/lib/browser/inline-completions/constants.js +69 -0
  92. package/lib/browser/inline-completions/constants.js.map +1 -0
  93. package/lib/browser/inline-completions/provider.d.ts +27 -0
  94. package/lib/browser/inline-completions/provider.d.ts.map +1 -0
  95. package/lib/browser/inline-completions/provider.js +63 -0
  96. package/lib/browser/inline-completions/provider.js.map +1 -0
  97. package/lib/browser/override/ai-editor-tab.service.d.ts +6 -0
  98. package/lib/browser/override/ai-editor-tab.service.d.ts.map +1 -0
  99. package/lib/browser/override/ai-editor-tab.service.js +22 -0
  100. package/lib/browser/override/ai-editor-tab.service.js.map +1 -0
  101. package/lib/browser/override/ai-marker.service.d.ts +11 -0
  102. package/lib/browser/override/ai-marker.service.d.ts.map +1 -0
  103. package/lib/browser/override/ai-marker.service.js +55 -0
  104. package/lib/browser/override/ai-marker.service.js.map +1 -0
  105. package/lib/browser/override/global.styles.less +268 -0
  106. package/lib/browser/override/layout/layout-config.d.ts +6 -0
  107. package/lib/browser/override/layout/layout-config.d.ts.map +1 -0
  108. package/lib/browser/override/layout/layout-config.js +17 -0
  109. package/lib/browser/override/layout/layout-config.js.map +1 -0
  110. package/lib/browser/override/layout/layout.module.less +7 -0
  111. package/lib/browser/override/layout/main-slot-renderer.d.ts +4 -0
  112. package/lib/browser/override/layout/main-slot-renderer.d.ts.map +1 -0
  113. package/lib/browser/override/layout/main-slot-renderer.js +22 -0
  114. package/lib/browser/override/layout/main-slot-renderer.js.map +1 -0
  115. package/lib/browser/override/layout/menu-bar/menu-bar.contribution.d.ts +8 -0
  116. package/lib/browser/override/layout/menu-bar/menu-bar.contribution.d.ts.map +1 -0
  117. package/lib/browser/override/layout/menu-bar/menu-bar.contribution.js +32 -0
  118. package/lib/browser/override/layout/menu-bar/menu-bar.contribution.js.map +1 -0
  119. package/lib/browser/override/layout/menu-bar/menu-bar.module.less +41 -0
  120. package/lib/browser/override/layout/menu-bar/menu-bar.view.d.ts +3 -0
  121. package/lib/browser/override/layout/menu-bar/menu-bar.view.d.ts.map +1 -0
  122. package/lib/browser/override/layout/menu-bar/menu-bar.view.js +62 -0
  123. package/lib/browser/override/layout/menu-bar/menu-bar.view.js.map +1 -0
  124. package/lib/browser/override/layout/tabbar.view.d.ts +17 -0
  125. package/lib/browser/override/layout/tabbar.view.d.ts.map +1 -0
  126. package/lib/browser/override/layout/tabbar.view.js +38 -0
  127. package/lib/browser/override/layout/tabbar.view.js.map +1 -0
  128. package/lib/browser/override/override.module.less +32 -0
  129. package/lib/browser/override/theme/default-theme.d.ts +315 -0
  130. package/lib/browser/override/theme/default-theme.d.ts.map +1 -0
  131. package/lib/browser/override/theme/default-theme.js +821 -0
  132. package/lib/browser/override/theme/default-theme.js.map +1 -0
  133. package/lib/browser/run/run.service.d.ts +52 -0
  134. package/lib/browser/run/run.service.d.ts.map +1 -0
  135. package/lib/browser/run/run.service.js +176 -0
  136. package/lib/browser/run/run.service.js.map +1 -0
  137. package/lib/common/command.d.ts +17 -0
  138. package/lib/common/command.d.ts.map +1 -0
  139. package/lib/common/command.js +21 -0
  140. package/lib/common/command.js.map +1 -0
  141. package/lib/common/index.d.ts +37 -0
  142. package/lib/common/index.d.ts.map +1 -0
  143. package/lib/common/index.js +22 -0
  144. package/lib/common/index.js.map +1 -0
  145. package/lib/index.d.ts +2 -0
  146. package/lib/index.d.ts.map +1 -0
  147. package/lib/index.js +5 -0
  148. package/lib/index.js.map +1 -0
  149. package/lib/node/index.d.ts +10 -0
  150. package/lib/node/index.d.ts.map +1 -0
  151. package/lib/node/index.js +32 -0
  152. package/lib/node/index.js.map +1 -0
  153. package/package.json +38 -0
  154. package/src/browser/ai-chat.contribution.ts +294 -0
  155. package/src/browser/ai-chat.module.less +174 -0
  156. package/src/browser/ai-chat.service.ts +152 -0
  157. package/src/browser/ai-chat.view.tsx +421 -0
  158. package/src/browser/ai-editor.contribution.ts +521 -0
  159. package/src/browser/ai-project/generate.service.ts +505 -0
  160. package/src/browser/ai-sumi/sumi.service.ts +65 -0
  161. package/src/browser/code-widget/ai-code-document.provider.ts +22 -0
  162. package/src/browser/code-widget/ai-code-widget.tsx +202 -0
  163. package/src/browser/components/AIImprove.tsx +45 -0
  164. package/src/browser/components/AIInput.tsx +30 -0
  165. package/src/browser/components/ChatEditor.tsx +129 -0
  166. package/src/browser/components/ChatInput.tsx +197 -0
  167. package/src/browser/components/ChatMoreActions.tsx +33 -0
  168. package/src/browser/components/Thinking.tsx +23 -0
  169. package/src/browser/components/components.module.less +259 -0
  170. package/src/browser/components/lineVertical.tsx +19 -0
  171. package/src/browser/content-widget/ai-content-widget.tsx +132 -0
  172. package/src/browser/content-widget/ai-inline-chat-panel.tsx +154 -0
  173. package/src/browser/content-widget/ai-inline-chat.module.less +74 -0
  174. package/src/browser/content-widget/ai-inline-chat.service.ts +46 -0
  175. package/src/browser/diff-widget/ai-diff-document.provider.ts +22 -0
  176. package/src/browser/diff-widget/ai-diff-widget.tsx +196 -0
  177. package/src/browser/index.ts +91 -0
  178. package/src/browser/inline-completions/constants.ts +108 -0
  179. package/src/browser/inline-completions/provider.ts +55 -0
  180. package/src/browser/override/ai-editor-tab.service.tsx +22 -0
  181. package/src/browser/override/ai-marker.service.tsx +55 -0
  182. package/src/browser/override/global.styles.less +268 -0
  183. package/src/browser/override/layout/layout-config.ts +21 -0
  184. package/src/browser/override/layout/layout.module.less +7 -0
  185. package/src/browser/override/layout/main-slot-renderer.tsx +62 -0
  186. package/src/browser/override/layout/menu-bar/menu-bar.contribution.tsx +28 -0
  187. package/src/browser/override/layout/menu-bar/menu-bar.module.less +41 -0
  188. package/src/browser/override/layout/menu-bar/menu-bar.view.tsx +92 -0
  189. package/src/browser/override/layout/tabbar.view.tsx +99 -0
  190. package/src/browser/override/override.module.less +32 -0
  191. package/src/browser/override/theme/default-theme.ts +818 -0
  192. package/src/browser/run/run.service.ts +183 -0
  193. package/src/common/command.ts +21 -0
  194. package/src/common/index.ts +39 -0
  195. package/src/index.ts +1 -0
  196. package/src/node/index.ts +24 -0
@@ -0,0 +1,421 @@
1
+ /* eslint-disable no-console */
2
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
3
+ import * as React from 'react';
4
+ // @ts-ignore
5
+ import { MessageList, SystemMessage, Avatar } from 'react-chat-elements';
6
+
7
+ import { Markdown } from '@opensumi/ide-components/lib/markdown/index';
8
+ import { useInjectable, getIcon, AppConfig } from '@opensumi/ide-core-browser';
9
+ import { Button, Icon, Popover } from '@opensumi/ide-core-browser/lib/components';
10
+ import { LAYOUT_VIEW_SIZE } from '@opensumi/ide-core-browser/lib/layout/constants';
11
+ import { CommandOpener } from '@opensumi/ide-core-browser/lib/opener/command-opener';
12
+ import { URI, Command, isMacintosh } from '@opensumi/ide-core-common';
13
+
14
+ import 'react-chat-elements/dist/main.css';
15
+ import { DebugConfiguration } from '@opensumi/ide-debug';
16
+
17
+ import { AiGPTBackSerivcePath, AISerivceType } from '../common';
18
+
19
+ import * as styles from './ai-chat.module.less';
20
+ import { AiChatService, IChatMessageStructure } from './ai-chat.service';
21
+ import { AiProjectGenerateService, Requirements } from './ai-project/generate.service';
22
+ import { AiSumiService } from './ai-sumi/sumi.service';
23
+ import { CodeBlockWrapper } from './components/ChatEditor';
24
+ import { ChatInput } from './components/ChatInput';
25
+ import { ChatMoreActions } from './components/ChatMoreActions';
26
+ import { LineVertical } from './components/lineVertical';
27
+ import { Thinking } from './components/Thinking';
28
+ import { AiRunService } from './run/run.service';
29
+
30
+ const AI_AVATAR = 'https://mdn.alipayobjects.com/huamei_htww6h/afts/img/A*wv3HTok2c58AAAAAAAAAAAAADhl8AQ/original';
31
+
32
+ const createMessage = (position: string, title: string, text: string | React.ReactNode) => ({
33
+ position,
34
+ type: 'text',
35
+ title,
36
+ text,
37
+ className: position === 'left' ? 'rce-ai-msg' : 'rce-user-msg',
38
+ });
39
+
40
+ const createMessageByAI = (text: string | React.ReactNode) => createMessage('left', '', text);
41
+
42
+ const AI_NAME = 'AI 研发助手';
43
+ const ME_NAME = '';
44
+
45
+ export const AiChatView = () => {
46
+ const aiChatService = useInjectable<AiChatService>(AiChatService);
47
+ const aiProjectGenerateService = useInjectable<AiProjectGenerateService>(AiProjectGenerateService);
48
+ const aiSumiService = useInjectable<AiSumiService>(AiSumiService);
49
+ const aiGPTBackService = useInjectable<any>(AiGPTBackSerivcePath);
50
+ const aiRunService = useInjectable<AiRunService>(AiRunService);
51
+ const opener = useInjectable<CommandOpener>(CommandOpener);
52
+ const appConfig = useInjectable<AppConfig>(AppConfig);
53
+ const containerRef = React.useRef<HTMLDivElement>(null);
54
+
55
+ const [messageListData, setMessageListData] = React.useState<any[]>([]);
56
+ const [loading, setLoading] = React.useState(false);
57
+
58
+ const [, updateState] = React.useState<any>();
59
+
60
+ const aiGenerateInfo: Requirements =
61
+ localStorage.getItem('ai-generate') && JSON.parse(localStorage.getItem('ai-generate')!);
62
+
63
+ const generateProject = React.useCallback(async (messageList) => {
64
+ await aiProjectGenerateService.clearWorkspace();
65
+ const languageReply = `项目语言为:${aiGenerateInfo.language}\n使用框架:${aiGenerateInfo.framework}`;
66
+ messageList.unshift(createMessageByAI(<AiReply text={languageReply} immediately={true} />));
67
+ setMessageListData([...messageList]);
68
+ const filePathList = await aiProjectGenerateService.generateProjectStructure(aiGenerateInfo);
69
+ messageList.splice(
70
+ -1,
71
+ 0,
72
+ createMessageByAI(<AiReply text={`项目结构为:\n${filePathList.join('\n')}`} immediately={true} />),
73
+ );
74
+ setMessageListData([...messageList]);
75
+
76
+ await aiProjectGenerateService.generateFile(filePathList, aiGenerateInfo, (file: string) => {
77
+ messageList.splice(-1, 0, createMessageByAI(<AiReply text={`正在生成文件:${file}`} />));
78
+ setMessageListData([...messageList]);
79
+ });
80
+
81
+ messageList.pop();
82
+ setMessageListData([...messageList]);
83
+ localStorage.removeItem('ai-generate');
84
+ }, []);
85
+
86
+ const InitMsgComponent = () => {
87
+ const lists = [
88
+ // { icon: getIcon('plus'), text: '生成 Java 快排算法' },
89
+ // { icon: getIcon('branches'), text: '提交代码' },
90
+ // { icon: getIcon('open-changes'), text: '创建合并请求' },
91
+ // { icon: getIcon('scm'), text: '触发流水线' },
92
+ ];
93
+
94
+ if (aiGenerateInfo) {
95
+ return (
96
+ <div>
97
+ <span style={{ display: 'block' }}>项目生成中,请稍后....</span>
98
+ </div>
99
+ );
100
+ }
101
+
102
+ return (
103
+ <div>
104
+ <span style={{ display: 'block' }}>嗨,我是您的专属 AI 小助手,我在这里回答有关代码的问题,并帮助您思考!</span>
105
+ <br />
106
+ <span style={{ display: 'block' }}>您可以提问我一些关于代码的问题</span>
107
+ <br />
108
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
109
+ {lists.map((data: any) => (
110
+ <a
111
+ href='javascript:void(0)'
112
+ style={{ marginBottom: '8px' }}
113
+ onClick={() => {
114
+ aiChatService.launchChatMessage({ message: data.text });
115
+ }}
116
+ >
117
+ <Icon className={data.icon} style={{ color: 'inherit', marginRight: '4px' }} />
118
+ <span>{data.text}</span>
119
+ </a>
120
+ ))}
121
+ </div>
122
+ </div>
123
+ );
124
+ };
125
+
126
+ const firstMsg = React.useMemo(() => createMessageByAI(<InitMsgComponent />), [InitMsgComponent]);
127
+
128
+ React.useEffect(() => {
129
+ if (aiGenerateInfo) {
130
+ generateProject([firstMsg]);
131
+ } else if (messageListData && messageListData.length === 0) {
132
+ setMessageListData([firstMsg]);
133
+ }
134
+
135
+ const dispose = aiChatService.onChatMessageLaunch(async (message) => {
136
+ await handleSend(message);
137
+ });
138
+ // aiChatService.removeOldExtension();
139
+ return () => dispose.dispose();
140
+ }, []);
141
+
142
+ const handleSend = React.useCallback(
143
+ async (value: IChatMessageStructure) => {
144
+ const { message, prompt } = value;
145
+
146
+ const preMessagelist = messageListData;
147
+ const preInputValue = message;
148
+
149
+ if (containerRef && containerRef.current) {
150
+ containerRef.current.scrollTop = Number.MAX_SAFE_INTEGER;
151
+ }
152
+
153
+ setLoading(true);
154
+
155
+ preMessagelist.push(createMessage('right', ME_NAME, preInputValue));
156
+ setMessageListData(preMessagelist);
157
+ // 检查前缀 aiSearchKey
158
+ if (typeof preInputValue === 'string') {
159
+ let aiMessage;
160
+
161
+ const userInput = await aiChatService.switchAIService(preInputValue, prompt);
162
+
163
+ if (userInput!.type === AISerivceType.Search || userInput!.type === AISerivceType.SearchCode) {
164
+ aiMessage = await AISearch(userInput, aiGPTBackService);
165
+ } else if (userInput!.type === AISerivceType.Sumi) {
166
+ aiMessage = await aiSumiService.message(userInput!.message!);
167
+
168
+ aiMessage = await AIWithCommandReply(aiMessage, opener);
169
+ } else if (userInput!.type === AISerivceType.GPT) {
170
+ aiMessage = await aiChatService.messageWithGPT(userInput!.message!);
171
+ aiMessage = await AIChatGPTReply(aiMessage);
172
+ } else if (userInput!.type === AISerivceType.Explain) {
173
+ aiMessage = await aiChatService.messageWithGPT(userInput!.message!);
174
+ aiMessage = await AIChatGPTReply(aiMessage);
175
+ } else if (userInput!.type === AISerivceType.Run) {
176
+ aiMessage = await aiChatService.aiBackService.aiAntGlm(userInput!.message!);
177
+ aiMessage = await AIChatRunReply(aiMessage.data, aiRunService);
178
+ }
179
+
180
+ if (aiMessage) {
181
+ preMessagelist.push(aiMessage);
182
+ setMessageListData(preMessagelist);
183
+ updateState({});
184
+ if (containerRef && containerRef.current) {
185
+ containerRef.current.scrollTop = Number.MAX_SAFE_INTEGER;
186
+ }
187
+ }
188
+
189
+ setLoading(false);
190
+
191
+ return;
192
+ }
193
+ },
194
+ [messageListData, containerRef],
195
+ );
196
+
197
+ const layoutViewSize = React.useMemo(() => {
198
+ return appConfig.layoutViewSize || LAYOUT_VIEW_SIZE;
199
+ }, [appConfig])
200
+
201
+ const viewHeight = React.useMemo(
202
+ () => `calc(100vh - ${layoutViewSize.MENUBAR_HEIGHT + layoutViewSize.STATUSBAR_HEIGHT}px)`,
203
+ [],
204
+ );
205
+
206
+ return (
207
+ <div className={styles.ai_chat_view} style={{ height: viewHeight }}>
208
+ <div className={styles.header_container}>
209
+ <div className={styles.left}>
210
+ <div className={styles.ai_avatar_icon}>
211
+ <Avatar src={AI_AVATAR} className={styles.ai_chat_avatar_icon} />
212
+ </div>
213
+ <span className={styles.title}>{AI_NAME}</span>
214
+ <LineVertical />
215
+ <span className={styles.des}>Chat</span>
216
+ </div>
217
+ <div className={styles.right}>
218
+ <Popover id={'ai-chat-header-clear'} title='清空'>
219
+ <Icon className={getIcon('clear')} />
220
+ </Popover>
221
+ <Popover id={'ai-chat-header-close'} title='关闭'>
222
+ <Icon className={getIcon('close')} />
223
+ </Popover>
224
+ </div>
225
+ </div>
226
+ <div className={styles.body_container}>
227
+ <div className={styles.left_bar}>
228
+ <div className={styles.chat_container} ref={containerRef}>
229
+ {/* @ts-ignore */}
230
+ <MessageList
231
+ className={styles.message_list}
232
+ lockable={true}
233
+ toBottomHeight={'100%'}
234
+ // @ts-ignore
235
+ dataSource={messageListData}
236
+ />
237
+ {loading && (
238
+ <div className={styles.chat_loading_msg_box}>
239
+ {/* @ts-ignore */}
240
+ <SystemMessage
241
+ title={AI_NAME}
242
+ className={styles.smsg}
243
+ // @ts-ignore
244
+ text={<Thinking />}
245
+ ></SystemMessage>
246
+ </div>
247
+ )}
248
+ </div>
249
+ <ChatInput onSend={(value) => handleSend({ message: value })} />
250
+ </div>
251
+ <div className={styles.right_bar}>
252
+ <ul className={styles.chat_list}>
253
+ <li className={styles.active_chat_bar}>
254
+ {/* <Icon className={getExternalIcon('comment-discussion')} /> */}
255
+ <Avatar
256
+ src='https://mdn.alipayobjects.com/huamei_htww6h/afts/img/A*CfffRK50dpQAAAAAAAAAAAAADhl8AQ/original'
257
+ className={styles.ai_chat_avatar_icon}
258
+ />
259
+ </li>
260
+ </ul>
261
+ </div>
262
+ </div>
263
+ </div>
264
+ );
265
+ };
266
+
267
+ // AI 回复组件,就是能一个字一个出现的那种效果
268
+ const AiReply = ({ text, endNode = <></>, immediately = false }) => {
269
+ const [currentIndex, setCurrentIndex] = React.useState(0);
270
+ const [currentText, setCurrentText] = React.useState('');
271
+
272
+ React.useEffect(() => {
273
+ if (currentIndex < text.length) {
274
+ if (immediately) {
275
+ setCurrentText(text);
276
+ setCurrentIndex(text.length);
277
+ } else {
278
+ const timeoutId = setTimeout(() => {
279
+ if (timeoutId) {
280
+ clearTimeout(timeoutId);
281
+ }
282
+
283
+ setCurrentText(text.slice(0, currentIndex + 1));
284
+ setCurrentIndex(currentIndex + 1);
285
+ }, Math.floor(Math.random() * 41) + 10);
286
+ return () => clearTimeout(timeoutId);
287
+ }
288
+ }
289
+ }, [currentIndex, text]);
290
+
291
+ return (
292
+ <div style={{ whiteSpace: 'break-spaces' }}>
293
+ {currentIndex === text.length ? (
294
+ <>
295
+ {currentText}
296
+ {endNode}
297
+ </>
298
+ ) : (
299
+ currentText
300
+ )}
301
+ </div>
302
+ );
303
+ };
304
+
305
+ const AISearch = async (input, aiGPTBackService) => {
306
+ try {
307
+ const result = await aiGPTBackService.aiSearchRequest(
308
+ input.message,
309
+ input.type === AISerivceType.SearchCode ? 'code' : 'overall',
310
+ );
311
+
312
+ const { responseText, urlMessage } = result;
313
+
314
+ console.log('ai search: >>>> ', result);
315
+
316
+ const aiMessage = createMessageByAI(
317
+ <ChatMoreActions>
318
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
319
+ <div>
320
+ <CodeBlockWrapper text={responseText} />
321
+ </div>
322
+ <div style={{ whiteSpace: 'pre-wrap' }}>
323
+ <Markdown value={urlMessage}></Markdown>
324
+ {/* {AIChatGPTReply(urlMessage)} */}
325
+ </div>
326
+ </div>
327
+ </ChatMoreActions>
328
+ );
329
+
330
+ return aiMessage;
331
+ } catch (error) {
332
+ console.log('/search: error >>>>>', error);
333
+ }
334
+ };
335
+
336
+ // 带有代码的 AI 回复组件
337
+ const AIChatGPTReply = async (input) => {
338
+ try {
339
+ console.log('ai chat gpt reply: >>>> ', input);
340
+
341
+ const aiMessage = createMessageByAI(
342
+ <ChatMoreActions><CodeBlockWrapper text={input} /></ChatMoreActions>
343
+ );
344
+
345
+ return aiMessage;
346
+ } catch (error) {
347
+ console.log('/chat gpt reply: error >>>>>', error);
348
+ }
349
+ };
350
+
351
+ // run 的 AI 回复组件
352
+ const AIChatRunReply = async (input, aiRunService: AiRunService) => {
353
+ try {
354
+ console.log('ai chat run reply: >>>> ', input);
355
+ const regex = /"(\S+)"/s;
356
+ const value = regex.exec(input);
357
+ if (!value) {
358
+ return createMessageByAI('未找到合适的启动命令,请重试');
359
+ };
360
+
361
+ const [, command] = value;
362
+ const configuration: DebugConfiguration = {
363
+ name: `Run Tnpm ${command}`,
364
+ type: 'node',
365
+ request: 'launch',
366
+ runtimeExecutable: 'tnpm',
367
+ runtimeArgs: [
368
+ 'run',
369
+ `${command}`,
370
+ ],
371
+ cwd: '\${workspaceFolder}',
372
+ console: 'integratedTerminal',
373
+ };
374
+
375
+ const launchContent = `
376
+ 根据您的项目类型,已为您找到合适的项目启动运行命令
377
+ 以下是 launch.json 的运行命令配置
378
+ \`\`\`json
379
+ ${JSON.stringify(configuration, undefined, 2)}
380
+ \`\`\``;
381
+
382
+ const aiMessage = createMessageByAI(<ChatMoreActions>
383
+ <CodeBlockWrapper text={launchContent} />
384
+ <Button onClick={() => aiRunService.addRunConfiguration(configuration)}>添加该配置并再次执行 run</Button>
385
+ </ChatMoreActions>);
386
+
387
+ return aiMessage;
388
+ } catch (error) {
389
+ console.log('/chat run reply: error >>>>>', error);
390
+ }
391
+ };
392
+
393
+ // 带有命令按钮的 AI 回复
394
+ const AIWithCommandReply = async (command: Command, opener) => {
395
+ try {
396
+ console.log('ai command reply: >>>> ', command);
397
+
398
+ if (!command) {
399
+ return createMessageByAI('未找到合适的功能');
400
+ }
401
+
402
+ const { labelLocalized, label, delegate, id } = command;
403
+
404
+ const aiMessage = createMessageByAI(
405
+ <ChatMoreActions>
406
+ <div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
407
+ <div>已在系统内找到适合功能: {labelLocalized?.localized || label},可以按以下步骤尝试:</div>
408
+ <ol style={{ margin: '8px 0' }}>
409
+ <li style={{ listStyle: 'inherit' }}>打开命令面板:({isMacintosh ? 'cmd' : 'ctrl'} + shift + p)</li>
410
+ <li style={{ listStyle: 'inherit' }}>输入:{labelLocalized?.localized || label}</li>
411
+ </ol>
412
+ <Button onClick={() => opener.open(URI.parse(`command:${delegate || id}`))}>点击执行命令</Button>
413
+ </div>
414
+ </ChatMoreActions>
415
+ );
416
+
417
+ return aiMessage;
418
+ } catch (error) {
419
+ console.log('/ai command reply: error >>>>>', error);
420
+ }
421
+ };