Add customization of prompts for MCP tools

This commit is contained in:
dimitrievgs 2026-06-14 01:33:49 +03:00
parent aa4f8d5342
commit 1256d64498

87
main.ts
View File

@ -14,12 +14,20 @@ import 'src/css/styles.css';
import { LLM_DEFAULTS } from 'src/constants';
export interface MCPToolState {
name: string;
originalDescription: string;
customDescription: string;
}
export interface MCPServerConfig {
id: string;
name: string;
command: string;
args: string;
envString: string;
serverInstruction?: string;
fetchedTools?: MCPToolState[];
}
// ----------------------------------------------- Settings ---------------------------------------------------------------
@ -707,6 +715,20 @@ class SampleSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
});
});
new Setting(serverDiv)
.setName('Общая инструкция для сервера (Над-инструкция)')
.setDesc('Эти инструкции будут добавлены в системный промпт при использовании графа.')
.addTextArea(t => {
t.inputEl.style.width = '100%';
t.inputEl.style.height = '60px';
t.setValue(server.serverInstruction || '').onChange(async v => {
server.serverInstruction = v;
await this.plugin.saveSettings();
});
});
this.createFetchedTools(server, serverDiv);
});
new Setting(container).addButton(b => b.setButtonText(' Добавить MCP сервер').setCta().onClick(async () => {
@ -716,6 +738,71 @@ class SampleSettingTab extends PluginSettingTab {
}));
}
createFetchedTools(server: MCPServerConfig, serverDiv: HTMLDivElement) {
const toolsContainer = serverDiv.createDiv({ cls: 'mcp-tools-container', attr: { style: 'margin-top: 15px; border-top: 1px solid var(--background-modifier-border); padding-top: 10px;' } });
const fetchBtn = toolsContainer.createEl('button', { text: '🔄 Подгрузить/Обновить инструменты' });
fetchBtn.style.marginBottom = '10px';
fetchBtn.onclick = async () => {
fetchBtn.textContent = '⏳ Подгрузка...';
fetchBtn.disabled = true;
try {
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/mcp/fetch`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(server)
});
if (!response.ok) throw new Error("Ошибка HTTP: " + response.status);
const remoteTools: {name: string, description: string}[] = await response.json();
// Логика синхронизации: оставляем кастомные описания, удаляем пропавшие, добавляем новые
if (!server.fetchedTools) server.fetchedTools = [];
const existingMap = new Map(server.fetchedTools.map(t => [t.name, t]));
server.fetchedTools = remoteTools.map(rt => {
if (existingMap.has(rt.name)) {
const existing = existingMap.get(rt.name)!;
return { ...existing, originalDescription: rt.description }; // обновляем оригинальное описание на всякий случай
}
return { name: rt.name, originalDescription: rt.description, customDescription: '' };
});
await this.plugin.saveSettings();
new Notice(`Загружено инструментов: ${remoteTools.length}`);
this.display(); // Перерисовываем UI
} catch (e) {
console.error(e);
new Notice('Ошибка подгрузки инструментов: ' + e);
} finally {
fetchBtn.textContent = '🔄 Подгрузить/Обновить инструменты';
fetchBtn.disabled = false;
}
};
// Отрисовка списка тулов
if (server.fetchedTools && server.fetchedTools.length > 0) {
server.fetchedTools.forEach((tool, tIndex) => {
const toolDiv = toolsContainer.createDiv({ attr: { style: 'margin-bottom: 10px; padding: 10px; background: var(--background-primary); border-radius: 6px;' } });
toolDiv.createEl('div', { text: `🛠 ${tool.name}`, attr: { style: 'font-weight: bold; margin-bottom: 5px;' } });
toolDiv.createEl('div', { text: tool.originalDescription, attr: { style: 'font-size: 0.85em; color: var(--text-muted); margin-bottom: 8px;' } });
new Setting(toolDiv)
.setName('Кастомное описание (Override)')
.setDesc('Оставьте пустым, чтобы использовать оригинальное.')
.addTextArea(t => {
t.inputEl.style.width = '100%';
t.setValue(tool.customDescription).onChange(async v => {
tool.customDescription = v;
await this.plugin.saveSettings();
});
});
});
}
}
renderVoiceSettings(container: HTMLElement) {
container.createEl('h3', { text: 'Транскрибация Vosk' });