@opensumi/ide-ai-native 3.9.1-next-1749007675.0 → 3.9.1-next-1749022016.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/chat-manager.service.d.ts +0 -1
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +3 -8
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +1 -3
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +17 -48
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +0 -2
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +50 -57
- 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 +11 -7
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatMentionInput.d.ts.map +1 -1
- package/lib/browser/components/ChatMentionInput.js +141 -30
- package/lib/browser/components/ChatMentionInput.js.map +1 -1
- package/lib/browser/components/ChatReply.js +2 -2
- package/lib/browser/components/ChatReply.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +1 -0
- package/lib/browser/components/components.module.less +37 -8
- package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
- package/lib/browser/components/mention-input/mention-input.js +161 -14
- package/lib/browser/components/mention-input/mention-input.js.map +1 -1
- package/lib/browser/components/mention-input/mention-input.module.less +165 -1
- package/lib/browser/components/mention-input/mention-select.d.ts +28 -0
- package/lib/browser/components/mention-input/mention-select.d.ts.map +1 -0
- package/lib/browser/components/mention-input/mention-select.js +136 -0
- package/lib/browser/components/mention-input/mention-select.js.map +1 -0
- package/lib/browser/components/mention-input/mention-select.module.less +297 -0
- package/lib/browser/components/mention-input/types.d.ts +16 -1
- package/lib/browser/components/mention-input/types.d.ts.map +1 -1
- package/lib/browser/components/mention-input/types.js +1 -0
- package/lib/browser/components/mention-input/types.js.map +1 -1
- package/lib/browser/components/utils.d.ts +2 -2
- package/lib/browser/context/llm-context.service.d.ts +21 -2
- package/lib/browser/context/llm-context.service.d.ts.map +1 -1
- package/lib/browser/context/llm-context.service.js +162 -20
- package/lib/browser/context/llm-context.service.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/diff-computer.js +1 -1
- package/lib/browser/contrib/intelligent-completions/diff-computer.js.map +1 -1
- package/lib/browser/contrib/terminal/terminal.feature.registry.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +7 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +2 -2
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/getOpenEditorFileDiagnostics.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +1 -39
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +3 -170
- 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 +5 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/rules/rules.contribution.d.ts +29 -0
- package/lib/browser/rules/rules.contribution.d.ts.map +1 -0
- package/lib/browser/rules/rules.contribution.js +94 -0
- package/lib/browser/rules/rules.contribution.js.map +1 -0
- package/lib/browser/rules/rules.module.less +175 -0
- package/lib/browser/rules/rules.service.d.ts +25 -0
- package/lib/browser/rules/rules.service.d.ts.map +1 -0
- package/lib/browser/rules/rules.service.js +180 -0
- package/lib/browser/rules/rules.service.js.map +1 -0
- package/lib/browser/rules/rules.view.d.ts +3 -0
- package/lib/browser/rules/rules.view.d.ts.map +1 -0
- package/lib/browser/rules/rules.view.js +76 -0
- package/lib/browser/rules/rules.view.js.map +1 -0
- 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.map +1 -1
- package/lib/common/MDC_PARSER_README.md +171 -0
- package/lib/common/index.d.ts +2 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +2 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/llm-context.d.ts +19 -0
- package/lib/common/llm-context.d.ts.map +1 -1
- package/lib/common/llm-context.js.map +1 -1
- package/lib/common/mdc-parser.d.ts +60 -0
- package/lib/common/mdc-parser.d.ts.map +1 -0
- package/lib/common/mdc-parser.js +246 -0
- package/lib/common/mdc-parser.js.map +1 -0
- package/lib/common/model.d.ts +1 -0
- package/lib/common/model.d.ts.map +1 -1
- package/lib/common/model.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts +0 -2
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +35 -29
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/prompts/system-prompt.d.ts +2 -0
- package/lib/common/prompts/system-prompt.d.ts.map +1 -0
- package/lib/common/prompts/system-prompt.js +5 -0
- package/lib/common/prompts/system-prompt.js.map +1 -0
- package/lib/common/types.d.ts +7 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +2 -1
- package/lib/node/base-language-model.js.map +1 -1
- package/package.json +25 -24
- package/src/browser/chat/chat-manager.service.ts +6 -15
- package/src/browser/chat/chat-model.ts +19 -56
- package/src/browser/chat/chat-proxy.service.ts +68 -81
- package/src/browser/chat/chat.view.tsx +19 -7
- package/src/browser/components/ChatMentionInput.tsx +169 -35
- package/src/browser/components/ChatReply.tsx +4 -4
- package/src/browser/components/ChatToolRender.module.less +1 -0
- package/src/browser/components/components.module.less +37 -8
- package/src/browser/components/mention-input/mention-input.module.less +165 -1
- package/src/browser/components/mention-input/mention-input.tsx +257 -32
- package/src/browser/components/mention-input/mention-select.module.less +297 -0
- package/src/browser/components/mention-input/mention-select.tsx +256 -0
- package/src/browser/components/mention-input/types.ts +16 -0
- package/src/browser/context/llm-context.service.ts +182 -21
- package/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts +1 -1
- package/src/browser/contrib/intelligent-completions/diff-computer.ts +1 -1
- package/src/browser/contrib/terminal/terminal.feature.registry.ts +1 -1
- package/src/browser/index.ts +8 -0
- package/src/browser/mcp/base-apply.service.ts +0 -1
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -1
- package/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts +1 -1
- package/src/browser/mcp/tools/handlers/ListDir.ts +1 -1
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -1
- package/src/browser/model/msg-history-manager.ts +3 -230
- package/src/browser/preferences/schema.ts +5 -0
- package/src/browser/rules/rules.contribution.ts +105 -0
- package/src/browser/rules/rules.module.less +175 -0
- package/src/browser/rules/rules.service.ts +189 -0
- package/src/browser/rules/rules.view.tsx +127 -0
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +0 -1
- package/src/common/MDC_PARSER_README.md +171 -0
- package/src/common/index.ts +3 -0
- package/src/common/llm-context.ts +23 -0
- package/src/common/mdc-parser.ts +295 -0
- package/src/common/model.ts +1 -0
- package/src/common/prompts/context-prompt-provider.ts +55 -40
- package/src/common/prompts/system-prompt.ts +2 -0
- package/src/common/types.ts +8 -0
- package/src/node/base-language-model.ts +1 -2
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { Autowired, Injectable } from '@opensumi/di';
|
|
2
|
-
import {
|
|
2
|
+
import { PreferenceService } from '@opensumi/ide-core-browser';
|
|
3
3
|
import {
|
|
4
4
|
AIBackSerivcePath,
|
|
5
5
|
CancellationToken,
|
|
6
6
|
ChatAgentViewServiceToken,
|
|
7
7
|
ChatFeatureRegistryToken,
|
|
8
|
-
ChatServiceToken,
|
|
9
8
|
Deferred,
|
|
10
9
|
Disposable,
|
|
11
10
|
IAIBackService,
|
|
12
11
|
IAIReporter,
|
|
13
12
|
IApplicationService,
|
|
14
13
|
IChatProgress,
|
|
15
|
-
getOperatingSystemName,
|
|
16
14
|
} from '@opensumi/ide-core-common';
|
|
17
15
|
import { AINativeSettingSectionsId } from '@opensumi/ide-core-common/lib/settings/ai-native';
|
|
18
16
|
import { MonacoCommandRegistry } from '@opensumi/ide-editor/lib/browser/monaco-contrib/command/command.service';
|
|
@@ -27,10 +25,10 @@ import {
|
|
|
27
25
|
IChatAgentService,
|
|
28
26
|
IChatAgentWelcomeMessage,
|
|
29
27
|
} from '../../common';
|
|
28
|
+
import { DEFAULT_SYSTEM_PROMPT } from '../../common/prompts/system-prompt';
|
|
30
29
|
import { ChatToolRender } from '../components/ChatToolRender';
|
|
31
30
|
import { IChatAgentViewService } from '../types';
|
|
32
31
|
|
|
33
|
-
import { ChatService } from './chat.api.service';
|
|
34
32
|
import { ChatFeatureRegistry } from './chat.feature.registry';
|
|
35
33
|
|
|
36
34
|
/**
|
|
@@ -53,9 +51,6 @@ export class ChatProxyService extends Disposable {
|
|
|
53
51
|
@Autowired(MonacoCommandRegistry)
|
|
54
52
|
private readonly monacoCommandRegistry: MonacoCommandRegistry;
|
|
55
53
|
|
|
56
|
-
@Autowired(ChatServiceToken)
|
|
57
|
-
private aiChatService: ChatService;
|
|
58
|
-
|
|
59
54
|
@Autowired(IAIReporter)
|
|
60
55
|
private readonly aiReporter: IAIReporter;
|
|
61
56
|
|
|
@@ -71,9 +66,6 @@ export class ChatProxyService extends Disposable {
|
|
|
71
66
|
@Autowired(IMessageService)
|
|
72
67
|
private readonly messageService: IMessageService;
|
|
73
68
|
|
|
74
|
-
@Autowired(AppConfig)
|
|
75
|
-
private readonly appConfig: AppConfig;
|
|
76
|
-
|
|
77
69
|
private chatDeferred: Deferred<void> = new Deferred<void>();
|
|
78
70
|
|
|
79
71
|
public getRequestOptions() {
|
|
@@ -112,79 +104,74 @@ export class ChatProxyService extends Disposable {
|
|
|
112
104
|
initialProps: {},
|
|
113
105
|
});
|
|
114
106
|
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.preferenceService.get<string>(
|
|
107
|
+
this.applicationService.getBackendOS().then(() => {
|
|
108
|
+
this.addDispose(
|
|
109
|
+
this.chatAgentService.registerAgent({
|
|
110
|
+
id: ChatProxyService.AGENT_ID,
|
|
111
|
+
metadata: {
|
|
112
|
+
systemPrompt: this.preferenceService.get<string>(
|
|
121
113
|
AINativeSettingSectionsId.SystemPrompt,
|
|
122
|
-
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (commandHandler && commandHandler.providerPrompt) {
|
|
142
|
-
const editor = this.monacoCommandRegistry.getActiveCodeEditor();
|
|
143
|
-
const slashCommandPrompt = await commandHandler.providerPrompt(message, editor);
|
|
144
|
-
prompt = slashCommandPrompt;
|
|
114
|
+
DEFAULT_SYSTEM_PROMPT,
|
|
115
|
+
),
|
|
116
|
+
},
|
|
117
|
+
invoke: async (
|
|
118
|
+
request: IChatAgentRequest,
|
|
119
|
+
progress: (part: IChatProgress) => void,
|
|
120
|
+
history: CoreMessage[],
|
|
121
|
+
token: CancellationToken,
|
|
122
|
+
): Promise<IChatAgentResult> => {
|
|
123
|
+
this.chatDeferred = new Deferred<void>();
|
|
124
|
+
const { message, command } = request;
|
|
125
|
+
let prompt: string = message;
|
|
126
|
+
if (command) {
|
|
127
|
+
const commandHandler = this.chatFeatureRegistry.getSlashCommandHandler(command);
|
|
128
|
+
if (commandHandler && commandHandler.providerPrompt) {
|
|
129
|
+
const editor = this.monacoCommandRegistry.getActiveCodeEditor();
|
|
130
|
+
const slashCommandPrompt = await commandHandler.providerPrompt(message, editor);
|
|
131
|
+
prompt = slashCommandPrompt;
|
|
132
|
+
}
|
|
145
133
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
);
|
|
134
|
+
|
|
135
|
+
const stream = await this.aiBackService.requestStream(
|
|
136
|
+
prompt,
|
|
137
|
+
{
|
|
138
|
+
requestId: request.requestId,
|
|
139
|
+
sessionId: request.sessionId,
|
|
140
|
+
history,
|
|
141
|
+
images: request.images,
|
|
142
|
+
...this.getRequestOptions(),
|
|
143
|
+
},
|
|
144
|
+
token,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
listenReadable<IChatProgress>(stream, {
|
|
148
|
+
onData: (data) => {
|
|
149
|
+
progress(data);
|
|
150
|
+
},
|
|
151
|
+
onEnd: () => {
|
|
152
|
+
this.chatDeferred.resolve();
|
|
153
|
+
},
|
|
154
|
+
onError: (error) => {
|
|
155
|
+
this.messageService.error(error.message);
|
|
156
|
+
this.aiReporter.end(request.sessionId + '_' + request.requestId, {
|
|
157
|
+
message: error.message,
|
|
158
|
+
success: false,
|
|
159
|
+
command,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
await this.chatDeferred.promise;
|
|
165
|
+
return {};
|
|
166
|
+
},
|
|
167
|
+
provideSlashCommands: async (): Promise<IChatAgentCommand[]> =>
|
|
168
|
+
this.chatFeatureRegistry
|
|
169
|
+
.getAllSlashCommand()
|
|
170
|
+
.map((s) => ({ ...s, name: s.name, description: s.description || '' })),
|
|
171
|
+
provideChatWelcomeMessage: async (): Promise<IChatAgentWelcomeMessage | undefined> => undefined,
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
174
|
+
});
|
|
188
175
|
|
|
189
176
|
queueMicrotask(() => {
|
|
190
177
|
this.chatAgentService.updateAgent(ChatProxyService.AGENT_ID, {});
|
|
@@ -617,7 +617,12 @@ export const AIChatView = () => {
|
|
|
617
617
|
const { message, images, agentId, command, reportExtra } = value;
|
|
618
618
|
const { actionType, actionSource } = reportExtra || {};
|
|
619
619
|
|
|
620
|
-
const request = aiChatService.createRequest(
|
|
620
|
+
const request = aiChatService.createRequest(
|
|
621
|
+
message.replaceAll(LLM_CONTEXT_KEY_REGEX, ''),
|
|
622
|
+
agentId!,
|
|
623
|
+
images,
|
|
624
|
+
command,
|
|
625
|
+
);
|
|
621
626
|
if (!request) {
|
|
622
627
|
return;
|
|
623
628
|
}
|
|
@@ -641,7 +646,7 @@ export const AIChatView = () => {
|
|
|
641
646
|
600 * 1000,
|
|
642
647
|
);
|
|
643
648
|
msgHistoryManager.addUserMessage({
|
|
644
|
-
content: message
|
|
649
|
+
content: message,
|
|
645
650
|
images: images || [],
|
|
646
651
|
agentId: agentId!,
|
|
647
652
|
agentCommand: command!,
|
|
@@ -695,14 +700,9 @@ export const AIChatView = () => {
|
|
|
695
700
|
let processedContent = message;
|
|
696
701
|
const filePattern = /\{\{@file:(.*?)\}\}/g;
|
|
697
702
|
const fileMatches = message.match(filePattern);
|
|
698
|
-
let isCleanContext = false;
|
|
699
703
|
if (fileMatches) {
|
|
700
704
|
for (const match of fileMatches) {
|
|
701
705
|
const filePath = match.replace(/\{\{@file:(.*?)\}\}/, '$1');
|
|
702
|
-
if (filePath && !isCleanContext) {
|
|
703
|
-
isCleanContext = true;
|
|
704
|
-
llmContextService.cleanFileContext();
|
|
705
|
-
}
|
|
706
706
|
const fileUri = new URI(filePath);
|
|
707
707
|
const relativePath = (await workspaceService.asRelativePath(fileUri))?.path || fileUri.displayName;
|
|
708
708
|
processedContent = processedContent.replace(match, `\`${LLM_CONTEXT_KEY.AttachedFile}${relativePath}\``);
|
|
@@ -738,6 +738,18 @@ export const AIChatView = () => {
|
|
|
738
738
|
);
|
|
739
739
|
}
|
|
740
740
|
}
|
|
741
|
+
const rulePattern = /\{\{@rule:(.*?)\}\}/g;
|
|
742
|
+
const ruleMatches = processedContent.match(rulePattern);
|
|
743
|
+
if (ruleMatches) {
|
|
744
|
+
for (const match of ruleMatches) {
|
|
745
|
+
const ruleName = match.replace(/\{\{@rule:(.*?)\}\}/, '$1');
|
|
746
|
+
const ruleUri = new URI(ruleName);
|
|
747
|
+
processedContent = processedContent.replace(
|
|
748
|
+
match,
|
|
749
|
+
`\`${LLM_CONTEXT_KEY.AttachedFile}${ruleUri.displayName}\``,
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
741
753
|
return handleAgentReply({ message: processedContent, images, agentId, command, reportExtra });
|
|
742
754
|
},
|
|
743
755
|
[handleAgentReply],
|
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
useInjectable,
|
|
11
11
|
} from '@opensumi/ide-core-browser';
|
|
12
12
|
import { Icon, getIcon } from '@opensumi/ide-core-browser/lib/components';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
AINativeSettingSectionsId,
|
|
15
|
+
ChatFeatureRegistryToken,
|
|
16
|
+
RulesServiceToken,
|
|
17
|
+
URI,
|
|
18
|
+
localize,
|
|
19
|
+
} from '@opensumi/ide-core-common';
|
|
14
20
|
import { CommandService } from '@opensumi/ide-core-common/lib/command';
|
|
15
21
|
import { defaultFilesWatcherExcludes } from '@opensumi/ide-core-common/lib/preferences/file-watch';
|
|
16
22
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
@@ -18,6 +24,8 @@ import { FileSearchServicePath, IFileSearchService } from '@opensumi/ide-file-se
|
|
|
18
24
|
import { OutlineCompositeTreeNode, OutlineTreeNode } from '@opensumi/ide-outline/lib/browser/outline-node.define';
|
|
19
25
|
import { OutlineTreeService } from '@opensumi/ide-outline/lib/browser/services/outline-tree.service';
|
|
20
26
|
import { IMessageService } from '@opensumi/ide-overlay';
|
|
27
|
+
import { IconType } from '@opensumi/ide-theme';
|
|
28
|
+
import { IconService } from '@opensumi/ide-theme/lib/browser';
|
|
21
29
|
import { IWorkspaceService } from '@opensumi/ide-workspace';
|
|
22
30
|
|
|
23
31
|
import { IChatInternalService } from '../../common';
|
|
@@ -25,6 +33,8 @@ import { LLMContextService } from '../../common/llm-context';
|
|
|
25
33
|
import { ChatFeatureRegistry } from '../chat/chat.feature.registry';
|
|
26
34
|
import { ChatInternalService } from '../chat/chat.internal.service';
|
|
27
35
|
import { MCPConfigCommands } from '../mcp/config/mcp-config.commands';
|
|
36
|
+
import { RulesCommands } from '../rules/rules.contribution';
|
|
37
|
+
import { RulesService } from '../rules/rules.service';
|
|
28
38
|
|
|
29
39
|
import styles from './components.module.less';
|
|
30
40
|
import { MentionInput } from './mention-input/mention-input';
|
|
@@ -72,15 +82,21 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
72
82
|
const workspaceService = useInjectable<IWorkspaceService>(IWorkspaceService);
|
|
73
83
|
const editorService = useInjectable<WorkbenchEditorService>(WorkbenchEditorService);
|
|
74
84
|
const labelService = useInjectable<LabelService>(LabelService);
|
|
85
|
+
const iconService = useInjectable<IconService>(IconService);
|
|
75
86
|
const messageService = useInjectable<IMessageService>(IMessageService);
|
|
76
87
|
const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
|
|
77
88
|
const outlineTreeService = useInjectable<OutlineTreeService>(OutlineTreeService);
|
|
78
89
|
const prevOutlineItems = useRef<MentionItem[]>([]);
|
|
79
90
|
const preferenceService = useInjectable<PreferenceService>(PreferenceService);
|
|
91
|
+
const rulesService = useInjectable<RulesService>(RulesServiceToken);
|
|
80
92
|
const handleShowMCPConfig = React.useCallback(() => {
|
|
81
93
|
commandService.executeCommand(MCPConfigCommands.OPEN_MCP_CONFIG.id);
|
|
82
94
|
}, [commandService]);
|
|
83
95
|
|
|
96
|
+
const handleShowRules = React.useCallback(() => {
|
|
97
|
+
commandService.executeCommand(RulesCommands.OPEN_RULES_FILE.id);
|
|
98
|
+
}, [commandService]);
|
|
99
|
+
|
|
84
100
|
useEffect(() => {
|
|
85
101
|
if (props.value !== value) {
|
|
86
102
|
setValue(props.value || '');
|
|
@@ -107,6 +123,55 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
107
123
|
[outlineTreeService],
|
|
108
124
|
);
|
|
109
125
|
|
|
126
|
+
// 拆分目录路径为多个层级的辅助函数
|
|
127
|
+
const expandFolderPaths = async (folderPaths: string[], workspaceRootPath: string): Promise<MentionItem[]> => {
|
|
128
|
+
const expandedPaths = new Set<string>();
|
|
129
|
+
const workspaceUri = new URI(workspaceRootPath);
|
|
130
|
+
|
|
131
|
+
// 将所有路径展开为多层级
|
|
132
|
+
for (const folderPath of folderPaths) {
|
|
133
|
+
const uri = new URI(folderPath);
|
|
134
|
+
const relativePath = await workspaceService.asRelativePath(uri);
|
|
135
|
+
|
|
136
|
+
if (relativePath?.path) {
|
|
137
|
+
const pathSegments = relativePath.path.split('/').filter(Boolean);
|
|
138
|
+
|
|
139
|
+
// 为每个层级创建路径
|
|
140
|
+
for (let i = 0; i < pathSegments.length; i++) {
|
|
141
|
+
const segmentPath = pathSegments.slice(0, i + 1).join('/');
|
|
142
|
+
const fullPath = workspaceUri.resolve(segmentPath).codeUri.fsPath;
|
|
143
|
+
|
|
144
|
+
// 避免添加工作区本身或其上级目录
|
|
145
|
+
if (fullPath !== workspaceRootPath && !workspaceRootPath.startsWith(fullPath)) {
|
|
146
|
+
expandedPaths.add(fullPath);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
// 如果无法获取相对路径,直接添加(但仍要过滤工作区路径)
|
|
151
|
+
if (folderPath !== workspaceRootPath && !workspaceRootPath.startsWith(folderPath)) {
|
|
152
|
+
expandedPaths.add(folderPath);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 转换为 MentionItem 格式
|
|
158
|
+
return Promise.all(
|
|
159
|
+
Array.from(expandedPaths).map(async (folderPath) => {
|
|
160
|
+
const uri = new URI(folderPath);
|
|
161
|
+
const relativePath = await workspaceService.asRelativePath(uri);
|
|
162
|
+
return {
|
|
163
|
+
id: uri.codeUri.fsPath,
|
|
164
|
+
type: MentionType.FOLDER,
|
|
165
|
+
text: uri.displayName,
|
|
166
|
+
value: uri.codeUri.fsPath,
|
|
167
|
+
description: relativePath?.root ? relativePath.path : '',
|
|
168
|
+
contextId: uri.codeUri.fsPath,
|
|
169
|
+
icon: getIcon('folder'),
|
|
170
|
+
};
|
|
171
|
+
}),
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
|
|
110
175
|
// 默认菜单项
|
|
111
176
|
const defaultMenuItems: MentionItem[] = [
|
|
112
177
|
{
|
|
@@ -214,21 +279,7 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
214
279
|
.filter((folder) => folder !== workspaceService.workspace?.uri.toString() && folder !== '/'),
|
|
215
280
|
),
|
|
216
281
|
);
|
|
217
|
-
folders = await
|
|
218
|
-
recentFolder.map(async (folder) => {
|
|
219
|
-
const uri = new URI(folder);
|
|
220
|
-
const relativePath = await workspaceService.asRelativePath(uri);
|
|
221
|
-
return {
|
|
222
|
-
id: uri.codeUri.fsPath,
|
|
223
|
-
type: MentionType.FOLDER,
|
|
224
|
-
text: uri.displayName,
|
|
225
|
-
value: uri.codeUri.fsPath,
|
|
226
|
-
description: relativePath?.root ? relativePath.path : '',
|
|
227
|
-
contextId: uri.codeUri.fsPath,
|
|
228
|
-
icon: getIcon('folder'),
|
|
229
|
-
};
|
|
230
|
-
}),
|
|
231
|
-
);
|
|
282
|
+
folders = await expandFolderPaths(recentFolder, workspaceService.workspace?.uri.toString() || '');
|
|
232
283
|
} else {
|
|
233
284
|
const rootUris = (await workspaceService.roots).map((root) => new URI(root.uri).codeUri.fsPath.toString());
|
|
234
285
|
const files = await searchService.find(searchText, {
|
|
@@ -246,22 +297,11 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
246
297
|
.filter((folder) => folder !== workspaceService.workspace?.uri.toString()),
|
|
247
298
|
),
|
|
248
299
|
);
|
|
249
|
-
return
|
|
250
|
-
folders.map(async (folder) => {
|
|
251
|
-
const uri = new URI(folder);
|
|
252
|
-
return {
|
|
253
|
-
id: uri.codeUri.fsPath,
|
|
254
|
-
type: MentionType.FOLDER,
|
|
255
|
-
text: uri.displayName,
|
|
256
|
-
value: uri.codeUri.fsPath,
|
|
257
|
-
description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
|
|
258
|
-
contextId: uri.codeUri.fsPath,
|
|
259
|
-
icon: getIcon('folder'),
|
|
260
|
-
};
|
|
261
|
-
}),
|
|
262
|
-
);
|
|
300
|
+
return await expandFolderPaths(folders, workspaceService.workspace?.uri.toString() || '');
|
|
263
301
|
}
|
|
264
|
-
return folders
|
|
302
|
+
return folders
|
|
303
|
+
.filter(Boolean)
|
|
304
|
+
.filter((folder) => folder.id !== new URI(workspaceService.workspace?.uri).codeUri.fsPath);
|
|
265
305
|
},
|
|
266
306
|
},
|
|
267
307
|
{
|
|
@@ -312,13 +352,100 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
312
352
|
}
|
|
313
353
|
},
|
|
314
354
|
},
|
|
315
|
-
|
|
355
|
+
{
|
|
356
|
+
id: MentionType.RULE,
|
|
357
|
+
type: MentionType.RULE,
|
|
358
|
+
text: 'Rule',
|
|
359
|
+
icon: getIcon('rules'),
|
|
360
|
+
getHighestLevelItems: () => [],
|
|
361
|
+
getItems: async (searchText: string) => {
|
|
362
|
+
const rules = await rulesService.projectRules;
|
|
363
|
+
const mappedRules = rules.map((rule) => {
|
|
364
|
+
const uri = new URI(rule.path);
|
|
365
|
+
return {
|
|
366
|
+
id: uri.codeUri.fsPath,
|
|
367
|
+
type: MentionType.RULE,
|
|
368
|
+
text: uri.displayName,
|
|
369
|
+
value: uri.codeUri.fsPath,
|
|
370
|
+
contextId: uri.codeUri.fsPath,
|
|
371
|
+
description: rule.description,
|
|
372
|
+
icon: getIcon('rules'),
|
|
373
|
+
};
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
if (!searchText) {
|
|
377
|
+
return mappedRules.slice(0, 10);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const lowerSearchText = searchText.toLocaleLowerCase();
|
|
381
|
+
return mappedRules
|
|
382
|
+
.filter((rule) => rule.text.toLocaleLowerCase().includes(lowerSearchText))
|
|
383
|
+
.sort((a, b) => {
|
|
384
|
+
const aTextLower = a.text.toLocaleLowerCase();
|
|
385
|
+
const bTextLower = b.text.toLocaleLowerCase();
|
|
386
|
+
const aDescLower = a.description?.toLocaleLowerCase() || '';
|
|
387
|
+
const bDescLower = b.description?.toLocaleLowerCase() || '';
|
|
316
388
|
|
|
389
|
+
// 优先级:文件名包含搜索文本 > 描述包含搜索文本
|
|
390
|
+
const aTextMatch = aTextLower.includes(lowerSearchText);
|
|
391
|
+
const bTextMatch = bTextLower.includes(lowerSearchText);
|
|
392
|
+
const aDescMatch = aDescLower.includes(lowerSearchText);
|
|
393
|
+
const bDescMatch = bDescLower.includes(lowerSearchText);
|
|
394
|
+
|
|
395
|
+
if (aTextMatch && bTextMatch) {
|
|
396
|
+
// 如果都匹配文件名,按文件名字母序排序
|
|
397
|
+
return aTextLower.localeCompare(bTextLower);
|
|
398
|
+
}
|
|
399
|
+
if (aTextMatch && !bTextMatch) {
|
|
400
|
+
return -1;
|
|
401
|
+
}
|
|
402
|
+
if (!aTextMatch && bTextMatch) {
|
|
403
|
+
return 1;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// 如果文件名都不匹配,比较描述
|
|
407
|
+
if (aDescMatch && bDescMatch) {
|
|
408
|
+
return aTextLower.localeCompare(bTextLower);
|
|
409
|
+
}
|
|
410
|
+
if (aDescMatch && !bDescMatch) {
|
|
411
|
+
return -1;
|
|
412
|
+
}
|
|
413
|
+
if (!aDescMatch && bDescMatch) {
|
|
414
|
+
return 1;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// 如果都不匹配,按文件名字母序排序
|
|
418
|
+
return aTextLower.localeCompare(bTextLower);
|
|
419
|
+
})
|
|
420
|
+
.slice(0, 10);
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
];
|
|
317
424
|
const defaultMentionInputFooterOptions: FooterConfig = useMemo(
|
|
318
425
|
() => ({
|
|
319
426
|
modelOptions: [
|
|
320
|
-
{
|
|
321
|
-
|
|
427
|
+
{
|
|
428
|
+
label: 'Claude 4 Sonnet',
|
|
429
|
+
value: 'claude_sonnet4',
|
|
430
|
+
iconClass: iconService.fromIcon(
|
|
431
|
+
'',
|
|
432
|
+
'https://img.alicdn.com/imgextra/i3/O1CN01p0mziz1Nsl40lp1HO_!!6000000001626-55-tps-92-65.svg',
|
|
433
|
+
IconType.Background,
|
|
434
|
+
),
|
|
435
|
+
tags: ['多模态', '长上下文理解', '思考模式'],
|
|
436
|
+
description: '高性能模型,支持多模态输入',
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
label: 'DeepSeek R1',
|
|
440
|
+
value: 'DeepSeek-R1-0528',
|
|
441
|
+
iconClass: iconService.fromIcon(
|
|
442
|
+
'',
|
|
443
|
+
'https://img.alicdn.com/imgextra/i3/O1CN01ClcK2w1JwdxcbAB3a_!!6000000001093-55-tps-30-30.svg',
|
|
444
|
+
IconType.Background,
|
|
445
|
+
),
|
|
446
|
+
tags: ['思考模式', '长上下文理解'],
|
|
447
|
+
description: '专业创作,支持多模态输入',
|
|
448
|
+
},
|
|
322
449
|
],
|
|
323
450
|
defaultModel:
|
|
324
451
|
props.sessionModelId || preferenceService.get<string>(AINativeSettingSectionsId.ModelID) || 'deepseek-r1',
|
|
@@ -330,6 +457,13 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
330
457
|
onClick: handleShowMCPConfig,
|
|
331
458
|
position: FooterButtonPosition.LEFT,
|
|
332
459
|
},
|
|
460
|
+
{
|
|
461
|
+
id: 'rules',
|
|
462
|
+
icon: 'rules',
|
|
463
|
+
title: 'Rules',
|
|
464
|
+
onClick: handleShowRules,
|
|
465
|
+
position: FooterButtonPosition.LEFT,
|
|
466
|
+
},
|
|
333
467
|
{
|
|
334
468
|
id: 'upload-image',
|
|
335
469
|
icon: 'image',
|
|
@@ -352,7 +486,7 @@ export const ChatMentionInput = (props: IChatMentionInputProps) => {
|
|
|
352
486
|
showModelSelector: true,
|
|
353
487
|
disableModelSelector: props.disableModelSelector,
|
|
354
488
|
}),
|
|
355
|
-
[handleShowMCPConfig, props.disableModelSelector, props.sessionModelId],
|
|
489
|
+
[iconService, handleShowMCPConfig, handleShowRules, props.disableModelSelector, props.sessionModelId],
|
|
356
490
|
);
|
|
357
491
|
|
|
358
492
|
const handleStop = useCallback(() => {
|
|
@@ -342,10 +342,10 @@ export const ChatReply = (props: IChatReplyProps) => {
|
|
|
342
342
|
}}
|
|
343
343
|
>
|
|
344
344
|
<Icon iconClass='codicon codicon-sparkle' />
|
|
345
|
-
{
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
345
|
+
<span style={{ marginLeft: 4 }} className={isThinking ? styles.shiny_text : ''}>
|
|
346
|
+
{localize('aiNative.chat.thinking')}
|
|
347
|
+
</span>
|
|
348
|
+
{isThinking ? null : collapseThinkingIndexSet.has(index) ? (
|
|
349
349
|
<Icon iconClass='codicon codicon-chevron-right' />
|
|
350
350
|
) : (
|
|
351
351
|
<Icon iconClass='codicon codicon-chevron-down' />
|
|
@@ -524,7 +524,6 @@
|
|
|
524
524
|
display: flex;
|
|
525
525
|
font-size: 11px;
|
|
526
526
|
align-items: center;
|
|
527
|
-
min-width: 150px;
|
|
528
527
|
}
|
|
529
528
|
|
|
530
529
|
.mcp_desc {
|
|
@@ -585,7 +584,6 @@
|
|
|
585
584
|
.reasoning_content {
|
|
586
585
|
padding: 8px 12px;
|
|
587
586
|
margin-top: 4px;
|
|
588
|
-
border-left: 2px solid var(--descriptionForeground);
|
|
589
587
|
color: var(--descriptionForeground);
|
|
590
588
|
background: var(--design-block-background);
|
|
591
589
|
border-radius: 4px;
|
|
@@ -597,8 +595,8 @@
|
|
|
597
595
|
align-items: center;
|
|
598
596
|
padding: 0 4px;
|
|
599
597
|
margin: 0 2px;
|
|
600
|
-
background: var(--
|
|
601
|
-
color: var(--
|
|
598
|
+
background-color: var(--chat-slashCommandBackground);
|
|
599
|
+
color: var(--chat-slashCommandForeground);
|
|
602
600
|
border-radius: 3px;
|
|
603
601
|
vertical-align: middle;
|
|
604
602
|
font-size: 12px;
|
|
@@ -609,10 +607,6 @@
|
|
|
609
607
|
margin-right: 3px;
|
|
610
608
|
}
|
|
611
609
|
}
|
|
612
|
-
&:hover {
|
|
613
|
-
background-color: var(--chat-slashCommandBackground);
|
|
614
|
-
color: var(--chat-slashCommandForeground);
|
|
615
|
-
}
|
|
616
610
|
}
|
|
617
611
|
|
|
618
612
|
.attachment_text {
|
|
@@ -620,6 +614,13 @@
|
|
|
620
614
|
vertical-align: middle;
|
|
621
615
|
font-size: 12px;
|
|
622
616
|
word-break: break-all;
|
|
617
|
+
max-width: 100px;
|
|
618
|
+
text-overflow: ellipsis;
|
|
619
|
+
direction: rtl;
|
|
620
|
+
unicode-bidi: plaintext;
|
|
621
|
+
overflow: hidden;
|
|
622
|
+
white-space: nowrap;
|
|
623
|
+
display: inline-block;
|
|
623
624
|
}
|
|
624
625
|
|
|
625
626
|
.thumbnail_container {
|
|
@@ -672,3 +673,31 @@
|
|
|
672
673
|
border-radius: 3px;
|
|
673
674
|
overflow: hidden;
|
|
674
675
|
}
|
|
676
|
+
|
|
677
|
+
.shiny_text {
|
|
678
|
+
color: #b5b5b5a4; /* Adjust this color to change intensity/style */
|
|
679
|
+
background: linear-gradient(
|
|
680
|
+
120deg,
|
|
681
|
+
rgba(255, 255, 255, 0) 40%,
|
|
682
|
+
rgba(255, 255, 255, 0.8) 50%,
|
|
683
|
+
rgba(255, 255, 255, 0) 60%
|
|
684
|
+
);
|
|
685
|
+
background-size: 200% 100%;
|
|
686
|
+
-webkit-background-clip: text;
|
|
687
|
+
background-clip: text;
|
|
688
|
+
display: inline-block;
|
|
689
|
+
animation: shine 5s linear infinite;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
@keyframes shine {
|
|
693
|
+
0% {
|
|
694
|
+
background-position: 100%;
|
|
695
|
+
}
|
|
696
|
+
100% {
|
|
697
|
+
background-position: -100%;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.shiny_text.disabled {
|
|
702
|
+
animation: none;
|
|
703
|
+
}
|