@opensumi/ide-ai-native 3.8.1-next-1740556231.0 → 3.8.1-next-1740571693.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 (182) hide show
  1. package/lib/browser/ai-core.contextkeys.d.ts +1 -1
  2. package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contextkeys.js +1 -1
  4. package/lib/browser/ai-core.contextkeys.js.map +1 -1
  5. package/lib/browser/ai-core.contribution.d.ts +1 -4
  6. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  7. package/lib/browser/ai-core.contribution.js +11 -23
  8. package/lib/browser/ai-core.contribution.js.map +1 -1
  9. package/lib/browser/chat/chat-manager.service.d.ts +0 -1
  10. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-manager.service.js +0 -13
  12. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  13. package/lib/browser/chat/chat.internal.service.d.ts +0 -1
  14. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.internal.service.js +0 -3
  16. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  17. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  18. package/lib/browser/chat/chat.view.js +30 -1
  19. package/lib/browser/chat/chat.view.js.map +1 -1
  20. package/lib/browser/components/ChatHistory.d.ts +1 -0
  21. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  22. package/lib/browser/components/ChatHistory.js +14 -14
  23. package/lib/browser/components/ChatHistory.js.map +1 -1
  24. package/lib/browser/contrib/inline-completions/inline-completions.controller.js +1 -1
  25. package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -1
  26. package/lib/browser/contrib/intelligent-completions/index.d.ts +2 -1
  27. package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
  28. package/lib/browser/contrib/intelligent-completions/index.js +4 -1
  29. package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
  30. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +2 -2
  31. package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
  32. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
  33. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +5 -4
  34. package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
  35. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.d.ts.map +1 -1
  36. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js +4 -2
  37. package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js.map +1 -1
  38. package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
  39. package/lib/browser/contrib/intelligent-completions/view/default.js +17 -11
  40. package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
  41. package/lib/browser/index.d.ts.map +1 -1
  42. package/lib/browser/index.js +4 -0
  43. package/lib/browser/index.js.map +1 -1
  44. package/lib/browser/mcp/base-apply.service.d.ts +40 -31
  45. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  46. package/lib/browser/mcp/base-apply.service.js +167 -233
  47. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  48. package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
  49. package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
  50. package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
  51. package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
  52. package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
  53. package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
  54. package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
  55. package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
  56. package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
  57. package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  58. package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
  59. package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
  60. package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
  61. package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
  62. package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
  63. package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
  64. package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
  65. package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
  66. package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
  67. package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
  68. package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
  69. package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
  70. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  71. package/lib/browser/mcp/mcp-server.feature.registry.js +3 -2
  72. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  73. package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
  74. package/lib/browser/mcp/tools/components/EditFile.js +41 -55
  75. package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
  76. package/lib/browser/mcp/tools/components/index.module.less +3 -22
  77. package/lib/browser/mcp/tools/editFile.js +1 -1
  78. package/lib/browser/mcp/tools/editFile.js.map +1 -1
  79. package/lib/browser/mcp/tools/handlers/EditFile.d.ts +1 -5
  80. package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -1
  81. package/lib/browser/mcp/tools/handlers/EditFile.js +4 -4
  82. package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
  83. package/lib/browser/model/msg-history-manager.d.ts +0 -1
  84. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  85. package/lib/browser/model/msg-history-manager.js +2 -12
  86. package/lib/browser/model/msg-history-manager.js.map +1 -1
  87. package/lib/browser/preferences/schema.d.ts.map +1 -1
  88. package/lib/browser/preferences/schema.js +16 -0
  89. package/lib/browser/preferences/schema.js.map +1 -1
  90. package/lib/browser/types.d.ts +1 -1
  91. package/lib/browser/types.d.ts.map +1 -1
  92. package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +0 -12
  93. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +0 -2
  94. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  95. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +4 -11
  96. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  97. package/lib/common/index.d.ts +8 -1
  98. package/lib/common/index.d.ts.map +1 -1
  99. package/lib/common/index.js +3 -1
  100. package/lib/common/index.js.map +1 -1
  101. package/lib/common/mcp-server-manager.d.ts +17 -1
  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/tool-invocation-registry.d.ts +2 -2
  105. package/lib/common/tool-invocation-registry.d.ts.map +1 -1
  106. package/lib/common/tool-invocation-registry.js +1 -1
  107. package/lib/common/tool-invocation-registry.js.map +1 -1
  108. package/lib/common/types.d.ts +6 -17
  109. package/lib/common/types.d.ts.map +1 -1
  110. package/lib/common/types.js.map +1 -1
  111. package/lib/common/utils.d.ts.map +1 -1
  112. package/lib/common/utils.js +2 -1
  113. package/lib/common/utils.js.map +1 -1
  114. package/lib/node/base-language-model.d.ts +1 -1
  115. package/lib/node/base-language-model.d.ts.map +1 -1
  116. package/lib/node/base-language-model.js +8 -58
  117. package/lib/node/base-language-model.js.map +1 -1
  118. package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
  119. package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
  120. package/lib/node/mcp/sumi-mcp-server.js +59 -6
  121. package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
  122. package/lib/node/mcp-server-manager-impl.d.ts +4 -3
  123. package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
  124. package/lib/node/mcp-server-manager-impl.js +26 -6
  125. package/lib/node/mcp-server-manager-impl.js.map +1 -1
  126. package/lib/node/mcp-server.d.ts +5 -16
  127. package/lib/node/mcp-server.d.ts.map +1 -1
  128. package/lib/node/mcp-server.js +12 -6
  129. package/lib/node/mcp-server.js.map +1 -1
  130. package/lib/node/openai/openai-language-model.d.ts +4 -3
  131. package/lib/node/openai/openai-language-model.d.ts.map +1 -1
  132. package/lib/node/openai/openai-language-model.js +3 -2
  133. package/lib/node/openai/openai-language-model.js.map +1 -1
  134. package/package.json +27 -27
  135. package/src/browser/ai-core.contextkeys.ts +3 -3
  136. package/src/browser/ai-core.contribution.ts +14 -29
  137. package/src/browser/chat/chat-manager.service.ts +0 -12
  138. package/src/browser/chat/chat.internal.service.ts +0 -4
  139. package/src/browser/chat/chat.view.tsx +47 -0
  140. package/src/browser/components/ChatHistory.tsx +15 -21
  141. package/src/browser/contrib/inline-completions/inline-completions.controller.ts +1 -1
  142. package/src/browser/contrib/intelligent-completions/index.ts +5 -1
  143. package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +3 -3
  144. package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +6 -5
  145. package/src/browser/contrib/intelligent-completions/view/code-edits-previewer.ts +4 -2
  146. package/src/browser/contrib/intelligent-completions/view/default.ts +27 -19
  147. package/src/browser/index.ts +4 -0
  148. package/src/browser/mcp/base-apply.service.ts +213 -266
  149. package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
  150. package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
  151. package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
  152. package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
  153. package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
  154. package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
  155. package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
  156. package/src/browser/mcp/mcp-server.feature.registry.ts +3 -2
  157. package/src/browser/mcp/tools/components/EditFile.tsx +60 -82
  158. package/src/browser/mcp/tools/components/index.module.less +3 -22
  159. package/src/browser/mcp/tools/editFile.ts +2 -2
  160. package/src/browser/mcp/tools/handlers/EditFile.ts +4 -4
  161. package/src/browser/model/msg-history-manager.ts +2 -12
  162. package/src/browser/preferences/schema.ts +16 -0
  163. package/src/browser/types.ts +1 -1
  164. package/src/browser/widget/inline-diff/inline-diff-widget.module.less +0 -12
  165. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -13
  166. package/src/common/index.ts +7 -1
  167. package/src/common/mcp-server-manager.ts +17 -1
  168. package/src/common/tool-invocation-registry.ts +2 -2
  169. package/src/common/types.ts +6 -20
  170. package/src/common/utils.ts +3 -1
  171. package/src/node/base-language-model.ts +8 -67
  172. package/src/node/mcp/sumi-mcp-server.ts +67 -9
  173. package/src/node/mcp-server-manager-impl.ts +30 -9
  174. package/src/node/mcp-server.ts +11 -14
  175. package/src/node/openai/openai-language-model.ts +7 -4
  176. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts +0 -6
  177. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +0 -1
  178. package/lib/browser/widget/inline-diff/inline-diff-manager.js +0 -27
  179. package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +0 -1
  180. package/src/browser/widget/inline-diff/inline-diff-manager.tsx +0 -38
  181. /package/lib/browser/components/{chat-history.module.less → chat-history.css} +0 -0
  182. /package/src/browser/components/{chat-history.module.less → chat-history.css} +0 -0
