Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/ai-native/src/browser/chat/chat.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
height: 100%;
border-radius: 12px;
overflow: hidden;
font-size: 14px;
font-size: 12px;
user-select: text;

border-top-left-radius: 12px;
Expand Down Expand Up @@ -75,7 +75,7 @@

.header_container {
height: 36px;
padding: 8px 0 8px 16px;
padding: 8px 8px 8px 16px;
box-sizing: border-box;
background-color: var(--editorGroupHeader-tabsBackground);
user-select: none;
Expand Down
59 changes: 29 additions & 30 deletions packages/ai-native/src/browser/chat/chat.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,9 @@ export const AIChatView = () => {
const promptProvider = useInjectable<ChatAgentPromptProvider>(ChatAgentPromptProvider);

const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
const msgHistoryManager = aiChatService.sessionModel.history;
const containerRef = React.useRef<HTMLDivElement>(null);
const chatInputRef = React.useRef<{ setInputValue: (v: string) => void } | null>(null);
const dialogService = useInjectable<IDialogService>(IDialogService);
const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);

const [shortcutCommands, setShortcutCommands] = React.useState<ChatSlashCommandItemModel[]>([]);

Expand All @@ -110,7 +107,6 @@ export const AIChatView = () => {
const [defaultAgentId, setDefaultAgentId] = React.useState<string>('');
const [command, setCommand] = React.useState('');
const [theme, setTheme] = React.useState<string | null>(null);
const [mcpToolsCount, setMcpToolsCount] = React.useState<number>(0);

React.useEffect(() => {
const featureSlashCommands = chatFeatureRegistry.getAllShortcutSlashCommand();
Expand Down Expand Up @@ -662,25 +658,6 @@ export const AIChatView = () => {
};
}, [aiChatService.sessionModel]);

useEventEffect(
mcpServerProxyService.onChangeMCPServers,
() => {
mcpServerProxyService.getAllMCPTools().then((tools) => {
setMcpToolsCount(tools.length);
});
},
[mcpServerProxyService],
);

const handleShowMCPTools = React.useCallback(async () => {
const tools = await mcpServerProxyService.getAllMCPTools();
dialogService.open({
message: <MCPToolsDialog tools={tools} />,
type: MessageType.Empty,
buttons: ['关闭'],
});
}, [mcpServerProxyService, dialogService]);

return (
<div id={styles.ai_chat_view}>
<div className={styles.header_container}>
Expand Down Expand Up @@ -720,13 +697,6 @@ export const AIChatView = () => {
</Popover>
))}
</div>
<div className={styles.header_operate_right}>
{aiNativeConfigService.capabilities.supportsMCP && (
<div className={styles.tag} onClick={handleShowMCPTools}>
{`MCP Tools: ${mcpToolsCount}`}
</div>
)}
</div>
</div>
<ChatInputWrapperRender
onSend={(value, agentId, command) =>
Expand Down Expand Up @@ -765,6 +735,9 @@ export function DefaultChatViewHeader({
handleClear: () => any;
handleCloseChatView: () => any;
}) {
const dialogService = useInjectable<IDialogService>(IDialogService);
const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
const mcpServerProxyService = useInjectable<MCPServerProxyService>(TokenMCPServerProxyService);
const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
const [historyList, setHistoryList] = React.useState<IChatHistoryItem[]>([]);
const [currentTitle, setCurrentTitle] = React.useState<string>('');
Expand All @@ -786,6 +759,15 @@ export function DefaultChatViewHeader({
[aiChatService],
);

const handleShowMCPTools = React.useCallback(async () => {
const tools = await mcpServerProxyService.getAllMCPTools();
dialogService.open({
message: <MCPToolsDialog tools={tools} />,
type: MessageType.Empty,
buttons: ['关闭'],
});
}, [mcpServerProxyService, dialogService]);

React.useEffect(() => {
const getHistoryList = () => {
const currentMessages = aiChatService.sessionModel.history.getMessages();
Expand Down Expand Up @@ -865,6 +847,23 @@ export function DefaultChatViewHeader({
ariaLabel={localize('aiNative.operate.clear.title')}
/>
</Popover>
{aiNativeConfigService.capabilities.supportsMCP && (
<Popover
overlayClassName={styles.popover_icon}
id={'ai-chat-header-tools'}
position={PopoverPosition.left}
title={localize('aiNative.operate.tools.title')}
>
<EnhanceIcon
wrapperClassName={styles.action_btn}
className={getIcon('menubar-tool')}
onClick={handleShowMCPTools}
tabIndex={0}
role='button'
ariaLabel={localize('aiNative.operate.tools.title')}
/>
</Popover>
)}
<Popover
overlayClassName={styles.popover_icon}
id={'ai-chat-header-close'}
Expand Down
2 changes: 1 addition & 1 deletion packages/ai-native/src/browser/components/chat-history.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
.dm-chat-history-header-actions {
display: flex;
align-items: center;
font-size: 14px;
font-size: 12px;

.dm-chat-history-header-actions-history {
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}

.thinking_text {
font-size: 14px;
font-size: 12px;
}

.bottom_container {
Expand Down Expand Up @@ -480,7 +480,7 @@
* welcome
*/
.chat_welcome_head {
font-size: 14px;
font-size: 12px;
line-height: 22px;
a {
color: #3c8dff;
Expand Down
2 changes: 1 addition & 1 deletion packages/ai-native/src/browser/layout/layout.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
.rce-mbox-text {
line-height: 18px;
width: inherit;
font-size: 14px;
font-size: 12px;
}

.rce-smsg {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
}

.run_cmd_tool {
background-color: var(--design-chatInput-background);
padding: 10px;
border-radius: 4px;

.command_title {
display: flex;
align-items: center;
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/common/en-US.lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,7 @@ export const localizationBundle = {
'aiNative.operate.stop.title': 'Stop',
'aiNative.operate.close.title': 'Close',
'aiNative.operate.clear.title': 'Clear',
'aiNative.operate.tools.title': 'MCP Tools',
'aiNative.operate.newChat.title': 'New Chat',
'aiNative.operate.chatHistory.title': 'Chat History',
'aiNative.operate.chatHistory.searchPlaceholder': 'Search Chats...',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/common/zh-CN.lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,7 @@ export const localizationBundle = {
'aiNative.operate.stop.title': '停止',
'aiNative.operate.close.title': '关闭',
'aiNative.operate.clear.title': '清空',
'aiNative.operate.tools.title': 'MCP 工具',
'aiNative.operate.newChat.title': '新建聊天',
'aiNative.operate.chatHistory.title': '聊天历史',
'aiNative.operate.chatHistory.searchPlaceholder': '请搜索...',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,30 +160,30 @@ export class AINativeContribution implements AINativeCoreContribution {
},
);

registry.registerEditorInlineChat(
{
id: 'ai-explain',
name: EInlineOperation.Explain,
renderType: 'button',
codeAction: {
isPreferred: true,
},
},
{
execute: async (editor: ICodeEditor, selection: ISelection, token) => {
const model = editor.getModel();
if (!model) {
return;
}

const crossCode = editor.getModel()?.getValueInRange(Selection.liftSelection(selection));
this.aiChatService.sendMessage({
message: `Explain code: \`\`\`\n${crossCode}\n\`\`\``,
prompt: `Help me, Explain code: \`\`\`\n${crossCode}\n\`\`\``,
});
},
},
);
// registry.registerEditorInlineChat(
// {
// id: 'ai-explain',
// name: EInlineOperation.Explain,
// renderType: 'button',
// codeAction: {
// isPreferred: true,
// },
// },
// {
// execute: async (editor: ICodeEditor, selection: ISelection, token) => {
// const model = editor.getModel();
// if (!model) {
// return;
// }

// const crossCode = editor.getModel()?.getValueInRange(Selection.liftSelection(selection));
// this.aiChatService.sendMessage({
// message: `Explain code: \`\`\`\n${crossCode}\n\`\`\``,
// prompt: `Help me, Explain code: \`\`\`\n${crossCode}\n\`\`\``,
// });
// },
// },
// );

registry.registerTerminalInlineChat(
{
Expand Down Expand Up @@ -236,38 +236,38 @@ export class AINativeContribution implements AINativeCoreContribution {
],
);

registry.registerSlashCommand(
{
name: 'Explain',
description: 'Explain',
isShortcut: true,
tooltip: 'Explain',
},
{
providerRender: SlashCommand,
providerInputPlaceholder(value, editor) {
return 'Please enter or paste the code.';
},
providerPrompt(value, editor) {
return `Explain code: \`\`\`\n${value}\n\`\`\``;
},
execute: (value: string, send: TChatSlashCommandSend, editor: ICodeEditor) => {
send(value);
},
},
);

registry.registerSlashCommand(
{
name: 'Test',
description: 'Test',
},
{
execute: (value: string, send: TChatSlashCommandSend, editor: ICodeEditor) => {
send(value);
},
},
);
// registry.registerSlashCommand(
// {
// name: 'Explain',
// description: 'Explain',
// isShortcut: true,
// tooltip: 'Explain',
// },
// {
// providerRender: SlashCommand,
// providerInputPlaceholder(value, editor) {
// return 'Please enter or paste the code.';
// },
// providerPrompt(value, editor) {
// return `Explain code: \`\`\`\n${value}\n\`\`\``;
// },
// execute: (value: string, send: TChatSlashCommandSend, editor: ICodeEditor) => {
// send(value);
// },
// },
// );

// registry.registerSlashCommand(
// {
// name: 'Test',
// description: 'Test',
// },
// {
// execute: (value: string, send: TChatSlashCommandSend, editor: ICodeEditor) => {
// send(value);
// },
// },
// );
}

registerResolveConflictFeature(registry: IResolveConflictRegistry): void {
Expand Down