Skip to content

Transcrição local: em massa, de vídeos, automática, na linha, cache por modelo; atalhos de revisão, J/O e WPPConnect 2.10.48 - #479

Merged
gabrielhhaber merged 31 commits into
mainfrom
claude/brave-goldberg-9d8rnx
Oct 12, 2026
Merged

gabrielhhaber merged 31 commits into
mainfrom
claude/brave-goldberg-9d8rnx

Conversation

@gustavo-barrios2006

@gustavo-barrios2006 gustavo-barrios2006 commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #469
Closes #462
Refs #379

O que muda para quem usa

Transcrição local

  • Transcrição em massa das mensagens selecionadas ([Feature]: Transcrição em lote de várias mensagens de voz selecionadas #469). No submenu "Ações em massa" há duas opções, cada uma com atalho próprio configurável na aba "Atalhos de teclado":
    • Ctrl+Alt+Shift+T (como Alt+Shift+T) mostra todas as transcrições juntas numa janela.
    • Ctrl+Alt+Shift+N (como Alt+Shift+N) põe cada transcrição na linha da sua mensagem.
    • Com "substituir atalhos por ações em massa" ligado e mensagens selecionadas, Alt+Shift+T e Alt+Shift+N também agem sobre a seleção.
    • Antes de começar, o WinZapp diz quantas mensagens vai transcrever, quantas pula e quantas reaproveita. Durante, anuncia "mensagem i de n".
    • Uma falha não para a fila; o atalho ou o menu de contexto cancela.
  • Transcrição na linha da mensagem. Alt+Shift+N põe a transcrição na própria linha ("…, duração: 0:12, transcrição: …") e lê em voz alta, sem janela. Uma opção da aba Interface do usuário troca esse comportamento com Enter/Espaço.
  • Vídeos são transcritos pela trilha de som, com todas as opções. Áudios e vídeos enviados como documento também mostram o texto na linha.
  • Transcrição automática das mensagens de voz recebidas, direto na linha. Vem desligada.
  • Cache por modelo:
    • O texto salvo é guardado separadamente para cada modelo.
    • Uma chave geral liga ou desliga o cache, e cada modelo pode ter a sua própria escolha.
    • Há botões para limpar o cache de um modelo ou de todos.
  • Manter o modelo carregado na memória. Vem desligado; sem a opção, o modelo é liberado após 5 minutos parado.
  • Reaproveitar as bibliotecas CUDA e os programas whisper.cpp já baixados em outra pasta.
  • Aba Transcrição local:
    • Teclas Alt em todos os botões.
    • Downloads em segundo plano que seguem a configuração geral, com botão de cancelar.
    • Marcação de modelos na lista e download dos marcados em sequência.

Outros

Todas as strings novas estão nos 7 idiomas, e o changelog da 2.1.0.0 foi atualizado em todos eles.

Revisão

O branch foi revisado em três fatias pelo agente winzapp-reviewer, iterando até a aprovação. É uma revisão local, não uma aprovação no GitHub.

  • Fatia 1 (configurações e runtime da transcrição): aprovada. Principais correções:
    • Foco durante os downloads em segundo plano.
    • Verificação de arquivos do whisper.cpp reaproveitado.
    • Pasta de modelos bloqueada durante um download.
  • Fatia 2 (guardar, mostrar e produzir transcrições): aprovada. Principais correções:
    • A janela em massa não mostra o texto de mensagem apagada para todos.
    • Apagar uma transcrição redesenha a linha.
    • Limpar um cache não apaga resultado salvo enquanto a limpeza esperava.
    • Fechar o WinZapp cancela as transcrições automáticas e em massa, matando o ffmpeg/whisper-cli e apagando o áudio decifrado.
    • Marcar um texto antigo na linha mantém a data em que foi feito.
  • Fatia 3 (atualizador, J/O, [Feature]: add shortcut keys alt 1 through alt 0 to review last 10 messages when in a conversation. #462, encaminhar, Performance proposal: Concurrency throttling for getMessages and V8 memory management during chat history sync #379, WPPConnect, mesclagem): aprovada. Principal correção: um atalho de revisão com tecla escolhida pelo usuário abria a janela de erro na lista de mídias de "Dados da conversa".

Depois da abertura da PR, o CI apontou um problema que a revisão local não podia ver: na aba Transcrição local, um trabalho que nunca chegou a começar quebrava o aviso do resultado, e os argumentos passados ao trabalho tinham mudado. Os commits bc93a64 e a7e6c0c corrigem isso, voltando aos argumentos da main, com teste.

Mesclagem com a main

A main foi mesclada três vezes. A última trouxe a #478 (cancelamento do atualizador e entrega ao instalador).

  • Conflitos: só nos changelogs, onde os itens dos dois lados foram mantidos, e na contagem de docs/reference/keyboard-shortcuts.md, recalculada para 269 atribuições e 287 registros.
  • Conflitos semânticos:
    • Os novos Ctrl+Shift+I da main estão nos escopos de status e do visualizador de mídia, sem colisão com os atalhos deste branch.
    • A descrição de vídeos e os atalhos de chamada no campo de mensagem não tocam os caminhos de transcrição.
    • A Fix updater cancellation and installer handoff lifecycle #478 convive com a limpeza da pasta temporária deste branch: os testes do atualizador falham aqui exatamente nos mesmos casos que na main pura, por limitação do ambiente Linux.

Testes

  • CI (Windows, wx real, --run-wx-gui): verde no head atual (a7e6c0c).
  • Localmente, em Linux, com um wx falso: os arquivos tocados passam, exceto falhas que acontecem igual na main. A comparação ampla com a main não mostrou falha nova.
  • Traduções: translations-check OK (7 idiomas, 0 pendentes).
  • Não executado: o app em si e a reinstalação da API com a 2.10.48.

🤖 Generated with Claude Code

https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9

claude added 30 commits October 11, 2026 15:56
faster-whisper opens a path with PyAV (av.open(..., metadata_errors=...)),
which fails on an old av after the model has loaded and surfaces only as
backend_error. The prepared file is our own 16 kHz mono PCM WAV, so read it
with the wave module and pass the float32 samples; fall back to the path if
it cannot be read.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…lt field, downloads follow the background setting

- All seventeen action buttons get an Alt key in every locale; the same word
  shares one letter across rows and none takes OK/Cancel/Apply.
- Verifying (model, CUDA, whisper.cpp, folder in another location) moves the
  focus to the result field; picking another model/backend/build/folder
  drops the old outcome so the field hides when empty.
- Model, CUDA and whisper.cpp downloads/repairs honour 'download in the
  background': the main window runs the job, the tab adopts it, nothing moves
  the focus when it ends. The setting's label now says it covers them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…ist, download the marked ones in sequence

- A Cancel button shows while a download runs in the background; it stops the
  current job and drops the queue, and the app quitting does the same.
- The model drop-down is a list with the selection mode of the chat and
  message lists: Ctrl+Space marks, Space marks while something is marked, Esc
  unmarks, following the same two user-interface settings.
- Download with models marked fetches them one after another after a single
  confirmation sized as the sum, behind the progress dialog or as one
  background run; the first failure or cancellation stops the rest.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…line; Enter/Space can transcribe instead of play

- A transcription stored as inline shows in the row (', transcrição: texto'),
  is read aloud, and opens no window; a fresh result that cannot be kept still
  opens the window so the text is not lost.
- Ctrl+Shift+T alternates with the new User Interface option 'Enter and Space
  on a voice message transcribe it into its line' (off by default): off, it
  transcribes into the line and Enter plays; on, Enter/Space transcribe and it
  plays or pauses. Menu item, F1 list and the option's label say which.
- Alt+L reads the rest of a long inline transcription.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
… Alt+Shift+N

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…nd sweep old leftovers

The installer script only deleted itself, so every update left a full copy of
the release in winzapp_ext_*. The script now removes it after a successful copy
and the relaunch (never on failure paths), and the next start sweeps what older
updates, failed installs and killed downloads left, with a grace period so a
package another account staged in the background is not taken.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…eply to me

The forward halves of Alt+Shift+M and Alt+Shift+P, with the same wrap-around.
Both are catalogue shortcuts (customisable in the Shortcuts tab); their
defaults were checked against every locale with the tab's own conflict rule.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…by position

Each reads the Nth newest message aloud without moving the focus, and pressing
the same key twice quickly copies it. They ship with no key (Alt+1..Alt+9 belong
to the main window): they are ten rows of the shortcut catalogue that the
Shortcuts tab can bind, free of conflicts like any other command.

Closes #462

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…a message box

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
The sync and backfill pools fired get-messages from up to six threads into the
one WhatsApp Web page, which serialises them anyway and costs CPU and memory on
small machines. Their requests (and only theirs) now share a gate of two, with
the pools, timeouts, retries and every foreground fetch unchanged; the wait is
bounded and is never counted as a request fault. Launch flags and forced GC from
the issue are deliberately left for later measurement.

Refs #379

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…ed transcriptions

A saved transcription now belongs to the model that made it: changing the
model asks for a new run and the earlier model's text stays for when the user
goes back. Settings > Local transcription gets a button that deletes, in every
chat, only what the selected model transcribed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
faster-whisper's cached model had no end: one transcription held its RAM or
VRAM for the whole session. It is now released five minutes after the last run
ended, unless Settings > Local transcription > Keep the model loaded is on.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…ed to another folder

Settings > Local transcription gets a group to point WinZapp at a folder of CUDA
libraries and at a folder of whisper.cpp builds it already downloaded, instead of
downloading them again. The folders are only read; the CUDA libraries must load
and the whisper.cpp builds go through the same manifest and pinned-digest checks
as WinZapp's own.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…al, into the message line

Settings > Local transcription > 'Automatically transcribe received voice
messages' (off by default) transcribes each fresh incoming voice message, one at
a time, and keeps the text as an inline transcription. Locked chats, backlogs and
very long recordings are skipped; a machine that is not set up pauses the queue
and says so once.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…lear every model's cache

Settings > Local transcription gets a general switch (on by default) for saving
transcriptions with the messages, a per-model override of it (follow the general
setting / on / off), and a button that clears the saved transcriptions of all
models in every chat. With the cache off for a model its new results are not
saved and the result window opens instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…ption

A video message (never a GIF) and a video document are transcribed like a voice
note: ffmpeg drops the picture and converts the sound for faster-whisper or
whisper.cpp. Inline text, Alt+Shift+N, Enter/Space transcribing, automatic
transcription of received ones, the per-model cache and clearing all apply. A
video with no sound gets its own sentence.

Also fixes the flow tests the per-model change left behind (the stored text
belongs to the selected model; a record that names no model still matches).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…e is transcribed

Closes #469

Two bulk actions, each with its own customisable shortcut and an entry in the
Bulk actions submenu: Ctrl+Alt+Shift+T (like Alt+Shift+T: kept, then all shown
together in the result window) and Ctrl+Alt+Shift+N (like Alt+Shift+N: each into
its message's line). With 'replace shortcuts with bulk actions' on, Alt+Shift+T
and Alt+Shift+N also act on the selection. The plan is confirmed first, the
queue runs one at a time in the background announcing progress, carries on
past a failure (stops on a setup fault), can be cancelled, and ends with a
tally; the context menu then shows every text together to copy or save.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
Conflicts only in the changelogs (both sides added items: kept both) and the
translation catalogs (both sides added entries next to each other: kept both,
then translations-update / check / compile).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
- the table-coverage fake owner did not know the ID_REVIEW[d] family;
- the 'models in other folders' buttons have Alt keys now (shared by word);
- 'unknown length' is a missing duration, not 0 (which reads as 0 seconds).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
- Focus: a background run moves it to Cancel; Cancel and the Clear/Browse
  buttons are no longer disabled under the focus; at the end a stranded focus
  is moved to a control that answers.
- A queued job that cannot start now ends the run for the Settings tab too.
- The startup hooks (keep the model loaded, reused folders) are one tested
  call (core/transcription/runtime_settings.py).
- The tab says when whisper.cpp builds and CUDA libraries come from the reused
  folder, and its device notices follow them.
- whisper.cpp: a .dll/.exe the manifest does not list refuses the launch.
- No models-folder move while a background download holds the models lock.
- Residency: a stale timer can no longer take the next one's place.
- Nits: tr-TR wording, build names spoken, log the exception report, in-place
  WAV scaling, dead state removed, rules paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
- Bulk window re-reads each text when it opens (bulk.shown_entries): a
  message withdrawn mid-run, or whose text was deleted or cleared, is left
  out; a text the cache did not keep is the run's own and the tally says so.
- Ctrl+Alt+Shift+T opens the window only in the run's conversation with the
  app active, and the window says the tally; elsewhere it is offered.
- Marking an existing text inline keeps its "made" date (stored.marked_inline)
  and is not refused by the cache switches (existing=True).
- Deleting a transcription redraws the row, so its line drops the text.
- Clearing a model or all models leaves alone a result stored while the clear
  waited in the queue (stored.values_on snapshot).
- The database write keeps the row's other models' results
  (stored.with_missing_results).
- Quitting stops the automatic queue and a bulk run, cancelling the running
  transcription (MainWindow.stop_transcription_runs).
- Audio/video documents show their inline text in the row and get Read more.
- Automatic transcription re-checks the chat lock before each run.
- Docstrings, test names and spacing-tolerant source checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…onversation

- with_known_transcription merges the row's other models' results when both
  sides carry the same decision, so a copy built in memory without them no
  longer drops them on the next sync.
- The flow's row redraw happens only in the message's own conversation; an
  answer arriving after the user moved on no longer rebuilds another one.
- The bulk run offers its window only when some text is left to show.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
Audited 2.10.37 -> 2.10.48 with audit_wpp_upgrade.audit() over a local
clone of upstream: 22 dependency/release commits, only CHANGELOG.md,
package.json and yarn.lock changed, so nothing WinZapp overrides moved.
Upstream's @wppconnect-team/wppconnect caret moved to ^2.3.4, the exact pin
WinZapp already ships; wa-js 4.6.1 and engines.node 22.22.2 unchanged. The
only runtime range bump is express-rate-limit (^8.7.0 -> ^8.7.1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…oural tests

- logical_key: a command with no shipped key (a review position) passes the
  pressed chord on instead of None, which crashed command_key_event in
  Conversation data's media list once such a key was bound.
- Changelog, every locale: forwarding now speaks its confirmation instead of
  a box (changed 2.0 behaviour); the missing full stop in the J/O item; the
  review-position item names the "Keyboard shortcuts" tab.
- Tests: the messages table is evaluated for Alt+Shift+J/O and for review
  positions (no key until one is chosen) instead of grepping the source; the
  installer cleanup test calls _run_batch_installer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…st stays in tmp_path

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
Conflicts only in the changelogs and docs/reference/keyboard-shortcuts.md:
- Changelogs (every locale): both sides' new items kept. The "Local
  transcription" item appeared twice because main carried the old text next
  to its new item; the branch's longer version is kept (the difference was
  only the branch's additions), giving 65 items in V2.1.0.0 everywhere.
- keyboard-shortcuts.md: the catalogue counts recomputed for the merged
  catalogue, 269 assignments and 287 records (main's Ctrl+Shift+I rows plus
  the branch's).

Semantic check: main's new Ctrl+Shift+I rows are in the status and media
scopes, which the branch does not use; its message-field call shortcuts and
video description do not touch the transcription paths. Translation catalogs
updated, checked and compiled. The relevant test files show no new failure
against origin/main under the fake wx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
…tion

CI (Windows, real wx) failed test_transcription_settings_tab::
TestTheWhisperCppProgram::test_the_action_reaches_the_job_with_its_build_and_the_card:
_after_transcription_job read job.action, and the progress dialog can
answer with no job at all. Before the background mode the callers passed
the action, model and build themselves; they do so again, and the job's
own values are only the fallback. A model with no job is not counted as
arrived, so it stays marked in the queue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ToZG4a1BnrYaZdEMDszBSB
…ackground mode

CI still failed test_the_action_reaches_the_job_with_its_build_and_the_card:
_start_transcription_job handed every action model_id, build_id and
compute_capability. As before, a whisper.cpp action gets its build and card
and a model or CUDA action its model; the new test pins both shapes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RitkxPiQTUgQNToYouWF9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants