Add 4th tab in voice panel with quantitive and qualitive metrics
This commit is contained in:
parent
a103966178
commit
143160ee26
29
main.ts
29
main.ts
|
|
@ -26,10 +26,12 @@ interface LLMAgentSettings {
|
||||||
voiceCommandModel: string;
|
voiceCommandModel: string;
|
||||||
logsFolder: string;
|
logsFolder: string;
|
||||||
voiceInterval: number;
|
voiceInterval: number;
|
||||||
|
metricsInterval: number;
|
||||||
voiceDisplayLimit: number; // 3000
|
voiceDisplayLimit: number; // 3000
|
||||||
voiceContextLimit: number; // N2 символов для LLM
|
voiceContextLimit: number; // N2 символов для LLM
|
||||||
promptRegular: string;
|
promptRegular: string;
|
||||||
promptCommands: string;
|
promptCommands: string;
|
||||||
|
promptMetrics: string;
|
||||||
markerStart: string; // "старт"
|
markerStart: string; // "старт"
|
||||||
markerStop: string; // "стоп"
|
markerStop: string; // "стоп"
|
||||||
}
|
}
|
||||||
|
|
@ -48,10 +50,12 @@ const DEFAULT_SETTINGS: LLMAgentSettings = {
|
||||||
voiceCommandModel: '',
|
voiceCommandModel: '',
|
||||||
logsFolder: 'audio-logs',
|
logsFolder: 'audio-logs',
|
||||||
voiceInterval: 1,
|
voiceInterval: 1,
|
||||||
|
metricsInterval: 15,
|
||||||
voiceDisplayLimit: 30000,
|
voiceDisplayLimit: 30000,
|
||||||
voiceContextLimit: 30000,
|
voiceContextLimit: 30000,
|
||||||
promptRegular: '',
|
promptRegular: '',
|
||||||
promptCommands: '',
|
promptCommands: '',
|
||||||
|
promptMetrics: '',
|
||||||
markerStart: 'старт',
|
markerStart: 'старт',
|
||||||
markerStop: 'стоп'
|
markerStop: 'стоп'
|
||||||
};
|
};
|
||||||
|
|
@ -76,6 +80,7 @@ export default class LLMAgentPlugin extends Plugin {
|
||||||
settingsToSync.systemPrompt = await engine.processRawSettingValue(this.settings.systemPrompt);
|
settingsToSync.systemPrompt = await engine.processRawSettingValue(this.settings.systemPrompt);
|
||||||
settingsToSync.promptRegular = await engine.processRawSettingValue(this.settings.promptRegular);
|
settingsToSync.promptRegular = await engine.processRawSettingValue(this.settings.promptRegular);
|
||||||
settingsToSync.promptCommands = await engine.processRawSettingValue(this.settings.promptCommands);
|
settingsToSync.promptCommands = await engine.processRawSettingValue(this.settings.promptCommands);
|
||||||
|
settingsToSync.promptMetrics = await engine.processRawSettingValue(this.settings.promptMetrics);
|
||||||
|
|
||||||
const adapter = this.app.vault.adapter;
|
const adapter = this.app.vault.adapter;
|
||||||
if (adapter instanceof FileSystemAdapter) {
|
if (adapter instanceof FileSystemAdapter) {
|
||||||
|
|
@ -163,8 +168,12 @@ export default class LLMAgentPlugin extends Plugin {
|
||||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||||
|
|
||||||
await this.fetchAvailableModels();
|
await this.fetchAvailableModels();
|
||||||
// Вызываем один раз при запуске
|
|
||||||
|
// Ждем полной инициализации хранилища перед вызовом зависимых функций
|
||||||
|
// await this.syncSettings();
|
||||||
|
this.app.workspace.onLayoutReady(async () => {
|
||||||
await this.syncSettings();
|
await this.syncSettings();
|
||||||
|
});
|
||||||
|
|
||||||
this.registerEvent(
|
this.registerEvent(
|
||||||
this.app.vault.on('modify', async (file) => {
|
this.app.vault.on('modify', async (file) => {
|
||||||
|
|
@ -348,6 +357,19 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName('Интервал аналитики (мин)')
|
||||||
|
.setDesc('Как часто Python и LLM генерируют графики и качественный анализ (Таб 4).')
|
||||||
|
.addText((text) =>
|
||||||
|
text
|
||||||
|
.setValue(String(this.plugin.settings.metricsInterval))
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.metricsInterval = Number(value) || 15;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
await this.plugin.syncSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName('Объем контекста (символы)')
|
.setName('Объем контекста (символы)')
|
||||||
.setDesc('Сколько последних символов транскрибации отправлять в модель.')
|
.setDesc('Сколько последних символов транскрибации отправлять в модель.')
|
||||||
|
|
@ -401,6 +423,11 @@ class SampleSettingTab extends PluginSettingTab {
|
||||||
'promptCommands'
|
'promptCommands'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.addPromptAutocomplete(
|
||||||
|
new Setting(containerEl).setName('Промпт качественной аналитики'),
|
||||||
|
'promptMetrics'
|
||||||
|
);
|
||||||
|
|
||||||
containerEl.createEl('h2', { text: 'Управление ссылками и файлами' });
|
containerEl.createEl('h2', { text: 'Управление ссылками и файлами' });
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import LLMAgentPlugin from 'main';
|
||||||
import { MarkdownRenderer, setIcon, Notice } from 'obsidian';
|
import { MarkdownRenderer, setIcon, Notice } from 'obsidian';
|
||||||
|
|
||||||
export class VoicePanel {
|
export class VoicePanel {
|
||||||
private activeTab: 'res1' | 'res2' | 'trans' = 'res1';
|
private activeTab: 'res1' | 'res2' | 'trans' | 'metrics' = 'res1';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private container: HTMLElement,
|
private container: HTMLElement,
|
||||||
|
|
@ -25,6 +25,7 @@ export class VoicePanel {
|
||||||
<button class="v-tab active" data-tab="res1">Response 1</button>
|
<button class="v-tab active" data-tab="res1">Response 1</button>
|
||||||
<button class="v-tab" data-tab="res2">Response 2</button>
|
<button class="v-tab" data-tab="res2">Response 2</button>
|
||||||
<button class="v-tab" data-tab="trans">Transcription</button>
|
<button class="v-tab" data-tab="trans">Transcription</button>
|
||||||
|
<button class="v-tab" data-tab="metrics">Metrics</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="v-body" class="voice-body selectable"></div>
|
<div id="v-body" class="voice-body selectable"></div>
|
||||||
|
|
@ -84,6 +85,42 @@ export class VoicePanel {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.activeTab === 'metrics') {
|
||||||
|
if (!data.metrics) return;
|
||||||
|
|
||||||
|
// 1. Строгая проверка через JSON.stringify, чтобы отсечь лишние апдейты
|
||||||
|
// и не перестраивать DOM (что и вызывает дергание)
|
||||||
|
const newDataString = JSON.stringify(data.metrics);
|
||||||
|
if ((body as any).lastMetricsData === newDataString) return;
|
||||||
|
(body as any).lastMetricsData = newDataString;
|
||||||
|
|
||||||
|
// 2. Запоминаем позицию скролла перед обновлением
|
||||||
|
const scrollTop = body.scrollTop;
|
||||||
|
|
||||||
|
body.empty();
|
||||||
|
|
||||||
|
// Рендер графиков
|
||||||
|
if (data.metrics.graphs && data.metrics.graphs.length > 0) {
|
||||||
|
const graphsContainer = document.createElement('div');
|
||||||
|
graphsContainer.style.display = "flex";
|
||||||
|
graphsContainer.style.flexDirection = "column";
|
||||||
|
graphsContainer.innerHTML = data.metrics.graphs.join('');
|
||||||
|
body.appendChild(graphsContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рендер текста
|
||||||
|
if (data.metrics.text) {
|
||||||
|
const textContainer = document.createElement('div');
|
||||||
|
textContainer.addClass('markdown-rendered');
|
||||||
|
await MarkdownRenderer.renderMarkdown(data.metrics.text, textContainer, '', this.plugin);
|
||||||
|
body.appendChild(textContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Возвращаем скролл на место сразу после рендера в следующем микротаске
|
||||||
|
setTimeout(() => { body.scrollTop = scrollTop; }, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Получаем записи (они уже приходят отсортированные: новые в начале)
|
// Получаем записи (они уже приходят отсортированные: новые в начале)
|
||||||
const entries: { id: string; content: string }[] = this.activeTab === 'res1' ? data.response1 : data.response2;
|
const entries: { id: string; content: string }[] = this.activeTab === 'res1' ? data.response1 : data.response2;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user