Fix available models checking and models' choice settings
This commit is contained in:
parent
37bbc44741
commit
fde784afbf
106
main.ts
106
main.ts
|
|
@ -18,12 +18,13 @@ interface LLMAgentSettings {
|
|||
excludedFolders: string[];
|
||||
refCacheFolder: string;
|
||||
|
||||
voiceModel: string;
|
||||
summarizationModel: string;
|
||||
voiceCommandModel: string;
|
||||
voiceInterval: number;
|
||||
voiceDisplayLimit: number; // 3000
|
||||
voiceContextLimit: number; // N2 символов для LLM
|
||||
promptRegularPath: string;
|
||||
promptCommandsPath: string;
|
||||
promptRegular: string;
|
||||
promptCommands: string;
|
||||
markerStart: string; // "старт"
|
||||
markerStop: string; // "стоп"
|
||||
}
|
||||
|
|
@ -42,8 +43,8 @@ const DEFAULT_SETTINGS: LLMAgentSettings = {
|
|||
voiceInterval: 1,
|
||||
voiceDisplayLimit: 3000,
|
||||
voiceContextLimit: 3000,
|
||||
promptRegularPath: '',
|
||||
promptCommandsPath: '',
|
||||
promptRegular: '',
|
||||
promptCommands: '',
|
||||
markerStart: 'старт',
|
||||
markerStop: 'стоп'
|
||||
};
|
||||
|
|
@ -55,8 +56,9 @@ export default class LLMAgentPlugin extends Plugin {
|
|||
eventBus: EventBus;
|
||||
webSocketService: WebSocketService;
|
||||
activeStreamControllers: Map<string, AbortController>;
|
||||
availableModels: string[];
|
||||
|
||||
async syncVoiceSettings() {
|
||||
async syncSettings() {
|
||||
try {
|
||||
const response = await fetch(`${this.settings.apiBaseUrl}/settings/sync`, {
|
||||
method: 'POST',
|
||||
|
|
@ -71,6 +73,24 @@ export default class LLMAgentPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает список доступных моделей с бэкенда.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async fetchAvailableModels(): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${this.settings.apiBaseUrl}/models`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Ошибка загрузки моделей: ${response.status}`);
|
||||
}
|
||||
this.availableModels = await response.json();
|
||||
} catch (error) {
|
||||
console.error('Ошибка загрузки доступных моделей:', error);
|
||||
// Fallback к базовым моделям
|
||||
this.availableModels = ['gemini-2.5-flash', 'gpt-4o-mini', 'claude-3-5-sonnet-20241022'];
|
||||
}
|
||||
}
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
|
|
@ -118,9 +138,9 @@ export default class LLMAgentPlugin extends Plugin {
|
|||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
|
||||
await this.fetchAvailableModels();
|
||||
// Вызываем один раз при запуске
|
||||
await this.syncVoiceSettings();
|
||||
await this.syncSettings();
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
|
@ -144,6 +164,7 @@ export default class LLMAgentPlugin extends Plugin {
|
|||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
this.eventBus.emit('settings-changed');
|
||||
}
|
||||
|
||||
// ----------------------------------------------- View Management ---------------------------------------------------------------
|
||||
|
|
@ -206,6 +227,32 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
|
||||
containerEl.createEl('h2', { text: 'Основные настройки' });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Модель по умолчанию')
|
||||
.setDesc('Выберите модель для основного чата.')
|
||||
.addDropdown((dropdown) => {
|
||||
this.plugin.availableModels.forEach(model => dropdown.addOption(model, model));
|
||||
dropdown.setValue(this.plugin.settings.defaultModel)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.defaultModel = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Модель суммаризации')
|
||||
.setDesc('Выберите модель для суммаризации.')
|
||||
.addDropdown((dropdown) => {
|
||||
this.plugin.availableModels.forEach(model => dropdown.addOption(model, model));
|
||||
dropdown.setValue(this.plugin.settings.summarizationModel)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.summarizationModel = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('API Base URL')
|
||||
.setDesc('Базовый URL для API LLM Agent')
|
||||
|
|
@ -216,6 +263,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.apiBaseUrl = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -229,11 +277,25 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.systemPrompt = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
containerEl.createEl('h2', { text: 'Голосовое управление (Voice Service)' });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Модель команд')
|
||||
.setDesc('LLM для обработки голосовых команд.')
|
||||
.addDropdown((dropdown) => {
|
||||
this.plugin.availableModels.forEach(model => dropdown.addOption(model, model));
|
||||
dropdown.setValue(this.plugin.settings.voiceCommandModel)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.voiceCommandModel = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Интервал регулярного анализа (мин)')
|
||||
.setDesc('Как часто LLM анализирует последние фразы (Prompt 1).')
|
||||
|
|
@ -243,7 +305,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.voiceInterval = Number(value);
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -256,7 +318,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.voiceContextLimit = Number(value);
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -270,7 +332,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.markerStart = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -284,7 +346,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.markerStop = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -294,11 +356,11 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.addTextArea((text) =>
|
||||
text
|
||||
// .setPlaceholder('prompts/regular_analysis.md')
|
||||
.setValue(this.plugin.settings.promptRegularPath)
|
||||
.setValue(this.plugin.settings.promptRegular)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.promptRegularPath = value;
|
||||
this.plugin.settings.promptRegular = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -308,11 +370,11 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.addTextArea((text) =>
|
||||
text
|
||||
// .setPlaceholder('prompts/voice_commands.md')
|
||||
.setValue(this.plugin.settings.promptCommandsPath)
|
||||
.setValue(this.plugin.settings.promptCommands)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.promptCommandsPath = value;
|
||||
this.plugin.settings.promptCommands = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncVoiceSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -328,6 +390,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.promptsFolder = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -341,6 +404,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.refCacheFolder = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -352,6 +416,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
toggle.setValue(this.plugin.settings.enableFileReferences).onChange(async (value) => {
|
||||
this.plugin.settings.enableFileReferences = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -363,6 +428,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
toggle.setValue(this.plugin.settings.enablePromptReferences).onChange(async (value) => {
|
||||
this.plugin.settings.enablePromptReferences = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -374,6 +440,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
toggle.setValue(this.plugin.settings.enableFileReferences).onChange(async (value) => {
|
||||
this.plugin.settings.enableFileReferences = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -388,6 +455,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onChange(async (value) => {
|
||||
this.plugin.settings.excludedFolders[index] = value;
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
// Очищаем кэш автокомплита при изменении настроек
|
||||
this.plugin.eventBus.emit('settings-changed');
|
||||
});
|
||||
|
|
@ -399,6 +467,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onClick(async () => {
|
||||
this.plugin.settings.excludedFolders.splice(index, 1);
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
this.display(); // Перерисовать настройки для обновления списка
|
||||
// Очищаем кэш автокомплита при изменении настроек
|
||||
this.plugin.eventBus.emit('settings-changed');
|
||||
|
|
@ -413,6 +482,7 @@ class SampleSettingTab extends PluginSettingTab {
|
|||
.onClick(async () => {
|
||||
this.plugin.settings.excludedFolders.push(''); // Добавляем пустое поле
|
||||
await this.plugin.saveSettings();
|
||||
await this.plugin.syncSettings();
|
||||
this.display(); // Перерисовать настройки для обновления списка
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import { CacheManager } from 'src/references/CacheManager';
|
|||
interface ChatPanelProps {
|
||||
chatHistory: ChatHistoryItem[];
|
||||
onSendMessage: (message: string, selectedModel?: string, attachments?: Attachment[]) => void;
|
||||
availableModels?: string[];
|
||||
selectedModel?: string;
|
||||
plugin: LLMAgentPlugin;
|
||||
currentGraphCustomSystemPrompt: string | null;
|
||||
|
|
@ -133,9 +132,9 @@ export class ChatPanel {
|
|||
}
|
||||
|
||||
updateModelDropdown(): void {
|
||||
if (!this.props.availableModels) return;
|
||||
if (!this.props.plugin.availableModels) return;
|
||||
|
||||
this.modelDropdown.innerHTML = this.props.availableModels
|
||||
this.modelDropdown.innerHTML = this.props.plugin.availableModels
|
||||
.map(
|
||||
(model) => `
|
||||
<div class="model-option" data-model="${model}">
|
||||
|
|
@ -410,11 +409,6 @@ export class ChatPanel {
|
|||
await this.renderHistory();
|
||||
}
|
||||
|
||||
updateAvailableModels(models: string[]): void {
|
||||
this.props.availableModels = models;
|
||||
this.updateModelDropdown();
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
if (this.referenceAutocomplete) {
|
||||
this.referenceAutocomplete.destroy();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export class VoicePanel {
|
|||
if (!body) return;
|
||||
if (data.obsidian_settings_fetched == false) // если это не сделать, то на беке останутся пустые настройки, если обсидиан запущен раньше бека
|
||||
{
|
||||
this.plugin.syncVoiceSettings();
|
||||
this.plugin.syncSettings();
|
||||
}
|
||||
if (this.activeTab === 'trans') body.textContent = data.transcription;
|
||||
if (this.activeTab === 'res1') body.textContent = data.response1;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ export class ChatView extends ItemView {
|
|||
currentNode: string | null;
|
||||
chatContainer: HTMLDivElement;
|
||||
chatPanel: ChatPanel | null;
|
||||
availableModels: string[];
|
||||
currentGraphCustomSystemPrompt: string | null;
|
||||
currentStreamingNodeId: string | null = null;
|
||||
|
||||
|
|
@ -30,7 +29,6 @@ export class ChatView extends ItemView {
|
|||
this.selectedGraphId = null;
|
||||
this.currentNode = null;
|
||||
this.chatPanel = null;
|
||||
this.availableModels = [];
|
||||
this.currentGraphCustomSystemPrompt = null;
|
||||
}
|
||||
|
||||
|
|
@ -54,19 +52,19 @@ export class ChatView extends ItemView {
|
|||
this.chatContainer = container.createDiv() as HTMLDivElement;
|
||||
this.chatContainer.addClass('llm-agent-chat-container');
|
||||
|
||||
// Загружаем доступные модели
|
||||
await this.fetchAvailableModels();
|
||||
// Загружаем доступные модели (TODO: проверить, что здесь это нужно, что не сделали этого ранее)
|
||||
// await this.plugin.fetchAvailableModels();
|
||||
|
||||
// Инициализируем только чат панель с передачей plugin
|
||||
this.chatPanel = new ChatPanel(this.chatContainer, {
|
||||
chatHistory: this.chatHistory,
|
||||
onSendMessage: this.handleSendMessage.bind(this),
|
||||
availableModels: this.availableModels,
|
||||
selectedModel: this.plugin.settings.defaultModel || 'gemini-2.5-flash',
|
||||
plugin: this.plugin,
|
||||
currentGraphCustomSystemPrompt: this.currentGraphCustomSystemPrompt
|
||||
});
|
||||
|
||||
this.plugin.eventBus.on('settings-changed', this.handleSettingsChanged.bind(this));
|
||||
this.plugin.eventBus.on('node-selected', this.handleNodeSelected.bind(this));
|
||||
this.plugin.eventBus.on('new-chat', this.handleNewChat.bind(this));
|
||||
this.plugin.eventBus.on('graph-selected', this.handleGraphSelected.bind(this));
|
||||
|
|
@ -84,6 +82,7 @@ export class ChatView extends ItemView {
|
|||
this.chatPanel.destroy();
|
||||
this.chatPanel = null;
|
||||
}
|
||||
this.plugin.eventBus.off('settings-changed', this.handleSettingsChanged);
|
||||
this.plugin.eventBus.off('node-selected', this.handleNodeSelected);
|
||||
this.plugin.eventBus.off('new-chat', this.handleNewChat);
|
||||
this.plugin.eventBus.off('graph-selected', this.handleGraphSelected);
|
||||
|
|
@ -154,24 +153,6 @@ export class ChatView extends ItemView {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает список доступных моделей с бэкенда.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async fetchAvailableModels(): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${this.plugin.settings.apiBaseUrl}/models`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Ошибка загрузки моделей: ${response.status}`);
|
||||
}
|
||||
this.availableModels = await response.json();
|
||||
} catch (error) {
|
||||
console.error('Ошибка загрузки доступных моделей:', error);
|
||||
// Fallback к базовым моделям
|
||||
this.availableModels = ['gemini-2.5-flash', 'gpt-4o-mini', 'claude-3-5-sonnet-20241022'];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------- Event Handlers ---------------------------------------------------------------
|
||||
|
||||
async handleSendMessage(message: string, selectedModel?: string, attachments?: Attachment[]): Promise<void> {
|
||||
|
|
@ -227,6 +208,13 @@ export class ChatView extends ItemView {
|
|||
}
|
||||
}
|
||||
|
||||
handleSettingsChanged(): void {
|
||||
if (this.chatPanel)
|
||||
{
|
||||
this.chatPanel.setSelectedModel(this.plugin.settings.defaultModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обрабатывает выбор узла на графе. Загружает историю сообщений до выбранного узла
|
||||
* и обновляет панель чата.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user