engines: Test button inline with result + selectable; benchmark: persist WAV/ref paths (v2.0.7)
- Engines tab: move Test button out of the toolbar, place it in a row directly beside the result label so button and output are co-located; result label is now selectable so error text can be copied - Benchmark tab: add bench_wav/bench_ref/bench_expand_models to Config; file pickers restore last-used paths on open; any change (file-set, toggle, or Run) writes directly to cfg so paths survive without Save; [benchmark] section written to config.toml on Save Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1c16cfeb0f
commit
5458fdc1eb
@ -6,4 +6,4 @@ counterpart to the macOS Blitztext menu bar app: it runs natively on the host
|
||||
(not in a container) so it can type into any application via xdotool.
|
||||
"""
|
||||
|
||||
__version__ = "2.0.6"
|
||||
__version__ = "2.0.7"
|
||||
|
||||
@ -120,6 +120,10 @@ class Config:
|
||||
# Wakeword engines to compare in the benchmark (each a wyoming-openwakeword
|
||||
# endpoint). Empty → the benchmark falls back to the live [wakeword] above.
|
||||
wakeword_engines: list[WakewordEngine] = field(default_factory=list)
|
||||
# STT benchmark: last-used WAV / reference transcript paths and options
|
||||
bench_wav: str = ""
|
||||
bench_ref: str = ""
|
||||
bench_expand_models: bool = False
|
||||
# workflows
|
||||
workflows: list[Workflow] = field(default_factory=list)
|
||||
|
||||
@ -236,6 +240,9 @@ def load(path: Path = CONFIG_PATH) -> Config:
|
||||
tts_api_key_env=tts.get("api_key_env", ""),
|
||||
tts_model=tts.get("model", ""),
|
||||
tts_voices=list(tts.get("voices", ["alloy", "echo", "fable", "onyx", "nova", "shimmer"])),
|
||||
bench_wav=data.get("benchmark", {}).get("wav", ""),
|
||||
bench_ref=data.get("benchmark", {}).get("ref", ""),
|
||||
bench_expand_models=bool(data.get("benchmark", {}).get("expand_models", False)),
|
||||
)
|
||||
|
||||
for entry in data.get("workflow", []):
|
||||
@ -371,6 +378,11 @@ def save(cfg: Config, path: Path = CONFIG_PATH) -> None:
|
||||
"model": cfg.tts_model,
|
||||
"voices": cfg.tts_voices,
|
||||
},
|
||||
"benchmark": {
|
||||
"wav": cfg.bench_wav,
|
||||
"ref": cfg.bench_ref,
|
||||
"expand_models": cfg.bench_expand_models,
|
||||
},
|
||||
"wakeword_engine": [
|
||||
{"name": e.name, "uri": e.uri, "model": e.model} for e in cfg.wakeword_engines
|
||||
],
|
||||
|
||||
@ -1146,9 +1146,8 @@ notebook.bt-nb tab:checked label {
|
||||
qs.set_tooltip_text("Fill the form from a common service template")
|
||||
qs.connect("clicked", self._show_stt_templates)
|
||||
bar.pack_start(qs, False, False, 0)
|
||||
# Right: actions
|
||||
# Right: actions (Test moved to its own row below the config)
|
||||
for label, cb, tip in (
|
||||
("Test", self._stt_test, "Record 4 s and transcribe to test this engine"),
|
||||
("Delete", self._stt_delete, "Remove this engine preset"),
|
||||
("⟳", lambda _b: self._refresh_status(), "Re-check connection status"),
|
||||
):
|
||||
@ -1185,8 +1184,19 @@ notebook.bt-nb tab:checked label {
|
||||
tooltip="Precision of the model. int8 is fastest and uses least memory. "
|
||||
"float16 is most accurate. Auto lets Blitztext decide.")
|
||||
|
||||
self.stt_result = Gtk.Label(xalign=0.0); self.stt_result.set_line_wrap(True)
|
||||
box.pack_start(self.stt_result, False, False, 2)
|
||||
test_row = Gtk.Box(spacing=10)
|
||||
test_row.set_margin_top(6)
|
||||
stt_test_btn = Gtk.Button(label="Test")
|
||||
stt_test_btn.set_tooltip_text("Record 4 s and transcribe to test this engine")
|
||||
stt_test_btn.connect("clicked", self._stt_test)
|
||||
stt_test_btn.set_valign(Gtk.Align.START)
|
||||
test_row.pack_start(stt_test_btn, False, False, 0)
|
||||
self.stt_result = Gtk.Label(xalign=0.0)
|
||||
self.stt_result.set_line_wrap(True)
|
||||
self.stt_result.set_selectable(True)
|
||||
self.stt_result.set_valign(Gtk.Align.START)
|
||||
test_row.pack_start(self.stt_result, True, True, 0)
|
||||
box.pack_start(test_row, False, False, 2)
|
||||
self._stt_load(self.stt_combo.get_active())
|
||||
return box
|
||||
|
||||
@ -1842,17 +1852,31 @@ notebook.bt-nb tab:checked label {
|
||||
ft = Gtk.FileFilter(); ft.set_name("Text (.txt)"); ft.add_pattern("*.txt"); reff.add_filter(ft)
|
||||
self.bench_ref = _labeled(page, "Reference (.txt)", reff)
|
||||
|
||||
# Restore saved paths
|
||||
if self.cfg.bench_wav and Path(self.cfg.bench_wav).exists():
|
||||
wavf.set_filename(self.cfg.bench_wav)
|
||||
if self.cfg.bench_ref and Path(self.cfg.bench_ref).exists():
|
||||
reff.set_filename(self.cfg.bench_ref)
|
||||
|
||||
def _on_wav_set(_b):
|
||||
fn = wavf.get_filename()
|
||||
if not fn: return
|
||||
self.cfg.bench_wav = fn
|
||||
p = Path(fn)
|
||||
for ext in (".reference.txt", ".txt"):
|
||||
cand = p.with_name(p.stem + ext)
|
||||
if cand.exists():
|
||||
reff.set_filename(str(cand))
|
||||
self.cfg.bench_ref = str(cand)
|
||||
break
|
||||
wavf.connect("file-set", _on_wav_set)
|
||||
|
||||
def _on_ref_set(_b):
|
||||
fn = reff.get_filename()
|
||||
if fn:
|
||||
self.cfg.bench_ref = fn
|
||||
reff.connect("file-set", _on_ref_set)
|
||||
|
||||
run_row = Gtk.Box(spacing=16)
|
||||
run_row.set_margin_bottom(2)
|
||||
run = Gtk.Button(label="Run benchmark"); run.connect("clicked", self._run_bench)
|
||||
@ -1862,6 +1886,9 @@ notebook.bt-nb tab:checked label {
|
||||
self.bench_expand.set_tooltip_text(
|
||||
"Fetch every available model from each remote engine and run a separate "
|
||||
"benchmark row per model — useful to compare models on the same server.")
|
||||
self.bench_expand.set_active(self.cfg.bench_expand_models)
|
||||
self.bench_expand.connect("toggled",
|
||||
lambda cb: setattr(self.cfg, "bench_expand_models", cb.get_active()))
|
||||
run_row.pack_start(self.bench_expand, False, False, 0)
|
||||
page.pack_start(run_row, False, False, 6)
|
||||
|
||||
@ -1945,6 +1972,11 @@ notebook.bt-nb tab:checked label {
|
||||
def _run_bench(self, _b) -> None:
|
||||
wav = self.bench_wav.get_filename()
|
||||
refp = self.bench_ref.get_filename()
|
||||
# Persist immediately so paths survive without clicking Save
|
||||
if wav:
|
||||
self.cfg.bench_wav = wav
|
||||
if refp:
|
||||
self.cfg.bench_ref = refp
|
||||
if not wav or not refp:
|
||||
self._error("Pick a .wav file and a matching reference .txt file.")
|
||||
return
|
||||
|
||||
Loading…
Reference in New Issue
Block a user