@opensumi/ide-ai-native 3.8.1-next-1740478950.0 → 3.8.1-next-1740556231.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 (206) hide show
  1. package/lib/browser/ai-core.contribution.d.ts +4 -1
  2. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contribution.js +23 -11
  4. package/lib/browser/ai-core.contribution.js.map +1 -1
  5. package/lib/browser/chat/chat-manager.service.d.ts +1 -5
  6. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  7. package/lib/browser/chat/chat-manager.service.js +13 -17
  8. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  9. package/lib/browser/chat/chat-model.d.ts +0 -2
  10. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-model.js +2 -8
  12. package/lib/browser/chat/chat-model.js.map +1 -1
  13. package/lib/browser/chat/chat.internal.service.d.ts +1 -0
  14. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.internal.service.js +3 -0
  16. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  17. package/lib/browser/chat/chat.module.less +2 -1
  18. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  19. package/lib/browser/chat/chat.view.js +9 -6
  20. package/lib/browser/chat/chat.view.js.map +1 -1
  21. package/lib/browser/components/ChatContext/index.js +2 -2
  22. package/lib/browser/components/ChatContext/index.js.map +1 -1
  23. package/lib/browser/components/ChatHistory.d.ts +0 -1
  24. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  25. package/lib/browser/components/ChatHistory.js +14 -14
  26. package/lib/browser/components/ChatHistory.js.map +1 -1
  27. package/lib/browser/components/ChatInput.d.ts.map +1 -1
  28. package/lib/browser/components/ChatInput.js +1 -25
  29. package/lib/browser/components/ChatInput.js.map +1 -1
  30. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  31. package/lib/browser/components/ChatToolRender.js +3 -2
  32. package/lib/browser/components/ChatToolRender.js.map +1 -1
  33. package/lib/browser/components/{chat-history.css → chat-history.module.less} +1 -1
  34. package/lib/browser/components/components.module.less +0 -20
  35. package/lib/browser/context/llm-context.service.d.ts +5 -16
  36. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  37. package/lib/browser/context/llm-context.service.js +47 -78
  38. package/lib/browser/context/llm-context.service.js.map +1 -1
  39. package/lib/browser/index.d.ts.map +1 -1
  40. package/lib/browser/index.js +0 -4
  41. package/lib/browser/index.js.map +1 -1
  42. package/lib/browser/layout/layout.module.less +4 -4
  43. package/lib/browser/mcp/base-apply.service.d.ts +31 -40
  44. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  45. package/lib/browser/mcp/base-apply.service.js +233 -167
  46. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  47. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +0 -6
  48. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  49. package/lib/browser/mcp/mcp-server-proxy.service.js +1 -10
  50. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  51. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  52. package/lib/browser/mcp/mcp-server.feature.registry.js +2 -3
  53. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  54. package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
  55. package/lib/browser/mcp/tools/components/EditFile.js +55 -41
  56. package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
  57. package/lib/browser/mcp/tools/components/index.module.less +22 -4
  58. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  59. package/lib/browser/mcp/tools/createNewFileWithText.js +0 -1
  60. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  61. package/lib/browser/mcp/tools/editFile.js +1 -1
  62. package/lib/browser/mcp/tools/editFile.js.map +1 -1
  63. package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
  64. package/lib/browser/mcp/tools/getDiagnosticsByPath.js +0 -1
  65. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  66. package/lib/browser/mcp/tools/handlers/EditFile.d.ts +5 -1
  67. package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -1
  68. package/lib/browser/mcp/tools/handlers/EditFile.js +4 -4
  69. package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
  70. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  71. package/lib/browser/mcp/tools/handlers/RunCommand.js +0 -2
  72. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  73. package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
  74. package/lib/browser/mcp/tools/runTerminalCmd.js +0 -1
  75. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  76. package/lib/browser/model/msg-history-manager.d.ts +1 -0
  77. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  78. package/lib/browser/model/msg-history-manager.js +12 -2
  79. package/lib/browser/model/msg-history-manager.js.map +1 -1
  80. package/lib/browser/preferences/schema.d.ts.map +1 -1
  81. package/lib/browser/preferences/schema.js +0 -16
  82. package/lib/browser/preferences/schema.js.map +1 -1
  83. package/lib/browser/types.d.ts +1 -1
  84. package/lib/browser/types.d.ts.map +1 -1
  85. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts +6 -0
  86. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -0
  87. package/lib/browser/widget/inline-diff/inline-diff-manager.js +27 -0
  88. package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -0
  89. package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +12 -0
  90. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +2 -0
  91. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  92. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +11 -4
  93. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  94. package/lib/common/index.d.ts +1 -8
  95. package/lib/common/index.d.ts.map +1 -1
  96. package/lib/common/index.js +1 -3
  97. package/lib/common/index.js.map +1 -1
  98. package/lib/common/llm-context.d.ts +9 -12
  99. package/lib/common/llm-context.d.ts.map +1 -1
  100. package/lib/common/llm-context.js.map +1 -1
  101. package/lib/common/mcp-server-manager.d.ts +1 -17
  102. package/lib/common/mcp-server-manager.d.ts.map +1 -1
  103. package/lib/common/mcp-server-manager.js.map +1 -1
  104. package/lib/common/prompts/context-prompt-provider.d.ts +3 -2
  105. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  106. package/lib/common/prompts/context-prompt-provider.js +22 -21
  107. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  108. package/lib/common/tool-invocation-registry.d.ts +2 -2
  109. package/lib/common/tool-invocation-registry.d.ts.map +1 -1
  110. package/lib/common/tool-invocation-registry.js +1 -1
  111. package/lib/common/tool-invocation-registry.js.map +1 -1
  112. package/lib/common/types.d.ts +17 -6
  113. package/lib/common/types.d.ts.map +1 -1
  114. package/lib/common/types.js.map +1 -1
  115. package/lib/common/utils.d.ts.map +1 -1
  116. package/lib/common/utils.js +1 -2
  117. package/lib/common/utils.js.map +1 -1
  118. package/lib/node/base-language-model.d.ts +1 -1
  119. package/lib/node/base-language-model.d.ts.map +1 -1
  120. package/lib/node/base-language-model.js +54 -3
  121. package/lib/node/base-language-model.js.map +1 -1
  122. package/lib/node/mcp/sumi-mcp-server.d.ts +3 -17
  123. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  124. package/lib/node/mcp/sumi-mcp-server.js +6 -59
  125. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  126. package/lib/node/mcp-server-manager-impl.d.ts +3 -4
  127. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  128. package/lib/node/mcp-server-manager-impl.js +6 -26
  129. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  130. package/lib/node/mcp-server.d.ts +16 -5
  131. package/lib/node/mcp-server.d.ts.map +1 -1
  132. package/lib/node/mcp-server.js +6 -12
  133. package/lib/node/mcp-server.js.map +1 -1
  134. package/lib/node/openai/openai-language-model.d.ts +3 -4
  135. package/lib/node/openai/openai-language-model.d.ts.map +1 -1
  136. package/lib/node/openai/openai-language-model.js +2 -3
  137. package/lib/node/openai/openai-language-model.js.map +1 -1
  138. package/package.json +27 -27
  139. package/src/browser/ai-core.contribution.ts +29 -14
  140. package/src/browser/chat/chat-manager.service.ts +13 -17
  141. package/src/browser/chat/chat-model.ts +3 -18
  142. package/src/browser/chat/chat.internal.service.ts +4 -0
  143. package/src/browser/chat/chat.module.less +2 -1
  144. package/src/browser/chat/chat.view.tsx +26 -10
  145. package/src/browser/components/ChatContext/index.tsx +2 -2
  146. package/src/browser/components/ChatHistory.tsx +21 -15
  147. package/src/browser/components/ChatInput.tsx +4 -67
  148. package/src/browser/components/ChatToolRender.tsx +2 -1
  149. package/src/browser/components/{chat-history.css → chat-history.module.less} +1 -1
  150. package/src/browser/components/components.module.less +0 -20
  151. package/src/browser/context/llm-context.service.ts +54 -90
  152. package/src/browser/index.ts +0 -4
  153. package/src/browser/layout/layout.module.less +4 -4
  154. package/src/browser/mcp/base-apply.service.ts +266 -213
  155. package/src/browser/mcp/mcp-server-proxy.service.ts +2 -14
  156. package/src/browser/mcp/mcp-server.feature.registry.ts +2 -3
  157. package/src/browser/mcp/tools/components/EditFile.tsx +82 -60
  158. package/src/browser/mcp/tools/components/index.module.less +22 -4
  159. package/src/browser/mcp/tools/createNewFileWithText.ts +0 -1
  160. package/src/browser/mcp/tools/editFile.ts +2 -2
  161. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +0 -1
  162. package/src/browser/mcp/tools/handlers/EditFile.ts +4 -4
  163. package/src/browser/mcp/tools/handlers/RunCommand.ts +0 -2
  164. package/src/browser/mcp/tools/runTerminalCmd.ts +0 -1
  165. package/src/browser/model/msg-history-manager.ts +12 -2
  166. package/src/browser/preferences/schema.ts +0 -16
  167. package/src/browser/types.ts +1 -1
  168. package/src/browser/widget/inline-diff/inline-diff-manager.tsx +38 -0
  169. package/src/browser/widget/inline-diff/inline-diff-widget.module.less +12 -0
  170. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +13 -4
  171. package/src/common/index.ts +1 -7
  172. package/src/common/llm-context.ts +4 -10
  173. package/src/common/mcp-server-manager.ts +1 -17
  174. package/src/common/prompts/context-prompt-provider.ts +28 -26
  175. package/src/common/tool-invocation-registry.ts +2 -2
  176. package/src/common/types.ts +20 -6
  177. package/src/common/utils.ts +1 -3
  178. package/src/node/base-language-model.ts +63 -1
  179. package/src/node/mcp/sumi-mcp-server.ts +9 -67
  180. package/src/node/mcp-server-manager-impl.ts +9 -30
  181. package/src/node/mcp-server.ts +14 -11
  182. package/src/node/openai/openai-language-model.ts +4 -7
  183. package/lib/browser/mcp/config/components/mcp-config.module.less +0 -178
  184. package/lib/browser/mcp/config/components/mcp-config.view.d.ts +0 -3
  185. package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +0 -1
  186. package/lib/browser/mcp/config/components/mcp-config.view.js +0 -150
  187. package/lib/browser/mcp/config/components/mcp-config.view.js.map +0 -1
  188. package/lib/browser/mcp/config/components/mcp-server-form.d.ts +0 -16
  189. package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +0 -1
  190. package/lib/browser/mcp/config/components/mcp-server-form.js +0 -84
  191. package/lib/browser/mcp/config/components/mcp-server-form.js.map +0 -1
  192. package/lib/browser/mcp/config/components/mcp-server-form.module.less +0 -78
  193. package/lib/browser/mcp/config/mcp-config.commands.d.ts +0 -10
  194. package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +0 -1
  195. package/lib/browser/mcp/config/mcp-config.commands.js +0 -35
  196. package/lib/browser/mcp/config/mcp-config.commands.js.map +0 -1
  197. package/lib/browser/mcp/config/mcp-config.contribution.d.ts +0 -16
  198. package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +0 -1
  199. package/lib/browser/mcp/config/mcp-config.contribution.js +0 -62
  200. package/lib/browser/mcp/config/mcp-config.contribution.js.map +0 -1
  201. package/src/browser/mcp/config/components/mcp-config.module.less +0 -178
  202. package/src/browser/mcp/config/components/mcp-config.view.tsx +0 -215
  203. package/src/browser/mcp/config/components/mcp-server-form.module.less +0 -78
  204. package/src/browser/mcp/config/components/mcp-server-form.tsx +0 -144
  205. package/src/browser/mcp/config/mcp-config.commands.ts +0 -29
  206. package/src/browser/mcp/config/mcp-config.contribution.ts +0 -65
