@opensumi/ide-ai-native 3.7.1-next-1737628160.0 → 3.7.1-next-1737703128.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 +31 -4
- 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 +21 -9
- 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 +11 -0
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/components/ChatEditor.d.ts +8 -0
- package/lib/browser/components/ChatEditor.d.ts.map +1 -1
- package/lib/browser/components/ChatEditor.js +8 -7
- package/lib/browser/components/ChatEditor.js.map +1 -1
- package/lib/browser/components/ChatReply.d.ts.map +1 -1
- package/lib/browser/components/ChatReply.js +33 -4
- 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 +24 -0
- package/lib/browser/components/ChatToolRender.js.map +1 -0
- package/lib/browser/components/components.module.less +32 -31
- package/lib/browser/contrib/intelligent-completions/index.d.ts +1 -5
- package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.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 +1 -2
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/base.d.ts +2 -1
- package/lib/browser/contrib/intelligent-completions/source/base.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/base.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts +3 -2
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.js +21 -51
- package/lib/browser/contrib/intelligent-completions/source/line-change.source.js.map +1 -1
- package/lib/browser/index.d.ts +11 -3
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +39 -3
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +17 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.js +36 -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 +45 -0
- package/lib/browser/mcp/mcp-server.feature.registry.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 +84 -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/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +0 -4
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +31 -0
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/types.js +4 -1
- package/lib/browser/types.js.map +1 -1
- package/lib/common/index.d.ts +5 -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/mcp-server-manager.d.ts +39 -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 +67 -0
- package/lib/common/tool-invocation-registry.d.ts.map +1 -0
- package/lib/common/tool-invocation-registry.js +68 -0
- package/lib/common/tool-invocation-registry.js.map +1 -0
- package/lib/common/types.d.ts +14 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/node/anthropic/anthropic-language-model.d.ts +13 -0
- package/lib/node/anthropic/anthropic-language-model.d.ts.map +1 -0
- package/lib/node/anthropic/anthropic-language-model.js +79 -0
- package/lib/node/anthropic/anthropic-language-model.js.map +1 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +21 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +84 -0
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -0
- package/lib/node/mcp/sumi-mcp-server.js +134 -0
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -0
- package/lib/node/mcp-server-manager-impl.d.ts +20 -0
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -0
- package/lib/node/mcp-server-manager-impl.js +123 -0
- package/lib/node/mcp-server-manager-impl.js.map +1 -0
- package/lib/node/mcp-server.d.ts +205 -0
- package/lib/node/mcp-server.d.ts.map +1 -0
- package/lib/node/mcp-server.js +86 -0
- package/lib/node/mcp-server.js.map +1 -0
- package/lib/node/openai/openai-language-model.d.ts +12 -0
- package/lib/node/openai/openai-language-model.d.ts.map +1 -0
- package/lib/node/openai/openai-language-model.js +136 -0
- package/lib/node/openai/openai-language-model.js.map +1 -0
- package/package.json +26 -21
- package/src/browser/ai-core.contribution.ts +47 -4
- package/src/browser/chat/chat-model.ts +21 -9
- package/src/browser/chat/chat-proxy.service.ts +12 -0
- package/src/browser/components/ChatEditor.tsx +6 -4
- package/src/browser/components/ChatReply.tsx +40 -4
- package/src/browser/components/ChatToolRender.tsx +27 -0
- package/src/browser/components/components.module.less +32 -31
- package/src/browser/contrib/intelligent-completions/index.ts +2 -3
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +1 -2
- package/src/browser/contrib/intelligent-completions/source/base.ts +2 -0
- package/src/browser/contrib/intelligent-completions/source/line-change.source.ts +24 -79
- package/src/browser/index.ts +50 -4
- package/src/browser/mcp/mcp-server-proxy.service.ts +32 -0
- package/src/browser/mcp/mcp-server.feature.registry.ts +47 -0
- package/src/browser/mcp/tools/createNewFileWithText.ts +85 -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/preferences/schema.ts +0 -4
- package/src/browser/types.ts +39 -0
- package/src/common/index.ts +9 -0
- package/src/common/mcp-server-manager.ts +45 -0
- package/src/common/tool-invocation-registry.ts +124 -0
- package/src/common/types.ts +18 -0
- package/src/node/anthropic/anthropic-language-model.ts +96 -0
- package/src/node/index.ts +24 -0
- package/src/node/mcp/sumi-mcp-server.ts +161 -0
- package/src/node/mcp-server-manager-impl.ts +130 -0
- package/src/node/mcp-server.ts +118 -0
- package/src/node/openai/openai-language-model.ts +152 -0
- package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts +0 -9
- package/lib/browser/contrib/intelligent-completions/source/typing.source.d.ts.map +0 -1
- package/lib/browser/contrib/intelligent-completions/source/typing.source.js +0 -38
- package/lib/browser/contrib/intelligent-completions/source/typing.source.js.map +0 -1
- package/src/browser/contrib/intelligent-completions/source/typing.source.ts +0 -36
|
@@ -70,7 +70,11 @@ import {
|
|
|
70
70
|
AI_CHAT_VIEW_ID,
|
|
71
71
|
AI_MENU_BAR_DEBUG_TOOLBAR,
|
|
72
72
|
ChatProxyServiceToken,
|
|
73
|
+
ISumiMCPServerBackend,
|
|
74
|
+
SumiMCPServerProxyServicePath,
|
|
73
75
|
} from '../common';
|
|
76
|
+
import { MCPServerDescription, MCPServerManager, MCPServerManagerPath } from '../common/mcp-server-manager';
|
|
77
|
+
import { ToolInvocationRegistry, ToolInvocationRegistryImpl } from '../common/tool-invocation-registry';
|
|
74
78
|
|
|
75
79
|
import { ChatProxyService } from './chat/chat-proxy.service';
|
|
76
80
|
import { AIChatView } from './chat/chat.view';
|
|
@@ -94,10 +98,13 @@ import {
|
|
|
94
98
|
IChatFeatureRegistry,
|
|
95
99
|
IChatRenderRegistry,
|
|
96
100
|
IIntelligentCompletionsRegistry,
|
|
101
|
+
IMCPServerRegistry,
|
|
97
102
|
IProblemFixProviderRegistry,
|
|
98
103
|
IRenameCandidatesProviderRegistry,
|
|
99
104
|
IResolveConflictRegistry,
|
|
100
105
|
ITerminalProviderRegistry,
|
|
106
|
+
MCPServerContribution,
|
|
107
|
+
TokenMCPServerRegistry,
|
|
101
108
|
} from './types';
|
|
102
109
|
import { InlineChatEditorController } from './widget/inline-chat/inline-chat-editor.controller';
|
|
103
110
|
import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
|
|
@@ -142,6 +149,12 @@ export class AINativeBrowserContribution
|
|
|
142
149
|
@Autowired(AINativeCoreContribution)
|
|
143
150
|
private readonly contributions: ContributionProvider<AINativeCoreContribution>;
|
|
144
151
|
|
|
152
|
+
@Autowired(MCPServerContribution)
|
|
153
|
+
private readonly mcpServerContributions: ContributionProvider<MCPServerContribution>;
|
|
154
|
+
|
|
155
|
+
@Autowired(TokenMCPServerRegistry)
|
|
156
|
+
private readonly mcpServerRegistry: IMCPServerRegistry;
|
|
157
|
+
|
|
145
158
|
@Autowired(InlineChatFeatureRegistryToken)
|
|
146
159
|
private readonly inlineChatFeatureRegistry: InlineChatFeatureRegistry;
|
|
147
160
|
|
|
@@ -205,6 +218,12 @@ export class AINativeBrowserContribution
|
|
|
205
218
|
@Autowired(CodeActionSingleHandler)
|
|
206
219
|
private readonly codeActionSingleHandler: CodeActionSingleHandler;
|
|
207
220
|
|
|
221
|
+
// @Autowired(MCPServerManagerPath)
|
|
222
|
+
// private readonly mcpServerManager: MCPServerManager;
|
|
223
|
+
|
|
224
|
+
@Autowired(SumiMCPServerProxyServicePath)
|
|
225
|
+
private readonly sumiMCPServerBackendProxy: ISumiMCPServerBackend;
|
|
226
|
+
|
|
208
227
|
constructor() {
|
|
209
228
|
this.registerFeature();
|
|
210
229
|
}
|
|
@@ -303,6 +322,11 @@ export class AINativeBrowserContribution
|
|
|
303
322
|
contribution.registerIntelligentCompletionFeature?.(this.intelligentCompletionsRegistry);
|
|
304
323
|
contribution.registerProblemFixFeature?.(this.problemFixProviderRegistry);
|
|
305
324
|
});
|
|
325
|
+
|
|
326
|
+
// 注册 Opensumi 框架提供的 MCP Server Tools 能力 (此时的 Opensumi 作为 MCP Server)
|
|
327
|
+
this.mcpServerContributions.getContributions().forEach((contribution) => {
|
|
328
|
+
contribution.registerMCPServer(this.mcpServerRegistry);
|
|
329
|
+
});
|
|
306
330
|
}
|
|
307
331
|
|
|
308
332
|
registerSetting(registry: ISettingRegistry) {
|
|
@@ -365,10 +389,6 @@ export class AINativeBrowserContribution
|
|
|
365
389
|
id: AINativeSettingSectionsId.CodeEditsLineChange,
|
|
366
390
|
localized: 'preference.ai.native.codeEdits.lineChange',
|
|
367
391
|
},
|
|
368
|
-
{
|
|
369
|
-
id: AINativeSettingSectionsId.CodeEditsTyping,
|
|
370
|
-
localized: 'preference.ai.native.codeEdits.typing',
|
|
371
|
-
},
|
|
372
392
|
],
|
|
373
393
|
});
|
|
374
394
|
}
|
|
@@ -411,6 +431,29 @@ export class AINativeBrowserContribution
|
|
|
411
431
|
}
|
|
412
432
|
|
|
413
433
|
registerCommands(commands: CommandRegistry): void {
|
|
434
|
+
commands.registerCommand(
|
|
435
|
+
{ id: 'ai.native.mcp.start', label: 'MCP: Start MCP Server' },
|
|
436
|
+
{
|
|
437
|
+
execute: async () => {
|
|
438
|
+
// this.mcpServerManager.initBuiltinServer();
|
|
439
|
+
|
|
440
|
+
this.sumiMCPServerBackendProxy.initBuiltinMCPServer();
|
|
441
|
+
|
|
442
|
+
const description: MCPServerDescription = {
|
|
443
|
+
name: 'filesystem',
|
|
444
|
+
command: 'npx',
|
|
445
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/Users/retrox/AlipayProjects/core'],
|
|
446
|
+
env: {},
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
// this.mcpServerManager.addOrUpdateServer(description);
|
|
450
|
+
|
|
451
|
+
// await this.mcpServerManager.startServer(description.name);
|
|
452
|
+
// await this.mcpServerManager.collectTools(description.name);
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
);
|
|
456
|
+
|
|
414
457
|
commands.registerCommand(AI_INLINE_CHAT_VISIBLE, {
|
|
415
458
|
execute: (value: boolean) => {
|
|
416
459
|
this.aiInlineChatService._onInlineChatVisible.fire(value);
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
IChatComponent,
|
|
7
7
|
IChatMarkdownContent,
|
|
8
8
|
IChatProgress,
|
|
9
|
+
IChatToolContent,
|
|
9
10
|
IChatTreeData,
|
|
10
11
|
ILogger,
|
|
11
12
|
memoize,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
import { MsgHistoryManager } from '../model/msg-history-manager';
|
|
27
28
|
import { IChatSlashCommandItem } from '../types';
|
|
28
29
|
|
|
29
|
-
export type IChatProgressResponseContent = IChatMarkdownContent | IChatAsyncContent | IChatTreeData | IChatComponent;
|
|
30
|
+
export type IChatProgressResponseContent = IChatMarkdownContent | IChatAsyncContent | IChatTreeData | IChatComponent | IChatToolContent;
|
|
30
31
|
|
|
31
32
|
@Injectable({ multiple: true })
|
|
32
33
|
export class ChatResponseModel extends Disposable {
|
|
@@ -81,8 +82,8 @@ export class ChatResponseModel extends Disposable {
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
updateContent(progress: IChatProgress, quiet?: boolean): void {
|
|
85
|
+
const responsePartLength = this.#responseParts.length - 1;
|
|
84
86
|
if (progress.kind === 'content' || progress.kind === 'markdownContent') {
|
|
85
|
-
const responsePartLength = this.#responseParts.length - 1;
|
|
86
87
|
const lastResponsePart = this.#responseParts[responsePartLength];
|
|
87
88
|
|
|
88
89
|
if (!lastResponsePart || lastResponsePart.kind !== 'markdownContent') {
|
|
@@ -120,11 +121,19 @@ export class ChatResponseModel extends Disposable {
|
|
|
120
121
|
}
|
|
121
122
|
this.#updateResponseText(quiet);
|
|
122
123
|
});
|
|
123
|
-
} else if (progress.kind === 'treeData') {
|
|
124
|
+
} else if (progress.kind === 'treeData' || progress.kind === 'component') {
|
|
124
125
|
this.#responseParts.push(progress);
|
|
125
126
|
this.#updateResponseText(quiet);
|
|
126
|
-
} else if (progress.kind === '
|
|
127
|
-
|
|
127
|
+
} else if (progress.kind === 'toolCall') {
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
const find: IChatToolContent | undefined = this.#responseParts.find((item) => item.kind === 'toolCall' && (item.content.id === progress.content.id || item.content.index === progress.content.index));
|
|
130
|
+
if (find) {
|
|
131
|
+
find.content.function.arguments = find.content.function.arguments + progress.content.function.arguments;
|
|
132
|
+
this.#responseParts[responsePartLength] = find;
|
|
133
|
+
} else {
|
|
134
|
+
this.#responseParts.push(progress);
|
|
135
|
+
}
|
|
136
|
+
console.log("🚀 ~ ChatResponseModel ~ updateContent ~ this.#responseParts:", this.#responseParts)
|
|
128
137
|
this.#updateResponseText(quiet);
|
|
129
138
|
}
|
|
130
139
|
}
|
|
@@ -141,6 +150,9 @@ export class ChatResponseModel extends Disposable {
|
|
|
141
150
|
if (part.kind === 'component') {
|
|
142
151
|
return '';
|
|
143
152
|
}
|
|
153
|
+
if (part.kind === 'toolCall') {
|
|
154
|
+
return part.content.function.name;
|
|
155
|
+
}
|
|
144
156
|
return part.content.value;
|
|
145
157
|
})
|
|
146
158
|
.join('\n\n');
|
|
@@ -162,9 +174,9 @@ export class ChatResponseModel extends Disposable {
|
|
|
162
174
|
}
|
|
163
175
|
this.#responseContents = result;
|
|
164
176
|
|
|
165
|
-
if (!quiet) {
|
|
177
|
+
// if (!quiet) {
|
|
166
178
|
this.#onDidChange.fire();
|
|
167
|
-
}
|
|
179
|
+
// }
|
|
168
180
|
}
|
|
169
181
|
|
|
170
182
|
complete(): void {
|
|
@@ -258,10 +270,10 @@ export class ChatModel extends Disposable implements IChatModel {
|
|
|
258
270
|
|
|
259
271
|
const { kind } = progress;
|
|
260
272
|
|
|
261
|
-
const basicKind = ['content', 'markdownContent', 'asyncContent', 'treeData', 'component'];
|
|
273
|
+
const basicKind = ['content', 'markdownContent', 'asyncContent', 'treeData', 'component', 'toolCall'];
|
|
262
274
|
|
|
263
275
|
if (basicKind.includes(kind)) {
|
|
264
|
-
request.response.updateContent(progress,
|
|
276
|
+
request.response.updateContent(progress, false);
|
|
265
277
|
} else {
|
|
266
278
|
this.logger.error(`Couldn't handle progress: ${JSON.stringify(progress)}`);
|
|
267
279
|
}
|
|
@@ -25,6 +25,9 @@ import {
|
|
|
25
25
|
|
|
26
26
|
import { ChatService } from './chat.api.service';
|
|
27
27
|
import { ChatFeatureRegistry } from './chat.feature.registry';
|
|
28
|
+
import { ChatAgentViewServiceToken } from '@opensumi/ide-core-common';
|
|
29
|
+
import { IChatAgentViewService } from '../types';
|
|
30
|
+
import { ChatToolRender } from '../components/ChatToolRender';
|
|
28
31
|
|
|
29
32
|
/**
|
|
30
33
|
* @internal
|
|
@@ -52,9 +55,18 @@ export class ChatProxyService extends Disposable {
|
|
|
52
55
|
@Autowired(IAIReporter)
|
|
53
56
|
private readonly aiReporter: IAIReporter;
|
|
54
57
|
|
|
58
|
+
@Autowired(ChatAgentViewServiceToken)
|
|
59
|
+
private readonly chatAgentViewService: IChatAgentViewService;
|
|
60
|
+
|
|
55
61
|
private chatDeferred: Deferred<void> = new Deferred<void>();
|
|
56
62
|
|
|
57
63
|
public registerDefaultAgent() {
|
|
64
|
+
this.chatAgentViewService.registerChatComponent({
|
|
65
|
+
id: 'toolCall',
|
|
66
|
+
component: ChatToolRender,
|
|
67
|
+
initialProps: {},
|
|
68
|
+
});
|
|
69
|
+
|
|
58
70
|
this.addDispose(
|
|
59
71
|
this.chatAgentService.registerAgent({
|
|
60
72
|
id: ChatProxyService.AGENT_ID,
|
|
@@ -130,11 +130,12 @@ export const CodeEditorWithHighlight = (props: Props) => {
|
|
|
130
130
|
);
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
-
const CodeBlock = ({
|
|
133
|
+
export const CodeBlock = ({
|
|
134
134
|
content = '',
|
|
135
135
|
relationId,
|
|
136
136
|
renderText,
|
|
137
137
|
agentId = '',
|
|
138
|
+
language = '',
|
|
138
139
|
command = '',
|
|
139
140
|
}: {
|
|
140
141
|
content?: string;
|
|
@@ -142,14 +143,15 @@ const CodeBlock = ({
|
|
|
142
143
|
renderText?: (t: string) => React.ReactNode;
|
|
143
144
|
agentId?: string;
|
|
144
145
|
command?: string;
|
|
146
|
+
language?: string;
|
|
145
147
|
}) => {
|
|
146
148
|
const rgInlineCode = /`([^`]+)`/g;
|
|
147
149
|
const rgBlockCode = /```([^]+?)```/g;
|
|
148
150
|
const rgBlockCodeBefore = /```([^]+)?/g;
|
|
149
151
|
|
|
150
152
|
const renderCodeEditor = (content: string) => {
|
|
151
|
-
const
|
|
152
|
-
const heighLightLang = highLightLanguageSupport.find((lang) => lang ===
|
|
153
|
+
const _language = content.split('\n')[0].trim().toLowerCase();
|
|
154
|
+
const heighLightLang = highLightLanguageSupport.find((lang) => lang === _language) || 'plaintext';
|
|
153
155
|
|
|
154
156
|
content = content.replace(/.*?\n/, '');
|
|
155
157
|
content = content.trim();
|
|
@@ -158,7 +160,7 @@ const CodeBlock = ({
|
|
|
158
160
|
<div className={styles.code_language}>{capitalize(heighLightLang)}</div>
|
|
159
161
|
<CodeEditorWithHighlight
|
|
160
162
|
input={content}
|
|
161
|
-
language={language}
|
|
163
|
+
language={_language || language}
|
|
162
164
|
relationId={relationId}
|
|
163
165
|
agentId={agentId}
|
|
164
166
|
command={command}
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
IChatComponent,
|
|
39
39
|
IChatContent,
|
|
40
40
|
IChatResponseProgressFileTreeData,
|
|
41
|
+
IChatToolContent,
|
|
41
42
|
URI,
|
|
42
43
|
} from '@opensumi/ide-core-common';
|
|
43
44
|
import { IIconService } from '@opensumi/ide-theme';
|
|
@@ -148,6 +149,34 @@ const TreeRenderer = (props: { treeData: IChatResponseProgressFileTreeData }) =>
|
|
|
148
149
|
);
|
|
149
150
|
};
|
|
150
151
|
|
|
152
|
+
const ToolCallRender = (props: { toolCall: IChatToolContent['content'] }) => {
|
|
153
|
+
console.log("🚀 ~ ToolCallRender ~ props:", props)
|
|
154
|
+
const { toolCall } = props;
|
|
155
|
+
const chatAgentViewService = useInjectable<IChatAgentViewService>(ChatAgentViewServiceToken);
|
|
156
|
+
const [node, setNode] = useState<React.JSX.Element | null>(null);
|
|
157
|
+
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
const config = chatAgentViewService.getChatComponent('toolCall');
|
|
160
|
+
if (config) {
|
|
161
|
+
const { component: Component, initialProps } = config;
|
|
162
|
+
setNode(<Component {...initialProps} value={toolCall} />);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
setNode(
|
|
166
|
+
<div>
|
|
167
|
+
<Loading />
|
|
168
|
+
<span style={{ marginLeft: 4 }}>正在加载组件</span>
|
|
169
|
+
</div>,
|
|
170
|
+
);
|
|
171
|
+
const deferred = chatAgentViewService.getChatComponentDeferred('toolCall')!;
|
|
172
|
+
deferred.promise.then(({ component: Component, initialProps }) => {
|
|
173
|
+
setNode(<Component {...initialProps} value={toolCall} />);
|
|
174
|
+
});
|
|
175
|
+
}, [toolCall]);
|
|
176
|
+
|
|
177
|
+
return node;
|
|
178
|
+
};
|
|
179
|
+
|
|
151
180
|
const ComponentRender = (props: { component: string; value?: unknown }) => {
|
|
152
181
|
const chatAgentViewService = useInjectable<IChatAgentViewService>(ChatAgentViewServiceToken);
|
|
153
182
|
const [node, setNode] = useState<React.JSX.Element | null>(null);
|
|
@@ -202,6 +231,7 @@ export const ChatReply = (props: IChatReplyProps) => {
|
|
|
202
231
|
|
|
203
232
|
disposableCollection.push(
|
|
204
233
|
request.response.onDidChange(() => {
|
|
234
|
+
console.log("🚀 ~ request.response.onDidChange ~ onDidChange:", 'onDidChange')
|
|
205
235
|
history.updateAssistantMessage(msgId, { content: request.response.responseText });
|
|
206
236
|
|
|
207
237
|
if (request.response.isComplete) {
|
|
@@ -219,10 +249,10 @@ export const ChatReply = (props: IChatReplyProps) => {
|
|
|
219
249
|
});
|
|
220
250
|
}
|
|
221
251
|
|
|
222
|
-
startTransition(() => {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
252
|
+
// startTransition(() => {
|
|
253
|
+
// });
|
|
254
|
+
onDidChange?.();
|
|
255
|
+
update();
|
|
226
256
|
}),
|
|
227
257
|
);
|
|
228
258
|
|
|
@@ -274,6 +304,10 @@ export const ChatReply = (props: IChatReplyProps) => {
|
|
|
274
304
|
<ComponentRender component={componentId} value={value} />
|
|
275
305
|
);
|
|
276
306
|
|
|
307
|
+
const renderToolCall = (toolCall: IChatToolContent['content']) => {
|
|
308
|
+
return <ToolCallRender toolCall={toolCall} />;
|
|
309
|
+
};
|
|
310
|
+
|
|
277
311
|
const contentNode = React.useMemo(
|
|
278
312
|
() =>
|
|
279
313
|
request.response.responseContents.map((item, index) => {
|
|
@@ -284,6 +318,8 @@ export const ChatReply = (props: IChatReplyProps) => {
|
|
|
284
318
|
node = renderTreeData(item.treeData);
|
|
285
319
|
} else if (item.kind === 'component') {
|
|
286
320
|
node = renderComponent(item.component, item.value);
|
|
321
|
+
} else if (item.kind === 'toolCall') {
|
|
322
|
+
node = renderToolCall(item.content);
|
|
287
323
|
} else {
|
|
288
324
|
node = renderMarkdown(item.content);
|
|
289
325
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IChatToolContent, uuid } from "@opensumi/ide-core-common";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { CodeEditorWithHighlight } from "./ChatEditor";
|
|
4
|
+
|
|
5
|
+
export const ChatToolRender = (props: { value: IChatToolContent['content'] }) => {
|
|
6
|
+
const { value } = props;
|
|
7
|
+
console.log("🚀 ~ ChatToolRender ~ toolCall:", value)
|
|
8
|
+
|
|
9
|
+
if (!value || !value.function || !value.id) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return <div>
|
|
14
|
+
<span>当前调用的工具: </span>
|
|
15
|
+
<span>{value?.function?.name}</span>
|
|
16
|
+
<br />
|
|
17
|
+
<span></span>
|
|
18
|
+
{
|
|
19
|
+
value?.function?.arguments &&
|
|
20
|
+
(<CodeEditorWithHighlight
|
|
21
|
+
input={value?.function?.arguments}
|
|
22
|
+
language={'json'}
|
|
23
|
+
relationId={uuid(4)}
|
|
24
|
+
/>)
|
|
25
|
+
}
|
|
26
|
+
</div>
|
|
27
|
+
};
|
|
@@ -244,44 +244,45 @@
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
.
|
|
247
|
+
.monaco_wrapper {
|
|
248
248
|
position: relative;
|
|
249
|
-
min-width:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
line-height: 18px;
|
|
262
|
-
&::-webkit-scrollbar {
|
|
263
|
-
width: auto;
|
|
264
|
-
height: 4px;
|
|
265
|
-
}
|
|
249
|
+
min-width: 130px;
|
|
250
|
+
> pre {
|
|
251
|
+
margin-bottom: 10px;
|
|
252
|
+
}
|
|
253
|
+
.editor {
|
|
254
|
+
border-radius: 8px;
|
|
255
|
+
font-size: 12px;
|
|
256
|
+
padding: 32px 8px 8px 8px;
|
|
257
|
+
line-height: 18px;
|
|
258
|
+
&::-webkit-scrollbar {
|
|
259
|
+
width: auto;
|
|
260
|
+
height: 4px;
|
|
266
261
|
}
|
|
262
|
+
}
|
|
267
263
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
264
|
+
.action_toolbar {
|
|
265
|
+
display: flex;
|
|
266
|
+
position: absolute;
|
|
267
|
+
right: 8px;
|
|
268
|
+
top: 6px;
|
|
269
|
+
z-index: 100;
|
|
270
|
+
height: 20px;
|
|
271
|
+
align-items: center;
|
|
272
|
+
overflow: hidden;
|
|
277
273
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
274
|
+
:global {
|
|
275
|
+
.kt-popover {
|
|
276
|
+
height: inherit;
|
|
282
277
|
}
|
|
283
278
|
}
|
|
284
279
|
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.code_block {
|
|
283
|
+
position: relative;
|
|
284
|
+
min-width: 100px;
|
|
285
|
+
margin-top: 4px;
|
|
285
286
|
|
|
286
287
|
:global {
|
|
287
288
|
.hljs {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Disposable, ECodeEditsSourceTyping } from '@opensumi/ide-core-common';
|
|
2
|
-
import {
|
|
2
|
+
import { IPosition, IRange, InlineCompletion } from '@opensumi/ide-monaco';
|
|
3
3
|
|
|
4
4
|
import type { ILineChangeData } from './source/line-change.source';
|
|
5
5
|
import type { ILinterErrorData } from './source/lint-error.source';
|
|
@@ -14,8 +14,7 @@ export interface IIntelligentCompletionsResult<T = any> {
|
|
|
14
14
|
|
|
15
15
|
export type ICodeEditsContextBean =
|
|
16
16
|
| { typing: ECodeEditsSourceTyping.LinterErrors; position: IPosition; data: ILinterErrorData }
|
|
17
|
-
| { typing: ECodeEditsSourceTyping.LineChange; position: IPosition; data: ILineChangeData }
|
|
18
|
-
| { typing: ECodeEditsSourceTyping.Typing; position: IPosition; data: IModelContentChangedEvent };
|
|
17
|
+
| { typing: ECodeEditsSourceTyping.LineChange; position: IPosition; data: ILineChangeData };
|
|
19
18
|
|
|
20
19
|
export interface ICodeEdit {
|
|
21
20
|
/**
|
|
@@ -47,7 +47,6 @@ import { IntelligentCompletionsRegistry } from './intelligent-completions.featur
|
|
|
47
47
|
import { CodeEditsSourceCollection } from './source/base';
|
|
48
48
|
import { LineChangeCodeEditsSource } from './source/line-change.source';
|
|
49
49
|
import { LintErrorCodeEditsSource } from './source/lint-error.source';
|
|
50
|
-
import { TypingCodeEditsSource } from './source/typing.source';
|
|
51
50
|
|
|
52
51
|
import { CodeEditsResultValue } from './index';
|
|
53
52
|
|
|
@@ -96,7 +95,7 @@ export class IntelligentCompletionsController extends BaseAIMonacoEditorControll
|
|
|
96
95
|
this.additionsDeletionsDecorationModel = new AdditionsDeletionsDecorationModel(this.monacoEditor);
|
|
97
96
|
this.aiNativeContextKey = this.injector.get(AINativeContextKey, [this.monacoEditor.contextKeyService]);
|
|
98
97
|
this.codeEditsSourceCollection = this.injector.get(CodeEditsSourceCollection, [
|
|
99
|
-
[LintErrorCodeEditsSource, LineChangeCodeEditsSource
|
|
98
|
+
[LintErrorCodeEditsSource, LineChangeCodeEditsSource],
|
|
100
99
|
this.monacoEditor,
|
|
101
100
|
]);
|
|
102
101
|
|
|
@@ -69,6 +69,8 @@ export abstract class BaseCodeEditsSource extends Disposable {
|
|
|
69
69
|
private cancellationTokenSource = new CancellationTokenSource();
|
|
70
70
|
private readonly relationID = observableValue<string | undefined>(this, undefined);
|
|
71
71
|
|
|
72
|
+
protected abstract doTrigger(...args: any[]): MaybePromise<void>;
|
|
73
|
+
|
|
72
74
|
public readonly codeEditsContextBean = disposableObservableValue<CodeEditsContextBean | undefined>(this, undefined);
|
|
73
75
|
public abstract priority: number;
|
|
74
76
|
public abstract mount(): IDisposable;
|
|
@@ -1,102 +1,47 @@
|
|
|
1
1
|
import { Injectable } from '@opensumi/di';
|
|
2
2
|
import { AINativeSettingSectionsId, ECodeEditsSourceTyping, IDisposable } from '@opensumi/ide-core-common';
|
|
3
|
-
import { ICursorPositionChangedEvent,
|
|
4
|
-
import {
|
|
5
|
-
autorunDelta,
|
|
6
|
-
derivedHandleChanges,
|
|
7
|
-
observableFromEvent,
|
|
8
|
-
recomputeInitiallyAndOnChange,
|
|
9
|
-
} from '@opensumi/ide-monaco/lib/common/observable';
|
|
3
|
+
import { ICursorPositionChangedEvent, Position } from '@opensumi/ide-monaco';
|
|
10
4
|
|
|
11
5
|
import { BaseCodeEditsSource } from './base';
|
|
12
6
|
|
|
13
7
|
export interface ILineChangeData {
|
|
14
8
|
currentLineNumber: number;
|
|
15
9
|
preLineNumber?: number;
|
|
16
|
-
change?: IModelContentChangedEvent;
|
|
17
10
|
}
|
|
18
11
|
|
|
19
12
|
@Injectable({ multiple: true })
|
|
20
13
|
export class LineChangeCodeEditsSource extends BaseCodeEditsSource {
|
|
21
14
|
public priority = 2;
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
const modelContentChangeObs = observableFromEvent<IModelContentChangedEvent>(
|
|
25
|
-
this,
|
|
26
|
-
this.monacoEditor.onDidChangeModelContent,
|
|
27
|
-
(event: IModelContentChangedEvent) => event,
|
|
28
|
-
);
|
|
29
|
-
const positionChangeObs = observableFromEvent<ICursorPositionChangedEvent>(
|
|
30
|
-
this,
|
|
31
|
-
this.monacoEditor.onDidChangeCursorPosition,
|
|
32
|
-
(event: ICursorPositionChangedEvent) => event,
|
|
33
|
-
);
|
|
16
|
+
private prePosition = this.monacoEditor.getPosition();
|
|
34
17
|
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
owner: this,
|
|
38
|
-
createEmptyChangeSummary: () => ({ change: undefined }),
|
|
39
|
-
handleChange: (ctx, changeSummary: { change: IModelContentChangedEvent | undefined }) => {
|
|
40
|
-
// 如果只是改了光标则设置 change 为空,避免获取到缓存的 change
|
|
41
|
-
if (ctx.didChange(positionChangeObs)) {
|
|
42
|
-
changeSummary.change = undefined;
|
|
43
|
-
} else {
|
|
44
|
-
changeSummary.change = modelContentChangeObs.get();
|
|
45
|
-
}
|
|
46
|
-
return true;
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
(reader, changeSummary) => {
|
|
50
|
-
positionChangeObs.read(reader);
|
|
51
|
-
modelContentChangeObs.read(reader);
|
|
52
|
-
return changeSummary.change;
|
|
53
|
-
},
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
this.addDispose(recomputeInitiallyAndOnChange(latestModelContentChangeObs));
|
|
57
|
-
|
|
58
|
-
let lastModelContent: IModelContentChangedEvent | undefined;
|
|
18
|
+
public mount(): IDisposable {
|
|
59
19
|
this.addDispose(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
20
|
+
this.monacoEditor.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => {
|
|
21
|
+
const currentPosition = event.position;
|
|
22
|
+
if (this.prePosition && this.prePosition.lineNumber !== currentPosition.lineNumber) {
|
|
23
|
+
this.doTrigger(currentPosition);
|
|
24
|
+
this.prePosition = currentPosition;
|
|
25
|
+
}
|
|
66
26
|
}),
|
|
67
27
|
);
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
68
30
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const contentChange = lastModelContent;
|
|
72
|
-
|
|
73
|
-
const isLineChangeEnabled = this.preferenceService.getValid(
|
|
74
|
-
AINativeSettingSectionsId.CodeEditsLineChange,
|
|
75
|
-
false,
|
|
76
|
-
);
|
|
77
|
-
if (!isLineChangeEnabled) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const prePosition = lastValue?.position;
|
|
82
|
-
const currentPosition = newValue?.position;
|
|
83
|
-
if (prePosition && prePosition.lineNumber !== currentPosition?.lineNumber) {
|
|
84
|
-
this.setBean({
|
|
85
|
-
typing: ECodeEditsSourceTyping.LineChange,
|
|
86
|
-
position: currentPosition,
|
|
87
|
-
data: {
|
|
88
|
-
preLineNumber: prePosition.lineNumber,
|
|
89
|
-
currentLineNumber: currentPosition.lineNumber,
|
|
90
|
-
change: contentChange,
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
}
|
|
31
|
+
protected doTrigger(position: Position) {
|
|
32
|
+
const isLineChangeEnabled = this.preferenceService.getValid(AINativeSettingSectionsId.CodeEditsLineChange, false);
|
|
94
33
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
);
|
|
34
|
+
if (!isLineChangeEnabled || !position) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
99
37
|
|
|
100
|
-
|
|
38
|
+
this.setBean({
|
|
39
|
+
typing: ECodeEditsSourceTyping.LineChange,
|
|
40
|
+
position,
|
|
41
|
+
data: {
|
|
42
|
+
preLineNumber: this.prePosition?.lineNumber,
|
|
43
|
+
currentLineNumber: position.lineNumber,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
101
46
|
}
|
|
102
47
|
}
|