docs: um passeio guiado pela arquitetura, e o faster-whisper declarado - #10
Merged
Conversation
O `README.md` deste repositorio tem 69 KB e cobre instalacao, configuracao, troca de voz e solucao de problemas. O que faltava era outra coisa: um documento que responda **"como isso funciona?"** para quem nunca viu o projeto, sem exigir que a pessoa leia 69 KB para descobrir. `COMO-FUNCIONA.md` e esse documento. Quinze minutos, com diagramas Mermaid (que o GitHub renderiza): - o caminho de uma pergunta em dez passos, do bloco de 30 ms do microfone ate os olhos se mexendo junto com a voz; - as pecas uma a uma, agrupadas por pasta, cada uma com o que faz e por que existe; - as quatro decisoes que explicam o desenho — falar antes de terminar de pensar, duas IAs com troca invisivel, a face que nao pode engasgar, e sobreviver ao proprio hardware; - os tres servicos systemd do robo, e por que a ponte BLE roda separada e como root; - os tres contratos que precisam bater com os outros repositorios. **E um defeito de empacotamento, achado ao escrever a secao de instalacao.** O extra `stt` declarava so o `vosk` — mas o backend padrao e o `whisper` (`HearingSettings.backend = "whisper"`), que precisa do `faster-whisper`, que nao estava declarado em lugar nenhum. No robo atual funciona porque alguem o instalou a mao (`pip show` confirma: `Required-by:` vazio). Num cartao novo, `--escuta` instalaria o Vosk, o `baixar-modelo-escuta.sh` falharia no `import faster_whisper`, o setup seguiria com um aviso — e o robo subiria com a escuta ligada, no motor padrao, sem a biblioteca dele. Surdo, e sem nada explicando por que. De quebra, o `CLAUDE.md` dizia que `Event` tem 8 subclasses. Tem 10: `SpeechHeard` e `ListeningChanged` entraram depois e a contagem ficou para tras. 703 testes passam, ruff limpo. Os 3 diagramas foram validados com o `mermaid-cli`, nao so escritos. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v
A `main` estava vermelha desde o merge anterior, e a culpa e deste teste.
`test_reabre_e_volta_a_entregar_frases` exercita o contrato que importa — quem
consome `frases()` nao percebe a queda do dispositivo — e para isso chama a
funcao publica. Mas `frases()` importa o `sounddevice` antes de qualquer coisa,
de proposito: e o que faz o robo falhar cedo, com mensagem boa, numa maquina
sem audio.
O teste substitui `_uma_captura`, entao nunca chega a usar o `sounddevice`. So
que passa pelo import. Resultado: ele so roda onde o extra `tts` estiver
instalado, e a CI instala apenas `[dev]`.
HearingError: microfone indisponivel: No module named 'sounddevice'
Nao apareceu aqui porque o venv local tem o extra completo. Agora o teste poe
um modulo vazio no lugar, e a verificacao foi feita como a CI faz: venv novo,
`pip install -e ".[dev]"`, sem `sounddevice` — 703 passam.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v
O caminho da sintese adiantada terminava em `continue` e pulava o `finally` do outro caminho — o unico lugar que chamava `_idle.set()` e `_set_speaking(False)`. Consequencia: quando a **ultima** fala de uma resposta vinha pronta — o caso comum, porque a sintese se adianta de proposito enquanto a frase anterior toca — o locutor a dizia e voltava a esperar na fila sem nunca ter anunciado silencio. `wait_until_idle` esperava para sempre e `is_speaking` ficava preso em True ate alguem enfileirar outra coisa. Aparecia como teste instavel, e era um instavel dos ruins: medido aqui, `test_lote_respeita_o_teto_de_tamanho` falhava **14 de 40 vezes**. Dependia de a ultima fala das doze cair no caminho adiantado ou no normal. Um teste que reprova um terco do tempo sem apontar nada e pior que teste nenhum — foi ele que deixou a CI da main vermelha, e o reflexo natural seria culpar a CI. A correcao junta os dois caminhos num metodo so, `_anunciar_silencio_se_acabou()`, que olha os **tres** lugares onde uma fala pode estar esperando: a fila, `_held` (o que ja saiu da fila e nao foi dito) e `_pronto` (o audio ja sintetizado da proxima). Quatro testes novos no lugar do instavel, todos deterministicos. O que cobre o defeito exato deixa uma fala em `_pronto` **antes** de o laco arrancar, forcando o caminho adiantado: falha 100% das vezes sem a correcao, passa 100% com ela. Conferido desfazendo a correcao e rodando de novo. 707 testes passam, nos dois ambientes — o venv completo e um venv novo com apenas `[dev]`, igual ao da CI. Trinta repeticoes seguidas da suite do locutor, zero falhas. ruff e mypy limpos. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
O que é
O
README.mddeste repositório tem 69 KB e cobre instalação, configuração, troca de voz e solução de problemas. O que faltava era outra coisa: um documento que responda "como isso funciona?" para quem nunca viu o projeto — sem exigir que a pessoa leia 69 KB para descobrir.COMO-FUNCIONA.mdé esse documento. Quinze minutos, com diagramas Mermaid que o GitHub renderiza:E um defeito de empacotamento
Achado ao escrever a seção de instalação: o extra
sttdeclarava só ovosk— mas o backend padrão é owhisper(HearingSettings.backend = "whisper"), que precisa dofaster-whisper, não declarado em lugar nenhum.No robô atual funciona porque alguém o instalou à mão (
pip showconfirma:Required-by:vazio). Num cartão novo,--escutainstalaria o Vosk, obaixar-modelo-escuta.shfalharia noimport faster_whisper, o setup seguiria com um aviso — e o robô subiria com a escuta ligada, no motor padrão, sem a biblioteca dele. Surdo, e sem nada explicando por quê.Verificação
rufflimpomermaid-cli, não só escritos🤖 Generated with Claude Code
https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v