Browse Source

feat: add model and vocabulary settings

master
Yutsuo 4 days ago
parent
commit
974a2e6029
  1. 27
      src/voice_transcriptor/ui/settings_dialog.py
  2. 10
      tests/ui/test_settings_dialog.py

27
src/voice_transcriptor/ui/settings_dialog.py

@ -10,11 +10,13 @@ from PySide6.QtWidgets import (
QDialog,
QDialogButtonBox,
QCheckBox,
QComboBox,
QFileDialog,
QFormLayout,
QHBoxLayout,
QLineEdit,
QMessageBox,
QPlainTextEdit,
QPushButton,
QSpinBox,
QToolButton,
@ -24,7 +26,17 @@ from PySide6.QtWidgets import (
from voice_transcriptor.models import AppSettings
from voice_transcriptor.services.credentials import CredentialError, CredentialService
from voice_transcriptor.services.settings import SettingsError, SettingsRepository
from voice_transcriptor.services.settings import SUPPORTED_MODEL_SUGGESTIONS, SettingsError, SettingsRepository
class EditableModelCombo(QComboBox):
"""Editable model picker with the previous line-edit convenience API."""
def text(self) -> str:
return self.currentText()
def setText(self, value: str) -> None:
self.setCurrentText(value)
class SettingsDialog(QDialog):
@ -44,7 +56,10 @@ class SettingsDialog(QDialog):
self._credentials = credentials
self.setWindowTitle("Settings")
self.model_input = QLineEdit(settings.model, self)
self.model_input = EditableModelCombo(self)
self.model_input.setEditable(True)
self.model_input.addItems(SUPPORTED_MODEL_SUGGESTIONS)
self.model_input.setCurrentText(settings.model)
self.model_input.setObjectName("modelInput")
self.language_input = QLineEdit(settings.language, self)
self.language_input.setObjectName("languageInput")
@ -53,6 +68,9 @@ class SettingsDialog(QDialog):
self.api_key_input.setEchoMode(QLineEdit.EchoMode.Password)
self.output_directory_input = QLineEdit(str(settings.output_directory), self)
self.output_directory_input.setObjectName("outputDirectoryInput")
self.context_input = QPlainTextEdit(settings.context_vocabulary, self)
self.context_input.setObjectName("contextVocabularyInput")
self.context_input.setPlaceholderText("Names, acronyms, technical terms, and conversation context")
self.choose_directory_button = QPushButton("Browse…", self)
self.choose_directory_button.setObjectName("chooseDirectoryButton")
self.choose_directory_button.clicked.connect(self.choose_output_directory)
@ -65,6 +83,7 @@ class SettingsDialog(QDialog):
form.addRow("OpenAI API key", self.api_key_input)
form.addRow("Model", self.model_input)
form.addRow("Language", self.language_input)
form.addRow("Context / Vocabulary", self.context_input)
form.addRow("Output directory", output_directory_layout)
self.advanced_toggle = QToolButton(self)
@ -133,7 +152,7 @@ class SettingsDialog(QDialog):
)
return
model = self.model_input.text().strip()
model = self.model_input.currentText().strip()
language = self.language_input.text().strip()
if not model or not language:
QMessageBox.warning(self, "Invalid settings", "Model and language are required.")
@ -146,7 +165,7 @@ class SettingsDialog(QDialog):
return
updated_settings = AppSettings(
model, language, output_directory, chunk_duration, overlap,
self.retain_temporary_files_input.isChecked(),
self.retain_temporary_files_input.isChecked(), self.context_input.toPlainText().strip(),
)
try:
self._repository.save(updated_settings)

10
tests/ui/test_settings_dialog.py

@ -3,11 +3,12 @@ from __future__ import annotations
from pathlib import Path
import pytest
from PySide6.QtWidgets import QLineEdit, QMessageBox
from PySide6.QtWidgets import QComboBox, QLineEdit, QMessageBox
from voice_transcriptor.models import AppSettings
from voice_transcriptor.services.credentials import CredentialError
from voice_transcriptor.services.settings import SettingsError
from voice_transcriptor.services.settings import SUPPORTED_MODEL_SUGGESTIONS
from voice_transcriptor.ui.settings_dialog import SettingsDialog
@ -53,6 +54,10 @@ def test_populates_fields_from_settings(qtbot, settings: AppSettings) -> None:
assert dialog.advanced_panel.isVisible() is False
assert dialog.chunk_duration_input.value() == 900
assert dialog.chunk_overlap_input.value() == 15
assert isinstance(dialog.model_input, QComboBox)
assert dialog.model_input.isEditable()
assert tuple(dialog.model_input.itemText(i) for i in range(dialog.model_input.count())) == SUPPORTED_MODEL_SUGGESTIONS
assert dialog.context_input.toPlainText() == settings.context_vocabulary
def test_advanced_settings_are_saved(qtbot, settings: AppSettings) -> None:
@ -98,10 +103,11 @@ def test_save_persists_new_api_key_and_emits_saved_settings(qtbot, settings: App
dialog.api_key_input.setText(supplied_key)
dialog.model_input.setText("gpt-4o-mini-transcribe")
dialog.context_input.setPlainText("Pix, Banco do Brasil")
dialog.save()
assert saved_with.args == [
AppSettings("gpt-4o-mini-transcribe", "pt-BR", settings.output_directory)
AppSettings("gpt-4o-mini-transcribe", "pt-BR", settings.output_directory, context_vocabulary="Pix, Banco do Brasil")
]
assert credentials.api_key == supplied_key
assert repository.saved == saved_with.args

Loading…
Cancel
Save