@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,261 @@
1
+ // 进度条
2
+ .thinking_container {
3
+ position: relative;
4
+
5
+ .stop {
6
+ position: absolute;
7
+ bottom: -39px;
8
+ width: 100%;
9
+ padding-top: 12px;
10
+
11
+ .block {
12
+ display: flex;
13
+ align-items: center;
14
+ font-size: 12px;
15
+ color: rgba(255, 255, 255, 0.65);
16
+ cursor: pointer;
17
+ }
18
+ }
19
+ }
20
+
21
+ .chat_input_container {
22
+ padding: 16px;
23
+ display: flex;
24
+ flex-direction: column;
25
+ position: relative;
26
+ background-color: #1b232b;
27
+ box-shadow: 0 -1px 12px 0 rgba(0, 0, 0, 0.12), 0 -1px 3px 0 rgba(0, 0, 0, 0.12);
28
+ border-radius: 0 0 0 12px;
29
+
30
+ .block {
31
+ background-color: rgba(255, 255, 255, 0.08);
32
+ border-radius: 6px;
33
+ padding: 4px;
34
+ width: fit-content;
35
+ height: 24px;
36
+ display: flex;
37
+ align-items: center;
38
+ cursor: pointer;
39
+
40
+ .name {
41
+ margin-left: 4px;
42
+ }
43
+ }
44
+
45
+ .header_operate {
46
+ display: flex;
47
+ align-items: center;
48
+ margin-bottom: 12px;
49
+
50
+ .block {
51
+ margin-right: 8px;
52
+ }
53
+ }
54
+
55
+ .instruction_options_container {
56
+ position: absolute;
57
+ width: calc(100% - 32px);
58
+ background-color: #171c25;
59
+ border: 1px solid #363940;
60
+ box-shadow: 0 9px 28px 8px rgba(0, 0, 0, 0.15), 0 6px 16px 0 rgba(0, 0, 0, 0.24), 0 3px 6px -4px rgba(0, 0, 0, 0.36);
61
+ border-radius: 8px;
62
+ bottom: 61px;
63
+ z-index: 1000;
64
+
65
+ .options {
66
+ ul {
67
+ margin: 0;
68
+ padding: 0;
69
+ padding: 4px 0;
70
+
71
+ li {
72
+ display: flex;
73
+ align-items: center;
74
+ padding: 8px 16px;
75
+ font-size: 14px;
76
+ cursor: pointer;
77
+
78
+ &:hover {
79
+ background-color: rgba(255, 255, 255, 0.08);
80
+ }
81
+
82
+ .block {
83
+ margin-right: 8px;
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ .commonly_used {
90
+ border-top: 1px solid #363940;
91
+ padding: 12px 16px;
92
+ display: flex;
93
+ align-items: center;
94
+ }
95
+ }
96
+
97
+ .input_wrapper {
98
+ min-height: 40px;
99
+ max-height: 160px;
100
+ border-radius: 8px;
101
+ background-color: #ffffff14;
102
+ padding: 9px 12px;
103
+ font-size: 14px;
104
+ position: relative;
105
+
106
+ :global {
107
+ .kt-input-addon-after {
108
+ align-items: flex-end;
109
+ }
110
+
111
+ .kt-input-addon-before {
112
+ margin-right: 0;
113
+ }
114
+ }
115
+
116
+ textarea {
117
+ resize: none;
118
+ }
119
+
120
+ .slash_widget_block {
121
+ position: absolute;
122
+ background-color: #34414b;
123
+ color: #40a6ff;
124
+ border-radius: 3px;
125
+ padding: 1px 2px;
126
+ z-index: 1;
127
+ top: 9.5px;
128
+ }
129
+
130
+ .send_chat_btn {
131
+ border-radius: 2px;
132
+ background-color: rgba(95, 101, 107, 0.25);
133
+ width: 24px;
134
+ height: 22px;
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: center;
138
+ cursor: pointer;
139
+
140
+ &.active {
141
+ background-color: rgba(60, 141, 255, 1);
142
+
143
+ span {
144
+ color: #fff;
145
+ }
146
+ }
147
+
148
+ span {
149
+ color: rgba(95, 101, 107, 1);
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ // chat 面板的代码展示部分
156
+ .ai_chat_code_wrapper {
157
+ position: relative;
158
+ width: 100%;
159
+
160
+ .render_text {
161
+ white-space: pre-wrap;
162
+
163
+ span.code_inline {
164
+ display: inline;
165
+ color: #d7ba7d;
166
+
167
+ &::after {
168
+ content: none;
169
+ }
170
+ }
171
+
172
+ .code_block {
173
+ .monaco_wrapper {
174
+ position: relative;
175
+
176
+ &:hover {
177
+ .action_toolbar {
178
+ display: flex;
179
+ }
180
+ }
181
+
182
+ .editor {
183
+ border-radius: 8px;
184
+ border: 1px solid #ffffff1a;
185
+ overflow: hidden;
186
+ }
187
+
188
+ .action_toolbar {
189
+ display: none;
190
+ position: absolute;
191
+ right: 0;
192
+ top: 0;
193
+ background-color: #151b21;
194
+ border-radius: 6px 6px 0 6px;
195
+ z-index: 100;
196
+ top: -15px;
197
+ height: 30px;
198
+ border: 1px solid #ffffff1a;
199
+ align-items: center;
200
+ overflow: hidden;
201
+
202
+ :global {
203
+ .kt-popover {
204
+ height: inherit;
205
+ }
206
+ }
207
+
208
+ span {
209
+ width: 30px;
210
+ height: 100%;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+
215
+ &:hover {
216
+ background-color: rgba(255, 255, 255, 0.08);
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+
225
+ .ai_chat_more_actions_container {
226
+ position: relative;
227
+
228
+ .ai_chat_message {
229
+ }
230
+
231
+ .more_actions {
232
+ position: absolute;
233
+ z-index: 1000;
234
+ bottom: -36px;
235
+ display: flex;
236
+ align-items: center;
237
+ justify-content: space-between;
238
+ width: 100%;
239
+ height: 16px;
240
+
241
+ &::after {
242
+ content: initial;
243
+ }
244
+
245
+ .side {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-items: right;
249
+ height: inherit;
250
+
251
+ span {
252
+ margin-right: 6px;
253
+ cursor: pointer;
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ .ai_native_input_container {
260
+ height: 32px;
261
+ }
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+
3
+ const lineStyles = {
4
+ borderLeft: '1px solid #666',
5
+ height: '100%',
6
+ width: '1px',
7
+ display: 'block',
8
+ };
9
+
10
+ const horizontalStyles = {
11
+ backgroundColor: 'rgba(255,255,255,0.08)',
12
+ width: '100%',
13
+ height: '1px',
14
+ minHeight: '1px',
15
+ };
16
+
17
+ export const LineVertical = () => <span style={lineStyles}></span>;
18
+
19
+ export const HorizontalVertical = () => <span style={horizontalStyles}></span>;
@@ -0,0 +1,132 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+
4
+ import { Injectable, Autowired } from '@opensumi/di';
5
+ import { AppConfig, ConfigProvider } from '@opensumi/ide-core-browser';
6
+ import { Disposable, Emitter, Event } from '@opensumi/ide-core-common';
7
+ import type { ICodeEditor as IMonacoCodeEditor } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
8
+ import * as monaco from '@opensumi/monaco-editor-core/esm/vs/editor/editor.api';
9
+
10
+ import { AIInlineChatPanel } from './ai-inline-chat-panel';
11
+
12
+ export interface IAiContentWidget extends monaco.editor.IContentWidget {
13
+ show: (options?: ShowAiContentOptions | undefined) => void;
14
+ hide: (options?: ShowAiContentOptions | undefined) => void;
15
+ }
16
+
17
+ export interface ShowAiContentOptions {
18
+ /**
19
+ * 选中区域
20
+ */
21
+ selection?: monaco.Range;
22
+
23
+ /**
24
+ * 行列
25
+ */
26
+ position?: monaco.IPosition;
27
+ }
28
+
29
+ @Injectable({ multiple: true })
30
+ export class AiContentWidget extends Disposable implements IAiContentWidget {
31
+
32
+ @Autowired(AppConfig)
33
+ private configContext: AppConfig;
34
+
35
+ allowEditorOverflow?: boolean | undefined = true;
36
+ suppressMouseDown?: boolean | undefined = false;
37
+
38
+ private domNode: HTMLElement;
39
+ protected options: ShowAiContentOptions | undefined;
40
+
41
+ private readonly _onSelectChange = new Emitter<string>();
42
+ public readonly onSelectChange: Event<string> = this._onSelectChange.event;
43
+
44
+ constructor(private readonly editor: IMonacoCodeEditor) {
45
+ super();
46
+
47
+ this.hide();
48
+ this.renderView();
49
+ }
50
+
51
+ override dispose(): void {
52
+ this.hide();
53
+ super.dispose();
54
+ }
55
+
56
+ private renderView(): void {
57
+ ReactDOM.render(
58
+ <ConfigProvider value={this.configContext}>
59
+ <AIInlineChatPanel selectChangeFire={this._onSelectChange} />
60
+ </ConfigProvider>,
61
+ this.getDomNode(),
62
+ );
63
+ this.layoutContentWidget();
64
+ }
65
+
66
+ async show(options?: ShowAiContentOptions | undefined): Promise<void> {
67
+ if (!options) {
68
+ return;
69
+ }
70
+
71
+ if (this.options && this.options.selection && this.options.selection.equalsRange(options.selection!)) {
72
+ return;
73
+ }
74
+
75
+ this.options = options;
76
+
77
+ this.editor.addContentWidget(this);
78
+ }
79
+
80
+ setOptions(options: ShowAiContentOptions): void {
81
+ this.options = options;
82
+ }
83
+
84
+ hide: (options?: ShowAiContentOptions | undefined) => void = () => {
85
+ this.options = undefined;
86
+ this.editor.removeContentWidget(this);
87
+ };
88
+
89
+ getId(): string {
90
+ return 'AI-Content-Widget';
91
+ }
92
+
93
+ layoutContentWidget(): void {
94
+ this.editor.layoutContentWidget(this);
95
+ }
96
+
97
+ getDomNode(): HTMLElement {
98
+ if (!this.domNode) {
99
+ this.domNode = document.createElement('div');
100
+ this.domNode.classList.add(this.getId());
101
+ }
102
+ return this.domNode;
103
+ }
104
+
105
+ getPosition(): monaco.editor.IContentWidgetPosition | null {
106
+ if (!this.options) {
107
+ return null;
108
+ }
109
+
110
+ const { position, selection } = this.options;
111
+
112
+ if (position) {
113
+ return {
114
+ position,
115
+ preference: [
116
+ monaco.editor.ContentWidgetPositionPreference.BELOW,
117
+ ],
118
+ };
119
+ }
120
+
121
+ const endPosition = selection && selection.getEndPosition();
122
+ return endPosition
123
+ ? {
124
+ // @ts-ignore
125
+ position: new monaco.Position(endPosition.lineNumber, this.options?.selection.startColumn),
126
+ preference: [
127
+ monaco.editor.ContentWidgetPositionPreference.BELOW,
128
+ ],
129
+ }
130
+ : null;
131
+ }
132
+ }
@@ -0,0 +1,163 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+
3
+ import { getIcon, useInjectable } from '@opensumi/ide-core-browser';
4
+ import { getExternalIcon } from '@opensumi/ide-core-browser';
5
+ import { Button, Icon } from '@opensumi/ide-core-browser/lib/components/index';
6
+ import { Progress } from '@opensumi/ide-core-browser/lib/progress/progress-bar';
7
+ import { Emitter } from '@opensumi/ide-core-common';
8
+
9
+ import { AIImprove } from '../components/AIImprove';
10
+ import { AiInput } from '../components/AIInput';
11
+
12
+ import * as styles from './ai-inline-chat.module.less';
13
+ import { AiInlineChatService, EChatStatus } from './ai-inline-chat.service';
14
+
15
+ export const AIInlineChatPanel = (props: { selectChangeFire: Emitter<string> }) => {
16
+ const aiInlineChatService: AiInlineChatService = useInjectable(AiInlineChatService);
17
+ const [isLoading, setIsLoading] = useState<boolean>(false);
18
+ const [isDone, setIsDone] = useState<boolean>(false);
19
+ const [currentCheckText, setCurrentCheckText] = useState<string>('优化代码');
20
+
21
+ useEffect(() => {
22
+ const dis = aiInlineChatService.onChatStatus((status) => {
23
+ if (status === EChatStatus.THINKING) {
24
+ setIsLoading(true);
25
+ setIsDone(false);
26
+ } else {
27
+ setIsLoading(false);
28
+ }
29
+
30
+ if (status === EChatStatus.DONE) {
31
+ setIsDone(true);
32
+ } else {
33
+ setIsDone(false);
34
+ }
35
+
36
+ if (status === EChatStatus.ERROR) {
37
+ setIsLoading(false);
38
+ setIsDone(false);
39
+ }
40
+ });
41
+
42
+ return () => {
43
+ dis.dispose();
44
+ };
45
+ }, []);
46
+
47
+ const improveList = useMemo(
48
+ () => [
49
+ { title: '解释代码', iconClass: getExternalIcon('git-pull-request') },
50
+ { title: '|', iconClass: '' },
51
+ { title: '生成注释', iconClass: getExternalIcon('git-pull-request') },
52
+ { title: '|', iconClass: '' },
53
+ { title: '优化代码', iconClass: getExternalIcon('git-pull-request') },
54
+ { title: '|', iconClass: '' },
55
+ { title: '生成测试用例', iconClass: getExternalIcon('git-pull-request') },
56
+ ],
57
+ [],
58
+ );
59
+
60
+ const renderHeader = useMemo(() => {
61
+ if (!isLoading && !isDone) {
62
+ return null;
63
+ }
64
+
65
+ return (
66
+ <div className={styles.panel_header}>
67
+ <div className={styles.header_container}>
68
+ <div className={styles.left_side}>
69
+ <span>Chat</span>
70
+ </div>
71
+ <div className={styles.right_side}>
72
+ <Icon className={getIcon('clear')} style={{ marginRight: '8px' }} />
73
+ <Icon className={getIcon('close')} />
74
+ </div>
75
+ </div>
76
+ {/* 进度条 */}
77
+ <span className={styles.progress_bar}>
78
+ <Progress loading={!isDone} />
79
+ </span>
80
+ </div>
81
+ );
82
+ }, [isLoading, isDone]);
83
+
84
+ const renderResult = useMemo(() => {
85
+ if (!isLoading && !isDone) {
86
+ return null;
87
+ }
88
+
89
+ return (
90
+ <div className={styles.panel_result}>
91
+ <div className={styles.result_container}>
92
+ <div className={styles.title}>
93
+ <Icon />
94
+ <span>{currentCheckText}</span>
95
+ </div>
96
+ {isDone && (
97
+ <>
98
+ <span className={styles.v_line}></span>
99
+ <div className={styles.operate}>
100
+ <div className={styles.left_side}>
101
+ <Button
102
+ size={'small'}
103
+ onClick={() => {
104
+ aiInlineChatService._onAccept.fire();
105
+ }}
106
+ >
107
+ 采纳
108
+ </Button>
109
+ <Button
110
+ size={'small'}
111
+ type={'ghost'}
112
+ onClick={() => {
113
+ aiInlineChatService._onDiscard.fire();
114
+ }}
115
+ >
116
+ 丢弃
117
+ </Button>
118
+ </div>
119
+ <div className={styles.right_side}>
120
+ <Button size={'small'}>
121
+ <Icon className={getIcon('layout')} />
122
+ </Button>
123
+ <span>|</span>
124
+ <Icon className={getExternalIcon('thumbsup')} />
125
+ <Icon className={getExternalIcon('thumbsdown')} />
126
+ </div>
127
+ </div>
128
+ </>
129
+ )}
130
+ </div>
131
+ </div>
132
+ );
133
+ }, [isLoading, isDone, aiInlineChatService]);
134
+
135
+ return (
136
+ <div className={styles.ai_inline_chat_panel}>
137
+ {/* header */}
138
+ {renderHeader}
139
+ {/* result */}
140
+ {renderResult}
141
+ {/* chat */}
142
+ <div className={styles.panel_chat}>
143
+ <div className={styles.ai_shortcuts}>
144
+ <AIImprove
145
+ onClick={(title) => {
146
+ props.selectChangeFire.fire(title);
147
+ setCurrentCheckText(title);
148
+ }}
149
+ lists={improveList}
150
+ />
151
+ </div>
152
+ <div className={styles.ai_content_widget_input}>
153
+ <AiInput
154
+ onValueChange={(value) => {
155
+ props.selectChangeFire.fire(value);
156
+ setCurrentCheckText(value);
157
+ }}
158
+ />
159
+ </div>
160
+ </div>
161
+ </div>
162
+ );
163
+ };
@@ -0,0 +1,81 @@
1
+ .ai_inline_chat_panel {
2
+ box-shadow: 0 9px 28px 8px rgba(0, 0, 0, 0.15);
3
+ border-radius: 10px;
4
+ padding: 12px 16px;
5
+ background-color: rgba(23, 28, 37, 1);
6
+ border: 1px solid rgba(54, 57, 64, 1);
7
+
8
+ .ai_shortcuts {
9
+ margin-bottom: 12px;
10
+ }
11
+
12
+ .panel_header {
13
+ border-bottom: 1px solid rgba(255, 255, 255, 0.12);
14
+ margin: 0 -16px 12px -16px;
15
+
16
+ .progress_bar {
17
+ position: relative;
18
+ height: 1px;
19
+ width: 100%;
20
+ display: inherit;
21
+
22
+ .bar {
23
+ background: linear-gradient(to right, rgba(22, 119, 255, 1), rgba(22, 238, 255, 1));
24
+ }
25
+ }
26
+
27
+ .header_container {
28
+ margin: 0 16px;
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: space-between;
32
+ margin-bottom: 10px;
33
+ }
34
+ }
35
+
36
+ .panel_result {
37
+ margin-bottom: 16px;
38
+
39
+ .result_container {
40
+ border-radius: 8px;
41
+ background-color: rgba(255, 255, 255, 0.04);
42
+ padding: 12px;
43
+
44
+ button {
45
+ border-radius: 6px;
46
+ }
47
+
48
+ .v_line {
49
+ height: 1px;
50
+ display: block;
51
+ width: 100%;
52
+ background-color: rgba(233, 233, 233, 0.08);
53
+ margin: 12px 0 12px 0;
54
+ }
55
+
56
+ .line {
57
+ width: 1px;
58
+ display: block;
59
+ height: 100%;
60
+ background-color: rgba(255, 255, 255, 0.12);
61
+ }
62
+
63
+ .operate {
64
+ display: flex;
65
+ justify-content: space-between;
66
+ align-items: center;
67
+
68
+ .left_side {
69
+ button:first-child {
70
+ margin-right: 8px;
71
+ }
72
+ }
73
+
74
+ .right_side {
75
+ display: flex;
76
+ align-items: center;
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,46 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import { PreferenceService } from '@opensumi/ide-core-browser';
3
+ import { Emitter, Event, CommandService } from '@opensumi/ide-core-common';
4
+ import { ExtensionManagementService } from '@opensumi/ide-extension/lib/browser/extension-management.service';
5
+
6
+ import { AiGPTBackSerivcePath } from '../../common/index';
7
+
8
+ export const enum EChatStatus {
9
+ READY,
10
+ THINKING,
11
+ DONE,
12
+ ERROR
13
+ }
14
+
15
+ @Injectable({ multiple: false })
16
+ export class AiInlineChatService {
17
+
18
+ @Autowired(AiGPTBackSerivcePath)
19
+ aiBackService: any;
20
+
21
+ @Autowired(CommandService)
22
+ protected readonly commandService: CommandService;
23
+
24
+ @Autowired(PreferenceService)
25
+ protected preferenceService: PreferenceService;
26
+
27
+ @Autowired()
28
+ protected extensionManagementService: ExtensionManagementService;
29
+
30
+ private readonly _onChatStatus = new Emitter<EChatStatus>();
31
+ public readonly onChatStatus: Event<EChatStatus> = this._onChatStatus.event;
32
+
33
+ // 采纳
34
+ public readonly _onAccept = new Emitter<void>();
35
+ public readonly onAccept: Event<void> = this._onAccept.event;
36
+
37
+ // 丢弃
38
+ public readonly _onDiscard = new Emitter<void>();
39
+ public readonly onDiscard: Event<void> = this._onDiscard.event;
40
+
41
+ public launchChatMessage(message: EChatStatus) {
42
+ setTimeout(() => {
43
+ this._onChatStatus.fire(message);
44
+ });
45
+ }
46
+ }