Let the cleanup model be told how hard to think

This commit is contained in:
yusufipk
2026-07-26 23:14:06 +07:00
parent e3e678a0f2
commit 32e0fb061d
8 changed files with 48 additions and 3 deletions
+2 -1
View File
@@ -37,7 +37,8 @@ runs on either one (`gpt-4o-transcribe` by default), cleanup always on
OpenRouter (`google/gemini-3.5-flash-lite`), so a single OpenRouter key can
cover both. They fall back to `OPENAI_API_KEY` and `OPENROUTER_API_KEY`, and are
stored in `~/.config/dikte/config.json`, mode 600. Cleanup can be switched off,
in which case the raw transcript is pasted.
in which case the raw transcript is pasted, and a thinking model's effort can be
set next to it.
## Using it
+1 -1
View File
@@ -38,7 +38,7 @@ temizleme her zaman OpenRouter'da (`google/gemini-3.5-flash-lite`), yani tek bir
OpenRouter anahtarı ikisine de yeter. Boş bırakırsan `OPENAI_API_KEY` ve
`OPENROUTER_API_KEY` kullanılır; anahtarlar `~/.config/dikte/config.json`
içinde, izinler 600. Temizlemeyi tamamen kapatabilirsin, o zaman ham transkript
yapıştırılır.
yapıştırılır; modelin yanındaki kutudan düşünme seviyesini de seçebilirsin.
## Kullanım
+7 -1
View File
@@ -173,7 +173,8 @@ def transcribe_segments(target, wav_path, language="", prompt="", timeout=300):
return out
def cleanup(text, api_key, model, system_prompt, base_url=OPENROUTER_URL, timeout=180):
def cleanup(text, api_key, model, system_prompt, reasoning="",
base_url=OPENROUTER_URL, timeout=180):
if not api_key:
raise ApiError(t("{service} API key is empty. Add it in Settings.",
service="OpenRouter"))
@@ -185,6 +186,11 @@ def cleanup(text, api_key, model, system_prompt, base_url=OPENROUTER_URL, timeou
{"role": "user", "content": f"<transcript>\n{text}\n</transcript>"},
],
}
# An empty level means "whatever the model does on its own"; anything else is
# one of OpenRouter's efforts. The thinking itself is never shown, so ask for
# it to be left out of the reply.
if reasoning:
payload["reasoning"] = {"effort": reasoning, "exclude": True}
try:
data = _request(
f"{base_url.rstrip('/')}/chat/completions",
+1
View File
@@ -116,6 +116,7 @@ DEFAULTS = {
"transcribe_prompt": "",
"cleanup_enabled": True,
"cleanup_model": "google/gemini-3.5-flash-lite",
"cleanup_reasoning": "", # empty -> whatever the model does by default
"cleanup_prompt": "", # empty -> language-specific default
"auto_paste": True,
"paste_shortcut": "ctrl+v",
+1
View File
@@ -135,6 +135,7 @@ class FileTranscriber(QObject):
conf.openrouter_key(),
conf["cleanup_model"],
prompt,
reasoning=conf["cleanup_reasoning"],
base_url=conf["openrouter_base_url"],
))
return ("\n" if timestamps else "\n\n").join(out)
+15
View File
@@ -158,6 +158,21 @@ TR = {
"Connection works. {count} audio models visible.":
"Bağlantı tamam. {count} ses modeli görünüyor.",
"Clean the transcript with a model": "Transkripti bir modelle temizle",
"Thinking": "Düşünme",
"Model's own default": "Modelin kendi varsayılanı",
"Off": "Kapalı",
"Minimal": "En az",
"Low": "Düşük",
"Medium": "Orta",
"High": "Yüksek",
"Very high": "Çok yüksek",
"Maximum": "En yüksek",
"How long a thinking model may reason before it answers. Cleanup is a light "
"job, so more thinking mostly costs time and tokens. Models that cannot "
"think ignore this.":
"Düşünebilen bir modelin yanıtlamadan önce ne kadar düşüneceği. Temizleme "
"hafif bir iş, fazla düşünmenin çoğunlukla getirisi süre ve token. "
"Düşünemeyen modeller bunu yok sayar.",
"Fetch model list": "Model listesini çek",
"Fetching model list…": "Model listesi çekiliyor…",
"Could not fetch the list: {error}": "Liste alınamadı: {error}",
+20
View File
@@ -43,6 +43,13 @@ CLEANUP_MODELS = [
"google/gemini-2.5-flash-lite", "anthropic/claude-haiku-4.5",
"openai/gpt-5-mini", "meta-llama/llama-3.3-70b-instruct",
]
# How hard the cleanup model may think before it answers, in OpenRouter's own
# effort levels. A model that ignores the field simply answers as it always did.
REASONING_LEVELS = [
("Model's own default", ""), ("Off", "none"), ("Minimal", "minimal"),
("Low", "low"), ("Medium", "medium"), ("High", "high"),
("Very high", "xhigh"), ("Maximum", "max"),
]
PASTE_SHORTCUTS = ["ctrl+v", "ctrl+shift+v", "shift+insert"]
AUDIO_FILTER = ("*.mp3 *.wav *.m4a *.ogg *.opus *.flac *.aac *.wma "
"*.mp4 *.mkv *.webm *.mov *.avi")
@@ -231,6 +238,17 @@ class SettingsWindow(QDialog):
self.refresh_models = QPushButton(t("Fetch model list"))
self.refresh_models.clicked.connect(self._load_models)
orr_form.addRow(t("Model"), self._row(self.cleanup_model, self.refresh_models))
self.cleanup_reasoning = QComboBox()
for label, value in REASONING_LEVELS:
self.cleanup_reasoning.addItem(t(label), value)
self.cleanup_reasoning.setToolTip(
t("How long a thinking model may reason before it answers. Cleanup is "
"a light job, so more thinking mostly costs time and tokens. Models "
"that cannot think ignore this.")
)
orr_form.addRow(t("Thinking"), self.cleanup_reasoning)
self.models_label = QLabel(t("Runs on OpenRouter."))
self.models_label.setWordWrap(True)
orr_form.addRow(self.models_label)
@@ -456,6 +474,7 @@ class SettingsWindow(QDialog):
self._provider_changed() # selecting index 0 fires no signal
self.cleanup_enabled.setChecked(conf["cleanup_enabled"])
self.cleanup_model.setCurrentText(conf["cleanup_model"])
self._select_data(self.cleanup_reasoning, conf["cleanup_reasoning"])
self.cleanup_prompt.setPlainText(conf["cleanup_prompt"] or cfg.default_cleanup_prompt())
self.transcribe_prompt.setPlainText(conf["transcribe_prompt"])
@@ -498,6 +517,7 @@ class SettingsWindow(QDialog):
conf["cleanup_enabled"] = self.cleanup_enabled.isChecked()
conf["cleanup_model"] = self.cleanup_model.currentText().strip()
conf["cleanup_reasoning"] = self.cleanup_reasoning.currentData() or ""
# Store an empty prompt when it matches the default, so switching the
# interface language also switches the prompt language.
+1
View File
@@ -83,6 +83,7 @@ class Pipeline(QObject):
conf.openrouter_key(),
conf["cleanup_model"],
conf.cleanup_prompt(),
reasoning=conf["cleanup_reasoning"],
base_url=conf["openrouter_base_url"],
)
except api.ApiError as exc: