Skip to content

Releases: kkdclaw/dictate

v0.15.0 — слои словаря под контекст

Choose a tag to compare

@kkdclaw kkdclaw released this 19 Aug 12:49

Слои словаря — свой набор терминов на приложение. У подсказки Whisper (initial_prompt) потолок ~210 токенов, и один словарь на все случаи занимает его целиком: в терминал уезжают названия систем бронирования, в переписку — launchd. Теперь словарь можно разложить по слоям: terms.d/<имя>.txt включается для конкретного приложения или как слой по умолчанию — устроено ровно как стили. Слой уходит в подсказку первым и вытесняет хвост общего словаря; дубли бюджет не тратят.

Тем же слоем пользуются системный промпт чистки и пост-контроль правок, поэтому активное приложение теперь выясняется до распознавания, а не после. В меню появилось подменю «Словарь терминов» (слой для приложения, слой по умолчанию, открыть слой и папку слоёв), в окне состояния — строка «Словарь»: сколько терминов и токенов реально ушло в подсказку. В лог к каждой диктовке дописывается активный слой.

A/B на синтезированной речи со слоем dev: «Давай сделаем push и commit на GitHub» вместо «push и comment», «перезапусти демон launchd» вместо «демон лонч, ты»; эха словаря не появилось.


Context-specific dictionary layers. Whisper's initial_prompt holds only ~210 tokens, so a single dictionary for every situation fills it up with terms that are irrelevant to whatever you are dictating into right now. Terms can now be split into layers: terms.d/<name>.txt is enabled per application, or as the default layer — the same way styles already work. A layer goes into the prompt first and pushes out the tail of the shared dictionary; duplicates don't cost budget twice.

The same layer feeds the cleanup model's system prompt and the correction guard, so the frontmost application is now resolved before transcription rather than after. New «Словарь терминов» submenu, a dictionary row in the status window showing how many terms and tokens actually made it into the prompt, and the active layer is logged with every dictation.

Коммиты:

  • 30571c3 Версия 0.15.0
  • 9dc049a Слои словаря: свой набор терминов на приложение

v0.14.0 — выгрузка модели чистки и понятные кнопки обновления

Choose a tag to compare

@kkdclaw kkdclaw released this 19 Aug 12:17

Выгрузка модели чистки из памяти — по галке. Модель для LLM-чистки паразитов срабатывает примерно на каждой шестой диктовке, а память занимала постоянно. Новая галка «Выгружать модель чистки в простое» (главное меню, рядом с «LLM-чистка паразитов») переводит её на загрузку по требованию: на старте в память не берём, грузим при первой же правке, выгружаем после 10 минут простоя (интервал — llm_idle_min в config.json). Замер на Mac Studio с GigaChat3.1-10B: RSS 8.1 → 2.2 ГБ, старт 5.0 → 1.8 с, загрузка по требованию ~2 с. По умолчанию галка выключена — поведение прежнее.

Понятные кнопки обновления. Строка «Обновления» раньше была статусом и кнопкой одновременно: первый клик спрашивал GitHub, второй ставил, между ними всплывало окно «нажми эту строку ещё раз». Теперь состояние — отдельная строка, а на кнопке написано, что произойдёт по клику («Проверить обновления» → «Установить 0.14.0 и перезапустить…»); найденное обновление сразу показывает список изменений. Стрелка ⬆️ идёт одной цепочкой: меню-бар → «О программе» → кнопка. Добавлен пункт «Как это работает…».


Optional unloading of the cleanup model. The filler-word cleanup LLM runs on roughly one dictation in six but used to sit in memory all the time. The new «Выгружать модель чистки в простое» checkbox switches it to on-demand loading: not loaded at startup, loaded on the first cleanup, unloaded after 10 idle minutes (llm_idle_min in config.json). Measured on a Mac Studio with GigaChat3.1-10B: 8.1 → 2.2 GB RSS, startup 5.0 → 1.8 s, on-demand load ~2 s. Off by default.

Clearer update buttons. Status and action are now separate: a non-clickable status line, and a button that says what the click will do. A found update opens the changelog right away instead of asking for a second click.

Коммиты:

  • 564b339 Версия 0.14.0
  • 7117ce5 Обновления: состояние отдельно от кнопки, установка в один клик
  • 8e46b1b Выгрузка модели чистки из памяти по галке, загрузка по требованию

v0.13.0 — индикация этапов прогрева

Choose a tag to compare

@kkdclaw kkdclaw released this 19 Aug 11:20

