@opensumi/ide-ai-native 3.7.2-next-1739848467.0 → 3.7.2-next-1739945875.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 +3 -0
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +68 -2
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +2 -2
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +16 -5
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +4 -0
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +43 -0
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +29 -2
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatContext/ContextSelector.d.ts +12 -0
- package/lib/browser/components/ChatContext/ContextSelector.d.ts.map +1 -0
- package/lib/browser/components/ChatContext/ContextSelector.js +113 -0
- package/lib/browser/components/ChatContext/ContextSelector.js.map +1 -0
- package/lib/browser/components/ChatContext/index.d.ts +4 -0
- package/lib/browser/components/ChatContext/index.d.ts.map +1 -0
- package/lib/browser/components/ChatContext/index.js +84 -0
- package/lib/browser/components/ChatContext/index.js.map +1 -0
- package/lib/browser/components/ChatContext/style.module.less +189 -0
- package/lib/browser/components/ChatInput.d.ts.map +1 -1
- package/lib/browser/components/ChatInput.js.map +1 -1
- package/lib/browser/components/ChatReply.d.ts.map +1 -1
- package/lib/browser/components/ChatReply.js +25 -0
- package/lib/browser/components/ChatReply.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts +6 -0
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -0
- package/lib/browser/components/ChatToolRender.js +53 -0
- package/lib/browser/components/ChatToolRender.js.map +1 -0
- package/lib/browser/components/ChatToolRender.module.less +86 -0
- package/lib/browser/components/components.module.less +32 -31
- package/lib/browser/components/utils.d.ts +2 -2
- package/lib/browser/context/llm-context.contribution.d.ts +7 -0
- package/lib/browser/context/llm-context.contribution.d.ts.map +1 -0
- package/lib/browser/context/llm-context.contribution.js +21 -0
- package/lib/browser/context/llm-context.contribution.js.map +1 -0
- package/lib/browser/context/llm-context.service.d.ts +24 -0
- package/lib/browser/context/llm-context.service.d.ts.map +1 -0
- package/lib/browser/context/llm-context.service.js +136 -0
- package/lib/browser/context/llm-context.service.js.map +1 -0
- package/lib/browser/index.d.ts +11 -3
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +56 -3
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +25 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.js +56 -0
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -0
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts +16 -0
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-server.feature.registry.js +53 -0
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -0
- package/lib/browser/mcp/mcp-tools-dialog.module.less +44 -0
- package/lib/browser/mcp/mcp-tools-dialog.view.d.ts +8 -0
- package/lib/browser/mcp/mcp-tools-dialog.view.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-tools-dialog.view.js +16 -0
- package/lib/browser/mcp/mcp-tools-dialog.view.js.map +1 -0
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts +9 -0
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -0
- package/lib/browser/mcp/tools/createNewFileWithText.js +83 -0
- package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -0
- package/lib/browser/mcp/tools/findFilesByNameSubstring.d.ts +9 -0
- package/lib/browser/mcp/tools/findFilesByNameSubstring.d.ts.map +1 -0
- package/lib/browser/mcp/tools/findFilesByNameSubstring.js +92 -0
- package/lib/browser/mcp/tools/findFilesByNameSubstring.js.map +1 -0
- package/lib/browser/mcp/tools/getCurrentFilePath.d.ts +8 -0
- package/lib/browser/mcp/tools/getCurrentFilePath.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getCurrentFilePath.js +49 -0
- package/lib/browser/mcp/tools/getCurrentFilePath.js.map +1 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts +10 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js +119 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -0
- package/lib/browser/mcp/tools/getFileTextByPath.d.ts +9 -0
- package/lib/browser/mcp/tools/getFileTextByPath.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getFileTextByPath.js +97 -0
- package/lib/browser/mcp/tools/getFileTextByPath.js.map +1 -0
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.d.ts +11 -0
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js +119 -0
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -0
- package/lib/browser/mcp/tools/getOpenEditorFileText.d.ts +8 -0
- package/lib/browser/mcp/tools/getOpenEditorFileText.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getOpenEditorFileText.js +50 -0
- package/lib/browser/mcp/tools/getOpenEditorFileText.js.map +1 -0
- package/lib/browser/mcp/tools/getSelectedText.d.ts +8 -0
- package/lib/browser/mcp/tools/getSelectedText.d.ts.map +1 -0
- package/lib/browser/mcp/tools/getSelectedText.js +57 -0
- package/lib/browser/mcp/tools/getSelectedText.js.map +1 -0
- package/lib/browser/mcp/tools/handlers/ListDir.d.ts +21 -0
- package/lib/browser/mcp/tools/handlers/ListDir.d.ts.map +1 -0
- package/lib/browser/mcp/tools/handlers/ListDir.js +112 -0
- package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.d.ts +47 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.js +147 -0
- package/lib/browser/mcp/tools/handlers/ReadFile.js.map +1 -0
- package/lib/browser/mcp/tools/listDir.d.ts +8 -0
- package/lib/browser/mcp/tools/listDir.d.ts.map +1 -0
- package/lib/browser/mcp/tools/listDir.js +65 -0
- package/lib/browser/mcp/tools/listDir.js.map +1 -0
- package/lib/browser/mcp/tools/readFile.d.ts +8 -0
- package/lib/browser/mcp/tools/readFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/readFile.js +82 -0
- package/lib/browser/mcp/tools/readFile.js.map +1 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFile.d.ts +8 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFile.d.ts.map +1 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFile.js +79 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFile.js.map +1 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.d.ts +8 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.d.ts.map +1 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js +84 -0
- package/lib/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.js.map +1 -0
- package/lib/browser/mcp/tools/runTerminalCmd.d.ts +18 -0
- package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -0
- package/lib/browser/mcp/tools/runTerminalCmd.js +96 -0
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -0
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +60 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +45 -0
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js +5 -1
- package/lib/browser/types.js.map +1 -1
- package/lib/common/index.d.ts +9 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +4 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/llm-context.d.ts +37 -0
- package/lib/common/llm-context.d.ts.map +1 -0
- package/lib/common/llm-context.js +5 -0
- package/lib/common/llm-context.js.map +1 -0
- package/lib/common/mcp-server-manager.d.ts +40 -0
- package/lib/common/mcp-server-manager.d.ts.map +1 -0
- package/lib/common/mcp-server-manager.js +6 -0
- package/lib/common/mcp-server-manager.js.map +1 -0
- package/lib/common/tool-invocation-registry.d.ts +91 -0
- package/lib/common/tool-invocation-registry.d.ts.map +1 -0
- package/lib/common/tool-invocation-registry.js +90 -0
- package/lib/common/tool-invocation-registry.js.map +1 -0
- package/lib/common/types.d.ts +17 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/node/anthropic/anthropic-language-model.d.ts +9 -0
- package/lib/node/anthropic/anthropic-language-model.d.ts.map +1 -0
- package/lib/node/anthropic/anthropic-language-model.js +26 -0
- package/lib/node/anthropic/anthropic-language-model.js.map +1 -0
- package/lib/node/base-language-model.d.ts +14 -0
- package/lib/node/base-language-model.d.ts.map +1 -0
- package/lib/node/base-language-model.js +136 -0
- package/lib/node/base-language-model.js.map +1 -0
- package/lib/node/deepseek/deepseek-language-model.d.ts +9 -0
- package/lib/node/deepseek/deepseek-language-model.d.ts.map +1 -0
- package/lib/node/deepseek/deepseek-language-model.js +26 -0
- package/lib/node/deepseek/deepseek-language-model.js.map +1 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +19 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +91 -0
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -0
- package/lib/node/mcp/sumi-mcp-server.js +172 -0
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -0
- package/lib/node/mcp-server-manager-impl.d.ts +27 -0
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -0
- package/lib/node/mcp-server-manager-impl.js +127 -0
- package/lib/node/mcp-server-manager-impl.js.map +1 -0
- package/lib/node/mcp-server.d.ts +207 -0
- package/lib/node/mcp-server.d.ts.map +1 -0
- package/lib/node/mcp-server.js +91 -0
- package/lib/node/mcp-server.js.map +1 -0
- package/lib/node/openai/openai-language-model.d.ts +9 -0
- package/lib/node/openai/openai-language-model.d.ts.map +1 -0
- package/lib/node/openai/openai-language-model.js +29 -0
- package/lib/node/openai/openai-language-model.js.map +1 -0
- package/package.json +34 -22
- package/src/browser/ai-core.contribution.ts +77 -1
- package/src/browser/chat/chat-model.ts +24 -6
- package/src/browser/chat/chat-proxy.service.ts +42 -0
- package/src/browser/chat/chat.view.tsx +59 -6
- package/src/browser/components/ChatContext/ContextSelector.tsx +177 -0
- package/src/browser/components/ChatContext/index.tsx +135 -0
- package/src/browser/components/ChatContext/style.module.less +189 -0
- package/src/browser/components/ChatInput.tsx +1 -0
- package/src/browser/components/ChatReply.tsx +32 -0
- package/src/browser/components/ChatToolRender.module.less +86 -0
- package/src/browser/components/ChatToolRender.tsx +77 -0
- package/src/browser/components/components.module.less +32 -31
- package/src/browser/context/llm-context.contribution.ts +14 -0
- package/src/browser/context/llm-context.service.ts +156 -0
- package/src/browser/index.ts +68 -4
- package/src/browser/mcp/mcp-server-proxy.service.ts +53 -0
- package/src/browser/mcp/mcp-server.feature.registry.ts +54 -0
- package/src/browser/mcp/mcp-tools-dialog.module.less +44 -0
- package/src/browser/mcp/mcp-tools-dialog.view.tsx +24 -0
- package/src/browser/mcp/tools/createNewFileWithText.ts +83 -0
- package/src/browser/mcp/tools/findFilesByNameSubstring.ts +93 -0
- package/src/browser/mcp/tools/getCurrentFilePath.ts +49 -0
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +123 -0
- package/src/browser/mcp/tools/getFileTextByPath.ts +97 -0
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +121 -0
- package/src/browser/mcp/tools/getOpenEditorFileText.ts +50 -0
- package/src/browser/mcp/tools/getSelectedText.ts +57 -0
- package/src/browser/mcp/tools/handlers/ListDir.ts +117 -0
- package/src/browser/mcp/tools/handlers/ReadFile.ts +174 -0
- package/src/browser/mcp/tools/listDir.ts +66 -0
- package/src/browser/mcp/tools/readFile.ts +82 -0
- package/src/browser/mcp/tools/replaceOpenEditorFile.ts +80 -0
- package/src/browser/mcp/tools/replaceOpenEditorFileByDiffPreviewer.ts +91 -0
- package/src/browser/mcp/tools/runTerminalCmd.ts +107 -0
- package/src/browser/preferences/schema.ts +60 -0
- package/src/browser/types.ts +56 -0
- package/src/common/index.ts +14 -0
- package/src/common/llm-context.ts +41 -0
- package/src/common/mcp-server-manager.ts +46 -0
- package/src/common/tool-invocation-registry.ts +170 -0
- package/src/common/types.ts +22 -0
- package/src/node/anthropic/anthropic-language-model.ts +25 -0
- package/src/node/base-language-model.ts +163 -0
- package/src/node/deepseek/deepseek-language-model.ts +25 -0
- package/src/node/index.ts +21 -0
- package/src/node/mcp/sumi-mcp-server.ts +197 -0
- package/src/node/mcp-server-manager-impl.ts +148 -0
- package/src/node/mcp-server.ts +126 -0
- package/src/node/openai/openai-language-model.ts +25 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
|
|
4
|
+
import { Autowired, Injectable } from '@opensumi/di';
|
|
5
|
+
import { Domain } from '@opensumi/ide-core-common';
|
|
6
|
+
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
7
|
+
import { Selection, SelectionDirection } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/selection';
|
|
8
|
+
|
|
9
|
+
import { IMCPServerRegistry, MCPLogger, MCPServerContribution, MCPToolDefinition } from '../../types';
|
|
10
|
+
import { LiveInlineDiffPreviewer } from '../../widget/inline-diff/inline-diff-previewer';
|
|
11
|
+
import { InlineDiffController } from '../../widget/inline-diff/inline-diff.controller';
|
|
12
|
+
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
text: z.string().describe('The new content to replace the entire file with'),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
@Domain(MCPServerContribution)
|
|
18
|
+
export class ReplaceOpenEditorFileByDiffPreviewerTool implements MCPServerContribution {
|
|
19
|
+
@Autowired(WorkbenchEditorService)
|
|
20
|
+
private readonly editorService: WorkbenchEditorService;
|
|
21
|
+
|
|
22
|
+
registerMCPServer(registry: IMCPServerRegistry): void {
|
|
23
|
+
registry.registerMCPTool(this.getToolDefinition());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getToolDefinition(): MCPToolDefinition {
|
|
27
|
+
return {
|
|
28
|
+
name: 'replace_open_in_editor_file_text',
|
|
29
|
+
description:
|
|
30
|
+
'Replaces the entire content of the currently active file in the IDE editor with specified new text using diff previewer. ' +
|
|
31
|
+
"Use this tool when you need to completely overwrite the current file's content with diff preview. " +
|
|
32
|
+
'Requires a text parameter containing the new content. ' +
|
|
33
|
+
'Returns one of three possible responses: ' +
|
|
34
|
+
'"ok" if the file content was successfully replaced, ' +
|
|
35
|
+
'"no file open" if no editor is active, ' +
|
|
36
|
+
'"unknown error" if the operation fails.',
|
|
37
|
+
inputSchema: zodToJsonSchema(inputSchema),
|
|
38
|
+
handler: this.handler.bind(this),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
|
|
43
|
+
try {
|
|
44
|
+
const editor = this.editorService.currentEditor;
|
|
45
|
+
if (!editor || !editor.monacoEditor) {
|
|
46
|
+
logger.appendLine('Error: No active text editor found');
|
|
47
|
+
return {
|
|
48
|
+
content: [{ type: 'text', text: 'no file open' }],
|
|
49
|
+
isError: true,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Get the model and its full range
|
|
54
|
+
const model = editor.monacoEditor.getModel();
|
|
55
|
+
if (!model) {
|
|
56
|
+
logger.appendLine('Error: No model found for current editor');
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: 'text', text: 'unknown error' }],
|
|
59
|
+
isError: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const fullRange = model.getFullModelRange();
|
|
64
|
+
const inlineDiffHandler = InlineDiffController.get(editor.monacoEditor)!;
|
|
65
|
+
|
|
66
|
+
// Create diff previewer
|
|
67
|
+
const previewer = inlineDiffHandler.createDiffPreviewer(
|
|
68
|
+
editor.monacoEditor,
|
|
69
|
+
Selection.fromRange(fullRange, SelectionDirection.LTR),
|
|
70
|
+
{
|
|
71
|
+
disposeWhenEditorClosed: false,
|
|
72
|
+
renderRemovedWidgetImmediately: true,
|
|
73
|
+
},
|
|
74
|
+
) as LiveInlineDiffPreviewer;
|
|
75
|
+
|
|
76
|
+
// Set the new content
|
|
77
|
+
previewer.setValue(args.text);
|
|
78
|
+
|
|
79
|
+
logger.appendLine('Successfully created diff preview with new content');
|
|
80
|
+
return {
|
|
81
|
+
content: [{ type: 'text', text: 'ok' }],
|
|
82
|
+
};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
logger.appendLine(`Error during file content replacement: ${error}`);
|
|
85
|
+
return {
|
|
86
|
+
content: [{ type: 'text', text: 'unknown error' }],
|
|
87
|
+
isError: true,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
|
|
4
|
+
import { Autowired } from '@opensumi/di';
|
|
5
|
+
import { AppConfig } from '@opensumi/ide-core-browser';
|
|
6
|
+
import { Deferred, Domain } from '@opensumi/ide-core-common';
|
|
7
|
+
import { ITerminalController, ITerminalGroupViewService } from '@opensumi/ide-terminal-next/lib/common/controller';
|
|
8
|
+
|
|
9
|
+
import { IMCPServerRegistry, MCPLogger, MCPServerContribution, MCPToolDefinition } from '../../types';
|
|
10
|
+
|
|
11
|
+
const color = {
|
|
12
|
+
italic: '\x1b[3m',
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
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
|
+
});
|
|
28
|
+
|
|
29
|
+
@Domain(MCPServerContribution)
|
|
30
|
+
export class RunTerminalCommandTool implements MCPServerContribution {
|
|
31
|
+
@Autowired(ITerminalController)
|
|
32
|
+
protected readonly terminalController: ITerminalController;
|
|
33
|
+
|
|
34
|
+
@Autowired(AppConfig)
|
|
35
|
+
protected readonly appConfig: AppConfig;
|
|
36
|
+
|
|
37
|
+
@Autowired(ITerminalGroupViewService)
|
|
38
|
+
protected readonly terminalView: ITerminalGroupViewService;
|
|
39
|
+
|
|
40
|
+
private terminalId = 0;
|
|
41
|
+
|
|
42
|
+
registerMCPServer(registry: IMCPServerRegistry): void {
|
|
43
|
+
registry.registerMCPTool(this.getToolDefinition());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getToolDefinition(): MCPToolDefinition {
|
|
47
|
+
return {
|
|
48
|
+
name: 'run_terminal_cmd',
|
|
49
|
+
description:
|
|
50
|
+
"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.",
|
|
51
|
+
inputSchema: zodToJsonSchema(inputSchema),
|
|
52
|
+
handler: this.handler.bind(this),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getShellLaunchConfig(command: string) {
|
|
57
|
+
return {
|
|
58
|
+
name: `MCP:Terminal_${this.terminalId++}`,
|
|
59
|
+
cwd: this.appConfig.workspaceDir,
|
|
60
|
+
args: ['-c', command],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
|
|
65
|
+
if (args.require_user_approval) {
|
|
66
|
+
// FIXME: support approval
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const terminalClient = await this.terminalController.createTerminalWithWidget({
|
|
70
|
+
config: this.getShellLaunchConfig(args.command),
|
|
71
|
+
closeWhenExited: false,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
this.terminalController.showTerminalPanel();
|
|
75
|
+
|
|
76
|
+
const result: { type: string; text: string }[] = [];
|
|
77
|
+
const def = new Deferred<{ isError?: boolean; content: { type: string; text: string }[] }>();
|
|
78
|
+
|
|
79
|
+
terminalClient.onOutput((e) => {
|
|
80
|
+
result.push({
|
|
81
|
+
type: 'output',
|
|
82
|
+
text: e.data.toString(),
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
terminalClient.onExit((e) => {
|
|
87
|
+
const isError = e.code !== 0;
|
|
88
|
+
def.resolve({
|
|
89
|
+
isError,
|
|
90
|
+
content: result,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
terminalClient.term.writeln(
|
|
94
|
+
`\n${color.italic}> Command ${args.command} executed successfully. Terminal will close in ${
|
|
95
|
+
3000 / 1000
|
|
96
|
+
} seconds.${color.reset}\n`,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
terminalClient.dispose();
|
|
101
|
+
this.terminalView.removeWidget(terminalClient.id);
|
|
102
|
+
}, 3000);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return def.promise;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -58,6 +58,66 @@ export const aiNativePreferenceSchema: PreferenceSchema = {
|
|
|
58
58
|
type: 'boolean',
|
|
59
59
|
default: false,
|
|
60
60
|
},
|
|
61
|
+
[AINativeSettingSectionsId.LLMModelSelection]: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
default: 'deepseek',
|
|
64
|
+
enum: ['deepseek', 'anthropic', 'openai'],
|
|
65
|
+
description: localize('preference.ai.native.llm.model.selection.description'),
|
|
66
|
+
},
|
|
67
|
+
[AINativeSettingSectionsId.DeepseekApiKey]: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
default: '',
|
|
70
|
+
description: localize('preference.ai.native.deepseek.apiKey.description'),
|
|
71
|
+
},
|
|
72
|
+
[AINativeSettingSectionsId.AnthropicApiKey]: {
|
|
73
|
+
type: 'string',
|
|
74
|
+
default: '',
|
|
75
|
+
description: localize('preference.ai.native.anthropic.apiKey.description'),
|
|
76
|
+
},
|
|
77
|
+
[AINativeSettingSectionsId.OpenaiApiKey]: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
default: '',
|
|
80
|
+
description: localize('preference.ai.native.openai.apiKey.description'),
|
|
81
|
+
},
|
|
82
|
+
[AINativeSettingSectionsId.OpenaiBaseURL]: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
default: '',
|
|
85
|
+
description: localize('preference.ai.native.openai.baseURL.description'),
|
|
86
|
+
},
|
|
87
|
+
[AINativeSettingSectionsId.MCPServers]: {
|
|
88
|
+
type: 'array',
|
|
89
|
+
default: [],
|
|
90
|
+
description: localize('preference.ai.native.mcp.servers.description'),
|
|
91
|
+
items: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
required: ['name', 'command', 'args'],
|
|
94
|
+
properties: {
|
|
95
|
+
name: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
description: localize('preference.ai.native.mcp.servers.name.description'),
|
|
98
|
+
},
|
|
99
|
+
command: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
description: localize('preference.ai.native.mcp.servers.command.description'),
|
|
102
|
+
},
|
|
103
|
+
args: {
|
|
104
|
+
type: 'array',
|
|
105
|
+
items: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
},
|
|
108
|
+
description: localize('preference.ai.native.mcp.servers.args.description'),
|
|
109
|
+
},
|
|
110
|
+
env: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
additionalProperties: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
},
|
|
115
|
+
description: localize('preference.ai.native.mcp.servers.env.description'),
|
|
116
|
+
default: {},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
61
121
|
[AINativeSettingSectionsId.CodeEditsTyping]: {
|
|
62
122
|
type: 'boolean',
|
|
63
123
|
default: false,
|
package/src/browser/types.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
|
|
|
26
26
|
import { IMarker } from '@opensumi/monaco-editor-core/esm/vs/platform/markers/common/markers';
|
|
27
27
|
|
|
28
28
|
import { IChatWelcomeMessageContent, ISampleQuestions, ITerminalCommandSuggestionDesc } from '../common';
|
|
29
|
+
import { SerializedContext } from '../common/llm-context';
|
|
29
30
|
|
|
30
31
|
import {
|
|
31
32
|
ICodeEditsContextBean,
|
|
@@ -325,6 +326,51 @@ export interface AINativeCoreContribution {
|
|
|
325
326
|
* proposed api
|
|
326
327
|
*/
|
|
327
328
|
registerIntelligentCompletionFeature?(registry: IIntelligentCompletionsRegistry): void;
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* 注册 Agent 模式下的 chat prompt provider
|
|
332
|
+
* @param provider
|
|
333
|
+
*/
|
|
334
|
+
registerChatAgentPromptProvider?(): void;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// MCP Server 的 贡献点
|
|
338
|
+
export const MCPServerContribution = Symbol('MCPServerContribution');
|
|
339
|
+
|
|
340
|
+
export const TokenMCPServerRegistry = Symbol('TokenMCPServerRegistry');
|
|
341
|
+
|
|
342
|
+
export interface MCPServerContribution {
|
|
343
|
+
registerMCPServer(registry: IMCPServerRegistry): void;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export interface MCPLogger {
|
|
347
|
+
appendLine(message: string): void;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface MCPToolDefinition {
|
|
351
|
+
name: string;
|
|
352
|
+
description: string;
|
|
353
|
+
inputSchema: any; // JSON Schema
|
|
354
|
+
handler: (
|
|
355
|
+
args: any,
|
|
356
|
+
logger: MCPLogger,
|
|
357
|
+
) => Promise<{
|
|
358
|
+
content: { type: string; text: string }[];
|
|
359
|
+
isError?: boolean;
|
|
360
|
+
}>;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export interface IMCPServerRegistry {
|
|
364
|
+
registerMCPTool(tool: MCPToolDefinition): void;
|
|
365
|
+
getMCPTools(): MCPToolDefinition[];
|
|
366
|
+
callMCPTool(
|
|
367
|
+
name: string,
|
|
368
|
+
args: any,
|
|
369
|
+
): Promise<{
|
|
370
|
+
content: { type: string; text: string }[];
|
|
371
|
+
isError?: boolean;
|
|
372
|
+
}>;
|
|
373
|
+
// 后续支持其他 MCP 功能
|
|
328
374
|
}
|
|
329
375
|
|
|
330
376
|
export interface IChatComponentConfig {
|
|
@@ -359,3 +405,13 @@ export interface IAIMiddleware {
|
|
|
359
405
|
provideInlineCompletions?: IProvideInlineCompletionsSignature;
|
|
360
406
|
};
|
|
361
407
|
}
|
|
408
|
+
|
|
409
|
+
export const ChatAgentPromptProvider = Symbol('ChatAgentPromptProvider');
|
|
410
|
+
|
|
411
|
+
export interface ChatAgentPromptProvider {
|
|
412
|
+
/**
|
|
413
|
+
* 提供上下文提示
|
|
414
|
+
* @param context 上下文
|
|
415
|
+
*/
|
|
416
|
+
provideContextPrompt(context: SerializedContext, userMessage: string): MaybePromise<string>;
|
|
417
|
+
}
|
package/src/common/index.ts
CHANGED
|
@@ -16,6 +16,9 @@ import { IChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
|
|
|
16
16
|
import { DESIGN_MENUBAR_CONTAINER_VIEW_ID } from '@opensumi/ide-design/lib/common/constants';
|
|
17
17
|
import { IPosition, ITextModel, InlineCompletionContext } from '@opensumi/ide-monaco/lib/common';
|
|
18
18
|
|
|
19
|
+
import { MCPServerDescription } from './mcp-server-manager';
|
|
20
|
+
import { MCPTool } from './types';
|
|
21
|
+
|
|
19
22
|
export const IAINativeService = Symbol('IAINativeService');
|
|
20
23
|
|
|
21
24
|
/**
|
|
@@ -116,6 +119,17 @@ export const IChatAgentService = Symbol('IChatAgentService');
|
|
|
116
119
|
|
|
117
120
|
export const ChatProxyServiceToken = Symbol('ChatProxyServiceToken');
|
|
118
121
|
|
|
122
|
+
// 暴露给 Node.js 层,使其可以感知 Opensumi 注册的 MCP 能力
|
|
123
|
+
export const TokenMCPServerProxyService = Symbol('TokenMCPServerProxyService');
|
|
124
|
+
|
|
125
|
+
export interface ISumiMCPServerBackend {
|
|
126
|
+
initBuiltinMCPServer(): void;
|
|
127
|
+
initExternalMCPServers(servers: MCPServerDescription[]): void;
|
|
128
|
+
getAllMCPTools(): Promise<MCPTool[]>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export const SumiMCPServerProxyServicePath = 'SumiMCPServerProxyServicePath';
|
|
132
|
+
|
|
119
133
|
export interface IChatAgentService {
|
|
120
134
|
readonly onDidChangeAgents: Event<void>;
|
|
121
135
|
readonly onDidSendMessage: Event<IChatProgress>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Event, URI } from '@opensumi/ide-core-common/lib/utils';
|
|
2
|
+
|
|
3
|
+
export interface LLMContextService {
|
|
4
|
+
startAutoCollection(): void;
|
|
5
|
+
|
|
6
|
+
stopAutoCollection(): void;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 添加文件到 context 中
|
|
10
|
+
*/
|
|
11
|
+
addFileToContext(uri: URI, selection?: [number, number], isManual?: boolean): void;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 清除上下文
|
|
15
|
+
*/
|
|
16
|
+
cleanFileContext(): void;
|
|
17
|
+
|
|
18
|
+
onDidContextFilesChangeEvent: Event<FileContext[]>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 从 context 中移除文件
|
|
22
|
+
* @param uri URI
|
|
23
|
+
*/
|
|
24
|
+
removeFileFromContext(uri: URI): void;
|
|
25
|
+
|
|
26
|
+
/** 导出为可序列化格式 */
|
|
27
|
+
serialize(): SerializedContext;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FileContext {
|
|
31
|
+
uri: URI;
|
|
32
|
+
selection?: [number, number];
|
|
33
|
+
isManual: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const LLMContextServiceToken = Symbol('LLMContextService');
|
|
37
|
+
|
|
38
|
+
export interface SerializedContext {
|
|
39
|
+
recentlyViewFiles: string[];
|
|
40
|
+
attachedFiles: Array<{ content: string; lineErrors: string[]; path: string; language: string }>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
|
|
3
|
+
export interface MCPServerManager {
|
|
4
|
+
callTool(serverName: string, toolName: string, arg_string: string): ReturnType<Client['callTool']>;
|
|
5
|
+
removeServer(name: string): void;
|
|
6
|
+
addOrUpdateServer(description: MCPServerDescription): void;
|
|
7
|
+
// invoke in node.js only
|
|
8
|
+
addOrUpdateServerDirectly(server: any): void;
|
|
9
|
+
initBuiltinServer(builtinMCPServer: any): void;
|
|
10
|
+
getTools(serverName: string): ReturnType<Client['listTools']>;
|
|
11
|
+
getServerNames(): Promise<string[]>;
|
|
12
|
+
startServer(serverName: string): Promise<void>;
|
|
13
|
+
stopServer(serverName: string): Promise<void>;
|
|
14
|
+
getStartedServers(): Promise<string[]>;
|
|
15
|
+
registerTools(serverName: string): Promise<void>;
|
|
16
|
+
addExternalMCPServers(servers: MCPServerDescription[]): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type MCPTool = Awaited<ReturnType<MCPServerManager['getTools']>>['tools'][number];
|
|
20
|
+
|
|
21
|
+
export type MCPToolParameter = Awaited<ReturnType<MCPServerManager['getTools']>>['tools'][number]['inputSchema'];
|
|
22
|
+
|
|
23
|
+
export interface MCPServerDescription {
|
|
24
|
+
/**
|
|
25
|
+
* The unique name of the MCP server.
|
|
26
|
+
*/
|
|
27
|
+
name: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The command to execute the MCP server.
|
|
31
|
+
*/
|
|
32
|
+
command: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An array of arguments to pass to the command.
|
|
36
|
+
*/
|
|
37
|
+
args?: string[];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Optional environment variables to set when starting the server.
|
|
41
|
+
*/
|
|
42
|
+
env?: { [key: string]: string };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const MCPServerManager = Symbol('MCPServerManager');
|
|
46
|
+
export const MCPServerManagerPath = 'ServicesMCPServerManager';
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
import { Injectable } from '@opensumi/di';
|
|
4
|
+
|
|
5
|
+
import { MCPToolParameter } from './mcp-server-manager';
|
|
6
|
+
|
|
7
|
+
export const ToolParameterSchema = z.object({
|
|
8
|
+
type: z.enum(['string', 'number', 'boolean', 'object', 'array']),
|
|
9
|
+
description: z.string().optional(),
|
|
10
|
+
enum: z.array(z.any()).optional(),
|
|
11
|
+
items: z.lazy(() => ToolParameterSchema).optional(),
|
|
12
|
+
properties: z.record(z.lazy(() => ToolParameterSchema)).optional(),
|
|
13
|
+
required: z.array(z.string()).optional(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type ToolParameter = z.infer<typeof ToolParameterSchema>;
|
|
17
|
+
|
|
18
|
+
export interface ToolRequest {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
parameters?: any;
|
|
22
|
+
description?: string;
|
|
23
|
+
handler: (arg_string: string) => Promise<any>;
|
|
24
|
+
providerName?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export namespace ToolRequest {
|
|
28
|
+
export function isToolParameter(obj: unknown): obj is ToolParameter {
|
|
29
|
+
return ToolParameterSchema.safeParse(obj).success;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const ToolInvocationRegistry = Symbol('ToolInvocationRegistry');
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 为 Agent 提供的所有可用函数调用的注册表
|
|
37
|
+
*/
|
|
38
|
+
export interface ToolInvocationRegistry {
|
|
39
|
+
/**
|
|
40
|
+
* 在注册表中注册一个工具
|
|
41
|
+
*
|
|
42
|
+
* @param tool - 要注册的 `ToolRequest` 对象
|
|
43
|
+
*/
|
|
44
|
+
registerTool(tool: ToolRequest): void;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 从注册表中获取特定的 `ToolRequest`
|
|
48
|
+
*
|
|
49
|
+
* @param toolId - 要获取的工具的唯一标识符
|
|
50
|
+
* @returns 对应提供的工具 ID 的 `ToolRequest` 对象,
|
|
51
|
+
* 如果在注册表中找不到该工具,则返回 `undefined`
|
|
52
|
+
*/
|
|
53
|
+
getFunction(toolId: string): ToolRequest | undefined;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 从注册表中获取多个 `ToolRequest`
|
|
57
|
+
*
|
|
58
|
+
* @param toolIds - 要获取的工具 ID 列表
|
|
59
|
+
* @returns 指定工具 ID 的 `ToolRequest` 对象数组
|
|
60
|
+
* 如果找不到某个工具 ID,将在返回的数组中跳过该工具
|
|
61
|
+
*/
|
|
62
|
+
getFunctions(...toolIds: string[]): ToolRequest[];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 获取当前注册表中的所有 `ToolRequest`
|
|
66
|
+
*
|
|
67
|
+
* @returns 注册表中所有 `ToolRequest` 对象的数组
|
|
68
|
+
*/
|
|
69
|
+
getAllFunctions(): ToolRequest[];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 注销特定工具提供者的所有工具
|
|
73
|
+
*
|
|
74
|
+
* @param providerName - 要移除其工具的工具提供者名称(在 `ToolRequest` 中指定)
|
|
75
|
+
*/
|
|
76
|
+
unregisterAllTools(providerName: string): void;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const ToolProvider = Symbol('ToolProvider');
|
|
80
|
+
export interface ToolProvider {
|
|
81
|
+
getTool(): ToolRequest;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class ToolInvocationRegistryImpl implements ToolInvocationRegistry {
|
|
85
|
+
private tools: Map<string, ToolRequest> = new Map<string, ToolRequest>();
|
|
86
|
+
|
|
87
|
+
unregisterAllTools(providerName: string): void {
|
|
88
|
+
const toolsToRemove: string[] = [];
|
|
89
|
+
for (const [id, tool] of this.tools.entries()) {
|
|
90
|
+
if (tool.providerName === providerName) {
|
|
91
|
+
toolsToRemove.push(id);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
toolsToRemove.forEach((id) => this.tools.delete(id));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getAllFunctions(): ToolRequest[] {
|
|
98
|
+
return Array.from(this.tools.values());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
registerTool(tool: ToolRequest): void {
|
|
102
|
+
if (this.tools.has(tool.id)) {
|
|
103
|
+
// TODO: 使用适当的日志机制
|
|
104
|
+
this.tools.set(tool.id, tool);
|
|
105
|
+
} else {
|
|
106
|
+
this.tools.set(tool.id, tool);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
getFunction(toolId: string): ToolRequest | undefined {
|
|
111
|
+
return this.tools.get(toolId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getFunctions(...toolIds: string[]): ToolRequest[] {
|
|
115
|
+
const tools: ToolRequest[] = toolIds.map((toolId) => {
|
|
116
|
+
const tool = this.tools.get(toolId);
|
|
117
|
+
if (tool) {
|
|
118
|
+
return tool;
|
|
119
|
+
} else {
|
|
120
|
+
throw new Error(`找不到 ID 为 ${toolId} 的函数`);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return tools;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 管理多个 ToolInvocationRegistry 实例的管理器,每个实例与一个 clientId 关联
|
|
129
|
+
*/
|
|
130
|
+
export interface IToolInvocationRegistryManager {
|
|
131
|
+
/**
|
|
132
|
+
* 获取或创建特定 clientId 的 ToolInvocationRegistry
|
|
133
|
+
*/
|
|
134
|
+
getRegistry(clientId: string): ToolInvocationRegistry;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 移除特定 clientId 的 ToolInvocationRegistry
|
|
138
|
+
*/
|
|
139
|
+
removeRegistry(clientId: string): void;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 检查特定 clientId 是否存在对应的注册表
|
|
143
|
+
*/
|
|
144
|
+
hasRegistry(clientId: string): boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export const ToolInvocationRegistryManager = Symbol('ToolInvocationRegistryManager');
|
|
148
|
+
|
|
149
|
+
@Injectable()
|
|
150
|
+
export class ToolInvocationRegistryManagerImpl implements IToolInvocationRegistryManager {
|
|
151
|
+
private registries: Map<string, ToolInvocationRegistry> = new Map();
|
|
152
|
+
|
|
153
|
+
getRegistry(clientId: string): ToolInvocationRegistry {
|
|
154
|
+
let registry = this.registries.get(clientId);
|
|
155
|
+
if (!registry) {
|
|
156
|
+
registry = new ToolInvocationRegistryImpl();
|
|
157
|
+
this.registries.set(clientId, registry);
|
|
158
|
+
}
|
|
159
|
+
return registry;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
removeRegistry(clientId: string): void {
|
|
163
|
+
this.registries.delete(clientId);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
hasRegistry(clientId: string): boolean {
|
|
167
|
+
return this.registries.has(clientId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
package/src/common/types.ts
CHANGED
|
@@ -18,3 +18,25 @@ export interface INearestCodeBlock {
|
|
|
18
18
|
offset: number;
|
|
19
19
|
type?: NearestCodeBlockType;
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
// SUMI MCP Server 网页部分暴露给 Node.js 部分的能力
|
|
23
|
+
export interface IMCPServerProxyService {
|
|
24
|
+
$callMCPTool(
|
|
25
|
+
name: string,
|
|
26
|
+
args: any,
|
|
27
|
+
): Promise<{
|
|
28
|
+
content: { type: string; text: string }[];
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
// 获取 browser 层注册的 MCP 工具列表 (Browser tab 维度)
|
|
32
|
+
$getMCPTools(): Promise<MCPTool[]>;
|
|
33
|
+
// 通知前端 MCP 服务注册表发生了变化
|
|
34
|
+
$updateMCPServers(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface MCPTool {
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
inputSchema: any;
|
|
41
|
+
providerName: string;
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AnthropicProvider, createAnthropic } from '@ai-sdk/anthropic';
|
|
2
|
+
|
|
3
|
+
import { Injectable } from '@opensumi/di';
|
|
4
|
+
import { IAIBackServiceOption } from '@opensumi/ide-core-common';
|
|
5
|
+
import { AINativeSettingSectionsId } from '@opensumi/ide-core-common/lib/settings/ai-native';
|
|
6
|
+
|
|
7
|
+
import { BaseLanguageModel } from '../base-language-model';
|
|
8
|
+
|
|
9
|
+
export const AnthropicModelIdentifier = Symbol('AnthropicModelIdentifier');
|
|
10
|
+
|
|
11
|
+
@Injectable()
|
|
12
|
+
export class AnthropicModel extends BaseLanguageModel {
|
|
13
|
+
protected initializeProvider(options: IAIBackServiceOption): AnthropicProvider {
|
|
14
|
+
const apiKey = options.apiKey;
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
throw new Error(`Please provide Anthropic API Key in preferences (${AINativeSettingSectionsId.AnthropicApiKey})`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return createAnthropic({ apiKey });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected getModelIdentifier(provider: AnthropicProvider) {
|
|
23
|
+
return provider('claude-3-5-sonnet-20241022');
|
|
24
|
+
}
|
|
25
|
+
}
|