summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-05-30 13:32:36 -0700
committeryum <yum.food.vr@gmail.com>2025-05-30 13:34:23 -0700
commit7fb9c575aea4d318e9c14b82174d1b323171b62b (patch)
tree8f924a32def3bdc963be40e67879887cbac68f08 /ui
parente1b3f638a1ea448de9691f69eb62ebf4c3944c9f (diff)
More stuff
- fix unicode output from python terminal - fix cpu inference - add filters - add beam search params to UI - DRY up config definition in UI
Diffstat (limited to 'ui')
-rw-r--r--ui/config-schema.js49
-rw-r--r--ui/index.html52
-rw-r--r--ui/index.js49
-rw-r--r--ui/renderer.js31
4 files changed, 125 insertions, 56 deletions
diff --git a/ui/config-schema.js b/ui/config-schema.js
new file mode 100644
index 0000000..b1108ff
--- /dev/null
+++ b/ui/config-schema.js
@@ -0,0 +1,49 @@
+// Shared configuration schema with types and defaults
+const CONFIG_SCHEMA = {
+ // String fields
+ compute_type: { type: 'select', default: 'float16' },
+ language: { type: 'select', default: 'english' },
+ model: { type: 'select', default: 'turbo' },
+ microphone: { type: 'number', default: 0 },
+ user_prompt: { type: 'text', default: 'Use proper punctuation and grammar. Prefer spelled out numbers like one, eleven, twenty, etc. Mm.' },
+
+ // Number fields
+ gpu_idx: { type: 'number', default: 0 },
+ max_speech_duration_s: { type: 'number', default: 10 },
+ min_silence_duration_ms: { type: 'number', default: 250 },
+ reset_after_silence_s: { type: 'number', default: 15 },
+ transcription_loop_delay_ms: { type: 'number', default: 100 },
+ block_width: { type: 'number', default: 2 },
+ num_blocks: { type: 'number', default: 40 },
+ rows: { type: 'number', default: 10 },
+ cols: { type: 'number', default: 24 },
+ beam_size: { type: 'number', default: 5 },
+ best_of: { type: 'number', default: 5 },
+
+ // Boolean fields (stored as 1/0)
+ enable_debug_mode: { type: 'boolean', default: 0 },
+ enable_previews: { type: 'boolean', default: 1 },
+ save_audio: { type: 'boolean', default: 0 },
+ use_cpu: { type: 'boolean', default: 0 },
+ enable_lowercase_filter: { type: 'boolean', default: 0 },
+ enable_uppercase_filter: { type: 'boolean', default: 0 },
+ enable_profanity_filter: { type: 'boolean', default: 0 },
+ remove_trailing_period: { type: 'boolean', default: 0 }
+};
+
+// Helper to extract just the default values
+function getDefaultConfig() {
+ const defaults = {};
+ for (const [key, schema] of Object.entries(CONFIG_SCHEMA)) {
+ defaults[key] = schema.default;
+ }
+ return defaults;
+}
+
+// Export for both CommonJS (main process) and ES modules (renderer)
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = { CONFIG_SCHEMA, getDefaultConfig };
+} else {
+ window.CONFIG_SCHEMA = CONFIG_SCHEMA;
+ window.getDefaultConfig = getDefaultConfig;
+} \ No newline at end of file
diff --git a/ui/index.html b/ui/index.html
index 90f78c1..97da3d2 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -10,9 +10,9 @@
<div class="container-fluid px-6 py-6 h-screen flex flex-col">
<div class="flex flex-1 gap-6 overflow-hidden">
<!-- Left Panel: Configuration Form -->
- <div class="max-w-96 relative flex flex-col">
+ <div class="max-w-96 relative flex flex-col overflow-hidden rounded-lg">
<!-- Loading Overlay -->
- <div id="loading-overlay" class="absolute inset-0 bg-white bg-opacity-75 backdrop-blur-sm z-50 hidden flex items-center justify-center rounded-lg">
+ <div id="loading-overlay" class="absolute inset-0 bg-white bg-opacity-75 backdrop-blur-sm z-50 hidden flex items-center justify-center">
<div class="text-center p-6">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
<p class="text-gray-700 font-medium"></p>
@@ -126,7 +126,7 @@
<h2 class="section-title">Transcription Settings</h2>
<div>
<label for="user_prompt" class="form-label">
- Custom Prompt
+ Prompt
<span class="text-gray-500 text-xs block mt-1"
title="Whisper is given this prompt before transcribing. It helps guide the transcription style. For example, you could improve the spelling of your friends' names with: 'My friends' names are Saoirse, Azariah, and Caoimhe.'">
(Hover for details)
@@ -136,6 +136,28 @@
class="form-input h-20 resize-none"
placeholder="My friends' names are Saoirse, Azariah, and Caoimhe."></textarea>
</div>
+ <div class="grid grid-cols-2 gap-4 mt-4">
+ <div>
+ <label for="beam_size" class="form-label">
+ Beam size
+ <span class="text-gray-500 text-xs block mt-1"
+ title="Number of beams for beam search. Higher values may improve accuracy but increase compute time.">
+ (Search width)
+ </span>
+ </label>
+ <input type="number" id="beam_size" min="1" max="20" value="5" class="form-input">
+ </div>
+ <div>
+ <label for="best_of" class="form-label">
+ Best of
+ <span class="text-gray-500 text-xs block mt-1"
+ title="Number of candidates to generate when sampling. The best one will be selected.">
+ (Sampling candidates)
+ </span>
+ </label>
+ <input type="number" id="best_of" min="1" max="20" value="5" class="form-input">
+ </div>
+ </div>
</section>
<!-- Performance Settings -->
@@ -166,6 +188,29 @@
</div>
</section>
+ <!-- Text Filters -->
+ <section class="config-section">
+ <h2 class="section-title">Text Filters</h2>
+ <div class="space-y-3">
+ <label for="enable_lowercase_filter" class="checkbox-label">
+ <input type="checkbox" id="enable_lowercase_filter" class="mr-2">
+ <span class="checkbox-text">Convert to lowercase</span>
+ </label>
+ <label for="enable_uppercase_filter" class="checkbox-label">
+ <input type="checkbox" id="enable_uppercase_filter" class="mr-2">
+ <span class="checkbox-text">Convert to uppercase</span>
+ </label>
+ <label for="enable_profanity_filter" class="checkbox-label">
+ <input type="checkbox" id="enable_profanity_filter" class="mr-2">
+ <span class="checkbox-text">Filter profanity</span>
+ </label>
+ <label for="remove_trailing_period" class="checkbox-label">
+ <input type="checkbox" id="remove_trailing_period" class="mr-2">
+ <span class="checkbox-text">Remove trailing period</span>
+ </label>
+ </div>
+ </section>
+
<!-- Display Settings -->
<section class="config-section">
<h2 class="section-title">Custom Chatbox Settings</h2>
@@ -240,6 +285,7 @@
</div>
</div>
+ <script src="config-schema.js"></script>
<script src="renderer.js"></script>
</body>
</html>
diff --git a/ui/index.js b/ui/index.js
index 2420ece..7717c92 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -4,6 +4,7 @@ const fs = require('node:fs').promises;
const yaml = require('js-yaml');
const { spawn } = require('child_process');
const https = require('https');
+const { CONFIG_SCHEMA, getDefaultConfig } = require('./config-schema.js');
const APP_ROOT = path.join(__dirname, '..');
const CONFIG_PATH = path.join(APP_ROOT, 'config.yaml');
@@ -82,6 +83,14 @@ function downloadFile(url, outputPath) {
});
}
+function shouldFilterMessage(message) {
+ // Filter out pydub ffmpeg/avconv warning. It does not actually matter.
+ if (message.includes("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work")) {
+ return true;
+ }
+ return false;
+}
+
// Helper function to setup process event handlers
function setupProcessHandlers(process) {
process.stdout.on('data', (data) => {
@@ -91,7 +100,9 @@ function setupProcessHandlers(process) {
process.stderr.on('data', (data) => {
const text = data.toString();
- sendPythonOutput(text.trimEnd(), 'stderr');
+ if (!shouldFilterMessage(text)) {
+ sendPythonOutput(text.trimEnd(), 'stderr');
+ }
});
process.on('error', (error) => {
@@ -137,7 +148,10 @@ function executePythonCommand(args, options = {}) {
pythonProcess.stderr.on('data', (data) => {
const text = data.toString();
stderr += text;
- sendPythonOutput(text.trimEnd(), 'stderr');
+ // Filter out specific warning messages
+ if (!shouldFilterMessage(text)) {
+ sendPythonOutput(text.trimEnd(), 'stderr');
+ }
});
pythonProcess.on('error', (error) => {
@@ -171,27 +185,8 @@ function createWindow () {
mainWindow.loadFile('index.html');
}
-// Default configuration based on user's current config.yaml
-const DEFAULT_CONFIG = {
- compute_type: 'float16',
- enable_debug_mode: 0,
- enable_previews: 1,
- user_prompt: 'Use proper punctuation and grammar. Prefer spelled out numbers like one, eleven, twenty, etc.',
- save_audio: 0,
- language: 'english',
- gpu_idx: 0,
- max_speech_duration_s: 10,
- min_silence_duration_ms: 250,
- microphone: 0,
- model: 'turbo',
- reset_after_silence_s: 15,
- transcription_loop_delay_ms: 100,
- use_cpu: 0,
- block_width: 2,
- num_blocks: 40,
- rows: 10,
- cols: 24
-};
+// Replace the DEFAULT_CONFIG constant with:
+const DEFAULT_CONFIG = getDefaultConfig();
// IPC handlers
ipcMain.handle('load-config', async () => {
@@ -521,12 +516,12 @@ ipcMain.handle('start-process', async () => {
});
ipcMain.handle('stop-process', async () => {
- if (!runningProcess) {
- throw new Error('No process is running');
- }
-
return new Promise((resolve) => {
let forcefullyKilled = false;
+
+ if (!runningProcess) {
+ resolve({ success: true, forcefullyKilled });
+ }
// Set up a timeout to force kill after 10 seconds
const killTimeout = setTimeout(() => {
diff --git a/ui/renderer.js b/ui/renderer.js
index 201eef6..133a79b 100644
--- a/ui/renderer.js
+++ b/ui/renderer.js
@@ -1,29 +1,5 @@
-// Configuration and form field mappings
-const CONFIG_FIELDS = {
- // String fields
- compute_type: { type: 'select', default: 'float16' },
- language: { type: 'select', default: 'english' },
- model: { type: 'select', default: 'turbo' },
- microphone: { type: 'number', default: 0 },
- user_prompt: { type: 'text', default: '' },
-
- // Number fields
- gpu_idx: { type: 'number', default: 0 },
- max_speech_duration_s: { type: 'number', default: 10 },
- min_silence_duration_ms: { type: 'number', default: 250 },
- reset_after_silence_s: { type: 'number', default: 15 },
- transcription_loop_delay_ms: { type: 'number', default: 100 },
- block_width: { type: 'number', default: 2 },
- num_blocks: { type: 'number', default: 40 },
- rows: { type: 'number', default: 10 },
- cols: { type: 'number', default: 24 },
-
- // Boolean fields (stored as 1/0)
- enable_debug_mode: { type: 'boolean', default: 0 },
- enable_previews: { type: 'boolean', default: 1 },
- save_audio: { type: 'boolean', default: 0 },
- use_cpu: { type: 'boolean', default: 0 }
-};
+// Import configuration schema
+const CONFIG_FIELDS = window.CONFIG_SCHEMA;
// Button management system
class ButtonManager {
@@ -35,6 +11,9 @@ class ButtonManager {
resetVenv: document.getElementById('reset-venv'),
refreshMicrophones: document.getElementById('refresh-microphones')
};
+
+ // Initialize button states on construction
+ this.setProcessStopped();
}
setState(buttonName, disabled) {