@opensumi/ide-ai-native 3.9.1-next-1747836538.0 → 3.9.1-next-1747917815.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 (37) hide show
  1. package/lib/browser/components/ChatEditor.js +2 -2
  2. package/lib/browser/components/ChatEditor.js.map +1 -1
  3. package/lib/browser/components/utils.d.ts +2 -2
  4. package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
  5. package/lib/browser/mcp/mcp-server.feature.registry.js +1 -7
  6. package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
  7. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  8. package/lib/browser/mcp/tools/createNewFileWithText.js +5 -10
  9. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  10. package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
  11. package/lib/browser/mcp/tools/fileSearch.js +5 -9
  12. package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
  13. package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
  14. package/lib/browser/mcp/tools/grepSearch.js +10 -22
  15. package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
  16. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts +1 -11
  17. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  18. package/lib/browser/mcp/tools/handlers/RunCommand.js +4 -11
  19. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  20. package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
  21. package/lib/browser/mcp/tools/listDir.js +15 -19
  22. package/lib/browser/mcp/tools/listDir.js.map +1 -1
  23. package/lib/node/mcp-server.sse.d.ts +1 -187
  24. package/lib/node/mcp-server.sse.d.ts.map +1 -1
  25. package/lib/node/mcp-server.sse.js +2 -2
  26. package/lib/node/mcp-server.sse.js.map +1 -1
  27. package/lib/node/mcp-server.stdio.d.ts +1 -187
  28. package/lib/node/mcp-server.stdio.d.ts.map +1 -1
  29. package/package.json +25 -25
  30. package/src/browser/components/ChatEditor.tsx +1 -1
  31. package/src/browser/mcp/mcp-server.feature.registry.ts +1 -6
  32. package/src/browser/mcp/tools/createNewFileWithText.ts +7 -12
  33. package/src/browser/mcp/tools/fileSearch.ts +5 -8
  34. package/src/browser/mcp/tools/grepSearch.ts +21 -32
  35. package/src/browser/mcp/tools/handlers/RunCommand.ts +14 -21
  36. package/src/browser/mcp/tools/listDir.ts +12 -15
  37. package/src/node/mcp-server.sse.ts +2 -1
@@ -25,7 +25,7 @@ import {
25
25
  localize,
26
26
  runWhenIdle,
27
27
  } from '@opensumi/ide-core-common';
28
- import { insertSnippetWithMonacoEditor } from '@opensumi/ide-editor/lib/browser/editor-collection.service';
28
+ import { insertSnippetWithMonacoEditor } from '@opensumi/ide-editor/lib/browser/base-editor-wrapper';
29
29
  import { MonacoCommandRegistry } from '@opensumi/ide-editor/lib/browser/monaco-contrib/command/command.service';
30
30
  import { ITheme, IThemeService } from '@opensumi/ide-theme';
31
31
  import { WorkbenchThemeService } from '@opensumi/ide-theme/lib/browser/workbench.theme.service';
@@ -44,12 +44,7 @@ export class MCPServerRegistry implements IMCPServerRegistry {
44
44
  }
45
45
 
46
46
  registerMCPTool(tool: MCPToolDefinition): void {
47
- const existingIndex = this.tools.findIndex((t) => t.name === tool.name);
48
- if (existingIndex !== -1) {
49
- this.tools[existingIndex] = tool;
50
- } else {
51
- this.tools.push(tool);
52
- }
47
+ this.tools.push(tool);
53
48
  }
54
49
 