Индикация этапов прогрева

Загрузка моделей больше не выглядит зависанием. Раньше между строкой «Прогреваю модели» и готовностью приложение не печатало ничего: в меню-баре висел одинаковый ⏳ и на второй секунде, и на третьей минуте, окно состояния обещало «~20–30 с», а отказ по хоткею — «через несколько секунд». На большой модели (GigaChat3.1 — MoE на 6 ГБ) это неправда, и отличить долгую загрузку от намертво вставшего процесса было нельзя.

Теперь прогрев разбит на пять этапов — VAD, отпечаток голоса, распознавание, чистка, прогрев генерации:

  • в логе строка на каждый этап со временем от старта, в конце «✓ модели готовы за N с»;
  • в меню-баре номер этапа рядом с песочными часами (⏳4/5);
  • окно состояния и отказ по хоткею называют текущий этап и сколько он уже идёт;
  • у этапа с LLM в подписи имя и размер модели, чтобы минутная загрузка не пугала.

Заодно: .gitignore закрывает отпечаток голоса нового формата (voiceprint.npz — раньше игнорировался только .npy до 0.5.0), а версия проекта в uv.lock синхронизирована — иначе любой uv run пачкал рабочую копию и блокировал обновление по кнопке.

Load progress stages (EN)

Model warm-up no longer looks like a freeze. Previously nothing was printed between "loading models" and readiness, so a cold start of a large model (GigaChat3.1, a 6 GB MoE) was indistinguishable from a hung process. Warm-up is now split into five stages, each reported in the log with elapsed time, shown as a counter in the menu bar (⏳4/5) and named in the status window and the hotkey refusal; the LLM stage also shows the model name and size. Also: .gitignore now covers voiceprint.npz, and the project version in uv.lock is in sync.

Коммиты

  • c078e74 Прогрев: пять этапов с номерами в логе, меню-баре и окне состояния
  • 94b72df Игнор: отпечаток голоса .npz мимо git; uv.lock с актуальной версией

v0.12.1 — Словарь: без галлюцинаций, обрезка по токенам

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 22:15

RU: Галлюцинация распознавания больше не попадает в словарь; словарь режется по токенам

EN: Recognition loops no longer poison the dictionary; the prompt is capped by tokens

Изменения / Changes (2026-08-19)

  • Словарь: галлюцинация распознавания больше не попадает в словарь, обрезка по токенам

Подробнее

Петля «галлюцинация → словарь → галлюцинация». Whisper на плохой записи
выдал одно слово двести раз подряд; строка легла в историю, автослой посчитал
слово самым частым и внёс в auto_terms.txt, а словарь уходит в
initial_prompt — и Whisper, уже подсказанный, выдавал его снова. Теперь
зацикливание отсекается сразу после распознавания (одно слово занимает 40%
фразы и повторено ≥8 раз — не вставляем и в историю не пишем), такие строки
не участвуют в сборке словаря, а латинские слова считаются один раз на
диктовку, а не по всем повторам.

Обрезка словаря по токенам. Раньше словарь резался по словам (60 штук), а
у initial_prompt потолок в 224 ТОКЕНА, и одно русское слово — это 3–5
токенов: словарь из 58 слов давал 227. Лишнее Whisper отрезает с начала, то
есть выбрасывал ровно ручные термины, которые важнее автослоя. Теперь режется
хвост автослоя, ручное ядро остаётся целиком.


Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.12.0 — Ячейки стилей, «Неформальный», починка конфигов моделей

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 22:06

RU: Ячейки стилей в окне постобработки, стиль «Неформальный», починка конфигов моделей

EN: Style slots in the review window, an "informal" style, model-config repair

Изменения / Changes (2026-08-19)

  • Окно постобработки: стили не считались из-за гонки с показом окна
  • Ячейки стилей: четыре, любую можно выключить; стиль «Неформальный»; связный русский
  • Модели: чиним конфиг с int вместо float, откат на дефолтную при провале загрузки

Подробнее

Исправлено: стили в окне не считались. show() уходит в главный поток
асинхронно и возвращается до отрисовки окна, а ML-поток сразу спрашивал «окно
видно?» — получал «нет» и не считал ни одного стиля. Открытость окна теперь
номер сессии, который ставится синхронно.

Ячейки стилей. Окно берёт стили из четырёх ячеек, любую можно выключить
пунктом «— выключена»: стиль не считается и строки в окне не занимает.
Мусор и дубли в настройке дают выключенную ячейку, а не случайный стиль.

