@opensumi/ide-ai-native 3.8.1-next-1740735952.0 → 3.8.1-next-1740965430.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 +4 -1
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +20 -1
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-agent.service.d.ts +8 -0
- package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-agent.service.js +34 -0
- package/lib/browser/chat/chat-agent.service.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +1 -0
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +13 -0
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +3 -2
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +1 -1
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.internal.service.d.ts +1 -0
- package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
- package/lib/browser/chat/chat.internal.service.js +3 -0
- package/lib/browser/chat/chat.internal.service.js.map +1 -1
- package/lib/browser/chat/chat.module.less +1 -2
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +6 -38
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatContext/index.js +2 -2
- package/lib/browser/components/ChatContext/index.js.map +1 -1
- package/lib/browser/components/ChatHistory.d.ts +0 -1
- package/lib/browser/components/ChatHistory.d.ts.map +1 -1
- package/lib/browser/components/ChatHistory.js +14 -14
- package/lib/browser/components/ChatHistory.js.map +1 -1
- package/lib/browser/components/ChatInput.d.ts.map +1 -1
- package/lib/browser/components/ChatInput.js +25 -1
- package/lib/browser/components/ChatInput.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +2 -3
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/{chat-history.css → chat-history.module.less} +1 -1
- package/lib/browser/components/components.module.less +20 -0
- package/lib/browser/context/llm-context.service.d.ts +18 -5
- package/lib/browser/context/llm-context.service.d.ts.map +1 -1
- package/lib/browser/context/llm-context.service.js +80 -47
- package/lib/browser/context/llm-context.service.js.map +1 -1
- package/lib/browser/layout/layout.module.less +4 -4
- package/lib/browser/mcp/base-apply.service.d.ts +31 -40
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +233 -167
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.js +55 -41
- package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/components/index.module.less +23 -3
- 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.js +1 -1
- package/lib/browser/mcp/tools/editFile.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js +1 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/EditFile.d.ts +5 -1
- package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/EditFile.js +4 -4
- package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.js +2 -0
- package/lib/browser/mcp/tools/handlers/RunCommand.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 +1 -0
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +12 -2
- 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 +0 -1
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +1 -1
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts +6 -0
- package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -0
- package/lib/browser/widget/inline-diff/inline-diff-manager.js +27 -0
- package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -0
- package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +12 -0
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +2 -0
- 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 +11 -4
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/common/llm-context.d.ts +13 -9
- package/lib/common/llm-context.d.ts.map +1 -1
- package/lib/common/llm-context.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts +4 -3
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +33 -22
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/types.d.ts +17 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js.map +1 -1
- package/lib/node/base-language-model.d.ts +1 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +54 -3
- package/lib/node/base-language-model.js.map +1 -1
- package/package.json +23 -23
- package/src/browser/ai-core.contribution.ts +25 -1
- package/src/browser/chat/chat-agent.service.ts +42 -3
- package/src/browser/chat/chat-manager.service.ts +12 -0
- package/src/browser/chat/chat-model.ts +11 -6
- package/src/browser/chat/chat-proxy.service.ts +2 -1
- package/src/browser/chat/chat.internal.service.ts +4 -0
- package/src/browser/chat/chat.module.less +1 -2
- package/src/browser/chat/chat.view.tsx +7 -70
- package/src/browser/components/ChatContext/index.tsx +2 -2
- package/src/browser/components/ChatHistory.tsx +21 -15
- package/src/browser/components/ChatInput.tsx +67 -4
- package/src/browser/components/ChatToolRender.tsx +1 -2
- package/src/browser/components/{chat-history.css → chat-history.module.less} +1 -1
- package/src/browser/components/components.module.less +20 -0
- package/src/browser/context/llm-context.service.ts +93 -54
- package/src/browser/layout/layout.module.less +4 -4
- package/src/browser/mcp/base-apply.service.ts +266 -213
- package/src/browser/mcp/tools/components/EditFile.tsx +82 -60
- package/src/browser/mcp/tools/components/index.module.less +23 -3
- package/src/browser/mcp/tools/createNewFileWithText.ts +1 -0
- package/src/browser/mcp/tools/editFile.ts +2 -2
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -0
- package/src/browser/mcp/tools/handlers/EditFile.ts +4 -4
- package/src/browser/mcp/tools/handlers/RunCommand.ts +2 -0
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -0
- package/src/browser/model/msg-history-manager.ts +12 -2
- package/src/browser/preferences/schema.ts +0 -1
- package/src/browser/types.ts +1 -1
- package/src/browser/widget/inline-diff/inline-diff-manager.tsx +38 -0
- package/src/browser/widget/inline-diff/inline-diff-widget.module.less +12 -0
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +13 -4
- package/src/common/llm-context.ts +10 -4
- package/src/common/prompts/context-prompt-provider.ts +38 -29
- package/src/common/types.ts +20 -0
- package/src/node/base-language-model.ts +63 -1
|
@@ -59,7 +59,11 @@ import {
|
|
|
59
59
|
} from '@opensumi/ide-core-common';
|
|
60
60
|
import { DESIGN_MENU_BAR_RIGHT } from '@opensumi/ide-design';
|
|
61
61
|
import { IEditor, WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
62
|
-
import {
|
|
62
|
+
import {
|
|
63
|
+
BrowserEditorContribution,
|
|
64
|
+
EditorComponentRegistry,
|
|
65
|
+
IEditorFeatureRegistry,
|
|
66
|
+
} from '@opensumi/ide-editor/lib/browser';
|
|
63
67
|
import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service';
|
|
64
68
|
import { IMainLayoutService } from '@opensumi/ide-main-layout';
|
|
65
69
|
import { ISettingRegistry, SettingContribution } from '@opensumi/ide-preferences';
|
|
@@ -100,6 +104,7 @@ import {
|
|
|
100
104
|
AIRightTabRenderer,
|
|
101
105
|
} from './layout/tabbar.view';
|
|
102
106
|
import { AIChatLogoAvatar } from './layout/view/avatar/avatar.view';
|
|
107
|
+
import { BaseApplyService } from './mcp/base-apply.service';
|
|
103
108
|
import {
|
|
104
109
|
AINativeCoreContribution,
|
|
105
110
|
IChatFeatureRegistry,
|
|
@@ -116,6 +121,7 @@ import {
|
|
|
116
121
|
import { InlineChatEditorController } from './widget/inline-chat/inline-chat-editor.controller';
|
|
117
122
|
import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
|
|
118
123
|
import { InlineChatService } from './widget/inline-chat/inline-chat.service';
|
|
124
|
+
import { InlineDiffManager } from './widget/inline-diff/inline-diff-manager';
|
|
119
125
|
import { InlineDiffController } from './widget/inline-diff/inline-diff.controller';
|
|
120
126
|
import { InlineHintController } from './widget/inline-hint/inline-hint.controller';
|
|
121
127
|
import { InlineInputController } from './widget/inline-input/inline-input.controller';
|
|
@@ -123,6 +129,8 @@ import { InlineInputService } from './widget/inline-input/inline-input.service';
|
|
|
123
129
|
import { InlineStreamDiffService } from './widget/inline-stream-diff/inline-stream-diff.service';
|
|
124
130
|
import { SumiLightBulbWidget } from './widget/light-bulb';
|
|
125
131
|
|
|
132
|
+
export const INLINE_DIFF_MANAGER_WIDGET_ID = 'inline-diff-manager-widget';
|
|
133
|
+
|
|
126
134
|
@Domain(
|
|
127
135
|
ClientAppContribution,
|
|
128
136
|
BrowserEditorContribution,
|
|
@@ -237,6 +245,9 @@ export class AINativeBrowserContribution
|
|
|
237
245
|
@Autowired(IChatInternalService)
|
|
238
246
|
private readonly chatInternalService: ChatInternalService;
|
|
239
247
|
|
|
248
|
+
@Autowired(BaseApplyService)
|
|
249
|
+
private readonly applyService: BaseApplyService;
|
|
250
|
+
|
|
240
251
|
constructor() {
|
|
241
252
|
this.registerFeature();
|
|
242
253
|
}
|
|
@@ -524,6 +535,19 @@ export class AINativeBrowserContribution
|
|
|
524
535
|
});
|
|
525
536
|
}
|
|
526
537
|
|
|
538
|
+
registerEditorComponent(registry: EditorComponentRegistry): void {
|
|
539
|
+
registry.registerEditorSideWidget({
|
|
540
|
+
id: INLINE_DIFF_MANAGER_WIDGET_ID,
|
|
541
|
+
component: InlineDiffManager,
|
|
542
|
+
displaysOnResource: (resource) => {
|
|
543
|
+
if (this.applyService.getUriPendingCodeBlock(resource.uri)) {
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
return false;
|
|
547
|
+
},
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
527
551
|
registerCommands(commands: CommandRegistry): void {
|
|
528
552
|
commands.registerCommand(AI_INLINE_CHAT_VISIBLE, {
|
|
529
553
|
execute: (value: boolean) => {
|
|
@@ -4,16 +4,15 @@ import { Autowired, Injectable } from '@opensumi/di';
|
|
|
4
4
|
import {
|
|
5
5
|
CancellationToken,
|
|
6
6
|
ChatFeatureRegistryToken,
|
|
7
|
+
ChatMessageRole,
|
|
7
8
|
ChatServiceToken,
|
|
8
9
|
Disposable,
|
|
9
10
|
Emitter,
|
|
10
|
-
IChatContent,
|
|
11
11
|
IChatProgress,
|
|
12
12
|
IDisposable,
|
|
13
13
|
ILogger,
|
|
14
|
-
toDisposable
|
|
14
|
+
toDisposable
|
|
15
15
|
} from '@opensumi/ide-core-common';
|
|
16
|
-
import { ChatMessageRole } from '@opensumi/ide-core-common';
|
|
17
16
|
import { IChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
|
|
18
17
|
|
|
19
18
|
import {
|
|
@@ -26,6 +25,8 @@ import {
|
|
|
26
25
|
IChatFollowup,
|
|
27
26
|
IChatMessageStructure,
|
|
28
27
|
} from '../../common';
|
|
28
|
+
import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
|
|
29
|
+
import { ChatAgentPromptProvider } from '../../common/prompts/context-prompt-provider';
|
|
29
30
|
import { IChatFeatureRegistry } from '../types';
|
|
30
31
|
|
|
31
32
|
import { ChatService } from './chat.api.service';
|
|
@@ -36,6 +37,12 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
|
|
|
36
37
|
|
|
37
38
|
private defaultAgentId: string | undefined;
|
|
38
39
|
|
|
40
|
+
private initialUserMessageMap: Map<string, string> = new Map();
|
|
41
|
+
|
|
42
|
+
private shouldUpdateContext = false;
|
|
43
|
+
|
|
44
|
+
private contextVersion: number;
|
|
45
|
+
|
|
39
46
|
private readonly _onDidChangeAgents = new Emitter<void>();
|
|
40
47
|
readonly onDidChangeAgents = this._onDidChangeAgents.event;
|
|
41
48
|
|
|
@@ -45,6 +52,12 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
|
|
|
45
52
|
@Autowired(ILogger)
|
|
46
53
|
logger: ILogger;
|
|
47
54
|
|
|
55
|
+
@Autowired(LLMContextServiceToken)
|
|
56
|
+
protected readonly contextService: LLMContextService;
|
|
57
|
+
|
|
58
|
+
@Autowired(ChatAgentPromptProvider)
|
|
59
|
+
protected readonly promptProvider: ChatAgentPromptProvider;
|
|
60
|
+
|
|
48
61
|
@Autowired(ChatServiceToken)
|
|
49
62
|
private aiChatService: ChatService;
|
|
50
63
|
|
|
@@ -54,6 +67,12 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
|
|
|
54
67
|
constructor() {
|
|
55
68
|
super();
|
|
56
69
|
this.addDispose(this._onDidChangeAgents);
|
|
70
|
+
this.addDispose(this.contextService.onDidContextFilesChangeEvent((event) => {
|
|
71
|
+
if (event.version !== this.contextVersion) {
|
|
72
|
+
this.contextVersion = event.version;
|
|
73
|
+
this.shouldUpdateContext = true;
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
57
76
|
}
|
|
58
77
|
|
|
59
78
|
registerAgent(agent: IChatAgent): IDisposable {
|
|
@@ -120,6 +139,8 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
|
|
|
120
139
|
if (!data) {
|
|
121
140
|
throw new Error(`No agent with id ${id}`);
|
|
122
141
|
}
|
|
142
|
+
|
|
143
|
+
// system
|
|
123
144
|
if (data.agent.metadata.systemPrompt) {
|
|
124
145
|
history.unshift({
|
|
125
146
|
role: ChatMessageRole.System,
|
|
@@ -127,10 +148,28 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
|
|
|
127
148
|
});
|
|
128
149
|
}
|
|
129
150
|
|
|
151
|
+
// 发送第一条消息时携带初始 context
|
|
152
|
+
if (!this.initialUserMessageMap.has(id)) {
|
|
153
|
+
this.initialUserMessageMap.set(id, request.message);
|
|
154
|
+
const rawMessage = request.message;
|
|
155
|
+
request.message = this.provideContextMessage(rawMessage);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (this.shouldUpdateContext) {
|
|
159
|
+
request.message = this.provideContextMessage(request.message);
|
|
160
|
+
this.shouldUpdateContext = false;
|
|
161
|
+
}
|
|
162
|
+
|
|
130
163
|
const result = await data.agent.invoke(request, progress, history, token);
|
|
131
164
|
return result;
|
|
132
165
|
}
|
|
133
166
|
|
|
167
|
+
private provideContextMessage(message: string) {
|
|
168
|
+
const context = this.contextService.serialize();
|
|
169
|
+
const fullMessage = this.promptProvider.provideContextPrompt(context, message);
|
|
170
|
+
return fullMessage;
|
|
171
|
+
}
|
|
172
|
+
|
|
134
173
|
populateChatInput(id: string, message: IChatMessageStructure) {
|
|
135
174
|
this.aiChatService.sendMessage({
|
|
136
175
|
...message,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
IStorage,
|
|
10
10
|
STORAGE_NAMESPACE,
|
|
11
11
|
StorageProvider,
|
|
12
|
+
debounce,
|
|
12
13
|
} from '@opensumi/ide-core-common';
|
|
13
14
|
import { ChatMessageRole, IChatMessage, IHistoryChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
|
|
14
15
|
|
|
@@ -89,6 +90,7 @@ export class ChatManagerService extends Disposable {
|
|
|
89
90
|
const savedSessions = this.fromJSON(sessionsModelData);
|
|
90
91
|
savedSessions.forEach((session) => {
|
|
91
92
|
this.#sessionModels.set(session.sessionId, session);
|
|
93
|
+
this.listenSession(session);
|
|
92
94
|
});
|
|
93
95
|
await this.storageInitEmitter.fireAndAwait();
|
|
94
96
|
}
|
|
@@ -100,6 +102,7 @@ export class ChatManagerService extends Disposable {
|
|
|
100
102
|
startSession() {
|
|
101
103
|
const model = new ChatModel();
|
|
102
104
|
this.#sessionModels.set(model.sessionId, model);
|
|
105
|
+
this.listenSession(model);
|
|
103
106
|
return model;
|
|
104
107
|
}
|
|
105
108
|
|
|
@@ -196,6 +199,15 @@ export class ChatManagerService extends Disposable {
|
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
|
|
202
|
+
protected listenSession(session: ChatModel) {
|
|
203
|
+
this.addDispose(
|
|
204
|
+
session.history.onMessageAdditionalChange(() => {
|
|
205
|
+
this.saveSessions();
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@debounce(1000)
|
|
199
211
|
protected saveSessions() {
|
|
200
212
|
this._chatStorage.set('sessionModels', this.getSessions());
|
|
201
213
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Injectable } from '@opensumi/di';
|
|
2
2
|
import {
|
|
3
3
|
Disposable,
|
|
4
4
|
Emitter,
|
|
@@ -8,8 +8,6 @@ import {
|
|
|
8
8
|
IChatProgress,
|
|
9
9
|
IChatToolContent,
|
|
10
10
|
IChatTreeData,
|
|
11
|
-
ILogger,
|
|
12
|
-
memoize,
|
|
13
11
|
uuid,
|
|
14
12
|
} from '@opensumi/ide-core-common';
|
|
15
13
|
import { MarkdownString, isMarkdownString } from '@opensumi/monaco-editor-core/esm/vs/base/common/htmlContent';
|
|
@@ -274,13 +272,18 @@ export class ChatRequestModel implements IChatRequestModel {
|
|
|
274
272
|
export class ChatModel extends Disposable implements IChatModel {
|
|
275
273
|
private static requestIdPool = 0;
|
|
276
274
|
|
|
277
|
-
constructor(initParams?: {
|
|
275
|
+
constructor(initParams?: {
|
|
276
|
+
sessionId?: string;
|
|
277
|
+
history?: MsgHistoryManager;
|
|
278
|
+
requests?: ChatRequestModel[];
|
|
279
|
+
}) {
|
|
278
280
|
super();
|
|
279
281
|
this.#sessionId = initParams?.sessionId ?? uuid();
|
|
280
282
|
this.history = initParams?.history ?? new MsgHistoryManager();
|
|
281
283
|
if (initParams?.requests) {
|
|
282
284
|
this.#requests = new Map(initParams.requests.map((r) => [r.requestId, r]));
|
|
283
285
|
}
|
|
286
|
+
|
|
284
287
|
}
|
|
285
288
|
|
|
286
289
|
#sessionId: string;
|
|
@@ -300,9 +303,11 @@ export class ChatModel extends Disposable implements IChatModel {
|
|
|
300
303
|
readonly history: MsgHistoryManager;
|
|
301
304
|
|
|
302
305
|
addRequest(message: IChatRequestMessage): ChatRequestModel {
|
|
306
|
+
const msg = message;
|
|
307
|
+
|
|
303
308
|
const requestId = `${this.sessionId}_request_${ChatModel.requestIdPool++}`;
|
|
304
|
-
const response = new ChatResponseModel(requestId, this,
|
|
305
|
-
const request = new ChatRequestModel(requestId, this,
|
|
309
|
+
const response = new ChatResponseModel(requestId, this, msg.agentId);
|
|
310
|
+
const request = new ChatRequestModel(requestId, this, msg, response);
|
|
306
311
|
|
|
307
312
|
this.#requests.set(requestId, request);
|
|
308
313
|
return request;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ChatServiceToken,
|
|
9
9
|
Deferred,
|
|
10
10
|
Disposable,
|
|
11
|
+
getOperatingSystemName,
|
|
11
12
|
IAIBackService,
|
|
12
13
|
IAIReporter,
|
|
13
14
|
IApplicationService,
|
|
@@ -92,7 +93,7 @@ export class ChatProxyService extends Disposable {
|
|
|
92
93
|
AINativeSettingSectionsId.SystemPrompt,
|
|
93
94
|
'You are a powerful AI coding assistant working in OpenSumi, a top IDE framework. You collaborate with a USER to solve coding tasks, which may involve creating, modifying, or debugging code, or answering questions. When the USER sends a message, relevant context (e.g., open files, cursor position, edit history, linter errors) may be attached. Use this information as needed.\n\n<tool_calling>\nYou have access to tools to assist with tasks. Follow these rules:\n1. Always adhere to the tool call schema and provide all required parameters.\n2. Only use tools explicitly provided; ignore unavailable ones.\n3. Avoid mentioning tool names to the USER (e.g., say "I will edit your file" instead of "I need to use the edit_file tool").\n4. Only call tools when necessary; respond directly if the task is general or you already know the answer.\n5. Explain to the USER why you’re using a tool before calling it.\n</tool_calling>\n\n<making_code_changes>\nWhen modifying code:\n1. Use code edit tools instead of outputting code unless explicitly requested.\n2. Limit tool calls to one per turn.\n3. Ensure generated code is immediately executable by including necessary imports, dependencies, and endpoints.\n4. For new projects, create a dependency management file (e.g., requirements.txt) and a README.\n5. For web apps, design a modern, user-friendly UI.\n6. Avoid generating non-textual or excessively long code.\n7. Read file contents before editing, unless appending a small change or creating a new file.\n8. Fix introduced linter errors if possible, but stop after 3 attempts and ask the USER for guidance.\n9. Reapply reasonable code edits if they weren’t followed initially.\n</making_code_changes>\n\nUse the appropriate tools to fulfill the USER’s request, ensuring all required parameters are provided or inferred from context.',
|
|
94
95
|
) +
|
|
95
|
-
`\n\n<user_info>\nThe user's OS
|
|
96
|
+
`\n\n<user_info>\nThe user's OS is ${getOperatingSystemName()}. The absolute path of the user's workspace is ${this.appConfig.workspaceDir}.\n</user_info>`,
|
|
96
97
|
},
|
|
97
98
|
invoke: async (
|
|
98
99
|
request: IChatAgentRequest,
|
|
@@ -94,6 +94,10 @@ export class ChatInternalService extends Disposable {
|
|
|
94
94
|
return this.chatManagerService.getSessions();
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
getSession(sessionId: string) {
|
|
98
|
+
return this.chatManagerService.getSession(sessionId);
|
|
99
|
+
}
|
|
100
|
+
|
|
97
101
|
activateSession(sessionId: string) {
|
|
98
102
|
const targetSession = this.chatManagerService.getSession(sessionId);
|
|
99
103
|
if (!targetSession) {
|
|
@@ -279,7 +279,6 @@
|
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
|
|
283
282
|
.chat_tips_container {
|
|
284
283
|
display: flex;
|
|
285
284
|
align-items: center;
|
|
@@ -290,6 +289,6 @@
|
|
|
290
289
|
}
|
|
291
290
|
|
|
292
291
|
.chat_history {
|
|
293
|
-
width: calc(100% -
|
|
292
|
+
width: calc(100% - 40px);
|
|
294
293
|
color: var(--design-text-foreground);
|
|
295
294
|
}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
AINativeConfigService,
|
|
6
6
|
CommandService,
|
|
7
7
|
getIcon,
|
|
8
|
-
useEventEffect,
|
|
9
8
|
useInjectable,
|
|
10
9
|
useUpdateOnEvent,
|
|
11
10
|
} from '@opensumi/ide-core-browser';
|
|
@@ -42,8 +41,6 @@ import {
|
|
|
42
41
|
IChatMessageStructure,
|
|
43
42
|
TokenMCPServerProxyService,
|
|
44
43
|
} from '../../common';
|
|
45
|
-
import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
|
|
46
|
-
import { ChatAgentPromptProvider } from '../../common/prompts/context-prompt-provider';
|
|
47
44
|
import { ChatContext } from '../components/ChatContext';
|
|
48
45
|
import { CodeBlockWrapperInput } from '../components/ChatEditor';
|
|
49
46
|
import ChatHistory, { IChatHistoryItem } from '../components/ChatHistory';
|
|
@@ -82,17 +79,11 @@ export const AIChatView = () => {
|
|
|
82
79
|
const chatAgentService = useInjectable<IChatAgentService>(IChatAgentService);
|
|
83
80
|
const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
|
|
84
81
|
const chatRenderRegistry = useInjectable<ChatRenderRegistry>(ChatRenderRegistryToken);
|
|
85
|
-
const contextService = useInjectable<LLMContextService>(LLMContextServiceToken);
|
|
86
|
-
const promptProvider = useInjectable<ChatAgentPromptProvider>(ChatAgentPromptProvider);
|
|
87
|
-
const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
|
|
88
82
|
|
|
89
83
|
const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
|
|
90
84
|
const msgHistoryManager = aiChatService.sessionModel.history;
|
|
91
85
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
92
86
|
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);
|
|
96
87
|
|
|
97
88
|
const [shortcutCommands, setShortcutCommands] = React.useState<ChatSlashCommandItemModel[]>([]);
|
|
98
89
|
|
|
@@ -114,8 +105,6 @@ export const AIChatView = () => {
|
|
|
114
105
|
const [defaultAgentId, setDefaultAgentId] = React.useState<string>('');
|
|
115
106
|
const [command, setCommand] = React.useState('');
|
|
116
107
|
const [theme, setTheme] = React.useState<string | null>(null);
|
|
117
|
-
const [mcpToolsCount, setMcpToolsCount] = React.useState<number>(0);
|
|
118
|
-
const [mcpServersCount, setMcpServersCount] = React.useState<number>(0);
|
|
119
108
|
|
|
120
109
|
React.useEffect(() => {
|
|
121
110
|
const featureSlashCommands = chatFeatureRegistry.getAllShortcutSlashCommand();
|
|
@@ -515,10 +504,7 @@ export const AIChatView = () => {
|
|
|
515
504
|
const { message, agentId, command, reportExtra } = value;
|
|
516
505
|
const { actionType, actionSource } = reportExtra || {};
|
|
517
506
|
|
|
518
|
-
const
|
|
519
|
-
const fullMessage = await promptProvider.provideContextPrompt(context, message);
|
|
520
|
-
|
|
521
|
-
const request = aiChatService.createRequest(fullMessage, agentId!, command);
|
|
507
|
+
const request = aiChatService.createRequest(message, agentId!, command);
|
|
522
508
|
if (!request) {
|
|
523
509
|
return;
|
|
524
510
|
}
|
|
@@ -667,32 +653,6 @@ export const AIChatView = () => {
|
|
|
667
653
|
};
|
|
668
654
|
}, [aiChatService.sessionModel]);
|
|
669
655
|
|
|
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
|
-
|
|
696
656
|
return (
|
|
697
657
|
<div id={styles.ai_chat_view}>
|
|
698
658
|
<div className={styles.header_container}>
|
|
@@ -732,18 +692,6 @@ export const AIChatView = () => {
|
|
|
732
692
|
</Popover>
|
|
733
693
|
))}
|
|
734
694
|
</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>
|
|
747
695
|
</div>
|
|
748
696
|
<ChatInputWrapperRender
|
|
749
697
|
onSend={(value, agentId, command) =>
|
|
@@ -786,6 +734,8 @@ export function DefaultChatViewHeader({
|
|
|
786
734
|
const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
|
|
787
735
|
const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
|
|
788
736
|
const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
|
|
737
|
+
const commandService = useInjectable<CommandService>(CommandService);
|
|
738
|
+
|
|
789
739
|
const [historyList, setHistoryList] = React.useState<IChatHistoryItem[]>([]);
|
|
790
740
|
const [currentTitle, setCurrentTitle] = React.useState<string>('');
|
|
791
741
|
const handleNewChat = React.useCallback(() => {
|
|
@@ -806,6 +756,10 @@ export function DefaultChatViewHeader({
|
|
|
806
756
|
[aiChatService],
|
|
807
757
|
);
|
|
808
758
|
|
|
759
|
+
const handleShowMCPConfig = React.useCallback(() => {
|
|
760
|
+
commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
|
|
761
|
+
}, [commandService]);
|
|
762
|
+
|
|
809
763
|
const handleShowMCPTools = React.useCallback(async () => {
|
|
810
764
|
const tools = await mcpServerProxyService.getAllMCPTools();
|
|
811
765
|
dialogService.open({
|
|
@@ -894,23 +848,6 @@ export function DefaultChatViewHeader({
|
|
|
894
848
|
ariaLabel={localize('aiNative.operate.clear.title')}
|
|
895
849
|
/>
|
|
896
850
|
</Popover>
|
|
897
|
-
{aiNativeConfigService.capabilities.supportsMCP && (
|
|
898
|
-
<Popover
|
|
899
|
-
overlayClassName={styles.popover_icon}
|
|
900
|
-
id={'ai-chat-header-tools'}
|
|
901
|
-
position={PopoverPosition.left}
|
|
902
|
-
title={localize('aiNative.operate.tools.title')}
|
|
903
|
-
>
|
|
904
|
-
<EnhanceIcon
|
|
905
|
-
wrapperClassName={styles.action_btn}
|
|
906
|
-
className={getIcon('menubar-tool')}
|
|
907
|
-
onClick={handleShowMCPTools}
|
|
908
|
-
tabIndex={0}
|
|
909
|
-
role='button'
|
|
910
|
-
ariaLabel={localize('aiNative.operate.tools.title')}
|
|
911
|
-
/>
|
|
912
|
-
</Popover>
|
|
913
|
-
)}
|
|
914
851
|
<Popover
|
|
915
852
|
overlayClassName={styles.popover_icon}
|
|
916
853
|
id={'ai-chat-header-close'}
|
|
@@ -39,7 +39,7 @@ export const ChatContext = memo(() => {
|
|
|
39
39
|
50,
|
|
40
40
|
)((files) => {
|
|
41
41
|
if (files) {
|
|
42
|
-
updateAddedFiles(files);
|
|
42
|
+
updateAddedFiles([...files.attached]);
|
|
43
43
|
}
|
|
44
44
|
}, contextService);
|
|
45
45
|
|
|
@@ -57,7 +57,7 @@ export const ChatContext = memo(() => {
|
|
|
57
57
|
}, []);
|
|
58
58
|
|
|
59
59
|
const onDidDeselect = useCallback((uri: URI) => {
|
|
60
|
-
contextService.removeFileFromContext(uri);
|
|
60
|
+
contextService.removeFileFromContext(uri, true);
|
|
61
61
|
}, []);
|
|
62
62
|
|
|
63
63
|
const onDidClickFile = useCallback((uri: URI) => {
|
|
@@ -2,10 +2,11 @@ import cls from 'classnames';
|
|
|
2
2
|
import React, { FC, memo, useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
|
|
4
4
|
import { Icon, Input, Loading, Popover, PopoverPosition, PopoverTriggerType, getIcon } from '@opensumi/ide-components';
|
|
5
|
-
import './chat-history.css';
|
|
6
5
|
import { localize } from '@opensumi/ide-core-browser';
|
|
7
6
|
import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
8
7
|
|
|
8
|
+
import styles from './chat-history.module.less';
|
|
9
|
+
|
|
9
10
|
export interface IChatHistoryItem {
|
|
10
11
|
id: string;
|
|
11
12
|
title: string;
|
|
@@ -162,22 +163,25 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
162
163
|
(item: IChatHistoryItem) => (
|
|
163
164
|
<div
|
|
164
165
|
key={item.id}
|
|
165
|
-
className={cls(
|
|
166
|
+
className={cls(
|
|
167
|
+
styles['dm-chat-history-item'],
|
|
168
|
+
item.id === currentId ? styles['dm-chat-history-item-selected'] : '',
|
|
169
|
+
)}
|
|
166
170
|
onClick={() => handleHistoryItemSelect(item)}
|
|
167
171
|
>
|
|
168
|
-
<div className='dm-chat-history-item-content'>
|
|
172
|
+
<div className={styles['dm-chat-history-item-content']}>
|
|
169
173
|
{item.loading ? (
|
|
170
174
|
<Loading />
|
|
171
175
|
) : (
|
|
172
176
|
<Icon icon='message' style={{ width: '16px', height: '16px', marginRight: 4 }} />
|
|
173
177
|
)}
|
|
174
178
|
{!historyTitleEditable?.[item.id] ? (
|
|
175
|
-
<span id={`dm-chat-history-item-title-${item.id}`} className='dm-chat-history-item-title'>
|
|
179
|
+
<span id={`dm-chat-history-item-title-${item.id}`} className={styles['dm-chat-history-item-title']}>
|
|
176
180
|
{item.title}
|
|
177
181
|
</span>
|
|
178
182
|
) : (
|
|
179
183
|
<Input
|
|
180
|
-
className='dm-chat-history-item-title'
|
|
184
|
+
className={styles['dm-chat-history-item-title']}
|
|
181
185
|
defaultValue={item.title}
|
|
182
186
|
ref={inputRef}
|
|
183
187
|
onPressEnter={(e: any) => {
|
|
@@ -187,7 +191,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
187
191
|
/>
|
|
188
192
|
)}
|
|
189
193
|
</div>
|
|
190
|
-
<div className='dm-chat-history-item-actions'>
|
|
194
|
+
<div className={styles['dm-chat-history-item-actions']}>
|
|
191
195
|
{/* <EditOutlined
|
|
192
196
|
title={localize('aiNative.operate.chatHistory.edit')}
|
|
193
197
|
style={{ marginRight: 8 }}
|
|
@@ -198,7 +202,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
198
202
|
}}
|
|
199
203
|
/> */}
|
|
200
204
|
<EnhanceIcon
|
|
201
|
-
className={cls('dm-chat-history-item-actions-delete', getIcon('delete'))}
|
|
205
|
+
className={cls(styles['dm-chat-history-item-actions-delete'], getIcon('delete'))}
|
|
202
206
|
onClick={(e) => {
|
|
203
207
|
e.preventDefault();
|
|
204
208
|
e.stopPropagation();
|
|
@@ -237,10 +241,10 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
237
241
|
value={searchValue}
|
|
238
242
|
onChange={handleSearchChange}
|
|
239
243
|
/>
|
|
240
|
-
<div className='dm-chat-history-list'>
|
|
244
|
+
<div className={styles['dm-chat-history-list']}>
|
|
241
245
|
{groupedHistoryList.map((group) => (
|
|
242
246
|
<div key={group.key} style={{ padding: '4px' }}>
|
|
243
|
-
<div className='dm-chat-history-time'>{group.key}</div>
|
|
247
|
+
<div className={styles['dm-chat-history-time']}>{group.key}</div>
|
|
244
248
|
{group.items.map(renderHistoryItem)}
|
|
245
249
|
</div>
|
|
246
250
|
))}
|
|
@@ -253,11 +257,11 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
253
257
|
const getPopupContainer = useCallback((triggerNode: HTMLElement) => triggerNode.parentElement!, []);
|
|
254
258
|
|
|
255
259
|
return (
|
|
256
|
-
<div className={cls('dm-chat-history-header', className)}>
|
|
257
|
-
<div className='dm-chat-history-header-title'>
|
|
260
|
+
<div className={cls(styles['dm-chat-history-header'], className)}>
|
|
261
|
+
<div className={styles['dm-chat-history-header-title']}>
|
|
258
262
|
<span>{title}</span>
|
|
259
263
|
</div>
|
|
260
|
-
<div className='dm-chat-history-header-actions'>
|
|
264
|
+
<div className={styles['dm-chat-history-header-actions']}>
|
|
261
265
|
<Popover
|
|
262
266
|
id='dm-chat-history-header-actions-history'
|
|
263
267
|
content={renderHistory()}
|
|
@@ -267,10 +271,12 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
267
271
|
getPopupContainer={getPopupContainer}
|
|
268
272
|
>
|
|
269
273
|
<div
|
|
270
|
-
className='dm-chat-history-header-actions-history'
|
|
274
|
+
className={styles['dm-chat-history-header-actions-history']}
|
|
271
275
|
title={localize('aiNative.operate.chatHistory.title')}
|
|
272
276
|
>
|
|
273
|
-
<EnhanceIcon
|
|
277
|
+
<EnhanceIcon
|
|
278
|
+
className={cls(styles['dm-chat-history-header-actions-history'], 'codicon codicon-history')}
|
|
279
|
+
/>
|
|
274
280
|
</div>
|
|
275
281
|
</Popover>
|
|
276
282
|
<Popover
|
|
@@ -279,7 +285,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
|
|
|
279
285
|
title={localize('aiNative.operate.newChat.title')}
|
|
280
286
|
>
|
|
281
287
|
<EnhanceIcon
|
|
282
|
-
className={cls('dm-chat-history-header-actions-new', getIcon('plus'))}
|
|
288
|
+
className={cls(styles['dm-chat-history-header-actions-new'], getIcon('plus'))}
|
|
283
289
|
onClick={handleNewChat}
|
|
284
290
|
/>
|
|
285
291
|
</Popover>
|