mirror of
https://github.com/lllin000/PaperForge.git
synced 2026-07-22 06:50:53 +00:00
feat(plugin): live terminal output + model descriptions + uninstall model button
This commit is contained in:
parent
121a2d9145
commit
cecfe3d0cc
1 changed files with 56 additions and 14 deletions
|
|
@ -2911,8 +2911,14 @@ class PaperForgeSettingTab extends PluginSettingTab {
|
|||
|
||||
// Model selector (local mode)
|
||||
if (this.plugin.settings.vector_db_mode === 'local') {
|
||||
const modelDesc = {
|
||||
'BAAI/bge-small-en-v1.5': 'Best balance — fast, accurate, recommended for most users (384d, 130MB)',
|
||||
'sentence-transformers/all-MiniLM-L6-v2': 'Lightest & fastest — lower accuracy, minimal disk (384d, 80MB)',
|
||||
'BAAI/bge-base-en-v1.5': 'Highest accuracy — slower, large disk footprint (768d, 440MB)',
|
||||
};
|
||||
new Setting(containerEl)
|
||||
.setName('Model')
|
||||
.setDesc(modelDesc[this.plugin.settings.vector_db_model] || '')
|
||||
.addDropdown(dropdown => {
|
||||
dropdown.addOption('BAAI/bge-small-en-v1.5', 'bge-small (384d, 130MB)');
|
||||
dropdown.addOption('sentence-transformers/all-MiniLM-L6-v2', 'MiniLM (384d, 80MB)');
|
||||
|
|
@ -2923,6 +2929,31 @@ class PaperForgeSettingTab extends PluginSettingTab {
|
|||
this.plugin.saveSettings();
|
||||
this.display();
|
||||
});
|
||||
})
|
||||
.addButton(button => {
|
||||
button.setButtonText('Uninstall')
|
||||
.setWarning()
|
||||
.onClick(async () => {
|
||||
const model = this.plugin.settings.vector_db_model;
|
||||
const cacheName = 'models--' + model.replace('/', '--');
|
||||
button.setButtonText('Removing...');
|
||||
button.setDisabled(true);
|
||||
try {
|
||||
const pyResult = resolvePythonExecutable(vp, this.plugin.settings);
|
||||
const { exec } = require('child_process');
|
||||
const env = Object.assign({}, process.env, { PYTHONIOENCODING: 'utf-8', PYTHONUTF8: '1' });
|
||||
await new Promise((resolve, reject) => {
|
||||
exec(`"${pyResult.path}" -c "import shutil, os,sys; p=os.path.join(os.path.expanduser('~/.cache/huggingface/hub'), '${cacheName}'); shutil.rmtree(p,ignore_errors=True); print('Removed' if os.path.exists(p) else 'Not cached')"`, {
|
||||
encoding: 'utf-8', timeout: 30000, env: env
|
||||
}, (error, stdout) => error ? reject(error) : resolve(stdout));
|
||||
});
|
||||
new Notice('Model cache removed.');
|
||||
} catch (e) {
|
||||
new Notice('Failed: ' + (e.stderr || e.message || e));
|
||||
}
|
||||
button.setButtonText('Uninstall');
|
||||
button.setDisabled(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2967,7 +2998,10 @@ class PaperForgeSettingTab extends PluginSettingTab {
|
|||
});
|
||||
}
|
||||
|
||||
// Rebuild button
|
||||
// Rebuild button with live terminal output
|
||||
const terminalEl = containerEl.createEl('pre');
|
||||
terminalEl.style.cssText = 'display:none; background:#1e1e1e; color:#d4d4d4; padding:10px; border-radius:4px; max-height:300px; overflow-y:auto; font-size:11px; font-family:var(--font-monospace); margin:8px 0; white-space:pre-wrap; word-break:break-all;';
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Rebuild Vectors')
|
||||
.setDesc(modelChanged ? 'Model changed — rebuild to update all vectors.' : 'Rebuild all OCR fulltext vectors. Required after model or mode change.')
|
||||
|
|
@ -2980,29 +3014,37 @@ class PaperForgeSettingTab extends PluginSettingTab {
|
|||
if (!pyResult.path) { new Notice('No Python found.'); return; }
|
||||
button.setButtonText('Building...');
|
||||
button.setDisabled(true);
|
||||
const notice = new Notice('Building vector index...', 0);
|
||||
terminalEl.style.display = 'block';
|
||||
terminalEl.setText('');
|
||||
|
||||
const { spawn } = require('child_process');
|
||||
const env = Object.assign({}, process.env, { PYTHONIOENCODING: 'utf-8', PYTHONUTF8: '1' });
|
||||
const child = spawn(pyResult.path, ['-m', 'paperforge', '--vault', vp, 'embed', 'build', '--force'], {
|
||||
env: env, stdio: ['ignore', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
const append = (text) => {
|
||||
terminalEl.setText((terminalEl.getText() || '') + text);
|
||||
terminalEl.scrollTop = terminalEl.scrollHeight;
|
||||
};
|
||||
|
||||
child.stdout.on('data', (data) => append(data.toString()));
|
||||
child.stderr.on('data', (data) => append(data.toString()));
|
||||
|
||||
try {
|
||||
const { exec } = require('child_process');
|
||||
const env = Object.assign({}, process.env, { PYTHONIOENCODING: 'utf-8', PYTHONUTF8: '1' });
|
||||
await new Promise((resolve, reject) => {
|
||||
const cmd = `"${pyResult.path}" -m paperforge --vault "${vp}" embed build --force`;
|
||||
exec(cmd, { encoding: 'utf-8', timeout: 600000, env: env }, (error, stdout) => {
|
||||
if (error) reject(error);
|
||||
else resolve(stdout);
|
||||
});
|
||||
child.on('close', (code) => code === 0 ? resolve() : reject(new Error('Exit code ' + code)));
|
||||
child.on('error', reject);
|
||||
});
|
||||
// Remember model used for this build
|
||||
this.plugin.settings.vector_db_last_model = currentModel;
|
||||
this.plugin.saveSettings();
|
||||
// Refresh status
|
||||
this._embedStatusText = null;
|
||||
this._execEmbedStatus(pyResult.path, vp, (text) => { this._embedStatusText = text; });
|
||||
notice.hide();
|
||||
new Notice('Vector build complete.');
|
||||
this.display();
|
||||
} catch (e) {
|
||||
notice.hide();
|
||||
new Notice('Build failed: ' + (e.stderr || e.message || e));
|
||||
append('\n--- BUILD FAILED ---\n' + (e.stderr || e.message || e));
|
||||
new Notice('Build failed. See terminal output.');
|
||||
button.setButtonText(label);
|
||||
button.setDisabled(false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue