Add customization of prompts for MCP tools
This commit is contained in:
parent
aa4f8d5342
commit
1256d64498
87
main.ts
87
main.ts
|
|
@ -14,12 +14,20 @@ import 'src/css/styles.css';
|
||||||
|
|
||||||
import { LLM_DEFAULTS } from 'src/constants';
|
import { LLM_DEFAULTS } from 'src/constants';
|
||||||
|
|
||||||
|
export interface MCPToolState {
|
||||||
|
name: string;
|
||||||
|
originalDescription: string;
|
||||||
|
customDescription: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MCPServerConfig {
|
export interface MCPServerConfig {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
command: string;
|
command: string;
|
||||||
args: string;
|
args: string;
|
||||||
envString: string;
|
envString: string;
|
||||||
|
serverInstruction?: string;
|
||||||
|
fetchedTools?: MCPToolState[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------- Settings ---------------------------------------------------------------
|
// ----------------------------------------------- Settings ---------------------------------------------------------------
|
||||||
|
|
@ -707,6 +715,20 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
await this.plugin.saveSettings();
|
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 () => {
|
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) {
|
renderVoiceSettings(container: HTMLElement) {
|
||||||
container.createEl('h3', { text: 'Транскрибация Vosk' });
|
container.createEl('h3', { text: 'Транскрибация Vosk' });
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user