@opensumi/ide-ai-native 3.9.1-next-1749181695.0 → 3.9.1-next-1749196667.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 (200) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +4 -9
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/apply.service.d.ts +0 -3
  5. package/lib/browser/chat/apply.service.d.ts.map +1 -1
  6. package/lib/browser/chat/apply.service.js +0 -47
  7. package/lib/browser/chat/apply.service.js.map +1 -1
  8. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  9. package/lib/browser/chat/chat-model.js +1 -3
  10. package/lib/browser/chat/chat-model.js.map +1 -1
  11. package/lib/browser/chat/chat-proxy.service.d.ts +2 -0
  12. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  13. package/lib/browser/chat/chat-proxy.service.js +57 -50
  14. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  15. package/lib/browser/chat/chat.feature.registry.d.ts +1 -4
  16. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  17. package/lib/browser/chat/chat.feature.registry.js +0 -6
  18. package/lib/browser/chat/chat.feature.registry.js.map +1 -1
  19. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  20. package/lib/browser/chat/chat.view.js +8 -33
  21. package/lib/browser/chat/chat.view.js.map +1 -1
  22. package/lib/browser/components/ChatEditor.js +2 -2
  23. package/lib/browser/components/ChatEditor.js.map +1 -1
  24. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  25. package/lib/browser/components/ChatHistory.js +1 -2
  26. package/lib/browser/components/ChatHistory.js.map +1 -1
  27. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
  28. package/lib/browser/components/ChatMentionInput.js +30 -148
  29. package/lib/browser/components/ChatMentionInput.js.map +1 -1
  30. package/lib/browser/components/ChatReply.js +2 -2
  31. package/lib/browser/components/ChatReply.js.map +1 -1
  32. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  33. package/lib/browser/components/ChatToolRender.js +2 -7
  34. package/lib/browser/components/ChatToolRender.js.map +1 -1
  35. package/lib/browser/components/ChatToolRender.module.less +0 -25
  36. package/lib/browser/components/components.module.less +8 -37
  37. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
  38. package/lib/browser/components/mention-input/mention-input.js +14 -150
  39. package/lib/browser/components/mention-input/mention-input.js.map +1 -1
  40. package/lib/browser/components/mention-input/mention-input.module.less +1 -165
  41. package/lib/browser/components/mention-input/types.d.ts +1 -28
  42. package/lib/browser/components/mention-input/types.d.ts.map +1 -1
  43. package/lib/browser/components/mention-input/types.js +0 -1
  44. package/lib/browser/components/mention-input/types.js.map +1 -1
  45. package/lib/browser/components/utils.d.ts +2 -2
  46. package/lib/browser/context/llm-context.service.d.ts +2 -21
  47. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  48. package/lib/browser/context/llm-context.service.js +20 -162
  49. package/lib/browser/context/llm-context.service.js.map +1 -1
  50. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
  51. package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
  52. package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
  53. package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
  54. package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
  55. package/lib/browser/index.d.ts.map +1 -1
  56. package/lib/browser/index.js +0 -7
  57. package/lib/browser/index.js.map +1 -1
  58. package/lib/browser/layout/ai-layout.d.ts.map +1 -1
  59. package/lib/browser/layout/ai-layout.js +4 -6
  60. package/lib/browser/layout/ai-layout.js.map +1 -1
  61. package/lib/browser/layout/tabbar.view.d.ts +1 -1
  62. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  63. package/lib/browser/layout/tabbar.view.js +12 -5
  64. package/lib/browser/layout/tabbar.view.js.map +1 -1
  65. package/lib/browser/mcp/base-apply.service.d.ts +4 -5
  66. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  67. package/lib/browser/mcp/base-apply.service.js +5 -23
  68. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  69. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +1 -3
  70. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  71. package/lib/browser/mcp/mcp-server-proxy.service.js +0 -4
  72. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  73. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  74. package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
  75. package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
  76. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  77. package/lib/browser/preferences/schema.d.ts.map +1 -1
  78. package/lib/browser/preferences/schema.js +0 -5
  79. package/lib/browser/preferences/schema.js.map +1 -1
  80. package/lib/browser/types.d.ts +1 -8
  81. package/lib/browser/types.d.ts.map +1 -1
  82. package/lib/browser/types.js.map +1 -1
  83. package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
  84. package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
  85. package/lib/common/index.d.ts +1 -5
  86. package/lib/common/index.d.ts.map +1 -1
  87. package/lib/common/index.js +0 -2
  88. package/lib/common/index.js.map +1 -1
  89. package/lib/common/llm-context.d.ts +0 -19
  90. package/lib/common/llm-context.d.ts.map +1 -1
  91. package/lib/common/llm-context.js.map +1 -1
  92. package/lib/common/model.d.ts +0 -1
  93. package/lib/common/model.d.ts.map +1 -1
  94. package/lib/common/model.js.map +1 -1
  95. package/lib/common/prompts/context-prompt-provider.d.ts +2 -0
  96. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  97. package/lib/common/prompts/context-prompt-provider.js +29 -35
  98. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  99. package/lib/common/types.d.ts +0 -21
  100. package/lib/common/types.d.ts.map +1 -1
  101. package/lib/common/types.js.map +1 -1
  102. package/lib/common/utils.d.ts +0 -1
  103. package/lib/common/utils.d.ts.map +1 -1
  104. package/lib/common/utils.js +2 -5
  105. package/lib/common/utils.js.map +1 -1
  106. package/lib/node/anthropic/anthropic-language-model.d.ts +1 -1
  107. package/lib/node/base-language-model.d.ts +1 -2
  108. package/lib/node/base-language-model.d.ts.map +1 -1
  109. package/lib/node/base-language-model.js +2 -12
  110. package/lib/node/base-language-model.js.map +1 -1
  111. package/lib/node/deepseek/deepseek-language-model.d.ts +1 -1
  112. package/lib/node/mcp/sumi-mcp-server.d.ts +1 -3
  113. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  114. package/lib/node/mcp/sumi-mcp-server.js +1 -7
  115. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  116. package/lib/node/mcp-server-manager-impl.d.ts +1 -3
  117. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  118. package/lib/node/mcp-server-manager-impl.js +2 -14
  119. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  120. package/package.json +25 -26
  121. package/src/browser/ai-core.contribution.ts +4 -14
  122. package/src/browser/chat/apply.service.ts +1 -62
  123. package/src/browser/chat/chat-model.ts +1 -3
  124. package/src/browser/chat/chat-proxy.service.ts +81 -68
  125. package/src/browser/chat/chat.feature.registry.ts +1 -17
  126. package/src/browser/chat/chat.view.tsx +10 -40
  127. package/src/browser/components/ChatEditor.tsx +1 -1
  128. package/src/browser/components/ChatHistory.tsx +1 -2
  129. package/src/browser/components/ChatMentionInput.tsx +35 -180
  130. package/src/browser/components/ChatReply.tsx +4 -4
  131. package/src/browser/components/ChatToolRender.module.less +0 -25
  132. package/src/browser/components/ChatToolRender.tsx +2 -10
  133. package/src/browser/components/components.module.less +8 -37
  134. package/src/browser/components/mention-input/mention-input.module.less +1 -165
  135. package/src/browser/components/mention-input/mention-input.tsx +31 -232
  136. package/src/browser/components/mention-input/types.ts +0 -29
  137. package/src/browser/context/llm-context.service.ts +21 -182
  138. package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
  139. package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
  140. package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
  141. package/src/browser/index.ts +0 -8
  142. package/src/browser/layout/ai-layout.tsx +8 -12
  143. package/src/browser/layout/tabbar.view.tsx +23 -10
  144. package/src/browser/mcp/base-apply.service.ts +10 -30
  145. package/src/browser/mcp/mcp-server-proxy.service.ts +1 -6
  146. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
  147. package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
  148. package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
  149. package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
  150. package/src/browser/preferences/schema.ts +0 -5
  151. package/src/browser/types.ts +0 -12
  152. package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +1 -0
  153. package/src/common/index.ts +1 -6
  154. package/src/common/llm-context.ts +0 -23
  155. package/src/common/model.ts +0 -1
  156. package/src/common/prompts/context-prompt-provider.ts +40 -55
  157. package/src/common/types.ts +0 -18
  158. package/src/common/utils.ts +1 -4
  159. package/src/node/base-language-model.ts +14 -11
  160. package/src/node/mcp/sumi-mcp-server.ts +2 -10
  161. package/src/node/mcp-server-manager-impl.ts +2 -17
  162. package/lib/browser/components/mention-input/mention-select.d.ts +0 -28
  163. package/lib/browser/components/mention-input/mention-select.d.ts.map +0 -1
  164. package/lib/browser/components/mention-input/mention-select.js +0 -136
  165. package/lib/browser/components/mention-input/mention-select.js.map +0 -1
  166. package/lib/browser/components/mention-input/mention-select.module.less +0 -297
  167. package/lib/browser/rules/rules.contribution.d.ts +0 -29
  168. package/lib/browser/rules/rules.contribution.d.ts.map +0 -1
  169. package/lib/browser/rules/rules.contribution.js +0 -94
  170. package/lib/browser/rules/rules.contribution.js.map +0 -1
  171. package/lib/browser/rules/rules.module.less +0 -175
  172. package/lib/browser/rules/rules.service.d.ts +0 -25
  173. package/lib/browser/rules/rules.service.d.ts.map +0 -1
  174. package/lib/browser/rules/rules.service.js +0 -180
  175. package/lib/browser/rules/rules.service.js.map +0 -1
  176. package/lib/browser/rules/rules.view.d.ts +0 -3
  177. package/lib/browser/rules/rules.view.d.ts.map +0 -1
  178. package/lib/browser/rules/rules.view.js +0 -76
  179. package/lib/browser/rules/rules.view.js.map +0 -1
  180. package/lib/common/image-compression.d.ts +0 -25
  181. package/lib/common/image-compression.d.ts.map +0 -1
  182. package/lib/common/image-compression.js +0 -153
  183. package/lib/common/image-compression.js.map +0 -1
  184. package/lib/common/mdc-parser.d.ts +0 -60
  185. package/lib/common/mdc-parser.d.ts.map +0 -1
  186. package/lib/common/mdc-parser.js +0 -246
  187. package/lib/common/mdc-parser.js.map +0 -1
  188. package/lib/common/prompts/system-prompt.d.ts +0 -2
  189. package/lib/common/prompts/system-prompt.d.ts.map +0 -1
  190. package/lib/common/prompts/system-prompt.js +0 -5
  191. package/lib/common/prompts/system-prompt.js.map +0 -1
  192. package/src/browser/components/mention-input/mention-select.module.less +0 -297
  193. package/src/browser/components/mention-input/mention-select.tsx +0 -256
  194. package/src/browser/rules/rules.contribution.ts +0 -105
  195. package/src/browser/rules/rules.module.less +0 -175
  196. package/src/browser/rules/rules.service.ts +0 -189
  197. package/src/browser/rules/rules.view.tsx +0 -127
  198. package/src/common/image-compression.ts +0 -174
  199. package/src/common/mdc-parser.ts +0 -295
  200. package/src/common/prompts/system-prompt.ts +0 -2