@@ -1,5 +1,5 @@
1
1
  import cls from 'classnames';
2
- import React, { useEffect, useMemo } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
 
4
4
  import { Icon, Popover } from '@opensumi/ide-components';
5
5
  import {
@@ -10,7 +10,6 @@ import {
10
10
  Uri,
11
11
  detectModeId,
12
12
  path,
13
- useAutorun,
14
13
  useInjectable,
15
14
  } from '@opensumi/ide-core-browser';
16
15
  import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
@@ -18,61 +17,24 @@ import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/com
18
17
  import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
19
18
  import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
20
19
 
20
+ import { CodeBlockData } from '../../../../common/types';
21
21
  import { ChatMarkdown } from '../../../components/ChatMarkdown';
22
22
  import { IMCPServerToolComponentProps } from '../../../types';
23
- import { BaseApplyService, CodeBlockData } from '../../base-apply.service';
23
+ import { BaseApplyService } from '../../base-apply.service';
24
24
 
25
25
  import styles from './index.module.less';
26
26
 
27
- const renderStatus = (codeBlockData: CodeBlockData) => {
28
- const status = codeBlockData.status;
29
- switch (status) {
30
- case 'generating':
31
- return <Loading />;
32
- case 'pending':
33
- return (
34
- <Popover title={status} id={'edit-file-tool-status-pending'}>
35
- <Icon iconClass='codicon codicon-circle-large' />
36
- </Popover>
37
- );
38
- case 'success':
39
- return (
40
- <Popover title={status} id={'edit-file-tool-status-success'}>
41
- <Icon iconClass='codicon codicon-check-all' />
42
- </Popover>
43
- );
44
- case 'failed':
45
- return (
46
- <Popover title={status} id={'edit-file-tool-status-failed'}>
47
- <Icon iconClass='codicon codicon-error' color='var(--vscode-input-errorForeground)' />
48
- </Popover>
49
- );
50
- case 'cancelled':
51
- return (
52
- <Popover title={status} id={'edit-file-tool-status-cancelled'}>
53
- <Icon iconClass='codicon codicon-close' color='var(--vscode-input-placeholderForeground)' />
54
- </Popover>
55
- );
56
- default:
57
- return null;
58
- }
59
- };
60
-
61
27
  export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
62
28
  const { args, messageId, toolCallId } = props;
29
+ const [mode, setMode] = useState<'code' | 'diff'>('code');
63
30
  const labelService = useInjectable(LabelService);
64
31
  const appConfig = useInjectable<AppConfig>(AppConfig);
65
32
  const applyService = useInjectable<BaseApplyService>(BaseApplyService);
66
33
  const { target_file = '', code_edit, instructions } = args || {};
67
34
  const absolutePath = path.join(appConfig.workspaceDir, target_file);
68
-
69
- const codeBlockData = applyService.getCodeBlock(absolutePath, messageId);
70
-
71
- useAutorun(applyService.codeBlockMapObservable);
72
-
73
- if (toolCallId && codeBlockData) {
74
- applyService.initToolCallId(codeBlockData.id, toolCallId);
75
- }
35
+ const [codeBlockData, setCodeBlockData] = useState<CodeBlockData | undefined>(
36
+ applyService.getCodeBlock(toolCallId, messageId),
37
+ );
76
38
 
77
39
  const icon = useMemo(() => {
78
40
  if (!target_file) {
@@ -91,40 +53,66 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
91
53
  return detectedModeId;
92
54
  }, [target_file, absolutePath]);
93
55
 
56
+ useEffect(() => {
57
+ const disposable = applyService.onCodeBlockUpdate((codeBlockData) => {
58
+ setCodeBlockData({ ...codeBlockData });
59
+ });
60
+ return () => {
61
+ disposable.dispose();
62
+ };
63
+ }, []);
64
+
94
65
  // 多次迭代时,仅在首处tool组件中展示
95
- if (!args || !codeBlockData || (toolCallId && toolCallId !== codeBlockData.initToolCallId)) {
66
+ // FIXME: 这个优化有必要吗?每次都展示也挺好?
67
+ if (!args || !codeBlockData) {
96
68
  return null;
97
69
  }
98
70
 
99
71
  return [
100
72
  instructions && <p>{instructions}</p>,
101
- <div className={styles['edit-file-tool']} key={`edit-file-tool-${codeBlockData.id}`}>
73
+ <div className={styles['edit-file-tool']} key={'edit-file-tool'}>
102
74
  <div
103
75
  className={cls(styles['edit-file-tool-header'], {
104
76
  clickable: codeBlockData.status === 'pending' || codeBlockData.status === 'success',
105
77
  })}
106
78
  onClick={() => {
107
79
  if (codeBlockData.status === 'pending') {
108
- applyService.reRenderPendingApply();
80
+ applyService.renderApplyResult(codeBlockData, codeBlockData.updatedCode!);
109
81
  } else if (codeBlockData.status === 'success') {
110
- applyService.revealApplyPosition(codeBlockData.id);
82
+ applyService.revealApplyPosition(codeBlockData);
111
83
  }
112
84
  }}
113
85
  >
114
- {icon && <span className={icon}></span>}
115
- <span className={styles['edit-file-tool-file-name']}>{target_file}</span>
116
- {codeBlockData.iterationCount > 1 && (
117
- <span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
118
- )}
119
- {renderStatus(codeBlockData)}
86
+ <div className={styles.left}>
87
+ {icon && <span className={icon}></span>}
88
+ <span className={styles['edit-file-tool-file-name']}>{target_file}</span>
89
+ {codeBlockData.iterationCount > 1 && (
90
+ <span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
91
+ )}
92
+ {renderStatus(codeBlockData)}
93
+ </div>
94
+ <div className={styles.right}>
95
+ <Popover title={'Show Code'} id={'edit-file-tool-show-code'}>
96
+ <Icon iconClass='codicon codicon-file-code' onClick={() => setMode('code')} />
97
+ </Popover>
98
+ {codeBlockData.applyResult?.diff && (
99
+ <Popover title={'Show Diff'} id={'edit-file-tool-show-diff'}>
100
+ <Icon iconClass='codicon codicon-diff-multiple' onClick={() => setMode('diff')} />
101
+ </Popover>
102
+ )}
103
+ </div>
120
104
  </div>
121
- <ChatMarkdown markdown={`\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``} hideInsert={true} />
105
+ <ChatMarkdown
106
+ markdown={
107
+ mode === 'code'
108
+ ? `\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``
109
+ : `\`\`\`diff\n${codeBlockData.applyResult?.diff}\n\`\`\``
110
+ }
111
+ hideInsert={true}
112
+ />
122
113
  </div>,
123
114
  codeBlockData.applyResult && codeBlockData.applyResult.diagnosticInfos.length > 0 && (
124
- <div
125
- className={styles['edit-file-tool-diagnostic-errors']}
126
- key={`edit-file-tool-diagnostic-errors-${codeBlockData.id}`}
127
- >
115
+ <div className={styles['edit-file-tool-diagnostic-errors']} key={'edit-file-tool-diagnostic-errors'}>
128
116
  <div className={styles['title']}>Found Lints:</div>
129
117
  {codeBlockData.applyResult?.diagnosticInfos.map((info) => (
130
118
  <div
@@ -142,3 +130,37 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
142
130
  ),
143
131
  ];
144
132
  };
133
+
134
+ const renderStatus = (codeBlockData: CodeBlockData) => {
135
+ const status = codeBlockData.status;
136
+ switch (status) {
137
+ case 'generating':
138
+ return <Loading />;
139
+ case 'pending':
140
+ return (
141
+ <Popover title='Pending' id={'edit-file-tool-status-pending'}>
142
+ <Icon iconClass='codicon codicon-circle-large' />
143
+ </Popover>
144
+ );
145
+ case 'success':
146
+ return (
147
+ <Popover title='Success' id={'edit-file-tool-status-success'}>
148
+ <Icon iconClass='codicon codicon-check-all' />
149
+ </Popover>
150
+ );
151
+ case 'failed':
152
+ return (
153
+ <Popover title='Failed' id={'edit-file-tool-status-failed'}>
154
+ <Icon iconClass='codicon codicon-error' style={{ color: 'var(--debugConsole-errorForeground)' }} />
155
+ </Popover>
156
+ );
157
+ case 'cancelled':
158
+ return (
159
+ <Popover title='Cancelled' id={'edit-file-tool-status-cancelled'}>
160
+ <Icon iconClass='codicon codicon-close' style={{ color: 'var(--input-placeholderForeground)' }} />
161
+ </Popover>
162
+ );
163
+ default:
164
+ return null;
165
+ }
166
+ };
@@ -1,15 +1,14 @@
1
1
  .edit-file-tool-header {
2
2
  display: flex;
3
3
  align-items: center;
4
+ justify-content: space-between;
4
5
  padding: 2px 8px;
5
6
  border-bottom: 1px solid var(--vscode-commandCenter-inactiveBorder);
6
7
  background-color: var(--design-block-background);
7
8
  font-size: 10px;
8
9
  margin-bottom: -4px;
9
10
  border-radius: 8px 8px 0 0;
10
- > span {
11
- margin-right: 4px;
12
- }
11
+ white-space: nowrap;
13
12
  :global(span.codicon) {
14
13
  font-size: 12px;
15
14
  }
@@ -18,6 +17,26 @@
18
17
  align-items: center;
19
18
  justify-content: center;
20
19
  }
20
+ .left,
21
+ .right {
22
+ display: flex;
23
+ align-items: center;
24
+ }
25
+ &::after {
26
+ display: none;
27
+ }
28
+ .left {
29
+ > span {
30
+ margin-right: 4px;
31
+ }
32
+ }
33
+ .right > div {
34
+ margin-left: 4px;
35
+ }
36
+ }
37
+ .edit-file-tool-file-name {
38
+ text-overflow: ellipsis;
39
+ overflow: hidden;
21
40
  }
22
41
  .edit-file-tool {
23
42
  border: 1px solid var(--vscode-commandCenter-inactiveBorder);
@@ -135,7 +154,6 @@
135
154
  background-color: var(--design-chatInput-background);
136
155
  padding: 10px;
137
156
  border-radius: 4px;
138
- margin: 10px 0px;
139
157
 
140
158
  .command_title {
141
159
  display: flex;
@@ -27,7 +27,6 @@ export class CreateNewFileWithTextTool implements MCPServerContribution {
27
27
  getToolDefinition(): MCPToolDefinition {
28
28
  return {
29
29
  name: 'create_new_file_with_text',
30
- label: 'Create File',
31
30
  description:
32
31
  'Creates a new file at the specified path within the project directory and populates it with the provided text. ' +
33
32
  'Use this tool to generate new files in your project structure. ' +
@@ -69,8 +69,8 @@ You should specify the following arguments before the others: [target_file]`,
69
69
  };
70
70
  }
71
71
 
72
- private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
73
- const result = await this.editFileHandler.handler(args.targetFile, args.codeEdit, args.instructions);
72
+ private async handler(args: z.infer<typeof inputSchema> & { toolCallId: string }, logger: MCPLogger) {
73
+ const result = await this.editFileHandler.handler(args, args.toolCallId);
74
74
  return {
75
75
  content: [
76
76
  {
@@ -29,7 +29,6 @@ export class GetDiagnosticsByPathTool implements MCPServerContribution {
29
29
  getToolDefinition(): MCPToolDefinition {
30
30
  return {
31
31
  name: 'get_diagnostics_by_path',
32
- label: 'Get Diagnostics',
33
32
  description:
34
33
  'Retrieves diagnostic information (errors, warnings, etc.) from a specific file in the project. ' +
35
34
  'Use this tool to get information about problems in any project file. ' +
@@ -12,10 +12,10 @@ export class EditFileHandler {
12
12
  @Autowired(BaseApplyService)
13
13
  private applyService: BaseApplyService;
14
14
 
15
- async handler(relativePath: string, updateContent: string, instructions?: string) {
16
- // TODO: ignore file
17
- this.applyService.registerCodeBlock(relativePath, updateContent);
18
- const blockData = await this.applyService.apply(relativePath, updateContent, instructions);
15
+ async handler(params: { targetFile: string; codeEdit: string; instructions?: string }, toolCallId: string) {
16
+ const { targetFile, codeEdit } = params;
17
+ const block = this.applyService.registerCodeBlock(targetFile, codeEdit, toolCallId);
18
+ const blockData = await this.applyService.apply(block);
19
19
  return blockData;
20
20
  }
21
21
  }
@@ -49,7 +49,6 @@ export class RunCommandHandler {
49
49
  }
50
50
 
51
51
  async handler(args: z.infer<typeof inputSchema> & { toolCallId: string }, logger: MCPLogger) {
52
- logger.appendLine(`Executing command: ${args.command}`);
53
52
  if (args.require_user_approval) {
54
53
  const def = new Deferred<boolean>();
55
54
  this.approvalDeferredMap.set(args.toolCallId, def);
@@ -90,7 +89,6 @@ export class RunCommandHandler {
90
89
  content: result,
91
90
  });
92
91
 
93
- logger.appendLine(`Command ${args.command} finished with exit code: ${e.code}`);
94
92
  terminalClient.term.writeln(
95
93
  `\n${color.italic}> Command ${args.command} executed successfully. Terminal will close in ${
96
94
  3000 / 1000
@@ -32,7 +32,6 @@ export class RunTerminalCommandTool implements MCPServerContribution {
32
32
  getToolDefinition(): MCPToolDefinition {
33
33
  return {
34
34
  name: 'run_terminal_cmd',
35
- label: 'Run Command',
36
35
  description:
37
36
  "PROPOSE a command to run on behalf of the user.\nIf you have this tool, note that you DO have the ability to run commands directly on the USER's system.\n\nAdhere to these rules:\n1. Based on the contents of the conversation, you will be told if you are in the same shell as a previous step or a new shell.\n2. If in a new shell, you should `cd` to the right directory and do necessary setup in addition to running the command.\n3. If in the same shell, the state will persist, no need to do things like `cd` to the same directory.\n4. For ANY commands that would use a pager, you should append ` | cat` to the command (or whatever is appropriate). You MUST do this for: git, less, head, tail, more, etc.\n5. For commands that are long running/expected to run indefinitely until interruption, please run them in the background. To run jobs in the background, set `is_background` to true rather than changing the details of the command.\n6. Dont include any newlines in the command.",
38
37
  inputSchema,
@@ -66,6 +66,11 @@ export class MsgHistoryManager extends Disposable {
66
66
  return this.startIndex;
67
67
  }
68
68
 
69
+ public get lastMessageId(): string | undefined {
70
+ const list = this.messageList;
71
+ return list[list.length - 1]?.id;
72
+ }
73
+
69
74
  public getMessages(maxTokens?: number): IHistoryChatMessage[] {
70
75
  if (maxTokens && this.totalTokens > maxTokens) {
71
76
  while (this.totalTokens > maxTokens) {
@@ -109,9 +114,14 @@ export class MsgHistoryManager extends Disposable {
109
114
  return;
110
115
  }
111
116
 
112
- this.messageAdditionalMap.set(id, additional);
117
+ const oldAdditional = this.messageAdditionalMap.get(id) || {};
118
+ const newAdditional = {
119
+ ...oldAdditional,
120
+ ...additional,
121
+ };
113
122
 
114
- this._onMessageAdditionalChange.fire(additional);
123
+ this.messageAdditionalMap.set(id, newAdditional);
124
+ this._onMessageAdditionalChange.fire(newAdditional);
115
125
  }
116
126
 
117
127
  public getMessageAdditional(id: string): Record<string, any> {
@@ -108,27 +108,11 @@ export const aiNativePreferenceSchema: PreferenceSchema = {
108
108
  type: 'string',
109
109
  description: localize('preference.ai.native.mcp.servers.command.description'),
110
110
  },
111
- type: {
112
- type: 'string',
113
- enum: ['stdio', 'sse'],
114
- enumDescriptions: [
115
- localize('preference.ai.native.mcp.servers.type.stdio'),
116
- localize('preference.ai.native.mcp.servers.type.sse'),
117
- ],
118
- description: localize('preference.ai.native.mcp.servers.type.description'),
119
- default: 'stdio',
120
- },
121
- enabled: {
122
- type: 'boolean',
123
- description: localize('preference.ai.native.mcp.servers.enabled.description'),
124
- default: true,
125
- },
126
111
  args: {
127
112
  type: 'array',
128
113
  items: {
129
114
  type: 'string',
130
115
  },
131
- default: [],
132
116
  description: localize('preference.ai.native.mcp.servers.args.description'),
133
117
  },
134
118
  env: {
@@ -368,7 +368,7 @@ export interface IMCPServerToolComponentProps {
368
368
  result?: any;
369
369
  index?: number;
370
370
  messageId?: string;
371
- toolCallId?: string;
371
+ toolCallId: string;
372
372
  }
373
373
 
374
374
  export interface IMCPServerRegistry {
@@ -0,0 +1,38 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ import { Button } from '@opensumi/ide-components';
4
+ import { localize, useInjectable } from '@opensumi/ide-core-browser';
5
+ import { IResource } from '@opensumi/ide-editor';
6
+
7
+ import { BaseApplyService } from '../../mcp/base-apply.service';
8
+
9
+ import styles from './inline-diff-widget.module.less';
10
+
11
+ export const InlineDiffManager: React.FC<{ resource: IResource }> = (props) => {
12
+ const applyService = useInjectable<BaseApplyService>(BaseApplyService);
13
+ const [show, setShow] = useState(true);
14
+ useEffect(() => {
15
+ applyService.onCodeBlockUpdate((codeBlock) => {
16
+ setShow(codeBlock.status === 'pending');
17
+ });
18
+ }, []);
19
+ return (
20
+ <div className={styles.inlineDiffManager} style={{ display: show ? 'flex' : 'none' }}>
21
+ <Button
22
+ onClick={() => {
23
+ applyService.processAll(props.resource.uri, 'accept');
24
+ }}
25
+ >
26
+ {localize('aiNative.inlineDiff.acceptAll')}
27
+ </Button>
28
+ <Button
29
+ type='ghost'
30
+ onClick={() => {
31
+ applyService.processAll(props.resource.uri, 'reject');
32
+ }}
33
+ >
34
+ {localize('aiNative.inlineDiff.rejectAll')}
35
+ </Button>
36
+ </div>
37
+ );
38
+ };
@@ -19,3 +19,15 @@
19
19
  display: flex;
20
20
  position: relative;
21
21
  }
22
+
23
+ .inlineDiffManager {
24
+ display: flex;
25
+ padding: 12px 16px;
26
+ justify-content: center;
27
+ position: absolute;
28
+ bottom: 0;
29
+ left: 50%;
30
+ transform: translateX(-50%);
31
+ gap: 12px;
32
+ z-index: 999;
33
+ }
@@ -52,6 +52,9 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
52
52
  protected readonly _onDidEditChange = this.registerDispose(new Emitter<void>());
53
53
  public readonly onDidEditChange: Event<void> = this._onDidEditChange.event;
54
54
 
55
+ protected readonly onDiffFinishedEmitter = this.registerDispose(new Emitter<IComputeDiffData>());
56
+ public readonly onDiffFinished: Event<IComputeDiffData> = this.onDiffFinishedEmitter.event;
57
+
55
58
  public previewerOptions: IDiffPreviewerOptions;
56
59
 
57
60
  private originalModel: ITextModel;
@@ -445,6 +448,8 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
445
448
  this.diffModel.set(currentDiffModel, tx);
446
449
  });
447
450
 
451
+ this.onDiffFinishedEmitter.fire(currentDiffModel);
452
+
448
453
  if (this.originalModel.id === this.monacoEditor.getModel()?.id) {
449
454
  this.renderDiffEdits(currentDiffModel);
450
455
  }
@@ -471,10 +476,13 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
471
476
  }
472
477
 
473
478
  public pushRateFinallyDiffStack(diffModel: IComputeDiffData): void {
474
- // 可能存在 rate editor controller 处理完之后接口层流式才结束
475
- if (this.isEditing === false) {
476
- this.finallyRender(diffModel);
477
- }
479
+ transaction((tx) => {
480
+ this.finallyDiffModel.set(diffModel, tx);
481
+ // 可能存在 rate editor controller 处理完之后接口层流式才结束
482
+ if (this.isEditing === false) {
483
+ this.finallyRender(diffModel);
484
+ }
485
+ });
478
486
  }
479
487
 
480
488
  public finallyRender(diffModel: IComputeDiffData): void {
@@ -487,6 +495,7 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
487
495
  return;
488
496
  }
489
497
 
498
+ this.onDiffFinishedEmitter.fire(diffModel);
490
499
  this.renderPartialEditWidgets(diffModel);
491
500
  this.renderDiffEdits(diffModel);
492
501
  this.pushStackElement();
@@ -31,9 +31,6 @@ export const AI_CHAT_CONTAINER_ID = 'AI-Chat-Container';
31
31
  export const AI_CHAT_LOGO_AVATAR_ID = 'AI-Chat-Logo-Avatar';
32
32
  export const AI_MENU_BAR_DEBUG_TOOLBAR = 'AI_MENU_BAR_DEBUG_TOOLBAR';
33
33
 
34
- // 内置 MCP 服务器名称
35
- export const BUILTIN_MCP_SERVER_NAME = 'sumi-builtin';
36
-
37
34
  /**
38
35
  * @deprecated Use {@link DESIGN_MENUBAR_CONTAINER_VIEW_ID} instead
39
36
  */
@@ -126,12 +123,9 @@ export const ChatProxyServiceToken = Symbol('ChatProxyServiceToken');
126
123
  export const TokenMCPServerProxyService = Symbol('TokenMCPServerProxyService');
127
124
 
128
125
  export interface ISumiMCPServerBackend {
129
- initBuiltinMCPServer(enabled: boolean): void;
126
+ initBuiltinMCPServer(): void;
130
127
  initExternalMCPServers(servers: MCPServerDescription[]): void;
131
128
  getAllMCPTools(): Promise<MCPTool[]>;
132
- getServers(): Promise<Array<{ name: string; isStarted: boolean }>>;
133
- startServer(serverName: string): Promise<void>;
134
- stopServer(serverName: string): Promise<void>;
135
129
  }
136
130
 
137
131
  export const SumiMCPServerProxyServicePath = 'SumiMCPServerProxyServicePath';
@@ -15,13 +15,13 @@ export interface LLMContextService {
15
15
  */
16
16
  cleanFileContext(): void;
17
17
 
18
- onDidContextFilesChangeEvent: Event<{ viewed: FileContext[]; attached: FileContext[] }>;
18
+ onDidContextFilesChangeEvent: Event<FileContext[]>;
19
19
 
20
20
  /**
21
21
  * 从 context 中移除文件
22
22
  * @param uri URI
23
23
  */
24
- removeFileFromContext(uri: URI, isManual?: boolean): void;
24
+ removeFileFromContext(uri: URI): void;
25
25
 
26
26
  /** 导出为可序列化格式 */
27
27
  serialize(): SerializedContext;
@@ -30,18 +30,12 @@ export interface LLMContextService {
30
30
  export interface FileContext {
31
31
  uri: URI;
32
32
  selection?: [number, number];
33
+ isManual: boolean;
33
34
  }
34
35
 
35
36
  export const LLMContextServiceToken = Symbol('LLMContextService');
36
37
 
37
- export interface AttachFileContext {
38
- content: string;
39
- lineErrors: string[];
40
- path: string;
41
- language: string;
42
- }
43
-
44
38
  export interface SerializedContext {
45
39
  recentlyViewFiles: string[];
46
- attachedFiles: Array<AttachFileContext>;
40
+ attachedFiles: Array<{ content: string; lineErrors: string[]; path: string; language: string }>;
47
41
  }
@@ -1,15 +1,5 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
 
3
- export interface IMCPServer {
4
- isStarted(): boolean;
5
- start(): Promise<void>;
6
- getServerName(): string;
7
- callTool(toolName: string, toolCallId: string, arg_string: string): ReturnType<Client['callTool']>;
8
- getTools(): ReturnType<Client['listTools']>;
9
- update(command: string, args?: string[], env?: { [key: string]: string }): void;
10
- stop(): void;
11
- }
12
-
13
3
  export interface MCPServerManager {
14
4
  callTool(
15
5
  serverName: string,
@@ -21,7 +11,7 @@ export interface MCPServerManager {
21
11
  addOrUpdateServer(description: MCPServerDescription): void;
22
12
  // invoke in node.js only
23
13
  addOrUpdateServerDirectly(server: any): void;
24
- initBuiltinServer(builtinMCPServer: any, enabled: boolean): void;
14
+ initBuiltinServer(builtinMCPServer: any): void;
25
15
  getTools(serverName: string): ReturnType<Client['listTools']>;
26
16
  getServerNames(): Promise<string[]>;
27
17
  startServer(serverName: string): Promise<void>;
@@ -29,7 +19,6 @@ export interface MCPServerManager {
29
19
  getStartedServers(): Promise<string[]>;
30
20
  registerTools(serverName: string): Promise<void>;
31
21
  addExternalMCPServers(servers: MCPServerDescription[]): void;
32
- getServers(): Map<string, IMCPServer>;
33
22
  }
34
23
 
35
24
  export type MCPTool = Awaited<ReturnType<MCPServerManager['getTools']>>['tools'][number];
@@ -56,11 +45,6 @@ export interface MCPServerDescription {
56
45
  * Optional environment variables to set when starting the server.
57
46
  */
58
47
  env?: { [key: string]: string };
59
-
60
- /**
61
- * Whether to enable the MCP server.
62
- */
63
- enabled?: boolean;
64
48
  }
65
49
 
66
50
  export const MCPServerManager = Symbol('MCPServerManager');