@opensumi/ide-ai-native 3.9.1-next-1747791726.0 → 3.9.1-next-1747829468.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/chat/apply.service.d.ts +0 -3
- package/lib/browser/chat/apply.service.d.ts.map +1 -1
- package/lib/browser/chat/apply.service.js +0 -47
- package/lib/browser/chat/apply.service.js.map +1 -1
- package/lib/browser/components/utils.d.ts +2 -2
- package/lib/browser/mcp/base-apply.service.d.ts +2 -3
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +5 -23
- package/lib/browser/mcp/base-apply.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 +7 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.js +9 -5
- package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.js +9 -5
- package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
- package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
- package/lib/browser/mcp/tools/listDir.js +19 -15
- package/lib/browser/mcp/tools/listDir.js.map +1 -1
- package/lib/node/mcp-server.sse.d.ts +187 -1
- package/lib/node/mcp-server.sse.d.ts.map +1 -1
- package/lib/node/mcp-server.sse.js +2 -2
- package/lib/node/mcp-server.sse.js.map +1 -1
- package/lib/node/mcp-server.stdio.d.ts +187 -1
- package/lib/node/mcp-server.stdio.d.ts.map +1 -1
- package/package.json +25 -25
- package/src/browser/chat/apply.service.ts +1 -62
- package/src/browser/mcp/base-apply.service.ts +9 -30
- package/src/browser/mcp/mcp-server.feature.registry.ts +6 -1
- package/src/browser/mcp/tools/fileSearch.ts +8 -5
- package/src/browser/mcp/tools/grepSearch.ts +8 -5
- package/src/browser/mcp/tools/listDir.ts +15 -12
- package/src/node/mcp-server.sse.ts +1 -2
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
2
|
-
import {
|
|
3
|
-
AIBackSerivcePath,
|
|
4
|
-
CancellationTokenSource,
|
|
5
|
-
IAIBackService,
|
|
6
|
-
IChatProgress,
|
|
7
|
-
URI,
|
|
8
|
-
path,
|
|
9
|
-
} from '@opensumi/ide-core-browser';
|
|
10
|
-
import { CommandService } from '@opensumi/ide-core-common/lib/command';
|
|
2
|
+
import { AIBackSerivcePath, IAIBackService, IChatProgress, URI, path } from '@opensumi/ide-core-browser';
|
|
11
3
|
import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser';
|
|
12
|
-
import { CodeAction, CodeActionContext, CodeActionTriggerType, ICodeEditor } from '@opensumi/ide-monaco';
|
|
13
|
-
import { languageFeaturesService } from '@opensumi/ide-monaco/lib/browser/monaco-api/languages';
|
|
14
4
|
import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
|
|
15
5
|
import { Range } from '@opensumi/monaco-editor-core';
|
|
16
6
|
|
|
@@ -20,59 +10,8 @@ import { BaseApplyService } from '../mcp/base-apply.service';
|
|
|
20
10
|
|
|
21
11
|
import { ChatProxyService } from './chat-proxy.service';
|
|
22
12
|
|
|
23
|
-
/**
|
|
24
|
-
* Filter code actions to only apply batch fixes
|
|
25
|
-
* Skip individual fixes as consecutive WorkspaceEdits may interfere with each other
|
|
26
|
-
* @param codeAction The code action to check
|
|
27
|
-
* @returns boolean indicating if the action is auto-fixable
|
|
28
|
-
*/
|
|
29
|
-
function isAutoFixable(codeAction: CodeAction): boolean {
|
|
30
|
-
return codeAction.title.toLowerCase().includes('all');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
13
|
@Injectable()
|
|
34
14
|
export class ApplyService extends BaseApplyService {
|
|
35
|
-
@Autowired(CommandService)
|
|
36
|
-
private commandService: CommandService;
|
|
37
|
-
|
|
38
|
-
protected async postApplyHandler(editor: ICodeEditor): Promise<void> {
|
|
39
|
-
const model = editor.getModel();
|
|
40
|
-
if (!model) {
|
|
41
|
-
return Promise.resolve();
|
|
42
|
-
}
|
|
43
|
-
const providers = languageFeaturesService.codeActionProvider.ordered(model);
|
|
44
|
-
|
|
45
|
-
if (!providers) {
|
|
46
|
-
return Promise.resolve();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const [provider] = providers;
|
|
50
|
-
const range = model.getFullModelRange();
|
|
51
|
-
const context: CodeActionContext = {
|
|
52
|
-
trigger: CodeActionTriggerType.Auto,
|
|
53
|
-
};
|
|
54
|
-
const ts = new CancellationTokenSource();
|
|
55
|
-
const actionList = await provider.provideCodeActions(model, range, context, ts.token);
|
|
56
|
-
|
|
57
|
-
// 提取所有可修复的代码操作
|
|
58
|
-
const fixableActions = actionList?.actions.filter(isAutoFixable) || [];
|
|
59
|
-
|
|
60
|
-
if (fixableActions.length === 0) {
|
|
61
|
-
return Promise.resolve();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// 执行所有可修复的代码操作
|
|
65
|
-
await Promise.allSettled(
|
|
66
|
-
fixableActions.map(async (action) => {
|
|
67
|
-
if (action.command) {
|
|
68
|
-
try {
|
|
69
|
-
await this.commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
|
|
70
|
-
} catch (err) {}
|
|
71
|
-
}
|
|
72
|
-
}),
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
15
|
@Autowired(IEditorDocumentModelService)
|
|
77
16
|
private readonly modelService: IEditorDocumentModelService;
|
|
78
17
|
|
|
@@ -63,8 +63,6 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
63
63
|
|
|
64
64
|
private currentSessionId?: string;
|
|
65
65
|
|
|
66
|
-
protected abstract postApplyHandler(editor: ICodeEditor): Promise<void>;
|
|
67
|
-
|
|
68
66
|
constructor() {
|
|
69
67
|
super();
|
|
70
68
|
this.addDispose(
|
|
@@ -315,26 +313,10 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
315
313
|
);
|
|
316
314
|
codeBlock.updatedCode = res.updatedCode;
|
|
317
315
|
codeBlock.status = 'pending';
|
|
318
|
-
|
|
319
|
-
// apply 结果流式输出完成后,自动尝试修复代码中的 lint 错误
|
|
320
|
-
if (this.postApplyHandler && typeof this.postApplyHandler === 'function') {
|
|
321
|
-
try {
|
|
322
|
-
await this.postApplyHandler(result.group.codeEditor.monacoEditor);
|
|
323
|
-
} catch (error) {}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const textModel = result.group.codeEditor.monacoEditor.getModel();
|
|
327
|
-
const diagnosticInfos = this.getDiagnosticInfos(textModel!.uri.toString(), res.result?.rangesFromDiffHunk || []);
|
|
328
|
-
|
|
329
316
|
// 用户实际接受的 apply 结果
|
|
330
|
-
|
|
331
|
-
codeBlock.applyResult = {
|
|
332
|
-
diff: res.result?.diff,
|
|
333
|
-
diagnosticInfos,
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
|
|
317
|
+
codeBlock.applyResult = res.result;
|
|
337
318
|
this.updateCodeBlock(codeBlock);
|
|
319
|
+
|
|
338
320
|
return codeBlock;
|
|
339
321
|
} catch (err) {
|
|
340
322
|
codeBlock.status = 'failed';
|
|
@@ -354,8 +336,8 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
354
336
|
codeBlock: CodeBlockData,
|
|
355
337
|
updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
|
|
356
338
|
range?: Range,
|
|
357
|
-
): Promise<{ result?: { diff: string;
|
|
358
|
-
const deferred = new Deferred<{ result?: { diff: string;
|
|
339
|
+
): Promise<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }> {
|
|
340
|
+
const deferred = new Deferred<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }>();
|
|
359
341
|
const inlineDiffController = InlineDiffController.get(editor)!;
|
|
360
342
|
range = range || editor.getModel()!.getFullModelRange();
|
|
361
343
|
|
|
@@ -391,11 +373,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
391
373
|
|
|
392
374
|
this.listenPartialEdit(editor.getModel()!, codeBlock).then((result) => {
|
|
393
375
|
if (result) {
|
|
394
|
-
|
|
395
|
-
codeBlock.applyResult = {
|
|
396
|
-
diff: result.diff,
|
|
397
|
-
diagnosticInfos,
|
|
398
|
-
};
|
|
376
|
+
codeBlock.applyResult = result;
|
|
399
377
|
}
|
|
400
378
|
this.updateCodeBlock(codeBlock);
|
|
401
379
|
this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)));
|
|
@@ -406,10 +384,11 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
406
384
|
updatedContent,
|
|
407
385
|
codeBlock.relativePath,
|
|
408
386
|
);
|
|
387
|
+
const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
|
|
409
388
|
deferred.resolve({
|
|
410
389
|
result: {
|
|
411
390
|
diff,
|
|
412
|
-
|
|
391
|
+
diagnosticInfos,
|
|
413
392
|
},
|
|
414
393
|
updatedCode: updatedContent,
|
|
415
394
|
});
|
|
@@ -555,7 +534,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
555
534
|
}
|
|
556
535
|
|
|
557
536
|
protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
|
|
558
|
-
const deferred = new Deferred<{ diff: string;
|
|
537
|
+
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
559
538
|
const uriString = model.uri.toString();
|
|
560
539
|
const toDispose = this.inlineDiffService.onPartialEdit((event) => {
|
|
561
540
|
if (
|
|
@@ -595,7 +574,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
595
574
|
});
|
|
596
575
|
deferred.resolve({
|
|
597
576
|
diff,
|
|
598
|
-
|
|
577
|
+
diagnosticInfos,
|
|
599
578
|
});
|
|
600
579
|
} else {
|
|
601
580
|
// 用户全部取消
|
|
@@ -44,7 +44,12 @@ export class MCPServerRegistry implements IMCPServerRegistry {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
registerMCPTool(tool: MCPToolDefinition): void {
|
|
47
|
-
this.tools.
|
|
47
|
+
const existingIndex = this.tools.findIndex((t) => t.name === tool.name);
|
|
48
|
+
if (existingIndex !== -1) {
|
|
49
|
+
this.tools[existingIndex] = tool;
|
|
50
|
+
} else {
|
|
51
|
+
this.tools.push(tool);
|
|
52
|
+
}
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
registerToolComponent(
|
|
@@ -80,11 +80,14 @@ export class FileSearchTool implements MCPServerContribution {
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
const messages = this.chatInternalService.sessionModel.history.getMessages();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
const messageId = messages[messages.length - 1]?.id;
|
|
84
|
+
if (messageId) {
|
|
85
|
+
this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
|
|
86
|
+
[args.toolCallId]: {
|
|
87
|
+
files,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
88
91
|
|
|
89
92
|
logger.appendLine(`Found ${files.length} files matching "${args.query}"`);
|
|
90
93
|
|
|
@@ -111,11 +111,14 @@ export class GrepSearchTool implements MCPServerContribution {
|
|
|
111
111
|
}
|
|
112
112
|
deferred.resolve(results.join('\n\n'));
|
|
113
113
|
const messages = this.chatInternalService.sessionModel.history.getMessages();
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
const messageId = messages[messages.length - 1]?.id;
|
|
115
|
+
if (messageId) {
|
|
116
|
+
this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
|
|
117
|
+
[args.toolCallId]: {
|
|
118
|
+
files,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
119
122
|
});
|
|
120
123
|
const text = await deferred.promise;
|
|
121
124
|
return {
|
|
@@ -63,18 +63,21 @@ export class ListDirTool implements MCPServerContribution {
|
|
|
63
63
|
|
|
64
64
|
// 设置消息的附加数据
|
|
65
65
|
const messages = this.chatInternalService.sessionModel.history.getMessages();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
const messageId = messages[messages.length - 1]?.id;
|
|
67
|
+
if (messageId) {
|
|
68
|
+
this.chatInternalService.sessionModel.history.setMessageAdditional(messageId, {
|
|
69
|
+
[args.toolCallId]: {
|
|
70
|
+
files: fileUris,
|
|
71
|
+
title: `Listed directory "${args.relativeWorkspacePath}"`,
|
|
72
|
+
details: result.files.map((file) => ({
|
|
73
|
+
type: file.isDirectory ? 'dir' : 'file',
|
|
74
|
+
name: file.name,
|
|
75
|
+
info: file.isDirectory ? `${file.numChildren ?? '?'} items` : `${file.size}KB, ${file.numLines} lines`,
|
|
76
|
+
lastModified: file.lastModified,
|
|
77
|
+
})),
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
78
81
|
|
|
79
82
|
logger.appendLine(`Listed ${fileUris.length} files in directory "${args.relativeWorkspacePath}"`);
|
|
80
83
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// have to import with extension since the exports map is ./* -> ./dist/cjs/*
|
|
2
2
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
3
4
|
import { EventSource } from 'eventsource';
|
|
4
5
|
|
|
5
6
|
import { ILogger } from '@opensumi/ide-core-common';
|
|
@@ -47,8 +48,6 @@ export class SSEMCPServer implements IMCPServer {
|
|
|
47
48
|
}
|
|
48
49
|
this.logger?.log(`Starting server "${this.name}" with url: ${this.url}`);
|
|
49
50
|
|
|
50
|
-
const SSEClientTransport = (await import('@modelcontextprotocol/sdk/client/sse.js')).SSEClientTransport;
|
|
51
|
-
|
|
52
51
|
const transport = new SSEClientTransport(new URL(this.url), this.transportOptions);
|
|
53
52
|
|
|
54
53
|
transport.onerror = (error) => {
|