@opensumi/ide-ai-native 3.8.1-next-1740556231.0 → 3.8.1-next-1740625266.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.contextkeys.d.ts +1 -1
- package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
- package/lib/browser/ai-core.contextkeys.js +1 -1
- package/lib/browser/ai-core.contextkeys.js.map +1 -1
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +10 -3
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +30 -1
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.d.ts +2 -1
- package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.js +4 -1
- package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +2 -2
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +5 -4
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js +4 -2
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.js +17 -11
- package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +4 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
- package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +3 -2
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +16 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/common/index.d.ts +8 -1
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +3 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/mcp-server-manager.d.ts +17 -1
- package/lib/common/mcp-server-manager.d.ts.map +1 -1
- package/lib/common/mcp-server-manager.js.map +1 -1
- package/lib/common/tool-invocation-registry.d.ts +2 -2
- package/lib/common/tool-invocation-registry.d.ts.map +1 -1
- package/lib/common/tool-invocation-registry.js +1 -1
- package/lib/common/tool-invocation-registry.js.map +1 -1
- package/lib/common/types.d.ts +6 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +2 -1
- package/lib/common/utils.js.map +1 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +5 -4
- package/lib/node/base-language-model.js.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.js +59 -6
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts +4 -3
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +26 -6
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.d.ts +5 -16
- package/lib/node/mcp-server.d.ts.map +1 -1
- package/lib/node/mcp-server.js +12 -6
- package/lib/node/mcp-server.js.map +1 -1
- package/lib/node/openai/openai-language-model.d.ts +4 -3
- package/lib/node/openai/openai-language-model.d.ts.map +1 -1
- package/lib/node/openai/openai-language-model.js +3 -2
- package/lib/node/openai/openai-language-model.js.map +1 -1
- package/package.json +27 -27
- package/src/browser/ai-core.contextkeys.ts +3 -3
- package/src/browser/ai-core.contribution.ts +13 -4
- package/src/browser/chat/chat.view.tsx +47 -0
- package/src/browser/contrib/inline-completions/inline-completions.controller.ts +1 -1
- package/src/browser/contrib/intelligent-completions/index.ts +5 -1
- package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +3 -3
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +6 -5
- package/src/browser/contrib/intelligent-completions/view/code-edits-previewer.ts +4 -2
- package/src/browser/contrib/intelligent-completions/view/default.ts +27 -19
- package/src/browser/index.ts +4 -0
- package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
- package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
- package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
- package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
- package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
- package/src/browser/mcp/mcp-server.feature.registry.ts +3 -2
- package/src/browser/preferences/schema.ts +16 -0
- package/src/common/index.ts +7 -1
- package/src/common/mcp-server-manager.ts +17 -1
- package/src/common/tool-invocation-registry.ts +2 -2
- package/src/common/types.ts +6 -0
- package/src/common/utils.ts +3 -1
- package/src/node/base-language-model.ts +7 -4
- package/src/node/mcp/sumi-mcp-server.ts +67 -9
- package/src/node/mcp-server-manager-impl.ts +30 -9
- package/src/node/mcp-server.ts +11 -14
- package/src/node/openai/openai-language-model.ts +7 -4
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Autowired, Injectable, Optional } from '@opensumi/di';
|
|
2
2
|
import { IContextKey, IContextKeyService, IScopedContextKeyService } from '@opensumi/ide-core-browser';
|
|
3
3
|
import {
|
|
4
|
+
CodeEditsIsVisible,
|
|
4
5
|
InlineChatIsVisible,
|
|
5
6
|
InlineCompletionIsTrigger,
|
|
6
7
|
InlineDiffPartialEditsIsVisible,
|
|
7
8
|
InlineHintWidgetIsVisible,
|
|
8
9
|
InlineInputWidgetIsStreaming,
|
|
9
10
|
InlineInputWidgetIsVisible,
|
|
10
|
-
MultiLineEditsIsVisible,
|
|
11
11
|
} from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
|
|
12
12
|
import { ContextKeyService } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService';
|
|
13
13
|
import { IContextKeyServiceTarget } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
|
|
@@ -25,7 +25,7 @@ export class AINativeContextKey {
|
|
|
25
25
|
public readonly inlineInputWidgetIsVisible: IContextKey<boolean>;
|
|
26
26
|
public readonly inlineInputWidgetIsStreaming: IContextKey<boolean>;
|
|
27
27
|
public readonly inlineDiffPartialEditsIsVisible: IContextKey<boolean>;
|
|
28
|
-
public readonly
|
|
28
|
+
public readonly codeEditsIsVisible: IContextKey<boolean>;
|
|
29
29
|
public get contextKeyService() {
|
|
30
30
|
return this._contextKeyService;
|
|
31
31
|
}
|
|
@@ -38,6 +38,6 @@ export class AINativeContextKey {
|
|
|
38
38
|
this.inlineInputWidgetIsVisible = InlineInputWidgetIsVisible.bind(this._contextKeyService);
|
|
39
39
|
this.inlineInputWidgetIsStreaming = InlineInputWidgetIsStreaming.bind(this._contextKeyService);
|
|
40
40
|
this.inlineDiffPartialEditsIsVisible = InlineDiffPartialEditsIsVisible.bind(this._contextKeyService);
|
|
41
|
-
this.
|
|
41
|
+
this.codeEditsIsVisible = CodeEditsIsVisible.bind(this._contextKeyService);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
AI_CHAT_LOGO_AVATAR_ID,
|
|
77
77
|
AI_CHAT_VIEW_ID,
|
|
78
78
|
AI_MENU_BAR_DEBUG_TOOLBAR,
|
|
79
|
+
BUILTIN_MCP_SERVER_NAME,
|
|
79
80
|
ChatProxyServiceToken,
|
|
80
81
|
IChatInternalService,
|
|
81
82
|
IChatManagerService,
|
|
@@ -338,15 +339,23 @@ export class AINativeBrowserContribution
|
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
if (supportsMCP) {
|
|
341
|
-
// 初始化内置 MCP Server
|
|
342
|
-
this.sumiMCPServerBackendProxy.initBuiltinMCPServer();
|
|
343
|
-
|
|
344
342
|
// 从 preferences 获取并初始化外部 MCP Servers
|
|
345
343
|
const mcpServers = this.preferenceService.getValid<MCPServerDescription[]>(
|
|
346
344
|
AINativeSettingSectionsId.MCPServers,
|
|
347
345
|
);
|
|
346
|
+
|
|
347
|
+
// 查找内置 MCP Server 的配置
|
|
348
|
+
const builtinServer = mcpServers?.find((server) => server.name === BUILTIN_MCP_SERVER_NAME);
|
|
349
|
+
|
|
350
|
+
// 总是初始化内置服务器,根据配置决定是否启用
|
|
351
|
+
this.sumiMCPServerBackendProxy.initBuiltinMCPServer(builtinServer?.enabled ?? true);
|
|
352
|
+
|
|
353
|
+
// 初始化其他外部 MCP Servers
|
|
348
354
|
if (mcpServers && mcpServers.length > 0) {
|
|
349
|
-
|
|
355
|
+
const externalServers = mcpServers.filter((server) => server.name !== BUILTIN_MCP_SERVER_NAME);
|
|
356
|
+
if (externalServers.length > 0) {
|
|
357
|
+
this.sumiMCPServerBackendProxy.initExternalMCPServers(externalServers);
|
|
358
|
+
}
|
|
350
359
|
}
|
|
351
360
|
}
|
|
352
361
|
});
|
|
@@ -3,6 +3,7 @@ import { MessageList } from 'react-chat-elements';
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
AINativeConfigService,
|
|
6
|
+
CommandService,
|
|
6
7
|
getIcon,
|
|
7
8
|
useEventEffect,
|
|
8
9
|
useInjectable,
|
|
@@ -52,6 +53,7 @@ import { ChatNotify, ChatReply } from '../components/ChatReply';
|
|
|
52
53
|
import { SlashCustomRender } from '../components/SlashCustomRender';
|
|
53
54
|
import { MessageData, createMessageByAI, createMessageByUser } from '../components/utils';
|
|
54
55
|
import { WelcomeMessage } from '../components/WelcomeMsg';
|
|
56
|
+
import { OPEN_MCP_CONFIG_COMMAND } from '../mcp/config/mcp-config.commands';
|
|
55
57
|
import { MCPServerProxyService } from '../mcp/mcp-server-proxy.service';
|
|
56
58
|
import { MCPToolsDialog } from '../mcp/mcp-tools-dialog.view';
|
|
57
59
|
import { ChatViewHeaderRender, TSlashCommandCustomRender } from '../types';
|
|
@@ -63,6 +65,7 @@ import { ChatFeatureRegistry } from './chat.feature.registry';
|
|
|
63
65
|
import { ChatInternalService } from './chat.internal.service';
|
|
64
66
|
import styles from './chat.module.less';
|
|
65
67
|
import { ChatRenderRegistry } from './chat.render.registry';
|
|
68
|
+
|
|
66
69
|
const SCROLL_CLASSNAME = 'chat_scroll';
|
|
67
70
|
|
|
68
71
|
interface TDispatchAction {
|
|
@@ -81,11 +84,15 @@ export const AIChatView = () => {
|
|
|
81
84
|
const chatRenderRegistry = useInjectable<ChatRenderRegistry>(ChatRenderRegistryToken);
|
|
82
85
|
const contextService = useInjectable<LLMContextService>(LLMContextServiceToken);
|
|
83
86
|
const promptProvider = useInjectable<ChatAgentPromptProvider>(ChatAgentPromptProvider);
|
|
87
|
+
const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
|
|
84
88
|
|
|
85
89
|
const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
|
|
86
90
|
const msgHistoryManager = aiChatService.sessionModel.history;
|
|
87
91
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
88
92
|
const chatInputRef = React.useRef<{ setInputValue: (v: string) => void } | null>(null);
|
|
93
|
+
const dialogService = useInjectable<IDialogService>(IDialogService);
|
|
94
|
+
const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
|
|
95
|
+
const commandService = useInjectable<CommandService>(CommandService);
|
|
89
96
|
|
|
90
97
|
const [shortcutCommands, setShortcutCommands] = React.useState<ChatSlashCommandItemModel[]>([]);
|
|
91
98
|
|
|
@@ -107,6 +114,8 @@ export const AIChatView = () => {
|
|
|
107
114
|
const [defaultAgentId, setDefaultAgentId] = React.useState<string>('');
|
|
108
115
|
const [command, setCommand] = React.useState('');
|
|
109
116
|
const [theme, setTheme] = React.useState<string | null>(null);
|
|
117
|
+
const [mcpToolsCount, setMcpToolsCount] = React.useState<number>(0);
|
|
118
|
+
const [mcpServersCount, setMcpServersCount] = React.useState<number>(0);
|
|
110
119
|
|
|
111
120
|
React.useEffect(() => {
|
|
112
121
|
const featureSlashCommands = chatFeatureRegistry.getAllShortcutSlashCommand();
|
|
@@ -658,6 +667,32 @@ export const AIChatView = () => {
|
|
|
658
667
|
};
|
|
659
668
|
}, [aiChatService.sessionModel]);
|
|
660
669
|
|
|
670
|
+
useEventEffect(
|
|
671
|
+
mcpServerProxyService.onChangeMCPServers,
|
|
672
|
+
() => {
|
|
673
|
+
mcpServerProxyService.getAllMCPTools().then((tools) => {
|
|
674
|
+
setMcpToolsCount(tools.length);
|
|
675
|
+
});
|
|
676
|
+
mcpServerProxyService.$getServers().then((servers) => {
|
|
677
|
+
setMcpServersCount(servers.length);
|
|
678
|
+
});
|
|
679
|
+
},
|
|
680
|
+
[mcpServerProxyService],
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
const handleShowMCPTools = React.useCallback(async () => {
|
|
684
|
+
const tools = await mcpServerProxyService.getAllMCPTools();
|
|
685
|
+
dialogService.open({
|
|
686
|
+
message: <MCPToolsDialog tools={tools} />,
|
|
687
|
+
type: MessageType.Empty,
|
|
688
|
+
buttons: ['关闭'],
|
|
689
|
+
});
|
|
690
|
+
}, [mcpServerProxyService, dialogService]);
|
|
691
|
+
|
|
692
|
+
const handleShowMCPConfig = React.useCallback(() => {
|
|
693
|
+
commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
|
|
694
|
+
}, [commandService]);
|
|
695
|
+
|
|
661
696
|
return (
|
|
662
697
|
<div id={styles.ai_chat_view}>
|
|
663
698
|
<div className={styles.header_container}>
|
|
@@ -697,6 +732,18 @@ export const AIChatView = () => {
|
|
|
697
732
|
</Popover>
|
|
698
733
|
))}
|
|
699
734
|
</div>
|
|
735
|
+
<div className={styles.header_operate_right}>
|
|
736
|
+
{aiNativeConfigService.capabilities.supportsMCP && (
|
|
737
|
+
<>
|
|
738
|
+
<div className={styles.tag} onClick={handleShowMCPConfig}>
|
|
739
|
+
{`MCP Servers: ${mcpServersCount}`}
|
|
740
|
+
</div>
|
|
741
|
+
<div className={styles.tag} onClick={handleShowMCPTools}>
|
|
742
|
+
{`MCP Tools: ${mcpToolsCount}`}
|
|
743
|
+
</div>
|
|
744
|
+
</>
|
|
745
|
+
)}
|
|
746
|
+
</div>
|
|
700
747
|
</div>
|
|
701
748
|
<ChatInputWrapperRender
|
|
702
749
|
onSend={(value, agentId, command) =>
|
|
@@ -170,7 +170,7 @@ export class InlineCompletionsController extends BaseAIMonacoEditorController {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// 如果上一次补全结果还在,则不重复请求
|
|
173
|
-
const isVisible = this.aiNativeContextKey.
|
|
173
|
+
const isVisible = this.aiNativeContextKey.codeEditsIsVisible.get();
|
|
174
174
|
if (isVisible) {
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
@@ -69,7 +69,11 @@ export class CodeEditsResultValue<T extends ICodeEdit = ICodeEdit> extends Dispo
|
|
|
69
69
|
}));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
public get
|
|
72
|
+
public get firstRange(): IRange {
|
|
73
73
|
return this.raw.items[0].range;
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
public get firstText(): string {
|
|
77
|
+
return this.raw.items[0].insertText;
|
|
78
|
+
}
|
|
75
79
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
KeybindingScope,
|
|
9
9
|
} from '@opensumi/ide-core-browser';
|
|
10
10
|
import { AI_CODE_EDITS_COMMANDS } from '@opensumi/ide-core-browser/lib/ai-native/command';
|
|
11
|
-
import {
|
|
11
|
+
import { CodeEditsIsVisible } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
|
|
12
12
|
import { CommandContribution, CommandRegistry, Domain } from '@opensumi/ide-core-common';
|
|
13
13
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
14
14
|
import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service';
|
|
@@ -61,7 +61,7 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
61
61
|
keybindings.registerKeybinding({
|
|
62
62
|
command: AI_CODE_EDITS_COMMANDS.DISCARD.id,
|
|
63
63
|
keybinding: Key.ESCAPE.code,
|
|
64
|
-
when:
|
|
64
|
+
when: CodeEditsIsVisible.raw,
|
|
65
65
|
priority: 100,
|
|
66
66
|
});
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ export class IntelligentCompletionsContribution implements KeybindingContributio
|
|
|
69
69
|
{
|
|
70
70
|
command: AI_CODE_EDITS_COMMANDS.ACCEPT.id,
|
|
71
71
|
keybinding: Key.TAB.code,
|
|
72
|
-
when:
|
|
72
|
+
when: CodeEditsIsVisible.raw,
|
|
73
73
|
},
|
|
74
74
|
KeybindingScope.USER,
|
|
75
75
|
);
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
KeybindingScope,
|
|
6
6
|
PreferenceService,
|
|
7
7
|
} from '@opensumi/ide-core-browser';
|
|
8
|
-
import {
|
|
8
|
+
import { CodeEditsIsVisible } from '@opensumi/ide-core-browser/lib/contextkey/ai-native';
|
|
9
9
|
import {
|
|
10
10
|
AINativeSettingSectionsId,
|
|
11
11
|
CodeEditsRT,
|
|
@@ -98,13 +98,13 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
98
98
|
this.monacoEditor,
|
|
99
99
|
]);
|
|
100
100
|
|
|
101
|
-
const multiLineEditsIsVisibleKey = new Set([
|
|
101
|
+
const multiLineEditsIsVisibleKey = new Set([CodeEditsIsVisible.raw]);
|
|
102
102
|
this.multiLineEditsIsVisibleObs = observableFromEvent(
|
|
103
103
|
this,
|
|
104
104
|
Event.filter(this.aiNativeContextKey.contextKeyService!.onDidChangeContext, (e: ContextKeyChangeEvent) =>
|
|
105
105
|
e.payload.affectsSome(multiLineEditsIsVisibleKey),
|
|
106
106
|
),
|
|
107
|
-
() => !!this.aiNativeContextKey.
|
|
107
|
+
() => !!this.aiNativeContextKey.codeEditsIsVisible.get(),
|
|
108
108
|
);
|
|
109
109
|
|
|
110
110
|
this.registerFeature(this.monacoEditor);
|
|
@@ -205,7 +205,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
205
205
|
|
|
206
206
|
public hide() {
|
|
207
207
|
this.cancelToken();
|
|
208
|
-
this.aiNativeContextKey.
|
|
208
|
+
this.aiNativeContextKey.codeEditsIsVisible.reset();
|
|
209
209
|
this.codeEditsPreviewer.hide();
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -273,6 +273,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
273
273
|
public trigger(tx: ITransaction): void {
|
|
274
274
|
const triggerSource = this.codeEditsSourceCollection.getSource(TriggerCodeEditsSource) as TriggerCodeEditsSource;
|
|
275
275
|
if (triggerSource) {
|
|
276
|
+
this.hide();
|
|
276
277
|
triggerSource.triggerSignal.trigger(tx);
|
|
277
278
|
}
|
|
278
279
|
}
|
|
@@ -314,7 +315,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
314
315
|
handleChange: (context) => {
|
|
315
316
|
if (context.didChange(this.codeEditsSourceCollection.codeEditsContextBean)) {
|
|
316
317
|
// 如果上一次补全结果还在,则不重复请求
|
|
317
|
-
const isVisible = this.aiNativeContextKey.
|
|
318
|
+
const isVisible = this.aiNativeContextKey.codeEditsIsVisible.get();
|
|
318
319
|
return !isVisible;
|
|
319
320
|
}
|
|
320
321
|
return false;
|
|
@@ -51,19 +51,21 @@ export class CodeEditsPreviewer extends Disposable {
|
|
|
51
51
|
|
|
52
52
|
public render(completionModel: CodeEditsResultValue) {
|
|
53
53
|
this.view?.render(completionModel);
|
|
54
|
-
this.aiNativeContextKey.
|
|
54
|
+
this.aiNativeContextKey.codeEditsIsVisible.set(true);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
public hide() {
|
|
58
58
|
this.view?.hide();
|
|
59
|
-
this.aiNativeContextKey.
|
|
59
|
+
this.aiNativeContextKey.codeEditsIsVisible.set(false);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
public accept() {
|
|
63
63
|
this.view?.accept();
|
|
64
|
+
this.aiNativeContextKey.codeEditsIsVisible.set(false);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
public discard() {
|
|
67
68
|
this.view?.discard();
|
|
69
|
+
this.aiNativeContextKey.codeEditsIsVisible.set(false);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
@@ -80,17 +80,23 @@ export class DefaultCodeEditsView extends BaseCodeEditsView {
|
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
83
|
+
const position = this.editorObs.positions.get()?.[0];
|
|
84
|
+
if (!position) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
const model = this.editorObs.model.get();
|
|
89
|
+
if (!model) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
93
92
|
|
|
93
|
+
const originalContent = model.getValueInRange(completionModel.firstRange);
|
|
94
|
+
// edits 的内容与原内容一样就不展示
|
|
95
|
+
if (originalContent === completionModel.firstText) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
asyncTransaction(async (tx) => {
|
|
94
100
|
const versionId = this.editorObs.versionId.get();
|
|
95
101
|
const context: InlineCompletionContext = {
|
|
96
102
|
triggerKind: InlineCompletionTriggerKind.Automatic,
|
|
@@ -103,16 +109,16 @@ export class DefaultCodeEditsView extends BaseCodeEditsView {
|
|
|
103
109
|
const inlineEdits: InlineCompletionProviderResult = await provideInlineCompletions(
|
|
104
110
|
{
|
|
105
111
|
all: () => [
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
{
|
|
113
|
+
provideInlineCompletions: () => {},
|
|
114
|
+
provideInlineEditsForRange(model, range, context, token) {
|
|
115
|
+
return completionModel;
|
|
116
|
+
},
|
|
117
|
+
freeInlineCompletions: () => [],
|
|
118
|
+
} as InlineCompletionsProvider<ICodeEditsResult<ICodeEdit>>,
|
|
119
|
+
],
|
|
114
120
|
} as unknown as LanguageFeatureRegistry<InlineCompletionsProvider>,
|
|
115
|
-
Range.lift(completionModel.
|
|
121
|
+
Range.lift(completionModel.firstRange),
|
|
116
122
|
model,
|
|
117
123
|
context,
|
|
118
124
|
);
|
|
@@ -122,9 +128,11 @@ export class DefaultCodeEditsView extends BaseCodeEditsView {
|
|
|
122
128
|
request,
|
|
123
129
|
model,
|
|
124
130
|
this.editorObs.versionId,
|
|
125
|
-
constObservable(
|
|
131
|
+
constObservable(4000),
|
|
126
132
|
);
|
|
133
|
+
|
|
127
134
|
source.inlineCompletions.set(completions, tx);
|
|
135
|
+
source.loading.set(false, tx);
|
|
128
136
|
});
|
|
129
137
|
}
|
|
130
138
|
|
package/src/browser/index.ts
CHANGED
|
@@ -55,6 +55,8 @@ import { RenameCandidatesProviderRegistry } from './contrib/rename/rename.featur
|
|
|
55
55
|
import { TerminalAIContribution } from './contrib/terminal/terminal-ai.contributon';
|
|
56
56
|
import { TerminalFeatureRegistry } from './contrib/terminal/terminal.feature.registry';
|
|
57
57
|
import { LanguageParserService } from './languages/service';
|
|
58
|
+
import { MCPConfigCommandContribution } from './mcp/config/mcp-config.commands';
|
|
59
|
+
import { MCPConfigContribution } from './mcp/config/mcp-config.contribution';
|
|
58
60
|
import { MCPServerProxyService } from './mcp/mcp-server-proxy.service';
|
|
59
61
|
import { MCPServerRegistry } from './mcp/mcp-server.feature.registry';
|
|
60
62
|
import { CreateNewFileWithTextTool } from './mcp/tools/createNewFileWithText';
|
|
@@ -91,6 +93,8 @@ export class AINativeModule extends BrowserModule {
|
|
|
91
93
|
AICodeActionContribution,
|
|
92
94
|
AINativePreferencesContribution,
|
|
93
95
|
IntelligentCompletionsContribution,
|
|
96
|
+
MCPConfigContribution,
|
|
97
|
+
MCPConfigCommandContribution,
|
|
94
98
|
|
|
95
99
|
// MCP Server Contributions START
|
|
96
100
|
ListDirTool,
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
padding: 20px;
|
|
3
|
+
color: var(--foreground);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.header {
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: space-between;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
margin-bottom: 24px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.title {
|
|
14
|
+
margin: 0 0 8px 0;
|
|
15
|
+
font-size: 24px;
|
|
16
|
+
font-weight: 600;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.description {
|
|
20
|
+
margin: 0;
|
|
21
|
+
color: var(--descriptionForeground);
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.addButton {
|
|
26
|
+
padding: 8px 16px;
|
|
27
|
+
border-radius: 4px;
|
|
28
|
+
background-color: var(--button-primary-background);
|
|
29
|
+
color: var(--button-primary-foreground);
|
|
30
|
+
border: none;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
font-size: 13px;
|
|
33
|
+
|
|
34
|
+
&:hover {
|
|
35
|
+
background-color: var(--button-primary-hover-background);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.serversList {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: 12px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.serverItem {
|
|
46
|
+
padding: 16px;
|
|
47
|
+
border-radius: 8px;
|
|
48
|
+
background-color: var(--editorWidget-background);
|
|
49
|
+
border: 1px solid var(--border-color);
|
|
50
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
51
|
+
transition: all 0.2s ease;
|
|
52
|
+
|
|
53
|
+
&:hover {
|
|
54
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
|
55
|
+
border-color: var(--focusBorder);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.serverHeader {
|
|
60
|
+
display: flex;
|
|
61
|
+
justify-content: space-between;
|
|
62
|
+
align-items: center;
|
|
63
|
+
margin-bottom: 12px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.serverTitleRow {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: 8px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.serverName {
|
|
73
|
+
margin: 0;
|
|
74
|
+
font-size: 14px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.serverStatus,
|
|
79
|
+
.serverType {
|
|
80
|
+
font-size: 12px;
|
|
81
|
+
padding: 2px 8px;
|
|
82
|
+
border-radius: 12px;
|
|
83
|
+
font-weight: 500;
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.serverType {
|
|
89
|
+
background-color: var(--editor-background);
|
|
90
|
+
color: var(--descriptionForeground);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.running {
|
|
94
|
+
background-color: var(--notification-info-background);
|
|
95
|
+
color: var(--notification-info-foreground);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.stopped {
|
|
99
|
+
background-color: var(--notification-error-background);
|
|
100
|
+
color: var(--notification-error-foreground);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.serverActions {
|
|
104
|
+
display: flex;
|
|
105
|
+
gap: 4px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.iconButton {
|
|
109
|
+
padding: 4px;
|
|
110
|
+
border: none;
|
|
111
|
+
background: none;
|
|
112
|
+
color: var(--icon-foreground);
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
border-radius: 4px;
|
|
115
|
+
|
|
116
|
+
&:hover {
|
|
117
|
+
background-color: var(--list-hover-background);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.serverDetail {
|
|
122
|
+
margin-top: 12px;
|
|
123
|
+
padding: 12px;
|
|
124
|
+
border-radius: 6px;
|
|
125
|
+
background-color: var(--editor-background);
|
|
126
|
+
font-size: 13px;
|
|
127
|
+
|
|
128
|
+
&:not(:last-child) {
|
|
129
|
+
margin-bottom: 8px;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.detailRow {
|
|
134
|
+
display: flex;
|
|
135
|
+
gap: 8px;
|
|
136
|
+
margin-bottom: 4px;
|
|
137
|
+
align-items: center;
|
|
138
|
+
|
|
139
|
+
&:last-child {
|
|
140
|
+
margin-bottom: 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.detailLabel {
|
|
145
|
+
color: var(--descriptionForeground);
|
|
146
|
+
min-width: 70px;
|
|
147
|
+
height: 24px;
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.detailContent {
|
|
153
|
+
color: var(--foreground);
|
|
154
|
+
word-break: break-all;
|
|
155
|
+
flex: 1;
|
|
156
|
+
background-color: var(--editor-background);
|
|
157
|
+
padding: 4px 8px;
|
|
158
|
+
border-radius: 4px;
|
|
159
|
+
font-family: var(--monaco-monospace-font);
|
|
160
|
+
min-height: 24px;
|
|
161
|
+
display: flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
gap: 8px;
|
|
164
|
+
flex-wrap: wrap;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.toolTag {
|
|
168
|
+
display: inline-flex;
|
|
169
|
+
align-items: center;
|
|
170
|
+
padding: 2px 8px;
|
|
171
|
+
background-color: var(--editorWidget-background);
|
|
172
|
+
color: var(--button-secondary-foreground);
|
|
173
|
+
border-radius: 12px;
|
|
174
|
+
font-size: 12px;
|
|
175
|
+
font-weight: 500;
|
|
176
|
+
transition: all 0.2s ease;
|
|
177
|
+
border: 1px solid var(--border-color);
|
|
178
|
+
}
|