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