@opensumi/ide-ai-native 3.8.2-next-1741622293.0 → 3.8.3-next-1741661270.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +20 -0
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +2 -1
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +26 -7
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +3 -3
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +22 -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 +2 -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 +61 -5
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ApplyStatus.d.ts +7 -0
- package/lib/browser/components/ApplyStatus.d.ts.map +1 -0
- package/lib/browser/components/ApplyStatus.js +32 -0
- package/lib/browser/components/ApplyStatus.js.map +1 -0
- package/lib/browser/components/ChangeList.d.ts +17 -0
- package/lib/browser/components/ChangeList.d.ts.map +1 -0
- package/lib/browser/components/ChangeList.js +72 -0
- package/lib/browser/components/ChangeList.js.map +1 -0
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +18 -12
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +27 -15
- package/lib/browser/components/change-list.module.less +126 -0
- package/lib/browser/components/chat-history.module.less +1 -1
- package/lib/browser/components/components.module.less +14 -0
- package/lib/browser/contrib/inline-completions/prompt/matcher.js +2 -2
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.js +2 -2
- package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
- 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 -4
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +14 -6
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +80 -52
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.view.js +12 -8
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -1
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.js +3 -24
- package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/components/ExpandableFileList.js +3 -2
- package/lib/browser/mcp/tools/components/ExpandableFileList.js.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.js +1 -0
- package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
- package/lib/browser/mcp/tools/editFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/editFile.js +1 -0
- package/lib/browser/mcp/tools/editFile.js.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.js +1 -0
- package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js +2 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js +2 -0
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.js +1 -0
- 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 +1 -0
- package/lib/browser/mcp/tools/listDir.js.map +1 -1
- package/lib/browser/mcp/tools/readFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/readFile.js +1 -0
- package/lib/browser/mcp/tools/readFile.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js +1 -0
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +0 -2
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +1 -6
- package/lib/browser/model/msg-history-manager.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +8 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +1 -0
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.js +2 -2
- package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts +3 -2
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.service.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +0 -33
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js +1 -6
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +15 -14
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/common/index.d.ts +7 -2
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +3 -2
- package/lib/common/index.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +2 -4
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/types.d.ts +33 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js +6 -1
- package/lib/common/types.js.map +1 -1
- package/package.json +23 -23
- package/src/browser/ai-core.contribution.ts +28 -0
- package/src/browser/chat/chat-manager.service.ts +53 -31
- package/src/browser/chat/chat-model.ts +22 -8
- package/src/browser/chat/chat-proxy.service.ts +2 -0
- package/src/browser/chat/chat.view.tsx +80 -9
- package/src/browser/components/ApplyStatus.tsx +44 -0
- package/src/browser/components/ChangeList.tsx +131 -0
- package/src/browser/components/ChatToolRender.module.less +27 -15
- package/src/browser/components/ChatToolRender.tsx +14 -12
- package/src/browser/components/change-list.module.less +126 -0
- package/src/browser/components/chat-history.module.less +1 -1
- package/src/browser/components/components.module.less +14 -0
- package/src/browser/contrib/inline-completions/prompt/matcher.ts +2 -2
- package/src/browser/contrib/inline-completions/prompt/similarSnippets.ts +2 -2
- package/src/browser/contrib/intelligent-completions/view/default.ts +1 -0
- package/src/browser/index.ts +5 -4
- package/src/browser/mcp/base-apply.service.ts +84 -62
- package/src/browser/mcp/config/components/mcp-config.view.tsx +4 -0
- package/src/browser/mcp/config/mcp-config.contribution.ts +1 -1
- package/src/browser/mcp/mcp-server.feature.registry.ts +1 -1
- package/src/browser/mcp/tools/components/EditFile.tsx +3 -37
- package/src/browser/mcp/tools/components/ExpandableFileList.tsx +3 -1
- package/src/browser/mcp/tools/createNewFileWithText.ts +1 -0
- package/src/browser/mcp/tools/editFile.ts +1 -0
- package/src/browser/mcp/tools/fileSearch.ts +1 -0
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +2 -1
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +2 -0
- package/src/browser/mcp/tools/grepSearch.ts +1 -0
- package/src/browser/mcp/tools/listDir.ts +1 -0
- package/src/browser/mcp/tools/readFile.ts +1 -0
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -0
- package/src/browser/model/msg-history-manager.ts +1 -8
- package/src/browser/preferences/schema.ts +8 -0
- package/src/browser/types.ts +1 -0
- package/src/browser/widget/inline-diff/inline-diff-manager.tsx +3 -2
- package/src/browser/widget/inline-diff/inline-diff.controller.ts +2 -1
- package/src/browser/widget/inline-diff/inline-diff.service.ts +3 -2
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -4
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +0 -34
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +8 -9
- package/src/common/index.ts +9 -2
- package/src/common/prompts/context-prompt-provider.ts +2 -6
- package/src/common/types.ts +35 -0
|
@@ -5,6 +5,7 @@ import { useInjectable } from '@opensumi/ide-core-browser';
|
|
|
5
5
|
import { Icon } from '@opensumi/ide-core-browser/lib/components';
|
|
6
6
|
import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
7
7
|
import { IChatToolContent, uuid } from '@opensumi/ide-core-common';
|
|
8
|
+
import { localize } from '@opensumi/ide-core-common/lib/localize';
|
|
8
9
|
|
|
9
10
|
import { IMCPServerRegistry, TokenMCPServerRegistry } from '../types';
|
|
10
11
|
|
|
@@ -64,28 +65,29 @@ export const ChatToolRender = (props: { value: IChatToolContent['content']; mess
|
|
|
64
65
|
toolCallId={value.id}
|
|
65
66
|
/>
|
|
66
67
|
) : (
|
|
67
|
-
<div className={styles
|
|
68
|
-
<div className={styles
|
|
69
|
-
<div className={styles
|
|
70
|
-
<Icon iconClass={`codicon codicon-
|
|
71
|
-
{
|
|
68
|
+
<div className={styles.chat_tool_render}>
|
|
69
|
+
<div className={styles.tool_header} onClick={toggleExpand}>
|
|
70
|
+
<div className={styles.tool_name}>
|
|
71
|
+
<Icon iconClass={`codicon codicon-chevron-${isExpanded ? 'down' : 'right'}`} />
|
|
72
|
+
<Icon size='small' iconClass={cls('codicon codicon-tools', styles.tool_icon)} />
|
|
73
|
+
<span className={styles.tool_label}>{label}</span>
|
|
72
74
|
</div>
|
|
73
75
|
{value.state && (
|
|
74
|
-
<div className={styles
|
|
75
|
-
<span className={styles
|
|
76
|
+
<div className={styles.tool_state}>
|
|
77
|
+
<span className={styles.state_icon}>{stateInfo.icon}</span>
|
|
76
78
|
</div>
|
|
77
79
|
)}
|
|
78
80
|
</div>
|
|
79
|
-
<div className={cls(styles
|
|
81
|
+
<div className={cls(styles.tool_content, { [styles.expanded]: isExpanded })}>
|
|
80
82
|
{value?.function?.arguments && (
|
|
81
|
-
<div className={styles
|
|
82
|
-
<div className={styles
|
|
83
|
+
<div className={styles.tool_arguments}>
|
|
84
|
+
<div className={styles.section_label}>{localize('ai.native.mcp.tool.arguments')}:</div>
|
|
83
85
|
<CodeEditorWithHighlight input={value?.function?.arguments} language={'json'} relationId={uuid(4)} />
|
|
84
86
|
</div>
|
|
85
87
|
)}
|
|
86
88
|
{value?.result && (
|
|
87
|
-
<div className={styles
|
|
88
|
-
<div className={styles
|
|
89
|
+
<div className={styles.tool_result}>
|
|
90
|
+
<div className={styles.section_label}>{localize('ai.native.mcp.tool.results')}:</div>
|
|
89
91
|
<CodeEditorWithHighlight input={value.result} language={'json'} relationId={uuid(4)} />
|
|
90
92
|
</div>
|
|
91
93
|
)}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
margin: 0 12px;
|
|
3
|
+
background: var(--design-chatInput-background);
|
|
4
|
+
border-radius: 9px 9px 0 0;
|
|
5
|
+
border: 1px solid var(--kt-input-border);
|
|
6
|
+
border-bottom: none;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
padding-bottom: 6px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.header {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: space-between;
|
|
15
|
+
padding: 8px 12px 2px 12px;
|
|
16
|
+
background-color: transparent;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
user-select: none;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
color: var(--descriptionForeground);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.title:hover {
|
|
24
|
+
color: var(--design-text-highlightForeground);
|
|
25
|
+
.toggleButton :global(.kt-icon) {
|
|
26
|
+
color: var(--design-text-highlightForeground);
|
|
27
|
+
transition: color 0.2s ease-in-out;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.toggleButton {
|
|
32
|
+
background: none;
|
|
33
|
+
border: none;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
padding: 0;
|
|
36
|
+
width: 16px;
|
|
37
|
+
height: 16px;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
font-size: 12px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.title {
|
|
45
|
+
gap: 6px;
|
|
46
|
+
transition: color 0.2s ease-in-out;
|
|
47
|
+
display: flex;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.fileList {
|
|
51
|
+
list-style: none;
|
|
52
|
+
margin: 0;
|
|
53
|
+
padding: 0 12px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.fileItem {
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
padding: 4px 0;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
border: none;
|
|
62
|
+
font-size: 13px;
|
|
63
|
+
color: var(--descriptionForeground);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.fileItem:hover {
|
|
67
|
+
background-color: var(--design-block-hoverBackground);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.fileIcon {
|
|
71
|
+
margin-right: 6px;
|
|
72
|
+
width: 16px;
|
|
73
|
+
height: 16px;
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.fileInfo {
|
|
80
|
+
flex: 1;
|
|
81
|
+
display: flex;
|
|
82
|
+
justify-content: space-between;
|
|
83
|
+
align-items: center;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
:global(.kt-popover-trigger) {
|
|
86
|
+
margin-left: 8px;
|
|
87
|
+
}
|
|
88
|
+
:global(.codicon) {
|
|
89
|
+
font-size: 12px !important;
|
|
90
|
+
position: relative;
|
|
91
|
+
top: 1px;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.filePath {
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
margin: 0;
|
|
98
|
+
white-space: nowrap;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
text-overflow: ellipsis;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.fileStats {
|
|
104
|
+
font-size: 12px;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: 4px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.additions {
|
|
111
|
+
color: #52c41a;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.deletions {
|
|
115
|
+
color: var(--debugConsole-errorForeground);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.noChange {
|
|
119
|
+
color: #6a737d;
|
|
120
|
+
font-style: italic;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.collapsed {
|
|
125
|
+
display: none;
|
|
126
|
+
}
|
|
@@ -527,3 +527,17 @@
|
|
|
527
527
|
align-items: center;
|
|
528
528
|
}
|
|
529
529
|
}
|
|
530
|
+
|
|
531
|
+
.status {
|
|
532
|
+
:global {
|
|
533
|
+
.codicon-pass {
|
|
534
|
+
color: #52c41a;
|
|
535
|
+
}
|
|
536
|
+
.codicon-error {
|
|
537
|
+
color: var(--debugConsole-errorForeground);
|
|
538
|
+
}
|
|
539
|
+
.codicon-circle-slash {
|
|
540
|
+
color: var(--input-placeholderForeground);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
@@ -244,8 +244,8 @@ export abstract class WindowedMatcher {
|
|
|
244
244
|
tokens.slice(startLine, endLine).forEach((token) => token.forEach((word) => size.add(word)));
|
|
245
245
|
cache.push(size);
|
|
246
246
|
}
|
|
247
|
-
const
|
|
248
|
-
const score = this.similarityScore(
|
|
247
|
+
const traget = cache[index];
|
|
248
|
+
const score = this.similarityScore(traget, this.referenceTokens);
|
|
249
249
|
snippets.push({
|
|
250
250
|
score,
|
|
251
251
|
startLine,
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
import { MAX_NEIGHBOR_AGGREGATE_LENGTH } from './const';
|
|
16
16
|
import { FixedWindowSizeJaccardMatcher } from './jaccardMatcher';
|
|
17
17
|
|
|
18
|
-
export const getOpenedTabFileList = (
|
|
18
|
+
export const getOpenedTabFileList = (docuemnts: IEditorDocumentModel[]) => {
|
|
19
19
|
// 过滤超大文档
|
|
20
|
-
const recentFiles =
|
|
20
|
+
const recentFiles = docuemnts.filter((document) => isDocumentValid(document));
|
|
21
21
|
return recentFiles;
|
|
22
22
|
};
|
|
23
23
|
|
package/src/browser/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
IChatAgentService,
|
|
26
26
|
IChatInternalService,
|
|
27
27
|
IChatManagerService,
|
|
28
|
+
InlineDiffServiceToken,
|
|
28
29
|
SumiMCPServerProxyServicePath,
|
|
29
30
|
TokenMCPServerProxyService,
|
|
30
31
|
} from '../common';
|
|
@@ -193,14 +194,14 @@ export class AINativeModule extends BrowserModule {
|
|
|
193
194
|
token: IAIInlineCompletionsProvider,
|
|
194
195
|
useClass: AIInlineCompletionsProvider,
|
|
195
196
|
},
|
|
196
|
-
{
|
|
197
|
-
token: InlineDiffService,
|
|
198
|
-
useClass: InlineDiffService,
|
|
199
|
-
},
|
|
200
197
|
{
|
|
201
198
|
token: ChatAgentPromptProvider,
|
|
202
199
|
useClass: DefaultChatAgentPromptProvider,
|
|
203
200
|
},
|
|
201
|
+
{
|
|
202
|
+
token: InlineDiffServiceToken,
|
|
203
|
+
useClass: InlineDiffService,
|
|
204
|
+
},
|
|
204
205
|
{
|
|
205
206
|
token: BaseApplyService,
|
|
206
207
|
useClass: ApplyService,
|
|
@@ -26,17 +26,13 @@ import { Deferred, DisposableMap, Emitter, IDisposable, URI, path } from '@opens
|
|
|
26
26
|
import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
|
|
27
27
|
import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
|
|
28
28
|
|
|
29
|
-
import { IChatInternalService } from '../../common';
|
|
29
|
+
import { IChatInternalService, IInlineDiffService, InlineDiffServiceToken } from '../../common';
|
|
30
30
|
import { CodeBlockData, CodeBlockStatus } from '../../common/types';
|
|
31
31
|
import { ChatInternalService } from '../chat/chat.internal.service';
|
|
32
32
|
import { InlineChatController } from '../widget/inline-chat/inline-chat-controller';
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
InlineDiffService,
|
|
37
|
-
LiveInlineDiffPreviewer,
|
|
38
|
-
} from '../widget/inline-diff';
|
|
39
|
-
import { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
|
|
33
|
+
import { BaseInlineDiffPreviewer, InlineDiffController, LiveInlineDiffPreviewer } from '../widget/inline-diff';
|
|
34
|
+
|
|
35
|
+
import type { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
|
|
40
36
|
|
|
41
37
|
export abstract class BaseApplyService extends WithEventBus {
|
|
42
38
|
@Autowired(IChatInternalService)
|
|
@@ -48,8 +44,8 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
48
44
|
@Autowired(WorkbenchEditorService)
|
|
49
45
|
protected readonly editorService: WorkbenchEditorService;
|
|
50
46
|
|
|
51
|
-
@Autowired(
|
|
52
|
-
private readonly inlineDiffService:
|
|
47
|
+
@Autowired(InlineDiffServiceToken)
|
|
48
|
+
private readonly inlineDiffService: IInlineDiffService;
|
|
53
49
|
|
|
54
50
|
@Autowired(IMarkerService)
|
|
55
51
|
private readonly markerService: IMarkerService;
|
|
@@ -155,7 +151,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
155
151
|
// 使用最后一个版本内容渲染 apply 内容
|
|
156
152
|
if (filePendingApplies.length > 0 && filePendingApplies[0].updatedCode) {
|
|
157
153
|
const editor = event.payload.group.codeEditor.monacoEditor;
|
|
158
|
-
this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
|
|
154
|
+
await this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
|
|
159
155
|
}
|
|
160
156
|
}
|
|
161
157
|
|
|
@@ -183,9 +179,10 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
183
179
|
return sessionCodeBlocks.filter((block) => block.status === 'pending').map((block) => block.relativePath);
|
|
184
180
|
}
|
|
185
181
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
getSessionCodeBlocks(sessionId?: string) {
|
|
183
|
+
const sessionModel = sessionId
|
|
184
|
+
? this.chatInternalService.getSession(sessionId)
|
|
185
|
+
: this.chatInternalService.sessionModel;
|
|
189
186
|
if (!sessionModel) {
|
|
190
187
|
throw new Error(`Session ${sessionId} not found`);
|
|
191
188
|
}
|
|
@@ -301,22 +298,17 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
301
298
|
if (!result) {
|
|
302
299
|
throw new Error('Failed to open file');
|
|
303
300
|
}
|
|
304
|
-
|
|
305
|
-
codeBlock.updatedCode = fastApplyFileResult.result;
|
|
306
|
-
codeBlock.status = 'pending';
|
|
307
|
-
this.updateCodeBlock(codeBlock);
|
|
308
|
-
}
|
|
309
|
-
const applyResult = await this.renderApplyResult(
|
|
301
|
+
const res = await this.renderApplyResult(
|
|
310
302
|
result.group.codeEditor.monacoEditor,
|
|
311
303
|
codeBlock,
|
|
312
304
|
(fastApplyFileResult.result || fastApplyFileResult.stream)!,
|
|
313
305
|
fastApplyFileResult.range,
|
|
314
306
|
);
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
307
|
+
codeBlock.updatedCode = res.updatedCode;
|
|
308
|
+
codeBlock.status = 'pending';
|
|
309
|
+
// 用户实际接受的 apply 结果
|
|
310
|
+
codeBlock.applyResult = res.result;
|
|
311
|
+
this.updateCodeBlock(codeBlock);
|
|
320
312
|
|
|
321
313
|
return codeBlock;
|
|
322
314
|
} catch (err) {
|
|
@@ -328,31 +320,33 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
328
320
|
}
|
|
329
321
|
}
|
|
330
322
|
|
|
323
|
+
/**
|
|
324
|
+
* 渲染apply结果(支持流式和直接输出结果)
|
|
325
|
+
* 副作用:渲染时会添加accept、reject操作监听器,监听到结果时会自动更新codeBlock的result
|
|
326
|
+
*/
|
|
331
327
|
async renderApplyResult(
|
|
332
328
|
editor: ICodeEditor,
|
|
333
329
|
codeBlock: CodeBlockData,
|
|
334
330
|
updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
|
|
335
331
|
range?: Range,
|
|
336
|
-
): Promise<{ diff: string; diagnosticInfos: IMarker[] }
|
|
337
|
-
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
332
|
+
): Promise<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }> {
|
|
333
|
+
const deferred = new Deferred<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }>();
|
|
338
334
|
const inlineDiffController = InlineDiffController.get(editor)!;
|
|
339
335
|
range = range || editor.getModel()!.getFullModelRange();
|
|
340
336
|
|
|
341
337
|
if (typeof updatedContentOrStream === 'string') {
|
|
338
|
+
const updatedContent = updatedContentOrStream;
|
|
342
339
|
const editorCurrentContent = editor.getModel()!.getValue();
|
|
343
340
|
const uri = URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath));
|
|
344
341
|
const document = this.editorDocumentModelService.getModelReference(uri);
|
|
345
|
-
if (editorCurrentContent !==
|
|
346
|
-
editor.getModel()?.pushEditOperations([], [EditOperation.replace(range,
|
|
342
|
+
if (editorCurrentContent !== updatedContent || document?.instance.dirty) {
|
|
343
|
+
editor.getModel()?.pushEditOperations([], [EditOperation.replace(range, updatedContent)], () => null);
|
|
347
344
|
await this.editorService.save(uri);
|
|
348
345
|
}
|
|
349
346
|
const uriPendingCodeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
|
|
350
347
|
const earlistPendingCodeBlock = uriPendingCodeBlocks?.[uriPendingCodeBlocks.length - 1];
|
|
351
|
-
if ((earlistPendingCodeBlock
|
|
352
|
-
|
|
353
|
-
this.updateCodeBlock(codeBlock);
|
|
354
|
-
deferred.resolve();
|
|
355
|
-
return;
|
|
348
|
+
if ((earlistPendingCodeBlock || codeBlock)?.originalCode === updatedContent) {
|
|
349
|
+
throw new Error('No changes applied');
|
|
356
350
|
}
|
|
357
351
|
// Create diff previewer
|
|
358
352
|
const previewer = inlineDiffController.createDiffPreviewer(
|
|
@@ -380,13 +374,16 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
380
374
|
|
|
381
375
|
const { diff, rangesFromDiffHunk } = this.getDiffResult(
|
|
382
376
|
codeBlock.originalCode,
|
|
383
|
-
|
|
377
|
+
updatedContent,
|
|
384
378
|
codeBlock.relativePath,
|
|
385
379
|
);
|
|
386
380
|
const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
|
|
387
381
|
deferred.resolve({
|
|
388
|
-
|
|
389
|
-
|
|
382
|
+
result: {
|
|
383
|
+
diff,
|
|
384
|
+
diagnosticInfos,
|
|
385
|
+
},
|
|
386
|
+
updatedCode: updatedContent,
|
|
390
387
|
});
|
|
391
388
|
} else {
|
|
392
389
|
const controller = new InlineChatController();
|
|
@@ -414,21 +411,21 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
414
411
|
this.addDispose(
|
|
415
412
|
// 流式输出结束后,转为直接输出逻辑
|
|
416
413
|
previewer.getNode()!.onDiffFinished(async (diffModel) => {
|
|
417
|
-
codeBlock.updatedCode = diffModel.newFullRangeTextLines.join('\n');
|
|
418
414
|
// TODO: 添加 reapply
|
|
415
|
+
const updatedCode = diffModel.newFullRangeTextLines.join('\n');
|
|
419
416
|
// 实际应用结果为空,则取消
|
|
420
|
-
if (codeBlock.
|
|
421
|
-
codeBlock.status = 'failed';
|
|
422
|
-
this.updateCodeBlock(codeBlock);
|
|
417
|
+
if (codeBlock.originalCode === updatedCode) {
|
|
423
418
|
previewer.dispose();
|
|
424
419
|
deferred.reject(new Error('no changes applied'));
|
|
425
420
|
return;
|
|
426
421
|
}
|
|
427
|
-
codeBlock.status = 'pending';
|
|
428
|
-
this.updateCodeBlock(codeBlock);
|
|
429
422
|
previewer.dispose();
|
|
430
|
-
|
|
431
|
-
|
|
423
|
+
try {
|
|
424
|
+
const res = await this.renderApplyResult(editor, codeBlock, updatedCode);
|
|
425
|
+
deferred.resolve(res);
|
|
426
|
+
} catch (err) {
|
|
427
|
+
deferred.reject(err);
|
|
428
|
+
}
|
|
432
429
|
}),
|
|
433
430
|
);
|
|
434
431
|
this.activePreviewerMap.set(codeBlock.relativePath, previewer);
|
|
@@ -483,14 +480,36 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
483
480
|
}
|
|
484
481
|
}
|
|
485
482
|
|
|
486
|
-
processAll(
|
|
487
|
-
const codeBlocks =
|
|
483
|
+
processAll(type: 'accept' | 'reject', uri?: URI): void {
|
|
484
|
+
const codeBlocks = uri
|
|
485
|
+
? this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending')
|
|
486
|
+
: this.getSessionCodeBlocks().filter((block) => block.status === 'pending');
|
|
488
487
|
if (!codeBlocks?.length) {
|
|
489
488
|
throw new Error('No pending code block found');
|
|
490
489
|
}
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
490
|
+
const relativePaths = uri
|
|
491
|
+
? [codeBlocks[0].relativePath]
|
|
492
|
+
: codeBlocks
|
|
493
|
+
.map((block) => block.relativePath)
|
|
494
|
+
.reduce((acc, cur) => {
|
|
495
|
+
if (acc.includes(cur)) {
|
|
496
|
+
return acc;
|
|
497
|
+
}
|
|
498
|
+
acc.push(cur);
|
|
499
|
+
return acc;
|
|
500
|
+
}, [] as string[]);
|
|
501
|
+
relativePaths.forEach((relativePath) => {
|
|
502
|
+
this.doProcess(type, relativePath);
|
|
503
|
+
});
|
|
504
|
+
codeBlocks.forEach((codeBlock) => {
|
|
505
|
+
codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
|
|
506
|
+
// TODO: 批量更新
|
|
507
|
+
this.updateCodeBlock(codeBlock);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
protected doProcess(type: 'accept' | 'reject', relativePath: string) {
|
|
512
|
+
const decorationModel = this.activePreviewerMap.get(relativePath)?.getNode()?.livePreviewDiffDecorationModel;
|
|
494
513
|
if (!decorationModel) {
|
|
495
514
|
throw new Error('No active previewer found');
|
|
496
515
|
}
|
|
@@ -499,19 +518,13 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
499
518
|
} else {
|
|
500
519
|
decorationModel.discardUnProcessed();
|
|
501
520
|
}
|
|
502
|
-
this.editorService.save(
|
|
503
|
-
codeBlocks.forEach((codeBlock) => {
|
|
504
|
-
codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
|
|
505
|
-
// TODO: 批量更新
|
|
506
|
-
this.updateCodeBlock(codeBlock);
|
|
507
|
-
});
|
|
521
|
+
this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
|
|
508
522
|
}
|
|
509
523
|
|
|
510
524
|
protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
|
|
511
525
|
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
512
526
|
const uriString = model.uri.toString();
|
|
513
527
|
const toDispose = this.inlineDiffService.onPartialEdit((event) => {
|
|
514
|
-
// TODO 支持自动保存
|
|
515
528
|
if (
|
|
516
529
|
event.totalPartialEditCount === event.resolvedPartialEditCount &&
|
|
517
530
|
event.uri.path === model.uri.path.toString()
|
|
@@ -532,11 +545,19 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
532
545
|
actionSource: ActionSourceEnum.Chat,
|
|
533
546
|
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
534
547
|
isReceive: true,
|
|
535
|
-
|
|
536
|
-
|
|
548
|
+
// 是否有丢弃部分代码
|
|
549
|
+
isDrop: event.acceptPartialEditCount !== event.totalPartialEditCount,
|
|
550
|
+
code: appliedResult,
|
|
551
|
+
originCode: codeBlock.originalCode,
|
|
537
552
|
message: JSON.stringify({
|
|
538
553
|
diff,
|
|
539
554
|
diagnosticInfos,
|
|
555
|
+
instructions: codeBlock.instructions,
|
|
556
|
+
codeEdit: codeBlock.codeEdit,
|
|
557
|
+
partialEditCount: event.totalPartialEditCount,
|
|
558
|
+
acceptPartialEditCount: event.acceptPartialEditCount,
|
|
559
|
+
addedLinesCount: event.totalAddedLinesCount,
|
|
560
|
+
deletedLinesCount: event.totalDeletedLinesCount,
|
|
540
561
|
}),
|
|
541
562
|
});
|
|
542
563
|
deferred.resolve({
|
|
@@ -554,8 +575,11 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
554
575
|
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
555
576
|
isReceive: false,
|
|
556
577
|
isDrop: true,
|
|
557
|
-
code: codeBlock.codeEdit,
|
|
558
578
|
originCode: codeBlock.originalCode,
|
|
579
|
+
message: JSON.stringify({
|
|
580
|
+
instructions: codeBlock.instructions,
|
|
581
|
+
codeEdit: codeBlock.codeEdit,
|
|
582
|
+
}),
|
|
559
583
|
});
|
|
560
584
|
}
|
|
561
585
|
this.editorListenerMap.disposeKey(uriString);
|
|
@@ -593,8 +617,6 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
593
617
|
result?: string;
|
|
594
618
|
}>;
|
|
595
619
|
|
|
596
|
-
// FIXME: 貌似筛选逻辑不太对,需要重构
|
|
597
|
-
// TODO: 支持使用内存中的document获取诊断信息,实现并行apply accept
|
|
598
620
|
protected getDiagnosticInfos(uri: string, ranges: Range[]) {
|
|
599
621
|
const markers = this.markerService.getManager().getMarkers({ resource: uri });
|
|
600
622
|
return markers.filter(
|
|
@@ -5,6 +5,7 @@ import { Badge } from '@opensumi/ide-components';
|
|
|
5
5
|
import { AINativeSettingSectionsId, ILogger, useInjectable } from '@opensumi/ide-core-browser';
|
|
6
6
|
import { PreferenceService } from '@opensumi/ide-core-browser/lib/preferences';
|
|
7
7
|
import { localize } from '@opensumi/ide-core-common';
|
|
8
|
+
import { IMessageService } from '@opensumi/ide-overlay/lib/common';
|
|
8
9
|
|
|
9
10
|
import { BUILTIN_MCP_SERVER_NAME, ISumiMCPServerBackend, SumiMCPServerProxyServicePath } from '../../../../common';
|
|
10
11
|
import { MCPServerDescription } from '../../../../common/mcp-server-manager';
|
|
@@ -19,6 +20,7 @@ export const MCPConfigView: React.FC = () => {
|
|
|
19
20
|
const preferenceService = useInjectable<PreferenceService>(PreferenceService);
|
|
20
21
|
const sumiMCPServerBackendProxy = useInjectable<ISumiMCPServerBackend>(SumiMCPServerProxyServicePath);
|
|
21
22
|
const logger = useInjectable<ILogger>(ILogger);
|
|
23
|
+
const messageService = useInjectable<IMessageService>(IMessageService);
|
|
22
24
|
const [servers, setServers] = React.useState<MCPServer[]>([]);
|
|
23
25
|
const [formVisible, setFormVisible] = React.useState(false);
|
|
24
26
|
const [editingServer, setEditingServer] = React.useState<MCPServerFormData | undefined>();
|
|
@@ -88,7 +90,9 @@ export const MCPConfigView: React.FC = () => {
|
|
|
88
90
|
await preferenceService.set(AINativeSettingSectionsId.MCPServers, updatedServers);
|
|
89
91
|
await loadServers();
|
|
90
92
|
} catch (error) {
|
|
93
|
+
const msg = error.message || error;
|
|
91
94
|
logger.error(`Failed to ${start ? 'start' : 'stop'} server ${serverName}:`, error);
|
|
95
|
+
messageService.error(`Failed to ${start ? 'start' : 'stop'} server ${serverName}:` + msg);
|
|
92
96
|
}
|
|
93
97
|
},
|
|
94
98
|
[mcpServerProxyService, preferenceService, sumiMCPServerBackendProxy, loadServers],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Autowired } from '@opensumi/di';
|
|
2
2
|
import { LabelService } from '@opensumi/ide-core-browser/lib/services';
|
|
3
|
-
import { Domain,
|
|
3
|
+
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
4
4
|
import {
|
|
5
5
|
BrowserEditorContribution,
|
|
6
6
|
EditorComponentRegistry,
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
path,
|
|
13
13
|
useInjectable,
|
|
14
14
|
} from '@opensumi/ide-core-browser';
|
|
15
|
-
import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
16
15
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
17
16
|
import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages/language';
|
|
18
17
|
import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
|
|
19
18
|
import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
20
19
|
|
|
21
20
|
import { CodeBlockData } from '../../../../common/types';
|
|
21
|
+
import { ApplyStatus } from '../../../components/ApplyStatus';
|
|
22
22
|
import { ChatMarkdown } from '../../../components/ChatMarkdown';
|
|
23
23
|
import { IMCPServerToolComponentProps } from '../../../types';
|
|
24
24
|
import { BaseApplyService } from '../../base-apply.service';
|
|
@@ -76,7 +76,7 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
return [
|
|
79
|
-
instructions && <p>{instructions}</p>,
|
|
79
|
+
instructions && <p key={'edit-file-tool-instructions'}>{instructions}</p>,
|
|
80
80
|
<div className={styles['edit-file-tool']} key={'edit-file-tool'}>
|
|
81
81
|
<div
|
|
82
82
|
className={cls(styles['edit-file-tool-header'], {
|
|
@@ -96,7 +96,7 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
96
96
|
{codeBlockData.iterationCount > 1 && (
|
|
97
97
|
<span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
|
|
98
98
|
)}
|
|
99
|
-
{
|
|
99
|
+
<ApplyStatus status={codeBlockData.status} error={props.result} />
|
|
100
100
|
</div>
|
|
101
101
|
<div className={styles.right}>
|
|
102
102
|
<Popover title={'Show Code'} id={'edit-file-tool-show-code'}>
|
|
@@ -137,37 +137,3 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
137
137
|
),
|
|
138
138
|
];
|
|
139
139
|
};
|
|
140
|
-
|
|
141
|
-
const renderStatus = (codeBlockData: CodeBlockData, error?: string) => {
|
|
142
|
-
const status = codeBlockData.status;
|
|
143
|
-
switch (status) {
|
|
144
|
-
case 'generating':
|
|
145
|
-
return <Loading />;
|
|
146
|
-
case 'pending':
|
|
147
|
-
return (
|
|
148
|
-
<Popover title='Pending' id={'edit-file-tool-status-pending'}>
|
|
149
|
-
<Icon iconClass='codicon codicon-circle-large' />
|
|
150
|
-
</Popover>
|
|
151
|
-
);
|
|
152
|
-
case 'success':
|
|
153
|
-
return (
|
|
154
|
-
<Popover title='Success' id={'edit-file-tool-status-success'}>
|
|
155
|
-
<Icon iconClass='codicon codicon-check-all' />
|
|
156
|
-
</Popover>
|
|
157
|
-
);
|
|
158
|
-
case 'failed':
|
|
159
|
-
return (
|
|
160
|
-
<Popover title={`Failed (${error})`} id={'edit-file-tool-status-failed'}>
|
|
161
|
-
<Icon iconClass='codicon codicon-error' style={{ color: 'var(--debugConsole-errorForeground)' }} />
|
|
162
|
-
</Popover>
|
|
163
|
-
);
|
|
164
|
-
case 'cancelled':
|
|
165
|
-
return (
|
|
166
|
-
<Popover title='Cancelled' id={'edit-file-tool-status-cancelled'}>
|
|
167
|
-
<Icon iconClass='codicon codicon-close' style={{ color: 'var(--input-placeholderForeground)' }} />
|
|
168
|
-
</Popover>
|
|
169
|
-
);
|
|
170
|
-
default:
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
};
|