@opensumi/ide-ai-native 3.7.2-next-1740066619.0 → 3.7.2-next-1740107209.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.
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +4 -0
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-agent.service.js +6 -0
- package/lib/browser/chat/chat-agent.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +5 -23
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +1 -0
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +8 -1
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.internal.service.d.ts +4 -0
- package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
- package/lib/browser/chat/chat.internal.service.js +10 -1
- package/lib/browser/chat/chat.internal.service.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +2 -2
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatEditor.d.ts +1 -0
- package/lib/browser/components/ChatEditor.d.ts.map +1 -1
- package/lib/browser/components/ChatEditor.js +3 -3
- package/lib/browser/components/ChatEditor.js.map +1 -1
- package/lib/browser/components/ChatMarkdown.d.ts +1 -0
- package/lib/browser/components/ChatMarkdown.d.ts.map +1 -1
- package/lib/browser/components/ChatMarkdown.js +2 -2
- package/lib/browser/components/ChatMarkdown.js.map +1 -1
- package/lib/browser/components/ChatReply.d.ts.map +1 -1
- package/lib/browser/components/ChatReply.js +6 -8
- package/lib/browser/components/ChatReply.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts +2 -1
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +40 -19
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/components.module.less +3 -2
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +7 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +67 -0
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -0
- package/lib/browser/mcp/base-apply.service.js +290 -0
- package/lib/browser/mcp/base-apply.service.js.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +2 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts +5 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +15 -0
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.d.ts +3 -0
- package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/components/EditFile.js +101 -0
- package/lib/browser/mcp/tools/components/EditFile.js.map +1 -0
- package/lib/browser/mcp/tools/components/index.module.less +67 -0
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.js +1 -2
- package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
- package/lib/browser/mcp/tools/editFile.d.ts +8 -0
- package/lib/browser/mcp/tools/editFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/editFile.js +95 -0
- package/lib/browser/mcp/tools/editFile.js.map +1 -0
- package/lib/browser/mcp/tools/findFilesByNameSubstring.d.ts.map +1 -1
- package/lib/browser/mcp/tools/findFilesByNameSubstring.js +1 -2
- package/lib/browser/mcp/tools/findFilesByNameSubstring.js.map +1 -1
- package/lib/browser/mcp/tools/getCurrentFilePath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getCurrentFilePath.js +1 -2
- package/lib/browser/mcp/tools/getCurrentFilePath.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js +1 -2
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/getFileTextByPath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getFileTextByPath.js +1 -2
- package/lib/browser/mcp/tools/getFileTextByPath.js.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js +1 -2
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileText.js +1 -2
- package/lib/browser/mcp/tools/getOpenEditorFileText.js.map +1 -1
- package/lib/browser/mcp/tools/getSelectedText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getSelectedText.js +1 -2
- package/lib/browser/mcp/tools/getSelectedText.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/EditFile.d.ts +10 -0
- package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/handlers/EditFile.js +28 -0
- package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.d.ts +6 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/ReadFile.js +14 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/utils.d.ts +2 -0
- package/lib/browser/mcp/tools/handlers/utils.d.ts.map +1 -0
- package/lib/browser/mcp/tools/handlers/utils.js +7 -0
- package/lib/browser/mcp/tools/handlers/utils.js.map +1 -0
- package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
- package/lib/browser/mcp/tools/listDir.js +2 -4
- package/lib/browser/mcp/tools/listDir.js.map +1 -1
- package/lib/browser/mcp/tools/readFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/readFile.js +2 -4
- package/lib/browser/mcp/tools/readFile.js.map +1 -1
- package/lib/browser/mcp/tools/replaceOpenEditorFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/replaceOpenEditorFile.js +6 -5
- package/lib/browser/mcp/tools/replaceOpenEditorFile.js.map +1 -1
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.d.ts.map +1 -1
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js +1 -2
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js +1 -2
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +5 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +14 -10
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js +1 -2
- package/lib/browser/types.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +1 -0
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +3 -0
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +4 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +1 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/common/index.d.ts +1 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts +14 -0
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -0
- package/lib/common/prompts/context-prompt-provider.js +38 -0
- package/lib/common/prompts/context-prompt-provider.js.map +1 -0
- package/lib/common/utils.d.ts +1 -0
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +3 -1
- package/lib/common/utils.js.map +1 -1
- package/lib/node/base-language-model.d.ts +2 -2
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +8 -4
- package/lib/node/base-language-model.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +2 -1
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/openai/openai-language-model.d.ts +1 -1
- package/lib/node/openai/openai-language-model.d.ts.map +1 -1
- package/lib/node/openai/openai-language-model.js +2 -2
- package/lib/node/openai/openai-language-model.js.map +1 -1
- package/package.json +23 -25
- package/src/browser/ai-core.contribution.ts +4 -0
- package/src/browser/chat/chat-agent.service.ts +7 -0
- package/src/browser/chat/chat-model.ts +0 -2
- package/src/browser/chat/chat-proxy.service.ts +12 -2
- package/src/browser/chat/chat.internal.service.ts +12 -1
- package/src/browser/chat/chat.view.tsx +2 -1
- package/src/browser/components/ChatEditor.tsx +13 -10
- package/src/browser/components/ChatMarkdown.tsx +3 -1
- package/src/browser/components/ChatReply.tsx +8 -15
- package/src/browser/components/ChatToolRender.tsx +41 -20
- package/src/browser/components/components.module.less +3 -2
- package/src/browser/index.ts +7 -0
- package/src/browser/mcp/base-apply.service.ts +349 -0
- package/src/browser/mcp/mcp-server-proxy.service.ts +4 -2
- package/src/browser/mcp/mcp-server.feature.registry.ts +25 -3
- package/src/browser/mcp/tools/components/EditFile.tsx +144 -0
- package/src/browser/mcp/tools/components/index.module.less +67 -0
- package/src/browser/mcp/tools/createNewFileWithText.ts +1 -2
- package/src/browser/mcp/tools/editFile.ts +100 -0
- package/src/browser/mcp/tools/findFilesByNameSubstring.ts +1 -2
- package/src/browser/mcp/tools/getCurrentFilePath.ts +1 -2
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -2
- package/src/browser/mcp/tools/getFileTextByPath.ts +1 -2
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -2
- package/src/browser/mcp/tools/getOpenEditorFileText.ts +1 -2
- package/src/browser/mcp/tools/getSelectedText.ts +1 -2
- package/src/browser/mcp/tools/handlers/EditFile.ts +21 -0
- package/src/browser/mcp/tools/handlers/ReadFile.ts +19 -1
- package/src/browser/mcp/tools/handlers/utils.ts +3 -0
- package/src/browser/mcp/tools/listDir.ts +2 -4
- package/src/browser/mcp/tools/readFile.ts +2 -4
- package/src/browser/mcp/tools/replaceOpenEditorFile.ts +8 -7
- package/src/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.ts +1 -2
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -2
- package/src/browser/preferences/schema.ts +5 -0
- package/src/browser/types.ts +15 -11
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -0
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +4 -0
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +1 -0
- package/src/common/index.ts +1 -0
- package/src/common/prompts/context-prompt-provider.ts +46 -0
- package/src/common/utils.ts +2 -0
- package/src/node/base-language-model.ts +17 -4
- package/src/node/mcp-server-manager-impl.ts +2 -1
- package/src/node/openai/openai-language-model.ts +2 -2
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
2
|
+
|
|
1
3
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
2
4
|
import { ILogger } from '@opensumi/ide-core-browser';
|
|
3
5
|
import { Emitter, Event } from '@opensumi/ide-core-common';
|
|
@@ -29,10 +31,10 @@ export class MCPServerProxyService implements IMCPServerProxyService {
|
|
|
29
31
|
async $getMCPTools() {
|
|
30
32
|
const tools = await this.mcpServerRegistry.getMCPTools().map((tool) =>
|
|
31
33
|
// 不要传递 handler
|
|
32
|
-
|
|
34
|
+
({
|
|
33
35
|
name: tool.name,
|
|
34
36
|
description: tool.description,
|
|
35
|
-
inputSchema: tool.inputSchema,
|
|
37
|
+
inputSchema: zodToJsonSchema(tool.inputSchema),
|
|
36
38
|
providerName: 'sumi-builtin',
|
|
37
39
|
}),
|
|
38
40
|
);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// OpenSumi as MCP Server 前端的代理服务
|
|
2
2
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
3
|
-
import {
|
|
3
|
+
import { ILogger } from '@opensumi/ide-core-common';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { getToolName } from '../../common/utils';
|
|
6
|
+
import { IMCPServerRegistry, IMCPServerToolComponentProps, MCPLogger, MCPToolDefinition } from '../types';
|
|
6
7
|
|
|
7
8
|
class LoggerAdapter implements MCPLogger {
|
|
8
|
-
constructor(private readonly logger: ILogger) {
|
|
9
|
+
constructor(private readonly logger: ILogger) {}
|
|
9
10
|
|
|
10
11
|
appendLine(message: string): void {
|
|
11
12
|
this.logger.log(message);
|
|
@@ -15,6 +16,7 @@ class LoggerAdapter implements MCPLogger {
|
|
|
15
16
|
@Injectable()
|
|
16
17
|
export class MCPServerRegistry implements IMCPServerRegistry {
|
|
17
18
|
private tools: MCPToolDefinition[] = [];
|
|
19
|
+
private toolComponents: Record<string, React.FC<IMCPServerToolComponentProps>> = {};
|
|
18
20
|
|
|
19
21
|
@Autowired(ILogger)
|
|
20
22
|
private readonly baseLogger: ILogger;
|
|
@@ -23,10 +25,26 @@ export class MCPServerRegistry implements IMCPServerRegistry {
|
|
|
23
25
|
return new LoggerAdapter(this.baseLogger);
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
getMCPTool(name: string, serverName = 'sumi-builtin'): MCPToolDefinition | undefined {
|
|
29
|
+
return this.tools.find((tool) => getToolName(tool.name, serverName) === name);
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
registerMCPTool(tool: MCPToolDefinition): void {
|
|
27
33
|
this.tools.push(tool);
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
registerToolComponent(
|
|
37
|
+
name: string,
|
|
38
|
+
component: React.FC<IMCPServerToolComponentProps>,
|
|
39
|
+
serverName = 'sumi-builtin',
|
|
40
|
+
): void {
|
|
41
|
+
this.toolComponents[getToolName(name, serverName)] = component;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getToolComponent(name: string): React.FC<IMCPServerToolComponentProps> | undefined {
|
|
45
|
+
return this.toolComponents[name];
|
|
46
|
+
}
|
|
47
|
+
|
|
30
48
|
getMCPTools(): MCPToolDefinition[] {
|
|
31
49
|
return this.tools;
|
|
32
50
|
}
|
|
@@ -43,8 +61,12 @@ export class MCPServerRegistry implements IMCPServerRegistry {
|
|
|
43
61
|
if (!tool) {
|
|
44
62
|
throw new Error(`MCP tool ${name} not found`);
|
|
45
63
|
}
|
|
64
|
+
// 统一校验并转换
|
|
65
|
+
args = tool.inputSchema.parse(args);
|
|
46
66
|
return await tool.handler(args, this.logger);
|
|
47
67
|
} catch (error) {
|
|
68
|
+
// eslint-disable-next-line no-console
|
|
69
|
+
console.error('callMCPTool error:', error);
|
|
48
70
|
return {
|
|
49
71
|
content: [{ type: 'text', text: `The tool ${name} failed to execute. Error: ${error}` }],
|
|
50
72
|
isError: true,
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import cls from 'classnames';
|
|
2
|
+
import React, { useEffect, useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { Icon, Popover } from '@opensumi/ide-components';
|
|
5
|
+
import {
|
|
6
|
+
AppConfig,
|
|
7
|
+
LabelService,
|
|
8
|
+
MarkerSeverity,
|
|
9
|
+
URI,
|
|
10
|
+
Uri,
|
|
11
|
+
detectModeId,
|
|
12
|
+
path,
|
|
13
|
+
useAutorun,
|
|
14
|
+
useInjectable,
|
|
15
|
+
} from '@opensumi/ide-core-browser';
|
|
16
|
+
import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
17
|
+
import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages/language';
|
|
18
|
+
import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
|
|
19
|
+
import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
20
|
+
|
|
21
|
+
import { ChatMarkdown } from '../../../components/ChatMarkdown';
|
|
22
|
+
import { IMCPServerToolComponentProps } from '../../../types';
|
|
23
|
+
import { BaseApplyService, CodeBlockData } from '../../base-apply.service';
|
|
24
|
+
|
|
25
|
+
import styles from './index.module.less';
|
|
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
|
+
export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
62
|
+
const { args, messageId, toolCallId } = props;
|
|
63
|
+
const labelService = useInjectable(LabelService);
|
|
64
|
+
const appConfig = useInjectable<AppConfig>(AppConfig);
|
|
65
|
+
const applyService = useInjectable<BaseApplyService>(BaseApplyService);
|
|
66
|
+
const { target_file = '', code_edit, instructions } = args || {};
|
|
67
|
+
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
|
+
}
|
|
76
|
+
|
|
77
|
+
const icon = useMemo(() => {
|
|
78
|
+
if (!target_file) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const icon = `file-icon ${labelService.getIcon(URI.file(absolutePath))}`;
|
|
82
|
+
return icon;
|
|
83
|
+
}, [target_file, absolutePath]);
|
|
84
|
+
const languageId = useMemo(() => {
|
|
85
|
+
if (!target_file) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const modelService = StandaloneServices.get(IModelService);
|
|
89
|
+
const languageService = StandaloneServices.get(ILanguageService);
|
|
90
|
+
const detectedModeId = detectModeId(modelService, languageService, Uri.file(absolutePath));
|
|
91
|
+
return detectedModeId;
|
|
92
|
+
}, [target_file, absolutePath]);
|
|
93
|
+
|
|
94
|
+
// 多次迭代时,仅在首处tool组件中展示
|
|
95
|
+
if (!args || !codeBlockData || (toolCallId && toolCallId !== codeBlockData.initToolCallId)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [
|
|
100
|
+
instructions && <p>{instructions}</p>,
|
|
101
|
+
<div className={styles['edit-file-tool']} key={`edit-file-tool-${codeBlockData.id}`}>
|
|
102
|
+
<div
|
|
103
|
+
className={cls(styles['edit-file-tool-header'], {
|
|
104
|
+
clickable: codeBlockData.status === 'pending' || codeBlockData.status === 'success',
|
|
105
|
+
})}
|
|
106
|
+
onClick={() => {
|
|
107
|
+
if (codeBlockData.status === 'pending') {
|
|
108
|
+
applyService.reRenderPendingApply();
|
|
109
|
+
} else if (codeBlockData.status === 'success') {
|
|
110
|
+
applyService.revealApplyPosition(codeBlockData.id);
|
|
111
|
+
}
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
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)}
|
|
120
|
+
</div>
|
|
121
|
+
<ChatMarkdown markdown={`\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``} hideInsert={true} />
|
|
122
|
+
</div>,
|
|
123
|
+
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
|
+
>
|
|
128
|
+
<div className={styles['title']}>Found Lints:</div>
|
|
129
|
+
{codeBlockData.applyResult?.diagnosticInfos.map((info) => (
|
|
130
|
+
<div
|
|
131
|
+
key={info.message}
|
|
132
|
+
className={cls({
|
|
133
|
+
[styles['error']]: info.severity === MarkerSeverity.Error,
|
|
134
|
+
[styles['warning']]: info.severity === MarkerSeverity.Warning,
|
|
135
|
+
})}
|
|
136
|
+
>
|
|
137
|
+
<Icon className={`codicon codicon-${info.severity === MarkerSeverity.Error ? 'error' : 'warning'}`} />
|
|
138
|
+
{info.message.split('\n')[0]}
|
|
139
|
+
</div>
|
|
140
|
+
))}
|
|
141
|
+
</div>
|
|
142
|
+
),
|
|
143
|
+
];
|
|
144
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.edit-file-tool-header {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
padding: 2px 8px;
|
|
5
|
+
border-bottom: 1px solid var(--vscode-commandCenter-inactiveBorder);
|
|
6
|
+
background-color: var(--design-block-background);
|
|
7
|
+
font-size: 10px;
|
|
8
|
+
margin-bottom: -4px;
|
|
9
|
+
border-radius: 8px 8px 0 0;
|
|
10
|
+
> span {
|
|
11
|
+
margin-right: 4px;
|
|
12
|
+
}
|
|
13
|
+
:global(span.codicon) {
|
|
14
|
+
font-size: 12px;
|
|
15
|
+
}
|
|
16
|
+
:global(.kt-popover-trigger) {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
.edit-file-tool {
|
|
23
|
+
border: 1px solid var(--vscode-commandCenter-inactiveBorder);
|
|
24
|
+
border-radius: 4px;
|
|
25
|
+
margin: 8px 0;
|
|
26
|
+
:global(.language-badge) {
|
|
27
|
+
border-top-left-radius: 0;
|
|
28
|
+
}
|
|
29
|
+
pre > code {
|
|
30
|
+
border-radius: 0 0 8px 8px !important;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.edit-file-tool-iteration-count {
|
|
34
|
+
color: var(--vscode-input-placeholderForeground);
|
|
35
|
+
margin-left: 4px;
|
|
36
|
+
}
|
|
37
|
+
:global(.clickable) {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
.edit-file-tool-diagnostic-errors {
|
|
41
|
+
padding: 8px;
|
|
42
|
+
border: 1px solid var(--vscode-commandCenter-inactiveBorder);
|
|
43
|
+
background-color: var(--design-block-background);
|
|
44
|
+
border-radius: 8px;
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
margin: 4px 0;
|
|
47
|
+
> div {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
padding: 2px 0;
|
|
51
|
+
}
|
|
52
|
+
:global(.codicon) {
|
|
53
|
+
margin-right: 4px;
|
|
54
|
+
}
|
|
55
|
+
.title {
|
|
56
|
+
margin-bottom: 3px;
|
|
57
|
+
display: inline-block;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
.error,
|
|
61
|
+
.error > span {
|
|
62
|
+
color: var(--debugConsole-errorForeground);
|
|
63
|
+
}
|
|
64
|
+
.warning,
|
|
65
|
+
.warning > span {
|
|
66
|
+
color: var(--debugConsole-warningForeground);
|
|
67
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired } from '@opensumi/di';
|
|
5
4
|
import { Domain, URI, path } from '@opensumi/ide-core-common';
|
|
@@ -38,7 +37,7 @@ export class CreateNewFileWithTextTool implements MCPServerContribution {
|
|
|
38
37
|
'"ok" if the file was successfully created and populated, ' +
|
|
39
38
|
'"can\'t find project dir" if the project directory cannot be determined. ' +
|
|
40
39
|
'Note: Creates any necessary parent directories automatically.',
|
|
41
|
-
inputSchema
|
|
40
|
+
inputSchema,
|
|
42
41
|
handler: this.handler.bind(this),
|
|
43
42
|
};
|
|
44
43
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
import { Autowired } from '@opensumi/di';
|
|
4
|
+
import { Domain } from '@opensumi/ide-core-common';
|
|
5
|
+
|
|
6
|
+
import { IMCPServerRegistry, MCPLogger, MCPServerContribution, MCPToolDefinition } from '../../types';
|
|
7
|
+
|
|
8
|
+
import { EditFileToolComponent } from './components/EditFile';
|
|
9
|
+
import { EditFileHandler } from './handlers/EditFile';
|
|
10
|
+
const inputSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
target_file: z
|
|
13
|
+
.string()
|
|
14
|
+
.describe(
|
|
15
|
+
'The target file to modify. Always specify the target file as the first argument and use the relative path in the workspace of the file to edit',
|
|
16
|
+
),
|
|
17
|
+
instructions: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe(
|
|
21
|
+
'A single sentence instruction describing what you are going to do for the sketched edit. This is used to assist the less intelligent model in applying the edit. Please use the first person to describe what you are going to do. Dont repeat what you have said previously in normal messages. And use it to disambiguate uncertainty in the edit.',
|
|
22
|
+
),
|
|
23
|
+
code_edit: z
|
|
24
|
+
.string()
|
|
25
|
+
.describe(
|
|
26
|
+
"Specify ONLY the precise lines of code that you wish to edit. **NEVER specify or write out unchanged code**. Instead, represent all unchanged code using the comment of the language you're editing in - example: `// ... existing code ...`",
|
|
27
|
+
),
|
|
28
|
+
})
|
|
29
|
+
.transform((data) => ({
|
|
30
|
+
targetFile: data.target_file,
|
|
31
|
+
instructions: data.instructions,
|
|
32
|
+
codeEdit: data.code_edit,
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
@Domain(MCPServerContribution)
|
|
36
|
+
export class EditFileTool implements MCPServerContribution {
|
|
37
|
+
@Autowired(EditFileHandler)
|
|
38
|
+
private readonly editFileHandler: EditFileHandler;
|
|
39
|
+
|
|
40
|
+
registerMCPServer(registry: IMCPServerRegistry): void {
|
|
41
|
+
registry.registerMCPTool(this.getToolDefinition());
|
|
42
|
+
registry.registerToolComponent('edit_file', EditFileToolComponent);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getToolDefinition(): MCPToolDefinition {
|
|
46
|
+
return {
|
|
47
|
+
name: 'edit_file',
|
|
48
|
+
label: 'Edit File',
|
|
49
|
+
description: `Use this tool to propose an edit to an existing file.
|
|
50
|
+
This will be read by a less intelligent model, which will quickly apply the edit. You should make it clear what the edit is, while also minimizing the unchanged code you write.
|
|
51
|
+
When writing the edit, you should specify each edit in sequence, with the special comment \`// ... existing code ...\` to represent unchanged code in between edited lines.
|
|
52
|
+
For example:
|
|
53
|
+
\`\`\`
|
|
54
|
+
// ... existing code ...
|
|
55
|
+
FIRST_EDIT
|
|
56
|
+
// ... existing code ...
|
|
57
|
+
SECOND_EDIT
|
|
58
|
+
// ... existing code ...
|
|
59
|
+
THIRD_EDIT
|
|
60
|
+
// ... existing code ...
|
|
61
|
+
\`\`\`
|
|
62
|
+
You should bias towards repeating as few lines of the original file as possible to convey the change.
|
|
63
|
+
But, each edit should contain sufficient context of unchanged lines around the code you're editing to resolve ambiguity.
|
|
64
|
+
DO NOT omit spans of pre-existing code without using the \`// ... existing code ...\` comment to indicate its absence.
|
|
65
|
+
Make sure it is clear what the edit should be.
|
|
66
|
+
You should specify the following arguments before the others: [target_file]`,
|
|
67
|
+
inputSchema,
|
|
68
|
+
handler: this.handler.bind(this),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
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);
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: 'text',
|
|
78
|
+
// TODO: lint error
|
|
79
|
+
text: result.applyResult
|
|
80
|
+
? `The apply model made the following changes to the file:
|
|
81
|
+
|
|
82
|
+
\`\`\`
|
|
83
|
+
${result.applyResult.diff}
|
|
84
|
+
\`\`\`
|
|
85
|
+
${
|
|
86
|
+
result.applyResult.diagnosticInfos.length > 0
|
|
87
|
+
? `The edit introduced the following new linter errors:
|
|
88
|
+
${result.applyResult.diagnosticInfos
|
|
89
|
+
.map((error) => `Line ${error.startLineNumber}: ${error.message.split('\n')[0]}`)
|
|
90
|
+
.join('\n')}
|
|
91
|
+
|
|
92
|
+
Please fix the linter errors if it is clear how to (or you can easily figure out how to). Do not make uneducated guesses. And do not loop more than 3 times on fixing linter errors on the same file.`
|
|
93
|
+
: ''
|
|
94
|
+
}`
|
|
95
|
+
: 'User cancelled the edit.',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
5
4
|
|
|
6
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
7
6
|
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
@@ -38,7 +37,7 @@ export class FindFilesByNameSubstringTool implements MCPServerContribution {
|
|
|
38
37
|
'- name: File name ' +
|
|
39
38
|
'Returns an empty array ([]) if no matching files are found. ' +
|
|
40
39
|
'Note: Only searches through files within the project directory, excluding libraries and external dependencies.',
|
|
41
|
-
inputSchema
|
|
40
|
+
inputSchema,
|
|
42
41
|
handler: this.handler.bind(this),
|
|
43
42
|
};
|
|
44
43
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
5
4
|
import { Domain } from '@opensumi/ide-core-common';
|
|
@@ -25,7 +24,7 @@ export class GetCurrentFilePathTool implements MCPServerContribution {
|
|
|
25
24
|
'Retrieves the absolute path of the currently active file in the VS Code editor. ' +
|
|
26
25
|
'Use this tool to get the file location for tasks requiring file path information. ' +
|
|
27
26
|
'Returns an empty string if no file is currently open.',
|
|
28
|
-
inputSchema
|
|
27
|
+
inputSchema,
|
|
29
28
|
handler: this.handler.bind(this),
|
|
30
29
|
};
|
|
31
30
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
5
4
|
|
|
6
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
7
6
|
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
@@ -47,7 +46,7 @@ export class GetDiagnosticsByPathTool implements MCPServerContribution {
|
|
|
47
46
|
'- "error": Must be fixed immediately as they indicate critical issues that will prevent code from working correctly. ' +
|
|
48
47
|
'- "warning": For user code, preserve unless the warning indicates a clear improvement opportunity. For generated code, optimize to remove warnings. ' +
|
|
49
48
|
'- "information"/"hint": For user code, preserve as they might reflect intentional patterns. For generated code, optimize if it improves code quality without changing functionality.',
|
|
50
|
-
inputSchema
|
|
49
|
+
inputSchema,
|
|
51
50
|
handler: this.handler.bind(this),
|
|
52
51
|
};
|
|
53
52
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
5
4
|
|
|
6
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
7
6
|
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
@@ -38,7 +37,7 @@ export class GetFileTextByPathTool implements MCPServerContribution {
|
|
|
38
37
|
'- error "project dir not found" if project directory cannot be determined ' +
|
|
39
38
|
'- error "file not found" if the file doesn\'t exist or is outside project scope ' +
|
|
40
39
|
'Note: Automatically refreshes the file system before reading',
|
|
41
|
-
inputSchema
|
|
40
|
+
inputSchema,
|
|
42
41
|
handler: this.handler.bind(this),
|
|
43
42
|
};
|
|
44
43
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
5
4
|
|
|
6
5
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
7
6
|
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
@@ -47,7 +46,7 @@ export class GetOpenEditorFileDiagnosticsTool implements MCPServerContribution {
|
|
|
47
46
|
'- "error": Must be fixed immediately as they indicate critical issues that will prevent code from working correctly. ' +
|
|
48
47
|
'- "warning": For user code, preserve unless the warning indicates a clear improvement opportunity. For generated code, optimize to remove warnings. ' +
|
|
49
48
|
'- "information"/"hint": For user code, preserve as they might reflect intentional patterns. For generated code, optimize if it improves code quality without changing functionality.',
|
|
50
|
-
inputSchema
|
|
49
|
+
inputSchema,
|
|
51
50
|
handler: this.handler.bind(this),
|
|
52
51
|
};
|
|
53
52
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
5
4
|
import { Domain } from '@opensumi/ide-core-common';
|
|
@@ -25,7 +24,7 @@ export class GetOpenEditorFileTextTool implements MCPServerContribution {
|
|
|
25
24
|
'Retrieves the complete text content of the currently active file in the IDE editor. ' +
|
|
26
25
|
"Use this tool to access and analyze the file's contents for tasks such as code review, content inspection, or text processing. " +
|
|
27
26
|
'Returns empty string if no file is currently open.',
|
|
28
|
-
inputSchema
|
|
27
|
+
inputSchema,
|
|
29
28
|
handler: this.handler.bind(this),
|
|
30
29
|
};
|
|
31
30
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
5
4
|
import { Domain } from '@opensumi/ide-core-common';
|
|
@@ -25,7 +24,7 @@ export class GetSelectedTextTool implements MCPServerContribution {
|
|
|
25
24
|
'Retrieves the currently selected text from the active editor in VS Code. ' +
|
|
26
25
|
'Use this tool when you need to access and analyze text that has been highlighted/selected by the user. ' +
|
|
27
26
|
'Returns an empty string if no text is selected or no editor is open.',
|
|
28
|
-
inputSchema
|
|
27
|
+
inputSchema,
|
|
29
28
|
handler: this.handler.bind(this),
|
|
30
29
|
};
|
|
31
30
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Autowired, Injectable } from '@opensumi/di';
|
|
2
|
+
|
|
3
|
+
import { BaseApplyService } from '../../base-apply.service';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TODO: 代码块改动版本号,次数,流式工具调用?
|
|
7
|
+
* 基础文件编辑处理类
|
|
8
|
+
* 用于处理代码改动的应用、保存等操作
|
|
9
|
+
*/
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class EditFileHandler {
|
|
12
|
+
@Autowired(BaseApplyService)
|
|
13
|
+
private applyService: BaseApplyService;
|
|
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);
|
|
19
|
+
return blockData;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -12,6 +12,11 @@ export class FileHandler {
|
|
|
12
12
|
private static readonly MAX_CHARS = 1e5;
|
|
13
13
|
private static readonly NEWLINE = '\n';
|
|
14
14
|
|
|
15
|
+
private fileResultMap: Map<
|
|
16
|
+
string,
|
|
17
|
+
{ content: string; startLineOneIndexed: number; endLineOneIndexedInclusive: number }
|
|
18
|
+
> = new Map();
|
|
19
|
+
|
|
15
20
|
@Autowired(IEditorDocumentModelService)
|
|
16
21
|
protected modelService: IEditorDocumentModelService;
|
|
17
22
|
|
|
@@ -141,7 +146,14 @@ export class FileHandler {
|
|
|
141
146
|
didShortenCharRange = true;
|
|
142
147
|
selectedContent = this.trimContent(selectedContent, FileHandler.MAX_CHARS);
|
|
143
148
|
}
|
|
144
|
-
|
|
149
|
+
// 文件的浏览窗口需要记录,应用的时候需要用
|
|
150
|
+
if (didShortenLineRange) {
|
|
151
|
+
this.fileResultMap.set(fileParams.relativeWorkspacePath, {
|
|
152
|
+
content: selectedContent,
|
|
153
|
+
startLineOneIndexed: adjustedStart,
|
|
154
|
+
endLineOneIndexedInclusive: adjustedEnd,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
145
157
|
return {
|
|
146
158
|
contents: selectedContent,
|
|
147
159
|
didDowngradeToLineRange: shouldForceLimitLines,
|
|
@@ -171,4 +183,10 @@ export class FileHandler {
|
|
|
171
183
|
modelReference?.dispose();
|
|
172
184
|
}
|
|
173
185
|
}
|
|
186
|
+
|
|
187
|
+
getFileReadResult(
|
|
188
|
+
relativeWorkspacePath: string,
|
|
189
|
+
): { content: string; startLineOneIndexed: number; endLineOneIndexedInclusive: number } | undefined {
|
|
190
|
+
return this.fileResultMap.get(relativeWorkspacePath);
|
|
191
|
+
}
|
|
174
192
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired } from '@opensumi/di';
|
|
5
4
|
import { Domain } from '@opensumi/ide-core-common';
|
|
@@ -33,16 +32,15 @@ export class ListDirTool implements MCPServerContribution {
|
|
|
33
32
|
getToolDefinition(): MCPToolDefinition {
|
|
34
33
|
return {
|
|
35
34
|
name: 'list_dir',
|
|
35
|
+
label: 'List Directory',
|
|
36
36
|
description:
|
|
37
37
|
'List the contents of a directory. The quick tool to use for discovery, before using more targeted tools like semantic search or file reading. Useful to try to understand the file structure before diving deeper into specific files. Can be used to explore the codebase.',
|
|
38
|
-
inputSchema
|
|
38
|
+
inputSchema,
|
|
39
39
|
handler: this.handler.bind(this),
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
|
|
44
|
-
// TODO: 应该添加统一的 validate 逻辑
|
|
45
|
-
args = inputSchema.parse(args);
|
|
46
44
|
const result = await this.listDirHandler.handler(args);
|
|
47
45
|
return {
|
|
48
46
|
content: [
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
2
|
|
|
4
3
|
import { Autowired } from '@opensumi/di';
|
|
5
4
|
import { Domain } from '@opensumi/ide-core-common';
|
|
@@ -37,6 +36,7 @@ export class ReadFileTool implements MCPServerContribution {
|
|
|
37
36
|
getToolDefinition(): MCPToolDefinition {
|
|
38
37
|
return {
|
|
39
38
|
name: 'read_file',
|
|
39
|
+
label: 'Read File',
|
|
40
40
|
description: `Read the contents of a file (and the outline).
|
|
41
41
|
|
|
42
42
|
When using this tool to gather information, it's your responsibility to ensure you have the COMPLETE context. Each time you call this command you should:
|
|
@@ -48,14 +48,12 @@ When using this tool to gather information, it's your responsibility to ensure y
|
|
|
48
48
|
If reading a range of lines is not enough, you may choose to read the entire file.
|
|
49
49
|
Reading entire files is often wasteful and slow, especially for large files (i.e. more than a few hundred lines). So you should use this option sparingly.
|
|
50
50
|
Reading the entire file is not allowed in most cases. You are only allowed to read the entire file if it has been edited or manually attached to the conversation by the user.`,
|
|
51
|
-
inputSchema
|
|
51
|
+
inputSchema,
|
|
52
52
|
handler: this.handler.bind(this),
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
|
|
57
|
-
// TODO: 应该添加统一的 validate 逻辑
|
|
58
|
-
args = inputSchema.parse(args);
|
|
59
57
|
const result = await this.fileHandler.readFile(args);
|
|
60
58
|
return {
|
|
61
59
|
content: [
|