Стиль «Неформальный (по-человечески)» — язык рабочего чата; это не
«Разговорный», тот про формат «без точек».

Связный русский в стилях. Задания переписаны по итогам замеров на реальных
фразах: задание идёт после текста, а не в системном промпте (иначе 4B-модель
принимает диктовку за обращение к себе и отвечает на неё, выдумывая факты), и
прямо запрещён телеграфный стиль (иначе фраза рубится на обрывки). Плюс
страховки: слишком длинный результат или потерянный «?» откатывают на сырой текст.

Конфиги моделей. GigaChat3.1 приезжает с "routed_scaling_factor": 1, а
transformers 5 требует там float и отказывается читать конфиг — модель не
грузилась вовсе. Теперь такие поля приводятся к float автоматически, а если
выбранная модель всё же не поехала, служба возвращает модель по умолчанию и
перезапускается.


Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.11.0 — Окно постобработки: выбор варианта перед вставкой; надёжность аудио

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 21:24

RU: Окно постобработки — выбор варианта перед вставкой; надёжность аудио

EN: Review window — pick the variant before pasting; audio-layer reliability

Изменения / Changes (2026-08-19)

  • Окно постобработки: выбор варианта перед вставкой + стиль «Кратко»
  • Аудио: одно переоткрытие потока вместо двух, тихий вочдог, время в логе

Подробнее

Окно постобработки (выключено по умолчанию, меню → «Окно постобработки»).
Фраза не вставляется сразу: всплывает панель с вариантами — «Как сказано»
(сырой Whisper, без LLM), обычный результат и два стиля на выбор (по умолчанию
«Строгий» и «Кратко», слоты меняются в подменю). Клик вставляет выбранное в то
же поле. LLM-чистка иногда меняет смысл — ослышка распознавателя плюс
«исправление» модели, — и окно даёт откатиться на сырой текст или взять другую
формулировку, не передиктовывая. Панель не забирает фокус, поэтому ⌘V попадает
туда же, куда и без окна; выбор мышью. Сырой и обычный варианты готовы сразу,
стили дописываются на ходу.

Новый стиль «Кратко»: сжать до сути, но числа, суммы, даты, имена и термины
перенести дословно. Доступен и как профиль приложения / стиль по умолчанию.

Аудио. Вочдог и вотчер смены входа просыпались от одного события (AirPods
достали из кейса) и открывали поток дважды — лишний щелчок A2DP↔HFP съедал
первую секунду речи; теперь второй переоткрыватель видит живой поток на том же
входе и уходит ни с чем. В режиме «микрофонов нет вообще» опрос раз в 15 с
вместо 3 с: каждый опрос — полный Pa_Terminate/Pa_Initialize, от которого
CoreAudio сыпал «PaMacCore (AUHAL) err=-50». Повторы одной ошибки в лог больше
не пишутся, и каждая строка лога начинается со времени.


Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.10.0 — Обновление по кнопке: changelog, откат при сбое, перезапуск, автопроверка (опц.)

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 11:37

RU: Обновление по кнопке: changelog, откат при сбое, перезапуск, автопроверка (опц.)

EN: One-click update: changelog, rollback on failure, service restart, optional check at startup

Изменения / Changes (2026-08-18)

  • Обновление по кнопке: список изменений, откат при сбое, uv из демона, кнопка перезапуска

Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.9.0 — Голосовые команды и сниппеты

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 11:37

RU: Голосовые команды и сниппеты

EN: Voice commands and snippets

Изменения / Changes (2026-08-18)

  • Голосовые команды и сниппеты: «удали», «отмени», «отправь», хвостовая форма

Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.8.0 — Настраиваемая горячая клавиша, возврат буфера обмена

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 11:37

RU: Настраиваемая горячая клавиша, возврат буфера обмена

EN: Configurable hotkey, clipboard restored after paste

Изменения / Changes (2026-08-18)

  • Настраиваемая горячая клавиша и возврат буфера обмена после вставки

Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.

v0.7.1 — Проверка обновлений только по кнопке

Choose a tag to compare

@kkdclaw kkdclaw released this 18 Aug 11:37

RU: Проверка обновлений только по кнопке

EN: Update check is manual-only (button), no background requests

Изменения / Changes (2026-08-17)

  • Проверка обновлений — только по кнопке, без фоновых запросов

Обновление из приложения: меню «О программе · версия» → «Обновления» (git по HTTPS, ключи не нужны). Ручной вариант: git pull --ff-only && uv sync && ./daemon.sh restart.