@@ -4,7 +4,7 @@ import { Autowired, Injectable } from '@opensumi/di';
4
4
  import { ILogger } from '@opensumi/ide-core-browser';
5
5
  import { Emitter, Event } from '@opensumi/ide-core-common';
6
6
 
7
- import { ISumiMCPServerBackend, SumiMCPServerProxyServicePath } from '../../common';
7
+ import { BUILTIN_MCP_SERVER_NAME, ISumiMCPServerBackend, SumiMCPServerProxyServicePath } from '../../common';
8
8
  import { IMCPServerProxyService } from '../../common/types';
9
9
  import { IMCPServerRegistry, TokenMCPServerRegistry } from '../types';
10
10
 
@@ -35,7 +35,7 @@ export class MCPServerProxyService implements IMCPServerProxyService {
35
35
  name: tool.name,
36
36
  description: tool.description,
37
37
  inputSchema: zodToJsonSchema(tool.inputSchema),
38
- providerName: 'sumi-builtin',
38
+ providerName: BUILTIN_MCP_SERVER_NAME,
39
39
  }),
40
40
  );
41
41
 
@@ -52,4 +52,16 @@ export class MCPServerProxyService implements IMCPServerProxyService {
52
52
  async getAllMCPTools() {
53
53
  return this.sumiMCPServerProxyService.getAllMCPTools();
54
54
  }
55
+
56
+ async $getServers() {
57
+ return this.sumiMCPServerProxyService.getServers();
58
+ }
59
+
60
+ async $startServer(serverName: string) {
61
+ await this.sumiMCPServerProxyService.startServer(serverName);
62
+ }
63
+
64
+ async $stopServer(serverName: string) {
65
+ await this.sumiMCPServerProxyService.stopServer(serverName);
66
+ }
55
67
  }