@@ -6,6 +6,7 @@
6
6
 
7
7
  .model_selector {
8
8
  margin-right: 5px;
9
+ min-width: 150px;
9
10
  }
10
11
 
11
12
  .editor_area {
@@ -28,9 +29,7 @@
28
29
  word-break: break-word;
29
30
 
30
31
  .mention_tag {
31
- height: 20px;
32
32
  margin: 0 2px;
33
- margin-top: -3px;
34
33
  vertical-align: middle;
35
34
  }
36
35
  }
@@ -96,13 +95,11 @@
96
95
  .stop_logo {
97
96
  background-color: var(--badge-background);
98
97
  color: var(--badge-foreground);
99
-
100
98
  .stop_logo_icon {
101
99
  line-height: 16px;
102
100
  color: var(--kt-dangerButton-background);
103
101
  }
104
102
  }
105
-
106
103
  .send_logo {
107
104
  &:hover {
108
105
  background-color: var(--kt-primaryButton-background);
@@ -143,38 +140,31 @@
143
140
  display: flex;
144
141
  justify-content: center;
145
142
  }
146
-
147
143
  .context_container {
148
144
  display: flex;
149
145
  align-items: center;
150
146
  justify-content: center;
151
147
  cursor: pointer;
152
-
153
148
  .context_icon {
154
149
  flex-grow: 0;
155
150
  flex-shrink: 0;
156
-
157
151
  :global(.kt-icon) {
158
152
  font-size: 12px;
159
153
  }
160
-
161
154
  :global(.kticon-close) {
162
155
  display: none;
163
156
  }
164
157
  }
165
-
166
158
  &:hover {
167
159
  .context_icon {
168
160
  :global(.kticon-close) {
169
161
  display: block;
170
162
  }
171
-
172
163
  :global(.kticon-out-link) {
173
164
  display: none;
174
165
  }
175
166
  }
176
167
  }
177
-
178
168
  .context_description {
179
169
  flex: 1;
180
170
  margin-left: 3px;
@@ -264,7 +254,6 @@
264
254
  display: inline;
265
255
  flex: 1;
266
256
  direction: rtl;
267
- unicode-bidi: plaintext;
268
257
  text-overflow: ellipsis;
269
258
  overflow: hidden;
270
259
  white-space: nowrap;
@@ -352,10 +341,6 @@
352
341
  justify-content: center;
353
342
  margin-right: 3px;
354
343
  font-size: 12px;
355
- &::before {
356
- font-size: 12px;
357
- background-size: 12px !important;
358
- }
359
344
  }
360
345
 
361
346
  .empty_state {
@@ -419,152 +404,3 @@
419
404
  color: #666;
420
405
  font-style: italic;
421
406
  }
422
-
423
- .context_preview_container {
424
- background-color: var(--kt-editorWidget-background);
425
- border: 1px solid var(--kt-editorWidget-border);
426
- margin: 0 16px;
427
- animation: slideIn 0.3s ease-out;
428
- display: flex;
429
- flex-wrap: wrap;
430
- gap: 4px;
431
- align-items: flex-start;
432
- margin-bottom: 3px;
433
- width: calc(100% - 32px);
434
- }
435
-
436
- .context_preview_title {
437
- cursor: pointer;
438
- display: flex;
439
- align-items: center;
440
- justify-content: center;
441
- padding: 2px 3px;
442
- height: 18px;
443
- width: auto;
444
- box-sizing: border-box;
445
- border-radius: 4px;
446
- border: 1px solid color-mix(in srgb, var(--editor-foreground) 10%, transparent);
447
- outline: none;
448
- flex-shrink: 0;
449
- color: var(--descriptionForeground);
450
- font-size: 11px;
451
-
452
- &::before {
453
- content: '@';
454
- margin-right: 4px;
455
- }
456
- &.has_context {
457
- width: 18px;
458
- &::before {
459
- content: '@';
460
- margin-right: 0;
461
- }
462
- }
463
-
464
- &:hover {
465
- color: var(--badge-foreground);
466
- }
467
- }
468
-
469
- .context_preview_item {
470
- cursor: pointer;
471
- display: flex;
472
- align-items: center;
473
- justify-content: flex-start;
474
- padding: 2px 4px;
475
- height: 18px;
476
- width: auto;
477
- min-width: fit-content;
478
- max-width: 300px;
479
- box-sizing: border-box;
480
- border-radius: 4px;
481
- border: 1px solid color-mix(in srgb, var(--badge-background) 30%, transparent);
482
- outline: none;
483
- flex: 0 1 auto;
484
- margin-left: 3px;
485
-
486
- .icon {
487
- width: 12px !important;
488
- height: 12px !important;
489
- line-height: 12px !important;
490
- margin-right: 2px;
491
- flex-shrink: 0;
492
- }
493
-
494
- .close_icon {
495
- margin-right: 2px;
496
- display: none !important;
497
- width: 12px !important;
498
- height: 12px !important;
499
- line-height: 12px !important;
500
- flex-shrink: 0;
501
- opacity: 0.8;
502
-
503
- &:hover {
504
- opacity: 1;
505
- }
506
- }
507
-
508
- &:hover {
509
- opacity: 1;
510
- .icon {
511
- display: none;
512
- }
513
- .close_icon {
514
- display: inline-block !important;
515
- font-size: 12px !important;
516
- }
517
- }
518
- }
519
-
520
- .context_preview_item_icon {
521
- display: flex;
522
- align-items: center;
523
- justify-content: center;
524
- flex-shrink: 0;
525
- opacity: 0.8;
526
- &::before {
527
- background-position: 2px !important;
528
- font-size: 12px;
529
- background-size: 11px !important;
530
- }
531
- }
532
-
533
- .context_preview_item_text {
534
- flex: 1;
535
- overflow: hidden;
536
- text-overflow: ellipsis;
537
- color: var(--descriptionForeground);
538
- white-space: nowrap;
539
- font-weight: 400;
540
- line-height: 1.2;
541
- font-size: 11px;
542
- max-width: 200px;
543
- }
544
-
545
- .context_preview_item_remove {
546
- cursor: pointer;
547
- opacity: 0.5;
548
- font-size: 12px;
549
- margin-left: 4px;
550
- padding: 2px;
551
- border-radius: 50%;
552
- display: flex;
553
- align-items: center;
554
- justify-content: center;
555
- flex-shrink: 0;
556
- transition: all 0.2s ease;
557
- width: 16px;
558
- height: 16px;
559
-
560
- &:hover {
561
- opacity: 1;
562
- background-color: var(--kt-dangerButton-background);
563
- color: var(--kt-dangerButton-foreground);
564
- transform: scale(1.1);
565
- }
566
-
567
- &:active {
568
- transform: scale(0.9);
569
- }
570
- }
@@ -1,17 +1,15 @@
1
1
  import cls from 'classnames';
2
2
  import * as React from 'react';
3
3
 
4
- import { getSymbolIcon, localize } from '@opensumi/ide-core-browser';
4
+ import { formatLocalize, getSymbolIcon, localize } from '@opensumi/ide-core-browser';
5
5
  import { Icon, Popover, PopoverPosition, Select, getIcon } from '@opensumi/ide-core-browser/lib/components';
6
6
  import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
7
7
  import { URI } from '@opensumi/ide-utils';
8
8
 
9
9
  import { FileContext } from '../../../common/llm-context';
10
- import { ProjectRule } from '../../../common/types';
11
10
 
12
11
  import styles from './mention-input.module.less';
13
12
  import { MentionPanel } from './mention-panel';
14
- import { ExtendedModelOption, MentionSelect } from './mention-select';
15
13
  import {
16
14
  FooterButtonPosition,
17
15
  MENTION_KEYWORD,
@@ -69,22 +67,11 @@ export const MentionInput: React.FC<MentionInputProps> = ({
69
67
  const [attachedFiles, setAttachedFiles] = React.useState<{
70
68
  files: FileContext[];
71
69
  folders: FileContext[];
72
- rules: ProjectRule[];
73
70
  }>({
74
71
  files: [],
75
72
  folders: [],
76
- rules: [],
77
73
  });
78
74
 
79
- // 添加用于跟踪 mention_tag 的状态
80
- const prevMentionTagsRef = React.useRef<
81
- Array<{
82
- id: string;
83
- type: string;
84
- contextId: string;
85
- }>
86
- >([]);
87
-
88
75
  const getCurrentItems = (): MentionItem[] => {
89
76
  if (mentionState.level === 0) {
90
77
  return mentionItems;
@@ -190,14 +177,14 @@ export const MentionInput: React.FC<MentionInputProps> = ({
190
177
  }, [debouncedSecondLevelFilter, mentionState.level, mentionState.parentType]);
191
178
 
192
179
  React.useEffect(() => {
193
- const disposable = contextService?.onDidContextFilesChangeEvent(({ attached, attachedFolders, attachedRules }) => {
194
- setAttachedFiles({ files: attached, folders: attachedFolders, rules: attachedRules });
180
+ const disposable = contextService?.onDidContextFilesChangeEvent(({ attached, attachedFolders }) => {
181
+ setAttachedFiles({ files: attached, folders: attachedFolders });
195
182
  });
196
183
 
197
184
  return () => {
198
185
  disposable?.dispose();
199
186
  };
200
- }, []);
187
+ }, [contextService]);
201
188
 
202
189
  // 获取光标位置
203
190
  const getCursorPosition = (element: HTMLElement): number => {
@@ -220,45 +207,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
220
207
  setHistoryIndex(-1);
221
208
  }
222
209
 
223
- // 检测 mention_tag 的删除
224
- if (editorRef.current) {
225
- const currentMentionTags = Array.from(editorRef.current.querySelectorAll(`.${styles.mention_tag}`)).map(
226
- (tag) => ({
227
- id: tag.getAttribute('data-id') || '',
228
- type: tag.getAttribute('data-type') || '',
229
- contextId: tag.getAttribute('data-context-id') || '',
230
- }),
231
- );
232
-
233
- // 找出被删除的 mention_tag
234
- const deletedTags = prevMentionTagsRef.current.filter(
235
- (prevTag) =>
236
- !currentMentionTags.some(
237
- (currentTag) =>
238
- currentTag.id === prevTag.id &&
239
- currentTag.type === prevTag.type &&
240
- currentTag.contextId === prevTag.contextId,
241
- ),
242
- );
243
-
244
- // 清理被删除的 mention_tag 对应的 context
245
- deletedTags.forEach((deletedTag) => {
246
- if (deletedTag.contextId) {
247
- const uri = new URI(deletedTag.contextId);
248
- if (deletedTag.type === MentionType.FILE) {
249
- removeContext(MentionType.FILE, uri);
250
- } else if (deletedTag.type === MentionType.FOLDER) {
251
- removeContext(MentionType.FOLDER, uri);
252
- } else if (deletedTag.type === MentionType.RULE) {
253
- removeContext(MentionType.RULE, uri);
254
- }
255
- }
256
- });
257
-
258
- // 更新 mention_tag 状态
259
- prevMentionTagsRef.current = currentMentionTags;
260
- }
261
-
262
210
  const selection = window.getSelection();
263
211
  if (!selection || !selection.rangeCount || !editorRef.current) {
264
212
  return;
@@ -542,7 +490,7 @@ export const MentionInput: React.FC<MentionInputProps> = ({
542
490
  const imageFiles: File[] = [];
543
491
  // eslint-disable-next-line @typescript-eslint/prefer-for-of
544
492
  for (let i = 0; i < items.length; i++) {
545
- if (items[i].kind === MentionType.FILE && items[i].type.startsWith('image/')) {
493
+ if (items[i].kind === 'file' && items[i].type.startsWith('image/')) {
546
494
  const file = items[i].getAsFile();
547
495
  if (file) {
548
496
  imageFiles.push(file);
@@ -624,16 +572,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
624
572
  if (placeholder && !editorRef.current.textContent) {
625
573
  editorRef.current.setAttribute('data-placeholder', placeholder);
626
574
  }
627
-
628
- // 初始化 mention_tag 状态
629
- const initialMentionTags = Array.from(editorRef.current.querySelectorAll(`.${styles.mention_tag}`)).map(
630
- (tag) => ({
631
- id: tag.getAttribute('data-id') || '',
632
- type: tag.getAttribute('data-type') || '',
633
- contextId: tag.getAttribute('data-context-id') || '',
634
- }),
635
- );
636
- prevMentionTagsRef.current = initialMentionTags;
637
575
  }
638
576
  }, [placeholder]);
639
577
 
@@ -785,11 +723,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
785
723
  true,
786
724
  );
787
725
  }
788
- } else if (item.type === MentionType.RULE) {
789
- const iconSpan = document.createElement('span');
790
- iconSpan.className = cls(styles.mention_icon, getIcon('rules'));
791
- mentionTag.appendChild(iconSpan);
792
- contextService?.addRuleToContext(new URI(item.contextId), true);
793
726
  }
794
727
  const workspace = workspaceService?.workspace;
795
728
  let relativePath = item.text;
@@ -889,12 +822,12 @@ export const MentionInput: React.FC<MentionInputProps> = ({
889
822
  mentionTag.contentEditable = 'false';
890
823
 
891
824
  // 为 file 和 folder 类型添加图标
892
- if (item.type === MentionType.FILE || item.type === 'folder') {
825
+ if (item.type === 'file' || item.type === 'folder') {
893
826
  // 创建图标容器
894
827
  const iconSpan = document.createElement('span');
895
828
  iconSpan.className = cls(
896
829
  styles.mention_icon,
897
- item.type === MentionType.FILE ? labelService?.getIcon(new URI(item.text)) : getIcon('folder'),
830
+ item.type === 'file' ? labelService?.getIcon(new URI(item.text)) : getIcon('folder'),
898
831
  );
899
832
  mentionTag.appendChild(iconSpan);
900
833
  }
@@ -1050,65 +983,6 @@ export const MentionInput: React.FC<MentionInputProps> = ({
1050
983
  contextService?.cleanFileContext();
1051
984
  }, [contextService]);
1052
985
 
1053
- const handleTitleClick = React.useCallback(() => {
1054
- if (!editorRef.current) {
1055
- return;
1056
- }
1057
-
1058
- // 聚焦输入框
1059
- editorRef.current.focus();
1060
-
1061
- // 获取当前光标位置
1062
- const selection = window.getSelection();
1063
- if (!selection) {
1064
- return;
1065
- }
1066
-
1067
- // 在当前位置插入 @ 符号
1068
- const range = document.createRange();
1069
-
1070
- // 如果编辑器为空,直接插入
1071
- if (!editorRef.current.textContent || editorRef.current.textContent.trim() === '') {
1072
- editorRef.current.innerHTML = '@';
1073
- range.setStart(editorRef.current.firstChild || editorRef.current, 1);
1074
- range.setEnd(editorRef.current.firstChild || editorRef.current, 1);
1075
- } else {
1076
- // 当输入框有内容时,总是在末尾插入 @ 符号
1077
- const textNode = document.createTextNode(' @');
1078
-
1079
- // 移动到编辑器末尾
1080
- range.selectNodeContents(editorRef.current);
1081
- range.collapse(false); // 移动到末尾
1082
-
1083
- // 在末尾插入空格和 @ 符号
1084
- range.insertNode(textNode);
1085
- range.setStartAfter(textNode);
1086
- range.setEndAfter(textNode);
1087
- }
1088
-
1089
- // 设置新的光标位置
1090
- selection.removeAllRanges();
1091
- selection.addRange(range);
1092
-
1093
- // 获取插入后的光标位置
1094
- const newCursorPos = getCursorPosition(editorRef.current);
1095
-
1096
- // 激活菜单状态
1097
- setMentionState({
1098
- active: true,
1099
- startPos: newCursorPos,
1100
- filter: '@',
1101
- position: { top: 0, left: 0 },
1102
- activeIndex: 0,
1103
- level: 0,
1104
- parentType: null,
1105
- secondLevelFilter: '',
1106
- inlineSearchActive: false,
1107
- inlineSearchStartPos: null,
1108
- loading: false,
1109
- });
1110
- }, []);
1111
-
1112
986
  const handleStop = React.useCallback(() => {
1113
987
  if (onStop) {
1114
988
  onStop();
@@ -1141,7 +1015,7 @@ export const MentionInput: React.FC<MentionInputProps> = ({
1141
1015
  );
1142
1016
 
1143
1017
  const hasContext = React.useMemo(
1144
- () => attachedFiles.files.length > 0 || attachedFiles.folders.length > 0 || attachedFiles.rules.length > 0,
1018
+ () => attachedFiles.files.length > 0 || attachedFiles.folders.length > 0,
1145
1019
  [attachedFiles],
1146
1020
  );
1147
1021
 
@@ -1163,101 +1037,8 @@ export const MentionInput: React.FC<MentionInputProps> = ({
1163
1037
  [footerConfig.disableModelSelector],
1164
1038
  );
1165
1039
 
1166
- // 转换模型选项为扩展格式
1167
- const getExtendedModelOptions = React.useMemo((): ExtendedModelOption[] => {
1168
- // 如果有扩展模型选项,直接使用
1169
- if (footerConfig.extendedModelOptions) {
1170
- return footerConfig.extendedModelOptions.map((option) => ({
1171
- ...option,
1172
- selected: option.value === selectedModel,
1173
- }));
1174
- }
1175
-
1176
- // 否则从基础模型选项转换
1177
- return (footerConfig.modelOptions || []).map((option): ExtendedModelOption => {
1178
- const extendedOption: ExtendedModelOption = {
1179
- ...option,
1180
- };
1181
-
1182
- // 设置选中状态:如果当前模型匹配选中的模型,则标记为选中
1183
- extendedOption.selected = option.value === selectedModel;
1184
-
1185
- return extendedOption;
1186
- });
1187
- }, [footerConfig.modelOptions, footerConfig.extendedModelOptions, selectedModel]);
1188
-
1189
- const removeContext = React.useCallback(
1190
- (type: MentionType, uri: URI) => {
1191
- if (type === MentionType.FILE) {
1192
- contextService?.removeFileFromContext(uri, true);
1193
- } else if (type === MentionType.FOLDER) {
1194
- contextService?.removeFolderFromContext(uri);
1195
- } else if (type === MentionType.RULE) {
1196
- contextService?.removeRuleFromContext(uri);
1197
- }
1198
- },
1199
- [contextService],
1200
- );
1201
-
1202
- const getFileNameFromPath = (path: string) => decodeURIComponent(path.split('/').pop() || 'Unknown Rule');
1203
-
1204
- const renderContextPreview = React.useCallback(
1205
- () => (
1206
- <div className={styles.context_preview_container}>
1207
- <span
1208
- className={cls(styles.context_preview_title, hasContext && styles.has_context)}
1209
- onClick={handleTitleClick}
1210
- >
1211
- {!hasContext ? localize('aiNative.chat.context.title') : ''}
1212
- </span>
1213
- {attachedFiles.files.map((file, index) => (
1214
- <div key={`file-${index}`} className={styles.context_preview_item} data-type={MentionType.FILE}>
1215
- <Icon
1216
- iconClass={cls(
1217
- labelService?.getIcon(file.uri) || MentionType.FILE,
1218
- styles.context_preview_item_icon,
1219
- styles.icon,
1220
- )}
1221
- />
1222
- <Icon
1223
- iconClass={cls(styles.close_icon, getIcon('close'))}
1224
- onClick={() => removeContext(MentionType.FILE, file.uri)}
1225
- />
1226
- <span className={styles.context_preview_item_text}>{new URI(file.uri.toString()).displayName}</span>
1227
- </div>
1228
- ))}
1229
-
1230
- {attachedFiles.folders.map((folder, index) => (
1231
- <div key={`folder-${index}`} className={styles.context_preview_item} data-type='folder'>
1232
- <Icon iconClass={cls(getIcon('folder'), styles.context_preview_item_icon, styles.icon)} />
1233
- <Icon
1234
- iconClass={cls(styles.close_icon, getIcon('close'))}
1235
- onClick={() => removeContext(MentionType.FOLDER, folder.uri)}
1236
- />
1237
- <span className={styles.context_preview_item_text}>{new URI(folder.uri.toString()).displayName}</span>
1238
- </div>
1239
- ))}
1240
-
1241
- {attachedFiles.rules.map((rule, index) => (
1242
- <div key={`rule-${index}`} className={styles.context_preview_item} data-type='rule'>
1243
- <Icon iconClass={cls(getIcon('rules'), styles.context_preview_item_icon, styles.icon)} />
1244
- <Icon
1245
- iconClass={cls(styles.close_icon, getIcon('close'))}
1246
- onClick={() => removeContext(MentionType.RULE, new URI(rule.path))}
1247
- />
1248
- <span className={styles.context_preview_item_text}>
1249
- {getFileNameFromPath(rule.path).replace('.mdc', '')}
1250
- </span>
1251
- </div>
1252
- ))}
1253
- </div>
1254
- ),
1255
- [handleClearContext, hasContext, attachedFiles, labelService, contextService, handleTitleClick, removeContext],
1256
- );
1257
-
1258
1040
  return (
1259
1041
  <div className={styles.input_container}>
1260
- {renderContextPreview()}
1261
1042
  {mentionState.active && (
1262
1043
  <div className={styles.mention_panel_container}>
1263
1044
  <MentionPanel
@@ -1287,22 +1068,40 @@ export const MentionInput: React.FC<MentionInputProps> = ({
1287
1068
  <div className={styles.left_control}>
1288
1069
  {footerConfig.showModelSelector &&
1289
1070
  renderModelSelectorTip(
1290
- <MentionSelect
1291
- options={getExtendedModelOptions}
1071
+ <Select
1072
+ options={footerConfig.modelOptions || []}
1292
1073
  value={selectedModel}
1293
1074
  onChange={handleModelChange}
1294
1075
  className={styles.model_selector}
1295
1076
  size='small'
1296
1077
  disabled={footerConfig.disableModelSelector}
1297
- showThinking={footerConfig.showThinking}
1298
- thinkingEnabled={footerConfig.thinkingEnabled}
1299
- onThinkingChange={footerConfig.onThinkingChange}
1300
1078
  />,
1301
1079
  )}
1302
1080
  {renderButtons(FooterButtonPosition.LEFT)}
1303
1081
  </div>
1304
1082
  <div className={styles.right_control}>
1305
1083
  {renderButtons(FooterButtonPosition.RIGHT)}
1084
+ {hasContext && (
1085
+ <Popover
1086
+ overlayClassName={styles.popover_icon}
1087
+ id={'ai-chat-clear-context'}
1088
+ position={PopoverPosition.top}
1089
+ content={localize('aiNative.chat.context.clear')}
1090
+ >
1091
+ <div className={styles.context_container} onClick={handleClearContext}>
1092
+ <div className={styles.context_icon}>
1093
+ <Icon icon='out-link' />
1094
+ <Icon icon='close' />
1095
+ </div>
1096
+ <div className={styles.context_description}>
1097
+ {formatLocalize(
1098
+ 'aiNative.chat.context.description',
1099
+ attachedFiles.files.length + attachedFiles.folders.length,
1100
+ )}
1101
+ </div>
1102
+ </div>
1103
+ </Popover>
1104
+ )}
1306
1105
  <Popover
1307
1106
  overlayClassName={styles.popover_icon}
1308
1107
  id={'ai-chat-send'}
@@ -46,30 +46,6 @@ export interface MentionState {
46
46
  interface ModelOption {
47
47
  label: string;
48
48
  value: string;
49
- icon?: string;
50
- iconClass?: string;
51
- tags?: string[];
52
- description?: string;
53
- badge?: string;
54
- badgeColor?: string;
55
- }
56
-
57
- export interface ExtendedModelOption extends ModelOption {
58
- disabled?: boolean;
59
- selected?: boolean; // 由外部控制选中状态
60
- }
61
-
62
- export interface ExtendedModelOption {
63
- label: string;
64
- value: string;
65
- icon?: string;
66
- iconClass?: string;
67
- tags?: string[];
68
- features?: string[];
69
- description?: string;
70
- disabled?: boolean;
71
- badge?: string;
72
- badgeColor?: string;
73
49
  }
74
50
 
75
51
  export enum FooterButtonPosition {
@@ -81,7 +57,6 @@ export enum MentionType {
81
57
  FILE = 'file',
82
58
  FOLDER = 'folder',
83
59
  CODE = 'code',
84
- RULE = 'rule',
85
60
  }
86
61
 
87
62
  interface FooterButton {
@@ -95,14 +70,10 @@ interface FooterButton {
95
70
 
96
71
  export interface FooterConfig {
97
72
  modelOptions?: ModelOption[];
98
- extendedModelOptions?: ExtendedModelOption[];
99
73
  defaultModel?: string;
100
74
  buttons?: FooterButton[];
101
75
  showModelSelector?: boolean;
102
76
  disableModelSelector?: boolean;
103
- showThinking?: boolean;
104
- thinkingEnabled?: boolean;
105
- onThinkingChange?: (enabled: boolean) => void;
106
77
  }
107
78
 
108
79
  export interface MentionInputProps {