55
50
  registerToolComponent(
@@ -10,15 +10,10 @@ import { BaseApplyService } from '../base-apply.service';
10
10
 
11
11
  import { EditFileToolComponent } from './components/EditFile';
12
12
 
13
- const inputSchema = z
14
- .object({
15
- target_file: z.string().describe('The relative path where the file should be created'),
16
- code_edit: z.string().describe('The content to write into the new file'),
17
- })
18
- .transform((data) => ({
19
- targetFile: data.target_file,
20
- codeEdit: data.code_edit,
21
- }));
13
+ const inputSchema = z.object({
14
+ target_file: z.string().describe('The relative path where the file should be created'),
15
+ code_edit: z.string().describe('The content to write into the new file'),
16
+ });
22
17
 
23
18
  @Domain(MCPServerContribution)
24
19
  export class CreateNewFileWithTextTool implements MCPServerContribution {
@@ -67,7 +62,7 @@ export class CreateNewFileWithTextTool implements MCPServerContribution {
67
62
 
68
63
  // 构建完整的文件路径
69
64
  const rootUri = URI.parse(workspaceRoots[0].uri);
70
- const fullPath = path.join(rootUri.codeUri.fsPath, args.targetFile);
65
+ const fullPath = path.join(rootUri.codeUri.fsPath, args.target_file);
71
66
  const fileUri = URI.file(fullPath);
72
67
 
73
68
  // 创建父目录
@@ -79,10 +74,10 @@ export class CreateNewFileWithTextTool implements MCPServerContribution {
79
74
  await this.fileService.createFile(fileUri.toString());
80
75
 
81
76
  // 使用 applyService 写入文件内容
82
- const codeBlock = await this.applyService.registerCodeBlock(args.targetFile, args.codeEdit, args.toolCallId);
77
+ const codeBlock = await this.applyService.registerCodeBlock(args.target_file, args.code_edit, args.toolCallId);
83
78
  await this.applyService.apply(codeBlock);
84
79
 
85
- logger.appendLine(`Successfully created file at: ${args.targetFile}`);
80
+ logger.appendLine(`Successfully created file at: ${args.target_file}`);
86
81
  return {
87
82
  content: [{ type: 'text', text: 'ok' }],
88
83
  };
@@ -80,14 +80,11 @@ export class FileSearchTool implements MCPServerContribution {
80
80
  });
81
81
 
82
82
  const messages = this.chatInternalService.sessionModel.history.getMessages();
83
- const messageId = messages[messages.length - 1]?.id;
84
- if (messageId) {
85
- this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
86
- [args.toolCallId]: {
87
- files,
88
- },
89
- });
90
- }
83
+ this.chatInternalService.sessionModel.history.setMessageAdditional(messages[messages.length - 1].id, {
84
+ [args.toolCallId]: {
85
+ files,
86
+ },
87
+ });
91
88
 
92
89
  logger.appendLine(`Found ${files.length} files matching "${args.query}"`);
93
90
 
@@ -12,27 +12,19 @@ import { IMCPServerRegistry, MCPLogger, MCPServerContribution, MCPToolDefinition
12
12
 
13
13
  import { GrepSearchToolComponent } from './components/ExpandableFileList';
14
14
 
15
- const inputSchema = z
16
- .object({
17
- query: z.string().describe('The regex pattern to search for'),
18
- case_sensitive: z.boolean().optional().describe('Whether the search should be case sensitive'),
19
- include_pattern: z
20
- .string()
21
- .optional()
22
- .describe('Glob pattern for files to include (e.g. "*.ts" for TypeScript files)'),
23
- exclude_pattern: z.string().optional().describe('Glob pattern for files to exclude'),
24
- explanation: z
25
- .string()
26
- .optional()
27
- .describe('One sentence explanation as to why this tool is being used, and how it contributes to the goal.'),
28
- })
29
- .transform((data) => ({
30
- query: data.query,
31
- caseSensitive: data.case_sensitive,
32
- includePattern: data.include_pattern,
33
- excludePattern: data.exclude_pattern,
34
- explanation: data.explanation,
35
- }));
15
+ const inputSchema = z.object({
16
+ query: z.string().describe('The regex pattern to search for'),
17
+ case_sensitive: z.boolean().optional().describe('Whether the search should be case sensitive'),
18
+ include_pattern: z
19
+ .string()
20
+ .optional()
21
+ .describe('Glob pattern for files to include (e.g. "*.ts" for TypeScript files)'),
22
+ exclude_pattern: z.string().optional().describe('Glob pattern for files to exclude'),
23
+ explanation: z
24
+ .string()
25
+ .optional()
26
+ .describe('One sentence explanation as to why this tool is being used, and how it contributes to the goal.'),
27
+ });
36
28
 
37
29
  const MAX_RESULTS = 50;
38
30
 
@@ -80,9 +72,9 @@ export class GrepSearchTool implements MCPServerContribution {
80
72
  await this.searchService.doSearch(
81
73
  searchPattern,
82
74
  {
83
- isMatchCase: !!args.caseSensitive,
84
- include: args.includePattern?.split(','),
85
- exclude: args.excludePattern?.split(','),
75
+ isMatchCase: !!args.case_sensitive,
76
+ include: args.include_pattern?.split(','),
77
+ exclude: args.exclude_pattern?.split(','),
86
78
  maxResults: MAX_RESULTS,
87
79
  isUseRegexp: true,
88
80
  isToggleOpen: false,
@@ -119,14 +111,11 @@ export class GrepSearchTool implements MCPServerContribution {
119
111
  }
120
112
  deferred.resolve(results.join('\n\n'));
121
113
  const messages = this.chatInternalService.sessionModel.history.getMessages();
122
- const messageId = messages[messages.length - 1]?.id;
123
- if (messageId) {
124
- this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
125
- [args.toolCallId]: {
126
- files,
127
- },
128
- });
129
- }
114
+ this.chatInternalService.sessionModel.history.setMessageAdditional(messages[messages.length - 1].id, {
115
+ [args.toolCallId]: {
116
+ files,
117
+ },
118
+ });
130
119
  });
131
120
  const text = await deferred.promise;
132
121
  return {
@@ -13,25 +13,18 @@ const color = {
13
13
  reset: '\x1b[0m',
14
14
  };
15
15
 
16
- export const inputSchema = z
17
- .object({
18
- command: z.string().describe('The terminal command to execute'),
19
- is_background: z.boolean().describe('Whether the command should be run in the background'),
20
- explanation: z
21
- .string()
22
- .describe('One sentence explanation as to why this command needs to be run and how it contributes to the goal.'),
23
- require_user_approval: z
24
- .boolean()
25
- .describe(
26
- "Whether the user must approve the command before it is executed. Only set this to false if the command is safe and if it matches the user's requirements for commands that should be executed automatically.",
27
- ),
28
- })
29
- .transform((data) => ({
30
- command: data.command,
31
- isBackground: data.is_background,
32
- explanation: data.explanation,
33
- requireUserApproval: data.require_user_approval,
34
- }));
16
+ export const inputSchema = z.object({
17
+ command: z.string().describe('The terminal command to execute'),
18
+ is_background: z.boolean().describe('Whether the command should be run in the background'),
19
+ explanation: z
20
+ .string()
21
+ .describe('One sentence explanation as to why this command needs to be run and how it contributes to the goal.'),
22
+ require_user_approval: z
23
+ .boolean()
24
+ .describe(
25
+ "Whether the user must approve the command before it is executed. Only set this to false if the command is safe and if it matches the user's requirements for commands that should be executed automatically.",
26
+ ),
27
+ });
35
28
 
36
29
  @Injectable()
37
30
  export class RunCommandHandler {
@@ -73,7 +66,7 @@ export class RunCommandHandler {
73
66
 
74
67
  async handler(args: z.infer<typeof inputSchema> & { toolCallId: string }, logger: MCPLogger) {
75
68
  logger.appendLine(`Executing command: ${args.command}`);
76
- if (this.isAlwaysApproval(args.requireUserApproval)) {
69
+ if (this.isAlwaysApproval(args.require_user_approval)) {
77
70
  const def = new Deferred<boolean>();
78
71
  this.approvalDeferredMap.set(args.toolCallId, def);
79
72
  const approval = await def.promise;
@@ -100,7 +93,7 @@ export class RunCommandHandler {
100
93
  const result: { type: string; text: string }[] = [];
101
94
  const def = new Deferred<{ isError?: boolean; content: { type: string; text: string }[] }>();
102
95
 
103
- if (args.isBackground) {
96
+ if (args.is_background) {
104
97
  def.resolve({
105
98
  isError: false,
106
99
  content: [{ type: 'text', text: `Successful run command ${args.command} in background.` }],
@@ -63,21 +63,18 @@ export class ListDirTool implements MCPServerContribution {
63
63
 
64
64
  // 设置消息的附加数据
65
65
  const messages = this.chatInternalService.sessionModel.history.getMessages();
66
- const messageId = messages[messages.length - 1]?.id;
67
- if (messageId) {
68
- this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
69
- [args.toolCallId]: {
70
- files: fileUris,
71
- title: `Listed directory "${args.relativeWorkspacePath}"`,
72
- details: result.files.map((file) => ({
73
- type: file.isDirectory ? 'dir' : 'file',
74
- name: file.name,
75
- info: file.isDirectory ? `${file.numChildren ?? '?'} items` : `${file.size}KB, ${file.numLines} lines`,
76
- lastModified: file.lastModified,
77
- })),
78
- },
79
- });
80
- }
66
+ this.chatInternalService.sessionModel.history.setMessageAdditional(messages[messages.length - 1].id, {
67
+ [args.toolCallId]: {
68
+ files: fileUris,
69
+ title: `Listed directory "${args.relativeWorkspacePath}"`,
70
+ details: result.files.map((file) => ({
71
+ type: file.isDirectory ? 'dir' : 'file',
72
+ name: file.name,
73
+ info: file.isDirectory ? `${file.numChildren ?? '?'} items` : `${file.size}KB, ${file.numLines} lines`,
74
+ lastModified: file.lastModified,
75
+ })),
76
+ },
77
+ });
81
78
 
82
79
  logger.appendLine(`Listed ${fileUris.length} files in directory "${args.relativeWorkspacePath}"`);
83
80
 
@@ -1,6 +1,5 @@
1
1
  // have to import with extension since the exports map is ./* -> ./dist/cjs/*
2
2
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
- import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
4
3
  import { EventSource } from 'eventsource';
5
4
 
6
5
  import { ILogger } from '@opensumi/ide-core-common';
@@ -48,6 +47,8 @@ export class SSEMCPServer implements IMCPServer {
48
47
  }
49
48
  this.logger?.log(`Starting server "${this.name}" with url: ${this.url}`);
50
49
 
50
+ const SSEClientTransport = (await import('@modelcontextprotocol/sdk/client/sse.js')).SSEClientTransport;
51
+
51
52
  const transport = new SSEClientTransport(new URL(this.url), this.transportOptions);
52
53
 
53
54
  transport.onerror = (error) => {