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