Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 26ad68b

Browse files
erha19ensorrow
andauthored
feat: improve LLM context service enhance logic (#4527)
* fix: llm context service enhance * chore: remove current file context when has referenced * chore: improve file context * feat: add model change restriction and tooltip style update * fix: update model switch tip for ongoing sessions * refactor: remove unused Tooltip import and CSS rule * refactor: update model selector tooltip text * chore: fix clear file from context * chore: fix attach file content * chore: update tips * fix: progress view id * chore: update mcp config * chore: remove useless code * chore: update model position * chore: use NODE_BINARY_PATH command * chore: fix update logic --------- Co-authored-by: ensorrow <[email protected]>
1 parent a693495 commit 26ad68b

File tree

13 files changed

+80
-43
lines changed

13 files changed

+80
-43
lines changed

packages/ai-native/src/browser/components/mention-input/mention-input.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,24 @@ export const MentionInput: React.FC<MentionInputProps> = ({
10191019
[attachedFiles],
10201020
);
10211021

1022+
const renderModelSelectorTip = React.useCallback(
1023+
(children: React.ReactNode) => {
1024+
if (footerConfig.disableModelSelector) {
1025+
return (
1026+
<Popover
1027+
id='ai-chat-model-selector'
1028+
title={localize('aiNative.chat.modelSelector.disableTip')}
1029+
position={PopoverPosition.top}
1030+
>
1031+
{children}
1032+
</Popover>
1033+
);
1034+
}
1035+
return children;
1036+
},
1037+
[footerConfig.disableModelSelector],
1038+
);
1039+
10221040
return (
10231041
<div className={styles.input_container}>
10241042
{mentionState.active && (
@@ -1048,16 +1066,17 @@ export const MentionInput: React.FC<MentionInputProps> = ({
10481066
</div>
10491067
<div className={styles.footer}>
10501068
<div className={styles.left_control}>
1051-
{footerConfig.showModelSelector && (
1052-
<Select
1053-
options={footerConfig.modelOptions || []}
1054-
value={selectedModel}
1055-
onChange={handleModelChange}
1056-
className={styles.model_selector}
1057-
size='small'
1058-
disabled={footerConfig.disableModelSelector}
1059-
/>
1060-
)}
1069+
{footerConfig.showModelSelector &&
1070+
renderModelSelectorTip(
1071+
<Select
1072+
options={footerConfig.modelOptions || []}
1073+
value={selectedModel}
1074+
onChange={handleModelChange}
1075+
className={styles.model_selector}
1076+
size='small'
1077+
disabled={footerConfig.disableModelSelector}
1078+
/>,
1079+
)}
10611080
{renderButtons(FooterButtonPosition.LEFT)}
10621081
</div>
10631082
<div className={styles.right_control}>

packages/ai-native/src/browser/context/llm-context.service.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,16 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
4848
attachedFolders: FileContext[];
4949
version: number;
5050
}>();
51+
private hasUserManualReference = false;
5152
onDidContextFilesChangeEvent = this.onDidContextFilesChangeEmitter.event;
5253

5354
private addFileToList(file: FileContext, list: FileContext[], maxLimit: number) {
54-
const existingIndex = list.findIndex((f) => f.uri.toString() === file.uri.toString());
55+
const existingIndex = list.findIndex(
56+
(f) =>
57+
f.uri.toString() === file.uri.toString() &&
58+
f.selection?.[0] === file.selection?.[0] &&
59+
f.selection?.[1] === file.selection?.[1],
60+
);
5561
if (existingIndex > -1) {
5662
list.splice(existingIndex, 1);
5763
}
@@ -85,6 +91,7 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
8591

8692
if (isManual) {
8793
this.docModelManager.createModelReference(uri);
94+
this.hasUserManualReference = true;
8895
}
8996

9097
this.addFileToList(file, targetList, maxLimit);
@@ -109,6 +116,7 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
109116
cleanFileContext() {
110117
this.attachedFiles = [];
111118
this.attachedFolders = [];
119+
this.hasUserManualReference = false;
112120
this.notifyContextChange();
113121
}
114122

@@ -127,6 +135,11 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
127135
if (index > -1) {
128136
targetList.splice(index, 1);
129137
}
138+
if (isManual) {
139+
if (this.attachedFiles.length === 0) {
140+
this.hasUserManualReference = false;
141+
}
142+
}
130143
this.notifyContextChange();
131144
}
132145

@@ -176,14 +189,17 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
176189
event.payload.selections[0].positionLineNumber,
177190
].sort() as [number, number];
178191

179-
if (selection[0] === selection[1]) {
180-
this.addFileToContext(event.payload.editorUri, undefined, false);
181-
} else {
182-
this.addFileToContext(
183-
event.payload.editorUri,
184-
selection.sort((a, b) => a - b),
185-
false,
186-
);
192+
if (!this.hasUserManualReference) {
193+
// 当没有用户手动引用时,才自动收集
194+
if (selection[0] === selection[1]) {
195+
this.addFileToContext(event.payload.editorUri, undefined, false);
196+
} else {
197+
this.addFileToContext(
198+
event.payload.editorUri,
199+
selection.sort((a, b) => a - b),
200+
false,
201+
);
202+
}
187203
}
188204
}
189205
}),
@@ -275,9 +291,7 @@ export class LLMContextServiceImpl extends WithEventBus implements LLMContextSer
275291
}
276292

277293
return {
278-
content: ref.instance.getText(
279-
file.selection && new Range(file.selection[0], Infinity, file.selection[1], Infinity),
280-
),
294+
content: ref.instance.getText(file.selection && new Range(file.selection[0], 0, file.selection[1], Infinity)),
281295
lineErrors: this.getFileErrors(file.uri),
282296
path: workspaceRoot.relative(file.uri)!.toString(),
283297
language: ref.instance.languageId!,

packages/ai-native/src/browser/mcp/config/mcp-config.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,14 @@ export class MCPConfigService extends Disposable {
201201
delete servers[prev.name];
202202
}
203203
servers[data.name] = serverConfig;
204-
await this.sumiMCPServerBackendProxy.$addOrUpdateServer(data as MCPServerDescription);
205204
// 更新情况下,如果原有服务是启用状态,则进行如下操作:
206205
// 1. 关闭旧的服务
207206
// 2. 启动新的服务
207+
await this.preferenceService.set('mcp', { mcpServers: servers });
208208
if (prev?.enabled) {
209-
await this.sumiMCPServerBackendProxy.$removeServer(prev.name);
209+
this.sumiMCPServerBackendProxy.$removeServer(prev.name);
210210
}
211-
await this.preferenceService.set('mcp', { mcpServers: servers });
211+
this.sumiMCPServerBackendProxy.$addOrUpdateServer(data as MCPServerDescription);
212212
}
213213

214214
async deleteServer(serverName: string): Promise<void> {

packages/ai-native/src/browser/mcp/mcp-preferences-contribution.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Autowired, Injectable } from '@opensumi/di';
22
import {
3-
CodeSchemaId,
43
Domain,
5-
IJSONSchema,
64
IJSONSchemaRegistry,
75
JsonSchemaContribution,
86
MaybePromise,

packages/ai-native/src/common/prompts/context-prompt-provider.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ export class DefaultChatAgentPromptProvider implements ChatAgentPromptProvider {
2323
protected readonly workspaceService: IWorkspaceService;
2424

2525
async provideContextPrompt(context: SerializedContext, userMessage: string) {
26-
const currentFileInfo = await this.getCurrentFileInfo();
26+
const currentFileInfo =
27+
context.attachedFiles.length > 0 || context.attachedFolders.length > 0 ? null : await this.getCurrentFileInfo();
2728

2829
return this.buildPromptTemplate({
2930
recentFiles: this.buildRecentFilesSection(context.recentlyViewFiles),
30-
attachedFiles: this.buildAttachedFilesSection(context.attachedFiles, context.recentlyViewFiles),
31+
attachedFiles: this.buildAttachedFilesSection(context.attachedFiles),
3132
attachedFolders: this.buildAttachedFoldersSection(context.attachedFolders),
3233
currentFile: currentFileInfo,
3334
userMessage,
@@ -91,11 +92,7 @@ ${files.map((file, idx) => ` ${idx + 1}: ${file}`).join('\n')}
9192
</recently_viewed_files>`;
9293
}
9394

94-
private buildAttachedFilesSection(
95-
files: { path: string; content: string; lineErrors: string[] }[],
96-
recentlyViewFiles: string[],
97-
): string {
98-
files = files.filter((file) => !recentlyViewFiles.includes(file.path));
95+
private buildAttachedFilesSection(files: { path: string; content: string; lineErrors: string[] }[]): string {
9996
if (!files.length) {
10097
return '';
10198
}

packages/ai-native/src/node/mcp-server.stdio.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class StdioMCPServer implements IMCPServer {
2424
private readonly logger?: ILogger,
2525
) {
2626
this.name = name;
27-
this.command = command;
27+
this.command = command === 'node' ? process.env.NODE_BINARY_PATH || 'node' : command;
2828
this.args = args;
2929
this.env = env;
3030
}
@@ -132,7 +132,7 @@ export class StdioMCPServer implements IMCPServer {
132132
}
133133

134134
update(command: string, args?: string[], env?: { [key: string]: string }): void {
135-
this.command = command;
135+
this.command = command === 'node' ? process.env.NODE_BINARY_PATH || 'node' : command;
136136
this.args = args;
137137
this.env = env;
138138
}

packages/components/src/style/variable.less

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
@zindex-back-top: 10;
5252
@zindex-picker-panel: 10;
5353
@zindex-popup-close: 10;
54-
@zindex-modal: 1000;
55-
@zindex-modal-mask: 1000;
54+
@zindex-modal: 10000;
55+
@zindex-modal-mask: 10000;
5656
@zindex-message: 1010;
5757
@zindex-notification: 1010;
5858
@zindex-popover: 1030;

packages/core-browser/src/progress/progress-bar.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import styles from './progress.module.less';
77

88
import { IProgressModel } from '.';
99

10-
export const ProgressBar: React.FC<{ progressModel: IProgressModel; className?: string }> = ({
10+
export const ProgressBar: React.FC<{ progressModel?: IProgressModel; className?: string }> = ({
1111
progressModel,
1212
className,
1313
}) => {
14+
if (!progressModel) {
15+
return null;
16+
}
1417
const worked = useAutorun<number>(progressModel.worked);
1518
const total = useAutorun<number | undefined>(progressModel.total);
1619
const show = useAutorun<boolean>(progressModel.show);

packages/i18n/src/common/en-US.lang.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,8 @@ export const localizationBundle = {
14661466
'aiNative.chat.clearContext': 'Clear Context',
14671467
'aiNative.chat.context.description': 'Total {0} References',
14681468
'aiNative.chat.context.clear': 'Clear References',
1469+
'aiNative.chat.modelSelector.disableTip': 'Clear or create session to change model',
1470+
14691471
'aiNative.inline.chat.operate.chat.title': 'Chat({0})',
14701472
'aiNative.inline.chat.operate.check.title': 'Check',
14711473
'aiNative.inline.chat.operate.thumbsup.title': 'Thumbs up',

packages/i18n/src/common/zh-CN.lang.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ export const localizationBundle = {
12341234
'aiNative.chat.clearContext': '清空上下文',
12351235
'aiNative.chat.context.description': '共 {0} 个引用',
12361236
'aiNative.chat.context.clear': '点击清空引用',
1237+
'aiNative.chat.modelSelector.disableTip': '如需切换模型,请新建或清空会话',
12371238

12381239
'aiNative.inline.chat.operate.chat.title': 'Chat({0})',
12391240
'aiNative.inline.chat.operate.check.title': '采纳',

0 commit comments

Comments
 (0)