Add enable-toggles for mcp servers and particular tools
This commit is contained in:
parent
1256d64498
commit
5f7f07ee6f
55
main.ts
55
main.ts
|
|
@ -18,6 +18,7 @@ export interface MCPToolState {
|
||||||
name: string;
|
name: string;
|
||||||
originalDescription: string;
|
originalDescription: string;
|
||||||
customDescription: string;
|
customDescription: string;
|
||||||
|
isEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MCPServerConfig {
|
export interface MCPServerConfig {
|
||||||
|
|
@ -28,6 +29,7 @@ export interface MCPServerConfig {
|
||||||
envString: string;
|
envString: string;
|
||||||
serverInstruction?: string;
|
serverInstruction?: string;
|
||||||
fetchedTools?: MCPToolState[];
|
fetchedTools?: MCPToolState[];
|
||||||
|
isEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------- Settings ---------------------------------------------------------------
|
// ----------------------------------------------- Settings ---------------------------------------------------------------
|
||||||
|
|
@ -667,12 +669,25 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
if (!this.plugin.settings.mcpServers) this.plugin.settings.mcpServers = [];
|
if (!this.plugin.settings.mcpServers) this.plugin.settings.mcpServers = [];
|
||||||
|
|
||||||
this.plugin.settings.mcpServers.forEach((server, index) => {
|
this.plugin.settings.mcpServers.forEach((server, index) => {
|
||||||
|
if (server.isEnabled === undefined) server.isEnabled = true;
|
||||||
|
|
||||||
const serverDiv = container.createDiv({
|
const serverDiv = container.createDiv({
|
||||||
attr: { style: 'border: 1px solid var(--interactive-accent); padding: 10px; margin-bottom: 15px; border-radius: 8px; background-color: var(--background-secondary-alt);' }
|
attr: { style: `border: 1px solid var(--interactive-accent); padding: 10px; margin-bottom: 15px; border-radius: 8px; background-color: var(--background-secondary-alt); transition: opacity 0.3s; opacity: ${server.isEnabled ? '1' : '0.5'}` }
|
||||||
});
|
});
|
||||||
|
|
||||||
new Setting(serverDiv)
|
new Setting(serverDiv)
|
||||||
.setName(`Имя сервера`)
|
.setName(`Имя сервера`)
|
||||||
|
.addToggle(tg => tg
|
||||||
|
.setTooltip(server.isEnabled ? 'Выключить сервер' : 'Включить сервер')
|
||||||
|
.setValue(server.isEnabled!)
|
||||||
|
.onChange(async v => {
|
||||||
|
server.isEnabled = v;
|
||||||
|
serverDiv.style.opacity = v ? '1' : '0.5';
|
||||||
|
tg.setTooltip(v ? 'Выключить сервер' : 'Включить сервер');
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
await this.plugin.syncSettings(); // Мгновенно синхроним с бэкендом
|
||||||
|
})
|
||||||
|
)
|
||||||
.addText(t => t.setValue(server.name).onChange(async v => {
|
.addText(t => t.setValue(server.name).onChange(async v => {
|
||||||
server.name = v.replace(/[^a-zA-Z0-9_\-]/g, '');
|
server.name = v.replace(/[^a-zA-Z0-9_\-]/g, '');
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
|
|
@ -732,7 +747,7 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
});
|
});
|
||||||
|
|
||||||
new Setting(container).addButton(b => b.setButtonText('➕ Добавить MCP сервер').setCta().onClick(async () => {
|
new Setting(container).addButton(b => b.setButtonText('➕ Добавить MCP сервер').setCta().onClick(async () => {
|
||||||
this.plugin.settings.mcpServers.push({ id: uuidv4(), name: 'duckduckgo', command: 'docker', args: 'run -i --rm ddg-mcp-server', envString: '' });
|
this.plugin.settings.mcpServers.push({ id: uuidv4(), name: 'duckduckgo', command: 'docker', args: 'run -i --rm ddg-mcp-server', envString: '', isEnabled: true });
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
this.display();
|
this.display();
|
||||||
}));
|
}));
|
||||||
|
|
@ -767,7 +782,7 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
const existing = existingMap.get(rt.name)!;
|
const existing = existingMap.get(rt.name)!;
|
||||||
return { ...existing, originalDescription: rt.description }; // обновляем оригинальное описание на всякий случай
|
return { ...existing, originalDescription: rt.description }; // обновляем оригинальное описание на всякий случай
|
||||||
}
|
}
|
||||||
return { name: rt.name, originalDescription: rt.description, customDescription: '' };
|
return { name: rt.name, originalDescription: rt.description, customDescription: '', isEnabled: true };
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
|
|
@ -785,13 +800,39 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
// Отрисовка списка тулов
|
// Отрисовка списка тулов
|
||||||
if (server.fetchedTools && server.fetchedTools.length > 0) {
|
if (server.fetchedTools && server.fetchedTools.length > 0) {
|
||||||
server.fetchedTools.forEach((tool, tIndex) => {
|
server.fetchedTools.forEach((tool, tIndex) => {
|
||||||
const toolDiv = toolsContainer.createDiv({ attr: { style: 'margin-bottom: 10px; padding: 10px; background: var(--background-primary); border-radius: 6px;' } });
|
if (tool.isEnabled === undefined) tool.isEnabled = true;
|
||||||
toolDiv.createEl('div', { text: `🛠 ${tool.name}`, attr: { style: 'font-weight: bold; margin-bottom: 5px;' } });
|
|
||||||
|
const toolDiv = toolsContainer.createDiv({
|
||||||
|
attr: { style: `margin-bottom: 10px; padding: 10px; background: var(--background-primary); border-radius: 6px; transition: opacity 0.3s; opacity: ${tool.isEnabled ? '1' : '0.5'}` }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Заголовок тула с переключателем
|
||||||
|
const headerDiv = toolDiv.createDiv({ attr: { style: 'display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 5px;' } });
|
||||||
|
headerDiv.createEl('div', { text: `🛠 ${tool.name}`, attr: { style: 'font-weight: bold; margin-top: 5px;' } });
|
||||||
|
|
||||||
|
const toggleSetting = new Setting(headerDiv)
|
||||||
|
.addToggle(tg => tg
|
||||||
|
.setTooltip(tool.isEnabled ? 'Выключить инструмент' : 'Включить инструмент')
|
||||||
|
.setValue(tool.isEnabled!)
|
||||||
|
.onChange(async v => {
|
||||||
|
tool.isEnabled = v;
|
||||||
|
toolDiv.style.opacity = v ? '1' : '0.5';
|
||||||
|
tg.setTooltip(v ? 'Выключить инструмент' : 'Включить инструмент');
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
await this.plugin.syncSettings(); // Мгновенно синхроним с бэкендом
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// Убираем лишние рамки и отступы у элемента Setting для компактности в шапке
|
||||||
|
toggleSetting.settingEl.style.border = 'none';
|
||||||
|
toggleSetting.settingEl.style.padding = '0';
|
||||||
|
toggleSetting.infoEl.remove();
|
||||||
|
|
||||||
|
// Описание
|
||||||
toolDiv.createEl('div', { text: tool.originalDescription, attr: { style: 'font-size: 0.85em; color: var(--text-muted); margin-bottom: 8px;' } });
|
toolDiv.createEl('div', { text: tool.originalDescription, attr: { style: 'font-size: 0.85em; color: var(--text-muted); margin-bottom: 8px;' } });
|
||||||
|
|
||||||
new Setting(toolDiv)
|
new Setting(toolDiv)
|
||||||
.setName('Кастомное описание (Override)')
|
.setName('Дополнительные инструкции')
|
||||||
.setDesc('Оставьте пустым, чтобы использовать оригинальное.')
|
.setDesc('Этот текст будет добавлен к оригинальному описанию инструмента. Оставьте пустым, если не требуется.')
|
||||||
.addTextArea(t => {
|
.addTextArea(t => {
|
||||||
t.inputEl.style.width = '100%';
|
t.inputEl.style.width = '100%';
|
||||||
t.setValue(tool.customDescription).onChange(async v => {
|
t.setValue(tool.customDescription).onChange(async v => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user