@@ -2,6 +2,7 @@
2
2
  import { Autowired, Injectable } from '@opensumi/di';
3
3
  import { ILogger } from '@opensumi/ide-core-common';
4
4
 
5
+ import { BUILTIN_MCP_SERVER_NAME } from '../../common';
5
6
  import { getToolName } from '../../common/utils';
6
7
  import { IMCPServerRegistry, IMCPServerToolComponentProps, MCPLogger, MCPToolDefinition } from '../types';
7
8
 
@@ -25,7 +26,7 @@ export class MCPServerRegistry implements IMCPServerRegistry {
25
26
  return new LoggerAdapter(this.baseLogger);
26
27
  }
27
28
 
28
- getMCPTool(name: string, serverName = 'sumi-builtin'): MCPToolDefinition | undefined {
29
+ getMCPTool(name: string, serverName = BUILTIN_MCP_SERVER_NAME): MCPToolDefinition | undefined {
29
30
  return this.tools.find((tool) => getToolName(tool.name, serverName) === name);
30
31
  }
31
32
 
@@ -36,7 +37,7 @@ export class MCPServerRegistry implements IMCPServerRegistry {
36
37
  registerToolComponent(
37
38
  name: string,
38
39
  component: React.FC<IMCPServerToolComponentProps>,
39
- serverName = 'sumi-builtin',
40
+ serverName = BUILTIN_MCP_SERVER_NAME,
40
41
  ): void {
41
42
  this.toolComponents[getToolName(name, serverName)] = component;
42
43
  }
@@ -1,5 +1,5 @@
1
1
  import cls from 'classnames';
2
- import React, { useEffect, useMemo, useState } from 'react';
2
+ import React, { useEffect, useMemo } from 'react';
3
3
 
4
4
  import { Icon, Popover } from '@opensumi/ide-components';
5
5
  import {
@@ -10,6 +10,7 @@ import {
10
10
  Uri,
11
11
  detectModeId,
12
12
  path,
13
+ useAutorun,
13
14
  useInjectable,
14
15
  } from '@opensumi/ide-core-browser';
15
16
  import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
@@ -17,24 +18,61 @@ import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/com
17
18
  import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
18
19
  import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
19
20
 
20
- import { CodeBlockData } from '../../../../common/types';
21
21
  import { ChatMarkdown } from '../../../components/ChatMarkdown';
22
22
  import { IMCPServerToolComponentProps } from '../../../types';
23
- import { BaseApplyService } from '../../base-apply.service';
23
+ import { BaseApplyService, CodeBlockData } 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
+
27
61
  export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
28
62
  const { args, messageId, toolCallId } = props;
29
- const [mode, setMode] = useState<'code' | 'diff'>('code');
30
63
  const labelService = useInjectable(LabelService);
31
64
  const appConfig = useInjectable<AppConfig>(AppConfig);
32
65
  const applyService = useInjectable<BaseApplyService>(BaseApplyService);
33
66
  const { target_file = '', code_edit, instructions } = args || {};
34
67
  const absolutePath = path.join(appConfig.workspaceDir, target_file);
35
- const [codeBlockData, setCodeBlockData] = useState<CodeBlockData | undefined>(
36
- applyService.getCodeBlock(toolCallId, messageId),
37
- );
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
+ }
38
76
 
39
77
  const icon = useMemo(() => {
40
78
  if (!target_file) {
@@ -53,66 +91,40 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
53
91
  return detectedModeId;
54
92
  }, [target_file, absolutePath]);
55
93
 
56
- useEffect(() => {
57
- const disposable = applyService.onCodeBlockUpdate((codeBlockData) => {
58
- setCodeBlockData({ ...codeBlockData });
59
- });
60
- return () => {
61
- disposable.dispose();
62
- };
63
- }, []);
64
-
65
94
  // 多次迭代时,仅在首处tool组件中展示
66
- // FIXME: 这个优化有必要吗?每次都展示也挺好?
67
- if (!args || !codeBlockData) {
95
+ if (!args || !codeBlockData || (toolCallId && toolCallId !== codeBlockData.initToolCallId)) {
68
96
  return null;
69
97
  }
70
98
 
71
99
  return [
72
100
  instructions && <p>{instructions}</p>,
73
- <div className={styles['edit-file-tool']} key={'edit-file-tool'}>
101
+ <div className={styles['edit-file-tool']} key={`edit-file-tool-${codeBlockData.id}`}>
74
102
  <div
75
103
  className={cls(styles['edit-file-tool-header'], {
76
104
  clickable: codeBlockData.status === 'pending' || codeBlockData.status === 'success',
77
105
  })}
78
106
  onClick={() => {
79
107
  if (codeBlockData.status === 'pending') {
80
- applyService.renderApplyResult(codeBlockData, codeBlockData.updatedCode!);
108
+ applyService.reRenderPendingApply();
81
109
  } else if (codeBlockData.status === 'success') {
82
- applyService.revealApplyPosition(codeBlockData);
110
+ applyService.revealApplyPosition(codeBlockData.id);
83
111
  }
84
112
  }}
85
113
  >
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>
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)}
104
120
  </div>
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
- />
121
+ <ChatMarkdown markdown={`\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``} hideInsert={true} />
113
122
  </div>,
114
123
  codeBlockData.applyResult && codeBlockData.applyResult.diagnosticInfos.length > 0 && (
115
- <div className={styles['edit-file-tool-diagnostic-errors']} key={'edit-file-tool-diagnostic-errors'}>
124
+ <div
125
+ className={styles['edit-file-tool-diagnostic-errors']}
126
+ key={`edit-file-tool-diagnostic-errors-${codeBlockData.id}`}
127
+ >
116
128
  <div className={styles['title']}>Found Lints:</div>
117
129
  {codeBlockData.applyResult?.diagnosticInfos.map((info) => (
118
130
  <div
@@ -130,37 +142,3 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
130
142
  ),
131
143
  ];
132
144
  };
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,14 +1,15 @@
1
1
  .edit-file-tool-header {
2
2
  display: flex;
3
3
  align-items: center;
4
- justify-content: space-between;
5
4
  padding: 2px 8px;
6
5
  border-bottom: 1px solid var(--vscode-commandCenter-inactiveBorder);
7
6
  background-color: var(--design-block-background);
8
7
  font-size: 10px;
9
8
  margin-bottom: -4px;
10
9
  border-radius: 8px 8px 0 0;
11
- white-space: nowrap;
10
+ > span {
11
+ margin-right: 4px;
12
+ }
12
13
  :global(span.codicon) {
13
14
  font-size: 12px;
14
15
  }
@@ -17,26 +18,6 @@
17
18
  align-items: center;
18
19
  justify-content: center;
19
20
  }
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;
40
21
  }
41
22
  .edit-file-tool {
42
23
  border: 1px solid var(--vscode-commandCenter-inactiveBorder);
@@ -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> & { toolCallId: string }, logger: MCPLogger) {
73
- const result = await this.editFileHandler.handler(args, args.toolCallId);
72
+ private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
73
+ const result = await this.editFileHandler.handler(args.targetFile, args.codeEdit, args.instructions);
74
74
  return {
75
75
  content: [
76
76
  {
@@ -12,10 +12,10 @@ export class EditFileHandler {
12
12
  @Autowired(BaseApplyService)
13
13
  private applyService: BaseApplyService;
14
14
 
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);
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);
19
19
  return blockData;
20
20
  }
21
21
  }
@@ -66,11 +66,6 @@ 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
-
74
69
  public getMessages(maxTokens?: number): IHistoryChatMessage[] {
75
70
  if (maxTokens && this.totalTokens > maxTokens) {
76
71
  while (this.totalTokens > maxTokens) {
@@ -114,14 +109,9 @@ export class MsgHistoryManager extends Disposable {
114
109
  return;
115
110
  }
116
111
 
117
- const oldAdditional = this.messageAdditionalMap.get(id) || {};
118
- const newAdditional = {
119
- ...oldAdditional,
120
- ...additional,
121
- };
112
+ this.messageAdditionalMap.set(id, additional);
122
113
 
123
- this.messageAdditionalMap.set(id, newAdditional);
124
- this._onMessageAdditionalChange.fire(newAdditional);
114
+ this._onMessageAdditionalChange.fire(additional);
125
115
  }
126
116
 
127
117
  public getMessageAdditional(id: string): Record<string, any> {
@@ -108,11 +108,27 @@ 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
+ },
111
126
  args: {
112
127
  type: 'array',
113
128
  items: {
114
129
  type: 'string',
115
130
  },
131
+ default: [],
116
132
  description: localize('preference.ai.native.mcp.servers.args.description'),
117
133
  },
118
134
  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 {
@@ -19,15 +19,3 @@
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,9 +52,6 @@ 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
-
58
55
  public previewerOptions: IDiffPreviewerOptions;
59
56
 
60
57
  private originalModel: ITextModel;
@@ -448,8 +445,6 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
448
445
  this.diffModel.set(currentDiffModel, tx);
449
446
  });
450
447
 
451
- this.onDiffFinishedEmitter.fire(currentDiffModel);
452
-
453
448
  if (this.originalModel.id === this.monacoEditor.getModel()?.id) {
454
449
  this.renderDiffEdits(currentDiffModel);
455
450
  }
@@ -476,13 +471,10 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
476
471
  }
477
472
 
478
473
  public pushRateFinallyDiffStack(diffModel: IComputeDiffData): void {
479
- transaction((tx) => {
480
- this.finallyDiffModel.set(diffModel, tx);
481
- // 可能存在 rate editor controller 处理完之后接口层流式才结束
482
- if (this.isEditing === false) {
483
- this.finallyRender(diffModel);
484
- }
485
- });
474
+ // 可能存在 rate editor controller 处理完之后接口层流式才结束
475
+ if (this.isEditing === false) {
476
+ this.finallyRender(diffModel);
477
+ }
486
478
  }
487
479
 
488
480
  public finallyRender(diffModel: IComputeDiffData): void {
@@ -495,7 +487,6 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
495
487
  return;
496
488
  }
497
489
 
498
- this.onDiffFinishedEmitter.fire(diffModel);
499
490
  this.renderPartialEditWidgets(diffModel);
500
491
  this.renderDiffEdits(diffModel);
501
492
  this.pushStackElement();
@@ -31,6 +31,9 @@ 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
+
34
37
  /**
35
38
  * @deprecated Use {@link DESIGN_MENUBAR_CONTAINER_VIEW_ID} instead
36
39
  */
@@ -123,9 +126,12 @@ export const ChatProxyServiceToken = Symbol('ChatProxyServiceToken');
123
126
  export const TokenMCPServerProxyService = Symbol('TokenMCPServerProxyService');
124
127
 
125
128
  export interface ISumiMCPServerBackend {
126
- initBuiltinMCPServer(): void;
129
+ initBuiltinMCPServer(enabled: boolean): void;
127
130
  initExternalMCPServers(servers: MCPServerDescription[]): void;
128
131
  getAllMCPTools(): Promise<MCPTool[]>;
132
+ getServers(): Promise<Array<{ name: string; isStarted: boolean }>>;
133
+ startServer(serverName: string): Promise<void>;
134
+ stopServer(serverName: string): Promise<void>;
129
135
  }
130
136
 
131
137
  export const SumiMCPServerProxyServicePath = 'SumiMCPServerProxyServicePath';
@@ -1,5 +1,15 @@
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
+
3
13
  export interface MCPServerManager {
4
14
  callTool(
5
15
  serverName: string,
@@ -11,7 +21,7 @@ export interface MCPServerManager {
11
21
  addOrUpdateServer(description: MCPServerDescription): void;
12
22
  // invoke in node.js only
13
23
  addOrUpdateServerDirectly(server: any): void;
14
- initBuiltinServer(builtinMCPServer: any): void;
24
+ initBuiltinServer(builtinMCPServer: any, enabled: boolean): void;
15
25
  getTools(serverName: string): ReturnType<Client['listTools']>;
16
26
  getServerNames(): Promise<string[]>;
17
27
  startServer(serverName: string): Promise<void>;
@@ -19,6 +29,7 @@ export interface MCPServerManager {
19
29
  getStartedServers(): Promise<string[]>;
20
30
  registerTools(serverName: string): Promise<void>;
21
31
  addExternalMCPServers(servers: MCPServerDescription[]): void;
32
+ getServers(): Map<string, IMCPServer>;
22
33
  }
23
34
 
24
35
  export type MCPTool = Awaited<ReturnType<MCPServerManager['getTools']>>['tools'][number];
@@ -45,6 +56,11 @@ export interface MCPServerDescription {
45
56
  * Optional environment variables to set when starting the server.
46
57
  */
47
58
  env?: { [key: string]: string };
59
+
60
+ /**
61
+ * Whether to enable the MCP server.
62
+ */
63
+ enabled?: boolean;
48
64
  }
49
65
 
50
66
  export const MCPServerManager = Symbol('MCPServerManager');
@@ -72,7 +72,7 @@ export interface ToolInvocationRegistry {
72
72
  *
73
73
  * @param providerName - 要移除其工具的工具提供者名称(在 `ToolRequest` 中指定)
74
74
  */
75
- unregisterAllTools(providerName: string): void;
75
+ unregisterProviderTools(providerName: string): void;
76
76
  }
77
77
 
78
78
  export const ToolProvider = Symbol('ToolProvider');
@@ -83,7 +83,7 @@ export interface ToolProvider {
83
83
  export class ToolInvocationRegistryImpl implements ToolInvocationRegistry {
84
84
  private tools: Map<string, ToolRequest> = new Map<string, ToolRequest>();
85
85
 
86
- unregisterAllTools(providerName: string): void {
86
+ unregisterProviderTools(providerName: string): void {
87
87
  const toolsToRemove: string[] = [];
88
88
  for (const [id, tool] of this.tools.entries()) {
89
89
  if (tool.providerName === providerName) {
@@ -1,5 +1,3 @@
1
- import { IMarker } from '@opensumi/ide-core-browser';
2
-
3
1
  export enum NearestCodeBlockType {
4
2
  Block = 'block',
5
3
  Line = 'line',
@@ -34,6 +32,12 @@ export interface IMCPServerProxyService {
34
32
  $getMCPTools(): Promise<MCPTool[]>;
35
33
  // 通知前端 MCP 服务注册表发生了变化
36
34
  $updateMCPServers(): Promise<void>;
35
+ // 获取所有 MCP 服务器列表
36
+ $getServers(): Promise<Array<{ name: string; isStarted: boolean }>>;
37
+ // 启动指定的 MCP 服务器
38
+ $startServer(serverName: string): Promise<void>;
39
+ // 停止指定的 MCP 服务器
40
+ $stopServer(serverName: string): Promise<void>;
37
41
  }
38
42
 
39
43
  export interface MCPTool {
@@ -42,21 +46,3 @@ export interface MCPTool {
42
46
  inputSchema: any;
43
47
  providerName: string;
44
48
  }
45
-
46
- export interface CodeBlockData {
47
- toolCallId: string;
48
- codeEdit: string;
49
- updatedCode?: string;
50
- relativePath: string;
51
- status: CodeBlockStatus;
52
- iterationCount: number;
53
- createdAt: number;
54
- version: number;
55
- instructions?: string;
56
- applyResult?: {
57
- diff: string;
58
- diagnosticInfos: IMarker[];
59
- };
60
- }
61
-
62
- export type CodeBlockStatus = 'generating' | 'pending' | 'success' | 'rejected' | 'failed' | 'cancelled';
@@ -1,5 +1,7 @@
1
1
  import { IEditorDocumentModel } from '@opensumi/ide-editor';
2
2
 
3
+ import { BUILTIN_MCP_SERVER_NAME } from './index';
4
+
3
5
  const BACK_QUOTE_3_SYMBOL = '```';
4
6
  const MIN_PROMPT_CHARS = 10;
5
7
 
@@ -49,4 +51,4 @@ export const extractCodeBlocks = (content: string): string => {
49
51
  return newContents.join('\n');
50
52
  };
51
53
 
52
- export const getToolName = (toolName: string, serverName = 'sumi-builtin') => `mcp_${serverName}_${toolName}`;
54
+ export const getToolName = (toolName: string, serverName = BUILTIN_MCP_SERVER_NAME) => `mcp_${serverName}_${toolName}`;