Move Whisper device/compute into Engines→STT; add LLM Type (local/cloud)

- Local-Whisper Device + Compute type now live under the STT engine section
  ("Local engine — device & precision"), removed from the General tab. The
  local engine's Model field shows the effective whisper size.
- LLM engines gain a Type field (local | cloud), mirroring STT, stored in config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mARTin-B78 2026-06-05 09:48:26 +02:00
parent 78350bdb99
commit f1ee4bd4c5
3 changed files with 17 additions and 11 deletions

View File

@ -199,6 +199,7 @@ def load(path: Path = CONFIG_PATH) -> Config:
model=e.get("model", "gpt-4o-mini"),
api_key_env=e.get("api_key_env", ""),
temperature=float(e.get("temperature", cfg.temperature)),
type=e.get("type", "cloud"),
)
for e in data.get("llm_engine", [])
] or [LLMEngine("Default", cfg.base_url, cfg.rewrite_model, cfg.api_key_env, cfg.temperature)]
@ -266,7 +267,7 @@ def save(cfg: Config, path: Path = CONFIG_PATH) -> None:
],
"llm": {"active": cfg.llm_active},
"llm_engine": [
{"name": e.name, "url": e.url, "model": e.model,
{"name": e.name, "type": e.type, "url": e.url, "model": e.model,
"api_key_env": e.api_key_env, "temperature": e.temperature}
for e in cfg.llm_engines
],
@ -390,6 +391,7 @@ active = "Default"
[[llm_engine]]
name = "Default"
type = "cloud" # "local" | "cloud"
url = "https://api.openai.com/v1"
model = "gpt-4o-mini"
api_key_env = "OPENAI_API_KEY"
@ -397,6 +399,7 @@ temperature = 0.3
# [[llm_engine]]
# name = "Local llama-swap"
# type = "local"
# url = "http://localhost:28080/v1"
# model = "Qwen3.5-4B"
# api_key_env = ""

View File

@ -344,6 +344,12 @@ class SettingsDialog:
self.stt_url.connect("changed", lambda _e: self._schedule_models("stt"))
self.stt_key.connect("changed", lambda _e: self._schedule_models("stt"))
self.stt_type.connect("changed", self._stt_type_changed)
sep = Gtk.Separator(); sep.set_margin_top(4); form.pack_start(sep, False, False, 4)
form.pack_start(Gtk.Label(label="Local engine (faster-whisper) — device & precision", xalign=0.0), False, False, 0)
self.stt_device = _labeled(form, "Device", _combo(["auto", "cpu", "cuda"], self.cfg.device))
self.stt_compute = _labeled(form, "Compute type", _combo(["auto", "int8", "float16", "int8_float16"], self.cfg.compute_type))
self.stt_result = Gtk.Label(xalign=0.0); self.stt_result.set_line_wrap(True)
box.pack_start(self.stt_result, False, False, 2)
self._stt_load(self.stt_combo.get_active())
@ -368,6 +374,7 @@ class SettingsDialog:
box.pack_start(bar, False, False, 2)
form = Gtk.Box(orientation=Gtk.Orientation.VERTICAL); box.pack_start(form, False, False, 2)
self.llm_type = _labeled(form, "Type", _combo(["local", "cloud"]))
self.llm_url = _url_field(form, "Base URL", "http://localhost:28080/v1 · https://api.openai.com/v1",
lambda: self._populate_models(self.llm_model, self.llm_url.get_text().strip(), self.llm_key.get_text().strip()))
self.llm_model = _labeled(form, "Model", _model_combo("pick after entering URL"))
@ -386,7 +393,7 @@ class SettingsDialog:
self.stt_type.set_active(["local", "openai"].index(e.type) if e.type in ("local", "openai") else 0)
self.stt_url.set_text(e.url); self.stt_key.set_text(e.api_key_env)
if e.type == "local":
_fill_combo(self.stt_model, ["tiny", "base", "small", "medium", "large-v3"], e.model)
_fill_combo(self.stt_model, ["tiny", "base", "small", "medium", "large-v3"], e.model or self.cfg.model)
else:
_fill_combo(self.stt_model, [], e.model)
self._populate_models(self.stt_model, e.url, e.api_key_env)
@ -450,6 +457,7 @@ class SettingsDialog:
if not (0 <= idx < len(self.cfg.llm_engines)):
return
e = self.cfg.llm_engines[idx]
self.llm_type.set_active(["local", "cloud"].index(e.type) if e.type in ("local", "cloud") else 1)
self.llm_url.set_text(e.url)
self.llm_key.set_text(e.api_key_env); self.llm_temp.set_text(str(e.temperature))
_fill_combo(self.llm_model, [], e.model)
@ -461,6 +469,7 @@ class SettingsDialog:
if not (0 <= idx < len(self.cfg.llm_engines)):
return
e = self.cfg.llm_engines[idx]
e.type = self.llm_type.get_active_text() or "cloud"
e.url = self.llm_url.get_text().strip().rstrip("/")
e.model = _combo_text(self.llm_model)
e.api_key_env = self.llm_key.get_text().strip()
@ -609,12 +618,6 @@ class SettingsDialog:
_labeled(page, "Notifications", self.gen_notify)
self.gen_boot = Gtk.Switch(); self.gen_boot.set_active(autostart.is_enabled()); self.gen_boot.set_halign(Gtk.Align.START)
_labeled(page, "Launch on login", self.gen_boot)
page.pack_start(Gtk.Separator(), False, False, 8)
page.pack_start(Gtk.Label(label="Local Whisper (for the local STT engine)", xalign=0.0), False, False, 2)
self.gen_model = _labeled(page, "Model", _entry(self.cfg.model))
self.gen_device = _labeled(page, "Device", _combo(["auto", "cpu", "cuda"], self.cfg.device))
self.gen_compute = _labeled(page, "Compute type", _combo(["auto", "int8", "float16", "int8_float16"], self.cfg.compute_type))
self._start_meter()
def _selected_mic_name(self) -> str:
@ -700,9 +703,8 @@ class SettingsDialog:
c.output = self.gen_output.get_active_text() or "type"
c.language = self.gen_lang.get_text().strip()
c.notify = self.gen_notify.get_active()
c.model = self.gen_model.get_text().strip()
c.device = self.gen_device.get_active_text() or "auto"
c.compute_type = self.gen_compute.get_active_text() or "auto"
c.device = self.stt_device.get_active_text() or "auto"
c.compute_type = self.stt_compute.get_active_text() or "auto"
autostart.set_enabled(self.gen_boot.get_active())
except ValueError as exc:
self._error(f"Check numeric fields: {exc}")

View File

@ -24,6 +24,7 @@ class LLMEngine:
model: str = "gpt-4o-mini"
api_key_env: str = "OPENAI_API_KEY"
temperature: float = 0.3
type: str = "cloud" # "local" | "cloud" (label/category)
@property
def api_key(self) -> str | None: